ocx-cursor 1.0.4 → 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 +1 -1
- package/package.json +1 -1
- package/src/cursor-patch.mjs +162 -2
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
package/src/cursor-patch.mjs
CHANGED
|
@@ -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"
|
|
128
|
-
|
|
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
|
|