@qjp88995/agent-runtime 0.0.0-stage → 0.1.0
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 +55 -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,158 @@
|
|
|
1
|
+
import type { JSONValue, ModelMessage, ToolResultPart } from 'ai';
|
|
2
|
+
import { type MessagePart, type ToolResultImage } from '../schema/index.js';
|
|
3
|
+
export interface StoredMessage {
|
|
4
|
+
role: string;
|
|
5
|
+
parts: MessagePart[];
|
|
6
|
+
/**
|
|
7
|
+
* 该行的 `chat_message.seq`。**只有裁剪/压缩投影用得上**(见
|
|
8
|
+
* `ProjectionOptions`),两个指针都不传时可以不给。
|
|
9
|
+
*/
|
|
10
|
+
seq?: number;
|
|
11
|
+
/**
|
|
12
|
+
* 该行的 `chat_message.metadata.kind`。两个取值,都表示「这条 role='user' 的
|
|
13
|
+
* 行不是用户说的话」,投影时各自包上自己的围栏(见 `wrapStoredUserText`):
|
|
14
|
+
* `COMPACTION_CHECKPOINT_KIND`(压缩产生的交接说明,另外还要提到最前面)与
|
|
15
|
+
* `LOOP_REMINDER_KIND`(重复调用提醒的存量行)与 `TODO_REMINDER_KIND`(待办
|
|
16
|
+
* 结账提醒),以及宿主自己登记的 `ProjectionOptions.reminderKinds`。其余行不带这个字段。
|
|
17
|
+
*/
|
|
18
|
+
kind?: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface ProjectionOptions {
|
|
21
|
+
/**
|
|
22
|
+
* 裁剪指针(`chat_session.pruned_upto_seq`):`seq ≤ 它`的行,tool-result
|
|
23
|
+
* 的正文换成存根。null/undefined = 不裁剪,逐字回到裁剪之前的行为。
|
|
24
|
+
*/
|
|
25
|
+
prunedUptoSeq?: number | null;
|
|
26
|
+
/**
|
|
27
|
+
* 压缩指针(`chat_session.compacted_upto_seq`):`seq ≤ 它`的行**整行不进
|
|
28
|
+
* 上下文**,由 checkpoint 行代表。null/undefined = 未压缩过。
|
|
29
|
+
*
|
|
30
|
+
* 比裁剪更靠后的一级:裁剪只丢工具结果正文,压缩连「调过什么工具」这条事实
|
|
31
|
+
* 一起换成一段自然语言。两个指针同时给时,压缩先生效(被压掉的行根本不会走到
|
|
32
|
+
* 裁剪那一步)。
|
|
33
|
+
*/
|
|
34
|
+
compactedUptoSeq?: number | null;
|
|
35
|
+
/**
|
|
36
|
+
* 宿主自己往会话里塞的 user 行标记(`StoredMessage.kind`),投影时一律包 `<system-reminder>`
|
|
37
|
+
* 围栏(agent-base 分身线的开工消息与通知)。**当轮注入时怎么包,这里就得登记**,
|
|
38
|
+
* 否则重放时它以裸用户文字喂给模型、与当轮不再逐字相同。
|
|
39
|
+
*/
|
|
40
|
+
reminderKinds?: readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* 旧工具名 → 现名(`ToolRegistry.toolNameAliases()`)。历史里 tool-call / tool-result 的
|
|
43
|
+
* `toolName` 命中旧名时换成现名:工具改过名之后,模型在同一段上下文里只该看到一个名字。
|
|
44
|
+
* 库里一个字节不动。
|
|
45
|
+
*/
|
|
46
|
+
toolNameAliases?: ReadonlyMap<string, string>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 被裁掉的工具结果在模型眼里长什么样。
|
|
50
|
+
*
|
|
51
|
+
* **保留工具名与调用参数、只丢正文**:正文才是体积(Read/Grep/Bash 那一族动辄
|
|
52
|
+
* 几万字符),而「我调过 Read('/workspace/x.md')」这件事只要几十个字符,却是模型
|
|
53
|
+
* 判断「要不要再跑一次」的全部依据。只留一句「结果已移除」而不说是哪次调用,
|
|
54
|
+
* 模型既想不起自己看过什么,也无从重跑。
|
|
55
|
+
*
|
|
56
|
+
* 文案明说是**为了腾空间**:这既不是工具失败,也不是结果过期。把预算行为写成
|
|
57
|
+
* 别的措辞,模型会据此下错结论(比如以为那个文件读不到了)。
|
|
58
|
+
*/
|
|
59
|
+
export declare function renderPrunedToolOutput(toolName: string, input: unknown): string;
|
|
60
|
+
/**
|
|
61
|
+
* 一次工具结果在模型眼里长什么样:正文 + 平台针对这次调用追加的那句提示
|
|
62
|
+
* (`MessagePart.systemNote`,当前唯一来源是重复调用提醒)。
|
|
63
|
+
*
|
|
64
|
+
* **拼接只在这里发生**,落库存的是纯正文与独立字段(同 checkpoint /
|
|
65
|
+
* subagent-result 那条分工)。**内核本轮喂给模型的那份也走这个函数**——两条路
|
|
66
|
+
* 各拼一次的话,同一次调用在本轮与下一轮重放时会长得不一样,而「投影是纯函数」
|
|
67
|
+
* 正是要防这个。
|
|
68
|
+
*
|
|
69
|
+
* **不包 `<system-reminder>` 围栏**:那层围栏唯一的作用是解释「这不是用户在
|
|
70
|
+
* 说话」,而 tool-result 天然就是系统反馈,模型不会把它读成用户发言。前缀标记
|
|
71
|
+
* 只为把平台的话与工具正文分开,**它不是安全边界**(工具正文来自文件/网页,
|
|
72
|
+
* 完全可以伪造同样的字样)——可接受,因为这句话本身只是劝告,不拦任何东西。
|
|
73
|
+
*
|
|
74
|
+
* `output` 声明成 `unknown`:落库的正文历史上就是 `z.unknown()`(几乎总是
|
|
75
|
+
* string)。**非字符串时原样返回、绝不 `String()` 强转**——那会把一个对象变成
|
|
76
|
+
* `[object Object]` 喂给模型。
|
|
77
|
+
*/
|
|
78
|
+
export declare function withSystemNote(output: unknown, note: string | undefined): JSONValue;
|
|
79
|
+
/**
|
|
80
|
+
* 投影层给图片打的引用命名空间。`FilePart.data = {type:'reference', reference:
|
|
81
|
+
* {[IMAGE_REFERENCE_KEY]: src}}` 会被 `ai` 核心原样透传到 provider prompt
|
|
82
|
+
* (已核 `ai@7.0.77` 的 `convertToLanguageModelV4FilePart`),由图片递送
|
|
83
|
+
* (`images/`,`resolveTurnModel` 包的模型)在请求前解析成 Files API 引用 / 公网 URL /
|
|
84
|
+
* base64。**没包递送时不会静默**:provider 包解析引用找不到自己的 key 会响亮地抛。
|
|
85
|
+
* (agent-base 里叫 `agentBase`;它只在投影时现生成、不落库,改名不影响历史。)
|
|
86
|
+
*
|
|
87
|
+
* 同一个 key 也用作 file part 的 `providerOptions` 命名空间,带上 `path`——那是
|
|
88
|
+
* 合成 user 消息里那句「这是哪张图」的材料,provider 包只读自己的命名空间、
|
|
89
|
+
* 对它视而不见。
|
|
90
|
+
*/
|
|
91
|
+
export declare const IMAGE_REFERENCE_KEY = "agentRuntime";
|
|
92
|
+
/** `MessagePart.images[]` 的一张 → 投影层的 file part。 */
|
|
93
|
+
export declare function imageFilePart(img: ToolResultImage): {
|
|
94
|
+
type: "file";
|
|
95
|
+
mediaType: string;
|
|
96
|
+
data: {
|
|
97
|
+
type: "reference";
|
|
98
|
+
reference: {
|
|
99
|
+
agentRuntime: string;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
providerOptions: {
|
|
103
|
+
agentRuntime: {
|
|
104
|
+
path?: string | undefined;
|
|
105
|
+
src: string;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* 一次工具结果 → 喂模型的 `ToolResultPart.output`。**轮内(`turn-run.ts`)
|
|
111
|
+
* 与重放(下面的投影)共用**,两条路各拼一次的话同一次调用在本轮与下一轮会长得
|
|
112
|
+
* 不一样,而「投影是纯函数」正是要防这个。
|
|
113
|
+
*
|
|
114
|
+
* 三个变体的判据:`isError` → `error-json`(裁剪不改它,那是「这次调用成功过
|
|
115
|
+
* 没有」的事实);有图 → `content`(正文 + file 引用;正文非字符串时不进这支,
|
|
116
|
+
* `content` 的 text item 只收字符串);其余 → `json`,与裁剪之前的行为逐字一致。
|
|
117
|
+
*/
|
|
118
|
+
export declare function toolResultOutput(args: {
|
|
119
|
+
output: unknown;
|
|
120
|
+
isError?: boolean;
|
|
121
|
+
systemNote?: string;
|
|
122
|
+
images?: ToolResultImage[];
|
|
123
|
+
}): ToolResultPart['output'];
|
|
124
|
+
/**
|
|
125
|
+
* 落库消息 → 喂模型的 ModelMessage[]。**必须无损**:工具调用与结果完整带回,
|
|
126
|
+
* 否则模型看不到自己上一轮调了什么工具、拿到什么结果(agent-x 的
|
|
127
|
+
* getMessagesForAI 正是栽在这里)。
|
|
128
|
+
*
|
|
129
|
+
* reasoning part **默认**丢弃 —— 各 provider 对 reasoning 的回放要求不同,
|
|
130
|
+
* 且当它只是补充材料时不是模型行为的必要输入。**但**若一条 assistant 消息
|
|
131
|
+
* 一个 text part 都没有(deepseek-v4-flash 偶发把整轮回复整段塞进
|
|
132
|
+
* reasoning_content、content 一个 token 都不产——真实数据取证:
|
|
133
|
+
* tokenUsage.outputTokenDetails 为 {textTokens:0, reasoningTokens:91}),
|
|
134
|
+
* 那么 reasoning 就是这一轮的全部回复,照旧丢弃会让下一轮模型看不到自己
|
|
135
|
+
* 说过什么(静默的对话记忆损坏,比"丢一点思考过程"严重得多,也违反本函数
|
|
136
|
+
* 头一句"必须无损"的硬约束)。故只在这唯一情形下把 reasoning 文本当正文
|
|
137
|
+
* 写进 content——写回的是普通 `{type:'text'}` content part,不是 provider
|
|
138
|
+
* 专属的 `reasoning_content` 字段,回放给任何 provider 都不会被拒收。
|
|
139
|
+
* 只要该条消息里有任意一个 text part,行为完全不变(reasoning 仍旧丢弃,
|
|
140
|
+
* 见下方测试 "keeps dropping reasoning when text is also present" 的护栏)。
|
|
141
|
+
* reasoning 规则**按段**套用(一轮一行后一条消息含多段)。
|
|
142
|
+
*
|
|
143
|
+
* **裁剪(`opts.prunedUptoSeq`)只换 tool-result 的正文,绝不删 part。**
|
|
144
|
+
* 删掉整个 tool-result 是这里最容易写出的错解:它编译通过、单测不看协议也照绿,
|
|
145
|
+
* 而结果是留下一个没有 result 的 tool_use —— 各家协议一律 400,且此后这个会话
|
|
146
|
+
* **每一次**发言都失败(历史只会越读越长),错误信息与真实原因毫无关系。下面
|
|
147
|
+
* `flushSegment` 里补齐无主 tool-call 的那段注释讲的是同一个坑的另一半。
|
|
148
|
+
*
|
|
149
|
+
* **压缩(`opts.compactedUptoSeq`)则是整行不进**,那是它与裁剪的分界:被压掉的
|
|
150
|
+
* 那段历史已经由 checkpoint 行整体代表了,留着半条只会让同一件事说两遍。切点只
|
|
151
|
+
* 落在行边界,故不会切出「有 tool_use 没 tool_result」——那是上一段那个 400 的
|
|
152
|
+
* 同一条约束。
|
|
153
|
+
*
|
|
154
|
+
* **本函数是纯函数**,这条是整套上下文预算的地基:给定 (rows, 指针),喂给模型
|
|
155
|
+
* 的历史唯一确定,模型看到的一切都能从库里重建。
|
|
156
|
+
*/
|
|
157
|
+
export declare function partsToModelMessages(msgs: StoredMessage[], opts?: ProjectionOptions): ModelMessage[];
|
|
158
|
+
//# sourceMappingURL=parts-to-model-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts-to-model-messages.d.ts","sourceRoot":"","sources":["../../src/turn/parts-to-model-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EAGZ,cAAc,EACf,MAAM,IAAI,CAAC;AAEZ,OAAO,EAGL,KAAK,WAAW,EAEhB,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAK5B,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;OAIG;IACH,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,GACb,MAAM,CAER;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,SAAS,CAGX;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe;;;;;;;;;;;;;;;EAejD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B,GAAG,cAAc,CAAC,QAAQ,CAAC,CAa3B;AA6DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,aAAa,EAAE,EACrB,IAAI,GAAE,iBAAsB,GAC3B,YAAY,EAAE,CAiKhB"}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { COMPACTION_CHECKPOINT_KIND, LOOP_REMINDER_KIND, TODO_REMINDER_KIND, } from '../schema/index.js';
|
|
2
|
+
import { wrapCompactionSummary } from './compaction.js';
|
|
3
|
+
import { previewJson } from './json-preview.js';
|
|
4
|
+
import { wrapSystemReminder } from './loop-reminder.js';
|
|
5
|
+
/**
|
|
6
|
+
* 被裁掉的工具结果在模型眼里长什么样。
|
|
7
|
+
*
|
|
8
|
+
* **保留工具名与调用参数、只丢正文**:正文才是体积(Read/Grep/Bash 那一族动辄
|
|
9
|
+
* 几万字符),而「我调过 Read('/workspace/x.md')」这件事只要几十个字符,却是模型
|
|
10
|
+
* 判断「要不要再跑一次」的全部依据。只留一句「结果已移除」而不说是哪次调用,
|
|
11
|
+
* 模型既想不起自己看过什么,也无从重跑。
|
|
12
|
+
*
|
|
13
|
+
* 文案明说是**为了腾空间**:这既不是工具失败,也不是结果过期。把预算行为写成
|
|
14
|
+
* 别的措辞,模型会据此下错结论(比如以为那个文件读不到了)。
|
|
15
|
+
*/
|
|
16
|
+
export function renderPrunedToolOutput(toolName, input) {
|
|
17
|
+
return `[结果已从上下文中移出以腾出空间。工具:${toolName},参数:${previewJson(input)}]`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 一次工具结果在模型眼里长什么样:正文 + 平台针对这次调用追加的那句提示
|
|
21
|
+
* (`MessagePart.systemNote`,当前唯一来源是重复调用提醒)。
|
|
22
|
+
*
|
|
23
|
+
* **拼接只在这里发生**,落库存的是纯正文与独立字段(同 checkpoint /
|
|
24
|
+
* subagent-result 那条分工)。**内核本轮喂给模型的那份也走这个函数**——两条路
|
|
25
|
+
* 各拼一次的话,同一次调用在本轮与下一轮重放时会长得不一样,而「投影是纯函数」
|
|
26
|
+
* 正是要防这个。
|
|
27
|
+
*
|
|
28
|
+
* **不包 `<system-reminder>` 围栏**:那层围栏唯一的作用是解释「这不是用户在
|
|
29
|
+
* 说话」,而 tool-result 天然就是系统反馈,模型不会把它读成用户发言。前缀标记
|
|
30
|
+
* 只为把平台的话与工具正文分开,**它不是安全边界**(工具正文来自文件/网页,
|
|
31
|
+
* 完全可以伪造同样的字样)——可接受,因为这句话本身只是劝告,不拦任何东西。
|
|
32
|
+
*
|
|
33
|
+
* `output` 声明成 `unknown`:落库的正文历史上就是 `z.unknown()`(几乎总是
|
|
34
|
+
* string)。**非字符串时原样返回、绝不 `String()` 强转**——那会把一个对象变成
|
|
35
|
+
* `[object Object]` 喂给模型。
|
|
36
|
+
*/
|
|
37
|
+
export function withSystemNote(output, note) {
|
|
38
|
+
if (!note || typeof output !== 'string')
|
|
39
|
+
return output;
|
|
40
|
+
return `${output}\n\n[系统提醒] ${note}`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 投影层给图片打的引用命名空间。`FilePart.data = {type:'reference', reference:
|
|
44
|
+
* {[IMAGE_REFERENCE_KEY]: src}}` 会被 `ai` 核心原样透传到 provider prompt
|
|
45
|
+
* (已核 `ai@7.0.77` 的 `convertToLanguageModelV4FilePart`),由图片递送
|
|
46
|
+
* (`images/`,`resolveTurnModel` 包的模型)在请求前解析成 Files API 引用 / 公网 URL /
|
|
47
|
+
* base64。**没包递送时不会静默**:provider 包解析引用找不到自己的 key 会响亮地抛。
|
|
48
|
+
* (agent-base 里叫 `agentBase`;它只在投影时现生成、不落库,改名不影响历史。)
|
|
49
|
+
*
|
|
50
|
+
* 同一个 key 也用作 file part 的 `providerOptions` 命名空间,带上 `path`——那是
|
|
51
|
+
* 合成 user 消息里那句「这是哪张图」的材料,provider 包只读自己的命名空间、
|
|
52
|
+
* 对它视而不见。
|
|
53
|
+
*/
|
|
54
|
+
export const IMAGE_REFERENCE_KEY = 'agentRuntime';
|
|
55
|
+
/** `MessagePart.images[]` 的一张 → 投影层的 file part。 */
|
|
56
|
+
export function imageFilePart(img) {
|
|
57
|
+
return {
|
|
58
|
+
type: 'file',
|
|
59
|
+
mediaType: img.mediaType,
|
|
60
|
+
data: {
|
|
61
|
+
type: 'reference',
|
|
62
|
+
reference: { [IMAGE_REFERENCE_KEY]: img.src },
|
|
63
|
+
},
|
|
64
|
+
providerOptions: {
|
|
65
|
+
[IMAGE_REFERENCE_KEY]: {
|
|
66
|
+
src: img.src,
|
|
67
|
+
...(img.path !== undefined ? { path: img.path } : {}),
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 一次工具结果 → 喂模型的 `ToolResultPart.output`。**轮内(`turn-run.ts`)
|
|
74
|
+
* 与重放(下面的投影)共用**,两条路各拼一次的话同一次调用在本轮与下一轮会长得
|
|
75
|
+
* 不一样,而「投影是纯函数」正是要防这个。
|
|
76
|
+
*
|
|
77
|
+
* 三个变体的判据:`isError` → `error-json`(裁剪不改它,那是「这次调用成功过
|
|
78
|
+
* 没有」的事实);有图 → `content`(正文 + file 引用;正文非字符串时不进这支,
|
|
79
|
+
* `content` 的 text item 只收字符串);其余 → `json`,与裁剪之前的行为逐字一致。
|
|
80
|
+
*/
|
|
81
|
+
export function toolResultOutput(args) {
|
|
82
|
+
const value = withSystemNote(args.output, args.systemNote);
|
|
83
|
+
if (args.isError)
|
|
84
|
+
return { type: 'error-json', value };
|
|
85
|
+
if (args.images && args.images.length > 0 && typeof value === 'string') {
|
|
86
|
+
// 文本项先单独建:直接写在数组字面量里时,ai 7.0.169 起 typescript-eslint 的
|
|
87
|
+
// no-deprecated 会把它的 `type` 按上下文联合解析到已废弃的变体上(误报)。
|
|
88
|
+
const text = { type: 'text', text: value };
|
|
89
|
+
return {
|
|
90
|
+
type: 'content',
|
|
91
|
+
value: [text, ...args.images.map(imageFilePart)],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return { type: 'json', value };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 一条落库的 user 行在模型眼里长什么样。
|
|
98
|
+
*
|
|
99
|
+
* **围栏按 `kind` 拼,不按「调用方传了什么选项」**:这两类行只要出现在历史里就
|
|
100
|
+
* 必须带围栏——checkpoint 是模型自己写的自由文本,提醒里夹着模型自己写的参数,
|
|
101
|
+
* 裸拼的话它们与平台的话在字节层面无从区分。落库存的都是纯正文(见各自 kind
|
|
102
|
+
* 常量的说明:落库的是数据,围栏是给模型看的呈现层,否则前端还得把标签剥回去)。
|
|
103
|
+
*/
|
|
104
|
+
function wrapStoredUserText(kind, text, reminderKinds) {
|
|
105
|
+
if (kind === COMPACTION_CHECKPOINT_KIND)
|
|
106
|
+
return wrapCompactionSummary(text);
|
|
107
|
+
if (kind === LOOP_REMINDER_KIND || kind === TODO_REMINDER_KIND) {
|
|
108
|
+
return wrapSystemReminder(text);
|
|
109
|
+
}
|
|
110
|
+
// 宿主登记的提醒行:当轮按 `system_reminder` 一律包围栏,重放必须同样包。
|
|
111
|
+
if (kind != null && reminderKinds.includes(kind)) {
|
|
112
|
+
return wrapSystemReminder(text);
|
|
113
|
+
}
|
|
114
|
+
return text;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* 压缩投影:丢掉阴影区里的整行,并把 checkpoint 提到最前面。
|
|
118
|
+
*
|
|
119
|
+
* **提头不是排版偏好,是因果顺序。** checkpoint 行是压缩完才插进去的,拿的是
|
|
120
|
+
* 当时最大的 seq,按序号排它会落在**保留下来的那段历史之后** —— 模型读到的就是
|
|
121
|
+
* 「最近几轮对话… 然后是一段更早的摘要」。倒过来的因果最直接的后果是它把摘要
|
|
122
|
+
* 里那些已经被后续对话推翻的结论当成最新决定,而这件事不会报错,只会让它答得
|
|
123
|
+
* 越来越不对。
|
|
124
|
+
*
|
|
125
|
+
* 至多一条 checkpoint 能活下来,这由切点规则保证(新的压缩切点必须覆盖上一条
|
|
126
|
+
* checkpoint,见 `ContextBudgetTracker.compact`)。真出现第二条时这里只提最早
|
|
127
|
+
* 的那条、后一条留在原位——降级而不是抛错:那毕竟只是历史顺序不理想,不值得
|
|
128
|
+
* 让整个会话从此发不出话。
|
|
129
|
+
*/
|
|
130
|
+
function applyCompaction(msgs, compactedUpto) {
|
|
131
|
+
if (compactedUpto === null)
|
|
132
|
+
return msgs;
|
|
133
|
+
const surviving = [];
|
|
134
|
+
for (const msg of msgs) {
|
|
135
|
+
if (msg.seq == null) {
|
|
136
|
+
// 同下面裁剪那条:**不静默跳过**。静默的症状只有「账单变贵」。
|
|
137
|
+
throw new Error('partsToModelMessages: compactedUptoSeq given but a message has no seq');
|
|
138
|
+
}
|
|
139
|
+
if (msg.seq <= compactedUpto)
|
|
140
|
+
continue;
|
|
141
|
+
surviving.push(msg);
|
|
142
|
+
}
|
|
143
|
+
const at = surviving.findIndex(m => m.kind === COMPACTION_CHECKPOINT_KIND);
|
|
144
|
+
if (at <= 0)
|
|
145
|
+
return surviving;
|
|
146
|
+
return [surviving[at], ...surviving.slice(0, at), ...surviving.slice(at + 1)];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 落库消息 → 喂模型的 ModelMessage[]。**必须无损**:工具调用与结果完整带回,
|
|
150
|
+
* 否则模型看不到自己上一轮调了什么工具、拿到什么结果(agent-x 的
|
|
151
|
+
* getMessagesForAI 正是栽在这里)。
|
|
152
|
+
*
|
|
153
|
+
* reasoning part **默认**丢弃 —— 各 provider 对 reasoning 的回放要求不同,
|
|
154
|
+
* 且当它只是补充材料时不是模型行为的必要输入。**但**若一条 assistant 消息
|
|
155
|
+
* 一个 text part 都没有(deepseek-v4-flash 偶发把整轮回复整段塞进
|
|
156
|
+
* reasoning_content、content 一个 token 都不产——真实数据取证:
|
|
157
|
+
* tokenUsage.outputTokenDetails 为 {textTokens:0, reasoningTokens:91}),
|
|
158
|
+
* 那么 reasoning 就是这一轮的全部回复,照旧丢弃会让下一轮模型看不到自己
|
|
159
|
+
* 说过什么(静默的对话记忆损坏,比"丢一点思考过程"严重得多,也违反本函数
|
|
160
|
+
* 头一句"必须无损"的硬约束)。故只在这唯一情形下把 reasoning 文本当正文
|
|
161
|
+
* 写进 content——写回的是普通 `{type:'text'}` content part,不是 provider
|
|
162
|
+
* 专属的 `reasoning_content` 字段,回放给任何 provider 都不会被拒收。
|
|
163
|
+
* 只要该条消息里有任意一个 text part,行为完全不变(reasoning 仍旧丢弃,
|
|
164
|
+
* 见下方测试 "keeps dropping reasoning when text is also present" 的护栏)。
|
|
165
|
+
* reasoning 规则**按段**套用(一轮一行后一条消息含多段)。
|
|
166
|
+
*
|
|
167
|
+
* **裁剪(`opts.prunedUptoSeq`)只换 tool-result 的正文,绝不删 part。**
|
|
168
|
+
* 删掉整个 tool-result 是这里最容易写出的错解:它编译通过、单测不看协议也照绿,
|
|
169
|
+
* 而结果是留下一个没有 result 的 tool_use —— 各家协议一律 400,且此后这个会话
|
|
170
|
+
* **每一次**发言都失败(历史只会越读越长),错误信息与真实原因毫无关系。下面
|
|
171
|
+
* `flushSegment` 里补齐无主 tool-call 的那段注释讲的是同一个坑的另一半。
|
|
172
|
+
*
|
|
173
|
+
* **压缩(`opts.compactedUptoSeq`)则是整行不进**,那是它与裁剪的分界:被压掉的
|
|
174
|
+
* 那段历史已经由 checkpoint 行整体代表了,留着半条只会让同一件事说两遍。切点只
|
|
175
|
+
* 落在行边界,故不会切出「有 tool_use 没 tool_result」——那是上一段那个 400 的
|
|
176
|
+
* 同一条约束。
|
|
177
|
+
*
|
|
178
|
+
* **本函数是纯函数**,这条是整套上下文预算的地基:给定 (rows, 指针),喂给模型
|
|
179
|
+
* 的历史唯一确定,模型看到的一切都能从库里重建。
|
|
180
|
+
*/
|
|
181
|
+
export function partsToModelMessages(msgs, opts = {}) {
|
|
182
|
+
const out = [];
|
|
183
|
+
const prunedUpto = opts.prunedUptoSeq ?? null;
|
|
184
|
+
const aliases = opts.toolNameAliases;
|
|
185
|
+
const nameOf = (toolName) => aliases?.get(toolName) ?? toolName;
|
|
186
|
+
for (const msg of applyCompaction(msgs, opts.compactedUptoSeq ?? null)) {
|
|
187
|
+
if (prunedUpto !== null && msg.seq == null) {
|
|
188
|
+
// **不静默跳过裁剪**:那样机制会在「看起来一切正常」的情况下整个失效,
|
|
189
|
+
// 唯一的症状是账单变贵。调用方要么给全 seq,要么根本别传指针。
|
|
190
|
+
throw new Error('partsToModelMessages: prunedUptoSeq given but a message has no seq');
|
|
191
|
+
}
|
|
192
|
+
const shadowed = prunedUpto !== null && msg.seq <= prunedUpto;
|
|
193
|
+
if (msg.role === 'user') {
|
|
194
|
+
// 用户文本原样喂给模型。`@` 引用的文件在**写入时**就已经改写成内联的
|
|
195
|
+
// `<file …>` 标签留在这段文字里(`session-file-ref.service.ts`),所以
|
|
196
|
+
// 这里不需要、也不该再做一次渲染——落库的文本就是模型看到的文本。
|
|
197
|
+
const text = msg.parts
|
|
198
|
+
.filter((p) => p.type === 'text')
|
|
199
|
+
.map(p => p.text)
|
|
200
|
+
.join('');
|
|
201
|
+
out.push({
|
|
202
|
+
role: 'user',
|
|
203
|
+
content: wrapStoredUserText(msg.kind, text, opts.reminderKinds ?? []),
|
|
204
|
+
});
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (msg.role !== 'assistant')
|
|
208
|
+
continue;
|
|
209
|
+
// 一条 assistant 消息可能跨多个 step(一轮一行)。以「已收集过
|
|
210
|
+
// tool-result 后再遇到 text/reasoning/tool-call」为 step 边界,逐段
|
|
211
|
+
// flush 出 (assistant, tool) 对,重建原来的行边界、保住因果顺序。
|
|
212
|
+
let assistantContent = [];
|
|
213
|
+
let toolOutputs = [];
|
|
214
|
+
let hasText = false;
|
|
215
|
+
let reasoningChunks = [];
|
|
216
|
+
let sawToolResult = false;
|
|
217
|
+
// 存根要带上「这次调用的参数」,而参数在同一行的 tool-call part 上。整行先
|
|
218
|
+
// 扫一遍建索引,不去依赖「tool-result 与它的 tool-call 必在同一段」——那条
|
|
219
|
+
// 性质当前成立,但让这里与 flushSegment 的切段规则耦合,改切段就会静默
|
|
220
|
+
// 丢掉参数。
|
|
221
|
+
const callInputs = new Map();
|
|
222
|
+
if (shadowed) {
|
|
223
|
+
for (const p of msg.parts) {
|
|
224
|
+
if (p.type === 'tool-call')
|
|
225
|
+
callInputs.set(p.toolCallId, p.input);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const flushSegment = () => {
|
|
229
|
+
if (!hasText && reasoningChunks.length > 0) {
|
|
230
|
+
assistantContent.unshift({
|
|
231
|
+
type: 'text',
|
|
232
|
+
text: reasoningChunks.join(''),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
// **补齐无主的 tool-call**。落库是增量的(`turn-run.ts` 的
|
|
236
|
+
// `flushStep`:发出 tool-call 就写一次,工具可能再跑几分钟),所以进程在
|
|
237
|
+
// 工具执行途中被杀,库里就留下一条有调用、没结果的记录。各家协议都要求
|
|
238
|
+
// 每个 tool_use 配一个 tool_result,缺一个就是整条请求 400 ——而历史只会
|
|
239
|
+
// 越读越长,这个会话从此**每一次**发言都失败,且错误信息与真实原因毫无
|
|
240
|
+
// 关系。
|
|
241
|
+
//
|
|
242
|
+
// 合成一条错误结果而不是把 tool-call 删掉:删掉等于告诉模型它从没调过这个
|
|
243
|
+
// 工具,它多半会原样再调一次(若那是个有副作用的写操作,就是重复执行);
|
|
244
|
+
// 合成的这条如实说明"没跑完",模型自己决定重试还是换路。
|
|
245
|
+
const answered = new Set(toolOutputs.map(o => o.toolCallId));
|
|
246
|
+
for (const c of assistantContent) {
|
|
247
|
+
if (c.type !== 'tool-call' || answered.has(c.toolCallId))
|
|
248
|
+
continue;
|
|
249
|
+
toolOutputs.push({
|
|
250
|
+
type: 'tool-result',
|
|
251
|
+
toolCallId: c.toolCallId,
|
|
252
|
+
toolName: c.toolName,
|
|
253
|
+
output: {
|
|
254
|
+
type: 'error-json',
|
|
255
|
+
value: '该工具调用没有留下结果(服务中断),执行是否生效未知。',
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
if (assistantContent.length > 0) {
|
|
260
|
+
out.push({ role: 'assistant', content: assistantContent });
|
|
261
|
+
}
|
|
262
|
+
if (toolOutputs.length > 0) {
|
|
263
|
+
out.push({ role: 'tool', content: toolOutputs });
|
|
264
|
+
}
|
|
265
|
+
assistantContent = [];
|
|
266
|
+
toolOutputs = [];
|
|
267
|
+
hasText = false;
|
|
268
|
+
reasoningChunks = [];
|
|
269
|
+
sawToolResult = false;
|
|
270
|
+
};
|
|
271
|
+
for (const part of msg.parts) {
|
|
272
|
+
if (part.type === 'text' ||
|
|
273
|
+
part.type === 'reasoning' ||
|
|
274
|
+
part.type === 'tool-call') {
|
|
275
|
+
if (sawToolResult)
|
|
276
|
+
flushSegment(); // 新 step 开始
|
|
277
|
+
}
|
|
278
|
+
if (part.type === 'text') {
|
|
279
|
+
assistantContent.push({ type: 'text', text: part.text });
|
|
280
|
+
hasText = true;
|
|
281
|
+
}
|
|
282
|
+
else if (part.type === 'reasoning') {
|
|
283
|
+
reasoningChunks.push(part.text);
|
|
284
|
+
}
|
|
285
|
+
else if (part.type === 'tool-call') {
|
|
286
|
+
assistantContent.push({
|
|
287
|
+
type: 'tool-call',
|
|
288
|
+
toolCallId: part.toolCallId,
|
|
289
|
+
toolName: nameOf(part.toolName),
|
|
290
|
+
input: part.input,
|
|
291
|
+
// 思考签名这类厂商要求原样带回的数据(只有适配器声明过的命名空间才会
|
|
292
|
+
// 落库,见 `MessagePart.providerMetadata`)。轮内回喂的那份是同一个值。
|
|
293
|
+
...(part.providerMetadata && {
|
|
294
|
+
providerOptions: part.providerMetadata,
|
|
295
|
+
}),
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
else if (part.type === 'tool-result') {
|
|
299
|
+
// `pinned` 的结果不换存根(当前唯一来源:`Ask` 回写的结局):
|
|
300
|
+
// 裁剪的前提是「正文是体积、丢了可以重跑」,而那是一两句话的**用户决定**,
|
|
301
|
+
// 裁掉之后模型无从重新得知。判据与置位方见 `MessagePart.pinned`。
|
|
302
|
+
const pruned = shadowed && part.pinned !== true;
|
|
303
|
+
// **`systemNote` 不跟着正文换存根**:裁剪的目的是省体积,而它极短,
|
|
304
|
+
// 且是「当时确实提醒过」这件事的记录——换掉它等于让模型在被裁剪过的
|
|
305
|
+
// 历史里读到一次没人提醒过的死循环。
|
|
306
|
+
//
|
|
307
|
+
// **图跟着正文一起卸**:裁剪指针推过去,`images` 就不进投影——这正是
|
|
308
|
+
// 图挂在 tool-result 上的收益(零新机制就有了一级卸载)。投影仍是同一条
|
|
309
|
+
// tool-result、条数不变,`ContextBudgetTracker.prune` 那道条数守卫因此
|
|
310
|
+
// 不会触发;合成的 user 消息在 provider prompt 层才出现,不在这里。
|
|
311
|
+
toolOutputs.push({
|
|
312
|
+
type: 'tool-result',
|
|
313
|
+
toolCallId: part.toolCallId,
|
|
314
|
+
toolName: nameOf(part.toolName),
|
|
315
|
+
// **裁剪不改 `isError`**:那是「这次调用成功过没有」的事实,与正文
|
|
316
|
+
// 还在不在无关。把裁掉的失败调用投影成成功,模型会把一个从没生效的
|
|
317
|
+
// 写操作当成已完成。
|
|
318
|
+
output: toolResultOutput({
|
|
319
|
+
output: pruned
|
|
320
|
+
? renderPrunedToolOutput(nameOf(part.toolName), callInputs.get(part.toolCallId))
|
|
321
|
+
: part.output,
|
|
322
|
+
isError: part.isError,
|
|
323
|
+
systemNote: part.systemNote,
|
|
324
|
+
images: pruned ? undefined : part.images,
|
|
325
|
+
}),
|
|
326
|
+
});
|
|
327
|
+
sawToolResult = true;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
flushSegment(); // 收尾最后一段
|
|
331
|
+
}
|
|
332
|
+
return out;
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=parts-to-model-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts-to-model-messages.js","sourceRoot":"","sources":["../../src/turn/parts-to-model-messages.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAElB,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAiDxD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAgB,EAChB,KAAc;IAEd,OAAO,uBAAuB,QAAQ,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC;AACrE,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAe,EACf,IAAwB;IAExB,IAAI,CAAC,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAmB,CAAC;IACpE,OAAO,GAAG,MAAM,cAAc,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAElD,mDAAmD;AACnD,MAAM,UAAU,aAAa,CAAC,GAAoB;IAChD,OAAO;QACL,IAAI,EAAE,MAAe;QACrB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,IAAI,EAAE;YACJ,IAAI,EAAE,WAAoB;YAC1B,SAAS,EAAE,EAAE,CAAC,mBAAmB,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE;SAC9C;QACD,eAAe,EAAE;YACf,CAAC,mBAAmB,CAAC,EAAE;gBACrB,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtD;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAKhC;IACC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IACvD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvE,uDAAuD;QACvD,kDAAkD;QAClD,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACpD,OAAO;YACL,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;SACjD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,kBAAkB,CACzB,IAA+B,EAC/B,IAAY,EACZ,aAAgC;IAEhC,IAAI,IAAI,KAAK,0BAA0B;QAAE,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC5E,IAAI,IAAI,KAAK,kBAAkB,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QAC/D,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,gDAAgD;IAChD,IAAI,IAAI,IAAI,IAAI,IAAI,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,eAAe,CACtB,IAAqB,EACrB,aAA4B;IAE5B,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,SAAS,GAAoB,EAAE,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YACpB,mCAAmC;YACnC,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,GAAG,IAAI,aAAa;YAAE,SAAS;QACvC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IACD,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,0BAA0B,CAAC,CAAC;IAC3E,IAAI,EAAE,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAqB,EACrB,OAA0B,EAAE;IAE5B,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC;IACrC,MAAM,MAAM,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC1C,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,EAAE,CAAC;QACvE,IAAI,UAAU,KAAK,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YAC3C,uCAAuC;YACvC,mCAAmC;YACnC,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,UAAU,KAAK,IAAI,IAAK,GAAG,CAAC,GAAc,IAAI,UAAU,CAAC;QAE1E,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,wCAAwC;YACxC,yDAAyD;YACzD,mCAAmC;YACnC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK;iBACnB,MAAM,CACL,CAAC,CAAC,EAA+C,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CACtE;iBACA,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAChB,IAAI,CAAC,EAAE,CAAC,CAAC;YACZ,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;aACtE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAEvC,yCAAyC;QACzC,yDAAyD;QACzD,+CAA+C;QAC/C,IAAI,gBAAgB,GAAmC,EAAE,CAAC;QAC1D,IAAI,WAAW,GAAqB,EAAE,CAAC;QACvC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,eAAe,GAAa,EAAE,CAAC;QACnC,IAAI,aAAa,GAAG,KAAK,CAAC;QAE1B,+CAA+C;QAC/C,mDAAmD;QACnD,4CAA4C;QAC5C,QAAQ;QACR,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmB,CAAC;QAC9C,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;oBAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,gBAAgB,CAAC,OAAO,CAAC;oBACvB,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;iBAC/B,CAAC,CAAC;YACL,CAAC;YACD,6CAA6C;YAC7C,iDAAiD;YACjD,qCAAqC;YACrC,oDAAoD;YACpD,uCAAuC;YACvC,MAAM;YACN,EAAE;YACF,4CAA4C;YAC5C,sCAAsC;YACtC,+BAA+B;YAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YAC7D,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;gBACjC,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;oBAAE,SAAS;gBACnE,WAAW,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,aAAa;oBACnB,UAAU,EAAE,CAAC,CAAC,UAAU;oBACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,MAAM,EAAE;wBACN,IAAI,EAAE,YAAY;wBAClB,KAAK,EAAE,6BAA6B;qBACrC;iBACF,CAAC,CAAC;YACL,CAAC;YACD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YACnD,CAAC;YACD,gBAAgB,GAAG,EAAE,CAAC;YACtB,WAAW,GAAG,EAAE,CAAC;YACjB,OAAO,GAAG,KAAK,CAAC;YAChB,eAAe,GAAG,EAAE,CAAC;YACrB,aAAa,GAAG,KAAK,CAAC;QACxB,CAAC,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC7B,IACE,IAAI,CAAC,IAAI,KAAK,MAAM;gBACpB,IAAI,CAAC,IAAI,KAAK,WAAW;gBACzB,IAAI,CAAC,IAAI,KAAK,WAAW,EACzB,CAAC;gBACD,IAAI,aAAa;oBAAE,YAAY,EAAE,CAAC,CAAC,YAAY;YACjD,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACzB,gBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzD,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBACrC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBACrC,gBAAgB,CAAC,IAAI,CAAC;oBACpB,IAAI,EAAE,WAAW;oBACjB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,oCAAoC;oBACpC,qDAAqD;oBACrD,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI;wBAC3B,eAAe,EAAE,IAAI,CAAC,gBAAgB;qBACvC,CAAC;iBACH,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACvC,wCAAwC;gBACxC,yCAAyC;gBACzC,6CAA6C;gBAC7C,MAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;gBAChD,4CAA4C;gBAC5C,oCAAoC;gBACpC,oBAAoB;gBACpB,EAAE;gBACF,2CAA2C;gBAC3C,4CAA4C;gBAC5C,yDAAyD;gBACzD,+CAA+C;gBAC/C,WAAW,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,aAAa;oBACnB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAC/B,0CAA0C;oBAC1C,mCAAmC;oBACnC,YAAY;oBACZ,MAAM,EAAE,gBAAgB,CAAC;wBACvB,MAAM,EAAE,MAAM;4BACZ,CAAC,CAAC,sBAAsB,CACpB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EACrB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAChC;4BACH,CAAC,CAAC,IAAI,CAAC,MAAM;wBACf,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;qBACzC,CAAC;iBACH,CAAC,CAAC;gBACH,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;QACH,CAAC;QACD,YAAY,EAAE,CAAC,CAAC,SAAS;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ModelMessage } from 'ai';
|
|
2
|
+
/**
|
|
3
|
+
* 会话是否还有「待模型响应」的输入。纯从 messages 推导(无状态),
|
|
4
|
+
* 使 loop 的终止判定在 crash/重启后仍正确:
|
|
5
|
+
* - 结尾 'user':用户消息未答 → 待响应。
|
|
6
|
+
* - 结尾 'tool':工具结果待模型跟进 → 待响应。
|
|
7
|
+
* - 结尾 'assistant':已给最终答复(无待办工具)→ 不待响应。
|
|
8
|
+
*/
|
|
9
|
+
export declare function hasPendingWork(messages: ModelMessage[]): boolean;
|
|
10
|
+
//# sourceMappingURL=pending-work.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-work.d.ts","sourceRoot":"","sources":["../../src/turn/pending-work.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAEvC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAIhE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话是否还有「待模型响应」的输入。纯从 messages 推导(无状态),
|
|
3
|
+
* 使 loop 的终止判定在 crash/重启后仍正确:
|
|
4
|
+
* - 结尾 'user':用户消息未答 → 待响应。
|
|
5
|
+
* - 结尾 'tool':工具结果待模型跟进 → 待响应。
|
|
6
|
+
* - 结尾 'assistant':已给最终答复(无待办工具)→ 不待响应。
|
|
7
|
+
*/
|
|
8
|
+
export function hasPendingWork(messages) {
|
|
9
|
+
const last = messages[messages.length - 1];
|
|
10
|
+
if (!last)
|
|
11
|
+
return false;
|
|
12
|
+
return last.role === 'user' || last.role === 'tool';
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=pending-work.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-work.js","sourceRoot":"","sources":["../../src/turn/pending-work.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,QAAwB;IACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 拿到这一步**真正**的失败原因。
|
|
3
|
+
*
|
|
4
|
+
* `streamError` 是调用方从 `streamText` 的 `onError` 里接住的那个错误。判据
|
|
5
|
+
* 刻意窄——**只有** `err` 是那个无信息的 `NoOutputGeneratedError` 壳、且这一步
|
|
6
|
+
* 确实记到过流内错误时才替换。abort 走的是另一条(SDK 用 `abortSignal.reason`
|
|
7
|
+
* reject),不会被这里误伤。
|
|
8
|
+
*/
|
|
9
|
+
export declare function unwrapInferenceError(err: unknown, streamError: unknown): unknown;
|
|
10
|
+
/**
|
|
11
|
+
* 把错误说成一句用户能看懂、运维能定位的中文。
|
|
12
|
+
*
|
|
13
|
+
* 落进 `TurnResult.error`(→ `chat_message.metadata.error` 与零产出时的占位
|
|
14
|
+
* 气泡)。**始终带上服务商原话**:归一化只是给前面加一句「该干什么」,把原文
|
|
15
|
+
* 抹掉就等于让运维去猜。
|
|
16
|
+
*/
|
|
17
|
+
export declare function describeProviderError(err: unknown): string;
|
|
18
|
+
/**
|
|
19
|
+
* 传输层断连的判据:**响应流读到一半,连接没了**。
|
|
20
|
+
*
|
|
21
|
+
* 这一类错误不是 HTTP 错误——没有状态码,AI SDK 的请求级重试(只认
|
|
22
|
+
* `APICallError.isRetryable`,且只包着「发起请求」那一步)罩不到它;流式响应
|
|
23
|
+
* 里它经 `onError` 冒出来,原始形状是 Node 内置 HTTP 客户端 undici 的
|
|
24
|
+
* `TypeError: terminated`(对端关闭)或 `ECONNRESET`(连接被重置),真正的
|
|
25
|
+
* 原因挂在 `cause` 链上。2026-09-09 线上 deepseek 一次 555 秒的轮次就是这么
|
|
26
|
+
* 死的:前 5 步正常,第 6 次调模型读流中途 `terminated`,整轮 failed。
|
|
27
|
+
*
|
|
28
|
+
* **判据刻意窄**:只认「已经建立的连接中途断开」这一族(code 表 + undici 的几句
|
|
29
|
+
* 原话),不认连接建立阶段的失败(`fetch failed` / `ECONNREFUSED` / DNS)——
|
|
30
|
+
* 那些发生在请求阶段,SDK 自己已经退避重试过了,到这里的是它放弃之后的
|
|
31
|
+
* `RetryError`,再重试一轮只是把同一个死结多绕三圈。也**不认 abort**:用户按
|
|
32
|
+
* 停止走的是 `AbortError`,那是有人要它停,不是链路坏了。
|
|
33
|
+
*
|
|
34
|
+
* 顺着 `cause` 链看(最多 8 层):undici 把 `SocketError` 包在 `TypeError`
|
|
35
|
+
* 里,只看最外层的 message 会漏掉 `ECONNRESET` 这种只在里层出现的 code。
|
|
36
|
+
*/
|
|
37
|
+
export declare function isTransportError(err: unknown): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* 把 `cause` 链摊平成一行给日志:`TypeError: terminated ← SocketError: other
|
|
40
|
+
* side closed [UND_ERR_SOCKET]`。`String(err)` 只有最外层那句,而对传输层错误
|
|
41
|
+
* 来说最外层恰恰是信息量最低的一层——线上那次日志里只剩一个 `terminated`,
|
|
42
|
+
* 连是对端正常关闭还是被重置都分不出来。
|
|
43
|
+
*/
|
|
44
|
+
export declare function describeErrorChain(err: unknown): string;
|
|
45
|
+
//# sourceMappingURL=provider-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-error.d.ts","sourceRoot":"","sources":["../../src/turn/provider-error.ts"],"names":[],"mappings":"AAsCA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,OAAO,GACnB,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAe1D;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAYtD;AAkBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAkBvD"}
|