@slock-ai/daemon 0.57.1 → 0.57.2
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/{chunk-6RZCYFJP.js → chunk-EKSATDT3.js} +401 -48
- package/dist/cli/index.js +80 -5
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -351,40 +351,127 @@ var NoopActiveSpan = class {
|
|
|
351
351
|
}
|
|
352
352
|
};
|
|
353
353
|
var noopTracer = new NoopTracer();
|
|
354
|
-
function
|
|
354
|
+
function projectTraceScopeAttrs(scope) {
|
|
355
|
+
const attrs = {};
|
|
356
|
+
addOptionalStringAttr(attrs, "daemon_version", scope.resource?.daemonVersion);
|
|
357
|
+
addPresenceAttr(attrs, "daemon_version_present", scope.resource?.daemonVersion);
|
|
358
|
+
addOptionalStringAttr(attrs, "computer_version", scope.resource?.computerVersion);
|
|
359
|
+
addPresenceAttr(attrs, "computer_version_present", scope.resource?.computerVersion);
|
|
360
|
+
addOptionalStringAttr(attrs, "deployment_environment", scope.resource?.deploymentEnvironment);
|
|
361
|
+
addOptionalStringAttr(attrs, "service_revision", scope.resource?.serviceRevision);
|
|
362
|
+
addOptionalStringAttr(attrs, "request_id", scope.request?.requestId);
|
|
363
|
+
addPresenceAttr(attrs, "request_id_present", scope.request?.requestId);
|
|
364
|
+
addOptionalStringAttr(attrs, "route_pattern", scope.request?.routePattern);
|
|
365
|
+
addOptionalStringAttr(attrs, "method", scope.request?.method);
|
|
366
|
+
addOptionalStringAttr(attrs, "caller_kind", scope.request?.callerKind);
|
|
367
|
+
if (typeof scope.request?.userIdPresent === "boolean") {
|
|
368
|
+
attrs.user_id_present = scope.request.userIdPresent;
|
|
369
|
+
}
|
|
370
|
+
addOptionalStringAttr(attrs, "server_id", scope.actor?.serverId);
|
|
371
|
+
addPresenceAttr(attrs, "server_id_present", scope.actor?.serverId, scope.actor?.serverIdPresent);
|
|
372
|
+
addOptionalStringAttr(attrs, "machine_id", scope.actor?.machineId);
|
|
373
|
+
addPresenceAttr(attrs, "machine_id_present", scope.actor?.machineId, scope.actor?.machineIdPresent);
|
|
374
|
+
addOptionalStringAttr(attrs, "agent_id", scope.actor?.agentId);
|
|
375
|
+
addPresenceAttr(attrs, "agent_id_present", scope.actor?.agentId, scope.actor?.agentIdPresent);
|
|
376
|
+
addOptionalStringAttr(attrs, "launch_id", scope.actor?.launchId);
|
|
377
|
+
addPresenceAttr(attrs, "launch_id_present", scope.actor?.launchId, scope.actor?.launchIdPresent);
|
|
378
|
+
addOptionalStringAttr(attrs, "session_id", scope.actor?.sessionId);
|
|
379
|
+
addPresenceAttr(attrs, "session_id_present", scope.actor?.sessionId, scope.actor?.sessionIdPresent);
|
|
380
|
+
return attrs;
|
|
381
|
+
}
|
|
382
|
+
function createTraceScopeTracer(tracer, scope, options = {}) {
|
|
383
|
+
const scopedTracer = createScopedTracer(tracer, projectTraceScopeAttrs(scope), {
|
|
384
|
+
attrPrecedence: options.scopeAttrPrecedence
|
|
385
|
+
});
|
|
386
|
+
return options.spanAttrContracts ? createSpanAttrContractTracer(scopedTracer, options.spanAttrContracts) : scopedTracer;
|
|
387
|
+
}
|
|
388
|
+
function createScopedTracer(tracer, scopeAttrs, options = {}) {
|
|
355
389
|
if (!Object.keys(scopeAttrs).length) return tracer;
|
|
356
|
-
return new ScopedTracer(tracer, scopeAttrs);
|
|
390
|
+
return new ScopedTracer(tracer, scopeAttrs, options.attrPrecedence ?? "scope");
|
|
357
391
|
}
|
|
358
392
|
var ScopedTracer = class {
|
|
359
|
-
constructor(tracer, scopeAttrs) {
|
|
393
|
+
constructor(tracer, scopeAttrs, attrPrecedence) {
|
|
360
394
|
this.tracer = tracer;
|
|
361
395
|
this.scopeAttrs = scopeAttrs;
|
|
396
|
+
this.attrPrecedence = attrPrecedence;
|
|
362
397
|
}
|
|
363
398
|
startSpan(name, options) {
|
|
364
399
|
const span = this.tracer.startSpan(name, {
|
|
365
400
|
...options,
|
|
366
|
-
attrs:
|
|
401
|
+
attrs: this.mergeScopeAttrs(options.attrs)
|
|
367
402
|
});
|
|
368
|
-
return new ScopedActiveSpan(span, this.scopeAttrs);
|
|
403
|
+
return new ScopedActiveSpan(span, this.scopeAttrs, this.attrPrecedence);
|
|
404
|
+
}
|
|
405
|
+
mergeScopeAttrs(attrs) {
|
|
406
|
+
return this.attrPrecedence === "caller" ? mergeAttrs(this.scopeAttrs, attrs) : mergeAttrs(attrs, this.scopeAttrs);
|
|
369
407
|
}
|
|
370
408
|
};
|
|
371
409
|
var ScopedActiveSpan = class {
|
|
372
|
-
constructor(span, scopeAttrs) {
|
|
410
|
+
constructor(span, scopeAttrs, attrPrecedence) {
|
|
373
411
|
this.span = span;
|
|
374
412
|
this.scopeAttrs = scopeAttrs;
|
|
413
|
+
this.attrPrecedence = attrPrecedence;
|
|
375
414
|
this.context = span.context;
|
|
376
415
|
}
|
|
377
416
|
context;
|
|
378
417
|
addEvent(name, attrs) {
|
|
379
|
-
this.span.addEvent(name,
|
|
418
|
+
this.span.addEvent(name, this.mergeScopeAttrs(attrs));
|
|
380
419
|
}
|
|
381
420
|
end(status, options) {
|
|
382
421
|
this.span.end(status, options ? {
|
|
383
422
|
...options,
|
|
384
|
-
attrs:
|
|
423
|
+
attrs: this.mergeScopeAttrs(options.attrs)
|
|
385
424
|
} : void 0);
|
|
386
425
|
}
|
|
426
|
+
mergeScopeAttrs(attrs) {
|
|
427
|
+
return this.attrPrecedence === "caller" ? mergeAttrs(this.scopeAttrs, attrs) : mergeAttrs(attrs, this.scopeAttrs);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
function createSpanAttrContractTracer(tracer, contracts) {
|
|
431
|
+
if (!Object.keys(contracts).length) return tracer;
|
|
432
|
+
return new SpanAttrContractTracer(tracer, contracts);
|
|
433
|
+
}
|
|
434
|
+
var SpanAttrContractTracer = class {
|
|
435
|
+
constructor(tracer, contracts) {
|
|
436
|
+
this.tracer = tracer;
|
|
437
|
+
this.contracts = contracts;
|
|
438
|
+
}
|
|
439
|
+
startSpan(name, options) {
|
|
440
|
+
const contract = this.contracts[name];
|
|
441
|
+
if (!contract) return this.tracer.startSpan(name, options);
|
|
442
|
+
const span = this.tracer.startSpan(name, {
|
|
443
|
+
...options,
|
|
444
|
+
attrs: filterTraceAttrs(options.attrs, contract.spanAttrs)
|
|
445
|
+
});
|
|
446
|
+
return new SpanAttrContractActiveSpan(span, contract);
|
|
447
|
+
}
|
|
387
448
|
};
|
|
449
|
+
var SpanAttrContractActiveSpan = class {
|
|
450
|
+
constructor(span, contract) {
|
|
451
|
+
this.span = span;
|
|
452
|
+
this.contract = contract;
|
|
453
|
+
this.context = span.context;
|
|
454
|
+
}
|
|
455
|
+
context;
|
|
456
|
+
addEvent(name, attrs) {
|
|
457
|
+
this.span.addEvent(name, filterTraceAttrs(attrs, this.contract.eventAttrs?.[name]));
|
|
458
|
+
}
|
|
459
|
+
end(status, options) {
|
|
460
|
+
this.span.end(status, options ? {
|
|
461
|
+
...options,
|
|
462
|
+
attrs: filterTraceAttrs(options.attrs, this.contract.endAttrs)
|
|
463
|
+
} : void 0);
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
function filterTraceAttrs(attrs, allowedKeys) {
|
|
467
|
+
if (!attrs || !allowedKeys) return attrs;
|
|
468
|
+
const allowed = new Set(allowedKeys);
|
|
469
|
+
const filtered = {};
|
|
470
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
471
|
+
if (allowed.has(key)) filtered[key] = value;
|
|
472
|
+
}
|
|
473
|
+
return Object.keys(filtered).length ? filtered : void 0;
|
|
474
|
+
}
|
|
388
475
|
var BasicTracer = class {
|
|
389
476
|
sink;
|
|
390
477
|
clock;
|
|
@@ -482,6 +569,14 @@ function mergeAttrs(base, extra) {
|
|
|
482
569
|
if (!extra) return base;
|
|
483
570
|
return { ...base, ...extra };
|
|
484
571
|
}
|
|
572
|
+
function addOptionalStringAttr(attrs, key, value) {
|
|
573
|
+
const normalized = value?.trim();
|
|
574
|
+
if (!normalized) return;
|
|
575
|
+
attrs[key] = normalized;
|
|
576
|
+
}
|
|
577
|
+
function addPresenceAttr(attrs, key, value, explicitPresent) {
|
|
578
|
+
attrs[key] = typeof explicitPresent === "boolean" ? explicitPresent : Boolean(value?.trim());
|
|
579
|
+
}
|
|
485
580
|
function generateTraceId() {
|
|
486
581
|
return randomNonZeroHex(TRACE_ID_HEX_LENGTH);
|
|
487
582
|
}
|
|
@@ -1046,6 +1141,9 @@ var SERVER_CAPABILITY_MATRIX = {
|
|
|
1046
1141
|
|
|
1047
1142
|
// ../shared/src/index.ts
|
|
1048
1143
|
var RUNTIME_CONFIG_VERSION = 1;
|
|
1144
|
+
var EXTERNAL_AGENT_RUNTIME_ID = "external";
|
|
1145
|
+
var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
|
|
1146
|
+
var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
|
|
1049
1147
|
var RUNTIMES = [
|
|
1050
1148
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
1051
1149
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
@@ -1058,6 +1156,9 @@ var RUNTIMES = [
|
|
|
1058
1156
|
{ id: "pi", displayName: "Pi", binary: "pi", supported: true }
|
|
1059
1157
|
];
|
|
1060
1158
|
var RUNTIME_MODELS = {
|
|
1159
|
+
[EXTERNAL_AGENT_RUNTIME_ID]: [
|
|
1160
|
+
{ id: EXTERNAL_AGENT_RUNTIME_MODEL, label: EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME }
|
|
1161
|
+
],
|
|
1061
1162
|
claude: [
|
|
1062
1163
|
{ id: "opus", label: "Claude Opus" },
|
|
1063
1164
|
{ id: "claude-opus-4-8", label: "Claude Opus 4.8" },
|
|
@@ -7381,16 +7482,19 @@ var RuntimeProgressState = class {
|
|
|
7381
7482
|
};
|
|
7382
7483
|
|
|
7383
7484
|
// src/runtimeNotificationState.ts
|
|
7485
|
+
function inboxNoticeMessageIdentity(message) {
|
|
7486
|
+
const seq = typeof message.seq === "number" && Number.isFinite(message.seq) && message.seq > 0 ? Math.floor(message.seq) : null;
|
|
7487
|
+
if (seq !== null) {
|
|
7488
|
+
return `s:${seq}`;
|
|
7489
|
+
}
|
|
7490
|
+
const id = typeof message.message_id === "string" && message.message_id.length > 0 ? message.message_id : typeof message.id === "string" && message.id.length > 0 ? message.id : "";
|
|
7491
|
+
return id.length > 0 ? `m:${id}` : "";
|
|
7492
|
+
}
|
|
7384
7493
|
function computeInboxNoticeFingerprint(messages) {
|
|
7385
7494
|
const keys = [];
|
|
7386
7495
|
for (const m of messages) {
|
|
7387
|
-
const
|
|
7388
|
-
if (
|
|
7389
|
-
keys.push(`s:${seq}`);
|
|
7390
|
-
continue;
|
|
7391
|
-
}
|
|
7392
|
-
const id = typeof m.message_id === "string" && m.message_id.length > 0 ? m.message_id : typeof m.id === "string" && m.id.length > 0 ? m.id : "";
|
|
7393
|
-
if (id.length > 0) keys.push(`m:${id}`);
|
|
7496
|
+
const key = inboxNoticeMessageIdentity(m);
|
|
7497
|
+
if (key.length > 0) keys.push(key);
|
|
7394
7498
|
}
|
|
7395
7499
|
if (keys.length === 0) return "";
|
|
7396
7500
|
keys.sort();
|
|
@@ -7401,6 +7505,10 @@ var RuntimeNotificationState = class {
|
|
|
7401
7505
|
pendingCountValue = 0;
|
|
7402
7506
|
lastNoticeFingerprint = null;
|
|
7403
7507
|
lastNoticeSessionId = null;
|
|
7508
|
+
lastEncodeFailedFingerprint = null;
|
|
7509
|
+
lastEncodeFailedSessionId = null;
|
|
7510
|
+
contributedSessionId = null;
|
|
7511
|
+
contributedIdentities = /* @__PURE__ */ new Set();
|
|
7404
7512
|
get pendingCount() {
|
|
7405
7513
|
return this.pendingCountValue;
|
|
7406
7514
|
}
|
|
@@ -7443,13 +7551,63 @@ var RuntimeNotificationState = class {
|
|
|
7443
7551
|
return this.lastNoticeFingerprint === fingerprint && this.lastNoticeSessionId === sessionId;
|
|
7444
7552
|
}
|
|
7445
7553
|
/** Register a fingerprint as written — call ONLY after a successful stdin write. */
|
|
7446
|
-
recordNoticeWritten(fingerprint, sessionId) {
|
|
7554
|
+
recordNoticeWritten(fingerprint, sessionId, messages = []) {
|
|
7447
7555
|
this.lastNoticeFingerprint = fingerprint;
|
|
7448
7556
|
this.lastNoticeSessionId = sessionId;
|
|
7557
|
+
this.lastEncodeFailedFingerprint = null;
|
|
7558
|
+
this.lastEncodeFailedSessionId = null;
|
|
7559
|
+
this.ensureContributionSession(sessionId);
|
|
7560
|
+
for (const message of messages) {
|
|
7561
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7562
|
+
if (identity.length > 0) {
|
|
7563
|
+
this.contributedIdentities.add(identity);
|
|
7564
|
+
}
|
|
7565
|
+
}
|
|
7566
|
+
}
|
|
7567
|
+
hasContributedMessage(message, sessionId) {
|
|
7568
|
+
if (this.contributedSessionId !== sessionId) return false;
|
|
7569
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7570
|
+
return identity.length > 0 && this.contributedIdentities.has(identity);
|
|
7571
|
+
}
|
|
7572
|
+
filterUncontributedMessages(messages, sessionId) {
|
|
7573
|
+
if (this.contributedSessionId !== sessionId || this.contributedIdentities.size === 0) {
|
|
7574
|
+
return [...messages];
|
|
7575
|
+
}
|
|
7576
|
+
return messages.filter((message) => {
|
|
7577
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7578
|
+
return identity.length === 0 || !this.contributedIdentities.has(identity);
|
|
7579
|
+
});
|
|
7580
|
+
}
|
|
7581
|
+
pruneContributedToPending(messages, sessionId) {
|
|
7582
|
+
this.ensureContributionSession(sessionId);
|
|
7583
|
+
if (this.contributedIdentities.size === 0) return;
|
|
7584
|
+
const pending = /* @__PURE__ */ new Set();
|
|
7585
|
+
for (const message of messages) {
|
|
7586
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7587
|
+
if (identity.length > 0) pending.add(identity);
|
|
7588
|
+
}
|
|
7589
|
+
for (const identity of this.contributedIdentities) {
|
|
7590
|
+
if (!pending.has(identity)) {
|
|
7591
|
+
this.contributedIdentities.delete(identity);
|
|
7592
|
+
}
|
|
7593
|
+
}
|
|
7594
|
+
}
|
|
7595
|
+
isDuplicateEncodeFailedNotice(fingerprint, sessionId) {
|
|
7596
|
+
if (fingerprint.length === 0) return false;
|
|
7597
|
+
return this.lastEncodeFailedFingerprint === fingerprint && this.lastEncodeFailedSessionId === sessionId;
|
|
7598
|
+
}
|
|
7599
|
+
recordNoticeEncodeFailed(fingerprint, sessionId) {
|
|
7600
|
+
if (fingerprint.length === 0) return;
|
|
7601
|
+
this.lastEncodeFailedFingerprint = fingerprint;
|
|
7602
|
+
this.lastEncodeFailedSessionId = sessionId;
|
|
7449
7603
|
}
|
|
7450
7604
|
clearNoticeFingerprint() {
|
|
7451
7605
|
this.lastNoticeFingerprint = null;
|
|
7452
7606
|
this.lastNoticeSessionId = null;
|
|
7607
|
+
this.lastEncodeFailedFingerprint = null;
|
|
7608
|
+
this.lastEncodeFailedSessionId = null;
|
|
7609
|
+
this.contributedSessionId = null;
|
|
7610
|
+
this.contributedIdentities.clear();
|
|
7453
7611
|
}
|
|
7454
7612
|
schedule(callback, delayMs) {
|
|
7455
7613
|
if (this.timerValue) return false;
|
|
@@ -7462,6 +7620,11 @@ var RuntimeNotificationState = class {
|
|
|
7462
7620
|
this.clearTimer();
|
|
7463
7621
|
return count;
|
|
7464
7622
|
}
|
|
7623
|
+
ensureContributionSession(sessionId) {
|
|
7624
|
+
if (this.contributedSessionId === sessionId) return;
|
|
7625
|
+
this.contributedSessionId = sessionId;
|
|
7626
|
+
this.contributedIdentities.clear();
|
|
7627
|
+
}
|
|
7465
7628
|
};
|
|
7466
7629
|
|
|
7467
7630
|
// src/agentProcessManager.ts
|
|
@@ -8605,6 +8768,7 @@ var RUNTIME_TELEMETRY_RESERVED_ATTR_KEYS = /* @__PURE__ */ new Set([
|
|
|
8605
8768
|
"sessionId",
|
|
8606
8769
|
"turnId",
|
|
8607
8770
|
"runtimeResultId",
|
|
8771
|
+
"runtimeResultIdSource",
|
|
8608
8772
|
"daemonVersion",
|
|
8609
8773
|
"daemon_version",
|
|
8610
8774
|
"daemon_version_present",
|
|
@@ -8780,13 +8944,33 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8780
8944
|
this.sendStdinNotification(agentId);
|
|
8781
8945
|
}, delayMs);
|
|
8782
8946
|
}
|
|
8947
|
+
flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, source) {
|
|
8948
|
+
if (ap.notifications.pendingCount === 0) return false;
|
|
8949
|
+
if (ap.isIdle) return false;
|
|
8950
|
+
if (!ap.sessionId) return false;
|
|
8951
|
+
if (!ap.driver.supportsStdinNotification) return false;
|
|
8952
|
+
if (ap.runtime.descriptor.busyDelivery !== "direct") return false;
|
|
8953
|
+
if (ap.gatedSteering.compacting) return false;
|
|
8954
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification.retry_signal", {
|
|
8955
|
+
agentId,
|
|
8956
|
+
runtime: ap.config.runtime,
|
|
8957
|
+
model: ap.config.model,
|
|
8958
|
+
launchId: ap.launchId || void 0,
|
|
8959
|
+
source,
|
|
8960
|
+
mode: "busy",
|
|
8961
|
+
pending_notification_count: ap.notifications.pendingCount,
|
|
8962
|
+
inbox_count: ap.inbox.length,
|
|
8963
|
+
session_id_present: true
|
|
8964
|
+
});
|
|
8965
|
+
return this.sendStdinNotification(agentId, { forceUnsupportedRetry: true });
|
|
8966
|
+
}
|
|
8783
8967
|
clearRuntimeErrorDeliveryBackoff(ap) {
|
|
8784
8968
|
if (ap.runtimeErrorDeliveryBackoff.timer) {
|
|
8785
8969
|
clearTimeout(ap.runtimeErrorDeliveryBackoff.timer);
|
|
8786
8970
|
}
|
|
8787
8971
|
ap.runtimeErrorDeliveryBackoff = createRuntimeErrorDeliveryBackoffState();
|
|
8788
8972
|
}
|
|
8789
|
-
|
|
8973
|
+
clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, resetSource) {
|
|
8790
8974
|
if (ap.runtimeErrorDeliveryBackoff.attempts === 0 && ap.runtimeErrorDeliveryBackoff.untilMs === 0) return;
|
|
8791
8975
|
const attempts = ap.runtimeErrorDeliveryBackoff.attempts;
|
|
8792
8976
|
const reason = ap.runtimeErrorDeliveryBackoff.reason;
|
|
@@ -8798,9 +8982,12 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8798
8982
|
launchId: ap.launchId || void 0,
|
|
8799
8983
|
reason: reason || void 0,
|
|
8800
8984
|
attempts,
|
|
8801
|
-
reset_source:
|
|
8985
|
+
reset_source: resetSource
|
|
8802
8986
|
});
|
|
8803
8987
|
}
|
|
8988
|
+
clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, eventKind) {
|
|
8989
|
+
this.clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, eventKind);
|
|
8990
|
+
}
|
|
8804
8991
|
runtimeErrorDeliveryBackoffRemainingMs(ap) {
|
|
8805
8992
|
return Math.max(0, ap.runtimeErrorDeliveryBackoff.untilMs - Date.now());
|
|
8806
8993
|
}
|
|
@@ -8828,8 +9015,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8828
9015
|
return "provider_connection_error";
|
|
8829
9016
|
case "ProviderStreamError":
|
|
8830
9017
|
return "provider_stream_error";
|
|
8831
|
-
|
|
9018
|
+
case "TimeoutError":
|
|
8832
9019
|
return null;
|
|
9020
|
+
default:
|
|
9021
|
+
return "runtime_error";
|
|
8833
9022
|
}
|
|
8834
9023
|
}
|
|
8835
9024
|
noteRuntimeErrorDeliveryBackoff(agentId, ap, message, terminalFailure, stickyTerminalFailure, reasonOverride) {
|
|
@@ -8900,9 +9089,24 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8900
9089
|
if (ap.inbox.length === 0) return false;
|
|
8901
9090
|
const reason = ap.runtimeErrorDeliveryBackoff.reason || "runtime_error_backoff";
|
|
8902
9091
|
if (ap.isIdle && ap.driver.supportsStdinNotification && ap.sessionId) {
|
|
8903
|
-
|
|
9092
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
9093
|
+
const messages = ap.notifications.filterUncontributedMessages(ap.inbox, ap.sessionId);
|
|
8904
9094
|
ap.notifications.clearPending();
|
|
8905
9095
|
ap.notifications.clearTimer();
|
|
9096
|
+
if (messages.length === 0) {
|
|
9097
|
+
this.recordDaemonTrace("daemon.agent.runtime_error_delivery_backoff.flush", {
|
|
9098
|
+
agentId,
|
|
9099
|
+
runtime: ap.config.runtime,
|
|
9100
|
+
model: ap.config.model,
|
|
9101
|
+
launchId: ap.launchId || void 0,
|
|
9102
|
+
reason,
|
|
9103
|
+
mode: "idle",
|
|
9104
|
+
outcome: "suppressed_already_contributed",
|
|
9105
|
+
inbox_count: ap.inbox.length,
|
|
9106
|
+
messages_count: 0
|
|
9107
|
+
});
|
|
9108
|
+
return false;
|
|
9109
|
+
}
|
|
8906
9110
|
this.commitApmIdleState(agentId, ap, false);
|
|
8907
9111
|
this.startRuntimeTrace(agentId, ap, "runtime-error-backoff-idle-delivery", messages);
|
|
8908
9112
|
this.broadcastActivity(agentId, "working", "Message received");
|
|
@@ -9583,6 +9787,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
9583
9787
|
runtimeProgress: new RuntimeProgressState(Date.now()),
|
|
9584
9788
|
runtimeTraceSpan: null,
|
|
9585
9789
|
runtimeTraceCounters: createRuntimeTraceCounters(),
|
|
9790
|
+
runtimeTelemetryResultSeq: 0,
|
|
9586
9791
|
lastActivity: "",
|
|
9587
9792
|
lastActivityDetail: "",
|
|
9588
9793
|
recentStdout: [],
|
|
@@ -10135,6 +10340,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
10135
10340
|
this.agents.delete(agentId);
|
|
10136
10341
|
if (!silent) {
|
|
10137
10342
|
this.activityClientSeqByAgent.delete(agentId);
|
|
10343
|
+
this.agentVisibleBoundaries.delete(agentId);
|
|
10344
|
+
this.agentVisibleMessageIds.delete(agentId);
|
|
10138
10345
|
}
|
|
10139
10346
|
this.runtimeExitTraceAttrs.set(ap.runtime, {
|
|
10140
10347
|
stop_source: silent ? "daemon_internal" : "explicit_request",
|
|
@@ -10358,6 +10565,25 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
10358
10565
|
}));
|
|
10359
10566
|
return true;
|
|
10360
10567
|
}
|
|
10568
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
10569
|
+
const noticeFingerprint = computeInboxNoticeFingerprint([message]);
|
|
10570
|
+
const messageAlreadyPending = noticeFingerprint.length > 0 && ap.inbox.some((pending) => computeInboxNoticeFingerprint([pending]) === noticeFingerprint);
|
|
10571
|
+
const messageAlreadyContributed = ap.notifications.hasContributedMessage(message, ap.sessionId);
|
|
10572
|
+
if (messageAlreadyPending && (messageAlreadyContributed || ap.notifications.isDuplicateNotice(noticeFingerprint, ap.sessionId))) {
|
|
10573
|
+
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
10574
|
+
outcome: "suppressed_duplicate_stdin_idle_delivery",
|
|
10575
|
+
accepted: true,
|
|
10576
|
+
process_present: true,
|
|
10577
|
+
runtime: ap.config.runtime,
|
|
10578
|
+
session_id_present: true,
|
|
10579
|
+
launchId: ap.launchId || void 0,
|
|
10580
|
+
is_idle: ap.isIdle,
|
|
10581
|
+
inbox_count: ap.inbox.length,
|
|
10582
|
+
pending_notification_count: ap.notifications.pendingCount
|
|
10583
|
+
}));
|
|
10584
|
+
logger.info(`[Agent ${agentId}] Suppressing duplicate idle stdin inbox update (unread-set unchanged since last write); pending=${ap.inbox.length}`);
|
|
10585
|
+
return true;
|
|
10586
|
+
}
|
|
10361
10587
|
ap.inbox.push(message);
|
|
10362
10588
|
const nextMessages = [...ap.inbox];
|
|
10363
10589
|
this.commitApmIdleState(agentId, ap, false);
|
|
@@ -11226,6 +11452,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11226
11452
|
if (row.flags.includes("task")) taskTargetCount += 1;
|
|
11227
11453
|
}
|
|
11228
11454
|
return {
|
|
11455
|
+
target_count: rows.length,
|
|
11456
|
+
changed_target_count: rows.length,
|
|
11229
11457
|
inbox_target_count: rows.length,
|
|
11230
11458
|
pending_message_count: pendingMessageCount,
|
|
11231
11459
|
max_pending_per_target: maxPendingCount,
|
|
@@ -11399,7 +11627,9 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11399
11627
|
return false;
|
|
11400
11628
|
}
|
|
11401
11629
|
const messages = [...ap.inbox];
|
|
11402
|
-
ap.notifications.
|
|
11630
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
11631
|
+
ap.notifications.clearPending();
|
|
11632
|
+
ap.notifications.clearTimer();
|
|
11403
11633
|
if (messages.length === 0) {
|
|
11404
11634
|
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11405
11635
|
outcome: "empty",
|
|
@@ -11415,12 +11645,23 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11415
11645
|
messageCount: messages.length
|
|
11416
11646
|
});
|
|
11417
11647
|
}
|
|
11418
|
-
this.broadcastActivity(agentId, "working", "Message received");
|
|
11419
11648
|
const runtimeProfileMessages = messages.filter((message) => runtimeProfileNotificationFromMessage(message));
|
|
11420
|
-
const
|
|
11649
|
+
const ordinaryMessageCandidates = messages.filter((message) => !runtimeProfileNotificationFromMessage(message));
|
|
11650
|
+
const ordinaryMessages = ap.notifications.filterUncontributedMessages(
|
|
11651
|
+
ordinaryMessageCandidates,
|
|
11652
|
+
ap.sessionId
|
|
11653
|
+
);
|
|
11654
|
+
if (runtimeProfileMessages.length === 0 && ordinaryMessages.length === 0) {
|
|
11655
|
+
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11656
|
+
outcome: "suppressed_already_contributed",
|
|
11657
|
+
delivered_messages_count: 0
|
|
11658
|
+
});
|
|
11659
|
+
return false;
|
|
11660
|
+
}
|
|
11661
|
+
this.broadcastActivity(agentId, "working", "Message received");
|
|
11421
11662
|
let accepted = true;
|
|
11422
11663
|
if (runtimeProfileMessages.length > 0) {
|
|
11423
|
-
ap.inbox.splice(0, ap.inbox.length, ...
|
|
11664
|
+
ap.inbox.splice(0, ap.inbox.length, ...ordinaryMessageCandidates);
|
|
11424
11665
|
accepted = this.deliverMessagesViaStdin(agentId, ap, runtimeProfileMessages, effect.stdinMode);
|
|
11425
11666
|
}
|
|
11426
11667
|
if (ordinaryMessages.length > 0) {
|
|
@@ -11434,7 +11675,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11434
11675
|
}
|
|
11435
11676
|
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11436
11677
|
outcome: accepted ? "written" : "not_written",
|
|
11437
|
-
delivered_messages_count:
|
|
11678
|
+
delivered_messages_count: runtimeProfileMessages.length + ordinaryMessages.length
|
|
11438
11679
|
});
|
|
11439
11680
|
return accepted;
|
|
11440
11681
|
}
|
|
@@ -11666,6 +11907,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11666
11907
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
11667
11908
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
11668
11909
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "thinking" });
|
|
11910
|
+
this.flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, event.kind);
|
|
11669
11911
|
}
|
|
11670
11912
|
break;
|
|
11671
11913
|
}
|
|
@@ -11676,6 +11918,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11676
11918
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
11677
11919
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
11678
11920
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "text" });
|
|
11921
|
+
this.flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, event.kind);
|
|
11679
11922
|
}
|
|
11680
11923
|
break;
|
|
11681
11924
|
}
|
|
@@ -11748,6 +11991,9 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11748
11991
|
if (ap) {
|
|
11749
11992
|
if (event.sessionId) ap.sessionId = event.sessionId;
|
|
11750
11993
|
const stickyTerminalFailure = classifyStickyTerminalFailure(ap);
|
|
11994
|
+
if (!stickyTerminalFailure && ap.runtimeErrorDeliveryBackoff.reason === "runtime_error") {
|
|
11995
|
+
this.clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, "turn_end_unclassified_runtime_error");
|
|
11996
|
+
}
|
|
11751
11997
|
const reduction = reduceApmGatedTurnEnd(ap.gatedSteering, {
|
|
11752
11998
|
inboxLength: stickyTerminalFailure ? 0 : ap.inbox.length,
|
|
11753
11999
|
supportsStdinNotification: ap.driver.supportsStdinNotification,
|
|
@@ -11879,7 +12125,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11879
12125
|
}
|
|
11880
12126
|
}
|
|
11881
12127
|
recordRuntimeTelemetry(agentId, ap, event) {
|
|
11882
|
-
const sessionId = ap.driver.currentSessionId ?? event.sessionId;
|
|
12128
|
+
const sessionId = ap.driver.currentSessionId ?? event.sessionId ?? ap.sessionId ?? ap.config.sessionId;
|
|
12129
|
+
const resultIdentity = this.runtimeTelemetryResultIdentity(agentId, ap, event);
|
|
11883
12130
|
const payloadAttrs = sanitizeRuntimeTelemetryPayloadAttrs(event.attrs);
|
|
11884
12131
|
const versionAttrs = this.runtimeTelemetryVersionAttrs();
|
|
11885
12132
|
const telemetryAttrs = {
|
|
@@ -11889,7 +12136,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11889
12136
|
...event.usageKind ? { usageKind: event.usageKind } : {},
|
|
11890
12137
|
...sessionId ? { sessionId } : {},
|
|
11891
12138
|
...event.turnId ? { turnId: event.turnId } : {},
|
|
11892
|
-
...
|
|
12139
|
+
...resultIdentity
|
|
11893
12140
|
};
|
|
11894
12141
|
const attrs = {
|
|
11895
12142
|
agentId,
|
|
@@ -11902,6 +12149,16 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11902
12149
|
ap.runtimeTraceSpan?.addEvent(`runtime.telemetry.${event.name}`, telemetryAttrs);
|
|
11903
12150
|
this.recordDaemonTrace(`daemon.runtime.telemetry.${event.name}`, attrs);
|
|
11904
12151
|
}
|
|
12152
|
+
runtimeTelemetryResultIdentity(agentId, ap, event) {
|
|
12153
|
+
if (event.runtimeResultId) return { runtimeResultId: event.runtimeResultId };
|
|
12154
|
+
if (event.name !== "token_usage" || event.source !== "claude_result_usage") return {};
|
|
12155
|
+
const sequence = ++ap.runtimeTelemetryResultSeq;
|
|
12156
|
+
const scope = ap.launchId || agentId;
|
|
12157
|
+
return {
|
|
12158
|
+
runtimeResultId: `${scope}:claude_result_usage:${sequence}`,
|
|
12159
|
+
runtimeResultIdSource: "daemon_sequence"
|
|
12160
|
+
};
|
|
12161
|
+
}
|
|
11905
12162
|
runtimeTelemetryVersionAttrs() {
|
|
11906
12163
|
return {
|
|
11907
12164
|
...this.daemonVersion ? {
|
|
@@ -11970,7 +12227,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11970
12227
|
}
|
|
11971
12228
|
}
|
|
11972
12229
|
/** Send a batched notification to the agent via stdin about pending messages */
|
|
11973
|
-
sendStdinNotification(agentId) {
|
|
12230
|
+
sendStdinNotification(agentId, options = {}) {
|
|
11974
12231
|
const ap = this.agents.get(agentId);
|
|
11975
12232
|
if (!ap) return false;
|
|
11976
12233
|
const count = ap.notifications.takePendingAndClearTimer();
|
|
@@ -12012,7 +12269,24 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12012
12269
|
}
|
|
12013
12270
|
const inboxCount = ap.inbox.length;
|
|
12014
12271
|
if (inboxCount === 0) return false;
|
|
12015
|
-
|
|
12272
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
12273
|
+
const changedMessageCandidates = ap.inbox.slice(Math.max(0, ap.inbox.length - count));
|
|
12274
|
+
const changedMessages = ap.notifications.filterUncontributedMessages(changedMessageCandidates, ap.sessionId);
|
|
12275
|
+
if (changedMessages.length === 0) {
|
|
12276
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12277
|
+
agentId,
|
|
12278
|
+
runtime: ap.config.runtime,
|
|
12279
|
+
model: ap.config.model,
|
|
12280
|
+
launchId: ap.launchId || void 0,
|
|
12281
|
+
outcome: "suppressed_already_contributed",
|
|
12282
|
+
mode: "busy",
|
|
12283
|
+
pending_notification_count: count,
|
|
12284
|
+
inbox_count: ap.inbox.length,
|
|
12285
|
+
session_id_present: true
|
|
12286
|
+
});
|
|
12287
|
+
logger.info(`[Agent ${agentId}] Suppressing stdin inbox notice because all candidate messages already contributed; pending=${ap.inbox.length}`);
|
|
12288
|
+
return false;
|
|
12289
|
+
}
|
|
12016
12290
|
const noticeFingerprint = computeInboxNoticeFingerprint(changedMessages);
|
|
12017
12291
|
if (ap.notifications.isDuplicateNotice(noticeFingerprint, ap.sessionId)) {
|
|
12018
12292
|
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
@@ -12029,6 +12303,22 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12029
12303
|
logger.info(`[Agent ${agentId}] Suppressing duplicate stdin inbox notice (unread-set unchanged since last write); pending=${ap.inbox.length}`);
|
|
12030
12304
|
return false;
|
|
12031
12305
|
}
|
|
12306
|
+
if (!options.forceUnsupportedRetry && ap.notifications.isDuplicateEncodeFailedNotice(noticeFingerprint, ap.sessionId)) {
|
|
12307
|
+
ap.notifications.add(count);
|
|
12308
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12309
|
+
agentId,
|
|
12310
|
+
runtime: ap.config.runtime,
|
|
12311
|
+
model: ap.config.model,
|
|
12312
|
+
launchId: ap.launchId || void 0,
|
|
12313
|
+
outcome: "suppressed_duplicate_encode_failed",
|
|
12314
|
+
mode: "busy",
|
|
12315
|
+
pending_notification_count: count,
|
|
12316
|
+
inbox_count: ap.inbox.length,
|
|
12317
|
+
session_id_present: true
|
|
12318
|
+
});
|
|
12319
|
+
logger.info(`[Agent ${agentId}] Suppressing duplicate unsupported stdin inbox notice (unread-set unchanged since last encode failure); pending=${ap.inbox.length}`);
|
|
12320
|
+
return false;
|
|
12321
|
+
}
|
|
12032
12322
|
const inboxRows = projectAgentInboxSnapshot(changedMessages);
|
|
12033
12323
|
const notification = `[Slock inbox notice:
|
|
12034
12324
|
${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
@@ -12051,6 +12341,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12051
12341
|
model: ap.config.model,
|
|
12052
12342
|
launchId: ap.launchId || void 0,
|
|
12053
12343
|
mode: "busy",
|
|
12344
|
+
source: "busy_stdin_notification",
|
|
12054
12345
|
notification_byte_count: notificationByteCount,
|
|
12055
12346
|
...projectionAttrs
|
|
12056
12347
|
});
|
|
@@ -12066,12 +12357,15 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12066
12357
|
inbox_target_count: inboxRows.length,
|
|
12067
12358
|
session_id_present: true
|
|
12068
12359
|
});
|
|
12069
|
-
ap.notifications.recordNoticeWritten(noticeFingerprint, ap.sessionId);
|
|
12360
|
+
ap.notifications.recordNoticeWritten(noticeFingerprint, ap.sessionId, changedMessages);
|
|
12070
12361
|
return true;
|
|
12071
12362
|
} else {
|
|
12072
12363
|
ap.notifications.add(count);
|
|
12073
|
-
const retryScheduled = ap.runtime.descriptor.busyDelivery === "direct" ? this.scheduleStdinNotification(agentId, ap, this.stdinNotificationRetryMs) : false;
|
|
12364
|
+
const retryScheduled = ap.runtime.descriptor.busyDelivery === "direct" && sendResult.reason !== "unsupported" ? this.scheduleStdinNotification(agentId, ap, this.stdinNotificationRetryMs) : false;
|
|
12074
12365
|
const outcome = runtimeSendFailureOutcome(sendResult);
|
|
12366
|
+
if (outcome === "encode_failed") {
|
|
12367
|
+
ap.notifications.recordNoticeEncodeFailed(noticeFingerprint, ap.sessionId);
|
|
12368
|
+
}
|
|
12075
12369
|
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12076
12370
|
agentId,
|
|
12077
12371
|
runtime: ap.config.runtime,
|
|
@@ -12113,6 +12407,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12113
12407
|
model: ap.config.model,
|
|
12114
12408
|
launchId: ap.launchId || void 0,
|
|
12115
12409
|
mode,
|
|
12410
|
+
source,
|
|
12116
12411
|
notification_byte_count: Buffer.byteLength(renderedInput, "utf8"),
|
|
12117
12412
|
cursors_advanced: "none",
|
|
12118
12413
|
...projectionAttrs
|
|
@@ -12191,6 +12486,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12191
12486
|
stdin_write_attempted: true,
|
|
12192
12487
|
cursors_advanced: "none"
|
|
12193
12488
|
});
|
|
12489
|
+
ap.notifications.recordNoticeWritten(computeInboxNoticeFingerprint(messages), ap.sessionId, messages);
|
|
12194
12490
|
return true;
|
|
12195
12491
|
}
|
|
12196
12492
|
/** Deliver a message to an agent via stdin, formatting it the same way as the MCP bridge */
|
|
@@ -12407,7 +12703,7 @@ var DaemonConnection = class {
|
|
|
12407
12703
|
logger.warn(`[Daemon] Dropping outbound message while disconnected: ${msg.type}`);
|
|
12408
12704
|
}
|
|
12409
12705
|
this.trace("daemon.connection.outbound_dropped", {
|
|
12410
|
-
|
|
12706
|
+
outbound_message_kind: msg.type,
|
|
12411
12707
|
ws_ready_state: this.ws?.readyState ?? null
|
|
12412
12708
|
});
|
|
12413
12709
|
}
|
|
@@ -12456,7 +12752,7 @@ var DaemonConnection = class {
|
|
|
12456
12752
|
this.resetWatchdog();
|
|
12457
12753
|
if (messageKind !== "ping") {
|
|
12458
12754
|
this.trace("daemon.connection.inbound_received", {
|
|
12459
|
-
|
|
12755
|
+
inbound_message_kind: messageKind,
|
|
12460
12756
|
last_inbound_age_ms_bucket: "0"
|
|
12461
12757
|
});
|
|
12462
12758
|
}
|
|
@@ -12547,7 +12843,7 @@ var DaemonConnection = class {
|
|
|
12547
12843
|
if (msg.launchId && latestLaunchId && msg.launchId !== latestLaunchId) {
|
|
12548
12844
|
this.trace("daemon.connection.pending_activity_invalidated", {
|
|
12549
12845
|
reason: "launch_changed",
|
|
12550
|
-
|
|
12846
|
+
outbound_message_kind: msg.type,
|
|
12551
12847
|
agentId: msg.agentId,
|
|
12552
12848
|
stale_launch_id_present: true,
|
|
12553
12849
|
next_launch_id_present: true
|
|
@@ -12567,7 +12863,7 @@ var DaemonConnection = class {
|
|
|
12567
12863
|
this.pendingActivityByAgent.delete(identity.agentId);
|
|
12568
12864
|
this.trace("daemon.connection.pending_activity_invalidated", {
|
|
12569
12865
|
reason: "launch_changed",
|
|
12570
|
-
|
|
12866
|
+
outbound_message_kind: msg.type,
|
|
12571
12867
|
agentId: identity.agentId,
|
|
12572
12868
|
stale_launch_id_present: Boolean(pending.launchId),
|
|
12573
12869
|
next_launch_id_present: true
|
|
@@ -12596,7 +12892,7 @@ var DaemonConnection = class {
|
|
|
12596
12892
|
ws.send(JSON.stringify(msg));
|
|
12597
12893
|
}
|
|
12598
12894
|
this.trace("daemon.connection.outbound_replayed", {
|
|
12599
|
-
|
|
12895
|
+
outbound_message_kind: "agent:activity",
|
|
12600
12896
|
message_count: pending.length
|
|
12601
12897
|
});
|
|
12602
12898
|
}
|
|
@@ -13422,6 +13718,51 @@ var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
|
13422
13718
|
var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
|
|
13423
13719
|
var RUNNER_CREDENTIAL_MINT_MAX_ATTEMPTS2 = 3;
|
|
13424
13720
|
var RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2 = 250;
|
|
13721
|
+
var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
13722
|
+
"daemon.lifecycle.start": {
|
|
13723
|
+
spanAttrs: ["machine_dir_present", "local_trace_enabled"],
|
|
13724
|
+
eventAttrs: {
|
|
13725
|
+
"daemon.machine_lock.acquired": ["machine_dir_present"]
|
|
13726
|
+
}
|
|
13727
|
+
},
|
|
13728
|
+
"daemon.lifecycle.stop": {
|
|
13729
|
+
spanAttrs: ["machine_lock_present"]
|
|
13730
|
+
},
|
|
13731
|
+
"daemon.runner_credential_mint.retry": {
|
|
13732
|
+
spanAttrs: ["agentId", "runtime", "attempt", "max_attempts", "status", "code", "reason", "retryable"]
|
|
13733
|
+
},
|
|
13734
|
+
"daemon.runner_credential_mint.failed": {
|
|
13735
|
+
spanAttrs: ["agentId", "runtime", "status", "code", "reason", "retryable", "max_attempts"]
|
|
13736
|
+
},
|
|
13737
|
+
"daemon.agent.spawn.failed": {
|
|
13738
|
+
spanAttrs: ["agentId", "launchId", "runtime", "model", "failure_reason", "failure_detail", "session_id_present"]
|
|
13739
|
+
},
|
|
13740
|
+
"daemon.agent.delivery": {
|
|
13741
|
+
spanAttrs: ["agentId", "deliveryId", "delivery_correlation_id", "messageId", "message_id_present", "seq"],
|
|
13742
|
+
eventAttrs: {
|
|
13743
|
+
"daemon.receive": ["seq", "deliveryId"],
|
|
13744
|
+
"daemon.deliver_to_agent_manager": ["accepted"],
|
|
13745
|
+
"daemon.ack.sent": ["seq"]
|
|
13746
|
+
},
|
|
13747
|
+
endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class"]
|
|
13748
|
+
},
|
|
13749
|
+
"daemon.runtime_profile.control.received": {
|
|
13750
|
+
spanAttrs: ["agentId", "control_kind", "key_present", "launchId"],
|
|
13751
|
+
endAttrs: ["outcome", "error_class"]
|
|
13752
|
+
},
|
|
13753
|
+
"daemon.computer_control.received": {
|
|
13754
|
+
spanAttrs: ["action", "handled"]
|
|
13755
|
+
},
|
|
13756
|
+
"daemon.ready.sent": {
|
|
13757
|
+
spanAttrs: ["runtimes_count", "running_agents_count", "idle_agents_count", "runtime_profile_reports_count"]
|
|
13758
|
+
},
|
|
13759
|
+
"daemon.runtime_profile.report.sent": {
|
|
13760
|
+
spanAttrs: ["agentId", "launchId", "runtime", "report_source", "model_present", "session_ref_present", "workspace_ref_present"]
|
|
13761
|
+
},
|
|
13762
|
+
"daemon.connection.local_disconnect_observed": {
|
|
13763
|
+
spanAttrs: ["running_agents_count", "idle_agents_count"]
|
|
13764
|
+
}
|
|
13765
|
+
};
|
|
13425
13766
|
var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
|
|
13426
13767
|
var RunnerCredentialMintError2 = class extends Error {
|
|
13427
13768
|
code;
|
|
@@ -13629,6 +13970,8 @@ var DaemonCore = class {
|
|
|
13629
13970
|
tracer;
|
|
13630
13971
|
injectedTracer;
|
|
13631
13972
|
machineLock = null;
|
|
13973
|
+
observedServerId = null;
|
|
13974
|
+
observedMachineId = null;
|
|
13632
13975
|
localTraceSink = null;
|
|
13633
13976
|
traceBundleUploader = null;
|
|
13634
13977
|
constructor(options) {
|
|
@@ -13679,6 +14022,7 @@ var DaemonCore = class {
|
|
|
13679
14022
|
return process.env.SLOCK_DAEMON_LOCAL_TRACE !== "0";
|
|
13680
14023
|
}
|
|
13681
14024
|
resolveTraceJitter() {
|
|
14025
|
+
if (process.env.SLOCK_DAEMON_TRACE_JITTER_DISABLED === "1") return NO_JITTER;
|
|
13682
14026
|
const lockId = this.machineLock?.lockId;
|
|
13683
14027
|
return lockId ? computeTraceJitter(lockId) : NO_JITTER;
|
|
13684
14028
|
}
|
|
@@ -13710,7 +14054,7 @@ var DaemonCore = class {
|
|
|
13710
14054
|
workerUrl,
|
|
13711
14055
|
tracer: this.tracer,
|
|
13712
14056
|
currentFileProvider: () => this.localTraceSink?.getCurrentFile() ?? null,
|
|
13713
|
-
|
|
14057
|
+
jitter: this.resolveTraceJitter()
|
|
13714
14058
|
});
|
|
13715
14059
|
this.traceBundleUploader.start();
|
|
13716
14060
|
}
|
|
@@ -13789,22 +14133,29 @@ var DaemonCore = class {
|
|
|
13789
14133
|
span.end(status);
|
|
13790
14134
|
}
|
|
13791
14135
|
withDaemonTraceScope(tracer) {
|
|
13792
|
-
return
|
|
14136
|
+
return {
|
|
14137
|
+
startSpan: (name, options) => createTraceScopeTracer(tracer, this.daemonTraceScope(), {
|
|
14138
|
+
spanAttrContracts: DAEMON_CORE_TRACE_ATTR_CONTRACTS
|
|
14139
|
+
}).startSpan(name, options)
|
|
14140
|
+
};
|
|
13793
14141
|
}
|
|
13794
|
-
|
|
14142
|
+
daemonTraceScope() {
|
|
13795
14143
|
return {
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
|
|
13803
|
-
} : {
|
|
13804
|
-
computer_version_present: false
|
|
14144
|
+
resource: {
|
|
14145
|
+
daemonVersion: this.daemonVersion,
|
|
14146
|
+
computerVersion: this.computerVersion
|
|
14147
|
+
},
|
|
14148
|
+
actor: {
|
|
14149
|
+
serverId: this.observedServerId,
|
|
14150
|
+
machineId: this.observedMachineId
|
|
13805
14151
|
}
|
|
13806
14152
|
};
|
|
13807
14153
|
}
|
|
14154
|
+
observeRuntimeContext(config) {
|
|
14155
|
+
const ctx = config.runtimeContext;
|
|
14156
|
+
if (ctx?.serverId) this.observedServerId = ctx.serverId;
|
|
14157
|
+
if (ctx?.machineId) this.observedMachineId = ctx.machineId;
|
|
14158
|
+
}
|
|
13808
14159
|
async requestRunnerCredentialOnce(agentId, config) {
|
|
13809
14160
|
const url = new URL(`/internal/computer/runners/${encodeURIComponent(agentId)}/credentials`, this.options.serverUrl);
|
|
13810
14161
|
const res = await daemonFetch(url, {
|
|
@@ -13896,6 +14247,7 @@ var DaemonCore = class {
|
|
|
13896
14247
|
);
|
|
13897
14248
|
}
|
|
13898
14249
|
async startAgentFromMessage(msg) {
|
|
14250
|
+
this.observeRuntimeContext(msg.config);
|
|
13899
14251
|
const agentCredential = await this.mintRunnerCredential(msg.agentId, msg.config);
|
|
13900
14252
|
const config = { ...msg.config, agentCredentialKey: agentCredential.apiKey, agentCredentialId: agentCredential.credentialId };
|
|
13901
14253
|
await this.agentManager.startAgent(
|
|
@@ -13913,6 +14265,7 @@ var DaemonCore = class {
|
|
|
13913
14265
|
logger.info(`[Daemon] Received ${msg.type}${summary ? ` ${summary}` : ""}`);
|
|
13914
14266
|
switch (msg.type) {
|
|
13915
14267
|
case "agent:start":
|
|
14268
|
+
this.observeRuntimeContext(msg.config);
|
|
13916
14269
|
logger.info(`[Agent ${msg.agentId}] Start requested (runtime=${msg.config.runtime}, model=${msg.config.model}, session=${msg.config.sessionId || "new"}${msg.wakeMessage ? ", wake=true" : ""})`);
|
|
13917
14270
|
this.startAgentFromMessage(msg).catch((err) => {
|
|
13918
14271
|
const classification = classifySpawnFailure(err);
|
package/dist/cli/index.js
CHANGED
|
@@ -860,11 +860,17 @@ async function runDeviceCodeLogin(options) {
|
|
|
860
860
|
const pollIntervalMs = options.pollIntervalOverrideMs ?? serverIntervalMs;
|
|
861
861
|
const deadlineMs = Date.now() + Math.max(1, authorizeBody.expiresIn ?? 600) * 1e3;
|
|
862
862
|
while (Date.now() < deadlineMs) {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
863
|
+
let tokenRes;
|
|
864
|
+
try {
|
|
865
|
+
tokenRes = await httpFetch(`${base}/api/auth/device/token`, {
|
|
866
|
+
method: "POST",
|
|
867
|
+
headers: { "content-type": "application/json" },
|
|
868
|
+
body: JSON.stringify({ deviceCode: authorizeBody.deviceCode })
|
|
869
|
+
});
|
|
870
|
+
} catch {
|
|
871
|
+
await delay(pollIntervalMs);
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
868
874
|
if (tokenRes.ok) {
|
|
869
875
|
const tokenBody = await tokenRes.json();
|
|
870
876
|
if (!tokenBody.accessToken || !tokenBody.refreshToken || !tokenBody.userId) {
|
|
@@ -15249,6 +15255,12 @@ var SERVER_CAPABILITY_MATRIX = {
|
|
|
15249
15255
|
};
|
|
15250
15256
|
|
|
15251
15257
|
// ../shared/src/index.ts
|
|
15258
|
+
var EXTERNAL_AGENT_RUNTIME_ID = "external";
|
|
15259
|
+
var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
|
|
15260
|
+
var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
|
|
15261
|
+
function isExternalAgentRuntime(runtime) {
|
|
15262
|
+
return runtime === EXTERNAL_AGENT_RUNTIME_ID;
|
|
15263
|
+
}
|
|
15252
15264
|
var RUNTIMES = [
|
|
15253
15265
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
15254
15266
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
@@ -15261,8 +15273,71 @@ var RUNTIMES = [
|
|
|
15261
15273
|
{ id: "pi", displayName: "Pi", binary: "pi", supported: true }
|
|
15262
15274
|
];
|
|
15263
15275
|
function getRuntimeDisplayName(id) {
|
|
15276
|
+
if (isExternalAgentRuntime(id)) return EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME;
|
|
15264
15277
|
return RUNTIMES.find((r) => r.id === id)?.displayName ?? id;
|
|
15265
15278
|
}
|
|
15279
|
+
var RUNTIME_MODELS = {
|
|
15280
|
+
[EXTERNAL_AGENT_RUNTIME_ID]: [
|
|
15281
|
+
{ id: EXTERNAL_AGENT_RUNTIME_MODEL, label: EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME }
|
|
15282
|
+
],
|
|
15283
|
+
claude: [
|
|
15284
|
+
{ id: "opus", label: "Claude Opus" },
|
|
15285
|
+
{ id: "claude-opus-4-8", label: "Claude Opus 4.8" },
|
|
15286
|
+
{ id: "claude-opus-4-7", label: "Claude Opus 4.7" },
|
|
15287
|
+
{ id: "claude-opus-4-6", label: "Claude Opus 4.6" },
|
|
15288
|
+
{ id: "sonnet", label: "Claude Sonnet" },
|
|
15289
|
+
{ id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
|
|
15290
|
+
{ id: "haiku", label: "Claude Haiku" },
|
|
15291
|
+
{ id: "claude-haiku-4-5", label: "Claude Haiku 4.5" }
|
|
15292
|
+
],
|
|
15293
|
+
codex: [
|
|
15294
|
+
{ id: "gpt-5.5", label: "GPT-5.5" },
|
|
15295
|
+
{ id: "gpt-5.4", label: "GPT-5.4" },
|
|
15296
|
+
{ id: "gpt-5.3-codex", label: "GPT-5.3 Codex" },
|
|
15297
|
+
{ id: "gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark" },
|
|
15298
|
+
{ id: "gpt-5.2-codex", label: "GPT-5.2 Codex" },
|
|
15299
|
+
{ id: "gpt-5.2", label: "GPT-5.2" },
|
|
15300
|
+
{ id: "gpt-5.1-codex-max", label: "GPT-5.1 Codex Max" },
|
|
15301
|
+
{ id: "gpt-5.1-codex", label: "GPT-5.1 Codex" },
|
|
15302
|
+
{ id: "gpt-5-codex", label: "GPT-5 Codex" },
|
|
15303
|
+
{ id: "gpt-5", label: "GPT-5" }
|
|
15304
|
+
],
|
|
15305
|
+
antigravity: [
|
|
15306
|
+
{ id: "default", label: "AGY configured default", verified: "suggestion_only" }
|
|
15307
|
+
],
|
|
15308
|
+
copilot: [
|
|
15309
|
+
{ id: "gpt-5.4", label: "GPT-5.4" },
|
|
15310
|
+
{ id: "gpt-5.2", label: "GPT-5.2" },
|
|
15311
|
+
{ id: "claude-4-sonnet", label: "Claude 4 Sonnet" },
|
|
15312
|
+
{ id: "claude-4.5-sonnet", label: "Claude 4.5 Sonnet" }
|
|
15313
|
+
],
|
|
15314
|
+
cursor: [
|
|
15315
|
+
{ id: "composer-2-fast", label: "Composer 2 Fast" },
|
|
15316
|
+
{ id: "composer-2", label: "Composer 2" },
|
|
15317
|
+
{ id: "auto", label: "Auto" }
|
|
15318
|
+
],
|
|
15319
|
+
gemini: [
|
|
15320
|
+
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" },
|
|
15321
|
+
{ id: "gemini-3.1-pro-preview", label: "Gemini 3.1 Pro (Preview)" },
|
|
15322
|
+
{ id: "gemini-3-flash-preview", label: "Gemini 3 Flash (Preview)" },
|
|
15323
|
+
{ id: "gemini-2.5-pro", label: "Gemini 2.5 Pro" },
|
|
15324
|
+
{ id: "gemini-2.5-flash", label: "Gemini 2.5 Flash" }
|
|
15325
|
+
],
|
|
15326
|
+
opencode: [
|
|
15327
|
+
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" },
|
|
15328
|
+
{ id: "deepseek/deepseek-v4-pro", label: "DeepSeek V4 Pro (OpenCode)", verified: "suggestion_only" },
|
|
15329
|
+
{ id: "openrouter/anthropic/claude-opus-4.5", label: "Claude Opus 4.5 via OpenRouter", verified: "suggestion_only" },
|
|
15330
|
+
{ id: "fusecode/opus[1m]", label: "Opus 1M via FuseCode", verified: "suggestion_only" }
|
|
15331
|
+
],
|
|
15332
|
+
pi: [
|
|
15333
|
+
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" }
|
|
15334
|
+
],
|
|
15335
|
+
// Kimi CLI resolves model keys from each user's local config, so the safest
|
|
15336
|
+
// built-in option is to defer to whatever default model the CLI already uses.
|
|
15337
|
+
kimi: [
|
|
15338
|
+
{ id: "default", label: "Configured Default" }
|
|
15339
|
+
]
|
|
15340
|
+
};
|
|
15266
15341
|
var PLAN_CONFIG = {
|
|
15267
15342
|
free: {
|
|
15268
15343
|
displayName: "Hobby",
|
package/dist/core.js
CHANGED
package/dist/index.js
CHANGED