oh-my-opencode-slim 0.8.0 → 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 +90 -79
- package/dist/cli/providers.d.ts +1 -1
- package/dist/cli/skills.d.ts +17 -0
- 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/autopilot/index.d.ts +43 -0
- package/dist/hooks/chat-headers.d.ts +16 -0
- package/dist/hooks/delegate-task-retry/guidance.d.ts +2 -0
- package/dist/hooks/delegate-task-retry/hook.d.ts +8 -0
- package/dist/hooks/delegate-task-retry/index.d.ts +4 -0
- package/dist/hooks/delegate-task-retry/patterns.d.ts +11 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/json-error-recovery/hook.d.ts +18 -0
- package/dist/hooks/json-error-recovery/index.d.ts +1 -0
- package/dist/hooks/phase-reminder/index.d.ts +1 -0
- package/dist/index.js +402 -43
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/internal-initiator.d.ts +6 -0
- package/package.json +1 -1
- package/dist/tools/quota/api.d.ts +0 -5
- package/dist/tools/quota/command.d.ts +0 -1
- package/dist/tools/quota/index.d.ts +0 -21
- package/dist/tools/quota/types.d.ts +0 -41
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
|
@@ -80,11 +80,11 @@ function pickSupportChutesModel(models, primaryModel) {
|
|
|
80
80
|
}
|
|
81
81
|
// src/cli/config-io.ts
|
|
82
82
|
import {
|
|
83
|
-
copyFileSync,
|
|
84
|
-
existsSync as
|
|
83
|
+
copyFileSync as copyFileSync2,
|
|
84
|
+
existsSync as existsSync3,
|
|
85
85
|
readFileSync,
|
|
86
86
|
renameSync,
|
|
87
|
-
statSync,
|
|
87
|
+
statSync as statSync2,
|
|
88
88
|
writeFileSync
|
|
89
89
|
} from "fs";
|
|
90
90
|
|
|
@@ -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(),
|
|
@@ -13729,7 +13738,7 @@ var BackgroundTaskConfigSchema = exports_external.object({
|
|
|
13729
13738
|
});
|
|
13730
13739
|
var FailoverConfigSchema = exports_external.object({
|
|
13731
13740
|
enabled: exports_external.boolean().default(true),
|
|
13732
|
-
timeoutMs: exports_external.number().min(
|
|
13741
|
+
timeoutMs: exports_external.number().min(0).default(15000),
|
|
13733
13742
|
chains: FallbackChainsSchema.default({})
|
|
13734
13743
|
});
|
|
13735
13744
|
var PluginConfigSchema = exports_external.object({
|
|
@@ -13756,6 +13765,67 @@ var DEFAULT_AGENT_MCPS = {
|
|
|
13756
13765
|
|
|
13757
13766
|
// src/cli/skills.ts
|
|
13758
13767
|
import { spawnSync } from "child_process";
|
|
13768
|
+
|
|
13769
|
+
// src/cli/custom-skills.ts
|
|
13770
|
+
import {
|
|
13771
|
+
copyFileSync,
|
|
13772
|
+
existsSync as existsSync2,
|
|
13773
|
+
mkdirSync as mkdirSync2,
|
|
13774
|
+
readdirSync,
|
|
13775
|
+
statSync
|
|
13776
|
+
} from "fs";
|
|
13777
|
+
import { homedir as homedir2 } from "os";
|
|
13778
|
+
import { dirname, join as join2 } from "path";
|
|
13779
|
+
import { fileURLToPath } from "url";
|
|
13780
|
+
var CUSTOM_SKILLS = [
|
|
13781
|
+
{
|
|
13782
|
+
name: "cartography",
|
|
13783
|
+
description: "Repository understanding and hierarchical codemap generation",
|
|
13784
|
+
allowedAgents: ["orchestrator", "explorer"],
|
|
13785
|
+
sourcePath: "src/skills/cartography"
|
|
13786
|
+
}
|
|
13787
|
+
];
|
|
13788
|
+
function getCustomSkillsDir() {
|
|
13789
|
+
return join2(homedir2(), ".config", "opencode", "skills");
|
|
13790
|
+
}
|
|
13791
|
+
function copyDirRecursive(src, dest) {
|
|
13792
|
+
if (!existsSync2(dest)) {
|
|
13793
|
+
mkdirSync2(dest, { recursive: true });
|
|
13794
|
+
}
|
|
13795
|
+
const entries = readdirSync(src);
|
|
13796
|
+
for (const entry of entries) {
|
|
13797
|
+
const srcPath = join2(src, entry);
|
|
13798
|
+
const destPath = join2(dest, entry);
|
|
13799
|
+
const stat = statSync(srcPath);
|
|
13800
|
+
if (stat.isDirectory()) {
|
|
13801
|
+
copyDirRecursive(srcPath, destPath);
|
|
13802
|
+
} else {
|
|
13803
|
+
const destDir = dirname(destPath);
|
|
13804
|
+
if (!existsSync2(destDir)) {
|
|
13805
|
+
mkdirSync2(destDir, { recursive: true });
|
|
13806
|
+
}
|
|
13807
|
+
copyFileSync(srcPath, destPath);
|
|
13808
|
+
}
|
|
13809
|
+
}
|
|
13810
|
+
}
|
|
13811
|
+
function installCustomSkill(skill) {
|
|
13812
|
+
try {
|
|
13813
|
+
const packageRoot = fileURLToPath(new URL("../..", import.meta.url));
|
|
13814
|
+
const sourcePath = join2(packageRoot, skill.sourcePath);
|
|
13815
|
+
const targetPath = join2(getCustomSkillsDir(), skill.name);
|
|
13816
|
+
if (!existsSync2(sourcePath)) {
|
|
13817
|
+
console.error(`Custom skill source not found: ${sourcePath}`);
|
|
13818
|
+
return false;
|
|
13819
|
+
}
|
|
13820
|
+
copyDirRecursive(sourcePath, targetPath);
|
|
13821
|
+
return true;
|
|
13822
|
+
} catch (error48) {
|
|
13823
|
+
console.error(`Failed to install custom skill: ${skill.name}`, error48);
|
|
13824
|
+
return false;
|
|
13825
|
+
}
|
|
13826
|
+
}
|
|
13827
|
+
|
|
13828
|
+
// src/cli/skills.ts
|
|
13759
13829
|
var RECOMMENDED_SKILLS = [
|
|
13760
13830
|
{
|
|
13761
13831
|
name: "simplify",
|
|
@@ -13863,7 +13933,7 @@ var MODEL_MAPPINGS = {
|
|
|
13863
13933
|
},
|
|
13864
13934
|
antigravity: {
|
|
13865
13935
|
orchestrator: { model: "google/antigravity-gemini-3-flash" },
|
|
13866
|
-
oracle: { model: "google/antigravity-gemini-3-pro" },
|
|
13936
|
+
oracle: { model: "google/antigravity-gemini-3.1-pro" },
|
|
13867
13937
|
librarian: {
|
|
13868
13938
|
model: "google/antigravity-gemini-3-flash",
|
|
13869
13939
|
variant: "low"
|
|
@@ -14203,9 +14273,9 @@ function stripJsonComments(json2) {
|
|
|
14203
14273
|
}
|
|
14204
14274
|
function parseConfigFile(path) {
|
|
14205
14275
|
try {
|
|
14206
|
-
if (!
|
|
14276
|
+
if (!existsSync3(path))
|
|
14207
14277
|
return { config: null };
|
|
14208
|
-
const stat =
|
|
14278
|
+
const stat = statSync2(path);
|
|
14209
14279
|
if (stat.size === 0)
|
|
14210
14280
|
return { config: null };
|
|
14211
14281
|
const content = readFileSync(path, "utf-8");
|
|
@@ -14234,8 +14304,8 @@ function writeConfig(configPath, config2) {
|
|
|
14234
14304
|
const bakPath = `${configPath}.bak`;
|
|
14235
14305
|
const content = `${JSON.stringify(config2, null, 2)}
|
|
14236
14306
|
`;
|
|
14237
|
-
if (
|
|
14238
|
-
|
|
14307
|
+
if (existsSync3(configPath)) {
|
|
14308
|
+
copyFileSync2(configPath, bakPath);
|
|
14239
14309
|
}
|
|
14240
14310
|
writeFileSync(tmpPath, content);
|
|
14241
14311
|
renameSync(tmpPath, configPath);
|
|
@@ -14284,8 +14354,8 @@ function writeLiteConfig(installConfig) {
|
|
|
14284
14354
|
const bakPath = `${configPath}.bak`;
|
|
14285
14355
|
const content = `${JSON.stringify(config2, null, 2)}
|
|
14286
14356
|
`;
|
|
14287
|
-
if (
|
|
14288
|
-
|
|
14357
|
+
if (existsSync3(configPath)) {
|
|
14358
|
+
copyFileSync2(configPath, bakPath);
|
|
14289
14359
|
}
|
|
14290
14360
|
writeFileSync(tmpPath, content);
|
|
14291
14361
|
renameSync(tmpPath, configPath);
|
|
@@ -14368,8 +14438,8 @@ function addGoogleProvider() {
|
|
|
14368
14438
|
const providers = config2.provider ?? {};
|
|
14369
14439
|
providers.google = {
|
|
14370
14440
|
models: {
|
|
14371
|
-
"antigravity-gemini-3-pro": {
|
|
14372
|
-
name: "Gemini 3 Pro (Antigravity)",
|
|
14441
|
+
"antigravity-gemini-3.1-pro": {
|
|
14442
|
+
name: "Gemini 3.1 Pro (Antigravity)",
|
|
14373
14443
|
limit: { context: 1048576, output: 65535 },
|
|
14374
14444
|
modalities: { input: ["text", "image", "pdf"], output: ["text"] },
|
|
14375
14445
|
variants: {
|
|
@@ -14426,8 +14496,8 @@ function addGoogleProvider() {
|
|
|
14426
14496
|
limit: { context: 1048576, output: 65536 },
|
|
14427
14497
|
modalities: { input: ["text", "image", "pdf"], output: ["text"] }
|
|
14428
14498
|
},
|
|
14429
|
-
"gemini-3-pro-preview": {
|
|
14430
|
-
name: "Gemini 3 Pro Preview (Gemini CLI)",
|
|
14499
|
+
"gemini-3.1-pro-preview": {
|
|
14500
|
+
name: "Gemini 3.1 Pro Preview (Gemini CLI)",
|
|
14431
14501
|
limit: { context: 1048576, output: 65535 },
|
|
14432
14502
|
modalities: { input: ["text", "image", "pdf"], output: ["text"] }
|
|
14433
14503
|
}
|
|
@@ -15751,7 +15821,7 @@ async function fetchExternalModelSignals(options) {
|
|
|
15751
15821
|
return { signals: aggregate, warnings };
|
|
15752
15822
|
}
|
|
15753
15823
|
// src/cli/system.ts
|
|
15754
|
-
import { statSync as
|
|
15824
|
+
import { statSync as statSync3 } from "fs";
|
|
15755
15825
|
var cachedOpenCodePath = null;
|
|
15756
15826
|
function getOpenCodePaths() {
|
|
15757
15827
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
@@ -15793,7 +15863,7 @@ function resolveOpenCodePath() {
|
|
|
15793
15863
|
if (opencodePath === "opencode")
|
|
15794
15864
|
continue;
|
|
15795
15865
|
try {
|
|
15796
|
-
const stat =
|
|
15866
|
+
const stat = statSync3(opencodePath);
|
|
15797
15867
|
if (stat.isFile()) {
|
|
15798
15868
|
cachedOpenCodePath = opencodePath;
|
|
15799
15869
|
return opencodePath;
|
|
@@ -16023,65 +16093,6 @@ function pickSupportOpenCodeModel(models, primaryModel) {
|
|
|
16023
16093
|
}, primaryModel);
|
|
16024
16094
|
return support;
|
|
16025
16095
|
}
|
|
16026
|
-
// src/cli/custom-skills.ts
|
|
16027
|
-
import {
|
|
16028
|
-
copyFileSync as copyFileSync2,
|
|
16029
|
-
existsSync as existsSync3,
|
|
16030
|
-
mkdirSync as mkdirSync2,
|
|
16031
|
-
readdirSync,
|
|
16032
|
-
statSync as statSync3
|
|
16033
|
-
} from "fs";
|
|
16034
|
-
import { homedir as homedir2 } from "os";
|
|
16035
|
-
import { dirname, join as join3 } from "path";
|
|
16036
|
-
import { fileURLToPath } from "url";
|
|
16037
|
-
var CUSTOM_SKILLS = [
|
|
16038
|
-
{
|
|
16039
|
-
name: "cartography",
|
|
16040
|
-
description: "Repository understanding and hierarchical codemap generation",
|
|
16041
|
-
allowedAgents: ["orchestrator"],
|
|
16042
|
-
sourcePath: "src/skills/cartography"
|
|
16043
|
-
}
|
|
16044
|
-
];
|
|
16045
|
-
function getCustomSkillsDir() {
|
|
16046
|
-
return join3(homedir2(), ".config", "opencode", "skills");
|
|
16047
|
-
}
|
|
16048
|
-
function copyDirRecursive(src, dest) {
|
|
16049
|
-
if (!existsSync3(dest)) {
|
|
16050
|
-
mkdirSync2(dest, { recursive: true });
|
|
16051
|
-
}
|
|
16052
|
-
const entries = readdirSync(src);
|
|
16053
|
-
for (const entry of entries) {
|
|
16054
|
-
const srcPath = join3(src, entry);
|
|
16055
|
-
const destPath = join3(dest, entry);
|
|
16056
|
-
const stat = statSync3(srcPath);
|
|
16057
|
-
if (stat.isDirectory()) {
|
|
16058
|
-
copyDirRecursive(srcPath, destPath);
|
|
16059
|
-
} else {
|
|
16060
|
-
const destDir = dirname(destPath);
|
|
16061
|
-
if (!existsSync3(destDir)) {
|
|
16062
|
-
mkdirSync2(destDir, { recursive: true });
|
|
16063
|
-
}
|
|
16064
|
-
copyFileSync2(srcPath, destPath);
|
|
16065
|
-
}
|
|
16066
|
-
}
|
|
16067
|
-
}
|
|
16068
|
-
function installCustomSkill(skill) {
|
|
16069
|
-
try {
|
|
16070
|
-
const packageRoot = fileURLToPath(new URL("../..", import.meta.url));
|
|
16071
|
-
const sourcePath = join3(packageRoot, skill.sourcePath);
|
|
16072
|
-
const targetPath = join3(getCustomSkillsDir(), skill.name);
|
|
16073
|
-
if (!existsSync3(sourcePath)) {
|
|
16074
|
-
console.error(`Custom skill source not found: ${sourcePath}`);
|
|
16075
|
-
return false;
|
|
16076
|
-
}
|
|
16077
|
-
copyDirRecursive(sourcePath, targetPath);
|
|
16078
|
-
return true;
|
|
16079
|
-
} catch (error48) {
|
|
16080
|
-
console.error(`Failed to install custom skill: ${skill.name}`, error48);
|
|
16081
|
-
return false;
|
|
16082
|
-
}
|
|
16083
|
-
}
|
|
16084
|
-
|
|
16085
16096
|
// src/cli/install.ts
|
|
16086
16097
|
var GREEN = "\x1B[32m";
|
|
16087
16098
|
var BLUE = "\x1B[34m";
|
|
@@ -16430,8 +16441,8 @@ async function runManualSetupMode(rl, detected, modelsOnly = false) {
|
|
|
16430
16441
|
}
|
|
16431
16442
|
if (antigravity === "yes") {
|
|
16432
16443
|
availableModels.push({
|
|
16433
|
-
model: "google/antigravity-gemini-3-pro",
|
|
16434
|
-
name: "Gemini 3 Pro"
|
|
16444
|
+
model: "google/antigravity-gemini-3.1-pro",
|
|
16445
|
+
name: "Gemini 3.1 Pro"
|
|
16435
16446
|
});
|
|
16436
16447
|
availableModels.push({
|
|
16437
16448
|
model: "google/antigravity-gemini-3-flash",
|
package/dist/cli/providers.d.ts
CHANGED
|
@@ -130,7 +130,7 @@ export declare const MODEL_MAPPINGS: {
|
|
|
130
130
|
readonly model: "google/antigravity-gemini-3-flash";
|
|
131
131
|
};
|
|
132
132
|
readonly oracle: {
|
|
133
|
-
readonly model: "google/antigravity-gemini-3-pro";
|
|
133
|
+
readonly model: "google/antigravity-gemini-3.1-pro";
|
|
134
134
|
};
|
|
135
135
|
readonly librarian: {
|
|
136
136
|
readonly model: "google/antigravity-gemini-3-flash";
|
package/dist/cli/skills.d.ts
CHANGED
|
@@ -15,11 +15,28 @@ export interface RecommendedSkill {
|
|
|
15
15
|
/** Optional commands to run after the skill is added */
|
|
16
16
|
postInstallCommands?: string[];
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* A skill that is managed externally (e.g. user-installed) and needs
|
|
20
|
+
* permission grants but is NOT installed by this plugin's CLI.
|
|
21
|
+
*/
|
|
22
|
+
export interface PermissionOnlySkill {
|
|
23
|
+
/** Skill name — must match the name OpenCode uses for permission checks */
|
|
24
|
+
name: string;
|
|
25
|
+
/** List of agents that should auto-allow this skill */
|
|
26
|
+
allowedAgents: string[];
|
|
27
|
+
/** Human-readable description (for documentation only) */
|
|
28
|
+
description: string;
|
|
29
|
+
}
|
|
18
30
|
/**
|
|
19
31
|
* List of recommended skills.
|
|
20
32
|
* Add new skills here to include them in the installation flow.
|
|
21
33
|
*/
|
|
22
34
|
export declare const RECOMMENDED_SKILLS: RecommendedSkill[];
|
|
35
|
+
/**
|
|
36
|
+
* Skills managed externally (not installed by this plugin's CLI).
|
|
37
|
+
* Entries here only affect agent permission grants — nothing is installed.
|
|
38
|
+
*/
|
|
39
|
+
export declare const PERMISSION_ONLY_SKILLS: PermissionOnlySkill[];
|
|
23
40
|
/**
|
|
24
41
|
* Install a skill using `npx skills add`.
|
|
25
42
|
* @param skill - The skill to install
|
|
@@ -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,43 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
import type { PluginConfig } from '../../config';
|
|
3
|
+
declare const AUTOPILOT_CONTINUE_PROMPT = "[AUTOPILOT] Continue executing work in this same session now. Do not acknowledge autopilot, do not ask for confirmation, and do not stop after a status message. Perform the next concrete action immediately (run a tool/command, edit files, or advance the active todo). Only stop when all todos are completed/cancelled or the user explicitly disables autopilot.";
|
|
4
|
+
interface MessagePart {
|
|
5
|
+
type: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
}
|
|
8
|
+
interface TodoEntry {
|
|
9
|
+
status?: string;
|
|
10
|
+
}
|
|
11
|
+
type AutopilotCommand = 'enable' | 'disable' | 'status' | null;
|
|
12
|
+
declare function parseAutopilotCommand(text: string, keyword: string, disableKeyword: string): AutopilotCommand;
|
|
13
|
+
declare function extractTodoList(data: unknown): TodoEntry[];
|
|
14
|
+
declare function isActiveTodo(todo: TodoEntry): boolean;
|
|
15
|
+
export declare function createAutopilotHook(ctx: PluginInput, config: PluginConfig): {
|
|
16
|
+
'chat.message': (input: {
|
|
17
|
+
sessionID: string;
|
|
18
|
+
agent?: string;
|
|
19
|
+
messageID?: string;
|
|
20
|
+
}, output: {
|
|
21
|
+
parts: MessagePart[];
|
|
22
|
+
}) => Promise<void>;
|
|
23
|
+
event: (input: {
|
|
24
|
+
event: {
|
|
25
|
+
type: string;
|
|
26
|
+
properties?: {
|
|
27
|
+
sessionID?: string;
|
|
28
|
+
status?: {
|
|
29
|
+
type?: string;
|
|
30
|
+
};
|
|
31
|
+
info?: {
|
|
32
|
+
id?: string;
|
|
33
|
+
role?: string;
|
|
34
|
+
sessionID?: string;
|
|
35
|
+
time?: {
|
|
36
|
+
completed?: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}) => Promise<void>;
|
|
42
|
+
};
|
|
43
|
+
export { AUTOPILOT_CONTINUE_PROMPT, extractTodoList, isActiveTodo, parseAutopilotCommand, };
|
|
@@ -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 {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DelegateTaskErrorPattern {
|
|
2
|
+
pattern: string;
|
|
3
|
+
errorType: string;
|
|
4
|
+
fixHint: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const DELEGATE_TASK_ERROR_PATTERNS: DelegateTaskErrorPattern[];
|
|
7
|
+
export interface DetectedError {
|
|
8
|
+
errorType: string;
|
|
9
|
+
originalOutput: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function detectDelegateTaskError(output: string): DetectedError | null;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export type { AutoUpdateCheckerOptions } from './auto-update-checker';
|
|
2
2
|
export { createAutoUpdateCheckerHook } from './auto-update-checker';
|
|
3
|
+
export { createChatHeadersHook } from './chat-headers';
|
|
4
|
+
export { createDelegateTaskRetryHook } from './delegate-task-retry';
|
|
5
|
+
export { createJsonErrorRecoveryHook } from './json-error-recovery';
|
|
3
6
|
export { createPhaseReminderHook } from './phase-reminder';
|
|
4
7
|
export { createPostReadNudgeHook } from './post-read-nudge';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
export declare const JSON_ERROR_TOOL_EXCLUDE_LIST: readonly ["bash", "read", "glob", "grep", "webfetch", "grep_app_searchgithub", "websearch_web_search_exa"];
|
|
3
|
+
export declare const JSON_ERROR_PATTERNS: readonly [RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp];
|
|
4
|
+
export declare const JSON_ERROR_REMINDER = "\n[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]\n\nYou sent invalid JSON arguments. The system could not parse your tool call.\nSTOP and do this NOW:\n\n1. LOOK at the error message above to see what was expected vs what you sent.\n2. CORRECT your JSON syntax (missing braces, unescaped quotes, trailing commas, etc).\n3. RETRY the tool call with valid JSON.\n\nDO NOT repeat the exact same invalid call.\n";
|
|
5
|
+
interface ToolExecuteAfterInput {
|
|
6
|
+
tool: string;
|
|
7
|
+
sessionID: string;
|
|
8
|
+
callID: string;
|
|
9
|
+
}
|
|
10
|
+
interface ToolExecuteAfterOutput {
|
|
11
|
+
title: string;
|
|
12
|
+
output: unknown;
|
|
13
|
+
metadata: unknown;
|
|
14
|
+
}
|
|
15
|
+
export declare function createJsonErrorRecoveryHook(_ctx: PluginInput): {
|
|
16
|
+
'tool.execute.after': (input: ToolExecuteAfterInput, output: ToolExecuteAfterOutput) => Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createJsonErrorRecoveryHook, JSON_ERROR_PATTERNS, JSON_ERROR_REMINDER, JSON_ERROR_TOOL_EXCLUDE_LIST, } from './hook';
|
|
@@ -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
|
@@ -3277,6 +3277,16 @@ var require_main = __commonJS((exports) => {
|
|
|
3277
3277
|
exports.createMessageConnection = createMessageConnection;
|
|
3278
3278
|
});
|
|
3279
3279
|
|
|
3280
|
+
// src/cli/custom-skills.ts
|
|
3281
|
+
var CUSTOM_SKILLS = [
|
|
3282
|
+
{
|
|
3283
|
+
name: "cartography",
|
|
3284
|
+
description: "Repository understanding and hierarchical codemap generation",
|
|
3285
|
+
allowedAgents: ["orchestrator", "explorer"],
|
|
3286
|
+
sourcePath: "src/skills/cartography"
|
|
3287
|
+
}
|
|
3288
|
+
];
|
|
3289
|
+
|
|
3280
3290
|
// src/cli/skills.ts
|
|
3281
3291
|
var RECOMMENDED_SKILLS = [
|
|
3282
3292
|
{
|
|
@@ -3298,6 +3308,13 @@ var RECOMMENDED_SKILLS = [
|
|
|
3298
3308
|
]
|
|
3299
3309
|
}
|
|
3300
3310
|
];
|
|
3311
|
+
var PERMISSION_ONLY_SKILLS = [
|
|
3312
|
+
{
|
|
3313
|
+
name: "requesting-code-review",
|
|
3314
|
+
allowedAgents: ["oracle"],
|
|
3315
|
+
description: "Code review template for reviewer subagents in multi-step workflows"
|
|
3316
|
+
}
|
|
3317
|
+
];
|
|
3301
3318
|
function getSkillPermissionsForAgent(agentName, skillList) {
|
|
3302
3319
|
const permissions = {
|
|
3303
3320
|
"*": agentName === "orchestrator" ? "allow" : "deny"
|
|
@@ -3321,6 +3338,18 @@ function getSkillPermissionsForAgent(agentName, skillList) {
|
|
|
3321
3338
|
permissions[skill.skillName] = "allow";
|
|
3322
3339
|
}
|
|
3323
3340
|
}
|
|
3341
|
+
for (const skill of CUSTOM_SKILLS) {
|
|
3342
|
+
const isAllowed = skill.allowedAgents.includes("*") || skill.allowedAgents.includes(agentName);
|
|
3343
|
+
if (isAllowed) {
|
|
3344
|
+
permissions[skill.name] = "allow";
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
for (const skill of PERMISSION_ONLY_SKILLS) {
|
|
3348
|
+
const isAllowed = skill.allowedAgents.includes("*") || skill.allowedAgents.includes(agentName);
|
|
3349
|
+
if (isAllowed) {
|
|
3350
|
+
permissions[skill.name] = "allow";
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3324
3353
|
return permissions;
|
|
3325
3354
|
}
|
|
3326
3355
|
|
|
@@ -3340,14 +3369,14 @@ var ORCHESTRATOR_NAME = "orchestrator";
|
|
|
3340
3369
|
var ALL_AGENT_NAMES = [ORCHESTRATOR_NAME, ...SUBAGENT_NAMES];
|
|
3341
3370
|
var SUBAGENT_DELEGATION_RULES = {
|
|
3342
3371
|
orchestrator: SUBAGENT_NAMES,
|
|
3343
|
-
fixer: [
|
|
3344
|
-
designer: [
|
|
3372
|
+
fixer: [],
|
|
3373
|
+
designer: [],
|
|
3345
3374
|
explorer: [],
|
|
3346
3375
|
librarian: [],
|
|
3347
3376
|
oracle: []
|
|
3348
3377
|
};
|
|
3349
3378
|
var DEFAULT_MODELS = {
|
|
3350
|
-
orchestrator:
|
|
3379
|
+
orchestrator: undefined,
|
|
3351
3380
|
oracle: "openai/gpt-5.2-codex",
|
|
3352
3381
|
librarian: "openai/gpt-5.1-codex-mini",
|
|
3353
3382
|
explorer: "openai/gpt-5.1-codex-mini",
|
|
@@ -16985,7 +17014,16 @@ var FallbackChainsSchema = exports_external.object({
|
|
|
16985
17014
|
fixer: AgentModelChainSchema.optional()
|
|
16986
17015
|
}).catchall(AgentModelChainSchema);
|
|
16987
17016
|
var AgentOverrideConfigSchema = exports_external.object({
|
|
16988
|
-
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(),
|
|
16989
17027
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
16990
17028
|
variant: exports_external.string().optional().catch(undefined),
|
|
16991
17029
|
skills: exports_external.array(exports_external.string()).optional(),
|
|
@@ -17010,7 +17048,7 @@ var BackgroundTaskConfigSchema = exports_external.object({
|
|
|
17010
17048
|
});
|
|
17011
17049
|
var FailoverConfigSchema = exports_external.object({
|
|
17012
17050
|
enabled: exports_external.boolean().default(true),
|
|
17013
|
-
timeoutMs: exports_external.number().min(
|
|
17051
|
+
timeoutMs: exports_external.number().min(0).default(15000),
|
|
17014
17052
|
chains: FallbackChainsSchema.default({})
|
|
17015
17053
|
});
|
|
17016
17054
|
var PluginConfigSchema = exports_external.object({
|
|
@@ -17109,25 +17147,27 @@ function loadPluginConfig(directory) {
|
|
|
17109
17147
|
}
|
|
17110
17148
|
return config2;
|
|
17111
17149
|
}
|
|
17112
|
-
function loadAgentPrompt(agentName) {
|
|
17150
|
+
function loadAgentPrompt(agentName, preset) {
|
|
17151
|
+
const presetDirName = preset && /^[a-zA-Z0-9_-]+$/.test(preset) ? preset : undefined;
|
|
17113
17152
|
const promptsDir = path.join(getUserConfigDir(), "opencode", PROMPTS_DIR_NAME);
|
|
17153
|
+
const promptSearchDirs = presetDirName ? [path.join(promptsDir, presetDirName), promptsDir] : [promptsDir];
|
|
17114
17154
|
const result = {};
|
|
17115
|
-
const
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17121
|
-
|
|
17122
|
-
|
|
17123
|
-
|
|
17124
|
-
|
|
17125
|
-
|
|
17126
|
-
result.appendPrompt = fs.readFileSync(appendPromptPath, "utf-8");
|
|
17127
|
-
} catch (error48) {
|
|
17128
|
-
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
|
+
}
|
|
17129
17166
|
}
|
|
17130
|
-
|
|
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");
|
|
17131
17171
|
return result;
|
|
17132
17172
|
}
|
|
17133
17173
|
// src/config/utils.ts
|
|
@@ -17280,9 +17320,10 @@ var FIXER_PROMPT = `You are Fixer - a fast, focused implementation specialist.
|
|
|
17280
17320
|
|
|
17281
17321
|
**Constraints**:
|
|
17282
17322
|
- NO external research (no websearch, context7, grep_app)
|
|
17283
|
-
- NO delegation (no background_task)
|
|
17323
|
+
- NO delegation (no background_task, no spawning subagents)
|
|
17284
17324
|
- No multi-step research/planning; minimal execution sequence ok
|
|
17285
|
-
- If context is insufficient
|
|
17325
|
+
- If context is insufficient: use grep/glob/lsp_diagnostics directly \u2014 do not delegate
|
|
17326
|
+
- Only ask for missing inputs you truly cannot retrieve yourself
|
|
17286
17327
|
|
|
17287
17328
|
**Output Format**:
|
|
17288
17329
|
<summary>
|
|
@@ -17504,6 +17545,10 @@ Balance: respect dependencies, avoid parallelizing what must be sequential.
|
|
|
17504
17545
|
- Confirm specialists completed successfully
|
|
17505
17546
|
- Verify solution meets requirements
|
|
17506
17547
|
|
|
17548
|
+
## Agent Role Mapping
|
|
17549
|
+
When a workflow calls for an **implementer** subagent: dispatch \`@fixer\`. Fixer has enforced constraints (no research, no delegation, structured output) that match the implementer role exactly.
|
|
17550
|
+
When a workflow calls for a **reviewer** subagent: dispatch \`@oracle\`. Oracle has the depth for architectural review and access to code review skills.
|
|
17551
|
+
|
|
17507
17552
|
</Workflow>
|
|
17508
17553
|
|
|
17509
17554
|
<Communication>
|
|
@@ -17546,21 +17591,32 @@ function createOrchestratorAgent(model, customPrompt, customAppendPrompt) {
|
|
|
17546
17591
|
|
|
17547
17592
|
${customAppendPrompt}`;
|
|
17548
17593
|
}
|
|
17549
|
-
|
|
17594
|
+
const definition = {
|
|
17550
17595
|
name: "orchestrator",
|
|
17551
17596
|
description: "AI coding orchestrator that delegates tasks to specialist agents for optimal quality, speed, and cost",
|
|
17552
17597
|
config: {
|
|
17553
|
-
model,
|
|
17554
17598
|
temperature: 0.1,
|
|
17555
17599
|
prompt
|
|
17556
17600
|
}
|
|
17557
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;
|
|
17558
17608
|
}
|
|
17559
17609
|
|
|
17560
17610
|
// src/agents/index.ts
|
|
17561
17611
|
function applyOverrides(agent, override) {
|
|
17562
|
-
if (override.model)
|
|
17563
|
-
|
|
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
|
+
}
|
|
17564
17620
|
if (override.variant)
|
|
17565
17621
|
agent.config.variant = override.variant;
|
|
17566
17622
|
if (override.temperature !== undefined)
|
|
@@ -17591,12 +17647,20 @@ var SUBAGENT_FACTORIES = {
|
|
|
17591
17647
|
function createAgents(config2) {
|
|
17592
17648
|
const getModelForAgent = (name) => {
|
|
17593
17649
|
if (name === "fixer" && !getAgentOverride(config2, "fixer")?.model) {
|
|
17594
|
-
|
|
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;
|
|
17595
17659
|
}
|
|
17596
17660
|
return DEFAULT_MODELS[name];
|
|
17597
17661
|
};
|
|
17598
17662
|
const protoSubAgents = Object.entries(SUBAGENT_FACTORIES).map(([name, factory]) => {
|
|
17599
|
-
const customPrompts = loadAgentPrompt(name);
|
|
17663
|
+
const customPrompts = loadAgentPrompt(name, config2?.preset);
|
|
17600
17664
|
return factory(getModelForAgent(name), customPrompts.prompt, customPrompts.appendPrompt);
|
|
17601
17665
|
});
|
|
17602
17666
|
const allSubAgents = protoSubAgents.map((agent) => {
|
|
@@ -17607,13 +17671,13 @@ function createAgents(config2) {
|
|
|
17607
17671
|
applyDefaultPermissions(agent, override?.skills);
|
|
17608
17672
|
return agent;
|
|
17609
17673
|
});
|
|
17610
|
-
const
|
|
17611
|
-
const
|
|
17674
|
+
const orchestratorOverride = getAgentOverride(config2, "orchestrator");
|
|
17675
|
+
const orchestratorModel = orchestratorOverride?.model ?? DEFAULT_MODELS.orchestrator;
|
|
17676
|
+
const orchestratorPrompts = loadAgentPrompt("orchestrator", config2?.preset);
|
|
17612
17677
|
const orchestrator = createOrchestratorAgent(orchestratorModel, orchestratorPrompts.prompt, orchestratorPrompts.appendPrompt);
|
|
17613
|
-
|
|
17614
|
-
|
|
17615
|
-
|
|
17616
|
-
applyOverrides(orchestrator, oOverride);
|
|
17678
|
+
applyDefaultPermissions(orchestrator, orchestratorOverride?.skills);
|
|
17679
|
+
if (orchestratorOverride) {
|
|
17680
|
+
applyOverrides(orchestrator, orchestratorOverride);
|
|
17617
17681
|
}
|
|
17618
17682
|
return [orchestrator, ...allSubAgents];
|
|
17619
17683
|
}
|
|
@@ -17675,6 +17739,27 @@ function applyAgentVariant(variant, body) {
|
|
|
17675
17739
|
}
|
|
17676
17740
|
return { ...body, variant };
|
|
17677
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
|
+
}
|
|
17678
17763
|
// src/utils/tmux.ts
|
|
17679
17764
|
var {spawn } = globalThis.Bun;
|
|
17680
17765
|
var tmuxPath = null;
|
|
@@ -18085,7 +18170,15 @@ class BackgroundTaskManager {
|
|
|
18085
18170
|
const primary = this.config?.agents?.[agentName]?.model;
|
|
18086
18171
|
const chain = [];
|
|
18087
18172
|
const seen = new Set;
|
|
18088
|
-
|
|
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]) {
|
|
18089
18182
|
if (!model || seen.has(model))
|
|
18090
18183
|
continue;
|
|
18091
18184
|
seen.add(model);
|
|
@@ -18094,6 +18187,10 @@ class BackgroundTaskManager {
|
|
|
18094
18187
|
return chain;
|
|
18095
18188
|
}
|
|
18096
18189
|
async promptWithTimeout(args, timeoutMs) {
|
|
18190
|
+
if (timeoutMs <= 0) {
|
|
18191
|
+
await this.client.session.prompt(args);
|
|
18192
|
+
return;
|
|
18193
|
+
}
|
|
18097
18194
|
await Promise.race([
|
|
18098
18195
|
this.client.session.prompt(args),
|
|
18099
18196
|
new Promise((_, reject) => {
|
|
@@ -18143,8 +18240,8 @@ class BackgroundTaskManager {
|
|
|
18143
18240
|
tools: toolPermissions,
|
|
18144
18241
|
parts: [{ type: "text", text: task.prompt }]
|
|
18145
18242
|
});
|
|
18146
|
-
const timeoutMs = this.config?.fallback?.timeoutMs ?? FALLBACK_FAILOVER_TIMEOUT_MS;
|
|
18147
18243
|
const fallbackEnabled = this.config?.fallback?.enabled ?? true;
|
|
18244
|
+
const timeoutMs = fallbackEnabled ? this.config?.fallback?.timeoutMs ?? FALLBACK_FAILOVER_TIMEOUT_MS : 0;
|
|
18148
18245
|
const chain = fallbackEnabled ? this.resolveFallbackChain(task.agent) : [];
|
|
18149
18246
|
const attemptModels = chain.length > 0 ? chain : [undefined];
|
|
18150
18247
|
const errors3 = [];
|
|
@@ -18303,7 +18400,7 @@ class BackgroundTaskManager {
|
|
|
18303
18400
|
await this.client.session.prompt({
|
|
18304
18401
|
path: { id: task.parentSessionId },
|
|
18305
18402
|
body: {
|
|
18306
|
-
parts: [
|
|
18403
|
+
parts: [createInternalAgentTextPart(message)]
|
|
18307
18404
|
}
|
|
18308
18405
|
});
|
|
18309
18406
|
}
|
|
@@ -18933,10 +19030,220 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
|
|
|
18933
19030
|
body: { title, message, variant, duration: duration3 }
|
|
18934
19031
|
}).catch(() => {});
|
|
18935
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
|
+
}
|
|
19083
|
+
// src/hooks/delegate-task-retry/patterns.ts
|
|
19084
|
+
var DELEGATE_TASK_ERROR_PATTERNS = [
|
|
19085
|
+
{
|
|
19086
|
+
pattern: "run_in_background",
|
|
19087
|
+
errorType: "missing_run_in_background",
|
|
19088
|
+
fixHint: "Add run_in_background=false (delegation) or run_in_background=true (parallel exploration)."
|
|
19089
|
+
},
|
|
19090
|
+
{
|
|
19091
|
+
pattern: "load_skills",
|
|
19092
|
+
errorType: "missing_load_skills",
|
|
19093
|
+
fixHint: "Add load_skills=[] (empty array when no skill is needed)."
|
|
19094
|
+
},
|
|
19095
|
+
{
|
|
19096
|
+
pattern: "category OR subagent_type",
|
|
19097
|
+
errorType: "mutual_exclusion",
|
|
19098
|
+
fixHint: 'Provide only one: category (e.g., "unspecified-low") OR subagent_type (e.g., "explorer").'
|
|
19099
|
+
},
|
|
19100
|
+
{
|
|
19101
|
+
pattern: "Must provide either category or subagent_type",
|
|
19102
|
+
errorType: "missing_category_or_agent",
|
|
19103
|
+
fixHint: 'Add either category="unspecified-low" or subagent_type="explorer".'
|
|
19104
|
+
},
|
|
19105
|
+
{
|
|
19106
|
+
pattern: "Unknown category",
|
|
19107
|
+
errorType: "unknown_category",
|
|
19108
|
+
fixHint: "Use a valid category listed in the error output."
|
|
19109
|
+
},
|
|
19110
|
+
{
|
|
19111
|
+
pattern: "Unknown agent",
|
|
19112
|
+
errorType: "unknown_agent",
|
|
19113
|
+
fixHint: "Use a valid agent name from the available list."
|
|
19114
|
+
},
|
|
19115
|
+
{
|
|
19116
|
+
pattern: "Skills not found",
|
|
19117
|
+
errorType: "unknown_skills",
|
|
19118
|
+
fixHint: "Use valid skill names listed in the error output."
|
|
19119
|
+
},
|
|
19120
|
+
{
|
|
19121
|
+
pattern: "is not allowed. Allowed agents:",
|
|
19122
|
+
errorType: "background_agent_not_allowed",
|
|
19123
|
+
fixHint: "Use one of the allowed agents shown in the error or delegate from a parent agent that can call this subagent."
|
|
19124
|
+
}
|
|
19125
|
+
];
|
|
19126
|
+
function detectDelegateTaskError(output) {
|
|
19127
|
+
if (!output || typeof output !== "string")
|
|
19128
|
+
return null;
|
|
19129
|
+
const hasErrorSignal = output.includes("[ERROR]") || output.includes("Invalid arguments") || output.includes("is not allowed. Allowed agents:");
|
|
19130
|
+
if (!hasErrorSignal)
|
|
19131
|
+
return null;
|
|
19132
|
+
for (const pattern of DELEGATE_TASK_ERROR_PATTERNS) {
|
|
19133
|
+
if (output.includes(pattern.pattern)) {
|
|
19134
|
+
return {
|
|
19135
|
+
errorType: pattern.errorType,
|
|
19136
|
+
originalOutput: output
|
|
19137
|
+
};
|
|
19138
|
+
}
|
|
19139
|
+
}
|
|
19140
|
+
return null;
|
|
19141
|
+
}
|
|
19142
|
+
|
|
19143
|
+
// src/hooks/delegate-task-retry/guidance.ts
|
|
19144
|
+
function extractAvailableList(output) {
|
|
19145
|
+
const match = output.match(/Allowed agents:\s*(.+)$/m);
|
|
19146
|
+
if (match)
|
|
19147
|
+
return match[1].trim();
|
|
19148
|
+
const available = output.match(/Available[^:]*:\s*(.+)$/m);
|
|
19149
|
+
if (available)
|
|
19150
|
+
return available[1].trim();
|
|
19151
|
+
return null;
|
|
19152
|
+
}
|
|
19153
|
+
function buildRetryGuidance(errorInfo) {
|
|
19154
|
+
const pattern = DELEGATE_TASK_ERROR_PATTERNS.find((p) => p.errorType === errorInfo.errorType);
|
|
19155
|
+
if (!pattern) {
|
|
19156
|
+
return `
|
|
19157
|
+
[delegate-task retry] Fix parameters and retry with corrected arguments.`;
|
|
19158
|
+
}
|
|
19159
|
+
const available = extractAvailableList(errorInfo.originalOutput);
|
|
19160
|
+
const lines = [
|
|
19161
|
+
"",
|
|
19162
|
+
"[delegate-task retry suggestion]",
|
|
19163
|
+
`Error type: ${errorInfo.errorType}`,
|
|
19164
|
+
`Fix: ${pattern.fixHint}`
|
|
19165
|
+
];
|
|
19166
|
+
if (available) {
|
|
19167
|
+
lines.push(`Available: ${available}`);
|
|
19168
|
+
}
|
|
19169
|
+
lines.push("Retry now with corrected parameters. Example:", 'task(description="...", prompt="...", category="unspecified-low", run_in_background=false, load_skills=[])');
|
|
19170
|
+
return lines.join(`
|
|
19171
|
+
`);
|
|
19172
|
+
}
|
|
19173
|
+
// src/hooks/delegate-task-retry/hook.ts
|
|
19174
|
+
function createDelegateTaskRetryHook(_ctx) {
|
|
19175
|
+
return {
|
|
19176
|
+
"tool.execute.after": async (input, output) => {
|
|
19177
|
+
const toolName = input.tool.toLowerCase();
|
|
19178
|
+
const isDelegateTool = toolName === "task" || toolName === "background_task";
|
|
19179
|
+
if (!isDelegateTool)
|
|
19180
|
+
return;
|
|
19181
|
+
if (typeof output.output !== "string")
|
|
19182
|
+
return;
|
|
19183
|
+
const detected = detectDelegateTaskError(output.output);
|
|
19184
|
+
if (!detected)
|
|
19185
|
+
return;
|
|
19186
|
+
output.output += `
|
|
19187
|
+
${buildRetryGuidance(detected)}`;
|
|
19188
|
+
}
|
|
19189
|
+
};
|
|
19190
|
+
}
|
|
19191
|
+
// src/hooks/json-error-recovery/hook.ts
|
|
19192
|
+
var JSON_ERROR_TOOL_EXCLUDE_LIST = [
|
|
19193
|
+
"bash",
|
|
19194
|
+
"read",
|
|
19195
|
+
"glob",
|
|
19196
|
+
"grep",
|
|
19197
|
+
"webfetch",
|
|
19198
|
+
"grep_app_searchgithub",
|
|
19199
|
+
"websearch_web_search_exa"
|
|
19200
|
+
];
|
|
19201
|
+
var JSON_ERROR_PATTERNS = [
|
|
19202
|
+
/json parse error/i,
|
|
19203
|
+
/failed to parse json/i,
|
|
19204
|
+
/invalid json/i,
|
|
19205
|
+
/malformed json/i,
|
|
19206
|
+
/unexpected end of json input/i,
|
|
19207
|
+
/syntaxerror:\s*unexpected token.*json/i,
|
|
19208
|
+
/json[^\n]*expected '\}'/i,
|
|
19209
|
+
/json[^\n]*unexpected eof/i
|
|
19210
|
+
];
|
|
19211
|
+
var JSON_ERROR_REMINDER_MARKER = "[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]";
|
|
19212
|
+
var JSON_ERROR_EXCLUDED_TOOLS = new Set(JSON_ERROR_TOOL_EXCLUDE_LIST);
|
|
19213
|
+
var JSON_ERROR_REMINDER = `
|
|
19214
|
+
[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]
|
|
19215
|
+
|
|
19216
|
+
You sent invalid JSON arguments. The system could not parse your tool call.
|
|
19217
|
+
STOP and do this NOW:
|
|
19218
|
+
|
|
19219
|
+
1. LOOK at the error message above to see what was expected vs what you sent.
|
|
19220
|
+
2. CORRECT your JSON syntax (missing braces, unescaped quotes, trailing commas, etc).
|
|
19221
|
+
3. RETRY the tool call with valid JSON.
|
|
19222
|
+
|
|
19223
|
+
DO NOT repeat the exact same invalid call.
|
|
19224
|
+
`;
|
|
19225
|
+
function createJsonErrorRecoveryHook(_ctx) {
|
|
19226
|
+
return {
|
|
19227
|
+
"tool.execute.after": async (input, output) => {
|
|
19228
|
+
if (JSON_ERROR_EXCLUDED_TOOLS.has(input.tool.toLowerCase()))
|
|
19229
|
+
return;
|
|
19230
|
+
if (typeof output.output !== "string")
|
|
19231
|
+
return;
|
|
19232
|
+
if (output.output.includes(JSON_ERROR_REMINDER_MARKER))
|
|
19233
|
+
return;
|
|
19234
|
+
const outputText = output.output;
|
|
19235
|
+
const hasJsonError = JSON_ERROR_PATTERNS.some((pattern) => pattern.test(outputText));
|
|
19236
|
+
if (hasJsonError) {
|
|
19237
|
+
output.output += `
|
|
19238
|
+
${JSON_ERROR_REMINDER}`;
|
|
19239
|
+
}
|
|
19240
|
+
}
|
|
19241
|
+
};
|
|
19242
|
+
}
|
|
18936
19243
|
// src/hooks/phase-reminder/index.ts
|
|
18937
|
-
var PHASE_REMINDER = `<reminder
|
|
18938
|
-
|
|
18939
|
-
|
|
19244
|
+
var PHASE_REMINDER = `<reminder>Recall Workflow Rules:
|
|
19245
|
+
Understand \u2192 find the best path (delegate based on rules and parallelize independent work) \u2192 execute \u2192 verify.
|
|
19246
|
+
If delegating, launch the specialist in the same turn you mention it.</reminder>`;
|
|
18940
19247
|
function createPhaseReminderHook() {
|
|
18941
19248
|
return {
|
|
18942
19249
|
"experimental.chat.messages.transform": async (_input, output) => {
|
|
@@ -18964,6 +19271,9 @@ function createPhaseReminderHook() {
|
|
|
18964
19271
|
return;
|
|
18965
19272
|
}
|
|
18966
19273
|
const originalText = lastUserMessage.parts[textPartIndex].text ?? "";
|
|
19274
|
+
if (originalText.includes(SLIM_INTERNAL_INITIATOR_MARKER)) {
|
|
19275
|
+
return;
|
|
19276
|
+
}
|
|
18967
19277
|
lastUserMessage.parts[textPartIndex].text = `${PHASE_REMINDER}
|
|
18968
19278
|
|
|
18969
19279
|
---
|
|
@@ -18976,7 +19286,7 @@ ${originalText}`;
|
|
|
18976
19286
|
var NUDGE = `
|
|
18977
19287
|
|
|
18978
19288
|
---
|
|
18979
|
-
Reminder
|
|
19289
|
+
Workflow Reminder: delegate based on rules; If mentioning a specialist, launch it in this same turn.`;
|
|
18980
19290
|
function createPostReadNudgeHook() {
|
|
18981
19291
|
return {
|
|
18982
19292
|
"tool.execute.after": async (input, output) => {
|
|
@@ -33218,7 +33528,14 @@ var lsp_rename = tool({
|
|
|
33218
33528
|
// src/index.ts
|
|
33219
33529
|
var OhMyOpenCodeLite = async (ctx) => {
|
|
33220
33530
|
const config3 = loadPluginConfig(ctx.directory);
|
|
33531
|
+
const agentDefs = createAgents(config3);
|
|
33221
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
|
+
}
|
|
33222
33539
|
const tmuxConfig = {
|
|
33223
33540
|
enabled: config3.tmux?.enabled ?? false,
|
|
33224
33541
|
layout: config3.tmux?.layout ?? "main-vertical",
|
|
@@ -33242,6 +33559,9 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33242
33559
|
});
|
|
33243
33560
|
const phaseReminderHook = createPhaseReminderHook();
|
|
33244
33561
|
const postReadNudgeHook = createPostReadNudgeHook();
|
|
33562
|
+
const chatHeadersHook = createChatHeadersHook(ctx);
|
|
33563
|
+
const delegateTaskRetryHook = createDelegateTaskRetryHook(ctx);
|
|
33564
|
+
const jsonErrorRecoveryHook = createJsonErrorRecoveryHook(ctx);
|
|
33245
33565
|
return {
|
|
33246
33566
|
name: "oh-my-opencode-slim",
|
|
33247
33567
|
agent: agents,
|
|
@@ -33264,6 +33584,40 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33264
33584
|
Object.assign(opencodeConfig.agent, agents);
|
|
33265
33585
|
}
|
|
33266
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
|
+
}
|
|
33267
33621
|
const configMcp = opencodeConfig.mcp;
|
|
33268
33622
|
if (!configMcp) {
|
|
33269
33623
|
opencodeConfig.mcp = { ...mcps };
|
|
@@ -33300,8 +33654,13 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33300
33654
|
await backgroundManager.handleSessionDeleted(input.event);
|
|
33301
33655
|
await tmuxSessionManager.onSessionDeleted(input.event);
|
|
33302
33656
|
},
|
|
33657
|
+
"chat.headers": chatHeadersHook["chat.headers"],
|
|
33303
33658
|
"experimental.chat.messages.transform": phaseReminderHook["experimental.chat.messages.transform"],
|
|
33304
|
-
"tool.execute.after":
|
|
33659
|
+
"tool.execute.after": async (input, output) => {
|
|
33660
|
+
await delegateTaskRetryHook["tool.execute.after"](input, output);
|
|
33661
|
+
await jsonErrorRecoveryHook["tool.execute.after"](input, output);
|
|
33662
|
+
await postReadNudgeHook["tool.execute.after"](input, output);
|
|
33663
|
+
}
|
|
33305
33664
|
};
|
|
33306
33665
|
};
|
|
33307
33666
|
var src_default = OhMyOpenCodeLite;
|
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
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { Account, AccountQuotaResult, AccountsConfig } from './types';
|
|
2
|
-
export declare const CONFIG_PATHS: string[];
|
|
3
|
-
export declare function loadAccountsConfig(): AccountsConfig | null;
|
|
4
|
-
export declare function fetchAccountQuota(account: Account): Promise<AccountQuotaResult>;
|
|
5
|
-
export declare function fetchAllQuotas(accounts: Account[]): Promise<AccountQuotaResult[]>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compact quota display tool - groups models by quota family
|
|
3
|
-
*
|
|
4
|
-
* Output format:
|
|
5
|
-
* ```
|
|
6
|
-
* tornikevault
|
|
7
|
-
* Claude [░░░░░░░░░░] 0% 3h23m
|
|
8
|
-
* G-Flash [██████████] 100% 4h59m
|
|
9
|
-
* G-Pro [██████████] 100% 4h59m
|
|
10
|
-
*
|
|
11
|
-
* tzedgin
|
|
12
|
-
* Claude [░░░░░░░░░░] 0% 1h41m
|
|
13
|
-
* G-Flash [██████████] 100% 4h59m
|
|
14
|
-
* G-Pro [██████████] 100% 4h59m
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export declare const antigravity_quota: {
|
|
18
|
-
description: string;
|
|
19
|
-
args: {};
|
|
20
|
-
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
21
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export interface Account {
|
|
2
|
-
email: string;
|
|
3
|
-
refreshToken: string;
|
|
4
|
-
projectId?: string;
|
|
5
|
-
managedProjectId?: string;
|
|
6
|
-
rateLimitResetTimes: Record<string, number>;
|
|
7
|
-
}
|
|
8
|
-
export interface AccountsConfig {
|
|
9
|
-
accounts: Account[];
|
|
10
|
-
activeIndex: number;
|
|
11
|
-
}
|
|
12
|
-
export interface QuotaInfo {
|
|
13
|
-
remainingFraction?: number;
|
|
14
|
-
resetTime?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface ModelInfo {
|
|
17
|
-
displayName?: string;
|
|
18
|
-
model?: string;
|
|
19
|
-
quotaInfo?: QuotaInfo;
|
|
20
|
-
recommended?: boolean;
|
|
21
|
-
}
|
|
22
|
-
export interface QuotaResponse {
|
|
23
|
-
models?: Record<string, ModelInfo>;
|
|
24
|
-
}
|
|
25
|
-
export interface TokenResponse {
|
|
26
|
-
access_token: string;
|
|
27
|
-
}
|
|
28
|
-
export interface LoadCodeAssistResponse {
|
|
29
|
-
cloudaicompanionProject?: unknown;
|
|
30
|
-
}
|
|
31
|
-
export interface ModelQuota {
|
|
32
|
-
name: string;
|
|
33
|
-
percent: number;
|
|
34
|
-
resetIn: string;
|
|
35
|
-
}
|
|
36
|
-
export interface AccountQuotaResult {
|
|
37
|
-
email: string;
|
|
38
|
-
success: boolean;
|
|
39
|
-
error?: string;
|
|
40
|
-
models: ModelQuota[];
|
|
41
|
-
}
|