behemoth-cli
Version:
🌍 BEHEMOTH CLIv3.760.4 - Level 50+ POST-SINGULARITY Intelligence Trading AI
533 lines (483 loc) • 15.8 kB
text/typescript
/**
* Dynamic Tool Orchestration System
* Enables Claude-like multi-step reasoning and tool chaining
*/
interface OrchestrationStep {
id: string;
command: string;
condition?: string;
dependsOn?: string[];
timeout?: number;
retries?: number;
}
interface OrchestrationResult {
stepId: string;
command: string;
result: any;
success: boolean;
error?: string;
executionTime: number;
}
interface OrchestrationPlan {
id: string;
description: string;
steps: OrchestrationStep[];
estimatedTime: string;
createdAt: Date;
}
interface OrchestrationContext {
results: Map<string, OrchestrationResult>;
variables: Map<string, any>;
startTime: Date;
currentStep?: string;
}
export class DynamicOrchestrator {
private activePlans: Map<string, OrchestrationContext> = new Map();
private agent: any; // Will be injected by Agent class
constructor(agent?: any) {
this.agent = agent;
}
/**
* Create an orchestration plan from natural language input
*/
async createPlan(input: string): Promise<OrchestrationPlan | null> {
const planId = `plan_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
// Complex query patterns that require orchestration
const orchestrationPatterns = [
{
pattern: /(?:find|look.*?for|search.*?for).*?(?:long|opportunity|entry).*?(?:eth|ethereum|btc|bitcoin|sol|solana)/i,
createPlan: (input: string) => this.createTradingOpportunityPlan(input, planId)
},
{
pattern: /(?:portfolio|position.*?size|risk.*?assessment).*?(?:\$\d+|\d+.*?dollar|medium|high|low.*?risk)/i,
createPlan: (input: string) => this.createPortfolioAnalysisPlan(input, planId)
},
{
pattern: /(?:market.*?overview|full.*?analysis|complete.*?check|comprehensive.*?analysis)/i,
createPlan: (input: string) => this.createComprehensiveAnalysisPlan(input, planId)
},
{
pattern: /(?:compare|vs|versus|against).*?(?:eth|ethereum|btc|bitcoin|sol|solana)/i,
createPlan: (input: string) => this.createComparisonPlan(input, planId)
},
{
pattern: /(?:sentiment.*?analysis|market.*?mood|fear.*?greed).*?(?:multiple|all|several|various)/i,
createPlan: (input: string) => this.createSentimentAnalysisPlan(input, planId)
}
];
for (const pattern of orchestrationPatterns) {
if (pattern.pattern.test(input)) {
return await pattern.createPlan(input);
}
}
return null;
}
/**
* Execute an orchestration plan with state management
*/
async executePlan(plan: OrchestrationPlan, onStepComplete?: (result: OrchestrationResult) => void): Promise<OrchestrationResult[]> {
const context: OrchestrationContext = {
results: new Map(),
variables: new Map(),
startTime: new Date(),
currentStep: undefined
};
this.activePlans.set(plan.id, context);
const results: OrchestrationResult[] = [];
try {
for (const step of plan.steps) {
context.currentStep = step.id;
// Check dependencies
if (step.dependsOn && step.dependsOn.length > 0) {
const dependencyResults = step.dependsOn.map(depId => context.results.get(depId));
if (dependencyResults.some(result => !result || !result.success)) {
const result: OrchestrationResult = {
stepId: step.id,
command: step.command,
result: null,
success: false,
error: 'Dependency failed',
executionTime: 0
};
results.push(result);
context.results.set(step.id, result);
continue;
}
}
// Check conditions
if (step.condition && !this.evaluateCondition(step.condition, context)) {
const result: OrchestrationResult = {
stepId: step.id,
command: step.command,
result: null,
success: false,
error: 'Condition not met',
executionTime: 0
};
results.push(result);
context.results.set(step.id, result);
continue;
}
// Execute step with retries
const maxRetries = step.retries || 1;
let lastError: string | undefined;
let stepResult: OrchestrationResult | null = null;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const startTime = Date.now();
const commandResult = await this.executeCommand(step.command, context);
const executionTime = Date.now() - startTime;
stepResult = {
stepId: step.id,
command: step.command,
result: commandResult,
success: true,
executionTime
};
break;
} catch (error) {
lastError = error instanceof Error ? error.message : String(error);
if (attempt === maxRetries - 1) {
stepResult = {
stepId: step.id,
command: step.command,
result: null,
success: false,
error: lastError,
executionTime: 0
};
}
}
}
if (stepResult) {
results.push(stepResult);
context.results.set(step.id, stepResult);
// Extract variables from successful results
if (stepResult.success && stepResult.result) {
this.extractVariables(stepResult.result, context);
}
if (onStepComplete) {
onStepComplete(stepResult);
}
}
}
} finally {
this.activePlans.delete(plan.id);
}
return results;
}
/**
* Create trading opportunity analysis plan
*/
private createTradingOpportunityPlan(input: string, planId: string): OrchestrationPlan {
const symbol = this.extractSymbol(input);
return {
id: planId,
description: `Complete trading opportunity analysis for ${symbol}`,
estimatedTime: '45-60 seconds',
createdAt: new Date(),
steps: [
{
id: 'price_check',
command: `/mcp__behemoth__binance_spot_ticker --symbol=${symbol}`,
timeout: 10000
},
{
id: 'rsi_analysis',
command: `/mcp__behemoth__rsi_analysis --symbol=${symbol}`,
dependsOn: ['price_check'],
timeout: 15000
},
{
id: 'macd_analysis',
command: `/mcp__behemoth__macd_analysis --symbol=${symbol}`,
dependsOn: ['price_check'],
timeout: 15000
},
{
id: 'support_resistance',
command: `/mcp__behemoth__support_resistance --symbol=${symbol}`,
dependsOn: ['rsi_analysis', 'macd_analysis'],
timeout: 20000
},
{
id: 'sentiment_check',
command: `/mcp__behemoth__fear_greed_index --symbol=${symbol}`,
condition: 'rsi_bullish OR macd_bullish',
dependsOn: ['rsi_analysis', 'macd_analysis'],
timeout: 10000
}
]
};
}
/**
* Create portfolio analysis plan
*/
private createPortfolioAnalysisPlan(input: string, planId: string): OrchestrationPlan {
const symbol = this.extractSymbol(input);
const amount = this.extractAmount(input);
return {
id: planId,
description: `Portfolio risk analysis for ${amount} in ${symbol}`,
estimatedTime: '30-40 seconds',
createdAt: new Date(),
steps: [
{
id: 'current_price',
command: `/mcp__behemoth__binance_spot_ticker --symbol=${symbol}`,
timeout: 10000
},
{
id: 'volatility_check',
command: `/mcp__behemoth__volatility_analysis --symbol=${symbol}`,
dependsOn: ['current_price'],
timeout: 15000
},
{
id: 'risk_assessment',
command: `/mcp__behemoth__var_calculator --symbol=${symbol}`,
dependsOn: ['current_price', 'volatility_check'],
timeout: 15000
},
{
id: 'position_sizing',
command: `/mcp__behemoth__kelly_criterion_calculator --symbol=${symbol}`,
dependsOn: ['risk_assessment'],
timeout: 10000
}
]
};
}
/**
* Create comprehensive market analysis plan
*/
private createComprehensiveAnalysisPlan(input: string, planId: string): OrchestrationPlan {
const symbol = this.extractSymbol(input);
return {
id: planId,
description: `Comprehensive market analysis for ${symbol}`,
estimatedTime: '60-90 seconds',
createdAt: new Date(),
steps: [
{
id: 'system_health',
command: `/mcp__behemoth__system_health`,
timeout: 5000
},
{
id: 'price_data',
command: `/mcp__behemoth__get_all_futures_prices --symbol=${symbol}`,
timeout: 15000
},
{
id: 'technical_rsi',
command: `/mcp__behemoth__rsi_analysis --symbol=${symbol}`,
dependsOn: ['price_data'],
timeout: 15000
},
{
id: 'technical_macd',
command: `/mcp__behemoth__macd_analysis --symbol=${symbol}`,
dependsOn: ['price_data'],
timeout: 15000
},
{
id: 'technical_bollinger',
command: `/mcp__behemoth__bollinger_bands --symbol=${symbol}`,
dependsOn: ['price_data'],
timeout: 15000
},
{
id: 'market_sentiment',
command: `/mcp__behemoth__fear_greed_index --symbol=${symbol}`,
dependsOn: ['technical_rsi'],
timeout: 10000
},
{
id: 'funding_analysis',
command: `/mcp__behemoth__binance_funding_rate --symbol=${symbol}`,
dependsOn: ['price_data'],
timeout: 10000
},
{
id: 'cosmic_analysis',
command: `/mcp__behemoth__cosmic_analyst_signals --symbol=${symbol}`,
dependsOn: ['market_sentiment'],
timeout: 10000
}
]
};
}
/**
* Create comparison analysis plan
*/
private createComparisonPlan(input: string, planId: string): OrchestrationPlan {
const symbols = this.extractMultipleSymbols(input);
return {
id: planId,
description: `Comparative analysis between ${symbols.join(' vs ')}`,
estimatedTime: '40-50 seconds',
createdAt: new Date(),
steps: symbols.flatMap((symbol, index) => [
{
id: `price_${index}`,
command: `/mcp__behemoth__binance_spot_ticker --symbol=${symbol}`,
timeout: 10000
},
{
id: `rsi_${index}`,
command: `/mcp__behemoth__rsi_analysis --symbol=${symbol}`,
dependsOn: [`price_${index}`],
timeout: 15000
}
])
};
}
/**
* Create sentiment analysis plan
*/
private createSentimentAnalysisPlan(input: string, planId: string): OrchestrationPlan {
const symbol = this.extractSymbol(input);
return {
id: planId,
description: `Multi-source sentiment analysis for ${symbol}`,
estimatedTime: '25-35 seconds',
createdAt: new Date(),
steps: [
{
id: 'fear_greed',
command: `/mcp__behemoth__fear_greed_index --symbol=${symbol}`,
timeout: 10000
},
{
id: 'social_sentiment',
command: `/mcp__behemoth__social_volume --symbol=${symbol}`,
timeout: 10000
},
{
id: 'news_sentiment',
command: `/mcp__behemoth__news_sentiment --symbol=${symbol}`,
timeout: 15000
},
{
id: 'market_mood',
command: `/mcp__behemoth__market_mood --symbol=${symbol}`,
dependsOn: ['fear_greed', 'social_sentiment'],
timeout: 10000
}
]
};
}
/**
* Execute a single command within orchestration context
*/
private async executeCommand(command: string, context: OrchestrationContext): Promise<any> {
if (!this.agent) {
throw new Error('Agent not configured for orchestration');
}
// Parse command and extract tool name and arguments
const [toolName, ...argParts] = command.split(' ');
const cleanToolName = toolName.replace('/', '');
// Parse arguments
const args: any = {};
for (const argPart of argParts) {
if (argPart.includes('=')) {
const [key, value] = argPart.split('=');
args[key.replace('--', '')] = value;
}
}
// Execute through agent's tool system
return await this.agent.executeTool(cleanToolName, args);
}
/**
* Evaluate conditions for conditional execution
*/
private evaluateCondition(condition: string, context: OrchestrationContext): boolean {
// Simple condition evaluation - can be extended
if (condition === 'rsi_bullish OR macd_bullish') {
const rsiResult = context.results.get('rsi_analysis');
const macdResult = context.results.get('macd_analysis');
const rsiBullish = !!(rsiResult?.success && rsiResult.result?.signal === 'BUY');
const macdBullish = !!(macdResult?.success && macdResult.result?.signal_interpretation === 'BULLISH');
return rsiBullish || macdBullish;
}
return true; // Default to true for unknown conditions
}
/**
* Extract variables from step results for use in subsequent steps
*/
private extractVariables(result: any, context: OrchestrationContext): void {
if (result.price) {
context.variables.set('current_price', result.price);
}
if (result.symbol) {
context.variables.set('symbol', result.symbol);
}
if (result.signal) {
context.variables.set('signal', result.signal);
}
if (result.rsi) {
context.variables.set('rsi_value', result.rsi);
}
}
/**
* Helper method to extract symbol from natural language
*/
private extractSymbol(input: string): string {
const symbolMap: { [key: string]: string } = {
'bitcoin': 'BTCUSDT',
'btc': 'BTCUSDT',
'ethereum': 'ETHUSDT',
'eth': 'ETHUSDT',
'solana': 'SOLUSDT',
'sol': 'SOLUSDT'
};
const normalizedInput = input.toLowerCase();
for (const [key, value] of Object.entries(symbolMap)) {
if (normalizedInput.includes(key)) {
return value;
}
}
return 'BTCUSDT'; // default
}
/**
* Helper method to extract multiple symbols for comparison
*/
private extractMultipleSymbols(input: string): string[] {
const symbols: string[] = [];
const symbolMap: { [key: string]: string } = {
'bitcoin': 'BTCUSDT',
'btc': 'BTCUSDT',
'ethereum': 'ETHUSDT',
'eth': 'ETHUSDT',
'solana': 'SOLUSDT',
'sol': 'SOLUSDT'
};
const normalizedInput = input.toLowerCase();
for (const [key, value] of Object.entries(symbolMap)) {
if (normalizedInput.includes(key)) {
symbols.push(value);
}
}
return symbols.length > 0 ? symbols : ['BTCUSDT', 'ETHUSDT']; // default comparison
}
/**
* Helper method to extract amount from input
*/
private extractAmount(input: string): string {
const amountMatch = input.match(/\$?(\d+(?:,\d{3})*(?:\.\d+)?)/);
return amountMatch ? amountMatch[1].replace(',', '') : '1000';
}
/**
* Get current plan status
*/
getPlanStatus(planId: string): OrchestrationContext | null {
return this.activePlans.get(planId) || null;
}
/**
* Cancel a running plan
*/
cancelPlan(planId: string): boolean {
return this.activePlans.delete(planId);
}
}