@codeproxy/core 0.1.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/dist/index.js ADDED
@@ -0,0 +1,2111 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
+
9
+ // src/translate/anthropic/index.ts
10
+ var anthropic_exports = {};
11
+ __export(anthropic_exports, {
12
+ mapOutputItems: () => mapOutputItems,
13
+ translateAnthropicEvents: () => translateAnthropicEvents,
14
+ translateRequest: () => translateRequest,
15
+ translateResponse: () => translateResponse,
16
+ translateStream: () => translateStream
17
+ });
18
+
19
+ // src/utils/id.ts
20
+ var counter = 0;
21
+ function nextSeq() {
22
+ counter = counter + 1 & 2147483647;
23
+ return counter;
24
+ }
25
+ function makeId(prefix) {
26
+ return `${prefix}_${Date.now()}_${nextSeq()}`;
27
+ }
28
+
29
+ // src/translate/anthropic/translateRequest.ts
30
+ var ANTHROPIC_BUILTIN_TOOL_TYPES = /* @__PURE__ */ new Set([
31
+ "web_search_20250305",
32
+ "computer_use_20250124",
33
+ "text_editor_20250124",
34
+ "bash_20250124"
35
+ ]);
36
+ var DEFAULT_REASONING_BUDGETS = {
37
+ minimal: 1024,
38
+ low: 4096,
39
+ medium: 16384,
40
+ high: 32768,
41
+ xhigh: 65536
42
+ };
43
+ function translateRequest(data, options = {}) {
44
+ const model = data.model;
45
+ const maxTokens = typeof data.max_output_tokens === "number" && data.max_output_tokens || typeof data.max_tokens === "number" && data.max_tokens || options.defaultMaxTokens || 8192;
46
+ const systemBlocks = extractSystemBlocks(data.instructions);
47
+ const built = buildMessages(data, systemBlocks);
48
+ let messages = built.messages;
49
+ const hasPromptCache = built.hasPromptCache;
50
+ messages = repairToolAdjacency(messages);
51
+ messages = sanitizeMessages(messages);
52
+ messages = ensureEndsWithUser(messages);
53
+ const request = {
54
+ model,
55
+ messages,
56
+ max_tokens: maxTokens
57
+ };
58
+ if (systemBlocks.length) {
59
+ request.system = systemBlocks;
60
+ }
61
+ if (typeof data.temperature === "number") {
62
+ request.temperature = data.temperature;
63
+ }
64
+ if (typeof data.top_p === "number") {
65
+ request.top_p = data.top_p;
66
+ }
67
+ const tools = mapTools(data.tools || []);
68
+ if (tools.length) {
69
+ request.tools = tools;
70
+ const toolChoice = mapToolChoice(data.tool_choice);
71
+ if (toolChoice) {
72
+ request.tool_choice = toolChoice;
73
+ }
74
+ }
75
+ if (data.metadata && typeof data.metadata === "object") {
76
+ request.metadata = data.metadata;
77
+ }
78
+ const thinking = mapThinking(data, maxTokens, options.reasoningBudgets);
79
+ if (thinking) {
80
+ request.thinking = thinking;
81
+ }
82
+ return { request, hasPromptCache };
83
+ }
84
+ function extractSystemBlocks(instructions) {
85
+ if (!instructions) {
86
+ return [];
87
+ }
88
+ if (typeof instructions === "string") {
89
+ return [{ type: "text", text: instructions }];
90
+ }
91
+ if (!Array.isArray(instructions)) {
92
+ return [];
93
+ }
94
+ const blocks = [];
95
+ for (const item of instructions) {
96
+ if (typeof item === "string") {
97
+ blocks.push({ type: "text", text: item });
98
+ } else if (item && typeof item === "object") {
99
+ const block = {
100
+ type: "text",
101
+ text: String(item.text ?? "")
102
+ };
103
+ const cacheItem = item;
104
+ const cache = cacheItem.cache_control;
105
+ if (cache) {
106
+ block.cache_control = cache;
107
+ }
108
+ blocks.push(block);
109
+ }
110
+ }
111
+ return blocks;
112
+ }
113
+ function buildMessages(data, systemBlocks) {
114
+ const messages = [];
115
+ let hasPromptCache = false;
116
+ let pendingToolUses = [];
117
+ let pendingToolResults = [];
118
+ const flushToolUses = () => {
119
+ if (pendingToolUses.length) {
120
+ messages.push({ role: "assistant", content: pendingToolUses });
121
+ pendingToolUses = [];
122
+ }
123
+ };
124
+ const flushToolResults = () => {
125
+ if (pendingToolResults.length) {
126
+ messages.push({ role: "user", content: pendingToolResults });
127
+ pendingToolResults = [];
128
+ }
129
+ };
130
+ const flushPending = () => {
131
+ flushToolUses();
132
+ flushToolResults();
133
+ };
134
+ const rawInput = data.input;
135
+ const inputItems = typeof rawInput === "string" ? [rawInput] : Array.isArray(rawInput) ? rawInput : [];
136
+ for (const raw of inputItems) {
137
+ if (typeof raw === "string") {
138
+ flushPending();
139
+ messages.push({ role: "user", content: [{ type: "text", text: raw }] });
140
+ continue;
141
+ }
142
+ if (!raw || typeof raw !== "object") {
143
+ continue;
144
+ }
145
+ const item = raw;
146
+ const itemType = String(item.type || "message");
147
+ if (itemType === "function_call_output" || itemType === "commandExecutionOutput" || itemType === "fileChangeOutput" || itemType === "custom_tool_call_output") {
148
+ flushToolUses();
149
+ const callId = String(item.call_id || item.id || makeId("call"));
150
+ pendingToolResults.push({
151
+ type: "tool_result",
152
+ tool_use_id: callId,
153
+ content: extractToolOutputText(item)
154
+ });
155
+ continue;
156
+ }
157
+ if (itemType === "function_call" || itemType === "commandExecution" || itemType === "local_shell_call" || itemType === "fileChange" || itemType === "custom_tool_call" || itemType === "web_search_call") {
158
+ flushToolResults();
159
+ const block = mapInputToolCall(item);
160
+ if (block) {
161
+ pendingToolUses.push(block);
162
+ }
163
+ continue;
164
+ }
165
+ if (itemType === "reasoning") {
166
+ flushPending();
167
+ continue;
168
+ }
169
+ if (itemType === "message" || itemType === "agentMessage") {
170
+ flushPending();
171
+ let role = String(item.role || "user");
172
+ if (role === "developer") {
173
+ role = "system";
174
+ }
175
+ if (role === "system") {
176
+ const text = extractMessageText(item);
177
+ if (text) {
178
+ systemBlocks.push({ type: "text", text });
179
+ }
180
+ continue;
181
+ }
182
+ const contentBlocks = [];
183
+ const rawContent = item.content;
184
+ if (typeof rawContent === "string") {
185
+ contentBlocks.push({ type: "text", text: rawContent });
186
+ } else if (Array.isArray(rawContent)) {
187
+ for (const part of rawContent) {
188
+ if (typeof part === "string") {
189
+ contentBlocks.push({ type: "text", text: part });
190
+ } else if (part && typeof part === "object") {
191
+ const contentPart = part;
192
+ if (contentPart.type === "input_text" || contentPart.type === "text" || contentPart.type === "output_text") {
193
+ contentBlocks.push({ type: "text", text: String(contentPart.text ?? "") });
194
+ } else if (contentPart.type === "input_image" || contentPart.type === "image" || contentPart.type === "image_url") {
195
+ const imgUrlPart = contentPart;
196
+ const imgUrl = imgUrlPart.image_url;
197
+ const urlStr = typeof imgUrl === "string" ? imgUrl : imgUrl && typeof imgUrl === "object" ? imgUrl.url : "";
198
+ if (urlStr.startsWith("data:")) {
199
+ const match = /^data:([^;,]+);base64,(.*)$/.exec(urlStr);
200
+ if (match) {
201
+ contentBlocks.push({
202
+ type: "image",
203
+ source: { type: "base64", media_type: match[1], data: match[2] }
204
+ });
205
+ }
206
+ } else if (urlStr) {
207
+ const imgSource = { type: "url", url: urlStr };
208
+ contentBlocks.push({
209
+ type: "image",
210
+ source: imgSource
211
+ });
212
+ } else {
213
+ const data2 = String(contentPart.data ?? contentPart.base64 ?? "");
214
+ if (data2) {
215
+ contentBlocks.push({
216
+ type: "image",
217
+ source: {
218
+ type: "base64",
219
+ media_type: contentPart.mime_type || contentPart.media_type || "image/png",
220
+ data: data2
221
+ }
222
+ });
223
+ }
224
+ }
225
+ } else if (contentPart.type === "input_file") {
226
+ contentBlocks.push({
227
+ type: "document",
228
+ source: {
229
+ type: "base64",
230
+ media_type: contentPart.mime_type || "application/pdf",
231
+ data: String(contentPart.data ?? "")
232
+ }
233
+ });
234
+ }
235
+ }
236
+ }
237
+ }
238
+ if (role === "assistant" || role === "model") {
239
+ if (contentBlocks.length) {
240
+ messages.push({ role: "assistant", content: contentBlocks });
241
+ }
242
+ } else {
243
+ if (contentBlocks.length) {
244
+ messages.push({ role: "user", content: contentBlocks });
245
+ }
246
+ }
247
+ continue;
248
+ }
249
+ }
250
+ flushPending();
251
+ for (const block of systemBlocks) {
252
+ if (block.cache_control) {
253
+ hasPromptCache = true;
254
+ }
255
+ }
256
+ return { messages, hasPromptCache };
257
+ }
258
+ function extractMessageText(item) {
259
+ const rawContent = item.content;
260
+ if (typeof rawContent === "string") {
261
+ return rawContent;
262
+ }
263
+ if (Array.isArray(rawContent)) {
264
+ let out = "";
265
+ for (const part of rawContent) {
266
+ if (typeof part === "string") {
267
+ out += part;
268
+ } else if (part && typeof part === "object") {
269
+ out += String(part.text ?? "");
270
+ }
271
+ }
272
+ return out;
273
+ }
274
+ return "";
275
+ }
276
+ function extractToolOutputText(item) {
277
+ const raw = item.output ?? item.content ?? item.stdout ?? "";
278
+ if (typeof raw === "string") {
279
+ return raw;
280
+ }
281
+ if (Array.isArray(raw)) {
282
+ let out = "";
283
+ for (const part of raw) {
284
+ if (typeof part === "string") {
285
+ out += part;
286
+ } else if (part && typeof part === "object") {
287
+ out += String(part.text ?? "");
288
+ }
289
+ }
290
+ return out;
291
+ }
292
+ if (raw && typeof raw === "object") {
293
+ return String(raw.content ?? "");
294
+ }
295
+ return "";
296
+ }
297
+ function mapInputToolCall(item) {
298
+ const callId = String(item.call_id || item.id || makeId("call"));
299
+ let name = typeof item.name === "string" ? item.name : void 0;
300
+ const itemType = typeof item.type === "string" ? item.type : void 0;
301
+ if (!name) {
302
+ if (itemType === "commandExecution") {
303
+ name = "run_shell_command";
304
+ } else if (itemType === "local_shell_call") {
305
+ name = "local_shell_command";
306
+ } else if (itemType === "fileChange") {
307
+ name = "write_file";
308
+ } else if (itemType === "web_search_call") {
309
+ name = "web_search";
310
+ }
311
+ }
312
+ if (!name) {
313
+ return void 0;
314
+ }
315
+ const args = typeof item.arguments === "object" && item.arguments !== null ? (
316
+ // eslint-disable-next-line no-restricted-syntax -- TypeScript narrowing requires this cast
317
+ item.arguments
318
+ ) : {};
319
+ const input = args;
320
+ const block = {
321
+ type: "tool_use",
322
+ id: callId,
323
+ name,
324
+ input
325
+ };
326
+ const cacheItem = item;
327
+ const cache = cacheItem.cache_control;
328
+ if (cache) {
329
+ block.cache_control = cache;
330
+ }
331
+ return block;
332
+ }
333
+ function mapTools(tools) {
334
+ const out = [];
335
+ for (const tool of tools) {
336
+ if (!tool || typeof tool !== "object") {
337
+ continue;
338
+ }
339
+ const tt = tool.type || "";
340
+ if (ANTHROPIC_BUILTIN_TOOL_TYPES.has(tt)) {
341
+ out.push(tool);
342
+ continue;
343
+ }
344
+ if (tt !== "function") {
345
+ continue;
346
+ }
347
+ const fn = tool.function;
348
+ const name = fn?.name ?? tool.name;
349
+ if (!name) {
350
+ continue;
351
+ }
352
+ const toolInputSchema = fn?.parameters ?? tool.parameters ?? { type: "object" };
353
+ out.push({
354
+ name,
355
+ description: fn?.description ?? tool.description ?? "",
356
+ input_schema: toolInputSchema
357
+ });
358
+ }
359
+ return out;
360
+ }
361
+ function mapToolChoice(choice) {
362
+ if (choice == null || choice === "auto") {
363
+ return { type: "auto" };
364
+ }
365
+ if (choice === "required") {
366
+ return { type: "any" };
367
+ }
368
+ if (choice === "none") {
369
+ return void 0;
370
+ }
371
+ if (typeof choice === "object") {
372
+ if (choice.type === "function" && "function" in choice && choice.function?.name) {
373
+ return { type: "tool", name: choice.function.name };
374
+ }
375
+ if (choice.type === "auto" || choice.type === "any") {
376
+ return { type: choice.type };
377
+ }
378
+ }
379
+ return { type: "auto" };
380
+ }
381
+ function mapThinking(data, maxTokens, overrides) {
382
+ const reasoning = data.reasoning;
383
+ if (!reasoning) {
384
+ return void 0;
385
+ }
386
+ const effort = reasoning.effort;
387
+ if (!effort || effort === "minimal") {
388
+ return void 0;
389
+ }
390
+ const budgets = { ...DEFAULT_REASONING_BUDGETS, ...overrides };
391
+ const budget = budgets[effort] ?? DEFAULT_REASONING_BUDGETS.medium;
392
+ const clamped = Math.max(1024, Math.min(budget, Math.max(1024, maxTokens - 1024)));
393
+ return { type: "enabled", budget_tokens: clamped };
394
+ }
395
+ function repairToolAdjacency(messages) {
396
+ const repaired = [];
397
+ const working = messages.map((msg) => ({
398
+ ...msg,
399
+ content: Array.isArray(msg.content) ? [...msg.content] : msg.content
400
+ }));
401
+ for (let i = 0; i < working.length; i++) {
402
+ const msg = working[i];
403
+ repaired.push(msg);
404
+ const content = msg.content;
405
+ if (msg.role !== "assistant" || !Array.isArray(content)) {
406
+ continue;
407
+ }
408
+ const toolUseIds = content.filter((block) => !!block && block.type === "tool_use").map((block) => block.id);
409
+ if (!toolUseIds.length) {
410
+ continue;
411
+ }
412
+ const next = working[i + 1];
413
+ const nextUserContent = next && next.role === "user" && Array.isArray(next.content) ? next.content : [];
414
+ const foundById = /* @__PURE__ */ new Map();
415
+ const consumedInNext = /* @__PURE__ */ new Set();
416
+ for (const block of nextUserContent) {
417
+ if (block && block.type === "tool_result") {
418
+ const tr = block;
419
+ if (toolUseIds.includes(tr.tool_use_id) && !foundById.has(tr.tool_use_id)) {
420
+ foundById.set(tr.tool_use_id, tr);
421
+ consumedInNext.add(tr.tool_use_id);
422
+ }
423
+ }
424
+ }
425
+ const missing = toolUseIds.filter((id) => !foundById.has(id));
426
+ if (missing.length) {
427
+ const missingSet = new Set(missing);
428
+ for (let j = i + 2; j < working.length && missingSet.size; j++) {
429
+ const later = working[j];
430
+ if (later.role !== "user" || !Array.isArray(later.content)) {
431
+ continue;
432
+ }
433
+ const keep = [];
434
+ for (const block of later.content) {
435
+ if (block && block.type === "tool_result") {
436
+ const tr = block;
437
+ if (missingSet.has(tr.tool_use_id)) {
438
+ foundById.set(tr.tool_use_id, tr);
439
+ missingSet.delete(tr.tool_use_id);
440
+ continue;
441
+ }
442
+ }
443
+ keep.push(block);
444
+ }
445
+ later.content = keep;
446
+ }
447
+ }
448
+ const ordered = toolUseIds.map(
449
+ (id) => foundById.get(id) ?? {
450
+ type: "tool_result",
451
+ tool_use_id: id,
452
+ content: ""
453
+ }
454
+ );
455
+ repaired.push({ role: "user", content: ordered });
456
+ if (nextUserContent.length) {
457
+ const remaining = nextUserContent.filter((block) => {
458
+ if (block && block.type === "tool_result") {
459
+ const tr = block;
460
+ if (consumedInNext.has(tr.tool_use_id)) {
461
+ consumedInNext.delete(tr.tool_use_id);
462
+ return false;
463
+ }
464
+ }
465
+ return true;
466
+ });
467
+ if (remaining.length) {
468
+ repaired.push({ role: "user", content: remaining });
469
+ }
470
+ i += 1;
471
+ }
472
+ }
473
+ return repaired;
474
+ }
475
+ function sanitizeMessages(messages) {
476
+ const out = [];
477
+ for (const msg of messages) {
478
+ if (!msg || msg.role !== "user" && msg.role !== "assistant") {
479
+ continue;
480
+ }
481
+ if (Array.isArray(msg.content)) {
482
+ const blocks = msg.content.filter((block) => {
483
+ if (!block || typeof block !== "object") {
484
+ return false;
485
+ }
486
+ if (block.type === "text" && !block.text) {
487
+ return false;
488
+ }
489
+ return true;
490
+ });
491
+ if (!blocks.length) {
492
+ continue;
493
+ }
494
+ out.push({ role: msg.role, content: blocks });
495
+ } else if (typeof msg.content === "string" && msg.content) {
496
+ out.push({ role: msg.role, content: [{ type: "text", text: msg.content }] });
497
+ }
498
+ }
499
+ return out;
500
+ }
501
+ function ensureEndsWithUser(messages) {
502
+ if (!messages.length) {
503
+ return [{ role: "user", content: [{ type: "text", text: "..." }] }];
504
+ }
505
+ const last = messages[messages.length - 1];
506
+ if (last.role === "user") {
507
+ return messages;
508
+ }
509
+ return [...messages, { role: "user", content: [{ type: "text", text: "Continue." }] }];
510
+ }
511
+
512
+ // src/utils/json.ts
513
+ function safeJsonParse(text) {
514
+ try {
515
+ const parsed = JSON.parse(text);
516
+ return parsed;
517
+ } catch {
518
+ return void 0;
519
+ }
520
+ }
521
+ function jsonStringifySafe(value) {
522
+ try {
523
+ return JSON.stringify(value);
524
+ } catch {
525
+ return "";
526
+ }
527
+ }
528
+
529
+ // src/translate/anthropic/translateResponse.ts
530
+ function translateResponse(body, options = {}) {
531
+ const createdAt = options.createdAt ?? Math.floor(Date.now() / 1e3);
532
+ const id = options.responseId ?? body.id ?? makeId("resp");
533
+ const model = options.model ?? body.model ?? "";
534
+ const output = mapOutputItems(body.content ?? []);
535
+ const usage = body.usage ?? { input_tokens: 0, output_tokens: 0 };
536
+ return {
537
+ id,
538
+ object: "response",
539
+ created_at: createdAt,
540
+ model,
541
+ status: "completed",
542
+ output,
543
+ usage: {
544
+ input_tokens: usage.input_tokens ?? 0,
545
+ output_tokens: usage.output_tokens ?? 0,
546
+ total_tokens: (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
547
+ input_tokens_details: {
548
+ cached_tokens: usage.cache_read_input_tokens ?? 0,
549
+ cache_creation_tokens: usage.cache_creation_input_tokens ?? 0
550
+ }
551
+ }
552
+ };
553
+ }
554
+ var SHELL_TOOL_NAMES = /* @__PURE__ */ new Set(["shell", "container.exec", "shell_command"]);
555
+ function mapOutputItems(content) {
556
+ const out = [];
557
+ const textChunks = [];
558
+ for (const block of content) {
559
+ if (!block || typeof block !== "object") {
560
+ continue;
561
+ }
562
+ const btype = block.type;
563
+ if (btype === "text") {
564
+ textChunks.push(String(block.text ?? ""));
565
+ } else if (btype === "tool_use") {
566
+ const args = jsonStringifySafe(block.input ?? {});
567
+ const callId = block.id ?? makeId("call");
568
+ const item = {
569
+ id: callId,
570
+ type: "function_call",
571
+ status: "completed",
572
+ // eslint-disable-next-line no-restricted-syntax -- TypeScript narrowing requires this cast
573
+ name: block.name ?? "tool",
574
+ arguments: args,
575
+ call_id: callId
576
+ };
577
+ if (
578
+ // eslint-disable-next-line no-restricted-syntax -- TypeScript narrowing requires this cast
579
+ block.name && // eslint-disable-next-line no-restricted-syntax -- TypeScript narrowing requires this cast
580
+ SHELL_TOOL_NAMES.has(block.name)
581
+ ) {
582
+ item.type = "local_shell_call";
583
+ const input_ = block.input ?? {};
584
+ const command = Array.isArray(input_.command) ? input_.command : [];
585
+ item.action = { type: "exec", command };
586
+ }
587
+ out.push(item);
588
+ } else if (btype === "thinking") {
589
+ const text = String(block.thinking ?? "");
590
+ const reasoning = {
591
+ id: makeId("rs"),
592
+ type: "reasoning",
593
+ summary: [],
594
+ content: [{ type: "reasoning_text", text }],
595
+ status: "completed"
596
+ };
597
+ out.push(reasoning);
598
+ }
599
+ }
600
+ if (textChunks.length) {
601
+ const message = {
602
+ id: makeId("msg"),
603
+ type: "message",
604
+ role: "assistant",
605
+ status: "completed",
606
+ content: [{ type: "output_text", text: textChunks.join("") }]
607
+ };
608
+ out.push(message);
609
+ }
610
+ return out;
611
+ }
612
+
613
+ // src/utils/sse.ts
614
+ async function* parseSseStream(stream) {
615
+ const reader = stream.getReader();
616
+ const decoder = new TextDecoder("utf-8");
617
+ let buffer = "";
618
+ try {
619
+ while (true) {
620
+ const { value, done } = await reader.read();
621
+ if (done) {
622
+ break;
623
+ }
624
+ if (value) {
625
+ buffer += decoder.decode(value, { stream: true });
626
+ }
627
+ let idx;
628
+ while ((idx = buffer.search(/\r?\n\r?\n/)) !== -1) {
629
+ const raw = buffer.slice(0, idx);
630
+ buffer = buffer.slice(idx + (buffer[idx] === "\r" ? 4 : 2));
631
+ const msg = parseSseBlock(raw);
632
+ if (msg) {
633
+ yield msg;
634
+ }
635
+ }
636
+ }
637
+ buffer += decoder.decode();
638
+ if (buffer.trim().length > 0) {
639
+ const msg = parseSseBlock(buffer);
640
+ if (msg) {
641
+ yield msg;
642
+ }
643
+ }
644
+ } finally {
645
+ reader.releaseLock();
646
+ }
647
+ }
648
+ function parseSseBlock(block) {
649
+ let event;
650
+ const dataLines = [];
651
+ for (const line of block.split(/\r?\n/)) {
652
+ if (!line || line.startsWith(":")) {
653
+ continue;
654
+ }
655
+ const colon = line.indexOf(":");
656
+ const field = colon === -1 ? line : line.slice(0, colon);
657
+ let value = colon === -1 ? "" : line.slice(colon + 1);
658
+ if (value.startsWith(" ")) {
659
+ value = value.slice(1);
660
+ }
661
+ if (field === "event") {
662
+ event = value;
663
+ } else if (field === "data") {
664
+ dataLines.push(value);
665
+ }
666
+ }
667
+ if (dataLines.length === 0) {
668
+ return void 0;
669
+ }
670
+ return { event, data: dataLines.join("\n") };
671
+ }
672
+ function encodeSseEvent(event, data) {
673
+ const payload = typeof data === "string" ? data : JSON.stringify(data);
674
+ return `event: ${event}
675
+ data: ${payload}
676
+
677
+ `;
678
+ }
679
+
680
+ // src/translate/anthropic/translateStream.ts
681
+ async function* translateStream(stream, options = {}) {
682
+ const translator = new StreamTranslator(options);
683
+ yield translator.createInitialEvent();
684
+ for await (const msg of parseSseStream(stream)) {
685
+ const event = parseAnthropicEvent(msg);
686
+ if (!event) {
687
+ continue;
688
+ }
689
+ yield* translator.handleEvent(event);
690
+ }
691
+ yield* translator.finalize();
692
+ }
693
+ async function* translateAnthropicEvents(events, options = {}) {
694
+ const translator = new StreamTranslator(options);
695
+ yield translator.createInitialEvent();
696
+ for await (const event of events) {
697
+ yield* translator.handleEvent(event);
698
+ }
699
+ yield* translator.finalize();
700
+ }
701
+ function parseAnthropicEvent(msg) {
702
+ const parsed = safeJsonParse(msg.data);
703
+ if (!parsed) {
704
+ return void 0;
705
+ }
706
+ return parsed;
707
+ }
708
+ var SHELL_TOOL_NAMES2 = /* @__PURE__ */ new Set(["shell", "container.exec", "shell_command"]);
709
+ var StreamTranslator = class {
710
+ constructor(options) {
711
+ __publicField(this, "model");
712
+ __publicField(this, "responseId");
713
+ __publicField(this, "createdAt");
714
+ __publicField(this, "metadata");
715
+ __publicField(this, "seq", 0);
716
+ __publicField(this, "outputCounter", 0);
717
+ __publicField(this, "blocks", /* @__PURE__ */ new Map());
718
+ __publicField(this, "inputTokens", 0);
719
+ __publicField(this, "outputTokens", 0);
720
+ __publicField(this, "cacheCreationTokens", 0);
721
+ __publicField(this, "cacheReadTokens", 0);
722
+ __publicField(this, "textItem");
723
+ __publicField(this, "textItemIndex", -1);
724
+ __publicField(this, "textBuffer", "");
725
+ __publicField(this, "stopReason");
726
+ this.model = options.model ?? "";
727
+ this.responseId = options.responseId ?? makeId("resp");
728
+ this.createdAt = options.createdAt ?? Math.floor(Date.now() / 1e3);
729
+ this.metadata = options.requestMetadata ?? {};
730
+ }
731
+ createInitialEvent() {
732
+ const response = {
733
+ id: this.responseId,
734
+ object: "response",
735
+ created_at: this.createdAt,
736
+ model: this.model,
737
+ status: "in_progress",
738
+ temperature: this.metadata.temperature,
739
+ top_p: this.metadata.top_p,
740
+ tool_choice: this.metadata.tool_choice,
741
+ tools: this.metadata.tools ?? [],
742
+ parallel_tool_calls: true,
743
+ store: this.metadata.store ?? true,
744
+ metadata: this.metadata.metadata ?? {},
745
+ output: []
746
+ };
747
+ return this.makeEvent("response.created", { response });
748
+ }
749
+ *handleEvent(event) {
750
+ switch (event.type) {
751
+ case "message_start": {
752
+ const msgStartEvt = event;
753
+ this.onMessageStart(msgStartEvt);
754
+ return;
755
+ }
756
+ case "content_block_start":
757
+ {
758
+ const cbsEvt = event;
759
+ yield* this.onContentBlockStart(cbsEvt);
760
+ }
761
+ return;
762
+ case "content_block_delta":
763
+ {
764
+ const cbdEvt = event;
765
+ yield* this.onContentBlockDelta(cbdEvt);
766
+ }
767
+ return;
768
+ case "content_block_stop":
769
+ return;
770
+ case "message_delta":
771
+ {
772
+ const msgDeltaEvt = event;
773
+ this.onMessageDelta(msgDeltaEvt);
774
+ }
775
+ return;
776
+ case "message_stop":
777
+ case "ping":
778
+ return;
779
+ default:
780
+ return;
781
+ }
782
+ }
783
+ *finalize() {
784
+ const items = [];
785
+ if (this.textItem) {
786
+ items.push({ index: this.textItemIndex, item: this.textItem });
787
+ }
788
+ for (const block of this.blocks.values()) {
789
+ if (!block.item) {
790
+ continue;
791
+ }
792
+ if (items.find((item2) => item2.index === block.outputIndex)) {
793
+ continue;
794
+ }
795
+ const item = block.item;
796
+ item.status = "completed";
797
+ if (block.type === "tool_use") {
798
+ const call = block.item;
799
+ if (call.name && SHELL_TOOL_NAMES2.has(call.name)) {
800
+ call.type = "local_shell_call";
801
+ const parsed = safeJsonParse(call.arguments ?? "");
802
+ call.action = { type: "exec", command: parsed?.command ?? [] };
803
+ }
804
+ }
805
+ items.push({ index: block.outputIndex, item: block.item });
806
+ }
807
+ items.sort((alpha, beta) => alpha.index - beta.index);
808
+ for (const { index, item } of items) {
809
+ yield this.makeEvent("response.output_item.done", {
810
+ response_id: this.responseId,
811
+ output_index: index,
812
+ item
813
+ });
814
+ }
815
+ const output = items.map((item) => item.item);
816
+ const total = this.inputTokens + this.outputTokens;
817
+ const response = {
818
+ id: this.responseId,
819
+ object: "response",
820
+ created_at: this.createdAt,
821
+ completed_at: Math.floor(Date.now() / 1e3),
822
+ model: this.model,
823
+ status: "completed",
824
+ temperature: this.metadata.temperature,
825
+ top_p: this.metadata.top_p,
826
+ tool_choice: this.metadata.tool_choice,
827
+ tools: this.metadata.tools ?? [],
828
+ parallel_tool_calls: true,
829
+ store: this.metadata.store ?? true,
830
+ metadata: this.metadata.metadata ?? {},
831
+ output,
832
+ usage: {
833
+ input_tokens: this.inputTokens,
834
+ output_tokens: this.outputTokens,
835
+ total_tokens: total,
836
+ input_tokens_details: {
837
+ cached_tokens: this.cacheReadTokens,
838
+ cache_creation_tokens: this.cacheCreationTokens
839
+ }
840
+ }
841
+ };
842
+ yield this.makeEvent("response.completed", { response });
843
+ }
844
+ onMessageStart(event) {
845
+ const usage = event.message?.usage;
846
+ if (usage) {
847
+ this.inputTokens = usage.input_tokens ?? 0;
848
+ this.cacheCreationTokens = usage.cache_creation_input_tokens ?? 0;
849
+ this.cacheReadTokens = usage.cache_read_input_tokens ?? 0;
850
+ }
851
+ return;
852
+ }
853
+ *onContentBlockStart(event) {
854
+ const index = event.index;
855
+ const block = event.content_block;
856
+ const btype = block.type;
857
+ if (btype === "thinking") {
858
+ const outputIndex = this.outputCounter++;
859
+ const item = {
860
+ id: makeId("rs"),
861
+ type: "reasoning",
862
+ summary: [],
863
+ content: [{ type: "reasoning_text", text: "" }],
864
+ status: "in_progress"
865
+ };
866
+ this.blocks.set(index, { type: "thinking", outputIndex, item, buffer: "" });
867
+ yield this.makeEvent("response.output_item.added", {
868
+ response_id: this.responseId,
869
+ output_index: outputIndex,
870
+ item
871
+ });
872
+ return;
873
+ }
874
+ if (btype === "text") {
875
+ if (!this.textItem) {
876
+ const outputIndex = this.outputCounter++;
877
+ this.textItemIndex = outputIndex;
878
+ this.textItem = {
879
+ id: makeId("msg"),
880
+ type: "message",
881
+ role: "assistant",
882
+ status: "in_progress",
883
+ content: [{ type: "output_text", text: "" }]
884
+ };
885
+ yield this.makeEvent("response.output_item.added", {
886
+ response_id: this.responseId,
887
+ output_index: outputIndex,
888
+ item: this.textItem
889
+ });
890
+ }
891
+ this.blocks.set(index, { type: "text", outputIndex: this.textItemIndex, buffer: "" });
892
+ return;
893
+ }
894
+ if (btype === "tool_use") {
895
+ const outputIndex = this.outputCounter++;
896
+ const callId = block.id ?? makeId("call");
897
+ const item = {
898
+ id: callId,
899
+ type: "function_call",
900
+ status: "in_progress",
901
+ name: block.name ?? "",
902
+ arguments: "",
903
+ call_id: callId
904
+ };
905
+ this.blocks.set(index, { type: "tool_use", outputIndex, item, buffer: "" });
906
+ yield this.makeEvent("response.output_item.added", {
907
+ response_id: this.responseId,
908
+ output_index: outputIndex,
909
+ item
910
+ });
911
+ return;
912
+ }
913
+ this.blocks.set(index, { type: btype, outputIndex: -1, buffer: "" });
914
+ }
915
+ *onContentBlockDelta(event) {
916
+ const block = this.blocks.get(event.index);
917
+ if (!block) {
918
+ return;
919
+ }
920
+ const delta = event.delta;
921
+ const dtype = typeof delta.type === "string" ? delta.type : "";
922
+ if (dtype === "text_delta") {
923
+ const text = String(delta.text ?? "");
924
+ if (!text) {
925
+ return;
926
+ }
927
+ this.textBuffer += text;
928
+ yield this.makeEvent("response.output_text.delta", {
929
+ response_id: this.responseId,
930
+ item_id: this.textItem?.id ?? "",
931
+ output_index: this.textItemIndex,
932
+ content_index: 0,
933
+ delta: text
934
+ });
935
+ return;
936
+ }
937
+ if (dtype === "thinking_delta") {
938
+ const thinking = String(delta.thinking ?? "");
939
+ if (!thinking) {
940
+ return;
941
+ }
942
+ block.buffer += thinking;
943
+ const item = block.item;
944
+ if (item) {
945
+ item.content[0].text = block.buffer;
946
+ }
947
+ yield this.makeEvent("response.reasoning_text.delta", {
948
+ response_id: this.responseId,
949
+ item_id: item?.id ?? "",
950
+ output_index: block.outputIndex,
951
+ content_index: 0,
952
+ delta: thinking
953
+ });
954
+ return;
955
+ }
956
+ if (dtype === "input_json_delta") {
957
+ const partial = String(delta.partial_json ?? "");
958
+ if (!partial) {
959
+ return;
960
+ }
961
+ block.buffer += partial;
962
+ const item = block.item;
963
+ if (item) {
964
+ item.arguments = block.buffer;
965
+ }
966
+ yield this.makeEvent("response.function_call_arguments.delta", {
967
+ response_id: this.responseId,
968
+ item_id: item?.id ?? "",
969
+ output_index: block.outputIndex,
970
+ delta: partial
971
+ });
972
+ return;
973
+ }
974
+ }
975
+ onMessageDelta(event) {
976
+ if (event.usage?.output_tokens != null) {
977
+ this.outputTokens = event.usage.output_tokens;
978
+ }
979
+ const eventDelta = event.delta;
980
+ const stopReason = eventDelta?.stop_reason;
981
+ if (stopReason) {
982
+ this.stopReason = stopReason;
983
+ }
984
+ return;
985
+ }
986
+ makeEvent(type, data) {
987
+ this.seq += 1;
988
+ return {
989
+ id: makeId("evt"),
990
+ object: "response.event",
991
+ type,
992
+ created_at: Math.floor(Date.now() / 1e3),
993
+ sequence_number: this.seq,
994
+ ...data
995
+ };
996
+ }
997
+ };
998
+
999
+ // src/translate/openai/index.ts
1000
+ var openai_exports = {};
1001
+ __export(openai_exports, {
1002
+ translateRequest: () => translateRequest2,
1003
+ translateResponse: () => translateResponse2,
1004
+ translateStream: () => translateStream2
1005
+ });
1006
+
1007
+ // src/translate/openai/translateRequest.ts
1008
+ function translateRequest2(data, options = {}) {
1009
+ const messages = [];
1010
+ const systemContent = buildSystemContent(data.instructions);
1011
+ if (systemContent) {
1012
+ messages.push({ role: "system", content: systemContent });
1013
+ }
1014
+ const inputItems = typeof data.input === "string" ? [data.input] : Array.isArray(data.input) ? data.input : [];
1015
+ for (const raw of inputItems) {
1016
+ if (typeof raw === "string") {
1017
+ messages.push({ role: "user", content: raw });
1018
+ continue;
1019
+ }
1020
+ if (!raw || typeof raw !== "object") {
1021
+ continue;
1022
+ }
1023
+ const rawItem = raw;
1024
+ processInputItem(rawItem, messages, options.dropImages);
1025
+ }
1026
+ const request = {
1027
+ model: data.model,
1028
+ messages
1029
+ };
1030
+ if (typeof data.temperature === "number") {
1031
+ request.temperature = data.temperature;
1032
+ }
1033
+ if (typeof data.top_p === "number") {
1034
+ request.top_p = data.top_p;
1035
+ }
1036
+ const effort = typeof data.reasoning?.effort === "string" ? data.reasoning.effort : void 0;
1037
+ if (effort) {
1038
+ const req = request;
1039
+ req.reasoning_effort = effort;
1040
+ }
1041
+ const maxTokens = typeof data.max_output_tokens === "number" && data.max_output_tokens || typeof data.max_tokens === "number" && data.max_tokens || options.defaultMaxTokens;
1042
+ if (typeof maxTokens === "number") {
1043
+ request.max_tokens = maxTokens;
1044
+ }
1045
+ const tools = mapTools2(data.tools ?? []);
1046
+ if (tools.length) {
1047
+ request.tools = tools;
1048
+ const toolChoice = mapToolChoice2(data.tool_choice);
1049
+ if (toolChoice !== void 0) {
1050
+ request.tool_choice = toolChoice;
1051
+ }
1052
+ }
1053
+ const placeholder = options.reasoningPlaceholder ?? ".";
1054
+ if (options.backfillReasoning !== false && placeholder) {
1055
+ for (const m of messages) {
1056
+ if (m.role === "assistant" && m.reasoning_content == null) {
1057
+ m.reasoning_content = placeholder;
1058
+ }
1059
+ }
1060
+ }
1061
+ repairToolMessageOrder(messages);
1062
+ return { request };
1063
+ }
1064
+ function buildSystemContent(instructions) {
1065
+ if (!instructions) {
1066
+ return "";
1067
+ }
1068
+ if (typeof instructions === "string") {
1069
+ return instructions;
1070
+ }
1071
+ if (!Array.isArray(instructions)) {
1072
+ return "";
1073
+ }
1074
+ let out = "";
1075
+ for (const block of instructions) {
1076
+ if (typeof block === "string") {
1077
+ out += block;
1078
+ } else if (block && typeof block === "object") {
1079
+ out += String(block.text ?? "");
1080
+ }
1081
+ }
1082
+ return out;
1083
+ }
1084
+ function processInputItem(item, messages, dropImages) {
1085
+ const itemType = String(item.type) || "message";
1086
+ const getLastAssistant = () => {
1087
+ const last = messages[messages.length - 1];
1088
+ if (last && last.role === "assistant") {
1089
+ return last;
1090
+ }
1091
+ const msg = { role: "assistant", content: null };
1092
+ messages.push(msg);
1093
+ return msg;
1094
+ };
1095
+ if (itemType === "message" || itemType === "agentMessage") {
1096
+ let role = String(item.role) || "user";
1097
+ if (role === "developer") {
1098
+ role = "system";
1099
+ }
1100
+ let reasoningContent = String(item.reasoning_content ?? "");
1101
+ const rawContent = item.content;
1102
+ if (role === "assistant" || role === "model") {
1103
+ let content = "";
1104
+ if (typeof rawContent === "string") {
1105
+ content = rawContent;
1106
+ } else if (Array.isArray(rawContent)) {
1107
+ for (const part of rawContent) {
1108
+ if (typeof part === "string") {
1109
+ content += part;
1110
+ } else if (part && typeof part === "object") {
1111
+ const contentPart = part;
1112
+ if (contentPart.type === "input_text" || contentPart.type === "text" || contentPart.type === "output_text") {
1113
+ content += String(contentPart.text ?? "");
1114
+ } else if (contentPart.type === "reasoning_text") {
1115
+ reasoningContent += String(contentPart.text ?? "");
1116
+ }
1117
+ }
1118
+ }
1119
+ }
1120
+ const amsg = getLastAssistant();
1121
+ if (content) {
1122
+ amsg.content = (amsg.content ?? "") + content;
1123
+ }
1124
+ if (reasoningContent) {
1125
+ amsg.reasoning_content = (amsg.reasoning_content ?? "") + reasoningContent;
1126
+ }
1127
+ const sig = item.thought_signature;
1128
+ if (typeof sig === "string" && sig) {
1129
+ amsg.thought_signature = sig;
1130
+ }
1131
+ } else {
1132
+ if (typeof rawContent === "string") {
1133
+ messages.push({ role, content: rawContent });
1134
+ } else if (Array.isArray(rawContent)) {
1135
+ const contentBlocks = [];
1136
+ for (const part of rawContent) {
1137
+ if (typeof part === "string") {
1138
+ contentBlocks.push({ type: "text", text: part });
1139
+ } else if (part && typeof part === "object") {
1140
+ const contentPart = part;
1141
+ if (contentPart.type === "input_text" || contentPart.type === "text" || contentPart.type === "output_text") {
1142
+ contentBlocks.push({ type: "text", text: String(contentPart.text ?? "") });
1143
+ } else if (contentPart.type === "reasoning_text") {
1144
+ reasoningContent += String(contentPart.text ?? "");
1145
+ } else if (contentPart.type === "input_image" || contentPart.type === "image" || contentPart.type === "image_url") {
1146
+ if (dropImages) {
1147
+ continue;
1148
+ }
1149
+ let url = "";
1150
+ const partWithImage = part;
1151
+ const imgUrl = partWithImage.image_url;
1152
+ if (typeof imgUrl === "string") {
1153
+ url = imgUrl;
1154
+ } else if (imgUrl && typeof imgUrl === "object" && imgUrl.url) {
1155
+ url = imgUrl.url;
1156
+ } else {
1157
+ const partWithData = part;
1158
+ const imgData = String(partWithData.data ?? partWithData.base64 ?? "");
1159
+ if (imgData) {
1160
+ const partWithMime = part;
1161
+ const mimeType = String(
1162
+ partWithMime.mime_type ?? partWithMime.media_type ?? "image/png"
1163
+ );
1164
+ url = imgData.startsWith("data:") ? imgData : `data:${mimeType};base64,${imgData}`;
1165
+ }
1166
+ }
1167
+ if (url) {
1168
+ contentBlocks.push({ type: "image_url", image_url: { url } });
1169
+ }
1170
+ } else if (part.type === "input_file" || part.type === "file") {
1171
+ const partFile = part;
1172
+ const fileData = String(partFile.file_data ?? partFile.data ?? "");
1173
+ const mimeType = String(
1174
+ partFile.mime_type ?? partFile.media_type ?? "application/pdf"
1175
+ );
1176
+ if (fileData) {
1177
+ const url = fileData.startsWith("data:") ? fileData : `data:${mimeType};base64,${fileData}`;
1178
+ contentBlocks.push({ type: "image_url", image_url: { url } });
1179
+ }
1180
+ }
1181
+ }
1182
+ }
1183
+ const msg = { role, content: contentBlocks };
1184
+ if (reasoningContent) {
1185
+ msg.reasoning_content = reasoningContent;
1186
+ }
1187
+ const sig = item.thought_signature;
1188
+ if (typeof sig === "string" && sig) {
1189
+ msg.thought_signature = sig;
1190
+ }
1191
+ messages.push(msg);
1192
+ } else {
1193
+ messages.push({ role, content: "" });
1194
+ }
1195
+ }
1196
+ return;
1197
+ }
1198
+ if (itemType === "reasoning") {
1199
+ const rawList = item.content;
1200
+ let content = "";
1201
+ if (Array.isArray(rawList)) {
1202
+ for (const cp of rawList) {
1203
+ if (typeof cp === "string") {
1204
+ content += cp;
1205
+ } else if (cp && typeof cp === "object") {
1206
+ content += String(cp.text ?? "");
1207
+ }
1208
+ }
1209
+ } else if (typeof rawList === "string") {
1210
+ content += rawList;
1211
+ }
1212
+ const amsg = getLastAssistant();
1213
+ amsg.reasoning_content = (amsg.reasoning_content ?? "") + content;
1214
+ const sig = item.thought_signature;
1215
+ if (typeof sig === "string" && sig) {
1216
+ amsg.thought_signature = sig;
1217
+ }
1218
+ return;
1219
+ }
1220
+ if (itemType === "function_call" || itemType === "commandExecution" || itemType === "local_shell_call" || itemType === "fileChange" || itemType === "custom_tool_call" || itemType === "web_search_call") {
1221
+ processToolCall(item, messages, getLastAssistant);
1222
+ return;
1223
+ }
1224
+ if (itemType === "function_call_output" || itemType === "commandExecutionOutput" || itemType === "fileChangeOutput" || itemType === "custom_tool_call_output") {
1225
+ processToolOutput(item, messages);
1226
+ return;
1227
+ }
1228
+ }
1229
+ function processToolCall(item, messages, getLastAssistant) {
1230
+ const callId = String(item.call_id ?? "") || String(item.id ?? "") || makeId("call");
1231
+ let name = item.name === void 0 ? void 0 : String(item.name);
1232
+ const itemType = item.type === void 0 ? void 0 : String(item.type);
1233
+ if (!name) {
1234
+ if (itemType === "commandExecution") {
1235
+ name = "run_shell_command";
1236
+ } else if (itemType === "local_shell_call") {
1237
+ name = "local_shell_command";
1238
+ } else if (itemType === "fileChange") {
1239
+ name = "write_file";
1240
+ } else if (itemType === "web_search_call") {
1241
+ name = "web_search";
1242
+ }
1243
+ }
1244
+ let args = item.arguments ?? item.input ?? (isEmpty(item.arguments) && isEmpty(item.input) ? {} : {});
1245
+ if (isEmpty(args) && itemType === "web_search_call") {
1246
+ args = item.action ?? {};
1247
+ }
1248
+ if (isEmpty(args)) {
1249
+ if (itemType === "commandExecution") {
1250
+ args = {
1251
+ command: item.command ?? "",
1252
+ dir_path: item.cwd ?? "."
1253
+ };
1254
+ } else if (itemType === "local_shell_call") {
1255
+ const action = item.action === void 0 ? {} : item.action;
1256
+ const execChild = action.exec === void 0 ? {} : action.exec;
1257
+ args = {
1258
+ command: execChild.command ?? [],
1259
+ working_directory: execChild.working_directory
1260
+ };
1261
+ } else if (itemType === "fileChange") {
1262
+ const changes = Array.isArray(item.changes) ? item.changes : [];
1263
+ const path = changes[0]?.path ?? "unknown";
1264
+ args = { file_path: path };
1265
+ }
1266
+ }
1267
+ const argsStr = typeof args === "string" ? args : jsonStringifySafe(args ?? {});
1268
+ if (!name) {
1269
+ return;
1270
+ }
1271
+ const amsg = getLastAssistant();
1272
+ if (!amsg.tool_calls) {
1273
+ amsg.tool_calls = [];
1274
+ }
1275
+ amsg.tool_calls.push({
1276
+ id: callId,
1277
+ type: "function",
1278
+ function: { name, arguments: argsStr }
1279
+ });
1280
+ const sig = item.thought_signature;
1281
+ const thought = item.thought;
1282
+ if (typeof sig === "string" && sig) {
1283
+ amsg.thought_signature = sig;
1284
+ }
1285
+ if (typeof thought === "string" && thought) {
1286
+ amsg.reasoning_content = (amsg.reasoning_content ?? "") + thought;
1287
+ }
1288
+ }
1289
+ function processToolOutput(item, messages) {
1290
+ const callId = item.call_id === void 0 ? void 0 : String(item.call_id);
1291
+ const outputRaw = item.output ?? item.content ?? item.stdout ?? "";
1292
+ let content = "";
1293
+ if (typeof outputRaw === "string") {
1294
+ content = outputRaw;
1295
+ } else if (Array.isArray(outputRaw)) {
1296
+ for (const part of outputRaw) {
1297
+ if (typeof part === "string") {
1298
+ content += part;
1299
+ } else if (part && typeof part === "object") {
1300
+ const partItem = part;
1301
+ if (partItem.type === "input_text" || partItem.type === "text") {
1302
+ content += String(partItem.text ?? "");
1303
+ }
1304
+ }
1305
+ }
1306
+ } else if (outputRaw && typeof outputRaw === "object") {
1307
+ const obj = outputRaw;
1308
+ content = String(obj.content ?? "");
1309
+ if (!content && obj.success === false) {
1310
+ content = "Error: Tool execution failed";
1311
+ }
1312
+ }
1313
+ if (!content && typeof item.stderr === "string" && item.stderr) {
1314
+ content = `Error: ${item.stderr}`;
1315
+ }
1316
+ messages.push({
1317
+ role: "tool",
1318
+ tool_call_id: callId,
1319
+ content
1320
+ });
1321
+ }
1322
+ function mapTools2(tools) {
1323
+ const out = [];
1324
+ for (const tool of tools) {
1325
+ if (!tool || typeof tool !== "object") {
1326
+ continue;
1327
+ }
1328
+ const tt = tool.type;
1329
+ if (tt === "function") {
1330
+ const fn = tool.function;
1331
+ const name = fn?.name ?? tool.name;
1332
+ if (!name) {
1333
+ continue;
1334
+ }
1335
+ const params = fn?.parameters ?? tool.parameters ?? { type: "object" };
1336
+ out.push({
1337
+ type: "function",
1338
+ function: {
1339
+ name,
1340
+ description: fn?.description ?? tool.description ?? "",
1341
+ parameters: params
1342
+ }
1343
+ });
1344
+ continue;
1345
+ }
1346
+ }
1347
+ return out;
1348
+ }
1349
+ function mapToolChoice2(choice) {
1350
+ if (choice == null) {
1351
+ return void 0;
1352
+ }
1353
+ if (choice === "auto" || choice === "required" || choice === "none") {
1354
+ return choice;
1355
+ }
1356
+ if (typeof choice === "object") {
1357
+ if (choice.type === "function" && "function" in choice && choice.function?.name) {
1358
+ return { type: "function", function: { name: choice.function.name } };
1359
+ }
1360
+ return choice;
1361
+ }
1362
+ return void 0;
1363
+ }
1364
+ function isEmpty(value) {
1365
+ if (value == null) {
1366
+ return true;
1367
+ }
1368
+ if (typeof value === "string") {
1369
+ return value.length === 0;
1370
+ }
1371
+ if (Array.isArray(value)) {
1372
+ return value.length === 0;
1373
+ }
1374
+ if (typeof value === "object" && value !== null) {
1375
+ return Object.keys(value).length === 0;
1376
+ }
1377
+ return false;
1378
+ }
1379
+ function repairToolMessageOrder(messages) {
1380
+ if (messages.length === 0) {
1381
+ return;
1382
+ }
1383
+ const blocks = [];
1384
+ let currentBlock = null;
1385
+ for (const msg of messages) {
1386
+ if (msg.role === "assistant") {
1387
+ currentBlock = { assistant: msg, trailing: [] };
1388
+ blocks.push(currentBlock);
1389
+ } else if (currentBlock) {
1390
+ currentBlock.trailing.push(msg);
1391
+ } else {
1392
+ blocks.push({ assistant: { role: "assistant", content: null }, trailing: [msg] });
1393
+ }
1394
+ }
1395
+ for (const block of blocks) {
1396
+ const toolCallIds = new Set(
1397
+ (block.assistant.tool_calls ?? []).map((tc) => tc.id).filter(Boolean)
1398
+ );
1399
+ if (toolCallIds.size === 0) {
1400
+ continue;
1401
+ }
1402
+ const tools = [];
1403
+ const others = [];
1404
+ for (const m of block.trailing) {
1405
+ if (m.role === "tool" && m.tool_call_id !== void 0 && toolCallIds.has(String(m.tool_call_id))) {
1406
+ tools.push(m);
1407
+ } else {
1408
+ others.push(m);
1409
+ }
1410
+ }
1411
+ block.trailing = [...tools, ...others];
1412
+ }
1413
+ messages.length = 0;
1414
+ for (const block of blocks) {
1415
+ if (block.assistant.tool_calls || block.assistant.content != null) {
1416
+ messages.push(block.assistant);
1417
+ }
1418
+ messages.push(...block.trailing);
1419
+ }
1420
+ }
1421
+
1422
+ // src/translate/openai/translateResponse.ts
1423
+ var SHELL_TOOL_NAMES3 = /* @__PURE__ */ new Set(["shell", "container.exec", "shell_command"]);
1424
+ function translateResponse2(body, options = {}) {
1425
+ const createdAt = options.createdAt ?? body.created ?? Math.floor(Date.now() / 1e3);
1426
+ const id = options.responseId ?? body.id ?? makeId("resp");
1427
+ const model = options.model ?? body.model ?? "";
1428
+ const choice = body.choices?.[0];
1429
+ const message = choice?.message;
1430
+ const output = [];
1431
+ if (message?.tool_calls?.length) {
1432
+ for (const tc of message.tool_calls) {
1433
+ const item = mapToolCallToOutput(tc);
1434
+ if (item) {
1435
+ output.push(item);
1436
+ }
1437
+ }
1438
+ }
1439
+ if (typeof message?.content === "string" && message.content) {
1440
+ output.push({
1441
+ id: makeId("msg"),
1442
+ type: "message",
1443
+ role: "assistant",
1444
+ status: "completed",
1445
+ content: [{ type: "output_text", text: message.content }]
1446
+ });
1447
+ }
1448
+ const usage = body.usage ?? {};
1449
+ const input = usage.prompt_tokens ?? 0;
1450
+ const completion = usage.completion_tokens ?? 0;
1451
+ const total = usage.total_tokens ?? input + completion;
1452
+ const cached = usage.prompt_tokens_details?.cached_tokens ?? 0;
1453
+ return {
1454
+ id,
1455
+ object: "response",
1456
+ created_at: createdAt,
1457
+ model,
1458
+ status: "completed",
1459
+ output,
1460
+ usage: {
1461
+ input_tokens: input,
1462
+ output_tokens: completion,
1463
+ total_tokens: total,
1464
+ input_tokens_details: {
1465
+ cached_tokens: cached
1466
+ }
1467
+ }
1468
+ };
1469
+ }
1470
+ function mapToolCallToOutput(tc) {
1471
+ const name = tc.function?.name;
1472
+ if (!name) {
1473
+ return void 0;
1474
+ }
1475
+ const callId = tc.id ?? makeId("call");
1476
+ let args = tc.function?.arguments ?? "";
1477
+ if (typeof args !== "string") {
1478
+ args = jsonStringifySafe(args ?? {});
1479
+ }
1480
+ const item = {
1481
+ id: callId,
1482
+ type: "function_call",
1483
+ status: "completed",
1484
+ name,
1485
+ arguments: args,
1486
+ call_id: callId
1487
+ };
1488
+ if (SHELL_TOOL_NAMES3.has(name)) {
1489
+ item.type = "local_shell_call";
1490
+ const parsed = safeJsonParse(args);
1491
+ item.action = { type: "exec", command: parsed?.command ?? [] };
1492
+ }
1493
+ return item;
1494
+ }
1495
+
1496
+ // src/translate/openai/translateStream.ts
1497
+ var SHELL_TOOL_NAMES4 = /* @__PURE__ */ new Set(["shell", "container.exec", "shell_command"]);
1498
+ async function* translateStream2(stream, options = {}) {
1499
+ const translator = new StreamTranslator2(options);
1500
+ yield translator.createInitialEvent();
1501
+ for await (const msg of parseSseStream(stream)) {
1502
+ if (isDoneMessage(msg)) {
1503
+ break;
1504
+ }
1505
+ const chunk = safeJsonParse(msg.data);
1506
+ if (!chunk) {
1507
+ continue;
1508
+ }
1509
+ yield* translator.handleChunk(chunk);
1510
+ }
1511
+ yield* translator.finalize();
1512
+ }
1513
+ function isDoneMessage(msg) {
1514
+ return msg.data.trim() === "[DONE]";
1515
+ }
1516
+ var StreamTranslator2 = class {
1517
+ constructor(options) {
1518
+ __publicField(this, "model");
1519
+ __publicField(this, "responseId");
1520
+ __publicField(this, "createdAt");
1521
+ __publicField(this, "metadata");
1522
+ __publicField(this, "seq", 0);
1523
+ __publicField(this, "outputCounter", 0);
1524
+ __publicField(this, "textItem");
1525
+ __publicField(this, "textItemIndex", -1);
1526
+ __publicField(this, "textBuffer", "");
1527
+ __publicField(this, "toolCalls", /* @__PURE__ */ new Map());
1528
+ __publicField(this, "inputTokens", 0);
1529
+ __publicField(this, "outputTokens", 0);
1530
+ __publicField(this, "cachedTokens", 0);
1531
+ this.model = options.model ?? "";
1532
+ this.responseId = options.responseId ?? makeId("resp");
1533
+ this.createdAt = options.createdAt ?? Math.floor(Date.now() / 1e3);
1534
+ this.metadata = options.requestMetadata ?? {};
1535
+ }
1536
+ createInitialEvent() {
1537
+ const toolsArr = this.metadata.tools ?? [];
1538
+ const response = {
1539
+ id: this.responseId,
1540
+ object: "response",
1541
+ created_at: this.createdAt,
1542
+ model: this.model,
1543
+ status: "in_progress",
1544
+ temperature: this.metadata.temperature,
1545
+ top_p: this.metadata.top_p,
1546
+ tool_choice: this.metadata.tool_choice,
1547
+ tools: toolsArr,
1548
+ parallel_tool_calls: true,
1549
+ store: this.metadata.store ?? true,
1550
+ metadata: this.metadata.metadata ?? {},
1551
+ output: []
1552
+ };
1553
+ return this.makeEvent("response.created", { response });
1554
+ }
1555
+ *handleChunk(chunk) {
1556
+ if (chunk.usage) {
1557
+ if (typeof chunk.usage.prompt_tokens === "number") {
1558
+ this.inputTokens = chunk.usage.prompt_tokens;
1559
+ }
1560
+ if (typeof chunk.usage.completion_tokens === "number") {
1561
+ this.outputTokens = chunk.usage.completion_tokens;
1562
+ }
1563
+ const cached = chunk.usage.prompt_tokens_details?.cached_tokens;
1564
+ if (typeof cached === "number") {
1565
+ this.cachedTokens = cached;
1566
+ }
1567
+ }
1568
+ const choice = chunk.choices?.[0];
1569
+ const delta = choice?.delta;
1570
+ if (!delta) {
1571
+ return;
1572
+ }
1573
+ if (delta.tool_calls?.length) {
1574
+ for (const tc of delta.tool_calls) {
1575
+ const idx = tc.index ?? 0;
1576
+ let state = this.toolCalls.get(idx);
1577
+ if (!state) {
1578
+ const outputIndex = this.outputCounter++;
1579
+ const callId = tc.id ?? makeId("call");
1580
+ const item = {
1581
+ id: callId,
1582
+ type: "function_call",
1583
+ status: "in_progress",
1584
+ name: "",
1585
+ arguments: "",
1586
+ call_id: callId
1587
+ };
1588
+ state = { outputIndex, item };
1589
+ this.toolCalls.set(idx, state);
1590
+ yield this.makeEvent("response.output_item.added", {
1591
+ response_id: this.responseId,
1592
+ output_index: outputIndex,
1593
+ item
1594
+ });
1595
+ }
1596
+ const fn = tc.function;
1597
+ if (fn?.name) {
1598
+ state.item.name = (state.item.name ?? "") + fn.name;
1599
+ }
1600
+ if (fn?.arguments != null) {
1601
+ const partial = typeof fn.arguments === "string" ? fn.arguments : jsonStringifySafe(fn.arguments);
1602
+ if (partial) {
1603
+ state.item.arguments = (state.item.arguments ?? "") + partial;
1604
+ yield this.makeEvent("response.function_call_arguments.delta", {
1605
+ response_id: this.responseId,
1606
+ item_id: state.item.id,
1607
+ output_index: state.outputIndex,
1608
+ delta: partial
1609
+ });
1610
+ }
1611
+ }
1612
+ }
1613
+ }
1614
+ if (typeof delta.content === "string" && delta.content) {
1615
+ if (!this.textItem) {
1616
+ const outputIndex = this.outputCounter++;
1617
+ this.textItemIndex = outputIndex;
1618
+ this.textItem = {
1619
+ id: makeId("msg"),
1620
+ type: "message",
1621
+ role: "assistant",
1622
+ status: "in_progress",
1623
+ content: [{ type: "output_text", text: "" }]
1624
+ };
1625
+ yield this.makeEvent("response.output_item.added", {
1626
+ response_id: this.responseId,
1627
+ output_index: outputIndex,
1628
+ item: this.textItem
1629
+ });
1630
+ }
1631
+ this.textBuffer += delta.content;
1632
+ const textContent = this.textItem.content[0];
1633
+ textContent.text = this.textBuffer;
1634
+ yield this.makeEvent("response.output_text.delta", {
1635
+ response_id: this.responseId,
1636
+ item_id: this.textItem.id,
1637
+ output_index: this.textItemIndex,
1638
+ content_index: 0,
1639
+ delta: delta.content
1640
+ });
1641
+ }
1642
+ }
1643
+ *finalize() {
1644
+ const items = [];
1645
+ if (this.textItem) {
1646
+ this.textItem.status = "completed";
1647
+ items.push({ index: this.textItemIndex, item: this.textItem });
1648
+ }
1649
+ for (const state of this.toolCalls.values()) {
1650
+ const item = state.item;
1651
+ item.status = "completed";
1652
+ if (item.name && SHELL_TOOL_NAMES4.has(item.name)) {
1653
+ item.type = "local_shell_call";
1654
+ const parsed = safeJsonParse(item.arguments ?? "");
1655
+ item.action = { type: "exec", command: parsed?.command ?? [] };
1656
+ }
1657
+ items.push({ index: state.outputIndex, item });
1658
+ }
1659
+ items.sort((alpha, beta) => alpha.index - beta.index);
1660
+ for (const { index, item } of items) {
1661
+ yield this.makeEvent("response.output_item.done", {
1662
+ response_id: this.responseId,
1663
+ output_index: index,
1664
+ item
1665
+ });
1666
+ }
1667
+ const output = items.map((item) => item.item);
1668
+ const finalToolsArr = this.metadata.tools ?? [];
1669
+ const total = this.inputTokens + this.outputTokens;
1670
+ const response = {
1671
+ id: this.responseId,
1672
+ object: "response",
1673
+ created_at: this.createdAt,
1674
+ completed_at: Math.floor(Date.now() / 1e3),
1675
+ model: this.model,
1676
+ status: "completed",
1677
+ temperature: this.metadata.temperature,
1678
+ top_p: this.metadata.top_p,
1679
+ tool_choice: this.metadata.tool_choice,
1680
+ tools: finalToolsArr,
1681
+ parallel_tool_calls: true,
1682
+ store: this.metadata.store ?? true,
1683
+ metadata: this.metadata.metadata ?? {},
1684
+ output,
1685
+ usage: {
1686
+ input_tokens: this.inputTokens,
1687
+ output_tokens: this.outputTokens,
1688
+ total_tokens: total,
1689
+ input_tokens_details: {
1690
+ cached_tokens: this.cachedTokens
1691
+ }
1692
+ }
1693
+ };
1694
+ yield this.makeEvent("response.completed", { response });
1695
+ }
1696
+ makeEvent(type, data) {
1697
+ this.seq += 1;
1698
+ return {
1699
+ id: makeId("evt"),
1700
+ object: "response.event",
1701
+ type,
1702
+ created_at: Math.floor(Date.now() / 1e3),
1703
+ sequence_number: this.seq,
1704
+ ...data
1705
+ };
1706
+ }
1707
+ };
1708
+
1709
+ // src/fetch.ts
1710
+ function createResponsesFetch(options) {
1711
+ if (!options.baseUrl) {
1712
+ throw new Error("baseUrl is required");
1713
+ }
1714
+ const rawFormat = options.upstreamFormat;
1715
+ const format = rawFormat ? normalizeFormat(rawFormat) : inferFormatFromUrl(options.baseUrl) ?? "openai-chat";
1716
+ if (!format) {
1717
+ throw new Error(
1718
+ `Unsupported upstream format: ${options.upstreamFormat}. Use 'anthropic' or 'openai-chat'`
1719
+ );
1720
+ }
1721
+ const baseFetch = options.fetch ?? globalThis.fetch;
1722
+ if (!baseFetch) {
1723
+ throw new Error("fetch is not available; pass options.fetch");
1724
+ }
1725
+ const passthrough = options.passthroughFetch ?? baseFetch;
1726
+ return async (input, init) => {
1727
+ const url = urlOf(input);
1728
+ if (!isResponsesEndpoint(url)) {
1729
+ return passthrough(input, init);
1730
+ }
1731
+ const { body, signal, method, headers } = await extractRequest(input, init);
1732
+ if (method !== "POST") {
1733
+ return passthrough(input, init);
1734
+ }
1735
+ let parsed;
1736
+ try {
1737
+ parsed = body ? JSON.parse(body) : void 0;
1738
+ } catch {
1739
+ return jsonErrorResponse(400, "Invalid JSON body for /responses");
1740
+ }
1741
+ if (!parsed) {
1742
+ return jsonErrorResponse(400, "Missing body for /responses");
1743
+ }
1744
+ if (options.model) {
1745
+ parsed.model = options.model;
1746
+ }
1747
+ return handleResponses(parsed, format, options, baseFetch, headers, signal, options.dropImages);
1748
+ };
1749
+ }
1750
+ function normalizeBaseUrl(url, format) {
1751
+ try {
1752
+ const parsedUrl = new URL(url);
1753
+ const path = parsedUrl.pathname.replace(/\/+$/, "");
1754
+ if (format === "anthropic") {
1755
+ if (path.endsWith("/v1/messages") || path.endsWith("/messages")) {
1756
+ return parsedUrl.toString();
1757
+ }
1758
+ if (path.endsWith("/v1")) {
1759
+ parsedUrl.pathname += "/messages";
1760
+ return parsedUrl.toString();
1761
+ }
1762
+ parsedUrl.pathname = "/v1/messages";
1763
+ } else {
1764
+ if (path.endsWith("/v1/chat/completions") || path.endsWith("/chat/completions")) {
1765
+ return parsedUrl.toString();
1766
+ }
1767
+ if (path.endsWith("/v1")) {
1768
+ parsedUrl.pathname += "/chat/completions";
1769
+ return parsedUrl.toString();
1770
+ }
1771
+ parsedUrl.pathname = "/v1/chat/completions";
1772
+ }
1773
+ return parsedUrl.toString();
1774
+ } catch {
1775
+ return url;
1776
+ }
1777
+ }
1778
+ function normalizeFormat(format) {
1779
+ const fmt = format === "anthropic" || format === "openai-chat" ? format : null;
1780
+ return fmt;
1781
+ }
1782
+ function inferFormatFromUrl(baseUrl) {
1783
+ try {
1784
+ const parsedUrl = new URL(baseUrl);
1785
+ const path = parsedUrl.pathname.replace(/\/+$/, "");
1786
+ if (/\/messages$/.test(path) || parsedUrl.hostname.toLowerCase().includes("anthropic")) {
1787
+ return "anthropic";
1788
+ }
1789
+ if (/\/chat\/completions$/.test(path)) {
1790
+ return "openai-chat";
1791
+ }
1792
+ } catch {
1793
+ }
1794
+ return null;
1795
+ }
1796
+ function isResponsesEndpoint(url) {
1797
+ try {
1798
+ return /\/v1\/responses\/?$/.test(new URL(url, "http://_internal_").pathname);
1799
+ } catch {
1800
+ return /\/v1\/responses(?:\?|$)/.test(url);
1801
+ }
1802
+ }
1803
+ function urlOf(input) {
1804
+ if (typeof input === "string") {
1805
+ return input;
1806
+ }
1807
+ if (input instanceof URL) {
1808
+ return input.toString();
1809
+ }
1810
+ if (typeof Request !== "undefined" && input instanceof Request) {
1811
+ return input.url;
1812
+ }
1813
+ return String(input);
1814
+ }
1815
+ function parseHeaders(raw) {
1816
+ const out = {};
1817
+ if (!raw) {
1818
+ return out;
1819
+ }
1820
+ if (typeof Headers !== "undefined" && raw instanceof Headers) {
1821
+ raw.forEach((val, key) => {
1822
+ out[key.toLowerCase()] = val;
1823
+ });
1824
+ return out;
1825
+ }
1826
+ if (Array.isArray(raw)) {
1827
+ for (const [k, v] of raw) {
1828
+ out[String(k).toLowerCase()] = String(v);
1829
+ }
1830
+ return out;
1831
+ }
1832
+ for (const [k, v] of Object.entries(raw)) {
1833
+ out[k.toLowerCase()] = String(v);
1834
+ }
1835
+ return out;
1836
+ }
1837
+ async function extractRequest(input, init) {
1838
+ if (typeof Request !== "undefined" && input instanceof Request) {
1839
+ const text = await input.clone().text();
1840
+ const headers = parseHeaders(input.headers);
1841
+ return { body: text || void 0, signal: input.signal, method: input.method, headers };
1842
+ }
1843
+ const method = init?.method?.toUpperCase() ?? "GET";
1844
+ const body = init?.body != null ? typeof init.body === "string" ? init.body : await readBody(init.body) : void 0;
1845
+ return { body, signal: init?.signal, method, headers: parseHeaders(init?.headers) };
1846
+ }
1847
+ async function readBody(body) {
1848
+ if (typeof body === "string") {
1849
+ return body;
1850
+ }
1851
+ if (body instanceof Uint8Array || body instanceof ArrayBuffer) {
1852
+ return new TextDecoder().decode(body);
1853
+ }
1854
+ return String(body);
1855
+ }
1856
+ async function handleResponses(request, format, options, baseFetch, incomingHeaders, signal, dropImages) {
1857
+ if (dropImages && options.fallbackUpstream && lastUserMessageHasImage(request)) {
1858
+ dropImages = false;
1859
+ const fb = options.fallbackUpstream;
1860
+ options = { ...options, ...fb, fallbackUpstream: void 0 };
1861
+ format = fb.upstreamFormat ?? format;
1862
+ if (options.model) {
1863
+ request.model = options.model;
1864
+ }
1865
+ const fbModel = fb.model ? `, model: ${fb.model}` : "";
1866
+ console.warn(`[fallback] last user message has image, routing to ${fb.baseUrl}${fbModel}`);
1867
+ }
1868
+ const streaming = request.stream ?? false;
1869
+ const resolvedUrl = normalizeBaseUrl(options.baseUrl, format);
1870
+ const { upstreamBody, requestMetadata } = buildUpstreamBody(
1871
+ request,
1872
+ format,
1873
+ streaming,
1874
+ options.baseUrl,
1875
+ dropImages,
1876
+ options.reasoning_effort,
1877
+ options.thinking
1878
+ );
1879
+ const upstreamHeaders = buildUpstreamHeaders(format, options, incomingHeaders);
1880
+ const upstream = await baseFetch(resolvedUrl, {
1881
+ method: "POST",
1882
+ headers: upstreamHeaders,
1883
+ body: JSON.stringify(upstreamBody),
1884
+ signal
1885
+ });
1886
+ if (!upstream.ok) {
1887
+ return new Response(await upstream.text().catch(() => ""), {
1888
+ status: upstream.status,
1889
+ headers: { "content-type": "application/json" }
1890
+ });
1891
+ }
1892
+ if (!streaming) {
1893
+ const body = await upstream.json();
1894
+ const translated = format === "anthropic" ? (
1895
+ // eslint-disable-next-line no-restricted-syntax -- union type narrowing requires type assertion
1896
+ translateResponse(body, { model: request.model })
1897
+ ) : (
1898
+ // eslint-disable-next-line no-restricted-syntax -- union type narrowing requires type assertion
1899
+ translateResponse2(body, { model: request.model })
1900
+ );
1901
+ options.onCacheStats?.(extractCacheStatsFromResponse(translated));
1902
+ return new Response(JSON.stringify(translated), {
1903
+ status: 200,
1904
+ headers: { "content-type": "application/json" }
1905
+ });
1906
+ }
1907
+ if (!upstream.body) {
1908
+ return jsonErrorResponse(502, "Upstream streaming response has no body");
1909
+ }
1910
+ const events = format === "anthropic" ? translateStream(upstream.body, { model: request.model, requestMetadata }) : translateStream2(upstream.body, { model: request.model, requestMetadata });
1911
+ return new Response(
1912
+ responsesEventsToSseStream(collectCacheStatsFromStream(events, options.onCacheStats)),
1913
+ {
1914
+ status: 200,
1915
+ headers: {
1916
+ "content-type": "text/event-stream; charset=utf-8",
1917
+ "cache-control": "no-cache",
1918
+ connection: "keep-alive"
1919
+ }
1920
+ }
1921
+ );
1922
+ }
1923
+ function buildRequestMetadata(request, temperature, top_p) {
1924
+ return {
1925
+ temperature,
1926
+ top_p,
1927
+ tools: request.tools ?? [],
1928
+ tool_choice: request.tool_choice,
1929
+ store: request.store ?? true,
1930
+ metadata: request.metadata ?? {}
1931
+ };
1932
+ }
1933
+ function buildUpstreamBody(request, format, streaming, baseUrl, dropImages, reasoning_effort, thinking) {
1934
+ if (format === "anthropic") {
1935
+ const { request: ar } = translateRequest(request);
1936
+ ar.stream = streaming;
1937
+ if (thinking !== void 0) {
1938
+ ar.thinking = thinking;
1939
+ } else if (reasoning_effort) {
1940
+ const effort = reasoning_effort.toLowerCase();
1941
+ if (effort === "minimal") {
1942
+ ar.thinking = { type: "disabled" };
1943
+ } else if (effort === "low") {
1944
+ ar.thinking = { type: "enabled", budget_tokens: 4096 };
1945
+ } else if (effort === "medium") {
1946
+ ar.thinking = { type: "enabled", budget_tokens: 16384 };
1947
+ } else if (effort === "high") {
1948
+ ar.thinking = { type: "enabled", budget_tokens: 32768 };
1949
+ } else if (effort === "xhigh") {
1950
+ ar.thinking = { type: "enabled", budget_tokens: 65536 };
1951
+ }
1952
+ }
1953
+ return {
1954
+ upstreamBody: ar,
1955
+ requestMetadata: buildRequestMetadata(request, ar.temperature, ar.top_p)
1956
+ };
1957
+ }
1958
+ const { request: cr } = translateRequest2(request, { dropImages });
1959
+ cr.stream = streaming;
1960
+ if (streaming) {
1961
+ cr.stream_options = { include_usage: true };
1962
+ }
1963
+ if (reasoning_effort !== void 0) {
1964
+ cr.reasoning_effort = reasoning_effort;
1965
+ }
1966
+ if (thinking !== void 0) {
1967
+ cr.thinking = thinking;
1968
+ }
1969
+ return {
1970
+ upstreamBody: cr,
1971
+ requestMetadata: buildRequestMetadata(request, cr.temperature, cr.top_p)
1972
+ };
1973
+ }
1974
+ function buildUpstreamHeaders(format, options, incoming) {
1975
+ const out = {};
1976
+ for (const [key, value] of Object.entries(incoming)) {
1977
+ if (DROPPED_HEADERS.has(key) || isClientSpecificHeader(key)) {
1978
+ continue;
1979
+ }
1980
+ out[key] = value;
1981
+ }
1982
+ if (options.defaultHeaders) {
1983
+ for (const [k, v] of Object.entries(options.defaultHeaders)) {
1984
+ out[k.toLowerCase()] = v;
1985
+ }
1986
+ }
1987
+ out["content-type"] = "application/json";
1988
+ if (format === "anthropic") {
1989
+ if (!out["anthropic-version"]) {
1990
+ out["anthropic-version"] = options.apiVersion ?? "2023-06-01";
1991
+ }
1992
+ if (typeof out["authorization"] === "string") {
1993
+ const match = /^Bearer\s+(.+)$/i.exec(out["authorization"]);
1994
+ if (match) {
1995
+ out["x-api-key"] = match[1].trim();
1996
+ }
1997
+ }
1998
+ delete out["authorization"];
1999
+ }
2000
+ return out;
2001
+ }
2002
+ var DROPPED_HEADERS = /* @__PURE__ */ new Set([
2003
+ "host",
2004
+ "content-length",
2005
+ "connection",
2006
+ "accept-encoding",
2007
+ "accept",
2008
+ "user-agent"
2009
+ ]);
2010
+ function isClientSpecificHeader(key) {
2011
+ const keyLower = key.toLowerCase();
2012
+ return keyLower.startsWith("openai-") || keyLower.startsWith("x-stainless") || keyLower.startsWith("x-codex-") || keyLower === "originator" || keyLower === "session_id" || keyLower === "x-client-request-id";
2013
+ }
2014
+ function responsesEventsToSseStream(events) {
2015
+ const encoder = new TextEncoder();
2016
+ return new ReadableStream({
2017
+ async pull(controller) {
2018
+ try {
2019
+ const { value, done } = await events.next();
2020
+ if (done) {
2021
+ controller.enqueue(encoder.encode("data: [DONE]\n\n"));
2022
+ controller.close();
2023
+ return;
2024
+ }
2025
+ controller.enqueue(encoder.encode(encodeSseEvent(value && value.type, value)));
2026
+ } catch (err) {
2027
+ controller.error(err);
2028
+ }
2029
+ },
2030
+ async cancel() {
2031
+ try {
2032
+ await events.return?.();
2033
+ } catch {
2034
+ }
2035
+ }
2036
+ });
2037
+ }
2038
+ function extractCacheStatsFromResponse(response) {
2039
+ const usage = response.usage;
2040
+ return {
2041
+ cachedTokens: usage?.input_tokens_details?.cached_tokens ?? 0,
2042
+ cacheCreationTokens: usage?.input_tokens_details?.cache_creation_tokens ?? 0,
2043
+ inputTokens: usage?.input_tokens ?? 0,
2044
+ outputTokens: usage?.output_tokens ?? 0,
2045
+ totalTokens: usage?.total_tokens ?? 0
2046
+ };
2047
+ }
2048
+ async function* collectCacheStatsFromStream(events, onCacheStats) {
2049
+ let lastStats;
2050
+ for await (const event of events) {
2051
+ if (event.type === "response.completed") {
2052
+ const eventResp = event;
2053
+ const resp = eventResp.response;
2054
+ if (resp?.usage) {
2055
+ lastStats = extractCacheStatsFromResponse(resp);
2056
+ }
2057
+ }
2058
+ yield event;
2059
+ }
2060
+ if (lastStats && onCacheStats) {
2061
+ onCacheStats(lastStats);
2062
+ }
2063
+ }
2064
+ function lastUserMessageHasImage(request) {
2065
+ const input = request.input;
2066
+ if (!input || !Array.isArray(input)) {
2067
+ return false;
2068
+ }
2069
+ for (let i = input.length - 1; i >= 0; i--) {
2070
+ const item = input[i];
2071
+ if (!item || typeof item !== "object") {
2072
+ continue;
2073
+ }
2074
+ const itemRecord = item;
2075
+ if (itemRecord.role !== "user") {
2076
+ continue;
2077
+ }
2078
+ const content = itemRecord.content;
2079
+ if (!Array.isArray(content)) {
2080
+ return false;
2081
+ }
2082
+ for (const part of content) {
2083
+ if (part && typeof part === "object") {
2084
+ const partItem = part;
2085
+ const type = partItem.type;
2086
+ if (type === "input_image" || type === "image" || type === "image_url") {
2087
+ return true;
2088
+ }
2089
+ }
2090
+ }
2091
+ return false;
2092
+ }
2093
+ return false;
2094
+ }
2095
+ function jsonErrorResponse(status, message) {
2096
+ return new Response(
2097
+ JSON.stringify({ error: { message, type: "upstream_error", code: String(status) } }),
2098
+ { status, headers: { "content-type": "application/json" } }
2099
+ );
2100
+ }
2101
+
2102
+ // src/translate/index.ts
2103
+ var translate_exports = {};
2104
+ __export(translate_exports, {
2105
+ anthropic: () => anthropic_exports,
2106
+ openai: () => openai_exports
2107
+ });
2108
+
2109
+ export { createResponsesFetch, encodeSseEvent, parseSseStream, translate_exports as translate };
2110
+ //# sourceMappingURL=index.js.map
2111
+ //# sourceMappingURL=index.js.map