@slock-ai/daemon 0.44.2 → 0.46.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/dist/chat-bridge.js +21 -104
- package/dist/{chunk-NM2MFLQ7.js → chunk-Q4XUZB34.js} +1707 -267
- package/dist/{chunk-JG7ONJZ6.js → chunk-Z3PCMYZO.js} +101 -1
- package/dist/cli/index.js +65 -14
- package/dist/core.js +2 -2
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/dist/chat-bridge.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
|
|
3
4
|
buildFetchDispatcher,
|
|
5
|
+
executeJsonRequest,
|
|
6
|
+
executeResponseRequest,
|
|
4
7
|
logger
|
|
5
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Z3PCMYZO.js";
|
|
6
9
|
|
|
7
10
|
// src/chat-bridge.ts
|
|
8
11
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -164,103 +167,6 @@ function formatHistoryMessageLine(message) {
|
|
|
164
167
|
return `[${headerParts.join(" ")}] ${formatHistorySenderHandle(message)}: ${message.content}${attachSuffix}${taskSuffix}`;
|
|
165
168
|
}
|
|
166
169
|
|
|
167
|
-
// src/chatBridgeRequest.ts
|
|
168
|
-
var DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS = Number.parseInt(
|
|
169
|
-
process.env.SLOCK_CHAT_BRIDGE_TOOL_TIMEOUT_MS || "",
|
|
170
|
-
10
|
|
171
|
-
) || 6e4;
|
|
172
|
-
var ChatBridgeToolTimeoutError = class extends Error {
|
|
173
|
-
toolName;
|
|
174
|
-
target;
|
|
175
|
-
timeoutMs;
|
|
176
|
-
durationMs;
|
|
177
|
-
constructor(toolName, target, timeoutMs, durationMs) {
|
|
178
|
-
super(`${toolName} timed out after ${timeoutMs}ms${target ? ` (target: ${target})` : ""}`);
|
|
179
|
-
this.name = "ChatBridgeToolTimeoutError";
|
|
180
|
-
this.toolName = toolName;
|
|
181
|
-
this.target = target;
|
|
182
|
-
this.timeoutMs = timeoutMs;
|
|
183
|
-
this.durationMs = durationMs;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
function describeError(err) {
|
|
187
|
-
if (err instanceof Error) return `${err.name}: ${err.message}`;
|
|
188
|
-
return String(err);
|
|
189
|
-
}
|
|
190
|
-
async function executeJsonRequest(url, init, {
|
|
191
|
-
toolName,
|
|
192
|
-
target = null,
|
|
193
|
-
timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
|
|
194
|
-
fetchImpl,
|
|
195
|
-
now = () => Date.now(),
|
|
196
|
-
warn = (message) => logger.warn(message)
|
|
197
|
-
}) {
|
|
198
|
-
const startedAt = now();
|
|
199
|
-
const timeoutController = new AbortController();
|
|
200
|
-
const signals = [timeoutController.signal];
|
|
201
|
-
if (init.signal) signals.push(init.signal);
|
|
202
|
-
const signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
|
|
203
|
-
const timeout = setTimeout(() => {
|
|
204
|
-
timeoutController.abort();
|
|
205
|
-
}, timeoutMs);
|
|
206
|
-
timeout.unref?.();
|
|
207
|
-
try {
|
|
208
|
-
const response = await fetchImpl(url, { ...init, signal });
|
|
209
|
-
const data = await response.json();
|
|
210
|
-
return { response, data, durationMs: now() - startedAt };
|
|
211
|
-
} catch (err) {
|
|
212
|
-
const durationMs = now() - startedAt;
|
|
213
|
-
if (timeoutController.signal.aborted && !init.signal?.aborted) {
|
|
214
|
-
warn(
|
|
215
|
-
`[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
|
|
216
|
-
);
|
|
217
|
-
throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
|
|
218
|
-
}
|
|
219
|
-
warn(
|
|
220
|
-
`[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
|
|
221
|
-
);
|
|
222
|
-
throw err;
|
|
223
|
-
} finally {
|
|
224
|
-
clearTimeout(timeout);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
async function executeResponseRequest(url, init, {
|
|
228
|
-
toolName,
|
|
229
|
-
target = null,
|
|
230
|
-
timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
|
|
231
|
-
fetchImpl,
|
|
232
|
-
now = () => Date.now(),
|
|
233
|
-
warn = (message) => logger.warn(message)
|
|
234
|
-
}) {
|
|
235
|
-
const startedAt = now();
|
|
236
|
-
const timeoutController = new AbortController();
|
|
237
|
-
const signals = [timeoutController.signal];
|
|
238
|
-
if (init.signal) signals.push(init.signal);
|
|
239
|
-
const signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
|
|
240
|
-
const timeout = setTimeout(() => {
|
|
241
|
-
timeoutController.abort();
|
|
242
|
-
}, timeoutMs);
|
|
243
|
-
timeout.unref?.();
|
|
244
|
-
try {
|
|
245
|
-
const response = await fetchImpl(url, { ...init, signal });
|
|
246
|
-
return { response, durationMs: now() - startedAt };
|
|
247
|
-
} catch (err) {
|
|
248
|
-
const durationMs = now() - startedAt;
|
|
249
|
-
if (timeoutController.signal.aborted && !init.signal?.aborted) {
|
|
250
|
-
warn(
|
|
251
|
-
`[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
|
|
252
|
-
);
|
|
253
|
-
throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
|
|
254
|
-
}
|
|
255
|
-
warn(
|
|
256
|
-
`[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
|
|
257
|
-
);
|
|
258
|
-
throw err;
|
|
259
|
-
} finally {
|
|
260
|
-
clearTimeout(timeout);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
170
|
// src/chatBridgeSendRequest.ts
|
|
265
171
|
import { randomUUID } from "crypto";
|
|
266
172
|
async function executeRetrySafeSendRequest(url, buildInit, {
|
|
@@ -325,6 +231,8 @@ function buildChatBridgeCommonHeaders(authToken2, { includeContentType = true }
|
|
|
325
231
|
}
|
|
326
232
|
|
|
327
233
|
// src/chat-bridge.ts
|
|
234
|
+
var MAX_UPLOAD_FILE_BYTES = 50 * 1024 * 1024;
|
|
235
|
+
var MAX_UPLOAD_FILE_LABEL = "50MB";
|
|
328
236
|
function toLocalTime(iso) {
|
|
329
237
|
const d = new Date(iso);
|
|
330
238
|
if (isNaN(d.getTime())) return iso;
|
|
@@ -710,7 +618,7 @@ ${formatMessages(unreadToShow)}`;
|
|
|
710
618
|
);
|
|
711
619
|
server.tool(
|
|
712
620
|
"upload_file",
|
|
713
|
-
|
|
621
|
+
`Upload a file to attach to a message. Returns an attachment ID that you can pass to send_message's attachment_ids parameter. Images keep preview behavior; other files are sent as downloadable attachments. Max size: ${MAX_UPLOAD_FILE_LABEL}. Video files are downloadable attachments and are not parsed by agents. Large PDFs may need to be downloaded and inspected in smaller chunks.`,
|
|
714
622
|
{
|
|
715
623
|
file_path: z2.string().describe("Absolute path to the file on your local filesystem"),
|
|
716
624
|
channel: z2.string().describe("The channel target where this file will be used (e.g. '#general', 'dm:@richard')")
|
|
@@ -726,10 +634,16 @@ ${formatMessages(unreadToShow)}`;
|
|
|
726
634
|
};
|
|
727
635
|
}
|
|
728
636
|
const stat = fs.statSync(file_path);
|
|
729
|
-
if (stat.size >
|
|
637
|
+
if (stat.size > MAX_UPLOAD_FILE_BYTES) {
|
|
638
|
+
return {
|
|
639
|
+
isError: true,
|
|
640
|
+
content: [{ type: "text", text: `Error: File too large (${(stat.size / 1024 / 1024).toFixed(1)}MB). Max ${MAX_UPLOAD_FILE_LABEL} per file.` }]
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
if (stat.size === 0) {
|
|
730
644
|
return {
|
|
731
645
|
isError: true,
|
|
732
|
-
content: [{ type: "text", text:
|
|
646
|
+
content: [{ type: "text", text: "Error: File is empty; refusing to upload a 0-byte attachment." }]
|
|
733
647
|
};
|
|
734
648
|
}
|
|
735
649
|
const { response: listRes, data: listData } = await executeJsonRequest(
|
|
@@ -911,10 +825,11 @@ Use this ID in send_message's attachment_ids parameter to include it in a messag
|
|
|
911
825
|
const humans = data.humans ?? [];
|
|
912
826
|
text += formatRuntimeContext(data.runtimeContext);
|
|
913
827
|
text += "### Channels\n";
|
|
914
|
-
text += 'Visible public channels may appear even when `joined=false`. Use `read_history(channel="#name")` to inspect
|
|
828
|
+
text += 'Visible public channels may appear even when `joined=false`. Private channels are shown only when you are a member; do not disclose private-channel names, membership, or content outside that channel. Use `read_history(channel="#name")` to inspect visible channels. When a channel is not joined, you cannot send messages there or receive ordinary channel delivery until a human adds you to the channel. To leave a regular channel you have joined, use `leave_channel(target="#name")`.\n';
|
|
915
829
|
if (channels.length > 0) {
|
|
916
830
|
for (const t of channels) {
|
|
917
|
-
const
|
|
831
|
+
const visibility = t.type === "private" ? "private" : "public";
|
|
832
|
+
const status = `${visibility}, ${t.joined ? "joined" : "not joined"}`;
|
|
918
833
|
text += t.description ? ` - #${t.name} [${status}] \u2014 ${t.description}
|
|
919
834
|
` : ` - #${t.name} [${status}]
|
|
920
835
|
`;
|
|
@@ -1007,9 +922,10 @@ Use this ID in send_message's attachment_ids parameter to include it in a messag
|
|
|
1007
922
|
sender_id: z2.string().optional().describe("Optional exact sender id filter."),
|
|
1008
923
|
after: z2.string().optional().describe("Optional inclusive ISO datetime lower bound for message created_at."),
|
|
1009
924
|
before: z2.string().optional().describe("Optional inclusive ISO datetime upper bound for message created_at."),
|
|
925
|
+
sort: z2.enum(["relevance", "recent"]).optional().describe("Optional result sort. Use 'relevance' for best match first or 'recent' for newest first."),
|
|
1010
926
|
limit: z2.number().default(10).describe("Max number of search results to return (default 10, max 20)")
|
|
1011
927
|
},
|
|
1012
|
-
async ({ query, channel, sender_id, after, before, limit }) => {
|
|
928
|
+
async ({ query, channel, sender_id, after, before, sort, limit }) => {
|
|
1013
929
|
try {
|
|
1014
930
|
const trimmed = query.trim();
|
|
1015
931
|
if (!trimmed) {
|
|
@@ -1024,6 +940,7 @@ Use this ID in send_message's attachment_ids parameter to include it in a messag
|
|
|
1024
940
|
if (sender_id) params.set("senderId", sender_id);
|
|
1025
941
|
if (after) params.set("after", after);
|
|
1026
942
|
if (before) params.set("before", before);
|
|
943
|
+
if (sort) params.set("sort", sort);
|
|
1027
944
|
const { response: res, data } = await executeJsonRequest(
|
|
1028
945
|
`${serverUrl}/internal/agent/${agentId}/search?${params}`,
|
|
1029
946
|
{ method: "GET", headers: commonHeaders },
|