registerTool method
Register tool lifecycle callbacks.
Implementation
void registerTool(ToolLifecycle lifecycle) {
if (lifecycle.onToolRegistered != null) {
_register(
HookRegistration(
id: 'lifecycle:tool:registered',
type: HookType.onToolRegistration,
priority: HookPriority.normal,
name: 'Tool Registered Lifecycle',
source: 'lifecycle',
asyncHandler: (context) async {
final event = ToolRegisteredEvent(
timestamp: context.timestamp,
sessionId: context.sessionId,
metadata: context.metadata,
toolName: context.metadata['toolName'] as String? ?? '',
source: context.metadata['source'] as String? ?? 'unknown',
);
await lifecycle.onToolRegistered!(event);
_emitEvent(event);
return const HookContinue();
},
),
);
}
if (lifecycle.onToolBeforeExecution != null) {
_register(
HookRegistration(
id: 'lifecycle:tool:before',
type: HookType.preToolExecution,
priority: HookPriority.normal,
name: 'Tool Before Execution Lifecycle',
source: 'lifecycle',
asyncHandler: (context) async {
if (context is! ToolHookContext) return const HookContinue();
final event = ToolBeforeExecutionEvent(
timestamp: context.timestamp,
sessionId: context.sessionId,
metadata: context.metadata,
toolName: context.toolName,
input: context.toolInput,
);
final modifiedInput = await lifecycle.onToolBeforeExecution!(event);
_emitEvent(event);
if (modifiedInput != null) {
return HookTransform(modifiedInput);
}
return const HookContinue();
},
),
);
}
if (lifecycle.onToolAfterExecution != null) {
_register(
HookRegistration(
id: 'lifecycle:tool:after',
type: HookType.postToolExecution,
priority: HookPriority.normal,
name: 'Tool After Execution Lifecycle',
source: 'lifecycle',
asyncHandler: (context) async {
if (context is! ToolHookContext) return const HookContinue();
final event = ToolAfterExecutionEvent(
timestamp: context.timestamp,
sessionId: context.sessionId,
metadata: context.metadata,
toolName: context.toolName,
input: context.toolInput,
output: context.toolOutput ?? '',
isError: context.toolIsError ?? false,
executionDuration: context.executionDuration ?? Duration.zero,
);
final modifiedOutput = await lifecycle.onToolAfterExecution!(event);
_emitEvent(event);
if (modifiedOutput != null) {
return HookTransform({'output': modifiedOutput});
}
return const HookContinue();
},
),
);
}
if (lifecycle.onToolError != null) {
_register(
HookRegistration(
id: 'lifecycle:tool:error',
type: HookType.onError,
priority: HookPriority.normal,
name: 'Tool Error Lifecycle',
source: 'lifecycle',
matcher: (context) =>
context is ErrorHookContext && context.source == 'tool',
asyncHandler: (context) async {
if (context is! ErrorHookContext) return const HookContinue();
final event = ToolErrorEvent(
timestamp: context.timestamp,
sessionId: context.sessionId,
metadata: context.metadata,
toolName: context.metadata['toolName'] as String? ?? '',
input:
context.metadata['toolInput'] as Map<String, dynamic>? ?? {},
error: context.error,
stackTrace: context.stackTrace,
);
final action = await lifecycle.onToolError!(event);
_emitEvent(event);
return switch (action) {
ToolRecoveryAction.propagate => const HookContinue(),
ToolRecoveryAction.retry => const HookRetry(Duration(seconds: 1)),
ToolRecoveryAction.retryWithModifiedInput => const HookRetry(
Duration(seconds: 1),
),
ToolRecoveryAction.suppress => const HookSkip('Error suppressed'),
ToolRecoveryAction.abortTurn => const HookAbort(
'Turn aborted due to tool error',
),
};
},
),
);
}
if (lifecycle.onToolTimeout != null) {
_register(
HookRegistration(
id: 'lifecycle:tool:timeout',
type: HookType.onError,
priority: HookPriority.normal,
name: 'Tool Timeout Lifecycle',
source: 'lifecycle',
matcher: (context) =>
context is ErrorHookContext &&
context.errorCategory == 'timeout' &&
context.source == 'tool',
asyncHandler: (context) async {
if (context is! ErrorHookContext) return const HookContinue();
final event = ToolTimeoutEvent(
timestamp: context.timestamp,
sessionId: context.sessionId,
metadata: context.metadata,
toolName: context.metadata['toolName'] as String? ?? '',
input:
context.metadata['toolInput'] as Map<String, dynamic>? ?? {},
timeoutDuration:
context.metadata['timeout'] as Duration? ??
const Duration(seconds: 30),
);
await lifecycle.onToolTimeout!(event);
_emitEvent(event);
return const HookContinue();
},
),
);
}
}