|
|
@@ -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`
|