verybot 0.1.8

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 (277) hide show
  1. package/README.md +167 -0
  2. package/dist/aliases/store.d.ts +21 -0
  3. package/dist/aliases/store.js +148 -0
  4. package/dist/aliases/types.d.ts +6 -0
  5. package/dist/aliases/types.js +1 -0
  6. package/dist/brain/agent-registry.d.ts +96 -0
  7. package/dist/brain/agent-registry.js +141 -0
  8. package/dist/brain/agent.d.ts +167 -0
  9. package/dist/brain/agent.js +932 -0
  10. package/dist/brain/channel-store.d.ts +27 -0
  11. package/dist/brain/channel-store.js +78 -0
  12. package/dist/brain/compaction.d.ts +37 -0
  13. package/dist/brain/compaction.js +214 -0
  14. package/dist/brain/context.d.ts +43 -0
  15. package/dist/brain/context.js +139 -0
  16. package/dist/brain/delegation-store.d.ts +33 -0
  17. package/dist/brain/delegation-store.js +106 -0
  18. package/dist/brain/loop.d.ts +24 -0
  19. package/dist/brain/loop.js +318 -0
  20. package/dist/brain/mcp-adapter.d.ts +43 -0
  21. package/dist/brain/mcp-adapter.js +244 -0
  22. package/dist/brain/memory-extractor.d.ts +26 -0
  23. package/dist/brain/memory-extractor.js +82 -0
  24. package/dist/brain/providers.d.ts +14 -0
  25. package/dist/brain/providers.js +85 -0
  26. package/dist/brain/queue.d.ts +18 -0
  27. package/dist/brain/queue.js +111 -0
  28. package/dist/brain/run-tools.d.ts +50 -0
  29. package/dist/brain/run-tools.js +136 -0
  30. package/dist/brain/session-key.d.ts +23 -0
  31. package/dist/brain/session-key.js +41 -0
  32. package/dist/brain/session-state.d.ts +36 -0
  33. package/dist/brain/session-state.js +51 -0
  34. package/dist/brain/session-store.d.ts +50 -0
  35. package/dist/brain/session-store.js +207 -0
  36. package/dist/brain/session.d.ts +32 -0
  37. package/dist/brain/session.js +75 -0
  38. package/dist/brain/task-subscriber.d.ts +56 -0
  39. package/dist/brain/task-subscriber.js +317 -0
  40. package/dist/brain/user-content.d.ts +16 -0
  41. package/dist/brain/user-content.js +32 -0
  42. package/dist/brain/utils.d.ts +4 -0
  43. package/dist/brain/utils.js +26 -0
  44. package/dist/brain/worker-coordinator.d.ts +25 -0
  45. package/dist/brain/worker-coordinator.js +83 -0
  46. package/dist/channels/commands.d.ts +50 -0
  47. package/dist/channels/commands.js +132 -0
  48. package/dist/channels/discord/channel.d.ts +29 -0
  49. package/dist/channels/discord/channel.js +159 -0
  50. package/dist/channels/discord/markdown.d.ts +19 -0
  51. package/dist/channels/discord/markdown.js +62 -0
  52. package/dist/channels/manager.d.ts +29 -0
  53. package/dist/channels/manager.js +100 -0
  54. package/dist/channels/slack/channel.d.ts +37 -0
  55. package/dist/channels/slack/channel.js +227 -0
  56. package/dist/channels/slack/markdown.d.ts +19 -0
  57. package/dist/channels/slack/markdown.js +62 -0
  58. package/dist/channels/specs.d.ts +32 -0
  59. package/dist/channels/specs.js +99 -0
  60. package/dist/channels/telegram/channel.d.ts +29 -0
  61. package/dist/channels/telegram/channel.js +182 -0
  62. package/dist/channels/telegram/markdown.d.ts +17 -0
  63. package/dist/channels/telegram/markdown.js +66 -0
  64. package/dist/channels/types.d.ts +26 -0
  65. package/dist/channels/types.js +1 -0
  66. package/dist/channels/whatsapp/channel.d.ts +34 -0
  67. package/dist/channels/whatsapp/channel.js +276 -0
  68. package/dist/channels/whatsapp/markdown.d.ts +20 -0
  69. package/dist/channels/whatsapp/markdown.js +51 -0
  70. package/dist/cli/claude-login.d.ts +5 -0
  71. package/dist/cli/claude-login.js +47 -0
  72. package/dist/cli/config.d.ts +5 -0
  73. package/dist/cli/config.js +78 -0
  74. package/dist/cli/index.d.ts +11 -0
  75. package/dist/cli/index.js +96 -0
  76. package/dist/computer/browser/actions.d.ts +31 -0
  77. package/dist/computer/browser/actions.js +148 -0
  78. package/dist/computer/browser/context-manager.d.ts +28 -0
  79. package/dist/computer/browser/context-manager.js +78 -0
  80. package/dist/computer/browser/manager.d.ts +91 -0
  81. package/dist/computer/browser/manager.js +344 -0
  82. package/dist/computer/browser/profile-badge.d.ts +13 -0
  83. package/dist/computer/browser/profile-badge.js +67 -0
  84. package/dist/computer/browser/screenshot.d.ts +5 -0
  85. package/dist/computer/browser/screenshot.js +21 -0
  86. package/dist/computer/browser/snapshot.d.ts +30 -0
  87. package/dist/computer/browser/snapshot.js +242 -0
  88. package/dist/computer/browser/tools.d.ts +5 -0
  89. package/dist/computer/browser/tools.js +167 -0
  90. package/dist/computer/browser/types.d.ts +26 -0
  91. package/dist/computer/browser/types.js +1 -0
  92. package/dist/computer/desktop/adapter.d.ts +25 -0
  93. package/dist/computer/desktop/adapter.js +11 -0
  94. package/dist/computer/desktop/macos.d.ts +24 -0
  95. package/dist/computer/desktop/macos.js +223 -0
  96. package/dist/computer/desktop/tools.d.ts +25 -0
  97. package/dist/computer/desktop/tools.js +114 -0
  98. package/dist/config/agent-config.d.ts +55 -0
  99. package/dist/config/agent-config.js +16 -0
  100. package/dist/config/model-catalog.d.ts +22 -0
  101. package/dist/config/model-catalog.js +112 -0
  102. package/dist/config/model-spec.d.ts +8 -0
  103. package/dist/config/model-spec.js +66 -0
  104. package/dist/config/store.d.ts +25 -0
  105. package/dist/config/store.js +143 -0
  106. package/dist/config.d.ts +110 -0
  107. package/dist/config.js +259 -0
  108. package/dist/control-ui/assets/index-Cbl7G5Sc.css +1 -0
  109. package/dist/control-ui/assets/index-Cu1P4C62.js +266 -0
  110. package/dist/control-ui/assets/noto-sans-cyrillic-ext-wght-normal-DSNfmdVt.woff2 +0 -0
  111. package/dist/control-ui/assets/noto-sans-cyrillic-wght-normal-B2hlT84T.woff2 +0 -0
  112. package/dist/control-ui/assets/noto-sans-devanagari-wght-normal-Cv-Vwajv.woff2 +0 -0
  113. package/dist/control-ui/assets/noto-sans-greek-ext-wght-normal-12T8GTDR.woff2 +0 -0
  114. package/dist/control-ui/assets/noto-sans-greek-wght-normal-Ymb6dZNd.woff2 +0 -0
  115. package/dist/control-ui/assets/noto-sans-latin-ext-wght-normal-W1qJv59z.woff2 +0 -0
  116. package/dist/control-ui/assets/noto-sans-latin-wght-normal-BYSzYMf3.woff2 +0 -0
  117. package/dist/control-ui/assets/noto-sans-vietnamese-wght-normal-DLTJy58D.woff2 +0 -0
  118. package/dist/control-ui/index.html +14 -0
  119. package/dist/control-ui/vite.svg +1 -0
  120. package/dist/events.d.ts +2 -0
  121. package/dist/events.js +11 -0
  122. package/dist/gateway/broadcast.d.ts +5 -0
  123. package/dist/gateway/broadcast.js +33 -0
  124. package/dist/gateway/methods/aliases.d.ts +17 -0
  125. package/dist/gateway/methods/aliases.js +22 -0
  126. package/dist/gateway/methods/chat.d.ts +33 -0
  127. package/dist/gateway/methods/chat.js +37 -0
  128. package/dist/gateway/methods/config.d.ts +14 -0
  129. package/dist/gateway/methods/config.js +24 -0
  130. package/dist/gateway/methods/models.d.ts +10 -0
  131. package/dist/gateway/methods/models.js +14 -0
  132. package/dist/gateway/methods/playbooks.d.ts +45 -0
  133. package/dist/gateway/methods/playbooks.js +488 -0
  134. package/dist/gateway/methods/prompt-templates.d.ts +27 -0
  135. package/dist/gateway/methods/prompt-templates.js +106 -0
  136. package/dist/gateway/methods/scheduler.d.ts +62 -0
  137. package/dist/gateway/methods/scheduler.js +129 -0
  138. package/dist/gateway/methods/sessions.d.ts +44 -0
  139. package/dist/gateway/methods/sessions.js +111 -0
  140. package/dist/gateway/methods/system.d.ts +12 -0
  141. package/dist/gateway/methods/system.js +39 -0
  142. package/dist/gateway/methods/tasks.d.ts +40 -0
  143. package/dist/gateway/methods/tasks.js +151 -0
  144. package/dist/gateway/methods/teams.d.ts +69 -0
  145. package/dist/gateway/methods/teams.js +376 -0
  146. package/dist/gateway/methods/tools.d.ts +6 -0
  147. package/dist/gateway/methods/tools.js +7 -0
  148. package/dist/gateway/methods/whatsapp.d.ts +19 -0
  149. package/dist/gateway/methods/whatsapp.js +35 -0
  150. package/dist/gateway/rpc.d.ts +38 -0
  151. package/dist/gateway/rpc.js +79 -0
  152. package/dist/gateway/server.d.ts +9 -0
  153. package/dist/gateway/server.js +137 -0
  154. package/dist/index.d.ts +1 -0
  155. package/dist/index.js +254 -0
  156. package/dist/integrations/github.d.ts +7 -0
  157. package/dist/integrations/github.js +133 -0
  158. package/dist/integrations/mcp.d.ts +7 -0
  159. package/dist/integrations/mcp.js +106 -0
  160. package/dist/integrations/registry.d.ts +47 -0
  161. package/dist/integrations/registry.js +332 -0
  162. package/dist/integrations/scanner.d.ts +10 -0
  163. package/dist/integrations/scanner.js +122 -0
  164. package/dist/integrations/twitter.d.ts +10 -0
  165. package/dist/integrations/twitter.js +120 -0
  166. package/dist/integrations/types.d.ts +72 -0
  167. package/dist/integrations/types.js +1 -0
  168. package/dist/logger.d.ts +16 -0
  169. package/dist/logger.js +104 -0
  170. package/dist/markdown/chunk.d.ts +9 -0
  171. package/dist/markdown/chunk.js +52 -0
  172. package/dist/markdown/ir.d.ts +37 -0
  173. package/dist/markdown/ir.js +529 -0
  174. package/dist/markdown/render.d.ts +22 -0
  175. package/dist/markdown/render.js +148 -0
  176. package/dist/markdown/table-render.d.ts +43 -0
  177. package/dist/markdown/table-render.js +219 -0
  178. package/dist/markdown/tables.d.ts +17 -0
  179. package/dist/markdown/tables.js +27 -0
  180. package/dist/memory/embedding.d.ts +16 -0
  181. package/dist/memory/embedding.js +66 -0
  182. package/dist/memory/explicit.d.ts +16 -0
  183. package/dist/memory/explicit.js +29 -0
  184. package/dist/memory/extractor.d.ts +13 -0
  185. package/dist/memory/extractor.js +82 -0
  186. package/dist/memory/search.d.ts +15 -0
  187. package/dist/memory/search.js +57 -0
  188. package/dist/memory/session-learning.d.ts +23 -0
  189. package/dist/memory/session-learning.js +55 -0
  190. package/dist/memory/store.d.ts +36 -0
  191. package/dist/memory/store.js +334 -0
  192. package/dist/memory/types.d.ts +9 -0
  193. package/dist/memory/types.js +2 -0
  194. package/dist/paths.d.ts +28 -0
  195. package/dist/paths.js +48 -0
  196. package/dist/prompt-templates/builtins/index.d.ts +4 -0
  197. package/dist/prompt-templates/builtins/index.js +5 -0
  198. package/dist/prompt-templates/builtins/planner.d.ts +4 -0
  199. package/dist/prompt-templates/builtins/planner.js +77 -0
  200. package/dist/prompt-templates/store.d.ts +45 -0
  201. package/dist/prompt-templates/store.js +224 -0
  202. package/dist/prompt-templates/types.d.ts +10 -0
  203. package/dist/prompt-templates/types.js +1 -0
  204. package/dist/scheduler/connected-channels.d.ts +24 -0
  205. package/dist/scheduler/connected-channels.js +57 -0
  206. package/dist/scheduler/scheduler.d.ts +22 -0
  207. package/dist/scheduler/scheduler.js +132 -0
  208. package/dist/scheduler/store.d.ts +27 -0
  209. package/dist/scheduler/store.js +205 -0
  210. package/dist/scheduler/types.d.ts +29 -0
  211. package/dist/scheduler/types.js +1 -0
  212. package/dist/security/command-validator.d.ts +22 -0
  213. package/dist/security/command-validator.js +160 -0
  214. package/dist/security/docker-sandbox.d.ts +48 -0
  215. package/dist/security/docker-sandbox.js +218 -0
  216. package/dist/security/env-filter.d.ts +8 -0
  217. package/dist/security/env-filter.js +41 -0
  218. package/dist/skills/loader.d.ts +33 -0
  219. package/dist/skills/loader.js +132 -0
  220. package/dist/skills/prompt.d.ts +6 -0
  221. package/dist/skills/prompt.js +17 -0
  222. package/dist/skills/read-tool.d.ts +7 -0
  223. package/dist/skills/read-tool.js +24 -0
  224. package/dist/skills/scanner.d.ts +6 -0
  225. package/dist/skills/scanner.js +73 -0
  226. package/dist/skills/types.d.ts +15 -0
  227. package/dist/skills/types.js +1 -0
  228. package/dist/tasks/inline-attachment-content.d.ts +9 -0
  229. package/dist/tasks/inline-attachment-content.js +64 -0
  230. package/dist/tasks/store.d.ts +112 -0
  231. package/dist/tasks/store.js +519 -0
  232. package/dist/tasks/types.d.ts +129 -0
  233. package/dist/tasks/types.js +80 -0
  234. package/dist/teams/status-config.d.ts +8 -0
  235. package/dist/teams/status-config.js +40 -0
  236. package/dist/teams/store.d.ts +111 -0
  237. package/dist/teams/store.js +671 -0
  238. package/dist/teams/types.d.ts +30 -0
  239. package/dist/teams/types.js +1 -0
  240. package/dist/tools/bash.d.ts +18 -0
  241. package/dist/tools/bash.js +64 -0
  242. package/dist/tools/channel-history.d.ts +10 -0
  243. package/dist/tools/channel-history.js +43 -0
  244. package/dist/tools/delegate.d.ts +20 -0
  245. package/dist/tools/delegate.js +299 -0
  246. package/dist/tools/fs.d.ts +4 -0
  247. package/dist/tools/fs.js +335 -0
  248. package/dist/tools/integration-toggle.d.ts +14 -0
  249. package/dist/tools/integration-toggle.js +47 -0
  250. package/dist/tools/memory.d.ts +13 -0
  251. package/dist/tools/memory.js +59 -0
  252. package/dist/tools/prompt-templates.d.ts +7 -0
  253. package/dist/tools/prompt-templates.js +133 -0
  254. package/dist/tools/registry.d.ts +6 -0
  255. package/dist/tools/registry.js +9 -0
  256. package/dist/tools/schedule.d.ts +8 -0
  257. package/dist/tools/schedule.js +219 -0
  258. package/dist/tools/speak.d.ts +10 -0
  259. package/dist/tools/speak.js +56 -0
  260. package/dist/tools/tasks.d.ts +67 -0
  261. package/dist/tools/tasks.js +288 -0
  262. package/dist/tools/teams.d.ts +22 -0
  263. package/dist/tools/teams.js +470 -0
  264. package/dist/tools/web-fetch.d.ts +3 -0
  265. package/dist/tools/web-fetch.js +22 -0
  266. package/dist/tts/edge.d.ts +10 -0
  267. package/dist/tts/edge.js +60 -0
  268. package/dist/tts/speak.d.ts +12 -0
  269. package/dist/tts/speak.js +81 -0
  270. package/dist/tts/transcribe.d.ts +5 -0
  271. package/dist/tts/transcribe.js +40 -0
  272. package/dist/utils.d.ts +5 -0
  273. package/dist/utils.js +22 -0
  274. package/dist/version.d.ts +1 -0
  275. package/dist/version.js +13 -0
  276. package/package.json +102 -0
  277. package/verybot.js +2 -0
@@ -0,0 +1,50 @@
1
+ import { Session } from "./session.js";
2
+ export interface SessionIndexEntry {
3
+ key: string;
4
+ file: string;
5
+ messageCount: number;
6
+ updatedAt: number;
7
+ /** Human-readable title — auto-set from first user message, editable via rename. */
8
+ title?: string;
9
+ /** Team UUID (stable reference, survives renames). */
10
+ teamId?: string;
11
+ /** Team name snapshot at save time (denormalized for fast display). */
12
+ teamName?: string;
13
+ /** Channel type: "gateway", "worker", "scheduler", "telegram", etc. */
14
+ channelType?: string;
15
+ /** Worker agent ID (stable reference for worker sessions). */
16
+ agentId?: string;
17
+ /** Worker agent name snapshot at save time (denormalized for display). */
18
+ agentName?: string;
19
+ }
20
+ export declare class SessionStore {
21
+ private dataDir;
22
+ private indexPath;
23
+ private index;
24
+ constructor(dataDir: string);
25
+ /** Save session to JSONL. Three modes: compaction marker, full rewrite, or append. */
26
+ save(session: Session): Promise<void>;
27
+ /** Load a session from its JSONL file. Respects compaction markers. */
28
+ load(sessionKey: string): Promise<Session | null>;
29
+ /** List all session keys with metadata. */
30
+ list(): SessionIndexEntry[];
31
+ /** Rename a session (update its title in the index). */
32
+ rename(sessionKey: string, title: string): boolean;
33
+ /**
34
+ * Update session metadata (team name, agent info). Only writes to disk if something changed.
35
+ * Note: teamName and agentName are denormalized snapshots — they may become stale if
36
+ * the team or agent is renamed after the session was last active.
37
+ */
38
+ updateMetadata(sessionKey: string, meta: {
39
+ teamId?: string;
40
+ teamName?: string;
41
+ channelType?: string;
42
+ agentId?: string;
43
+ agentName?: string;
44
+ }): void;
45
+ /** Clear a session — deletes the JSONL file and removes the index entry. */
46
+ clear(sessionKey: string): Promise<void>;
47
+ private getOrCreateEntry;
48
+ private loadIndex;
49
+ private saveIndex;
50
+ }
@@ -0,0 +1,207 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { Session } from "./session.js";
4
+ import { parseSessionKey } from "./session-key.js";
5
+ const MAX_TITLE_LEN = 30;
6
+ function isCompaction(entry) {
7
+ return "type" in entry && entry.type === "compaction";
8
+ }
9
+ export class SessionStore {
10
+ dataDir;
11
+ indexPath;
12
+ index;
13
+ constructor(dataDir) {
14
+ this.dataDir = dataDir;
15
+ this.indexPath = path.join(dataDir, "index.json");
16
+ // Ensure directory exists
17
+ fs.mkdirSync(dataDir, { recursive: true });
18
+ // Load existing index
19
+ this.index = this.loadIndex();
20
+ }
21
+ /** Save session to JSONL. Three modes: compaction marker, full rewrite, or append. */
22
+ async save(session) {
23
+ const entry = this.getOrCreateEntry(session.key);
24
+ const filePath = path.join(this.dataDir, entry.file);
25
+ if (session.pendingCompaction) {
26
+ // Compaction: append marker + re-append kept messages (append-only, preserves history)
27
+ const marker = {
28
+ type: "compaction",
29
+ ts: Date.now(),
30
+ summary: session.pendingCompaction.summary,
31
+ };
32
+ const kept = session.getCompactionMessages();
33
+ const lines = JSON.stringify(marker) +
34
+ "\n" +
35
+ kept.map((msg) => JSON.stringify({ ts: Date.now(), message: msg })).join("\n") +
36
+ "\n";
37
+ fs.appendFileSync(filePath, lines, "utf-8");
38
+ }
39
+ else if (session.needsFullRewrite) {
40
+ // Emergency truncate: overwrite entire file
41
+ const all = session.getMessages();
42
+ const lines = all.map((msg) => JSON.stringify({ ts: Date.now(), message: msg })).join("\n") + "\n";
43
+ fs.writeFileSync(filePath, lines, "utf-8");
44
+ }
45
+ else {
46
+ // Normal: append only new messages
47
+ const newMessages = session.getNewMessages();
48
+ if (newMessages.length === 0)
49
+ return;
50
+ const lines = newMessages.map((msg) => JSON.stringify({ ts: Date.now(), message: msg })).join("\n") + "\n";
51
+ fs.appendFileSync(filePath, lines, "utf-8");
52
+ }
53
+ session.markPersisted();
54
+ // Update index
55
+ entry.messageCount = session.messageCount;
56
+ entry.updatedAt = Date.now();
57
+ // Auto-set title from first user message (once)
58
+ if (!entry.title) {
59
+ const firstUserMsg = session
60
+ .getMessages()
61
+ .find((m) => m.role === "user" && typeof m.content === "string" && m.content.trim());
62
+ if (firstUserMsg && typeof firstUserMsg.content === "string") {
63
+ const raw = firstUserMsg.content.trim().split("\n")[0];
64
+ entry.title = raw.length > MAX_TITLE_LEN ? raw.slice(0, MAX_TITLE_LEN - 1) + "\u2026" : raw;
65
+ }
66
+ }
67
+ this.saveIndex();
68
+ }
69
+ /** Load a session from its JSONL file. Respects compaction markers. */
70
+ async load(sessionKey) {
71
+ const entry = this.index.get(sessionKey);
72
+ if (!entry)
73
+ return null;
74
+ const filePath = path.join(this.dataDir, entry.file);
75
+ if (!fs.existsSync(filePath))
76
+ return null;
77
+ const content = fs.readFileSync(filePath, "utf-8");
78
+ const entries = [];
79
+ for (const line of content.split("\n")) {
80
+ if (!line.trim())
81
+ continue;
82
+ try {
83
+ entries.push(JSON.parse(line));
84
+ }
85
+ catch {
86
+ // skip malformed lines
87
+ }
88
+ }
89
+ // Find the last compaction marker
90
+ let lastCompactionIdx = -1;
91
+ for (let i = entries.length - 1; i >= 0; i--) {
92
+ if (isCompaction(entries[i])) {
93
+ lastCompactionIdx = i;
94
+ break;
95
+ }
96
+ }
97
+ const messages = [];
98
+ if (lastCompactionIdx >= 0) {
99
+ // Compacted: summary message + all message entries after the marker
100
+ const marker = entries[lastCompactionIdx];
101
+ messages.push({
102
+ role: "user",
103
+ content: `[Prior conversation summary]\n${marker.summary}`,
104
+ });
105
+ for (let i = lastCompactionIdx + 1; i < entries.length; i++) {
106
+ const e = entries[i];
107
+ if (!isCompaction(e)) {
108
+ messages.push(e.message);
109
+ }
110
+ }
111
+ }
112
+ else {
113
+ // No compaction: load all messages
114
+ for (const e of entries) {
115
+ if (!isCompaction(e)) {
116
+ messages.push(e.message);
117
+ }
118
+ }
119
+ }
120
+ return new Session(sessionKey, messages);
121
+ }
122
+ /** List all session keys with metadata. */
123
+ list() {
124
+ return [...this.index.values()].sort((a, b) => b.updatedAt - a.updatedAt);
125
+ }
126
+ /** Rename a session (update its title in the index). */
127
+ rename(sessionKey, title) {
128
+ if (typeof title !== "string")
129
+ return false;
130
+ const entry = this.index.get(sessionKey);
131
+ if (!entry)
132
+ return false;
133
+ // Strip control characters and trim
134
+ const sanitized = title.replace(/[\x00-\x1F\x7F-\x9F]/g, "").trim();
135
+ if (sanitized.length === 0)
136
+ return false;
137
+ entry.title = sanitized.length > MAX_TITLE_LEN ? sanitized.slice(0, MAX_TITLE_LEN - 1) + "\u2026" : sanitized;
138
+ this.saveIndex();
139
+ return true;
140
+ }
141
+ /**
142
+ * Update session metadata (team name, agent info). Only writes to disk if something changed.
143
+ * Note: teamName and agentName are denormalized snapshots — they may become stale if
144
+ * the team or agent is renamed after the session was last active.
145
+ */
146
+ updateMetadata(sessionKey, meta) {
147
+ const entry = this.index.get(sessionKey);
148
+ if (!entry)
149
+ return;
150
+ const FIELDS = ["teamId", "teamName", "channelType", "agentId", "agentName"];
151
+ let changed = false;
152
+ for (const field of FIELDS) {
153
+ if (meta[field] !== undefined && entry[field] !== meta[field]) {
154
+ entry[field] = meta[field];
155
+ changed = true;
156
+ }
157
+ }
158
+ if (changed)
159
+ this.saveIndex();
160
+ }
161
+ /** Clear a session — deletes the JSONL file and removes the index entry. */
162
+ async clear(sessionKey) {
163
+ const entry = this.index.get(sessionKey);
164
+ if (!entry)
165
+ return;
166
+ const filePath = path.join(this.dataDir, entry.file);
167
+ if (fs.existsSync(filePath)) {
168
+ fs.unlinkSync(filePath);
169
+ }
170
+ this.index.delete(sessionKey);
171
+ this.saveIndex();
172
+ }
173
+ // --- internal ---
174
+ getOrCreateEntry(key) {
175
+ let entry = this.index.get(key);
176
+ if (!entry) {
177
+ const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
178
+ const parsed = parseSessionKey(key);
179
+ entry = {
180
+ key,
181
+ file: `${safeKey}.jsonl`,
182
+ messageCount: 0,
183
+ updatedAt: Date.now(),
184
+ teamId: parsed.teamId,
185
+ channelType: parsed.channelType,
186
+ };
187
+ this.index.set(key, entry);
188
+ }
189
+ return entry;
190
+ }
191
+ loadIndex() {
192
+ if (!fs.existsSync(this.indexPath)) {
193
+ return new Map();
194
+ }
195
+ try {
196
+ const raw = JSON.parse(fs.readFileSync(this.indexPath, "utf-8"));
197
+ return new Map(Object.entries(raw));
198
+ }
199
+ catch {
200
+ return new Map();
201
+ }
202
+ }
203
+ saveIndex() {
204
+ const obj = Object.fromEntries(this.index);
205
+ fs.writeFileSync(this.indexPath, JSON.stringify(obj, null, 2), "utf-8");
206
+ }
207
+ }
@@ -0,0 +1,32 @@
1
+ import type { LanguageModel, ModelMessage } from "ai";
2
+ export interface PendingCompaction {
3
+ summary: string;
4
+ }
5
+ export declare class Session {
6
+ readonly key: string;
7
+ private messages;
8
+ private persistedCount;
9
+ private _pendingCompaction;
10
+ private _needsFullRewrite;
11
+ constructor(key: string, messages?: ModelMessage[]);
12
+ append(msg: ModelMessage): void;
13
+ getMessages(): ModelMessage[];
14
+ /** Returns only messages not yet written to disk (normal append path). */
15
+ getNewMessages(): ModelMessage[];
16
+ /** After compaction: returns kept + new messages (everything except the summary at index 0). */
17
+ getCompactionMessages(): ModelMessage[];
18
+ /** Mark all current messages as persisted. */
19
+ markPersisted(): void;
20
+ /** Pending compaction info for the store to persist as a marker. */
21
+ get pendingCompaction(): PendingCompaction | null;
22
+ /** True when the file must be fully overwritten (emergency truncate). */
23
+ get needsFullRewrite(): boolean;
24
+ /** LLM-based compaction — summarizes old messages when tokens exceed context budget. */
25
+ compact(model: LanguageModel, contextWindow: number, systemPrompt: string): Promise<boolean>;
26
+ /** Replace the internal messages array (e.g. after programmatic compaction). Marks full rewrite. */
27
+ replaceMessages(messages: ModelMessage[]): void;
28
+ /** Emergency truncation — drop oldest messages, keeping last N. */
29
+ truncate(keep: number): void;
30
+ get messageCount(): number;
31
+ get updatedAt(): number;
32
+ }
@@ -0,0 +1,75 @@
1
+ import { compactMessages } from "./compaction.js";
2
+ export class Session {
3
+ key;
4
+ messages = [];
5
+ persistedCount = 0; // how many messages are already on disk
6
+ _pendingCompaction = null;
7
+ _needsFullRewrite = false;
8
+ constructor(key, messages = []) {
9
+ this.key = key;
10
+ this.messages = messages;
11
+ this.persistedCount = messages.length;
12
+ }
13
+ append(msg) {
14
+ this.messages.push(msg);
15
+ }
16
+ getMessages() {
17
+ return [...this.messages];
18
+ }
19
+ /** Returns only messages not yet written to disk (normal append path). */
20
+ getNewMessages() {
21
+ return this.messages.slice(this.persistedCount);
22
+ }
23
+ /** After compaction: returns kept + new messages (everything except the summary at index 0). */
24
+ getCompactionMessages() {
25
+ return this.messages.slice(1);
26
+ }
27
+ /** Mark all current messages as persisted. */
28
+ markPersisted() {
29
+ this.persistedCount = this.messages.length;
30
+ this._pendingCompaction = null;
31
+ this._needsFullRewrite = false;
32
+ }
33
+ /** Pending compaction info for the store to persist as a marker. */
34
+ get pendingCompaction() {
35
+ return this._pendingCompaction;
36
+ }
37
+ /** True when the file must be fully overwritten (emergency truncate). */
38
+ get needsFullRewrite() {
39
+ return this._needsFullRewrite;
40
+ }
41
+ /** LLM-based compaction — summarizes old messages when tokens exceed context budget. */
42
+ async compact(model, contextWindow, systemPrompt) {
43
+ const result = await compactMessages(model, this.messages, contextWindow, systemPrompt);
44
+ if (result.compacted) {
45
+ this.messages = result.messages;
46
+ if (result.summary) {
47
+ // LLM summarization succeeded — persist as append-only compaction marker
48
+ this._pendingCompaction = { summary: result.summary };
49
+ }
50
+ else {
51
+ // Fallback truncation (no summary) — needs full file rewrite
52
+ this._needsFullRewrite = true;
53
+ }
54
+ }
55
+ return result.compacted;
56
+ }
57
+ /** Replace the internal messages array (e.g. after programmatic compaction). Marks full rewrite. */
58
+ replaceMessages(messages) {
59
+ this.messages = messages;
60
+ this._needsFullRewrite = true;
61
+ }
62
+ /** Emergency truncation — drop oldest messages, keeping last N. */
63
+ truncate(keep) {
64
+ if (this.messages.length > keep) {
65
+ this.messages = this.messages.slice(-keep);
66
+ this._needsFullRewrite = true;
67
+ }
68
+ }
69
+ get messageCount() {
70
+ return this.messages.length;
71
+ }
72
+ get updatedAt() {
73
+ return Date.now();
74
+ }
75
+ }
@@ -0,0 +1,56 @@
1
+ import type { ToolSet } from "ai";
2
+ import type { Config } from "../config.js";
3
+ import type { TaskStore } from "../tasks/store.js";
4
+ import type { TeamStore } from "../teams/store.js";
5
+ import type { MemoryStore } from "../memory/store.js";
6
+ import type { EmbeddingProvider } from "../memory/embedding.js";
7
+ import type { SkillManager } from "../skills/loader.js";
8
+ import type { BrowserConfig } from "../computer/browser/manager.js";
9
+ import { SessionStore } from "./session-store.js";
10
+ export interface SubscriberDeps {
11
+ taskStore: TaskStore;
12
+ teamStore: TeamStore;
13
+ sessionStore: SessionStore;
14
+ memoryStore: MemoryStore | null;
15
+ embeddingProvider: EmbeddingProvider | null;
16
+ memoryMaxResults: number;
17
+ config: Config;
18
+ baseTools: ToolSet;
19
+ skillManager: SkillManager;
20
+ browserConfig: BrowserConfig | null;
21
+ sandboxEnabled: boolean;
22
+ }
23
+ /**
24
+ * Pull-based task execution: workers subscribe to task statuses
25
+ * and self-select tasks from the board. Runs a single poll timer
26
+ * and an efficient cross-table query per tick.
27
+ */
28
+ export declare class TaskSubscriberManager {
29
+ private deps;
30
+ private timer;
31
+ /** agentId → Set<taskId> of currently running tasks */
32
+ private activeRuns;
33
+ private polling;
34
+ constructor(deps: SubscriberDeps);
35
+ start(): void;
36
+ stop(): void;
37
+ private poll;
38
+ /** Release claims that have been held longer than STALE_CLAIM_TIMEOUT_MS. */
39
+ private cleanupStaleClaims;
40
+ /** Emit `taskChange.updated` with the latest task snapshot if it still exists. */
41
+ private emitTaskUpdated;
42
+ /**
43
+ * Find a claimable task and atomically claim it via the store.
44
+ * Uses TeamStore.findClaimableTasks() for cross-table query,
45
+ * then TaskStore.claimTask() for atomic claim.
46
+ */
47
+ private findAndClaim;
48
+ /**
49
+ * Run full LLM loop for a claimed task.
50
+ * Follows same pattern as delegate.ts runWorker().
51
+ */
52
+ private runWorker;
53
+ /** Filter base tools by agent allowlist (empty = inherit all). */
54
+ private filterTools;
55
+ private filterToolSetByAllowlist;
56
+ }