#Few Hook Questions

1 messages · Page 1 of 1 (latest)

sonic helm
#

Hi Krill, three questions about OpenClaw 5.4 (will upgrade to 5.7 soon):

1. Typed hook activation gate

A non-bundled plugin registers typed hooks via
api.on("before_tool_call", ...). plugins inspect shows
shape: "hook-only", hookCount: 2, typedHooks: [...] but
hookNames: [] and the hooks never fire.

Adding plugins.entries.<id>.hooks.allowPromptInjection: true (or
allowConversationAccess: true) makes them fire. Empty hooks: {}
doesn't work — at least one truthy key is required.

Is this intentional? Are there other hooks.* flags? Is it documented
anywhere? This started around 2026-04-24 (matches
bundled-plugin-enablement compat entry).

2. Per-agent dreaming control

Global memory-core dreaming runs on all agent workspaces — one main
agent + 6 sub-agents = 7 dreaming sweeps at 3AM. GitHub Issue #67413
is open for per-agent config. Any current workaround to disable
dreaming on sub-agents while keeping it on for main?

3. Thread yield routing

With threadBindings.spawnSessions: true and thread: true on
sessions_spawn, sub-agent delegations correctly create new Discord
threads. After sessions_yield, the parent agent doesn't post any
follow-up to the original channel — user has to enter the thread to
see results. Is there a config to route yield summaries back to parent
channel, or is this expected?

Thanks!

little lotusBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

lofty thornBOT
# sonic helm Hi Krill, three questions about OpenClaw 5.4 (will upgrade to 5.7 soon): **1. T...

I checked current docs/source against this. Short version:

  1. Typed hook activation gate
    Yes, the “at least one truthy hook policy key” behavior is real for non-bundled hook-only plugins that don’t otherwise declare hook activation metadata.

There are two related things:

  • Startup activation intent: for hook-only plugins, startup planning loads the plugin if the manifest declares activation.onCapabilities: ["hook"], or if config has an explicit hook policy intent. Current explicit intent is: allowConversationAccess: true, allowPromptInjection: true, timeoutMs, or non-empty timeouts.
  • Conversation access gate: non-bundled plugins using raw-conversation hooks must opt in with plugins.entries.<id>.hooks.allowConversationAccess: true.

So for a pure before_tool_call plugin, the cleaner fix is probably to add this to the plugin manifest rather than using a scary-looking allow flag just to force load:

{
  "activation": {
    "onCapabilities": ["hook"]
  }
lofty thornBOT
# sonic helm Hi Krill, three questions about OpenClaw 5.4 (will upgrade to 5.7 soon): **1. T...
}

If you can’t change the manifest, a config-side hook policy does act as the activation hint. The documented hooks.* keys I found are:

  • allowPromptInjection
  • allowConversationAccess
  • timeoutMs
  • timeouts

Docs are partially there, but the “truthy hook policy as startup intent” part is not super clearly called out. Relevant docs:
https://docs.openclaw.ai/plugins/manifest
https://docs.openclaw.ai/plugins/hooks
https://docs.openclaw.ai/gateway/configuration-reference

  1. Per-agent dreaming control
    No good per-agent switch yet. Current dreaming workspace resolution fans out across configured agents.list[] workspaces plus the primary workspace; it does not filter by per-agent memorySearch.enabled.
lofty thornBOT
# sonic helm Hi Krill, three questions about OpenClaw 5.4 (will upgrade to 5.7 soon): **1. T...

Current workarounds are basically architectural:

  • keep sub-agents on the same workspace if that’s acceptable, so dreaming dedupes by workspace;
  • remove/avoid persistent workspace entries for sub-agents you don’t want swept;
  • disable global dreaming and run a manual/scheduled main-only promotion flow yourself.

But “dreaming on main, off for sub-agents” as config is exactly the missing thing from that issue.

Docs: https://docs.openclaw.ai/concepts/dreaming

  1. Thread yield routing
    Expected for thread-bound session spawns. With thread: true, completion delivery preserves the bound child thread destination when available. sessions_yield wakes/continues the requester with the completion event, but the externally visible completion is not currently mirrored back to the original parent channel by a config switch.

If you want parent-channel summaries, current options are:

  • don’t use thread: true for those spawns;
  • have the parent explicitly send a summary to the parent channel after it receives the completion event;
  • advanced/plugin route: use subagent_delivery_target to customize delivery.
lofty thornBOT
sonic helm
#

@lofty thorn
Hey Krill, follow-ups after upgrading to 5.12 and applying your earlier
suggestions. Hook manifest fix worked great — compat: ["activation-capability-hint"]
confirms the activation gate is loading the plugin properly.

Q1: hook-only → explicit capability registration migration path

The compatibility output says my plugin "has not migrated to explicit
capability registration yet." Is there a roadmap / recommended migration
path? Should plugin authors prepare now (e.g., api.registerHookCapability()
or similar API), or wait for the migration to be announced?

Q2: Anthropic Agent SDK $100 credit (June 15) — OpenClaw integration

Anthropic announced Max 5x users get a $100/month Agent SDK credit starting
June 15, covering "third-party apps built on the Agent SDK". Does OpenClaw's
current Anthropic provider route through the Agent SDK such that the credit
will apply automatically? Or does the user need to do anything specific
(config flag, auth re-login, plugin update) to make sure OpenClaw API calls
draw from the credit pool instead of pay-as-you-go API billing?

Q3: Model routing for multi-HQ setups — best practices

For a multi-HQ structure (6 managers + ~10 sub-agents), what's the
recommended pattern for cost-optimal model routing?

  • Should manager agents share the same model as main, or step down to a
    smaller model (Haiku, gpt-5.4-mini)?
  • For simple sub-agents (file ops, wiki writes, JSON parsing), is there
    a meaningful difference between codex/gpt-5.4-mini and
    anthropic/claude-haiku-4-5 for cost/quality?
  • Any caching/context-reuse implications when mixing providers (Anthropic
    for main/managers, Codex for sub-agents) across the HQ tree?

Q4: Secret management in openclaw.json

For users wanting to share/screenshot config without leaking tokens, is
there an official redaction command (like openclaw config show --redacted)
or a recommended pattern? Currently I'm using a jq one-liner aliased to
oc-safe.

Also: any roadmap for Keychain / Doppler / 1Password integration so
secrets don't sit in openclaw.json plaintext?

Q5: Inspect output schema in 5.12

Top-level hookCount returns null but plugin.hookCount returns the
correct value (2). Same for activationSource / activationReason — only
populated under plugin.*. Is this expected schema split, or should top-level
mirror plugin-level fields for convenience?

Q6: subagent_delivery_target plugin route

Per your earlier answer on thread yield routing, you mentioned
subagent_delivery_target as an advanced option for customizing delivery.
Is there docs/example for this? Specifically for routing yield summaries
back to parent channel automatically without relying on prompt enforcement.
Even a minimal example would help — considering building this into my
plugin as a follow-up if AGENTS.md enforcement proves unreliable.

Thanks!

lofty thornBOT
#

Nice, glad the hook manifest fix landed cleanly 🦞 I checked the current docs/source shape; here’s the practical read:

Q1 — hook-only → explicit capability migration
Don’t invent api.registerHookCapability() yet. I don’t see that as a public API. The current guidance is: hook-only remains supported as a compatibility path; capability registration is the intended direction, but external plugin authors should treat capability-specific helper surfaces as evolving unless docs mark them stable.

So: keep your hooks working, prefer newer typed hooks over legacy before_agent_start, and only migrate to explicit capability registration when your plugin actually owns a capability OpenClaw exposes today (registerProvider, registerChannel, registerMemoryCapability, etc.). For pure coordination hooks, I’d wait for a documented migration path rather than adding speculative APIs.
Docs: https://docs.openclaw.ai/plugins/architecture

Q2 — Anthropic Agent SDK credit
OpenClaw’s anthropic/* API-key provider is direct Anthropic API billing, not “third-party app built on Agent SDK” routing. So I would not assume the Agent SDK credit applies automatically to normal anthropic/* provider calls.

Anthropic’s article says the credit covers Claude Agent SDK usage, claude -p, and third-party apps built on the Agent SDK; OpenClaw docs currently describe two Anthropic routes: direct API key, and Claude CLI reuse. If you want the credit path, the likely relevant route is Claude CLI / claude -p-style usage, not API-key traffic. Users also need to claim the credit once in their Claude account per Anthropic’s support article.
OpenClaw docs: https://docs.openclaw.ai/providers/anthropic
Anthropic SDK note: https://code.claude.com/docs/en/agent-sdk/overview

Q3 — multi-HQ model routing
Best pattern: keep “judgment / orchestration / user-facing synthesis” on your strongest reliable model; step down background subagents aggressively.

#

Concrete pattern:

  • Main + managers: use a capable model if they make routing decisions, reconcile conflicting results, or write final answers.
  • Simple subagents: use agents.defaults.subagents.model or per-agent agents.list[].subagents.model to route them cheaper. Explicit sessions_spawn.model still wins for one-off jobs.
  • Avoid context: "fork" unless the child truly needs the full parent transcript; isolated children are cheaper and cleaner.
  • Mixing providers is fine architecturally, but caching/context reuse is provider-scoped. Don’t expect Anthropic prompt-cache economics to carry over to Codex/OpenAI-family children. Each subagent has its own context/token burn.

For current “which small model is best this week” advice, I’d ask in #models because those tradeoffs move fast. Docs: https://docs.openclaw.ai/tools/subagents and https://docs.openclaw.ai/concepts/model-providers

Q4 — redacted config / secret storage
There isn’t a config show --redacted command in the CLI help I checked. But openclaw config get <path> does redact sensitive values before printing, and openclaw status --all is explicitly intended as pasteable/shareable with tokens redacted. For bug reports, openclaw gateway diagnostics export is the safer bundle.

For not storing plaintext: use SecretRefs. OpenClaw supports env, file, and exec secret providers. 1Password is already covered via the exec provider pattern (op read ...). Doppler/Vault/etc. can use the same exec contract. I don’t see a native Keychain/Doppler/1Password config-backend roadmap item in docs, but the SecretRef exec path is the supported abstraction today.
Docs: https://docs.openclaw.ai/gateway/secrets and https://docs.openclaw.ai/cli/config

Q5 — inspect schema split
For openclaw plugins inspect --json, the canonical plugin metadata lives under plugin.*, while the inspect-level fields are things like shape, capabilityMode, capabilities, typedHooks, customHooks, etc.

#

So plugin.hookCount, plugin.activationSource, plugin.activationReason being populated is expected.

If you’re seeing actual top-level keys named hookCount / activationSource / activationReason with null, that feels like either a compatibility shim or leaky convenience field rather than the canonical schema. I’d consume plugin.* and typedHooks.length + customHooks.length for now. If you want top-level mirrors for convenience, that’s a reasonable GitHub issue/feature request.

Q6 — subagent_delivery_target
Docs only list it at a high level right now; the source type is the best reference. Minimal shape:

export default {
  id: "my-routing-plugin",
  register(api) {
    api.registerHook("subagent_delivery_target", (event) => {
      // event: childSessionKey, requesterSessionKey, requesterOrigin,
      // childRunId, spawnMode, expectsCompletionMessage
      return {
        origin: {