aicodeswitch 1.0.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.
@@ -0,0 +1,888 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ClaudeToOpenAIResponsesEventTransform = exports.OpenAIResponsesToClaudeEventTransform = exports.OpenAIToClaudeEventTransform = exports.rewriteStream = exports.SSESerializerTransform = exports.SSEParserTransform = void 0;
7
+ const stream_1 = require("stream");
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ const claude_openai_1 = require("./claude-openai");
10
+ class SSEParserTransform extends stream_1.Transform {
11
+ constructor() {
12
+ super({ readableObjectMode: true });
13
+ Object.defineProperty(this, "buffer", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: ''
18
+ });
19
+ Object.defineProperty(this, "currentEvent", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: {}
24
+ });
25
+ Object.defineProperty(this, "dataLines", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: []
30
+ });
31
+ }
32
+ _transform(chunk, _encoding, callback) {
33
+ this.buffer += chunk.toString('utf8');
34
+ const lines = this.buffer.split('\n');
35
+ this.buffer = lines.pop() || '';
36
+ for (const line of lines) {
37
+ this.processLine(line);
38
+ }
39
+ callback();
40
+ }
41
+ _flush(callback) {
42
+ if (this.buffer.trim()) {
43
+ this.processLine(this.buffer.trim());
44
+ this.flushEvent();
45
+ }
46
+ callback();
47
+ }
48
+ processLine(line) {
49
+ if (!line.trim()) {
50
+ this.flushEvent();
51
+ return;
52
+ }
53
+ if (line.startsWith('event:')) {
54
+ this.currentEvent.event = line.slice(6).trim();
55
+ return;
56
+ }
57
+ if (line.startsWith('id:')) {
58
+ this.currentEvent.id = line.slice(3).trim();
59
+ return;
60
+ }
61
+ if (line.startsWith('data:')) {
62
+ this.dataLines.push(line.slice(5).trim());
63
+ }
64
+ }
65
+ flushEvent() {
66
+ if (!this.currentEvent.event && this.dataLines.length === 0 && !this.currentEvent.id) {
67
+ return;
68
+ }
69
+ if (this.dataLines.length > 0) {
70
+ const data = this.dataLines.join('\n');
71
+ if (data === '[DONE]') {
72
+ this.currentEvent.data = { type: 'done' };
73
+ }
74
+ else {
75
+ try {
76
+ this.currentEvent.data = JSON.parse(data);
77
+ }
78
+ catch (_a) {
79
+ this.currentEvent.data = data;
80
+ }
81
+ }
82
+ }
83
+ this.push(this.currentEvent);
84
+ this.currentEvent = {};
85
+ this.dataLines = [];
86
+ }
87
+ }
88
+ exports.SSEParserTransform = SSEParserTransform;
89
+ class SSESerializerTransform extends stream_1.Transform {
90
+ constructor() {
91
+ super({ writableObjectMode: true });
92
+ }
93
+ _transform(event, _encoding, callback) {
94
+ var _a;
95
+ let output = '';
96
+ if (event.event) {
97
+ output += `event: ${event.event}\n`;
98
+ }
99
+ if (event.id) {
100
+ output += `id: ${event.id}\n`;
101
+ }
102
+ if (event.data !== undefined) {
103
+ if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === 'done') {
104
+ output += 'data: [DONE]\n';
105
+ }
106
+ else if (typeof event.data === 'string') {
107
+ output += `data: ${event.data}\n`;
108
+ }
109
+ else {
110
+ output += `data: ${JSON.stringify(event.data)}\n`;
111
+ }
112
+ }
113
+ output += '\n';
114
+ this.push(output);
115
+ callback();
116
+ }
117
+ }
118
+ exports.SSESerializerTransform = SSESerializerTransform;
119
+ const rewriteStream = (stream, processor) => {
120
+ const transformer = new stream_1.Transform({
121
+ objectMode: true,
122
+ transform: (chunk, _encoding, callback) => {
123
+ Promise.resolve(processor(chunk, transformer))
124
+ .then((processed) => {
125
+ if (processed !== undefined) {
126
+ transformer.push(processed);
127
+ }
128
+ callback();
129
+ })
130
+ .catch((error) => callback(error));
131
+ },
132
+ });
133
+ return stream.pipe(transformer);
134
+ };
135
+ exports.rewriteStream = rewriteStream;
136
+ class OpenAIToClaudeEventTransform extends stream_1.Transform {
137
+ constructor(options) {
138
+ var _a;
139
+ super({ objectMode: true });
140
+ Object.defineProperty(this, "contentIndex", {
141
+ enumerable: true,
142
+ configurable: true,
143
+ writable: true,
144
+ value: 0
145
+ });
146
+ Object.defineProperty(this, "textBlockIndex", {
147
+ enumerable: true,
148
+ configurable: true,
149
+ writable: true,
150
+ value: null
151
+ });
152
+ Object.defineProperty(this, "thinkingBlockIndex", {
153
+ enumerable: true,
154
+ configurable: true,
155
+ writable: true,
156
+ value: null
157
+ });
158
+ Object.defineProperty(this, "toolCalls", {
159
+ enumerable: true,
160
+ configurable: true,
161
+ writable: true,
162
+ value: new Map()
163
+ });
164
+ Object.defineProperty(this, "toolCallIndexToBlockIndex", {
165
+ enumerable: true,
166
+ configurable: true,
167
+ writable: true,
168
+ value: new Map()
169
+ });
170
+ Object.defineProperty(this, "hasMessageStart", {
171
+ enumerable: true,
172
+ configurable: true,
173
+ writable: true,
174
+ value: false
175
+ });
176
+ Object.defineProperty(this, "stopReason", {
177
+ enumerable: true,
178
+ configurable: true,
179
+ writable: true,
180
+ value: 'end_turn'
181
+ });
182
+ Object.defineProperty(this, "usage", {
183
+ enumerable: true,
184
+ configurable: true,
185
+ writable: true,
186
+ value: null
187
+ });
188
+ Object.defineProperty(this, "messageId", {
189
+ enumerable: true,
190
+ configurable: true,
191
+ writable: true,
192
+ value: null
193
+ });
194
+ Object.defineProperty(this, "model", {
195
+ enumerable: true,
196
+ configurable: true,
197
+ writable: true,
198
+ value: null
199
+ });
200
+ Object.defineProperty(this, "finalized", {
201
+ enumerable: true,
202
+ configurable: true,
203
+ writable: true,
204
+ value: false
205
+ });
206
+ this.model = (_a = options === null || options === void 0 ? void 0 : options.model) !== null && _a !== void 0 ? _a : null;
207
+ }
208
+ getUsage() {
209
+ if (!this.usage)
210
+ return undefined;
211
+ return Object.assign({}, this.usage);
212
+ }
213
+ _transform(event, _encoding, callback) {
214
+ var _a;
215
+ if (this.finalized) {
216
+ callback();
217
+ return;
218
+ }
219
+ if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === 'done') {
220
+ this.finalize();
221
+ callback();
222
+ return;
223
+ }
224
+ const chunk = event.data;
225
+ if (!chunk) {
226
+ callback();
227
+ return;
228
+ }
229
+ if (chunk.id && !this.messageId) {
230
+ this.messageId = chunk.id;
231
+ }
232
+ if (chunk.model && !this.model) {
233
+ this.model = chunk.model;
234
+ }
235
+ if (chunk.usage) {
236
+ this.usage = (0, claude_openai_1.convertOpenAIUsageToClaude)(chunk.usage);
237
+ }
238
+ if (Array.isArray(chunk.choices)) {
239
+ for (const choice of chunk.choices) {
240
+ this.handleChoice(choice);
241
+ }
242
+ }
243
+ callback();
244
+ }
245
+ _flush(callback) {
246
+ this.finalize();
247
+ callback();
248
+ }
249
+ assignContentBlockIndex() {
250
+ const index = this.contentIndex;
251
+ this.contentIndex += 1;
252
+ return index;
253
+ }
254
+ pushEvent(type, data) {
255
+ this.push({ event: type, data });
256
+ }
257
+ ensureMessageStart() {
258
+ if (this.hasMessageStart)
259
+ return;
260
+ const message = {
261
+ id: this.messageId || `msg_${crypto_1.default.randomUUID()}`,
262
+ type: 'message',
263
+ role: 'assistant',
264
+ content: [],
265
+ model: this.model || 'unknown',
266
+ stop_reason: null,
267
+ stop_sequence: null,
268
+ usage: {
269
+ input_tokens: 0,
270
+ output_tokens: 0,
271
+ },
272
+ };
273
+ this.pushEvent('message_start', { type: 'message_start', message });
274
+ this.hasMessageStart = true;
275
+ }
276
+ handleChoice(choice) {
277
+ var _a, _b, _c;
278
+ const delta = choice === null || choice === void 0 ? void 0 : choice.delta;
279
+ if (!delta)
280
+ return;
281
+ if (typeof (choice === null || choice === void 0 ? void 0 : choice.finish_reason) === 'string') {
282
+ this.stopReason = (0, claude_openai_1.mapStopReason)(choice.finish_reason);
283
+ }
284
+ if (typeof delta.content === 'string') {
285
+ this.ensureMessageStart();
286
+ if (this.textBlockIndex === null) {
287
+ this.textBlockIndex = this.assignContentBlockIndex();
288
+ this.pushEvent('content_block_start', {
289
+ type: 'content_block_start',
290
+ index: this.textBlockIndex,
291
+ content_block: { type: 'text' },
292
+ });
293
+ }
294
+ this.pushEvent('content_block_delta', {
295
+ type: 'content_block_delta',
296
+ index: this.textBlockIndex,
297
+ delta: {
298
+ type: 'text_delta',
299
+ text: delta.content,
300
+ },
301
+ });
302
+ }
303
+ if (typeof ((_a = delta.thinking) === null || _a === void 0 ? void 0 : _a.content) === 'string') {
304
+ this.ensureMessageStart();
305
+ if (this.thinkingBlockIndex === null) {
306
+ this.thinkingBlockIndex = this.assignContentBlockIndex();
307
+ this.pushEvent('content_block_start', {
308
+ type: 'content_block_start',
309
+ index: this.thinkingBlockIndex,
310
+ content_block: { type: 'thinking', thinking: '' },
311
+ });
312
+ }
313
+ this.pushEvent('content_block_delta', {
314
+ type: 'content_block_delta',
315
+ index: this.thinkingBlockIndex,
316
+ delta: {
317
+ type: 'thinking_delta',
318
+ thinking: delta.thinking.content,
319
+ },
320
+ });
321
+ }
322
+ if (Array.isArray(delta.tool_calls)) {
323
+ for (let i = 0; i < delta.tool_calls.length; i += 1) {
324
+ const toolCall = delta.tool_calls[i];
325
+ const toolIndex = typeof (toolCall === null || toolCall === void 0 ? void 0 : toolCall.index) === 'number' ? toolCall.index : i;
326
+ const toolName = (_b = toolCall === null || toolCall === void 0 ? void 0 : toolCall.function) === null || _b === void 0 ? void 0 : _b.name;
327
+ if ((toolCall === null || toolCall === void 0 ? void 0 : toolCall.id) && toolName) {
328
+ this.ensureMessageStart();
329
+ const toolBlockIndex = this.assignContentBlockIndex();
330
+ this.toolCalls.set(toolIndex, {
331
+ id: toolCall.id,
332
+ name: toolName,
333
+ arguments: '',
334
+ });
335
+ this.toolCallIndexToBlockIndex.set(toolIndex, toolBlockIndex);
336
+ this.pushEvent('content_block_start', {
337
+ type: 'content_block_start',
338
+ index: toolBlockIndex,
339
+ content_block: {
340
+ type: 'tool_use',
341
+ id: toolCall.id,
342
+ name: toolName,
343
+ },
344
+ });
345
+ }
346
+ if ((_c = toolCall === null || toolCall === void 0 ? void 0 : toolCall.function) === null || _c === void 0 ? void 0 : _c.arguments) {
347
+ this.ensureMessageStart();
348
+ const stored = this.toolCalls.get(toolIndex);
349
+ if (stored) {
350
+ stored.arguments += toolCall.function.arguments;
351
+ }
352
+ const toolBlockIndex = this.toolCallIndexToBlockIndex.get(toolIndex);
353
+ if (toolBlockIndex !== undefined) {
354
+ this.pushEvent('content_block_delta', {
355
+ type: 'content_block_delta',
356
+ index: toolBlockIndex,
357
+ delta: {
358
+ type: 'input_json_delta',
359
+ partial_json: toolCall.function.arguments,
360
+ },
361
+ });
362
+ }
363
+ }
364
+ }
365
+ }
366
+ }
367
+ finalize() {
368
+ if (this.finalized)
369
+ return;
370
+ this.ensureMessageStart();
371
+ for (const toolBlockIndex of this.toolCallIndexToBlockIndex.values()) {
372
+ this.pushEvent('content_block_stop', {
373
+ type: 'content_block_stop',
374
+ index: toolBlockIndex,
375
+ });
376
+ }
377
+ if (this.thinkingBlockIndex !== null) {
378
+ this.pushEvent('content_block_stop', {
379
+ type: 'content_block_stop',
380
+ index: this.thinkingBlockIndex,
381
+ });
382
+ this.thinkingBlockIndex = null;
383
+ }
384
+ if (this.textBlockIndex !== null) {
385
+ this.pushEvent('content_block_stop', {
386
+ type: 'content_block_stop',
387
+ index: this.textBlockIndex,
388
+ });
389
+ this.textBlockIndex = null;
390
+ }
391
+ const usage = this.usage || {
392
+ input_tokens: 0,
393
+ output_tokens: 0,
394
+ cache_read_input_tokens: 0,
395
+ };
396
+ this.pushEvent('message_delta', {
397
+ type: 'message_delta',
398
+ delta: {
399
+ stop_reason: this.stopReason,
400
+ stop_sequence: null,
401
+ },
402
+ usage,
403
+ });
404
+ this.pushEvent('message_stop', { type: 'message_stop' });
405
+ this.finalized = true;
406
+ }
407
+ }
408
+ exports.OpenAIToClaudeEventTransform = OpenAIToClaudeEventTransform;
409
+ class OpenAIResponsesToClaudeEventTransform extends stream_1.Transform {
410
+ constructor(options) {
411
+ var _a;
412
+ super({ objectMode: true });
413
+ Object.defineProperty(this, "contentIndex", {
414
+ enumerable: true,
415
+ configurable: true,
416
+ writable: true,
417
+ value: 0
418
+ });
419
+ Object.defineProperty(this, "textBlockIndex", {
420
+ enumerable: true,
421
+ configurable: true,
422
+ writable: true,
423
+ value: null
424
+ });
425
+ Object.defineProperty(this, "toolCalls", {
426
+ enumerable: true,
427
+ configurable: true,
428
+ writable: true,
429
+ value: new Map()
430
+ });
431
+ Object.defineProperty(this, "toolCallKeyToBlockIndex", {
432
+ enumerable: true,
433
+ configurable: true,
434
+ writable: true,
435
+ value: new Map()
436
+ });
437
+ Object.defineProperty(this, "hasMessageStart", {
438
+ enumerable: true,
439
+ configurable: true,
440
+ writable: true,
441
+ value: false
442
+ });
443
+ Object.defineProperty(this, "stopReason", {
444
+ enumerable: true,
445
+ configurable: true,
446
+ writable: true,
447
+ value: 'end_turn'
448
+ });
449
+ Object.defineProperty(this, "usage", {
450
+ enumerable: true,
451
+ configurable: true,
452
+ writable: true,
453
+ value: null
454
+ });
455
+ Object.defineProperty(this, "messageId", {
456
+ enumerable: true,
457
+ configurable: true,
458
+ writable: true,
459
+ value: null
460
+ });
461
+ Object.defineProperty(this, "model", {
462
+ enumerable: true,
463
+ configurable: true,
464
+ writable: true,
465
+ value: null
466
+ });
467
+ Object.defineProperty(this, "finalized", {
468
+ enumerable: true,
469
+ configurable: true,
470
+ writable: true,
471
+ value: false
472
+ });
473
+ this.model = (_a = options === null || options === void 0 ? void 0 : options.model) !== null && _a !== void 0 ? _a : null;
474
+ }
475
+ getUsage() {
476
+ if (!this.usage)
477
+ return undefined;
478
+ return Object.assign({}, this.usage);
479
+ }
480
+ _transform(event, _encoding, callback) {
481
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
482
+ if (this.finalized) {
483
+ callback();
484
+ return;
485
+ }
486
+ const eventType = event.event || ((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) || '';
487
+ if (eventType.includes('response.created')) {
488
+ const response = ((_b = event.data) === null || _b === void 0 ? void 0 : _b.response) || event.data;
489
+ if (response === null || response === void 0 ? void 0 : response.id)
490
+ this.messageId = response.id;
491
+ if (response === null || response === void 0 ? void 0 : response.model)
492
+ this.model = response.model;
493
+ this.ensureMessageStart();
494
+ callback();
495
+ return;
496
+ }
497
+ if (eventType.includes('output_text')) {
498
+ const deltaText = (_d = (_c = event.data) === null || _c === void 0 ? void 0 : _c.delta) !== null && _d !== void 0 ? _d : (_e = event.data) === null || _e === void 0 ? void 0 : _e.text;
499
+ if (typeof deltaText === 'string' && deltaText.length > 0) {
500
+ this.handleTextDelta(deltaText);
501
+ }
502
+ if (eventType.includes('done')) {
503
+ this.closeTextBlock();
504
+ }
505
+ callback();
506
+ return;
507
+ }
508
+ if (eventType.includes('tool_call')) {
509
+ const toolId = ((_f = event.data) === null || _f === void 0 ? void 0 : _f.tool_call_id) || ((_g = event.data) === null || _g === void 0 ? void 0 : _g.id) || ((_j = (_h = event.data) === null || _h === void 0 ? void 0 : _h.tool_call) === null || _j === void 0 ? void 0 : _j.id) || `tool_${this.toolCalls.size + 1}`;
510
+ const toolName = ((_k = event.data) === null || _k === void 0 ? void 0 : _k.name) || ((_m = (_l = event.data) === null || _l === void 0 ? void 0 : _l.tool_call) === null || _m === void 0 ? void 0 : _m.name) || 'tool';
511
+ const delta = (_p = (_o = event.data) === null || _o === void 0 ? void 0 : _o.delta) !== null && _p !== void 0 ? _p : (_q = event.data) === null || _q === void 0 ? void 0 : _q.arguments;
512
+ if (typeof delta === 'string') {
513
+ this.handleToolDelta(toolId, toolName, delta);
514
+ }
515
+ if (eventType.includes('done')) {
516
+ const key = toolId || toolName;
517
+ this.closeToolBlock(key);
518
+ }
519
+ callback();
520
+ return;
521
+ }
522
+ if (eventType.includes('response.completed')) {
523
+ const response = ((_r = event.data) === null || _r === void 0 ? void 0 : _r.response) || event.data;
524
+ if (response === null || response === void 0 ? void 0 : response.usage) {
525
+ const inputTokens = (_v = (_t = (_s = response.usage) === null || _s === void 0 ? void 0 : _s.input_tokens) !== null && _t !== void 0 ? _t : (_u = response.usage) === null || _u === void 0 ? void 0 : _u.prompt_tokens) !== null && _v !== void 0 ? _v : 0;
526
+ const outputTokens = (_z = (_x = (_w = response.usage) === null || _w === void 0 ? void 0 : _w.output_tokens) !== null && _x !== void 0 ? _x : (_y = response.usage) === null || _y === void 0 ? void 0 : _y.completion_tokens) !== null && _z !== void 0 ? _z : 0;
527
+ const cacheRead = (_4 = (_1 = (_0 = response.usage) === null || _0 === void 0 ? void 0 : _0.cache_read_input_tokens) !== null && _1 !== void 0 ? _1 : (_3 = (_2 = response.usage) === null || _2 === void 0 ? void 0 : _2.prompt_tokens_details) === null || _3 === void 0 ? void 0 : _3.cached_tokens) !== null && _4 !== void 0 ? _4 : 0;
528
+ this.usage = {
529
+ input_tokens: inputTokens,
530
+ output_tokens: outputTokens,
531
+ cache_read_input_tokens: cacheRead,
532
+ };
533
+ }
534
+ this.finalize();
535
+ callback();
536
+ return;
537
+ }
538
+ callback();
539
+ }
540
+ _flush(callback) {
541
+ this.finalize();
542
+ callback();
543
+ }
544
+ assignContentBlockIndex() {
545
+ const index = this.contentIndex;
546
+ this.contentIndex += 1;
547
+ return index;
548
+ }
549
+ pushEvent(type, data) {
550
+ this.push({ event: type, data });
551
+ }
552
+ ensureMessageStart() {
553
+ if (this.hasMessageStart)
554
+ return;
555
+ const message = {
556
+ id: this.messageId || `msg_${crypto_1.default.randomUUID()}`,
557
+ type: 'message',
558
+ role: 'assistant',
559
+ content: [],
560
+ model: this.model || 'unknown',
561
+ stop_reason: null,
562
+ stop_sequence: null,
563
+ usage: {
564
+ input_tokens: 0,
565
+ output_tokens: 0,
566
+ },
567
+ };
568
+ this.pushEvent('message_start', { type: 'message_start', message });
569
+ this.hasMessageStart = true;
570
+ }
571
+ handleTextDelta(text) {
572
+ this.ensureMessageStart();
573
+ if (this.textBlockIndex === null) {
574
+ this.textBlockIndex = this.assignContentBlockIndex();
575
+ this.pushEvent('content_block_start', {
576
+ type: 'content_block_start',
577
+ index: this.textBlockIndex,
578
+ content_block: { type: 'text' },
579
+ });
580
+ }
581
+ this.pushEvent('content_block_delta', {
582
+ type: 'content_block_delta',
583
+ index: this.textBlockIndex,
584
+ delta: { type: 'text_delta', text },
585
+ });
586
+ }
587
+ closeTextBlock() {
588
+ if (this.textBlockIndex === null)
589
+ return;
590
+ this.pushEvent('content_block_stop', {
591
+ type: 'content_block_stop',
592
+ index: this.textBlockIndex,
593
+ });
594
+ this.textBlockIndex = null;
595
+ }
596
+ handleToolDelta(toolId, toolName, delta) {
597
+ this.ensureMessageStart();
598
+ const key = toolId || toolName;
599
+ if (!this.toolCalls.has(key)) {
600
+ const toolBlockIndex = this.assignContentBlockIndex();
601
+ this.toolCalls.set(key, { id: toolId, name: toolName, arguments: '' });
602
+ this.toolCallKeyToBlockIndex.set(key, toolBlockIndex);
603
+ this.pushEvent('content_block_start', {
604
+ type: 'content_block_start',
605
+ index: toolBlockIndex,
606
+ content_block: { type: 'tool_use', id: toolId, name: toolName },
607
+ });
608
+ }
609
+ const toolEntry = this.toolCalls.get(key);
610
+ if (toolEntry) {
611
+ toolEntry.arguments += delta;
612
+ }
613
+ const blockIndex = this.toolCallKeyToBlockIndex.get(key);
614
+ if (blockIndex !== undefined) {
615
+ this.pushEvent('content_block_delta', {
616
+ type: 'content_block_delta',
617
+ index: blockIndex,
618
+ delta: { type: 'input_json_delta', partial_json: delta },
619
+ });
620
+ }
621
+ }
622
+ closeToolBlock(key) {
623
+ const blockIndex = this.toolCallKeyToBlockIndex.get(key);
624
+ if (blockIndex === undefined)
625
+ return;
626
+ this.pushEvent('content_block_stop', {
627
+ type: 'content_block_stop',
628
+ index: blockIndex,
629
+ });
630
+ this.toolCallKeyToBlockIndex.delete(key);
631
+ this.toolCalls.delete(key);
632
+ }
633
+ finalize() {
634
+ if (this.finalized)
635
+ return;
636
+ this.ensureMessageStart();
637
+ this.closeTextBlock();
638
+ for (const blockIndex of this.toolCallKeyToBlockIndex.values()) {
639
+ this.pushEvent('content_block_stop', {
640
+ type: 'content_block_stop',
641
+ index: blockIndex,
642
+ });
643
+ }
644
+ this.toolCallKeyToBlockIndex.clear();
645
+ this.toolCalls.clear();
646
+ const usage = this.usage || {
647
+ input_tokens: 0,
648
+ output_tokens: 0,
649
+ cache_read_input_tokens: 0,
650
+ };
651
+ this.pushEvent('message_delta', {
652
+ type: 'message_delta',
653
+ delta: { stop_reason: this.stopReason, stop_sequence: null },
654
+ usage,
655
+ });
656
+ this.pushEvent('message_stop', { type: 'message_stop' });
657
+ this.finalized = true;
658
+ }
659
+ }
660
+ exports.OpenAIResponsesToClaudeEventTransform = OpenAIResponsesToClaudeEventTransform;
661
+ class ClaudeToOpenAIResponsesEventTransform extends stream_1.Transform {
662
+ constructor(options) {
663
+ var _a;
664
+ super({ objectMode: true });
665
+ Object.defineProperty(this, "responseId", {
666
+ enumerable: true,
667
+ configurable: true,
668
+ writable: true,
669
+ value: null
670
+ });
671
+ Object.defineProperty(this, "model", {
672
+ enumerable: true,
673
+ configurable: true,
674
+ writable: true,
675
+ value: null
676
+ });
677
+ Object.defineProperty(this, "createdAt", {
678
+ enumerable: true,
679
+ configurable: true,
680
+ writable: true,
681
+ value: Date.now()
682
+ });
683
+ Object.defineProperty(this, "outputText", {
684
+ enumerable: true,
685
+ configurable: true,
686
+ writable: true,
687
+ value: ''
688
+ });
689
+ Object.defineProperty(this, "textBlockIndex", {
690
+ enumerable: true,
691
+ configurable: true,
692
+ writable: true,
693
+ value: null
694
+ });
695
+ Object.defineProperty(this, "toolCalls", {
696
+ enumerable: true,
697
+ configurable: true,
698
+ writable: true,
699
+ value: new Map()
700
+ });
701
+ Object.defineProperty(this, "completedToolCalls", {
702
+ enumerable: true,
703
+ configurable: true,
704
+ writable: true,
705
+ value: []
706
+ });
707
+ Object.defineProperty(this, "usage", {
708
+ enumerable: true,
709
+ configurable: true,
710
+ writable: true,
711
+ value: null
712
+ });
713
+ Object.defineProperty(this, "hasCreated", {
714
+ enumerable: true,
715
+ configurable: true,
716
+ writable: true,
717
+ value: false
718
+ });
719
+ this.model = (_a = options === null || options === void 0 ? void 0 : options.model) !== null && _a !== void 0 ? _a : null;
720
+ }
721
+ getUsage() {
722
+ if (!this.usage)
723
+ return undefined;
724
+ return Object.assign({}, this.usage);
725
+ }
726
+ _transform(event, _encoding, callback) {
727
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
728
+ const eventType = event.event || '';
729
+ if (eventType === 'message_start') {
730
+ const message = (_a = event.data) === null || _a === void 0 ? void 0 : _a.message;
731
+ if (message === null || message === void 0 ? void 0 : message.id)
732
+ this.responseId = message.id;
733
+ if (message === null || message === void 0 ? void 0 : message.model)
734
+ this.model = message.model;
735
+ this.ensureResponseCreated();
736
+ callback();
737
+ return;
738
+ }
739
+ if (eventType === 'content_block_start') {
740
+ const block = (_b = event.data) === null || _b === void 0 ? void 0 : _b.content_block;
741
+ const index = (_c = event.data) === null || _c === void 0 ? void 0 : _c.index;
742
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'text') {
743
+ this.textBlockIndex = index;
744
+ }
745
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'tool_use' && typeof index === 'number') {
746
+ this.toolCalls.set(index, {
747
+ id: block.id || `tool_${index}`,
748
+ name: block.name || 'tool',
749
+ arguments: '',
750
+ });
751
+ }
752
+ callback();
753
+ return;
754
+ }
755
+ if (eventType === 'content_block_delta') {
756
+ const delta = (_d = event.data) === null || _d === void 0 ? void 0 : _d.delta;
757
+ const index = (_e = event.data) === null || _e === void 0 ? void 0 : _e.index;
758
+ if ((delta === null || delta === void 0 ? void 0 : delta.type) === 'text_delta' && typeof delta.text === 'string') {
759
+ this.ensureResponseCreated();
760
+ this.outputText += delta.text;
761
+ this.pushEvent('response.output_text.delta', {
762
+ type: 'response.output_text.delta',
763
+ delta: delta.text,
764
+ output_index: 0,
765
+ content_index: 0,
766
+ });
767
+ }
768
+ if ((delta === null || delta === void 0 ? void 0 : delta.type) === 'input_json_delta' && typeof delta.partial_json === 'string' && typeof index === 'number') {
769
+ const tool = this.toolCalls.get(index);
770
+ if (tool) {
771
+ tool.arguments += delta.partial_json;
772
+ this.ensureResponseCreated();
773
+ this.pushEvent('response.output_tool_call.delta', {
774
+ type: 'response.output_tool_call.delta',
775
+ delta: delta.partial_json,
776
+ output_index: index,
777
+ tool_call_id: tool.id,
778
+ name: tool.name,
779
+ });
780
+ }
781
+ }
782
+ callback();
783
+ return;
784
+ }
785
+ if (eventType === 'content_block_stop') {
786
+ const index = (_f = event.data) === null || _f === void 0 ? void 0 : _f.index;
787
+ if (typeof index === 'number') {
788
+ if (this.textBlockIndex === index) {
789
+ this.pushEvent('response.output_text.done', {
790
+ type: 'response.output_text.done',
791
+ text: this.outputText,
792
+ output_index: 0,
793
+ content_index: 0,
794
+ });
795
+ this.textBlockIndex = null;
796
+ }
797
+ const tool = this.toolCalls.get(index);
798
+ if (tool) {
799
+ this.completedToolCalls.push(tool);
800
+ this.pushEvent('response.output_tool_call.done', {
801
+ type: 'response.output_tool_call.done',
802
+ output_index: index,
803
+ tool_call: {
804
+ id: tool.id,
805
+ name: tool.name,
806
+ arguments: tool.arguments,
807
+ },
808
+ });
809
+ this.toolCalls.delete(index);
810
+ }
811
+ }
812
+ callback();
813
+ return;
814
+ }
815
+ if (eventType === 'message_delta') {
816
+ if ((_g = event.data) === null || _g === void 0 ? void 0 : _g.usage) {
817
+ this.usage = {
818
+ input_tokens: (_h = event.data.usage.input_tokens) !== null && _h !== void 0 ? _h : 0,
819
+ output_tokens: (_j = event.data.usage.output_tokens) !== null && _j !== void 0 ? _j : 0,
820
+ cache_read_input_tokens: (_k = event.data.usage.cache_read_input_tokens) !== null && _k !== void 0 ? _k : 0,
821
+ };
822
+ }
823
+ callback();
824
+ return;
825
+ }
826
+ if (eventType === 'message_stop') {
827
+ this.pushCompletedResponse();
828
+ callback();
829
+ return;
830
+ }
831
+ callback();
832
+ }
833
+ ensureResponseCreated() {
834
+ if (this.hasCreated)
835
+ return;
836
+ const response = {
837
+ id: this.responseId || `resp_${crypto_1.default.randomUUID()}`,
838
+ object: 'response',
839
+ model: this.model || 'unknown',
840
+ output: [],
841
+ created_at: this.createdAt,
842
+ };
843
+ this.pushEvent('response.created', { type: 'response.created', response });
844
+ this.hasCreated = true;
845
+ }
846
+ pushEvent(event, data) {
847
+ this.push({ event, data });
848
+ }
849
+ pushCompletedResponse() {
850
+ var _a, _b, _c, _d, _e, _f;
851
+ this.ensureResponseCreated();
852
+ const output = [];
853
+ if (this.outputText) {
854
+ output.push({
855
+ type: 'message',
856
+ role: 'assistant',
857
+ content: [{ type: 'output_text', text: this.outputText }],
858
+ });
859
+ }
860
+ for (const tool of this.completedToolCalls) {
861
+ output.push({
862
+ type: 'tool_call',
863
+ id: tool.id,
864
+ name: tool.name,
865
+ arguments: tool.arguments,
866
+ });
867
+ }
868
+ const inputTokens = (_b = (_a = this.usage) === null || _a === void 0 ? void 0 : _a.input_tokens) !== null && _b !== void 0 ? _b : 0;
869
+ const cacheRead = (_d = (_c = this.usage) === null || _c === void 0 ? void 0 : _c.cache_read_input_tokens) !== null && _d !== void 0 ? _d : 0;
870
+ const outputTokens = (_f = (_e = this.usage) === null || _e === void 0 ? void 0 : _e.output_tokens) !== null && _f !== void 0 ? _f : 0;
871
+ const response = {
872
+ id: this.responseId || `resp_${crypto_1.default.randomUUID()}`,
873
+ object: 'response',
874
+ model: this.model || 'unknown',
875
+ output,
876
+ output_text: this.outputText,
877
+ status: 'completed',
878
+ created_at: this.createdAt,
879
+ usage: {
880
+ input_tokens: inputTokens + cacheRead,
881
+ output_tokens: outputTokens,
882
+ total_tokens: inputTokens + cacheRead + outputTokens,
883
+ },
884
+ };
885
+ this.pushEvent('response.completed', { type: 'response.completed', response });
886
+ }
887
+ }
888
+ exports.ClaudeToOpenAIResponsesEventTransform = ClaudeToOpenAIResponsesEventTransform;