@averyyy/pi-coding-agent 0.87.1-piclient.1 → 0.87.1-piclient.2

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.
@@ -33,7 +33,8 @@ import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
33
33
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
34
34
  import { convertToLlm } from "./messages.js";
35
35
  import { ModelRegistry } from "./model-registry.js";
36
- import { cancelPiServerOperations, compactPiServer, } from "./pi-server-client.js";
36
+ import { cancelPiServerOperations, compactPiServer, hashStaticContext, } from "./pi-server-client.js";
37
+ import { hashPiServerProviderMessages } from "./pi-server-protocol.js";
37
38
  import { expandPromptTemplate } from "./prompt-templates.js";
38
39
  import { CURRENT_SESSION_VERSION, getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
39
40
  import { createSyntheticSourceInfo } from "./source-info.js";
@@ -195,6 +196,7 @@ export class AgentSession {
195
196
  _prePromptCompletionPromise = undefined;
196
197
  _overflowRecoveryAttempted = false;
197
198
  _lastServerCompactionTimestamp = undefined;
199
+ _cachePrefixUnavailableReason;
198
200
  // Branch summarization state
199
201
  _branchSummaryAbortController = undefined;
200
202
  _branchSummaryCompletionPromise = undefined;
@@ -427,6 +429,8 @@ export class AgentSession {
427
429
  }
428
430
  _installAgentRequestProjection() {
429
431
  const previousPrepareRequest = this.agent.prepareRequest;
432
+ if (previousPrepareRequest)
433
+ this._cachePrefixUnavailableReason ??= "custom_prepare_request";
430
434
  this.agent.prepareRequest = async (request, signal) => {
431
435
  const canonicalContext = {
432
436
  ...request.context,
@@ -1264,6 +1268,8 @@ export class AgentSession {
1264
1268
  */
1265
1269
  _installAgentForcedPromptProjection() {
1266
1270
  const previousTransformContext = this.agent.transformContext;
1271
+ if (previousTransformContext)
1272
+ this._cachePrefixUnavailableReason ??= "custom_context_transform";
1267
1273
  this.agent.transformContext = async (messages, signal) => {
1268
1274
  const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
1269
1275
  const forced = this._runSystemPromptOptions?.forceSystemPrompt;
@@ -2280,6 +2286,58 @@ export class AgentSession {
2280
2286
  // =========================================================================
2281
2287
  // Compaction
2282
2288
  // =========================================================================
2289
+ async _buildCompactionCacheInput(model, preparation) {
2290
+ if (this._cachePrefixUnavailableReason)
2291
+ return { reason: this._cachePrefixUnavailableReason };
2292
+ if (this.agent.onPayload)
2293
+ return { reason: "request_payload_hook_active" };
2294
+ if (this._runSystemPromptOptions?.forceSystemPrompt !== undefined) {
2295
+ return { reason: "forced_system_prompt_active" };
2296
+ }
2297
+ const activeModel = this.agent.state.model;
2298
+ if (!modelsAreEqual(model, activeModel) ||
2299
+ model.api !== activeModel.api ||
2300
+ model.baseUrl !== activeModel.baseUrl) {
2301
+ return { reason: "summary_model_mismatch" };
2302
+ }
2303
+ if (!this.agent.sessionId)
2304
+ return { reason: "session_id_unavailable" };
2305
+ const projectedMessages = this.sessionManager.buildSessionProjection().messages;
2306
+ if (JSON.stringify(projectedMessages) !== JSON.stringify(this.agent.state.messages)) {
2307
+ return { reason: "request_context_mismatch" };
2308
+ }
2309
+ const fullMessages = await this.agent.convertToLlm(projectedMessages);
2310
+ const fullContext = normalizeContext({ messages: fullMessages });
2311
+ const cacheOptions = {
2312
+ sessionId: this.agent.sessionId,
2313
+ transport: this.agent.transport,
2314
+ thinkingBudgets: this.agent.thinkingBudgets,
2315
+ maxRetryDelayMs: this.agent.maxRetryDelayMs,
2316
+ };
2317
+ if (!preparation) {
2318
+ return {
2319
+ cacheContextHash: hashPiServerProviderMessages(fullMessages),
2320
+ cacheStaticContextHash: hashStaticContext({
2321
+ systemPrompt: this.systemPrompt,
2322
+ tools: this.agent.state.tools,
2323
+ messages: [],
2324
+ }),
2325
+ cacheOptions,
2326
+ reason: "exact_prefix_unavailable",
2327
+ };
2328
+ }
2329
+ const prefixMessages = await this.agent.convertToLlm(preparation.cachePrefixMessages);
2330
+ const cachePrefixContext = normalizeContext({ messages: prefixMessages });
2331
+ if (cachePrefixContext.messages.length > fullContext.messages.length ||
2332
+ cachePrefixContext.messages.some((message, index) => JSON.stringify(message) !== JSON.stringify(fullContext.messages[index]))) {
2333
+ return { reason: "projected_prefix_mismatch" };
2334
+ }
2335
+ return {
2336
+ cachePrefixContext,
2337
+ cacheOptions,
2338
+ reason: "exact_prefix_unavailable",
2339
+ };
2340
+ }
2283
2341
  async _applyPiServerCompactionResult(result, reason, willRetry) {
2284
2342
  this.sessionManager.replaceTree(result.entries, result.leafId);
2285
2343
  const sessionContext = this.sessionManager.buildSessionContext();
@@ -2338,15 +2396,20 @@ export class AgentSession {
2338
2396
  const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
2339
2397
  if (isPiServerMode()) {
2340
2398
  this._detachPiServerTerminalAssistantFailure();
2399
+ const cacheInput = await this._buildCompactionCacheInput(requestModel);
2341
2400
  const piServerResult = await compactPiServer(requestModel, {
2342
2401
  systemPrompt: this.systemPrompt,
2343
2402
  messages: this.agent.state.messages,
2344
2403
  tools: this.agent.state.tools,
2345
2404
  }, {
2405
+ ...cacheInput.cacheOptions,
2346
2406
  sessionId: this.sessionId,
2347
2407
  apiKey,
2348
2408
  headers,
2349
2409
  customInstructions,
2410
+ cacheContextHash: cacheInput.cacheContextHash,
2411
+ cacheStaticContextHash: cacheInput.cacheStaticContextHash,
2412
+ cacheFallbackReason: cacheInput.reason,
2350
2413
  settings: this.settingsManager.getCompactionSettings(),
2351
2414
  sessionTree: buildPiServerSessionTree(this.sessionManager.getEntries(), this.sessionManager.getLeafId()),
2352
2415
  signal: this._compactionAbortController.signal,
@@ -2409,7 +2472,8 @@ export class AgentSession {
2409
2472
  }
2410
2473
  else {
2411
2474
  // Generate compaction result
2412
- const result = await compact(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }));
2475
+ const cacheInput = await this._buildCompactionCacheInput(requestModel, preparation);
2476
+ const result = await compact(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }), undefined, cacheInput.cachePrefixContext, cacheInput.cacheOptions, cacheInput.reason);
2413
2477
  summary = result.summary;
2414
2478
  firstKeptEntryId = result.firstKeptEntryId;
2415
2479
  tokensBefore = result.tokensBefore;
@@ -2650,14 +2714,19 @@ export class AgentSession {
2650
2714
  abortController.signal.throwIfAborted();
2651
2715
  const { model: requestModel, apiKey, headers, } = await this._getSummarizationRequestAuth(model, abortController.signal);
2652
2716
  abortController.signal.throwIfAborted();
2717
+ const cacheInput = await this._buildCompactionCacheInput(requestModel);
2653
2718
  const piServerResult = await compactPiServer(requestModel, {
2654
2719
  systemPrompt: this.systemPrompt,
2655
2720
  messages: this.agent.state.messages,
2656
2721
  tools: this.agent.state.tools,
2657
2722
  }, {
2723
+ ...cacheInput.cacheOptions,
2658
2724
  sessionId: this.sessionId,
2659
2725
  apiKey,
2660
2726
  headers,
2727
+ cacheContextHash: cacheInput.cacheContextHash,
2728
+ cacheStaticContextHash: cacheInput.cacheStaticContextHash,
2729
+ cacheFallbackReason: cacheInput.reason,
2661
2730
  settings,
2662
2731
  preparation: preparationOptions,
2663
2732
  sessionTree: buildPiServerSessionTree(this.sessionManager.getEntries(), this.sessionManager.getLeafId()),
@@ -2726,7 +2795,8 @@ export class AgentSession {
2726
2795
  details = extensionCompaction.details;
2727
2796
  }
2728
2797
  else {
2729
- const compactResult = await compact(preparation, requestModel, apiKey, headers, undefined, abortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }));
2798
+ const cacheInput = await this._buildCompactionCacheInput(requestModel, preparation);
2799
+ const compactResult = await compact(preparation, requestModel, apiKey, headers, undefined, abortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined, cacheInput.cachePrefixContext, cacheInput.cacheOptions, cacheInput.reason);
2730
2800
  summary = compactResult.summary;
2731
2801
  firstKeptEntryId = compactResult.firstKeptEntryId;
2732
2802
  tokensBefore = compactResult.tokensBefore;