talon-agent 3.34.0 → 3.35.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 (70) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +0 -10
  3. package/package.json +6 -4
  4. package/src/backend/claude-sdk/handler.ts +428 -415
  5. package/src/backend/codex/auth.ts +40 -1
  6. package/src/backend/codex/handler/message.ts +290 -366
  7. package/src/backend/codex/handler/rollout-accounting.ts +137 -0
  8. package/src/backend/codex/plan-usage.ts +27 -2
  9. package/src/backend/kilo/handler/message.ts +2 -0
  10. package/src/backend/kilo/server.ts +1 -0
  11. package/src/backend/openai-agents/handler/message.ts +282 -356
  12. package/src/backend/opencode/handler/message.ts +2 -0
  13. package/src/backend/opencode/server.ts +1 -0
  14. package/src/backend/remote-server/chat-turn.ts +76 -122
  15. package/src/backend/remote-server/index.ts +4 -0
  16. package/src/backend/remote-server/lifecycle.ts +37 -0
  17. package/src/backend/remote-server/mcp.ts +73 -9
  18. package/src/backend/remote-server/model-catalog/presentation.ts +269 -228
  19. package/src/backend/remote-server/server-bindings.ts +12 -0
  20. package/src/backend/remote-server/sessions.ts +2 -2
  21. package/src/backend/remote-server/state.ts +8 -0
  22. package/src/backend/remote-server/turn.ts +93 -23
  23. package/src/backend/shared/cache-telemetry.ts +17 -1
  24. package/src/backend/shared/handler-to-events.ts +11 -16
  25. package/src/backend/shared/index.ts +14 -15
  26. package/src/backend/shared/result-events.ts +30 -0
  27. package/src/backend/shared/turn-phases.ts +277 -0
  28. package/src/bootstrap.ts +24 -10
  29. package/src/core/auth/expiry-monitor.ts +89 -0
  30. package/src/core/auth/login-flow.ts +247 -0
  31. package/src/core/auth/status.ts +193 -0
  32. package/src/core/background/triggers/exit.ts +19 -2
  33. package/src/core/background/triggers/resume.ts +14 -7
  34. package/src/core/background/triggers/state.ts +9 -0
  35. package/src/core/engine/gateway-actions/history.ts +12 -1
  36. package/src/core/errors.ts +1 -1
  37. package/src/core/mcp-hub/child-transport.ts +215 -0
  38. package/src/core/mcp-hub/children.ts +72 -13
  39. package/src/core/mcp-hub/index.ts +32 -13
  40. package/src/core/models/active-model.ts +29 -6
  41. package/src/core/tools/history.ts +10 -1
  42. package/src/core/weaver/shuttle.ts +4 -0
  43. package/src/frontend/shared/model-commands.ts +400 -0
  44. package/src/frontend/telegram/admin.ts +75 -52
  45. package/src/frontend/telegram/auth-panel.ts +205 -0
  46. package/src/frontend/telegram/callbacks/auth.ts +70 -0
  47. package/src/frontend/telegram/callbacks/index.ts +16 -0
  48. package/src/frontend/telegram/callbacks/whatsapp.ts +50 -0
  49. package/src/frontend/telegram/commands/auth.ts +58 -0
  50. package/src/frontend/telegram/commands/definitions.ts +4 -0
  51. package/src/frontend/telegram/commands/index.ts +10 -4
  52. package/src/frontend/telegram/commands/whatsapp-pairing.ts +121 -79
  53. package/src/frontend/whatsapp/actions/chat-info.ts +2 -36
  54. package/src/frontend/whatsapp/actions/history.ts +100 -0
  55. package/src/frontend/whatsapp/actions/index.ts +4 -1
  56. package/src/frontend/whatsapp/commands.ts +371 -0
  57. package/src/frontend/whatsapp/inbound.ts +24 -46
  58. package/src/frontend/whatsapp/index.ts +12 -1
  59. package/src/frontend/whatsapp/media-store.ts +20 -1
  60. package/src/frontend/whatsapp/message-store.ts +101 -24
  61. package/src/storage/history.ts +22 -1
  62. package/src/storage/repositories/history-repo.ts +14 -0
  63. package/src/storage/repositories/whatsapp-messages-repo.ts +101 -0
  64. package/src/storage/sql/history.sql +12 -0
  65. package/src/storage/sql/schema.sql +21 -0
  66. package/src/storage/sql/statements.generated.ts +50 -1
  67. package/src/storage/sql/whatsapp-messages.sql +29 -0
  68. package/src/storage/trigger-store.ts +8 -0
  69. package/src/storage/whatsapp-messages.ts +51 -0
  70. package/src/util/watchdog.ts +32 -7
@@ -43,6 +43,7 @@
43
43
 
44
44
  import { existsSync, readFileSync } from "node:fs";
45
45
  import { join } from "node:path";
46
+ import { TalonError } from "../../core/errors.js";
46
47
 
47
48
  /** Detected auth mode. */
48
49
  type CodexAuthMode = "api-key" | "chatgpt" | "none";
@@ -321,7 +322,9 @@ export function isChatGptModelMismatchError(message: string): boolean {
321
322
  * - Error text contains `"Codex Exec exited"` (SDK's wrapper);
322
323
  * - Error text contains `"Reading prompt from stdin"` (CLI banner);
323
324
  * - Error text does NOT contain the explicit mismatch phrase (the
324
- * other detector handles that case).
325
+ * other detector handles that case);
326
+ * - Error text does NOT carry the OAuth refresh failure (an expired
327
+ * login exits with the same banner — `isCodexRefreshTokenError`).
325
328
  *
326
329
  * Callers MUST additionally check `authInfo.mode === "chatgpt"` and
327
330
  * that the model isn't already the OAuth default before falling back —
@@ -334,8 +337,44 @@ export function isChatGptModelMismatchError(message: string): boolean {
334
337
  export function isSilentOAuthExitError(message: string): boolean {
335
338
  if (!message) return false;
336
339
  if (isChatGptModelMismatchError(message)) return false;
340
+ if (isCodexRefreshTokenError(message)) return false;
337
341
  return (
338
342
  /Codex\s+Exec\s+exited\s+with\s+code\s+\d+/i.test(message) &&
339
343
  /Reading\s+prompt\s+from\s+stdin/i.test(message)
340
344
  );
341
345
  }
346
+
347
+ /**
348
+ * Detect an expired ChatGPT OAuth login.
349
+ *
350
+ * When the stored refresh token has been invalidated (the user logged
351
+ * out elsewhere, or the session was ended server-side) the Codex CLI
352
+ * prints its startup banner, logs
353
+ *
354
+ * `ERROR codex_login::auth::manager: Failed to refresh token: 401
355
+ * Unauthorized: {"error": {"code": "refresh_token_invalidated", …}}`
356
+ *
357
+ * to stderr, and exits 1 before the prompt reaches the model. The SDK
358
+ * folds that stderr into the same `Codex Exec exited with code 1:
359
+ * Reading prompt from stdin...` wrapper the silent OAuth-incompat exit
360
+ * uses, so without this check it is misread as a model mismatch —
361
+ * resetting the thread and retrying on a fallback model that fails the
362
+ * same way. Nothing but `codex login` fixes it.
363
+ */
364
+ export function isCodexRefreshTokenError(message: string): boolean {
365
+ return /Failed\s+to\s+refresh\s+token|refresh_token_invalidated/i.test(
366
+ message,
367
+ );
368
+ }
369
+
370
+ /**
371
+ * The error surfaced to the user for an expired Codex login. Typed
372
+ * `auth` so the shared retry ladder propagates it untouched — no thread
373
+ * reset, no fallback model — and `friendlyMessage` keeps the detail.
374
+ */
375
+ export function codexLoginExpiredError(cause: unknown): TalonError {
376
+ return new TalonError(
377
+ "Codex login expired — run `codex login` to re-authenticate.",
378
+ { reason: "auth", retryable: false, status: 401, cause },
379
+ );
380
+ }