talon-agent 3.33.3 → 3.34.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 (75) hide show
  1. package/package.json +6 -5
  2. package/src/app.ts +16 -8
  3. package/src/backend/claude-sdk/stream.ts +76 -53
  4. package/src/backend/remote-server/turn.ts +58 -55
  5. package/src/bootstrap.ts +120 -79
  6. package/src/cli/setup.ts +375 -349
  7. package/src/core/background/cron-spec.ts +273 -0
  8. package/src/core/background/heartbeat/agent.ts +167 -104
  9. package/src/core/engine/backend-controller/pool.ts +2 -0
  10. package/src/core/engine/backend-controller/state.ts +25 -12
  11. package/src/core/engine/gateway-actions/cron.ts +28 -292
  12. package/src/core/engine/gateway-routes.ts +239 -0
  13. package/src/core/engine/gateway.ts +66 -238
  14. package/src/core/vfs/mounts/files.ts +128 -115
  15. package/src/core/weaver/shuttle.ts +29 -2
  16. package/src/core/weaver/weaver.ts +37 -6
  17. package/src/frontend/discord/callbacks/components/agent-buttons.ts +82 -0
  18. package/src/frontend/discord/callbacks/components/backend-select.ts +149 -0
  19. package/src/frontend/discord/callbacks/components/effort.ts +72 -0
  20. package/src/frontend/discord/callbacks/components/index.ts +120 -0
  21. package/src/frontend/discord/callbacks/components/metrics.ts +24 -0
  22. package/src/frontend/discord/callbacks/components/model-nav.ts +93 -0
  23. package/src/frontend/discord/callbacks/components/model-select.ts +118 -0
  24. package/src/frontend/discord/callbacks/components/model.ts +33 -0
  25. package/src/frontend/discord/callbacks/components/pulse.ts +93 -0
  26. package/src/frontend/discord/callbacks/components/settings.ts +243 -0
  27. package/src/frontend/discord/callbacks/components/types.ts +34 -0
  28. package/src/frontend/discord/callbacks/index.ts +4 -4
  29. package/src/frontend/discord/connection.ts +36 -0
  30. package/src/frontend/discord/diagnostics.ts +62 -0
  31. package/src/frontend/discord/guild-policy.ts +89 -0
  32. package/src/frontend/discord/index.ts +44 -305
  33. package/src/frontend/discord/outbound.ts +61 -0
  34. package/src/frontend/discord/ready.ts +73 -0
  35. package/src/frontend/discord/runtime.ts +55 -0
  36. package/src/frontend/native/chat-lifecycle.ts +39 -0
  37. package/src/frontend/native/chat-wire.ts +69 -0
  38. package/src/frontend/native/context.ts +106 -0
  39. package/src/frontend/native/control.ts +78 -0
  40. package/src/frontend/native/emit.ts +167 -0
  41. package/src/frontend/native/empty-chat-sweep.ts +50 -0
  42. package/src/frontend/native/handlers.ts +121 -0
  43. package/src/frontend/native/history.ts +101 -0
  44. package/src/frontend/native/index.ts +90 -1293
  45. package/src/frontend/native/media.ts +43 -0
  46. package/src/frontend/native/models.ts +221 -0
  47. package/src/frontend/native/queue.ts +47 -0
  48. package/src/frontend/native/reset.ts +50 -0
  49. package/src/frontend/native/routes/chats.ts +115 -0
  50. package/src/frontend/native/routes/daemon.ts +70 -0
  51. package/src/frontend/native/routes/host.ts +151 -0
  52. package/src/frontend/native/routes/index.ts +22 -0
  53. package/src/frontend/native/routes/mesh.ts +72 -0
  54. package/src/frontend/native/routes/models.ts +54 -0
  55. package/src/frontend/native/routes/params.ts +29 -0
  56. package/src/frontend/native/routes/pre-auth.ts +94 -0
  57. package/src/frontend/native/routes/table.ts +92 -0
  58. package/src/frontend/native/runtime.ts +109 -0
  59. package/src/frontend/native/server.ts +30 -555
  60. package/src/frontend/native/status.ts +26 -0
  61. package/src/frontend/native/tool-result.ts +48 -0
  62. package/src/frontend/native/turn.ts +341 -0
  63. package/src/frontend/whatsapp/access.ts +67 -0
  64. package/src/frontend/whatsapp/connection.ts +280 -0
  65. package/src/frontend/whatsapp/inbound.ts +327 -0
  66. package/src/frontend/whatsapp/index.ts +28 -599
  67. package/src/frontend/whatsapp/runtime.ts +74 -0
  68. package/src/plugins/github/provision.ts +1 -1
  69. package/src/storage/metrics.ts +18 -0
  70. package/src/storage/session-record.ts +29 -0
  71. package/src/storage/sessions.ts +24 -0
  72. package/src/util/boot-timer.ts +31 -0
  73. package/src/util/concurrency.ts +28 -0
  74. package/src/frontend/discord/callbacks/components.ts +0 -793
  75. package/src/frontend/discord/callbacks/shared.ts +0 -22
@@ -0,0 +1,101 @@
1
+ /**
2
+ * History pages + search — persisted rows re-hydrated into the wire shape
3
+ * (attached images get a fresh /media URL, assistant rows their turn meta).
4
+ */
5
+
6
+ import {
7
+ getRecentHistory,
8
+ getHistoryBefore,
9
+ searchHistoryMessages,
10
+ type HistoryMessage,
11
+ } from "../../storage/history.js";
12
+ import { isDeliveryTool } from "../../core/tools/index.js";
13
+ import type { ChatEntry } from "./chats.js";
14
+ import { refreshContext } from "./context.js";
15
+ import { mediaUrl, registerMedia } from "./media.js";
16
+ import {
17
+ historyToClientMessage,
18
+ type ClientMessage,
19
+ type SearchResult,
20
+ } from "./protocol.js";
21
+ import type { NativeRuntime } from "./runtime.js";
22
+ import { getTurnMeta } from "./turn-meta.js";
23
+
24
+ export type HistoryPageOptions = { before?: number; limit?: number };
25
+
26
+ function hydrateHistoryRow(
27
+ runtime: NativeRuntime,
28
+ chatId: string,
29
+ row: HistoryMessage,
30
+ ): ClientMessage {
31
+ const msg = historyToClientMessage(row, chatId);
32
+ // Re-hydrate an attached image: re-register its on-disk path into
33
+ // the media map and hand back a fresh /media URL so the image shows
34
+ // in reloaded history (survives restarts as long as the file exists).
35
+ if (row.mediaType === "photo" && row.filePath) {
36
+ msg.imagePath = mediaUrl(registerMedia(runtime, row.filePath));
37
+ }
38
+ // Re-hydrate turn meta (tool timeline + stats) for assistant rows.
39
+ if (msg.role === "assistant") {
40
+ const meta = getTurnMeta(chatId, msg.id);
41
+ if (meta) {
42
+ // Delivery tools are excluded at record time, but metas
43
+ // persisted by older daemons still carry them — filter on
44
+ // the way out so upgraded installs get clean history too.
45
+ const tools = meta.tools?.filter((t) => !isDeliveryTool(t.name));
46
+ if (tools?.length) msg.tools = tools;
47
+ if (meta.durationMs) msg.durationMs = meta.durationMs;
48
+ if (meta.tokensIn) msg.tokensIn = meta.tokensIn;
49
+ if (meta.tokensOut) msg.tokensOut = meta.tokensOut;
50
+ }
51
+ }
52
+ return msg;
53
+ }
54
+
55
+ /** A page of history: newest window, or the window before `before`. */
56
+ export function historyPage(
57
+ runtime: NativeRuntime,
58
+ chatId: string,
59
+ options?: HistoryPageOptions,
60
+ ): ClientMessage[] {
61
+ // Opening a chat is the one moment we know a client wants its numbers:
62
+ // refresh the context readout on the full path (model fallback and
63
+ // all), which covers every chat the startup warm skipped or couldn't
64
+ // resolve. Fire-and-forget — the figure arrives as a chat_updated.
65
+ const entry = runtime.chats.get(chatId);
66
+ if (entry && options?.before === undefined) {
67
+ void refreshContext(runtime, entry).catch(() => {});
68
+ }
69
+ const limit = Math.min(Math.max(options?.limit ?? 200, 1), 500);
70
+ const rows =
71
+ options?.before !== undefined
72
+ ? getHistoryBefore(chatId, options.before, limit)
73
+ : getRecentHistory(chatId, limit);
74
+ return rows
75
+ .map((m) => hydrateHistoryRow(runtime, chatId, m))
76
+ .sort((a, b) => Number(a.id) - Number(b.id));
77
+ }
78
+
79
+ /** Full-text search across chats (or one chat when `chatId` is given). */
80
+ export function searchHistory(
81
+ runtime: NativeRuntime,
82
+ query: string,
83
+ chatId?: string,
84
+ ): SearchResult[] {
85
+ const targets = chatId
86
+ ? [runtime.chats.get(chatId)].filter((e): e is ChatEntry => e != null)
87
+ : runtime.chats.list();
88
+ const results: SearchResult[] = [];
89
+ for (const entry of targets) {
90
+ for (const m of searchHistoryMessages(entry.id, query, 10)) {
91
+ results.push({
92
+ chatId: entry.id,
93
+ chatTitle: entry.title,
94
+ message: historyToClientMessage(m, entry.id),
95
+ });
96
+ }
97
+ }
98
+ // Newest hits first, bounded across all chats.
99
+ results.sort((a, b) => b.message.ts - a.message.ts);
100
+ return results.slice(0, 50);
101
+ }