@adhdev/daemon-standalone 1.0.28-rc.17 → 1.0.28-rc.19

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/public/index.html CHANGED
@@ -7,7 +7,7 @@
7
7
  <meta name="description" content="ADHDev self-hosted dashboard for controlling AI agents" />
8
8
  <link rel="icon" href="/otter-logo.png" />
9
9
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
10
- <script type="module" crossorigin src="/assets/index-BaD_sbu-.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-CWWODSEE.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-cL4V2vaO.js">
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-8TNNoifN.css">
13
13
  </head>
@@ -304,6 +304,33 @@ function dedupeSummaryFromTail(messages, summary) {
304
304
  return { ...rest, content: "", _sameAsSummary: true };
305
305
  });
306
306
  }
307
+ var TURN_IDENTITY_FIELDS = [
308
+ "authority",
309
+ "status",
310
+ "stage",
311
+ "terminalOutcome",
312
+ "terminalReason",
313
+ "meshId",
314
+ "taskId",
315
+ "attemptId",
316
+ "attemptSeq",
317
+ "sessionId",
318
+ "nodeId",
319
+ "providerType",
320
+ "acceptedAt",
321
+ "deliveredAt",
322
+ "consumedAt",
323
+ "terminalAt",
324
+ "updatedAt"
325
+ ];
326
+ function slimTurnPresentation(turn) {
327
+ if (!turn || typeof turn !== "object" || Array.isArray(turn)) return null;
328
+ const slim = {};
329
+ for (const key of TURN_IDENTITY_FIELDS) {
330
+ if (turn[key] !== void 0) slim[key] = turn[key];
331
+ }
332
+ return Object.keys(slim).length > 0 ? slim : null;
333
+ }
307
334
  function compactChatPayload(payload, opts = {}) {
308
335
  const rawMessages = Array.isArray(payload?.messages) ? payload.messages : [];
309
336
  const visible = rawMessages.filter(isCoordinatorVisibleMessage);
@@ -320,6 +347,7 @@ function compactChatPayload(payload, opts = {}) {
320
347
  const toolSummaries = rawMessages.filter((m) => !isCoordinatorVisibleMessage(m)).map(summarizeToolMessage).filter((s) => s !== null);
321
348
  const omittedMessages = Math.max(0, rawMessages.length - messages.length);
322
349
  const filteredMessages = Math.max(0, rawMessages.length - visible.length);
350
+ const slimTurn = opts.preserveTurn ? slimTurnPresentation(payload?.turn) : null;
323
351
  return {
324
352
  success: payload?.success !== false,
325
353
  compact: true,
@@ -327,6 +355,9 @@ function compactChatPayload(payload, opts = {}) {
327
355
  ...opts.sessionId !== void 0 ? { sessionId: opts.sessionId } : {},
328
356
  status: payload?.status ?? null,
329
357
  providerSessionId: payload?.providerSessionId ?? null,
358
+ ...slimTurn ? { turn: slimTurn } : {},
359
+ ...slimTurn?.attemptId !== void 0 ? { attemptId: slimTurn.attemptId } : {},
360
+ ...slimTurn?.stage !== void 0 ? { turnStage: slimTurn.stage } : {},
330
361
  totalMessages: rawMessages.length,
331
362
  visibleMessages: visible.length,
332
363
  filteredMessages,
@@ -3585,6 +3616,11 @@ async function meshStatus(ctx, args = {}) {
3585
3616
  status: s.status ?? s.lifecycle ?? s.state,
3586
3617
  providerType: s.providerType ?? s.cliType ?? s.type,
3587
3618
  ...s.activeChat?.status ? { chatStatus: s.activeChat.status } : {},
3619
+ // Stage 6: attempt identity + causal stage from the unified turn
3620
+ // projection (present on mesh-owned sessions only), so mesh_status
3621
+ // reports the SAME attemptId/stage as read_chat and the dashboard.
3622
+ ...s.turn?.attemptId ? { attemptId: s.turn.attemptId } : {},
3623
+ ...s.turn?.stage ? { turnStage: s.turn.stage } : {},
3588
3624
  ...isSelfCoordinator ? { isSelfCoordinator: true, role: "coordinator" } : {},
3589
3625
  // [T2] Carry the worker-computed last-message preview through the slim so
3590
3626
  // the coordinator's inbox can show the worker's latest ASSISTANT reply
@@ -6679,30 +6715,29 @@ async function meshSendTask(ctx, args) {
6679
6715
  }
6680
6716
  if (explicitTargetSession && !isIdleSessionRecord(explicitTargetSession) && !isTerminalSessionRecord(explicitTargetSession)) {
6681
6717
  const sessionStatus = typeof explicitTargetSession?.status === "string" ? explicitTargetSession.status : "unknown";
6682
- const { createSessionDelivery: createDelivery, resolveDeliveryDecision } = await import("@adhdev/daemon-core");
6718
+ const { resolveDeliveryDecision } = await import("@adhdev/daemon-core");
6683
6719
  const policyResult = resolveDeliveryDecision(sessionStatus, { kind: "task" });
6684
6720
  if (policyResult.decision === "queued") {
6685
- const delivery = createDelivery({
6686
- meshId: ctx.mesh.id,
6687
- nodeId: args.node_id,
6688
- sessionId: args.session_id,
6689
- providerType: resolvedProviderType,
6690
- kind: "task",
6691
- message,
6692
- status: "queued"
6721
+ const queuedTask = (0, import_daemon_core4.enqueueTask)(ctx.mesh.id, message, {
6722
+ targetNodeId: args.node_id,
6723
+ targetSessionId: args.session_id,
6724
+ taskMode,
6725
+ ...readonly ? { readonly: true } : {},
6726
+ ...missionId ? { missionId } : {},
6727
+ ...ctx.coordinatorSessionId ? { sourceCoordinatorSessionId: ctx.coordinatorSessionId } : {}
6693
6728
  });
6694
6729
  return JSON.stringify({
6695
6730
  success: true,
6696
6731
  dispatched: false,
6697
6732
  decision: "queued_delivery",
6698
- deliveryId: delivery.id,
6733
+ taskId: queuedTask.id,
6699
6734
  reason: policyResult.reason,
6700
6735
  nodeId: args.node_id,
6701
6736
  sessionId: args.session_id,
6702
6737
  sessionStatus,
6703
6738
  taskMode: taskMode || void 0,
6704
6739
  message: policyResult.message,
6705
- nextAction: `Use mesh_status to watch for session idle transition, or use mesh_enqueue_task for queue-based assignment. Check deliveryId '${delivery.id}' to track queued delivery.`
6740
+ nextAction: `Task '${queuedTask.id}' is queued and pinned to session '${args.session_id}' \u2014 it auto-delivers the moment the session goes idle. Use mesh_status or mesh_task_history to track it; no manual resend needed.`
6706
6741
  });
6707
6742
  }
6708
6743
  }
@@ -6894,7 +6929,11 @@ async function meshReadChat(ctx, args) {
6894
6929
  const compactPayload = compactChatPayload(payload, {
6895
6930
  nodeId: args.node_id,
6896
6931
  sessionId: args.session_id,
6897
- limit: args.tail ?? 10
6932
+ limit: args.tail ?? 10,
6933
+ // Carry the daemon's Stage 6 turn projection (attemptId/turnStage/
6934
+ // authority/terminal outcome) so the slim response stays at parity
6935
+ // with daemon read_chat and mesh_status. Non-content scalars only.
6936
+ preserveTurn: true
6898
6937
  });
6899
6938
  return JSON.stringify(
6900
6939
  payload.pollingAdvisory ? { ...compactPayload, pollingAdvisory: payload.pollingAdvisory } : compactPayload,
@@ -7931,7 +7970,7 @@ function formatChatResult(result, sessionId, format, limit = 50, compact = false
7931
7970
  }
7932
7971
  const messages = result?.messages ?? result?.data?.messages ?? [];
7933
7972
  const source = { ...result, messages };
7934
- const compactPayload = compact ? compactChatPayload(source, { sessionId: sessionId ?? null, limit }) : null;
7973
+ const compactPayload = compact ? compactChatPayload(source, { sessionId: sessionId ?? null, limit, preserveTurn: true }) : null;
7935
7974
  const outputMessages = compact ? compactPayload.messages : messages;
7936
7975
  if (format === "json") {
7937
7976
  if (compact && compactPayload) {
@@ -8664,13 +8703,13 @@ ${raw.output}` : "";
8664
8703
  // src/tools/launch-session.ts
8665
8704
  var LAUNCH_SESSION_TOOL = {
8666
8705
  name: "launch_session",
8667
- description: "Launch a new agent session on the daemon. Supports CLI agents (e.g. hermes-cli, claude-cli, gemini-cli), ACP agents (e.g. claude-acp), and IDEs (e.g. cursor, vscode).",
8706
+ description: "Launch a new agent session on the daemon. Supports CLI agents (e.g. kimi, hermes-cli, claude-cli, gemini-cli), ACP agents (e.g. claude-acp), and IDEs (e.g. cursor, vscode).",
8668
8707
  inputSchema: {
8669
8708
  type: "object",
8670
8709
  properties: {
8671
8710
  type: {
8672
8711
  type: "string",
8673
- description: "Provider type to launch. CLI examples: hermes-cli, claude-cli, gemini-cli. ACP examples: claude-acp. IDE examples: cursor, vscode."
8712
+ description: "Provider type to launch. CLI examples: kimi, hermes-cli, claude-cli, gemini-cli. ACP examples: claude-acp. IDE examples: cursor, vscode. Manifest aliases (e.g. codex \u2192 codex-cli) resolve to the canonical provider type."
8674
8713
  },
8675
8714
  workspace: {
8676
8715
  type: "string",
@@ -8684,14 +8723,48 @@ var LAUNCH_SESSION_TOOL = {
8684
8723
  required: ["type"]
8685
8724
  }
8686
8725
  };
8726
+ function legacyHeuristicRoute(type) {
8727
+ const isCliOrAcp = type.includes("-cli") || type.includes("-acp") || type === "codex";
8728
+ return { route: isCliOrAcp ? "cli" : "ide", canonicalType: type };
8729
+ }
8730
+ async function resolveProviderRoute(transport, requestedType) {
8731
+ const type = requestedType.trim();
8732
+ if (!type) return { error: "type is required" };
8733
+ let catalog;
8734
+ try {
8735
+ catalog = await transport.command("list_provider_availability", {});
8736
+ } catch {
8737
+ catalog = null;
8738
+ }
8739
+ const providers = Array.isArray(catalog?.providers) ? catalog.providers : null;
8740
+ if (!catalog || catalog.success === false || !providers) {
8741
+ return legacyHeuristicRoute(type);
8742
+ }
8743
+ const query = type.toLowerCase();
8744
+ const hit = providers.find((p) => {
8745
+ if (!p || typeof p.type !== "string") return false;
8746
+ if (p.type.toLowerCase() === query) return true;
8747
+ const aliases = Array.isArray(p.aliases) ? p.aliases : [];
8748
+ return aliases.some((alias) => typeof alias === "string" && alias.toLowerCase() === query);
8749
+ });
8750
+ if (!hit) {
8751
+ const known = providers.map((p) => p && typeof p.type === "string" ? p.type : null).filter(Boolean).sort();
8752
+ return {
8753
+ error: `Unknown provider type '${type}'. Known provider types: ${known.join(", ")}`
8754
+ };
8755
+ }
8756
+ const route = hit.category === "cli" || hit.category === "acp" ? "cli" : "ide";
8757
+ return { route, canonicalType: hit.type };
8758
+ }
8687
8759
  async function launchSession(transport, args) {
8688
- const isCliOrAcp = args.type.includes("-cli") || args.type.includes("-acp") || args.type === "codex";
8689
- const commandType = isCliOrAcp ? "launch_cli" : "launch_ide";
8690
- const payload = isCliOrAcp ? { cliType: args.type, dir: args.workspace ?? "~", ...args.model ? { model: args.model } : {} } : { ideType: args.type, enableCdp: true };
8760
+ const resolved = await resolveProviderRoute(transport, args.type);
8761
+ if ("error" in resolved) return `Error: ${resolved.error}`;
8762
+ const commandType = resolved.route === "cli" ? "launch_cli" : "launch_ide";
8763
+ const payload = resolved.route === "cli" ? { cliType: resolved.canonicalType, dir: args.workspace ?? "~", ...args.model ? { model: args.model } : {} } : { ideType: resolved.canonicalType, enableCdp: true };
8691
8764
  const result = await transport.command(commandType, payload);
8692
8765
  if (result?.success === false) return `Error: ${result.error ?? "launch failed"}`;
8693
8766
  const id = result?.id ?? result?.sessionId;
8694
- return id ? `Session launched. id: ${id}, type: ${args.type}` : `Launched: ${JSON.stringify(result)}`;
8767
+ return id ? `Session launched. id: ${id}, type: ${resolved.canonicalType}` : `Launched: ${JSON.stringify(result)}`;
8695
8768
  }
8696
8769
 
8697
8770
  // src/tools/stop-session.ts