@slock-ai/daemon 0.48.0 → 0.48.1

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.
@@ -169,16 +169,64 @@ function formatHistoryMessageLine(message) {
169
169
  }
170
170
 
171
171
  // src/chatBridgeSendRequest.ts
172
- import { randomUUID } from "crypto";
172
+ import { createHash, randomUUID } from "crypto";
173
+ var DEFAULT_SEND_RETRY_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
174
+ var ambiguousSendKeys = /* @__PURE__ */ new Map();
175
+ function pruneExpiredAmbiguousSendKeys(nowMs) {
176
+ for (const [fingerprint, entry] of ambiguousSendKeys) {
177
+ if (entry.expiresAt <= nowMs) {
178
+ ambiguousSendKeys.delete(fingerprint);
179
+ }
180
+ }
181
+ }
182
+ function resolveIdempotencyKey(opts) {
183
+ if (opts.idempotencyKey) return opts.idempotencyKey;
184
+ if (!opts.retryFingerprint) return randomUUID();
185
+ pruneExpiredAmbiguousSendKeys(opts.nowMs);
186
+ const existing = ambiguousSendKeys.get(opts.retryFingerprint);
187
+ if (existing && existing.expiresAt > opts.nowMs) {
188
+ return existing.idempotencyKey;
189
+ }
190
+ return randomUUID();
191
+ }
192
+ function rememberAmbiguousSendKey(retryFingerprint, idempotencyKey, nowMs, ttlMs) {
193
+ if (!retryFingerprint) return;
194
+ pruneExpiredAmbiguousSendKeys(nowMs);
195
+ ambiguousSendKeys.set(retryFingerprint, {
196
+ idempotencyKey,
197
+ expiresAt: nowMs + ttlMs
198
+ });
199
+ }
200
+ function clearAmbiguousSendKey(retryFingerprint) {
201
+ if (!retryFingerprint) return;
202
+ ambiguousSendKeys.delete(retryFingerprint);
203
+ }
204
+ function buildSendRetryFingerprint(input) {
205
+ const attachmentIds = input.attachmentIds ?? [];
206
+ const hash = createHash("sha256").update(JSON.stringify({
207
+ target: input.target,
208
+ content: input.content,
209
+ attachmentIds
210
+ })).digest("hex");
211
+ return `send_message:${hash}`;
212
+ }
173
213
  async function executeRetrySafeSendRequest(url, buildInit, {
174
214
  fetchImpl,
175
215
  target,
176
216
  timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
177
217
  now = () => Date.now(),
178
218
  warn = (message) => logger.warn(message),
179
- idempotencyKey = randomUUID()
219
+ idempotencyKey: explicitIdempotencyKey,
220
+ retryFingerprint,
221
+ retryFingerprintTtlMs = DEFAULT_SEND_RETRY_FINGERPRINT_TTL_MS
180
222
  }) {
181
223
  let lastError;
224
+ const idempotencyKey = resolveIdempotencyKey({
225
+ idempotencyKey: explicitIdempotencyKey,
226
+ retryFingerprint,
227
+ retryFingerprintTtlMs,
228
+ nowMs: now()
229
+ });
182
230
  for (let attempt = 1; attempt <= 2; attempt += 1) {
183
231
  try {
184
232
  const result = await executeJsonRequest(
@@ -193,6 +241,7 @@ async function executeRetrySafeSendRequest(url, buildInit, {
193
241
  warn
194
242
  }
195
243
  );
244
+ clearAmbiguousSendKey(retryFingerprint);
196
245
  return {
197
246
  ...result,
198
247
  idempotencyKey,
@@ -206,6 +255,7 @@ async function executeRetrySafeSendRequest(url, buildInit, {
206
255
  );
207
256
  }
208
257
  }
258
+ rememberAmbiguousSendKey(retryFingerprint, idempotencyKey, now(), retryFingerprintTtlMs);
209
259
  throw lastError;
210
260
  }
211
261
  function describeRetryReason(error) {
@@ -578,7 +628,12 @@ if (!deprecatedShimMode && !runtimeActionsOnlyMode) {
578
628
  }),
579
629
  {
580
630
  target,
581
- fetchImpl: bridgeFetch
631
+ fetchImpl: bridgeFetch,
632
+ retryFingerprint: buildSendRetryFingerprint({
633
+ target,
634
+ content,
635
+ attachmentIds: attachment_ids
636
+ })
582
637
  }
583
638
  );
584
639
  if (!res.ok) {
@@ -4410,6 +4410,17 @@ Success = user starts useful collaboration and setup progresses,
4410
4410
  not finishing a long onboarding conversation in one channel.
4411
4411
  `;
4412
4412
  }
4413
+ function createRuntimeTraceCounters() {
4414
+ return {
4415
+ events: 0,
4416
+ toolCalls: 0,
4417
+ toolOutputs: 0,
4418
+ compactionStarts: 0,
4419
+ compactionFinishes: 0,
4420
+ textEvents: 0,
4421
+ thinkingEvents: 0
4422
+ };
4423
+ }
4413
4424
  function createGatedSteeringState() {
4414
4425
  return {
4415
4426
  phase: "idle",
@@ -4588,10 +4599,113 @@ function buildRuntimeStallDiagnostic(ap, staleForMs, staleForMinutes) {
4588
4599
  outstandingToolUses: ap.gatedSteering.outstandingToolUses,
4589
4600
  compacting: ap.gatedSteering.compacting,
4590
4601
  recentStderrCount: ap.recentStderr.length,
4591
- recentStdoutCount: ap.recentStdout.length
4602
+ recentStdoutCount: ap.recentStdout.length,
4603
+ ...runtimeTraceCounterAttrs(ap)
4592
4604
  }
4593
4605
  };
4594
4606
  }
4607
+ function bucketBytes(value) {
4608
+ const bytes = typeof value === "string" ? Buffer.byteLength(value, "utf8") : Math.max(0, Math.floor(value ?? 0));
4609
+ if (bytes === 0) return "0";
4610
+ if (bytes < 1024) return "<1KB";
4611
+ if (bytes < 10 * 1024) return "1KB-10KB";
4612
+ if (bytes < 100 * 1024) return "10KB-100KB";
4613
+ if (bytes < 1024 * 1024) return "100KB-1MB";
4614
+ return "1MB+";
4615
+ }
4616
+ function attachmentBytesBucket(bytes, knownCount) {
4617
+ return knownCount > 0 ? bucketBytes(bytes) : "unknown";
4618
+ }
4619
+ function summarizeMessageInputBytes(messages) {
4620
+ if (!messages || messages.length === 0) {
4621
+ return {
4622
+ runtime_input_messages_count: 0,
4623
+ runtime_input_messages_content_bytes_bucket: "0",
4624
+ runtime_input_attachments_count: 0,
4625
+ runtime_input_image_attachments_count: 0,
4626
+ runtime_input_attachments_size_known_count: 0,
4627
+ runtime_input_attachments_bytes_bucket: "0",
4628
+ runtime_input_image_attachments_size_known_count: 0,
4629
+ runtime_input_image_attachments_bytes_bucket: "0",
4630
+ runtime_input_largest_attachment_bytes_bucket: "0",
4631
+ runtime_input_thread_context_messages_count: 0,
4632
+ runtime_input_thread_context_content_bytes_bucket: "0"
4633
+ };
4634
+ }
4635
+ let contentBytes = 0;
4636
+ let attachmentCount = 0;
4637
+ let imageAttachmentCount = 0;
4638
+ let attachmentSizeKnownCount = 0;
4639
+ let attachmentBytes = 0;
4640
+ let imageAttachmentSizeKnownCount = 0;
4641
+ let imageAttachmentBytes = 0;
4642
+ let largestAttachmentBytes = 0;
4643
+ let threadContextMessages = 0;
4644
+ let threadContextContentBytes = 0;
4645
+ for (const message of messages) {
4646
+ contentBytes += Buffer.byteLength(message.content || "", "utf8");
4647
+ for (const attachment of message.attachments || []) {
4648
+ attachmentCount++;
4649
+ if (typeof attachment.sizeBytes === "number" && Number.isFinite(attachment.sizeBytes) && attachment.sizeBytes >= 0) {
4650
+ attachmentSizeKnownCount++;
4651
+ attachmentBytes += attachment.sizeBytes;
4652
+ largestAttachmentBytes = Math.max(largestAttachmentBytes, attachment.sizeBytes);
4653
+ }
4654
+ if (attachment.mimeType?.startsWith("image/")) {
4655
+ imageAttachmentCount++;
4656
+ if (typeof attachment.sizeBytes === "number" && Number.isFinite(attachment.sizeBytes) && attachment.sizeBytes >= 0) {
4657
+ imageAttachmentSizeKnownCount++;
4658
+ imageAttachmentBytes += attachment.sizeBytes;
4659
+ }
4660
+ }
4661
+ }
4662
+ const joinContext = message.thread_join_context;
4663
+ if (joinContext) {
4664
+ const contextMessages = [joinContext.parent_message, ...joinContext.recent_messages];
4665
+ threadContextMessages += contextMessages.length;
4666
+ for (const contextMessage of contextMessages) {
4667
+ threadContextContentBytes += Buffer.byteLength(contextMessage.content || "", "utf8");
4668
+ }
4669
+ }
4670
+ }
4671
+ return {
4672
+ runtime_input_messages_count: messages.length,
4673
+ runtime_input_messages_content_bytes_bucket: bucketBytes(contentBytes),
4674
+ runtime_input_attachments_count: attachmentCount,
4675
+ runtime_input_image_attachments_count: imageAttachmentCount,
4676
+ runtime_input_attachments_size_known_count: attachmentSizeKnownCount,
4677
+ runtime_input_attachments_bytes_bucket: attachmentCount > 0 ? attachmentBytesBucket(attachmentBytes, attachmentSizeKnownCount) : "0",
4678
+ runtime_input_image_attachments_size_known_count: imageAttachmentSizeKnownCount,
4679
+ runtime_input_image_attachments_bytes_bucket: imageAttachmentCount > 0 ? attachmentBytesBucket(imageAttachmentBytes, imageAttachmentSizeKnownCount) : "0",
4680
+ runtime_input_largest_attachment_bytes_bucket: attachmentCount > 0 ? attachmentBytesBucket(largestAttachmentBytes, attachmentSizeKnownCount) : "0",
4681
+ runtime_input_thread_context_messages_count: threadContextMessages,
4682
+ runtime_input_thread_context_content_bytes_bucket: bucketBytes(threadContextContentBytes)
4683
+ };
4684
+ }
4685
+ function buildRuntimeInputTraceAttrs(opts) {
4686
+ return {
4687
+ runtime_input_source: opts.source,
4688
+ runtime_input_prompt_bytes_bucket: bucketBytes(opts.prompt),
4689
+ runtime_input_standing_prompt_bytes_bucket: bucketBytes(opts.standingPrompt),
4690
+ runtime_input_resume_prompt_present: Boolean(opts.resumePrompt),
4691
+ runtime_input_resume_prompt_bytes_bucket: bucketBytes(opts.resumePrompt),
4692
+ runtime_input_session_present: opts.sessionIdPresent,
4693
+ runtime_input_native_standing_prompt_present: opts.nativeStandingPrompt,
4694
+ runtime_input_unread_channels_count: opts.unreadSummary ? Object.keys(opts.unreadSummary).length : 0,
4695
+ ...summarizeMessageInputBytes(opts.messages)
4696
+ };
4697
+ }
4698
+ function runtimeTraceCounterAttrs(ap) {
4699
+ return {
4700
+ runtime_events_count: ap.runtimeTraceCounters.events,
4701
+ runtime_tool_calls_count: ap.runtimeTraceCounters.toolCalls,
4702
+ runtime_tool_outputs_count: ap.runtimeTraceCounters.toolOutputs,
4703
+ runtime_compaction_starts_count: ap.runtimeTraceCounters.compactionStarts,
4704
+ runtime_compaction_finishes_count: ap.runtimeTraceCounters.compactionFinishes,
4705
+ runtime_text_events_count: ap.runtimeTraceCounters.textEvents,
4706
+ runtime_thinking_events_count: ap.runtimeTraceCounters.thinkingEvents
4707
+ };
4708
+ }
4595
4709
  function getMessageDeliveryText(driver) {
4596
4710
  return driver.supportsStdinNotification ? "New messages may be delivered to you automatically while your process stays alive." : "The daemon will automatically restart you when new messages arrive.";
4597
4711
  }
@@ -4916,17 +5030,21 @@ var AgentProcessManager = class _AgentProcessManager {
4916
5030
  const isResume = !!runtimeConfig.sessionId;
4917
5031
  const standingPrompt = driver.buildSystemPrompt(runtimeConfig, agentId);
4918
5032
  let prompt;
5033
+ let promptSource;
4919
5034
  if (runtimeConfig.runtimeProfileControl && !wakeMessage) {
4920
5035
  prompt = driver.supportsNativeStandingPrompt ? NATIVE_STANDING_PROMPT_STARTUP_INPUT : formatRuntimeProfileControlStartupInput(runtimeConfig.runtimeProfileControl, driver);
5036
+ promptSource = "runtime_profile_control";
4921
5037
  } else if (isResume && resumePrompt) {
4922
5038
  prompt = resumePrompt;
4923
5039
  prompt += getBusyDeliveryNote(driver);
5040
+ promptSource = "resume_prompt";
4924
5041
  } else if (wakeMessage) {
4925
5042
  const runtimeProfileControlPrompt = formatRuntimeProfileControlPrompt([wakeMessage]);
4926
5043
  const channelLabel = formatChannelLabel(wakeMessage);
4927
5044
  prompt = runtimeProfileControlPrompt ?? `New message received:
4928
5045
 
4929
5046
  ${formatIncomingMessage(wakeMessage, driver)}`;
5047
+ promptSource = runtimeProfileControlPrompt ? "runtime_profile_control_message" : "wake_message";
4930
5048
  if (!runtimeProfileControlPrompt && unreadSummary && Object.keys(unreadSummary).length > 0) {
4931
5049
  const otherUnread = Object.entries(unreadSummary).filter(([key]) => key !== channelLabel);
4932
5050
  if (otherUnread.length > 0) {
@@ -4960,12 +5078,25 @@ IMPORTANT: If the message requires multi-step work (e.g. research, code changes,
4960
5078
  prompt += `
4961
5079
 
4962
5080
  Use ${communicationCommand(driver, "read_history")} to catch up on the channels listed above, then stop. Read each listed channel at most once unless a read fails. Do NOT call ${communicationCommand(driver, "check_messages")} in this mode. If the history reveals a direct request, assignment, @mention, review request, or task clearly addressed to you, switch into active handling instead of stopping: ${dynamicReplyInstruction(driver)} and ${dynamicClaimInstruction(driver)} before starting work. Otherwise, do NOT send any message in this mode. ${getMessageDeliveryText(driver)}`;
5081
+ promptSource = "resume_unread_summary";
4963
5082
  } else if (isResume) {
4964
5083
  prompt = `No new messages while you were away. Nothing to do \u2014 just stop. ${getMessageDeliveryText(driver)}`;
4965
5084
  prompt += getBusyDeliveryNote(driver);
5085
+ promptSource = "resume_empty";
4966
5086
  } else {
4967
5087
  prompt = driver.supportsNativeStandingPrompt ? NATIVE_STANDING_PROMPT_STARTUP_INPUT : standingPrompt;
5088
+ promptSource = "cold_start";
4968
5089
  }
5090
+ const runtimeInputTraceAttrs = buildRuntimeInputTraceAttrs({
5091
+ source: promptSource,
5092
+ prompt,
5093
+ standingPrompt,
5094
+ resumePrompt,
5095
+ messages: wakeMessage ? [wakeMessage] : void 0,
5096
+ unreadSummary,
5097
+ sessionIdPresent: isResume,
5098
+ nativeStandingPrompt: Boolean(driver.supportsNativeStandingPrompt)
5099
+ });
4969
5100
  const effectiveConfig = await this.buildSpawnConfig(agentId, runtimeConfig);
4970
5101
  const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !runtimeConfig.runtimeProfileControl && (!unreadSummary || Object.keys(unreadSummary).length === 0);
4971
5102
  if (canDeferEmptyStart) {
@@ -5026,6 +5157,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
5026
5157
  lastRuntimeEventAt: Date.now(),
5027
5158
  runtimeProgressStaleSince: null,
5028
5159
  runtimeTraceSpan: null,
5160
+ runtimeTraceCounters: createRuntimeTraceCounters(),
5029
5161
  lastActivity: "",
5030
5162
  lastActivityDetail: "",
5031
5163
  activityClientSeq: 0,
@@ -5047,7 +5179,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
5047
5179
  sessionId: effectiveConfig.sessionId || null,
5048
5180
  launchId: launchId || null
5049
5181
  });
5050
- this.startRuntimeTrace(agentId, agentProcess, "spawn", wakeMessage ? [wakeMessage] : void 0);
5182
+ this.startRuntimeTrace(agentId, agentProcess, "spawn", wakeMessage ? [wakeMessage] : void 0, runtimeInputTraceAttrs);
5051
5183
  this.agentsStarting.delete(agentId);
5052
5184
  if (config.runtimeProfileControl) {
5053
5185
  this.ackInjectedRuntimeProfileControl(agentId, config.runtimeProfileControl, agentProcess.launchId);
@@ -5141,6 +5273,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
5141
5273
  expectedTerminationReason: ap.expectedTerminationReason || void 0,
5142
5274
  exitCode: finalCode,
5143
5275
  exitSignal: finalSignal,
5276
+ ...runtimeTraceCounterAttrs(ap),
5144
5277
  ...this.finalizeRuntimeProfileTurnControl(agentId, ap, "process_exit")
5145
5278
  });
5146
5279
  if (processEndedCleanly) {
@@ -5993,6 +6126,12 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
5993
6126
  /**
5994
6127
  * Broadcast an activity change — emits a single agent:activity event that carries
5995
6128
  * both the status (for the dot indicator) and trajectory entries (for the activity log).
6129
+ *
6130
+ * TODO(lifecycle-v2/daemon-protocol): split this legacy frame into
6131
+ * structured lifecycle producers. Runtime progress, transient heartbeat,
6132
+ * provider/runtime error, process exit, and user-visible activity entries
6133
+ * should carry explicit reason/correlation/window attrs so the server no
6134
+ * longer infers lifecycle semantics from generic activity strings.
5996
6135
  */
5997
6136
  broadcastActivity(agentId, activity, detail, extraTrajectory = [], launchIdOverride) {
5998
6137
  const ap = this.agents.get(agentId);
@@ -6218,8 +6357,9 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6218
6357
  runtime_profile_turn_outcome: control.kind === "migration" ? control.migrationDoneToolObserved ? "migration_done_observed" : "missing_migration_done" : "notice_only"
6219
6358
  };
6220
6359
  }
6221
- startRuntimeTrace(agentId, ap, reason, messages) {
6360
+ startRuntimeTrace(agentId, ap, reason, messages, inputTraceAttrs = {}) {
6222
6361
  if (ap.runtimeTraceSpan) return ap.runtimeTraceSpan;
6362
+ ap.runtimeTraceCounters = createRuntimeTraceCounters();
6223
6363
  const messageControl = this.runtimeProfileTurnControlFromMessages(messages);
6224
6364
  if (messageControl) {
6225
6365
  this.activateRuntimeProfileTurnControl(ap, messageControl);
@@ -6234,12 +6374,14 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6234
6374
  reason,
6235
6375
  hasSession: Boolean(ap.sessionId),
6236
6376
  ...this.messagesTraceAttrs(messages),
6377
+ ...inputTraceAttrs,
6237
6378
  ...this.runtimeProfileTurnControlTraceAttrs(ap.runtimeProfileTurnControl)
6238
6379
  }
6239
6380
  });
6240
6381
  span.addEvent("daemon.turn.started", {
6241
6382
  reason,
6242
6383
  ...this.messagesTraceAttrs(messages),
6384
+ ...inputTraceAttrs,
6243
6385
  ...this.runtimeProfileTurnControlTraceAttrs(ap.runtimeProfileTurnControl)
6244
6386
  });
6245
6387
  ap.runtimeTraceSpan = span;
@@ -6348,6 +6490,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6348
6490
  lastActivity: ap.lastActivity,
6349
6491
  lastActivityDetailPresent: Boolean(ap.lastActivityDetail),
6350
6492
  lastActivityDetailKind: classifyActivityDetailForTrace(ap.lastActivityDetail),
6493
+ ...runtimeTraceCounterAttrs(ap),
6351
6494
  ...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_stalled")
6352
6495
  });
6353
6496
  this.broadcastActivity(agentId, "error", diagnostic.detail);
@@ -6380,6 +6523,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6380
6523
  lastActivityDetailKind: classifyActivityDetailForTrace(ap.lastActivityDetail),
6381
6524
  pendingMessages: ap.inbox.length,
6382
6525
  recovery: "terminate_for_queued_message",
6526
+ ...runtimeTraceCounterAttrs(ap),
6383
6527
  ...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_stalled")
6384
6528
  });
6385
6529
  ap.expectedTerminationReason = "stalled_recovery";
@@ -6407,6 +6551,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6407
6551
  const ap = this.agents.get(agentId);
6408
6552
  if (ap) {
6409
6553
  const wasStalled = Boolean(ap.runtimeProgressStaleSince);
6554
+ this.noteRuntimeTraceCounter(ap, event);
6410
6555
  this.recordRuntimeTraceEvent(agentId, ap, "runtime.event.received", { kind: event.kind });
6411
6556
  if (wasStalled) {
6412
6557
  this.recordRuntimeTraceEvent(agentId, ap, "runtime.progress.observed", { afterStall: true });
@@ -6534,6 +6679,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6534
6679
  }
6535
6680
  this.endRuntimeTrace(ap, "ok", {
6536
6681
  outcome: "turn-completed",
6682
+ ...runtimeTraceCounterAttrs(ap),
6537
6683
  ...this.finalizeRuntimeProfileTurnControl(agentId, ap, "turn_end")
6538
6684
  });
6539
6685
  if (ap.driver.terminateProcessOnTurnEnd) {
@@ -6575,10 +6721,14 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6575
6721
  `[Agent ${agentId}] Disabled Claude tool-boundary gated steering after thinking-block mutation error; lastFlushReason=${ap.gatedSteering.lastFlushReason || "none"}`
6576
6722
  );
6577
6723
  }
6578
- this.recordRuntimeTraceEvent(agentId, ap, "runtime.error", runtimeErrorDiagnostics.eventAttrs);
6724
+ this.recordRuntimeTraceEvent(agentId, ap, "runtime.error", {
6725
+ ...runtimeErrorDiagnostics.eventAttrs,
6726
+ ...runtimeTraceCounterAttrs(ap)
6727
+ });
6579
6728
  this.endRuntimeTrace(ap, "error", {
6580
6729
  outcome: "runtime-error",
6581
6730
  ...runtimeErrorDiagnostics.spanAttrs,
6731
+ ...runtimeTraceCounterAttrs(ap),
6582
6732
  ...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_error")
6583
6733
  });
6584
6734
  if (ap.driver.supportsStdinNotification && classifyTerminalFailure(ap)) {
@@ -6601,6 +6751,29 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
6601
6751
  sendAgentStatus(agentId, status, launchId) {
6602
6752
  this.sendToServer({ type: "agent:status", agentId, status, launchId: launchId || void 0 });
6603
6753
  }
6754
+ noteRuntimeTraceCounter(ap, event) {
6755
+ ap.runtimeTraceCounters.events++;
6756
+ switch (event.kind) {
6757
+ case "tool_call":
6758
+ ap.runtimeTraceCounters.toolCalls++;
6759
+ break;
6760
+ case "tool_output":
6761
+ ap.runtimeTraceCounters.toolOutputs++;
6762
+ break;
6763
+ case "compaction_started":
6764
+ ap.runtimeTraceCounters.compactionStarts++;
6765
+ break;
6766
+ case "compaction_finished":
6767
+ ap.runtimeTraceCounters.compactionFinishes++;
6768
+ break;
6769
+ case "text":
6770
+ ap.runtimeTraceCounters.textEvents++;
6771
+ break;
6772
+ case "thinking":
6773
+ ap.runtimeTraceCounters.thinkingEvents++;
6774
+ break;
6775
+ }
6776
+ }
6604
6777
  /** Send a batched notification to the agent via stdin about pending messages */
6605
6778
  sendStdinNotification(agentId) {
6606
6779
  const ap = this.agents.get(agentId);
@@ -6703,6 +6876,14 @@ ${messages.map((message) => formatIncomingMessage(message, ap.driver)).join("\n"
6703
6876
 
6704
6877
  Respond as appropriate. Complete all your work before stopping.
6705
6878
  ${RESPONSE_TARGET_HINT}`);
6879
+ const inputTraceAttrs = buildRuntimeInputTraceAttrs({
6880
+ source: `stdin_${mode}_delivery`,
6881
+ prompt,
6882
+ messages,
6883
+ sessionIdPresent: Boolean(ap.sessionId),
6884
+ nativeStandingPrompt: Boolean(ap.driver.supportsNativeStandingPrompt)
6885
+ });
6886
+ this.recordRuntimeTraceEvent(agentId, ap, "runtime.input.prepared", inputTraceAttrs);
6706
6887
  const encoded = ap.driver.encodeStdinMessage(prompt, ap.sessionId, { mode });
6707
6888
  if (!encoded) {
6708
6889
  ap.inbox.unshift(...messages);
@@ -6714,6 +6895,7 @@ ${RESPONSE_TARGET_HINT}`);
6714
6895
  );
6715
6896
  this.recordDaemonTrace("daemon.agent.stdin_delivery", {
6716
6897
  ...traceAttrs,
6898
+ ...inputTraceAttrs,
6717
6899
  outcome: "encode_failed",
6718
6900
  requeued_messages_count: messages.length
6719
6901
  }, "error");
@@ -6730,6 +6912,7 @@ ${RESPONSE_TARGET_HINT}`);
6730
6912
  this.ackInjectedRuntimeProfileMessages(agentId, messages, ap.launchId);
6731
6913
  this.recordDaemonTrace("daemon.agent.stdin_delivery", {
6732
6914
  ...traceAttrs,
6915
+ ...inputTraceAttrs,
6733
6916
  outcome: "written",
6734
6917
  stdin_write_attempted: true
6735
6918
  });
package/dist/core.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  resolveSlockCliPath,
10
10
  resolveWorkspaceDirectoryPath,
11
11
  scanWorkspaceDirectories
12
- } from "./chunk-EDE2E6QR.js";
12
+ } from "./chunk-RDRY2MW2.js";
13
13
  import {
14
14
  subscribeDaemonLogs
15
15
  } from "./chunk-B7XIMLOT.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-EDE2E6QR.js";
6
+ } from "./chunk-RDRY2MW2.js";
7
7
  import "./chunk-B7XIMLOT.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.48.0",
3
+ "version": "0.48.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "slock-daemon": "dist/index.js"