@clawos-dev/clawd 0.2.191 → 0.2.192-beta.386.33a5833

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.
@@ -39549,6 +39549,8 @@ async function handlePersonaDispatchToolCall(input, ctx) {
39549
39549
  log("personaDispatch tool entered", {
39550
39550
  targetPersona: input.targetPersona,
39551
39551
  promptLen: input.prompt.length,
39552
+ hasTargetSessionId: Boolean(input.targetSessionId),
39553
+ hasTargetDeviceId: Boolean(input.targetDeviceId),
39552
39554
  sessionId: ctx.sessionId,
39553
39555
  daemonUrl: ctx.daemonUrl
39554
39556
  });
@@ -39578,7 +39580,9 @@ async function handlePersonaDispatchToolCall(input, ctx) {
39578
39580
  targetPersona: input.targetPersona,
39579
39581
  prompt: input.prompt,
39580
39582
  // 跨设备:非空时透传,daemon run handler 据此走 A 角色转发分支。
39581
- ...input.targetDeviceId ? { targetDeviceId: input.targetDeviceId } : {}
39583
+ ...input.targetDeviceId ? { targetDeviceId: input.targetDeviceId } : {},
39584
+ // 精确寻址:非空时透传,daemon 校验权限并走 resumeDispatchedSession 路径。
39585
+ ...input.targetSessionId ? { targetSessionId: input.targetSessionId } : {}
39582
39586
  })
39583
39587
  });
39584
39588
  } catch (err) {
@@ -39607,10 +39611,19 @@ async function handlePersonaDispatchToolCall(input, ctx) {
39607
39611
  };
39608
39612
  }
39609
39613
  const outcome = json.result.outcome;
39610
- log("personaDispatch resolved", { outcomeKind: outcome.kind });
39614
+ const dispatchedSessionId = json.result.dispatchedSessionId;
39615
+ log("personaDispatch resolved", {
39616
+ outcomeKind: outcome.kind,
39617
+ dispatchedSessionId
39618
+ });
39619
+ const idTail = `
39620
+
39621
+ (dispatchedSessionId: ${dispatchedSessionId} \u2014 pass this as targetSessionId in a follow-up call to reuse this same B session.)`;
39611
39622
  if (outcome.kind === "failure") {
39612
39623
  return {
39613
- content: [{ type: "text", text: `Dispatch failed: ${outcome.reason}` }],
39624
+ content: [
39625
+ { type: "text", text: `Dispatch failed: ${outcome.reason}${idTail}` }
39626
+ ],
39614
39627
  isError: true
39615
39628
  };
39616
39629
  }
@@ -39619,7 +39632,7 @@ async function handlePersonaDispatchToolCall(input, ctx) {
39619
39632
  Related files:
39620
39633
  ${outcome.filePaths.map((p) => `- ${p}`).join("\n")}` : "";
39621
39634
  return {
39622
- content: [{ type: "text", text: `${outcome.text}${paths}` }]
39635
+ content: [{ type: "text", text: `${outcome.text}${paths}${idTail}` }]
39623
39636
  };
39624
39637
  }
39625
39638
  async function handlePersonaDispatchCompleteToolCall(input, ctx) {
@@ -39628,16 +39641,16 @@ async function handlePersonaDispatchCompleteToolCall(input, ctx) {
39628
39641
  isFailure: Boolean(input.isFailure),
39629
39642
  textLen: input.text?.length ?? 0,
39630
39643
  filePathCount: input.filePaths?.length ?? 0,
39631
- dispatchId: ctx.dispatchId,
39644
+ sessionId: ctx.sessionId,
39632
39645
  daemonUrl: ctx.daemonUrl
39633
39646
  });
39634
- if (!ctx.dispatchId) {
39635
- log("personaDispatchComplete CLAWD_DISPATCH_ID missing");
39647
+ if (!ctx.sessionId) {
39648
+ log("personaDispatchComplete CLAWD_SESSION_ID missing");
39636
39649
  return {
39637
39650
  content: [
39638
39651
  {
39639
39652
  type: "text",
39640
- text: "Error: CLAWD_DISPATCH_ID env not set; this session was not dispatched."
39653
+ text: "Error: CLAWD_SESSION_ID env not set; daemon cannot resolve in-flight dispatch without sessionId."
39641
39654
  }
39642
39655
  ],
39643
39656
  isError: true
@@ -39652,14 +39665,15 @@ async function handlePersonaDispatchCompleteToolCall(input, ctx) {
39652
39665
  filePaths: input.filePaths
39653
39666
  };
39654
39667
  const url = `${ctx.daemonUrl}/api/rpc/personaDispatch.complete`;
39655
- log("personaDispatchComplete pre-fetch", { url, hasSessionId: Boolean(ctx.sessionId) });
39656
- const headers = { "content-type": "application/json" };
39657
- if (ctx.sessionId) headers["x-clawd-session-id"] = ctx.sessionId;
39668
+ log("personaDispatchComplete pre-fetch", { url, sessionId: ctx.sessionId });
39658
39669
  try {
39659
39670
  const res = await f(url, {
39660
39671
  method: "POST",
39661
- headers,
39662
- body: JSON.stringify({ dispatchId: ctx.dispatchId, outcome })
39672
+ headers: {
39673
+ "content-type": "application/json",
39674
+ "x-clawd-session-id": ctx.sessionId
39675
+ },
39676
+ body: JSON.stringify({ outcome })
39663
39677
  });
39664
39678
  log("personaDispatchComplete post-fetch", { url, status: res.status });
39665
39679
  } catch (err) {
@@ -39683,12 +39697,10 @@ async function handlePersonaDispatchCompleteToolCall(input, ctx) {
39683
39697
  async function main() {
39684
39698
  const daemonUrl = process.env.CLAWD_DAEMON_URL;
39685
39699
  const sessionId = process.env.CLAWD_SESSION_ID;
39686
- const dispatchId = process.env.CLAWD_DISPATCH_ID;
39687
39700
  log("boot", {
39688
39701
  pid: process.pid,
39689
39702
  hasDaemonUrl: Boolean(daemonUrl),
39690
39703
  hasSessionId: Boolean(sessionId),
39691
- hasDispatchId: Boolean(dispatchId),
39692
39704
  logPath: DISPATCH_LOG ?? "(stderr)"
39693
39705
  });
39694
39706
  if (!daemonUrl) {
@@ -39705,7 +39717,7 @@ async function main() {
39705
39717
  "personaDispatch",
39706
39718
  {
39707
39719
  title: "Dispatch task to another persona",
39708
- description: "Delegate a task to another clawd persona. Use this when the user message contains `@persona/<id>` to hand the task off to that persona. The tool blocks until the other persona finishes and returns its result.",
39720
+ description: "Delegate a task to another clawd persona. Use this when the user message contains `@persona/<id>` to hand the task off to that persona. The tool blocks until the other persona finishes and returns its result. To reuse the same B session (continue an earlier task), pass its dispatchedSessionId (from a previous call's output tail) as targetSessionId \u2014 cross-device continuation additionally requires the original targetDeviceId. Omit targetSessionId to spawn a fresh B session.",
39709
39721
  inputSchema: {
39710
39722
  targetPersona: external_exports.string().describe("persona id (e.g. persona-app-builder)"),
39711
39723
  prompt: external_exports.string().describe(
@@ -39713,6 +39725,9 @@ async function main() {
39713
39725
  ),
39714
39726
  targetDeviceId: external_exports.string().optional().describe(
39715
39727
  "contact deviceId of the remote device when delegating cross-device (omit for a local persona)"
39728
+ ),
39729
+ targetSessionId: external_exports.string().optional().describe(
39730
+ "existing B session id to reuse (from a previous dispatchedSessionId). Omit to spawn a fresh B session."
39716
39731
  )
39717
39732
  }
39718
39733
  },
@@ -39731,8 +39746,8 @@ async function main() {
39731
39746
  }
39732
39747
  },
39733
39748
  // sessionId 透传:complete RPC 必须带 x-clawd-session-id header(rpc-adapter 强制)。
39734
- // B session cc env CLAWD_SESSION_ID = BsessionId
39735
- async (input) => handlePersonaDispatchCompleteToolCall(input, { daemonUrl, sessionId, dispatchId })
39749
+ // daemon 用该 sessionId 反查 PersonaDispatchManager 里该 B in-flight dispatchId 配对回 A waiter
39750
+ async (input) => handlePersonaDispatchCompleteToolCall(input, { daemonUrl, sessionId })
39736
39751
  );
39737
39752
  await server.connect(new StdioServerTransport());
39738
39753
  }