pi-openai-toolkit 0.3.0 → 0.4.0
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/README.md +25 -4
- package/README_zh.md +25 -4
- package/package.json +79 -79
- package/src/config.ts +283 -273
- package/src/debug.ts +18 -7
- package/src/extension-runtime.ts +92 -50
- package/src/native-fallback.ts +2 -21
- package/src/runtime.ts +445 -283
- package/src/supported-environment.ts +5 -0
- package/src/types.ts +18 -0
- package/tsconfig.check.json +36 -36
package/src/extension-runtime.ts
CHANGED
|
@@ -16,9 +16,9 @@ import {
|
|
|
16
16
|
import { getCompactionRequestExtras, rememberRequestContext } from "./request-context-cache";
|
|
17
17
|
import { executeRemoteV2Compaction } from "./remote-v2-client";
|
|
18
18
|
import {
|
|
19
|
-
isResponsesCompatiblePayload,
|
|
20
19
|
resolveNativeCompactionEnvironment,
|
|
21
|
-
|
|
20
|
+
resolveRemoteCompactionExecution,
|
|
21
|
+
type RemoteCompactionExecution,
|
|
22
22
|
} from "./runtime";
|
|
23
23
|
import { serializeMessagesToCompactRequest, type NativeCompactionRequestBody, type ResponsesInputItem } from "./serializer";
|
|
24
24
|
import {
|
|
@@ -59,6 +59,7 @@ function getCompactionIdentityDebugInfo(entry: { details?: unknown } | undefined
|
|
|
59
59
|
api: entry.details.api,
|
|
60
60
|
model: entry.details.model,
|
|
61
61
|
baseUrl: entry.details.baseUrl,
|
|
62
|
+
compactionModel: entry.details.compactionModel,
|
|
62
63
|
}
|
|
63
64
|
: undefined;
|
|
64
65
|
}
|
|
@@ -94,15 +95,16 @@ async function runResponsesNativeCompact(
|
|
|
94
95
|
event: SessionBeforeCompactEvent,
|
|
95
96
|
ctx: ExtensionContext,
|
|
96
97
|
config: CompactionConfig,
|
|
97
|
-
|
|
98
|
+
execution: RemoteCompactionExecution,
|
|
98
99
|
): Promise<ResponsesCompactOutcome> {
|
|
100
|
+
const { consumer, compactor } = execution;
|
|
99
101
|
const instructions = buildCompactionInstructions(ctx.getSystemPrompt(), event.customInstructions);
|
|
100
102
|
const branchEntries = ctx.sessionManager.getBranch();
|
|
101
103
|
const latestNativeCompaction = resolveLatestNativeCompactionEntry(branchEntries, {
|
|
102
|
-
provider:
|
|
103
|
-
api:
|
|
104
|
-
model:
|
|
105
|
-
baseUrl:
|
|
104
|
+
provider: consumer.provider,
|
|
105
|
+
api: consumer.api,
|
|
106
|
+
model: consumer.model,
|
|
107
|
+
baseUrl: consumer.baseUrl,
|
|
106
108
|
});
|
|
107
109
|
|
|
108
110
|
let requestSource: "session-context" | "non-native-session-context" | "latest-native-replay";
|
|
@@ -116,10 +118,10 @@ async function runResponsesNativeCompact(
|
|
|
116
118
|
requestSource = "latest-native-replay";
|
|
117
119
|
const input: ResponsesInputItem[] = [
|
|
118
120
|
...(cloneOpaqueWindow(details.compactedWindow) as ResponsesInputItem[]),
|
|
119
|
-
...serializeLiveTailToResponsesInput({ model:
|
|
121
|
+
...serializeLiveTailToResponsesInput({ model: compactor.currentModel, entries: liveTailEntries }),
|
|
120
122
|
];
|
|
121
123
|
request = {
|
|
122
|
-
model:
|
|
124
|
+
model: compactor.model,
|
|
123
125
|
input,
|
|
124
126
|
instructions,
|
|
125
127
|
};
|
|
@@ -138,7 +140,7 @@ async function runResponsesNativeCompact(
|
|
|
138
140
|
...event.preparation.turnPrefixMessages,
|
|
139
141
|
];
|
|
140
142
|
request = serializeMessagesToCompactRequest({
|
|
141
|
-
model:
|
|
143
|
+
model: compactor.currentModel,
|
|
142
144
|
messages,
|
|
143
145
|
instructions,
|
|
144
146
|
});
|
|
@@ -148,10 +150,18 @@ async function runResponsesNativeCompact(
|
|
|
148
150
|
{
|
|
149
151
|
event: "session_before_compact.remote-v2-skip",
|
|
150
152
|
reason: latestNativeCompaction.reason,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
consumer: {
|
|
154
|
+
provider: consumer.provider,
|
|
155
|
+
api: consumer.api,
|
|
156
|
+
model: consumer.model,
|
|
157
|
+
baseUrl: consumer.baseUrl,
|
|
158
|
+
},
|
|
159
|
+
compactor: {
|
|
160
|
+
provider: compactor.provider,
|
|
161
|
+
api: compactor.api,
|
|
162
|
+
model: compactor.model,
|
|
163
|
+
baseUrl: compactor.baseUrl,
|
|
164
|
+
},
|
|
155
165
|
latestCompactionIndex: latestNativeCompaction.latestCompactionIndex,
|
|
156
166
|
latestCompactionIdentity: getCompactionIdentityDebugInfo(latestNativeCompaction.latestCompaction),
|
|
157
167
|
},
|
|
@@ -164,10 +174,10 @@ async function runResponsesNativeCompact(
|
|
|
164
174
|
// Mirror the latest codex_rs CompactionInput fields captured from the most
|
|
165
175
|
// recent live provider request for this model (tools, reasoning, etc.).
|
|
166
176
|
const extras = getCompactionRequestExtras({
|
|
167
|
-
provider:
|
|
168
|
-
api:
|
|
169
|
-
model:
|
|
170
|
-
baseUrl:
|
|
177
|
+
provider: consumer.provider,
|
|
178
|
+
api: consumer.api,
|
|
179
|
+
model: consumer.model,
|
|
180
|
+
baseUrl: consumer.baseUrl,
|
|
171
181
|
sessionId: getSessionId(ctx),
|
|
172
182
|
});
|
|
173
183
|
if (extras) {
|
|
@@ -175,7 +185,7 @@ async function runResponsesNativeCompact(
|
|
|
175
185
|
}
|
|
176
186
|
|
|
177
187
|
const compactResult = await executeRemoteV2Compaction({
|
|
178
|
-
runtime,
|
|
188
|
+
runtime: compactor,
|
|
179
189
|
request,
|
|
180
190
|
signal: event.signal,
|
|
181
191
|
settings: config,
|
|
@@ -200,10 +210,16 @@ async function runResponsesNativeCompact(
|
|
|
200
210
|
let details: NativeCompactionDetails;
|
|
201
211
|
try {
|
|
202
212
|
details = createNativeCompactionDetails({
|
|
203
|
-
provider:
|
|
204
|
-
api:
|
|
205
|
-
model:
|
|
206
|
-
baseUrl:
|
|
213
|
+
provider: consumer.provider,
|
|
214
|
+
api: consumer.api,
|
|
215
|
+
model: consumer.model,
|
|
216
|
+
baseUrl: consumer.baseUrl,
|
|
217
|
+
compactionModel: {
|
|
218
|
+
provider: compactor.provider,
|
|
219
|
+
api: compactor.api,
|
|
220
|
+
model: compactor.model,
|
|
221
|
+
baseUrl: compactor.baseUrl,
|
|
222
|
+
},
|
|
207
223
|
compactedWindow: compactResult.compactedWindow,
|
|
208
224
|
compactResponseId: compactResult.compactResponseId,
|
|
209
225
|
createdAt: compactResult.createdAt,
|
|
@@ -215,10 +231,18 @@ async function runResponsesNativeCompact(
|
|
|
215
231
|
{
|
|
216
232
|
event: "session_before_compact.invalid-native-details",
|
|
217
233
|
reason: error instanceof Error ? error.message : String(error),
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
234
|
+
consumer: {
|
|
235
|
+
provider: consumer.provider,
|
|
236
|
+
api: consumer.api,
|
|
237
|
+
model: consumer.model,
|
|
238
|
+
baseUrl: consumer.baseUrl,
|
|
239
|
+
},
|
|
240
|
+
compactor: {
|
|
241
|
+
provider: compactor.provider,
|
|
242
|
+
api: compactor.api,
|
|
243
|
+
model: compactor.model,
|
|
244
|
+
baseUrl: compactor.baseUrl,
|
|
245
|
+
},
|
|
222
246
|
},
|
|
223
247
|
config,
|
|
224
248
|
ctx,
|
|
@@ -236,9 +260,18 @@ async function runResponsesNativeCompact(
|
|
|
236
260
|
"compaction-event",
|
|
237
261
|
{
|
|
238
262
|
event: "session_before_compact.remote-v2-success",
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
263
|
+
consumer: {
|
|
264
|
+
provider: consumer.provider,
|
|
265
|
+
api: consumer.api,
|
|
266
|
+
model: consumer.model,
|
|
267
|
+
baseUrl: consumer.baseUrl,
|
|
268
|
+
},
|
|
269
|
+
compactor: {
|
|
270
|
+
provider: compactor.provider,
|
|
271
|
+
api: compactor.api,
|
|
272
|
+
model: compactor.model,
|
|
273
|
+
baseUrl: compactor.baseUrl,
|
|
274
|
+
},
|
|
242
275
|
requestSource,
|
|
243
276
|
requestInputItems: request.input.length,
|
|
244
277
|
requestExtras: extras ? Object.keys(extras) : [],
|
|
@@ -282,12 +315,16 @@ async function handleSessionBeforeCompact(event: SessionBeforeCompactEvent, ctx:
|
|
|
282
315
|
}
|
|
283
316
|
|
|
284
317
|
// Branch 1: Responses-family APIs use remote_compaction_v2 on the normal Responses stream.
|
|
285
|
-
const resolution = await
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
318
|
+
const resolution = await resolveRemoteCompactionExecution(
|
|
319
|
+
ctx,
|
|
320
|
+
{
|
|
321
|
+
enabled: config.enabled,
|
|
322
|
+
responsesApis: config.responsesApis,
|
|
323
|
+
},
|
|
324
|
+
config.remoteCompactModel,
|
|
325
|
+
);
|
|
289
326
|
if (resolution.ok) {
|
|
290
|
-
const responsesOutcome = await runResponsesNativeCompact(event, ctx, config, resolution.
|
|
327
|
+
const responsesOutcome = await runResponsesNativeCompact(event, ctx, config, resolution.execution);
|
|
291
328
|
if (responsesOutcome.outcome === "success") {
|
|
292
329
|
return { compaction: responsesOutcome.compaction };
|
|
293
330
|
}
|
|
@@ -305,11 +342,18 @@ async function handleSessionBeforeCompact(event: SessionBeforeCompactEvent, ctx:
|
|
|
305
342
|
api: resolution.api,
|
|
306
343
|
model: resolution.model,
|
|
307
344
|
baseUrl: resolution.baseUrl,
|
|
345
|
+
modelSpec: resolution.modelSpec,
|
|
308
346
|
errorMessage: resolution.errorMessage,
|
|
309
347
|
},
|
|
310
348
|
config,
|
|
311
349
|
ctx,
|
|
312
350
|
);
|
|
351
|
+
if (config.remoteCompactModel) {
|
|
352
|
+
notifyWarning(
|
|
353
|
+
ctx,
|
|
354
|
+
`remote compaction model "${config.remoteCompactModel}" unusable (${resolution.reason}); using the native fallback chain`,
|
|
355
|
+
);
|
|
356
|
+
}
|
|
313
357
|
}
|
|
314
358
|
|
|
315
359
|
// Branch 2: run pi's native compaction method with the configured model.
|
|
@@ -368,21 +412,6 @@ async function handleBeforeProviderRequest(event: BeforeProviderRequestEvent, ct
|
|
|
368
412
|
return undefined;
|
|
369
413
|
}
|
|
370
414
|
|
|
371
|
-
// Capture compact-relevant request fields (tools, reasoning, ...) for the next
|
|
372
|
-
// remote_compaction_v2 call, regardless of whether this request gets rewritten.
|
|
373
|
-
if (isResponsesCompatiblePayload(event.payload)) {
|
|
374
|
-
const descriptor = ctx.model;
|
|
375
|
-
if (descriptor?.provider && descriptor.api && descriptor.baseUrl) {
|
|
376
|
-
rememberRequestContext(event.payload, {
|
|
377
|
-
provider: descriptor.provider,
|
|
378
|
-
api: descriptor.api,
|
|
379
|
-
model: descriptor.id,
|
|
380
|
-
baseUrl: descriptor.baseUrl.replace(/\/+$/, ""),
|
|
381
|
-
sessionId: getSessionId(ctx),
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
415
|
const resolution = await resolveNativeCompactionEnvironment(
|
|
387
416
|
ctx,
|
|
388
417
|
{
|
|
@@ -416,6 +445,19 @@ async function handleBeforeProviderRequest(event: BeforeProviderRequestEvent, ct
|
|
|
416
445
|
if (!payload) {
|
|
417
446
|
return undefined;
|
|
418
447
|
}
|
|
448
|
+
|
|
449
|
+
// Capture compact-relevant request fields (tools, reasoning, ...) for the next
|
|
450
|
+
// synthetic compact request using the active consumer's effective runtime identity.
|
|
451
|
+
// This hook runs before the separate Web Search transform, so injected native search
|
|
452
|
+
// tools are not copied into remote_compaction_v2.
|
|
453
|
+
rememberRequestContext(payload, {
|
|
454
|
+
provider: runtime.provider,
|
|
455
|
+
api: runtime.api,
|
|
456
|
+
model: runtime.model,
|
|
457
|
+
baseUrl: runtime.baseUrl,
|
|
458
|
+
sessionId: getSessionId(ctx),
|
|
459
|
+
});
|
|
460
|
+
|
|
419
461
|
const branchEntries = ctx.sessionManager.getBranch();
|
|
420
462
|
const latestNativeCompaction = resolveLatestNativeCompactionEntry(branchEntries, {
|
|
421
463
|
provider: runtime.provider,
|
package/src/native-fallback.ts
CHANGED
|
@@ -6,12 +6,10 @@ import {
|
|
|
6
6
|
} from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import type { ProviderHeaders } from "@earendil-works/pi-ai";
|
|
8
8
|
import { mergeProviderHeaders } from "./provider-headers";
|
|
9
|
+
import { parseModelSpec } from "./runtime";
|
|
9
10
|
import type { CompactionConfig } from "./types";
|
|
10
11
|
|
|
11
|
-
export
|
|
12
|
-
provider: string;
|
|
13
|
-
modelId: string;
|
|
14
|
-
};
|
|
12
|
+
export { parseModelSpec } from "./runtime";
|
|
15
13
|
|
|
16
14
|
export type NativeFallbackFailureReason =
|
|
17
15
|
| "no-model-configured"
|
|
@@ -43,23 +41,6 @@ type ResolvedAuth =
|
|
|
43
41
|
| { ok: true; apiKey?: string; headers?: ProviderHeaders; env?: Record<string, string> }
|
|
44
42
|
| { ok: false; error: string };
|
|
45
43
|
|
|
46
|
-
/** Parse "provider/model-id" (model ids may themselves contain slashes). */
|
|
47
|
-
export function parseModelSpec(spec: string): ParsedModelSpec | undefined {
|
|
48
|
-
const trimmed = spec.trim();
|
|
49
|
-
const separatorIndex = trimmed.indexOf("/");
|
|
50
|
-
if (separatorIndex <= 0 || separatorIndex >= trimmed.length - 1) {
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const provider = trimmed.slice(0, separatorIndex).trim();
|
|
55
|
-
const modelId = trimmed.slice(separatorIndex + 1).trim();
|
|
56
|
-
if (!provider || !modelId) {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return { provider, modelId };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
44
|
function isAbortError(error: unknown): boolean {
|
|
64
45
|
return (
|
|
65
46
|
(error instanceof DOMException && error.name === "AbortError") ||
|