Skip to main content
Agent.run() executes a natural-language task in a Narada environment and returns an AgentResponse. Create an environment first, then bind an agent to it:
from narada import Agent, BrowserEnvironment

env = BrowserEnvironment()
agent = Agent(environment=env)

response = await agent.run(prompt="Search for Narada AI and summarize the first result.")
print(response.text)
Agent.run() is the current SDK interface. The older Narada().open_and_initialize_browser_window() and window.agent(...) pattern is no longer the recommended API.

Constructor

class Agent:
    def __init__(
        self,
        *,
        environment: Environment,
        kind: AgentKind | str = AgentKind.OPERATOR,
    ) -> None: ...

Run Signature

async def run(
    self,
    prompt: str,
    *,
    reasoning: ReasoningEffort | None = None,
    clear_chat: bool | None = None,
    generate_gif: bool | None = None,
    output_schema: type[BaseModel] | None = None,
    previous_request_id: str | None = None,
    chat_history: list[RemoteDispatchChatHistoryItem] | None = None,
    additional_context: dict[str, str] | None = None,
    attachment: File | IO[Any] | None = None,
    time_zone: str = "America/Los_Angeles",
    user_resource_credentials: UserResourceCredentials | None = None,
    mcp_servers: list[McpServer] | None = None,
    secret_variables: dict[str, str] | None = None,
    input_variables: Mapping[str, Any] | None = None,
    callback_url: str | None = None,
    callback_secret: str | None = None,
    callback_headers: Mapping[str, Any] | None = None,
    on_input_required: InputRequiredCallback | None = None,
    critic: CriticConfig | None = None,
    timeout: int = 1000,
) -> AgentResponse

Agent Kinds

Choose the agent kind when constructing Agent.
kind
AgentKind | str
default:"AgentKind.OPERATOR"
The agent to use for task execution.
Best for browser automation tasks like clicking, navigating, filling forms, and extracting data from pages.
from narada import Agent, AgentKind

agent = Agent(environment=env, kind=AgentKind.OPERATOR)

Parameters

prompt
str
required
The natural-language instruction for the task. When using AgentKind.OPERATOR, Narada applies the correct Operator prefix automatically.
prompt="Search for machine learning jobs and extract the first 5 results"
reasoning
ReasoningEffort | None
default:"None"
Controls how much reasoning the Core Agent uses before responding. This option is only valid with AgentKind.CORE_AGENT.
from narada import AgentKind, ReasoningEffort

agent = Agent(environment=env, kind=AgentKind.CORE_AGENT)
response = await agent.run(
    prompt="Analyze the page and explain the pricing model.",
    reasoning=ReasoningEffort.MEDIUM,
)
clear_chat
bool | None
default:"None"
Whether to clear chat context before executing the command.
clear_chat=True
generate_gif
bool | None
default:"None"
Whether to capture an animated GIF of the automation trajectory.
generate_gif=True
output_schema
type[BaseModel] | None
default:"None"
A Pydantic model class defining the expected structured response.
from pydantic import BaseModel, Field

class JobListing(BaseModel):
    title: str = Field(description="Job title")
    company: str = Field(description="Company name")
    location: str = Field(description="Job location")

response = await agent.run(
    prompt="Extract the first job listing.",
    output_schema=JobListing,
)
previous_request_id
str | None
default:"None"
The prior request ID to continue a conversation.
first = await agent.run(prompt="Pick a lucky number.")
second = await agent.run(
    prompt="What number did you pick?",
    previous_request_id=first.request_id,
)
attachment
File | IO[Any] | None
default:"None"
A file-like object to attach to the request. The SDK uploads the file automatically before dispatching the task.
with open("document.pdf", "rb") as f:
    response = await agent.run(
        prompt="Summarize the attached document.",
        attachment=f,
    )
time_zone
str
default:"America/Los_Angeles"
The time zone for time-related operations.
time_zone="America/New_York"
mcp_servers
list[McpServer] | None
default:"None"
MCP servers to connect during task execution.
from narada_core.models import AuthenticationNone, McpServer

mcp_server = McpServer(
    url="https://your-mcp-server.example.com",
    label="My MCP Server",
    description="Custom tools",
    authentication=AuthenticationNone(),
)

response = await agent.run(
    prompt="Use the MCP tools to process this data.",
    mcp_servers=[mcp_server],
)
secret_variables
dict[str, str] | None
default:"None"
Sensitive values substituted at action time. The LLM sees placeholders such as ${password}, not the actual values.
response = await agent.run(
    prompt="Log in with username ${username} and password ${password}.",
    secret_variables={
        "username": "john.doe@company.com",
        "password": "super_secret_password_123",
    },
)
input_variables
Mapping[str, Any] | None
default:"None"
Values passed into prompts using {{$variable_name}} syntax. File-like values are uploaded automatically.
response = await agent.run(
    prompt="Summarize {{$doc}}.",
    input_variables={"doc": file_obj},
)
callback_url
str | None
default:"None"
URL to call when the task status changes or completes. Use this with callback_secret or callback_headers to authenticate callbacks.
on_input_required
InputRequiredCallback | None
default:"None"
Callback invoked when a task enters an input-required state.
critic
CriticConfig | None
default:"None"
Optional critic configuration that validates the run after the main agent finishes.
timeout
int
default:"1000"
Maximum time in seconds to wait for task completion.
timeout=180

Response

Agent.run() returns an AgentResponse object:
request_id
str
Unique identifier for this request. Use it for debugging, callbacks, or conversation continuation.
status
str
Execution status: "success", "error", or "input-required".
text
str
The text response from the agent.
structured_output
BaseModel | None
Parsed structured data when output_schema is provided. Otherwise None.
output
TextOutput | StructuredOutput
Discriminated union containing either text or structured data:
{ type: "text", content: string }
| { type: "structured", content: object }
usage
AgentUsage
Usage metrics:
  • actions: Number of actions performed
  • credits: Credits consumed for the task
action_trace
ActionTrace | None
Detailed log of agent actions. See Action Trace for the trace format.
workflow_trace
dict | None
Workflow-level trace data when available.
critic_result
CriticResult | None
Result from the optional critic step.

Examples

import asyncio

from narada import Agent, BrowserEnvironment


async def main() -> None:
    env = BrowserEnvironment()
    agent = Agent(environment=env)

    try:
        response = await agent.run(
            prompt="Search for Python tutorials on Google and get the title of the first result",
        )

        print(f"Status: {response.status}")
        print(f"Result: {response.text}")
        print(f"Actions used: {response.usage.actions}")
    finally:
        await env.close()


if __name__ == "__main__":
    asyncio.run(main())

Best Practices

Reuse Environments

Create one environment and reuse it across multiple Agent instances when tasks should share a browser session.

Choose the Agent Kind

Use AgentKind.OPERATOR for browser automation and AgentKind.CORE_AGENT for read-only reasoning or conversation.

Use Structured Output

Define Pydantic schemas for consistent, typed responses from data extraction tasks.

Protect Sensitive Data

Use secret_variables for passwords, API keys, or personal information that should not be exposed to the LLM.

Pass Files Directly

Pass file-like objects with attachment= instead of calling a separate upload method.

Handle Timeouts

Set appropriate timeouts and call agent.reset_agent_state() before retrying after a timeout.

Migration from Older SDKs

Older SDK examples used a Narada client and window object:
async with Narada() as narada:
    window = await narada.open_and_initialize_browser_window()
    response = await window.agent(prompt='search for "jobs" on Google')
Use an environment and agent instead:
env = BrowserEnvironment()
agent = Agent(environment=env)

try:
    response = await agent.run(prompt='search for "jobs" on Google')
    print(response.text)
finally:
    await env.close()
For browser actions, call methods on agent:
await agent.go_to_url(url="https://example.com")
await agent.agentic_selector(
    action={"type": "click"},
    selectors={"aria_label": "Submit"},
    fallback_operator_query="click the Submit button",
)
For lifecycle and IDs, use the environment:
await env.start()
print(env.browser_window_id)
await env.close()