@bitkyc08/opencodex 2.64.0-preview.20260923 → 2.65.0-preview.20260925
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/README.md +28 -25
- package/bin/ocx.mjs +16 -2
- package/gui/dist/assets/App-8NMiZxT0.css +1 -0
- package/gui/dist/assets/App-CsYvvpr3.js +50 -0
- package/gui/dist/assets/Tray-DUvc_Wul.js +1 -0
- package/gui/dist/assets/{index-DiBRuK-d.css → index--EWgGQvZ.css} +1 -1
- package/gui/dist/assets/{index-BEq4OCOz.js → index-BB0iHG8-.js} +12 -12
- package/gui/dist/assets/tray-data-f0lTZ4sF.js +1 -0
- package/gui/dist/index.html +2 -2
- package/package.json +1 -4
- package/src/adapters/anthropic.ts +30 -1
- package/src/adapters/claude-cli/adapter.ts +218 -0
- package/src/adapters/claude-cli/profiles.ts +38 -0
- package/src/adapters/codebuddy/profiles.ts +2 -0
- package/src/adapters/coding-agent/profile.ts +12 -4
- package/src/adapters/coding-agent/turn.ts +16 -6
- package/src/adapters/command-code-tool-text.ts +133 -23
- package/src/adapters/cursor/catalog.ts +4 -8
- package/src/adapters/cursor/discovery.ts +10 -5
- package/src/adapters/cursor/effort-map.ts +2 -6
- package/src/adapters/cursor/envelope-echo.ts +10 -5
- package/src/adapters/cursor/request-builder.ts +9 -4
- package/src/adapters/cursor/thread-continuity.ts +53 -0
- package/src/adapters/cursor.ts +29 -13
- package/src/adapters/devin/cloud-direct/chat.ts +3 -1
- package/src/adapters/google-tool-schema.ts +26 -3
- package/src/adapters/identity.ts +214 -2
- package/src/adapters/openai-chat/passthrough.ts +1 -0
- package/src/adapters/openai-chat/serialized-tool-call-content.ts +569 -0
- package/src/adapters/openai-chat.ts +43 -15
- package/src/adapters/openai-responses/canonical-forward.ts +17 -10
- package/src/adapters/openai-responses/passthrough.ts +19 -4
- package/src/adapters/openai-responses/request-strips.ts +25 -0
- package/src/adapters/openai-responses/web-search.ts +22 -4
- package/src/adapters/qoder/profiles.ts +2 -0
- package/src/adapters/registry.ts +8 -0
- package/src/adapters/run-turn-queue.ts +7 -0
- package/src/bridge/response-json.ts +6 -4
- package/src/bridge/sse.ts +7 -5
- package/src/claude/alias.ts +73 -26
- package/src/claude/context-windows.ts +15 -6
- package/src/claude/desktop-3p-library.ts +3 -2
- package/src/claude/desktop-3p.ts +1 -1
- package/src/claude/desktop-first-party.ts +63 -22
- package/src/claude/desktop-picker-profile.ts +302 -0
- package/src/claude/desktop-picker.ts +365 -0
- package/src/claude/desktop-risk.ts +20 -0
- package/src/claude/gateway-cache.ts +13 -4
- package/src/claude/inbound.ts +5 -2
- package/src/claude/intercept/connect-proxy.ts +106 -29
- package/src/claude/intercept/local-ca.ts +76 -18
- package/src/claude/intercept/model-bindings.ts +145 -0
- package/src/claude/intercept/picker-bootstrap.ts +141 -0
- package/src/claude/intercept/picker-ca.ts +126 -0
- package/src/claude/intercept/picker-listener.ts +213 -0
- package/src/claude/intercept/picker-models.ts +101 -0
- package/src/claude/intercept/picker-runtime.ts +330 -0
- package/src/claude/intercept/picker-trust.ts +125 -0
- package/src/claude/intercept/runtime.ts +149 -2
- package/src/claude/model-info.ts +18 -4
- package/src/cli/agent.ts +16 -2
- package/src/cli/capabilities.ts +71 -2
- package/src/cli/claude-desktop.ts +319 -33
- package/src/cli/claude.ts +15 -7
- package/src/cli/codex-shim-autorestore.ts +1 -0
- package/src/cli/dispatch.ts +29 -23
- package/src/cli/effort.ts +16 -6
- package/src/cli/ensure-desired-integrations.ts +29 -4
- package/src/cli/ready.ts +1 -1
- package/src/cli/registry.ts +8 -0
- package/src/cli/restart-scope.ts +9 -1
- package/src/cli/runtime-api.ts +17 -0
- package/src/cli/system-command.ts +11 -12
- package/src/client/connect.ts +12 -2
- package/src/client/state.ts +39 -1
- package/src/clients/config-export.ts +57 -9
- package/src/codex/auth-context.ts +51 -11
- package/src/codex/catalog/derive-entry.ts +5 -5
- package/src/codex/catalog/gather-capture.ts +25 -6
- package/src/codex/catalog/metadata.ts +3 -3
- package/src/codex/catalog/parsing.ts +39 -1
- package/src/codex/catalog/provider-models.ts +8 -6
- package/src/codex/catalog/retained-sync.ts +17 -7
- package/src/codex/catalog/sync.ts +2 -2
- package/src/codex/desktop-app-restart.ts +8 -0
- package/src/codex/desktop-switches.ts +9 -1
- package/src/codex/home.ts +43 -4
- package/src/codex/inject/config-toml.ts +137 -0
- package/src/codex/inject/plan.ts +23 -0
- package/src/codex/inject/remove.ts +21 -1
- package/src/codex/inject.ts +63 -8
- package/src/codex/journal.ts +36 -0
- package/src/codex/main-account-hard-lock.ts +14 -1
- package/src/codex/main-account-policy-wait.ts +109 -0
- package/src/codex/native-profile-startup.ts +24 -6
- package/src/codex/native-residue.ts +28 -10
- package/src/codex/quota-types.ts +8 -1
- package/src/codex/quota.ts +49 -7
- package/src/codex/runtime.ts +31 -10
- package/src/combos/failover.ts +7 -6
- package/src/combos/resolve.ts +91 -14
- package/src/combos/types.ts +18 -1
- package/src/config/load-degrade.ts +2 -0
- package/src/config/schema/config-schema.ts +21 -2
- package/src/config/schema/leaf-validators.ts +6 -3
- package/src/config/subagent-models.ts +3 -1
- package/src/generated/compatibility-version.json +275 -163
- package/src/images/artifacts.ts +14 -0
- package/src/integrations/owned-refresh.ts +1 -1
- package/src/integrations/ownership-policy.ts +32 -1
- package/src/integrations/state.ts +3 -1
- package/src/integrations/writer.ts +9 -0
- package/src/lib/config-ownership.ts +3 -0
- package/src/lib/errors.ts +87 -0
- package/src/lib/package-tree-integrity.ts +1 -1
- package/src/lib/request-execution-budget.ts +42 -14
- package/src/lib/request-resend-gate.ts +4 -3
- package/src/lib/retry-delay.ts +7 -1
- package/src/lib/tool-envelope-echo-filter.ts +236 -0
- package/src/lib/upstream-retry.ts +20 -12
- package/src/oauth/index.ts +1 -0
- package/src/oauth/kiro-credentials.ts +14 -1
- package/src/oauth/login-cli.ts +1 -0
- package/src/providers/derive.ts +4 -0
- package/src/providers/fast-opt-in.ts +31 -0
- package/src/providers/model-rename-fields.ts +2 -0
- package/src/providers/provider-id-rewrite.ts +2 -0
- package/src/providers/quota/vendor-probes-key.ts +8 -2
- package/src/providers/registry/entries-core.ts +45 -2
- package/src/providers/registry/entries-extended.ts +99 -12
- package/src/providers/registry/model-ids.ts +2 -0
- package/src/providers/registry/types.ts +7 -1
- package/src/providers/resolved-model-policy.ts +11 -4
- package/src/providers/service-tier.ts +10 -3
- package/src/responses/code-mode-helper-compat.ts +3 -0
- package/src/responses/parser.ts +45 -3
- package/src/router.ts +6 -0
- package/src/server/auth-cors.ts +8 -0
- package/src/server/chat-completions.ts +3 -1
- package/src/server/claude-messages.ts +69 -14
- package/src/server/grok-upstream-envelope-echo.ts +120 -0
- package/src/server/index/claude-intercept-lifecycle.ts +24 -0
- package/src/server/index/serve-options.ts +2 -2
- package/src/server/index.ts +7 -0
- package/src/server/management/agent-settings-routes.ts +204 -112
- package/src/server/management/claude-desktop-picker-routes.ts +128 -0
- package/src/server/management/combo-routes.ts +59 -2
- package/src/server/management/config-routes.ts +81 -39
- package/src/server/management/context.ts +3 -0
- package/src/server/management/native-integration-routes.ts +169 -93
- package/src/server/management/provider-routes.ts +46 -4
- package/src/server/management/route-registry.ts +10 -0
- package/src/server/management/routing-profile-routes.ts +9 -0
- package/src/server/management/sidebar-routes.ts +52 -0
- package/src/server/management-api.ts +2 -0
- package/src/server/proxy-liveness.ts +38 -3
- package/src/server/request-log-account-rotation.ts +53 -0
- package/src/server/request-log.ts +3 -16
- package/src/server/responses/adapter-dispatch.ts +17 -1
- package/src/server/responses/agent-task-recovery.ts +49 -26
- package/src/server/responses/codex-ws-exchange.ts +18 -7
- package/src/server/responses/codex-ws-wire.ts +27 -4
- package/src/server/responses/core-combo.ts +21 -3
- package/src/server/responses/core-normalize.ts +7 -0
- package/src/server/responses/core-opaque-recovery.ts +3 -2
- package/src/server/responses/encrypted-payload.ts +15 -14
- package/src/server/responses/fetch-helpers.ts +1 -1
- package/src/server/responses/input-admission.ts +10 -6
- package/src/server/responses/native-response-control.ts +2 -2
- package/src/server/responses/passthrough-delivery.ts +182 -12
- package/src/server/responses/passthrough-dispatch.ts +102 -44
- package/src/server/responses/policy-fallback.ts +3 -0
- package/src/server/responses/policy-refusal.ts +67 -0
- package/src/server/responses/request-send-budget.ts +4 -0
- package/src/server/responses/run-turn-execution.ts +42 -11
- package/src/server/responses/ws-upstream.ts +2 -1
- package/src/server/system-env-shell.ts +0 -1
- package/src/server/system-env.ts +25 -4
- package/src/service/cli.ts +34 -3
- package/src/tray/assets/opencodex-tray-offline-update.ico +0 -0
- package/src/tray/assets/opencodex-tray-online-update.ico +0 -0
- package/src/tray/assets/opencodex-tray-warning-update.ico +0 -0
- package/src/tray/windows-tray.ps1 +188 -7
- package/src/tray/windows.ts +23 -2
- package/src/types/config.ts +52 -12
- package/src/types/provider.ts +22 -5
- package/src/types/tools.ts +11 -5
- package/src/types.ts +1 -0
- package/src/update/async-check.ts +109 -0
- package/src/update/badge.ts +11 -17
- package/src/update/check-types.ts +9 -0
- package/src/update/desktop-badge.ts +102 -0
- package/src/update/index.ts +48 -8
- package/src/update/install-detection.d.mts +29 -2
- package/src/update/install-detection.mjs +213 -7
- package/src/update/job.ts +17 -12
- package/src/update/notify.ts +16 -11
- package/src/update/pnpm-owner-worker.ts +12 -0
- package/src/update/refresh-scheduler.ts +141 -0
- package/src/usage/cost.ts +31 -4
- package/src/usage/expected-prices.ts +57 -0
- package/assets/download-linux.svg +0 -10
- package/assets/download-macos.svg +0 -10
- package/assets/download-windows.svg +0 -10
- package/gui/dist/assets/App-D5eN1TID.js +0 -50
- package/gui/dist/assets/App-I5AnaSLh.css +0 -1
- package/gui/dist/assets/Tray-Bh_ErQDh.js +0 -1
- package/gui/dist/assets/usage-companion-chart-DBG_37kQ.js +0 -1
package/src/adapters/identity.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { OcxContext } from "../types";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Central routed-model identity repair.
|
|
3
5
|
*
|
|
@@ -72,11 +74,221 @@ function safeRoutedModelIdentity(modelName: string): string | null {
|
|
|
72
74
|
* native template.
|
|
73
75
|
*/
|
|
74
76
|
export function identifyRoutedModel(systemText: string, modelName: string): string {
|
|
77
|
+
const replacement = routedIdentityLine(modelName);
|
|
78
|
+
return systemText
|
|
79
|
+
.replace(CODEX_GPT5_IDENTITY_RE, () => replacement)
|
|
80
|
+
.replace(NEUTRAL_IDENTITY_RE, () => replacement)
|
|
81
|
+
.replace(ROUTED_IDENTITY_RE, () => replacement);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function routedIdentityLine(modelName: string): string {
|
|
75
85
|
const identity = safeRoutedModelIdentity(modelName);
|
|
76
|
-
|
|
86
|
+
return identity
|
|
77
87
|
? `You are a coding agent powered by the ${identity}. If asked which model you are, identify as ${identity}. Do not claim to be a different model or to have a different creator.`
|
|
78
88
|
: "You are a coding agent powered by the configured model. If asked which model you are, identify as configured model. Do not claim to be GPT-5 or made by OpenAI.";
|
|
79
|
-
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* This proxy's OWN generated identity sentence (both the named and the `configured model`
|
|
93
|
+
* fallback form). Codex stores a session's instructions once and replays them verbatim when it
|
|
94
|
+
* spawns a sub-agent on a DIFFERENT model (#5217), so a worker inherits the parent's sentence and
|
|
95
|
+
* then answers identity questions with the parent's model id.
|
|
96
|
+
*
|
|
97
|
+
* The pattern is deliberately anchored on the exact wording this module emits — the leading
|
|
98
|
+
* "You are a coding agent powered by the " and the matching "If asked which model you are,
|
|
99
|
+
* identify as " clause — so it can only ever rewrite text the proxy generated. The model id is
|
|
100
|
+
* matched with the same character class `safeRoutedModelIdentity` allows, never `.*`, so user
|
|
101
|
+
* prose, fenced code and provider-native identity blocks are out of reach.
|
|
102
|
+
*/
|
|
103
|
+
const ROUTED_IDENTITY_RE =
|
|
104
|
+
/You are a coding agent powered by the (?:configured model|[A-Za-z0-9._/@:+\-[\]~]+)\. If asked which model you are, identify as (?:configured model|[A-Za-z0-9._/@:+\-[\]~]+)\. Do not claim to be (?:a different model or to have a different creator|GPT-5 or made by OpenAI)\./g;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The model-neutral catalog line. Since #5217 the catalog no longer bakes a model id into
|
|
108
|
+
* `base_instructions` — a stored instruction block is replayed to sub-agents on other models —
|
|
109
|
+
* so the id is written at request time instead, where the destination is known.
|
|
110
|
+
*/
|
|
111
|
+
const NEUTRAL_IDENTITY_RE = new RegExp(
|
|
112
|
+
NEUTRAL_IDENTITY_LINE.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
|
|
113
|
+
"g",
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* True when `text` carries an identity sentence this proxy generated — either a sentence that names
|
|
118
|
+
* a model already, or the model-neutral catalog line. Both need request-time attention: the named
|
|
119
|
+
* form is renamed for the destination, the neutral form is named for the first time.
|
|
120
|
+
*/
|
|
121
|
+
export function hasRoutedIdentity(text: string): boolean {
|
|
122
|
+
ROUTED_IDENTITY_RE.lastIndex = 0;
|
|
123
|
+
NEUTRAL_IDENTITY_RE.lastIndex = 0;
|
|
124
|
+
return ROUTED_IDENTITY_RE.test(text) || NEUTRAL_IDENTITY_RE.test(text);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Request-time repair for a routed destination: rewrite an inherited identity sentence so it names
|
|
129
|
+
* the model this request is actually sent to. Text without one is returned unchanged.
|
|
130
|
+
*/
|
|
131
|
+
export function repairRoutedIdentity(text: string, modelName: string): string {
|
|
132
|
+
const replacement = routedIdentityLine(modelName);
|
|
133
|
+
return text.replace(ROUTED_IDENTITY_RE, () => replacement);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Request-time naming for text that will be handed to a routed model from a stored instruction
|
|
138
|
+
* block: rewrite the model-neutral catalog line AND any sentence naming an earlier model so both
|
|
139
|
+
* name this request's destination.
|
|
140
|
+
*
|
|
141
|
+
* This is the parser's entry point. A routed adapter that never calls `identifyRoutedModel` (the
|
|
142
|
+
* native-wire adapters build their own system text) would otherwise ship the catalog's neutral line
|
|
143
|
+
* with no model name at all, which is what `base_instructions` used to carry before #5217 made the
|
|
144
|
+
* on-disk block model-neutral.
|
|
145
|
+
*/
|
|
146
|
+
export function nameRoutedIdentity(text: string, modelName: string): string {
|
|
147
|
+
const replacement = routedIdentityLine(modelName);
|
|
148
|
+
// Name the neutral line first, then let the rename pass settle any earlier model id the block
|
|
149
|
+
// still carries — including the one just written, which the second pass rewrites to itself.
|
|
150
|
+
return repairRoutedIdentity(text.replace(NEUTRAL_IDENTITY_RE, () => replacement), modelName);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Settle this proxy's identity sentence on the model a routed request is actually dispatched to.
|
|
155
|
+
*
|
|
156
|
+
* The parser writes the CLIENT-selected id (an alias, a namespaced slug, a combo name) because
|
|
157
|
+
* routing has not run yet, and only some adapters rename the sentence afterwards: the ones that
|
|
158
|
+
* build their own system text and call `identifyRoutedModel`. Every other adapter — the native-wire
|
|
159
|
+
* ones and the `runTurn` ones — ships whatever the parser wrote, so a request routed anywhere else
|
|
160
|
+
* would hand the upstream an id it never sees, and an inherited sub-agent block the parent's id.
|
|
161
|
+
*
|
|
162
|
+
* The route owner knows the model id that will be sent, and this is the one place every dispatch
|
|
163
|
+
* path (passthrough, runTurn, request build) reads the context from. Text without a sentence of
|
|
164
|
+
* ours is returned unchanged, and the same by reference: the guard is a regex test, not a scan of
|
|
165
|
+
* every turn's text.
|
|
166
|
+
*/
|
|
167
|
+
export function renameRoutedIdentityInContext(context: OcxContext, wireModelId: string): OcxContext {
|
|
168
|
+
let changed = false;
|
|
169
|
+
const mapText = (text: string): string => {
|
|
170
|
+
if (!hasRoutedIdentity(text)) return text;
|
|
171
|
+
const next = repairRoutedIdentity(text, wireModelId);
|
|
172
|
+
if (next !== text) changed = true;
|
|
173
|
+
return next;
|
|
174
|
+
};
|
|
175
|
+
const systemPrompt = context.systemPrompt?.map(mapText);
|
|
176
|
+
const messages = context.messages.map((message) => {
|
|
177
|
+
// Instruction text only. A user turn is the caller's own content, and every other role is
|
|
178
|
+
// either model output or tool output — none of it is ours to rewrite.
|
|
179
|
+
if (message.role !== "developer") return message;
|
|
180
|
+
const content = message.content;
|
|
181
|
+
if (typeof content === "string") {
|
|
182
|
+
const next = mapText(content);
|
|
183
|
+
return next === content ? message : { ...message, content: next };
|
|
184
|
+
}
|
|
185
|
+
let partChanged = false;
|
|
186
|
+
const parts = content.map((part) => {
|
|
187
|
+
if (part.type !== "text" || !hasRoutedIdentity(part.text)) return part;
|
|
188
|
+
const next = repairRoutedIdentity(part.text, wireModelId);
|
|
189
|
+
if (next === part.text) return part;
|
|
190
|
+
partChanged = true;
|
|
191
|
+
return { ...part, text: next };
|
|
192
|
+
});
|
|
193
|
+
if (!partChanged) return message;
|
|
194
|
+
changed = true;
|
|
195
|
+
return { ...message, content: parts };
|
|
196
|
+
});
|
|
197
|
+
if (!changed) return context;
|
|
198
|
+
return { ...context, ...(systemPrompt ? { systemPrompt } : {}), messages };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** A content part carrying no text is not content; every other part shape stays. */
|
|
202
|
+
function isEmptyTextPart(part: unknown): boolean {
|
|
203
|
+
if (!part || typeof part !== "object" || Array.isArray(part)) return false;
|
|
204
|
+
const record = part as Record<string, unknown>;
|
|
205
|
+
return typeof record.text === "string" && record.text.length === 0;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Apply `repair` to the instruction text of a Responses request body: the top-level `instructions`
|
|
210
|
+
* string and every developer/system `input` message. Nothing else is in reach — user turns, tool
|
|
211
|
+
* output and assistant history are the caller's content.
|
|
212
|
+
*
|
|
213
|
+
* Stripping consumes text rather than replacing it, so a value can end up empty. An empty
|
|
214
|
+
* `instructions` string is a different payload from an absent key, and an empty developer message is
|
|
215
|
+
* a message the caller never wrote, so both are removed instead of sent blank.
|
|
216
|
+
*/
|
|
217
|
+
export function repairIdentityInResponsesBody(body: unknown, repair: (text: string) => string): unknown {
|
|
218
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) return body;
|
|
219
|
+
const record = body as Record<string, unknown>;
|
|
220
|
+
let changed = false;
|
|
221
|
+
const mapText = (text: string): string => {
|
|
222
|
+
if (!hasRoutedIdentity(text)) return text;
|
|
223
|
+
const next = repair(text);
|
|
224
|
+
if (next !== text) changed = true;
|
|
225
|
+
return next;
|
|
226
|
+
};
|
|
227
|
+
let instructions = record.instructions;
|
|
228
|
+
if (typeof instructions === "string") {
|
|
229
|
+
const next = mapText(instructions);
|
|
230
|
+
if (next !== instructions) {
|
|
231
|
+
changed = true;
|
|
232
|
+
instructions = next.length > 0 ? next : undefined;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const mapInputItem = (item: unknown): unknown => {
|
|
236
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return item;
|
|
237
|
+
const message = item as Record<string, unknown>;
|
|
238
|
+
if (message.type !== undefined && message.type !== "message") return item;
|
|
239
|
+
if (message.role !== "developer" && message.role !== "system") return item;
|
|
240
|
+
if (typeof message.content === "string") {
|
|
241
|
+
const next = mapText(message.content);
|
|
242
|
+
if (next === message.content) return item;
|
|
243
|
+
return next.length > 0 ? { ...message, content: next } : undefined;
|
|
244
|
+
}
|
|
245
|
+
if (!Array.isArray(message.content)) return item;
|
|
246
|
+
let partChanged = false;
|
|
247
|
+
const content = message.content.map((part: unknown) => {
|
|
248
|
+
if (!part || typeof part !== "object" || Array.isArray(part)) return part;
|
|
249
|
+
const partRecord = part as Record<string, unknown>;
|
|
250
|
+
if (typeof partRecord.text !== "string") return part;
|
|
251
|
+
const next = mapText(partRecord.text);
|
|
252
|
+
if (next === partRecord.text) return part;
|
|
253
|
+
partChanged = true;
|
|
254
|
+
return { ...partRecord, text: next };
|
|
255
|
+
});
|
|
256
|
+
if (!partChanged) return item;
|
|
257
|
+
return content.every(isEmptyTextPart) ? undefined : { ...message, content };
|
|
258
|
+
};
|
|
259
|
+
const input = Array.isArray(record.input)
|
|
260
|
+
? record.input.flatMap((item: unknown) => {
|
|
261
|
+
const next = mapInputItem(item);
|
|
262
|
+
return next === undefined ? [] : [next];
|
|
263
|
+
})
|
|
264
|
+
: record.input;
|
|
265
|
+
if (!changed) return body;
|
|
266
|
+
const next: Record<string, unknown> = { ...record, input };
|
|
267
|
+
// `...record` carries the original key, so a removed instruction has to be deleted rather than
|
|
268
|
+
// merely left out of the spread.
|
|
269
|
+
if (instructions === undefined) delete next.instructions;
|
|
270
|
+
else next.instructions = instructions;
|
|
271
|
+
return next;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Request-time repair for a native (Codex/OpenAI) destination: drop an inherited routed identity
|
|
276
|
+
* sentence instead of rewriting it. A native worker keeps Codex's own identity wording, which the
|
|
277
|
+
* client already sends in its `model_switch` block; re-stating a routed sentence there would tell
|
|
278
|
+
* a first-party model it is some third-party model.
|
|
279
|
+
*
|
|
280
|
+
* The model-neutral catalog line goes too. It is proxy-authored text as well, and unlike the named
|
|
281
|
+
* form it does not even have to be inherited from a routed parent: the on-disk catalog block
|
|
282
|
+
* carries it since #5217, so it rides along on every instruction block Codex replays to a worker.
|
|
283
|
+
* Left in place it reaches a first-party model as an instruction that contradicts the model_switch
|
|
284
|
+
* identity Codex sends for the same request.
|
|
285
|
+
*/
|
|
286
|
+
export function stripRoutedIdentity(text: string): string {
|
|
287
|
+
return text
|
|
288
|
+
.replace(ROUTED_IDENTITY_RE, () => "")
|
|
289
|
+
.replace(NEUTRAL_IDENTITY_RE, () => "")
|
|
290
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
291
|
+
.trim();
|
|
80
292
|
}
|
|
81
293
|
|
|
82
294
|
/** The catalog (static, on-disk) replacement for `base_instructions`. Same neutral wording. */
|
|
@@ -96,6 +96,7 @@ export function buildOpenAIChatPassthroughRequest(
|
|
|
96
96
|
|
|
97
97
|
if (modelInList(provider.noTemperatureModels, modelId)) delete body.temperature;
|
|
98
98
|
if (modelInList(provider.noTopPModels, modelId)) delete body.top_p;
|
|
99
|
+
if (modelInList(provider.noStopModels, modelId)) delete body.stop;
|
|
99
100
|
if (modelInList(provider.noPenaltyModels, modelId)) {
|
|
100
101
|
delete body.presence_penalty;
|
|
101
102
|
delete body.frequency_penalty;
|