@bastani/pi-ai 0.9.24 → 0.9.25-alpha.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.
- package/CHANGELOG.md +18 -0
- package/NOTICE.md +1 -1
- package/README.md +17 -6
- package/dist/api/cloudflare-workers-ai-system-one.js +2 -2
- package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts +2 -2
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +8 -28
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +25 -6
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +66 -19
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts +2 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +21 -32
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/system-one-shared.d.ts +2 -2
- package/dist/api/system-one-shared.d.ts.map +1 -1
- package/dist/api/system-one-shared.js +26 -1
- package/dist/api/system-one-shared.js.map +1 -1
- package/dist/api/typesafe-system-one.js +2 -2
- package/dist/api/typesafe-system-one.js.map +1 -1
- package/dist/auth/helpers.js +1 -1
- package/dist/auth/helpers.js.map +1 -1
- package/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/dist/auth/oauth/anthropic.js +19 -128
- package/dist/auth/oauth/anthropic.js.map +1 -1
- package/dist/auth/oauth/callback-server.d.ts +31 -0
- package/dist/auth/oauth/callback-server.d.ts.map +1 -0
- package/dist/auth/oauth/callback-server.js +138 -0
- package/dist/auth/oauth/callback-server.js.map +1 -0
- package/dist/auth/oauth/load.d.ts +2 -0
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +5 -0
- package/dist/auth/oauth/load.js.map +1 -1
- package/dist/auth/oauth/oauth-page.js +1 -1
- package/dist/auth/oauth/oauth-page.js.map +1 -1
- package/dist/auth/oauth/openai-chatgpt.d.ts +3 -0
- package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -0
- package/dist/auth/oauth/openai-chatgpt.js +250 -0
- package/dist/auth/oauth/openai-chatgpt.js.map +1 -0
- package/dist/auth/oauth/openai-codex.d.ts +1 -1
- package/dist/auth/oauth/openai-codex.d.ts.map +1 -1
- package/dist/auth/oauth/openai-codex.js +20 -124
- package/dist/auth/oauth/openai-codex.js.map +1 -1
- package/dist/auth/oauth/openrouter.d.ts +1 -1
- package/dist/auth/oauth/openrouter.d.ts.map +1 -1
- package/dist/auth/oauth/openrouter.js +19 -138
- package/dist/auth/oauth/openrouter.js.map +1 -1
- package/dist/auth/oauth/radius.d.ts +1 -1
- package/dist/auth/oauth/radius.d.ts.map +1 -1
- package/dist/auth/oauth/radius.js +21 -89
- package/dist/auth/oauth/radius.js.map +1 -1
- package/dist/auth/types.d.ts +6 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/bun-oauth.d.ts.map +1 -1
- package/dist/bun-oauth.js +2 -0
- package/dist/bun-oauth.js.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/models.d.ts +5 -3
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +6 -2
- package/dist/models.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/azure-openai-responses.json +1 -1
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cerebras.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/openai-codex.js +1 -1
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +11 -2
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/opencode.d.ts +3 -1
- package/dist/providers/opencode.d.ts.map +1 -1
- package/dist/providers/opencode.js +4 -2
- package/dist/providers/opencode.js.map +1 -1
- package/dist/providers/vercel-ai-gateway.d.ts.map +1 -1
- package/dist/providers/vercel-ai-gateway.js +4 -2
- package/dist/providers/vercel-ai-gateway.js.map +1 -1
- package/dist/types.d.ts +40 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/oauth-page.d.ts +2 -0
- package/dist/utils/oauth-page.d.ts.map +1 -0
- package/dist/utils/oauth-page.js +2 -0
- package/dist/utils/oauth-page.js.map +1 -0
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +3 -0
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/validation.d.ts +1 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +3 -0
- package/dist/utils/validation.js.map +1 -1
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ This package is a Bastani fork of `@earendil-works/pi-ai`. Upstream history at t
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.25-alpha.1] - 2026-09-29
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added GPT-6.1 Sol for OpenAI and Codex with supported reasoning efforts, prompt-cache and tool capabilities, and long-context pricing metadata.
|
|
12
|
+
- Added GPT-6.1 Sol to the GitHub Copilot catalog with Copilot's Responses endpoint, supported reasoning efforts, and provider-published context and output limits. Availability remains subject to the account's model policy.
|
|
13
|
+
- Added **Sign in with ChatGPT** for the OpenAI Responses API alongside API-key authentication, separate from Codex subscription login.
|
|
14
|
+
- Added Jev classifiers on Vercel AI Gateway and OpenCode Zen, and provider-reported classifier usage and costs, including billed responses with invalid answers.
|
|
15
|
+
- Added the lightweight `@bastani/pi-ai/models` entry point for model catalog consumers.
|
|
16
|
+
- Added `Model.serviceTiers` and `getServiceTierCost()` for the Fast and Ultrafast tiers a model advertises and their published rates. The OpenAI catalog follows OpenAI's Fast and Ultrafast pricing tables. The Codex catalog follows Codex's per-model tiers: Fast for every model except GPT-5.3 Codex Spark, and Ultrafast for GPT-6 Astra.
|
|
17
|
+
- The OpenAI Responses adapter can send GPT-6 Astra's `ultrafast` tier.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- The Codex Responses adapter sends `service_tier` only when the model advertises it, following Codex: `flex` always passes through, `default` sends no tier, and an unadvertised tier is left out instead of failing.
|
|
22
|
+
- The OpenAI Responses adapter leaves out a Fast or Ultrafast tier the model doesn't advertise. It sends other tiers as requested.
|
|
23
|
+
- Fast and Ultrafast usage is priced at the served tier's published rates. A model without tier metadata keeps the previous Fast multiplier.
|
|
24
|
+
|
|
7
25
|
## [0.9.24] - 2026-09-29
|
|
8
26
|
|
|
9
27
|
### Added
|
package/NOTICE.md
CHANGED
|
@@ -6,7 +6,7 @@ monorepo at `packages/ai` and publishes at the same version as `@bastani/atomic`
|
|
|
6
6
|
|
|
7
7
|
- Upstream package: [`@earendil-works/pi-ai`](https://www.npmjs.com/package/@earendil-works/pi-ai)
|
|
8
8
|
- Original fork point: `v0.84.2` (`914cf1472e715297caa30db4b9535d534a9eb718`)
|
|
9
|
-
- Pi AI fixes and generated
|
|
9
|
+
- Applicable Pi AI fixes and generated catalogs synced through audited upstream `main`: `earendil-works/pi@1b347794e2a630e4359f2584f4eea388145d0ddf`. Atomic retains its adaptations and does not enable upstream virtual models.
|
|
10
10
|
- Catalog JSON under `src/providers/data/` is generated at build time from models.dev, matching upstream. It is not committed.
|
|
11
11
|
|
|
12
12
|
Original work is Copyright (c) 2025 Mario Zechner and is licensed under the MIT License.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @bastani/pi-ai
|
|
2
2
|
|
|
3
|
-
Bastani-branded fork of [`@earendil-works/pi-ai`](https://www.npmjs.com/package/@earendil-works/pi-ai) from [earendil-works/pi](https://github.com/earendil-works/pi). Originally forked at **v0.84.2** (`914cf1472e715297caa30db4b9535d534a9eb718`); upstream Pi AI fixes and the unified model catalog are synced through [`
|
|
3
|
+
Bastani-branded fork of [`@earendil-works/pi-ai`](https://www.npmjs.com/package/@earendil-works/pi-ai) from [earendil-works/pi](https://github.com/earendil-works/pi). Originally forked at **v0.84.2** (`914cf1472e715297caa30db4b9535d534a9eb718`); applicable upstream Pi AI fixes and the unified model catalog are synced through [`1b347794e2a630e4359f2584f4eea388145d0ddf`](https://github.com/earendil-works/pi/commit/1b347794e2a630e4359f2584f4eea388145d0ddf). `@bastani/pi-ai` publishes at the same version as Atomic. `npm run build` refreshes the models.dev catalog, same as upstream.
|
|
4
4
|
|
|
5
5
|
The public API is a drop-in replacement: install `@bastani/pi-ai` and import from `@bastani/pi-ai` instead of `@earendil-works/pi-ai`. See [NOTICE.md](NOTICE.md). This package lives in the Atomic monorepo and publishes from `.github/workflows/publish.yml`. The first npm version must be published by hand so trusted publishing can be attached.
|
|
6
6
|
|
|
@@ -63,10 +63,10 @@ Unified LLM API with provider collections, automatic auth resolution, token and
|
|
|
63
63
|
|
|
64
64
|
## Supported Providers
|
|
65
65
|
|
|
66
|
-
- **OpenAI**
|
|
66
|
+
- **OpenAI** (API key or Sign in with ChatGPT)
|
|
67
67
|
- **Ant Ling**
|
|
68
68
|
- **Azure OpenAI (Responses)**
|
|
69
|
-
- **OpenAI Codex** (ChatGPT
|
|
69
|
+
- **OpenAI Codex (legacy)** (ChatGPT subscription, requires OAuth, see below)
|
|
70
70
|
- **Radius** (API key or OAuth, with a dynamically refreshed gateway catalog)
|
|
71
71
|
- **TypeSafe** (System One classifier API)
|
|
72
72
|
- **DeepSeek**
|
|
@@ -261,6 +261,8 @@ models.setProvider(openrouterProvider());
|
|
|
261
261
|
|
|
262
262
|
Provider factories import their model catalog and a lazy API wrapper. They do not import other providers. With bundler code splitting, SDK implementations (`@anthropic-ai/sdk`, `openai`, `@google/genai`, etc.) stay in lazy chunks loaded on the first request to a model of that API.
|
|
263
263
|
|
|
264
|
+
For a collection without TypeBox, built-in catalogs or provider SDKs, import `createModels` and `createProvider` from `@bastani/pi-ai/models`. Import the provider factories you need separately.
|
|
265
|
+
|
|
264
266
|
### All Built-in Providers
|
|
265
267
|
|
|
266
268
|
For apps that want everything (as in Quick Start):
|
|
@@ -878,6 +880,8 @@ Classifier models consume structured JSON state and answer one or more typed que
|
|
|
878
880
|
| `typesafe` | `jev-latest` | `TYPESAFE_API_KEY` |
|
|
879
881
|
| `openrouter` | `typesafe/jev-1.13`, `~typesafe/jev-latest` | `OPENROUTER_API_KEY` or OpenRouter OAuth |
|
|
880
882
|
| `cloudflare-workers-ai` | `typesafe/jev` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
883
|
+
| `vercel-ai-gateway` | `typesafe-ai/jev` | `AI_GATEWAY_API_KEY` |
|
|
884
|
+
| `opencode` | `jev-1.13`, `jev-1.13-free` | `OPENCODE_API_KEY` |
|
|
881
885
|
|
|
882
886
|
```typescript
|
|
883
887
|
import { builtinModels } from '@bastani/pi-ai/providers/all';
|
|
@@ -913,6 +917,8 @@ console.log(result.answers);
|
|
|
913
917
|
|
|
914
918
|
The public contract uses `bool` questions and `{ type: "bool", probability }` answers. The TypeSafe adapter translates those to and from its `noul` wire representation. Like image generation, `classify()` resolves to a result with `stopReason: "error"` instead of rejecting for provider, authentication, or response errors.
|
|
915
919
|
|
|
920
|
+
System One results include `usage` when the service reports input or output token counts. Costs use the model's catalog pricing. A billed response can retain usage even when its answers are malformed; absent usage means unknown, not zero.
|
|
921
|
+
|
|
916
922
|
`ClassifierOptions.temperature` divides the answer logits by the given value before they are normalized; values above 1 soften the distribution. APIs that cannot apply it, such as System One, ignore it.
|
|
917
923
|
|
|
918
924
|
### Chat models on llama.cpp
|
|
@@ -993,6 +999,8 @@ for (const block of response.content) {
|
|
|
993
999
|
|
|
994
1000
|
`xhigh` and `max` are model-specific, opt-in levels. Use `getSupportedThinkingLevels(model)` to determine whether a concrete model exposes either level; models such as GPT-5.6 can expose both.
|
|
995
1001
|
|
|
1002
|
+
GPT-6.1 Sol supports `low`, `medium`, `high`, `xhigh` and `max` on OpenAI and Azure Responses. It does not support `off`. The Codex provider also exposes a `minimal` UI alias that sends `low` to the API.
|
|
1003
|
+
|
|
996
1004
|
### Provider-Specific Options (stream/complete)
|
|
997
1005
|
|
|
998
1006
|
`models.stream()`/`complete()` accept the owning API's full option set. Use `hasApi()` to narrow a dynamically looked-up model to its API for full option typing:
|
|
@@ -1620,7 +1628,7 @@ Browser compatibility notes:
|
|
|
1620
1628
|
For small bundles, import only the providers you need:
|
|
1621
1629
|
|
|
1622
1630
|
```typescript
|
|
1623
|
-
import { createModels } from '@bastani/pi-ai';
|
|
1631
|
+
import { createModels } from '@bastani/pi-ai/models';
|
|
1624
1632
|
import { openaiProvider } from '@bastani/pi-ai/providers/openai';
|
|
1625
1633
|
|
|
1626
1634
|
const models = createModels();
|
|
@@ -1693,7 +1701,8 @@ Use this when one process needs different provider settings per request, or when
|
|
|
1693
1701
|
Several providers support OAuth authentication instead of static API keys:
|
|
1694
1702
|
|
|
1695
1703
|
- **Anthropic** (Claude Pro/Max subscription)
|
|
1696
|
-
- **OpenAI
|
|
1704
|
+
- **OpenAI** (Sign in with ChatGPT, direct Responses API access)
|
|
1705
|
+
- **OpenAI Codex (legacy)** (ChatGPT subscription, Codex Responses access)
|
|
1697
1706
|
- **GitHub Copilot** (Copilot subscription)
|
|
1698
1707
|
- **OpenRouter** (OAuth PKCE that mints a user-controlled API key)
|
|
1699
1708
|
|
|
@@ -1733,6 +1742,8 @@ await models.complete(model, context);
|
|
|
1733
1742
|
await models.logout('anthropic');
|
|
1734
1743
|
```
|
|
1735
1744
|
|
|
1745
|
+
For OpenAI Sign in with ChatGPT, pass a fourth `LoginOptions` argument with `getDeviceId: () => installationUuid`. Persist this UUID and return the same value on later logins. The login registers a user-owned client and stores its issued client ID and granted scopes with the credential. Direct ChatGPT access omits unsupported temperature, output-token limits and cache-retention fields. If its shared subscription limit is exhausted, check [ChatGPT usage](https://chatgpt.com/settings/usage).
|
|
1746
|
+
|
|
1736
1747
|
### Vertex AI
|
|
1737
1748
|
|
|
1738
1749
|
Vertex AI models support either a Google Cloud API key or Application Default Credentials (ADC). Its provider-owned API-key login flow can configure either method:
|
|
@@ -1773,7 +1784,7 @@ Built-in login and refresh flows are private provider implementations. Use provi
|
|
|
1773
1784
|
|
|
1774
1785
|
Provider notes:
|
|
1775
1786
|
|
|
1776
|
-
**OpenAI Codex**: Requires a ChatGPT
|
|
1787
|
+
**OpenAI Codex (legacy)**: Requires a ChatGPT subscription with model access. Includes GPT-6.1 Sol and Codex models with extended context windows and reasoning capabilities. The library handles session-based prompt caching when `sessionId` is provided unless `cacheRetention` is `"none"`. Set `transport` to `"sse"`, `"websocket"`, or `"auto"` for Codex Responses transport selection. WebSocket connections with a `sessionId` and caching enabled are reused per session and expire after 5 minutes of inactivity.
|
|
1777
1788
|
|
|
1778
1789
|
Call `cleanupSessionResources(sessionId)` when finished with a Codex session so its pooled WebSocket connection does not keep the process alive. Import it from `@bastani/pi-ai`.
|
|
1779
1790
|
|
|
@@ -22,7 +22,7 @@ const transport = {
|
|
|
22
22
|
label: LABEL,
|
|
23
23
|
url: (model) => new URL("run", `${model.baseUrl.replace(/\/+$/u, "")}/`),
|
|
24
24
|
payload: (model, request) => ({ model: model.id, input: request }),
|
|
25
|
-
|
|
25
|
+
output: (body) => {
|
|
26
26
|
if (!isRecord(body))
|
|
27
27
|
throw new Error(`${LABEL} returned an unexpected response`);
|
|
28
28
|
if (body.success === false)
|
|
@@ -35,7 +35,7 @@ const transport = {
|
|
|
35
35
|
}
|
|
36
36
|
if (!isRecord(run.result))
|
|
37
37
|
throw new Error(`${LABEL} returned an unexpected response`);
|
|
38
|
-
return run.result
|
|
38
|
+
return run.result;
|
|
39
39
|
},
|
|
40
40
|
};
|
|
41
41
|
/** Cloudflare Workers AI System One classification with public `bool` values mapped to wire-level `noul`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare-workers-ai-system-one.js","sourceRoot":"","sources":["../../src/api/cloudflare-workers-ai-system-one.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAA2B,MAAM,wBAAwB,CAAC;AAE9F,MAAM,KAAK,GAAG,uBAAuB,CAAC;AAEtC,SAAS,sBAAsB,CAAC,MAAe;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM;aACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;aAClG,MAAM,CAAC,CAAC,OAAO,EAAqB,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;QAChE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,GAAG,KAAK,WAAW,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1E,CAAC;IACD,OAAO,GAAG,KAAK,iBAAiB,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,SAAS,GAAuB;IACrC,GAAG,EAAE,kCAAkC;IACvC,KAAK,EAAE,KAAK;IACZ,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC;IACxE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAClE,
|
|
1
|
+
{"version":3,"file":"cloudflare-workers-ai-system-one.js","sourceRoot":"","sources":["../../src/api/cloudflare-workers-ai-system-one.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAA2B,MAAM,wBAAwB,CAAC;AAE9F,MAAM,KAAK,GAAG,uBAAuB,CAAC;AAEtC,SAAS,sBAAsB,CAAC,MAAe;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM;aACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;aAClG,MAAM,CAAC,CAAC,OAAO,EAAqB,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;QAChE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,GAAG,KAAK,WAAW,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1E,CAAC;IACD,OAAO,GAAG,KAAK,iBAAiB,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,SAAS,GAAuB;IACrC,GAAG,EAAE,kCAAkC;IACvC,KAAK,EAAE,KAAK;IACZ,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC;IACxE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAClE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;QACjF,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACjF,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;QAChF,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iCAAiC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;QACvF,OAAO,GAAG,CAAC,MAAM,CAAC;IACnB,CAAC;CACD,CAAC;AAEF,6GAA6G;AAC7G,MAAM,CAAC,MAAM,QAAQ,GAA0C,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAC1F,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC","sourcesContent":["import type { ClassifierFunction, ClassifierOptions } from \"../types.ts\";\nimport { classifySystemOne, isRecord, type SystemOneTransport } from \"./system-one-shared.ts\";\n\nconst LABEL = \"Cloudflare Workers AI\";\n\nfunction cloudflareErrorMessage(errors: unknown): string {\n\tif (Array.isArray(errors)) {\n\t\tconst messages = errors\n\t\t\t.map((error) => (isRecord(error) && typeof error.message === \"string\" ? error.message : undefined))\n\t\t\t.filter((message): message is string => message !== undefined);\n\t\tif (messages.length > 0) return `${LABEL} error: ${messages.join(\"; \")}`;\n\t}\n\treturn `${LABEL} request failed`;\n}\n\n/**\n * System One models on the Workers AI REST endpoint:\n * `POST /accounts/{account}/ai/run` with `{ model, input }`. The REST API\n * wraps the model output in Cloudflare's API envelope and a run record:\n * `{ success, result: { state: \"Completed\", result: { answers, usage } } }`.\n * https://developers.cloudflare.com/ai/models/typesafe/jev/\n */\nconst transport: SystemOneTransport = {\n\tapi: \"cloudflare-workers-ai-system-one\",\n\tlabel: LABEL,\n\turl: (model) => new URL(\"run\", `${model.baseUrl.replace(/\\/+$/u, \"\")}/`),\n\tpayload: (model, request) => ({ model: model.id, input: request }),\n\toutput: (body) => {\n\t\tif (!isRecord(body)) throw new Error(`${LABEL} returned an unexpected response`);\n\t\tif (body.success === false) throw new Error(cloudflareErrorMessage(body.errors));\n\t\tconst run = body.result;\n\t\tif (!isRecord(run)) throw new Error(`${LABEL} returned an unexpected response`);\n\t\tif (run.state !== \"Completed\") {\n\t\t\tthrow new Error(`${LABEL} run did not complete (state: ${String(run.state)})`);\n\t\t}\n\t\tif (!isRecord(run.result)) throw new Error(`${LABEL} returned an unexpected response`);\n\t\treturn run.result;\n\t},\n};\n\n/** Cloudflare Workers AI System One classification with public `bool` values mapped to wire-level `noul`. */\nexport const classify: ClassifierFunction<ClassifierOptions> = (model, context, options) =>\n\tclassifySystemOne(transport, model, context, options);\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ResponseCreateParamsStreaming } from "openai/resources/responses/responses.js";
|
|
2
1
|
import type { SimpleStreamOptions, StreamFunction, StreamOptions } from "../types.ts";
|
|
2
|
+
import { type ResponsesServiceTier } from "./openai-responses-shared.ts";
|
|
3
3
|
export interface OpenAICodexResponsesOptions extends StreamOptions {
|
|
4
4
|
reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
5
5
|
reasoningSummary?: "auto" | "concise" | "detailed" | "off" | "on" | null;
|
|
6
|
-
serviceTier?:
|
|
6
|
+
serviceTier?: ResponsesServiceTier;
|
|
7
7
|
textVerbosity?: "low" | "medium" | "high";
|
|
8
8
|
toolChoice?: "auto" | "none" | "required";
|
|
9
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-codex-responses.d.ts","sourceRoot":"","sources":["../../src/api/openai-codex-responses.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-codex-responses.d.ts","sourceRoot":"","sources":["../../src/api/openai-codex-responses.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAMX,mBAAmB,EACnB,cAAc,EACd,aAAa,EAGb,MAAM,aAAa,CAAC;AAwBrB,OAAO,EAMN,KAAK,oBAAoB,EAGzB,MAAM,8BAA8B,CAAC;AAkCtC,MAAM,WAAW,2BAA4B,SAAQ,aAAa;IACjE,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IACnF,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IACzE,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,aAAa,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;CAC1C;AAwJD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,wBAAwB,EAAE,2BAA2B,CA0QxF,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,wBAAwB,EAAE,mBAAmB,CAqBtF,CAAC;AA2WF,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AA0BD,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,MAAM,GAAG,8BAA8B,GAAG,SAAS,CAG/G;AAED,wBAAgB,mCAAmC,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAQ5E;AAED,wBAAgB,iCAAiC,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAc1E"}
|
|
@@ -13,7 +13,7 @@ import { getDeclaredTools, getInitialSystemMessage, normalizeContext, resolveTra
|
|
|
13
13
|
import { uuidv7 } from "../utils/uuid.js";
|
|
14
14
|
import { createGrammarToolInputProperties } from "./constrained-sampling.js";
|
|
15
15
|
import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
|
|
16
|
-
import { assertPayloadPreservesFastRoute, convertResponsesMessages, convertResponsesTools, processResponsesStream, resolveRequestedServiceTier, } from "./openai-responses-shared.js";
|
|
16
|
+
import { applyServiceTierPricing, assertPayloadPreservesFastRoute, convertResponsesMessages, convertResponsesTools, processResponsesStream, resolveRequestedServiceTier, codexServiceTierForRequest, } from "./openai-responses-shared.js";
|
|
17
17
|
import { buildBaseOptions } from "./simple-options.js";
|
|
18
18
|
// ============================================================================
|
|
19
19
|
// Configuration
|
|
@@ -409,8 +409,7 @@ function buildRequestBody(model, context, options, cacheSessionId, grammarToolIn
|
|
|
409
409
|
if (options?.temperature !== undefined) {
|
|
410
410
|
body.temperature = options.temperature;
|
|
411
411
|
}
|
|
412
|
-
|
|
413
|
-
const requestedServiceTier = resolveRequestedServiceTier(model, options?.serviceTier);
|
|
412
|
+
const requestedServiceTier = resolveCodexRequestServiceTier(model, options?.serviceTier);
|
|
414
413
|
if (requestedServiceTier !== undefined) {
|
|
415
414
|
body.service_tier = requestedServiceTier;
|
|
416
415
|
}
|
|
@@ -439,31 +438,12 @@ function buildRequestBody(model, context, options, cacheSessionId, grammarToolIn
|
|
|
439
438
|
}
|
|
440
439
|
return body;
|
|
441
440
|
}
|
|
442
|
-
function
|
|
443
|
-
|
|
444
|
-
// per-model rate (gpt-5.5) is not silently charged the generic multiplier.
|
|
445
|
-
const pricedModelId = model.fastRoute?.baseModelId ?? model.id;
|
|
446
|
-
switch (serviceTier) {
|
|
447
|
-
case "flex":
|
|
448
|
-
return 0.5;
|
|
449
|
-
case "priority":
|
|
450
|
-
return pricedModelId === "gpt-5.5" ? 2.5 : 2;
|
|
451
|
-
default:
|
|
452
|
-
return 1;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
function applyServiceTierPricing(usage, serviceTier, model) {
|
|
456
|
-
const multiplier = getServiceTierCostMultiplier(model, serviceTier);
|
|
457
|
-
if (multiplier === 1)
|
|
458
|
-
return;
|
|
459
|
-
usage.cost.input *= multiplier;
|
|
460
|
-
usage.cost.output *= multiplier;
|
|
461
|
-
usage.cost.cacheRead *= multiplier;
|
|
462
|
-
usage.cost.cacheWrite *= multiplier;
|
|
463
|
-
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
441
|
+
function resolveCodexRequestServiceTier(model, optionsServiceTier) {
|
|
442
|
+
return codexServiceTierForRequest(model, resolveRequestedServiceTier(model, optionsServiceTier));
|
|
464
443
|
}
|
|
465
444
|
function resolveCodexServiceTier(responseServiceTier, requestServiceTier) {
|
|
466
|
-
if (responseServiceTier === "default" &&
|
|
445
|
+
if (responseServiceTier === "default" &&
|
|
446
|
+
(requestServiceTier === "flex" || requestServiceTier === "priority" || requestServiceTier === "ultrafast")) {
|
|
467
447
|
return requestServiceTier;
|
|
468
448
|
}
|
|
469
449
|
return responseServiceTier ?? requestServiceTier;
|
|
@@ -491,7 +471,7 @@ function resolveCodexWebSocketUrl(baseUrl) {
|
|
|
491
471
|
async function processStream(response, output, stream, model, grammarToolInputProperties, options, streamDeadline) {
|
|
492
472
|
const events = mapCodexEvents(parseSSE(response, streamDeadline.signal), output, model, options?.onProviderStreamEvent);
|
|
493
473
|
await processResponsesStream(withStreamDeadline(events, streamDeadline.deadlineMs, streamDeadline.abort), output, stream, model, {
|
|
494
|
-
serviceTier:
|
|
474
|
+
serviceTier: resolveCodexRequestServiceTier(model, options?.serviceTier),
|
|
495
475
|
grammarToolInputProperties,
|
|
496
476
|
resolveServiceTier: resolveCodexServiceTier,
|
|
497
477
|
applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),
|
|
@@ -1217,7 +1197,7 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
|
|
|
1217
1197
|
try {
|
|
1218
1198
|
socket.send(JSON.stringify({ type: "response.create", ...requestBody }));
|
|
1219
1199
|
await processResponsesStream(startWebSocketOutputOnFirstEvent(mapCodexEvents(parseWebSocket(socket, options?.signal, idleTimeoutMs), output, model, options?.onProviderStreamEvent), onStart), output, stream, model, {
|
|
1220
|
-
serviceTier:
|
|
1200
|
+
serviceTier: resolveCodexRequestServiceTier(model, options?.serviceTier),
|
|
1221
1201
|
grammarToolInputProperties,
|
|
1222
1202
|
resolveServiceTier: resolveCodexServiceTier,
|
|
1223
1203
|
applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),
|