Skip to main content

Crate nanocodex_tools

Crate nanocodex_tools 

Source
Expand description

§Nanocodex Tools

Tool building blocks for OpenAI agents.

nanocodex-tools is useful without the Nanocodex agent loop. It provides the caller-defined Tool contract, tool macro, heterogeneous Tools registry, Code Mode runtime, standard workspace tools, and native MCP clients. The shared contract types are defined by nanocodex-oai-api and re-exported here so a tool implementation has one import surface.

§Define and select tools

The definition is the single source of truth for a tool’s registry name. The macro derives its input and output schemas from the function:

use nanocodex_tools::{Tools, tool};

#[tool(
    name = "deployment_region",
    description = "Return the production region for a named service.",
    parallel = true
)]
async fn deployment_region(service: String) -> Result<String, std::io::Error> {
    Ok(format!("{service}: us-west-2"))
}

let tools = Tools::builder()
    .without_defaults()
    .tool(deployment_region)
    .build()?;

Tools defaults to ToolExposure::CodeModeOnly, where ordinary tools are available through exec and only Code Mode entrypoints are directly visible. Select ToolExposure::DirectAndCodeMode when a consumer needs the same ordinary tools directly as well as through exec:

use nanocodex_tools::{ToolExposure, Tools};

let tools = Tools::builder()
    .exposure(ToolExposure::DirectAndCodeMode)
    .build()?;

Matching Codex, direct-plus-Code-Mode exposure keeps exec terse and adds each typed exec declaration to the corresponding direct tool; Code Mode-only instead carries the complete nested catalog in exec. Selection changes model-visible exposure, not registration or dispatch behavior. tool_with_exposure can override one registered tool with DirectOnly, CodeModeOnly, DirectAndCodeMode, or Hidden while preserving the global default for the rest. Host-owned exec, wait, and tool_search names cannot be replaced, and the first tool registered for a normalized JavaScript name wins the nested Code Mode surface. Namespaced Code Mode names such as image_gen__imagegen remain available to exec; normal Code Mode exposes the Codex-compatible image_gen.imagegen Responses namespace and routes its namespaced call to the same handler.

Macro tools execute serially unless parallel = true explicitly marks their local effects as safe to overlap. This does not change the provider wire protocol.

Implement Tool directly when execution needs ToolContext, freeform input, multimodal ToolOutput, or a custom definition:

use nanocodex_tools::{
    Tool, ToolContext, ToolDefinition, ToolInput, ToolOutput, ToolResult,
    contract::async_trait,
};
use serde_json::json;

struct DeploymentRegion;

#[async_trait]
impl Tool for DeploymentRegion {
    fn definition(&self) -> ToolDefinition {
        ToolDefinition::function(
            "deployment_region",
            "Return the production region for a named service.",
            json!({
                "type": "object",
                "properties": { "service": { "type": "string" } },
                "required": ["service"],
                "additionalProperties": false
            }),
        )
    }

    async fn execute(
        &self,
        input: ToolInput,
        _context: ToolContext<'_>,
    ) -> ToolResult {
        let input: serde_json::Value = input.decode_json()?;
        let service = input["service"].as_str().ok_or_else(|| {
            std::io::Error::new(
                std::io::ErrorKind::InvalidInput,
                "service must be a string",
            )
        })?;
        Ok(ToolOutput::text(format!("{service}: us-west-2")))
    }
}

§Embed Code Mode in another host

hosted is the portable boundary for environments that own JavaScript execution outside Rust. Implement hosted::CodeModeHost and pass it to hosted::HostedTools; the adapter reuses the same execution, nested-call, notification, observer, and owned-context types as native Code Mode. The hosted module documentation includes a complete host implementation.

§MCP is native and always available

MCP is not a feature flag. Native consumers configure stdio or Streamable HTTP servers and install the provider into the same registry:

use nanocodex_tools::{
    Tools,
    mcp::{Mcp, McpServer},
};

let mcp = Mcp::builder()
    .server(
        "company_docs",
        McpServer::stdio("company-docs-mcp").arg("--readonly"),
    )
    .build()?;

let tools = Tools::builder().provider(mcp).build()?;

Handshakes and discovery start with the owning runtime. Both exposure policies keep the provider-native tool_search visible while omitting deferred MCP schemas from the initial request. Code Mode lists those deferred tools as compact name/description entries in ALL_TOOLS. Search results contain loadable MCP namespaces for direct model calls and also activate matching Code Mode definitions, keeping large catalogs out of the initial tool list. McpServer::tool_exposure independently selects DeferredOnly, CodeModeOnly, DeferredAndCodeMode, or Hidden for each server. Automatic catalog and aggregate resource pagination is bounded by page, item, cursor, and wall-clock limits.

§Companion workspace runtimes

The default native feature remains the complete tools crate: registry, Code Mode, MCP, web/image tools, macros, and standard workspace tools.

The narrower workspace-runtime feature exists only for process companions such as nanocodex-vm-guest. With default features disabled, it exposes the canonical workspace_runtime::WorkspaceToolRuntime, standard tool identities, and their shared contracts without linking OpenAI transports, Code Mode/QuickJS, MCP, or HTTP clients. This is artifact separation, not a second tool implementation or an alternate mode for normal native applications.

§Going lower level

The crate root intentionally contains only the normal registry path: Tools, ToolsBuilder, ToolsBuildError, Tool, tool, and the types required by the Tool methods. ToolExposure is the advanced declaration policy for consumers that compare direct and Code Mode calls. The root also exposes ambient_sensitive_environment for deliberately restoring proxy-safe credential markers to tool subprocesses.

  • contract contains complete model-visible inputs, outputs, errors, and retained wire forms.
  • hosted contains the portable application-owned Code Mode boundary.
  • runtime contains the stateful per-agent executor, built-in connection configuration, and dynamic-provider contract.
  • code_mode contains cell results, notifications, and nested-tool updates.
  • mcp contains transport configuration, authentication, discovery, login, and runtime control.
  • standard contains reusable standard-tool identities and the host-owned plan implementation.
  • workspace_runtime contains the retained canonical workspace-tool runtime used by process companions.
  • image contains prompt-image preparation and tool-output normalization.

Re-exports§

pub use runtime::ToolExposure;Non-target_family=wasm
pub use runtime::Tools;native
pub use runtime::ToolsBuildError;Non-target_family=wasm
pub use runtime::ToolsBuilder;Non-target_family=wasm

Modules§

code_modeNon-target_family=wasm
Code Mode execution results, notifications, and nested-tool observation.
contract
Model-visible tool definitions, inputs, outputs, and execution contracts.
hostednative
Portable adapter for Code Mode runtimes owned by an embedding host.
imageNon-target_family=wasm
Prompt image preparation and model-output image normalization.
mcpNon-target_family=wasm
Background-handshaken MCP tools for Nanocodex Code Mode.
runtimeNon-target_family=wasm
Declarative tool selection and the stateful per-agent execution runtime.
standardNon-target_family=wasm
Stable identities and reusable implementations for standard workspace tools.
workspace_runtimeNon-target_family=wasm
Focused retained runtime for the canonical local workspace tools.

Structs§

ToolContext
Read-only context for one tool invocation.
ToolOutput
Complete output of one tool invocation.

Enums§

ToolDefinition
Model-visible tool definition carried by Responses Lite input.
ToolInput
Canonical input presented to function and freeform tools.

Traits§

Tool
A caller-defined model-visible tool.

Functions§

ambient_sensitive_environmentnative and non-target_family=wasm
Returns the ambient environment variables the shell tool withholds from tool subprocesses because their names look sensitive.

Type Aliases§

ToolResult
Result returned by Tool::execute.

Attribute Macros§

toolNon-target_family=wasm
Defines a typed JSON function tool from an async Rust function.