Files
devclaw-gitea/lib/setup/smart-model-selector.ts
Lauren ten Hoor 57c78f3656 feat: Implement Architect role & design_task tool (#189)
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
2026-02-14 17:08:17 +08:00

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`;
}