@nexface/agent 0.1.1-alpha.0

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 (56) hide show
  1. package/THIRD_PARTY_LICENSES.txt +245 -0
  2. package/dist/agent.d.ts +19 -0
  3. package/dist/agent.js +1509 -0
  4. package/dist/agent.js.map +1 -0
  5. package/dist/browser-prompt.d.ts +5 -0
  6. package/dist/browser-prompt.generated.d.ts +1 -0
  7. package/dist/browser-prompt.generated.js +50 -0
  8. package/dist/browser-prompt.generated.js.map +1 -0
  9. package/dist/browser-prompt.js +9 -0
  10. package/dist/browser-prompt.js.map +1 -0
  11. package/dist/errors.d.ts +21 -0
  12. package/dist/errors.js +55 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/index.d.ts +6 -0
  15. package/dist/index.js +4 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/model/binding.d.ts +22 -0
  18. package/dist/model/binding.js +31 -0
  19. package/dist/model/binding.js.map +1 -0
  20. package/dist/model/error.d.ts +6 -0
  21. package/dist/model/error.js +10 -0
  22. package/dist/model/error.js.map +1 -0
  23. package/dist/model/internal-adapter.d.ts +8 -0
  24. package/dist/model/internal-adapter.js +13 -0
  25. package/dist/model/internal-adapter.js.map +1 -0
  26. package/dist/model/types.d.ts +9 -0
  27. package/dist/model/types.js +2 -0
  28. package/dist/model/types.js.map +1 -0
  29. package/dist/models/885.js +630 -0
  30. package/dist/models/956.js +5 -0
  31. package/dist/models/_chunks/35-e1813138.js +8304 -0
  32. package/dist/models/_chunks/879-7e580bb2.js +1189 -0
  33. package/dist/models/_chunks/958-bedced75.js +453 -0
  34. package/dist/models/_chunks/anthropic-messages~1-a4b25b48.js +8057 -0
  35. package/dist/models/_chunks/deferred-tools-90f3c977.js +37 -0
  36. package/dist/models/_chunks/error-body-8bee35c2.js +134 -0
  37. package/dist/models/_chunks/google-generative-ai~1-78bb2822.js +22104 -0
  38. package/dist/models/_chunks/openai-completions~1-7677fb83.js +1285 -0
  39. package/dist/models/_chunks/openai-responses~1-cc0a71cd.js +958 -0
  40. package/dist/models/anthropic-messages.d.ts +4 -0
  41. package/dist/models/anthropic-messages.js +32 -0
  42. package/dist/models/google-generative-ai.d.ts +4 -0
  43. package/dist/models/google-generative-ai.js +32 -0
  44. package/dist/models/openai-completions.d.ts +5 -0
  45. package/dist/models/openai-completions.js +16 -0
  46. package/dist/models/openai-responses.d.ts +5 -0
  47. package/dist/models/openai-responses.js +16 -0
  48. package/dist/models/rslib-runtime.js +59 -0
  49. package/dist/models/types.d.ts +26 -0
  50. package/dist/tool-bridge.d.ts +36 -0
  51. package/dist/tool-bridge.js +299 -0
  52. package/dist/tool-bridge.js.map +1 -0
  53. package/dist/types.d.ts +129 -0
  54. package/dist/types.js +2 -0
  55. package/dist/types.js.map +1 -0
  56. package/package.json +55 -0
@@ -0,0 +1,630 @@
1
+ import { defineAgentModelConfig } from "../model/binding.js";
2
+
3
+ // Generic event stream class for async iteration
4
+ class EventStream {
5
+ queue = [];
6
+ waiting = [];
7
+ done = false;
8
+ finalResultPromise;
9
+ resolveFinalResult;
10
+ isComplete;
11
+ extractResult;
12
+ constructor(isComplete, extractResult) {
13
+ this.isComplete = isComplete;
14
+ this.extractResult = extractResult;
15
+ this.finalResultPromise = new Promise((resolve) => {
16
+ this.resolveFinalResult = resolve;
17
+ });
18
+ }
19
+ push(event) {
20
+ if (this.done)
21
+ return;
22
+ if (this.isComplete(event)) {
23
+ this.done = true;
24
+ this.resolveFinalResult(this.extractResult(event));
25
+ }
26
+ // Deliver to waiting consumer or queue it
27
+ const waiter = this.waiting.shift();
28
+ if (waiter) {
29
+ waiter({ value: event, done: false });
30
+ }
31
+ else {
32
+ this.queue.push(event);
33
+ }
34
+ }
35
+ end(result) {
36
+ this.done = true;
37
+ if (result !== undefined) {
38
+ this.resolveFinalResult(result);
39
+ }
40
+ // Notify all waiting consumers that we're done
41
+ while (this.waiting.length > 0) {
42
+ const waiter = this.waiting.shift();
43
+ waiter({ value: undefined, done: true });
44
+ }
45
+ }
46
+ async *[Symbol.asyncIterator]() {
47
+ while (true) {
48
+ if (this.queue.length > 0) {
49
+ yield this.queue.shift();
50
+ }
51
+ else if (this.done) {
52
+ return;
53
+ }
54
+ else {
55
+ const result = await new Promise((resolve) => this.waiting.push(resolve));
56
+ if (result.done)
57
+ return;
58
+ yield result.value;
59
+ }
60
+ }
61
+ }
62
+ result() {
63
+ return this.finalResultPromise;
64
+ }
65
+ }
66
+ class AssistantMessageEventStream extends EventStream {
67
+ constructor() {
68
+ super((event) => event.type === "done" || event.type === "error", (event) => {
69
+ if (event.type === "done") {
70
+ return event.message;
71
+ }
72
+ else if (event.type === "error") {
73
+ return event.error;
74
+ }
75
+ throw new Error("Unexpected event type for final result");
76
+ });
77
+ }
78
+ }
79
+ /** Factory function for AssistantMessageEventStream (for use in extensions) */
80
+ function createAssistantMessageEventStream() {
81
+ return new AssistantMessageEventStream();
82
+ }
83
+ //# sourceMappingURL=event-stream.js.map
84
+
85
+ function createSetupErrorMessage(model, error) {
86
+ return {
87
+ role: "assistant",
88
+ content: [],
89
+ api: model.api,
90
+ provider: model.provider,
91
+ model: model.id,
92
+ usage: {
93
+ input: 0,
94
+ output: 0,
95
+ cacheRead: 0,
96
+ cacheWrite: 0,
97
+ totalTokens: 0,
98
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
99
+ },
100
+ stopReason: "error",
101
+ errorMessage: error instanceof Error ? error.message : String(error),
102
+ timestamp: Date.now(),
103
+ };
104
+ }
105
+ function hasResult(source) {
106
+ return typeof source.result === "function";
107
+ }
108
+ async function forwardStream(target, source) {
109
+ for await (const event of source) {
110
+ target.push(event);
111
+ }
112
+ target.end(hasResult(source) ? await source.result() : undefined);
113
+ }
114
+ /**
115
+ * Returns a stream synchronously while running async setup (auth resolution,
116
+ * lazy module loading) behind it. Setup failures terminate the stream with an
117
+ * error event.
118
+ */
119
+ function lazyStream(model, setup) {
120
+ const outer = new AssistantMessageEventStream();
121
+ setup()
122
+ .then((inner) => forwardStream(outer, inner))
123
+ .catch((error) => {
124
+ const message = createSetupErrorMessage(model, error);
125
+ outer.push({ type: "error", reason: "error", error: message });
126
+ outer.end(message);
127
+ });
128
+ return outer;
129
+ }
130
+ function lazyApi(load, capabilities) {
131
+ const api = {
132
+ stream: (model, context, options) => lazyStream(model, async () => (await load()).stream(model, context, options)),
133
+ streamSimple: (model, context, options) => lazyStream(model, async () => (await load()).streamSimple(model, context, options)),
134
+ };
135
+ if (capabilities?.fetchDeferred) {
136
+ api.fetchDeferred = (model, handle, options) => lazyStream(model, async () => {
137
+ const implementation = await load();
138
+ if (!implementation.fetchDeferred)
139
+ throw new Error("API does not support deferred responses");
140
+ return implementation.fetchDeferred(model, handle, options);
141
+ });
142
+ }
143
+ if (capabilities?.cancelDeferred) {
144
+ api.cancelDeferred = async (model, handle, options) => {
145
+ const implementation = await load();
146
+ if (!implementation.cancelDeferred)
147
+ throw new Error("API cannot cancel deferred responses");
148
+ await implementation.cancelDeferred(model, handle, options);
149
+ };
150
+ }
151
+ return api;
152
+ }
153
+ //# sourceMappingURL=lazy.js.map
154
+
155
+ const AGENT_ERROR_CODES = [
156
+ "AGENT_RUN_ACTIVE",
157
+ "AGENT_INTERRUPT_PENDING",
158
+ "AGENT_RUN_LIMIT_REACHED",
159
+ "AGENT_TOOL_RUNTIME_UNAVAILABLE",
160
+ "BROWSER_SKILL_REQUIRED",
161
+ "CONTEXT_SNAPSHOT_TOO_LARGE",
162
+ "INVALID_MODEL_RESPONSE",
163
+ "INVALID_RUN_INPUT",
164
+ "INVALID_SKILL_CONFIG",
165
+ "INVALID_TOOL_BATCH",
166
+ "UNKNOWN_MODEL_TOOL"
167
+ ];
168
+ const AGENT_MODEL_ERROR_CODES = [
169
+ "AGENT_MODEL_SWITCH_BLOCKED",
170
+ "AGENT_RUN_BLOCKED",
171
+ "INVALID_MODEL_RESPONSE",
172
+ "MODEL_CONFIG_INVALID",
173
+ "MODEL_NOT_FOUND",
174
+ "MODEL_REQUEST_FAILED",
175
+ "MODEL_INPUT_UNSUPPORTED"
176
+ ];
177
+ const AGENT_ERROR_CODE_SET = new Set(AGENT_ERROR_CODES);
178
+ const AGENT_MODEL_ERROR_CODE_SET = new Set(AGENT_MODEL_ERROR_CODES);
179
+ function isAgentError(error) {
180
+ if (!error || typeof error !== "object") return false;
181
+ const candidate = error;
182
+ if (candidate.type !== "agent_error" || typeof candidate.code !== "string" || typeof candidate.message !== "string") {
183
+ return false;
184
+ }
185
+ if (candidate.domain === "agent") {
186
+ return AGENT_ERROR_CODE_SET.has(candidate.code);
187
+ }
188
+ if (candidate.domain === "model") {
189
+ return AGENT_MODEL_ERROR_CODE_SET.has(candidate.code);
190
+ }
191
+ return false;
192
+ }
193
+ class AgentError extends Error {
194
+ code;
195
+ details;
196
+ domain;
197
+ type = "agent_error";
198
+ constructor(code, message, details, domain = "agent"){
199
+ super(message), this.code = code, this.details = details, this.domain = domain;
200
+ this.name = "AgentError";
201
+ }
202
+ }
203
+
204
+
205
+ class AgentModelError extends AgentError {
206
+ code;
207
+ constructor(code, message){
208
+ super(code, message, undefined, "model"), this.code = code;
209
+ this.name = "AgentModelError";
210
+ }
211
+ }
212
+
213
+
214
+ function parseArguments(value) {
215
+ try {
216
+ const parsed = JSON.parse(value);
217
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
218
+ } catch {
219
+ return {};
220
+ }
221
+ }
222
+ function genericAssistant(message, model) {
223
+ return {
224
+ role: "assistant",
225
+ api: model.api,
226
+ provider: model.provider,
227
+ model: model.id,
228
+ content: [
229
+ ...message.content ? [
230
+ {
231
+ type: "text",
232
+ text: message.content
233
+ }
234
+ ] : [],
235
+ ...message.toolCalls.map((call)=>({
236
+ type: "toolCall",
237
+ id: call.id,
238
+ name: call.name,
239
+ arguments: parseArguments(call.arguments)
240
+ }))
241
+ ],
242
+ usage: {
243
+ input: 0,
244
+ output: 0,
245
+ cacheRead: 0,
246
+ cacheWrite: 0,
247
+ totalTokens: 0,
248
+ cost: {
249
+ input: 0,
250
+ output: 0,
251
+ cacheRead: 0,
252
+ cacheWrite: 0,
253
+ total: 0
254
+ }
255
+ },
256
+ stopReason: message.toolCalls.length ? "toolUse" : "stop",
257
+ timestamp: Date.now()
258
+ };
259
+ }
260
+ function toolIsError(content) {
261
+ try {
262
+ const parsed = JSON.parse(content);
263
+ return "error" in parsed;
264
+ } catch {
265
+ return false;
266
+ }
267
+ }
268
+ function createPiContext(messages, tools, model, replay) {
269
+ // pi-ai exposes one trusted systemPrompt rather than chronological system messages.
270
+ // Keep canonical checkpoints append-only, then consolidate them in their original order.
271
+ const system = [];
272
+ const piMessages = [];
273
+ messages.forEach((message, index)=>{
274
+ if (message.role === "system" || message.role === "application_context") {
275
+ system.push(message.content);
276
+ return;
277
+ }
278
+ if (message.role === "user") {
279
+ const content = typeof message.content === "string" ? message.content : message.content.map((part)=>{
280
+ if (part.type === "text") return part;
281
+ if (!model.input.includes("image")) throw new AgentModelError("MODEL_INPUT_UNSUPPORTED", "The configured model does not support image input.");
282
+ if (part.source.type !== "data") throw new AgentModelError("MODEL_INPUT_UNSUPPORTED", "Only inline image data is supported.");
283
+ return {
284
+ type: "image",
285
+ data: part.source.value,
286
+ mimeType: part.source.mimeType
287
+ };
288
+ });
289
+ piMessages.push({
290
+ role: "user",
291
+ content,
292
+ timestamp: Date.now()
293
+ });
294
+ return;
295
+ }
296
+ if (message.role === "assistant") {
297
+ piMessages.push(replay.get(index) ?? genericAssistant(message, model));
298
+ return;
299
+ }
300
+ if (message.role === "tool") {
301
+ piMessages.push({
302
+ role: "toolResult",
303
+ toolCallId: message.toolCallId,
304
+ toolName: message.name,
305
+ content: [
306
+ {
307
+ type: "text",
308
+ text: message.content
309
+ }
310
+ ],
311
+ isError: toolIsError(message.content),
312
+ timestamp: Date.now()
313
+ });
314
+ }
315
+ });
316
+ const piTools = tools.map((tool)=>({
317
+ name: tool.name,
318
+ description: tool.description,
319
+ parameters: tool.inputSchema
320
+ }));
321
+ return {
322
+ ...system.length ? {
323
+ systemPrompt: system.join("\n\n")
324
+ } : {},
325
+ messages: piMessages,
326
+ tools: piTools
327
+ };
328
+ }
329
+ function fromPiAssistant(message) {
330
+ const text = message.content.filter((block)=>block.type === "text").map((block)=>block.text).join("");
331
+ return {
332
+ content: text || null,
333
+ toolCalls: message.content.filter((block)=>block.type === "toolCall").map((block)=>({
334
+ id: block.id,
335
+ name: block.name,
336
+ arguments: JSON.stringify(block.arguments)
337
+ })),
338
+ usage: {
339
+ promptTokens: message.usage.input,
340
+ cachedPromptTokens: message.usage.cacheRead,
341
+ cacheMissPromptTokens: Math.max(0, message.usage.input - message.usage.cacheRead),
342
+ completionTokens: message.usage.output,
343
+ totalTokens: message.usage.totalTokens
344
+ }
345
+ };
346
+ }
347
+
348
+
349
+
350
+
351
+ const DEFAULT_CAPABILITIES = {
352
+ reasoning: false,
353
+ input: [
354
+ "text"
355
+ ],
356
+ contextWindow: 128000,
357
+ maxOutputTokens: 16384
358
+ };
359
+ const KEYLESS_GATEWAY_API_KEY = "nexface-keyless-gateway";
360
+ function invalid(message) {
361
+ throw new AgentModelError("MODEL_CONFIG_INVALID", message);
362
+ }
363
+ function assertNonEmpty(value, name) {
364
+ if (typeof value !== "string" || !value.trim()) invalid(`${name} must be a non-empty string.`);
365
+ }
366
+ function normalizedBaseURL(value, fallback) {
367
+ const candidate = value ?? fallback;
368
+ assertNonEmpty(candidate, "baseURL");
369
+ const browserOrigin = globalThis.location?.origin;
370
+ let url;
371
+ try {
372
+ url = browserOrigin ? new URL(candidate, browserOrigin) : new URL(candidate);
373
+ } catch {
374
+ return invalid("baseURL must be absolute outside a browser environment.");
375
+ }
376
+ if (url.search || url.hash) invalid("baseURL must not contain a query or hash.");
377
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
378
+ invalid("baseURL must use http or https.");
379
+ }
380
+ if (url.username || url.password) invalid("baseURL must not contain credentials.");
381
+ url.pathname = url.pathname.replace(/\/+$/, "") || "/";
382
+ return url.toString().replace(/\/$/, "");
383
+ }
384
+ function hasAuthenticationHeader(headers) {
385
+ const authenticationHeaders = new Set([
386
+ "authorization",
387
+ "x-api-key",
388
+ "x-goog-api-key"
389
+ ]);
390
+ for (const [name, value] of Object.entries(headers ?? {})){
391
+ if (!authenticationHeaders.has(name.toLowerCase())) continue;
392
+ assertNonEmpty(value, `headers.${name}`);
393
+ return true;
394
+ }
395
+ return false;
396
+ }
397
+ function assertFiniteNumber(value, name, minimum) {
398
+ if (value !== undefined && (!Number.isFinite(value) || value < minimum)) {
399
+ invalid(`${name} must be a finite number greater than or equal to ${minimum}.`);
400
+ }
401
+ }
402
+ function stripKeylessSecret(input, init) {
403
+ const headers = new Headers(init?.headers);
404
+ for (const name of [
405
+ "authorization",
406
+ "x-api-key",
407
+ "x-goog-api-key"
408
+ ]){
409
+ const value = headers.get(name);
410
+ if (value === KEYLESS_GATEWAY_API_KEY || value === `Bearer ${KEYLESS_GATEWAY_API_KEY}`) {
411
+ headers.delete(name);
412
+ }
413
+ }
414
+ let nextInput = input;
415
+ const rawURL = input instanceof Request ? input.url : String(input);
416
+ try {
417
+ const url = new URL(rawURL, globalThis.location?.origin);
418
+ for (const name of [
419
+ "key",
420
+ "api_key"
421
+ ]){
422
+ if (url.searchParams.get(name) === KEYLESS_GATEWAY_API_KEY) url.searchParams.delete(name);
423
+ }
424
+ nextInput = input instanceof Request ? new Request(url, input) : url;
425
+ } catch {
426
+ // Keep non-URL RequestInfo unchanged.
427
+ }
428
+ return [
429
+ nextInput,
430
+ {
431
+ ...init,
432
+ headers
433
+ }
434
+ ];
435
+ }
436
+ function createKeylessFetch(fetchImpl) {
437
+ return async (input, init)=>{
438
+ const [nextInput, nextInit] = stripKeylessSecret(input, init);
439
+ return fetchImpl(nextInput, nextInit);
440
+ };
441
+ }
442
+ async function consumeStream(stream, onTextDelta) {
443
+ let result;
444
+ for await (const event of stream){
445
+ if (event.type === "text_delta") onTextDelta?.(event.delta);
446
+ if (event.type === "done") result = event.message;
447
+ if (event.type === "error") {
448
+ if (event.reason === "aborted") {
449
+ throw new DOMException("The model request was aborted.", "AbortError");
450
+ }
451
+ throw new AgentModelError("MODEL_REQUEST_FAILED", "The model request failed.");
452
+ }
453
+ }
454
+ if (!result) {
455
+ throw new AgentModelError("INVALID_MODEL_RESPONSE", "Model stream ended without a final message.");
456
+ }
457
+ return result;
458
+ }
459
+ class PiModelBinding {
460
+ info;
461
+ #replay = new Map();
462
+ #model;
463
+ #stream;
464
+ #options;
465
+ constructor(info, model, stream, options){
466
+ this.info = info;
467
+ this.#model = model;
468
+ this.#stream = stream;
469
+ this.#options = options;
470
+ }
471
+ async complete(request) {
472
+ const raw = await consumeStream(this.#stream.streamSimple(this.#model, createPiContext(request.messages, request.tools, this.#model, this.#replay), {
473
+ ...this.#options,
474
+ signal: request.signal,
475
+ sessionId: request.agentId
476
+ }), request.onTextDelta);
477
+ const response = fromPiAssistant(raw);
478
+ const replayIndex = request.messages.length;
479
+ let accepted = false;
480
+ return {
481
+ ...response,
482
+ accept: ()=>{
483
+ if (accepted) return;
484
+ accepted = true;
485
+ this.#replay.set(replayIndex, raw);
486
+ }
487
+ };
488
+ }
489
+ }
490
+ function resolveModel(definition, config, baseURL) {
491
+ const catalogModel = definition.resolveCatalogModel?.(config.model);
492
+ if (definition.resolveCatalogModel && !catalogModel) {
493
+ throw new AgentModelError("MODEL_NOT_FOUND", `Model "${config.model}" was not found for provider "${definition.provider}".`);
494
+ }
495
+ const capabilities = {
496
+ ...DEFAULT_CAPABILITIES,
497
+ ...config.capabilities
498
+ };
499
+ if (catalogModel) {
500
+ return {
501
+ ...catalogModel,
502
+ baseUrl: baseURL,
503
+ ...config.capabilities?.reasoning === undefined ? {} : {
504
+ reasoning: config.capabilities.reasoning
505
+ },
506
+ ...config.capabilities?.input === undefined ? {} : {
507
+ input: [
508
+ ...config.capabilities.input
509
+ ]
510
+ },
511
+ ...config.capabilities?.contextWindow === undefined ? {} : {
512
+ contextWindow: config.capabilities.contextWindow
513
+ },
514
+ ...config.capabilities?.maxOutputTokens === undefined ? {} : {
515
+ maxTokens: config.capabilities.maxOutputTokens
516
+ }
517
+ };
518
+ }
519
+ return {
520
+ id: config.model,
521
+ name: config.model,
522
+ api: definition.api,
523
+ provider: definition.provider,
524
+ baseUrl: baseURL,
525
+ reasoning: capabilities.reasoning,
526
+ input: capabilities.input,
527
+ cost: {
528
+ input: 0,
529
+ output: 0,
530
+ cacheRead: 0,
531
+ cacheWrite: 0
532
+ },
533
+ contextWindow: capabilities.contextWindow,
534
+ maxTokens: capabilities.maxOutputTokens
535
+ };
536
+ }
537
+ function createProtocolModelConfig(definition, config) {
538
+ if (!config || typeof config !== "object") invalid("model config must be an object.");
539
+ assertNonEmpty(config.model, "model");
540
+ if (config.apiKey !== undefined) assertNonEmpty(config.apiKey, "apiKey");
541
+ if (config.apiKey && hasAuthenticationHeader(config.headers)) {
542
+ invalid("apiKey and an authentication header cannot be configured together.");
543
+ }
544
+ if (definition.supportsCustomFetch === false && config.fetch) {
545
+ invalid(`Custom fetch is not supported for provider "${definition.provider}".`);
546
+ }
547
+ if (definition.resolveCatalogModel && config.capabilities !== undefined) {
548
+ invalid(`Capability overrides are not supported for provider "${definition.provider}".`);
549
+ }
550
+ assertFiniteNumber(config.temperature, "temperature", 0);
551
+ assertFiniteNumber(config.maxTokens, "maxTokens", 1);
552
+ assertFiniteNumber(config.timeoutMs, "timeoutMs", 1);
553
+ assertFiniteNumber(config.maxRetries, "maxRetries", 0);
554
+ if (config.maxRetries !== undefined && !Number.isInteger(config.maxRetries)) {
555
+ invalid("maxRetries must be an integer.");
556
+ }
557
+ assertFiniteNumber(config.capabilities?.contextWindow, "capabilities.contextWindow", 1);
558
+ assertFiniteNumber(config.capabilities?.maxOutputTokens, "capabilities.maxOutputTokens", 1);
559
+ const baseURL = normalizedBaseURL(config.baseURL, definition.defaultBaseURL);
560
+ const browserOrigin = globalThis.location?.origin;
561
+ if (browserOrigin && config.apiKey === undefined && !hasAuthenticationHeader(config.headers) && new URL(baseURL).origin !== browserOrigin) {
562
+ invalid("Keyless browser model requests must use a same-origin gateway.");
563
+ }
564
+ if ((definition.api === "openai-completions" || definition.api === "openai-responses") && /\/(?:chat\/completions|responses)$/i.test(new URL(baseURL).pathname)) {
565
+ invalid("baseURL must be an API root and must not include the final endpoint.");
566
+ }
567
+ const preparedConfig = {
568
+ ...config,
569
+ baseURL,
570
+ ...config.headers === undefined ? {} : {
571
+ headers: {
572
+ ...config.headers
573
+ }
574
+ },
575
+ ...config.capabilities === undefined ? {} : {
576
+ capabilities: {
577
+ ...config.capabilities,
578
+ ...config.capabilities.input === undefined ? {} : {
579
+ input: [
580
+ ...config.capabilities.input
581
+ ]
582
+ }
583
+ }
584
+ }
585
+ };
586
+ const info = {
587
+ provider: definition.provider,
588
+ model: preparedConfig.model
589
+ };
590
+ return defineAgentModelConfig({
591
+ info,
592
+ async resolve () {
593
+ const configuredFetch = preparedConfig.fetch ?? globalThis.fetch;
594
+ const options = {
595
+ ...preparedConfig.temperature === undefined ? {} : {
596
+ temperature: preparedConfig.temperature
597
+ },
598
+ ...preparedConfig.maxTokens === undefined ? {} : {
599
+ maxTokens: preparedConfig.maxTokens
600
+ },
601
+ ...preparedConfig.reasoning === undefined ? {} : {
602
+ reasoning: preparedConfig.reasoning
603
+ },
604
+ ...preparedConfig.timeoutMs === undefined ? {} : {
605
+ timeoutMs: preparedConfig.timeoutMs
606
+ },
607
+ ...preparedConfig.maxRetries === undefined ? {} : {
608
+ maxRetries: preparedConfig.maxRetries
609
+ },
610
+ ...preparedConfig.headers === undefined ? {} : {
611
+ headers: preparedConfig.headers
612
+ },
613
+ ...definition.supportsCustomFetch === false || preparedConfig.apiKey === undefined ? {} : {
614
+ fetch: configuredFetch
615
+ },
616
+ ...preparedConfig.apiKey === undefined ? {
617
+ apiKey: KEYLESS_GATEWAY_API_KEY,
618
+ ...definition.supportsCustomFetch === false ? {} : {
619
+ fetch: createKeylessFetch(configuredFetch)
620
+ }
621
+ } : {
622
+ apiKey: preparedConfig.apiKey
623
+ }
624
+ };
625
+ return new PiModelBinding(info, resolveModel(definition, preparedConfig, baseURL), definition.stream, options);
626
+ }
627
+ });
628
+ }
629
+
630
+ export { AgentModelError, AssistantMessageEventStream, createProtocolModelConfig, lazyApi };
@@ -0,0 +1,5 @@
1
+ function flattenModelCatalog(_provider, groups) {
2
+ return Object.assign({}, ...Object.values(groups));
3
+ }
4
+ //# sourceMappingURL=model-catalog.js.map
5
+ export { flattenModelCatalog };