ultraworkers-claw-code/rust/crates/api/src
YeonGyu-Kim a3d0c9e5e7 fix(api): sanitize orphaned tool messages at request-building layer
Adds sanitize_tool_message_pairing() called from build_chat_completion_request()
after translate_message() runs. Drops any role:"tool" message whose
immediately-preceding non-tool message is role:"assistant" but has no
tool_calls entry matching the tool_call_id.

This is the second layer of the tool-pairing invariant defense:
- 6e301c8: compaction boundary fix (producer layer)
- this commit: request-builder sanitizer (sender layer)

Together these close the 400-error loop for resumed/compacted multi-turn
tool sessions on OpenAI-compatible backends.

Sanitization only fires when preceding message is role:assistant (not
user/system) to avoid dropping valid translation artifacts from mixed
user-message content blocks.

Regression tests: sanitize_drops_orphaned_tool_messages covers valid pair,
orphaned tool (no tool_calls in preceding assistant), mismatched id, and
two tool results both referencing the same assistant turn.

116 api + 159 CLI + 431 runtime tests pass. Fmt clean.
2026-04-10 01:35:00 +09:00
..
providers fix(api): sanitize orphaned tool messages at request-building layer 2026-04-10 01:35:00 +09:00
client.rs fix(api): route DashScope models to dashscope config, not openai 2026-04-08 18:04:37 +09:00
error.rs fix(api): auth-provider error copy — prefix-routing hints + sk-ant-* bearer detection — closes ROADMAP #28 2026-04-08 16:29:03 +09:00
http_client.rs feat: b6-openai-models — batch 6 2026-04-07 15:52:30 +09:00
lib.rs feat: b6-pdf-extract-v2 follow-up work — batch 6 2026-04-07 16:11:51 +09:00
prompt_cache.rs feat(api): add tuning params (temperature, top_p, penalties, stop) to MessageRequest 2026-04-08 07:07:33 +09:00
sse.rs fix(api): enrich JSON parse errors with response body, provider, and model 2026-04-07 14:22:05 +09:00
types.rs feat(api): add reasoning_effort field to MessageRequest and OpenAI-compat path 2026-04-09 04:02:59 +09:00