2.2 Constructor Reference
What you'll learn
- The smallest call that works: four parameters, or two with a pre-built
llm_client=- All 33 parameters on one map, grouped by what they configure
- The ones you'll typically pass in production (transport, permissions, MCP, …)
- The advanced injection surface for hosts that need full control
- The two factory paths (
Agentao(...)direct vs.build_from_environment(...)) and when to pick each
Two construction paths
| Path | When to use |
|---|---|
Agentao(...) directly | You want explicit control — no env / disk side effects at construction time. The body of this page covers this. |
agentao.embedding.build_from_environment(...) | Your host follows the same project-directory conventions as the CLI. Reads .env, permissions.json, mcp.json, memory roots and builds Agentao for you. See § Factory. |
| Situation | Use |
|---|---|
| A notebook or script that should behave like the CLI and read your local config | build_from_environment |
| A multi-tenant web app with one agent per request or tenant | Agentao(...) |
A container or sandbox that ships no .env | Agentao(...) |
| An IDE plugin whose host already owns the state | Agentao(...) |
| A test harness that needs reproducible runs | Agentao(...) |
Both produce an Agentao instance. They combine in one way: every Agentao keyword is also a factory override, and an override wins over what the factory discovers. So build_from_environment(working_directory=wd, permission_engine=my_engine) keeps the rest of the discovery and replaces only the engine. What does not work is a half-way mix: a direct Agentao(...) that tries to reproduce the factory's discovery by hand drifts from it on the next release.
All 33 parameters at a glance
Agentao.__init__ takes 33 parameters. Only working_directory has no default. The first five (api_key, base_url, model, temperature, max_tokens) may be passed by position; every other one is keyword-only. Below they are grouped by what they configure, so you can skip the groups you don't need.
| Group | Parameters | Covered in |
|---|---|---|
| Session root (required) | working_directory | Tier 1 |
| Model, raw settings | api_key, base_url, model (all three required without llm_client); temperature, max_tokens, api_format, extra_body, prompt_cache, prompt_cache_ttl | Tiers 1–3 |
| Model, pre-built | llm_client (replaces the whole raw-settings row; passing both raises ValueError) | Tier 2 |
| Permissions and interaction | transport, permission_mode or permission_engine, plan_session | Tiers 2–3 |
| Context and compaction | max_context_tokens, compaction_controller | Tiers 2–3 |
| Tools | extra_tools, disable_tools or enabled_tools | Tier 2 |
| MCP | mcp_manager, or extra_mcp_servers and mcp_registry (these two combine) | Tiers 2–3 |
| Prompt | project_instructions | Tier 2 |
| Bring your own object | logger, memory_manager, skill_manager, filesystem, shell | Tier 3 |
| Opt-in subsystems (off by default) | bg_store, sandbox_policy, replay_config, enable_builtin_agents | Tier 3 |
Parameters joined by or, and the two Model rows, are mutually exclusive: passing both sides raises ValueError; see Mutual-exclusion rules.
Tier 1 · The smallest call that works
Four parameters. Everything else has a default.
from pathlib import Path
from agentao import Agentao
agent = Agentao(
api_key="sk-...",
base_url="https://api.openai.com/v1",
model="gpt-5.4",
working_directory=Path("/tmp/my-session"),
)| Param | Type | Why |
|---|---|---|
api_key | str | LLM credential |
base_url | str | The endpoint: OpenAI, DeepSeek, a Gemini gateway, vLLM, … There is no built-in default |
model | str | Model id |
working_directory | Path | The session's project root. Frozen at construction — file / shell / memory all resolve against it |
Without llm_client=, leaving out any of api_key, base_url or model raises ValueError. A direct Agentao(...) reads no environment variables: OPENAI_API_KEY and the rest are read only by build_from_environment() (see Factory path). The other smallest call is Agentao(llm_client=my_client, working_directory=...), with the credentials on the client.
Don't skip working_directory
In a Web server / multi-tenant process, Path.cwd() is process-global — concurrent sessions would cross-contaminate. Since 0.3.0 the keyword is required; calls without it raise TypeError from Python signature dispatch.
Tier 2 · Common production params
These cover most production embeddings:
from agentao import Agentao
from agentao.transport import SdkTransport
from agentao.permissions import PermissionEngine, PermissionMode
engine = PermissionEngine(project_root=workdir)
engine.set_mode(PermissionMode.WORKSPACE_WRITE)
transport = SdkTransport(on_event=..., confirm_tool=..., ask_user=...)
agent = Agentao(
api_key="sk-...",
base_url="https://api.openai.com/v1",
model="gpt-5.4",
temperature=0.1,
working_directory=workdir,
transport=transport,
permission_engine=engine,
max_context_tokens=128_000,
extra_mcp_servers={...},
)PermissionEngine(project_root=workdir), with no rules= and no user_root=, loads no rule file: a <workdir>/.agentao/permissions.json is never loaded, only warned about. So the two engine lines above give the same rules as passing permission_mode="workspace-write" instead of permission_engine=engine. Build an engine yourself when you have rules for it: rules=[...], or user_root= to load <user_root>/permissions.json.
| Param | Type | Default | What it does |
|---|---|---|---|
max_tokens | int | None | None — the client's 65,536 | Per-call output cap |
temperature | float | None | None | Sampling temperature. None sends no temperature, so the provider's default applies (0.5.7; was 0.2) |
extra_body | Dict[str,Any] | None | Forwarded verbatim to the LLM .create() as the SDK's extra_body — the escape hatch for params the closed request build does not expose (reasoning_effort / top_p / seed / response_format / provider-specific fields). Keyword-only. Sub-agents inherit it; logged with credential keys redacted. Mutually exclusive with llm_client. See below |
api_format | str | "openai-completions" | The wire protocol spoken to base_url (0.5.0): "openai-completions", "anthropic-messages" (Anthropic's Messages API over the official SDK) or "openai-responses" (OpenAI's Responses API, 0.5.3). Keyword-only, configured and never inferred from the URL or the model name, changed afterwards only by set_provider(..., api_format=), inherited by sub-agents, and mutually exclusive with llm_client=. An unknown value raises ValueError. On anthropic-messages, base_url is the API root, temperature is not sent, and extended thinking goes through extra_body. Env equivalent: {PROVIDER}_API_FORMAT — see Appendix B |
transport | CoreTransport | NullTransport() | UI bridge: events + confirm + ask_user + max-iter fallback. See Part 4 |
permission_engine | PermissionEngine | None — no engine, no rule evaluated (build_from_environment builds one rooted at working_directory) | Rule-based gating; modes and set_permission_mode need one. See 5.4 |
permission_mode | str | None — builds nothing | "read-only" / "workspace-write" / "full-access" ("plan" is refused): builds PermissionEngine(project_root=working_directory, rules=[]) in that mode, reading no rule file, and starts in it without emitting an event. Mutually exclusive with permission_engine. See 5.4 |
max_context_tokens | int | 200_000 | Triggers conversation compression beyond this |
extra_mcp_servers | Dict[str,Dict] | None | Per-session MCP servers without touching .agentao/mcp.json. Same-name keys override. Useful for per-tenant tokens |
extra_tools | Sequence[Tool] | None | Inject / replace tools (instances; register last, same name overrides a built-in). See 5.1 |
disable_tools | Iterable[str] | None | Skip these built-ins by name (unknown name → ValueError). Mutually exclusive with enabled_tools |
enabled_tools | Iterable[str] | None | Allowlist of agentao-owned tools to keep; None=off, any iterable incl. set()=on. Mutually exclusive with disable_tools |
llm_client | LLMClient | (constructed from credentials) | Inject a pre-built client to fully control logger / log file. Mutually exclusive with every raw model setting: api_key / base_url / model / temperature / max_tokens / extra_body / prompt_cache / prompt_cache_ttl / api_format (a host with its own client passes them to that client) |
project_instructions | str | (read from <wd>/AGENTAO.md) | Pass AGENTAO.md content directly — skips the disk read |
Async hosts use arun()
agent.chat(...) is synchronous. Async hosts call await agent.arun(user_message), which runs the turn on Agentao's own worker pool, not on the event loop's default executor. Cancellation, replay, and max_iterations semantics are identical across both surfaces. Why the pool is separate, and what that means for sizing: 2.3 Async hosts.
Tier 3 · Advanced injections
Most embeddings never need these. Expand only what applies to you.
Capability protocols — filesystem, shell, mcp_registry, memory_manager
Four host→Agentao injection slots cover every IO surface tools touch. Replace any one to route IO through Docker exec, virtual filesystems, audit proxies, plugin-driven MCP discovery, or a remote memory backend. The defaults match Agentao's pre-0.2.16 byte-for-byte behavior.
| Slot | Protocol | Default | Bound at |
|---|---|---|---|
filesystem | FileSystem | LocalFileSystem | Tool registration → tool.filesystem on every file/search tool |
shell | ShellExecutor | LocalShellExecutor | Tool registration → tool.shell on the shell tool |
mcp_registry | MCPRegistry | None: reads <wd>/.agentao/mcp.json and ~/.agentao/mcp.json, the same files as the factory's FileBackedMCPRegistry | Agentao.__init__ reads list_servers() once during MCP init |
memory_manager (wraps MemoryStore) | MemoryStore | SQLiteMemoryStore under <wd>/.agentao/memory.db | Held on agent._memory_manager; the save_memory tool delegates here |
from agentao import Agentao
from agentao.host.protocols import FileSystem, ShellExecutor, MCPRegistry, MemoryStore
from agentao.memory import MemoryManager
agent = Agentao(
working_directory=workdir,
filesystem=MyDockerExecFileSystem(...), # FileSystem
shell=MyAuditingShellExecutor(...), # ShellExecutor
mcp_registry=MyPluginMCPRegistry(...), # MCPRegistry
memory_manager=MemoryManager( # MemoryStore wrapped in a manager
project_store=MyRedisMemoryStore(...),
),
)Always import the protocols from agentao.host.protocols (public surface). Default impls live in agentao.capabilities and agentao.memory. None for any slot means fall back to the local default, not disable; to disable a capability, inject an implementation that raises on call. For MCP, mcp_registry=InMemoryMCPRegistry() (from agentao.mcp) loads no servers at all.
Matching the method signatures is not the whole contract. FileSystem.write_text must replace an existing file atomically, so a process killed mid-write cannot leave the user's file truncated. A wrapper that delegates to LocalFileSystem gets this for free. A from-scratch implementation must stage the content and swap it in with one operation, as LocalFileSystem does with a sibling temp file and os.replace (host-api.md).
Runnable end-to-end example — examples/protocol-injection/
Replaces all four slots with small adapters (in-memory FS, audit-logging shell, dict-backed memory store, programmatic MCP registry) and asserts each one is consulted via 6 smoke tests. No OPENAI_API_KEY required. Run with uv sync --extra dev && PYTHONPATH=. uv run pytest tests/.
Multi-tenant FS isolation: 6.4. :::
Memory / Skills / MCP managers — memory_manager, skill_manager, mcp_manager, mcp_registry
Inject pre-built managers when you don't want Agentao to construct them from defaults — typically because the manager is shared across many sessions, or you want programmatic config rather than disk lookups.
| Param | Replaces |
|---|---|
memory_manager | The default MemoryManager opening <wd>/.agentao/memory.db. Yours to close: agent.close() leaves it open |
skill_manager | The bundled-skill auto-discovery scan |
mcp_manager | .agentao/mcp.json discovery + lifecycle. Yours to disconnect: agent.close() leaves it connected. Mutually exclusive with extra_mcp_servers= and mcp_registry= |
mcp_registry | load_mcp_config(...) source. Use InMemoryMCPRegistry for programmatic registration. Mutually exclusive with mcp_manager= |
Opt-in subsystems — bg_store, sandbox_policy, replay_config, enable_builtin_agents
Default is None (or False) = fully disabled. Pay zero cost if you don't use them.
| Param | When None |
|---|---|
bg_store | Background-task tools (check_background_agent, cancel_background_agent) are not registered; sub-agent tool schemas drop the run_in_background field; /agent bg|dashboard|cancel|delete|logs|result CLI subcommands no-op with a warning |
sandbox_policy | Shell runs without macOS sandbox-exec wrapper. The policy wraps only run_shell_command, only on macOS, and only when ~/.agentao/sandbox.json sets enabled: true (a <wd>/.agentao/sandbox.json is ignored); it does not restrict the file tools (sandbox/policy.py) |
enable_builtin_agents (False) | The built-in sub-agents (codebase-investigator, generalist) are not registered as delegation tools. The factory reads agents.enable_builtin from settings.json |
replay_config | The replay block of <wd>/.agentao/settings.json is not read at construction; no ReplayManager is attached until start_replay() / reload_replay_config() creates one. start_replay() alone creates it with replay off (it returns None); reload_replay_config() reads that block but starts nothing: a start_replay() after it records only if the block has enabled true |
With a value set:
bg_storeenables background sub-agents.BackgroundTaskStore(persistence_dir=wd)keeps its records in<wd>/.agentao/background_tasks.json. After a restart, a task that was still running is markedfailed: the record survives, the work does not. At mostmax_concurrentrun at once (default 6,Nonefor no cap), and a launch past that is refused, not queued. Leave itNonein a one-shot process, asagentao rundoes, because the workers are daemon threads that die at exit.close()cancels the tasks this agent launched. Details: Appendix A.1.replay_configrecords to<wd>/.agentao/replays/*.jsonlonly after the host callsagent.start_replay(). The CLI and ACP do this per session. Neither the factory norAgentao(...)does. Replay records a session; it does not re-run one (6.6).
Logger injection — logger
Pass logger=app.logger to skip Agentao's package-root level / handler mutation in LLMClient.__init__. Your logging stack stays untouched, and the default rolling <wd>/agentao.log file is not created (the file-handler branch is skipped along with the rest of the mutation).
To control the file-handler axis independently, build LLMClient yourself and pass log_file=None (skip file) or log_file="custom.log" (redirect). Note: passing only log_file=None without logger= still elevates getLogger("agentao") to DEBUG. See 6.6 Observability → Take over Agentao's logger for the full matrix and a fully-silent recipe.
LLM request passthrough — extra_body
Agentao builds the OpenAI-compatible request from a closed set of fields (model / messages / temperature / tools / max_tokens). When you need a param that set does not expose — reasoning_effort, top_p, seed, response_format, or any provider-specific body field (top_k, repetition_penalty, vendor extensions) — pass extra_body. It is forwarded verbatim to the SDK's .create(extra_body=...), which merges it into the JSON request body, bypassing the typed signature.
agent = Agentao(
api_key="sk-...",
base_url="https://api.openai.com/v1",
model="gpt-5.4",
working_directory=workdir,
extra_body={"reasoning_effort": "high", "seed": 7},
)- Keyword-only. Unlike
api_key/temperature,extra_bodyis declared after*, so it never shifts the legacy positional arguments. - The host owns the values. Agentao does not validate them — the SDK / provider does. You are configuring your own endpoint, so this is not third-party proxying.
- Sub-agents inherit it, the same way they inherit
temperature/max_tokens. - No auto-recovery on model switch. Unlike
temperature(which auto-drops when a model rejects it), a staleextra_bodykey — e.g.reasoning_effortafter switching to a non-reasoning model — makes every later call 400 until you clear it. Dropping model-specific keys on switch is the host's responsibility. - Logged with credentials redacted. If
extra_bodynests credential-like keys (api_key,authorization,x-api-key, …), their values are masked (***) inagentao.log. - CLI / factory path: set the
LLM_EXTRA_BODYenv var to a JSON object (e.g.LLM_EXTRA_BODY='{"reasoning_effort":"high"}'). Malformed or non-object values warn and are skipped; empty is treated as unset. See Appendix B. - Mutually exclusive with
llm_client=. A host injecting its ownLLMClientpassesextra_body=to that client's constructor instead.
extra_headers and a settings.json file layer are intentionally deferred; see docs/design/host-llm-extra-params.md.
Rarely set — prompt_cache, prompt_cache_ttl, compaction_controller, plan_session
| Param | Default | What it does |
|---|---|---|
prompt_cache | None (off) | "anthropic" puts explicit prompt-cache breakpoints on each request (at most 3). Off by default because endpoint support is not verified. Never inferred from the URL or model name. Env equivalent: LLM_PROMPT_CACHE, read only by the factory |
prompt_cache_ttl | None (provider default, "5m") | "5m" or "1h". Ignored while prompt_cache is off. Env equivalent: LLM_PROMPT_CACHE_TTL |
compaction_controller | None | A synchronous callable that allows, cancels, or supplies the summary for a compaction. Fail-open: a raise counts as allow. See host-api.md |
plan_session | None (a fresh PlanSession) | Plan-mode state. The CLI passes its own; an embedded host normally leaves it alone |
The 8 legacy callbacks (removed in 0.5.0)
Pre-0.2.10 API. They warned through 0.4.x and are no longer parameters: passing one raises TypeError. Either go through Transport, or keep the callbacks and wrap them — agentao.embedding.compat.build_compat_transport(...) takes the same eight names and is not deprecated: Agentao(transport=build_compat_transport(confirmation_callback=...), ...).
| Removed param | Replacement |
|---|---|
confirmation_callback | SdkTransport(confirm_tool=...) |
step_callback | on_event= + TOOL_START / TURN_START |
thinking_callback | on_event= + THINKING |
ask_user_callback | SdkTransport(ask_user=...) |
output_callback | on_event= + TOOL_OUTPUT |
tool_complete_callback | on_event= + TOOL_COMPLETE |
llm_text_callback | on_event= + LLM_TEXT |
on_max_iterations_callback | SdkTransport(on_max_iterations=...) |
⚠️ Only the first five parameters are positional (api_key, base_url, model, temperature, max_tokens). The callbacks used to sit between max_context_tokens, permission_engine, transport and plan_session, so those four are keyword-only now — a call still passing a callback sixth is a TypeError, not a silent re-binding. Full guide: docs/migration/0.4.x-to-0.5.0.md.
Mutual-exclusion rules
Violating any of these raises ValueError at construction:
| Cannot combine | Reason |
|---|---|
llm_client= + any of api_key / base_url / model / temperature / max_tokens / extra_body / prompt_cache / prompt_cache_ttl / api_format | The injected client is already the credential source — pass those to that client directly instead |
mcp_manager= + extra_mcp_servers= | Per-session merge needs a manager Agentao constructs |
mcp_manager= + mcp_registry= | Registry is the config source; manager is the construction outcome |
permission_engine= + permission_mode= | One is an engine, the other builds one — set the mode on your engine, or call set_permission_mode() after construction |
Factory path: build_from_environment()
When your host follows CLI conventions (project-rooted .env, .agentao/ configs, memory dirs):
from pathlib import Path
from agentao.embedding import build_from_environment
agent = build_from_environment(
working_directory=Path("/data/tenant-acme"),
transport=my_transport,
max_context_tokens=128_000,
)What it does, in order (embedding/factory.py):
| # | Step | If it goes wrong |
|---|---|---|
| 1 | Resolves working_directory to an absolute path and freezes it. Omitted, it is Path.cwd(), which an embedded host should not rely on | — |
| 2 | Reads <wd>/.agentao/settings.json for factory toggles such as agents.enable_builtin | A malformed file is logged and ignored |
| 3 | Loads <wd>/.env into os.environ. Without one, it loads the nearest .env from the process cwd upward. A non-empty variable already in the environment wins | — |
| 4 | Reads the LLM settings from LLM_PROVIDER (default OPENAI) and {PROVIDER}_API_KEY / _BASE_URL / _MODEL / _API_FORMAT, plus LLM_TEMPERATURE, LLM_MAX_TOKENS, LLM_EXTRA_BODY, LLM_PROMPT_CACHE, LLM_PROMPT_CACHE_TTL. Skipped when you pass llm_client= | A non-numeric LLM_TEMPERATURE / LLM_MAX_TOKENS raises. A bad LLM_EXTRA_BODY is warned about and skipped |
| 5 | Reads ~/.agentao/permissions.json and builds PermissionEngine(project_root=wd, user_root=~/.agentao) with its rules. Its shell block picks the shell executor | Fails closed: a file that exists but is unreadable or invalid raises PermissionConfigError. Dropping it would turn a deny rule into an ask, or into no prompt at all for an mcp_* tool. <wd>/.agentao/permissions.json is never loaded, only warned about |
| 6 | Wires the opt-in subsystems: BackgroundTaskStore(persistence_dir=wd), SandboxPolicy(project_root=wd), replay_config from the replay block of settings.json, and enable_builtin_agents from step 2 | A malformed replay block means no replay |
| 7 | Uses FileBackedMCPRegistry(project_root=wd, user_root=~/.agentao) unless you pass mcp_registry= or mcp_manager= | — |
| 8 | Opens memory: the project store at <wd>/.agentao/memory.db and the user store at ~/.agentao/memory.db | The project store falls back to an in-memory database. If the user store cannot be opened, the session has none: existing user memories are not read, and a new user-scope write is saved to the project store, with a log entry (5.5) |
| 9 | Calls Agentao(...) with all of the above as explicit keywords. Your overrides win over everything discovered | If construction raises, the factory closes the memory stores it opened |
An explicit None for bg_store, sandbox_policy or replay_config disables that subsystem. permission_mode= is applied to the engine from step 5, so the user's rules stay. The CLI and ACP session/new build their agents through this factory.
What reads the environment. The factory does the CLI-style discovery at construction in one place: environment variables, .env, permissions.json, settings.json and sandbox.json. A direct Agentao(...) skips that discovery, but it still touches some files under its defaults:
| Default | Reads | To avoid it, pass |
|---|---|---|
project_instructions=None | <wd>/AGENTAO.md | project_instructions= |
skill_manager=None | ~/.agentao/skills/, <wd>/.agentao/skills/, <wd>/skills/, <wd>/.agentao/skills_config.json. It also copies the bundled skills into ~/.agentao/skills/ on first run | skill_manager= |
memory_manager=None | Opens <wd>/.agentao/memory.db (project scope only) | memory_manager= |
mcp_registry=None | <wd>/.agentao/mcp.json and ~/.agentao/mcp.json | mcp_registry= or mcp_manager= |
logger=None (with llm_client=None) | Creates and writes <wd>/agentao.log | logger= or llm_client= (6.6) |
With all five passed, constructing the agent creates no file. That covers construction only: a turn can still write, for example a replay, a tool output spilled to .agentao/tool-outputs/, or what the tools themselves do.
Full production template
from pathlib import Path
import os
from agentao import Agentao
from agentao.transport import SdkTransport
from agentao.permissions import PermissionEngine, PermissionMode
def make_agent_for_session(
tenant_id: str,
tenant_workdir: Path,
tenant_token: str,
on_event,
confirm_tool,
) -> Agentao:
engine = PermissionEngine(project_root=tenant_workdir)
engine.set_mode(PermissionMode.WORKSPACE_WRITE)
transport = SdkTransport(
on_event=on_event,
confirm_tool=confirm_tool,
on_max_iterations=lambda n, _msgs: {"action": "stop"},
)
return Agentao(
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ["OPENAI_BASE_URL"],
model="gpt-5.4",
temperature=0.1,
transport=transport,
working_directory=tenant_workdir,
max_context_tokens=128_000,
permission_engine=engine,
extra_mcp_servers={
"gh": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_TOKEN": tenant_token},
},
},
)Or, if your host already follows CLI conventions:
from agentao.embedding import build_from_environment
agent = build_from_environment(
working_directory=tenant_workdir,
transport=transport,
max_context_tokens=128_000,
)Version note
- 0.5.0 — The 8 legacy callback kwargs (
confirmation_callback,step_callback,thinking_callback,ask_user_callback,output_callback,tool_complete_callback,llm_text_callback,on_max_iterations_callback) were removed from theAgentao(...)signature, and every parameter aftermax_tokensbecame keyword-only. Usetransport=SdkTransport(...), or wrap the old callbacks withagentao.embedding.compat.build_compat_transport(...). - 0.4.x — The 8 legacy callbacks emitted a single
DeprecationWarningper construction (from 0.4.5). - 0.3.4 — Capability protocols (
FileSystem,ShellExecutor) re-exported onagentao.host.protocols. Always import from there, not internalagentao.capabilities.*. - 0.3.0 —
working_directory=became a required keyword (calls without it raiseTypeError).mcp_registry=introduced as a stable config-source surface; defaultFileBackedMCPRegistrymatches the pre-#17 disk read. - 0.2.16 — Explicit-injection surface added (
memory_manager,skill_manager,mcp_manager,filesystem,shell, …);replay_config,sandbox_policy,bg_storedefaulted toNone. - 0.2.10 — Decoupled core runtime; the 8 legacy callbacks remain accepted via
build_compat_transport().
Upgrading from 0.2.15: docs/migration/0.2.15-to-0.3.3.md.
TL;DR
- 33 parameters, one required:
working_directory(Path, frozen at construction). The map above groups the rest by purpose. - Smallest working call:
api_key+base_url+model+working_directory, orllm_client+working_directory. A directAgentao(...)reads no environment variables. - Typical production additions:
transport,permission_mode(orpermission_engine),max_context_tokens,extra_mcp_servers,project_instructions,temperature. - Everything else is opt-in or advanced — capability protocols, custom managers, prompt caching, compaction control, sandbox / replay / background / sub-agent subsystems.
- Two factories:
build_from_environment()for CLI conventions; directAgentao(...)for explicit control. To change one part of the factory's result, pass that keyword to the factory as an override.
→ Next: 2.3 Lifecycle