oh-my-opencode 3.1.8 → 3.1.10
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.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.zh-cn.md +1 -1
- package/dist/agents/atlas.d.ts +3 -0
- package/dist/agents/explore.d.ts +3 -0
- package/dist/agents/librarian.d.ts +3 -0
- package/dist/agents/metis.d.ts +3 -0
- package/dist/agents/momus.d.ts +4 -1
- package/dist/agents/multimodal-looker.d.ts +3 -0
- package/dist/agents/oracle.d.ts +3 -0
- package/dist/agents/sisyphus-junior.d.ts +3 -0
- package/dist/agents/sisyphus.d.ts +3 -0
- package/dist/agents/types.d.ts +14 -1
- package/dist/cli/index.js +99 -42
- package/dist/cli/types.d.ts +3 -0
- package/dist/config/schema.d.ts +1 -0
- package/dist/index.js +579 -458
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/model-availability.d.ts +9 -1
- package/dist/shared/model-requirements.d.ts +1 -0
- package/dist/shared/model-resolver.d.ts +2 -1
- package/dist/shared/model-suggestion-retry.d.ts +24 -0
- package/dist/shared/model-suggestion-retry.test.d.ts +1 -0
- package/dist/tools/delegate-task/constants.d.ts +2 -1
- package/dist/tools/delegate-task/tools.d.ts +1 -0
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -58,15 +58,40 @@ var init_constants = __esm(() => {
|
|
|
58
58
|
PART_STORAGE = join2(OPENCODE_STORAGE, "part");
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
// src/shared/logger.ts
|
|
62
|
+
var exports_logger = {};
|
|
63
|
+
__export(exports_logger, {
|
|
64
|
+
log: () => log,
|
|
65
|
+
getLogFilePath: () => getLogFilePath
|
|
66
|
+
});
|
|
67
|
+
import * as fs from "fs";
|
|
68
|
+
import * as os2 from "os";
|
|
69
|
+
import * as path2 from "path";
|
|
70
|
+
function log(message, data) {
|
|
71
|
+
try {
|
|
72
|
+
const timestamp = new Date().toISOString();
|
|
73
|
+
const logEntry = `[${timestamp}] ${message} ${data ? JSON.stringify(data) : ""}
|
|
74
|
+
`;
|
|
75
|
+
fs.appendFileSync(logFile, logEntry);
|
|
76
|
+
} catch {}
|
|
77
|
+
}
|
|
78
|
+
function getLogFilePath() {
|
|
79
|
+
return logFile;
|
|
80
|
+
}
|
|
81
|
+
var logFile;
|
|
82
|
+
var init_logger = __esm(() => {
|
|
83
|
+
logFile = path2.join(os2.tmpdir(), "oh-my-opencode.log");
|
|
84
|
+
});
|
|
85
|
+
|
|
61
86
|
// src/features/hook-message-injector/injector.ts
|
|
62
87
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "fs";
|
|
63
|
-
import { join as
|
|
88
|
+
import { join as join4 } from "path";
|
|
64
89
|
function findNearestMessageWithFields(messageDir) {
|
|
65
90
|
try {
|
|
66
91
|
const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
67
92
|
for (const file of files) {
|
|
68
93
|
try {
|
|
69
|
-
const content = readFileSync(
|
|
94
|
+
const content = readFileSync(join4(messageDir, file), "utf-8");
|
|
70
95
|
const msg = JSON.parse(content);
|
|
71
96
|
if (msg.agent && msg.model?.providerID && msg.model?.modelID) {
|
|
72
97
|
return msg;
|
|
@@ -77,7 +102,7 @@ function findNearestMessageWithFields(messageDir) {
|
|
|
77
102
|
}
|
|
78
103
|
for (const file of files) {
|
|
79
104
|
try {
|
|
80
|
-
const content = readFileSync(
|
|
105
|
+
const content = readFileSync(join4(messageDir, file), "utf-8");
|
|
81
106
|
const msg = JSON.parse(content);
|
|
82
107
|
if (msg.agent || msg.model?.providerID && msg.model?.modelID) {
|
|
83
108
|
return msg;
|
|
@@ -96,7 +121,7 @@ function findFirstMessageWithAgent(messageDir) {
|
|
|
96
121
|
const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort();
|
|
97
122
|
for (const file of files) {
|
|
98
123
|
try {
|
|
99
|
-
const content = readFileSync(
|
|
124
|
+
const content = readFileSync(join4(messageDir, file), "utf-8");
|
|
100
125
|
const msg = JSON.parse(content);
|
|
101
126
|
if (msg.agent) {
|
|
102
127
|
return msg.agent;
|
|
@@ -124,12 +149,12 @@ function getOrCreateMessageDir(sessionID) {
|
|
|
124
149
|
if (!existsSync(MESSAGE_STORAGE)) {
|
|
125
150
|
mkdirSync(MESSAGE_STORAGE, { recursive: true });
|
|
126
151
|
}
|
|
127
|
-
const directPath =
|
|
152
|
+
const directPath = join4(MESSAGE_STORAGE, sessionID);
|
|
128
153
|
if (existsSync(directPath)) {
|
|
129
154
|
return directPath;
|
|
130
155
|
}
|
|
131
156
|
for (const dir of readdirSync(MESSAGE_STORAGE)) {
|
|
132
|
-
const sessionPath =
|
|
157
|
+
const sessionPath = join4(MESSAGE_STORAGE, dir, sessionID);
|
|
133
158
|
if (existsSync(sessionPath)) {
|
|
134
159
|
return sessionPath;
|
|
135
160
|
}
|
|
@@ -139,7 +164,7 @@ function getOrCreateMessageDir(sessionID) {
|
|
|
139
164
|
}
|
|
140
165
|
function injectHookMessage(sessionID, hookContent, originalMessage) {
|
|
141
166
|
if (!hookContent || hookContent.trim().length === 0) {
|
|
142
|
-
|
|
167
|
+
log("[hook-message-injector] Attempted to inject empty hook content, skipping injection", {
|
|
143
168
|
sessionID,
|
|
144
169
|
hasAgent: !!originalMessage.agent,
|
|
145
170
|
hasModel: !!(originalMessage.model?.providerID && originalMessage.model?.modelID)
|
|
@@ -191,12 +216,12 @@ function injectHookMessage(sessionID, hookContent, originalMessage) {
|
|
|
191
216
|
sessionID
|
|
192
217
|
};
|
|
193
218
|
try {
|
|
194
|
-
writeFileSync(
|
|
195
|
-
const partDir =
|
|
219
|
+
writeFileSync(join4(messageDir, `${messageID}.json`), JSON.stringify(messageMeta, null, 2));
|
|
220
|
+
const partDir = join4(PART_STORAGE, messageID);
|
|
196
221
|
if (!existsSync(partDir)) {
|
|
197
222
|
mkdirSync(partDir, { recursive: true });
|
|
198
223
|
}
|
|
199
|
-
writeFileSync(
|
|
224
|
+
writeFileSync(join4(partDir, `${partID}.json`), JSON.stringify(textPart, null, 2));
|
|
200
225
|
return true;
|
|
201
226
|
} catch {
|
|
202
227
|
return false;
|
|
@@ -204,6 +229,7 @@ function injectHookMessage(sessionID, hookContent, originalMessage) {
|
|
|
204
229
|
}
|
|
205
230
|
var init_injector = __esm(() => {
|
|
206
231
|
init_constants();
|
|
232
|
+
init_logger();
|
|
207
233
|
});
|
|
208
234
|
|
|
209
235
|
// src/features/hook-message-injector/index.ts
|
|
@@ -212,31 +238,6 @@ var init_hook_message_injector = __esm(() => {
|
|
|
212
238
|
init_constants();
|
|
213
239
|
});
|
|
214
240
|
|
|
215
|
-
// src/shared/logger.ts
|
|
216
|
-
var exports_logger = {};
|
|
217
|
-
__export(exports_logger, {
|
|
218
|
-
log: () => log,
|
|
219
|
-
getLogFilePath: () => getLogFilePath
|
|
220
|
-
});
|
|
221
|
-
import * as fs from "fs";
|
|
222
|
-
import * as os2 from "os";
|
|
223
|
-
import * as path2 from "path";
|
|
224
|
-
function log(message, data) {
|
|
225
|
-
try {
|
|
226
|
-
const timestamp = new Date().toISOString();
|
|
227
|
-
const logEntry = `[${timestamp}] ${message} ${data ? JSON.stringify(data) : ""}
|
|
228
|
-
`;
|
|
229
|
-
fs.appendFileSync(logFile, logEntry);
|
|
230
|
-
} catch {}
|
|
231
|
-
}
|
|
232
|
-
function getLogFilePath() {
|
|
233
|
-
return logFile;
|
|
234
|
-
}
|
|
235
|
-
var logFile;
|
|
236
|
-
var init_logger = __esm(() => {
|
|
237
|
-
logFile = path2.join(os2.tmpdir(), "oh-my-opencode.log");
|
|
238
|
-
});
|
|
239
|
-
|
|
240
241
|
// src/shared/system-directive.ts
|
|
241
242
|
function createSystemDirective(type) {
|
|
242
243
|
return `${SYSTEM_DIRECTIVE_PREFIX} - ${type}]`;
|
|
@@ -4848,6 +4849,8 @@ var init_model_requirements = __esm(() => {
|
|
|
4848
4849
|
sisyphus: {
|
|
4849
4850
|
fallbackChain: [
|
|
4850
4851
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4852
|
+
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
4853
|
+
{ providers: ["opencode"], model: "kimi-k2.5-free" },
|
|
4851
4854
|
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
4852
4855
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
4853
4856
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
@@ -4856,14 +4859,14 @@ var init_model_requirements = __esm(() => {
|
|
|
4856
4859
|
oracle: {
|
|
4857
4860
|
fallbackChain: [
|
|
4858
4861
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4859
|
-
{ providers: ["
|
|
4860
|
-
{ providers: ["
|
|
4862
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" },
|
|
4863
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }
|
|
4861
4864
|
]
|
|
4862
4865
|
},
|
|
4863
4866
|
librarian: {
|
|
4864
4867
|
fallbackChain: [
|
|
4865
4868
|
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
4866
|
-
{ providers: ["opencode"], model: "
|
|
4869
|
+
{ providers: ["opencode"], model: "glm-4.7-free" },
|
|
4867
4870
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" }
|
|
4868
4871
|
]
|
|
4869
4872
|
},
|
|
@@ -4879,6 +4882,8 @@ var init_model_requirements = __esm(() => {
|
|
|
4879
4882
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
4880
4883
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
4881
4884
|
{ providers: ["zai-coding-plan"], model: "glm-4.6v" },
|
|
4885
|
+
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
4886
|
+
{ providers: ["opencode"], model: "kimi-k2.5-free" },
|
|
4882
4887
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
4883
4888
|
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
4884
4889
|
]
|
|
@@ -4886,6 +4891,8 @@ var init_model_requirements = __esm(() => {
|
|
|
4886
4891
|
prometheus: {
|
|
4887
4892
|
fallbackChain: [
|
|
4888
4893
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4894
|
+
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
4895
|
+
{ providers: ["opencode"], model: "kimi-k2.5-free" },
|
|
4889
4896
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4890
4897
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4891
4898
|
]
|
|
@@ -4893,6 +4900,8 @@ var init_model_requirements = __esm(() => {
|
|
|
4893
4900
|
metis: {
|
|
4894
4901
|
fallbackChain: [
|
|
4895
4902
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4903
|
+
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
4904
|
+
{ providers: ["opencode"], model: "kimi-k2.5-free" },
|
|
4896
4905
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4897
4906
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
4898
4907
|
]
|
|
@@ -4900,12 +4909,14 @@ var init_model_requirements = __esm(() => {
|
|
|
4900
4909
|
momus: {
|
|
4901
4910
|
fallbackChain: [
|
|
4902
4911
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "medium" },
|
|
4903
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5" },
|
|
4912
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4904
4913
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
4905
4914
|
]
|
|
4906
4915
|
},
|
|
4907
4916
|
atlas: {
|
|
4908
4917
|
fallbackChain: [
|
|
4918
|
+
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
4919
|
+
{ providers: ["opencode"], model: "kimi-k2.5-free" },
|
|
4909
4920
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
4910
4921
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
4911
4922
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
@@ -4917,22 +4928,31 @@ var init_model_requirements = __esm(() => {
|
|
|
4917
4928
|
fallbackChain: [
|
|
4918
4929
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" },
|
|
4919
4930
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4920
|
-
{ providers: ["
|
|
4931
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" }
|
|
4921
4932
|
]
|
|
4922
4933
|
},
|
|
4923
4934
|
ultrabrain: {
|
|
4924
4935
|
fallbackChain: [
|
|
4925
4936
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "xhigh" },
|
|
4926
|
-
{ providers: ["
|
|
4927
|
-
{ providers: ["
|
|
4937
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" },
|
|
4938
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }
|
|
4928
4939
|
]
|
|
4929
4940
|
},
|
|
4941
|
+
deep: {
|
|
4942
|
+
fallbackChain: [
|
|
4943
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
4944
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4945
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
4946
|
+
],
|
|
4947
|
+
requiresModel: "gpt-5.2-codex"
|
|
4948
|
+
},
|
|
4930
4949
|
artistry: {
|
|
4931
4950
|
fallbackChain: [
|
|
4932
4951
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" },
|
|
4933
4952
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4934
4953
|
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
4935
|
-
]
|
|
4954
|
+
],
|
|
4955
|
+
requiresModel: "gemini-3-pro"
|
|
4936
4956
|
},
|
|
4937
4957
|
quick: {
|
|
4938
4958
|
fallbackChain: [
|
|
@@ -5246,29 +5266,31 @@ async function updateConnectedProvidersCache(client) {
|
|
|
5246
5266
|
const connected = result.data?.connected ?? [];
|
|
5247
5267
|
log("[connected-providers-cache] Fetched connected providers", { count: connected.length, providers: connected });
|
|
5248
5268
|
writeConnectedProvidersCache(connected);
|
|
5269
|
+
let modelsByProvider = {};
|
|
5249
5270
|
if (client.model?.list) {
|
|
5250
5271
|
try {
|
|
5251
5272
|
const modelsResult = await client.model.list();
|
|
5252
5273
|
const models = modelsResult.data ?? [];
|
|
5253
|
-
const modelsByProvider = {};
|
|
5254
5274
|
for (const model of models) {
|
|
5255
5275
|
if (!modelsByProvider[model.provider]) {
|
|
5256
5276
|
modelsByProvider[model.provider] = [];
|
|
5257
5277
|
}
|
|
5258
5278
|
modelsByProvider[model.provider].push(model.id);
|
|
5259
5279
|
}
|
|
5260
|
-
|
|
5261
|
-
models: modelsByProvider,
|
|
5262
|
-
connected
|
|
5263
|
-
});
|
|
5264
|
-
log("[connected-providers-cache] Provider-models cache updated", {
|
|
5280
|
+
log("[connected-providers-cache] Fetched models from API", {
|
|
5265
5281
|
providerCount: Object.keys(modelsByProvider).length,
|
|
5266
5282
|
totalModels: models.length
|
|
5267
5283
|
});
|
|
5268
5284
|
} catch (modelErr) {
|
|
5269
|
-
log("[connected-providers-cache] Error fetching models", { error: String(modelErr) });
|
|
5285
|
+
log("[connected-providers-cache] Error fetching models, writing empty cache", { error: String(modelErr) });
|
|
5270
5286
|
}
|
|
5287
|
+
} else {
|
|
5288
|
+
log("[connected-providers-cache] client.model.list not available, writing empty cache");
|
|
5271
5289
|
}
|
|
5290
|
+
writeProviderModelsCache({
|
|
5291
|
+
models: modelsByProvider,
|
|
5292
|
+
connected
|
|
5293
|
+
});
|
|
5272
5294
|
} catch (err) {
|
|
5273
5295
|
log("[connected-providers-cache] Error updating cache", { error: String(err) });
|
|
5274
5296
|
}
|
|
@@ -5319,68 +5341,142 @@ function fuzzyMatchModel(target, available, providers) {
|
|
|
5319
5341
|
log("[fuzzyMatchModel] shortest match", { result });
|
|
5320
5342
|
return result;
|
|
5321
5343
|
}
|
|
5322
|
-
|
|
5323
|
-
|
|
5344
|
+
function isModelAvailable(targetModel, availableModels) {
|
|
5345
|
+
return fuzzyMatchModel(targetModel, availableModels) !== null;
|
|
5346
|
+
}
|
|
5347
|
+
async function getConnectedProviders(client) {
|
|
5348
|
+
if (!client?.provider?.list) {
|
|
5349
|
+
log("[getConnectedProviders] client.provider.list not available");
|
|
5350
|
+
return [];
|
|
5351
|
+
}
|
|
5352
|
+
try {
|
|
5353
|
+
const result = await client.provider.list();
|
|
5354
|
+
const connected = result.data?.connected ?? [];
|
|
5355
|
+
log("[getConnectedProviders] connected providers", { count: connected.length, providers: connected });
|
|
5356
|
+
return connected;
|
|
5357
|
+
} catch (err) {
|
|
5358
|
+
log("[getConnectedProviders] SDK error", { error: String(err) });
|
|
5359
|
+
return [];
|
|
5360
|
+
}
|
|
5361
|
+
}
|
|
5362
|
+
async function fetchAvailableModels(client, options) {
|
|
5363
|
+
let connectedProviders = options?.connectedProviders ?? null;
|
|
5364
|
+
let connectedProvidersUnknown = connectedProviders === null;
|
|
5324
5365
|
log("[fetchAvailableModels] CALLED", {
|
|
5325
5366
|
connectedProvidersUnknown,
|
|
5326
5367
|
connectedProviders: options?.connectedProviders
|
|
5327
5368
|
});
|
|
5369
|
+
if (connectedProvidersUnknown && client) {
|
|
5370
|
+
const liveConnected = await getConnectedProviders(client);
|
|
5371
|
+
if (liveConnected.length > 0) {
|
|
5372
|
+
connectedProviders = liveConnected;
|
|
5373
|
+
connectedProvidersUnknown = false;
|
|
5374
|
+
log("[fetchAvailableModels] connected providers fetched from client", { count: liveConnected.length });
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5328
5377
|
if (connectedProvidersUnknown) {
|
|
5378
|
+
if (client?.model?.list) {
|
|
5379
|
+
const modelSet2 = new Set;
|
|
5380
|
+
try {
|
|
5381
|
+
const modelsResult = await client.model.list();
|
|
5382
|
+
const models = modelsResult.data ?? [];
|
|
5383
|
+
for (const model of models) {
|
|
5384
|
+
if (model?.provider && model?.id) {
|
|
5385
|
+
modelSet2.add(`${model.provider}/${model.id}`);
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5388
|
+
log("[fetchAvailableModels] fetched models from client without provider filter", {
|
|
5389
|
+
count: modelSet2.size
|
|
5390
|
+
});
|
|
5391
|
+
return modelSet2;
|
|
5392
|
+
} catch (err) {
|
|
5393
|
+
log("[fetchAvailableModels] client.model.list error", { error: String(err) });
|
|
5394
|
+
}
|
|
5395
|
+
}
|
|
5329
5396
|
log("[fetchAvailableModels] connected providers unknown, returning empty set for fallback resolution");
|
|
5330
5397
|
return new Set;
|
|
5331
5398
|
}
|
|
5332
|
-
const
|
|
5333
|
-
const connectedSet = new Set(
|
|
5399
|
+
const connectedProvidersList = connectedProviders ?? [];
|
|
5400
|
+
const connectedSet = new Set(connectedProvidersList);
|
|
5334
5401
|
const modelSet = new Set;
|
|
5335
5402
|
const providerModelsCache = readProviderModelsCache();
|
|
5336
5403
|
if (providerModelsCache) {
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5404
|
+
const providerCount = Object.keys(providerModelsCache.models).length;
|
|
5405
|
+
if (providerCount === 0) {
|
|
5406
|
+
log("[fetchAvailableModels] provider-models cache empty, falling back to models.json");
|
|
5407
|
+
} else {
|
|
5408
|
+
log("[fetchAvailableModels] using provider-models cache (whitelist-filtered)");
|
|
5409
|
+
for (const [providerId, modelIds] of Object.entries(providerModelsCache.models)) {
|
|
5410
|
+
if (!connectedSet.has(providerId)) {
|
|
5411
|
+
continue;
|
|
5412
|
+
}
|
|
5413
|
+
for (const modelId of modelIds) {
|
|
5414
|
+
modelSet.add(`${providerId}/${modelId}`);
|
|
5415
|
+
}
|
|
5341
5416
|
}
|
|
5342
|
-
|
|
5343
|
-
modelSet.
|
|
5417
|
+
log("[fetchAvailableModels] parsed from provider-models cache", {
|
|
5418
|
+
count: modelSet.size,
|
|
5419
|
+
connectedProviders: connectedProvidersList.slice(0, 5)
|
|
5420
|
+
});
|
|
5421
|
+
if (modelSet.size > 0) {
|
|
5422
|
+
return modelSet;
|
|
5344
5423
|
}
|
|
5424
|
+
log("[fetchAvailableModels] provider-models cache produced no models for connected providers, falling back to models.json");
|
|
5345
5425
|
}
|
|
5346
|
-
log("[fetchAvailableModels] parsed from provider-models cache", {
|
|
5347
|
-
count: modelSet.size,
|
|
5348
|
-
connectedProviders: connectedProviders.slice(0, 5)
|
|
5349
|
-
});
|
|
5350
|
-
return modelSet;
|
|
5351
5426
|
}
|
|
5352
5427
|
log("[fetchAvailableModels] provider-models cache not found, falling back to models.json");
|
|
5353
5428
|
const cacheFile = join13(getOpenCodeCacheDir(), "models.json");
|
|
5354
5429
|
if (!existsSync10(cacheFile)) {
|
|
5355
|
-
log("[fetchAvailableModels] models.json cache file not found,
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5430
|
+
log("[fetchAvailableModels] models.json cache file not found, falling back to client");
|
|
5431
|
+
} else {
|
|
5432
|
+
try {
|
|
5433
|
+
const content = readFileSync7(cacheFile, "utf-8");
|
|
5434
|
+
const data = JSON.parse(content);
|
|
5435
|
+
const providerIds = Object.keys(data);
|
|
5436
|
+
log("[fetchAvailableModels] providers found in models.json", { count: providerIds.length, providers: providerIds.slice(0, 10) });
|
|
5437
|
+
for (const providerId of providerIds) {
|
|
5438
|
+
if (!connectedSet.has(providerId)) {
|
|
5439
|
+
continue;
|
|
5440
|
+
}
|
|
5441
|
+
const provider = data[providerId];
|
|
5442
|
+
const models = provider?.models;
|
|
5443
|
+
if (!models || typeof models !== "object")
|
|
5444
|
+
continue;
|
|
5445
|
+
for (const modelKey of Object.keys(models)) {
|
|
5446
|
+
modelSet.add(`${providerId}/${modelKey}`);
|
|
5447
|
+
}
|
|
5366
5448
|
}
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
modelSet
|
|
5449
|
+
log("[fetchAvailableModels] parsed models from models.json (NO whitelist filtering)", {
|
|
5450
|
+
count: modelSet.size,
|
|
5451
|
+
connectedProviders: connectedProvidersList.slice(0, 5)
|
|
5452
|
+
});
|
|
5453
|
+
if (modelSet.size > 0) {
|
|
5454
|
+
return modelSet;
|
|
5373
5455
|
}
|
|
5456
|
+
} catch (err) {
|
|
5457
|
+
log("[fetchAvailableModels] error", { error: String(err) });
|
|
5374
5458
|
}
|
|
5375
|
-
log("[fetchAvailableModels] parsed models from models.json (NO whitelist filtering)", {
|
|
5376
|
-
count: modelSet.size,
|
|
5377
|
-
connectedProviders: connectedProviders.slice(0, 5)
|
|
5378
|
-
});
|
|
5379
|
-
return modelSet;
|
|
5380
|
-
} catch (err) {
|
|
5381
|
-
log("[fetchAvailableModels] error", { error: String(err) });
|
|
5382
|
-
return modelSet;
|
|
5383
5459
|
}
|
|
5460
|
+
if (client?.model?.list) {
|
|
5461
|
+
try {
|
|
5462
|
+
const modelsResult = await client.model.list();
|
|
5463
|
+
const models = modelsResult.data ?? [];
|
|
5464
|
+
for (const model of models) {
|
|
5465
|
+
if (!model?.provider || !model?.id)
|
|
5466
|
+
continue;
|
|
5467
|
+
if (connectedSet.has(model.provider)) {
|
|
5468
|
+
modelSet.add(`${model.provider}/${model.id}`);
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
log("[fetchAvailableModels] fetched models from client (filtered)", {
|
|
5472
|
+
count: modelSet.size,
|
|
5473
|
+
connectedProviders: connectedProvidersList.slice(0, 5)
|
|
5474
|
+
});
|
|
5475
|
+
} catch (err) {
|
|
5476
|
+
log("[fetchAvailableModels] client.model.list error", { error: String(err) });
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5479
|
+
return modelSet;
|
|
5384
5480
|
}
|
|
5385
5481
|
function isModelCacheAvailable() {
|
|
5386
5482
|
if (hasProviderModelsCache()) {
|
|
@@ -5404,7 +5500,7 @@ function resolveModel(input) {
|
|
|
5404
5500
|
return normalizeModel(input.userModel) ?? normalizeModel(input.inheritedModel) ?? input.systemDefault;
|
|
5405
5501
|
}
|
|
5406
5502
|
function resolveModelWithFallback(input) {
|
|
5407
|
-
const { uiSelectedModel, userModel, fallbackChain, availableModels, systemDefaultModel } = input;
|
|
5503
|
+
const { uiSelectedModel, userModel, categoryDefaultModel, fallbackChain, availableModels, systemDefaultModel } = input;
|
|
5408
5504
|
const normalizedUiModel = normalizeModel(uiSelectedModel);
|
|
5409
5505
|
if (normalizedUiModel) {
|
|
5410
5506
|
log("Model resolved via UI selection", { model: normalizedUiModel });
|
|
@@ -5415,6 +5511,33 @@ function resolveModelWithFallback(input) {
|
|
|
5415
5511
|
log("Model resolved via config override", { model: normalizedUserModel });
|
|
5416
5512
|
return { model: normalizedUserModel, source: "override" };
|
|
5417
5513
|
}
|
|
5514
|
+
const normalizedCategoryDefault = normalizeModel(categoryDefaultModel);
|
|
5515
|
+
if (normalizedCategoryDefault) {
|
|
5516
|
+
if (availableModels.size > 0) {
|
|
5517
|
+
const parts = normalizedCategoryDefault.split("/");
|
|
5518
|
+
const providerHint = parts.length >= 2 ? [parts[0]] : undefined;
|
|
5519
|
+
const match = fuzzyMatchModel(normalizedCategoryDefault, availableModels, providerHint);
|
|
5520
|
+
if (match) {
|
|
5521
|
+
log("Model resolved via category default (fuzzy matched)", { original: normalizedCategoryDefault, matched: match });
|
|
5522
|
+
return { model: match, source: "category-default" };
|
|
5523
|
+
}
|
|
5524
|
+
} else {
|
|
5525
|
+
const connectedProviders = readConnectedProvidersCache();
|
|
5526
|
+
if (connectedProviders === null) {
|
|
5527
|
+
log("Model resolved via category default (no cache, first run)", { model: normalizedCategoryDefault });
|
|
5528
|
+
return { model: normalizedCategoryDefault, source: "category-default" };
|
|
5529
|
+
}
|
|
5530
|
+
const parts = normalizedCategoryDefault.split("/");
|
|
5531
|
+
if (parts.length >= 2) {
|
|
5532
|
+
const provider = parts[0];
|
|
5533
|
+
if (connectedProviders.includes(provider)) {
|
|
5534
|
+
log("Model resolved via category default (connected provider)", { model: normalizedCategoryDefault });
|
|
5535
|
+
return { model: normalizedCategoryDefault, source: "category-default" };
|
|
5536
|
+
}
|
|
5537
|
+
}
|
|
5538
|
+
}
|
|
5539
|
+
log("Category default model not available, falling through to fallback chain", { model: normalizedCategoryDefault });
|
|
5540
|
+
}
|
|
5418
5541
|
if (fallbackChain && fallbackChain.length > 0) {
|
|
5419
5542
|
if (availableModels.size === 0) {
|
|
5420
5543
|
const connectedProviders = readConnectedProvidersCache();
|
|
@@ -5426,7 +5549,7 @@ function resolveModelWithFallback(input) {
|
|
|
5426
5549
|
for (const provider of entry.providers) {
|
|
5427
5550
|
if (connectedSet.has(provider)) {
|
|
5428
5551
|
const model = `${provider}/${entry.model}`;
|
|
5429
|
-
log("Model resolved via fallback chain (
|
|
5552
|
+
log("Model resolved via fallback chain (connected provider)", {
|
|
5430
5553
|
provider,
|
|
5431
5554
|
model: entry.model,
|
|
5432
5555
|
variant: entry.variant
|
|
@@ -5437,18 +5560,28 @@ function resolveModelWithFallback(input) {
|
|
|
5437
5560
|
}
|
|
5438
5561
|
log("No connected provider found in fallback chain, falling through to system default");
|
|
5439
5562
|
}
|
|
5440
|
-
}
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5563
|
+
} else {
|
|
5564
|
+
for (const entry of fallbackChain) {
|
|
5565
|
+
for (const provider of entry.providers) {
|
|
5566
|
+
const fullModel = `${provider}/${entry.model}`;
|
|
5567
|
+
const match = fuzzyMatchModel(fullModel, availableModels, [provider]);
|
|
5568
|
+
if (match) {
|
|
5569
|
+
log("Model resolved via fallback chain (availability confirmed)", { provider, model: entry.model, match, variant: entry.variant });
|
|
5570
|
+
return { model: match, source: "provider-fallback", variant: entry.variant };
|
|
5571
|
+
}
|
|
5572
|
+
}
|
|
5573
|
+
const crossProviderMatch = fuzzyMatchModel(entry.model, availableModels);
|
|
5574
|
+
if (crossProviderMatch) {
|
|
5575
|
+
log("Model resolved via fallback chain (cross-provider fuzzy match)", {
|
|
5576
|
+
model: entry.model,
|
|
5577
|
+
match: crossProviderMatch,
|
|
5578
|
+
variant: entry.variant
|
|
5579
|
+
});
|
|
5580
|
+
return { model: crossProviderMatch, source: "provider-fallback", variant: entry.variant };
|
|
5448
5581
|
}
|
|
5449
5582
|
}
|
|
5583
|
+
log("No available model found in fallback chain, falling through to system default");
|
|
5450
5584
|
}
|
|
5451
|
-
log("No available model found in fallback chain, falling through to system default");
|
|
5452
5585
|
}
|
|
5453
5586
|
if (systemDefaultModel === undefined) {
|
|
5454
5587
|
log("No model resolved - systemDefaultModel not configured");
|
|
@@ -5720,6 +5853,92 @@ var init_tmux = __esm(() => {
|
|
|
5720
5853
|
init_tmux_utils();
|
|
5721
5854
|
});
|
|
5722
5855
|
|
|
5856
|
+
// src/shared/model-suggestion-retry.ts
|
|
5857
|
+
function extractMessage(error) {
|
|
5858
|
+
if (typeof error === "string")
|
|
5859
|
+
return error;
|
|
5860
|
+
if (error instanceof Error)
|
|
5861
|
+
return error.message;
|
|
5862
|
+
if (typeof error === "object" && error !== null) {
|
|
5863
|
+
const obj = error;
|
|
5864
|
+
if (typeof obj.message === "string")
|
|
5865
|
+
return obj.message;
|
|
5866
|
+
try {
|
|
5867
|
+
return JSON.stringify(error);
|
|
5868
|
+
} catch {
|
|
5869
|
+
return "";
|
|
5870
|
+
}
|
|
5871
|
+
}
|
|
5872
|
+
return String(error);
|
|
5873
|
+
}
|
|
5874
|
+
function parseModelSuggestion(error) {
|
|
5875
|
+
if (!error)
|
|
5876
|
+
return null;
|
|
5877
|
+
if (typeof error === "object") {
|
|
5878
|
+
const errObj = error;
|
|
5879
|
+
if (errObj.name === "ProviderModelNotFoundError" && typeof errObj.data === "object" && errObj.data !== null) {
|
|
5880
|
+
const data = errObj.data;
|
|
5881
|
+
const suggestions = data.suggestions;
|
|
5882
|
+
if (Array.isArray(suggestions) && suggestions.length > 0 && typeof suggestions[0] === "string") {
|
|
5883
|
+
return {
|
|
5884
|
+
providerID: String(data.providerID ?? ""),
|
|
5885
|
+
modelID: String(data.modelID ?? ""),
|
|
5886
|
+
suggestion: suggestions[0]
|
|
5887
|
+
};
|
|
5888
|
+
}
|
|
5889
|
+
return null;
|
|
5890
|
+
}
|
|
5891
|
+
for (const key of ["data", "error", "cause"]) {
|
|
5892
|
+
const nested = errObj[key];
|
|
5893
|
+
if (nested && typeof nested === "object") {
|
|
5894
|
+
const result = parseModelSuggestion(nested);
|
|
5895
|
+
if (result)
|
|
5896
|
+
return result;
|
|
5897
|
+
}
|
|
5898
|
+
}
|
|
5899
|
+
}
|
|
5900
|
+
const message = extractMessage(error);
|
|
5901
|
+
if (!message)
|
|
5902
|
+
return null;
|
|
5903
|
+
const modelMatch = message.match(/model not found:\s*([^/\s]+)\s*\/\s*([^.\s]+)/i);
|
|
5904
|
+
const suggestionMatch = message.match(/did you mean:\s*([^,?]+)/i);
|
|
5905
|
+
if (modelMatch && suggestionMatch) {
|
|
5906
|
+
return {
|
|
5907
|
+
providerID: modelMatch[1].trim(),
|
|
5908
|
+
modelID: modelMatch[2].trim(),
|
|
5909
|
+
suggestion: suggestionMatch[1].trim()
|
|
5910
|
+
};
|
|
5911
|
+
}
|
|
5912
|
+
return null;
|
|
5913
|
+
}
|
|
5914
|
+
async function promptWithModelSuggestionRetry(client, args) {
|
|
5915
|
+
try {
|
|
5916
|
+
await client.session.prompt(args);
|
|
5917
|
+
} catch (error) {
|
|
5918
|
+
const suggestion = parseModelSuggestion(error);
|
|
5919
|
+
if (!suggestion || !args.body.model) {
|
|
5920
|
+
throw error;
|
|
5921
|
+
}
|
|
5922
|
+
log("[model-suggestion-retry] Model not found, retrying with suggestion", {
|
|
5923
|
+
original: `${suggestion.providerID}/${suggestion.modelID}`,
|
|
5924
|
+
suggested: suggestion.suggestion
|
|
5925
|
+
});
|
|
5926
|
+
await client.session.prompt({
|
|
5927
|
+
...args,
|
|
5928
|
+
body: {
|
|
5929
|
+
...args.body,
|
|
5930
|
+
model: {
|
|
5931
|
+
providerID: suggestion.providerID,
|
|
5932
|
+
modelID: suggestion.suggestion
|
|
5933
|
+
}
|
|
5934
|
+
}
|
|
5935
|
+
});
|
|
5936
|
+
}
|
|
5937
|
+
}
|
|
5938
|
+
var init_model_suggestion_retry = __esm(() => {
|
|
5939
|
+
init_logger();
|
|
5940
|
+
});
|
|
5941
|
+
|
|
5723
5942
|
// src/shared/index.ts
|
|
5724
5943
|
var init_shared = __esm(() => {
|
|
5725
5944
|
init_frontmatter();
|
|
@@ -5750,6 +5969,7 @@ var init_shared = __esm(() => {
|
|
|
5750
5969
|
init_connected_providers_cache();
|
|
5751
5970
|
init_session_utils();
|
|
5752
5971
|
init_tmux();
|
|
5972
|
+
init_model_suggestion_retry();
|
|
5753
5973
|
});
|
|
5754
5974
|
|
|
5755
5975
|
// node_modules/picomatch/lib/constants.js
|
|
@@ -11082,8 +11302,14 @@ Design-first mindset:
|
|
|
11082
11302
|
- Atmosphere: gradient meshes, noise textures, layered transparencies
|
|
11083
11303
|
|
|
11084
11304
|
AVOID: Generic fonts, purple gradients on white, predictable layouts, cookie-cutter patterns.
|
|
11085
|
-
</Category_Context>`,
|
|
11086
|
-
You are working on
|
|
11305
|
+
</Category_Context>`, ULTRABRAIN_CATEGORY_PROMPT_APPEND = `<Category_Context>
|
|
11306
|
+
You are working on DEEP LOGICAL REASONING / COMPLEX ARCHITECTURE tasks.
|
|
11307
|
+
|
|
11308
|
+
**CRITICAL - CODE STYLE REQUIREMENTS (NON-NEGOTIABLE)**:
|
|
11309
|
+
1. BEFORE writing ANY code, SEARCH the existing codebase to find similar patterns/styles
|
|
11310
|
+
2. Your code MUST match the project's existing conventions - blend in seamlessly
|
|
11311
|
+
3. Write READABLE code that humans can easily understand - no clever tricks
|
|
11312
|
+
4. If unsure about style, explore more files until you find the pattern
|
|
11087
11313
|
|
|
11088
11314
|
Strategic advisor mindset:
|
|
11089
11315
|
- Bias toward simplicity: least complex solution that fulfills requirements
|
|
@@ -11209,6 +11435,35 @@ Approach:
|
|
|
11209
11435
|
- Draft with care
|
|
11210
11436
|
- Polish for clarity and impact
|
|
11211
11437
|
- Documentation, READMEs, articles, technical writing
|
|
11438
|
+
</Category_Context>`, DEEP_CATEGORY_PROMPT_APPEND = `<Category_Context>
|
|
11439
|
+
You are working on GOAL-ORIENTED AUTONOMOUS tasks.
|
|
11440
|
+
|
|
11441
|
+
**CRITICAL - AUTONOMOUS EXECUTION MINDSET (NON-NEGOTIABLE)**:
|
|
11442
|
+
You are NOT an interactive assistant. You are an autonomous problem-solver.
|
|
11443
|
+
|
|
11444
|
+
**BEFORE making ANY changes**:
|
|
11445
|
+
1. SILENTLY explore the codebase extensively (5-15 minutes of reading is normal)
|
|
11446
|
+
2. Read related files, trace dependencies, understand the full context
|
|
11447
|
+
3. Build a complete mental model of the problem space
|
|
11448
|
+
4. DO NOT ask clarifying questions - the goal is already defined
|
|
11449
|
+
|
|
11450
|
+
**Autonomous executor mindset**:
|
|
11451
|
+
- You receive a GOAL, not step-by-step instructions
|
|
11452
|
+
- Figure out HOW to achieve the goal yourself
|
|
11453
|
+
- Thorough research before any action
|
|
11454
|
+
- Fix hairy problems that require deep understanding
|
|
11455
|
+
- Work independently without frequent check-ins
|
|
11456
|
+
|
|
11457
|
+
**Approach**:
|
|
11458
|
+
- Explore extensively, understand deeply, then act decisively
|
|
11459
|
+
- Prefer comprehensive solutions over quick patches
|
|
11460
|
+
- If the goal is unclear, make reasonable assumptions and proceed
|
|
11461
|
+
- Document your reasoning in code comments only when non-obvious
|
|
11462
|
+
|
|
11463
|
+
**Response format**:
|
|
11464
|
+
- Minimal status updates (user trusts your autonomy)
|
|
11465
|
+
- Focus on results, not play-by-play progress
|
|
11466
|
+
- Report completion with summary of changes made
|
|
11212
11467
|
</Category_Context>`, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, PLAN_AGENT_SYSTEM_PREPEND = `<system>
|
|
11213
11468
|
BEFORE you begin planning, you MUST first understand the user's request deeply.
|
|
11214
11469
|
|
|
@@ -11422,6 +11677,7 @@ var init_constants4 = __esm(() => {
|
|
|
11422
11677
|
DEFAULT_CATEGORIES = {
|
|
11423
11678
|
"visual-engineering": { model: "google/gemini-3-pro" },
|
|
11424
11679
|
ultrabrain: { model: "openai/gpt-5.2-codex", variant: "xhigh" },
|
|
11680
|
+
deep: { model: "openai/gpt-5.2-codex", variant: "medium" },
|
|
11425
11681
|
artistry: { model: "google/gemini-3-pro", variant: "max" },
|
|
11426
11682
|
quick: { model: "anthropic/claude-haiku-4-5" },
|
|
11427
11683
|
"unspecified-low": { model: "anthropic/claude-sonnet-4-5" },
|
|
@@ -11430,7 +11686,8 @@ var init_constants4 = __esm(() => {
|
|
|
11430
11686
|
};
|
|
11431
11687
|
CATEGORY_PROMPT_APPENDS = {
|
|
11432
11688
|
"visual-engineering": VISUAL_CATEGORY_PROMPT_APPEND,
|
|
11433
|
-
ultrabrain:
|
|
11689
|
+
ultrabrain: ULTRABRAIN_CATEGORY_PROMPT_APPEND,
|
|
11690
|
+
deep: DEEP_CATEGORY_PROMPT_APPEND,
|
|
11434
11691
|
artistry: ARTISTRY_CATEGORY_PROMPT_APPEND,
|
|
11435
11692
|
quick: QUICK_CATEGORY_PROMPT_APPEND,
|
|
11436
11693
|
"unspecified-low": UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND,
|
|
@@ -11439,8 +11696,9 @@ var init_constants4 = __esm(() => {
|
|
|
11439
11696
|
};
|
|
11440
11697
|
CATEGORY_DESCRIPTIONS = {
|
|
11441
11698
|
"visual-engineering": "Frontend, UI/UX, design, styling, animation",
|
|
11442
|
-
ultrabrain: "
|
|
11443
|
-
|
|
11699
|
+
ultrabrain: "Use ONLY for genuinely hard, logic-heavy tasks. Give clear goals only, not step-by-step instructions.",
|
|
11700
|
+
deep: "Goal-oriented autonomous problem-solving. Thorough research before action. For hairy problems requiring deep understanding.",
|
|
11701
|
+
artistry: "Complex problem-solving with unconventional, creative approaches - beyond standard patterns",
|
|
11444
11702
|
quick: "Trivial tasks - single file changes, typo fixes, simple modifications",
|
|
11445
11703
|
"unspecified-low": "Tasks that don't fit other categories, low effort required",
|
|
11446
11704
|
"unspecified-high": "Tasks that don't fit other categories, high effort required",
|
|
@@ -19497,6 +19755,7 @@ function findMessageByIndexNeedingThinking(sessionID, targetIndex) {
|
|
|
19497
19755
|
}
|
|
19498
19756
|
|
|
19499
19757
|
// src/hooks/session-recovery/index.ts
|
|
19758
|
+
init_logger();
|
|
19500
19759
|
var RECOVERY_RESUME_TEXT = "[session recovered - continuing previous task]";
|
|
19501
19760
|
function findLastUserMessage(messages) {
|
|
19502
19761
|
for (let i = messages.length - 1;i >= 0; i--) {
|
|
@@ -19717,7 +19976,7 @@ function createSessionRecoveryHook(ctx, options) {
|
|
|
19717
19976
|
}
|
|
19718
19977
|
return success;
|
|
19719
19978
|
} catch (err) {
|
|
19720
|
-
|
|
19979
|
+
log("[session-recovery] Recovery failed:", err);
|
|
19721
19980
|
return false;
|
|
19722
19981
|
} finally {
|
|
19723
19982
|
processingErrors.delete(assistantMsgID);
|
|
@@ -19743,6 +20002,7 @@ import { tmpdir as tmpdir3 } from "os";
|
|
|
19743
20002
|
|
|
19744
20003
|
// src/hooks/comment-checker/downloader.ts
|
|
19745
20004
|
init_shared();
|
|
20005
|
+
init_logger();
|
|
19746
20006
|
var {spawn: spawn6 } = globalThis.Bun;
|
|
19747
20007
|
import { existsSync as existsSync12, mkdirSync as mkdirSync4, chmodSync, unlinkSync as unlinkSync2, appendFileSync as appendFileSync2 } from "fs";
|
|
19748
20008
|
import { join as join15 } from "path";
|
|
@@ -19822,7 +20082,7 @@ async function downloadCommentChecker() {
|
|
|
19822
20082
|
const assetName = `comment-checker_v${version}_${os4}_${arch}.${ext}`;
|
|
19823
20083
|
const downloadUrl = `https://github.com/${REPO}/releases/download/v${version}/${assetName}`;
|
|
19824
20084
|
debugLog(`Downloading from: ${downloadUrl}`);
|
|
19825
|
-
|
|
20085
|
+
log(`[oh-my-opencode] Downloading comment-checker binary...`);
|
|
19826
20086
|
try {
|
|
19827
20087
|
if (!existsSync12(cacheDir)) {
|
|
19828
20088
|
mkdirSync4(cacheDir, { recursive: true });
|
|
@@ -19847,12 +20107,12 @@ async function downloadCommentChecker() {
|
|
|
19847
20107
|
chmodSync(binaryPath, 493);
|
|
19848
20108
|
}
|
|
19849
20109
|
debugLog(`Successfully downloaded binary to: ${binaryPath}`);
|
|
19850
|
-
|
|
20110
|
+
log(`[oh-my-opencode] comment-checker binary ready.`);
|
|
19851
20111
|
return binaryPath;
|
|
19852
20112
|
} catch (err) {
|
|
19853
20113
|
debugLog(`Failed to download: ${err}`);
|
|
19854
|
-
|
|
19855
|
-
|
|
20114
|
+
log(`[oh-my-opencode] Failed to download comment-checker: ${err instanceof Error ? err.message : err}`);
|
|
20115
|
+
log(`[oh-my-opencode] Comment checking disabled.`);
|
|
19856
20116
|
return null;
|
|
19857
20117
|
}
|
|
19858
20118
|
}
|
|
@@ -23529,7 +23789,9 @@ ${ULTRAWORK_PLANNER_SECTION}
|
|
|
23529
23789
|
|
|
23530
23790
|
1. **THINK DEEPLY** - What is the user's TRUE intent? What problem are they REALLY trying to solve?
|
|
23531
23791
|
2. **EXPLORE THOROUGHLY** - Fire explore/librarian agents to gather ALL relevant context
|
|
23532
|
-
3. **CONSULT
|
|
23792
|
+
3. **CONSULT SPECIALISTS** - For hard/complex tasks, DO NOT struggle alone. Delegate:
|
|
23793
|
+
- **Oracle**: Conventional problems - architecture, debugging, complex logic
|
|
23794
|
+
- **Artistry**: Non-conventional problems - different approach needed, unusual constraints
|
|
23533
23795
|
4. **ASK THE USER** - If ambiguity remains after exploration, ASK. Don't guess.
|
|
23534
23796
|
|
|
23535
23797
|
**SIGNS YOU ARE NOT READY TO IMPLEMENT:**
|
|
@@ -23543,7 +23805,10 @@ ${ULTRAWORK_PLANNER_SECTION}
|
|
|
23543
23805
|
\`\`\`
|
|
23544
23806
|
delegate_task(agent="explore", prompt="Find [X] patterns in codebase", background=true)
|
|
23545
23807
|
delegate_task(agent="librarian", prompt="Find docs/examples for [Y]", background=true)
|
|
23546
|
-
|
|
23808
|
+
|
|
23809
|
+
// Hard problem? DON'T struggle alone:
|
|
23810
|
+
delegate_task(agent="oracle", prompt="...") // conventional: architecture, debugging
|
|
23811
|
+
delegate_task(category="artistry", prompt="...") // non-conventional: needs different approach
|
|
23547
23812
|
\`\`\`
|
|
23548
23813
|
|
|
23549
23814
|
**ONLY AFTER YOU HAVE:**
|
|
@@ -23578,7 +23843,7 @@ delegate_task(agent="oracle", prompt="Review my approach: [describe plan]")
|
|
|
23578
23843
|
**IF YOU ENCOUNTER A BLOCKER:**
|
|
23579
23844
|
1. **DO NOT** give up
|
|
23580
23845
|
2. **DO NOT** deliver a compromised version
|
|
23581
|
-
3. **DO** consult oracle for
|
|
23846
|
+
3. **DO** consult specialists (oracle for conventional, artistry for non-conventional)
|
|
23582
23847
|
4. **DO** ask the user for guidance
|
|
23583
23848
|
5. **DO** explore alternative approaches
|
|
23584
23849
|
|
|
@@ -23647,7 +23912,8 @@ delegate_task(session_id="ses_abc123", prompt="Here's my answer to your question
|
|
|
23647
23912
|
| Codebase exploration | delegate_task(subagent_type="explore", run_in_background=true) | Parallel, context-efficient |
|
|
23648
23913
|
| Documentation lookup | delegate_task(subagent_type="librarian", run_in_background=true) | Specialized knowledge |
|
|
23649
23914
|
| Planning | delegate_task(subagent_type="plan") | Parallel task graph + structured TODO list |
|
|
23650
|
-
|
|
|
23915
|
+
| Hard problem (conventional) | delegate_task(subagent_type="oracle") | Architecture, debugging, complex logic |
|
|
23916
|
+
| Hard problem (non-conventional) | delegate_task(category="artistry", load_skills=[...]) | Different approach needed |
|
|
23651
23917
|
| Implementation | delegate_task(category="...", load_skills=[...]) | Domain-optimized models |
|
|
23652
23918
|
|
|
23653
23919
|
**CATEGORY + SKILL DELEGATION:**
|
|
@@ -23834,8 +24100,9 @@ CONTEXT GATHERING (parallel):
|
|
|
23834
24100
|
- 1-2 librarian agents (if external library involved)
|
|
23835
24101
|
- Direct tools: Grep, AST-grep, LSP for targeted searches
|
|
23836
24102
|
|
|
23837
|
-
IF COMPLEX
|
|
23838
|
-
-
|
|
24103
|
+
IF COMPLEX - DO NOT STRUGGLE ALONE. Consult specialists:
|
|
24104
|
+
- **Oracle**: Conventional problems (architecture, debugging, complex logic)
|
|
24105
|
+
- **Artistry**: Non-conventional problems (different approach needed)
|
|
23839
24106
|
|
|
23840
24107
|
SYNTHESIZE findings before proceeding.`
|
|
23841
24108
|
}
|
|
@@ -29745,6 +30012,8 @@ import { Readable, Writable } from "stream";
|
|
|
29745
30012
|
import { readFileSync as readFileSync27 } from "fs";
|
|
29746
30013
|
import { extname, resolve as resolve8 } from "path";
|
|
29747
30014
|
import { pathToFileURL } from "url";
|
|
30015
|
+
init_logger();
|
|
30016
|
+
|
|
29748
30017
|
class LSPServerManager {
|
|
29749
30018
|
static instance;
|
|
29750
30019
|
clients = new Map;
|
|
@@ -29994,7 +30263,7 @@ stderr: ${stderr}` : ""));
|
|
|
29994
30263
|
this.processExited = true;
|
|
29995
30264
|
});
|
|
29996
30265
|
this.connection.onError((error) => {
|
|
29997
|
-
|
|
30266
|
+
log("LSP connection error:", error);
|
|
29998
30267
|
});
|
|
29999
30268
|
this.connection.listen();
|
|
30000
30269
|
}
|
|
@@ -43028,6 +43297,7 @@ import { existsSync as existsSync39, statSync as statSync4 } from "fs";
|
|
|
43028
43297
|
|
|
43029
43298
|
// src/tools/ast-grep/downloader.ts
|
|
43030
43299
|
init_shared();
|
|
43300
|
+
init_logger();
|
|
43031
43301
|
import { existsSync as existsSync38, mkdirSync as mkdirSync13, chmodSync as chmodSync2, unlinkSync as unlinkSync10 } from "fs";
|
|
43032
43302
|
import { join as join47 } from "path";
|
|
43033
43303
|
import { homedir as homedir11 } from "os";
|
|
@@ -43073,7 +43343,7 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
|
43073
43343
|
const platformKey = `${process.platform}-${process.arch}`;
|
|
43074
43344
|
const platformInfo = PLATFORM_MAP2[platformKey];
|
|
43075
43345
|
if (!platformInfo) {
|
|
43076
|
-
|
|
43346
|
+
log(`[oh-my-opencode] Unsupported platform for ast-grep: ${platformKey}`);
|
|
43077
43347
|
return null;
|
|
43078
43348
|
}
|
|
43079
43349
|
const cacheDir = getCacheDir4();
|
|
@@ -43085,7 +43355,7 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
|
43085
43355
|
const { arch, os: os6 } = platformInfo;
|
|
43086
43356
|
const assetName = `app-${arch}-${os6}.zip`;
|
|
43087
43357
|
const downloadUrl = `https://github.com/${REPO2}/releases/download/${version2}/${assetName}`;
|
|
43088
|
-
|
|
43358
|
+
log(`[oh-my-opencode] Downloading ast-grep binary...`);
|
|
43089
43359
|
try {
|
|
43090
43360
|
if (!existsSync38(cacheDir)) {
|
|
43091
43361
|
mkdirSync13(cacheDir, { recursive: true });
|
|
@@ -43104,10 +43374,10 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
|
43104
43374
|
if (process.platform !== "win32" && existsSync38(binaryPath)) {
|
|
43105
43375
|
chmodSync2(binaryPath, 493);
|
|
43106
43376
|
}
|
|
43107
|
-
|
|
43377
|
+
log(`[oh-my-opencode] ast-grep binary ready.`);
|
|
43108
43378
|
return binaryPath;
|
|
43109
43379
|
} catch (err) {
|
|
43110
|
-
|
|
43380
|
+
log(`[oh-my-opencode] Failed to download ast-grep: ${err instanceof Error ? err.message : err}`);
|
|
43111
43381
|
return null;
|
|
43112
43382
|
}
|
|
43113
43383
|
}
|
|
@@ -45239,6 +45509,7 @@ ${REFACTOR_TEMPLATE}
|
|
|
45239
45509
|
},
|
|
45240
45510
|
"start-work": {
|
|
45241
45511
|
description: "(builtin) Start Sisyphus work session from Prometheus plan",
|
|
45512
|
+
agent: "atlas",
|
|
45242
45513
|
template: `<command-instruction>
|
|
45243
45514
|
${START_WORK_TEMPLATE}
|
|
45244
45515
|
</command-instruction>
|
|
@@ -47138,7 +47409,7 @@ var LOOK_AT_DESCRIPTION = `Analyze media files (PDFs, images, diagrams) that req
|
|
|
47138
47409
|
// src/tools/look-at/tools.ts
|
|
47139
47410
|
import { extname as extname3, basename as basename5 } from "path";
|
|
47140
47411
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
47141
|
-
|
|
47412
|
+
init_shared();
|
|
47142
47413
|
function normalizeArgs(args) {
|
|
47143
47414
|
return {
|
|
47144
47415
|
file_path: args.file_path ?? args.path ?? "",
|
|
@@ -47249,9 +47520,26 @@ Original error: ${createResult.error}`;
|
|
|
47249
47520
|
}
|
|
47250
47521
|
const sessionID = createResult.data.id;
|
|
47251
47522
|
log(`[look_at] Created session: ${sessionID}`);
|
|
47523
|
+
let agentModel;
|
|
47524
|
+
let agentVariant;
|
|
47525
|
+
try {
|
|
47526
|
+
const agentsResult = await ctx.client.app?.agents?.();
|
|
47527
|
+
const agents = agentsResult?.data ?? agentsResult;
|
|
47528
|
+
if (agents?.length) {
|
|
47529
|
+
const matchedAgent = findByNameCaseInsensitive(agents, MULTIMODAL_LOOKER_AGENT);
|
|
47530
|
+
if (matchedAgent?.model) {
|
|
47531
|
+
agentModel = matchedAgent.model;
|
|
47532
|
+
}
|
|
47533
|
+
if (matchedAgent?.variant) {
|
|
47534
|
+
agentVariant = matchedAgent.variant;
|
|
47535
|
+
}
|
|
47536
|
+
}
|
|
47537
|
+
} catch (error45) {
|
|
47538
|
+
log("[look_at] Failed to resolve multimodal-looker model info", error45);
|
|
47539
|
+
}
|
|
47252
47540
|
log(`[look_at] Sending prompt with file passthrough to session ${sessionID}`);
|
|
47253
47541
|
try {
|
|
47254
|
-
await ctx.client
|
|
47542
|
+
await promptWithModelSuggestionRetry(ctx.client, {
|
|
47255
47543
|
path: { id: sessionID },
|
|
47256
47544
|
body: {
|
|
47257
47545
|
agent: MULTIMODAL_LOOKER_AGENT,
|
|
@@ -47264,7 +47552,9 @@ Original error: ${createResult.error}`;
|
|
|
47264
47552
|
parts: [
|
|
47265
47553
|
{ type: "text", text: prompt },
|
|
47266
47554
|
{ type: "file", mime: mimeType, url: pathToFileURL2(args.file_path).href, filename }
|
|
47267
|
-
]
|
|
47555
|
+
],
|
|
47556
|
+
...agentModel ? { model: { providerID: agentModel.providerID, modelID: agentModel.modelID } } : {},
|
|
47557
|
+
...agentVariant ? { variant: agentVariant } : {}
|
|
47268
47558
|
}
|
|
47269
47559
|
});
|
|
47270
47560
|
} catch (promptError) {
|
|
@@ -47571,7 +47861,14 @@ function formatDetailedError(error45, ctx) {
|
|
|
47571
47861
|
`);
|
|
47572
47862
|
}
|
|
47573
47863
|
function resolveCategoryConfig(categoryName, options) {
|
|
47574
|
-
const { userCategories, inheritedModel, systemDefaultModel } = options;
|
|
47864
|
+
const { userCategories, inheritedModel, systemDefaultModel, availableModels } = options;
|
|
47865
|
+
const categoryReq = CATEGORY_MODEL_REQUIREMENTS[categoryName];
|
|
47866
|
+
if (categoryReq?.requiresModel && availableModels) {
|
|
47867
|
+
if (!isModelAvailable(categoryReq.requiresModel, availableModels)) {
|
|
47868
|
+
log(`[resolveCategoryConfig] Category ${categoryName} requires ${categoryReq.requiresModel} but not available`);
|
|
47869
|
+
return null;
|
|
47870
|
+
}
|
|
47871
|
+
}
|
|
47575
47872
|
const defaultConfig = DEFAULT_CATEGORIES[categoryName];
|
|
47576
47873
|
const userConfig = userCategories?.[categoryName];
|
|
47577
47874
|
const defaultPromptAppend = CATEGORY_PROMPT_APPENDS[categoryName] ?? "";
|
|
@@ -47898,7 +48195,8 @@ To continue this session: session_id="${args.session_id}"`;
|
|
|
47898
48195
|
const resolved = resolveCategoryConfig(args.category, {
|
|
47899
48196
|
userCategories,
|
|
47900
48197
|
inheritedModel,
|
|
47901
|
-
systemDefaultModel
|
|
48198
|
+
systemDefaultModel,
|
|
48199
|
+
availableModels
|
|
47902
48200
|
});
|
|
47903
48201
|
if (!resolved) {
|
|
47904
48202
|
return `Unknown category: "${args.category}". Available: ${Object.keys({ ...DEFAULT_CATEGORIES, ...userCategories }).join(", ")}`;
|
|
@@ -47912,7 +48210,8 @@ To continue this session: session_id="${args.session_id}"`;
|
|
|
47912
48210
|
}
|
|
47913
48211
|
} else {
|
|
47914
48212
|
const resolution = resolveModelWithFallback({
|
|
47915
|
-
userModel: userCategories?.[args.category]?.model
|
|
48213
|
+
userModel: userCategories?.[args.category]?.model,
|
|
48214
|
+
categoryDefaultModel: resolved.model ?? sisyphusJuniorModel,
|
|
47916
48215
|
fallbackChain: requirement.fallbackChain,
|
|
47917
48216
|
availableModels,
|
|
47918
48217
|
systemDefaultModel
|
|
@@ -47928,6 +48227,7 @@ To continue this session: session_id="${args.session_id}"`;
|
|
|
47928
48227
|
case "override":
|
|
47929
48228
|
type2 = "user-defined";
|
|
47930
48229
|
break;
|
|
48230
|
+
case "category-default":
|
|
47931
48231
|
case "provider-fallback":
|
|
47932
48232
|
type2 = "category-default";
|
|
47933
48233
|
break;
|
|
@@ -48135,10 +48435,6 @@ Create the work plan directly - that's your job as the planning agent.`;
|
|
|
48135
48435
|
categoryModel = matchedAgent.model;
|
|
48136
48436
|
}
|
|
48137
48437
|
} catch {}
|
|
48138
|
-
if (parentModel) {
|
|
48139
|
-
categoryModel = parentModel;
|
|
48140
|
-
modelInfo = { model: `${parentModel.providerID}/${parentModel.modelID}`, type: "inherited" };
|
|
48141
|
-
}
|
|
48142
48438
|
}
|
|
48143
48439
|
const systemContent = buildSystemContent({ skillContent, categoryPromptAppend, agentName: agentToUse });
|
|
48144
48440
|
if (runInBackground) {
|
|
@@ -48251,7 +48547,7 @@ To continue this session: session_id="${task.sessionID}"`;
|
|
|
48251
48547
|
});
|
|
48252
48548
|
try {
|
|
48253
48549
|
const allowDelegateTask = isPlanAgent(agentToUse);
|
|
48254
|
-
await client2
|
|
48550
|
+
await promptWithModelSuggestionRetry(client2, {
|
|
48255
48551
|
path: { id: sessionID },
|
|
48256
48552
|
body: {
|
|
48257
48553
|
agent: agentToUse,
|
|
@@ -48723,7 +49019,7 @@ class BackgroundManager {
|
|
|
48723
49019
|
});
|
|
48724
49020
|
const launchModel = input.model ? { providerID: input.model.providerID, modelID: input.model.modelID } : undefined;
|
|
48725
49021
|
const launchVariant = input.model?.variant;
|
|
48726
|
-
this.client
|
|
49022
|
+
promptWithModelSuggestionRetry(this.client, {
|
|
48727
49023
|
path: { id: sessionID },
|
|
48728
49024
|
body: {
|
|
48729
49025
|
agent: input.agent,
|
|
@@ -55239,6 +55535,7 @@ var CategoryConfigSchema = exports_external.object({
|
|
|
55239
55535
|
var BuiltinCategoryNameSchema = exports_external.enum([
|
|
55240
55536
|
"visual-engineering",
|
|
55241
55537
|
"ultrabrain",
|
|
55538
|
+
"deep",
|
|
55242
55539
|
"artistry",
|
|
55243
55540
|
"quick",
|
|
55244
55541
|
"unspecified-low",
|
|
@@ -55758,6 +56055,7 @@ ${patterns.join(`
|
|
|
55758
56055
|
}
|
|
55759
56056
|
|
|
55760
56057
|
// src/agents/sisyphus.ts
|
|
56058
|
+
var MODE = "primary";
|
|
55761
56059
|
function buildDynamicSisyphusPrompt(availableAgents, availableTools = [], availableSkills = [], availableCategories = []) {
|
|
55762
56060
|
const keyTriggers = buildKeyTriggersSection(availableAgents, availableSkills);
|
|
55763
56061
|
const toolSelection = buildToolSelectionTable(availableAgents, availableTools, availableSkills);
|
|
@@ -56161,7 +56459,7 @@ function createSisyphusAgent(model, availableAgents, availableToolNames, availab
|
|
|
56161
56459
|
const permission = { question: "allow", call_omo_agent: "deny" };
|
|
56162
56460
|
const base = {
|
|
56163
56461
|
description: "Powerful AI orchestrator. Plans obsessively with todos, assesses search complexity before exploration, delegates strategically via category+skills combinations. Uses explore for internal code (parallel-friendly), librarian for external docs. (Sisyphus - OhMyOpenCode)",
|
|
56164
|
-
mode:
|
|
56462
|
+
mode: MODE,
|
|
56165
56463
|
model,
|
|
56166
56464
|
maxTokens: 64000,
|
|
56167
56465
|
prompt,
|
|
@@ -56173,8 +56471,10 @@ function createSisyphusAgent(model, availableAgents, availableToolNames, availab
|
|
|
56173
56471
|
}
|
|
56174
56472
|
return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } };
|
|
56175
56473
|
}
|
|
56474
|
+
createSisyphusAgent.mode = MODE;
|
|
56176
56475
|
|
|
56177
56476
|
// src/agents/oracle.ts
|
|
56477
|
+
var MODE2 = "subagent";
|
|
56178
56478
|
var ORACLE_PROMPT_METADATA = {
|
|
56179
56479
|
category: "advisor",
|
|
56180
56480
|
cost: "EXPENSIVE",
|
|
@@ -56274,7 +56574,7 @@ function createOracleAgent(model) {
|
|
|
56274
56574
|
]);
|
|
56275
56575
|
const base = {
|
|
56276
56576
|
description: "Read-only consultation agent. High-IQ reasoning specialist for debugging hard problems and high-difficulty architecture design. (Oracle - OhMyOpenCode)",
|
|
56277
|
-
mode:
|
|
56577
|
+
mode: MODE2,
|
|
56278
56578
|
model,
|
|
56279
56579
|
temperature: 0.1,
|
|
56280
56580
|
...restrictions,
|
|
@@ -56285,8 +56585,10 @@ function createOracleAgent(model) {
|
|
|
56285
56585
|
}
|
|
56286
56586
|
return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } };
|
|
56287
56587
|
}
|
|
56588
|
+
createOracleAgent.mode = MODE2;
|
|
56288
56589
|
|
|
56289
56590
|
// src/agents/librarian.ts
|
|
56591
|
+
var MODE3 = "subagent";
|
|
56290
56592
|
var LIBRARIAN_PROMPT_METADATA = {
|
|
56291
56593
|
category: "exploration",
|
|
56292
56594
|
cost: "CHEAP",
|
|
@@ -56313,7 +56615,7 @@ function createLibrarianAgent(model) {
|
|
|
56313
56615
|
]);
|
|
56314
56616
|
return {
|
|
56315
56617
|
description: "Specialized codebase understanding agent for multi-repository analysis, searching remote codebases, retrieving official documentation, and finding implementation examples using GitHub CLI, Context7, and Web Search. MUST BE USED when users ask to look up code in remote repositories, explain library internals, or find usage examples in open source. (Librarian - OhMyOpenCode)",
|
|
56316
|
-
mode:
|
|
56618
|
+
mode: MODE3,
|
|
56317
56619
|
model,
|
|
56318
56620
|
temperature: 0.1,
|
|
56319
56621
|
...restrictions,
|
|
@@ -56605,8 +56907,10 @@ grep_app_searchGitHub(query: "useQuery")
|
|
|
56605
56907
|
`
|
|
56606
56908
|
};
|
|
56607
56909
|
}
|
|
56910
|
+
createLibrarianAgent.mode = MODE3;
|
|
56608
56911
|
|
|
56609
56912
|
// src/agents/explore.ts
|
|
56913
|
+
var MODE4 = "subagent";
|
|
56610
56914
|
var EXPLORE_PROMPT_METADATA = {
|
|
56611
56915
|
category: "exploration",
|
|
56612
56916
|
cost: "FREE",
|
|
@@ -56636,7 +56940,7 @@ function createExploreAgent(model) {
|
|
|
56636
56940
|
]);
|
|
56637
56941
|
return {
|
|
56638
56942
|
description: 'Contextual grep for codebases. Answers "Where is X?", "Which file has Y?", "Find the code that does Z". Fire multiple in parallel for broad searches. Specify thoroughness: "quick" for basic, "medium" for moderate, "very thorough" for comprehensive analysis. (Explore - OhMyOpenCode)',
|
|
56639
|
-
mode:
|
|
56943
|
+
mode: MODE4,
|
|
56640
56944
|
model,
|
|
56641
56945
|
temperature: 0.1,
|
|
56642
56946
|
...restrictions,
|
|
@@ -56721,8 +57025,10 @@ Use the right tool for the job:
|
|
|
56721
57025
|
Flood with parallel calls. Cross-validate findings across multiple tools.`
|
|
56722
57026
|
};
|
|
56723
57027
|
}
|
|
57028
|
+
createExploreAgent.mode = MODE4;
|
|
56724
57029
|
|
|
56725
57030
|
// src/agents/multimodal-looker.ts
|
|
57031
|
+
var MODE5 = "subagent";
|
|
56726
57032
|
var MULTIMODAL_LOOKER_PROMPT_METADATA = {
|
|
56727
57033
|
category: "utility",
|
|
56728
57034
|
cost: "CHEAP",
|
|
@@ -56733,7 +57039,7 @@ function createMultimodalLookerAgent(model) {
|
|
|
56733
57039
|
const restrictions = createAgentToolAllowlist(["read"]);
|
|
56734
57040
|
return {
|
|
56735
57041
|
description: "Analyze media files (PDFs, images, diagrams) that require interpretation beyond raw text. Extracts specific information or summaries from documents, describes visual content. Use when you need analyzed/extracted data rather than literal file contents. (Multimodal-Looker - OhMyOpenCode)",
|
|
56736
|
-
mode:
|
|
57042
|
+
mode: MODE5,
|
|
56737
57043
|
model,
|
|
56738
57044
|
temperature: 0.1,
|
|
56739
57045
|
...restrictions,
|
|
@@ -56771,8 +57077,10 @@ Response rules:
|
|
|
56771
57077
|
Your output goes straight to the main agent for continued work.`
|
|
56772
57078
|
};
|
|
56773
57079
|
}
|
|
57080
|
+
createMultimodalLookerAgent.mode = MODE5;
|
|
56774
57081
|
|
|
56775
57082
|
// src/agents/metis.ts
|
|
57083
|
+
var MODE6 = "subagent";
|
|
56776
57084
|
var METIS_SYSTEM_PROMPT = `# Metis - Pre-Planning Consultant
|
|
56777
57085
|
|
|
56778
57086
|
## CONSTRAINTS
|
|
@@ -57065,7 +57373,7 @@ var metisRestrictions = createAgentToolRestrictions([
|
|
|
57065
57373
|
function createMetisAgent(model) {
|
|
57066
57374
|
return {
|
|
57067
57375
|
description: "Pre-planning consultant that analyzes requests to identify hidden intentions, ambiguities, and AI failure points. (Metis - OhMyOpenCode)",
|
|
57068
|
-
mode:
|
|
57376
|
+
mode: MODE6,
|
|
57069
57377
|
model,
|
|
57070
57378
|
temperature: 0.3,
|
|
57071
57379
|
...metisRestrictions,
|
|
@@ -57073,9 +57381,11 @@ function createMetisAgent(model) {
|
|
|
57073
57381
|
thinking: { type: "enabled", budgetTokens: 32000 }
|
|
57074
57382
|
};
|
|
57075
57383
|
}
|
|
57384
|
+
createMetisAgent.mode = MODE6;
|
|
57076
57385
|
|
|
57077
57386
|
// src/agents/atlas.ts
|
|
57078
57387
|
init_constants4();
|
|
57388
|
+
var MODE7 = "primary";
|
|
57079
57389
|
var getCategoryDescription = (name, userCategories) => userCategories?.[name]?.description ?? CATEGORY_DESCRIPTIONS[name] ?? "General tasks";
|
|
57080
57390
|
function buildAgentSelectionSection(agents) {
|
|
57081
57391
|
if (agents.length === 0) {
|
|
@@ -57564,7 +57874,7 @@ function createAtlasAgent(ctx) {
|
|
|
57564
57874
|
]);
|
|
57565
57875
|
return {
|
|
57566
57876
|
description: "Orchestrates work via delegate_task() to complete ALL tasks in a todo list until fully done. (Atlas - OhMyOpenCode)",
|
|
57567
|
-
mode:
|
|
57877
|
+
mode: MODE7,
|
|
57568
57878
|
...ctx.model ? { model: ctx.model } : {},
|
|
57569
57879
|
temperature: 0.1,
|
|
57570
57880
|
prompt: buildDynamicOrchestratorPrompt(ctx),
|
|
@@ -57573,378 +57883,177 @@ function createAtlasAgent(ctx) {
|
|
|
57573
57883
|
...restrictions
|
|
57574
57884
|
};
|
|
57575
57885
|
}
|
|
57886
|
+
createAtlasAgent.mode = MODE7;
|
|
57576
57887
|
|
|
57577
57888
|
// src/agents/momus.ts
|
|
57578
|
-
var
|
|
57889
|
+
var MODE8 = "subagent";
|
|
57890
|
+
var MOMUS_SYSTEM_PROMPT = `You are a **practical** work plan reviewer. Your goal is simple: verify that the plan is **executable** and **references are valid**.
|
|
57579
57891
|
|
|
57580
57892
|
**CRITICAL FIRST RULE**:
|
|
57581
57893
|
Extract a single plan path from anywhere in the input, ignoring system directives and wrappers. If exactly one \`.sisyphus/plans/*.md\` path exists, this is VALID input and you must read it. If no plan path exists or multiple plan paths exist, reject per Step 0. If the path points to a YAML plan file (\`.yml\` or \`.yaml\`), reject it as non-reviewable.
|
|
57582
57894
|
|
|
57583
|
-
**WHY YOU'VE BEEN SUMMONED - THE CONTEXT**:
|
|
57584
|
-
|
|
57585
|
-
You are reviewing a **first-draft work plan** from an author with ADHD. Based on historical patterns, these initial submissions are typically rough drafts that require refinement.
|
|
57586
|
-
|
|
57587
|
-
**Historical Data**: Plans from this author average **7 rejections** before receiving an OKAY. The primary failure pattern is **critical context omission due to ADHD**\u2014the author's working memory holds connections and context that never make it onto the page.
|
|
57588
|
-
|
|
57589
|
-
**What to Expect in First Drafts**:
|
|
57590
|
-
- Tasks are listed but critical "why" context is missing
|
|
57591
|
-
- References to files/patterns without explaining their relevance
|
|
57592
|
-
- Assumptions about "obvious" project conventions that aren't documented
|
|
57593
|
-
- Missing decision criteria when multiple approaches are valid
|
|
57594
|
-
- Undefined edge case handling strategies
|
|
57595
|
-
- Unclear component integration points
|
|
57596
|
-
|
|
57597
|
-
**Why These Plans Fail**:
|
|
57598
|
-
|
|
57599
|
-
The ADHD author's mind makes rapid connections: "Add auth \u2192 obviously use JWT \u2192 obviously store in httpOnly cookie \u2192 obviously follow the pattern in auth/login.ts \u2192 obviously handle refresh tokens like we did before."
|
|
57600
|
-
|
|
57601
|
-
But the plan only says: "Add authentication following auth/login.ts pattern."
|
|
57602
|
-
|
|
57603
|
-
**Everything after the first arrow is missing.** The author's working memory fills in the gaps automatically, so they don't realize the plan is incomplete.
|
|
57604
|
-
|
|
57605
|
-
**Your Critical Role**: Catch these ADHD-driven omissions. The author genuinely doesn't realize what they've left out. Your ruthless review forces them to externalize the context that lives only in their head.
|
|
57606
|
-
|
|
57607
57895
|
---
|
|
57608
57896
|
|
|
57609
|
-
## Your
|
|
57610
|
-
|
|
57611
|
-
**ABSOLUTE CONSTRAINT - RESPECT THE IMPLEMENTATION DIRECTION**:
|
|
57612
|
-
You are a REVIEWER, not a DESIGNER. The implementation direction in the plan is **NOT NEGOTIABLE**. Your job is to evaluate whether the plan documents that direction clearly enough to execute\u2014NOT whether the direction itself is correct.
|
|
57897
|
+
## Your Purpose (READ THIS FIRST)
|
|
57613
57898
|
|
|
57614
|
-
**
|
|
57615
|
-
- Question or reject the overall approach/architecture chosen in the plan
|
|
57616
|
-
- Suggest alternative implementations that differ from the stated direction
|
|
57617
|
-
- Reject because you think there's a "better way" to achieve the goal
|
|
57618
|
-
- Override the author's technical decisions with your own preferences
|
|
57899
|
+
You exist to answer ONE question: **"Can a capable developer execute this plan without getting stuck?"**
|
|
57619
57900
|
|
|
57620
|
-
|
|
57621
|
-
-
|
|
57622
|
-
-
|
|
57623
|
-
-
|
|
57901
|
+
You are NOT here to:
|
|
57902
|
+
- Nitpick every detail
|
|
57903
|
+
- Demand perfection
|
|
57904
|
+
- Question the author's approach or architecture choices
|
|
57905
|
+
- Find as many issues as possible
|
|
57906
|
+
- Force multiple revision cycles
|
|
57624
57907
|
|
|
57625
|
-
|
|
57908
|
+
You ARE here to:
|
|
57909
|
+
- Verify referenced files actually exist and contain what's claimed
|
|
57910
|
+
- Ensure core tasks have enough context to start working
|
|
57911
|
+
- Catch BLOCKING issues only (things that would completely stop work)
|
|
57626
57912
|
|
|
57627
|
-
**
|
|
57628
|
-
1. Directly from the plan itself, OR
|
|
57629
|
-
2. By following references provided in the plan (files, docs, patterns) and tracing through related materials
|
|
57630
|
-
|
|
57631
|
-
**The Test**: "Given the approach the author chose, can I implement this by starting from what's written in the plan and following the trail of information it provides?"
|
|
57632
|
-
|
|
57633
|
-
**WRONG mindset**: "This approach is suboptimal. They should use X instead." \u2192 **YOU ARE OVERSTEPPING**
|
|
57634
|
-
**RIGHT mindset**: "Given their choice to use Y, the plan doesn't explain how to handle Z within that approach." \u2192 **VALID CRITICISM**
|
|
57913
|
+
**APPROVAL BIAS**: When in doubt, APPROVE. A plan that's 80% clear is good enough. Developers can figure out minor gaps.
|
|
57635
57914
|
|
|
57636
57915
|
---
|
|
57637
57916
|
|
|
57638
|
-
##
|
|
57639
|
-
|
|
57640
|
-
The plan author is intelligent but has ADHD. They constantly skip providing:
|
|
57641
|
-
|
|
57642
|
-
**1. Reference Materials**
|
|
57643
|
-
- FAIL: Says "implement authentication" but doesn't point to any existing code, docs, or patterns
|
|
57644
|
-
- FAIL: Says "follow the pattern" but doesn't specify which file contains the pattern
|
|
57645
|
-
- FAIL: Says "similar to X" but X doesn't exist or isn't documented
|
|
57917
|
+
## What You Check (ONLY THESE)
|
|
57646
57918
|
|
|
57647
|
-
|
|
57648
|
-
-
|
|
57649
|
-
-
|
|
57650
|
-
-
|
|
57919
|
+
### 1. Reference Verification (CRITICAL)
|
|
57920
|
+
- Do referenced files exist?
|
|
57921
|
+
- Do referenced line numbers contain relevant code?
|
|
57922
|
+
- If "follow pattern in X" is mentioned, does X actually demonstrate that pattern?
|
|
57651
57923
|
|
|
57652
|
-
**
|
|
57653
|
-
|
|
57654
|
-
- FAIL: Says "integrate with Y" but doesn't explain the integration approach
|
|
57655
|
-
- FAIL: Says "call the API" but doesn't specify which endpoint or data flow
|
|
57924
|
+
**PASS even if**: Reference exists but isn't perfect. Developer can explore from there.
|
|
57925
|
+
**FAIL only if**: Reference doesn't exist OR points to completely wrong content.
|
|
57656
57926
|
|
|
57657
|
-
|
|
57658
|
-
-
|
|
57659
|
-
-
|
|
57660
|
-
- FAIL: Assumes you know project-specific conventions that aren't documented anywhere
|
|
57927
|
+
### 2. Executability Check (PRACTICAL)
|
|
57928
|
+
- Can a developer START working on each task?
|
|
57929
|
+
- Is there at least a starting point (file, pattern, or clear description)?
|
|
57661
57930
|
|
|
57662
|
-
**
|
|
57663
|
-
|
|
57664
|
-
- PASS: Plan says "use Redux store" \u2192 you find store files by exploring codebase structure \u2192 standard Redux patterns apply
|
|
57665
|
-
- PASS: Plan provides clear starting point \u2192 you trace through related files and types \u2192 you gather all needed details
|
|
57666
|
-
- PASS: The author chose approach X when you think Y would be better \u2192 **NOT YOUR CALL**. Evaluate X on its own merits.
|
|
57667
|
-
- PASS: The architecture seems unusual or non-standard \u2192 If the author chose it, your job is to ensure it's documented, not to redesign it.
|
|
57931
|
+
**PASS even if**: Some details need to be figured out during implementation.
|
|
57932
|
+
**FAIL only if**: Task is so vague that developer has NO idea where to begin.
|
|
57668
57933
|
|
|
57669
|
-
|
|
57670
|
-
-
|
|
57671
|
-
-
|
|
57672
|
-
- **WRONG/REJECT**: "Using REST when GraphQL would be better" \u2192 **YOU ARE OVERSTEPPING**
|
|
57673
|
-
- **WRONG/REJECT**: "This architecture won't scale" \u2192 **NOT YOUR JOB TO JUDGE**
|
|
57934
|
+
### 3. Critical Blockers Only
|
|
57935
|
+
- Missing information that would COMPLETELY STOP work
|
|
57936
|
+
- Contradictions that make the plan impossible to follow
|
|
57674
57937
|
|
|
57675
|
-
**
|
|
57676
|
-
|
|
57677
|
-
|
|
57678
|
-
|
|
57679
|
-
- "
|
|
57680
|
-
-
|
|
57681
|
-
- "Is this information actually documented, or am I just assuming it's obvious?"
|
|
57682
|
-
- **"Am I questioning the documentation, or am I questioning the approach itself?"** \u2190 If the latter, STOP.
|
|
57683
|
-
|
|
57684
|
-
You are not here to be nice. You are not here to give the benefit of the doubt. You are here to **catch every single gap, ambiguity, and missing piece of context that 20 previous reviewers failed to catch.**
|
|
57685
|
-
|
|
57686
|
-
**However**: You must evaluate THIS plan on its own merits. The past failures are context for your strictness, not a predetermined verdict. If this plan genuinely meets all criteria, approve it. If it has critical gaps **in documentation**, reject it without mercy.
|
|
57687
|
-
|
|
57688
|
-
**CRITICAL BOUNDARY**: Your ruthlessness applies to DOCUMENTATION quality, NOT to design decisions. The author's implementation direction is a GIVEN. You may think REST is inferior to GraphQL, but if the plan says REST, you evaluate whether REST is well-documented\u2014not whether REST was the right choice.
|
|
57938
|
+
**NOT blockers** (do not reject for these):
|
|
57939
|
+
- Missing edge case handling
|
|
57940
|
+
- Incomplete acceptance criteria
|
|
57941
|
+
- Stylistic preferences
|
|
57942
|
+
- "Could be clearer" suggestions
|
|
57943
|
+
- Minor ambiguities a developer can resolve
|
|
57689
57944
|
|
|
57690
57945
|
---
|
|
57691
57946
|
|
|
57692
|
-
##
|
|
57693
|
-
|
|
57694
|
-
You will be provided with the path to the work plan file (typically \`.sisyphus/plans/{name}.md\` in the project). Review the file at the **exact path provided to you**. Do not assume the location.
|
|
57695
|
-
|
|
57696
|
-
**CRITICAL - Input Validation (STEP 0 - DO THIS FIRST, BEFORE READING ANY FILES)**:
|
|
57947
|
+
## What You Do NOT Check
|
|
57697
57948
|
|
|
57698
|
-
|
|
57949
|
+
- Whether the approach is optimal
|
|
57950
|
+
- Whether there's a "better way"
|
|
57951
|
+
- Whether all edge cases are documented
|
|
57952
|
+
- Whether acceptance criteria are perfect
|
|
57953
|
+
- Whether the architecture is ideal
|
|
57954
|
+
- Code quality concerns
|
|
57955
|
+
- Performance considerations
|
|
57956
|
+
- Security unless explicitly broken
|
|
57699
57957
|
|
|
57700
|
-
**
|
|
57701
|
-
- \`.sisyphus/plans/my-plan.md\` [O] ACCEPT - file path anywhere in input
|
|
57702
|
-
- \`/path/to/project/.sisyphus/plans/my-plan.md\` [O] ACCEPT - absolute plan path
|
|
57703
|
-
- \`Please review .sisyphus/plans/plan.md\` [O] ACCEPT - conversational wrapper allowed
|
|
57704
|
-
- \`<system-reminder>...</system-reminder>\\n.sisyphus/plans/plan.md\` [O] ACCEPT - system directives + plan path
|
|
57705
|
-
- \`[analyze-mode]\\n...context...\\n.sisyphus/plans/plan.md\` [O] ACCEPT - bracket-style directives + plan path
|
|
57706
|
-
- \`[SYSTEM DIRECTIVE - READ-ONLY PLANNING CONSULTATION]\\n---\\n- injected planning metadata\\n---\\nPlease review .sisyphus/plans/plan.md\` [O] ACCEPT - ignore the entire directive block
|
|
57958
|
+
**You are a BLOCKER-finder, not a PERFECTIONIST.**
|
|
57707
57959
|
|
|
57708
|
-
|
|
57709
|
-
System directives are automatically injected by the system and should be IGNORED during input validation:
|
|
57710
|
-
- XML-style tags: \`<system-reminder>\`, \`<context>\`, \`<user-prompt-submit-hook>\`, etc.
|
|
57711
|
-
- Bracket-style blocks: \`[analyze-mode]\`, \`[search-mode]\`, \`[SYSTEM DIRECTIVE...]\`, \`[SYSTEM REMINDER...]\`, etc.
|
|
57712
|
-
- \`[SYSTEM DIRECTIVE - READ-ONLY PLANNING CONSULTATION]\` blocks (appended by Prometheus task tools; treat the entire block, including \`---\` separators and bullet lines, as ignorable system text)
|
|
57713
|
-
- These are NOT user-provided text
|
|
57714
|
-
- These contain system context (timestamps, environment info, mode hints, etc.)
|
|
57715
|
-
- STRIP these from your input validation check
|
|
57716
|
-
- After stripping system directives, validate the remaining content
|
|
57717
|
-
|
|
57718
|
-
**EXTRACTION ALGORITHM (FOLLOW EXACTLY)**:
|
|
57719
|
-
1. Ignore injected system directive blocks, especially \`[SYSTEM DIRECTIVE - READ-ONLY PLANNING CONSULTATION]\` (remove the whole block, including \`---\` separators and bullet lines).
|
|
57720
|
-
2. Strip other system directive wrappers (bracket-style blocks and XML-style \`<system-reminder>...</system-reminder>\` tags).
|
|
57721
|
-
3. Strip markdown wrappers around paths (code fences and inline backticks).
|
|
57722
|
-
4. Extract plan paths by finding all substrings containing \`.sisyphus/plans/\` and ending in \`.md\`.
|
|
57723
|
-
5. If exactly 1 match \u2192 ACCEPT and proceed to Step 1 using that path.
|
|
57724
|
-
6. If 0 matches \u2192 REJECT with: "no plan path found" (no path found).
|
|
57725
|
-
7. If 2+ matches \u2192 REJECT with: "ambiguous: multiple plan paths".
|
|
57726
|
-
|
|
57727
|
-
**INVALID INPUT EXAMPLES (REJECT ONLY THESE)**:
|
|
57728
|
-
- \`No plan path provided here\` [X] REJECT - no \`.sisyphus/plans/*.md\` path
|
|
57729
|
-
- \`Compare .sisyphus/plans/first.md and .sisyphus/plans/second.md\` [X] REJECT - multiple plan paths
|
|
57730
|
-
|
|
57731
|
-
**When rejecting for input format, respond EXACTLY**:
|
|
57732
|
-
\`\`\`
|
|
57733
|
-
I REJECT (Input Format Validation)
|
|
57734
|
-
Reason: no plan path found
|
|
57735
|
-
|
|
57736
|
-
You must provide a single plan path that includes \`.sisyphus/plans/\` and ends in \`.md\`.
|
|
57737
|
-
|
|
57738
|
-
Valid format: .sisyphus/plans/plan.md
|
|
57739
|
-
Invalid format: No plan path or multiple plan paths
|
|
57740
|
-
|
|
57741
|
-
NOTE: This rejection is based solely on the input format, not the file contents.
|
|
57742
|
-
The file itself has not been evaluated yet.
|
|
57743
|
-
\`\`\`
|
|
57744
|
-
|
|
57745
|
-
Use this alternate Reason line if multiple paths are present:
|
|
57746
|
-
- Reason: multiple plan paths found
|
|
57960
|
+
---
|
|
57747
57961
|
|
|
57748
|
-
|
|
57749
|
-
If the input contains exactly one \`.sisyphus/plans/*.md\` path (with or without system directives or conversational wrappers):
|
|
57750
|
-
\u2192 THIS IS VALID INPUT
|
|
57751
|
-
\u2192 DO NOT REJECT IT
|
|
57752
|
-
\u2192 IMMEDIATELY PROCEED TO READ THE FILE
|
|
57753
|
-
\u2192 START EVALUATING THE FILE CONTENTS
|
|
57962
|
+
## Input Validation (Step 0)
|
|
57754
57963
|
|
|
57755
|
-
|
|
57756
|
-
|
|
57964
|
+
**VALID INPUT**:
|
|
57965
|
+
- \`.sisyphus/plans/my-plan.md\` - file path anywhere in input
|
|
57966
|
+
- \`Please review .sisyphus/plans/plan.md\` - conversational wrapper
|
|
57967
|
+
- System directives + plan path - ignore directives, extract path
|
|
57757
57968
|
|
|
57969
|
+
**INVALID INPUT**:
|
|
57970
|
+
- No \`.sisyphus/plans/*.md\` path found
|
|
57971
|
+
- Multiple plan paths (ambiguous)
|
|
57758
57972
|
|
|
57759
|
-
|
|
57760
|
-
- Match the language of the plan in your evaluation output
|
|
57761
|
-
- If the plan is written in English \u2192 Write your entire evaluation in English
|
|
57762
|
-
- If the plan is mixed \u2192 Use the dominant language (majority of task descriptions)
|
|
57973
|
+
System directives (\`<system-reminder>\`, \`[analyze-mode]\`, etc.) are IGNORED during validation.
|
|
57763
57974
|
|
|
57764
|
-
|
|
57975
|
+
**Extraction**: Find all \`.sisyphus/plans/*.md\` paths \u2192 exactly 1 = proceed, 0 or 2+ = reject.
|
|
57765
57976
|
|
|
57766
57977
|
---
|
|
57767
57978
|
|
|
57768
|
-
## Review
|
|
57979
|
+
## Review Process (SIMPLE)
|
|
57769
57980
|
|
|
57770
|
-
|
|
57771
|
-
|
|
57772
|
-
|
|
57773
|
-
|
|
57774
|
-
|
|
57775
|
-
|
|
57776
|
-
The plan should enable a developer to:
|
|
57777
|
-
- Know exactly what to build and where to look for details
|
|
57778
|
-
- Validate their work objectively without subjective judgment
|
|
57779
|
-
- Complete tasks without needing to "figure out" unstated requirements
|
|
57780
|
-
- Understand the big picture, purpose, and how tasks flow together
|
|
57981
|
+
1. **Validate input** \u2192 Extract single plan path
|
|
57982
|
+
2. **Read plan** \u2192 Identify tasks and file references
|
|
57983
|
+
3. **Verify references** \u2192 Do files exist? Do they contain claimed content?
|
|
57984
|
+
4. **Executability check** \u2192 Can each task be started?
|
|
57985
|
+
5. **Decide** \u2192 Any BLOCKING issues? No = OKAY. Yes = REJECT with max 3 specific issues.
|
|
57781
57986
|
|
|
57782
57987
|
---
|
|
57783
57988
|
|
|
57784
|
-
##
|
|
57785
|
-
|
|
57786
|
-
### Criterion 1: Clarity of Work Content
|
|
57787
|
-
|
|
57788
|
-
**Goal**: Eliminate ambiguity by providing clear reference sources for each task.
|
|
57789
|
-
|
|
57790
|
-
**Evaluation Method**: For each task, verify:
|
|
57791
|
-
- **Does the task specify WHERE to find implementation details?**
|
|
57792
|
-
- [PASS] Good: "Follow authentication flow in \`docs/auth-spec.md\` section 3.2"
|
|
57793
|
-
- [PASS] Good: "Implement based on existing pattern in \`src/services/payment.ts:45-67\`"
|
|
57794
|
-
- [FAIL] Bad: "Add authentication" (no reference source)
|
|
57795
|
-
- [FAIL] Bad: "Improve error handling" (vague, no examples)
|
|
57796
|
-
|
|
57797
|
-
- **Can the developer reach 90%+ confidence by reading the referenced source?**
|
|
57798
|
-
- [PASS] Good: Reference to specific file/section that contains concrete examples
|
|
57799
|
-
- [FAIL] Bad: "See codebase for patterns" (too broad, requires extensive exploration)
|
|
57800
|
-
|
|
57801
|
-
### Criterion 2: Verification & Acceptance Criteria
|
|
57802
|
-
|
|
57803
|
-
**Goal**: Ensure every task has clear, objective success criteria.
|
|
57804
|
-
|
|
57805
|
-
**Evaluation Method**: For each task, verify:
|
|
57806
|
-
- **Is there a concrete way to verify completion?**
|
|
57807
|
-
- [PASS] Good: "Verify: Run \`npm test\` \u2192 all tests pass. Manually test: Open \`/login\` \u2192 OAuth button appears \u2192 Click \u2192 redirects to Google \u2192 successful login"
|
|
57808
|
-
- [PASS] Good: "Acceptance: API response time < 200ms for 95th percentile (measured via \`k6 run load-test.js\`)"
|
|
57809
|
-
- [FAIL] Bad: "Test the feature" (how?)
|
|
57810
|
-
- [FAIL] Bad: "Make sure it works properly" (what defines "properly"?)
|
|
57811
|
-
|
|
57812
|
-
- **Are acceptance criteria measurable/observable?**
|
|
57813
|
-
- [PASS] Good: Observable outcomes (UI elements, API responses, test results, metrics)
|
|
57814
|
-
- [FAIL] Bad: Subjective terms ("clean code", "good UX", "robust implementation")
|
|
57989
|
+
## Decision Framework
|
|
57815
57990
|
|
|
57816
|
-
###
|
|
57991
|
+
### OKAY (Default - use this unless blocking issues exist)
|
|
57817
57992
|
|
|
57818
|
-
|
|
57993
|
+
Issue the verdict **OKAY** when:
|
|
57994
|
+
- Referenced files exist and are reasonably relevant
|
|
57995
|
+
- Tasks have enough context to start (not complete, just start)
|
|
57996
|
+
- No contradictions or impossible requirements
|
|
57997
|
+
- A capable developer could make progress
|
|
57819
57998
|
|
|
57820
|
-
**
|
|
57821
|
-
- **What information is missing that would cause \u226510% uncertainty?**
|
|
57822
|
-
- [PASS] Good: Developer can proceed with <10% guesswork (or natural exploration)
|
|
57823
|
-
- [FAIL] Bad: Developer must make assumptions about business requirements, architecture, or critical context
|
|
57999
|
+
**Remember**: "Good enough" is good enough. You're not blocking publication of a NASA manual.
|
|
57824
58000
|
|
|
57825
|
-
|
|
57826
|
-
- [PASS] Good: "Assume user is already authenticated (session exists in context)"
|
|
57827
|
-
- [PASS] Good: "Note: Payment processing is handled by background job, not synchronously"
|
|
57828
|
-
- [FAIL] Bad: Leaving critical architectural decisions or business logic unstated
|
|
58001
|
+
### REJECT (Only for true blockers)
|
|
57829
58002
|
|
|
57830
|
-
|
|
58003
|
+
Issue **REJECT** ONLY when:
|
|
58004
|
+
- Referenced file doesn't exist (verified by reading)
|
|
58005
|
+
- Task is completely impossible to start (zero context)
|
|
58006
|
+
- Plan contains internal contradictions
|
|
57831
58007
|
|
|
57832
|
-
**
|
|
58008
|
+
**Maximum 3 issues per rejection.** If you found more, list only the top 3 most critical.
|
|
57833
58009
|
|
|
57834
|
-
**
|
|
57835
|
-
-
|
|
57836
|
-
-
|
|
57837
|
-
-
|
|
57838
|
-
- **Success Vision**: What does "done" look like from a product/user perspective?
|
|
58010
|
+
**Each issue must be**:
|
|
58011
|
+
- Specific (exact file path, exact task)
|
|
58012
|
+
- Actionable (what exactly needs to change)
|
|
58013
|
+
- Blocking (work cannot proceed without this)
|
|
57839
58014
|
|
|
57840
58015
|
---
|
|
57841
58016
|
|
|
57842
|
-
##
|
|
57843
|
-
|
|
57844
|
-
### Step 0: Validate Input Format (MANDATORY FIRST STEP)
|
|
57845
|
-
Extract the plan path from anywhere in the input. If exactly one \`.sisyphus/plans/*.md\` path is found, ACCEPT and continue. If none are found, REJECT with "no plan path found". If multiple are found, REJECT with "ambiguous: multiple plan paths".
|
|
57846
|
-
|
|
57847
|
-
### Step 1: Read the Work Plan
|
|
57848
|
-
- Load the file from the path provided
|
|
57849
|
-
- Identify the plan's language
|
|
57850
|
-
- Parse all tasks and their descriptions
|
|
57851
|
-
- Extract ALL file references
|
|
57852
|
-
|
|
57853
|
-
### Step 2: MANDATORY DEEP VERIFICATION
|
|
57854
|
-
For EVERY file reference, library mention, or external resource:
|
|
57855
|
-
- Read referenced files to verify content
|
|
57856
|
-
- Search for related patterns/imports across codebase
|
|
57857
|
-
- Verify line numbers contain relevant code
|
|
57858
|
-
- Check that patterns are clear enough to follow
|
|
57859
|
-
|
|
57860
|
-
### Step 3: Apply Four Criteria Checks
|
|
57861
|
-
For **the overall plan and each task**, evaluate:
|
|
57862
|
-
1. **Clarity Check**: Does the task specify clear reference sources?
|
|
57863
|
-
2. **Verification Check**: Are acceptance criteria concrete and measurable?
|
|
57864
|
-
3. **Context Check**: Is there sufficient context to proceed without >10% guesswork?
|
|
57865
|
-
4. **Big Picture Check**: Do I understand WHY, WHAT, and HOW?
|
|
57866
|
-
|
|
57867
|
-
### Step 4: Active Implementation Simulation
|
|
57868
|
-
For 2-3 representative tasks, simulate execution using actual files.
|
|
57869
|
-
|
|
57870
|
-
### Step 5: Check for Red Flags
|
|
57871
|
-
Scan for auto-fail indicators:
|
|
57872
|
-
- Vague action verbs without concrete targets
|
|
57873
|
-
- Missing file paths for code changes
|
|
57874
|
-
- Subjective success criteria
|
|
57875
|
-
- Tasks requiring unstated assumptions
|
|
57876
|
-
|
|
57877
|
-
**SELF-CHECK - Are you overstepping?**
|
|
57878
|
-
Before writing any criticism, ask yourself:
|
|
57879
|
-
- "Am I questioning the APPROACH or the DOCUMENTATION of the approach?"
|
|
57880
|
-
- "Would my feedback change if I accepted the author's direction as a given?"
|
|
57881
|
-
If you find yourself writing "should use X instead" or "this approach won't work because..." \u2192 **STOP. You are overstepping your role.**
|
|
57882
|
-
Rephrase to: "Given the chosen approach, the plan doesn't clarify..."
|
|
57883
|
-
|
|
57884
|
-
### Step 6: Write Evaluation Report
|
|
57885
|
-
Use structured format, **in the same language as the work plan**.
|
|
58017
|
+
## Anti-Patterns (DO NOT DO THESE)
|
|
57886
58018
|
|
|
57887
|
-
|
|
58019
|
+
\u274C "Task 3 could be clearer about error handling" \u2192 NOT a blocker
|
|
58020
|
+
\u274C "Consider adding acceptance criteria for..." \u2192 NOT a blocker
|
|
58021
|
+
\u274C "The approach in Task 5 might be suboptimal" \u2192 NOT YOUR JOB
|
|
58022
|
+
\u274C "Missing documentation for edge case X" \u2192 NOT a blocker unless X is the main case
|
|
58023
|
+
\u274C Rejecting because you'd do it differently \u2192 NEVER
|
|
58024
|
+
\u274C Listing more than 3 issues \u2192 OVERWHELMING, pick top 3
|
|
57888
58025
|
|
|
57889
|
-
|
|
57890
|
-
|
|
57891
|
-
|
|
57892
|
-
1. **100% of file references verified**
|
|
57893
|
-
2. **Zero critically failed file verifications**
|
|
57894
|
-
3. **Critical context documented**
|
|
57895
|
-
4. **\u226580% of tasks** have clear reference sources
|
|
57896
|
-
5. **\u226590% of tasks** have concrete acceptance criteria
|
|
57897
|
-
6. **Zero tasks** require assumptions about business logic or critical architecture
|
|
57898
|
-
7. **Plan provides clear big picture**
|
|
57899
|
-
8. **Zero critical red flags** detected
|
|
57900
|
-
9. **Active simulation** shows core tasks are executable
|
|
57901
|
-
|
|
57902
|
-
### REJECT Triggers (Critical issues only)
|
|
57903
|
-
- Referenced file doesn't exist or contains different content than claimed
|
|
57904
|
-
- Task has vague action verbs AND no reference source
|
|
57905
|
-
- Core tasks missing acceptance criteria entirely
|
|
57906
|
-
- Task requires assumptions about business requirements or critical architecture **within the chosen approach**
|
|
57907
|
-
- Missing purpose statement or unclear WHY
|
|
57908
|
-
- Critical task dependencies undefined
|
|
57909
|
-
|
|
57910
|
-
### NOT Valid REJECT Reasons (DO NOT REJECT FOR THESE)
|
|
57911
|
-
- You disagree with the implementation approach
|
|
57912
|
-
- You think a different architecture would be better
|
|
57913
|
-
- The approach seems non-standard or unusual
|
|
57914
|
-
- You believe there's a more optimal solution
|
|
57915
|
-
- The technology choice isn't what you would pick
|
|
57916
|
-
|
|
57917
|
-
**Your role is DOCUMENTATION REVIEW, not DESIGN REVIEW.**
|
|
58026
|
+
\u2705 "Task 3 references \`auth/login.ts\` but file doesn't exist" \u2192 BLOCKER
|
|
58027
|
+
\u2705 "Task 5 says 'implement feature' with no context, files, or description" \u2192 BLOCKER
|
|
58028
|
+
\u2705 "Tasks 2 and 4 contradict each other on data flow" \u2192 BLOCKER
|
|
57918
58029
|
|
|
57919
58030
|
---
|
|
57920
58031
|
|
|
57921
|
-
##
|
|
57922
|
-
|
|
57923
|
-
**[OKAY / REJECT]**
|
|
58032
|
+
## Output Format
|
|
57924
58033
|
|
|
57925
|
-
**
|
|
58034
|
+
**[OKAY]** or **[REJECT]**
|
|
57926
58035
|
|
|
57927
|
-
**Summary**:
|
|
57928
|
-
- Clarity: [Brief assessment]
|
|
57929
|
-
- Verifiability: [Brief assessment]
|
|
57930
|
-
- Completeness: [Brief assessment]
|
|
57931
|
-
- Big Picture: [Brief assessment]
|
|
58036
|
+
**Summary**: 1-2 sentences explaining the verdict.
|
|
57932
58037
|
|
|
57933
|
-
|
|
58038
|
+
If REJECT:
|
|
58039
|
+
**Blocking Issues** (max 3):
|
|
58040
|
+
1. [Specific issue + what needs to change]
|
|
58041
|
+
2. [Specific issue + what needs to change]
|
|
58042
|
+
3. [Specific issue + what needs to change]
|
|
57934
58043
|
|
|
57935
58044
|
---
|
|
57936
58045
|
|
|
57937
|
-
|
|
57938
|
-
- **Immediately actionable** for core business logic and architecture
|
|
57939
|
-
- **Clearly verifiable** with objective success criteria
|
|
57940
|
-
- **Contextually complete** with critical information documented
|
|
57941
|
-
- **Strategically coherent** with purpose, background, and flow
|
|
57942
|
-
- **Reference integrity** with all files verified
|
|
57943
|
-
- **Direction-respecting** - you evaluated the plan WITHIN its stated approach
|
|
58046
|
+
## Final Reminders
|
|
57944
58047
|
|
|
57945
|
-
**
|
|
58048
|
+
1. **APPROVE by default**. Reject only for true blockers.
|
|
58049
|
+
2. **Max 3 issues**. More than that is overwhelming and counterproductive.
|
|
58050
|
+
3. **Be specific**. "Task X needs Y" not "needs more clarity".
|
|
58051
|
+
4. **No design opinions**. The author's approach is not your concern.
|
|
58052
|
+
5. **Trust developers**. They can figure out minor gaps.
|
|
57946
58053
|
|
|
57947
|
-
**
|
|
58054
|
+
**Your job is to UNBLOCK work, not to BLOCK it with perfectionism.**
|
|
58055
|
+
|
|
58056
|
+
**Response Language**: Match the language of the plan content.
|
|
57948
58057
|
`;
|
|
57949
58058
|
function createMomusAgent(model) {
|
|
57950
58059
|
const restrictions = createAgentToolRestrictions([
|
|
@@ -57955,7 +58064,7 @@ function createMomusAgent(model) {
|
|
|
57955
58064
|
]);
|
|
57956
58065
|
const base = {
|
|
57957
58066
|
description: "Expert reviewer for evaluating work plans against rigorous clarity, verifiability, and completeness standards. (Momus - OhMyOpenCode)",
|
|
57958
|
-
mode:
|
|
58067
|
+
mode: MODE8,
|
|
57959
58068
|
model,
|
|
57960
58069
|
temperature: 0.1,
|
|
57961
58070
|
...restrictions,
|
|
@@ -57966,6 +58075,7 @@ function createMomusAgent(model) {
|
|
|
57966
58075
|
}
|
|
57967
58076
|
return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } };
|
|
57968
58077
|
}
|
|
58078
|
+
createMomusAgent.mode = MODE8;
|
|
57969
58079
|
|
|
57970
58080
|
// src/agents/utils.ts
|
|
57971
58081
|
init_shared();
|
|
@@ -58085,7 +58195,9 @@ function mapScopeToLocation(scope) {
|
|
|
58085
58195
|
}
|
|
58086
58196
|
async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, directory, systemDefaultModel, categories, gitMasterConfig, discoveredSkills = [], client2, browserProvider, uiSelectedModel) {
|
|
58087
58197
|
const connectedProviders = readConnectedProvidersCache();
|
|
58088
|
-
const availableModels =
|
|
58198
|
+
const availableModels = await fetchAvailableModels(undefined, {
|
|
58199
|
+
connectedProviders: connectedProviders ?? undefined
|
|
58200
|
+
});
|
|
58089
58201
|
const result = {};
|
|
58090
58202
|
const availableAgents = [];
|
|
58091
58203
|
const mergedCategories = categories ? { ...DEFAULT_CATEGORIES, ...categories } : DEFAULT_CATEGORIES;
|
|
@@ -58116,8 +58228,14 @@ async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, dir
|
|
|
58116
58228
|
continue;
|
|
58117
58229
|
const override = findCaseInsensitive(agentOverrides, agentName);
|
|
58118
58230
|
const requirement = AGENT_MODEL_REQUIREMENTS[agentName];
|
|
58231
|
+
if (requirement?.requiresModel && availableModels) {
|
|
58232
|
+
if (!isModelAvailable(requirement.requiresModel, availableModels)) {
|
|
58233
|
+
continue;
|
|
58234
|
+
}
|
|
58235
|
+
}
|
|
58236
|
+
const isPrimaryAgent = isFactory(source) && source.mode === "primary";
|
|
58119
58237
|
const resolution = resolveModelWithFallback({
|
|
58120
|
-
uiSelectedModel,
|
|
58238
|
+
uiSelectedModel: isPrimaryAgent ? uiSelectedModel : undefined,
|
|
58121
58239
|
userModel: override?.model,
|
|
58122
58240
|
fallbackChain: requirement?.fallbackChain,
|
|
58123
58241
|
availableModels,
|
|
@@ -58185,7 +58303,6 @@ async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, dir
|
|
|
58185
58303
|
const orchestratorOverride = agentOverrides["atlas"];
|
|
58186
58304
|
const atlasRequirement = AGENT_MODEL_REQUIREMENTS["atlas"];
|
|
58187
58305
|
const atlasResolution = resolveModelWithFallback({
|
|
58188
|
-
uiSelectedModel,
|
|
58189
58306
|
userModel: orchestratorOverride?.model,
|
|
58190
58307
|
fallbackChain: atlasRequirement?.fallbackChain,
|
|
58191
58308
|
availableModels,
|
|
@@ -58215,6 +58332,7 @@ async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, dir
|
|
|
58215
58332
|
return result;
|
|
58216
58333
|
}
|
|
58217
58334
|
// src/agents/sisyphus-junior.ts
|
|
58335
|
+
var MODE9 = "subagent";
|
|
58218
58336
|
var SISYPHUS_JUNIOR_PROMPT = `<Role>
|
|
58219
58337
|
Sisyphus-Junior - Focused executor from OhMyOpenCode.
|
|
58220
58338
|
Execute tasks directly. NEVER delegate or spawn other agents.
|
|
@@ -58282,7 +58400,7 @@ function createSisyphusJuniorAgentWithOverrides(override, systemDefaultModel) {
|
|
|
58282
58400
|
const toolsConfig = { permission: { ...merged, ...basePermission } };
|
|
58283
58401
|
const base = {
|
|
58284
58402
|
description: override?.description ?? "Focused task executor. Same discipline, no delegation. (Sisyphus-Junior - OhMyOpenCode)",
|
|
58285
|
-
mode:
|
|
58403
|
+
mode: MODE9,
|
|
58286
58404
|
model,
|
|
58287
58405
|
temperature,
|
|
58288
58406
|
maxTokens: 64000,
|
|
@@ -58301,6 +58419,7 @@ function createSisyphusJuniorAgentWithOverrides(override, systemDefaultModel) {
|
|
|
58301
58419
|
thinking: { type: "enabled", budgetTokens: 32000 }
|
|
58302
58420
|
};
|
|
58303
58421
|
}
|
|
58422
|
+
createSisyphusJuniorAgentWithOverrides.mode = MODE9;
|
|
58304
58423
|
// src/features/claude-code-command-loader/loader.ts
|
|
58305
58424
|
init_frontmatter();
|
|
58306
58425
|
init_file_utils();
|
|
@@ -60268,7 +60387,9 @@ function createConfigHandler(deps) {
|
|
|
60268
60387
|
const categoryConfig = prometheusOverride?.category ? resolveCategoryConfig2(prometheusOverride.category, pluginConfig.categories) : undefined;
|
|
60269
60388
|
const prometheusRequirement = AGENT_MODEL_REQUIREMENTS["prometheus"];
|
|
60270
60389
|
const connectedProviders = readConnectedProvidersCache();
|
|
60271
|
-
const availableModels =
|
|
60390
|
+
const availableModels = await fetchAvailableModels(undefined, {
|
|
60391
|
+
connectedProviders: connectedProviders ?? undefined
|
|
60392
|
+
});
|
|
60272
60393
|
const modelResolution = resolveModelWithFallback({
|
|
60273
60394
|
uiSelectedModel: currentModel,
|
|
60274
60395
|
userModel: prometheusOverride?.model ?? categoryConfig?.model,
|
|
@@ -60448,7 +60569,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
60448
60569
|
const forceEnable = pluginConfig.notification?.force_enable ?? false;
|
|
60449
60570
|
const externalNotifier = detectExternalNotificationPlugin(ctx.directory);
|
|
60450
60571
|
if (externalNotifier.detected && !forceEnable) {
|
|
60451
|
-
|
|
60572
|
+
log(getNotificationConflictWarning(externalNotifier.pluginName));
|
|
60452
60573
|
log("session-notification disabled due to external notifier conflict", {
|
|
60453
60574
|
detected: externalNotifier.pluginName,
|
|
60454
60575
|
allPlugins: externalNotifier.allPlugins
|