open-multi-agent-kit 0.94.1 → 0.95.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.
Files changed (113) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/README.md +100 -647
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +11 -11
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/auth-storage.d.ts +27 -2
  7. package/dist/core/auth-storage.d.ts.map +1 -1
  8. package/dist/core/auth-storage.js +239 -56
  9. package/dist/core/auth-storage.js.map +1 -1
  10. package/dist/core/context-budget-v2-cache-invalidation.d.ts.map +1 -1
  11. package/dist/core/context-budget-v2-cache-invalidation.js +1 -1
  12. package/dist/core/context-budget-v2-cache-invalidation.js.map +1 -1
  13. package/dist/core/context-budget-v2-cache-provider.d.ts +5 -1
  14. package/dist/core/context-budget-v2-cache-provider.d.ts.map +1 -1
  15. package/dist/core/context-budget-v2-cache-provider.js +37 -7
  16. package/dist/core/context-budget-v2-cache-provider.js.map +1 -1
  17. package/dist/core/context-budget-v2-cache-telemetry.d.ts +1 -1
  18. package/dist/core/context-budget-v2-cache-telemetry.d.ts.map +1 -1
  19. package/dist/core/context-budget-v2-cache-telemetry.js +2 -1
  20. package/dist/core/context-budget-v2-cache-telemetry.js.map +1 -1
  21. package/dist/core/context-budget-v2-cache.d.ts.map +1 -1
  22. package/dist/core/context-budget-v2-cache.js +3 -0
  23. package/dist/core/context-budget-v2-cache.js.map +1 -1
  24. package/dist/core/context-budget-v2-representation-cache.d.ts.map +1 -1
  25. package/dist/core/context-budget-v2-representation-cache.js +4 -3
  26. package/dist/core/context-budget-v2-representation-cache.js.map +1 -1
  27. package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
  28. package/dist/core/context-budget-v2-selection.js +4 -0
  29. package/dist/core/context-budget-v2-selection.js.map +1 -1
  30. package/dist/core/context-budget-v2-types.d.ts +3 -0
  31. package/dist/core/context-budget-v2-types.d.ts.map +1 -1
  32. package/dist/core/context-budget-v2-types.js.map +1 -1
  33. package/dist/core/extensions/types.d.ts +2 -0
  34. package/dist/core/extensions/types.d.ts.map +1 -1
  35. package/dist/core/extensions/types.js.map +1 -1
  36. package/dist/core/github-repository.d.ts +3 -0
  37. package/dist/core/github-repository.d.ts.map +1 -0
  38. package/dist/core/github-repository.js +3 -0
  39. package/dist/core/github-repository.js.map +1 -0
  40. package/dist/core/model-registry.d.ts +3 -3
  41. package/dist/core/model-registry.d.ts.map +1 -1
  42. package/dist/core/model-registry.js +9 -8
  43. package/dist/core/model-registry.js.map +1 -1
  44. package/dist/core/provider-usage.d.ts +48 -0
  45. package/dist/core/provider-usage.d.ts.map +1 -0
  46. package/dist/core/provider-usage.js +780 -0
  47. package/dist/core/provider-usage.js.map +1 -0
  48. package/dist/core/sdk.d.ts.map +1 -1
  49. package/dist/core/sdk.js +10 -0
  50. package/dist/core/sdk.js.map +1 -1
  51. package/dist/core/session-termination.d.ts.map +1 -1
  52. package/dist/core/session-termination.js +8 -1
  53. package/dist/core/session-termination.js.map +1 -1
  54. package/dist/core/settings-manager.d.ts +1 -5
  55. package/dist/core/settings-manager.d.ts.map +1 -1
  56. package/dist/core/settings-manager.js +15 -17
  57. package/dist/core/settings-manager.js.map +1 -1
  58. package/dist/core/skills-catalog-cache.d.ts +1 -0
  59. package/dist/core/skills-catalog-cache.d.ts.map +1 -1
  60. package/dist/core/skills-catalog-cache.js +42 -11
  61. package/dist/core/skills-catalog-cache.js.map +1 -1
  62. package/dist/core/slash-commands.d.ts.map +1 -1
  63. package/dist/core/slash-commands.js +1 -4
  64. package/dist/core/slash-commands.js.map +1 -1
  65. package/dist/core/tools/read.d.ts +1 -1
  66. package/dist/core/tools/read.d.ts.map +1 -1
  67. package/dist/core/tools/read.js.map +1 -1
  68. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  69. package/dist/modes/interactive/components/footer.js.map +1 -1
  70. package/dist/modes/interactive/components/index.d.ts +1 -0
  71. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  72. package/dist/modes/interactive/components/index.js +1 -0
  73. package/dist/modes/interactive/components/index.js.map +1 -1
  74. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  75. package/dist/modes/interactive/components/model-selector.js +5 -3
  76. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  77. package/dist/modes/interactive/components/oauth-account-selector.d.ts +16 -0
  78. package/dist/modes/interactive/components/oauth-account-selector.d.ts.map +1 -0
  79. package/dist/modes/interactive/components/oauth-account-selector.js +61 -0
  80. package/dist/modes/interactive/components/oauth-account-selector.js.map +1 -0
  81. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  82. package/dist/modes/interactive/components/oauth-selector.js +25 -4
  83. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  84. package/dist/modes/interactive/components/status-sidebar.d.ts +21 -1
  85. package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -1
  86. package/dist/modes/interactive/components/status-sidebar.js +165 -6
  87. package/dist/modes/interactive/components/status-sidebar.js.map +1 -1
  88. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  89. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  90. package/dist/modes/interactive/interactive-mode.js +89 -60
  91. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  92. package/dist/utils/image-resize-core.d.ts.map +1 -1
  93. package/dist/utils/image-resize-core.js +2 -2
  94. package/dist/utils/image-resize-core.js.map +1 -1
  95. package/docs/development.md +3 -2
  96. package/docs/providers.md +19 -4
  97. package/docs/settings.md +9 -20
  98. package/docs/usage.md +10 -10
  99. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  100. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  101. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  102. package/examples/extensions/gondolin/package-lock.json +2 -2
  103. package/examples/extensions/gondolin/package.json +1 -1
  104. package/examples/extensions/sandbox/package-lock.json +2 -2
  105. package/examples/extensions/sandbox/package.json +1 -1
  106. package/examples/extensions/with-deps/package-lock.json +2 -2
  107. package/examples/extensions/with-deps/package.json +1 -1
  108. package/npm-shrinkwrap.json +24 -24
  109. package/package.json +6 -6
  110. package/dist/core/github-star-nudge.d.ts +0 -15
  111. package/dist/core/github-star-nudge.d.ts.map +0 -1
  112. package/dist/core/github-star-nudge.js +0 -21
  113. package/dist/core/github-star-nudge.js.map +0 -1
@@ -16,7 +16,7 @@ import { parseSkillBlock } from "../../core/agent-session.js";
16
16
  import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
17
17
  import { parseBangInvocation } from "../../core/bang-skill-invocation.js";
18
18
  import { FooterDataProvider } from "../../core/footer-data-provider.js";
19
- import { githubStarNudgeBody, githubStarNudgeTitle, OMK_GITHUB_STAR_URL, shouldShowGithubStarNudge, } from "../../core/github-star-nudge.js";
19
+ import { OMK_GITHUB_REPOSITORY_URL } from "../../core/github-repository.js";
20
20
  import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
21
21
  import { KeybindingsManager } from "../../core/keybindings.js";
22
22
  import { createCompactionSummaryMessage } from "../../core/messages.js";
@@ -59,6 +59,7 @@ import { FooterComponent } from "./components/footer.js";
59
59
  import { formatKeyText, keyDisplayText, keyHint, keyText, rawKeyHint } from "./components/keybinding-hints.js";
60
60
  import { LoginDialogComponent } from "./components/login-dialog.js";
61
61
  import { ModelSelectorComponent } from "./components/model-selector.js";
62
+ import { OAuthAccountSelectorComponent } from "./components/oauth-account-selector.js";
62
63
  import { OAuthSelectorComponent } from "./components/oauth-selector.js";
63
64
  import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
64
65
  import { SessionSelectorComponent } from "./components/session-selector.js";
@@ -507,28 +508,6 @@ export class InteractiveMode {
507
508
  this.editor.setAutocompleteProvider?.(provider);
508
509
  }
509
510
  }
510
- showGithubStarNudgeIfNeeded() {
511
- if (!shouldShowGithubStarNudge({ githubStarred: this.settingsManager.getGithubStarred() })) {
512
- return;
513
- }
514
- const starUrl = OMK_GITHUB_STAR_URL;
515
- const starLink = getCapabilities().hyperlinks
516
- ? hyperlink(theme.fg("accent", "open repo & star"), starUrl)
517
- : theme.fg("accent", starUrl);
518
- const actionLine = theme.fg("muted", "Star it, then run ") +
519
- theme.bold(theme.fg("accent", "/star")) +
520
- theme.fg("muted", " so this stops. Link: ") +
521
- starLink;
522
- if (this.chatContainer.children.length > 0) {
523
- this.chatContainer.addChild(new Spacer(1));
524
- }
525
- this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("accent", text)));
526
- this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("accent", githubStarNudgeTitle()))}\n${githubStarNudgeBody()}`, 1, 0));
527
- this.chatContainer.addChild(new Spacer(1));
528
- this.chatContainer.addChild(new Text(actionLine, 1, 0));
529
- this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("accent", text)));
530
- this.ui.requestRender();
531
- }
532
511
  showStartupNoticesIfNeeded() {
533
512
  if (this.startupNoticesShown) {
534
513
  return;
@@ -666,7 +645,7 @@ export class InteractiveMode {
666
645
  // rail is actually visible, so the same data is never rendered twice.
667
646
  this.statusSidebarPinned = this.settingsManager.getPinStatusSidebar();
668
647
  this.ui.addChild(this.footerSlot);
669
- this.statusSidebar = new StatusSidebarComponent(() => this.session, this.footerDataProvider, () => this.session.autoCompactionEnabled, () => this.ui.terminal.rows);
648
+ this.statusSidebar = new StatusSidebarComponent(() => this.session, this.footerDataProvider, () => this.session.autoCompactionEnabled, () => this.ui.terminal.rows, { requestRender: () => this.ui.requestRender() });
670
649
  this.ui.showOverlay(this.statusSidebar, {
671
650
  anchor: "top-right",
672
651
  // Responsive: ~26% of the terminal, clamped — grows on fullscreen.
@@ -1445,7 +1424,6 @@ export class InteractiveMode {
1445
1424
  this.setupExtensionShortcuts(extensionRunner);
1446
1425
  this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });
1447
1426
  this.showStartupNoticesIfNeeded();
1448
- this.showGithubStarNudgeIfNeeded();
1449
1427
  }
1450
1428
  applyRuntimeSettings() {
1451
1429
  configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
@@ -2292,8 +2270,8 @@ export class InteractiveMode {
2292
2270
  this.editor.setText("");
2293
2271
  return;
2294
2272
  }
2295
- if (text === "/star" || text.startsWith("/star ")) {
2296
- this.handleStarCommand(text);
2273
+ if (text === "/star") {
2274
+ this.handleStarCommand();
2297
2275
  return true;
2298
2276
  }
2299
2277
  if (text === "/changelog") {
@@ -2651,12 +2629,7 @@ export class InteractiveMode {
2651
2629
  this.statusContainer.clear();
2652
2630
  }
2653
2631
  if (event.aborted) {
2654
- if (event.reason === "manual") {
2655
- this.showError("Compaction cancelled");
2656
- }
2657
- else {
2658
- this.showStatus("Auto-compaction cancelled");
2659
- }
2632
+ this.showStatus(event.reason === "manual" ? "Compaction cancelled" : "Auto-compaction cancelled");
2660
2633
  }
2661
2634
  else if (event.result) {
2662
2635
  this.chatContainer.clear();
@@ -2769,6 +2742,9 @@ export class InteractiveMode {
2769
2742
  if (termination.kind === "completed" || this.lastRenderedTermination === termination)
2770
2743
  return;
2771
2744
  this.lastRenderedTermination = termination;
2745
+ // compaction_end owns the concise cancellation status; rendering this too duplicates it as a scary error.
2746
+ if (termination.causeCode === "compaction.aborted")
2747
+ return;
2772
2748
  this.showError(formatSessionTermination(termination));
2773
2749
  }
2774
2750
  showPromptError(error, previousTermination) {
@@ -3056,15 +3032,21 @@ export class InteractiveMode {
3056
3032
  try {
3057
3033
  this.unregisterSignalHandlers();
3058
3034
  }
3059
- catch { }
3035
+ catch (cleanupError) {
3036
+ void cleanupError;
3037
+ }
3060
3038
  try {
3061
3039
  killTrackedDetachedChildren();
3062
3040
  }
3063
- catch { }
3041
+ catch (cleanupError) {
3042
+ void cleanupError;
3043
+ }
3064
3044
  try {
3065
3045
  this.ui.stop();
3066
3046
  }
3067
- catch { }
3047
+ catch (cleanupError) {
3048
+ void cleanupError;
3049
+ }
3068
3050
  console.error("OMK exiting due to uncaughtException:");
3069
3051
  console.error(error);
3070
3052
  process.exit(1);
@@ -4215,7 +4197,13 @@ export class InteractiveMode {
4215
4197
  return;
4216
4198
  }
4217
4199
  if (providerOption.authType === "oauth") {
4218
- await this.showLoginDialog(providerOption.id, providerOption.name);
4200
+ const accounts = this.session.modelRegistry.authStorage.listOAuthAccounts(providerOption.id);
4201
+ if (accounts.length > 0) {
4202
+ this.showOAuthAccountSelector(providerOption);
4203
+ }
4204
+ else {
4205
+ await this.showLoginDialog(providerOption.id, providerOption.name);
4206
+ }
4219
4207
  }
4220
4208
  else if (providerOption.id === BEDROCK_PROVIDER_ID) {
4221
4209
  this.showBedrockSetupDialog(providerOption.id, providerOption.name);
@@ -4230,6 +4218,39 @@ export class InteractiveMode {
4230
4218
  return { component: selector, focus: selector };
4231
4219
  });
4232
4220
  }
4221
+ showOAuthAccountSelector(provider) {
4222
+ const authStorage = this.session.modelRegistry.authStorage;
4223
+ const accounts = authStorage.listOAuthAccounts(provider.id);
4224
+ if (accounts.length === 0) {
4225
+ void this.showLoginDialog(provider.id, provider.name);
4226
+ return;
4227
+ }
4228
+ this.showSelector((done) => {
4229
+ const selector = new OAuthAccountSelectorComponent(provider.name, accounts, async (selection) => {
4230
+ done();
4231
+ if (selection.kind === "add") {
4232
+ await this.showLoginDialog(provider.id, provider.name);
4233
+ return;
4234
+ }
4235
+ try {
4236
+ authStorage.selectOAuthAccount(provider.id, selection.index);
4237
+ this.session.modelRegistry.refresh();
4238
+ await this.updateAvailableProviderCount();
4239
+ this.footer.invalidate();
4240
+ this.updateEditorBorderColor();
4241
+ const label = authStorage.getOAuthAccountLabel(provider.id) ?? `Account ${selection.index + 1}`;
4242
+ this.showStatus(`Active ${provider.name} account: ${label}.`);
4243
+ }
4244
+ catch (error) {
4245
+ this.showError(`Account selection failed: ${error instanceof Error ? error.message : String(error)}`);
4246
+ }
4247
+ }, () => {
4248
+ done();
4249
+ this.showLoginProviderSelector("oauth");
4250
+ });
4251
+ return { component: selector, focus: selector };
4252
+ });
4253
+ }
4233
4254
  async showOAuthSelector(mode) {
4234
4255
  if (mode === "login") {
4235
4256
  this.showLoginAuthTypeSelector();
@@ -4248,12 +4269,20 @@ export class InteractiveMode {
4248
4269
  return;
4249
4270
  }
4250
4271
  try {
4272
+ const oauthAccountCount = this.session.modelRegistry.authStorage.getOAuthAccountCount(providerOption.id);
4251
4273
  this.session.modelRegistry.authStorage.logout(providerOption.id);
4252
4274
  this.session.modelRegistry.refresh();
4253
4275
  await this.updateAvailableProviderCount();
4254
- const message = providerOption.authType === "oauth"
4255
- ? `Logged out of ${providerOption.name}`
4256
- : `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;
4276
+ let message;
4277
+ if (providerOption.authType === "oauth") {
4278
+ message =
4279
+ oauthAccountCount > 1
4280
+ ? `Logged out of ${providerOption.name}. Removed ${oauthAccountCount} subscription accounts.`
4281
+ : `Logged out of ${providerOption.name}`;
4282
+ }
4283
+ else {
4284
+ message = `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;
4285
+ }
4257
4286
  this.showStatus(message);
4258
4287
  }
4259
4288
  catch (error) {
@@ -4268,7 +4297,18 @@ export class InteractiveMode {
4268
4297
  }
4269
4298
  async completeProviderAuthentication(providerId, providerName, authType, previousModel) {
4270
4299
  this.session.modelRegistry.refresh();
4271
- const actionLabel = authType === "oauth" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;
4300
+ const oauthAccountCount = this.session.modelRegistry.authStorage.getOAuthAccountCount(providerId);
4301
+ const oauthAccountLabel = this.session.modelRegistry.authStorage.getOAuthAccountLabel(providerId);
4302
+ let actionLabel;
4303
+ if (authType === "oauth") {
4304
+ actionLabel = `Logged in to ${providerName}${oauthAccountLabel ? ` as ${oauthAccountLabel}` : ""}`;
4305
+ if (oauthAccountCount > 1) {
4306
+ actionLabel += ` (${oauthAccountCount} subscription accounts; use /login to switch)`;
4307
+ }
4308
+ }
4309
+ else {
4310
+ actionLabel = `Saved API key for ${providerName}`;
4311
+ }
4272
4312
  let selectedModel;
4273
4313
  let selectionError;
4274
4314
  if (isUnknownModel(previousModel)) {
@@ -4787,28 +4827,17 @@ export class InteractiveMode {
4787
4827
  this.chatContainer.addChild(new Text(info, 1, 0));
4788
4828
  this.ui.requestRender();
4789
4829
  }
4790
- handleStarCommand(text) {
4791
- const arg = text === "/star" ? "" : text.slice("/star".length).trim().toLowerCase();
4792
- const reset = arg === "reset" || arg === "again" || arg === "clear";
4793
- if (reset) {
4794
- this.settingsManager.setGithubStarred(false);
4795
- this.chatContainer.addChild(new Spacer(1));
4796
- this.chatContainer.addChild(new Text(theme.fg("warning", "Star nudge reset. It will show again on the next interactive launch until you /star."), 1, 0));
4797
- this.ui.requestRender();
4798
- return;
4799
- }
4800
- openBrowser(OMK_GITHUB_STAR_URL);
4801
- this.settingsManager.setGithubStarred(true);
4802
- const starLink = getCapabilities().hyperlinks
4803
- ? hyperlink(theme.fg("accent", OMK_GITHUB_STAR_URL), OMK_GITHUB_STAR_URL)
4804
- : theme.fg("accent", OMK_GITHUB_STAR_URL);
4830
+ handleStarCommand() {
4831
+ openBrowser(OMK_GITHUB_REPOSITORY_URL);
4832
+ const repositoryLink = getCapabilities().hyperlinks
4833
+ ? hyperlink(theme.fg("accent", OMK_GITHUB_REPOSITORY_URL), OMK_GITHUB_REPOSITORY_URL)
4834
+ : theme.fg("accent", OMK_GITHUB_REPOSITORY_URL);
4805
4835
  this.chatContainer.addChild(new Spacer(1));
4806
4836
  this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("accent", text)));
4807
4837
  this.chatContainer.addChild(new Text([
4808
- theme.bold(theme.fg("accent", "Thanks star nudge off")),
4809
- theme.fg("muted", "Opened the repo (if a browser is available). Hit the star if you have not yet."),
4810
- `${theme.fg("muted", "Repo: ")}${starLink}`,
4811
- theme.fg("dim", "Forgot already? /star reset brings the nag back."),
4838
+ theme.bold(theme.fg("accent", "OMK on GitHub")),
4839
+ theme.fg("muted", "Opened the OMK repository in your browser."),
4840
+ `${theme.fg("muted", "Repository: ")}${repositoryLink}`,
4812
4841
  ].join("\n"), 1, 0));
4813
4842
  this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("accent", text)));
4814
4843
  this.ui.requestRender();