Skip to main content
The Agent class is the primary entry point for the PraisonAI TypeScript SDK — instructions, tools, and optional persistence in one API.
As of PR #4841 every Agent constructor and Agent.chat option is honoured — see Agent Options below. Two remain partial: attachments and toolConfig.parallel work on the OpenAI-compatible backend and emit a notice on the AI SDK backend. See Parity Notices for the ledger.
Many Python Agent helper methods are not yet on the TypeScript Agent. The constructor and chat / start cover the common path; see the SDK parity baseline for the current method list.
Several options now throw on a typo instead of silently running locally. If you pass an unregistered runOn / toolsRunOn / auth name, an unknown sandbox field, or two conflicting placement options, construction fails with a TypeError or Error. See When your option throws.

Quick Start

1

Simple Usage

2

Install

Basic Usage

Simple Agent

Agent with Custom Name

Agent with Model Selection

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.
Set your provider key and it just works. The model is chosen in this order: Provider key → default model, checked top to bottom: 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:

Multiple Tools

Agent with Persistence

Use the db() factory for easy database setup:

Database URL Formats

Only sqlite: and memory: are wired to the Agent’s session store. db("postgres://…") and db("redis://…") throw — see Database.

Agent Configuration

Full Configuration Options

Provider Credential Options

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

Structured Output Options

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.
If the loop still needs another tool round-trip after maxIterations, chat() throws and agent.lastStopReason === 'max_steps':
Previous versions used maxIterations = 5 and silently returned "" on exhaustion. Both defaults and behaviour changed — wrap chat() in try/catch and raise maxIterations if you see this error.

Exported Types

Import these types for the streaming, chat, and execute surfaces:
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. 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.
Supply a custom fetch to route requests through native code (Tauri, native bridge). See Browser & Webview Runtimes for the full story.

Advanced Mode (Role/Goal/Backstory)

For more structured agent definitions:
role, goal, and backstory are stored as readable fields on every agent:
When an agent is a handoff target, its role and goal are woven into the auto-generated handoff description — so setting them improves routing accuracy for free.

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.
The package root (import { Agent } from 'praisonai') re-exports the CLI and MCP server and is not webview-safe by design. See Browser & Webview Runtimes for the full contract, supported browsers, and the load guarantee.

Session Management

Methods

chat(prompt: string)

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

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.
Still fatal, even with errorsAsNull: true (Python re-raises these too): 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).
Pass a prompt to override that fallback:

execute(task?, context?)

Run a task on this agent. Matches Python’s Agent.execute(task, context=None).
The prompt is resolved in four branches: 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().
Breaking change (v2). Before this release, execute(str) treated the string as previousResult (substituted for {{previous}} in the instructions) and silently discarded it if the instructions had no placeholder. To reproduce the old chaining call, write:

getResult(): string | null

The text this agent produced on its most recent completed turn. null until the agent has run at least once.
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.

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.
Restored history is now actually replayed to the provider on the next start() / chat(). Previous versions (pre-#4513) called generateText(prompt) on the no-tools path, which dropped every earlier turn — the model behaved as though the conversation never happened. Existing code that already used getHistory() sees a stricter return type (AgentMessage[]) and no runtime break.

Properties

lastStopReason

Terminal reason for the most recent run. null until the agent has run at least once.
Import the StopReason union type from either praisonai or praisonai/agent:
This mirrors Python’s Agent.last_stop_reason, so a run’s terminal state is the same story across both SDKs.

stream(prompt: string, opts?: AgentStreamOptions)

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

streamEvents(prompt: string, opts?: AgentStreamOptions)

Return an AsyncIterable<AgentEvent> of structured events (text, tool_call, tool_result, finish, error) — use when you need finish/error/tool semantics. See Streaming.

Environment Variables

Environment variables remain the default fallback. A per-agent apiKey / baseURL wins when both are set.OPENAI_BASE_URL is now honoured in the env-only fallback path — not only for a per-agent baseURL. Exporting it points module-level convenience functions and env-only Agents at your proxy or gateway, and a change is picked up on the next call. See JS Credential Rotation.

Examples

Research Agent

Code Assistant

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

Per-call chat options

AgentChatOptions is the second argument to chat().

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.
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? }.

Getters and fields

AgentTeam

Multi-agent orchestration

Placement

backend / runOn / toolsRunOn

Auth

Subscription auth

Sandbox

executeCode & SandboxConfig

AgentFlow

Step-based workflows

Tools

Custom tool development

Cancellation

Stop a running agent