Agent

The core Agent class for building AI agents in TypeScript

The Agent class is the primary entry point for the PraisonAI TypeScript SDK — instructions, tools, and optional persistence in one API.

Diagram

User

Agent

Tools

Response

Quick Start

  1. Simple Usage
    typescript
    import { Agent } from 'praisonai';
    
    const agent = new Agent({ instructions: "You are a helpful assistant" });
    const response = await agent.chat("Hello!");
    console.log(response);
  2. Install
    bash
    npm install praisonai

Basic Usage

Simple Agent

typescript
import { Agent } from 'praisonai';

const agent = new Agent({
  instructions: "You are a helpful AI assistant that provides concise answers."
});

const response = await agent.chat("What is the capital of France?");
console.log(response); // "Paris is the capital of France."

Agent with Custom Name

typescript
const agent = new Agent({
  name: "ResearchBot",
  instructions: "You are a research assistant specializing in scientific topics."
});

Agent with Model Selection

typescript
const agent = new Agent({
  instructions: "You are helpful",
  llm: "claude-3-5-sonnet-latest"  // or "gpt-4o", "gemini-2.0-flash", etc.
});

A bare claude- or gemini- name routes to Anthropic or Google — see Model Routing for how names are resolved.

Default model

Omit llm and the agent picks a model that matches whichever provider key you’ve set — no OpenAI key required.

typescript
// Only ANTHROPIC_API_KEY is set → uses anthropic/claude-3-5-sonnet-latest
const agent = new Agent({ instructions: "You are helpful" });

// Only GEMINI_API_KEY is set → uses gemini/gemini-1.5-flash
const gemini = new Agent({ instructions: "You are helpful" });

// Only OLLAMA_HOST is set → uses ollama/llama3.2 (runs locally, no cloud key)
const local = new Agent({ instructions: "You are helpful" });

Set your provider key and it just works. The model is chosen in this order:

OrderSourceExample
1Explicit llm / model on the agentllm: "gpt-4o"
2OPENAI_MODEL_NAME env varOPENAI_MODEL_NAME=gpt-4o
3PRAISONAI_MODEL env varPRAISONAI_MODEL=gpt-4o
4First provider key present (order below)ANTHROPIC_API_KEY → anthropic/claude-3-5-sonnet-latest
5Fallbackgpt-4o-mini

Provider key → default model, checked top to bottom:

Provider keyDefault model
OPENAI_API_KEYgpt-4o-mini
ANTHROPIC_API_KEYanthropic/claude-3-5-sonnet-latest
GEMINI_API_KEYgemini/gemini-1.5-flash
GOOGLE_API_KEYgoogle/gemini-1.5-flash
GROQ_API_KEYgroq/llama-3.3-70b-versatile
COHERE_API_KEYcohere/command-r
OLLAMA_HOSTollama/llama3.2

See Model Routing for how the chosen model string reaches its vendor.

Agent with Tools

Pass plain JavaScript functions as tools – schemas are auto-generated:

typescript
import { Agent } from 'praisonai';

// Define a simple tool function
const getWeather = (city: string) => `Weather in ${city}: 22°C, Sunny`;

const agent = new Agent({
  instructions: "You are a weather assistant. Use the getWeather tool to answer weather questions.",
  tools: [getWeather]
});

const response = await agent.chat("What's the weather in Paris?");
console.log(response); // Uses the tool and responds with weather info

Multiple Tools

typescript
const getWeather = (city: string) => `Weather in ${city}: 22°C`;
const getTime = (timezone: string) => `Current time in ${timezone}: 14:30`;
const calculate = (expression: string) => eval(expression).toString();

const agent = new Agent({
  instructions: "You can check weather, time, and do calculations.",
  tools: [getWeather, getTime, calculate]
});

Agent with Persistence

Use the db() factory for easy database setup:

typescript
import { Agent, db } from 'praisonai';

const agent = new Agent({
  instructions: "You are a helpful assistant with memory.",
  db: db("sqlite:./conversations.db"),
  sessionId: "user-123"
});

// Conversations are automatically persisted
await agent.chat("My name is Alice");
await agent.chat("What's my name?"); // Remembers: "Your name is Alice"

Database URL Formats

typescript
// SQLite — durable, survives restarts (recommended)
db("sqlite:./data.db")
db("sqlite::memory:")   // real SQLite, but process-local

// In-memory (default) — lost on exit
db("memory:")
db(":memory:")

// PostgreSQL / Redis — throw today (remote-only transports, not session stores)
db("postgres://user:pass@host:5432/dbname")
db("redis://localhost:6379")

Agent Configuration

Full Configuration Options

typescript
interface SimpleAgentConfig {
  // Required
  instructions: string;           // System prompt / agent instructions

  // Optional - Identity
  name?: string;                  // Agent name (auto-generated if not provided)

  // Optional - LLM
  llm?: string;                   // Model: "gpt-4o-mini", "claude-3-sonnet", etc.

  // Optional - Credentials & transport
  apiKey?: string;                // Per-agent API key; falls back to *_API_KEY env var
  baseURL?: string;               // Custom endpoint (OpenAI-compatible proxies etc.)
  fetch?: typeof fetch;           // Custom fetch (Tauri / native bridge); implies browser support

  // Optional - Behavior
  verbose?: boolean;              // Enable logging (default: true)
  pretty?: boolean;               // Pretty output formatting
  markdown?: boolean;             // Markdown in responses (default: true)
  stream?: boolean;               // Streaming responses (default: true)

  // Optional - Tools
  tools?: Function[];             // Array of tool functions
  toolFunctions?: Record<string, Function>;  // Named tool implementations
  maxIterations?: number;         // Max tool-call round-trips before the loop aborts (default: 20)
  maxToolCallsPerTurn?: number;   // Max tool calls executed per round (default: 10)

  // Optional - Structured output (works on every provider)
  outputSchema?: Record<string, any>;  // JSON Schema for structured output
  outputSchemaName?: string;           // Schema name (default: "response")

  // Optional - Persistence
  db?: DbAdapter;                 // Database adapter for persistence
  sessionId?: string;             // Session ID (auto-generated if not provided)
  runId?: string;                 // Run ID for tracing

  // Optional - Advanced Mode (role/goal/backstory) — stored as readable fields
  role?: string;                  // Agent role (default: "Assistant")
  goal?: string;                  // Agent goal (default: instructions, else "Help the user with their tasks")
  backstory?: string;             // Agent backstory (default: instructions, else "I am an AI assistant")
}

Provider Credential Options

OptionTypeDefaultDescription
apiKeystringundefinedPer-agent API key. As of PR #4483 it is forwarded to whichever backend the model routes to — not only OpenAI.
baseURLstringundefinedPer-agent endpoint. When set and the llm string is a bare name, the agent stays on the OpenAI-compatible path (proxy case). An explicit provider/model prefix still wins.

See Model Routing for how bare names resolve and the baseURL exception.

Structured Output Options

OptionTypeDefaultDescription
outputSchemaRecord<string, any>undefinedJSON Schema for structured output. Works on every provider — OpenAI uses native response_format: json_schema, other providers route through the AI SDK backend’s generateObject({ schema }) (PraisonAI PR #4412).
outputSchemaNamestring'response'Name used for the JSON schema in response_format.json_schema.name.

See Structured Output for the full guide.

Tool-Call Loop

When an agent has tools, it loops between the model and your tool functions until the model produces a final answer. Two knobs bound the loop.

typescript
import { Agent } from 'praisonai';

const agent = new Agent({
  name: "Researcher",
  instructions: "Answer questions using the available tools.",
  tools: [search, fetchUrl],
  maxIterations: 30,          // default is 20
  maxToolCallsPerTurn: 5,     // default is 10
});

const answer = await agent.chat("Summarise today's top AI story.");
OptionTypeDefaultDescription
maxIterationsnumber20Maximum tool-call round-trips before the loop aborts.
maxToolCallsPerTurnnumber10Maximum tool calls executed in a single round. Extras in one round are dropped with a warning; the assistant message sent back to the model lists only the executed calls, so tool_call_id pairing with tool results stays consistent.
Diagram

yes

no

iterations >= maxIterations

📝 User prompt

🤖 Agent

Model wants a tool?

🔧 Run tool

✅ Final answer

❌ Throw

Exported Types

Import these types for the streaming, chat, and execute surfaces:

typescript
import type {
  AgentEvent,
  AgentStreamOptions,
  AgentChatCallOptions,  // new — chat() with errorsAsNull
  AgentExecuteTask,      // new — execute() first-argument union
  AgentTaskLike,         // new — duck-type: { description?: string, ... }
} from 'praisonai';

AgentEvent is the discriminated union yielded by streamEvents(); AgentStreamOptions is the optional second argument to stream() / streamEvents(). See Streaming for both reference tables. AgentChatCallOptions extends AgentChatOptions with errorsAsNull; AgentExecuteTask is string | AgentTaskLike | Task, the first argument to execute().

Behaviour notes (v1.7.4)

  • Importing praisonai no longer requires OPENAI_API_KEY. The key is checked at OpenAI client creation, so Anthropic / Google users can require('praisonai') without it.
  • Default temperature: 0.7 is omitted for reasoning-family models (gpt-5, o1, o3, o4), which reject any temperature field. An explicit temperature still takes effect.
  • Agent.chat() no longer double-appends the user prompt to history. This is a bugfix — no code change needed.
  • Env-only OpenAI client now rebuilds when OPENAI_API_KEY or OPENAI_BASE_URL changes between calls — rotating a key in a settings screen no longer requires restarting the process. See JS Credential Rotation.
  • OPENAI_BASE_URL is now forwarded on the env-only path, so exporting it works for module-level convenience functions and env-only Agents the same way an explicit baseURL on the config already did.
  • New public export resetOpenAIClient() forces a rebuild on the next call.

Runtime compatibility

The Agent module has no static dependency on any Node.js builtin, so it imports and runs anywhere JavaScript runs.

RuntimeImport-timeRandom IDs (runId, approvals)
Node 19+✅crypto.randomUUID (WebCrypto global)
Node 18✅crypto.getRandomValues fallback
Browser / Electron renderer / Tauri webview✅crypto.randomUUID
React Native✅crypto.getRandomValues fallback
Older webviews without WebCrypto✅Math.random() fallback (weak source, still valid v4 UUID)

See Browser & Webview Runtimes for how to run agents in a browser, Tauri app, Electron renderer, or React Native app.

Credentials & Transport

Pass apiKey and baseURL directly on the Agent — no environment variables required.

typescript
import { Agent } from 'praisonai';

const agent = new Agent({
  instructions: "Use my local model",
  llm: "local-llama",
  apiKey: "not-needed",
  baseURL: "http://localhost:1234/v1",  // LM Studio, vLLM, etc.
});

Supply a custom fetch to route requests through native code (Tauri, native bridge). See Browser & Webview Runtimes for the full story.

OptionTypeDefaultDescription
apiKeystringundefined (falls back to OPENAI_API_KEY)Per-agent OpenAI key.
baseURLstringundefinedPer-agent base URL for OpenAI-compatible endpoints.
fetchtypeof fetchundefinedCustom transport; implies browser support.

Advanced Mode (Role/Goal/Backstory)

For more structured agent definitions:

typescript
const agent = new Agent({
  role: "Senior Research Analyst",
  goal: "Analyze market trends and provide investment insights",
  backstory: "You have 20 years of experience in financial markets..."
});

// Equivalent to:
const agent2 = new Agent({
  instructions: `You are a Senior Research Analyst.
Your goal is: Analyze market trends and provide investment insights
Background: You have 20 years of experience in financial markets...`
});

role, goal, and backstory are stored as readable fields on every agent:

typescript
const agent = new Agent({ role: "Support Specialist", goal: "Resolve customer tickets" });

console.log(agent.role);      // "Support Specialist"
console.log(agent.goal);      // "Resolve customer tickets"
console.log(agent.backstory); // "I am an AI assistant" (default)
FieldTypeDefault
rolestring"Assistant"
goalstringinstructions if set, else "Help the user with their tasks"
backstorystringinstructions if set, else "I am an AI assistant"

Using Agent in a webview / mobile app

Agent is safe to import in a browser, Electron renderer, Tauri webview, or React Native bundle when you import it from the praisonai/mobile entry. That entry is guaranteed by CI to have no static Node-builtin imports on the Agent graph.

typescript
// ✅ mobile / webview bundle
import { Agent } from 'praisonai/mobile';

Session Management

typescript
const agent = new Agent({
  instructions: "You are helpful",
  sessionId: "custom-session-id"
});

// Get session and run IDs
console.log(agent.getSessionId()); // "custom-session-id"
console.log(agent.getRunId());     // Auto-generated UUID

Methods

chat(prompt: string)

Send a message and get a response. Pass a third signal?: AbortSignal argument to stop the call — see Cancellation:

typescript
const response = await agent.chat("Hello!");

// With a Stop button:
const controller = new AbortController();
await agent.chat("Write an essay", undefined, controller.signal);

Return null on error (errorsAsNull)

By default chat() rejects on any error. Pass { errorsAsNull: true } for Python’s contract — the promise resolves with null instead. The return type widens to Promise<string | null> only on this call.

typescript
const result: string | null = await agent.chat(
  "Hello!",
  undefined,
  undefined,
  { errorsAsNull: true },
);

if (result === null) {
  // the turn failed; the error was still logged via Logger.error
}

Still fatal, even with errorsAsNull: true (Python re-raises these too):

ErrorWhy
AbortError / aborted signalAn aborted turn is not an empty answer
InterruptedErrorSame
ToolExecutionErrorA tool failed — the caller must handle it
BudgetExceededErrorA budget stop is not a model outcome

Only chat() honours errorsAsNull. start() and stream() accept AgentChatOptions and ignore it — see the Parity Notices ledger for why an accepted-but-ignored option is the defect this package tracks.

start(prompt?: string)

Run the agent. The prompt is optional — omit it and the agent falls back to its instructions (or "Hello" when instructions is not set).

typescript
import { Agent } from 'praisonai';

const agent = new Agent({ instructions: "Write a haiku about the ocean" });
await agent.start(); // uses instructions as the prompt

Pass a prompt to override that fallback:

typescript
const response = await agent.start("Begin the task");

execute(task?, context?)

Run a task on this agent. Matches Python’s Agent.execute(task, context=None).

typescript
import { Agent } from 'praisonai';

const agent = new Agent({ instructions: "You are a research assistant" });

// A string runs as the task
await agent.execute("Summarise the Q3 revenue report.");

// A task-like object is read through `description`
await agent.execute({ description: "Write the release notes." });

// A real Task instance also works
import { Task } from 'praisonai';
const task = new Task({ name: "research", description: "…", expected_output: "…" });
await agent.execute(task);

// Chain prior output — substituted for {{previous}} in the prompt
await agent.execute("Improve this draft: {{previous}}", "the rough draft");

// An array of dependency results is joined with blank lines
await agent.execute("Merge: {{previous}}", ["result A", "result B"]);

// No task → runs the agent's own instructions (unchanged)
await agent.execute();

The prompt is resolved in four branches:

Diagram

no

yes

string

object

yes

no

execute task, context

task given?

Run instructions

typeof task

Run the string

task.description
is a string?

Run task.description

Run String task

Resolution order for the prompt:

  1. execute() with no argument → runs instructions
  2. execute(str) → runs str as the task
  3. execute(task) with a string task.description → runs task.description
  4. execute(other) → runs String(other)

The optional second argument, context, is prior output substituted for {{previous}} in the resolved prompt. An array is joined with blank lines (fan-in of dependency results). execute() routes through chat(), so the turn is recorded in history and in getResult().

getResult(): string | null

The text this agent produced on its most recent completed turn. null until the agent has run at least once.

typescript
const agent = new Agent({ instructions: "You are helpful" });

agent.getResult(); // null

await agent.chat("Hello!");
agent.getResult(); // "Hi, how can I help?"

Recording covers every entry point — start(), chat(), execute(), stream(), streamEvents(), and cache hits on chat(). A turn that throws or is cancelled leaves the previous value in place: the field records the last result there was, not the last attempt.

History (save & restore a chat)

Persist a conversation and reopen it later. The next chat() picks up where the previous run left off — the model regains its memory of the conversation, tool calls included.

typescript
import { Agent, type AgentMessage } from 'praisonai';

const agent = new Agent({ instructions: 'You are helpful' });
await agent.chat('My name is Alice');

const saved: AgentMessage[] = agent.getHistory();  // persist this
// … later …
const restored = new Agent({ instructions: 'You are helpful' });
restored.setHistory(saved);
await restored.chat('What is my name?');           // "Your name is Alice"

getHistory(): AgentMessage[]

Returns a copy of the full conversation, including tool_calls / tool_call_id. Persisting this output is the intended way to save a chat.

setHistory(messages: readonly AgentMessage[]): void

Validates and restores a saved conversation. Throws on: non-array input, unknown role, orphaned tool_call_id, or a non-leading system message. A leading system message is accepted and stripped (the agent’s own instructions are prepended on every run). See Chat History Restore for the full contract.

Properties

lastStopReason

Terminal reason for the most recent run. null until the agent has run at least once.

typescript
import { Agent } from 'praisonai';
import type { StopReason } from 'praisonai';

const agent = new Agent({ instructions: 'You are helpful', tools: [search] });

try {
  await agent.chat('Do a hard task');
  console.log(agent.lastStopReason); // 'completed'
} catch (err) {
  console.log(agent.lastStopReason); // 'max_steps' or 'error'
}
ValueMeaning
'completed'The run finished normally with a final answer.
'max_steps'The tool loop was aborted because maxIterations was reached. Paired with a thrown error.
'cancelled'The run was cancelled by the caller.
'error'The run threw an error other than max_steps exhaustion.
nullThe agent has not been run yet.

stream(prompt: string, opts?: AgentStreamOptions)

Return an AsyncIterable<string> of text tokens — iterate them to render the response live in any host. See Streaming.

typescript
for await (const token of agent.stream("Tell me a story")) {
  process.stdout.write(token);
}

streamEvents(prompt: string, opts?: AgentStreamOptions)

Return an `AsyncIterable

of structured events (text, tool_call, tool_result, finish, error`) — use when you need finish/error/tool semantics. See Streaming.

typescript
for await (const event of agent.streamEvents("Hi")) {
  if (event.type === 'text') process.stdout.write(event.delta);
}

Environment Variables

bash
# Model selection — override the provider-aware default (see Default model above)
OPENAI_MODEL_NAME=gpt-4o
PRAISONAI_MODEL=gpt-4o

# Behavior
PRAISON_VERBOSE=true
PRAISON_PRETTY=true

# API Keys
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_API_KEY=...

Examples

Research Agent

typescript
const researcher = new Agent({
  name: "Researcher",
  instructions: `You are a research assistant. 
  - Search for information on topics
  - Summarize findings concisely
  - Cite sources when possible`,
  llm: "gpt-4o"
});

const findings = await researcher.chat("Research the latest AI developments in 2024");

Code Assistant

typescript
const coder = new Agent({
  name: "CodeHelper",
  instructions: `You are a coding assistant.
  - Write clean, well-documented code
  - Explain your solutions
  - Follow best practices`,
  tools: [runCode, searchDocs]
});

const code = await coder.chat("Write a function to sort an array");

Agent Options

PR #4841 wired up 15 constructor options and 6 per-call chat options that were previously accepted for parity and dropped. Each snippet below is the shortest way to turn the behaviour on.

Constructor options

OptionTypeNotes
authstringSubscription provider; picks a default model ('claude-code' → 'anthropic/claude-sonnet-4-5', 'qwen-cli' → 'openai/qwen3-coder-plus'). Throws on an unregistered provider. See Auth.
toolsetsstring[]Named toolset groups. Throws on an unknown name.
reflection`boolean \preset \ReflectionConfig`Critique-and-regenerate loop. Presets: minimal, standard, thorough. Rounds at agent.lastReflections.
autonomy`’suggest’ \‘auto_edit’ \‘full_auto’ \AutonomyConfig`Enables the loop and a doom-loop guard (autonomy.doomLoopThreshold, default 3). AgentTeam.autonomy propagates to members that declared none (see AgentTeam); adopt one directly with agent.adoptAutonomy(config) (no-op if one is already set).
templatesTemplateConfigsystem, prompt, response, useSystemPrompt. Throws on an unknown field.
selfImprove`boolean \‘inline’ \‘background’ \SelfImproveConfig`Isolated skill-review turn after a tool-using turn; proposals at agent.lastSkillProposals.
toolConfig`boolean \ToolConfig`timeout, retryPolicy, outputLimit, outputDirection, parallel, allowGlobalTools. See Tool Config.
learn`boolean \‘agentic’ \‘propose’ \LearnConfig`Extracts learnings and injects Learned Insights. See Learn.
backendManagedBackendLikeCustom object exposing execute(prompt, options). Throws without execute(). See Placement.
runOn`string \ManagedBackendLike`A managed runtime hosts the whole agent. Throws on an unknown name.
toolsRunOn`string \ToolPlaceLike`A tool place runs the tools; the loop stays local. Throws on an unknown name. Names come from the compute-provider registry — docker and local ship in the box; register more with registerComputeProvider. AgentTeam.toolsRunOn propagates to members that declared none (see AgentTeam). Adopt a place directly with agent.adoptToolPlace(place) (no-op if one is already set). See Compute Providers (TypeScript).
runtime`boolean \string \AgentRuntimeConfig`Delegates the turn to a registered runtime (DEFAULT_RUNTIME_ID = 'praisonai'). See Runtime.
toolSearch`boolean \‘on’ \‘off’ \‘auto’ \ToolSearchConfig`Progressive tool disclosure via tool_search / tool_describe / tool_call.
messageSteering`boolean \MessageSteeringProtocol`Enables agent.steer().
sandbox`boolean \string \SandboxConfig`Sandboxed code execution. See Sandbox.
typescript
import { Agent } from 'praisonai';

// auth — bill against a subscription seat; picks the provider's default model
const a1 = new Agent({ instructions: 'You are helpful', auth: 'claude-code' });

// toolsets — attach a named group
const a2 = new Agent({ instructions: 'Search the web', toolsets: ['web'] });

// reflection — critique and regenerate, then read the rounds
const a3 = new Agent({ instructions: 'Answer carefully', reflection: 'minimal' });
await a3.chat('Explain TLS');
console.log(a3.lastReflections);

// autonomy — approve edits automatically, prompt for the rest
const a4 = new Agent({ instructions: 'Refactor code', tools: [], autonomy: 'auto_edit' });

// templates — control the system prompt
const a5 = new Agent({
  instructions: 'Be terse',
  templates: { system: 'You are {name}. {instructions}', useSystemPrompt: true },
});

// selfImprove — review skills after a tool-using turn without blocking
const a6 = new Agent({ instructions: 'Do work', selfImprove: 'background' });

// toolConfig — cap a tool at 10s with two retries
const a7 = new Agent({
  instructions: 'Use tools',
  toolConfig: { timeout: 10, retryPolicy: { maxAttempts: 2 } },
});

// learn — extract and inject learnings each turn
const a8 = new Agent({ instructions: 'Assist', learn: 'agentic' });

// backend — run the whole agent on a custom managed backend
const a9 = new Agent({
  instructions: 'Hosted',
  backend: { async execute(prompt) { return `handled: ${prompt}`; } },
});

// runOn / toolsRunOn — see /js/placement for registration
// const a10 = new Agent({ instructions: 'Hosted', runOn: 'my-runtime' });
// const a11 = new Agent({ instructions: 'Local loop', toolsRunOn: 'local' });

// runtime — delegate the turn to the builtin runtime
const a12 = new Agent({ instructions: 'Delegated', runtime: true });

// toolSearch — defer big tool lists behind bridge tools
const a13 = new Agent({ instructions: 'Many tools', toolSearch: 'auto' });

// messageSteering — accept live guidance
const a14 = new Agent({ instructions: 'Steerable', messageSteering: true });

// sandbox — give the agent a subprocess sandbox
const a15 = new Agent({ instructions: 'Run code', sandbox: true });

Per-call chat options

AgentChatOptions is the second argument to chat().

OptionTypeNotes
attachmentsreadonly string[]Image paths, http(s):// or data: URIs. Images only (.jpg/.jpeg/.png/.gif/.webp); other inputs warn-and-skip. Ephemeral. Emits a notice on the AI SDK backend.
reasoningStepsbooleanForces a single non-streaming completion. Beats stream.
taskNamestringMerged into agent_start / agent_complete hook contexts; read via agent.getTaskContext().
taskDescriptionstringAs taskName.
taskIdstringAs taskName.
configRecord<string, unknown>Forwarded verbatim to a managed backend’s execute().
errorsAsNullbooleanchat() only. Resolve with null instead of rejecting. Cancellation, ToolExecutionError, and BudgetExceededError still reject. Widens the return to `Promise<string \null>`.
typescript
import { Agent } from 'praisonai';

const agent = new Agent({ instructions: 'Describe images' });

// attachments — images for this turn only
await agent.chat('What is in this picture?', { attachments: ['./photo.png'] });

// reasoningSteps — one non-streaming reasoning completion
await agent.chat('Prove the theorem', { reasoningSteps: true });

// task metadata — readable afterwards
await agent.chat('Step 1', { taskName: 'ingest', taskDescription: 'load data', taskId: 't-1' });
console.log(agent.getTaskContext()); // { name: 'ingest', description: 'load data', id: 't-1' }

// config — forwarded to a managed backend's execute()
await agent.chat('Run remotely', { config: { region: 'eu' } });

When your option throws

Previous code that mis-typed a placement name, an auth provider, or a sandbox field ran silently in-process. The same code now raises at construction (or on executeCode()), so a typo never becomes a wrong-machine run. Grep for the exact text:

Other typed inputs throw their own tested messages: toolsets: ['unknown-name'], reflection: 'exhaustive', templates: { greeting: 'hi' }, an invalid messageSteering, and an invalid runtime type.

New methods and fields

PR #4841 adds these instance methods and public fields.

steer(message: string, priority?: number)

Queue priority-aware guidance for the next turn (requires messageSteering: true). Returns a message id, or '' when steering is off or the queue is full.

typescript
import { Agent } from 'praisonai';
import { SteeringPriority } from 'praisonai';

const agent = new Agent({ instructions: 'Assist', messageSteering: true });
agent.steer('check the staging config first', SteeringPriority.HIGH);
await agent.chat('Deploy the service');

SteeringPriority is { LOW: 1, NORMAL: 5, HIGH: 10, URGENT: 20, INTERRUPT: 30 }. Drained notes are prefixed [USER GUIDANCE], [URGENT USER GUIDANCE] or [INTERRUPT USER GUIDANCE] by priority.

executeCode(code: string, options?: ExecuteCodeOptions)

Run a one-shot snippet in the agent’s sandbox. options is { language?, checkSecurity?, runIn? }.

typescript
import { Agent } from 'praisonai';

const agent = new Agent({ instructions: 'Run code', sandbox: true });
const result = await agent.executeCode('print(2 + 2)', { language: 'python' });
console.log(result.stdout, result.metadata?.securityWarnings);

Getters and fields

MemberReturns
agent.getTaskContext()`TaskContext \undefined — the last turn's taskName / taskDescription / taskId`.
agent.getLearnManager()The lazily-built learn manager, or undefined.
agent.getManagedBackend()The resolved backend / runOn target, or undefined.
agent.getToolPlace()The resolved toolsRunOn place, or undefined.
agent.getMessageSteering()The MessageSteeringProtocol, or undefined.
agent.getRuntime()The resolved runtime, or undefined.
agent.getAutonomy()The AutonomyConfig, or undefined.
agent.getSandboxConfig()The SandboxConfig, or undefined.
agent.hasSandboxboolean — whether a sandbox is configured.
agent.lastSkillProposalsSkillProposal[] — proposals from the last self-improve review.
agent.lastReflectionsReflectionRound[] — critiques from the last reflection loop.

Related