useToolAnswer
For declarative forms, the earlier form, whose own action hides them: it answers the agent's submit and keeps the form in place until the agent has its answer.
For declarative forms, the earlier form, whose own action hides them: it answers the agent’s submit and keeps the form in place until the agent has its answer. Chrome cancels a tool call whose definition changes mid-flight, and unmounting or un-naming a declarative form changes it.
A tool from useWebTool does not need it: its execute simply returns the answer, and the hook keeps the tool registered until the call is answered.
Import
import { useToolAnswer } from "@webmcp-agents/react";
import type { ToolAnswer } from "@webmcp-agents/react";
Example
Applying a code hides the form, so it stays for a moment after the agent’s submit. answer takes the native event and the result as a promise.
import { useToolAnswer } from "@webmcp-agents/react";
import type { FormEvent } from "react";
// A declarative form (the earlier form). Applying a code hides the
// form, so it stays for a moment after the agent's submit.
export function ApplyPromoForm({ applied }: { applied: boolean }) {
const { answering, answer } = useToolAnswer();
if (applied && !answering) return null;
function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const code = new FormData(event.currentTarget).get("code");
answer(
event.nativeEvent as SubmitEvent,
Promise.resolve(`Applied ${String(code)}.`),
);
}
return (
<form
toolname="apply_promo"
tooldescription="Apply a promo code to the cart."
toolautosubmit=""
onSubmit={onSubmit}
>
<input
name="code"
required
toolparamdescription="The code, e.g. WELCOME10"
/>
<button type="submit">Apply</button>
</form>
);
}
Options
None. The hook takes no arguments.
Returns
A ToolAnswer:
| Name | Type | Description |
|---|---|---|
answering |
boolean |
True from an agent’s submit until 500 ms (RESPONSE_GRACE_MS) after its result settles. Keep the form rendered meanwhile. |
answer(event, result) |
(event: SubmitEvent, result: Promise<unknown>) => void |
Answers an agent-invoked submit: calls event.respondWith(result) and sets answering. Does nothing for a person’s submit (event.agentInvoked is falsy). |
Notes
- Pass the native event: in a React handler that is
e.nativeEvent as SubmitEvent.agentInvokedandrespondWithlive on it. - A rejected
resultalso endsansweringafter the grace, without leaving a second unhandled rejection behind. - A form that navigates away after answering should navigate after the grace too (
RESPONSE_GRACE_MS, exported by core). - Call
answersynchronously in the submit handler. The polyfill reads the response when the event’s dispatch returns, and answers"Form submitted."if none was given. useAnswerGraceis the same function under its old name. It is deprecated.
See also
- Tools with input, the way new code writes a form
- Declarative forms
- JSX attributes
useWebToolPolyfillModelContext(declarative forms,agentInvoked,respondWith)- Tool error codes