Kaynağa Gözat

docs: plan message role validation

zhenyu.hu 3 hafta önce
ebeveyn
işleme
d5a908172f

+ 57 - 0
docs/plans/todo-14-message-role-validation.md

@@ -0,0 +1,57 @@
+# Todo 14 Message Role Validation Plan
+
+**Status:** in_progress
+
+## Goal
+
+Reject provider-invalid API message roles and malformed tool replies before runtime work or network calls.
+
+## Why
+
+The UI no longer exposes `tool` pre-messages, and the OpenAI client rejects tool messages without `tool_call_id`. API callers can still send arbitrary `role` values in `pre_messages`, which can fail later at the provider boundary. The request contract should fail fast.
+
+## Scope
+
+This todo covers:
+
+- Constrain `ChatMessage.role` to Chat Completions-compatible roles.
+- Reject `pre_messages` with `role="tool"` in `DebugRunRequest`, because request pre-messages cannot provide a matching assistant `tool_calls` context safely.
+- Preserve internally generated EventAgent tool replies.
+- Keep OpenAI client payload serialization tests passing.
+
+This todo does not cover:
+
+- Full arbitrary conversation transcript validation.
+- UI changes.
+- Tool handler exception isolation.
+
+## Files
+
+- Modify: `src/agent_lab/domain/messages.py`
+- Modify: `src/agent_lab/application/contracts.py`
+- Modify: `tests/test_websocket_api.py` or add focused contract tests.
+
+## Steps
+
+1. Add failing tests:
+   - invalid pre-message role is rejected by `DebugRunRequest.model_validate()`;
+   - `pre_messages` with `role="tool"` is rejected before runtime;
+   - internally created `ChatMessage(role="tool", tool_call_id="...")` remains valid.
+2. Implement a `Literal` role type in `ChatMessage`.
+3. Add a `DebugRunRequest` validator that rejects tool pre-messages.
+4. Run:
+
+```bash
+uv run pytest tests/test_websocket_api.py tests/test_event_agent.py
+uv run pytest
+```
+
+5. Update this plan and `docs/plans/todos.md`, then commit.
+
+## Verification
+
+Expected result:
+
+- Request validation fails before provider/network work for invalid roles.
+- Runtime-generated tool replies still validate.
+- Full suite passes.

+ 1 - 1
docs/plans/todos.md

@@ -40,6 +40,6 @@
 | 11 | done | `docs/plans/todo-11-prompt-workspace.md` | Improve prompt/pre-message editing with browser-side persistence and reusable prompt sets. | UI tests or focused JS tests prove prompts persist and can be restored. |
 | 12 | done | `docs/plans/todo-12-round-stats.md` | Move round statistics to structured backend events for token counts, cached tokens, TTFT, elapsed time, and per-turn summaries. | `uv run pytest tests/test_debug_runtime.py tests/test_websocket_api.py`; `uv run pytest`. |
 | 13 | done | `docs/plans/todo-13-real-queue-websocket-loop.md` | Make runtime queues real producer/consumer boundaries and let WebSocket run separate upstream/downstream tasks. | `uv run pytest tests/test_debug_runtime.py tests/test_websocket_api.py`; `uv run pytest`. |
-| 14 | pending | `docs/plans/todo-14-message-role-validation.md` | Reject provider-invalid API message roles and malformed tool replies before network calls. | Tests prove request validation rejects invalid roles and orphan tool messages. |
+| 14 | in_progress | `docs/plans/todo-14-message-role-validation.md` | Reject provider-invalid API message roles and malformed tool replies before network calls. | Tests prove request validation rejects invalid roles and orphan tool messages. |
 | 15 | pending | `docs/plans/todo-15-static-package-data.md` | Include static UI assets in installed package builds. | Build/package inspection proves `index.html`, JS, and CSS are present. |
 | 16 | pending | `docs/plans/todo-16-tool-error-isolation.md` | Convert EventAgent tool handler exceptions into structured tool-result errors instead of aborting the session. | Tests prove a failing tool returns an error payload and the WebSocket run stays structured. |