@neon/ai-sdk-provider 0.7.2 → 0.8.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.
- package/{LICENSE.md → LICENSE} +27 -3
- package/README.md +131 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/lib/neon-anthropic-language-model.d.ts +8 -0
- package/dist/lib/neon-anthropic-language-model.d.ts.map +1 -1
- package/dist/lib/neon-anthropic-language-model.js +39 -13
- package/dist/lib/neon-anthropic-language-model.js.map +1 -1
- package/dist/lib/neon-capabilities.d.ts.map +1 -1
- package/dist/lib/neon-capabilities.js +17 -11
- package/dist/lib/neon-capabilities.js.map +1 -1
- package/dist/lib/neon-chat-options.d.ts +4 -11
- package/dist/lib/neon-chat-options.d.ts.map +1 -1
- package/dist/lib/neon-chat-options.js +23 -28
- package/dist/lib/neon-chat-options.js.map +1 -1
- package/dist/lib/neon-gateway-error.d.ts +56 -0
- package/dist/lib/neon-gateway-error.d.ts.map +1 -0
- package/dist/lib/neon-gateway-error.js +102 -0
- package/dist/lib/neon-gateway-error.js.map +1 -0
- package/dist/lib/neon-model-capabilities.d.ts +7 -0
- package/dist/lib/neon-model-capabilities.d.ts.map +1 -1
- package/dist/lib/neon-model-capabilities.js +47 -10
- package/dist/lib/neon-model-capabilities.js.map +1 -1
- package/dist/lib/neon-responses-language-model.d.ts +5 -11
- package/dist/lib/neon-responses-language-model.d.ts.map +1 -1
- package/dist/lib/neon-responses-language-model.js +8 -29
- package/dist/lib/neon-responses-language-model.js.map +1 -1
- package/dist/lib/neon-responses-options.d.ts +14 -0
- package/dist/lib/neon-responses-options.d.ts.map +1 -0
- package/dist/lib/neon-responses-options.js +66 -0
- package/dist/lib/neon-responses-options.js.map +1 -0
- package/dist/lib/provider.d.ts.map +1 -1
- package/dist/lib/provider.js +5 -4
- package/dist/lib/provider.js.map +1 -1
- package/dist/package.js +1 -1
- package/package.json +1 -1
package/{LICENSE.md → LICENSE}
RENAMED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
# Apache License 2.0
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
Apache License
|
|
4
3
|
Version 2.0, January 2004
|
|
5
4
|
http://www.apache.org/licenses/
|
|
6
5
|
|
|
@@ -175,4 +174,29 @@
|
|
|
175
174
|
incurred by, or claims asserted against, such Contributor by reason
|
|
176
175
|
of your accepting any such warranty or additional liability.
|
|
177
176
|
|
|
178
|
-
END OF TERMS AND CONDITIONS
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Community [Vercel AI SDK](https://ai-sdk.dev) provider for the [Neon](https://neon.com) AI Gateway. Supports **AI SDK v6 and v7** (`ai@^6` or `ai@^7`).
|
|
4
4
|
|
|
5
|
-
The Neon AI Gateway is **branch-scoped**: each Neon project branch gets its own gateway host, and a platform token authorizes requests for that branch.
|
|
5
|
+
The Neon AI Gateway is **branch-scoped**: each Neon project branch gets its own gateway host, and a platform token authorizes requests for that branch. Use the same `neon(modelId)` API across the branch's model catalog; the provider selects Anthropic Messages, OpenAI Responses, or Chat Completions for each model.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Use canonical model ids such as `gpt-5-mini`, `llama-4-maverick`, and `gemini-3-flash`, matching the [`neon` provider on models.dev](https://models.dev). The typed catalog includes the known model ids, and arbitrary strings are accepted so newly available models work before the types update.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -31,7 +31,7 @@ import { generateText } from "ai";
|
|
|
31
31
|
|
|
32
32
|
// Reads NEON_AI_GATEWAY_BASE_URL + NEON_AI_GATEWAY_TOKEN from the environment.
|
|
33
33
|
const { text } = await generateText({
|
|
34
|
-
model: neon("
|
|
34
|
+
model: neon("gpt-5-mini"), // or "llama-4-maverick", "gemini-3-flash", …
|
|
35
35
|
prompt: "Summarize Postgres for me.",
|
|
36
36
|
});
|
|
37
37
|
```
|
|
@@ -51,17 +51,56 @@ const neon = createNeon({
|
|
|
51
51
|
|
|
52
52
|
| Model family | Endpoint | Why |
|
|
53
53
|
| --- | --- | --- |
|
|
54
|
-
| Anthropic (`claude-*`) |
|
|
55
|
-
| OpenAI (`gpt-*`, `*-codex`) |
|
|
56
|
-
| Everything else (Gemini, Llama, Qwen, gpt-oss, ...) |
|
|
54
|
+
| Anthropic (`claude-*`) | Messages API | Anthropic tools, structured output, and reasoning |
|
|
55
|
+
| OpenAI (`gpt-*`, `*-codex`) | Responses API | Codex, reasoning, and built-in tools such as image generation |
|
|
56
|
+
| Everything else (Gemini, Llama, Qwen, gpt-oss, ...) | Chat Completions API | one streaming interface across the remaining model families |
|
|
57
57
|
|
|
58
|
-
Routing matches on the model id
|
|
58
|
+
Routing matches on the model id.
|
|
59
59
|
|
|
60
60
|
## Capabilities
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
`generateText` and `streamText` work with any model available to your branch. `generateObject`, `streamObject`, and single- or multi-step tool calls work with OpenAI (including Codex), Meta, Alibaba, Zhipu AI, and Thinking Machines models. Gemini currently supports `generateText` and `streamText`; structured output and multi-step tools are not supported. Vision input works on models that accept images.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
Claude models use the Messages API. On both that route and Chat Completions the provider removes call options the gateway rejects and reports each one in `result.warnings` instead of failing the request — see [Dropped call options](#dropped-call-options). Unsupported Responses API storage options throw before a request is sent — see [Errors](#errors).
|
|
65
|
+
|
|
66
|
+
Which ids your branch serves is account-specific during the beta; `GET $NEON_AI_GATEWAY_BASE_URL/v1/models` is the authoritative list. `NeonChatModelId` accepts any string, so an id this package has not caught up with still works — and, equally, an id the gateway has retired still type-checks and fails at the gateway instead.
|
|
67
|
+
|
|
68
|
+
### Dropped call options
|
|
69
|
+
|
|
70
|
+
Upstream backends behind the gateway accept different subsets of the OpenAI-style parameters the AI SDK emits, and sending one an upstream rejects is a hard `400`. The provider drops those before the request and records a warning in `result.warnings`, so a call succeeds instead of failing on a parameter you passed in good faith.
|
|
71
|
+
|
|
72
|
+
These rules apply on the Anthropic Messages and Chat Completions routes. The Responses route (every `gpt-*` id) relies on the upstream OpenAI model's own stripping instead, so its behaviour is the AI SDK's rather than described here — but `getNeonModelCapabilities` still answers for those ids.
|
|
73
|
+
|
|
74
|
+
| Models | Dropped |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| Claude 4.7 and newer (`claude-opus-4-7`, `claude-opus-4-8`, `claude-opus-5`, `claude-sonnet-5`, `claude-fable-5`) | `temperature`, `topP` |
|
|
77
|
+
| All Claude | `frequencyPenalty`, `presencePenalty`, `seed`, `reasoningEffort`, and `topP` when you set both `temperature` and `topP` (Anthropic accepts only one) |
|
|
78
|
+
| `gpt-oss` | `frequencyPenalty`, `presencePenalty`, `seed`, `stopSequences` |
|
|
79
|
+
| Qwen, Gemma | `frequencyPenalty`, `presencePenalty`, `seed` |
|
|
80
|
+
| `glm-5-2`, `inkling` | `frequencyPenalty`, `presencePenalty` |
|
|
81
|
+
| Meta Llama | `frequencyPenalty`, `presencePenalty`, `seed` |
|
|
82
|
+
| Gemini | `reasoningEffort` |
|
|
83
|
+
|
|
84
|
+
**`temperature` on a Claude 5 model therefore has no effect.** That is the gateway's behaviour, not a provider choice; sending it returns `does not support the temperature parameter`. Steer those models with Anthropic's own effort control instead — note that this is `effort`, not the OpenAI-style `reasoningEffort`, which every Claude id drops:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
await generateText({
|
|
88
|
+
model: neon('claude-opus-5'),
|
|
89
|
+
prompt: 'Plan a schema migration.',
|
|
90
|
+
providerOptions: { anthropic: { effort: 'high' } }, // low | medium | high | xhigh | max
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Query the rules directly rather than hardcoding them:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { getNeonModelCapabilities } from '@neon/ai-sdk-provider';
|
|
98
|
+
|
|
99
|
+
getNeonModelCapabilities('claude-opus-5').supportsTemperature; // false
|
|
100
|
+
getNeonModelCapabilities('glm-5-2').supportsPenalties; // false
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Gemini is the only family on the unified endpoint that accepts penalties. A model none of these rules match is left untouched, so a brand-new id gets the gateway's own error rather than a guess.
|
|
65
104
|
|
|
66
105
|
## Image generation
|
|
67
106
|
|
|
@@ -85,11 +124,90 @@ for await (const part of result.fullStream) {
|
|
|
85
124
|
}
|
|
86
125
|
```
|
|
87
126
|
|
|
127
|
+
### Edit a generated image
|
|
128
|
+
|
|
129
|
+
The gateway does not support stored Responses API items (`store: true`, `previousResponseId`, or `conversation`), which the Responses API uses to reuse tool results across turns. For image edits, pass the returned bytes back as image input; otherwise the model does not receive the original image and generates a new one.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const first = await generateText({
|
|
133
|
+
model: neon("gpt-5-mini"),
|
|
134
|
+
prompt: "Generate an image of a plain red square.",
|
|
135
|
+
tools: { image_generation: neon.tools.imageGeneration({ outputFormat: "jpeg" }) },
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const generated = first.steps
|
|
139
|
+
.flatMap((step) => step.toolResults)
|
|
140
|
+
.find((result) => result.toolName === "image_generation");
|
|
141
|
+
const output = generated?.output;
|
|
142
|
+
if (
|
|
143
|
+
!output ||
|
|
144
|
+
typeof output !== "object" ||
|
|
145
|
+
!("result" in output) ||
|
|
146
|
+
typeof output.result !== "string"
|
|
147
|
+
) {
|
|
148
|
+
throw new Error("Image generation did not return image bytes.");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Pass it back as image content, not as conversation history.
|
|
152
|
+
await generateText({
|
|
153
|
+
model: neon("gpt-5-mini"),
|
|
154
|
+
tools: { image_generation: neon.tools.imageGeneration({ outputFormat: "jpeg" }) },
|
|
155
|
+
messages: [
|
|
156
|
+
{
|
|
157
|
+
role: "user",
|
|
158
|
+
content: [
|
|
159
|
+
{ type: "image", image: output.result, mediaType: "image/jpeg" },
|
|
160
|
+
{ type: "text", text: "Make that same square blue instead." },
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The same stateless limitation applies to other built-in Responses tools such as web search and code interpreter.
|
|
168
|
+
|
|
169
|
+
## Errors
|
|
170
|
+
|
|
171
|
+
A failed call rejects with the AI SDK's `APICallError`, and `error.message` carries the gateway's own reason rather than the bare HTTP status line:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { APICallError, generateText } from "ai";
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
await generateText({ model: neon("gpt-5-mini"), maxOutputTokens: 1, prompt });
|
|
178
|
+
} catch (error) {
|
|
179
|
+
if (APICallError.isInstance(error)) {
|
|
180
|
+
error.message; // "Invalid 'max_output_tokens': integer below minimum
|
|
181
|
+
// value. Expected a value >= 16, but got 1 instead."
|
|
182
|
+
error.responseBody; // the gateway's original body, including its error_code
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The provider normalizes JSON error responses so the gateway's reason lands on `error.message`. Errors delivered inside an open stream and non-JSON responses keep the HTTP status line; inspect `error.responseBody` for their payload.
|
|
188
|
+
|
|
189
|
+
Requests that cannot work are refused before they leave, with `UnsupportedFunctionalityError`:
|
|
190
|
+
|
|
191
|
+
| `providerOptions.openai` | Why |
|
|
192
|
+
| --- | --- |
|
|
193
|
+
| `store: true` or `store: null` | The Responses route is stateless and never persists items. `null` is not "omitted" — the AI SDK reads it as `true`. |
|
|
194
|
+
| `previousResponseId`, `conversation` | Nothing is stored for them to refer to. Send the full message history instead. |
|
|
195
|
+
|
|
196
|
+
Provider options are namespaced per route, which decides where the SDK reads them from:
|
|
197
|
+
|
|
198
|
+
| Route | Models | Namespace |
|
|
199
|
+
| --- | --- | --- |
|
|
200
|
+
| Responses | `gpt-*` (incl. Codex) | `openai` |
|
|
201
|
+
| Chat Completions | Gemini, Llama, Qwen, gpt-oss, … | `neon` |
|
|
202
|
+
| Anthropic Messages | `claude-*` | `anthropic` |
|
|
203
|
+
|
|
204
|
+
So `store` is only refused on the Responses route; the same option is ignored elsewhere.
|
|
205
|
+
|
|
88
206
|
## Limitations
|
|
89
207
|
|
|
90
|
-
- `generateImage()` and
|
|
91
|
-
-
|
|
92
|
-
-
|
|
208
|
+
- The gateway does not offer image or embedding model endpoints, so `generateImage()`, `embed()`, and `embedMany()` throw `NoSuchModelError`. Image generation is available through the Responses API's built-in `image_generation` tool with `neon.tools.imageGeneration()`.
|
|
209
|
+
- Results from provider-executed tools (`neon.tools.imageGeneration`, and the other Responses built-ins) are not replayed to the gateway on a later step — see [Edit a generated image](#edit-a-generated-image).
|
|
210
|
+
- The Responses route is stateless, so the provider sends `store: false` and refuses `store: true`, `store: null`, `previousResponseId`, or `conversation` — see [Errors](#errors).
|
|
93
211
|
|
|
94
212
|
## End-to-end tests
|
|
95
213
|
|
|
@@ -100,4 +218,4 @@ cp .env.example .env # fill NEON_AI_GATEWAY_BASE_URL + NEON_AI_GATEWAY_TOKEN f
|
|
|
100
218
|
pnpm test:e2e
|
|
101
219
|
```
|
|
102
220
|
|
|
103
|
-
The matrix covers one models.dev `neon` model per family (Anthropic, OpenAI, Codex, Gemini, Meta) across `generateText`, `streamText`, `generateObject`, tool calling, and `neon.tools.imageGeneration`. It also fetches the live `/v1/models` catalog and calls every currently enabled model with both AI SDK 6 and AI SDK 7. Tests are skipped when gateway env vars are absent.
|
|
221
|
+
The matrix covers one models.dev `neon` model per family (Anthropic, OpenAI, Codex, Gemini, Meta, Alibaba, Zhipu, Thinking Machines) across `generateText`, `streamText`, `generateObject`, tool calling, and `neon.tools.imageGeneration`. `generateObject` and tool calling run on the subset of families where they are verified (see [Capabilities](#capabilities)); a family whose representative id the branch does not serve is skipped rather than failed. It also fetches the live `/v1/models` catalog and calls every currently enabled model with both AI SDK 6 and AI SDK 7. Tests are skipped when gateway env vars are absent.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NeonAnthropicLanguageModel } from "./lib/neon-anthropic-language-model.js";
|
|
2
2
|
import { NeonChatLanguageModel } from "./lib/neon-chat-language-model.js";
|
|
3
|
-
import {
|
|
3
|
+
import { NEON_MODELS_DEV_IDS, NeonChatModelId, NeonKnownModelId } from "./lib/neon-chat-options.js";
|
|
4
4
|
import { NeonModelCapabilities, NeonModelFamily, NeonModelRoute, getNeonModelCapabilities, getNeonModelRoute } from "./lib/neon-model-capabilities.js";
|
|
5
5
|
import { NeonResponsesLanguageModel } from "./lib/neon-responses-language-model.js";
|
|
6
6
|
import { NeonErrorData, NeonProvider, NeonProviderSettings, createNeon, neon } from "./lib/provider.js";
|
|
7
|
-
export {
|
|
7
|
+
export { NEON_MODELS_DEV_IDS, NeonAnthropicLanguageModel, NeonChatLanguageModel, type NeonChatModelId, type NeonErrorData, type NeonKnownModelId, type NeonModelCapabilities, type NeonModelFamily, type NeonModelRoute, type NeonProvider, type NeonProviderSettings, NeonResponsesLanguageModel, createNeon, getNeonModelCapabilities, getNeonModelRoute, neon };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { NeonAnthropicLanguageModel } from "./lib/neon-anthropic-language-model.js";
|
|
2
1
|
import { getNeonModelCapabilities, getNeonModelRoute } from "./lib/neon-model-capabilities.js";
|
|
2
|
+
import { NeonAnthropicLanguageModel } from "./lib/neon-anthropic-language-model.js";
|
|
3
3
|
import { NeonChatLanguageModel } from "./lib/neon-chat-language-model.js";
|
|
4
|
-
import {
|
|
4
|
+
import { NEON_MODELS_DEV_IDS } from "./lib/neon-chat-options.js";
|
|
5
5
|
import { NeonResponsesLanguageModel } from "./lib/neon-responses-language-model.js";
|
|
6
6
|
import { createNeon, neon } from "./lib/provider.js";
|
|
7
|
-
export {
|
|
7
|
+
export { NEON_MODELS_DEV_IDS, NeonAnthropicLanguageModel, NeonChatLanguageModel, NeonResponsesLanguageModel, createNeon, getNeonModelCapabilities, getNeonModelRoute, neon };
|
|
@@ -12,6 +12,14 @@ import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateRes
|
|
|
12
12
|
* (`eager_input_streaming: true`) on streaming tool calls, which the gateway
|
|
13
13
|
* rejects (`Extra inputs are not permitted`). We disable it via the model's own
|
|
14
14
|
* `toolStreaming` option so streaming tool calls work. Users can still override.
|
|
15
|
+
*
|
|
16
|
+
* Capability filtering runs here as well as on the unified endpoint. The
|
|
17
|
+
* upstream Anthropic model drops sampling parameters for the Claude versions it
|
|
18
|
+
* knows about, but not for ones released after it, so `claude-opus-5` and
|
|
19
|
+
* `claude-sonnet-5` reached the API and came back
|
|
20
|
+
* `` `temperature` is deprecated for this model ``. Applying our own rules keeps
|
|
21
|
+
* the behaviour tied to what the gateway was measured to accept rather than to
|
|
22
|
+
* the SDK's release date.
|
|
15
23
|
*/
|
|
16
24
|
declare class NeonAnthropicLanguageModel extends AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
17
25
|
private withGatewayCompat;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-anthropic-language-model.d.ts","names":[],"sources":["../../src/lib/neon-anthropic-language-model.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"neon-anthropic-language-model.d.ts","names":[],"sources":["../../src/lib/neon-anthropic-language-model.ts"],"mappings":";;;;;;;AA+BA;AACC;AA6BU;AACC;AAAR;AASO;AACC;AAAR;AAxCK;AACG;AAAe;;;;;;cAFd,0BAAA,SACJ,8BAAA,YACG;;sBA4BD,6BACP,QAAQ;oBASD,6BACP,QAAQ"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applyNeonCapabilities, mergeStreamStartWarnings } from "./neon-capabilities.js";
|
|
1
2
|
import { AnthropicMessagesLanguageModel } from "@ai-sdk/anthropic/internal";
|
|
2
3
|
//#region src/lib/neon-anthropic-language-model.ts
|
|
3
4
|
/**
|
|
@@ -9,27 +10,52 @@ import { AnthropicMessagesLanguageModel } from "@ai-sdk/anthropic/internal";
|
|
|
9
10
|
* (`eager_input_streaming: true`) on streaming tool calls, which the gateway
|
|
10
11
|
* rejects (`Extra inputs are not permitted`). We disable it via the model's own
|
|
11
12
|
* `toolStreaming` option so streaming tool calls work. Users can still override.
|
|
13
|
+
*
|
|
14
|
+
* Capability filtering runs here as well as on the unified endpoint. The
|
|
15
|
+
* upstream Anthropic model drops sampling parameters for the Claude versions it
|
|
16
|
+
* knows about, but not for ones released after it, so `claude-opus-5` and
|
|
17
|
+
* `claude-sonnet-5` reached the API and came back
|
|
18
|
+
* `` `temperature` is deprecated for this model ``. Applying our own rules keeps
|
|
19
|
+
* the behaviour tied to what the gateway was measured to accept rather than to
|
|
20
|
+
* the SDK's release date.
|
|
12
21
|
*/
|
|
13
22
|
var NeonAnthropicLanguageModel = class extends AnthropicMessagesLanguageModel {
|
|
14
23
|
withGatewayCompat(options) {
|
|
15
|
-
const
|
|
16
|
-
|
|
24
|
+
const { options: adjusted, warnings } = applyNeonCapabilities(this.modelId, options);
|
|
25
|
+
const anthropic = adjusted.providerOptions?.anthropic;
|
|
26
|
+
if (anthropic != null && "toolStreaming" in anthropic) return {
|
|
27
|
+
options: adjusted,
|
|
28
|
+
warnings
|
|
29
|
+
};
|
|
17
30
|
return {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
options: {
|
|
32
|
+
...adjusted,
|
|
33
|
+
providerOptions: {
|
|
34
|
+
...adjusted.providerOptions,
|
|
35
|
+
anthropic: {
|
|
36
|
+
...anthropic,
|
|
37
|
+
toolStreaming: false
|
|
38
|
+
}
|
|
24
39
|
}
|
|
25
|
-
}
|
|
40
|
+
},
|
|
41
|
+
warnings
|
|
26
42
|
};
|
|
27
43
|
}
|
|
28
|
-
doGenerate(options) {
|
|
29
|
-
|
|
44
|
+
async doGenerate(options) {
|
|
45
|
+
const { options: adjusted, warnings } = this.withGatewayCompat(options);
|
|
46
|
+
const result = await super.doGenerate(adjusted);
|
|
47
|
+
return warnings.length > 0 ? {
|
|
48
|
+
...result,
|
|
49
|
+
warnings: [...warnings, ...result.warnings]
|
|
50
|
+
} : result;
|
|
30
51
|
}
|
|
31
|
-
doStream(options) {
|
|
32
|
-
|
|
52
|
+
async doStream(options) {
|
|
53
|
+
const { options: adjusted, warnings } = this.withGatewayCompat(options);
|
|
54
|
+
const result = await super.doStream(adjusted);
|
|
55
|
+
return warnings.length > 0 ? {
|
|
56
|
+
...result,
|
|
57
|
+
stream: result.stream.pipeThrough(mergeStreamStartWarnings(warnings))
|
|
58
|
+
} : result;
|
|
33
59
|
}
|
|
34
60
|
};
|
|
35
61
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-anthropic-language-model.js","names":[],"sources":["../../src/lib/neon-anthropic-language-model.ts"],"sourcesContent":["import { AnthropicMessagesLanguageModel } from \"@ai-sdk/anthropic/internal\";\nimport type {\n\tLanguageModelV3,\n\tLanguageModelV3CallOptions,\n\tLanguageModelV3GenerateResult,\n\tLanguageModelV3StreamResult,\n} from \"@ai-sdk/provider\";\n\n/**\n * Language model for Anthropic models served via the Neon AI Gateway's native\n * Messages API (`/anthropic/v1/messages`). Unlocks streaming\n * structured output and native reasoning for Claude.\n *\n * The shared Anthropic model defaults to fine-grained tool-input streaming\n * (`eager_input_streaming: true`) on streaming tool calls, which the gateway\n * rejects (`Extra inputs are not permitted`). We disable it via the model's own\n * `toolStreaming` option so streaming tool calls work. Users can still override.\n */\nexport class NeonAnthropicLanguageModel\n\textends AnthropicMessagesLanguageModel\n\timplements LanguageModelV3\n{\n\tprivate withGatewayCompat(\n\t\toptions: LanguageModelV3CallOptions
|
|
1
|
+
{"version":3,"file":"neon-anthropic-language-model.js","names":[],"sources":["../../src/lib/neon-anthropic-language-model.ts"],"sourcesContent":["import { AnthropicMessagesLanguageModel } from \"@ai-sdk/anthropic/internal\";\nimport type {\n\tLanguageModelV3,\n\tLanguageModelV3CallOptions,\n\tLanguageModelV3GenerateResult,\n\tLanguageModelV3StreamResult,\n\tSharedV3Warning,\n} from \"@ai-sdk/provider\";\nimport {\n\tapplyNeonCapabilities,\n\tmergeStreamStartWarnings,\n} from \"./neon-capabilities.js\";\n\n/**\n * Language model for Anthropic models served via the Neon AI Gateway's native\n * Messages API (`/anthropic/v1/messages`). Unlocks streaming\n * structured output and native reasoning for Claude.\n *\n * The shared Anthropic model defaults to fine-grained tool-input streaming\n * (`eager_input_streaming: true`) on streaming tool calls, which the gateway\n * rejects (`Extra inputs are not permitted`). We disable it via the model's own\n * `toolStreaming` option so streaming tool calls work. Users can still override.\n *\n * Capability filtering runs here as well as on the unified endpoint. The\n * upstream Anthropic model drops sampling parameters for the Claude versions it\n * knows about, but not for ones released after it, so `claude-opus-5` and\n * `claude-sonnet-5` reached the API and came back\n * `` `temperature` is deprecated for this model ``. Applying our own rules keeps\n * the behaviour tied to what the gateway was measured to accept rather than to\n * the SDK's release date.\n */\nexport class NeonAnthropicLanguageModel\n\textends AnthropicMessagesLanguageModel\n\timplements LanguageModelV3\n{\n\tprivate withGatewayCompat(options: LanguageModelV3CallOptions): {\n\t\toptions: LanguageModelV3CallOptions;\n\t\twarnings: SharedV3Warning[];\n\t} {\n\t\tconst { options: adjusted, warnings } = applyNeonCapabilities(\n\t\t\tthis.modelId,\n\t\t\toptions,\n\t\t);\n\t\tconst anthropic = adjusted.providerOptions?.anthropic;\n\t\t// Respect an explicit user setting.\n\t\tif (anthropic != null && \"toolStreaming\" in anthropic) {\n\t\t\treturn { options: adjusted, warnings };\n\t\t}\n\t\treturn {\n\t\t\toptions: {\n\t\t\t\t...adjusted,\n\t\t\t\tproviderOptions: {\n\t\t\t\t\t...adjusted.providerOptions,\n\t\t\t\t\tanthropic: { ...anthropic, toolStreaming: false },\n\t\t\t\t},\n\t\t\t},\n\t\t\twarnings,\n\t\t};\n\t}\n\n\toverride async doGenerate(\n\t\toptions: LanguageModelV3CallOptions,\n\t): Promise<LanguageModelV3GenerateResult> {\n\t\tconst { options: adjusted, warnings } = this.withGatewayCompat(options);\n\t\tconst result = await super.doGenerate(adjusted);\n\t\treturn warnings.length > 0\n\t\t\t? { ...result, warnings: [...warnings, ...result.warnings] }\n\t\t\t: result;\n\t}\n\n\toverride async doStream(\n\t\toptions: LanguageModelV3CallOptions,\n\t): Promise<LanguageModelV3StreamResult> {\n\t\tconst { options: adjusted, warnings } = this.withGatewayCompat(options);\n\t\tconst result = await super.doStream(adjusted);\n\t\treturn warnings.length > 0\n\t\t\t? {\n\t\t\t\t\t...result,\n\t\t\t\t\tstream: result.stream.pipeThrough(\n\t\t\t\t\t\tmergeStreamStartWarnings(warnings),\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t: result;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA+BA,IAAa,6BAAb,cACS,+BAET;CACC,kBAA0B,SAGxB;EACD,MAAM,EAAE,SAAS,UAAU,aAAa,sBACvC,KAAK,SACL,OACD;EACA,MAAM,YAAY,SAAS,iBAAiB;EAE5C,IAAI,aAAa,QAAQ,mBAAmB,WAC3C,OAAO;GAAE,SAAS;GAAU;EAAS;EAEtC,OAAO;GACN,SAAS;IACR,GAAG;IACH,iBAAiB;KAChB,GAAG,SAAS;KACZ,WAAW;MAAE,GAAG;MAAW,eAAe;KAAM;IACjD;GACD;GACA;EACD;CACD;CAEA,MAAe,WACd,SACyC;EACzC,MAAM,EAAE,SAAS,UAAU,aAAa,KAAK,kBAAkB,OAAO;EACtE,MAAM,SAAS,MAAM,MAAM,WAAW,QAAQ;EAC9C,OAAO,SAAS,SAAS,IACtB;GAAE,GAAG;GAAQ,UAAU,CAAC,GAAG,UAAU,GAAG,OAAO,QAAQ;EAAE,IACzD;CACJ;CAEA,MAAe,SACd,SACuC;EACvC,MAAM,EAAE,SAAS,UAAU,aAAa,KAAK,kBAAkB,OAAO;EACtE,MAAM,SAAS,MAAM,MAAM,SAAS,QAAQ;EAC5C,OAAO,SAAS,SAAS,IACtB;GACA,GAAG;GACH,QAAQ,OAAO,OAAO,YACrB,yBAAyB,QAAQ,CAClC;EACD,IACC;CACJ;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-capabilities.d.ts","names":[],"sources":["../../src/lib/neon-capabilities.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"neon-capabilities.d.ts","names":[],"sources":["../../src/lib/neon-capabilities.ts"],"mappings":";;;;;;AAoBA;AAAqC;AAE3B;AACI,iBAHE,qBAAA,CAGF,OAAA,EAAA,MAAA,EAAA,OAAA,EADJ,0BACI,CAAA,EAAA;EAAsC,OAAA,EAAtC,0BAAsC;EAAe,QAAA,EAAf,eAAe,EAAA;AA8GnE,CAAA;AAAwC;AAAQ;AAAiB;AAAA,iBAAjD,wBAAA,CAAiD,KAAA,EAAjB,eAAiB,EAAA,CAAA,EAAA,eAAA,CAAA,yBAAA,EAAA,yBAAA,CAAA"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { getNeonModelCapabilities } from "./neon-model-capabilities.js";
|
|
2
2
|
//#region src/lib/neon-capabilities.ts
|
|
3
|
+
const PENALTY_DETAILS = "Only Gemini accepts penalties on the gateway's unified endpoint, so it was dropped rather than sent.";
|
|
4
|
+
const GENERIC_DETAILS = "The Neon AI Gateway rejects this parameter for this model, so it was dropped rather than sent.";
|
|
5
|
+
const REASONING_EFFORT_DETAILS = "This model does not take the OpenAI reasoning_effort field, so it was dropped rather than sent.";
|
|
3
6
|
/**
|
|
4
7
|
* Drop call options the resolved model's upstream backend does not accept and
|
|
5
8
|
* collect a warning for each, so callers get a clear signal instead of a hard
|
|
@@ -9,20 +12,23 @@ function applyNeonCapabilities(modelId, options) {
|
|
|
9
12
|
const caps = getNeonModelCapabilities(modelId);
|
|
10
13
|
const warnings = [];
|
|
11
14
|
const patch = {};
|
|
12
|
-
const
|
|
15
|
+
const drop = (feature, details, type = "unsupported") => {
|
|
13
16
|
warnings.push({
|
|
14
|
-
type
|
|
17
|
+
type,
|
|
15
18
|
feature,
|
|
16
|
-
details
|
|
19
|
+
details
|
|
17
20
|
});
|
|
18
21
|
};
|
|
22
|
+
const unrecognizedClaude = caps.claudeSamplingUnrecognized === true;
|
|
23
|
+
const samplingDetails = unrecognizedClaude ? "This Claude version was not recognised. Claude 4.7 and newer reject sampling parameters, so it was dropped as a precaution; set `providerOptions.anthropic.effort` instead." : caps.family === "anthropic" ? "Claude 4.7 and newer reject sampling parameters, so it was dropped rather than sent. Use `providerOptions.anthropic.effort` (low | medium | high | xhigh | max) to steer these models." : "The Neon AI Gateway rejects this parameter for this model, so it was dropped rather than sent.";
|
|
24
|
+
const samplingType = unrecognizedClaude ? "compatibility" : "unsupported";
|
|
19
25
|
if (options.temperature != null && !caps.supportsTemperature) {
|
|
20
26
|
patch.temperature = void 0;
|
|
21
|
-
|
|
27
|
+
drop("temperature", samplingDetails, samplingType);
|
|
22
28
|
}
|
|
23
29
|
if (options.topP != null && !caps.supportsTopP) {
|
|
24
30
|
patch.topP = void 0;
|
|
25
|
-
|
|
31
|
+
drop("topP", samplingDetails, samplingType);
|
|
26
32
|
}
|
|
27
33
|
const effectiveTemperature = "temperature" in patch ? patch.temperature : options.temperature;
|
|
28
34
|
const effectiveTopP = "topP" in patch ? patch.topP : options.topP;
|
|
@@ -31,29 +37,29 @@ function applyNeonCapabilities(modelId, options) {
|
|
|
31
37
|
warnings.push({
|
|
32
38
|
type: "compatibility",
|
|
33
39
|
feature: "topP",
|
|
34
|
-
details:
|
|
40
|
+
details: "Anthropic models accept only one of temperature or topP; topP was dropped and temperature kept."
|
|
35
41
|
});
|
|
36
42
|
}
|
|
37
43
|
if (options.frequencyPenalty != null && !caps.supportsPenalties) {
|
|
38
44
|
patch.frequencyPenalty = void 0;
|
|
39
|
-
|
|
45
|
+
drop("frequencyPenalty", PENALTY_DETAILS);
|
|
40
46
|
}
|
|
41
47
|
if (options.presencePenalty != null && !caps.supportsPenalties) {
|
|
42
48
|
patch.presencePenalty = void 0;
|
|
43
|
-
|
|
49
|
+
drop("presencePenalty", PENALTY_DETAILS);
|
|
44
50
|
}
|
|
45
51
|
if (options.seed != null && !caps.supportsSeed) {
|
|
46
52
|
patch.seed = void 0;
|
|
47
|
-
|
|
53
|
+
drop("seed", GENERIC_DETAILS);
|
|
48
54
|
}
|
|
49
55
|
if (options.stopSequences != null && !caps.supportsStopSequences) {
|
|
50
56
|
patch.stopSequences = void 0;
|
|
51
|
-
|
|
57
|
+
drop("stopSequences", GENERIC_DETAILS);
|
|
52
58
|
}
|
|
53
59
|
if (!caps.supportsReasoningEffort) {
|
|
54
60
|
const { providerOptions } = options;
|
|
55
61
|
if (providerOptions != null && Object.values(providerOptions).some((group) => "reasoningEffort" in group && group.reasoningEffort != null)) {
|
|
56
|
-
|
|
62
|
+
drop("reasoningEffort", REASONING_EFFORT_DETAILS);
|
|
57
63
|
if (providerOptions != null) {
|
|
58
64
|
const cleaned = {};
|
|
59
65
|
for (const [key, group] of Object.entries(providerOptions)) if ("reasoningEffort" in group) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-capabilities.js","names":[],"sources":["../../src/lib/neon-capabilities.ts"],"sourcesContent":["import type {\n\tLanguageModelV3CallOptions,\n\tLanguageModelV3StreamPart,\n\tSharedV3ProviderOptions,\n\tSharedV3Warning,\n} from \"@ai-sdk/provider\";\nimport { getNeonModelCapabilities } from \"./neon-model-capabilities.js\";\n\n/**\n * Drop call options the resolved model's upstream backend does not accept and\n * collect a warning for each, so callers get a clear signal instead of a hard\n * `400` from the gateway.\n */\nexport function applyNeonCapabilities(\n\tmodelId: string,\n\toptions: LanguageModelV3CallOptions,\n): { options: LanguageModelV3CallOptions; warnings: SharedV3Warning[] } {\n\tconst caps = getNeonModelCapabilities(modelId);\n\tconst warnings: SharedV3Warning[] = [];\n\tconst patch: Partial<LanguageModelV3CallOptions> = {};\n\n\tconst
|
|
1
|
+
{"version":3,"file":"neon-capabilities.js","names":[],"sources":["../../src/lib/neon-capabilities.ts"],"sourcesContent":["import type {\n\tLanguageModelV3CallOptions,\n\tLanguageModelV3StreamPart,\n\tSharedV3ProviderOptions,\n\tSharedV3Warning,\n} from \"@ai-sdk/provider\";\nimport { getNeonModelCapabilities } from \"./neon-model-capabilities.js\";\n\nconst PENALTY_DETAILS =\n\t\"Only Gemini accepts penalties on the gateway's unified endpoint, so it was dropped rather than sent.\";\nconst GENERIC_DETAILS =\n\t\"The Neon AI Gateway rejects this parameter for this model, so it was dropped rather than sent.\";\nconst REASONING_EFFORT_DETAILS =\n\t\"This model does not take the OpenAI reasoning_effort field, so it was dropped rather than sent.\";\n\n/**\n * Drop call options the resolved model's upstream backend does not accept and\n * collect a warning for each, so callers get a clear signal instead of a hard\n * `400` from the gateway.\n */\nexport function applyNeonCapabilities(\n\tmodelId: string,\n\toptions: LanguageModelV3CallOptions,\n): { options: LanguageModelV3CallOptions; warnings: SharedV3Warning[] } {\n\tconst caps = getNeonModelCapabilities(modelId);\n\tconst warnings: SharedV3Warning[] = [];\n\tconst patch: Partial<LanguageModelV3CallOptions> = {};\n\n\t// The AI SDK prints the provider, the model id and the feature name ahead of\n\t// `details`, so each reason says only what those cannot: why the gateway\n\t// refuses it, and what to use instead. Each carries its own \"was dropped\"\n\t// clause rather than a shared suffix — appending one everywhere restated the\n\t// penalty reason and asserted a 400 for the unrecognised case, which is the\n\t// overstatement this wording exists to avoid.\n\tconst drop = (\n\t\tfeature: string,\n\t\tdetails: string,\n\t\ttype: \"unsupported\" | \"compatibility\" = \"unsupported\",\n\t) => {\n\t\twarnings.push({ type, feature, details });\n\t};\n\n\t// Precautionary rather than measured, so it is flagged as a compatibility\n\t// choice: the SDK renders `unsupported` as a flat \"is not supported\", which\n\t// would contradict the hedge in the sentence that follows it.\n\tconst unrecognizedClaude = caps.claudeSamplingUnrecognized === true;\n\tconst samplingDetails = unrecognizedClaude\n\t\t? \"This Claude version was not recognised. Claude 4.7 and newer reject sampling parameters, so it was dropped as a precaution; set `providerOptions.anthropic.effort` instead.\"\n\t\t: caps.family === \"anthropic\"\n\t\t\t? \"Claude 4.7 and newer reject sampling parameters, so it was dropped rather than sent. Use `providerOptions.anthropic.effort` (low | medium | high | xhigh | max) to steer these models.\"\n\t\t\t: \"The Neon AI Gateway rejects this parameter for this model, so it was dropped rather than sent.\";\n\tconst samplingType = unrecognizedClaude ? \"compatibility\" : \"unsupported\";\n\n\tif (options.temperature != null && !caps.supportsTemperature) {\n\t\tpatch.temperature = undefined;\n\t\tdrop(\"temperature\", samplingDetails, samplingType);\n\t}\n\tif (options.topP != null && !caps.supportsTopP) {\n\t\tpatch.topP = undefined;\n\t\tdrop(\"topP\", samplingDetails, samplingType);\n\t}\n\n\t// Anthropic-style models accept only one of temperature / topP.\n\tconst effectiveTemperature =\n\t\t\"temperature\" in patch ? patch.temperature : options.temperature;\n\tconst effectiveTopP = \"topP\" in patch ? patch.topP : options.topP;\n\tif (\n\t\tcaps.temperatureTopPMutuallyExclusive &&\n\t\teffectiveTemperature != null &&\n\t\teffectiveTopP != null\n\t) {\n\t\tpatch.topP = undefined;\n\t\twarnings.push({\n\t\t\ttype: \"compatibility\",\n\t\t\tfeature: \"topP\",\n\t\t\tdetails:\n\t\t\t\t\"Anthropic models accept only one of temperature or topP; topP was dropped and temperature kept.\",\n\t\t});\n\t}\n\n\tif (options.frequencyPenalty != null && !caps.supportsPenalties) {\n\t\tpatch.frequencyPenalty = undefined;\n\t\tdrop(\"frequencyPenalty\", PENALTY_DETAILS);\n\t}\n\tif (options.presencePenalty != null && !caps.supportsPenalties) {\n\t\tpatch.presencePenalty = undefined;\n\t\tdrop(\"presencePenalty\", PENALTY_DETAILS);\n\t}\n\tif (options.seed != null && !caps.supportsSeed) {\n\t\tpatch.seed = undefined;\n\t\tdrop(\"seed\", GENERIC_DETAILS);\n\t}\n\n\tif (options.stopSequences != null && !caps.supportsStopSequences) {\n\t\tpatch.stopSequences = undefined;\n\t\tdrop(\"stopSequences\", GENERIC_DETAILS);\n\t}\n\n\tif (!caps.supportsReasoningEffort) {\n\t\tconst { providerOptions } = options;\n\t\tconst hasProviderEffort =\n\t\t\tproviderOptions != null &&\n\t\t\tObject.values(providerOptions).some(\n\t\t\t\t(group) =>\n\t\t\t\t\t\"reasoningEffort\" in group && group.reasoningEffort != null,\n\t\t\t);\n\n\t\tif (hasProviderEffort) {\n\t\t\tdrop(\"reasoningEffort\", REASONING_EFFORT_DETAILS);\n\t\t\tif (providerOptions != null) {\n\t\t\t\tconst cleaned: SharedV3ProviderOptions = {};\n\t\t\t\tfor (const [key, group] of Object.entries(providerOptions)) {\n\t\t\t\t\tif (\"reasoningEffort\" in group) {\n\t\t\t\t\t\tconst { reasoningEffort: _removed, ...rest } = group;\n\t\t\t\t\t\tcleaned[key] = rest;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcleaned[key] = group;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpatch.providerOptions = cleaned;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (Object.keys(patch).length === 0) {\n\t\treturn { options, warnings };\n\t}\n\treturn { options: { ...options, ...patch }, warnings };\n}\n\n/**\n * Merge additional warnings into the `stream-start` part of a model stream.\n */\nexport function mergeStreamStartWarnings(extra: SharedV3Warning[]) {\n\tlet merged = false;\n\treturn new TransformStream<\n\t\tLanguageModelV3StreamPart,\n\t\tLanguageModelV3StreamPart\n\t>({\n\t\ttransform(part, controller) {\n\t\t\tif (!merged && part.type === \"stream-start\") {\n\t\t\t\tmerged = true;\n\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t...part,\n\t\t\t\t\twarnings: [...extra, ...part.warnings],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tcontroller.enqueue(part);\n\t\t\t}\n\t\t},\n\t});\n}\n"],"mappings":";;AAQA,MAAM,kBACL;AACD,MAAM,kBACL;AACD,MAAM,2BACL;;;;;;AAOD,SAAgB,sBACf,SACA,SACuE;CACvE,MAAM,OAAO,yBAAyB,OAAO;CAC7C,MAAM,WAA8B,CAAC;CACrC,MAAM,QAA6C,CAAC;CAQpD,MAAM,QACL,SACA,SACA,OAAwC,kBACpC;EACJ,SAAS,KAAK;GAAE;GAAM;GAAS;EAAQ,CAAC;CACzC;CAKA,MAAM,qBAAqB,KAAK,+BAA+B;CAC/D,MAAM,kBAAkB,qBACrB,gLACA,KAAK,WAAW,cACf,2LACA;CACJ,MAAM,eAAe,qBAAqB,kBAAkB;CAE5D,IAAI,QAAQ,eAAe,QAAQ,CAAC,KAAK,qBAAqB;EAC7D,MAAM,cAAc,KAAA;EACpB,KAAK,eAAe,iBAAiB,YAAY;CAClD;CACA,IAAI,QAAQ,QAAQ,QAAQ,CAAC,KAAK,cAAc;EAC/C,MAAM,OAAO,KAAA;EACb,KAAK,QAAQ,iBAAiB,YAAY;CAC3C;CAGA,MAAM,uBACL,iBAAiB,QAAQ,MAAM,cAAc,QAAQ;CACtD,MAAM,gBAAgB,UAAU,QAAQ,MAAM,OAAO,QAAQ;CAC7D,IACC,KAAK,oCACL,wBAAwB,QACxB,iBAAiB,MAChB;EACD,MAAM,OAAO,KAAA;EACb,SAAS,KAAK;GACb,MAAM;GACN,SAAS;GACT,SACC;EACF,CAAC;CACF;CAEA,IAAI,QAAQ,oBAAoB,QAAQ,CAAC,KAAK,mBAAmB;EAChE,MAAM,mBAAmB,KAAA;EACzB,KAAK,oBAAoB,eAAe;CACzC;CACA,IAAI,QAAQ,mBAAmB,QAAQ,CAAC,KAAK,mBAAmB;EAC/D,MAAM,kBAAkB,KAAA;EACxB,KAAK,mBAAmB,eAAe;CACxC;CACA,IAAI,QAAQ,QAAQ,QAAQ,CAAC,KAAK,cAAc;EAC/C,MAAM,OAAO,KAAA;EACb,KAAK,QAAQ,eAAe;CAC7B;CAEA,IAAI,QAAQ,iBAAiB,QAAQ,CAAC,KAAK,uBAAuB;EACjE,MAAM,gBAAgB,KAAA;EACtB,KAAK,iBAAiB,eAAe;CACtC;CAEA,IAAI,CAAC,KAAK,yBAAyB;EAClC,MAAM,EAAE,oBAAoB;EAQ5B,IANC,mBAAmB,QACnB,OAAO,OAAO,eAAe,CAAC,CAAC,MAC7B,UACA,qBAAqB,SAAS,MAAM,mBAAmB,IACzD,GAEsB;GACtB,KAAK,mBAAmB,wBAAwB;GAChD,IAAI,mBAAmB,MAAM;IAC5B,MAAM,UAAmC,CAAC;IAC1C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,eAAe,GACxD,IAAI,qBAAqB,OAAO;KAC/B,MAAM,EAAE,iBAAiB,UAAU,GAAG,SAAS;KAC/C,QAAQ,OAAO;IAChB,OACC,QAAQ,OAAO;IAGjB,MAAM,kBAAkB;GACzB;EACD;CACD;CAEA,IAAI,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,GACjC,OAAO;EAAE;EAAS;CAAS;CAE5B,OAAO;EAAE,SAAS;GAAE,GAAG;GAAS,GAAG;EAAM;EAAG;CAAS;AACtD;;;;AAKA,SAAgB,yBAAyB,OAA0B;CAClE,IAAI,SAAS;CACb,OAAO,IAAI,gBAGT,EACD,UAAU,MAAM,YAAY;EAC3B,IAAI,CAAC,UAAU,KAAK,SAAS,gBAAgB;GAC5C,SAAS;GACT,WAAW,QAAQ;IAClB,GAAG;IACH,UAAU,CAAC,GAAG,OAAO,GAAG,KAAK,QAAQ;GACtC,CAAC;EACF,OACC,WAAW,QAAQ,IAAI;CAEzB,EACD,CAAC;AACF"}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
//#region src/lib/neon-chat-options.d.ts
|
|
2
2
|
/** The models.dev `neon` catalog (canonical, unprefixed ids). */
|
|
3
|
-
declare const NEON_MODELS_DEV_IDS: readonly ["claude-
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
* Verified to resolve against the gateway; retained for autocomplete. If
|
|
7
|
-
* models.dev later lists one of these, the drift check flags it for promotion
|
|
8
|
-
* into `NEON_MODELS_DEV_IDS`.
|
|
9
|
-
*/
|
|
10
|
-
declare const NEON_EXTRA_MODEL_IDS: readonly ["claude-opus-4-8", "gpt-5-2-codex", "gpt-5-3-codex", "gpt-5-5-pro", "gemini-3-5-flash", "gemma-3-12b", "llama-4-maverick", "meta-llama-3-3-70b-instruct", "meta-llama-3-1-8b-instruct", "qwen3-next-80b-a3b-instruct", "qwen35-122b-a10b"];
|
|
11
|
-
/** A known Neon AI Gateway model id (models.dev catalog + gateway extras). */
|
|
12
|
-
type NeonKnownModelId = (typeof NEON_MODELS_DEV_IDS)[number] | (typeof NEON_EXTRA_MODEL_IDS)[number];
|
|
3
|
+
declare const NEON_MODELS_DEV_IDS: readonly ["claude-fable-5", "claude-haiku-4-5", "claude-opus-4-1", "claude-opus-4-5", "claude-opus-4-6", "claude-opus-4-7", "claude-opus-4-8", "claude-opus-5", "claude-sonnet-4-5", "claude-sonnet-4-6", "claude-sonnet-5", "gpt-5", "gpt-5-1", "gpt-5-2", "gpt-5-3-codex", "gpt-5-4", "gpt-5-4-mini", "gpt-5-4-nano", "gpt-5-5", "gpt-5-5-pro", "gpt-5-6-luna", "gpt-5-6-sol", "gpt-5-6-terra", "gpt-5-mini", "gpt-5-nano", "gpt-oss-120b", "gpt-oss-20b", "gemini-3-1-flash-lite", "gemini-3-1-pro", "gemini-3-5-flash", "gemini-3-flash", "gemma-3-12b", "llama-4-maverick", "meta-llama-3-1-8b-instruct", "meta-llama-3-3-70b-instruct", "qwen3-next-80b-a3b-instruct", "qwen35-122b-a10b", "glm-5-2", "inkling"];
|
|
4
|
+
/** A known Neon AI Gateway model id. */
|
|
5
|
+
type NeonKnownModelId = (typeof NEON_MODELS_DEV_IDS)[number];
|
|
13
6
|
/**
|
|
14
7
|
* A Neon AI Gateway model id. Known ids are listed for autocomplete; any other
|
|
15
8
|
* id (e.g. a brand-new model, or the legacy `databricks-` prefixed form) is
|
|
@@ -17,5 +10,5 @@ type NeonKnownModelId = (typeof NEON_MODELS_DEV_IDS)[number] | (typeof NEON_EXTR
|
|
|
17
10
|
*/
|
|
18
11
|
type NeonChatModelId = NeonKnownModelId | (string & {});
|
|
19
12
|
//#endregion
|
|
20
|
-
export {
|
|
13
|
+
export { NEON_MODELS_DEV_IDS, NeonChatModelId, NeonKnownModelId };
|
|
21
14
|
//# sourceMappingURL=neon-chat-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-chat-options.d.ts","names":[],"sources":["../../src/lib/neon-chat-options.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"neon-chat-options.d.ts","names":[],"sources":["../../src/lib/neon-chat-options.ts"],"mappings":";;AAsBa,cAAA,mBAgDH,EAAA,SAAA,CAAA,gBAAA,EAAA,kBAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,SAAA,EAAA,SAAA,EAAA,eAAA,EAAA,SAAA,EAAA,cAAA,EAAA,cAAA,EAAA,SAAA,EAAA,aAAA,EAAA,cAAA,EAAA,aAAA,EAAA,eAAA,EAAA,YAAA,EAAA,YAAA,EAAA,cAAA,EAAA,aAAA,EAAA,uBAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA,aAAA,EAAA,kBAAA,EAAA,4BAAA,EAAA,6BAAA,EAAA,6BAAA,EAAA,kBAAA,EAAA,SAAA,EAAA,SAAA,CAAA;AAGV;AAOY,KAPA,gBAAA,GAOe,CAAG,OAPS,mBAOO,CAAA,CAAA,MAAA,CAAA;;;;;;KAAlC,eAAA,GAAkB"}
|
|
@@ -1,52 +1,47 @@
|
|
|
1
1
|
//#region src/lib/neon-chat-options.ts
|
|
2
2
|
/** The models.dev `neon` catalog (canonical, unprefixed ids). */
|
|
3
3
|
const NEON_MODELS_DEV_IDS = [
|
|
4
|
-
"claude-
|
|
5
|
-
"claude-
|
|
6
|
-
"claude-opus-4-5",
|
|
4
|
+
"claude-fable-5",
|
|
5
|
+
"claude-haiku-4-5",
|
|
7
6
|
"claude-opus-4-1",
|
|
8
|
-
"claude-
|
|
7
|
+
"claude-opus-4-5",
|
|
8
|
+
"claude-opus-4-6",
|
|
9
|
+
"claude-opus-4-7",
|
|
10
|
+
"claude-opus-4-8",
|
|
11
|
+
"claude-opus-5",
|
|
9
12
|
"claude-sonnet-4-5",
|
|
10
|
-
"claude-sonnet-4",
|
|
11
|
-
"claude-
|
|
13
|
+
"claude-sonnet-4-6",
|
|
14
|
+
"claude-sonnet-5",
|
|
12
15
|
"gpt-5",
|
|
13
|
-
"gpt-5-mini",
|
|
14
|
-
"gpt-5-nano",
|
|
15
16
|
"gpt-5-1",
|
|
16
17
|
"gpt-5-2",
|
|
18
|
+
"gpt-5-3-codex",
|
|
17
19
|
"gpt-5-4",
|
|
18
20
|
"gpt-5-4-mini",
|
|
19
21
|
"gpt-5-4-nano",
|
|
20
22
|
"gpt-5-5",
|
|
23
|
+
"gpt-5-5-pro",
|
|
24
|
+
"gpt-5-6-luna",
|
|
25
|
+
"gpt-5-6-sol",
|
|
26
|
+
"gpt-5-6-terra",
|
|
27
|
+
"gpt-5-mini",
|
|
28
|
+
"gpt-5-nano",
|
|
21
29
|
"gpt-oss-120b",
|
|
22
30
|
"gpt-oss-20b",
|
|
23
|
-
"gemini-3-pro",
|
|
24
|
-
"gemini-3-flash",
|
|
25
|
-
"gemini-3-1-pro",
|
|
26
31
|
"gemini-3-1-flash-lite",
|
|
27
|
-
"gemini-
|
|
28
|
-
"gemini-2-5-flash"
|
|
29
|
-
];
|
|
30
|
-
/**
|
|
31
|
-
* Ids the gateway serves that the models.dev `neon` provider does not list.
|
|
32
|
-
* Verified to resolve against the gateway; retained for autocomplete. If
|
|
33
|
-
* models.dev later lists one of these, the drift check flags it for promotion
|
|
34
|
-
* into `NEON_MODELS_DEV_IDS`.
|
|
35
|
-
*/
|
|
36
|
-
const NEON_EXTRA_MODEL_IDS = [
|
|
37
|
-
"claude-opus-4-8",
|
|
38
|
-
"gpt-5-2-codex",
|
|
39
|
-
"gpt-5-3-codex",
|
|
40
|
-
"gpt-5-5-pro",
|
|
32
|
+
"gemini-3-1-pro",
|
|
41
33
|
"gemini-3-5-flash",
|
|
34
|
+
"gemini-3-flash",
|
|
42
35
|
"gemma-3-12b",
|
|
43
36
|
"llama-4-maverick",
|
|
44
|
-
"meta-llama-3-3-70b-instruct",
|
|
45
37
|
"meta-llama-3-1-8b-instruct",
|
|
38
|
+
"meta-llama-3-3-70b-instruct",
|
|
46
39
|
"qwen3-next-80b-a3b-instruct",
|
|
47
|
-
"qwen35-122b-a10b"
|
|
40
|
+
"qwen35-122b-a10b",
|
|
41
|
+
"glm-5-2",
|
|
42
|
+
"inkling"
|
|
48
43
|
];
|
|
49
44
|
//#endregion
|
|
50
|
-
export {
|
|
45
|
+
export { NEON_MODELS_DEV_IDS };
|
|
51
46
|
|
|
52
47
|
//# sourceMappingURL=neon-chat-options.js.map
|