@botiverse/raft-daemon 0.63.5 → 0.63.6
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-DZ25KV6L.js → chunk-DUWRNQQE.js} +502 -138
- package/dist/cli/index.js +331 -20
- package/dist/core.js +1 -1
- package/dist/{dist-KC6QHBPD.js → dist-S7UP42L2.js} +323 -20
- package/dist/index.js +1 -1
- package/package.json +2 -1
|
@@ -11,6 +11,72 @@ function makeIsMember(members) {
|
|
|
11
11
|
return (value) => typeof value === "string" && set.has(value);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
// ../shared/src/generated/runtimeProviderDisplayNames.ts
|
|
15
|
+
var RUNTIME_PROVIDER_DISPLAY_NAMES = {
|
|
16
|
+
"anthropic": "Anthropic",
|
|
17
|
+
"deepseek": "DeepSeek",
|
|
18
|
+
"fusecode": "FuseCode",
|
|
19
|
+
"google": "Google",
|
|
20
|
+
"openai": "OpenAI",
|
|
21
|
+
"opencode": "OpenCode",
|
|
22
|
+
"opencode-go": "OpenCode Go",
|
|
23
|
+
"openrouter": "OpenRouter"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// ../shared/src/runtimeProviderDisplay.ts
|
|
27
|
+
function getRuntimeProviderDisplayName(providerId) {
|
|
28
|
+
return RUNTIME_PROVIDER_DISPLAY_NAMES[providerId] ?? humanizeRuntimeProviderSegment(providerId);
|
|
29
|
+
}
|
|
30
|
+
function formatRuntimeProviderModelLabel(modelId) {
|
|
31
|
+
const separatorIndex = modelId.indexOf("/");
|
|
32
|
+
if (separatorIndex <= 0 || separatorIndex === modelId.length - 1) return modelId;
|
|
33
|
+
const providerId = modelId.slice(0, separatorIndex);
|
|
34
|
+
const modelName = modelId.slice(separatorIndex + 1);
|
|
35
|
+
const providerLabel = getRuntimeProviderDisplayName(providerId);
|
|
36
|
+
const modelParts = modelName.split("/");
|
|
37
|
+
const modelLabel = humanizeRuntimeProviderSegment(modelParts[modelParts.length - 1] || modelName);
|
|
38
|
+
if (modelParts.length === 1) return `${modelLabel} \xB7 ${providerLabel}`;
|
|
39
|
+
const upstreamLabel = modelParts.slice(0, -1).map(getRuntimeProviderDisplayName).join(" / ");
|
|
40
|
+
return `${modelLabel} \xB7 ${upstreamLabel} via ${providerLabel}`;
|
|
41
|
+
}
|
|
42
|
+
function humanizeRuntimeProviderSegment(value) {
|
|
43
|
+
return value.replace(/\[(\d+)m\]/gi, "-$1m").split(/[-_/]/).filter(Boolean).map(formatRuntimeProviderLabelToken).join(" ");
|
|
44
|
+
}
|
|
45
|
+
function formatRuntimeProviderLabelToken(token) {
|
|
46
|
+
const normalized = token.toLowerCase();
|
|
47
|
+
const specialCases = {
|
|
48
|
+
ai: "AI",
|
|
49
|
+
api: "API",
|
|
50
|
+
chatgpt: "ChatGPT",
|
|
51
|
+
claude: "Claude",
|
|
52
|
+
codestral: "Codestral",
|
|
53
|
+
deepseek: "DeepSeek",
|
|
54
|
+
flash: "Flash",
|
|
55
|
+
free: "Free",
|
|
56
|
+
gemini: "Gemini",
|
|
57
|
+
glm: "GLM",
|
|
58
|
+
gpt: "GPT",
|
|
59
|
+
hy3: "HY3",
|
|
60
|
+
kimi: "Kimi",
|
|
61
|
+
minimax: "MiniMax",
|
|
62
|
+
nano: "Nano",
|
|
63
|
+
nemotron: "Nemotron",
|
|
64
|
+
omni: "Omni",
|
|
65
|
+
opus: "Opus",
|
|
66
|
+
pro: "Pro",
|
|
67
|
+
sonnet: "Sonnet",
|
|
68
|
+
super: "Super"
|
|
69
|
+
};
|
|
70
|
+
if (specialCases[normalized]) return specialCases[normalized];
|
|
71
|
+
if (normalized === "b" || normalized === "m") return normalized.toUpperCase();
|
|
72
|
+
if (/^v\d+(\.\d+)?$/.test(normalized)) return normalized.toUpperCase();
|
|
73
|
+
if (/^\d+m$/i.test(token)) return token.toUpperCase();
|
|
74
|
+
if (/^\d+[bk]$/i.test(token)) return token.toUpperCase();
|
|
75
|
+
if (/^m\d+(\.\d+)?$/i.test(token)) return token.toUpperCase();
|
|
76
|
+
if (/^\d/.test(token)) return token;
|
|
77
|
+
return normalized.charAt(0).toUpperCase() + normalized.slice(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
14
80
|
// ../shared/src/slockRefs.ts
|
|
15
81
|
var SLOCK_REF_CHANNEL_NAME_PATTERN = String.raw`[\p{L}\p{N}_-]+`;
|
|
16
82
|
var SLOCK_REF_USER_NAME_PATTERN = SLOCK_REF_CHANNEL_NAME_PATTERN;
|
|
@@ -1039,11 +1105,36 @@ var integrationApproveAgentLoginOperationSchema = z.object({
|
|
|
1039
1105
|
scopes: z.array(z.string().trim().min(1).max(120)).max(64),
|
|
1040
1106
|
draftHint: draftHintSchema
|
|
1041
1107
|
});
|
|
1108
|
+
var integrationAppDraftFieldsSchema = z.object({
|
|
1109
|
+
name: z.string().trim().min(1).max(120).optional(),
|
|
1110
|
+
description: z.string().trim().max(1e3).optional(),
|
|
1111
|
+
homepageUrl: z.string().trim().max(2e3).optional(),
|
|
1112
|
+
returnUrl: z.string().trim().max(2e3).optional(),
|
|
1113
|
+
agentManifestUrl: z.string().trim().max(2e3).optional()
|
|
1114
|
+
});
|
|
1115
|
+
var integrationRegisterAppOperationSchema = integrationAppDraftFieldsSchema.extend({
|
|
1116
|
+
type: z.literal("integration:register_app"),
|
|
1117
|
+
name: z.string().trim().min(1).max(120),
|
|
1118
|
+
clientKey: z.string().trim().min(1).max(120),
|
|
1119
|
+
returnUrl: z.string().trim().min(1).max(2e3),
|
|
1120
|
+
scopes: z.array(z.string().trim().min(1).max(120)).max(64).default([]),
|
|
1121
|
+
unsafeDemoUrlOverride: z.boolean().optional(),
|
|
1122
|
+
draftHint: draftHintSchema
|
|
1123
|
+
});
|
|
1124
|
+
var integrationUpdateAppRegistrationOperationSchema = integrationAppDraftFieldsSchema.extend({
|
|
1125
|
+
type: z.literal("integration:update_app_registration"),
|
|
1126
|
+
clientKey: z.string().trim().min(1).max(120),
|
|
1127
|
+
scopes: z.array(z.string().trim().min(1).max(120)).max(64).optional(),
|
|
1128
|
+
unsafeDemoUrlOverride: z.boolean().optional(),
|
|
1129
|
+
draftHint: draftHintSchema
|
|
1130
|
+
});
|
|
1042
1131
|
var actionCardActionSchema = z.discriminatedUnion("type", [
|
|
1043
1132
|
channelCreateOperationSchema,
|
|
1044
1133
|
agentCreateOperationSchema,
|
|
1045
1134
|
channelAddMemberOperationSchema,
|
|
1046
|
-
integrationApproveAgentLoginOperationSchema
|
|
1135
|
+
integrationApproveAgentLoginOperationSchema,
|
|
1136
|
+
integrationRegisterAppOperationSchema,
|
|
1137
|
+
integrationUpdateAppRegistrationOperationSchema
|
|
1047
1138
|
]);
|
|
1048
1139
|
|
|
1049
1140
|
// ../shared/src/agentInbox.ts
|
|
@@ -1362,9 +1453,9 @@ var RUNTIME_MODELS = {
|
|
|
1362
1453
|
],
|
|
1363
1454
|
opencode: [
|
|
1364
1455
|
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" },
|
|
1365
|
-
{ id: "deepseek/deepseek-v4-pro", label: "
|
|
1366
|
-
{ id: "openrouter/anthropic/claude-opus-4.5", label: "
|
|
1367
|
-
{ id: "fusecode/opus[1m]", label: "
|
|
1456
|
+
{ id: "deepseek/deepseek-v4-pro", label: formatRuntimeProviderModelLabel("deepseek/deepseek-v4-pro"), verified: "suggestion_only" },
|
|
1457
|
+
{ id: "openrouter/anthropic/claude-opus-4.5", label: formatRuntimeProviderModelLabel("openrouter/anthropic/claude-opus-4.5"), verified: "suggestion_only" },
|
|
1458
|
+
{ id: "fusecode/opus[1m]", label: formatRuntimeProviderModelLabel("fusecode/opus[1m]"), verified: "suggestion_only" }
|
|
1368
1459
|
],
|
|
1369
1460
|
pi: [
|
|
1370
1461
|
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" }
|
|
@@ -1530,6 +1621,11 @@ function runtimeConfigToLaunchFields(config) {
|
|
|
1530
1621
|
...normalized.command ? { command: normalized.command } : {}
|
|
1531
1622
|
};
|
|
1532
1623
|
}
|
|
1624
|
+
var PRO_SEAT_MONTHLY_USD = 10;
|
|
1625
|
+
var PRO_AGENT_SEAT_BLOCK_SIZE = 10;
|
|
1626
|
+
var PRO_AGENT_SEAT_FRACTION = 1 / PRO_AGENT_SEAT_BLOCK_SIZE;
|
|
1627
|
+
var PRO_SEAT_ANNUAL_MONTHLY_USD = 8.8;
|
|
1628
|
+
var PRO_PACK_AGENT_SEATS = PRO_AGENT_SEAT_BLOCK_SIZE;
|
|
1533
1629
|
var PLAN_CONFIG = {
|
|
1534
1630
|
free: {
|
|
1535
1631
|
displayName: "Free",
|
|
@@ -1556,9 +1652,9 @@ var PLAN_CONFIG = {
|
|
|
1556
1652
|
},
|
|
1557
1653
|
pro: {
|
|
1558
1654
|
displayName: "Pro",
|
|
1559
|
-
limits: { maxMachines: -1, maxAgents:
|
|
1655
|
+
limits: { maxMachines: -1, maxAgents: PRO_PACK_AGENT_SEATS, maxChannels: -1, messageHistoryDays: -1, includedAgents: PRO_PACK_AGENT_SEATS },
|
|
1560
1656
|
comingSoon: false,
|
|
1561
|
-
price:
|
|
1657
|
+
price: PRO_SEAT_MONTHLY_USD,
|
|
1562
1658
|
extraAgentPrice: 0
|
|
1563
1659
|
}
|
|
1564
1660
|
};
|
|
@@ -1568,8 +1664,8 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
1568
1664
|
displayName: "Pro",
|
|
1569
1665
|
limits: { maxMachines: -1, maxAgents: -1, maxChannels: -1, messageHistoryDays: -1, includedAgents: -1 },
|
|
1570
1666
|
comingSoon: false,
|
|
1571
|
-
price:
|
|
1572
|
-
priceCadence: "/ seat
|
|
1667
|
+
price: PRO_SEAT_MONTHLY_USD,
|
|
1668
|
+
priceCadence: "/ seat / month",
|
|
1573
1669
|
extraAgentPrice: 0,
|
|
1574
1670
|
displayFeatures: [
|
|
1575
1671
|
"Everything in Free",
|
|
@@ -1579,7 +1675,7 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
1579
1675
|
"More professional features coming soon"
|
|
1580
1676
|
],
|
|
1581
1677
|
displayDescription: "For builders and teams scaling agent collaboration.",
|
|
1582
|
-
displayNote:
|
|
1678
|
+
displayNote: `$${PRO_SEAT_ANNUAL_MONTHLY_USD.toFixed(2)} / seat / month when billed yearly. Each human uses 1 seat; each agent uses ${PRO_AGENT_SEAT_FRACTION} seat.`
|
|
1583
1679
|
},
|
|
1584
1680
|
enterprise: {
|
|
1585
1681
|
displayName: "Enterprise",
|
|
@@ -3426,6 +3522,7 @@ function latestVisibleMessages(messages, limit) {
|
|
|
3426
3522
|
return sorted.slice(Math.max(0, sorted.length - limit));
|
|
3427
3523
|
}
|
|
3428
3524
|
function isMessageModelSeen(input, message) {
|
|
3525
|
+
if (messageSenderId(message) === input.agentId) return true;
|
|
3429
3526
|
const seq = Math.floor(messageSeq(message));
|
|
3430
3527
|
if (Number.isFinite(seq) && seq > 0 && typeof input.modelSeenSeq === "number" && input.modelSeenSeq >= seq) return true;
|
|
3431
3528
|
return input.isMessageModelSeen?.({ target: input.target, message }) === true;
|
|
@@ -8047,14 +8144,6 @@ var SLOCK_AGENT_NAME = "slock";
|
|
|
8047
8144
|
var NO_MESSAGE_PROMPT = "No new messages are pending. Stop now.";
|
|
8048
8145
|
var FIRST_MESSAGE_TASK_PREFIX = "First message task (system-triggered):";
|
|
8049
8146
|
var MIN_SUPPORTED_OPENCODE_VERSION = "1.14.30";
|
|
8050
|
-
var OPENCODE_PROVIDER_LABELS = {
|
|
8051
|
-
opencode: "OpenCode",
|
|
8052
|
-
"opencode-go": "OpenCode Go",
|
|
8053
|
-
openai: "OpenAI",
|
|
8054
|
-
openrouter: "OpenRouter",
|
|
8055
|
-
deepseek: "DeepSeek",
|
|
8056
|
-
fusecode: "FuseCode"
|
|
8057
|
-
};
|
|
8058
8147
|
function parseOpenCodeConfigContent(raw) {
|
|
8059
8148
|
if (!raw) return {};
|
|
8060
8149
|
try {
|
|
@@ -8192,62 +8281,12 @@ function parseOpenCodeModelsOutput(output) {
|
|
|
8192
8281
|
seen.add(line);
|
|
8193
8282
|
models.push({
|
|
8194
8283
|
id: line,
|
|
8195
|
-
label:
|
|
8284
|
+
label: formatRuntimeProviderModelLabel(line),
|
|
8196
8285
|
verified: "launchable"
|
|
8197
8286
|
});
|
|
8198
8287
|
}
|
|
8199
8288
|
return models.length > 0 ? { models } : null;
|
|
8200
8289
|
}
|
|
8201
|
-
function formatOpenCodeModelLabel(modelId) {
|
|
8202
|
-
const separatorIndex = modelId.indexOf("/");
|
|
8203
|
-
if (separatorIndex <= 0 || separatorIndex === modelId.length - 1) return modelId;
|
|
8204
|
-
const providerId = modelId.slice(0, separatorIndex);
|
|
8205
|
-
const modelName = modelId.slice(separatorIndex + 1);
|
|
8206
|
-
const providerLabel = OPENCODE_PROVIDER_LABELS[providerId] || humanizeOpenCodeSegment(providerId);
|
|
8207
|
-
const modelParts = modelName.split("/");
|
|
8208
|
-
const modelLabel = humanizeOpenCodeSegment(modelParts[modelParts.length - 1] || modelName);
|
|
8209
|
-
if (modelParts.length === 1) return `${modelLabel} \xB7 ${providerLabel}`;
|
|
8210
|
-
const upstreamLabel = modelParts.slice(0, -1).map(humanizeOpenCodeSegment).join(" / ");
|
|
8211
|
-
return `${modelLabel} \xB7 ${upstreamLabel} via ${providerLabel}`;
|
|
8212
|
-
}
|
|
8213
|
-
function humanizeOpenCodeSegment(value) {
|
|
8214
|
-
return value.replace(/\[(\d+)m\]/gi, "-$1m").split(/[-_]/).filter(Boolean).map(formatOpenCodeLabelToken).join(" ");
|
|
8215
|
-
}
|
|
8216
|
-
function formatOpenCodeLabelToken(token) {
|
|
8217
|
-
const normalized = token.toLowerCase();
|
|
8218
|
-
const specialCases = {
|
|
8219
|
-
ai: "AI",
|
|
8220
|
-
api: "API",
|
|
8221
|
-
b: "B",
|
|
8222
|
-
chatgpt: "ChatGPT",
|
|
8223
|
-
claude: "Claude",
|
|
8224
|
-
codestral: "Codestral",
|
|
8225
|
-
deepseek: "DeepSeek",
|
|
8226
|
-
flash: "Flash",
|
|
8227
|
-
free: "Free",
|
|
8228
|
-
gemini: "Gemini",
|
|
8229
|
-
glm: "GLM",
|
|
8230
|
-
gpt: "GPT",
|
|
8231
|
-
hy3: "HY3",
|
|
8232
|
-
kimi: "Kimi",
|
|
8233
|
-
m: "M",
|
|
8234
|
-
minimax: "MiniMax",
|
|
8235
|
-
nano: "Nano",
|
|
8236
|
-
nemotron: "Nemotron",
|
|
8237
|
-
omni: "Omni",
|
|
8238
|
-
opus: "Opus",
|
|
8239
|
-
pro: "Pro",
|
|
8240
|
-
sonnet: "Sonnet",
|
|
8241
|
-
super: "Super"
|
|
8242
|
-
};
|
|
8243
|
-
if (specialCases[normalized]) return specialCases[normalized];
|
|
8244
|
-
if (/^v\d+(\.\d+)?$/.test(normalized)) return normalized.toUpperCase();
|
|
8245
|
-
if (/^\d+m$/i.test(token)) return token.toUpperCase();
|
|
8246
|
-
if (/^\d+[bk]$/i.test(token)) return token.toUpperCase();
|
|
8247
|
-
if (/^m\d+(\.\d+)?$/i.test(token)) return token.toUpperCase();
|
|
8248
|
-
if (/^\d/.test(token)) return token;
|
|
8249
|
-
return normalized.charAt(0).toUpperCase() + normalized.slice(1);
|
|
8250
|
-
}
|
|
8251
8290
|
function detectOpenCodeModels(home = os5.homedir(), runCommand = runOpenCodeModelsCommand) {
|
|
8252
8291
|
const commandResult = runCommand(home);
|
|
8253
8292
|
if (commandResult.error || commandResult.status !== 0) return null;
|
|
@@ -8530,12 +8569,6 @@ import {
|
|
|
8530
8569
|
} from "@earendil-works/pi-coding-agent";
|
|
8531
8570
|
var PI_SESSION_DIR = ".pi-sessions";
|
|
8532
8571
|
var PI_SDK_COMPACTION_ENABLED = true;
|
|
8533
|
-
var PI_PROVIDER_LABELS = {
|
|
8534
|
-
google: "Google",
|
|
8535
|
-
openai: "OpenAI",
|
|
8536
|
-
openrouter: "OpenRouter",
|
|
8537
|
-
deepseek: "DeepSeek"
|
|
8538
|
-
};
|
|
8539
8572
|
function createPiSdkEventMappingState(sessionId = null) {
|
|
8540
8573
|
return {
|
|
8541
8574
|
sessionId,
|
|
@@ -8577,7 +8610,7 @@ function detectPiModelsFromRegistry(modelRegistry) {
|
|
|
8577
8610
|
seen.add(id);
|
|
8578
8611
|
models.push({
|
|
8579
8612
|
id,
|
|
8580
|
-
label: `${model.name ||
|
|
8613
|
+
label: `${model.name || humanizeRuntimeProviderSegment(model.id)} \xB7 ${getRuntimeProviderDisplayName(model.provider)}`,
|
|
8581
8614
|
verified: "launchable"
|
|
8582
8615
|
});
|
|
8583
8616
|
}
|
|
@@ -8648,25 +8681,6 @@ async function detectPiModels(modelRegistry, traceContext = {}) {
|
|
|
8648
8681
|
);
|
|
8649
8682
|
return result;
|
|
8650
8683
|
}
|
|
8651
|
-
function humanizePiSegment(value) {
|
|
8652
|
-
return value.split(/[-_/]/).filter(Boolean).map(formatPiLabelToken).join(" ");
|
|
8653
|
-
}
|
|
8654
|
-
function formatPiLabelToken(token) {
|
|
8655
|
-
const normalized = token.toLowerCase();
|
|
8656
|
-
const specialCases = {
|
|
8657
|
-
ai: "AI",
|
|
8658
|
-
api: "API",
|
|
8659
|
-
flash: "Flash",
|
|
8660
|
-
gpt: "GPT",
|
|
8661
|
-
pro: "Pro",
|
|
8662
|
-
v4: "V4"
|
|
8663
|
-
};
|
|
8664
|
-
if (specialCases[normalized]) return specialCases[normalized];
|
|
8665
|
-
if (/^v\d+(\.\d+)?$/.test(normalized)) return normalized.toUpperCase();
|
|
8666
|
-
if (/^\d+[bk]$/i.test(token)) return token.toUpperCase();
|
|
8667
|
-
if (/^\d/.test(token)) return token;
|
|
8668
|
-
return normalized.charAt(0).toUpperCase() + normalized.slice(1);
|
|
8669
|
-
}
|
|
8670
8684
|
function piErrorMessage(error) {
|
|
8671
8685
|
if (typeof error === "string" && error.trim()) return error.trim();
|
|
8672
8686
|
if (error && typeof error === "object") {
|
|
@@ -9895,6 +9909,33 @@ function runnerCredentialErrorDetail(error) {
|
|
|
9895
9909
|
async function waitForRunnerCredentialRetry() {
|
|
9896
9910
|
await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS));
|
|
9897
9911
|
}
|
|
9912
|
+
function probeSubprocessOsState(pid) {
|
|
9913
|
+
if (typeof pid !== "number") return "unknown";
|
|
9914
|
+
try {
|
|
9915
|
+
const status = readFileSync6(`/proc/${pid}/status`, "utf8");
|
|
9916
|
+
const match = status.match(/^State:\s+(\S)/m);
|
|
9917
|
+
if (match) {
|
|
9918
|
+
const code = match[1];
|
|
9919
|
+
if (code === "R") return "running";
|
|
9920
|
+
if (code === "S") return "sleeping";
|
|
9921
|
+
if (code === "D") return "uninterruptible_sleep";
|
|
9922
|
+
if (code === "Z") return "zombie";
|
|
9923
|
+
if (code === "T" || code === "t") return "stopped";
|
|
9924
|
+
}
|
|
9925
|
+
return "unknown";
|
|
9926
|
+
} catch {
|
|
9927
|
+
return "gone";
|
|
9928
|
+
}
|
|
9929
|
+
}
|
|
9930
|
+
function bucketMs(ms) {
|
|
9931
|
+
if (ms < 1e3) return "<1s";
|
|
9932
|
+
if (ms < 1e4) return "1-10s";
|
|
9933
|
+
if (ms < 6e4) return "10-60s";
|
|
9934
|
+
if (ms < 3e5) return "1-5m";
|
|
9935
|
+
if (ms < 9e5) return "5-15m";
|
|
9936
|
+
if (ms < 36e5) return "15-60m";
|
|
9937
|
+
return ">60m";
|
|
9938
|
+
}
|
|
9898
9939
|
function stalledRecoverySigtermTimeoutMs() {
|
|
9899
9940
|
return readNonNegativeIntegerEnv(
|
|
9900
9941
|
"SLOCK_DAEMON_STALLED_RECOVERY_SIGTERM_TIMEOUT_MS",
|
|
@@ -10300,6 +10341,7 @@ var STDIN_NOTIFICATION_INITIAL_DELAY_MS = 3e3;
|
|
|
10300
10341
|
var STDIN_NOTIFICATION_RETRY_DELAY_MS = 15e3;
|
|
10301
10342
|
var RUNTIME_ERROR_DELIVERY_BACKOFF_BASE_MS = 1e4;
|
|
10302
10343
|
var RUNTIME_ERROR_DELIVERY_BACKOFF_MAX_MS = 5 * 6e4;
|
|
10344
|
+
var RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD = 3;
|
|
10303
10345
|
var SPAWN_FAIL_BACKOFF_BASE_MS = 1e3;
|
|
10304
10346
|
var SPAWN_FAIL_BACKOFF_MAX_MS = 3e4;
|
|
10305
10347
|
var SPAWN_FAIL_BACKOFF_THRESHOLD = 3;
|
|
@@ -11209,6 +11251,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
11209
11251
|
agentStartIntervalMs;
|
|
11210
11252
|
startingInboxes = /* @__PURE__ */ new Map();
|
|
11211
11253
|
terminalRuntimeFailures = /* @__PURE__ */ new Map();
|
|
11254
|
+
runtimeErrorFingerprintFences = /* @__PURE__ */ new Map();
|
|
11212
11255
|
pendingStartRebinds = /* @__PURE__ */ new Map();
|
|
11213
11256
|
/** Cached configs for agents whose process exited normally — enables auto-restart on next message */
|
|
11214
11257
|
idleAgentConfigs = /* @__PURE__ */ new Map();
|
|
@@ -11236,11 +11279,13 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
11236
11279
|
// BEFORE ap exists; rate-state must persist across stop/respawn so churn can't bypass).
|
|
11237
11280
|
// Explicit stop clears (fresh launch resets dedup clock — CC1 lifecycle pattern); silent
|
|
11238
11281
|
// stop preserves (same-launch respawn must keep counter or churn bypasses the cap).
|
|
11282
|
+
pendingSpawnCause = /* @__PURE__ */ new Map();
|
|
11239
11283
|
agentSpawnFailBackoff = /* @__PURE__ */ new Map();
|
|
11240
11284
|
daemonVersion;
|
|
11241
11285
|
computerVersion;
|
|
11242
11286
|
workerUrl;
|
|
11243
11287
|
fetchImpl;
|
|
11288
|
+
serverConnected;
|
|
11244
11289
|
constructor(sendToServer, daemonApiKey, opts) {
|
|
11245
11290
|
this.slockCliPath = opts.slockCliPath ?? "";
|
|
11246
11291
|
this.sendToServer = sendToServer;
|
|
@@ -11256,6 +11301,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
11256
11301
|
this.computerVersion = opts.computerVersion?.trim() || null;
|
|
11257
11302
|
this.workerUrl = opts.workerUrl?.trim() || null;
|
|
11258
11303
|
this.fetchImpl = opts.fetchImpl ?? daemonFetch;
|
|
11304
|
+
this.serverConnected = opts.serverConnected ?? (() => true);
|
|
11259
11305
|
this.stdinNotificationRetryMs = Math.max(
|
|
11260
11306
|
0,
|
|
11261
11307
|
Math.floor(opts.stdinNotificationRetryMs ?? STDIN_NOTIFICATION_RETRY_DELAY_MS)
|
|
@@ -11372,6 +11418,94 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
11372
11418
|
if (state.timer) clearTimeout(state.timer);
|
|
11373
11419
|
this.agentSpawnFailBackoff.delete(agentId);
|
|
11374
11420
|
}
|
|
11421
|
+
// ----- RUNTIME-ERROR FINGERPRINT FENCE (per-agent) ---------------------
|
|
11422
|
+
// The delivery backoff above is scoped to AgentProcess and is cleared when a
|
|
11423
|
+
// runtime process exits. Recoverable terminal errors intentionally keep an
|
|
11424
|
+
// idle restart cache so the next message can wake the agent, but that also
|
|
11425
|
+
// means a deterministic same-fingerprint runtime error can close/restart
|
|
11426
|
+
// forever. Keep this counter outside AgentProcess and reset only on real turn
|
|
11427
|
+
// progress or explicit stop.
|
|
11428
|
+
runtimeErrorFingerprintFenceResetEvent(eventKind) {
|
|
11429
|
+
switch (eventKind) {
|
|
11430
|
+
case "thinking":
|
|
11431
|
+
case "text":
|
|
11432
|
+
case "tool_call":
|
|
11433
|
+
case "tool_output":
|
|
11434
|
+
case "compaction_finished":
|
|
11435
|
+
case "review_finished":
|
|
11436
|
+
case "turn_end":
|
|
11437
|
+
return true;
|
|
11438
|
+
default:
|
|
11439
|
+
return false;
|
|
11440
|
+
}
|
|
11441
|
+
}
|
|
11442
|
+
resetRuntimeErrorFingerprintFence(agentId, resetSource, ap) {
|
|
11443
|
+
const state = this.runtimeErrorFingerprintFences.get(agentId);
|
|
11444
|
+
if (!state) return;
|
|
11445
|
+
this.runtimeErrorFingerprintFences.delete(agentId);
|
|
11446
|
+
this.recordDaemonTrace("daemon.agent.runtime_error_fingerprint_fence.reset", {
|
|
11447
|
+
agentId,
|
|
11448
|
+
runtime: ap?.config.runtime,
|
|
11449
|
+
model: ap?.config.model,
|
|
11450
|
+
launchId: ap?.launchId || state.launchId || void 0,
|
|
11451
|
+
fingerprint: state.fingerprint,
|
|
11452
|
+
attempts: state.attempts,
|
|
11453
|
+
reset_source: resetSource
|
|
11454
|
+
});
|
|
11455
|
+
}
|
|
11456
|
+
formatRuntimeErrorFingerprintFenceDetail(state) {
|
|
11457
|
+
return [
|
|
11458
|
+
`Runtime stopped after ${state.attempts} repeated runtime errors with the same fingerprint (${state.fingerprint}).`,
|
|
11459
|
+
`Last error: ${state.lastRuntimeError}`,
|
|
11460
|
+
"Restart after the runtime/tooling issue is fixed."
|
|
11461
|
+
].join(" ");
|
|
11462
|
+
}
|
|
11463
|
+
noteRuntimeErrorFingerprintFence(agentId, ap, message, fingerprint, terminalFailure, stickyTerminalFailure) {
|
|
11464
|
+
if (!fingerprint) return null;
|
|
11465
|
+
if (stickyTerminalFailure || terminalFailure?.actionRequired) return null;
|
|
11466
|
+
let state = this.runtimeErrorFingerprintFences.get(agentId);
|
|
11467
|
+
if (!state || state.fingerprint !== fingerprint) {
|
|
11468
|
+
state = {
|
|
11469
|
+
fingerprint,
|
|
11470
|
+
attempts: 0,
|
|
11471
|
+
lastRuntimeError: message,
|
|
11472
|
+
detail: "",
|
|
11473
|
+
launchId: ap.launchId
|
|
11474
|
+
};
|
|
11475
|
+
this.runtimeErrorFingerprintFences.set(agentId, state);
|
|
11476
|
+
}
|
|
11477
|
+
state.attempts += 1;
|
|
11478
|
+
state.lastRuntimeError = message;
|
|
11479
|
+
state.launchId = ap.launchId;
|
|
11480
|
+
state.detail = this.formatRuntimeErrorFingerprintFenceDetail(state);
|
|
11481
|
+
const fenced = state.attempts >= RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD;
|
|
11482
|
+
this.recordDaemonTrace("daemon.agent.runtime_error_fingerprint_fence", {
|
|
11483
|
+
agentId,
|
|
11484
|
+
runtime: ap.config.runtime,
|
|
11485
|
+
model: ap.config.model,
|
|
11486
|
+
launchId: ap.launchId || void 0,
|
|
11487
|
+
fingerprint,
|
|
11488
|
+
attempts: state.attempts,
|
|
11489
|
+
threshold: RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD,
|
|
11490
|
+
fenced,
|
|
11491
|
+
runtime_error_class: buildRuntimeErrorDiagnosticEnvelope(message).spanAttrs.runtime_error_class
|
|
11492
|
+
}, fenced ? "error" : "ok");
|
|
11493
|
+
return fenced ? state : null;
|
|
11494
|
+
}
|
|
11495
|
+
applyRuntimeErrorFingerprintFence(agentId, ap, state) {
|
|
11496
|
+
this.recordDaemonTrace("daemon.agent.runtime_error_fingerprint_fence.tripped", {
|
|
11497
|
+
agentId,
|
|
11498
|
+
runtime: ap.config.runtime,
|
|
11499
|
+
model: ap.config.model,
|
|
11500
|
+
launchId: ap.launchId || void 0,
|
|
11501
|
+
fingerprint: state.fingerprint,
|
|
11502
|
+
attempts: state.attempts,
|
|
11503
|
+
threshold: RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD
|
|
11504
|
+
}, "error");
|
|
11505
|
+
this.idleAgentConfigs.delete(agentId);
|
|
11506
|
+
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
11507
|
+
this.cleanupTerminalRuntimeFailure(agentId, ap, state.detail);
|
|
11508
|
+
}
|
|
11375
11509
|
scheduleStdinNotification(agentId, ap, delayMs) {
|
|
11376
11510
|
return ap.notifications.schedule(() => {
|
|
11377
11511
|
this.sendStdinNotification(agentId);
|
|
@@ -11925,6 +12059,18 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
11925
12059
|
});
|
|
11926
12060
|
span.end(status);
|
|
11927
12061
|
}
|
|
12062
|
+
processLifecycleIdentityAttrs(agentId, ap) {
|
|
12063
|
+
const runtimeContext = ap.config.runtimeContext;
|
|
12064
|
+
return {
|
|
12065
|
+
agent_id: agentId,
|
|
12066
|
+
server_id: runtimeContext?.serverId,
|
|
12067
|
+
machine_id: runtimeContext?.machineId,
|
|
12068
|
+
process_instance_id: ap.processInstanceId,
|
|
12069
|
+
runtime: ap.config.runtime,
|
|
12070
|
+
runtime_version: runtimeContext?.daemonVersion,
|
|
12071
|
+
pid: typeof ap.runtime.pid === "number" ? ap.runtime.pid : void 0
|
|
12072
|
+
};
|
|
12073
|
+
}
|
|
11928
12074
|
startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
|
|
11929
12075
|
return {
|
|
11930
12076
|
agentId,
|
|
@@ -12343,6 +12489,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
12343
12489
|
let prompt;
|
|
12344
12490
|
let promptSource;
|
|
12345
12491
|
let wakeMessageDeliveredAsInboxUpdate = false;
|
|
12492
|
+
let startingInboxDeliveredAsInput = false;
|
|
12346
12493
|
const startingInboxMessages = this.startingInboxes.get(agentId) || [];
|
|
12347
12494
|
if (runtimeConfig.runtimeProfileControl && !wakeMessage) {
|
|
12348
12495
|
prompt = driver.supportsNativeStandingPrompt ? NATIVE_STANDING_PROMPT_STARTUP_INPUT : formatRuntimeProfileControlStartupInput(runtimeConfig.runtimeProfileControl, driver);
|
|
@@ -12383,6 +12530,10 @@ You also have unread messages in other channels:`;
|
|
|
12383
12530
|
Use the inbox/read commands at a natural breakpoint if you choose to inspect those targets.`;
|
|
12384
12531
|
}
|
|
12385
12532
|
}
|
|
12533
|
+
} else if (startingInboxMessages.length > 0) {
|
|
12534
|
+
startingInboxDeliveredAsInput = true;
|
|
12535
|
+
prompt = this.formatInboxUpdateRuntimeInput(startingInboxMessages, driver);
|
|
12536
|
+
promptSource = "starting_inbox_update";
|
|
12386
12537
|
} else if (isResume && unreadSummary && Object.keys(unreadSummary).length > 0) {
|
|
12387
12538
|
prompt = `You have unread messages from while you were offline:`;
|
|
12388
12539
|
for (const [ch, count] of Object.entries(unreadSummary)) {
|
|
@@ -12459,6 +12610,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12459
12610
|
};
|
|
12460
12611
|
const initialSessionId = this.initialAgentProcessSessionId(driver, liveProcessConfig);
|
|
12461
12612
|
const restartSessionId = initialSessionId || (driver.requiresSessionInitForDelivery ? liveProcessConfig.sessionId || null : null);
|
|
12613
|
+
const processInstanceId = randomUUID5();
|
|
12462
12614
|
agentProcess = {
|
|
12463
12615
|
runtime,
|
|
12464
12616
|
driver,
|
|
@@ -12488,6 +12640,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12488
12640
|
runtimeErrorSinceProgress: false,
|
|
12489
12641
|
runtimeErrorDeliveryBackoff: createRuntimeErrorDeliveryBackoffState(),
|
|
12490
12642
|
spawnError: null,
|
|
12643
|
+
processInstanceId,
|
|
12644
|
+
spawnedAtMs: Date.now(),
|
|
12491
12645
|
exitCode: null,
|
|
12492
12646
|
exitSignal: null,
|
|
12493
12647
|
stalledRecoverySigtermTimer: null,
|
|
@@ -12512,6 +12666,10 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12512
12666
|
}
|
|
12513
12667
|
if (wakeMessageDeliveredAsInboxUpdate) {
|
|
12514
12668
|
this.recordInboxUpdateProjection(agentId, agentProcess, agentProcess.inbox, "spawn_wake_inbox_update", "wake", prompt);
|
|
12669
|
+
} else if (startingInboxDeliveredAsInput) {
|
|
12670
|
+
this.recordInboxUpdateProjection(agentId, agentProcess, startingInboxMessages, "spawn_starting_inbox_update", "wake", prompt);
|
|
12671
|
+
this.consumeVisibleMessages(agentId, { messages: startingInboxMessages, source: "spawn_starting_inbox_update" });
|
|
12672
|
+
this.ackInjectedRuntimeProfileMessages(agentId, startingInboxMessages, agentProcess.launchId);
|
|
12515
12673
|
} else if (wakeMessage && !wakeMessageTransient) {
|
|
12516
12674
|
this.consumeVisibleMessages(agentId, { messages: [wakeMessage], source: "spawn_wake_message" });
|
|
12517
12675
|
this.ackInjectedRuntimeProfileMessages(agentId, [wakeMessage], agentProcess.launchId);
|
|
@@ -12574,6 +12732,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12574
12732
|
current.exitCode = code;
|
|
12575
12733
|
current.exitSignal = signal;
|
|
12576
12734
|
}
|
|
12735
|
+
const exitTraceAttrs = this.runtimeExitTraceAttrs.get(runtime);
|
|
12577
12736
|
this.recordDaemonTrace("daemon.agent.process.exited", {
|
|
12578
12737
|
agentId,
|
|
12579
12738
|
launchId: current?.launchId || void 0,
|
|
@@ -12585,8 +12744,22 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12585
12744
|
runtime_trace_active: Boolean(current?.runtimeTraceSpan),
|
|
12586
12745
|
inbox_count: current?.inbox.length ?? 0,
|
|
12587
12746
|
pending_notification_count: current?.notifications.pendingCount ?? 0,
|
|
12588
|
-
...
|
|
12747
|
+
...exitTraceAttrs
|
|
12589
12748
|
});
|
|
12749
|
+
if (agentProcess) {
|
|
12750
|
+
const stopSource = exitTraceAttrs?.stop_source;
|
|
12751
|
+
const exitCause = stopSource?.includes("stall") ? "stall_kill" : stopSource === "disconnect" ? "disconnect_kill" : stopSource === "daemon_exit" ? "parent_exit" : stopSource === "explicit_request" || stopSource === "daemon_internal" || code === 0 ? "expected_terminate" : "crash";
|
|
12752
|
+
const staleForMs = agentProcess.runtimeProgress.ageMs();
|
|
12753
|
+
this.recordDaemonTrace("daemon.runtime.process.exit", {
|
|
12754
|
+
...this.processLifecycleIdentityAttrs(agentId, agentProcess),
|
|
12755
|
+
exit_code: code,
|
|
12756
|
+
exit_signal: signal,
|
|
12757
|
+
cause: exitCause,
|
|
12758
|
+
last_event_kind: agentProcess.lastActivity || void 0,
|
|
12759
|
+
last_event_age_ms_bucket: bucketMs(staleForMs),
|
|
12760
|
+
uptime_ms_bucket: bucketMs(Date.now() - agentProcess.spawnedAtMs)
|
|
12761
|
+
}, code === 0 ? "ok" : "error");
|
|
12762
|
+
}
|
|
12590
12763
|
logger.info(`[Agent ${agentId}] Process exited with code ${code}${signal ? ` (signal ${signal})` : ""}`);
|
|
12591
12764
|
});
|
|
12592
12765
|
runtime.on("close", ({ code, signal }) => {
|
|
@@ -12650,6 +12823,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12650
12823
|
text: `Stored ${runtimeLabel} session ${staleSessionId} ${reasonText}. Falling back to a cold start; earlier runtime context may not be restored.`
|
|
12651
12824
|
}]
|
|
12652
12825
|
);
|
|
12826
|
+
this.pendingSpawnCause.set(agentId, "restart_crash");
|
|
12653
12827
|
this.startAgent(
|
|
12654
12828
|
agentId,
|
|
12655
12829
|
restartConfig,
|
|
@@ -12659,6 +12833,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12659
12833
|
ap.launchId || void 0
|
|
12660
12834
|
).catch((err) => {
|
|
12661
12835
|
logger.error(`[Agent ${agentId}] Cold start recovery failed`, err);
|
|
12836
|
+
this.pendingSpawnCause.delete(agentId);
|
|
12662
12837
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
12663
12838
|
this.broadcastActivity(agentId, "offline", `Crashed (${summary})`, [], ap.launchId);
|
|
12664
12839
|
});
|
|
@@ -12685,6 +12860,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12685
12860
|
});
|
|
12686
12861
|
this.broadcastActivity(agentId, "working", "Message received");
|
|
12687
12862
|
this.idleAgentConfigs.delete(agentId);
|
|
12863
|
+
if (expectedTerminationReason === "stalled_recovery") {
|
|
12864
|
+
this.pendingSpawnCause.set(agentId, "restart_stall");
|
|
12865
|
+
}
|
|
12688
12866
|
this.startAgent(agentId, nextConfig, queuedWakeMessage, unreadSummary2, void 0, ap.launchId || void 0).catch((err) => {
|
|
12689
12867
|
logger.error(`[Agent ${agentId}] Failed to continue with queued message`, err);
|
|
12690
12868
|
if (this.reportRunnerCredentialMintFailure(agentId, err, ap.launchId, "queued_continuation")) {
|
|
@@ -12769,6 +12947,16 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
12769
12947
|
new_session: false,
|
|
12770
12948
|
process_pid_present: typeof runtime.pid === "number"
|
|
12771
12949
|
});
|
|
12950
|
+
const pendingCause = this.pendingSpawnCause.get(agentId);
|
|
12951
|
+
this.pendingSpawnCause.delete(agentId);
|
|
12952
|
+
const startCause = pendingCause ?? (isResume ? "session_resume" : wakeMessage ? "wake_message" : "explicit_start");
|
|
12953
|
+
this.recordDaemonTrace("daemon.runtime.process.spawn", {
|
|
12954
|
+
...this.processLifecycleIdentityAttrs(agentId, agentProcess),
|
|
12955
|
+
start_cause: startCause,
|
|
12956
|
+
credential_type: effectiveConfig.agentCredentialKey ? "managed_runner" : "legacy_machine",
|
|
12957
|
+
session_id_present: Boolean(agentProcess.sessionId),
|
|
12958
|
+
launch_id_present: Boolean(agentProcess.launchId)
|
|
12959
|
+
});
|
|
12772
12960
|
this.sendAgentStatus(agentId, "active", agentProcess.launchId);
|
|
12773
12961
|
if (pendingStartRebind && agentProcess.sessionId) {
|
|
12774
12962
|
this.sendToServer({ type: "agent:session", agentId, sessionId: agentProcess.sessionId, launchId: agentProcess.launchId || void 0 });
|
|
@@ -13123,6 +13311,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
13123
13311
|
this.agentVisibleBoundaries.delete(agentId);
|
|
13124
13312
|
this.agentVisibleMessageIds.delete(agentId);
|
|
13125
13313
|
this.resetSpawnFailBackoff(agentId);
|
|
13314
|
+
this.resetRuntimeErrorFingerprintFence(agentId, "explicit_stop", ap);
|
|
13126
13315
|
}
|
|
13127
13316
|
this.runtimeExitTraceAttrs.set(ap.runtime, {
|
|
13128
13317
|
stop_source: silent ? "daemon_internal" : "explicit_request",
|
|
@@ -13307,6 +13496,19 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
13307
13496
|
return false;
|
|
13308
13497
|
});
|
|
13309
13498
|
}
|
|
13499
|
+
if (!transientDelivery && (this.queuedAgentStarts.has(agentId) || this.agentsStarting.has(agentId))) {
|
|
13500
|
+
const pending = this.startingInboxes.get(agentId) || [];
|
|
13501
|
+
pending.push(message);
|
|
13502
|
+
this.startingInboxes.set(agentId, pending);
|
|
13503
|
+
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
13504
|
+
outcome: this.agentsStarting.has(agentId) ? "queued_for_starting_process" : "queued_for_queued_start",
|
|
13505
|
+
accepted: true,
|
|
13506
|
+
process_present: false,
|
|
13507
|
+
cached_idle_config_present: false,
|
|
13508
|
+
starting_inbox_count: pending.length
|
|
13509
|
+
}));
|
|
13510
|
+
return true;
|
|
13511
|
+
}
|
|
13310
13512
|
logger.warn(`[Agent ${agentId}] Delivery received but no running process or cached idle config exists`);
|
|
13311
13513
|
if (transientDelivery) {
|
|
13312
13514
|
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
@@ -14307,26 +14509,18 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
14307
14509
|
if (!hasToolStart) {
|
|
14308
14510
|
entries.push({ kind: "status", activity, detail });
|
|
14309
14511
|
}
|
|
14512
|
+
const launchId = launchIdOverride || ap?.launchId || void 0;
|
|
14513
|
+
const clientSeq = ap ? this.nextActivityClientSeq(agentId) : void 0;
|
|
14310
14514
|
this.sendToServer({
|
|
14311
14515
|
type: "agent:activity",
|
|
14312
14516
|
agentId,
|
|
14313
14517
|
activity,
|
|
14314
14518
|
detail,
|
|
14315
14519
|
entries,
|
|
14316
|
-
launchId
|
|
14317
|
-
clientSeq
|
|
14318
|
-
});
|
|
14319
|
-
this.recordDaemonTrace("daemon.agent.activity.produced", {
|
|
14320
|
-
agentId,
|
|
14321
|
-
activity,
|
|
14322
|
-
detail_present: Boolean(detail),
|
|
14323
|
-
entry_kinds: entries.map((e) => e.kind).join(","),
|
|
14324
|
-
ap_present: Boolean(ap),
|
|
14325
|
-
launch_id_present: Boolean(launchIdOverride || ap?.launchId),
|
|
14326
|
-
client_seq_present: ap ? true : false,
|
|
14327
|
-
session_id_present: Boolean(ap?.sessionId),
|
|
14328
|
-
runtime: ap?.config.runtime
|
|
14520
|
+
launchId,
|
|
14521
|
+
clientSeq
|
|
14329
14522
|
});
|
|
14523
|
+
this.recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq);
|
|
14330
14524
|
if (ap) {
|
|
14331
14525
|
ap.lastActivity = activity;
|
|
14332
14526
|
ap.lastActivityDetail = detail;
|
|
@@ -14337,14 +14531,17 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
14337
14531
|
this.recordRuntimeTraceEvent(agentId, ap, "activity.heartbeat.sent", {
|
|
14338
14532
|
activity: ap.lastActivity
|
|
14339
14533
|
});
|
|
14534
|
+
const heartbeatLaunchId = launchIdOverride || ap.launchId || void 0;
|
|
14535
|
+
const heartbeatClientSeq = this.nextActivityClientSeq(agentId);
|
|
14340
14536
|
this.sendToServer({
|
|
14341
14537
|
type: "agent:activity",
|
|
14342
14538
|
agentId,
|
|
14343
14539
|
activity: ap.lastActivity,
|
|
14344
14540
|
detail: ap.lastActivityDetail,
|
|
14345
|
-
launchId:
|
|
14346
|
-
clientSeq:
|
|
14541
|
+
launchId: heartbeatLaunchId,
|
|
14542
|
+
clientSeq: heartbeatClientSeq
|
|
14347
14543
|
});
|
|
14544
|
+
this.recordActivityProducedTrace(agentId, ap.lastActivity, ap.lastActivityDetail, [], ap, heartbeatLaunchId, heartbeatClientSeq);
|
|
14348
14545
|
}, ACTIVITY_HEARTBEAT_MS);
|
|
14349
14546
|
}
|
|
14350
14547
|
} else {
|
|
@@ -14355,6 +14552,29 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
14355
14552
|
}
|
|
14356
14553
|
}
|
|
14357
14554
|
}
|
|
14555
|
+
recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq) {
|
|
14556
|
+
const runtimeContext = ap?.config.runtimeContext;
|
|
14557
|
+
this.recordDaemonTrace("daemon.agent.activity.produced", {
|
|
14558
|
+
agentId,
|
|
14559
|
+
agent_id: agentId,
|
|
14560
|
+
server_id: runtimeContext?.serverId,
|
|
14561
|
+
machine_id: runtimeContext?.machineId,
|
|
14562
|
+
process_instance_id: ap?.processInstanceId,
|
|
14563
|
+
activity,
|
|
14564
|
+
detail_present: Boolean(detail),
|
|
14565
|
+
entry_kinds: entries.map((e) => e.kind).join(","),
|
|
14566
|
+
ap_present: Boolean(ap),
|
|
14567
|
+
launchId,
|
|
14568
|
+
launch_id: launchId,
|
|
14569
|
+
launch_id_present: Boolean(launchId),
|
|
14570
|
+
clientSeq,
|
|
14571
|
+
client_seq: clientSeq,
|
|
14572
|
+
client_seq_present: typeof clientSeq === "number",
|
|
14573
|
+
correlation_id: `agent:${agentId}:daemonActivity:${launchId ?? "legacy"}:${clientSeq ?? "unsequenced"}`,
|
|
14574
|
+
session_id_present: Boolean(ap?.sessionId),
|
|
14575
|
+
runtime: ap?.config.runtime
|
|
14576
|
+
});
|
|
14577
|
+
}
|
|
14358
14578
|
/**
|
|
14359
14579
|
* Respond to a server-issued `agent:activity_probe`. Echoes the
|
|
14360
14580
|
* agent's current `lastActivity` back through the existing
|
|
@@ -14380,15 +14600,18 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
14380
14600
|
const ap = this.agents.get(agentId);
|
|
14381
14601
|
const activity = ap?.lastActivity || "offline";
|
|
14382
14602
|
const detail = ap?.lastActivityDetail || (ap ? "" : "Agent not running");
|
|
14603
|
+
const launchId = ap?.launchId || void 0;
|
|
14604
|
+
const clientSeq = ap ? this.nextActivityClientSeq(agentId) : void 0;
|
|
14383
14605
|
this.sendToServer({
|
|
14384
14606
|
type: "agent:activity",
|
|
14385
14607
|
agentId,
|
|
14386
14608
|
activity,
|
|
14387
14609
|
detail,
|
|
14388
|
-
launchId
|
|
14610
|
+
launchId,
|
|
14389
14611
|
probeId,
|
|
14390
|
-
clientSeq
|
|
14612
|
+
clientSeq
|
|
14391
14613
|
});
|
|
14614
|
+
this.recordActivityProducedTrace(agentId, activity, detail, [], ap, launchId, clientSeq);
|
|
14392
14615
|
}
|
|
14393
14616
|
flushPendingTrajectory(agentId) {
|
|
14394
14617
|
const ap = this.agents.get(agentId);
|
|
@@ -14488,6 +14711,12 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
14488
14711
|
);
|
|
14489
14712
|
try {
|
|
14490
14713
|
void runtimeAtSignal.stop({ signal: "SIGKILL", reason: "stalled_recovery_sigterm_timeout" });
|
|
14714
|
+
this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
|
|
14715
|
+
...this.processLifecycleIdentityAttrs(agentId, current),
|
|
14716
|
+
action: "sigkill_escalation",
|
|
14717
|
+
outcome: "initiated",
|
|
14718
|
+
delay_ms_bucket: bucketMs(timeoutMs)
|
|
14719
|
+
}, "error");
|
|
14491
14720
|
} catch (err) {
|
|
14492
14721
|
const reason = err instanceof Error ? err.message : String(err);
|
|
14493
14722
|
this.recordDaemonTrace("daemon.agent.stalled_recovery.sigkill_failed", {
|
|
@@ -14497,6 +14726,16 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
14497
14726
|
model: current.config.model,
|
|
14498
14727
|
reason
|
|
14499
14728
|
}, "error");
|
|
14729
|
+
this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
|
|
14730
|
+
...this.processLifecycleIdentityAttrs(agentId, current),
|
|
14731
|
+
action: "sigkill_escalation",
|
|
14732
|
+
outcome: "kill_failed",
|
|
14733
|
+
delay_ms_bucket: bucketMs(timeoutMs),
|
|
14734
|
+
kill_signal_sequence: "SIGTERM,SIGKILL",
|
|
14735
|
+
kill_attempts: 2,
|
|
14736
|
+
subprocess_os_state: probeSubprocessOsState(current.runtime.pid),
|
|
14737
|
+
daemon_child_tracking_present: this.agents.has(agentId)
|
|
14738
|
+
}, "error");
|
|
14500
14739
|
logger.warn(`[Agent ${agentId}] Failed to force kill stalled ${runtimeLabel} process: ${reason}`);
|
|
14501
14740
|
}
|
|
14502
14741
|
}, timeoutMs);
|
|
@@ -15036,6 +15275,23 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
15036
15275
|
...runtimeTraceCounterAttrs(ap),
|
|
15037
15276
|
...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_stalled")
|
|
15038
15277
|
});
|
|
15278
|
+
let subprocessPidAlive;
|
|
15279
|
+
if (typeof ap.runtime.pid === "number") {
|
|
15280
|
+
try {
|
|
15281
|
+
process.kill(ap.runtime.pid, 0);
|
|
15282
|
+
subprocessPidAlive = true;
|
|
15283
|
+
} catch {
|
|
15284
|
+
subprocessPidAlive = false;
|
|
15285
|
+
}
|
|
15286
|
+
}
|
|
15287
|
+
this.recordDaemonTrace("daemon.runtime.stall.detected", {
|
|
15288
|
+
...this.processLifecycleIdentityAttrs(agentId, ap),
|
|
15289
|
+
last_event_kind: ap.lastActivity || void 0,
|
|
15290
|
+
last_event_age_ms_bucket: bucketMs(staleForMs),
|
|
15291
|
+
subprocess_pid_alive: subprocessPidAlive,
|
|
15292
|
+
subprocess_socket_alive: !ap.runtime.closed,
|
|
15293
|
+
daemon_connected_to_server: this.serverConnected()
|
|
15294
|
+
}, "error");
|
|
15039
15295
|
this.broadcastActivity(agentId, "error", diagnostic.detail);
|
|
15040
15296
|
return true;
|
|
15041
15297
|
}
|
|
@@ -15087,9 +15343,25 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
15087
15343
|
this.runtimeExitTraceAttrs.set(ap.runtime, projection.processExitAttrs);
|
|
15088
15344
|
this.startStalledRecoverySigtermWatchdog(agentId, ap, runtimeLabel, ap.inbox.length, staleForMs);
|
|
15089
15345
|
void ap.runtime.stop({ signal: "SIGTERM", reason: projection.runtimeStopReason });
|
|
15346
|
+
this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
|
|
15347
|
+
...this.processLifecycleIdentityAttrs(agentId, ap),
|
|
15348
|
+
action: "terminate_for_restart",
|
|
15349
|
+
outcome: "initiated",
|
|
15350
|
+
delay_ms_bucket: bucketMs(staleForMs)
|
|
15351
|
+
});
|
|
15090
15352
|
} catch (err) {
|
|
15091
15353
|
this.clearStalledRecoverySigtermWatchdog(ap);
|
|
15092
15354
|
const reason = err instanceof Error ? err.message : String(err);
|
|
15355
|
+
this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
|
|
15356
|
+
...this.processLifecycleIdentityAttrs(agentId, ap),
|
|
15357
|
+
action: "terminate_for_restart",
|
|
15358
|
+
outcome: "kill_failed",
|
|
15359
|
+
delay_ms_bucket: bucketMs(staleForMs),
|
|
15360
|
+
kill_signal_sequence: "SIGTERM",
|
|
15361
|
+
kill_attempts: 1,
|
|
15362
|
+
subprocess_os_state: probeSubprocessOsState(ap.runtime.pid),
|
|
15363
|
+
daemon_child_tracking_present: this.agents.has(agentId)
|
|
15364
|
+
}, "error");
|
|
15093
15365
|
logger.warn(`[Agent ${agentId}] Failed to terminate stalled ${runtimeLabel} process: ${reason}`);
|
|
15094
15366
|
return false;
|
|
15095
15367
|
}
|
|
@@ -15168,6 +15440,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
15168
15440
|
return;
|
|
15169
15441
|
}
|
|
15170
15442
|
this.noteRuntimeProgress(ap, event.kind);
|
|
15443
|
+
if (this.runtimeErrorFingerprintFenceResetEvent(event.kind)) {
|
|
15444
|
+
this.resetRuntimeErrorFingerprintFence(agentId, `runtime_progress:${event.kind}`, ap);
|
|
15445
|
+
}
|
|
15171
15446
|
recordProgressObservedAfterStall();
|
|
15172
15447
|
} else if (event.kind !== "internal_progress") {
|
|
15173
15448
|
this.recordDaemonTrace("daemon.agent.event.received_without_process", {
|
|
@@ -15360,6 +15635,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
15360
15635
|
let visibleErrorMessage = event.message;
|
|
15361
15636
|
if (ap) {
|
|
15362
15637
|
const runtimeErrorDiagnostics = buildRuntimeErrorDiagnosticEnvelope(event.message);
|
|
15638
|
+
const runtimeErrorFingerprint = typeof runtimeErrorDiagnostics.spanAttrs.runtime_error_fingerprint === "string" ? runtimeErrorDiagnostics.spanAttrs.runtime_error_fingerprint : null;
|
|
15363
15639
|
if (runtimeErrorDiagnostics.spanAttrs.runtime_error_action_required === true) {
|
|
15364
15640
|
visibleErrorMessage = formatRuntimeLoginRequiredMessage(ap.driver.id);
|
|
15365
15641
|
}
|
|
@@ -15376,6 +15652,17 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
15376
15652
|
terminalWakeable: Boolean(ap.driver.supportsStdinNotification && terminalFailure && !terminalFailure.actionRequired)
|
|
15377
15653
|
});
|
|
15378
15654
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "error" });
|
|
15655
|
+
const fingerprintFence = this.noteRuntimeErrorFingerprintFence(
|
|
15656
|
+
agentId,
|
|
15657
|
+
ap,
|
|
15658
|
+
event.message,
|
|
15659
|
+
runtimeErrorFingerprint,
|
|
15660
|
+
terminalFailure,
|
|
15661
|
+
stickyTerminalFailure
|
|
15662
|
+
);
|
|
15663
|
+
if (fingerprintFence) {
|
|
15664
|
+
visibleErrorMessage = fingerprintFence.detail;
|
|
15665
|
+
}
|
|
15379
15666
|
this.noteRuntimeErrorDeliveryBackoff(agentId, ap, event.message, terminalFailure, stickyTerminalFailure, backoffReasonOverride);
|
|
15380
15667
|
if (reduction.shouldDisableToolBoundaryFlush) {
|
|
15381
15668
|
this.recordGatedSteeringEvent(agentId, ap, "disabled", {
|
|
@@ -15396,7 +15683,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
|
|
|
15396
15683
|
...runtimeTraceCounterAttrs(ap),
|
|
15397
15684
|
...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_error")
|
|
15398
15685
|
});
|
|
15399
|
-
if (
|
|
15686
|
+
if (fingerprintFence) {
|
|
15687
|
+
this.applyRuntimeErrorFingerprintFence(agentId, ap, fingerprintFence);
|
|
15688
|
+
} else if (ap.driver.supportsStdinNotification && terminalFailure) {
|
|
15400
15689
|
if (terminalFailure.actionRequired) {
|
|
15401
15690
|
logger.warn(`[Agent ${agentId}] ${ap.driver.id} auth requires user action; terminating runtime process`);
|
|
15402
15691
|
try {
|
|
@@ -16430,7 +16719,13 @@ var DIAGNOSTIC_ID_ATTRS = /* @__PURE__ */ new Set([
|
|
|
16430
16719
|
"bundleId",
|
|
16431
16720
|
"deliveryId",
|
|
16432
16721
|
"deliveryCorrelationId",
|
|
16433
|
-
"delivery_correlation_id"
|
|
16722
|
+
"delivery_correlation_id",
|
|
16723
|
+
"agent_id",
|
|
16724
|
+
"server_id",
|
|
16725
|
+
"machine_id",
|
|
16726
|
+
"process_instance_id",
|
|
16727
|
+
"launch_id",
|
|
16728
|
+
"correlation_id"
|
|
16434
16729
|
]);
|
|
16435
16730
|
var DIAGNOSTIC_ERROR_ATTRS = /* @__PURE__ */ new Set([
|
|
16436
16731
|
"runtime_error_class",
|
|
@@ -16680,6 +16975,21 @@ var TRACE_UPLOAD_SCOPE = "daemon-trace-bundle:create";
|
|
|
16680
16975
|
var DEFAULT_UPLOAD_INTERVAL_MS = 5 * 60 * 1e3;
|
|
16681
16976
|
var DEFAULT_MIN_FILE_AGE_MS = 60 * 1e3;
|
|
16682
16977
|
var DEFAULT_MAX_FILES_PER_RUN = 4;
|
|
16978
|
+
var ALLOWED_PRODUCER_DEPLOYMENT_ENVIRONMENTS = /* @__PURE__ */ new Set([
|
|
16979
|
+
"production",
|
|
16980
|
+
"staging",
|
|
16981
|
+
"dev",
|
|
16982
|
+
"test",
|
|
16983
|
+
"slockdev"
|
|
16984
|
+
]);
|
|
16985
|
+
function readProducerDeploymentEnvironment() {
|
|
16986
|
+
const raw = process.env.SLOCK_DAEMON_DEPLOYMENT_ENV;
|
|
16987
|
+
if (!raw) return void 0;
|
|
16988
|
+
const trimmed = raw.trim();
|
|
16989
|
+
if (!trimmed) return void 0;
|
|
16990
|
+
if (!ALLOWED_PRODUCER_DEPLOYMENT_ENVIRONMENTS.has(trimmed)) return void 0;
|
|
16991
|
+
return trimmed;
|
|
16992
|
+
}
|
|
16683
16993
|
var DaemonTraceBundleUploader = class {
|
|
16684
16994
|
options;
|
|
16685
16995
|
jitter;
|
|
@@ -16798,7 +17108,11 @@ var DaemonTraceBundleUploader = class {
|
|
|
16798
17108
|
attestationMetadata: {
|
|
16799
17109
|
bundleId,
|
|
16800
17110
|
bundleSha256,
|
|
16801
|
-
bundleSizeBytes: gzipped.byteLength
|
|
17111
|
+
bundleSizeBytes: gzipped.byteLength,
|
|
17112
|
+
...(() => {
|
|
17113
|
+
const env = readProducerDeploymentEnvironment();
|
|
17114
|
+
return env ? { deploymentEnvironment: env } : {};
|
|
17115
|
+
})()
|
|
16802
17116
|
},
|
|
16803
17117
|
createBody: {
|
|
16804
17118
|
bundleSha256,
|
|
@@ -16891,9 +17205,10 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
16891
17205
|
eventAttrs: {
|
|
16892
17206
|
"daemon.receive": ["seq", "deliveryId"],
|
|
16893
17207
|
"daemon.deliver_to_agent_manager": ["accepted"],
|
|
17208
|
+
"daemon.delivery.buffered_for_start": ["pending_count"],
|
|
16894
17209
|
"daemon.ack.sent": ["seq"]
|
|
16895
17210
|
},
|
|
16896
|
-
endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class"]
|
|
17211
|
+
endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class", "pending_count"]
|
|
16897
17212
|
},
|
|
16898
17213
|
"daemon.runtime_profile.control.received": {
|
|
16899
17214
|
spanAttrs: ["agentId", "control_kind", "key_present", "launchId"],
|
|
@@ -16930,7 +17245,7 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
16930
17245
|
spanAttrs: ["running_agents_count", "idle_agents_count"]
|
|
16931
17246
|
},
|
|
16932
17247
|
"daemon.agent.activity.produced": {
|
|
16933
|
-
spanAttrs: ["agentId", "activity", "detail_present", "entry_kinds", "ap_present", "launch_id_present", "client_seq_present", "session_id_present", "runtime"]
|
|
17248
|
+
spanAttrs: ["agentId", "agent_id", "server_id", "machine_id", "activity", "detail_present", "entry_kinds", "ap_present", "launchId", "launch_id", "launch_id_present", "clientSeq", "client_seq", "client_seq_present", "correlation_id", "session_id_present", "runtime"]
|
|
16934
17249
|
},
|
|
16935
17250
|
"daemon.agent.activity.skipped": {
|
|
16936
17251
|
spanAttrs: ["agentId", "event_kind", "reason", "text_length"]
|
|
@@ -17014,7 +17329,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
|
17014
17329
|
}
|
|
17015
17330
|
async function runBundledSlockCli(argv) {
|
|
17016
17331
|
process.argv = [process.execPath, "slock", ...argv];
|
|
17017
|
-
await import("./dist-
|
|
17332
|
+
await import("./dist-S7UP42L2.js");
|
|
17018
17333
|
}
|
|
17019
17334
|
function detectRuntimes(tracer = noopTracer) {
|
|
17020
17335
|
const ids = [];
|
|
@@ -17177,6 +17492,8 @@ var DaemonCore = class {
|
|
|
17177
17492
|
observedMachineId = null;
|
|
17178
17493
|
localTraceSink = null;
|
|
17179
17494
|
traceBundleUploader = null;
|
|
17495
|
+
coreStartingAgentIds = /* @__PURE__ */ new Set();
|
|
17496
|
+
coreStartPendingDeliveries = /* @__PURE__ */ new Map();
|
|
17180
17497
|
constructor(options) {
|
|
17181
17498
|
this.options = options;
|
|
17182
17499
|
this.daemonVersion = options.daemonVersion ?? readDaemonVersion();
|
|
@@ -17202,7 +17519,8 @@ var DaemonCore = class {
|
|
|
17202
17519
|
tracer: this.tracer,
|
|
17203
17520
|
daemonVersion: this.daemonVersion,
|
|
17204
17521
|
computerVersion: this.computerVersion,
|
|
17205
|
-
workerUrl: traceUploadDisabled ? void 0 : process.env.SLOCK_DAEMON_TRACE_UPLOAD_URL || DEFAULT_TRACE_UPLOAD_URL
|
|
17522
|
+
workerUrl: traceUploadDisabled ? void 0 : process.env.SLOCK_DAEMON_TRACE_UPLOAD_URL || DEFAULT_TRACE_UPLOAD_URL,
|
|
17523
|
+
serverConnected: () => connection?.connected ?? false
|
|
17206
17524
|
};
|
|
17207
17525
|
this.agentManager = options.agentManagerFactory ? options.agentManagerFactory((msg) => connection.send(msg), options.apiKey, agentManagerOptions) : new AgentProcessManager((msg) => connection.send(msg), options.apiKey, agentManagerOptions);
|
|
17208
17526
|
const connectionFactory = options.connectionFactory ?? ((connOptions) => new DaemonConnection(connOptions));
|
|
@@ -17453,19 +17771,63 @@ var DaemonCore = class {
|
|
|
17453
17771
|
}
|
|
17454
17772
|
);
|
|
17455
17773
|
}
|
|
17774
|
+
sendDeliveryAck(msg, traceparent) {
|
|
17775
|
+
const ackSeq = msg.seq > 0 ? msg.seq : msg.message.seq ?? 0;
|
|
17776
|
+
const ack = {
|
|
17777
|
+
type: "agent:deliver:ack",
|
|
17778
|
+
agentId: msg.agentId,
|
|
17779
|
+
seq: ackSeq,
|
|
17780
|
+
deliveryId: msg.deliveryId,
|
|
17781
|
+
...traceparent ? { traceparent } : {}
|
|
17782
|
+
};
|
|
17783
|
+
this.connection.send(ack);
|
|
17784
|
+
}
|
|
17456
17785
|
async startAgentFromMessage(msg) {
|
|
17457
|
-
this.
|
|
17458
|
-
|
|
17459
|
-
|
|
17460
|
-
|
|
17461
|
-
msg.
|
|
17462
|
-
config
|
|
17463
|
-
msg.
|
|
17464
|
-
msg.
|
|
17465
|
-
msg.
|
|
17466
|
-
msg.
|
|
17467
|
-
msg.wakeMessageTransient ?? false
|
|
17468
|
-
|
|
17786
|
+
this.coreStartingAgentIds.add(msg.agentId);
|
|
17787
|
+
let wakeDeliveryAck = null;
|
|
17788
|
+
let replayDeliveries = [];
|
|
17789
|
+
try {
|
|
17790
|
+
this.observeRuntimeContext(msg.config);
|
|
17791
|
+
const agentCredential = await this.mintRunnerCredential(msg.agentId, msg.config);
|
|
17792
|
+
const config = { ...msg.config, agentCredentialKey: agentCredential.apiKey, agentCredentialId: agentCredential.credentialId };
|
|
17793
|
+
const pendingDeliveries = this.coreStartPendingDeliveries.get(msg.agentId) || [];
|
|
17794
|
+
this.coreStartPendingDeliveries.delete(msg.agentId);
|
|
17795
|
+
let wakeMessage = msg.wakeMessage;
|
|
17796
|
+
let wakeMessageTransient = msg.wakeMessageTransient ?? false;
|
|
17797
|
+
replayDeliveries = [...pendingDeliveries];
|
|
17798
|
+
if (!wakeMessage) {
|
|
17799
|
+
const wakeIndex = replayDeliveries.findIndex((delivery) => delivery.transient !== true);
|
|
17800
|
+
if (wakeIndex >= 0) {
|
|
17801
|
+
const [wakeDelivery] = replayDeliveries.splice(wakeIndex, 1);
|
|
17802
|
+
if (wakeDelivery) {
|
|
17803
|
+
wakeDeliveryAck = wakeDelivery;
|
|
17804
|
+
wakeMessage = wakeDelivery.message;
|
|
17805
|
+
wakeMessageTransient = wakeDelivery.transient ?? false;
|
|
17806
|
+
}
|
|
17807
|
+
}
|
|
17808
|
+
}
|
|
17809
|
+
await this.agentManager.startAgent(
|
|
17810
|
+
msg.agentId,
|
|
17811
|
+
config,
|
|
17812
|
+
wakeMessage,
|
|
17813
|
+
msg.unreadSummary,
|
|
17814
|
+
msg.resumePrompt,
|
|
17815
|
+
msg.launchId,
|
|
17816
|
+
wakeMessageTransient
|
|
17817
|
+
);
|
|
17818
|
+
this.coreStartingAgentIds.delete(msg.agentId);
|
|
17819
|
+
if (wakeDeliveryAck) {
|
|
17820
|
+
this.sendDeliveryAck(wakeDeliveryAck);
|
|
17821
|
+
}
|
|
17822
|
+
for (const delivery of replayDeliveries) {
|
|
17823
|
+
this.handleMessage(delivery);
|
|
17824
|
+
}
|
|
17825
|
+
} catch (err) {
|
|
17826
|
+
this.coreStartPendingDeliveries.delete(msg.agentId);
|
|
17827
|
+
throw err;
|
|
17828
|
+
} finally {
|
|
17829
|
+
this.coreStartingAgentIds.delete(msg.agentId);
|
|
17830
|
+
}
|
|
17469
17831
|
}
|
|
17470
17832
|
handleMessage(msg) {
|
|
17471
17833
|
const summary = summarizeIncomingMessage(msg);
|
|
@@ -17520,6 +17882,14 @@ var DaemonCore = class {
|
|
|
17520
17882
|
logger.info(`[Agent ${msg.agentId}] Delivery received (seq=${msg.seq}, from=@${msg.message.sender_name}, target=${formatChannelTarget(msg)})`);
|
|
17521
17883
|
try {
|
|
17522
17884
|
span.addEvent("daemon.receive", { seq: msg.seq, deliveryId: msg.deliveryId });
|
|
17885
|
+
if (this.coreStartingAgentIds.has(msg.agentId)) {
|
|
17886
|
+
const pending = this.coreStartPendingDeliveries.get(msg.agentId) || [];
|
|
17887
|
+
pending.push(msg);
|
|
17888
|
+
this.coreStartPendingDeliveries.set(msg.agentId, pending);
|
|
17889
|
+
span.addEvent("daemon.delivery.buffered_for_start", { pending_count: pending.length });
|
|
17890
|
+
span.end("ok", { attrs: { outcome: "buffered-for-start", pending_count: pending.length } });
|
|
17891
|
+
break;
|
|
17892
|
+
}
|
|
17523
17893
|
const acceptedOrPromise = this.agentManager.deliverMessage(msg.agentId, msg.message, {
|
|
17524
17894
|
deliveryId: msg.deliveryId,
|
|
17525
17895
|
transient: msg.transient ?? false
|
|
@@ -17532,13 +17902,7 @@ var DaemonCore = class {
|
|
|
17532
17902
|
}
|
|
17533
17903
|
const ackSeq = msg.seq > 0 ? msg.seq : msg.message.seq ?? 0;
|
|
17534
17904
|
span.addEvent("daemon.ack.sent", { seq: ackSeq });
|
|
17535
|
-
this.
|
|
17536
|
-
type: "agent:deliver:ack",
|
|
17537
|
-
agentId: msg.agentId,
|
|
17538
|
-
seq: ackSeq,
|
|
17539
|
-
traceparent: formatTraceparent(span.context),
|
|
17540
|
-
deliveryId: msg.deliveryId
|
|
17541
|
-
});
|
|
17905
|
+
this.sendDeliveryAck(msg, formatTraceparent(span.context));
|
|
17542
17906
|
span.end("ok", { attrs: { outcome: "ack-sent", ackSeq, deliveryId: msg.deliveryId } });
|
|
17543
17907
|
}, (err) => {
|
|
17544
17908
|
logger.error(`[Agent ${msg.agentId}] Delivery handling failed`, err);
|