pi-openai-toolkit 0.23.1 → 0.23.2
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/LICENSE +21 -21
- package/NOTICE +83 -83
- package/README.md +6 -2
- package/README.zh.md +6 -2
- package/config.schema.json +278 -278
- package/docs/configuration.md +306 -298
- package/docs/internals.md +184 -181
- package/package.json +136 -135
- package/src/compact-client.ts +412 -412
- package/src/compaction-projection.ts +35 -35
- package/src/config/migration.ts +103 -103
- package/src/config.ts +310 -310
- package/src/context-management/codex-provider.ts +270 -270
- package/src/context-management/history-notes.ts +357 -357
- package/src/context-management/manual-compact.ts +247 -599
- package/src/context-management/scoped-compaction.ts +89 -0
- package/src/context-management/tools.ts +371 -371
- package/src/context-management/types.ts +168 -168
- package/src/context-management/window-manager.ts +912 -905
- package/src/debug.ts +238 -238
- package/src/deferred-tool-carryover.ts +282 -282
- package/src/details-store.ts +151 -151
- package/src/extension-runtime.ts +1919 -1986
- package/src/image-generation/extension.ts +189 -189
- package/src/image-generation/protocol.ts +579 -579
- package/src/image-generation/types.ts +300 -300
- package/src/native-fallback.ts +32 -29
- package/src/payload-rewrite.ts +515 -515
- package/src/pi-context-hook.ts +117 -117
- package/src/remote-v2-client.ts +811 -811
- package/src/request-context-cache.ts +155 -155
- package/src/responses-headers.ts +180 -180
- package/src/runtime.ts +865 -865
- package/src/serializer.ts +882 -882
- package/src/supported-environment.ts +27 -27
- package/src/types.ts +565 -565
- package/src/web-search/alpha-client.ts +876 -876
- package/src/web-search/extension.ts +530 -530
- package/src/web-search/payload.ts +299 -299
- package/src/web-search/prompt.ts +60 -60
- package/src/web-search/types.ts +166 -166
- package/tsconfig.check.json +50 -50
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import {
|
|
3
|
+
estimateTokens,
|
|
4
|
+
findCutPoint,
|
|
5
|
+
type FileOperations,
|
|
6
|
+
type SessionBeforeCompactEvent,
|
|
7
|
+
type SessionEntry,
|
|
8
|
+
} from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { isRecord } from "./types";
|
|
10
|
+
import type { RemoteWindowCompactionInput } from "./window-manager";
|
|
11
|
+
|
|
12
|
+
function addFileOperation(name: string, args: unknown, files: FileOperations): void {
|
|
13
|
+
if (!isRecord(args) || typeof args.path !== "string") return;
|
|
14
|
+
if (name === "read") files.read.add(args.path);
|
|
15
|
+
else if (name === "write") files.written.add(args.path);
|
|
16
|
+
else if (name === "edit") files.edited.add(args.path);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Only canonical, current-window operations may contribute summary file metadata. */
|
|
20
|
+
function collectFileOperations(messages: readonly AgentMessage[], scope: RemoteWindowCompactionInput): FileOperations {
|
|
21
|
+
const files: FileOperations = { read: new Set(), written: new Set(), edited: new Set() };
|
|
22
|
+
const previous = scope.owningCompaction;
|
|
23
|
+
if (previous && isRecord(previous.details)) {
|
|
24
|
+
for (const path of Array.isArray(previous.details.readFiles) ? previous.details.readFiles : []) {
|
|
25
|
+
if (typeof path === "string") files.read.add(path);
|
|
26
|
+
}
|
|
27
|
+
for (const path of Array.isArray(previous.details.modifiedFiles) ? previous.details.modifiedFiles : []) {
|
|
28
|
+
if (typeof path === "string") files.edited.add(path);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
for (const message of messages) {
|
|
32
|
+
if (message.role === "assistant") {
|
|
33
|
+
for (const block of message.content) if (block.type === "toolCall") addFileOperation(block.name, block.arguments, files);
|
|
34
|
+
} else if (message.role === "toolResult") {
|
|
35
|
+
for (const call of message.nestedCalls?.calls ?? []) addFileOperation(call.name, call.arguments, files);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return files;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Adapt canonical contributions to the public cut-point primitive. These are
|
|
43
|
+
* detached in-memory views with REAL source IDs, never entries to persist.
|
|
44
|
+
* Omitted entries contribute nothing; edited messages replace their raw values.
|
|
45
|
+
*/
|
|
46
|
+
export function prepareScopedNativeCompaction(
|
|
47
|
+
event: SessionBeforeCompactEvent,
|
|
48
|
+
scope: RemoteWindowCompactionInput,
|
|
49
|
+
): SessionBeforeCompactEvent {
|
|
50
|
+
const entries: SessionEntry[] = [];
|
|
51
|
+
for (const projected of scope.entries) {
|
|
52
|
+
if (projected.sourceEntry.type === "compaction") continue;
|
|
53
|
+
const messages = projected.messages.filter((message) => message.role !== "system");
|
|
54
|
+
if (!messages.length) continue;
|
|
55
|
+
// A single retained ID cannot safely identify a split within one source.
|
|
56
|
+
if (messages.length !== 1) throw new Error("compaction-source-projection-unavailable");
|
|
57
|
+
entries.push({ type: "message", id: projected.sourceEntry.id, parentId: projected.sourceEntry.parentId,
|
|
58
|
+
timestamp: projected.sourceEntry.timestamp, message: structuredClone(messages[0]!) });
|
|
59
|
+
}
|
|
60
|
+
if (!entries.length) throw new Error("unsafe-compaction-retained-start");
|
|
61
|
+
const settings = event.preparation.settings;
|
|
62
|
+
if (!settings || !Number.isFinite(settings.keepRecentTokens) || !Number.isFinite(settings.reserveTokens)) {
|
|
63
|
+
throw new Error("compaction-settings-unavailable");
|
|
64
|
+
}
|
|
65
|
+
const owner = scope.owningCompaction;
|
|
66
|
+
const ownerIndex = owner ? event.branchEntries.findIndex((entry) => entry.id === owner.id) : -1;
|
|
67
|
+
if (owner && ownerIndex < scope.windowBoundaryIndex) throw new Error("compaction-owner-mismatch");
|
|
68
|
+
const lowerIndex = Math.max(scope.windowBoundaryIndex, ownerIndex);
|
|
69
|
+
const minimumKeptIndex = entries.findIndex((entry) => event.branchEntries.findIndex((raw) => raw.id === entry.id) >= lowerIndex);
|
|
70
|
+
if (minimumKeptIndex < 0) throw new Error("compaction-current-window-too-small");
|
|
71
|
+
const cut = findCutPoint(entries, minimumKeptIndex, entries.length, settings.keepRecentTokens);
|
|
72
|
+
const kept = entries[cut.firstKeptEntryIndex];
|
|
73
|
+
if (kept?.type !== "message" || kept.message.role === "toolResult") throw new Error("unsafe-compaction-retained-start");
|
|
74
|
+
const firstKeptEntryId = kept.id;
|
|
75
|
+
if (!firstKeptEntryId) throw new Error("unsafe-compaction-retained-start");
|
|
76
|
+
const messages = (start: number, end: number) => entries.slice(start, end).flatMap((entry) => entry.type === "message" ? [entry.message] : []);
|
|
77
|
+
const messagesToSummarize = messages(0, cut.isSplitTurn ? cut.turnStartIndex : cut.firstKeptEntryIndex);
|
|
78
|
+
const turnPrefixMessages = cut.isSplitTurn ? messages(cut.turnStartIndex, cut.firstKeptEntryIndex) : [];
|
|
79
|
+
return {
|
|
80
|
+
...event,
|
|
81
|
+
preparation: {
|
|
82
|
+
firstKeptEntryId, messagesToSummarize, turnPrefixMessages, isSplitTurn: cut.isSplitTurn,
|
|
83
|
+
tokensBefore: scope.messages.reduce((tokens, message) => tokens + estimateTokens(message), 0),
|
|
84
|
+
previousSummary: scope.owningCompaction?.summary,
|
|
85
|
+
fileOps: collectFileOperations([...messagesToSummarize, ...turnPrefixMessages], scope),
|
|
86
|
+
settings: { ...settings },
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|