@slock-ai/daemon 0.40.2 → 0.41.1-alpha.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.
@@ -336,12 +336,14 @@ var agentId = "";
336
336
  var serverUrl = "http://localhost:3001";
337
337
  var authToken = "";
338
338
  var runtime = "unknown";
339
+ var launchId = "";
339
340
  var deprecatedShimMode = false;
340
341
  for (let i = 0; i < args.length; i++) {
341
342
  if (args[i] === "--agent-id" && args[i + 1]) agentId = args[++i];
342
343
  if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
343
344
  if (args[i] === "--auth-token" && args[i + 1]) authToken = args[++i];
344
345
  if (args[i] === "--runtime" && args[i + 1]) runtime = args[++i];
346
+ if (args[i] === "--launch-id" && args[i + 1]) launchId = args[++i];
345
347
  if (args[i] === "--deprecated-shim") deprecatedShimMode = true;
346
348
  }
347
349
  if (!agentId) {
@@ -349,6 +351,10 @@ if (!agentId) {
349
351
  process.exit(1);
350
352
  }
351
353
  var commonHeaders = buildChatBridgeCommonHeaders(authToken);
354
+ var runtimeActionHeaders = {
355
+ ...commonHeaders,
356
+ ...launchId ? { "X-Agent-Launch-Id": launchId } : {}
357
+ };
352
358
  function bridgeFetch(url, init = {}) {
353
359
  const dispatcher = buildFetchDispatcher(url, process.env);
354
360
  const requestInit = dispatcher ? { ...init, dispatcher } : init;
@@ -496,6 +502,38 @@ function formatSenderHandle(message) {
496
502
  const senderDescription = message.sender_description ?? message.senderDescription ?? null;
497
503
  return senderDescription ? `@${senderName} \u2014 ${senderDescription}` : `@${senderName}`;
498
504
  }
505
+ async function listServerChannels() {
506
+ const { response: res, data } = await executeJsonRequest(
507
+ `${serverUrl}/internal/agent/${agentId}/server`,
508
+ { method: "GET", headers: commonHeaders },
509
+ {
510
+ toolName: "list_server.channels",
511
+ fetchImpl: bridgeFetch
512
+ }
513
+ );
514
+ if (!res.ok) {
515
+ throw new Error("Failed to load server channels");
516
+ }
517
+ return data.channels ?? [];
518
+ }
519
+ function parseRegularChannelTarget(target) {
520
+ if (!target.startsWith("#")) return null;
521
+ if (target.includes(":")) return null;
522
+ const name = target.slice(1).trim();
523
+ return name.length > 0 ? name : null;
524
+ }
525
+ async function resolveRegularChannelTarget(target) {
526
+ const channelName = parseRegularChannelTarget(target);
527
+ if (!channelName) {
528
+ throw new Error("Target must be a regular channel in the form '#channel-name'");
529
+ }
530
+ const channels = await listServerChannels();
531
+ const channel = channels.find((candidate) => candidate.name === channelName);
532
+ if (!channel) {
533
+ throw new Error(`Channel not found: ${target}`);
534
+ }
535
+ return channel;
536
+ }
499
537
  var server = new McpServer({
500
538
  name: "chat",
501
539
  version: "1.0.0"
@@ -524,6 +562,51 @@ if (deprecatedShimMode) {
524
562
  registerDeprecatedTool(tool);
525
563
  }
526
564
  }
565
+ var RUNTIME_PROFILE_MIGRATION_DONE_TOOL_NAME = "runtime_profile_migration_done";
566
+ server.tool(
567
+ RUNTIME_PROFILE_MIGRATION_DONE_TOOL_NAME,
568
+ "Complete the current Runtime Profile migration. This one-shot runtime control action is only valid while the agent is migrating and must use the migration_key from the private migration hint.",
569
+ {
570
+ migration_key: z2.string().describe("The migration key from the Runtime Profile migration hint")
571
+ },
572
+ async ({ migration_key }) => {
573
+ const key = migration_key.trim();
574
+ if (!key) {
575
+ return {
576
+ isError: true,
577
+ content: [{ type: "text", text: "Error: migration_key is required" }]
578
+ };
579
+ }
580
+ try {
581
+ const { response: res, data } = await executeJsonRequest(
582
+ `${serverUrl}/internal/agent/${agentId}/runtime-profile/migration-done`,
583
+ {
584
+ method: "POST",
585
+ headers: runtimeActionHeaders,
586
+ body: JSON.stringify({ migrationKey: key })
587
+ },
588
+ {
589
+ toolName: RUNTIME_PROFILE_MIGRATION_DONE_TOOL_NAME,
590
+ fetchImpl: bridgeFetch
591
+ }
592
+ );
593
+ if (!res.ok) {
594
+ return {
595
+ isError: true,
596
+ content: [{ type: "text", text: `Error: ${data.error || "Runtime Profile migration is not active"}` }]
597
+ };
598
+ }
599
+ return {
600
+ content: [{ type: "text", text: "Runtime Profile migration completed. Normal inbox delivery can resume." }]
601
+ };
602
+ } catch (err) {
603
+ return {
604
+ isError: true,
605
+ content: [{ type: "text", text: `Error: ${err.message}` }]
606
+ };
607
+ }
608
+ }
609
+ );
527
610
  if (!deprecatedShimMode) {
528
611
  let formatMessages = function(messages) {
529
612
  return messages.map((m) => {
@@ -805,7 +888,7 @@ Use this ID in send_message's attachment_ids parameter to include it in a messag
805
888
  const agents = data.agents ?? [];
806
889
  const humans = data.humans ?? [];
807
890
  text += "### Channels\n";
808
- text += 'Visible public channels may appear even when `joined=false`. Use `read_history(channel="#name")` to inspect them. When a channel is not joined, you cannot send messages there or receive ordinary channel delivery until a human adds you to the channel.\n';
891
+ text += 'Visible public channels may appear even when `joined=false`. Use `read_history(channel="#name")` to inspect them. 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';
809
892
  if (channels.length > 0) {
810
893
  for (const t of channels) {
811
894
  const status = t.joined ? "joined" : "not joined";
@@ -849,6 +932,49 @@ Use this ID in send_message's attachment_ids parameter to include it in a messag
849
932
  }
850
933
  }
851
934
  );
935
+ server.tool(
936
+ "leave_channel",
937
+ "Leave a regular channel you have joined. This only affects your own agent membership; it does not require admin privileges. After leaving, you can still inspect visible public channel history, but you will stop receiving ordinary channel delivery and cannot send until a human adds you again.",
938
+ {
939
+ target: z2.string().describe("Regular channel to leave, in the form '#channel-name'. DMs and thread targets are not supported.")
940
+ },
941
+ async ({ target }) => {
942
+ try {
943
+ const channel = await resolveRegularChannelTarget(target);
944
+ if (!channel.joined) {
945
+ return {
946
+ content: [{ type: "text", text: `Already not joined in ${target}.` }]
947
+ };
948
+ }
949
+ const { response: res, data } = await executeJsonRequest(
950
+ `${serverUrl}/internal/agent/${agentId}/channels/${channel.id}/leave`,
951
+ {
952
+ method: "POST",
953
+ headers: commonHeaders
954
+ },
955
+ {
956
+ toolName: "leave_channel",
957
+ target,
958
+ fetchImpl: bridgeFetch
959
+ }
960
+ );
961
+ if (!res.ok) {
962
+ return {
963
+ isError: true,
964
+ content: [{ type: "text", text: `Error: ${data.error || `Failed to leave ${target}`}` }]
965
+ };
966
+ }
967
+ return {
968
+ content: [{ type: "text", text: `Left ${target}. You can still inspect visible public channel history there, but you can no longer send or receive ordinary channel delivery until a human adds you again.` }]
969
+ };
970
+ } catch (err) {
971
+ return {
972
+ isError: true,
973
+ content: [{ type: "text", text: `Error: ${err.message}` }]
974
+ };
975
+ }
976
+ }
977
+ );
852
978
  server.tool(
853
979
  "search_messages",
854
980
  "Search messages visible to the agent. Use this to find relevant conversations, then inspect a hit with read_history(channel=..., around=messageId).",