@qjp88995/agent-runtime 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-extensions.d.ts +30 -0
- package/dist/agent-extensions.d.ts.map +1 -0
- package/dist/agent-extensions.js +4 -0
- package/dist/agent-extensions.js.map +1 -0
- package/dist/builtins/ask-outcome.d.ts +49 -0
- package/dist/builtins/ask-outcome.d.ts.map +1 -0
- package/dist/builtins/ask-outcome.js +128 -0
- package/dist/builtins/ask-outcome.js.map +1 -0
- package/dist/builtins/ask-schema.d.ts +110 -0
- package/dist/builtins/ask-schema.d.ts.map +1 -0
- package/dist/builtins/ask-schema.js +124 -0
- package/dist/builtins/ask-schema.js.map +1 -0
- package/dist/builtins/ask.service.d.ts +210 -0
- package/dist/builtins/ask.service.d.ts.map +1 -0
- package/dist/builtins/ask.service.js +373 -0
- package/dist/builtins/ask.service.js.map +1 -0
- package/dist/builtins/ask.tool.d.ts +49 -0
- package/dist/builtins/ask.tool.d.ts.map +1 -0
- package/dist/builtins/ask.tool.js +109 -0
- package/dist/builtins/ask.tool.js.map +1 -0
- package/dist/builtins/index.d.ts +8 -0
- package/dist/builtins/index.d.ts.map +1 -0
- package/dist/builtins/index.js +8 -0
- package/dist/builtins/index.js.map +1 -0
- package/dist/builtins/todo-schema.d.ts +90 -0
- package/dist/builtins/todo-schema.d.ts.map +1 -0
- package/dist/builtins/todo-schema.js +97 -0
- package/dist/builtins/todo-schema.js.map +1 -0
- package/dist/builtins/todo-settle.hook.d.ts +110 -0
- package/dist/builtins/todo-settle.hook.d.ts.map +1 -0
- package/dist/builtins/todo-settle.hook.js +174 -0
- package/dist/builtins/todo-settle.hook.js.map +1 -0
- package/dist/builtins/todo.tool.d.ts +59 -0
- package/dist/builtins/todo.tool.d.ts.map +1 -0
- package/dist/builtins/todo.tool.js +107 -0
- package/dist/builtins/todo.tool.js.map +1 -0
- package/dist/context/context-budget-tracker.d.ts +185 -0
- package/dist/context/context-budget-tracker.d.ts.map +1 -0
- package/dist/context/context-budget-tracker.js +400 -0
- package/dist/context/context-budget-tracker.js.map +1 -0
- package/dist/context/context-budget.d.ts +48 -0
- package/dist/context/context-budget.d.ts.map +1 -0
- package/dist/context/context-budget.js +89 -0
- package/dist/context/context-budget.js.map +1 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +3 -0
- package/dist/context/index.js.map +1 -0
- package/dist/extensions/repeat-call.hook.d.ts +32 -0
- package/dist/extensions/repeat-call.hook.d.ts.map +1 -0
- package/dist/extensions/repeat-call.hook.js +54 -0
- package/dist/extensions/repeat-call.hook.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/turn-hook.registry.d.ts +51 -0
- package/dist/hooks/turn-hook.registry.d.ts.map +1 -0
- package/dist/hooks/turn-hook.registry.js +233 -0
- package/dist/hooks/turn-hook.registry.js.map +1 -0
- package/dist/hooks/turn-hook.types.d.ts +179 -0
- package/dist/hooks/turn-hook.types.d.ts.map +1 -0
- package/dist/hooks/turn-hook.types.js +48 -0
- package/dist/hooks/turn-hook.types.js.map +1 -0
- package/dist/images/byte-cache.d.ts +24 -0
- package/dist/images/byte-cache.d.ts.map +1 -0
- package/dist/images/byte-cache.js +51 -0
- package/dist/images/byte-cache.js.map +1 -0
- package/dist/images/delivery.d.ts +115 -0
- package/dist/images/delivery.d.ts.map +1 -0
- package/dist/images/delivery.js +321 -0
- package/dist/images/delivery.js.map +1 -0
- package/dist/images/index.d.ts +5 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +5 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/prompt.d.ts +151 -0
- package/dist/images/prompt.d.ts.map +1 -0
- package/dist/images/prompt.js +172 -0
- package/dist/images/prompt.js.map +1 -0
- package/dist/images/vendor-files.d.ts +93 -0
- package/dist/images/vendor-files.d.ts.map +1 -0
- package/dist/images/vendor-files.js +156 -0
- package/dist/images/vendor-files.js.map +1 -0
- package/dist/in-process/conversation-store.d.ts +64 -0
- package/dist/in-process/conversation-store.d.ts.map +1 -0
- package/dist/in-process/conversation-store.js +222 -0
- package/dist/in-process/conversation-store.js.map +1 -0
- package/dist/in-process/coordination.d.ts +54 -0
- package/dist/in-process/coordination.d.ts.map +1 -0
- package/dist/in-process/coordination.js +137 -0
- package/dist/in-process/coordination.js.map +1 -0
- package/dist/in-process/image-source.d.ts +15 -0
- package/dist/in-process/image-source.d.ts.map +1 -0
- package/dist/in-process/image-source.js +27 -0
- package/dist/in-process/image-source.js.map +1 -0
- package/dist/in-process/index.d.ts +36 -0
- package/dist/in-process/index.d.ts.map +1 -0
- package/dist/in-process/index.js +37 -0
- package/dist/in-process/index.js.map +1 -0
- package/dist/in-process/question-store.d.ts +28 -0
- package/dist/in-process/question-store.d.ts.map +1 -0
- package/dist/in-process/question-store.js +122 -0
- package/dist/in-process/question-store.js.map +1 -0
- package/dist/in-process/run-store.d.ts +36 -0
- package/dist/in-process/run-store.d.ts.map +1 -0
- package/dist/in-process/run-store.js +81 -0
- package/dist/in-process/run-store.js.map +1 -0
- package/dist/in-process/session-store.d.ts +33 -0
- package/dist/in-process/session-store.d.ts.map +1 -0
- package/dist/in-process/session-store.js +93 -0
- package/dist/in-process/session-store.js.map +1 -0
- package/dist/in-process/stream-bus.d.ts +52 -0
- package/dist/in-process/stream-bus.d.ts.map +1 -0
- package/dist/in-process/stream-bus.js +200 -0
- package/dist/in-process/stream-bus.js.map +1 -0
- package/dist/in-process/vendor-file-cache.d.ts +11 -0
- package/dist/in-process/vendor-file-cache.d.ts.map +1 -0
- package/dist/in-process/vendor-file-cache.js +47 -0
- package/dist/in-process/vendor-file-cache.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/loop/active-tick.registry.d.ts +31 -0
- package/dist/loop/active-tick.registry.d.ts.map +1 -0
- package/dist/loop/active-tick.registry.js +45 -0
- package/dist/loop/active-tick.registry.js.map +1 -0
- package/dist/loop/index.d.ts +6 -0
- package/dist/loop/index.d.ts.map +1 -0
- package/dist/loop/index.js +6 -0
- package/dist/loop/index.js.map +1 -0
- package/dist/loop/loop-driver.d.ts +127 -0
- package/dist/loop/loop-driver.d.ts.map +1 -0
- package/dist/loop/loop-driver.js +199 -0
- package/dist/loop/loop-driver.js.map +1 -0
- package/dist/loop/message-hub.d.ts +236 -0
- package/dist/loop/message-hub.d.ts.map +1 -0
- package/dist/loop/message-hub.js +439 -0
- package/dist/loop/message-hub.js.map +1 -0
- package/dist/loop/orphan-run.sweeper.d.ts +79 -0
- package/dist/loop/orphan-run.sweeper.d.ts.map +1 -0
- package/dist/loop/orphan-run.sweeper.js +145 -0
- package/dist/loop/orphan-run.sweeper.js.map +1 -0
- package/dist/loop/root-host.d.ts +51 -0
- package/dist/loop/root-host.d.ts.map +1 -0
- package/dist/loop/root-host.js +65 -0
- package/dist/loop/root-host.js.map +1 -0
- package/dist/ports/context-store.d.ts +69 -0
- package/dist/ports/context-store.d.ts.map +1 -0
- package/dist/ports/context-store.js +2 -0
- package/dist/ports/context-store.js.map +1 -0
- package/dist/ports/conversation-store.d.ts +144 -0
- package/dist/ports/conversation-store.d.ts.map +1 -0
- package/dist/ports/conversation-store.js +2 -0
- package/dist/ports/conversation-store.js.map +1 -0
- package/dist/ports/coordination.d.ts +76 -0
- package/dist/ports/coordination.d.ts.map +1 -0
- package/dist/ports/coordination.js +12 -0
- package/dist/ports/coordination.js.map +1 -0
- package/dist/ports/image-source.d.ts +26 -0
- package/dist/ports/image-source.d.ts.map +1 -0
- package/dist/ports/image-source.js +2 -0
- package/dist/ports/image-source.js.map +1 -0
- package/dist/ports/index.d.ts +11 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +4 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/ports/logger.d.ts +14 -0
- package/dist/ports/logger.d.ts.map +1 -0
- package/dist/ports/logger.js +23 -0
- package/dist/ports/logger.js.map +1 -0
- package/dist/ports/question-store.d.ts +91 -0
- package/dist/ports/question-store.d.ts.map +1 -0
- package/dist/ports/question-store.js +8 -0
- package/dist/ports/question-store.js.map +1 -0
- package/dist/ports/run-store.d.ts +66 -0
- package/dist/ports/run-store.d.ts.map +1 -0
- package/dist/ports/run-store.js +2 -0
- package/dist/ports/run-store.js.map +1 -0
- package/dist/ports/session-store.d.ts +72 -0
- package/dist/ports/session-store.d.ts.map +1 -0
- package/dist/ports/session-store.js +9 -0
- package/dist/ports/session-store.js.map +1 -0
- package/dist/ports/stream-bus.d.ts +52 -0
- package/dist/ports/stream-bus.d.ts.map +1 -0
- package/dist/ports/stream-bus.js +2 -0
- package/dist/ports/stream-bus.js.map +1 -0
- package/dist/ports/vendor-file-cache.d.ts +46 -0
- package/dist/ports/vendor-file-cache.d.ts.map +1 -0
- package/dist/ports/vendor-file-cache.js +2 -0
- package/dist/ports/vendor-file-cache.js.map +1 -0
- package/dist/schema/agent-event.d.ts +35 -0
- package/dist/schema/agent-event.d.ts.map +1 -0
- package/dist/schema/agent-event.js +46 -0
- package/dist/schema/agent-event.js.map +1 -0
- package/dist/schema/agent-run.d.ts +23 -0
- package/dist/schema/agent-run.d.ts.map +1 -0
- package/dist/schema/agent-run.js +37 -0
- package/dist/schema/agent-run.js.map +1 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/message-part.d.ts +73 -0
- package/dist/schema/message-part.d.ts.map +1 -0
- package/dist/schema/message-part.js +90 -0
- package/dist/schema/message-part.js.map +1 -0
- package/dist/subagent/delegate.tool.d.ts +145 -0
- package/dist/subagent/delegate.tool.d.ts.map +1 -0
- package/dist/subagent/delegate.tool.js +329 -0
- package/dist/subagent/delegate.tool.js.map +1 -0
- package/dist/subagent/index.d.ts +10 -0
- package/dist/subagent/index.d.ts.map +1 -0
- package/dist/subagent/index.js +10 -0
- package/dist/subagent/index.js.map +1 -0
- package/dist/subagent/milestone-body.d.ts +82 -0
- package/dist/subagent/milestone-body.d.ts.map +1 -0
- package/dist/subagent/milestone-body.js +112 -0
- package/dist/subagent/milestone-body.js.map +1 -0
- package/dist/subagent/output-scan.d.ts +14 -0
- package/dist/subagent/output-scan.d.ts.map +1 -0
- package/dist/subagent/output-scan.js +41 -0
- package/dist/subagent/output-scan.js.map +1 -0
- package/dist/subagent/registry-spawn-policy.d.ts +32 -0
- package/dist/subagent/registry-spawn-policy.d.ts.map +1 -0
- package/dist/subagent/registry-spawn-policy.js +48 -0
- package/dist/subagent/registry-spawn-policy.js.map +1 -0
- package/dist/subagent/roster-block.d.ts +45 -0
- package/dist/subagent/roster-block.d.ts.map +1 -0
- package/dist/subagent/roster-block.js +69 -0
- package/dist/subagent/roster-block.js.map +1 -0
- package/dist/subagent/situation-block.d.ts +16 -0
- package/dist/subagent/situation-block.d.ts.map +1 -0
- package/dist/subagent/situation-block.js +71 -0
- package/dist/subagent/situation-block.js.map +1 -0
- package/dist/subagent/spawn-guards.d.ts +32 -0
- package/dist/subagent/spawn-guards.d.ts.map +1 -0
- package/dist/subagent/spawn-guards.js +39 -0
- package/dist/subagent/spawn-guards.js.map +1 -0
- package/dist/subagent/subagent-registry.d.ts +150 -0
- package/dist/subagent/subagent-registry.d.ts.map +1 -0
- package/dist/subagent/subagent-registry.js +167 -0
- package/dist/subagent/subagent-registry.js.map +1 -0
- package/dist/subagent/subagent-sessions.d.ts +213 -0
- package/dist/subagent/subagent-sessions.d.ts.map +1 -0
- package/dist/subagent/subagent-sessions.js +295 -0
- package/dist/subagent/subagent-sessions.js.map +1 -0
- package/dist/testing/contracts.d.ts +37 -0
- package/dist/testing/contracts.d.ts.map +1 -0
- package/dist/testing/contracts.js +607 -0
- package/dist/testing/contracts.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/stub.d.ts +28 -0
- package/dist/testing/stub.d.ts.map +1 -0
- package/dist/testing/stub.js +3 -0
- package/dist/testing/stub.js.map +1 -0
- package/dist/tools/agent-tool.base.d.ts +186 -0
- package/dist/tools/agent-tool.base.d.ts.map +1 -0
- package/dist/tools/agent-tool.base.js +243 -0
- package/dist/tools/agent-tool.base.js.map +1 -0
- package/dist/tools/agent-tool.interface.d.ts +95 -0
- package/dist/tools/agent-tool.interface.d.ts.map +1 -0
- package/dist/tools/agent-tool.interface.js +2 -0
- package/dist/tools/agent-tool.interface.js.map +1 -0
- package/dist/tools/builtin-names.d.ts +18 -0
- package/dist/tools/builtin-names.d.ts.map +1 -0
- package/dist/tools/builtin-names.js +20 -0
- package/dist/tools/builtin-names.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/tool-definition.d.ts +18 -0
- package/dist/tools/tool-definition.d.ts.map +1 -0
- package/dist/tools/tool-definition.js +77 -0
- package/dist/tools/tool-definition.js.map +1 -0
- package/dist/tools/tool-meta.d.ts +55 -0
- package/dist/tools/tool-meta.d.ts.map +1 -0
- package/dist/tools/tool-meta.js +2 -0
- package/dist/tools/tool-meta.js.map +1 -0
- package/dist/tools/tool-registry.d.ts +190 -0
- package/dist/tools/tool-registry.d.ts.map +1 -0
- package/dist/tools/tool-registry.js +379 -0
- package/dist/tools/tool-registry.js.map +1 -0
- package/dist/tools/tool-result.d.ts +41 -0
- package/dist/tools/tool-result.d.ts.map +1 -0
- package/dist/tools/tool-result.js +19 -0
- package/dist/tools/tool-result.js.map +1 -0
- package/dist/tools/tool-wire.d.ts +24 -0
- package/dist/tools/tool-wire.d.ts.map +1 -0
- package/dist/tools/tool-wire.js +2 -0
- package/dist/tools/tool-wire.js.map +1 -0
- package/dist/turn/agent-runtime.d.ts +31 -0
- package/dist/turn/agent-runtime.d.ts.map +1 -0
- package/dist/turn/agent-runtime.js +30 -0
- package/dist/turn/agent-runtime.js.map +1 -0
- package/dist/turn/chunk-projection.d.ts +32 -0
- package/dist/turn/chunk-projection.d.ts.map +1 -0
- package/dist/turn/chunk-projection.js +62 -0
- package/dist/turn/chunk-projection.js.map +1 -0
- package/dist/turn/compaction.d.ts +48 -0
- package/dist/turn/compaction.d.ts.map +1 -0
- package/dist/turn/compaction.js +89 -0
- package/dist/turn/compaction.js.map +1 -0
- package/dist/turn/context-overflow.d.ts +11 -0
- package/dist/turn/context-overflow.d.ts.map +1 -0
- package/dist/turn/context-overflow.js +53 -0
- package/dist/turn/context-overflow.js.map +1 -0
- package/dist/turn/context-pressure.d.ts +100 -0
- package/dist/turn/context-pressure.d.ts.map +1 -0
- package/dist/turn/context-pressure.js +21 -0
- package/dist/turn/context-pressure.js.map +1 -0
- package/dist/turn/events-to-steps.d.ts +8 -0
- package/dist/turn/events-to-steps.d.ts.map +1 -0
- package/dist/turn/events-to-steps.js +64 -0
- package/dist/turn/events-to-steps.js.map +1 -0
- package/dist/turn/index.d.ts +17 -0
- package/dist/turn/index.d.ts.map +1 -0
- package/dist/turn/index.js +16 -0
- package/dist/turn/index.js.map +1 -0
- package/dist/turn/json-preview.d.ts +22 -0
- package/dist/turn/json-preview.d.ts.map +1 -0
- package/dist/turn/json-preview.js +34 -0
- package/dist/turn/json-preview.js.map +1 -0
- package/dist/turn/json-string-field.d.ts +30 -0
- package/dist/turn/json-string-field.d.ts.map +1 -0
- package/dist/turn/json-string-field.js +125 -0
- package/dist/turn/json-string-field.js.map +1 -0
- package/dist/turn/loop-reminder.d.ts +79 -0
- package/dist/turn/loop-reminder.d.ts.map +1 -0
- package/dist/turn/loop-reminder.js +0 -0
- package/dist/turn/loop-reminder.js.map +1 -0
- package/dist/turn/nul-safe.d.ts +21 -0
- package/dist/turn/nul-safe.d.ts.map +1 -0
- package/dist/turn/nul-safe.js +23 -0
- package/dist/turn/nul-safe.js.map +1 -0
- package/dist/turn/parts-from-events.d.ts +71 -0
- package/dist/turn/parts-from-events.d.ts.map +1 -0
- package/dist/turn/parts-from-events.js +217 -0
- package/dist/turn/parts-from-events.js.map +1 -0
- package/dist/turn/parts-to-model-messages.d.ts +158 -0
- package/dist/turn/parts-to-model-messages.d.ts.map +1 -0
- package/dist/turn/parts-to-model-messages.js +334 -0
- package/dist/turn/parts-to-model-messages.js.map +1 -0
- package/dist/turn/pending-work.d.ts +10 -0
- package/dist/turn/pending-work.d.ts.map +1 -0
- package/dist/turn/pending-work.js +14 -0
- package/dist/turn/pending-work.js.map +1 -0
- package/dist/turn/provider-error.d.ts +45 -0
- package/dist/turn/provider-error.d.ts.map +1 -0
- package/dist/turn/provider-error.js +154 -0
- package/dist/turn/provider-error.js.map +1 -0
- package/dist/turn/tool-input-preview.d.ts +94 -0
- package/dist/turn/tool-input-preview.d.ts.map +1 -0
- package/dist/turn/tool-input-preview.js +143 -0
- package/dist/turn/tool-input-preview.js.map +1 -0
- package/dist/turn/tool-input-progress.d.ts +47 -0
- package/dist/turn/tool-input-progress.d.ts.map +1 -0
- package/dist/turn/tool-input-progress.js +50 -0
- package/dist/turn/tool-input-progress.js.map +1 -0
- package/dist/turn/turn-envelope.d.ts +184 -0
- package/dist/turn/turn-envelope.d.ts.map +1 -0
- package/dist/turn/turn-envelope.js +2 -0
- package/dist/turn/turn-envelope.js.map +1 -0
- package/dist/turn/turn-journal.d.ts +49 -0
- package/dist/turn/turn-journal.d.ts.map +1 -0
- package/dist/turn/turn-journal.js +51 -0
- package/dist/turn/turn-journal.js.map +1 -0
- package/dist/turn/turn-run.d.ts +487 -0
- package/dist/turn/turn-run.d.ts.map +1 -0
- package/dist/turn/turn-run.js +1167 -0
- package/dist/turn/turn-run.js.map +1 -0
- package/dist/turn/usage.d.ts +27 -0
- package/dist/turn/usage.d.ts.map +1 -0
- package/dist/turn/usage.js +51 -0
- package/dist/turn/usage.js.map +1 -0
- package/package.json +59 -3
- package/src/agent-extensions.ts +33 -0
- package/src/builtins/ask-outcome.ts +168 -0
- package/src/builtins/ask-schema.ts +186 -0
- package/src/builtins/ask.service.ts +482 -0
- package/src/builtins/ask.tool.ts +138 -0
- package/src/builtins/index.ts +25 -0
- package/src/builtins/todo-schema.ts +108 -0
- package/src/builtins/todo-settle.hook.ts +221 -0
- package/src/builtins/todo.tool.ts +134 -0
- package/src/context/context-budget-tracker.ts +519 -0
- package/src/context/context-budget.ts +124 -0
- package/src/context/index.ts +17 -0
- package/src/extensions/repeat-call.hook.ts +77 -0
- package/src/hooks/index.ts +19 -0
- package/src/hooks/turn-hook.registry.ts +307 -0
- package/src/hooks/turn-hook.types.ts +210 -0
- package/src/images/byte-cache.ts +61 -0
- package/src/images/delivery.ts +508 -0
- package/src/images/index.ts +35 -0
- package/src/images/prompt.ts +289 -0
- package/src/images/vendor-files.ts +235 -0
- package/src/in-process/conversation-store.ts +304 -0
- package/src/in-process/coordination.ts +177 -0
- package/src/in-process/image-source.ts +29 -0
- package/src/in-process/index.ts +52 -0
- package/src/in-process/question-store.ts +155 -0
- package/src/in-process/run-store.ts +115 -0
- package/src/in-process/session-store.ts +118 -0
- package/src/in-process/stream-bus.ts +244 -0
- package/src/in-process/vendor-file-cache.ts +67 -0
- package/src/index.ts +28 -0
- package/src/loop/active-tick.registry.ts +49 -0
- package/src/loop/index.ts +25 -0
- package/src/loop/loop-driver.ts +275 -0
- package/src/loop/message-hub.ts +532 -0
- package/src/loop/orphan-run.sweeper.ts +204 -0
- package/src/loop/root-host.ts +119 -0
- package/src/ports/context-store.ts +71 -0
- package/src/ports/conversation-store.ts +165 -0
- package/src/ports/coordination.ts +81 -0
- package/src/ports/image-source.ts +26 -0
- package/src/ports/index.ts +56 -0
- package/src/ports/logger.ts +34 -0
- package/src/ports/question-store.ts +117 -0
- package/src/ports/run-store.ts +69 -0
- package/src/ports/session-store.ts +80 -0
- package/src/ports/stream-bus.ts +59 -0
- package/src/ports/vendor-file-cache.ts +54 -0
- package/src/schema/agent-event.ts +69 -0
- package/src/schema/agent-run.ts +44 -0
- package/src/schema/index.ts +25 -0
- package/src/schema/message-part.ts +100 -0
- package/src/subagent/delegate.tool.ts +476 -0
- package/src/subagent/index.ts +63 -0
- package/src/subagent/milestone-body.ts +144 -0
- package/src/subagent/output-scan.ts +56 -0
- package/src/subagent/registry-spawn-policy.ts +85 -0
- package/src/subagent/roster-block.ts +103 -0
- package/src/subagent/situation-block.ts +83 -0
- package/src/subagent/spawn-guards.ts +54 -0
- package/src/subagent/subagent-registry.ts +283 -0
- package/src/subagent/subagent-sessions.ts +496 -0
- package/src/testing/contracts.ts +882 -0
- package/src/testing/index.ts +14 -0
- package/src/testing/stub.ts +28 -0
- package/src/tools/agent-tool.base.ts +361 -0
- package/src/tools/agent-tool.interface.ts +101 -0
- package/src/tools/builtin-names.ts +26 -0
- package/src/tools/index.ts +39 -0
- package/src/tools/tool-definition.ts +93 -0
- package/src/tools/tool-meta.ts +60 -0
- package/src/tools/tool-registry.ts +513 -0
- package/src/tools/tool-result.ts +45 -0
- package/src/tools/tool-wire.ts +24 -0
- package/src/turn/agent-runtime.ts +43 -0
- package/src/turn/chunk-projection.ts +81 -0
- package/src/turn/compaction.ts +103 -0
- package/src/turn/context-overflow.ts +54 -0
- package/src/turn/context-pressure.ts +114 -0
- package/src/turn/events-to-steps.ts +73 -0
- package/src/turn/index.ts +71 -0
- package/src/turn/json-preview.ts +36 -0
- package/src/turn/json-string-field.ts +134 -0
- package/src/turn/loop-reminder.ts +0 -0
- package/src/turn/nul-safe.ts +22 -0
- package/src/turn/parts-from-events.ts +248 -0
- package/src/turn/parts-to-model-messages.ts +428 -0
- package/src/turn/pending-work.ts +14 -0
- package/src/turn/provider-error.ts +160 -0
- package/src/turn/tool-input-preview.ts +223 -0
- package/src/turn/tool-input-progress.ts +76 -0
- package/src/turn/turn-envelope.ts +185 -0
- package/src/turn/turn-journal.ts +102 -0
- package/src/turn/turn-run.ts +1479 -0
- package/src/turn/usage.ts +56 -0
- package/README.md +0 -3
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { wrapSubagentResult } from '../subagent/milestone-body.js';
|
|
3
|
+
import { wrapSystemReminder } from '../turn/loop-reminder.js';
|
|
4
|
+
/**
|
|
5
|
+
* 「这批 parts 是否值得落一条 assistant chat_message」的判据——单纯的空
|
|
6
|
+
* text part(`{type:'text',text:''}`)不算,其余任意 part(非空 text /
|
|
7
|
+
* tool-call / tool-result / reasoning)都算。
|
|
8
|
+
*
|
|
9
|
+
* 两个消费方(`record` 跳过全空的一步、`close` 判这一轮是否留下过东西)**必须
|
|
10
|
+
* 用同一份**:两处对「有没有内容」的认定一分叉,就会有一批 part 落不进库、或
|
|
11
|
+
* 者一条空气泡凭空出现。
|
|
12
|
+
*/
|
|
13
|
+
function hasMeaningfulParts(parts) {
|
|
14
|
+
return parts.some(p => p.type !== 'text' || p.text.trim().length > 0);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 一轮的记录器 —— `openTurn` 造,`close` 收,**一轮一个**。
|
|
18
|
+
*
|
|
19
|
+
* 它存在的理由是「这一轮落过什么」需要一个家:那两笔记账(领到过消息没有、
|
|
20
|
+
* 落过 assistant 段没有)过去是 `buildRootHost` 里的两个闭包变量,中心这边则
|
|
21
|
+
* 只有 `openTurn` 没有收尾点。**刻意不做成中心里的 `Map<runId, …>`**:那张表
|
|
22
|
+
* 要在三条终态路径上都记得删,漏一条漏一类会话,症状是内存慢慢涨(同
|
|
23
|
+
* `TurnContext.turnState` 那条判据)。生命周期跟着对象走,结构上不可能泄漏。
|
|
24
|
+
*
|
|
25
|
+
* **三位一体的 id 在这里**:`runId` = `streamId` = 本轮 assistant `chat_message`
|
|
26
|
+
* 行的主键 = `AgentEvent.messageId`。前端靠 `messageId` 把流式增量路由到气泡
|
|
27
|
+
* (`chunk.id`),而「`messageId` 恒等于 `runId`」是「换轮」那一轮的产物——在那
|
|
28
|
+
* 之前它们是两个东西,靠一族分段判据互相对应。拆开来各生成各的,等于把那族
|
|
29
|
+
* 判据原样请回来。
|
|
30
|
+
*/
|
|
31
|
+
export class TurnRecorder {
|
|
32
|
+
hub;
|
|
33
|
+
sessionId;
|
|
34
|
+
runId;
|
|
35
|
+
streamId;
|
|
36
|
+
/**
|
|
37
|
+
* 这一轮有没有从 inbox 领到过东西。与 `wrote` 一起把两件在收尾时长得一模一样
|
|
38
|
+
* 的事分开:「模型被问了话但一个字没说」(该留一条可见占位)与「压根没有输入
|
|
39
|
+
* 可跑」(该一行都不落)。两者的终态都是 completed、都没落过任何 step。
|
|
40
|
+
*/
|
|
41
|
+
drained = false;
|
|
42
|
+
/** 这一轮有没有真的落过 assistant 段(`close` 拿它决定要不要补一条)。 */
|
|
43
|
+
wrote = false;
|
|
44
|
+
/** 最近一次落库覆盖到的事件 seq(`metadata.flushedSeq`),收尾时原样保留。 */
|
|
45
|
+
flushedSeq = null;
|
|
46
|
+
/**
|
|
47
|
+
* 本轮「开跑」事件的服务端时刻(ms),落进 `metadata.runStartedAt`。
|
|
48
|
+
*
|
|
49
|
+
* 前端运行状态行的「已跑 N 秒」靠它:开跑事件在第一次落库后就从会话流里
|
|
50
|
+
* 退役了,刷新之后流里再也找不到这一轮从什么时候开始——没有这一列就只能按
|
|
51
|
+
* 前端本地计时,刷新一次数字就从零重来。取**事件的 `ts`** 而不是在这里
|
|
52
|
+
* `Date.now()`:与流里那条开跑事件是同一个数,刷新前后显示不跳。
|
|
53
|
+
*/
|
|
54
|
+
runStartedAt = null;
|
|
55
|
+
constructor(hub, sessionId, runId, streamId) {
|
|
56
|
+
this.hub = hub;
|
|
57
|
+
this.sessionId = sessionId;
|
|
58
|
+
this.runId = runId;
|
|
59
|
+
this.streamId = streamId;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 本轮的一条事件出去(`RunTurnArgs.sink` 接的就是这里)。
|
|
63
|
+
*
|
|
64
|
+
* **这是两条通道汇合的那一点**:同一个对象既往 `chat_message` 写,也往流上
|
|
65
|
+
* 发。此前 SSE 是内核直连总线(`sink: e => bus.publish(e)` 写在 loop 的
|
|
66
|
+
* `runTick` 里)、落库绕回会话层,两条路从来没在同一个地方碰过头——而「同一次
|
|
67
|
+
* 工具调用在流里和库里长得不一样」正是从那里长出来的(那次分叉已经由「落库
|
|
68
|
+
* 只从事件账本重建」修掉,这一步是把结构本身补齐:`bus.publish` 全仓只剩这
|
|
69
|
+
* 一个调用点,`TurnRecorder` 是「这一轮怎么到达外面」的完整答案)。
|
|
70
|
+
*
|
|
71
|
+
* **内核仍然不认识总线**:它只知道一个同步投递口(判据见 `RunTurnArgs.sink`),
|
|
72
|
+
* 这里是那个口的下游。**同步**:账本 `append` 是同步可回读的,投递不能反过来
|
|
73
|
+
* 要求它等(判据见 `TurnJournal`)。
|
|
74
|
+
*
|
|
75
|
+
* 抛错怎么办由账本那一侧管(记 warn、事件照常进账本——观测非承重,绝不能把
|
|
76
|
+
* 一轮成功的生成变成 failed)。
|
|
77
|
+
*
|
|
78
|
+
* **会话级事件不走这里**(`publishSessionEvent`:自动命名、孤儿 sweep 的补发
|
|
79
|
+
* run-finish):它们没有正在跑的这一轮,也就没有 recorder;它们自己会话面
|
|
80
|
+
* 分配游标,见 `StreamBus.publishSessionEvent`。
|
|
81
|
+
*/
|
|
82
|
+
emit(event) {
|
|
83
|
+
// 按 runId 认「本轮自己的」开跑:同一个 sink 上还会流过子 Agent 的事件。
|
|
84
|
+
if (event.type === 'run-start' &&
|
|
85
|
+
event.runId === this.runId &&
|
|
86
|
+
this.runStartedAt === null) {
|
|
87
|
+
this.runStartedAt = event.ts;
|
|
88
|
+
}
|
|
89
|
+
this.hub.publish(event);
|
|
90
|
+
}
|
|
91
|
+
/** 取出本轮要处理的消息(落库在同一事务里,见 `MessageHub.take`)。 */
|
|
92
|
+
async take() {
|
|
93
|
+
const out = await this.hub.take(this.sessionId);
|
|
94
|
+
this.drained ||= out.length > 0;
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
/** 探一眼本会话的 inbox 还有没有排队的(换轮判据,只探不取)。 */
|
|
98
|
+
hasPending() {
|
|
99
|
+
return this.hub.hasPending(this.sessionId);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 本轮又产出了这一截 parts —— 增量落进 `runId` 那一行(首次 INSERT,之后
|
|
103
|
+
* jsonb 追加)。全空的一步直接跳过,不留一条空气泡、也不翻「落过」的账。
|
|
104
|
+
*/
|
|
105
|
+
async record(parts, uptoSeq = null) {
|
|
106
|
+
if (!hasMeaningfulParts(parts))
|
|
107
|
+
return;
|
|
108
|
+
await this.hub.appendAssistantStep({
|
|
109
|
+
messageId: this.runId,
|
|
110
|
+
runId: this.runId,
|
|
111
|
+
sessionId: this.sessionId,
|
|
112
|
+
parts,
|
|
113
|
+
flushedSeq: uptoSeq,
|
|
114
|
+
runStartedAt: this.runStartedAt,
|
|
115
|
+
});
|
|
116
|
+
if (uptoSeq != null)
|
|
117
|
+
this.flushedSeq = uptoSeq;
|
|
118
|
+
// **写成功了才算落过**。提前置位的话,一轮里每次写库都失败时 `close` 会跳过
|
|
119
|
+
// 占位、直接去 finalize 一条不存在的行(UPDATE 0 行、静默)——这一轮在流里
|
|
120
|
+
// 出现过、刷新后却什么都没有,看起来像系统把回复吃了。置位放在 await 之后,
|
|
121
|
+
// 全部失败时 `close` 至少会补一条可见占位(终态是 failed,文案会说原因)。
|
|
122
|
+
this.wrote = true;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 收尾:盖终态 metadata 与整轮 usage。
|
|
126
|
+
*
|
|
127
|
+
* 三条路,**判据全在这一个方法里**(过去分散在宿主的 `persist` 与内核的
|
|
128
|
+
* `TurnResult.parts` 之间):
|
|
129
|
+
*
|
|
130
|
+
* 1. **空转轮**(没领到、没落过、且 completed)→ **一行都不落**。占位文案说的
|
|
131
|
+
* 是「模型本轮没有返回任何内容」,而这一轮模型压根没被问过话;落下去就是
|
|
132
|
+
* 一条凭空出现的助手气泡,更要命的是子会话的 `finalizeIfIdle` 会把它当成
|
|
133
|
+
* 这一轮的新产出回投给父。成因是 wake 与真正 drain 之间那段窗口里那批货
|
|
134
|
+
* 没了(最常见的是用户在 QueueBar 上撤回)。
|
|
135
|
+
* **限定 completed**:failed / aborted / rejected 即使零产出也必须留下可见
|
|
136
|
+
* 痕迹,那才是占位文案存在的理由。
|
|
137
|
+
* 2. **一个字都没落过**(但被问过话,或终态不是 completed)→ 补一条可见占位。
|
|
138
|
+
* 3. **落过** → 只盖终态,不再追加任何 parts。
|
|
139
|
+
*
|
|
140
|
+
* @returns 这一轮在对话流里留下东西了没有。宿主据此决定要不要安排自动命名
|
|
141
|
+
* (空转轮没有任何新消息,命名的材料都不存在)。
|
|
142
|
+
*/
|
|
143
|
+
async close(terminal) {
|
|
144
|
+
if (!this.drained && !this.wrote && terminal.status === 'completed') {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
if (!this.wrote) {
|
|
148
|
+
await this.record([
|
|
149
|
+
{ type: 'text', text: emptyReplyPlaceholder(terminal) },
|
|
150
|
+
]);
|
|
151
|
+
}
|
|
152
|
+
await this.hub.finalizeAssistantTurn({
|
|
153
|
+
messageId: this.runId,
|
|
154
|
+
runId: this.runId,
|
|
155
|
+
metadata: {
|
|
156
|
+
// 终态整体重写 metadata,落库边界要跟着带过去——前端刷新后仍靠它把
|
|
157
|
+
// 宽限期内重放的事件丢掉。
|
|
158
|
+
...(this.flushedSeq != null ? { flushedSeq: this.flushedSeq } : {}),
|
|
159
|
+
...(this.runStartedAt != null
|
|
160
|
+
? { runStartedAt: this.runStartedAt }
|
|
161
|
+
: {}),
|
|
162
|
+
status: terminal.status,
|
|
163
|
+
stopReason: terminal.stopReason,
|
|
164
|
+
...(terminal.error ? { error: terminal.error } : {}),
|
|
165
|
+
...terminal.metadata,
|
|
166
|
+
},
|
|
167
|
+
usage: terminal.usage,
|
|
168
|
+
});
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 零产出时的可见文案,带上原因让用户知道发生了什么。
|
|
174
|
+
*
|
|
175
|
+
* **`error` 优先于 `stopReason`**:失败路径上 stopReason 一律是那个常量
|
|
176
|
+
* `'error'`,「原因:error」等于没说——真正的解释在 `error` 里(内核已经把
|
|
177
|
+
* provider 的原话归一化成中文,见 `provider-error.ts`)。stopReason 只在没有
|
|
178
|
+
* error 时兜底,它对 aborted/rejected 那两类才是有信息的。
|
|
179
|
+
*/
|
|
180
|
+
function emptyReplyPlaceholder(t) {
|
|
181
|
+
const detail = t.error ?? t.stopReason;
|
|
182
|
+
const reason = detail ? `,原因:${detail}` : '';
|
|
183
|
+
switch (t.status) {
|
|
184
|
+
case 'aborted':
|
|
185
|
+
return `本轮已中断,且未产生任何内容${reason}`;
|
|
186
|
+
case 'failed':
|
|
187
|
+
return `本轮生成失败,未产生任何内容${reason}`;
|
|
188
|
+
case 'rejected':
|
|
189
|
+
return `本轮被拦截,未产生任何内容${reason}`;
|
|
190
|
+
default:
|
|
191
|
+
return `模型本轮没有返回任何内容${reason}`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* 取 parts 里的文本(子 Agent 回执包围栏时用)。里程碑 payload 当前恒是单个
|
|
196
|
+
* text part(`finalizeIfIdle` 写死),拼接只是不对这一点做硬假设。
|
|
197
|
+
*/
|
|
198
|
+
function textOfParts(parts) {
|
|
199
|
+
return parts
|
|
200
|
+
.filter((p) => p.type === 'text')
|
|
201
|
+
.map(p => p.text)
|
|
202
|
+
.join('\n');
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* inbox 行 → 内核的 `DrainedTurnMessage`。
|
|
206
|
+
*
|
|
207
|
+
* **落库与注入模型是两份形态**:`parts` 是纯正文(前端回执气泡直接显示它),
|
|
208
|
+
* `modelParts` 把同一段正文包进 `<subagent-result …>` 围栏 —— 子 Agent 的产出是
|
|
209
|
+
* 不可信外部输入,裸拼的话它与之后的平台文案在字节层面无从区分(见
|
|
210
|
+
* `milestone-body.ts#wrapSubagentResult`)。围栏不落库:落库的是数据,围栏是
|
|
211
|
+
* 呈现层,否则前端还得把标签再剥回去。
|
|
212
|
+
*
|
|
213
|
+
* `source`(toolName/handle/status/stopReason)经 metadata 落进 `chat_message`,
|
|
214
|
+
* 前端据它认出回执并打状态 Tag —— **不从正文里用正则抠 handle**。
|
|
215
|
+
*/
|
|
216
|
+
function toTurnMessage(d) {
|
|
217
|
+
if (d.kind === 'system_reminder') {
|
|
218
|
+
// 与 tool_result 同一条分工:落库纯正文 + `metadata.kind`,围栏只进模型。
|
|
219
|
+
// 刷新后从库里重建时由投影层按同一个 kind 再包一次(`wrapStoredUserText`),
|
|
220
|
+
// 两条路读的是同一个标记。
|
|
221
|
+
const kind = typeof d.source?.kind === 'string' ? d.source.kind : null;
|
|
222
|
+
if (!kind) {
|
|
223
|
+
throw new Error('system_reminder inbox row must carry source.kind');
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
id: d.messageId,
|
|
227
|
+
parts: d.parts,
|
|
228
|
+
modelParts: [
|
|
229
|
+
{
|
|
230
|
+
type: 'text',
|
|
231
|
+
text: wrapSystemReminder(textOfParts(d.parts)),
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
// `source` 整个落进 metadata:投递方随行带的判据(如待办提醒的完成数)
|
|
235
|
+
// 要经 `TurnContext.inbound` 回到它自己手里;`kind` 是必带的那一个。
|
|
236
|
+
metadata: { ...d.source, kind },
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if (d.kind !== 'tool_result')
|
|
240
|
+
return { id: d.messageId, parts: d.parts };
|
|
241
|
+
const s = (d.source ?? {});
|
|
242
|
+
return {
|
|
243
|
+
id: d.messageId,
|
|
244
|
+
parts: d.parts,
|
|
245
|
+
modelParts: [
|
|
246
|
+
{
|
|
247
|
+
type: 'text',
|
|
248
|
+
text: wrapSubagentResult(textOfParts(d.parts), {
|
|
249
|
+
handle: s.handle,
|
|
250
|
+
status: s.status,
|
|
251
|
+
reason: s.stopReason,
|
|
252
|
+
}),
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
metadata: { source: d.source },
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/** 进程被杀、一个字都没落库就中断的那一轮补的可见正文(会随历史喂回模型,故写的是事实)。 */
|
|
259
|
+
export const INTERRUPTED_PLACEHOLDER = '本轮已中断(服务重启),未产生任何内容。';
|
|
260
|
+
/**
|
|
261
|
+
* 消息中心:会话里「一条消息」的产生、排队、落库与寻址,只此一处。
|
|
262
|
+
*
|
|
263
|
+
* ## 边界
|
|
264
|
+
*
|
|
265
|
+
* **中心是 `ConversationStore` 写方法的唯一调用方**(`ContextStore` 那三样除外:
|
|
266
|
+
* 上下文预算的 tracker 直接用,那是 agent-base 里就有的分工——决策归预算,
|
|
267
|
+
* checkpoint 落库在那边也经中心,这里由端口的原子契约代替)。宿主要投递消息走
|
|
268
|
+
* `post`,别直接 `store.enqueue`:消息主键的铸造、取出时的形态换算都在这里。
|
|
269
|
+
*
|
|
270
|
+
* **不归中心的**:tick 调度 / 会话锁 / 续租是 loop(`LoopDriver`)的活;跑次归
|
|
271
|
+
* `RunStore`;上下文预算的决策归 `ContextBudgetTracker`;内核的工作内存与事件
|
|
272
|
+
* 账本归 `TurnRun`(账本要被内核同步回读,中心只可能是它的下游 sink)。
|
|
273
|
+
*/
|
|
274
|
+
export class MessageHub {
|
|
275
|
+
store;
|
|
276
|
+
bus;
|
|
277
|
+
constructor(store,
|
|
278
|
+
// 本轮事件的去向(`TurnRecorder.emit` 的下游)。**唯一的 `bus.publish` 调用点**。
|
|
279
|
+
bus) {
|
|
280
|
+
this.store = store;
|
|
281
|
+
this.bus = bus;
|
|
282
|
+
}
|
|
283
|
+
/** run 级事件投递。只有 `TurnRecorder.emit` 调它,公开只为让它能被替身观测。 */
|
|
284
|
+
publish(event) {
|
|
285
|
+
this.bus.publish(event);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* 投递。**所有入口唯一的一个**(用户发言、派生子 Agent 的首个 prompt、追加任务、
|
|
289
|
+
* 里程碑回投)。落库用的 id 在这里产生并返回:前端拿它做气泡收敛,必须与库里
|
|
290
|
+
* 那一行同源。
|
|
291
|
+
*
|
|
292
|
+
* **不负责唤醒**:投递方紧接着自己 `wake`(或用 `LoopDriver.post`,两步一起)。
|
|
293
|
+
*/
|
|
294
|
+
async post(input) {
|
|
295
|
+
const messageId = randomUUID();
|
|
296
|
+
await this.store.enqueue({
|
|
297
|
+
sessionId: input.sessionId,
|
|
298
|
+
kind: input.kind,
|
|
299
|
+
sourceKind: input.sourceKind,
|
|
300
|
+
sourceUserId: input.sourceUserId ?? null,
|
|
301
|
+
source: input.source ?? null,
|
|
302
|
+
parts: input.parts,
|
|
303
|
+
messageId,
|
|
304
|
+
});
|
|
305
|
+
return { messageId };
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* 取出本会话待处理的全部消息,**并在同一个事务里落库**(判据在
|
|
309
|
+
* `ConversationStore.takeInbox`),返回内核要的形态。
|
|
310
|
+
*
|
|
311
|
+
* **一轮只被调一次**(内核的第一次迭代,模型开口之前):轮内后来进来的消息由
|
|
312
|
+
* `hasPending` 探到后换轮,留给下一个 tick 的这同一个点。所以这里刚落库的
|
|
313
|
+
* user 行永远早于本轮的任何 assistant 输出。
|
|
314
|
+
*/
|
|
315
|
+
async take(sessionId) {
|
|
316
|
+
const taken = await this.store.takeInbox(sessionId, item => {
|
|
317
|
+
const m = toTurnMessage(item);
|
|
318
|
+
return {
|
|
319
|
+
id: m.id,
|
|
320
|
+
sessionId,
|
|
321
|
+
role: 'user',
|
|
322
|
+
parts: m.parts,
|
|
323
|
+
...(m.metadata ? { metadata: m.metadata } : {}),
|
|
324
|
+
};
|
|
325
|
+
});
|
|
326
|
+
// 回填落库后的真实 id:内核随后把它随 `inbox-drained` 事件推给前端就地插
|
|
327
|
+
// 气泡,而之后的 refetch 要按同一个 id 收敛掉那条气泡。
|
|
328
|
+
return taken.map(({ item, message }) => ({
|
|
329
|
+
...toTurnMessage(item),
|
|
330
|
+
id: message.id,
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* 只探不取。换轮判据(内核每次调模型前探一下,见 `TurnHost.hasPendingInbox`),
|
|
335
|
+
* 以及 loop / sweep 判「这个会话还有没有货」的同一个问题。
|
|
336
|
+
*/
|
|
337
|
+
hasPending(sessionId) {
|
|
338
|
+
return this.store.hasPending(sessionId);
|
|
339
|
+
}
|
|
340
|
+
/** 撤回:只删「自己的」「还没被取走的」那一项。 */
|
|
341
|
+
withdraw(id, userId) {
|
|
342
|
+
return this.store.withdraw(id, userId);
|
|
343
|
+
}
|
|
344
|
+
/** 本会话的待处理队列。 */
|
|
345
|
+
listPending(sessionId) {
|
|
346
|
+
return this.store.listPending(sessionId);
|
|
347
|
+
}
|
|
348
|
+
/** 此刻还有待处理项的全部会话 id。供启动时补唤醒(wake 是瞬时广播,inbox 是持久的)。 */
|
|
349
|
+
listSessionIdsWithPending() {
|
|
350
|
+
return this.store.listSessionIdsWithPending();
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* 一轮开张:铸那个**三位一体**的 id(`runId` = `streamId` = 本轮 assistant 行主键
|
|
354
|
+
* = `AgentEvent.messageId`),返回本轮的记录器。值本身只是一个 uuid,这个方法的
|
|
355
|
+
* 意义是**只有一处会铸它**。
|
|
356
|
+
*/
|
|
357
|
+
openTurn(sessionId) {
|
|
358
|
+
const id = randomUUID();
|
|
359
|
+
return new TurnRecorder(this, sessionId, id, id);
|
|
360
|
+
}
|
|
361
|
+
/** 落一条消息(按 id 幂等,见 `ConversationStore.appendMessage`)。 */
|
|
362
|
+
appendMessage(message) {
|
|
363
|
+
return this.store.appendMessage(message);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* setup 阶段失败的可见占位(会话 / agent / 模型解析就抛错,流从未开、`runTurn`
|
|
367
|
+
* 根本没跑)——不补这条用户会看到彻底的沉默:消息已经进了 inbox,界面上什么都
|
|
368
|
+
* 不会发生。文案由调用方定(`LoopHost.describeSetupError`)。
|
|
369
|
+
*/
|
|
370
|
+
async appendSetupError(sessionId, text) {
|
|
371
|
+
await this.store.appendMessage({
|
|
372
|
+
sessionId,
|
|
373
|
+
role: 'assistant',
|
|
374
|
+
parts: [{ type: 'text', text }],
|
|
375
|
+
metadata: { status: 'failed', stopReason: 'setup-error' },
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* assistant 段落的落库原语(`TurnRecorder.record` 用)。首次建行、之后追加。
|
|
380
|
+
*
|
|
381
|
+
* `flushedSeq`:这批 parts 覆盖到的最后一个事件的 seq,**与 parts 同一次写入**
|
|
382
|
+
* `metadata.flushedSeq`,写成功后才让会话流退役 seq ≤ 它的事件——分开写的话会
|
|
383
|
+
* 出现「流里已经删了、库里的边界还是旧的」,刷新后前端按旧边界去重,把不该丢的
|
|
384
|
+
* 尾巴当成重放丢掉。
|
|
385
|
+
*/
|
|
386
|
+
async appendAssistantStep(opts) {
|
|
387
|
+
await this.store.appendAssistantStep({
|
|
388
|
+
messageId: opts.messageId,
|
|
389
|
+
runId: opts.runId,
|
|
390
|
+
sessionId: opts.sessionId,
|
|
391
|
+
parts: opts.parts,
|
|
392
|
+
metadataPatch: {
|
|
393
|
+
...(opts.flushedSeq != null ? { flushedSeq: opts.flushedSeq } : {}),
|
|
394
|
+
...(opts.runStartedAt != null
|
|
395
|
+
? { runStartedAt: opts.runStartedAt }
|
|
396
|
+
: {}),
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
if (opts.flushedSeq != null) {
|
|
400
|
+
this.bus.retireUpTo(opts.runId, opts.flushedSeq);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/** 一轮收尾:在 `messageId`(= runId)那一行上盖终态 metadata 与整轮 usage。 */
|
|
404
|
+
finalizeAssistantTurn(opts) {
|
|
405
|
+
return this.store.finalizeAssistantTurn(opts);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* 收尾一轮被进程死亡打断的轮次在对话流里的痕迹(`OrphanRunSweeper` 用),返回受
|
|
409
|
+
* 影响的行 id。
|
|
410
|
+
*
|
|
411
|
+
* 两条路,判据是「有没有落过库的 assistant 段」:
|
|
412
|
+
* - **产出过** → 只给还没盖终态的段盖上。已产出的正文原样保留,不追加任何
|
|
413
|
+
* 解释性文字——那会把模型没说过的话写进它的历史。
|
|
414
|
+
* - **一个字都没落库**(run 刚 open 就被杀)→ 补一条可见占位。不补的话用户
|
|
415
|
+
* 那句话孤零零挂着、下面什么都没有,看起来像系统把消息吃了。
|
|
416
|
+
*
|
|
417
|
+
* 会话已删(`sessionId` 为 null)时补不了占位,也没必要。
|
|
418
|
+
*/
|
|
419
|
+
async closeInterruptedTurn(runId, sessionId) {
|
|
420
|
+
const segments = await this.store.listTurnSegmentIds(runId);
|
|
421
|
+
if (segments.length > 0 || !sessionId) {
|
|
422
|
+
return this.store.finalizeInterruptedTurn(runId);
|
|
423
|
+
}
|
|
424
|
+
// 第 0 段的行 id 就是 runId(见 `openTurn`)。
|
|
425
|
+
await this.store.appendAssistantStep({
|
|
426
|
+
messageId: runId,
|
|
427
|
+
runId,
|
|
428
|
+
sessionId,
|
|
429
|
+
parts: [{ type: 'text', text: INTERRUPTED_PLACEHOLDER }],
|
|
430
|
+
});
|
|
431
|
+
await this.store.finalizeAssistantTurn({
|
|
432
|
+
messageId: runId,
|
|
433
|
+
runId,
|
|
434
|
+
metadata: { status: 'aborted', stopReason: 'aborted' },
|
|
435
|
+
});
|
|
436
|
+
return [runId];
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=message-hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-hub.js","sourceRoot":"","sources":["../../src/loop/message-hub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type SessionLock, type WakeChannel } from '../ports/coordination.js';
|
|
2
|
+
import { type Logger } from '../ports/logger.js';
|
|
3
|
+
import type { RunStore, StaleRun } from '../ports/run-store.js';
|
|
4
|
+
import type { StreamBus } from '../ports/stream-bus.js';
|
|
5
|
+
import type { MessageHub } from './message-hub.js';
|
|
6
|
+
/**
|
|
7
|
+
* 两次 sweep 的间隔。也是「进程被杀后多久那一轮才会被收尾」的上界之一——
|
|
8
|
+
* 另一个是会话锁的自然过期(`LOCK_TTL_MS`),两者相加即最坏延迟。
|
|
9
|
+
*/
|
|
10
|
+
export declare const SWEEP_INTERVAL_MS = 60000;
|
|
11
|
+
/** run 开跑多久之后才纳入候选:给「run 刚记下、锁的抢占与本次探测交叉」留出宽限。 */
|
|
12
|
+
export declare const ORPHAN_MIN_AGE_MS = 60000;
|
|
13
|
+
export declare const INTERRUPTED_ERROR = "\u670D\u52A1\u4E2D\u65AD\uFF08\u8FDB\u7A0B\u91CD\u542F\uFF09\uFF0C\u672C\u8F6E\u672A\u8DD1\u5B8C\u3002";
|
|
14
|
+
export interface OrphanRunSweeperDeps {
|
|
15
|
+
runs: RunStore;
|
|
16
|
+
lock: SessionLock;
|
|
17
|
+
wake: WakeChannel;
|
|
18
|
+
hub: MessageHub;
|
|
19
|
+
bus: StreamBus;
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
/**
|
|
22
|
+
* 宿主挂在这一轮上的同步等待一并作废(提问面板、确认面板……):那一轮可能正死在
|
|
23
|
+
* 「等用户回答」上,留着它用户对着的是一个答了也没人接的面板。只对有会话的孤儿调。
|
|
24
|
+
*
|
|
25
|
+
* **抛错不影响收尾的其余几步**(照样补发 run-finish),只记日志。
|
|
26
|
+
*/
|
|
27
|
+
onRunOrphaned?(run: StaleRun & {
|
|
28
|
+
sessionId: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
/** 缺省 `SWEEP_INTERVAL_MS`。 */
|
|
31
|
+
intervalMs?: number;
|
|
32
|
+
/** 缺省 `ORPHAN_MIN_AGE_MS`。 */
|
|
33
|
+
minAgeMs?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 收尾「进程被杀留下的半截轮次」。
|
|
37
|
+
*
|
|
38
|
+
* 一轮的终态**只存在于跑它的那个进程的内存里**:跑次的 `finish()`、消息上的终态
|
|
39
|
+
* metadata 都在 tick 跑完那一刻才写。进程没了,这两个写入永远不会发生——跑次永久
|
|
40
|
+
* 停在 running、前端把那条没盖终态的消息当成「一轮真的还在飞」,每次刷新都卡成
|
|
41
|
+
* 「进行中」,点停止也救不回来(活跃登记簿随进程没了)。
|
|
42
|
+
*
|
|
43
|
+
* 判据是 **「该会话此刻有没有 loop 持锁」**:锁在整个 tick 期间持有并定期续租,
|
|
44
|
+
* 而 `finish()` 发生在 `release()` 之前,故「无锁 + 仍 running」是确定的孤儿,多
|
|
45
|
+
* 实例部署下也不会误伤别的实例正在跑的轮次。这条判据继承了会话锁的口径(锁过期 =
|
|
46
|
+
* 跑它的 loop 已经死了),误判的后果也是收敛的:`markInterrupted` 只在仍 running
|
|
47
|
+
* 时翻牌,那个进程后来恢复并 `finish()` 会覆盖成真实终态。
|
|
48
|
+
*
|
|
49
|
+
* **周期跑而不是只在启动跑一次**:进程被杀时会话锁不会主动释放,要等 TTL 自然
|
|
50
|
+
* 过期。启动那一刻锁多半还在,启动那次会(正确地)跳过所有候选。
|
|
51
|
+
*/
|
|
52
|
+
export declare class OrphanRunSweeper {
|
|
53
|
+
private readonly deps;
|
|
54
|
+
private timer?;
|
|
55
|
+
private readonly logger;
|
|
56
|
+
constructor(deps: OrphanRunSweeperDeps);
|
|
57
|
+
/**
|
|
58
|
+
* 启动:立刻扫一次、把 inbox 有积压的会话各叫醒一次,之后周期扫。都是
|
|
59
|
+
* fire-and-forget,绝不阻塞 / 拖垮启动。返回停止函数(同 `dispose`)。
|
|
60
|
+
*/
|
|
61
|
+
start(): () => void;
|
|
62
|
+
dispose(): void;
|
|
63
|
+
/**
|
|
64
|
+
* 扫一轮孤儿 run 并收尾,返回收了几条。no-throw 到单条粒度:一条坏记录不能中断
|
|
65
|
+
* sweep(否则它后面那些本可以修好的轮次会一直卡着)。
|
|
66
|
+
*/
|
|
67
|
+
sweep(): Promise<number>;
|
|
68
|
+
/** 单条候选的处置。返回它是否真的由本次调用收的尾。 */
|
|
69
|
+
private finalizeOrphan;
|
|
70
|
+
private publishRunFinish;
|
|
71
|
+
/**
|
|
72
|
+
* 把「inbox 里还有待处理项」的会话各叫醒一次(wake 是瞬时广播,没有持久化;进程
|
|
73
|
+
* 在「已投递、loop 还没取」之间被杀,那条消息就只剩存储里一行,谁也不会再来叫醒
|
|
74
|
+
* 它)。只在启动跑:正常运行期间 `onWake` 收尾时会自查并重新广播。多实例同时启动
|
|
75
|
+
* 各 wake 一次也无害——抢锁只有一个赢。
|
|
76
|
+
*/
|
|
77
|
+
wakePendingInboxes(): Promise<number>;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=orphan-run.sweeper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orphan-run.sweeper.d.ts","sourceRoot":"","sources":["../../src/loop/orphan-run.sweeper.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,kDAAkD;AAClD,eAAO,MAAM,iBAAiB,QAAc,CAAC;AAE7C,eAAO,MAAM,iBAAiB,2GAAsB,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;IAChB,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,aAAa,CAAC,CAAC,GAAG,EAAE,QAAQ,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,8BAA8B;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAgB;IAIf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,KAAK,CAAC,CAAiC;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEH,IAAI,EAAE,oBAAoB;IAIvD;;;OAGG;IACH,KAAK,IAAI,MAAM,IAAI;IAiBnB,OAAO,IAAI,IAAI;IAKf;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAwB9B,+BAA+B;YACjB,cAAc;IAiC5B,OAAO,CAAC,gBAAgB;IAwBxB;;;;;OAKG;IACG,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;CAkB5C"}
|