@code-yeongyu/senpi 0.74.0 → 2026.5.13

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 (112) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +4 -0
  3. package/dist/core/agent-session-services.d.ts.map +1 -1
  4. package/dist/core/agent-session-services.js +3 -1
  5. package/dist/core/agent-session-services.js.map +1 -1
  6. package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts.map +1 -1
  7. package/dist/core/extensions/builtin/anthropic-web-search/index.js +25 -14
  8. package/dist/core/extensions/builtin/anthropic-web-search/index.js.map +1 -1
  9. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.d.ts.map +1 -1
  10. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js +56 -7
  11. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js.map +1 -1
  12. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts +7 -3
  13. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  14. package/dist/core/extensions/builtin/prompt-preset/presets.js +12 -4
  15. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  16. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -0
  17. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  18. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -1
  19. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  20. package/dist/core/extensions/builtin/todotools/continuation/runtime.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/todotools/continuation/runtime.js +7 -10
  22. package/dist/core/extensions/builtin/todotools/continuation/runtime.js.map +1 -1
  23. package/dist/core/extensions/builtin/todotools/index.d.ts +2 -2
  24. package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
  25. package/dist/core/extensions/builtin/todotools/index.js +2 -2
  26. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  27. package/dist/core/extensions/builtin/todotools/settings.d.ts +6 -0
  28. package/dist/core/extensions/builtin/todotools/settings.d.ts.map +1 -0
  29. package/dist/core/extensions/builtin/todotools/settings.js +58 -0
  30. package/dist/core/extensions/builtin/todotools/settings.js.map +1 -0
  31. package/dist/core/extensions/builtin/todotools/system-messages.d.ts +34 -0
  32. package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -0
  33. package/dist/core/extensions/builtin/todotools/system-messages.js +82 -0
  34. package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -0
  35. package/dist/core/extensions/builtin/todotools/tools/todoread.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/todotools/tools/todoread.js +3 -1
  37. package/dist/core/extensions/builtin/todotools/tools/todoread.js.map +1 -1
  38. package/dist/core/extensions/builtin/todotools/tools/todowrite.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/todotools/tools/todowrite.js +3 -1
  40. package/dist/core/extensions/builtin/todotools/tools/todowrite.js.map +1 -1
  41. package/dist/core/keybindings.d.ts +5 -0
  42. package/dist/core/keybindings.d.ts.map +1 -1
  43. package/dist/core/keybindings.js +10 -3
  44. package/dist/core/keybindings.js.map +1 -1
  45. package/dist/core/model-registry.d.ts.map +1 -1
  46. package/dist/core/model-registry.js +8 -3
  47. package/dist/core/model-registry.js.map +1 -1
  48. package/dist/core/resource-loader.d.ts +8 -0
  49. package/dist/core/resource-loader.d.ts.map +1 -1
  50. package/dist/core/resource-loader.js +168 -17
  51. package/dist/core/resource-loader.js.map +1 -1
  52. package/dist/core/tools/bash.d.ts.map +1 -1
  53. package/dist/core/tools/bash.js +11 -4
  54. package/dist/core/tools/bash.js.map +1 -1
  55. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  56. package/dist/modes/interactive/components/bash-execution.js +11 -3
  57. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  58. package/dist/modes/interactive/components/favorite-models-selector.d.ts +10 -4
  59. package/dist/modes/interactive/components/favorite-models-selector.d.ts.map +1 -1
  60. package/dist/modes/interactive/components/favorite-models-selector.js +56 -78
  61. package/dist/modes/interactive/components/favorite-models-selector.js.map +1 -1
  62. package/dist/modes/interactive/components/model-favorites.d.ts +10 -0
  63. package/dist/modes/interactive/components/model-favorites.d.ts.map +1 -0
  64. package/dist/modes/interactive/components/model-favorites.js +53 -0
  65. package/dist/modes/interactive/components/model-favorites.js.map +1 -0
  66. package/dist/modes/interactive/components/model-selector.d.ts +9 -1
  67. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  68. package/dist/modes/interactive/components/model-selector.js +52 -10
  69. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  70. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  71. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  72. package/dist/modes/interactive/interactive-mode.js +83 -94
  73. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  74. package/docs/models.md +26 -1
  75. package/docs/settings.md +14 -0
  76. package/package.json +5 -8
  77. package/dist/core/extensions/builtin/agent-system/agent-types.d.ts +0 -25
  78. package/dist/core/extensions/builtin/agent-system/agent-types.d.ts.map +0 -1
  79. package/dist/core/extensions/builtin/agent-system/agent-types.js +0 -38
  80. package/dist/core/extensions/builtin/agent-system/agent-types.js.map +0 -1
  81. package/dist/core/extensions/builtin/agent-system/builtin-agents.d.ts +0 -3
  82. package/dist/core/extensions/builtin/agent-system/builtin-agents.d.ts.map +0 -1
  83. package/dist/core/extensions/builtin/agent-system/builtin-agents.js +0 -32
  84. package/dist/core/extensions/builtin/agent-system/builtin-agents.js.map +0 -1
  85. package/dist/core/extensions/builtin/agent-system/index.d.ts +0 -3
  86. package/dist/core/extensions/builtin/agent-system/index.d.ts.map +0 -1
  87. package/dist/core/extensions/builtin/agent-system/index.js +0 -42
  88. package/dist/core/extensions/builtin/agent-system/index.js.map +0 -1
  89. package/dist/core/extensions/builtin/agent-system/loader.d.ts +0 -4
  90. package/dist/core/extensions/builtin/agent-system/loader.d.ts.map +0 -1
  91. package/dist/core/extensions/builtin/agent-system/loader.js +0 -59
  92. package/dist/core/extensions/builtin/agent-system/loader.js.map +0 -1
  93. package/dist/core/extensions/builtin/agent-system/permission.d.ts +0 -11
  94. package/dist/core/extensions/builtin/agent-system/permission.d.ts.map +0 -1
  95. package/dist/core/extensions/builtin/agent-system/permission.js +0 -24
  96. package/dist/core/extensions/builtin/agent-system/permission.js.map +0 -1
  97. package/dist/core/extensions/builtin/agent-system/registry.d.ts +0 -10
  98. package/dist/core/extensions/builtin/agent-system/registry.d.ts.map +0 -1
  99. package/dist/core/extensions/builtin/agent-system/registry.js +0 -50
  100. package/dist/core/extensions/builtin/agent-system/registry.js.map +0 -1
  101. package/dist/core/extensions/builtin/agent-system/types.d.ts +0 -9
  102. package/dist/core/extensions/builtin/agent-system/types.d.ts.map +0 -1
  103. package/dist/core/extensions/builtin/agent-system/types.js +0 -2
  104. package/dist/core/extensions/builtin/agent-system/types.js.map +0 -1
  105. package/dist/core/extensions/builtin/agent-system/wildcard.d.ts +0 -4
  106. package/dist/core/extensions/builtin/agent-system/wildcard.d.ts.map +0 -1
  107. package/dist/core/extensions/builtin/agent-system/wildcard.js +0 -58
  108. package/dist/core/extensions/builtin/agent-system/wildcard.js.map +0 -1
  109. package/dist/core/extensions/builtin/anthropic-web-fetch/index.d.ts +0 -7
  110. package/dist/core/extensions/builtin/anthropic-web-fetch/index.d.ts.map +0 -1
  111. package/dist/core/extensions/builtin/anthropic-web-fetch/index.js +0 -112
  112. package/dist/core/extensions/builtin/anthropic-web-fetch/index.js.map +0 -1
@@ -15,7 +15,7 @@ import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime
15
15
  import { FooterDataProvider } from "../../core/footer-data-provider.js";
16
16
  import { KeybindingsManager } from "../../core/keybindings.js";
17
17
  import { createCompactionSummaryMessage } from "../../core/messages.js";
18
- import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScope } from "../../core/model-resolver.js";
18
+ import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScope, } from "../../core/model-resolver.js";
19
19
  import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "../../core/provider-display-names.js";
20
20
  import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
21
21
  import { SessionManager } from "../../core/session-manager.js";
@@ -48,6 +48,7 @@ import { FavoriteModelsSelectorComponent } from "./components/favorite-models-se
48
48
  import { FooterComponent } from "./components/footer.js";
49
49
  import { formatKeyText, keyDisplayText, keyHint, keyText, rawKeyHint } from "./components/keybinding-hints.js";
50
50
  import { LoginDialogComponent } from "./components/login-dialog.js";
51
+ import { getModelFullId } from "./components/model-favorites.js";
51
52
  import { ModelSelectorComponent } from "./components/model-selector.js";
52
53
  import { OAuthSelectorComponent } from "./components/oauth-selector.js";
53
54
  import { SessionSelectorComponent } from "./components/session-selector.js";
@@ -945,19 +946,6 @@ export class InteractiveMode {
945
946
  return;
946
947
  }
947
948
  const sectionHeader = (name, color = "mdHeading") => theme.fg(color, `[${name}]`);
948
- const _compactPath = (resourcePath, sourceInfo) => {
949
- const builtinName = this.getBuiltinExtensionNameFromPath(resourcePath);
950
- if (builtinName) {
951
- return `builtin/${builtinName}`;
952
- }
953
- const shortPath = this.getShortPath(resourcePath, sourceInfo);
954
- const normalizedPath = shortPath.replace(/\\/g, "/");
955
- const segments = normalizedPath.split("/").filter((segment) => segment.length > 0 && segment !== "~");
956
- if (segments.length > 0) {
957
- return segments[segments.length - 1];
958
- }
959
- return shortPath;
960
- };
961
949
  const formatCompactList = (items, options) => {
962
950
  const labels = items.map((item) => item.trim()).filter((item) => item.length > 0);
963
951
  if (options?.sort !== false) {
@@ -2426,8 +2414,8 @@ export class InteractiveMode {
2426
2414
  return "";
2427
2415
  const textBlocks = typeof message.content === "string"
2428
2416
  ? [{ type: "text", text: message.content }]
2429
- : message.content.filter((c) => c.type === "text");
2430
- return textBlocks.map((c) => c.text).join("");
2417
+ : message.content.filter((content) => content.type === "text");
2418
+ return textBlocks.map((content) => content.text).join("");
2431
2419
  }
2432
2420
  /**
2433
2421
  * Show a status message in the chat.
@@ -2525,7 +2513,8 @@ export class InteractiveMode {
2525
2513
  break;
2526
2514
  }
2527
2515
  default: {
2528
- const _exhaustive = message;
2516
+ const exhaustive = message;
2517
+ void exhaustive;
2529
2518
  }
2530
2519
  }
2531
2520
  }
@@ -3277,20 +3266,7 @@ export class InteractiveMode {
3277
3266
  }
3278
3267
  const model = await this.findExactModelMatch(searchTerm);
3279
3268
  if (model) {
3280
- try {
3281
- const systemPromptChange = await this.session.setModel(model);
3282
- this.footer.invalidate();
3283
- this.updateEditorBorderColor();
3284
- const systemPromptStr = systemPromptChange?.systemPromptName
3285
- ? ` (system prompt: ${systemPromptChange.systemPromptName})`
3286
- : "";
3287
- this.showStatus(`Model: ${model.id}${systemPromptStr}`);
3288
- void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
3289
- this.checkDaxnutsEasterEgg(model);
3290
- }
3291
- catch (error) {
3292
- this.showError(error instanceof Error ? error.message : String(error));
3293
- }
3269
+ await this.selectModelFromUi(model);
3294
3270
  return;
3295
3271
  }
3296
3272
  this.showModelSelector(searchTerm);
@@ -3302,7 +3278,7 @@ export class InteractiveMode {
3302
3278
  async getModelCandidates() {
3303
3279
  this.session.modelRegistry.refresh();
3304
3280
  try {
3305
- const availableModels = await this.session.modelRegistry.getAvailable();
3281
+ const availableModels = this.session.modelRegistry.getAvailable();
3306
3282
  if (this.session.scopedModels.length === 0) {
3307
3283
  return availableModels;
3308
3284
  }
@@ -3316,6 +3292,63 @@ export class InteractiveMode {
3316
3292
  return [];
3317
3293
  }
3318
3294
  }
3295
+ async selectModelFromUi(model, done) {
3296
+ try {
3297
+ const systemPromptChange = await this.session.setModel(model);
3298
+ this.footer.invalidate();
3299
+ this.updateEditorBorderColor();
3300
+ done?.();
3301
+ const systemPromptStr = systemPromptChange?.systemPromptName
3302
+ ? ` (system prompt: ${systemPromptChange.systemPromptName})`
3303
+ : "";
3304
+ this.showStatus(`Model: ${model.id}${systemPromptStr}`);
3305
+ void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
3306
+ this.checkDaxnutsEasterEgg(model);
3307
+ }
3308
+ catch (error) {
3309
+ done?.();
3310
+ this.showError(error instanceof Error ? error.message : String(error));
3311
+ }
3312
+ }
3313
+ async resolveFavoriteModelsForUi(patterns, candidateModels) {
3314
+ const candidateIds = new Set(candidateModels.map(getModelFullId));
3315
+ const warnings = [];
3316
+ const resolvedModels = await resolveModelScope(patterns, this.session.modelRegistry, {
3317
+ onWarning: (message) => warnings.push(message),
3318
+ });
3319
+ for (const warning of warnings) {
3320
+ this.showWarning(warning);
3321
+ }
3322
+ return resolvedModels.filter((resolved) => candidateIds.has(getModelFullId(resolved.model)));
3323
+ }
3324
+ async getFavoriteModelIdsForUi(candidateModels) {
3325
+ const candidateIds = new Set(candidateModels.map(getModelFullId));
3326
+ const sessionFavoriteIds = this.session.favoriteModels
3327
+ .map((favorite) => getModelFullId(favorite.model))
3328
+ .filter((id) => candidateIds.has(id));
3329
+ if (sessionFavoriteIds.length > 0)
3330
+ return sessionFavoriteIds;
3331
+ const patterns = this.settingsManager.getFavoriteModels() ?? [];
3332
+ if (patterns.length === 0)
3333
+ return [];
3334
+ const favoriteModels = await this.resolveFavoriteModelsForUi(patterns, candidateModels);
3335
+ return favoriteModels.map((favorite) => getModelFullId(favorite.model));
3336
+ }
3337
+ async updateSessionFavoritesFromIds(favoriteIds, candidateModels) {
3338
+ const nextIds = favoriteIds === null ? candidateModels.map(getModelFullId) : favoriteIds;
3339
+ if (nextIds.length === 0) {
3340
+ this.session.setFavoriteModels([]);
3341
+ this.ui.requestRender();
3342
+ return;
3343
+ }
3344
+ const newFavoriteModels = await this.resolveFavoriteModelsForUi(nextIds, candidateModels);
3345
+ this.session.setFavoriteModels(newFavoriteModels.map((favorite) => ({
3346
+ model: favorite.model,
3347
+ thinkingLevel: favorite.thinkingLevel,
3348
+ serviceTier: favorite.serviceTier,
3349
+ })));
3350
+ this.ui.requestRender();
3351
+ }
3319
3352
  /** Update the footer's available provider count from current model candidates */
3320
3353
  async updateAvailableProviderCount() {
3321
3354
  const models = await this.getModelCandidates();
@@ -3352,27 +3385,20 @@ export class InteractiveMode {
3352
3385
  }
3353
3386
  showModelSelector(initialSearchInput) {
3354
3387
  this.showSelector((done) => {
3355
- const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, async (model) => {
3356
- try {
3357
- const systemPromptChange = await this.session.setModel(model);
3358
- this.footer.invalidate();
3359
- this.updateEditorBorderColor();
3360
- done();
3361
- const systemPromptStr = systemPromptChange?.systemPromptName
3362
- ? ` (system prompt: ${systemPromptChange.systemPromptName})`
3363
- : "";
3364
- this.showStatus(`Model: ${model.id}${systemPromptStr}`);
3365
- void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
3366
- this.checkDaxnutsEasterEgg(model);
3367
- }
3368
- catch (error) {
3369
- done();
3370
- this.showError(error instanceof Error ? error.message : String(error));
3371
- }
3388
+ const favoriteModelIds = this.session.favoriteModels.map((favorite) => getModelFullId(favorite.model));
3389
+ const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, (model) => {
3390
+ void this.selectModelFromUi(model, done);
3372
3391
  }, () => {
3373
3392
  done();
3374
3393
  this.ui.requestRender();
3375
- }, initialSearchInput);
3394
+ }, initialSearchInput, {
3395
+ favoriteModelIds,
3396
+ onFavoriteChange: async (favoriteIds, allModels) => {
3397
+ await this.updateSessionFavoritesFromIds(favoriteIds, allModels);
3398
+ const newPatterns = favoriteIds === null ? allModels.map(getModelFullId) : favoriteIds;
3399
+ this.settingsManager.setFavoriteModels(newPatterns.length > 0 ? [...newPatterns] : undefined);
3400
+ },
3401
+ });
3376
3402
  return { component: selector, focus: selector };
3377
3403
  });
3378
3404
  }
@@ -3382,61 +3408,24 @@ export class InteractiveMode {
3382
3408
  this.showStatus("No models available");
3383
3409
  return;
3384
3410
  }
3385
- // Build favorite model IDs from session state or settings
3386
- let currentFavoriteIds = [];
3387
- const candidateIds = new Set(allModels.map((model) => `${model.provider}/${model.id}`));
3388
- const resolveScopeForUi = async (patterns) => {
3389
- const warnings = [];
3390
- const resolvedModels = await resolveModelScope(patterns, this.session.modelRegistry, {
3391
- onWarning: (message) => warnings.push(message),
3392
- });
3393
- for (const warning of warnings) {
3394
- this.showWarning(warning);
3395
- }
3396
- return resolvedModels.filter((resolved) => candidateIds.has(`${resolved.model.provider}/${resolved.model.id}`));
3397
- };
3398
- if (this.session.favoriteModels.length > 0) {
3399
- currentFavoriteIds = this.session.favoriteModels
3400
- .map((favorite) => `${favorite.model.provider}/${favorite.model.id}`)
3401
- .filter((id) => candidateIds.has(id));
3402
- }
3403
- else {
3404
- const patterns = this.settingsManager.getFavoriteModels() ?? [];
3405
- if (patterns.length > 0) {
3406
- const favoriteModels = await resolveScopeForUi(patterns);
3407
- currentFavoriteIds = favoriteModels.map((favorite) => `${favorite.model.provider}/${favorite.model.id}`);
3408
- }
3409
- }
3410
- // Helper to update session's favorite models (session-only, no persist)
3411
- const updateSessionFavorites = async (favoriteIds) => {
3412
- const nextIds = favoriteIds === null ? allModels.map((model) => `${model.provider}/${model.id}`) : favoriteIds;
3413
- currentFavoriteIds = favoriteIds === null ? null : [...favoriteIds];
3414
- if (nextIds.length > 0) {
3415
- const newFavoriteModels = await resolveScopeForUi(nextIds);
3416
- this.session.setFavoriteModels(newFavoriteModels.map((sm) => ({
3417
- model: sm.model,
3418
- thinkingLevel: sm.thinkingLevel,
3419
- serviceTier: sm.serviceTier,
3420
- })));
3421
- }
3422
- else {
3423
- this.session.setFavoriteModels([]);
3424
- }
3425
- this.ui.requestRender();
3426
- };
3411
+ const currentFavoriteIds = await this.getFavoriteModelIdsForUi(allModels);
3427
3412
  this.showSelector((done) => {
3428
3413
  const selector = new FavoriteModelsSelectorComponent({
3429
3414
  allModels,
3430
3415
  favoriteModelIds: currentFavoriteIds,
3416
+ currentModel: this.session.model,
3431
3417
  }, {
3432
3418
  onChange: async (favoriteIds) => {
3433
- await updateSessionFavorites(favoriteIds);
3419
+ await this.updateSessionFavoritesFromIds(favoriteIds, allModels);
3434
3420
  },
3435
3421
  onPersist: (favoriteIds) => {
3436
- const newPatterns = favoriteIds === null ? allModels.map((model) => `${model.provider}/${model.id}`) : favoriteIds;
3422
+ const newPatterns = favoriteIds === null ? allModels.map(getModelFullId) : favoriteIds;
3437
3423
  this.settingsManager.setFavoriteModels(newPatterns.length > 0 ? [...newPatterns] : undefined);
3438
3424
  this.showStatus("Favorite models saved to settings");
3439
3425
  },
3426
+ onSelect: (model) => {
3427
+ void this.selectModelFromUi(model, done);
3428
+ },
3440
3429
  onCancel: () => {
3441
3430
  done();
3442
3431
  this.ui.requestRender();