mirror of
https://github.com/hanzoai/agents.git
synced 2026-10-30 18:48:36 +00:00
Transforms hanzoai/agents from a marketplace config repo into a full agent orchestration platform by merging the AgentField infrastructure: - Go control plane (K8s-like agent orchestration, service mesh, DAG workflows) - Python SDK (FastAPI-based agent framework, LiteLLM, memory, DID/VC) - TypeScript SDK (@hanzo/agents - Vercel AI SDK, MCP, workflows) - Go SDK (idiomatic agent builder + client) - React 19 embedded dashboard (XyFlow DAGs, Recharts, Radix UI) - Docker/K8s/Helm deployment configs - Examples: hello world, deep research, RAG, simulation, benchmarks - Functional test suite across Python/Go/TypeScript All references rebranded: AgentField β Hanzo Agents - Module: github.com/hanzoai/agents/control-plane - Python: hanzo_agents - TypeScript: @hanzo/agents - Go: github.com/hanzoai/agents/sdk/go - Env vars: HANZO_AGENTS_* - Config: hanzo-agents.yaml Previous marketplace configs moved to config/ directory.
161 lines
5.4 KiB
TypeScript
161 lines
5.4 KiB
TypeScript
import { AgentRouter } from '@hanzo-agents/sdk';
|
|
import {
|
|
EntityDecisionSchema,
|
|
EntityProfileSchema,
|
|
FactorGraphSchema,
|
|
RunSimulationInputSchema,
|
|
ScenarioAnalysisSchema,
|
|
SimulationResultSchema,
|
|
type EntityDecision,
|
|
type EntityProfile,
|
|
type FactorGraph,
|
|
type RunSimulationInput,
|
|
type ScenarioAnalysis,
|
|
type SimulationResult
|
|
} from '../schemas.js';
|
|
|
|
export const simulationRouter = new AgentRouter({ prefix: 'simulation' });
|
|
|
|
const scenarioTargets = {
|
|
decompose: 'scenario_decomposeScenario',
|
|
factorGraph: 'scenario_generateFactorGraph'
|
|
} as const;
|
|
|
|
const entityTargets = {
|
|
batch: 'entity_generateEntityBatch'
|
|
} as const;
|
|
|
|
const decisionTargets = {
|
|
batch: 'decision_simulateBatchDecisions'
|
|
} as const;
|
|
|
|
const aggregationTargets = {
|
|
aggregate: 'aggregation_aggregateAndAnalyze'
|
|
} as const;
|
|
|
|
simulationRouter.reasoner<RunSimulationInput, SimulationResult>(
|
|
'runSimulation',
|
|
async (ctx) => {
|
|
const scenario = ctx.input.scenario;
|
|
const populationSize = ctx.input.populationSize;
|
|
const context = ctx.input.context ?? [];
|
|
const parallelBatchSize = ctx.input.parallelBatchSize ?? 20;
|
|
const explorationRatio = ctx.input.explorationRatio ?? 0.1;
|
|
|
|
const assertArray = (value: any, label: string) => {
|
|
if (!Array.isArray(value)) {
|
|
throw new Error(`${label} is not an array: ${JSON.stringify(value)}`);
|
|
}
|
|
};
|
|
|
|
const logAndThrow = (stage: string, err: unknown) => {
|
|
console.error(`β ${stage} failed`, err);
|
|
throw err;
|
|
};
|
|
|
|
console.log(`π Starting simulation: ${populationSize} entities`);
|
|
|
|
console.log('\nπ Phase 1: Analyzing scenario...');
|
|
const scenarioAnalysis = (await ctx
|
|
.call(scenarioTargets.decompose, {
|
|
scenario,
|
|
context
|
|
})
|
|
.catch((err) => logAndThrow('Scenario analysis', err))) as ScenarioAnalysis;
|
|
if (!scenarioAnalysis?.decisionOptions) {
|
|
logAndThrow('Scenario analysis output validation', new Error('decisionOptions missing'));
|
|
}
|
|
console.log(` Entity type: ${scenarioAnalysis.entityType}`);
|
|
console.log(` Decision type: ${scenarioAnalysis.decisionType}`);
|
|
console.log(` Options: ${scenarioAnalysis.decisionOptions.join(', ')}`);
|
|
|
|
console.log('\nπΈοΈ Phase 2: Building factor graph...');
|
|
const factorGraph = (await ctx
|
|
.call(scenarioTargets.factorGraph, {
|
|
scenario,
|
|
scenarioAnalysis,
|
|
context
|
|
})
|
|
.catch((err) => logAndThrow('Factor graph', err))) as FactorGraph;
|
|
if (!factorGraph?.attributes) {
|
|
logAndThrow('Factor graph output validation', new Error('attributes missing'));
|
|
}
|
|
console.log(` Tracking ${Object.keys(factorGraph.attributes).length} attributes`);
|
|
|
|
console.log(`\nπ₯ Phase 3: Generating ${populationSize} entities...`);
|
|
const entitiesPerBatch = 20;
|
|
const allEntities: EntityProfile[] = [];
|
|
const numEntityBatches = Math.ceil(populationSize / entitiesPerBatch);
|
|
for (let batchNum = 0; batchNum < numEntityBatches; batchNum++) {
|
|
const startId = batchNum * entitiesPerBatch;
|
|
const batchSize = Math.min(entitiesPerBatch, populationSize - startId);
|
|
console.log(` Batch ${batchNum + 1}/${numEntityBatches}: Generating ${batchSize} entities...`);
|
|
const batch = (await ctx
|
|
.call(entityTargets.batch, {
|
|
startId,
|
|
batchSize,
|
|
scenarioAnalysis,
|
|
factorGraph,
|
|
explorationRatio
|
|
})
|
|
.catch((err) => logAndThrow(`Entity batch ${batchNum + 1}`, err))) as EntityProfile[];
|
|
assertArray(batch, `entity batch ${batchNum + 1}`);
|
|
allEntities.push(...batch);
|
|
}
|
|
console.log(` β
Generated ${allEntities.length} entities`);
|
|
|
|
console.log('\nπ― Phase 4: Simulating decisions...');
|
|
const allDecisions = (await ctx
|
|
.call(decisionTargets.batch, {
|
|
entities: allEntities,
|
|
scenario,
|
|
scenarioAnalysis,
|
|
context,
|
|
parallelBatchSize
|
|
})
|
|
.catch((err) => logAndThrow('Decision batch', err))) as EntityDecision[];
|
|
assertArray(allDecisions, 'decision batch');
|
|
console.log(` β
Simulated ${allDecisions.length} decisions`);
|
|
|
|
console.log('\nπ Phase 5: Aggregating results and generating insights...');
|
|
const insights = (await ctx
|
|
.call(aggregationTargets.aggregate, {
|
|
scenario,
|
|
scenarioAnalysis,
|
|
factorGraph,
|
|
entities: allEntities,
|
|
decisions: allDecisions,
|
|
context
|
|
})
|
|
.catch((err) => logAndThrow('Aggregation', err))) as SimulationResult['insights'];
|
|
|
|
const insightsForLog =
|
|
insights && typeof insights === 'object'
|
|
? insights
|
|
: {
|
|
outcomeDistribution: {},
|
|
keyInsight: 'Fallback insight',
|
|
detailedAnalysis: 'Fallback analysis due to invalid model response.',
|
|
segmentPatterns: 'Fallback segment patterns.',
|
|
causalDrivers: 'Fallback causal drivers.'
|
|
};
|
|
console.log(`\nπ― KEY INSIGHT: ${insightsForLog.keyInsight}`);
|
|
console.log('\nπ OUTCOME DISTRIBUTION:');
|
|
Object.entries(insightsForLog.outcomeDistribution).forEach(([decision, pct]) => {
|
|
console.log(` ${decision}: ${(pct * 100).toFixed(1)}%`);
|
|
});
|
|
|
|
return {
|
|
scenario,
|
|
context,
|
|
populationSize,
|
|
scenarioAnalysis,
|
|
factorGraph,
|
|
entities: allEntities,
|
|
decisions: allDecisions,
|
|
insights: insightsForLog
|
|
};
|
|
},
|
|
{ inputSchema: RunSimulationInputSchema, outputSchema: SimulationResultSchema }
|
|
);
|