Skip to content

core-plugin-tools takes ~30s per turn; no apparent supported no-tools mode for agentTurn #76606

@daruire

Description

@daruire

Summary

On OpenClaw 2026.4.29, per-turn preparation is very slow. The largest repeated contributor appears to be the aggregated core-plugin-tools stage, taking approximately 29–34s per turn.

This also happens in isolated sessions, and an agentTurn configured with toolsAllow: [] does not reduce the core-plugin-tools time.

Environment

  • OpenClaw version: 2026.4.29
  • Runtime: local OpenClaw gateway / agent runtime
  • Issue observed during normal assistant turns, isolated session probes, and cron agentTurn probes

Symptom

Repeated startup/prep traces show:

  • core-plugin-tools: approximately 29–34s
  • Total prep time: approximately 60–70s
  • Responses take a long time before model output begins
  • Gateway and related commands degrade under load:
    • cron status/list becomes slow or times out
    • memory status / memory status --deep times out
    • Gateway event loop delay spikes under load

Timing evidence

Baseline

Recent normal-turn traces consistently showed:

  • core-plugin-tools: ~29–34s
  • model-resolution: ~21–25s
  • auth: ~10–13s
  • stream-setup: ~13–15s
  • system-prompt: ~10–13s

Related read-only checks showed system-wide latency symptoms:

  • openclaw status --deep: ~13–27s
  • cron status/list: around 5s to timeout
  • openclaw memory status: timeout at 15s
  • openclaw memory status --deep: timeout at 45s

Isolated session reproduction

A clean isolated session probe with:

Responde solo: OK

returned successfully, but timing remained slow:

  • startup: ~48.2s
  • prep: ~70.8s
  • core-plugin-tools: ~33.8s

This suggests the issue is not primarily caused by a long-lived current session.

toolsAllow: [] reproduction

A temporary agentTurn probe was configured with:

{
  "toolsAllow": [],
  "sessionTarget": "isolated",
  "delivery": {
    "mode": "none"
  },
  "deleteAfterRun": true
}

The turn returned OK, but timing remained near baseline:

  • startup: ~42.1s
  • prep: ~62.4s
  • core-plugin-tools: ~29.3s

So toolsAllow: [] did not appear to avoid tool/plugin construction cost.

Code finding

From code inspection, toolsAllow appears to be applied only after tool construction.

The helper:

applyEmbeddedAttemptToolsAllow(tools, toolsAllow)

returns all tools when toolsAllow is falsy or an empty array:

if (!toolsAllow || toolsAllow.length === 0) return tools

Additionally, createOpenClawCodingTools(...) appears to run before this filtering is applied, meaning the full construction cost is already paid before allowlist filtering can remove anything.

The inspected construction path indicates that createOpenClawCodingTools(...) builds or resolves:

  • base coding tools
  • exec/process/apply_patch tools
  • channel agent tools
  • OpenClaw tools
  • plugin tools
  • policy pipeline / wrappers / hooks
  • deferred tool descriptions

createOpenClawTools(...) also constructs/resolves tools such as:

  • canvas
  • nodes
  • cron
  • message
  • gateway
  • agents/sessions/subagents
  • session_status
  • web/media tools
  • plugin tools

resolvePluginTools(...) appears to resolve plugin runtime/load context and registry, iterate registry tools, run tool factories, and then optionally apply allowlist filtering.

Because core-plugin-tools is exposed as an aggregated stage in the timing logs, I cannot confirm from the available logs whether the 29–34s are mostly spent in base tool construction, plugin registry/factories, channel tools, policy wrapping, deferred descriptions, or some combination of these.

A non-empty allowlist such as:

{
  "toolsAllow": ["session_status"]
}

would likely still pay most or all of the same construction cost if filtering happens after createOpenClawCodingTools(...), although I have not separately benchmarked that exact case.

Hypothesis

OpenClaw currently pays the global tool/plugin construction cost for every turn, even when tools are later filtered.

Also, toolsAllow: [] currently appears to mean “no filtering / unrestricted”, rather than “zero tools”. If that semantics is intentional, there does not seem to be an obvious supported way to request an explicit no-tools agentTurn.

Impact

This has a large user-visible latency impact:

  • total prep time is often ~60–70s
  • responses are delayed significantly before streaming/model output begins
  • Gateway responsiveness degrades under load
  • operational commands such as cron and memory status become slow or time out

Suggested fixes / design options

Possible improvements:

  1. Distinguish undefined from [], if changing this semantics is acceptable:

    • toolsAllow: undefined = current default behavior / unrestricted
    • toolsAllow: [] = explicitly no tools
  2. If toolsAllow: [] is intended to mean no tools, short-circuit when it is explicitly defined and empty:

    • avoid calling createOpenClawCodingTools(...)
    • return an empty tool list early
  3. If toolsAllow: [] must keep its current behavior, add an explicit no-tools mode, for example:

{
  "disableTools": true
}

or:

{
  "toolsMode": "none"
}
  1. Ideally pass the allowlist into tool construction earlier:

    • avoid constructing tools that will be filtered out
    • especially avoid resolving plugin tools/factories unless needed
  2. Consider lazy-loading plugin tools:

    • defer plugin registry/tool factory work until the tool is actually enabled or requested

Compatibility risks

Changing the semantics of toolsAllow: [] may break users who currently rely on an empty array meaning “no restriction”.

If that behavior is intentional or needs to remain stable, a new explicit flag such as disableTools: true or toolsMode: "none" may be safer.

Minimal reproduction

  1. Run a normal turn and inspect startup/prep timing.
  2. Run an isolated session with a trivial prompt:
Responde solo: OK
  1. Run an agentTurn with:
{
  "toolsAllow": [],
  "sessionTarget": "isolated",
  "delivery": {
    "mode": "none"
  },
  "deleteAfterRun": true
}
  1. Compare core-plugin-tools timing across the three runs.

Observed result:

  • core-plugin-tools remains around 29–34s.

Desired result / question:

  • If toolsAllow: [] is intended to mean “no tools”, it would be useful for it to avoid constructing tools.
  • If toolsAllow: [] is intentionally “unrestricted”, is there another supported explicit no-tools mode for agentTurn?
  • More generally, can allowlist/no-tools intent be applied before expensive tool/plugin construction?

Questions

  1. Is it intentional that toolsAllow: [] means “do not filter tools” rather than “zero tools”?
  2. Is there a supported way to launch an agentTurn without constructing tools?
  3. Would a non-empty allowlist currently still construct all tools before filtering?
  4. Are there fixes or performance improvements for this area in versions newer than 2026.4.29?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions