oh-my-opencode-slim 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/agents/orchestrator.d.ts +9 -1
- package/dist/cli/index.js +10 -1
- package/dist/config/constants.d.ts +1 -1
- package/dist/config/loader.d.ts +4 -1
- package/dist/config/schema.d.ts +21 -4
- package/dist/hooks/chat-headers.d.ts +16 -0
- package/dist/hooks/delegate-task-retry/index.d.ts +2 -2
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/phase-reminder/index.d.ts +1 -0
- package/dist/index.js +188 -32
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/internal-initiator.d.ts +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="img/team.png" alt="Pantheon agents" width="420">
|
|
3
3
|
<p><i>Six divine beings emerged from the dawn of code, each an immortal master of their craft await your command to forge order from chaos and build what was once thought impossible.</i></p>
|
|
4
4
|
<p><b>Open Multi Agent Suite</b> · Mix any models · Auto delegate tasks</p>
|
|
5
|
-
<p><a href="https://moltfounders.com/
|
|
5
|
+
<p><a href="https://moltfounders.com/jobs/09d1c6e7-9e0e-4683-8d78-e2376aaa2333"><img src="https://moltfounders.com/badges/4.png" alt="MoltFounders" height="30"></a></p>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
---
|
|
@@ -259,6 +259,6 @@ MIT
|
|
|
259
259
|
---
|
|
260
260
|
|
|
261
261
|
<!-- MoltFounders Banner -->
|
|
262
|
-
<a href="https://moltfounders.com/
|
|
262
|
+
<a href="https://moltfounders.com/jobs/09d1c6e7-9e0e-4683-8d78-e2376aaa2333">
|
|
263
263
|
<img src="img/moltfounders-banner.png" alt="MoltFounders - The Agent Co-Founder Network">
|
|
264
264
|
</a>
|
|
@@ -3,5 +3,13 @@ export interface AgentDefinition {
|
|
|
3
3
|
name: string;
|
|
4
4
|
description?: string;
|
|
5
5
|
config: AgentConfig;
|
|
6
|
+
/** Priority-ordered model entries for runtime fallback resolution. */
|
|
7
|
+
_modelArray?: Array<{
|
|
8
|
+
id: string;
|
|
9
|
+
variant?: string;
|
|
10
|
+
}>;
|
|
6
11
|
}
|
|
7
|
-
export declare function createOrchestratorAgent(model
|
|
12
|
+
export declare function createOrchestratorAgent(model?: string | Array<string | {
|
|
13
|
+
id: string;
|
|
14
|
+
variant?: string;
|
|
15
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
package/dist/cli/index.js
CHANGED
|
@@ -13704,7 +13704,16 @@ var FallbackChainsSchema = exports_external.object({
|
|
|
13704
13704
|
fixer: AgentModelChainSchema.optional()
|
|
13705
13705
|
}).catchall(AgentModelChainSchema);
|
|
13706
13706
|
var AgentOverrideConfigSchema = exports_external.object({
|
|
13707
|
-
model: exports_external.
|
|
13707
|
+
model: exports_external.union([
|
|
13708
|
+
exports_external.string(),
|
|
13709
|
+
exports_external.array(exports_external.union([
|
|
13710
|
+
exports_external.string(),
|
|
13711
|
+
exports_external.object({
|
|
13712
|
+
id: exports_external.string(),
|
|
13713
|
+
variant: exports_external.string().optional()
|
|
13714
|
+
})
|
|
13715
|
+
]))
|
|
13716
|
+
]).optional(),
|
|
13708
13717
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
13709
13718
|
variant: exports_external.string().optional().catch(undefined),
|
|
13710
13719
|
skills: exports_external.array(exports_external.string()).optional(),
|
|
@@ -4,7 +4,7 @@ export declare const ORCHESTRATOR_NAME: "orchestrator";
|
|
|
4
4
|
export declare const ALL_AGENT_NAMES: readonly ["orchestrator", "explorer", "librarian", "oracle", "designer", "fixer"];
|
|
5
5
|
export type AgentName = (typeof ALL_AGENT_NAMES)[number];
|
|
6
6
|
export declare const SUBAGENT_DELEGATION_RULES: Record<AgentName, readonly string[]>;
|
|
7
|
-
export declare const DEFAULT_MODELS: Record<AgentName, string>;
|
|
7
|
+
export declare const DEFAULT_MODELS: Record<AgentName, string | undefined>;
|
|
8
8
|
export declare const POLL_INTERVAL_MS = 500;
|
|
9
9
|
export declare const POLL_INTERVAL_SLOW_MS = 1000;
|
|
10
10
|
export declare const POLL_INTERVAL_BACKGROUND_MS = 2000;
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -17,11 +17,14 @@ export declare function loadPluginConfig(directory: string): PluginConfig;
|
|
|
17
17
|
/**
|
|
18
18
|
* Load custom prompt for an agent from the prompts directory.
|
|
19
19
|
* Checks for {agent}.md (replaces default) and {agent}_append.md (appends to default).
|
|
20
|
+
* If preset is provided and safe for paths, it first checks {preset}/ subdirectory,
|
|
21
|
+
* then falls back to the root prompts directory.
|
|
20
22
|
*
|
|
21
23
|
* @param agentName - Name of the agent (e.g., "orchestrator", "explorer")
|
|
24
|
+
* @param preset - Optional preset name for preset-scoped prompt lookup
|
|
22
25
|
* @returns Object with prompt and/or appendPrompt if files exist
|
|
23
26
|
*/
|
|
24
|
-
export declare function loadAgentPrompt(agentName: string): {
|
|
27
|
+
export declare function loadAgentPrompt(agentName: string, preset?: string): {
|
|
25
28
|
prompt?: string;
|
|
26
29
|
appendPrompt?: string;
|
|
27
30
|
};
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -50,7 +50,10 @@ export type ManualAgentPlan = z.infer<typeof ManualAgentPlanSchema>;
|
|
|
50
50
|
export type ManualPlan = z.infer<typeof ManualPlanSchema>;
|
|
51
51
|
export type FallbackAgentName = (typeof FALLBACK_AGENT_NAMES)[number];
|
|
52
52
|
export declare const AgentOverrideConfigSchema: z.ZodObject<{
|
|
53
|
-
model: z.ZodOptional<z.ZodString
|
|
53
|
+
model: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
54
|
+
id: z.ZodString;
|
|
55
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
56
|
+
}, z.core.$strip>]>>]>>;
|
|
54
57
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
55
58
|
variant: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
56
59
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -77,8 +80,16 @@ export declare const TmuxConfigSchema: z.ZodObject<{
|
|
|
77
80
|
}, z.core.$strip>;
|
|
78
81
|
export type TmuxConfig = z.infer<typeof TmuxConfigSchema>;
|
|
79
82
|
export type AgentOverrideConfig = z.infer<typeof AgentOverrideConfigSchema>;
|
|
83
|
+
/** Normalized model entry with optional per-model variant. */
|
|
84
|
+
export type ModelEntry = {
|
|
85
|
+
id: string;
|
|
86
|
+
variant?: string;
|
|
87
|
+
};
|
|
80
88
|
export declare const PresetSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
81
|
-
model: z.ZodOptional<z.ZodString
|
|
89
|
+
model: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
90
|
+
id: z.ZodString;
|
|
91
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
92
|
+
}, z.core.$strip>]>>]>>;
|
|
82
93
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
83
94
|
variant: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
84
95
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -155,14 +166,20 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
155
166
|
}, z.core.$strip>;
|
|
156
167
|
}, z.core.$strict>>;
|
|
157
168
|
presets: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
158
|
-
model: z.ZodOptional<z.ZodString
|
|
169
|
+
model: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
170
|
+
id: z.ZodString;
|
|
171
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
172
|
+
}, z.core.$strip>]>>]>>;
|
|
159
173
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
160
174
|
variant: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
161
175
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
162
176
|
mcps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
163
177
|
}, z.core.$strip>>>>;
|
|
164
178
|
agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
165
|
-
model: z.ZodOptional<z.ZodString
|
|
179
|
+
model: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
180
|
+
id: z.ZodString;
|
|
181
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
182
|
+
}, z.core.$strip>]>>]>>;
|
|
166
183
|
temperature: z.ZodOptional<z.ZodNumber>;
|
|
167
184
|
variant: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
168
185
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PluginInput, ProviderContext } from '@opencode-ai/plugin';
|
|
2
|
+
import type { Model, UserMessage } from '@opencode-ai/sdk';
|
|
3
|
+
interface ChatHeadersInput {
|
|
4
|
+
sessionID: string;
|
|
5
|
+
model: Model;
|
|
6
|
+
provider: ProviderContext;
|
|
7
|
+
message: UserMessage;
|
|
8
|
+
}
|
|
9
|
+
interface ChatHeadersOutput {
|
|
10
|
+
headers: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
export declare function __resetInternalMarkerCacheForTesting(): void;
|
|
13
|
+
export declare function createChatHeadersHook(ctx: PluginInput): {
|
|
14
|
+
'chat.headers': (input: ChatHeadersInput, output: ChatHeadersOutput) => Promise<void>;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { DelegateTaskErrorPattern, DetectedError } from './patterns';
|
|
2
|
-
export { DELEGATE_TASK_ERROR_PATTERNS, detectDelegateTaskError } from './patterns';
|
|
3
1
|
export { buildRetryGuidance } from './guidance';
|
|
4
2
|
export { createDelegateTaskRetryHook } from './hook';
|
|
3
|
+
export type { DelegateTaskErrorPattern, DetectedError } from './patterns';
|
|
4
|
+
export { DELEGATE_TASK_ERROR_PATTERNS, detectDelegateTaskError, } from './patterns';
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { AutoUpdateCheckerOptions } from './auto-update-checker';
|
|
2
2
|
export { createAutoUpdateCheckerHook } from './auto-update-checker';
|
|
3
|
+
export { createChatHeadersHook } from './chat-headers';
|
|
3
4
|
export { createDelegateTaskRetryHook } from './delegate-task-retry';
|
|
4
5
|
export { createJsonErrorRecoveryHook } from './json-error-recovery';
|
|
5
6
|
export { createPhaseReminderHook } from './phase-reminder';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const PHASE_REMINDER = "<reminder>Recall Workflow Rules:\nUnderstand \u2192 find the best path (delegate based on rules and parallelize independent work) \u2192 execute \u2192 verify.\nIf delegating, launch the specialist in the same turn you mention it.</reminder>";
|
|
1
2
|
interface MessageInfo {
|
|
2
3
|
role: string;
|
|
3
4
|
agent?: string;
|
package/dist/index.js
CHANGED
|
@@ -3376,7 +3376,7 @@ var SUBAGENT_DELEGATION_RULES = {
|
|
|
3376
3376
|
oracle: []
|
|
3377
3377
|
};
|
|
3378
3378
|
var DEFAULT_MODELS = {
|
|
3379
|
-
orchestrator:
|
|
3379
|
+
orchestrator: undefined,
|
|
3380
3380
|
oracle: "openai/gpt-5.2-codex",
|
|
3381
3381
|
librarian: "openai/gpt-5.1-codex-mini",
|
|
3382
3382
|
explorer: "openai/gpt-5.1-codex-mini",
|
|
@@ -17014,7 +17014,16 @@ var FallbackChainsSchema = exports_external.object({
|
|
|
17014
17014
|
fixer: AgentModelChainSchema.optional()
|
|
17015
17015
|
}).catchall(AgentModelChainSchema);
|
|
17016
17016
|
var AgentOverrideConfigSchema = exports_external.object({
|
|
17017
|
-
model: exports_external.
|
|
17017
|
+
model: exports_external.union([
|
|
17018
|
+
exports_external.string(),
|
|
17019
|
+
exports_external.array(exports_external.union([
|
|
17020
|
+
exports_external.string(),
|
|
17021
|
+
exports_external.object({
|
|
17022
|
+
id: exports_external.string(),
|
|
17023
|
+
variant: exports_external.string().optional()
|
|
17024
|
+
})
|
|
17025
|
+
]))
|
|
17026
|
+
]).optional(),
|
|
17018
17027
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
17019
17028
|
variant: exports_external.string().optional().catch(undefined),
|
|
17020
17029
|
skills: exports_external.array(exports_external.string()).optional(),
|
|
@@ -17138,25 +17147,27 @@ function loadPluginConfig(directory) {
|
|
|
17138
17147
|
}
|
|
17139
17148
|
return config2;
|
|
17140
17149
|
}
|
|
17141
|
-
function loadAgentPrompt(agentName) {
|
|
17150
|
+
function loadAgentPrompt(agentName, preset) {
|
|
17151
|
+
const presetDirName = preset && /^[a-zA-Z0-9_-]+$/.test(preset) ? preset : undefined;
|
|
17142
17152
|
const promptsDir = path.join(getUserConfigDir(), "opencode", PROMPTS_DIR_NAME);
|
|
17153
|
+
const promptSearchDirs = presetDirName ? [path.join(promptsDir, presetDirName), promptsDir] : [promptsDir];
|
|
17143
17154
|
const result = {};
|
|
17144
|
-
const
|
|
17145
|
-
|
|
17146
|
-
|
|
17147
|
-
|
|
17148
|
-
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
|
|
17152
|
-
|
|
17153
|
-
|
|
17154
|
-
|
|
17155
|
-
result.appendPrompt = fs.readFileSync(appendPromptPath, "utf-8");
|
|
17156
|
-
} catch (error48) {
|
|
17157
|
-
console.warn(`[oh-my-opencode-slim] Error reading append prompt file ${appendPromptPath}:`, error48 instanceof Error ? error48.message : String(error48));
|
|
17155
|
+
const readFirstPrompt = (fileName, errorPrefix) => {
|
|
17156
|
+
for (const dir of promptSearchDirs) {
|
|
17157
|
+
const promptPath = path.join(dir, fileName);
|
|
17158
|
+
if (!fs.existsSync(promptPath)) {
|
|
17159
|
+
continue;
|
|
17160
|
+
}
|
|
17161
|
+
try {
|
|
17162
|
+
return fs.readFileSync(promptPath, "utf-8");
|
|
17163
|
+
} catch (error48) {
|
|
17164
|
+
console.warn(`[oh-my-opencode-slim] ${errorPrefix} ${promptPath}:`, error48 instanceof Error ? error48.message : String(error48));
|
|
17165
|
+
}
|
|
17158
17166
|
}
|
|
17159
|
-
|
|
17167
|
+
return;
|
|
17168
|
+
};
|
|
17169
|
+
result.prompt = readFirstPrompt(`${agentName}.md`, "Error reading prompt file");
|
|
17170
|
+
result.appendPrompt = readFirstPrompt(`${agentName}_append.md`, "Error reading append prompt file");
|
|
17160
17171
|
return result;
|
|
17161
17172
|
}
|
|
17162
17173
|
// src/config/utils.ts
|
|
@@ -17580,21 +17591,32 @@ function createOrchestratorAgent(model, customPrompt, customAppendPrompt) {
|
|
|
17580
17591
|
|
|
17581
17592
|
${customAppendPrompt}`;
|
|
17582
17593
|
}
|
|
17583
|
-
|
|
17594
|
+
const definition = {
|
|
17584
17595
|
name: "orchestrator",
|
|
17585
17596
|
description: "AI coding orchestrator that delegates tasks to specialist agents for optimal quality, speed, and cost",
|
|
17586
17597
|
config: {
|
|
17587
|
-
model,
|
|
17588
17598
|
temperature: 0.1,
|
|
17589
17599
|
prompt
|
|
17590
17600
|
}
|
|
17591
17601
|
};
|
|
17602
|
+
if (Array.isArray(model)) {
|
|
17603
|
+
definition._modelArray = model.map((m) => typeof m === "string" ? { id: m } : m);
|
|
17604
|
+
} else if (typeof model === "string" && model) {
|
|
17605
|
+
definition.config.model = model;
|
|
17606
|
+
}
|
|
17607
|
+
return definition;
|
|
17592
17608
|
}
|
|
17593
17609
|
|
|
17594
17610
|
// src/agents/index.ts
|
|
17595
17611
|
function applyOverrides(agent, override) {
|
|
17596
|
-
if (override.model)
|
|
17597
|
-
|
|
17612
|
+
if (override.model) {
|
|
17613
|
+
if (Array.isArray(override.model)) {
|
|
17614
|
+
agent._modelArray = override.model.map((m) => typeof m === "string" ? { id: m } : m);
|
|
17615
|
+
agent.config.model = undefined;
|
|
17616
|
+
} else {
|
|
17617
|
+
agent.config.model = override.model;
|
|
17618
|
+
}
|
|
17619
|
+
}
|
|
17598
17620
|
if (override.variant)
|
|
17599
17621
|
agent.config.variant = override.variant;
|
|
17600
17622
|
if (override.temperature !== undefined)
|
|
@@ -17625,12 +17647,20 @@ var SUBAGENT_FACTORIES = {
|
|
|
17625
17647
|
function createAgents(config2) {
|
|
17626
17648
|
const getModelForAgent = (name) => {
|
|
17627
17649
|
if (name === "fixer" && !getAgentOverride(config2, "fixer")?.model) {
|
|
17628
|
-
|
|
17650
|
+
const librarianOverride = getAgentOverride(config2, "librarian")?.model;
|
|
17651
|
+
let librarianModel;
|
|
17652
|
+
if (Array.isArray(librarianOverride)) {
|
|
17653
|
+
const first = librarianOverride[0];
|
|
17654
|
+
librarianModel = typeof first === "string" ? first : first?.id;
|
|
17655
|
+
} else {
|
|
17656
|
+
librarianModel = librarianOverride;
|
|
17657
|
+
}
|
|
17658
|
+
return librarianModel ?? DEFAULT_MODELS.librarian;
|
|
17629
17659
|
}
|
|
17630
17660
|
return DEFAULT_MODELS[name];
|
|
17631
17661
|
};
|
|
17632
17662
|
const protoSubAgents = Object.entries(SUBAGENT_FACTORIES).map(([name, factory]) => {
|
|
17633
|
-
const customPrompts = loadAgentPrompt(name);
|
|
17663
|
+
const customPrompts = loadAgentPrompt(name, config2?.preset);
|
|
17634
17664
|
return factory(getModelForAgent(name), customPrompts.prompt, customPrompts.appendPrompt);
|
|
17635
17665
|
});
|
|
17636
17666
|
const allSubAgents = protoSubAgents.map((agent) => {
|
|
@@ -17641,13 +17671,13 @@ function createAgents(config2) {
|
|
|
17641
17671
|
applyDefaultPermissions(agent, override?.skills);
|
|
17642
17672
|
return agent;
|
|
17643
17673
|
});
|
|
17644
|
-
const
|
|
17645
|
-
const
|
|
17674
|
+
const orchestratorOverride = getAgentOverride(config2, "orchestrator");
|
|
17675
|
+
const orchestratorModel = orchestratorOverride?.model ?? DEFAULT_MODELS.orchestrator;
|
|
17676
|
+
const orchestratorPrompts = loadAgentPrompt("orchestrator", config2?.preset);
|
|
17646
17677
|
const orchestrator = createOrchestratorAgent(orchestratorModel, orchestratorPrompts.prompt, orchestratorPrompts.appendPrompt);
|
|
17647
|
-
|
|
17648
|
-
|
|
17649
|
-
|
|
17650
|
-
applyOverrides(orchestrator, oOverride);
|
|
17678
|
+
applyDefaultPermissions(orchestrator, orchestratorOverride?.skills);
|
|
17679
|
+
if (orchestratorOverride) {
|
|
17680
|
+
applyOverrides(orchestrator, orchestratorOverride);
|
|
17651
17681
|
}
|
|
17652
17682
|
return [orchestrator, ...allSubAgents];
|
|
17653
17683
|
}
|
|
@@ -17709,6 +17739,27 @@ function applyAgentVariant(variant, body) {
|
|
|
17709
17739
|
}
|
|
17710
17740
|
return { ...body, variant };
|
|
17711
17741
|
}
|
|
17742
|
+
// src/utils/internal-initiator.ts
|
|
17743
|
+
var SLIM_INTERNAL_INITIATOR_MARKER = "<!-- SLIM_INTERNAL_INITIATOR -->";
|
|
17744
|
+
function isRecord(value) {
|
|
17745
|
+
return typeof value === "object" && value !== null;
|
|
17746
|
+
}
|
|
17747
|
+
function createInternalAgentTextPart(text) {
|
|
17748
|
+
return {
|
|
17749
|
+
type: "text",
|
|
17750
|
+
text: `${text}
|
|
17751
|
+
${SLIM_INTERNAL_INITIATOR_MARKER}`
|
|
17752
|
+
};
|
|
17753
|
+
}
|
|
17754
|
+
function hasInternalInitiatorMarker(part) {
|
|
17755
|
+
if (!isRecord(part) || part.type !== "text") {
|
|
17756
|
+
return false;
|
|
17757
|
+
}
|
|
17758
|
+
if (typeof part.text !== "string") {
|
|
17759
|
+
return false;
|
|
17760
|
+
}
|
|
17761
|
+
return part.text.includes(SLIM_INTERNAL_INITIATOR_MARKER);
|
|
17762
|
+
}
|
|
17712
17763
|
// src/utils/tmux.ts
|
|
17713
17764
|
var {spawn } = globalThis.Bun;
|
|
17714
17765
|
var tmuxPath = null;
|
|
@@ -18119,7 +18170,15 @@ class BackgroundTaskManager {
|
|
|
18119
18170
|
const primary = this.config?.agents?.[agentName]?.model;
|
|
18120
18171
|
const chain = [];
|
|
18121
18172
|
const seen = new Set;
|
|
18122
|
-
|
|
18173
|
+
let primaryIds;
|
|
18174
|
+
if (Array.isArray(primary)) {
|
|
18175
|
+
primaryIds = primary.map((m) => typeof m === "string" ? m : m.id);
|
|
18176
|
+
} else if (typeof primary === "string") {
|
|
18177
|
+
primaryIds = [primary];
|
|
18178
|
+
} else {
|
|
18179
|
+
primaryIds = [];
|
|
18180
|
+
}
|
|
18181
|
+
for (const model of [...primaryIds, ...configuredChain]) {
|
|
18123
18182
|
if (!model || seen.has(model))
|
|
18124
18183
|
continue;
|
|
18125
18184
|
seen.add(model);
|
|
@@ -18341,7 +18400,7 @@ class BackgroundTaskManager {
|
|
|
18341
18400
|
await this.client.session.prompt({
|
|
18342
18401
|
path: { id: task.parentSessionId },
|
|
18343
18402
|
body: {
|
|
18344
|
-
parts: [
|
|
18403
|
+
parts: [createInternalAgentTextPart(message)]
|
|
18345
18404
|
}
|
|
18346
18405
|
});
|
|
18347
18406
|
}
|
|
@@ -18971,6 +19030,56 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
|
|
|
18971
19030
|
body: { title, message, variant, duration: duration3 }
|
|
18972
19031
|
}).catch(() => {});
|
|
18973
19032
|
}
|
|
19033
|
+
// src/hooks/chat-headers.ts
|
|
19034
|
+
var INTERNAL_MARKER_CACHE_LIMIT = 1000;
|
|
19035
|
+
var internalMarkerCache = new Map;
|
|
19036
|
+
function getProviderID(input) {
|
|
19037
|
+
return input.provider.info?.id || input.model.providerID;
|
|
19038
|
+
}
|
|
19039
|
+
function isCopilotProvider(providerID) {
|
|
19040
|
+
return providerID === "github-copilot" || providerID === "github-copilot-enterprise";
|
|
19041
|
+
}
|
|
19042
|
+
async function hasInternalMarker(client, sessionID, messageID) {
|
|
19043
|
+
const cacheKey = `${sessionID}:${messageID}`;
|
|
19044
|
+
const cached2 = internalMarkerCache.get(cacheKey);
|
|
19045
|
+
if (cached2 !== undefined) {
|
|
19046
|
+
return cached2;
|
|
19047
|
+
}
|
|
19048
|
+
try {
|
|
19049
|
+
const response = await client.session.message({
|
|
19050
|
+
path: { id: sessionID, messageID }
|
|
19051
|
+
});
|
|
19052
|
+
const hasMarker = (response.data?.parts ?? []).some(hasInternalInitiatorMarker);
|
|
19053
|
+
if (hasMarker) {
|
|
19054
|
+
if (internalMarkerCache.size >= INTERNAL_MARKER_CACHE_LIMIT) {
|
|
19055
|
+
internalMarkerCache.clear();
|
|
19056
|
+
}
|
|
19057
|
+
internalMarkerCache.set(cacheKey, true);
|
|
19058
|
+
}
|
|
19059
|
+
return hasMarker;
|
|
19060
|
+
} catch {
|
|
19061
|
+
return false;
|
|
19062
|
+
}
|
|
19063
|
+
}
|
|
19064
|
+
function createChatHeadersHook(ctx) {
|
|
19065
|
+
return {
|
|
19066
|
+
"chat.headers": async (input, output) => {
|
|
19067
|
+
if (!isCopilotProvider(getProviderID(input))) {
|
|
19068
|
+
return;
|
|
19069
|
+
}
|
|
19070
|
+
if (input.model.api.npm === "@ai-sdk/github-copilot") {
|
|
19071
|
+
return;
|
|
19072
|
+
}
|
|
19073
|
+
if (!input.message.id || input.message.role !== "user") {
|
|
19074
|
+
return;
|
|
19075
|
+
}
|
|
19076
|
+
if (!await hasInternalMarker(ctx.client, input.sessionID, input.message.id)) {
|
|
19077
|
+
return;
|
|
19078
|
+
}
|
|
19079
|
+
output.headers["x-initiator"] = "agent";
|
|
19080
|
+
}
|
|
19081
|
+
};
|
|
19082
|
+
}
|
|
18974
19083
|
// src/hooks/delegate-task-retry/patterns.ts
|
|
18975
19084
|
var DELEGATE_TASK_ERROR_PATTERNS = [
|
|
18976
19085
|
{
|
|
@@ -19030,6 +19139,7 @@ function detectDelegateTaskError(output) {
|
|
|
19030
19139
|
}
|
|
19031
19140
|
return null;
|
|
19032
19141
|
}
|
|
19142
|
+
|
|
19033
19143
|
// src/hooks/delegate-task-retry/guidance.ts
|
|
19034
19144
|
function extractAvailableList(output) {
|
|
19035
19145
|
const match = output.match(/Allowed agents:\s*(.+)$/m);
|
|
@@ -19161,6 +19271,9 @@ function createPhaseReminderHook() {
|
|
|
19161
19271
|
return;
|
|
19162
19272
|
}
|
|
19163
19273
|
const originalText = lastUserMessage.parts[textPartIndex].text ?? "";
|
|
19274
|
+
if (originalText.includes(SLIM_INTERNAL_INITIATOR_MARKER)) {
|
|
19275
|
+
return;
|
|
19276
|
+
}
|
|
19164
19277
|
lastUserMessage.parts[textPartIndex].text = `${PHASE_REMINDER}
|
|
19165
19278
|
|
|
19166
19279
|
---
|
|
@@ -33415,7 +33528,14 @@ var lsp_rename = tool({
|
|
|
33415
33528
|
// src/index.ts
|
|
33416
33529
|
var OhMyOpenCodeLite = async (ctx) => {
|
|
33417
33530
|
const config3 = loadPluginConfig(ctx.directory);
|
|
33531
|
+
const agentDefs = createAgents(config3);
|
|
33418
33532
|
const agents = getAgentConfigs(config3);
|
|
33533
|
+
const modelArrayMap = {};
|
|
33534
|
+
for (const agentDef of agentDefs) {
|
|
33535
|
+
if (agentDef._modelArray && agentDef._modelArray.length > 0) {
|
|
33536
|
+
modelArrayMap[agentDef.name] = agentDef._modelArray;
|
|
33537
|
+
}
|
|
33538
|
+
}
|
|
33419
33539
|
const tmuxConfig = {
|
|
33420
33540
|
enabled: config3.tmux?.enabled ?? false,
|
|
33421
33541
|
layout: config3.tmux?.layout ?? "main-vertical",
|
|
@@ -33439,6 +33559,7 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33439
33559
|
});
|
|
33440
33560
|
const phaseReminderHook = createPhaseReminderHook();
|
|
33441
33561
|
const postReadNudgeHook = createPostReadNudgeHook();
|
|
33562
|
+
const chatHeadersHook = createChatHeadersHook(ctx);
|
|
33442
33563
|
const delegateTaskRetryHook = createDelegateTaskRetryHook(ctx);
|
|
33443
33564
|
const jsonErrorRecoveryHook = createJsonErrorRecoveryHook(ctx);
|
|
33444
33565
|
return {
|
|
@@ -33463,6 +33584,40 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33463
33584
|
Object.assign(opencodeConfig.agent, agents);
|
|
33464
33585
|
}
|
|
33465
33586
|
const configAgent = opencodeConfig.agent;
|
|
33587
|
+
if (Object.keys(modelArrayMap).length > 0) {
|
|
33588
|
+
const providerConfig = opencodeConfig.provider ?? {};
|
|
33589
|
+
const configuredProviders = Object.keys(providerConfig);
|
|
33590
|
+
for (const [agentName, modelArray] of Object.entries(modelArrayMap)) {
|
|
33591
|
+
let resolved = false;
|
|
33592
|
+
for (const modelEntry of modelArray) {
|
|
33593
|
+
const slashIdx = modelEntry.id.indexOf("/");
|
|
33594
|
+
if (slashIdx === -1)
|
|
33595
|
+
continue;
|
|
33596
|
+
const providerID = modelEntry.id.slice(0, slashIdx);
|
|
33597
|
+
if (configuredProviders.includes(providerID)) {
|
|
33598
|
+
const entry = configAgent[agentName];
|
|
33599
|
+
if (entry) {
|
|
33600
|
+
entry.model = modelEntry.id;
|
|
33601
|
+
if (modelEntry.variant) {
|
|
33602
|
+
entry.variant = modelEntry.variant;
|
|
33603
|
+
}
|
|
33604
|
+
}
|
|
33605
|
+
log("[plugin] resolved model fallback", {
|
|
33606
|
+
agent: agentName,
|
|
33607
|
+
model: modelEntry.id,
|
|
33608
|
+
variant: modelEntry.variant
|
|
33609
|
+
});
|
|
33610
|
+
resolved = true;
|
|
33611
|
+
break;
|
|
33612
|
+
}
|
|
33613
|
+
}
|
|
33614
|
+
if (!resolved) {
|
|
33615
|
+
log("[plugin] no provider match for model array", {
|
|
33616
|
+
agent: agentName
|
|
33617
|
+
});
|
|
33618
|
+
}
|
|
33619
|
+
}
|
|
33620
|
+
}
|
|
33466
33621
|
const configMcp = opencodeConfig.mcp;
|
|
33467
33622
|
if (!configMcp) {
|
|
33468
33623
|
opencodeConfig.mcp = { ...mcps };
|
|
@@ -33499,6 +33654,7 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33499
33654
|
await backgroundManager.handleSessionDeleted(input.event);
|
|
33500
33655
|
await tmuxSessionManager.onSessionDeleted(input.event);
|
|
33501
33656
|
},
|
|
33657
|
+
"chat.headers": chatHeadersHook["chat.headers"],
|
|
33502
33658
|
"experimental.chat.messages.transform": phaseReminderHook["experimental.chat.messages.transform"],
|
|
33503
33659
|
"tool.execute.after": async (input, output) => {
|
|
33504
33660
|
await delegateTaskRetryHook["tool.execute.after"](input, output);
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const SLIM_INTERNAL_INITIATOR_MARKER = "<!-- SLIM_INTERNAL_INITIATOR -->";
|
|
2
|
+
export declare function createInternalAgentTextPart(text: string): {
|
|
3
|
+
type: 'text';
|
|
4
|
+
text: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function hasInternalInitiatorMarker(part: unknown): boolean;
|
package/package.json
CHANGED