@mariozechner/pi-ai 0.5.19 → 0.5.21

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.
@@ -1,5 +1,6 @@
1
1
  import OpenAI from "openai";
2
2
  import { calculateCost } from "../models.js";
3
+ import { transformMessages } from "./utils.js";
3
4
  export class OpenAIResponsesLLM {
4
5
  client;
5
6
  modelInfo;
@@ -16,7 +17,21 @@ export class OpenAIResponsesLLM {
16
17
  getModel() {
17
18
  return this.modelInfo;
18
19
  }
19
- async complete(request, options) {
20
+ async generate(request, options) {
21
+ const output = {
22
+ role: "assistant",
23
+ content: [],
24
+ provider: this.modelInfo.provider,
25
+ model: this.modelInfo.id,
26
+ usage: {
27
+ input: 0,
28
+ output: 0,
29
+ cacheRead: 0,
30
+ cacheWrite: 0,
31
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
32
+ },
33
+ stopReason: "stop",
34
+ };
20
35
  try {
21
36
  const input = this.convertToInput(request.messages, request.systemPrompt);
22
37
  const params = {
@@ -45,65 +60,108 @@ export class OpenAIResponsesLLM {
45
60
  signal: options?.signal,
46
61
  });
47
62
  options?.onEvent?.({ type: "start", model: this.modelInfo.id, provider: this.modelInfo.provider });
48
- const outputItems = []; // any for function_call items
49
- let currentTextAccum = ""; // For delta accumulation
50
- let currentThinkingAccum = ""; // For delta accumulation
51
- let usage = {
52
- input: 0,
53
- output: 0,
54
- cacheRead: 0,
55
- cacheWrite: 0,
56
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
57
- };
58
- let stopReason = "stop";
63
+ const outputItems = [];
64
+ let currentItem = null;
59
65
  for await (const event of stream) {
60
66
  // Handle output item start
61
67
  if (event.type === "response.output_item.added") {
62
68
  const item = event.item;
63
69
  if (item.type === "reasoning") {
64
70
  options?.onEvent?.({ type: "thinking_start" });
65
- currentThinkingAccum = "";
71
+ outputItems.push(item);
72
+ currentItem = item;
66
73
  }
67
74
  else if (item.type === "message") {
68
75
  options?.onEvent?.({ type: "text_start" });
69
- currentTextAccum = "";
76
+ outputItems.push(item);
77
+ currentItem = item;
70
78
  }
71
79
  }
72
80
  // Handle reasoning summary deltas
81
+ else if (event.type === "response.reasoning_summary_part.added") {
82
+ if (currentItem && currentItem.type === "reasoning") {
83
+ currentItem.summary = currentItem.summary || [];
84
+ currentItem.summary.push(event.part);
85
+ }
86
+ }
73
87
  else if (event.type === "response.reasoning_summary_text.delta") {
74
- const delta = event.delta;
75
- currentThinkingAccum += delta;
76
- options?.onEvent?.({ type: "thinking_delta", content: currentThinkingAccum, delta });
88
+ if (currentItem && currentItem.type === "reasoning") {
89
+ currentItem.summary = currentItem.summary || [];
90
+ const lastPart = currentItem.summary[currentItem.summary.length - 1];
91
+ if (lastPart) {
92
+ lastPart.text += event.delta;
93
+ options?.onEvent?.({
94
+ type: "thinking_delta",
95
+ content: currentItem.summary.map((s) => s.text).join("\n\n"),
96
+ delta: event.delta,
97
+ });
98
+ }
99
+ }
77
100
  }
78
101
  // Add a new line between summary parts (hack...)
79
102
  else if (event.type === "response.reasoning_summary_part.done") {
80
- currentThinkingAccum += "\n\n";
81
- options?.onEvent?.({ type: "thinking_delta", content: currentThinkingAccum, delta: "\n\n" });
103
+ if (currentItem && currentItem.type === "reasoning") {
104
+ currentItem.summary = currentItem.summary || [];
105
+ const lastPart = currentItem.summary[currentItem.summary.length - 1];
106
+ if (lastPart) {
107
+ lastPart.text += "\n\n";
108
+ options?.onEvent?.({
109
+ type: "thinking_delta",
110
+ content: currentItem.summary.map((s) => s.text).join("\n\n"),
111
+ delta: "\n\n",
112
+ });
113
+ }
114
+ }
82
115
  }
83
116
  // Handle text output deltas
117
+ else if (event.type === "response.content_part.added") {
118
+ if (currentItem && currentItem.type === "message") {
119
+ currentItem.content = currentItem.content || [];
120
+ currentItem.content.push(event.part);
121
+ }
122
+ }
84
123
  else if (event.type === "response.output_text.delta") {
85
- const delta = event.delta;
86
- currentTextAccum += delta;
87
- options?.onEvent?.({ type: "text_delta", content: currentTextAccum, delta });
124
+ if (currentItem && currentItem.type === "message") {
125
+ const lastPart = currentItem.content[currentItem.content.length - 1];
126
+ if (lastPart && lastPart.type === "output_text") {
127
+ lastPart.text += event.delta;
128
+ options?.onEvent?.({
129
+ type: "text_delta",
130
+ content: currentItem.content
131
+ .map((c) => (c.type === "output_text" ? c.text : c.refusal))
132
+ .join(""),
133
+ delta: event.delta,
134
+ });
135
+ }
136
+ }
88
137
  }
89
- // Handle refusal output deltas
90
138
  else if (event.type === "response.refusal.delta") {
91
- const delta = event.delta;
92
- currentTextAccum += delta;
93
- options?.onEvent?.({ type: "text_delta", content: currentTextAccum, delta });
139
+ if (currentItem && currentItem.type === "message") {
140
+ const lastPart = currentItem.content[currentItem.content.length - 1];
141
+ if (lastPart && lastPart.type === "refusal") {
142
+ lastPart.refusal += event.delta;
143
+ options?.onEvent?.({
144
+ type: "text_delta",
145
+ content: currentItem.content
146
+ .map((c) => (c.type === "output_text" ? c.text : c.refusal))
147
+ .join(""),
148
+ delta: event.delta,
149
+ });
150
+ }
151
+ }
94
152
  }
95
153
  // Handle output item completion
96
154
  else if (event.type === "response.output_item.done") {
97
155
  const item = event.item;
98
156
  if (item.type === "reasoning") {
157
+ outputItems[outputItems.length - 1] = item; // Update with final item
99
158
  const thinkingContent = item.summary?.map((s) => s.text).join("\n\n") || "";
100
159
  options?.onEvent?.({ type: "thinking_end", content: thinkingContent });
101
- outputItems.push(item);
102
160
  }
103
161
  else if (item.type === "message") {
162
+ outputItems[outputItems.length - 1] = item; // Update with final item
104
163
  const textContent = item.content.map((c) => (c.type === "output_text" ? c.text : c.refusal)).join("");
105
164
  options?.onEvent?.({ type: "text_end", content: textContent });
106
- outputItems.push(item);
107
165
  }
108
166
  else if (item.type === "function_call") {
109
167
  const toolCall = {
@@ -120,7 +178,7 @@ export class OpenAIResponsesLLM {
120
178
  else if (event.type === "response.completed") {
121
179
  const response = event.response;
122
180
  if (response?.usage) {
123
- usage = {
181
+ output.usage = {
124
182
  input: response.usage.input_tokens || 0,
125
183
  output: response.usage.output_tokens || 0,
126
184
  cacheRead: response.usage.input_tokens_details?.cached_tokens || 0,
@@ -128,59 +186,45 @@ export class OpenAIResponsesLLM {
128
186
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
129
187
  };
130
188
  }
189
+ calculateCost(this.modelInfo, output.usage);
131
190
  // Map status to stop reason
132
- stopReason = this.mapStopReason(response?.status);
191
+ output.stopReason = this.mapStopReason(response?.status);
192
+ if (outputItems.some((b) => b.type === "function_call") && output.stopReason === "stop") {
193
+ output.stopReason = "toolUse";
194
+ }
133
195
  }
134
196
  // Handle errors
135
197
  else if (event.type === "error") {
136
- const errorOutput = {
137
- role: "assistant",
138
- content: [],
139
- provider: this.modelInfo.provider,
140
- model: this.modelInfo.id,
141
- usage,
142
- stopReason: "error",
143
- error: `Code ${event.code}: ${event.message}` || "Unknown error",
144
- };
145
- options?.onEvent?.({ type: "error", error: errorOutput.error || "Unknown error" });
146
- return errorOutput;
198
+ output.stopReason = "error";
199
+ output.error = `Code ${event.code}: ${event.message}` || "Unknown error";
200
+ options?.onEvent?.({ type: "error", error: output.error });
201
+ return output;
147
202
  }
148
203
  else if (event.type === "response.failed") {
149
- const errorOutput = {
150
- role: "assistant",
151
- content: [],
152
- provider: this.modelInfo.provider,
153
- model: this.modelInfo.id,
154
- usage,
155
- stopReason: "error",
156
- error: "Unknown error",
157
- };
158
- options?.onEvent?.({ type: "error", error: errorOutput.error || "Unknown error" });
159
- return errorOutput;
204
+ output.stopReason = "error";
205
+ output.error = "Unknown error";
206
+ options?.onEvent?.({ type: "error", error: output.error });
207
+ return output;
160
208
  }
161
209
  }
162
- if (options?.signal?.aborted) {
163
- throw new Error("Request was aborted");
164
- }
165
210
  // Convert output items to blocks
166
- const blocks = [];
167
211
  for (const item of outputItems) {
168
212
  if (item.type === "reasoning") {
169
- blocks.push({
213
+ output.content.push({
170
214
  type: "thinking",
171
215
  thinking: item.summary?.map((s) => s.text).join("\n\n") || "",
172
216
  thinkingSignature: JSON.stringify(item), // Full item for resubmission
173
217
  });
174
218
  }
175
219
  else if (item.type === "message") {
176
- blocks.push({
220
+ output.content.push({
177
221
  type: "text",
178
222
  text: item.content.map((c) => (c.type === "output_text" ? c.text : c.refusal)).join(""),
179
223
  textSignature: item.id, // ID for resubmission
180
224
  });
181
225
  }
182
226
  else if (item.type === "function_call") {
183
- blocks.push({
227
+ output.content.push({
184
228
  type: "toolCall",
185
229
  id: item.call_id + "|" + item.id,
186
230
  name: item.name,
@@ -188,44 +232,23 @@ export class OpenAIResponsesLLM {
188
232
  });
189
233
  }
190
234
  }
191
- // Check if we have tool calls for stop reason
192
- if (blocks.some((b) => b.type === "toolCall") && stopReason === "stop") {
193
- stopReason = "toolUse";
235
+ if (options?.signal?.aborted) {
236
+ throw new Error("Request was aborted");
194
237
  }
195
- calculateCost(this.modelInfo, usage);
196
- const output = {
197
- role: "assistant",
198
- content: blocks,
199
- provider: this.modelInfo.provider,
200
- model: this.modelInfo.id,
201
- usage,
202
- stopReason,
203
- };
204
238
  options?.onEvent?.({ type: "done", reason: output.stopReason, message: output });
205
239
  return output;
206
240
  }
207
241
  catch (error) {
208
- const output = {
209
- role: "assistant",
210
- content: [],
211
- provider: this.modelInfo.provider,
212
- model: this.modelInfo.id,
213
- usage: {
214
- input: 0,
215
- output: 0,
216
- cacheRead: 0,
217
- cacheWrite: 0,
218
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
219
- },
220
- stopReason: "error",
221
- error: error instanceof Error ? error.message : String(error),
222
- };
223
- options?.onEvent?.({ type: "error", error: output.error || "Unknown error" });
242
+ output.stopReason = "error";
243
+ output.error = error instanceof Error ? error.message : JSON.stringify(error);
244
+ options?.onEvent?.({ type: "error", error: output.error });
224
245
  return output;
225
246
  }
226
247
  }
227
248
  convertToInput(messages, systemPrompt) {
228
249
  const input = [];
250
+ // Transform messages for cross-provider compatibility
251
+ const transformedMessages = transformMessages(messages, this.modelInfo);
229
252
  // Add system prompt if provided
230
253
  if (systemPrompt) {
231
254
  const role = this.modelInfo?.reasoning ? "developer" : "system";
@@ -235,7 +258,7 @@ export class OpenAIResponsesLLM {
235
258
  });
236
259
  }
237
260
  // Convert messages
238
- for (const msg of messages) {
261
+ for (const msg of transformedMessages) {
239
262
  if (msg.role === "user") {
240
263
  // Handle both string and array content
241
264
  if (typeof msg.content === "string") {
@@ -272,7 +295,8 @@ export class OpenAIResponsesLLM {
272
295
  // Process content blocks in order
273
296
  const output = [];
274
297
  for (const block of msg.content) {
275
- if (block.type === "thinking") {
298
+ // Do not submit thinking blocks if the completion had an error (i.e. abort)
299
+ if (block.type === "thinking" && msg.stopReason !== "error") {
276
300
  // Push the full reasoning item(s) from signature
277
301
  if (block.thinkingSignature) {
278
302
  const reasoningItem = JSON.parse(block.thinkingSignature);
@@ -288,8 +312,9 @@ export class OpenAIResponsesLLM {
288
312
  status: "completed",
289
313
  id: textBlock.textSignature || "msg_" + Math.random().toString(36).substring(2, 15),
290
314
  });
315
+ // Do not submit thinking blocks if the completion had an error (i.e. abort)
291
316
  }
292
- else if (block.type === "toolCall") {
317
+ else if (block.type === "toolCall" && msg.stopReason !== "error") {
293
318
  const toolCall = block;
294
319
  output.push({
295
320
  type: "function_call",
@@ -1 +1 @@
1
- {"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../../src/providers/openai-responses.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenAI from \"openai\";\nimport type {\n\tTool as OpenAITool,\n\tResponseCreateParamsStreaming,\n\tResponseFunctionToolCall,\n\tResponseInput,\n\tResponseInputContent,\n\tResponseInputImage,\n\tResponseInputText,\n\tResponseOutputMessage,\n\tResponseReasoningItem,\n} from \"openai/resources/responses/responses.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tLLM,\n\tLLMOptions,\n\tMessage,\n\tModel,\n\tStopReason,\n\tTextContent,\n\tTool,\n\tToolCall,\n\tUsage,\n} from \"../types.js\";\n\nexport interface OpenAIResponsesLLMOptions extends LLMOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\";\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n}\n\nexport class OpenAIResponsesLLM implements LLM<OpenAIResponsesLLMOptions> {\n\tprivate client: OpenAI;\n\tprivate modelInfo: Model;\n\n\tconstructor(model: Model, apiKey?: string) {\n\t\tif (!apiKey) {\n\t\t\tif (!process.env.OPENAI_API_KEY) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"OpenAI API key is required. Set OPENAI_API_KEY environment variable or pass it as an argument.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tapiKey = process.env.OPENAI_API_KEY;\n\t\t}\n\t\tthis.client = new OpenAI({ apiKey, baseURL: model.baseUrl, dangerouslyAllowBrowser: true });\n\t\tthis.modelInfo = model;\n\t}\n\n\tgetModel(): Model {\n\t\treturn this.modelInfo;\n\t}\n\n\tasync complete(request: Context, options?: OpenAIResponsesLLMOptions): Promise<AssistantMessage> {\n\t\ttry {\n\t\t\tconst input = this.convertToInput(request.messages, request.systemPrompt);\n\n\t\t\tconst params: ResponseCreateParamsStreaming = {\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tinput,\n\t\t\t\tstream: true,\n\t\t\t};\n\n\t\t\tif (options?.maxTokens) {\n\t\t\t\tparams.max_output_tokens = options?.maxTokens;\n\t\t\t}\n\n\t\t\tif (options?.temperature !== undefined) {\n\t\t\t\tparams.temperature = options?.temperature;\n\t\t\t}\n\n\t\t\tif (request.tools) {\n\t\t\t\tparams.tools = this.convertTools(request.tools);\n\t\t\t}\n\n\t\t\t// Add reasoning options for models that support it\n\t\t\tif (this.modelInfo?.reasoning && (options?.reasoningEffort || options?.reasoningSummary)) {\n\t\t\t\tparams.reasoning = {\n\t\t\t\t\teffort: options?.reasoningEffort || \"medium\",\n\t\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t\t};\n\t\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t\t}\n\n\t\t\tconst stream = await this.client.responses.create(params, {\n\t\t\t\tsignal: options?.signal,\n\t\t\t});\n\n\t\t\toptions?.onEvent?.({ type: \"start\", model: this.modelInfo.id, provider: this.modelInfo.provider });\n\n\t\t\tconst outputItems: (ResponseReasoningItem | ResponseOutputMessage | ResponseFunctionToolCall)[] = []; // any for function_call items\n\t\t\tlet currentTextAccum = \"\"; // For delta accumulation\n\t\t\tlet currentThinkingAccum = \"\"; // For delta accumulation\n\t\t\tlet usage: Usage = {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t};\n\t\t\tlet stopReason: StopReason = \"stop\";\n\n\t\t\tfor await (const event of stream) {\n\t\t\t\t// Handle output item start\n\t\t\t\tif (event.type === \"response.output_item.added\") {\n\t\t\t\t\tconst item = event.item;\n\t\t\t\t\tif (item.type === \"reasoning\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_start\" });\n\t\t\t\t\t\tcurrentThinkingAccum = \"\";\n\t\t\t\t\t} else if (item.type === \"message\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_start\" });\n\t\t\t\t\t\tcurrentTextAccum = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Handle reasoning summary deltas\n\t\t\t\telse if (event.type === \"response.reasoning_summary_text.delta\") {\n\t\t\t\t\tconst delta = event.delta;\n\t\t\t\t\tcurrentThinkingAccum += delta;\n\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_delta\", content: currentThinkingAccum, delta });\n\t\t\t\t}\n\t\t\t\t// Add a new line between summary parts (hack...)\n\t\t\t\telse if (event.type === \"response.reasoning_summary_part.done\") {\n\t\t\t\t\tcurrentThinkingAccum += \"\\n\\n\";\n\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_delta\", content: currentThinkingAccum, delta: \"\\n\\n\" });\n\t\t\t\t}\n\t\t\t\t// Handle text output deltas\n\t\t\t\telse if (event.type === \"response.output_text.delta\") {\n\t\t\t\t\tconst delta = event.delta;\n\t\t\t\t\tcurrentTextAccum += delta;\n\t\t\t\t\toptions?.onEvent?.({ type: \"text_delta\", content: currentTextAccum, delta });\n\t\t\t\t}\n\t\t\t\t// Handle refusal output deltas\n\t\t\t\telse if (event.type === \"response.refusal.delta\") {\n\t\t\t\t\tconst delta = event.delta;\n\t\t\t\t\tcurrentTextAccum += delta;\n\t\t\t\t\toptions?.onEvent?.({ type: \"text_delta\", content: currentTextAccum, delta });\n\t\t\t\t}\n\t\t\t\t// Handle output item completion\n\t\t\t\telse if (event.type === \"response.output_item.done\") {\n\t\t\t\t\tconst item = event.item;\n\n\t\t\t\t\tif (item.type === \"reasoning\") {\n\t\t\t\t\t\tconst thinkingContent = item.summary?.map((s: any) => s.text).join(\"\\n\\n\") || \"\";\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_end\", content: thinkingContent });\n\t\t\t\t\t\toutputItems.push(item);\n\t\t\t\t\t} else if (item.type === \"message\") {\n\t\t\t\t\t\tconst textContent = item.content.map((c) => (c.type === \"output_text\" ? c.text : c.refusal)).join(\"\");\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_end\", content: textContent });\n\t\t\t\t\t\toutputItems.push(item);\n\t\t\t\t\t} else if (item.type === \"function_call\") {\n\t\t\t\t\t\tconst toolCall: ToolCall = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: item.call_id + \"|\" + item.id,\n\t\t\t\t\t\t\tname: item.name,\n\t\t\t\t\t\t\targuments: JSON.parse(item.arguments),\n\t\t\t\t\t\t};\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"toolCall\", toolCall });\n\t\t\t\t\t\toutputItems.push(item);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Handle completion\n\t\t\t\telse if (event.type === \"response.completed\") {\n\t\t\t\t\tconst response = event.response;\n\t\t\t\t\tif (response?.usage) {\n\t\t\t\t\t\tusage = {\n\t\t\t\t\t\t\tinput: response.usage.input_tokens || 0,\n\t\t\t\t\t\t\toutput: response.usage.output_tokens || 0,\n\t\t\t\t\t\t\tcacheRead: response.usage.input_tokens_details?.cached_tokens || 0,\n\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Map status to stop reason\n\t\t\t\t\tstopReason = this.mapStopReason(response?.status);\n\t\t\t\t}\n\t\t\t\t// Handle errors\n\t\t\t\telse if (event.type === \"error\") {\n\t\t\t\t\tconst errorOutput = {\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [],\n\t\t\t\t\t\tprovider: this.modelInfo.provider,\n\t\t\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t\tstopReason: \"error\",\n\t\t\t\t\t\terror: `Code ${event.code}: ${event.message}` || \"Unknown error\",\n\t\t\t\t\t} satisfies AssistantMessage;\n\t\t\t\t\toptions?.onEvent?.({ type: \"error\", error: errorOutput.error || \"Unknown error\" });\n\t\t\t\t\treturn errorOutput;\n\t\t\t\t} else if (event.type === \"response.failed\") {\n\t\t\t\t\tconst errorOutput = {\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [],\n\t\t\t\t\t\tprovider: this.modelInfo.provider,\n\t\t\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t\tstopReason: \"error\",\n\t\t\t\t\t\terror: \"Unknown error\",\n\t\t\t\t\t} satisfies AssistantMessage;\n\t\t\t\t\toptions?.onEvent?.({ type: \"error\", error: errorOutput.error || \"Unknown error\" });\n\t\t\t\t\treturn errorOutput;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\t// Convert output items to blocks\n\t\t\tconst blocks: AssistantMessage[\"content\"] = [];\n\n\t\t\tfor (const item of outputItems) {\n\t\t\t\tif (item.type === \"reasoning\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\tthinking: item.summary?.map((s: any) => s.text).join(\"\\n\\n\") || \"\",\n\t\t\t\t\t\tthinkingSignature: JSON.stringify(item), // Full item for resubmission\n\t\t\t\t\t});\n\t\t\t\t} else if (item.type === \"message\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: item.content.map((c) => (c.type === \"output_text\" ? c.text : c.refusal)).join(\"\"),\n\t\t\t\t\t\ttextSignature: item.id, // ID for resubmission\n\t\t\t\t\t});\n\t\t\t\t} else if (item.type === \"function_call\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\tid: item.call_id + \"|\" + item.id,\n\t\t\t\t\t\tname: item.name,\n\t\t\t\t\t\targuments: JSON.parse(item.arguments),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check if we have tool calls for stop reason\n\t\t\tif (blocks.some((b) => b.type === \"toolCall\") && stopReason === \"stop\") {\n\t\t\t\tstopReason = \"toolUse\";\n\t\t\t}\n\n\t\t\tcalculateCost(this.modelInfo, usage);\n\n\t\t\tconst output = {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: blocks,\n\t\t\t\tprovider: this.modelInfo.provider,\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tusage,\n\t\t\t\tstopReason,\n\t\t\t} satisfies AssistantMessage;\n\t\t\toptions?.onEvent?.({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\treturn output;\n\t\t} catch (error) {\n\t\t\tconst output = {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: [],\n\t\t\t\tprovider: this.modelInfo.provider,\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tusage: {\n\t\t\t\t\tinput: 0,\n\t\t\t\t\toutput: 0,\n\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t\t},\n\t\t\t\tstopReason: \"error\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t} satisfies AssistantMessage;\n\t\t\toptions?.onEvent?.({ type: \"error\", error: output.error || \"Unknown error\" });\n\t\t\treturn output;\n\t\t}\n\t}\n\n\tprivate convertToInput(messages: Message[], systemPrompt?: string): ResponseInput {\n\t\tconst input: ResponseInput = [];\n\n\t\t// Add system prompt if provided\n\t\tif (systemPrompt) {\n\t\t\tconst role = this.modelInfo?.reasoning ? \"developer\" : \"system\";\n\t\t\tinput.push({\n\t\t\t\trole,\n\t\t\t\tcontent: systemPrompt,\n\t\t\t});\n\t\t}\n\n\t\t// Convert messages\n\t\tfor (const msg of messages) {\n\t\t\tif (msg.role === \"user\") {\n\t\t\t\t// Handle both string and array content\n\t\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\t\tinput.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"input_text\", text: msg.content }],\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Convert array content to OpenAI Responses format\n\t\t\t\t\tconst content: ResponseInputContent[] = msg.content.map((item): ResponseInputContent => {\n\t\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"input_text\",\n\t\t\t\t\t\t\t\ttext: item.text,\n\t\t\t\t\t\t\t} satisfies ResponseInputText;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Image content - OpenAI Responses uses data URLs\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"input_image\",\n\t\t\t\t\t\t\t\tdetail: \"auto\",\n\t\t\t\t\t\t\t\timage_url: `data:${item.mimeType};base64,${item.data}`,\n\t\t\t\t\t\t\t} satisfies ResponseInputImage;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tinput.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (msg.role === \"assistant\") {\n\t\t\t\t// Process content blocks in order\n\t\t\t\tconst output: ResponseInput = [];\n\n\t\t\t\tfor (const block of msg.content) {\n\t\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\t\t// Push the full reasoning item(s) from signature\n\t\t\t\t\t\tif (block.thinkingSignature) {\n\t\t\t\t\t\t\tconst reasoningItem = JSON.parse(block.thinkingSignature);\n\t\t\t\t\t\t\toutput.push(reasoningItem);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (block.type === \"text\") {\n\t\t\t\t\t\tconst textBlock = block as TextContent;\n\t\t\t\t\t\toutput.push({\n\t\t\t\t\t\t\ttype: \"message\",\n\t\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\t\tcontent: [{ type: \"output_text\", text: textBlock.text, annotations: [] }],\n\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\tid: textBlock.textSignature || \"msg_\" + Math.random().toString(36).substring(2, 15),\n\t\t\t\t\t\t} satisfies ResponseOutputMessage);\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\tconst toolCall = block as ToolCall;\n\t\t\t\t\t\toutput.push({\n\t\t\t\t\t\t\ttype: \"function_call\",\n\t\t\t\t\t\t\tid: toolCall.id.split(\"|\")[1], // Extract original ID\n\t\t\t\t\t\t\tcall_id: toolCall.id.split(\"|\")[0], // Extract call session ID\n\t\t\t\t\t\t\tname: toolCall.name,\n\t\t\t\t\t\t\targuments: JSON.stringify(toolCall.arguments),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Add all output items to input\n\t\t\t\tinput.push(...output);\n\t\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t\t// Tool results are sent as function_call_output\n\t\t\t\tinput.push({\n\t\t\t\t\ttype: \"function_call_output\",\n\t\t\t\t\tcall_id: msg.toolCallId.split(\"|\")[0], // Extract call session ID\n\t\t\t\t\toutput: msg.content,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn input;\n\t}\n\n\tprivate convertTools(tools: Tool[]): OpenAITool[] {\n\t\treturn tools.map((tool) => ({\n\t\t\ttype: \"function\",\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tparameters: tool.parameters,\n\t\t\tstrict: null,\n\t\t}));\n\t}\n\n\tprivate mapStopReason(status: string | undefined): StopReason {\n\t\tswitch (status) {\n\t\t\tcase \"completed\":\n\t\t\t\treturn \"stop\";\n\t\t\tcase \"incomplete\":\n\t\t\t\treturn \"length\";\n\t\t\tcase \"failed\":\n\t\t\tcase \"cancelled\":\n\t\t\t\treturn \"error\";\n\t\t\tdefault:\n\t\t\t\treturn \"stop\";\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../../src/providers/openai-responses.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenAI from \"openai\";\nimport type {\n\tTool as OpenAITool,\n\tResponseCreateParamsStreaming,\n\tResponseFunctionToolCall,\n\tResponseInput,\n\tResponseInputContent,\n\tResponseInputImage,\n\tResponseInputText,\n\tResponseOutputMessage,\n\tResponseReasoningItem,\n} from \"openai/resources/responses/responses.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tLLM,\n\tLLMOptions,\n\tMessage,\n\tModel,\n\tStopReason,\n\tTextContent,\n\tTool,\n\tToolCall,\n} from \"../types.js\";\nimport { transformMessages } from \"./utils.js\";\n\nexport interface OpenAIResponsesLLMOptions extends LLMOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\";\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n}\n\nexport class OpenAIResponsesLLM implements LLM<OpenAIResponsesLLMOptions> {\n\tprivate client: OpenAI;\n\tprivate modelInfo: Model;\n\n\tconstructor(model: Model, apiKey?: string) {\n\t\tif (!apiKey) {\n\t\t\tif (!process.env.OPENAI_API_KEY) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"OpenAI API key is required. Set OPENAI_API_KEY environment variable or pass it as an argument.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tapiKey = process.env.OPENAI_API_KEY;\n\t\t}\n\t\tthis.client = new OpenAI({ apiKey, baseURL: model.baseUrl, dangerouslyAllowBrowser: true });\n\t\tthis.modelInfo = model;\n\t}\n\n\tgetModel(): Model {\n\t\treturn this.modelInfo;\n\t}\n\n\tasync generate(request: Context, options?: OpenAIResponsesLLMOptions): Promise<AssistantMessage> {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tprovider: this.modelInfo.provider,\n\t\t\tmodel: this.modelInfo.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t};\n\t\ttry {\n\t\t\tconst input = this.convertToInput(request.messages, request.systemPrompt);\n\n\t\t\tconst params: ResponseCreateParamsStreaming = {\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tinput,\n\t\t\t\tstream: true,\n\t\t\t};\n\n\t\t\tif (options?.maxTokens) {\n\t\t\t\tparams.max_output_tokens = options?.maxTokens;\n\t\t\t}\n\n\t\t\tif (options?.temperature !== undefined) {\n\t\t\t\tparams.temperature = options?.temperature;\n\t\t\t}\n\n\t\t\tif (request.tools) {\n\t\t\t\tparams.tools = this.convertTools(request.tools);\n\t\t\t}\n\n\t\t\t// Add reasoning options for models that support it\n\t\t\tif (this.modelInfo?.reasoning && (options?.reasoningEffort || options?.reasoningSummary)) {\n\t\t\t\tparams.reasoning = {\n\t\t\t\t\teffort: options?.reasoningEffort || \"medium\",\n\t\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t\t};\n\t\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t\t}\n\n\t\t\tconst stream = await this.client.responses.create(params, {\n\t\t\t\tsignal: options?.signal,\n\t\t\t});\n\n\t\t\toptions?.onEvent?.({ type: \"start\", model: this.modelInfo.id, provider: this.modelInfo.provider });\n\n\t\t\tconst outputItems: (ResponseReasoningItem | ResponseOutputMessage | ResponseFunctionToolCall)[] = [];\n\t\t\tlet currentItem: ResponseReasoningItem | ResponseOutputMessage | ResponseFunctionToolCall | null = null;\n\n\t\t\tfor await (const event of stream) {\n\t\t\t\t// Handle output item start\n\t\t\t\tif (event.type === \"response.output_item.added\") {\n\t\t\t\t\tconst item = event.item;\n\t\t\t\t\tif (item.type === \"reasoning\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_start\" });\n\t\t\t\t\t\toutputItems.push(item);\n\t\t\t\t\t\tcurrentItem = item;\n\t\t\t\t\t} else if (item.type === \"message\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_start\" });\n\t\t\t\t\t\toutputItems.push(item);\n\t\t\t\t\t\tcurrentItem = item;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Handle reasoning summary deltas\n\t\t\t\telse if (event.type === \"response.reasoning_summary_part.added\") {\n\t\t\t\t\tif (currentItem && currentItem.type === \"reasoning\") {\n\t\t\t\t\t\tcurrentItem.summary = currentItem.summary || [];\n\t\t\t\t\t\tcurrentItem.summary.push(event.part);\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"response.reasoning_summary_text.delta\") {\n\t\t\t\t\tif (currentItem && currentItem.type === \"reasoning\") {\n\t\t\t\t\t\tcurrentItem.summary = currentItem.summary || [];\n\t\t\t\t\t\tconst lastPart = currentItem.summary[currentItem.summary.length - 1];\n\t\t\t\t\t\tif (lastPart) {\n\t\t\t\t\t\t\tlastPart.text += event.delta;\n\t\t\t\t\t\t\toptions?.onEvent?.({\n\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\tcontent: currentItem.summary.map((s) => s.text).join(\"\\n\\n\"),\n\t\t\t\t\t\t\t\tdelta: event.delta,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Add a new line between summary parts (hack...)\n\t\t\t\telse if (event.type === \"response.reasoning_summary_part.done\") {\n\t\t\t\t\tif (currentItem && currentItem.type === \"reasoning\") {\n\t\t\t\t\t\tcurrentItem.summary = currentItem.summary || [];\n\t\t\t\t\t\tconst lastPart = currentItem.summary[currentItem.summary.length - 1];\n\t\t\t\t\t\tif (lastPart) {\n\t\t\t\t\t\t\tlastPart.text += \"\\n\\n\";\n\t\t\t\t\t\t\toptions?.onEvent?.({\n\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\tcontent: currentItem.summary.map((s) => s.text).join(\"\\n\\n\"),\n\t\t\t\t\t\t\t\tdelta: \"\\n\\n\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Handle text output deltas\n\t\t\t\telse if (event.type === \"response.content_part.added\") {\n\t\t\t\t\tif (currentItem && currentItem.type === \"message\") {\n\t\t\t\t\t\tcurrentItem.content = currentItem.content || [];\n\t\t\t\t\t\tcurrentItem.content.push(event.part);\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"response.output_text.delta\") {\n\t\t\t\t\tif (currentItem && currentItem.type === \"message\") {\n\t\t\t\t\t\tconst lastPart = currentItem.content[currentItem.content.length - 1];\n\t\t\t\t\t\tif (lastPart && lastPart.type === \"output_text\") {\n\t\t\t\t\t\t\tlastPart.text += event.delta;\n\t\t\t\t\t\t\toptions?.onEvent?.({\n\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\tcontent: currentItem.content\n\t\t\t\t\t\t\t\t\t.map((c) => (c.type === \"output_text\" ? c.text : c.refusal))\n\t\t\t\t\t\t\t\t\t.join(\"\"),\n\t\t\t\t\t\t\t\tdelta: event.delta,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"response.refusal.delta\") {\n\t\t\t\t\tif (currentItem && currentItem.type === \"message\") {\n\t\t\t\t\t\tconst lastPart = currentItem.content[currentItem.content.length - 1];\n\t\t\t\t\t\tif (lastPart && lastPart.type === \"refusal\") {\n\t\t\t\t\t\t\tlastPart.refusal += event.delta;\n\t\t\t\t\t\t\toptions?.onEvent?.({\n\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\tcontent: currentItem.content\n\t\t\t\t\t\t\t\t\t.map((c) => (c.type === \"output_text\" ? c.text : c.refusal))\n\t\t\t\t\t\t\t\t\t.join(\"\"),\n\t\t\t\t\t\t\t\tdelta: event.delta,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Handle output item completion\n\t\t\t\telse if (event.type === \"response.output_item.done\") {\n\t\t\t\t\tconst item = event.item;\n\n\t\t\t\t\tif (item.type === \"reasoning\") {\n\t\t\t\t\t\toutputItems[outputItems.length - 1] = item; // Update with final item\n\t\t\t\t\t\tconst thinkingContent = item.summary?.map((s) => s.text).join(\"\\n\\n\") || \"\";\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_end\", content: thinkingContent });\n\t\t\t\t\t} else if (item.type === \"message\") {\n\t\t\t\t\t\toutputItems[outputItems.length - 1] = item; // Update with final item\n\t\t\t\t\t\tconst textContent = item.content.map((c) => (c.type === \"output_text\" ? c.text : c.refusal)).join(\"\");\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_end\", content: textContent });\n\t\t\t\t\t} else if (item.type === \"function_call\") {\n\t\t\t\t\t\tconst toolCall: ToolCall = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: item.call_id + \"|\" + item.id,\n\t\t\t\t\t\t\tname: item.name,\n\t\t\t\t\t\t\targuments: JSON.parse(item.arguments),\n\t\t\t\t\t\t};\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"toolCall\", toolCall });\n\t\t\t\t\t\toutputItems.push(item);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Handle completion\n\t\t\t\telse if (event.type === \"response.completed\") {\n\t\t\t\t\tconst response = event.response;\n\t\t\t\t\tif (response?.usage) {\n\t\t\t\t\t\toutput.usage = {\n\t\t\t\t\t\t\tinput: response.usage.input_tokens || 0,\n\t\t\t\t\t\t\toutput: response.usage.output_tokens || 0,\n\t\t\t\t\t\t\tcacheRead: response.usage.input_tokens_details?.cached_tokens || 0,\n\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tcalculateCost(this.modelInfo, output.usage);\n\t\t\t\t\t// Map status to stop reason\n\t\t\t\t\toutput.stopReason = this.mapStopReason(response?.status);\n\t\t\t\t\tif (outputItems.some((b) => b.type === \"function_call\") && output.stopReason === \"stop\") {\n\t\t\t\t\t\toutput.stopReason = \"toolUse\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Handle errors\n\t\t\t\telse if (event.type === \"error\") {\n\t\t\t\t\toutput.stopReason = \"error\";\n\t\t\t\t\toutput.error = `Code ${event.code}: ${event.message}` || \"Unknown error\";\n\t\t\t\t\toptions?.onEvent?.({ type: \"error\", error: output.error });\n\t\t\t\t\treturn output;\n\t\t\t\t} else if (event.type === \"response.failed\") {\n\t\t\t\t\toutput.stopReason = \"error\";\n\t\t\t\t\toutput.error = \"Unknown error\";\n\t\t\t\t\toptions?.onEvent?.({ type: \"error\", error: output.error });\n\t\t\t\t\treturn output;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Convert output items to blocks\n\t\t\tfor (const item of outputItems) {\n\t\t\t\tif (item.type === \"reasoning\") {\n\t\t\t\t\toutput.content.push({\n\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\tthinking: item.summary?.map((s: any) => s.text).join(\"\\n\\n\") || \"\",\n\t\t\t\t\t\tthinkingSignature: JSON.stringify(item), // Full item for resubmission\n\t\t\t\t\t});\n\t\t\t\t} else if (item.type === \"message\") {\n\t\t\t\t\toutput.content.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: item.content.map((c) => (c.type === \"output_text\" ? c.text : c.refusal)).join(\"\"),\n\t\t\t\t\t\ttextSignature: item.id, // ID for resubmission\n\t\t\t\t\t});\n\t\t\t\t} else if (item.type === \"function_call\") {\n\t\t\t\t\toutput.content.push({\n\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\tid: item.call_id + \"|\" + item.id,\n\t\t\t\t\t\tname: item.name,\n\t\t\t\t\t\targuments: JSON.parse(item.arguments),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\toptions?.onEvent?.({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\treturn output;\n\t\t} catch (error) {\n\t\t\toutput.stopReason = \"error\";\n\t\t\toutput.error = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\toptions?.onEvent?.({ type: \"error\", error: output.error });\n\t\t\treturn output;\n\t\t}\n\t}\n\n\tprivate convertToInput(messages: Message[], systemPrompt?: string): ResponseInput {\n\t\tconst input: ResponseInput = [];\n\n\t\t// Transform messages for cross-provider compatibility\n\t\tconst transformedMessages = transformMessages(messages, this.modelInfo);\n\n\t\t// Add system prompt if provided\n\t\tif (systemPrompt) {\n\t\t\tconst role = this.modelInfo?.reasoning ? \"developer\" : \"system\";\n\t\t\tinput.push({\n\t\t\t\trole,\n\t\t\t\tcontent: systemPrompt,\n\t\t\t});\n\t\t}\n\n\t\t// Convert messages\n\t\tfor (const msg of transformedMessages) {\n\t\t\tif (msg.role === \"user\") {\n\t\t\t\t// Handle both string and array content\n\t\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\t\tinput.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"input_text\", text: msg.content }],\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Convert array content to OpenAI Responses format\n\t\t\t\t\tconst content: ResponseInputContent[] = msg.content.map((item): ResponseInputContent => {\n\t\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"input_text\",\n\t\t\t\t\t\t\t\ttext: item.text,\n\t\t\t\t\t\t\t} satisfies ResponseInputText;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Image content - OpenAI Responses uses data URLs\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"input_image\",\n\t\t\t\t\t\t\t\tdetail: \"auto\",\n\t\t\t\t\t\t\t\timage_url: `data:${item.mimeType};base64,${item.data}`,\n\t\t\t\t\t\t\t} satisfies ResponseInputImage;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tinput.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (msg.role === \"assistant\") {\n\t\t\t\t// Process content blocks in order\n\t\t\t\tconst output: ResponseInput = [];\n\n\t\t\t\tfor (const block of msg.content) {\n\t\t\t\t\t// Do not submit thinking blocks if the completion had an error (i.e. abort)\n\t\t\t\t\tif (block.type === \"thinking\" && msg.stopReason !== \"error\") {\n\t\t\t\t\t\t// Push the full reasoning item(s) from signature\n\t\t\t\t\t\tif (block.thinkingSignature) {\n\t\t\t\t\t\t\tconst reasoningItem = JSON.parse(block.thinkingSignature);\n\t\t\t\t\t\t\toutput.push(reasoningItem);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (block.type === \"text\") {\n\t\t\t\t\t\tconst textBlock = block as TextContent;\n\t\t\t\t\t\toutput.push({\n\t\t\t\t\t\t\ttype: \"message\",\n\t\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\t\tcontent: [{ type: \"output_text\", text: textBlock.text, annotations: [] }],\n\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\tid: textBlock.textSignature || \"msg_\" + Math.random().toString(36).substring(2, 15),\n\t\t\t\t\t\t} satisfies ResponseOutputMessage);\n\t\t\t\t\t\t// Do not submit thinking blocks if the completion had an error (i.e. abort)\n\t\t\t\t\t} else if (block.type === \"toolCall\" && msg.stopReason !== \"error\") {\n\t\t\t\t\t\tconst toolCall = block as ToolCall;\n\t\t\t\t\t\toutput.push({\n\t\t\t\t\t\t\ttype: \"function_call\",\n\t\t\t\t\t\t\tid: toolCall.id.split(\"|\")[1], // Extract original ID\n\t\t\t\t\t\t\tcall_id: toolCall.id.split(\"|\")[0], // Extract call session ID\n\t\t\t\t\t\t\tname: toolCall.name,\n\t\t\t\t\t\t\targuments: JSON.stringify(toolCall.arguments),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Add all output items to input\n\t\t\t\tinput.push(...output);\n\t\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t\t// Tool results are sent as function_call_output\n\t\t\t\tinput.push({\n\t\t\t\t\ttype: \"function_call_output\",\n\t\t\t\t\tcall_id: msg.toolCallId.split(\"|\")[0], // Extract call session ID\n\t\t\t\t\toutput: msg.content,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn input;\n\t}\n\n\tprivate convertTools(tools: Tool[]): OpenAITool[] {\n\t\treturn tools.map((tool) => ({\n\t\t\ttype: \"function\",\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tparameters: tool.parameters,\n\t\t\tstrict: null,\n\t\t}));\n\t}\n\n\tprivate mapStopReason(status: string | undefined): StopReason {\n\t\tswitch (status) {\n\t\t\tcase \"completed\":\n\t\t\t\treturn \"stop\";\n\t\t\tcase \"incomplete\":\n\t\t\t\treturn \"length\";\n\t\t\tcase \"failed\":\n\t\t\tcase \"cancelled\":\n\t\t\t\treturn \"error\";\n\t\t\tdefault:\n\t\t\t\treturn \"stop\";\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { Message, Model } from "../types.js";
2
+ /**
3
+ * Transform messages for cross-provider compatibility.
4
+ *
5
+ * - User and toolResult messages are copied verbatim
6
+ * - Assistant messages:
7
+ * - If from the same provider/model, copied as-is
8
+ * - If from different provider/model, thinking blocks are converted to text blocks with <thinking></thinking> tags
9
+ *
10
+ * @param messages The messages to transform
11
+ * @param model The target model that will process these messages
12
+ * @returns A copy of the messages array with transformations applied
13
+ */
14
+ export declare function transformMessages(messages: Message[], model: Model): Message[];
15
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/providers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpE;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,CAuC9E"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Transform messages for cross-provider compatibility.
3
+ *
4
+ * - User and toolResult messages are copied verbatim
5
+ * - Assistant messages:
6
+ * - If from the same provider/model, copied as-is
7
+ * - If from different provider/model, thinking blocks are converted to text blocks with <thinking></thinking> tags
8
+ *
9
+ * @param messages The messages to transform
10
+ * @param model The target model that will process these messages
11
+ * @returns A copy of the messages array with transformations applied
12
+ */
13
+ export function transformMessages(messages, model) {
14
+ return messages.map((msg) => {
15
+ // User and toolResult messages pass through unchanged
16
+ if (msg.role === "user" || msg.role === "toolResult") {
17
+ return msg;
18
+ }
19
+ // Assistant messages need transformation check
20
+ if (msg.role === "assistant") {
21
+ const assistantMsg = msg;
22
+ // If message is from the same provider and model, keep as-is
23
+ if (assistantMsg.provider === model.provider && assistantMsg.model === model.id) {
24
+ return msg;
25
+ }
26
+ // Transform message from different provider/model
27
+ const transformedContent = assistantMsg.content.map((block) => {
28
+ if (block.type === "thinking") {
29
+ // Convert thinking block to text block with <thinking> tags
30
+ return {
31
+ type: "text",
32
+ text: `<thinking>\n${block.thinking}\n</thinking>`,
33
+ };
34
+ }
35
+ // All other blocks (text, toolCall) pass through unchanged
36
+ return block;
37
+ });
38
+ // Return transformed assistant message
39
+ return {
40
+ ...assistantMsg,
41
+ content: transformedContent,
42
+ };
43
+ }
44
+ // Should not reach here, but return as-is for safety
45
+ return msg;
46
+ });
47
+ }
48
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/providers/utils.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAmB,EAAE,KAAY;IAClE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3B,sDAAsD;QACtD,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACtD,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,+CAA+C;QAC/C,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,GAAuB,CAAC;YAE7C,6DAA6D;YAC7D,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,IAAI,YAAY,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;gBACjF,OAAO,GAAG,CAAC;YACZ,CAAC;YAED,kDAAkD;YAClD,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC7D,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC/B,4DAA4D;oBAC5D,OAAO;wBACN,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,eAAe,KAAK,CAAC,QAAQ,eAAe;qBAClD,CAAC;gBACH,CAAC;gBACD,2DAA2D;gBAC3D,OAAO,KAAK,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,uCAAuC;YACvC,OAAO;gBACN,GAAG,YAAY;gBACf,OAAO,EAAE,kBAAkB;aAC3B,CAAC;QACH,CAAC;QAED,qDAAqD;QACrD,OAAO,GAAG,CAAC;IACZ,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { AssistantMessage, Message, Model } from \"../types.js\";\n\n/**\n * Transform messages for cross-provider compatibility.\n *\n * - User and toolResult messages are copied verbatim\n * - Assistant messages:\n * - If from the same provider/model, copied as-is\n * - If from different provider/model, thinking blocks are converted to text blocks with <thinking></thinking> tags\n *\n * @param messages The messages to transform\n * @param model The target model that will process these messages\n * @returns A copy of the messages array with transformations applied\n */\nexport function transformMessages(messages: Message[], model: Model): Message[] {\n\treturn messages.map((msg) => {\n\t\t// User and toolResult messages pass through unchanged\n\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\treturn msg;\n\t\t}\n\n\t\t// Assistant messages need transformation check\n\t\tif (msg.role === \"assistant\") {\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\n\t\t\t// If message is from the same provider and model, keep as-is\n\t\t\tif (assistantMsg.provider === model.provider && assistantMsg.model === model.id) {\n\t\t\t\treturn msg;\n\t\t\t}\n\n\t\t\t// Transform message from different provider/model\n\t\t\tconst transformedContent = assistantMsg.content.map((block) => {\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\t// Convert thinking block to text block with <thinking> tags\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: `<thinking>\\n${block.thinking}\\n</thinking>`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// All other blocks (text, toolCall) pass through unchanged\n\t\t\t\treturn block;\n\t\t\t});\n\n\t\t\t// Return transformed assistant message\n\t\t\treturn {\n\t\t\t\t...assistantMsg,\n\t\t\t\tcontent: transformedContent,\n\t\t\t};\n\t\t}\n\n\t\t// Should not reach here, but return as-is for safety\n\t\treturn msg;\n\t});\n}\n"]}
package/dist/types.d.ts CHANGED
@@ -5,7 +5,7 @@ export interface LLMOptions {
5
5
  signal?: AbortSignal;
6
6
  }
7
7
  export interface LLM<T extends LLMOptions> {
8
- complete(request: Context, options?: T): Promise<AssistantMessage>;
8
+ generate(request: Context, options?: T): Promise<AssistantMessage>;
9
9
  getModel(): Model;
10
10
  }
11
11
  export interface TextContent {
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface LLMOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tonEvent?: (event: AssistantMessageEvent) => void;\n\tsignal?: AbortSignal;\n}\n\nexport interface LLM<T extends LLMOptions> {\n\tcomplete(request: Context, options?: T): Promise<AssistantMessage>;\n\tgetModel(): Model;\n}\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, the message ID\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"safety\" | \"error\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall)[];\n\tprovider: string;\n\tmodel: string;\n\tusage: Usage;\n\n\tstopReason: StopReason;\n\terror?: string | Error;\n}\n\nexport interface ToolResultMessage {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: string;\n\tisError: boolean;\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nexport interface Tool {\n\tname: string;\n\tdescription: string;\n\tparameters: Record<string, any>; // JSON Schema\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; model: string; provider: string }\n\t| { type: \"text_start\" }\n\t| { type: \"text_delta\"; content: string; delta: string }\n\t| { type: \"text_end\"; content: string }\n\t| { type: \"thinking_start\" }\n\t| { type: \"thinking_delta\"; content: string; delta: string }\n\t| { type: \"thinking_end\"; content: string }\n\t| { type: \"toolCall\"; toolCall: ToolCall }\n\t| { type: \"done\"; reason: StopReason; message: AssistantMessage }\n\t| { type: \"error\"; error: string };\n\n// Model interface for the unified model system\nexport interface Model {\n\tid: string;\n\tname: string;\n\tprovider: string;\n\tbaseUrl?: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface LLMOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tonEvent?: (event: AssistantMessageEvent) => void;\n\tsignal?: AbortSignal;\n}\n\nexport interface LLM<T extends LLMOptions> {\n\tgenerate(request: Context, options?: T): Promise<AssistantMessage>;\n\tgetModel(): Model;\n}\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, the message ID\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"safety\" | \"error\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall)[];\n\tprovider: string;\n\tmodel: string;\n\tusage: Usage;\n\n\tstopReason: StopReason;\n\terror?: string | Error;\n}\n\nexport interface ToolResultMessage {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: string;\n\tisError: boolean;\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nexport interface Tool {\n\tname: string;\n\tdescription: string;\n\tparameters: Record<string, any>; // JSON Schema\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; model: string; provider: string }\n\t| { type: \"text_start\" }\n\t| { type: \"text_delta\"; content: string; delta: string }\n\t| { type: \"text_end\"; content: string }\n\t| { type: \"thinking_start\" }\n\t| { type: \"thinking_delta\"; content: string; delta: string }\n\t| { type: \"thinking_end\"; content: string }\n\t| { type: \"toolCall\"; toolCall: ToolCall }\n\t| { type: \"done\"; reason: StopReason; message: AssistantMessage }\n\t| { type: \"error\"; error: string };\n\n// Model interface for the unified model system\nexport interface Model {\n\tid: string;\n\tname: string;\n\tprovider: string;\n\tbaseUrl?: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mariozechner/pi-ai",
3
- "version": "0.5.19",
3
+ "version": "0.5.21",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",