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 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/project/0f5874c7-9291-415b-9622-7509d96a2c73"><img src="https://moltfounders.com/badges/4.png" alt="MoltFounders" height="30"></a></p>
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/project/0f5874c7-9291-415b-9622-7509d96a2c73">
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: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
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.string().optional(),
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;
@@ -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
  };
@@ -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';
@@ -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: "kimi-for-coding/k2p5",
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.string().optional(),
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 promptPath = path.join(promptsDir, `${agentName}.md`);
17145
- if (fs.existsSync(promptPath)) {
17146
- try {
17147
- result.prompt = fs.readFileSync(promptPath, "utf-8");
17148
- } catch (error48) {
17149
- console.warn(`[oh-my-opencode-slim] Error reading prompt file ${promptPath}:`, error48 instanceof Error ? error48.message : String(error48));
17150
- }
17151
- }
17152
- const appendPromptPath = path.join(promptsDir, `${agentName}_append.md`);
17153
- if (fs.existsSync(appendPromptPath)) {
17154
- try {
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
- return {
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
- agent.config.model = override.model;
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
- return getAgentOverride(config2, "librarian")?.model ?? DEFAULT_MODELS.librarian;
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 orchestratorModel = getAgentOverride(config2, "orchestrator")?.model ?? DEFAULT_MODELS.orchestrator;
17645
- const orchestratorPrompts = loadAgentPrompt("orchestrator");
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
- const oOverride = getAgentOverride(config2, "orchestrator");
17648
- applyDefaultPermissions(orchestrator, oOverride?.skills);
17649
- if (oOverride) {
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
- for (const model of [primary, ...configuredChain]) {
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: [{ type: "text", text: message }]
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);
@@ -1,5 +1,6 @@
1
1
  export * from './agent-variant';
2
2
  export * from './env';
3
+ export * from './internal-initiator';
3
4
  export { log } from './logger';
4
5
  export * from './polling';
5
6
  export * from './tmux';
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-slim",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "Lightweight agent orchestration plugin for OpenCode - a slimmed-down fork of oh-my-opencode",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",