@stacksjs/ai 0.70.88 → 0.70.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/claude/index.d.ts +29 -0
- package/dist/agents/claude/index.js +197 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.js +1 -0
- package/dist/buddy.d.ts +67 -0
- package/dist/buddy.js +393 -0
- package/dist/drivers/anthropic/index.d.ts +40 -0
- package/dist/drivers/anthropic/index.js +276 -0
- package/dist/drivers/claude-agent-sdk/index.d.ts +40 -0
- package/dist/drivers/claude-agent-sdk/index.js +198 -0
- package/dist/drivers/index.d.ts +13 -0
- package/dist/drivers/index.js +4 -0
- package/dist/drivers/ollama/index.d.ts +93 -0
- package/dist/drivers/ollama/index.js +332 -0
- package/dist/drivers/openai/index.d.ts +66 -0
- package/dist/drivers/openai/index.js +351 -0
- package/dist/image.d.ts +83 -0
- package/dist/image.js +375 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +16 -0
- package/dist/mcp.d.ts +115 -0
- package/dist/mcp.js +361 -0
- package/dist/personalization.d.ts +118 -0
- package/dist/personalization.js +244 -0
- package/dist/search.d.ts +101 -0
- package/dist/search.js +316 -0
- package/dist/text.d.ts +10 -0
- package/dist/text.js +51 -0
- package/dist/types.d.ts +185 -0
- package/dist/types.js +0 -0
- package/dist/utils/client-bedrock-runtime.d.ts +16 -0
- package/dist/utils/client-bedrock-runtime.js +17 -0
- package/dist/utils/client-bedrock.d.ts +27 -0
- package/dist/utils/client-bedrock.js +20 -0
- package/dist/utils/model-access.d.ts +1 -0
- package/dist/utils/model-access.js +21 -0
- package/dist/utils/retry.d.ts +38 -0
- package/dist/utils/retry.js +39 -0
- package/dist/utils/tokens.d.ts +50 -0
- package/dist/utils/tokens.js +59 -0
- package/dist/utils/usage.d.ts +56 -0
- package/dist/utils/usage.js +27 -0
- package/dist/utils/vision.d.ts +22 -0
- package/dist/utils/vision.js +54 -0
- package/package.json +1 -1
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { fetchWithRetry } from "../../utils/retry";
|
|
2
|
+
import { recordUsage } from "../../utils/usage";
|
|
3
|
+
import { normalizeMessagesForProvider } from "../../utils/vision";
|
|
4
|
+
const DEFAULT_MODEL = "gpt-4o", DEFAULT_MAX_TOKENS = 4096, DEFAULT_EMBEDDING_MODEL = "text-embedding-3-small", DEFAULT_BASE_URL = "https://api.openai.com/v1";
|
|
5
|
+
let globalConfig = null;
|
|
6
|
+
export function configure(config) {
|
|
7
|
+
globalConfig = config;
|
|
8
|
+
}
|
|
9
|
+
function getConfig(config) {
|
|
10
|
+
const merged = { ...globalConfig, ...config };
|
|
11
|
+
if (!merged.apiKey)
|
|
12
|
+
merged.apiKey = process.env.OPENAI_API_KEY || "";
|
|
13
|
+
return merged;
|
|
14
|
+
}
|
|
15
|
+
export function createOpenAIDriver(config) {
|
|
16
|
+
const {
|
|
17
|
+
apiKey,
|
|
18
|
+
model = DEFAULT_MODEL,
|
|
19
|
+
maxTokens = DEFAULT_MAX_TOKENS,
|
|
20
|
+
baseUrl = DEFAULT_BASE_URL,
|
|
21
|
+
embeddingModel = DEFAULT_EMBEDDING_MODEL
|
|
22
|
+
} = config;
|
|
23
|
+
return {
|
|
24
|
+
name: "OpenAI",
|
|
25
|
+
async process(command, systemPrompt, history) {
|
|
26
|
+
if (!apiKey)
|
|
27
|
+
throw Error("OpenAI API key not set. Configure your API key in settings.");
|
|
28
|
+
const response = await fetchWithRetry(`${baseUrl}/chat/completions`, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: {
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
Authorization: `Bearer ${apiKey}`
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
model,
|
|
36
|
+
max_tokens: maxTokens,
|
|
37
|
+
messages: [
|
|
38
|
+
{ role: "system", content: systemPrompt },
|
|
39
|
+
...history,
|
|
40
|
+
{ role: "user", content: command }
|
|
41
|
+
]
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const error = await response.text();
|
|
46
|
+
throw Error(`OpenAI API error: ${error}`);
|
|
47
|
+
}
|
|
48
|
+
const data = await response.json();
|
|
49
|
+
if (!data.choices || data.choices.length === 0)
|
|
50
|
+
throw Error("OpenAI API returned empty choices");
|
|
51
|
+
return data.choices[0].message.content;
|
|
52
|
+
},
|
|
53
|
+
async* stream(command, systemPrompt, history) {
|
|
54
|
+
if (!apiKey)
|
|
55
|
+
throw Error("OpenAI API key not set. Configure your API key in settings.");
|
|
56
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
Authorization: `Bearer ${apiKey}`
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
model,
|
|
64
|
+
max_tokens: maxTokens,
|
|
65
|
+
stream: !0,
|
|
66
|
+
messages: [
|
|
67
|
+
{ role: "system", content: systemPrompt },
|
|
68
|
+
...history,
|
|
69
|
+
{ role: "user", content: command }
|
|
70
|
+
]
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const error = await response.text();
|
|
75
|
+
throw Error(`OpenAI API error: ${error}`);
|
|
76
|
+
}
|
|
77
|
+
const reader = response.body?.getReader();
|
|
78
|
+
if (!reader)
|
|
79
|
+
throw Error("No response body");
|
|
80
|
+
const decoder = new TextDecoder;
|
|
81
|
+
let buffer = "";
|
|
82
|
+
const handlePayload = function* (data) {
|
|
83
|
+
if (data === "[DONE]")
|
|
84
|
+
return;
|
|
85
|
+
let parsed;
|
|
86
|
+
try {
|
|
87
|
+
parsed = JSON.parse(data);
|
|
88
|
+
} catch {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (parsed?.error) {
|
|
92
|
+
const msg = parsed.error.message || JSON.stringify(parsed.error);
|
|
93
|
+
throw Error(`[openai/stream] mid-stream error: ${msg}`);
|
|
94
|
+
}
|
|
95
|
+
const content = parsed.choices?.[0]?.delta?.content;
|
|
96
|
+
if (content)
|
|
97
|
+
yield content;
|
|
98
|
+
};
|
|
99
|
+
while (!0) {
|
|
100
|
+
const { done, value } = await reader.read();
|
|
101
|
+
if (done)
|
|
102
|
+
break;
|
|
103
|
+
buffer += decoder.decode(value, { stream: !0 });
|
|
104
|
+
const lines = buffer.split(`
|
|
105
|
+
`);
|
|
106
|
+
buffer = lines.pop() || "";
|
|
107
|
+
for (const line of lines)
|
|
108
|
+
if (line.startsWith("data: "))
|
|
109
|
+
yield* handlePayload(line.slice(6));
|
|
110
|
+
}
|
|
111
|
+
if (buffer.startsWith("data: "))
|
|
112
|
+
yield* handlePayload(buffer.slice(6));
|
|
113
|
+
},
|
|
114
|
+
async embed(input) {
|
|
115
|
+
if (!apiKey)
|
|
116
|
+
throw Error("OpenAI API key not set. Configure your API key in settings.");
|
|
117
|
+
const response = await fetch(`${baseUrl}/embeddings`, {
|
|
118
|
+
method: "POST",
|
|
119
|
+
headers: {
|
|
120
|
+
"Content-Type": "application/json",
|
|
121
|
+
Authorization: `Bearer ${apiKey}`
|
|
122
|
+
},
|
|
123
|
+
body: JSON.stringify({
|
|
124
|
+
model: embeddingModel,
|
|
125
|
+
input
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
const error = await response.text();
|
|
130
|
+
throw Error(`OpenAI Embeddings API error: ${error}`);
|
|
131
|
+
}
|
|
132
|
+
const data = await response.json();
|
|
133
|
+
if (Array.isArray(input))
|
|
134
|
+
return data.data.map((d) => d.embedding);
|
|
135
|
+
return data.data[0].embedding;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export async function chat(messages, options = {}) {
|
|
140
|
+
const config = getConfig(), {
|
|
141
|
+
model = DEFAULT_MODEL,
|
|
142
|
+
maxTokens = DEFAULT_MAX_TOKENS,
|
|
143
|
+
temperature,
|
|
144
|
+
topP,
|
|
145
|
+
stop
|
|
146
|
+
} = options, normalizedMessages = normalizeMessagesForProvider(messages, "openai"), startedAt = Date.now(), response = await fetchWithRetry(`${config.baseUrl || DEFAULT_BASE_URL}/chat/completions`, {
|
|
147
|
+
method: "POST",
|
|
148
|
+
headers: {
|
|
149
|
+
"Content-Type": "application/json",
|
|
150
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
151
|
+
},
|
|
152
|
+
body: JSON.stringify({
|
|
153
|
+
model,
|
|
154
|
+
max_tokens: maxTokens,
|
|
155
|
+
temperature,
|
|
156
|
+
top_p: topP,
|
|
157
|
+
stop,
|
|
158
|
+
messages: normalizedMessages
|
|
159
|
+
})
|
|
160
|
+
});
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
const error = await response.text();
|
|
163
|
+
throw Error(`OpenAI API error: ${error}`);
|
|
164
|
+
}
|
|
165
|
+
const data = await response.json();
|
|
166
|
+
if (!data.choices || data.choices.length === 0)
|
|
167
|
+
throw Error("OpenAI API returned empty choices");
|
|
168
|
+
const result = {
|
|
169
|
+
content: data.choices[0].message.content,
|
|
170
|
+
model: data.model,
|
|
171
|
+
usage: {
|
|
172
|
+
promptTokens: data.usage?.prompt_tokens || 0,
|
|
173
|
+
completionTokens: data.usage?.completion_tokens || 0,
|
|
174
|
+
totalTokens: data.usage?.total_tokens || 0
|
|
175
|
+
},
|
|
176
|
+
finishReason: data.choices[0].finish_reason
|
|
177
|
+
};
|
|
178
|
+
recordUsage({
|
|
179
|
+
provider: "openai",
|
|
180
|
+
model: data.model,
|
|
181
|
+
promptTokens: result.usage.promptTokens,
|
|
182
|
+
completionTokens: result.usage.completionTokens,
|
|
183
|
+
totalTokens: result.usage.totalTokens,
|
|
184
|
+
durationMs: Date.now() - startedAt,
|
|
185
|
+
timestamp: Date.now()
|
|
186
|
+
});
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
export async function* streamChat(messages, options = {}) {
|
|
190
|
+
const config = getConfig(), {
|
|
191
|
+
model = DEFAULT_MODEL,
|
|
192
|
+
maxTokens = DEFAULT_MAX_TOKENS,
|
|
193
|
+
temperature,
|
|
194
|
+
topP,
|
|
195
|
+
stop
|
|
196
|
+
} = options, response = await fetch(`${config.baseUrl || DEFAULT_BASE_URL}/chat/completions`, {
|
|
197
|
+
method: "POST",
|
|
198
|
+
headers: {
|
|
199
|
+
"Content-Type": "application/json",
|
|
200
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
201
|
+
},
|
|
202
|
+
body: JSON.stringify({
|
|
203
|
+
model,
|
|
204
|
+
max_tokens: maxTokens,
|
|
205
|
+
temperature,
|
|
206
|
+
top_p: topP,
|
|
207
|
+
stop,
|
|
208
|
+
stream: !0,
|
|
209
|
+
messages: normalizeMessagesForProvider(messages, "openai")
|
|
210
|
+
})
|
|
211
|
+
});
|
|
212
|
+
if (!response.ok) {
|
|
213
|
+
const error = await response.text();
|
|
214
|
+
throw Error(`OpenAI API error: ${error}`);
|
|
215
|
+
}
|
|
216
|
+
const reader = response.body?.getReader();
|
|
217
|
+
if (!reader)
|
|
218
|
+
throw Error("No response body");
|
|
219
|
+
const decoder = new TextDecoder;
|
|
220
|
+
let buffer = "";
|
|
221
|
+
while (!0) {
|
|
222
|
+
const { done, value } = await reader.read();
|
|
223
|
+
if (done)
|
|
224
|
+
break;
|
|
225
|
+
buffer += decoder.decode(value, { stream: !0 });
|
|
226
|
+
const lines = buffer.split(`
|
|
227
|
+
`);
|
|
228
|
+
buffer = lines.pop() || "";
|
|
229
|
+
for (const line of lines)
|
|
230
|
+
if (line.startsWith("data: ")) {
|
|
231
|
+
const data = line.slice(6);
|
|
232
|
+
if (data === "[DONE]")
|
|
233
|
+
continue;
|
|
234
|
+
try {
|
|
235
|
+
const content = JSON.parse(data).choices[0]?.delta?.content;
|
|
236
|
+
if (content)
|
|
237
|
+
yield content;
|
|
238
|
+
} catch {}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
export async function embed(input, model = DEFAULT_EMBEDDING_MODEL) {
|
|
243
|
+
const config = getConfig(), response = await fetch(`${config.baseUrl || DEFAULT_BASE_URL}/embeddings`, {
|
|
244
|
+
method: "POST",
|
|
245
|
+
headers: {
|
|
246
|
+
"Content-Type": "application/json",
|
|
247
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
248
|
+
},
|
|
249
|
+
body: JSON.stringify({ model, input })
|
|
250
|
+
});
|
|
251
|
+
if (!response.ok) {
|
|
252
|
+
const error = await response.text();
|
|
253
|
+
throw Error(`OpenAI Embeddings API error: ${error}`);
|
|
254
|
+
}
|
|
255
|
+
const data = await response.json();
|
|
256
|
+
if (Array.isArray(input))
|
|
257
|
+
return data.data.map((d) => d.embedding);
|
|
258
|
+
return data.data[0].embedding;
|
|
259
|
+
}
|
|
260
|
+
export async function generateImage(prompt, options = {}) {
|
|
261
|
+
const config = getConfig(), {
|
|
262
|
+
model = "dall-e-3",
|
|
263
|
+
size = "1024x1024",
|
|
264
|
+
quality = "standard",
|
|
265
|
+
n = 1,
|
|
266
|
+
responseFormat = "url"
|
|
267
|
+
} = options, response = await fetch(`${config.baseUrl || DEFAULT_BASE_URL}/images/generations`, {
|
|
268
|
+
method: "POST",
|
|
269
|
+
headers: {
|
|
270
|
+
"Content-Type": "application/json",
|
|
271
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
272
|
+
},
|
|
273
|
+
body: JSON.stringify({
|
|
274
|
+
model,
|
|
275
|
+
prompt,
|
|
276
|
+
size,
|
|
277
|
+
quality,
|
|
278
|
+
n,
|
|
279
|
+
response_format: responseFormat
|
|
280
|
+
})
|
|
281
|
+
});
|
|
282
|
+
if (!response.ok) {
|
|
283
|
+
const error = await response.text();
|
|
284
|
+
throw Error(`OpenAI Image API error: ${error}`);
|
|
285
|
+
}
|
|
286
|
+
return (await response.json()).data;
|
|
287
|
+
}
|
|
288
|
+
export async function transcribe(audioFile, options = {}) {
|
|
289
|
+
const config = getConfig(), formData = new FormData;
|
|
290
|
+
formData.append("file", audioFile);
|
|
291
|
+
formData.append("model", options.model || "whisper-1");
|
|
292
|
+
if (options.language)
|
|
293
|
+
formData.append("language", options.language);
|
|
294
|
+
if (options.prompt)
|
|
295
|
+
formData.append("prompt", options.prompt);
|
|
296
|
+
if (options.responseFormat)
|
|
297
|
+
formData.append("response_format", options.responseFormat);
|
|
298
|
+
if (options.temperature !== void 0)
|
|
299
|
+
formData.append("temperature", String(options.temperature));
|
|
300
|
+
const response = await fetch(`${config.baseUrl || DEFAULT_BASE_URL}/audio/transcriptions`, {
|
|
301
|
+
method: "POST",
|
|
302
|
+
headers: {
|
|
303
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
304
|
+
},
|
|
305
|
+
body: formData
|
|
306
|
+
});
|
|
307
|
+
if (!response.ok) {
|
|
308
|
+
const error = await response.text();
|
|
309
|
+
throw Error(`OpenAI Whisper API error: ${error}`);
|
|
310
|
+
}
|
|
311
|
+
return response.json();
|
|
312
|
+
}
|
|
313
|
+
export async function textToSpeech(input, options = {}) {
|
|
314
|
+
const config = getConfig(), {
|
|
315
|
+
model = "tts-1",
|
|
316
|
+
voice = "alloy",
|
|
317
|
+
responseFormat = "mp3",
|
|
318
|
+
speed = 1
|
|
319
|
+
} = options, response = await fetch(`${config.baseUrl || DEFAULT_BASE_URL}/audio/speech`, {
|
|
320
|
+
method: "POST",
|
|
321
|
+
headers: {
|
|
322
|
+
"Content-Type": "application/json",
|
|
323
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
324
|
+
},
|
|
325
|
+
body: JSON.stringify({
|
|
326
|
+
model,
|
|
327
|
+
input,
|
|
328
|
+
voice,
|
|
329
|
+
response_format: responseFormat,
|
|
330
|
+
speed
|
|
331
|
+
})
|
|
332
|
+
});
|
|
333
|
+
if (!response.ok) {
|
|
334
|
+
const error = await response.text();
|
|
335
|
+
throw Error(`OpenAI TTS API error: ${error}`);
|
|
336
|
+
}
|
|
337
|
+
return response.arrayBuffer();
|
|
338
|
+
}
|
|
339
|
+
export const openaiDriver = {
|
|
340
|
+
create: createOpenAIDriver
|
|
341
|
+
}, openai = {
|
|
342
|
+
configure,
|
|
343
|
+
chat,
|
|
344
|
+
streamChat,
|
|
345
|
+
embed,
|
|
346
|
+
generateImage,
|
|
347
|
+
transcribe,
|
|
348
|
+
textToSpeech,
|
|
349
|
+
createDriver: createOpenAIDriver
|
|
350
|
+
};
|
|
351
|
+
export default openai;
|
package/dist/image.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { AIResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Generate images from a text prompt.
|
|
4
|
+
* Currently supports OpenAI DALL-E models.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateImage(prompt: string, options?: ImageGenerationOptions): Promise<ImageGenerationResult>;
|
|
7
|
+
/**
|
|
8
|
+
* Edit an existing image with a text prompt (OpenAI DALL-E 2).
|
|
9
|
+
*/
|
|
10
|
+
export declare function editImage(image: Blob | File, prompt: string, options?: ImageEditOptions): Promise<ImageGenerationResult>;
|
|
11
|
+
/**
|
|
12
|
+
* Create variations of an existing image (OpenAI DALL-E 2).
|
|
13
|
+
*/
|
|
14
|
+
export declare function createImageVariation(image: Blob | File, options?: {
|
|
15
|
+
model?: 'dall-e-2'
|
|
16
|
+
n?: number
|
|
17
|
+
size?: '256x256' | '512x512' | '1024x1024'
|
|
18
|
+
responseFormat?: 'url' | 'b64_json'
|
|
19
|
+
}): Promise<ImageGenerationResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Analyze an image using AI vision capabilities.
|
|
22
|
+
* Supports Anthropic Claude, OpenAI GPT-4V, and Ollama multimodal models.
|
|
23
|
+
*/
|
|
24
|
+
export declare function analyzeImage(imageInput: ImageInput, prompt: string, options?: VisionOptions): Promise<VisionResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Analyze multiple images together with a prompt.
|
|
27
|
+
* Useful for comparison, batch analysis, etc.
|
|
28
|
+
*/
|
|
29
|
+
export declare function analyzeImages(images: ImageInput[], prompt: string, options?: VisionOptions): Promise<VisionResult>;
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Exports
|
|
32
|
+
// ============================================================================
|
|
33
|
+
export declare const image: {
|
|
34
|
+
generate: unknown;
|
|
35
|
+
edit: unknown;
|
|
36
|
+
variation: unknown;
|
|
37
|
+
analyze: unknown;
|
|
38
|
+
analyzeMultiple: unknown
|
|
39
|
+
};
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Types
|
|
42
|
+
// ============================================================================
|
|
43
|
+
export declare interface ImageGenerationOptions {
|
|
44
|
+
provider?: 'openai' | 'ollama'
|
|
45
|
+
model?: string
|
|
46
|
+
size?: '256x256' | '512x512' | '1024x1024' | '1792x1024' | '1024x1792'
|
|
47
|
+
quality?: 'standard' | 'hd'
|
|
48
|
+
n?: number
|
|
49
|
+
responseFormat?: 'url' | 'b64_json'
|
|
50
|
+
style?: 'vivid' | 'natural'
|
|
51
|
+
}
|
|
52
|
+
export declare interface ImageGenerationResult {
|
|
53
|
+
images: Array<{
|
|
54
|
+
url?: string
|
|
55
|
+
b64_json?: string
|
|
56
|
+
revisedPrompt?: string
|
|
57
|
+
}>
|
|
58
|
+
provider: string
|
|
59
|
+
model: string
|
|
60
|
+
}
|
|
61
|
+
export declare interface VisionOptions {
|
|
62
|
+
provider?: 'anthropic' | 'openai' | 'ollama'
|
|
63
|
+
model?: string
|
|
64
|
+
maxTokens?: number
|
|
65
|
+
temperature?: number
|
|
66
|
+
detail?: 'auto' | 'low' | 'high'
|
|
67
|
+
}
|
|
68
|
+
export declare interface VisionResult extends AIResult {
|
|
69
|
+
provider: string
|
|
70
|
+
}
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Image Editing
|
|
73
|
+
// ============================================================================
|
|
74
|
+
export declare interface ImageEditOptions {
|
|
75
|
+
mask?: Blob | File
|
|
76
|
+
model?: 'dall-e-2'
|
|
77
|
+
n?: number
|
|
78
|
+
size?: '256x256' | '512x512' | '1024x1024'
|
|
79
|
+
responseFormat?: 'url' | 'b64_json'
|
|
80
|
+
}
|
|
81
|
+
export type ImageInput = | { type: 'url'; url: string }
|
|
82
|
+
| { type: 'base64'; data: string; mediaType: string }
|
|
83
|
+
| { type: 'file'; path: string }
|