mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-16 09:45:24 -04:00
Harden streaming deltas against null payloads
This commit is contained in:
+13
-13
@@ -387,8 +387,8 @@ def _build_anthropic_payload(model, messages, temperature, max_tokens, stream=Fa
|
||||
if m.get("content"):
|
||||
content.append({"type": "text", "text": m["content"]})
|
||||
for tc in m["tool_calls"]:
|
||||
fn = tc.get("function", {})
|
||||
args_str = fn.get("arguments", "{}")
|
||||
fn = tc.get("function") or {}
|
||||
args_str = fn.get("arguments") or "{}"
|
||||
try:
|
||||
args = json.loads(args_str) if isinstance(args_str, str) else args_str
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
@@ -886,26 +886,26 @@ async def stream_llm(url: str, model: str, messages: List[Dict], temperature: fl
|
||||
evt = j.get("type", "")
|
||||
if evt == "content_block_start":
|
||||
_anth_block_idx = j.get("index", _anth_block_idx + 1)
|
||||
cb = j.get("content_block", {})
|
||||
cb = j.get("content_block") or {}
|
||||
_anth_block_type = cb.get("type", "text")
|
||||
if _anth_block_type == "tool_use":
|
||||
_anth_tool_blocks[_anth_block_idx] = {
|
||||
"id": cb.get("id", f"call_{_anth_block_idx}"),
|
||||
"name": cb.get("name", ""),
|
||||
"id": cb.get("id") or f"call_{_anth_block_idx}",
|
||||
"name": cb.get("name") or "",
|
||||
"arguments": "",
|
||||
}
|
||||
elif evt == "content_block_delta":
|
||||
delta = j.get("delta", {})
|
||||
delta = j.get("delta") or {}
|
||||
delta_type = delta.get("type", "")
|
||||
if delta_type == "text_delta":
|
||||
text = delta.get("text", "")
|
||||
text = delta.get("text") or ""
|
||||
if text:
|
||||
yield f'data: {json.dumps({"delta": text})}\n\n'
|
||||
elif delta_type == "input_json_delta":
|
||||
# Accumulate tool arguments JSON
|
||||
idx = j.get("index", _anth_block_idx)
|
||||
if idx in _anth_tool_blocks:
|
||||
partial = delta.get("partial_json", "")
|
||||
partial = delta.get("partial_json") or ""
|
||||
_anth_tool_blocks[idx]["arguments"] += partial
|
||||
# Stream tool arg deltas for doc tools
|
||||
if partial and _anth_tool_blocks[idx].get("name") in ("create_document", "update_document", "edit_document"):
|
||||
@@ -1000,14 +1000,14 @@ async def stream_llm(url: str, model: str, messages: List[Dict], temperature: fl
|
||||
u = j["usage"]
|
||||
yield f'data: {json.dumps({"type": "usage", "data": {"input_tokens": u.get("prompt_tokens", 0), "output_tokens": u.get("completion_tokens", 0)}})}\n\n'
|
||||
elif "choices" in j:
|
||||
delta = j["choices"][0].get("delta", {})
|
||||
delta = j["choices"][0].get("delta") or {}
|
||||
if isinstance(delta, dict):
|
||||
# Text content
|
||||
# Reasoning tokens (VLLM --reasoning-parser, e.g. Qwen3/DeepSeek-R1)
|
||||
reasoning = delta.get("reasoning_content", "")
|
||||
reasoning = delta.get("reasoning_content") or ""
|
||||
if reasoning:
|
||||
yield f'data: {json.dumps({"delta": reasoning, "thinking": True})}\n\n'
|
||||
content = delta.get("content", "")
|
||||
content = delta.get("content") or ""
|
||||
if content:
|
||||
# Some thinking backends start normal content with a
|
||||
# stray closing tag. Repair only that shape; do not
|
||||
@@ -1018,13 +1018,13 @@ async def stream_llm(url: str, model: str, messages: List[Dict], temperature: fl
|
||||
_first_content_sent = True
|
||||
yield f'data: {json.dumps({"delta": content})}\n\n'
|
||||
# Native tool calls — accumulate across chunks
|
||||
for tc in delta.get("tool_calls", []):
|
||||
for tc in delta.get("tool_calls") or []:
|
||||
idx = tc.get("index", 0)
|
||||
if idx not in _tc_acc:
|
||||
_tc_acc[idx] = {"id": "", "name": "", "arguments": ""}
|
||||
if tc.get("id"):
|
||||
_tc_acc[idx]["id"] = tc["id"]
|
||||
func = tc.get("function", {})
|
||||
func = tc.get("function") or {}
|
||||
if func.get("name"):
|
||||
_tc_acc[idx]["name"] = func["name"]
|
||||
if "arguments" in func:
|
||||
|
||||
Reference in New Issue
Block a user