@animalabs/agent-framework 0.26.1 → 0.27.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 +57 -7
- package/dist/src/agent.d.ts +263 -22
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +531 -54
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +1 -2
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/auto-continue.d.ts +33 -0
- package/dist/src/auto-continue.d.ts.map +1 -0
- package/dist/src/auto-continue.js +35 -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/framework.d.ts +829 -156
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +3906 -1008
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +309 -46
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +2117 -395
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/gate/index.d.ts +2 -2
- package/dist/src/gate/index.d.ts.map +1 -1
- package/dist/src/gate/index.js +1 -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/types.d.ts +68 -8
- package/dist/src/gate/types.d.ts.map +1 -1
- package/dist/src/index.d.ts +6 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -2
- package/dist/src/index.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 +1152 -434
- 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/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 +737 -78
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +82 -3
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +132 -7
- package/dist/src/mcpl/server-connection.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 +259 -0
- package/dist/src/mcpl/tool-presence.d.ts.map +1 -0
- package/dist/src/mcpl/tool-presence.js +628 -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 +39 -0
- package/dist/src/mcpl/tool-signature.d.ts.map +1 -0
- package/dist/src/mcpl/tool-signature.js +292 -0
- package/dist/src/mcpl/tool-signature.js.map +1 -0
- package/dist/src/mcpl/toolset-host.d.ts +200 -0
- package/dist/src/mcpl/toolset-host.d.ts.map +1 -0
- package/dist/src/mcpl/toolset-host.js +621 -0
- package/dist/src/mcpl/toolset-host.js.map +1 -0
- package/dist/src/mcpl/toolsets-module.d.ts +80 -0
- package/dist/src/mcpl/toolsets-module.d.ts.map +1 -0
- package/dist/src/mcpl/toolsets-module.js +431 -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 +21 -1
- 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 +23 -8
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +68 -15
- 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 +51 -17
- 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/direct-write.d.ts +181 -0
- package/dist/src/modules/workspace/direct-write.d.ts.map +1 -0
- package/dist/src/modules/workspace/direct-write.js +384 -0
- package/dist/src/modules/workspace/direct-write.js.map +1 -0
- package/dist/src/modules/workspace/edit-text.d.ts +26 -12
- package/dist/src/modules/workspace/edit-text.d.ts.map +1 -1
- package/dist/src/modules/workspace/edit-text.js +58 -28
- 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 +1 -1
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +246 -27
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +1216 -236
- package/dist/src/modules/workspace/index.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 +213 -0
- package/dist/src/modules/workspace/read-page.js.map +1 -0
- package/dist/src/modules/workspace/result-text.d.ts +67 -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/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 +41 -17
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.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 +81 -0
- package/dist/src/thinking-drops.d.ts.map +1 -0
- package/dist/src/thinking-drops.js +103 -0
- package/dist/src/thinking-drops.js.map +1 -0
- 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 +4 -2
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +21 -6
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +186 -21
- package/dist/src/tool-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +428 -89
- 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/types/agent.d.ts +186 -7
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +19 -2
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +24 -3
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +90 -7
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +57 -2
- package/dist/src/types/trace.d.ts.map +1 -1
- package/package.json +4 -3
- package/src/agent.ts +593 -60
- package/src/api/server.ts +1 -2
- package/src/auto-continue.ts +42 -0
- package/src/code-execution/isolate/scripts.ts +11 -3
- package/src/framework.ts +4004 -1026
- package/src/gate/event-gate.ts +2315 -389
- package/src/gate/index.ts +2 -1
- package/src/gate/recipe-reconcile.ts +355 -0
- package/src/gate/types.ts +70 -8
- package/src/index.ts +7 -4
- package/src/mcpl/channel-registry.ts +1220 -467
- 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/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 +852 -78
- package/src/mcpl/server-connection.ts +145 -7
- package/src/mcpl/tool-lifecycle.ts +21 -0
- package/src/mcpl/tool-presence.ts +650 -0
- package/src/mcpl/tool-result-normalize.ts +18 -6
- package/src/mcpl/tool-signature.ts +285 -0
- package/src/mcpl/toolset-host.ts +637 -0
- package/src/mcpl/toolsets-module.ts +451 -0
- package/src/mcpl/transport.ts +3 -2
- package/src/mcpl/types.ts +22 -1
- package/src/mcpl/visible-content.ts +22 -9
- package/src/module-registry.ts +77 -24
- package/src/modules/discord/index.ts +1 -1
- package/src/modules/history/index.ts +48 -18
- package/src/modules/history/semantic.ts +308 -54
- package/src/modules/workspace/direct-write.ts +425 -0
- package/src/modules/workspace/edit-text.ts +82 -35
- package/src/modules/workspace/effects.ts +1 -1
- package/src/modules/workspace/index.ts +1274 -241
- package/src/modules/workspace/read-page.ts +222 -0
- package/src/modules/workspace/result-text.ts +119 -0
- package/src/modules/workspace/text.ts +58 -32
- package/src/modules/workspace/types.ts +41 -17
- 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 +141 -0
- package/src/tool-image-ledger.ts +9 -8
- package/src/tool-presentation.ts +3 -1
- package/src/tool-result-guard.ts +19 -6
- package/src/tool-result-history.ts +488 -88
- package/src/tune-out/coordinator.ts +80 -37
- package/src/types/agent.ts +189 -7
- package/src/types/events.ts +19 -2
- package/src/types/framework.ts +21 -3
- package/src/types/module.ts +86 -7
- package/src/types/trace.ts +58 -2
package/src/gate/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { EventGate, wakeProvenance, type WakeProvenance } from './event-gate.js';
|
|
1
|
+
export { EventGate, wakeProvenance, wakeLineText, type WakeProvenance, type WritePlacement } from './event-gate.js';
|
|
2
2
|
export type {
|
|
3
3
|
GateConfig,
|
|
4
4
|
GateOptions,
|
|
@@ -9,4 +9,5 @@ export type {
|
|
|
9
9
|
GateEventInfo,
|
|
10
10
|
GateStatus,
|
|
11
11
|
GatePolicyStats,
|
|
12
|
+
WakeLine,
|
|
12
13
|
} from './types.js';
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a start does to an existing gate.json, given the recipe's gate config.
|
|
3
|
+
*
|
|
4
|
+
* The gate keeps the recipe it last applied in a file of its own beside
|
|
5
|
+
* gate.json (`gate.recipe.json` for `gate.json`), written by the gate. A start
|
|
6
|
+
* merges the recipe into gate.json three ways, rule by rule, against it:
|
|
7
|
+
* - a rule as the last recipe left it follows the new recipe: it takes the
|
|
8
|
+
* new definition, or goes when the new recipe no longer declares it, so a
|
|
9
|
+
* renamed rule goes under its old name and comes in under its new one;
|
|
10
|
+
* - a rule edited since the last recipe keeps its definition, unless it now
|
|
11
|
+
* agrees with the recipe's;
|
|
12
|
+
* - a rule both recipes declare, removed from gate.json since, comes back;
|
|
13
|
+
* - a rule no recipe declared (added at run time, or by hand) stays, and if
|
|
14
|
+
* the recipe now declares it as it stands, it's the recipe's from then on;
|
|
15
|
+
* - a rule new in the recipe comes in.
|
|
16
|
+
*
|
|
17
|
+
* Order is an edit of its own, apart from a rule's definition. When gate.json
|
|
18
|
+
* holds the rules both recipes declare in the last recipe's order, the recipe's
|
|
19
|
+
* rules take the new recipe's order, in the places gate.json gives them, and
|
|
20
|
+
* every other rule keeps its place. When one of them was moved since
|
|
21
|
+
* (wake_add_rule's position moves one), gate.json's order stays. Either way, a
|
|
22
|
+
* recipe rule new to gate.json goes before the recipe rule that follows it
|
|
23
|
+
* there, or after the one before it when none follows.
|
|
24
|
+
* `default` follows the same rule as a definition.
|
|
25
|
+
*
|
|
26
|
+
* Without a last recipe, as at the first start after this change, nothing is
|
|
27
|
+
* removed or redefined: the rules that match the recipe by name and definition
|
|
28
|
+
* take its order, every other rule stays, and the line names those that differ
|
|
29
|
+
* from the recipe or aren't in it. A rule that differs can be removed, and the
|
|
30
|
+
* next start restores it from the recipe.
|
|
31
|
+
*
|
|
32
|
+
* Rules are compared by what they mean and kept as written. Two rules agree
|
|
33
|
+
* when the gate reads them the same, so a rule `wake_add_rule` wrote as the
|
|
34
|
+
* gate reads it agrees with the recipe's rule as written, and a change to a
|
|
35
|
+
* field the gate doesn't read alone isn't an edit; the caller gives the
|
|
36
|
+
* meaning (`meaningOf`). A rule the gate leaves out has no reading, so it is
|
|
37
|
+
* compared as written, a change to any of its fields an edit. A rule that agrees with the recipe stays as gate.json
|
|
38
|
+
* holds it, and one that follows the recipe takes the recipe's rule as
|
|
39
|
+
* written. A rule with no name stays where gate.json holds it, and a recipe's
|
|
40
|
+
* rule with no name is never merged: the merge keys rules by name.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/** What a start changed, by rule name, for its trace and its log line. */
|
|
44
|
+
export interface RecipeChanges {
|
|
45
|
+
added: string[];
|
|
46
|
+
removed: string[];
|
|
47
|
+
updated: string[];
|
|
48
|
+
restored: string[];
|
|
49
|
+
moved: string[];
|
|
50
|
+
/** Edited since the last recipe, and kept, though the new recipe changed or dropped it. */
|
|
51
|
+
keptEdited: string[];
|
|
52
|
+
/** Kept, though the recipe declares the name with another definition. */
|
|
53
|
+
differsFromRecipe: string[];
|
|
54
|
+
/** Kept, and in no recipe: named at a start without a last recipe only. */
|
|
55
|
+
outsideRecipe: string[];
|
|
56
|
+
/** gate.json's order was kept, though the recipe changed its order, since a recipe rule was moved in it. */
|
|
57
|
+
orderKept: boolean;
|
|
58
|
+
defaultChange?: { from: string; to: string };
|
|
59
|
+
/** The live `default`, kept as edited, though the recipe changed it. */
|
|
60
|
+
defaultKept?: string;
|
|
61
|
+
/** At a start without a last recipe: the live `default`, kept, and the recipe's, which differs. */
|
|
62
|
+
defaultDiffers?: { kept: string; recipe: string };
|
|
63
|
+
/** Why the recorded recipe couldn't be read, when it exists and doesn't read. */
|
|
64
|
+
recordUnreadable?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** The file beside gate.json that holds the recipe the gate last applied. */
|
|
68
|
+
export function lastRecipePath(configPath: string): string {
|
|
69
|
+
return `${configPath.replace(/\.json$/, '')}.recipe.json`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function sortKeys(value: unknown): unknown {
|
|
73
|
+
if (Array.isArray(value)) return value.map(sortKeys);
|
|
74
|
+
if (value && typeof value === 'object') {
|
|
75
|
+
// No prototype, so a key such as "__proto__", which JSON.parse gives as an
|
|
76
|
+
// own field, is copied as one rather than setting the prototype.
|
|
77
|
+
const out: Record<string, unknown> = Object.create(null);
|
|
78
|
+
for (const key of Object.keys(value as Record<string, unknown>).sort()) {
|
|
79
|
+
out[key] = sortKeys((value as Record<string, unknown>)[key]);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** A config or policy as text that doesn't depend on its keys' order. */
|
|
87
|
+
export function canonical(value: unknown): string {
|
|
88
|
+
return JSON.stringify(sortKeys(value));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const same = (a: unknown, b: unknown): boolean => canonical(a) === canonical(b);
|
|
92
|
+
|
|
93
|
+
/** Changes with nothing in them, for a start to fill. */
|
|
94
|
+
export function noChanges(): RecipeChanges {
|
|
95
|
+
return {
|
|
96
|
+
added: [], removed: [], updated: [], restored: [], moved: [],
|
|
97
|
+
keptEdited: [], differsFromRecipe: [], outsideRecipe: [], orderKept: false,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** A gate config as written: its rule list and its `default`, each as given. */
|
|
102
|
+
export interface WrittenConfig { rules: readonly unknown[]; default: unknown }
|
|
103
|
+
|
|
104
|
+
/** A rule's name as written, when it has a usable one. */
|
|
105
|
+
export function ruleName(rule: unknown): string | undefined {
|
|
106
|
+
if (!rule || typeof rule !== 'object' || Array.isArray(rule)) return undefined;
|
|
107
|
+
const name = (rule as { name?: unknown }).name;
|
|
108
|
+
return typeof name === 'string' && name ? name : undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** A rule name the list gives more than once, if any: the merge keys rules by name. */
|
|
112
|
+
export function duplicateName(rules: readonly unknown[]): string | undefined {
|
|
113
|
+
const seen = new Set<string>();
|
|
114
|
+
for (const rule of rules) {
|
|
115
|
+
const name = ruleName(rule);
|
|
116
|
+
if (name === undefined) continue;
|
|
117
|
+
if (seen.has(name)) return name;
|
|
118
|
+
seen.add(name);
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** A `default` as the gate reads one: left out, null or "" is "always". */
|
|
124
|
+
function behaviorOf(value: unknown): unknown {
|
|
125
|
+
return value === undefined || value === null || value === '' ? 'always' : value;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** The names in one longest sequence that `a` and `b` share in order. */
|
|
129
|
+
function longestShared(a: string[], b: string[]): Set<string> {
|
|
130
|
+
const rows = a.length + 1;
|
|
131
|
+
const cols = b.length + 1;
|
|
132
|
+
const table: number[][] = Array.from({ length: rows }, () => new Array<number>(cols).fill(0));
|
|
133
|
+
for (let i = a.length - 1; i >= 0; i--) {
|
|
134
|
+
for (let j = b.length - 1; j >= 0; j--) {
|
|
135
|
+
table[i][j] = a[i] === b[j] ? table[i + 1][j + 1] + 1 : Math.max(table[i + 1][j], table[i][j + 1]);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const shared = new Set<string>();
|
|
139
|
+
let i = 0;
|
|
140
|
+
let j = 0;
|
|
141
|
+
while (i < a.length && j < b.length) {
|
|
142
|
+
if (a[i] === b[j]) {
|
|
143
|
+
shared.add(a[i]);
|
|
144
|
+
i++;
|
|
145
|
+
j++;
|
|
146
|
+
} else if (table[i + 1][j] > table[i][j + 1]) {
|
|
147
|
+
i++;
|
|
148
|
+
} else {
|
|
149
|
+
// On a tie, the result's rule is the one named as moved: the rule a
|
|
150
|
+
// swap brought earlier, such as one the old appending left behind a
|
|
151
|
+
// catch-all.
|
|
152
|
+
j++;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return shared;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Merge `recipe` into `live` against `last`, the recipe last applied (null
|
|
160
|
+
* when there is none), each as written. Pure: the caller reads and writes the
|
|
161
|
+
* files, and gives `meaningOf`, a rule's meaning as a string two rules share
|
|
162
|
+
* when they mean the same (as written, unless given). Returns the rule list
|
|
163
|
+
* and `default` to write, each as written, and whether `default` changed.
|
|
164
|
+
* Throws when `live` or `recipe` names a rule twice, since the merge keys
|
|
165
|
+
* rules by name.
|
|
166
|
+
*/
|
|
167
|
+
export function reconcileWithRecipe(
|
|
168
|
+
live: WrittenConfig,
|
|
169
|
+
recipe: WrittenConfig,
|
|
170
|
+
last: WrittenConfig | null,
|
|
171
|
+
meaningOf: (rule: unknown) => string = canonical,
|
|
172
|
+
): { rules: unknown[]; default: unknown; defaultChanged: boolean; changes: RecipeChanges } {
|
|
173
|
+
const agree = (a: unknown, b: unknown): boolean => meaningOf(a) === meaningOf(b);
|
|
174
|
+
const liveDuplicate = duplicateName(live.rules);
|
|
175
|
+
if (liveDuplicate !== undefined) {
|
|
176
|
+
throw new Error(`gate.json names the rule "${liveDuplicate}" twice`);
|
|
177
|
+
}
|
|
178
|
+
const recipeDuplicate = duplicateName(recipe.rules);
|
|
179
|
+
if (recipeDuplicate !== undefined) {
|
|
180
|
+
throw new Error(`the recipe names the rule "${recipeDuplicate}" twice`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const changes = noChanges();
|
|
184
|
+
// Each rule by its name; a rule with no name by a key no name can be, so
|
|
185
|
+
// it keeps its place and matches nothing.
|
|
186
|
+
const keyOf = (rule: unknown, index: number): string => ruleName(rule) ?? `\u0000nameless ${index}`;
|
|
187
|
+
const byName = (rules: readonly unknown[]) => new Map(rules.flatMap((rule) => {
|
|
188
|
+
const name = ruleName(rule);
|
|
189
|
+
return name === undefined ? [] : [[name, rule] as const];
|
|
190
|
+
}));
|
|
191
|
+
const inLive = new Map(live.rules.map((rule, index) => [keyOf(rule, index), rule] as const));
|
|
192
|
+
const inRecipe = byName(recipe.rules);
|
|
193
|
+
const inLast = last ? byName(last.rules) : null;
|
|
194
|
+
|
|
195
|
+
// Each rule gate.json keeps, with its definition, and which of them take
|
|
196
|
+
// the recipe's order (`ordered`); the rest keep their places.
|
|
197
|
+
const definitions = new Map<string, unknown>();
|
|
198
|
+
const ordered = new Set<string>();
|
|
199
|
+
live.rules.forEach((rule, index) => {
|
|
200
|
+
const name = keyOf(rule, index);
|
|
201
|
+
const declared = inRecipe.get(name);
|
|
202
|
+
const before = inLast?.get(name);
|
|
203
|
+
if (declared !== undefined && agree(rule, declared)) {
|
|
204
|
+
// As the recipe has it: kept as written, whatever the record says, and
|
|
205
|
+
// nothing to change or name.
|
|
206
|
+
definitions.set(name, rule);
|
|
207
|
+
ordered.add(name);
|
|
208
|
+
} else if (ruleName(rule) === undefined) {
|
|
209
|
+
definitions.set(name, rule);
|
|
210
|
+
} else if (!inLast) {
|
|
211
|
+
definitions.set(name, rule);
|
|
212
|
+
(declared !== undefined ? changes.differsFromRecipe : changes.outsideRecipe).push(name);
|
|
213
|
+
} else if (before !== undefined) {
|
|
214
|
+
const edited = !agree(rule, before);
|
|
215
|
+
if (declared === undefined) {
|
|
216
|
+
if (edited) {
|
|
217
|
+
definitions.set(name, rule);
|
|
218
|
+
changes.keptEdited.push(name);
|
|
219
|
+
} else {
|
|
220
|
+
changes.removed.push(name);
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
// Both recipes declare it: it's a recipe rule, so it takes the recipe's order.
|
|
224
|
+
ordered.add(name);
|
|
225
|
+
if (edited) {
|
|
226
|
+
definitions.set(name, rule);
|
|
227
|
+
if (!agree(declared, before)) changes.keptEdited.push(name);
|
|
228
|
+
} else {
|
|
229
|
+
definitions.set(name, declared);
|
|
230
|
+
changes.updated.push(name);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
} else {
|
|
234
|
+
// No recipe declared it as it stands: a run-time rule, or one the recipe
|
|
235
|
+
// now declares otherwise.
|
|
236
|
+
definitions.set(name, rule);
|
|
237
|
+
if (declared !== undefined) changes.differsFromRecipe.push(name);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const liveOrder = live.rules.map(keyOf);
|
|
242
|
+
const recipeOrder = recipe.rules.flatMap((rule) => {
|
|
243
|
+
const name = ruleName(rule);
|
|
244
|
+
return name === undefined ? [] : [name];
|
|
245
|
+
});
|
|
246
|
+
const staying = liveOrder.filter((name) => definitions.has(name));
|
|
247
|
+
|
|
248
|
+
// Whether gate.json holds the rules both recipes declare in the last recipe's order.
|
|
249
|
+
const shared = (order: string[]) => order.filter((name) => inLast?.has(name) && inRecipe.has(name) && inLive.has(name));
|
|
250
|
+
const lastOrder = last ? last.rules.flatMap((rule) => {
|
|
251
|
+
const name = ruleName(rule);
|
|
252
|
+
return name === undefined ? [] : [name];
|
|
253
|
+
}) : [];
|
|
254
|
+
const followsLast = canonical(shared(liveOrder)) === canonical(shared(lastOrder));
|
|
255
|
+
|
|
256
|
+
let order: string[];
|
|
257
|
+
if (followsLast) {
|
|
258
|
+
// The recipe's rules fill the places its rules hold, in the recipe's order.
|
|
259
|
+
const recipeRules = recipeOrder.filter((name) => ordered.has(name));
|
|
260
|
+
let next = 0;
|
|
261
|
+
order = staying.map((name) => (ordered.has(name) ? recipeRules[next++] : name));
|
|
262
|
+
} else {
|
|
263
|
+
order = staying;
|
|
264
|
+
// Named only when it holds something back: the recipe reordered these
|
|
265
|
+
// rules, and gate.json doesn't already hold the recipe's order.
|
|
266
|
+
changes.orderKept = canonical(shared(recipeOrder)) !== canonical(shared(lastOrder))
|
|
267
|
+
&& canonical(shared(liveOrder)) !== canonical(shared(recipeOrder));
|
|
268
|
+
}
|
|
269
|
+
// A recipe rule new to gate.json goes before the recipe rule that follows it
|
|
270
|
+
// there, or after the one before it when none follows.
|
|
271
|
+
recipeOrder.forEach((name, index) => {
|
|
272
|
+
if (inLive.has(name)) return;
|
|
273
|
+
definitions.set(name, inRecipe.get(name)!);
|
|
274
|
+
(inLast?.has(name) ? changes.restored : changes.added).push(name);
|
|
275
|
+
const following = recipeOrder.slice(index + 1).find((later) => order.includes(later));
|
|
276
|
+
if (following !== undefined) {
|
|
277
|
+
order.splice(order.indexOf(following), 0, name);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const preceding = recipeOrder.slice(0, index).reverse().find((earlier) => order.includes(earlier));
|
|
281
|
+
if (preceding !== undefined) order.splice(order.indexOf(preceding) + 1, 0, name);
|
|
282
|
+
else order.push(name);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Only the recipe's rules move; every other rule keeps its place.
|
|
286
|
+
const stayedInOrder = longestShared(staying.filter((name) => ordered.has(name)), order.filter((name) => ordered.has(name)));
|
|
287
|
+
changes.moved = order.filter((name) => ordered.has(name) && !stayedInOrder.has(name));
|
|
288
|
+
|
|
289
|
+
// `default` as the gate reads it, compared as written once read.
|
|
290
|
+
const liveDefault = behaviorOf(live.default);
|
|
291
|
+
const recipeDefault = behaviorOf(recipe.default);
|
|
292
|
+
let defaultBehavior = live.default;
|
|
293
|
+
let defaultChanged = false;
|
|
294
|
+
const shownBehavior = (value: unknown): string => (typeof value === 'string' ? value : JSON.stringify(value));
|
|
295
|
+
if (!last) {
|
|
296
|
+
if (!same(liveDefault, recipeDefault)) changes.defaultDiffers = { kept: shownBehavior(liveDefault), recipe: shownBehavior(recipeDefault) };
|
|
297
|
+
} else {
|
|
298
|
+
const lastDefault = behaviorOf(last.default);
|
|
299
|
+
if (same(liveDefault, lastDefault) || same(liveDefault, recipeDefault)) {
|
|
300
|
+
if (!same(recipeDefault, liveDefault)) {
|
|
301
|
+
defaultBehavior = recipe.default;
|
|
302
|
+
defaultChanged = true;
|
|
303
|
+
changes.defaultChange = { from: shownBehavior(liveDefault), to: shownBehavior(recipeDefault) };
|
|
304
|
+
}
|
|
305
|
+
} else if (!same(recipeDefault, lastDefault)) {
|
|
306
|
+
changes.defaultKept = shownBehavior(liveDefault);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
rules: order.map((name) => definitions.get(name)),
|
|
312
|
+
default: defaultBehavior,
|
|
313
|
+
defaultChanged,
|
|
314
|
+
changes,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/** The log line a start gives its changes, or null when it changed nothing worth saying. */
|
|
319
|
+
export function reconcileLine(changes: RecipeChanges): string | null {
|
|
320
|
+
const parts: string[] = [];
|
|
321
|
+
if (changes.recordUnreadable !== undefined) {
|
|
322
|
+
parts.push(`the recorded recipe couldn't be read (${changes.recordUnreadable}), so this start removed and redefined nothing`);
|
|
323
|
+
}
|
|
324
|
+
const list = (label: string, names: string[]) => {
|
|
325
|
+
if (names.length > 0) parts.push(`${label} ${names.join(', ')}`);
|
|
326
|
+
};
|
|
327
|
+
list('added', changes.added);
|
|
328
|
+
list('removed', changes.removed);
|
|
329
|
+
list('updated', changes.updated);
|
|
330
|
+
list('restored', changes.restored);
|
|
331
|
+
list('moved', changes.moved);
|
|
332
|
+
list('kept as edited, though the recipe changed or dropped it:', changes.keptEdited);
|
|
333
|
+
if (changes.differsFromRecipe.length > 0) {
|
|
334
|
+
parts.push(
|
|
335
|
+
`kept, though the recipe defines it otherwise: ${changes.differsFromRecipe.join(', ')} `
|
|
336
|
+
+ '(remove such a rule, and the next start restores it from the recipe)',
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
if (changes.outsideRecipe.length > 0) {
|
|
340
|
+
parts.push(
|
|
341
|
+
`kept, not in the recipe: ${changes.outsideRecipe.join(', ')} `
|
|
342
|
+
+ "(a stale one can be removed, and no start brings it back)",
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
if (changes.defaultChange) parts.push(`default ${changes.defaultChange.from} → ${changes.defaultChange.to}`);
|
|
346
|
+
if (changes.defaultKept) parts.push(`default kept as edited (${changes.defaultKept}), though the recipe changed it`);
|
|
347
|
+
if (changes.defaultDiffers) {
|
|
348
|
+
parts.push(
|
|
349
|
+
`default kept as gate.json has it (${changes.defaultDiffers.kept}), though the recipe's is ${changes.defaultDiffers.recipe} `
|
|
350
|
+
+ "(set it to the recipe's, and later starts follow the recipe)",
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
if (changes.orderKept) parts.push("gate.json's order kept, though the recipe reordered its rules, since a recipe rule was moved in it");
|
|
354
|
+
return parts.length > 0 ? `[gate] the recipe was applied to gate.json: ${parts.join('; ')}` : null;
|
|
355
|
+
}
|
package/src/gate/types.ts
CHANGED
|
@@ -17,9 +17,10 @@
|
|
|
17
17
|
* bucket are denied (decision: trigger=false). Tokens regenerate at one per
|
|
18
18
|
* `refillIntervalMs`, capped at `tokens`. Buckets are partitioned by the
|
|
19
19
|
* value of `keyBy` resolved against event metadata — so a per-user limit
|
|
20
|
-
* uses `keyBy: "senderId"`, a per-channel limit uses `keyBy: "channelId"
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* uses `keyBy: "senderId"`, a per-channel limit uses `keyBy: "channelId"`
|
|
21
|
+
* (resolved to the channel's registered id, as `keyBy` says), etc. With no
|
|
22
|
+
* `keyBy` (or when the resolved value is missing), one shared bucket is used
|
|
23
|
+
* for the policy.
|
|
23
24
|
*/
|
|
24
25
|
export interface RateLimitConfig {
|
|
25
26
|
/** Max bucket capacity, also the initial fill. Must be > 0. */
|
|
@@ -27,8 +28,12 @@ export interface RateLimitConfig {
|
|
|
27
28
|
/** Milliseconds between token regenerations. Must be > 0. */
|
|
28
29
|
refillIntervalMs: number;
|
|
29
30
|
/**
|
|
30
|
-
* Metadata field name to partition buckets by.
|
|
31
|
-
*
|
|
31
|
+
* Metadata field name to partition buckets by. `"channelId"` takes the
|
|
32
|
+
* channel's registered id where the gate resolves one, as `match.channel`
|
|
33
|
+
* does, so a channel's push events share its messages' bucket, a voice
|
|
34
|
+
* report's included, though it carries no `channelId`. Otherwise, if
|
|
35
|
+
* absent or the metadata field is missing on a given event, all such
|
|
36
|
+
* events share one bucket.
|
|
32
37
|
*/
|
|
33
38
|
keyBy?: string;
|
|
34
39
|
}
|
|
@@ -45,7 +50,8 @@ export interface RateLimitConfig {
|
|
|
45
50
|
export interface PassiveSampleConfig {
|
|
46
51
|
/** Trigger every N-th match. Must be > 0. */
|
|
47
52
|
every: number;
|
|
48
|
-
/** Optional metadata field name for separate per-key counters
|
|
53
|
+
/** Optional metadata field name for separate per-key counters, resolved
|
|
54
|
+
* as `RateLimitConfig.keyBy` is. */
|
|
49
55
|
keyBy?: string;
|
|
50
56
|
}
|
|
51
57
|
|
|
@@ -68,7 +74,12 @@ export interface GatePolicyMatch {
|
|
|
68
74
|
scope?: string[];
|
|
69
75
|
/** ServerId to match (exact or glob with *). */
|
|
70
76
|
source?: string;
|
|
71
|
-
/**
|
|
77
|
+
/** Channel to match (exact or glob with *): against the event's channel
|
|
78
|
+
* id, then the registered id the gate resolves for it
|
|
79
|
+
* (`resolveRouteChannel`). A channels/incoming message carries the
|
|
80
|
+
* registered id (`discord:<guild>:<channel>`), and a push the adapter's
|
|
81
|
+
* raw one or none, so a registered-form pattern meets every event in its
|
|
82
|
+
* channel whose push names the channel, and a raw id only push events. */
|
|
72
83
|
channel?: string;
|
|
73
84
|
/** Content text filter. */
|
|
74
85
|
filter?: { type: 'text' | 'regex'; pattern: string };
|
|
@@ -155,7 +166,17 @@ export interface GateConfig {
|
|
|
155
166
|
export interface GateOptions {
|
|
156
167
|
/** Path to gate.json. Default: derived from storePath. */
|
|
157
168
|
configPath?: string;
|
|
158
|
-
/**
|
|
169
|
+
/**
|
|
170
|
+
* The recipe's gate config. The first start seeds gate.json with it. Each
|
|
171
|
+
* later start merges it into gate.json against the recipe last applied,
|
|
172
|
+
* which the gate keeps beside gate.json (`gate.recipe.json`): a rule the
|
|
173
|
+
* recipe dropped, renamed, moved or redefined follows it, a rule edited at
|
|
174
|
+
* run time or by hand stays, and so does one no recipe declared. Rules are
|
|
175
|
+
* merged by name, compared by what they mean and kept as written: a
|
|
176
|
+
* recipe's rule with no name is never merged, as one with no name was never
|
|
177
|
+
* added, and where gate.json or the recipe names a rule twice, a start only
|
|
178
|
+
* adds the rules gate.json lacks. See `recipe-reconcile.ts`.
|
|
179
|
+
*/
|
|
159
180
|
config?: GateConfig;
|
|
160
181
|
/**
|
|
161
182
|
* Path to a JSON file listing user ids that may wake the agent even while
|
|
@@ -231,6 +252,47 @@ export interface GateEventInfo {
|
|
|
231
252
|
tags?: string[];
|
|
232
253
|
}
|
|
233
254
|
|
|
255
|
+
/** An MCPL event whose content the framework stored at arrival, as a
|
|
256
|
+
* batched wake names it to the framework (EventGate's `isNewestEntry`):
|
|
257
|
+
* a channel message by its server, channel and message id, a push event by
|
|
258
|
+
* its server and event id. */
|
|
259
|
+
export interface GateEntryRef {
|
|
260
|
+
eventType: string;
|
|
261
|
+
serverId?: string;
|
|
262
|
+
channelId?: string;
|
|
263
|
+
messageId?: string;
|
|
264
|
+
eventId?: string;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** A batched wake's `[Gate: …]` line that the gate handed to the wake rather
|
|
268
|
+
* than wrote: its batch was one event whose entry was still the newest in
|
|
269
|
+
* the window when the batch fired (EventGate's `isNewestEntry`). A fresh
|
|
270
|
+
* start of the wake's turn decides it (the framework's placeWakeLines): the
|
|
271
|
+
* delivery agent's own start leaves it out while that entry is still the
|
|
272
|
+
* newest, and writes it once something follows; a co-resident's start
|
|
273
|
+
* places none; two or more such lines are each written;
|
|
274
|
+
* and none is written while the host is quiesced or another reader of the
|
|
275
|
+
* residents' shared slot has a turn alive. A line left out stays for a
|
|
276
|
+
* later fresh start of the same wake. Its text is rendered when it's
|
|
277
|
+
* written (wakeLineText), so its age is true then.
|
|
278
|
+
*
|
|
279
|
+
* Every request for one wake carries the same object: the framework writes
|
|
280
|
+
* each line once by its identity, across the wake's retries and holds. A
|
|
281
|
+
* host that hands the gate's requests on itself passes the line on as it
|
|
282
|
+
* is, not a copy per agent. */
|
|
283
|
+
export interface WakeLine {
|
|
284
|
+
/** The event's own entry. */
|
|
285
|
+
entry: GateEntryRef;
|
|
286
|
+
policyNames: string[];
|
|
287
|
+
/** The channel as the line names it to the agent. */
|
|
288
|
+
shown: string;
|
|
289
|
+
/** When the event arrived (ms): the line's age is counted from it to when
|
|
290
|
+
* the line is written (wakeLineText). */
|
|
291
|
+
at: number;
|
|
292
|
+
/** The channel the line names, as the omission's trace reports it. */
|
|
293
|
+
channelId?: string;
|
|
294
|
+
}
|
|
295
|
+
|
|
234
296
|
/** Per-policy runtime statistics (for gate:status). */
|
|
235
297
|
export interface GatePolicyStats {
|
|
236
298
|
name: string;
|
package/src/index.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
export * from './types/index.js';
|
|
3
3
|
|
|
4
4
|
// Core classes
|
|
5
|
-
export { AgentFramework, BudgetPreflightError, ProviderWaitNotSleptError, QuiesceBlockedError, ResumeBlockedError } from './framework.js';
|
|
5
|
+
export { AgentFramework, BudgetPreflightError, DefaultErrorPolicy, ProviderWaitNotSleptError, QuiesceBlockedError, ResumeBlockedError } from './framework.js';
|
|
6
6
|
export type { RuntimeSettingsPreview, HostModeStatus } from './framework.js';
|
|
7
7
|
export { Agent } from './agent.js';
|
|
8
|
+
export { storedInjectionMarkOf, type StoredInjectionMark } from './stored-injections.js';
|
|
8
9
|
export type { StartStreamResult } from './agent.js';
|
|
9
10
|
export { ProcessQueueImpl } from './queue.js';
|
|
10
11
|
export { ModuleRegistry } from './module-registry.js';
|
|
@@ -67,12 +68,12 @@ export { buildCodeExecutionToolDefinition, CODE_EXECUTION_TOOL_NAME } from './co
|
|
|
67
68
|
export type { SessionUsage, AgentUsage, SessionUsageSnapshot, UsageUpdatedEvent } from './usage/index.js';
|
|
68
69
|
|
|
69
70
|
// EventGate
|
|
70
|
-
export { EventGate, type WakeProvenance } from './gate/index.js';
|
|
71
|
-
export type { GateConfig, GateOptions, GatePolicy, GatePolicyMatch, GateBehavior } from './gate/index.js';
|
|
71
|
+
export { EventGate, wakeLineText, type WakeProvenance, type WritePlacement } from './gate/index.js';
|
|
72
|
+
export type { GateConfig, GateOptions, GatePolicy, GatePolicyMatch, GateBehavior, WakeLine } from './gate/index.js';
|
|
72
73
|
|
|
73
74
|
// MCPL channel registry (exposed for modules that need channel-level operations)
|
|
74
75
|
export { ChannelRegistry } from './mcpl/index.js';
|
|
75
|
-
export type { PublishRefusalReason } from './mcpl/index.js';
|
|
76
|
+
export type { ChannelRef, PublishRefusalReason } from './mcpl/index.js';
|
|
76
77
|
|
|
77
78
|
// Where each accepted inbound item came from (`metadata.inboundSource`), and
|
|
78
79
|
// the digest its delivered and stored bodies are stamped with
|
|
@@ -95,6 +96,8 @@ export type { McplServerConfig } from './mcpl/index.js';
|
|
|
95
96
|
// exactly the way the framework host does: MCPL over stdio or WebSocket, and
|
|
96
97
|
// modern MCP over stdio or Streamable HTTP)
|
|
97
98
|
export { McplServerConnection, McplRequestError, McplProtocolVersionError, McplUnreapedLaunchError } from './mcpl/index.js';
|
|
99
|
+
// RFC-014: the meta-tools' module and its names.
|
|
100
|
+
export { ToolsetsModule, TOOLSETS_MODULE, META_TOOL_NAMES } from './mcpl/index.js';
|
|
98
101
|
export { ModernMcpConnection } from './mcpl/index.js';
|
|
99
102
|
export type { ModernToolCallResult } from './mcpl/index.js';
|
|
100
103
|
export {
|