@linxiraos/pi-ai 1.1.13 → 1.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -70
- package/dist/types/error/flags.d.ts +6 -0
- package/dist/types/providers/anthropic-wire.d.ts +44 -7
- package/dist/types/providers/anthropic.d.ts +42 -0
- package/dist/types/providers/github-copilot-headers.d.ts +71 -1
- package/dist/types/providers/openai-completions.d.ts +1 -1
- package/dist/types/providers/openai-shared.d.ts +8 -0
- package/dist/types/providers/vision-guard.d.ts +16 -2
- package/dist/types/registry/oauth/github-copilot.d.ts +1 -0
- package/dist/types/registry/oauth/muse-code.d.ts +4 -4
- package/dist/types/types.d.ts +47 -1
- package/dist/types/usage/charm-hyper.d.ts +2 -0
- package/dist/types/utils/block-symbols.d.ts +41 -0
- package/package.json +6 -6
- package/src/auth-storage.ts +2 -0
- package/src/error/finalize.ts +9 -2
- package/src/error/flags.ts +46 -1
- package/src/error/rate-limit.ts +14 -1
- package/src/error/retryable.ts +2 -0
- package/src/providers/amazon-bedrock.ts +35 -25
- package/src/providers/anthropic-wire.ts +42 -9
- package/src/providers/anthropic.ts +648 -82
- package/src/providers/cursor.ts +1 -1
- package/src/providers/devin.ts +1 -1
- package/src/providers/github-copilot-headers.ts +242 -1
- package/src/providers/google-gemini-cli.ts +1 -1
- package/src/providers/google-shared.ts +1 -1
- package/src/providers/ollama.ts +11 -2
- package/src/providers/openai-codex-responses.ts +7 -2
- package/src/providers/openai-completions.ts +23 -4
- package/src/providers/openai-responses.ts +17 -9
- package/src/providers/openai-shared.ts +25 -4
- package/src/providers/pi-native-server.ts +3 -0
- package/src/providers/transform-messages.ts +7 -3
- package/src/providers/vision-guard.ts +28 -2
- package/src/registry/oauth/github-copilot.ts +28 -4
- package/src/registry/oauth/muse-code.ts +2 -2
- package/src/registry/oauth/openai-codex.ts +7 -8
- package/src/stream.ts +1 -0
- package/src/types.ts +49 -1
- package/src/usage/charm-hyper.ts +95 -0
- package/src/usage/claude.ts +106 -12
- package/src/usage/kimi.ts +11 -1
- package/src/utils/block-symbols.ts +47 -0
- package/src/utils/empty-completion-retry.ts +7 -4
- package/src/utils/http-inspector.ts +1 -1
- package/src/utils/proxy.ts +4 -3
package/src/error/flags.ts
CHANGED
|
@@ -156,6 +156,13 @@ const TIMEOUT_PATTERN = /\b(?:operation\s+)?timed?\s*out\b|\btimeout\b|\bstream
|
|
|
156
156
|
const TRANSIENT_ENVELOPE_PATTERN = /anthropic stream envelope error:/i;
|
|
157
157
|
const TRANSIENT_ENVELOPE_TRUNCATION_PATTERN = /before message_(?:start|stop)/i;
|
|
158
158
|
export const STREAM_READ_ERROR_PATTERN = /stream[_ -]?read[_ -]?error/i;
|
|
159
|
+
/** Python h2/httpx diagnostics forwarded through provider or proxy error events. */
|
|
160
|
+
export const PYTHON_HTTP2_STREAM_RESET_PATTERN = /<StreamReset stream_id:\d+, error_code:(?:2|7), remote_reset:True>/;
|
|
161
|
+
/** Python h11/httpx EOF while reading an HTTP/1.1 chunked response body. */
|
|
162
|
+
export const PYTHON_HTTP_INCOMPLETE_CHUNK_PATTERN =
|
|
163
|
+
/peer closed connection without sending complete message body \(incomplete chunked read\)/;
|
|
164
|
+
/** reqwest body-frame failures forwarded by the Codex HTTP proxy. */
|
|
165
|
+
export const CODEX_HTTP_BODY_READ_ERROR_PATTERN = /\btransport error reading codex response body\b/i;
|
|
159
166
|
export const TRANSIENT_TRANSPORT_PATTERN =
|
|
160
167
|
/\b(?:no[_ -]?capacity|(?:high|peak)[ _-]?demand|(?:at|over|insufficient)[ _-]?capacity|capacity[ _-]?(?:exceeded|exhausted)|peak[ _-]?load)\b|overloaded|provider.?returned.?error|rate.?limit|too many requests|auth-gateway\s+5\d{2}(?=[:\s]|$)|\b(?:429|500|502|503|504)\b|service.?unavailable|server.?error|internal.?error|retry your request|network.?error|connection.?error|connection.?refused|unable.?to.?connect\.\s*is the computer able to access the url\?|other side closed|fetch failed|upstream.?connect|upstream.?request.?failed|reset before headers|socket hang up|timed? out|timeout|terminated|retry delay|stream stall|no error details in response|HTTP2(?:StreamReset|RefusedStream|EnhanceYourCalm)|nghttp2_(?:internal_error|refused_stream)|stream closed with error code nghttp2_(?:internal_error|refused_stream)|malformed.?function.?call/i;
|
|
161
168
|
const AUTH_FAILURE_PATTERN =
|
|
@@ -396,6 +403,8 @@ function isTransientErrorText(text: string): boolean {
|
|
|
396
403
|
return (
|
|
397
404
|
isUnexpectedSocketCloseMessage(text) ||
|
|
398
405
|
isStreamReadErrorText(text) ||
|
|
406
|
+
PYTHON_HTTP2_STREAM_RESET_PATTERN.test(text) ||
|
|
407
|
+
PYTHON_HTTP_INCOMPLETE_CHUNK_PATTERN.test(text) ||
|
|
399
408
|
(TRANSIENT_ENVELOPE_PATTERN.test(text) && TRANSIENT_ENVELOPE_TRUNCATION_PATTERN.test(text)) ||
|
|
400
409
|
TRANSIENT_TRANSPORT_PATTERN.test(text)
|
|
401
410
|
);
|
|
@@ -432,6 +441,17 @@ function matchesOverflowText(text: string): boolean {
|
|
|
432
441
|
return OVERFLOW_PATTERNS.some(p => p.test(text)) || OVERFLOW_NO_BODY_PATTERN.test(text);
|
|
433
442
|
}
|
|
434
443
|
|
|
444
|
+
/**
|
|
445
|
+
* A 4xx the provider rejected as a deterministic client error — every 4xx
|
|
446
|
+
* except 408 (Request Timeout) and 429 (Too Many Requests), the retryable
|
|
447
|
+
* pair. Mirrors the 4xx policy in {@link isProviderRetryableError}: such a
|
|
448
|
+
* request replays identically, so a transient signal riding on it (e.g. a
|
|
449
|
+
* truncation phrase in the body) must not flip it to retryable.
|
|
450
|
+
*/
|
|
451
|
+
function isTerminalClientErrorStatus(status: number | undefined): boolean {
|
|
452
|
+
return status !== undefined && status >= 400 && status < 500 && status !== 408 && status !== 429;
|
|
453
|
+
}
|
|
454
|
+
|
|
435
455
|
function classifyText(
|
|
436
456
|
errorMessage: string | undefined,
|
|
437
457
|
errorStatus: number | undefined,
|
|
@@ -483,6 +503,24 @@ function classifyText(
|
|
|
483
503
|
}
|
|
484
504
|
if (isTimeoutText(errorMessage)) kinds |= Flag.Transient | Flag.Timeout;
|
|
485
505
|
else if (isTransientErrorText(errorMessage)) kinds |= Flag.Transient;
|
|
506
|
+
// A stream truncation or forwarded Codex HTTP body-read failure may not
|
|
507
|
+
// match TRANSIENT_TRANSPORT_PATTERN. Flag it explicitly so AIError.retriable and
|
|
508
|
+
// the turn-recovery layer treat it as retryable, matching the provider
|
|
509
|
+
// retry path (isProviderRetryableError). Separate `if` (not chained onto
|
|
510
|
+
// the else-if) so a timeout whose text also reads as a truncation keeps
|
|
511
|
+
// Flag.Timeout alongside Flag.Transient. The string arm applies the strict
|
|
512
|
+
// STREAM_PARSE_DIAGNOSTIC_PATTERN, per the rationale on isTransientStreamParseError.
|
|
513
|
+
// Skip a truncation phrase that rides on a terminal 4xx (e.g. a malformed
|
|
514
|
+
// request rejected as "400 unexpected EOF"): that is a deterministic client
|
|
515
|
+
// error that replays identically, so keep it terminal. classify() carries
|
|
516
|
+
// the outer terminal status down the cause chain so a wrapped truncation
|
|
517
|
+
// (ProviderHttpError 400 → cause "unexpected EOF") is caught here too.
|
|
518
|
+
if (
|
|
519
|
+
!isTerminalClientErrorStatus(statusClean) &&
|
|
520
|
+
(isTransientStreamParseError(errorMessage) || CODEX_HTTP_BODY_READ_ERROR_PATTERN.test(errorMessage))
|
|
521
|
+
) {
|
|
522
|
+
kinds |= Flag.Transient;
|
|
523
|
+
}
|
|
486
524
|
// A concurrency cap (e.g. Vertex "Online prediction concurrent requests
|
|
487
525
|
// quota exceeded") is transient — shed-and-backoff. The bare wording need
|
|
488
526
|
// not match TRANSIENT_TRANSPORT_PATTERN, so flag it explicitly to keep
|
|
@@ -521,6 +559,11 @@ export function classify(error: unknown, api?: Api): number {
|
|
|
521
559
|
const seen = new Set<object>();
|
|
522
560
|
const causeTokenEvidence = hasCauseTokenContextOverflowEvidence(error);
|
|
523
561
|
let link: unknown = error;
|
|
562
|
+
// A terminal 4xx on an outer link governs its own cause diagnostics: a
|
|
563
|
+
// wrapped truncation is describing why the deterministic request failed,
|
|
564
|
+
// not an independently retryable transport fault. Carry it down so the
|
|
565
|
+
// stream-parse guard in classifyText sees it on the status-less cause.
|
|
566
|
+
let governingTerminalStatus: number | undefined;
|
|
524
567
|
while (link !== undefined && link !== null) {
|
|
525
568
|
if (typeof link === "object") {
|
|
526
569
|
if (seen.has(link)) break;
|
|
@@ -595,8 +638,10 @@ export function classify(error: unknown, api?: Api): number {
|
|
|
595
638
|
linkMessage = (link as { message: string }).message;
|
|
596
639
|
}
|
|
597
640
|
|
|
598
|
-
const
|
|
641
|
+
const linkStatus = status(link);
|
|
642
|
+
const textId = classifyText(linkMessage, linkStatus ?? governingTerminalStatus, causeTokenEvidence, api);
|
|
599
643
|
kinds |= textId & KIND_MASK;
|
|
644
|
+
if (isTerminalClientErrorStatus(linkStatus)) governingTerminalStatus = linkStatus;
|
|
600
645
|
|
|
601
646
|
link = typeof link === "object" && "cause" in link ? (link as { cause: unknown }).cause : undefined;
|
|
602
647
|
}
|
package/src/error/rate-limit.ts
CHANGED
|
@@ -30,6 +30,13 @@ const INSUFFICIENT_BALANCE_PATTERN = /insufficient.?balance/i;
|
|
|
30
30
|
// "credits exhausted". Account-local, so rotate to a sibling credential.
|
|
31
31
|
const CREDITS_EXHAUSTED_PATTERN =
|
|
32
32
|
/\b(?:exceed\w*|insufficient|not enough)\b[^\n]{0,40}\bcredits?\b|\bcredits?\b[^\n]{0,40}\b(?:exhausted|depleted)\b/i;
|
|
33
|
+
// Anthropic subscription entitlement wall: "Usage credits are required for this
|
|
34
|
+
// model" with `error_code: credits_required`. The account cannot serve the model
|
|
35
|
+
// at all, so rotate to a sibling rather than backing off on this one. Bounded to
|
|
36
|
+
// the documented sentence and the exact code: bare "usage credits" also appears
|
|
37
|
+
// in unrelated diagnostics ("Failed to fetch usage credits from billing
|
|
38
|
+
// service"), which must not rotate a healthy credential.
|
|
39
|
+
const ANTHROPIC_CREDITS_REQUIRED_PATTERN = /\busage credits are required\b|\bcredits_required\b/i;
|
|
33
40
|
const SPEND_LIMIT_PATTERN = /spend.?limit/i;
|
|
34
41
|
const SUBSCRIPTION_CAP_PATTERN =
|
|
35
42
|
/\b(?:subscription|plan|membership)\b[^\n]{0,80}\b(?:rate.?limits?|quota|cap)\b|\b(?:rate.?limits?|quota|cap)\b[^\n]{0,80}\b(?:subscription|plan|membership)\b/i;
|
|
@@ -234,6 +241,10 @@ export function parseRateLimitReason(errorMessage: string): RateLimitReason {
|
|
|
234
241
|
return "QUOTA_EXHAUSTED";
|
|
235
242
|
}
|
|
236
243
|
|
|
244
|
+
if (ANTHROPIC_CREDITS_REQUIRED_PATTERN.test(errorMessage)) {
|
|
245
|
+
return "QUOTA_EXHAUSTED";
|
|
246
|
+
}
|
|
247
|
+
|
|
237
248
|
if (
|
|
238
249
|
lower.includes("per minute") ||
|
|
239
250
|
lower.includes("rate limit") ||
|
|
@@ -253,6 +264,7 @@ export function parseRateLimitReason(errorMessage: string): RateLimitReason {
|
|
|
253
264
|
lower.includes("out of credits") ||
|
|
254
265
|
lower.includes("spending-limit") ||
|
|
255
266
|
lower.includes("spending limit") ||
|
|
267
|
+
lower.includes("access_terminated_error") ||
|
|
256
268
|
INSUFFICIENT_BALANCE_PATTERN.test(errorMessage) ||
|
|
257
269
|
CREDITS_EXHAUSTED_PATTERN.test(errorMessage)
|
|
258
270
|
) {
|
|
@@ -294,7 +306,7 @@ export function calculateRateLimitBackoffMs(reason: RateLimitReason): number {
|
|
|
294
306
|
|
|
295
307
|
/** Detect usage/quota limit errors in error messages (persistent, requires credential switch). */
|
|
296
308
|
const USAGE_LIMIT_PATTERN =
|
|
297
|
-
/usage.?limit|usage_limit_reached|usage_not_included|limit_reached|quota.?(?:exceeded|reached|insufficient)|额度不足|额度耗尽|resource.?exhausted|exhausted your capacity|quota will reset|insufficient.?(?:balance|quota)|balance.?exhausted|run out of credits|out of credits|spending[- _]?limit|personal-team-blocked|clinepass limit|free limit reached on model/i;
|
|
309
|
+
/usage.?limit|usage_limit_reached|usage_not_included|limit_reached|quota.?(?:exceeded|reached|insufficient)|额度不足|额度耗尽|resource.?exhausted|exhausted your capacity|quota will reset|insufficient.?(?:balance|quota)|balance.?exhausted|run out of credits|out of credits|spending[- _]?limit|personal-team-blocked|clinepass limit|free limit reached on model|access_terminated_error/i;
|
|
298
310
|
|
|
299
311
|
/**
|
|
300
312
|
* HTTP status codes that, absent richer body classification, represent an
|
|
@@ -397,6 +409,7 @@ export function matchesUsageLimitText(errorMessage: string): boolean {
|
|
|
397
409
|
if (isDashScopeTokenLimitText(errorMessage)) return false;
|
|
398
410
|
return (
|
|
399
411
|
USAGE_LIMIT_PATTERN.test(errorMessage) ||
|
|
412
|
+
ANTHROPIC_CREDITS_REQUIRED_PATTERN.test(errorMessage) ||
|
|
400
413
|
CREDITS_EXHAUSTED_PATTERN.test(errorMessage) ||
|
|
401
414
|
(CN_QUOTA_EXHAUSTED_PATTERN.test(errorMessage) && !CN_TRANSIENT_CAP_PATTERN.test(errorMessage)) ||
|
|
402
415
|
SPEND_LIMIT_PATTERN.test(errorMessage) ||
|
package/src/error/retryable.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isRetryableError, isUnexpectedSocketCloseMessage } from "@linxiraos/pi-utils";
|
|
2
2
|
import {
|
|
3
|
+
CODEX_HTTP_BODY_READ_ERROR_PATTERN,
|
|
3
4
|
isRetryableStreamEnvelopeError,
|
|
4
5
|
isTransientStreamParseError,
|
|
5
6
|
isUsageLimit,
|
|
@@ -51,6 +52,7 @@ export function isProviderRetryableError(error: unknown): boolean {
|
|
|
51
52
|
isUnexpectedSocketCloseMessage(msg) ||
|
|
52
53
|
isTransientTransportMessage(msg) ||
|
|
53
54
|
TRANSIENT_TRANSPORT_PATTERN.test(msg) ||
|
|
55
|
+
CODEX_HTTP_BODY_READ_ERROR_PATTERN.test(msg) ||
|
|
54
56
|
PROVIDER_TRANSIENT_EXTRA_PATTERN.test(msg) ||
|
|
55
57
|
isTransientStreamParseError(error) ||
|
|
56
58
|
isRetryableStreamEnvelopeError(error)
|
|
@@ -836,7 +836,7 @@ function handleMetadata(event: MetadataEvent, model: Model<"bedrock-converse-str
|
|
|
836
836
|
output.usage.cacheRead = event.usage.cacheReadInputTokens || 0;
|
|
837
837
|
output.usage.cacheWrite = event.usage.cacheWriteInputTokens || 0;
|
|
838
838
|
output.usage.totalTokens = event.usage.totalTokens || output.usage.input + output.usage.output;
|
|
839
|
-
calculateCost(model, output.usage);
|
|
839
|
+
calculateCost(model, output.usage, output.timestamp);
|
|
840
840
|
}
|
|
841
841
|
}
|
|
842
842
|
|
|
@@ -924,6 +924,34 @@ function buildSystemPrompt(
|
|
|
924
924
|
return blocks;
|
|
925
925
|
}
|
|
926
926
|
|
|
927
|
+
function buildToolResultBlock(
|
|
928
|
+
message: ToolResultMessage,
|
|
929
|
+
model: Model<"bedrock-converse-stream">,
|
|
930
|
+
hoistedImages: ImageBlockWire[],
|
|
931
|
+
): ToolResultBlockWire {
|
|
932
|
+
const content: Array<TextBlockWire | ImageBlockWire> = [];
|
|
933
|
+
for (const block of message.content) {
|
|
934
|
+
if (block.type === "image") {
|
|
935
|
+
const image: ImageBlockWire = { image: createImageBlock(block.mimeType, block.data) };
|
|
936
|
+
if (model.requiresToolResultImageHoisting) {
|
|
937
|
+
content.push({ text: "(see attached image)" });
|
|
938
|
+
hoistedImages.push(image);
|
|
939
|
+
} else {
|
|
940
|
+
content.push(image);
|
|
941
|
+
}
|
|
942
|
+
} else {
|
|
943
|
+
content.push({ text: block.text.toWellFormed() });
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return {
|
|
947
|
+
toolResult: {
|
|
948
|
+
toolUseId: normalizeToolCallId(message.toolCallId),
|
|
949
|
+
content,
|
|
950
|
+
status: message.isError ? "error" : "success",
|
|
951
|
+
},
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
|
|
927
955
|
function convertMessages(
|
|
928
956
|
context: Context,
|
|
929
957
|
model: Model<"bedrock-converse-stream">,
|
|
@@ -1022,38 +1050,20 @@ function convertMessages(
|
|
|
1022
1050
|
case "toolResult": {
|
|
1023
1051
|
// Collect all consecutive toolResult messages into a single user message —
|
|
1024
1052
|
// Bedrock requires all tool results to be in one message.
|
|
1025
|
-
const
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
toolUseId: normalizeToolCallId(m.toolCallId),
|
|
1029
|
-
content: m.content.map(c =>
|
|
1030
|
-
c.type === "image"
|
|
1031
|
-
? { image: createImageBlock(c.mimeType, c.data) }
|
|
1032
|
-
: { text: c.text.toWellFormed() },
|
|
1033
|
-
),
|
|
1034
|
-
status: m.isError ? "error" : "success",
|
|
1035
|
-
},
|
|
1036
|
-
});
|
|
1053
|
+
const contentBlocks: UserContent[] = [];
|
|
1054
|
+
const hoistedImages: ImageBlockWire[] = [];
|
|
1055
|
+
contentBlocks.push(buildToolResultBlock(m, model, hoistedImages));
|
|
1037
1056
|
|
|
1038
1057
|
let j = i + 1;
|
|
1039
1058
|
while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
|
|
1040
1059
|
const nextMsg = transformedMessages[j] as ToolResultMessage;
|
|
1041
|
-
|
|
1042
|
-
toolResult: {
|
|
1043
|
-
toolUseId: normalizeToolCallId(nextMsg.toolCallId),
|
|
1044
|
-
content: nextMsg.content.map(c =>
|
|
1045
|
-
c.type === "image"
|
|
1046
|
-
? { image: createImageBlock(c.mimeType, c.data) }
|
|
1047
|
-
: { text: c.text.toWellFormed() },
|
|
1048
|
-
),
|
|
1049
|
-
status: nextMsg.isError ? "error" : "success",
|
|
1050
|
-
},
|
|
1051
|
-
});
|
|
1060
|
+
contentBlocks.push(buildToolResultBlock(nextMsg, model, hoistedImages));
|
|
1052
1061
|
j++;
|
|
1053
1062
|
}
|
|
1054
1063
|
i = j - 1;
|
|
1055
1064
|
|
|
1056
|
-
|
|
1065
|
+
contentBlocks.push(...hoistedImages);
|
|
1066
|
+
result.push({ role: "user", content: contentBlocks });
|
|
1057
1067
|
break;
|
|
1058
1068
|
}
|
|
1059
1069
|
default:
|
|
@@ -168,6 +168,22 @@ export type FallbackBlockParam = {
|
|
|
168
168
|
to: { model: string };
|
|
169
169
|
};
|
|
170
170
|
|
|
171
|
+
/** Beta enabling server-side compaction (`compact_20260112` edit, `compaction` blocks). */
|
|
172
|
+
export const COMPACTION_BETA = "compact-2026-01-12";
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Server-side compaction summary (compact-2026-01-12). Returned at the start
|
|
176
|
+
* of the assistant response that crossed the trigger; on replay the API drops
|
|
177
|
+
* every block that precedes it, so it may open the messages array. The
|
|
178
|
+
* `encrypted_content` is opaque provider state, round-tripped verbatim.
|
|
179
|
+
*/
|
|
180
|
+
export type CompactionBlockParam = {
|
|
181
|
+
type: "compaction";
|
|
182
|
+
content: string;
|
|
183
|
+
encrypted_content?: string | null;
|
|
184
|
+
cache_control?: CacheControlEphemeral | null;
|
|
185
|
+
};
|
|
186
|
+
|
|
171
187
|
export type ContentBlockParam =
|
|
172
188
|
| TextBlockParam
|
|
173
189
|
| ImageBlockParam
|
|
@@ -180,7 +196,8 @@ export type ContentBlockParam =
|
|
|
180
196
|
| ToolRemovalBlockParam
|
|
181
197
|
| ThinkingBlockParam
|
|
182
198
|
| RedactedThinkingBlockParam
|
|
183
|
-
| FallbackBlockParam
|
|
199
|
+
| FallbackBlockParam
|
|
200
|
+
| CompactionBlockParam;
|
|
184
201
|
|
|
185
202
|
/**
|
|
186
203
|
* A single conversation turn.
|
|
@@ -276,9 +293,19 @@ export type FallbackParam = {
|
|
|
276
293
|
speed?: "fast";
|
|
277
294
|
};
|
|
278
295
|
|
|
296
|
+
/** Server-side compaction edit (compact-2026-01-12). */
|
|
297
|
+
export type CompactionEdit = {
|
|
298
|
+
type: "compact_20260112";
|
|
299
|
+
/** `input_tokens` is the only trigger; `value` must be at least 50,000. */
|
|
300
|
+
trigger?: { type: "input_tokens"; value: number };
|
|
301
|
+
pause_after_compaction?: boolean;
|
|
302
|
+
/** Replaces the API's default summarization prompt entirely. */
|
|
303
|
+
instructions?: string;
|
|
304
|
+
};
|
|
305
|
+
|
|
279
306
|
/** Claude Code context-management beta payload. */
|
|
280
307
|
export type ContextManagement = {
|
|
281
|
-
edits: Array<{ type: "clear_thinking_20251015"; keep: "all" }>;
|
|
308
|
+
edits: Array<{ type: "clear_thinking_20251015"; keep: "all" } | CompactionEdit>;
|
|
282
309
|
};
|
|
283
310
|
|
|
284
311
|
export type MessageCreateParams = {
|
|
@@ -322,7 +349,8 @@ export type StopReason =
|
|
|
322
349
|
| "pause_turn"
|
|
323
350
|
| "refusal"
|
|
324
351
|
| "sensitive"
|
|
325
|
-
| "model_context_window_exceeded"
|
|
352
|
+
| "model_context_window_exceeded"
|
|
353
|
+
| "compaction";
|
|
326
354
|
|
|
327
355
|
export type CacheCreation = {
|
|
328
356
|
ephemeral_5m_input_tokens?: number | null;
|
|
@@ -336,12 +364,15 @@ export type ServerToolUsage = {
|
|
|
336
364
|
|
|
337
365
|
/**
|
|
338
366
|
* Per-attempt token accounting inside a multi-run turn
|
|
339
|
-
* (server-side-fallback-2026-06-01). Populated whenever
|
|
340
|
-
* ran, including sticky-served turns with no `fallback`
|
|
341
|
-
*
|
|
367
|
+
* (server-side-fallback-2026-06-01, compact-2026-01-12). Populated whenever
|
|
368
|
+
* a fallback chain ran, including sticky-served turns with no `fallback`
|
|
369
|
+
* content block, and whenever the compaction beta is active. A
|
|
370
|
+
* `fallback_message` entry is the definitive "served by fallback" signal; a
|
|
371
|
+
* `compaction` entry is the summarization sampling the top-level usage
|
|
372
|
+
* excludes.
|
|
342
373
|
*/
|
|
343
374
|
export type UsageIteration = {
|
|
344
|
-
type?: "message" | "fallback_message" | string;
|
|
375
|
+
type?: "message" | "fallback_message" | "compaction" | string;
|
|
345
376
|
model?: string | null;
|
|
346
377
|
input_tokens?: number | null;
|
|
347
378
|
output_tokens?: number | null;
|
|
@@ -401,13 +432,15 @@ export type ResponseContentBlock =
|
|
|
401
432
|
| ServerToolUseBlockParam
|
|
402
433
|
| WebSearchToolResultBlockParam
|
|
403
434
|
| ToolSearchToolResultBlockParam
|
|
404
|
-
| { type: "fallback"; from: { model: string }; to: { model: string } }
|
|
435
|
+
| { type: "fallback"; from: { model: string }; to: { model: string } }
|
|
436
|
+
| { type: "compaction"; content?: string | null; encrypted_content?: string | null };
|
|
405
437
|
|
|
406
438
|
export type ContentBlockDelta =
|
|
407
439
|
| { type: "text_delta"; text: string }
|
|
408
440
|
| { type: "input_json_delta"; partial_json: string }
|
|
409
441
|
| { type: "thinking_delta"; thinking: string }
|
|
410
|
-
| { type: "signature_delta"; signature: string }
|
|
442
|
+
| { type: "signature_delta"; signature: string }
|
|
443
|
+
| { type: "compaction_delta"; content?: string | null; encrypted_content?: string | null };
|
|
411
444
|
|
|
412
445
|
export type StopDetails = {
|
|
413
446
|
type: string;
|