@ottocode/sdk 0.1.192 → 0.1.193
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/package.json
CHANGED
|
@@ -79,6 +79,7 @@ export async function authorizeOpenAI(): Promise<OpenAIOAuthResult> {
|
|
|
79
79
|
id_token_add_organizations: 'true',
|
|
80
80
|
codex_cli_simplified_flow: 'true',
|
|
81
81
|
state: state,
|
|
82
|
+
originator: 'codex_cli_rs',
|
|
82
83
|
});
|
|
83
84
|
|
|
84
85
|
const authUrl = `${OPENAI_ISSUER}/oauth/authorize?${params.toString()}`;
|
|
@@ -253,14 +254,13 @@ export async function refreshOpenAIToken(refreshToken: string) {
|
|
|
253
254
|
const response = await fetch(`${OPENAI_ISSUER}/oauth/token`, {
|
|
254
255
|
method: 'POST',
|
|
255
256
|
headers: {
|
|
256
|
-
'Content-Type': 'application/
|
|
257
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
257
258
|
},
|
|
258
|
-
body:
|
|
259
|
-
client_id: OPENAI_CLIENT_ID,
|
|
259
|
+
body: new URLSearchParams({
|
|
260
260
|
grant_type: 'refresh_token',
|
|
261
261
|
refresh_token: refreshToken,
|
|
262
|
-
|
|
263
|
-
}),
|
|
262
|
+
client_id: OPENAI_CLIENT_ID,
|
|
263
|
+
}).toString(),
|
|
264
264
|
});
|
|
265
265
|
|
|
266
266
|
if (!response.ok) {
|
|
@@ -336,6 +336,7 @@ export function authorizeOpenAIWeb(redirectUri: string): {
|
|
|
336
336
|
id_token_add_organizations: 'true',
|
|
337
337
|
codex_cli_simplified_flow: 'true',
|
|
338
338
|
state: state,
|
|
339
|
+
originator: 'codex_cli_rs',
|
|
339
340
|
});
|
|
340
341
|
|
|
341
342
|
return {
|
|
@@ -422,3 +422,14 @@ To create a new plan, call `update_todos` with a short list of 1‑sentence step
|
|
|
422
422
|
When steps have been completed, use `update_todos` to mark each finished step as `completed` and the next step you are working on as `in_progress`. There should always be exactly one `in_progress` step until everything is done. You can mark multiple items as complete in a single `update_todos` call.
|
|
423
423
|
|
|
424
424
|
If all steps are complete, ensure you call `update_todos` to mark all steps as `completed`.
|
|
425
|
+
|
|
426
|
+
## `finish` — MANDATORY
|
|
427
|
+
|
|
428
|
+
A tool named `finish` is available to you. You MUST call it as your very last action when you are completely done with the user's request. No exceptions.
|
|
429
|
+
|
|
430
|
+
The workflow is:
|
|
431
|
+
1. Do all work (tool calls, edits, searches, etc.)
|
|
432
|
+
2. Stream your final summary/response text to the user
|
|
433
|
+
3. Call `finish` tool with `{}` — this is REQUIRED
|
|
434
|
+
|
|
435
|
+
**If you do not call `finish`, the system cannot detect that you are done and will force a continuation turn.** Always call `finish` as your absolute last action.
|
|
@@ -11,6 +11,7 @@ const SETU_ID: ProviderId = 'setu';
|
|
|
11
11
|
|
|
12
12
|
const isAllowedOpenAIModel = (id: string): boolean => {
|
|
13
13
|
if (id === 'codex-mini-latest') return true;
|
|
14
|
+
if (id === 'gpt-5.3' || id.startsWith('gpt-5.3-')) return false;
|
|
14
15
|
if (id.startsWith('gpt-5')) return true;
|
|
15
16
|
if (id.includes('codex')) return true;
|
|
16
17
|
return false;
|
|
@@ -1496,7 +1496,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
1496
1496
|
cacheWrite: 6.25,
|
|
1497
1497
|
},
|
|
1498
1498
|
limit: {
|
|
1499
|
-
context:
|
|
1499
|
+
context: 200000,
|
|
1500
1500
|
output: 128000,
|
|
1501
1501
|
},
|
|
1502
1502
|
},
|
|
@@ -2446,6 +2446,32 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
2446
2446
|
output: 32000,
|
|
2447
2447
|
},
|
|
2448
2448
|
},
|
|
2449
|
+
{
|
|
2450
|
+
id: 'anthropic/claude-opus-4.6',
|
|
2451
|
+
label: 'Claude Opus 4.6',
|
|
2452
|
+
modalities: {
|
|
2453
|
+
input: ['text', 'image', 'pdf'],
|
|
2454
|
+
output: ['text'],
|
|
2455
|
+
},
|
|
2456
|
+
toolCall: true,
|
|
2457
|
+
reasoningText: true,
|
|
2458
|
+
attachment: true,
|
|
2459
|
+
temperature: true,
|
|
2460
|
+
knowledge: '2025-05-30',
|
|
2461
|
+
releaseDate: '2026-02-05',
|
|
2462
|
+
lastUpdated: '2026-02-05',
|
|
2463
|
+
openWeights: false,
|
|
2464
|
+
cost: {
|
|
2465
|
+
input: 5,
|
|
2466
|
+
output: 25,
|
|
2467
|
+
cacheRead: 0.5,
|
|
2468
|
+
cacheWrite: 6.25,
|
|
2469
|
+
},
|
|
2470
|
+
limit: {
|
|
2471
|
+
context: 1000000,
|
|
2472
|
+
output: 128000,
|
|
2473
|
+
},
|
|
2474
|
+
},
|
|
2449
2475
|
{
|
|
2450
2476
|
id: 'anthropic/claude-sonnet-4',
|
|
2451
2477
|
label: 'Claude Sonnet 4',
|
|
@@ -5203,6 +5229,29 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
5203
5229
|
output: 100000,
|
|
5204
5230
|
},
|
|
5205
5231
|
},
|
|
5232
|
+
{
|
|
5233
|
+
id: 'openrouter/pony-alpha',
|
|
5234
|
+
label: 'Pony Alpha',
|
|
5235
|
+
modalities: {
|
|
5236
|
+
input: ['text'],
|
|
5237
|
+
output: ['text'],
|
|
5238
|
+
},
|
|
5239
|
+
toolCall: true,
|
|
5240
|
+
reasoningText: true,
|
|
5241
|
+
attachment: false,
|
|
5242
|
+
temperature: true,
|
|
5243
|
+
releaseDate: '2026-02-06',
|
|
5244
|
+
lastUpdated: '2026-02-06',
|
|
5245
|
+
openWeights: false,
|
|
5246
|
+
cost: {
|
|
5247
|
+
input: 0,
|
|
5248
|
+
output: 0,
|
|
5249
|
+
},
|
|
5250
|
+
limit: {
|
|
5251
|
+
context: 200000,
|
|
5252
|
+
output: 131000,
|
|
5253
|
+
},
|
|
5254
|
+
},
|
|
5206
5255
|
{
|
|
5207
5256
|
id: 'openrouter/sherlock-dash-alpha',
|
|
5208
5257
|
label: 'Sherlock Dash Alpha',
|
|
@@ -6273,6 +6322,31 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
6273
6322
|
output: 10000,
|
|
6274
6323
|
},
|
|
6275
6324
|
},
|
|
6325
|
+
{
|
|
6326
|
+
id: 'xiaomi/mimo-v2-flash',
|
|
6327
|
+
label: 'MiMo-V2-Flash',
|
|
6328
|
+
modalities: {
|
|
6329
|
+
input: ['text'],
|
|
6330
|
+
output: ['text'],
|
|
6331
|
+
},
|
|
6332
|
+
toolCall: true,
|
|
6333
|
+
reasoningText: true,
|
|
6334
|
+
attachment: false,
|
|
6335
|
+
temperature: true,
|
|
6336
|
+
knowledge: '2024-12',
|
|
6337
|
+
releaseDate: '2025-12-14',
|
|
6338
|
+
lastUpdated: '2025-12-14',
|
|
6339
|
+
openWeights: true,
|
|
6340
|
+
cost: {
|
|
6341
|
+
input: 0.1,
|
|
6342
|
+
output: 0.3,
|
|
6343
|
+
cacheRead: 0.01,
|
|
6344
|
+
},
|
|
6345
|
+
limit: {
|
|
6346
|
+
context: 262144,
|
|
6347
|
+
output: 65536,
|
|
6348
|
+
},
|
|
6349
|
+
},
|
|
6276
6350
|
{
|
|
6277
6351
|
id: 'z-ai/glm-4.5',
|
|
6278
6352
|
label: 'GLM 4.5',
|
|
@@ -2,8 +2,10 @@ import { createOpenAI } from '@ai-sdk/openai';
|
|
|
2
2
|
import type { OAuth } from '../../types/src/index.ts';
|
|
3
3
|
import { refreshOpenAIToken } from '../../auth/src/openai-oauth.ts';
|
|
4
4
|
import { setAuth, getAuth } from '../../auth/src/index.ts';
|
|
5
|
+
import os from 'node:os';
|
|
5
6
|
|
|
6
7
|
const CODEX_BASE_URL = 'https://chatgpt.com/backend-api/codex';
|
|
8
|
+
const CODEX_RESPONSES_URL = 'https://chatgpt.com/backend-api/codex/responses';
|
|
7
9
|
|
|
8
10
|
export type OpenAIOAuthConfig = {
|
|
9
11
|
oauth: OAuth;
|
|
@@ -56,7 +58,7 @@ function rewriteUrl(url: string): string {
|
|
|
56
58
|
parsed.pathname.includes('/v1/responses') ||
|
|
57
59
|
parsed.pathname.includes('/chat/completions')
|
|
58
60
|
) {
|
|
59
|
-
return
|
|
61
|
+
return CODEX_RESPONSES_URL;
|
|
60
62
|
}
|
|
61
63
|
return url;
|
|
62
64
|
}
|
|
@@ -70,7 +72,14 @@ function buildHeaders(
|
|
|
70
72
|
headers.delete('Authorization');
|
|
71
73
|
headers.delete('authorization');
|
|
72
74
|
headers.set('authorization', `Bearer ${accessToken}`);
|
|
73
|
-
headers.set('originator', '
|
|
75
|
+
headers.set('originator', 'codex_cli_rs');
|
|
76
|
+
headers.set('version', '0.98.0');
|
|
77
|
+
headers.set('x-oai-web-search-eligible', 'true');
|
|
78
|
+
headers.set('accept', 'text/event-stream');
|
|
79
|
+
headers.set(
|
|
80
|
+
'User-Agent',
|
|
81
|
+
`codex_cli_rs/0.98.0 (${os.platform()} ${os.release()}; ${os.arch()})`,
|
|
82
|
+
);
|
|
74
83
|
if (accountId) {
|
|
75
84
|
headers.set('ChatGPT-Account-Id', accountId);
|
|
76
85
|
}
|
|
@@ -96,6 +105,7 @@ export function createOpenAIOAuthFetch(config: OpenAIOAuthConfig) {
|
|
|
96
105
|
const targetUrl = rewriteUrl(originalUrl);
|
|
97
106
|
|
|
98
107
|
const headers = buildHeaders(init, validated.access, validated.accountId);
|
|
108
|
+
headers.set('accept-encoding', 'identity');
|
|
99
109
|
|
|
100
110
|
const response = await fetch(targetUrl, {
|
|
101
111
|
...init,
|
|
@@ -103,6 +113,7 @@ export function createOpenAIOAuthFetch(config: OpenAIOAuthConfig) {
|
|
|
103
113
|
// biome-ignore lint/suspicious/noTsIgnore: Bun-specific fetch option
|
|
104
114
|
// @ts-ignore
|
|
105
115
|
timeout: false,
|
|
116
|
+
decompress: false,
|
|
106
117
|
});
|
|
107
118
|
|
|
108
119
|
if (response.status === 401) {
|
|
@@ -125,6 +136,7 @@ export function createOpenAIOAuthFetch(config: OpenAIOAuthConfig) {
|
|
|
125
136
|
currentOAuth.access,
|
|
126
137
|
currentOAuth.accountId,
|
|
127
138
|
);
|
|
139
|
+
retryHeaders.set('accept-encoding', 'identity');
|
|
128
140
|
|
|
129
141
|
return fetch(targetUrl, {
|
|
130
142
|
...init,
|
|
@@ -132,6 +144,7 @@ export function createOpenAIOAuthFetch(config: OpenAIOAuthConfig) {
|
|
|
132
144
|
// biome-ignore lint/suspicious/noTsIgnore: Bun-specific fetch option
|
|
133
145
|
// @ts-ignore
|
|
134
146
|
timeout: false,
|
|
147
|
+
decompress: false,
|
|
135
148
|
});
|
|
136
149
|
} catch {
|
|
137
150
|
console.error(
|