@vibedev-si/dsh-vibedev 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +155 -0
  3. package/THIRD-PARTY-NOTICES.txt +566 -0
  4. package/client/client.js +1368 -0
  5. package/cordis.patch.yml +5 -0
  6. package/icon.svg +7 -0
  7. package/lib/account/index.d.ts +118 -0
  8. package/lib/anthropic-messages-KOS0z8Fy.js +13472 -0
  9. package/lib/auth/credentials.d.ts +47 -0
  10. package/lib/auth/login.d.ts +154 -0
  11. package/lib/gateway/assets.d.ts +61 -0
  12. package/lib/gateway/catalog.d.ts +126 -0
  13. package/lib/gateway/errors.d.ts +76 -0
  14. package/lib/gateway/http.d.ts +94 -0
  15. package/lib/index.d.ts +105 -0
  16. package/lib/index.js +7301 -0
  17. package/lib/llm/adapter.d.ts +129 -0
  18. package/lib/llm/catalog.d.ts +75 -0
  19. package/lib/llm/context.d.ts +54 -0
  20. package/lib/llm/index.d.ts +69 -0
  21. package/lib/llm/limits.d.ts +19 -0
  22. package/lib/llm/models.d.ts +67 -0
  23. package/lib/llm/replay.d.ts +66 -0
  24. package/lib/llm/stream.d.ts +46 -0
  25. package/lib/media/chat.d.ts +49 -0
  26. package/lib/media/sources.d.ts +46 -0
  27. package/lib/models-CAcLevEN.js +1045 -0
  28. package/lib/node-Cujw_a4_.js +2403 -0
  29. package/lib/node-vkDR3GtK.js +25 -0
  30. package/lib/openai-completions-DqTCiqpS.js +983 -0
  31. package/lib/openai-prompt-cache-kzRZVokq.js +9567 -0
  32. package/lib/openai-responses-DygWnsye.js +832 -0
  33. package/lib/pricing.d.ts +49 -0
  34. package/lib/runtime.d.ts +150 -0
  35. package/lib/search/provider.d.ts +86 -0
  36. package/lib/service.d.ts +99 -0
  37. package/lib/tasks/remote.d.ts +47 -0
  38. package/lib/tasks/store.d.ts +132 -0
  39. package/lib/tasks/tracker.d.ts +127 -0
  40. package/lib/tools/account.d.ts +21 -0
  41. package/lib/tools/audio.d.ts +13 -0
  42. package/lib/tools/common.d.ts +77 -0
  43. package/lib/tools/image.d.ts +50 -0
  44. package/lib/tools/models.d.ts +13 -0
  45. package/lib/tools/tasks.d.ts +13 -0
  46. package/lib/tools/transcribe.d.ts +19 -0
  47. package/lib/tools/video.d.ts +48 -0
  48. package/lib/transform-messages-Csvf2ItW.js +1023 -0
  49. package/lib/util/files.d.ts +80 -0
  50. package/lib/video/plan.d.ts +96 -0
  51. package/locale/en.json +6 -0
  52. package/locale/zh.json +6 -0
  53. package/package.json +127 -0
@@ -0,0 +1,1045 @@
1
+ //#region node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js
2
+ var FifoQueue = class {
3
+ incoming = [];
4
+ outgoing = [];
5
+ get length() {
6
+ return this.incoming.length + this.outgoing.length;
7
+ }
8
+ enqueue(value) {
9
+ this.incoming.push(value);
10
+ }
11
+ dequeue() {
12
+ if (this.outgoing.length === 0) while (this.incoming.length > 0) this.outgoing.push(this.incoming.pop());
13
+ return this.outgoing.pop();
14
+ }
15
+ };
16
+ var EventStream = class {
17
+ queue = new FifoQueue();
18
+ waiting = new FifoQueue();
19
+ done = false;
20
+ finalResultPromise;
21
+ resolveFinalResult;
22
+ isComplete;
23
+ extractResult;
24
+ constructor(isComplete, extractResult) {
25
+ this.isComplete = isComplete;
26
+ this.extractResult = extractResult;
27
+ this.finalResultPromise = new Promise((resolve) => {
28
+ this.resolveFinalResult = resolve;
29
+ });
30
+ }
31
+ push(event) {
32
+ if (this.done) return;
33
+ if (this.isComplete(event)) {
34
+ this.done = true;
35
+ this.resolveFinalResult(this.extractResult(event));
36
+ }
37
+ const waiter = this.waiting.dequeue();
38
+ if (waiter) waiter({
39
+ value: event,
40
+ done: false
41
+ });
42
+ else this.queue.enqueue(event);
43
+ }
44
+ end(result) {
45
+ this.done = true;
46
+ if (result !== void 0) this.resolveFinalResult(result);
47
+ while (this.waiting.length > 0) this.waiting.dequeue()({
48
+ value: void 0,
49
+ done: true
50
+ });
51
+ }
52
+ async *[Symbol.asyncIterator]() {
53
+ while (true) if (this.queue.length > 0) yield this.queue.dequeue();
54
+ else if (this.done) return;
55
+ else {
56
+ const result = await new Promise((resolve) => this.waiting.enqueue(resolve));
57
+ if (result.done) return;
58
+ yield result.value;
59
+ }
60
+ }
61
+ result() {
62
+ return this.finalResultPromise;
63
+ }
64
+ };
65
+ var AssistantMessageEventStream = class extends EventStream {
66
+ constructor() {
67
+ super((event) => event.type === "done" || event.type === "error", (event) => {
68
+ if (event.type === "done") return event.message;
69
+ else if (event.type === "error") return event.error;
70
+ throw new Error("Unexpected event type for final result");
71
+ });
72
+ }
73
+ };
74
+ //#endregion
75
+ //#region node_modules/@earendil-works/pi-ai/dist/api/lazy.js
76
+ function createSetupErrorMessage(model, error) {
77
+ return {
78
+ role: "assistant",
79
+ content: [],
80
+ api: model.api,
81
+ provider: model.provider,
82
+ model: model.id,
83
+ usage: {
84
+ input: 0,
85
+ output: 0,
86
+ cacheRead: 0,
87
+ cacheWrite: 0,
88
+ totalTokens: 0,
89
+ cost: {
90
+ input: 0,
91
+ output: 0,
92
+ cacheRead: 0,
93
+ cacheWrite: 0,
94
+ total: 0
95
+ }
96
+ },
97
+ stopReason: "error",
98
+ errorMessage: error instanceof Error ? error.message : String(error),
99
+ timestamp: Date.now()
100
+ };
101
+ }
102
+ function hasResult(source) {
103
+ return typeof source.result === "function";
104
+ }
105
+ async function forwardStream(target, source) {
106
+ for await (const event of source) target.push(event);
107
+ target.end(hasResult(source) ? await source.result() : void 0);
108
+ }
109
+ /**
110
+ * Returns a stream synchronously while running async setup (auth resolution,
111
+ * lazy module loading) behind it. Setup failures terminate the stream with an
112
+ * error event.
113
+ */
114
+ function lazyStream(model, setup) {
115
+ const outer = new AssistantMessageEventStream();
116
+ setup().then((inner) => forwardStream(outer, inner)).catch((error) => {
117
+ const message = createSetupErrorMessage(model, error);
118
+ outer.push({
119
+ type: "error",
120
+ reason: "error",
121
+ error: message
122
+ });
123
+ outer.end(message);
124
+ });
125
+ return outer;
126
+ }
127
+ function lazyApi(load, capabilities) {
128
+ const api = {
129
+ stream: (model, context, options) => lazyStream(model, async () => (await load()).stream(model, context, options)),
130
+ streamSimple: (model, context, options) => lazyStream(model, async () => (await load()).streamSimple(model, context, options))
131
+ };
132
+ if (capabilities?.fetchDeferred) api.fetchDeferred = (model, handle, options) => lazyStream(model, async () => {
133
+ const implementation = await load();
134
+ if (!implementation.fetchDeferred) throw new Error("API does not support deferred responses");
135
+ return implementation.fetchDeferred(model, handle, options);
136
+ });
137
+ if (capabilities?.cancelDeferred) api.cancelDeferred = async (model, handle, options) => {
138
+ const implementation = await load();
139
+ if (!implementation.cancelDeferred) throw new Error("API cannot cancel deferred responses");
140
+ await implementation.cancelDeferred(model, handle, options);
141
+ };
142
+ return api;
143
+ }
144
+ //#endregion
145
+ //#region node_modules/@earendil-works/pi-ai/dist/auth/context.js
146
+ var __rewriteRelativeImportExtension = function(path, preserveJsx) {
147
+ if (typeof path === "string" && /^\.\.?\//.test(path)) return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
148
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
149
+ });
150
+ return path;
151
+ };
152
+ const importNodeModule = (specifier) => import(__rewriteRelativeImportExtension(specifier));
153
+ function getProcessEnv() {
154
+ return globalThis.process?.env;
155
+ }
156
+ /**
157
+ * Default auth context: env vars from `process.env` (undefined in browsers),
158
+ * file existence via node:fs (always false in browsers).
159
+ */
160
+ function defaultProviderAuthContext() {
161
+ return {
162
+ async env(name) {
163
+ const value = getProcessEnv()?.[name];
164
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
165
+ },
166
+ async fileExists(path) {
167
+ try {
168
+ const fs = await importNodeModule("node:fs/promises");
169
+ let resolved = path;
170
+ if (resolved.startsWith("~")) resolved = (await importNodeModule("node:os")).homedir() + resolved.slice(1);
171
+ await fs.access(resolved);
172
+ return true;
173
+ } catch {
174
+ return false;
175
+ }
176
+ }
177
+ };
178
+ }
179
+ //#endregion
180
+ //#region node_modules/@earendil-works/pi-ai/dist/utils/abort.js
181
+ function abortReason(signal) {
182
+ if (signal.reason !== void 0) return signal.reason;
183
+ const error = /* @__PURE__ */ new Error("The operation was aborted");
184
+ error.name = "AbortError";
185
+ return error;
186
+ }
187
+ /** Create an operation-local signal for public APIs whose signal is optional. */
188
+ function operationSignal(signal) {
189
+ return signal ?? new AbortController().signal;
190
+ }
191
+ /**
192
+ * Stop waiting for an operation when its signal aborts while continuing to
193
+ * observe the abandoned promise so a later rejection is always handled.
194
+ */
195
+ function raceWithAbortSignal(operation, signal) {
196
+ if (signal.aborted) {
197
+ operation.catch(() => {});
198
+ return Promise.reject(abortReason(signal));
199
+ }
200
+ return new Promise((resolve, reject) => {
201
+ let settled = false;
202
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
203
+ const onAbort = () => {
204
+ if (settled) return;
205
+ settled = true;
206
+ cleanup();
207
+ reject(abortReason(signal));
208
+ };
209
+ signal.addEventListener("abort", onAbort, { once: true });
210
+ operation.then((value) => {
211
+ if (settled) return;
212
+ settled = true;
213
+ cleanup();
214
+ resolve(value);
215
+ }, (error) => {
216
+ if (settled) return;
217
+ settled = true;
218
+ cleanup();
219
+ reject(error);
220
+ });
221
+ if (signal.aborted) onAbort();
222
+ });
223
+ }
224
+ //#endregion
225
+ //#region node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js
226
+ /**
227
+ * Default in-memory credential store. Apps inject persistent stores.
228
+ * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
229
+ * Writes are serialized per provider through a promise chain.
230
+ */
231
+ var InMemoryCredentialStore = class {
232
+ credentials = /* @__PURE__ */ new Map();
233
+ chains = /* @__PURE__ */ new Map();
234
+ /** Serialize tasks per provider id without releasing the chain before active work settles. */
235
+ enqueue(providerId, task, options) {
236
+ const signal = operationSignal(options?.signal);
237
+ const previous = this.chains.get(providerId) ?? Promise.resolve();
238
+ const queued = (async () => {
239
+ await previous.catch(() => {});
240
+ signal.throwIfAborted();
241
+ return task();
242
+ })();
243
+ const tail = queued.catch(() => {});
244
+ this.chains.set(providerId, tail);
245
+ tail.then(() => {
246
+ if (this.chains.get(providerId) === tail) this.chains.delete(providerId);
247
+ });
248
+ return raceWithAbortSignal(queued, signal);
249
+ }
250
+ async read(providerId, options) {
251
+ options?.signal?.throwIfAborted();
252
+ return this.credentials.get(providerId);
253
+ }
254
+ async list(options) {
255
+ options?.signal?.throwIfAborted();
256
+ return [...this.credentials].map(([providerId, credential]) => ({
257
+ providerId,
258
+ type: credential.type
259
+ }));
260
+ }
261
+ modify(providerId, fn, options) {
262
+ return this.enqueue(providerId, async () => {
263
+ const current = this.credentials.get(providerId);
264
+ const next = await fn(current);
265
+ options?.signal?.throwIfAborted();
266
+ if (next !== void 0) this.credentials.set(providerId, next);
267
+ return next ?? current;
268
+ }, options);
269
+ }
270
+ delete(providerId, options) {
271
+ return this.enqueue(providerId, async () => {
272
+ this.credentials.delete(providerId);
273
+ }, options);
274
+ }
275
+ };
276
+ //#endregion
277
+ //#region node_modules/@earendil-works/pi-ai/dist/utils/diagnostics.js
278
+ function formatThrownValue(value) {
279
+ if (value instanceof Error) return value.message || value.name;
280
+ if (typeof value === "string") return value;
281
+ return String(value);
282
+ }
283
+ function appendAssistantMessageDiagnostic(message, diagnostic) {
284
+ message.diagnostics = [...message.diagnostics ?? [], diagnostic];
285
+ }
286
+ //#endregion
287
+ //#region node_modules/@earendil-works/pi-ai/dist/auth/resolve.js
288
+ var ModelsError = class extends Error {
289
+ code;
290
+ constructor(code, message, options) {
291
+ super(withCauseDetail(message, options?.cause), options);
292
+ this.name = "ModelsError";
293
+ this.code = code;
294
+ }
295
+ };
296
+ /** Callers surface `error.message` only, so keep the underlying reason in it. */
297
+ function withCauseDetail(message, cause) {
298
+ if (cause === void 0 || cause === null) return message;
299
+ const detail = formatThrownValue(cause).trim();
300
+ if (!detail || message.includes(detail)) return message;
301
+ return `${message}: ${detail}`;
302
+ }
303
+ /**
304
+ * Auth resolution shared by the `Models` and `ImagesModels` collections.
305
+ * A stored credential owns the provider: ambient/env is consulted only when
306
+ * nothing is stored. No silent env fallback after a failed refresh or for a
307
+ * credential type without a matching handler.
308
+ */
309
+ function resolveProviderAuth(provider, credentials, authContext, overrides) {
310
+ const signal = operationSignal(overrides?.signal);
311
+ return raceWithAbortSignal(resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal), signal);
312
+ }
313
+ async function resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal) {
314
+ signal.throwIfAborted();
315
+ const requestAuthContext = overrides?.env ? overlayEnvAuthContext(authContext, overrides.env) : authContext;
316
+ if (overrides?.apiKey !== void 0 && provider.auth.apiKey) return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, {
317
+ type: "api_key",
318
+ key: overrides.apiKey,
319
+ env: overrides.env
320
+ }, signal);
321
+ const stored = await readCredential(credentials, provider.id, signal);
322
+ if (stored) {
323
+ if (stored.type === "oauth" && provider.auth.oauth) return resolveStoredOAuth(credentials, provider.id, provider.auth.oauth, stored, signal, overrides?.minOAuthValidityMs);
324
+ if (stored.type === "api_key" && provider.auth.apiKey) {
325
+ const credential = overrides?.env ? {
326
+ ...stored,
327
+ env: {
328
+ ...stored.env,
329
+ ...overrides.env
330
+ }
331
+ } : stored;
332
+ return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);
333
+ }
334
+ return;
335
+ }
336
+ return provider.auth.apiKey ? resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, void 0, signal) : void 0;
337
+ }
338
+ function overlayEnvAuthContext(base, env) {
339
+ return {
340
+ env: async (name) => env[name] || await base.env(name),
341
+ fileExists: (path) => base.fileExists(path)
342
+ };
343
+ }
344
+ const DEFAULT_OAUTH_MINIMUM_VALIDITY_MS = 3e5;
345
+ const DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15e3;
346
+ /**
347
+ * OAuth resolution with double-checked locking: tokens with less than five
348
+ * minutes remaining lock, re-check expiry under the lock, refresh once
349
+ * globally, and persist the rotated credential before release.
350
+ */
351
+ async function resolveStoredOAuth(credentials, providerId, oauth, stored, signal, minOAuthValidityMs) {
352
+ const minimumValidityMs = Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS, minOAuthValidityMs ?? 0);
353
+ const expiresSoon = (credential) => Date.now() + minimumValidityMs >= credential.expires;
354
+ let credential = stored;
355
+ if (expiresSoon(credential)) {
356
+ let post;
357
+ try {
358
+ post = await credentials.modify(providerId, async (current) => {
359
+ if (current?.type !== "oauth") return void 0;
360
+ if (!expiresSoon(current)) return void 0;
361
+ try {
362
+ const refreshSignal = AbortSignal.any([signal, AbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS)]);
363
+ return await oauth.refresh(current, refreshSignal);
364
+ } catch (error) {
365
+ throw new ModelsError("oauth", `OAuth refresh failed for ${providerId}`, { cause: error });
366
+ }
367
+ }, { signal });
368
+ } catch (error) {
369
+ if (error instanceof ModelsError) throw error;
370
+ throw new ModelsError("auth", `Credential store modify failed for ${providerId}`, { cause: error });
371
+ }
372
+ if (post?.type !== "oauth") return void 0;
373
+ credential = post;
374
+ if (minOAuthValidityMs !== void 0 && expiresSoon(credential)) throw new ModelsError("oauth", `OAuth refresh returned a token that expires too soon for ${providerId}`);
375
+ }
376
+ try {
377
+ return {
378
+ auth: await oauth.toAuth(credential),
379
+ source: "OAuth"
380
+ };
381
+ } catch (error) {
382
+ throw new ModelsError("oauth", `OAuth auth derivation failed for ${providerId}`, { cause: error });
383
+ }
384
+ }
385
+ async function resolveApiKey(authContext, apiKey, providerId, credential, signal) {
386
+ try {
387
+ return await apiKey.resolve({
388
+ ctx: authContext,
389
+ credential,
390
+ signal
391
+ });
392
+ } catch (error) {
393
+ throw new ModelsError("auth", `API key auth failed for provider ${providerId}`, { cause: error });
394
+ }
395
+ }
396
+ async function readCredential(credentials, providerId, signal) {
397
+ try {
398
+ return await credentials.read(providerId, { signal });
399
+ } catch (error) {
400
+ throw new ModelsError("auth", `Credential store read failed for ${providerId}`, { cause: error });
401
+ }
402
+ }
403
+ //#endregion
404
+ //#region node_modules/@earendil-works/pi-ai/dist/models-store.js
405
+ var InMemoryModelsStore = class {
406
+ entries = /* @__PURE__ */ new Map();
407
+ async read(providerId, options) {
408
+ options?.signal?.throwIfAborted();
409
+ const entry = this.entries.get(providerId);
410
+ return entry ? structuredClone(entry) : void 0;
411
+ }
412
+ async write(providerId, entry, options) {
413
+ options?.signal?.throwIfAborted();
414
+ this.entries.set(providerId, structuredClone(entry));
415
+ }
416
+ async delete(providerId, options) {
417
+ options?.signal?.throwIfAborted();
418
+ this.entries.delete(providerId);
419
+ }
420
+ };
421
+ //#endregion
422
+ //#region node_modules/@earendil-works/pi-ai/dist/utils/text.js
423
+ /** Extract and join text from message content. */
424
+ function contentText(content, separator = "\n") {
425
+ if (typeof content === "string") return content;
426
+ return content.filter((block) => block.type === "text").map((block) => block.text).join(separator);
427
+ }
428
+ /** Render a system message as a complete prompt: its content followed by its sections. */
429
+ function getSystemMessageText(message) {
430
+ const parts = [contentText(message.content)];
431
+ for (const text of Object.values(message.sections ?? {})) if (text !== null) parts.push(text);
432
+ return parts.filter((part) => part.length > 0).join("\n\n");
433
+ }
434
+ /**
435
+ * Render a later system message for APIs that accept system messages mid-conversation.
436
+ * Section changes are framed by name so the model can relate them to the leading prompt.
437
+ * This framing is request-time only and may change between versions.
438
+ */
439
+ function renderSystemMessageUpdate(message) {
440
+ const parts = [];
441
+ const text = contentText(message.content);
442
+ if (text.length > 0) parts.push(text);
443
+ for (const [name, value] of Object.entries(message.sections ?? {})) parts.push(value === null ? `Removed system prompt section "${name}".` : `Updated system prompt section "${name}":\n\n${value}`);
444
+ return parts.join("\n\n");
445
+ }
446
+ //#endregion
447
+ //#region node_modules/@earendil-works/pi-ai/dist/utils/transcript.js
448
+ /**
449
+ * Build the leading system message for a prompt and tool set. Returns undefined when
450
+ * both are empty, so an empty transcript stays empty.
451
+ */
452
+ function createInitialSystemMessage(systemPrompt, tools) {
453
+ const hasSystemPrompt = systemPrompt !== void 0 && systemPrompt.length > 0;
454
+ const hasTools = tools !== void 0 && tools.length > 0;
455
+ if (!hasSystemPrompt && !hasTools) return void 0;
456
+ return {
457
+ role: "system",
458
+ content: systemPrompt ?? "",
459
+ ...hasTools ? { toolsAdded: tools } : {},
460
+ timestamp: 0
461
+ };
462
+ }
463
+ /**
464
+ * Fold `Context.systemPrompt` and `Context.tools` into a leading system message.
465
+ * This is the only entry point that produces a {@link TranscriptContext}; every
466
+ * provider-facing function expects the result.
467
+ */
468
+ function normalizeContext(context) {
469
+ const initialMessage = createInitialSystemMessage(context.systemPrompt, context.tools);
470
+ return { messages: initialMessage ? [initialMessage, ...context.messages] : context.messages };
471
+ }
472
+ function isSystemMessage(message) {
473
+ return message.role === "system";
474
+ }
475
+ /** Return the leading system message, if the transcript starts with one. */
476
+ function getInitialSystemMessage(messages) {
477
+ const first = messages[0];
478
+ return first && isSystemMessage(first) ? first : void 0;
479
+ }
480
+ /** Resolve the tools available after applying every transcript delta in order. */
481
+ function getCurrentTools(messages) {
482
+ const tools = /* @__PURE__ */ new Map();
483
+ for (const message of messages) {
484
+ if (!isSystemMessage(message)) continue;
485
+ for (const tool of message.toolsRemoved ?? []) tools.delete(tool.name);
486
+ for (const tool of message.toolsAdded ?? []) tools.set(tool.name, tool);
487
+ }
488
+ return [...tools.values()];
489
+ }
490
+ /**
491
+ * Replay every system message into one leading system message holding the current
492
+ * prompt and tools. Later `content` is appended to the base prompt, `sections` are
493
+ * patched by name, and tools are resolved with {@link getCurrentTools}.
494
+ */
495
+ function getCurrentSystemMessage(messages) {
496
+ const content = [];
497
+ const sections = /* @__PURE__ */ new Map();
498
+ let timestamp;
499
+ for (const message of messages) {
500
+ if (!isSystemMessage(message)) continue;
501
+ timestamp ??= message.timestamp;
502
+ const text = contentText(message.content);
503
+ if (text.length > 0) content.push(text);
504
+ for (const [name, value] of Object.entries(message.sections ?? {})) if (value === null) sections.delete(name);
505
+ else sections.set(name, value);
506
+ }
507
+ const tools = getCurrentTools(messages);
508
+ if (timestamp === void 0 && tools.length === 0) return void 0;
509
+ return {
510
+ role: "system",
511
+ content: content.join("\n\n"),
512
+ ...sections.size > 0 ? { sections: Object.fromEntries(sections) } : {},
513
+ ...tools.length > 0 ? { toolsAdded: tools } : {},
514
+ timestamp: timestamp ?? 0
515
+ };
516
+ }
517
+ /**
518
+ * Rebuild the transcript for APIs without mid-conversation system messages: the replayed
519
+ * system message leads, and every later system message is dropped.
520
+ */
521
+ function collapseSystemMessages(context) {
522
+ const head = getCurrentSystemMessage(context.messages);
523
+ const messages = context.messages.filter((message) => message.role !== "system");
524
+ return { messages: head ? [head, ...messages] : messages };
525
+ }
526
+ /** Keep later system messages in place when the model accepts them; otherwise collapse them. */
527
+ function resolveTranscript(context, supportsMidConvoSystemMessages) {
528
+ return supportsMidConvoSystemMessages ? context : collapseSystemMessages(context);
529
+ }
530
+ /** Strip executable and display-only fields from a tool before transcript comparison or persistence. */
531
+ function toToolDeclaration(tool) {
532
+ return {
533
+ name: tool.name,
534
+ description: tool.description,
535
+ parameters: JSON.parse(JSON.stringify(tool.parameters)),
536
+ ...tool.constrainedSampling === void 0 ? {} : { constrainedSampling: tool.constrainedSampling }
537
+ };
538
+ }
539
+ /**
540
+ * Whether two tools declare the same interface to the model.
541
+ *
542
+ * Both sides go through {@link toToolDeclaration} first: its JSON round-trip drops the
543
+ * typebox symbol keys and `undefined` fields that a structural comparison would see, and
544
+ * builds both objects with the same key order, so comparing the serialized declarations
545
+ * is exact. This avoids a deep-equal dependency in a browser-safe package.
546
+ */
547
+ function declarationsEqual(left, right) {
548
+ return JSON.stringify(toToolDeclaration(left)) === JSON.stringify(toToolDeclaration(right));
549
+ }
550
+ /** Every definition referenced by transcript tool state, in first-declaration order. */
551
+ function getDeclaredTools(messages) {
552
+ const definitions = /* @__PURE__ */ new Map();
553
+ for (const message of messages) {
554
+ if (!isSystemMessage(message)) continue;
555
+ for (const tool of message.toolsAdded ?? []) definitions.set(tool.name, tool);
556
+ }
557
+ return [...definitions.values()];
558
+ }
559
+ /**
560
+ * Whether a tool name was declared twice with different definitions. Transports that
561
+ * reference tools by name (Anthropic `tool_addition`/`tool_removal`) cannot express that.
562
+ */
563
+ function hasToolRedefinitions(messages) {
564
+ const declared = /* @__PURE__ */ new Map();
565
+ for (const message of messages) {
566
+ if (!isSystemMessage(message)) continue;
567
+ for (const tool of message.toolsAdded ?? []) {
568
+ const previous = declared.get(tool.name);
569
+ if (previous !== void 0 && !declarationsEqual(previous, tool)) return true;
570
+ declared.set(tool.name, tool);
571
+ }
572
+ }
573
+ return false;
574
+ }
575
+ /** Whether tool history contains a removal or same-name redeclaration that an addition-only transport cannot replay. */
576
+ function hasNonAdditiveToolChanges(messages) {
577
+ const declared = /* @__PURE__ */ new Set();
578
+ for (const message of messages) {
579
+ if (!isSystemMessage(message)) continue;
580
+ if ((message.toolsRemoved?.length ?? 0) > 0) return true;
581
+ for (const tool of message.toolsAdded ?? []) {
582
+ if (declared.has(tool.name)) return true;
583
+ declared.add(tool.name);
584
+ }
585
+ }
586
+ return false;
587
+ }
588
+ /**
589
+ * Split tool declarations between the top-level request field and in-place additions.
590
+ * Transports that can anchor additions at a system message keep the initial tools at the
591
+ * top and load later ones where they appear; that only works when no tool was removed or
592
+ * redeclared, so everything else sends the current tool list.
593
+ */
594
+ function resolveTranscriptTools(messages, supportsToolAdditions) {
595
+ const anchorsAdditions = supportsToolAdditions && !hasNonAdditiveToolChanges(messages);
596
+ return {
597
+ requestTools: anchorsAdditions ? getInitialSystemMessage(messages)?.toolsAdded ?? [] : getCurrentTools(messages),
598
+ anchorsAdditions
599
+ };
600
+ }
601
+ //#endregion
602
+ //#region node_modules/@earendil-works/pi-ai/dist/models.js
603
+ function mergeHeaders(base, override) {
604
+ if (!base && !override) return void 0;
605
+ const merged = { ...base };
606
+ for (const [name, value] of Object.entries(override ?? {})) {
607
+ const lowerName = name.toLowerCase();
608
+ for (const existingName of Object.keys(merged)) if (existingName.toLowerCase() === lowerName) delete merged[existingName];
609
+ merged[name] = value;
610
+ }
611
+ return merged;
612
+ }
613
+ var ModelsImpl = class {
614
+ providers = /* @__PURE__ */ new Map();
615
+ credentials;
616
+ modelsStore;
617
+ authContext;
618
+ refreshGenerations = /* @__PURE__ */ new Map();
619
+ refreshControllers = /* @__PURE__ */ new Map();
620
+ publicationChains = /* @__PURE__ */ new Map();
621
+ constructor(options) {
622
+ this.credentials = options?.credentials ?? new InMemoryCredentialStore();
623
+ this.modelsStore = options?.modelsStore ?? new InMemoryModelsStore();
624
+ this.authContext = options?.authContext ?? defaultProviderAuthContext();
625
+ }
626
+ setProvider(provider) {
627
+ this.supersedeProviderRefresh(provider.id);
628
+ this.providers.set(provider.id, provider);
629
+ }
630
+ deleteProvider(id) {
631
+ this.supersedeProviderRefresh(id);
632
+ this.providers.delete(id);
633
+ }
634
+ clearProviders() {
635
+ for (const id of /* @__PURE__ */ new Set([...this.providers.keys(), ...this.refreshControllers.keys()])) this.supersedeProviderRefresh(id);
636
+ this.providers.clear();
637
+ }
638
+ getProviders() {
639
+ return Array.from(this.providers.values());
640
+ }
641
+ getProvider(id) {
642
+ return this.providers.get(id);
643
+ }
644
+ getModels(provider) {
645
+ if (provider !== void 0) {
646
+ const entry = this.providers.get(provider);
647
+ if (!entry) return [];
648
+ try {
649
+ return entry.getModels();
650
+ } catch {
651
+ return [];
652
+ }
653
+ }
654
+ const models = [];
655
+ for (const entry of this.providers.values()) try {
656
+ models.push(...entry.getModels());
657
+ } catch {}
658
+ return models;
659
+ }
660
+ getModel(provider, id) {
661
+ return this.getModels(provider).find((model) => model.id === id);
662
+ }
663
+ supersedeProviderRefresh(providerId) {
664
+ const generation = (this.refreshGenerations.get(providerId) ?? 0) + 1;
665
+ this.refreshGenerations.set(providerId, generation);
666
+ const previous = this.refreshControllers.get(providerId);
667
+ if (previous) {
668
+ this.refreshControllers.delete(providerId);
669
+ previous.abort();
670
+ }
671
+ return generation;
672
+ }
673
+ beginProviderRefresh(providerId) {
674
+ const generation = this.supersedeProviderRefresh(providerId);
675
+ const controller = new AbortController();
676
+ this.refreshControllers.set(providerId, controller);
677
+ return {
678
+ generation,
679
+ controller
680
+ };
681
+ }
682
+ publishProviderModels(providerId, generation, signal, publication) {
683
+ const previous = this.publicationChains.get(providerId) ?? Promise.resolve();
684
+ const queued = (async () => {
685
+ await previous.catch(() => {});
686
+ if (signal.aborted || this.refreshGenerations.get(providerId) !== generation) return false;
687
+ if (publication.persist === null) await this.modelsStore.delete(providerId, { signal });
688
+ else if (publication.persist !== void 0) await this.modelsStore.write(providerId, structuredClone(publication.persist), { signal });
689
+ if (signal.aborted || this.refreshGenerations.get(providerId) !== generation) return false;
690
+ publication.update?.();
691
+ return true;
692
+ })();
693
+ const tail = queued.catch(() => {});
694
+ this.publicationChains.set(providerId, tail);
695
+ tail.then(() => {
696
+ if (this.publicationChains.get(providerId) === tail) this.publicationChains.delete(providerId);
697
+ });
698
+ return raceWithAbortSignal(queued, signal);
699
+ }
700
+ async runProviderRefreshPhase(provider, credential, allowNetwork, force, generation, signal) {
701
+ const stored = await this.modelsStore.read(provider.id, { signal });
702
+ await provider.refreshModels({
703
+ credential,
704
+ stored: stored ? structuredClone(stored) : void 0,
705
+ publish: (publication) => this.publishProviderModels(provider.id, generation, signal, publication),
706
+ allowNetwork,
707
+ force: allowNetwork ? force : void 0,
708
+ signal
709
+ });
710
+ }
711
+ async refresh(options = {}) {
712
+ const allowNetwork = options.allowNetwork ?? true;
713
+ const callerSignal = operationSignal(options.signal);
714
+ const errors = /* @__PURE__ */ new Map();
715
+ if (callerSignal.aborted) return {
716
+ aborted: true,
717
+ errors
718
+ };
719
+ const selected = options.providers ? new Set(options.providers) : void 0;
720
+ const refreshable = Array.from(this.providers.values()).filter((provider) => provider.refreshModels !== void 0 && (!selected || selected.has(provider.id)));
721
+ const refresh = Promise.all(refreshable.map(async (provider) => {
722
+ const { generation, controller } = this.beginProviderRefresh(provider.id);
723
+ const signal = AbortSignal.any([callerSignal, controller.signal]);
724
+ const operation = (async () => {
725
+ let storedCredential;
726
+ let credentialError;
727
+ try {
728
+ storedCredential = await this.readCredential(provider.id, signal);
729
+ } catch (error) {
730
+ credentialError = error;
731
+ }
732
+ await this.runProviderRefreshPhase(provider, storedCredential, false, void 0, generation, signal);
733
+ if (credentialError !== void 0) throw credentialError;
734
+ if (!allowNetwork || signal.aborted) return;
735
+ const credential = await this.resolveRefreshCredential(provider, storedCredential, signal);
736
+ if (!credential) return;
737
+ await this.runProviderRefreshPhase(provider, credential, true, options.force, generation, signal);
738
+ })();
739
+ try {
740
+ await raceWithAbortSignal(operation, signal);
741
+ } catch (error) {
742
+ if (!signal.aborted) errors.set(provider.id, error instanceof Error ? error : new ModelsError("model_source", `Model refresh failed for ${provider.id}`, { cause: error }));
743
+ } finally {
744
+ if (this.refreshControllers.get(provider.id) === controller) this.refreshControllers.delete(provider.id);
745
+ }
746
+ }));
747
+ try {
748
+ await raceWithAbortSignal(refresh, callerSignal);
749
+ } catch (error) {
750
+ if (!callerSignal.aborted) throw error;
751
+ }
752
+ return {
753
+ aborted: callerSignal.aborted,
754
+ errors: new Map(errors)
755
+ };
756
+ }
757
+ async resolveRefreshCredential(provider, stored, signal) {
758
+ if (stored?.type === "oauth") {
759
+ const oauth = provider.auth.oauth;
760
+ if (!oauth) return void 0;
761
+ if (Date.now() < stored.expires) return stored;
762
+ if (signal.aborted) return void 0;
763
+ const post = await this.credentials.modify(provider.id, async (current) => {
764
+ if (current?.type !== "oauth" || Date.now() < current.expires) return void 0;
765
+ return oauth.refresh(current, signal);
766
+ }, { signal });
767
+ return post?.type === "oauth" ? post : void 0;
768
+ }
769
+ const apiKey = provider.auth.apiKey;
770
+ if (!apiKey) return void 0;
771
+ const credential = stored?.type === "api_key" ? stored : void 0;
772
+ const result = await apiKey.resolve({
773
+ ctx: this.authContext,
774
+ credential,
775
+ signal
776
+ });
777
+ if (!result) return void 0;
778
+ return {
779
+ type: "api_key",
780
+ key: result.auth.apiKey,
781
+ env: result.env
782
+ };
783
+ }
784
+ async readCredential(providerId, signal) {
785
+ try {
786
+ return await this.credentials.read(providerId, { signal });
787
+ } catch (error) {
788
+ throw new ModelsError("auth", `Credential store read failed for ${providerId}`, { cause: error });
789
+ }
790
+ }
791
+ async checkProviderAuth(provider, credential, signal) {
792
+ if (credential?.type === "oauth") return provider.auth.oauth ? {
793
+ source: "OAuth",
794
+ type: "oauth"
795
+ } : void 0;
796
+ const apiKey = provider.auth.apiKey;
797
+ if (!apiKey) return void 0;
798
+ if (apiKey.check) try {
799
+ return await apiKey.check({
800
+ ctx: this.authContext,
801
+ credential: credential?.type === "api_key" ? credential : void 0,
802
+ signal
803
+ });
804
+ } catch (error) {
805
+ throw new ModelsError("auth", `API key auth check failed for provider ${provider.id}`, { cause: error });
806
+ }
807
+ const resolution = await resolveProviderAuth(provider, this.credentials, this.authContext, { signal });
808
+ return resolution ? {
809
+ source: resolution.source,
810
+ type: "api_key"
811
+ } : void 0;
812
+ }
813
+ checkAuth(providerId, options) {
814
+ const signal = operationSignal(options?.signal);
815
+ return raceWithAbortSignal((async () => {
816
+ signal.throwIfAborted();
817
+ const provider = this.providers.get(providerId);
818
+ if (!provider) return void 0;
819
+ return this.checkProviderAuth(provider, await this.readCredential(providerId, signal), signal);
820
+ })(), signal);
821
+ }
822
+ getAvailable(providerId, options) {
823
+ const signal = operationSignal(options?.signal);
824
+ return raceWithAbortSignal((async () => {
825
+ signal.throwIfAborted();
826
+ const providers = providerId ? [this.providers.get(providerId)].filter((entry) => entry !== void 0) : this.getProviders();
827
+ return (await Promise.all(providers.map(async (provider) => {
828
+ const credential = await this.readCredential(provider.id, signal);
829
+ return {
830
+ provider,
831
+ credential,
832
+ auth: await this.checkProviderAuth(provider, credential, signal)
833
+ };
834
+ }))).flatMap(({ provider, credential, auth }) => {
835
+ if (!auth) return [];
836
+ const models = provider.getModels();
837
+ return provider.filterModels?.(models, credential) ?? models;
838
+ });
839
+ })(), signal);
840
+ }
841
+ async getAuth(providerOrModel, overrides) {
842
+ const signal = operationSignal(overrides?.signal);
843
+ const providerId = typeof providerOrModel === "string" ? providerOrModel : providerOrModel.provider;
844
+ const provider = this.providers.get(providerId);
845
+ if (!provider) return void 0;
846
+ const result = await resolveProviderAuth(provider, this.credentials, this.authContext, {
847
+ ...overrides,
848
+ signal
849
+ });
850
+ if (!result || typeof providerOrModel === "string" || !providerOrModel.headers) return result;
851
+ return {
852
+ ...result,
853
+ auth: {
854
+ ...result.auth,
855
+ headers: mergeHeaders(result.auth.headers, providerOrModel.headers)
856
+ }
857
+ };
858
+ }
859
+ async login(providerId, type, interaction) {
860
+ const signal = operationSignal(interaction.signal);
861
+ signal.throwIfAborted();
862
+ const provider = this.providers.get(providerId);
863
+ if (!provider) throw new ModelsError("provider", `Unknown provider: ${providerId}`);
864
+ const method = type === "oauth" ? provider.auth.oauth : provider.auth.apiKey;
865
+ if (!method?.login) throw new ModelsError("auth", `${provider.name} does not support ${type} login`);
866
+ const credential = await raceWithAbortSignal(method.login({
867
+ ...interaction,
868
+ signal
869
+ }), signal);
870
+ let mutationStarted = false;
871
+ let markMutationStarted;
872
+ const started = new Promise((resolve) => {
873
+ markMutationStarted = resolve;
874
+ });
875
+ const mutation = this.credentials.modify(providerId, async () => {
876
+ mutationStarted = true;
877
+ markMutationStarted?.();
878
+ return credential;
879
+ }, { signal });
880
+ mutation.catch(() => {});
881
+ try {
882
+ await new Promise((resolve, reject) => {
883
+ const onAbort = () => {
884
+ if (!mutationStarted) reject(signal.reason);
885
+ };
886
+ signal.addEventListener("abort", onAbort, { once: true });
887
+ Promise.race([started, mutation]).then(() => {
888
+ signal.removeEventListener("abort", onAbort);
889
+ resolve();
890
+ }, (error) => {
891
+ signal.removeEventListener("abort", onAbort);
892
+ reject(error);
893
+ });
894
+ if (signal.aborted) onAbort();
895
+ });
896
+ await mutation;
897
+ } catch (error) {
898
+ signal.throwIfAborted();
899
+ throw new ModelsError("auth", `Credential store modify failed for ${providerId}`, { cause: error });
900
+ }
901
+ return credential;
902
+ }
903
+ async logout(providerId, options) {
904
+ const signal = operationSignal(options?.signal);
905
+ signal.throwIfAborted();
906
+ try {
907
+ await this.credentials.delete(providerId, { signal });
908
+ } catch (error) {
909
+ signal.throwIfAborted();
910
+ throw new ModelsError("auth", `Credential store delete failed for ${providerId}`, { cause: error });
911
+ }
912
+ }
913
+ requireProvider(model) {
914
+ const provider = this.providers.get(model.provider);
915
+ if (!provider) throw new ModelsError("provider", `Unknown provider: ${model.provider}`);
916
+ return provider;
917
+ }
918
+ async applyAuth(model, options) {
919
+ this.requireProvider(model);
920
+ const resolution = await this.getAuth(model, {
921
+ apiKey: options?.apiKey,
922
+ env: options?.env,
923
+ signal: options?.signal
924
+ });
925
+ if (!resolution) throw new ModelsError("auth", `Provider is not configured: ${model.provider}`);
926
+ const auth = resolution.auth;
927
+ const apiKey = options?.apiKey ?? auth.apiKey;
928
+ let headers = mergeHeaders(auth.headers, options?.headers);
929
+ if (options?.transformHeaders) headers = await options.transformHeaders(headers ?? {});
930
+ const env = resolution.env || options?.env ? {
931
+ ...resolution.env ?? {},
932
+ ...options?.env ?? {}
933
+ } : void 0;
934
+ const requestModel = auth.baseUrl ? {
935
+ ...model,
936
+ baseUrl: auth.baseUrl
937
+ } : model;
938
+ const { transformHeaders: _transformHeaders, ...providerOptions } = options ?? {};
939
+ return {
940
+ requestModel,
941
+ requestOptions: {
942
+ ...providerOptions,
943
+ apiKey,
944
+ headers,
945
+ env
946
+ }
947
+ };
948
+ }
949
+ stream(model, context, options) {
950
+ const transcript = normalizeContext(context);
951
+ return lazyStream(model, async () => {
952
+ const provider = this.requireProvider(model);
953
+ const { requestModel, requestOptions } = await this.applyAuth(model, options);
954
+ return provider.stream(requestModel, transcript, requestOptions);
955
+ });
956
+ }
957
+ async complete(model, context, options) {
958
+ return this.stream(model, context, options).result();
959
+ }
960
+ streamSimple(model, context, options) {
961
+ const transcript = normalizeContext(context);
962
+ return lazyStream(model, async () => {
963
+ const provider = this.requireProvider(model);
964
+ const { requestModel, requestOptions } = await this.applyAuth(model, options);
965
+ return provider.streamSimple(requestModel, transcript, requestOptions);
966
+ });
967
+ }
968
+ async completeSimple(model, context, options) {
969
+ return this.streamSimple(model, context, options).result();
970
+ }
971
+ streamDeferred(model, handle, options) {
972
+ return lazyStream(model, async () => {
973
+ const provider = this.requireProvider(model);
974
+ if (!provider.fetchDeferred) throw new ModelsError("provider", `Provider ${model.provider} does not support deferred responses`);
975
+ const { requestModel, requestOptions } = await this.applyAuth(model, options);
976
+ return provider.fetchDeferred(requestModel, handle, requestOptions);
977
+ });
978
+ }
979
+ async fetchDeferred(model, handle, options) {
980
+ return this.streamDeferred(model, handle, options).result();
981
+ }
982
+ async cancelDeferred(model, handle, options) {
983
+ const provider = this.requireProvider(model);
984
+ if (!provider.cancelDeferred) throw new ModelsError("provider", `Provider ${model.provider} does not support deferred responses`);
985
+ const { requestModel, requestOptions } = await this.applyAuth(model, options);
986
+ await provider.cancelDeferred(requestModel, handle, requestOptions);
987
+ }
988
+ };
989
+ function createModels(options) {
990
+ return new ModelsImpl(options);
991
+ }
992
+ function calculateCost(model, usage) {
993
+ const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;
994
+ let rates = model.cost;
995
+ let matchedThreshold = -1;
996
+ for (const tier of model.cost.tiers ?? []) if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > matchedThreshold) {
997
+ rates = tier;
998
+ matchedThreshold = tier.inputTokensAbove;
999
+ }
1000
+ const longWrite = usage.cacheWrite1h ?? 0;
1001
+ const shortWrite = usage.cacheWrite - longWrite;
1002
+ usage.cost.input = rates.input / 1e6 * usage.input;
1003
+ usage.cost.output = rates.output / 1e6 * usage.output;
1004
+ usage.cost.cacheRead = rates.cacheRead / 1e6 * usage.cacheRead;
1005
+ usage.cost.cacheWrite = (rates.cacheWrite * shortWrite + rates.input * 2 * longWrite) / 1e6;
1006
+ usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
1007
+ return usage.cost;
1008
+ }
1009
+ const EXTENDED_THINKING_LEVELS = [
1010
+ "off",
1011
+ "minimal",
1012
+ "low",
1013
+ "medium",
1014
+ "high",
1015
+ "xhigh",
1016
+ "max"
1017
+ ];
1018
+ function getSupportedThinkingLevels(model) {
1019
+ if (!model.reasoning) return ["off"];
1020
+ return EXTENDED_THINKING_LEVELS.filter((level) => {
1021
+ const mapped = model.thinkingLevelMap?.[level];
1022
+ if (mapped === null) return false;
1023
+ if (level === "xhigh" || level === "max") return mapped !== void 0;
1024
+ return true;
1025
+ });
1026
+ }
1027
+ function clampThinkingLevel(model, level) {
1028
+ const availableLevels = getSupportedThinkingLevels(model);
1029
+ if (availableLevels.includes(level)) return level;
1030
+ const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);
1031
+ if (requestedIndex === -1) return availableLevels[0] ?? "off";
1032
+ for (let i = requestedIndex; i < EXTENDED_THINKING_LEVELS.length; i++) {
1033
+ const candidate = EXTENDED_THINKING_LEVELS[i];
1034
+ if (availableLevels.includes(candidate)) return candidate;
1035
+ }
1036
+ for (let i = requestedIndex - 1; i >= 0; i--) {
1037
+ const candidate = EXTENDED_THINKING_LEVELS[i];
1038
+ if (availableLevels.includes(candidate)) return candidate;
1039
+ }
1040
+ return availableLevels[0] ?? "off";
1041
+ }
1042
+ //#endregion
1043
+ export { getDeclaredTools as a, resolveTranscript as c, renderSystemMessageUpdate as d, appendAssistantMessageDiagnostic as f, getCurrentTools as i, resolveTranscriptTools as l, AssistantMessageEventStream as m, clampThinkingLevel as n, getInitialSystemMessage as o, lazyApi as p, createModels as r, hasToolRedefinitions as s, calculateCost as t, getSystemMessageText as u };
1044
+
1045
+ //# sourceMappingURL=models-CAcLevEN.js.map