useAg2bTool
Build a Tool.
function useAg2bTool<P extends z.ZodObject, R>(
config: ToolConfig<P, R>,
deps?: unknown[]
): Tool<P, R>Reactivity rules
Always-fresh — handler, enabled. The hook re-reads the latest closure on every invocation, so inline arrows can close over reactive state without remounting the tool.
Captured at mount — description, parameters. If either reads reactive state, list those values in deps so the tool remounts on change.
Usage
Building a tool
Pass a ToolConfig. The hook returns a stable Tool that you hand to a scope:
function PullRequestTools() {
const pr = usePullRequest();
const approve = useAg2bTool({
name: 'approvePR',
description: 'Approve the current pull request.',
parameters: z.object({ comment: z.string().optional() }),
handler: ({ comment }) => pr.approve(comment),
});
useAg2bScope({ name: 'pullRequest', tools: [approve] });
return null;
}Conditional availability
enabled gates the tool dynamically. Always-fresh along with handler — both see the latest store snapshot without listing reactive values in deps:
const approve = useAg2bTool({
name: 'approvePR',
description: 'Approve the current pull request.',
parameters: z.object({ comment: z.string().optional() }),
enabled: () => pr.status === 'open',
handler: ({ comment }) => pr.approve(comment),
});Reactive captured values
If description or parameters reads reactive state — a translated string, a Zod constraint pulled from props — list those values in deps:
const comment = useAg2bTool({
name: 'commentOnPR',
description: t('tool.commentOnPR.description'),
parameters: z.object({ body: z.string().max(maxLen) }),
handler: ({ body }) => pr.comment(body),
}, [t, maxLen]);Forget deps and the tool keeps serving the original description / parameters to the LLM even after the values change. handler and enabled stay current regardless.