examples/workflow-dsl.mjs
Rama master · réplica de lectura del repositorio original.
#!/usr/bin/env node
import { GraphRuntime, InMemoryCheckpointStore, workflow } from '../dist/index.js';
import { z } from 'zod';
function formatEvent(event) {
switch (event.type) {
case 'run_start':
return `run_start ${event.runId}`;
case 'node_start':
return `node_start ${event.nodeId}`;
case 'node_end':
return `node_end ${event.nodeId}`;
case 'edge_transition':
return `edge_transition ${event.sourceId} -> ${event.targetId} (${event.edgeType})`;
case 'checkpoint_saved':
return `checkpoint_saved ${event.nodeId}`;
case 'run_end':
return 'run_end';
default:
return event.type;
}
}
const onboarding = workflow('user-onboarding')
.input(
z.object({
email: z.string().email(),
name: z.string(),
desiredPlan: z.enum(['free', 'pro']),
}),
)
.returns(
z.object({
userId: z.string().optional(),
plan: z.enum(['free', 'pro']).optional(),
summary: z.string().optional(),
}),
)
.step('validate-email', { tool: 'email_validator' })
.branch(
(state) => state.input.desiredPlan,
{
pro: { tool: 'activate_pro_plan' },
free: { tool: 'create_free_account' },
},
)
.parallel(
[
{ tool: 'send_welcome_email' },
{ tool: 'notify_crm' },
],
{
strategy: 'all',
merge: { 'scratch.completedTasks': 'concat' },
},
)
.then('summarize', {
gmi: { instructions: 'Summarize the onboarding result for the caller.' },
})
.compile();
const runtime = new GraphRuntime({
checkpointStore: new InMemoryCheckpointStore(),
nodeExecutor: {
async execute(node, state) {
const config = node.executorConfig;
switch (config.type) {
case 'tool': {
switch (config.toolName) {
case 'email_validator':
return {
success: true,
output: { valid: true },
scratchUpdate: { completedTasks: ['validated email'] },
};
case 'activate_pro_plan':
return {
success: true,
output: { activated: true },
artifactsUpdate: { userId: 'usr_pro_001', plan: 'pro' },
};
case 'create_free_account':
return {
success: true,
output: { created: true },
artifactsUpdate: { userId: 'usr_free_001', plan: 'free' },
};
case 'send_welcome_email':
return {
success: true,
output: 'queued welcome email',
scratchUpdate: { completedTasks: ['queued welcome email'] },
};
case 'notify_crm':
return {
success: true,
output: 'updated CRM',
scratchUpdate: { completedTasks: ['updated CRM'] },
};
default:
return { success: true, output: `handled tool ${config.toolName}` };
}
}
case 'router':
return {
success: true,
output: config.condition.type === 'function'
? config.condition.fn(state)
: state.input.desiredPlan,
};
case 'gmi':
return {
success: true,
output: 'summary ready',
artifactsUpdate: {
...state.artifacts,
summary: [
`Created a ${state.artifacts.plan} account for ${state.input.name}.`,
`Completed tasks: ${(state.scratch.completedTasks ?? []).join(', ')}.`,
].join(' '),
},
};
default:
return { success: true, output: `noop:${node.id}` };
}
},
},
});
async function main() {
console.log('=== workflow() DSL ===');
console.log('Compiled nodes:', onboarding.toIR().nodes.map((node) => node.id).join(' -> '));
let finalOutput;
for await (const event of runtime.stream(onboarding.toIR(), {
email: 'johnn@example.com',
name: 'John',
desiredPlan: 'pro',
})) {
console.log(formatEvent(event));
if (event.type === 'run_end') {
finalOutput = event.finalOutput;
}
}
console.log('\nFinal artifacts:');
console.dir(finalOutput, { depth: null });
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});