nanobot source and test index
This index is organized by learning question, not by mechanically listing directories. Paths are relative to example/nanobot/code-EN.
Entry points and the core Turn
| Question | Source anchor | Tests to read first | Explanation |
|---|---|---|---|
| How does CLI start one chat request? | nanobot/cli/commands.py::agent | tests/cli/test_commands.py | Five entry points and runtime boundaries |
| How does Gateway assemble persistent services? | nanobot/cli/gateway.py, nanobot/gateway/runtime.py | tests/gateway/test_runtime.py, tests/cli/test_gateway_commands.py | Channels and Gateway |
| How does the HTTP API enter the Agent? | nanobot/api/server.py::create_app, handle_chat_completions | tests/test_openai_api.py, tests/test_api_stream.py | HTTP API and Python SDK |
| How does the Python SDK construct a runtime? | nanobot/nanobot.py::Nanobot, nanobot/sdk/runtime.py | tests/test_nanobot_facade.py | Same as above |
| How does WebSocket receive and send? | nanobot/channels/websocket.py::WebSocketChannel | tests/channels/test_websocket_integration.py | WebSocket and WebUI |
| How does one Turn advance through states? | nanobot/agent/loop.py::AgentLoop._process_message | tests/agent/test_loop_runner_integration.py, test_loop_save_turn.py | AgentLoop state machine |
| How does the model–Tool loop end? | nanobot/agent/runner.py::AgentRunner.run | tests/agent/test_runner_core.py, test_runner_tool_execution.py | AgentRunner’s model–Tool loop |
| How are the system prompt and history assembled? | nanobot/agent/context.py::ContextBuilder | tests/agent/test_context_builder.py, test_context_prompt_cache.py | ContextBuilder and model context |
Messages, events, and state
| Question | Source anchor | Tests to read first | Explanation |
|---|---|---|---|
| Which fields belong to inbound and outbound messages? | nanobot/bus/events.py | tests/bus/, Channel tests | Messages, Session keys, and entry points |
| How are messages queued? | nanobot/bus/queue.py::MessageBus | adjacent AgentLoop and Channel integration tests | Same as above |
| What exact Runtime Event types exist? | nanobot/bus/runtime_events.py | tests/bus/test_runtime_events.py | Persistence, response, and Runtime Events |
| How are Sessions saved, loaded, and locked? | nanobot/session/manager.py::SessionManager | tests/agent/test_session_atomic.py, test_session_manager_history.py | Session files and replay boundaries |
| How are Session keys normalized? | nanobot/session/keys.py | tests/agent/test_unified_session.py | Messages, Session keys, and entry points |
| When is history compacted? | nanobot/agent/memory.py::Consolidator, nanobot/agent/autocompact.py | tests/agent/test_auto_compact.py, test_consolidator.py | Compaction, Memory, and Dream |
| How does a persistent Goal continue? | nanobot/session/goal_state.py, turn_continuation.py | tests/agent/test_runner_goal_continue.py, test_loop_goal_wall_timeout.py | Goals and Continuations |
| How are Subagents created and cleaned up? | nanobot/agent/subagent.py, agent/tools/spawn.py | tests/agent/test_subagent_lifecycle.py | Subagent lifecycle |
Providers, Tools, and extensions
| Question | Source anchor | Tests to read first | Explanation |
|---|---|---|---|
| What is the unified Provider contract? | nanobot/providers/base.py::LLMProvider | tests/providers/ | Provider resolution and fallback |
| How is a Provider selected and instantiated? | nanobot/providers/registry.py, factory.py | tests/cli/test_commands.py, tests/agent/test_runtime_refresh.py | Same as above |
| How is fallback chained? | nanobot/providers/fallback_provider.py | tests/agent/test_runner_fallback.py | Same as above |
| What is the Tool contract? | nanobot/agent/tools/base.py::Tool | tests/tools/test_tool_validation.py | Add a Tool |
| How are Tools registered, validated, and executed? | nanobot/agent/tools/registry.py::ToolRegistry | tests/agent/test_runner_tool_execution.py | Tool registration, validation, and execution |
| How are external Tool plugins discovered? | nanobot/agent/tools/loader.py | tests/agent/test_tool_loader_entrypoints.py, test_tool_loader_scopes.py | Add a Tool |
| How are Skills discovered and filtered? | nanobot/agent/skills.py::SkillsLoader | tests/agent/test_skills_loader.py | Add a Skill |
| How does MCP connect and wrap Tools? | nanobot/agent/tools/mcp.py | tests/agent/test_mcp_connection.py, test_mcp_transient_retry.py | Integrate MCP |
| How are Channels discovered? | nanobot/channels/registry.py | tests/channels/test_channel_plugins.py | Add a Channel |
| How do Channels share outbound delivery? | nanobot/channels/base.py, manager.py | tests/channels/test_base_channel.py, test_channel_manager_delta_coalescing.py | Channels and Gateway |
Automation, engineering, and security
| Question | Source anchor | Tests to read first | Explanation |
|---|---|---|---|
| How does Cron persist and trigger jobs? | nanobot/cron/service.py, types.py | tests/cron/ | Cron and Heartbeat |
| How does Heartbeat connect to Cron? | heartbeat-job assembly in nanobot/cli/commands.py, nanobot/cron/service.py | tests/agent/test_loop_cron_timezone.py, adjacent Cron tests | Same as above |
| How is context protected after cancellation? | nanobot/agent/runner.py::_emit_checkpoint, nanobot/agent/loop.py::_restore_runtime_checkpoint | tests/agent/test_task_cancel.py, test_stop_preserves_context.py | asyncio concurrency, cancellation, and cleanup |
| How are workspace paths restricted? | nanobot/security/workspace_policy.py, workspace_access.py | tests/agent/test_workspace_scope.py, tests/security/ | Workspace, shell, and SSRF security boundaries |
| How is SSRF evaluated? | nanobot/security/network.py | tests/security/ and web Tool tests | Same as above |
| How is WebUI packaged into Python? | pyproject.toml, webui/, build scripts | packaging and build tests | Packaging, WebUI build, and cross-platform behavior |
Read the test name before the test body
A test name often states the behavior maintainers intend to preserve. Read its fixtures, triggering action, and assertions before returning to the implementation; this greatly reduces guesswork based on function names.
Index boundaries
- This page does not enumerate every Provider, Channel, or configuration field; use the official documentation for complete lists.
- If tests are reorganized, inspect the current
tests/tree withrg --files tests. - “Adjacent tests” means the behavior may span multiple test layers; one file alone may not prove every boundary.
Return to Quick reference.