@adhdev/daemon-core 0.9.82-rc.485 → 0.9.82-rc.486

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/index.mjs CHANGED
@@ -140,7 +140,8 @@ var init_repo_mesh_types = __esm({
140
140
  "first_eligible",
141
141
  "least_loaded",
142
142
  "round_robin",
143
- "priority_only"
143
+ "priority_only",
144
+ "fitness"
144
145
  ];
145
146
  DEFAULT_MESH_SCHEDULING_STRATEGY = "first_eligible";
146
147
  MESH_CONVERGE_REFINE_TAG = "converge=refine";
@@ -152,7 +153,11 @@ var init_repo_mesh_types = __esm({
152
153
  allowAutoPublishSubmoduleMainCommits: false,
153
154
  requireApprovalForDestructiveGit: true,
154
155
  dirtyWorkspaceBehavior: "warn",
155
- maxParallelTasks: 2,
156
+ // Mesh-wide task cap is effectively unlimited by default: the real concurrency
157
+ // limits live per node / per capability slot (ORCHESTRATION_NODE_SLOTS.md), so a
158
+ // global ceiling is rarely meaningful. The UI hides this control; set it via the
159
+ // API only to impose a deliberate mesh-wide cap.
160
+ maxParallelTasks: 200,
156
161
  // Coordinator-spawned worker sessions default to hidden so the dashboard is not
157
162
  // flooded with mesh noise tabs/notifications. Users can still surface or unmute
158
163
  // any specific session manually; that override is preserved per-device.
@@ -404,10 +409,10 @@ function readInjected(value) {
404
409
  }
405
410
  function getDaemonBuildInfo() {
406
411
  if (cached) return cached;
407
- const commit = readInjected(true ? "ddf2eb6eafcf949165edfda2c3cf7c77597fa6f8" : void 0) ?? "unknown";
408
- const commitShort = readInjected(true ? "ddf2eb6e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
- const version = readInjected(true ? "0.9.82-rc.485" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
- const builtAt = readInjected(true ? "2026-07-08T15:14:11.978Z" : void 0);
412
+ const commit = readInjected(true ? "cae0f42043ded25e4d3bed93d9f658035c09e007" : void 0) ?? "unknown";
413
+ const commitShort = readInjected(true ? "cae0f420" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
+ const version = readInjected(true ? "0.9.82-rc.486" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
+ const builtAt = readInjected(true ? "2026-07-09T23:19:53.642Z" : void 0);
411
416
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
412
417
  return cached;
413
418
  }
@@ -2792,6 +2797,74 @@ function normalizeDifficultyBrainMap(raw) {
2792
2797
  }
2793
2798
  return out;
2794
2799
  }
2800
+ function normalizeNodeCapabilitySlot(raw) {
2801
+ const r = raw && typeof raw === "object" ? raw : {};
2802
+ const provider = typeof r.provider === "string" ? r.provider.trim() : "";
2803
+ if (!provider) return null;
2804
+ const model = typeof r.model === "string" ? r.model.trim() : "";
2805
+ const thinkingLevel = typeof r.thinkingLevel === "string" ? r.thinkingLevel.trim() : "";
2806
+ const difficulty = Array.isArray(r.difficulty) ? r.difficulty.filter(isMeshTaskDifficulty) : [];
2807
+ const capability = Array.isArray(r.capability) ? r.capability.filter((t) => typeof t === "string" && !!t.trim()).map((t) => t.trim()) : [];
2808
+ const maxParallelNum = Number(r.maxParallel);
2809
+ const maxParallel = Number.isFinite(maxParallelNum) && maxParallelNum > 0 ? Math.floor(maxParallelNum) : void 0;
2810
+ return {
2811
+ provider,
2812
+ ...model ? { model } : {},
2813
+ ...thinkingLevel ? { thinkingLevel } : {},
2814
+ ...difficulty.length ? { difficulty } : {},
2815
+ ...capability.length ? { capability } : {},
2816
+ ...maxParallel !== void 0 ? { maxParallel } : {}
2817
+ };
2818
+ }
2819
+ function normalizeNodeCapabilitySlots(raw) {
2820
+ if (!Array.isArray(raw)) return [];
2821
+ const out = [];
2822
+ for (const entry of raw) {
2823
+ const slot = normalizeNodeCapabilitySlot(entry);
2824
+ if (slot) out.push(slot);
2825
+ }
2826
+ return out;
2827
+ }
2828
+ function deriveSlotsFromLegacy(input) {
2829
+ const priority = Array.isArray(input.providerPriority) ? input.providerPriority.filter((p) => typeof p === "string" && !!p.trim()).map((p) => p.trim()) : [];
2830
+ if (priority.length === 0) return [];
2831
+ const roleCap = /* @__PURE__ */ new Map();
2832
+ for (const role of input.providerRoles || []) {
2833
+ if (role && typeof role.providerType === "string" && Number.isFinite(role.maxParallel)) {
2834
+ roleCap.set(role.providerType.trim(), Math.floor(Number(role.maxParallel)));
2835
+ }
2836
+ }
2837
+ const brains = input.difficultyBrains || {};
2838
+ const byProvider = /* @__PURE__ */ new Map();
2839
+ const shared = [];
2840
+ for (const diff of MESH_TASK_DIFFICULTIES) {
2841
+ const b = brains[diff];
2842
+ if (!b) continue;
2843
+ const entry = { difficulty: diff, model: b.model, thinkingLevel: b.thinkingLevel };
2844
+ if (b.provider) {
2845
+ const list = byProvider.get(b.provider) ?? [];
2846
+ list.push(entry);
2847
+ byProvider.set(b.provider, list);
2848
+ } else {
2849
+ shared.push(entry);
2850
+ }
2851
+ }
2852
+ return priority.map((provider) => {
2853
+ const specific = byProvider.get(provider) || [];
2854
+ const applied = specific.length ? specific : shared;
2855
+ const difficulty = applied.map((a) => a.difficulty);
2856
+ const model = applied.find((a) => a.model)?.model;
2857
+ const thinkingLevel = applied.find((a) => a.thinkingLevel)?.thinkingLevel;
2858
+ const maxParallel = roleCap.get(provider);
2859
+ return {
2860
+ provider,
2861
+ ...model ? { model } : {},
2862
+ ...thinkingLevel ? { thinkingLevel } : {},
2863
+ ...difficulty.length ? { difficulty } : {},
2864
+ ...maxParallel !== void 0 ? { maxParallel } : {}
2865
+ };
2866
+ });
2867
+ }
2795
2868
  var DAEMON_ID_PREFIXES, MAGI_RAW_ANSWER_CAP, MESH_TASK_DIFFICULTIES, DEFAULT_DIFFICULTY_BRAINS, CANONICAL_MESH_TOOL_NAMES, CANONICAL_MESH_TOOL_COUNT;
2796
2869
  var init_dist = __esm({
2797
2870
  "../mesh-shared/dist/index.mjs"() {
@@ -2847,7 +2920,9 @@ var init_dist = __esm({
2847
2920
  "mesh_magi_review",
2848
2921
  "mesh_magi_collect",
2849
2922
  "mesh_magi_kind_panel_set",
2850
- "mesh_magi_kind_panel_list"
2923
+ "mesh_magi_kind_panel_list",
2924
+ "mesh_node_slots_set",
2925
+ "mesh_node_slots_list"
2851
2926
  ];
2852
2927
  CANONICAL_MESH_TOOL_COUNT = CANONICAL_MESH_TOOL_NAMES.length;
2853
2928
  }
@@ -3799,6 +3874,7 @@ function buildRulesSection(coordinatorCliType) {
3799
3874
  - **Reuse idle sessions.** For follow-up, retry, commit/push, or cleanup on the same issue, send only the delta to the existing idle session. Start fresh only for independent work, provider mismatch, transcript contamination, or required worktree isolation.
3800
3875
  - **Worktree affinity.** A worktree is a durable per-branch workspace; keep all of a branch's code_change/fix/review work on its worktree node by targeting \`required_tags: ["worktree=<branch>"]\` or \`target_node_id\`. Get the id/branch from the \`mesh_clone_node\` result or a live \`mesh_status\` \u2014 the Configured Nodes snapshot won't list a worktree cloned after launch. Untargeted same-branch follow-ups drift to the base node. Only \`convergence\` (merge/push) runs on the base, never pinned to the worktree.
3801
3876
  - **Classify task difficulty to save tokens.** For each task you enqueue, judge its execution difficulty and pass \`difficulty\`: \`easy\` (extraction, renames, doc tweaks, trivial fixes), \`medium\` (ordinary feature/bugfix work), \`difficult\` (architecture, tricky debugging, multi-file refactors, subtle reasoning), or \`freeform\`. The mesh's per-difficulty brain preset then runs easy tasks on a cheaper model at low reasoning effort and hard tasks on a stronger model at high effort \u2014 real token savings on simple work. The current presets are shown in the "Brain presets" section below. You may still pass an explicit \`model\`/\`thinkingLevel\` to override the preset for one task.
3877
+ - **Retune node profiles when routing is a poor fit \u2014 but only with approval.** A node's capability slots (its provider/model/thinking + difficulty range + capability tags, seen via \`mesh_node_slots_list\`) are what task\u2192node fitness routing matches against. If you notice a persistent mismatch \u2014 e.g. every \`difficult\` task lands on a node whose only slot is a cheap model, or a capability a node clearly has isn't declared \u2014 you MAY propose a slot change with \`mesh_node_slots_set\` (write=false). That returns current-vs-proposed; present that diff to the user with a one-line reason and apply (write=true) ONLY after they approve. It is a WHOLESALE replacement of the node's slots, so include the slots you want to keep. Never rewrite a node's profile silently or without a clear routing reason.
3802
3878
  - **Respect explicit provider requests.** Map: Hermes \u2192 \`hermes-cli\`, Claude/Claude Code \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`, Antigravity \u2192 \`antigravity-cli\`. Never substitute the coordinator's own runtime.
3803
3879
  - **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
3804
3880
  - **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. This caps *concurrent* load \u2014 it does not mean serialize independent work: when a new, independent request arrives and there is headroom under \`maxParallelTasks\`, dispatch it right away rather than waiting for an in-flight task or a user nudge (read-only diagnosis especially, since it has no merge cost).
@@ -3876,7 +3952,9 @@ var init_coordinator_prompt = __esm({
3876
3952
  | \`mesh_magi_review\` | Cross-verify a read-only investigation across a standing panel of independent mesh agents (different machines/providers) instead of a single worker |
3877
3953
  | \`mesh_magi_collect\` | Collect + synthesize a previously dispatched MAGI fan-out by its consensus group id (async companion to mesh_magi_review wait:false) |
3878
3954
  | \`mesh_magi_kind_panel_set\` | Bind a task_kind \u2192 MAGI kind-panel slots (the SOLE MAGI panel-resolution surface; machine-local, wholesale replacement \u2014 approve current-vs-new first) |
3879
- | \`mesh_magi_kind_panel_list\` | List configured task_kind \u2192 MAGI kind-panel slot bindings (machine-local, read-only) |`;
3955
+ | \`mesh_magi_kind_panel_list\` | List configured task_kind \u2192 MAGI kind-panel slot bindings (machine-local, read-only) |
3956
+ | \`mesh_node_slots_list\` | List a node's capability slots (its AI-tool profile: provider/model/thinking + difficulty range + capability tags), read-only |
3957
+ | \`mesh_node_slots_set\` | PROPOSE (dry-run) or APPLY a node's capability slots \u2014 how you autonomously retune a node's tool profile; WHOLESALE replacement, present current-vs-proposed and get user approval before write=true |`;
3880
3958
  TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
3881
3959
 
3882
3960
  Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;
@@ -5824,6 +5902,7 @@ function enqueueTask(meshId, message, opts) {
5824
5902
  const maxRetries = typeof opts?.maxRetries === "number" && Number.isFinite(opts.maxRetries) && opts.maxRetries >= 0 ? Math.floor(opts.maxRetries) : void 0;
5825
5903
  let effectiveModel = typeof opts?.model === "string" && opts.model.trim() ? opts.model.trim() : void 0;
5826
5904
  let effectiveThinkingLevel = typeof opts?.thinkingLevel === "string" && opts.thinkingLevel.trim() ? opts.thinkingLevel.trim() : void 0;
5905
+ const taskDifficulty = isMeshTaskDifficulty(opts?.difficulty) ? opts.difficulty : void 0;
5827
5906
  if (isMeshTaskDifficulty(opts?.difficulty)) {
5828
5907
  try {
5829
5908
  const preset = getDifficultyBrains()[opts.difficulty];
@@ -5867,6 +5946,7 @@ function enqueueTask(meshId, message, opts) {
5867
5946
  ...typeof opts?.consensusGroupId === "string" && opts.consensusGroupId.trim() ? { consensusGroupId: opts.consensusGroupId.trim() } : {},
5868
5947
  ...effectiveModel ? { model: effectiveModel } : {},
5869
5948
  ...effectiveThinkingLevel ? { thinkingLevel: effectiveThinkingLevel } : {},
5949
+ ...taskDifficulty ? { difficulty: taskDifficulty } : {},
5870
5950
  ...typeof opts?.sourceCoordinatorSessionId === "string" && opts.sourceCoordinatorSessionId.trim() ? { sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId.trim() } : {},
5871
5951
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
5872
5952
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -15865,8 +15945,16 @@ function nodeHasActiveAssignment(meshId, nodeId) {
15865
15945
  function nodeActiveLoad(meshId, nodeId) {
15866
15946
  return MeshRuntimeStore.getInstance().nodeActiveAssignmentCount(meshId, nodeId);
15867
15947
  }
15948
+ function meshHasExplicitSlots(mesh) {
15949
+ const nodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
15950
+ return nodes.some((n) => normalizeNodeCapabilitySlots(n?.policy?.slots).length > 0);
15951
+ }
15868
15952
  function resolveSchedulingStrategy(mesh) {
15869
- return normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
15953
+ const raw = mesh?.policy?.schedulingStrategy;
15954
+ if (typeof raw === "string" && raw.trim()) {
15955
+ return normalizeMeshSchedulingStrategy(raw);
15956
+ }
15957
+ return meshHasExplicitSlots(mesh) ? "fitness" : normalizeMeshSchedulingStrategy(void 0);
15870
15958
  }
15871
15959
  function buildSchedulingPool(localCandidates, remoteCandidates) {
15872
15960
  const pool = [...localCandidates, ...remoteCandidates].map((c) => ({
@@ -15880,10 +15968,68 @@ function buildSchedulingPool(localCandidates, remoteCandidates) {
15880
15968
  }));
15881
15969
  return { pool, uniqueNodes };
15882
15970
  }
15971
+ function resolveNodeCapabilitySlots(node) {
15972
+ const explicit = normalizeNodeCapabilitySlots(node?.policy?.slots);
15973
+ if (explicit.length) return explicit;
15974
+ let difficultyBrains;
15975
+ try {
15976
+ difficultyBrains = getDifficultyBrains();
15977
+ } catch {
15978
+ difficultyBrains = void 0;
15979
+ }
15980
+ return deriveSlotsFromLegacy({
15981
+ providerPriority: normalizeProviderPriority(node?.policy),
15982
+ providerRoles: Array.isArray(node?.policy?.providerRoles) ? node.policy.providerRoles : void 0,
15983
+ difficultyBrains
15984
+ });
15985
+ }
15986
+ function scoreSlotForTask(slot, task) {
15987
+ let score = 1;
15988
+ const diff = isMeshTaskDifficulty(task.difficulty) ? task.difficulty : void 0;
15989
+ if (diff) {
15990
+ if (slot.difficulty?.length) {
15991
+ score += slot.difficulty.includes(diff) ? 100 : 0;
15992
+ } else {
15993
+ score += 20;
15994
+ }
15995
+ }
15996
+ const req = task.requiredTags?.filter((t) => !!t) ?? [];
15997
+ if (req.length) {
15998
+ const cap = new Set(slot.capability ?? []);
15999
+ const covered = req.every((t) => cap.has(t));
16000
+ score += covered ? 30 : 0;
16001
+ }
16002
+ return score;
16003
+ }
16004
+ function bestSlotForTask(node, task) {
16005
+ const slots = resolveNodeCapabilitySlots(node);
16006
+ if (!slots.length) return null;
16007
+ let best = null;
16008
+ for (const slot of slots) {
16009
+ const score = scoreSlotForTask(slot, task);
16010
+ if (!best || score > best.score) best = { slot, score };
16011
+ }
16012
+ return best;
16013
+ }
16014
+ function nodeFitnessForTask(node, task) {
16015
+ return bestSlotForTask(node, task)?.score ?? 0;
16016
+ }
15883
16017
  function orderEligibleNodes(meshId, strategy, nodes, opts) {
15884
16018
  if (strategy === "first_eligible" || nodes.length <= 1) {
15885
16019
  return nodes;
15886
16020
  }
16021
+ if (strategy === "fitness" && opts?.task) {
16022
+ const task = opts.task;
16023
+ return [...nodes].sort((a, b) => {
16024
+ const fitDelta = nodeFitnessForTask(b.node, task) - nodeFitnessForTask(a.node, task);
16025
+ if (fitDelta !== 0) return fitDelta;
16026
+ const prioDelta = resolveNodeSchedulingPriority(b.node?.policy) - resolveNodeSchedulingPriority(a.node?.policy);
16027
+ if (prioDelta !== 0) return prioDelta;
16028
+ const loadDelta = nodeActiveLoad(meshId, a.nodeId) - nodeActiveLoad(meshId, b.nodeId);
16029
+ if (loadDelta !== 0) return loadDelta;
16030
+ return a.index - b.index;
16031
+ });
16032
+ }
15887
16033
  const priorityOf = (n) => resolveNodeSchedulingPriority(n.node?.policy);
15888
16034
  let rotation = 0;
15889
16035
  if (strategy === "least_loaded" || strategy === "round_robin") {
@@ -16027,13 +16173,15 @@ function markAutoLaunch(meshId, taskId, args) {
16027
16173
  retractActionableSkipIfPreviouslyNotified(meshId, taskId);
16028
16174
  }
16029
16175
  }
16030
- async function resolveUsableProvider(components, nodeId, node, requiredTags) {
16031
- const providerPriority = normalizeProviderPriority(node?.policy);
16032
- if (!providerPriority.length) return { reason: "missing_provider_priority" };
16176
+ async function resolveUsableProvider(components, nodeId, node, requiredTags, task) {
16033
16177
  const providerLoader = components.providerLoader;
16034
16178
  if (!providerLoader) return { reason: "provider_loader_unavailable" };
16179
+ const slots = resolveNodeCapabilitySlots(node);
16180
+ if (!slots.length) return { reason: "missing_provider_priority" };
16181
+ const orderedSlots = task ? [...slots].sort((a, b) => scoreSlotForTask(b, task) - scoreSlotForTask(a, task)) : slots;
16035
16182
  const failed = [];
16036
- for (const requestedType of providerPriority) {
16183
+ for (const slot of orderedSlots) {
16184
+ const requestedType = slot.provider;
16037
16185
  const normalizedType = typeof providerLoader.resolveAlias === "function" ? providerLoader.resolveAlias(requestedType) : requestedType;
16038
16186
  if (requiredTags?.length && !nodeSatisfiesRequiredTags(requiredTags, buildMeshNodeCapabilityTags(node, normalizedType))) {
16039
16187
  failed.push(`${requestedType}: required_tags_mismatch`);
@@ -16058,7 +16206,13 @@ async function resolveUsableProvider(components, nodeId, node, requiredTags) {
16058
16206
  }], false);
16059
16207
  }
16060
16208
  components.onStatusChange?.();
16061
- if (detected) return { providerType: normalizedType };
16209
+ if (detected) {
16210
+ return {
16211
+ providerType: normalizedType,
16212
+ ...slot.model ? { model: slot.model } : {},
16213
+ ...slot.thinkingLevel ? { thinkingLevel: slot.thinkingLevel } : {}
16214
+ };
16215
+ }
16062
16216
  failed.push(`${requestedType}: not detected`);
16063
16217
  }
16064
16218
  return { reason: `provider_priority_unusable: ${failed.join("; ") || nodeId}` };
@@ -16186,7 +16340,9 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
16186
16340
  meshId,
16187
16341
  strategy,
16188
16342
  candidateNodes.map((node, index) => ({ nodeId: readMeshNodeId(node), node, index })).filter((c) => c.nodeId),
16189
- { bumpCursor: true }
16343
+ // Auto-launch drains one task at a time, so the task IS in scope here —
16344
+ // pass it through for the 'fitness' strategy's task→slot ranking.
16345
+ { bumpCursor: true, task: { difficulty: task.difficulty, requiredTags: task.requiredTags } }
16190
16346
  ).map((c) => c.node);
16191
16347
  for (const node of orderedCandidateNodes) {
16192
16348
  const nodeId = readMeshNodeId(node);
@@ -16233,11 +16389,13 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
16233
16389
  }
16234
16390
  autoLaunchInProgress.add(launchKey);
16235
16391
  try {
16236
- const resolved = await resolveUsableProvider(components, nodeId, node, task.requiredTags);
16392
+ const resolved = await resolveUsableProvider(components, nodeId, node, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags });
16237
16393
  if (!resolved.providerType) {
16238
16394
  markAutoLaunch(meshId, task.id, { status: "skipped", reason: resolved.reason || "provider_unusable", nodeId });
16239
16395
  continue;
16240
16396
  }
16397
+ const effectiveModel = typeof task.model === "string" && task.model.trim() ? task.model.trim() : resolved.model;
16398
+ const effectiveThinkingLevel = typeof task.thinkingLevel === "string" && task.thinkingLevel.trim() ? task.thinkingLevel.trim() : resolved.thinkingLevel;
16241
16399
  const providerCap = resolveProviderMaxParallel(node?.policy, resolved.providerType);
16242
16400
  if (providerCap !== void 0 && activeProviderAssignedCount(meshId, nodeId, resolved.providerType) >= providerCap) {
16243
16401
  markAutoLaunch(meshId, task.id, { status: "skipped", reason: "max_provider_parallel_reached", nodeId, providerType: resolved.providerType });
@@ -16271,9 +16429,10 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
16271
16429
  settings: remoteSettings,
16272
16430
  // MAGI-KIND-PANEL model axis: forward the task's model override so the
16273
16431
  // remote worker session launches with it (initialModel). Best-effort.
16274
- ...typeof task.model === "string" && task.model.trim() ? { initialModel: task.model.trim() } : {},
16275
- // BRAIN-ROUTING thinking axis: forward the task's thinking level (initialThinkingLevel).
16276
- ...typeof task.thinkingLevel === "string" && task.thinkingLevel.trim() ? { initialThinkingLevel: task.thinkingLevel.trim() } : {}
16432
+ // Slot-aware: task override wins, else the matched slot's model.
16433
+ ...effectiveModel ? { initialModel: effectiveModel } : {},
16434
+ // BRAIN-ROUTING thinking axis: forward the effective thinking level (initialThinkingLevel).
16435
+ ...effectiveThinkingLevel ? { initialThinkingLevel: effectiveThinkingLevel } : {}
16277
16436
  });
16278
16437
  } catch (e) {
16279
16438
  markAutoLaunch(meshId, task.id, { status: "failed", reason: `remote_launch_dispatch_failed: ${e?.message || String(e)}`, nodeId, providerType: resolved.providerType });
@@ -16300,11 +16459,11 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
16300
16459
  cliType: resolved.providerType,
16301
16460
  dir: node.workspace,
16302
16461
  settings: launchSettings,
16303
- // MAGI-KIND-PANEL model axis: local launch forwards the task's model
16304
- // override as initialModel (CLI → modelLaunchArgs; ACP → setConfigOption).
16305
- ...typeof task.model === "string" && task.model.trim() ? { initialModel: task.model.trim() } : {},
16306
- // BRAIN-ROUTING thinking axis: forward the task's thinking level (initialThinkingLevel).
16307
- ...typeof task.thinkingLevel === "string" && task.thinkingLevel.trim() ? { initialThinkingLevel: task.thinkingLevel.trim() } : {}
16462
+ // MAGI-KIND-PANEL model axis: local launch forwards the effective model
16463
+ // (task override, else matched slot) as initialModel (CLI → modelLaunchArgs; ACP → setConfigOption).
16464
+ ...effectiveModel ? { initialModel: effectiveModel } : {},
16465
+ // BRAIN-ROUTING thinking axis: forward the effective thinking level (initialThinkingLevel).
16466
+ ...effectiveThinkingLevel ? { initialThinkingLevel: effectiveThinkingLevel } : {}
16308
16467
  });
16309
16468
  if (!launchResult?.success) {
16310
16469
  const reason = launchResult?.error || "launch_cli_failed";
@@ -16439,7 +16598,7 @@ async function triggerMeshQueue(components, meshId) {
16439
16598
  const aPrio = resolveNodeSchedulingPriority(a.node?.policy);
16440
16599
  const bPrio = resolveNodeSchedulingPriority(b.node?.policy);
16441
16600
  if (aPrio !== bPrio) return bPrio - aPrio;
16442
- if (strategy === "least_loaded" || strategy === "round_robin") {
16601
+ if (strategy === "least_loaded" || strategy === "round_robin" || strategy === "fitness") {
16443
16602
  const loadDelta = nodeActiveLoad(meshId, a.nodeId) - nodeActiveLoad(meshId, b.nodeId);
16444
16603
  if (loadDelta !== 0) return loadDelta;
16445
16604
  }
@@ -18433,6 +18592,22 @@ var init_provider_input_support = __esm({
18433
18592
  });
18434
18593
 
18435
18594
  // src/status/builders.ts
18595
+ function isCoordinatorSpawnedHiddenWorker(settings) {
18596
+ if (!settings) return false;
18597
+ return settings.launchedByCoordinator === true && typeof settings.meshNodeFor === "string" && settings.meshNodeFor.trim().length > 0 && settings.spawnedSessionVisibility === "hidden";
18598
+ }
18599
+ function resolveSurfaceHidden(settings) {
18600
+ if (!settings) return false;
18601
+ if (settings.userHidden === true) return true;
18602
+ if (settings.userHidden === false) return false;
18603
+ return settings.spawnedSessionVisibility === "hidden" || isCoordinatorSpawnedHiddenWorker(settings);
18604
+ }
18605
+ function resolveMuted(settings) {
18606
+ if (!settings) return false;
18607
+ if (settings.userMuted === true) return true;
18608
+ if (settings.userMuted === false) return false;
18609
+ return isCoordinatorSpawnedHiddenWorker(settings);
18610
+ }
18436
18611
  function getActiveChatOptions(profile) {
18437
18612
  if (profile === "full") return {};
18438
18613
  return LIVE_STATUS_ACTIVE_CHAT_OPTIONS;
@@ -18638,7 +18813,8 @@ function buildCliSession(state, options) {
18638
18813
  settings: state.settings,
18639
18814
  ...coordinator && { coordinator },
18640
18815
  ...meshQueueStats && { meshQueueStats },
18641
- ...state.settings?.spawnedSessionVisibility === "hidden" && { surfaceHidden: true }
18816
+ ...resolveSurfaceHidden(state.settings) && { surfaceHidden: true },
18817
+ ...resolveMuted(state.settings) && { muted: true }
18642
18818
  };
18643
18819
  }
18644
18820
  function buildAcpSession(state, options) {
@@ -18679,7 +18855,8 @@ function buildAcpSession(state, options) {
18679
18855
  settings: state.settings,
18680
18856
  ...coordinator && { coordinator },
18681
18857
  ...meshQueueStats && { meshQueueStats },
18682
- ...state.settings?.spawnedSessionVisibility === "hidden" && { surfaceHidden: true }
18858
+ ...resolveSurfaceHidden(state.settings) && { surfaceHidden: true },
18859
+ ...resolveMuted(state.settings) && { muted: true }
18683
18860
  };
18684
18861
  }
18685
18862
  function buildSessionEntries(allStates, cdpManagers, options = {}) {
@@ -39078,11 +39255,15 @@ ${formatManifestValidationIssues2(validation.issues)}`,
39078
39255
  if (!manifestPath) continue;
39079
39256
  try {
39080
39257
  const m = JSON.parse(fs41.readFileSync(manifestPath, "utf-8"));
39258
+ const modelOptions = Array.isArray(m.modelOptions) ? m.modelOptions.filter((x) => typeof x === "string" && !!x.trim()) : [];
39259
+ const thinkingLevelOptions = Array.isArray(m.thinkingLevelOptions) ? m.thinkingLevelOptions.filter((x) => typeof x === "string" && !!x.trim()) : [];
39081
39260
  items.push({
39082
39261
  type,
39083
39262
  category,
39084
39263
  version: typeof m.providerVersion === "string" ? m.providerVersion : "0.0.0",
39085
- path: manifestPath
39264
+ path: manifestPath,
39265
+ ...modelOptions.length ? { modelOptions } : {},
39266
+ ...thinkingLevelOptions.length ? { thinkingLevelOptions } : {}
39086
39267
  });
39087
39268
  } catch {
39088
39269
  }
@@ -49871,6 +50052,31 @@ var cliAgentHandlers = {
49871
50052
  record_provider_pty: async (ctx, args) => {
49872
50053
  return ctx.deps.cliManager.handleCliCommand("record_provider_pty", args);
49873
50054
  },
50055
+ // Daemon-owned per-session user Mute/Hide. Replaces the old browser-local
50056
+ // localStorage layer: the user's manual hide/mute for a conversation is stored
50057
+ // in-memory on the live session's settings (userHidden / userMuted) and rides
50058
+ // the SAME status snapshot pipeline as the coordinator-policy surfaceHidden
50059
+ // flag, so every client of this daemon sees the same state. In-memory only —
50060
+ // resets on daemon restart (coordinator-spawned sessions re-derive their hidden
50061
+ // default from mesh policy on relaunch). Passing null/undefined for a field
50062
+ // leaves it unchanged; pass an explicit boolean to set, or false to clear an
50063
+ // earlier hide/mute (e.g. unmute a coordinator-spawned worker overrides the
50064
+ // policy default until restart).
50065
+ set_conversation_prefs: async (ctx, args) => {
50066
+ const sessionId = readStringValue(args?.sessionId, args?.targetSessionId, args?.instanceId);
50067
+ if (!sessionId) return { success: false, error: "sessionId required" };
50068
+ const inst = ctx.deps.instanceManager.getInstance(sessionId);
50069
+ if (!inst || typeof inst.updateSettings !== "function") {
50070
+ return { success: false, error: "Session not found or does not support preferences" };
50071
+ }
50072
+ const patch = {};
50073
+ if (typeof args?.hidden === "boolean") patch.userHidden = args.hidden;
50074
+ if (typeof args?.muted === "boolean") patch.userMuted = args.muted;
50075
+ if (!Object.keys(patch).length) return { success: false, error: "Nothing to update (hidden and/or muted required)" };
50076
+ inst.updateSettings(patch);
50077
+ ctx.deps.onStatusChange?.();
50078
+ return { success: true, sessionId, ...patch };
50079
+ },
49874
50080
  agent_command: async (ctx, args) => {
49875
50081
  {
49876
50082
  const dispatchSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
@@ -56132,6 +56338,8 @@ var meshCoordinatorLaunchHandlers = {
56132
56338
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
56133
56339
  let cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "";
56134
56340
  const extraSystemPrompt = typeof args?.extraSystemPrompt === "string" ? args.extraSystemPrompt.trim() : "";
56341
+ const initialModel = typeof args?.initialModel === "string" && args.initialModel.trim() ? args.initialModel.trim() : null;
56342
+ const initialThinkingLevel = typeof args?.initialThinkingLevel === "string" && args.initialThinkingLevel.trim() ? args.initialThinkingLevel.trim() : null;
56135
56343
  if (!meshId) return { success: false, error: "meshId required" };
56136
56344
  try {
56137
56345
  const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
@@ -56402,7 +56610,9 @@ ${ptyResult.output.slice(-2e3)}`);
56402
56610
  dir: workspace,
56403
56611
  cliArgs: cliCmdArgs.length > 0 ? cliCmdArgs : void 0,
56404
56612
  env: Object.keys(cliCmdEnv).length > 0 ? cliCmdEnv : void 0,
56405
- settings: { meshCoordinatorFor: meshId }
56613
+ settings: { meshCoordinatorFor: meshId },
56614
+ ...initialModel ? { initialModel } : {},
56615
+ ...initialThinkingLevel ? { initialThinkingLevel } : {}
56406
56616
  });
56407
56617
  if (cliCmdLaunch?.success && cliCmdContextFilePath) {
56408
56618
  const stripPath = cliCmdContextFilePath;
@@ -56587,7 +56797,9 @@ ${ptyResult.output.slice(-2e3)}`);
56587
56797
  env: Object.keys(launchEnv).length > 0 ? launchEnv : void 0,
56588
56798
  settings: {
56589
56799
  meshCoordinatorFor: meshId
56590
- }
56800
+ },
56801
+ ...initialModel ? { initialModel } : {},
56802
+ ...initialThinkingLevel ? { initialThinkingLevel } : {}
56591
56803
  });
56592
56804
  if (launchResult?.success && autoImportContextFilePath) {
56593
56805
  const stripPath = autoImportContextFilePath;
@@ -56946,6 +57158,11 @@ var meshStatusHandlers = {
56946
57158
  ...node.reportedProviderVersions && typeof node.reportedProviderVersions === "object" ? { providerVersions: node.reportedProviderVersions } : {},
56947
57159
  ...typeof node.reportedDaemonBuildVersion === "string" && node.reportedDaemonBuildVersion ? { daemonBuildVersion: node.reportedDaemonBuildVersion } : {},
56948
57160
  providerPriority,
57161
+ // ORCHESTRATION_NODE_SLOTS.md: surface the node's capability
57162
+ // slots so the dashboard slot editor can read them. Only
57163
+ // emitted when explicitly configured (derived-from-legacy
57164
+ // slots stay implicit — the editor shows the legacy fields).
57165
+ ...Array.isArray(node.policy?.slots) && node.policy.slots.length ? { slots: normalizeNodeCapabilitySlots(node.policy.slots) } : {},
56949
57166
  activeSessions: [],
56950
57167
  activeSessionDetails: [],
56951
57168
  launchReady: false
@@ -69819,6 +70036,7 @@ export {
69819
70036
  appendRemoteLedgerEntries,
69820
70037
  assertNoDependencyCycle,
69821
70038
  buildAssistantChatMessage,
70039
+ buildAvailableProviders,
69822
70040
  buildChatMessage,
69823
70041
  buildChatMessageSignature,
69824
70042
  buildChatTailDeliverySignature,