}}
});
+ if (timings.prompt_n >= 0) {
+ server_sent_events.back().at("data").push_back({"timings", timings.to_json()});
+ }
+
return server_sent_events;
}
thinking_block_started = state.thinking_block_started;
text_block_started = state.text_block_started;
+ oai_resp_created = state.oai_resp_created;
oai_resp_id = state.oai_resp_id;
oai_resp_reasoning_id = state.oai_resp_reasoning_id;
oai_resp_message_id = state.oai_resp_message_id;
// track if the accumulated message has any reasoning content
anthropic_has_reasoning = !state.chat_msg.reasoning_content.empty();
+ if (res_type == TASK_RESPONSE_TYPE_OAI_RESP && !state.oai_resp_created && (is_progress || n_decoded == 1)) {
+ state.oai_resp_created = true;
+ }
+
// Pre-compute state updates based on diffs (for next chunk)
for (const common_chat_msg_diff & diff : oaicompat_msg_diffs) {
if (!diff.reasoning_content_delta.empty() && !state.thinking_block_started) {
json server_task_result_cmpl_partial::to_json_oaicompat_resp() {
std::vector<json> events;
- if (n_decoded == 1) {
+ if (!oai_resp_created) {
events.push_back(json {
{"event", "response.created"},
{"data", json {
}},
}},
});
+ } else if (is_progress) {
+ events.push_back(json {
+ {"event", "response.in_progress"},
+ {"data", json {
+ {"type", "response.in_progress"},
+ {"response", json {
+ {"id", oai_resp_id},
+ {"object", "response"},
+ {"status", "in_progress"},
+ }},
+ }},
+ });
}
for (const common_chat_msg_diff & diff : oaicompat_msg_diffs) {
});
}
}
+
+ if (!events.empty()) {
+ json & data = events.back().at("data");
+ if (timings.prompt_n >= 0) {
+ data.push_back({"timings", timings.to_json()});
+ }
+ if (is_progress) {
+ data.push_back({"prompt_progress", progress.to_json()});
+ }
+ }
+
return events;
}
bool text_block_started = false;
// for OpenAI Responses streaming API
+ bool oai_resp_created = false;
const std::string oai_resp_id;
const std::string oai_resp_reasoning_id;
const std::string oai_resp_message_id;
bool text_block_started = false;
// for OpenAI Responses API
+ bool oai_resp_created = false;
std::string oai_resp_id;
std::string oai_resp_reasoning_id;
std::string oai_resp_message_id;
assert r.response.output[0].id.startswith("msg_")
assert gathered_text == r.response.output_text
assert match_regex("(Suddenly)+", r.response.output_text)
+
+
+def test_responses_stream_with_llama_telemetry():
+ global server
+ server.n_ctx = 256
+ server.n_batch = 32
+ server.n_slots = 1
+ server.start()
+
+ saw_progress = False
+ saw_delta_timings = False
+ completed = None
+
+ res = server.make_stream_request("POST", "/responses", data={
+ "input": "This is a test" * 10,
+ "max_output_tokens": 8,
+ "temperature": 0.8,
+ "stream": True,
+ "timings_per_token": True,
+ "return_progress": True,
+ })
+
+ for data in res:
+ if "prompt_progress" in data:
+ assert data["type"] == "response.in_progress"
+ assert data["prompt_progress"]["total"] > 0
+ assert data["prompt_progress"]["processed"] >= data["prompt_progress"]["cache"]
+ saw_progress = True
+ if "timings" in data:
+ assert "prompt_per_second" in data["timings"]
+ assert "predicted_per_second" in data["timings"]
+ if data["type"] == "response.output_text.delta":
+ saw_delta_timings = True
+ if data["type"] == "response.completed":
+ completed = data
+
+ assert saw_progress
+ assert saw_delta_timings
+ assert completed is not None
+ assert "usage" in completed["response"]
+ assert "timings" in completed