You are reading Nightly documentation for 0.12.4.dev0+g50bde75.

This documentation may describe behavior that differs from Stable.

Open Stable documentation

Documentation version

0.12.4.dev0+g50bde75 · Nightly

Dynamic tool discovery and bounded code mode

Dynamic tool discovery and bounded code mode

Dynamic discovery keeps large native, MCP, skill, command, browser, extension,
and connected-app catalogs out of the model's initial context. New sessions
start with three small safety-critical tools:

  • tool_search returns at most eight ranked, schema-free descriptors.
  • tool_list returns a bounded list filtered by availability state.
  • tool_inspect selects one exact name or opaque handle and, when policy
    permits, loads that tool's exact schema for later model turns.

Host stop/cancel controls and approval responses remain always-available
control-plane actions outside the model schema catalog. Empty tool allowlists
cannot remove the three discovery/recovery tools.

Search and inspect never grant execution permission. A direct model call, alias,
opaque handle, legacy run_tool_script call, and bounded-code call all resolve
again through the current canonical registry immediately before execution.
Normal validation, lifecycle hooks, governance, approval, timeout, output
screening, and event recording still apply.

Installed skills and slash commands also appear as normalized descriptors with
their trust, required permissions, and provenance. They remain catalog-only:
they receive no capability handle or model-tool schema and must be used through
the existing skill or slash-command surface.

Availability states

Settings → Capability Center shows the effective catalog and explains each
state, denial reason, and next safe action. See Capability Center.

The same table also reports static sessions when dynamic discovery is disabled. In that mode,
loaded means the exact schema was supplied at session creation, while hidden identifies a tool
excluded by the session's agent-profile allowlist or provider visibility.

State Meaning
available Safe bounded metadata exists; the exact schema is not loaded.
hidden Provider visibility excludes the capability from model use, or the entry is catalog-only and names its required native surface.
discovered A search matched the tool; search still granted no permission.
loaded tool_inspect loaded the exact schema within the session budget.
denied A profile, session, or project rule prevents invocation.
invoked The canonical registry authorized an execution attempt; the normal approval path still applied.

Activity records registry transitions, searches, schema loads, denials,
invocations, and bounded-code summaries. Each record includes a stable provider
provenance identity and the relevant reason; it does not copy prompts, tool
arguments, tool output, or secrets.

Configuration

Dynamic discovery and the bounded multi-call tool are opt-in during the staged
Nightly rollout. Enable them in Settings → Capability Center or with
environment variables:

HOLARYN_DYNAMIC_TOOL_DISCOVERY=true
HOLARYN_BOUNDED_CODE_MODE=false

Changing either setting applies to new sessions. To roll back, set dynamic
discovery to false; the runtime returns to the static model-visible tool list.
No stored data migration is required.

Profiles continue to use their allowed_tools ceiling. Host integrations can
also supply session allow/deny rules. A coding project may add the data-only
file .holaryn/tool-policy.json:

{
  "allow": ["read_file", "grep_files", "repo_query"],
  "deny": ["bash", "run_tool_script"]
}

deny wins at every scope. An omitted allow means all otherwise permitted
tools; an empty allow means none. The three discovery controls remain
available so the model and operator can understand a denial instead of losing
the safety/recovery surface. A malformed project policy fails session creation
with the exact file and validation error.

Registry versions cover descriptor metadata, permissions, exact schema hashes,
provider identity, visibility/invokability, aliases, and scoped policy. When a
connector or tool changes, the discovery cache and opaque handles are
invalidated immediately, loaded schemas are cleared, and active sessions
receive a tool_registry_changed event with the old and new versions.

Bounded code mode

When enabled, discover and inspect run_tool_code. Its source looks familiar,
but Holaryn does not run or evaluate Python. A small AST interpreter accepts
only sequential assignments and calls:

first = call("toolh_a1b2...", {"path": "notes.txt"})
call("toolh_c3d4...", {"content": first})

The handle must come from the current registry and its schema must already be
loaded. Literal strings, numbers, booleans, nulls, lists, dictionaries, and
prior result variables are supported. The result is structured JSON containing
the run id, status, explicit limits, and one ordered trace row per attempted
call.

The runtime has no imports, packages, builtins, attributes, reflection,
comprehensions, loops, environment, filesystem, sockets, subprocesses, or
ambient network. It enforces:

  • no more than 16 calls (default 8);
  • no more than 30 seconds (default 20);
  • no more than 64 KiB returned or retained intermediate tool output (default
    32 KiB);
  • 16 KiB source and 256 syntax nodes;
  • nesting depth one—code mode, delegation, discovery, and script bridges cannot
    be called from inside it.

Every inner handle call still passes the ordinary gate. A denied approval stops
the sequence with a structured partial trace. Cancellation propagates to the
active tool and records a cancelled summary. Timeouts stop remaining calls.
Forged or stale handles are rejected before dispatch.

The older run_tool_script remains a separate ask-first shell-equivalent
feature with ambient process access. It is not the restricted code mode.

Example model flow

Prompt:

Find the project release notes and summarize them.

Representative tool flow:

tool_search({"query":"find and read project release notes"})
→ read_file (available, source native, schema not loaded)

tool_inspect({"name":"read_file"})
→ exact schema loaded; handle toolh_...

read_file({"path":"changes.md"})
→ normal approval/output/event path

With bounded code mode enabled, a task that needs two already-inspected tools
may use one run_tool_code call, but each inner action remains independently
authorized.

Performance evidence

The packaged no-network HolarynBench suite registers a 300-tool catalog, records
the ranked selection and static/dynamic schema byte footprints in the canonical
event trajectory, and requires the selected tool workflow to succeed against a
reviewed baseline:

uv run holaryn bench run --suite tool-discovery \
  --baseline benchmarks/baselines/tool-discovery-v1.json \
  --fail-on-regression --output-dir benchmark-results/tool-discovery

The release gate requires at least 90% initial schema-byte reduction, a
top-ranked glob_files selection for the intent fixture, and 100% workflow
success. Additional deterministic fixtures in tests/test_tool_discovery.py
cover browser, memory, filesystem, exact-name, description, schema-field,
permission, and provenance ranking plus cache/version transitions without a
network or live model.