@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.
@@ -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. */
@@ -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 selected = options.reasoningEffort === undefined ? undefined : String(options.reasoningEffort);
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 === selected
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 selectedEffort = options.reasoningEffort === undefined
238
- ? undefined : String(options.reasoningEffort);
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
  }
@@ -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>;
@@ -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(),
@@ -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 withTurnState(request, turnState) {
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: { ...metadata, 'x-codex-turn-state': turnState },
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(withTurnState(prepared.request, entry.turnState));
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(withTurnState(prepared.request, entry.turnState), justPrewarmed);
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
@@ -14,6 +14,7 @@ export type NativeCodexReplayDescriptor = {
14
14
  } | {
15
15
  type: 'function_call';
16
16
  id?: string;
17
+ namespace?: string;
17
18
  block: number;
18
19
  };
19
20
  export interface NativeCodexReplayState {
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
- || !onlyKeys(row, ['type', 'id', 'block'])) {
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 { type: 'function_call', ...(id === undefined ? {} : { id }), block: Number(row.block) };
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
  }
@@ -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: string;
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
- /** Parse only response.completed usage_metadata.amount and preserve its exact string value. */
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;
@@ -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
- /** Parse only response.completed usage_metadata.amount and preserve its exact string value. */
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 metadata = record(response?.usage_metadata);
14
- const amount = metadata?.amount;
15
- if (typeof amount !== 'string' || amount.length === 0
16
- || Buffer.byteLength(amount) > MAX_AMOUNT_BYTES)
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 { amount };
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) {
@@ -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 HTTP Responses body. */
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
- return { type: 'input_image', image_url: `data:${image.mediaType};base64,${image.dataBase64}` };
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 HTTP Responses body. */
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
- return {
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 = "6478a751fde8884b2fdc76486fe23175a8e795d4";
4
- export declare const TRACKED_CODEX_RELEASE = "rust-v0.151.0";
5
- /** Whole release version sent to the Codex model-catalog endpoint. */
6
- export declare const CODEX_CLIENT_VERSION = "0.151.0";
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 = '6478a751fde8884b2fdc76486fe23175a8e795d4';
4
- export const TRACKED_CODEX_RELEASE = 'rust-v0.151.0';
5
- /** Whole release version sent to the Codex model-catalog endpoint. */
6
- export const CODEX_CLIENT_VERSION = '0.151.0';
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
@@ -8,6 +8,7 @@ export interface UsageWindow {
8
8
  export interface UsageLimitSummary {
9
9
  id: string;
10
10
  name?: string;
11
+ normalModelSlug?: string;
11
12
  primary?: UsageWindow;
12
13
  secondary?: UsageWindow;
13
14
  limitReached?: boolean;
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 limitReached = typeof row.limit_reached === 'boolean'
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
- limits.push(extra);
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.8.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
+ }