@oh-my-pi/pi-agent-core 18.12.3 → 18.12.4
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
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.12.4] - 2026-10-20
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Enabled native compaction for supported Bedrock Claude models ([#16343](https://github.com/can1357/oh-my-pi/pull/16343) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy))
|
|
10
|
+
|
|
5
11
|
## [18.12.3] - 2026-10-19
|
|
6
12
|
|
|
7
13
|
### Added
|
|
@@ -14,6 +14,8 @@ export declare const ANTHROPIC_COMPACTION_PRESERVE_KEY = "anthropicCompaction";
|
|
|
14
14
|
export interface AnthropicCompactionPreserveData {
|
|
15
15
|
provider: string;
|
|
16
16
|
content: string;
|
|
17
|
+
/** Opaque signed tool-change records; replayed without normalization. */
|
|
18
|
+
toolChanges?: Record<string, unknown>[];
|
|
17
19
|
/** Signature attached to an on-demand block; replayed verbatim. */
|
|
18
20
|
signature?: string;
|
|
19
21
|
/** Legacy threshold block state; replay-only. */
|
|
@@ -35,9 +37,11 @@ export interface AnthropicCompactionPreserveData {
|
|
|
35
37
|
* lineage the beta documents); endpoint eligibility is resolved the way the
|
|
36
38
|
* provider routes requests, so a Foundry or `ANTHROPIC_BASE_URL` reroute of a
|
|
37
39
|
* first-party model is excluded unless the route opted in with
|
|
38
|
-
* `remoteCompaction.enabled`.
|
|
40
|
+
* `remoteCompaction.enabled`. Bedrock Converse models compact through a
|
|
41
|
+
* Bedrock Runtime side request; their ordinary turns stay on Converse.
|
|
39
42
|
*/
|
|
40
|
-
export declare function shouldUseAnthropicNativeCompaction(model: Model): model is Model<"anthropic-messages">;
|
|
43
|
+
export declare function shouldUseAnthropicNativeCompaction(model: Model): model is Model<"anthropic-messages" | "bedrock-converse-stream">;
|
|
44
|
+
type AnthropicNativeCompactionModel = Model<"anthropic-messages" | "bedrock-converse-stream">;
|
|
41
45
|
export declare function getPreservedAnthropicCompactionData(preserveData: Record<string, unknown> | undefined): AnthropicCompactionPreserveData | undefined;
|
|
42
46
|
/** Set or strip the Anthropic compaction slot; a new compaction never inherits a stale summary. */
|
|
43
47
|
export declare function withAnthropicCompactionPreserveData(preserveData: Record<string, unknown> | undefined, compaction: AnthropicCompactionPreserveData | undefined): Record<string, unknown> | undefined;
|
|
@@ -67,6 +71,7 @@ export interface AnthropicNativeCompactionRequest {
|
|
|
67
71
|
export interface AnthropicNativeCompactionResponse {
|
|
68
72
|
content: string;
|
|
69
73
|
signature: string;
|
|
74
|
+
toolChanges?: Record<string, unknown>[];
|
|
70
75
|
usage: Usage;
|
|
71
76
|
model: string;
|
|
72
77
|
}
|
|
@@ -81,4 +86,5 @@ export interface AnthropicNativeCompactionOptions extends Pick<SimpleStreamOptio
|
|
|
81
86
|
* without a summary is a native failure, including tool use, refusals and
|
|
82
87
|
* output limits; the configured method order can then choose a fallback.
|
|
83
88
|
*/
|
|
84
|
-
export declare function requestAnthropicNativeCompaction(model:
|
|
89
|
+
export declare function requestAnthropicNativeCompaction(model: AnthropicNativeCompactionModel, apiKey: ApiKey, request: AnthropicNativeCompactionRequest, signal: AbortSignal | undefined, options: AnthropicNativeCompactionOptions): Promise<AnthropicNativeCompactionResponse>;
|
|
90
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-agent-core",
|
|
4
|
-
"version": "18.12.
|
|
4
|
+
"version": "18.12.4",
|
|
5
5
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": {
|
|
@@ -38,16 +38,16 @@
|
|
|
38
38
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@oh-my-pi/pi-ai": "18.12.
|
|
42
|
-
"@oh-my-pi/pi-catalog": "18.12.
|
|
43
|
-
"@oh-my-pi/pi-natives": "18.12.
|
|
44
|
-
"@oh-my-pi/pi-utils": "18.12.
|
|
45
|
-
"@oh-my-pi/pi-wire": "18.12.
|
|
46
|
-
"@oh-my-pi/snapcompact": "18.12.
|
|
41
|
+
"@oh-my-pi/pi-ai": "18.12.4",
|
|
42
|
+
"@oh-my-pi/pi-catalog": "18.12.4",
|
|
43
|
+
"@oh-my-pi/pi-natives": "18.12.4",
|
|
44
|
+
"@oh-my-pi/pi-utils": "18.12.4",
|
|
45
|
+
"@oh-my-pi/pi-wire": "18.12.4",
|
|
46
|
+
"@oh-my-pi/snapcompact": "18.12.4",
|
|
47
47
|
"@opentelemetry/api": "^1.9.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@oh-my-pi/omptype": "18.12.
|
|
50
|
+
"@oh-my-pi/omptype": "18.12.4",
|
|
51
51
|
"@opentelemetry/context-async-hooks": "^2.9.0",
|
|
52
52
|
"@opentelemetry/sdk-trace-base": "^2.9.0",
|
|
53
53
|
"@types/bun": "^1.3.14"
|
|
@@ -19,7 +19,10 @@ import type {
|
|
|
19
19
|
} from "@oh-my-pi/pi-ai";
|
|
20
20
|
import * as AIError from "@oh-my-pi/pi-ai/error";
|
|
21
21
|
import { resolveAnthropicCompactionEffort } from "@oh-my-pi/pi-ai/providers/anthropic";
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
supportsAnthropicCompaction,
|
|
24
|
+
supportsBedrockConverseCompaction,
|
|
25
|
+
} from "@oh-my-pi/pi-ai/providers/anthropic-compaction";
|
|
23
26
|
import { isRecord, prompt } from "@oh-my-pi/pi-utils";
|
|
24
27
|
import { type InstrumentedChatSpanOptions, instrumentedCompleteSimple } from "../telemetry";
|
|
25
28
|
import type { AgentMessage } from "../types";
|
|
@@ -31,6 +34,8 @@ export const ANTHROPIC_COMPACTION_PRESERVE_KEY = "anthropicCompaction";
|
|
|
31
34
|
export interface AnthropicCompactionPreserveData {
|
|
32
35
|
provider: string;
|
|
33
36
|
content: string;
|
|
37
|
+
/** Opaque signed tool-change records; replayed without normalization. */
|
|
38
|
+
toolChanges?: Record<string, unknown>[];
|
|
34
39
|
/** Signature attached to an on-demand block; replayed verbatim. */
|
|
35
40
|
signature?: string;
|
|
36
41
|
/** Legacy threshold block state; replay-only. */
|
|
@@ -51,18 +56,28 @@ function isAnthropicMessagesModel(model: Model): model is Model<"anthropic-messa
|
|
|
51
56
|
return model.api === "anthropic-messages";
|
|
52
57
|
}
|
|
53
58
|
|
|
59
|
+
function isBedrockConverseModel(model: Model): model is Model<"bedrock-converse-stream"> {
|
|
60
|
+
return model.api === "bedrock-converse-stream";
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
/**
|
|
55
64
|
* Whether a model compacts through the Anthropic compaction beta. Model
|
|
56
65
|
* eligibility is catalog policy (`compat.supportsServerCompaction`, the
|
|
57
66
|
* lineage the beta documents); endpoint eligibility is resolved the way the
|
|
58
67
|
* provider routes requests, so a Foundry or `ANTHROPIC_BASE_URL` reroute of a
|
|
59
68
|
* first-party model is excluded unless the route opted in with
|
|
60
|
-
* `remoteCompaction.enabled`.
|
|
69
|
+
* `remoteCompaction.enabled`. Bedrock Converse models compact through a
|
|
70
|
+
* Bedrock Runtime side request; their ordinary turns stay on Converse.
|
|
61
71
|
*/
|
|
62
|
-
export function shouldUseAnthropicNativeCompaction(
|
|
63
|
-
|
|
72
|
+
export function shouldUseAnthropicNativeCompaction(
|
|
73
|
+
model: Model,
|
|
74
|
+
): model is Model<"anthropic-messages" | "bedrock-converse-stream"> {
|
|
75
|
+
if (isAnthropicMessagesModel(model)) return supportsAnthropicCompaction(model);
|
|
76
|
+
return isBedrockConverseModel(model) && supportsBedrockConverseCompaction(model);
|
|
64
77
|
}
|
|
65
78
|
|
|
79
|
+
type AnthropicNativeCompactionModel = Model<"anthropic-messages" | "bedrock-converse-stream">;
|
|
80
|
+
|
|
66
81
|
export function getPreservedAnthropicCompactionData(
|
|
67
82
|
preserveData: Record<string, unknown> | undefined,
|
|
68
83
|
): AnthropicCompactionPreserveData | undefined {
|
|
@@ -70,6 +85,9 @@ export function getPreservedAnthropicCompactionData(
|
|
|
70
85
|
if (!isRecord(candidate)) return undefined;
|
|
71
86
|
if (typeof candidate.provider !== "string" || candidate.provider.length === 0) return undefined;
|
|
72
87
|
if (typeof candidate.content !== "string" || candidate.content.length === 0) return undefined;
|
|
88
|
+
const toolChanges = candidate.toolChanges;
|
|
89
|
+
// The signature covers `tool_changes`: a block missing or mangling them cannot replay.
|
|
90
|
+
if (toolChanges !== undefined && (!Array.isArray(toolChanges) || !toolChanges.every(isRecord))) return undefined;
|
|
73
91
|
return {
|
|
74
92
|
provider: candidate.provider,
|
|
75
93
|
content: candidate.content,
|
|
@@ -90,6 +108,7 @@ export function getPreservedAnthropicCompactionData(
|
|
|
90
108
|
),
|
|
91
109
|
}
|
|
92
110
|
: {}),
|
|
111
|
+
...(toolChanges !== undefined ? { toolChanges } : {}),
|
|
93
112
|
...(candidate.exactTail === true ? { exactTail: true as const } : {}),
|
|
94
113
|
...(typeof candidate.model === "string" ? { model: candidate.model } : {}),
|
|
95
114
|
...(typeof candidate.usedTokens === "number" ? { usedTokens: candidate.usedTokens } : {}),
|
|
@@ -124,6 +143,7 @@ export function getAnthropicCompactionPayload(
|
|
|
124
143
|
...(preserved.signature ? { signature: preserved.signature } : {}),
|
|
125
144
|
...(preserved.encryptedContent ? { encryptedContent: preserved.encryptedContent } : {}),
|
|
126
145
|
...(preserved.filesText ? { filesText: preserved.filesText } : {}),
|
|
146
|
+
...(preserved.toolChanges ? { toolChanges: preserved.toolChanges } : {}),
|
|
127
147
|
...(preserved.retainedFiles?.length ? { retainedFiles: preserved.retainedFiles } : {}),
|
|
128
148
|
...(preserved.exactTail ? { exactTail: true as const } : {}),
|
|
129
149
|
};
|
|
@@ -196,6 +216,7 @@ export interface AnthropicNativeCompactionRequest {
|
|
|
196
216
|
export interface AnthropicNativeCompactionResponse {
|
|
197
217
|
content: string;
|
|
198
218
|
signature: string;
|
|
219
|
+
toolChanges?: Record<string, unknown>[];
|
|
199
220
|
usage: Usage;
|
|
200
221
|
model: string;
|
|
201
222
|
}
|
|
@@ -224,7 +245,7 @@ export interface AnthropicNativeCompactionOptions
|
|
|
224
245
|
* output limits; the configured method order can then choose a fallback.
|
|
225
246
|
*/
|
|
226
247
|
export async function requestAnthropicNativeCompaction(
|
|
227
|
-
model:
|
|
248
|
+
model: AnthropicNativeCompactionModel,
|
|
228
249
|
apiKey: ApiKey,
|
|
229
250
|
request: AnthropicNativeCompactionRequest,
|
|
230
251
|
signal: AbortSignal | undefined,
|
|
@@ -237,7 +258,9 @@ export async function requestAnthropicNativeCompaction(
|
|
|
237
258
|
apiKey,
|
|
238
259
|
signal,
|
|
239
260
|
maxTokens: request.maxTokens,
|
|
240
|
-
reasoning:
|
|
261
|
+
reasoning: isAnthropicMessagesModel(model)
|
|
262
|
+
? resolveAnthropicCompactionEffort(model, request.context.messages, request.reasoning)
|
|
263
|
+
: request.reasoning,
|
|
241
264
|
initiatorOverride: options.initiatorOverride,
|
|
242
265
|
metadata: options.metadata,
|
|
243
266
|
fetch: options.fetch,
|
|
@@ -279,6 +302,7 @@ export async function requestAnthropicNativeCompaction(
|
|
|
279
302
|
return {
|
|
280
303
|
content: payload.content,
|
|
281
304
|
signature: payload.signature,
|
|
305
|
+
...(payload.toolChanges ? { toolChanges: payload.toolChanges } : {}),
|
|
282
306
|
usage: response.usage,
|
|
283
307
|
model: response.model,
|
|
284
308
|
};
|
|
@@ -2024,6 +2024,7 @@ export async function compact(
|
|
|
2024
2024
|
let nativeFirstKeptEntryId = firstKeptEntryId;
|
|
2025
2025
|
let nativeUsedTokens: number | undefined;
|
|
2026
2026
|
let nativeRetainedFiles: AnthropicCompactionFiles[] | undefined;
|
|
2027
|
+
let nativeToolChanges: Record<string, unknown>[] | undefined;
|
|
2027
2028
|
if (!usedRemoteCompaction && settings.remoteEnabled !== false && shouldUseAnthropicNativeCompaction(model)) {
|
|
2028
2029
|
const previousNative = getPreservedAnthropicCompactionData(previousPreserveData);
|
|
2029
2030
|
// Lead with the previous summary as the live context renders it:
|
|
@@ -2052,6 +2053,7 @@ export async function compact(
|
|
|
2052
2053
|
: {}),
|
|
2053
2054
|
...(previousNative.filesText ? { filesText: previousNative.filesText } : {}),
|
|
2054
2055
|
...(previousNative.retainedFiles ? { retainedFiles: previousNative.retainedFiles } : {}),
|
|
2056
|
+
...(previousNative.toolChanges ? { toolChanges: previousNative.toolChanges } : {}),
|
|
2055
2057
|
...(previousNative.exactTail ? { exactTail: true as const } : {}),
|
|
2056
2058
|
}
|
|
2057
2059
|
: undefined,
|
|
@@ -2148,6 +2150,7 @@ export async function compact(
|
|
|
2148
2150
|
);
|
|
2149
2151
|
nativeSummary = remote.content;
|
|
2150
2152
|
nativeSignature = remote.signature;
|
|
2153
|
+
nativeToolChanges = remote.toolChanges;
|
|
2151
2154
|
nativeUsedTokens = calculatePromptTokens(remote.usage);
|
|
2152
2155
|
usedRemoteCompaction = true;
|
|
2153
2156
|
} catch (err) {
|
|
@@ -2235,16 +2238,18 @@ export async function compact(
|
|
|
2235
2238
|
const { readFiles, modifiedFiles } = computeFileLists(fileOps);
|
|
2236
2239
|
summary = upsertFileOperations(summary, readFiles, modifiedFiles, fileOps.read);
|
|
2237
2240
|
if (nativeSummary !== undefined) {
|
|
2238
|
-
// The replayed block
|
|
2239
|
-
// matches its signature. The
|
|
2240
|
-
// separately: the converter replaces the
|
|
2241
|
-
// block and skips its text, so they would
|
|
2242
|
-
// this provider. Every other provider keeps
|
|
2241
|
+
// The replayed block (summary and any `tool_changes`) stays
|
|
2242
|
+
// byte-identical to the API's output so it matches its signature. The
|
|
2243
|
+
// harness file lists above travel separately: the converter replaces the
|
|
2244
|
+
// summary message with the block and skips its text, so they would
|
|
2245
|
+
// otherwise be invisible to this provider. Every other provider keeps
|
|
2246
|
+
// reading the entry text.
|
|
2243
2247
|
const filesText = upsertFileOperations("", readFiles, modifiedFiles, fileOps.read) || undefined;
|
|
2244
2248
|
preserveData = withAnthropicCompactionPreserveData(preserveData, {
|
|
2245
2249
|
provider: model.provider,
|
|
2246
2250
|
content: nativeSummary,
|
|
2247
2251
|
...(nativeSignature ? { signature: nativeSignature } : {}),
|
|
2252
|
+
...(nativeToolChanges ? { toolChanges: nativeToolChanges } : {}),
|
|
2248
2253
|
...(filesText ? { filesText } : {}),
|
|
2249
2254
|
...(nativeRetainedFiles ? { retainedFiles: nativeRetainedFiles } : {}),
|
|
2250
2255
|
exactTail: true,
|