mancode 0.6.4 → 0.6.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 (34) hide show
  1. package/README.en.md +165 -45
  2. package/README.md +109 -28
  3. package/dist/{chunk-7HPP3KYG.js → chunk-D5ABGAF4.js} +2422 -1003
  4. package/dist/chunk-D5ABGAF4.js.map +1 -0
  5. package/dist/chunk-GI24QVXE.js +1099 -0
  6. package/dist/chunk-GI24QVXE.js.map +1 -0
  7. package/dist/chunk-IRZQYMHD.js +334 -0
  8. package/dist/chunk-IRZQYMHD.js.map +1 -0
  9. package/dist/{chunk-WJ6WARGG.js → chunk-RMHUYJXB.js} +46 -47
  10. package/dist/chunk-RMHUYJXB.js.map +1 -0
  11. package/dist/chunk-THOE33LU.js +1124 -0
  12. package/dist/chunk-THOE33LU.js.map +1 -0
  13. package/dist/chunk-WRBNOPFA.js +1235 -0
  14. package/dist/chunk-WRBNOPFA.js.map +1 -0
  15. package/dist/cli.js +15488 -15613
  16. package/dist/cli.js.map +1 -1
  17. package/dist/gateway/worker.d.ts +2 -0
  18. package/dist/gateway/worker.js +181 -0
  19. package/dist/gateway/worker.js.map +1 -0
  20. package/dist/privacy-gateway-Q4GD2JXF.js +20 -0
  21. package/dist/store-LLXL7QYG.js +11 -0
  22. package/dist/{v3-adapter-T3IKK3LU.js → v3-adapter-KA2NOVI5.js} +2 -2
  23. package/dist/v3-adapter-KA2NOVI5.js.map +1 -0
  24. package/docs/README.md +34 -0
  25. package/docs/privacy-guide.md +76 -0
  26. package/docs/privacy-implementation-plan.md +101 -0
  27. package/docs/privacy-rule-sources.md +22 -0
  28. package/docs/privacy-upstream-license.txt +661 -0
  29. package/package.json +10 -4
  30. package/dist/chunk-7HPP3KYG.js.map +0 -1
  31. package/dist/chunk-WJ6WARGG.js.map +0 -1
  32. package/dist/store-LN63OL66.js +0 -9
  33. /package/dist/{store-LN63OL66.js.map → privacy-gateway-Q4GD2JXF.js.map} +0 -0
  34. /package/dist/{v3-adapter-T3IKK3LU.js.map → store-LLXL7QYG.js.map} +0 -0
@@ -0,0 +1,1099 @@
1
+ import {
2
+ scanSensitiveText
3
+ } from "./chunk-IRZQYMHD.js";
4
+
5
+ // src/gateway/errors.ts
6
+ var GatewayError = class extends Error {
7
+ constructor(code, status = 400) {
8
+ super(code);
9
+ this.code = code;
10
+ this.status = status;
11
+ }
12
+ };
13
+ function gatewayErrorCode(error) {
14
+ return error instanceof GatewayError ? error.code : "MANCODE_GATEWAY_FAILED";
15
+ }
16
+
17
+ // src/gateway/json.ts
18
+ import { parseTree } from "jsonc-parser";
19
+ function parseStrictJson(source) {
20
+ if (Buffer.byteLength(source) > 1024 * 1024)
21
+ throw new GatewayError("MANCODE_GATEWAY_JSON_LIMIT");
22
+ let depth = 0;
23
+ let structures = 0;
24
+ let inString = false;
25
+ let escaped = false;
26
+ for (const character of source) {
27
+ if (inString) {
28
+ if (escaped) escaped = false;
29
+ else if (character === "\\") escaped = true;
30
+ else if (character === '"') inString = false;
31
+ } else if (character === '"') inString = true;
32
+ else if (character === "{" || character === "[") {
33
+ if (++depth > 48 || ++structures > 8e3)
34
+ throw new GatewayError("MANCODE_GATEWAY_JSON_LIMIT");
35
+ } else if (character === "}" || character === "]") depth--;
36
+ else if ((character === "," || character === ":") && ++structures > 8e3)
37
+ throw new GatewayError("MANCODE_GATEWAY_JSON_LIMIT");
38
+ }
39
+ const errors = [];
40
+ const tree = parseTree(source, errors, {
41
+ allowTrailingComma: false,
42
+ disallowComments: true,
43
+ allowEmptyContent: false
44
+ });
45
+ if (!tree || errors.length)
46
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_JSON");
47
+ let count = 0;
48
+ const visit = (node, depth2) => {
49
+ if (depth2 > 48 || ++count > 4e4)
50
+ throw new GatewayError("MANCODE_GATEWAY_JSON_LIMIT");
51
+ if (node.type === "object") {
52
+ const keys = /* @__PURE__ */ new Set();
53
+ for (const property2 of node.children ?? []) {
54
+ const key = property2.children?.[0]?.value;
55
+ if (keys.has(key))
56
+ throw new GatewayError("MANCODE_GATEWAY_DUPLICATE_KEY");
57
+ keys.add(key);
58
+ }
59
+ }
60
+ for (const child of node.children ?? []) visit(child, depth2 + 1);
61
+ };
62
+ visit(tree, 0);
63
+ return tree;
64
+ }
65
+ function property(node, name) {
66
+ return node.type === "object" ? node.children?.find((child) => child.children?.[0]?.value === name)?.children?.[1] : void 0;
67
+ }
68
+ function stringValue(node) {
69
+ return node?.type === "string" ? node.value : void 0;
70
+ }
71
+ function applyJsonEdits(input, edits) {
72
+ let source = input;
73
+ let last = source.length;
74
+ for (const edit of [...edits].sort((a, b) => b.offset - a.offset)) {
75
+ if (edit.offset + edit.length > last)
76
+ throw new GatewayError("MANCODE_GATEWAY_OVERLAPPING_EDIT");
77
+ source = source.slice(0, edit.offset) + edit.text + source.slice(edit.offset + edit.length);
78
+ last = edit.offset;
79
+ }
80
+ return source;
81
+ }
82
+ function replaceString(edits, node, value) {
83
+ if (value !== node.value)
84
+ edits.push({
85
+ offset: node.offset,
86
+ length: node.length,
87
+ text: JSON.stringify(value)
88
+ });
89
+ }
90
+
91
+ // src/gateway/mapping.ts
92
+ import { randomBytes } from "crypto";
93
+ var TOKEN_PREFIX = "__MANCODE_";
94
+ var TOKEN_PATTERN = /__MANCODE_[a-f0-9]{32}__/g;
95
+ var DEFAULT_MAPPING_LIMITS = {
96
+ entries: 4096,
97
+ bytes: 4 * 1024 * 1024,
98
+ ttlMs: 15 * 6e4,
99
+ lineage: 256
100
+ };
101
+ var MappingStore = class {
102
+ constructor(scope, limits = DEFAULT_MAPPING_LIMITS, now = Date.now) {
103
+ this.scope = scope;
104
+ this.limits = limits;
105
+ this.now = now;
106
+ }
107
+ entries = /* @__PURE__ */ new Map();
108
+ originals = /* @__PURE__ */ new Map();
109
+ responses = /* @__PURE__ */ new Map();
110
+ bytes = 0;
111
+ begin(previousResponseId) {
112
+ this.prune();
113
+ const inherited = previousResponseId ? this.responses.get(previousResponseId) : void 0;
114
+ if (previousResponseId && !inherited)
115
+ throw new GatewayError("MANCODE_GATEWAY_HISTORY_UNAVAILABLE");
116
+ const request = new RequestMapping(this);
117
+ for (const token of inherited?.tokens ?? []) request.authorize(token);
118
+ return request;
119
+ }
120
+ allocate(original) {
121
+ this.prune();
122
+ const existing = this.originals.get(original);
123
+ if (existing) return existing;
124
+ const bytes = Buffer.byteLength(original);
125
+ if (this.entries.size >= this.limits.entries || this.bytes + bytes > this.limits.bytes)
126
+ throw new GatewayError("MANCODE_GATEWAY_MAPPING_CAPACITY", 429);
127
+ const token = `${TOKEN_PREFIX}${randomBytes(16).toString("hex")}__`;
128
+ this.entries.set(token, {
129
+ original,
130
+ expires: this.now() + this.limits.ttlMs,
131
+ pins: 0,
132
+ bytes
133
+ });
134
+ this.originals.set(original, token);
135
+ this.bytes += bytes;
136
+ return token;
137
+ }
138
+ pin(token) {
139
+ const entry = this.entries.get(token);
140
+ if (!entry) throw new GatewayError("MANCODE_GATEWAY_UNKNOWN_TOKEN");
141
+ entry.pins++;
142
+ }
143
+ original(token) {
144
+ const entry = this.entries.get(token);
145
+ if (!entry) throw new GatewayError("MANCODE_GATEWAY_UNKNOWN_TOKEN");
146
+ return entry.original;
147
+ }
148
+ finish(tokens, responseId) {
149
+ if (responseId) {
150
+ if (this.responses.has(responseId))
151
+ throw new GatewayError("MANCODE_GATEWAY_RESPONSE_REPLAY");
152
+ if (this.responses.size >= this.limits.lineage)
153
+ this.responses.delete(this.responses.keys().next().value);
154
+ this.responses.set(responseId, {
155
+ tokens: new Set(tokens),
156
+ expires: this.now() + this.limits.ttlMs
157
+ });
158
+ }
159
+ }
160
+ release(tokens) {
161
+ for (const token of tokens) {
162
+ const entry = this.entries.get(token);
163
+ if (entry) {
164
+ entry.pins--;
165
+ entry.expires = this.now() + this.limits.ttlMs;
166
+ }
167
+ }
168
+ }
169
+ prune() {
170
+ for (const [token, entry] of this.entries)
171
+ if (entry.pins === 0 && entry.expires <= this.now()) {
172
+ this.entries.delete(token);
173
+ this.originals.delete(entry.original);
174
+ this.bytes -= entry.bytes;
175
+ }
176
+ for (const [id, lineage] of this.responses)
177
+ if (lineage.expires <= this.now() || [...lineage.tokens].some((token) => !this.entries.has(token)))
178
+ this.responses.delete(id);
179
+ }
180
+ };
181
+ var RequestMapping = class {
182
+ constructor(store) {
183
+ this.store = store;
184
+ }
185
+ authorized = /* @__PURE__ */ new Set();
186
+ claudeReadAllowed = false;
187
+ released = false;
188
+ authorize(token) {
189
+ if (this.authorized.has(token)) return;
190
+ this.store.pin(token);
191
+ this.authorized.add(token);
192
+ }
193
+ mask(input, ruleIds) {
194
+ let value = input;
195
+ for (const match of value.matchAll(TOKEN_PATTERN)) this.authorize(match[0]);
196
+ if (value.replace(TOKEN_PATTERN, "").includes(TOKEN_PREFIX))
197
+ throw new GatewayError("MANCODE_GATEWAY_MALFORMED_TOKEN");
198
+ const scan = scanSensitiveText(value, ruleIds);
199
+ if (scan.status !== "complete")
200
+ throw new GatewayError("MANCODE_GATEWAY_SCAN_FAILED");
201
+ const ranges = [];
202
+ for (const finding of scan.findings) {
203
+ const last = ranges.at(-1);
204
+ if (last && finding.start <= last.end)
205
+ last.end = Math.max(last.end, finding.end);
206
+ else ranges.push({ start: finding.start, end: finding.end });
207
+ }
208
+ for (const range of ranges.reverse()) {
209
+ const original = value.slice(range.start, range.end);
210
+ const token = this.store.allocate(original);
211
+ this.authorize(token);
212
+ value = value.slice(0, range.start) + token + value.slice(range.end);
213
+ }
214
+ return value;
215
+ }
216
+ maskLiteral(value) {
217
+ if (value === "") return value;
218
+ if (/^__MANCODE_[a-f0-9]{32}__$/.test(value)) {
219
+ this.authorize(value);
220
+ return value;
221
+ }
222
+ if (value.includes(TOKEN_PREFIX))
223
+ throw new GatewayError("MANCODE_GATEWAY_MALFORMED_TOKEN");
224
+ const token = this.store.allocate(value);
225
+ this.authorize(token);
226
+ return token;
227
+ }
228
+ restore(value) {
229
+ const stripped = value.replace(TOKEN_PATTERN, "");
230
+ if (stripped.includes(TOKEN_PREFIX))
231
+ throw new GatewayError("MANCODE_GATEWAY_MALFORMED_TOKEN");
232
+ return value.replace(TOKEN_PATTERN, (token) => {
233
+ if (!this.authorized.has(token))
234
+ throw new GatewayError("MANCODE_GATEWAY_UNAUTHORIZED_TOKEN");
235
+ return this.store.original(token);
236
+ });
237
+ }
238
+ finish(responseId) {
239
+ this.store.finish(this.authorized, responseId);
240
+ }
241
+ withoutKnownEchoes(value) {
242
+ let result = value;
243
+ const originals = [...this.authorized].map((token) => this.store.original(token)).sort((a, b) => b.length - a.length);
244
+ for (const original of originals) result = result.split(original).join("");
245
+ return result;
246
+ }
247
+ release() {
248
+ if (!this.released) {
249
+ this.released = true;
250
+ this.store.release(this.authorized);
251
+ }
252
+ }
253
+ };
254
+ var IncrementalRestorer = class {
255
+ constructor(mapping) {
256
+ this.mapping = mapping;
257
+ }
258
+ pending = "";
259
+ push(input, final = false) {
260
+ let value = this.pending + input;
261
+ this.pending = "";
262
+ if (!final) {
263
+ const tokenStart = value.lastIndexOf(TOKEN_PREFIX);
264
+ if (tokenStart >= 0 && value.length - tokenStart < TOKEN_PREFIX.length + 34) {
265
+ this.pending = value.slice(tokenStart);
266
+ value = value.slice(0, tokenStart);
267
+ } else
268
+ for (let length = TOKEN_PREFIX.length - 1; length > 0; length--) {
269
+ const lastComplete = [...value.matchAll(TOKEN_PATTERN)].at(-1);
270
+ const completeEnd = lastComplete ? lastComplete.index + lastComplete[0].length : 0;
271
+ if (value.length - length >= completeEnd && value.endsWith(TOKEN_PREFIX.slice(0, length))) {
272
+ this.pending = value.slice(-length);
273
+ value = value.slice(0, -length);
274
+ break;
275
+ }
276
+ }
277
+ }
278
+ return this.mapping.restore(value);
279
+ }
280
+ };
281
+
282
+ // src/gateway/protocol.ts
283
+ import { createHash } from "crypto";
284
+ import path from "path";
285
+ var SENSITIVE_NUMBER_KEY = /(?:phone|mobile|telephone|id_?card|card_?number|account_?number|ssn)/i;
286
+ var CREDENTIAL_KEY = /(?:^|[_-])(?:password|passwd|secret|token|api[_-]?key|access[_-]?key|authorization|cookie)$/i;
287
+ function assertNoSensitive(value, rules) {
288
+ const scan = scanSensitiveText(value, rules);
289
+ if (scan.status !== "complete")
290
+ throw new GatewayError("MANCODE_GATEWAY_SCAN_FAILED");
291
+ if (scan.findings.length || value.includes(TOKEN_PREFIX))
292
+ throw new GatewayError("MANCODE_GATEWAY_SENSITIVE_STRUCTURE");
293
+ }
294
+ function transformData(source, node, edits, mapping, restore, rules, key = "") {
295
+ const credential = !restore && CREDENTIAL_KEY.test(key) && (!rules || rules.includes("named-secret"));
296
+ if (credential && (node.type === "object" || node.type === "array"))
297
+ throw new GatewayError("MANCODE_GATEWAY_CREDENTIAL_CONTAINER_UNSUPPORTED");
298
+ if (node.type === "string") {
299
+ replaceString(
300
+ edits,
301
+ node,
302
+ restore ? mapping.restore(node.value) : credential ? mapping.maskLiteral(node.value) : mapping.mask(node.value, rules)
303
+ );
304
+ } else if (node.type === "number" && SENSITIVE_NUMBER_KEY.test(key) || credential && node.type !== "object" && node.type !== "array" && node.type !== "null") {
305
+ throw new GatewayError("MANCODE_GATEWAY_SENSITIVE_NUMBER");
306
+ } else if (node.type === "object") {
307
+ for (const field of node.children ?? []) {
308
+ const name = field.children?.[0];
309
+ const value = field.children?.[1];
310
+ if (!name || !value)
311
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_JSON");
312
+ assertNoSensitive(name.value, rules);
313
+ transformData(source, value, edits, mapping, restore, rules, name.value);
314
+ }
315
+ } else
316
+ for (const value of node.children ?? [])
317
+ transformData(source, value, edits, mapping, restore, rules, key);
318
+ }
319
+ function scanStructure(source, node, rules) {
320
+ if (node.type === "string") assertNoSensitive(node.value, rules);
321
+ else
322
+ for (const child of node.children ?? [])
323
+ scanStructure(source, child, rules);
324
+ }
325
+ function transformToolDefinitions(source, node, edits, mapping, rules, fieldName = "") {
326
+ if (node.type === "string" && (fieldName === "description" || fieldName === "title")) {
327
+ replaceString(edits, node, mapping.mask(node.value, rules));
328
+ return;
329
+ }
330
+ if (node.type === "object") {
331
+ for (const field of node.children ?? []) {
332
+ const key = field.children?.[0];
333
+ const value = field.children?.[1];
334
+ if (!key || !value)
335
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_JSON");
336
+ assertNoSensitive(key.value, rules);
337
+ if (key.value === "enum" || key.value === "const" || key.value === "pattern" || key.value === "required")
338
+ scanStructure(source, value, rules);
339
+ else
340
+ transformToolDefinitions(
341
+ source,
342
+ value,
343
+ edits,
344
+ mapping,
345
+ rules,
346
+ key.value
347
+ );
348
+ }
349
+ } else if (node.type === "array")
350
+ for (const child of node.children ?? [])
351
+ transformToolDefinitions(source, child, edits, mapping, rules, fieldName);
352
+ else scanStructure(source, node, rules);
353
+ }
354
+ function transformText(value, mapping, restore, rules) {
355
+ if (!restore && /^[\s]*[\[{]/.test(value)) {
356
+ try {
357
+ const tree = parseStrictJson(value);
358
+ const edits = [];
359
+ transformData(value, tree, edits, mapping, false, rules);
360
+ return applyJsonEdits(value, edits);
361
+ } catch (error) {
362
+ if (!(error instanceof GatewayError) || error.code !== "MANCODE_GATEWAY_INVALID_JSON")
363
+ throw error;
364
+ }
365
+ }
366
+ return restore ? mapping.restore(value) : mapping.mask(value, rules);
367
+ }
368
+ var CLAUDE_READ_SCHEMA_SHA256 = "384be111a755f235f20b1c632d0ed1a665e9f16d191f02108e80232c7fc4b488";
369
+ function canonical(value) {
370
+ if (Array.isArray(value)) return value.map(canonical);
371
+ if (value && typeof value === "object")
372
+ return Object.fromEntries(
373
+ Object.entries(value).sort(([a], [b]) => a.localeCompare(b, "en")).map(([key, child]) => [key, canonical(child)])
374
+ );
375
+ return value;
376
+ }
377
+ function restoreToolArguments(source, mapping, name) {
378
+ const tree = parseStrictJson(source);
379
+ let needsRestore = false;
380
+ const inspect = (node) => {
381
+ if (node.type === "string" && node.value.includes(TOKEN_PREFIX))
382
+ needsRestore = true;
383
+ for (const child of node.children ?? []) inspect(child);
384
+ };
385
+ inspect(tree);
386
+ if (!needsRestore) return source;
387
+ if (!mapping?.claudeReadAllowed || name !== "Read" || tree.type !== "object")
388
+ throw new GatewayError("MANCODE_GATEWAY_TOOL_SINK_UNSUPPORTED");
389
+ for (const field of tree.children ?? []) {
390
+ const key = field.children?.[0]?.value;
391
+ const value = field.children?.[1];
392
+ if (key === "file_path") continue;
393
+ if ((key === "offset" || key === "limit") && value?.type === "number" && Number.isSafeInteger(value.value) && value.value >= (key === "offset" ? 0 : 1))
394
+ continue;
395
+ if (key === "pages" && value?.type === "string" && /^\d+(?:-\d+)?$/.test(value.value))
396
+ continue;
397
+ throw new GatewayError("MANCODE_GATEWAY_TOOL_SINK_UNSUPPORTED");
398
+ }
399
+ const filePath = property(tree, "file_path");
400
+ if (filePath?.type !== "string" || !/^__MANCODE_[a-f0-9]{32}__$/.test(filePath.value))
401
+ throw new GatewayError("MANCODE_GATEWAY_TOOL_PATH_COMPOSITION");
402
+ const restored = mapping.restore(filePath.value);
403
+ if (!path.isAbsolute(restored) && !path.win32.isAbsolute(restored) || /[\0\r\n]/.test(restored) || restored.startsWith("//") || restored.startsWith("\\\\"))
404
+ throw new GatewayError("MANCODE_GATEWAY_TOOL_PATH_INVALID");
405
+ const edits = [];
406
+ replaceString(edits, filePath, restored);
407
+ return applyJsonEdits(source, edits);
408
+ }
409
+ function content(source, node, edits, mapping, restore, coverage, rules) {
410
+ if (node.type === "string") {
411
+ replaceString(
412
+ edits,
413
+ node,
414
+ transformText(node.value, mapping, restore, rules)
415
+ );
416
+ return;
417
+ }
418
+ if (node.type === "array") {
419
+ for (const child of node.children ?? [])
420
+ content(source, child, edits, mapping, restore, coverage, rules);
421
+ return;
422
+ }
423
+ if (node.type !== "object")
424
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_CONTENT");
425
+ const type = stringValue(property(node, "type"));
426
+ const allowed = {
427
+ message: ["type", "role", "content", "id", "status", "phase"],
428
+ input_text: ["type", "text", "cache_control"],
429
+ output_text: ["type", "text", "annotations", "logprobs"],
430
+ text: ["type", "text", "cache_control", "citations"],
431
+ refusal: ["type", "refusal"],
432
+ function_call: ["type", "id", "call_id", "name", "arguments", "status"],
433
+ tool_use: ["type", "id", "name", "input", "cache_control"],
434
+ function_call_output: ["type", "id", "call_id", "output", "status"],
435
+ tool_result: [
436
+ "type",
437
+ "tool_use_id",
438
+ "content",
439
+ "is_error",
440
+ "cache_control"
441
+ ],
442
+ thinking: ["type", "thinking", "signature", "cache_control"],
443
+ redacted_thinking: ["type", "data", "cache_control"],
444
+ reasoning: ["type", "id", "summary", "encrypted_content", "status"]
445
+ };
446
+ const keys = allowed[type ?? (property(node, "role") ? "message" : "")];
447
+ if (!keys || node.children?.some((field) => !keys.includes(field.children?.[0]?.value)))
448
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_CONTENT");
449
+ for (const name of [
450
+ "id",
451
+ "call_id",
452
+ "tool_use_id",
453
+ "name",
454
+ "role",
455
+ "status",
456
+ "phase",
457
+ "type"
458
+ ]) {
459
+ const value = property(node, name);
460
+ if (value && (value.type !== "string" || value.value.length > 256))
461
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_PROTOCOL_ID");
462
+ }
463
+ const cacheControl = property(node, "cache_control");
464
+ if (cacheControl) scanStructure(source, cacheControl, rules);
465
+ if (type === "thinking" || type === "redacted_thinking" || type === "reasoning") {
466
+ coverage.opaque++;
467
+ return;
468
+ }
469
+ if (type === "input_text" || type === "output_text" || type === "text" || type === "refusal") {
470
+ const field = property(node, type === "refusal" ? "refusal" : "text");
471
+ if (!field || field.type !== "string")
472
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_CONTENT");
473
+ replaceString(
474
+ edits,
475
+ field,
476
+ transformText(field.value, mapping, restore, rules)
477
+ );
478
+ for (const child of node.children ?? []) {
479
+ const name = child.children?.[0]?.value;
480
+ const value = child.children?.[1];
481
+ if (value && name !== "text" && name !== "refusal" && name !== "type")
482
+ scanStructure(source, value, rules);
483
+ }
484
+ return;
485
+ }
486
+ if (type === "function_call" || type === "tool_use") {
487
+ const args = property(
488
+ node,
489
+ type === "function_call" ? "arguments" : "input"
490
+ );
491
+ if (!args) throw new GatewayError("MANCODE_GATEWAY_TOOL_ARGUMENTS_MISSING");
492
+ if (args.type === "string") {
493
+ const inner = args.value;
494
+ if (restore)
495
+ replaceString(
496
+ edits,
497
+ args,
498
+ restoreToolArguments(
499
+ inner,
500
+ mapping,
501
+ stringValue(property(node, "name"))
502
+ )
503
+ );
504
+ else {
505
+ const innerEdits = [];
506
+ transformData(
507
+ inner,
508
+ parseStrictJson(inner),
509
+ innerEdits,
510
+ mapping,
511
+ false,
512
+ rules
513
+ );
514
+ replaceString(edits, args, applyJsonEdits(inner, innerEdits));
515
+ }
516
+ } else if (type === "tool_use" && args.type === "object") {
517
+ if (restore) {
518
+ const restored = restoreToolArguments(
519
+ source.slice(args.offset, args.offset + args.length),
520
+ mapping,
521
+ stringValue(property(node, "name"))
522
+ );
523
+ edits.push({
524
+ offset: args.offset,
525
+ length: args.length,
526
+ text: restored
527
+ });
528
+ } else transformData(source, args, edits, mapping, false, rules);
529
+ } else throw new GatewayError("MANCODE_GATEWAY_INVALID_TOOL_ARGUMENTS");
530
+ return;
531
+ }
532
+ if (type === "function_call_output" || type === "tool_result") {
533
+ const field = property(
534
+ node,
535
+ type === "function_call_output" ? "output" : "content"
536
+ );
537
+ if (!field) throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_CONTENT");
538
+ content(source, field, edits, mapping, restore, coverage, rules);
539
+ return;
540
+ }
541
+ if (type === "message" || !type && property(node, "role")) {
542
+ const field = property(node, "content");
543
+ if (!field) throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_CONTENT");
544
+ content(source, field, edits, mapping, restore, coverage, rules);
545
+ return;
546
+ }
547
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_CONTENT");
548
+ }
549
+ var REQUEST_FIELDS = {
550
+ responses: /* @__PURE__ */ new Set([
551
+ "model",
552
+ "input",
553
+ "instructions",
554
+ "tools",
555
+ "tool_choice",
556
+ "parallel_tool_calls",
557
+ "store",
558
+ "stream",
559
+ "temperature",
560
+ "top_p",
561
+ "max_output_tokens",
562
+ "text",
563
+ "reasoning",
564
+ "metadata",
565
+ "previous_response_id",
566
+ "include",
567
+ "service_tier",
568
+ "prompt_cache_key",
569
+ "prompt_cache_retention",
570
+ "truncation",
571
+ "user",
572
+ "safety_identifier",
573
+ "client_metadata"
574
+ ]),
575
+ messages: /* @__PURE__ */ new Set([
576
+ "model",
577
+ "messages",
578
+ "system",
579
+ "tools",
580
+ "tool_choice",
581
+ "stream",
582
+ "temperature",
583
+ "top_p",
584
+ "top_k",
585
+ "max_tokens",
586
+ "stop_sequences",
587
+ "metadata",
588
+ "thinking",
589
+ "service_tier",
590
+ "context_management",
591
+ "output_config"
592
+ ])
593
+ };
594
+ function transformRequest(source, protocol, mapping, rules, verifiedHost) {
595
+ const tree = parseStrictJson(source);
596
+ const edits = [];
597
+ const coverage = { opaque: 0 };
598
+ if (tree.type !== "object")
599
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_REQUEST");
600
+ const bodyField = protocol === "responses" ? "input" : "messages";
601
+ if (!property(tree, bodyField))
602
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_REQUEST");
603
+ for (const child of tree.children ?? []) {
604
+ const name = child.children?.[0]?.value;
605
+ const value = child.children?.[1];
606
+ if (!value || !REQUEST_FIELDS[protocol].has(name))
607
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_FIELD");
608
+ if (name === bodyField || name === "system" || name === "instructions")
609
+ content(source, value, edits, mapping, false, coverage, rules);
610
+ else if (name === "metadata" || name === "client_metadata")
611
+ transformData(source, value, edits, mapping, false, rules);
612
+ else if (name === "context_management") {
613
+ const control = JSON.parse(
614
+ source.slice(value.offset, value.offset + value.length)
615
+ );
616
+ if (JSON.stringify(canonical(control)) !== JSON.stringify(
617
+ canonical({
618
+ edits: [{ type: "clear_thinking_20251015", keep: "all" }]
619
+ })
620
+ ))
621
+ throw new GatewayError("MANCODE_GATEWAY_CONTEXT_CONTROL_UNSUPPORTED");
622
+ } else if (name === "output_config") {
623
+ const effort = stringValue(property(value, "effort"));
624
+ if (value.type !== "object" || value.children?.length !== 1 || !effort || !["low", "medium", "high", "max"].includes(effort))
625
+ throw new GatewayError("MANCODE_GATEWAY_OUTPUT_CONFIG_UNSUPPORTED");
626
+ } else if (name === "previous_response_id") {
627
+ if (value.type !== "string")
628
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_HISTORY");
629
+ } else {
630
+ if (name === "tools" && protocol === "messages" && verifiedHost === "claude-code/2.1.142") {
631
+ for (const tool of value.children ?? []) {
632
+ const schema = property(tool, "input_schema");
633
+ if (stringValue(property(tool, "name")) === "Read" && schema) {
634
+ const schemaValue = JSON.parse(
635
+ source.slice(schema.offset, schema.offset + schema.length)
636
+ );
637
+ const digest = createHash("sha256").update(JSON.stringify(canonical(schemaValue))).digest("hex");
638
+ mapping.claudeReadAllowed = digest === CLAUDE_READ_SCHEMA_SHA256;
639
+ }
640
+ }
641
+ }
642
+ if (name === "tools")
643
+ transformToolDefinitions(source, value, edits, mapping, rules);
644
+ else scanStructure(source, value, rules);
645
+ }
646
+ }
647
+ return { body: applyJsonEdits(source, edits), opaqueBlocks: coverage.opaque };
648
+ }
649
+ function transformResponse(source, protocol, mapping) {
650
+ const tree = parseStrictJson(source);
651
+ const edits = [];
652
+ const coverage = { opaque: 0 };
653
+ const output = property(
654
+ tree,
655
+ protocol === "responses" ? "output" : "content"
656
+ );
657
+ if (!output) throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_RESPONSE");
658
+ content(source, output, edits, mapping, true, coverage);
659
+ return { body: applyJsonEdits(source, edits), opaqueBlocks: coverage.opaque };
660
+ }
661
+ function transformContentItem(source, mapping) {
662
+ const tree = parseStrictJson(source);
663
+ const edits = [];
664
+ const coverage = { opaque: 0 };
665
+ content(source, tree, edits, mapping, true, coverage);
666
+ return { body: applyJsonEdits(source, edits), opaqueBlocks: coverage.opaque };
667
+ }
668
+
669
+ // src/gateway/sse.ts
670
+ var SseDecoder = class {
671
+ constructor(maxEventBytes = 256 * 1024) {
672
+ this.maxEventBytes = maxEventBytes;
673
+ }
674
+ decoder = new TextDecoder("utf-8", { fatal: true });
675
+ pending = "";
676
+ push(chunk, final = false) {
677
+ try {
678
+ this.pending += this.decoder.decode(chunk, { stream: !final });
679
+ } catch {
680
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_UTF8");
681
+ }
682
+ const frames = [];
683
+ for (; ; ) {
684
+ const match = /\r?\n\r?\n/.exec(this.pending);
685
+ if (!match) break;
686
+ const block = this.pending.slice(0, match.index);
687
+ this.pending = this.pending.slice(match.index + match[0].length);
688
+ if (Buffer.byteLength(block) > this.maxEventBytes)
689
+ throw new GatewayError("MANCODE_GATEWAY_EVENT_LIMIT");
690
+ let event;
691
+ const data = [];
692
+ for (const line of block.split(/\r?\n/)) {
693
+ if (line.startsWith(":") || line === "") continue;
694
+ const colon = line.indexOf(":");
695
+ const name = colon < 0 ? line : line.slice(0, colon);
696
+ const value = colon < 0 ? "" : line.slice(colon + 1).replace(/^ /, "");
697
+ if (name === "event") event = value;
698
+ else if (name === "data") data.push(value);
699
+ else throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_SSE_FIELD");
700
+ }
701
+ if (data.length) frames.push({ event, data: data.join("\n") });
702
+ if (frames.length > 256)
703
+ throw new GatewayError("MANCODE_GATEWAY_EVENT_QUEUE_LIMIT");
704
+ }
705
+ if (Buffer.byteLength(this.pending) > this.maxEventBytes)
706
+ throw new GatewayError("MANCODE_GATEWAY_EVENT_LIMIT");
707
+ if (final && this.pending.trim())
708
+ throw new GatewayError("MANCODE_GATEWAY_TRUNCATED_SSE");
709
+ return frames;
710
+ }
711
+ };
712
+ function encodeSse(frame) {
713
+ return `${frame.event ? `event: ${frame.event}
714
+ ` : ""}${frame.data.split("\n").map((line) => `data: ${line}`).join("\n")}
715
+
716
+ `;
717
+ }
718
+ var RESPONSE_METADATA = /* @__PURE__ */ new Set(["response.in_progress", "response.queued"]);
719
+ var OPAQUE_EVENTS = /* @__PURE__ */ new Set([
720
+ "response.reasoning_summary_part.added",
721
+ "response.reasoning_summary_part.done",
722
+ "response.reasoning_summary_text.delta",
723
+ "response.reasoning_summary_text.done",
724
+ "response.reasoning_text.delta",
725
+ "response.reasoning_text.done"
726
+ ]);
727
+ var ProtocolStream = class {
728
+ constructor(protocol, mapping, maxChannels = 128, maxToolBytes = 256 * 1024) {
729
+ this.protocol = protocol;
730
+ this.mapping = mapping;
731
+ this.maxChannels = maxChannels;
732
+ this.maxToolBytes = maxToolBytes;
733
+ }
734
+ texts = /* @__PURE__ */ new Map();
735
+ tools = /* @__PURE__ */ new Map();
736
+ anthropicTypes = /* @__PURE__ */ new Map();
737
+ responseId;
738
+ completed = false;
739
+ opaqueBlocks = 0;
740
+ accept(frame) {
741
+ if (frame.data === "[DONE]") {
742
+ if (!this.completed)
743
+ throw new GatewayError("MANCODE_GATEWAY_TRUNCATED_RESPONSE");
744
+ return [frame];
745
+ }
746
+ if (this.completed)
747
+ throw new GatewayError("MANCODE_GATEWAY_EVENT_AFTER_DONE");
748
+ const tree = parseStrictJson(frame.data);
749
+ const type = stringValue(property(tree, "type"));
750
+ if (!type || frame.event && frame.event !== type)
751
+ throw new GatewayError("MANCODE_GATEWAY_EVENT_TYPE_MISMATCH");
752
+ return this.protocol === "responses" ? this.responses(frame, tree, type) : this.messages(frame, tree, type);
753
+ }
754
+ finish() {
755
+ if (!this.completed)
756
+ throw new GatewayError("MANCODE_GATEWAY_TRUNCATED_RESPONSE");
757
+ for (const channel of this.texts.values())
758
+ if (!channel.closed)
759
+ throw new GatewayError("MANCODE_GATEWAY_UNFINISHED_CHANNEL");
760
+ for (const channel of this.tools.values())
761
+ if (!channel.closed)
762
+ throw new GatewayError("MANCODE_GATEWAY_UNFINISHED_TOOL");
763
+ }
764
+ key(tree) {
765
+ const index = property(tree, "output_index")?.value;
766
+ const content2 = property(tree, "content_index")?.value ?? 0;
767
+ const item = stringValue(property(tree, "item_id"));
768
+ if (!Number.isSafeInteger(index) || index < 0 || !Number.isSafeInteger(content2) || content2 < 0 || !item || item.length > 256)
769
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_ID_INVALID");
770
+ return `${index}:${content2}:${item}`;
771
+ }
772
+ limitChannels() {
773
+ if (this.texts.size + this.tools.size >= this.maxChannels)
774
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_LIMIT");
775
+ }
776
+ textDelta(key, delta, done = false) {
777
+ let channel = this.texts.get(key);
778
+ if (!channel) {
779
+ this.limitChannels();
780
+ channel = {
781
+ restorer: new IncrementalRestorer(this.mapping),
782
+ closed: false
783
+ };
784
+ this.texts.set(key, channel);
785
+ }
786
+ if (channel.closed)
787
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_ALREADY_DONE");
788
+ const restored = channel.restorer.push(delta, done);
789
+ channel.closed = done;
790
+ return restored;
791
+ }
792
+ toolDelta(key, delta) {
793
+ let channel = this.tools.get(key);
794
+ if (!channel) {
795
+ this.limitChannels();
796
+ channel = { arguments: "", closed: false };
797
+ this.tools.set(key, channel);
798
+ }
799
+ if (channel.closed)
800
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_ALREADY_DONE");
801
+ if (Buffer.byteLength(channel.arguments) + Buffer.byteLength(delta) > this.maxToolBytes)
802
+ throw new GatewayError("MANCODE_GATEWAY_TOOL_LIMIT");
803
+ channel.arguments += delta;
804
+ }
805
+ toolDone(key, snapshot) {
806
+ const channel = this.tools.get(key);
807
+ if (channel?.closed)
808
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_ALREADY_DONE");
809
+ if (snapshot !== void 0 && channel?.arguments && snapshot !== channel.arguments)
810
+ throw new GatewayError("MANCODE_GATEWAY_TOOL_SNAPSHOT_MISMATCH");
811
+ const argumentsText = snapshot ?? (channel?.arguments || "{}");
812
+ const restored = restoreToolArguments(
813
+ argumentsText,
814
+ this.mapping,
815
+ channel?.name
816
+ );
817
+ if (channel) channel.closed = true;
818
+ return restored;
819
+ }
820
+ responses(frame, tree, type) {
821
+ if (type === "response.created") {
822
+ if (this.responseId)
823
+ throw new GatewayError("MANCODE_GATEWAY_DUPLICATE_RESPONSE");
824
+ const response = property(tree, "response");
825
+ this.responseId = response && stringValue(property(response, "id"));
826
+ if (!this.responseId)
827
+ throw new GatewayError("MANCODE_GATEWAY_RESPONSE_ID_MISSING");
828
+ const output = response && property(response, "output");
829
+ if (output?.children?.length)
830
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_RESPONSE");
831
+ return [frame];
832
+ }
833
+ if (type === "response.output_text.delta" || type === "response.refusal.delta") {
834
+ const delta = property(tree, "delta");
835
+ if (delta?.type !== "string")
836
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_DELTA");
837
+ const edits = [];
838
+ const value = this.textDelta(this.key(tree), delta.value);
839
+ replaceString(edits, delta, value);
840
+ return value ? [{ ...frame, data: applyJsonEdits(frame.data, edits) }] : [];
841
+ }
842
+ if (type === "response.output_text.done" || type === "response.refusal.done") {
843
+ const fieldName = type === "response.refusal.done" ? "refusal" : "text";
844
+ const field = property(tree, fieldName);
845
+ if (field?.type !== "string")
846
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_DELTA");
847
+ const tail = this.textDelta(this.key(tree), "", true);
848
+ const edits = [];
849
+ replaceString(edits, field, this.mapping.restore(field.value));
850
+ const output = [];
851
+ if (tail) {
852
+ const delta = {
853
+ type: type.replace(/\.done$/, ".delta"),
854
+ item_id: property(tree, "item_id")?.value,
855
+ output_index: property(tree, "output_index")?.value,
856
+ content_index: property(tree, "content_index")?.value,
857
+ delta: tail
858
+ };
859
+ output.push({ event: delta.type, data: JSON.stringify(delta) });
860
+ }
861
+ output.push({ ...frame, data: applyJsonEdits(frame.data, edits) });
862
+ return output;
863
+ }
864
+ if (type === "response.function_call_arguments.delta") {
865
+ const delta = stringValue(property(tree, "delta"));
866
+ if (delta === void 0)
867
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_DELTA");
868
+ if (!this.tools.has(this.key(tree)))
869
+ throw new GatewayError("MANCODE_GATEWAY_UNKNOWN_TOOL_CHANNEL");
870
+ this.toolDelta(this.key(tree), delta);
871
+ return [];
872
+ }
873
+ if (type === "response.function_call_arguments.done") {
874
+ const args = stringValue(property(tree, "arguments"));
875
+ if (args === void 0)
876
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_TOOL_ARGUMENTS");
877
+ const value = this.toolDone(this.key(tree), args);
878
+ const delta = {
879
+ type: "response.function_call_arguments.delta",
880
+ item_id: property(tree, "item_id")?.value,
881
+ output_index: property(tree, "output_index")?.value,
882
+ delta: value
883
+ };
884
+ return [{ event: delta.type, data: JSON.stringify(delta) }, frame];
885
+ }
886
+ if (type === "response.output_item.added" || type === "response.output_item.done" || type === "response.content_part.added" || type === "response.content_part.done") {
887
+ const item = property(
888
+ tree,
889
+ type.includes("output_item") ? "item" : "part"
890
+ );
891
+ if (!item) throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_EVENT");
892
+ if (type === "response.output_item.added" && stringValue(property(item, "type")) === "function_call" && stringValue(property(item, "arguments")) !== "")
893
+ throw new GatewayError("MANCODE_GATEWAY_NONEMPTY_INITIAL_TOOL");
894
+ if (type === "response.output_item.added" && stringValue(property(item, "type")) === "function_call" && stringValue(property(item, "arguments")) === "") {
895
+ const itemSource = frame.data.slice(
896
+ item.offset,
897
+ item.offset + item.length
898
+ );
899
+ const itemTree = parseStrictJson(itemSource);
900
+ const argumentsNode = property(itemTree, "arguments");
901
+ if (!argumentsNode)
902
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_TOOL_ARGUMENTS");
903
+ transformContentItem(
904
+ applyJsonEdits(itemSource, [
905
+ {
906
+ offset: argumentsNode.offset,
907
+ length: argumentsNode.length,
908
+ text: JSON.stringify("{}")
909
+ }
910
+ ]),
911
+ this.mapping
912
+ );
913
+ const index = property(tree, "output_index")?.value;
914
+ const itemId = stringValue(property(item, "id"));
915
+ if (!Number.isSafeInteger(index) || index < 0 || !itemId)
916
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_ID_INVALID");
917
+ const key = `${index}:0:${itemId}`;
918
+ if (this.tools.has(key))
919
+ throw new GatewayError("MANCODE_GATEWAY_DUPLICATE_TOOL");
920
+ this.toolDelta(key, "");
921
+ const channel = this.tools.get(key);
922
+ channel.name = stringValue(property(item, "name"));
923
+ return [frame];
924
+ }
925
+ const result = transformContentItem(
926
+ frame.data.slice(item.offset, item.offset + item.length),
927
+ this.mapping
928
+ );
929
+ this.opaqueBlocks += result.opaqueBlocks;
930
+ return [
931
+ {
932
+ ...frame,
933
+ data: applyJsonEdits(frame.data, [
934
+ { offset: item.offset, length: item.length, text: result.body }
935
+ ])
936
+ }
937
+ ];
938
+ }
939
+ if (type === "response.completed") {
940
+ const response = property(tree, "response");
941
+ if (!response || stringValue(property(response, "id")) !== this.responseId)
942
+ throw new GatewayError("MANCODE_GATEWAY_RESPONSE_SCOPE_MISMATCH");
943
+ const result = transformResponse(
944
+ frame.data.slice(response.offset, response.offset + response.length),
945
+ "responses",
946
+ this.mapping
947
+ );
948
+ this.opaqueBlocks += result.opaqueBlocks;
949
+ this.completed = true;
950
+ this.finish();
951
+ return [
952
+ {
953
+ ...frame,
954
+ data: applyJsonEdits(frame.data, [
955
+ {
956
+ offset: response.offset,
957
+ length: response.length,
958
+ text: result.body
959
+ }
960
+ ])
961
+ }
962
+ ];
963
+ }
964
+ if (OPAQUE_EVENTS.has(type)) {
965
+ this.opaqueBlocks++;
966
+ return [frame];
967
+ }
968
+ if (RESPONSE_METADATA.has(type)) return [frame];
969
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_EVENT");
970
+ }
971
+ messages(frame, tree, type) {
972
+ if (type === "ping") return [frame];
973
+ if (type === "message_start") {
974
+ if (this.responseId)
975
+ throw new GatewayError("MANCODE_GATEWAY_DUPLICATE_RESPONSE");
976
+ const message = property(tree, "message");
977
+ this.responseId = message && stringValue(property(message, "id"));
978
+ if (!this.responseId || property(message, "content")?.children?.length)
979
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_RESPONSE");
980
+ return [frame];
981
+ }
982
+ if (type === "message_delta") return [frame];
983
+ if (type === "message_stop") {
984
+ this.completed = true;
985
+ this.finish();
986
+ return [frame];
987
+ }
988
+ const index = property(tree, "index")?.value;
989
+ if (!Number.isSafeInteger(index) || index < 0)
990
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_ID_INVALID");
991
+ const key = `messages:${index}`;
992
+ if (type === "content_block_start") {
993
+ if (this.anthropicTypes.has(index) || this.anthropicTypes.size >= this.maxChannels)
994
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_LIMIT");
995
+ const block = property(tree, "content_block");
996
+ const blockType = block && stringValue(property(block, "type"));
997
+ if (!block || !blockType)
998
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_EVENT");
999
+ this.anthropicTypes.set(index, blockType);
1000
+ if (blockType === "tool_use") {
1001
+ const input = property(block, "input");
1002
+ if (input?.type !== "object" || input.children?.length)
1003
+ throw new GatewayError("MANCODE_GATEWAY_NONEMPTY_INITIAL_TOOL");
1004
+ transformContentItem(
1005
+ frame.data.slice(block.offset, block.offset + block.length),
1006
+ this.mapping
1007
+ );
1008
+ this.toolDelta(key, "");
1009
+ const channel = this.tools.get(key);
1010
+ channel.initial = frame;
1011
+ channel.name = stringValue(property(block, "name"));
1012
+ return [];
1013
+ }
1014
+ const result = transformContentItem(
1015
+ frame.data.slice(block.offset, block.offset + block.length),
1016
+ this.mapping
1017
+ );
1018
+ this.opaqueBlocks += result.opaqueBlocks;
1019
+ return [
1020
+ {
1021
+ ...frame,
1022
+ data: applyJsonEdits(frame.data, [
1023
+ { offset: block.offset, length: block.length, text: result.body }
1024
+ ])
1025
+ }
1026
+ ];
1027
+ }
1028
+ if (type === "content_block_delta") {
1029
+ const delta = property(tree, "delta");
1030
+ const deltaType = delta && stringValue(property(delta, "type"));
1031
+ if (!delta) throw new GatewayError("MANCODE_GATEWAY_INVALID_DELTA");
1032
+ if (deltaType === "input_json_delta" && this.anthropicTypes.get(index) === "tool_use") {
1033
+ const value = stringValue(property(delta, "partial_json"));
1034
+ if (value === void 0)
1035
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_DELTA");
1036
+ this.toolDelta(key, value);
1037
+ return [];
1038
+ }
1039
+ if (deltaType === "text_delta" && this.anthropicTypes.get(index) === "text") {
1040
+ const field = property(delta, "text");
1041
+ if (field?.type !== "string")
1042
+ throw new GatewayError("MANCODE_GATEWAY_INVALID_DELTA");
1043
+ const edits = [];
1044
+ const value = this.textDelta(key, field.value);
1045
+ replaceString(edits, field, value);
1046
+ return value ? [{ ...frame, data: applyJsonEdits(frame.data, edits) }] : [];
1047
+ }
1048
+ if ((deltaType === "thinking_delta" || deltaType === "signature_delta") && this.anthropicTypes.get(index) === "thinking") {
1049
+ this.opaqueBlocks++;
1050
+ return [frame];
1051
+ }
1052
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_EVENT");
1053
+ }
1054
+ if (type === "content_block_stop") {
1055
+ if (!this.anthropicTypes.has(index))
1056
+ throw new GatewayError("MANCODE_GATEWAY_CHANNEL_ID_INVALID");
1057
+ const tool = this.tools.get(key);
1058
+ if (tool) {
1059
+ const args = this.toolDone(key);
1060
+ const delta = {
1061
+ type: "content_block_delta",
1062
+ index,
1063
+ delta: { type: "input_json_delta", partial_json: args }
1064
+ };
1065
+ return [
1066
+ tool.initial,
1067
+ { event: delta.type, data: JSON.stringify(delta) },
1068
+ frame
1069
+ ];
1070
+ }
1071
+ const tail = this.texts.has(key) ? this.textDelta(key, "", true) : "";
1072
+ if (tail) {
1073
+ const delta = {
1074
+ type: "content_block_delta",
1075
+ index,
1076
+ delta: { type: "text_delta", text: tail }
1077
+ };
1078
+ return [{ event: delta.type, data: JSON.stringify(delta) }, frame];
1079
+ }
1080
+ return [frame];
1081
+ }
1082
+ throw new GatewayError("MANCODE_GATEWAY_UNSUPPORTED_EVENT");
1083
+ }
1084
+ };
1085
+
1086
+ export {
1087
+ GatewayError,
1088
+ gatewayErrorCode,
1089
+ parseStrictJson,
1090
+ property,
1091
+ stringValue,
1092
+ MappingStore,
1093
+ transformRequest,
1094
+ transformResponse,
1095
+ SseDecoder,
1096
+ encodeSse,
1097
+ ProtocolStream
1098
+ };
1099
+ //# sourceMappingURL=chunk-GI24QVXE.js.map