Files
Agentic-Compaction-and-Pipl…/delegation-system/core/context-handoff.ts
admin 8329636696 Add Delegation System with 3rd Party AI Tool Integration
NEW: Delegation System (v1.2.0)
- Request Classifier for fast request analysis (<50ms)
- Agent Pool Manager with auto-scaling (8 agent types)
- Delegation Engine with 4 strategies (full, parallel, hierarchical, hybrid)
- Progress Streamer for real-time updates
- Context Handoff Protocol for inter-agent communication
- Quality Gate with confidence thresholds and auto-escalation

NEW: 3rd Party Integration Adapters
- OpenClaw adapter with parallel execution support
- Claude Code CLI adapter with tool registration
- Generic adapter for custom integrations
- Standardized IntegrationAdapter interface

Agent Types Added:
- fast-responder (quick answers < 2s)
- explorer (code navigation)
- researcher (deep analysis)
- coder (implementation)
- reviewer (quality checks)
- planner (architecture)
- executor (commands)
- analyzer (debugging)

Tests: All 6 tests passing

This project was 100% autonomously built by Z.AI GLM-5
2026-03-04 10:06:17 +00:00

371 lines
10 KiB
TypeScript

/**
* Context Handoff Protocol
*
* Manages context transfer between agents for seamless delegation.
* Ensures proper serialization, validation, and cleanup of handoffs.
*/
import {
ContextHandoff,
HandoffResult,
ConversationTurn,
DelegationContext
} from '../core/types';
// ============================================================================
// Handoff Configuration
// ============================================================================
interface HandoffConfig {
defaultTimeout: number;
defaultTimeLimit: number;
maxHandoffs: number;
cleanupInterval: number;
handoffTTL: number;
}
const DEFAULT_CONFIG: HandoffConfig = {
defaultTimeout: 30000,
defaultTimeLimit: 60000,
maxHandoffs: 100,
cleanupInterval: 60000,
handoffTTL: 300000 // 5 minutes
};
// ============================================================================
// Context Handoff Manager Class
// ============================================================================
export class ContextHandoffManager {
private config: HandoffConfig;
private activeHandoffs: Map<string, ContextHandoff> = new Map();
private completedHandoffs: Map<string, HandoffResult> = new Map();
private cleanupTimer?: NodeJS.Timeout;
private handoffCounter: number = 0;
constructor(config: Partial<HandoffConfig> = {}) {
this.config = { ...DEFAULT_CONFIG, ...config };
this.startCleanupTimer();
}
// ============================================================================
// Handoff Creation
// ============================================================================
/**
* Create a new context handoff
*/
createHandoff(options: {
sourceAgent: string;
targetAgent: string;
request: any;
files?: Record<string, string>;
conversationHistory?: ConversationTurn[];
workspace?: string;
metadata?: Record<string, any>;
timeLimit?: number;
scope?: 'narrow' | 'medium' | 'broad';
qualityLevel?: 'fast' | 'balanced' | 'thorough';
callbackEndpoint?: string;
callbackTimeout?: number;
}): ContextHandoff {
const id = this.generateHandoffId();
const handoff: ContextHandoff = {
id,
sourceAgent: options.sourceAgent,
targetAgent: options.targetAgent,
request: options.request,
context: {
files: options.files || {},
conversationHistory: options.conversationHistory || [],
workspace: options.workspace || '',
metadata: options.metadata || {}
},
constraints: {
timeLimit: options.timeLimit || this.config.defaultTimeLimit,
scope: options.scope || 'medium',
qualityLevel: options.qualityLevel || 'balanced'
},
callback: {
endpoint: options.callbackEndpoint || '',
timeout: options.callbackTimeout || this.config.defaultTimeout,
retries: 3
},
createdAt: new Date(),
expiresAt: new Date(Date.now() + this.config.handoffTTL)
};
this.activeHandoffs.set(id, handoff);
this.handoffCounter++;
return handoff;
}
/**
* Create handoff from delegation context
*/
createFromDelegation(
delegationContext: DelegationContext,
sourceAgent: string,
targetAgent: string
): ContextHandoff {
return this.createHandoff({
sourceAgent,
targetAgent,
request: delegationContext.originalRequest,
metadata: {
requestId: delegationContext.requestId,
classification: delegationContext.classification,
strategy: delegationContext.delegationDecision.strategy
}
});
}
// ============================================================================
// Handoff Execution
// ============================================================================
/**
* Get a handoff by ID
*/
getHandoff(id: string): ContextHandoff | undefined {
return this.activeHandoffs.get(id);
}
/**
* Complete a handoff with result
*/
completeHandoff(
handoffId: string,
result: {
success: boolean;
output?: any;
error?: string;
processingTime: number;
}
): HandoffResult {
const handoff = this.activeHandoffs.get(handoffId);
const handoffResult: HandoffResult = {
handoffId,
success: result.success,
result: result.output,
error: result.error,
processingTime: result.processingTime
};
// Store result
this.completedHandoffs.set(handoffId, handoffResult);
// Remove from active
if (handoff) {
this.activeHandoffs.delete(handoffId);
// Execute callback if configured
if (handoff.callback.endpoint) {
this.executeCallback(handoff, handoffResult);
}
}
return handoffResult;
}
/**
* Cancel a handoff
*/
cancelHandoff(handoffId: string, reason: string): void {
const handoff = this.activeHandoffs.get(handoffId);
if (handoff) {
this.completeHandoff(handoffId, {
success: false,
error: `Cancelled: ${reason}`,
processingTime: 0
});
}
}
// ============================================================================
// Callback Execution
// ============================================================================
private async executeCallback(
handoff: ContextHandoff,
result: HandoffResult
): Promise<void> {
const { endpoint, timeout, retries } = handoff.callback;
for (let attempt = 0; attempt < retries; attempt++) {
try {
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
handoffId: handoff.id,
sourceAgent: handoff.sourceAgent,
targetAgent: handoff.targetAgent,
result
}),
signal: AbortSignal.timeout(timeout)
});
if (response.ok) {
return;
}
} catch (error) {
console.error(`Callback attempt ${attempt + 1} failed:`, error);
// Wait before retry
if (attempt < retries - 1) {
await this.sleep(1000 * (attempt + 1));
}
}
}
}
private sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
// ============================================================================
// Context Serialization
// ============================================================================
/**
* Serialize handoff for transmission
*/
serialize(handoff: ContextHandoff): string {
return JSON.stringify({
id: handoff.id,
sourceAgent: handoff.sourceAgent,
targetAgent: handoff.targetAgent,
request: handoff.request,
context: handoff.context,
constraints: handoff.constraints,
callback: handoff.callback,
createdAt: handoff.createdAt.toISOString(),
expiresAt: handoff.expiresAt.toISOString()
});
}
/**
* Deserialize handoff from transmission
*/
deserialize(data: string): ContextHandoff {
const parsed = JSON.parse(data);
return {
...parsed,
createdAt: new Date(parsed.createdAt),
expiresAt: new Date(parsed.expiresAt)
};
}
/**
* Validate handoff integrity
*/
validate(handoff: ContextHandoff): { valid: boolean; errors: string[] } {
const errors: string[] = [];
if (!handoff.id) errors.push('Missing handoff ID');
if (!handoff.sourceAgent) errors.push('Missing source agent');
if (!handoff.targetAgent) errors.push('Missing target agent');
if (!handoff.request) errors.push('Missing request');
if (handoff.constraints.timeLimit <= 0) {
errors.push('Invalid time limit');
}
if (handoff.expiresAt <= new Date()) {
errors.push('Handoff has expired');
}
return {
valid: errors.length === 0,
errors
};
}
// ============================================================================
// Cleanup
// ============================================================================
private startCleanupTimer(): void {
this.cleanupTimer = setInterval(() => {
this.cleanup();
}, this.config.cleanupInterval);
}
private cleanup(): void {
const now = new Date();
// Remove expired handoffs
for (const [id, handoff] of this.activeHandoffs) {
if (handoff.expiresAt <= now) {
this.cancelHandoff(id, 'Expired');
}
}
// Limit completed handoffs
if (this.completedHandoffs.size > this.config.maxHandoffs) {
const keys = Array.from(this.completedHandoffs.keys());
const toRemove = keys.slice(0, this.completedHandoffs.size - this.config.maxHandoffs);
toRemove.forEach(key => this.completedHandoffs.delete(key));
}
}
/**
* Stop cleanup timer and clear all
*/
shutdown(): void {
if (this.cleanupTimer) {
clearInterval(this.cleanupTimer);
}
this.activeHandoffs.clear();
this.completedHandoffs.clear();
}
// ============================================================================
// Statistics
// ============================================================================
getStats(): {
active: number;
completed: number;
totalCreated: number;
successRate: number;
averageProcessingTime: number;
} {
const completed = Array.from(this.completedHandoffs.values());
const successful = completed.filter(r => r.success);
return {
active: this.activeHandoffs.size,
completed: completed.length,
totalCreated: this.handoffCounter,
successRate: completed.length > 0 ? successful.length / completed.length : 0,
averageProcessingTime: completed.length > 0
? completed.reduce((sum, r) => sum + r.processingTime, 0) / completed.length
: 0
};
}
private generateHandoffId(): string {
return `handoff-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`;
}
}
// ============================================================================
// Factory Function
// ============================================================================
export function createContextHandoffManager(config?: Partial<HandoffConfig>): ContextHandoffManager {
return new ContextHandoffManager(config);
}
// ============================================================================
// Export
// ============================================================================
export default ContextHandoffManager;