How to invoke the agent

In shortStep-by-step guide to calling client.invoke() and handling the response.

  • 3 min read
  • 12 sections
  • Updated
  • v0.9.2
  • Markdown

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:

TypeScript
import { Message } from '10xgraph-client';

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

For a system prompt:

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

Step 2: Call invoke()

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

With a system prompt:

TypeScript
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':

TypeScript
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:

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

const result = await client.invoke(
  [Message.text_message('Tell me about Paris.')],
  {
    config: { 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: { 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:

TypeScript
const result = await client.invoke(
  [Message.text_message('Summarise this document')],
  {
    config: { thread_id: 'doc-summary-01' },
    response_granularity: 'low',  // Only return messages, no state or summary
  }
);
Value State included Summary included Use 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:

TypeScript
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:

TypeScript
import { AgentFlowError } from '10xgraph-client';

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

Complete working example

TypeScript
import {
  AgentFlowClient,
  Message,
  AgentFlowError,
} from '10xgraph-client';

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

async function ask(question: string, threadId: string): Promise<string> {
  const result = await client.invoke(
    [Message.text_message(question)],
    {
      config: { 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:

plaintext
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:

Terminal
10xgraph api

What you learned

  • Use Message.text_message() to create user and system messages.
  • Pass config: { 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.

Last updated for v0.9.2Edit this page on GitHubReport an issue