feat: Implement context detection and onboarding tools for DevClaw
- Add context-guard.ts to detect interaction context (via-agent, direct, group) and generate guardrails. - Introduce onboarding.ts for conversational onboarding context templates and workspace file checks. - Enhance setup.ts to support new agent creation with channel binding and migration of existing bindings. - Create analyze-channel-bindings.ts to analyze channel availability and detect binding conflicts. - Implement context-test.ts for debugging context detection. - Develop devclaw_onboard.ts for explicit onboarding tool that guides users through setup. - Update devclaw_setup.ts to include channel binding and migration support in setup process. - Modify project-register.ts to enforce project registration from group context and auto-populate group ID. - Enhance queue-status.ts to provide context-aware status checks and recommendations. - Update task tools (task-complete, task-create, task-pickup) to clarify group ID usage for Telegram/WhatsApp.
This commit is contained in:
122
lib/onboarding.ts
Normal file
122
lib/onboarding.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* onboarding.ts — Conversational onboarding context templates.
|
||||
*
|
||||
* Provides context templates for the devclaw_onboard tool.
|
||||
*/
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { ALL_TIERS, DEFAULT_MODELS, type Tier } from "./tiers.js";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Detection
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export function isPluginConfigured(
|
||||
pluginConfig?: Record<string, unknown>,
|
||||
): boolean {
|
||||
const models = (pluginConfig as { models?: Record<string, string> })?.models;
|
||||
return !!models && Object.keys(models).length > 0;
|
||||
}
|
||||
|
||||
export async function hasWorkspaceFiles(
|
||||
workspaceDir?: string,
|
||||
): Promise<boolean> {
|
||||
if (!workspaceDir) return false;
|
||||
try {
|
||||
const content = await fs.readFile(
|
||||
path.join(workspaceDir, "AGENTS.md"),
|
||||
"utf-8",
|
||||
);
|
||||
return content.includes("DevClaw") && content.includes("task_pickup");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Context templates
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function buildModelTable(pluginConfig?: Record<string, unknown>): string {
|
||||
const models =
|
||||
(pluginConfig as { models?: Record<string, string> })?.models ?? {};
|
||||
return ALL_TIERS.map(
|
||||
(t) =>
|
||||
` - **${t}**: ${models[t] || DEFAULT_MODELS[t as Tier]} (default: ${DEFAULT_MODELS[t as Tier]})`,
|
||||
).join("\n");
|
||||
}
|
||||
|
||||
export function buildReconfigContext(
|
||||
pluginConfig?: Record<string, unknown>,
|
||||
): string {
|
||||
const modelTable = buildModelTable(pluginConfig);
|
||||
return `# DevClaw Reconfiguration
|
||||
|
||||
The user wants to reconfigure DevClaw. Current model configuration:
|
||||
|
||||
${modelTable}
|
||||
|
||||
## What can be changed
|
||||
1. **Model tiers** — call \`devclaw_setup\` with a \`models\` object containing only the tiers to change
|
||||
2. **Workspace files** — \`devclaw_setup\` re-writes AGENTS.md, HEARTBEAT.md (backs up existing files)
|
||||
3. **Register new projects** — use \`project_register\`
|
||||
|
||||
Ask what they want to change, then call the appropriate tool.
|
||||
\`devclaw_setup\` is safe to re-run — it backs up existing files before overwriting.
|
||||
`;
|
||||
}
|
||||
|
||||
export function buildOnboardToolContext(): string {
|
||||
return `# DevClaw Onboarding
|
||||
|
||||
## What is DevClaw?
|
||||
DevClaw turns each Telegram group into an autonomous development team:
|
||||
- An **orchestrator** that manages backlogs and delegates work
|
||||
- **DEV workers** (junior/medior/senior tiers) that write code in isolated sessions
|
||||
- **QA workers** that review code and run tests
|
||||
- Atomic tools for label transitions, session dispatch, state management, and audit logging
|
||||
|
||||
## Setup Steps
|
||||
|
||||
**Step 1: Agent Selection**
|
||||
Ask: "Do you want to configure DevClaw for the current agent, or create a new dedicated agent?"
|
||||
- Current agent → no \`newAgentName\` needed
|
||||
- New agent → ask for:
|
||||
1. Agent name
|
||||
2. **Channel binding**: "Which channel should this agent listen to? (telegram/whatsapp/none)"
|
||||
- If telegram/whatsapp selected:
|
||||
a) Call \`analyze_channel_bindings\` to check for conflicts
|
||||
b) If channel not configured/enabled → warn and recommend skipping binding for now
|
||||
c) If channel-wide binding exists on another agent → ask: "Migrate binding from {agentName}?"
|
||||
d) Collect migration decision
|
||||
- If none selected, user can add bindings manually later via openclaw.json
|
||||
|
||||
**Step 2: Model Configuration**
|
||||
Show the default tier-to-model mapping and ask if they want to customize:
|
||||
|
||||
| Tier | Default Model | Purpose |
|
||||
|------|---------------|---------|
|
||||
| junior | anthropic/claude-haiku-4-5 | Typos, single-file fixes |
|
||||
| medior | anthropic/claude-sonnet-4-5 | Features, bug fixes |
|
||||
| senior | anthropic/claude-opus-4-5 | Architecture, refactoring |
|
||||
| qa | anthropic/claude-sonnet-4-5 | Code review, testing |
|
||||
|
||||
If the defaults are fine, proceed. If customizing, ask which tiers to change.
|
||||
|
||||
**Step 3: Run Setup**
|
||||
Call \`devclaw_setup\` with the collected answers:
|
||||
- Current agent: \`devclaw_setup({})\` or \`devclaw_setup({ models: { ... } })\`
|
||||
- New agent: \`devclaw_setup({ newAgentName: "<name>", channelBinding: "telegram"|"whatsapp"|null, migrateFrom: "<agentId>"|null, models: { ... } })\`
|
||||
- \`migrateFrom\`: Include if user wants to migrate an existing channel-wide binding
|
||||
|
||||
**Step 4: Optional Project Registration**
|
||||
After setup, ask: "Would you like to register a project now?"
|
||||
If yes, collect: project name, repo path, Telegram group ID, group name, base branch.
|
||||
Then call \`project_register\`.
|
||||
|
||||
## Guidelines
|
||||
- Be conversational and friendly. Ask one question at a time.
|
||||
- Show defaults so the user can accept them quickly.
|
||||
- After setup, summarize what was configured (including channel binding if applicable).
|
||||
`;
|
||||
}
|
||||
Reference in New Issue
Block a user