aicodeswitch 4.0.4 → 5.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.
Files changed (77) hide show
  1. package/README.md +6 -5
  2. package/UPGRADE.md +5 -6
  3. package/dist/server/coding-plan.js +94 -0
  4. package/dist/server/config-managed-fields.js +1 -0
  5. package/dist/server/conversions/compact.js +613 -0
  6. package/dist/server/conversions/detector.js +70 -0
  7. package/dist/server/conversions/index.js +290 -0
  8. package/dist/server/conversions/pairs/claude-completions/request.js +167 -0
  9. package/dist/server/conversions/pairs/claude-completions/response.js +56 -0
  10. package/dist/server/conversions/pairs/claude-completions/streaming.js +259 -0
  11. package/dist/server/conversions/pairs/claude-gemini/request.js +130 -0
  12. package/dist/server/conversions/pairs/claude-gemini/response.js +65 -0
  13. package/dist/server/conversions/pairs/claude-gemini/streaming.js +199 -0
  14. package/dist/server/conversions/pairs/claude-responses/request.js +190 -0
  15. package/dist/server/conversions/pairs/claude-responses/response.js +89 -0
  16. package/dist/server/conversions/pairs/claude-responses/streaming.js +266 -0
  17. package/dist/server/conversions/pairs/completions-claude/request.js +111 -0
  18. package/dist/server/conversions/pairs/completions-claude/response.js +67 -0
  19. package/dist/server/conversions/pairs/completions-claude/streaming.js +165 -0
  20. package/dist/server/conversions/pairs/completions-gemini/request.js +169 -0
  21. package/dist/server/conversions/pairs/completions-gemini/response.js +70 -0
  22. package/dist/server/conversions/pairs/completions-gemini/streaming.js +132 -0
  23. package/dist/server/conversions/pairs/completions-responses/request.js +149 -0
  24. package/dist/server/conversions/pairs/completions-responses/response.js +74 -0
  25. package/dist/server/conversions/pairs/completions-responses/streaming.js +189 -0
  26. package/dist/server/conversions/pairs/gemini-claude/request.js +118 -0
  27. package/dist/server/conversions/pairs/gemini-claude/response.js +45 -0
  28. package/dist/server/conversions/pairs/gemini-claude/streaming.js +146 -0
  29. package/dist/server/conversions/pairs/gemini-completions/request.js +151 -0
  30. package/dist/server/conversions/pairs/gemini-completions/response.js +54 -0
  31. package/dist/server/conversions/pairs/gemini-completions/streaming.js +108 -0
  32. package/dist/server/conversions/pairs/gemini-responses/request.js +18 -0
  33. package/dist/server/conversions/pairs/gemini-responses/response.js +18 -0
  34. package/dist/server/conversions/pairs/gemini-responses/streaming.js +43 -0
  35. package/dist/server/conversions/pairs/responses-claude/request.js +180 -0
  36. package/dist/server/conversions/pairs/responses-claude/response.js +70 -0
  37. package/dist/server/conversions/pairs/responses-claude/streaming.js +345 -0
  38. package/dist/server/conversions/pairs/responses-completions/request.js +207 -0
  39. package/dist/server/conversions/pairs/responses-completions/response.js +96 -0
  40. package/dist/server/conversions/pairs/responses-completions/streaming.js +344 -0
  41. package/dist/server/conversions/pairs/responses-gemini/request.js +18 -0
  42. package/dist/server/conversions/pairs/responses-gemini/response.js +18 -0
  43. package/dist/server/conversions/pairs/responses-gemini/streaming.js +43 -0
  44. package/dist/server/conversions/pairs/responses-responses/request.js +115 -0
  45. package/dist/server/conversions/pipeline.js +296 -0
  46. package/dist/server/conversions/stream-converter-adapter.js +49 -0
  47. package/dist/server/conversions/thinking/effort.js +61 -0
  48. package/dist/server/conversions/thinking/mapper.js +59 -0
  49. package/dist/server/conversions/thinking/providers.js +80 -0
  50. package/dist/server/conversions/types.js +5 -0
  51. package/dist/server/conversions/url-normalizer.js +58 -0
  52. package/dist/server/conversions/utils/format-mappers.js +57 -0
  53. package/dist/server/conversions/utils/id.js +33 -0
  54. package/dist/server/conversions/utils/stop-reasons.js +95 -0
  55. package/dist/server/conversions/utils/streaming-helpers.js +59 -0
  56. package/dist/server/conversions/utils/tool-schema.js +169 -0
  57. package/dist/server/conversions/utils/usage.js +82 -0
  58. package/dist/server/fs-database.js +465 -135
  59. package/dist/server/main.js +93 -33
  60. package/dist/server/original-config-reader.js +1 -1
  61. package/dist/server/proxy-server.js +887 -633
  62. package/dist/server/transformers/chunk-collector.js +5 -1
  63. package/dist/server/transformers/streaming.js +6 -3235
  64. package/dist/server/type-migration.js +2 -3
  65. package/dist/server/utils.js +5 -0
  66. package/dist/ui/assets/{index-C7G0whng.css → index-BHR12ImE.css} +1 -1
  67. package/dist/ui/assets/index-Rwiqttz-.js +517 -0
  68. package/dist/ui/index.html +2 -2
  69. package/package.json +1 -1
  70. package/dist/server/transformers/transformers.js +0 -1767
  71. package/dist/ui/assets/index-Dl-B9pXM.js +0 -514
  72. package/schema/claude.schema.md +0 -946
  73. package/schema/deepseek-chat.schema.md +0 -799
  74. package/schema/gemini.schema.md +0 -1408
  75. package/schema/openai-chat-completions.schema.md +0 -1088
  76. package/schema/openai-responses.schema.md +0 -226196
  77. package/schema/stream.md +0 -2592
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI Responses API → OpenAI Chat Completions API request conversion.
4
+ *
5
+ * Converts a Responses API request body into a Chat Completions request body.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.responsesToCompletions = responsesToCompletions;
9
+ const effort_js_1 = require("../../thinking/effort.js");
10
+ const id_js_1 = require("../../utils/id.js");
11
+ /**
12
+ * Convert an OpenAI Responses API request body to a Chat Completions request body.
13
+ */
14
+ function responsesToCompletions(body) {
15
+ var _a, _b;
16
+ const messages = [];
17
+ // --- instructions -> system message ---
18
+ if (body.instructions) {
19
+ messages.push({ role: 'system', content: body.instructions });
20
+ }
21
+ // --- input -> messages ---
22
+ if (typeof body.input === 'string') {
23
+ messages.push({ role: 'user', content: body.input });
24
+ }
25
+ else if (Array.isArray(body.input)) {
26
+ // We accumulate items that belong to the same assistant message
27
+ // (e.g. reasoning + content + function_calls need to merge)
28
+ let pendingAssistantMessage = null;
29
+ let pendingToolCalls = [];
30
+ let pendingReasoningContent;
31
+ for (const item of body.input) {
32
+ if (item.type === 'message') {
33
+ // Flush any pending assistant message before processing a new message
34
+ flushPendingAssistant(messages, pendingAssistantMessage, pendingToolCalls, pendingReasoningContent);
35
+ pendingAssistantMessage = null;
36
+ pendingToolCalls = [];
37
+ pendingReasoningContent = undefined;
38
+ if (item.role === 'system' || item.role === 'developer') {
39
+ // Merge system/developer messages into the system message at head
40
+ const text = extractContent(item.content, item.role === 'assistant' ? 'output_text' : 'input_text');
41
+ if (text) {
42
+ const existingSystem = messages.find((m) => m.role === 'system');
43
+ if (existingSystem) {
44
+ existingSystem.content += '\n' + text;
45
+ }
46
+ else {
47
+ messages.unshift({ role: 'system', content: text });
48
+ }
49
+ }
50
+ }
51
+ else if (item.role === 'user') {
52
+ const text = extractContent(item.content, 'input_text');
53
+ messages.push({ role: 'user', content: text || '' });
54
+ }
55
+ else if (item.role === 'assistant') {
56
+ const text = extractContent(item.content, 'output_text');
57
+ pendingAssistantMessage = { role: 'assistant', content: text || null };
58
+ }
59
+ }
60
+ else if (item.type === 'function_call') {
61
+ // Accumulate as tool_calls on the nearest assistant message
62
+ if (!pendingAssistantMessage) {
63
+ pendingAssistantMessage = { role: 'assistant', content: null };
64
+ }
65
+ pendingToolCalls.push({
66
+ id: item.call_id || (0, id_js_1.generateCallId)(),
67
+ type: 'function',
68
+ function: {
69
+ name: item.name || '',
70
+ arguments: item.arguments || '{}',
71
+ },
72
+ });
73
+ }
74
+ else if (item.type === 'function_call_output') {
75
+ // Flush any pending assistant message first
76
+ flushPendingAssistant(messages, pendingAssistantMessage, pendingToolCalls, pendingReasoningContent);
77
+ pendingAssistantMessage = null;
78
+ pendingToolCalls = [];
79
+ pendingReasoningContent = undefined;
80
+ messages.push({
81
+ role: 'tool',
82
+ tool_call_id: item.call_id,
83
+ content: item.output || '',
84
+ });
85
+ }
86
+ else if (item.type === 'reasoning') {
87
+ if (!pendingAssistantMessage) {
88
+ pendingAssistantMessage = { role: 'assistant', content: null };
89
+ }
90
+ const summaryTexts = Array.isArray(item.summary)
91
+ ? item.summary.map((s) => s.text || '').filter(Boolean)
92
+ : [];
93
+ if (summaryTexts.length > 0) {
94
+ pendingReasoningContent = summaryTexts.join('\n');
95
+ }
96
+ }
97
+ }
98
+ // Flush any remaining pending assistant message
99
+ flushPendingAssistant(messages, pendingAssistantMessage, pendingToolCalls, pendingReasoningContent);
100
+ }
101
+ // --- Build result ---
102
+ const result = {
103
+ model: body.model,
104
+ messages,
105
+ stream: (_a = body.stream) !== null && _a !== void 0 ? _a : false,
106
+ };
107
+ // --- Parameter mapping ---
108
+ if (body.max_output_tokens !== undefined) {
109
+ if (body.model && (0, effort_js_1.isOSeriesModel)(body.model)) {
110
+ result.max_completion_tokens = body.max_output_tokens;
111
+ }
112
+ else {
113
+ result.max_tokens = body.max_output_tokens;
114
+ }
115
+ }
116
+ if (body.temperature !== undefined)
117
+ result.temperature = body.temperature;
118
+ if (body.top_p !== undefined)
119
+ result.top_p = body.top_p;
120
+ // --- Reasoning effort ---
121
+ if ((_b = body.reasoning) === null || _b === void 0 ? void 0 : _b.effort) {
122
+ result.reasoning_effort = body.reasoning.effort;
123
+ }
124
+ // --- Tools ---
125
+ // 仅转换标准 function 类型工具,过滤掉 OpenAI 私有扩展类型
126
+ // (custom/tool_search/web_search/file_search/code_interpreter 等)
127
+ // 这些非标准类型没有 name 字段,直接转换会导致上游 API 返回参数错误
128
+ const functionTools = (body.tools || []).filter((t) => t.type === 'function');
129
+ if (functionTools.length > 0) {
130
+ result.tools = functionTools.map((tool) => ({
131
+ type: 'function',
132
+ function: {
133
+ name: tool.name,
134
+ description: tool.description || '',
135
+ parameters: tool.parameters || {},
136
+ },
137
+ }));
138
+ }
139
+ // --- Tool choice mapping ---
140
+ if (body.tool_choice !== undefined) {
141
+ result.tool_choice = responsesToCompletionsToolChoice(body.tool_choice);
142
+ }
143
+ // --- Auto-inject stream_options when streaming ---
144
+ if (result.stream) {
145
+ result.stream_options = { include_usage: true };
146
+ }
147
+ return result;
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Helpers
151
+ // ---------------------------------------------------------------------------
152
+ /**
153
+ * Extract text content from a Responses API message item's content array.
154
+ */
155
+ function extractContent(content, textType) {
156
+ if (!content)
157
+ return '';
158
+ if (typeof content === 'string')
159
+ return content;
160
+ if (!Array.isArray(content))
161
+ return '';
162
+ return content
163
+ .filter((part) => part.type === textType || part.type === 'text')
164
+ .map((part) => part.text || '')
165
+ .join('');
166
+ }
167
+ /**
168
+ * Flush a pending assistant message with accumulated tool_calls and reasoning_content.
169
+ */
170
+ function flushPendingAssistant(messages, pendingAssistant, pendingToolCalls, pendingReasoningContent) {
171
+ if (!pendingAssistant && pendingToolCalls.length === 0 && !pendingReasoningContent) {
172
+ return;
173
+ }
174
+ const msg = {
175
+ role: 'assistant',
176
+ content: (pendingAssistant === null || pendingAssistant === void 0 ? void 0 : pendingAssistant.content) || null,
177
+ };
178
+ if (pendingReasoningContent) {
179
+ msg.reasoning_content = pendingReasoningContent;
180
+ }
181
+ if (pendingToolCalls.length > 0) {
182
+ msg.tool_calls = pendingToolCalls;
183
+ // When tool_calls are present but no reasoning_content was provided,
184
+ // inject a placeholder so the receiver can detect tool-use context
185
+ if (!pendingReasoningContent) {
186
+ msg.reasoning_content = 'tool call';
187
+ }
188
+ }
189
+ messages.push(msg);
190
+ }
191
+ /**
192
+ * Map Responses API tool_choice to Chat Completions tool_choice.
193
+ */
194
+ function responsesToCompletionsToolChoice(toolChoice) {
195
+ if (typeof toolChoice === 'string') {
196
+ switch (toolChoice) {
197
+ case 'required': return 'required';
198
+ case 'auto': return 'auto';
199
+ case 'none': return 'none';
200
+ default: return 'auto';
201
+ }
202
+ }
203
+ if (typeof toolChoice === 'object' && toolChoice.type === 'function') {
204
+ return { type: 'function', function: { name: toolChoice.name } };
205
+ }
206
+ return 'auto';
207
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI Chat Completions → OpenAI Responses API response conversion.
4
+ *
5
+ * Converts a Chat Completions response body into an OpenAI Responses API response body.
6
+ * Reasoning content (reasoning_content) is converted to a standard `reasoning` output
7
+ * item following the official Responses API specification.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.completionsToResponsesResponse = completionsToResponsesResponse;
11
+ const stop_reasons_js_1 = require("../../utils/stop-reasons.js");
12
+ const usage_js_1 = require("../../utils/usage.js");
13
+ const id_js_1 = require("../../utils/id.js");
14
+ /**
15
+ * Convert a Chat Completions response to a Responses API response.
16
+ */
17
+ function completionsToResponsesResponse(response) {
18
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
19
+ const choice = (_a = response.choices) === null || _a === void 0 ? void 0 : _a[0];
20
+ if (!choice)
21
+ return response;
22
+ const output = [];
23
+ // reasoning_content -> reasoning output item (official Responses API format)
24
+ if ((_b = choice.message) === null || _b === void 0 ? void 0 : _b.reasoning_content) {
25
+ output.push({
26
+ type: 'reasoning',
27
+ id: (0, id_js_1.generateCallId)().replace('call_', 'rs_'),
28
+ summary: [{ type: 'summary_text', text: choice.message.reasoning_content }],
29
+ });
30
+ }
31
+ // Text content -> message item
32
+ if ((_c = choice.message) === null || _c === void 0 ? void 0 : _c.content) {
33
+ const messageContent = [
34
+ { type: 'output_text', text: choice.message.content, annotations: [] },
35
+ ];
36
+ // Refusal -> add as refusal in message content
37
+ if ((_d = choice.message) === null || _d === void 0 ? void 0 : _d.refusal) {
38
+ messageContent.push({ type: 'refusal', refusal: choice.message.refusal });
39
+ }
40
+ output.push({
41
+ type: 'message',
42
+ status: 'completed',
43
+ role: 'assistant',
44
+ content: messageContent,
45
+ });
46
+ }
47
+ else if ((_e = choice.message) === null || _e === void 0 ? void 0 : _e.refusal) {
48
+ // Message with only refusal, no text content
49
+ output.push({
50
+ type: 'message',
51
+ status: 'completed',
52
+ role: 'assistant',
53
+ content: [
54
+ { type: 'output_text', text: '', annotations: [] },
55
+ { type: 'refusal', refusal: choice.message.refusal },
56
+ ],
57
+ });
58
+ }
59
+ // Tool calls -> function_call items
60
+ if ((_f = choice.message) === null || _f === void 0 ? void 0 : _f.tool_calls) {
61
+ for (const tc of choice.message.tool_calls) {
62
+ output.push({
63
+ type: 'function_call',
64
+ status: 'completed',
65
+ call_id: tc.id,
66
+ name: ((_g = tc.function) === null || _g === void 0 ? void 0 : _g.name) || '',
67
+ arguments: ((_h = tc.function) === null || _h === void 0 ? void 0 : _h.arguments) || '{}',
68
+ });
69
+ }
70
+ }
71
+ // If no message was emitted (edge case: only tool calls), still emit a message
72
+ if (!((_j = choice.message) === null || _j === void 0 ? void 0 : _j.content) && !((_k = choice.message) === null || _k === void 0 ? void 0 : _k.refusal) && !((_l = choice.message) === null || _l === void 0 ? void 0 : _l.tool_calls)) {
73
+ output.push({
74
+ type: 'message',
75
+ status: 'completed',
76
+ role: 'assistant',
77
+ content: [{ type: 'output_text', text: '', annotations: [] }],
78
+ });
79
+ }
80
+ const finishReason = (0, stop_reasons_js_1.completionsToResponsesFinishReason)(choice.finish_reason);
81
+ const status = finishReason === 'incomplete' ? 'incomplete' : 'completed';
82
+ const usage = (0, usage_js_1.completionsToResponsesUsage)(response.usage);
83
+ const result = {
84
+ id: ((_m = response.id) === null || _m === void 0 ? void 0 : _m.startsWith('resp_')) ? response.id : (0, id_js_1.generateResponseId)(),
85
+ object: 'response',
86
+ status,
87
+ output,
88
+ model: response.model,
89
+ usage,
90
+ created_at: response.created || Math.floor(Date.now() / 1000),
91
+ };
92
+ if (status === 'incomplete') {
93
+ result.incomplete_details = { reason: 'max_output_tokens' };
94
+ }
95
+ return result;
96
+ }
@@ -0,0 +1,344 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI Chat Completions SSE → OpenAI Responses API SSE streaming conversion.
4
+ *
5
+ * Stateful converter that translates Chat Completions SSE events into
6
+ * OpenAI Responses API SSE events, following the official Responses API spec.
7
+ *
8
+ * Reasoning content (reasoning_content) is emitted as standard `reasoning`
9
+ * output items with `response.reasoning_summary_text.delta` events.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CompletionsToResponsesConverter = void 0;
13
+ const usage_js_1 = require("../../utils/usage.js");
14
+ const id_js_1 = require("../../utils/id.js");
15
+ const streaming_helpers_js_1 = require("../../utils/streaming-helpers.js");
16
+ /**
17
+ * CompletionsToResponsesConverter: Chat Completions SSE → Responses API SSE
18
+ */
19
+ class CompletionsToResponsesConverter {
20
+ constructor() {
21
+ Object.defineProperty(this, "started", {
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true,
25
+ value: false
26
+ });
27
+ Object.defineProperty(this, "responseId", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: ''
32
+ });
33
+ Object.defineProperty(this, "model", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: ''
38
+ });
39
+ Object.defineProperty(this, "reasoningStarted", {
40
+ enumerable: true,
41
+ configurable: true,
42
+ writable: true,
43
+ value: false
44
+ });
45
+ Object.defineProperty(this, "textStarted", {
46
+ enumerable: true,
47
+ configurable: true,
48
+ writable: true,
49
+ value: false
50
+ });
51
+ Object.defineProperty(this, "reasoningOutputIndex", {
52
+ enumerable: true,
53
+ configurable: true,
54
+ writable: true,
55
+ value: -1
56
+ });
57
+ Object.defineProperty(this, "messageOutputIndex", {
58
+ enumerable: true,
59
+ configurable: true,
60
+ writable: true,
61
+ value: -1
62
+ });
63
+ Object.defineProperty(this, "currentToolCalls", {
64
+ enumerable: true,
65
+ configurable: true,
66
+ writable: true,
67
+ value: new Map()
68
+ });
69
+ Object.defineProperty(this, "pendingReasoningText", {
70
+ enumerable: true,
71
+ configurable: true,
72
+ writable: true,
73
+ value: ''
74
+ });
75
+ Object.defineProperty(this, "accumulatedText", {
76
+ enumerable: true,
77
+ configurable: true,
78
+ writable: true,
79
+ value: ''
80
+ });
81
+ Object.defineProperty(this, "finalized", {
82
+ enumerable: true,
83
+ configurable: true,
84
+ writable: true,
85
+ value: false
86
+ });
87
+ Object.defineProperty(this, "output", {
88
+ enumerable: true,
89
+ configurable: true,
90
+ writable: true,
91
+ value: []
92
+ });
93
+ Object.defineProperty(this, "nextOutputIndex", {
94
+ enumerable: true,
95
+ configurable: true,
96
+ writable: true,
97
+ value: 0
98
+ });
99
+ Object.defineProperty(this, "usage", {
100
+ enumerable: true,
101
+ configurable: true,
102
+ writable: true,
103
+ value: null
104
+ });
105
+ Object.defineProperty(this, "finishReason", {
106
+ enumerable: true,
107
+ configurable: true,
108
+ writable: true,
109
+ value: null
110
+ });
111
+ }
112
+ convertEvent(event) {
113
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
114
+ if (!event.data)
115
+ return [];
116
+ // [DONE] -> trigger finalize
117
+ if (event.data === '[DONE]' || ((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === 'done') {
118
+ return this.flush();
119
+ }
120
+ try {
121
+ const chunk = (0, streaming_helpers_js_1.parseEventData)(event.data);
122
+ const events = [];
123
+ const delta = (_c = (_b = chunk.choices) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.delta;
124
+ const finishReason = (_e = (_d = chunk.choices) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.finish_reason;
125
+ const usage = chunk.usage;
126
+ const chunkId = chunk.id;
127
+ const chunkModel = chunk.model;
128
+ // First chunk -> emit response.created + response.in_progress
129
+ if (!this.started) {
130
+ this.responseId = (chunkId === null || chunkId === void 0 ? void 0 : chunkId.startsWith('resp_')) ? chunkId : (0, id_js_1.generateResponseId)();
131
+ this.model = chunkModel || '';
132
+ events.push(this.makeSSE('response.created', {
133
+ id: this.responseId,
134
+ object: 'response',
135
+ status: 'in_progress',
136
+ model: this.model,
137
+ output: [],
138
+ }));
139
+ events.push(this.makeSSE('response.in_progress', {
140
+ id: this.responseId,
141
+ object: 'response',
142
+ status: 'in_progress',
143
+ model: this.model,
144
+ output: [],
145
+ }));
146
+ this.started = true;
147
+ }
148
+ // --- reasoning_content -> standard reasoning output item ---
149
+ if (delta === null || delta === void 0 ? void 0 : delta.reasoning_content) {
150
+ this.pendingReasoningText += delta.reasoning_content;
151
+ if (!this.reasoningStarted) {
152
+ this.reasoningOutputIndex = this.nextOutputIndex++;
153
+ const rsId = (0, id_js_1.generateCallId)().replace('call_', 'rs_');
154
+ events.push(this.makeSSE('response.output_item.added', {
155
+ output_index: this.reasoningOutputIndex,
156
+ item: { type: 'reasoning', id: rsId },
157
+ }));
158
+ events.push(this.makeSSE('response.reasoning_summary_part.added', {
159
+ output_index: this.reasoningOutputIndex,
160
+ summary_index: 0,
161
+ part: { type: 'summary_text' },
162
+ }));
163
+ this.reasoningStarted = true;
164
+ }
165
+ // Emit using official standard event name
166
+ events.push(this.makeSSE('response.reasoning_summary_text.delta', {
167
+ output_index: this.reasoningOutputIndex,
168
+ summary_index: 0,
169
+ delta: delta.reasoning_content,
170
+ }));
171
+ }
172
+ // --- content (text) ---
173
+ if (delta === null || delta === void 0 ? void 0 : delta.content) {
174
+ this.accumulatedText += delta.content;
175
+ if (!this.textStarted) {
176
+ this.messageOutputIndex = this.nextOutputIndex++;
177
+ events.push(this.makeSSE('response.output_item.added', {
178
+ output_index: this.messageOutputIndex,
179
+ item: { type: 'message', status: 'in_progress', role: 'assistant', content: [] },
180
+ }));
181
+ events.push(this.makeSSE('response.content_part.added', {
182
+ output_index: this.messageOutputIndex,
183
+ content_index: 0,
184
+ part: { type: 'output_text', text: '', annotations: [] },
185
+ }));
186
+ this.textStarted = true;
187
+ }
188
+ events.push(this.makeSSE('response.output_text.delta', {
189
+ output_index: this.messageOutputIndex,
190
+ content_index: 0,
191
+ delta: delta.content,
192
+ }));
193
+ }
194
+ // --- tool_calls ---
195
+ if (Array.isArray(delta === null || delta === void 0 ? void 0 : delta.tool_calls)) {
196
+ for (const tc of delta.tool_calls) {
197
+ const toolIdx = (_f = tc.index) !== null && _f !== void 0 ? _f : 0;
198
+ const existing = this.currentToolCalls.get(toolIdx);
199
+ if (!existing) {
200
+ // New tool call
201
+ const tcId = tc.id || (0, id_js_1.generateCallId)();
202
+ const tcName = ((_g = tc.function) === null || _g === void 0 ? void 0 : _g.name) || '';
203
+ const tcOutputIndex = this.nextOutputIndex++;
204
+ this.currentToolCalls.set(toolIdx, {
205
+ id: tcId,
206
+ name: tcName,
207
+ argumentsText: '',
208
+ outputIndex: tcOutputIndex,
209
+ });
210
+ events.push(this.makeSSE('response.output_item.added', {
211
+ output_index: tcOutputIndex,
212
+ item: {
213
+ type: 'function_call',
214
+ status: 'in_progress',
215
+ call_id: tcId,
216
+ name: tcName,
217
+ arguments: '',
218
+ },
219
+ }));
220
+ }
221
+ // Arguments fragment
222
+ const argsFragment = (0, streaming_helpers_js_1.normalizeToolArgumentsFragment)((_h = tc.function) === null || _h === void 0 ? void 0 : _h.arguments);
223
+ if (argsFragment) {
224
+ const current = this.currentToolCalls.get(toolIdx);
225
+ if (current) {
226
+ current.argumentsText += argsFragment;
227
+ }
228
+ events.push(this.makeSSE('response.function_call_arguments.delta', {
229
+ output_index: (_j = current === null || current === void 0 ? void 0 : current.outputIndex) !== null && _j !== void 0 ? _j : this.output.length,
230
+ call_id: current === null || current === void 0 ? void 0 : current.id,
231
+ delta: argsFragment,
232
+ }));
233
+ }
234
+ }
235
+ }
236
+ // --- Finish reason ---
237
+ if (finishReason) {
238
+ this.finishReason = finishReason;
239
+ }
240
+ // --- Usage ---
241
+ if (usage) {
242
+ this.usage = usage;
243
+ }
244
+ return events;
245
+ }
246
+ catch (_k) {
247
+ return [event];
248
+ }
249
+ }
250
+ flush() {
251
+ if (this.finalized)
252
+ return [];
253
+ this.finalized = true;
254
+ const events = [];
255
+ // Finalize reasoning
256
+ if (this.reasoningStarted) {
257
+ events.push(this.makeSSE('response.reasoning.done', {
258
+ output_index: this.reasoningOutputIndex,
259
+ summary: [{ type: 'summary_text', text: this.pendingReasoningText }],
260
+ }));
261
+ events.push(this.makeSSE('response.reasoning_summary_part.done', {
262
+ output_index: this.reasoningOutputIndex,
263
+ }));
264
+ events.push(this.makeSSE('response.output_item.done', {
265
+ output_index: this.reasoningOutputIndex,
266
+ item: { type: 'reasoning' },
267
+ }));
268
+ this.output.push({
269
+ type: 'reasoning',
270
+ id: (0, id_js_1.generateCallId)().replace('call_', 'rs_'),
271
+ summary: [{ type: 'summary_text', text: this.pendingReasoningText }],
272
+ });
273
+ }
274
+ // Finalize text
275
+ if (this.textStarted) {
276
+ events.push(this.makeSSE('response.output_text.done', {
277
+ output_index: this.messageOutputIndex,
278
+ content_index: 0,
279
+ text: '',
280
+ }));
281
+ events.push(this.makeSSE('response.content_part.done', {
282
+ output_index: this.messageOutputIndex,
283
+ content_index: 0,
284
+ part: { type: 'output_text', text: '', annotations: [] },
285
+ }));
286
+ this.output.push({
287
+ type: 'message',
288
+ status: 'completed',
289
+ role: 'assistant',
290
+ content: [{ type: 'output_text', text: this.accumulatedText }],
291
+ });
292
+ events.push(this.makeSSE('response.output_item.done', {
293
+ output_index: this.messageOutputIndex,
294
+ item: { type: 'message', status: 'completed', role: 'assistant' },
295
+ }));
296
+ }
297
+ // Finalize tool calls
298
+ for (const [, tc] of this.currentToolCalls) {
299
+ events.push(this.makeSSE('response.function_call_arguments.done', {
300
+ output_index: tc.outputIndex,
301
+ call_id: tc.id,
302
+ }));
303
+ events.push(this.makeSSE('response.output_item.done', {
304
+ output_index: tc.outputIndex,
305
+ item: {
306
+ type: 'function_call',
307
+ status: 'completed',
308
+ call_id: tc.id,
309
+ name: tc.name,
310
+ arguments: tc.argumentsText,
311
+ },
312
+ }));
313
+ this.output.push({
314
+ type: 'function_call',
315
+ status: 'completed',
316
+ call_id: tc.id,
317
+ name: tc.name,
318
+ arguments: tc.argumentsText,
319
+ });
320
+ }
321
+ // Build full response object
322
+ const status = this.finishReason === 'length' ? 'incomplete' : 'completed';
323
+ const responseObj = {
324
+ id: this.responseId,
325
+ object: 'response',
326
+ status,
327
+ output: this.output,
328
+ model: this.model,
329
+ usage: this.usage ? (0, usage_js_1.completionsToResponsesUsage)(this.usage) : {},
330
+ created_at: Math.floor(Date.now() / 1000),
331
+ metadata: {},
332
+ };
333
+ if (status === 'incomplete') {
334
+ responseObj.incomplete_details = { reason: 'max_output_tokens' };
335
+ }
336
+ events.push(this.makeSSE('response.completed', { response: responseObj }));
337
+ events.push({ data: '[DONE]', event: '' });
338
+ return events;
339
+ }
340
+ makeSSE(eventName, data) {
341
+ return { event: eventName, data };
342
+ }
343
+ }
344
+ exports.CompletionsToResponsesConverter = CompletionsToResponsesConverter;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /**
3
+ * Responses API → Gemini composite request conversion.
4
+ *
5
+ * Composes: responses → completions → gemini
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.responsesToGeminiRequest = responsesToGeminiRequest;
9
+ const request_js_1 = require("../responses-completions/request.js");
10
+ const request_js_2 = require("../completions-gemini/request.js");
11
+ /**
12
+ * Convert Responses API request to Gemini request.
13
+ * Path: responses → completions → gemini
14
+ */
15
+ function responsesToGeminiRequest(body) {
16
+ const completionsBody = (0, request_js_1.responsesToCompletions)(body);
17
+ return (0, request_js_2.completionsToGemini)(completionsBody);
18
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /**
3
+ * Gemini → Responses API composite response conversion.
4
+ *
5
+ * Composes: gemini → completions → responses
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.geminiToResponsesResponse = geminiToResponsesResponse;
9
+ const response_js_1 = require("../completions-gemini/response.js");
10
+ const response_js_2 = require("../responses-completions/response.js");
11
+ /**
12
+ * Convert Gemini response to Responses API response.
13
+ * Path: gemini → completions → responses
14
+ */
15
+ function geminiToResponsesResponse(response) {
16
+ const completionsResponse = (0, response_js_1.geminiToCompletionsResponse)(response);
17
+ return (0, response_js_2.completionsToResponsesResponse)(completionsResponse);
18
+ }