talkToAgent
Client function: run one of the caller's own registered agents on a task, inline or as a polled job.
import { talkToAgent } from 'flowstack-sdk'Non-React client function. POST /agents/talk. Where useAgents() lets an app DISCOVER which agents can be targeted, this actually runs one and returns its answer, over the same shared service the MCP tool and the console use.
Async by design. Research and multi-step agents routinely take 60–120s. If the agent finishes within waitSeconds (default 25, max 50) you get the answer inline with status: 'done'. Otherwise you get status: 'running' plus a job_id — hand that to getAgentResult and poll roughly every 20–30s.
Three ways to address a target, in precedence order: handle (e.g. "@coach") outranks everything; siteId + agent names a persona at a site; supplying neither lets the capability registry route by task, which sets routed: true on the result.
Signature
talkToAgent(credentials, task, options?, config?): Promise<ApiResponse<AgentTalkResult>>Parameters
| Param | Type | Notes | Description |
|---|---|---|---|
credentials | FlowstackCredentials | required | The credentials of the user who owns the target agent. |
task | string | required | The task to run, in natural language. |
options | TalkToAgentOptions | — | Targeting (handle, or siteId + agent), fileRefs, and waitSeconds. Omit entirely to let the capability registry route. |
config | FlowstackClientConfig | — | Client config (baseUrl, tenantId as needed). |
Returns
| Field | Type | Description |
|---|---|---|
| — | Promise<ApiResponse<AgentTalkResult>> | status: 'done' with response when the agent finished inside waitSeconds; status: 'running' with job_id otherwise. |
Examples
const res = await talkToAgent(credentials, 'Summarize this week’s training load.', {
handle: '@coach',
waitSeconds: 30,
});
if (!res.ok) throw new Error(res.error);
let result = res.data;
while (result.status === 'running') {
await new Promise((r) => setTimeout(r, 25_000)); // ~20–30s between polls
const poll = await getAgentResult(credentials, result.job_id);
if (!poll.ok) break;
result = poll.data;
}
if (result.status === 'done') console.log(result.response);// No handle, no siteId — the registry routes by task and flags it.
const res = await talkToAgent(credentials, 'Reconcile last month’s invoices.');
if (res.ok && res.data.routed) console.log('routed to', res.data.persona);builtAppSafe is false: inside a generated app the end-user is not the owner, so they would only ever reach their own agents, never the app’s.status: 'running' with a job_id and no response field — code that reads res.data.response directly gets undefined for exactly the long-running agents it was written for. Always branch on status.waitSeconds is capped at 50. Asking for more does not extend the inline wait; it just delays the point where you must poll anyway.handle > siteId + agent > capability routing. Explicit targeting is deterministic; routing is not — prefer a handle when you know which agent you want.handle is the phone-friendly addressing path — "@coach" (the leading @ is optional), the same identifier used from SMS/voice surfaces.See also
getAgentResult · AgentTalkResult · TalkToAgentOptions · useAgents
Source: src/api/client.ts (agent-to-agent talk, P0-187 FR3b) · Also available in llms-full.txt and registry.json.