Skip to content
8 changes: 7 additions & 1 deletion skills/afk-coder/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ Read these files for detailed API references. Recommended order:
| 6 | [security-and-policies.md](./references/security-and-policies.md) | PolicyEngine, SandboxProfile, SkillToolPolicy, fail-safe |
| 7 | [multi-agent-and-delegation.md](./references/multi-agent-and-delegation.md) | Subagents, DelegationPlan, A2A protocol, MCP |
| 8 | [evals-and-testing.md](./references/evals-and-testing.md) | EvalCase, EvalSuite, assertions, budgets, testing patterns |
| 9 | [cookbook-examples.md](./references/cookbook-examples.md) | 11 complete runnable examples |
| 9 | [debugger.md](./references/debugger.md) | Debugger, DebuggerConfig, debug instrumentation |
| 10 | [queues.md](./references/queues.md) | TaskQueue, TaskWorker, retry policies |
| 11 | [environment-variables.md](./references/environment-variables.md) | All AFK_* env vars, loading from .env |
| 12 | [cookbook-examples.md](./references/cookbook-examples.md) | 11 complete runnable examples |

## Architecture

Expand Down Expand Up @@ -180,11 +183,14 @@ Key source files for implementation details:
| Memory store | `src/afk/memory/store.py` |
| Memory factory | `src/afk/memory/factory.py` |
| Memory backends | `src/afk/memory/adapters/` |
| Memory lifecycle | `src/afk/memory/lifecycle.py` |
| Streaming | `src/afk/core/streaming.py` |
| Interaction | `src/afk/core/interaction.py` |
| Policy engine | `src/afk/agents/policy/engine.py` |
| Delegation | `src/afk/core/runtime/dispatcher.py` |
| Evals | `src/afk/evals/` |
| Debugger | `src/afk/debugger/` |
| Queues | `src/afk/queues/` |
| MCP server | `src/afk/mcp/server/` |
| A2A protocol | `src/afk/agents/a2a/` |

Expand Down
21 changes: 19 additions & 2 deletions skills/afk-coder/references/agents-and-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,28 @@ defaults. Pass it to `Runner(config=RunnerConfig(...))`.
| `sanitize_tool_output` | `bool` | `True` | Sanitize tool output before forwarding to the model |
| `untrusted_tool_preamble` | `bool` | `True` | Inject untrusted-data warning preamble into tool results |
| `tool_output_max_chars` | `int` | `12_000` | Max characters of tool output forwarded to model |
| `default_sandbox_profile` | `SandboxProfile \| None` | `None` | Default sandbox profile for tool execution |
| `sandbox_profile_provider` | `SandboxProfileProvider \| None` | `None` | Runtime sandbox profile resolver |
| `secret_scope_provider` | `SecretScopeProvider \| None` | `None` | Secret injector per tool call |
| `default_allowlisted_commands` | `tuple[str, ...]` | `(ls, cat, head, tail, rg, pwd, echo)` | Allowed shell commands |
| `max_parallel_subagents_global` | `int` | `64` | Global cap for concurrently executing subagent tasks |
| `max_parallel_subagents_per_parent` | `int` | `8` | Per-parent-run cap for concurrent subagent fanout |
| `max_parallel_subagents_per_target_agent` | `int` | `4` | Per-target-agent cap under broad fanout |
| `subagent_queue_backpressure_limit` | `int` | `512` | Max pending subagent nodes before backpressure |
| `checkpoint_async_writes` | `bool` | `True` | Enable asynchronous checkpoint/state writes |
| `checkpoint_queue_maxsize` | `int` | `1024` | Maximum queued checkpoint writes |
| `checkpoint_flush_timeout_s` | `float` | `10.0` | Timeout for terminal checkpoint flush |
| `checkpoint_coalesce_runtime_state` | `bool` | `True` | Coalesce runtime-state writes by key |
| `debug` | `bool` | `False` | Enable debug instrumentation for run events |
| `debug_config` | `RunnerDebugConfig \| None` | `None` | Advanced debug settings |
| `background_tools_enabled` | `bool` | `True` | Allow tools to be deferred into background execution |
| `max_parallel_subagents_global` | `int` | `64` | Global cap for concurrently executing subagent tasks |
| `max_parallel_subagents_per_parent` | `int` | `8` | Per-parent-run cap for concurrent subagent fanout |
| `background_tool_default_grace_s` | `float` | `0.0` | Grace window before backgrounding |
| `background_tool_max_pending` | `int` | `256` | Max unresolved background tools per run |
| `background_tool_poll_interval_s` | `float` | `0.5` | Poll interval for persisted tool state |
| `background_tool_result_ttl_s` | `float` | `3600.0` | TTL for pending background tool tickets |
| `background_tool_interrupt_on_resolve` | `bool` | `True` | Hint loop wake-up on resolution |

`RunnerConfig` also has a `from_env()` class method that loads configuration from environment variables.

---

Expand Down
72 changes: 34 additions & 38 deletions skills/afk-coder/references/cookbook-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,8 @@ print(result2.final_text) # "Your name is Alice and you love Python."
Sandbox profiles, tool output limits, and fail-safe settings.

```python
from afk.agents import Agent, Runner
from afk.agents.types import FailSafeConfig
from afk.core.runner import RunnerConfig
from afk.agents import Agent, Runner, FailSafeConfig
from afk.core import RunnerConfig
from afk.tools.security import SandboxProfile

sandbox = SandboxProfile(
Expand Down Expand Up @@ -230,9 +229,9 @@ agent = Agent(
tools=[...],
max_steps=10,
fail_safe=FailSafeConfig(
max_consecutive_errors=3,
max_total_errors=5,
max_empty_responses=2,
max_steps=10,
max_wall_time_s=60.0,
max_total_cost_usd=0.50,
),
)

Expand Down Expand Up @@ -287,11 +286,9 @@ See [llm-configuration.md](./llm-configuration.md) for profiles, routing, and en
Interactive approval flow for sensitive operations.

```python
from afk.agents import Agent, Runner
from afk.agents.policy import PolicyRule, PolicyRuleCondition, PolicyEngine
from afk.agents import Agent, Runner, PolicyRule, PolicyRuleCondition, PolicyEngine
from afk.agents.types import ApprovalDecision
from afk.core.interaction import InteractionProvider
from afk.core.runner import RunnerConfig
from afk.core import InteractionProvider, RunnerConfig

class TerminalApprovalProvider:
"""Simple terminal-based approval provider."""
Expand Down Expand Up @@ -345,43 +342,42 @@ result = runner.run_sync(agent, user_message="Clean up old records")
Automated evaluation of agent behavior.

```python
from afk.evals import EvalCase, EvalSuite, BudgetConfig
from afk.agents import Agent
from afk.evals import (
EvalCase,
EvalSuiteConfig,
EvalBudget,
StateCompletedAssertion,
FinalTextContainsAssertion,
arun_suite,
)

cases = [
EvalCase(
case_id="greeting",
input="Hello!",
expected_output="friendly greeting",
assertions=[
{"type": "contains", "value": "hello", "case_insensitive": True},
],
tags=["basic"],
name="greeting",
agent=Agent(model="gpt-4.1-mini", instructions="Greet the user."),
user_message="Say hello",
),
EvalCase(
case_id="math",
input="What is 15 * 7?",
expected_output="105",
assertions=[
{"type": "contains", "value": "105"},
],
tags=["tools"],
name="math",
agent=Agent(model="gpt-4.1-mini", instructions="Answer math questions."),
user_message="What is 15 * 7?",
),
]

suite = EvalSuite(
suite_id="agent-v1",
result = await arun_suite(
runner_factory=None, # or pass Runner class
cases=cases,
budget=BudgetConfig(
max_steps=5,
timeout_s=30.0,
max_cost_usd=0.10,
config=EvalSuiteConfig(
assertions=(
StateCompletedAssertion(),
FinalTextContainsAssertion("hello", name="contains_greeting"),
),
),
)

# Run evaluation (pseudo code -- see evals reference for full API)
results = await suite.run(agent=agent, runner=runner)
for r in results:
print(f"{r.case_id}: {'PASS' if r.passed else 'FAIL'}")
print(f"Passed: {result.passed}/{result.total}")
for row in result.results:
print(f" {row.case}: {'PASS' if row.passed else 'FAIL'}")
```

See [evals-and-testing.md](./evals-and-testing.md) for assertions, scorers, and datasets.
Expand All @@ -395,8 +391,8 @@ Long-running tools that execute in the background.
```python
import uuid
from pydantic import BaseModel
from afk.agents import Agent, Runner
from afk.core.runner import RunnerConfig
from afk.agents import Agent
from afk.core import Runner, RunnerConfig
from afk.tools import tool, ToolResult, ToolDeferredHandle

class ReportArgs(BaseModel):
Expand Down
135 changes: 135 additions & 0 deletions skills/afk-coder/references/debugger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Debugger

AFK debugger module: Debug instrumentation, payload redaction, and run event enrichment.

- Doc page: https://afk.arpan.sh/library/debugger
- Source: `src/afk/debugger/`
- Cross-refs: `agents-and-runner.md`

---

## Overview

The `Debugger` module provides debug instrumentation for agent runs, including:
- Debug metadata enrichment and formatting hooks
- Payload redaction for sensitive data
- Verbosity levels for different detail amounts

Key public imports:

```python
from afk.debugger import Debugger, DebuggerConfig
```

---

## DebuggerConfig

Configuration for debugger formatting and payload redaction.

```python
from afk.debugger import DebuggerConfig

config = DebuggerConfig(
enabled=True,
verbosity="detailed",
include_content=True,
redact_secrets=True,
max_payload_chars=4000,
emit_timestamps=True,
emit_step_snapshots=True,
)
```

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `enabled` | `bool` | `True` | Enable debug metadata enrichment |
| `verbosity` | `str` | `"detailed"` | Detail level: `"basic"`, `"detailed"`, or `"trace"` |
| `include_content` | `bool` | `True` | Include event/tool/message content in debug payloads |
| `redact_secrets` | `bool` | `True` | Redact sensitive keys from debug payload |
| `max_payload_chars` | `int` | `4000` | Truncate debug payload fields to this length |
| `emit_timestamps` | `bool` | `True` | Attach timestamp metadata to debug payloads |
| `emit_step_snapshots` | `bool` | `True` | Emit summarized per-step snapshot metadata |

---

## Debugger

The `Debugger` class provides a facade for creating configured `Runner` instances with debug instrumentation.

```python
from afk.debugger import Debugger, DebuggerConfig

# Create debugger with custom config
debugger = Debugger(
DebuggerConfig(
enabled=True,
verbosity="detailed",
redact_secrets=True,
)
)

# Get a debug-configured runner
runner = debugger.runner()

# Or access the RunnerConfig directly
config = debugger.config()
```

### Debugger Constructor

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `config` | `DebuggerConfig \| None` | `None` | Debug configuration |

### Debugger Methods

| Method | Returns | Description |
|--------|---------|-------------|
| `runner(config=None)` | `Runner` | Create a runner with debug instrumentation |
| `config()` | `RunnerConfig` | Get the debug-configured RunnerConfig |

---

## Usage with Runner

The debugger can be used to wrap runner creation with debug settings:

```python
from afk.debugger import Debugger, DebuggerConfig
from afk.agents import Agent

debugger = Debugger(
DebuggerConfig(
enabled=True,
verbosity="detailed",
redact_secrets=True,
)
)

runner = debugger.runner()
agent = Agent(model="gpt-4.1-mini", instructions="You are helpful.")

result = runner.run_sync(
agent,
user_message="Hello",
thread_id="debug-thread",
)
```

---

## Source Files

| File | Purpose |
|------|---------|
| `src/afk/debugger/__init__.py` | Public API exports |
| `src/afk/debugger/core.py` | `Debugger` implementation |
| `src/afk/debugger/types.py` | `DebuggerConfig` dataclass |

---

## Cross-References

- **Runner API**: See [agents-and-runner.md](./agents-and-runner.md) for `RunnerConfig.debug` and `RunnerConfig.debug_config`
- **Tools**: See [tools-system.md](./tools-system.md) for debugging tools
Loading
Loading