@yourgpt/llm-sdk 2.6.0-beta.1 → 2.6.0-beta.3

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 (61) hide show
  1. package/README.md +146 -0
  2. package/dist/adapters/index.d.mts +5 -5
  3. package/dist/adapters/index.d.ts +5 -5
  4. package/dist/adapters/index.js +437 -39
  5. package/dist/adapters/index.mjs +437 -39
  6. package/dist/audio-BBSwnjo8.d.mts +92 -0
  7. package/dist/audio-BBSwnjo8.d.ts +92 -0
  8. package/dist/{base-CkeT7u-O.d.mts → base-BICaQaRS.d.mts} +7 -3
  9. package/dist/{base-BdTpUAWI.d.ts → base-CpRPB8u8.d.ts} +7 -3
  10. package/dist/fallback/index.d.mts +4 -4
  11. package/dist/fallback/index.d.ts +4 -4
  12. package/dist/index.d.mts +20 -36
  13. package/dist/index.d.ts +20 -36
  14. package/dist/index.js +327 -69
  15. package/dist/index.mjs +325 -70
  16. package/dist/providers/anthropic/index.d.mts +3 -3
  17. package/dist/providers/anthropic/index.d.ts +3 -3
  18. package/dist/providers/anthropic/index.js +116 -7
  19. package/dist/providers/anthropic/index.mjs +116 -7
  20. package/dist/providers/azure/index.d.mts +3 -3
  21. package/dist/providers/azure/index.d.ts +3 -3
  22. package/dist/providers/azure/index.js +101 -4
  23. package/dist/providers/azure/index.mjs +101 -4
  24. package/dist/providers/fireworks/index.d.mts +3 -3
  25. package/dist/providers/fireworks/index.d.ts +3 -3
  26. package/dist/providers/fireworks/index.js +393 -31
  27. package/dist/providers/fireworks/index.mjs +393 -31
  28. package/dist/providers/google/index.d.mts +3 -3
  29. package/dist/providers/google/index.d.ts +3 -3
  30. package/dist/providers/google/index.js +393 -31
  31. package/dist/providers/google/index.mjs +393 -31
  32. package/dist/providers/ollama/index.d.mts +4 -4
  33. package/dist/providers/ollama/index.d.ts +4 -4
  34. package/dist/providers/ollama/index.js +87 -2
  35. package/dist/providers/ollama/index.mjs +87 -2
  36. package/dist/providers/openai/index.d.mts +25 -6
  37. package/dist/providers/openai/index.d.ts +25 -6
  38. package/dist/providers/openai/index.js +822 -40
  39. package/dist/providers/openai/index.mjs +821 -41
  40. package/dist/providers/openrouter/index.d.mts +3 -3
  41. package/dist/providers/openrouter/index.d.ts +3 -3
  42. package/dist/providers/openrouter/index.js +393 -31
  43. package/dist/providers/openrouter/index.mjs +393 -31
  44. package/dist/providers/togetherai/index.d.mts +3 -3
  45. package/dist/providers/togetherai/index.d.ts +3 -3
  46. package/dist/providers/togetherai/index.js +393 -31
  47. package/dist/providers/togetherai/index.mjs +393 -31
  48. package/dist/providers/xai/index.d.mts +3 -3
  49. package/dist/providers/xai/index.d.ts +3 -3
  50. package/dist/providers/xai/index.js +393 -31
  51. package/dist/providers/xai/index.mjs +393 -31
  52. package/dist/{types-BWRYIvl_.d.mts → types-C3RgRbEC.d.mts} +1 -1
  53. package/dist/{types-CpXcT-tY.d.ts → types-DCFqkJAy.d.ts} +1 -1
  54. package/dist/{types-NOswlhm9.d.mts → types-DHQEMFHA.d.mts} +3 -3
  55. package/dist/{types-BW3csYo5.d.mts → types-Dg1Bcg1k.d.mts} +106 -3
  56. package/dist/{types-BW3csYo5.d.ts → types-Dg1Bcg1k.d.ts} +106 -3
  57. package/dist/{types-DA54bSmX.d.ts → types-Dikj3En4.d.ts} +3 -3
  58. package/dist/yourgpt/index.d.mts +1 -1
  59. package/dist/yourgpt/index.d.ts +1 -1
  60. package/docs/multimodal-and-audio.md +170 -0
  61. package/package.json +3 -2
package/README.md CHANGED
@@ -44,6 +44,108 @@ endpoints keep Chat routing. Servers with different parameter rules can set
44
44
  installed OpenAI client that exposes `responses.create`; older clients fail with
45
45
  an actionable error. This routing does not add the separate Decisions API.
46
46
 
47
+ ## OpenAI Responses and continuation
48
+
49
+ Select Responses explicitly, including calls without tools:
50
+
51
+ ```ts
52
+ import { generateText, streamText } from "@yourgpt/llm-sdk";
53
+ import { openai, createOpenAI } from "@yourgpt/llm-sdk/openai";
54
+
55
+ const model = openai("gpt-6-luna", {
56
+ api: "responses",
57
+ responses: { store: false },
58
+ });
59
+ const first = await generateText({ model, prompt: "Remember code ORBIT-42." });
60
+ const next = await streamText({
61
+ model,
62
+ messages: [
63
+ ...first.response.messages,
64
+ { role: "user", content: "What was the code?" },
65
+ ],
66
+ });
67
+ console.log(await next.text);
68
+ const history = (await next.response).messages;
69
+ const providerState = await next.providerMetadata;
70
+ ```
71
+
72
+ `api` accepts `"auto"` (the existing default routing), `"chat"`, and `"responses"`.
73
+ Responses options also select Responses. Default custom-endpoint routing remains
74
+ Chat; opt into Responses only when that endpoint implements it. Azure and other
75
+ compatible services are not certified by the OpenAI tests. Supplying
76
+ Responses-only options with `api: "chat"` fails before a network request.
77
+
78
+ The same options work on `createOpenAI({ api, responses })` for Runtime, and on
79
+ `OpenAIAdapter`. Per-call overrides use `generateText({ openai: { api, responses },
80
+ ... })` or `runtime.chat({ config: { openai: { api, responses } }, ... })`.
81
+ Request values override provider defaults. `reasoningEffort` remains a separate
82
+ existing option; `responses.reasoningSummary` requests a reasoning summary.
83
+
84
+ **Stateless replay:** use `store: false` and preserve the returned message objects,
85
+ including `providerMetadata`. Each assistant's `providerMetadata.openai.response`
86
+ contains minimal ordered continuation items, including function-call IDs, assistant
87
+ phase and completed encrypted reasoning. It excludes the raw response envelope,
88
+ native usage, logprobs, reasoning summaries and output-text annotations. Native
89
+ tool state needed for replay is retained with diagnostic fields removed. Streams
90
+ use completed items, never partially streamed reasoning. Keep this state intact
91
+ and within its original conversation; do not treat it as trusted authorization.
92
+
93
+ The separate **server-side model result** `providerMetadata` still contains the
94
+ full response ID, status, native usage and output for diagnostics and stored
95
+ continuation. Do not forward that complete model result to a public client.
96
+ `runtime.chat()` retains top-level `usage` for billing and `events` for debugging;
97
+ after billing, omit both before serializing it:
98
+
99
+ ```ts
100
+ const result = await runtime.chat(request);
101
+ await recordBilling(result.usage);
102
+ const { usage, events, ...clientResult } = result;
103
+ return Response.json(clientResult);
104
+ ```
105
+
106
+ SSE response helpers omit usage by default. `runtime.stream(...).toResponse({
107
+ includeUsage: true })` explicitly enables it for a server-controlled raw API.
108
+
109
+ `generateText().response.messages` now includes the final assistant turn as well
110
+ as tool turns. `streamText().response` returns the same complete history after
111
+ consuming its shared execution; accessing it does not make a second API call.
112
+ The Copilot client preserves provider state through JSON/SSE tool continuation
113
+ and serialized UI-message restoration. Custom `StorageAdapter` implementations
114
+ must retain `StorageMessage.metadata.providerMetadata`; map it back to the
115
+ message's top-level `providerMetadata` when restoring. The existing YourGPT cloud
116
+ storage adapter stores display/tool records and does **not** yet guarantee
117
+ lossless Responses replay after a remote session reload.
118
+
119
+ **Stored continuation:** explicitly use `store: true`, take the returned
120
+ `generateText(...).providerMetadata.openai.response.id` (the server result, not
121
+ the saved message metadata), and pass it as
122
+ `openai: { responses: { previousResponseId: id } }` on the next call. Send only new
123
+ input after that response, and resend system instructions; do not also resend
124
+ its entire history. The SDK does not automatically advance or persist response
125
+ IDs. If `store` is omitted, the provider default is unchanged (OpenAI currently
126
+ stores Responses by default).
127
+
128
+ Other supported Responses options are `include`, `promptCacheKey`,
129
+ `promptCacheOptions` (`mode`, `ttl`) and legacy `promptCacheRetention`
130
+ (`"in_memory"` or `"24h"`). With `store: false`, `reasoning.encrypted_content` is
131
+ included automatically. Cache options are forwarded; availability and retention
132
+ support remain model-specific. Raw usage preserves cache/reasoning breakdowns;
133
+ this does not add pricing/accounting logic.
134
+
135
+ Modern Responses accepts image URLs, data URLs/bytes, and file URL/base64 inputs.
136
+ This does not add generalized image-bearing function results, native MCP approval
137
+ flows, background jobs, or Decisions. Failed/incomplete/cancelled streams do not
138
+ produce executable partial function calls or a successful final result.
139
+
140
+ The contracts were checked against [OpenAI conversation state](https://developers.openai.com/api/docs/guides/conversation-state),
141
+ [Responses request fields](https://developers.openai.com/api/reference/resources/responses/methods/create),
142
+ and [Vercel's OpenAI provider](https://ai-sdk.dev/providers/ai-sdk-providers/openai).
143
+ Offline checks run with `pnpm --filter @yourgpt/llm-sdk test`; Copilot integration
144
+ checks run with `pnpm test:compatibility` after building both SDKs. The optional
145
+ `test/live/responses.cjs` runner requires `RUN_OPENAI_LIVE=1` and a privately
146
+ supplied `OPENAI_API_KEY`; it makes real requests and deletes its synthetic stored
147
+ responses after testing continuation.
148
+
47
149
  ## Compatibility fallback
48
150
 
49
151
  Transient failures retain bounded retries and fallback. Compatibility errors such
@@ -132,6 +234,28 @@ export async function POST(req: Request) {
132
234
  }
133
235
  ```
134
236
 
237
+ For Anthropic, Runtime accepts system instructions through either `systemPrompt`
238
+ or `{ role: "system", content: "..." }` messages. It combines them into
239
+ Anthropic's top-level `system` field: the request's nonempty `systemPrompt` (or
240
+ the runtime default) first, followed by system messages in order. System messages
241
+ are removed from the conversation sent to Anthropic. This applies to `chat`,
242
+ `generate`, `stream`, and `processChat`. If the same text is supplied through both
243
+ forms, the explicit prompt is sent once. Null, non-text values and unsupported
244
+ system blocks are ignored for proxy compatibility; valid text blocks are retained.
245
+ Repeated message-only instructions are preserved in order.
246
+
247
+ ```ts
248
+ const decision = await runtime.chat({
249
+ systemPrompt: "Classify the email. Do not answer it.",
250
+ messages: [{ role: "user", content: emailContext }],
251
+ });
252
+ ```
253
+
254
+ The published `2.6.0-beta.1` Runtime adapter silently dropped system-role
255
+ messages; use the explicit `systemPrompt` form above until you upgrade to a release
256
+ containing this fix. The separate `generateText`/`streamText` Anthropic provider
257
+ already handles system-role messages.
258
+
135
259
  ## Selective Tool Loading
136
260
 
137
261
  `llm-sdk` can now narrow tools before they reach the provider. This is opt-in and works with both local ranking and provider-native hints.
@@ -203,3 +327,25 @@ Visit **[copilot-sdk.yourgpt.ai](https://copilot-sdk.yourgpt.ai)** for full docu
203
327
  ## License
204
328
 
205
329
  MIT
330
+
331
+ ### Image tool results and recorded audio
332
+
333
+ Tools can return native image content using `toModelOutput` or the existing `_aiContent` field. Supported endpoints are OpenAI Responses and Anthropic. Raw application results remain available, and model-facing output survives tool continuation and serialized history. Unsupported endpoints reject image output explicitly.
334
+
335
+ `generateSpeech` / `transcribe` are separate server audio helpers, with `openaiSpeech` / `openaiTranscription` factories from `@yourgpt/llm-sdk/openai`. They support cancellation, validated encoded audio, and response metadata. Copilot's `VoiceRecorder` and `transcribeRecording` provide recorded microphone input and a reviewable transcript.
336
+
337
+ See [image and audio contracts, examples, and limitations](./docs/multimodal-and-audio.md). Realtime voice calls and image generation are separate follow-ups.
338
+
339
+ ### Beta compatibility fixes
340
+
341
+ OpenAI-compatible Chat transports preserve raw structured tool-message content
342
+ instead of coercing arrays or objects to `[object Object]`. The SDK's explicit
343
+ `modelOutput` representation still uses provider-specific conversion. This does
344
+ not make every provider accept arbitrary object content; the provider validates
345
+ its own schema. Use its supported content-part format for live calls.
346
+
347
+ Malformed Responses function calls are rejected before tool execution with
348
+ `status: 502`, `code: "INVALID_PROVIDER_RESPONSE"`. The fallback chain can retry or
349
+ fall back according to its configured policy before any content has been emitted.
350
+ It does not switch models after streaming content or tool execution has started.
351
+ `generateText` also accepts model results that omit the optional `toolCalls` field.
@@ -1,13 +1,13 @@
1
- import { L as LLMAdapter, C as ChatCompletionRequest, a as CompletionResult } from '../base-CkeT7u-O.mjs';
2
- export { A as AdapterFactory, l as AnthropicContentBlock, O as OpenAIContentBlock, j as attachmentToAnthropicDocument, i as attachmentToAnthropicImage, k as attachmentToOpenAIImage, f as formatMessages, c as formatMessagesForAnthropic, d as formatMessagesForOpenAI, b as formatTools, h as hasImageAttachments, g as hasMediaAttachments, m as messageToAnthropicContent, e as messageToOpenAIContent } from '../base-CkeT7u-O.mjs';
3
- import { a7 as OpenAIParameterOptions, W as WebSearchConfig, g as StreamEvent } from '../types-BW3csYo5.mjs';
4
- import { d as OllamaModelOptions } from '../types-NOswlhm9.mjs';
1
+ import { L as LLMAdapter, C as ChatCompletionRequest, a as CompletionResult } from '../base-BICaQaRS.mjs';
2
+ export { A as AdapterFactory, l as AnthropicContentBlock, O as OpenAIContentBlock, j as attachmentToAnthropicDocument, i as attachmentToAnthropicImage, k as attachmentToOpenAIImage, f as formatMessages, c as formatMessagesForAnthropic, d as formatMessagesForOpenAI, b as formatTools, h as hasImageAttachments, g as hasMediaAttachments, m as messageToAnthropicContent, e as messageToOpenAIContent } from '../base-BICaQaRS.mjs';
3
+ import { ae as OpenAIParameterOptions, O as OpenAITransportOptions, W as WebSearchConfig, i as StreamEvent } from '../types-Dg1Bcg1k.mjs';
4
+ import { d as OllamaModelOptions } from '../types-DHQEMFHA.mjs';
5
5
  import 'zod';
6
6
 
7
7
  /**
8
8
  * OpenAI adapter configuration
9
9
  */
10
- interface OpenAIAdapterConfig extends OpenAIParameterOptions {
10
+ interface OpenAIAdapterConfig extends OpenAIParameterOptions, OpenAITransportOptions {
11
11
  organization?: string;
12
12
  headers?: Record<string, string>;
13
13
  apiKey: string;
@@ -1,13 +1,13 @@
1
- import { L as LLMAdapter, C as ChatCompletionRequest, a as CompletionResult } from '../base-BdTpUAWI.js';
2
- export { A as AdapterFactory, l as AnthropicContentBlock, O as OpenAIContentBlock, j as attachmentToAnthropicDocument, i as attachmentToAnthropicImage, k as attachmentToOpenAIImage, f as formatMessages, c as formatMessagesForAnthropic, d as formatMessagesForOpenAI, b as formatTools, h as hasImageAttachments, g as hasMediaAttachments, m as messageToAnthropicContent, e as messageToOpenAIContent } from '../base-BdTpUAWI.js';
3
- import { a7 as OpenAIParameterOptions, W as WebSearchConfig, g as StreamEvent } from '../types-BW3csYo5.js';
4
- import { d as OllamaModelOptions } from '../types-DA54bSmX.js';
1
+ import { L as LLMAdapter, C as ChatCompletionRequest, a as CompletionResult } from '../base-CpRPB8u8.js';
2
+ export { A as AdapterFactory, l as AnthropicContentBlock, O as OpenAIContentBlock, j as attachmentToAnthropicDocument, i as attachmentToAnthropicImage, k as attachmentToOpenAIImage, f as formatMessages, c as formatMessagesForAnthropic, d as formatMessagesForOpenAI, b as formatTools, h as hasImageAttachments, g as hasMediaAttachments, m as messageToAnthropicContent, e as messageToOpenAIContent } from '../base-CpRPB8u8.js';
3
+ import { ae as OpenAIParameterOptions, O as OpenAITransportOptions, W as WebSearchConfig, i as StreamEvent } from '../types-Dg1Bcg1k.js';
4
+ import { d as OllamaModelOptions } from '../types-Dikj3En4.js';
5
5
  import 'zod';
6
6
 
7
7
  /**
8
8
  * OpenAI adapter configuration
9
9
  */
10
- interface OpenAIAdapterConfig extends OpenAIParameterOptions {
10
+ interface OpenAIAdapterConfig extends OpenAIParameterOptions, OpenAITransportOptions {
11
11
  organization?: string;
12
12
  headers?: Record<string, string>;
13
13
  apiKey: string;