mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
Anthropic message threads (#11545)
Anthropic can keep a conversation on the server (message threads beta). A request can then continue from the previous reply and send only the new messages, instead of the whole history every turn. pi uses this when a session id is set and caching is on. It still builds the full request, compares it with the previous one, and only sends the new part if nothing earlier changed. - Default: on only for the anthropic provider on api.anthropic.com. Gateways that drop unknown fields would lose the conversation. Override with compat.supportsMessageThreads. - If the server rejects a continuation, pi resends the full request as a new thread. Other errors turn threads off for the session. - New option StreamOptions.disableContinuation. The cache warmer sets it so warm requests don't replace the session's thread. - cleanupSessionResources(sessionId) frees a session's thread state.
This commit is contained in:
parent
3551ec07eb
commit
a758f3ae4c
14 changed files with 885 additions and 22 deletions
|
|
@ -5,6 +5,7 @@
|
|||
### Added
|
||||
|
||||
- `pi update` now lists each updated package with its npm version or git commit change, for example `npm:foo 1.2.0 -> 1.3.0`, and prints `Packages are already up to date` when nothing changed. When nothing changed but an update printed a warning, for example because npm left the old version installed after resolving stale registry metadata, it prints `No packages were updated, see the warnings above` instead; in offline mode it prints `Skipped package updates (offline mode)`. `PackageManager.update()` reports each changed package as a new `result` progress event whose `message` holds that line ([#11707](https://github.com/earendil-works/pi/pull/11707), [#11711](https://github.com/earendil-works/pi/pull/11711))
|
||||
- Anthropic sessions now use message threads: each request sends only the new messages and the server continues from the previous reply, falling back to the full request when the conversation changed (for example after compaction or a tool list change). On by default for the `anthropic` provider on `api.anthropic.com`; set `compat.supportsMessageThreads` in `models.json` to enable it for gateways that forward the `thread` field, or to turn it off. Cache warming does not touch the session's thread ([#11545](https://github.com/earendil-works/pi/pull/11545))
|
||||
|
||||
## [1.5.0] - 2026-11-02
|
||||
|
||||
|
|
|
|||
|
|
@ -878,6 +878,8 @@ pi.on("before_provider_request", (event, ctx) => {
|
|||
|
||||
This is mainly useful for debugging provider serialization and cache behavior.
|
||||
|
||||
The payload is the full request. Providers that continue from a previous response (OpenAI Codex over WebSocket, Anthropic message threads) may send only the part that is new since the previous request.
|
||||
|
||||
#### after_provider_response
|
||||
|
||||
Fired after an HTTP response is received and before its stream body is consumed. Handlers run in extension load order.
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ Also applies to `azure-openai-responses` and `openai-codex-responses`.
|
|||
| `supportsMidConvoEffort` | boolean | `false` | Whether the exact model transport supports effort-only system messages and thinking binding controls. |
|
||||
| `supportsMidConvoSystemMessages` | boolean | `false` | Whether the exact model accepts system-role messages inside the conversation. When false, later system messages are folded into the top-level system prompt. |
|
||||
| `supportsMidConvoToolChanges` | boolean | `false` | Whether the exact model accepts mid-conversation tool_addition and tool_removal blocks. Requires supportsMidConvoSystemMessages. |
|
||||
| `supportsMessageThreads` | boolean | | Whether the endpoint supports Anthropic message threads, which let a request with a session id send only the new messages and continue from the previous reply. Default: true for provider anthropic with a baseUrl on api.anthropic.com, false otherwise. Set true for gateways that forward the thread request field. |
|
||||
| `allowedFallbackModels` | `object[]` | | Models Anthropic accepts for server-side refusal fallback, with local pricing metadata for returned fallback responses. When absent or empty, callers must omit fallbacks; Anthropic rejects the field for models with no permitted fallback targets. |
|
||||
|
||||
### `bedrock-converse-stream`
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,10 @@
|
|||
"description": "Whether the exact model accepts mid-conversation tool_addition and tool_removal blocks. Requires supportsMidConvoSystemMessages.",
|
||||
"default": false
|
||||
},
|
||||
"supportsMessageThreads": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the endpoint supports Anthropic message threads, which let a request with a session id send only the new messages and continue from the previous reply. Default: true for provider anthropic with a baseUrl on api.anthropic.com, false otherwise. Set true for gateways that forward the thread request field."
|
||||
},
|
||||
"allowedFallbackModels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
|
|
|||
|
|
@ -333,6 +333,8 @@ export class CacheWarmer {
|
|||
.streamSimple(run.model, run.context, {
|
||||
...run.options,
|
||||
maxTokens: 1,
|
||||
// The warm request repeats the last request; it must not replace the conversation's thread state.
|
||||
disableContinuation: true,
|
||||
maxRetries: 0,
|
||||
signal: run.controller.signal,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -155,7 +155,14 @@ describe("cache warming", () => {
|
|||
|
||||
expect(calls[0]).toMatchObject({
|
||||
model: adaptiveModel,
|
||||
options: { reasoning: "high", sessionId: "s", transformHeaders, maxTokens: 1, maxRetries: 0 },
|
||||
options: {
|
||||
reasoning: "high",
|
||||
sessionId: "s",
|
||||
transformHeaders,
|
||||
maxTokens: 1,
|
||||
maxRetries: 0,
|
||||
disableContinuation: true,
|
||||
},
|
||||
});
|
||||
expect(calls[0].options?.signal).not.toBe(signal);
|
||||
expect(events[0]).toMatchObject({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue