openai-oauth-ai-provider 0.1.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 +21 -0
- package/README.md +375 -0
- package/dist/ai-sdk.d.ts +3 -0
- package/dist/ai-sdk.d.ts.map +1 -0
- package/dist/ai-sdk.js +3 -0
- package/dist/ai-sdk.js.map +1 -0
- package/dist/auth.d.ts +55 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +403 -0
- package/dist/auth.js.map +1 -0
- package/dist/authenticated-fetch.d.ts +8 -0
- package/dist/authenticated-fetch.d.ts.map +1 -0
- package/dist/authenticated-fetch.js +67 -0
- package/dist/authenticated-fetch.js.map +1 -0
- package/dist/codex-client.d.ts +3 -0
- package/dist/codex-client.d.ts.map +1 -0
- package/dist/codex-client.js +3 -0
- package/dist/codex-client.js.map +1 -0
- package/dist/codex.d.ts +29 -0
- package/dist/codex.d.ts.map +1 -0
- package/dist/codex.js +77 -0
- package/dist/codex.js.map +1 -0
- package/dist/collect-stream.d.ts +4 -0
- package/dist/collect-stream.d.ts.map +1 -0
- package/dist/collect-stream.js +126 -0
- package/dist/collect-stream.js.map +1 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +9 -0
- package/dist/constants.js.map +1 -0
- package/dist/core.d.ts +7 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +7 -0
- package/dist/core.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt.d.ts +18 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +68 -0
- package/dist/jwt.js.map +1 -0
- package/dist/provider.d.ts +38 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +106 -0
- package/dist/provider.js.map +1 -0
- package/dist/store.d.ts +32 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +167 -0
- package/dist/store.js.map +1 -0
- package/dist/tanstack-provider.d.ts +3 -0
- package/dist/tanstack-provider.d.ts.map +1 -0
- package/dist/tanstack-provider.js +3 -0
- package/dist/tanstack-provider.js.map +1 -0
- package/dist/tanstack.d.ts +35 -0
- package/dist/tanstack.d.ts.map +1 -0
- package/dist/tanstack.js +77 -0
- package/dist/tanstack.js.map +1 -0
- package/package.json +110 -0
- package/src/ai-sdk.ts +7 -0
- package/src/auth.ts +619 -0
- package/src/authenticated-fetch.ts +90 -0
- package/src/codex-client.ts +10 -0
- package/src/codex.ts +129 -0
- package/src/collect-stream.ts +149 -0
- package/src/constants.ts +8 -0
- package/src/core.ts +38 -0
- package/src/errors.ts +48 -0
- package/src/index.ts +22 -0
- package/src/jwt.ts +103 -0
- package/src/provider.ts +175 -0
- package/src/store.ts +220 -0
- package/src/tanstack-provider.ts +7 -0
- package/src/tanstack.ts +149 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stewart Bonnick
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
# openai-oauth-ai-provider
|
|
2
|
+
|
|
3
|
+
OpenAI OAuth authentication and AI-provider adapters for either:
|
|
4
|
+
|
|
5
|
+
- Vercel AI SDK 7 (`LanguageModelV4` / `ProviderV4`)
|
|
6
|
+
- TanStack AI (`TextAdapter` / AG-UI streams)
|
|
7
|
+
|
|
8
|
+
The package signs users in with the ChatGPT device-code flow used by the
|
|
9
|
+
open-source Codex CLI, automatically rotates OAuth tokens, and sends requests
|
|
10
|
+
to `https://chatgpt.com/backend-api/codex`.
|
|
11
|
+
|
|
12
|
+
The runtime uses Node built-ins plus the official provider implementation for
|
|
13
|
+
each SDK: `@ai-sdk/openai` and `@tanstack/ai-openai`.
|
|
14
|
+
|
|
15
|
+
This is an unofficial community project. It is not affiliated with or endorsed
|
|
16
|
+
by OpenAI, Vercel, or TanStack.
|
|
17
|
+
|
|
18
|
+
## Important status
|
|
19
|
+
|
|
20
|
+
The ChatGPT Codex backend is not the public OpenAI Platform API. This package
|
|
21
|
+
follows behavior visible in the open-source
|
|
22
|
+
[`openai/codex`](https://github.com/openai/codex) client, so endpoints and
|
|
23
|
+
payload requirements can change. Use it only with accounts and subscriptions
|
|
24
|
+
you are authorized to use, and follow applicable OpenAI terms and workspace
|
|
25
|
+
policies.
|
|
26
|
+
|
|
27
|
+
Prompts, messages, files, skills, tool inputs, and model configuration supplied
|
|
28
|
+
to an adapter are sent to the ChatGPT Codex backend. Remote MCP servers are a
|
|
29
|
+
separate trust boundary and may receive data selected by the model or your
|
|
30
|
+
application. Data retention, workspace controls, availability, quota, and
|
|
31
|
+
billing are controlled by those external services and your account policies.
|
|
32
|
+
|
|
33
|
+
Hosted capabilities such as remote MCP, uploaded skills, shell containers,
|
|
34
|
+
images, audio, and embeddings remain controlled by the signed-in ChatGPT plan
|
|
35
|
+
and backend. Client-side tools and client-side MCP do not depend on those
|
|
36
|
+
hosted capabilities.
|
|
37
|
+
|
|
38
|
+
## Requirements
|
|
39
|
+
|
|
40
|
+
- Node.js 24 or newer
|
|
41
|
+
- an ESM application (`import`; CommonJS `require` is not supported)
|
|
42
|
+
- a ChatGPT account with Codex access
|
|
43
|
+
- AI SDK 7 or TanStack AI 0.40+
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
For AI SDK 7:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npm install openai-oauth-ai-provider ai @ai-sdk/provider @ai-sdk/openai
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For TanStack AI:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npm install openai-oauth-ai-provider @tanstack/ai @tanstack/ai-openai zod
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For this source checkout:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
npm ci
|
|
63
|
+
npm run check
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Use the adapter-specific entry point for applications that only use one SDK:
|
|
67
|
+
|
|
68
|
+
- `openai-oauth-ai-provider/ai-sdk` exports authentication plus the AI SDK
|
|
69
|
+
provider without loading the TanStack adapter.
|
|
70
|
+
- `openai-oauth-ai-provider/tanstack` exports authentication plus the TanStack
|
|
71
|
+
adapter without loading the AI SDK provider.
|
|
72
|
+
- `openai-oauth-ai-provider/core` exports only authentication, token stores, and
|
|
73
|
+
shared utilities.
|
|
74
|
+
|
|
75
|
+
The root entry point continues to export everything for compatibility and for
|
|
76
|
+
applications that intentionally use both SDKs. Package managers still install
|
|
77
|
+
both official adapter dependencies; the subpaths isolate the runtime module
|
|
78
|
+
graph and give bundlers deterministic entry points.
|
|
79
|
+
|
|
80
|
+
## Device login
|
|
81
|
+
|
|
82
|
+
Authentication is shared by both adapters:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { OpenAIOAuth } from 'openai-oauth-ai-provider/core';
|
|
86
|
+
|
|
87
|
+
const auth = new OpenAIOAuth();
|
|
88
|
+
|
|
89
|
+
await auth.loginWithDeviceCode({
|
|
90
|
+
onVerification({ verificationUrl, userCode }) {
|
|
91
|
+
console.log(`Open ${verificationUrl} and enter ${userCode}`);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Credentials are stored separately from Codex CLI by default. This prevents two
|
|
97
|
+
processes from racing to rotate the same refresh token. Override the location
|
|
98
|
+
with `OPENAI_OAUTH_AUTH_FILE` or provide a custom `TokenStore`. The override
|
|
99
|
+
must be an absolute path; never place the token file inside a source repository
|
|
100
|
+
or synchronized folder.
|
|
101
|
+
|
|
102
|
+
Every request refreshes a token within five minutes of expiry. A `401` causes
|
|
103
|
+
one forced refresh and one retry. Concurrent refreshes in a process are
|
|
104
|
+
deduplicated.
|
|
105
|
+
|
|
106
|
+
Cancel an in-progress login with an `AbortSignal`, and remove persisted
|
|
107
|
+
credentials with `await auth.logout()`. If a refresh token is revoked or the
|
|
108
|
+
workspace changes, log out and complete device login again.
|
|
109
|
+
|
|
110
|
+
Run the included login example:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
npm run example:login
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Codex utilities
|
|
117
|
+
|
|
118
|
+
Use the standalone Codex client for authenticated account and catalog data that
|
|
119
|
+
does not belong to an AI SDK or TanStack AI adapter:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { OpenAIOAuth } from 'openai-oauth-ai-provider/core';
|
|
123
|
+
import { codex } from 'openai-oauth-ai-provider/codex';
|
|
124
|
+
|
|
125
|
+
const auth = new OpenAIOAuth();
|
|
126
|
+
const client = codex({ auth });
|
|
127
|
+
const models = await client.listCodexModels();
|
|
128
|
+
const usage = await client.getCodexUsage();
|
|
129
|
+
const accountStatus = await client.getCodexAccountStatus();
|
|
130
|
+
|
|
131
|
+
console.log(models.map((model) => model.slug));
|
|
132
|
+
console.log(usage, accountStatus);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`listCodexModels()` requests the model catalog available to the signed-in
|
|
136
|
+
account. `getCodexUsage()` returns the plan, quota, and rate-limit payload, and
|
|
137
|
+
`getCodexAccountStatus()` returns account eligibility data. Usage and account
|
|
138
|
+
payloads are deliberately typed as JSON objects because the private backend
|
|
139
|
+
schema changes independently of this package. All three operations use the same
|
|
140
|
+
credential refresh, workspace routing, and one-`401` retry behavior as model
|
|
141
|
+
requests.
|
|
142
|
+
|
|
143
|
+
## Vercel AI SDK 7
|
|
144
|
+
|
|
145
|
+
### Generate and stream text
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { generateText, streamText } from 'ai';
|
|
149
|
+
import { createOpenAIOAuthProvider } from 'openai-oauth-ai-provider/ai-sdk';
|
|
150
|
+
|
|
151
|
+
const openaiOAuth = createOpenAIOAuthProvider();
|
|
152
|
+
const model = openaiOAuth('gpt-5.4');
|
|
153
|
+
|
|
154
|
+
const generated = await generateText({
|
|
155
|
+
model,
|
|
156
|
+
prompt: 'Say hello in five words.',
|
|
157
|
+
});
|
|
158
|
+
console.log(generated.text);
|
|
159
|
+
|
|
160
|
+
const streamed = streamText({ model, prompt: 'Count to five.' });
|
|
161
|
+
for await (const text of streamed.textStream) {
|
|
162
|
+
process.stdout.write(text);
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The Codex Responses endpoint requires `stream: true`. The provider implements
|
|
167
|
+
AI SDK `doGenerate` by collecting the streaming transport into a normal
|
|
168
|
+
generation result, so both `generateText` and `streamText` work normally.
|
|
169
|
+
|
|
170
|
+
Run the example:
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
npm run example:generate
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### AI SDK function tools
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { generateText, isStepCount, jsonSchema, tool } from 'ai';
|
|
180
|
+
|
|
181
|
+
const result = await generateText({
|
|
182
|
+
model: openaiOAuth('gpt-5.4'),
|
|
183
|
+
prompt: 'Use add to calculate 19 + 23.',
|
|
184
|
+
stopWhen: isStepCount(3),
|
|
185
|
+
tools: {
|
|
186
|
+
add: tool({
|
|
187
|
+
inputSchema: jsonSchema<{ a: number; b: number }>({
|
|
188
|
+
type: 'object',
|
|
189
|
+
properties: { a: { type: 'number' }, b: { type: 'number' } },
|
|
190
|
+
required: ['a', 'b'],
|
|
191
|
+
additionalProperties: false,
|
|
192
|
+
}),
|
|
193
|
+
execute: async ({ a, b }) => ({ result: a + b }),
|
|
194
|
+
}),
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Run the tool-loop example:
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
npm run example:tools
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Provider-executed MCP and skills
|
|
206
|
+
|
|
207
|
+
The AI SDK provider exposes the OpenAI Responses tools and Provider V4 files
|
|
208
|
+
and skills surfaces:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
const result = await generateText({
|
|
212
|
+
model: openaiOAuth('gpt-5.4'),
|
|
213
|
+
prompt: 'Describe one capability exposed by the MCP server.',
|
|
214
|
+
tools: {
|
|
215
|
+
docs: openaiOAuth.tools.mcp({
|
|
216
|
+
serverLabel: 'docs',
|
|
217
|
+
serverUrl: 'https://example.com/mcp',
|
|
218
|
+
requireApproval: 'never',
|
|
219
|
+
}),
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const uploaded = await openaiOAuth.skills().uploadSkill({
|
|
224
|
+
files: [
|
|
225
|
+
{
|
|
226
|
+
path: 'SKILL.md',
|
|
227
|
+
data: new TextEncoder().encode('# Example skill'),
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Only disable MCP approval for a server you fully trust. Remote MCP tools can
|
|
234
|
+
receive conversation or tool data and can perform actions outside this
|
|
235
|
+
library's control.
|
|
236
|
+
|
|
237
|
+
## TanStack AI
|
|
238
|
+
|
|
239
|
+
### Streaming chat
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import { chat } from '@tanstack/ai';
|
|
243
|
+
import { openaiOAuthText } from 'openai-oauth-ai-provider/tanstack';
|
|
244
|
+
|
|
245
|
+
const adapter = openaiOAuthText('gpt-5.4');
|
|
246
|
+
|
|
247
|
+
const stream = chat({
|
|
248
|
+
adapter,
|
|
249
|
+
messages: [{ role: 'user', content: 'Say hello in five words.' }],
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
for await (const chunk of stream) {
|
|
253
|
+
if (chunk.type === 'TEXT_MESSAGE_CONTENT') {
|
|
254
|
+
process.stdout.write(chunk.delta);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Run the TanStack example:
|
|
260
|
+
|
|
261
|
+
```sh
|
|
262
|
+
npm run example:tanstack
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The adapter uses TanStack's official OpenAI Responses implementation for AG-UI
|
|
266
|
+
lifecycle events, reasoning, tool calls, multimodal messages, and structured
|
|
267
|
+
outputs. It injects rotating OAuth credentials and enforces Codex defaults:
|
|
268
|
+
|
|
269
|
+
- `stream: true`
|
|
270
|
+
- `store: false`
|
|
271
|
+
- `parallel_tool_calls: true` unless overridden
|
|
272
|
+
- `reasoning.encrypted_content` inclusion for stateless tool loops
|
|
273
|
+
|
|
274
|
+
### TanStack server tools
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
import { chat, toolDefinition } from '@tanstack/ai';
|
|
278
|
+
import { z } from 'zod';
|
|
279
|
+
import { openaiOAuthText } from 'openai-oauth-ai-provider/tanstack';
|
|
280
|
+
|
|
281
|
+
const add = toolDefinition({
|
|
282
|
+
name: 'add',
|
|
283
|
+
description: 'Add two numbers.',
|
|
284
|
+
inputSchema: z.object({ a: z.number(), b: z.number() }),
|
|
285
|
+
outputSchema: z.object({ result: z.number() }),
|
|
286
|
+
}).server(async ({ a, b }) => ({ result: a + b }));
|
|
287
|
+
|
|
288
|
+
const stream = chat({
|
|
289
|
+
adapter: openaiOAuthText('gpt-5.4'),
|
|
290
|
+
messages: [{ role: 'user', content: 'Use add to calculate 19 + 23.' }],
|
|
291
|
+
tools: [add],
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### TanStack structured output
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
import { chat } from '@tanstack/ai';
|
|
299
|
+
import { z } from 'zod';
|
|
300
|
+
|
|
301
|
+
const person = await chat({
|
|
302
|
+
adapter: openaiOAuthText('gpt-5.4'),
|
|
303
|
+
messages: [{ role: 'user', content: 'Ada Lovelace was 36.' }],
|
|
304
|
+
outputSchema: z.object({
|
|
305
|
+
name: z.string(),
|
|
306
|
+
age: z.number(),
|
|
307
|
+
}),
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
The custom adapter collects TanStack's streaming structured-output completion
|
|
312
|
+
when a non-streaming result is requested, because the Codex endpoint rejects
|
|
313
|
+
`stream: false`.
|
|
314
|
+
|
|
315
|
+
## Sharing one authenticated session
|
|
316
|
+
|
|
317
|
+
Applications using both SDKs can share one token manager:
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
import {
|
|
321
|
+
OpenAIOAuth,
|
|
322
|
+
codex,
|
|
323
|
+
createOpenAIOAuthProvider,
|
|
324
|
+
openaiOAuthText,
|
|
325
|
+
} from 'openai-oauth-ai-provider';
|
|
326
|
+
|
|
327
|
+
const auth = new OpenAIOAuth();
|
|
328
|
+
|
|
329
|
+
const codexClient = codex({ auth });
|
|
330
|
+
const aiSdkProvider = createOpenAIOAuthProvider({ auth });
|
|
331
|
+
const tanstackAdapter = openaiOAuthText('gpt-5.4', { auth });
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Upstream references
|
|
335
|
+
|
|
336
|
+
The implementation follows:
|
|
337
|
+
|
|
338
|
+
- [`openai/codex` device authentication](https://github.com/openai/codex/blob/main/codex-rs/login/src/device_code_auth.rs)
|
|
339
|
+
- [`openai/codex` token refresh](https://github.com/openai/codex/blob/main/codex-rs/login/src/auth/manager.rs)
|
|
340
|
+
- [`openai/codex` ChatGPT Codex base URL](https://github.com/openai/codex/blob/main/codex-rs/model-provider-info/src/lib.rs)
|
|
341
|
+
- [`vercel/ai` Provider V4](https://github.com/vercel/ai/blob/main/packages/provider/src/provider/v4/provider-v4.ts)
|
|
342
|
+
- [`TanStack/ai` text adapter contract](https://github.com/TanStack/ai/blob/main/packages/ai/src/activities/chat/adapter.ts)
|
|
343
|
+
- [`TanStack/ai` OpenAI Responses adapter](https://github.com/TanStack/ai/blob/main/packages/openai-base/src/adapters/responses-text.ts)
|
|
344
|
+
|
|
345
|
+
## Security notes
|
|
346
|
+
|
|
347
|
+
- Treat the token file like a password. The file store requests user-only
|
|
348
|
+
permissions where supported by the operating system. Windows users must also
|
|
349
|
+
rely on the ACLs protecting their profile directory.
|
|
350
|
+
- OAuth JWTs are decoded only for routing and expiry claims. Decoding is not
|
|
351
|
+
signature verification and is not used to authorize arbitrary issuers.
|
|
352
|
+
- Refresh tokens are never included in model requests.
|
|
353
|
+
- Caller-supplied authorization, ChatGPT account, and FedRAMP routing headers
|
|
354
|
+
are overwritten from the active authenticated session.
|
|
355
|
+
- Authenticated requests are restricted to their configured HTTPS origin and
|
|
356
|
+
reject redirects to avoid forwarding credentials to another service.
|
|
357
|
+
|
|
358
|
+
Report suspected vulnerabilities privately as described in
|
|
359
|
+
[`SECURITY.md`](SECURITY.md). Never include a live token or token file in an
|
|
360
|
+
issue, log, or security report.
|
|
361
|
+
|
|
362
|
+
## Releases and compatibility
|
|
363
|
+
|
|
364
|
+
This project follows Semantic Versioning for its public TypeScript API. The
|
|
365
|
+
private backend can still change without notice; compatibility fixes that
|
|
366
|
+
restore intended behavior may be released as patches. Releases are built from
|
|
367
|
+
protected `v<version>` tags, tested as packed consumer artifacts, and published
|
|
368
|
+
with npm provenance. See [`CHANGELOG.md`](CHANGELOG.md) for user-visible
|
|
369
|
+
changes.
|
|
370
|
+
|
|
371
|
+
## Contributing and support
|
|
372
|
+
|
|
373
|
+
See [`CONTRIBUTING.md`](CONTRIBUTING.md) before opening a pull request and
|
|
374
|
+
[`SUPPORT.md`](SUPPORT.md) for the supported scope. Participation is governed
|
|
375
|
+
by [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md).
|
package/dist/ai-sdk.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.d.ts","sourceRoot":"","sources":["../src/ai-sdk.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC"}
|
package/dist/ai-sdk.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../src/ai-sdk.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EACL,yBAAyB,GAI1B,MAAM,eAAe,CAAC"}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type OpenAIOAuthTokens, type TokenStore } from './store.js';
|
|
2
|
+
export interface DeviceAuthorization {
|
|
3
|
+
readonly expiresAt: number;
|
|
4
|
+
readonly userCode: string;
|
|
5
|
+
readonly verificationUrl: string;
|
|
6
|
+
}
|
|
7
|
+
export interface OpenAIOAuthOptions {
|
|
8
|
+
readonly clientId?: string;
|
|
9
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
10
|
+
readonly issuer?: string;
|
|
11
|
+
readonly now?: () => number;
|
|
12
|
+
readonly requestTimeoutMs?: number;
|
|
13
|
+
readonly tokenStore?: TokenStore;
|
|
14
|
+
}
|
|
15
|
+
export interface DeviceLoginOptions {
|
|
16
|
+
readonly onVerification?: (authorization: DeviceAuthorization) => void | Promise<void>;
|
|
17
|
+
readonly signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
export declare class OpenAIOAuth {
|
|
20
|
+
readonly clientId: string;
|
|
21
|
+
readonly issuer: string;
|
|
22
|
+
readonly tokenStore: TokenStore;
|
|
23
|
+
private readonly fetchImplementation;
|
|
24
|
+
private readonly now;
|
|
25
|
+
private readonly pendingAuthorizations;
|
|
26
|
+
private readonly requestTimeoutMs;
|
|
27
|
+
private cachedTokens;
|
|
28
|
+
private loaded;
|
|
29
|
+
private mutationQueue;
|
|
30
|
+
private refreshPromise;
|
|
31
|
+
private stateGeneration;
|
|
32
|
+
constructor(options?: OpenAIOAuthOptions);
|
|
33
|
+
startDeviceAuthorization(options?: {
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}): Promise<DeviceAuthorization>;
|
|
36
|
+
completeDeviceAuthorization(authorization: DeviceAuthorization, options?: {
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
}): Promise<OpenAIOAuthTokens>;
|
|
39
|
+
loginWithDeviceCode(options?: DeviceLoginOptions): Promise<OpenAIOAuthTokens>;
|
|
40
|
+
isAuthenticated(): Promise<boolean>;
|
|
41
|
+
getTokens(): Promise<OpenAIOAuthTokens>;
|
|
42
|
+
refresh(): Promise<OpenAIOAuthTokens>;
|
|
43
|
+
logout(): Promise<void>;
|
|
44
|
+
private requestDeviceAuthorization;
|
|
45
|
+
private pollForAuthorizationCode;
|
|
46
|
+
private persistOAuthResponse;
|
|
47
|
+
private shouldRefresh;
|
|
48
|
+
private performRefresh;
|
|
49
|
+
private performRefreshUnlocked;
|
|
50
|
+
private loadTokens;
|
|
51
|
+
private commitTokens;
|
|
52
|
+
private queueMutation;
|
|
53
|
+
private fetchWithTimeout;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAmCD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,CACxB,aAAa,EAAE,mBAAmB,KAC/B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AA2HD,qBAAa,WAAW;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0B;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAGlC;IACJ,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,eAAe,CAAK;IAE5B,YAAY,OAAO,GAAE,kBAAuB,EAe3C;IAEK,wBAAwB,CAC5B,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrC,OAAO,CAAC,mBAAmB,CAAC,CAE9B;IAEK,2BAA2B,CAC/B,aAAa,EAAE,mBAAmB,EAClC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrC,OAAO,CAAC,iBAAiB,CAAC,CAoC5B;IAEK,mBAAmB,CACvB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAQ5B;IAEK,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAExC;IAEK,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAqB5C;IAEK,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAQ1C;IAEK,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAS5B;YAEa,0BAA0B;YAyC1B,wBAAwB;YAoDxB,oBAAoB;IAyBlC,OAAO,CAAC,aAAa;YAQP,cAAc;YAWd,sBAAsB;YAwEtB,UAAU;YAQV,YAAY;YAiBZ,aAAa;YASb,gBAAgB;CAiC/B"}
|