@animalabs/agent-framework 0.32.0 → 0.34.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 +340 -22
- package/dist/src/admission/admit.d.ts +18 -0
- package/dist/src/admission/admit.d.ts.map +1 -1
- package/dist/src/admission/admit.js +16 -3
- package/dist/src/admission/admit.js.map +1 -1
- package/dist/src/agent.d.ts +208 -80
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +345 -113
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/mcp-server-core.d.ts.map +1 -1
- package/dist/src/api/mcp-server-core.js +50 -12
- package/dist/src/api/mcp-server-core.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +4 -20
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/append-all.d.ts +5 -0
- package/dist/src/append-all.d.ts.map +1 -0
- package/dist/src/append-all.js +8 -0
- package/dist/src/append-all.js.map +1 -0
- package/dist/src/code-execution/isolate/scripts.d.ts +12 -8
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
- package/dist/src/code-execution/isolate/scripts.js +24 -0
- package/dist/src/code-execution/isolate/scripts.js.map +1 -1
- package/dist/src/config-checks.d.ts +7 -0
- package/dist/src/config-checks.d.ts.map +1 -1
- package/dist/src/config-checks.js +14 -0
- package/dist/src/config-checks.js.map +1 -1
- package/dist/src/context-manager-errors.d.ts +25 -0
- package/dist/src/context-manager-errors.d.ts.map +1 -0
- package/dist/src/context-manager-errors.js +31 -0
- package/dist/src/context-manager-errors.js.map +1 -0
- package/dist/src/context-options.d.ts +70 -0
- package/dist/src/context-options.d.ts.map +1 -0
- package/dist/src/context-options.js +90 -0
- package/dist/src/context-options.js.map +1 -0
- package/dist/src/cut-off-round.js +4 -4
- package/dist/src/deferred-import.d.ts +93 -0
- package/dist/src/deferred-import.d.ts.map +1 -0
- package/dist/src/deferred-import.js +177 -0
- package/dist/src/deferred-import.js.map +1 -0
- package/dist/src/dendrite/audience.d.ts +223 -0
- package/dist/src/dendrite/audience.d.ts.map +1 -0
- package/dist/src/dendrite/audience.js +202 -0
- package/dist/src/dendrite/audience.js.map +1 -0
- package/dist/src/dendrite/index.d.ts +5 -3
- package/dist/src/dendrite/index.d.ts.map +1 -1
- package/dist/src/dendrite/index.js +2 -1
- package/dist/src/dendrite/index.js.map +1 -1
- package/dist/src/dendrite/presets.d.ts +10 -5
- package/dist/src/dendrite/presets.d.ts.map +1 -1
- package/dist/src/dendrite/presets.js +17 -5
- package/dist/src/dendrite/presets.js.map +1 -1
- package/dist/src/dendrite/registry.d.ts +62 -7
- package/dist/src/dendrite/registry.d.ts.map +1 -1
- package/dist/src/dendrite/registry.js +183 -12
- package/dist/src/dendrite/registry.js.map +1 -1
- package/dist/src/dendrite/types.d.ts +91 -8
- package/dist/src/dendrite/types.d.ts.map +1 -1
- package/dist/src/failure-text.d.ts +36 -0
- package/dist/src/failure-text.d.ts.map +1 -0
- package/dist/src/failure-text.js +89 -0
- package/dist/src/failure-text.js.map +1 -0
- package/dist/src/foreign-rounds.d.ts +69 -0
- package/dist/src/foreign-rounds.d.ts.map +1 -0
- package/dist/src/foreign-rounds.js +152 -0
- package/dist/src/foreign-rounds.js.map +1 -0
- package/dist/src/framework.d.ts +2064 -842
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +8586 -3739
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +125 -21
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +487 -72
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/gate/index.d.ts +1 -1
- package/dist/src/gate/index.d.ts.map +1 -1
- package/dist/src/gate/index.js.map +1 -1
- package/dist/src/gate/reply-judge.d.ts +4 -0
- package/dist/src/gate/reply-judge.d.ts.map +1 -1
- package/dist/src/gate/reply-judge.js +12 -3
- package/dist/src/gate/reply-judge.js.map +1 -1
- package/dist/src/gate/rule-scope.d.ts +30 -0
- package/dist/src/gate/rule-scope.d.ts.map +1 -0
- package/dist/src/gate/rule-scope.js +41 -0
- package/dist/src/gate/rule-scope.js.map +1 -0
- package/dist/src/gate/suppress-script-worker.d.ts +2 -0
- package/dist/src/gate/suppress-script-worker.d.ts.map +1 -0
- package/dist/src/gate/suppress-script-worker.js +103 -0
- package/dist/src/gate/suppress-script-worker.js.map +1 -0
- package/dist/src/gate/suppress-scripts.d.ts +105 -0
- package/dist/src/gate/suppress-scripts.d.ts.map +1 -0
- package/dist/src/gate/suppress-scripts.js +403 -0
- package/dist/src/gate/suppress-scripts.js.map +1 -0
- package/dist/src/gate/suppression-review.d.ts +143 -0
- package/dist/src/gate/suppression-review.d.ts.map +1 -0
- package/dist/src/gate/suppression-review.js +463 -0
- package/dist/src/gate/suppression-review.js.map +1 -0
- package/dist/src/gate/suppression-stats.d.ts +125 -0
- package/dist/src/gate/suppression-stats.d.ts.map +1 -0
- package/dist/src/gate/suppression-stats.js +214 -0
- package/dist/src/gate/suppression-stats.js.map +1 -0
- package/dist/src/gate/types.d.ts +142 -7
- package/dist/src/gate/types.d.ts.map +1 -1
- package/dist/src/gate/wake-onboarding.d.ts +119 -0
- package/dist/src/gate/wake-onboarding.d.ts.map +1 -0
- package/dist/src/gate/wake-onboarding.js +277 -0
- package/dist/src/gate/wake-onboarding.js.map +1 -0
- package/dist/src/heartbeat/heartbeat.js +1 -1
- package/dist/src/heartbeat/heartbeat.js.map +1 -1
- package/dist/src/held-writes.d.ts +31 -23
- package/dist/src/held-writes.d.ts.map +1 -1
- package/dist/src/held-writes.js +44 -59
- package/dist/src/held-writes.js.map +1 -1
- package/dist/src/index.d.ts +6 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/inference-bounds.d.ts +2 -1
- package/dist/src/inference-bounds.d.ts.map +1 -1
- package/dist/src/inference-bounds.js +9 -6
- package/dist/src/inference-bounds.js.map +1 -1
- package/dist/src/jsonrpc-envelope.d.ts +69 -0
- package/dist/src/jsonrpc-envelope.d.ts.map +1 -0
- package/dist/src/jsonrpc-envelope.js +66 -0
- package/dist/src/jsonrpc-envelope.js.map +1 -0
- package/dist/src/mcpl/channel-registry.d.ts +188 -28
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +426 -70
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.d.ts +2 -4
- package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
- package/dist/src/mcpl/feature-set-manager.d.ts +2 -4
- package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
- package/dist/src/mcpl/feature-set-manager.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +2 -1
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +2 -1
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/inference-router.d.ts +6 -6
- package/dist/src/mcpl/inference-router.d.ts.map +1 -1
- package/dist/src/mcpl/inference-router.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts +109 -15
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
- package/dist/src/mcpl/modern-connection.js +593 -86
- package/dist/src/mcpl/modern-connection.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts +3 -1
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +15 -9
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +132 -22
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +105 -15
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +9 -7
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +50 -28
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +165 -72
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
- package/dist/src/mcpl/tool-classes.js +3 -0
- package/dist/src/mcpl/tool-classes.js.map +1 -1
- package/dist/src/mcpl/tool-presence.d.ts.map +1 -1
- package/dist/src/mcpl/tool-presence.js +10 -6
- package/dist/src/mcpl/tool-presence.js.map +1 -1
- package/dist/src/mcpl/toolset-host.d.ts.map +1 -1
- package/dist/src/mcpl/toolset-host.js +7 -6
- package/dist/src/mcpl/toolset-host.js.map +1 -1
- package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
- package/dist/src/mcpl/toolsets-module.js +2 -1
- package/dist/src/mcpl/toolsets-module.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +33 -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 +24 -1
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +68 -18
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts +45 -8
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +238 -87
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/health/index.js +2 -2
- package/dist/src/modules/health/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts +59 -0
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +432 -67
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +6 -5
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +18 -25
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.d.ts +1 -1
- package/dist/src/modules/workspace/disk-agreement.js +1 -1
- package/dist/src/modules/workspace/index.d.ts +28 -7
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +80 -25
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +2 -1
- 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 +3 -2
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/notice-tags.d.ts +20 -9
- package/dist/src/notice-tags.d.ts.map +1 -1
- package/dist/src/notice-tags.js +20 -9
- package/dist/src/notice-tags.js.map +1 -1
- package/dist/src/operator-log.d.ts +36 -3
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js +2 -2
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/presentation.d.ts +747 -0
- package/dist/src/presentation.d.ts.map +1 -0
- package/dist/src/presentation.js +1437 -0
- package/dist/src/presentation.js.map +1 -0
- package/dist/src/prose-drafts.d.ts +15 -11
- package/dist/src/prose-drafts.d.ts.map +1 -1
- package/dist/src/prose-drafts.js +16 -12
- package/dist/src/prose-drafts.js.map +1 -1
- package/dist/src/read-marks.d.ts +192 -0
- package/dist/src/read-marks.d.ts.map +1 -0
- package/dist/src/read-marks.js +242 -0
- package/dist/src/read-marks.js.map +1 -0
- package/dist/src/reasoning-loss.d.ts +5 -0
- package/dist/src/reasoning-loss.d.ts.map +1 -0
- package/dist/src/reasoning-loss.js +8 -0
- package/dist/src/reasoning-loss.js.map +1 -0
- package/dist/src/recovery/offline-branch.d.ts +91 -6
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +277 -32
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js +24 -4
- package/dist/src/recovery/recover-cli.js.map +1 -1
- package/dist/src/send-tools.d.ts +5 -9
- package/dist/src/send-tools.d.ts.map +1 -1
- package/dist/src/send-tools.js +40 -7
- package/dist/src/send-tools.js.map +1 -1
- package/dist/src/sent-rows.js +1 -1
- package/dist/src/stored-injections.d.ts +2 -2
- package/dist/src/stored-injections.js +2 -2
- package/dist/src/stored-removal.d.ts +17 -4
- package/dist/src/stored-removal.d.ts.map +1 -1
- package/dist/src/stored-removal.js +29 -5
- package/dist/src/stored-removal.js.map +1 -1
- package/dist/src/supplied-text.d.ts +1 -1
- package/dist/src/supplied-text.js +3 -3
- package/dist/src/supplied-text.js.map +1 -1
- package/dist/src/thinking-drops.d.ts +2 -0
- package/dist/src/thinking-drops.d.ts.map +1 -1
- package/dist/src/thinking-drops.js.map +1 -1
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +38 -9
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts +12 -1
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +42 -8
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +1170 -81
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +3732 -369
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/tune-out/tools.d.ts +114 -17
- package/dist/src/tune-out/tools.d.ts.map +1 -1
- package/dist/src/tune-out/tools.js +89 -28
- package/dist/src/tune-out/tools.js.map +1 -1
- package/dist/src/tune-out/window-anchor.d.ts +143 -0
- package/dist/src/tune-out/window-anchor.d.ts.map +1 -0
- package/dist/src/tune-out/window-anchor.js +202 -0
- package/dist/src/tune-out/window-anchor.js.map +1 -0
- package/dist/src/types/agent.d.ts +121 -25
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +2 -0
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +72 -17
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/inference-log.d.ts +1 -0
- package/dist/src/types/inference-log.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +180 -69
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +573 -39
- package/dist/src/types/trace.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/admission/admit.ts +32 -3
- package/src/agent.ts +392 -132
- package/src/api/mcp-server-core.ts +54 -17
- package/src/api/server.ts +4 -23
- package/src/append-all.ts +6 -0
- package/src/code-execution/isolate/scripts.ts +28 -3
- package/src/config-checks.ts +14 -0
- package/src/context-manager-errors.ts +37 -0
- package/src/context-options.ts +106 -0
- package/src/cut-off-round.ts +4 -4
- package/src/deferred-import.ts +239 -0
- package/src/dendrite/audience.ts +315 -0
- package/src/dendrite/index.ts +14 -2
- package/src/dendrite/presets.ts +18 -6
- package/src/dendrite/registry.ts +213 -14
- package/src/dendrite/types.ts +92 -8
- package/src/failure-text.ts +88 -0
- package/src/foreign-rounds.ts +199 -0
- package/src/framework.ts +8796 -3813
- package/src/gate/event-gate.ts +518 -91
- package/src/gate/index.ts +3 -0
- package/src/gate/reply-judge.ts +12 -3
- package/src/gate/rule-scope.ts +45 -0
- package/src/gate/suppress-script-worker.ts +89 -0
- package/src/gate/suppress-scripts.ts +414 -0
- package/src/gate/suppression-review.ts +517 -0
- package/src/gate/suppression-stats.ts +314 -0
- package/src/gate/types.ts +148 -7
- package/src/gate/wake-onboarding.ts +309 -0
- package/src/heartbeat/heartbeat.ts +1 -1
- package/src/held-writes.ts +49 -60
- package/src/index.ts +10 -2
- package/src/inference-bounds.ts +11 -6
- package/src/jsonrpc-envelope.ts +81 -0
- package/src/mcpl/channel-registry.ts +513 -116
- package/src/mcpl/checkpoint-manager.ts +3 -2
- package/src/mcpl/feature-set-manager.ts +2 -1
- package/src/mcpl/inbound-source.ts +2 -1
- package/src/mcpl/inference-router.ts +7 -4
- package/src/mcpl/modern-connection.ts +629 -91
- package/src/mcpl/protocol-family.ts +15 -9
- package/src/mcpl/push-coalescer.ts +193 -34
- package/src/mcpl/push-handler.ts +10 -5
- package/src/mcpl/server-connection.ts +169 -75
- package/src/mcpl/tool-classes.ts +3 -0
- package/src/mcpl/tool-presence.ts +10 -5
- package/src/mcpl/toolset-host.ts +7 -6
- package/src/mcpl/toolsets-module.ts +2 -1
- package/src/mcpl/types.ts +33 -6
- package/src/module-registry.ts +73 -17
- package/src/modules/discord/index.ts +230 -82
- package/src/modules/health/index.ts +2 -2
- package/src/modules/history/index.ts +439 -70
- package/src/modules/history/semantic.ts +18 -24
- package/src/modules/workspace/disk-agreement.ts +1 -1
- package/src/modules/workspace/index.ts +89 -26
- package/src/modules/workspace/observe.ts +2 -1
- package/src/modules/workspace/reconcile.ts +3 -2
- package/src/notice-tags.ts +21 -9
- package/src/operator-log.ts +36 -3
- package/src/presentation.ts +1678 -0
- package/src/prose-drafts.ts +16 -12
- package/src/read-marks.ts +328 -0
- package/src/reasoning-loss.ts +7 -0
- package/src/recovery/offline-branch.ts +350 -35
- package/src/recovery/recover-cli.ts +23 -4
- package/src/send-tools.ts +40 -7
- package/src/sent-rows.ts +1 -1
- package/src/stored-injections.ts +2 -2
- package/src/stored-removal.ts +31 -7
- package/src/supplied-text.ts +3 -3
- package/src/thinking-drops.ts +2 -0
- package/src/tool-presentation.ts +34 -9
- package/src/tool-result-guard.ts +41 -7
- package/src/tune-out/coordinator.ts +4121 -472
- package/src/tune-out/tools.ts +162 -44
- package/src/tune-out/window-anchor.ts +277 -0
- package/src/types/agent.ts +122 -25
- package/src/types/events.ts +2 -0
- package/src/types/framework.ts +73 -17
- package/src/types/inference-log.ts +1 -0
- package/src/types/module.ts +181 -68
- package/src/types/trace.ts +607 -43
package/dist/src/agent.js
CHANGED
|
@@ -3,17 +3,21 @@ import { heartbeatToolAlias } from './heartbeat/heartbeat.js';
|
|
|
3
3
|
import { isAbortedResponse } from '@animalabs/membrane';
|
|
4
4
|
import { streamBounds } from './inference-bounds.js';
|
|
5
5
|
import { ToolResultGuard } from './tool-result-guard.js';
|
|
6
|
+
import { storeOwnRow } from './dendrite/audience.js';
|
|
6
7
|
import { withoutTokenEstimates } from './thinking-token-stamp.js';
|
|
7
8
|
import { placeThinkingDrops } from './thinking-drops.js';
|
|
8
9
|
import { carriedBlock } from './sent-rows.js';
|
|
10
|
+
import { foreignRowAsSent, transcribeForeignRounds } from './foreign-rounds.js';
|
|
9
11
|
import { injectionsAsStored } from './text-as-stored.js';
|
|
10
12
|
import { stableHash } from './stable-hash.js';
|
|
11
13
|
import { hasRenderedContent, storedInjectionMarkOf } from './stored-injections.js';
|
|
12
|
-
import {
|
|
14
|
+
import { covers, markAtOrAfter, readMarkOf, storeHeadOf } from './read-marks.js';
|
|
15
|
+
import { assertBooleanSetting, assertOneOfSetting, holdsSettings, kindOf } from './config-checks.js';
|
|
13
16
|
import { CONTINUE_ROW, continueTurn, indexRequestOnlyRows, renderRequestOnlyRows, silentHeartbeatSeparatorTurn, tickKey, toolLoopPrompt, } from './silent-heartbeat.js';
|
|
14
17
|
import { randomUUID } from 'node:crypto';
|
|
15
18
|
import { resolveClockConfig } from './clock-rows.js';
|
|
16
19
|
import { nonErrorResultText, truncateForHistory, DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS, } from './tool-result-history.js';
|
|
20
|
+
import { appendAll } from './append-all.js';
|
|
17
21
|
/** The render stats of the dry compile behind each request a dry run
|
|
18
22
|
* assembled (`assembleActivationRequest` with `dryRun`), by that request.
|
|
19
23
|
* A request that is sent has none here. Read through the framework's
|
|
@@ -53,11 +57,13 @@ export function assertThinkingBinding(setting, value) {
|
|
|
53
57
|
}
|
|
54
58
|
/**
|
|
55
59
|
* Refuse an agent config whose `promptCaching`, `toolResultGuard`,
|
|
56
|
-
* `toolWrapperProseGuard`, `thinking.enabled`, `thinkingBinding.dropBlock`,
|
|
60
|
+
* `toolWrapperProseGuard`, `turnInputsPin`, `thinking.enabled`, `thinkingBinding.dropBlock`,
|
|
57
61
|
* `thinkingBinding.binds` or `refusalHandling.autoRewind` holds anything but true or false
|
|
58
62
|
* (assertBooleanSetting, where null counts as left out), or whose `thinking`, `thinkingBinding` or
|
|
59
63
|
* `refusalHandling` is anything but an object, null or false (holdsSettings),
|
|
60
|
-
* or whose `autoContinue` resolveAutoContinue refuses
|
|
64
|
+
* or whose `autoContinue` resolveAutoContinue refuses, or whose `observes`
|
|
65
|
+
* is anything but a list of names, or whose `foreignRounds` is neither of
|
|
66
|
+
* its modes (assertOneOfSetting). The constructor runs it
|
|
61
67
|
* first, so the rule holds wherever an Agent is built. `create()` also runs it
|
|
62
68
|
* for each of its agents before anything opens, and `createEphemeralAgent`
|
|
63
69
|
* before it reserves the name, so a refusal there leaves nothing behind.
|
|
@@ -79,6 +85,15 @@ export function assertAgentSwitches(config) {
|
|
|
79
85
|
'and false or leaving it out doesn\'t');
|
|
80
86
|
assertBooleanSetting(`${agent} toolWrapperProseGuard`, config.toolWrapperProseGuard, 'true keeps a response whose whole prose is a tool-call-shaped wrapper from running or entering the agent\'s history, ' +
|
|
81
87
|
'and false or leaving it out doesn\'t');
|
|
88
|
+
assertBooleanSetting(`${agent} turnInputsPin`, config.turnInputsPin, 'true or leaving it out pins the rows that open a turn raw until it ends, and false places no pin');
|
|
89
|
+
const observes = config.observes;
|
|
90
|
+
if (observes !== undefined && observes !== null
|
|
91
|
+
&& (!Array.isArray(observes) || !observes.every((name) => typeof name === 'string'))) {
|
|
92
|
+
throw new Error(`${agent} observes must be a list of agent names, such as ["nova"], not ${Array.isArray(observes) ? 'a list holding something else' : kindOf(observes)}: ` +
|
|
93
|
+
'each names another configured agent whose own rows this agent\'s window takes');
|
|
94
|
+
}
|
|
95
|
+
assertOneOfSetting(`${agent} foreignRounds`, config.foreignRounds, ['transcript', 'raw'], '\'transcript\' or leaving it out sends the rounds of an agent it observes as a line per call and result, ' +
|
|
96
|
+
'without their thinking, and \'raw\' sends them as stored');
|
|
82
97
|
resolveAutoContinue(config);
|
|
83
98
|
}
|
|
84
99
|
/** `AutoContinueConfig.maxConsecutive` when left out. */
|
|
@@ -116,6 +131,7 @@ export function resolveAutoContinue(config) {
|
|
|
116
131
|
}
|
|
117
132
|
return { maxConsecutive: max };
|
|
118
133
|
}
|
|
134
|
+
/** A branch's key in Agent.unsentSince: its id and when it was created. */
|
|
119
135
|
export function branchKey(branch) {
|
|
120
136
|
return `${branch.id}\u0000${branch.created}`;
|
|
121
137
|
}
|
|
@@ -153,6 +169,8 @@ export class Agent {
|
|
|
153
169
|
toolResultGuard;
|
|
154
170
|
/** Prose delivery mode (see AgentConfig.proseRouting). Default 'locus'. */
|
|
155
171
|
proseRouting;
|
|
172
|
+
/** Locked mode's destination until the agent chooses one (see AgentConfig.proseLock). */
|
|
173
|
+
proseLock;
|
|
156
174
|
/** Exact whole-response known-tool wrapper containment (default off). */
|
|
157
175
|
toolWrapperProseGuard;
|
|
158
176
|
/** Continuation after a turn the model ends itself (see
|
|
@@ -236,6 +254,7 @@ export class Agent {
|
|
|
236
254
|
* the next change.
|
|
237
255
|
*/
|
|
238
256
|
liveBudgetEpoch = 0;
|
|
257
|
+
contextSettingsChangeCount = 0;
|
|
239
258
|
/**
|
|
240
259
|
* Counts changes of the descent (each arm of one, the same target included,
|
|
241
260
|
* a reset, a cancel, a settle). A settle proves its target only to a
|
|
@@ -291,11 +310,13 @@ export class Agent {
|
|
|
291
310
|
this.refusalHandling = config.refusalHandling;
|
|
292
311
|
this.toolResultGuard = new ToolResultGuard(config.name, contextManager, config.toolResultGuard === true);
|
|
293
312
|
this.proseRouting = config.proseRouting ?? 'locus';
|
|
313
|
+
this.proseLock = typeof config.proseLock === 'string' && config.proseLock.trim() ? config.proseLock.trim() : undefined;
|
|
294
314
|
this.toolWrapperProseGuard = config.toolWrapperProseGuard === true;
|
|
295
315
|
this.autoContinue = resolveAutoContinue(config);
|
|
296
316
|
this.clock = resolveClockConfig(config.name, config.clock);
|
|
297
317
|
this.cacheTtl = config.cacheTtl ?? '1h';
|
|
298
318
|
this.promptCaching = config.promptCaching !== false;
|
|
319
|
+
this.pinsTurnInputs = config.turnInputsPin !== false;
|
|
299
320
|
this.prefillUserMessage = config.prefillUserMessage;
|
|
300
321
|
this.providerParams = config.providerParams;
|
|
301
322
|
this.sameRoundThinkTextPolicy = config.sameRoundThinkTextPolicy;
|
|
@@ -368,6 +389,44 @@ export class Agent {
|
|
|
368
389
|
isOwnParticipant(participant) {
|
|
369
390
|
return this.ownParticipants.has(participant);
|
|
370
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* How another agent's rounds go out in this agent's requests (#291, answer
|
|
394
|
+
* 13): `'raw'`, as stored, or `'transcript'` (foreign-rounds.ts), a line
|
|
395
|
+
* per call and per result and no thinking, the same in every compile and
|
|
396
|
+
* in what a tool boundary injects. The framework sets it, once the
|
|
397
|
+
* agent's window follows the presentation index, for the persistent
|
|
398
|
+
* subconscious, for a resident that observes another
|
|
399
|
+
* (AgentConfig.observes), as their configurations' `foreignRounds` say
|
|
400
|
+
* (`'transcript'` by default), and for an agent derived or forked from
|
|
401
|
+
* one of them, in that agent's mode (its inheritance holds them); every
|
|
402
|
+
* other agent reads no other agent's
|
|
403
|
+
* rounds, but for a co-resident's rows stored before audience stamps,
|
|
404
|
+
* which a window written down from the record keeps and which go out as
|
|
405
|
+
* stored ('raw'), as earlier releases sent them.
|
|
406
|
+
*/
|
|
407
|
+
foreignRounds = 'raw';
|
|
408
|
+
/** Set how another agent's rounds go out in this agent's requests (see foreignRounds). */
|
|
409
|
+
setForeignRounds(mode) {
|
|
410
|
+
this.foreignRounds = mode;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* A stored row as this agent's requests carry it, for a row a tool
|
|
414
|
+
* boundary injects: another participant's row as a transcript where this
|
|
415
|
+
* agent is sent other agents' rounds so (setForeignRounds), its own and
|
|
416
|
+
* every row otherwise as stored. An injected row holds no tool block (the
|
|
417
|
+
* boundary cuts at one), so what changes is its thinking.
|
|
418
|
+
*/
|
|
419
|
+
injectedAsSent(participant, content) {
|
|
420
|
+
if (this.foreignRounds !== 'transcript' || this.isOwnParticipant(participant))
|
|
421
|
+
return content;
|
|
422
|
+
return foreignRowAsSent(content);
|
|
423
|
+
}
|
|
424
|
+
/** A compile's messages with other agents' rounds as this agent is sent them (setForeignRounds). */
|
|
425
|
+
foreignRoundsAsSent(messages) {
|
|
426
|
+
if (this.foreignRounds !== 'transcript')
|
|
427
|
+
return messages;
|
|
428
|
+
return transcribeForeignRounds(messages, (participant) => this.isOwnParticipant(participant));
|
|
429
|
+
}
|
|
371
430
|
/**
|
|
372
431
|
* Role assignment for a request: every participant that is this agent's
|
|
373
432
|
* own voice — its name, and for a derived agent the agent it inherited
|
|
@@ -436,7 +495,18 @@ export class Agent {
|
|
|
436
495
|
if (typeof manager.updateHotContextSettings !== 'function') {
|
|
437
496
|
throw new Error('The active context strategy does not support live context settings');
|
|
438
497
|
}
|
|
439
|
-
|
|
498
|
+
const settings = (s) => JSON.stringify([s?.tailTokens, s?.transitionPaceTokens, s?.preparedWindowTokens]);
|
|
499
|
+
const before = settings(this.getHotContextSettings());
|
|
500
|
+
const status = manager.updateHotContextSettings(update);
|
|
501
|
+
if (settings(status) !== before)
|
|
502
|
+
this.contextSettingsChangeCount++;
|
|
503
|
+
return status;
|
|
504
|
+
}
|
|
505
|
+
/** How many times the live budget, its descent target or the hot context
|
|
506
|
+
* settings have changed.
|
|
507
|
+
* @internal For the framework's budget holds; not a host API. */
|
|
508
|
+
contextSettingsChanges() {
|
|
509
|
+
return this.contextSettingsChangeCount;
|
|
440
510
|
}
|
|
441
511
|
getRuntimeSettings() {
|
|
442
512
|
const hot = this.getHotContextSettings();
|
|
@@ -499,6 +569,8 @@ export class Agent {
|
|
|
499
569
|
this.liveBudgetEpoch++;
|
|
500
570
|
if (armed || target !== this.contextBudgetTargetTokens)
|
|
501
571
|
this.descentEpoch++;
|
|
572
|
+
if (budget !== this.contextBudgetTokens || target !== this.contextBudgetTargetTokens)
|
|
573
|
+
this.contextSettingsChangeCount++;
|
|
502
574
|
this.contextBudgetTokens = budget;
|
|
503
575
|
this.contextBudgetTargetTokens = target;
|
|
504
576
|
}
|
|
@@ -539,7 +611,7 @@ export class Agent {
|
|
|
539
611
|
}
|
|
540
612
|
finally {
|
|
541
613
|
this.compilesRunning.delete(started);
|
|
542
|
-
const earliest =
|
|
614
|
+
const earliest = [...this.compilesRunning].reduce((min, start) => Math.min(min, start), Infinity);
|
|
543
615
|
for (const [budget, start] of this.latestEndedStart) {
|
|
544
616
|
if (start < earliest)
|
|
545
617
|
this.latestEndedStart.delete(budget);
|
|
@@ -929,16 +1001,28 @@ export class Agent {
|
|
|
929
1001
|
return true;
|
|
930
1002
|
}
|
|
931
1003
|
/**
|
|
932
|
-
* RFC-006 consumed watermark, per branch: the
|
|
933
|
-
* the latest of
|
|
934
|
-
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
*
|
|
1004
|
+
* RFC-006 consumed watermark, per branch: how far the agent had read as of
|
|
1005
|
+
* the latest of its creation, a committing compile that returns, and a
|
|
1006
|
+
* tool boundary that injected messages into a live stream declaring it
|
|
1007
|
+
* carries them (`supportsInjectedMessages` true: membrane's native path,
|
|
1008
|
+
* from membrane 0.6.0). A compile counts from when it takes its mark,
|
|
1009
|
+
* before it awaits, so one that began before a boundary's mark doesn't
|
|
1010
|
+
* roll the mark back (applyCompileWatermark), and a dry run, such as
|
|
1011
|
+
* previewActivation's, doesn't move it.
|
|
1012
|
+
*
|
|
1013
|
+
* It is a ReadMark (read-marks.ts), read only through `covers`. Once the
|
|
1014
|
+
* agent's context presents rows (#291's presentation index, in presented
|
|
1015
|
+
* mode), it covers exactly the rows in the agent's window as of the mark:
|
|
1016
|
+
* a row stored then and not yet presented to the agent isn't covered.
|
|
1017
|
+
* While the context is in legacy mode, its window is the record, and the
|
|
1018
|
+
* mark covers every row stored on the branch by then, as it always did:
|
|
1019
|
+
* a prefix of the record, so it also covers stored messages the agent
|
|
1020
|
+
* wasn't given, such as another slot's. Once the window is written down
|
|
1021
|
+
* (an agent registered on a branch its window was never written down on
|
|
1022
|
+
* holds such a mark until its first compile), a mark taken in legacy mode
|
|
1023
|
+
* covers the rows its window held by the mark where they still stand, as
|
|
1024
|
+
* a mark taken in presented mode then would: a row stored after it, taken
|
|
1025
|
+
* out of the window since, or presented to the agent again, isn't.
|
|
942
1026
|
*
|
|
943
1027
|
* A message above it may still be replaced or withdrawn in place by its
|
|
944
1028
|
* sender, though it may already have been in one of the agent's requests.
|
|
@@ -950,16 +1034,19 @@ export class Agent {
|
|
|
950
1034
|
* compile that finishes can tell whether one was made while it ran. */
|
|
951
1035
|
watermarkMarks = 0;
|
|
952
1036
|
/**
|
|
953
|
-
*
|
|
954
|
-
* front of
|
|
955
|
-
*
|
|
956
|
-
*
|
|
957
|
-
* have been shown, though: for one, a live stream carries each
|
|
958
|
-
* content and results, stored at a boundary that injected
|
|
959
|
-
* next request. A compile that throws assembled nothing,
|
|
960
|
-
* back where it can (unshowFailedCompile). A
|
|
961
|
-
*
|
|
962
|
-
*
|
|
1037
|
+
* How far a compile or a tool boundary may have put the agent's context in
|
|
1038
|
+
* front of it, per branch. It moves where the consumed watermark does,
|
|
1039
|
+
* and sooner: when a committing compile takes its mark, before it awaits,
|
|
1040
|
+
* and at every tool boundary that injects into its stream. A message above
|
|
1041
|
+
* it may still have been shown, though: for one, a live stream carries each
|
|
1042
|
+
* round's own content and results, stored at a boundary that injected
|
|
1043
|
+
* nothing, into its next request. A compile that throws assembled nothing,
|
|
1044
|
+
* and gives its move back where it can (unshowFailedCompile). A mark taken
|
|
1045
|
+
* in legacy mode, read while the window is the record, counts a prefix of
|
|
1046
|
+
* the record, so a message stored below it without having been shown
|
|
1047
|
+
* counts as shown, which errs toward a marker; one taken in presented
|
|
1048
|
+
* mode, and one taken in legacy mode read once the window is written down,
|
|
1049
|
+
* cover the window as it stood.
|
|
963
1050
|
*/
|
|
964
1051
|
shownWatermark = null;
|
|
965
1052
|
getConsumedWatermark() {
|
|
@@ -987,14 +1074,18 @@ export class Agent {
|
|
|
987
1074
|
if (watermark)
|
|
988
1075
|
this.answeredWatermark = watermark;
|
|
989
1076
|
}
|
|
1077
|
+
/** Whether a turn this agent opens pins its inputs (AgentConfig.turnInputsPin, on by default). */
|
|
1078
|
+
pinsTurnInputs;
|
|
990
1079
|
/**
|
|
991
|
-
* Keep the
|
|
992
|
-
* opening, with a raw pin under one name per agent
|
|
993
|
-
*
|
|
994
|
-
*
|
|
995
|
-
*
|
|
996
|
-
*
|
|
997
|
-
*
|
|
1080
|
+
* Keep the rows of the agent's window from `first` through `last` raw for
|
|
1081
|
+
* the turn now opening, with a raw pin under one name per agent: a
|
|
1082
|
+
* strategy reads a pin by its rows' positions in its message view, which
|
|
1083
|
+
* is the window, in its order (#291; in legacy mode the record). Any pin
|
|
1084
|
+
* of that name already held is removed first, one a crash left included.
|
|
1085
|
+
* Under a strategy without pins nothing is pinned. A committing compile
|
|
1086
|
+
* that refuses as over budget while a pin of that name is held removes it
|
|
1087
|
+
* and compiles once more, and `unpinTurnInputs` removes it. Returns the
|
|
1088
|
+
* pin's id, or undefined when nothing was pinned.
|
|
998
1089
|
*
|
|
999
1090
|
* @internal For the framework's turn starts; not a host API.
|
|
1000
1091
|
*/
|
|
@@ -1055,46 +1146,89 @@ export class Agent {
|
|
|
1055
1146
|
* draft resend, or a send tool whose channel the framework records), on
|
|
1056
1147
|
* the branch it was taken on. A wake that carries a channel, unless it's
|
|
1057
1148
|
* marked ambient (InferenceRequest.ambient), keeps its turn unless the
|
|
1058
|
-
* agent spoke there after reading the
|
|
1149
|
+
* agent spoke there after reading the row the wake is for. It
|
|
1059
1150
|
* lives as long as this Agent: an agent made again starts it empty, and
|
|
1060
1151
|
* such a wake then stays.
|
|
1061
1152
|
*/
|
|
1062
1153
|
publishedThrough = new Map();
|
|
1063
1154
|
/** Note a publish into `destination` (its key), made having read through
|
|
1064
1155
|
* `readThrough`: the consumed watermark when its words were written, or
|
|
1065
|
-
* its call made.
|
|
1156
|
+
* its call made. A later mark on the same branch (markAtOrAfter: of two
|
|
1157
|
+
* at one head, the one whose window reached further) replaces an earlier
|
|
1158
|
+
* one; one on another branch replaces whatever was noted. */
|
|
1066
1159
|
notePublished(destination, readThrough) {
|
|
1067
1160
|
if (!readThrough)
|
|
1068
1161
|
return;
|
|
1069
1162
|
const noted = this.publishedThrough.get(destination);
|
|
1070
|
-
if (noted && noted
|
|
1163
|
+
if (noted && markAtOrAfter(noted, readThrough) === true)
|
|
1071
1164
|
return;
|
|
1072
1165
|
this.publishedThrough.set(destination, readThrough);
|
|
1073
1166
|
}
|
|
1074
1167
|
/** Whether the agent published into `destination` (its key) having read
|
|
1075
|
-
*
|
|
1076
|
-
|
|
1168
|
+
* `row`, as `cm` (the agent's context, where the row's place in its
|
|
1169
|
+
* window is read) says: the mark noted for the destination covers it. A
|
|
1170
|
+
* mark that can't say (one on another branch) says no. */
|
|
1171
|
+
publishedAfterReading(destination, row, cm) {
|
|
1077
1172
|
const noted = this.publishedThrough.get(destination);
|
|
1078
|
-
return !!noted && noted
|
|
1173
|
+
return !!noted && covers(noted, cm, row) === 'covered';
|
|
1079
1174
|
}
|
|
1080
|
-
/**
|
|
1081
|
-
*
|
|
1082
|
-
*
|
|
1175
|
+
/**
|
|
1176
|
+
* Every read mark this agent holds: its consumed, shown and answered
|
|
1177
|
+
* watermarks and the mark noted for each destination it published into,
|
|
1178
|
+
* each mark once (two of them are often the one mark). A redo on the
|
|
1179
|
+
* window (AgentFramework.redo) reads which of them covered the rows it
|
|
1180
|
+
* puts back, and gives those marks again (replaceReadMarks).
|
|
1181
|
+
*/
|
|
1182
|
+
heldReadMarks() {
|
|
1183
|
+
const held = new Set();
|
|
1184
|
+
for (const mark of [this.consumedWatermark, this.shownWatermark, this.answeredWatermark, ...this.publishedThrough.values()]) {
|
|
1185
|
+
if (mark)
|
|
1186
|
+
held.add(mark);
|
|
1187
|
+
}
|
|
1188
|
+
return [...held];
|
|
1189
|
+
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Put each mark `replacements` maps in its place wherever this agent holds
|
|
1192
|
+
* it (heldReadMarks), so a mark held as two of them stays one: a redo on
|
|
1193
|
+
* the window (#291) puts rows back at new ordinals, past every mark that
|
|
1194
|
+
* covered them before their undo, and gives each such mark again where it
|
|
1195
|
+
* covers them now. It counts as a mark (watermarkMarks), so a compile that
|
|
1196
|
+
* began before it doesn't put its own older mark back over it.
|
|
1197
|
+
*/
|
|
1198
|
+
replaceReadMarks(replacements) {
|
|
1199
|
+
const swap = (mark) => (mark && replacements.get(mark)) ?? mark;
|
|
1200
|
+
const consumed = swap(this.consumedWatermark);
|
|
1201
|
+
if (consumed !== this.consumedWatermark) {
|
|
1202
|
+
this.consumedWatermark = consumed;
|
|
1203
|
+
this.watermarkMarks++;
|
|
1204
|
+
}
|
|
1205
|
+
this.shownWatermark = swap(this.shownWatermark);
|
|
1206
|
+
this.answeredWatermark = swap(this.answeredWatermark);
|
|
1207
|
+
for (const [destination, mark] of this.publishedThrough) {
|
|
1208
|
+
const next = replacements.get(mark);
|
|
1209
|
+
if (next)
|
|
1210
|
+
this.publishedThrough.set(destination, next);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
/** Mark everything in the agent's window (in legacy mode, everything
|
|
1214
|
+
* stored) as consumed: the agent's creation, at boot or later, and a tool
|
|
1215
|
+
* boundary that injected messages into a live stream declaring it carries
|
|
1216
|
+
* them; see consumedWatermark. */
|
|
1083
1217
|
markContextConsumed() {
|
|
1084
1218
|
// Tolerates partial context-manager doubles (tests build Agents over
|
|
1085
1219
|
// stubs). Without a watermark, a reader that looks for one takes its own
|
|
1086
1220
|
// side: the coalescer counts the message as read, and the framework's
|
|
1087
|
-
//
|
|
1088
|
-
//
|
|
1089
|
-
// (
|
|
1221
|
+
// releasedWindow counts it as unread. A wake for a row it reads
|
|
1222
|
+
// (InferenceRequest.readsRow) reads the answered watermark instead
|
|
1223
|
+
// (rowDone).
|
|
1090
1224
|
this.consumedWatermark = this.pendingWatermark();
|
|
1091
1225
|
this.watermarkMarks++;
|
|
1092
1226
|
this.shownWatermark = this.consumedWatermark;
|
|
1093
1227
|
}
|
|
1094
|
-
/** Mark everything
|
|
1095
|
-
* that injected messages into
|
|
1096
|
-
* a watermark the coalescer counts a message as
|
|
1097
|
-
* read without a consumed watermark. */
|
|
1228
|
+
/** Mark everything in the agent's window (in legacy mode, everything
|
|
1229
|
+
* stored) as possibly shown (a tool boundary that injected messages into
|
|
1230
|
+
* its stream). Without a watermark the coalescer counts a message as
|
|
1231
|
+
* shown, as it counts one read without a consumed watermark. */
|
|
1098
1232
|
markContextShown() {
|
|
1099
1233
|
this.shownWatermark = this.pendingWatermark();
|
|
1100
1234
|
}
|
|
@@ -1107,7 +1241,9 @@ export class Agent {
|
|
|
1107
1241
|
* the second then throws, it restores the first's failed claim. Messages
|
|
1108
1242
|
* up to that claim then count as shown, although no request held those
|
|
1109
1243
|
* above the watermark the first compile found, which errs toward a marker
|
|
1110
|
-
* until the next compile or boundary moves the watermark.
|
|
1244
|
+
* until the next compile or boundary moves the watermark. Each mark is a
|
|
1245
|
+
* fresh object (readMarkOf), so the compare by identity is this compile's
|
|
1246
|
+
* own claim. */
|
|
1111
1247
|
unshowFailedCompile(watermark, before) {
|
|
1112
1248
|
if (watermark && this.shownWatermark === watermark)
|
|
1113
1249
|
this.shownWatermark = before;
|
|
@@ -1119,52 +1255,42 @@ export class Agent {
|
|
|
1119
1255
|
* mark's branch, so a boundary's mark is never rolled back by a compile
|
|
1120
1256
|
* that started before it (a committing compile, such as compileContext's,
|
|
1121
1257
|
* run during a live turn; a dry run, such as previewActivation's, never
|
|
1122
|
-
* reaches here).
|
|
1258
|
+
* reaches here). Marks are ordered by markAtOrAfter: by the window's
|
|
1259
|
+
* index length where both keep one, else by the store's head, each of
|
|
1260
|
+
* which only grows on a branch.
|
|
1123
1261
|
*/
|
|
1124
1262
|
applyCompileWatermark(watermark, marksBefore) {
|
|
1125
1263
|
const current = this.consumedWatermark;
|
|
1126
|
-
if (this.watermarkMarks !== marksBefore && current
|
|
1127
|
-
&& (current.branch !== watermark.branch || current.sequence >= watermark.sequence))
|
|
1264
|
+
if (this.watermarkMarks !== marksBefore && current && markAtOrAfter(current, watermark) !== false)
|
|
1128
1265
|
return;
|
|
1129
1266
|
this.consumedWatermark = watermark;
|
|
1130
1267
|
this.watermarkMarks++;
|
|
1131
1268
|
}
|
|
1132
1269
|
/**
|
|
1133
|
-
* The branch now (`branchKey`) and
|
|
1134
|
-
*
|
|
1270
|
+
* The branch now (`branchKey`) and the store's head on it (storeHeadOf, the
|
|
1271
|
+
* head a mark pendingWatermark takes keeps): a message stored on that
|
|
1272
|
+
* branch later has a larger sequence. Sequences are numbered per branch, so
|
|
1273
|
+
* one compares with another only on the same branch. A record sequence, not
|
|
1274
|
+
* a place in the agent's window (#291).
|
|
1135
1275
|
*/
|
|
1136
1276
|
branchHead() {
|
|
1137
|
-
const
|
|
1277
|
+
const sequence = storeHeadOf(this.contextManager);
|
|
1138
1278
|
const cm = this.contextManager;
|
|
1139
|
-
if (
|
|
1279
|
+
if (sequence === null || typeof cm.currentBranchRef !== 'function')
|
|
1140
1280
|
return undefined;
|
|
1141
1281
|
try {
|
|
1142
|
-
return { branch: branchKey(cm.currentBranchRef()), sequence
|
|
1282
|
+
return { branch: branchKey(cm.currentBranchRef()), sequence };
|
|
1143
1283
|
}
|
|
1144
1284
|
catch {
|
|
1145
1285
|
return undefined;
|
|
1146
1286
|
}
|
|
1147
1287
|
}
|
|
1148
|
-
/** The watermark a successful compile will establish (taken before, applied
|
|
1288
|
+
/** The watermark a successful compile will establish (taken before, applied
|
|
1289
|
+
* after): where the agent's context stands now (readMarkOf), its window's
|
|
1290
|
+
* index length with the store's head once it presents rows. Null for a
|
|
1291
|
+
* context double that can't say. */
|
|
1149
1292
|
pendingWatermark() {
|
|
1150
|
-
|
|
1151
|
-
try {
|
|
1152
|
-
if (typeof cm.currentBranch !== 'function' || typeof cm.getAllMessages !== 'function')
|
|
1153
|
-
return null;
|
|
1154
|
-
// The chronicle head, not this slot's last message: a compile reads
|
|
1155
|
-
// everything stored on the branch so far, including messages merged in
|
|
1156
|
-
// from another slot (the subconscious reads the residents' shared slot).
|
|
1157
|
-
const store = typeof cm.getStore === 'function' ? cm.getStore() : undefined;
|
|
1158
|
-
let sequence = typeof store?.currentSequence === 'function' ? store.currentSequence() : undefined;
|
|
1159
|
-
if (sequence === undefined) {
|
|
1160
|
-
const count = typeof cm.getMessageCount === 'function' ? cm.getMessageCount() : cm.getAllMessages().length;
|
|
1161
|
-
sequence = count > 0 ? cm.getAllMessages().at(-1)?.sequence ?? 0 : 0;
|
|
1162
|
-
}
|
|
1163
|
-
return { branch: cm.currentBranch().name, sequence };
|
|
1164
|
-
}
|
|
1165
|
-
catch {
|
|
1166
|
-
return null;
|
|
1167
|
-
}
|
|
1293
|
+
return readMarkOf(this.contextManager);
|
|
1168
1294
|
}
|
|
1169
1295
|
/** A committing compile, as for a request that is sent: the context
|
|
1170
1296
|
* manager commits what it commits for one, the consumed watermark moves,
|
|
@@ -1233,9 +1359,8 @@ export class Agent {
|
|
|
1233
1359
|
/**
|
|
1234
1360
|
* A host's hook, called with each committing compile's `thinkingStrip` (never a dry run's) and the key of the
|
|
1235
1361
|
* branch it read (`branchKey`), as the compile returns, whether or not its request is then sent, since the
|
|
1236
|
-
* context manager's binding record takes the strip either way. One that throws is logged.
|
|
1237
|
-
*
|
|
1238
|
-
* whose `[reasoning]` line for the agent then isn't told.
|
|
1362
|
+
* context manager's binding record takes the strip either way. One that throws is logged. It is observational only;
|
|
1363
|
+
* the framework does not write agent-facing reasoning-loss notices.
|
|
1239
1364
|
*/
|
|
1240
1365
|
onThinkingStrip;
|
|
1241
1366
|
/**
|
|
@@ -1248,18 +1373,23 @@ export class Agent {
|
|
|
1248
1373
|
* start and the next (a host's own committing compile, or the compression
|
|
1249
1374
|
* an over-budget retry waits for) can summarize them all the same: the
|
|
1250
1375
|
* next request then has the summary's word for them, and the start after
|
|
1251
|
-
* it stores them again, as after any fold. The
|
|
1252
|
-
* rows at a time from the newest, stopping at that point.
|
|
1376
|
+
* it stores them again, as after any fold. The slot's record is read
|
|
1377
|
+
* back 64 rows at a time from the newest, stopping at that point.
|
|
1378
|
+
*
|
|
1379
|
+
* It reads the record, by sequence, not the agent's window, and that
|
|
1380
|
+
* holds once the context presents rows (#291): the rows it counts are
|
|
1381
|
+
* this agent's own stored injections, its own rows, which enter its
|
|
1382
|
+
* window as they are written, so one stored after the point is in no
|
|
1383
|
+
* request yet whatever else has been stored or presented since. Another
|
|
1384
|
+
* agent's rows, stored into a shared slot at once rather than queued, are
|
|
1385
|
+
* passed over, whatever they are.
|
|
1253
1386
|
*/
|
|
1254
1387
|
unsentInjection(namespace) {
|
|
1255
1388
|
let newest;
|
|
1256
1389
|
try {
|
|
1257
|
-
const
|
|
1258
|
-
const since = this.unsentSince.get(branch);
|
|
1390
|
+
const since = this.unsentSince.get(branchKey(this.contextManager.currentBranchRef()));
|
|
1259
1391
|
if (since === undefined) {
|
|
1260
|
-
|
|
1261
|
-
const top = count > 0 ? this.contextManager.getMessageWindow(count - 1, 1, { resolveBlobs: false }).messages[0]?.sequence ?? 0 : 0;
|
|
1262
|
-
this.unsentSince.set(branch, top);
|
|
1392
|
+
this.markUnsentPoint();
|
|
1263
1393
|
return undefined;
|
|
1264
1394
|
}
|
|
1265
1395
|
scan: for (let end = this.contextManager.getMessageCount(); end > 0;) {
|
|
@@ -1272,6 +1402,10 @@ export class Agent {
|
|
|
1272
1402
|
const mark = storedInjectionMarkOf(row.metadata);
|
|
1273
1403
|
if (mark?.agent !== this.name || mark.namespace !== namespace)
|
|
1274
1404
|
continue;
|
|
1405
|
+
// A copy an undo took out of the window (#291) is in no window
|
|
1406
|
+
// now, so it isn't the copy the agent will read.
|
|
1407
|
+
if (this.contextManager.windowMode?.() === 'presented' && this.contextManager.windowStatusOf(row.id) === 'undone')
|
|
1408
|
+
continue;
|
|
1275
1409
|
// Read from the newest back, the first copy met is the newest
|
|
1276
1410
|
// content; its other parts pool with it.
|
|
1277
1411
|
newest ??= { contentHash: mark.contentHash, parts: mark.parts, held: new Set() };
|
|
@@ -1296,6 +1430,45 @@ export class Agent {
|
|
|
1296
1430
|
}
|
|
1297
1431
|
return newest && { contentHash: newest.contentHash, whole: newest.held.size === newest.parts };
|
|
1298
1432
|
}
|
|
1433
|
+
/** Set the unsent point where it isn't set, as a start's plan does: a row
|
|
1434
|
+
* stored after it counts as in no request until a compile built to send.
|
|
1435
|
+
* @internal For the framework's budget holds; not a host API. */
|
|
1436
|
+
markUnsentPoint() {
|
|
1437
|
+
const branch = branchKey(this.contextManager.currentBranchRef());
|
|
1438
|
+
if (this.unsentSince.has(branch))
|
|
1439
|
+
return;
|
|
1440
|
+
const count = this.contextManager.getMessageCount();
|
|
1441
|
+
const top = count > 0 ? this.contextManager.getMessageWindow(count - 1, 1, { resolveBlobs: false }).messages[0]?.sequence ?? 0 : 0;
|
|
1442
|
+
this.unsentSince.set(branch, top);
|
|
1443
|
+
}
|
|
1444
|
+
/** The ids of this agent's stored injections, of every namespace, stored
|
|
1445
|
+
* on its branch since its last compile built to send and in its window
|
|
1446
|
+
* where it's presented, in the record's order, a sharded body's first
|
|
1447
|
+
* shard first: the rows unsentInjection counts, which no request has
|
|
1448
|
+
* carried. Reads only, so an unset point gives none. */
|
|
1449
|
+
unsentInjectionRows() {
|
|
1450
|
+
const ids = [];
|
|
1451
|
+
const since = this.unsentSince.get(branchKey(this.contextManager.currentBranchRef()));
|
|
1452
|
+
if (since === undefined)
|
|
1453
|
+
return ids;
|
|
1454
|
+
const presented = this.contextManager.windowMode?.() === 'presented';
|
|
1455
|
+
scan: for (let end = this.contextManager.getMessageCount(); end > 0;) {
|
|
1456
|
+
const span = Math.min(end, 64);
|
|
1457
|
+
const { messages } = this.contextManager.getMessageWindow(end - span, span, { resolveBlobs: false });
|
|
1458
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1459
|
+
const row = messages[i];
|
|
1460
|
+
if (row.sequence <= since)
|
|
1461
|
+
break scan;
|
|
1462
|
+
if (storedInjectionMarkOf(row.metadata)?.agent !== this.name)
|
|
1463
|
+
continue;
|
|
1464
|
+
if (presented && this.contextManager.windowStatusOf(row.id) !== 'in')
|
|
1465
|
+
continue;
|
|
1466
|
+
ids.push(row.id);
|
|
1467
|
+
}
|
|
1468
|
+
end -= span;
|
|
1469
|
+
}
|
|
1470
|
+
return ids.reverse();
|
|
1471
|
+
}
|
|
1299
1472
|
/** Record which of this agent's stored injections a compile built to send
|
|
1300
1473
|
* rendered. Another agent's stored rows never reach this agent's compile,
|
|
1301
1474
|
* since every compile of a shared store leaves them out by its view
|
|
@@ -1345,13 +1518,9 @@ export class Agent {
|
|
|
1345
1518
|
const held = body.complete || (body.missing !== undefined && !body.missing.includes('shards'));
|
|
1346
1519
|
const contents = byNamespace.get(mark.namespace) ?? new Map();
|
|
1347
1520
|
byNamespace.set(mark.namespace, contents);
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
if (held)
|
|
1352
|
-
known.held.add(mark.part);
|
|
1353
|
-
known.sequence = Math.max(known.sequence, body.sequence);
|
|
1354
|
-
contents.set(mark.contentHash, known);
|
|
1521
|
+
const copies = contents.get(mark.contentHash) ?? [];
|
|
1522
|
+
copies.push({ id: body.messageId, part: mark.part, parts: mark.parts, held, sequence: body.sequence });
|
|
1523
|
+
contents.set(mark.contentHash, copies);
|
|
1355
1524
|
}
|
|
1356
1525
|
}
|
|
1357
1526
|
this.renderedInjections = { branch: provenance.branch, byNamespace };
|
|
@@ -1360,9 +1529,13 @@ export class Agent {
|
|
|
1360
1529
|
* The newest content of `namespace` among this agent's stored injections
|
|
1361
1530
|
* that the last compile built to send rendered, by its newest copy: its
|
|
1362
1531
|
* content hash, and whether every part of that content was there in some
|
|
1363
|
-
* copy, every shard, however the strategy shaped it.
|
|
1364
|
-
*
|
|
1365
|
-
* the
|
|
1532
|
+
* copy, every shard, however the strategy shaped it. Copies of the same
|
|
1533
|
+
* content pool what they hold: the agent has each part one of them holds.
|
|
1534
|
+
* A copy the agent's next request won't hold is passed over: one an undo
|
|
1535
|
+
* took out of its window since (#291: `'undone'`, which no presentation
|
|
1536
|
+
* point presents again until a redo), and one no longer stored. Undefined
|
|
1537
|
+
* when no copy is left, when this agent hasn't built a request since it
|
|
1538
|
+
* started, or when the window's branch has changed since.
|
|
1366
1539
|
*/
|
|
1367
1540
|
renderedInjection(namespace) {
|
|
1368
1541
|
const rendered = this.renderedInjections;
|
|
@@ -1370,11 +1543,38 @@ export class Agent {
|
|
|
1370
1543
|
if (!rendered || rendered.branch.id !== branch.id || rendered.branch.created !== branch.created)
|
|
1371
1544
|
return undefined;
|
|
1372
1545
|
let newest;
|
|
1373
|
-
for (const
|
|
1374
|
-
|
|
1375
|
-
|
|
1546
|
+
for (const [contentHash, copies] of rendered.byNamespace.get(namespace) ?? []) {
|
|
1547
|
+
let pooled;
|
|
1548
|
+
for (const copy of copies) {
|
|
1549
|
+
if (!this.renderedCopyStands(copy.id))
|
|
1550
|
+
continue;
|
|
1551
|
+
pooled ??= { parts: copy.parts, held: new Set(), sequence: copy.sequence };
|
|
1552
|
+
if (copy.held)
|
|
1553
|
+
pooled.held.add(copy.part);
|
|
1554
|
+
pooled.sequence = Math.max(pooled.sequence, copy.sequence);
|
|
1555
|
+
}
|
|
1556
|
+
if (pooled && (!newest || pooled.sequence > newest.sequence))
|
|
1557
|
+
newest = { contentHash, ...pooled };
|
|
1558
|
+
}
|
|
1559
|
+
return newest ? { contentHash: newest.contentHash, whole: newest.held.size === newest.parts } : undefined;
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* Whether a stored injection's copy the last compile rendered is still
|
|
1563
|
+
* where the agent's next request reads it: stored, and not taken out of
|
|
1564
|
+
* its window by an undo (#291). A copy out of the window otherwise
|
|
1565
|
+
* (`'out'`, as a redo leaves one presented since its undo) is presented
|
|
1566
|
+
* again at the agent's next point, its own rows' sweep, so it counts. A
|
|
1567
|
+
* context that can't say (a double without windowStatusOf, a read that
|
|
1568
|
+
* throws) counts it, as before the window was presented.
|
|
1569
|
+
*/
|
|
1570
|
+
renderedCopyStands(id) {
|
|
1571
|
+
try {
|
|
1572
|
+
const status = this.contextManager.windowStatusOf?.(id);
|
|
1573
|
+
return status !== 'undone' && status !== 'absent';
|
|
1574
|
+
}
|
|
1575
|
+
catch {
|
|
1576
|
+
return true;
|
|
1376
1577
|
}
|
|
1377
|
-
return newest ? { contentHash: newest[0], whole: newest[1].held.size === newest[1].parts } : undefined;
|
|
1378
1578
|
}
|
|
1379
1579
|
/**
|
|
1380
1580
|
* Whether compiled message `i` of `result` is a row of this agent's stored
|
|
@@ -1523,13 +1723,13 @@ export class Agent {
|
|
|
1523
1723
|
const { systemInjections } = compiled;
|
|
1524
1724
|
// The framework's own pricing stamp never goes out (thinking-token-stamp.ts);
|
|
1525
1725
|
// the agent's own turns are then presented under its name (presentOwnTurns).
|
|
1526
|
-
const messages = this.presentOwnTurns(withoutTokenEstimates(compiled.messages));
|
|
1726
|
+
const messages = this.presentOwnTurns(this.foreignRoundsAsSent(withoutTokenEstimates(compiled.messages)));
|
|
1527
1727
|
// Read once, after the first compile, since results may have become
|
|
1528
1728
|
// ready while it ran; the refusal retry, assembled while the agent is
|
|
1529
1729
|
// inferring, sends the same ones.
|
|
1530
1730
|
unguardedResults ??= this._state.status === 'ready' && !guardedResults
|
|
1531
1731
|
? this.buildToolResultMessages(this._state.toolResults) : [];
|
|
1532
|
-
messages
|
|
1732
|
+
appendAll(messages, unguardedResults);
|
|
1533
1733
|
return {
|
|
1534
1734
|
messages: this.toolResultGuard.prepareRequest(messages, true),
|
|
1535
1735
|
system: this.buildSystemPrompt(systemInjections),
|
|
@@ -1741,6 +1941,8 @@ export class Agent {
|
|
|
1741
1941
|
// compression path.)
|
|
1742
1942
|
// The same pass a tool boundary applies to what it notes as sent
|
|
1743
1943
|
// (sent-rows.ts), so the two can't drift.
|
|
1944
|
+
// Another agent's rounds go out as this agent is sent them (setForeignRounds).
|
|
1945
|
+
messages = this.foreignRoundsAsSent(messages);
|
|
1744
1946
|
messages = messages
|
|
1745
1947
|
.map((m) => ({ ...m, content: m.content.filter(carriedBlock) }))
|
|
1746
1948
|
.filter((m) => m.content.length > 0);
|
|
@@ -1842,8 +2044,9 @@ export class Agent {
|
|
|
1842
2044
|
const own = this.thinking !== null && typeof this.thinking === 'object' ? this.thinking : { enabled: false };
|
|
1843
2045
|
return { ...own, blockBinding: { prefixMismatchBehavior: 'drop_block' } };
|
|
1844
2046
|
}
|
|
1845
|
-
/** The stream's way to tell the context manager what its later rounds sent, with the head its compile was given
|
|
1846
|
-
* where the agent's model binds its thinking
|
|
2047
|
+
/** The stream's way to tell the context manager what its later rounds sent, with the head its compile was given,
|
|
2048
|
+
* and which stored bodies' thinking the provider dropped: where the agent's model binds its thinking
|
|
2049
|
+
* (context-manager's `noteRequestSent` and `noteThinkingDropped`). */
|
|
1847
2050
|
requestNotes(binding, compiled) {
|
|
1848
2051
|
const identity = binding.identity;
|
|
1849
2052
|
// Each note names the compile the stream was built from, so a note can't vouch for this stream under a record a
|
|
@@ -1853,7 +2056,10 @@ export class Agent {
|
|
|
1853
2056
|
if (!identity || compileId === undefined)
|
|
1854
2057
|
return {};
|
|
1855
2058
|
const cm = this.contextManager;
|
|
1856
|
-
return {
|
|
2059
|
+
return {
|
|
2060
|
+
noteRequestSent: (rows) => cm.noteRequestSent(rows, identity, compileId),
|
|
2061
|
+
noteThinkingDropped: (messageIds) => cm.noteThinkingDropped(messageIds, compileId),
|
|
2062
|
+
};
|
|
1857
2063
|
}
|
|
1858
2064
|
/**
|
|
1859
2065
|
* The binding a compile of this agent is told of (bindingCompileOptions), and a preview of its context too: the
|
|
@@ -1897,17 +2103,23 @@ export class Agent {
|
|
|
1897
2103
|
async buildActivationRequest(availableTools, injections, budget, compressionTools = availableTools, options = {}) {
|
|
1898
2104
|
return (await this.assembleActivationRequest(availableTools, injections, budget, compressionTools, options)).request;
|
|
1899
2105
|
}
|
|
1900
|
-
/** Stored rows that follow a request-only turn, memoized on the
|
|
1901
|
-
* cached
|
|
1902
|
-
*
|
|
2106
|
+
/** Stored rows that follow a request-only turn, memoized on the window's
|
|
2107
|
+
* cached row array (ContextManager returns the same array until the
|
|
2108
|
+
* window changes): the rows a compile sends are the window's (#291), and
|
|
2109
|
+
* a write another agent stores, which the window doesn't take, leaves the
|
|
2110
|
+
* memo as it was. A context without a window reads the record, the same
|
|
2111
|
+
* array as the window's for a single slot that is still the record. */
|
|
1903
2112
|
requestOnlyIndex = null;
|
|
1904
2113
|
indexRequestOnlyRows() {
|
|
1905
2114
|
const empty = { ticks: new Map(), prompts: new Map() };
|
|
1906
2115
|
const cm = this.contextManager;
|
|
1907
|
-
|
|
2116
|
+
const read = typeof cm.getPresentedMessages === 'function' ? () => cm.getPresentedMessages()
|
|
2117
|
+
: typeof cm.getAllMessages === 'function' ? () => cm.getAllMessages()
|
|
2118
|
+
: undefined;
|
|
2119
|
+
if (!read)
|
|
1908
2120
|
return empty;
|
|
1909
2121
|
try {
|
|
1910
|
-
const stored =
|
|
2122
|
+
const stored = read();
|
|
1911
2123
|
if (this.requestOnlyIndex?.source === stored)
|
|
1912
2124
|
return this.requestOnlyIndex.index;
|
|
1913
2125
|
const index = indexRequestOnlyRows(stored, this.ownParticipants);
|
|
@@ -2099,7 +2311,9 @@ export class Agent {
|
|
|
2099
2311
|
`output. See the refusal/inference-failed record for why.`);
|
|
2100
2312
|
return undefined;
|
|
2101
2313
|
}
|
|
2102
|
-
|
|
2314
|
+
// The agent's own round, stamped as its own (#291's audience stamp); its
|
|
2315
|
+
// id is the stream's last reply for the thinking binding (noteStreamEnd).
|
|
2316
|
+
return storeOwnRow(this, this.name, content, metadata);
|
|
2103
2317
|
}
|
|
2104
2318
|
/**
|
|
2105
2319
|
* Transition back to streaming state after tool results are provided.
|
|
@@ -2200,6 +2414,24 @@ export class Agent {
|
|
|
2200
2414
|
getContextManager() {
|
|
2201
2415
|
return this.contextManager;
|
|
2202
2416
|
}
|
|
2417
|
+
/** Where this agent tells of its own rows once they are stored (setOwnRowSink). */
|
|
2418
|
+
ownRowSink;
|
|
2419
|
+
/**
|
|
2420
|
+
* Install where this agent tells of its own rows once they are stored
|
|
2421
|
+
* (its rounds and the rows the framework writes for it through
|
|
2422
|
+
* storeOwnRow, and its tool results through its guard), or take it off
|
|
2423
|
+
* with undefined. The presentation index (#291) installs one when it takes
|
|
2424
|
+
* the agent on, and presents each row in the agent's window as it is
|
|
2425
|
+
* told. With none, as for an agent nothing took on, nothing is told.
|
|
2426
|
+
*/
|
|
2427
|
+
setOwnRowSink(sink) {
|
|
2428
|
+
this.ownRowSink = sink;
|
|
2429
|
+
this.toolResultGuard.setOwnRowSink(sink);
|
|
2430
|
+
}
|
|
2431
|
+
/** Tell the sink of own rows just stored (storeOwnRow calls it, once each add has returned). */
|
|
2432
|
+
ownRowsStored(ids) {
|
|
2433
|
+
this.ownRowSink?.(ids);
|
|
2434
|
+
}
|
|
2203
2435
|
/**
|
|
2204
2436
|
* Build the effective system prompt, appending any system-position
|
|
2205
2437
|
* injections, their blocks joined by line breaks. The system prompt is
|
|
@@ -2280,9 +2512,9 @@ export class Agent {
|
|
|
2280
2512
|
this.toolResultGuard.recovering = false;
|
|
2281
2513
|
const content = guardedRefusal ? [] : response.content;
|
|
2282
2514
|
const { toolCalls, speechContent } = this.extractToolCallsAndSpeech(content);
|
|
2283
|
-
// Add assistant response to context
|
|
2515
|
+
// Add assistant response to context, as the agent's own row
|
|
2284
2516
|
if (!guardedRefusal)
|
|
2285
|
-
|
|
2517
|
+
storeOwnRow(this, this.name, content);
|
|
2286
2518
|
return {
|
|
2287
2519
|
toolCalls,
|
|
2288
2520
|
speechContent,
|