@bitkyc08/opencodex 2.11.0 → 2.11.1
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/gui/dist/assets/{index-Bk-PN-70.css → index-BA1dgo4q.css} +1 -1
- package/gui/dist/assets/index-DDZpgzKk.js +70 -0
- package/gui/dist/index.html +2 -2
- package/package.json +6 -4
- package/src/adapters/anthropic.ts +10 -2
- package/src/adapters/cursor/native-exec-common.ts +6 -2
- package/src/adapters/google-antigravity-replay.ts +3 -2
- package/src/adapters/google-antigravity-wire.ts +38 -6
- package/src/adapters/google.ts +57 -10
- package/src/adapters/openai-chat.ts +19 -2
- package/src/claude/model-info.ts +1 -1
- package/src/cli/account-auth.ts +3 -1
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +15 -1
- package/src/cli/codex-shim-readiness.ts +69 -0
- package/src/cli/combo.ts +5 -0
- package/src/cli/config-command.ts +33 -4
- package/src/cli/doctor.ts +21 -0
- package/src/cli/export-command.ts +6 -6
- package/src/cli/help.ts +6 -6
- package/src/cli/index.ts +22 -5
- package/src/cli/models-runtime.ts +13 -1
- package/src/cli/provider.ts +7 -0
- package/src/clients/config-export.ts +67 -5
- package/src/codex/account-lifecycle.ts +99 -10
- package/src/codex/auth-api.ts +222 -34
- package/src/codex/catalog/account-models.ts +9 -4
- package/src/codex/catalog/aggregation.ts +41 -8
- package/src/codex/catalog/bundled.ts +54 -22
- package/src/codex/catalog/effort.ts +47 -20
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +70 -18
- package/src/codex/catalog/native-models.ts +7 -0
- package/src/codex/catalog/parsing.ts +29 -11
- package/src/codex/catalog/provider-fetch.ts +335 -50
- package/src/codex/catalog/sync.ts +588 -126
- package/src/codex/catalog-refresh-status.ts +87 -0
- package/src/codex/catalog-write-serialization.ts +2 -1
- package/src/codex/catalog.ts +4 -3
- package/src/codex/convergence-types.ts +1 -1
- package/src/codex/convergence.ts +190 -52
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/features.ts +79 -1
- package/src/codex/history-job.ts +81 -1
- package/src/codex/history-lock.ts +2 -1
- package/src/codex/history-provider.ts +4 -3
- package/src/codex/inject.ts +56 -12
- package/src/codex/model-cache.ts +50 -10
- package/src/codex/transition-state.ts +10 -2
- package/src/codex/user-identity.ts +110 -2
- package/src/combos/index.ts +3 -0
- package/src/combos/types.ts +75 -9
- package/src/config.ts +26 -12
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +12 -10
- package/src/integrations/registry.ts +7 -0
- package/src/integrations/writer.ts +1 -1
- package/src/lib/pinned-http.ts +40 -9
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +42 -9
- package/src/oauth/cursor.ts +25 -5
- package/src/oauth/index.ts +59 -45
- package/src/providers/antigravity-models.ts +115 -3
- package/src/providers/context-cap.ts +13 -5
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +14 -15
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +93 -19
- package/src/providers/registry.ts +16 -5
- package/src/providers/slug-codec.ts +13 -6
- package/src/reasoning-effort.ts +22 -0
- package/src/router.ts +0 -20
- package/src/routing/history/indexer.ts +54 -39
- package/src/routing/quota.ts +77 -56
- package/src/server/index.ts +32 -7
- package/src/server/management/combo-routes.ts +43 -19
- package/src/server/management/config-routes.ts +115 -20
- package/src/server/management/model-routes.ts +10 -7
- package/src/server/management/model-rows.ts +6 -2
- package/src/server/management/oauth-account-routes.ts +12 -0
- package/src/server/management/provider-routes.ts +114 -40
- package/src/server/management/routing-profile-routes.ts +0 -22
- package/src/server/management-api.ts +7 -25
- package/src/server/responses/core.ts +3 -3
- package/src/server/responses/policy-fallback.ts +152 -0
- package/src/server/responses.ts +3 -2
- package/src/types.ts +15 -2
- package/src/usage/cost.ts +0 -0
- package/src/vision/describe.ts +3 -1
- package/src/vision/index.ts +17 -6
- package/src/vision/reasoning.ts +55 -0
- package/src/web-search/parse.ts +15 -3
- package/gui/dist/assets/index-BynIEIV-.js +0 -70
package/src/vision/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import type { OcxConfig, OcxContentPart, OcxMessage, OcxParsedRequest, OcxProviderConfig, OcxTextContent } from "../types";
|
|
3
3
|
import { modelInList } from "../types";
|
|
4
|
+
import type { VisionReasoningEffort } from "../reasoning-effort";
|
|
4
5
|
import { describeImage, type DescribeOutcome, type VisionSettings } from "./describe";
|
|
5
6
|
import { describeImageAnthropic } from "./anthropic-describe";
|
|
7
|
+
import { normalizeVisionReasoningForModel } from "./reasoning";
|
|
6
8
|
import type { CodexAuthContext } from "../codex/auth-context";
|
|
7
9
|
import { getAccountSet } from "../oauth/store";
|
|
8
10
|
import type { ResolvedOpenAiForwardSidecar } from "../providers/openai-sidecar";
|
|
@@ -16,6 +18,7 @@ export { describeImageAnthropic, parseAnthropicVisionSSE } from "./anthropic-des
|
|
|
16
18
|
const DEFAULT_VISION_MODEL = "gpt-5.4-mini";
|
|
17
19
|
const DEFAULT_ANTHROPIC_VISION_MODEL = "claude-sonnet-5";
|
|
18
20
|
const DEFAULT_TIMEOUT_MS = 45_000;
|
|
21
|
+
const DEFAULT_REASONING: VisionReasoningEffort = "low";
|
|
19
22
|
const DEFAULT_MAX_DESCRIPTIONS_PER_TURN = 8;
|
|
20
23
|
const DESCRIPTION_CACHE_MAX_ENTRIES = 256;
|
|
21
24
|
export const VISION_DESCRIPTION_CACHE_MAX_BYTES = 1024 * 1024;
|
|
@@ -186,7 +189,7 @@ export function resolveVisionBackend(
|
|
|
186
189
|
|
|
187
190
|
/** Native model used by the OpenAI vision helper, including its bounded default. */
|
|
188
191
|
export function resolveOpenAiVisionModel(config: Pick<OcxConfig, "visionSidecar">): string {
|
|
189
|
-
return config.visionSidecar?.model
|
|
192
|
+
return config.visionSidecar?.model || DEFAULT_VISION_MODEL;
|
|
190
193
|
}
|
|
191
194
|
|
|
192
195
|
/** A user/developer/toolResult message can carry images (toolResult: e.g. Codex view_image output). */
|
|
@@ -242,19 +245,29 @@ export function planVisionSidecar(
|
|
|
242
245
|
|
|
243
246
|
if (backend === "anthropic") {
|
|
244
247
|
if (!anthropicSidecar) return undefined;
|
|
248
|
+
const model = cfg.model || DEFAULT_ANTHROPIC_VISION_MODEL;
|
|
245
249
|
return {
|
|
246
250
|
backend,
|
|
247
251
|
anthropicSidecar,
|
|
248
|
-
settings: {
|
|
252
|
+
settings: {
|
|
253
|
+
model,
|
|
254
|
+
reasoning: normalizeVisionReasoningForModel(model, cfg.reasoning) ?? DEFAULT_REASONING,
|
|
255
|
+
timeoutMs: cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
256
|
+
},
|
|
249
257
|
maxDescriptionsPerTurn,
|
|
250
258
|
};
|
|
251
259
|
}
|
|
252
260
|
|
|
253
261
|
if (!openAiSidecar) return undefined;
|
|
262
|
+
const model = resolveOpenAiVisionModel(config);
|
|
254
263
|
return {
|
|
255
264
|
backend,
|
|
256
265
|
forwardSidecar: openAiSidecar,
|
|
257
|
-
settings: {
|
|
266
|
+
settings: {
|
|
267
|
+
model,
|
|
268
|
+
reasoning: normalizeVisionReasoningForModel(model, cfg.reasoning) ?? DEFAULT_REASONING,
|
|
269
|
+
timeoutMs: cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
270
|
+
},
|
|
258
271
|
maxDescriptionsPerTurn,
|
|
259
272
|
};
|
|
260
273
|
}
|
|
@@ -363,6 +376,7 @@ function descriptionIdentity(job: ImageJob, plan: VisionPlan): { key: string; pe
|
|
|
363
376
|
key: JSON.stringify([
|
|
364
377
|
plan.backend,
|
|
365
378
|
plan.settings.model,
|
|
379
|
+
...(plan.backend === "openai" ? [plan.settings.reasoning] : []),
|
|
366
380
|
job.detail ?? "high",
|
|
367
381
|
imageHash,
|
|
368
382
|
sha256(normalizedContext(job.contextText)),
|
|
@@ -418,7 +432,6 @@ export async function describeImagesInPlace(
|
|
|
418
432
|
recordSidecarOutcome?: SidecarOutcomeRecorder,
|
|
419
433
|
translatorBudget?: TranslatorBudget,
|
|
420
434
|
): Promise<void> {
|
|
421
|
-
// 1. Gather every image part across messages, each with its own message's text as context.
|
|
422
435
|
const jobs: ImageJob[] = [];
|
|
423
436
|
const targets: { msg: OcxMessage; parts: OcxContentPart[] }[] = [];
|
|
424
437
|
for (const msg of parsed.context.messages) {
|
|
@@ -440,7 +453,6 @@ export async function describeImagesInPlace(
|
|
|
440
453
|
return;
|
|
441
454
|
}
|
|
442
455
|
|
|
443
|
-
// 2. Admit misses in source order. Cache hits and same-turn waiters do not consume the cap.
|
|
444
456
|
const inFlight = new Map<string, Promise<DescribeOutcome>>();
|
|
445
457
|
const executions: Array<() => Promise<void>> = [];
|
|
446
458
|
const outcomePromises: Array<Promise<DescribeOutcome>> = [];
|
|
@@ -492,7 +504,6 @@ export async function describeImagesInPlace(
|
|
|
492
504
|
await runBounded(executions, VISION_CONCURRENCY, execute => execute());
|
|
493
505
|
const outcomes = await Promise.all(outcomePromises);
|
|
494
506
|
|
|
495
|
-
// 3. Rebuild each message, replacing image parts with their descriptions in order.
|
|
496
507
|
let oi = 0;
|
|
497
508
|
const descriptions: string[] = [];
|
|
498
509
|
for (const { msg, parts } of targets) {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { NATIVE_OPENAI_MODELS, nativeReasoningEfforts } from "../codex/catalog/metadata";
|
|
2
|
+
import {
|
|
3
|
+
VISION_REASONING_EFFORTS,
|
|
4
|
+
sanitizeVisionReasoning,
|
|
5
|
+
type VisionReasoningEffort,
|
|
6
|
+
} from "../reasoning-effort";
|
|
7
|
+
|
|
8
|
+
/** Keep the public config type aligned without replacing the heavily-changed shared types file. */
|
|
9
|
+
declare module "../types" {
|
|
10
|
+
interface OcxVisionSidecarConfig {
|
|
11
|
+
/** OpenAI Responses reasoning effort used by the vision describer. Default: low. */
|
|
12
|
+
reasoning?: VisionReasoningEffort;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const NATIVE_VISION_MODELS = new Set(NATIVE_OPENAI_MODELS);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Return the known vision reasoning ladder for a native OpenAI model.
|
|
20
|
+
* Unknown/custom models deliberately return undefined so callers stay permissive when reliable
|
|
21
|
+
* capability metadata is unavailable.
|
|
22
|
+
*/
|
|
23
|
+
export function nativeVisionReasoningEfforts(modelId: string): VisionReasoningEffort[] | undefined {
|
|
24
|
+
if (!NATIVE_VISION_MODELS.has(modelId)) return undefined;
|
|
25
|
+
const advertised = new Set(nativeReasoningEfforts(modelId));
|
|
26
|
+
const supported = VISION_REASONING_EFFORTS.filter(effort => advertised.has(effort));
|
|
27
|
+
return supported.length > 0 ? [...supported] : undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Normalize one configured effort against a model's known ladder. Invalid enum values degrade to
|
|
32
|
+
* undefined; valid values on unknown/custom models are preserved. A known native model clamps to
|
|
33
|
+
* the highest supported rung at or below the requested value.
|
|
34
|
+
*/
|
|
35
|
+
export function normalizeVisionReasoningForModel(
|
|
36
|
+
modelId: string,
|
|
37
|
+
value: unknown,
|
|
38
|
+
): VisionReasoningEffort | undefined {
|
|
39
|
+
const requested = sanitizeVisionReasoning(value);
|
|
40
|
+
if (!requested) return undefined;
|
|
41
|
+
const supported = nativeVisionReasoningEfforts(modelId);
|
|
42
|
+
if (!supported || supported.includes(requested)) return requested;
|
|
43
|
+
|
|
44
|
+
const requestedRank = VISION_REASONING_EFFORTS.indexOf(requested);
|
|
45
|
+
let best = supported[0];
|
|
46
|
+
let bestRank = VISION_REASONING_EFFORTS.indexOf(best);
|
|
47
|
+
for (const effort of supported) {
|
|
48
|
+
const rank = VISION_REASONING_EFFORTS.indexOf(effort);
|
|
49
|
+
if (rank <= requestedRank && rank >= bestRank) {
|
|
50
|
+
best = effort;
|
|
51
|
+
bestRank = rank;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return best;
|
|
55
|
+
}
|
package/src/web-search/parse.ts
CHANGED
|
@@ -155,11 +155,23 @@ export async function parseSidecarSSE(response: Response): Promise<WebSearchResu
|
|
|
155
155
|
|
|
156
156
|
const handle = (payload: string): void => {
|
|
157
157
|
if (!payload || payload === "[DONE]") return;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
// Neither warning below copies the frame's content. An upstream SSE payload can carry model
|
|
159
|
+
// output or credential material, and a malformed frame is exactly the case where the content
|
|
160
|
+
// is least trustworthy. Length plus a classification separates the two failure modes in a log
|
|
161
|
+
// without reproducing anything from the wire.
|
|
162
|
+
let parsed: unknown;
|
|
163
|
+
try { parsed = JSON.parse(payload); } catch {
|
|
164
|
+
console.warn(`[web-search-parse] malformed SSE JSON (${payload.length} chars)`);
|
|
161
165
|
return;
|
|
162
166
|
}
|
|
167
|
+
// `JSON.parse("null")` returns null rather than throwing, so the catch above cannot cover it
|
|
168
|
+
// and the `data.type` read below threw out of parseSidecarSSE.
|
|
169
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
170
|
+
const shape = Array.isArray(parsed) ? "array" : parsed === null ? "null" : typeof parsed;
|
|
171
|
+
console.warn(`[web-search-parse] non-record SSE JSON frame (${payload.length} chars, ${shape})`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const data = parsed as Record<string, unknown>;
|
|
163
175
|
const type = data.type as string | undefined;
|
|
164
176
|
if (type === "response.output_text.delta" && typeof data.delta === "string") {
|
|
165
177
|
acc.deltaText += data.delta;
|