@flowcodex/core 0.3.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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/index-LbxYtxxS.d.ts +560 -0
- package/dist/index.d.ts +995 -0
- package/dist/index.js +3840 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel/index.d.ts +1 -0
- package/dist/kernel/index.js +551 -0
- package/dist/kernel/index.js.map +1 -0
- package/package.json +39 -0
- package/src/agent/agent-loop.ts +254 -0
- package/src/agent/context.ts +99 -0
- package/src/agent/conversation-state.ts +44 -0
- package/src/agent/provider-runner.ts +241 -0
- package/src/agent/system-prompt-builder.ts +193 -0
- package/src/execution/compactor.ts +256 -0
- package/src/execution/index.ts +7 -0
- package/src/execution/output-serializer.ts +90 -0
- package/src/execution/schema-validator.ts +124 -0
- package/src/execution/tool-executor.ts +276 -0
- package/src/execution/tool-registry.ts +104 -0
- package/src/index.ts +215 -0
- package/src/infrastructure/catalog-parser.ts +218 -0
- package/src/infrastructure/index.ts +16 -0
- package/src/infrastructure/path-resolver.ts +123 -0
- package/src/infrastructure/provider-factory.ts +116 -0
- package/src/infrastructure/provider-presets.ts +19 -0
- package/src/infrastructure/retry-policy.ts +50 -0
- package/src/infrastructure/secret-scrubber.ts +67 -0
- package/src/infrastructure/token-counter.ts +156 -0
- package/src/infrastructure/tracer.ts +23 -0
- package/src/kernel/container.ts +166 -0
- package/src/kernel/events.ts +323 -0
- package/src/kernel/index.ts +18 -0
- package/src/kernel/pipeline.ts +152 -0
- package/src/kernel/run-controller.ts +85 -0
- package/src/kernel/tokens.ts +21 -0
- package/src/security/index.ts +13 -0
- package/src/security/permission-policy.ts +273 -0
- package/src/session/audit-log.ts +201 -0
- package/src/session/auth-service.ts +178 -0
- package/src/session/index.ts +26 -0
- package/src/session/secret-vault.ts +183 -0
- package/src/session/session-store.ts +339 -0
- package/src/session/types.ts +100 -0
- package/src/types/blocks.ts +56 -0
- package/src/types/context.ts +54 -0
- package/src/types/errors.ts +359 -0
- package/src/types/index.ts +34 -0
- package/src/types/provider.ts +58 -0
- package/src/types/tool.ts +39 -0
- package/src/utils/error.ts +3 -0
- package/src/utils/fs.ts +185 -0
- package/src/utils/image-resize.ts +76 -0
- package/src/utils/ssrf-guard.ts +133 -0
- package/src/utils/ulid.ts +72 -0
- package/src/utils/version-check.ts +59 -0
- package/tests/agent-loop.test.ts +490 -0
- package/tests/audit-log.test.ts +199 -0
- package/tests/auth-service.test.ts +170 -0
- package/tests/blocks.test.ts +79 -0
- package/tests/catalog-parser.test.ts +174 -0
- package/tests/compactor.test.ts +180 -0
- package/tests/container.test.ts +224 -0
- package/tests/conversation-state.test.ts +75 -0
- package/tests/errors.test.ts +429 -0
- package/tests/events-v021.test.ts +60 -0
- package/tests/events-v022.test.ts +75 -0
- package/tests/events.test.ts +340 -0
- package/tests/fixtures/large-image.png +0 -0
- package/tests/fixtures/small-image.png +0 -0
- package/tests/fs-utils.test.ts +164 -0
- package/tests/image-resize.test.ts +51 -0
- package/tests/output-serializer.test.ts +79 -0
- package/tests/path-resolver.test.ts +91 -0
- package/tests/permission-policy.test.ts +174 -0
- package/tests/pipeline.test.ts +193 -0
- package/tests/provider-factory.test.ts +245 -0
- package/tests/provider-runner.test.ts +535 -0
- package/tests/retry-policy.test.ts +104 -0
- package/tests/run-controller.test.ts +115 -0
- package/tests/sanity.test.ts +26 -0
- package/tests/schema-validator.test.ts +109 -0
- package/tests/secret-scrubber.test.ts +133 -0
- package/tests/secret-vault.test.ts +130 -0
- package/tests/session-store.test.ts +429 -0
- package/tests/ssrf-guard.test.ts +112 -0
- package/tests/system-prompt-builder.test.ts +116 -0
- package/tests/token-counter.test.ts +163 -0
- package/tests/tokens.test.ts +42 -0
- package/tests/tool-executor.test.ts +452 -0
- package/tests/tool-registry.test.ts +143 -0
- package/tests/tracer.test.ts +32 -0
- package/tests/ulid.test.ts +53 -0
- package/tests/version-check.test.ts +57 -0
- package/tsconfig.json +11 -0
- package/tsup.config.ts +16 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { B as BindOptions, g as Container, D as Decorator, E as EventBus, i as EventLogger, j as EventMap, k as EventName, F as Factory, L as Listener, l as Middleware, m as MiddlewareHandler, N as NextFn, P as Pipeline, p as PipelineErrorEvent, q as PipelineErrorHandler, r as PipelineErrorPolicy, s as PipelineOptions, R as ReadonlyPipeline, u as RunController, v as RunControllerOptions, w as ScopedEventBus, x as TOKENS, z as Token, G as token } from '../index-LbxYtxxS.js';
|
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
// src/utils/error.ts
|
|
2
|
+
function toErrorMessage(err) {
|
|
3
|
+
return err instanceof Error ? err.message : String(err);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// src/types/errors.ts
|
|
7
|
+
var ERROR_CODES = {
|
|
8
|
+
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
9
|
+
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
10
|
+
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY"};
|
|
11
|
+
var FlowCodexError = class extends Error {
|
|
12
|
+
code;
|
|
13
|
+
subsystem;
|
|
14
|
+
severity;
|
|
15
|
+
recoverable;
|
|
16
|
+
context;
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
super(opts.message, { cause: opts.cause });
|
|
19
|
+
this.name = "FlowCodexError";
|
|
20
|
+
this.code = opts.code;
|
|
21
|
+
this.subsystem = opts.subsystem;
|
|
22
|
+
this.severity = opts.severity ?? "error";
|
|
23
|
+
this.recoverable = opts.recoverable ?? false;
|
|
24
|
+
this.context = opts.context;
|
|
25
|
+
}
|
|
26
|
+
describe() {
|
|
27
|
+
const ctx = this.context ? ` ${formatContext(this.context)}` : "";
|
|
28
|
+
return `${this.code}: ${this.message}${ctx}`;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function formatContext(ctx) {
|
|
32
|
+
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
33
|
+
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/kernel/container.ts
|
|
37
|
+
var Container = class {
|
|
38
|
+
entries = /* @__PURE__ */ new Map();
|
|
39
|
+
resolving = /* @__PURE__ */ new Set();
|
|
40
|
+
bind(token2, factory, opts = {}) {
|
|
41
|
+
if (this.entries.has(token2)) {
|
|
42
|
+
throw new FlowCodexError({
|
|
43
|
+
message: `Container: token "${token2.description ?? "unknown"}" already bound`,
|
|
44
|
+
code: ERROR_CODES.CONTAINER_TOKEN_ALREADY_BOUND,
|
|
45
|
+
subsystem: "container",
|
|
46
|
+
context: { token: token2.description }
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
this.entries.set(token2, {
|
|
50
|
+
factory,
|
|
51
|
+
singleton: opts.singleton ?? true,
|
|
52
|
+
decorators: [],
|
|
53
|
+
owner: opts.owner ?? "core"
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
override(token2, factory, opts = {}) {
|
|
57
|
+
const existing = this.entries.get(token2);
|
|
58
|
+
if (!existing) {
|
|
59
|
+
throw new FlowCodexError({
|
|
60
|
+
message: `Container: cannot override "${token2.description ?? "unknown"}" \u2014 not bound`,
|
|
61
|
+
code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,
|
|
62
|
+
subsystem: "container",
|
|
63
|
+
context: { token: token2.description }
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
this.entries.set(token2, {
|
|
67
|
+
factory,
|
|
68
|
+
singleton: opts.singleton ?? existing.singleton,
|
|
69
|
+
decorators: existing.decorators,
|
|
70
|
+
owner: opts.owner ?? existing.owner
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
decorate(token2, decorator, owner = "core") {
|
|
74
|
+
const existing = this.entries.get(token2);
|
|
75
|
+
if (!existing) {
|
|
76
|
+
throw new FlowCodexError({
|
|
77
|
+
message: `Container: cannot decorate "${token2.description ?? "unknown"}" \u2014 not bound`,
|
|
78
|
+
code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,
|
|
79
|
+
subsystem: "container",
|
|
80
|
+
context: { token: token2.description }
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
existing.decorators.push(decorator);
|
|
84
|
+
existing.cache = void 0;
|
|
85
|
+
existing.owner = `${existing.owner}+${owner}`;
|
|
86
|
+
}
|
|
87
|
+
resolve(token2) {
|
|
88
|
+
const entry = this.entries.get(token2);
|
|
89
|
+
if (!entry) {
|
|
90
|
+
throw new FlowCodexError({
|
|
91
|
+
message: `Container: token "${token2.description ?? "unknown"}" not bound`,
|
|
92
|
+
code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,
|
|
93
|
+
subsystem: "container",
|
|
94
|
+
context: { token: token2.description }
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
if (entry.singleton && entry.cache !== void 0) {
|
|
98
|
+
return entry.cache;
|
|
99
|
+
}
|
|
100
|
+
if (this.resolving.has(token2)) {
|
|
101
|
+
const cycle = this.describeCycle(token2);
|
|
102
|
+
throw new FlowCodexError({
|
|
103
|
+
message: `Container: circular dependency detected \u2014 ${cycle}`,
|
|
104
|
+
code: ERROR_CODES.CONTAINER_CIRCULAR_DEPENDENCY,
|
|
105
|
+
subsystem: "container",
|
|
106
|
+
context: { token: token2.description, cycle }
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
this.resolving.add(token2);
|
|
110
|
+
try {
|
|
111
|
+
let value = entry.factory(this);
|
|
112
|
+
for (const d of entry.decorators) {
|
|
113
|
+
value = d(value, this);
|
|
114
|
+
}
|
|
115
|
+
if (entry.singleton) {
|
|
116
|
+
entry.cache = value;
|
|
117
|
+
}
|
|
118
|
+
return value;
|
|
119
|
+
} finally {
|
|
120
|
+
this.resolving.delete(token2);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
describeCycle(reentry) {
|
|
124
|
+
const descs = [];
|
|
125
|
+
for (const t2 of this.resolving) {
|
|
126
|
+
descs.push(t2.description ?? "unknown");
|
|
127
|
+
}
|
|
128
|
+
descs.push(reentry.description ?? "unknown");
|
|
129
|
+
return descs.join(" \u2192 ");
|
|
130
|
+
}
|
|
131
|
+
has(token2) {
|
|
132
|
+
return this.entries.has(token2);
|
|
133
|
+
}
|
|
134
|
+
safeResolve(token2) {
|
|
135
|
+
return this.has(token2) ? this.resolve(token2) : void 0;
|
|
136
|
+
}
|
|
137
|
+
ownerOf(token2) {
|
|
138
|
+
return this.entries.get(token2)?.owner;
|
|
139
|
+
}
|
|
140
|
+
unbind(token2) {
|
|
141
|
+
return this.entries.delete(token2);
|
|
142
|
+
}
|
|
143
|
+
clear() {
|
|
144
|
+
this.entries.clear();
|
|
145
|
+
}
|
|
146
|
+
list() {
|
|
147
|
+
return Array.from(this.entries.entries()).map(([token2, entry]) => ({
|
|
148
|
+
token: token2,
|
|
149
|
+
owner: entry.owner
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
inspect(token2) {
|
|
153
|
+
const entry = this.entries.get(token2);
|
|
154
|
+
if (!entry) return null;
|
|
155
|
+
return {
|
|
156
|
+
owner: entry.owner,
|
|
157
|
+
singleton: entry.singleton,
|
|
158
|
+
decoratorCount: entry.decorators.length,
|
|
159
|
+
cached: entry.cache !== void 0
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
function token(description) {
|
|
164
|
+
return Symbol(description);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/kernel/pipeline.ts
|
|
168
|
+
var Pipeline = class {
|
|
169
|
+
chain = [];
|
|
170
|
+
errorHandler;
|
|
171
|
+
setErrorHandler(handler) {
|
|
172
|
+
this.errorHandler = handler;
|
|
173
|
+
return this;
|
|
174
|
+
}
|
|
175
|
+
use(mw) {
|
|
176
|
+
this.ensureUnique(mw.name);
|
|
177
|
+
this.chain.push(mw);
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
prepend(mw) {
|
|
181
|
+
this.ensureUnique(mw.name);
|
|
182
|
+
this.chain.unshift(mw);
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
insertAt(index, mw) {
|
|
186
|
+
this.ensureUnique(mw.name);
|
|
187
|
+
const idx = Math.max(0, Math.min(index, this.chain.length));
|
|
188
|
+
this.chain.splice(idx, 0, mw);
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
insertBefore(target, mw, opts) {
|
|
192
|
+
this.ensureUnique(mw.name);
|
|
193
|
+
const idx = this.indexOf(target, opts?.optional);
|
|
194
|
+
if (idx === -1) return this;
|
|
195
|
+
this.chain.splice(idx, 0, mw);
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
insertAfter(target, mw, opts) {
|
|
199
|
+
this.ensureUnique(mw.name);
|
|
200
|
+
const idx = this.indexOf(target, opts?.optional);
|
|
201
|
+
if (idx === -1) return this;
|
|
202
|
+
this.chain.splice(idx + 1, 0, mw);
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
replace(target, mw, opts) {
|
|
206
|
+
if (mw.name !== target) this.ensureUnique(mw.name);
|
|
207
|
+
const idx = this.indexOf(target, opts?.optional);
|
|
208
|
+
if (idx === -1) return this;
|
|
209
|
+
this.chain[idx] = mw;
|
|
210
|
+
return this;
|
|
211
|
+
}
|
|
212
|
+
remove(name, opts) {
|
|
213
|
+
const idx = this.indexOf(name, opts?.optional);
|
|
214
|
+
if (idx === -1) return this;
|
|
215
|
+
this.chain.splice(idx, 1);
|
|
216
|
+
return this;
|
|
217
|
+
}
|
|
218
|
+
list() {
|
|
219
|
+
return this.chain.map((m) => m.name);
|
|
220
|
+
}
|
|
221
|
+
size() {
|
|
222
|
+
return this.chain.length;
|
|
223
|
+
}
|
|
224
|
+
asReadonly() {
|
|
225
|
+
const self = this;
|
|
226
|
+
return Object.freeze({
|
|
227
|
+
get size() {
|
|
228
|
+
return self.size();
|
|
229
|
+
},
|
|
230
|
+
list() {
|
|
231
|
+
return Object.freeze(self.list());
|
|
232
|
+
},
|
|
233
|
+
run(input) {
|
|
234
|
+
return self.run(input);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
async run(input) {
|
|
239
|
+
let index = -1;
|
|
240
|
+
const chain = this.chain;
|
|
241
|
+
const errorHandler = this.errorHandler;
|
|
242
|
+
const dispatch = async (i, value) => {
|
|
243
|
+
if (i <= index) {
|
|
244
|
+
throw new Error(`Pipeline: next() called multiple times in "${chain[index]?.name}"`);
|
|
245
|
+
}
|
|
246
|
+
index = i;
|
|
247
|
+
const mw = chain[i];
|
|
248
|
+
if (!mw) return value;
|
|
249
|
+
try {
|
|
250
|
+
return await mw.handler(value, (v) => dispatch(i + 1, v));
|
|
251
|
+
} catch (err) {
|
|
252
|
+
if (!errorHandler) throw err;
|
|
253
|
+
const policy = await errorHandler({ middleware: mw.name, owner: mw.owner, err });
|
|
254
|
+
if (policy === "rethrow") throw err;
|
|
255
|
+
return value;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
return dispatch(0, input);
|
|
259
|
+
}
|
|
260
|
+
indexOf(name, optional = false) {
|
|
261
|
+
const idx = this.chain.findIndex((m) => m.name === name);
|
|
262
|
+
if (idx === -1 && !optional) {
|
|
263
|
+
throw new Error(`Pipeline: middleware "${name}" not found`);
|
|
264
|
+
}
|
|
265
|
+
return idx;
|
|
266
|
+
}
|
|
267
|
+
ensureUnique(name) {
|
|
268
|
+
if (this.chain.some((m) => m.name === name)) {
|
|
269
|
+
throw new Error(`Pipeline: middleware "${name}" already registered`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// src/kernel/run-controller.ts
|
|
275
|
+
var RunController = class {
|
|
276
|
+
ctrl = new AbortController();
|
|
277
|
+
hooks = [];
|
|
278
|
+
disposed = false;
|
|
279
|
+
hooksDrained = false;
|
|
280
|
+
errorSink;
|
|
281
|
+
constructor(opts = {}) {
|
|
282
|
+
this.errorSink = opts.errorSink ?? ((err, where) => {
|
|
283
|
+
console.warn(JSON.stringify({
|
|
284
|
+
level: "warn",
|
|
285
|
+
event: "run.cleanup_hook_failed",
|
|
286
|
+
where,
|
|
287
|
+
message: toErrorMessage(err),
|
|
288
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
289
|
+
}));
|
|
290
|
+
});
|
|
291
|
+
if (opts.parentSignal) {
|
|
292
|
+
const parent = opts.parentSignal;
|
|
293
|
+
if (parent.aborted) {
|
|
294
|
+
this.ctrl.abort(parent.reason);
|
|
295
|
+
} else {
|
|
296
|
+
const onParentAbort = () => this.ctrl.abort(parent.reason);
|
|
297
|
+
parent.addEventListener("abort", onParentAbort, { once: true });
|
|
298
|
+
this.onAbort(() => parent.removeEventListener("abort", onParentAbort));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
this.ctrl.signal.addEventListener(
|
|
302
|
+
"abort",
|
|
303
|
+
() => {
|
|
304
|
+
void this.runHooks();
|
|
305
|
+
},
|
|
306
|
+
{ once: true }
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
get signal() {
|
|
310
|
+
return this.ctrl.signal;
|
|
311
|
+
}
|
|
312
|
+
get aborted() {
|
|
313
|
+
return this.ctrl.signal.aborted;
|
|
314
|
+
}
|
|
315
|
+
abort(reason) {
|
|
316
|
+
if (this.ctrl.signal.aborted) return;
|
|
317
|
+
this.ctrl.abort(reason);
|
|
318
|
+
}
|
|
319
|
+
onAbort(fn) {
|
|
320
|
+
this.hooks.push(fn);
|
|
321
|
+
return () => {
|
|
322
|
+
const idx = this.hooks.indexOf(fn);
|
|
323
|
+
if (idx !== -1) this.hooks.splice(idx, 1);
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
async dispose() {
|
|
327
|
+
if (this.disposed) return;
|
|
328
|
+
this.disposed = true;
|
|
329
|
+
await this.runHooks();
|
|
330
|
+
}
|
|
331
|
+
async runHooks() {
|
|
332
|
+
if (this.hooksDrained) return;
|
|
333
|
+
this.hooksDrained = true;
|
|
334
|
+
const snapshot = this.hooks.splice(0, this.hooks.length).reverse();
|
|
335
|
+
for (const hook of snapshot) {
|
|
336
|
+
try {
|
|
337
|
+
await hook();
|
|
338
|
+
} catch (err) {
|
|
339
|
+
this.errorSink(err, "RunController.dispose");
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// src/kernel/tokens.ts
|
|
346
|
+
var t = (name) => Symbol(name);
|
|
347
|
+
var TOKENS = {
|
|
348
|
+
Logger: t("Logger"),
|
|
349
|
+
TokenCounter: t("TokenCounter"),
|
|
350
|
+
SessionStore: t("SessionStore"),
|
|
351
|
+
ConfigStore: t("ConfigStore"),
|
|
352
|
+
ConfigLoader: t("ConfigLoader"),
|
|
353
|
+
PermissionPolicy: t("PermissionPolicy"),
|
|
354
|
+
Compactor: t("Compactor"),
|
|
355
|
+
PathResolver: t("PathResolver"),
|
|
356
|
+
Renderer: t("Renderer"),
|
|
357
|
+
InputReader: t("InputReader"),
|
|
358
|
+
ErrorHandler: t("ErrorHandler"),
|
|
359
|
+
RetryPolicy: t("RetryPolicy"),
|
|
360
|
+
SystemPromptBuilder: t("SystemPromptBuilder"),
|
|
361
|
+
SecretScrubber: t("SecretScrubber"),
|
|
362
|
+
ProviderRunner: t("ProviderRunner")
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
// src/kernel/events.ts
|
|
366
|
+
var EventBus = class {
|
|
367
|
+
listeners = /* @__PURE__ */ new Map();
|
|
368
|
+
wildcards = [];
|
|
369
|
+
logger;
|
|
370
|
+
setLogger(logger) {
|
|
371
|
+
this.logger = logger;
|
|
372
|
+
}
|
|
373
|
+
on(event, fn) {
|
|
374
|
+
let set = this.listeners.get(event);
|
|
375
|
+
if (!set) {
|
|
376
|
+
set = /* @__PURE__ */ new Set();
|
|
377
|
+
this.listeners.set(event, set);
|
|
378
|
+
}
|
|
379
|
+
set.add(fn);
|
|
380
|
+
return () => this.off(event, fn);
|
|
381
|
+
}
|
|
382
|
+
off(event, fn) {
|
|
383
|
+
this.listeners.get(event)?.delete(fn);
|
|
384
|
+
}
|
|
385
|
+
once(event, fn) {
|
|
386
|
+
const wrapper = (payload) => {
|
|
387
|
+
this.off(event, wrapper);
|
|
388
|
+
fn(payload);
|
|
389
|
+
};
|
|
390
|
+
this.on(event, wrapper);
|
|
391
|
+
return () => {
|
|
392
|
+
this.off(event, wrapper);
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
onAny(fn) {
|
|
396
|
+
return this.onPattern("*", fn);
|
|
397
|
+
}
|
|
398
|
+
onPattern(pattern, fn) {
|
|
399
|
+
const match = makePatternMatcher(pattern);
|
|
400
|
+
const entry = { match, fn };
|
|
401
|
+
this.wildcards.push(entry);
|
|
402
|
+
return () => {
|
|
403
|
+
const idx = this.wildcards.indexOf(entry);
|
|
404
|
+
if (idx >= 0) this.wildcards.splice(idx, 1);
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
onRegex(regex, fn) {
|
|
408
|
+
const entry = { match: (e) => regex.test(e), fn };
|
|
409
|
+
this.wildcards.push(entry);
|
|
410
|
+
return () => {
|
|
411
|
+
const idx = this.wildcards.indexOf(entry);
|
|
412
|
+
if (idx >= 0) this.wildcards.splice(idx, 1);
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
emit(event, payload) {
|
|
416
|
+
const set = this.listeners.get(event);
|
|
417
|
+
if (set) {
|
|
418
|
+
for (const fn of set) {
|
|
419
|
+
try {
|
|
420
|
+
fn(payload);
|
|
421
|
+
} catch (err) {
|
|
422
|
+
this.logger?.error(`EventBus listener for "${event}" threw`, err);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (this.wildcards.length > 0) {
|
|
427
|
+
const name = event;
|
|
428
|
+
const snapshot = this.wildcards.slice();
|
|
429
|
+
for (const { match, fn } of snapshot) {
|
|
430
|
+
if (!match(name)) continue;
|
|
431
|
+
try {
|
|
432
|
+
fn(name, payload);
|
|
433
|
+
} catch (err) {
|
|
434
|
+
this.logger?.error(`EventBus wildcard listener for "${name}" threw`, err);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
emitCustom(event, payload) {
|
|
440
|
+
if (this.wildcards.length === 0) return;
|
|
441
|
+
const snapshot = this.wildcards.slice();
|
|
442
|
+
for (const { match, fn } of snapshot) {
|
|
443
|
+
if (!match(event)) continue;
|
|
444
|
+
try {
|
|
445
|
+
fn(event, payload);
|
|
446
|
+
} catch (err) {
|
|
447
|
+
this.logger?.error(`EventBus wildcard listener for "${event}" threw`, err);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
clear() {
|
|
452
|
+
this.listeners.clear();
|
|
453
|
+
this.wildcards.length = 0;
|
|
454
|
+
}
|
|
455
|
+
listenerCount(event) {
|
|
456
|
+
if (event !== void 0) return this.listeners.get(event)?.size ?? 0;
|
|
457
|
+
let total = 0;
|
|
458
|
+
for (const set of this.listeners.values()) total += set.size;
|
|
459
|
+
return total;
|
|
460
|
+
}
|
|
461
|
+
wildcardCount() {
|
|
462
|
+
return this.wildcards.length;
|
|
463
|
+
}
|
|
464
|
+
hasListenerFor(event) {
|
|
465
|
+
if ((this.listeners.get(event)?.size ?? 0) > 0) return true;
|
|
466
|
+
return this.wildcards.some((w) => w.match(event));
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
var ScopedEventBus = class extends EventBus {
|
|
470
|
+
registrations = /* @__PURE__ */ new Map();
|
|
471
|
+
nextKey = 0;
|
|
472
|
+
on(event, fn) {
|
|
473
|
+
const key = this.nextKey++;
|
|
474
|
+
const unsub = super.on(event, fn);
|
|
475
|
+
this.registrations.set(key, unsub);
|
|
476
|
+
return () => {
|
|
477
|
+
this.registrations.delete(key);
|
|
478
|
+
unsub();
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
once(event, fn) {
|
|
482
|
+
const key = this.nextKey++;
|
|
483
|
+
const wrapper = (payload) => {
|
|
484
|
+
EventBus.prototype.off.call(this, event, wrapper);
|
|
485
|
+
this.registrations.delete(key);
|
|
486
|
+
fn(payload);
|
|
487
|
+
};
|
|
488
|
+
EventBus.prototype.on.call(this, event, wrapper);
|
|
489
|
+
const unsub = () => {
|
|
490
|
+
this.registrations.delete(key);
|
|
491
|
+
EventBus.prototype.off.call(this, event, wrapper);
|
|
492
|
+
};
|
|
493
|
+
this.registrations.set(key, unsub);
|
|
494
|
+
return unsub;
|
|
495
|
+
}
|
|
496
|
+
onAny(fn) {
|
|
497
|
+
const key = this.nextKey++;
|
|
498
|
+
const unsub = EventBus.prototype.onPattern.call(this, "*", fn);
|
|
499
|
+
this.registrations.set(key, unsub);
|
|
500
|
+
return () => {
|
|
501
|
+
this.registrations.delete(key);
|
|
502
|
+
unsub();
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
onPattern(pattern, fn) {
|
|
506
|
+
const key = this.nextKey++;
|
|
507
|
+
const unsub = super.onPattern(pattern, fn);
|
|
508
|
+
this.registrations.set(key, unsub);
|
|
509
|
+
return () => {
|
|
510
|
+
this.registrations.delete(key);
|
|
511
|
+
unsub();
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
onRegex(regex, fn) {
|
|
515
|
+
const key = this.nextKey++;
|
|
516
|
+
const unsub = super.onRegex(regex, fn);
|
|
517
|
+
this.registrations.set(key, unsub);
|
|
518
|
+
return () => {
|
|
519
|
+
this.registrations.delete(key);
|
|
520
|
+
unsub();
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
teardown() {
|
|
524
|
+
for (const unsub of this.registrations.values()) {
|
|
525
|
+
try {
|
|
526
|
+
unsub();
|
|
527
|
+
} catch {
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
this.registrations.clear();
|
|
531
|
+
this.clear();
|
|
532
|
+
}
|
|
533
|
+
[Symbol.dispose]() {
|
|
534
|
+
this.teardown();
|
|
535
|
+
}
|
|
536
|
+
get scopedListenerCount() {
|
|
537
|
+
return this.registrations.size;
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
function makePatternMatcher(pattern) {
|
|
541
|
+
if (pattern === "*") return () => true;
|
|
542
|
+
if (pattern.endsWith(".*")) {
|
|
543
|
+
const prefix = pattern.slice(0, -2);
|
|
544
|
+
return (e) => e.startsWith(`${prefix}.`);
|
|
545
|
+
}
|
|
546
|
+
return (e) => e === pattern;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
export { Container, EventBus, Pipeline, RunController, ScopedEventBus, TOKENS, token };
|
|
550
|
+
//# sourceMappingURL=index.js.map
|
|
551
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/error.ts","../../src/types/errors.ts","../../src/kernel/container.ts","../../src/kernel/pipeline.ts","../../src/kernel/run-controller.ts","../../src/kernel/tokens.ts","../../src/kernel/events.ts"],"names":["token","t"],"mappings":"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","file":"index.js","sourcesContent":["export function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}","import { toErrorMessage } from '../utils/error.js';\n\nexport const ERROR_CODES = {\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n PROVIDER_STREAM_HANG: 'PROVIDER_STREAM_HANG',\n PROVIDER_UNSUPPORTED: 'PROVIDER_UNSUPPORTED',\n PROVIDER_NOT_WIRED: 'PROVIDER_NOT_WIRED',\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n AGENT_BUDGET_EXCEEDED: 'AGENT_BUDGET_EXCEEDED',\n COMPACTION_FAILED: 'COMPACTION_FAILED',\n PROMPT_BUDGET_EXCEEDED: 'PROMPT_BUDGET_EXCEEDED',\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n FS_PATH_ESCAPE: 'FS_PATH_ESCAPE',\n SSRF_BLOCKED: 'SSRF_BLOCKED',\n WEBFETCH_FAILED: 'WEBFETCH_FAILED',\n WEBSEARCH_FAILED: 'WEBSEARCH_FAILED',\n DIFF_FILE_NOT_FOUND: 'DIFF_FILE_NOT_FOUND',\n PATCH_HUNK_FAILED: 'PATCH_HUNK_FAILED',\n DEV_TOOL_NOT_FOUND: 'DEV_TOOL_NOT_FOUND',\n REPLAY_MISS: 'REPLAY_MISS',\n SESSION_EXPORT_FAILED: 'SESSION_EXPORT_FAILED',\n PROVIDER_UNSUPPORTED_MODALITY: 'PROVIDER_UNSUPPORTED_MODALITY',\n TOOL_BATCH_FAILED: 'TOOL_BATCH_FAILED',\n TOOL_BATCH_TOO_LARGE: 'TOOL_BATCH_TOO_LARGE',\n TOOL_NESTED_BATCH: 'TOOL_NESTED_BATCH',\n TOOL_INVALID_ATTACHMENT: 'TOOL_INVALID_ATTACHMENT',\n TOOL_UNSUPPORTED_PROVIDER: 'TOOL_UNSUPPORTED_PROVIDER',\n AGENT_STRUCTURED_OUTPUT_NOT_PRODUCED: 'AGENT_STRUCTURED_OUTPUT_NOT_PRODUCED',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'container'\n | 'fs'\n | 'general';\n\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\nexport class FlowCodexError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'FlowCodexError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\nexport class ToolError extends FlowCodexError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\nexport class ConfigError extends FlowCodexError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\nexport class PluginError extends FlowCodexError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\nexport class AgentError extends FlowCodexError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'AGENT_ITERATION_LIMIT'\n | 'AGENT_CONTEXT_OVERFLOW'\n | 'AGENT_ABORTED'\n | 'AGENT_RUN_FAILED'\n | 'AGENT_BUDGET_EXCEEDED'\n | 'COMPACTION_FAILED'\n | 'PROMPT_BUDGET_EXCEEDED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\nexport class PermissionError extends FlowCodexError {\n readonly tool: string;\n readonly pattern?: string | undefined;\n readonly source: string;\n\n constructor(opts: {\n message: string;\n tool: string;\n pattern?: string | undefined;\n source: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.TOOL_PERMISSION_DENIED,\n subsystem: 'tool',\n recoverable: false,\n context: { tool: opts.tool, pattern: opts.pattern, source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PermissionError';\n this.tool = opts.tool;\n this.pattern = opts.pattern;\n this.source = opts.source;\n }\n}\n\nexport function toFlowCodexError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): FlowCodexError {\n if (err instanceof FlowCodexError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\nexport class SessionError extends FlowCodexError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\nexport class FsError extends FlowCodexError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'FS_READ_FAILED'\n | 'FS_WRITE_FAILED'\n | 'FS_MKDIR_FAILED'\n | 'FS_DELETE_FAILED'\n | 'FS_ATOMIC_WRITE_FAILED'\n | 'FS_PATH_ESCAPE'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\nexport function isFlowCodexError(err: unknown): err is FlowCodexError {\n return err instanceof FlowCodexError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isPermissionError(err: unknown): err is PermissionError {\n return err instanceof PermissionError;\n}","import { FlowCodexError, ERROR_CODES } from '../types/errors.js';\n\nexport type Token<T> = symbol & { readonly __type?: T };\nexport type Factory<T> = (c: Container) => T;\nexport type Decorator<T> = (inner: T, c: Container) => T;\n\ninterface Entry<T = unknown> {\n factory: Factory<T>;\n singleton: boolean;\n decorators: Decorator<T>[];\n cache?: T | undefined;\n owner: string;\n}\n\nexport interface BindOptions {\n singleton?: boolean | undefined;\n owner?: string | undefined;\n}\n\nexport class Container {\n private readonly entries = new Map<symbol, Entry>();\n private readonly resolving = new Set<symbol>();\n\n bind<T>(token: Token<T>, factory: Factory<T>, opts: BindOptions = {}): void {\n if (this.entries.has(token)) {\n throw new FlowCodexError({\n message: `Container: token \"${token.description ?? 'unknown'}\" already bound`,\n code: ERROR_CODES.CONTAINER_TOKEN_ALREADY_BOUND,\n subsystem: 'container',\n context: { token: token.description },\n });\n }\n this.entries.set(token, {\n factory: factory as Factory<unknown>,\n singleton: opts.singleton ?? true,\n decorators: [],\n owner: opts.owner ?? 'core',\n });\n }\n\n override<T>(token: Token<T>, factory: Factory<T>, opts: BindOptions = {}): void {\n const existing = this.entries.get(token);\n if (!existing) {\n throw new FlowCodexError({\n message: `Container: cannot override \"${token.description ?? 'unknown'}\" — not bound`,\n code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,\n subsystem: 'container',\n context: { token: token.description },\n });\n }\n this.entries.set(token, {\n factory: factory as Factory<unknown>,\n singleton: opts.singleton ?? existing.singleton,\n decorators: existing.decorators,\n owner: opts.owner ?? existing.owner,\n });\n }\n\n decorate<T>(token: Token<T>, decorator: Decorator<T>, owner = 'core'): void {\n const existing = this.entries.get(token);\n if (!existing) {\n throw new FlowCodexError({\n message: `Container: cannot decorate \"${token.description ?? 'unknown'}\" — not bound`,\n code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,\n subsystem: 'container',\n context: { token: token.description },\n });\n }\n existing.decorators.push(decorator as Decorator<unknown>);\n existing.cache = undefined;\n existing.owner = `${existing.owner}+${owner}`;\n }\n\n resolve<T>(token: Token<T>): T {\n const entry = this.entries.get(token);\n if (!entry) {\n throw new FlowCodexError({\n message: `Container: token \"${token.description ?? 'unknown'}\" not bound`,\n code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,\n subsystem: 'container',\n context: { token: token.description },\n });\n }\n if (entry.singleton && entry.cache !== undefined) {\n return entry.cache as T;\n }\n if (this.resolving.has(token)) {\n const cycle = this.describeCycle(token);\n throw new FlowCodexError({\n message: `Container: circular dependency detected — ${cycle}`,\n code: ERROR_CODES.CONTAINER_CIRCULAR_DEPENDENCY,\n subsystem: 'container',\n context: { token: token.description, cycle },\n });\n }\n this.resolving.add(token);\n try {\n let value: unknown = entry.factory(this);\n for (const d of entry.decorators) {\n value = d(value, this);\n }\n if (entry.singleton) {\n entry.cache = value;\n }\n return value as T;\n } finally {\n this.resolving.delete(token);\n }\n }\n\n private describeCycle(reentry: symbol): string {\n const descs: string[] = [];\n for (const t of this.resolving) {\n descs.push(t.description ?? 'unknown');\n }\n descs.push(reentry.description ?? 'unknown');\n return descs.join(' → ');\n }\n\n has<T>(token: Token<T>): boolean {\n return this.entries.has(token);\n }\n\n safeResolve<T>(token: Token<T>): T | undefined {\n return this.has(token) ? this.resolve(token) : undefined;\n }\n\n ownerOf<T>(token: Token<T>): string | undefined {\n return this.entries.get(token)?.owner;\n }\n\n unbind<T>(token: Token<T>): boolean {\n return this.entries.delete(token);\n }\n\n clear(): void {\n this.entries.clear();\n }\n\n list(): Array<{ token: symbol; owner: string }> {\n return Array.from(this.entries.entries()).map(([token, entry]) => ({\n token,\n owner: entry.owner,\n }));\n }\n\n inspect<T>(token: Token<T>): {\n owner: string;\n singleton: boolean;\n decoratorCount: number;\n cached: boolean;\n } | null {\n const entry = this.entries.get(token);\n if (!entry) return null;\n return {\n owner: entry.owner,\n singleton: entry.singleton,\n decoratorCount: entry.decorators.length,\n cached: entry.cache !== undefined,\n };\n }\n}\n\nexport function token<T>(description: string): Token<T> {\n return Symbol(description) as Token<T>;\n}","export type NextFn<T> = (value: T) => Promise<T>;\nexport type MiddlewareHandler<T> = (value: T, next: NextFn<T>) => Promise<T>;\n\nexport type PipelineErrorPolicy = 'rethrow' | 'swallow';\n\nexport interface PipelineErrorEvent {\n middleware: string;\n owner?: string | undefined;\n err: unknown;\n}\n\nexport type PipelineErrorHandler = (\n ev: PipelineErrorEvent,\n) => PipelineErrorPolicy | Promise<PipelineErrorPolicy>;\n\nexport interface Middleware<T> {\n name: string;\n handler: MiddlewareHandler<T>;\n owner?: string | undefined;\n}\n\nexport interface PipelineOptions {\n optional?: boolean | undefined;\n}\n\nexport interface ReadonlyPipeline<T> {\n readonly size: number;\n list(): readonly string[];\n run(input: T): Promise<T>;\n}\n\nexport class Pipeline<T> {\n private readonly chain: Middleware<T>[] = [];\n private errorHandler?: PipelineErrorHandler | undefined;\n\n setErrorHandler(handler: PipelineErrorHandler | undefined): this {\n this.errorHandler = handler;\n return this;\n }\n\n use(mw: Middleware<T> | Middleware<unknown>): this {\n this.ensureUnique(mw.name);\n this.chain.push(mw as Middleware<T>);\n return this;\n }\n\n prepend(mw: Middleware<T>): this {\n this.ensureUnique(mw.name);\n this.chain.unshift(mw);\n return this;\n }\n\n insertAt(index: number, mw: Middleware<T>): this {\n this.ensureUnique(mw.name);\n const idx = Math.max(0, Math.min(index, this.chain.length));\n this.chain.splice(idx, 0, mw);\n return this;\n }\n\n insertBefore(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\n this.ensureUnique(mw.name);\n const idx = this.indexOf(target, opts?.optional);\n if (idx === -1) return this;\n this.chain.splice(idx, 0, mw);\n return this;\n }\n\n insertAfter(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\n this.ensureUnique(mw.name);\n const idx = this.indexOf(target, opts?.optional);\n if (idx === -1) return this;\n this.chain.splice(idx + 1, 0, mw);\n return this;\n }\n\n replace(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\n if (mw.name !== target) this.ensureUnique(mw.name);\n const idx = this.indexOf(target, opts?.optional);\n if (idx === -1) return this;\n this.chain[idx] = mw;\n return this;\n }\n\n remove(name: string, opts?: PipelineOptions): this {\n const idx = this.indexOf(name, opts?.optional);\n if (idx === -1) return this;\n this.chain.splice(idx, 1);\n return this;\n }\n\n list(): readonly string[] {\n return this.chain.map((m) => m.name);\n }\n\n size(): number {\n return this.chain.length;\n }\n\n asReadonly(): ReadonlyPipeline<T> {\n const self = this;\n return Object.freeze({\n get size() {\n return self.size();\n },\n list() {\n return Object.freeze(self.list());\n },\n run(input: T) {\n return self.run(input);\n },\n });\n }\n\n async run(input: T): Promise<T> {\n let index = -1;\n const chain = this.chain;\n const errorHandler = this.errorHandler;\n\n const dispatch = async (i: number, value: T): Promise<T> => {\n if (i <= index) {\n throw new Error(`Pipeline: next() called multiple times in \"${chain[index]?.name}\"`);\n }\n index = i;\n const mw = chain[i];\n if (!mw) return value;\n try {\n return await mw.handler(value, (v) => dispatch(i + 1, v));\n } catch (err) {\n if (!errorHandler) throw err;\n const policy = await errorHandler({ middleware: mw.name, owner: mw.owner, err });\n if (policy === 'rethrow') throw err;\n return value;\n }\n };\n\n return dispatch(0, input);\n }\n\n private indexOf(name: string, optional = false): number {\n const idx = this.chain.findIndex((m) => m.name === name);\n if (idx === -1 && !optional) {\n throw new Error(`Pipeline: middleware \"${name}\" not found`);\n }\n return idx;\n }\n\n private ensureUnique(name: string): void {\n if (this.chain.some((m) => m.name === name)) {\n throw new Error(`Pipeline: middleware \"${name}\" already registered`);\n }\n }\n}","import { toErrorMessage } from '../utils/error.js';\n\nexport interface RunControllerOptions {\n parentSignal?: AbortSignal | undefined;\n errorSink?: (err: unknown, where: string) => void;\n}\n\nexport class RunController {\n private readonly ctrl = new AbortController();\n private readonly hooks: Array<() => void | Promise<void>> = [];\n private disposed = false;\n private hooksDrained = false;\n private readonly errorSink: (err: unknown, where: string) => void;\n\n constructor(opts: RunControllerOptions = {}) {\n this.errorSink =\n opts.errorSink ??\n ((err, where) => {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'run.cleanup_hook_failed',\n where,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n });\n if (opts.parentSignal) {\n const parent = opts.parentSignal;\n if (parent.aborted) {\n this.ctrl.abort(parent.reason);\n } else {\n const onParentAbort = () => this.ctrl.abort(parent.reason);\n parent.addEventListener('abort', onParentAbort, { once: true });\n this.onAbort(() => parent.removeEventListener('abort', onParentAbort));\n }\n }\n this.ctrl.signal.addEventListener(\n 'abort',\n () => {\n void this.runHooks();\n },\n { once: true },\n );\n }\n\n get signal(): AbortSignal {\n return this.ctrl.signal;\n }\n\n get aborted(): boolean {\n return this.ctrl.signal.aborted;\n }\n\n abort(reason?: unknown): void {\n if (this.ctrl.signal.aborted) return;\n this.ctrl.abort(reason);\n }\n\n onAbort(fn: () => void | Promise<void>): () => void {\n this.hooks.push(fn);\n return () => {\n const idx = this.hooks.indexOf(fn);\n if (idx !== -1) this.hooks.splice(idx, 1);\n };\n }\n\n async dispose(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n await this.runHooks();\n }\n\n private async runHooks(): Promise<void> {\n if (this.hooksDrained) return;\n this.hooksDrained = true;\n const snapshot = this.hooks.splice(0, this.hooks.length).reverse();\n for (const hook of snapshot) {\n try {\n await hook();\n } catch (err) {\n this.errorSink(err, 'RunController.dispose');\n }\n }\n }\n}","import type { Token } from './container.js';\n\nconst t = <T>(name: string): Token<T> => Symbol(name) as Token<T>;\n\nexport const TOKENS = {\n Logger: t<unknown>('Logger'),\n TokenCounter: t<unknown>('TokenCounter'),\n SessionStore: t<unknown>('SessionStore'),\n ConfigStore: t<unknown>('ConfigStore'),\n ConfigLoader: t<unknown>('ConfigLoader'),\n PermissionPolicy: t<unknown>('PermissionPolicy'),\n Compactor: t<unknown>('Compactor'),\n PathResolver: t<unknown>('PathResolver'),\n Renderer: t<unknown>('Renderer'),\n InputReader: t<unknown>('InputReader'),\n ErrorHandler: t<unknown>('ErrorHandler'),\n RetryPolicy: t<unknown>('RetryPolicy'),\n SystemPromptBuilder: t<unknown>('SystemPromptBuilder'),\n SecretScrubber: t<unknown>('SecretScrubber'),\n ProviderRunner: t<unknown>('ProviderRunner'),\n} as const;","import type { SessionSummary } from '../session/types.js';\n\nexport interface EventMap {\n 'session.started': { id: string };\n 'session.ended': { id: string; usage: unknown };\n 'session.damaged': { sessionId: string; detail: string };\n 'session.resumed': { sessionId: string; forkedFrom?: string | undefined };\n 'session.summary_written': { sessionId: string; summary: SessionSummary };\n\n 'iteration.started': { index: number };\n 'iteration.completed': { index: number };\n 'iteration.limit_reached': {\n currentIterations: number;\n currentLimit: number;\n grant: (extraIterations: number) => void;\n deny: () => void;\n };\n\n 'provider.response': { usage: unknown; stopReason: string };\n 'provider.text_delta': { text: string };\n 'provider.thinking_delta': { text: string };\n 'provider.tool_use_start': { id: string; name: string };\n 'provider.tool_use_input_delta': { id: string; partialJson: string };\n 'provider.tool_use_stop': { id: string; name: string };\n 'provider.stream_error': { eventType: string; msg: string };\n 'provider.retry': {\n providerId: string;\n attempt: number;\n delayMs: number;\n status: number;\n description: string;\n };\n 'provider.error': {\n providerId: string;\n status: number;\n description: string;\n retryable: boolean;\n };\n 'provider.fallback': {\n providerId: string;\n from: string;\n to: string;\n reason: string;\n status: number;\n };\n 'provider.fallback_skipped': {\n providerId: string;\n reason: 'no_api_key' | 'unsupported_family' | 'not_in_catalog';\n };\n\n 'tool.started': { name: string; id: string; input?: unknown | undefined };\n 'tool.progress': { name: string; id: string; event: unknown };\n 'tool.confirm_needed': {\n tool: unknown;\n input: unknown;\n toolUseId: string;\n suggestedPattern: string;\n resolve: (decision: 'yes' | 'no' | 'always' | 'deny') => void;\n };\n 'tool.executed': {\n id?: string | undefined;\n name: string;\n durationMs: number;\n ok: boolean;\n input?: unknown | undefined;\n output?: string | undefined;\n outputBytes?: number | undefined;\n };\n 'tool.tier_filtered': { total: number; kept: number };\n 'tool.batch_started': { count: number; names: string[] };\n 'tool.batch_completed': { count: number; succeeded: number; failed: number; durationMs: number };\n 'provider.structured_output': { name: string; valid: boolean };\n 'provider.modality_rejected': { provider: string; model: string; modality: string };\n\n 'ctx.pct': { load: number; tokens: number; maxContext: number };\n 'ctx.max_context': { providerId: string; modelId: string; maxContext: number };\n 'token.threshold': { used: number; limit: number };\n 'token.accounted': {\n usage: unknown;\n cost: { input: number; output: number; total: number };\n };\n 'token.cost_estimate_unavailable': { model: string };\n\n 'ssrf.blocked': { url: string; ip: string; reason: string };\n\n 'permission.persisted': {\n action: 'allow' | 'deny';\n tool: string;\n pattern: string;\n scope: 'session' | 'trust';\n };\n\n 'compaction.fired': {\n before: number;\n after: number;\n level: 'soft' | 'hard';\n aggressive: boolean;\n };\n\n 'compaction.failed': {\n reason: string;\n attemptedLevel: 'soft' | 'hard';\n };\n\n 'error': { err: Error; phase: string };\n}\n\nexport type EventName = keyof EventMap;\nexport type Listener<E extends EventName> = (payload: EventMap[E]) => void;\n\nexport interface EventLogger {\n error(msg: string, ctx?: unknown): void | undefined;\n}\n\nexport class EventBus {\n private readonly listeners = new Map<EventName, Set<Listener<EventName>>>();\n private readonly wildcards: Array<{\n match: (event: string) => boolean;\n fn: (event: string, payload: unknown) => void;\n }> = [];\n private logger?: EventLogger | undefined;\n\n setLogger(logger: EventLogger): void {\n this.logger = logger;\n }\n\n on<E extends EventName>(event: E, fn: Listener<E>): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(fn as Listener<EventName>);\n return () => this.off(event, fn);\n }\n\n off<E extends EventName>(event: E, fn: Listener<E>): void {\n this.listeners.get(event)?.delete(fn as Listener<EventName>);\n }\n\n once<E extends EventName>(event: E, fn: Listener<E>): () => void {\n const wrapper: Listener<E> = (payload) => {\n this.off(event, wrapper as Listener<EventName>);\n (fn as Listener<E>)(payload);\n };\n this.on(event, wrapper as Listener<E>);\n return () => {\n this.off(event, wrapper as Listener<EventName>);\n };\n }\n\n onAny(fn: (event: string, payload: unknown) => void): () => void {\n return this.onPattern('*', fn);\n }\n\n onPattern(pattern: string, fn: (event: string, payload: unknown) => void): () => void {\n const match = makePatternMatcher(pattern);\n const entry = { match, fn };\n this.wildcards.push(entry);\n return () => {\n const idx = this.wildcards.indexOf(entry);\n if (idx >= 0) this.wildcards.splice(idx, 1);\n };\n }\n\n onRegex(regex: RegExp, fn: (event: string, payload: unknown) => void): () => void {\n const entry = { match: (e: string) => regex.test(e), fn };\n this.wildcards.push(entry);\n return () => {\n const idx = this.wildcards.indexOf(entry);\n if (idx >= 0) this.wildcards.splice(idx, 1);\n };\n }\n\n emit<E extends EventName>(event: E, payload: EventMap[E]): void {\n const set = this.listeners.get(event);\n if (set) {\n for (const fn of set) {\n try {\n (fn as Listener<E>)(payload);\n } catch (err) {\n this.logger?.error(`EventBus listener for \"${event}\" threw`, err);\n }\n }\n }\n if (this.wildcards.length > 0) {\n const name = event as string;\n const snapshot = this.wildcards.slice();\n for (const { match, fn } of snapshot) {\n if (!match(name)) continue;\n try {\n fn(name, payload);\n } catch (err) {\n this.logger?.error(`EventBus wildcard listener for \"${name}\" threw`, err);\n }\n }\n }\n }\n\n emitCustom(event: string, payload: unknown): void {\n if (this.wildcards.length === 0) return;\n const snapshot = this.wildcards.slice();\n for (const { match, fn } of snapshot) {\n if (!match(event)) continue;\n try {\n fn(event, payload);\n } catch (err) {\n this.logger?.error(`EventBus wildcard listener for \"${event}\" threw`, err);\n }\n }\n }\n\n clear(): void {\n this.listeners.clear();\n this.wildcards.length = 0;\n }\n\n listenerCount(event?: EventName): number {\n if (event !== undefined) return this.listeners.get(event)?.size ?? 0;\n let total = 0;\n for (const set of this.listeners.values()) total += set.size;\n return total;\n }\n\n wildcardCount(): number {\n return this.wildcards.length;\n }\n\n hasListenerFor(event: string): boolean {\n if ((this.listeners.get(event as EventName)?.size ?? 0) > 0) return true;\n return this.wildcards.some((w) => w.match(event));\n }\n}\n\nexport class ScopedEventBus extends EventBus {\n private readonly registrations = new Map<number, () => void>();\n private nextKey = 0;\n\n override on<E extends EventName>(event: E, fn: Listener<E>): () => void {\n const key = this.nextKey++;\n const unsub = super.on(event, fn);\n this.registrations.set(key, unsub);\n return () => {\n this.registrations.delete(key);\n unsub();\n };\n }\n\n override once<E extends EventName>(event: E, fn: Listener<E>): () => void {\n const key = this.nextKey++;\n const wrapper: Listener<E> = (payload) => {\n EventBus.prototype.off.call(this, event, wrapper as Listener<EventName>);\n this.registrations.delete(key);\n (fn as Listener<E>)(payload);\n };\n EventBus.prototype.on.call(this, event, wrapper as Listener<EventName>);\n const unsub = () => {\n this.registrations.delete(key);\n EventBus.prototype.off.call(this, event, wrapper as Listener<EventName>);\n };\n this.registrations.set(key, unsub);\n return unsub;\n }\n\n override onAny(fn: (event: string, payload: unknown) => void): () => void {\n const key = this.nextKey++;\n const unsub = EventBus.prototype.onPattern.call(this, '*', fn);\n this.registrations.set(key, unsub);\n return () => {\n this.registrations.delete(key);\n unsub();\n };\n }\n\n override onPattern(pattern: string, fn: (event: string, payload: unknown) => void): () => void {\n const key = this.nextKey++;\n const unsub = super.onPattern(pattern, fn);\n this.registrations.set(key, unsub);\n return () => {\n this.registrations.delete(key);\n unsub();\n };\n }\n\n override onRegex(regex: RegExp, fn: (event: string, payload: unknown) => void): () => void {\n const key = this.nextKey++;\n const unsub = super.onRegex(regex, fn);\n this.registrations.set(key, unsub);\n return () => {\n this.registrations.delete(key);\n unsub();\n };\n }\n\n teardown(): void {\n for (const unsub of this.registrations.values()) {\n try {\n unsub();\n } catch {\n // best effort\n }\n }\n this.registrations.clear();\n this.clear();\n }\n\n [Symbol.dispose](): void {\n this.teardown();\n }\n\n get scopedListenerCount(): number {\n return this.registrations.size;\n }\n}\n\nfunction makePatternMatcher(pattern: string): (event: string) => boolean {\n if (pattern === '*') return () => true;\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2);\n return (e: string) => e.startsWith(`${prefix}.`);\n }\n return (e: string) => e === pattern;\n}"]}
|