@adhdev/daemon-core 0.9.82-rc.459 → 0.9.82-rc.460
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/index.js +423 -50
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +423 -50
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/contracts.d.ts +66 -0
- package/dist/mesh/coordinator-prompt.d.ts +7 -20
- package/dist/mesh/mesh-events-pending.d.ts +45 -1
- package/dist/mesh/mesh-ledger.d.ts +18 -0
- package/dist/mesh/mesh-queue-assignment.d.ts +17 -0
- package/dist/mesh/mesh-runtime-store.d.ts +26 -0
- package/package.json +6 -3
- package/src/commands/router-refine.ts +15 -2
- package/src/mesh/contracts.ts +131 -0
- package/src/mesh/coordinator-prompt.ts +133 -13
- package/src/mesh/mesh-events-pending.ts +111 -1
- package/src/mesh/mesh-ledger.ts +31 -0
- package/src/mesh/mesh-node-identity.ts +6 -0
- package/src/mesh/mesh-queue-assignment.ts +55 -4
- package/src/mesh/mesh-reconcile-loop.ts +147 -17
- package/src/mesh/mesh-runtime-store.ts +164 -3
package/dist/index.js
CHANGED
|
@@ -409,10 +409,10 @@ function readInjected(value) {
|
|
|
409
409
|
}
|
|
410
410
|
function getDaemonBuildInfo() {
|
|
411
411
|
if (cached) return cached;
|
|
412
|
-
const commit = readInjected(true ? "
|
|
413
|
-
const commitShort = readInjected(true ? "
|
|
414
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
415
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
412
|
+
const commit = readInjected(true ? "f8ce1329d3bdef9564c4130a1e7f0b607738f3cd" : void 0) ?? "unknown";
|
|
413
|
+
const commitShort = readInjected(true ? "f8ce1329" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
414
|
+
const version = readInjected(true ? "0.9.82-rc.460" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
415
|
+
const builtAt = readInjected(true ? "2026-07-04T14:24:11.778Z" : void 0);
|
|
416
416
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
417
417
|
return cached;
|
|
418
418
|
}
|
|
@@ -3467,6 +3467,33 @@ __export(coordinator_prompt_exports, {
|
|
|
3467
3467
|
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt
|
|
3468
3468
|
});
|
|
3469
3469
|
function buildCoordinatorSystemPrompt(ctx) {
|
|
3470
|
+
let prompt = assembleCoordinatorPrompt(ctx, {});
|
|
3471
|
+
if (byteLength2(prompt) <= PROMPT_SOFT_CAP_BYTES) return prompt;
|
|
3472
|
+
if (usesOverrideBase(ctx)) return prompt;
|
|
3473
|
+
const shed = [];
|
|
3474
|
+
prompt = assembleCoordinatorPrompt(ctx, { dropOperatingNotes: true });
|
|
3475
|
+
shed.push("operating notes");
|
|
3476
|
+
if (byteLength2(prompt) <= PROMPT_SOFT_CAP_BYTES) {
|
|
3477
|
+
return appendTruncationNotice(prompt, shed);
|
|
3478
|
+
}
|
|
3479
|
+
prompt = assembleCoordinatorPrompt(ctx, { dropOperatingNotes: true, dropRecentActivity: true });
|
|
3480
|
+
shed.push("recent activity");
|
|
3481
|
+
return appendTruncationNotice(prompt, shed);
|
|
3482
|
+
}
|
|
3483
|
+
function usesOverrideBase(ctx) {
|
|
3484
|
+
if (ctx.mesh.coordinator?.systemPromptOverride?.trim()) return true;
|
|
3485
|
+
return readUserPromptFile(ctx.coordinatorCliType, "md") !== null;
|
|
3486
|
+
}
|
|
3487
|
+
function byteLength2(s2) {
|
|
3488
|
+
return Buffer.byteLength(s2, "utf8");
|
|
3489
|
+
}
|
|
3490
|
+
function appendTruncationNotice(prompt, shed) {
|
|
3491
|
+
if (shed.length === 0) return prompt;
|
|
3492
|
+
return `${prompt}
|
|
3493
|
+
|
|
3494
|
+
_Prompt exceeded the ${Math.floor(PROMPT_SOFT_CAP_BYTES / 1024)}KB soft cap; omitted to fit: ${shed.join(", ")}. Full detail remains in the ledger (\`mesh_task_history\` / \`mesh_record_note\`)._`;
|
|
3495
|
+
}
|
|
3496
|
+
function assembleCoordinatorPrompt(ctx, drop) {
|
|
3470
3497
|
const { mesh, userInstruction, coordinatorCliType } = ctx;
|
|
3471
3498
|
const meshOverride = mesh.coordinator?.systemPromptOverride?.trim();
|
|
3472
3499
|
let base;
|
|
@@ -3477,7 +3504,7 @@ function buildCoordinatorSystemPrompt(ctx) {
|
|
|
3477
3504
|
if (userOverride !== null) {
|
|
3478
3505
|
base = expandPromptPlaceholders(userOverride, ctx);
|
|
3479
3506
|
} else {
|
|
3480
|
-
base = buildDefaultCoordinatorPrompt(ctx);
|
|
3507
|
+
base = buildDefaultCoordinatorPrompt(ctx, drop);
|
|
3481
3508
|
}
|
|
3482
3509
|
}
|
|
3483
3510
|
const sections = [base];
|
|
@@ -3495,7 +3522,7 @@ ${userInstruction}`);
|
|
|
3495
3522
|
}
|
|
3496
3523
|
return sections.join("\n\n");
|
|
3497
3524
|
}
|
|
3498
|
-
function buildDefaultCoordinatorPrompt(ctx) {
|
|
3525
|
+
function buildDefaultCoordinatorPrompt(ctx, drop = {}) {
|
|
3499
3526
|
const { mesh, status, coordinatorCliType } = ctx;
|
|
3500
3527
|
const sections = [];
|
|
3501
3528
|
sections.push(`You are a **Repo Mesh Coordinator** \u2014 a technical team lead who orchestrates work across multiple agent sessions on a shared Git repository.
|
|
@@ -3513,10 +3540,14 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
|
3513
3540
|
if (ctx.missionSection?.trim()) {
|
|
3514
3541
|
sections.push(ctx.missionSection.trim());
|
|
3515
3542
|
}
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3543
|
+
if (!drop.dropRecentActivity) {
|
|
3544
|
+
const recentActivity = buildRecentActivitySection(ctx.recentActivity);
|
|
3545
|
+
if (recentActivity) sections.push(recentActivity);
|
|
3546
|
+
}
|
|
3547
|
+
if (!drop.dropOperatingNotes) {
|
|
3548
|
+
const operatingNotes = buildOperatingNotesSection(ctx.operatingNotes);
|
|
3549
|
+
if (operatingNotes) sections.push(operatingNotes);
|
|
3550
|
+
}
|
|
3520
3551
|
sections.push(buildPolicySection(mergeAndNormalizePolicy(void 0, mesh.policy)));
|
|
3521
3552
|
sections.push(TOOLS_SECTION);
|
|
3522
3553
|
sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
|
|
@@ -3630,6 +3661,7 @@ function buildRecentActivitySection(activity) {
|
|
|
3630
3661
|
const assigned = Number.isFinite(activity.assignedTasks) ? Number(activity.assignedTasks) : 0;
|
|
3631
3662
|
const stalled = Number.isFinite(activity.stalledTasks) ? Number(activity.stalledTasks) : 0;
|
|
3632
3663
|
const recentFailureCount = Number.isFinite(activity.recentFailureCount) ? Number(activity.recentFailureCount) : failures.length;
|
|
3664
|
+
const windowMinutes = Number.isFinite(activity.windowMinutes) && Number(activity.windowMinutes) > 0 ? Math.floor(Number(activity.windowMinutes)) : 30;
|
|
3633
3665
|
if (failures.length === 0 && pending === 0 && assigned === 0 && stalled === 0 && recentFailureCount === 0) {
|
|
3634
3666
|
return "";
|
|
3635
3667
|
}
|
|
@@ -3640,7 +3672,7 @@ function buildRecentActivitySection(activity) {
|
|
|
3640
3672
|
if (pending > 0) counts.push(`**${pending}** pending`);
|
|
3641
3673
|
if (assigned > 0) counts.push(`**${assigned}** assigned`);
|
|
3642
3674
|
if (stalled > 0) counts.push(`**${stalled}** stalled`);
|
|
3643
|
-
if (recentFailureCount > 0) counts.push(`**${recentFailureCount}** failed in the last
|
|
3675
|
+
if (recentFailureCount > 0) counts.push(`**${recentFailureCount}** failed in the last ${windowMinutes} min`);
|
|
3644
3676
|
if (counts.length) lines.push(`- Queue/ledger: ${counts.join(", ")}.`);
|
|
3645
3677
|
if (activity.lastActivityAt) lines.push(`- Last ledger activity: ${activity.lastActivityAt}.`);
|
|
3646
3678
|
if (failures.length > 0) {
|
|
@@ -3664,15 +3696,25 @@ function buildOperatingNotesSection(notes) {
|
|
|
3664
3696
|
pattern_to_avoid: "pattern to avoid",
|
|
3665
3697
|
recovery_lesson: "recovery lesson"
|
|
3666
3698
|
};
|
|
3699
|
+
const omittedCount = Math.max(0, valid.length - OPERATING_NOTES_PROMPT_CAP);
|
|
3700
|
+
const shown = omittedCount > 0 ? valid.slice(-OPERATING_NOTES_PROMPT_CAP) : valid;
|
|
3667
3701
|
const lines = ["## Operating Notes", ""];
|
|
3668
3702
|
lines.push("Lessons earlier coordinators on this mesh recorded via `mesh_record_note`. Treat them as accumulated operating knowledge \u2014 apply them. When you learn a durable lesson (a provider quirk, a pattern to avoid, a recovery lesson), record it with `mesh_record_note` so future coordinators inherit it.");
|
|
3669
3703
|
lines.push("");
|
|
3670
|
-
for (const n of
|
|
3704
|
+
for (const n of shown) {
|
|
3671
3705
|
const cat = n.category && categoryLabel[n.category] ? `[${categoryLabel[n.category]}] ` : "";
|
|
3672
|
-
lines.push(`- ${cat}${n.text.trim()}`);
|
|
3706
|
+
lines.push(`- ${cat}${truncateNote(n.text.trim())}`);
|
|
3707
|
+
}
|
|
3708
|
+
if (omittedCount > 0) {
|
|
3709
|
+
lines.push("");
|
|
3710
|
+
lines.push(`_${omittedCount} older note${omittedCount === 1 ? "" : "s"} omitted (kept in ledger; prune with \`mesh_forget_note\`)._`);
|
|
3673
3711
|
}
|
|
3674
3712
|
return lines.join("\n");
|
|
3675
3713
|
}
|
|
3714
|
+
function truncateNote(text) {
|
|
3715
|
+
if (text.length <= OPERATING_NOTE_MAX_CHARS) return text;
|
|
3716
|
+
return `${text.slice(0, OPERATING_NOTE_MAX_CHARS).trimEnd()}\u2026 [truncated]`;
|
|
3717
|
+
}
|
|
3676
3718
|
function buildPolicySection(policy) {
|
|
3677
3719
|
const rules = [];
|
|
3678
3720
|
if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
|
|
@@ -3711,9 +3753,17 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
3711
3753
|
- **Honor per-node instructions.** When a node carries a \u{1F4CC} Node instruction in the nodes section, include the relevant parts of that instruction in the task message you send to that node. Don't paraphrase the instruction into your own words \u2014 quote it verbatim so the worker agent sees exactly what the user wrote.
|
|
3712
3754
|
- **Mission status does not update itself.** When a mission's tasks are all done or the work is abandoned, explicitly call \`mesh_mission_upsert\` to set status \`completed\` or \`abandoned\`. Never leave a finished mission in \`active\`. All-cancelled tasks with no further work \u2192 \`abandoned\`.
|
|
3713
3755
|
- **Never fabricate tool results.** Always call the actual tool.
|
|
3714
|
-
- **Keep the user informed.** One or two sentences after each delegation round.${coordinatorNote}
|
|
3756
|
+
- **Keep the user informed.** One or two sentences after each delegation round.${coordinatorNote}
|
|
3757
|
+
|
|
3758
|
+
### Task Messaging Requirements
|
|
3759
|
+
|
|
3760
|
+
When you compose the task message you dispatch to a node, include these requirements so the worker follows repo conventions the daemon can't enforce for it:
|
|
3761
|
+
|
|
3762
|
+
- **OSS English commits.** If a task commits anything under \`oss/\` (an AGPL public repo whose history external contributors read), tell the worker explicitly that commit messages in \`oss/\` MUST be English. Root-level commits (proprietary packages) may use any language.
|
|
3763
|
+
- **Scoped test runs.** For a validation or code-change task, instruct the worker to run only the tests covering the changed files (\`vitest run <path>\` or \`-t <name>\`), not the whole suite. Run the full suite only when the task is explicitly a full-suite gate \u2014 a broad daemon-core run is minutes of wall-clock and the biggest source of worker slowness.
|
|
3764
|
+
- **Branch convergence state.** For a worktree task, require the completion report to classify the touched branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. A task that ends on a non-main branch is not complete unless the report names that state and the next step.`;
|
|
3715
3765
|
}
|
|
3716
|
-
var fs2, os2, path8, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, ONBOARDING_SECTION;
|
|
3766
|
+
var fs2, os2, path8, PROMPT_SOFT_CAP_BYTES, OPERATING_NOTES_PROMPT_CAP, OPERATING_NOTE_MAX_CHARS, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, ONBOARDING_SECTION;
|
|
3717
3767
|
var init_coordinator_prompt = __esm({
|
|
3718
3768
|
"src/mesh/coordinator-prompt.ts"() {
|
|
3719
3769
|
"use strict";
|
|
@@ -3721,6 +3771,9 @@ var init_coordinator_prompt = __esm({
|
|
|
3721
3771
|
os2 = __toESM(require("os"));
|
|
3722
3772
|
path8 = __toESM(require("path"));
|
|
3723
3773
|
init_repo_mesh_types();
|
|
3774
|
+
PROMPT_SOFT_CAP_BYTES = 60 * 1024;
|
|
3775
|
+
OPERATING_NOTES_PROMPT_CAP = 20;
|
|
3776
|
+
OPERATING_NOTE_MAX_CHARS = 300;
|
|
3724
3777
|
TOOLS_SECTION = `## Available Tools
|
|
3725
3778
|
|
|
3726
3779
|
| Tool | Purpose |
|
|
@@ -4120,6 +4173,54 @@ var init_load_better_sqlite3 = __esm({
|
|
|
4120
4173
|
}
|
|
4121
4174
|
});
|
|
4122
4175
|
|
|
4176
|
+
// src/mesh/contracts.ts
|
|
4177
|
+
function defaultScopeForEvent(eventName) {
|
|
4178
|
+
if (SYSTEM_EVENTS.has(eventName)) return "system";
|
|
4179
|
+
if (TERMINAL_TASK_EVENTS.has(eventName)) return "unicast";
|
|
4180
|
+
return "broadcast";
|
|
4181
|
+
}
|
|
4182
|
+
function coordinatorIdentityFromEmitFields(fields) {
|
|
4183
|
+
const daemonId = typeof fields.daemonId === "string" && fields.daemonId.length > 0 ? fields.daemonId : void 0;
|
|
4184
|
+
if (!daemonId) return void 0;
|
|
4185
|
+
const coordinatorRunId = typeof fields.coordinatorRunId === "string" && fields.coordinatorRunId.length > 0 ? fields.coordinatorRunId : daemonId;
|
|
4186
|
+
const sessionId = typeof fields.sessionId === "string" && fields.sessionId.length > 0 ? fields.sessionId : void 0;
|
|
4187
|
+
return sessionId !== void 0 ? { daemonId, coordinatorRunId, sessionId } : { daemonId, coordinatorRunId };
|
|
4188
|
+
}
|
|
4189
|
+
function buildPendingEventEmitStamp(opts) {
|
|
4190
|
+
if (!opts.dispatchedBy) return void 0;
|
|
4191
|
+
let scope = opts.scope ?? defaultScopeForEvent(opts.eventName);
|
|
4192
|
+
let intendedFor = opts.intendedFor;
|
|
4193
|
+
if (scope === "unicast" && !intendedFor) {
|
|
4194
|
+
scope = "broadcast";
|
|
4195
|
+
}
|
|
4196
|
+
if (scope !== "unicast") intendedFor = void 0;
|
|
4197
|
+
return {
|
|
4198
|
+
protocolVersion: MESH_PROTOCOL_VERSION_V2,
|
|
4199
|
+
eventId: opts.eventId,
|
|
4200
|
+
scope,
|
|
4201
|
+
dispatchedBy: opts.dispatchedBy,
|
|
4202
|
+
...intendedFor ? { intendedFor } : {}
|
|
4203
|
+
};
|
|
4204
|
+
}
|
|
4205
|
+
var MESH_PROTOCOL_VERSION_V2, TERMINAL_TASK_EVENTS, SYSTEM_EVENTS;
|
|
4206
|
+
var init_contracts = __esm({
|
|
4207
|
+
"src/mesh/contracts.ts"() {
|
|
4208
|
+
"use strict";
|
|
4209
|
+
init_dist();
|
|
4210
|
+
MESH_PROTOCOL_VERSION_V2 = "2.0";
|
|
4211
|
+
TERMINAL_TASK_EVENTS = /* @__PURE__ */ new Set([
|
|
4212
|
+
"agent:generating_completed",
|
|
4213
|
+
"agent:stopped",
|
|
4214
|
+
"refine:completed",
|
|
4215
|
+
"refine:failed",
|
|
4216
|
+
"refine:accepted"
|
|
4217
|
+
]);
|
|
4218
|
+
SYSTEM_EVENTS = /* @__PURE__ */ new Set([
|
|
4219
|
+
"mesh:dispatch_blocked"
|
|
4220
|
+
]);
|
|
4221
|
+
}
|
|
4222
|
+
});
|
|
4223
|
+
|
|
4123
4224
|
// src/mesh/mesh-ledger.ts
|
|
4124
4225
|
var mesh_ledger_exports = {};
|
|
4125
4226
|
__export(mesh_ledger_exports, {
|
|
@@ -4131,6 +4232,7 @@ __export(mesh_ledger_exports, {
|
|
|
4131
4232
|
__clearMeshLedgerForTests: () => __clearMeshLedgerForTests,
|
|
4132
4233
|
appendLedgerEntry: () => appendLedgerEntry,
|
|
4133
4234
|
appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
|
|
4235
|
+
buildLedgerOriginatingCoordinatorStamp: () => buildLedgerOriginatingCoordinatorStamp,
|
|
4134
4236
|
buildTaskCompletionEvidence: () => buildTaskCompletionEvidence,
|
|
4135
4237
|
buildWorkerTaskFooter: () => buildWorkerTaskFooter,
|
|
4136
4238
|
compactLedger: () => compactLedger,
|
|
@@ -4415,6 +4517,15 @@ function buildTaskCompletionEvidence(opts) {
|
|
|
4415
4517
|
}
|
|
4416
4518
|
};
|
|
4417
4519
|
}
|
|
4520
|
+
function buildLedgerOriginatingCoordinatorStamp(fields) {
|
|
4521
|
+
const originatingCoordinator = coordinatorIdentityFromEmitFields({
|
|
4522
|
+
daemonId: fields.coordinatorDaemonId,
|
|
4523
|
+
coordinatorRunId: fields.coordinatorRunId,
|
|
4524
|
+
sessionId: fields.coordinatorSessionId
|
|
4525
|
+
});
|
|
4526
|
+
if (!originatingCoordinator) return void 0;
|
|
4527
|
+
return { originatingCoordinator, protocolVersion: MESH_PROTOCOL_VERSION_V2 };
|
|
4528
|
+
}
|
|
4418
4529
|
function appendLedgerEntry(meshId, partial) {
|
|
4419
4530
|
if (partial.kind === OPERATING_NOTE_KIND) {
|
|
4420
4531
|
const text = operatingNoteText(partial.payload);
|
|
@@ -4909,6 +5020,7 @@ var init_mesh_ledger = __esm({
|
|
|
4909
5020
|
init_dist();
|
|
4910
5021
|
import_events = require("events");
|
|
4911
5022
|
init_mesh_runtime_store();
|
|
5023
|
+
init_contracts();
|
|
4912
5024
|
LEDGER_DIR_NAME = "mesh-ledger";
|
|
4913
5025
|
MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
4914
5026
|
COMPACT_THRESHOLD_BYTES = 2 * 1024 * 1024;
|
|
@@ -6186,7 +6298,18 @@ var init_mesh_runtime_store = __esm({
|
|
|
6186
6298
|
fingerprint TEXT,
|
|
6187
6299
|
queued_at INTEGER NOT NULL,
|
|
6188
6300
|
drained INTEGER NOT NULL DEFAULT 0,
|
|
6189
|
-
drained_at INTEGER
|
|
6301
|
+
drained_at INTEGER,
|
|
6302
|
+
-- v2 protocol envelope (B2a). All nullable so pre-v2 rows and events
|
|
6303
|
+
-- emitted before a coordinator identity is known coexist as v1. The
|
|
6304
|
+
-- authoritative copy of each also rides inside the payload column; these
|
|
6305
|
+
-- columns exist for queryable idempotency (event_id) and scope-based drain
|
|
6306
|
+
-- filtering without JSON-parsing every row. dispatched_by / intended_for
|
|
6307
|
+
-- hold the JSON-serialized CoordinatorIdentity.
|
|
6308
|
+
protocol_version TEXT,
|
|
6309
|
+
event_id TEXT,
|
|
6310
|
+
scope TEXT,
|
|
6311
|
+
dispatched_by TEXT,
|
|
6312
|
+
intended_for TEXT
|
|
6190
6313
|
);
|
|
6191
6314
|
|
|
6192
6315
|
CREATE INDEX IF NOT EXISTS idx_mesh_pending_events_mesh_drained
|
|
@@ -6222,6 +6345,38 @@ var init_mesh_runtime_store = __esm({
|
|
|
6222
6345
|
mesh_id TEXT PRIMARY KEY,
|
|
6223
6346
|
cursor INTEGER NOT NULL DEFAULT 0
|
|
6224
6347
|
);
|
|
6348
|
+
|
|
6349
|
+
-- T2 (B2b): persistent acked-hold state for in-flight direct dispatches.
|
|
6350
|
+
-- The reconcile loop's PHASE-4 acked-hold (death-consequence counter,
|
|
6351
|
+
-- fast-track idle streak, live-confirmed flag) used to live only in a
|
|
6352
|
+
-- process-local Map (mesh-reconcile-loop.ts inFlightAckedHoldState), so a
|
|
6353
|
+
-- daemon restart lost it \u2014 re-opening the door to the duplicate-emit / drop
|
|
6354
|
+
-- window that the PHASE-4 transcript synth backstop then had to correct after
|
|
6355
|
+
-- the fact. Persisting it lets the state survive a restart: the loop
|
|
6356
|
+
-- rehydrates the Map from this table on first touch and stays read-through /
|
|
6357
|
+
-- write-through against it thereafter. Keyed by task_id (one hold per
|
|
6358
|
+
-- in-flight dispatch); mesh_id is carried for per-mesh listing / prune.
|
|
6359
|
+
-- hold_reason \u2014 'live' once a conclusive read confirmed the session
|
|
6360
|
+
-- reachable since the ack, else 'unconfirmed' (drives
|
|
6361
|
+
-- the death-backstop's liveConfirmedSinceAck gate).
|
|
6362
|
+
-- held_at \u2014 ms epoch the hold row was first created.
|
|
6363
|
+
-- first_idle_since_ack \u2014 ms epoch of the FIRST tick in the current continuous
|
|
6364
|
+
-- idle-with-final-assistant run (fast-track streak); NULL
|
|
6365
|
+
-- when the streak is broken / not yet started.
|
|
6366
|
+
-- read_failure_count \u2014 consecutive read_chat failures since the last
|
|
6367
|
+
-- conclusive read (death backstop (a)).
|
|
6368
|
+
CREATE TABLE IF NOT EXISTS mesh_inflight_hold (
|
|
6369
|
+
task_id TEXT PRIMARY KEY,
|
|
6370
|
+
mesh_id TEXT,
|
|
6371
|
+
hold_reason TEXT,
|
|
6372
|
+
held_at INTEGER,
|
|
6373
|
+
first_idle_since_ack INTEGER,
|
|
6374
|
+
read_failure_count INTEGER,
|
|
6375
|
+
updated_at INTEGER
|
|
6376
|
+
);
|
|
6377
|
+
|
|
6378
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_inflight_hold_mesh
|
|
6379
|
+
ON mesh_inflight_hold(mesh_id);
|
|
6225
6380
|
`);
|
|
6226
6381
|
this.migrateMeshIsolationColumns();
|
|
6227
6382
|
}
|
|
@@ -6269,6 +6424,17 @@ var init_mesh_runtime_store = __esm({
|
|
|
6269
6424
|
if (!missionCols.has("source")) {
|
|
6270
6425
|
this.db.exec(`ALTER TABLE mesh_missions ADD COLUMN source TEXT`);
|
|
6271
6426
|
}
|
|
6427
|
+
const pendingCols = this.tableColumns("mesh_pending_events");
|
|
6428
|
+
for (const col of ["protocol_version", "event_id", "scope", "dispatched_by", "intended_for"]) {
|
|
6429
|
+
if (!pendingCols.has(col)) {
|
|
6430
|
+
this.db.exec(`ALTER TABLE mesh_pending_events ADD COLUMN ${col} TEXT`);
|
|
6431
|
+
}
|
|
6432
|
+
}
|
|
6433
|
+
this.db.exec(`
|
|
6434
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_pending_events_event_id
|
|
6435
|
+
ON mesh_pending_events(mesh_id, event_id)
|
|
6436
|
+
WHERE event_id IS NOT NULL
|
|
6437
|
+
`);
|
|
6272
6438
|
} catch (err) {
|
|
6273
6439
|
if (!loggedMigrationFailure) {
|
|
6274
6440
|
loggedMigrationFailure = true;
|
|
@@ -6485,6 +6651,62 @@ var init_mesh_runtime_store = __esm({
|
|
|
6485
6651
|
return current;
|
|
6486
6652
|
});
|
|
6487
6653
|
}
|
|
6654
|
+
// ── Acked-Hold State (T2 / B2b) ──────────────────────────────────────────
|
|
6655
|
+
//
|
|
6656
|
+
// Persistent mirror of the reconcile loop's inFlightAckedHoldState Map. Keyed
|
|
6657
|
+
// by task_id (one in-flight dispatch = one hold). These are plain read/write/
|
|
6658
|
+
// delete/list accessors; the read-through/write-through cache and the restart
|
|
6659
|
+
// rehydrate live in mesh-reconcile-loop.ts.
|
|
6660
|
+
mapInflightHoldRow(r) {
|
|
6661
|
+
if (!r) return null;
|
|
6662
|
+
return {
|
|
6663
|
+
taskId: r.task_id,
|
|
6664
|
+
meshId: r.mesh_id ?? null,
|
|
6665
|
+
holdReason: r.hold_reason ?? null,
|
|
6666
|
+
heldAt: r.held_at ?? null,
|
|
6667
|
+
firstIdleSinceAck: r.first_idle_since_ack ?? null,
|
|
6668
|
+
readFailureCount: r.read_failure_count ?? null,
|
|
6669
|
+
updatedAt: r.updated_at ?? null
|
|
6670
|
+
};
|
|
6671
|
+
}
|
|
6672
|
+
upsertInflightHold(entry) {
|
|
6673
|
+
const now = Date.now();
|
|
6674
|
+
this.db.prepare(`
|
|
6675
|
+
INSERT INTO mesh_inflight_hold
|
|
6676
|
+
(task_id, mesh_id, hold_reason, held_at, first_idle_since_ack, read_failure_count, updated_at)
|
|
6677
|
+
VALUES (@taskId, @meshId, @holdReason, @heldAt, @firstIdleSinceAck, @readFailureCount, @updatedAt)
|
|
6678
|
+
ON CONFLICT(task_id) DO UPDATE SET
|
|
6679
|
+
mesh_id = excluded.mesh_id,
|
|
6680
|
+
hold_reason = excluded.hold_reason,
|
|
6681
|
+
first_idle_since_ack = excluded.first_idle_since_ack,
|
|
6682
|
+
read_failure_count = excluded.read_failure_count,
|
|
6683
|
+
updated_at = excluded.updated_at
|
|
6684
|
+
`).run({
|
|
6685
|
+
taskId: entry.taskId,
|
|
6686
|
+
meshId: entry.meshId ?? null,
|
|
6687
|
+
holdReason: entry.holdReason ?? null,
|
|
6688
|
+
heldAt: entry.heldAt ?? now,
|
|
6689
|
+
firstIdleSinceAck: entry.firstIdleSinceAck ?? null,
|
|
6690
|
+
readFailureCount: entry.readFailureCount ?? null,
|
|
6691
|
+
updatedAt: now
|
|
6692
|
+
});
|
|
6693
|
+
this.maybeCheckpointWal();
|
|
6694
|
+
}
|
|
6695
|
+
getInflightHold(taskId) {
|
|
6696
|
+
const row = this.db.prepare(
|
|
6697
|
+
"SELECT * FROM mesh_inflight_hold WHERE task_id = ?"
|
|
6698
|
+
).get(taskId);
|
|
6699
|
+
return this.mapInflightHoldRow(row);
|
|
6700
|
+
}
|
|
6701
|
+
listInflightHoldsByMesh(meshId) {
|
|
6702
|
+
const rows = this.db.prepare(
|
|
6703
|
+
"SELECT * FROM mesh_inflight_hold WHERE mesh_id = ?"
|
|
6704
|
+
).all(meshId);
|
|
6705
|
+
return rows.map((r) => this.mapInflightHoldRow(r)).filter((r) => r !== null);
|
|
6706
|
+
}
|
|
6707
|
+
deleteInflightHold(taskId) {
|
|
6708
|
+
this.db.prepare("DELETE FROM mesh_inflight_hold WHERE task_id = ?").run(taskId);
|
|
6709
|
+
}
|
|
6488
6710
|
/**
|
|
6489
6711
|
* Count active (status='assigned') tasks on a (node, provider) combination,
|
|
6490
6712
|
* matched by the assignedProviderType stamped on the payload at claim time.
|
|
@@ -7220,8 +7442,9 @@ var init_mesh_runtime_store = __esm({
|
|
|
7220
7442
|
insertPendingEvent(event) {
|
|
7221
7443
|
const result = this.db.prepare(
|
|
7222
7444
|
`INSERT OR IGNORE INTO mesh_pending_events
|
|
7223
|
-
(id, mesh_id, coordinator_daemon_id, event, payload, fingerprint, queued_at
|
|
7224
|
-
|
|
7445
|
+
(id, mesh_id, coordinator_daemon_id, event, payload, fingerprint, queued_at,
|
|
7446
|
+
protocol_version, event_id, scope, dispatched_by, intended_for)
|
|
7447
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
7225
7448
|
).run(
|
|
7226
7449
|
event.id,
|
|
7227
7450
|
event.meshId,
|
|
@@ -7229,7 +7452,12 @@ var init_mesh_runtime_store = __esm({
|
|
|
7229
7452
|
event.event,
|
|
7230
7453
|
JSON.stringify(event.payload ?? {}),
|
|
7231
7454
|
event.fingerprint ?? null,
|
|
7232
|
-
event.queuedAt
|
|
7455
|
+
event.queuedAt,
|
|
7456
|
+
event.protocolVersion ?? null,
|
|
7457
|
+
event.eventId ?? null,
|
|
7458
|
+
event.scope ?? null,
|
|
7459
|
+
event.dispatchedBy ?? null,
|
|
7460
|
+
event.intendedFor ?? null
|
|
7233
7461
|
);
|
|
7234
7462
|
this.maybeCheckpointWal();
|
|
7235
7463
|
return result.changes > 0;
|
|
@@ -11293,7 +11521,35 @@ function trimPendingEventsIfNeeded(path44) {
|
|
|
11293
11521
|
} catch {
|
|
11294
11522
|
}
|
|
11295
11523
|
}
|
|
11296
|
-
function
|
|
11524
|
+
function stampPendingEventV2(event, hint) {
|
|
11525
|
+
if (event.protocolVersion === MESH_PROTOCOL_VERSION_V2 && readNonEmptyString2(event.eventId)) {
|
|
11526
|
+
return event;
|
|
11527
|
+
}
|
|
11528
|
+
const dispatchedBy = hint?.dispatchedBy ?? coordinatorIdentityFromEmitFields({
|
|
11529
|
+
daemonId: event.targetCoordinatorDaemonId,
|
|
11530
|
+
coordinatorRunId: hint?.coordinatorRunId,
|
|
11531
|
+
sessionId: event.targetCoordinatorSessionId
|
|
11532
|
+
});
|
|
11533
|
+
const intendedFor = hint?.intendedFor ?? dispatchedBy;
|
|
11534
|
+
const stamp = buildPendingEventEmitStamp({
|
|
11535
|
+
eventName: event.event,
|
|
11536
|
+
eventId: (0, import_crypto8.randomUUID)(),
|
|
11537
|
+
dispatchedBy,
|
|
11538
|
+
intendedFor,
|
|
11539
|
+
scope: hint?.scope
|
|
11540
|
+
});
|
|
11541
|
+
if (!stamp) return event;
|
|
11542
|
+
return {
|
|
11543
|
+
...event,
|
|
11544
|
+
protocolVersion: stamp.protocolVersion,
|
|
11545
|
+
eventId: stamp.eventId,
|
|
11546
|
+
scope: stamp.scope,
|
|
11547
|
+
dispatchedBy: stamp.dispatchedBy,
|
|
11548
|
+
...stamp.intendedFor ? { intendedFor: stamp.intendedFor } : {}
|
|
11549
|
+
};
|
|
11550
|
+
}
|
|
11551
|
+
function queuePendingMeshCoordinatorEvent(rawEvent, hint) {
|
|
11552
|
+
const event = stampPendingEventV2(rawEvent, hint);
|
|
11297
11553
|
try {
|
|
11298
11554
|
if (hasPendingRefineTerminalEventDuplicate(event)) {
|
|
11299
11555
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for refine job ${readRefineJobId2(event)}`);
|
|
@@ -11313,7 +11569,16 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
11313
11569
|
event: event.event,
|
|
11314
11570
|
payload: event,
|
|
11315
11571
|
fingerprint: fingerprint || null,
|
|
11316
|
-
queuedAt: event.queuedAt
|
|
11572
|
+
queuedAt: event.queuedAt,
|
|
11573
|
+
// v2 envelope columns (B2a) — all nullable so v1 rows coexist. The
|
|
11574
|
+
// authoritative copy still rides inside `payload`; these columns exist
|
|
11575
|
+
// for queryable idempotency (event_id) and scope-based drain filtering
|
|
11576
|
+
// (scope / intended_for) without JSON-parsing every row.
|
|
11577
|
+
protocolVersion: event.protocolVersion ?? null,
|
|
11578
|
+
eventId: event.eventId ?? null,
|
|
11579
|
+
scope: event.scope ?? null,
|
|
11580
|
+
dispatchedBy: event.dispatchedBy ? JSON.stringify(event.dispatchedBy) : null,
|
|
11581
|
+
intendedFor: event.intendedFor ? JSON.stringify(event.intendedFor) : null
|
|
11317
11582
|
});
|
|
11318
11583
|
sqliteOk = true;
|
|
11319
11584
|
} catch {
|
|
@@ -11536,6 +11801,7 @@ var init_mesh_events_pending = __esm({
|
|
|
11536
11801
|
init_mesh_runtime_store();
|
|
11537
11802
|
init_mesh_events_utils();
|
|
11538
11803
|
init_dist();
|
|
11804
|
+
init_contracts();
|
|
11539
11805
|
REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
|
|
11540
11806
|
TERMINAL_COMPLETION_EVENTS = /* @__PURE__ */ new Set(["agent:generating_completed", "agent:stopped"]);
|
|
11541
11807
|
MAX_PENDING_EVENTS_BYTES = 100 * 1024;
|
|
@@ -13241,6 +13507,18 @@ function nodeActiveLoad(meshId, nodeId) {
|
|
|
13241
13507
|
function resolveSchedulingStrategy(mesh) {
|
|
13242
13508
|
return normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
|
|
13243
13509
|
}
|
|
13510
|
+
function buildSchedulingPool(localCandidates, remoteCandidates) {
|
|
13511
|
+
const pool = [...localCandidates, ...remoteCandidates].map((c) => ({
|
|
13512
|
+
...c,
|
|
13513
|
+
nodeId: normalizeMeshNodeId(c.node) ?? c.nodeId
|
|
13514
|
+
}));
|
|
13515
|
+
const uniqueNodes = [...new Set(pool.map((c) => c.nodeId))].map((nodeId, index) => ({
|
|
13516
|
+
nodeId,
|
|
13517
|
+
node: pool.find((c) => meshNodeIdMatches({ id: c.nodeId }, nodeId))?.node,
|
|
13518
|
+
index
|
|
13519
|
+
}));
|
|
13520
|
+
return { pool, uniqueNodes };
|
|
13521
|
+
}
|
|
13244
13522
|
function orderEligibleNodes(meshId, strategy, nodes, opts) {
|
|
13245
13523
|
if (strategy === "first_eligible" || nodes.length <= 1) {
|
|
13246
13524
|
return nodes;
|
|
@@ -13779,12 +14057,11 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
13779
14057
|
for (const candidate of localCandidates) assignIdleCandidate(candidate);
|
|
13780
14058
|
for (const candidate of remoteCandidates) assignIdleCandidate(candidate);
|
|
13781
14059
|
} else {
|
|
13782
|
-
const pool =
|
|
14060
|
+
const { pool, uniqueNodes } = buildSchedulingPool(localCandidates, remoteCandidates);
|
|
13783
14061
|
const baseIndex = /* @__PURE__ */ new Map();
|
|
13784
14062
|
pool.forEach((c, i) => {
|
|
13785
14063
|
if (!baseIndex.has(c.nodeId)) baseIndex.set(c.nodeId, i);
|
|
13786
14064
|
});
|
|
13787
|
-
const uniqueNodes = [...new Set(pool.map((c) => c.nodeId))].map((nodeId, index) => ({ nodeId, node: pool.find((c) => c.nodeId === nodeId)?.node, index }));
|
|
13788
14065
|
const ranked = orderEligibleNodes(meshId, strategy, uniqueNodes, { bumpCursor: true });
|
|
13789
14066
|
const rankIndex = new Map(ranked.map((r, i) => [r.nodeId, i]));
|
|
13790
14067
|
const remaining = [...pool];
|
|
@@ -14903,7 +15180,7 @@ function flattenContent(content) {
|
|
|
14903
15180
|
if (typeof content === "string") return content;
|
|
14904
15181
|
return flattenMessageParts(normalizeMessageParts(content));
|
|
14905
15182
|
}
|
|
14906
|
-
var
|
|
15183
|
+
var init_contracts2 = __esm({
|
|
14907
15184
|
"src/providers/contracts.ts"() {
|
|
14908
15185
|
"use strict";
|
|
14909
15186
|
init_io_contracts();
|
|
@@ -15267,7 +15544,7 @@ var DEFAULT_FINAL_SUMMARY_MAX_CHARS, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VI
|
|
|
15267
15544
|
var init_chat_message_normalization = __esm({
|
|
15268
15545
|
"src/providers/chat-message-normalization.ts"() {
|
|
15269
15546
|
"use strict";
|
|
15270
|
-
|
|
15547
|
+
init_contracts2();
|
|
15271
15548
|
DEFAULT_FINAL_SUMMARY_MAX_CHARS = 16e3;
|
|
15272
15549
|
BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
|
|
15273
15550
|
CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
|
|
@@ -15506,7 +15783,7 @@ ${cleanBody}`;
|
|
|
15506
15783
|
var init_control_effects = __esm({
|
|
15507
15784
|
"src/providers/control-effects.ts"() {
|
|
15508
15785
|
"use strict";
|
|
15509
|
-
|
|
15786
|
+
init_contracts2();
|
|
15510
15787
|
init_chat_message_normalization();
|
|
15511
15788
|
}
|
|
15512
15789
|
});
|
|
@@ -17684,6 +17961,85 @@ function resolveAckedTranscriptFastTrackGraceMs() {
|
|
|
17684
17961
|
function inFlightSynthKey(meshId, taskId) {
|
|
17685
17962
|
return `${meshId}::${taskId}`;
|
|
17686
17963
|
}
|
|
17964
|
+
function taskIdFromSynthKey(meshId, synthKey) {
|
|
17965
|
+
const prefix = `${meshId}::`;
|
|
17966
|
+
return synthKey.startsWith(prefix) ? synthKey.slice(prefix.length) : synthKey;
|
|
17967
|
+
}
|
|
17968
|
+
function holdStore() {
|
|
17969
|
+
try {
|
|
17970
|
+
return MeshRuntimeStore.getInstance();
|
|
17971
|
+
} catch {
|
|
17972
|
+
return void 0;
|
|
17973
|
+
}
|
|
17974
|
+
}
|
|
17975
|
+
function getHoldState(synthKey, meshId) {
|
|
17976
|
+
const cached3 = inFlightAckedHoldState.get(synthKey);
|
|
17977
|
+
if (cached3) return cached3;
|
|
17978
|
+
const store = holdStore();
|
|
17979
|
+
if (!store) return void 0;
|
|
17980
|
+
let row;
|
|
17981
|
+
try {
|
|
17982
|
+
row = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
17983
|
+
} catch {
|
|
17984
|
+
return void 0;
|
|
17985
|
+
}
|
|
17986
|
+
if (!row) return void 0;
|
|
17987
|
+
const state = {
|
|
17988
|
+
liveConfirmedSinceAck: row.holdReason === "live",
|
|
17989
|
+
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
17990
|
+
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {}
|
|
17991
|
+
};
|
|
17992
|
+
inFlightAckedHoldState.set(synthKey, state);
|
|
17993
|
+
return state;
|
|
17994
|
+
}
|
|
17995
|
+
function setHoldState(synthKey, meshId, state) {
|
|
17996
|
+
inFlightAckedHoldState.set(synthKey, state);
|
|
17997
|
+
const store = holdStore();
|
|
17998
|
+
if (!store) return;
|
|
17999
|
+
try {
|
|
18000
|
+
store.upsertInflightHold({
|
|
18001
|
+
taskId: taskIdFromSynthKey(meshId, synthKey),
|
|
18002
|
+
meshId,
|
|
18003
|
+
holdReason: state.liveConfirmedSinceAck ? "live" : "unconfirmed",
|
|
18004
|
+
firstIdleSinceAck: state.transcriptIdleSinceMs ?? null,
|
|
18005
|
+
readFailureCount: state.consecutiveReadFailures
|
|
18006
|
+
});
|
|
18007
|
+
} catch {
|
|
18008
|
+
}
|
|
18009
|
+
}
|
|
18010
|
+
function deleteHoldState(synthKey, meshId) {
|
|
18011
|
+
inFlightAckedHoldState.delete(synthKey);
|
|
18012
|
+
const store = holdStore();
|
|
18013
|
+
if (!store) return;
|
|
18014
|
+
try {
|
|
18015
|
+
store.deleteInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
18016
|
+
} catch {
|
|
18017
|
+
}
|
|
18018
|
+
}
|
|
18019
|
+
function rehydrateAckedHoldsForMesh(meshId) {
|
|
18020
|
+
if (rehydratedHoldMeshes.has(meshId)) return;
|
|
18021
|
+
rehydratedHoldMeshes.add(meshId);
|
|
18022
|
+
const store = holdStore();
|
|
18023
|
+
if (!store) return;
|
|
18024
|
+
let rows;
|
|
18025
|
+
try {
|
|
18026
|
+
rows = store.listInflightHoldsByMesh(meshId);
|
|
18027
|
+
} catch {
|
|
18028
|
+
return;
|
|
18029
|
+
}
|
|
18030
|
+
for (const row of rows) {
|
|
18031
|
+
const synthKey = inFlightSynthKey(meshId, row.taskId);
|
|
18032
|
+
if (inFlightAckedHoldState.has(synthKey)) continue;
|
|
18033
|
+
inFlightAckedHoldState.set(synthKey, {
|
|
18034
|
+
liveConfirmedSinceAck: row.holdReason === "live",
|
|
18035
|
+
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
18036
|
+
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {}
|
|
18037
|
+
});
|
|
18038
|
+
}
|
|
18039
|
+
if (rows.length > 0) {
|
|
18040
|
+
LOG.info("MeshReconcile", `Rehydrated ${rows.length} persisted acked-hold row(s) for mesh ${meshId} after (re)start`);
|
|
18041
|
+
}
|
|
18042
|
+
}
|
|
17687
18043
|
function resolveCoordinatorDaemonIds(components) {
|
|
17688
18044
|
const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
|
|
17689
18045
|
const machineId = readNonEmptyString2(loadConfig().machineId);
|
|
@@ -18475,15 +18831,27 @@ async function reprobeWorkerStatus(components, args) {
|
|
|
18475
18831
|
}
|
|
18476
18832
|
async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId) {
|
|
18477
18833
|
const dispatches = getActiveDirectDispatches(mesh.id);
|
|
18478
|
-
|
|
18834
|
+
rehydrateAckedHoldsForMesh(mesh.id);
|
|
18479
18835
|
const activeTaskKeys = new Set(
|
|
18480
18836
|
dispatches.map((d) => readNonEmptyString2(d.taskId)).filter(Boolean).map((taskId) => inFlightSynthKey(mesh.id, taskId))
|
|
18481
18837
|
);
|
|
18838
|
+
const heldKeys = /* @__PURE__ */ new Set();
|
|
18482
18839
|
for (const key2 of inFlightAckedHoldState.keys()) {
|
|
18483
|
-
if (key2.startsWith(`${mesh.id}::`)
|
|
18484
|
-
|
|
18840
|
+
if (key2.startsWith(`${mesh.id}::`)) heldKeys.add(key2);
|
|
18841
|
+
}
|
|
18842
|
+
const store = holdStore();
|
|
18843
|
+
if (store) {
|
|
18844
|
+
try {
|
|
18845
|
+
for (const row of store.listInflightHoldsByMesh(mesh.id)) {
|
|
18846
|
+
heldKeys.add(inFlightSynthKey(mesh.id, row.taskId));
|
|
18847
|
+
}
|
|
18848
|
+
} catch {
|
|
18485
18849
|
}
|
|
18486
18850
|
}
|
|
18851
|
+
for (const key2 of heldKeys) {
|
|
18852
|
+
if (!activeTaskKeys.has(key2)) deleteHoldState(key2, mesh.id);
|
|
18853
|
+
}
|
|
18854
|
+
if (dispatches.length === 0) return;
|
|
18487
18855
|
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
18488
18856
|
const nodeById = new Map(mesh.nodes.map((n) => [n.id, n]));
|
|
18489
18857
|
for (const dispatch of dispatches) {
|
|
@@ -18530,25 +18898,25 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
18530
18898
|
if (!payload && !readFailed) continue;
|
|
18531
18899
|
if (readFailed || !payload) {
|
|
18532
18900
|
if (isAcked) {
|
|
18533
|
-
const prior =
|
|
18901
|
+
const prior = getHoldState(synthKey, mesh.id);
|
|
18534
18902
|
const failures = (prior?.consecutiveReadFailures ?? 0) + 1;
|
|
18535
18903
|
const liveConfirmedSinceAck = prior?.liveConfirmedSinceAck ?? false;
|
|
18536
|
-
|
|
18904
|
+
setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck, consecutiveReadFailures: failures });
|
|
18537
18905
|
if (liveConfirmedSinceAck && failures >= ACKED_DEATH_CONSECUTIVE_READ_FAILURES) {
|
|
18538
18906
|
LOG.warn("MeshReconcile", `Acked-hold death signal: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read_chat failed ${failures}x consecutively after a live-confirmed ack \u2014 worker session presumed gone mid-turn; releasing the indefinite synth hold to the stranded-reclaim / orphan-prune nets`);
|
|
18539
18907
|
}
|
|
18540
18908
|
}
|
|
18541
18909
|
continue;
|
|
18542
18910
|
}
|
|
18543
|
-
const priorHoldState =
|
|
18544
|
-
|
|
18911
|
+
const priorHoldState = getHoldState(synthKey, mesh.id);
|
|
18912
|
+
setHoldState(synthKey, mesh.id, {
|
|
18545
18913
|
liveConfirmedSinceAck: true,
|
|
18546
18914
|
consecutiveReadFailures: 0,
|
|
18547
18915
|
...priorHoldState?.transcriptIdleSinceMs !== void 0 ? { transcriptIdleSinceMs: priorHoldState.transcriptIdleSinceMs } : {}
|
|
18548
18916
|
});
|
|
18549
18917
|
const nowMs = Date.now();
|
|
18550
18918
|
if (readChatPayloadStatus(payload) !== "idle") {
|
|
18551
|
-
|
|
18919
|
+
setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck: true, consecutiveReadFailures: 0 });
|
|
18552
18920
|
continue;
|
|
18553
18921
|
}
|
|
18554
18922
|
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
@@ -18557,12 +18925,12 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
18557
18925
|
const ackedAtMs = Date.parse(readNonEmptyString2(dispatch.updatedAt));
|
|
18558
18926
|
const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
|
|
18559
18927
|
const deathDeadlineMs = resolveAckedDeathDeadlineMs();
|
|
18560
|
-
const holdState =
|
|
18928
|
+
const holdState = getHoldState(synthKey, mesh.id);
|
|
18561
18929
|
let fastTrackReady = false;
|
|
18562
18930
|
if (evidence.finalSummary) {
|
|
18563
18931
|
const idleSinceMs = holdState?.transcriptIdleSinceMs ?? nowMs;
|
|
18564
18932
|
if (holdState && holdState.transcriptIdleSinceMs === void 0) {
|
|
18565
|
-
|
|
18933
|
+
setHoldState(synthKey, mesh.id, { ...holdState, transcriptIdleSinceMs: idleSinceMs });
|
|
18566
18934
|
}
|
|
18567
18935
|
const fastTrackGraceMs = resolveAckedTranscriptFastTrackGraceMs();
|
|
18568
18936
|
const idleHeldMs = nowMs - idleSinceMs;
|
|
@@ -18571,7 +18939,7 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
18571
18939
|
LOG.info("MeshReconcile", `Acked-hold transcript fast-track: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle WITH a final assistant message for ${Math.round(idleHeldMs / 1e3)}s continuous (grace ${Math.round(fastTrackGraceMs / 1e3)}s) \u2014 promoting the synth ahead of the ${Math.round(deathDeadlineMs / 1e3)}s death backstop; the worker's real emit was lost/late and a later one no-ops idempotently.`);
|
|
18572
18940
|
}
|
|
18573
18941
|
} else if (holdState?.transcriptIdleSinceMs !== void 0) {
|
|
18574
|
-
|
|
18942
|
+
setHoldState(synthKey, mesh.id, { ...holdState, transcriptIdleSinceMs: void 0 });
|
|
18575
18943
|
}
|
|
18576
18944
|
if (!fastTrackReady && sinceAckMs < deathDeadlineMs) {
|
|
18577
18945
|
LOG.info("MeshReconcile", `Acked-hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle ${Number.isFinite(sinceAckMs) ? Math.round(sinceAckMs / 1e3) + "s" : "\u221E"} since the generating_started ack \u2014 HOLDING synth (worker presumed alive; a later real emit is idempotent). Transcript fast-track promotes at ${Math.round(resolveAckedTranscriptFastTrackGraceMs() / 1e3)}s continuous idle-with-final-assistant; death backstop at ${Math.round(deathDeadlineMs / 1e3)}s or on consecutive read failures.`);
|
|
@@ -18582,7 +18950,7 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
18582
18950
|
}
|
|
18583
18951
|
}
|
|
18584
18952
|
if (realTerminalEmitPendingForTask(mesh.id, taskId)) {
|
|
18585
|
-
|
|
18953
|
+
deleteHoldState(synthKey, mesh.id);
|
|
18586
18954
|
LOG.info("MeshReconcile", `Worker-emit priority: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) has a real terminal completion already queued \u2014 yielding synth to the worker's own emit`);
|
|
18587
18955
|
continue;
|
|
18588
18956
|
}
|
|
@@ -18602,7 +18970,7 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
18602
18970
|
}
|
|
18603
18971
|
const reprobeStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
|
|
18604
18972
|
if (reprobeStatus && reprobeStatus !== "idle") {
|
|
18605
|
-
|
|
18973
|
+
deleteHoldState(synthKey, mesh.id);
|
|
18606
18974
|
LOG.info("MeshReconcile", `Live re-probe defer: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read '${reprobeStatus}' at synth-commit time \u2014 worker resumed generating; deferring synth to a later tick`);
|
|
18607
18975
|
continue;
|
|
18608
18976
|
}
|
|
@@ -18744,7 +19112,7 @@ function setupMeshReconcileLoop(components) {
|
|
|
18744
19112
|
}
|
|
18745
19113
|
};
|
|
18746
19114
|
}
|
|
18747
|
-
var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS, ACKED_DEATH_CONSECUTIVE_READ_FAILURES, inFlightAckedHoldState, coordinatorModalParkState, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, DELIVERED_NO_TURN_DEADLINE_MS, RECLAIM_UNKNOWN_GRACE_TICKS, deliveredNoTurnUnknownStreak, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
|
|
19115
|
+
var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS, ACKED_DEATH_CONSECUTIVE_READ_FAILURES, inFlightAckedHoldState, rehydratedHoldMeshes, coordinatorModalParkState, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, DELIVERED_NO_TURN_DEADLINE_MS, RECLAIM_UNKNOWN_GRACE_TICKS, deliveredNoTurnUnknownStreak, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
|
|
18748
19116
|
var init_mesh_reconcile_loop = __esm({
|
|
18749
19117
|
"src/mesh/mesh-reconcile-loop.ts"() {
|
|
18750
19118
|
"use strict";
|
|
@@ -18771,6 +19139,7 @@ var init_mesh_reconcile_loop = __esm({
|
|
|
18771
19139
|
DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS = 12e3;
|
|
18772
19140
|
ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
|
|
18773
19141
|
inFlightAckedHoldState = /* @__PURE__ */ new Map();
|
|
19142
|
+
rehydratedHoldMeshes = /* @__PURE__ */ new Set();
|
|
18774
19143
|
coordinatorModalParkState = /* @__PURE__ */ new Map();
|
|
18775
19144
|
heldEventLedgerRecorded = /* @__PURE__ */ new Set();
|
|
18776
19145
|
ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
|
|
@@ -27870,10 +28239,10 @@ var CdpDomHandlers = class {
|
|
|
27870
28239
|
|
|
27871
28240
|
// src/providers/ide-provider-instance.ts
|
|
27872
28241
|
var crypto2 = __toESM(require("crypto"));
|
|
27873
|
-
|
|
28242
|
+
init_contracts2();
|
|
27874
28243
|
|
|
27875
28244
|
// src/providers/extension-provider-instance.ts
|
|
27876
|
-
|
|
28245
|
+
init_contracts2();
|
|
27877
28246
|
|
|
27878
28247
|
// src/providers/status-monitor.ts
|
|
27879
28248
|
var DEFAULT_MONITOR_CONFIG = {
|
|
@@ -29905,7 +30274,7 @@ init_logger();
|
|
|
29905
30274
|
init_control_effects();
|
|
29906
30275
|
|
|
29907
30276
|
// src/providers/read-chat-contract.ts
|
|
29908
|
-
|
|
30277
|
+
init_contracts2();
|
|
29909
30278
|
|
|
29910
30279
|
// src/providers/transcript-v2.ts
|
|
29911
30280
|
var CHAT_CONTRACT_VERSION_V1 = "1.0";
|
|
@@ -31351,7 +31720,7 @@ init_debug_trace();
|
|
|
31351
31720
|
|
|
31352
31721
|
// src/commands/chat-commands-read.ts
|
|
31353
31722
|
var path16 = __toESM(require("path"));
|
|
31354
|
-
|
|
31723
|
+
init_contracts2();
|
|
31355
31724
|
init_coordinator_registry();
|
|
31356
31725
|
init_logger();
|
|
31357
31726
|
init_debug_trace();
|
|
@@ -33606,7 +33975,7 @@ async function handleGetChatDebugBundle(h, args) {
|
|
|
33606
33975
|
}
|
|
33607
33976
|
|
|
33608
33977
|
// src/commands/chat-commands-write.ts
|
|
33609
|
-
|
|
33978
|
+
init_contracts2();
|
|
33610
33979
|
init_provider_input_support();
|
|
33611
33980
|
init_approval_utils();
|
|
33612
33981
|
init_logger();
|
|
@@ -38353,7 +38722,7 @@ var path26 = __toESM(require("path"));
|
|
|
38353
38722
|
var crypto4 = __toESM(require("crypto"));
|
|
38354
38723
|
var fs19 = __toESM(require("fs"));
|
|
38355
38724
|
var import_node_module = require("module");
|
|
38356
|
-
|
|
38725
|
+
init_contracts2();
|
|
38357
38726
|
init_provider_input_support();
|
|
38358
38727
|
init_hash();
|
|
38359
38728
|
|
|
@@ -44124,7 +44493,7 @@ var path27 = __toESM(require("path"));
|
|
|
44124
44493
|
var import_stream = require("stream");
|
|
44125
44494
|
var import_child_process7 = require("child_process");
|
|
44126
44495
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
44127
|
-
|
|
44496
|
+
init_contracts2();
|
|
44128
44497
|
init_provider_input_support();
|
|
44129
44498
|
init_summary_metadata();
|
|
44130
44499
|
init_chat_message_normalization();
|
|
@@ -45367,7 +45736,7 @@ ${rawInput}` : rawInput;
|
|
|
45367
45736
|
};
|
|
45368
45737
|
|
|
45369
45738
|
// src/commands/cli-manager.ts
|
|
45370
|
-
|
|
45739
|
+
init_contracts2();
|
|
45371
45740
|
init_provider_input_support();
|
|
45372
45741
|
init_logger();
|
|
45373
45742
|
|
|
@@ -56559,7 +56928,8 @@ function queueRefineJobEvent(self, event, handle, result) {
|
|
|
56559
56928
|
}
|
|
56560
56929
|
async function appendRefineJobLedger(self, kind, handle, result) {
|
|
56561
56930
|
try {
|
|
56562
|
-
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
56931
|
+
const { appendLedgerEntry: appendLedgerEntry2, buildLedgerOriginatingCoordinatorStamp: buildLedgerOriginatingCoordinatorStamp2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
56932
|
+
const originatingStamp = kind === "task_dispatched" ? buildLedgerOriginatingCoordinatorStamp2({ coordinatorDaemonId: handle.targetCoordinatorDaemonId }) : void 0;
|
|
56563
56933
|
appendLedgerEntry2(handle.meshId, {
|
|
56564
56934
|
kind,
|
|
56565
56935
|
nodeId: handle.targetNodeId,
|
|
@@ -56580,6 +56950,7 @@ async function appendRefineJobLedger(self, kind, handle, result) {
|
|
|
56580
56950
|
},
|
|
56581
56951
|
async: true,
|
|
56582
56952
|
retryOfJobId: handle.retryOfJobId,
|
|
56953
|
+
...originatingStamp ? { originatingCoordinator: originatingStamp } : {},
|
|
56583
56954
|
...result ? {
|
|
56584
56955
|
success: result.success === true,
|
|
56585
56956
|
result,
|
|
@@ -57593,7 +57964,8 @@ function queueRefineBatchJobEvent(self, event, handle, result) {
|
|
|
57593
57964
|
}
|
|
57594
57965
|
async function appendRefineBatchJobLedger(self, kind, handle, result) {
|
|
57595
57966
|
try {
|
|
57596
|
-
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
57967
|
+
const { appendLedgerEntry: appendLedgerEntry2, buildLedgerOriginatingCoordinatorStamp: buildLedgerOriginatingCoordinatorStamp2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
57968
|
+
const originatingStamp = kind === "task_dispatched" ? buildLedgerOriginatingCoordinatorStamp2({ coordinatorDaemonId: handle.targetCoordinatorDaemonId }) : void 0;
|
|
57597
57969
|
appendLedgerEntry2(handle.meshId, {
|
|
57598
57970
|
kind,
|
|
57599
57971
|
nodeId: handle.batchLabel,
|
|
@@ -57613,6 +57985,7 @@ async function appendRefineBatchJobLedger(self, kind, handle, result) {
|
|
|
57613
57985
|
},
|
|
57614
57986
|
async: true,
|
|
57615
57987
|
batch: true,
|
|
57988
|
+
...originatingStamp ? { originatingCoordinator: originatingStamp } : {},
|
|
57616
57989
|
...result ? {
|
|
57617
57990
|
success: result.success === true,
|
|
57618
57991
|
result
|