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