Просмотр исходного кода

docs: plan batch replay and terminal hardening

Problem: batch keys are pre-normalization, replay is non-atomic and unbounded, sibling deadlines can suppress termination, sync handlers block timeout enforcement, and tool-only termination can end without a farewell.

Risk: canonical coalescing must preserve per-call correlation; terminal grace and thread dispatch must remain bounded; round scopes must prevent stale parser-local replay.
zhenyu.hu 2 недель назад
Родитель
Сommit
e37c079d64

+ 71 - 0
docs/plans/todo-48.1-batch-canonical-replay-and-terminal-safety.md

@@ -0,0 +1,71 @@
+# Todo 48.1 Batch Canonical Replay and Terminal Safety Plan
+
+**Status:** in_progress
+
+## Goal
+
+Close review-confirmed batch correctness, lifecycle, timeout, and user-visible termination gaps while keeping the scheduler and policy layer generic.
+
+## Canonical Dedupe and Replay
+
+- Split canonical request identity from event ID:
+  - batch coalescing uses event name, source, and deterministically normalized request arguments, excluding event ID;
+  - replay identity additionally includes caller scope and event ID.
+- Apply definition normalizers before forming provider/structured request keys. Text name-only events may coalesce within one batch, but Runtime scopes must include round so parser-local IDs cannot replay stale results across rounds before resolution.
+- Clone coalesced/replayed `EventResult` correlation fields for each requested event ID while retaining explicit deduplication provenance.
+- Add an in-flight future map guarded atomically so concurrent identical replay keys execute one handler.
+- Add explicit scope release and a defensive capacity bound; Runtime/EventAgent release round scopes after results are delivered.
+
+## Terminal Deadline
+
+- Non-terminal siblings use the configured batch deadline.
+- After siblings finish or become timeout results, terminal events receive a short independent grace window bounded by their own timeout.
+- Mark `deadline_exceeded=True` for the sibling phase while still allowing terminal execution.
+- Preserve terminal-last order and failure isolation.
+
+## Sync Handler Timeout
+
+- Run synchronous handlers off the event loop in async kernel execution so event/batch timeout can return promptly and unrelated events/session work remain responsive.
+- Keep `execute_sync()` behavior unchanged.
+- Do not swallow cancellation/BaseException.
+- Document/test that timeout stops awaiting the worker; production side-effect ports should remain cancellation/idempotency aware.
+
+## Farewell and Search Acceptance
+
+- Give `session.terminate` a plugin-owned deterministic farewell factory.
+- When a successful terminal batch has no visible ChatAgent content, emit that deterministic farewell before ending one-shot/reusable sessions.
+- If ChatAgent already streamed a farewell, do not duplicate it.
+- Add dedicated `knowledge.web.search` two-answer regressions for both modes: first visible response, search/tool execution, one grounded second ChatAgent response.
+
+## Files
+
+- Modify: `src/agent_lab/application/events/batch.py`
+- Modify: `src/agent_lab/application/events/kernel.py`
+- Modify: `src/agent_lab/application/events/models.py`
+- Modify: `src/agent_lab/application/events/builtin_plugins.py`
+- Modify: `src/agent_lab/application/tools.py`
+- Modify: `src/agent_lab/application/event_agent.py`
+- Modify: `src/agent_lab/application/runtime.py`
+- Modify: `tests/test_event_batch.py`
+- Modify: `tests/test_event_kernel.py`
+- Modify: `tests/test_debug_runtime.py`
+
+## Requirement Execution Loop
+
+### Plan
+
+1. Add RED normalized-equivalence, different-ID coalescing, cross-round stale replay, concurrent in-flight replay, and scope cleanup tests.
+2. Add RED sibling-timeout/terminal-grace and blocking-sync-handler timeout tests.
+3. Add RED tool-call-only terminate farewell and direct/dual search two-answer tests.
+4. Implement canonical keys, atomic in-flight sharing, bounded cleanup, terminal grace, async sync-handler dispatch, and policy-owned farewell.
+5. Run focused/full verification and renewed bounded reviews.
+
+### Observe / Update
+
+Close Todo 48 only when no Critical/Important findings remain and the named direct/dual user-visible flows are permanent regressions.
+
+## Verification
+
+- `UV_CACHE_DIR=.uv-cache uv run pytest tests/test_event_batch.py tests/test_event_kernel.py tests/test_debug_runtime.py -q`
+- `UV_CACHE_DIR=.uv-cache uv run pytest`
+- `git diff --check`

+ 1 - 0
docs/plans/todos.md

@@ -89,6 +89,7 @@
 | 47.2 | done | `docs/plans/todo-47.2-plugin-token-and-compatibility-boundaries.md` | Reject remaining negated/non-integer volume tokens, canonicalize integral JSON numbers, preserve fallback state, use standard date-time semantics, and restore positional dataclass compatibility. | Named negation/token cases, integral floats, fallback provenance, RFC3339, and positional compatibility pass. |
 | 47.3 | done | `docs/plans/todo-47.3-bare-volume-numeric-guard.md` | Apply malformed numeric rejection to the existing bare `volume to`, `volume at`, and `volume=` syntaxes. | Bare decimal/grouped tokens are rejected with no side effect; integer forms remain valid; bounded gate APPROVED. |
 | 48 | in_progress | `docs/plans/todo-48-parallel-event-batches.md` | Execute multiple flat events with bounded parallelism, failure isolation, aggregation, and a terminal barrier. | Runtime tests prove independent concurrency, stable result order, isolated failures, and termination after sibling completion or timeout. |
+| 48.1 | in_progress | `docs/plans/todo-48.1-batch-canonical-replay-and-terminal-safety.md` | Canonicalize batch keys, make replay atomic and bounded, guarantee terminal grace after sibling timeout, enforce async timeout around sync handlers, and ensure termination has a farewell. | Normalized equivalents coalesce safely; in-flight duplicates execute once; scopes release cache; terminal runs after sibling timeout; blocking sync work cannot block the loop; search two-answer and tool-only farewell regressions pass. |
 | 49 | pending | `docs/plans/todo-49-tool-mode-ui-session-restore.md` | Add UI mode selection, workspace/session restoration, and clear EventAgent applicability feedback. | Static/WebSocket tests prove requests, snapshots, loaded sessions, and audit context preserve the selected mode. |
 | 50 | pending | `docs/plans/todo-50-comparable-model-tool-metrics.md` | Record mode-aware model/tool spans and include EventAgent usage so both architectures can be compared fairly. | Persistence/API tests report agent, call kind, tokens, TTFT, tool latency, fallback usage, and total turn wall time without double counting. |
 | 51 | pending | `docs/plans/todo-51-comparison-matrix-closeout.md` | Add repeatable comparison fixtures, update project documentation, and close the experimental implementation. | Both modes pass the same scenario matrix; full tests, JS syntax, app import, and documentation checks pass. |