switchroom 0.19.26 → 0.19.28

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 (92) hide show
  1. package/bin/git-agent-attribution-hook.sh +144 -0
  2. package/dist/agent-scheduler/index.js +60 -2
  3. package/dist/auth-broker/index.js +244 -13
  4. package/dist/cli/autoaccept-poll.js +225 -17
  5. package/dist/cli/notion-write-pretool.mjs +60 -2
  6. package/dist/cli/switchroom.js +2843 -1220
  7. package/dist/host-control/main.js +245 -14
  8. package/dist/vault/approvals/kernel-server.js +242 -13
  9. package/dist/vault/broker/server.js +242 -13
  10. package/package.json +7 -2
  11. package/profiles/_base/cron-session.sh.hbs +8 -0
  12. package/profiles/_base/start.sh.hbs +175 -15
  13. package/telegram-plugin/card-layout.ts +328 -0
  14. package/telegram-plugin/dist/bridge/bridge.js +94 -1
  15. package/telegram-plugin/dist/gateway/gateway.js +2544 -1182
  16. package/telegram-plugin/dist/server.js +97 -1
  17. package/telegram-plugin/edit-flood-fuse.ts +841 -57
  18. package/telegram-plugin/flood-429-ledger.ts +526 -0
  19. package/telegram-plugin/flood-circuit-breaker.ts +18 -0
  20. package/telegram-plugin/gateway/callback-query-handlers.ts +6 -0
  21. package/telegram-plugin/gateway/flood-reply-queue.ts +168 -0
  22. package/telegram-plugin/gateway/gateway.ts +67 -70
  23. package/telegram-plugin/gateway/mcp-failure-hook.ts +74 -0
  24. package/telegram-plugin/gateway/narrative-lane.ts +14 -0
  25. package/telegram-plugin/gateway/outbound-send-path.ts +36 -0
  26. package/telegram-plugin/gateway/outbox-sweep.ts +183 -6
  27. package/telegram-plugin/gateway/pinned-message-handler.ts +12 -16
  28. package/telegram-plugin/gateway/status-pin-retarget.ts +72 -36
  29. package/telegram-plugin/gateway/status-pin-store.ts +58 -9
  30. package/telegram-plugin/gateway/worker-pin-reaper.ts +56 -7
  31. package/telegram-plugin/inline-keyboard-callbacks.ts +202 -21
  32. package/telegram-plugin/llm-error-present.ts +61 -2
  33. package/telegram-plugin/mcp-credential-failure.ts +459 -0
  34. package/telegram-plugin/model-unavailable.ts +8 -0
  35. package/telegram-plugin/operator-events.ts +110 -5
  36. package/telegram-plugin/outbound-class.ts +81 -0
  37. package/telegram-plugin/provider-credit.ts +237 -0
  38. package/telegram-plugin/scripts/bun-test-ci.sh +36 -6
  39. package/telegram-plugin/send-gate.ts +24 -2
  40. package/telegram-plugin/status-no-truncate.ts +10 -48
  41. package/telegram-plugin/status-pin-driver.ts +33 -45
  42. package/telegram-plugin/status-pin.ts +18 -1
  43. package/telegram-plugin/tests/card-golden.test.ts +69 -0
  44. package/telegram-plugin/tests/card-lifecycle-render.test.ts +362 -0
  45. package/telegram-plugin/tests/card-type-distinguishability.test.ts +187 -164
  46. package/telegram-plugin/tests/card-variants.golden.txt +211 -0
  47. package/telegram-plugin/tests/card-variants.ts +366 -0
  48. package/telegram-plugin/tests/edit-flood-fuse-ban-awareness.test.ts +373 -0
  49. package/telegram-plugin/tests/edit-flood-fuse-default-deny.test.ts +319 -0
  50. package/telegram-plugin/tests/edit-flood-fuse-reply-reserve.test.ts +340 -0
  51. package/telegram-plugin/tests/edit-flood-fuse.test.ts +11 -2
  52. package/telegram-plugin/tests/feed-edit-rate-ceiling.test.ts +462 -0
  53. package/telegram-plugin/tests/finalize-callback-flood-policy.test.ts +298 -0
  54. package/telegram-plugin/tests/finalize-callback.test.ts +41 -8
  55. package/telegram-plugin/tests/fixtures/real-429-stream.ts +220 -0
  56. package/telegram-plugin/tests/flood-429-ledger.test.ts +278 -0
  57. package/telegram-plugin/tests/flood-429-recorder-wiring.test.ts +128 -0
  58. package/telegram-plugin/tests/flood-reply-queue.test.ts +418 -0
  59. package/telegram-plugin/tests/mcp-credential-failure.test.ts +310 -0
  60. package/telegram-plugin/tests/outbox-sweep-flood-breaker.test.ts +221 -0
  61. package/telegram-plugin/tests/pinned-card-collapse.test.ts +19 -24
  62. package/telegram-plugin/tests/pinned-message-handler.test.ts +15 -15
  63. package/telegram-plugin/tests/provider-credit-402.test.ts +243 -0
  64. package/telegram-plugin/tests/status-pin-api.test.ts +11 -11
  65. package/telegram-plugin/tests/status-pin-boot-recovery.test.ts +36 -37
  66. package/telegram-plugin/tests/status-pin-lifecycle.test.ts +602 -0
  67. package/telegram-plugin/tests/status-pin-retarget.test.ts +90 -62
  68. package/telegram-plugin/tests/status-pin-service-message-suppression.test.ts +7 -3
  69. package/telegram-plugin/tests/status-pin-store.test.ts +109 -60
  70. package/telegram-plugin/tests/status-pin.test.ts +56 -5
  71. package/telegram-plugin/tests/test-runner-coverage.test.ts +133 -0
  72. package/telegram-plugin/tests/worker-activity-feed.test.ts +12 -10
  73. package/telegram-plugin/tests/worker-feed-coalesce.test.ts +23 -29
  74. package/telegram-plugin/tests/worker-feed-pin-persistence.test.ts +56 -59
  75. package/telegram-plugin/tests/worker-feed-terminal-edit-class.test.ts +335 -0
  76. package/telegram-plugin/tests/worker-visibility-prose-silent-harness.test.ts +1 -1
  77. package/telegram-plugin/tool-activity-summary.ts +239 -365
  78. package/telegram-plugin/uat/assertions.ts +22 -11
  79. package/telegram-plugin/uat/feed-matcher.test.ts +24 -17
  80. package/telegram-plugin/worker-activity-feed.ts +105 -47
  81. package/vendor/hindsight-memory/CLAUDE.md +45 -0
  82. package/vendor/hindsight-memory/scripts/drain_pending.py +433 -11
  83. package/vendor/hindsight-memory/scripts/lib/config.py +33 -0
  84. package/vendor/hindsight-memory/scripts/lib/pending.py +193 -28
  85. package/vendor/hindsight-memory/scripts/recall.py +176 -7
  86. package/vendor/hindsight-memory/scripts/tests/test_config_recall_passthrough_env.py +170 -0
  87. package/vendor/hindsight-memory/scripts/tests/test_drain_circuit_breaker.py +401 -0
  88. package/vendor/hindsight-memory/scripts/tests/test_drain_serialisation.py +286 -0
  89. package/vendor/hindsight-memory/scripts/tests/test_pending_drops.py +817 -8
  90. package/vendor/hindsight-memory/scripts/tests/test_recall_min_score.py +464 -0
  91. package/vendor/hindsight-memory/settings.json +1 -1
  92. package/vendor/hindsight-memory/tests/test_hooks.py +11 -2
@@ -17094,6 +17094,92 @@ var init_model_unavailable = __esm(() => {
17094
17094
  litellmV3LimiterSignalPair = ["rate limit exceeded for ", "limit type:"];
17095
17095
  });
17096
17096
 
17097
+ // provider-credit.ts
17098
+ function sample(text) {
17099
+ if (typeof text !== "string" || text.length === 0)
17100
+ return "";
17101
+ return (text.length > MAX_SCAN_CHARS ? text.slice(0, MAX_SCAN_CHARS) : text).toLowerCase();
17102
+ }
17103
+ function isProviderCreditStatus(status) {
17104
+ return typeof status === "number" && CREDIT_EXHAUSTION_STATUSES.includes(status);
17105
+ }
17106
+ function hasCreditExhaustionWording(text) {
17107
+ const lower = sample(text);
17108
+ if (lower.length === 0)
17109
+ return false;
17110
+ return CREDIT_EXHAUSTION_SIGNALS.some((s) => lower.includes(s));
17111
+ }
17112
+ function attributeProvider(text) {
17113
+ const lower = sample(text);
17114
+ if (lower.length === 0)
17115
+ return null;
17116
+ for (const entry of PROVIDER_CREDIT_REGISTRY) {
17117
+ if (entry.markers.some((m) => lower.includes(m)))
17118
+ return entry;
17119
+ }
17120
+ return null;
17121
+ }
17122
+ function detectProviderCreditExhaustion(text, status) {
17123
+ if (isProviderCreditStatus(status)) {
17124
+ return { provider: attributeProvider(text), via: "status" };
17125
+ }
17126
+ if (hasCreditExhaustionWording(text)) {
17127
+ return { provider: attributeProvider(text), via: "wording" };
17128
+ }
17129
+ return null;
17130
+ }
17131
+ var PROVIDER_CREDIT_REGISTRY, CREDIT_EXHAUSTION_SIGNALS, CREDIT_EXHAUSTION_STATUSES, MAX_SCAN_CHARS = 16384;
17132
+ var init_provider_credit = __esm(() => {
17133
+ PROVIDER_CREDIT_REGISTRY = [
17134
+ {
17135
+ id: "openrouter",
17136
+ label: "OpenRouter",
17137
+ vaultKey: "openrouter/api-key",
17138
+ consoleUrl: "https://openrouter.ai/credits",
17139
+ action: "Top up the OpenRouter balance (or raise the key\u2019s credit limit) in the OpenRouter console.",
17140
+ markers: ["openrouter", "openrouter.ai"]
17141
+ },
17142
+ {
17143
+ id: "openai",
17144
+ label: "OpenAI",
17145
+ vaultKey: "openai/api-key",
17146
+ consoleUrl: "https://platform.openai.com/settings/organization/billing",
17147
+ action: "Add credit / raise the billing limit in the OpenAI console.",
17148
+ markers: ["api.openai.com", "openai.", "openaiexception", "openai_api"]
17149
+ },
17150
+ {
17151
+ id: "perplexity",
17152
+ label: "Perplexity",
17153
+ vaultKey: "perplexity/api-key",
17154
+ consoleUrl: "https://www.perplexity.ai/settings/api",
17155
+ action: "Top up the Perplexity API balance (or re-issue the key) in the Perplexity console.",
17156
+ markers: ["perplexity", "api.perplexity.ai", "pplx"]
17157
+ }
17158
+ ];
17159
+ CREDIT_EXHAUSTION_SIGNALS = [
17160
+ "payment_required",
17161
+ "payment required",
17162
+ "insufficient credits",
17163
+ "insufficient_credits",
17164
+ "more credits are required",
17165
+ "requires more credits",
17166
+ "add more credits",
17167
+ "out of credits",
17168
+ "insufficient_quota",
17169
+ "exceeded your current quota",
17170
+ "billing_hard_limit_reached",
17171
+ "billing hard limit",
17172
+ "insufficient balance",
17173
+ "insufficient_balance",
17174
+ "credit balance is too low",
17175
+ "credit balance too low",
17176
+ "credit_balance_too_low",
17177
+ "no credits remaining",
17178
+ "quota exceeded for credits"
17179
+ ];
17180
+ CREDIT_EXHAUSTION_STATUSES = [402];
17181
+ });
17182
+
17097
17183
  // operator-events.ts
17098
17184
  function classifyClaudeError(raw) {
17099
17185
  try {
@@ -17127,9 +17213,16 @@ ${message}`)) {
17127
17213
  if (errorType === "invalid_api_key" || errorCode === "invalid_api_key" || sdkCode === "invalid_api_key" || message.toLowerCase().includes("invalid_api_key") || message.toLowerCase().includes("invalid api key")) {
17128
17214
  return "credentials-invalid";
17129
17215
  }
17130
- if (errorType === "credit_balance_too_low" || errorCode === "credit_balance_too_low" || sdkCode === "credit_balance_too_low" || message.toLowerCase().includes("credit_balance_too_low") || message.toLowerCase().includes("credit balance")) {
17216
+ const creditScanText = `${errorType}
17217
+ ${errorCode}
17218
+ ${sdkCode}
17219
+ ${message}`;
17220
+ if ((errorType === "credit_balance_too_low" || errorCode === "credit_balance_too_low" || sdkCode === "credit_balance_too_low" || message.toLowerCase().includes("credit_balance_too_low") || message.toLowerCase().includes("credit balance")) && attributeProvider(creditScanText) == null) {
17131
17221
  return "credit-exhausted";
17132
17222
  }
17223
+ if (detectProviderCreditExhaustion(creditScanText, status) != null) {
17224
+ return "provider-credit-exhausted";
17225
+ }
17133
17226
  if (errorType === "rate_limit_error" || errorCode === "rate_limit_error" || sdkCode === "rate_limit_error" || message.toLowerCase().includes("rate_limit_error") || message.toLowerCase().includes("rate limit")) {
17134
17227
  return "rate-limited";
17135
17228
  }
@@ -17166,12 +17259,15 @@ var DEFAULT_OPERATOR_EVENT_COOLDOWN_MS, cooldownMap, OPERATOR_ACTIONABLE_KINDS;
17166
17259
  var init_operator_events = __esm(() => {
17167
17260
  init_format();
17168
17261
  init_model_unavailable();
17262
+ init_provider_credit();
17169
17263
  DEFAULT_OPERATOR_EVENT_COOLDOWN_MS = 5 * 60000;
17170
17264
  cooldownMap = new Map;
17171
17265
  OPERATOR_ACTIONABLE_KINDS = new Set([
17172
17266
  "credentials-expired",
17173
17267
  "credentials-invalid",
17174
17268
  "credit-exhausted",
17269
+ "provider-credit-exhausted",
17270
+ "mcp-dependency-blocked",
17175
17271
  "proxy-misconfig"
17176
17272
  ]);
17177
17273
  });