Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Use the mods API changedplugins/mods/api

Nearest release: v2.1.296, published 2 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 9 Oct 2026 19:51 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 9 Oct 2026 20:07 UTC.

Upstream edited
Recorded here
Lines+89added
Lines−8removed
From line 67 where the diff opens
First seen 1 Oct 2026 this site's first read of the page
Recorded edits12to this page, all time

### Send one prompt ### Use prompt caching #### Choose between `prompt` and `system` #### Check for cache hits ### What a `model.complete` hook receives

The whole hunk

from line 67, old and new numbered
/
lines
from line 67
6767 
6868## Call a model
6969 
70A mod can ask a model a question of its own, outside the conversation, for a small job such as sorting or summarizing a piece of text. `$.model.complete` sends one prompt to a model with your session's credentials and resolves to the reply. It has no conversation history.
70A mod can send its own requests to a model for a small job such as classifying or summarizing text. `$.model.complete` sends your prompt on its own, and `$.model.fork({ prompt })` sends the current conversation with your prompt at the end.
7171 
72This table compares what each request contains:
73 
74| In the request | `$.model.complete` | `$.model.fork` |
75| :- | :- | :- |
76| Model | The `model` you pass | The session's model |
77| System prompt | A short [attribution block](/docs/en/llm-gateway-protocol#system-prompt-attribution-block), then your `system` if you pass one | The session's system prompt |
78| Messages | One user message, your `prompt` | The conversation so far, then your `prompt` as a user message |
79| CLAUDE.md and other project context | Not included | Included, as in the conversation's last request |
80| Tools | None | Claude's tools, which the model can't call |
81 
82A fork repeats the conversation's last request, so the Claude API serves most of it from the [prompt cache](/docs/en/prompt-caching) while the conversation is still cached.
83 
84Both calls use the session's credentials, so they bill to the user's plan, API key, or cloud provider. [The types for your build](/docs/en/plugins/mods/create#get-the-types-for-your-build) document every `$.model` method.
85 
86### Send one prompt
87 
88Pass `model` and `prompt` to `$.model.complete`. `prompt` becomes the user message. To give the model instructions, such as a role or an output format, also pass `system`, which becomes the system prompt.
89 
7290This hook answers a `/triage` command, [registered as a command](#add-a-command), by asking a small model to label the text typed after it:
7391 
7492```javascript theme={null}
from line 106
88106})
89107```
90108 
91When you run `/triage the export button does nothing`, the mod sends that text to the model and prints its answer, such as `Label: bug`. Claude's conversation isn't part of the request. When the model doesn't answer, the label is `unknown`.
109When you run `/triage the export button does nothing`, the mod sends that text to the model and prints its answer, such as `Label: bug`. When the model doesn't answer, the label is `unknown`.
92110 
93A Claude API failure doesn't reject the call, so check `r.isAnswered`, and read `r.reason` when it's `false`. The call rejects for a request Claude Code won't send, such as a model your organization blocks. [The types for your build](/docs/en/plugins/mods/create#get-the-types-for-your-build) list the other options, such as `effort`, and the [limits](/docs/en/plugins/mods/reference#limits) give the `maxTokens` default.
111A Claude API failure doesn't reject the call, so check `r.isAnswered`, and read `r.reason` when it's `false`. The call rejects for a request Claude Code won't send, such as a model your organization blocks.
94112 
95`$.model.fork({ prompt })` asks one question over the current conversation instead, with the same model and system prompt, so the Claude API serves most of it from the prompt cache.
113[The types for your build](/docs/en/plugins/mods/create#get-the-types-for-your-build) list the other options, such as `effort`, and the [limits](/docs/en/plugins/mods/reference#limits) give the `maxTokens` default.
96114 
97These calls use the user's plan or API key.
115### Use prompt caching
116 
117`$.model.complete` supports the Claude API's [prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching). The API caches the start of a request, called the prefix, up to a [cache breakpoint](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#explicit-cache-breakpoints) that you set. When every call starts with the same long static content, such as instructions or reference material, set a breakpoint at the end of that content. Later calls then read it from the cache instead of paying the full input price for it.
118 
119To set a breakpoint, pass `prompt` as an array of `{ text }` blocks instead of a string, and add `cache: true` to the last block of the static content. Claude Code sends that block with the API's `cache_control` field. `system` takes the same array form. To decide between them, see [Choose between `prompt` and `system`](#choose-between-prompt-and-system).
120 
121<Note>
122 Arrays of blocks require Claude Code v2.1.292 or later. Earlier versions reject an array in `prompt` with an error that ends with `takes { model, prompt } (host check)`, and they leave an array in `system` out of the request.
123</Note>
124 
125This version of the [`/triage` hook](#send-one-prompt) sends a long set of labeling rules before the text to label, with a breakpoint after the rules. `RULES` is a string of your own:
126 
127```javascript theme={null}
128on('command.run', { command: 'triage' }, async ($, e) => {
129 const r = await $.model.complete({
130 model: 'haiku',
131 prompt: [
132 // Identical on every call, so it forms the cached prefix
133 { text: RULES, cache: true },
134 // Changes on every call, so it goes after the breakpoint
135 { text: e.args },
136 ],
137 })
138 return { text: 'Label: ' + (r.isAnswered ? r.text.trim() : 'unknown') }
139})
140```
141 
142The TTL and the number of breakpoints have these limits:
143 
144* **TTL**: a cache entry lasts five minutes after its last use. The TTL comes from the user's Claude Code settings, not from the call. For one hour, set [`subagentPromptCacheTtl`](/docs/en/prompt-caching#choose-the-ttl-yourself) to `1h`.
145* **Breakpoints per request**: the API accepts [up to four](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#when-to-use-multiple-breakpoints), and one more comes back as an `api-error` in `r.reason`
146 
147#### Choose between `prompt` and `system`
148 
149Put the static content that your calls share at the start of `prompt` unless you know that your requests go directly to the Claude API:
150 
151* **Directly to the Claude API, with an API key or a Claude subscription**: either field works
152* **Through [Amazon Bedrock](/docs/en/amazon-bedrock), [Claude Platform on AWS](/docs/en/claude-platform-on-aws), [Google Cloud's Agent Platform](/docs/en/google-vertex-ai), [Microsoft Foundry](/docs/en/microsoft-foundry), or an [LLM gateway](/docs/en/llm-gateway)**: use `prompt`. Claude Code begins the system prompt with an [attribution block](/docs/en/llm-gateway-protocol#system-prompt-attribution-block) whose fingerprint comes from the start of the user message. The `api.anthropic.com` endpoint strips that block before caching. Other endpoints receive it as part of the prompt, so a breakpoint in `system` can miss when `prompt` starts differently.
153* **In a mod that other people run**: use `prompt`, because you don't choose their provider
154 
155`system` comes before `prompt` in the prefix, so a breakpoint in `prompt` covers `system` too, and a call with a different `system` misses the cache.
156 
157#### Check for cache hits
158 
159The result of `$.model.complete` has a `usage` object with the API's [cache fields](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#tracking-cache-performance). `usage.cache_creation_input_tokens` counts the tokens the call wrote to the cache, and `usage.cache_read_input_tokens` counts the tokens it read from the cache. Expect a write on the first call and reads on later calls within the TTL.
160 
161If every call writes and none reads, the prefix differs between calls or the calls are further apart than the TTL. For a prefix that differs, see [Choose between `prompt` and `system`](#choose-between-prompt-and-system).
162 
163If both fields stay at zero on calls the model answered, nothing was cached. Check for each of these causes:
164 
165* **The prefix is too short**: the API doesn't cache a prefix under the model's [minimum length](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#cache-limitations), and it returns no error
166* **Prompt caching is disabled**: when a [`DISABLE_PROMPT_CACHING` variable](/docs/en/prompt-caching#disable-prompt-caching) applies to the model, Claude Code removes the breakpoints and sends the text uncached
167* **Your gateway strips `cache_control`**: a gateway can [remove the field and still return success](/docs/en/prompt-caching#where-the-cache-lives)
168* **Another mod rewrites the start of the text**: Claude Code then [sends it without breakpoints](#what-a-model-complete-hook-receives)
169 
170### What a `model.complete` hook receives
171 
172If you hook the [`model.complete`](/docs/en/plugins/mods/reference#mods-api-calls) event to inspect or change other mods' requests, read the text from these fields:
173 
174* **`e.prompt`**: always a string. When the caller passed an array, it's the blocks' text concatenated in order.
175* **`e.system`**: a string built the same way, or absent when the caller passed no `system`
176* **`e.promptBlocks` and `e.systemBlocks`**: the caller's arrays, each present when the caller passed an array for that field
177 
178Claude Code sends the strings your hook passes to `next` and uses the arrays you pass with them to place [cache breakpoints](#use-prompt-caching). It keeps the leading blocks that still match the start of the string, with their breakpoints, and sends the rest of the string with no breakpoint. For example, `next({ ...e, prompt: e.prompt + NOTE })` keeps the caller's breakpoints, and a hook that changes the start of `prompt` removes them.
98179 
99180## Run work in the background
100181 
Feedback