@dyyz1993/pi-coding-agent 0.70.3 → 0.70.5

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/core/agent-session.d.ts +4 -0
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +60 -14
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/compaction/compaction.d.ts +1 -0
  7. package/dist/core/compaction/compaction.d.ts.map +1 -1
  8. package/dist/core/compaction/compaction.js.map +1 -1
  9. package/dist/core/defaults.d.ts +1 -0
  10. package/dist/core/defaults.d.ts.map +1 -1
  11. package/dist/core/defaults.js +5 -0
  12. package/dist/core/defaults.js.map +1 -1
  13. package/dist/core/extensions/types.d.ts +4 -0
  14. package/dist/core/extensions/types.d.ts.map +1 -1
  15. package/dist/core/extensions/types.js.map +1 -1
  16. package/dist/core/model-resolver.d.ts +4 -1
  17. package/dist/core/model-resolver.d.ts.map +1 -1
  18. package/dist/core/model-resolver.js +51 -7
  19. package/dist/core/model-resolver.js.map +1 -1
  20. package/dist/core/settings-manager.d.ts +2 -0
  21. package/dist/core/settings-manager.d.ts.map +1 -1
  22. package/dist/core/settings-manager.js +4 -0
  23. package/dist/core/settings-manager.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/main.d.ts.map +1 -1
  29. package/dist/main.js +17 -2
  30. package/dist/main.js.map +1 -1
  31. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  32. package/dist/modes/interactive/interactive-mode.js +14 -1
  33. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  34. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  35. package/dist/modes/rpc/rpc-mode.js +17 -2
  36. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  37. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  38. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  39. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  40. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  41. package/examples/extensions/with-deps/package-lock.json +2 -2
  42. package/examples/extensions/with-deps/package.json +1 -1
  43. package/package.json +4 -4
@@ -24,13 +24,14 @@ import { theme } from "../modes/interactive/theme/theme.js";
24
24
  import { stripFrontmatter } from "../utils/frontmatter.js";
25
25
  import { sleep } from "../utils/sleep.js";
26
26
  import { executeBashWithOperations } from "./bash-executor.js";
27
- import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
27
+ import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
28
28
  import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
29
29
  import { exportSessionToHtml } from "./export-html/index.js";
30
30
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
31
31
  import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
32
32
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
33
33
  import { handleLargeInput } from "./large-input.js";
34
+ import { resolveModelAlias } from "./model-resolver.js";
34
35
  import { expandPromptTemplate } from "./prompt-templates.js";
35
36
  import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
36
37
  import { createSyntheticSourceInfo } from "./source-info.js";
@@ -116,6 +117,7 @@ export class AgentSession {
116
117
  _backgroundTasks = new Set();
117
118
  // Model registry for API key resolution
118
119
  _modelRegistry;
120
+ _tierModels = {};
119
121
  // Tool registry for extension getTools/setTools
120
122
  _toolRegistry = new Map();
121
123
  _toolDefinitions = new Map();
@@ -523,6 +525,12 @@ export class AgentSession {
523
525
  get model() {
524
526
  return this.agent.state.model;
525
527
  }
528
+ getTierModels() {
529
+ return this._tierModels;
530
+ }
531
+ setTierModels(mapping) {
532
+ this._tierModels = { ...mapping };
533
+ }
526
534
  /** Current thinking level */
527
535
  get thinkingLevel() {
528
536
  return this.agent.state.thinkingLevel;
@@ -1589,6 +1597,11 @@ export class AgentSession {
1589
1597
  tokensBefore,
1590
1598
  details,
1591
1599
  };
1600
+ let tokensAfter = 0;
1601
+ for (const msg of sessionContext.messages) {
1602
+ tokensAfter += estimateTokens(msg);
1603
+ }
1604
+ result.tokensAfter = tokensAfter;
1592
1605
  this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
1593
1606
  if (willRetry) {
1594
1607
  const messages = this.agent.state.messages;
@@ -1884,8 +1897,36 @@ export class AgentSession {
1884
1897
  },
1885
1898
  });
1886
1899
  }
1900
+ async _resolveOptionalModel(modelSpec) {
1901
+ if (!modelSpec)
1902
+ return this.model;
1903
+ const aliasResolved = resolveModelAlias(modelSpec, this._tierModels);
1904
+ const candidate = aliasResolved ?? modelSpec;
1905
+ let provider;
1906
+ let modelId;
1907
+ if (candidate.includes("/")) {
1908
+ const slashIdx = candidate.indexOf("/");
1909
+ provider = candidate.substring(0, slashIdx);
1910
+ modelId = candidate.substring(slashIdx + 1);
1911
+ }
1912
+ else {
1913
+ modelId = candidate;
1914
+ }
1915
+ let resolved;
1916
+ if (provider) {
1917
+ resolved = this._modelRegistry.find(provider, modelId);
1918
+ }
1919
+ if (!resolved) {
1920
+ const available = this._modelRegistry.getAvailable();
1921
+ resolved = available.find((m) => m.id === modelId);
1922
+ }
1923
+ if (resolved && this._modelRegistry.hasConfiguredAuth(resolved)) {
1924
+ return resolved;
1925
+ }
1926
+ return this.model;
1927
+ }
1887
1928
  async callLLM(options) {
1888
- const model = this.model;
1929
+ const model = await this._resolveOptionalModel(options.model);
1889
1930
  if (!model)
1890
1931
  throw new Error("No model selected");
1891
1932
  const auth = await this._modelRegistry.getApiKeyAndHeaders(model);
@@ -2052,7 +2093,7 @@ export class AgentSession {
2052
2093
  throw lastError ?? new Error("callLLMStructured failed");
2053
2094
  }
2054
2095
  async forkAgent(promptText, options) {
2055
- const model = this.model;
2096
+ const model = await this._resolveOptionalModel(options?.model);
2056
2097
  if (!model)
2057
2098
  throw new Error("No model selected");
2058
2099
  const auth = await this._modelRegistry.getApiKeyAndHeaders(model);
@@ -2800,15 +2841,10 @@ export class AgentSession {
2800
2841
  const contextWindow = model.contextWindow ?? 0;
2801
2842
  if (contextWindow <= 0)
2802
2843
  return undefined;
2803
- // After compaction, the last assistant usage reflects pre-compaction context size.
2804
- // We can only trust usage from an assistant that responded after the latest compaction.
2805
- // If no such assistant exists, context token count is unknown until the next LLM response.
2806
2844
  const branchEntries = this.sessionManager.getBranch();
2807
2845
  const latestCompaction = getLatestCompactionEntry(branchEntries);
2808
2846
  if (latestCompaction) {
2809
- // Check if there's a valid assistant usage after the compaction boundary
2810
2847
  const compactionIndex = branchEntries.lastIndexOf(latestCompaction);
2811
- let hasPostCompactionUsage = false;
2812
2848
  for (let i = branchEntries.length - 1; i > compactionIndex; i--) {
2813
2849
  const entry = branchEntries[i];
2814
2850
  if (entry.type === "message" && entry.message.role === "assistant") {
@@ -2816,18 +2852,28 @@ export class AgentSession {
2816
2852
  if (assistant.stopReason !== "aborted" && assistant.stopReason !== "error") {
2817
2853
  const contextTokens = calculateContextTokens(assistant.usage);
2818
2854
  if (contextTokens > 0) {
2819
- hasPostCompactionUsage = true;
2855
+ const percent = (contextTokens / contextWindow) * 100;
2856
+ return { tokens: contextTokens, contextWindow, percent };
2820
2857
  }
2821
- break;
2822
2858
  }
2859
+ break;
2823
2860
  }
2824
2861
  }
2825
- if (!hasPostCompactionUsage) {
2826
- return { tokens: null, contextWindow, percent: null };
2827
- }
2828
2862
  }
2829
2863
  const estimate = estimateContextTokens(this.messages);
2830
- const percent = (estimate.tokens / contextWindow) * 100;
2864
+ if (latestCompaction && estimate.lastUsageIndex !== null) {
2865
+ const usageMsg = this.messages[estimate.lastUsageIndex];
2866
+ if (usageMsg?.role === "assistant" &&
2867
+ usageMsg.timestamp <= new Date(latestCompaction.timestamp).getTime()) {
2868
+ let estimated = 0;
2869
+ for (const message of this.messages) {
2870
+ estimated += estimateTokens(message);
2871
+ }
2872
+ const fallbackPercent = contextWindow > 0 ? (estimated / contextWindow) * 100 : 0;
2873
+ return { tokens: estimated, contextWindow, percent: fallbackPercent };
2874
+ }
2875
+ }
2876
+ const percent = contextWindow > 0 ? (estimate.tokens / contextWindow) * 100 : 0;
2831
2877
  return {
2832
2878
  tokens: estimate.tokens,
2833
2879
  contextWindow,