ocx-cursor 1.0.3 → 1.0.5

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 CHANGED
@@ -121,7 +121,7 @@ The installer patches these files:
121
121
  /Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.glass.main.js
122
122
  ```
123
123
 
124
- The patch keeps the model metadata that Cursor would discard. It leaves Cursor's local-agent mode disabled and does not edit either local-agent runtime.
124
+ The patch keeps the model metadata that Cursor would discard and allows managed `opencodex/` models in Cursor's explicit subagent model list, including the gateway credentials and legacy model details used by Cursor's agent protocol. Generated OpenCodex agent definitions are hidden from Cursor so model routing uses Cursor's built-in subagent types instead of creating one custom type per model. Other user-added and BYOK models remain excluded from the model list. It leaves Cursor's local-agent mode disabled and does not edit either local-agent runtime.
125
125
 
126
126
  The login service refreshes the catalog every 15 seconds. It waits for Cursor to quit before writing the state database or reapplying a patch after a Cursor update.
127
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocx-cursor",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Use OpenCodex models in Cursor through an authenticated HTTPS gateway",
5
5
  "keywords": [
6
6
  "opencodex",
package/src/catalog.mjs CHANGED
@@ -73,6 +73,30 @@ export function priorityModelIds(catalogFile = configuredCodexCatalogFile()) {
73
73
  }
74
74
  }
75
75
 
76
+ export function codexNativeModels(catalogFile = configuredCodexCatalogFile()) {
77
+ try {
78
+ const payload = JSON.parse(readFileSync(catalogFile, "utf8"));
79
+ return payload.models
80
+ .filter((model) => typeof model?.slug === "string"
81
+ && !model.slug.includes("/")
82
+ && model.visibility === "list"
83
+ && model.supported_in_api === true
84
+ && model.opencodex_capability_provenance === undefined)
85
+ .map((model) => ({
86
+ id: model.slug,
87
+ owned_by: "openai",
88
+ capabilities: {
89
+ input_modalities: model.input_modalities,
90
+ context_length: model.context_window,
91
+ max_output_tokens: model.max_output_tokens,
92
+ reasoning_effort: model.supported_reasoning_levels?.map(({ effort }) => effort),
93
+ },
94
+ }));
95
+ } catch {
96
+ return [];
97
+ }
98
+ }
99
+
76
100
  export function normalizeActiveCatalog(configured, active, fastModelIds = new Set()) {
77
101
  const configuredById = new Map(configured
78
102
  .filter((model) => typeof model.provider === "string" && typeof model.model === "string")
@@ -141,9 +165,10 @@ export async function activeModels(fetchImpl = fetch) {
141
165
  }
142
166
 
143
167
  export async function buildActiveCatalog(options = {}) {
168
+ const codexCatalogFile = options.codexCatalogFile || configuredCodexCatalogFile();
144
169
  return normalizeActiveCatalog(
145
170
  configuredModels(options.ocxBin),
146
- await activeModels(options.fetchImpl),
147
- options.fastModelIds || priorityModelIds(options.codexCatalogFile),
171
+ [...await activeModels(options.fetchImpl), ...codexNativeModels(codexCatalogFile)],
172
+ options.fastModelIds || priorityModelIds(codexCatalogFile),
148
173
  );
149
174
  }
@@ -15,6 +15,14 @@ import {
15
15
  export const cursorPatchMarker = "/*ocx-cursor-model-metadata-v6*/";
16
16
  export const legacyCursorPatchMarker = "/*ocx-cursor-model-metadata*/";
17
17
  export const cursorByokRoutingPatchMarker = "/*ocx-cursor-byok-model-routing-v1*/";
18
+ export const cursorSubagentModelsPatchMarker = "/*ocx-cursor-subagent-models-v1*/";
19
+ export const cursorSubagentCredentialsPatchMarker = "/*ocx-cursor-subagent-credentials-v1*/";
20
+ export const cursorSubagentLegacyDetailsPatchMarker = "/*ocx-cursor-subagent-legacy-details-v1*/";
21
+ export const cursorSubagentPromptRoutingPatchMarker = "/*ocx-cursor-subagent-prompt-routing-v3*/";
22
+ export const cursorSubagentExecutionRoutingPatchMarker = "/*ocx-cursor-subagent-execution-routing-v5*/";
23
+ export const cursorSubagentRunRoutingPatchMarker = "/*ocx-cursor-subagent-run-routing-v1*/";
24
+ export const cursorSubagentRuntimeCredentialsPatchMarker = "/*ocx-cursor-subagent-runtime-credentials-v1*/";
25
+ export const cursorRoutedSubagentTypesPatchMarker = "/*ocx-cursor-hide-routed-subagent-types-v1*/";
18
26
  export const cursorLocalModeDisabled = "localMode:!1";
19
27
  export const cursorLocalModeEnabled = "localMode:!0";
20
28
  export const cursorLocalRuntimePatchMarker = "/*ocx-cursor-local-model-display-v2*/";
@@ -29,6 +37,25 @@ export function isCursorModelMetadataBundle(file) {
29
37
  const catalogNormalization = /(?<normalization>\b(?<catalog>[A-Za-z_$][\w$]*)=\k<catalog>\.map\((?<item>[A-Za-z_$][\w$]*)=>(?<plain>[A-Za-z_$][\w$]*)\(\k<item>\)\)),(?=(?<batch>[A-Za-z_$][\w$]*)\(\(\)=>\{this\._reactiveStorageService\.setApplicationUserPersistentStorage\("availableDefaultModels2",\k<catalog>\))/g;
30
38
  const previousCatalogInjection = /\/\*ocx-cursor-model-metadata(?:-v[2-5])?\*\/(?<catalog>[A-Za-z_$][\w$]*)=[\s\S]*?,(?=(?<batch>[A-Za-z_$][\w$]*)\(\(\)=>\{this\._reactiveStorageService\.setApplicationUserPersistentStorage\("availableDefaultModels2",\k<catalog>\))/g;
31
39
  const byokModelRouting = /function (?<functionName>[A-Za-z_$][\w$]*)\((?<model>[A-Za-z_$][\w$]*),(?<settings>[A-Za-z_$][\w$]*)\)\{return (?<isClaude>[A-Za-z_$][\w$]*)\(\k<model>\)\?\k<settings>\.useClaudeKey\?"anthropic":void 0:(?<isGemini>[A-Za-z_$][\w$]*)\(\k<model>\)\?\k<settings>\.useGoogleKey\?"google":void 0:\k<settings>\.useOpenAIKey\?"openai":void 0\}/g;
40
+ const explicitSubagentModelFilter = /function (?<functionName>[A-Za-z_$][\w$]*)\((?<model>[A-Za-z_$][\w$]*),(?<isUserAdded>[A-Za-z_$][\w$]*),(?<storage>[A-Za-z_$][\w$]*)\)\{return \k<isUserAdded>===!0\?!0:(?<hasProviderOverride>[A-Za-z_$][\w$]*)\(\k<storage>\)\|\|(?<usesByok>[A-Za-z_$][\w$]*)\(\k<model>,\k<storage>\)\}(?=function [A-Za-z_$][\w$]*\([A-Za-z_$][\w$]*\)\{const\{modelDetails:)/g;
41
+ const explicitSubagentModelSelection = /function (?<functionName>[A-Za-z_$][\w$]*)\((?<input>[A-Za-z_$][\w$]*)\)\{const\{modelDetails:(?<modelDetails>[A-Za-z_$][\w$]*),flagEnabled:(?<flagEnabled>[A-Za-z_$][\w$]*),availableModels:(?<availableModels>[A-Za-z_$][\w$]*),storage:(?<storage>[A-Za-z_$][\w$]*),resolveModelParametersForSubmission:(?<resolveParameters>[A-Za-z_$][\w$]*)\}=\k<input>,(?<maxMode>[A-Za-z_$][\w$]*)=\k<modelDetails>\.maxMode===!0;/g;
42
+ const explicitSubagentRequestedModel = /new (?<requestedModelType>[A-Za-z_$][\w$]*)\(\{modelId:(?<model>[A-Za-z_$][\w$]*)\.name,maxMode:(?<maxMode>[A-Za-z_$][\w$]*),parameters:(?<parameters>[A-Za-z_$][\w$]*)\.map\((?<parameter>[A-Za-z_$][\w$]*)=>new (?<parameterType>[A-Za-z_$][\w$]*)\(\{id:\k<parameter>\.id,value:\k<parameter>\.value\}\)\)\}\)(?=\}\)\}\})/g;
43
+ const explicitSubagentSelectionCall = /getSelectedSubagentModelSelections\((?<modelDetails>[A-Za-z_$][\w$]*)\)\{return (?<selector>[A-Za-z_$][\w$]*)\(\{modelDetails:\k<modelDetails>,flagEnabled:(?<featureGate>[\s\S]*?),availableModels:this\.modelConfigService\.getAvailableDefaultModels\(\),storage:this\.reactiveStorageService\.applicationUserPersistentStorage,resolveModelParametersForSubmission:\((?<model>[A-Za-z_$][\w$]*),(?<maxMode>[A-Za-z_$][\w$]*)\)=>this\.modelConfigService\.resolveModelParametersForSubmission\(\k<model>,void 0,\k<maxMode>\)\}\)\}/g;
44
+ const agentModelDetailsType = /(?<type>[A-Za-z_$][\w$]*)=[A-Za-z_$][\w$]*\.makeMessageType\("agent\.v1\.ModelDetails"/g;
45
+ const selectedSubagentLegacyDetails = /selectedSubagentModelDetails:(?<options>[A-Za-z_$][\w$]*)\.selectedSubagentModelsLegacy/g;
46
+ const agentCustomSystemPrompt = /customSystemPrompt:(?<options>[A-Za-z_$][\w$]*)\.customSystemPrompt(?=,harness:)/g;
47
+ const agentRequestAction = /(?<prefix>conversationState:[A-Za-z_$][\w$]*\([A-Za-z_$][\w$]*\),action:)(?<action>[A-Za-z_$][\w$]*)(?=,modelDetails:)/g;
48
+ const legacySubagentPromptRouting = /customSystemPrompt:\(\(\)=>\{\/\*ocx-cursor-subagent-prompt-routing-v1\*\/const ocxCursorModelIds=\((?<options>[A-Za-z_$][\w$]*)\.selectedSubagentModels[\s\S]*?\}\)\(\)(?=,harness:)/g;
49
+ const legacySubagentRequestRouting = /(?<prefix>conversationState:[A-Za-z_$][\w$]*\([A-Za-z_$][\w$]*\),action:)\(\(\)=>\{\/\*ocx-cursor-subagent-prompt-routing-v2\*\/[\s\S]*?return (?<action>[A-Za-z_$][\w$]*)\}\)\(\)(?=,modelDetails:)/g;
50
+ const createOrResumeSubagentStart = /async createOrResumeSubagent\((?<input>[A-Za-z_$][\w$]*)\)\{/g;
51
+ const legacySubagentExecutionRouting = /(?<start>async createOrResumeSubagent\((?<input>[A-Za-z_$][\w$]*)\)\{)\/\*ocx-cursor-subagent-execution-routing-v[1-4]\*\/[\s\S]*?(?=let [A-Za-z_$][\w$]*,[A-Za-z_$][\w$]*=\k<input>\.resumeAgentId;)/g;
52
+ const legacySubagentModelConfigFixup = /(?<fixup>[A-Za-z_$][\w$]*)=ocxCursorRequestedModel\?void 0:typeof this\._modelConfigService\.fixupModelConfigForCurrentFlag=="function"\?this\._modelConfigService\.fixupModelConfigForCurrentFlag\(\{modelName:(?<input>[A-Za-z_$][\w$]*)\.modelId,maxMode:(?<composerConfig>[A-Za-z_$][\w$]*)\.maxMode===!0\}\):void 0/g;
53
+ const subagentModelConfigFixup = /(?<fixup>[A-Za-z_$][\w$]*)=typeof this\._modelConfigService\.fixupModelConfigForCurrentFlag=="function"\?this\._modelConfigService\.fixupModelConfigForCurrentFlag\(\{modelName:(?<input>[A-Za-z_$][\w$]*)\.modelId,maxMode:(?<composerConfig>[A-Za-z_$][\w$]*)\.maxMode===!0\}\):void 0/g;
54
+ const appendSubagentComposer = /(?<declaration>const (?<result>[A-Za-z_$][\w$]*)=await this\._composerDataService\.appendSubComposer\((?<composer>[A-Za-z_$][\w$]*)\))/g;
55
+ const runSubagentWithHandle = /async runSubagentWithHandle\((?<input>[A-Za-z_$][\w$]*),(?<handle>[A-Za-z_$][\w$]*)\)\{return this\._runSubagent\(\k<input>,\k<handle>\)\}/g;
56
+ const runSubagentModelConfigFixup = /(?<fixed>[A-Za-z_$][\w$]*)=\(typeof this\._modelConfigService\.fixupModelConfigForCurrentFlag=="function"\?this\._modelConfigService\.fixupModelConfigForCurrentFlag\(\{modelName:(?<resolved>[A-Za-z_$][\w$]*),maxMode:(?<maxMode>[A-Za-z_$][\w$]*)\}\):void 0\)\?\.selectedModels\?\?\[\],(?<stored>[A-Za-z_$][\w$]*)=(?<config>[A-Za-z_$][\w$]*)\?\.selectedModels\?\?\[\]/g;
57
+ const requestedModelCredentials = /(?<prefix>new [A-Za-z_$][\w$]*\(\{modelId:(?<model>[A-Za-z_$][\w$]*),maxMode:(?<details>[A-Za-z_$][\w$]*)\.maxMode,parameters:[\s\S]*?,credentials:)this\.convertModelDetailsToCredentials\(\k<details>\)(?<suffix>\}\))(?=\}convertModelDetailsToCredentials)/g;
58
+ const rawSubagentLoad = /(?<raw>[A-Za-z_$][\w$]*)=this\.subagentsService\.peekRawSubagents\(\)/g;
32
59
  const localModelConstructor = /function (?<functionName>[A-Za-z_$][\w$]*)\(e,t\)\{return new (?<modelType>[A-Za-z_$][\w$]*\.[A-Za-z_$][\w$]*)\(\{modelId:e,displayModelId:e,displayName:null!=t\?t:e,displayNameShort:null!=t\?t:e,aliases:\[\]\}\)\}/g;
33
60
  const localRuntimeVisionCapability = /"boolean"==typeof (?<object>[A-Za-z_$][\w$]*)\.supports_vision\?\{supports_vision:\k<object>\.supports_vision\}:\{\}\)/g;
34
61
  const localRuntimePickerInput = /toPickerInput\((?<model>[A-Za-z_$][\w$]*)\)\{var [A-Za-z_$][\w$]*;const [A-Za-z_$][\w$]*=this\.modelMetadataById\.get\(\k<model>\.modelId\),(?<capabilities>[A-Za-z_$][\w$]*)=.*?;return\{.*?supportsReasoning:[^,]+,supportsVision:/g;
@@ -120,12 +147,145 @@ export function patchCursorByokModelRoutingSource(source) {
120
147
  return { status: "patched", source: patched };
121
148
  }
122
149
 
150
+ export function patchCursorExplicitSubagentModelsSource(source) {
151
+ if (source.includes(cursorSubagentModelsPatchMarker)) return { status: "already-patched", source };
152
+ const patched = replaceSingleMatch(source, explicitSubagentModelFilter, (match) => {
153
+ const { functionName, model, isUserAdded, storage, hasProviderOverride, usesByok } = match.groups;
154
+ return `function ${functionName}(${model},${isUserAdded},${storage}){${cursorSubagentModelsPatchMarker}return ${model}.startsWith("opencodex/")?!1:${isUserAdded}===!0?!0:${hasProviderOverride}(${storage})||${usesByok}(${model},${storage})}`;
155
+ }, "explicit subagent model filter");
156
+ return { status: "patched", source: patched };
157
+ }
158
+
159
+ export function patchCursorSubagentCredentialsSource(source) {
160
+ if (source.includes(cursorSubagentCredentialsPatchMarker)) return { status: "already-patched", source };
161
+ let patched = replaceSingleMatch(source, explicitSubagentModelSelection, (match) => {
162
+ const { functionName, input, modelDetails, flagEnabled, availableModels, storage, resolveParameters, maxMode } = match.groups;
163
+ return `function ${functionName}(${input}){${cursorSubagentCredentialsPatchMarker}const{modelDetails:${modelDetails},flagEnabled:${flagEnabled},availableModels:${availableModels},storage:${storage},resolveModelParametersForSubmission:${resolveParameters},resolveCredentialsForSubmission:ocxCursorResolveCredentials}=${input},${maxMode}=${modelDetails}.maxMode===!0;`;
164
+ }, "explicit subagent selection hook");
165
+ patched = replaceSingleMatch(patched, explicitSubagentRequestedModel, (match) => {
166
+ const { requestedModelType, model, maxMode, parameters, parameter, parameterType } = match.groups;
167
+ return `new ${requestedModelType}({modelId:${model}.name,maxMode:${maxMode},credentials:ocxCursorResolveCredentials?.(${model}.name),parameters:${parameters}.map(${parameter}=>new ${parameterType}({id:${parameter}.id,value:${parameter}.value}))})`;
168
+ }, "explicit subagent requested model");
169
+ patched = replaceSingleMatch(patched, explicitSubagentSelectionCall, (match) => {
170
+ const { modelDetails, selector, featureGate, model, maxMode } = match.groups;
171
+ return `getSelectedSubagentModelSelections(${modelDetails}){return ${selector}({modelDetails:${modelDetails},flagEnabled:${featureGate},availableModels:this.modelConfigService.getAvailableDefaultModels(),storage:this.reactiveStorageService.applicationUserPersistentStorage,resolveModelParametersForSubmission:(${model},${maxMode})=>this.modelConfigService.resolveModelParametersForSubmission(${model},void 0,${maxMode}),resolveCredentialsForSubmission:ocxCursorModel=>ocxCursorModel.startsWith("opencodex/")?this.convertModelDetailsToCredentials({apiKey:this.cursorAuthenticationService.openAIKey()??void 0,openaiApiBaseUrl:this.reactiveStorageService.applicationUserPersistentStorage.openAIBaseUrl}):void 0})}`;
172
+ }, "explicit subagent selection caller");
173
+ return { status: "patched", source: patched };
174
+ }
175
+
176
+ export function patchCursorSubagentLegacyDetailsSource(source) {
177
+ if (source.includes(cursorSubagentLegacyDetailsPatchMarker)) return { status: "already-patched", source };
178
+ const modelDetailsMatches = [...source.matchAll(agentModelDetailsType)];
179
+ if (modelDetailsMatches.length !== 1) {
180
+ throw new Error(`Expected one Cursor agent model details type, found ${modelDetailsMatches.length}`);
181
+ }
182
+ const modelDetailsType = modelDetailsMatches[0].groups.type;
183
+ const patched = replaceSingleMatch(source, selectedSubagentLegacyDetails, (match) => {
184
+ const { options } = match.groups;
185
+ return `selectedSubagentModelDetails:${cursorSubagentLegacyDetailsPatchMarker}${options}.selectedSubagentModelsLegacy?.length?${options}.selectedSubagentModelsLegacy:${options}.selectedSubagentModels?.filter(ocxCursorModel=>ocxCursorModel.modelId.startsWith("opencodex/")).map(ocxCursorModel=>new ${modelDetailsType}({modelId:ocxCursorModel.modelId,displayModelId:ocxCursorModel.modelId,displayName:ocxCursorModel.modelId,displayNameShort:ocxCursorModel.modelId,aliases:[],maxMode:ocxCursorModel.maxMode,credentials:ocxCursorModel.credentials}))`;
186
+ }, "legacy explicit subagent model details");
187
+ return { status: "patched", source: patched };
188
+ }
189
+
190
+ export function patchCursorSubagentPromptRoutingSource(source) {
191
+ if (source.includes(cursorSubagentPromptRoutingPatchMarker)) return { status: "already-patched", source };
192
+ let restored = source;
193
+ if (restored.includes("/*ocx-cursor-subagent-prompt-routing-v1*/")) {
194
+ restored = replaceSingleMatch(restored, legacySubagentPromptRouting, (match) => {
195
+ return `customSystemPrompt:${match.groups.options}.customSystemPrompt`;
196
+ }, "legacy subagent prompt routing");
197
+ }
198
+ if (restored.includes("/*ocx-cursor-subagent-prompt-routing-v2*/")) {
199
+ restored = replaceSingleMatch(restored, legacySubagentRequestRouting, (match) => {
200
+ return `${match.groups.prefix}${match.groups.action}`;
201
+ }, "legacy subagent request routing");
202
+ }
203
+ const promptMatches = [...restored.matchAll(agentCustomSystemPrompt)];
204
+ if (promptMatches.length !== 1) {
205
+ throw new Error(`Expected one Cursor custom system prompt field, found ${promptMatches.length}`);
206
+ }
207
+ const options = promptMatches[0].groups.options;
208
+ const patched = replaceSingleMatch(restored, agentRequestAction, (match) => {
209
+ const { prefix, action } = match.groups;
210
+ return `${prefix}(()=>{${cursorSubagentPromptRoutingPatchMarker}const ocxCursorUserMessage=${action}.action.case==="userMessageAction"?${action}.action.value.userMessage:void 0;if(ocxCursorUserMessage){const ocxCursorModelIds=(${options}.selectedSubagentModels??[]).map(ocxCursorModel=>ocxCursorModel.modelId).filter(ocxCursorModelId=>ocxCursorModelId.startsWith("opencodex/")),ocxCursorRequestedModel=ocxCursorModelIds.find(ocxCursorModelId=>ocxCursorUserMessage.text?.includes(ocxCursorModelId)||ocxCursorUserMessage.richText?.includes(ocxCursorModelId));if(ocxCursorRequestedModel){for(const ocxCursorField of["text","richText"])typeof ocxCursorUserMessage[ocxCursorField]==="string"&&(ocxCursorUserMessage[ocxCursorField]=ocxCursorUserMessage[ocxCursorField].split(ocxCursorRequestedModel).join("composer-2.5"));ocxCursorUserMessage.text+=("\\n\\nLocal routing requirement: when calling the Subagent tool, its prompt must begin exactly with <ocx-subagent-model>"+ocxCursorRequestedModel+"</ocx-subagent-model>. Preserve this marker exactly.")}}return ${action}})()`;
211
+ }, "agent request action");
212
+ return { status: "patched", source: patched };
213
+ }
214
+
215
+ export function patchCursorSubagentExecutionRoutingSource(source) {
216
+ if (source.includes(cursorSubagentExecutionRoutingPatchMarker)) return { status: "already-patched", source };
217
+ let restored = source;
218
+ if (restored.includes("/*ocx-cursor-subagent-execution-routing-v4*/")) {
219
+ restored = replaceSingleMatch(restored, legacySubagentModelConfigFixup, (match) => {
220
+ const { fixup, input, composerConfig } = match.groups;
221
+ return `${fixup}=typeof this._modelConfigService.fixupModelConfigForCurrentFlag=="function"?this._modelConfigService.fixupModelConfigForCurrentFlag({modelName:${input}.modelId,maxMode:${composerConfig}.maxMode===!0}):void 0`;
222
+ }, "legacy subagent model config fixup");
223
+ }
224
+ if (restored.includes("/*ocx-cursor-subagent-execution-routing-v1*/") || restored.includes("/*ocx-cursor-subagent-execution-routing-v2*/") || restored.includes("/*ocx-cursor-subagent-execution-routing-v3*/") || restored.includes("/*ocx-cursor-subagent-execution-routing-v4*/")) {
225
+ restored = replaceSingleMatch(restored, legacySubagentExecutionRouting, (match) => match.groups.start, "legacy subagent execution routing");
226
+ }
227
+ let patched = replaceSingleMatch(restored, createOrResumeSubagentStart, (match) => {
228
+ const { input } = match.groups;
229
+ return `${match[0]}${cursorSubagentExecutionRoutingPatchMarker}const ocxCursorModelMarker=typeof ${input}.prompt==="string"?/^\\s*<ocx-subagent-model>(opencodex\\/[A-Za-z0-9._\\/-]+)<\\/ocx-subagent-model>\\s*/.exec(${input}.prompt):null,ocxCursorRequestedModel=ocxCursorModelMarker?.[1];if(ocxCursorRequestedModel&&!${input}.resumeAgentId){const ocxCursorModelAvailable=this._modelConfigService.getAvailableDefaultModels().some(ocxCursorModel=>ocxCursorModel?.name===ocxCursorRequestedModel);if(!ocxCursorModelAvailable)throw new Error("OpenCodex subagent model is unavailable: "+ocxCursorRequestedModel);${input}={...${input},modelId:ocxCursorRequestedModel}}if(ocxCursorModelMarker)${input}={...${input},prompt:${input}.prompt.slice(ocxCursorModelMarker[0].length)};`;
230
+ }, "subagent execution entrypoint");
231
+ patched = replaceSingleMatch(patched, subagentModelConfigFixup, (match) => {
232
+ const { fixup, input, composerConfig } = match.groups;
233
+ return `${fixup}=ocxCursorRequestedModel?void 0:typeof this._modelConfigService.fixupModelConfigForCurrentFlag=="function"?this._modelConfigService.fixupModelConfigForCurrentFlag({modelName:${input}.modelId,maxMode:${composerConfig}.maxMode===!0}):void 0`;
234
+ }, "subagent model config fixup");
235
+ patched = replaceSingleMatch(patched, appendSubagentComposer, (match) => {
236
+ const { declaration, composer } = match.groups;
237
+ return `ocxCursorRequestedModel&&(${composer}.modelConfig={modelName:ocxCursorRequestedModel,maxMode:${composer}.modelConfig?.maxMode===!0,selectedModels:[{modelId:ocxCursorRequestedModel,parameters:[]}]});${declaration}`;
238
+ }, "final subagent model config");
239
+ return { status: "patched", source: patched };
240
+ }
241
+
242
+ export function patchCursorSubagentRunRoutingSource(source) {
243
+ if (source.includes(cursorSubagentRunRoutingPatchMarker)) return { status: "already-patched", source };
244
+ let patched = replaceSingleMatch(source, runSubagentWithHandle, (match) => {
245
+ const { input, handle } = match.groups;
246
+ return `async runSubagentWithHandle(${input},${handle}){${cursorSubagentRunRoutingPatchMarker}const ocxCursorStoredModel=${handle}.data.modelConfig?.modelName;return this._runSubagent(ocxCursorStoredModel?.startsWith("opencodex/")?{...${input},modelId:ocxCursorStoredModel}:${input},${handle})}`;
247
+ }, "subagent run input");
248
+ patched = replaceSingleMatch(patched, runSubagentModelConfigFixup, (match) => {
249
+ const { fixed, resolved, maxMode, stored, config } = match.groups;
250
+ return `${fixed}=${resolved}.startsWith("opencodex/")?${config}?.selectedModels??[]:(typeof this._modelConfigService.fixupModelConfigForCurrentFlag=="function"?this._modelConfigService.fixupModelConfigForCurrentFlag({modelName:${resolved},maxMode:${maxMode}}):void 0)?.selectedModels??[],${stored}=${config}?.selectedModels??[]`;
251
+ }, "subagent run model config");
252
+ return { status: "patched", source: patched };
253
+ }
254
+
255
+ export function patchCursorSubagentRuntimeCredentialsSource(source) {
256
+ if (source.includes(cursorSubagentRuntimeCredentialsPatchMarker)) return { status: "already-patched", source };
257
+ const patched = replaceSingleMatch(source, requestedModelCredentials, (match) => {
258
+ const { prefix, model, details, suffix } = match.groups;
259
+ return `${prefix}${cursorSubagentRuntimeCredentialsPatchMarker}${model}.startsWith("opencodex/")?this.convertModelDetailsToCredentials({apiKey:this.cursorAuthenticationService.openAIKey()??void 0,openaiApiBaseUrl:this.reactiveStorageService.applicationUserPersistentStorage.openAIBaseUrl}):this.convertModelDetailsToCredentials(${details})${suffix}`;
260
+ }, "subagent runtime credentials");
261
+ return { status: "patched", source: patched };
262
+ }
263
+
264
+ export function patchCursorRoutedSubagentTypesSource(source) {
265
+ if (source.includes(cursorRoutedSubagentTypesPatchMarker)) return { status: "already-patched", source };
266
+ const patched = replaceSingleMatch(source, rawSubagentLoad, (match) => {
267
+ const { raw } = match.groups;
268
+ return `${raw}=this.subagentsService.peekRawSubagents()?.filter(ocxCursorSubagent=>{${cursorRoutedSubagentTypesPatchMarker}const ocxCursorPrompt=ocxCursorSubagent?.prompt;return!ocxCursorPrompt?.includes("generated-by: opencodex")&&!ocxCursorPrompt?.includes("generated-by: ocx-cursor")})`;
269
+ }, "custom subagent loader");
270
+ return { status: "patched", source: patched };
271
+ }
272
+
123
273
  export function patchCursorWorkbenchSource(source) {
124
274
  const metadata = patchCursorModelMetadataSource(source);
125
275
  const routing = patchCursorByokModelRoutingSource(metadata.source);
276
+ const subagents = patchCursorExplicitSubagentModelsSource(routing.source);
277
+ const credentials = patchCursorSubagentCredentialsSource(subagents.source);
278
+ const legacyDetails = patchCursorSubagentLegacyDetailsSource(credentials.source);
279
+ const promptRouting = patchCursorSubagentPromptRoutingSource(legacyDetails.source);
280
+ const executionRouting = patchCursorSubagentExecutionRoutingSource(promptRouting.source);
281
+ const runRouting = patchCursorSubagentRunRoutingSource(executionRouting.source);
282
+ const runtimeCredentials = patchCursorSubagentRuntimeCredentialsSource(runRouting.source);
283
+ const subagentTypes = patchCursorRoutedSubagentTypesSource(runtimeCredentials.source);
126
284
  return {
127
- status: metadata.status === "patched" || routing.status === "patched" ? "patched" : "already-patched",
128
- source: routing.source,
285
+ status: metadata.status === "patched" || routing.status === "patched" || subagents.status === "patched" || credentials.status === "patched" || legacyDetails.status === "patched" || promptRouting.status === "patched" || executionRouting.status === "patched" || runRouting.status === "patched" || runtimeCredentials.status === "patched" || subagentTypes.status === "patched"
286
+ ? "patched"
287
+ : "already-patched",
288
+ source: subagentTypes.source,
129
289
  };
130
290
  }
131
291