linkque-cli-v2 1.0.5 → 1.0.6
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/README.md +1 -1
- package/linkquejs.js +27 -2212
- package/package.json +4 -1
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/anthropic-messages-B5T6TFD2.js +7172 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/azure-openai-responses-S7HNQOSE.js +229 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-2NGJGNYB.js +1765 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-3S3TOEBZ.js +608 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-46SEH6ER.js +78 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-52BVDZQ2.js +60299 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-6MHDOBWO.js +12 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-6WHNFJT4.js +31278 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-7BQRUS4C.js +671 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-7QWAKKTY.js +7054 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-CT4G24PS.js +8 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-DYEQRE6N.js +343 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-E2P6TIFG.js +31 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-FHNQ6DPF.js +14 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-HTG7JBF2.js +38 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-I64V3ICJ.js +11166 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-IKZ25GJD.js +497 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-MKS245OU.js +3570 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-NKEOCGYU.js +76 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-NQM5ZCTR.js +12015 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-OXGCUIKV.js +33 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-RYONFGPP.js +317 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-UEVQXSKG.js +4765 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-UFVAKOTZ.js +17 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-VS2QQHAK.js +46 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-XMVFOHGJ.js +31 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-XUFLSZM4.js +5319 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-Y6UTJIT4.js +23 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/chunk-YDKZZ6EH.js +3584 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/dist-QD3CV4KC.js +1224 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/google-generative-ai-IOXNKFEV.js +412 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/google-vertex-U4ZV5IXZ.js +461 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/mistral-conversations-G3K7SSWR.js +30344 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/multipart-parser-2VJ7LVQD.js +170 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/multipart-parser-AJMV6U6H.js +178 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/multipart-parser-PULXGNYO.js +368 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/openai-codex-responses-4JJLPTCS.js +1308 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/openai-completions-PH4WW6E7.js +977 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/openai-responses-KGWAX6HR.js +264 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/openrouter-images-LMBZZQ76.js +138 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/otel-7GSG7QQO.js +6657 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/pi-messages-ZX3KUWSZ.js +309 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/runtime/handler/chat.js +2354 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/runtime/handler/clientCapability.js +16 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/runtime/protocol.js +17 -0
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/src-NGZW4JXI.js +1396 -0
- package/vendor/linkque-agent-appwrite-integrate/package.json +1 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import {
|
|
2
|
+
splitDeferredTools
|
|
3
|
+
} from "./chunk-HTG7JBF2.js";
|
|
4
|
+
import {
|
|
5
|
+
buildCopilotDynamicHeaders,
|
|
6
|
+
hasCopilotVisionInput
|
|
7
|
+
} from "./chunk-XMVFOHGJ.js";
|
|
8
|
+
import {
|
|
9
|
+
convertResponsesMessages,
|
|
10
|
+
convertResponsesTools,
|
|
11
|
+
processResponsesStream
|
|
12
|
+
} from "./chunk-IKZ25GJD.js";
|
|
13
|
+
import "./chunk-UFVAKOTZ.js";
|
|
14
|
+
import {
|
|
15
|
+
OpenAI
|
|
16
|
+
} from "./chunk-7QWAKKTY.js";
|
|
17
|
+
import {
|
|
18
|
+
clampOpenAIPromptCacheKey
|
|
19
|
+
} from "./chunk-FHNQ6DPF.js";
|
|
20
|
+
import {
|
|
21
|
+
formatProviderError,
|
|
22
|
+
normalizeProviderError
|
|
23
|
+
} from "./chunk-NKEOCGYU.js";
|
|
24
|
+
import {
|
|
25
|
+
buildBaseOptions
|
|
26
|
+
} from "./chunk-RYONFGPP.js";
|
|
27
|
+
import "./chunk-CT4G24PS.js";
|
|
28
|
+
import {
|
|
29
|
+
headersToRecord
|
|
30
|
+
} from "./chunk-Y6UTJIT4.js";
|
|
31
|
+
import {
|
|
32
|
+
clampThinkingLevel
|
|
33
|
+
} from "./chunk-3S3TOEBZ.js";
|
|
34
|
+
import {
|
|
35
|
+
getProviderEnvValue
|
|
36
|
+
} from "./chunk-OXGCUIKV.js";
|
|
37
|
+
import "./chunk-DYEQRE6N.js";
|
|
38
|
+
import {
|
|
39
|
+
AssistantMessageEventStream
|
|
40
|
+
} from "./chunk-46SEH6ER.js";
|
|
41
|
+
import "./chunk-VS2QQHAK.js";
|
|
42
|
+
|
|
43
|
+
// ../../node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js
|
|
44
|
+
var OPENAI_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openai-codex", "opencode"]);
|
|
45
|
+
var OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;
|
|
46
|
+
function hasHeader(headers, name) {
|
|
47
|
+
if (!headers)
|
|
48
|
+
return false;
|
|
49
|
+
const expected = name.toLowerCase();
|
|
50
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
51
|
+
if (key.toLowerCase() === expected && value !== null && value.trim().length > 0)
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
function getClientApiKey(provider, apiKey, headers) {
|
|
57
|
+
if (apiKey)
|
|
58
|
+
return apiKey;
|
|
59
|
+
if (hasHeader(headers, "authorization") || hasHeader(headers, "cf-aig-authorization"))
|
|
60
|
+
return "unused";
|
|
61
|
+
throw new Error(`No API key for provider: ${provider}`);
|
|
62
|
+
}
|
|
63
|
+
function detectSessionAffinityFormat(model) {
|
|
64
|
+
return model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai") ? "openrouter" : "openai";
|
|
65
|
+
}
|
|
66
|
+
function resolveCacheRetention(cacheRetention, env) {
|
|
67
|
+
if (cacheRetention) {
|
|
68
|
+
return cacheRetention;
|
|
69
|
+
}
|
|
70
|
+
if (getProviderEnvValue("PI_CACHE_RETENTION", env) === "long") {
|
|
71
|
+
return "long";
|
|
72
|
+
}
|
|
73
|
+
return "short";
|
|
74
|
+
}
|
|
75
|
+
function getCompat(model) {
|
|
76
|
+
return {
|
|
77
|
+
supportsDeveloperRole: model.compat?.supportsDeveloperRole ?? true,
|
|
78
|
+
sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? detectSessionAffinityFormat(model),
|
|
79
|
+
supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
|
|
80
|
+
supportsToolSearch: model.compat?.supportsToolSearch ?? false
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function getPromptCacheRetention(compat, cacheRetention) {
|
|
84
|
+
return cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : void 0;
|
|
85
|
+
}
|
|
86
|
+
function formatOpenAIResponsesError(error) {
|
|
87
|
+
return formatProviderError(normalizeProviderError(error), "OpenAI API error");
|
|
88
|
+
}
|
|
89
|
+
var stream = (model, context, options) => {
|
|
90
|
+
const stream2 = new AssistantMessageEventStream();
|
|
91
|
+
(async () => {
|
|
92
|
+
const output = {
|
|
93
|
+
role: "assistant",
|
|
94
|
+
content: [],
|
|
95
|
+
api: model.api,
|
|
96
|
+
provider: model.provider,
|
|
97
|
+
model: model.id,
|
|
98
|
+
usage: {
|
|
99
|
+
input: 0,
|
|
100
|
+
output: 0,
|
|
101
|
+
cacheRead: 0,
|
|
102
|
+
cacheWrite: 0,
|
|
103
|
+
totalTokens: 0,
|
|
104
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
105
|
+
},
|
|
106
|
+
stopReason: "stop",
|
|
107
|
+
timestamp: Date.now()
|
|
108
|
+
};
|
|
109
|
+
try {
|
|
110
|
+
const apiKey = getClientApiKey(model.provider, options?.apiKey, options?.headers);
|
|
111
|
+
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
112
|
+
const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
|
|
113
|
+
const client = createClient(model, context, apiKey, options?.headers, cacheSessionId);
|
|
114
|
+
let params = buildParams(model, context, options);
|
|
115
|
+
const nextParams = await options?.onPayload?.(params, model);
|
|
116
|
+
if (nextParams !== void 0) {
|
|
117
|
+
params = nextParams;
|
|
118
|
+
}
|
|
119
|
+
const requestOptions = {
|
|
120
|
+
...options?.signal ? { signal: options.signal } : {},
|
|
121
|
+
...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
|
|
122
|
+
maxRetries: options?.maxRetries ?? 0
|
|
123
|
+
};
|
|
124
|
+
const { data: openaiStream, response } = await client.responses.create(params, requestOptions).withResponse();
|
|
125
|
+
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
|
|
126
|
+
stream2.push({ type: "start", partial: output });
|
|
127
|
+
await processResponsesStream(openaiStream, output, stream2, model, {
|
|
128
|
+
serviceTier: options?.serviceTier,
|
|
129
|
+
applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model)
|
|
130
|
+
});
|
|
131
|
+
if (options?.signal?.aborted) {
|
|
132
|
+
throw new Error("Request was aborted");
|
|
133
|
+
}
|
|
134
|
+
if (output.stopReason === "aborted" || output.stopReason === "error") {
|
|
135
|
+
throw new Error("An unknown error occurred");
|
|
136
|
+
}
|
|
137
|
+
stream2.push({ type: "done", reason: output.stopReason, message: output });
|
|
138
|
+
stream2.end();
|
|
139
|
+
} catch (error) {
|
|
140
|
+
for (const block of output.content) {
|
|
141
|
+
delete block.index;
|
|
142
|
+
delete block.partialJson;
|
|
143
|
+
}
|
|
144
|
+
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
145
|
+
output.errorMessage = formatOpenAIResponsesError(error);
|
|
146
|
+
stream2.push({ type: "error", reason: output.stopReason, error: output });
|
|
147
|
+
stream2.end();
|
|
148
|
+
}
|
|
149
|
+
})();
|
|
150
|
+
return stream2;
|
|
151
|
+
};
|
|
152
|
+
var streamSimple = (model, context, options) => {
|
|
153
|
+
getClientApiKey(model.provider, options?.apiKey, options?.headers);
|
|
154
|
+
const base = buildBaseOptions(model, context, options, options?.apiKey);
|
|
155
|
+
const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : void 0;
|
|
156
|
+
const reasoningEffort = clampedReasoning === "off" ? void 0 : clampedReasoning;
|
|
157
|
+
return stream(model, context, {
|
|
158
|
+
...base,
|
|
159
|
+
reasoningEffort
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
function createClient(model, context, apiKey, optionsHeaders, sessionId) {
|
|
163
|
+
const compat = getCompat(model);
|
|
164
|
+
const headers = { ...model.headers };
|
|
165
|
+
if (model.provider === "github-copilot") {
|
|
166
|
+
const hasImages = hasCopilotVisionInput(context.messages);
|
|
167
|
+
const copilotHeaders = buildCopilotDynamicHeaders({
|
|
168
|
+
messages: context.messages,
|
|
169
|
+
hasImages
|
|
170
|
+
});
|
|
171
|
+
Object.assign(headers, copilotHeaders);
|
|
172
|
+
}
|
|
173
|
+
if (sessionId) {
|
|
174
|
+
if (compat.sessionAffinityFormat === "openrouter") {
|
|
175
|
+
headers["x-session-id"] = sessionId;
|
|
176
|
+
} else {
|
|
177
|
+
if (compat.sessionAffinityFormat === "openai") {
|
|
178
|
+
headers.session_id = sessionId;
|
|
179
|
+
}
|
|
180
|
+
headers["x-client-request-id"] = sessionId;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (optionsHeaders) {
|
|
184
|
+
Object.assign(headers, optionsHeaders);
|
|
185
|
+
}
|
|
186
|
+
return new OpenAI({
|
|
187
|
+
apiKey,
|
|
188
|
+
baseURL: model.baseUrl,
|
|
189
|
+
dangerouslyAllowBrowser: true,
|
|
190
|
+
defaultHeaders: headers
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function buildParams(model, context, options) {
|
|
194
|
+
const compat = getCompat(model);
|
|
195
|
+
const toolPlacement = splitDeferredTools(context, compat.supportsToolSearch);
|
|
196
|
+
const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {
|
|
197
|
+
deferredTools: toolPlacement.deferred
|
|
198
|
+
});
|
|
199
|
+
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
200
|
+
const params = {
|
|
201
|
+
model: model.id,
|
|
202
|
+
input: messages,
|
|
203
|
+
stream: true,
|
|
204
|
+
prompt_cache_key: cacheRetention === "none" ? void 0 : clampOpenAIPromptCacheKey(options?.sessionId),
|
|
205
|
+
prompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),
|
|
206
|
+
store: false
|
|
207
|
+
};
|
|
208
|
+
if (options?.maxTokens) {
|
|
209
|
+
params.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);
|
|
210
|
+
}
|
|
211
|
+
if (options?.temperature !== void 0) {
|
|
212
|
+
params.temperature = options?.temperature;
|
|
213
|
+
}
|
|
214
|
+
if (options?.serviceTier !== void 0) {
|
|
215
|
+
params.service_tier = options.serviceTier;
|
|
216
|
+
}
|
|
217
|
+
if (toolPlacement.immediate.length > 0) {
|
|
218
|
+
params.tools = convertResponsesTools(toolPlacement.immediate);
|
|
219
|
+
}
|
|
220
|
+
if (options?.toolChoice !== void 0) {
|
|
221
|
+
params.tool_choice = options.toolChoice;
|
|
222
|
+
}
|
|
223
|
+
if (model.reasoning) {
|
|
224
|
+
if (options?.reasoningEffort || options?.reasoningSummary) {
|
|
225
|
+
const effort = options?.reasoningEffort ? model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort : "medium";
|
|
226
|
+
params.reasoning = {
|
|
227
|
+
effort,
|
|
228
|
+
summary: options?.reasoningSummary || "auto"
|
|
229
|
+
};
|
|
230
|
+
params.include = ["reasoning.encrypted_content"];
|
|
231
|
+
} else if (model.provider !== "github-copilot" && model.thinkingLevelMap?.off !== null) {
|
|
232
|
+
params.reasoning = {
|
|
233
|
+
effort: model.thinkingLevelMap?.off ?? "none"
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
if (model.provider === "xai")
|
|
237
|
+
params.include = ["reasoning.encrypted_content"];
|
|
238
|
+
}
|
|
239
|
+
return params;
|
|
240
|
+
}
|
|
241
|
+
function getServiceTierCostMultiplier(model, serviceTier) {
|
|
242
|
+
switch (serviceTier) {
|
|
243
|
+
case "flex":
|
|
244
|
+
return 0.5;
|
|
245
|
+
case "priority":
|
|
246
|
+
return model.id === "gpt-5.5" ? 2.5 : 2;
|
|
247
|
+
default:
|
|
248
|
+
return 1;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function applyServiceTierPricing(usage, serviceTier, model) {
|
|
252
|
+
const multiplier = getServiceTierCostMultiplier(model, serviceTier);
|
|
253
|
+
if (multiplier === 1)
|
|
254
|
+
return;
|
|
255
|
+
usage.cost.input *= multiplier;
|
|
256
|
+
usage.cost.output *= multiplier;
|
|
257
|
+
usage.cost.cacheRead *= multiplier;
|
|
258
|
+
usage.cost.cacheWrite *= multiplier;
|
|
259
|
+
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
260
|
+
}
|
|
261
|
+
export {
|
|
262
|
+
stream,
|
|
263
|
+
streamSimple
|
|
264
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OpenAI
|
|
3
|
+
} from "./chunk-7QWAKKTY.js";
|
|
4
|
+
import {
|
|
5
|
+
formatProviderError,
|
|
6
|
+
normalizeProviderError
|
|
7
|
+
} from "./chunk-NKEOCGYU.js";
|
|
8
|
+
import {
|
|
9
|
+
sanitizeSurrogates
|
|
10
|
+
} from "./chunk-CT4G24PS.js";
|
|
11
|
+
import {
|
|
12
|
+
headersToRecord,
|
|
13
|
+
providerHeadersToRecord
|
|
14
|
+
} from "./chunk-Y6UTJIT4.js";
|
|
15
|
+
import "./chunk-VS2QQHAK.js";
|
|
16
|
+
|
|
17
|
+
// ../../node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js
|
|
18
|
+
var generateImages = async (model, context, options) => {
|
|
19
|
+
const output = {
|
|
20
|
+
api: model.api,
|
|
21
|
+
provider: model.provider,
|
|
22
|
+
model: model.id,
|
|
23
|
+
output: [],
|
|
24
|
+
stopReason: "stop",
|
|
25
|
+
timestamp: Date.now()
|
|
26
|
+
};
|
|
27
|
+
try {
|
|
28
|
+
const apiKey = options?.apiKey;
|
|
29
|
+
if (!apiKey) {
|
|
30
|
+
throw new Error(`No API key for provider: ${model.provider}`);
|
|
31
|
+
}
|
|
32
|
+
const client = createClient(model, apiKey, options?.headers);
|
|
33
|
+
let params = buildParams(model, context);
|
|
34
|
+
const nextParams = await options?.onPayload?.(params, model);
|
|
35
|
+
if (nextParams !== void 0) {
|
|
36
|
+
params = nextParams;
|
|
37
|
+
}
|
|
38
|
+
const requestOptions = {
|
|
39
|
+
...options?.signal ? { signal: options.signal } : {},
|
|
40
|
+
...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
|
|
41
|
+
maxRetries: options?.maxRetries ?? 0
|
|
42
|
+
};
|
|
43
|
+
const { data: response, response: rawResponse } = await client.chat.completions.create(params, requestOptions).withResponse();
|
|
44
|
+
await options?.onResponse?.({ status: rawResponse.status, headers: headersToRecord(rawResponse.headers) }, model);
|
|
45
|
+
const imageResponse = response;
|
|
46
|
+
output.responseId = imageResponse.id;
|
|
47
|
+
if (imageResponse.usage) {
|
|
48
|
+
output.usage = parseUsage(imageResponse.usage, model);
|
|
49
|
+
}
|
|
50
|
+
const choice = imageResponse.choices[0];
|
|
51
|
+
if (choice) {
|
|
52
|
+
const content = choice.message.content;
|
|
53
|
+
if (typeof content === "string" && content.length > 0) {
|
|
54
|
+
output.output.push({ type: "text", text: content });
|
|
55
|
+
}
|
|
56
|
+
for (const image of choice.message.images ?? []) {
|
|
57
|
+
const imageUrl = typeof image.image_url === "string" ? image.image_url : image.image_url?.url;
|
|
58
|
+
if (!imageUrl?.startsWith("data:"))
|
|
59
|
+
continue;
|
|
60
|
+
const matches = imageUrl.match(/^data:([^;]+);base64,(.+)$/);
|
|
61
|
+
if (!matches)
|
|
62
|
+
continue;
|
|
63
|
+
output.output.push({
|
|
64
|
+
type: "image",
|
|
65
|
+
mimeType: matches[1],
|
|
66
|
+
data: matches[2]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return output;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
73
|
+
output.errorMessage = formatProviderError(normalizeProviderError(error));
|
|
74
|
+
return output;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
function createClient(model, apiKey, optionsHeaders) {
|
|
78
|
+
return new OpenAI({
|
|
79
|
+
apiKey,
|
|
80
|
+
baseURL: model.baseUrl,
|
|
81
|
+
dangerouslyAllowBrowser: true,
|
|
82
|
+
defaultHeaders: providerHeadersToRecord({ ...model.headers, ...optionsHeaders })
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function buildParams(model, context) {
|
|
86
|
+
const content = context.input.map((item) => {
|
|
87
|
+
if (item.type === "text") {
|
|
88
|
+
return {
|
|
89
|
+
type: "text",
|
|
90
|
+
text: sanitizeSurrogates(item.text)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
type: "image_url",
|
|
95
|
+
image_url: {
|
|
96
|
+
url: `data:${item.mimeType};base64,${item.data}`
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
model: model.id,
|
|
102
|
+
messages: [
|
|
103
|
+
{
|
|
104
|
+
role: "user",
|
|
105
|
+
content
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
stream: false,
|
|
109
|
+
modalities: model.output.includes("text") ? ["image", "text"] : ["image"]
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function parseUsage(rawUsage, model) {
|
|
113
|
+
const promptTokens = rawUsage.prompt_tokens || 0;
|
|
114
|
+
const reportedCachedTokens = rawUsage.prompt_tokens_details?.cached_tokens || 0;
|
|
115
|
+
const cacheWriteTokens = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
|
|
116
|
+
const cacheReadTokens = cacheWriteTokens > 0 ? Math.max(0, reportedCachedTokens - cacheWriteTokens) : reportedCachedTokens;
|
|
117
|
+
const input = Math.max(0, promptTokens - cacheReadTokens - cacheWriteTokens);
|
|
118
|
+
const output = rawUsage.completion_tokens || 0;
|
|
119
|
+
const usage = {
|
|
120
|
+
input,
|
|
121
|
+
output,
|
|
122
|
+
cacheRead: cacheReadTokens,
|
|
123
|
+
cacheWrite: cacheWriteTokens,
|
|
124
|
+
totalTokens: input + output + cacheReadTokens + cacheWriteTokens,
|
|
125
|
+
cost: {
|
|
126
|
+
input: model.cost.input / 1e6 * input,
|
|
127
|
+
output: model.cost.output / 1e6 * output,
|
|
128
|
+
cacheRead: model.cost.cacheRead / 1e6 * cacheReadTokens,
|
|
129
|
+
cacheWrite: model.cost.cacheWrite / 1e6 * cacheWriteTokens,
|
|
130
|
+
total: 0
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
134
|
+
return usage;
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
generateImages
|
|
138
|
+
};
|