@yourgpt/llm-sdk 2.6.0-beta.0 → 2.6.0-beta.2

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 (64) hide show
  1. package/README.md +189 -0
  2. package/dist/adapters/index.d.mts +11 -13
  3. package/dist/adapters/index.d.ts +11 -13
  4. package/dist/adapters/index.js +610 -186
  5. package/dist/adapters/index.mjs +610 -186
  6. package/dist/audio-BBSwnjo8.d.mts +92 -0
  7. package/dist/audio-BBSwnjo8.d.ts +92 -0
  8. package/dist/{base-tNgbBaSo.d.mts → base-BICaQaRS.d.mts} +8 -3
  9. package/dist/{base-C58Dsr9p.d.ts → base-CpRPB8u8.d.ts} +8 -3
  10. package/dist/fallback/index.d.mts +4 -4
  11. package/dist/fallback/index.d.ts +4 -4
  12. package/dist/fallback/index.js +75 -39
  13. package/dist/fallback/index.mjs +75 -39
  14. package/dist/index.d.mts +18 -35
  15. package/dist/index.d.ts +18 -35
  16. package/dist/index.js +304 -88
  17. package/dist/index.mjs +302 -89
  18. package/dist/providers/anthropic/index.d.mts +3 -3
  19. package/dist/providers/anthropic/index.d.ts +3 -3
  20. package/dist/providers/anthropic/index.js +123 -7
  21. package/dist/providers/anthropic/index.mjs +123 -7
  22. package/dist/providers/azure/index.d.mts +3 -3
  23. package/dist/providers/azure/index.d.ts +3 -3
  24. package/dist/providers/azure/index.js +101 -4
  25. package/dist/providers/azure/index.mjs +101 -4
  26. package/dist/providers/fireworks/index.d.mts +3 -3
  27. package/dist/providers/fireworks/index.d.ts +3 -3
  28. package/dist/providers/fireworks/index.js +559 -178
  29. package/dist/providers/fireworks/index.mjs +559 -178
  30. package/dist/providers/google/index.d.mts +3 -3
  31. package/dist/providers/google/index.d.ts +3 -3
  32. package/dist/providers/google/index.js +559 -178
  33. package/dist/providers/google/index.mjs +559 -178
  34. package/dist/providers/ollama/index.d.mts +4 -4
  35. package/dist/providers/ollama/index.d.ts +4 -4
  36. package/dist/providers/ollama/index.js +87 -2
  37. package/dist/providers/ollama/index.mjs +87 -2
  38. package/dist/providers/openai/index.d.mts +25 -23
  39. package/dist/providers/openai/index.d.ts +25 -23
  40. package/dist/providers/openai/index.js +1397 -481
  41. package/dist/providers/openai/index.mjs +1396 -482
  42. package/dist/providers/openrouter/index.d.mts +3 -3
  43. package/dist/providers/openrouter/index.d.ts +3 -3
  44. package/dist/providers/openrouter/index.js +559 -178
  45. package/dist/providers/openrouter/index.mjs +559 -178
  46. package/dist/providers/togetherai/index.d.mts +3 -3
  47. package/dist/providers/togetherai/index.d.ts +3 -3
  48. package/dist/providers/togetherai/index.js +559 -178
  49. package/dist/providers/togetherai/index.mjs +559 -178
  50. package/dist/providers/xai/index.d.mts +3 -3
  51. package/dist/providers/xai/index.d.ts +3 -3
  52. package/dist/providers/xai/index.js +559 -178
  53. package/dist/providers/xai/index.mjs +559 -178
  54. package/dist/{types-B6dhnguR.d.mts → types-C3RgRbEC.d.mts} +11 -4
  55. package/dist/{types-CCxPmkmK.d.ts → types-DCFqkJAy.d.ts} +11 -4
  56. package/dist/{types-BQ31QIsA.d.ts → types-DHQEMFHA.d.mts} +3 -11
  57. package/dist/{types-BkQCSiIt.d.mts → types-Dg1Bcg1k.d.mts} +127 -3
  58. package/dist/{types-BkQCSiIt.d.ts → types-Dg1Bcg1k.d.ts} +127 -3
  59. package/dist/{types-BSSiJW2o.d.mts → types-Dikj3En4.d.ts} +3 -11
  60. package/dist/yourgpt/index.d.mts +1 -1
  61. package/dist/yourgpt/index.d.ts +1 -1
  62. package/docs/multimodal-and-audio.md +170 -0
  63. package/package.json +117 -49
  64. package/LICENSE +0 -21
@@ -1,8 +1,8 @@
1
- import { c as OllamaProviderConfig, A as AIProvider } from '../../types-BSSiJW2o.mjs';
2
- export { d as OllamaModelOptions } from '../../types-BSSiJW2o.mjs';
3
- import '../../types-BkQCSiIt.mjs';
1
+ import { c as OllamaProviderConfig, A as AIProvider } from '../../types-DHQEMFHA.mjs';
2
+ export { d as OllamaModelOptions } from '../../types-DHQEMFHA.mjs';
3
+ import '../../types-Dg1Bcg1k.mjs';
4
4
  import 'zod';
5
- import '../../base-tNgbBaSo.mjs';
5
+ import '../../base-BICaQaRS.mjs';
6
6
 
7
7
  /**
8
8
  * Ollama Provider
@@ -1,8 +1,8 @@
1
- import { c as OllamaProviderConfig, A as AIProvider } from '../../types-BQ31QIsA.js';
2
- export { d as OllamaModelOptions } from '../../types-BQ31QIsA.js';
3
- import '../../types-BkQCSiIt.js';
1
+ import { c as OllamaProviderConfig, A as AIProvider } from '../../types-Dikj3En4.js';
2
+ export { d as OllamaModelOptions } from '../../types-Dikj3En4.js';
3
+ import '../../types-Dg1Bcg1k.js';
4
4
  import 'zod';
5
- import '../../base-C58Dsr9p.js';
5
+ import '../../base-CpRPB8u8.js';
6
6
 
7
7
  /**
8
8
  * Ollama Provider
@@ -1,5 +1,90 @@
1
1
  'use strict';
2
2
 
3
+ // src/core/tool-output.ts
4
+ var imageTypes = /* @__PURE__ */ new Set([
5
+ "image/png",
6
+ "image/jpeg",
7
+ "image/webp",
8
+ "image/gif"
9
+ ]);
10
+ function normalizeToolOutput(value) {
11
+ const output = value;
12
+ if (output?.type !== "content" || !Array.isArray(output.content) || !output.content.length) {
13
+ throw new Error("Tool model output must contain a nonempty content array");
14
+ }
15
+ return {
16
+ type: "content",
17
+ content: output.content.map((part) => {
18
+ if (part?.type === "text" && typeof part.text === "string")
19
+ return { type: "text", text: part.text };
20
+ if (part?.type !== "image")
21
+ throw new Error("Unsupported tool output content type");
22
+ const sources = ["data", "url", "fileId"].filter((key) => key in part);
23
+ if (sources.length !== 1)
24
+ throw new Error(
25
+ "Tool image requires exactly one of data, url, or fileId"
26
+ );
27
+ if ("fileId" in part) {
28
+ if (part.provider !== "openai" || typeof part.fileId !== "string" || !part.fileId.trim())
29
+ throw new Error(
30
+ "Tool image file references must name the openai provider and fileId"
31
+ );
32
+ return { type: "image", fileId: part.fileId, provider: "openai" };
33
+ }
34
+ if ("url" in part) {
35
+ let url;
36
+ try {
37
+ url = new URL(part.url);
38
+ } catch {
39
+ throw new Error("Invalid tool image URL");
40
+ }
41
+ if (!["https:", "http:"].includes(url.protocol) || url.username || url.password)
42
+ throw new Error(
43
+ "Tool image URL must use HTTP(S) without credentials"
44
+ );
45
+ return { type: "image", url: url.href };
46
+ }
47
+ if (!("data" in part) || !imageTypes.has(part.mediaType))
48
+ throw new Error("Unsupported tool image media type");
49
+ let data = part.data instanceof Uint8Array ? Buffer.from(part.data).toString("base64") : part.data;
50
+ if (typeof data !== "string")
51
+ throw new Error("Tool image data must be base64 or bytes");
52
+ if (data.startsWith("data:")) {
53
+ const match = /^data:([^;,]+);base64,(.+)$/.exec(data);
54
+ if (!match || match[1] !== part.mediaType)
55
+ throw new Error(
56
+ "Tool image data URL media type does not match mediaType"
57
+ );
58
+ data = match[2];
59
+ }
60
+ if (!data.length || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(data))
61
+ throw new Error("Invalid tool image base64 data");
62
+ if (Buffer.byteLength(data, "base64") > 20 * 1024 * 1024)
63
+ throw new Error("Tool image exceeds 20 MiB");
64
+ if (Buffer.from(data, "base64").toString("base64") !== data)
65
+ throw new Error("Invalid tool image base64 data");
66
+ return { type: "image", data, mediaType: part.mediaType };
67
+ })
68
+ };
69
+ }
70
+ function toolOutputForProvider(value, provider) {
71
+ const output = normalizeToolOutput(value);
72
+ return output.content.map((part) => {
73
+ if (part.type === "text")
74
+ return {
75
+ type: "text",
76
+ text: part.text
77
+ };
78
+ throw new Error(
79
+ "Image tool results require OpenAI Responses or Anthropic; this endpoint is not supported"
80
+ );
81
+ });
82
+ }
83
+ function textToolOutput(value, fallback) {
84
+ if (value === void 0) return fallback;
85
+ return toolOutputForProvider(value).map((part) => part.text).join("\n");
86
+ }
87
+
3
88
  // src/core/utils.ts
4
89
  function generateId(prefix = "id") {
5
90
  return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
@@ -150,7 +235,7 @@ async function formatMessagesForOllama(messages, systemPrompt) {
150
235
  for (const msg of messages) {
151
236
  const baseMessage = {
152
237
  role: msg.role,
153
- content: msg.content ?? ""
238
+ content: msg.role === "tool" ? textToolOutput(msg.modelOutput, msg.content ?? "") : msg.content ?? ""
154
239
  };
155
240
  if (msg.role === "user" && msg.metadata?.attachments) {
156
241
  const images = await extractImagesFromAttachments(
@@ -187,7 +272,7 @@ async function processRawMessagesForOllama(rawMessages, systemPrompt) {
187
272
  for (const msg of rawMessages) {
188
273
  const baseMessage = {
189
274
  role: msg.role,
190
- content: msg.content ?? ""
275
+ content: msg.role === "tool" ? textToolOutput(msg.modelOutput, String(msg.content ?? "")) : msg.content ?? ""
191
276
  };
192
277
  if (msg.role === "user" && msg.attachments && Array.isArray(msg.attachments)) {
193
278
  const attachments = msg.attachments;
@@ -1,3 +1,88 @@
1
+ // src/core/tool-output.ts
2
+ var imageTypes = /* @__PURE__ */ new Set([
3
+ "image/png",
4
+ "image/jpeg",
5
+ "image/webp",
6
+ "image/gif"
7
+ ]);
8
+ function normalizeToolOutput(value) {
9
+ const output = value;
10
+ if (output?.type !== "content" || !Array.isArray(output.content) || !output.content.length) {
11
+ throw new Error("Tool model output must contain a nonempty content array");
12
+ }
13
+ return {
14
+ type: "content",
15
+ content: output.content.map((part) => {
16
+ if (part?.type === "text" && typeof part.text === "string")
17
+ return { type: "text", text: part.text };
18
+ if (part?.type !== "image")
19
+ throw new Error("Unsupported tool output content type");
20
+ const sources = ["data", "url", "fileId"].filter((key) => key in part);
21
+ if (sources.length !== 1)
22
+ throw new Error(
23
+ "Tool image requires exactly one of data, url, or fileId"
24
+ );
25
+ if ("fileId" in part) {
26
+ if (part.provider !== "openai" || typeof part.fileId !== "string" || !part.fileId.trim())
27
+ throw new Error(
28
+ "Tool image file references must name the openai provider and fileId"
29
+ );
30
+ return { type: "image", fileId: part.fileId, provider: "openai" };
31
+ }
32
+ if ("url" in part) {
33
+ let url;
34
+ try {
35
+ url = new URL(part.url);
36
+ } catch {
37
+ throw new Error("Invalid tool image URL");
38
+ }
39
+ if (!["https:", "http:"].includes(url.protocol) || url.username || url.password)
40
+ throw new Error(
41
+ "Tool image URL must use HTTP(S) without credentials"
42
+ );
43
+ return { type: "image", url: url.href };
44
+ }
45
+ if (!("data" in part) || !imageTypes.has(part.mediaType))
46
+ throw new Error("Unsupported tool image media type");
47
+ let data = part.data instanceof Uint8Array ? Buffer.from(part.data).toString("base64") : part.data;
48
+ if (typeof data !== "string")
49
+ throw new Error("Tool image data must be base64 or bytes");
50
+ if (data.startsWith("data:")) {
51
+ const match = /^data:([^;,]+);base64,(.+)$/.exec(data);
52
+ if (!match || match[1] !== part.mediaType)
53
+ throw new Error(
54
+ "Tool image data URL media type does not match mediaType"
55
+ );
56
+ data = match[2];
57
+ }
58
+ if (!data.length || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(data))
59
+ throw new Error("Invalid tool image base64 data");
60
+ if (Buffer.byteLength(data, "base64") > 20 * 1024 * 1024)
61
+ throw new Error("Tool image exceeds 20 MiB");
62
+ if (Buffer.from(data, "base64").toString("base64") !== data)
63
+ throw new Error("Invalid tool image base64 data");
64
+ return { type: "image", data, mediaType: part.mediaType };
65
+ })
66
+ };
67
+ }
68
+ function toolOutputForProvider(value, provider) {
69
+ const output = normalizeToolOutput(value);
70
+ return output.content.map((part) => {
71
+ if (part.type === "text")
72
+ return {
73
+ type: "text",
74
+ text: part.text
75
+ };
76
+ throw new Error(
77
+ "Image tool results require OpenAI Responses or Anthropic; this endpoint is not supported"
78
+ );
79
+ });
80
+ }
81
+ function textToolOutput(value, fallback) {
82
+ if (value === void 0) return fallback;
83
+ return toolOutputForProvider(value).map((part) => part.text).join("\n");
84
+ }
85
+
1
86
  // src/core/utils.ts
2
87
  function generateId(prefix = "id") {
3
88
  return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
@@ -148,7 +233,7 @@ async function formatMessagesForOllama(messages, systemPrompt) {
148
233
  for (const msg of messages) {
149
234
  const baseMessage = {
150
235
  role: msg.role,
151
- content: msg.content ?? ""
236
+ content: msg.role === "tool" ? textToolOutput(msg.modelOutput, msg.content ?? "") : msg.content ?? ""
152
237
  };
153
238
  if (msg.role === "user" && msg.metadata?.attachments) {
154
239
  const images = await extractImagesFromAttachments(
@@ -185,7 +270,7 @@ async function processRawMessagesForOllama(rawMessages, systemPrompt) {
185
270
  for (const msg of rawMessages) {
186
271
  const baseMessage = {
187
272
  role: msg.role,
188
- content: msg.content ?? ""
273
+ content: msg.role === "tool" ? textToolOutput(msg.modelOutput, String(msg.content ?? "")) : msg.content ?? ""
189
274
  };
190
275
  if (msg.role === "user" && msg.attachments && Array.isArray(msg.attachments)) {
191
276
  const attachments = msg.attachments;
@@ -1,27 +1,11 @@
1
- import { L as LanguageModel } from '../../types-BkQCSiIt.mjs';
2
- import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-BSSiJW2o.mjs';
1
+ import { ae as OpenAIParameterOptions, O as OpenAITransportOptions, L as LanguageModel } from '../../types-Dg1Bcg1k.mjs';
2
+ export { h as OpenAIReasoningEffort, ab as OpenAIResponseItem, ac as OpenAIResponseMetadata, aa as OpenAIResponsesOptions, P as ProviderMetadata } from '../../types-Dg1Bcg1k.mjs';
3
+ import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-DHQEMFHA.mjs';
4
+ import { S as SpeechModel, T as TranscriptionModel } from '../../audio-BBSwnjo8.mjs';
3
5
  import 'zod';
4
- import '../../base-tNgbBaSo.mjs';
6
+ import '../../base-BICaQaRS.mjs';
5
7
 
6
- /**
7
- * OpenAI Provider - Modern Pattern
8
- *
9
- * Returns a LanguageModel instance that can be used directly with
10
- * generateText() and streamText().
11
- *
12
- * @example
13
- * ```ts
14
- * import { openai } from '@yourgpt/llm-sdk/openai';
15
- * import { generateText } from '@yourgpt/llm-sdk';
16
- *
17
- * const result = await generateText({
18
- * model: openai('gpt-4o'),
19
- * prompt: 'Hello!',
20
- * });
21
- * ```
22
- */
23
-
24
- interface OpenAIProviderOptions {
8
+ interface OpenAIProviderOptions extends OpenAIParameterOptions, OpenAITransportOptions {
25
9
  /** API key (defaults to OPENAI_API_KEY env var) */
26
10
  apiKey?: string;
27
11
  /** Base URL for API (defaults to https://api.openai.com/v1) */
@@ -52,6 +36,24 @@ interface OpenAIProviderOptions {
52
36
  */
53
37
  declare function openai(modelId: string, options?: OpenAIProviderOptions): LanguageModel;
54
38
 
39
+ interface OpenAIAudioProviderOptions {
40
+ apiKey?: string;
41
+ baseUrl?: string;
42
+ organization?: string;
43
+ project?: string;
44
+ /** Custom fetch for proxies and tests. */
45
+ fetch?: typeof globalThis.fetch;
46
+ }
47
+ interface OpenAITranscriptionOptions {
48
+ timestampGranularities?: Array<"word" | "segment">;
49
+ includeLogprobs?: boolean;
50
+ chunkingStrategy?: "auto";
51
+ }
52
+ /** Server-side, buffered text-to-speech. No microphone or realtime session. */
53
+ declare function openaiSpeech(modelId?: string, config?: OpenAIAudioProviderOptions): SpeechModel;
54
+ /** Recorded-file transcription. Timestamp and diarization options are model-gated. */
55
+ declare function openaiTranscription(modelId?: string, config?: OpenAIAudioProviderOptions): TranscriptionModel;
56
+
55
57
  /**
56
58
  * OpenAI Provider
57
59
  *
@@ -84,4 +86,4 @@ declare function openai(modelId: string, options?: OpenAIProviderOptions): Langu
84
86
  declare function createOpenAI(config?: OpenAIProviderConfig): AIProvider;
85
87
  declare const createOpenAIProvider: typeof createOpenAI;
86
88
 
87
- export { type OpenAIProviderOptions, createOpenAI, openai as createOpenAIModel, createOpenAIProvider, openai };
89
+ export { type OpenAIAudioProviderOptions, OpenAIParameterOptions, type OpenAIProviderOptions, type OpenAITranscriptionOptions, OpenAITransportOptions, createOpenAI, openai as createOpenAIModel, createOpenAIProvider, openai, openaiSpeech, openaiTranscription };
@@ -1,27 +1,11 @@
1
- import { L as LanguageModel } from '../../types-BkQCSiIt.js';
2
- import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-BQ31QIsA.js';
1
+ import { ae as OpenAIParameterOptions, O as OpenAITransportOptions, L as LanguageModel } from '../../types-Dg1Bcg1k.js';
2
+ export { h as OpenAIReasoningEffort, ab as OpenAIResponseItem, ac as OpenAIResponseMetadata, aa as OpenAIResponsesOptions, P as ProviderMetadata } from '../../types-Dg1Bcg1k.js';
3
+ import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-Dikj3En4.js';
4
+ import { S as SpeechModel, T as TranscriptionModel } from '../../audio-BBSwnjo8.js';
3
5
  import 'zod';
4
- import '../../base-C58Dsr9p.js';
6
+ import '../../base-CpRPB8u8.js';
5
7
 
6
- /**
7
- * OpenAI Provider - Modern Pattern
8
- *
9
- * Returns a LanguageModel instance that can be used directly with
10
- * generateText() and streamText().
11
- *
12
- * @example
13
- * ```ts
14
- * import { openai } from '@yourgpt/llm-sdk/openai';
15
- * import { generateText } from '@yourgpt/llm-sdk';
16
- *
17
- * const result = await generateText({
18
- * model: openai('gpt-4o'),
19
- * prompt: 'Hello!',
20
- * });
21
- * ```
22
- */
23
-
24
- interface OpenAIProviderOptions {
8
+ interface OpenAIProviderOptions extends OpenAIParameterOptions, OpenAITransportOptions {
25
9
  /** API key (defaults to OPENAI_API_KEY env var) */
26
10
  apiKey?: string;
27
11
  /** Base URL for API (defaults to https://api.openai.com/v1) */
@@ -52,6 +36,24 @@ interface OpenAIProviderOptions {
52
36
  */
53
37
  declare function openai(modelId: string, options?: OpenAIProviderOptions): LanguageModel;
54
38
 
39
+ interface OpenAIAudioProviderOptions {
40
+ apiKey?: string;
41
+ baseUrl?: string;
42
+ organization?: string;
43
+ project?: string;
44
+ /** Custom fetch for proxies and tests. */
45
+ fetch?: typeof globalThis.fetch;
46
+ }
47
+ interface OpenAITranscriptionOptions {
48
+ timestampGranularities?: Array<"word" | "segment">;
49
+ includeLogprobs?: boolean;
50
+ chunkingStrategy?: "auto";
51
+ }
52
+ /** Server-side, buffered text-to-speech. No microphone or realtime session. */
53
+ declare function openaiSpeech(modelId?: string, config?: OpenAIAudioProviderOptions): SpeechModel;
54
+ /** Recorded-file transcription. Timestamp and diarization options are model-gated. */
55
+ declare function openaiTranscription(modelId?: string, config?: OpenAIAudioProviderOptions): TranscriptionModel;
56
+
55
57
  /**
56
58
  * OpenAI Provider
57
59
  *
@@ -84,4 +86,4 @@ declare function openai(modelId: string, options?: OpenAIProviderOptions): Langu
84
86
  declare function createOpenAI(config?: OpenAIProviderConfig): AIProvider;
85
87
  declare const createOpenAIProvider: typeof createOpenAI;
86
88
 
87
- export { type OpenAIProviderOptions, createOpenAI, openai as createOpenAIModel, createOpenAIProvider, openai };
89
+ export { type OpenAIAudioProviderOptions, OpenAIParameterOptions, type OpenAIProviderOptions, type OpenAITranscriptionOptions, OpenAITransportOptions, createOpenAI, openai as createOpenAIModel, createOpenAIProvider, openai, openaiSpeech, openaiTranscription };