@mariozechner/pi-ai 0.5.18 → 0.5.20

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,4 +1,6 @@
1
1
  import OpenAI from "openai";
2
+ import { calculateCost } from "../models.js";
3
+ import { transformMessages } from "./utils.js";
2
4
  export class OpenAIResponsesLLM {
3
5
  client;
4
6
  modelInfo;
@@ -15,7 +17,21 @@ export class OpenAIResponsesLLM {
15
17
  getModel() {
16
18
  return this.modelInfo;
17
19
  }
18
- 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
+ };
19
35
  try {
20
36
  const input = this.convertToInput(request.messages, request.systemPrompt);
21
37
  const params = {
@@ -44,65 +60,108 @@ export class OpenAIResponsesLLM {
44
60
  signal: options?.signal,
45
61
  });
46
62
  options?.onEvent?.({ type: "start", model: this.modelInfo.id, provider: this.modelInfo.provider });
47
- const outputItems = []; // any for function_call items
48
- let currentTextAccum = ""; // For delta accumulation
49
- let currentThinkingAccum = ""; // For delta accumulation
50
- let usage = {
51
- input: 0,
52
- output: 0,
53
- cacheRead: 0,
54
- cacheWrite: 0,
55
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
56
- };
57
- let stopReason = "stop";
63
+ const outputItems = [];
64
+ let currentItem = null;
58
65
  for await (const event of stream) {
59
66
  // Handle output item start
60
67
  if (event.type === "response.output_item.added") {
61
68
  const item = event.item;
62
69
  if (item.type === "reasoning") {
63
70
  options?.onEvent?.({ type: "thinking_start" });
64
- currentThinkingAccum = "";
71
+ outputItems.push(item);
72
+ currentItem = item;
65
73
  }
66
74
  else if (item.type === "message") {
67
75
  options?.onEvent?.({ type: "text_start" });
68
- currentTextAccum = "";
76
+ outputItems.push(item);
77
+ currentItem = item;
69
78
  }
70
79
  }
71
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
+ }
72
87
  else if (event.type === "response.reasoning_summary_text.delta") {
73
- const delta = event.delta;
74
- currentThinkingAccum += delta;
75
- 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
+ }
76
100
  }
77
101
  // Add a new line between summary parts (hack...)
78
102
  else if (event.type === "response.reasoning_summary_part.done") {
79
- currentThinkingAccum += "\n\n";
80
- 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
+ }
81
115
  }
82
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
+ }
83
123
  else if (event.type === "response.output_text.delta") {
84
- const delta = event.delta;
85
- currentTextAccum += delta;
86
- 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
+ }
87
137
  }
88
- // Handle refusal output deltas
89
138
  else if (event.type === "response.refusal.delta") {
90
- const delta = event.delta;
91
- currentTextAccum += delta;
92
- 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
+ }
93
152
  }
94
153
  // Handle output item completion
95
154
  else if (event.type === "response.output_item.done") {
96
155
  const item = event.item;
97
156
  if (item.type === "reasoning") {
157
+ outputItems[outputItems.length - 1] = item; // Update with final item
98
158
  const thinkingContent = item.summary?.map((s) => s.text).join("\n\n") || "";
99
159
  options?.onEvent?.({ type: "thinking_end", content: thinkingContent });
100
- outputItems.push(item);
101
160
  }
102
161
  else if (item.type === "message") {
162
+ outputItems[outputItems.length - 1] = item; // Update with final item
103
163
  const textContent = item.content.map((c) => (c.type === "output_text" ? c.text : c.refusal)).join("");
104
164
  options?.onEvent?.({ type: "text_end", content: textContent });
105
- outputItems.push(item);
106
165
  }
107
166
  else if (item.type === "function_call") {
108
167
  const toolCall = {
@@ -119,7 +178,7 @@ export class OpenAIResponsesLLM {
119
178
  else if (event.type === "response.completed") {
120
179
  const response = event.response;
121
180
  if (response?.usage) {
122
- usage = {
181
+ output.usage = {
123
182
  input: response.usage.input_tokens || 0,
124
183
  output: response.usage.output_tokens || 0,
125
184
  cacheRead: response.usage.input_tokens_details?.cached_tokens || 0,
@@ -127,59 +186,45 @@ export class OpenAIResponsesLLM {
127
186
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
128
187
  };
129
188
  }
189
+ calculateCost(this.modelInfo, output.usage);
130
190
  // Map status to stop reason
131
- 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
+ }
132
195
  }
133
196
  // Handle errors
134
197
  else if (event.type === "error") {
135
- const errorOutput = {
136
- role: "assistant",
137
- content: [],
138
- provider: this.modelInfo.provider,
139
- model: this.modelInfo.id,
140
- usage,
141
- stopReason: "error",
142
- error: `Code ${event.code}: ${event.message}` || "Unknown error",
143
- };
144
- options?.onEvent?.({ type: "error", error: errorOutput.error || "Unknown error" });
145
- 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;
146
202
  }
147
203
  else if (event.type === "response.failed") {
148
- const errorOutput = {
149
- role: "assistant",
150
- content: [],
151
- provider: this.modelInfo.provider,
152
- model: this.modelInfo.id,
153
- usage,
154
- stopReason: "error",
155
- error: "Unknown error",
156
- };
157
- options?.onEvent?.({ type: "error", error: errorOutput.error || "Unknown error" });
158
- return errorOutput;
204
+ output.stopReason = "error";
205
+ output.error = "Unknown error";
206
+ options?.onEvent?.({ type: "error", error: output.error });
207
+ return output;
159
208
  }
160
209
  }
161
- if (options?.signal?.aborted) {
162
- throw new Error("Request was aborted");
163
- }
164
210
  // Convert output items to blocks
165
- const blocks = [];
166
211
  for (const item of outputItems) {
167
212
  if (item.type === "reasoning") {
168
- blocks.push({
213
+ output.content.push({
169
214
  type: "thinking",
170
215
  thinking: item.summary?.map((s) => s.text).join("\n\n") || "",
171
216
  thinkingSignature: JSON.stringify(item), // Full item for resubmission
172
217
  });
173
218
  }
174
219
  else if (item.type === "message") {
175
- blocks.push({
220
+ output.content.push({
176
221
  type: "text",
177
222
  text: item.content.map((c) => (c.type === "output_text" ? c.text : c.refusal)).join(""),
178
223
  textSignature: item.id, // ID for resubmission
179
224
  });
180
225
  }
181
226
  else if (item.type === "function_call") {
182
- blocks.push({
227
+ output.content.push({
183
228
  type: "toolCall",
184
229
  id: item.call_id + "|" + item.id,
185
230
  name: item.name,
@@ -187,43 +232,23 @@ export class OpenAIResponsesLLM {
187
232
  });
188
233
  }
189
234
  }
190
- // Check if we have tool calls for stop reason
191
- if (blocks.some((b) => b.type === "toolCall") && stopReason === "stop") {
192
- stopReason = "toolUse";
235
+ if (options?.signal?.aborted) {
236
+ throw new Error("Request was aborted");
193
237
  }
194
- const output = {
195
- role: "assistant",
196
- content: blocks,
197
- provider: this.modelInfo.provider,
198
- model: this.modelInfo.id,
199
- usage,
200
- stopReason,
201
- };
202
238
  options?.onEvent?.({ type: "done", reason: output.stopReason, message: output });
203
239
  return output;
204
240
  }
205
241
  catch (error) {
206
- const output = {
207
- role: "assistant",
208
- content: [],
209
- provider: this.modelInfo.provider,
210
- model: this.modelInfo.id,
211
- usage: {
212
- input: 0,
213
- output: 0,
214
- cacheRead: 0,
215
- cacheWrite: 0,
216
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
217
- },
218
- stopReason: "error",
219
- error: error instanceof Error ? error.message : String(error),
220
- };
221
- 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 });
222
245
  return output;
223
246
  }
224
247
  }
225
248
  convertToInput(messages, systemPrompt) {
226
249
  const input = [];
250
+ // Transform messages for cross-provider compatibility
251
+ const transformedMessages = transformMessages(messages, this.modelInfo);
227
252
  // Add system prompt if provided
228
253
  if (systemPrompt) {
229
254
  const role = this.modelInfo?.reasoning ? "developer" : "system";
@@ -233,7 +258,7 @@ export class OpenAIResponsesLLM {
233
258
  });
234
259
  }
235
260
  // Convert messages
236
- for (const msg of messages) {
261
+ for (const msg of transformedMessages) {
237
262
  if (msg.role === "user") {
238
263
  // Handle both string and array content
239
264
  if (typeof msg.content === "string") {
@@ -270,7 +295,8 @@ export class OpenAIResponsesLLM {
270
295
  // Process content blocks in order
271
296
  const output = [];
272
297
  for (const block of msg.content) {
273
- 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") {
274
300
  // Push the full reasoning item(s) from signature
275
301
  if (block.thinkingSignature) {
276
302
  const reasoningItem = JSON.parse(block.thinkingSignature);
@@ -286,8 +312,9 @@ export class OpenAIResponsesLLM {
286
312
  status: "completed",
287
313
  id: textBlock.textSignature || "msg_" + Math.random().toString(36).substring(2, 15),
288
314
  });
315
+ // Do not submit thinking blocks if the completion had an error (i.e. abort)
289
316
  }
290
- else if (block.type === "toolCall") {
317
+ else if (block.type === "toolCall" && msg.stopReason !== "error") {
291
318
  const toolCall = block;
292
319
  output.push({
293
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 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\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.18",
3
+ "version": "0.5.20",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",