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.
@@ -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
- type NativeCompactionRuntime,
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
- runtime: NativeCompactionRuntime,
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: runtime.provider,
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: runtime.currentModel, entries: liveTailEntries }),
118
+ ...serializeLiveTailToResponsesInput({ model: compactor.currentModel, entries: liveTailEntries }),
120
119
  ];
121
120
  request = {
122
- model: runtime.currentModel.id,
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: runtime.currentModel,
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
- provider: runtime.provider,
152
- api: runtime.api,
153
- model: runtime.model,
154
- baseUrl: runtime.baseUrl,
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: runtime.provider,
168
- api: runtime.api,
169
- model: runtime.model,
170
- baseUrl: runtime.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: runtime.provider,
204
- api: runtime.api,
205
- model: runtime.model,
206
- baseUrl: runtime.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
- provider: runtime.provider,
219
- api: runtime.api,
220
- model: runtime.model,
221
- baseUrl: runtime.baseUrl,
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
- provider: runtime.provider,
240
- api: runtime.api,
241
- model: runtime.model,
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 resolveNativeCompactionEnvironment(ctx, {
286
- enabled: config.enabled,
287
- responsesApis: config.responsesApis,
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.runtime);
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
- const branchEntries = ctx.sessionManager.getBranch();
420
- const latestNativeCompaction = resolveLatestNativeCompactionEntry(branchEntries, {
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(
@@ -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 type ParsedModelSpec = {
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") ||