feat: implement Phase 4 - Multi-Agent Swarm + Skill Discovery
Phase 4a: Agent Swarm Collaboration Framework (agent-swarm.ts) - AgentSwarm class with configurable coordinator + specialist agents - Three collaboration modes: Sequential (chain), Parallel (concurrent), Debate (multi-round) - Auto task decomposition based on specialist capabilities - Debate consensus detection with keyword similarity heuristic - Rule-based result aggregation with structured markdown output - Specialist management (add/update/remove) and config updates - History persistence to localStorage (last 25 tasks) - Memory integration: saves task completion as lesson memories Phase 4b: Skill Discovery Engine (skill-discovery.ts) - SkillDiscoveryEngine with 12 built-in skill definitions from skills/ directory - Multi-signal search: name, description, triggers, capabilities, category matching - Conversation-based skill recommendation via topic extraction (CN + EN patterns) - Memory-augmented confidence scoring for suggestions - Skill registration, install status toggle, category filtering - localStorage persistence for skill index and suggestion cache Phase 4c: chatStore Integration - dispatchSwarmTask(description, style): creates and executes swarm task, adds result as message - searchSkills(query): exposes skill search to UI layer Tests: 317 passing across 13 test files (43 new for swarm + skills) - AgentSwarm: createTask, sequential/parallel/debate execution, history, specialist mgmt - SkillDiscovery: search, suggest, register, persist, categories Refs: ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md updated - all 4 phases complete
This commit is contained in:
@@ -6,6 +6,8 @@ import { getAgentIdentityManager } from '../lib/agent-identity';
|
||||
import { getMemoryExtractor } from '../lib/memory-extractor';
|
||||
import { getContextCompactor } from '../lib/context-compactor';
|
||||
import { getReflectionEngine } from '../lib/reflection-engine';
|
||||
import { getAgentSwarm } from '../lib/agent-swarm';
|
||||
import { getSkillDiscovery } from '../lib/skill-discovery';
|
||||
|
||||
export interface MessageFile {
|
||||
name: string;
|
||||
@@ -91,6 +93,8 @@ interface ChatState {
|
||||
newConversation: () => void;
|
||||
switchConversation: (id: string) => void;
|
||||
deleteConversation: (id: string) => void;
|
||||
dispatchSwarmTask: (description: string, style?: 'sequential' | 'parallel' | 'debate') => Promise<string | null>;
|
||||
searchSkills: (query: string) => { results: Array<{ id: string; name: string; description: string }>; totalAvailable: number };
|
||||
}
|
||||
|
||||
function generateConvId(): string {
|
||||
@@ -489,6 +493,48 @@ export const useChatStore = create<ChatState>()(
|
||||
}
|
||||
},
|
||||
|
||||
dispatchSwarmTask: async (description: string, style?: 'sequential' | 'parallel' | 'debate') => {
|
||||
try {
|
||||
const swarm = getAgentSwarm();
|
||||
const task = swarm.createTask(description, {
|
||||
communicationStyle: style || 'parallel',
|
||||
});
|
||||
|
||||
// Set up executor that uses gateway client
|
||||
swarm.setExecutor(async (agentId: string, prompt: string, context?: string) => {
|
||||
const client = getGatewayClient();
|
||||
const fullPrompt = context ? `${context}\n\n${prompt}` : prompt;
|
||||
const result = await client.chat(fullPrompt, { agentId: agentId.startsWith('clone_') ? undefined : agentId });
|
||||
return result?.response || '(无响应)';
|
||||
});
|
||||
|
||||
const result = await swarm.execute(task);
|
||||
|
||||
// Add swarm result as assistant message
|
||||
const swarmMsg: Message = {
|
||||
id: `swarm_${Date.now()}`,
|
||||
role: 'assistant',
|
||||
content: result.summary || '协作任务完成',
|
||||
timestamp: new Date(),
|
||||
};
|
||||
get().addMessage(swarmMsg);
|
||||
|
||||
return result.task.id;
|
||||
} catch (err) {
|
||||
console.warn('[Chat] Swarm dispatch failed:', err);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
searchSkills: (query: string) => {
|
||||
const discovery = getSkillDiscovery();
|
||||
const result = discovery.searchSkills(query);
|
||||
return {
|
||||
results: result.results.map(s => ({ id: s.id, name: s.name, description: s.description })),
|
||||
totalAvailable: result.totalAvailable,
|
||||
};
|
||||
},
|
||||
|
||||
initStreamListener: () => {
|
||||
const client = getGatewayClient();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user