opencode-akane 0.1.3 → 0.1.5
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 +20 -0
- package/dist/artifacts.js +16 -0
- package/dist/config.js +21 -1
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +10 -0
- package/dist/types.d.ts +5 -0
- package/dist/workflow.js +66 -18
- package/examples/akane.example.json +11 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,6 +73,26 @@ For package-based installation, publish this repository to npm and add it to the
|
|
|
73
73
|
Akane still reads its runtime config from `~/.config/opencode/akane.json`.
|
|
74
74
|
If that file does not exist yet, the plugin now bootstraps it automatically on first load with the default config.
|
|
75
75
|
You only need to edit it when you want to override the default role or artifact settings.
|
|
76
|
+
By default, Akane stays model-first and does not depend on `oh-my-opencode`.
|
|
77
|
+
If you want to opt into OMO agents, set `workflow.preferAgents` to `true`.
|
|
78
|
+
|
|
79
|
+
`akane.json` supports both model routing and agent routing:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"workflow": {
|
|
84
|
+
"preferAgents": true
|
|
85
|
+
},
|
|
86
|
+
"roleAgents": {
|
|
87
|
+
"planner": "prometheus",
|
|
88
|
+
"plan_reviewer": "hephaestus",
|
|
89
|
+
"implementer": "atlas",
|
|
90
|
+
"reviewer_codex": "momus",
|
|
91
|
+
"reviewer_claude": "oracle",
|
|
92
|
+
"synthesizer": "sisyphus"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
76
96
|
|
|
77
97
|
## Publish flow
|
|
78
98
|
|
package/dist/artifacts.js
CHANGED
|
@@ -56,6 +56,7 @@ export function createInitialState(input) {
|
|
|
56
56
|
activeStage: null,
|
|
57
57
|
stageOrder: [...input.config.workflow.stageOrder],
|
|
58
58
|
stages,
|
|
59
|
+
roleAgents: { ...input.config.roleAgents },
|
|
59
60
|
roles: { ...input.config.roles },
|
|
60
61
|
};
|
|
61
62
|
}
|
|
@@ -109,6 +110,21 @@ export async function ensureArtifactLayout(input) {
|
|
|
109
110
|
await writeStateFile(statePath, state);
|
|
110
111
|
createdFiles.push(statePath);
|
|
111
112
|
}
|
|
113
|
+
else {
|
|
114
|
+
let updated = false;
|
|
115
|
+
if (!state.roleAgents) {
|
|
116
|
+
state.roleAgents = { ...input.config.roleAgents };
|
|
117
|
+
updated = true;
|
|
118
|
+
}
|
|
119
|
+
if (!state.roles) {
|
|
120
|
+
state.roles = { ...input.config.roles };
|
|
121
|
+
updated = true;
|
|
122
|
+
}
|
|
123
|
+
if (updated) {
|
|
124
|
+
state.updatedAt = nowIso();
|
|
125
|
+
await writeStateFile(statePath, state);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
112
128
|
return { artifactDir, statePath, state, createdFiles };
|
|
113
129
|
}
|
|
114
130
|
export async function writeStageArtifact(input) {
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { AKANE_SERVICE_NAME, AKANE_STAGE_IDS, DEFAULT_ARTIFACT_DIR, DEFAULT_GLOBAL_CONFIG_PATH, DEFAULT_PLUGIN_OUTPUT_PATH, DEFAULT_ROLE_MODELS, DEFAULT_STAGE_FILES, DEFAULT_STAGE_ORDER, DEFAULT_STATE_FILE, } from "./constants.js";
|
|
4
|
+
import { AKANE_SERVICE_NAME, AKANE_ROLE_IDS, AKANE_STAGE_IDS, DEFAULT_ARTIFACT_DIR, DEFAULT_GLOBAL_CONFIG_PATH, DEFAULT_PLUGIN_OUTPUT_PATH, DEFAULT_ROLE_AGENTS, DEFAULT_ROLE_MODELS, DEFAULT_STAGE_FILES, DEFAULT_STAGE_ORDER, DEFAULT_STATE_FILE, } from "./constants.js";
|
|
5
5
|
function isRecord(value) {
|
|
6
6
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
7
|
}
|
|
@@ -50,7 +50,9 @@ export function defaultAkaneConfig(configPath = DEFAULT_GLOBAL_CONFIG_PATH) {
|
|
|
50
50
|
},
|
|
51
51
|
workflow: {
|
|
52
52
|
stageOrder: [...DEFAULT_STAGE_ORDER],
|
|
53
|
+
preferAgents: false,
|
|
53
54
|
},
|
|
55
|
+
roleAgents: { ...DEFAULT_ROLE_AGENTS },
|
|
54
56
|
roles: { ...DEFAULT_ROLE_MODELS },
|
|
55
57
|
};
|
|
56
58
|
}
|
|
@@ -76,6 +78,19 @@ function normalizeRoles(input, fallback) {
|
|
|
76
78
|
}
|
|
77
79
|
return next;
|
|
78
80
|
}
|
|
81
|
+
function normalizeRoleAgents(input, fallback) {
|
|
82
|
+
if (!isRecord(input)) {
|
|
83
|
+
return { ...fallback };
|
|
84
|
+
}
|
|
85
|
+
const next = { ...fallback };
|
|
86
|
+
for (const role of AKANE_ROLE_IDS) {
|
|
87
|
+
const candidate = input[role];
|
|
88
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
89
|
+
next[role] = candidate.trim();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return next;
|
|
93
|
+
}
|
|
79
94
|
function normalizeFiles(input, fallback) {
|
|
80
95
|
if (!isRecord(input)) {
|
|
81
96
|
return { ...fallback };
|
|
@@ -126,7 +141,12 @@ export function mergeAkaneConfig(base, overrides) {
|
|
|
126
141
|
},
|
|
127
142
|
workflow: {
|
|
128
143
|
stageOrder: normalizeStageOrder(isRecord(overrides.workflow) ? overrides.workflow.stageOrder : undefined, base.workflow.stageOrder),
|
|
144
|
+
preferAgents: isRecord(overrides.workflow) &&
|
|
145
|
+
typeof overrides.workflow.preferAgents === "boolean"
|
|
146
|
+
? overrides.workflow.preferAgents
|
|
147
|
+
: base.workflow.preferAgents,
|
|
129
148
|
},
|
|
149
|
+
roleAgents: normalizeRoleAgents(overrides.roleAgents, base.roleAgents),
|
|
130
150
|
roles: normalizeRoles(overrides.roles, base.roles),
|
|
131
151
|
};
|
|
132
152
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -16,6 +16,16 @@ export declare const DEFAULT_ROLE_MODELS: {
|
|
|
16
16
|
readonly reviewer_claude: "anthropic/claude-opus-4-6";
|
|
17
17
|
readonly synthesizer: "openai/gpt-5.4";
|
|
18
18
|
};
|
|
19
|
+
export declare const DEFAULT_ROLE_AGENTS: {
|
|
20
|
+
readonly planner: "prometheus";
|
|
21
|
+
readonly plan_reviewer: "metis";
|
|
22
|
+
readonly implementer: "atlas";
|
|
23
|
+
readonly consultant_primary: "oracle";
|
|
24
|
+
readonly consultant_secondary: "librarian";
|
|
25
|
+
readonly reviewer_codex: "momus";
|
|
26
|
+
readonly reviewer_claude: "oracle";
|
|
27
|
+
readonly synthesizer: "sisyphus";
|
|
28
|
+
};
|
|
19
29
|
export declare const DEFAULT_STAGE_FILES: {
|
|
20
30
|
readonly plan: "plan.md";
|
|
21
31
|
readonly "plan-review": "plan-review.md";
|
package/dist/constants.js
CHANGED
|
@@ -41,6 +41,16 @@ export const DEFAULT_ROLE_MODELS = {
|
|
|
41
41
|
reviewer_claude: "anthropic/claude-opus-4-6",
|
|
42
42
|
synthesizer: "openai/gpt-5.4",
|
|
43
43
|
};
|
|
44
|
+
export const DEFAULT_ROLE_AGENTS = {
|
|
45
|
+
planner: "prometheus",
|
|
46
|
+
plan_reviewer: "metis",
|
|
47
|
+
implementer: "atlas",
|
|
48
|
+
consultant_primary: "oracle",
|
|
49
|
+
consultant_secondary: "librarian",
|
|
50
|
+
reviewer_codex: "momus",
|
|
51
|
+
reviewer_claude: "oracle",
|
|
52
|
+
synthesizer: "sisyphus",
|
|
53
|
+
};
|
|
44
54
|
export const DEFAULT_STAGE_FILES = {
|
|
45
55
|
plan: "plan.md",
|
|
46
56
|
"plan-review": "plan-review.md",
|
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { AKANE_ROLE_IDS, AKANE_STAGE_IDS, DEFAULT_ROLE_MODELS, DEFAULT_STAG
|
|
|
2
2
|
export type AkaneStageId = (typeof AKANE_STAGE_IDS)[number];
|
|
3
3
|
export type AkaneRoleId = (typeof AKANE_ROLE_IDS)[number];
|
|
4
4
|
export type AkaneRoles = Record<AkaneRoleId, string>;
|
|
5
|
+
export type AkaneRoleAgents = Record<AkaneRoleId, string>;
|
|
5
6
|
export type AkaneStageFiles = Record<AkaneStageId, string>;
|
|
6
7
|
export interface AkaneConfig {
|
|
7
8
|
version: number;
|
|
@@ -15,7 +16,9 @@ export interface AkaneConfig {
|
|
|
15
16
|
};
|
|
16
17
|
workflow: {
|
|
17
18
|
stageOrder: AkaneStageId[];
|
|
19
|
+
preferAgents: boolean;
|
|
18
20
|
};
|
|
21
|
+
roleAgents: AkaneRoleAgents;
|
|
19
22
|
roles: AkaneRoles;
|
|
20
23
|
}
|
|
21
24
|
export interface LoadedAkaneConfig {
|
|
@@ -28,6 +31,7 @@ export interface AkaneStageState {
|
|
|
28
31
|
status: "pending" | "initialized" | "completed";
|
|
29
32
|
updatedAt: string | null;
|
|
30
33
|
role?: AkaneRoleId;
|
|
34
|
+
agent?: string;
|
|
31
35
|
model?: string;
|
|
32
36
|
sessionID?: string;
|
|
33
37
|
messageID?: string;
|
|
@@ -44,6 +48,7 @@ export interface AkaneState {
|
|
|
44
48
|
activeStage: AkaneStageId | null;
|
|
45
49
|
stageOrder: AkaneStageId[];
|
|
46
50
|
stages: Record<AkaneStageId, AkaneStageState>;
|
|
51
|
+
roleAgents: AkaneRoleAgents;
|
|
47
52
|
roles: AkaneRoles;
|
|
48
53
|
}
|
|
49
54
|
export type ArtifactWriteMode = "append" | "replace";
|
package/dist/workflow.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
|
-
import { AKANE_SERVICE_NAME, AKANE_TOOL_IDS, } from "./constants.js";
|
|
4
|
+
import { AKANE_SERVICE_NAME, AKANE_TOOL_IDS, DEFAULT_ROLE_AGENTS, } from "./constants.js";
|
|
5
5
|
import { ensureArtifactLayout, resolveProjectRoot, resolveStageArtifactPath, writeStageArtifact, } from "./artifacts.js";
|
|
6
6
|
const execFileAsync = promisify(execFile);
|
|
7
7
|
const STAGE_ROLE_MAP = {
|
|
@@ -12,13 +12,27 @@ const STAGE_ROLE_MAP = {
|
|
|
12
12
|
"review-claude": "reviewer_claude",
|
|
13
13
|
"final-synthesis": "synthesizer",
|
|
14
14
|
};
|
|
15
|
-
const
|
|
16
|
-
planner: "plan",
|
|
17
|
-
plan_reviewer:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
const DEFAULT_ROLE_AGENT_CANDIDATES = {
|
|
16
|
+
planner: ["prometheus", "Prometheus (Plan Builder)", "plan"],
|
|
17
|
+
plan_reviewer: [
|
|
18
|
+
"metis",
|
|
19
|
+
"Metis (Plan Consultant)",
|
|
20
|
+
"hephaestus",
|
|
21
|
+
"Hephaestus (Deep Agent)",
|
|
22
|
+
"general",
|
|
23
|
+
],
|
|
24
|
+
implementer: ["atlas", "Atlas (Plan Executor)", "build"],
|
|
25
|
+
consultant_primary: ["oracle", "general"],
|
|
26
|
+
consultant_secondary: ["librarian", "explore", "general"],
|
|
27
|
+
reviewer_codex: [
|
|
28
|
+
"momus",
|
|
29
|
+
"Momus (Plan Critic)",
|
|
30
|
+
"hephaestus",
|
|
31
|
+
"Hephaestus (Deep Agent)",
|
|
32
|
+
"general",
|
|
33
|
+
],
|
|
34
|
+
reviewer_claude: ["oracle", "general"],
|
|
35
|
+
synthesizer: ["sisyphus", "Sisyphus (Ultraworker)", "general"],
|
|
22
36
|
};
|
|
23
37
|
const IMPLEMENT_TIMEOUT_MS = 15 * 60 * 1000;
|
|
24
38
|
const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
@@ -39,6 +53,14 @@ function stageTitle(stage) {
|
|
|
39
53
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
40
54
|
.join(" ");
|
|
41
55
|
}
|
|
56
|
+
function normalizeAgentName(input) {
|
|
57
|
+
return input.trim().toLowerCase();
|
|
58
|
+
}
|
|
59
|
+
function agentNameAliases(input) {
|
|
60
|
+
const normalized = normalizeAgentName(input);
|
|
61
|
+
const base = normalized.replace(/\s*\([^)]*\)\s*$/, "").trim();
|
|
62
|
+
return Array.from(new Set([normalized, base].filter(Boolean)));
|
|
63
|
+
}
|
|
42
64
|
function parseModelRef(modelRef) {
|
|
43
65
|
const [providerID, ...rest] = modelRef.split("/");
|
|
44
66
|
const modelID = rest.join("/").trim();
|
|
@@ -86,23 +108,36 @@ function findLatestAssistantMessage(messages) {
|
|
|
86
108
|
function makeToolRestrictions(allowWorkspaceMutation) {
|
|
87
109
|
const restrictions = Object.fromEntries(AKANE_TOOL_IDS.map((toolID) => [toolID, false]));
|
|
88
110
|
if (!allowWorkspaceMutation) {
|
|
89
|
-
for (const toolID of ["bash", "edit", "patch", "write"
|
|
111
|
+
for (const toolID of ["bash", "edit", "patch", "write"]) {
|
|
90
112
|
restrictions[toolID] = false;
|
|
91
113
|
}
|
|
92
114
|
}
|
|
93
115
|
return restrictions;
|
|
94
116
|
}
|
|
95
|
-
async function resolveAgentName(client, directory, role) {
|
|
96
|
-
|
|
97
|
-
if (!preferred) {
|
|
117
|
+
async function resolveAgentName(client, directory, role, config) {
|
|
118
|
+
if (!config.workflow.preferAgents) {
|
|
98
119
|
return undefined;
|
|
99
120
|
}
|
|
121
|
+
const candidates = [
|
|
122
|
+
config.roleAgents[role],
|
|
123
|
+
...DEFAULT_ROLE_AGENT_CANDIDATES[role],
|
|
124
|
+
DEFAULT_ROLE_AGENTS[role],
|
|
125
|
+
]
|
|
126
|
+
.filter((candidate) => typeof candidate === "string" && candidate.trim().length > 0)
|
|
127
|
+
.filter((candidate, index, all) => all.findIndex((value) => normalizeAgentName(value) === normalizeAgentName(candidate)) === index);
|
|
100
128
|
try {
|
|
101
129
|
const result = await client.app.agents({
|
|
102
130
|
query: { directory },
|
|
103
131
|
});
|
|
104
132
|
const agents = requireResultData(result, "agent list");
|
|
105
|
-
|
|
133
|
+
for (const candidate of candidates) {
|
|
134
|
+
const candidateAliases = agentNameAliases(candidate);
|
|
135
|
+
const matched = agents.find((agent) => agentNameAliases(agent.name).some((alias) => candidateAliases.includes(alias)));
|
|
136
|
+
if (matched) {
|
|
137
|
+
return matched.name;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return undefined;
|
|
106
141
|
}
|
|
107
142
|
catch {
|
|
108
143
|
return undefined;
|
|
@@ -199,6 +234,7 @@ function renderStageDocument(input) {
|
|
|
199
234
|
"",
|
|
200
235
|
`- Service: ${AKANE_SERVICE_NAME}`,
|
|
201
236
|
`- Role: ${input.role}`,
|
|
237
|
+
...(input.agent ? [`- Agent: ${input.agent}`] : []),
|
|
202
238
|
`- Model: ${input.model}`,
|
|
203
239
|
`- Session ID: ${input.sessionID}`,
|
|
204
240
|
`- Message ID: ${input.messageID}`,
|
|
@@ -246,9 +282,9 @@ function buildArtifactBlock(title, content) {
|
|
|
246
282
|
}
|
|
247
283
|
async function runStageSession(input) {
|
|
248
284
|
const role = STAGE_ROLE_MAP[input.stage];
|
|
249
|
-
const
|
|
250
|
-
const modelRef = parseModelRef(
|
|
251
|
-
const agent = await resolveAgentName(input.pluginInput.client, input.projectRoot, role);
|
|
285
|
+
const configuredModel = input.configInfo.config.roles[role];
|
|
286
|
+
const modelRef = parseModelRef(configuredModel);
|
|
287
|
+
const agent = await resolveAgentName(input.pluginInput.client, input.projectRoot, role, input.configInfo.config);
|
|
252
288
|
const session = await createStageSession({
|
|
253
289
|
client: input.pluginInput.client,
|
|
254
290
|
parentSessionID: input.toolContext.sessionID,
|
|
@@ -261,7 +297,7 @@ async function runStageSession(input) {
|
|
|
261
297
|
signal: input.toolContext.abort,
|
|
262
298
|
body: {
|
|
263
299
|
...(agent ? { agent } : {}),
|
|
264
|
-
model: modelRef,
|
|
300
|
+
...(agent ? {} : { model: modelRef }),
|
|
265
301
|
system: input.system,
|
|
266
302
|
tools: makeToolRestrictions(input.allowWorkspaceMutation),
|
|
267
303
|
parts: [
|
|
@@ -293,7 +329,9 @@ async function runStageSession(input) {
|
|
|
293
329
|
return {
|
|
294
330
|
stage: input.stage,
|
|
295
331
|
role,
|
|
296
|
-
model
|
|
332
|
+
model: latestAssistant.info.providerID && latestAssistant.info.modelID
|
|
333
|
+
? `${latestAssistant.info.providerID}/${latestAssistant.info.modelID}`
|
|
334
|
+
: configuredModel,
|
|
297
335
|
agent,
|
|
298
336
|
sessionID: session.id,
|
|
299
337
|
messageID: latestAssistant.info.id,
|
|
@@ -381,6 +419,7 @@ export async function executePlanStage(input) {
|
|
|
381
419
|
const content = renderStageDocument({
|
|
382
420
|
stage: result.stage,
|
|
383
421
|
role: result.role,
|
|
422
|
+
agent: result.agent,
|
|
384
423
|
model: result.model,
|
|
385
424
|
sessionID: result.sessionID,
|
|
386
425
|
messageID: result.messageID,
|
|
@@ -396,6 +435,7 @@ export async function executePlanStage(input) {
|
|
|
396
435
|
mode: "replace",
|
|
397
436
|
details: {
|
|
398
437
|
role: result.role,
|
|
438
|
+
agent: result.agent,
|
|
399
439
|
model: result.model,
|
|
400
440
|
sessionID: result.sessionID,
|
|
401
441
|
messageID: result.messageID,
|
|
@@ -429,6 +469,7 @@ export async function executePlanReviewStage(input) {
|
|
|
429
469
|
const content = renderStageDocument({
|
|
430
470
|
stage: result.stage,
|
|
431
471
|
role: result.role,
|
|
472
|
+
agent: result.agent,
|
|
432
473
|
model: result.model,
|
|
433
474
|
sessionID: result.sessionID,
|
|
434
475
|
messageID: result.messageID,
|
|
@@ -444,6 +485,7 @@ export async function executePlanReviewStage(input) {
|
|
|
444
485
|
mode: "replace",
|
|
445
486
|
details: {
|
|
446
487
|
role: result.role,
|
|
488
|
+
agent: result.agent,
|
|
447
489
|
model: result.model,
|
|
448
490
|
sessionID: result.sessionID,
|
|
449
491
|
messageID: result.messageID,
|
|
@@ -500,6 +542,7 @@ export async function executeImplementStage(input) {
|
|
|
500
542
|
const content = renderStageDocument({
|
|
501
543
|
stage: result.stage,
|
|
502
544
|
role: result.role,
|
|
545
|
+
agent: result.agent,
|
|
503
546
|
model: result.model,
|
|
504
547
|
sessionID: result.sessionID,
|
|
505
548
|
messageID: result.messageID,
|
|
@@ -530,6 +573,7 @@ export async function executeImplementStage(input) {
|
|
|
530
573
|
mode: "replace",
|
|
531
574
|
details: {
|
|
532
575
|
role: result.role,
|
|
576
|
+
agent: result.agent,
|
|
533
577
|
model: result.model,
|
|
534
578
|
sessionID: result.sessionID,
|
|
535
579
|
messageID: result.messageID,
|
|
@@ -577,6 +621,7 @@ async function executeReviewerStage(input) {
|
|
|
577
621
|
const content = renderStageDocument({
|
|
578
622
|
stage: result.stage,
|
|
579
623
|
role: result.role,
|
|
624
|
+
agent: result.agent,
|
|
580
625
|
model: result.model,
|
|
581
626
|
sessionID: result.sessionID,
|
|
582
627
|
messageID: result.messageID,
|
|
@@ -592,6 +637,7 @@ async function executeReviewerStage(input) {
|
|
|
592
637
|
mode: "replace",
|
|
593
638
|
details: {
|
|
594
639
|
role: result.role,
|
|
640
|
+
agent: result.agent,
|
|
595
641
|
model: result.model,
|
|
596
642
|
sessionID: result.sessionID,
|
|
597
643
|
messageID: result.messageID,
|
|
@@ -655,6 +701,7 @@ export async function executeSynthesizeStage(input) {
|
|
|
655
701
|
const content = renderStageDocument({
|
|
656
702
|
stage: result.stage,
|
|
657
703
|
role: result.role,
|
|
704
|
+
agent: result.agent,
|
|
658
705
|
model: result.model,
|
|
659
706
|
sessionID: result.sessionID,
|
|
660
707
|
messageID: result.messageID,
|
|
@@ -670,6 +717,7 @@ export async function executeSynthesizeStage(input) {
|
|
|
670
717
|
mode: "replace",
|
|
671
718
|
details: {
|
|
672
719
|
role: result.role,
|
|
720
|
+
agent: result.agent,
|
|
673
721
|
model: result.model,
|
|
674
722
|
sessionID: result.sessionID,
|
|
675
723
|
messageID: result.messageID,
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"workflow": {
|
|
19
|
+
"preferAgents": false,
|
|
19
20
|
"stageOrder": [
|
|
20
21
|
"plan",
|
|
21
22
|
"plan-review",
|
|
@@ -25,6 +26,16 @@
|
|
|
25
26
|
"final-synthesis"
|
|
26
27
|
]
|
|
27
28
|
},
|
|
29
|
+
"roleAgents": {
|
|
30
|
+
"planner": "prometheus",
|
|
31
|
+
"plan_reviewer": "metis",
|
|
32
|
+
"implementer": "atlas",
|
|
33
|
+
"consultant_primary": "oracle",
|
|
34
|
+
"consultant_secondary": "librarian",
|
|
35
|
+
"reviewer_codex": "momus",
|
|
36
|
+
"reviewer_claude": "oracle",
|
|
37
|
+
"synthesizer": "sisyphus"
|
|
38
|
+
},
|
|
28
39
|
"roles": {
|
|
29
40
|
"planner": "anthropic/claude-opus-4-6",
|
|
30
41
|
"plan_reviewer": "openai/gpt-5.4",
|