@animalabs/agent-framework 0.32.0 → 0.33.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 +204 -14
- 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 +185 -78
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +279 -102
- 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/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 +67 -0
- package/dist/src/context-options.d.ts.map +1 -0
- package/dist/src/context-options.js +85 -0
- package/dist/src/context-options.js.map +1 -0
- 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 +179 -10
- 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/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 +1976 -818
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +7566 -3422
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +85 -15
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +421 -47
- 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/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 +135 -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/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 +5 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -0
- package/dist/src/index.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 +131 -15
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +290 -46
- 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/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 +13 -10
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +134 -56
- 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/types.d.ts +8 -2
- 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 +237 -86
- package/dist/src/modules/discord/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 +15 -22
- 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 +76 -22
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/notice-tags.d.ts +10 -1
- package/dist/src/notice-tags.d.ts.map +1 -1
- package/dist/src/notice-tags.js +10 -1
- 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 +746 -0
- package/dist/src/presentation.d.ts.map +1 -0
- package/dist/src/presentation.js +1435 -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/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 +273 -29
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js +22 -3
- 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/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/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 +1159 -79
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +3709 -363
- 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 +87 -27
- 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 +82 -20
- 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 +32 -12
- package/dist/src/types/framework.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 +510 -36
- package/dist/src/types/trace.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/admission/admit.ts +32 -3
- package/src/agent.ts +323 -120
- package/src/api/mcp-server-core.ts +54 -17
- package/src/api/server.ts +4 -23
- 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 +96 -0
- 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 +209 -12
- package/src/dendrite/types.ts +92 -8
- package/src/foreign-rounds.ts +199 -0
- package/src/framework.ts +7804 -3546
- package/src/gate/event-gate.ts +428 -65
- package/src/gate/index.ts +3 -0
- 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 +141 -7
- package/src/gate/wake-onboarding.ts +309 -0
- package/src/held-writes.ts +49 -60
- package/src/index.ts +9 -2
- package/src/jsonrpc-envelope.ts +81 -0
- package/src/mcpl/channel-registry.ts +353 -85
- 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/push-coalescer.ts +193 -34
- package/src/mcpl/push-handler.ts +10 -5
- package/src/mcpl/server-connection.ts +141 -60
- package/src/mcpl/tool-classes.ts +3 -0
- package/src/mcpl/types.ts +8 -2
- package/src/module-registry.ts +73 -17
- package/src/modules/discord/index.ts +229 -81
- package/src/modules/history/index.ts +439 -70
- package/src/modules/history/semantic.ts +15 -21
- package/src/modules/workspace/disk-agreement.ts +1 -1
- package/src/modules/workspace/index.ts +85 -23
- package/src/notice-tags.ts +10 -1
- package/src/operator-log.ts +36 -3
- package/src/presentation.ts +1676 -0
- package/src/prose-drafts.ts +16 -12
- package/src/read-marks.ts +328 -0
- package/src/recovery/offline-branch.ts +346 -32
- package/src/recovery/recover-cli.ts +21 -3
- package/src/send-tools.ts +40 -7
- package/src/stored-injections.ts +2 -2
- package/src/stored-removal.ts +31 -7
- package/src/tool-result-guard.ts +41 -7
- package/src/tune-out/coordinator.ts +4089 -457
- package/src/tune-out/tools.ts +160 -43
- package/src/tune-out/window-anchor.ts +277 -0
- package/src/types/agent.ts +86 -20
- package/src/types/events.ts +2 -0
- package/src/types/framework.ts +32 -12
- package/src/types/module.ts +181 -68
- package/src/types/trace.ts +542 -40
package/src/send-tools.ts
CHANGED
|
@@ -1,12 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tools whose call
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* it was delivered.
|
|
2
|
+
* Tools whose call carries the resident's words, by bare name (an MCPL
|
|
3
|
+
* server's `<prefix>--` stripped); edit_message's words are the new text of a
|
|
4
|
+
* message it sent. The framework reads a call of a `silences` one as an
|
|
5
|
+
* explicit send that silences the round's auto-routed prose where it may have
|
|
6
|
+
* posted; the history module reads the words of any of them as what the
|
|
7
|
+
* resident wrote to someone, whether or not it was delivered. With prose
|
|
8
|
+
* routing disabled the resident speaks through these.
|
|
8
9
|
*/
|
|
9
|
-
|
|
10
|
+
const SPEECH_TOOLS: ReadonlyMap<string, { words: readonly string[]; silences: boolean }> = new Map([
|
|
11
|
+
// channel_publish still takes `text` from older callers.
|
|
12
|
+
['channel_publish', { words: ['content', 'text'], silences: true }],
|
|
13
|
+
// telegram-mcpl's send_message takes `message`.
|
|
14
|
+
['send_message', { words: ['content', 'message', 'text'], silences: true }],
|
|
15
|
+
['reply_message', { words: ['content', 'text'], silences: true }],
|
|
16
|
+
['send_dm', { words: ['content', 'text'], silences: true }],
|
|
17
|
+
// telegram-mcpl's reply, file send, scheduled send and poll.
|
|
18
|
+
['reply_to_message', { words: ['text'], silences: true }],
|
|
19
|
+
['send_file', { words: ['caption'], silences: false }],
|
|
20
|
+
['send_scheduled_message', { words: ['message'], silences: false }],
|
|
21
|
+
['create_poll', { words: ['question'], silences: false }],
|
|
22
|
+
// telegram-mcpl's edit_message takes `new_text`.
|
|
23
|
+
['edit_message', { words: ['content', 'new_text', 'text'], silences: false }],
|
|
24
|
+
// slack-mcpl's upload_file posts `comment` with the file; its `content` is
|
|
25
|
+
// the file.
|
|
26
|
+
['upload_file', { words: ['comment'], silences: false }],
|
|
27
|
+
// Eidoverse's say and whisper take `text`.
|
|
28
|
+
['say', { words: ['text'], silences: true }],
|
|
29
|
+
['whisper', { words: ['text'], silences: true }],
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
export const SILENCING_SENDS = new Set([...SPEECH_TOOLS].filter(([, tool]) => tool.silences).map(([name]) => name));
|
|
10
33
|
|
|
11
34
|
/** Strip the `server--` MCPL prefix from a tool name. */
|
|
12
35
|
export const bareToolName = (n: string): string => n.split('--').pop()!;
|
|
36
|
+
|
|
37
|
+
export function speechOf(name: unknown, input: unknown): { tool: string; words: string } | undefined {
|
|
38
|
+
if (typeof name !== 'string' || typeof input !== 'object' || input === null) return undefined;
|
|
39
|
+
const tool = bareToolName(name);
|
|
40
|
+
const row = SPEECH_TOOLS.get(tool);
|
|
41
|
+
if (!row) return undefined;
|
|
42
|
+
const args = input as Record<string, unknown>;
|
|
43
|
+
const words = row.words.map((arg) => args[arg]).find((value) => value !== undefined && value !== null);
|
|
44
|
+
return typeof words === 'string' && words.trim().length > 0 ? { tool, words } : undefined;
|
|
45
|
+
}
|
package/src/stored-injections.ts
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* a start stored whose compile then didn't record) has the same content,
|
|
15
15
|
* every part of it, and the compile
|
|
16
16
|
* then renders
|
|
17
|
-
* it from the store like any message, where it stays. While the
|
|
18
|
-
*
|
|
17
|
+
* it from the store like any message, where it stays. While the host is
|
|
18
|
+
* quiesced, `compile()` places it instead. Being a
|
|
19
19
|
* message, it's history to the strategy: capped by its per-message bound,
|
|
20
20
|
* sharded, selected by the budget and folded like any other.
|
|
21
21
|
*
|
package/src/stored-removal.ts
CHANGED
|
@@ -50,13 +50,14 @@ export function locateMessageIndices(
|
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Inclusive slot range of the body-group run containing `index` (the slot
|
|
53
|
-
* itself when it is not sharded)
|
|
54
|
-
* `alignToBodyGroups` edge walk — one
|
|
53
|
+
* itself when it is not sharded), and the ids of its rows in store order.
|
|
54
|
+
* Delegates to the store's own `alignToBodyGroups` edge walk — one
|
|
55
|
+
* contiguity assumption, not two.
|
|
55
56
|
*/
|
|
56
57
|
export function bodyGroupRun(
|
|
57
58
|
cm: SurgeryReadableCm,
|
|
58
59
|
index: number,
|
|
59
|
-
): { from: number; to: number; fromId: string; toId: string; group: boolean } {
|
|
60
|
+
): { from: number; to: number; fromId: string; toId: string; group: boolean; ids: MessageId[] } {
|
|
60
61
|
const win = cm.getMessageWindow(index, 1, { alignToBodyGroups: true, resolveBlobs: false });
|
|
61
62
|
const from = win.startIndex;
|
|
62
63
|
const to = win.startIndex + win.messages.length - 1;
|
|
@@ -66,6 +67,7 @@ export function bodyGroupRun(
|
|
|
66
67
|
fromId: String(win.messages[0].id),
|
|
67
68
|
toId: String(win.messages[win.messages.length - 1].id),
|
|
68
69
|
group: win.messages[0].bodyGroupId !== undefined,
|
|
70
|
+
ids: win.messages.map((m) => String(m.id) as MessageId),
|
|
69
71
|
};
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -90,23 +92,45 @@ export function removeStoredMessages(cm: Removals, first: StoredLike, last: Stor
|
|
|
90
92
|
* Remove one stored message by its id, with the rest of its body when it's
|
|
91
93
|
* in one: a module or a coalescer removes a message it added by the id
|
|
92
94
|
* `addMessage` returned, which for a long message stored in shards is its
|
|
93
|
-
* first shard's.
|
|
95
|
+
* first shard's. Returns the ids of every row it removed, in store order:
|
|
96
|
+
* the id given for a message outside any body, each shard's for a body, so
|
|
97
|
+
* a caller can take them out of the windows of the other agents that held
|
|
98
|
+
* them (#291).
|
|
94
99
|
*/
|
|
95
|
-
export function removeStoredMessage(cm: ContextManager, id: MessageId):
|
|
100
|
+
export function removeStoredMessage(cm: ContextManager, id: MessageId): MessageId[] {
|
|
96
101
|
const message = cm.getMessage(id) as StoredLike | null;
|
|
97
102
|
if (!message?.bodyGroupId) {
|
|
98
103
|
cm.removeMessage(id);
|
|
99
|
-
return;
|
|
104
|
+
return [id];
|
|
100
105
|
}
|
|
101
106
|
// Found in blob-free windows: a full read of the branch would inflate every
|
|
102
107
|
// attachment on it, once for each message a sweep removes.
|
|
103
108
|
const index = locateMessageIndex(cm, String(id));
|
|
104
109
|
if (index < 0) {
|
|
105
110
|
cm.removeMessage(id);
|
|
106
|
-
return;
|
|
111
|
+
return [id];
|
|
107
112
|
}
|
|
108
113
|
const run = bodyGroupRun(cm, index);
|
|
109
114
|
cm.removeMessages(run.fromId as MessageId, run.toId as MessageId);
|
|
115
|
+
return run.ids;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The ids of the stored messages `firstId`..`lastId` (inclusive, in store
|
|
120
|
+
* order, every shard of a body), read before a removal of that interval so
|
|
121
|
+
* the caller knows what it took. Both ends are found tail-first and the
|
|
122
|
+
* rows between them read in one blob-free window. Empty when either end is
|
|
123
|
+
* not on the active branch; the ends may be given in either order.
|
|
124
|
+
*/
|
|
125
|
+
export function storedIdsBetween(cm: SurgeryReadableCm, firstId: string, lastId: string): MessageId[] {
|
|
126
|
+
const found = locateMessageIndices(cm, new Set([firstId, lastId]));
|
|
127
|
+
const first = found.get(firstId);
|
|
128
|
+
const last = found.get(lastId);
|
|
129
|
+
if (!first || !last) return [];
|
|
130
|
+
const from = Math.min(first.index, last.index);
|
|
131
|
+
const to = Math.max(first.index, last.index);
|
|
132
|
+
const { messages } = cm.getMessageWindow(from, to - from + 1, { resolveBlobs: false });
|
|
133
|
+
return messages.map((m) => String(m.id) as MessageId);
|
|
110
134
|
}
|
|
111
135
|
|
|
112
136
|
/** removeStoredMessages for an interval known by its ids. */
|
package/src/tool-result-guard.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { ensureStateRegistered } from './module-registry.js';
|
|
|
7
7
|
import { classifyBlock } from './mcpl/references.js';
|
|
8
8
|
import { resultClaimsOf, rfc005TextOf, toolResultDataToHistoryString } from './tool-result-history.js';
|
|
9
9
|
import { safeSlice } from './safe-slice.js';
|
|
10
|
+
import { asOwnRow, presentLandedThenRethrow } from './dendrite/audience.js';
|
|
10
11
|
|
|
11
12
|
export const TOOL_RESULT_GUARD_NOTICE = 'Tool result withheld by the guard. The tool has already executed.';
|
|
12
13
|
export type WithheldNoticeKind = 'ran' | 'refused' | 'error';
|
|
@@ -195,6 +196,16 @@ export class ToolResultGuard {
|
|
|
195
196
|
|
|
196
197
|
get enabled(): boolean { return this.override ?? this.configured; }
|
|
197
198
|
setHost(host: WithheldHost | undefined): void { this.host = host; }
|
|
199
|
+
|
|
200
|
+
/** Where the results message is told of once stored (the agent's own-row sink, Agent.setOwnRowSink). */
|
|
201
|
+
private ownRowSink?: (ids: readonly MessageId[]) => void;
|
|
202
|
+
/**
|
|
203
|
+
* Install where storeResults tells of the results message it stores, once
|
|
204
|
+
* the add has returned (the presentation index presents it in the agent's
|
|
205
|
+
* window then, #291), or take it off with undefined. An idempotent retry
|
|
206
|
+
* of a batch already staged stores nothing and tells nothing.
|
|
207
|
+
*/
|
|
208
|
+
setOwnRowSink(sink: ((ids: readonly MessageId[]) => void) | undefined): void { this.ownRowSink = sink; }
|
|
198
209
|
/** Settles once every annotation started so far has finished: each of
|
|
199
210
|
* those stubs has been edited to say where its original is, or its edit
|
|
200
211
|
* failed and waits in the storage queue, retried in order until it lands
|
|
@@ -343,7 +354,9 @@ export class ToolResultGuard {
|
|
|
343
354
|
|
|
344
355
|
/** `keptCap` is where what a stub keeps of a withheld result is cut: the
|
|
345
356
|
* cap the caller stored `content` under, less the stub's notice room where
|
|
346
|
-
* its message's bound sets it (toolResultShare, tool-image-ledger.ts).
|
|
357
|
+
* its message's bound sets it (toolResultShare, tool-image-ledger.ts).
|
|
358
|
+
* The results are the agent's own row, stamped so (asOwnRow) on top of
|
|
359
|
+
* the caller's `metadata`, guarded or not. */
|
|
347
360
|
storeResults(
|
|
348
361
|
content: ContentBlock[],
|
|
349
362
|
wireResults: ToolResult[],
|
|
@@ -352,7 +365,17 @@ export class ToolResultGuard {
|
|
|
352
365
|
/** Where what a stub keeps is cut. */
|
|
353
366
|
keptCap: number | undefined,
|
|
354
367
|
): MessageId {
|
|
355
|
-
|
|
368
|
+
metadata = asOwnRow(metadata, this.agentName);
|
|
369
|
+
if (!this.enabled) {
|
|
370
|
+
let id: MessageId;
|
|
371
|
+
try {
|
|
372
|
+
id = this.cm.addMessage('user', content, metadata);
|
|
373
|
+
} catch (error) {
|
|
374
|
+
presentLandedThenRethrow(error, this.agentName, this.ownRowSink, (row) => this.cm.getMessage(row) !== null);
|
|
375
|
+
}
|
|
376
|
+
this.ownRowSink?.([id]);
|
|
377
|
+
return id;
|
|
378
|
+
}
|
|
356
379
|
if (this.pending) {
|
|
357
380
|
// Idempotent for the same not-yet-submitted batch: a caller that
|
|
358
381
|
// retries after a failure between staging and submission (e.g. a
|
|
@@ -392,9 +415,19 @@ export class ToolResultGuard {
|
|
|
392
415
|
// chunk is ever summarized from the placeholder; released after the
|
|
393
416
|
// settlement edit. Holds are in-memory only — a reopened manager has none,
|
|
394
417
|
// which is correct since a reopened guard has no pending batch.
|
|
395
|
-
|
|
418
|
+
// A write that throws with rows of it stored presents them, as one that
|
|
419
|
+
// returned would be, and throws on with no batch pending, as before.
|
|
420
|
+
let messageId: MessageId;
|
|
421
|
+
try {
|
|
422
|
+
messageId = this.cm.addMessage('user', withheld, metadata, undefined, { holdCompression: true });
|
|
423
|
+
} catch (error) {
|
|
424
|
+
presentLandedThenRethrow(error, this.agentName, this.ownRowSink, (row) => this.cm.getMessage(row) !== null);
|
|
425
|
+
}
|
|
396
426
|
this.pending = { id, messageId, content, withheld, wireResults,
|
|
397
427
|
branch: this.cm.currentBranch().name, submitted: false, durable: false, kept, notices };
|
|
428
|
+
// Told before the durability barrier below, so the sync that makes the
|
|
429
|
+
// audit durable carries the row's presentation too.
|
|
430
|
+
this.ownRowSink?.([messageId]);
|
|
398
431
|
// Durability barrier: the audit must reach Chronicle's chain heads before
|
|
399
432
|
// the originals can go to a provider. On a failed sync the batch fails
|
|
400
433
|
// CLOSED: the placeholders go on the wire instead (the turn continues,
|
|
@@ -575,8 +608,9 @@ export class ToolResultGuard {
|
|
|
575
608
|
let deadlineSpent = false;
|
|
576
609
|
for (const [index, block] of pending.content.entries()) {
|
|
577
610
|
if (block.type !== 'tool_result') continue;
|
|
578
|
-
// Once the store has left the batch's branch (a rollback,
|
|
579
|
-
// host's switch
|
|
611
|
+
// Once the store has left the batch's branch (a rollback, a
|
|
612
|
+
// suppression, a host's switch; an undo moves no branch), write no
|
|
613
|
+
// more. This result and every later one is
|
|
580
614
|
// skipped, and its original stays in the audit record. Nothing
|
|
581
615
|
// yields from here to the edit's own branch check, so while the
|
|
582
616
|
// store is away the stub stays as it is. A write already under way
|
|
@@ -606,8 +640,8 @@ export class ToolResultGuard {
|
|
|
606
640
|
// Declined where it would have committed, since the workspace had
|
|
607
641
|
// left the batch's branch. Nothing was written, and no more are, as
|
|
608
642
|
// for the results the branch check above stops. If the branch is
|
|
609
|
-
// back by the edit, as after
|
|
610
|
-
// result and the later ones name the audit record.
|
|
643
|
+
// back by the edit, as after a host's switch away and back, the stubs
|
|
644
|
+
// of this result and the later ones name the audit record.
|
|
611
645
|
if (spill && 'skipped' in spill && spill.skipped === 'branch_changed') branchLeft = true;
|
|
612
646
|
// A batch that used its deadline is said once, here, where the
|
|
613
647
|
// batch is known; the host returns the skip without a line.
|