@code-yeongyu/senpi 2026.5.16 → 2026.5.18-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.
Files changed (94) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/dist/cli/config-selector.d.ts.map +1 -1
  3. package/dist/cli/config-selector.js +1 -1
  4. package/dist/cli/config-selector.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +5 -1
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +12 -3
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/agent-session.d.ts +2 -0
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +47 -6
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/compaction/compaction.d.ts +5 -3
  16. package/dist/core/compaction/compaction.d.ts.map +1 -1
  17. package/dist/core/compaction/compaction.js +22 -14
  18. package/dist/core/compaction/compaction.js.map +1 -1
  19. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js +5 -128
  21. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js.map +1 -1
  22. package/dist/core/model-registry.d.ts +1 -0
  23. package/dist/core/model-registry.d.ts.map +1 -1
  24. package/dist/core/model-registry.js +64 -9
  25. package/dist/core/model-registry.js.map +1 -1
  26. package/dist/core/package-manager.d.ts +5 -0
  27. package/dist/core/package-manager.d.ts.map +1 -1
  28. package/dist/core/package-manager.js +72 -31
  29. package/dist/core/package-manager.js.map +1 -1
  30. package/dist/core/prompt-templates.d.ts.map +1 -1
  31. package/dist/core/prompt-templates.js +6 -4
  32. package/dist/core/prompt-templates.js.map +1 -1
  33. package/dist/core/session-manager.d.ts.map +1 -1
  34. package/dist/core/session-manager.js +38 -8
  35. package/dist/core/session-manager.js.map +1 -1
  36. package/dist/core/skills.d.ts.map +1 -1
  37. package/dist/core/skills.js +2 -5
  38. package/dist/core/skills.js.map +1 -1
  39. package/dist/core/system-prompt.d.ts.map +1 -1
  40. package/dist/core/system-prompt.js +3 -2
  41. package/dist/core/system-prompt.js.map +1 -1
  42. package/dist/core/tools/diff-render.d.ts +13 -0
  43. package/dist/core/tools/diff-render.d.ts.map +1 -0
  44. package/dist/core/tools/diff-render.js +130 -0
  45. package/dist/core/tools/diff-render.js.map +1 -0
  46. package/dist/core/tools/edit.d.ts.map +1 -1
  47. package/dist/core/tools/edit.js +8 -3
  48. package/dist/core/tools/edit.js.map +1 -1
  49. package/dist/core/tools/write.d.ts.map +1 -1
  50. package/dist/core/tools/write.js +28 -7
  51. package/dist/core/tools/write.js.map +1 -1
  52. package/dist/modes/interactive/components/config-selector.d.ts +2 -2
  53. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  54. package/dist/modes/interactive/components/config-selector.js +7 -4
  55. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  56. package/dist/modes/interactive/components/footer.d.ts +0 -1
  57. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/footer.js +42 -44
  59. package/dist/modes/interactive/components/footer.js.map +1 -1
  60. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  61. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  62. package/dist/modes/interactive/interactive-mode.js +55 -48
  63. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  64. package/dist/modes/interactive/session-info-format.d.ts +3 -0
  65. package/dist/modes/interactive/session-info-format.d.ts.map +1 -0
  66. package/dist/modes/interactive/session-info-format.js +44 -0
  67. package/dist/modes/interactive/session-info-format.js.map +1 -0
  68. package/dist/modes/interactive/working-status.d.ts +6 -0
  69. package/dist/modes/interactive/working-status.d.ts.map +1 -1
  70. package/dist/modes/interactive/working-status.js +11 -0
  71. package/dist/modes/interactive/working-status.js.map +1 -1
  72. package/dist/package-manager-cli.d.ts.map +1 -1
  73. package/dist/package-manager-cli.js +3 -4
  74. package/dist/package-manager-cli.js.map +1 -1
  75. package/dist/senpi +5 -1
  76. package/dist/utils/child-process.d.ts +7 -1
  77. package/dist/utils/child-process.d.ts.map +1 -1
  78. package/dist/utils/child-process.js +60 -7
  79. package/dist/utils/child-process.js.map +1 -1
  80. package/dist/utils/tools-manager.d.ts.map +1 -1
  81. package/dist/utils/tools-manager.js +4 -1
  82. package/dist/utils/tools-manager.js.map +1 -1
  83. package/docs/custom-provider.md +55 -0
  84. package/docs/extensions.md +1 -1
  85. package/docs/settings.md +1 -3
  86. package/docs/skills.md +3 -4
  87. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  88. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  89. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  90. package/examples/extensions/sandbox/package-lock.json +2 -2
  91. package/examples/extensions/sandbox/package.json +1 -1
  92. package/examples/extensions/with-deps/package-lock.json +2 -2
  93. package/examples/extensions/with-deps/package.json +1 -1
  94. package/package.json +6 -6
@@ -15,7 +15,7 @@
15
15
  import { randomUUID } from "node:crypto";
16
16
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
17
17
  import { basename, dirname, resolve } from "node:path";
18
- import { cleanupSessionResources, isContextOverflow, modelsAreEqual, resetApiProviders } from "@earendil-works/pi-ai";
18
+ import { cleanupSessionResources, isContextOverflow, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai";
19
19
  import { expandTildePath } from "../config.js";
20
20
  import { theme } from "../modes/interactive/theme/theme.js";
21
21
  import { stripFrontmatter } from "../utils/frontmatter.js";
@@ -97,6 +97,7 @@ export class AgentSession {
97
97
  _retryAttempt = 0;
98
98
  _retryPromise = undefined;
99
99
  _retryResolve = undefined;
100
+ _userAbortPromise = undefined;
100
101
  // Bash execution state
101
102
  _bashAbortController = undefined;
102
103
  _pendingBashMessages = [];
@@ -150,6 +151,19 @@ export class AgentSession {
150
151
  }
151
152
  this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
152
153
  this._installAgentToolHooks();
154
+ const previousPrepareNextTurn = this.agent.prepareNextTurn;
155
+ this.agent.prepareNextTurn = async (signal) => {
156
+ const nextTurn = await previousPrepareNextTurn?.(signal);
157
+ const model = this.agent.state.model;
158
+ if (!model) {
159
+ return nextTurn;
160
+ }
161
+ return {
162
+ ...nextTurn,
163
+ model,
164
+ thinkingLevel: this.agent.state.thinkingLevel,
165
+ };
166
+ };
153
167
  this._buildRuntime({
154
168
  activeToolNames: this._initialActiveToolNames,
155
169
  includeAllExtensionTools: true,
@@ -178,6 +192,13 @@ export class AgentSession {
178
192
  }
179
193
  throw new Error(formatNoApiKeyFoundMessage(model.provider));
180
194
  }
195
+ async _getCompactionRequestAuth(model) {
196
+ if (this.agent.streamFn === streamSimple) {
197
+ return this._getRequiredRequestAuth(model);
198
+ }
199
+ const result = await this._modelRegistry.getApiKeyAndHeaders(model);
200
+ return result.ok ? { apiKey: result.apiKey, headers: result.headers, extraBody: result.extraBody } : {};
201
+ }
181
202
  /**
182
203
  * Install tool hooks once on the Agent instance.
183
204
  *
@@ -746,6 +767,10 @@ export class AgentSession {
746
767
  * @throws Error if no model selected or no API key available (when not streaming)
747
768
  */
748
769
  async prompt(text, options) {
770
+ const userAbortPromise = this._userAbortPromise;
771
+ if (userAbortPromise) {
772
+ await userAbortPromise;
773
+ }
749
774
  const expandPromptTemplates = options?.expandPromptTemplates ?? true;
750
775
  const preflightResult = options?.preflightResult;
751
776
  let messages;
@@ -1115,8 +1140,24 @@ export class AgentSession {
1115
1140
  */
1116
1141
  async abort() {
1117
1142
  this.abortRetry();
1118
- this.agent.abort();
1119
- await this.agent.waitForIdle();
1143
+ if (this._userAbortPromise) {
1144
+ this.agent.abort();
1145
+ await this._userAbortPromise;
1146
+ return;
1147
+ }
1148
+ const abortPromise = (async () => {
1149
+ this.agent.abort();
1150
+ await this.agent.waitForIdle();
1151
+ })();
1152
+ this._userAbortPromise = abortPromise;
1153
+ try {
1154
+ await abortPromise;
1155
+ }
1156
+ finally {
1157
+ if (this._userAbortPromise === abortPromise) {
1158
+ this._userAbortPromise = undefined;
1159
+ }
1160
+ }
1120
1161
  }
1121
1162
  // =========================================================================
1122
1163
  // Model Management
@@ -1485,8 +1526,8 @@ export class AgentSession {
1485
1526
  }
1486
1527
  }
1487
1528
  if (!compactionResult) {
1488
- const { apiKey, headers, extraBody } = await this._getRequiredRequestAuth(this.model);
1489
- compactionResult = await compact(preparation, this.model, apiKey, headers, request.customInstructions, signal, extraBody, this.thinkingLevel);
1529
+ const { apiKey, headers, extraBody } = await this._getCompactionRequestAuth(this.model);
1530
+ compactionResult = await compact(preparation, this.model, apiKey, headers, request.customInstructions, signal, extraBody, this.thinkingLevel, this.agent.streamFn);
1490
1531
  }
1491
1532
  }
1492
1533
  if (signal.aborted) {
@@ -1724,7 +1765,7 @@ export class AgentSession {
1724
1765
  return;
1725
1766
  }
1726
1767
  const authResult = await this._modelRegistry.getApiKeyAndHeaders(this.model);
1727
- if (!authResult.ok || !authResult.apiKey) {
1768
+ if (this.agent.streamFn === streamSimple && (!authResult.ok || !authResult.apiKey)) {
1728
1769
  if (reason === "overflow")
1729
1770
  this._overflowRecoveryAttempted = false;
1730
1771
  this._emit({