execute method
Future<AiRunResult>
execute({
- required AiAgent agent,
- required AiRunContext context,
- required AiPlan plan,
- required AiToolRegistry toolRegistry,
- required AiToolPolicy toolPolicy,
override
Implementation
@override
Future<AiRunResult> execute({
required AiAgent agent,
required AiRunContext context,
required AiPlan plan,
required AiToolRegistry toolRegistry,
required AiToolPolicy toolPolicy,
}) async {
try {
context.run.status = AiRunStatus.running;
await context.addEvent('run.started', payload: {
'agent': agent.name,
'plan': plan.toMap(),
});
for (final step in plan.steps) {
await context.addEvent('step.started', payload: step.toMap());
if (step.toolName != null && step.toolName!.isNotEmpty) {
context.run.status = AiRunStatus.waitingForTool;
final tool = toolRegistry.tool(step.toolName!);
if (tool == null) {
throw StateError('Unknown AI tool: ${step.toolName}');
}
final invocation = AiToolInvocation(
name: step.toolName!,
runId: context.run.id,
userId: context.userId,
tenantId: context.tenantId,
arguments: step.arguments,
enabledByDefault: tool.enabledByDefault,
requiredCapabilities: tool.requiredCapabilities,
);
final allowed = await toolPolicy.canExecute(invocation);
if (!allowed) {
throw StateError('Tool execution forbidden for ${step.toolName}');
}
final result = await tool.execute(
AiToolContext(
runId: context.run.id,
userId: context.userId,
tenantId: context.tenantId,
state: context.state,
arguments: step.arguments,
context: context.requestContext,
metadata: context.metadata,
artifacts: context.artifacts,
),
);
context.state[step.id] = result;
context.run.status = AiRunStatus.running;
await context.addEvent('step.tool.completed', payload: {
'stepId': step.id,
'tool': step.toolName,
'result': result,
});
} else {
context.state[step.id] = step.arguments;
await context.addEvent('step.completed', payload: {
'stepId': step.id,
'result': step.arguments,
});
}
}
final output = await agent.synthesize(context);
context.run.status = AiRunStatus.completed;
context.run.output = output;
await context.addEvent('run.completed', payload: {
'output': output,
});
return AiRunResult(
run: context.run,
output: output,
);
} catch (error) {
context.run.status = AiRunStatus.failed;
await context.addEvent('run.failed', payload: {
'error': error.toString(),
});
rethrow;
}
}