@absolutejs/ai 0.0.49 → 0.0.50
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/README.md +117 -0
- package/dist/ai/index.js +661 -54
- package/dist/ai/index.js.map +14 -12
- package/dist/ai/providers/anthropic.js +6 -2
- package/dist/ai/providers/anthropic.js.map +4 -4
- package/dist/ai/providers/gemini.js +33 -3
- package/dist/ai/providers/gemini.js.map +4 -4
- package/dist/ai/providers/ollama.js +3 -2
- package/dist/ai/providers/ollama.js.map +3 -3
- package/dist/ai/providers/openai.js +130 -35
- package/dist/ai/providers/openai.js.map +4 -4
- package/dist/ai/providers/openaiCompatible.js +130 -35
- package/dist/ai/providers/openaiCompatible.js.map +4 -4
- package/dist/ai/providers/openaiResponses.js +48 -18
- package/dist/ai/providers/openaiResponses.js.map +4 -4
- package/dist/ai/providers/openrouter.js +1757 -0
- package/dist/ai/providers/openrouter.js.map +17 -0
- package/dist/src/ai/generateAI.d.ts +4 -1
- package/dist/src/ai/index.d.ts +2 -0
- package/dist/src/ai/providers/openai.d.ts +7 -3
- package/dist/src/ai/providers/openaiResponses.d.ts +9 -4
- package/dist/src/ai/providers/openrouter.d.ts +113 -0
- package/dist/src/ai/providers/openrouterClient.d.ts +147 -0
- package/dist/types/ai.d.ts +63 -6
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -78,3 +78,120 @@ completion. Payload types are exported (`AISSECompletePayload`,
|
|
|
78
78
|
The default (HTML) path is unchanged for the built-in HTMX/default UI, except an
|
|
79
79
|
abort now renders the (previously unused) `canceled` renderer instead of a
|
|
80
80
|
misleading usage chip.
|
|
81
|
+
|
|
82
|
+
## OpenRouter
|
|
83
|
+
|
|
84
|
+
`@absolutejs/ai/openrouter` uses the shared provider contract and
|
|
85
|
+
OpenAI-compatible stream parser while adding OpenRouter-specific routing,
|
|
86
|
+
attribution, cost metadata, and local model-policy enforcement.
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { openrouter } from "@absolutejs/ai/openrouter";
|
|
90
|
+
|
|
91
|
+
const provider = openrouter({
|
|
92
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
93
|
+
appName: "My AbsoluteJS App",
|
|
94
|
+
appUrl: "https://example.com",
|
|
95
|
+
// Exact IDs and namespace wildcards are supported. A disallowed model fails
|
|
96
|
+
// locally before any request reaches OpenRouter.
|
|
97
|
+
allowedModels: ["anthropic/*", "google/*", "mistralai/*", "openai/*"],
|
|
98
|
+
// This becomes provider.only, so OpenRouter cannot select another inference
|
|
99
|
+
// provider during fallback.
|
|
100
|
+
allowedProviders: ["anthropic", "google-vertex", "mistral", "openai"],
|
|
101
|
+
routing: {
|
|
102
|
+
dataCollection: "deny",
|
|
103
|
+
maxPrice: { prompt: 3, completion: 15 },
|
|
104
|
+
requireParameters: true,
|
|
105
|
+
sort: "price",
|
|
106
|
+
zdr: true,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The adapter intentionally has no built-in geopolitical model list. Applications
|
|
112
|
+
must define their own explicit `allowedModels` and `allowedProviders` policy.
|
|
113
|
+
Avoid `openrouter/auto` unless it is deliberately present in that model policy.
|
|
114
|
+
|
|
115
|
+
Provider usage callbacks include OpenRouter's reported `costCredits`,
|
|
116
|
+
`upstreamInferenceCostCredits`, cache-read/write token counts, and reasoning
|
|
117
|
+
tokens when those fields are present in the final streaming usage message.
|
|
118
|
+
Hosted-tool counters are exposed as `serverToolUse`.
|
|
119
|
+
|
|
120
|
+
OpenRouter-specific features are available per request without weakening the
|
|
121
|
+
portable provider contract:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
await generateAI({
|
|
125
|
+
provider,
|
|
126
|
+
model: "anthropic/claude-sonnet-4.6",
|
|
127
|
+
messages,
|
|
128
|
+
providerOptions: {
|
|
129
|
+
openrouter: {
|
|
130
|
+
fallbackModels: ["openai/gpt-5.2"],
|
|
131
|
+
sessionId: conversationId, // sticky routing improves prompt-cache hits
|
|
132
|
+
serviceTier: "flex", // cheaper, slower capacity when available
|
|
133
|
+
responseCache: { enabled: true, ttlSeconds: 300 },
|
|
134
|
+
serverTools: [
|
|
135
|
+
{ type: "openrouter:web_search", parameters: { max_results: 3 } },
|
|
136
|
+
],
|
|
137
|
+
maxToolCalls: 5,
|
|
138
|
+
stopServerToolsWhen: [{ type: "max_cost", value: 0.02 }],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Other typed request options include presets, plugins, per-call provider routing,
|
|
145
|
+
message transforms, reasoning visibility, verbosity, user attribution, and an
|
|
146
|
+
`extraBody` escape hatch for new OpenRouter parameters. The escape hatch cannot
|
|
147
|
+
replace models, fallbacks, providers, presets, messages, plugins, or tools; those
|
|
148
|
+
fields use policy-aware typed options instead.
|
|
149
|
+
|
|
150
|
+
URL images and PDFs, base64 audio, and URL/base64 video inputs use the ordinary
|
|
151
|
+
AbsoluteJS content-block contract. URL citations are emitted as `citation`
|
|
152
|
+
chunks. The final `done` chunk includes the generation ID, resolved model,
|
|
153
|
+
selected inference provider, service tier, cache headers, and OpenRouter router
|
|
154
|
+
metadata when reported.
|
|
155
|
+
|
|
156
|
+
### OpenRouter platform client
|
|
157
|
+
|
|
158
|
+
`createOpenRouterClient()` covers model/provider discovery, embeddings,
|
|
159
|
+
reranking, image generation, Responses, speech, transcription, video jobs,
|
|
160
|
+
batches, presets, credits, key metadata, and generation metadata. Its typed
|
|
161
|
+
operations enforce the same model allowlist. `request()` and `requestRaw()` are
|
|
162
|
+
forward-compatible access to new or administrative OpenRouter endpoints.
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { createOpenRouterClient } from "@absolutejs/ai/openrouter";
|
|
166
|
+
|
|
167
|
+
const openrouterClient = createOpenRouterClient({
|
|
168
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
169
|
+
allowedModels: ["anthropic/*", "google/*", "mistralai/*", "openai/*"],
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const models = await openrouterClient.listModels({
|
|
173
|
+
supported_parameters: "tools",
|
|
174
|
+
});
|
|
175
|
+
const embedding = await openrouterClient.createEmbedding({
|
|
176
|
+
model: "openai/text-embedding-3-small",
|
|
177
|
+
input: "AbsoluteJS supports OpenRouter",
|
|
178
|
+
});
|
|
179
|
+
const reranked = await openrouterClient.rerank({
|
|
180
|
+
model: "openai/text-embedding-3-small",
|
|
181
|
+
query: "cost controls",
|
|
182
|
+
documents: ["response caching", "CSS layout"],
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
For a strict model-origin policy, also assign an OpenRouter key/workspace
|
|
187
|
+
guardrail with the same model allowlist. Provider allowlists restrict where a
|
|
188
|
+
model runs; they do not identify who developed it. Presets and router aliases
|
|
189
|
+
must be explicitly allowed, because their resolved model is controlled outside
|
|
190
|
+
the request. The raw client is intentionally unopinionated and should be limited
|
|
191
|
+
to trusted server-side administration code. OpenRouter's official SDK can be
|
|
192
|
+
used alongside this package for its complete organization, SSO, SCIM, BYOK, and
|
|
193
|
+
analytics type surface.
|
|
194
|
+
|
|
195
|
+
Use `openrouterResponses(config)` when an AbsoluteJS agent should stream through
|
|
196
|
+
OpenRouter's stateless Responses API instead of Chat Completions. It accepts the
|
|
197
|
+
same model/provider policies and `providerOptions.openrouter` controls.
|