Skip to main content
This page is the public import contract for application developers. Use these imports in docs, examples, tests that exercise public behavior, and downstream applications. For field-by-field configuration, see Configuration Reference. For generated module detail, see Full Module Reference.

Import map

TaskPublic import
Define an agentfrom afk.agents import Agent
Configure fail-safe limitsfrom afk.agents import FailSafeConfig
Configure policy rulesfrom afk.agents import PolicyEngine, PolicyRule
Implement dynamic policy hooksfrom afk.agents import PolicyRole
Run an agentfrom afk.core import Runner
Configure the runnerfrom afk.core import RunnerConfig
Consume streaming eventsfrom afk.core import AgentStreamEvent, AgentStreamHandle
Define a toolfrom afk.tools import tool
Access tool contextfrom afk.tools import ToolContext
Build an LLM clientfrom afk.llms import LLMBuilder
Run eval suitesfrom afk.evals import run_suite
Define eval casesfrom afk.evals import EvalCase, EvalBudget
Create memory storesfrom afk.memory import InMemoryMemoryStore, SQLiteMemoryStore
Create task queuesfrom afk.queues import InMemoryTaskQueue, RedisTaskQueue, TaskWorker
Expose MCP toolsfrom afk.mcp import MCPServer
Use A2A messagingfrom afk.messaging import InternalA2AProtocol
Do not use src.afk.* imports in user-facing docs.

Agent

from afk.agents import Agent

agent = Agent(
    *,
    model: str | LLM,
    name: str | None = None,
    tools: list | None = None,
    subagents: list[Agent] | None = None,
    instructions: str | callable | None = None,
    instruction_file: str | Path | None = None,
    prompts_dir: str | Path | None = None,
    context_defaults: dict | None = None,
    inherit_context_keys: list[str] | None = None,
    model_resolver: callable | None = None,
    skills: list[str] | None = None,
    mcp_servers: list | None = None,
    skills_dir: str | Path = ".agents/skills",
    instruction_roles: list | None = None,
    policy_roles: list | None = None,
    policy_engine: PolicyEngine | None = None,
    subagent_router: callable | None = None,
    max_steps: int = 20,
    tool_parallelism: int | None = None,
    subagent_parallelism_mode: str = "configurable",
    fail_safe: FailSafeConfig | None = None,
    reasoning_enabled: bool | None = None,
    reasoning_effort: str | None = None,
    reasoning_max_tokens: int | None = None,
    skill_tool_policy: SkillToolPolicy | None = None,
    enable_mcp_tools: bool = True,
    enable_skill_tools: bool = True,
    runner: Runner | None = None,
)
Only model is required. Most examples should also set name and instructions for clear traces and predictable behavior.

Runner

from afk.core import Runner, RunnerConfig

runner = Runner(
    memory_store=None,
    interaction_provider=None,
    policy_engine=None,
    telemetry=None,
    telemetry_config=None,
    config=RunnerConfig(),
)
Common methods:
MethodUse whenReturns
runner.run_sync(agent, user_message=..., thread_id=...)Scripts, CLIs, tests without an existing event loopAgentResult
await runner.run(agent, user_message=..., thread_id=...)Async services, workers, APIsAgentResult
await runner.run_stream(agent, user_message=..., thread_id=...)Chat UIs and progress streamsAgentStreamHandle
await runner.resume(agent, run_id=..., thread_id=..., context=...)Continue from persisted stateAgentResult
await runner.compact_thread(thread_id=...)Apply memory retention/compactionMemoryCompactionResult
run_sync() is a convenience wrapper for synchronous code. Use await runner.run(...) inside async applications.

RunnerConfig

from afk.core import RunnerConfig

config = RunnerConfig(
    interaction_mode="headless",
    approval_timeout_s=300.0,
    input_timeout_s=300.0,
    approval_fallback="deny",
    input_fallback="deny",
    sanitize_tool_output=True,
    untrusted_tool_preamble=True,
    tool_output_max_chars=12_000,
    max_parallel_subagents_global=64,
    max_parallel_subagents_per_parent=8,
    max_parallel_subagents_per_target_agent=4,
    checkpoint_async_writes=True,
    debug=False,
    background_tools_enabled=True,
)
Use Configuration Reference for the complete set of runner fields and defaults.

FailSafeConfig

from afk.agents import FailSafeConfig

fail_safe = FailSafeConfig(
    llm_failure_policy="retry_then_fail",
    tool_failure_policy="continue_with_error",
    subagent_failure_policy="continue",
    approval_denial_policy="skip_action",
    max_steps=20,
    max_wall_time_s=300.0,
    max_llm_calls=50,
    max_tool_calls=200,
    max_parallel_tools=16,
    max_subagent_depth=3,
    max_total_cost_usd=None,
    fallback_model_chain=[],
)
Set max_total_cost_usd for production agents. The default is intentionally unset because acceptable budgets vary by application.

Tool decorator

from pydantic import BaseModel

from afk.tools import tool


class SearchArgs(BaseModel):
    query: str


@tool(args_model=SearchArgs, name="search", description="Search by query.")
def search(args: SearchArgs) -> dict:
    return {"query": args.query, "results": []}
Tool functions may be sync or async. They may accept (args), (args, ctx), or (ctx, args).

AgentResult

result = Runner().run_sync(agent, user_message="Hello")

print(result.final_text)
print(result.state)
print(result.run_id)
print(result.thread_id)
print(result.tool_executions)
print(result.subagent_executions)
print(result.usage_aggregate.total_tokens)
print(result.total_cost_usd)
Important fields:
FieldMeaning
final_textFinal assistant text
stateTerminal run state
requested_modelModel requested by the caller or agent
normalized_modelEffective normalized model when available
provider_adapterProvider/adapter used when available
tool_executionsOrdered tool execution records
subagent_executionsOrdered subagent execution records
usage_aggregateAggregated input/output/total tokens
total_cost_usdEstimated total cost when available
state_snapshotTerminal runtime snapshot payload

API stability

  • Public docs and examples should use imports from afk.agents, afk.core, afk.tools, afk.llms, afk.memory, afk.queues, afk.mcp, afk.messaging, afk.observability, and afk.evals.
  • Internal modules under package subdirectories may change faster than public exports.
  • When changing public exports, update this page, Public API Rules, examples, and generated agent-facing docs.