Skip to main content

How to invoke the agent

client.invoke() sends messages to the agent graph and waits for the final response. This guide shows you how to make a basic call, use a persistent thread, extract the response text, and handle errors.

Prerequisites


Step 1: Build a message

Use Message.text_message() to create a plain text user message:

import { Message } from '@10xscale/agentflow-client';

const userMessage = Message.text_message('What is the capital of France?');

For a system prompt:

const systemPrompt = Message.text_message(
'You are a concise geography assistant. Answer in one sentence.',
'system'
);

Step 2: Call invoke()

const result = await client.invoke([userMessage]);

With a system prompt:

const result = await client.invoke([systemPrompt, userMessage]);

invoke() returns an InvokeResult. The response will not arrive until the graph has finished running — all tool calls complete before the await resolves.


Step 3: Extract the response text

The result.messages array contains the final messages from the last graph iteration. The assistant's response is typically the last message with role: 'assistant':

const assistantMsg = result.messages.find(m => m.role === 'assistant');
if (assistantMsg) {
// TextBlocks have a 'text' property
const text = assistantMsg.content
.filter(block => block.type === 'text')
.map(block => (block as any).text as string)
.join('');
console.log('Answer:', text);
}

Step 4: Use a persistent thread

Without a thread_id the graph runs without persistence — each call is independent. To keep conversation history across calls, pass a thread_id in config:

const THREAD_ID = 'user-123-session-1';

const result = await client.invoke(
[Message.text_message('Tell me about Paris.')],
{
config: { configurable: { thread_id: THREAD_ID } },
}
);

// After ending, continue the conversation in a later call
const followUp = await client.invoke(
[Message.text_message('And what about its history?')],
{
config: { configurable: { thread_id: THREAD_ID } },
}
);
// The agent remembers "Paris" from the first turn

result.meta.thread_id always contains the thread ID used. result.meta.is_new_thread is true on the first call for a given ID.


Step 5: Choose response granularity

The response_granularity option controls how much the server includes in the response. Use 'low' in production for best performance:

const result = await client.invoke(
[Message.text_message('Summarise this document')],
{
config: { configurable: { thread_id: 'doc-summary-01' } },
response_granularity: 'low', // Only return messages, no state or summary
}
);
ValueState includedSummary includedUse when
'full'Debugging, admin tools
'partial'When you need state for UI rendering
'low'Production chat, fastest response

Step 6: React to intermediate steps (optional)

If the graph makes multiple tool calls, you can observe each iteration with onPartialResult:

const result = await client.invoke(
[Message.text_message('Research the latest AI news.')],
{
onPartialResult(partial) {
if (partial.has_tool_calls) {
console.log(`Step ${partial.iteration}: searching…`);
}
},
}
);
console.log(`Completed in ${result.iterations} step(s)`);

Step 7: Handle errors

Wrap the call in a try/catch block to handle server errors gracefully:

import { AgentFlowError } from '@10xscale/agentflow-client';

try {
const result = await client.invoke([userMessage]);
displayResponse(result.messages);
} catch (err) {
if (err instanceof AgentFlowError) {
if (err.status === 401) {
redirectToLogin();
} else {
showError(`Server error [${err.status}]: ${err.message}`);
}
} else {
showError('Unexpected error');
throw err;
}
}

Complete working example

import {
AgentFlowClient,
Message,
AgentFlowError,
} from '@10xscale/agentflow-client';

const client = new AgentFlowClient({
baseUrl: 'http://localhost:8000',
auth: { type: 'bearer', token: process.env.API_TOKEN! },
response_granularity: 'low',
});

async function ask(question: string, threadId: string): Promise<string> {
const result = await client.invoke(
[Message.text_message(question)],
{
config: { configurable: { thread_id: threadId } },
response_granularity: 'low',
}
);

return result.messages
.filter(m => m.role === 'assistant')
.flatMap(m => m.content)
.filter(b => b.type === 'text')
.map(b => (b as any).text as string)
.join('');
}

// Usage
const answer = await ask('What is quantum entanglement?', 'thread-001');
console.log(answer);

Verification

Expected console output:

Answer: The capital of France is Paris.

If you see a 401 error, your token is wrong. If you see TypeError: Failed to fetch, the server is not running. Start it with:

agentflow api

What you learned

  • Use Message.text_message() to create user and system messages.
  • Pass config: { configurable: { thread_id } } to persist conversation state.
  • Extract assistant text by filtering result.messages for role === 'assistant' and block.type === 'text'.
  • Use response_granularity: 'low' for the fastest response in production.
  • Catch AgentFlowError to handle HTTP errors by status code.

Next step

See how-to/client/stream-responses to learn how to stream the response token by token for a better UI experience.