@animalabs/agent-framework 0.23.3 → 0.24.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/README.md +212 -42
- package/dist/src/agent.d.ts +65 -9
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +98 -12
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +14 -12
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/clock-rows.d.ts +115 -0
- package/dist/src/clock-rows.d.ts.map +1 -0
- package/dist/src/clock-rows.js +222 -0
- package/dist/src/clock-rows.js.map +1 -0
- package/dist/src/code-execution/engine.d.ts +177 -0
- package/dist/src/code-execution/engine.d.ts.map +1 -0
- package/dist/src/code-execution/engine.js +494 -0
- package/dist/src/code-execution/engine.js.map +1 -0
- package/dist/src/code-execution/index.d.ts +5 -10
- package/dist/src/code-execution/index.d.ts.map +1 -1
- package/dist/src/code-execution/index.js +5 -9
- package/dist/src/code-execution/index.js.map +1 -1
- package/dist/src/code-execution/isolate/calls.d.ts +114 -0
- package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/calls.js +145 -0
- package/dist/src/code-execution/isolate/calls.js.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.js +5 -0
- package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
- package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
- package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-main.js +132 -0
- package/dist/src/code-execution/isolate/child-main.js.map +1 -0
- package/dist/src/code-execution/isolate/child.d.ts +44 -0
- package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child.js +315 -0
- package/dist/src/code-execution/isolate/child.js.map +1 -0
- package/dist/src/code-execution/isolate/frames.d.ts +80 -0
- package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/frames.js +210 -0
- package/dist/src/code-execution/isolate/frames.js.map +1 -0
- package/dist/src/code-execution/isolate/output.d.ts +68 -0
- package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/output.js +143 -0
- package/dist/src/code-execution/isolate/output.js.map +1 -0
- package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
- package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/prelude.js +401 -0
- package/dist/src/code-execution/isolate/prelude.js.map +1 -0
- package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
- package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/protocol.js +150 -0
- package/dist/src/code-execution/isolate/protocol.js.map +1 -0
- package/dist/src/code-execution/isolate/render.d.ts +57 -0
- package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/render.js +214 -0
- package/dist/src/code-execution/isolate/render.js.map +1 -0
- package/dist/src/code-execution/isolate/runner.d.ts +250 -0
- package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/runner.js +854 -0
- package/dist/src/code-execution/isolate/runner.js.map +1 -0
- package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/scripts.js +357 -0
- package/dist/src/code-execution/isolate/scripts.js.map +1 -0
- package/dist/src/code-execution/quickjs.wasm +0 -0
- package/dist/src/code-execution/tool-definition.d.ts +93 -43
- package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
- package/dist/src/code-execution/tool-definition.js +176 -142
- package/dist/src/code-execution/tool-definition.js.map +1 -1
- package/dist/src/deadline-timer.d.ts +3 -0
- package/dist/src/deadline-timer.d.ts.map +1 -1
- package/dist/src/deadline-timer.js +1 -1
- package/dist/src/deadline-timer.js.map +1 -1
- package/dist/src/framework.d.ts +1120 -457
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +4635 -2505
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +28 -4
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +89 -13
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/held-writes.d.ts +16 -3
- package/dist/src/held-writes.d.ts.map +1 -1
- package/dist/src/held-writes.js +16 -3
- package/dist/src/held-writes.js.map +1 -1
- package/dist/src/index.d.ts +8 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +483 -115
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +1735 -425
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts +19 -39
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +27 -59
- package/dist/src/mcpl/conversation-router.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts.map +1 -1
- package/dist/src/mcpl/convert-block.js +9 -5
- package/dist/src/mcpl/convert-block.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +50 -0
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +130 -0
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/index.d.ts +2 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +3 -2
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/log-value.d.ts +6 -0
- package/dist/src/mcpl/log-value.d.ts.map +1 -1
- package/dist/src/mcpl/log-value.js +8 -0
- package/dist/src/mcpl/log-value.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts +15 -6
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
- package/dist/src/mcpl/modern-connection.js +168 -53
- package/dist/src/mcpl/modern-connection.js.map +1 -1
- package/dist/src/mcpl/prose-grammar.d.ts +4 -5
- package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
- package/dist/src/mcpl/prose-grammar.js +4 -5
- package/dist/src/mcpl/prose-grammar.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts +97 -10
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +174 -17
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +132 -14
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +227 -50
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +9 -20
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +7 -49
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +4 -4
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +50 -21
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +158 -74
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/tags.d.ts +24 -0
- package/dist/src/mcpl/tags.d.ts.map +1 -1
- package/dist/src/mcpl/tags.js +33 -0
- package/dist/src/mcpl/tags.js.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
- package/dist/src/mcpl/transport.d.ts +55 -7
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +163 -34
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +22 -6
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/module-registry.d.ts +4 -2
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +100 -13
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +8 -13
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +27 -4
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +15 -3
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +27 -5
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/index.d.ts +1 -1
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js.map +1 -1
- package/dist/src/modules/unknown-tool.d.ts +4 -1
- package/dist/src/modules/unknown-tool.d.ts.map +1 -1
- package/dist/src/modules/unknown-tool.js +4 -1
- package/dist/src/modules/unknown-tool.js.map +1 -1
- package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
- package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
- package/dist/src/modules/workspace/branch-intent.js +3 -1
- package/dist/src/modules/workspace/branch-intent.js.map +1 -1
- package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
- package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-plan.js +794 -0
- package/dist/src/modules/workspace/edit-plan.js.map +1 -0
- package/dist/src/modules/workspace/edit-text.d.ts +117 -0
- package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-text.js +584 -0
- package/dist/src/modules/workspace/edit-text.js.map +1 -0
- package/dist/src/modules/workspace/effects.d.ts +5 -4
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +78 -25
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +493 -62
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +2216 -652
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +213 -38
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +416 -36
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +15 -8
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/text.d.ts +32 -0
- package/dist/src/modules/workspace/text.d.ts.map +1 -0
- package/dist/src/modules/workspace/text.js +67 -0
- package/dist/src/modules/workspace/text.js.map +1 -0
- package/dist/src/modules/workspace/types.d.ts +210 -6
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.js.map +1 -1
- package/dist/src/modules/workspace/watcher.d.ts +3 -2
- package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/operator-log.d.ts +52 -24
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
- package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
- package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
- package/dist/src/recovery/offline-branch.d.ts +26 -1
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +164 -39
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js +23 -4
- package/dist/src/recovery/recover-cli.js.map +1 -1
- package/dist/src/send-tools.d.ts +11 -0
- package/dist/src/send-tools.d.ts.map +1 -0
- package/dist/src/send-tools.js +11 -0
- package/dist/src/send-tools.js.map +1 -0
- package/dist/src/timezone.d.ts +4 -2
- package/dist/src/timezone.d.ts.map +1 -1
- package/dist/src/timezone.js +4 -2
- package/dist/src/timezone.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts +46 -7
- package/dist/src/tool-image-ledger.d.ts.map +1 -1
- package/dist/src/tool-image-ledger.js +60 -7
- package/dist/src/tool-image-ledger.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts +14 -11
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +17 -14
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +3 -2
- package/dist/src/tool-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +3 -2
- package/dist/src/tool-result-history.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +21 -0
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +142 -40
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/types/agent.d.ts +31 -6
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +66 -9
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +69 -62
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +40 -8
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +111 -10
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/src/usage/types.d.ts +16 -0
- package/dist/src/usage/types.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.d.ts +14 -1
- package/dist/src/usage/usage-tracker.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.js +81 -41
- package/dist/src/usage/usage-tracker.js.map +1 -1
- package/package.json +6 -8
- package/src/agent.ts +99 -12
- package/src/api/server.ts +14 -12
- package/src/clock-rows.ts +302 -0
- package/src/code-execution/engine.ts +595 -0
- package/src/code-execution/index.ts +5 -17
- package/src/code-execution/isolate/calls.ts +199 -0
- package/src/code-execution/isolate/child-entry.ts +5 -0
- package/src/code-execution/isolate/child-main.ts +132 -0
- package/src/code-execution/isolate/child.ts +327 -0
- package/src/code-execution/isolate/frames.ts +209 -0
- package/src/code-execution/isolate/output.ts +161 -0
- package/src/code-execution/isolate/prelude.ts +409 -0
- package/src/code-execution/isolate/protocol.ts +240 -0
- package/src/code-execution/isolate/render.ts +230 -0
- package/src/code-execution/isolate/runner.ts +911 -0
- package/src/code-execution/isolate/scripts.ts +479 -0
- package/src/code-execution/quickjs.wasm +0 -0
- package/src/code-execution/quickjs.wasm.LICENSES +149 -0
- package/src/code-execution/tool-definition.ts +236 -167
- package/src/deadline-timer.ts +1 -1
- package/src/framework.ts +4978 -2671
- package/src/gate/event-gate.ts +79 -17
- package/src/held-writes.ts +17 -3
- package/src/index.ts +32 -22
- package/src/mcpl/channel-registry.ts +1892 -471
- package/src/mcpl/conversation-router.ts +26 -72
- package/src/mcpl/convert-block.ts +9 -5
- package/src/mcpl/inbound-source.ts +131 -0
- package/src/mcpl/index.ts +4 -2
- package/src/mcpl/log-value.ts +9 -0
- package/src/mcpl/modern-connection.ts +162 -53
- package/src/mcpl/prose-grammar.ts +4 -5
- package/src/mcpl/protocol-family.ts +200 -22
- package/src/mcpl/push-coalescer.ts +306 -62
- package/src/mcpl/push-handler.ts +12 -54
- package/src/mcpl/reference-fetcher.ts +4 -4
- package/src/mcpl/server-connection.ts +180 -79
- package/src/mcpl/tags.ts +36 -0
- package/src/mcpl/tool-result-normalize.ts +2 -1
- package/src/mcpl/transport.ts +162 -33
- package/src/mcpl/types.ts +23 -6
- package/src/module-registry.ts +92 -13
- package/src/modules/discord/index.ts +8 -13
- package/src/modules/history/index.ts +25 -3
- package/src/modules/history/semantic.ts +29 -6
- package/src/modules/index.ts +1 -0
- package/src/modules/unknown-tool.ts +4 -1
- package/src/modules/workspace/branch-intent.ts +3 -1
- package/src/modules/workspace/edit-plan.ts +954 -0
- package/src/modules/workspace/edit-text.ts +618 -0
- package/src/modules/workspace/effects.ts +70 -19
- package/src/modules/workspace/index.ts +2293 -650
- package/src/modules/workspace/observe.ts +465 -56
- package/src/modules/workspace/reconcile.ts +14 -7
- package/src/modules/workspace/text.ts +68 -0
- package/src/modules/workspace/types.ts +211 -6
- package/src/modules/workspace/watcher.ts +3 -2
- package/src/operator-log.ts +47 -19
- package/src/recovery/discord-awareness-outbox.ts +1500 -356
- package/src/recovery/offline-branch.ts +189 -55
- package/src/recovery/recover-cli.ts +25 -4
- package/src/send-tools.ts +11 -0
- package/src/timezone.ts +4 -2
- package/src/tool-image-ledger.ts +62 -8
- package/src/tool-result-guard.ts +18 -15
- package/src/tool-result-history.ts +3 -2
- package/src/tune-out/coordinator.ts +166 -45
- package/src/types/agent.ts +32 -6
- package/src/types/events.ts +66 -9
- package/src/types/framework.ts +69 -62
- package/src/types/module.ts +40 -8
- package/src/types/trace.ts +121 -15
- package/src/usage/types.ts +16 -0
- package/src/usage/usage-tracker.ts +86 -43
- package/dist/src/code-execution/py-runner.d.ts +0 -191
- package/dist/src/code-execution/py-runner.d.ts.map +0 -1
- package/dist/src/code-execution/py-runner.js +0 -655
- package/dist/src/code-execution/py-runner.js.map +0 -1
- package/dist/src/code-execution/runtime-py.d.ts +0 -50
- package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
- package/dist/src/code-execution/runtime-py.js +0 -677
- package/dist/src/code-execution/runtime-py.js.map +0 -1
- package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
- package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
- package/dist/src/mcpl/prose-stream-router.js +0 -291
- package/dist/src/mcpl/prose-stream-router.js.map +0 -1
- package/src/code-execution/py-runner.ts +0 -791
- package/src/code-execution/runtime-py.ts +0 -677
- package/src/mcpl/prose-stream-router.ts +0 -268
package/src/tool-result-guard.ts
CHANGED
|
@@ -18,7 +18,7 @@ export const TOOL_RESULT_GUARD_AUDIT_STATE = 'framework/tool-result-guard';
|
|
|
18
18
|
* left the stub's branch when the file would have been committed
|
|
19
19
|
* (`branch_changed`), or because the batch used its deadline before this
|
|
20
20
|
* write could start (`batch_deadline`); or null when no file is written at all (no writable
|
|
21
|
-
*
|
|
21
|
+
* mount without an include, or the host is stopping). */
|
|
22
22
|
export type WithheldSpill =
|
|
23
23
|
| { path: string; error?: string; unfinished?: true }
|
|
24
24
|
| { skipped: 'workspace_unanswered' | 'branch_changed' | 'batch_deadline' }
|
|
@@ -86,10 +86,11 @@ export function withheldResultNotice(spill: WithheldSpill, auditDurable: boolean
|
|
|
86
86
|
/**
|
|
87
87
|
* What a withheld result's stub keeps of it: the fields of its data that its
|
|
88
88
|
* tool marked as saying what it acted on (ToolResult.keepWhenWithheld), in
|
|
89
|
-
* the order marked, serialized as a stored result is. Past the
|
|
90
|
-
* they're cut, with a note that
|
|
91
|
-
* a later field can then be cut
|
|
92
|
-
* nothing, as for a failed result
|
|
89
|
+
* the order marked, serialized as a stored result is. Past `maxChars`, the
|
|
90
|
+
* inline cap or less (storeResults' keptCap), they're cut, with a note that
|
|
91
|
+
* says so and where the whole result is, since a later field can then be cut
|
|
92
|
+
* away entirely. Undefined when it keeps nothing, as for a failed result
|
|
93
|
+
* (agent-framework #277). A write's file
|
|
93
94
|
* list is evidence of what it did, rarely what drew a refusal, and keeping it
|
|
94
95
|
* is what shows a clobbered file when the receipt is withheld.
|
|
95
96
|
*/
|
|
@@ -109,7 +110,7 @@ export function keptWhenWithheld(result: CompletedToolCall['result'], maxChars:
|
|
|
109
110
|
// Never half a surrogate pair: the stub goes to the provider as text, so
|
|
110
111
|
// the cut can be one character short of the cap.
|
|
111
112
|
const head = safeSlice(whole, 0, maxChars);
|
|
112
|
-
return `${head} [cut
|
|
113
|
+
return `${head} [cut: ${head.length} of these fields' ${whole.length} ` +
|
|
113
114
|
'characters; the whole result is where this note says]';
|
|
114
115
|
}
|
|
115
116
|
|
|
@@ -313,15 +314,16 @@ export class ToolResultGuard {
|
|
|
313
314
|
: JSON.parse(json);
|
|
314
315
|
}
|
|
315
316
|
|
|
316
|
-
/** `
|
|
317
|
-
*
|
|
317
|
+
/** `keptCap` is where what a stub keeps of a withheld result is cut: the
|
|
318
|
+
* cap the caller stored `content` under, less the stub's notice room where
|
|
319
|
+
* its message's bound sets it (toolResultShare, tool-image-ledger.ts). */
|
|
318
320
|
storeResults(
|
|
319
321
|
content: ContentBlock[],
|
|
320
322
|
wireResults: ToolResult[],
|
|
321
323
|
originals: CompletedToolCall[],
|
|
322
324
|
metadata: MessageMetadata | undefined,
|
|
323
|
-
/**
|
|
324
|
-
|
|
325
|
+
/** Where what a stub keeps is cut. */
|
|
326
|
+
keptCap: number | undefined,
|
|
325
327
|
): MessageId {
|
|
326
328
|
if (!this.enabled) return this.cm.addMessage('user', content, metadata);
|
|
327
329
|
if (this.pending) {
|
|
@@ -355,7 +357,7 @@ export class ToolResultGuard {
|
|
|
355
357
|
const kept = new Map<number, string>();
|
|
356
358
|
for (const [index, block] of content.entries()) {
|
|
357
359
|
const result = block.type === 'tool_result' ? results.get(block.toolUseId) : undefined;
|
|
358
|
-
const text = result ? keptWhenWithheld(result,
|
|
360
|
+
const text = result ? keptWhenWithheld(result, keptCap) : undefined;
|
|
359
361
|
if (text !== undefined) kept.set(index, text);
|
|
360
362
|
}
|
|
361
363
|
// Compression hold (CM >= 0.12): placed BEFORE onNewMessage fires, so no
|
|
@@ -497,8 +499,9 @@ export class ToolResultGuard {
|
|
|
497
499
|
|
|
498
500
|
/**
|
|
499
501
|
* Turn a withheld batch's notices into stubs that say where each original
|
|
500
|
-
* is (agent-framework #277): written to the workspace when
|
|
501
|
-
*
|
|
502
|
+
* is (agent-framework #277): written to the workspace when it has a
|
|
503
|
+
* writable mount without an include to take it, else kept in the audit
|
|
504
|
+
* record. A stub also keeps the file
|
|
502
505
|
* lists its tool marked. Its own unedited placeholder is
|
|
503
506
|
* the only thing it edits: an operator's later edit, removal or rollback
|
|
504
507
|
* stands.
|
|
@@ -596,8 +599,8 @@ export class ToolResultGuard {
|
|
|
596
599
|
if (block.type !== 'tool_result') return [];
|
|
597
600
|
if (thrown.has(index)) return [{ toolUseId: block.toolUseId, error: thrown.get(index)! }];
|
|
598
601
|
const spill = spills.get(index) ?? null;
|
|
599
|
-
// No file was written: no writable
|
|
600
|
-
// was stopping.
|
|
602
|
+
// No file was written: no writable mount without an include,
|
|
603
|
+
// or the framework was stopping.
|
|
601
604
|
if (spill === null) return [{ toolUseId: block.toolUseId, skipped: 'no_workspace_file' }];
|
|
602
605
|
if ('skipped' in spill) return [{ toolUseId: block.toolUseId, skipped: spill.skipped }];
|
|
603
606
|
return [{ toolUseId: block.toolUseId, path: spill.path,
|
|
@@ -49,7 +49,7 @@ export interface HistorySerializeOptions {
|
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* House-safe default inline cap (chars) for tool results, error results, and
|
|
52
|
-
*
|
|
52
|
+
* script wake payloads (issue #89: a resident should never eat a
|
|
53
53
|
* 42k blob they didn't ask for). Durable per-residence value comes from
|
|
54
54
|
* `FrameworkConfig.toolResultInlineMaxChars`; a per-agent value from
|
|
55
55
|
* agent_settings `tool_result_inline_max_chars`.
|
|
@@ -101,7 +101,8 @@ export function nonErrorResultText(
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
/** Bounded copy of an arbitrary string with the standard truncation notice,
|
|
104
|
-
* cut at the cap
|
|
104
|
+
* cut at the cap where a tool result's stored copy is cut at that cap
|
|
105
|
+
* (toolResultCutAt), so it
|
|
105
106
|
* never ends in part of a slot. Each of its callers' readers sees this
|
|
106
107
|
* very text, never the images behind a placeholder, so nothing past the cut
|
|
107
108
|
* is kept for save_recent_image's index (#403). The framework stores a tool
|
|
@@ -37,6 +37,37 @@ const WAKE_COALESCE_MS = 2_000;
|
|
|
37
37
|
/** How long after an end time whose cancel threw the cancel is tried again. */
|
|
38
38
|
const EXPIRY_RETRY_MS = 60_000;
|
|
39
39
|
|
|
40
|
+
/** Ends a backlog line cut to fit in one of the residents' messages. */
|
|
41
|
+
const CUT_MARK = " [cut to fit; the whole message is in the channel's history]";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* tune_out's refusal of a channel already tuned out: its settings, then what
|
|
45
|
+
* its transport is now where the repeat tried to open it again (`transport`,
|
|
46
|
+
* from the framework's dispatch), then how to change the settings.
|
|
47
|
+
*/
|
|
48
|
+
export function alreadyTunedOutText(channelId: string, p: TuneOutParams, transport?: string): string {
|
|
49
|
+
// A duration so long its end is past what a Date can hold has no time to show.
|
|
50
|
+
const expires = p.expiresAtMs !== undefined ? new Date(p.expiresAtMs) : undefined;
|
|
51
|
+
const until = expires && Number.isFinite(expires.getTime())
|
|
52
|
+
? `, until ${expires.toISOString().replace(/\.\d+Z$/, 'Z')}`
|
|
53
|
+
: '';
|
|
54
|
+
// A thrown error's words may end without a stop.
|
|
55
|
+
const now = transport === undefined ? '' : /[.!?]$/.test(transport) ? `${transport} ` : `${transport}. `;
|
|
56
|
+
return `Nothing changed${transport !== undefined ? ' in the tune-out' : ''}: ${JSON.stringify(channelId)} is already `
|
|
57
|
+
+ `tuned out, with cadenceSeconds ${p.cadenceSeconds}, backlogCap ${p.backlogCap} and maxWakes ${p.maxWakes}${until}. `
|
|
58
|
+
+ now
|
|
59
|
+
+ 'To change those, cancel it first with tune_out mode "cancel", which delivers its backlog to you now, then call '
|
|
60
|
+
+ 'tune_out again with the new settings.';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The first `length` code units of `text`, one fewer where the last would be
|
|
64
|
+
* the first half of a surrogate pair. */
|
|
65
|
+
function prefixOf(text: string, length: number): string {
|
|
66
|
+
const cut = text.slice(0, Math.max(0, length));
|
|
67
|
+
const last = cut.charCodeAt(cut.length - 1);
|
|
68
|
+
return last >= 0xd800 && last <= 0xdbff ? cut.slice(0, -1) : cut;
|
|
69
|
+
}
|
|
70
|
+
|
|
40
71
|
/** What a thrown value says, without throwing: an Error's message, or the
|
|
41
72
|
* value as text, which String() can't give for an object with no prototype. */
|
|
42
73
|
function thrownReason(error: unknown): string {
|
|
@@ -63,6 +94,20 @@ export interface TuneOutFrameworkHooks {
|
|
|
63
94
|
primaryName: () => string | null;
|
|
64
95
|
/** Read the primary's stored messages (shared slot, unfiltered). */
|
|
65
96
|
getStoredMessages: () => StoredMessage[];
|
|
97
|
+
/**
|
|
98
|
+
* Messages admitted for the primary but not yet in its store (deferred
|
|
99
|
+
* while a turn was alive), oldest first. A cancel reads them too, so a
|
|
100
|
+
* message held mid-turn is in the backlog it belongs to (#232 gap 7).
|
|
101
|
+
*/
|
|
102
|
+
getDeferredMessages?: () => Array<Pick<StoredMessage, 'participant' | 'content' | 'metadata'>>;
|
|
103
|
+
/**
|
|
104
|
+
* The most characters of text every reader of the residents' shared slot
|
|
105
|
+
* is shown whole in one message: the smallest of their strategies'
|
|
106
|
+
* per-message caps (`maxMessageTokens`) at four characters a token, or
|
|
107
|
+
* undefined when none has such a cap. A cancel's dump is one message in
|
|
108
|
+
* that slot, so it holds as many backlog lines as fit.
|
|
109
|
+
*/
|
|
110
|
+
residentMessageChars?: () => number | undefined;
|
|
66
111
|
/** Current chronicle head sequence (window anchor for new epochs). */
|
|
67
112
|
currentSequence: () => number;
|
|
68
113
|
/** Move the subconscious window anchor (never forward past active epochs). */
|
|
@@ -178,7 +223,7 @@ export class TuneOutCoordinator {
|
|
|
178
223
|
channelId: string,
|
|
179
224
|
opts: { cadenceSeconds?: number; backlogCap?: number; maxWakes?: number; durationSeconds?: number },
|
|
180
225
|
source: string,
|
|
181
|
-
): { ok: true; params: TuneOutParams } | { ok: false; error: string } {
|
|
226
|
+
): { ok: true; params: TuneOutParams } | { ok: false; error: string; alreadyTunedOut?: true } {
|
|
182
227
|
if (!this.hooks.subconsciousName()) {
|
|
183
228
|
return {
|
|
184
229
|
ok: false,
|
|
@@ -197,21 +242,7 @@ export class TuneOutCoordinator {
|
|
|
197
242
|
};
|
|
198
243
|
}
|
|
199
244
|
const current = this.channelRegistry.getTuneOutState(serverId, channelId);
|
|
200
|
-
if (current) {
|
|
201
|
-
const p = current.params;
|
|
202
|
-
// A duration so long its end is past what a Date can hold has no time to show.
|
|
203
|
-
const expires = p.expiresAtMs !== undefined ? new Date(p.expiresAtMs) : undefined;
|
|
204
|
-
const until = expires && Number.isFinite(expires.getTime())
|
|
205
|
-
? `, until ${expires.toISOString().replace(/\.\d+Z$/, 'Z')}`
|
|
206
|
-
: '';
|
|
207
|
-
return {
|
|
208
|
-
ok: false,
|
|
209
|
-
error: `Nothing changed: ${JSON.stringify(channelId)} is already tuned out, with cadenceSeconds `
|
|
210
|
-
+ `${p.cadenceSeconds}, backlogCap ${p.backlogCap} and maxWakes ${p.maxWakes}${until}. To change those, `
|
|
211
|
-
+ 'cancel it first with tune_out mode "cancel", which delivers its backlog to you now, then call tune_out '
|
|
212
|
-
+ 'again with the new settings.',
|
|
213
|
-
};
|
|
214
|
-
}
|
|
245
|
+
if (current) return { ok: false, error: alreadyTunedOutText(channelId, current.params), alreadyTunedOut: true };
|
|
215
246
|
// A tool's input reaches here as the model wrote it, and the store can't
|
|
216
247
|
// keep a NaN or an Infinity: its append would throw after the registry
|
|
217
248
|
// had marked the channel tuned out. So each option is read as a number
|
|
@@ -259,9 +290,9 @@ export class TuneOutCoordinator {
|
|
|
259
290
|
startedAtSequence: this.hooks.currentSequence(),
|
|
260
291
|
...(expiresAtMs !== undefined ? { expiresAtMs } : {}),
|
|
261
292
|
};
|
|
262
|
-
// A tune-out
|
|
263
|
-
//
|
|
264
|
-
//
|
|
293
|
+
// A tune-out that ended in the registry without this coordinator's
|
|
294
|
+
// cancel would have left its timers armed: clear them, so none of them
|
|
295
|
+
// acts on this one.
|
|
265
296
|
this.clearTimers(serverId, channelId);
|
|
266
297
|
this.channelRegistry.enterTuneOut(serverId, channelId, params, source);
|
|
267
298
|
this.armExpiry(serverId, channelId, params);
|
|
@@ -302,35 +333,106 @@ export class TuneOutCoordinator {
|
|
|
302
333
|
this.clearTimers(serverId, channelId);
|
|
303
334
|
this.divertedSinceInvocation.delete(this.key(serverId, channelId));
|
|
304
335
|
|
|
305
|
-
// Backlog: every message
|
|
336
|
+
// Backlog: every message held under this epoch. The stored ones come in
|
|
337
|
+
// store order, then those still in the deferred queue (held mid-turn,
|
|
338
|
+
// not yet written), oldest first. That's arrival order, except when a
|
|
339
|
+
// held message stays queued while a later one is stored: a store write
|
|
340
|
+
// refused at a turn-start flush leaves it queued, and that turn's
|
|
341
|
+
// assembly can then store later coalesced messages directly.
|
|
306
342
|
const epochId = ended.params.epochId;
|
|
307
|
-
const
|
|
308
|
-
(m
|
|
309
|
-
);
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
343
|
+
const ofEpoch = (m: Pick<StoredMessage, 'metadata'>): boolean =>
|
|
344
|
+
(m.metadata as { tuneOut?: { epochId?: string } } | undefined)?.tuneOut?.epochId === epochId;
|
|
345
|
+
const held = (this.hooks.getDeferredMessages?.() ?? []).filter(ofEpoch);
|
|
346
|
+
const backlog: Array<Pick<StoredMessage, 'participant' | 'content' | 'metadata'>> = [
|
|
347
|
+
...this.hooks.getStoredMessages().filter(ofEpoch),
|
|
348
|
+
...held,
|
|
349
|
+
];
|
|
350
|
+
// Whole messages: a cap below one shows none, where slice(-0.5) would
|
|
351
|
+
// start at 0 and take them all.
|
|
352
|
+
const cap = Math.floor(ended.params.backlogCap);
|
|
353
|
+
const authorOf = (m: Pick<StoredMessage, 'participant' | 'metadata'>): string =>
|
|
354
|
+
(m.metadata as { author?: { name?: string } } | undefined)?.author?.name ?? m.participant;
|
|
355
|
+
const lineOf = (m: Pick<StoredMessage, 'participant' | 'content' | 'metadata'>): string => {
|
|
316
356
|
const text = m.content
|
|
317
357
|
.filter((b): b is Extract<ContentBlock, { type: 'text' }> => b.type === 'text')
|
|
318
358
|
.map((b) => b.text)
|
|
319
359
|
.join('\n');
|
|
320
|
-
return `${
|
|
321
|
-
}
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
360
|
+
return `${authorOf(m)}: ${text}`;
|
|
361
|
+
};
|
|
362
|
+
const lifecycle = `[Tune-out: ${channelId} cancelled — ${reason}, ${ended.wakeCount} wake${ended.wakeCount === 1 ? '' : 's'}]`;
|
|
363
|
+
const render = (lines: string[], truncated: number): string => {
|
|
364
|
+
const attrs = [
|
|
365
|
+
`channel="${channelId}"`,
|
|
366
|
+
`messages=${backlog.length}`,
|
|
367
|
+
...(truncated > 0 ? [`truncated=${truncated} (oldest; fetch_history covers the rest)`] : []),
|
|
368
|
+
];
|
|
369
|
+
return `${lifecycle}\n\n<tuned-out-backlog ${attrs.join(' ')}>\n${lines.join('\n')}\n</tuned-out-backlog>`;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// The dump is one message in the residents' shared slot, so each
|
|
373
|
+
// resident's strategy cuts it as it cuts any message past its per-message
|
|
374
|
+
// cap: context-manager's AutobiographicalStrategy (which connectome-host's
|
|
375
|
+
// FrontdeskStrategy extends) and WindowedPassthroughStrategy count a text
|
|
376
|
+
// block at a token per four characters, rounded up, and keep a message's
|
|
377
|
+
// first cap × 4 characters. Cut there, the dump would lose its newest
|
|
378
|
+
// lines, which would still count as shown. So it holds the newest lines
|
|
379
|
+
// that fit whole in the smallest such room, and those it leaves out, the
|
|
380
|
+
// oldest, count as truncated along with those above backlogCap, so the
|
|
381
|
+
// report is told of them. A newest message too long to fit alone is shown
|
|
382
|
+
// cut to the room left and marked, so the residents still get its head,
|
|
383
|
+
// as they would from a row of its own. When no line fits, whole or cut,
|
|
384
|
+
// the dump shows none; if the room is too small for even that, the
|
|
385
|
+
// residents' strategies cut its frame, the header and tags.
|
|
386
|
+
let shown = cap > 0 ? backlog.slice(-cap) : [];
|
|
387
|
+
let lines = shown.map(lineOf);
|
|
388
|
+
let newestCut = false;
|
|
389
|
+
const room = this.hooks.residentMessageChars?.();
|
|
390
|
+
if (room !== undefined && render(lines, backlog.length - shown.length).length > room) {
|
|
391
|
+
// The dump's length with no line, for the count that showing k lines
|
|
392
|
+
// leaves out: truncated= takes that count's digits, and goes at 0. With
|
|
393
|
+
// the newest k lines whole, the dump is that and the lines, with a
|
|
394
|
+
// newline between each two. While a message is left out, each line kept
|
|
395
|
+
// makes it longer, and they don't all fit, so the fit keeps lines from
|
|
396
|
+
// the newest while the next one fits.
|
|
397
|
+
const frameShowing = (k: number): number => render([], backlog.length - k).length;
|
|
398
|
+
let used = 0;
|
|
399
|
+
let kept = 0;
|
|
400
|
+
while (kept < lines.length) {
|
|
401
|
+
const next = used + lines[lines.length - 1 - kept]!.length + (kept > 0 ? 1 : 0);
|
|
402
|
+
if (frameShowing(kept + 1) + next > room) break;
|
|
403
|
+
used = next;
|
|
404
|
+
kept++;
|
|
405
|
+
}
|
|
406
|
+
// What of the newest line's text fits beside the frame and the mark. A
|
|
407
|
+
// cut shows some of it or none: a room under one character, or one
|
|
408
|
+
// that would split a surrogate pair, leaves the head empty.
|
|
409
|
+
const head = prefixOf(lines.at(-1) ?? '', room - frameShowing(1) - CUT_MARK.length);
|
|
410
|
+
if (kept === 0 && head !== '') {
|
|
411
|
+
lines = [head + CUT_MARK];
|
|
412
|
+
shown = shown.slice(-1);
|
|
413
|
+
newestCut = true;
|
|
414
|
+
} else {
|
|
415
|
+
lines = lines.slice(lines.length - kept);
|
|
416
|
+
shown = shown.slice(shown.length - kept);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const truncated = backlog.length - shown.length;
|
|
420
|
+
// The held messages the dump leaves out, the oldest of them. The
|
|
421
|
+
// subconscious's report covers what the dump leaves out, but its view
|
|
422
|
+
// holds stored rows only, so these go to it with its notice below. So does
|
|
423
|
+
// a held message the dump shows but can't give whole: one whose image or
|
|
424
|
+
// audio its text lines drop, or the newest, cut to fit.
|
|
425
|
+
const heldLeftOut = held.slice(0, Math.max(0, held.length - shown.length));
|
|
426
|
+
const heldForReport = [
|
|
427
|
+
...heldLeftOut,
|
|
428
|
+
...held.slice(heldLeftOut.length).filter((m) =>
|
|
429
|
+
m.content.some((b) => b.type !== 'text') || (newestCut && m === shown[0])),
|
|
326
430
|
];
|
|
327
|
-
const dump =
|
|
328
|
-
`<tuned-out-backlog ${attrs.join(' ')}>\n${lines.join('\n')}\n</tuned-out-backlog>`;
|
|
329
431
|
|
|
330
432
|
// Host-framed system artifacts — never voiced as anyone.
|
|
331
433
|
this.hooks.addMessage(
|
|
332
434
|
'user',
|
|
333
|
-
[{ type: 'text', text:
|
|
435
|
+
[{ type: 'text', text: render(lines, truncated) }],
|
|
334
436
|
{ system: true, kind: 'tune-out-cancel', channelId, epochId },
|
|
335
437
|
);
|
|
336
438
|
// The subconscious's own words, under its own name, verbatim.
|
|
@@ -346,20 +448,39 @@ export class TuneOutCoordinator {
|
|
|
346
448
|
if (primary) {
|
|
347
449
|
this.hooks.requestInference(primary, `tune-out cancelled (${reason})`, 'tune-out');
|
|
348
450
|
}
|
|
349
|
-
// The subconscious gets one cancel turn of its own
|
|
350
|
-
//
|
|
351
|
-
//
|
|
352
|
-
//
|
|
353
|
-
|
|
451
|
+
// The subconscious gets one cancel turn of its own: the issue's cancel
|
|
452
|
+
// shape is dump + a report from the subconscious, and when the dump left
|
|
453
|
+
// messages out, its summary is what covers them. The held messages the
|
|
454
|
+
// dump can't give the resident whole follow the notice, each a row of its
|
|
455
|
+
// own with its own content, as its view can't have them until they're
|
|
456
|
+
// stored. A cancel the subconscious makes itself gets the notice and the
|
|
457
|
+
// turn when some do, since it wrote its note before it could see them,
|
|
458
|
+
// and when it wrote no note and the dump left any message out, since
|
|
459
|
+
// nothing else then covers it. Otherwise its note speaks for what it saw.
|
|
460
|
+
const selfCancel = source === 'subconscious';
|
|
461
|
+
if (subName && (!selfCancel || heldForReport.length > 0 || (!subconsciousNote && truncated > 0))) {
|
|
354
462
|
const truncNote = truncated > 0
|
|
355
|
-
? ` ${truncated} of ${backlog.length} diverted messages
|
|
463
|
+
? ` ${truncated} of ${backlog.length} diverted messages, the oldest, weren't delivered raw to the resident.`
|
|
464
|
+
: '';
|
|
465
|
+
const heldNote = heldForReport.length > 0
|
|
466
|
+
? ` Still held at the cancel, so your view may not have them yet: the ${heldForReport.length} message${heldForReport.length === 1 ? '' : 's'} after this one.`
|
|
356
467
|
: '';
|
|
357
468
|
this.hooks.addMessage(
|
|
358
469
|
'user',
|
|
359
|
-
[{ type: 'text', text: `[Tune-out cancelled: ${channelId} — ${reason}.${truncNote}]` }],
|
|
470
|
+
[{ type: 'text', text: `[Tune-out cancelled: ${channelId} — ${reason}.${truncNote}${heldNote}]` }],
|
|
360
471
|
{ system: true, kind: 'tune-out-cancel-report', channelId },
|
|
361
472
|
subName,
|
|
362
473
|
);
|
|
474
|
+
// Each held message is a row of its own, so a per-message cap cuts each
|
|
475
|
+
// one on its own, its author's label included, not the batch's newest.
|
|
476
|
+
for (const m of heldForReport) {
|
|
477
|
+
this.hooks.addMessage(
|
|
478
|
+
'user',
|
|
479
|
+
[{ type: 'text', text: `${authorOf(m)}:` }, ...m.content],
|
|
480
|
+
{ system: true, kind: 'tune-out-cancel-held', channelId },
|
|
481
|
+
subName,
|
|
482
|
+
);
|
|
483
|
+
}
|
|
363
484
|
this.hooks.requestInference(subName, `tune-out cancelled: ${channelId}`, 'tune-out');
|
|
364
485
|
}
|
|
365
486
|
this.hooks.emitTrace({ type: 'tune-out:cancelled', serverId, channelId, epochId, reason, wakeCount: ended.wakeCount });
|
package/src/types/agent.ts
CHANGED
|
@@ -218,6 +218,34 @@ export interface AgentConfig {
|
|
|
218
218
|
* content-free system receipt is stored instead. Default false.
|
|
219
219
|
*/
|
|
220
220
|
toolWrapperProseGuard?: boolean;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Clock rows (off when left out): when a boundary of this interval on the
|
|
224
|
+
* agent's local wall clock (counted from local midnight, in the
|
|
225
|
+
* framework's `timeZone`) has passed since the last clock row, the window
|
|
226
|
+
* takes one more — `Clock: 10:50 Europe/Berlin (UTC+02:00)`, with the date
|
|
227
|
+
* when the day has changed — before the next thing it takes: an incoming
|
|
228
|
+
* event, a turn's start, or, mid-turn, after a tool round's results, where
|
|
229
|
+
* it also joins the live stream. Only the latest boundary is written, and
|
|
230
|
+
* a window that holds no clock row yet takes one at the next of these. A
|
|
231
|
+
* clock reads the boundary's time where its tick would have stood, else
|
|
232
|
+
* the time it is written (after a tool's results, say), so it never
|
|
233
|
+
* reads earlier than a row before it. A clock wakes no one. See
|
|
234
|
+
* src/clock-rows.ts.
|
|
235
|
+
*
|
|
236
|
+
* - A stream that can't carry injected messages (membrane's XML prefill
|
|
237
|
+
* path) takes no mid-turn clock: the next event or turn start writes it.
|
|
238
|
+
* - On some models a clock after a tool's results drops the loop's
|
|
239
|
+
* earlier thinking from the request, as any message heard while acting
|
|
240
|
+
* does there: at most once an interval.
|
|
241
|
+
* - Residents share one window, so every resident reads the clock rows any
|
|
242
|
+
* of them writes, a resident with no `clock` of its own included. Each
|
|
243
|
+
* writes one when a boundary of its own interval has passed since the
|
|
244
|
+
* window's last clock, whichever resident wrote that. The subconscious
|
|
245
|
+
* takes none of its own: it reads the residents' through its merged
|
|
246
|
+
* view.
|
|
247
|
+
*/
|
|
248
|
+
clock?: import('../clock-rows.js').ClockConfig;
|
|
221
249
|
}
|
|
222
250
|
|
|
223
251
|
/** The intentionally small set of agent settings that may change in-process. */
|
|
@@ -371,6 +399,10 @@ export interface InferenceRequest {
|
|
|
371
399
|
* all of them without materializing content, the turn has no cause left
|
|
372
400
|
* and does not run. */
|
|
373
401
|
coalescingBatchSubjects?: string[];
|
|
402
|
+
/** Host-owned: this wake's sole cause is reading this deferred write, a
|
|
403
|
+
* coalesced render placed in its agent's queue (wakeToRead). Once the
|
|
404
|
+
* agent has read the write, or it was removed, the wake starts no turn. */
|
|
405
|
+
readsDeferredWrite?: string;
|
|
374
406
|
agentName: string;
|
|
375
407
|
reason: string;
|
|
376
408
|
source: string;
|
|
@@ -386,12 +418,6 @@ export interface InferenceRequest {
|
|
|
386
418
|
* ephemeral run's (a subagent's), which takes no global fallback.
|
|
387
419
|
*/
|
|
388
420
|
channelId?: string;
|
|
389
|
-
/**
|
|
390
|
-
* Host-owned: the MCPL server whose message set `channelId`. A turn's
|
|
391
|
-
* replies to that channel go out through this server only. Unset where the
|
|
392
|
-
* wake's channel came from no one server's message.
|
|
393
|
-
*/
|
|
394
|
-
serverId?: string;
|
|
395
421
|
/**
|
|
396
422
|
* True when the triggering message explicitly addressed the agent (mention,
|
|
397
423
|
* reply-to-bot, DM — `chat:addressed` in MCPL RFC-001 terms). When a wake
|
package/src/types/events.ts
CHANGED
|
@@ -193,11 +193,32 @@ export interface ToolResult {
|
|
|
193
193
|
/** Whether this was an error (for LLM) */
|
|
194
194
|
isError?: boolean;
|
|
195
195
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
196
|
+
* The dispatcher refused the call before it opened, RFC-007's refusal, so
|
|
197
|
+
* nothing ran and the call certainly had no effect. Only the dispatcher's
|
|
198
|
+
* path, the model's calls and a script's, sets it: the caller may not use
|
|
199
|
+
* the tool (allowedTools), a `skip_reply` wake was refused, the call's MCPL
|
|
200
|
+
* server is absent or still connecting, the host's policy for that server
|
|
201
|
+
* denies the tool, or a fork reached outside its channel. RFC-007's
|
|
202
|
+
* lifecycle refuses the call from the same place, so observers see no
|
|
203
|
+
* events for it. A check made after the call opened, such as a module's
|
|
204
|
+
* answer for a name it has no tool for or arguments that don't fit a
|
|
205
|
+
* schema, is a failure whose text says nothing was done, as is an MCPL
|
|
206
|
+
* request that couldn't be written. A programmatic call (`executeToolCall`,
|
|
207
|
+
* `ModuleContext.callTool`) opens no RFC-007 call, so it's never refused:
|
|
208
|
+
* the allowedTools check answers it with a failure saying the call didn't
|
|
209
|
+
* run, and the other checks it gets, such as the module registry's, answer
|
|
210
|
+
* as they do once a call has opened. A module's result never carries it. A script's call refused so reaches the script as an
|
|
211
|
+
* Error, where any other failure is a result with `isError`.
|
|
212
|
+
*/
|
|
213
|
+
refused?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* The result's machine-readable form, beside `data`. Programs read it: a
|
|
216
|
+
* script gets it in its result object, and a host in the tool result
|
|
217
|
+
* event. The model never reads this field: it sees the value only where an
|
|
218
|
+
* MCP conversion put it in the content as JSON, which happens only when the
|
|
219
|
+
* server sent no text. An MCP tool's is its `structuredContent`, present
|
|
220
|
+
* exactly when the server sent one, so `false`, `0` and `null` are values
|
|
221
|
+
* here, not absence. Any other tool can set one too.
|
|
201
222
|
*/
|
|
202
223
|
structured?: unknown;
|
|
203
224
|
/**
|
|
@@ -237,15 +258,51 @@ export interface ToolCall {
|
|
|
237
258
|
* The turn the call was made in, the same id as that turn's
|
|
238
259
|
* `SpeechContext.turnId`. Set by the framework dispatch layer, beside
|
|
239
260
|
* `callerAgentName`: a model's call carries the turn whose stream made it, a
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* none. Ids increase, so a later turn's is larger, and they're unique only
|
|
261
|
+
* script's call the turn of the code_execution call watching the script when
|
|
262
|
+
* the call reaches the host, and a utility run its `utils` call's. A script left
|
|
263
|
+
* running, which no call watches, runs apart from any turn, so its calls
|
|
264
|
+
* carry none. Ids increase, so a later turn's is larger, and they're unique only
|
|
244
265
|
* within one run of the process. A call made with `executeToolCall` or a
|
|
245
266
|
* module's `callTool` skips that layer and carries whatever turn its caller
|
|
246
267
|
* put on the call, usually none.
|
|
247
268
|
*/
|
|
248
269
|
callerTurnId?: number;
|
|
270
|
+
/**
|
|
271
|
+
* How long this call's result may be and still reach its caller whole,
|
|
272
|
+
* measured as the framework stores it: an error's text, or a success's data
|
|
273
|
+
* as JSON (a content array as its text). For a model's call it is the
|
|
274
|
+
* agent's inline cap, past which the framework spills the result to a
|
|
275
|
+
* workspace file and sends a preview. A result that long is stored whole
|
|
276
|
+
* unless its round's results together pass the readers' per-message bound,
|
|
277
|
+
* or a save_recent_image in the round counted it by its share: then each
|
|
278
|
+
* result of the round takes an equal share of that bound, and one past its
|
|
279
|
+
* share spills. For a call from a running
|
|
280
|
+
* code_execution script it is the longest result that reaches the script
|
|
281
|
+
* whole whatever its characters, from the script's memory: the script
|
|
282
|
+
* takes an answer of up to a third of its memoryMaxBytes, in which a
|
|
283
|
+
* character of the result takes at most six bytes (a control character,
|
|
284
|
+
* escaped as `\u0000`), so the figure is that third, less the 80 bytes of a
|
|
285
|
+
* text answer's envelope, over six: 7,456,527 at the default 128 MiB. On
|
|
286
|
+
* Node, past about 1.5 GiB, the host's longest string bounds it instead.
|
|
287
|
+
* A result with a `structured` value reaches a script as its content's
|
|
288
|
+
* blocks as they are, beside that value as JSON, and the figure counts
|
|
289
|
+
* neither the value nor what the blocks carry past their text, such as each
|
|
290
|
+
* further block's keys or an image's data, so a tool that returns one
|
|
291
|
+
* leaves room for them; and a result nested past 2,000 levels, or whose parse
|
|
292
|
+
* needs more of the script's memory than is free, doesn't reach the script
|
|
293
|
+
* whatever its length. A result that doesn't reach it is answered
|
|
294
|
+
* ResultTooLarge, the call having taken effect. Nothing is cut or saved to
|
|
295
|
+
* a file. A tool that pages or budgets its answer can stay under it. The
|
|
296
|
+
* framework sets it on a model's, a script's and the operator's puppet's
|
|
297
|
+
* call to a module, a utility run through `utils` included. A call
|
|
298
|
+
* made in process with ModuleContext.callTool or executeToolCall carries
|
|
299
|
+
* what its caller put on it, as the puppet's does; the framework's own
|
|
300
|
+
* read_image tool passes a model's call to the workspace without it; and a
|
|
301
|
+
* utility run through `utils` carries what its `utils` call carried.
|
|
302
|
+
* Without it, a module holds its answer to a bound of its own, if any: the
|
|
303
|
+
* workspace's is the house default, 24,000.
|
|
304
|
+
*/
|
|
305
|
+
resultMaxChars?: number;
|
|
249
306
|
}
|
|
250
307
|
|
|
251
308
|
// ============================================================================
|