openai-swarmjs
Version:
Agentic framework inspired from OpenAI's swarm framework for TS, JS
211 lines (210 loc) • 7.99 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetaDagExecutionAgent = exports.DagExecutionAgent = exports.DagCreationAgent = void 0;
const BaseAgent_1 = require("../../core/BaseAgent");
const prompts_1 = require("./prompts");
// Meta DAG for standardized execution flow
const META_DAG = [
{
id: 'createDag',
type: 'function',
functionName: 'createDagFunction',
functionArgs: {
goal: '{goal}' // This will be replaced with the actual goal in constructor
},
dependencies: []
},
{
id: 'executeDag',
type: 'function',
functionName: 'executeSubdagFunction',
functionArgs: {
nodeId: '$createDag' // Uses the output from createDag as the nodeId
},
dependencies: ['createDag']
}
];
class DagCreationAgent extends BaseAgent_1.BaseAgent {
constructor(goal, functions) {
const executeDAGFunction = async (dag) => {
console.log('execute_dag function called by LLM with plan');
this.dagCreated = true;
this.createdDag = dag;
return new DagExecutionAgent(goal, functions, dag).getAgent();
};
Object.defineProperty(executeDAGFunction, 'description', {
value: prompts_1.EXECUTE_DAG_DESCRIPTION
});
const functionMap = new Map();
functions.forEach(f => {
const sanitizedName = BaseAgent_1.BaseAgent.sanitizeFunctionName(f.name);
functionMap.set(sanitizedName, f);
});
const creationInstructions = prompts_1.DAG_CREATION_INSTRUCTIONS
.replace('{goal}', goal)
.replace('{functionList}', '\n' + Array.from(functionMap.keys()).join('\n'))
.replace('{functionDescriptions}', BaseAgent_1.BaseAgent.buildFunctionDescriptions(functions));
const agent = {
name: 'Planner',
model: 'gpt-4o',
instructions: creationInstructions,
functions: [executeDAGFunction],
toolChoice: null,
parallelToolCalls: true,
};
super(goal, functions, agent);
this.dagCreated = false;
this.lastResponse = '';
this.createdDag = null;
}
updateLastResponse(response) {
this.lastResponse = response;
console.log('Stored LLM response:', response);
}
shouldTransferManually() {
return !this.dagCreated;
}
async nextAgent() {
if (this.dagCreated) {
console.log('No manual transfer needed, execute_dag was called');
return null;
}
console.log('Performing manual transfer using LLM response as plan');
if (!this.lastResponse) {
console.warn('No response available for manual transfer');
return null;
}
try {
const dag = JSON.parse(this.lastResponse);
return new DagExecutionAgent(this.goal, this.functions, dag).getAgent();
}
catch (e) {
console.error('Failed to parse DAG from response:', e);
return null;
}
}
getCreatedDag() {
return this.createdDag;
}
}
exports.DagCreationAgent = DagCreationAgent;
class DagExecutionAgent extends BaseAgent_1.BaseAgent {
constructor(goal, functions, dagSteps) {
const createDagFunction = async (args) => {
const creationAgent = new DagCreationAgent(args.goal ?? args, functions);
return {
value: 'DAG creation agent initialized',
agent: creationAgent.getAgent(),
contextVariables: {}
};
};
Object.defineProperty(createDagFunction, 'description', {
value: prompts_1.CREATE_DAG_DESCRIPTION
});
// Bind the execute subdag function to this instance
const executeSubdagFunction = async (args) => {
const task = this.findTask(args.nodeId);
if (!task || task.type !== 'subdag' || !task.subdag) {
throw new Error(`Invalid subdag task: ${args.nodeId}`);
}
this.currentSubdag = args.nodeId;
const executionAgent = new DagExecutionAgent(task.subdag.goal, functions, task.subdag.steps);
return {
value: `Executing subdag for ${args.nodeId}`,
agent: executionAgent.getAgent(),
contextVariables: {}
};
};
Object.defineProperty(executeSubdagFunction, 'description', {
value: prompts_1.EXECUTE_SUBDAG_DESCRIPTION
});
const enhancedFunctions = [
...functions,
createDagFunction,
executeSubdagFunction
];
const executionInstructions = prompts_1.DAG_EXECUTION_WITH_PLAN_INSTRUCTIONS
.replace('{goal}', goal)
.replace('{dagSteps}', JSON.stringify(dagSteps, null, 2))
.replace('{functionList}', '\n' + enhancedFunctions.map(f => f.name).join('\n'));
console.log('Execution instructions:', executionInstructions);
console.log('functions:', enhancedFunctions);
const agent = {
name: 'Executor',
model: 'gpt-4o',
instructions: executionInstructions,
functions: enhancedFunctions,
toolChoice: null,
parallelToolCalls: true,
};
super(goal, functions, agent);
this.completedTasks = new Set();
this.currentSubdag = null;
this.executionResults = new Map();
this.dagSteps = dagSteps;
}
findTask(taskId) {
return this.dagSteps.find(task => task.id === taskId) || null;
}
getExecutableTasks() {
return this.dagSteps
.filter(task => !this.completedTasks.has(task.id) &&
task.dependencies.every(depId => this.completedTasks.has(depId)))
.map(task => task.id);
}
resolveArguments(args) {
const resolved = {};
for (const [key, value] of Object.entries(args)) {
if (typeof value === 'string' && value.startsWith('$')) {
const taskId = value.slice(1);
if (!this.executionResults.has(taskId)) {
throw new Error(`Result not found for task: ${taskId}`);
}
resolved[key] = this.executionResults.get(taskId);
}
else {
resolved[key] = value;
}
}
return resolved;
}
markTaskCompleted(taskId, result) {
this.completedTasks.add(taskId);
this.executionResults.set(taskId, result);
if (this.currentSubdag === taskId) {
this.currentSubdag = null;
}
}
shouldTransferManually() {
return this.getExecutableTasks().length > 0 && !this.currentSubdag;
}
async nextAgent() {
if (this.isCompleted()) {
return null;
}
const executableTasks = this.getExecutableTasks();
if (executableTasks.length === 0) {
return null;
}
const nextTaskId = executableTasks[0];
const task = this.findTask(nextTaskId);
if (task.type === 'subdag' && task.subdag) {
this.currentSubdag = task.id;
return new DagCreationAgent(task.subdag.goal, this.functions).getAgent();
}
return this.getAgent();
}
isCompleted() {
return this.completedTasks.size === this.dagSteps.length;
}
}
exports.DagExecutionAgent = DagExecutionAgent;
class MetaDagExecutionAgent extends DagExecutionAgent {
constructor(goal, functions) {
const metaInstructions = prompts_1.META_DAG_INSTRUCTIONS.replace('{goal}', goal);
super(goal, functions, META_DAG);
// Override instructions with meta-DAG specific ones
this.agent.instructions = metaInstructions;
}
}
exports.MetaDagExecutionAgent = MetaDagExecutionAgent;