@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.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/errors/index.d.ts +170 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +204 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/evaluator-optimizer/index.d.ts +91 -0
- package/dist/evaluator-optimizer/index.d.ts.map +1 -0
- package/dist/evaluator-optimizer/index.js +85 -0
- package/dist/evaluator-optimizer/index.js.map +1 -0
- package/dist/factory.d.ts +13 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +1853 -0
- package/dist/factory.js.map +1 -0
- package/dist/fallback/index.d.ts +52 -0
- package/dist/fallback/index.d.ts.map +1 -0
- package/dist/fallback/index.js +53 -0
- package/dist/fallback/index.js.map +1 -0
- package/dist/fanout/index.d.ts +142 -0
- package/dist/fanout/index.d.ts.map +1 -0
- package/dist/fanout/index.js +252 -0
- package/dist/fanout/index.js.map +1 -0
- package/dist/filters/index.d.ts +137 -0
- package/dist/filters/index.d.ts.map +1 -0
- package/dist/filters/index.js +273 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/ids.js +46 -0
- package/dist/internal/ids.js.map +1 -0
- package/dist/internal/usage-accumulator.js +62 -0
- package/dist/internal/usage-accumulator.js.map +1 -0
- package/dist/lateral-leak/causality-monitor.d.ts +97 -0
- package/dist/lateral-leak/causality-monitor.d.ts.map +1 -0
- package/dist/lateral-leak/causality-monitor.js +139 -0
- package/dist/lateral-leak/causality-monitor.js.map +1 -0
- package/dist/lateral-leak/index.d.ts +4 -0
- package/dist/lateral-leak/index.js +5 -0
- package/dist/lateral-leak/merge-guard.d.ts +89 -0
- package/dist/lateral-leak/merge-guard.d.ts.map +1 -0
- package/dist/lateral-leak/merge-guard.js +65 -0
- package/dist/lateral-leak/merge-guard.js.map +1 -0
- package/dist/lateral-leak/protocol-guard.d.ts +76 -0
- package/dist/lateral-leak/protocol-guard.d.ts.map +1 -0
- package/dist/lateral-leak/protocol-guard.js +147 -0
- package/dist/lateral-leak/protocol-guard.js.map +1 -0
- package/dist/preferred-model/index.d.ts +53 -0
- package/dist/preferred-model/index.d.ts.map +1 -0
- package/dist/preferred-model/index.js +141 -0
- package/dist/preferred-model/index.js.map +1 -0
- package/dist/progress/index.d.ts +62 -0
- package/dist/progress/index.d.ts.map +1 -0
- package/dist/progress/index.js +150 -0
- package/dist/progress/index.js.map +1 -0
- package/dist/run-state/index.d.ts +152 -0
- package/dist/run-state/index.d.ts.map +1 -0
- package/dist/run-state/index.js +311 -0
- package/dist/run-state/index.js.map +1 -0
- package/dist/tooling/adapters.js +154 -0
- package/dist/tooling/adapters.js.map +1 -0
- package/dist/tooling/catalogue.js +37 -0
- package/dist/tooling/catalogue.js.map +1 -0
- package/dist/tooling/dataflow.js +99 -0
- package/dist/tooling/dataflow.js.map +1 -0
- package/dist/tooling/registry-build.js +85 -0
- package/dist/tooling/registry-build.js.map +1 -0
- package/dist/types.d.ts +413 -0
- package/dist/types.d.ts.map +1 -0
- 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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|