@framers/agentos 0.12.4 → 0.12.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/api/generateText.d.ts +12 -0
  2. package/dist/api/generateText.d.ts.map +1 -1
  3. package/dist/api/generateText.js +20 -6
  4. package/dist/api/generateText.js.map +1 -1
  5. package/dist/api/streamText.d.ts.map +1 -1
  6. package/dist/api/streamText.js +6 -3
  7. package/dist/api/streamText.js.map +1 -1
  8. package/dist/cognition/emergent/ComposableToolBuilder.d.ts.map +1 -1
  9. package/dist/cognition/emergent/ComposableToolBuilder.js +16 -8
  10. package/dist/cognition/emergent/ComposableToolBuilder.js.map +1 -1
  11. package/dist/cognition/emergent/EffectsStore.d.ts +58 -0
  12. package/dist/cognition/emergent/EffectsStore.d.ts.map +1 -0
  13. package/dist/cognition/emergent/EffectsStore.js +96 -0
  14. package/dist/cognition/emergent/EffectsStore.js.map +1 -0
  15. package/dist/cognition/emergent/EmergentCapabilityEngine.d.ts +22 -2
  16. package/dist/cognition/emergent/EmergentCapabilityEngine.d.ts.map +1 -1
  17. package/dist/cognition/emergent/EmergentCapabilityEngine.js +128 -19
  18. package/dist/cognition/emergent/EmergentCapabilityEngine.js.map +1 -1
  19. package/dist/cognition/emergent/EmergentJudge.d.ts +1 -1
  20. package/dist/cognition/emergent/EmergentJudge.d.ts.map +1 -1
  21. package/dist/cognition/emergent/EmergentToolRegistry.d.ts +12 -3
  22. package/dist/cognition/emergent/EmergentToolRegistry.d.ts.map +1 -1
  23. package/dist/cognition/emergent/EmergentToolRegistry.js +51 -4
  24. package/dist/cognition/emergent/EmergentToolRegistry.js.map +1 -1
  25. package/dist/cognition/emergent/ForgeToolMetaTool.d.ts.map +1 -1
  26. package/dist/cognition/emergent/ForgeToolMetaTool.js +4 -1
  27. package/dist/cognition/emergent/ForgeToolMetaTool.js.map +1 -1
  28. package/dist/cognition/emergent/SandboxedToolForge.d.ts +55 -51
  29. package/dist/cognition/emergent/SandboxedToolForge.d.ts.map +1 -1
  30. package/dist/cognition/emergent/SandboxedToolForge.js +103 -109
  31. package/dist/cognition/emergent/SandboxedToolForge.js.map +1 -1
  32. package/dist/cognition/emergent/ToolPackage.d.ts +2 -2
  33. package/dist/cognition/emergent/ToolPackage.d.ts.map +1 -1
  34. package/dist/cognition/emergent/broker/CapabilityBroker.d.ts +58 -0
  35. package/dist/cognition/emergent/broker/CapabilityBroker.d.ts.map +1 -0
  36. package/dist/cognition/emergent/broker/CapabilityBroker.js +288 -0
  37. package/dist/cognition/emergent/broker/CapabilityBroker.js.map +1 -0
  38. package/dist/cognition/emergent/broker/fetch.d.ts +44 -0
  39. package/dist/cognition/emergent/broker/fetch.d.ts.map +1 -0
  40. package/dist/cognition/emergent/broker/fetch.js +197 -0
  41. package/dist/cognition/emergent/broker/fetch.js.map +1 -0
  42. package/dist/cognition/emergent/broker/fs-read.d.ts +63 -0
  43. package/dist/cognition/emergent/broker/fs-read.d.ts.map +1 -0
  44. package/dist/cognition/emergent/broker/fs-read.js +133 -0
  45. package/dist/cognition/emergent/broker/fs-read.js.map +1 -0
  46. package/dist/cognition/emergent/broker/refusal.d.ts +10 -0
  47. package/dist/cognition/emergent/broker/refusal.d.ts.map +1 -0
  48. package/dist/cognition/emergent/broker/refusal.js +13 -0
  49. package/dist/cognition/emergent/broker/refusal.js.map +1 -0
  50. package/dist/cognition/emergent/ceiling.d.ts +75 -0
  51. package/dist/cognition/emergent/ceiling.d.ts.map +1 -0
  52. package/dist/cognition/emergent/ceiling.js +166 -0
  53. package/dist/cognition/emergent/ceiling.js.map +1 -0
  54. package/dist/cognition/emergent/index.d.ts +2 -0
  55. package/dist/cognition/emergent/index.d.ts.map +1 -1
  56. package/dist/cognition/emergent/index.js +1 -0
  57. package/dist/cognition/emergent/index.js.map +1 -1
  58. package/dist/cognition/emergent/types.d.ts +75 -2
  59. package/dist/cognition/emergent/types.d.ts.map +1 -1
  60. package/dist/cognition/emergent/types.js.map +1 -1
  61. package/dist/cognition/substrate/IGMI.d.ts +3 -0
  62. package/dist/cognition/substrate/IGMI.d.ts.map +1 -1
  63. package/dist/cognition/substrate/IGMI.js.map +1 -1
  64. package/dist/core/llm/providers/implementations/OpenRouterProvider.d.ts.map +1 -1
  65. package/dist/core/llm/providers/implementations/OpenRouterProvider.js +34 -13
  66. package/dist/core/llm/providers/implementations/OpenRouterProvider.js.map +1 -1
  67. package/dist/core/tools/ITool.d.ts +45 -0
  68. package/dist/core/tools/ITool.d.ts.map +1 -1
  69. package/dist/core/tools/ToolOrchestrator.d.ts.map +1 -1
  70. package/dist/core/tools/ToolOrchestrator.js +4 -8
  71. package/dist/core/tools/ToolOrchestrator.js.map +1 -1
  72. package/dist/io/media/images/imageToBuffer.d.ts.map +1 -1
  73. package/dist/io/media/images/imageToBuffer.js +6 -4
  74. package/dist/io/media/images/imageToBuffer.js.map +1 -1
  75. package/package.json +1 -1
@@ -0,0 +1,288 @@
1
+ /**
2
+ * @fileoverview The host-side broker for code-forged tools under a ceiling.
3
+ * It hands each run the functions the run's grant names, scoped by the
4
+ * ceiling. Before every capability call it checks, in this order: the run is
5
+ * live, the capability is in the grant, the target fits the scope. It then
6
+ * writes the intent record, checks the run is still live, performs the call
7
+ * while tracking it under the run's id, and writes the terminal record. When
8
+ * the run ends, `endCall` waits up to {@link CALL_SETTLE_MS} for what is in
9
+ * flight and returns the run's effects. On `node:vm` these checks are a
10
+ * guardrail for code that acts through these functions; Node's documentation
11
+ * says `node:vm` is not a security mechanism.
12
+ * @module @framers/agentos/emergent/broker/CapabilityBroker
13
+ */
14
+ import { createHash, createHmac, randomUUID } from 'node:crypto';
15
+ import { recordedTarget } from '../EffectsStore.js';
16
+ import { fetchTarget, prepareFetch, sendFetch } from './fetch.js';
17
+ import { prepareRead, readPrepared, ReadRoots, ReadTooLarge } from './fs-read.js';
18
+ import { CapabilityRefusal } from './refusal.js';
19
+ /** How long a run's end waits for its aborted capability calls to settle. */
20
+ export const CALL_SETTLE_MS = 1000;
21
+ /** The terminal half for a call that threw. */
22
+ function endOf(error) {
23
+ if (error instanceof ReadTooLarge) {
24
+ return { outcome: 'refused', code: error.code, bytes: error.bytesRead };
25
+ }
26
+ if (error instanceof CapabilityRefusal) {
27
+ if (error.code === 'aborted' || error.code === 'timed_out') {
28
+ return { outcome: error.code, code: error.code };
29
+ }
30
+ return { outcome: 'refused', code: error.code };
31
+ }
32
+ return { outcome: 'error', code: error instanceof Error ? error.name : 'error' };
33
+ }
34
+ export class CapabilityBroker {
35
+ /**
36
+ * @param ceiling - The resolved ceiling the functions are scoped by.
37
+ * @param store - Where effect records go; absent with `audit.store: 'none'`.
38
+ */
39
+ constructor(ceiling, store) {
40
+ this.ceiling = ceiling;
41
+ this.store = store;
42
+ this.runs = new Map();
43
+ this.readRoots = ceiling['fs.read'] ? new ReadRoots(ceiling['fs.read'].roots) : undefined;
44
+ }
45
+ /**
46
+ * The globals injected into one run's sandbox: a function for each
47
+ * capability that both the grant and the ceiling hold, and nothing else.
48
+ * The owner of the run's handle calls {@link endCall} when the run ends.
49
+ */
50
+ functionsFor(grant, call) {
51
+ const run = this.ledgerFor(call);
52
+ const functions = {};
53
+ const fetchScope = this.ceiling.fetch;
54
+ if (grant.includes('fetch') && fetchScope) {
55
+ functions.fetch = (input, init) => this.perform(run, grant, 'fetch', fetchTarget(input) ?? String(input), () => {
56
+ const prepared = prepareFetch(input, init, fetchScope);
57
+ return async (signal) => {
58
+ const sent = await sendFetch(prepared, fetchScope, signal);
59
+ return { value: sent.response, bytes: sent.bytes };
60
+ };
61
+ });
62
+ }
63
+ const readScope = this.ceiling['fs.read'];
64
+ const roots = this.readRoots;
65
+ if (grant.includes('fs.read') && readScope && roots) {
66
+ functions.fs = {
67
+ readFile: (filePath) => this.perform(run, grant, 'fs.read', String(filePath), () => {
68
+ const resolved = prepareRead(filePath, roots);
69
+ return async (signal) => {
70
+ const read = await readPrepared(resolved, roots, readScope, signal);
71
+ return { value: read.text, bytes: read.bytes };
72
+ };
73
+ }),
74
+ };
75
+ }
76
+ if (grant.includes('crypto') && this.ceiling.crypto) {
77
+ // Synchronous and reaching nothing outside the process: counted per
78
+ // run, with one record when the run ends, not one per call.
79
+ const use = () => {
80
+ this.admit(run, grant, 'crypto');
81
+ run.cryptoUses += 1;
82
+ };
83
+ functions.crypto = {
84
+ randomUUID: () => {
85
+ use();
86
+ return randomUUID();
87
+ },
88
+ createHash: (algorithm) => {
89
+ use();
90
+ return createHash(algorithm);
91
+ },
92
+ createHmac: (algorithm, key) => {
93
+ use();
94
+ return createHmac(algorithm, key);
95
+ },
96
+ };
97
+ }
98
+ return functions;
99
+ }
100
+ /**
101
+ * Ends a run: refuses its capability calls from now on (the owner aborts
102
+ * the run's signal too), waits up to `settleMs` for the calls in flight,
103
+ * writes the crypto count, and returns the run's effects. A call that has
104
+ * not settled is listed `pending`, and its record completes when it settles.
105
+ */
106
+ async endCall(callId, settleMs = CALL_SETTLE_MS) {
107
+ const run = this.runs.get(callId);
108
+ if (!run) {
109
+ return [];
110
+ }
111
+ run.ended = true;
112
+ this.runs.delete(callId);
113
+ if (run.inFlight.size > 0) {
114
+ let timer;
115
+ await Promise.race([
116
+ Promise.allSettled([...run.inFlight]),
117
+ new Promise((resolve) => {
118
+ timer = setTimeout(resolve, settleMs);
119
+ }),
120
+ ]);
121
+ clearTimeout(timer);
122
+ }
123
+ if (run.cryptoUses > 0) {
124
+ const effect = {
125
+ kind: 'capability',
126
+ toolId: run.call.toolId,
127
+ callId: run.call.id,
128
+ capability: 'crypto',
129
+ target: recordedTarget('', this.ceiling.audit.content),
130
+ decision: 'allowed',
131
+ decidedBy: 'ceiling',
132
+ outcome: 'ok',
133
+ uses: run.cryptoUses,
134
+ record: this.store ? 'written' : 'none',
135
+ };
136
+ if (this.store) {
137
+ try {
138
+ await this.store.whole(this.intentOf(run.call, 'crypto', '', 'allowed', 'ceiling'), {
139
+ outcome: 'ok',
140
+ uses: run.cryptoUses,
141
+ });
142
+ }
143
+ catch {
144
+ effect.record = 'none';
145
+ }
146
+ }
147
+ run.effects.push(effect);
148
+ }
149
+ return run.effects.map((effect) => ({ ...effect }));
150
+ }
151
+ ledgerFor(call) {
152
+ let run = this.runs.get(call.id);
153
+ if (!run) {
154
+ run = { call, effects: [], inFlight: new Set(), cryptoUses: 0, ended: false };
155
+ this.runs.set(call.id, run);
156
+ }
157
+ return run;
158
+ }
159
+ /** The run is live and the capability is in its grant and the ceiling. */
160
+ admit(run, grant, capability) {
161
+ if (run.ended || run.call.signal.aborted) {
162
+ throw new CapabilityRefusal('call_ended', capability);
163
+ }
164
+ if (!grant.includes(capability) || this.ceiling[capability] === undefined) {
165
+ throw new CapabilityRefusal('capability_not_granted', capability);
166
+ }
167
+ }
168
+ /**
169
+ * One capability call: the checks (a refusal is recorded as one row), then
170
+ * the recorded call, tracked in flight from its intent write to its
171
+ * terminal write, so ending the run waits for both.
172
+ */
173
+ async perform(run, grant, capability, target, prepare) {
174
+ let operation;
175
+ try {
176
+ this.admit(run, grant, capability);
177
+ operation = prepare();
178
+ }
179
+ catch (error) {
180
+ if (error instanceof CapabilityRefusal) {
181
+ await this.recordRefusal(run, capability, target, error.code);
182
+ }
183
+ throw error;
184
+ }
185
+ const effect = {
186
+ kind: 'capability',
187
+ toolId: run.call.toolId,
188
+ callId: run.call.id,
189
+ capability,
190
+ target: recordedTarget(target, this.ceiling.audit.content),
191
+ decision: 'allowed',
192
+ decidedBy: 'ceiling',
193
+ outcome: 'pending',
194
+ record: this.store ? 'written' : 'none',
195
+ };
196
+ run.effects.push(effect);
197
+ const recorded = this.carryOut(run, effect, capability, target, operation);
198
+ const settled = recorded.then(() => undefined, () => undefined);
199
+ run.inFlight.add(settled);
200
+ try {
201
+ return await recorded;
202
+ }
203
+ finally {
204
+ run.inFlight.delete(settled);
205
+ }
206
+ }
207
+ /** The intent record, the run checked again, the call, and its terminal record. */
208
+ async carryOut(run, effect, capability, target, operation) {
209
+ let rowId;
210
+ if (this.store) {
211
+ try {
212
+ rowId = await this.store.intent(this.intentOf(run.call, capability, target, 'allowed', 'ceiling'));
213
+ }
214
+ catch {
215
+ Object.assign(effect, {
216
+ decision: 'refused',
217
+ decidedBy: 'audit_unavailable',
218
+ outcome: 'refused',
219
+ code: 'audit_unavailable',
220
+ record: 'none',
221
+ });
222
+ throw new CapabilityRefusal('audit_unavailable', `${capability}: its effect record could not be written`);
223
+ }
224
+ }
225
+ // The run may have ended while its intent was written.
226
+ if (run.ended || run.call.signal.aborted) {
227
+ await this.finish(effect, rowId, { outcome: 'aborted', code: 'call_ended' });
228
+ throw new CapabilityRefusal('call_ended', capability);
229
+ }
230
+ let result;
231
+ try {
232
+ result = await operation(run.call.signal);
233
+ }
234
+ catch (error) {
235
+ await this.finish(effect, rowId, endOf(error));
236
+ throw error;
237
+ }
238
+ await this.finish(effect, rowId, { outcome: 'ok', bytes: result.bytes });
239
+ return result.value;
240
+ }
241
+ async finish(effect, rowId, end) {
242
+ effect.outcome = end.outcome;
243
+ if (end.code !== undefined) {
244
+ effect.code = end.code;
245
+ }
246
+ if (end.bytes !== undefined) {
247
+ effect.bytes = end.bytes;
248
+ }
249
+ if (this.store && rowId !== undefined) {
250
+ try {
251
+ await this.store.terminal(rowId, end);
252
+ }
253
+ catch {
254
+ effect.record = 'intent_only';
255
+ }
256
+ }
257
+ }
258
+ async recordRefusal(run, capability, target, code) {
259
+ const effect = {
260
+ kind: 'capability',
261
+ toolId: run.call.toolId,
262
+ callId: run.call.id,
263
+ capability,
264
+ target: recordedTarget(target, this.ceiling.audit.content),
265
+ decision: 'refused',
266
+ decidedBy: code,
267
+ outcome: 'refused',
268
+ code,
269
+ record: this.store ? 'written' : 'none',
270
+ };
271
+ run.effects.push(effect);
272
+ if (this.store) {
273
+ try {
274
+ await this.store.whole(this.intentOf(run.call, capability, target, 'refused', code), {
275
+ outcome: 'refused',
276
+ code,
277
+ });
278
+ }
279
+ catch {
280
+ effect.record = 'none';
281
+ }
282
+ }
283
+ }
284
+ intentOf(call, capability, target, decision, decidedBy) {
285
+ return { toolId: call.toolId, callId: call.id, agentId: call.agentId, capability, target, decision, decidedBy };
286
+ }
287
+ }
288
+ //# sourceMappingURL=CapabilityBroker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CapabilityBroker.js","sourceRoot":"","sources":["../../../../src/cognition/emergent/broker/CapabilityBroker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EAAE,cAAc,EAA6D,MAAM,oBAAoB,CAAC;AAE/G,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AAanC,+CAA+C;AAC/C,SAAS,KAAK,CAAC,KAAc;IAC3B,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QAClC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QACnD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AACnF,CAAC;AAED,MAAM,OAAO,gBAAgB;IAI3B;;;OAGG;IACH,YACW,OAAwB,EAChB,KAAoB;QAD5B,YAAO,GAAP,OAAO,CAAiB;QAChB,UAAK,GAAL,KAAK,CAAe;QARtB,SAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;QAUnD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,KAAgC,EAAE,IAAgB;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,SAAS,GAA4B,EAAE,CAAC;QAE9C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACtC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,UAAU,EAAE,CAAC;YAC1C,SAAS,CAAC,KAAK,GAAG,CAAC,KAAc,EAAE,IAAc,EAAqB,EAAE,CACtE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE;gBAC1E,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;gBACvD,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;oBACtB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;oBAC3D,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACrD,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;QACP,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACpD,SAAS,CAAC,EAAE,GAAG;gBACb,QAAQ,EAAE,CAAC,QAAiB,EAAmB,EAAE,CAC/C,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE;oBACzD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;oBAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;wBACtB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;wBACpE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;oBACjD,CAAC,CAAC;gBACJ,CAAC,CAAC;aACL,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpD,oEAAoE;YACpE,4DAA4D;YAC5D,MAAM,GAAG,GAAG,GAAS,EAAE;gBACrB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBACjC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC;YACtB,CAAC,CAAC;YACF,SAAS,CAAC,MAAM,GAAG;gBACjB,UAAU,EAAE,GAAG,EAAE;oBACf,GAAG,EAAE,CAAC;oBACN,OAAO,UAAU,EAAE,CAAC;gBACtB,CAAC;gBACD,UAAU,EAAE,CAAC,SAAiB,EAAE,EAAE;oBAChC,GAAG,EAAE,CAAC;oBACN,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;gBAC/B,CAAC;gBACD,UAAU,EAAE,CAAC,SAAiB,EAAE,GAAW,EAAE,EAAE;oBAC7C,GAAG,EAAE,CAAC;oBACN,OAAO,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;gBACpC,CAAC;aACF,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,WAAmB,cAAc;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,KAAiC,CAAC;YACtC,MAAM,OAAO,CAAC,IAAI,CAAC;gBACjB,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACrC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBAC5B,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBACxC,CAAC,CAAC;aACH,CAAC,CAAC;YACH,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,MAAM,GAAqB;gBAC/B,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM;gBACvB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;gBACnB,UAAU,EAAE,QAAQ;gBACpB,MAAM,EAAE,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;gBACtD,QAAQ,EAAE,SAAS;gBACnB,SAAS,EAAE,SAAS;gBACpB,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,GAAG,CAAC,UAAU;gBACpB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;aACxC,CAAC;YACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;wBAClF,OAAO,EAAE,IAAI;wBACb,IAAI,EAAE,GAAG,CAAC,UAAU;qBACrB,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;gBACzB,CAAC;YACH,CAAC;YACD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;IAEO,SAAS,CAAC,IAAgB;QAChC,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAC9E,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,0EAA0E;IAClE,KAAK,CAAC,GAAc,EAAE,KAAgC,EAAE,UAA0B;QACxF,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzC,MAAM,IAAI,iBAAiB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,SAAS,EAAE,CAAC;YAC1E,MAAM,IAAI,iBAAiB,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,OAAO,CACnB,GAAc,EACd,KAAgC,EAChC,UAA0B,EAC1B,MAAc,EACd,OAA2B;QAE3B,IAAI,SAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;YACnC,SAAS,GAAG,OAAO,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;gBACvC,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAChE,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAqB;YAC/B,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM;YACvB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;YACnB,UAAU;YACV,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YAC1D,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;SACxC,CAAC;QACF,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3E,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAC3B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;QACF,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC;QACxB,CAAC;gBAAS,CAAC;YACT,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,mFAAmF;IAC3E,KAAK,CAAC,QAAQ,CACpB,GAAc,EACd,MAAwB,EACxB,UAA0B,EAC1B,MAAc,EACd,SAAuB;QAEvB,IAAI,KAAyB,CAAC;QAC9B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;YACrG,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;oBACpB,QAAQ,EAAE,SAAS;oBACnB,SAAS,EAAE,mBAAmB;oBAC9B,OAAO,EAAE,SAAS;oBAClB,IAAI,EAAE,mBAAmB;oBACzB,MAAM,EAAE,MAAM;iBACf,CAAC,CAAC;gBACH,MAAM,IAAI,iBAAiB,CAAC,mBAAmB,EAAE,GAAG,UAAU,0CAA0C,CAAC,CAAC;YAC5G,CAAC;QACH,CAAC;QACD,uDAAuD;QACvD,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YAC7E,MAAM,IAAI,iBAAiB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,MAAmC,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/C,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QACzE,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,MAAwB,EAAE,KAAyB,EAAE,GAAmB;QAC3F,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACzB,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QAC3B,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,GAAc,EAAE,UAA0B,EAAE,MAAc,EAAE,IAAY;QAClG,MAAM,MAAM,GAAqB;YAC/B,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM;YACvB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;YACnB,UAAU;YACV,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YAC1D,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,SAAS;YAClB,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;SACxC,CAAC;QACF,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;oBACnF,OAAO,EAAE,SAAS;oBAClB,IAAI;iBACL,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAEO,QAAQ,CACd,IAAgB,EAChB,UAAkB,EAClB,MAAc,EACd,QAA+B,EAC/B,SAAiB;QAEjB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAClH,CAAC;CACF"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview The broker's `fetch` for code-forged tools under a ceiling.
3
+ * `prepareFetch` checks a request before anything is sent (the URL, its
4
+ * scheme, the method and the first host) and rebuilds the caller's options
5
+ * from the two it accepts; `sendFetch` sends it with `redirect: 'manual'`,
6
+ * follows each redirect itself after checking the next host, and reads the
7
+ * body as a stream that is refused past its limit.
8
+ * @module @framers/agentos/emergent/broker/fetch
9
+ */
10
+ /** The scope a ceiling grants `fetch` under, with its defaults applied. */
11
+ export interface FetchScope {
12
+ domains: string[] | '*';
13
+ methods: Array<'GET' | 'HEAD'>;
14
+ maxResponseBytes: number;
15
+ maxRedirects: number;
16
+ timeoutMs: number;
17
+ }
18
+ /** A request that passed every check made before anything is sent. */
19
+ export interface PreparedFetch {
20
+ url: URL;
21
+ method: 'GET' | 'HEAD';
22
+ headers: Headers;
23
+ }
24
+ /** The URL a forged tool's first argument names: a string, a URL, or an object with a `url` string. */
25
+ export declare function fetchTarget(input: unknown): string | undefined;
26
+ /**
27
+ * The checks made before anything is sent. The caller's options are read for
28
+ * `method` and `headers` only: a body, a redirect mode, credentials or a
29
+ * signal of the caller's are never passed on.
30
+ */
31
+ export declare function prepareFetch(input: unknown, init: unknown, scope: FetchScope): PreparedFetch;
32
+ /**
33
+ * Sends a prepared request. `signal` is the call's; the scope's `timeoutMs`
34
+ * bounds the whole request, redirects and body included. Every redirect is
35
+ * followed here, its host checked like the first; GET and HEAD keep their
36
+ * method through every redirect status.
37
+ */
38
+ export declare function sendFetch(prepared: PreparedFetch, scope: FetchScope, signal: AbortSignal): Promise<{
39
+ response: Response;
40
+ bytes: number;
41
+ }>;
42
+ /** The broker's fetch without its records: the checks, then the request. */
43
+ export declare function brokeredFetch(input: unknown, init: unknown, scope: FetchScope, signal: AbortSignal): Promise<Response>;
44
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../../src/cognition/emergent/broker/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IACxB,OAAO,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAOD,uGAAuG;AACvG,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAW9D;AAuCD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,aAAa,CAmB5F;AA8BD;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAiEhD;AAED,4EAA4E;AAC5E,wBAAsB,aAAa,CACjC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,QAAQ,CAAC,CAEnB"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * @fileoverview The broker's `fetch` for code-forged tools under a ceiling.
3
+ * `prepareFetch` checks a request before anything is sent (the URL, its
4
+ * scheme, the method and the first host) and rebuilds the caller's options
5
+ * from the two it accepts; `sendFetch` sends it with `redirect: 'manual'`,
6
+ * follows each redirect itself after checking the next host, and reads the
7
+ * body as a stream that is refused past its limit.
8
+ * @module @framers/agentos/emergent/broker/fetch
9
+ */
10
+ import { CapabilityRefusal } from './refusal.js';
11
+ const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
12
+ const NULL_BODY_STATUSES = new Set([204, 205, 304]);
13
+ /** Dropped when a redirect changes the origin, as fetch itself does. */
14
+ const CROSS_ORIGIN_DROPPED = ['authorization', 'proxy-authorization', 'cookie', 'host'];
15
+ /** The URL a forged tool's first argument names: a string, a URL, or an object with a `url` string. */
16
+ export function fetchTarget(input) {
17
+ if (typeof input === 'string') {
18
+ return input;
19
+ }
20
+ if (input instanceof URL) {
21
+ return input.href;
22
+ }
23
+ if (input && typeof input === 'object' && typeof input.url === 'string') {
24
+ return input.url;
25
+ }
26
+ return undefined;
27
+ }
28
+ function checkScheme(url) {
29
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
30
+ throw new CapabilityRefusal('scheme_not_allowed', `${url.protocol} (http and https only)`);
31
+ }
32
+ }
33
+ function checkHost(url, scope) {
34
+ const host = url.hostname.toLowerCase();
35
+ if (scope.domains !== '*' && !scope.domains.includes(host)) {
36
+ throw new CapabilityRefusal('host_not_allowed', host);
37
+ }
38
+ }
39
+ function headersFrom(given) {
40
+ const headers = new Headers();
41
+ try {
42
+ if (given instanceof Headers) {
43
+ given.forEach((value, name) => headers.set(name, value));
44
+ }
45
+ else if (Array.isArray(given)) {
46
+ for (const pair of given) {
47
+ if (Array.isArray(pair) && typeof pair[0] === 'string' && typeof pair[1] === 'string') {
48
+ headers.append(pair[0], pair[1]);
49
+ }
50
+ }
51
+ }
52
+ else if (given && typeof given === 'object') {
53
+ for (const [name, value] of Object.entries(given)) {
54
+ if (typeof value === 'string') {
55
+ headers.set(name, value);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ catch (error) {
61
+ throw new CapabilityRefusal('invalid_headers', error instanceof Error ? error.message : String(error));
62
+ }
63
+ return headers;
64
+ }
65
+ /**
66
+ * The checks made before anything is sent. The caller's options are read for
67
+ * `method` and `headers` only: a body, a redirect mode, credentials or a
68
+ * signal of the caller's are never passed on.
69
+ */
70
+ export function prepareFetch(input, init, scope) {
71
+ const raw = fetchTarget(input);
72
+ if (raw === undefined) {
73
+ throw new CapabilityRefusal('invalid_url', 'fetch takes a URL');
74
+ }
75
+ let url;
76
+ try {
77
+ url = new URL(raw);
78
+ }
79
+ catch {
80
+ throw new CapabilityRefusal('invalid_url', `"${raw}" is not an absolute URL`);
81
+ }
82
+ checkScheme(url);
83
+ const options = init && typeof init === 'object' ? init : {};
84
+ const method = (typeof options.method === 'string' ? options.method : 'GET').toUpperCase();
85
+ if (!scope.methods.includes(method)) {
86
+ throw new CapabilityRefusal('method_not_allowed', method);
87
+ }
88
+ checkHost(url, scope);
89
+ return { url, method: method, headers: headersFrom(options.headers) };
90
+ }
91
+ async function cappedBody(response, limit) {
92
+ if (!response.body) {
93
+ return new Uint8Array(0);
94
+ }
95
+ const reader = response.body.getReader();
96
+ const chunks = [];
97
+ let total = 0;
98
+ for (;;) {
99
+ const { done, value } = await reader.read();
100
+ if (done) {
101
+ break;
102
+ }
103
+ total += value.byteLength;
104
+ if (total > limit) {
105
+ await reader.cancel().catch(() => undefined);
106
+ throw new CapabilityRefusal('response_too_large', `more than ${limit} bytes`);
107
+ }
108
+ chunks.push(value);
109
+ }
110
+ const body = new Uint8Array(total);
111
+ let offset = 0;
112
+ for (const chunk of chunks) {
113
+ body.set(chunk, offset);
114
+ offset += chunk.byteLength;
115
+ }
116
+ return body;
117
+ }
118
+ /**
119
+ * Sends a prepared request. `signal` is the call's; the scope's `timeoutMs`
120
+ * bounds the whole request, redirects and body included. Every redirect is
121
+ * followed here, its host checked like the first; GET and HEAD keep their
122
+ * method through every redirect status.
123
+ */
124
+ export async function sendFetch(prepared, scope, signal) {
125
+ const bounded = AbortSignal.any([signal, AbortSignal.timeout(scope.timeoutMs)]);
126
+ const ended = (host) => new CapabilityRefusal(signal.aborted ? 'aborted' : 'timed_out', host);
127
+ const headers = new Headers(prepared.headers);
128
+ let url = prepared.url;
129
+ for (let redirects = 0;; redirects += 1) {
130
+ let response;
131
+ try {
132
+ response = await fetch(url, { method: prepared.method, headers, redirect: 'manual', signal: bounded });
133
+ }
134
+ catch (error) {
135
+ if (bounded.aborted) {
136
+ throw ended(url.hostname);
137
+ }
138
+ throw error;
139
+ }
140
+ const location = response.headers.get('location');
141
+ if (REDIRECT_STATUSES.has(response.status) && location !== null) {
142
+ await response.body?.cancel().catch(() => undefined);
143
+ if (redirects >= scope.maxRedirects) {
144
+ throw new CapabilityRefusal('too_many_redirects', `more than ${scope.maxRedirects}`);
145
+ }
146
+ let next;
147
+ try {
148
+ next = new URL(location, url);
149
+ }
150
+ catch {
151
+ throw new CapabilityRefusal('invalid_url', `a redirect to "${location}"`);
152
+ }
153
+ checkScheme(next);
154
+ checkHost(next, scope);
155
+ if (next.origin !== url.origin) {
156
+ for (const name of CROSS_ORIGIN_DROPPED) {
157
+ headers.delete(name);
158
+ }
159
+ }
160
+ url = next;
161
+ continue;
162
+ }
163
+ let body = null;
164
+ if (prepared.method === 'HEAD' || NULL_BODY_STATUSES.has(response.status)) {
165
+ await response.body?.cancel().catch(() => undefined);
166
+ }
167
+ else {
168
+ try {
169
+ body = await cappedBody(response, scope.maxResponseBytes);
170
+ }
171
+ catch (error) {
172
+ if (error instanceof CapabilityRefusal) {
173
+ throw error;
174
+ }
175
+ if (bounded.aborted) {
176
+ throw ended(url.hostname);
177
+ }
178
+ throw error;
179
+ }
180
+ }
181
+ return {
182
+ // The body's own ArrayBuffer (it was allocated whole above): a typed
183
+ // array is not a BodyInit under TypeScript 5.7 and later.
184
+ response: new Response(body === null ? null : body.buffer, {
185
+ status: response.status,
186
+ statusText: response.statusText,
187
+ headers: response.headers,
188
+ }),
189
+ bytes: body?.byteLength ?? 0,
190
+ };
191
+ }
192
+ }
193
+ /** The broker's fetch without its records: the checks, then the request. */
194
+ export async function brokeredFetch(input, init, scope, signal) {
195
+ return (await sendFetch(prepareFetch(input, init, scope), scope, signal)).response;
196
+ }
197
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../../src/cognition/emergent/broker/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @fileoverview The broker's `fs.readFile` for code-forged tools under a
3
+ * ceiling, and the path rules it shares with the forge's legacy read:
4
+ * lexical containment first, then the real path against the roots' real
5
+ * paths, each root's real path pinned on first success. The read is a
6
+ * stream refused past its limit, so no file is held whole before the limit
7
+ * applies.
8
+ * @module @framers/agentos/emergent/broker/fs-read
9
+ */
10
+ import { CapabilityRefusal } from './refusal.js';
11
+ /**
12
+ * Whether a path lies under one of the roots. Decided by `path.relative`, not
13
+ * a string prefix: a root that ends in a separator (`/`, `C:\`) would
14
+ * otherwise be compared against a doubled separator, and `path.relative`
15
+ * applies the platform's case rules. `''` is the root itself; a result that
16
+ * climbs out (`..`, `../x`) or stays absolute (another Windows drive) is
17
+ * outside. Checking the `..` segment, not the prefix, keeps a sibling named
18
+ * `..foo` from reading as an escape.
19
+ */
20
+ export declare function withinRoots(candidate: string, roots: readonly string[]): boolean;
21
+ /**
22
+ * Read roots, each root's real path resolved lazily and pinned per root.
23
+ *
24
+ * Both sides of a containment check are real paths: a root is often itself a
25
+ * link (on macOS `/tmp` is a link to `/private/tmp`). A resolved root stays
26
+ * pinned for the life of this object, so a root link repointed under a
27
+ * running sandbox is not followed. A failed resolution is not pinned, so a
28
+ * root that becomes readable later is picked up, and one unreadable root
29
+ * never un-pins a sibling; its lexical form never matches a real path, so it
30
+ * cannot widen the reads while it stays unreadable.
31
+ */
32
+ export declare class ReadRoots {
33
+ readonly roots: readonly string[];
34
+ private readonly cache;
35
+ constructor(roots: readonly string[]);
36
+ real(): Promise<string[]>;
37
+ private realOf;
38
+ }
39
+ /** A read refused past its limit, with how far it got. */
40
+ export declare class ReadTooLarge extends CapabilityRefusal {
41
+ readonly bytesRead: number;
42
+ constructor(bytesRead: number, limit: number);
43
+ }
44
+ /** The check made before the filesystem is touched: a path string, lexically under a root. Returns the resolved path. */
45
+ export declare function prepareRead(filePath: unknown, roots: ReadRoots): string;
46
+ /**
47
+ * The real-path check and the read. The file read is the resolved real path,
48
+ * not the caller's string: resolving the caller's string again would walk a
49
+ * link a second time, and the link can be repointed between the two walks.
50
+ */
51
+ export declare function readPrepared(resolved: string, roots: ReadRoots, scope: {
52
+ maxBytesPerRead: number;
53
+ timeoutMs: number;
54
+ }, signal: AbortSignal): Promise<{
55
+ text: string;
56
+ bytes: number;
57
+ }>;
58
+ /** The broker's read without its records: the checks, then the read. */
59
+ export declare function brokeredRead(filePath: unknown, roots: ReadRoots, scope: {
60
+ maxBytesPerRead: number;
61
+ timeoutMs: number;
62
+ }, signal: AbortSignal): Promise<string>;
63
+ //# sourceMappingURL=fs-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-read.d.ts","sourceRoot":"","sources":["../../../../src/cognition/emergent/broker/fs-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAQhF;AAED;;;;;;;;;;GAUG;AACH,qBAAa,SAAS;IAGR,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE;IAF7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;gBAEvC,KAAK,EAAE,SAAS,MAAM,EAAE;IAE7C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzB,OAAO,CAAC,MAAM;CAYf;AAED,0DAA0D;AAC1D,qBAAa,YAAa,SAAQ,iBAAiB;IAE/C,QAAQ,CAAC,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM,EAC1B,KAAK,EAAE,MAAM;CAIhB;AAED,yHAAyH;AACzH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CASvE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACrD,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA8C1C;AAED,wEAAwE;AACxE,wBAAsB,YAAY,CAChC,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACrD,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,CAAC,CAEjB"}