@pure01fx/dsh-openai-codex-auth 0.8.0 → 0.10.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/CHANGELOG.md +18 -0
- package/CODEX-COMPATIBILITY.md +93 -0
- package/README.md +60 -1
- package/client.js +95 -12
- package/lib/catalog.d.ts +6 -0
- package/lib/catalog.js +24 -0
- package/lib/cloud-context.d.ts +20 -0
- package/lib/cloud-context.js +89 -0
- package/lib/cloud-http.d.ts +28 -0
- package/lib/cloud-http.js +170 -0
- package/lib/cloud-images.d.ts +51 -0
- package/lib/cloud-images.js +122 -0
- package/lib/cloud-media.d.ts +52 -0
- package/lib/cloud-media.js +112 -0
- package/lib/cloud-search.d.ts +31 -0
- package/lib/cloud-search.js +172 -0
- package/lib/cloud-tools.d.ts +25 -0
- package/lib/cloud-tools.js +129 -0
- package/lib/cloud-vision.d.ts +34 -0
- package/lib/cloud-vision.js +108 -0
- package/lib/cloud-web-tool.d.ts +12 -0
- package/lib/cloud-web-tool.js +241 -0
- package/lib/index.d.ts +21 -1
- package/lib/index.js +601 -149
- package/lib/native-adapter.d.ts +5 -0
- package/lib/native-adapter.js +22 -10
- package/lib/native-http.d.ts +2 -0
- package/lib/native-http.js +3 -0
- package/lib/native-websocket.js +11 -5
- package/lib/replay.d.ts +1 -0
- package/lib/replay.js +8 -2
- package/lib/response-usage.d.ts +4 -2
- package/lib/response-usage.js +26 -6
- package/lib/responses.d.ts +10 -1
- package/lib/responses.js +86 -10
- package/lib/upstream.d.ts +6 -4
- package/lib/upstream.js +6 -4
- package/lib/usage.d.ts +1 -0
- package/lib/usage.js +10 -3
- package/package.json +62 -9
package/lib/native-adapter.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ export declare function nativeCodexWireReasoningEffort(effort: string | undefine
|
|
|
18
18
|
/** Request-scoped native Codex transport owned by this package. */
|
|
19
19
|
export interface NativeCodexTransportMode {
|
|
20
20
|
serviceTier?: typeof CODEX_FAST_SERVICE_TIER;
|
|
21
|
+
/** Enables the model-specific Responses Lite request and routing contract. */
|
|
22
|
+
responsesLite?: {
|
|
23
|
+
defaultVerbosity?: string;
|
|
24
|
+
instructionsTemplate?: string;
|
|
25
|
+
};
|
|
21
26
|
publicModel?: string;
|
|
22
27
|
authorityHash?: string;
|
|
23
28
|
/** Turn-scoped sticky routing state captured from a provider response. */
|
package/lib/native-adapter.js
CHANGED
|
@@ -53,6 +53,20 @@ function supportsFast(model) {
|
|
|
53
53
|
return model.serviceTiers.some(tier => tier.id === CODEX_FAST_SERVICE_TIER)
|
|
54
54
|
|| model.additionalSpeedTiers.includes('fast');
|
|
55
55
|
}
|
|
56
|
+
function responsesLiteMode(model, requestedModel = model?.slug) {
|
|
57
|
+
if (model !== undefined && !model.useResponsesLite)
|
|
58
|
+
return {};
|
|
59
|
+
// Never downgrade the tracked Lite-only Astra slug to Standard Responses during catalog outages.
|
|
60
|
+
if (model === undefined && requestedModel !== 'gpt-6-astra')
|
|
61
|
+
return {};
|
|
62
|
+
return {
|
|
63
|
+
responsesLite: {
|
|
64
|
+
defaultVerbosity: model?.defaultVerbosity ?? 'low',
|
|
65
|
+
...model?.instructionsTemplate === undefined ? {}
|
|
66
|
+
: { instructionsTemplate: model.instructionsTemplate },
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
56
70
|
function fastRoutes(models) {
|
|
57
71
|
const exact = new Set(models.map(model => model.slug));
|
|
58
72
|
const routes = new Map();
|
|
@@ -81,9 +95,10 @@ export function nativeCodexWireReasoningEffort(effort, model) {
|
|
|
81
95
|
return [...supported].reverse().find(level => level.effort !== 'ultra')?.effort ?? 'medium';
|
|
82
96
|
}
|
|
83
97
|
function withWireReasoning(options, model) {
|
|
84
|
-
const
|
|
98
|
+
const explicit = options.reasoningEffort === undefined ? undefined : String(options.reasoningEffort);
|
|
99
|
+
const selected = explicit ?? (model?.useResponsesLite ? model.defaultReasoningLevel : undefined);
|
|
85
100
|
const wire = nativeCodexWireReasoningEffort(selected, model);
|
|
86
|
-
return wire === undefined || wire ===
|
|
101
|
+
return wire === undefined || wire === explicit
|
|
87
102
|
? options
|
|
88
103
|
: { ...options, reasoningEffort: ReasoningEffortId(wire) };
|
|
89
104
|
}
|
|
@@ -217,7 +232,7 @@ export class NativeCodexAdapter extends LlmAdapter {
|
|
|
217
232
|
this.assertNotAborted(options.signal);
|
|
218
233
|
const exact = view.models.find(candidate => candidate.slug === options.model);
|
|
219
234
|
if (exact !== undefined) {
|
|
220
|
-
yield* this.transport.stream(withWireReasoning(options, exact));
|
|
235
|
+
yield* this.transport.stream(withWireReasoning(options, exact), responsesLiteMode(exact));
|
|
221
236
|
return;
|
|
222
237
|
}
|
|
223
238
|
const fast = fastRoutes(view.models).get(options.model);
|
|
@@ -231,16 +246,13 @@ export class NativeCodexAdapter extends LlmAdapter {
|
|
|
231
246
|
serviceTier: CODEX_FAST_SERVICE_TIER,
|
|
232
247
|
publicModel: options.model,
|
|
233
248
|
authorityHash: view.authorityHash,
|
|
249
|
+
...responsesLiteMode(fast),
|
|
234
250
|
});
|
|
235
251
|
return;
|
|
236
252
|
}
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
const model = selectedEffort === 'ultra'
|
|
240
|
-
? (await this.catalog?.list(options.signal) ?? [])
|
|
241
|
-
.find(candidate => candidate.slug === options.model)
|
|
242
|
-
: undefined;
|
|
253
|
+
const model = (await this.catalog?.list(options.signal) ?? [])
|
|
254
|
+
.find(candidate => candidate.slug === options.model);
|
|
243
255
|
this.assertNotAborted(options.signal);
|
|
244
|
-
yield* this.transport.stream(withWireReasoning(options, model));
|
|
256
|
+
yield* this.transport.stream(withWireReasoning(options, model), responsesLiteMode(model, options.model));
|
|
245
257
|
}
|
|
246
258
|
}
|
package/lib/native-http.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ type ImageBlock = Extract<ContentBlock, {
|
|
|
9
9
|
}>;
|
|
10
10
|
export interface NativeCodexImageRead {
|
|
11
11
|
data: Uint8Array;
|
|
12
|
+
/** Internal per-image control used by the explicit vision tool. */
|
|
13
|
+
detail?: import('./responses.js').CodexImageDetail;
|
|
12
14
|
}
|
|
13
15
|
export interface NativeCodexHttpOptions {
|
|
14
16
|
resolveCredential(signal?: AbortSignal): Promise<NativeCodexCredential>;
|
package/lib/native-http.js
CHANGED
|
@@ -119,6 +119,7 @@ async function resolveImage(block, options, signal) {
|
|
|
119
119
|
type: 'image',
|
|
120
120
|
mediaType: block.attachment.mediaType,
|
|
121
121
|
dataBase64: Buffer.from(stored.data).toString('base64'),
|
|
122
|
+
...stored.detail === undefined ? {} : { detail: stored.detail },
|
|
122
123
|
};
|
|
123
124
|
}
|
|
124
125
|
async function resolveToolResult(block, options, signal) {
|
|
@@ -470,6 +471,8 @@ export class NativeCodexHttpTransport {
|
|
|
470
471
|
'x-codex-routing-hint': routingHint,
|
|
471
472
|
...(activeTurnState === undefined ? {} : { 'x-codex-turn-state': activeTurnState }),
|
|
472
473
|
...(generation.purpose === 'compaction' ? { 'x-openai-subagent': 'compact' } : {}),
|
|
474
|
+
...(mode.responsesLite === undefined
|
|
475
|
+
? {} : { 'x-openai-internal-codex-responses-lite': 'true' }),
|
|
473
476
|
accept: 'text/event-stream',
|
|
474
477
|
'content-type': 'application/json',
|
|
475
478
|
...attributionHeaders(),
|
package/lib/native-websocket.js
CHANGED
|
@@ -106,8 +106,8 @@ function turnKey(generation) {
|
|
|
106
106
|
return createHash('sha256')
|
|
107
107
|
.update(`${generation.purpose ?? 'ordinary'}:handbuilt`).digest('base64url');
|
|
108
108
|
}
|
|
109
|
-
function
|
|
110
|
-
if (turnState === undefined)
|
|
109
|
+
function withRequestMetadata(request, turnState, responsesLite) {
|
|
110
|
+
if (turnState === undefined && !responsesLite)
|
|
111
111
|
return request;
|
|
112
112
|
const metadata = typeof request.client_metadata === 'object'
|
|
113
113
|
&& request.client_metadata !== null && !Array.isArray(request.client_metadata)
|
|
@@ -115,7 +115,12 @@ function withTurnState(request, turnState) {
|
|
|
115
115
|
: {};
|
|
116
116
|
return {
|
|
117
117
|
...request,
|
|
118
|
-
client_metadata: {
|
|
118
|
+
client_metadata: {
|
|
119
|
+
...metadata,
|
|
120
|
+
...(turnState === undefined ? {} : { 'x-codex-turn-state': turnState }),
|
|
121
|
+
...(responsesLite
|
|
122
|
+
? { ws_request_header_x_openai_internal_codex_responses_lite: 'true' } : {}),
|
|
123
|
+
},
|
|
119
124
|
};
|
|
120
125
|
}
|
|
121
126
|
function normalizedOutputItem(event) {
|
|
@@ -140,6 +145,7 @@ function normalizedOutputItem(event) {
|
|
|
140
145
|
if (item.type === 'function_call') {
|
|
141
146
|
return {
|
|
142
147
|
type: 'function_call', ...(id === undefined ? {} : { id }),
|
|
148
|
+
...(typeof item.namespace === 'string' ? { namespace: item.namespace } : {}),
|
|
143
149
|
call_id: item.call_id, name: item.name, arguments: item.arguments,
|
|
144
150
|
};
|
|
145
151
|
}
|
|
@@ -446,12 +452,12 @@ export class NativeCodexWebSocketTransport {
|
|
|
446
452
|
let justPrewarmed = false;
|
|
447
453
|
if (!entry.prewarmAttempted) {
|
|
448
454
|
entry.prewarmAttempted = true;
|
|
449
|
-
const warm = entry.protocol.prewarm(
|
|
455
|
+
const warm = entry.protocol.prewarm(withRequestMetadata(prepared.request, entry.turnState, prepared.mode.responsesLite !== undefined));
|
|
450
456
|
for await (const _chunk of this.exchange(entry, warm.payload, prepared.generation, prepared.mode, credential.accountId, true, signal)) { /* prewarm is invisible */ }
|
|
451
457
|
entry.prewarmSucceeded = true;
|
|
452
458
|
justPrewarmed = true;
|
|
453
459
|
}
|
|
454
|
-
const plan = entry.protocol.plan(
|
|
460
|
+
const plan = entry.protocol.plan(withRequestMetadata(prepared.request, entry.turnState, prepared.mode.responsesLite !== undefined), justPrewarmed);
|
|
455
461
|
yield* this.exchange(entry, plan.payload, prepared.generation, prepared.mode, credential.accountId, false, signal);
|
|
456
462
|
if (this.options.onCompleted !== undefined) {
|
|
457
463
|
try {
|
package/lib/replay.d.ts
CHANGED
package/lib/replay.js
CHANGED
|
@@ -86,11 +86,16 @@ function parseDescriptor(value) {
|
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
if (row.type === 'function_call') {
|
|
89
|
+
const namespace = row.namespace === undefined ? undefined : boundedString(row.namespace);
|
|
89
90
|
if (!Number.isSafeInteger(row.block) || Number(row.block) < 0
|
|
90
|
-
||
|
|
91
|
+
|| (row.namespace !== undefined && namespace === undefined)
|
|
92
|
+
|| !onlyKeys(row, ['type', 'id', 'namespace', 'block'])) {
|
|
91
93
|
throw failure('native Codex function replay descriptor is invalid');
|
|
92
94
|
}
|
|
93
|
-
return {
|
|
95
|
+
return {
|
|
96
|
+
type: 'function_call', ...(id === undefined ? {} : { id }),
|
|
97
|
+
...(namespace === undefined ? {} : { namespace }), block: Number(row.block),
|
|
98
|
+
};
|
|
94
99
|
}
|
|
95
100
|
throw failure('native Codex replay descriptor type is unsupported');
|
|
96
101
|
}
|
|
@@ -220,6 +225,7 @@ export function replayAssistantInput(content, source) {
|
|
|
220
225
|
const block = blockAt(content, used, item.block, 'tool-call');
|
|
221
226
|
input.push({
|
|
222
227
|
type: 'function_call', ...(item.id === undefined ? {} : { id: item.id }),
|
|
228
|
+
...(item.namespace === undefined ? {} : { namespace: item.namespace }),
|
|
223
229
|
call_id: String(block.id), name: block.name, arguments: block.arguments,
|
|
224
230
|
});
|
|
225
231
|
}
|
package/lib/response-usage.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/** Bounded per-response usage metadata emitted by the Codex Responses API. */
|
|
2
2
|
export interface CodexResponseUsageMetadata {
|
|
3
3
|
/** Exact provider representation; never coerce this high-precision value to a number. */
|
|
4
|
-
amount
|
|
4
|
+
amount?: string;
|
|
5
|
+
/** Complete bounded `response.usage` JSON, including fields unknown to this client. */
|
|
6
|
+
metadata?: unknown;
|
|
5
7
|
}
|
|
6
8
|
export interface CodexResponseUsageObservation {
|
|
7
9
|
accountId: string;
|
|
8
10
|
metadata: CodexResponseUsageMetadata;
|
|
9
11
|
}
|
|
10
12
|
export type CodexResponseUsageCallback = (observation: CodexResponseUsageObservation) => void;
|
|
11
|
-
/**
|
|
13
|
+
/** Preserve exact billing amount and the complete bounded response.usage payload. */
|
|
12
14
|
export declare function parseCodexResponseUsageMetadata(value: unknown): CodexResponseUsageMetadata | undefined;
|
|
13
15
|
/** Publish optional response usage without allowing diagnostics to fail generation. */
|
|
14
16
|
export declare function publishCodexResponseUsage(accountId: string, metadata: CodexResponseUsageMetadata | undefined, callback: CodexResponseUsageCallback | undefined, warn: ((message: string) => void) | undefined): void;
|
package/lib/response-usage.js
CHANGED
|
@@ -1,21 +1,41 @@
|
|
|
1
1
|
/** Bounded per-response usage metadata emitted by the Codex Responses API. */
|
|
2
2
|
const MAX_AMOUNT_BYTES = 256;
|
|
3
|
+
const MAX_RAW_USAGE_BYTES = 64 * 1024;
|
|
3
4
|
function record(value) {
|
|
4
5
|
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
5
6
|
? value : undefined;
|
|
6
7
|
}
|
|
7
|
-
|
|
8
|
+
function boundedJson(value) {
|
|
9
|
+
if (value === undefined || value === null)
|
|
10
|
+
return undefined;
|
|
11
|
+
try {
|
|
12
|
+
const encoded = JSON.stringify(value);
|
|
13
|
+
if (encoded === undefined || Buffer.byteLength(encoded) > MAX_RAW_USAGE_BYTES)
|
|
14
|
+
return undefined;
|
|
15
|
+
return JSON.parse(encoded);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Preserve exact billing amount and the complete bounded response.usage payload. */
|
|
8
22
|
export function parseCodexResponseUsageMetadata(value) {
|
|
9
23
|
const event = record(value);
|
|
10
24
|
if (event?.type !== 'response.completed')
|
|
11
25
|
return undefined;
|
|
12
26
|
const response = record(event.response);
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
const usageMetadata = record(response?.usage_metadata);
|
|
28
|
+
const rawAmount = usageMetadata?.amount;
|
|
29
|
+
const amount = typeof rawAmount === 'string' && rawAmount.length > 0
|
|
30
|
+
&& Buffer.byteLength(rawAmount) <= MAX_AMOUNT_BYTES
|
|
31
|
+
? rawAmount : undefined;
|
|
32
|
+
const metadata = boundedJson(response?.usage);
|
|
33
|
+
if (amount === undefined && metadata === undefined)
|
|
17
34
|
return undefined;
|
|
18
|
-
return {
|
|
35
|
+
return {
|
|
36
|
+
...amount === undefined ? {} : { amount },
|
|
37
|
+
...metadata === undefined ? {} : { metadata },
|
|
38
|
+
};
|
|
19
39
|
}
|
|
20
40
|
/** Publish optional response usage without allowing diagnostics to fail generation. */
|
|
21
41
|
export function publishCodexResponseUsage(accountId, metadata, callback, warn) {
|
package/lib/responses.d.ts
CHANGED
|
@@ -2,10 +2,12 @@ import { CallId, LlmError, type ContentBlock, type GenerateOptions, type StreamC
|
|
|
2
2
|
import { type ParseSseOptions } from './sse.js';
|
|
3
3
|
import { type NativeCodexReplaySource } from './replay.js';
|
|
4
4
|
export declare const DEFAULT_CODEX_INSTRUCTIONS = "You are Codex, an AI coding agent. Help the user with software engineering tasks.";
|
|
5
|
+
export type CodexImageDetail = 'auto' | 'low' | 'high' | 'original';
|
|
5
6
|
export interface ResolvedImagePart {
|
|
6
7
|
type: 'image';
|
|
7
8
|
mediaType: string;
|
|
8
9
|
dataBase64: string;
|
|
10
|
+
detail?: CodexImageDetail;
|
|
9
11
|
}
|
|
10
12
|
export interface ResolvedToolResultPart {
|
|
11
13
|
type: 'tool-result';
|
|
@@ -26,14 +28,20 @@ export interface ResponsesRequestInput {
|
|
|
26
28
|
input: Record<string, unknown>[];
|
|
27
29
|
}
|
|
28
30
|
export declare function toResponsesTools(tools: readonly ToolSchema[]): Record<string, unknown>[];
|
|
31
|
+
/** Responses Lite loads ordinary DSH functions through one canonical namespace. */
|
|
32
|
+
export declare function toResponsesLiteTools(tools: readonly ToolSchema[]): Record<string, unknown>[];
|
|
29
33
|
/** Convert resolved DSH messages into Responses instructions and ordered input items. */
|
|
30
34
|
export declare function toResponsesInput(messages: readonly ResolvedMessage[], system?: string): ResponsesRequestInput;
|
|
31
35
|
/** Bound call ids while preserving every function call/result correlation. */
|
|
32
36
|
export declare function normalizeCodexCallIds(input: readonly Record<string, unknown>[]): Record<string, unknown>[];
|
|
33
37
|
export interface ResponsesRequestMode {
|
|
34
38
|
serviceTier?: 'priority';
|
|
39
|
+
responsesLite?: {
|
|
40
|
+
defaultVerbosity?: string;
|
|
41
|
+
instructionsTemplate?: string;
|
|
42
|
+
};
|
|
35
43
|
}
|
|
36
|
-
/** Build the canonical Standard/Fast
|
|
44
|
+
/** Build the canonical Standard/Fast or model-specific Responses Lite body. */
|
|
37
45
|
export declare function codexRequestBody(options: GenerateOptions, messages: readonly ResolvedMessage[], mode?: ResponsesRequestMode): Record<string, unknown>;
|
|
38
46
|
export interface ResponsesUsage {
|
|
39
47
|
input_tokens: number;
|
|
@@ -55,6 +63,7 @@ interface ResponsesOutputItem {
|
|
|
55
63
|
id?: string;
|
|
56
64
|
call_id?: string;
|
|
57
65
|
name?: string;
|
|
66
|
+
namespace?: string;
|
|
58
67
|
arguments?: string;
|
|
59
68
|
encrypted_content?: string;
|
|
60
69
|
summary?: unknown[];
|
package/lib/responses.js
CHANGED
|
@@ -7,12 +7,25 @@ export const DEFAULT_CODEX_INSTRUCTIONS = 'You are Codex, an AI coding agent. He
|
|
|
7
7
|
const CALL_ID_MAX_LENGTH = 64;
|
|
8
8
|
const CALL_ID_PREFIX = 'call_';
|
|
9
9
|
const MAX_RETAINED_RESPONSE_BYTES = 64 * 1024 * 1024;
|
|
10
|
+
const UUID_NAMESPACE_OID = Buffer.from('6ba7b8129dad11d180b400c04fd430c8', 'hex');
|
|
11
|
+
function uuidV5(namespace, name) {
|
|
12
|
+
const bytes = createHash('sha1').update(namespace).update(name).digest().subarray(0, 16);
|
|
13
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x50;
|
|
14
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
15
|
+
const hex = bytes.toString('hex');
|
|
16
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
17
|
+
}
|
|
18
|
+
function uuidBytes(value) { return Buffer.from(value.replaceAll('-', ''), 'hex'); }
|
|
10
19
|
function fixedError(message, code) { return new LlmError(message, code); }
|
|
11
20
|
function imageItem(image) {
|
|
12
21
|
if (!/^image[/][a-z0-9.+-]+$/i.test(image.mediaType) || image.dataBase64.length === 0) {
|
|
13
22
|
throw fixedError('native Codex request contains invalid resolved image data', 'MALFORMED_REQUEST');
|
|
14
23
|
}
|
|
15
|
-
|
|
24
|
+
if (image.detail !== undefined && !['auto', 'low', 'high', 'original'].includes(image.detail)) {
|
|
25
|
+
throw fixedError('native Codex image detail is invalid', 'MALFORMED_REQUEST');
|
|
26
|
+
}
|
|
27
|
+
return { type: 'input_image', image_url: `data:${image.mediaType};base64,${image.dataBase64}`,
|
|
28
|
+
...image.detail === undefined ? {} : { detail: image.detail } };
|
|
16
29
|
}
|
|
17
30
|
function toolOutput(block) {
|
|
18
31
|
const images = block.content.some(part => part.type === 'image');
|
|
@@ -32,6 +45,13 @@ export function toResponsesTools(tools) {
|
|
|
32
45
|
type: 'function', name: tool.name, description: tool.description, parameters: tool.parameters,
|
|
33
46
|
}));
|
|
34
47
|
}
|
|
48
|
+
/** Responses Lite loads ordinary DSH functions through one canonical namespace. */
|
|
49
|
+
export function toResponsesLiteTools(tools) {
|
|
50
|
+
const functions = toResponsesTools(tools);
|
|
51
|
+
return functions.length === 0 ? [] : [{
|
|
52
|
+
type: 'namespace', name: 'functions', description: '', tools: functions,
|
|
53
|
+
}];
|
|
54
|
+
}
|
|
35
55
|
/** Convert resolved DSH messages into Responses instructions and ordered input items. */
|
|
36
56
|
export function toResponsesInput(messages, system) {
|
|
37
57
|
const input = [];
|
|
@@ -144,29 +164,82 @@ function assertSupportedOptions(options) {
|
|
|
144
164
|
throw fixedError('native Codex does not support stop sequences', 'UNSUPPORTED');
|
|
145
165
|
}
|
|
146
166
|
}
|
|
147
|
-
/** Build the canonical Standard/Fast
|
|
167
|
+
/** Build the canonical Standard/Fast or model-specific Responses Lite body. */
|
|
148
168
|
export function codexRequestBody(options, messages, mode = {}) {
|
|
149
169
|
assertSupportedOptions(options);
|
|
150
170
|
if (mode.serviceTier !== undefined && mode.serviceTier !== 'priority') {
|
|
151
171
|
throw fixedError('native Codex service tier is invalid', 'INVALID_ARGS');
|
|
152
172
|
}
|
|
153
173
|
const resolved = toResponsesInput(messages, options.system);
|
|
154
|
-
|
|
174
|
+
const instructions = resolved.instructions ?? DEFAULT_CODEX_INSTRUCTIONS;
|
|
175
|
+
const input = normalizeCodexCallIds(resolved.input);
|
|
176
|
+
if (mode.responsesLite !== undefined) {
|
|
177
|
+
for (const item of input) {
|
|
178
|
+
const parts = item.type === 'function_call_output' ? item.output : item.content;
|
|
179
|
+
if (Array.isArray(parts)) {
|
|
180
|
+
for (const part of parts)
|
|
181
|
+
if (part.type === 'input_image')
|
|
182
|
+
delete part.detail;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const common = {
|
|
155
187
|
model: options.model,
|
|
156
|
-
instructions: resolved.instructions ?? DEFAULT_CODEX_INSTRUCTIONS,
|
|
157
|
-
input: normalizeCodexCallIds(resolved.input),
|
|
158
|
-
...options.tools !== undefined && options.tools.length > 0
|
|
159
|
-
? { tools: toResponsesTools(options.tools) } : {},
|
|
160
188
|
tool_choice: 'auto',
|
|
161
|
-
parallel_tool_calls: true,
|
|
162
|
-
...options.reasoningEffort === undefined ? {}
|
|
163
|
-
: { reasoning: { effort: String(options.reasoningEffort), summary: 'auto' } },
|
|
164
189
|
store: false,
|
|
165
190
|
stream: true,
|
|
166
191
|
include: ['reasoning.encrypted_content'],
|
|
167
192
|
...mode.serviceTier === undefined ? {} : { service_tier: mode.serviceTier },
|
|
168
193
|
...options.sessionId === undefined ? {} : { prompt_cache_key: String(options.sessionId) },
|
|
169
194
|
};
|
|
195
|
+
if (mode.responsesLite === undefined) {
|
|
196
|
+
return {
|
|
197
|
+
...common,
|
|
198
|
+
instructions,
|
|
199
|
+
input,
|
|
200
|
+
...options.tools !== undefined && options.tools.length > 0
|
|
201
|
+
? { tools: toResponsesTools(options.tools) } : {},
|
|
202
|
+
parallel_tool_calls: true,
|
|
203
|
+
...options.reasoningEffort === undefined ? {}
|
|
204
|
+
: { reasoning: { effort: String(options.reasoningEffort), summary: 'auto' } },
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const tools = toResponsesLiteTools(options.tools ?? []);
|
|
208
|
+
const baseInstructions = mode.responsesLite.instructionsTemplate ?? instructions;
|
|
209
|
+
const contextualInstructions = mode.responsesLite.instructionsTemplate !== undefined
|
|
210
|
+
&& resolved.instructions !== undefined && resolved.instructions !== baseInstructions
|
|
211
|
+
? [{
|
|
212
|
+
type: 'message', role: 'developer',
|
|
213
|
+
content: [{ type: 'input_text', text: resolved.instructions }],
|
|
214
|
+
}]
|
|
215
|
+
: [];
|
|
216
|
+
const prefixNamespace = uuidBytes(uuidV5(UUID_NAMESPACE_OID, String(options.sessionId ?? options.model)));
|
|
217
|
+
const prefix = [{
|
|
218
|
+
type: 'additional_tools',
|
|
219
|
+
id: `at_${uuidV5(prefixNamespace, JSON.stringify(tools))}`,
|
|
220
|
+
role: 'developer',
|
|
221
|
+
tools,
|
|
222
|
+
}, {
|
|
223
|
+
type: 'message',
|
|
224
|
+
id: `msg_${uuidV5(prefixNamespace, baseInstructions)}`,
|
|
225
|
+
role: 'developer',
|
|
226
|
+
content: [{ type: 'input_text', text: baseInstructions }],
|
|
227
|
+
internal_chat_message_metadata_passthrough: {
|
|
228
|
+
content_item_kinds: ['model.base_instructions'],
|
|
229
|
+
},
|
|
230
|
+
}];
|
|
231
|
+
return {
|
|
232
|
+
...common,
|
|
233
|
+
input: [...prefix, ...contextualInstructions, ...input],
|
|
234
|
+
parallel_tool_calls: false,
|
|
235
|
+
reasoning: {
|
|
236
|
+
...options.reasoningEffort === undefined ? {} : { effort: String(options.reasoningEffort) },
|
|
237
|
+
summary: 'auto',
|
|
238
|
+
context: 'all_turns',
|
|
239
|
+
},
|
|
240
|
+
...mode.responsesLite.defaultVerbosity === undefined ? {}
|
|
241
|
+
: { text: { verbosity: mode.responsesLite.defaultVerbosity } },
|
|
242
|
+
};
|
|
170
243
|
}
|
|
171
244
|
function tokenCount(value, field, fallback) {
|
|
172
245
|
if (value === undefined && fallback !== undefined)
|
|
@@ -371,6 +444,8 @@ export class ResponsesStreamTranslator {
|
|
|
371
444
|
if (item.type === 'function_call') {
|
|
372
445
|
if (item.call_id === undefined || item.call_id.length === 0
|
|
373
446
|
|| item.name === undefined || item.name.length === 0
|
|
447
|
+
|| (item.namespace !== undefined && (typeof item.namespace !== 'string'
|
|
448
|
+
|| item.namespace.length === 0 || Buffer.byteLength(item.namespace) > 256))
|
|
374
449
|
|| typeof item.arguments !== 'string') {
|
|
375
450
|
throw fixedError('native Codex function call has invalid content', 'MALFORMED_RESPONSE');
|
|
376
451
|
}
|
|
@@ -391,6 +466,7 @@ export class ResponsesStreamTranslator {
|
|
|
391
466
|
if (this.replayContext !== undefined)
|
|
392
467
|
this.replayCapture?.add({
|
|
393
468
|
type: 'function_call', ...(replayId === undefined ? {} : { id: replayId }),
|
|
469
|
+
...(item.namespace === undefined ? {} : { namespace: item.namespace }),
|
|
394
470
|
block: block.index,
|
|
395
471
|
});
|
|
396
472
|
}
|
package/lib/upstream.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** Single source of truth for the OpenAI Codex revision this adapter tracks. */
|
|
2
2
|
export declare const TRACKED_CODEX_REPOSITORY = "https://github.com/openai/codex.git";
|
|
3
|
-
export declare const TRACKED_CODEX_COMMIT = "
|
|
4
|
-
export declare const TRACKED_CODEX_RELEASE = "
|
|
5
|
-
/**
|
|
6
|
-
export declare const
|
|
3
|
+
export declare const TRACKED_CODEX_COMMIT = "ddf04ad26789d040f9ef6a96736f76602e35a6cc";
|
|
4
|
+
export declare const TRACKED_CODEX_RELEASE = "main@ddf04ad";
|
|
5
|
+
/** Independently audited cloud search/image contracts; not local Codex executor parity. */
|
|
6
|
+
export declare const TRACKED_CODEX_CLOUD_COMMIT = "b348fc26674189f758d5941cdab3f78f258b2aa7";
|
|
7
|
+
/** Whole stable release version sent to the Codex model-catalog endpoint. */
|
|
8
|
+
export declare const CODEX_CLIENT_VERSION = "0.153.4";
|
package/lib/upstream.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** Single source of truth for the OpenAI Codex revision this adapter tracks. */
|
|
2
2
|
export const TRACKED_CODEX_REPOSITORY = 'https://github.com/openai/codex.git';
|
|
3
|
-
export const TRACKED_CODEX_COMMIT = '
|
|
4
|
-
export const TRACKED_CODEX_RELEASE = '
|
|
5
|
-
/**
|
|
6
|
-
export const
|
|
3
|
+
export const TRACKED_CODEX_COMMIT = 'ddf04ad26789d040f9ef6a96736f76602e35a6cc';
|
|
4
|
+
export const TRACKED_CODEX_RELEASE = 'main@ddf04ad';
|
|
5
|
+
/** Independently audited cloud search/image contracts; not local Codex executor parity. */
|
|
6
|
+
export const TRACKED_CODEX_CLOUD_COMMIT = 'b348fc26674189f758d5941cdab3f78f258b2aa7';
|
|
7
|
+
/** Whole stable release version sent to the Codex model-catalog endpoint. */
|
|
8
|
+
export const CODEX_CLIENT_VERSION = '0.153.4';
|
package/lib/usage.d.ts
CHANGED
package/lib/usage.js
CHANGED
|
@@ -33,9 +33,11 @@ function usageLimit(id, name, value) {
|
|
|
33
33
|
const row = value;
|
|
34
34
|
const primary = usageWindow(row.primary_window ?? row.primary);
|
|
35
35
|
const secondary = usageWindow(row.secondary_window ?? row.secondary);
|
|
36
|
-
const
|
|
36
|
+
const explicitLimitReached = typeof row.limit_reached === 'boolean'
|
|
37
37
|
? row.limit_reached
|
|
38
38
|
: typeof row.limitReached === 'boolean' ? row.limitReached : undefined;
|
|
39
|
+
const allowed = typeof row.allowed === 'boolean' ? row.allowed : undefined;
|
|
40
|
+
const limitReached = explicitLimitReached ?? (allowed === undefined ? undefined : !allowed);
|
|
39
41
|
if (primary === undefined && secondary === undefined && limitReached === undefined)
|
|
40
42
|
return undefined;
|
|
41
43
|
return {
|
|
@@ -71,8 +73,13 @@ export function normalizeUsage(value) {
|
|
|
71
73
|
if (id === undefined || id === 'codex' || limits.some(limit => limit.id === id))
|
|
72
74
|
continue;
|
|
73
75
|
const extra = usageLimit(id, boundedUsageText(row.limit_name ?? row.limitName), row.rate_limit ?? row.rateLimit);
|
|
74
|
-
if (extra !== undefined)
|
|
75
|
-
|
|
76
|
+
if (extra !== undefined) {
|
|
77
|
+
const normalModelSlug = boundedUsageText(row.normal_model_slug ?? row.normalModelSlug);
|
|
78
|
+
limits.push({
|
|
79
|
+
...extra,
|
|
80
|
+
...normalModelSlug === undefined ? {} : { normalModelSlug },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
const sortedLimits = sortedUsageLimits(limits);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pure01fx/dsh-openai-codex-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Native ChatGPT Codex provider, device-code-first login, and same-origin Web integration for DeepSeek Harness",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -61,19 +61,31 @@
|
|
|
61
61
|
"lib/sse.d.ts",
|
|
62
62
|
"lib/usage.js",
|
|
63
63
|
"lib/usage.d.ts",
|
|
64
|
+
"lib/cloud-http.js",
|
|
65
|
+
"lib/cloud-http.d.ts",
|
|
66
|
+
"lib/cloud-search.js",
|
|
67
|
+
"lib/cloud-search.d.ts",
|
|
68
|
+
"lib/cloud-images.js",
|
|
69
|
+
"lib/cloud-images.d.ts",
|
|
70
|
+
"lib/cloud-media.js",
|
|
71
|
+
"lib/cloud-media.d.ts",
|
|
72
|
+
"lib/cloud-vision.js",
|
|
73
|
+
"lib/cloud-vision.d.ts",
|
|
74
|
+
"lib/cloud-tools.js",
|
|
75
|
+
"lib/cloud-tools.d.ts",
|
|
76
|
+
"lib/cloud-context.js",
|
|
77
|
+
"lib/cloud-context.d.ts",
|
|
78
|
+
"lib/cloud-web-tool.js",
|
|
79
|
+
"lib/cloud-web-tool.d.ts",
|
|
64
80
|
"client.js",
|
|
65
81
|
"cordis.patch.yml",
|
|
66
82
|
"assets/readme/hero.svg",
|
|
67
83
|
"assets/readme/workflow.svg",
|
|
68
84
|
"README.md",
|
|
69
85
|
"CHANGELOG.md",
|
|
70
|
-
"LICENSE"
|
|
86
|
+
"LICENSE",
|
|
87
|
+
"CODEX-COMPATIBILITY.md"
|
|
71
88
|
],
|
|
72
|
-
"scripts": {
|
|
73
|
-
"build": "tsc",
|
|
74
|
-
"test": "vitest run",
|
|
75
|
-
"prepack": "pnpm build"
|
|
76
|
-
},
|
|
77
89
|
"dsh": {
|
|
78
90
|
"engines": {
|
|
79
91
|
"dsh": "0.1.1-rc.2"
|
|
@@ -93,28 +105,69 @@
|
|
|
93
105
|
},
|
|
94
106
|
"peerDependencies": {
|
|
95
107
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
108
|
+
"@deepseek-ai/dsh-attachment": "0.1.1-rc.2",
|
|
96
109
|
"@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
|
|
110
|
+
"@deepseek-ai/dsh-fs": "0.1.1-rc.2",
|
|
97
111
|
"@deepseek-ai/dsh-host-webserver": "0.1.1-rc.2",
|
|
98
|
-
"@deepseek-ai/dsh-llm": "0.1.1-rc.2"
|
|
112
|
+
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
|
|
113
|
+
"@deepseek-ai/dsh-sandbox": "0.1.1-rc.2",
|
|
114
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.1-rc.2",
|
|
115
|
+
"@deepseek-ai/dsh-shell": "0.1.1-rc.2",
|
|
116
|
+
"@deepseek-ai/dsh-tools": "0.1.1-rc.2"
|
|
99
117
|
},
|
|
100
118
|
"dependencies": {
|
|
101
119
|
"@deepseek-ai/dsh-atomic-write": "0.1.1-rc.2",
|
|
102
120
|
"@deepseek-ai/dsh-home-paths": "0.1.1-rc.2",
|
|
103
121
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
104
122
|
"https-proxy-agent": "7.0.6",
|
|
123
|
+
"image-size": "^2.0.2",
|
|
105
124
|
"proxy-from-env": "1.1.0",
|
|
106
125
|
"ws": "8.21.3"
|
|
107
126
|
},
|
|
108
127
|
"devDependencies": {
|
|
109
128
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
110
129
|
"@deepseek-ai/dsh-agent": "0.1.1-rc.2",
|
|
130
|
+
"@deepseek-ai/dsh-attachment": "0.1.1-rc.2",
|
|
131
|
+
"@deepseek-ai/dsh-attachment-local": "0.1.1-rc.2",
|
|
111
132
|
"@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
|
|
133
|
+
"@deepseek-ai/dsh-fs": "0.1.1-rc.2",
|
|
112
134
|
"@deepseek-ai/dsh-host-webserver": "0.1.1-rc.2",
|
|
113
135
|
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
|
|
136
|
+
"@deepseek-ai/dsh-sandbox": "0.1.1-rc.2",
|
|
137
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.1-rc.2",
|
|
138
|
+
"@deepseek-ai/dsh-scope": "0.1.1-rc.2",
|
|
114
139
|
"@deepseek-ai/dsh-session": "0.1.1-rc.2",
|
|
140
|
+
"@deepseek-ai/dsh-shell": "0.1.1-rc.2",
|
|
141
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
|
|
142
|
+
"@deepseek-ai/dsh-tools": "0.1.1-rc.2",
|
|
115
143
|
"@types/node": "^22.20.0",
|
|
116
144
|
"@types/proxy-from-env": "1.0.4",
|
|
145
|
+
"sharp": "^0.35.4",
|
|
117
146
|
"typescript": "^6.0.3",
|
|
118
147
|
"vitest": "^4.1.8"
|
|
148
|
+
},
|
|
149
|
+
"peerDependenciesMeta": {
|
|
150
|
+
"@deepseek-ai/dsh-tools": {
|
|
151
|
+
"optional": true
|
|
152
|
+
},
|
|
153
|
+
"@deepseek-ai/dsh-attachment": {
|
|
154
|
+
"optional": true
|
|
155
|
+
},
|
|
156
|
+
"@deepseek-ai/dsh-fs": {
|
|
157
|
+
"optional": true
|
|
158
|
+
},
|
|
159
|
+
"@deepseek-ai/dsh-shell": {
|
|
160
|
+
"optional": true
|
|
161
|
+
},
|
|
162
|
+
"@deepseek-ai/dsh-sandbox": {
|
|
163
|
+
"optional": true
|
|
164
|
+
},
|
|
165
|
+
"@deepseek-ai/dsh-sandbox-policy": {
|
|
166
|
+
"optional": true
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"scripts": {
|
|
170
|
+
"build": "tsc",
|
|
171
|
+
"test": "vitest run"
|
|
119
172
|
}
|
|
120
|
-
}
|
|
173
|
+
}
|