@slock-ai/daemon 0.55.2 → 0.55.3

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.
@@ -2172,7 +2172,7 @@ async function handleProxyRequest(req, res) {
2172
2172
  const bodyBuffer = new ArrayBuffer(rawBodyBuffer.byteLength);
2173
2173
  new Uint8Array(bodyBuffer).set(rawBodyBuffer);
2174
2174
  body = bodyBuffer;
2175
- headers.set("content-length", String(rawBodyBuffer.byteLength));
2175
+ headers.delete("content-length");
2176
2176
  }
2177
2177
  let sendTarget;
2178
2178
  const sideEffectAction = agentApiSideEffectAction(target.pathname);
@@ -2196,7 +2196,7 @@ async function handleProxyRequest(req, res) {
2196
2196
  body = prepared.bodyText;
2197
2197
  if (sideEffectAction === "send") sendTarget = prepared.target;
2198
2198
  headers.set("content-type", "application/json");
2199
- headers.set("content-length", String(Buffer.byteLength(prepared.bodyText)));
2199
+ headers.delete("content-length");
2200
2200
  }
2201
2201
  const upstream = await daemonFetch(target, {
2202
2202
  method,
@@ -2385,6 +2385,20 @@ function maxMessageSeq(messages) {
2385
2385
  }
2386
2386
  return maxSeq > 0 ? maxSeq : void 0;
2387
2387
  }
2388
+ function messageSenderId(message) {
2389
+ if (typeof message.sender_id === "string" && message.sender_id.length > 0) return message.sender_id;
2390
+ if (typeof message.senderId === "string" && message.senderId.length > 0) return message.senderId;
2391
+ return void 0;
2392
+ }
2393
+ function isSelfAuthoredMessage(registration, message) {
2394
+ return messageSenderId(message) === registration.agentId;
2395
+ }
2396
+ function isMessageModelSeen(coordinator, target, message) {
2397
+ const seq = Math.floor(messageSeq(message));
2398
+ const boundary = coordinator.getBoundary(target);
2399
+ if (Number.isFinite(seq) && seq > 0 && typeof boundary === "number" && boundary >= seq) return true;
2400
+ return coordinator.isMessageModelSeen?.({ target, message }) === true;
2401
+ }
2388
2402
  function resolveFreshnessBoundary(messages) {
2389
2403
  const seenUpToSeq = maxMessageSeq(messages);
2390
2404
  return typeof seenUpToSeq === "number" ? { ok: true, seenUpToSeq } : { ok: false, reason: "missing_seq_boundary" };
@@ -2525,7 +2539,7 @@ function parseTargetFields(target) {
2525
2539
  }
2526
2540
  function normalizeVisibleMessage(message, target) {
2527
2541
  const targetFields = target ? parseTargetFields(target) : {};
2528
- return {
2542
+ const normalized = {
2529
2543
  ...targetFields,
2530
2544
  ...message,
2531
2545
  message_id: message.message_id ?? message.id,
@@ -2534,6 +2548,9 @@ function normalizeVisibleMessage(message, target) {
2534
2548
  sender_name: message.sender_name ?? message.senderName,
2535
2549
  sender_description: message.sender_description ?? message.senderDescription ?? null
2536
2550
  };
2551
+ const senderId = messageSenderId(message);
2552
+ if (senderId) normalized.sender_id = senderId;
2553
+ return normalized;
2537
2554
  }
2538
2555
  function normalizeVisibleMessages(messages, target) {
2539
2556
  return messages.map((message) => normalizeVisibleMessage(message, target));
@@ -2634,6 +2651,9 @@ async function prepareAgentApiSideEffectForward(registration, headers, rawBody,
2634
2651
  }
2635
2652
  const recent = await loadRecentTargetMessages(registration, headers, target);
2636
2653
  if (recent.length > 0) {
2654
+ const unconsumedCounterparty = recent.filter(
2655
+ (message) => !isSelfAuthoredMessage(registration, message) && !isMessageModelSeen(coordinator, target, message)
2656
+ );
2637
2657
  const boundary2 = resolveFreshnessBoundary(recent);
2638
2658
  if (!boundary2.ok) {
2639
2659
  recordFreshnessDecision(coordinator, {
@@ -2647,6 +2667,39 @@ async function prepareAgentApiSideEffectForward(registration, headers, rawBody,
2647
2667
  });
2648
2668
  return { bodyText: JSON.stringify(body), target };
2649
2669
  }
2670
+ if (unconsumedCounterparty.length === 0) {
2671
+ const { seenUpToSeq: seenUpToSeq2 } = boundary2;
2672
+ if (action === "send") body.seenUpToSeq = seenUpToSeq2;
2673
+ coordinator.consumeVisibleMessages({ target, messages: recent, boundarySeq: seenUpToSeq2, source: "side_effect_preflight_context" });
2674
+ recordFreshnessDecision(coordinator, {
2675
+ action,
2676
+ decision: "forward",
2677
+ target,
2678
+ inboxTrustState: "untrusted",
2679
+ reason: "target_first_touch_recent_context_already_seen",
2680
+ pendingCount: 0,
2681
+ pendingMaxSeq: seenUpToSeq2,
2682
+ modelSeenSeq: seenUpToSeq2,
2683
+ heldMessageCount: 0,
2684
+ omittedMessageCount: 0
2685
+ });
2686
+ return { bodyText: JSON.stringify(body), target };
2687
+ }
2688
+ const heldBoundary = resolveFreshnessBoundary(unconsumedCounterparty);
2689
+ if (!heldBoundary.ok) {
2690
+ recordFreshnessDecision(coordinator, {
2691
+ action,
2692
+ decision: "forward",
2693
+ target,
2694
+ inboxTrustState: "untrusted",
2695
+ reason: "target_first_touch_counterparty_context_without_seq_boundary",
2696
+ pendingCount: 0,
2697
+ modelSeenSeq: 0
2698
+ });
2699
+ return { bodyText: JSON.stringify(body), target };
2700
+ }
2701
+ const heldMessages = latestVisibleMessages(unconsumedCounterparty, LOCAL_HELD_CONTEXT_LIMIT);
2702
+ const omittedMessageCount = Math.max(0, unconsumedCounterparty.length - heldMessages.length);
2650
2703
  const { seenUpToSeq } = boundary2;
2651
2704
  coordinator.consumeVisibleMessages({ target, messages: recent, boundarySeq: seenUpToSeq, source: "side_effect_preflight_context" });
2652
2705
  const decision = {
@@ -2656,10 +2709,10 @@ async function prepareAgentApiSideEffectForward(registration, headers, rawBody,
2656
2709
  inboxTrustState: "untrusted",
2657
2710
  reason: "target_first_touch_recent_context",
2658
2711
  pendingCount: 0,
2659
- pendingMaxSeq: seenUpToSeq,
2712
+ pendingMaxSeq: heldBoundary.seenUpToSeq,
2660
2713
  modelSeenSeq: 0,
2661
- heldMessageCount: recent.length,
2662
- omittedMessageCount: 0
2714
+ heldMessageCount: heldMessages.length,
2715
+ omittedMessageCount
2663
2716
  };
2664
2717
  const producerFactId = buildApmFreshnessDecisionProducerFactId(registration.agentId, decision);
2665
2718
  recordFreshnessDecision(coordinator, { ...decision, producerFactId });
@@ -2669,9 +2722,9 @@ async function prepareAgentApiSideEffectForward(registration, headers, rawBody,
2669
2722
  localResponse: projectApmHeldFreshnessEnvelope({
2670
2723
  producerFactId,
2671
2724
  action,
2672
- heldMessages: recent,
2673
- newMessageCount: recent.length,
2674
- omittedMessageCount: 0,
2725
+ heldMessages,
2726
+ newMessageCount: unconsumedCounterparty.length,
2727
+ omittedMessageCount,
2675
2728
  seenUpToSeq
2676
2729
  }).body
2677
2730
  };
@@ -3026,7 +3079,7 @@ function collectResultErrorDetail(message, fallback) {
3026
3079
  return parts.join(" | ") || fallback;
3027
3080
  }
3028
3081
  function isProviderApiFailureText(value, hasToolUse) {
3029
- return !hasToolUse && /^\s*API Error:/i.test(value) && (/\b(?:ECONNRESET|EPIPE|ETIMEDOUT|ECONNREFUSED|ENOTFOUND|EAI_AGAIN)\b/i.test(value) || /\bUnable to connect to API\b/i.test(value) || /\b(?:timed out|timeout)\b/i.test(value) || /\b5\d{2}\b/.test(value));
3082
+ return !hasToolUse && /^\s*API Error:/i.test(value) && (/\b(?:ECONNRESET|EPIPE|ETIMEDOUT|ECONNREFUSED|ENOTFOUND|EAI_AGAIN)\b/i.test(value) || /\bUnable to connect to API\b/i.test(value) || /\b(?:timed out|timeout)\b/i.test(value) || /\b4\d{2}\b/.test(value) || /\b5\d{2}\b/.test(value));
3030
3083
  }
3031
3084
  var ClaudeEventNormalizer = class {
3032
3085
  normalizeLine(line) {
@@ -4052,6 +4105,7 @@ var CodexDriver = class {
4052
4105
  cwd: ctx.workingDirectory,
4053
4106
  approvalPolicy: "never",
4054
4107
  sandbox: "danger-full-access",
4108
+ sandbox_mode: "danger-full-access",
4055
4109
  developerInstructions: ctx.standingPrompt,
4056
4110
  // Raw response items are used only as payload-free liveness signals in
4057
4111
  // the daemon. They replace the previous transcript-mtime heuristic.
@@ -7280,6 +7334,7 @@ var AgentProcessManager = class _AgentProcessManager {
7280
7334
  deliveryTraceContexts = /* @__PURE__ */ new WeakMap();
7281
7335
  processExitTraceAttrs = /* @__PURE__ */ new WeakMap();
7282
7336
  agentVisibleBoundaries = /* @__PURE__ */ new Map();
7337
+ agentVisibleMessageIds = /* @__PURE__ */ new Map();
7283
7338
  constructor(chatBridgePath, sendToServer, daemonApiKey, opts) {
7284
7339
  this.chatBridgePath = chatBridgePath;
7285
7340
  this.slockCliPath = opts.slockCliPath ?? "";
@@ -7325,6 +7380,24 @@ var AgentProcessManager = class _AgentProcessManager {
7325
7380
  getVisibleBoundary(agentId, target) {
7326
7381
  return this.agentVisibleBoundaries.get(agentId)?.get(target);
7327
7382
  }
7383
+ visibleMessageIdMap(agentId) {
7384
+ let map = this.agentVisibleMessageIds.get(agentId);
7385
+ if (!map) {
7386
+ map = /* @__PURE__ */ new Map();
7387
+ this.agentVisibleMessageIds.set(agentId, map);
7388
+ }
7389
+ return map;
7390
+ }
7391
+ getVisibleMessageIdSet(agentId, target) {
7392
+ return this.agentVisibleMessageIds.get(agentId)?.get(target);
7393
+ }
7394
+ isVisibleMessageModelSeen(agentId, target, message) {
7395
+ const seq = Number(message.seq ?? 0);
7396
+ const boundary = this.getVisibleBoundary(agentId, target);
7397
+ if (Number.isFinite(seq) && seq > 0 && typeof boundary === "number" && boundary >= Math.floor(seq)) return true;
7398
+ const id = typeof message.message_id === "string" ? message.message_id : typeof message.id === "string" ? message.id : "";
7399
+ return id.length > 0 && this.getVisibleMessageIdSet(agentId, target)?.has(id) === true;
7400
+ }
7328
7401
  scheduleStdinNotification(agentId, ap, delayMs) {
7329
7402
  return ap.notifications.schedule(() => {
7330
7403
  this.sendStdinNotification(agentId);
@@ -7359,13 +7432,14 @@ var AgentProcessManager = class _AgentProcessManager {
7359
7432
  };
7360
7433
  for (const message of input.messages) {
7361
7434
  const seq = Number(message.seq ?? 0);
7362
- if (!Number.isFinite(seq) || seq <= 0) continue;
7363
7435
  const target = input.target ?? formatVisibleMessageTarget(message);
7364
7436
  if (!target) continue;
7365
7437
  const bucket = ensureBucket(target);
7366
- bucket.maxSeq = Math.max(bucket.maxSeq, Math.floor(seq));
7367
- bucket.seqs.add(Math.floor(seq));
7368
- const id = typeof message.id === "string" ? message.id : typeof message.message_id === "string" ? message.message_id : null;
7438
+ if (Number.isFinite(seq) && seq > 0) {
7439
+ bucket.maxSeq = Math.max(bucket.maxSeq, Math.floor(seq));
7440
+ bucket.seqs.add(Math.floor(seq));
7441
+ }
7442
+ const id = typeof message.message_id === "string" ? message.message_id : typeof message.id === "string" ? message.id : null;
7369
7443
  if (id) bucket.ids.add(id);
7370
7444
  }
7371
7445
  if (input.target && typeof input.boundarySeq === "number" && Number.isFinite(input.boundarySeq) && input.boundarySeq > 0) {
@@ -7374,10 +7448,19 @@ var AgentProcessManager = class _AgentProcessManager {
7374
7448
  }
7375
7449
  if (byTarget.size === 0) return;
7376
7450
  const boundaryMap = this.visibleBoundaryMap(agentId);
7451
+ const visibleIds = this.visibleMessageIdMap(agentId);
7377
7452
  for (const [target, bucket] of byTarget) {
7378
7453
  const highWaterSeq = Math.max(bucket.maxSeq, bucket.boundarySeq);
7379
7454
  const previous = boundaryMap.get(target) ?? 0;
7380
7455
  boundaryMap.set(target, Math.max(previous, highWaterSeq));
7456
+ if (bucket.ids.size > 0) {
7457
+ let targetIds = visibleIds.get(target);
7458
+ if (!targetIds) {
7459
+ targetIds = /* @__PURE__ */ new Set();
7460
+ visibleIds.set(target, targetIds);
7461
+ }
7462
+ for (const id of bucket.ids) targetIds.add(id);
7463
+ }
7381
7464
  }
7382
7465
  const suppress = (messages) => {
7383
7466
  if (!messages || messages.length === 0) return 0;
@@ -7410,6 +7493,7 @@ var AgentProcessManager = class _AgentProcessManager {
7410
7493
  return {
7411
7494
  getBoundary: (target) => this.getVisibleBoundary(agentId, target),
7412
7495
  getPendingMessages: (target) => this.pendingVisibleMessages(agentId, target),
7496
+ isMessageModelSeen: ({ target, message }) => this.isVisibleMessageModelSeen(agentId, target, message),
7413
7497
  getAllPendingMessages: () => this.allPendingVisibleMessages(agentId),
7414
7498
  consumeVisibleMessages: (input) => this.consumeVisibleMessages(agentId, input),
7415
7499
  recordDrainOutcome: (input) => {
@@ -9606,7 +9690,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9606
9690
  }
9607
9691
  }
9608
9692
  isThinkingBlockMutationError(message) {
9609
- return /thinking.*redacted_thinking|redacted_thinking.*thinking/i.test(message) && /cannot be modified/i.test(message);
9693
+ return /thinking.*redacted_thinking|redacted_thinking.*thinking/i.test(message) && /cannot be modified/i.test(message) || /messages\.\d+\.content\.\d+\.text\.start_timestamp:\s*Extra inputs are not permitted/i.test(message);
9610
9694
  }
9611
9695
  markRuntimeProgressStaleIfNeeded(agentId, ap) {
9612
9696
  if (ap.lastActivity !== "working" && ap.lastActivity !== "thinking") return false;
package/dist/core.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  resolveSlockCliPath,
10
10
  resolveWorkspaceDirectoryPath,
11
11
  scanWorkspaceDirectories
12
- } from "./chunk-IDDG4Q4Q.js";
12
+ } from "./chunk-DLB2KVD7.js";
13
13
  import {
14
14
  subscribeDaemonLogs
15
15
  } from "./chunk-M2KQBJR3.js";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  DAEMON_CLI_USAGE,
4
4
  DaemonCore,
5
5
  parseDaemonCliArgs
6
- } from "./chunk-IDDG4Q4Q.js";
6
+ } from "./chunk-DLB2KVD7.js";
7
7
  import "./chunk-M2KQBJR3.js";
8
8
 
9
9
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slock-ai/daemon",
3
- "version": "0.55.2",
3
+ "version": "0.55.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "slock-daemon": "dist/index.js"