AG2B

useAg2bTool

Build a Tool.

function useAg2bTool<P extends z.ZodObject, R>(
  config: ToolConfig<P, R>,
  deps?: unknown[]
): Tool<P, R>

Reactivity rules

Always-freshhandler, 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 mountdescription, 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.

On this page