@graphorin/agent 0.5.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +159 -0
  4. package/dist/errors/index.d.ts +170 -0
  5. package/dist/errors/index.d.ts.map +1 -0
  6. package/dist/errors/index.js +204 -0
  7. package/dist/errors/index.js.map +1 -0
  8. package/dist/evaluator-optimizer/index.d.ts +91 -0
  9. package/dist/evaluator-optimizer/index.d.ts.map +1 -0
  10. package/dist/evaluator-optimizer/index.js +85 -0
  11. package/dist/evaluator-optimizer/index.js.map +1 -0
  12. package/dist/factory.d.ts +13 -0
  13. package/dist/factory.d.ts.map +1 -0
  14. package/dist/factory.js +1853 -0
  15. package/dist/factory.js.map +1 -0
  16. package/dist/fallback/index.d.ts +52 -0
  17. package/dist/fallback/index.d.ts.map +1 -0
  18. package/dist/fallback/index.js +53 -0
  19. package/dist/fallback/index.js.map +1 -0
  20. package/dist/fanout/index.d.ts +142 -0
  21. package/dist/fanout/index.d.ts.map +1 -0
  22. package/dist/fanout/index.js +252 -0
  23. package/dist/fanout/index.js.map +1 -0
  24. package/dist/filters/index.d.ts +137 -0
  25. package/dist/filters/index.d.ts.map +1 -0
  26. package/dist/filters/index.js +273 -0
  27. package/dist/filters/index.js.map +1 -0
  28. package/dist/index.d.ts +51 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +49 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/internal/ids.js +46 -0
  33. package/dist/internal/ids.js.map +1 -0
  34. package/dist/internal/usage-accumulator.js +62 -0
  35. package/dist/internal/usage-accumulator.js.map +1 -0
  36. package/dist/lateral-leak/causality-monitor.d.ts +97 -0
  37. package/dist/lateral-leak/causality-monitor.d.ts.map +1 -0
  38. package/dist/lateral-leak/causality-monitor.js +139 -0
  39. package/dist/lateral-leak/causality-monitor.js.map +1 -0
  40. package/dist/lateral-leak/index.d.ts +4 -0
  41. package/dist/lateral-leak/index.js +5 -0
  42. package/dist/lateral-leak/merge-guard.d.ts +89 -0
  43. package/dist/lateral-leak/merge-guard.d.ts.map +1 -0
  44. package/dist/lateral-leak/merge-guard.js +65 -0
  45. package/dist/lateral-leak/merge-guard.js.map +1 -0
  46. package/dist/lateral-leak/protocol-guard.d.ts +76 -0
  47. package/dist/lateral-leak/protocol-guard.d.ts.map +1 -0
  48. package/dist/lateral-leak/protocol-guard.js +147 -0
  49. package/dist/lateral-leak/protocol-guard.js.map +1 -0
  50. package/dist/preferred-model/index.d.ts +53 -0
  51. package/dist/preferred-model/index.d.ts.map +1 -0
  52. package/dist/preferred-model/index.js +141 -0
  53. package/dist/preferred-model/index.js.map +1 -0
  54. package/dist/progress/index.d.ts +62 -0
  55. package/dist/progress/index.d.ts.map +1 -0
  56. package/dist/progress/index.js +150 -0
  57. package/dist/progress/index.js.map +1 -0
  58. package/dist/run-state/index.d.ts +152 -0
  59. package/dist/run-state/index.d.ts.map +1 -0
  60. package/dist/run-state/index.js +311 -0
  61. package/dist/run-state/index.js.map +1 -0
  62. package/dist/tooling/adapters.js +154 -0
  63. package/dist/tooling/adapters.js.map +1 -0
  64. package/dist/tooling/catalogue.js +37 -0
  65. package/dist/tooling/catalogue.js.map +1 -0
  66. package/dist/tooling/dataflow.js +99 -0
  67. package/dist/tooling/dataflow.js.map +1 -0
  68. package/dist/tooling/registry-build.js +85 -0
  69. package/dist/tooling/registry-build.js.map +1 -0
  70. package/dist/types.d.ts +413 -0
  71. package/dist/types.d.ts.map +1 -0
  72. package/package.json +115 -0
@@ -0,0 +1,273 @@
1
+ import "@graphorin/core";
2
+
3
+ //#region src/filters/index.ts
4
+ const SENSITIVITY_RANK = {
5
+ public: 0,
6
+ internal: 1,
7
+ secret: 2
8
+ };
9
+ /**
10
+ * Return `true` iff the message's effective sensitivity is at most
11
+ * `maxTier` (a strictly weaker check than core's
12
+ * `acceptsSensitivity` because the filter library does not have
13
+ * the provider's `acceptsSensitivity[]` array — only a ceiling).
14
+ */
15
+ function withinTier(record, maxTier) {
16
+ return SENSITIVITY_RANK[record] <= SENSITIVITY_RANK[maxTier];
17
+ }
18
+ function makeFilter(fn, descriptor) {
19
+ const wrapped = ((history) => fn(history));
20
+ Object.defineProperty(wrapped, "descriptor", {
21
+ value: descriptor,
22
+ enumerable: true
23
+ });
24
+ return wrapped;
25
+ }
26
+ function isReasoningPart(part) {
27
+ if (typeof part !== "object" || part === null) return false;
28
+ return part.type === "reasoning";
29
+ }
30
+ function stripReasoningFromMessage(msg) {
31
+ if (msg.role === "system" || msg.role === "tool") return msg;
32
+ const content = msg.content;
33
+ if (typeof content === "string") return msg;
34
+ const filtered = content.filter((part) => !isReasoningPart(part));
35
+ if (filtered.length === content.length) return msg;
36
+ if (msg.role === "assistant") return {
37
+ ...msg,
38
+ content: filtered
39
+ };
40
+ return {
41
+ ...msg,
42
+ content: filtered
43
+ };
44
+ }
45
+ /**
46
+ * Keep the parent's system prompt and the last `n` non-system
47
+ * messages. Default `n = 10` per DEC-146 / RB-40 security-first
48
+ * compose.
49
+ *
50
+ * @stable
51
+ */
52
+ function lastN(n = 10) {
53
+ if (!Number.isFinite(n) || n <= 0) throw new RangeError(`filters.lastN: n must be a positive integer (got ${String(n)})`);
54
+ return makeFilter((history) => {
55
+ const out = [];
56
+ for (const msg of history) if (msg.role === "system") out.push(msg);
57
+ const nonSystem = history.filter((m) => m.role !== "system");
58
+ const tail = nonSystem.slice(Math.max(0, nonSystem.length - n));
59
+ return [...out, ...tail];
60
+ }, {
61
+ kind: "last-n",
62
+ meta: { n }
63
+ });
64
+ }
65
+ /**
66
+ * Keep only the parent's system prompt and the most recent user
67
+ * message. Useful for simple sub-agents that only need the question.
68
+ *
69
+ * @stable
70
+ */
71
+ function lastUser() {
72
+ return makeFilter((history) => {
73
+ const out = [];
74
+ let lastUserIdx = -1;
75
+ for (let i = history.length - 1; i >= 0; i--) {
76
+ const msg = history[i];
77
+ if (msg && msg.role === "user") {
78
+ lastUserIdx = i;
79
+ break;
80
+ }
81
+ }
82
+ for (const msg of history) if (msg.role === "system") out.push(msg);
83
+ if (lastUserIdx >= 0) {
84
+ const m = history[lastUserIdx];
85
+ if (m) out.push(m);
86
+ }
87
+ return out;
88
+ }, { kind: "last-user" });
89
+ }
90
+ /**
91
+ * The full unfiltered history. Discouraged — security-conscious
92
+ * callers should pick {@link lastN} or {@link bySensitivity} instead
93
+ * (a sub-agent rarely needs the parent's entire conversation).
94
+ *
95
+ * @stable
96
+ */
97
+ function full() {
98
+ return makeFilter((history) => history.slice(), { kind: "full" });
99
+ }
100
+ /**
101
+ * Replace the parent's history with a single system message carrying
102
+ * the supplied summary. Used by callers that wire in an LLM-based
103
+ * summarizer outside the framework.
104
+ *
105
+ * @stable
106
+ */
107
+ function summary(text) {
108
+ return makeFilter(() => [{
109
+ role: "system",
110
+ content: `[Summary of parent conversation]\n${text}`
111
+ }], {
112
+ kind: "summary",
113
+ meta: { summaryLength: text.length }
114
+ });
115
+ }
116
+ /**
117
+ * Drop messages whose effective sensitivity ceiling exceeds
118
+ * `maxTier`. Messages without sensitivity metadata default to
119
+ * `'public'` and are always kept.
120
+ *
121
+ * The framework currently records sensitivity at the
122
+ * `MessageContent` part level via the `inboundTrust` / `secret`
123
+ * annotations. v0.1 ships a coarse-grained heuristic: a message is
124
+ * kept iff every text part's content does not contain the literal
125
+ * `[REDACTED:secret]` token AND every part's annotated sensitivity
126
+ * is acceptable to `maxTier`. Operators that need a stricter
127
+ * filter compose the function with `stripSensitiveOutputs()` or a
128
+ * custom predicate.
129
+ *
130
+ * @stable
131
+ */
132
+ function bySensitivity(args = {}) {
133
+ const maxTier = args.maxTier ?? "public";
134
+ return makeFilter((history) => {
135
+ const out = [];
136
+ for (const msg of history) {
137
+ const content = msg.role === "system" ? msg.content : msg.content;
138
+ if ((typeof content === "string" ? content : JSON.stringify(content)).includes("[REDACTED:secret]") && !withinTier("secret", maxTier)) continue;
139
+ out.push(msg);
140
+ }
141
+ return out;
142
+ }, {
143
+ kind: "sensitivity-filter",
144
+ meta: { maxTier }
145
+ });
146
+ }
147
+ /**
148
+ * Strip every `ReasoningContent` part from each message. Always
149
+ * applied at the handoff boundary (the `compose(...)` helper appends
150
+ * this filter automatically).
151
+ *
152
+ * @stable
153
+ */
154
+ function stripReasoning() {
155
+ return makeFilter((history) => history.map(stripReasoningFromMessage), { kind: "strip-reasoning" });
156
+ }
157
+ /**
158
+ * Strip tool messages whose `content` carries the literal token
159
+ * `[REDACTED:secret]` or whose `secret` annotation marks the body as
160
+ * sensitive. Conservative-by-design: the agent runtime tags
161
+ * sensitive tool outputs at session-write time so this filter has
162
+ * stable bytes to scan against.
163
+ *
164
+ * @stable
165
+ */
166
+ function stripSensitiveOutputs() {
167
+ return makeFilter((history) => {
168
+ const out = [];
169
+ let stripped = 0;
170
+ for (const msg of history) {
171
+ if (msg.role === "tool") {
172
+ if ((typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)).includes("[REDACTED:")) {
173
+ stripped += 1;
174
+ continue;
175
+ }
176
+ }
177
+ out.push(msg);
178
+ }
179
+ return out;
180
+ }, { kind: "strip-sensitive-outputs" });
181
+ }
182
+ /**
183
+ * Drop every assistant `toolCalls` array AND every `tool` message.
184
+ * Useful when a sub-agent should only see the textual conversation.
185
+ *
186
+ * @stable
187
+ */
188
+ function stripToolCalls() {
189
+ return makeFilter((history) => {
190
+ const out = [];
191
+ for (const msg of history) {
192
+ if (msg.role === "tool") continue;
193
+ if (msg.role === "assistant" && msg.toolCalls && msg.toolCalls.length > 0) {
194
+ const { toolCalls: _toolCalls, ...rest } = msg;
195
+ out.push(rest);
196
+ continue;
197
+ }
198
+ out.push(msg);
199
+ }
200
+ return out;
201
+ }, { kind: "strip-tool-calls" });
202
+ }
203
+ /**
204
+ * Compose multiple filters left-to-right. The composer **always**
205
+ * appends `stripReasoning()` at the end so reasoning content never
206
+ * crosses a handoff boundary regardless of caller intent.
207
+ *
208
+ * @stable
209
+ */
210
+ function compose(...filters$1) {
211
+ const stripper = stripReasoning();
212
+ const ordered = [...filters$1, stripper];
213
+ const descriptors = filters$1.map((f) => {
214
+ return f.descriptor ?? { kind: "custom" };
215
+ });
216
+ descriptors.push(stripper.descriptor);
217
+ return makeFilter((history) => {
218
+ let current = history;
219
+ for (const filter of ordered) current = filter(current);
220
+ return current;
221
+ }, {
222
+ kind: "compose",
223
+ meta: { steps: descriptors }
224
+ });
225
+ }
226
+ /**
227
+ * Wrap a caller-supplied function as a {@link DescribedFilter} with
228
+ * the canonical `'custom'` descriptor.
229
+ *
230
+ * @stable
231
+ */
232
+ function custom(fn, meta) {
233
+ return makeFilter(fn, meta !== void 0 ? {
234
+ kind: "custom",
235
+ meta
236
+ } : { kind: "custom" });
237
+ }
238
+ /**
239
+ * The canonical default applied by the agent runtime to every
240
+ * `Agent.toTool(...)` and `handoff(...)` invocation when the caller
241
+ * does not supply an explicit filter.
242
+ *
243
+ * @stable
244
+ */
245
+ function defaultHandoffFilter() {
246
+ return compose(lastN(10), stripSensitiveOutputs());
247
+ }
248
+ /**
249
+ * Pure `HandoffInputFilterDescriptor` for callers that just need the
250
+ * descriptor without instantiating the runtime function (e.g. the
251
+ * sessions package's lenient-forward-parse path).
252
+ *
253
+ * @stable
254
+ */
255
+ const FILTER_KIND_CUSTOM = { kind: "custom" };
256
+ /** Aggregate module export. */
257
+ const filters = {
258
+ lastN,
259
+ lastUser,
260
+ full,
261
+ summary,
262
+ bySensitivity,
263
+ stripReasoning,
264
+ stripSensitiveOutputs,
265
+ stripToolCalls,
266
+ compose,
267
+ custom,
268
+ defaultHandoffFilter
269
+ };
270
+
271
+ //#endregion
272
+ export { FILTER_KIND_CUSTOM, bySensitivity, compose, custom, defaultHandoffFilter, filters, full, lastN, lastUser, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary };
273
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["SENSITIVITY_RANK: Record<Sensitivity, number>","out: Message[]","nonSystem: Message[]","maxTier: Sensitivity","filters","ordered: ReadonlyArray<HandoffFilter>","descriptors: HandoffInputFilterDescriptor[]","current: readonly Message[]","FILTER_KIND_CUSTOM: HandoffInputFilterDescriptor"],"sources":["../../src/filters/index.ts"],"sourcesContent":["/**\n * Handoff filter library — a small set of pure, composable functions\n * that take the parent agent's message history and return a filtered\n * subset suitable for forwarding to a child agent.\n *\n * Every filter pairs a `HandoffFilter` runtime function with a\n * serializable {@link HandoffInputFilterDescriptor} so the JSONL\n * session export (`@graphorin/sessions`) can replay the filter stack\n * even after the runtime implementations evolve.\n *\n * Reasoning content is **always** stripped at the handoff boundary —\n * `filters.compose(...)` guarantees `stripReasoning()` runs last so a\n * caller-supplied filter cannot accidentally forward reasoning to a\n * child agent. This is the confidentiality + token-economy default\n * documented in the agent-loop reference.\n *\n * @packageDocumentation\n */\n\nimport type {\n HandoffFilter,\n HandoffInputFilterDescriptor,\n Message,\n Sensitivity,\n} from '@graphorin/core';\nimport { SENSITIVITY_ORDER } from '@graphorin/core';\n\nconst SENSITIVITY_RANK: Record<Sensitivity, number> = {\n public: 0,\n internal: 1,\n secret: 2,\n};\n\n/**\n * Return `true` iff the message's effective sensitivity is at most\n * `maxTier` (a strictly weaker check than core's\n * `acceptsSensitivity` because the filter library does not have\n * the provider's `acceptsSensitivity[]` array — only a ceiling).\n */\nfunction withinTier(record: Sensitivity, maxTier: Sensitivity): boolean {\n return SENSITIVITY_RANK[record] <= SENSITIVITY_RANK[maxTier];\n}\n\nvoid SENSITIVITY_ORDER;\n\n/**\n * A `HandoffFilter` paired with the serializable descriptor that\n * round-trips through the JSONL session export. Authors of custom\n * filters return one of these via `filters.custom({...})`.\n *\n * @stable\n */\nexport interface DescribedFilter extends HandoffFilter {\n readonly descriptor: HandoffInputFilterDescriptor;\n}\n\nfunction makeFilter(fn: HandoffFilter, descriptor: HandoffInputFilterDescriptor): DescribedFilter {\n const wrapped = ((history: readonly Message[]): readonly Message[] =>\n fn(history)) as DescribedFilter;\n Object.defineProperty(wrapped, 'descriptor', { value: descriptor, enumerable: true });\n return wrapped;\n}\n\nfunction isReasoningPart(part: unknown): boolean {\n if (typeof part !== 'object' || part === null) return false;\n const t = (part as { readonly type?: unknown }).type;\n return t === 'reasoning';\n}\n\nfunction stripReasoningFromMessage(msg: Message): Message {\n if (msg.role === 'system' || msg.role === 'tool') return msg;\n const content = msg.content;\n if (typeof content === 'string') return msg;\n const filtered = content.filter((part) => !isReasoningPart(part));\n if (filtered.length === content.length) return msg;\n if (msg.role === 'assistant') {\n return { ...msg, content: filtered };\n }\n return { ...msg, content: filtered };\n}\n\n/**\n * Keep the parent's system prompt and the last `n` non-system\n * messages. Default `n = 10` per DEC-146 / RB-40 security-first\n * compose.\n *\n * @stable\n */\nexport function lastN(n = 10): DescribedFilter {\n if (!Number.isFinite(n) || n <= 0) {\n throw new RangeError(`filters.lastN: n must be a positive integer (got ${String(n)})`);\n }\n return makeFilter(\n (history) => {\n const out: Message[] = [];\n for (const msg of history) {\n if (msg.role === 'system') {\n out.push(msg);\n }\n }\n const nonSystem: Message[] = history.filter((m) => m.role !== 'system');\n const tail = nonSystem.slice(Math.max(0, nonSystem.length - n));\n return [...out, ...tail];\n },\n { kind: 'last-n', meta: { n } },\n );\n}\n\n/**\n * Keep only the parent's system prompt and the most recent user\n * message. Useful for simple sub-agents that only need the question.\n *\n * @stable\n */\nexport function lastUser(): DescribedFilter {\n return makeFilter(\n (history) => {\n const out: Message[] = [];\n let lastUserIdx = -1;\n for (let i = history.length - 1; i >= 0; i--) {\n const msg = history[i];\n if (msg && msg.role === 'user') {\n lastUserIdx = i;\n break;\n }\n }\n for (const msg of history) {\n if (msg.role === 'system') out.push(msg);\n }\n if (lastUserIdx >= 0) {\n const m = history[lastUserIdx];\n if (m) out.push(m);\n }\n return out;\n },\n { kind: 'last-user' },\n );\n}\n\n/**\n * The full unfiltered history. Discouraged — security-conscious\n * callers should pick {@link lastN} or {@link bySensitivity} instead\n * (a sub-agent rarely needs the parent's entire conversation).\n *\n * @stable\n */\nexport function full(): DescribedFilter {\n return makeFilter((history) => history.slice(), { kind: 'full' });\n}\n\n/**\n * Replace the parent's history with a single system message carrying\n * the supplied summary. Used by callers that wire in an LLM-based\n * summarizer outside the framework.\n *\n * @stable\n */\nexport function summary(text: string): DescribedFilter {\n return makeFilter(\n () => [\n {\n role: 'system',\n content: `[Summary of parent conversation]\\n${text}`,\n },\n ],\n { kind: 'summary', meta: { summaryLength: text.length } },\n );\n}\n\n/**\n * Drop messages whose effective sensitivity ceiling exceeds\n * `maxTier`. Messages without sensitivity metadata default to\n * `'public'` and are always kept.\n *\n * The framework currently records sensitivity at the\n * `MessageContent` part level via the `inboundTrust` / `secret`\n * annotations. v0.1 ships a coarse-grained heuristic: a message is\n * kept iff every text part's content does not contain the literal\n * `[REDACTED:secret]` token AND every part's annotated sensitivity\n * is acceptable to `maxTier`. Operators that need a stricter\n * filter compose the function with `stripSensitiveOutputs()` or a\n * custom predicate.\n *\n * @stable\n */\nexport function bySensitivity(args: { readonly maxTier?: Sensitivity } = {}): DescribedFilter {\n const maxTier: Sensitivity = args.maxTier ?? 'public';\n return makeFilter(\n (history) => {\n const out: Message[] = [];\n for (const msg of history) {\n const content = msg.role === 'system' ? msg.content : msg.content;\n const text = typeof content === 'string' ? content : JSON.stringify(content);\n if (text.includes('[REDACTED:secret]') && !withinTier('secret', maxTier)) {\n continue;\n }\n out.push(msg);\n }\n return out;\n },\n { kind: 'sensitivity-filter', meta: { maxTier } },\n );\n}\n\n/**\n * Strip every `ReasoningContent` part from each message. Always\n * applied at the handoff boundary (the `compose(...)` helper appends\n * this filter automatically).\n *\n * @stable\n */\nexport function stripReasoning(): DescribedFilter {\n return makeFilter((history) => history.map(stripReasoningFromMessage), {\n kind: 'strip-reasoning',\n });\n}\n\n/**\n * Strip tool messages whose `content` carries the literal token\n * `[REDACTED:secret]` or whose `secret` annotation marks the body as\n * sensitive. Conservative-by-design: the agent runtime tags\n * sensitive tool outputs at session-write time so this filter has\n * stable bytes to scan against.\n *\n * @stable\n */\nexport function stripSensitiveOutputs(): DescribedFilter {\n return makeFilter(\n (history) => {\n const out: Message[] = [];\n let stripped = 0;\n for (const msg of history) {\n if (msg.role === 'tool') {\n const text = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);\n if (text.includes('[REDACTED:')) {\n stripped += 1;\n continue;\n }\n }\n out.push(msg);\n }\n void stripped;\n return out;\n },\n { kind: 'strip-sensitive-outputs' },\n );\n}\n\n/**\n * Drop every assistant `toolCalls` array AND every `tool` message.\n * Useful when a sub-agent should only see the textual conversation.\n *\n * @stable\n */\nexport function stripToolCalls(): DescribedFilter {\n return makeFilter(\n (history) => {\n const out: Message[] = [];\n for (const msg of history) {\n if (msg.role === 'tool') continue;\n if (msg.role === 'assistant' && msg.toolCalls && msg.toolCalls.length > 0) {\n const { toolCalls: _toolCalls, ...rest } = msg;\n out.push(rest);\n continue;\n }\n out.push(msg);\n }\n return out;\n },\n { kind: 'strip-tool-calls' },\n );\n}\n\n/**\n * Compose multiple filters left-to-right. The composer **always**\n * appends `stripReasoning()` at the end so reasoning content never\n * crosses a handoff boundary regardless of caller intent.\n *\n * @stable\n */\nexport function compose(...filters: ReadonlyArray<HandoffFilter>): DescribedFilter {\n const stripper = stripReasoning();\n const ordered: ReadonlyArray<HandoffFilter> = [...filters, stripper];\n const descriptors: HandoffInputFilterDescriptor[] = filters.map((f) => {\n const desc = (f as DescribedFilter).descriptor;\n return desc ?? { kind: 'custom' };\n });\n descriptors.push(stripper.descriptor);\n return makeFilter(\n (history) => {\n let current: readonly Message[] = history;\n for (const filter of ordered) {\n current = filter(current);\n }\n return current;\n },\n { kind: 'compose', meta: { steps: descriptors } },\n );\n}\n\n/**\n * Wrap a caller-supplied function as a {@link DescribedFilter} with\n * the canonical `'custom'` descriptor.\n *\n * @stable\n */\nexport function custom(\n fn: HandoffFilter,\n meta?: Readonly<Record<string, unknown>>,\n): DescribedFilter {\n return makeFilter(fn, meta !== undefined ? { kind: 'custom', meta } : { kind: 'custom' });\n}\n\n/**\n * The canonical default applied by the agent runtime to every\n * `Agent.toTool(...)` and `handoff(...)` invocation when the caller\n * does not supply an explicit filter.\n *\n * @stable\n */\nexport function defaultHandoffFilter(): DescribedFilter {\n return compose(lastN(10), stripSensitiveOutputs());\n}\n\n/**\n * Pure `HandoffInputFilterDescriptor` for callers that just need the\n * descriptor without instantiating the runtime function (e.g. the\n * sessions package's lenient-forward-parse path).\n *\n * @stable\n */\nexport const FILTER_KIND_CUSTOM: HandoffInputFilterDescriptor = { kind: 'custom' };\n\n/** Aggregate module export. */\nexport const filters = {\n lastN,\n lastUser,\n full,\n summary,\n bySensitivity,\n stripReasoning,\n stripSensitiveOutputs,\n stripToolCalls,\n compose,\n custom,\n defaultHandoffFilter,\n};\n"],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { AgentResolutionError, AgentRuntimeError, AgentRuntimeErrorCode, EvaluatorOptimizerConfigError, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RunStateMalformedError, RunStateVersionUnsupportedError, ToolNotFoundError } from "./errors/index.js";
2
+ import { EvaluatorCallable, EvaluatorOptimizerOptions, EvaluatorOptimizerOutcome, EvaluatorOutcome, GeneratorCallable, Rubric, evaluatorOptimizer } from "./evaluator-optimizer/index.js";
3
+ import { AgentFallbackEligibility, AgentFallbackPolicy, AgentFallbackReason, isAgentFallbackEligible } from "./fallback/index.js";
4
+ import { ChildTrustInput, ContentOriginKind, MergeBiasDecision, MergeGuardConfig, TrustClass, computeSourceTrust, evaluateMerge } from "./lateral-leak/merge-guard.js";
5
+ import { ChildResult, FanOutOptions, FanOutResult, MergeStrategy, PerChildBudget, runFanOut } from "./fanout/index.js";
6
+ import { CausalityMonitor, CausalityMonitorCheck, CausalityMonitorConfig, CausalityMonitorStrictness, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH } from "./lateral-leak/causality-monitor.js";
7
+ import { ProgressIO, ProgressIOConfig, ProgressReadOptions, ProgressWriteOptions, createProgressIO } from "./progress/index.js";
8
+ import { AbortOptions, Agent, AgentCallOptions, AgentConfig, AgentInput, AgentToToolOptions, CompactOptions, CompactionApiResult, OutputSpec, PostCompactionHook, PrepareStepHook, PrepareStepOverrides, ResumeDirective, SkillsRegistryLike } from "./types.js";
9
+ import { createAgent } from "./factory.js";
10
+ import { DescribedFilter, FILTER_KIND_CUSTOM, bySensitivity, compose, custom, defaultHandoffFilter, filters, full, lastN, lastUser, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary } from "./filters/index.js";
11
+ import { GuardOutcome, ProtocolBoundary, ProtocolEscapePolicy, ProtocolGuardConfig, guardOutboundContent, resolvePolicy } from "./lateral-leak/protocol-guard.js";
12
+ import "./lateral-leak/index.js";
13
+ import { PreferredModelResolution, ResolvePreferredModelInput, pickTopTierAcrossTools, resolvePreferredModel } from "./preferred-model/index.js";
14
+ import { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, SerializeRunStateOptions, SerializedRunState, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState } from "./run-state/index.js";
15
+ import { GuardrailContext, GuardrailDefinition, GuardrailResult, InputGuardrail, OutputGuardrail } from "@graphorin/security/guardrails";
16
+
17
+ //#region src/index.d.ts
18
+
19
+ /**
20
+ * `@graphorin/agent` — agent runtime for the Graphorin framework.
21
+ *
22
+ * The package owns:
23
+ *
24
+ * - The `createAgent({...})` factory that wires the typed
25
+ * `model -> tool calls -> model` loop, the streaming event
26
+ * surface, the steering / followUp queues, durable HITL
27
+ * approvals, multi-agent handoffs (`Agent.toTool`, the filter
28
+ * library, secrets isolation), the agent-level model fallback
29
+ * chain, the per-step compaction lifecycle, the per-tool
30
+ * preferred-model resolution, the structured progress-artifact
31
+ * APIs, and the lateral-leak defense layer.
32
+ * - `runStateToJSON / runStateFromJSON` helpers for caller-managed
33
+ * durable HITL.
34
+ * - The handoff filter library.
35
+ * - The agent-step-level fan-out helpers (`runFanOut`,
36
+ * `evaluatorOptimizer`, the progress IO surface).
37
+ * - Pure decision functions consulted by the loop
38
+ * (`isAgentFallbackEligible`, `resolvePreferredModel`).
39
+ * - Lateral-leak primitives (`CausalityMonitor`,
40
+ * `MergeAgentSidewaysInjectionGuard` decision helpers,
41
+ * protocol-injection guard).
42
+ *
43
+ * The full documentation lives in the package `README.md`.
44
+ *
45
+ * @packageDocumentation
46
+ */
47
+ /** Canonical version constant. Mirrors the `package.json` version. */
48
+ declare const VERSION = "0.5.0";
49
+ //#endregion
50
+ export { type AbortOptions, type Agent, type AgentCallOptions, type AgentConfig, type AgentFallbackEligibility, type AgentFallbackPolicy, type AgentFallbackReason, type AgentInput, AgentResolutionError, AgentRuntimeError, type AgentRuntimeErrorCode, type AgentToToolOptions, CausalityMonitor, type CausalityMonitorCheck, type CausalityMonitorConfig, type CausalityMonitorStrictness, type ChildResult, type ChildTrustInput, type CompactOptions, type CompactionApiResult, type ContentOriginKind, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH, type DescribedFilter, type EvaluatorCallable, EvaluatorOptimizerConfigError, type EvaluatorOptimizerOptions, type EvaluatorOptimizerOutcome, type EvaluatorOutcome, FILTER_KIND_CUSTOM, type FanOutOptions, type FanOutResult, type GeneratorCallable, type GuardOutcome, type GuardrailContext, type GuardrailDefinition, type GuardrailResult, type InputGuardrail, InvalidAgentConfigError, InvalidPreferredModelError, type MergeBiasDecision, MergeBlockedError, type MergeGuardConfig, type MergeStrategy, MultipleHandoffsInStepError, type OutputGuardrail, type OutputSpec, type PerChildBudget, type PostCompactionHook, type PreferredModelResolution, type PrepareStepHook, type PrepareStepOverrides, type ProgressIO, type ProgressIOConfig, type ProgressReadOptions, ProgressWriteError, type ProgressWriteOptions, type ProtocolBoundary, type ProtocolEscapePolicy, type ProtocolGuardConfig, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, type ResolvePreferredModelInput, type ResumeDirective, type Rubric, RunStateMalformedError, RunStateVersionUnsupportedError, type SerializeRunStateOptions, type SerializedRunState, type SkillsRegistryLike, ToolNotFoundError, type TrustClass, VERSION, addModelUsage, aggregateUsageFromByModel, bySensitivity, completedToolCallsFromState, compose, computeSourceTrust, createAgent, createInitialRunState, createProgressIO, custom, defaultHandoffFilter, deserializeRunState, evaluateMerge, evaluatorOptimizer, filters, full, guardOutboundContent, isAgentFallbackEligible, lastN, lastUser, pickTopTierAcrossTools, resolvePolicy, resolvePreferredModel, runFanOut, runStateFromJSON, runStateToJSON, serializeRunState, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary };
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA;;;;;;;;;;;;cAAa,OAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,49 @@
1
+ import { AgentResolutionError, AgentRuntimeError, EvaluatorOptimizerConfigError, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RunStateMalformedError, RunStateVersionUnsupportedError, ToolNotFoundError } from "./errors/index.js";
2
+ import { evaluatorOptimizer } from "./evaluator-optimizer/index.js";
3
+ import { isAgentFallbackEligible } from "./fallback/index.js";
4
+ import { computeSourceTrust, evaluateMerge } from "./lateral-leak/merge-guard.js";
5
+ import { runFanOut } from "./fanout/index.js";
6
+ import { FILTER_KIND_CUSTOM, bySensitivity, compose, custom, defaultHandoffFilter, filters, full, lastN, lastUser, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary } from "./filters/index.js";
7
+ import { CausalityMonitor, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH } from "./lateral-leak/causality-monitor.js";
8
+ import { pickTopTierAcrossTools, resolvePreferredModel } from "./preferred-model/index.js";
9
+ import { createProgressIO } from "./progress/index.js";
10
+ import { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState } from "./run-state/index.js";
11
+ import { createAgent } from "./factory.js";
12
+ import { guardOutboundContent, resolvePolicy } from "./lateral-leak/protocol-guard.js";
13
+ import "./lateral-leak/index.js";
14
+
15
+ //#region src/index.ts
16
+ /**
17
+ * `@graphorin/agent` — agent runtime for the Graphorin framework.
18
+ *
19
+ * The package owns:
20
+ *
21
+ * - The `createAgent({...})` factory that wires the typed
22
+ * `model -> tool calls -> model` loop, the streaming event
23
+ * surface, the steering / followUp queues, durable HITL
24
+ * approvals, multi-agent handoffs (`Agent.toTool`, the filter
25
+ * library, secrets isolation), the agent-level model fallback
26
+ * chain, the per-step compaction lifecycle, the per-tool
27
+ * preferred-model resolution, the structured progress-artifact
28
+ * APIs, and the lateral-leak defense layer.
29
+ * - `runStateToJSON / runStateFromJSON` helpers for caller-managed
30
+ * durable HITL.
31
+ * - The handoff filter library.
32
+ * - The agent-step-level fan-out helpers (`runFanOut`,
33
+ * `evaluatorOptimizer`, the progress IO surface).
34
+ * - Pure decision functions consulted by the loop
35
+ * (`isAgentFallbackEligible`, `resolvePreferredModel`).
36
+ * - Lateral-leak primitives (`CausalityMonitor`,
37
+ * `MergeAgentSidewaysInjectionGuard` decision helpers,
38
+ * protocol-injection guard).
39
+ *
40
+ * The full documentation lives in the package `README.md`.
41
+ *
42
+ * @packageDocumentation
43
+ */
44
+ /** Canonical version constant. Mirrors the `package.json` version. */
45
+ const VERSION = "0.5.0";
46
+
47
+ //#endregion
48
+ export { AgentResolutionError, AgentRuntimeError, CausalityMonitor, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH, EvaluatorOptimizerConfigError, FILTER_KIND_CUSTOM, InvalidAgentConfigError, InvalidPreferredModelError, MergeBlockedError, MultipleHandoffsInStepError, ProgressWriteError, ProtocolInjectionRejectError, ProviderMiddlewareOrderError, RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, RunStateMalformedError, RunStateVersionUnsupportedError, ToolNotFoundError, VERSION, addModelUsage, aggregateUsageFromByModel, bySensitivity, completedToolCallsFromState, compose, computeSourceTrust, createAgent, createInitialRunState, createProgressIO, custom, defaultHandoffFilter, deserializeRunState, evaluateMerge, evaluatorOptimizer, filters, full, guardOutboundContent, isAgentFallbackEligible, lastN, lastUser, pickTopTierAcrossTools, resolvePolicy, resolvePreferredModel, runFanOut, runStateFromJSON, runStateToJSON, serializeRunState, stripReasoning, stripSensitiveOutputs, stripToolCalls, summary };
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@graphorin/agent` — agent runtime for the Graphorin framework.\n *\n * The package owns:\n *\n * - The `createAgent({...})` factory that wires the typed\n * `model -> tool calls -> model` loop, the streaming event\n * surface, the steering / followUp queues, durable HITL\n * approvals, multi-agent handoffs (`Agent.toTool`, the filter\n * library, secrets isolation), the agent-level model fallback\n * chain, the per-step compaction lifecycle, the per-tool\n * preferred-model resolution, the structured progress-artifact\n * APIs, and the lateral-leak defense layer.\n * - `runStateToJSON / runStateFromJSON` helpers for caller-managed\n * durable HITL.\n * - The handoff filter library.\n * - The agent-step-level fan-out helpers (`runFanOut`,\n * `evaluatorOptimizer`, the progress IO surface).\n * - Pure decision functions consulted by the loop\n * (`isAgentFallbackEligible`, `resolvePreferredModel`).\n * - Lateral-leak primitives (`CausalityMonitor`,\n * `MergeAgentSidewaysInjectionGuard` decision helpers,\n * protocol-injection guard).\n *\n * The full documentation lives in the package `README.md`.\n *\n * @packageDocumentation\n */\n\n/** Canonical version constant. Mirrors the `package.json` version. */\nexport const VERSION = '0.5.0';\n\n// AG-2 / SDF-4: the canonical guardrail contract lives in\n// `@graphorin/security`; re-exported here for config ergonomics.\nexport type {\n GuardrailContext,\n GuardrailDefinition,\n GuardrailResult,\n InputGuardrail,\n OutputGuardrail,\n} from '@graphorin/security/guardrails';\nexport {\n AgentResolutionError,\n AgentRuntimeError,\n type AgentRuntimeErrorCode,\n EvaluatorOptimizerConfigError,\n InvalidAgentConfigError,\n InvalidPreferredModelError,\n MergeBlockedError,\n MultipleHandoffsInStepError,\n ProgressWriteError,\n ProtocolInjectionRejectError,\n ProviderMiddlewareOrderError,\n RunStateMalformedError,\n RunStateVersionUnsupportedError,\n ToolNotFoundError,\n} from './errors/index.js';\nexport {\n type EvaluatorCallable,\n type EvaluatorOptimizerOptions,\n type EvaluatorOptimizerOutcome,\n type EvaluatorOutcome,\n evaluatorOptimizer,\n type GeneratorCallable,\n type Rubric,\n} from './evaluator-optimizer/index.js';\nexport { createAgent } from './factory.js';\nexport {\n type AgentFallbackEligibility,\n type AgentFallbackPolicy,\n type AgentFallbackReason,\n isAgentFallbackEligible,\n} from './fallback/index.js';\nexport {\n type ChildResult,\n type FanOutOptions,\n type FanOutResult,\n type MergeStrategy,\n type PerChildBudget,\n runFanOut,\n} from './fanout/index.js';\nexport {\n bySensitivity,\n compose,\n custom,\n type DescribedFilter,\n defaultHandoffFilter,\n FILTER_KIND_CUSTOM,\n filters,\n full,\n lastN,\n lastUser,\n stripReasoning,\n stripSensitiveOutputs,\n stripToolCalls,\n summary,\n} from './filters/index.js';\nexport {\n CausalityMonitor,\n type CausalityMonitorCheck,\n type CausalityMonitorConfig,\n type CausalityMonitorStrictness,\n type ChildTrustInput,\n type ContentOriginKind,\n computeSourceTrust,\n DEFAULT_DENIAL_PATTERNS,\n DEFAULT_MAX_CHAIN_DEPTH,\n evaluateMerge,\n type GuardOutcome,\n guardOutboundContent,\n type MergeBiasDecision,\n type MergeGuardConfig,\n type ProtocolBoundary,\n type ProtocolEscapePolicy,\n type ProtocolGuardConfig,\n resolvePolicy,\n type TrustClass,\n} from './lateral-leak/index.js';\nexport {\n type PreferredModelResolution,\n pickTopTierAcrossTools,\n type ResolvePreferredModelInput,\n resolvePreferredModel,\n} from './preferred-model/index.js';\nexport {\n createProgressIO,\n type ProgressIO,\n type ProgressIOConfig,\n type ProgressReadOptions,\n type ProgressWriteOptions,\n} from './progress/index.js';\nexport {\n addModelUsage,\n aggregateUsageFromByModel,\n completedToolCallsFromState,\n createInitialRunState,\n deserializeRunState,\n RUN_STATE_SCHEMA_MAJOR_SUPPORTED,\n RUN_STATE_SCHEMA_VERSION,\n runStateFromJSON,\n runStateToJSON,\n type SerializedRunState,\n type SerializeRunStateOptions,\n serializeRunState,\n} from './run-state/index.js';\nexport type {\n AbortOptions,\n Agent,\n AgentCallOptions,\n AgentConfig,\n AgentInput,\n AgentToToolOptions,\n CompactionApiResult,\n CompactOptions,\n OutputSpec,\n PostCompactionHook,\n PrepareStepHook,\n PrepareStepOverrides,\n ResumeDirective,\n SkillsRegistryLike,\n} from './types.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,UAAU"}
@@ -0,0 +1,46 @@
1
+ import { randomBytes } from "node:crypto";
2
+
3
+ //#region src/internal/ids.ts
4
+ /**
5
+ * Tiny id helpers used by the agent runtime. URL-safe Base32 alphabet,
6
+ * monotonic timestamp prefix to keep ids loosely sortable.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ const ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
11
+ function pad(value, width) {
12
+ return value.padStart(width, "0");
13
+ }
14
+ /**
15
+ * 7-character Base32 tail backed by 35 bits of CSPRNG entropy. We read
16
+ * 5 random bytes (40 bits) and consume 5 bits per emitted character
17
+ * MSB-first; the leftover bits are discarded. Sourcing from
18
+ * `randomBytes` (uniform over `[0, 256)`) guarantees a uniform
19
+ * distribution over `ALPHABET` — no modulo bias.
20
+ */
21
+ function randomTail() {
22
+ const buf = randomBytes(5);
23
+ let bitBuffer = 0;
24
+ let bitCount = 0;
25
+ let cursor = 0;
26
+ let out = "";
27
+ for (let i = 0; i < 7; i++) {
28
+ while (bitCount < 5) {
29
+ bitBuffer = bitBuffer << 8 | (buf[cursor++] ?? 0);
30
+ bitCount += 8;
31
+ }
32
+ bitCount -= 5;
33
+ const idx = bitBuffer >>> bitCount & 31;
34
+ out += ALPHABET[idx];
35
+ }
36
+ return out;
37
+ }
38
+ /** Generate a fresh, sortable, URL-safe identifier. */
39
+ function newId(prefix) {
40
+ const id = `${pad(Date.now().toString(32).toUpperCase(), 9)}${randomTail()}`;
41
+ return prefix ? `${prefix}_${id}` : id;
42
+ }
43
+
44
+ //#endregion
45
+ export { newId };
46
+ //# sourceMappingURL=ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.js","names":[],"sources":["../../src/internal/ids.ts"],"sourcesContent":["/**\n * Tiny id helpers used by the agent runtime. URL-safe Base32 alphabet,\n * monotonic timestamp prefix to keep ids loosely sortable.\n *\n * @packageDocumentation\n */\n\nimport { randomBytes } from 'node:crypto';\n\nconst ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\n\nfunction pad(value: string, width: number): string {\n return value.padStart(width, '0');\n}\n\n/**\n * 7-character Base32 tail backed by 35 bits of CSPRNG entropy. We read\n * 5 random bytes (40 bits) and consume 5 bits per emitted character\n * MSB-first; the leftover bits are discarded. Sourcing from\n * `randomBytes` (uniform over `[0, 256)`) guarantees a uniform\n * distribution over `ALPHABET` — no modulo bias.\n */\nfunction randomTail(): string {\n const buf = randomBytes(5);\n let bitBuffer = 0;\n let bitCount = 0;\n let cursor = 0;\n let out = '';\n for (let i = 0; i < 7; i++) {\n while (bitCount < 5) {\n bitBuffer = (bitBuffer << 8) | (buf[cursor++] ?? 0);\n bitCount += 8;\n }\n bitCount -= 5;\n const idx = (bitBuffer >>> bitCount) & 0x1f;\n out += ALPHABET[idx];\n }\n return out;\n}\n\n/** Generate a fresh, sortable, URL-safe identifier. */\nexport function newId(prefix?: string): string {\n const ts = pad(Date.now().toString(32).toUpperCase(), 9);\n const id = `${ts}${randomTail()}`;\n return prefix ? `${prefix}_${id}` : id;\n}\n"],"mappings":";;;;;;;;;AASA,MAAM,WAAW;AAEjB,SAAS,IAAI,OAAe,OAAuB;AACjD,QAAO,MAAM,SAAS,OAAO,IAAI;;;;;;;;;AAUnC,SAAS,aAAqB;CAC5B,MAAM,MAAM,YAAY,EAAE;CAC1B,IAAI,YAAY;CAChB,IAAI,WAAW;CACf,IAAI,SAAS;CACb,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,SAAO,WAAW,GAAG;AACnB,eAAa,aAAa,KAAM,IAAI,aAAa;AACjD,eAAY;;AAEd,cAAY;EACZ,MAAM,MAAO,cAAc,WAAY;AACvC,SAAO,SAAS;;AAElB,QAAO;;;AAIT,SAAgB,MAAM,QAAyB;CAE7C,MAAM,KAAK,GADA,IAAI,KAAK,KAAK,CAAC,SAAS,GAAG,CAAC,aAAa,EAAE,EAAE,GACrC,YAAY;AAC/B,QAAO,SAAS,GAAG,OAAO,GAAG,OAAO"}
@@ -0,0 +1,62 @@
1
+ //#region src/internal/usage-accumulator.ts
2
+ var InMemoryUsageAccumulator = class {
3
+ #aggregate = {
4
+ promptTokens: 0,
5
+ completionTokens: 0,
6
+ totalTokens: 0
7
+ };
8
+ #byModel = /* @__PURE__ */ new Map();
9
+ get total() {
10
+ return this.#aggregate;
11
+ }
12
+ get byModel() {
13
+ return this.#byModel;
14
+ }
15
+ add(modelId, usage) {
16
+ const prev = this.#byModel.get(modelId);
17
+ if (prev === void 0) this.#byModel.set(modelId, {
18
+ modelId,
19
+ promptTokens: usage.promptTokens,
20
+ completionTokens: usage.completionTokens,
21
+ totalTokens: usage.totalTokens,
22
+ callCount: 1,
23
+ ...usage.reasoningTokens !== void 0 ? { reasoningTokens: usage.reasoningTokens } : {},
24
+ ...usage.cost !== void 0 ? { cost: usage.cost } : {}
25
+ });
26
+ else {
27
+ const merged = {
28
+ modelId,
29
+ promptTokens: prev.promptTokens + usage.promptTokens,
30
+ completionTokens: prev.completionTokens + usage.completionTokens,
31
+ totalTokens: prev.totalTokens + usage.totalTokens,
32
+ callCount: prev.callCount + 1,
33
+ ...usage.reasoningTokens !== void 0 || prev.reasoningTokens !== void 0 ? { reasoningTokens: (prev.reasoningTokens ?? 0) + (usage.reasoningTokens ?? 0) } : {}
34
+ };
35
+ this.#byModel.set(modelId, merged);
36
+ }
37
+ this.#aggregate = {
38
+ promptTokens: this.#aggregate.promptTokens + usage.promptTokens,
39
+ completionTokens: this.#aggregate.completionTokens + usage.completionTokens,
40
+ totalTokens: this.#aggregate.totalTokens + usage.totalTokens,
41
+ ...usage.reasoningTokens !== void 0 || this.#aggregate.reasoningTokens !== void 0 ? { reasoningTokens: (this.#aggregate.reasoningTokens ?? 0) + (usage.reasoningTokens ?? 0) } : {}
42
+ };
43
+ }
44
+ reset() {
45
+ this.#aggregate = {
46
+ promptTokens: 0,
47
+ completionTokens: 0,
48
+ totalTokens: 0
49
+ };
50
+ this.#byModel.clear();
51
+ }
52
+ snapshot() {
53
+ return {
54
+ total: { ...this.#aggregate },
55
+ byModel: Array.from(this.#byModel.values()).map((m) => ({ ...m }))
56
+ };
57
+ }
58
+ };
59
+
60
+ //#endregion
61
+ export { InMemoryUsageAccumulator };
62
+ //# sourceMappingURL=usage-accumulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-accumulator.js","names":["#byModel","#aggregate","merged: ModelUsage"],"sources":["../../src/internal/usage-accumulator.ts"],"sourcesContent":["/**\n * Minimal {@link UsageAccumulator} implementation used by the agent\n * runtime when the consumer does not pass a custom one through\n * `RunContext.usage`. Tracks per-model breakdown and a running\n * aggregate.\n *\n * @packageDocumentation\n */\n\nimport type { ModelUsage, Usage, UsageAccumulator, UsageSnapshot } from '@graphorin/core';\n\nexport class InMemoryUsageAccumulator implements UsageAccumulator {\n #aggregate: Usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };\n readonly #byModel = new Map<string, ModelUsage>();\n\n get total(): Usage {\n return this.#aggregate;\n }\n\n get byModel(): ReadonlyMap<string, ModelUsage> {\n return this.#byModel;\n }\n\n add(modelId: string, usage: Usage): void {\n const prev = this.#byModel.get(modelId);\n if (prev === undefined) {\n this.#byModel.set(modelId, {\n modelId,\n promptTokens: usage.promptTokens,\n completionTokens: usage.completionTokens,\n totalTokens: usage.totalTokens,\n callCount: 1,\n ...(usage.reasoningTokens !== undefined ? { reasoningTokens: usage.reasoningTokens } : {}),\n ...(usage.cost !== undefined ? { cost: usage.cost } : {}),\n });\n } else {\n const merged: ModelUsage = {\n modelId,\n promptTokens: prev.promptTokens + usage.promptTokens,\n completionTokens: prev.completionTokens + usage.completionTokens,\n totalTokens: prev.totalTokens + usage.totalTokens,\n callCount: prev.callCount + 1,\n ...(usage.reasoningTokens !== undefined || prev.reasoningTokens !== undefined\n ? {\n reasoningTokens: (prev.reasoningTokens ?? 0) + (usage.reasoningTokens ?? 0),\n }\n : {}),\n };\n this.#byModel.set(modelId, merged);\n }\n this.#aggregate = {\n promptTokens: this.#aggregate.promptTokens + usage.promptTokens,\n completionTokens: this.#aggregate.completionTokens + usage.completionTokens,\n totalTokens: this.#aggregate.totalTokens + usage.totalTokens,\n ...(usage.reasoningTokens !== undefined || this.#aggregate.reasoningTokens !== undefined\n ? {\n reasoningTokens: (this.#aggregate.reasoningTokens ?? 0) + (usage.reasoningTokens ?? 0),\n }\n : {}),\n };\n }\n\n reset(): void {\n this.#aggregate = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };\n this.#byModel.clear();\n }\n\n snapshot(): UsageSnapshot {\n return {\n total: { ...this.#aggregate },\n byModel: Array.from(this.#byModel.values()).map((m) => ({ ...m })),\n };\n }\n}\n"],"mappings":";AAWA,IAAa,2BAAb,MAAkE;CAChE,aAAoB;EAAE,cAAc;EAAG,kBAAkB;EAAG,aAAa;EAAG;CAC5E,CAASA,0BAAW,IAAI,KAAyB;CAEjD,IAAI,QAAe;AACjB,SAAO,MAAKC;;CAGd,IAAI,UAA2C;AAC7C,SAAO,MAAKD;;CAGd,IAAI,SAAiB,OAAoB;EACvC,MAAM,OAAO,MAAKA,QAAS,IAAI,QAAQ;AACvC,MAAI,SAAS,OACX,OAAKA,QAAS,IAAI,SAAS;GACzB;GACA,cAAc,MAAM;GACpB,kBAAkB,MAAM;GACxB,aAAa,MAAM;GACnB,WAAW;GACX,GAAI,MAAM,oBAAoB,SAAY,EAAE,iBAAiB,MAAM,iBAAiB,GAAG,EAAE;GACzF,GAAI,MAAM,SAAS,SAAY,EAAE,MAAM,MAAM,MAAM,GAAG,EAAE;GACzD,CAAC;OACG;GACL,MAAME,SAAqB;IACzB;IACA,cAAc,KAAK,eAAe,MAAM;IACxC,kBAAkB,KAAK,mBAAmB,MAAM;IAChD,aAAa,KAAK,cAAc,MAAM;IACtC,WAAW,KAAK,YAAY;IAC5B,GAAI,MAAM,oBAAoB,UAAa,KAAK,oBAAoB,SAChE,EACE,kBAAkB,KAAK,mBAAmB,MAAM,MAAM,mBAAmB,IAC1E,GACD,EAAE;IACP;AACD,SAAKF,QAAS,IAAI,SAAS,OAAO;;AAEpC,QAAKC,YAAa;GAChB,cAAc,MAAKA,UAAW,eAAe,MAAM;GACnD,kBAAkB,MAAKA,UAAW,mBAAmB,MAAM;GAC3D,aAAa,MAAKA,UAAW,cAAc,MAAM;GACjD,GAAI,MAAM,oBAAoB,UAAa,MAAKA,UAAW,oBAAoB,SAC3E,EACE,kBAAkB,MAAKA,UAAW,mBAAmB,MAAM,MAAM,mBAAmB,IACrF,GACD,EAAE;GACP;;CAGH,QAAc;AACZ,QAAKA,YAAa;GAAE,cAAc;GAAG,kBAAkB;GAAG,aAAa;GAAG;AAC1E,QAAKD,QAAS,OAAO;;CAGvB,WAA0B;AACxB,SAAO;GACL,OAAO,EAAE,GAAG,MAAKC,WAAY;GAC7B,SAAS,MAAM,KAAK,MAAKD,QAAS,QAAQ,CAAC,CAAC,KAAK,OAAO,EAAE,GAAG,GAAG,EAAE;GACnE"}
@@ -0,0 +1,97 @@
1
+ import { LateralLeakVector } from "@graphorin/core";
2
+
3
+ //#region src/lateral-leak/causality-monitor.d.ts
4
+
5
+ /**
6
+ * Operator-tunable strictness level. Default `'detect-and-flag'`
7
+ * for cloud-tier providers; `'detect'` for loopback providers;
8
+ * `'off'` for v0.1-alpha backward compatibility.
9
+ *
10
+ * @stable
11
+ */
12
+ type CausalityMonitorStrictness = 'off' | 'detect' | 'detect-and-flag' | 'detect-and-block';
13
+ /**
14
+ * Per-agent configuration accepted by `createAgent({ causalityMonitor })`.
15
+ *
16
+ * @stable
17
+ */
18
+ interface CausalityMonitorConfig {
19
+ readonly strictness: CausalityMonitorStrictness;
20
+ /** Maximum depth of the chain. Default `32`. */
21
+ readonly maxChainDepth?: number;
22
+ /** Operator-extensible denial patterns. */
23
+ readonly denialPatterns?: ReadonlyArray<RegExp>;
24
+ /**
25
+ * When `true`, emit the chain on every `checkMessage(...)` call
26
+ * (high-cardinality; opt-in for compliance audits). Default
27
+ * `false` — only emit on detected leaks.
28
+ */
29
+ readonly auditAllChains?: boolean;
30
+ }
31
+ /**
32
+ * Default denial-pattern catalogue. The agent runtime extends this
33
+ * list when the operator supplies their own patterns.
34
+ *
35
+ * @stable
36
+ */
37
+ declare const DEFAULT_DENIAL_PATTERNS: ReadonlyArray<RegExp>;
38
+ /** Default chain depth when not specified. */
39
+ declare const DEFAULT_MAX_CHAIN_DEPTH = 32;
40
+ /**
41
+ * Result returned by {@link CausalityMonitor.checkMessage}.
42
+ *
43
+ * @stable
44
+ */
45
+ interface CausalityMonitorCheck {
46
+ readonly leakDetected: boolean;
47
+ readonly severity: 'info' | 'warn' | 'block';
48
+ readonly causalityChain: ReadonlyArray<string>;
49
+ readonly matchedPattern?: string;
50
+ readonly decision: 'detect' | 'flag' | 'strip' | 'block';
51
+ readonly vector: LateralLeakVector;
52
+ }
53
+ /**
54
+ * In-memory primitive instantiated per `RunContext`. Bounded-depth
55
+ * append discipline keeps the memory footprint trivial even on long
56
+ * runs.
57
+ *
58
+ * @stable
59
+ */
60
+ declare class CausalityMonitor {
61
+ #private;
62
+ readonly strictness: CausalityMonitorStrictness;
63
+ readonly maxChainDepth: number;
64
+ readonly denialPatterns: ReadonlyArray<RegExp>;
65
+ readonly auditAllChains: boolean;
66
+ constructor(cfg: CausalityMonitorConfig);
67
+ /** Snapshot the current causality chain. */
68
+ get chain(): ReadonlyArray<string>;
69
+ /**
70
+ * Append an entry to the causality chain, dropping the oldest
71
+ * when the chain exceeds `maxChainDepth`. Bounded-length, no PII,
72
+ * no secret values — entries are short opaque strings like
73
+ * `tool:slack-notify`, `tool.error:SecretAccessDenied`,
74
+ * `subagent:research-east`, `compaction:auto-trigger`.
75
+ */
76
+ recordCall(entry: string): void;
77
+ /** Reset the chain — e.g. on `agent.run` boundary. */
78
+ reset(): void;
79
+ /**
80
+ * Inspect a candidate assistant-visible string and return whether
81
+ * the lateral-leak defense should fire. Pure decision based on
82
+ * the current chain + the operator-extensible denial patterns.
83
+ */
84
+ checkMessage(content: string): CausalityMonitorCheck;
85
+ /**
86
+ * Drain the chain to the audit log on `agent.run` completion or
87
+ * `agent.abort`. The runtime supplies the audit emitter — the
88
+ * primitive itself is storage-agnostic.
89
+ */
90
+ flush(reason: 'agent.run.complete' | 'agent.abort'): {
91
+ readonly chain: ReadonlyArray<string>;
92
+ readonly reason: 'agent.run.complete' | 'agent.abort';
93
+ };
94
+ }
95
+ //#endregion
96
+ export { CausalityMonitor, CausalityMonitorCheck, CausalityMonitorConfig, CausalityMonitorStrictness, DEFAULT_DENIAL_PATTERNS, DEFAULT_MAX_CHAIN_DEPTH };
97
+ //# sourceMappingURL=causality-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causality-monitor.d.ts","names":[],"sources":["../../src/lateral-leak/causality-monitor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;KAuBY,0BAAA;;;;;;UAOK,sBAAA;uBACM;;;;4BAIK,cAAc;;;;;;;;;;;;;;cAe7B,yBAAyB,cAAc;;cAQvC,uBAAA;;;;;;UAOI,qBAAA;;;2BAGU;;;mBAGR;;;;;;;;;cAUN,gBAAA;;uBACU;;2BAEI,cAAc;;mBAItB;;eAUJ;;;;;;;;;;;;;;;;iCA8BkB;;;;;;;oBAuFb"}