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
@@ -10,6 +10,7 @@ import { logWarn } from "./log.js";
10
10
 
11
11
  let lastProcessedAt = Date.now();
12
12
  let lastReceivedAt = 0;
13
+ let lastActivityAt = 0;
13
14
  let totalMessagesProcessed = 0;
14
15
  const startTime = Date.now();
15
16
 
@@ -30,6 +31,20 @@ export function recordMessageProcessed(): void {
30
31
  resetStuckWarnBackoff();
31
32
  }
32
33
 
34
+ /**
35
+ * Record that a running turn showed signs of life: a backend event (tool
36
+ * call, text delta, result) flowed through the shuttle. A long agentic
37
+ * turn is not a wedged loop — an hour-long grind that keeps calling tools
38
+ * used to trip the stuck warning at the 10-minute mark and re-warn on
39
+ * backoff until it finished, because `lastProcessedAt` only advances at
40
+ * turn end. Stuck detection measures silence since the last event, not
41
+ * turn length.
42
+ */
43
+ export function recordTurnActivity(): void {
44
+ lastActivityAt = Date.now();
45
+ resetStuckWarnBackoff();
46
+ }
47
+
33
48
  /**
34
49
  * Record that a message's turn settled in failure. The loop is moving —
35
50
  * the error was reported and the queue slot freed — so advance the stuck
@@ -51,15 +66,22 @@ export function recordMessageSettled(): void {
51
66
  export function resetWatchdogActivityForTests(): void {
52
67
  lastProcessedAt = Date.now();
53
68
  lastReceivedAt = 0;
69
+ lastActivityAt = 0;
54
70
  resetStuckWarnBackoff();
55
71
  }
56
72
 
57
73
  /**
58
74
  * How long the newest RECEIVED message has been waiting with no processing
59
- * completed after it. Zero when idle or keeping up.
75
+ * completed after it AND no turn activity since. Zero when idle, keeping
76
+ * up, or mid-turn with events still flowing.
60
77
  */
61
78
  function stuckMs(now: number): number {
62
79
  if (lastReceivedAt === 0 || lastReceivedAt <= lastProcessedAt) return 0;
80
+ return now - Math.max(lastReceivedAt, lastActivityAt);
81
+ }
82
+
83
+ /** How long the newest RECEIVED message has been waiting for completion. */
84
+ function pendingMs(now: number): number {
63
85
  return now - lastReceivedAt;
64
86
  }
65
87
 
@@ -113,17 +135,20 @@ export function startWatchdog(workspaceDir?: string): void {
113
135
  if (watchdogTimer) return;
114
136
 
115
137
  watchdogTimer = setInterval(() => {
116
- // Warn only when work is actually stuck — a message arrived and nothing
117
- // has finished processing since. A quiet chat used to trip this every
118
- // minute all night ("No messages processed for N minutes"), burying real
119
- // warnings in noise. Repeat warnings back off exponentially.
138
+ // Warn only when work is actually stuck — a message arrived, nothing
139
+ // has finished processing since, and the turn has gone silent (no
140
+ // backend events) for the threshold. A quiet chat used to trip this
141
+ // every minute all night ("No messages processed for N minutes"), and a
142
+ // long tool-calling turn used to trip it at the 10-minute mark; both
143
+ // buried real warnings in noise. Repeat warnings back off exponentially.
120
144
  const now = Date.now();
121
145
  const stuck = stuckMs(now);
122
146
  if (stuck > STUCK_WARN_MS && now >= nextStuckWarnAt) {
123
- const mins = Math.round(stuck / 60000);
147
+ const silentMins = Math.round(stuck / 60000);
148
+ const pendingMins = Math.round(pendingMs(now) / 60000);
124
149
  logWarn(
125
150
  "watchdog",
126
- `Message received ${mins} minutes ago is still unprocessed — the message loop may be wedged`,
151
+ `Message received ${pendingMins} minutes ago is still unprocessed with no turn activity for ${silentMins} minutes — the message loop may be wedged`,
127
152
  );
128
153
  nextStuckWarnAt = now + stuckWarnBackoffMs;
129
154
  stuckWarnBackoffMs = Math.min(