@providerprotocol/ai 0.0.21 → 0.0.22

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 (46) hide show
  1. package/dist/anthropic/index.d.ts +1 -1
  2. package/dist/anthropic/index.js +100 -29
  3. package/dist/anthropic/index.js.map +1 -1
  4. package/dist/{chunk-Y3GBJNA2.js → chunk-7WYBJPJJ.js} +2 -2
  5. package/dist/chunk-I2VHCGQE.js +49 -0
  6. package/dist/chunk-I2VHCGQE.js.map +1 -0
  7. package/dist/{chunk-SKY2JLA7.js → chunk-MKDLXV4O.js} +1 -1
  8. package/dist/chunk-MKDLXV4O.js.map +1 -0
  9. package/dist/{chunk-Z7RBRCRN.js → chunk-NWS5IKNR.js} +37 -11
  10. package/dist/chunk-NWS5IKNR.js.map +1 -0
  11. package/dist/{chunk-EDENPF3E.js → chunk-RFWLEFAB.js} +96 -42
  12. package/dist/chunk-RFWLEFAB.js.map +1 -0
  13. package/dist/{chunk-Z4ILICF5.js → chunk-RS7C25LS.js} +35 -10
  14. package/dist/chunk-RS7C25LS.js.map +1 -0
  15. package/dist/google/index.d.ts +20 -6
  16. package/dist/google/index.js +261 -65
  17. package/dist/google/index.js.map +1 -1
  18. package/dist/http/index.d.ts +3 -3
  19. package/dist/http/index.js +4 -4
  20. package/dist/index.d.ts +7 -5
  21. package/dist/index.js +286 -119
  22. package/dist/index.js.map +1 -1
  23. package/dist/ollama/index.d.ts +1 -1
  24. package/dist/ollama/index.js +66 -12
  25. package/dist/ollama/index.js.map +1 -1
  26. package/dist/openai/index.d.ts +1 -1
  27. package/dist/openai/index.js +183 -43
  28. package/dist/openai/index.js.map +1 -1
  29. package/dist/openrouter/index.d.ts +1 -1
  30. package/dist/openrouter/index.js +161 -31
  31. package/dist/openrouter/index.js.map +1 -1
  32. package/dist/{provider-DGQHYE6I.d.ts → provider-DWEAzeM5.d.ts} +11 -1
  33. package/dist/proxy/index.d.ts +2 -2
  34. package/dist/proxy/index.js +171 -12
  35. package/dist/proxy/index.js.map +1 -1
  36. package/dist/{retry-Pcs3hnbu.d.ts → retry-DmPmqZL6.d.ts} +11 -2
  37. package/dist/{stream-Di9acos2.d.ts → stream-DbkLOIbJ.d.ts} +15 -5
  38. package/dist/xai/index.d.ts +1 -1
  39. package/dist/xai/index.js +139 -30
  40. package/dist/xai/index.js.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-EDENPF3E.js.map +0 -1
  43. package/dist/chunk-SKY2JLA7.js.map +0 -1
  44. package/dist/chunk-Z4ILICF5.js.map +0 -1
  45. package/dist/chunk-Z7RBRCRN.js.map +0 -1
  46. /package/dist/{chunk-Y3GBJNA2.js.map → chunk-7WYBJPJJ.js.map} +0 -0
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  Image
3
3
  } from "../chunk-WAKD3OO5.js";
4
+ import {
5
+ parseJsonResponse
6
+ } from "../chunk-I2VHCGQE.js";
4
7
  import {
5
8
  AssistantMessage,
6
9
  createProvider,
@@ -10,16 +13,17 @@ import {
10
13
  } from "../chunk-M4BMM5IB.js";
11
14
  import {
12
15
  parseSSEStream
13
- } from "../chunk-Z7RBRCRN.js";
16
+ } from "../chunk-NWS5IKNR.js";
14
17
  import {
15
18
  resolveApiKey
16
- } from "../chunk-Y3GBJNA2.js";
19
+ } from "../chunk-7WYBJPJJ.js";
17
20
  import {
18
21
  UPPError,
19
22
  doFetch,
20
23
  doStreamFetch,
21
- normalizeHttpError
22
- } from "../chunk-EDENPF3E.js";
24
+ normalizeHttpError,
25
+ toError
26
+ } from "../chunk-RFWLEFAB.js";
23
27
 
24
28
  // src/providers/google/transform.ts
25
29
  function transformRequest(request, modelId) {
@@ -28,14 +32,15 @@ function transformRequest(request, modelId) {
28
32
  const googleRequest = {
29
33
  contents: transformMessages(request.messages)
30
34
  };
31
- if (request.system) {
32
- if (typeof request.system === "string") {
35
+ const normalizedSystem = normalizeSystem(request.system);
36
+ if (normalizedSystem !== void 0) {
37
+ if (typeof normalizedSystem === "string") {
33
38
  googleRequest.systemInstruction = {
34
- parts: [{ text: request.system }]
39
+ parts: [{ text: normalizedSystem }]
35
40
  };
36
- } else {
41
+ } else if (normalizedSystem.length > 0) {
37
42
  googleRequest.systemInstruction = {
38
- parts: request.system
43
+ parts: normalizedSystem
39
44
  };
40
45
  }
41
46
  }
@@ -69,6 +74,56 @@ function transformRequest(request, modelId) {
69
74
  }
70
75
  return googleRequest;
71
76
  }
77
+ function normalizeSystem(system) {
78
+ if (system === void 0 || system === null) return void 0;
79
+ if (typeof system === "string") return system;
80
+ if (!Array.isArray(system)) {
81
+ throw new UPPError(
82
+ "System prompt must be a string or an array of text parts",
83
+ "INVALID_REQUEST",
84
+ "google",
85
+ "llm"
86
+ );
87
+ }
88
+ const parts = [];
89
+ for (const part of system) {
90
+ if (!part || typeof part !== "object" || !("text" in part)) {
91
+ throw new UPPError(
92
+ "Google system prompt array must contain text parts",
93
+ "INVALID_REQUEST",
94
+ "google",
95
+ "llm"
96
+ );
97
+ }
98
+ const textValue = part.text;
99
+ if (typeof textValue !== "string") {
100
+ throw new UPPError(
101
+ "Google system prompt text must be a string",
102
+ "INVALID_REQUEST",
103
+ "google",
104
+ "llm"
105
+ );
106
+ }
107
+ parts.push(part);
108
+ }
109
+ return parts.length > 0 ? parts : void 0;
110
+ }
111
+ var GOOGLE_TOOLCALL_PREFIX = "google_toolcall";
112
+ function createGoogleToolCallId(name, index) {
113
+ return `${GOOGLE_TOOLCALL_PREFIX}:${index}:${name}`;
114
+ }
115
+ function extractGoogleToolName(toolCallId) {
116
+ const prefix = `${GOOGLE_TOOLCALL_PREFIX}:`;
117
+ if (!toolCallId.startsWith(prefix)) {
118
+ return toolCallId;
119
+ }
120
+ const rest = toolCallId.slice(prefix.length);
121
+ const separatorIndex = rest.indexOf(":");
122
+ if (separatorIndex === -1) {
123
+ return toolCallId;
124
+ }
125
+ return rest.slice(separatorIndex + 1);
126
+ }
72
127
  function filterValidContent(content) {
73
128
  return content.filter((c) => c && typeof c.type === "string");
74
129
  }
@@ -124,7 +179,7 @@ function transformMessages(messages) {
124
179
  role: "user",
125
180
  parts: msg.results.map((result) => ({
126
181
  functionResponse: {
127
- name: result.toolCallId,
182
+ name: extractGoogleToolName(result.toolCallId),
128
183
  response: typeof result.result === "object" ? result.result : { result: result.result }
129
184
  }
130
185
  }))
@@ -191,8 +246,9 @@ function transformResponse(data) {
191
246
  }
192
247
  } else if ("functionCall" in part) {
193
248
  const fc = part;
249
+ const toolCallId = createGoogleToolCallId(fc.functionCall.name, toolCalls.length);
194
250
  toolCalls.push({
195
- toolCallId: fc.functionCall.name,
251
+ toolCallId,
196
252
  toolName: fc.functionCall.name,
197
253
  arguments: fc.functionCall.args
198
254
  });
@@ -234,7 +290,7 @@ ${codeResult.codeExecutionResult.output}\`\`\`
234
290
  return {
235
291
  message,
236
292
  usage,
237
- stopReason: candidate.finishReason ?? "STOP",
293
+ stopReason: normalizeStopReason(candidate.finishReason),
238
294
  data: structuredData
239
295
  };
240
296
  }
@@ -274,7 +330,9 @@ function transformStreamChunk(chunk, state) {
274
330
  });
275
331
  } else if ("functionCall" in part) {
276
332
  const fc = part;
333
+ const toolCallId = createGoogleToolCallId(fc.functionCall.name, state.toolCalls.length);
277
334
  state.toolCalls.push({
335
+ id: toolCallId,
278
336
  name: fc.functionCall.name,
279
337
  args: fc.functionCall.args,
280
338
  thoughtSignature: fc.thoughtSignature
@@ -283,7 +341,7 @@ function transformStreamChunk(chunk, state) {
283
341
  type: "tool_call_delta",
284
342
  index: state.toolCalls.length - 1,
285
343
  delta: {
286
- toolCallId: fc.functionCall.name,
344
+ toolCallId,
287
345
  toolName: fc.functionCall.name,
288
346
  argumentsJson: JSON.stringify(fc.functionCall.args)
289
347
  }
@@ -323,8 +381,9 @@ function buildResponseFromState(state) {
323
381
  }
324
382
  }
325
383
  for (const tc of state.toolCalls) {
384
+ const toolCallId = tc.id || createGoogleToolCallId(tc.name, toolCalls.length);
326
385
  toolCalls.push({
327
- toolCallId: tc.name,
386
+ toolCallId,
328
387
  toolName: tc.name,
329
388
  arguments: tc.args
330
389
  });
@@ -356,10 +415,25 @@ function buildResponseFromState(state) {
356
415
  return {
357
416
  message,
358
417
  usage,
359
- stopReason: state.finishReason ?? "STOP",
418
+ stopReason: normalizeStopReason(state.finishReason),
360
419
  data: structuredData
361
420
  };
362
421
  }
422
+ function normalizeStopReason(reason) {
423
+ switch (reason) {
424
+ case "STOP":
425
+ return "end_turn";
426
+ case "MAX_TOKENS":
427
+ return "max_tokens";
428
+ case "SAFETY":
429
+ case "RECITATION":
430
+ return "content_filter";
431
+ case "OTHER":
432
+ return "end_turn";
433
+ default:
434
+ return "end_turn";
435
+ }
436
+ }
363
437
 
364
438
  // src/providers/google/llm.ts
365
439
  var GOOGLE_API_BASE = "https://generativelanguage.googleapis.com/v1beta";
@@ -371,9 +445,8 @@ var GOOGLE_CAPABILITIES = {
371
445
  videoInput: true,
372
446
  audioInput: true
373
447
  };
374
- function buildUrl(modelId, action, apiKey) {
375
- const base = `${GOOGLE_API_BASE}/models/${modelId}:${action}`;
376
- return `${base}?key=${apiKey}`;
448
+ function buildUrl(modelId, action) {
449
+ return `${GOOGLE_API_BASE}/models/${modelId}:${action}`;
377
450
  }
378
451
  function createLLMHandler() {
379
452
  let providerRef = null;
@@ -403,10 +476,11 @@ function createLLMHandler() {
403
476
  "google",
404
477
  "llm"
405
478
  );
406
- const url = request.config.baseUrl ? `${request.config.baseUrl}/models/${modelId}:generateContent?key=${apiKey}` : buildUrl(modelId, "generateContent", apiKey);
479
+ const url = request.config.baseUrl ? `${request.config.baseUrl}/models/${modelId}:generateContent` : buildUrl(modelId, "generateContent");
407
480
  const body = transformRequest(request, modelId);
408
481
  const headers = {
409
- "Content-Type": "application/json"
482
+ "Content-Type": "application/json",
483
+ "x-goog-api-key": apiKey
410
484
  };
411
485
  if (request.config.headers) {
412
486
  for (const [key, value] of Object.entries(request.config.headers)) {
@@ -427,7 +501,7 @@ function createLLMHandler() {
427
501
  "google",
428
502
  "llm"
429
503
  );
430
- const data = await response.json();
504
+ const data = await parseJsonResponse(response, "google", "llm");
431
505
  return transformResponse(data);
432
506
  },
433
507
  stream(request) {
@@ -446,10 +520,12 @@ function createLLMHandler() {
446
520
  "google",
447
521
  "llm"
448
522
  );
449
- const url = request.config.baseUrl ? `${request.config.baseUrl}/models/${modelId}:streamGenerateContent?alt=sse&key=${apiKey}` : `${buildUrl(modelId, "streamGenerateContent", apiKey)}&alt=sse`;
523
+ const url = request.config.baseUrl ? `${request.config.baseUrl}/models/${modelId}:streamGenerateContent?alt=sse` : `${buildUrl(modelId, "streamGenerateContent")}?alt=sse`;
450
524
  const body = transformRequest(request, modelId);
451
525
  const headers = {
452
- "Content-Type": "application/json"
526
+ "Content-Type": "application/json",
527
+ Accept: "text/event-stream",
528
+ "x-goog-api-key": apiKey
453
529
  };
454
530
  if (request.config.headers) {
455
531
  for (const [key, value] of Object.entries(request.config.headers)) {
@@ -506,8 +582,9 @@ function createLLMHandler() {
506
582
  }
507
583
  responseResolve(buildResponseFromState(state));
508
584
  } catch (error) {
509
- responseReject(error);
510
- throw error;
585
+ const err = toError(error);
586
+ responseReject(err);
587
+ throw err;
511
588
  }
512
589
  }
513
590
  return {
@@ -574,9 +651,10 @@ function createEmbeddingHandler() {
574
651
  };
575
652
  return embedRequest;
576
653
  });
577
- const url = `${baseUrl}/models/${modelId}:batchEmbedContents?key=${apiKey}`;
654
+ const url = `${baseUrl}/models/${modelId}:batchEmbedContents`;
578
655
  const headers = {
579
- "Content-Type": "application/json"
656
+ "Content-Type": "application/json",
657
+ "x-goog-api-key": apiKey
580
658
  };
581
659
  if (request.config.headers) {
582
660
  for (const [key, value] of Object.entries(request.config.headers)) {
@@ -591,7 +669,7 @@ function createEmbeddingHandler() {
591
669
  body: JSON.stringify({ requests }),
592
670
  signal: request.signal
593
671
  }, request.config, "google", "embedding");
594
- const data = await response.json();
672
+ const data = await parseJsonResponse(response, "google", "embedding");
595
673
  let totalTokens = 0;
596
674
  for (const emb of data.embeddings) {
597
675
  totalTokens += emb.statistics?.tokenCount ?? 0;
@@ -687,7 +765,7 @@ async function executeGenerate(modelId, request) {
687
765
  body: JSON.stringify(body),
688
766
  signal: request.signal
689
767
  }, request.config, "google", "image");
690
- const data = await response.json();
768
+ const data = await parseJsonResponse(response, "google", "image");
691
769
  return transformResponse2(data);
692
770
  }
693
771
  function buildParameters(params) {
@@ -716,10 +794,19 @@ function transformResponse2(data) {
716
794
  }
717
795
 
718
796
  // src/providers/google/cache.ts
719
- var CACHE_API_BASE = "https://generativelanguage.googleapis.com/v1beta/cachedContents";
797
+ var DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
798
+ function resolveBaseUrl(config) {
799
+ if (config?.baseUrl) {
800
+ const trimmed = config.baseUrl.replace(/\/$/, "");
801
+ return trimmed.endsWith("/v1beta") ? trimmed : `${trimmed}/v1beta`;
802
+ }
803
+ return DEFAULT_BASE_URL;
804
+ }
720
805
  async function create(options) {
721
806
  const {
722
807
  apiKey,
808
+ config,
809
+ signal,
723
810
  model,
724
811
  displayName,
725
812
  contents,
@@ -728,6 +815,8 @@ async function create(options) {
728
815
  ttl,
729
816
  expireTime
730
817
  } = options;
818
+ const baseUrl = resolveBaseUrl(config);
819
+ const requestConfig = { ...config, apiKey };
731
820
  const requestBody = {
732
821
  model: model.startsWith("models/") ? model : `models/${model}`
733
822
  };
@@ -750,56 +839,163 @@ async function create(options) {
750
839
  } else if (expireTime) {
751
840
  requestBody.expireTime = expireTime;
752
841
  }
753
- const response = await fetch(`${CACHE_API_BASE}?key=${apiKey}`, {
754
- method: "POST",
755
- headers: { "Content-Type": "application/json" },
756
- body: JSON.stringify(requestBody)
757
- });
758
- if (!response.ok) {
759
- throw await normalizeHttpError(response, "google", "llm");
842
+ const headers = {
843
+ "Content-Type": "application/json",
844
+ "x-goog-api-key": apiKey
845
+ };
846
+ if (config?.headers) {
847
+ for (const [key, value] of Object.entries(config.headers)) {
848
+ if (value !== void 0) {
849
+ headers[key] = value;
850
+ }
851
+ }
760
852
  }
761
- return response.json();
853
+ const response = await doFetch(
854
+ `${baseUrl}/cachedContents`,
855
+ {
856
+ method: "POST",
857
+ headers,
858
+ body: JSON.stringify(requestBody),
859
+ signal
860
+ },
861
+ requestConfig,
862
+ "google",
863
+ "llm"
864
+ );
865
+ return parseJsonResponse(response, "google", "llm");
762
866
  }
763
- async function get(name, apiKey) {
867
+ async function get(name, apiKey, config, signal) {
764
868
  const cacheName = name.startsWith("cachedContents/") ? name : `cachedContents/${name}`;
765
- const url = `https://generativelanguage.googleapis.com/v1beta/${cacheName}?key=${apiKey}`;
766
- const response = await fetch(url, { method: "GET" });
767
- if (!response.ok) {
768
- throw await normalizeHttpError(response, "google", "llm");
869
+ const baseUrl = resolveBaseUrl(config);
870
+ const url = `${baseUrl}/${cacheName}`;
871
+ const requestConfig = { ...config, apiKey };
872
+ const headers = { "x-goog-api-key": apiKey };
873
+ if (config?.headers) {
874
+ for (const [key, value] of Object.entries(config.headers)) {
875
+ if (value !== void 0) {
876
+ headers[key] = value;
877
+ }
878
+ }
769
879
  }
770
- return response.json();
880
+ const response = await doFetch(
881
+ url,
882
+ {
883
+ method: "GET",
884
+ headers,
885
+ signal
886
+ },
887
+ requestConfig,
888
+ "google",
889
+ "llm"
890
+ );
891
+ return parseJsonResponse(response, "google", "llm");
771
892
  }
772
893
  async function list(options) {
773
- const { apiKey, pageSize, pageToken } = options;
774
- const params = new URLSearchParams({ key: apiKey });
894
+ const { apiKey, config, signal, pageSize, pageToken } = options;
895
+ const baseUrl = resolveBaseUrl(config);
896
+ const requestConfig = { ...config, apiKey };
897
+ const params = new URLSearchParams();
775
898
  if (pageSize) params.set("pageSize", String(pageSize));
776
899
  if (pageToken) params.set("pageToken", pageToken);
777
- const response = await fetch(`${CACHE_API_BASE}?${params}`, { method: "GET" });
778
- if (!response.ok) {
779
- throw await normalizeHttpError(response, "google", "llm");
900
+ const headers = { "x-goog-api-key": apiKey };
901
+ if (config?.headers) {
902
+ for (const [key, value] of Object.entries(config.headers)) {
903
+ if (value !== void 0) {
904
+ headers[key] = value;
905
+ }
906
+ }
780
907
  }
781
- return response.json();
908
+ const response = await doFetch(
909
+ `${baseUrl}/cachedContents?${params}`,
910
+ {
911
+ method: "GET",
912
+ headers,
913
+ signal
914
+ },
915
+ requestConfig,
916
+ "google",
917
+ "llm"
918
+ );
919
+ return parseJsonResponse(response, "google", "llm");
782
920
  }
783
- async function update(name, updateRequest, apiKey) {
921
+ async function update(name, updateRequest, apiKey, config, signal) {
922
+ if (updateRequest.expireTime && updateRequest.ttl) {
923
+ throw new UPPError(
924
+ "Provide either expireTime or ttl (not both)",
925
+ "INVALID_REQUEST",
926
+ "google",
927
+ "llm"
928
+ );
929
+ }
930
+ const updateMaskParts = [];
931
+ if (updateRequest.expireTime) {
932
+ updateMaskParts.push("expireTime");
933
+ }
934
+ if (updateRequest.ttl) {
935
+ updateMaskParts.push("ttl");
936
+ }
937
+ if (updateMaskParts.length === 0) {
938
+ throw new UPPError(
939
+ "Update request must include expireTime or ttl",
940
+ "INVALID_REQUEST",
941
+ "google",
942
+ "llm"
943
+ );
944
+ }
784
945
  const cacheName = name.startsWith("cachedContents/") ? name : `cachedContents/${name}`;
785
- const url = `https://generativelanguage.googleapis.com/v1beta/${cacheName}?key=${apiKey}`;
786
- const response = await fetch(url, {
787
- method: "PATCH",
788
- headers: { "Content-Type": "application/json" },
789
- body: JSON.stringify(updateRequest)
790
- });
791
- if (!response.ok) {
792
- throw await normalizeHttpError(response, "google", "llm");
946
+ const baseUrl = resolveBaseUrl(config);
947
+ const params = new URLSearchParams({ updateMask: updateMaskParts.join(",") });
948
+ const url = `${baseUrl}/${cacheName}?${params.toString()}`;
949
+ const requestConfig = { ...config, apiKey };
950
+ const headers = {
951
+ "Content-Type": "application/json",
952
+ "x-goog-api-key": apiKey
953
+ };
954
+ if (config?.headers) {
955
+ for (const [key, value] of Object.entries(config.headers)) {
956
+ if (value !== void 0) {
957
+ headers[key] = value;
958
+ }
959
+ }
793
960
  }
794
- return response.json();
961
+ const response = await doFetch(
962
+ url,
963
+ {
964
+ method: "PATCH",
965
+ headers,
966
+ body: JSON.stringify(updateRequest),
967
+ signal
968
+ },
969
+ requestConfig,
970
+ "google",
971
+ "llm"
972
+ );
973
+ return parseJsonResponse(response, "google", "llm");
795
974
  }
796
- async function deleteCache(name, apiKey) {
975
+ async function deleteCache(name, apiKey, config, signal) {
797
976
  const cacheName = name.startsWith("cachedContents/") ? name : `cachedContents/${name}`;
798
- const url = `https://generativelanguage.googleapis.com/v1beta/${cacheName}?key=${apiKey}`;
799
- const response = await fetch(url, { method: "DELETE" });
800
- if (!response.ok) {
801
- throw await normalizeHttpError(response, "google", "llm");
977
+ const baseUrl = resolveBaseUrl(config);
978
+ const url = `${baseUrl}/${cacheName}`;
979
+ const requestConfig = { ...config, apiKey };
980
+ const headers = { "x-goog-api-key": apiKey };
981
+ if (config?.headers) {
982
+ for (const [key, value] of Object.entries(config.headers)) {
983
+ if (value !== void 0) {
984
+ headers[key] = value;
985
+ }
986
+ }
802
987
  }
988
+ const response = await doFetch(
989
+ url,
990
+ {
991
+ method: "DELETE",
992
+ headers,
993
+ signal
994
+ },
995
+ requestConfig,
996
+ "google",
997
+ "llm"
998
+ );
803
999
  }
804
1000
  var cache = {
805
1001
  create,