Complete Agent Pipeline System with Claude Code & OpenClaw Integration
- Added Claude Code integration with full context compaction support - Added OpenClaw integration with deterministic pipeline support - Implemented parallel agent execution (4 projects x 3 roles pattern) - Added workspace isolation with permissions and quotas - Implemented Lobster-compatible YAML workflow parser - Added persistent memory store for cross-session context - Created comprehensive README with hero section This project was 100% autonomously built by Z.AI GLM-5
This commit is contained in:
232
agent-system/agents/task-agent.ts
Normal file
232
agent-system/agents/task-agent.ts
Normal file
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* Task Agent Module
|
||||
*
|
||||
* Specialized agent for executing structured tasks with
|
||||
* planning, execution, and verification phases.
|
||||
*/
|
||||
|
||||
import { BaseAgent, AgentConfig, AgentResponse, AgentTool } from './base-agent';
|
||||
|
||||
export interface TaskStep {
|
||||
id: string;
|
||||
description: string;
|
||||
status: 'pending' | 'running' | 'completed' | 'failed';
|
||||
result?: unknown;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface TaskPlan {
|
||||
steps: TaskStep[];
|
||||
estimatedComplexity: 'low' | 'medium' | 'high';
|
||||
dependencies: Map<string, string[]>;
|
||||
}
|
||||
|
||||
export interface TaskResult {
|
||||
success: boolean;
|
||||
steps: TaskStep[];
|
||||
output: unknown;
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* TaskAgent - Agent specialized for structured task execution
|
||||
*/
|
||||
export class TaskAgent extends BaseAgent {
|
||||
private currentPlan: TaskPlan | null = null;
|
||||
private taskHistory: TaskResult[] = [];
|
||||
|
||||
constructor(config: AgentConfig) {
|
||||
super(config);
|
||||
|
||||
// Add default tools for task agents
|
||||
this.addTool({
|
||||
name: 'plan',
|
||||
description: 'Create a plan for a complex task',
|
||||
execute: async (params) => {
|
||||
const task = params as { description: string };
|
||||
return this.createPlan(task.description);
|
||||
}
|
||||
});
|
||||
|
||||
this.addTool({
|
||||
name: 'execute_step',
|
||||
description: 'Execute a single step of the plan',
|
||||
execute: async (params) => {
|
||||
const step = params as { stepId: string };
|
||||
return this.executeStep(step.stepId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a task with planning
|
||||
*/
|
||||
async act(input: string, context?: string): Promise<AgentResponse> {
|
||||
// First, create a plan
|
||||
this.currentPlan = await this.createPlan(input);
|
||||
|
||||
// Execute the plan
|
||||
const result = await this.executePlan();
|
||||
|
||||
this.taskHistory.push(result);
|
||||
|
||||
return {
|
||||
content: result.success
|
||||
? `Task completed successfully.\n${JSON.stringify(result.output, null, 2)}`
|
||||
: `Task failed. Errors: ${result.errors.join(', ')}`,
|
||||
tokens: { prompt: 0, completion: 0, total: 0 },
|
||||
metadata: {
|
||||
plan: this.currentPlan,
|
||||
result
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a plan for a task
|
||||
*/
|
||||
private async createPlan(taskDescription: string): Promise<TaskPlan> {
|
||||
const planningPrompt = `Break down the following task into steps. For each step, provide a brief description.
|
||||
|
||||
Task: ${taskDescription}
|
||||
|
||||
Respond in JSON format:
|
||||
{
|
||||
"steps": [
|
||||
{ "id": "step1", "description": "First step description" },
|
||||
{ "id": "step2", "description": "Second step description" }
|
||||
],
|
||||
"complexity": "low|medium|high",
|
||||
"dependencies": {
|
||||
"step2": ["step1"]
|
||||
}
|
||||
}`;
|
||||
|
||||
const response = await this.process(planningPrompt);
|
||||
|
||||
try {
|
||||
// Extract JSON from response
|
||||
const jsonMatch = response.content.match(/\{[\s\S]*\}/);
|
||||
if (jsonMatch) {
|
||||
const plan = JSON.parse(jsonMatch[0]);
|
||||
return {
|
||||
steps: plan.steps.map((s: TaskStep) => ({ ...s, status: 'pending' as const })),
|
||||
estimatedComplexity: plan.complexity || 'medium',
|
||||
dependencies: new Map(Object.entries(plan.dependencies || {}))
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
// Fall back to simple plan
|
||||
}
|
||||
|
||||
// Default simple plan
|
||||
return {
|
||||
steps: [{ id: 'step1', description: taskDescription, status: 'pending' }],
|
||||
estimatedComplexity: 'low',
|
||||
dependencies: new Map()
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the current plan
|
||||
*/
|
||||
private async executePlan(): Promise<TaskResult> {
|
||||
if (!this.currentPlan) {
|
||||
return {
|
||||
success: false,
|
||||
steps: [],
|
||||
output: null,
|
||||
errors: ['No plan available']
|
||||
};
|
||||
}
|
||||
|
||||
const errors: string[] = [];
|
||||
const completedSteps = new Set<string>();
|
||||
|
||||
// Execute steps in order, respecting dependencies
|
||||
for (const step of this.currentPlan.steps) {
|
||||
// Check dependencies
|
||||
const deps = this.currentPlan.dependencies.get(step.id) || [];
|
||||
const depsMet = deps.every(depId => completedSteps.has(depId));
|
||||
|
||||
if (!depsMet) {
|
||||
step.status = 'failed';
|
||||
step.error = 'Dependencies not met';
|
||||
errors.push(`Step ${step.id}: Dependencies not met`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Execute step
|
||||
step.status = 'running';
|
||||
try {
|
||||
const result = await this.executeStep(step.id);
|
||||
step.status = 'completed';
|
||||
step.result = result;
|
||||
completedSteps.add(step.id);
|
||||
} catch (error) {
|
||||
step.status = 'failed';
|
||||
step.error = String(error);
|
||||
errors.push(`Step ${step.id}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
const success = errors.length === 0;
|
||||
const finalStep = this.currentPlan.steps[this.currentPlan.steps.length - 1];
|
||||
|
||||
return {
|
||||
success,
|
||||
steps: this.currentPlan.steps,
|
||||
output: finalStep.result,
|
||||
errors
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a single step
|
||||
*/
|
||||
private async executeStep(stepId: string): Promise<unknown> {
|
||||
if (!this.currentPlan) throw new Error('No plan available');
|
||||
|
||||
const step = this.currentPlan.steps.find(s => s.id === stepId);
|
||||
if (!step) throw new Error(`Step ${stepId} not found`);
|
||||
|
||||
const response = await this.process(
|
||||
`Execute the following step and provide the result:\n\n${step.description}`
|
||||
);
|
||||
|
||||
return response.content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get task history
|
||||
*/
|
||||
getTaskHistory(): TaskResult[] {
|
||||
return [...this.taskHistory];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current plan
|
||||
*/
|
||||
getCurrentPlan(): TaskPlan | null {
|
||||
return this.currentPlan;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a task agent
|
||||
*/
|
||||
export function createTaskAgent(
|
||||
name: string,
|
||||
systemPrompt: string,
|
||||
options?: {
|
||||
description?: string;
|
||||
tools?: AgentTool[];
|
||||
}
|
||||
): TaskAgent {
|
||||
return new TaskAgent({
|
||||
name,
|
||||
systemPrompt,
|
||||
description: options?.description || `Task Agent: ${name}`,
|
||||
tools: options?.tools
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user