thoth-agents 0.11.0 → 0.13.0
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 +16 -5
- package/dist/agents/agent-config.d.ts +13 -0
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/orchestrator.d.ts +1 -1
- package/dist/{chunk-I5TXGNSG.js → chunk-5MYXVRZZ.js} +634 -366
- package/dist/chunk-6O4GKDS7.js +207 -0
- package/dist/{chunk-RWQPMWEM.js → chunk-JLU3FSBT.js} +17 -2
- package/dist/chunk-MIDGZE34.js +107 -0
- package/dist/{chunk-HACUJFKI.js → chunk-NOLDFT7O.js} +4 -230
- package/dist/{chunk-5WPP6IY7.js → chunk-VVYAQTYE.js} +2 -2
- package/dist/{chunk-DNPKVFOB.js → chunk-YCWGTDFE.js} +604 -315
- package/dist/cli/config-io.d.ts +2 -2
- package/dist/cli/index.js +94 -41
- package/dist/cli/install.d.ts +1 -0
- package/dist/cli/opencode-profiles.d.ts +10 -0
- package/dist/cli/opencode-skill-consent.d.ts +5 -0
- package/dist/cli/operations/opencode.d.ts +2 -1
- package/dist/cli/operations/types.d.ts +1 -0
- package/dist/cli/owned-skills.d.ts +16 -0
- package/dist/cli/paths.d.ts +1 -1
- package/dist/cli/providers.d.ts +1 -1
- package/dist/cli/system.d.ts +3 -1
- package/dist/cli/thoth-mem-install.d.ts +10 -10
- package/dist/cli/tui/index.js +53 -5
- package/dist/cli/tui/operations.d.ts +2 -0
- package/dist/cli/types.d.ts +2 -4
- package/dist/config/loader.d.ts +2 -5
- package/dist/config/schema.d.ts +0 -53
- package/dist/harness/adapters/opencode.d.ts +1 -1
- package/dist/hooks/delegate-task-retry/hook.d.ts +8 -8
- package/dist/hooks/foreground-fallback/index.d.ts +14 -69
- package/dist/hooks/index.d.ts +0 -2
- package/dist/hooks/json-error-recovery/hook.d.ts +2 -15
- package/dist/hooks/oracle-gate-verdict/hook.d.ts +4 -11
- package/dist/index.d.ts +7 -4
- package/dist/index.js +1603 -1408
- package/dist/opencode/agents.d.ts +3 -0
- package/dist/opencode/command.d.ts +3 -0
- package/dist/opencode/context.d.ts +36 -0
- package/dist/opencode/delegation-hooks.d.ts +3 -0
- package/dist/opencode/mcp.d.ts +3 -0
- package/dist/opencode/permission-rules.d.ts +9 -0
- package/dist/opencode/permissions.d.ts +3 -0
- package/dist/opencode/profile-rpc-handlers.d.ts +3 -0
- package/dist/opencode/profile-rpc.d.ts +688 -0
- package/dist/opencode/profile-runtime.d.ts +3 -0
- package/dist/opencode/profile-sessions.d.ts +18 -0
- package/dist/opencode/profiles/editor.d.ts +44 -0
- package/dist/opencode/profiles/index.d.ts +18 -0
- package/dist/opencode/profiles/resolver.d.ts +12 -0
- package/dist/opencode/profiles/store.d.ts +63 -0
- package/dist/opencode/profiles/types.d.ts +26 -0
- package/dist/opencode/session-hooks.d.ts +3 -0
- package/dist/opencode/session-state.d.ts +39 -0
- package/dist/opencode/skills.d.ts +3 -0
- package/dist/opencode/tool-overrides/evaluator.d.ts +13 -0
- package/dist/opencode/tool-overrides/index.d.ts +5 -0
- package/dist/opencode/tool-overrides/store.d.ts +38 -0
- package/dist/opencode/tool-overrides/types.d.ts +32 -0
- package/dist/opencode/tool-overrides/validation.d.ts +5 -0
- package/dist/opencode/tool-overrides/wildcard.d.ts +3 -0
- package/dist/opencode/tool-rpc-handlers.d.ts +3 -0
- package/dist/opencode/tool-rpc.d.ts +428 -0
- package/dist/opencode/tools.d.ts +3 -0
- package/dist/pi.js +3 -3
- package/dist/tools/ast-grep/cli.d.ts +1 -0
- package/dist/tools/ast-grep/index.d.ts +108 -2
- package/dist/tools/ast-grep/tools.d.ts +107 -3
- package/dist/tools/define-tool.d.ts +23 -0
- package/dist/tools/lsp/tools.d.ts +97 -5
- package/dist/tui/fixtures.d.ts +2 -0
- package/dist/tui/flow.d.ts +16 -0
- package/dist/tui/index.d.ts +7 -0
- package/dist/tui/index.js +1384 -0
- package/dist/tui/model.d.ts +84 -0
- package/dist/tui/tools/fixtures.d.ts +3 -0
- package/dist/tui/tools/flow.d.ts +11 -0
- package/dist/tui/tools/model.d.ts +97 -0
- package/dist/utils/index.d.ts +0 -1
- package/package.json +18 -3
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/skills/thoth-sdd/SKILL.md +8 -2
- package/plugin/skills/thoth-sdd/scripts/validate-result.mjs +28 -2
- package/skills/thoth-sdd/SKILL.md +8 -2
- package/skills/thoth-sdd/scripts/validate-result.mjs +28 -2
- package/thoth-agents.schema.json +0 -96
- package/dist/chunk-62L3ORXN.js +0 -30
- package/dist/delegation/project-id.d.ts +0 -10
- package/dist/hooks/auto-update-checker/checker.d.ts +0 -23
- package/dist/hooks/auto-update-checker/constants.d.ts +0 -11
- package/dist/hooks/auto-update-checker/index.d.ts +0 -17
- package/dist/hooks/auto-update-checker/types.d.ts +0 -22
- package/dist/utils/tmux-session-manager.d.ts +0 -63
- package/dist/utils/tmux.d.ts +0 -32
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// src/opencode/profile-rpc.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var ProfileRoleSchema = z.enum([
|
|
4
|
+
"orchestrator",
|
|
5
|
+
"explorer",
|
|
6
|
+
"librarian",
|
|
7
|
+
"oracle",
|
|
8
|
+
"designer",
|
|
9
|
+
"worker"
|
|
10
|
+
]);
|
|
11
|
+
var ProfileScopeSchema = z.enum(["global", "project"]);
|
|
12
|
+
var SelectionScopeSchema = z.enum([
|
|
13
|
+
"session",
|
|
14
|
+
"project",
|
|
15
|
+
"global",
|
|
16
|
+
"default"
|
|
17
|
+
]);
|
|
18
|
+
var RoleModelSchema = z.object({
|
|
19
|
+
model: z.string().regex(/^[^/\s#]+\/[^\s#]+$/).optional(),
|
|
20
|
+
variant: z.string().regex(/^[^\s#]+$/).optional()
|
|
21
|
+
});
|
|
22
|
+
var ProfileSchema = z.object({
|
|
23
|
+
agents: z.partialRecord(ProfileRoleSchema, RoleModelSchema)
|
|
24
|
+
});
|
|
25
|
+
var name = z.string().trim().min(1);
|
|
26
|
+
var session = z.object({ sessionID: z.string().min(1) });
|
|
27
|
+
var optionalSession = session.partial();
|
|
28
|
+
var target = z.object({ scope: ProfileScopeSchema, name });
|
|
29
|
+
var selectionScope = z.enum(["session", "project", "global"]);
|
|
30
|
+
var ProfileEntrySchema = target.extend({
|
|
31
|
+
source: ProfileScopeSchema,
|
|
32
|
+
shadowed: z.boolean(),
|
|
33
|
+
profile: ProfileSchema,
|
|
34
|
+
/** Opaque per-profile token, including absence. Never construct in the client. */
|
|
35
|
+
revision: z.string()
|
|
36
|
+
});
|
|
37
|
+
var ProfileStateSchema = z.object({
|
|
38
|
+
profiles: z.array(ProfileEntrySchema),
|
|
39
|
+
defaultProfile: ProfileSchema,
|
|
40
|
+
roles: z.array(ProfileRoleSchema),
|
|
41
|
+
selections: z.object({
|
|
42
|
+
session: name.optional(),
|
|
43
|
+
project: name.optional(),
|
|
44
|
+
global: name.optional()
|
|
45
|
+
}),
|
|
46
|
+
effective: z.object({
|
|
47
|
+
name,
|
|
48
|
+
source: ProfileScopeSchema.optional(),
|
|
49
|
+
selectedBy: SelectionScopeSchema,
|
|
50
|
+
profile: ProfileSchema
|
|
51
|
+
}),
|
|
52
|
+
orchestrator: RoleModelSchema.optional(),
|
|
53
|
+
providers: z.array(
|
|
54
|
+
z.object({
|
|
55
|
+
id: z.string(),
|
|
56
|
+
name: z.string(),
|
|
57
|
+
models: z.array(
|
|
58
|
+
z.object({
|
|
59
|
+
id: z.string(),
|
|
60
|
+
name: z.string(),
|
|
61
|
+
variants: z.array(z.string())
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
})
|
|
65
|
+
),
|
|
66
|
+
warnings: z.array(z.string())
|
|
67
|
+
});
|
|
68
|
+
var ProfileErrorSchema = z.object({
|
|
69
|
+
code: z.enum([
|
|
70
|
+
"PROFILE_CONFLICT",
|
|
71
|
+
"PROFILE_SHADOWED",
|
|
72
|
+
"INVALID_REQUEST",
|
|
73
|
+
"MODEL_UNAVAILABLE",
|
|
74
|
+
"OPERATION_FAILED"
|
|
75
|
+
]),
|
|
76
|
+
message: z.string()
|
|
77
|
+
});
|
|
78
|
+
function result(value) {
|
|
79
|
+
return z.discriminatedUnion("ok", [
|
|
80
|
+
z.object({ ok: z.literal(true), value }),
|
|
81
|
+
z.object({ ok: z.literal(false), error: ProfileErrorSchema })
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
var profileRpc = {
|
|
85
|
+
id: "thoth-model-profiles",
|
|
86
|
+
methods: {
|
|
87
|
+
state: { input: optionalSession, output: result(ProfileStateSchema) },
|
|
88
|
+
create: {
|
|
89
|
+
input: target.extend({ profile: ProfileSchema }),
|
|
90
|
+
output: result(z.object({ revision: z.string() }))
|
|
91
|
+
},
|
|
92
|
+
save: {
|
|
93
|
+
input: target.extend({
|
|
94
|
+
profile: ProfileSchema,
|
|
95
|
+
baseRevision: z.string()
|
|
96
|
+
}),
|
|
97
|
+
output: result(z.object({ revision: z.string() }))
|
|
98
|
+
},
|
|
99
|
+
rename: {
|
|
100
|
+
input: target.extend({ newName: name }),
|
|
101
|
+
output: result(z.object({}))
|
|
102
|
+
},
|
|
103
|
+
delete: { input: target, output: result(z.object({})) },
|
|
104
|
+
activate: {
|
|
105
|
+
input: optionalSession.extend({ scope: selectionScope, name }),
|
|
106
|
+
output: result(ProfileStateSchema)
|
|
107
|
+
},
|
|
108
|
+
clear: {
|
|
109
|
+
input: optionalSession.extend({ scope: selectionScope }),
|
|
110
|
+
output: result(ProfileStateSchema)
|
|
111
|
+
},
|
|
112
|
+
capture: { input: session, output: result(RoleModelSchema) }
|
|
113
|
+
},
|
|
114
|
+
events: {}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/opencode/tool-rpc.ts
|
|
118
|
+
import { z as z2 } from "zod";
|
|
119
|
+
var ToolRoleSchema = z2.enum([
|
|
120
|
+
"explorer",
|
|
121
|
+
"librarian",
|
|
122
|
+
"oracle",
|
|
123
|
+
"designer",
|
|
124
|
+
"worker"
|
|
125
|
+
]);
|
|
126
|
+
var ToolScopeSchema = z2.enum(["global", "project"]);
|
|
127
|
+
var ToolEffectSchema = z2.enum(["allow", "ask", "deny"]);
|
|
128
|
+
var ToolOriginSchema = z2.enum(["default", "global", "project"]);
|
|
129
|
+
var ActionOverrideSchema = z2.object({
|
|
130
|
+
action: z2.string().min(1).refine((action) => action.trim().length > 0, "Action must not be blank"),
|
|
131
|
+
effect: ToolEffectSchema
|
|
132
|
+
});
|
|
133
|
+
var scopeState = z2.object({
|
|
134
|
+
present: z2.boolean(),
|
|
135
|
+
/** Opaque whole-file revision, including when this role is absent. */
|
|
136
|
+
revision: z2.string(),
|
|
137
|
+
/** Ordered entries, including duplicates and patterns matching no inventory action. */
|
|
138
|
+
overrides: z2.array(
|
|
139
|
+
ActionOverrideSchema.extend({ matchCount: z2.number().int().nonnegative() })
|
|
140
|
+
)
|
|
141
|
+
});
|
|
142
|
+
var ToolStateSchema = z2.object({
|
|
143
|
+
specialists: z2.array(ToolRoleSchema),
|
|
144
|
+
inventory: z2.array(
|
|
145
|
+
z2.object({
|
|
146
|
+
action: z2.string(),
|
|
147
|
+
tools: z2.array(z2.string()),
|
|
148
|
+
locked: z2.boolean()
|
|
149
|
+
})
|
|
150
|
+
),
|
|
151
|
+
roles: z2.array(
|
|
152
|
+
z2.object({
|
|
153
|
+
role: ToolRoleSchema,
|
|
154
|
+
effectiveScope: ToolOriginSchema,
|
|
155
|
+
global: scopeState,
|
|
156
|
+
project: scopeState,
|
|
157
|
+
actions: z2.array(
|
|
158
|
+
z2.object({
|
|
159
|
+
action: z2.string(),
|
|
160
|
+
effect: ToolEffectSchema,
|
|
161
|
+
/** Effect from shipped role rules alone, before any scope overrides. */
|
|
162
|
+
baseEffect: ToolEffectSchema,
|
|
163
|
+
origin: ToolOriginSchema,
|
|
164
|
+
locked: z2.boolean()
|
|
165
|
+
})
|
|
166
|
+
)
|
|
167
|
+
})
|
|
168
|
+
),
|
|
169
|
+
warnings: z2.array(z2.string())
|
|
170
|
+
});
|
|
171
|
+
var ToolErrorSchema = z2.object({
|
|
172
|
+
code: z2.enum(["TOOLS_CONFLICT", "INVALID_REQUEST", "OPERATION_FAILED"]),
|
|
173
|
+
message: z2.string()
|
|
174
|
+
});
|
|
175
|
+
var result2 = z2.discriminatedUnion("ok", [
|
|
176
|
+
z2.object({ ok: z2.literal(true), value: ToolStateSchema }),
|
|
177
|
+
z2.object({ ok: z2.literal(false), error: ToolErrorSchema })
|
|
178
|
+
]);
|
|
179
|
+
var target2 = z2.object({
|
|
180
|
+
scope: ToolScopeSchema,
|
|
181
|
+
role: ToolRoleSchema,
|
|
182
|
+
baseRevision: z2.string()
|
|
183
|
+
});
|
|
184
|
+
var toolRpc = {
|
|
185
|
+
id: "thoth-tool-permissions",
|
|
186
|
+
methods: {
|
|
187
|
+
state: { input: z2.object({}), output: result2 },
|
|
188
|
+
save: {
|
|
189
|
+
input: target2.extend({
|
|
190
|
+
overrides: z2.array(
|
|
191
|
+
ActionOverrideSchema.refine(
|
|
192
|
+
(entry) => entry.action !== "subagent",
|
|
193
|
+
"The subagent action is locked"
|
|
194
|
+
)
|
|
195
|
+
)
|
|
196
|
+
}),
|
|
197
|
+
output: result2
|
|
198
|
+
},
|
|
199
|
+
reset: { input: target2, output: result2 }
|
|
200
|
+
},
|
|
201
|
+
events: {}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
export {
|
|
205
|
+
profileRpc,
|
|
206
|
+
toolRpc
|
|
207
|
+
};
|
|
@@ -332,12 +332,27 @@ function checkExpectations(options, issue) {
|
|
|
332
332
|
"Expected digest must be 64 lowercase hex characters."
|
|
333
333
|
);
|
|
334
334
|
}
|
|
335
|
+
var isFenceLine = (line) => /^(?:`{3,}|~{3,})/.test(line);
|
|
336
|
+
var isVerdictLine = (line) => line.startsWith("thoth-gate-verdict ");
|
|
337
|
+
function unwrapSubagent(message, lines) {
|
|
338
|
+
if (!message.startsWith("<subagent ")) return message;
|
|
339
|
+
if (lines.at(-1) !== "</subagent>") return "";
|
|
340
|
+
const opener = lines.lastIndexOf("```thoth-result");
|
|
341
|
+
if (opener < 1) return "";
|
|
342
|
+
const header = lines.slice(0, opener).join("\n").trimEnd();
|
|
343
|
+
if (!header.includes('state="completed"') || lines.slice(0, opener).some((line) => isFenceLine(line) || isVerdictLine(line)))
|
|
344
|
+
return "";
|
|
345
|
+
return lines.slice(opener, -1).join("\n").trim();
|
|
346
|
+
}
|
|
335
347
|
function parseEnvelope(message) {
|
|
336
|
-
const
|
|
348
|
+
const complete = typeof message === "string" ? message.trim() : "";
|
|
349
|
+
const lines = complete.split(/\r\n|\r|\n/);
|
|
350
|
+
const singleEnvelope = lines.filter(isFenceLine).length === 2 && !lines.some(isVerdictLine);
|
|
351
|
+
const trimmed = singleEnvelope ? unwrapSubagent(complete, lines) : "";
|
|
337
352
|
const block = new RegExp(
|
|
338
353
|
`^\`\`\`${result_contract_default.fence}\\r?\\n([\\s\\S]*?)\\r?\\n\`\`\`$`
|
|
339
354
|
).exec(trimmed);
|
|
340
|
-
if (!block
|
|
355
|
+
if (!block) {
|
|
341
356
|
return {
|
|
342
357
|
issues: [
|
|
343
358
|
{
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// src/mcp/context7.ts
|
|
2
|
+
var CONTEXT7_MCP_URL = "https://mcp.context7.com/mcp";
|
|
3
|
+
var context7 = {
|
|
4
|
+
type: "remote",
|
|
5
|
+
url: CONTEXT7_MCP_URL,
|
|
6
|
+
headers: process.env.CONTEXT7_API_KEY ? { CONTEXT7_API_KEY: process.env.CONTEXT7_API_KEY } : void 0,
|
|
7
|
+
oauth: false
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// src/mcp/exa.ts
|
|
11
|
+
var exa = {
|
|
12
|
+
type: "local",
|
|
13
|
+
command: ["npx", "-y", "exa-mcp-server"]
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/mcp/grep-app.ts
|
|
17
|
+
var GREP_APP_MCP_URL = "https://mcp.grep.app";
|
|
18
|
+
var grep_app = {
|
|
19
|
+
type: "remote",
|
|
20
|
+
url: GREP_APP_MCP_URL,
|
|
21
|
+
oauth: false
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/utils/subprocess.ts
|
|
25
|
+
import {
|
|
26
|
+
spawn as nodeSpawn,
|
|
27
|
+
spawnSync as nodeSpawnSync
|
|
28
|
+
} from "child_process";
|
|
29
|
+
import { Readable } from "stream";
|
|
30
|
+
function emptyReadableStream() {
|
|
31
|
+
return new ReadableStream({
|
|
32
|
+
start(controller) {
|
|
33
|
+
controller.close();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function toWebReadable(stream) {
|
|
38
|
+
if (!stream) {
|
|
39
|
+
return emptyReadableStream();
|
|
40
|
+
}
|
|
41
|
+
return Readable.toWeb(
|
|
42
|
+
stream
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
function fallbackStdin() {
|
|
46
|
+
return {
|
|
47
|
+
write: () => void 0,
|
|
48
|
+
end: () => void 0
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function spawn(command, options = {}) {
|
|
52
|
+
const child = nodeSpawn(command[0], command.slice(1), {
|
|
53
|
+
cwd: options.cwd,
|
|
54
|
+
env: options.env,
|
|
55
|
+
stdio: [
|
|
56
|
+
options.stdin ?? "pipe",
|
|
57
|
+
options.stdout ?? "pipe",
|
|
58
|
+
options.stderr ?? "pipe"
|
|
59
|
+
],
|
|
60
|
+
shell: options.shell,
|
|
61
|
+
windowsHide: options.windowsHide ?? true
|
|
62
|
+
});
|
|
63
|
+
const managed = {
|
|
64
|
+
stdin: child.stdin ?? fallbackStdin(),
|
|
65
|
+
stdout: toWebReadable(child.stdout),
|
|
66
|
+
stderr: toWebReadable(child.stderr),
|
|
67
|
+
exited: new Promise((resolve) => {
|
|
68
|
+
child.on("exit", (code) => {
|
|
69
|
+
managed.exitCode = code;
|
|
70
|
+
resolve(code ?? 1);
|
|
71
|
+
});
|
|
72
|
+
child.on("error", () => {
|
|
73
|
+
managed.exitCode = 1;
|
|
74
|
+
resolve(1);
|
|
75
|
+
});
|
|
76
|
+
}),
|
|
77
|
+
exitCode: child.exitCode,
|
|
78
|
+
kill: () => {
|
|
79
|
+
child.kill();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
return managed;
|
|
83
|
+
}
|
|
84
|
+
function spawnSync(command, options = {}) {
|
|
85
|
+
const result = nodeSpawnSync(command[0], command.slice(1), {
|
|
86
|
+
cwd: options.cwd,
|
|
87
|
+
env: options.env,
|
|
88
|
+
stdio: [
|
|
89
|
+
options.stdin ?? "ignore",
|
|
90
|
+
options.stdout ?? "pipe",
|
|
91
|
+
options.stderr ?? "pipe"
|
|
92
|
+
],
|
|
93
|
+
shell: options.shell,
|
|
94
|
+
windowsHide: options.windowsHide ?? true
|
|
95
|
+
});
|
|
96
|
+
return { exitCode: result.status };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
CONTEXT7_MCP_URL,
|
|
101
|
+
context7,
|
|
102
|
+
exa,
|
|
103
|
+
GREP_APP_MCP_URL,
|
|
104
|
+
grep_app,
|
|
105
|
+
spawn,
|
|
106
|
+
spawnSync
|
|
107
|
+
};
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
loadAgentPrompt,
|
|
17
17
|
renderAgentRoutingDescription,
|
|
18
18
|
renderRolePrompt
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-YCWGTDFE.js";
|
|
20
20
|
|
|
21
21
|
// src/agents/designer.ts
|
|
22
22
|
var DESIGNER_PROMPT = renderRolePrompt(
|
|
@@ -363,7 +363,7 @@ var SUBAGENT_FACTORIES = {
|
|
|
363
363
|
function createAgents(config) {
|
|
364
364
|
const protoSubAgents = Object.entries(SUBAGENT_FACTORIES).map(([name, factory]) => {
|
|
365
365
|
const override = getAgentOverride(config, name);
|
|
366
|
-
const prompts = loadAgentPrompt(name
|
|
366
|
+
const prompts = loadAgentPrompt(name);
|
|
367
367
|
const model = getPrimaryModelForPrompt(override?.model) ?? DEFAULT_MODELS[name];
|
|
368
368
|
const agent = factory(model, prompts.prompt, prompts.appendPrompt);
|
|
369
369
|
agent.description = renderAgentRoutingDescription(getAgentRole(name));
|
|
@@ -379,7 +379,7 @@ function createAgents(config) {
|
|
|
379
379
|
return agent;
|
|
380
380
|
});
|
|
381
381
|
const orchestratorOverride = getAgentOverride(config, "orchestrator");
|
|
382
|
-
const orchestratorPrompts = loadAgentPrompt("orchestrator"
|
|
382
|
+
const orchestratorPrompts = loadAgentPrompt("orchestrator");
|
|
383
383
|
const orchestrator = createOrchestratorAgent(
|
|
384
384
|
orchestratorOverride?.model ?? `openai/${OPENCODE_OPENAI_ORCHESTRATOR_PRESET.model}`,
|
|
385
385
|
orchestratorPrompts.prompt,
|
|
@@ -455,234 +455,8 @@ var opencodeAdapter = {
|
|
|
455
455
|
}
|
|
456
456
|
};
|
|
457
457
|
|
|
458
|
-
// src/utils/subprocess.ts
|
|
459
|
-
import {
|
|
460
|
-
spawn as nodeSpawn,
|
|
461
|
-
spawnSync as nodeSpawnSync
|
|
462
|
-
} from "child_process";
|
|
463
|
-
import { Readable } from "stream";
|
|
464
|
-
function emptyReadableStream() {
|
|
465
|
-
return new ReadableStream({
|
|
466
|
-
start(controller) {
|
|
467
|
-
controller.close();
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
function toWebReadable(stream) {
|
|
472
|
-
if (!stream) {
|
|
473
|
-
return emptyReadableStream();
|
|
474
|
-
}
|
|
475
|
-
return Readable.toWeb(
|
|
476
|
-
stream
|
|
477
|
-
);
|
|
478
|
-
}
|
|
479
|
-
function fallbackStdin() {
|
|
480
|
-
return {
|
|
481
|
-
write: () => void 0,
|
|
482
|
-
end: () => void 0
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
function spawn(command, options = {}) {
|
|
486
|
-
const child = nodeSpawn(command[0], command.slice(1), {
|
|
487
|
-
cwd: options.cwd,
|
|
488
|
-
env: options.env,
|
|
489
|
-
stdio: [
|
|
490
|
-
options.stdin ?? "pipe",
|
|
491
|
-
options.stdout ?? "pipe",
|
|
492
|
-
options.stderr ?? "pipe"
|
|
493
|
-
],
|
|
494
|
-
shell: options.shell,
|
|
495
|
-
windowsHide: options.windowsHide ?? true
|
|
496
|
-
});
|
|
497
|
-
const managed = {
|
|
498
|
-
stdin: child.stdin ?? fallbackStdin(),
|
|
499
|
-
stdout: toWebReadable(child.stdout),
|
|
500
|
-
stderr: toWebReadable(child.stderr),
|
|
501
|
-
exited: new Promise((resolve) => {
|
|
502
|
-
child.on("exit", (code) => {
|
|
503
|
-
managed.exitCode = code;
|
|
504
|
-
resolve(code ?? 1);
|
|
505
|
-
});
|
|
506
|
-
child.on("error", () => {
|
|
507
|
-
managed.exitCode = 1;
|
|
508
|
-
resolve(1);
|
|
509
|
-
});
|
|
510
|
-
}),
|
|
511
|
-
exitCode: child.exitCode,
|
|
512
|
-
kill: () => {
|
|
513
|
-
child.kill();
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
return managed;
|
|
517
|
-
}
|
|
518
|
-
function spawnSync(command, options = {}) {
|
|
519
|
-
const result = nodeSpawnSync(command[0], command.slice(1), {
|
|
520
|
-
cwd: options.cwd,
|
|
521
|
-
env: options.env,
|
|
522
|
-
stdio: [
|
|
523
|
-
options.stdin ?? "ignore",
|
|
524
|
-
options.stdout ?? "pipe",
|
|
525
|
-
options.stderr ?? "pipe"
|
|
526
|
-
],
|
|
527
|
-
shell: options.shell,
|
|
528
|
-
windowsHide: options.windowsHide ?? true
|
|
529
|
-
});
|
|
530
|
-
return { exitCode: result.status };
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// src/cli/system.ts
|
|
534
|
-
import { statSync } from "fs";
|
|
535
|
-
var cachedOpenCodePath = null;
|
|
536
|
-
var OPENCODE_PROBE_TIMEOUT_MS = 1500;
|
|
537
|
-
function quoteWindowsShellCommand(command) {
|
|
538
|
-
if (!/[\s&()^<>"|]/.test(command)) {
|
|
539
|
-
return command;
|
|
540
|
-
}
|
|
541
|
-
return `"${command.replace(/"/g, '\\"')}"`;
|
|
542
|
-
}
|
|
543
|
-
function getOpenCodeVersionInvocation(opencodePath, platform = process.platform) {
|
|
544
|
-
const options = {
|
|
545
|
-
stdout: "pipe",
|
|
546
|
-
stderr: "pipe"
|
|
547
|
-
};
|
|
548
|
-
if (platform === "win32") {
|
|
549
|
-
return {
|
|
550
|
-
command: [`${quoteWindowsShellCommand(opencodePath)} --version`],
|
|
551
|
-
options: { ...options, shell: true }
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
return { command: [opencodePath, "--version"], options };
|
|
555
|
-
}
|
|
556
|
-
function getOpenCodePaths() {
|
|
557
|
-
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
558
|
-
return [
|
|
559
|
-
// PATH (try this first)
|
|
560
|
-
"opencode",
|
|
561
|
-
// User local installations (Linux & macOS)
|
|
562
|
-
`${home}/.local/bin/opencode`,
|
|
563
|
-
`${home}/.opencode/bin/opencode`,
|
|
564
|
-
`${home}/bin/opencode`,
|
|
565
|
-
// System-wide installations
|
|
566
|
-
"/usr/local/bin/opencode",
|
|
567
|
-
"/opt/opencode/bin/opencode",
|
|
568
|
-
"/usr/bin/opencode",
|
|
569
|
-
"/bin/opencode",
|
|
570
|
-
// macOS specific
|
|
571
|
-
"/Applications/OpenCode.app/Contents/MacOS/opencode",
|
|
572
|
-
`${home}/Applications/OpenCode.app/Contents/MacOS/opencode`,
|
|
573
|
-
// Homebrew (macOS & Linux)
|
|
574
|
-
"/opt/homebrew/bin/opencode",
|
|
575
|
-
"/home/linuxbrew/.linuxbrew/bin/opencode",
|
|
576
|
-
`${home}/homebrew/bin/opencode`,
|
|
577
|
-
// macOS user Library
|
|
578
|
-
`${home}/Library/Application Support/opencode/bin/opencode`,
|
|
579
|
-
// Snap (Linux)
|
|
580
|
-
"/snap/bin/opencode",
|
|
581
|
-
"/var/snap/opencode/current/bin/opencode",
|
|
582
|
-
// Flatpak (Linux)
|
|
583
|
-
"/var/lib/flatpak/exports/bin/ai.opencode.OpenCode",
|
|
584
|
-
`${home}/.local/share/flatpak/exports/bin/ai.opencode.OpenCode`,
|
|
585
|
-
// Nix (Linux/macOS)
|
|
586
|
-
"/nix/store/opencode/bin/opencode",
|
|
587
|
-
`${home}/.nix-profile/bin/opencode`,
|
|
588
|
-
"/run/current-system/sw/bin/opencode",
|
|
589
|
-
// Cargo (Rust toolchain)
|
|
590
|
-
`${home}/.cargo/bin/opencode`,
|
|
591
|
-
// npm/npx global
|
|
592
|
-
`${home}/.npm-global/bin/opencode`,
|
|
593
|
-
"/usr/local/lib/node_modules/opencode/bin/opencode",
|
|
594
|
-
// Yarn global
|
|
595
|
-
`${home}/.yarn/bin/opencode`,
|
|
596
|
-
// PNPM
|
|
597
|
-
`${home}/.pnpm-global/bin/opencode`
|
|
598
|
-
];
|
|
599
|
-
}
|
|
600
|
-
function resolveOpenCodePath() {
|
|
601
|
-
if (cachedOpenCodePath) {
|
|
602
|
-
return cachedOpenCodePath;
|
|
603
|
-
}
|
|
604
|
-
const paths = getOpenCodePaths();
|
|
605
|
-
for (const opencodePath of paths) {
|
|
606
|
-
if (opencodePath === "opencode") continue;
|
|
607
|
-
try {
|
|
608
|
-
const stat = statSync(opencodePath);
|
|
609
|
-
if (stat.isFile()) {
|
|
610
|
-
cachedOpenCodePath = opencodePath;
|
|
611
|
-
return opencodePath;
|
|
612
|
-
}
|
|
613
|
-
} catch {
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
return "opencode";
|
|
617
|
-
}
|
|
618
|
-
async function isOpenCodeInstalled() {
|
|
619
|
-
const paths = getOpenCodePaths();
|
|
620
|
-
for (const opencodePath of paths) {
|
|
621
|
-
try {
|
|
622
|
-
const invocation = getOpenCodeVersionInvocation(opencodePath);
|
|
623
|
-
const proc = spawn(invocation.command, {
|
|
624
|
-
...invocation.options,
|
|
625
|
-
windowsHide: true
|
|
626
|
-
});
|
|
627
|
-
let timer;
|
|
628
|
-
const timedOut = /* @__PURE__ */ Symbol("timeout");
|
|
629
|
-
try {
|
|
630
|
-
const outcome = await Promise.race([
|
|
631
|
-
proc.exited.then(() => proc.exitCode),
|
|
632
|
-
new Promise((resolve) => {
|
|
633
|
-
timer = setTimeout(
|
|
634
|
-
() => resolve(timedOut),
|
|
635
|
-
OPENCODE_PROBE_TIMEOUT_MS
|
|
636
|
-
);
|
|
637
|
-
})
|
|
638
|
-
]);
|
|
639
|
-
if (outcome === timedOut) {
|
|
640
|
-
proc.kill();
|
|
641
|
-
continue;
|
|
642
|
-
}
|
|
643
|
-
if (outcome === 0) {
|
|
644
|
-
cachedOpenCodePath = opencodePath;
|
|
645
|
-
return true;
|
|
646
|
-
}
|
|
647
|
-
} finally {
|
|
648
|
-
if (timer) {
|
|
649
|
-
clearTimeout(timer);
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
} catch {
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
return false;
|
|
656
|
-
}
|
|
657
|
-
async function getOpenCodeVersion() {
|
|
658
|
-
const opencodePath = resolveOpenCodePath();
|
|
659
|
-
try {
|
|
660
|
-
const invocation = getOpenCodeVersionInvocation(opencodePath);
|
|
661
|
-
const proc = spawn(invocation.command, {
|
|
662
|
-
...invocation.options,
|
|
663
|
-
windowsHide: true
|
|
664
|
-
});
|
|
665
|
-
const output = await new Response(proc.stdout).text();
|
|
666
|
-
await proc.exited;
|
|
667
|
-
if (proc.exitCode === 0) {
|
|
668
|
-
return output.trim();
|
|
669
|
-
}
|
|
670
|
-
} catch {
|
|
671
|
-
}
|
|
672
|
-
return null;
|
|
673
|
-
}
|
|
674
|
-
function getOpenCodePath() {
|
|
675
|
-
const path = resolveOpenCodePath();
|
|
676
|
-
return path === "opencode" ? null : path;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
458
|
export {
|
|
680
459
|
createAgents,
|
|
681
460
|
renderOpenCodeAgentConfigs,
|
|
682
|
-
opencodeAdapter
|
|
683
|
-
spawn,
|
|
684
|
-
spawnSync,
|
|
685
|
-
isOpenCodeInstalled,
|
|
686
|
-
getOpenCodeVersion,
|
|
687
|
-
getOpenCodePath
|
|
461
|
+
opencodeAdapter
|
|
688
462
|
};
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
renderAgentRoutingDescription,
|
|
20
20
|
renderPromptSection,
|
|
21
21
|
renderRolePrompt
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-YCWGTDFE.js";
|
|
23
23
|
|
|
24
24
|
// src/harness/writers/pi-agent.ts
|
|
25
25
|
var PI_MANAGED_OWNER = "thoth-agents";
|
|
@@ -733,7 +733,7 @@ function renderConfiguredRolePrompt({
|
|
|
733
733
|
config,
|
|
734
734
|
model
|
|
735
735
|
}) {
|
|
736
|
-
const promptOverrides = loadAgentPrompt(role
|
|
736
|
+
const promptOverrides = loadAgentPrompt(role);
|
|
737
737
|
const override = getAgentOverride(config, role);
|
|
738
738
|
const modelSection = createModelFamilySection(role, model);
|
|
739
739
|
const stepSection = createStepBudgetSection(override?.steps, role);
|