Guidance for AI coding agents working in this repository.
This file applies to the whole ldclabs/anda workspace. Follow more specific
instructions in nested AGENTS.md files if any are added later.
anda is a Rust workspace for composable AI agent runtimes.
anda_core: stable traits, shared data models, context capabilities, JSON schema helpers, and RPC helpers.anda_engine: runtime orchestration, contexts, model adapters, tools, hooks, memory, subagents, and reusable extensions.anda_engine_server: HTTP server layer for exposing engines.anda_cli: CLI entrypoint for configured engine servers.anda_web3_client: Web3 integration for non-TEE environments.docs/architecture.md: source-level runtime architecture.MCP_INTEGRATION.md: MCP host/client design and boundaries.
Keep anda_core small and dependency-light. Runtime integrations belong in
anda_engine or higher-level crates unless the shared contract genuinely needs
to change.
- Inspect the exact code and docs relevant to the request before editing.
- Preserve user or agent changes already present in the working tree. Do not revert unrelated dirty files.
- Prefer small, behavior-focused changes over broad refactors.
- Keep public API changes coherent across code, docs, examples, and tests.
- Use workspace dependencies from the root
Cargo.toml; do not add duplicate per-crate versions unless there is a clear reason. - Keep generated schemas and protocol-visible names stable. Agent, tool, and provider names must satisfy the function-name rules: lowercase ASCII letters, digits, underscores, and hyphens, starting with a lowercase letter, max 64 bytes.
- When changing model/provider conversion code, preserve raw-history and tool/user message boundaries. Do not merge tool outputs into user messages or lose provider-specific content unless the existing code explicitly does so.
ContentPart/chat_historyis the persisted, provider-neutral history. Provider per-turn intermediate state (Anthropicthinking.signature, GeminithoughtSignature) belongs inCompletionRequest::raw_history, which every adapter sends ahead of the convertedchat_historyand which is scoped to one in-process reasoning round. Do not add provider-specific fields toContentPartto carry such state — an adapter dropping it on the way in is correct by design. Do fix the reverse: converting out ofContentPartmust never emit something the provider rejects (e.g. athinkingblock with an empty signature); omit it instead.
ToolandToolSetare for static local tools.ToolProviderandToolProviderSetare for runtime-discovered tools, such as MCP servers.AgentCtxis the scheduling surface for local tools, dynamic providers, local agents, subagents, and remote engines.BaseCtxis the capability surface for tools and agents. Use scoped child contexts so cache, store, metadata, and cancellation behavior remain isolated.tools_searchandtools_selectare normal agents, not side channels. If a change affects discovery, verify schema selection, request tool merging, and repeated-selection compaction.- Remote engine prefixes and subagent prefixes are part of the runtime contract. Do not rename or reinterpret them without updating all call and discovery paths.
MCP support is implemented in anda_engine::extension::mcp and should remain a
generic engine capability. Product-level configuration, secret expansion,
approval UX, and launcher behavior belong in downstream applications such as
anda-bot.
- Use
rmcpfor MCP client behavior. Do not hand-roll JSON-RPC transports. - Support MCP tools through
tools/listandtools/call. - Keep both protocol generations working: the stateless
2026-07-28lifecycle (server/discover, per-request_meta,subscriptions/listen) and the legacyinitializehandshake. Negotiate2026-07-28only through discovery, and keep the fallback path for servers that neither implement nor cleanly refuse it. - Keep a bound on anything a remote server can leave pending — the discovery probe, a subscription acknowledgment, task polling — so one server cannot wedge session setup or a tool call.
- Keep stdio transport as
command + args; do not construct shell strings. - Keep Streamable HTTP headers validated before connecting.
- Treat remote MCP descriptions, annotations, and output as untrusted metadata.
- Preserve the local-name to remote-name route table so original MCP tool names are used for calls while Anda exposes legal local function names.
- Do not integrate SEP-2577-deprecated capabilities: Roots, Sampling, or Logging
control. In particular, do not advertise Roots, do not create Sampling
messages, and do not call
logging/setLevel.
- Engines are private by default. Be careful when changing
Management, exported agents/tools, or directagent_run/tool_callvalidation. - Filesystem tools must remain workspace-scoped and must reject unsafe symlink, parent-directory, non-regular-file, or hardlink escapes.
- Shell tools must keep environment forwarding explicit and must not leak secret values in definitions, logs, or tool outputs.
- HTTP/model clients should preserve existing timeout, retry, body-size, and content-decoding behavior unless the task is specifically to change it.
- Never expose full conversation history to tools or remote systems unless the existing public contract requires it.
Use the narrowest command that proves the change, then broaden when the touched surface is shared.
cargo fmt
cargo test -p anda_core -p anda_engine
cargo clippy -p anda_core -p anda_engine --all-targets --all-features -- -D warningsFor crate-specific work:
cargo test -p anda_core
cargo test -p anda_engine
cargo test -p anda_engine_server
cargo test -p anda_cli
cargo test -p anda_web3_clientFor public API or documentation-sensitive changes:
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-depsIf a command fails because dependencies or network access are unavailable, report that clearly and keep the successful local checks in the final summary.
- Add focused unit tests for new contracts, edge cases, and regressions.
- Add integration tests when behavior crosses crate, HTTP, transport, or runtime boundaries.
- For discovery or completion-runner changes, test both happy path and missing or malformed tool/agent paths.
- For MCP changes, test name mapping, include/exclude filters, schema conversion, call result conversion, and dynamic provider registration.
- For filesystem or shell changes, include negative tests for path escapes, encoding, symlinks, cancellation, and output limits where relevant.
Update docs when behavior changes user-facing or integrator-facing surfaces:
- Root
README.mdfor high-level capability changes. - Translated READMEs when the English README changes materially.
- Crate READMEs for crate-local public API changes.
docs/architecture.mdfor runtime architecture changes.MCP_INTEGRATION.mdfor MCP host/client design changes.- Rustdoc comments for new public types, methods, traits, and fields.
Keep examples copyable. Compile or test examples when they include API calls or protocol bytes.
- Rust edition is 2024.
- Prefer typed APIs and serde/schemars helpers over ad hoc JSON or string manipulation.
- Keep
lib.rsexports intentional and small. - Avoid new abstractions unless they reduce real duplication or match existing registry/context patterns.
- Keep comments concise and explain non-obvious decisions, not line-by-line mechanics.
- Use
Arcfor shared runtime components following existing patterns. - Prefer
BoxErrorand existing error style unless introducing a local error enum materially improves call-site clarity.
Check the final diff for unrelated churn. In the final response, summarize:
- Files or modules changed.
- Behavioral impact.
- Tests and checks run.
- Any checks not run and why.