@howaboua/pi-codex-conversion 1.5.5-dev.25.f80a775 → 1.5.5
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/package.json +1 -1
- package/src/adapter/activation.ts +0 -1
- package/src/adapter/config.ts +0 -24
- package/src/adapter/provider-request.ts +2 -4
- package/src/adapter/tool-set.ts +1 -2
- package/src/codex-settings/command.ts +3 -16
- package/src/codex-settings/ui.ts +48 -126
- package/src/index.ts +18 -34
- package/src/providers/openai-codex-custom-provider.ts +1 -1
- package/src/providers/openai-responses-shared.ts +0 -2
- package/vendor/apply-patch/win32-arm64/apply_patch.exe +0 -0
- package/vendor/apply-patch/win32-x64/apply_patch.exe +0 -0
- package/src/adapter/compact-client.ts +0 -257
- package/src/adapter/compaction-output.ts +0 -80
- package/src/adapter/compaction-runtime.ts +0 -272
- package/src/adapter/compaction.ts +0 -261
- package/src/adapter/context-filter.ts +0 -20
- package/src/adapter/details-store.ts +0 -151
- package/src/adapter/payload-rewrite.ts +0 -550
- package/src/adapter/serializer.ts +0 -288
- package/src/adapter/types.ts +0 -220
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
4
|
-
import { convertToLlm, getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
5
|
-
import type { Api, ImageContent, Message, Model, TextContent, ToolResultMessage, UserMessage } from "@earendil-works/pi-ai";
|
|
6
|
-
import type { ResponsesCompatibleRequestPayload } from "./compaction-runtime.ts";
|
|
7
|
-
import { CODEX_TOOL_CALL_PROVIDERS, convertResponsesMessages } from "../providers/openai-responses-shared.ts";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Decision for native compaction: reuse the provider's Responses serializer.
|
|
11
|
-
*
|
|
12
|
-
* Replay parity must match the actual OpenAI Codex provider payload, including
|
|
13
|
-
* tool-call id normalization and cross-model/provider history handling.
|
|
14
|
-
*/
|
|
15
|
-
export const COMPACTION_SERIALIZER_STRATEGY = "provider-responses-serializer" as const;
|
|
16
|
-
|
|
17
|
-
export type CompactionSerializerStrategy = typeof COMPACTION_SERIALIZER_STRATEGY;
|
|
18
|
-
export type AssistantPhase = "commentary" | "final_answer";
|
|
19
|
-
|
|
20
|
-
type ResponsesTextInputItem = {
|
|
21
|
-
type: "input_text";
|
|
22
|
-
text: string;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
type ResponsesImageInputItem = {
|
|
26
|
-
type: "input_image";
|
|
27
|
-
detail: "auto";
|
|
28
|
-
image_url: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type ResponsesInputContentItem = ResponsesTextInputItem | ResponsesImageInputItem;
|
|
32
|
-
|
|
33
|
-
export type ResponsesInputMessageItem = {
|
|
34
|
-
role: "user" | "developer" | "system";
|
|
35
|
-
content: ResponsesInputContentItem[] | string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export type ResponsesAssistantOutputItem = {
|
|
39
|
-
type: "message";
|
|
40
|
-
role: "assistant";
|
|
41
|
-
content: Array<{
|
|
42
|
-
type: "output_text";
|
|
43
|
-
text: string;
|
|
44
|
-
annotations: [];
|
|
45
|
-
}>;
|
|
46
|
-
status: "completed";
|
|
47
|
-
id: string;
|
|
48
|
-
phase?: AssistantPhase;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export type ResponsesFunctionCallItem = {
|
|
52
|
-
type: "function_call";
|
|
53
|
-
id?: string;
|
|
54
|
-
call_id: string;
|
|
55
|
-
name: string;
|
|
56
|
-
arguments: string;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export type ResponsesFunctionCallOutputItem = {
|
|
60
|
-
type: "function_call_output";
|
|
61
|
-
call_id: string;
|
|
62
|
-
output: ResponsesInputContentItem[] | string;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export type ResponsesReasoningItem = Record<string, unknown>;
|
|
66
|
-
|
|
67
|
-
export type ResponsesInputItem =
|
|
68
|
-
| ResponsesInputMessageItem
|
|
69
|
-
| ResponsesAssistantOutputItem
|
|
70
|
-
| ResponsesFunctionCallItem
|
|
71
|
-
| ResponsesFunctionCallOutputItem
|
|
72
|
-
| ResponsesReasoningItem;
|
|
73
|
-
|
|
74
|
-
export type NativeCompactionRequestBody = {
|
|
75
|
-
model: string;
|
|
76
|
-
input: ResponsesInputItem[];
|
|
77
|
-
instructions: string;
|
|
78
|
-
parallel_tool_calls?: boolean;
|
|
79
|
-
prompt_cache_key?: string;
|
|
80
|
-
service_tier?: string;
|
|
81
|
-
text?: { verbosity: string };
|
|
82
|
-
tools?: unknown[];
|
|
83
|
-
reasoning?: unknown;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export type NativeCompactionRequestOptions = Pick<
|
|
87
|
-
NativeCompactionRequestBody,
|
|
88
|
-
"parallel_tool_calls" | "prompt_cache_key" | "service_tier" | "text" | "tools" | "reasoning"
|
|
89
|
-
>;
|
|
90
|
-
|
|
91
|
-
export type SerializeResponsesMessagesOptions = {
|
|
92
|
-
instructions?: string;
|
|
93
|
-
includeInstructionsInInput?: boolean;
|
|
94
|
-
blockImages?: boolean;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export type ResponsesParityReport = {
|
|
98
|
-
ok: boolean;
|
|
99
|
-
actual: string[];
|
|
100
|
-
expected: string[];
|
|
101
|
-
mismatches: string[];
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
function sanitizeSurrogates(text: string): string {
|
|
106
|
-
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
110
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
let cachedBlockImagesSetting: boolean | undefined;
|
|
114
|
-
|
|
115
|
-
function readBlockImagesSetting(): boolean {
|
|
116
|
-
if (cachedBlockImagesSetting !== undefined) return cachedBlockImagesSetting;
|
|
117
|
-
try {
|
|
118
|
-
const parsed = JSON.parse(readFileSync(join(getAgentDir(), "settings.json"), "utf-8")) as unknown;
|
|
119
|
-
cachedBlockImagesSetting = isRecord(parsed) && isRecord(parsed.images) && parsed.images.blockImages === true;
|
|
120
|
-
} catch {
|
|
121
|
-
cachedBlockImagesSetting = false;
|
|
122
|
-
}
|
|
123
|
-
return cachedBlockImagesSetting;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function replaceImagesWithDisabledPlaceholder<TMessage extends UserMessage | ToolResultMessage>(message: TMessage): TMessage {
|
|
127
|
-
if (!Array.isArray(message.content) || !message.content.some((item) => item.type === "image")) return message;
|
|
128
|
-
const content = message.content
|
|
129
|
-
.map((item): TextContent | ImageContent => item.type === "image" ? { type: "text", text: "Image reading is disabled." } : item)
|
|
130
|
-
.filter((item, index, items) => {
|
|
131
|
-
const previous = items[index - 1];
|
|
132
|
-
return !(item.type === "text" && item.text === "Image reading is disabled." && previous?.type === "text" && previous.text === "Image reading is disabled.");
|
|
133
|
-
});
|
|
134
|
-
return { ...message, content };
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function applyBlockImages(messages: Message[], blockImages: boolean): Message[] {
|
|
138
|
-
if (!blockImages) return messages;
|
|
139
|
-
return messages.map((message) => {
|
|
140
|
-
if (message.role === "user" || message.role === "toolResult") return replaceImagesWithDisabledPlaceholder(message);
|
|
141
|
-
return message;
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
type CompactionPreparationLike = { messagesToSummarize: AgentMessage[]; turnPrefixMessages: AgentMessage[]; previousSummary?: string };
|
|
146
|
-
|
|
147
|
-
export function collectCompactionWindowMessages(preparation: CompactionPreparationLike): AgentMessage[] {
|
|
148
|
-
const previousSummary = preparation.previousSummary?.trim();
|
|
149
|
-
const previousSummaryMessages: AgentMessage[] = previousSummary
|
|
150
|
-
? [
|
|
151
|
-
{
|
|
152
|
-
role: "user",
|
|
153
|
-
content: `Previous compaction summary:\n${previousSummary}`,
|
|
154
|
-
timestamp: Date.now(),
|
|
155
|
-
} as AgentMessage,
|
|
156
|
-
]
|
|
157
|
-
: [];
|
|
158
|
-
return [...previousSummaryMessages, ...preparation.messagesToSummarize, ...preparation.turnPrefixMessages];
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function serializeCompactionPreparationToRequest<TApi extends Api>(args: {
|
|
162
|
-
model: Model<TApi>;
|
|
163
|
-
preparation: CompactionPreparationLike;
|
|
164
|
-
instructions: string;
|
|
165
|
-
requestOptions?: NativeCompactionRequestOptions;
|
|
166
|
-
}): NativeCompactionRequestBody {
|
|
167
|
-
return serializeMessagesToCompactRequest({
|
|
168
|
-
model: args.model,
|
|
169
|
-
messages: collectCompactionWindowMessages(args.preparation),
|
|
170
|
-
instructions: args.instructions,
|
|
171
|
-
requestOptions: args.requestOptions,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export function serializeMessagesToCompactRequest<TApi extends Api>(args: {
|
|
176
|
-
model: Model<TApi>;
|
|
177
|
-
messages: AgentMessage[];
|
|
178
|
-
instructions: string;
|
|
179
|
-
requestOptions?: NativeCompactionRequestOptions;
|
|
180
|
-
}): NativeCompactionRequestBody {
|
|
181
|
-
return {
|
|
182
|
-
model: args.model.id,
|
|
183
|
-
input: serializeMessagesToResponsesInput(args.model, args.messages),
|
|
184
|
-
instructions: sanitizeSurrogates(args.instructions),
|
|
185
|
-
...args.requestOptions,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function serializeMessagesToResponsesInput<TApi extends Api>(
|
|
190
|
-
model: Model<TApi>,
|
|
191
|
-
messages: AgentMessage[],
|
|
192
|
-
options: SerializeResponsesMessagesOptions = {},
|
|
193
|
-
): ResponsesInputItem[] {
|
|
194
|
-
const llmMessages = applyBlockImages(convertToLlm(messages), options.blockImages ?? readBlockImagesSetting());
|
|
195
|
-
return convertResponsesMessages(
|
|
196
|
-
model,
|
|
197
|
-
{
|
|
198
|
-
messages: llmMessages,
|
|
199
|
-
...(options.includeInstructionsInInput && options.instructions ? { systemPrompt: options.instructions } : {}),
|
|
200
|
-
},
|
|
201
|
-
CODEX_TOOL_CALL_PROVIDERS,
|
|
202
|
-
{ includeSystemPrompt: options.includeInstructionsInInput ?? false },
|
|
203
|
-
) as ResponsesInputItem[];
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export function createResponsesInputParitySignature(input: readonly unknown[]): string[] {
|
|
207
|
-
return input.map(describeResponsesInputItem);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export function compareResponsesInputParity(actual: readonly unknown[], expected: readonly unknown[]): ResponsesParityReport {
|
|
211
|
-
const actualSignature = createResponsesInputParitySignature(actual);
|
|
212
|
-
const expectedSignature = createResponsesInputParitySignature(expected);
|
|
213
|
-
const maxLength = Math.max(actualSignature.length, expectedSignature.length);
|
|
214
|
-
const mismatches: string[] = [];
|
|
215
|
-
|
|
216
|
-
for (let index = 0; index < maxLength; index++) {
|
|
217
|
-
const actualValue = actualSignature[index];
|
|
218
|
-
const expectedValue = expectedSignature[index];
|
|
219
|
-
if (actualValue !== expectedValue) {
|
|
220
|
-
mismatches.push(`index ${index}: expected ${expectedValue ?? "<missing>"}, got ${actualValue ?? "<missing>"}`);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return {
|
|
225
|
-
ok: mismatches.length === 0,
|
|
226
|
-
actual: actualSignature,
|
|
227
|
-
expected: expectedSignature,
|
|
228
|
-
mismatches,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
export function compareCompactRequestToPayload(
|
|
233
|
-
request: NativeCompactionRequestBody,
|
|
234
|
-
payload: Pick<ResponsesCompatibleRequestPayload, "model" | "input" | "instructions">,
|
|
235
|
-
): ResponsesParityReport {
|
|
236
|
-
const parity = compareResponsesInputParity(request.input, payload.input);
|
|
237
|
-
const mismatches = [...parity.mismatches];
|
|
238
|
-
|
|
239
|
-
if (payload.model !== request.model) {
|
|
240
|
-
mismatches.unshift(`model: expected ${payload.model}, got ${request.model}`);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if ((payload.instructions ?? "") !== request.instructions) {
|
|
244
|
-
mismatches.unshift("instructions: expected serialized instructions to match payload instructions");
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return {
|
|
248
|
-
ok: mismatches.length === 0,
|
|
249
|
-
actual: parity.actual,
|
|
250
|
-
expected: parity.expected,
|
|
251
|
-
mismatches,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function describeResponsesInputItem(item: unknown): string {
|
|
256
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
257
|
-
return typeof item;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const record = item as Record<string, unknown>;
|
|
261
|
-
const type = typeof record.type === "string" ? record.type : undefined;
|
|
262
|
-
if (type === "message") {
|
|
263
|
-
const phase =
|
|
264
|
-
record.phase === "commentary" || record.phase === "final_answer"
|
|
265
|
-
? `:${record.phase}`
|
|
266
|
-
: "";
|
|
267
|
-
return `message:${typeof record.role === "string" ? record.role : "unknown"}${phase}`;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (type === "function_call") {
|
|
271
|
-
return `function_call:${typeof record.name === "string" ? record.name : "unknown"}`;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (type === "function_call_output") {
|
|
275
|
-
return "function_call_output";
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (type === "reasoning") {
|
|
279
|
-
return "reasoning";
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (typeof record.role === "string") {
|
|
283
|
-
const content = Array.isArray(record.content) ? `[${record.content.length}]` : "";
|
|
284
|
-
return `input:${record.role}${content}`;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return type ? `item:${type}` : "object";
|
|
288
|
-
}
|
package/src/adapter/types.ts
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import type { CompactionEntry, CompactionResult } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
|
|
3
|
-
export const EXTENSION_ID = "openai-native-compaction";
|
|
4
|
-
export const NATIVE_COMPACTION_STRATEGY = "openai-native-compact-v1";
|
|
5
|
-
export const NATIVE_COMPACTION_SHIM_SUMMARY = "[OpenAI native compaction checkpoint]";
|
|
6
|
-
export const NATIVE_COMPACTION_DISPLAY_MESSAGE_TYPE = "codex-native-compaction-display";
|
|
7
|
-
export const NATIVE_COMPACTION_DISPLAY_TEXT = [
|
|
8
|
-
"Codex native compaction was used for this checkpoint.",
|
|
9
|
-
"",
|
|
10
|
-
"The compaction result is encrypted by OpenAI and is not human-readable in Pi.",
|
|
11
|
-
"",
|
|
12
|
-
"Warning: do not turn Responses compaction off mid-session; old context may be much less reliable.",
|
|
13
|
-
].join("\n");
|
|
14
|
-
|
|
15
|
-
export type NativeCompactionStrategy = typeof NATIVE_COMPACTION_STRATEGY;
|
|
16
|
-
export type NativeCompactionShimSummary = typeof NATIVE_COMPACTION_SHIM_SUMMARY;
|
|
17
|
-
|
|
18
|
-
export type NativeCompactionRequestMeta = {
|
|
19
|
-
tokensBefore?: number;
|
|
20
|
-
previousSummaryPresent?: boolean;
|
|
21
|
-
compactedKeptWindow?: boolean;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type NativeCompactionIdentity = {
|
|
25
|
-
provider: string;
|
|
26
|
-
api: string;
|
|
27
|
-
model: string;
|
|
28
|
-
baseUrl: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type NativeCompactionDetails = NativeCompactionIdentity & {
|
|
32
|
-
strategy: NativeCompactionStrategy;
|
|
33
|
-
compactedWindow: unknown[];
|
|
34
|
-
compactResponseId?: string;
|
|
35
|
-
createdAt: string;
|
|
36
|
-
requestMeta?: NativeCompactionRequestMeta;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export type NativeCompactionEntry = CompactionEntry<NativeCompactionDetails>;
|
|
40
|
-
|
|
41
|
-
export type CreateNativeCompactionDetailsInput = NativeCompactionIdentity & {
|
|
42
|
-
compactedWindow: unknown[];
|
|
43
|
-
compactResponseId?: string;
|
|
44
|
-
createdAt?: string;
|
|
45
|
-
requestMeta?: NativeCompactionRequestMeta;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export type CreateNativeCompactionShimResultInput = {
|
|
49
|
-
summary: string;
|
|
50
|
-
firstKeptEntryId: string;
|
|
51
|
-
tokensBefore: number;
|
|
52
|
-
details: NativeCompactionDetails;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
56
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function isNonEmptyString(value: unknown): value is string {
|
|
60
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function isFiniteNonNegativeNumber(value: unknown): value is number {
|
|
64
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function normalizeString(value: string): string {
|
|
68
|
-
return value.trim();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function isStructuredValue(value: unknown): boolean {
|
|
72
|
-
if (
|
|
73
|
-
value === null ||
|
|
74
|
-
typeof value === "string" ||
|
|
75
|
-
typeof value === "number" ||
|
|
76
|
-
typeof value === "boolean"
|
|
77
|
-
) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (Array.isArray(value)) {
|
|
82
|
-
return value.every(isStructuredValue);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (isRecord(value)) {
|
|
86
|
-
return Object.values(value).every(isStructuredValue);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function cloneStructuredValue(value: unknown): unknown {
|
|
93
|
-
if (
|
|
94
|
-
value === null ||
|
|
95
|
-
typeof value === "string" ||
|
|
96
|
-
typeof value === "number" ||
|
|
97
|
-
typeof value === "boolean"
|
|
98
|
-
) {
|
|
99
|
-
return value;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (Array.isArray(value)) {
|
|
103
|
-
return value.map(cloneStructuredValue);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (isRecord(value)) {
|
|
107
|
-
const clone: Record<string, unknown> = {};
|
|
108
|
-
for (const [key, nested] of Object.entries(value)) {
|
|
109
|
-
clone[key] = cloneStructuredValue(nested);
|
|
110
|
-
}
|
|
111
|
-
return clone;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
throw new Error(`Unsupported structured value: ${typeof value}`);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function isCompactedWindowItem(value: unknown): value is Record<string, unknown> {
|
|
118
|
-
return isRecord(value) && Object.values(value).every(isStructuredValue);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function isNativeCompactionRequestMeta(value: unknown): value is NativeCompactionRequestMeta {
|
|
122
|
-
if (!isRecord(value)) {
|
|
123
|
-
return false;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const { tokensBefore, previousSummaryPresent, compactedKeptWindow } = value;
|
|
127
|
-
if (tokensBefore !== undefined && !isFiniteNonNegativeNumber(tokensBefore)) {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (previousSummaryPresent !== undefined && typeof previousSummaryPresent !== "boolean") {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (compactedKeptWindow !== undefined && typeof compactedKeptWindow !== "boolean") {
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export function isNativeCompactionIdentity(value: unknown): value is NativeCompactionIdentity {
|
|
143
|
-
if (!isRecord(value)) {
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return (
|
|
148
|
-
isNonEmptyString(value.provider) &&
|
|
149
|
-
isNonEmptyString(value.api) &&
|
|
150
|
-
isNonEmptyString(value.model) &&
|
|
151
|
-
isNonEmptyString(value.baseUrl)
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function isNativeCompactionDetails(value: unknown): value is NativeCompactionDetails {
|
|
156
|
-
if (!isRecord(value)) {
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
const candidate = value as Record<string, unknown>;
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
candidate.strategy === NATIVE_COMPACTION_STRATEGY &&
|
|
163
|
-
isNonEmptyString(candidate.provider) &&
|
|
164
|
-
isNonEmptyString(candidate.api) &&
|
|
165
|
-
isNonEmptyString(candidate.model) &&
|
|
166
|
-
isNonEmptyString(candidate.baseUrl) &&
|
|
167
|
-
Array.isArray(candidate.compactedWindow) &&
|
|
168
|
-
candidate.compactedWindow.every(isCompactedWindowItem) &&
|
|
169
|
-
isNonEmptyString(candidate.createdAt) &&
|
|
170
|
-
(candidate.compactResponseId === undefined || isNonEmptyString(candidate.compactResponseId)) &&
|
|
171
|
-
(candidate.requestMeta === undefined || isNativeCompactionRequestMeta(candidate.requestMeta))
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export function isNativeCompactionEntry(value: unknown): value is NativeCompactionEntry {
|
|
176
|
-
return isRecord(value) && value.type === "compaction" && isNativeCompactionDetails(value.details);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export function isNativeCompactionShimSummary(value: unknown): value is NativeCompactionShimSummary {
|
|
180
|
-
return value === NATIVE_COMPACTION_SHIM_SUMMARY;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export function createNativeCompactionDetails(input: CreateNativeCompactionDetailsInput): NativeCompactionDetails {
|
|
184
|
-
return {
|
|
185
|
-
strategy: NATIVE_COMPACTION_STRATEGY,
|
|
186
|
-
provider: normalizeString(input.provider),
|
|
187
|
-
api: normalizeString(input.api),
|
|
188
|
-
model: normalizeString(input.model),
|
|
189
|
-
baseUrl: normalizeString(input.baseUrl),
|
|
190
|
-
compactedWindow: input.compactedWindow.map((item) => cloneStructuredValue(item)),
|
|
191
|
-
compactResponseId: isNonEmptyString(input.compactResponseId) ? normalizeString(input.compactResponseId) : undefined,
|
|
192
|
-
createdAt: isNonEmptyString(input.createdAt) ? normalizeString(input.createdAt) : new Date().toISOString(),
|
|
193
|
-
requestMeta: input.requestMeta
|
|
194
|
-
? {
|
|
195
|
-
...(input.requestMeta.tokensBefore !== undefined ? { tokensBefore: input.requestMeta.tokensBefore } : {}),
|
|
196
|
-
...(input.requestMeta.previousSummaryPresent !== undefined
|
|
197
|
-
? { previousSummaryPresent: input.requestMeta.previousSummaryPresent }
|
|
198
|
-
: {}),
|
|
199
|
-
...(input.requestMeta.compactedKeptWindow !== undefined
|
|
200
|
-
? { compactedKeptWindow: input.requestMeta.compactedKeptWindow }
|
|
201
|
-
: {}),
|
|
202
|
-
}
|
|
203
|
-
: undefined,
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export function createNativeCompactionShimSummary(): NativeCompactionShimSummary {
|
|
208
|
-
return NATIVE_COMPACTION_SHIM_SUMMARY;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export function createNativeCompactionShimResult(
|
|
212
|
-
input: CreateNativeCompactionShimResultInput,
|
|
213
|
-
): CompactionResult<NativeCompactionDetails> {
|
|
214
|
-
return {
|
|
215
|
-
summary: input.summary,
|
|
216
|
-
firstKeptEntryId: input.firstKeptEntryId,
|
|
217
|
-
tokensBefore: input.tokensBefore,
|
|
218
|
-
details: input.details,
|
|
219
|
-
};
|
|
220
|
-
}
|