@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.
- package/dist/chat-bridge.js +58 -3
- package/dist/{chunk-EDE2E6QR.js → chunk-RDRY2MW2.js} +187 -4
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/chat-bridge.js
CHANGED
|
@@ -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
|
|
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",
|
|
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
package/dist/index.js
CHANGED