Documentation Index
Fetch the complete documentation index at: https://afk.arpan.sh/llms.txt
Use this file to discover all available pages before exploring further.
Use afk.debugger.Debugger to run agents in a structured debug mode without changing your core runtime architecture.
Quick start
from afk.debugger import Debugger, DebuggerConfig
debugger = Debugger(
DebuggerConfig(
verbosity="detailed",
redact_secrets=True,
include_content=True,
)
)
runner = debugger.runner()
You can also enable debug mode directly on the runner:
from afk.core import Runner, RunnerConfig
runner = Runner(config=RunnerConfig(debug=True))
Attach to a run handle
handle = await runner.run_handle(agent, user_message="inspect this run")
await debugger.attach(handle) # prints formatted events
Redaction behavior
When redact_secrets=True, payload keys containing any of these markers are masked:
api_key
token
secret
authorization
password
Verbosity modes
basic: lightweight metadata and step markers.
detailed: includes payload previews and step metadata.
trace: highest detail for deep diagnostics.
from afk.tools import tool, ToolResult, ToolDeferredHandle
@tool(args_model=BuildArgs, name="build_project")
async def build_project(args: BuildArgs) -> ToolResult[dict[str, str]]:
future = asyncio.create_task(run_long_build(args.path))
return ToolResult(
success=True,
deferred=ToolDeferredHandle(
ticket_id="build-123",
tool_name="build_project",
status="running",
summary="Build started",
resume_hint="Continue documentation while build runs",
),
metadata={"background_task": future},
)
Flow:
- Agent writes code.
- Agent calls
build_project and receives tool_deferred.
- Agent continues with
write_docs or other tasks.
- Runner emits
tool_background_resolved when build completes.
- Agent uses resolved build output in a later step to finalize/fix.
External worker completion
For out-of-process execution, an external worker can complete a ticket by
writing background state into memory:
await memory.put_state(
thread_id,
f"bgtool:{run_id}:{ticket_id}:state",
{
"run_id": run_id,
"thread_id": thread_id,
"ticket_id": ticket_id,
"tool_name": "build_project",
"status": "completed", # or "failed"
"output": {"status": "ok", "artifact": "dist/app"},
"error": None,
},
)
The runner poller detects this update, emits tool_background_resolved or
tool_background_failed, and injects a synthetic tool message for the next step.