Jelajahi Sumber

docs: plan provider tool transcript support

Problem: direct ChatAgent tools require a provider-compatible assistant/tool transcript and explicit tool-choice semantics before Runtime can enable schemas.

Risk: this todo changes message validation and client serialization but intentionally does not enable direct Runtime routing.
zhenyu.hu 2 minggu lalu
induk
melakukan
c49c3b06c8
2 mengubah file dengan 90 tambahan dan 1 penghapusan
  1. 89 0
      docs/plans/todo-44-provider-tool-transcript.md
  2. 1 1
      docs/plans/todos.md

+ 89 - 0
docs/plans/todo-44-provider-tool-transcript.md

@@ -0,0 +1,89 @@
+# Todo 44 Provider Tool Transcript Plan
+
+**Status:** in_progress
+
+## Goal
+
+Represent and serialize a valid OpenAI-compatible assistant tool-call transcript so a later Runtime todo can continue ChatAgent after native tool execution without weakening the existing dual-agent path.
+
+## Scope
+
+- Add structured assistant `tool_calls` to the internal `ChatMessage` model.
+- Serialize assistant tool calls and matched `tool` replies into provider-compatible request messages.
+- Reject orphaned, mismatched, duplicate, or incomplete tool transcripts before network I/O.
+- Replace implicit “one tool means forced invocation” behavior with an explicit `tool_choice` argument.
+- EventAgent explicitly forces its one selected tool; ordinary ChatAgent requests keep automatic/no forced choice behavior.
+- Do not enable ChatAgent tools in Runtime in this todo.
+
+## Files
+
+- Modify: `src/agent_lab/domain/messages.py`
+- Modify: `src/agent_lab/infrastructure/chat_client.py`
+- Modify: `src/agent_lab/application/runtime.py`
+- Modify: `src/agent_lab/application/event_agent.py`
+- Modify: `src/agent_lab/application/contracts.py`
+- Modify: `tests/test_websocket_api.py`
+- Modify: `tests/test_event_agent.py`
+- Modify: `tests/test_debug_runtime.py` only for protocol signature compatibility if required
+- Modify: `docs/plans/todos.md`
+
+## Plan
+
+### Plan
+
+1. Define the desired internal transcript and tool-choice API through failing tests.
+2. Verify failures occur because `ChatMessage` lacks assistant tool calls, the client rejects all tool messages, and a single tool is implicitly forced.
+3. Add the minimum typed message fields and transcript validation/serialization.
+4. Add explicit optional `tool_choice` to the chat-client protocols and implementation.
+5. Make EventAgent pass a forced function choice; keep Runtime ChatAgent calls unchanged with `tools=[]` and no tool choice.
+6. Run focused and full regressions.
+
+### Act
+
+Follow TDD in small RED/GREEN slices:
+
+1. **Message shape RED**
+   - Add a test constructing an assistant `ChatMessage` with two `ToolCallEvent` entries and asserting `model_dump()` preserves IDs, names, parsed arguments, and raw arguments.
+   - Add validation tests rejecting `tool_calls` on non-assistant roles and rejecting a `tool` role without `tool_call_id`.
+2. **Provider serialization RED**
+   - Add a MockTransport request test containing:
+     - assistant content plus two tool calls;
+     - two matching tool replies;
+     - a final user or assistant-visible message after replies.
+   - Assert the provider payload uses standard `assistant.tool_calls[].function.arguments` raw JSON and `tool.tool_call_id`.
+3. **Transcript guard RED**
+   - Add separate tests rejecting before network I/O:
+     - orphan tool reply;
+     - mismatched call ID;
+     - duplicate tool reply;
+     - a non-tool message while assistant calls remain unresolved.
+4. **Tool choice RED**
+   - Add a test showing one ChatAgent tool with no explicit choice does not add forced `tool_choice`.
+   - Add a test showing an explicit forced function choice is serialized exactly.
+   - Update EventAgent tests to assert its argument-generation call supplies the selected function choice.
+5. Run focused tests and confirm expected failures.
+6. Implement minimal domain validation, transcript serialization, explicit choice plumbing, and EventAgent forcing.
+7. Re-run focused tests and then the full suite.
+
+### Observe
+
+Confirm that:
+
+- the legal transcript matches OpenAI-compatible message ordering;
+- visible assistant content can coexist with tool calls;
+- invalid histories fail locally before HTTP calls;
+- single-tool ChatAgent requests are no longer accidentally forced;
+- EventAgent retains deterministic selected-tool invocation;
+- Runtime still sends `tools=[]` in the existing dual-agent mode.
+
+### Update
+
+- Mark only todo 44 `done` after spec and quality reviews pass.
+- If review finds post-commit defects, add `44.1` directly below todo 44 and do not edit the completed row.
+- Commit code with the problem and any compatibility risk in the body.
+
+## Verification
+
+- `uv run pytest tests/test_websocket_api.py tests/test_event_agent.py tests/test_debug_runtime.py -q`
+- `uv run pytest`
+- `git diff --check`

+ 1 - 1
docs/plans/todos.md

@@ -72,7 +72,7 @@
 | 43 | done | `docs/plans/todo-43-typed-provider-tool-calls.md` | Preserve native provider tool calls as a distinct stream event without changing the existing text-event path. | `uv run pytest tests/test_openai_stream_parser.py -q`; focused typed-event regressions; full suite passes (`82 passed`, one existing warning). |
 | 43.1 | done | `docs/plans/todo-43.1-typed-event-consumer-regression.md` | Repair Runtime and EventAgent consumers after typed stream kinds exposed legacy `event` assumptions. | Runtime consumes `text_event`, EventAgent consumes `provider_tool_call`; focused and full tests pass. |
 | 43.2 | done | `docs/plans/todo-43.2-remove-legacy-event-consumption.md` | Remove legacy `event` consumption from production paths and migrate remaining fixtures to typed stream kinds. | Wrong-source negative tests and real client `[DONE]` integration pass; full suite passes (`82 passed`). |
-| 44 | pending | `docs/plans/todo-44-provider-tool-transcript.md` | Add provider-compatible assistant tool-call and tool-result message serialization plus explicit tool-choice behavior. | Client/domain tests prove legal transcripts serialize and malformed tool history is rejected. |
+| 44 | in_progress | `docs/plans/todo-44-provider-tool-transcript.md` | Add provider-compatible assistant tool-call and tool-result message serialization plus explicit tool-choice behavior. | Client/domain tests prove legal transcripts serialize and malformed tool history is rejected. |
 | 45 | pending | `docs/plans/todo-45-configurable-tool-invocation-mode.md` | Add `dual_agent` and `chat_agent_tools` runtime modes that share one registry and user-visible behavior. | Runtime tests prove mode-specific requests, direct execution, valid provider history, and dual-mode regression safety. |
 | 46 | pending | `docs/plans/todo-46-flat-event-policies-hybrid-resolution.md` | Extend flat event definitions with deterministic-first argument resolution, LLM fallback, and generic result policies. | Tests prove deterministic events skip EventAgent LLM and ambiguous cases use one bounded fallback. |
 | 47 | pending | `docs/plans/todo-47-production-event-definitions.md` | Add experimental terminate-session, device-volume, schedule, and web-search event definitions with normalized contracts. | Focused tests cover valid, ambiguous, invalid, idempotent, and failure results for all four events. |