Adds the Architect role for design/architecture investigations with persistent sessions and structured design proposals. ## New Features - **Architect role** with opus (complex) and sonnet (standard) levels - **design_task tool** — Creates To Design issues and dispatches architect - **Workflow states:** To Design → Designing → Planning - **Completion rules:** architect:done → Planning, architect:blocked → Refining - **Auto-level selection** based on complexity keywords ## Files Changed (22 files, 546 additions) ### New Files - lib/tools/design-task.ts — design_task tool implementation - lib/tools/design-task.test.ts — 16 tests for architect functionality ### Core Changes - lib/tiers.ts — ARCHITECT_LEVELS, WorkerRole type, models, emoji - lib/workflow.ts — toDesign/designing states, completion rules - lib/projects.ts — architect WorkerState on Project type - lib/dispatch.ts — architect role support in dispatch pipeline - lib/services/pipeline.ts — architect completion rules - lib/model-selector.ts — architect level selection heuristic ### Integration - index.ts — Register design_task tool, architect config schema - lib/notify.ts — architect role in notifications - lib/bootstrap-hook.ts — architect session key parsing - lib/services/tick.ts — architect in queue processing - lib/services/heartbeat.ts — architect in health checks - lib/tools/health.ts — architect in health scans - lib/tools/status.ts — architect in status dashboard - lib/tools/work-start.ts — architect role option - lib/tools/work-finish.ts — architect validation - lib/tools/project-register.ts — architect labels + role scaffolding - lib/templates.ts — architect instructions + AGENTS.md updates - lib/setup/workspace.ts — architect role file scaffolding - lib/setup/smart-model-selector.ts — architect in model assignment - lib/setup/llm-model-selector.ts — architect in LLM prompt
106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
/**
|
|
* smart-model-selector.ts — LLM-powered model selection for DevClaw roles.
|
|
*
|
|
* Uses an LLM to intelligently analyze and assign models to DevClaw roles.
|
|
*/
|
|
|
|
export type ModelAssignment = {
|
|
dev: {
|
|
junior: string;
|
|
medior: string;
|
|
senior: string;
|
|
};
|
|
qa: {
|
|
reviewer: string;
|
|
tester: string;
|
|
};
|
|
architect: {
|
|
opus: string;
|
|
sonnet: string;
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Intelligently assign available models to DevClaw roles using an LLM.
|
|
*
|
|
* Strategy:
|
|
* 1. If 0 models → return null (setup should be blocked)
|
|
* 2. If 1 model → assign it to all roles
|
|
* 3. If multiple models → use LLM to intelligently assign
|
|
*/
|
|
export async function assignModels(
|
|
availableModels: Array<{ model: string; provider: string; authenticated: boolean }>,
|
|
sessionKey?: string,
|
|
): Promise<ModelAssignment | null> {
|
|
// Filter to only authenticated models
|
|
const authenticated = availableModels.filter((m) => m.authenticated);
|
|
|
|
if (authenticated.length === 0) {
|
|
return null; // No models available - setup should be blocked
|
|
}
|
|
|
|
// If only one model, use it for everything
|
|
if (authenticated.length === 1) {
|
|
const model = authenticated[0].model;
|
|
return {
|
|
dev: { junior: model, medior: model, senior: model },
|
|
qa: { reviewer: model, tester: model },
|
|
architect: { opus: model, sonnet: model },
|
|
};
|
|
}
|
|
|
|
// Multiple models: use LLM-based selection
|
|
const { selectModelsWithLLM } = await import("./llm-model-selector.js");
|
|
const llmResult = await selectModelsWithLLM(authenticated, sessionKey);
|
|
|
|
if (!llmResult) {
|
|
throw new Error("LLM-based model selection failed. Please try again or configure models manually.");
|
|
}
|
|
|
|
return llmResult;
|
|
}
|
|
|
|
/**
|
|
* Format model assignment as a readable table.
|
|
*/
|
|
export function formatAssignment(assignment: ModelAssignment): string {
|
|
const lines = [
|
|
"| Role | Level | Model |",
|
|
"|------|----------|--------------------------|",
|
|
`| DEV | senior | ${assignment.dev.senior.padEnd(24)} |`,
|
|
`| DEV | medior | ${assignment.dev.medior.padEnd(24)} |`,
|
|
`| DEV | junior | ${assignment.dev.junior.padEnd(24)} |`,
|
|
`| QA | reviewer | ${assignment.qa.reviewer.padEnd(24)} |`,
|
|
`| QA | tester | ${assignment.qa.tester.padEnd(24)} |`,
|
|
`| ARCH | opus | ${assignment.architect.opus.padEnd(24)} |`,
|
|
`| ARCH | sonnet | ${assignment.architect.sonnet.padEnd(24)} |`,
|
|
];
|
|
return lines.join("\n");
|
|
}
|
|
|
|
/**
|
|
* Generate setup instructions when no models are available.
|
|
*/
|
|
export function generateSetupInstructions(): string {
|
|
return `❌ No authenticated models found. DevClaw needs at least one model to work.
|
|
|
|
To configure model authentication:
|
|
|
|
**For Anthropic Claude:**
|
|
export ANTHROPIC_API_KEY=your-api-key
|
|
# or: openclaw auth add --provider anthropic
|
|
|
|
**For OpenAI:**
|
|
export OPENAI_API_KEY=your-api-key
|
|
# or: openclaw auth add --provider openai
|
|
|
|
**For other providers:**
|
|
openclaw auth add --provider <provider>
|
|
|
|
**Verify authentication:**
|
|
openclaw models list
|
|
(Look for "Auth: yes" in the output)
|
|
|
|
Once you see authenticated models, re-run: onboard`;
|
|
}
|