refactor: add defaultAdapter + typed role union, adapters becomes Partial

- Each workflow factory takes defaultAdapter: AgentFn + adapters?: Partial<Record<RoleUnion, AgentFn>>
- index.ts only overrides roles that differ from default (planner/coder use cursor, rest fallback)
- Cleaner call sites, type-safe role names

Refs #15
This commit is contained in:
小橘 2026-04-29 12:38:21 +00:00
parent 1683e41b05
commit eaddd88109
6 changed files with 36 additions and 33 deletions

View File

@ -9,8 +9,11 @@ import { createPlannerRole } from "./roles/planner.js";
import { createReviewerRole } from "./roles/reviewer.js";
import { createTesterRole } from "./roles/tester.js";
type DevelopSenseRole = 'planner' | 'coder' | 'reviewer' | 'tester' | 'committer';
export type CreateDevelopSenseDeps = {
adapters: Record<string, AgentFn>;
defaultAdapter: AgentFn;
adapters?: Partial<Record<DevelopSenseRole, AgentFn>>;
extract: LlmExtractorConfig;
cwd: string;
};
@ -20,12 +23,13 @@ export function createDevelopSenseWorkflow({
extract,
cwd,
}: CreateDevelopSenseDeps): WorkflowDefinition<SenseMeta> {
const a = (role: DevelopSenseRole) => adapters?.[role] ?? defaultAdapter;
const roles = {
planner: createPlannerRole(adapters.planner, extract),
coder: createCoderRole(adapters.coder, extract),
reviewer: createReviewerRole(adapters.reviewer, extract, cwd),
tester: createTesterRole(adapters.tester, extract, cwd),
committer: createWorkspaceCommitterRole(adapters.committer, {
planner: createPlannerRole(a('planner'), extract),
coder: createCoderRole(a('coder'), extract),
reviewer: createReviewerRole(a('reviewer'), extract, cwd),
tester: createTesterRole(a('tester'), extract, cwd),
committer: createWorkspaceCommitterRole(a('committer'), {
extract,
nerveRoot: cwd,
workflowName: "develop-sense",

View File

@ -16,6 +16,7 @@ if (!apiKey || !baseUrl) {
const CURSOR_TIMEOUT_MS = 300_000;
const workflow = createDevelopSenseWorkflow({
defaultAdapter: hermesAdapter,
adapters: {
planner: createCursorAdapter({
type: "cursor",
@ -24,9 +25,6 @@ const workflow = createDevelopSenseWorkflow({
timeout: CURSOR_TIMEOUT_MS,
}),
coder: cursorAdapter,
reviewer: hermesAdapter,
tester: hermesAdapter,
committer: hermesAdapter,
},
extract: { provider: { apiKey, baseUrl, model } },
cwd: NERVE_ROOT,

View File

@ -9,8 +9,11 @@ import { createPlannerRole } from "./roles/planner.js";
import { createReviewerRole } from "./roles/reviewer.js";
import { createTesterRole } from "./roles/tester.js";
type DevelopWorkflowRole = 'planner' | 'coder' | 'reviewer' | 'tester' | 'committer';
export type CreateDevelopWorkflowDeps = {
adapters: Record<string, AgentFn>;
defaultAdapter: AgentFn;
adapters?: Partial<Record<DevelopWorkflowRole, AgentFn>>;
extract: LlmExtractorConfig;
nerveRoot: string;
};
@ -20,12 +23,13 @@ export function createDevelopWorkflowWorkflow({
extract,
nerveRoot,
}: CreateDevelopWorkflowDeps): WorkflowDefinition<WorkflowMeta> {
const a = (role: DevelopWorkflowRole) => adapters?.[role] ?? defaultAdapter;
const roles = {
planner: createPlannerRole(adapters.planner, extract),
coder: createCoderRole(adapters.coder, extract),
reviewer: createReviewerRole(adapters.reviewer, extract, nerveRoot),
tester: createTesterRole(adapters.tester, extract, nerveRoot),
committer: createWorkspaceCommitterRole(adapters.committer, {
planner: createPlannerRole(a('planner'), extract),
coder: createCoderRole(a('coder'), extract),
reviewer: createReviewerRole(a('reviewer'), extract, nerveRoot),
tester: createTesterRole(a('tester'), extract, nerveRoot),
committer: createWorkspaceCommitterRole(a('committer'), {
extract,
nerveRoot,
workflowName: "develop-workflow",

View File

@ -17,6 +17,7 @@ if (!apiKey || !baseUrl) {
const CURSOR_TIMEOUT_MS = 300_000;
const workflow = createDevelopWorkflowWorkflow({
defaultAdapter: hermesAdapter,
adapters: {
planner: createCursorAdapter({
type: "cursor",
@ -25,9 +26,6 @@ const workflow = createDevelopWorkflowWorkflow({
timeout: CURSOR_TIMEOUT_MS,
}),
coder: cursorAdapter,
reviewer: hermesAdapter,
tester: hermesAdapter,
committer: hermesAdapter,
},
extract: { provider: { apiKey, baseUrl, model } },
nerveRoot: NERVE_ROOT,

View File

@ -12,8 +12,11 @@ import { createReadIssueRole } from "./roles/read-issue/index.js";
import { createReviewRole } from "./roles/review/index.js";
import { createTestRole } from "./roles/test/index.js";
type SolveIssueRole = 'read-issue' | 'prepare' | 'plan' | 'implement' | 'committer' | 'review' | 'test' | 'publish';
export type CreateSolveIssueDeps = {
adapters: Record<string, AgentFn>;
defaultAdapter: AgentFn;
adapters?: Partial<Record<SolveIssueRole, AgentFn>>;
nerveRoot: string;
extract: LlmExtractorConfig;
};
@ -23,17 +26,18 @@ export function createSolveIssueWorkflow({
nerveRoot,
extract,
}: CreateSolveIssueDeps): WorkflowDefinition<WorkflowMeta> {
const a = (role: SolveIssueRole) => adapters?.[role] ?? defaultAdapter;
return {
name: "solve-issue",
roles: {
"read-issue": createReadIssueRole(adapters["read-issue"], extract),
prepare: createPrepareRole(adapters.prepare, extract),
plan: createPlanRole(adapters.plan, { extract, nerveRoot }),
implement: createImplementRole(adapters.implement, { extract, nerveRoot }),
committer: createCommitterRole(adapters.committer, { extract, nerveRoot }),
review: createReviewRole(adapters.review, extract, nerveRoot),
test: createTestRole(adapters.test, extract),
publish: createPublishRole(adapters.publish, { extract, nerveRoot }),
"read-issue": createReadIssueRole(a("read-issue"), extract),
prepare: createPrepareRole(a("prepare"), extract),
plan: createPlanRole(a("plan"), { extract, nerveRoot }),
implement: createImplementRole(a("implement"), { extract, nerveRoot }),
committer: createCommitterRole(a("committer"), { extract, nerveRoot }),
review: createReviewRole(a("review"), extract, nerveRoot),
test: createTestRole(a("test"), extract),
publish: createPublishRole(a("publish"), { extract, nerveRoot }),
},
moderator,
};

View File

@ -16,9 +16,8 @@ if (provider === null) {
const CURSOR_TIMEOUT_MS = 300_000;
const workflow = createSolveIssueWorkflow({
defaultAdapter: hermesAdapter,
adapters: {
"read-issue": hermesAdapter,
prepare: hermesAdapter,
plan: createCursorAdapter({
type: "cursor",
mode: "ask",
@ -30,10 +29,6 @@ const workflow = createSolveIssueWorkflow({
model: "auto",
timeout: CURSOR_TIMEOUT_MS,
}),
committer: hermesAdapter,
review: hermesAdapter,
test: hermesAdapter,
publish: hermesAdapter,
},
nerveRoot: NERVE_ROOT,
extract: { provider },