@bryti/agent 0.0.1 → 0.1.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 (228) hide show
  1. package/Dockerfile +27 -0
  2. package/README.md +77 -50
  3. package/config.example.yml +265 -0
  4. package/dist/active-hours.d.ts +23 -0
  5. package/dist/active-hours.d.ts.map +1 -0
  6. package/dist/active-hours.js +68 -0
  7. package/dist/active-hours.js.map +1 -0
  8. package/dist/agent.d.ts +84 -0
  9. package/dist/agent.d.ts.map +1 -0
  10. package/dist/agent.js +383 -0
  11. package/dist/agent.js.map +1 -0
  12. package/dist/channels/markdown/ir.d.ts +79 -0
  13. package/dist/channels/markdown/ir.d.ts.map +1 -0
  14. package/dist/channels/markdown/ir.js +824 -0
  15. package/dist/channels/markdown/ir.js.map +1 -0
  16. package/dist/channels/markdown/render.d.ts +35 -0
  17. package/dist/channels/markdown/render.d.ts.map +1 -0
  18. package/dist/channels/markdown/render.js +178 -0
  19. package/dist/channels/markdown/render.js.map +1 -0
  20. package/dist/channels/telegram-network-errors.d.ts +27 -0
  21. package/dist/channels/telegram-network-errors.d.ts.map +1 -0
  22. package/dist/channels/telegram-network-errors.js +156 -0
  23. package/dist/channels/telegram-network-errors.js.map +1 -0
  24. package/dist/channels/telegram.d.ts +76 -0
  25. package/dist/channels/telegram.d.ts.map +1 -0
  26. package/dist/channels/telegram.js +814 -0
  27. package/dist/channels/telegram.js.map +1 -0
  28. package/dist/channels/types.d.ts +59 -0
  29. package/dist/channels/types.d.ts.map +1 -0
  30. package/dist/channels/types.js +9 -0
  31. package/dist/channels/types.js.map +1 -0
  32. package/dist/channels/whatsapp.d.ts +45 -0
  33. package/dist/channels/whatsapp.d.ts.map +1 -0
  34. package/dist/channels/whatsapp.js +310 -0
  35. package/dist/channels/whatsapp.js.map +1 -0
  36. package/dist/cli.d.ts +13 -0
  37. package/dist/cli.d.ts.map +1 -0
  38. package/dist/cli.js +635 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/commands.d.ts +35 -0
  41. package/dist/commands.d.ts.map +1 -0
  42. package/dist/commands.js +113 -0
  43. package/dist/commands.js.map +1 -0
  44. package/dist/compaction/history.d.ts +17 -0
  45. package/dist/compaction/history.d.ts.map +1 -0
  46. package/dist/compaction/history.js +35 -0
  47. package/dist/compaction/history.js.map +1 -0
  48. package/dist/compaction/index.d.ts +3 -0
  49. package/dist/compaction/index.d.ts.map +1 -0
  50. package/dist/compaction/index.js +3 -0
  51. package/dist/compaction/index.js.map +1 -0
  52. package/dist/compaction/proactive.d.ts +25 -0
  53. package/dist/compaction/proactive.d.ts.map +1 -0
  54. package/dist/compaction/proactive.js +87 -0
  55. package/dist/compaction/proactive.js.map +1 -0
  56. package/dist/compaction/transcript-repair.d.ts +55 -0
  57. package/dist/compaction/transcript-repair.d.ts.map +1 -0
  58. package/dist/compaction/transcript-repair.js +215 -0
  59. package/dist/compaction/transcript-repair.js.map +1 -0
  60. package/dist/config.d.ts +128 -0
  61. package/dist/config.d.ts.map +1 -0
  62. package/dist/config.js +317 -0
  63. package/dist/config.js.map +1 -0
  64. package/dist/crash-recovery.d.ts +23 -0
  65. package/dist/crash-recovery.d.ts.map +1 -0
  66. package/dist/crash-recovery.js +96 -0
  67. package/dist/crash-recovery.js.map +1 -0
  68. package/dist/defaults/extensions/EXTENSIONS.md +158 -0
  69. package/dist/defaults/extensions/documents-hedgedoc.ts +153 -0
  70. package/dist/history.d.ts +31 -0
  71. package/dist/history.d.ts.map +1 -0
  72. package/dist/history.js +49 -0
  73. package/dist/history.js.map +1 -0
  74. package/dist/index.d.ts +19 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +673 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/logger.d.ts +39 -0
  79. package/dist/logger.d.ts.map +1 -0
  80. package/dist/logger.js +143 -0
  81. package/dist/logger.js.map +1 -0
  82. package/dist/memory/conversation-search.d.ts +15 -0
  83. package/dist/memory/conversation-search.d.ts.map +1 -0
  84. package/dist/memory/conversation-search.js +60 -0
  85. package/dist/memory/conversation-search.js.map +1 -0
  86. package/dist/memory/core-memory.d.ts +28 -0
  87. package/dist/memory/core-memory.d.ts.map +1 -0
  88. package/dist/memory/core-memory.js +102 -0
  89. package/dist/memory/core-memory.js.map +1 -0
  90. package/dist/memory/embeddings.d.ts +44 -0
  91. package/dist/memory/embeddings.d.ts.map +1 -0
  92. package/dist/memory/embeddings.js +139 -0
  93. package/dist/memory/embeddings.js.map +1 -0
  94. package/dist/memory/search.d.ts +49 -0
  95. package/dist/memory/search.d.ts.map +1 -0
  96. package/dist/memory/search.js +97 -0
  97. package/dist/memory/search.js.map +1 -0
  98. package/dist/memory/store.d.ts +32 -0
  99. package/dist/memory/store.d.ts.map +1 -0
  100. package/dist/memory/store.js +205 -0
  101. package/dist/memory/store.js.map +1 -0
  102. package/dist/message-queue.d.ts +73 -0
  103. package/dist/message-queue.d.ts.map +1 -0
  104. package/dist/message-queue.js +188 -0
  105. package/dist/message-queue.js.map +1 -0
  106. package/dist/model-infra.d.ts +64 -0
  107. package/dist/model-infra.d.ts.map +1 -0
  108. package/dist/model-infra.js +202 -0
  109. package/dist/model-infra.js.map +1 -0
  110. package/dist/projection/format.d.ts +10 -0
  111. package/dist/projection/format.d.ts.map +1 -0
  112. package/dist/projection/format.js +30 -0
  113. package/dist/projection/format.js.map +1 -0
  114. package/dist/projection/index.d.ts +11 -0
  115. package/dist/projection/index.d.ts.map +1 -0
  116. package/dist/projection/index.js +9 -0
  117. package/dist/projection/index.js.map +1 -0
  118. package/dist/projection/reflection.d.ts +94 -0
  119. package/dist/projection/reflection.d.ts.map +1 -0
  120. package/dist/projection/reflection.js +334 -0
  121. package/dist/projection/reflection.js.map +1 -0
  122. package/dist/projection/store.d.ts +144 -0
  123. package/dist/projection/store.d.ts.map +1 -0
  124. package/dist/projection/store.js +519 -0
  125. package/dist/projection/store.js.map +1 -0
  126. package/dist/projection/tools.d.ts +11 -0
  127. package/dist/projection/tools.d.ts.map +1 -0
  128. package/dist/projection/tools.js +237 -0
  129. package/dist/projection/tools.js.map +1 -0
  130. package/dist/scheduler.d.ts +36 -0
  131. package/dist/scheduler.d.ts.map +1 -0
  132. package/dist/scheduler.js +286 -0
  133. package/dist/scheduler.js.map +1 -0
  134. package/dist/system-prompt.d.ts +41 -0
  135. package/dist/system-prompt.d.ts.map +1 -0
  136. package/dist/system-prompt.js +162 -0
  137. package/dist/system-prompt.js.map +1 -0
  138. package/dist/time.d.ts +52 -0
  139. package/dist/time.d.ts.map +1 -0
  140. package/dist/time.js +138 -0
  141. package/dist/time.js.map +1 -0
  142. package/dist/tools/archival-memory-tool.d.ts +8 -0
  143. package/dist/tools/archival-memory-tool.d.ts.map +1 -0
  144. package/dist/tools/archival-memory-tool.js +68 -0
  145. package/dist/tools/archival-memory-tool.js.map +1 -0
  146. package/dist/tools/conversation-search-tool.d.ts +6 -0
  147. package/dist/tools/conversation-search-tool.d.ts.map +1 -0
  148. package/dist/tools/conversation-search-tool.js +28 -0
  149. package/dist/tools/conversation-search-tool.js.map +1 -0
  150. package/dist/tools/core-memory-tool.d.ts +7 -0
  151. package/dist/tools/core-memory-tool.d.ts.map +1 -0
  152. package/dist/tools/core-memory-tool.js +59 -0
  153. package/dist/tools/core-memory-tool.js.map +1 -0
  154. package/dist/tools/fetch-url.d.ts +15 -0
  155. package/dist/tools/fetch-url.d.ts.map +1 -0
  156. package/dist/tools/fetch-url.js +76 -0
  157. package/dist/tools/fetch-url.js.map +1 -0
  158. package/dist/tools/files.d.ts +10 -0
  159. package/dist/tools/files.d.ts.map +1 -0
  160. package/dist/tools/files.js +127 -0
  161. package/dist/tools/files.js.map +1 -0
  162. package/dist/tools/index.d.ts +17 -0
  163. package/dist/tools/index.d.ts.map +1 -0
  164. package/dist/tools/index.js +118 -0
  165. package/dist/tools/index.js.map +1 -0
  166. package/dist/tools/result.d.ts +21 -0
  167. package/dist/tools/result.d.ts.map +1 -0
  168. package/dist/tools/result.js +36 -0
  169. package/dist/tools/result.js.map +1 -0
  170. package/dist/tools/skill-install.d.ts +17 -0
  171. package/dist/tools/skill-install.d.ts.map +1 -0
  172. package/dist/tools/skill-install.js +148 -0
  173. package/dist/tools/skill-install.js.map +1 -0
  174. package/dist/tools/web-search.d.ts +42 -0
  175. package/dist/tools/web-search.d.ts.map +1 -0
  176. package/dist/tools/web-search.js +237 -0
  177. package/dist/tools/web-search.js.map +1 -0
  178. package/dist/trust/guardrail.d.ts +60 -0
  179. package/dist/trust/guardrail.d.ts.map +1 -0
  180. package/dist/trust/guardrail.js +171 -0
  181. package/dist/trust/guardrail.js.map +1 -0
  182. package/dist/trust/index.d.ts +12 -0
  183. package/dist/trust/index.d.ts.map +1 -0
  184. package/dist/trust/index.js +12 -0
  185. package/dist/trust/index.js.map +1 -0
  186. package/dist/trust/store.d.ts +118 -0
  187. package/dist/trust/store.d.ts.map +1 -0
  188. package/dist/trust/store.js +209 -0
  189. package/dist/trust/store.js.map +1 -0
  190. package/dist/trust/wrapper.d.ts +36 -0
  191. package/dist/trust/wrapper.d.ts.map +1 -0
  192. package/dist/trust/wrapper.js +142 -0
  193. package/dist/trust/wrapper.js.map +1 -0
  194. package/dist/usage.d.ts +53 -0
  195. package/dist/usage.d.ts.map +1 -0
  196. package/dist/usage.js +124 -0
  197. package/dist/usage.js.map +1 -0
  198. package/dist/util/math.d.ts +9 -0
  199. package/dist/util/math.d.ts.map +1 -0
  200. package/dist/util/math.js +22 -0
  201. package/dist/util/math.js.map +1 -0
  202. package/dist/util/ssrf.d.ts +21 -0
  203. package/dist/util/ssrf.d.ts.map +1 -0
  204. package/dist/util/ssrf.js +77 -0
  205. package/dist/util/ssrf.js.map +1 -0
  206. package/dist/workers/index.d.ts +8 -0
  207. package/dist/workers/index.d.ts.map +1 -0
  208. package/dist/workers/index.js +7 -0
  209. package/dist/workers/index.js.map +1 -0
  210. package/dist/workers/registry.d.ts +53 -0
  211. package/dist/workers/registry.d.ts.map +1 -0
  212. package/dist/workers/registry.js +38 -0
  213. package/dist/workers/registry.js.map +1 -0
  214. package/dist/workers/scoped-tools.d.ts +21 -0
  215. package/dist/workers/scoped-tools.d.ts.map +1 -0
  216. package/dist/workers/scoped-tools.js +111 -0
  217. package/dist/workers/scoped-tools.js.map +1 -0
  218. package/dist/workers/spawn.d.ts +62 -0
  219. package/dist/workers/spawn.d.ts.map +1 -0
  220. package/dist/workers/spawn.js +314 -0
  221. package/dist/workers/spawn.js.map +1 -0
  222. package/dist/workers/tools.d.ts +26 -0
  223. package/dist/workers/tools.d.ts.map +1 -0
  224. package/dist/workers/tools.js +380 -0
  225. package/dist/workers/tools.js.map +1 -0
  226. package/docker-compose.yml +72 -0
  227. package/package.json +16 -1
  228. package/run.sh +27 -0
@@ -0,0 +1,380 @@
1
+ /**
2
+ * Worker tools: dispatch, check, interrupt, steer.
3
+ *
4
+ * Workers are background LLM sessions with a scoped tool set. They write
5
+ * results to a file and signal completion by archiving a fact, which triggers
6
+ * any matching projection in the main agent.
7
+ *
8
+ * Lifecycle:
9
+ * 1. dispatch: create worker dir, write task.md, spawn session
10
+ * 2. Worker runs autonomously (web search, fetch URL, write result.md)
11
+ * 3. On completion/failure/timeout: write status.json, archive a fact
12
+ * 4. check: query status; interrupt: cancel immediately; steer: redirect
13
+ */
14
+ import fs from "node:fs";
15
+ import path from "node:path";
16
+ import crypto from "node:crypto";
17
+ import { Type } from "@sinclair/typebox";
18
+ import { embed } from "../memory/embeddings.js";
19
+ import { toolError, toolSuccess } from "../tools/result.js";
20
+ import { spawnWorkerSession, writeStatusFile, } from "./spawn.js";
21
+ // ---------------------------------------------------------------------------
22
+ // Constants and types
23
+ // ---------------------------------------------------------------------------
24
+ const ALLOWED_TOOLS = ["web_search", "fetch_url"];
25
+ const DEFAULT_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
26
+ // ---------------------------------------------------------------------------
27
+ // Tool schemas
28
+ // ---------------------------------------------------------------------------
29
+ const dispatchWorkerSchema = Type.Object({
30
+ task: Type.String({
31
+ description: "Detailed description of what the worker should do. Be specific: include what to search for, " +
32
+ "what sources to look at, and what format the result should take.",
33
+ }),
34
+ type: Type.Optional(Type.String({
35
+ description: "Worker type name from config. When set, the worker inherits the type's model, tools, " +
36
+ "and timeout as defaults. Explicit model/tools/timeout_seconds parameters still override.",
37
+ })),
38
+ tools: Type.Optional(Type.Array(Type.Union([Type.Literal("web_search"), Type.Literal("fetch_url")]), {
39
+ description: "Tools the worker may use. Defaults to [\"web_search\", \"fetch_url\"]. " +
40
+ "Omit fetch_url if only keyword search is needed.",
41
+ })),
42
+ model: Type.Optional(Type.String({
43
+ description: "Model to use for this worker. Defaults to the type's model if a type is set, " +
44
+ "otherwise the configured worker default.",
45
+ })),
46
+ timeout_seconds: Type.Optional(Type.Number({
47
+ description: "Maximum seconds before the worker is forcibly stopped. Default: 3600 (1 hour).",
48
+ })),
49
+ });
50
+ const checkWorkerSchema = Type.Object({
51
+ worker_id: Type.String({ description: "The worker_id returned by worker_dispatch." }),
52
+ });
53
+ const interruptWorkerSchema = Type.Object({
54
+ worker_id: Type.String({ description: "The worker_id returned by worker_dispatch." }),
55
+ });
56
+ const steerWorkerSchema = Type.Object({
57
+ worker_id: Type.String({ description: "The worker_id returned by worker_dispatch." }),
58
+ guidance: Type.String({
59
+ description: "New instructions for the worker. Be specific: what to focus on, what to skip, " +
60
+ "what to add. The worker checks for this after every few tool calls and adjusts accordingly. " +
61
+ "Replaces any prior steering — include everything the worker needs.",
62
+ }),
63
+ });
64
+ // ---------------------------------------------------------------------------
65
+ // Tool factory
66
+ // ---------------------------------------------------------------------------
67
+ /**
68
+ * Create worker tools (dispatch, check, interrupt, steer).
69
+ * When isWorkerSession is true, dispatch rejects all calls (no nesting).
70
+ */
71
+ export function createWorkerTools(config, memoryStore, registry, isWorkerSession = false, projectionStore, onTrigger) {
72
+ // Build description dynamically to include configured worker types
73
+ const types = config.tools.workers.types ?? {};
74
+ const typeNames = Object.keys(types);
75
+ let typesSuffix = "";
76
+ if (typeNames.length > 0) {
77
+ const typeLines = typeNames.map((name) => {
78
+ const t = types[name];
79
+ const parts = [name];
80
+ if (t.description)
81
+ parts.push(`— ${t.description}`);
82
+ if (t.model)
83
+ parts.push(`(model: ${t.model})`);
84
+ return parts.join(" ");
85
+ });
86
+ typesSuffix =
87
+ ` Available worker types: ${typeLines.join("; ")}. ` +
88
+ `Set the "type" parameter to use a type's defaults.`;
89
+ }
90
+ const dispatchTool = {
91
+ name: "worker_dispatch",
92
+ label: "worker_dispatch",
93
+ description: "Dispatch a background worker to perform a long-running task (research, content gathering, etc.). " +
94
+ "Returns immediately — the worker runs in the background. " +
95
+ "After dispatching, create a projection with trigger_on_fact matching the worker completion fact " +
96
+ "(e.g. 'worker <id> complete') so you are notified when results are ready. " +
97
+ "Workers can use web_search and fetch_url. They write results to result.md. " +
98
+ `Max ${config.tools.workers.max_concurrent} concurrent workers.` +
99
+ typesSuffix,
100
+ parameters: dispatchWorkerSchema,
101
+ async execute(_toolCallId, { task, type: typeName, tools: requestedTools, model: modelOverride, timeout_seconds }) {
102
+ // Hard block: no nesting
103
+ if (isWorkerSession) {
104
+ return toolError("Workers cannot dispatch other workers.");
105
+ }
106
+ // Concurrency limit
107
+ const maxConcurrent = config.tools.workers.max_concurrent;
108
+ if (registry.runningCount() >= maxConcurrent) {
109
+ return toolError(`Maximum concurrent workers (${maxConcurrent}) already running. ` +
110
+ `Use worker_check to see current workers, or wait for one to complete.`);
111
+ }
112
+ // Resolve worker type defaults (explicit params override type defaults)
113
+ const workerType = typeName ? config.tools.workers.types?.[typeName] : undefined;
114
+ if (typeName && !workerType) {
115
+ const available = Object.keys(config.tools.workers.types ?? {});
116
+ return toolError(`Unknown worker type "${typeName}". ` +
117
+ (available.length > 0
118
+ ? `Available types: ${available.join(", ")}`
119
+ : "No worker types configured."));
120
+ }
121
+ const effectiveTools = requestedTools ?? workerType?.tools ?? ["web_search", "fetch_url"];
122
+ const effectiveTimeout = timeout_seconds ?? workerType?.timeout_seconds;
123
+ const effectiveModel = modelOverride ?? workerType?.model;
124
+ // Validate requested tools
125
+ const toolNames = [];
126
+ for (const t of effectiveTools) {
127
+ if (!ALLOWED_TOOLS.includes(t)) {
128
+ return toolError(`Unknown tool "${t}". Allowed: ${ALLOWED_TOOLS.join(", ")}`);
129
+ }
130
+ toolNames.push(t);
131
+ }
132
+ if (toolNames.length === 0) {
133
+ toolNames.push("web_search", "fetch_url");
134
+ }
135
+ // Create worker directory
136
+ const workerId = `w-${crypto.randomUUID().slice(0, 8)}`;
137
+ const workerDir = path.join(config.data_dir, "files", "workers", workerId);
138
+ fs.mkdirSync(workerDir, { recursive: true });
139
+ // Write task brief
140
+ fs.writeFileSync(path.join(workerDir, "task.md"), task, "utf-8");
141
+ const timeoutMs = effectiveTimeout ? effectiveTimeout * 1000 : DEFAULT_TIMEOUT_MS;
142
+ // Resolve display model for registry/logs. The actual model resolution
143
+ // (with fallback chain) happens inside spawnWorkerSession.
144
+ const displayModel = effectiveModel
145
+ ?? config.tools.workers.model
146
+ ?? config.agent.fallback_models?.[0]
147
+ ?? config.agent.model;
148
+ const resultPath = path.join(workerDir, "result.md");
149
+ // Register immediately so worker_check can find it
150
+ registry.register({
151
+ workerId,
152
+ status: "running",
153
+ task,
154
+ resultPath,
155
+ workerDir,
156
+ startedAt: new Date(),
157
+ error: null,
158
+ model: displayModel,
159
+ abort: null,
160
+ timeoutHandle: null,
161
+ });
162
+ // Write initial status.json
163
+ writeStatusFile(workerDir, {
164
+ worker_id: workerId,
165
+ status: "running",
166
+ task,
167
+ started_at: new Date().toISOString(),
168
+ completed_at: null,
169
+ model: displayModel,
170
+ error: null,
171
+ result_path: resultPath,
172
+ });
173
+ console.log(`[worker] Dispatching ${workerId} (model: ${displayModel}, tools: ${toolNames.join(", ")})`);
174
+ // Spawn in background — intentionally not awaited
175
+ spawnWorkerSession({
176
+ config,
177
+ workerId,
178
+ workerDir,
179
+ task,
180
+ modelOverride: effectiveModel,
181
+ toolNames,
182
+ memoryStore,
183
+ projectionStore,
184
+ registry,
185
+ timeoutMs,
186
+ onTrigger,
187
+ }).catch((err) => {
188
+ console.error(`[worker] ${workerId} spawn failed:`, err.message);
189
+ registry.update(workerId, {
190
+ status: "failed",
191
+ completedAt: new Date(),
192
+ error: `Spawn failed: ${err.message}`,
193
+ });
194
+ });
195
+ // Return immediately — worker is running in the background
196
+ const relativeResultPath = path.relative(config.data_dir, resultPath);
197
+ return toolSuccess({
198
+ worker_id: workerId,
199
+ status: "running",
200
+ result_path: relativeResultPath,
201
+ trigger_hint: `worker ${workerId} complete`,
202
+ note: `Worker dispatched. Create a projection with trigger_on_fact: "worker ${workerId} complete" ` +
203
+ `to be notified when results are ready. Results will be at: ${relativeResultPath}`,
204
+ });
205
+ },
206
+ };
207
+ const checkTool = {
208
+ name: "worker_check",
209
+ label: "worker_check",
210
+ description: "Check the status of a background worker. " +
211
+ "Use when the user asks how a task is progressing, or to verify completion before reading results.",
212
+ parameters: checkWorkerSchema,
213
+ async execute(_toolCallId, { worker_id }) {
214
+ const entry = registry.get(worker_id);
215
+ if (!entry) {
216
+ // Try reading from status.json on disk as a fallback (survives restarts)
217
+ const workerDir = path.join(config.data_dir, "files", "workers", worker_id);
218
+ const statusFile = path.join(workerDir, "status.json");
219
+ if (fs.existsSync(statusFile)) {
220
+ try {
221
+ const data = JSON.parse(fs.readFileSync(statusFile, "utf-8"));
222
+ const relResult = path.relative(config.data_dir, data.result_path);
223
+ const elapsed = data.completed_at
224
+ ? Math.round((new Date(data.completed_at).getTime() - new Date(data.started_at).getTime()) / 60000)
225
+ : null;
226
+ return toolSuccess({
227
+ worker_id: data.worker_id,
228
+ status: data.status,
229
+ elapsed_minutes: elapsed,
230
+ result_path: relResult,
231
+ error: data.error ?? undefined,
232
+ note: "Status read from disk (worker no longer in active registry).",
233
+ });
234
+ }
235
+ catch {
236
+ // Fall through to not-found
237
+ }
238
+ }
239
+ return toolError(`Worker not found: ${worker_id}`);
240
+ }
241
+ const elapsedMs = Date.now() - entry.startedAt.getTime();
242
+ const elapsedMinutes = Math.round(elapsedMs / 60000);
243
+ const relativeResultPath = path.relative(config.data_dir, entry.resultPath);
244
+ return toolSuccess({
245
+ worker_id: entry.workerId,
246
+ status: entry.status,
247
+ elapsed_minutes: elapsedMinutes,
248
+ result_path: relativeResultPath,
249
+ ...(entry.error ? { error: entry.error } : {}),
250
+ ...(entry.status === "complete" ? { note: `Results available at ${relativeResultPath}` } : {}),
251
+ });
252
+ },
253
+ };
254
+ const interruptTool = {
255
+ name: "worker_interrupt",
256
+ label: "worker_interrupt",
257
+ description: "Cancel a running background worker immediately. " +
258
+ "Use when the task is no longer needed, the user asks you to stop it, or the worker is taking too long. " +
259
+ "If the worker has already finished, this is a no-op and returns the current status.",
260
+ parameters: interruptWorkerSchema,
261
+ async execute(_toolCallId, { worker_id }) {
262
+ const entry = registry.get(worker_id);
263
+ if (!entry) {
264
+ // Check disk as a fallback (worker may have been cleaned up from registry)
265
+ const workerDir = path.join(config.data_dir, "files", "workers", worker_id);
266
+ const statusFile = path.join(workerDir, "status.json");
267
+ if (fs.existsSync(statusFile)) {
268
+ try {
269
+ const data = JSON.parse(fs.readFileSync(statusFile, "utf-8"));
270
+ return toolSuccess({
271
+ worker_id,
272
+ status: data.status,
273
+ note: `Worker already finished with status "${data.status}". Nothing to interrupt.`,
274
+ });
275
+ }
276
+ catch {
277
+ // Fall through
278
+ }
279
+ }
280
+ return toolError(`Worker not found: ${worker_id}`);
281
+ }
282
+ // Already in a terminal state — nothing to do
283
+ if (entry.status !== "running") {
284
+ return toolSuccess({
285
+ worker_id,
286
+ status: entry.status,
287
+ note: `Worker already in terminal state "${entry.status}". Nothing to interrupt.`,
288
+ });
289
+ }
290
+ // Cancel the timeout so it doesn't fire after we've already cancelled
291
+ if (entry.timeoutHandle) {
292
+ clearTimeout(entry.timeoutHandle);
293
+ }
294
+ // Mark cancelled before calling abort() so the spawnWorkerSession catch
295
+ // block sees the terminal status and skips overwriting it
296
+ const cancelledAt = new Date();
297
+ registry.update(worker_id, {
298
+ status: "cancelled",
299
+ completedAt: cancelledAt,
300
+ error: null,
301
+ timeoutHandle: null,
302
+ });
303
+ writeStatusFile(path.join(config.data_dir, "files", "workers", worker_id), {
304
+ worker_id,
305
+ status: "cancelled",
306
+ task: entry.task,
307
+ started_at: entry.startedAt.toISOString(),
308
+ completed_at: cancelledAt.toISOString(),
309
+ model: entry.model,
310
+ error: null,
311
+ result_path: entry.resultPath,
312
+ });
313
+ // Abort the session if it's running. abort() may throw — treat as best-effort
314
+ if (entry.abort) {
315
+ try {
316
+ await entry.abort();
317
+ }
318
+ catch {
319
+ // Best-effort — the status is already set to cancelled
320
+ }
321
+ }
322
+ // Archive a cancellation fact so any projections watching this worker can clean up
323
+ const modelsDir = path.join(config.data_dir, ".models");
324
+ const factContent = `Worker ${worker_id} cancelled`;
325
+ try {
326
+ const embedding = await embed(factContent, modelsDir);
327
+ memoryStore.addFact(factContent, "worker", embedding);
328
+ console.log(`[worker] ${worker_id} cancellation fact archived`);
329
+ }
330
+ catch (err) {
331
+ console.error(`[worker] ${worker_id} failed to archive cancellation fact:`, err.message);
332
+ }
333
+ console.log(`[worker] ${worker_id} cancelled`);
334
+ return toolSuccess({
335
+ worker_id,
336
+ status: "cancelled",
337
+ note: "Worker has been cancelled. Any partial results may still exist in the worker directory.",
338
+ });
339
+ },
340
+ };
341
+ const steerTool = {
342
+ name: "worker_steer",
343
+ label: "worker_steer",
344
+ description: "Send updated guidance to a running background worker. " +
345
+ "The worker checks for a steering.md file after every few tool calls and incorporates the instructions. " +
346
+ "Use this to narrow focus, redirect research, add requirements, or correct course mid-task. " +
347
+ "Each call replaces the previous steering note — include everything the worker needs. " +
348
+ "Has no effect on workers that have already finished.",
349
+ parameters: steerWorkerSchema,
350
+ async execute(_toolCallId, { worker_id, guidance }) {
351
+ const entry = registry.get(worker_id);
352
+ if (!entry) {
353
+ return toolError(`Worker not found: ${worker_id}`);
354
+ }
355
+ if (entry.status !== "running") {
356
+ return toolSuccess({
357
+ worker_id,
358
+ status: entry.status,
359
+ note: `Worker is already in terminal state "${entry.status}". Steering has no effect.`,
360
+ });
361
+ }
362
+ const steeringPath = path.join(entry.workerDir, "steering.md");
363
+ try {
364
+ fs.writeFileSync(steeringPath, guidance, "utf-8");
365
+ }
366
+ catch (error) {
367
+ return toolError(error, "Failed to write steering note");
368
+ }
369
+ console.log(`[worker] ${worker_id} steering note updated (${Buffer.byteLength(guidance, "utf-8")} bytes)`);
370
+ return toolSuccess({
371
+ worker_id,
372
+ status: "running",
373
+ note: "Steering note written. The worker will pick it up after its next few tool calls " +
374
+ "and adjust its work accordingly.",
375
+ });
376
+ },
377
+ };
378
+ return [dispatchTool, checkTool, interruptTool, steerTool];
379
+ }
380
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/workers/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAG5D,OAAO,EACL,kBAAkB,EAClB,eAAe,GAGhB,MAAM,YAAY,CAAC;AAEpB,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,WAAW,CAAU,CAAC;AAG3D,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAKxD,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,MAAM,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;QAChB,WAAW,EACT,8FAA8F;YAC9F,kEAAkE;KACrE,CAAC;IACF,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9B,WAAW,EACT,uFAAuF;YACvF,0FAA0F;KAC7F,CAAC,CAAC;IACH,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAC7B,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EACnE;QACE,WAAW,EACT,yEAAyE;YACzE,kDAAkD;KACrD,CACF,CAAC;IACF,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B,WAAW,EACT,+EAA+E;YAC/E,0CAA0C;KAC7C,CAAC,CAAC;IACH,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QACzC,WAAW,EAAE,gFAAgF;KAC9F,CAAC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4CAA4C,EAAE,CAAC;CACtF,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC;IACxC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4CAA4C,EAAE,CAAC;CACtF,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4CAA4C,EAAE,CAAC;IACrF,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;QACpB,WAAW,EACT,gFAAgF;YAChF,8FAA8F;YAC9F,oEAAoE;KACvE,CAAC;CACH,CAAC,CAAC;AAOH,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,WAAwB,EACxB,QAAwB,EACxB,eAAe,GAAG,KAAK,EACvB,eAAiC,EACjC,SAAiC;IAEjC,mEAAmE;IACnE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACvC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,CAAC,CAAC,WAAW;gBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,WAAW;YACT,4BAA4B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBACpD,oDAAoD,CAAC;IACzD,CAAC;IAED,MAAM,YAAY,GAA2C;QAC3D,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,mGAAmG;YACnG,2DAA2D;YAC3D,kGAAkG;YAClG,4EAA4E;YAC5E,6EAA6E;YAC7E,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,sBAAsB;YAChE,WAAW;QACb,UAAU,EAAE,oBAAoB;QAChC,KAAK,CAAC,OAAO,CACX,WAAmB,EACnB,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,eAAe,EAAuB;YAE3G,yBAAyB;YACzB,IAAI,eAAe,EAAE,CAAC;gBACpB,OAAO,SAAS,CAAC,wCAAwC,CAAC,CAAC;YAC7D,CAAC;YAED,oBAAoB;YACpB,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;YAC1D,IAAI,QAAQ,CAAC,YAAY,EAAE,IAAI,aAAa,EAAE,CAAC;gBAC7C,OAAO,SAAS,CACd,+BAA+B,aAAa,qBAAqB;oBACjE,uEAAuE,CACxE,CAAC;YACJ,CAAC;YAED,wEAAwE;YACxE,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACjF,IAAI,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAChE,OAAO,SAAS,CACd,wBAAwB,QAAQ,KAAK;oBACrC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;wBACnB,CAAC,CAAC,oBAAoB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBAC5C,CAAC,CAAC,6BAA6B,CAAC,CACnC,CAAC;YACJ,CAAC;YAED,MAAM,cAAc,GAAG,cAAc,IAAI,UAAU,EAAE,KAAK,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YAC1F,MAAM,gBAAgB,GAAG,eAAe,IAAI,UAAU,EAAE,eAAe,CAAC;YACxE,MAAM,cAAc,GAAG,aAAa,IAAI,UAAU,EAAE,KAAK,CAAC;YAE1D,2BAA2B;YAC3B,MAAM,SAAS,GAAkB,EAAE,CAAC;YACpC,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;gBAC/B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAgB,CAAC,EAAE,CAAC;oBAC9C,OAAO,SAAS,CAAC,iBAAiB,CAAC,eAAe,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAChF,CAAC;gBACD,SAAS,CAAC,IAAI,CAAC,CAAgB,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YAC5C,CAAC;YAED,0BAA0B;YAC1B,MAAM,QAAQ,GAAG,KAAK,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACxD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC3E,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAE7C,mBAAmB;YACnB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAEjE,MAAM,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;YAClF,uEAAuE;YACvE,2DAA2D;YAC3D,MAAM,YAAY,GAAG,cAAc;mBAC9B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK;mBAC1B,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;mBACjC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YACxB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAErD,mDAAmD;YACnD,QAAQ,CAAC,QAAQ,CAAC;gBAChB,QAAQ;gBACR,MAAM,EAAE,SAAS;gBACjB,IAAI;gBACJ,UAAU;gBACV,SAAS;gBACT,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,YAAY;gBACnB,KAAK,EAAE,IAAI;gBACX,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YAEH,4BAA4B;YAC5B,eAAe,CAAC,SAAS,EAAE;gBACzB,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE,SAAS;gBACjB,IAAI;gBACJ,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,YAAY,EAAE,IAAI;gBAClB,KAAK,EAAE,YAAY;gBACnB,KAAK,EAAE,IAAI;gBACX,WAAW,EAAE,UAAU;aACxB,CAAC,CAAC;YAEH,OAAO,CAAC,GAAG,CAAC,wBAAwB,QAAQ,YAAY,YAAY,YAAY,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEzG,kDAAkD;YAClD,kBAAkB,CAAC;gBACjB,MAAM;gBACN,QAAQ;gBACR,SAAS;gBACT,IAAI;gBACJ,aAAa,EAAE,cAAc;gBAC7B,SAAS;gBACT,WAAW;gBACX,eAAe;gBACf,QAAQ;gBACR,SAAS;gBACT,SAAS;aACV,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;gBACtB,OAAO,CAAC,KAAK,CAAC,YAAY,QAAQ,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACjE,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;oBACxB,MAAM,EAAE,QAAQ;oBAChB,WAAW,EAAE,IAAI,IAAI,EAAE;oBACvB,KAAK,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;iBACtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,2DAA2D;YAC3D,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACtE,OAAO,WAAW,CAAC;gBACjB,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE,SAAS;gBACjB,WAAW,EAAE,kBAAkB;gBAC/B,YAAY,EAAE,UAAU,QAAQ,WAAW;gBAC3C,IAAI,EACF,wEAAwE,QAAQ,aAAa;oBAC7F,8DAA8D,kBAAkB,EAAE;aACrF,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,MAAM,SAAS,GAAwC;QACrD,IAAI,EAAE,cAAc;QACpB,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,2CAA2C;YAC3C,mGAAmG;QACrG,UAAU,EAAE,iBAAiB;QAC7B,KAAK,CAAC,OAAO,CACX,WAAmB,EACnB,EAAE,SAAS,EAAoB;YAE/B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,yEAAyE;gBACzE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;gBAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;gBACvD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC9B,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAqB,CAAC;wBAClF,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;wBACnE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY;4BAC/B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC;4BACnG,CAAC,CAAC,IAAI,CAAC;wBACT,OAAO,WAAW,CAAC;4BACjB,SAAS,EAAE,IAAI,CAAC,SAAS;4BACzB,MAAM,EAAE,IAAI,CAAC,MAAM;4BACnB,eAAe,EAAE,OAAO;4BACxB,WAAW,EAAE,SAAS;4BACtB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;4BAC9B,IAAI,EAAE,8DAA8D;yBACrE,CAAC,CAAC;oBACL,CAAC;oBAAC,MAAM,CAAC;wBACP,4BAA4B;oBAC9B,CAAC;gBACH,CAAC;gBACD,OAAO,SAAS,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACzD,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;YACrD,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YAE5E,OAAO,WAAW,CAAC;gBACjB,SAAS,EAAE,KAAK,CAAC,QAAQ;gBACzB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,eAAe,EAAE,cAAc;gBAC/B,WAAW,EAAE,kBAAkB;gBAC/B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9C,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,wBAAwB,kBAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/F,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,MAAM,aAAa,GAA4C;QAC7D,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,kDAAkD;YAClD,yGAAyG;YACzG,qFAAqF;QACvF,UAAU,EAAE,qBAAqB;QACjC,KAAK,CAAC,OAAO,CACX,WAAmB,EACnB,EAAE,SAAS,EAAwB;YAEnC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAEtC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,2EAA2E;gBAC3E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;gBAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;gBACvD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC9B,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAqB,CAAC;wBAClF,OAAO,WAAW,CAAC;4BACjB,SAAS;4BACT,MAAM,EAAE,IAAI,CAAC,MAAM;4BACnB,IAAI,EAAE,wCAAwC,IAAI,CAAC,MAAM,0BAA0B;yBACpF,CAAC,CAAC;oBACL,CAAC;oBAAC,MAAM,CAAC;wBACP,eAAe;oBACjB,CAAC;gBACH,CAAC;gBACD,OAAO,SAAS,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,8CAA8C;YAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,WAAW,CAAC;oBACjB,SAAS;oBACT,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,IAAI,EAAE,qCAAqC,KAAK,CAAC,MAAM,0BAA0B;iBAClF,CAAC,CAAC;YACL,CAAC;YAED,sEAAsE;YACtE,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACxB,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC;YAED,wEAAwE;YACxE,0DAA0D;YAC1D,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;YAC/B,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE;gBACzB,MAAM,EAAE,WAAW;gBACnB,WAAW,EAAE,WAAW;gBACxB,KAAK,EAAE,IAAI;gBACX,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YAEH,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;gBACzE,SAAS;gBACT,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE;gBACzC,YAAY,EAAE,WAAW,CAAC,WAAW,EAAE;gBACvC,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,KAAK,EAAE,IAAI;gBACX,WAAW,EAAE,KAAK,CAAC,UAAU;aAC9B,CAAC,CAAC;YAEH,8EAA8E;YAC9E,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,IAAI,CAAC;oBACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC;oBACP,uDAAuD;gBACzD,CAAC;YACH,CAAC;YAED,mFAAmF;YACnF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YACxD,MAAM,WAAW,GAAG,UAAU,SAAS,YAAY,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;gBACtD,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,6BAA6B,CAAC,CAAC;YAClE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,YAAY,SAAS,uCAAuC,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;YACtG,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,YAAY,CAAC,CAAC;YAE/C,OAAO,WAAW,CAAC;gBACjB,SAAS;gBACT,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,yFAAyF;aAChG,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,MAAM,SAAS,GAAwC;QACrD,IAAI,EAAE,cAAc;QACpB,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,wDAAwD;YACxD,yGAAyG;YACzG,6FAA6F;YAC7F,uFAAuF;YACvF,sDAAsD;QACxD,UAAU,EAAE,iBAAiB;QAC7B,KAAK,CAAC,OAAO,CACX,WAAmB,EACnB,EAAE,SAAS,EAAE,QAAQ,EAAoB;YAEzC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAEtC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,SAAS,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,WAAW,CAAC;oBACjB,SAAS;oBACT,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,IAAI,EAAE,wCAAwC,KAAK,CAAC,MAAM,4BAA4B;iBACvF,CAAC,CAAC;YACL,CAAC;YAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YAC/D,IAAI,CAAC;gBACH,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,SAAS,CAAC,KAAK,EAAE,+BAA+B,CAAC,CAAC;YAC3D,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,2BAA2B,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YAE3G,OAAO,WAAW,CAAC;gBACjB,SAAS;gBACT,MAAM,EAAE,SAAS;gBACjB,IAAI,EACF,kFAAkF;oBAClF,kCAAkC;aACrC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,OAAO,CAAC,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,72 @@
1
+ services:
2
+ bryti:
3
+ build:
4
+ context: .
5
+ dockerfile: Dockerfile
6
+ restart: unless-stopped
7
+ volumes:
8
+ - ./data:/data
9
+ env_file: .env
10
+ environment:
11
+ - BRYTI_DATA_DIR=/data
12
+
13
+ # ---------------------------------------------------------------------------
14
+ # HedgeDoc — collaborative document editing (optional)
15
+ #
16
+ # Provides document_create, document_update, document_read tools via the
17
+ # documents-hedgedoc extension in data/files/extensions/.
18
+ #
19
+ # To activate:
20
+ # 1. Uncomment this block and hedgedoc_db below
21
+ # 2. Set HEDGEDOC_URL and HEDGEDOC_PUBLIC_URL in your .env file
22
+ # 3. The extension picks them up automatically on next start
23
+ #
24
+ # .env entries needed:
25
+ # HEDGEDOC_URL=http://hedgedoc:3000
26
+ # HEDGEDOC_PUBLIC_URL=https://docs.yourdomain.com
27
+ # HEDGEDOC_DOMAIN=docs.yourdomain.com
28
+ # HEDGEDOC_SECRET=<run: openssl rand -hex 32>
29
+ # ---------------------------------------------------------------------------
30
+ # hedgedoc:
31
+ # image: quay.io/hedgedoc/hedgedoc:1.10
32
+ # restart: unless-stopped
33
+ # environment:
34
+ # - CMD_DB_URL=postgres://hedgedoc:hedgedoc@hedgedoc_db:5432/hedgedoc
35
+ # - CMD_DOMAIN=${HEDGEDOC_DOMAIN} # public hostname, no protocol
36
+ # - CMD_URL_ADDPORT=false
37
+ # - CMD_PROTOCOL_USESSL=true
38
+ # - CMD_ALLOW_ANONYMOUS=true # allow anonymous note creation
39
+ # - CMD_ALLOW_FREEURL=true # required for document_update to work
40
+ # - CMD_SESSION_SECRET=${HEDGEDOC_SECRET}
41
+ # volumes:
42
+ # - hedgedoc_uploads:/hedgedoc/public/uploads
43
+ # depends_on:
44
+ # - hedgedoc_db
45
+ #
46
+ # hedgedoc_db:
47
+ # image: postgres:16-alpine
48
+ # restart: unless-stopped
49
+ # environment:
50
+ # - POSTGRES_USER=hedgedoc
51
+ # - POSTGRES_PASSWORD=hedgedoc
52
+ # - POSTGRES_DB=hedgedoc
53
+ # volumes:
54
+ # - hedgedoc_db_data:/var/lib/postgresql/data
55
+
56
+ # Uncomment for production with webhook mode
57
+ # caddy:
58
+ # image: caddy:2-alpine
59
+ # restart: unless-stopped
60
+ # ports:
61
+ # - "80:80"
62
+ # - "443:443"
63
+ # volumes:
64
+ # - ./Caddyfile:/etc/caddy/Caddyfile
65
+ # - caddy_data:/data
66
+ # - caddy_config:/config
67
+
68
+ # volumes:
69
+ # caddy_data:
70
+ # caddy_config:
71
+ # hedgedoc_uploads:
72
+ # hedgedoc_db_data:
package/package.json CHANGED
@@ -1,10 +1,25 @@
1
1
  {
2
2
  "name": "@bryti/agent",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Your AI colleague, in the apps you already use.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "private": false,
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/larsderidder/bryti"
11
+ },
12
+ "main": "dist/index.js",
13
+ "bin": {
14
+ "bryti": "dist/cli.js"
15
+ },
16
+ "files": [
17
+ "dist/",
18
+ "config.example.yml",
19
+ "run.sh",
20
+ "Dockerfile",
21
+ "docker-compose.yml"
22
+ ],
8
23
  "scripts": {
9
24
  "build": "tsc && cp -r defaults dist/",
10
25
  "dev": "tsc --watch",
package/run.sh ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ cd "$(dirname "$0")"
5
+
6
+ RESTART_DELAY_SECONDS="${RESTART_DELAY_SECONDS:-2}"
7
+
8
+ while true; do
9
+ echo "Building TypeScript..."
10
+ npm run build
11
+
12
+ exit_code=0
13
+ node --env-file=.env dist/index.js || exit_code=$?
14
+
15
+ if [ "$exit_code" -eq 0 ]; then
16
+ echo "Bryti stopped cleanly."
17
+ exit 0
18
+ fi
19
+
20
+ if [ "$exit_code" -eq 42 ]; then
21
+ echo "Bryti restart requested. Rebuilding and restarting..."
22
+ continue
23
+ fi
24
+
25
+ echo "Bryti crashed (exit code $exit_code). Restarting in ${RESTART_DELAY_SECONDS}s..."
26
+ sleep "$RESTART_DELAY_SECONDS"
27
+ done