Plugin API: $.agent.register silently drops cacheTtl; no way to set a runtime-registered agent's cache TTL
Environment: Claude Code 2.1.296, Windows 10, CLI (claude -p, plugin loaded with --plugin-dir). subagentPromptCacheTtl and CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL are not set.
Related: #99808 (per-type TTL in settings; this one is about the plugin API).
Summary
A plugin can define an agent type at runtime with $.agent.register, and the type gets the model, effort and tools from the spec. The cache TTL is the one field it does not get. cacheTtl: "1h" and experimental: { cacheTtl: "1h" } are both accepted without an error and then dropped, so the agent always writes to the 5-minute cache. The same setting in an agent file inside the same plugin works. So the engine supports a per-agent TTL. The runtime API just does not pass it through, and it gives no sign that the field was ignored.
Steps
- A plugin registers two agent types on
session.start:
``ts``
$.agent.register({ name: "lowread", description: "...", prompt: "...",
model: "sonnet", effort: "low", tools: ["Read"], cacheTtl: "1h" })
$.agent.register({ name: "lowread_exp", description: "...", prompt: "...",
model: "sonnet", effort: "low", tools: ["Read"], experimental: { cacheTtl: "1h" } })
- The same plugin ships
agents/filettl.mdwith the same model, effort and tools and
``yaml``
experimental:
cacheTtl: 1h
- Spawn each type with
$.agent.spawnand read the subagent transcripts (subagents/agent-*.jsonl,.prefix.json).
Result
| Agent | effort | tools | ephemeral_1h_input_tokens | ephemeral_5m_input_tokens | .prefix.json is1hCacheTTL |
|---|---|---|---|---|---|
| lowread (register, cacheTtl) | low ✔ | Read ✔ | 0 | > 0 | false |
| lowread_exp (register, experimental.cacheTtl) | low ✔ | Read ✔ | 0 | > 0 | false |
| filettl (agent file) | low ✔ | Read ✔ | 10845 | 0 | true |
Neither register call returned an error or a warning. AgentSpec in the generated plugin types has no TTL field either.
Expected
$.agent.register either applies cacheTtl like every other field an agent file carries, or rejects the field. The documentation on AgentSpec says that every field an agent file may carry is accepted and takes effect the same way. For cacheTtl that is not true.
Request
- Accept
cacheTtl("5m"/"1h") inAgentSpec, with the same meaning asexperimental.cacheTtlin an agent file. - Optionally, accept a per-call
cacheTtlin$.agent.spawn. A delegation tool built on the plugin API registers one type per combination of model, effort and tools, and only the caller knows whether that agent will be launched again soon. - Allow
"off"as a value, so one launch can skip the cache write without turning caching off for the whole process withDISABLE_PROMPT_CACHING. - Reject or warn on
AgentSpecfields that are not applied, rather than dropping them silently.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗