Skip to content

Commit 005a6f9

Browse files
authored
fix(studio): preserve JSON runtime request headers (#1003)
1 parent d5a23be commit 005a6f9

2 files changed

Lines changed: 32 additions & 11 deletions

File tree

tests/cli/test_frontend_evaluation_feedback.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,14 @@ async def search_findskill(_catalog: object, **kwargs: Any) -> dict[str, object]
130130
],
131131
ids=["agent-info", "legacy-runtime-fallback", "first-feedback-dataset"],
132132
)
133+
@pytest.mark.parametrize("rating", ["good", "bad"])
133134
def test_message_feedback_writes_dataset_and_session_state(
134135
monkeypatch: pytest.MonkeyPatch,
135136
tmp_path: Path,
136137
agent_info_status: int,
137138
expected_agent_name: str,
138139
initially_empty: bool,
140+
rating: str,
139141
) -> None:
140142
app = _create_frontend_app(monkeypatch, tmp_path)
141143
openapi_calls: list[dict[str, Any]] = []
@@ -201,6 +203,15 @@ async def request(self, method: str, url: str, **kwargs: Any) -> _FakeResponse:
201203
status_code=agent_info_status,
202204
)
203205
if method == "PATCH" and "/sessions/session-1" in url:
206+
json_headers = [
207+
(name.lower(), value)
208+
for name, value in kwargs["headers"].items()
209+
if name.lower() in {"accept", "content-type"}
210+
]
211+
assert json_headers == [
212+
("accept", "application/json"),
213+
("content-type", "application/json"),
214+
]
204215
session_patches.append(kwargs["json"])
205216
return _FakeResponse({}, status_code=404)
206217
raise AssertionError((method, url))
@@ -225,7 +236,7 @@ async def post(self, url: str, **kwargs: Any) -> _FakeResponse:
225236
"EvaluationSets": [
226237
{
227238
"Id": "set-1",
228-
"Name": f"{expected_agent_name}_good_case",
239+
"Name": f"{expected_agent_name}_{rating}_case",
229240
"WorkspaceId": "workspace-1",
230241
}
231242
]
@@ -268,16 +279,18 @@ async def post(self, url: str, **kwargs: Any) -> _FakeResponse:
268279
"userId": "user-1",
269280
"sessionId": "session-1",
270281
"eventId": "assistant-event",
271-
"rating": "good",
282+
"rating": rating,
272283
"comment": annotation_comment,
273284
},
274285
)
275286

276287
assert response.status_code == 200
277-
assert response.json()["rating"] == "good"
288+
assert response.json()["rating"] == rating
278289
assert response.json()["comment"] == annotation_comment
279290
assert response.json()["evaluationItemId"] == "item-1"
280-
assert response.json()["evaluationSetName"] == (f"{expected_agent_name}_good_case")
291+
assert response.json()["evaluationSetName"] == (
292+
f"{expected_agent_name}_{rating}_case"
293+
)
281294
assert response.json()["statePersistence"] == "browser"
282295
expected_actions = [
283296
"ListEvaluationSets",
@@ -296,7 +309,7 @@ async def post(self, url: str, **kwargs: Any) -> _FakeResponse:
296309
else:
297310
assert openapi_calls[1]["params"]["WorkspaceId"] == "workspace-1"
298311
state = session_patches[0]["state_delta"]["veadk_feedback:assistant-event"]
299-
assert state["rating"] == "good"
312+
assert state["rating"] == rating
300313
assert state["comment"] == annotation_comment
301314
assert state["evaluationItemId"] == "item-1"
302315
create_item_call = next(
@@ -310,8 +323,9 @@ async def post(self, url: str, **kwargs: Any) -> _FakeResponse:
310323
assert fields["feedback_comment"] == annotation_comment
311324

312325

326+
@pytest.mark.parametrize("rating", ["good", "bad"])
313327
def test_message_feedback_byteplus_is_noop(
314-
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
328+
monkeypatch: pytest.MonkeyPatch, tmp_path: Path, rating: str
315329
) -> None:
316330
app = _create_frontend_app(
317331
monkeypatch,
@@ -363,7 +377,7 @@ def __init__(self, **kwargs: Any) -> None:
363377
"userId": "user-1",
364378
"sessionId": "session-1",
365379
"eventId": "assistant-event",
366-
"rating": "good",
380+
"rating": rating,
367381
},
368382
)
369383

veadk/cli/cli_frontend.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9117,10 +9117,17 @@ async def _runtime_json_request(
91179117
region,
91189118
runtime,
91199119
)
9120-
headers = _runtime_request_headers(
9121-
request,
9122-
apikey=apikey,
9123-
auth_type=auth_type,
9120+
# Starlette exposes incoming header names in lowercase. Wrap the
9121+
# forwarded mapping before overriding JSON headers so httpx replaces
9122+
# them case-insensitively instead of emitting duplicate values such as
9123+
# ``application/json, application/json``. FastAPI treats that combined
9124+
# media type as non-JSON and passes the body to Pydantic as a string.
9125+
headers = httpx.Headers(
9126+
_runtime_request_headers(
9127+
request,
9128+
apikey=apikey,
9129+
auth_type=auth_type,
9130+
)
91249131
)
91259132
headers["Accept"] = "application/json"
91269133
if payload is not None:

0 commit comments

Comments
 (0)