Agents
A Mentiora Agent is a hosted AI workflow configured and deployed on the Mentiora platform. Agents encapsulate a system prompt, model settings, and optional tool definitions into a single deployable unit. You interact with agents through the SDK without managing the underlying infrastructure.
Agents are resolved by tag (e.g. 'production', 'staging') or by explicit agentId / agent_id with an optional revision number. Tags point to a specific agent revision and can be reassigned in the dashboard, making it easy to promote new versions without changing client code.
The SDK provides two interaction modes: run() waits for the agent to finish and returns the complete result, while stream() yields incremental events (text deltas, tool calls, completion) as they arrive via Server-Sent Events. Use run() for simple request/response patterns and stream() when you need real-time output in a UI.
Unknown SSE event names are passed through as custom events so application code can handle domain-specific payloads without waiting for a new SDK release.
Note: Unlike tracing methods (which return SendTraceResult and never throw), agent methods throw exceptions on errors (ValidationError, NetworkError).
Quick Start
- TypeScript
- Python
import { MentioraClient } from '@mentiora.ai/sdk';
const client = new MentioraClient({ apiKey: process.env.MENTIORA_API_KEY });
const result = await client.agents.run({
tag: 'production',
message: 'What is the weather today?',
});
console.log(result.output);
import os
from mentiora import MentioraClient, MentioraConfig, AgentRunParams
client = MentioraClient(MentioraConfig(api_key=os.getenv('MENTIORA_API_KEY')))
result = await client.agents.run_async(AgentRunParams(
tag='production',
message='What is the weather today?',
))
print(result.output)
Streaming
Stream agent responses in real time using Server-Sent Events:
- TypeScript
- Python
for await (const event of client.agents.stream({
tag: 'production',
message: 'Write a poem about TypeScript.',
})) {
switch (event.type) {
case 'output_text_delta':
process.stdout.write(event.delta);
break;
case 'custom':
console.log(`\nCustom event: ${event.event}`, event.data);
break;
case 'chat_completed':
console.log(`\nDone: ${event.status}`);
break;
case 'error':
console.error(`\nError: ${event.message}`);
break;
}
}
Async (recommended):
from mentiora import AgentRunParams
async for event in client.agents.stream_async(AgentRunParams(
tag='production',
message='Write a poem about Python.',
)):
if event.type == 'output_text_delta':
print(event.delta, end='', flush=True)
elif event.type == 'custom':
print(f'\nCustom event: {event.event} {event.data}')
elif event.type == 'chat_completed':
print(f'\nDone: {event.status}')
elif event.type == 'error':
print(f'\nError: {event.message}')
Sync:
for event in client.agents.stream(AgentRunParams(
tag='production',
message='Write a poem about Python.',
)):
if event.type == 'output_text_delta':
print(event.delta, end='', flush=True)
elif event.type == 'custom':
print(f'\nCustom event: {event.event} {event.data}')
elif event.type == 'chat_completed':
print(f'\nDone: {event.status}')
elif event.type == 'error':
print(f'\nError: {event.message}')
Use the built-in Streaming Helpers to forward agent events as SSE with a single function call — works with Next.js, FastAPI, and other frameworks.
Multi-turn Conversations
Use threadId (TypeScript) or thread_id (Python) to continue conversations across multiple agent calls:
- TypeScript
- Python
// First turn
const result1 = await client.agents.run({
tag: 'production',
message: 'What is TypeScript?',
});
const threadId = result1.threadId; // Save the thread ID
// Continue the conversation
const result2 = await client.agents.run({
tag: 'production',
message: 'What are its main benefits?',
threadId, // Same thread continues the conversation
});
# First turn
result1 = await client.agents.run_async(AgentRunParams(
tag='production',
message='What is Python?',
))
thread_id = result1.thread_id # Save the thread ID
# Continue the conversation
result2 = await client.agents.run_async(AgentRunParams(
tag='production',
message='What are its main use cases?',
thread_id=thread_id, # Same thread continues the conversation
))
Agent Resolution
Identify which agent to run using either a tag or agentId/agent_id (but not both):
- TypeScript
- Python
// By tag (recommended for production)
const result = await client.agents.run({
tag: 'production',
message: 'Hello',
});
// By agent ID with specific revision
const result2 = await client.agents.run({
agentId: 'agent-abc-123',
revision: 5,
message: 'Hello',
});
# By tag (recommended for production)
result = await client.agents.run_async(AgentRunParams(
tag='production',
message='Hello',
))
# By agent ID with specific revision
result = await client.agents.run_async(AgentRunParams(
agent_id='agent-abc-123',
revision=5,
message='Hello',
))
End-User Tracking
Pass endUserId (TypeScript) or end_user_id (Python) to associate agent calls with specific end-users:
- TypeScript
- Python
const result = await client.agents.run({
tag: 'production',
message: 'Hello',
endUserId: 'user-123',
});
result = await client.agents.run_async(AgentRunParams(
tag='production',
message='Hello',
end_user_id='user-123',
))
Retry Behavior
- Non-streaming (
run()/run_async()): Retries up to 3 times on 5xx errors and rate limits (429), with exponential backoff and jitter. - Streaming (
stream()/stream_async()): No retry -- the stream is opened once. If the connection fails mid-stream, aNetworkErroris raised. Implement your own retry logic around the stream call if needed.
- TypeScript
- Python
| Mode | Method | Retries |
|---|---|---|
| Non-streaming | run() | Up to 3 |
| Streaming | stream() | None |
| Mode | Methods | Retries |
|---|---|---|
| Non-streaming | run() / run_async() | Up to 3 |
| Streaming | stream() / stream_async() | None |
Error Handling
Agent methods throw exceptions instead of returning error results:
- TypeScript
- Python
import { ValidationError, NetworkError } from '@mentiora.ai/sdk';
try {
const result = await client.agents.run({
tag: 'production',
message: 'Hello',
});
console.log(result.output);
} catch (error) {
if (error instanceof ValidationError) {
console.error(`Invalid parameters: ${error.message}`);
} else if (error instanceof NetworkError) {
console.error(`Network error (status ${error.statusCode}): ${error.message}`);
}
}
For streaming, an AgentErrorEvent is yielded when the server reports an error, and the stream stops automatically:
for await (const event of client.agents.stream(params)) {
if (event.type === 'error') {
console.error(`Agent error [${event.code}]: ${event.message}`);
break;
}
}
from mentiora.errors import ValidationError, NetworkError
try:
result = await client.agents.run_async(AgentRunParams(
tag='production',
message='Hello',
))
print(result.output)
except ValidationError as e:
print(f'Invalid parameters: {e}')
except NetworkError as e:
print(f'Network error (status {e.status_code}): {e}')
For streaming, an AgentErrorEvent is yielded when the server reports an error, and the stream stops automatically:
async for event in client.agents.stream_async(params):
if event.type == 'error':
print(f'Agent error [{event.code}]: {event.message}')
break
See Also
- Plugins -- auto-trace OpenAI and LangChain calls
- Streaming Helpers -- SSE utilities for web frontends
- Agents API Reference -- full method and type reference