@animalabs/agent-framework 0.26.2 → 0.28.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/README.md +99 -8
- package/dist/src/agent.d.ts +291 -23
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +596 -61
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +5 -4
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/auto-continue.d.ts +34 -0
- package/dist/src/auto-continue.d.ts.map +1 -0
- package/dist/src/auto-continue.js +36 -0
- package/dist/src/auto-continue.js.map +1 -0
- package/dist/src/code-execution/isolate/scripts.d.ts +11 -0
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
- package/dist/src/code-execution/isolate/scripts.js +5 -1
- package/dist/src/code-execution/isolate/scripts.js.map +1 -1
- package/dist/src/cut-off-round.d.ts +24 -0
- package/dist/src/cut-off-round.d.ts.map +1 -0
- package/dist/src/cut-off-round.js +87 -0
- package/dist/src/cut-off-round.js.map +1 -0
- package/dist/src/framework.d.ts +1038 -193
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +5967 -1514
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +405 -46
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +2646 -399
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/gate/index.d.ts +3 -2
- package/dist/src/gate/index.d.ts.map +1 -1
- package/dist/src/gate/index.js +2 -1
- package/dist/src/gate/index.js.map +1 -1
- package/dist/src/gate/recipe-reconcile.d.ts +103 -0
- package/dist/src/gate/recipe-reconcile.d.ts.map +1 -0
- package/dist/src/gate/recipe-reconcile.js +325 -0
- package/dist/src/gate/recipe-reconcile.js.map +1 -0
- package/dist/src/gate/reply-judge.d.ts +116 -0
- package/dist/src/gate/reply-judge.d.ts.map +1 -0
- package/dist/src/gate/reply-judge.js +467 -0
- package/dist/src/gate/reply-judge.js.map +1 -0
- package/dist/src/gate/types.d.ts +229 -8
- package/dist/src/gate/types.d.ts.map +1 -1
- package/dist/src/heartbeat/heartbeat.d.ts +184 -0
- package/dist/src/heartbeat/heartbeat.d.ts.map +1 -0
- package/dist/src/heartbeat/heartbeat.js +752 -0
- package/dist/src/heartbeat/heartbeat.js.map +1 -0
- package/dist/src/heartbeat/reminder-time.d.ts +5 -0
- package/dist/src/heartbeat/reminder-time.d.ts.map +1 -0
- package/dist/src/heartbeat/reminder-time.js +107 -0
- package/dist/src/heartbeat/reminder-time.js.map +1 -0
- package/dist/src/index.d.ts +10 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/capability-mask.d.ts.map +1 -1
- package/dist/src/mcpl/capability-mask.js +3 -2
- package/dist/src/mcpl/capability-mask.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +433 -113
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +1154 -435
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts +16 -8
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +29 -15
- 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 +14 -2
- package/dist/src/mcpl/convert-block.js.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.d.ts +7 -1
- package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.js +32 -7
- package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +26 -10
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +40 -69
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/index.d.ts +5 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +4 -0
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/inference-router.d.ts +14 -2
- package/dist/src/mcpl/inference-router.d.ts.map +1 -1
- package/dist/src/mcpl/inference-router.js +73 -28
- package/dist/src/mcpl/inference-router.js.map +1 -1
- package/dist/src/mcpl/prose-grammar.d.ts +4 -0
- package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
- package/dist/src/mcpl/prose-grammar.js +6 -0
- package/dist/src/mcpl/prose-grammar.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +3 -0
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +20 -2
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +33 -11
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +63 -42
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +177 -145
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/references.d.ts +380 -46
- package/dist/src/mcpl/references.d.ts.map +1 -1
- package/dist/src/mcpl/references.js +736 -77
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +93 -4
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +176 -11
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/tags.d.ts +9 -2
- package/dist/src/mcpl/tags.d.ts.map +1 -1
- package/dist/src/mcpl/tags.js +12 -2
- package/dist/src/mcpl/tags.js.map +1 -1
- package/dist/src/mcpl/tool-lifecycle.d.ts +11 -0
- package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -1
- package/dist/src/mcpl/tool-lifecycle.js +21 -0
- package/dist/src/mcpl/tool-lifecycle.js.map +1 -1
- package/dist/src/mcpl/tool-presence.d.ts +311 -0
- package/dist/src/mcpl/tool-presence.d.ts.map +1 -0
- package/dist/src/mcpl/tool-presence.js +697 -0
- package/dist/src/mcpl/tool-presence.js.map +1 -0
- package/dist/src/mcpl/tool-result-normalize.d.ts +9 -3
- package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.js +14 -6
- package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
- package/dist/src/mcpl/tool-signature.d.ts +46 -0
- package/dist/src/mcpl/tool-signature.d.ts.map +1 -0
- package/dist/src/mcpl/tool-signature.js +321 -0
- package/dist/src/mcpl/tool-signature.js.map +1 -0
- package/dist/src/mcpl/toolset-host.d.ts +251 -0
- package/dist/src/mcpl/toolset-host.d.ts.map +1 -0
- package/dist/src/mcpl/toolset-host.js +720 -0
- package/dist/src/mcpl/toolset-host.js.map +1 -0
- package/dist/src/mcpl/toolsets-module.d.ts +83 -0
- package/dist/src/mcpl/toolsets-module.d.ts.map +1 -0
- package/dist/src/mcpl/toolsets-module.js +523 -0
- package/dist/src/mcpl/toolsets-module.js.map +1 -0
- package/dist/src/mcpl/transport.d.ts +2 -2
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +3 -2
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +24 -2
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/mcpl/visible-content.d.ts +7 -9
- package/dist/src/mcpl/visible-content.d.ts.map +1 -1
- package/dist/src/mcpl/visible-content.js +21 -9
- package/dist/src/mcpl/visible-content.js.map +1 -1
- package/dist/src/module-registry.d.ts +27 -9
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +77 -17
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/discord/index.js +1 -1
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts +2 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +73 -28
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +108 -6
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +273 -57
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/workspace/answers.d.ts +22 -0
- package/dist/src/modules/workspace/answers.d.ts.map +1 -0
- package/dist/src/modules/workspace/answers.js +123 -0
- package/dist/src/modules/workspace/answers.js.map +1 -0
- package/dist/src/modules/workspace/branch-intent.d.ts +5 -3
- package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
- package/dist/src/modules/workspace/branch-intent.js +6 -2
- package/dist/src/modules/workspace/branch-intent.js.map +1 -1
- package/dist/src/modules/workspace/direct-write.d.ts +184 -0
- package/dist/src/modules/workspace/direct-write.d.ts.map +1 -0
- package/dist/src/modules/workspace/direct-write.js +417 -0
- package/dist/src/modules/workspace/direct-write.js.map +1 -0
- package/dist/src/modules/workspace/disk-agreement.d.ts +33 -11
- package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.js +48 -17
- package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
- package/dist/src/modules/workspace/edit-text.d.ts +27 -12
- package/dist/src/modules/workspace/edit-text.d.ts.map +1 -1
- package/dist/src/modules/workspace/edit-text.js +61 -29
- package/dist/src/modules/workspace/edit-text.js.map +1 -1
- package/dist/src/modules/workspace/effects.d.ts +10 -0
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +21 -14
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +308 -78
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +2103 -720
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +75 -63
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +366 -180
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/read-page.d.ts +41 -0
- package/dist/src/modules/workspace/read-page.d.ts.map +1 -0
- package/dist/src/modules/workspace/read-page.js +219 -0
- package/dist/src/modules/workspace/read-page.js.map +1 -0
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +26 -16
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/result-text.d.ts +68 -0
- package/dist/src/modules/workspace/result-text.d.ts.map +1 -0
- package/dist/src/modules/workspace/result-text.js +94 -0
- package/dist/src/modules/workspace/result-text.js.map +1 -0
- package/dist/src/modules/workspace/sync.d.ts +9 -0
- package/dist/src/modules/workspace/sync.d.ts.map +1 -1
- package/dist/src/modules/workspace/sync.js +14 -0
- package/dist/src/modules/workspace/sync.js.map +1 -1
- package/dist/src/modules/workspace/text.d.ts +29 -12
- package/dist/src/modules/workspace/text.d.ts.map +1 -1
- package/dist/src/modules/workspace/text.js +35 -33
- package/dist/src/modules/workspace/text.js.map +1 -1
- package/dist/src/modules/workspace/types.d.ts +137 -60
- 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.map +1 -1
- package/dist/src/modules/workspace/watcher.js +8 -3
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/prose-drafts.d.ts +4 -3
- package/dist/src/prose-drafts.d.ts.map +1 -1
- package/dist/src/prose-drafts.js +3 -2
- package/dist/src/prose-drafts.js.map +1 -1
- package/dist/src/reasoning-loss-notice.d.ts +23 -0
- package/dist/src/reasoning-loss-notice.d.ts.map +1 -0
- package/dist/src/reasoning-loss-notice.js +50 -0
- package/dist/src/reasoning-loss-notice.js.map +1 -0
- package/dist/src/reasoning-loss.d.ts +24 -0
- package/dist/src/reasoning-loss.d.ts.map +1 -0
- package/dist/src/reasoning-loss.js +102 -0
- package/dist/src/reasoning-loss.js.map +1 -0
- package/dist/src/send-tools.d.ts +3 -2
- package/dist/src/send-tools.d.ts.map +1 -1
- package/dist/src/send-tools.js +3 -2
- package/dist/src/send-tools.js.map +1 -1
- package/dist/src/sent-rows.d.ts +59 -0
- package/dist/src/sent-rows.d.ts.map +1 -0
- package/dist/src/sent-rows.js +145 -0
- package/dist/src/sent-rows.js.map +1 -0
- package/dist/src/silent-heartbeat.d.ts +17 -10
- package/dist/src/silent-heartbeat.d.ts.map +1 -1
- package/dist/src/silent-heartbeat.js.map +1 -1
- package/dist/src/stable-hash.d.ts +3 -0
- package/dist/src/stable-hash.d.ts.map +1 -0
- package/dist/src/stable-hash.js +15 -0
- package/dist/src/stable-hash.js.map +1 -0
- package/dist/src/stored-injections.d.ts +99 -0
- package/dist/src/stored-injections.d.ts.map +1 -0
- package/dist/src/stored-injections.js +106 -0
- package/dist/src/stored-injections.js.map +1 -0
- package/dist/src/text-as-stored.d.ts +4 -3
- package/dist/src/text-as-stored.d.ts.map +1 -1
- package/dist/src/text-as-stored.js +4 -3
- package/dist/src/text-as-stored.js.map +1 -1
- package/dist/src/thinking-drops.d.ts +74 -0
- package/dist/src/thinking-drops.d.ts.map +1 -0
- package/dist/src/thinking-drops.js +96 -0
- package/dist/src/thinking-drops.js.map +1 -0
- package/dist/src/tool-args.d.ts +12 -0
- package/dist/src/tool-args.d.ts.map +1 -1
- package/dist/src/tool-args.js +35 -1
- package/dist/src/tool-args.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts +9 -8
- package/dist/src/tool-image-ledger.d.ts.map +1 -1
- package/dist/src/tool-image-ledger.js +9 -8
- package/dist/src/tool-image-ledger.js.map +1 -1
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +3 -1
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts +12 -6
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +44 -17
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +176 -24
- package/dist/src/tool-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +411 -91
- package/dist/src/tool-result-history.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +17 -9
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +84 -37
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/tune-out/tools.d.ts +4 -1
- package/dist/src/tune-out/tools.d.ts.map +1 -1
- package/dist/src/types/agent.d.ts +217 -7
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +33 -9
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +39 -3
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +95 -9
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +91 -3
- package/dist/src/types/trace.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/agent.ts +661 -67
- package/src/api/server.ts +5 -4
- package/src/auto-continue.ts +43 -0
- package/src/code-execution/isolate/scripts.ts +11 -3
- package/src/cut-off-round.ts +98 -0
- package/src/framework.ts +6168 -1540
- package/src/gate/event-gate.ts +2895 -405
- package/src/gate/index.ts +10 -1
- package/src/gate/recipe-reconcile.ts +355 -0
- package/src/gate/reply-judge.ts +512 -0
- package/src/gate/types.ts +234 -9
- package/src/heartbeat/heartbeat.ts +804 -0
- package/src/heartbeat/reminder-time.ts +107 -0
- package/src/index.ts +11 -4
- package/src/mcpl/capability-mask.ts +3 -2
- package/src/mcpl/channel-registry.ts +1222 -468
- package/src/mcpl/conversation-router.ts +34 -16
- package/src/mcpl/convert-block.ts +14 -1
- package/src/mcpl/hook-orchestrator.ts +33 -6
- package/src/mcpl/inbound-source.ts +42 -69
- package/src/mcpl/index.ts +6 -1
- package/src/mcpl/inference-router.ts +79 -34
- package/src/mcpl/prose-grammar.ts +7 -0
- package/src/mcpl/protocol-family.ts +2 -0
- package/src/mcpl/push-coalescer.ts +51 -13
- package/src/mcpl/reference-fetcher.ts +201 -162
- package/src/mcpl/references.ts +851 -77
- package/src/mcpl/server-connection.ts +189 -11
- package/src/mcpl/tags.ts +13 -2
- package/src/mcpl/tool-lifecycle.ts +21 -0
- package/src/mcpl/tool-presence.ts +716 -0
- package/src/mcpl/tool-result-normalize.ts +18 -6
- package/src/mcpl/tool-signature.ts +316 -0
- package/src/mcpl/toolset-host.ts +727 -0
- package/src/mcpl/toolsets-module.ts +545 -0
- package/src/mcpl/transport.ts +3 -2
- package/src/mcpl/types.ts +25 -2
- package/src/mcpl/visible-content.ts +22 -9
- package/src/module-registry.ts +85 -26
- package/src/modules/discord/index.ts +1 -1
- package/src/modules/history/index.ts +70 -30
- package/src/modules/history/semantic.ts +308 -54
- package/src/modules/workspace/answers.ts +133 -0
- package/src/modules/workspace/branch-intent.ts +10 -5
- package/src/modules/workspace/direct-write.ts +460 -0
- package/src/modules/workspace/disk-agreement.ts +52 -21
- package/src/modules/workspace/edit-text.ts +84 -35
- package/src/modules/workspace/effects.ts +22 -13
- package/src/modules/workspace/index.ts +2142 -723
- package/src/modules/workspace/observe.ts +381 -177
- package/src/modules/workspace/read-page.ts +228 -0
- package/src/modules/workspace/reconcile.ts +27 -15
- package/src/modules/workspace/result-text.ts +121 -0
- package/src/modules/workspace/sync.ts +16 -0
- package/src/modules/workspace/text.ts +58 -32
- package/src/modules/workspace/types.ts +137 -60
- package/src/modules/workspace/watcher.ts +8 -3
- package/src/prose-drafts.ts +4 -3
- package/src/reasoning-loss-notice.ts +62 -0
- package/src/reasoning-loss.ts +120 -0
- package/src/send-tools.ts +3 -2
- package/src/sent-rows.ts +162 -0
- package/src/silent-heartbeat.ts +17 -10
- package/src/stable-hash.ts +14 -0
- package/src/stored-injections.ts +131 -0
- package/src/text-as-stored.ts +4 -3
- package/src/thinking-drops.ts +135 -0
- package/src/tool-args.ts +34 -1
- package/src/tool-image-ledger.ts +9 -8
- package/src/tool-presentation.ts +3 -1
- package/src/tool-result-guard.ts +45 -17
- package/src/tool-result-history.ts +471 -90
- package/src/tune-out/coordinator.ts +80 -37
- package/src/tune-out/tools.ts +4 -1
- package/src/types/agent.ts +220 -7
- package/src/types/events.ts +33 -9
- package/src/types/framework.ts +36 -3
- package/src/types/module.ts +91 -9
- package/src/types/trace.ts +94 -3
package/README.md
CHANGED
|
@@ -118,11 +118,11 @@ interface Module {
|
|
|
118
118
|
|
|
119
119
|
// Optional
|
|
120
120
|
onAgentSpeech?(agentName: string, content: ContentBlock[], context: SpeechContext): Promise<void>;
|
|
121
|
-
gatherContext?(agentName: string): Promise<
|
|
121
|
+
gatherContext?(agentName: string): Promise<ModuleContextInjection[]>;
|
|
122
122
|
}
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
An `EventResponse` can add/edit/remove messages, request inference, signal tool changes,
|
|
125
|
+
An `EventResponse` can add/edit/remove messages, update module state, request inference, and signal tool changes. The framework applies its message changes, then its state update, then its inference request; when one of these throws, what came before it stays applied, that step may have taken effect in part, and the rest of that response isn't:
|
|
126
126
|
|
|
127
127
|
```typescript
|
|
128
128
|
return {
|
|
@@ -150,7 +150,7 @@ Each agent has a `ContextManager` (from `@connectome/context-manager`) that main
|
|
|
150
150
|
- **PassthroughStrategy** - No compression, raw message replay up to budget
|
|
151
151
|
- **AutobiographicalStrategy** - Chunks old messages and summarizes them into diary entries, preserving recent context uncompressed
|
|
152
152
|
|
|
153
|
-
Before inference, modules and MCPL hooks can inject additional context via `gatherContext()`.
|
|
153
|
+
Before inference, modules and MCPL hooks can inject additional context via `gatherContext()`. An `afterUser` injection is stored in the agent's window, as the message `compile()` would have placed after the last user message, so it stays where the agent saw it: the replies after it keep their thinking, and the cache keeps the turns before it. A source's unchanged content isn't stored again while the copy the agent will read as current has it whole: the one its last request held, or a newer one a start stored whose compile then didn't record (it threw, or the start failed before it); once a fold has summarized it or the strategy's window has passed it, it's stored again, as one more row. Where a changed one lands right after the agent's own latest message, with no one else's message between, `[Continue]` still ends the request, after it. A stored row is history to the strategy, capped, sharded, budgeted and folded like any message. Its metadata carries `system: true`, `kind: 'context-injection'` and `contextInjection: { agent, namespace, contentHash, part, parts }`, which `storedInjectionMarkOf` reads, and every other agent's view leaves it out. A module's injection can set `placedEachCompile: true` to be placed by `compile()` at each start instead, near the end, at the cost of the thinking of every reply after its old place.
|
|
154
154
|
|
|
155
155
|
### Persistence
|
|
156
156
|
|
|
@@ -347,8 +347,9 @@ three ways:
|
|
|
347
347
|
configuration error: `allowHostCommands: true`, an `enabledCapabilities`
|
|
348
348
|
pattern that matches a capability denied by default, `channelSubscription:
|
|
349
349
|
'auto'` or a non-empty list, a scope's non-empty `whitelist`, a
|
|
350
|
-
`toolLifecycle` `observe` or `inputs` block,
|
|
351
|
-
`toolLifecycle.maxInputBytes` or an `autofetch` bound above its default
|
|
350
|
+
`toolLifecycle` `observe` or `inputs` block, a
|
|
351
|
+
`toolLifecycle.maxInputBytes` or an `autofetch` bound above its default,
|
|
352
|
+
and `toolHints: true`.
|
|
352
353
|
A setting
|
|
353
354
|
that only takes something away, or repeats a default, is already
|
|
354
355
|
satisfied, so it is accepted: `enabledFeatureSets` and the rest of
|
|
@@ -429,6 +430,94 @@ backlog is simply its unread backlog. Receipts and subject history are kept in
|
|
|
429
430
|
the `mcpl/coalescing` state (retry window 1 h); audit lines are
|
|
430
431
|
`mcpl:coalescing` trace events.
|
|
431
432
|
|
|
433
|
+
#### Tool presence and toolsets (RFC-014)
|
|
434
|
+
|
|
435
|
+
A server configured with `toolHints: true` (default false) is offered
|
|
436
|
+
`experimental.mcpl.toolHints`, and its hints count only if it advertised
|
|
437
|
+
`toolHints` too. Without it nothing changes: every tool is listed as before,
|
|
438
|
+
and the host advertises and reads nothing new.
|
|
439
|
+
|
|
440
|
+
With it, the server's static tools stay in the tool list as before, and its
|
|
441
|
+
dynamic tools (those in a toolset, or hinted `mcpl/presence: "dynamic"`) never
|
|
442
|
+
enter it, since every change to the list rebuilds the prompt cache. The
|
|
443
|
+
framework registers a `toolsets` module with four constant tools:
|
|
444
|
+
|
|
445
|
+
- `toolsets--open {server?, toolset?, instance?, options?}` opens a toolset (or
|
|
446
|
+
a named instance of one), and answers with what the server shows on opening
|
|
447
|
+
and the tools usable now;
|
|
448
|
+
- `toolsets--act {server?, tool, instance?, args?}` calls a dynamic tool down
|
|
449
|
+
the same path as a direct call of it (the agent's `allowedTools`, the
|
|
450
|
+
server's tool policy, the state exchange, the reading of its result, RFC-007
|
|
451
|
+
observers and RFC-008 class rules, which see the server's tool and its class),
|
|
452
|
+
with only the instance added, in
|
|
453
|
+
`_meta["mcpl/instance"]`. It first checks `args` against the definition in
|
|
454
|
+
force for that instance; that check is bounded, and leaves `pattern` and
|
|
455
|
+
anything nested or branching too far to the server, which checks every
|
|
456
|
+
call itself;
|
|
457
|
+
- `toolsets--look {server?, toolset?, instance?, tool?}` restates what is open
|
|
458
|
+
and what can be opened, or one tool's signature, description, class and
|
|
459
|
+
input schema. It
|
|
460
|
+
re-reads each server that presents toolsets first, and says so when it
|
|
461
|
+
couldn't; what that changed
|
|
462
|
+
is in the answer when look restates everything, and otherwise told as a
|
|
463
|
+
notice;
|
|
464
|
+
- `toolsets--close {server?, toolset?, instance?}` closes it.
|
|
465
|
+
|
|
466
|
+
`server` can be left out when only one server has the name. By our reading of
|
|
467
|
+
the code, a server with no toolsets stops presenting them once its latest `tools/list` has no dynamic
|
|
468
|
+
tool, so until the rebuild, act takes its last one only with `server` named.
|
|
469
|
+
Hint changes apply
|
|
470
|
+
as their message is read, in `rev` order, whatever becomes of the message (a
|
|
471
|
+
refused push, a result that came after its timeout). A move between static and
|
|
472
|
+
dynamic takes effect when the server's `tools/list` states it, and the tool
|
|
473
|
+
list follows at its next rebuild that lists the server, whichever refresh
|
|
474
|
+
brings it (a move is no reason to rebuild the tool list early). Until then the
|
|
475
|
+
tool is called at either place, where the tool list shows it or where the
|
|
476
|
+
server's latest list put it (RFC-014 §4.2 keeps it working where it is until
|
|
477
|
+
the move applies), and
|
|
478
|
+
once that rebuild has published the list, a notice says where it went. A list
|
|
479
|
+
read while a rebuild is under way can undo a move that rebuild then publishes;
|
|
480
|
+
neither is told, and the next rebuild puts the tool back.
|
|
481
|
+
A skipped rev re-reads `tools/list` and then `toolsets/list`, which the host
|
|
482
|
+
also reads after every (re)connect, adopting what the server kept open and
|
|
483
|
+
never re-opening anything.
|
|
484
|
+
What changed is told where it happened: after a call's own result, after the
|
|
485
|
+
push that explains it, or as a notice (`kind: 'mcpl-toolsets'`, which wakes
|
|
486
|
+
nothing) for a standalone `tools/hints`, a late result, an adoption, a
|
|
487
|
+
recovery, or a call whose result may not reach the agent (a script's, a
|
|
488
|
+
module's or a host's, or one the framework makes itself); an open, close or
|
|
489
|
+
look made that way also shows its caller the change, unless the change has
|
|
490
|
+
already gone as a notice (below). A dynamic tool's change also goes as a notice
|
|
491
|
+
when it wouldn't fit whole within its result's inline cap, or when its call
|
|
492
|
+
fails after the result was read. A call's change also goes as a notice, ahead of its
|
|
493
|
+
result, when a later change goes to the agent before the call's caller has
|
|
494
|
+
taken it, so changes are told in the order they were read (the agent's window
|
|
495
|
+
can still show a call's result, a push's event, or a change its taker couldn't
|
|
496
|
+
show after a change read later). The model's own call's change counts as told
|
|
497
|
+
once its result is handed back: if the turn is stopped while the call is out
|
|
498
|
+
(or, by our reading of the code, the agent is gone), the result is dropped and the change with it, and
|
|
499
|
+
`toolsets--look` shows the state it left. Notices and reminders
|
|
500
|
+
need the server's `pushEvents` grant, like any delivery; without it, a change
|
|
501
|
+
that would go as a notice is dropped, and `toolsets--look` shows the state. A new tool's first sentence is told with its
|
|
502
|
+
definition until text describing it has reached the model, except that, by our reading of the code, a puppet's
|
|
503
|
+
open, close or look whose result the store refuses has already counted it. Suggestions are shown, never acted on. Each
|
|
504
|
+
`ended` id is told once while the
|
|
505
|
+
host runs (told ids are kept in memory), short of rare interleavings, such as a
|
|
506
|
+
`toolsets--look` overlapping other reads of the same server, that can tell one
|
|
507
|
+
twice. When an
|
|
508
|
+
open toolset's announcements have left an agent's context (compressed or out
|
|
509
|
+
of the window), the module's `gatherContext` restates what is open, as a
|
|
510
|
+
stored `afterUser` injection (namespace `mcpl-toolsets`), at that agent's next
|
|
511
|
+
start.
|
|
512
|
+
|
|
513
|
+
A dynamic tool called by its prefixed name is refused, pointing at
|
|
514
|
+
`toolsets--act`, unless the tool list or the server's latest list shows it as
|
|
515
|
+
static (a move waiting for its rebuild). Calls to an undeclared toolset's
|
|
516
|
+
tools are refused while the host has that group closed (RFC-014 §5.4), except
|
|
517
|
+
by a tool's listed name until the rebuild that publishes its move into the
|
|
518
|
+
group. Projection and surface mode are not implemented: a `surface` server's
|
|
519
|
+
static tools are listed like any server's.
|
|
520
|
+
|
|
432
521
|
#### Per-channel conversation routing (deprecated)
|
|
433
522
|
|
|
434
523
|
> **Deprecated: `FrameworkConfig.conversations` (`ConversationRouter`).** Per-channel conversation routing sends each channel's traffic to its own fork agent, spawned from a template agent and closed after an idle TTL. It is being retired ([#235](https://github.com/anima-research/agent-framework/issues/235)). Its `'mention'` bind/trigger rule, the default for channels, reads `metadata.mentioned`, which discord-mcpl does not set, so on Discord channels an @-mention never binds a fork or triggers a bound one. Don't adopt it in new hosts. Existing configurations still route exactly as before, and the framework logs one `[deprecated]` line when it is created with `conversations` set. Removal is a follow-up.
|
|
@@ -439,7 +528,7 @@ the `mcpl/coalescing` state (retry window 1 h); audit lines are
|
|
|
439
528
|
2. **Drive**: Framework iterates stream events (tokens, tool-calls, complete, error)
|
|
440
529
|
3. **Tool yield**: Stream yields tool calls → framework dispatches concurrently → collects results
|
|
441
530
|
4. **Resume**: All results in → stream resumes with tool results
|
|
442
|
-
5. **Budget restart**: If input tokens exceed `maxStreamTokens`, the stream is cancelled, context is recompressed, and a fresh stream starts
|
|
531
|
+
5. **Budget restart**: If input tokens exceed `maxStreamTokens`, the stream is cancelled, context is recompressed, and a fresh stream starts. An agent whose model binds its thinking (`thinkingBinding.binds`) with `physicalWindowTokens` set skips this, and the window projection restarts it instead before a request the window can't hold
|
|
443
532
|
6. **Complete**: Final response saved to context, agent returns to idle
|
|
444
533
|
|
|
445
534
|
### Abort / Cancellation
|
|
@@ -451,9 +540,11 @@ framework.abortInference('assistant', 'user requested stop');
|
|
|
451
540
|
|
|
452
541
|
The non-streaming path uses `AbortSignal` forwarded to `membrane.stream()`, which returns an `AbortedResponse` with partial content. The streaming path cancels the `YieldingStream` directly.
|
|
453
542
|
|
|
454
|
-
A turn whose stream is cancelled this way, or by `agent.cancelStream()`, ends as a stop, whether the stream reports the cancel as `aborted`, as an `error`, or by just closing: one `inference:aborted` carrying the caller's reason (`user` when none was given), a `[turn-interrupted]` note in the agent's context, and never `inference:exhausted`, which is for failed inferences. A stream that membrane aborts on its own, at a deadline or on an error (reason `timeout` or `error`), is a failed inference. `stop()` and an operator's quiesce abandon end a turn as a stop too, with their own reasons, `shutdown` and `quiesce_abandoned`, and write no note. A stopped stream still writes its inference-log row, with `success: false`.
|
|
543
|
+
A turn whose stream is cancelled this way, or by `agent.cancelStream()`, ends as a stop, whether the stream reports the cancel as `aborted`, as an `error`, or by just closing: one `inference:aborted` carrying the caller's reason (`user` when none was given), a `[turn-interrupted]` note in the agent's context, and never `inference:exhausted`, which is for failed inferences. A stream that membrane aborts on its own, at a deadline or on an error (reason `timeout` or `error`), is a failed inference. `stop()` and an operator's quiesce abandon end a turn as a stop too, with their own reasons, `shutdown` and `quiesce_abandoned`, and write no note, except the `[speech-not-posted]` notice when the turn's rounds left speech unposted (XML tool mode, or a membrane without `roundContent`; see below). A stopped stream still writes its inference-log row, with `success: false`.
|
|
544
|
+
|
|
545
|
+
A caller's stop and an operator's quiesce abandon also reach a turn that has no live stream: one running its modules' `gatherContext`, its MCPL hooks or its compile, one waiting to retry a failed inference or compile (`abortInference()` and an operator's abandon end the wait, and a stop through `Agent.cancelStream()` waits for it to run out), and one whose tool-result guard is waiting to retry after a refusal, which holds only the round's finished stream. The turn ends at its next check, before it sends anything more, as a stop on a live stream ends it, and a turn whose compile fails after the stop ends at the failure, before a provider hold, the error policy's retry or `inference:exhausted`. A caller's stop leaves the note saying the turn was stopped before it sent anything or before it finished, and an operator's abandon leaves none, except the `[speech-not-posted]` notice when the turn's rounds left speech unposted. `abortInference()` returns `true` for such a turn. In the guard's wait, `stop()` ends the turn as a stop with reason `shutdown`, and an operator's abandon ends it as the abandon, even when a caller's stop came first; with both, it ends as `stop()`'s. `stop()` drops a turn in its hooks, its compile or a wait to retry before it sends anything, as before, and drops one whose compile fails while it runs, once a caller's stop has reached it, rather than ending it as that stop. While the failure of a turn's stream is reported (`inference:failed`), the agent no longer holds that stream, so `abortInference()` from a listener reports `false`. A failure to build a turn's request is reported while the turn's check is still ahead, so there `abortInference()` reports `true`, and the turn ends at that check. A caller's stop made where no check of a turn is ahead stops nothing, and doesn't end the agent's next turn: while the agent is idle, while a turn finishes its last delivery, and while a non-streaming turn's tool results wait to start the turn's next call. A turn whose continuation (a budget restart's, or a tool-result guard's retry) waits to start, or whose failed call a provider-capacity hold or a provider's stated wait keeps for its retry, is ended by `abortInference()`, by an operator's quiesce abandon and by `stop()`: the continuation or retry is dropped, and the turn ends with the caller's reason, `quiesce_abandoned` or `shutdown`. After `abortInference()` or an abandon, wakes that arrived meanwhile still run (after the abandon, once the host resumes): those a hold keeps beside the retry, and those the scheduler merged into the retry's or the continuation's start before that start began, which the stop or the abandon puts back in the queue. A stop through `Agent.cancelStream()` stops nothing there.
|
|
455
546
|
|
|
456
|
-
|
|
547
|
+
In XML tool mode, or with a membrane that gives a tool round no `roundContent`, such a round's speech reaches a channel only when its stream completes. When the stream ends any other way (a failure, a stop, a tool that ends the turn, an error policy's retry, a context-budget or tool-result-guard restart, a quiesce abandon or `stop()`), the rounds' words are already in the agent's context, and a `[speech-not-posted]` notice tells the agent that nothing it wrote before its tool calls in those rounds was posted, so it can send what should go out again. It's written once for those rounds: where the turn ends, or before a retry's or a restart's request is sent. A turn its own `skip_reply` ends, a silent turn, a round still waiting on its tools when its stream ends (which never reaches the context) and the rounds of a stream that completes get none. In XML tool mode with thinking on, a round whose text was only thinking gets the notice too, since the framework has only the round's raw text there. A failed turn's `[inference-failed]` note says that its earlier rounds ran when any round reached the context with its results, and that a round's tool calls were started and may have taken effect when any of its streams ended before that round's results came back; a caller's stop says the latter in its `[turn-interrupted]` note too. A turn that fails, or that a caller stops, writes no `[delivered]` receipt, so when its rounds' plain speech was delivered live (native tool mode, in locus or hybrid routing), its `[inference-failed]` note, or the stop's `[turn-interrupted]` note, says that speech was handed on for delivery as written and that no `[delivered]` line was written for it. When some of its speech was still being routed as the turn ended, the note also says it may yet be posted and to check the channel before sending it again. A delivery that finished undelivered gets neither: a channel delivery's `[discord-send-failed]` note, or a refused `>>>` envelope's bounce, already says what happened. A quiesce abandon and `stop()` write neither note.
|
|
457
548
|
|
|
458
549
|
## API Server
|
|
459
550
|
|
package/dist/src/agent.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { Membrane, NormalizedRequest, ContentBlock, YieldingStream } from '@animalabs/membrane';
|
|
1
|
+
import type { Membrane, NormalizedMessage, NormalizedRequest, ContentBlock, ThinkingBindingEntry, YieldingStream } from '@animalabs/membrane';
|
|
2
2
|
import type { CacheWireReceipt } from './kv-unified-wire.js';
|
|
3
3
|
import { ToolResultGuard } from './tool-result-guard.js';
|
|
4
|
+
import { type PlacedDrop } from './thinking-drops.js';
|
|
5
|
+
import { type SentRow } from './sent-rows.js';
|
|
4
6
|
import { type RequestOnlyPrompt, type SilentHeartbeatTick } from './silent-heartbeat.js';
|
|
5
7
|
import { type ResolvedClockConfig } from './clock-rows.js';
|
|
6
8
|
export interface ActivationRequestOptions {
|
|
@@ -9,13 +11,46 @@ export interface ActivationRequestOptions {
|
|
|
9
11
|
/** A request that will never be sent (a preview): compile it as a dry
|
|
10
12
|
* run (see `compileWithInjections` for what that leaves alone). */
|
|
11
13
|
dryRun?: boolean;
|
|
14
|
+
/** Messages added to the compile's: a preview's stand-in for the context
|
|
15
|
+
* injections a start would store before its compile
|
|
16
|
+
* (stored-injections.ts), put where that compile would render them, as
|
|
17
|
+
* the window's newest rows. A preview stores nothing, so the compile
|
|
18
|
+
* doesn't weigh them against the budget or shape them as it would the
|
|
19
|
+
* stored rows. */
|
|
20
|
+
appendedMessages?: NormalizedMessage[];
|
|
21
|
+
/** `false`: the caller retries this stream's failures itself, so membrane
|
|
22
|
+
* sends a failed round once and hands the error up. The framework's turns
|
|
23
|
+
* pass it (its errorPolicy is their retry layer); a direct caller of
|
|
24
|
+
* startStream keeps membrane's retries. */
|
|
25
|
+
membraneRetries?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** A compile's render stats, as context-manager's `getRenderStats()` types
|
|
28
|
+
* them; each compile carries its own, where the strategy records them, in
|
|
29
|
+
* `CompileResult.renderStats`. */
|
|
30
|
+
export type RenderStats = NonNullable<ReturnType<ContextManager['getRenderStats']>>;
|
|
31
|
+
/** The render stats of the dry compile that built `request`, or null: see
|
|
32
|
+
* `AgentFramework.getRequestCompileStats`. */
|
|
33
|
+
export declare function dryCompileStatsOf(request: object): RenderStats | null;
|
|
34
|
+
/**
|
|
35
|
+
* What a compile is told when the agent's model binds its thinking: `compile()`'s options for a context manager
|
|
36
|
+
* that keeps a thinking-binding record, as agent-framework holds the binding (with the participant whose messages
|
|
37
|
+
* are the agent's own replies) and as digests of the request's head (bindingCompileOptions).
|
|
38
|
+
*/
|
|
39
|
+
export interface BindingCompileOptions {
|
|
40
|
+
thinkingBinding?: {
|
|
41
|
+
binds: boolean;
|
|
42
|
+
dropBlock: boolean;
|
|
43
|
+
participant: string;
|
|
44
|
+
};
|
|
45
|
+
identity?: RequestIdentity;
|
|
12
46
|
}
|
|
13
47
|
export interface StartStreamResult {
|
|
14
48
|
stream: YieldingStream;
|
|
15
49
|
request: NormalizedRequest;
|
|
16
50
|
/** The request-only `[Continue]` prompt this request's reply follows, if
|
|
17
51
|
* any, read from the request: a new one when it ends on `[Continue]`;
|
|
18
|
-
* else, when it ends on tool results,
|
|
52
|
+
* else, when it ends on tool results, or on tool results and then
|
|
53
|
+
* stored context injections alone, the prompt of the reply that called
|
|
19
54
|
* those tools (`toolLoopPrompt`); else none. The framework stamps the
|
|
20
55
|
* reply's rows with it (`metadata.promptedBy`), for later compiles to
|
|
21
56
|
* render it before them. */
|
|
@@ -25,21 +60,54 @@ export interface StartStreamResult {
|
|
|
25
60
|
wireReceipt: CacheWireReceipt;
|
|
26
61
|
} | undefined;
|
|
27
62
|
drainKvSubmissionIds?: () => string[];
|
|
63
|
+
/** Where each block a call of this stream reports the provider dropped came from: a stored reply this
|
|
64
|
+
* request's compile rendered, a round the stream appended, or neither (placeThinkingDrops). Optional, so a
|
|
65
|
+
* stand-in for the stream start needn't supply it; without it, no drop can be placed. */
|
|
66
|
+
placeDrops?: (entries: readonly ThinkingBindingEntry[]) => PlacedDrop[];
|
|
67
|
+
/** The compile's `thinkingRecordedAfter`, when it gave one: a reply stored at or below it predates the branch's
|
|
68
|
+
* thinking-binding record, so the provider may drop its thinking with no strip having missed. */
|
|
69
|
+
thinkingRecordedAfter?: number;
|
|
70
|
+
/** The key (`branchKey`) of the branch the compile read, when its provenance names one. */
|
|
71
|
+
thinkingBranch?: string;
|
|
72
|
+
/** Tells the context manager what the stream's later rounds carried after the compiled messages, every round so
|
|
73
|
+
* far in sent order, with this request's head (context-manager's `noteRequestSent`). Present only where the
|
|
74
|
+
* model binds its thinking and the context manager keeps a record it can be told of. */
|
|
75
|
+
noteRequestSent?: (rows: readonly SentRow[]) => boolean;
|
|
76
|
+
/** The stored bodies the request's compile carried, by each body's first message id (its provenance's raw bodies).
|
|
77
|
+
* Absent when the compile reports no provenance. */
|
|
78
|
+
carriedBodies?: ReadonlySet<MessageId>;
|
|
28
79
|
}
|
|
29
|
-
import type { ContextManager, TokenBudget, ContextInjection, CompileResult, MessageMetadata } from '@animalabs/context-manager';
|
|
80
|
+
import type { ContextManager, TokenBudget, ContextInjection, CompileResult, MessageId, MessageMetadata, RequestIdentity, ThinkingStrip } from '@animalabs/context-manager';
|
|
30
81
|
import type { AgentConfig, AgentState, SameRoundThinkTextPolicy, SameRoundThinkTextPolicySource, ToolCallId, ToolCall, ToolResult, ToolDefinition, AgentInfo, InferenceResult, InferenceOptions, AgentRuntimeSettingsPatch, AgentRuntimeSettingsSnapshot, AgentRuntimeSettingsOverrides } from './types/index.js';
|
|
31
82
|
/**
|
|
32
83
|
* Refuse an agent config whose `promptCaching`, `toolResultGuard`,
|
|
33
|
-
* `toolWrapperProseGuard`, `thinking.enabled
|
|
34
|
-
* holds anything but true or false
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* the
|
|
84
|
+
* `toolWrapperProseGuard`, `thinking.enabled`, `thinkingBinding.dropBlock`,
|
|
85
|
+
* `thinkingBinding.binds` or `refusalHandling.autoRewind` holds anything but true or false
|
|
86
|
+
* (assertBooleanSetting, where null counts as left out), or whose `thinking`, `thinkingBinding` or
|
|
87
|
+
* `refusalHandling` is anything but an object, null or false (holdsSettings),
|
|
88
|
+
* or whose `autoContinue` resolveAutoContinue refuses. The constructor runs it
|
|
89
|
+
* first, so the rule holds wherever an Agent is built. `create()` also runs it
|
|
90
|
+
* for each of its agents before anything opens, and `createEphemeralAgent`
|
|
91
|
+
* before it reserves the name, so a refusal there leaves nothing behind.
|
|
92
|
+
* Membrane reads `thinking.enabled`, and the refusal is here because the
|
|
93
|
+
* setting is AgentConfig's.
|
|
41
94
|
*/
|
|
42
95
|
export declare function assertAgentSwitches(config: AgentConfig): void;
|
|
96
|
+
/** `AutoContinueConfig.maxConsecutive` when left out. */
|
|
97
|
+
export declare const DEFAULT_AUTO_CONTINUE_MAX = 3;
|
|
98
|
+
/**
|
|
99
|
+
* `AgentConfig.autoContinue` resolved: undefined when off (left out, null or
|
|
100
|
+
* false), else its cap. `true` takes the default cap; an object takes
|
|
101
|
+
* `maxConsecutive`, a whole number from 1 to 20 (the default when left out).
|
|
102
|
+
* Any other value is refused.
|
|
103
|
+
*/
|
|
104
|
+
export declare function resolveAutoContinue(config: AgentConfig): {
|
|
105
|
+
maxConsecutive: number;
|
|
106
|
+
} | undefined;
|
|
107
|
+
export declare function branchKey(branch: {
|
|
108
|
+
readonly id: string;
|
|
109
|
+
readonly created: number;
|
|
110
|
+
}): string;
|
|
43
111
|
/**
|
|
44
112
|
* An agent wraps a context manager and manages inference state.
|
|
45
113
|
*/
|
|
@@ -63,6 +131,12 @@ export declare class Agent {
|
|
|
63
131
|
* blocks are preserved through Chronicle.
|
|
64
132
|
*/
|
|
65
133
|
readonly thinking: AgentConfig['thinking'];
|
|
134
|
+
/** Whether requests ask the provider to drop signed thinking whose earlier
|
|
135
|
+
* conversation changed (see AgentConfig.thinkingBinding.dropBlock). */
|
|
136
|
+
private readonly thinkingDropBlock;
|
|
137
|
+
/** Whether the model binds its signed thinking to the conversation before
|
|
138
|
+
* it (see AgentConfig.thinkingBinding.binds). */
|
|
139
|
+
private readonly thinkingBinds;
|
|
66
140
|
/** Refusal auto-rewind policy (see AgentConfig.refusalHandling). */
|
|
67
141
|
readonly refusalHandling: AgentConfig['refusalHandling'];
|
|
68
142
|
readonly toolResultGuard: ToolResultGuard;
|
|
@@ -70,6 +144,11 @@ export declare class Agent {
|
|
|
70
144
|
readonly proseRouting: 'locus' | 'explicit' | 'hybrid' | 'disabled';
|
|
71
145
|
/** Exact whole-response known-tool wrapper containment (default off). */
|
|
72
146
|
readonly toolWrapperProseGuard: boolean;
|
|
147
|
+
/** Continuation after a turn the model ends itself (see
|
|
148
|
+
* AgentConfig.autoContinue); undefined when off. */
|
|
149
|
+
readonly autoContinue: {
|
|
150
|
+
maxConsecutive: number;
|
|
151
|
+
} | undefined;
|
|
73
152
|
/** Clock rows' interval and precision (see AgentConfig.clock); undefined
|
|
74
153
|
* when the agent writes none of its own (a resident still reads those
|
|
75
154
|
* another resident writes into the shared slot). */
|
|
@@ -402,6 +481,48 @@ export declare class Agent {
|
|
|
402
481
|
branch: string;
|
|
403
482
|
sequence: number;
|
|
404
483
|
} | null;
|
|
484
|
+
/**
|
|
485
|
+
* The newest consumed watermark a request carried that was answered: its
|
|
486
|
+
* round's tool calls, or its completion, came back. A message a boundary
|
|
487
|
+
* injected counts as heard only once a request carrying it is answered;
|
|
488
|
+
* the consumed watermark moves when the stream is handed it, before its
|
|
489
|
+
* request runs, so a request that fails, ending its stream with an error,
|
|
490
|
+
* leaves this as it was.
|
|
491
|
+
*/
|
|
492
|
+
private answeredWatermark;
|
|
493
|
+
getAnsweredWatermark(): {
|
|
494
|
+
branch: string;
|
|
495
|
+
sequence: number;
|
|
496
|
+
} | null;
|
|
497
|
+
/** A request that carried `watermark` was answered. Requests are answered
|
|
498
|
+
* in the order they're sent, and the consumed watermark only advances
|
|
499
|
+
* within a branch, so the latest is the newest. */
|
|
500
|
+
markAnswered(watermark: {
|
|
501
|
+
branch: string;
|
|
502
|
+
sequence: number;
|
|
503
|
+
} | null): void;
|
|
504
|
+
/**
|
|
505
|
+
* Per destination (a server's channel, by its key), the newest consumed
|
|
506
|
+
* watermark the agent had read when it published there by a route the
|
|
507
|
+
* framework sees (its prose, a sleep's announcement, a channel_publish, a
|
|
508
|
+
* draft resend, or a send tool whose channel the framework records), on
|
|
509
|
+
* the branch it was taken on. A wake that carries a channel, unless it's
|
|
510
|
+
* marked ambient (InferenceRequest.ambient), keeps its turn unless the
|
|
511
|
+
* agent spoke there after reading the write the wake is for. It
|
|
512
|
+
* lives as long as this Agent: an agent made again starts it empty, and
|
|
513
|
+
* such a wake then stays.
|
|
514
|
+
*/
|
|
515
|
+
private publishedThrough;
|
|
516
|
+
/** Note a publish into `destination` (its key), made having read through
|
|
517
|
+
* `readThrough`: the consumed watermark when its words were written, or
|
|
518
|
+
* its call made. */
|
|
519
|
+
notePublished(destination: string, readThrough: {
|
|
520
|
+
branch: string;
|
|
521
|
+
sequence: number;
|
|
522
|
+
} | null): void;
|
|
523
|
+
/** Whether the agent published into `destination` (its key) having read
|
|
524
|
+
* the row stored at `sequence` on `branch`. */
|
|
525
|
+
publishedAfterReading(destination: string, branch: string, sequence: number): boolean;
|
|
405
526
|
/** Mark everything currently stored as consumed (the agent's creation, at
|
|
406
527
|
* boot or later, and a tool boundary that injected messages into a live
|
|
407
528
|
* stream declaring it carries them; see consumedWatermark). */
|
|
@@ -432,14 +553,114 @@ export declare class Agent {
|
|
|
432
553
|
* reaches here).
|
|
433
554
|
*/
|
|
434
555
|
private applyCompileWatermark;
|
|
556
|
+
/**
|
|
557
|
+
* The branch now (`branchKey`) and its head, as `pendingWatermark` reads it: a message stored on that branch later
|
|
558
|
+
* has a larger sequence. Sequences are numbered per branch, so one compares with another only on the same branch.
|
|
559
|
+
*/
|
|
560
|
+
branchHead(): {
|
|
561
|
+
branch: string;
|
|
562
|
+
sequence: number;
|
|
563
|
+
} | undefined;
|
|
435
564
|
/** The watermark a successful compile will establish (taken before, applied after). */
|
|
436
565
|
private pendingWatermark;
|
|
437
566
|
/** A committing compile, as for a request that is sent: the context
|
|
438
567
|
* manager commits what it commits for one, the consumed watermark moves,
|
|
439
568
|
* and a prepared budget change settles. To inspect what the agent would
|
|
440
569
|
* see, use the framework's `previewActivation`, which compiles as a dry
|
|
441
|
-
* run.
|
|
570
|
+
* run. It isn't told the agent's thinking binding (`thinkingBinding.binds`),
|
|
571
|
+
* so a context manager that keeps a thinking-binding record neither reads
|
|
572
|
+
* nor writes the record here, and what it returns keeps thinking whose
|
|
573
|
+
* earlier conversation changed. */
|
|
442
574
|
compileContext(budget?: TokenBudget): Promise<CompileResult>;
|
|
575
|
+
/**
|
|
576
|
+
* The stored context injections of this agent's that the last compile it
|
|
577
|
+
* built to send rendered (stored-injections.ts), the framework's activation
|
|
578
|
+
* request's or the direct API's: for each namespace and content, the parts
|
|
579
|
+
* the compile held, and the branch it read. A compile built to send whose
|
|
580
|
+
* request then isn't sent (a stop, a failure) still records: its rows stay
|
|
581
|
+
* in the window all the same. Undefined before the first, as after a
|
|
582
|
+
* restart. The framework's same-content skip reads it (renderedInjection).
|
|
583
|
+
*/
|
|
584
|
+
private renderedInjections?;
|
|
585
|
+
/**
|
|
586
|
+
* Per branch (by id and created), the point a stored injection on it has
|
|
587
|
+
* to come after to have been in no request yet (unsentInjection): the
|
|
588
|
+
* newest row of this agent's window on that branch when the first plan
|
|
589
|
+
* there since its last compile built to send (a start's, or a preview's,
|
|
590
|
+
* which stores nothing) asked about a unit, before that plan's start
|
|
591
|
+
* stored anything. Each compile built to send that records what it
|
|
592
|
+
* held unsets its branch's, a restart unsets them all, and a plan asks
|
|
593
|
+
* here before it stores a unit, so every one of this agent's stored
|
|
594
|
+
* injections on a branch after its point was stored since that compile.
|
|
595
|
+
* Kept per branch, so a start or preview on another branch doesn't move
|
|
596
|
+
* this one's past a copy no request has had.
|
|
597
|
+
*/
|
|
598
|
+
private readonly unsentSince;
|
|
599
|
+
/**
|
|
600
|
+
* A host's hook, called with the messages of each compile built to send
|
|
601
|
+
* (never a dry run), as the compile is recorded: what the request carries,
|
|
602
|
+
* after compression and the window have done their work. The framework
|
|
603
|
+
* uses it to tell when an MCPL toolset's announcement has left the context
|
|
604
|
+
* (RFC-014 §8.3 reminders). It must not change the messages; one that
|
|
605
|
+
* throws is logged, and the start goes on.
|
|
606
|
+
*/
|
|
607
|
+
onCompiledToSend?: (messages: readonly unknown[]) => void;
|
|
608
|
+
/**
|
|
609
|
+
* A host's hook, called with each committing compile's `thinkingStrip` (never a dry run's) and the key of the
|
|
610
|
+
* branch it read (`branchKey`), as the compile returns, whether or not its request is then sent, since the
|
|
611
|
+
* context manager's binding record takes the strip either way. One that throws is logged. The framework sets it
|
|
612
|
+
* at the agent's first stream unless a host has set one, so a host's own observer stands in for the framework's,
|
|
613
|
+
* whose `[reasoning]` line for the agent then isn't told.
|
|
614
|
+
*/
|
|
615
|
+
onThinkingStrip?: (strip: ThinkingStrip, branch: string) => void;
|
|
616
|
+
/**
|
|
617
|
+
* The newest content of `namespace` among this agent's rows stored since
|
|
618
|
+
* its last compile built to send (unsentSince), and whether every part of
|
|
619
|
+
* it is among them: rows a start stored whose compile then didn't record
|
|
620
|
+
* (it threw, or the start failed before it), which no request has had
|
|
621
|
+
* yet, and which are newer than anything renderedInjection knows. Undefined when there are none, as at every
|
|
622
|
+
* start whose last compile was built and recorded. A fold between that
|
|
623
|
+
* start and the next (a host's own committing compile, or the compression
|
|
624
|
+
* an over-budget retry waits for) can summarize them all the same: the
|
|
625
|
+
* next request then has the summary's word for them, and the start after
|
|
626
|
+
* it stores them again, as after any fold. The window is read back 64
|
|
627
|
+
* rows at a time from the newest, stopping at that point.
|
|
628
|
+
*/
|
|
629
|
+
unsentInjection(namespace: string): {
|
|
630
|
+
contentHash: string;
|
|
631
|
+
whole: boolean;
|
|
632
|
+
} | undefined;
|
|
633
|
+
/** Record which of this agent's stored injections a compile built to send
|
|
634
|
+
* rendered. Another agent's stored rows never reach this agent's compile,
|
|
635
|
+
* since every compile of a shared store leaves them out by its view
|
|
636
|
+
* filter (isAnotherAgentsInjection): a compile of a shared store without
|
|
637
|
+
* that filter would mix them in here. */
|
|
638
|
+
private noteRenderedInjections;
|
|
639
|
+
/**
|
|
640
|
+
* The newest content of `namespace` among this agent's stored injections
|
|
641
|
+
* that the last compile built to send rendered, by its newest copy: its
|
|
642
|
+
* content hash, and whether every part of that content was there in some
|
|
643
|
+
* copy, every shard, however the strategy shaped it. Undefined when none
|
|
644
|
+
* was, when this agent hasn't built a request since it started, or when
|
|
645
|
+
* the window's branch has changed since.
|
|
646
|
+
*/
|
|
647
|
+
renderedInjection(namespace: string): {
|
|
648
|
+
contentHash: string;
|
|
649
|
+
whole: boolean;
|
|
650
|
+
} | undefined;
|
|
651
|
+
/**
|
|
652
|
+
* Whether compiled message `i` of `result` is a row of this agent's stored
|
|
653
|
+
* context injections (stored-injections.ts): rendered as an injection's
|
|
654
|
+
* participant, and each of its stored rows, by the compile's provenance,
|
|
655
|
+
* carrying this agent's mark. A speaker merely named like an injection's
|
|
656
|
+
* participant isn't one. Only such a message's rows are read, so a start
|
|
657
|
+
* reads the store for those alone.
|
|
658
|
+
*/
|
|
659
|
+
private isStoredInjectionRow;
|
|
660
|
+
/** A stored row's injection mark, or undefined for any other row, and for
|
|
661
|
+
* one the store can't read just now, which is logged: a start doesn't fail
|
|
662
|
+
* on it (the row then counts as no stored injection). */
|
|
663
|
+
private storedMarkOf;
|
|
443
664
|
/**
|
|
444
665
|
* Compile the context with injections (e.g. from MCPL servers), which the
|
|
445
666
|
* context manager merges into the compiled messages. Without
|
|
@@ -451,15 +672,23 @@ export declare class Agent {
|
|
|
451
672
|
compileWithInjections(budget?: TokenBudget, injections?: ContextInjection[], opts?: {
|
|
452
673
|
kvUnifiedImmutablePrefixHash?: string;
|
|
453
674
|
dryRun?: boolean;
|
|
454
|
-
}): Promise<CompileResult>;
|
|
675
|
+
} & BindingCompileOptions): Promise<CompileResult>;
|
|
455
676
|
/**
|
|
456
677
|
* Run inference and return result with tool calls and speech content.
|
|
457
|
-
* Updates agent state during execution.
|
|
678
|
+
* Updates agent state during execution. Its compile commits. With
|
|
679
|
+
* `thinkingBinding.binds` it also writes the context manager's
|
|
680
|
+
* thinking-binding record, so then call it only while none of this agent's
|
|
681
|
+
* requests is streaming: a stream open meanwhile then has its later notes
|
|
682
|
+
* write nothing, and its replies go without their thinking at the next
|
|
683
|
+
* compile. Its own reply is never noted, so with `binds` its thinking is
|
|
684
|
+
* left out at the compile after it's stored.
|
|
458
685
|
*/
|
|
459
686
|
runInference(availableTools: ToolDefinition[], budget?: TokenBudget, options?: InferenceOptions): Promise<InferenceResult>;
|
|
460
687
|
/**
|
|
461
688
|
* Run inference with context injections.
|
|
462
|
-
* Same as runInference but passes injections through to compile.
|
|
689
|
+
* Same as runInference but passes injections through to compile. Its
|
|
690
|
+
* compile commits, and with `thinkingBinding.binds` writes the
|
|
691
|
+
* thinking-binding record, as runInference's does (see there).
|
|
463
692
|
*/
|
|
464
693
|
runInferenceWithInjections(availableTools: ToolDefinition[], injections?: ContextInjection[], budget?: TokenBudget, options?: InferenceOptions): Promise<InferenceResult>;
|
|
465
694
|
/**
|
|
@@ -486,7 +715,10 @@ export declare class Agent {
|
|
|
486
715
|
* watermark); a preview passes `options.dryRun`, so its compile commits
|
|
487
716
|
* none of that (see `compileWithInjections` for what a dry run still
|
|
488
717
|
* leaves). Either way the context manager is handed the compression tool
|
|
489
|
-
* definitions. Safe to call regardless of the agent's current status
|
|
718
|
+
* definitions. Safe to call regardless of the agent's current status,
|
|
719
|
+
* except that with `thinkingBinding.binds` a compile that isn't a dry run
|
|
720
|
+
* writes the context manager's binding record, so while one of the
|
|
721
|
+
* agent's requests streams, a call to look passes `options.dryRun`.
|
|
490
722
|
* It doesn't wait for the tool-result guard's annotations, so a preview
|
|
491
723
|
* never waits on a workspace write (rollback, undo and redo report one), and
|
|
492
724
|
* may show a withheld stub before its place is added; the activation waits
|
|
@@ -495,13 +727,47 @@ export declare class Agent {
|
|
|
495
727
|
private assembleActivationRequest;
|
|
496
728
|
/**
|
|
497
729
|
* The request fields that come from this agent's own settings: its model
|
|
498
|
-
* config, prompt caching and cache TTL, prefill message,
|
|
499
|
-
* parameters and participant name. Every request the agent sends
|
|
500
|
-
* them from here, a framework turn's (assembleActivationRequest) and
|
|
501
|
-
* direct API's (runInferenceWithInjections), so a setting reaches both
|
|
502
|
-
* neither.
|
|
730
|
+
* config, thinking binding, prompt caching and cache TTL, prefill message,
|
|
731
|
+
* provider parameters and participant name. Every request the agent sends
|
|
732
|
+
* takes them from here, a framework turn's (assembleActivationRequest) and
|
|
733
|
+
* the direct API's (runInferenceWithInjections), so a setting reaches both
|
|
734
|
+
* or neither.
|
|
503
735
|
*/
|
|
504
736
|
private requestSettings;
|
|
737
|
+
/**
|
|
738
|
+
* The thinking config a request carries: the agent's own, with the binding
|
|
739
|
+
* control added when `thinkingBinding.dropBlock` asks for it. A model whose
|
|
740
|
+
* thinking is always on takes the control whatever `enabled` says, so an
|
|
741
|
+
* agent with no thinking config of its own still sends one, holding only
|
|
742
|
+
* the control and `enabled: false`. Membrane sends nothing from it to any
|
|
743
|
+
* other model, since thinking is off there.
|
|
744
|
+
*/
|
|
745
|
+
private requestThinking;
|
|
746
|
+
/** The stream's way to tell the context manager what its later rounds sent, with the head its compile was given:
|
|
747
|
+
* where the agent's model binds its thinking (context-manager's `noteRequestSent`). */
|
|
748
|
+
private requestNotes;
|
|
749
|
+
/**
|
|
750
|
+
* The binding a compile of this agent is told of (bindingCompileOptions), and a preview of its context too: the
|
|
751
|
+
* participant whose messages are its replies is its own name. Undefined where the model doesn't bind.
|
|
752
|
+
* @internal For the framework's preview and its budget rule; not a host API.
|
|
753
|
+
*/
|
|
754
|
+
thinkingBindingOption(): {
|
|
755
|
+
binds: true;
|
|
756
|
+
dropBlock: boolean;
|
|
757
|
+
participant: string;
|
|
758
|
+
} | undefined;
|
|
759
|
+
/**
|
|
760
|
+
* What a compile the agent sends tells the context manager when the model binds its thinking
|
|
761
|
+
* (`thinkingBinding.binds`): the binding as set, with the agent's own name as the participant whose messages
|
|
762
|
+
* are its replies (an agent stores its replies under its name), and a digest of each part of the request ahead of
|
|
763
|
+
* its messages, so a changed one can stand for a first difference where the context manager keeps a
|
|
764
|
+
* thinking-binding record. The system text is the one the request will carry, built from the system-position
|
|
765
|
+
* injections given to the compile as the kv-unified prefix hash builds it; the tools are the ones it will carry, in
|
|
766
|
+
* their order; `request` covers the thinking config, `maxTokens` and `providerParams`, where a host puts its own
|
|
767
|
+
* thinking config and `tool_choice`, and `prefillUserMessage`, which membrane sends as a leading user turn ahead
|
|
768
|
+
* of a conversation that would begin with the assistant. Nothing without `binds`: the compile is as it was.
|
|
769
|
+
*/
|
|
770
|
+
private bindingCompileOptions;
|
|
505
771
|
/** The request `assembleActivationRequest` builds (see there), for preview
|
|
506
772
|
* and debug tooling: what this agent's next activation would send. */
|
|
507
773
|
buildActivationRequest(availableTools: ToolDefinition[], injections?: ContextInjection[], budget?: TokenBudget, compressionTools?: ToolDefinition[], options?: ActivationRequestOptions): Promise<NormalizedRequest>;
|
|
@@ -530,7 +796,7 @@ export declare class Agent {
|
|
|
530
796
|
* Add an assistant response to context.
|
|
531
797
|
* Called by framework when stream completes.
|
|
532
798
|
*/
|
|
533
|
-
addAssistantResponse(content: ContentBlock[], metadata?: MessageMetadata):
|
|
799
|
+
addAssistantResponse(content: ContentBlock[], metadata?: MessageMetadata): MessageId | undefined;
|
|
534
800
|
/**
|
|
535
801
|
* Transition back to streaming state after tool results are provided.
|
|
536
802
|
*/
|
|
@@ -558,7 +824,9 @@ export declare class Agent {
|
|
|
558
824
|
* one is still ahead; otherwise the next start drops it. `reason` is
|
|
559
825
|
* provenance for the framework's inference:aborted trace and marker
|
|
560
826
|
* metadata (e.g. 'zombie_reclaim', 'subagent_cancel'); it never reaches
|
|
561
|
-
* the provider.
|
|
827
|
+
* the provider. When the stream's cancel() throws, the throw goes on to
|
|
828
|
+
* the caller, and the agent still holds the stream, its cancel record as
|
|
829
|
+
* it was before the call.
|
|
562
830
|
*/
|
|
563
831
|
cancelStream(reason?: string): void;
|
|
564
832
|
/** Collect (and clear) the cancelStream() made while this agent held no
|