pi-openai-toolkit 0.3.0 → 0.4.1
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 +24 -3
- package/README_zh.md +24 -3
- package/package.json +79 -79
- package/src/config.ts +283 -273
- package/src/debug.ts +18 -7
- package/src/extension-runtime.ts +88 -52
- package/src/native-fallback.ts +2 -21
- package/src/runtime.ts +421 -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,13 @@ 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
|
-
|
|
103
|
-
api: runtime.api,
|
|
104
|
-
model: runtime.model,
|
|
105
|
-
baseUrl: runtime.baseUrl,
|
|
104
|
+
baseUrl: consumer.baseUrl,
|
|
106
105
|
});
|
|
107
106
|
|
|
108
107
|
let requestSource: "session-context" | "non-native-session-context" | "latest-native-replay";
|
|
@@ -116,10 +115,10 @@ async function runResponsesNativeCompact(
|
|
|
116
115
|
requestSource = "latest-native-replay";
|
|
117
116
|
const input: ResponsesInputItem[] = [
|
|
118
117
|
...(cloneOpaqueWindow(details.compactedWindow) as ResponsesInputItem[]),
|
|
119
|
-
...serializeLiveTailToResponsesInput({ model:
|
|
118
|
+
...serializeLiveTailToResponsesInput({ model: compactor.currentModel, entries: liveTailEntries }),
|
|
120
119
|
];
|
|
121
120
|
request = {
|
|
122
|
-
model:
|
|
121
|
+
model: compactor.model,
|
|
123
122
|
input,
|
|
124
123
|
instructions,
|
|
125
124
|
};
|
|
@@ -138,7 +137,7 @@ async function runResponsesNativeCompact(
|
|
|
138
137
|
...event.preparation.turnPrefixMessages,
|
|
139
138
|
];
|
|
140
139
|
request = serializeMessagesToCompactRequest({
|
|
141
|
-
model:
|
|
140
|
+
model: compactor.currentModel,
|
|
142
141
|
messages,
|
|
143
142
|
instructions,
|
|
144
143
|
});
|
|
@@ -148,10 +147,18 @@ async function runResponsesNativeCompact(
|
|
|
148
147
|
{
|
|
149
148
|
event: "session_before_compact.remote-v2-skip",
|
|
150
149
|
reason: latestNativeCompaction.reason,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
consumer: {
|
|
151
|
+
provider: consumer.provider,
|
|
152
|
+
api: consumer.api,
|
|
153
|
+
model: consumer.model,
|
|
154
|
+
baseUrl: consumer.baseUrl,
|
|
155
|
+
},
|
|
156
|
+
compactor: {
|
|
157
|
+
provider: compactor.provider,
|
|
158
|
+
api: compactor.api,
|
|
159
|
+
model: compactor.model,
|
|
160
|
+
baseUrl: compactor.baseUrl,
|
|
161
|
+
},
|
|
155
162
|
latestCompactionIndex: latestNativeCompaction.latestCompactionIndex,
|
|
156
163
|
latestCompactionIdentity: getCompactionIdentityDebugInfo(latestNativeCompaction.latestCompaction),
|
|
157
164
|
},
|
|
@@ -164,10 +171,10 @@ async function runResponsesNativeCompact(
|
|
|
164
171
|
// Mirror the latest codex_rs CompactionInput fields captured from the most
|
|
165
172
|
// recent live provider request for this model (tools, reasoning, etc.).
|
|
166
173
|
const extras = getCompactionRequestExtras({
|
|
167
|
-
provider:
|
|
168
|
-
api:
|
|
169
|
-
model:
|
|
170
|
-
baseUrl:
|
|
174
|
+
provider: consumer.provider,
|
|
175
|
+
api: consumer.api,
|
|
176
|
+
model: consumer.model,
|
|
177
|
+
baseUrl: consumer.baseUrl,
|
|
171
178
|
sessionId: getSessionId(ctx),
|
|
172
179
|
});
|
|
173
180
|
if (extras) {
|
|
@@ -175,7 +182,7 @@ async function runResponsesNativeCompact(
|
|
|
175
182
|
}
|
|
176
183
|
|
|
177
184
|
const compactResult = await executeRemoteV2Compaction({
|
|
178
|
-
runtime,
|
|
185
|
+
runtime: compactor,
|
|
179
186
|
request,
|
|
180
187
|
signal: event.signal,
|
|
181
188
|
settings: config,
|
|
@@ -200,10 +207,16 @@ async function runResponsesNativeCompact(
|
|
|
200
207
|
let details: NativeCompactionDetails;
|
|
201
208
|
try {
|
|
202
209
|
details = createNativeCompactionDetails({
|
|
203
|
-
provider:
|
|
204
|
-
api:
|
|
205
|
-
model:
|
|
206
|
-
baseUrl:
|
|
210
|
+
provider: consumer.provider,
|
|
211
|
+
api: consumer.api,
|
|
212
|
+
model: consumer.model,
|
|
213
|
+
baseUrl: consumer.baseUrl,
|
|
214
|
+
compactionModel: {
|
|
215
|
+
provider: compactor.provider,
|
|
216
|
+
api: compactor.api,
|
|
217
|
+
model: compactor.model,
|
|
218
|
+
baseUrl: compactor.baseUrl,
|
|
219
|
+
},
|
|
207
220
|
compactedWindow: compactResult.compactedWindow,
|
|
208
221
|
compactResponseId: compactResult.compactResponseId,
|
|
209
222
|
createdAt: compactResult.createdAt,
|
|
@@ -215,10 +228,18 @@ async function runResponsesNativeCompact(
|
|
|
215
228
|
{
|
|
216
229
|
event: "session_before_compact.invalid-native-details",
|
|
217
230
|
reason: error instanceof Error ? error.message : String(error),
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
231
|
+
consumer: {
|
|
232
|
+
provider: consumer.provider,
|
|
233
|
+
api: consumer.api,
|
|
234
|
+
model: consumer.model,
|
|
235
|
+
baseUrl: consumer.baseUrl,
|
|
236
|
+
},
|
|
237
|
+
compactor: {
|
|
238
|
+
provider: compactor.provider,
|
|
239
|
+
api: compactor.api,
|
|
240
|
+
model: compactor.model,
|
|
241
|
+
baseUrl: compactor.baseUrl,
|
|
242
|
+
},
|
|
222
243
|
},
|
|
223
244
|
config,
|
|
224
245
|
ctx,
|
|
@@ -236,9 +257,18 @@ async function runResponsesNativeCompact(
|
|
|
236
257
|
"compaction-event",
|
|
237
258
|
{
|
|
238
259
|
event: "session_before_compact.remote-v2-success",
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
260
|
+
consumer: {
|
|
261
|
+
provider: consumer.provider,
|
|
262
|
+
api: consumer.api,
|
|
263
|
+
model: consumer.model,
|
|
264
|
+
baseUrl: consumer.baseUrl,
|
|
265
|
+
},
|
|
266
|
+
compactor: {
|
|
267
|
+
provider: compactor.provider,
|
|
268
|
+
api: compactor.api,
|
|
269
|
+
model: compactor.model,
|
|
270
|
+
baseUrl: compactor.baseUrl,
|
|
271
|
+
},
|
|
242
272
|
requestSource,
|
|
243
273
|
requestInputItems: request.input.length,
|
|
244
274
|
requestExtras: extras ? Object.keys(extras) : [],
|
|
@@ -282,12 +312,16 @@ async function handleSessionBeforeCompact(event: SessionBeforeCompactEvent, ctx:
|
|
|
282
312
|
}
|
|
283
313
|
|
|
284
314
|
// Branch 1: Responses-family APIs use remote_compaction_v2 on the normal Responses stream.
|
|
285
|
-
const resolution = await
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
315
|
+
const resolution = await resolveRemoteCompactionExecution(
|
|
316
|
+
ctx,
|
|
317
|
+
{
|
|
318
|
+
enabled: config.enabled,
|
|
319
|
+
responsesApis: config.responsesApis,
|
|
320
|
+
},
|
|
321
|
+
config.remoteCompactModel,
|
|
322
|
+
);
|
|
289
323
|
if (resolution.ok) {
|
|
290
|
-
const responsesOutcome = await runResponsesNativeCompact(event, ctx, config, resolution.
|
|
324
|
+
const responsesOutcome = await runResponsesNativeCompact(event, ctx, config, resolution.execution);
|
|
291
325
|
if (responsesOutcome.outcome === "success") {
|
|
292
326
|
return { compaction: responsesOutcome.compaction };
|
|
293
327
|
}
|
|
@@ -305,11 +339,18 @@ async function handleSessionBeforeCompact(event: SessionBeforeCompactEvent, ctx:
|
|
|
305
339
|
api: resolution.api,
|
|
306
340
|
model: resolution.model,
|
|
307
341
|
baseUrl: resolution.baseUrl,
|
|
342
|
+
modelSpec: resolution.modelSpec,
|
|
308
343
|
errorMessage: resolution.errorMessage,
|
|
309
344
|
},
|
|
310
345
|
config,
|
|
311
346
|
ctx,
|
|
312
347
|
);
|
|
348
|
+
if (config.remoteCompactModel) {
|
|
349
|
+
notifyWarning(
|
|
350
|
+
ctx,
|
|
351
|
+
`remote compaction model "${config.remoteCompactModel}" unusable (${resolution.reason}); using the native fallback chain`,
|
|
352
|
+
);
|
|
353
|
+
}
|
|
313
354
|
}
|
|
314
355
|
|
|
315
356
|
// Branch 2: run pi's native compaction method with the configured model.
|
|
@@ -368,21 +409,6 @@ async function handleBeforeProviderRequest(event: BeforeProviderRequestEvent, ct
|
|
|
368
409
|
return undefined;
|
|
369
410
|
}
|
|
370
411
|
|
|
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
412
|
const resolution = await resolveNativeCompactionEnvironment(
|
|
387
413
|
ctx,
|
|
388
414
|
{
|
|
@@ -416,12 +442,22 @@ async function handleBeforeProviderRequest(event: BeforeProviderRequestEvent, ct
|
|
|
416
442
|
if (!payload) {
|
|
417
443
|
return undefined;
|
|
418
444
|
}
|
|
419
|
-
|
|
420
|
-
|
|
445
|
+
|
|
446
|
+
// Capture compact-relevant request fields (tools, reasoning, ...) for the next
|
|
447
|
+
// synthetic compact request using the active consumer's effective runtime identity.
|
|
448
|
+
// This hook runs before the separate Web Search transform, so injected native search
|
|
449
|
+
// tools are not copied into remote_compaction_v2.
|
|
450
|
+
rememberRequestContext(payload, {
|
|
421
451
|
provider: runtime.provider,
|
|
422
452
|
api: runtime.api,
|
|
423
453
|
model: runtime.model,
|
|
424
454
|
baseUrl: runtime.baseUrl,
|
|
455
|
+
sessionId: getSessionId(ctx),
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
const branchEntries = ctx.sessionManager.getBranch();
|
|
459
|
+
const latestNativeCompaction = resolveLatestNativeCompactionEntry(branchEntries, {
|
|
460
|
+
baseUrl: runtime.baseUrl,
|
|
425
461
|
});
|
|
426
462
|
if (!latestNativeCompaction.ok) {
|
|
427
463
|
writeDebugArtifact(
|
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") ||
|