@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.
- package/Dockerfile +27 -0
- package/README.md +77 -50
- package/config.example.yml +265 -0
- package/dist/active-hours.d.ts +23 -0
- package/dist/active-hours.d.ts.map +1 -0
- package/dist/active-hours.js +68 -0
- package/dist/active-hours.js.map +1 -0
- package/dist/agent.d.ts +84 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +383 -0
- package/dist/agent.js.map +1 -0
- package/dist/channels/markdown/ir.d.ts +79 -0
- package/dist/channels/markdown/ir.d.ts.map +1 -0
- package/dist/channels/markdown/ir.js +824 -0
- package/dist/channels/markdown/ir.js.map +1 -0
- package/dist/channels/markdown/render.d.ts +35 -0
- package/dist/channels/markdown/render.d.ts.map +1 -0
- package/dist/channels/markdown/render.js +178 -0
- package/dist/channels/markdown/render.js.map +1 -0
- package/dist/channels/telegram-network-errors.d.ts +27 -0
- package/dist/channels/telegram-network-errors.d.ts.map +1 -0
- package/dist/channels/telegram-network-errors.js +156 -0
- package/dist/channels/telegram-network-errors.js.map +1 -0
- package/dist/channels/telegram.d.ts +76 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +814 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/types.d.ts +59 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +9 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/channels/whatsapp.d.ts +45 -0
- package/dist/channels/whatsapp.d.ts.map +1 -0
- package/dist/channels/whatsapp.js +310 -0
- package/dist/channels/whatsapp.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +635 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +35 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +113 -0
- package/dist/commands.js.map +1 -0
- package/dist/compaction/history.d.ts +17 -0
- package/dist/compaction/history.d.ts.map +1 -0
- package/dist/compaction/history.js +35 -0
- package/dist/compaction/history.js.map +1 -0
- package/dist/compaction/index.d.ts +3 -0
- package/dist/compaction/index.d.ts.map +1 -0
- package/dist/compaction/index.js +3 -0
- package/dist/compaction/index.js.map +1 -0
- package/dist/compaction/proactive.d.ts +25 -0
- package/dist/compaction/proactive.d.ts.map +1 -0
- package/dist/compaction/proactive.js +87 -0
- package/dist/compaction/proactive.js.map +1 -0
- package/dist/compaction/transcript-repair.d.ts +55 -0
- package/dist/compaction/transcript-repair.d.ts.map +1 -0
- package/dist/compaction/transcript-repair.js +215 -0
- package/dist/compaction/transcript-repair.js.map +1 -0
- package/dist/config.d.ts +128 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +317 -0
- package/dist/config.js.map +1 -0
- package/dist/crash-recovery.d.ts +23 -0
- package/dist/crash-recovery.d.ts.map +1 -0
- package/dist/crash-recovery.js +96 -0
- package/dist/crash-recovery.js.map +1 -0
- package/dist/defaults/extensions/EXTENSIONS.md +158 -0
- package/dist/defaults/extensions/documents-hedgedoc.ts +153 -0
- package/dist/history.d.ts +31 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +49 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +673 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +39 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +143 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory/conversation-search.d.ts +15 -0
- package/dist/memory/conversation-search.d.ts.map +1 -0
- package/dist/memory/conversation-search.js +60 -0
- package/dist/memory/conversation-search.js.map +1 -0
- package/dist/memory/core-memory.d.ts +28 -0
- package/dist/memory/core-memory.d.ts.map +1 -0
- package/dist/memory/core-memory.js +102 -0
- package/dist/memory/core-memory.js.map +1 -0
- package/dist/memory/embeddings.d.ts +44 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +139 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/search.d.ts +49 -0
- package/dist/memory/search.d.ts.map +1 -0
- package/dist/memory/search.js +97 -0
- package/dist/memory/search.js.map +1 -0
- package/dist/memory/store.d.ts +32 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +205 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/message-queue.d.ts +73 -0
- package/dist/message-queue.d.ts.map +1 -0
- package/dist/message-queue.js +188 -0
- package/dist/message-queue.js.map +1 -0
- package/dist/model-infra.d.ts +64 -0
- package/dist/model-infra.d.ts.map +1 -0
- package/dist/model-infra.js +202 -0
- package/dist/model-infra.js.map +1 -0
- package/dist/projection/format.d.ts +10 -0
- package/dist/projection/format.d.ts.map +1 -0
- package/dist/projection/format.js +30 -0
- package/dist/projection/format.js.map +1 -0
- package/dist/projection/index.d.ts +11 -0
- package/dist/projection/index.d.ts.map +1 -0
- package/dist/projection/index.js +9 -0
- package/dist/projection/index.js.map +1 -0
- package/dist/projection/reflection.d.ts +94 -0
- package/dist/projection/reflection.d.ts.map +1 -0
- package/dist/projection/reflection.js +334 -0
- package/dist/projection/reflection.js.map +1 -0
- package/dist/projection/store.d.ts +144 -0
- package/dist/projection/store.d.ts.map +1 -0
- package/dist/projection/store.js +519 -0
- package/dist/projection/store.js.map +1 -0
- package/dist/projection/tools.d.ts +11 -0
- package/dist/projection/tools.d.ts.map +1 -0
- package/dist/projection/tools.js +237 -0
- package/dist/projection/tools.js.map +1 -0
- package/dist/scheduler.d.ts +36 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +286 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/system-prompt.d.ts +41 -0
- package/dist/system-prompt.d.ts.map +1 -0
- package/dist/system-prompt.js +162 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/time.d.ts +52 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +138 -0
- package/dist/time.js.map +1 -0
- package/dist/tools/archival-memory-tool.d.ts +8 -0
- package/dist/tools/archival-memory-tool.d.ts.map +1 -0
- package/dist/tools/archival-memory-tool.js +68 -0
- package/dist/tools/archival-memory-tool.js.map +1 -0
- package/dist/tools/conversation-search-tool.d.ts +6 -0
- package/dist/tools/conversation-search-tool.d.ts.map +1 -0
- package/dist/tools/conversation-search-tool.js +28 -0
- package/dist/tools/conversation-search-tool.js.map +1 -0
- package/dist/tools/core-memory-tool.d.ts +7 -0
- package/dist/tools/core-memory-tool.d.ts.map +1 -0
- package/dist/tools/core-memory-tool.js +59 -0
- package/dist/tools/core-memory-tool.js.map +1 -0
- package/dist/tools/fetch-url.d.ts +15 -0
- package/dist/tools/fetch-url.d.ts.map +1 -0
- package/dist/tools/fetch-url.js +76 -0
- package/dist/tools/fetch-url.js.map +1 -0
- package/dist/tools/files.d.ts +10 -0
- package/dist/tools/files.d.ts.map +1 -0
- package/dist/tools/files.js +127 -0
- package/dist/tools/files.js.map +1 -0
- package/dist/tools/index.d.ts +17 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +118 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/result.d.ts +21 -0
- package/dist/tools/result.d.ts.map +1 -0
- package/dist/tools/result.js +36 -0
- package/dist/tools/result.js.map +1 -0
- package/dist/tools/skill-install.d.ts +17 -0
- package/dist/tools/skill-install.d.ts.map +1 -0
- package/dist/tools/skill-install.js +148 -0
- package/dist/tools/skill-install.js.map +1 -0
- package/dist/tools/web-search.d.ts +42 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +237 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/trust/guardrail.d.ts +60 -0
- package/dist/trust/guardrail.d.ts.map +1 -0
- package/dist/trust/guardrail.js +171 -0
- package/dist/trust/guardrail.js.map +1 -0
- package/dist/trust/index.d.ts +12 -0
- package/dist/trust/index.d.ts.map +1 -0
- package/dist/trust/index.js +12 -0
- package/dist/trust/index.js.map +1 -0
- package/dist/trust/store.d.ts +118 -0
- package/dist/trust/store.d.ts.map +1 -0
- package/dist/trust/store.js +209 -0
- package/dist/trust/store.js.map +1 -0
- package/dist/trust/wrapper.d.ts +36 -0
- package/dist/trust/wrapper.d.ts.map +1 -0
- package/dist/trust/wrapper.js +142 -0
- package/dist/trust/wrapper.js.map +1 -0
- package/dist/usage.d.ts +53 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +124 -0
- package/dist/usage.js.map +1 -0
- package/dist/util/math.d.ts +9 -0
- package/dist/util/math.d.ts.map +1 -0
- package/dist/util/math.js +22 -0
- package/dist/util/math.js.map +1 -0
- package/dist/util/ssrf.d.ts +21 -0
- package/dist/util/ssrf.d.ts.map +1 -0
- package/dist/util/ssrf.js +77 -0
- package/dist/util/ssrf.js.map +1 -0
- package/dist/workers/index.d.ts +8 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +7 -0
- package/dist/workers/index.js.map +1 -0
- package/dist/workers/registry.d.ts +53 -0
- package/dist/workers/registry.d.ts.map +1 -0
- package/dist/workers/registry.js +38 -0
- package/dist/workers/registry.js.map +1 -0
- package/dist/workers/scoped-tools.d.ts +21 -0
- package/dist/workers/scoped-tools.d.ts.map +1 -0
- package/dist/workers/scoped-tools.js +111 -0
- package/dist/workers/scoped-tools.js.map +1 -0
- package/dist/workers/spawn.d.ts +62 -0
- package/dist/workers/spawn.d.ts.map +1 -0
- package/dist/workers/spawn.js +314 -0
- package/dist/workers/spawn.js.map +1 -0
- package/dist/workers/tools.d.ts +26 -0
- package/dist/workers/tools.d.ts.map +1 -0
- package/dist/workers/tools.js +380 -0
- package/dist/workers/tools.js.map +1 -0
- package/docker-compose.yml +72 -0
- package/package.json +16 -1
- 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
|
|
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
|