@adhdev/daemon-core 0.9.82-rc.196 → 0.9.82-rc.197
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.d.ts +2 -0
- package/dist/index.js +392 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +388 -10
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-delivery-policy.d.ts +126 -0
- package/dist/mesh/mesh-runtime-store.d.ts +66 -0
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/mesh/mesh-delivery-policy.ts +298 -0
- package/src/mesh/mesh-events.ts +52 -3
- package/src/mesh/mesh-runtime-store.ts +219 -0
package/dist/index.d.ts
CHANGED
|
@@ -52,6 +52,8 @@ export type { MeshAsyncRefineJobStatus, MeshAsyncRefineJobSummary } from './mesh
|
|
|
52
52
|
export { buildMeshHostRequiredFailure, createDefaultMeshHostMetadata, isMeshHostOwner, normalizeMeshDaemonRole, requireMeshHostQueueOwner, resolveMeshHostStatus } from './mesh/mesh-host-ownership.js';
|
|
53
53
|
export { triggerMeshQueue, drainPendingMeshCoordinatorEvents, getPendingMeshCoordinatorEvents, clearPendingMeshCoordinatorEvents, queuePendingMeshCoordinatorEvent, reconcileDirectDispatchCompletionFromTranscript } from './mesh/mesh-events.js';
|
|
54
54
|
export type { PendingMeshCoordinatorEvent } from './mesh/mesh-events.js';
|
|
55
|
+
export { resolveDeliveryDecision, createSessionDelivery, updateSessionDeliveryStatus, getActiveSessionDeliveries, recordCompletionConflict, getRecentCompletionConflicts } from './mesh/mesh-delivery-policy.js';
|
|
56
|
+
export type { MeshSessionDeliveryStatus, MeshSessionDeliveryKind, MeshDeliveryDecision, MeshDeliveryPolicyResult, SessionDeliveryRecord } from './mesh/mesh-delivery-policy.js';
|
|
55
57
|
export { P2pRelayFailureError, buildP2pRelayFailurePayload, classifyP2pRelayFailure, isP2pRelayTransportFailure, } from './mesh/p2p-relay-failure.js';
|
|
56
58
|
export type { P2pRelayFailureClassification, P2pRelayFailureCode, P2pRelayFailureContext, P2pRelayFailurePayload, } from './mesh/p2p-relay-failure.js';
|
|
57
59
|
export { loadState, saveState, resetState } from './config/state-store.js';
|
package/dist/index.js
CHANGED
|
@@ -3424,6 +3424,49 @@ var init_mesh_runtime_store = __esm({
|
|
|
3424
3424
|
metadata TEXT,
|
|
3425
3425
|
PRIMARY KEY (node_id, session_id)
|
|
3426
3426
|
);
|
|
3427
|
+
|
|
3428
|
+
CREATE TABLE IF NOT EXISTS mesh_session_delivery (
|
|
3429
|
+
id TEXT PRIMARY KEY,
|
|
3430
|
+
mesh_id TEXT NOT NULL,
|
|
3431
|
+
node_id TEXT,
|
|
3432
|
+
session_id TEXT,
|
|
3433
|
+
provider_type TEXT,
|
|
3434
|
+
task_id TEXT,
|
|
3435
|
+
kind TEXT NOT NULL,
|
|
3436
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
3437
|
+
message TEXT NOT NULL,
|
|
3438
|
+
status TEXT NOT NULL DEFAULT 'queued',
|
|
3439
|
+
deliver_after TEXT,
|
|
3440
|
+
expires_at TEXT,
|
|
3441
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
3442
|
+
source_coordinator_session_id TEXT,
|
|
3443
|
+
source_coordinator_daemon_id TEXT,
|
|
3444
|
+
last_error TEXT,
|
|
3445
|
+
created_at TEXT NOT NULL,
|
|
3446
|
+
updated_at TEXT NOT NULL
|
|
3447
|
+
);
|
|
3448
|
+
|
|
3449
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_session_delivery_mesh_status
|
|
3450
|
+
ON mesh_session_delivery(mesh_id, status, created_at);
|
|
3451
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_session_delivery_session
|
|
3452
|
+
ON mesh_session_delivery(mesh_id, session_id, status);
|
|
3453
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_session_delivery_task
|
|
3454
|
+
ON mesh_session_delivery(mesh_id, task_id);
|
|
3455
|
+
|
|
3456
|
+
CREATE TABLE IF NOT EXISTS mesh_completion_conflicts (
|
|
3457
|
+
id TEXT PRIMARY KEY,
|
|
3458
|
+
mesh_id TEXT NOT NULL,
|
|
3459
|
+
fingerprint TEXT NOT NULL,
|
|
3460
|
+
conflicting_task_id TEXT,
|
|
3461
|
+
conflicting_session_id TEXT,
|
|
3462
|
+
original_task_id TEXT,
|
|
3463
|
+
original_session_id TEXT,
|
|
3464
|
+
event TEXT NOT NULL,
|
|
3465
|
+
created_at TEXT NOT NULL
|
|
3466
|
+
);
|
|
3467
|
+
|
|
3468
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_completion_conflicts_mesh
|
|
3469
|
+
ON mesh_completion_conflicts(mesh_id, created_at);
|
|
3427
3470
|
`);
|
|
3428
3471
|
}
|
|
3429
3472
|
hasCompletionFingerprint(fingerprint) {
|
|
@@ -3748,6 +3791,131 @@ var init_mesh_runtime_store = __esm({
|
|
|
3748
3791
|
pruneExpiredRemoteIdleSessions() {
|
|
3749
3792
|
this.db.prepare("DELETE FROM remote_idle_sessions WHERE expires_at <= ?").run(Date.now());
|
|
3750
3793
|
}
|
|
3794
|
+
// ── Session Delivery Queue ───────────────────────────────────────────────
|
|
3795
|
+
insertSessionDelivery(entry) {
|
|
3796
|
+
this.db.prepare(`
|
|
3797
|
+
INSERT OR REPLACE INTO mesh_session_delivery (
|
|
3798
|
+
id, mesh_id, node_id, session_id, provider_type, task_id, kind, priority,
|
|
3799
|
+
message, status, deliver_after, expires_at, attempt_count,
|
|
3800
|
+
source_coordinator_session_id, source_coordinator_daemon_id,
|
|
3801
|
+
last_error, created_at, updated_at
|
|
3802
|
+
) VALUES (
|
|
3803
|
+
@id, @meshId, @nodeId, @sessionId, @providerType, @taskId, @kind, @priority,
|
|
3804
|
+
@message, @status, @deliverAfter, @expiresAt, 0,
|
|
3805
|
+
@sourceCoordinatorSessionId, @sourceCoordinatorDaemonId,
|
|
3806
|
+
NULL, @createdAt, @updatedAt
|
|
3807
|
+
)
|
|
3808
|
+
`).run({
|
|
3809
|
+
id: entry.id,
|
|
3810
|
+
meshId: entry.meshId,
|
|
3811
|
+
nodeId: entry.nodeId ?? null,
|
|
3812
|
+
sessionId: entry.sessionId ?? null,
|
|
3813
|
+
providerType: entry.providerType ?? null,
|
|
3814
|
+
taskId: entry.taskId ?? null,
|
|
3815
|
+
kind: entry.kind,
|
|
3816
|
+
priority: entry.priority ?? 0,
|
|
3817
|
+
message: entry.message,
|
|
3818
|
+
status: entry.status,
|
|
3819
|
+
deliverAfter: entry.deliverAfter ?? null,
|
|
3820
|
+
expiresAt: entry.expiresAt ?? null,
|
|
3821
|
+
sourceCoordinatorSessionId: entry.sourceCoordinatorSessionId ?? null,
|
|
3822
|
+
sourceCoordinatorDaemonId: entry.sourceCoordinatorDaemonId ?? null,
|
|
3823
|
+
createdAt: entry.createdAt,
|
|
3824
|
+
updatedAt: entry.updatedAt
|
|
3825
|
+
});
|
|
3826
|
+
this.maybeCheckpointWal();
|
|
3827
|
+
}
|
|
3828
|
+
updateSessionDeliveryStatus(id, status, opts) {
|
|
3829
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3830
|
+
if (opts?.incrementAttempt) {
|
|
3831
|
+
this.db.prepare(`
|
|
3832
|
+
UPDATE mesh_session_delivery
|
|
3833
|
+
SET status = @status, last_error = @lastError, attempt_count = attempt_count + 1, updated_at = @updatedAt
|
|
3834
|
+
WHERE id = @id
|
|
3835
|
+
`).run({ id, status, lastError: opts?.lastError ?? null, updatedAt: now });
|
|
3836
|
+
} else {
|
|
3837
|
+
this.db.prepare(`
|
|
3838
|
+
UPDATE mesh_session_delivery
|
|
3839
|
+
SET status = @status, last_error = @lastError, updated_at = @updatedAt
|
|
3840
|
+
WHERE id = @id
|
|
3841
|
+
`).run({ id, status, lastError: opts?.lastError ?? null, updatedAt: now });
|
|
3842
|
+
}
|
|
3843
|
+
}
|
|
3844
|
+
getActiveSessionDeliveries(meshId, sessionId) {
|
|
3845
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3846
|
+
const sql = sessionId ? `SELECT * FROM mesh_session_delivery WHERE mesh_id = ? AND session_id = ? AND status NOT IN ('delivered','completed','failed','expired','cancelled') AND (expires_at IS NULL OR expires_at > ?) ORDER BY priority DESC, created_at ASC` : `SELECT * FROM mesh_session_delivery WHERE mesh_id = ? AND status NOT IN ('delivered','completed','failed','expired','cancelled') AND (expires_at IS NULL OR expires_at > ?) ORDER BY priority DESC, created_at ASC`;
|
|
3847
|
+
const rows = sessionId ? this.db.prepare(sql).all(meshId, sessionId, now) : this.db.prepare(sql).all(meshId, now);
|
|
3848
|
+
return rows.map((r) => ({
|
|
3849
|
+
id: r.id,
|
|
3850
|
+
meshId: r.mesh_id,
|
|
3851
|
+
nodeId: r.node_id,
|
|
3852
|
+
sessionId: r.session_id,
|
|
3853
|
+
providerType: r.provider_type,
|
|
3854
|
+
taskId: r.task_id,
|
|
3855
|
+
kind: r.kind,
|
|
3856
|
+
priority: r.priority,
|
|
3857
|
+
message: r.message,
|
|
3858
|
+
status: r.status,
|
|
3859
|
+
deliverAfter: r.deliver_after,
|
|
3860
|
+
expiresAt: r.expires_at,
|
|
3861
|
+
attemptCount: r.attempt_count,
|
|
3862
|
+
sourceCoordinatorSessionId: r.source_coordinator_session_id,
|
|
3863
|
+
sourceCoordinatorDaemonId: r.source_coordinator_daemon_id,
|
|
3864
|
+
lastError: r.last_error,
|
|
3865
|
+
createdAt: r.created_at,
|
|
3866
|
+
updatedAt: r.updated_at
|
|
3867
|
+
}));
|
|
3868
|
+
}
|
|
3869
|
+
expireStaleSessionDeliveries(meshId) {
|
|
3870
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3871
|
+
this.db.prepare(`
|
|
3872
|
+
UPDATE mesh_session_delivery
|
|
3873
|
+
SET status = 'expired', updated_at = ?
|
|
3874
|
+
WHERE mesh_id = ? AND expires_at IS NOT NULL AND expires_at <= ?
|
|
3875
|
+
AND status NOT IN ('delivered','completed','failed','expired','cancelled')
|
|
3876
|
+
`).run(now, meshId, now);
|
|
3877
|
+
}
|
|
3878
|
+
deleteSessionDeliveries(meshId) {
|
|
3879
|
+
this.db.prepare("DELETE FROM mesh_session_delivery WHERE mesh_id = ?").run(meshId);
|
|
3880
|
+
}
|
|
3881
|
+
// ── Completion Conflict Diagnostics ──────────────────────────────────────
|
|
3882
|
+
recordCompletionConflict(entry) {
|
|
3883
|
+
this.db.prepare(`
|
|
3884
|
+
INSERT OR IGNORE INTO mesh_completion_conflicts
|
|
3885
|
+
(id, mesh_id, fingerprint, conflicting_task_id, conflicting_session_id,
|
|
3886
|
+
original_task_id, original_session_id, event, created_at)
|
|
3887
|
+
VALUES (@id, @meshId, @fingerprint, @conflictingTaskId, @conflictingSessionId,
|
|
3888
|
+
@originalTaskId, @originalSessionId, @event, @createdAt)
|
|
3889
|
+
`).run({
|
|
3890
|
+
id: entry.id,
|
|
3891
|
+
meshId: entry.meshId,
|
|
3892
|
+
fingerprint: entry.fingerprint,
|
|
3893
|
+
conflictingTaskId: entry.conflictingTaskId ?? null,
|
|
3894
|
+
conflictingSessionId: entry.conflictingSessionId ?? null,
|
|
3895
|
+
originalTaskId: entry.originalTaskId ?? null,
|
|
3896
|
+
originalSessionId: entry.originalSessionId ?? null,
|
|
3897
|
+
event: entry.event,
|
|
3898
|
+
createdAt: entry.createdAt
|
|
3899
|
+
});
|
|
3900
|
+
this.maybeCheckpointWal();
|
|
3901
|
+
}
|
|
3902
|
+
getRecentCompletionConflicts(meshId, limitMs = 60 * 60 * 1e3) {
|
|
3903
|
+
const cutoff = new Date(Date.now() - limitMs).toISOString();
|
|
3904
|
+
const rows = this.db.prepare(
|
|
3905
|
+
"SELECT * FROM mesh_completion_conflicts WHERE mesh_id = ? AND created_at >= ? ORDER BY created_at DESC LIMIT 50"
|
|
3906
|
+
).all(meshId, cutoff);
|
|
3907
|
+
return rows.map((r) => ({
|
|
3908
|
+
id: r.id,
|
|
3909
|
+
meshId: r.mesh_id,
|
|
3910
|
+
fingerprint: r.fingerprint,
|
|
3911
|
+
conflictingTaskId: r.conflicting_task_id,
|
|
3912
|
+
conflictingSessionId: r.conflicting_session_id,
|
|
3913
|
+
originalTaskId: r.original_task_id,
|
|
3914
|
+
originalSessionId: r.original_session_id,
|
|
3915
|
+
event: r.event,
|
|
3916
|
+
createdAt: r.created_at
|
|
3917
|
+
}));
|
|
3918
|
+
}
|
|
3751
3919
|
};
|
|
3752
3920
|
}
|
|
3753
3921
|
});
|
|
@@ -4162,6 +4330,167 @@ var init_cli_detector = __esm({
|
|
|
4162
4330
|
}
|
|
4163
4331
|
});
|
|
4164
4332
|
|
|
4333
|
+
// src/mesh/mesh-delivery-policy.ts
|
|
4334
|
+
function resolveDeliveryDecision(sessionStatus, opts) {
|
|
4335
|
+
const status = (sessionStatus || "").trim().toLowerCase();
|
|
4336
|
+
if (!status) {
|
|
4337
|
+
return {
|
|
4338
|
+
decision: "rejected",
|
|
4339
|
+
reason: "unknown_session_status",
|
|
4340
|
+
message: "Session status is unknown. Delivery rejected (fail-closed). Use mesh_launch_session to start a fresh session."
|
|
4341
|
+
};
|
|
4342
|
+
}
|
|
4343
|
+
if (IMMEDIATE_DELIVERY_STATUSES.has(status)) {
|
|
4344
|
+
return {
|
|
4345
|
+
decision: "immediate",
|
|
4346
|
+
reason: `session_${status}`,
|
|
4347
|
+
message: `Session is ${status} \u2014 delivery allowed immediately.`
|
|
4348
|
+
};
|
|
4349
|
+
}
|
|
4350
|
+
if (BUSY_DELIVERY_STATUSES.has(status)) {
|
|
4351
|
+
if (opts?.allowBusyInjection) {
|
|
4352
|
+
return {
|
|
4353
|
+
decision: "immediate",
|
|
4354
|
+
reason: `session_${status}_busy_injection_allowed`,
|
|
4355
|
+
message: `Session is ${status} but provider supports busy injection. Delivered immediately.`
|
|
4356
|
+
};
|
|
4357
|
+
}
|
|
4358
|
+
if (status === "waiting_approval" && opts?.kind === "approval") {
|
|
4359
|
+
return {
|
|
4360
|
+
decision: "immediate",
|
|
4361
|
+
reason: "session_waiting_approval_approval_message",
|
|
4362
|
+
message: "Session is waiting for approval \u2014 approval message delivered immediately."
|
|
4363
|
+
};
|
|
4364
|
+
}
|
|
4365
|
+
return {
|
|
4366
|
+
decision: "queued",
|
|
4367
|
+
reason: `session_${status}_busy`,
|
|
4368
|
+
message: `Session is ${status}. Task queued for delivery when session becomes idle. Do not inject directly into a busy session.`
|
|
4369
|
+
};
|
|
4370
|
+
}
|
|
4371
|
+
if (TERMINAL_DELIVERY_STATUSES.has(status)) {
|
|
4372
|
+
return {
|
|
4373
|
+
decision: "rejected",
|
|
4374
|
+
reason: `session_${status}_terminal`,
|
|
4375
|
+
message: `Session is ${status} (terminal). Delivery rejected. Launch a new session before dispatching tasks.`
|
|
4376
|
+
};
|
|
4377
|
+
}
|
|
4378
|
+
return {
|
|
4379
|
+
decision: "rejected",
|
|
4380
|
+
reason: "unrecognized_session_status",
|
|
4381
|
+
message: `Session status '${sessionStatus}' is not recognized. Delivery rejected (fail-closed). Inspect session state before retrying.`
|
|
4382
|
+
};
|
|
4383
|
+
}
|
|
4384
|
+
function createSessionDelivery(opts) {
|
|
4385
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4386
|
+
const id = (0, import_crypto6.randomUUID)();
|
|
4387
|
+
const record = {
|
|
4388
|
+
id,
|
|
4389
|
+
meshId: opts.meshId,
|
|
4390
|
+
nodeId: opts.nodeId,
|
|
4391
|
+
sessionId: opts.sessionId,
|
|
4392
|
+
providerType: opts.providerType,
|
|
4393
|
+
taskId: opts.taskId,
|
|
4394
|
+
kind: opts.kind,
|
|
4395
|
+
priority: opts.priority ?? 0,
|
|
4396
|
+
message: opts.message,
|
|
4397
|
+
status: opts.status,
|
|
4398
|
+
deliverAfter: opts.deliverAfter,
|
|
4399
|
+
expiresAt: opts.expiresAt,
|
|
4400
|
+
attemptCount: 0,
|
|
4401
|
+
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
4402
|
+
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
4403
|
+
createdAt: now,
|
|
4404
|
+
updatedAt: now
|
|
4405
|
+
};
|
|
4406
|
+
MeshRuntimeStore.getInstance().insertSessionDelivery({
|
|
4407
|
+
id,
|
|
4408
|
+
meshId: opts.meshId,
|
|
4409
|
+
nodeId: opts.nodeId,
|
|
4410
|
+
sessionId: opts.sessionId,
|
|
4411
|
+
providerType: opts.providerType,
|
|
4412
|
+
taskId: opts.taskId,
|
|
4413
|
+
kind: opts.kind,
|
|
4414
|
+
priority: opts.priority ?? 0,
|
|
4415
|
+
message: opts.message,
|
|
4416
|
+
status: opts.status,
|
|
4417
|
+
deliverAfter: opts.deliverAfter,
|
|
4418
|
+
expiresAt: opts.expiresAt,
|
|
4419
|
+
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
4420
|
+
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
4421
|
+
createdAt: now,
|
|
4422
|
+
updatedAt: now
|
|
4423
|
+
});
|
|
4424
|
+
return record;
|
|
4425
|
+
}
|
|
4426
|
+
function updateSessionDeliveryStatus(id, status, opts) {
|
|
4427
|
+
try {
|
|
4428
|
+
MeshRuntimeStore.getInstance().updateSessionDeliveryStatus(id, status, opts);
|
|
4429
|
+
} catch {
|
|
4430
|
+
}
|
|
4431
|
+
}
|
|
4432
|
+
function getActiveSessionDeliveries(meshId, sessionId) {
|
|
4433
|
+
try {
|
|
4434
|
+
return MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
|
|
4435
|
+
} catch {
|
|
4436
|
+
return [];
|
|
4437
|
+
}
|
|
4438
|
+
}
|
|
4439
|
+
function recordCompletionConflict(opts) {
|
|
4440
|
+
try {
|
|
4441
|
+
MeshRuntimeStore.getInstance().recordCompletionConflict({
|
|
4442
|
+
id: (0, import_crypto6.randomUUID)(),
|
|
4443
|
+
meshId: opts.meshId,
|
|
4444
|
+
fingerprint: opts.fingerprint,
|
|
4445
|
+
conflictingTaskId: opts.conflictingTaskId,
|
|
4446
|
+
conflictingSessionId: opts.conflictingSessionId,
|
|
4447
|
+
originalTaskId: opts.originalTaskId,
|
|
4448
|
+
originalSessionId: opts.originalSessionId,
|
|
4449
|
+
event: opts.event,
|
|
4450
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4451
|
+
});
|
|
4452
|
+
} catch {
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
function getRecentCompletionConflicts(meshId, limitMs) {
|
|
4456
|
+
try {
|
|
4457
|
+
return MeshRuntimeStore.getInstance().getRecentCompletionConflicts(meshId, limitMs);
|
|
4458
|
+
} catch {
|
|
4459
|
+
return [];
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
var import_crypto6, IMMEDIATE_DELIVERY_STATUSES, BUSY_DELIVERY_STATUSES, TERMINAL_DELIVERY_STATUSES;
|
|
4463
|
+
var init_mesh_delivery_policy = __esm({
|
|
4464
|
+
"src/mesh/mesh-delivery-policy.ts"() {
|
|
4465
|
+
"use strict";
|
|
4466
|
+
import_crypto6 = require("crypto");
|
|
4467
|
+
init_mesh_runtime_store();
|
|
4468
|
+
IMMEDIATE_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
4469
|
+
"idle",
|
|
4470
|
+
"waiting_input",
|
|
4471
|
+
"ready"
|
|
4472
|
+
]);
|
|
4473
|
+
BUSY_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
4474
|
+
"generating",
|
|
4475
|
+
"running",
|
|
4476
|
+
"streaming",
|
|
4477
|
+
"busy",
|
|
4478
|
+
"starting",
|
|
4479
|
+
"initializing",
|
|
4480
|
+
"waiting_approval"
|
|
4481
|
+
]);
|
|
4482
|
+
TERMINAL_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
4483
|
+
"stopped",
|
|
4484
|
+
"failed",
|
|
4485
|
+
"terminated",
|
|
4486
|
+
"exited",
|
|
4487
|
+
"closed",
|
|
4488
|
+
"deleted",
|
|
4489
|
+
"error"
|
|
4490
|
+
]);
|
|
4491
|
+
}
|
|
4492
|
+
});
|
|
4493
|
+
|
|
4165
4494
|
// src/mesh/mesh-events.ts
|
|
4166
4495
|
var mesh_events_exports = {};
|
|
4167
4496
|
__export(mesh_events_exports, {
|
|
@@ -4506,7 +4835,18 @@ function buildMeshCompletionFingerprint(args) {
|
|
|
4506
4835
|
function isDuplicateMeshCompletionEvent(args) {
|
|
4507
4836
|
const fingerprint = buildMeshCompletionFingerprint(args);
|
|
4508
4837
|
if (!fingerprint) return false;
|
|
4509
|
-
if (hasFingerprintSeen(fingerprint))
|
|
4838
|
+
if (hasFingerprintSeen(fingerprint)) {
|
|
4839
|
+
if (args.taskId) {
|
|
4840
|
+
recordCompletionConflict({
|
|
4841
|
+
meshId: args.meshId,
|
|
4842
|
+
fingerprint,
|
|
4843
|
+
conflictingTaskId: args.taskId,
|
|
4844
|
+
conflictingSessionId: args.sessionId,
|
|
4845
|
+
event: args.event
|
|
4846
|
+
});
|
|
4847
|
+
}
|
|
4848
|
+
return true;
|
|
4849
|
+
}
|
|
4510
4850
|
recordFingerprintSeen(fingerprint);
|
|
4511
4851
|
return false;
|
|
4512
4852
|
}
|
|
@@ -4757,20 +5097,33 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
4757
5097
|
if (node?.daemonId && components.dispatchMeshCommand) {
|
|
4758
5098
|
const isLocalNode = components.cliManager.adapters.has(sessionId);
|
|
4759
5099
|
if (!isLocalNode) {
|
|
5100
|
+
const delivery2 = createSessionDelivery({
|
|
5101
|
+
meshId,
|
|
5102
|
+
nodeId,
|
|
5103
|
+
sessionId,
|
|
5104
|
+
providerType,
|
|
5105
|
+
taskId: task.id,
|
|
5106
|
+
kind: "task",
|
|
5107
|
+
message: task.message,
|
|
5108
|
+
status: "delivering"
|
|
5109
|
+
});
|
|
4760
5110
|
components.dispatchMeshCommand(node.daemonId, "agent_command", {
|
|
4761
5111
|
targetSessionId: sessionId,
|
|
4762
5112
|
cliType: providerType,
|
|
4763
5113
|
action: "send_chat",
|
|
4764
5114
|
message: task.message
|
|
5115
|
+
}).then(() => {
|
|
5116
|
+
updateSessionDeliveryStatus(delivery2.id, "delivered");
|
|
4765
5117
|
}).catch((e) => {
|
|
4766
5118
|
LOG.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
5119
|
+
updateSessionDeliveryStatus(delivery2.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
4767
5120
|
updateTaskStatus(meshId, task.id, "pending");
|
|
4768
5121
|
try {
|
|
4769
5122
|
appendLedgerEntry(meshId, {
|
|
4770
5123
|
kind: "dispatch_failed",
|
|
4771
5124
|
nodeId,
|
|
4772
5125
|
sessionId,
|
|
4773
|
-
payload: { taskId: task.id, error: e?.message, retryable: true }
|
|
5126
|
+
payload: { taskId: task.id, deliveryId: delivery2.id, error: e?.message, retryable: true }
|
|
4774
5127
|
});
|
|
4775
5128
|
} catch {
|
|
4776
5129
|
}
|
|
@@ -4778,13 +5131,26 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
4778
5131
|
return true;
|
|
4779
5132
|
}
|
|
4780
5133
|
}
|
|
5134
|
+
const delivery = createSessionDelivery({
|
|
5135
|
+
meshId,
|
|
5136
|
+
nodeId,
|
|
5137
|
+
sessionId,
|
|
5138
|
+
providerType,
|
|
5139
|
+
taskId: task.id,
|
|
5140
|
+
kind: "task",
|
|
5141
|
+
message: task.message,
|
|
5142
|
+
status: "delivering"
|
|
5143
|
+
});
|
|
4781
5144
|
components.cliManager.handleCliCommand("agent_command", {
|
|
4782
5145
|
targetSessionId: sessionId,
|
|
4783
5146
|
cliType: providerType,
|
|
4784
5147
|
action: "send_chat",
|
|
4785
5148
|
message: task.message
|
|
5149
|
+
}).then(() => {
|
|
5150
|
+
updateSessionDeliveryStatus(delivery.id, "delivered");
|
|
4786
5151
|
}).catch((e) => {
|
|
4787
5152
|
LOG.error("MeshQueue", `Failed to dispatch task locally to node ${nodeId}: ${e?.message}`);
|
|
5153
|
+
updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
4788
5154
|
updateTaskStatus(meshId, task.id, "failed");
|
|
4789
5155
|
});
|
|
4790
5156
|
return true;
|
|
@@ -5389,7 +5755,9 @@ function injectMeshSystemMessage(components, args) {
|
|
|
5389
5755
|
finalSummary: readNonEmptyString2(args.metadataEvent.finalSummary) || void 0,
|
|
5390
5756
|
// Scope dedup to the coordinator daemon so two coordinators for the same mesh
|
|
5391
5757
|
// don't suppress each other's completion events via shared fingerprint table.
|
|
5392
|
-
coordinatorDaemonId: workerCoordinatorDaemonId || void 0
|
|
5758
|
+
coordinatorDaemonId: workerCoordinatorDaemonId || void 0,
|
|
5759
|
+
taskId: readNonEmptyString2(args.metadataEvent.taskId) || void 0,
|
|
5760
|
+
nodeId: eventNodeId || void 0
|
|
5393
5761
|
});
|
|
5394
5762
|
if (duplicateCompletion) {
|
|
5395
5763
|
LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
|
|
@@ -5405,7 +5773,9 @@ function injectMeshSystemMessage(components, args) {
|
|
|
5405
5773
|
providerSessionId: readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0,
|
|
5406
5774
|
timestamp: eventTimestamp,
|
|
5407
5775
|
finalSummary: readNonEmptyString2(args.metadataEvent.finalSummary) || void 0,
|
|
5408
|
-
coordinatorDaemonId: workerCoordinatorDaemonId || void 0
|
|
5776
|
+
coordinatorDaemonId: workerCoordinatorDaemonId || void 0,
|
|
5777
|
+
taskId: readNonEmptyString2(args.metadataEvent.taskId) || void 0,
|
|
5778
|
+
nodeId: eventNodeId || void 0
|
|
5409
5779
|
});
|
|
5410
5780
|
if (duplicateStopped) {
|
|
5411
5781
|
LOG.info("MeshEvents", `Suppressed duplicate stopped event for mesh ${args.meshId} session ${eventSessionId}`);
|
|
@@ -5782,6 +6152,7 @@ var init_mesh_events = __esm({
|
|
|
5782
6152
|
init_mesh_work_queue();
|
|
5783
6153
|
init_mesh_runtime_store();
|
|
5784
6154
|
init_mesh_fast_forward();
|
|
6155
|
+
init_mesh_delivery_policy();
|
|
5785
6156
|
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
5786
6157
|
meshByWorkspaceCache = /* @__PURE__ */ new Map();
|
|
5787
6158
|
MESH_WORKSPACE_CACHE_TTL_MS = 5e3;
|
|
@@ -11333,6 +11704,7 @@ __export(index_exports, {
|
|
|
11333
11704
|
createInteractionId: () => createInteractionId,
|
|
11334
11705
|
createMesh: () => createMesh,
|
|
11335
11706
|
createNativeHistoryDispatcher: () => createNativeHistoryDispatcher,
|
|
11707
|
+
createSessionDelivery: () => createSessionDelivery,
|
|
11336
11708
|
createWorktree: () => createWorktree,
|
|
11337
11709
|
deleteMesh: () => deleteMesh,
|
|
11338
11710
|
detectAllVersions: () => detectAllVersions,
|
|
@@ -11356,6 +11728,7 @@ __export(index_exports, {
|
|
|
11356
11728
|
forwardAgentStreamsToIdeInstance: () => forwardAgentStreamsToIdeInstance,
|
|
11357
11729
|
getAIExtensions: () => getAIExtensions,
|
|
11358
11730
|
getActiveDirectDispatches: () => getActiveDirectDispatches,
|
|
11731
|
+
getActiveSessionDeliveries: () => getActiveSessionDeliveries,
|
|
11359
11732
|
getAvailableIdeIds: () => getAvailableIdeIds,
|
|
11360
11733
|
getCoordinatorForSession: () => getCoordinatorForSession,
|
|
11361
11734
|
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
@@ -11378,6 +11751,7 @@ __export(index_exports, {
|
|
|
11378
11751
|
getQueue: () => getQueue,
|
|
11379
11752
|
getRecentActivity: () => getRecentActivity,
|
|
11380
11753
|
getRecentCommands: () => getRecentCommands,
|
|
11754
|
+
getRecentCompletionConflicts: () => getRecentCompletionConflicts,
|
|
11381
11755
|
getRecentDebugTrace: () => getRecentDebugTrace,
|
|
11382
11756
|
getRecentLogs: () => getRecentLogs,
|
|
11383
11757
|
getSavedProviderSessions: () => getSavedProviderSessions,
|
|
@@ -11465,6 +11839,7 @@ __export(index_exports, {
|
|
|
11465
11839
|
readLedgerEntries: () => readLedgerEntries,
|
|
11466
11840
|
readLedgerSlice: () => readLedgerSlice,
|
|
11467
11841
|
reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
|
|
11842
|
+
recordCompletionConflict: () => recordCompletionConflict,
|
|
11468
11843
|
recordDebugTrace: () => recordDebugTrace,
|
|
11469
11844
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
11470
11845
|
registerMeshCoordinator: () => registerMeshCoordinator,
|
|
@@ -11478,6 +11853,7 @@ __export(index_exports, {
|
|
|
11478
11853
|
resolveChatMessageKind: () => resolveChatMessageKind,
|
|
11479
11854
|
resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
|
|
11480
11855
|
resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
|
|
11856
|
+
resolveDeliveryDecision: () => resolveDeliveryDecision,
|
|
11481
11857
|
resolveGitRepository: () => resolveGitRepository,
|
|
11482
11858
|
resolveMeshHostStatus: () => resolveMeshHostStatus,
|
|
11483
11859
|
resolveMeshRefineValidationPlan: () => resolveMeshRefineValidationPlan,
|
|
@@ -11507,6 +11883,7 @@ __export(index_exports, {
|
|
|
11507
11883
|
updateDirectDispatchStatus: () => updateDirectDispatchStatus,
|
|
11508
11884
|
updateMesh: () => updateMesh,
|
|
11509
11885
|
updateNode: () => updateNode,
|
|
11886
|
+
updateSessionDeliveryStatus: () => updateSessionDeliveryStatus,
|
|
11510
11887
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
11511
11888
|
updateTaskStatus: () => updateTaskStatus,
|
|
11512
11889
|
upsertSavedProviderSession: () => upsertSavedProviderSession,
|
|
@@ -14358,6 +14735,7 @@ function buildMeshAsyncRefineJobs(args) {
|
|
|
14358
14735
|
// src/index.ts
|
|
14359
14736
|
init_mesh_host_ownership();
|
|
14360
14737
|
init_mesh_events();
|
|
14738
|
+
init_mesh_delivery_policy();
|
|
14361
14739
|
|
|
14362
14740
|
// src/mesh/p2p-relay-failure.ts
|
|
14363
14741
|
var NO_FALLBACK_REASON = "Repo Mesh command/data-plane is P2P-only; WS/REST command fallback is intentionally disabled to preserve the transport boundary.";
|
|
@@ -41567,9 +41945,9 @@ var DaemonCommandRouter = class {
|
|
|
41567
41945
|
});
|
|
41568
41946
|
let node;
|
|
41569
41947
|
if (meshRecord.inline) {
|
|
41570
|
-
const { randomUUID:
|
|
41948
|
+
const { randomUUID: randomUUID12 } = await import("crypto");
|
|
41571
41949
|
node = {
|
|
41572
|
-
id: `node_${
|
|
41950
|
+
id: `node_${randomUUID12().replace(/-/g, "")}`,
|
|
41573
41951
|
workspace: result.worktreePath,
|
|
41574
41952
|
repoRoot: result.worktreePath,
|
|
41575
41953
|
daemonId: sourceNode.daemonId,
|
|
@@ -50017,7 +50395,7 @@ var SessionHostPtyTransportFactory = class {
|
|
|
50017
50395
|
};
|
|
50018
50396
|
|
|
50019
50397
|
// src/cli-adapters/raw-terminal-io.ts
|
|
50020
|
-
var
|
|
50398
|
+
var import_crypto7 = require("crypto");
|
|
50021
50399
|
var import_session_host_core4 = require("@adhdev/session-host-core");
|
|
50022
50400
|
var BASE_KEY_SEQUENCES = {
|
|
50023
50401
|
enter: "\r",
|
|
@@ -50115,7 +50493,7 @@ var RawTerminalAttachment = class _RawTerminalAttachment {
|
|
|
50115
50493
|
const sessionId = String(options.sessionId || "").trim();
|
|
50116
50494
|
if (!sessionId) throw new Error("sessionId is required");
|
|
50117
50495
|
const mode = options.mode || "read";
|
|
50118
|
-
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0,
|
|
50496
|
+
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto7.randomUUID)().slice(0, 8)}`;
|
|
50119
50497
|
const client = options.client || new import_session_host_core4.SessionHostClient({ endpoint: options.endpoint });
|
|
50120
50498
|
await client.connect();
|
|
50121
50499
|
const attachResponse = await client.request({
|
|
@@ -51229,6 +51607,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
51229
51607
|
createInteractionId,
|
|
51230
51608
|
createMesh,
|
|
51231
51609
|
createNativeHistoryDispatcher,
|
|
51610
|
+
createSessionDelivery,
|
|
51232
51611
|
createWorktree,
|
|
51233
51612
|
deleteMesh,
|
|
51234
51613
|
detectAllVersions,
|
|
@@ -51252,6 +51631,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
51252
51631
|
forwardAgentStreamsToIdeInstance,
|
|
51253
51632
|
getAIExtensions,
|
|
51254
51633
|
getActiveDirectDispatches,
|
|
51634
|
+
getActiveSessionDeliveries,
|
|
51255
51635
|
getAvailableIdeIds,
|
|
51256
51636
|
getCoordinatorForSession,
|
|
51257
51637
|
getCurrentDaemonLogPath,
|
|
@@ -51274,6 +51654,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
51274
51654
|
getQueue,
|
|
51275
51655
|
getRecentActivity,
|
|
51276
51656
|
getRecentCommands,
|
|
51657
|
+
getRecentCompletionConflicts,
|
|
51277
51658
|
getRecentDebugTrace,
|
|
51278
51659
|
getRecentLogs,
|
|
51279
51660
|
getSavedProviderSessions,
|
|
@@ -51361,6 +51742,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
51361
51742
|
readLedgerEntries,
|
|
51362
51743
|
readLedgerSlice,
|
|
51363
51744
|
reconcileDirectDispatchCompletionFromTranscript,
|
|
51745
|
+
recordCompletionConflict,
|
|
51364
51746
|
recordDebugTrace,
|
|
51365
51747
|
registerExtensionProviders,
|
|
51366
51748
|
registerMeshCoordinator,
|
|
@@ -51374,6 +51756,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
51374
51756
|
resolveChatMessageKind,
|
|
51375
51757
|
resolveCurrentGlobalInstallSurface,
|
|
51376
51758
|
resolveDebugRuntimeConfig,
|
|
51759
|
+
resolveDeliveryDecision,
|
|
51377
51760
|
resolveGitRepository,
|
|
51378
51761
|
resolveMeshHostStatus,
|
|
51379
51762
|
resolveMeshRefineValidationPlan,
|
|
@@ -51403,6 +51786,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
51403
51786
|
updateDirectDispatchStatus,
|
|
51404
51787
|
updateMesh,
|
|
51405
51788
|
updateNode,
|
|
51789
|
+
updateSessionDeliveryStatus,
|
|
51406
51790
|
updateSessionTaskStatus,
|
|
51407
51791
|
updateTaskStatus,
|
|
51408
51792
|
upsertSavedProviderSession,
|