fix(ai-chat): harden run finalize + restore int-spec, cover terminal callbacks (#184 round-2)
Round-2 review fixes for PR #234 (#184 autonomous agent runs). F6 (stability): finalizeRun no longer drops the in-memory entry before the terminal write. It now UPDATEs first with a bounded retry; only on success does it arm the idempotency once-gate (a new `settled` set keyed on "row already terminal", not "entry deleted") and free the chat's active slot. If every attempt fails the entry is RETAINED and the run left unsettled so a later finalize / requestStop->onAbort / sweep can retry — a transient blip can no longer strand a run 'running' and 409 every future turn in the chat. Idempotency preserved (double-settle still collapses to a single write). F7 (regression from F2): int-spec constructs AiChatRunService with the 2nd EnvironmentService arg ({ isCloud: () => false }) so the file type-checks and all integration tests compile+run again. F8 (regression from F1): the windowed "stale but not fresh" case now calls sweepRunning({ staleMs: SWEEP_RUN_STALE_MS }); added an int-level variant-C case proving the no-arg boot sweep aborts even a FRESH running run. F9 (coverage): run-race spec now captures streamText's options and invokes onStepFinish/onFinish/onAbort/onError, asserting the #184 run hooks (onStep / onSettled completed|aborted|error) fire with the right args. F10 (docs): added an autonomousRuns single-instance-only note to .env.example so the warnIfMultiInstance JSDoc reference is accurate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
14
.env.example
14
.env.example
@@ -170,6 +170,20 @@ MCP_DOCMOST_PASSWORD=
|
||||
# Default 900000 (15 min).
|
||||
# AI_MCP_CALL_TIMEOUT_MS=900000
|
||||
|
||||
# --- Autonomous / detached agent runs (settings.ai.autonomousRuns) ---
|
||||
# Opt-in per workspace (AI settings; off by default). When on, a chat turn becomes
|
||||
# a server-side RUN that survives a browser disconnect — only an explicit Stop ends
|
||||
# it, and a client reconnects/live-follows the run.
|
||||
#
|
||||
# DEPLOY CONSTRAINT — SINGLE-INSTANCE ONLY in phase 1: Stop and the in-process
|
||||
# AbortController that backs it are process-local, so a Stop only aborts a run
|
||||
# executing on the SAME replica that owns it (cross-instance pub/sub stop is phase
|
||||
# 2 and not yet reliable). Do NOT enable autonomousRuns on a horizontally-scaled
|
||||
# deployment (multiple replicas behind a load balancer, or Docmost cloud
|
||||
# CLOUD=true) — run a single instance instead. The server logs a startup WARNING
|
||||
# when it detects a multi-instance deployment (CLOUD=true) so the constraint is
|
||||
# visible, and a startup sweep settles any run left dangling by a restart.
|
||||
|
||||
# --- Anonymous public-share AI assistant ---
|
||||
# Opt-in per workspace (AI settings -> "public share assistant"; off by default).
|
||||
# When enabled, anonymous visitors of a published share can ask an AI about that
|
||||
|
||||
Reference in New Issue
Block a user