@agentproto/runtime 2.2.0 → 2.4.0
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/README.md +1 -0
- package/dist/catalog-models.mjs +2 -1
- package/dist/catalog-models.mjs.map +1 -1
- package/dist/config.d.ts +20 -0
- package/dist/config.mjs.map +1 -1
- package/dist/index.d.ts +261 -5
- package/dist/index.mjs +581 -38
- package/dist/index.mjs.map +1 -1
- package/dist/resume-strategies.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -310,11 +310,16 @@ function createTranscriptWriter(opts) {
|
|
|
310
310
|
}, DEBOUNCE_MS);
|
|
311
311
|
};
|
|
312
312
|
return {
|
|
313
|
-
recordPrompt(sessionId, message) {
|
|
313
|
+
recordPrompt(sessionId, message, opts2) {
|
|
314
314
|
const state = getState(sessionId);
|
|
315
315
|
flushBuffers(sessionId, state);
|
|
316
316
|
const text9 = typeof message === "string" ? message : JSON.stringify(message);
|
|
317
|
-
writeRecord(sessionId, state, {
|
|
317
|
+
writeRecord(sessionId, state, {
|
|
318
|
+
kind: "user-prompt",
|
|
319
|
+
sessionId,
|
|
320
|
+
text: text9,
|
|
321
|
+
...opts2?.source ? { source: opts2.source } : {}
|
|
322
|
+
});
|
|
318
323
|
},
|
|
319
324
|
recordEvent(sessionId, evt) {
|
|
320
325
|
const state = getState(sessionId);
|
|
@@ -404,6 +409,22 @@ function createTranscriptWriter(opts) {
|
|
|
404
409
|
options: evt.options
|
|
405
410
|
});
|
|
406
411
|
break;
|
|
412
|
+
// Durable counterpart to "agent-prompt" — recorded when
|
|
413
|
+
// `respondPermission` (or a dying session's cancel-in-flight sweep)
|
|
414
|
+
// resolves the ask, keyed by the same `toolCallId` so a reader can
|
|
415
|
+
// tell an answered request from a still-pending one without relying
|
|
416
|
+
// on the in-memory pending-permissions map (see sessions.ts's
|
|
417
|
+
// `resolvePendingPermission` / `cancelPendingPermissionsForSession`).
|
|
418
|
+
case "permission-resolved":
|
|
419
|
+
flushBuffers(sessionId, state);
|
|
420
|
+
writeRecord(sessionId, state, {
|
|
421
|
+
kind: "permission-resolved",
|
|
422
|
+
sessionId,
|
|
423
|
+
toolCallId: evt.toolCallId,
|
|
424
|
+
decision: evt.decision,
|
|
425
|
+
...evt.optionId ? { optionId: evt.optionId } : {}
|
|
426
|
+
});
|
|
427
|
+
break;
|
|
407
428
|
case "turn-end":
|
|
408
429
|
flushBuffers(sessionId, state);
|
|
409
430
|
writeRecord(sessionId, state, { kind: "turn-end", sessionId, reason: evt.reason });
|
|
@@ -2552,7 +2573,7 @@ function resolveAuthSpec(input) {
|
|
|
2552
2573
|
}
|
|
2553
2574
|
if (!provider) return void 0;
|
|
2554
2575
|
const sub = input.descriptor.authSubscription;
|
|
2555
|
-
const supportsSub = sub !== void 0 && (gatewayRoute === void 0 || isNativeGatewayPreset);
|
|
2576
|
+
const supportsSub = (sub !== void 0 || input.descriptor.modelDerivedApiKey === true) && (gatewayRoute === void 0 || isNativeGatewayPreset);
|
|
2556
2577
|
const enforce = input.descriptor.authEnforce ?? "when-configured";
|
|
2557
2578
|
const external = supportsSub && sub?.external === true;
|
|
2558
2579
|
const subCredAvailable = input.subscriptionCredential !== void 0 || external && input.externalSubscriptionVerified === true;
|
|
@@ -2584,7 +2605,7 @@ function resolveAuthSpec(input) {
|
|
|
2584
2605
|
credentialSource = subCredAvailable ? "cli-local-login" : "none";
|
|
2585
2606
|
externalCredential = true;
|
|
2586
2607
|
} else if (mode === "subscription") {
|
|
2587
|
-
setEnv = sub
|
|
2608
|
+
setEnv = sub?.setEnv ?? apiKeyEnv;
|
|
2588
2609
|
credential = input.subscriptionCredential;
|
|
2589
2610
|
credentialSource = credential !== void 0 ? input.subscriptionCredentialSource ?? "explicit-config" : "none";
|
|
2590
2611
|
} else {
|
|
@@ -3658,7 +3679,8 @@ function resolveModelId(id) {
|
|
|
3658
3679
|
}
|
|
3659
3680
|
function methodsForDirect(descriptor) {
|
|
3660
3681
|
const methods = [];
|
|
3661
|
-
if (descriptor?.authSubscription
|
|
3682
|
+
if (descriptor?.authSubscription || descriptor?.modelDerivedApiKey)
|
|
3683
|
+
methods.push("oauth-bearer");
|
|
3662
3684
|
if (descriptor?.provider || descriptor?.modelDerivedApiKey) methods.push("api-key");
|
|
3663
3685
|
return methods;
|
|
3664
3686
|
}
|
|
@@ -5116,6 +5138,14 @@ async function spawnAgentSession(deps2, input) {
|
|
|
5116
5138
|
};
|
|
5117
5139
|
});
|
|
5118
5140
|
}
|
|
5141
|
+
if (mcpServers === void 0 && parentSessionId && buildOrchestratorMcp && input.orchestrator !== false && input.sandbox === void 0) {
|
|
5142
|
+
const injection = buildOrchestratorMcp({
|
|
5143
|
+
tools: ["message_parent"],
|
|
5144
|
+
role: role.name
|
|
5145
|
+
});
|
|
5146
|
+
mcpServers = [injection.entry];
|
|
5147
|
+
bindOrchestratorLifecycle = injection.bindLifecycle;
|
|
5148
|
+
}
|
|
5119
5149
|
const spawnDefaults = resolveSpawnDefaults(configDefaults, input.adapter, {
|
|
5120
5150
|
skills: input.skills,
|
|
5121
5151
|
options: input.options,
|
|
@@ -5277,9 +5307,8 @@ async function spawnAgentSession(deps2, input) {
|
|
|
5277
5307
|
details: { adapter: input.adapter, gateway }
|
|
5278
5308
|
};
|
|
5279
5309
|
}
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
${input.prompt}` : input.prompt;
|
|
5310
|
+
const parentContextLine = parentSessionId ? `You were spawned by session ${parentSessionId} (also available in the ${PARENT_SESSION_ID_ENV} env var). When you finish \u2014 or hit a blocker you cannot resolve \u2014 report back to it via the message_parent tool if one is available (no session id needed; the daemon resolves your parent).` : void 0;
|
|
5311
|
+
let effectivePrompt = input.prompt ? [composeRoleContext(role, input.promptAppend, roleRegistry), parentContextLine, input.prompt].filter((p) => !!p).join("\n\n") : input.prompt;
|
|
5283
5312
|
const explicitTitle = input.title?.trim() ? input.title.trim() : void 0;
|
|
5284
5313
|
const spawnLabel = input.label?.trim() ? input.label.trim() : void 0;
|
|
5285
5314
|
const initialTitle = explicitTitle ?? spawnLabel ?? (input.prompt ? deriveSessionTitle(input.prompt) : void 0);
|
|
@@ -5536,7 +5565,12 @@ ${asyncPrompt}`;
|
|
|
5536
5565
|
// collide with, so this is the entire env for this spawn.
|
|
5537
5566
|
env: {
|
|
5538
5567
|
[SESSION_ID_ENV]: mintedSessionId,
|
|
5539
|
-
[WORKSPACE_SLUG_ENV]: resolvedSlug
|
|
5568
|
+
[WORKSPACE_SLUG_ENV]: resolvedSlug,
|
|
5569
|
+
// Lineage (PARENT_SESSION_ID_ENV's doc, sessions.ts) — mirrors
|
|
5570
|
+
// the descriptor's `parentSessionId` so the child can discover
|
|
5571
|
+
// who spawned it without a registry round-trip. Absent on a
|
|
5572
|
+
// parentless root spawn.
|
|
5573
|
+
...parentSessionId ? { [PARENT_SESSION_ID_ENV]: parentSessionId } : {}
|
|
5540
5574
|
},
|
|
5541
5575
|
onActivity: () => {
|
|
5542
5576
|
if (liveSessionId) registry.pulseActivity(liveSessionId);
|
|
@@ -6721,8 +6755,8 @@ function composeSessionObservers(observers) {
|
|
|
6721
6755
|
);
|
|
6722
6756
|
};
|
|
6723
6757
|
return {
|
|
6724
|
-
recordPrompt(sessionId, message) {
|
|
6725
|
-
forEachSafe((o) => o.recordPrompt(sessionId, message));
|
|
6758
|
+
recordPrompt(sessionId, message, opts) {
|
|
6759
|
+
forEachSafe((o) => o.recordPrompt(sessionId, message, opts));
|
|
6726
6760
|
},
|
|
6727
6761
|
recordEvent(sessionId, evt) {
|
|
6728
6762
|
forEachSafe((o) => o.recordEvent(sessionId, evt));
|
|
@@ -6740,10 +6774,10 @@ function composeSessionObservers(observers) {
|
|
|
6740
6774
|
}
|
|
6741
6775
|
function filterSessionObserver(inner, shouldObserve) {
|
|
6742
6776
|
return {
|
|
6743
|
-
recordPrompt(sessionId, message) {
|
|
6777
|
+
recordPrompt(sessionId, message, opts) {
|
|
6744
6778
|
if (!shouldObserve(sessionId)) return;
|
|
6745
6779
|
try {
|
|
6746
|
-
inner.recordPrompt(sessionId, message);
|
|
6780
|
+
inner.recordPrompt(sessionId, message, opts);
|
|
6747
6781
|
} catch {
|
|
6748
6782
|
}
|
|
6749
6783
|
},
|
|
@@ -7446,6 +7480,7 @@ function mintSessionId() {
|
|
|
7446
7480
|
}
|
|
7447
7481
|
var SESSION_ID_ENV = "AGENTPROTO_SESSION_ID";
|
|
7448
7482
|
var WORKSPACE_SLUG_ENV = "AGENTPROTO_WORKSPACE_SLUG";
|
|
7483
|
+
var PARENT_SESSION_ID_ENV = "AGENTPROTO_PARENT_SESSION_ID";
|
|
7449
7484
|
var SessionNotAliveError = class extends Error {
|
|
7450
7485
|
sessionId;
|
|
7451
7486
|
status;
|
|
@@ -7471,6 +7506,8 @@ function toSessionSummary(desc) {
|
|
|
7471
7506
|
lastOutputAt: desc.lastOutputAt,
|
|
7472
7507
|
lastActivityAt: desc.lastActivityAt,
|
|
7473
7508
|
processAlive: desc.processAlive,
|
|
7509
|
+
watchers: desc.watchers,
|
|
7510
|
+
childrenBusy: desc.childrenBusy,
|
|
7474
7511
|
label: desc.label,
|
|
7475
7512
|
title: desc.title,
|
|
7476
7513
|
renamedByUser: desc.renamedByUser,
|
|
@@ -7498,6 +7535,7 @@ function toSessionSummary(desc) {
|
|
|
7498
7535
|
turnsCompleted: desc.turnsCompleted,
|
|
7499
7536
|
busy: desc.busy,
|
|
7500
7537
|
blockedOn: desc.blockedOn,
|
|
7538
|
+
stalledSinceMs: desc.stalledSinceMs,
|
|
7501
7539
|
origin: desc.origin,
|
|
7502
7540
|
parentSessionId: desc.parentSessionId,
|
|
7503
7541
|
depth: desc.depth,
|
|
@@ -7625,6 +7663,28 @@ function createSessionsRegistry(opts) {
|
|
|
7625
7663
|
const sessionEvents = opts?.sessionEvents;
|
|
7626
7664
|
const resolveAgentAdapter = opts?.resolveAgentAdapter;
|
|
7627
7665
|
const sessions = /* @__PURE__ */ new Map();
|
|
7666
|
+
const watchersById = /* @__PURE__ */ new Map();
|
|
7667
|
+
const stampWatchers = (desc) => {
|
|
7668
|
+
desc.watchers = watchersById.get(desc.id) ?? 0;
|
|
7669
|
+
};
|
|
7670
|
+
const childrenBusyCounts = () => {
|
|
7671
|
+
const all = Array.from(sessions.values());
|
|
7672
|
+
const parentOf = new Map(all.map((s) => [s.desc.id, s.desc.parentSessionId]));
|
|
7673
|
+
const counts = /* @__PURE__ */ new Map();
|
|
7674
|
+
for (const s of all) {
|
|
7675
|
+
const d = s.desc;
|
|
7676
|
+
const midTurn = d.busy === true && (d.status === "running" || d.status === "starting");
|
|
7677
|
+
if (!midTurn) continue;
|
|
7678
|
+
const seen = /* @__PURE__ */ new Set([d.id]);
|
|
7679
|
+
let pid = d.parentSessionId;
|
|
7680
|
+
while (pid && !seen.has(pid)) {
|
|
7681
|
+
seen.add(pid);
|
|
7682
|
+
counts.set(pid, (counts.get(pid) ?? 0) + 1);
|
|
7683
|
+
pid = parentOf.get(pid);
|
|
7684
|
+
}
|
|
7685
|
+
}
|
|
7686
|
+
return counts;
|
|
7687
|
+
};
|
|
7628
7688
|
const pendingPermissions = /* @__PURE__ */ new Map();
|
|
7629
7689
|
let persistTimer = null;
|
|
7630
7690
|
let nextSubId = 1;
|
|
@@ -7688,6 +7748,17 @@ function createSessionsRegistry(opts) {
|
|
|
7688
7748
|
...rt.desc.endedReason ? { reason: rt.desc.endedReason } : {}
|
|
7689
7749
|
});
|
|
7690
7750
|
};
|
|
7751
|
+
const clearStalledFlag = (rt) => {
|
|
7752
|
+
if (rt.desc.stalledSinceMs === void 0) return;
|
|
7753
|
+
rt.desc.stalledSinceMs = void 0;
|
|
7754
|
+
schedulePersist();
|
|
7755
|
+
sessionEvents?.emit({
|
|
7756
|
+
type: "session:stall-cleared",
|
|
7757
|
+
sessionId: rt.desc.id,
|
|
7758
|
+
...rt.desc.label ? { label: rt.desc.label } : {},
|
|
7759
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
7760
|
+
});
|
|
7761
|
+
};
|
|
7691
7762
|
const refreshAwaitingPermission = (rt) => {
|
|
7692
7763
|
let has = false;
|
|
7693
7764
|
for (const p of pendingPermissions.values()) {
|
|
@@ -7748,6 +7819,11 @@ function createSessionsRegistry(opts) {
|
|
|
7748
7819
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
7749
7820
|
});
|
|
7750
7821
|
}
|
|
7822
|
+
transcriptWriter.recordEvent(rt.desc.id, {
|
|
7823
|
+
kind: "permission-resolved",
|
|
7824
|
+
toolCallId: id,
|
|
7825
|
+
decision: "cancelled"
|
|
7826
|
+
});
|
|
7751
7827
|
}
|
|
7752
7828
|
delete rt.desc.awaitingPermission;
|
|
7753
7829
|
};
|
|
@@ -7803,6 +7879,12 @@ function createSessionsRegistry(opts) {
|
|
|
7803
7879
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
7804
7880
|
});
|
|
7805
7881
|
}
|
|
7882
|
+
transcriptWriter.recordEvent(pending.sessionId, {
|
|
7883
|
+
kind: "permission-resolved",
|
|
7884
|
+
toolCallId: id,
|
|
7885
|
+
decision: input.decision,
|
|
7886
|
+
...chosenOptionId ? { optionId: chosenOptionId } : {}
|
|
7887
|
+
});
|
|
7806
7888
|
schedulePersist();
|
|
7807
7889
|
if (!okResolved) {
|
|
7808
7890
|
return { ok: true, permission: pending, decision: input.decision, ...chosenOptionId ? { optionId: chosenOptionId } : {} };
|
|
@@ -8435,7 +8517,7 @@ function createSessionsRegistry(opts) {
|
|
|
8435
8517
|
return;
|
|
8436
8518
|
}
|
|
8437
8519
|
}
|
|
8438
|
-
const runAgentTurn = async (rt, message) => {
|
|
8520
|
+
const runAgentTurn = async (rt, message, turnOpts) => {
|
|
8439
8521
|
if (!rt.agentSession) {
|
|
8440
8522
|
throw new Error("runAgentTurn: session has no agentSession");
|
|
8441
8523
|
}
|
|
@@ -8458,6 +8540,7 @@ ${message}`;
|
|
|
8458
8540
|
rt.desc.awaitingInput = false;
|
|
8459
8541
|
rt.desc.awaitingQuestion = void 0;
|
|
8460
8542
|
releaseBlockedOn(rt.desc);
|
|
8543
|
+
clearStalledFlag(rt);
|
|
8461
8544
|
let turnCompleted = false;
|
|
8462
8545
|
let sawTurnEnd = false;
|
|
8463
8546
|
let abnormalReason;
|
|
@@ -8471,7 +8554,11 @@ ${message}`;
|
|
|
8471
8554
|
`\x1B[2m\u2500\u2500 \u25B6 ${typeof message === "string" ? message : JSON.stringify(message)} \u2500\u2500\x1B[0m`,
|
|
8472
8555
|
"stdout"
|
|
8473
8556
|
);
|
|
8474
|
-
transcriptWriter.recordPrompt(
|
|
8557
|
+
transcriptWriter.recordPrompt(
|
|
8558
|
+
rt.desc.id,
|
|
8559
|
+
message,
|
|
8560
|
+
turnOpts?.promptSource ? { source: turnOpts.promptSource } : void 0
|
|
8561
|
+
);
|
|
8475
8562
|
const wrapped = typeof message === "string" ? { type: "text", text: message } : message;
|
|
8476
8563
|
for await (const evt of rt.agentSession.send(wrapped)) {
|
|
8477
8564
|
transcriptWriter.recordEvent(rt.desc.id, evt);
|
|
@@ -8511,6 +8598,7 @@ ${message}`;
|
|
|
8511
8598
|
rt.desc.busy = false;
|
|
8512
8599
|
rt.emitter.emit("busy", false);
|
|
8513
8600
|
releaseBlockedOn(rt.desc);
|
|
8601
|
+
clearStalledFlag(rt);
|
|
8514
8602
|
if (pendingToolCallIds.size > 0) {
|
|
8515
8603
|
for (const toolCallId of pendingToolCallIds) {
|
|
8516
8604
|
const synthetic = {
|
|
@@ -8882,7 +8970,11 @@ ${message}`;
|
|
|
8882
8970
|
schedulePersist();
|
|
8883
8971
|
recordConversationLink(rt);
|
|
8884
8972
|
if (input.initialPrompt) {
|
|
8885
|
-
void runAgentTurn(
|
|
8973
|
+
void runAgentTurn(
|
|
8974
|
+
rt,
|
|
8975
|
+
input.initialPrompt,
|
|
8976
|
+
desc.parentSessionId ? { promptSource: `agent:${desc.parentSessionId}` } : void 0
|
|
8977
|
+
).catch((err) => {
|
|
8886
8978
|
appendLine(
|
|
8887
8979
|
rt,
|
|
8888
8980
|
`[turn error] ${err instanceof Error ? err.message : String(err)}`,
|
|
@@ -9010,7 +9102,11 @@ ${message}`;
|
|
|
9010
9102
|
schedulePersist();
|
|
9011
9103
|
recordConversationLink(rt);
|
|
9012
9104
|
if (outcome.initialPrompt) {
|
|
9013
|
-
void runAgentTurn(
|
|
9105
|
+
void runAgentTurn(
|
|
9106
|
+
rt,
|
|
9107
|
+
outcome.initialPrompt,
|
|
9108
|
+
rt.desc.parentSessionId ? { promptSource: `agent:${rt.desc.parentSessionId}` } : void 0
|
|
9109
|
+
).catch((err) => {
|
|
9014
9110
|
appendLine(
|
|
9015
9111
|
rt,
|
|
9016
9112
|
`[turn error] ${err instanceof Error ? err.message : String(err)}`,
|
|
@@ -9268,7 +9364,7 @@ ${message}`;
|
|
|
9268
9364
|
}
|
|
9269
9365
|
if (rtPre) await maybeResumeAgent(rtPre);
|
|
9270
9366
|
const rt = validateAgentTurn(id, "sendPrompt");
|
|
9271
|
-
await runAgentTurn(rt, message);
|
|
9367
|
+
await runAgentTurn(rt, message, opts2?.source ? { promptSource: opts2.source } : void 0);
|
|
9272
9368
|
},
|
|
9273
9369
|
async enqueuePrompt(id, message, opts2) {
|
|
9274
9370
|
const rtPre = sessions.get(id);
|
|
@@ -9280,7 +9376,7 @@ ${message}`;
|
|
|
9280
9376
|
}
|
|
9281
9377
|
await maybeResumeAgent(rtPre);
|
|
9282
9378
|
const rt = validateAgentTurn(id, "enqueuePrompt");
|
|
9283
|
-
void runAgentTurn(rt, message).catch((err) => {
|
|
9379
|
+
void runAgentTurn(rt, message, opts2?.source ? { promptSource: opts2.source } : void 0).catch((err) => {
|
|
9284
9380
|
appendLine(
|
|
9285
9381
|
rtPre,
|
|
9286
9382
|
`[error] ${err instanceof Error ? err.message : String(err)}`,
|
|
@@ -9444,13 +9540,17 @@ ${message}`;
|
|
|
9444
9540
|
const rt = sessions.get(id);
|
|
9445
9541
|
if (!rt) return;
|
|
9446
9542
|
rt.desc.lastActivityAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9543
|
+
clearStalledFlag(rt);
|
|
9447
9544
|
schedulePersist();
|
|
9448
9545
|
},
|
|
9449
9546
|
list(opts2) {
|
|
9450
9547
|
const includeArchived = opts2?.includeArchived ?? false;
|
|
9548
|
+
const childrenBusy = childrenBusyCounts();
|
|
9451
9549
|
return Array.from(sessions.values()).map((s) => s.desc).filter((desc) => includeArchived || !desc.archived).sort((a, b) => b.startedAt.localeCompare(a.startedAt)).map((desc) => {
|
|
9452
9550
|
stampProcessAlive(desc);
|
|
9453
9551
|
stampInterrupted(desc);
|
|
9552
|
+
stampWatchers(desc);
|
|
9553
|
+
desc.childrenBusy = childrenBusy.get(desc.id) ?? 0;
|
|
9454
9554
|
return desc;
|
|
9455
9555
|
});
|
|
9456
9556
|
},
|
|
@@ -9458,11 +9558,14 @@ ${message}`;
|
|
|
9458
9558
|
const includeArchived = opts2?.includeArchived ?? false;
|
|
9459
9559
|
const limit = Math.max(1, Math.min(200, opts2?.limit ?? 50));
|
|
9460
9560
|
const offset = Math.max(0, opts2?.offset ?? 0);
|
|
9561
|
+
const childrenBusy = childrenBusyCounts();
|
|
9461
9562
|
const all = Array.from(sessions.values()).map((s) => s.desc).filter((desc) => includeArchived || !desc.archived).sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
|
9462
9563
|
const slice = all.slice(offset, offset + limit);
|
|
9463
9564
|
const summaries = slice.map((desc) => {
|
|
9464
9565
|
stampProcessAlive(desc);
|
|
9465
9566
|
stampInterrupted(desc);
|
|
9567
|
+
stampWatchers(desc);
|
|
9568
|
+
desc.childrenBusy = childrenBusy.get(desc.id) ?? 0;
|
|
9466
9569
|
return toSessionSummary(desc);
|
|
9467
9570
|
});
|
|
9468
9571
|
return { summaries, total: all.length };
|
|
@@ -9472,9 +9575,19 @@ ${message}`;
|
|
|
9472
9575
|
if (desc) {
|
|
9473
9576
|
stampProcessAlive(desc);
|
|
9474
9577
|
stampInterrupted(desc);
|
|
9578
|
+
stampWatchers(desc);
|
|
9579
|
+
desc.childrenBusy = childrenBusyCounts().get(desc.id) ?? 0;
|
|
9475
9580
|
}
|
|
9476
9581
|
return desc;
|
|
9477
9582
|
},
|
|
9583
|
+
incWatchers(id) {
|
|
9584
|
+
watchersById.set(id, (watchersById.get(id) ?? 0) + 1);
|
|
9585
|
+
},
|
|
9586
|
+
decWatchers(id) {
|
|
9587
|
+
const next = (watchersById.get(id) ?? 0) - 1;
|
|
9588
|
+
if (next > 0) watchersById.set(id, next);
|
|
9589
|
+
else watchersById.delete(id);
|
|
9590
|
+
},
|
|
9478
9591
|
attach(id, onLine) {
|
|
9479
9592
|
const rt = sessions.get(id);
|
|
9480
9593
|
if (!rt) return null;
|
|
@@ -9641,6 +9754,30 @@ ${message}`;
|
|
|
9641
9754
|
emitExited(rt);
|
|
9642
9755
|
return true;
|
|
9643
9756
|
},
|
|
9757
|
+
markStalled(id, stalledSinceMs) {
|
|
9758
|
+
const rt = sessions.get(id);
|
|
9759
|
+
if (!rt) return false;
|
|
9760
|
+
if (rt.desc.kind !== "agent-cli" || rt.desc.status !== "running") return false;
|
|
9761
|
+
if (rt.desc.busy !== true || rt.desc.blockedOn !== void 0) return false;
|
|
9762
|
+
if (rt.desc.stalledSinceMs !== void 0) return false;
|
|
9763
|
+
rt.desc.stalledSinceMs = stalledSinceMs;
|
|
9764
|
+
schedulePersist();
|
|
9765
|
+
sessionEvents?.emit({
|
|
9766
|
+
type: "session:stalled",
|
|
9767
|
+
sessionId: rt.desc.id,
|
|
9768
|
+
stalledSinceMs,
|
|
9769
|
+
...rt.desc.label ? { label: rt.desc.label } : {},
|
|
9770
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
9771
|
+
});
|
|
9772
|
+
return true;
|
|
9773
|
+
},
|
|
9774
|
+
clearStalled(id) {
|
|
9775
|
+
const rt = sessions.get(id);
|
|
9776
|
+
if (!rt) return false;
|
|
9777
|
+
const wasFlagged = rt.desc.stalledSinceMs !== void 0;
|
|
9778
|
+
clearStalledFlag(rt);
|
|
9779
|
+
return wasFlagged;
|
|
9780
|
+
},
|
|
9644
9781
|
isResuming(id) {
|
|
9645
9782
|
return !!sessions.get(id)?.resumePromise;
|
|
9646
9783
|
},
|
|
@@ -10707,12 +10844,17 @@ function registerFsTools(server, opts) {
|
|
|
10707
10844
|
const anchor = makeAnchor(opts.workspace);
|
|
10708
10845
|
server.tool(
|
|
10709
10846
|
"file_read",
|
|
10710
|
-
|
|
10711
|
-
{
|
|
10712
|
-
|
|
10847
|
+
`Read a file from the workspace. Defaults to UTF-8 text; pass encoding: "base64" for binary files (images, audio, video, \u2026) \u2014 UTF-8 decoding a non-text file replaces invalid byte sequences (e.g. a PNG's 0x89 header byte) with U+FFFD, corrupting the content.`,
|
|
10848
|
+
{
|
|
10849
|
+
path: z.string().describe("Workspace-relative path to the file."),
|
|
10850
|
+
encoding: z.enum(["utf8", "base64"]).optional().describe(
|
|
10851
|
+
'"utf8" (default) for text files, "base64" for binary files.'
|
|
10852
|
+
)
|
|
10853
|
+
},
|
|
10854
|
+
async ({ path, encoding }) => {
|
|
10713
10855
|
const abs = anchor(path);
|
|
10714
10856
|
const buf = await readFile(abs);
|
|
10715
|
-
return text(buf.toString("utf8"));
|
|
10857
|
+
return text(buf.toString(encoding === "base64" ? "base64" : "utf8"));
|
|
10716
10858
|
}
|
|
10717
10859
|
);
|
|
10718
10860
|
server.tool(
|
|
@@ -10946,6 +11088,7 @@ function registerAgentTools(server, opts) {
|
|
|
10946
11088
|
buildOrchestratorMcp,
|
|
10947
11089
|
callerScope,
|
|
10948
11090
|
callerSessionId,
|
|
11091
|
+
mcpBridgeOrigin,
|
|
10949
11092
|
webhookNotifier,
|
|
10950
11093
|
daemonMcpUrl,
|
|
10951
11094
|
loadRoleRegistry: loadRoleRegistry2,
|
|
@@ -11223,6 +11366,12 @@ function registerAgentTools(server, opts) {
|
|
|
11223
11366
|
{
|
|
11224
11367
|
...spawnInput,
|
|
11225
11368
|
adapter,
|
|
11369
|
+
// Auto-stamp the source channel (#session-visibility): when the
|
|
11370
|
+
// caller didn't pass an explicit `origin`, fall back to the connecting
|
|
11371
|
+
// client's `?origin=` label so a bridge-client spawn (cowork/vscode/
|
|
11372
|
+
// codex) is attributed instead of landing as a bare root. An explicit
|
|
11373
|
+
// `input.origin` (already in `spawnInput`) always wins.
|
|
11374
|
+
...!spawnInput.origin && mcpBridgeOrigin ? { origin: mcpBridgeOrigin } : {},
|
|
11226
11375
|
// The trusted caller id (from `?callerSessionId=`) becomes the
|
|
11227
11376
|
// implicit auto-parent — attach-by-default without the caller
|
|
11228
11377
|
// passing its own id. An explicit `parentSessionId` still outranks
|
|
@@ -11288,8 +11437,10 @@ function registerAgentTools(server, opts) {
|
|
|
11288
11437
|
const sessionId = resolveSessionIdArg(input);
|
|
11289
11438
|
if (!sessionId) return missingSessionIdError("agent_prompt");
|
|
11290
11439
|
try {
|
|
11440
|
+
const promptSource = callerScope?.ownerSessionId ?? callerSessionId;
|
|
11291
11441
|
await registry.enqueuePrompt(sessionId, input.prompt, {
|
|
11292
|
-
interrupt: input.interrupt
|
|
11442
|
+
interrupt: input.interrupt,
|
|
11443
|
+
...promptSource ? { source: `agent:${promptSource}` } : {}
|
|
11293
11444
|
});
|
|
11294
11445
|
return {
|
|
11295
11446
|
content: [
|
|
@@ -11316,6 +11467,67 @@ function registerAgentTools(server, opts) {
|
|
|
11316
11467
|
}
|
|
11317
11468
|
}
|
|
11318
11469
|
);
|
|
11470
|
+
server.tool(
|
|
11471
|
+
"message_parent",
|
|
11472
|
+
"Report a message UP to the session that spawned you (your parent/supervisor) \u2014 a result, a progress update, or a blocker. No session id needed: the daemon resolves your recorded parent from your own session identity (also visible as the AGENTPROTO_PARENT_SESSION_ID env var). Delivered as a prompt when the parent is idle, or queued onto its next turn when it's mid-turn (never interrupts). Errors if this session has no recorded parent or the parent is gone.",
|
|
11473
|
+
{
|
|
11474
|
+
message: z.string().min(1).describe("The message to deliver to your parent session (plain text).")
|
|
11475
|
+
},
|
|
11476
|
+
async (input) => {
|
|
11477
|
+
const fail = (text9) => ({
|
|
11478
|
+
content: [{ type: "text", text: text9 }],
|
|
11479
|
+
isError: true
|
|
11480
|
+
});
|
|
11481
|
+
const selfId = callerScope?.ownerSessionId ?? callerSessionId;
|
|
11482
|
+
if (!selfId) {
|
|
11483
|
+
return fail(
|
|
11484
|
+
"message_parent: cannot identify the calling session \u2014 this tool needs gateway access attributed to a session (a scoped orchestrator gateway, or a daemon `/mcp` URL carrying `?callerSessionId=`). A human/root caller has no parent to message."
|
|
11485
|
+
);
|
|
11486
|
+
}
|
|
11487
|
+
const self = registry.get(selfId);
|
|
11488
|
+
if (!self) {
|
|
11489
|
+
return fail(`message_parent: calling session "${selfId}" is not in the registry.`);
|
|
11490
|
+
}
|
|
11491
|
+
const parentId = self.parentSessionId;
|
|
11492
|
+
if (!parentId || parentId === selfId) {
|
|
11493
|
+
return fail(
|
|
11494
|
+
"message_parent: this session has no recorded parent \u2014 it was spawned at the root, so there is no one to report up to."
|
|
11495
|
+
);
|
|
11496
|
+
}
|
|
11497
|
+
const parent = registry.get(parentId);
|
|
11498
|
+
if (!parent) {
|
|
11499
|
+
return fail(`message_parent: parent session "${parentId}" no longer exists.`);
|
|
11500
|
+
}
|
|
11501
|
+
if (parent.status !== "running" && parent.status !== "starting") {
|
|
11502
|
+
return fail(
|
|
11503
|
+
`message_parent: parent session "${parentId}" is not running (status: ${parent.status}) \u2014 the message cannot be delivered.`
|
|
11504
|
+
);
|
|
11505
|
+
}
|
|
11506
|
+
const who = self.label ?? selfId;
|
|
11507
|
+
const notice = `[child-message] ${who} (${selfId}): ${input.message}`;
|
|
11508
|
+
const done = (delivery) => ({
|
|
11509
|
+
content: [
|
|
11510
|
+
{
|
|
11511
|
+
type: "text",
|
|
11512
|
+
text: JSON.stringify({ ok: true, parentSessionId: parentId, delivery }, null, 2)
|
|
11513
|
+
}
|
|
11514
|
+
]
|
|
11515
|
+
});
|
|
11516
|
+
if (!parent.busy) {
|
|
11517
|
+
try {
|
|
11518
|
+
await registry.enqueuePrompt(parentId, notice, {});
|
|
11519
|
+
return done("enqueued");
|
|
11520
|
+
} catch {
|
|
11521
|
+
}
|
|
11522
|
+
}
|
|
11523
|
+
if (!registry.stampPendingChildCrashNotice(parentId, notice)) {
|
|
11524
|
+
return fail(
|
|
11525
|
+
`message_parent: parent session "${parentId}" vanished mid-delivery.`
|
|
11526
|
+
);
|
|
11527
|
+
}
|
|
11528
|
+
return done("queued-next-turn");
|
|
11529
|
+
}
|
|
11530
|
+
);
|
|
11319
11531
|
server.tool(
|
|
11320
11532
|
"agent_output",
|
|
11321
11533
|
"Tail the recent output of a session. Returns the last N lines of the ring buffer (stdout + stderr inter-leaved, newest last). Use this to read an agent's reply after `agent_prompt`.",
|
|
@@ -12406,6 +12618,15 @@ async function restartAgentSession(registry, resolveAgentAdapter, prev, opts = {
|
|
|
12406
12618
|
...accessProfileEcho ? { accessProfile: accessProfileEcho } : {},
|
|
12407
12619
|
...effMode ? { mode: effMode } : {},
|
|
12408
12620
|
...resolved.commandPreview ? { commandPreview: resolved.commandPreview } : {},
|
|
12621
|
+
// Lineage carry-forward (#session-visibility). A restart is a NEW
|
|
12622
|
+
// descriptor, but it is the same logical session continued — so its
|
|
12623
|
+
// origin (which channel spawned it: cowork/vscode/codex/cron) and its
|
|
12624
|
+
// parent/depth must survive, exactly as continue-fresh already carries
|
|
12625
|
+
// them (session-continue-fresh.ts). Dropping them here is what left a
|
|
12626
|
+
// restarted session a bare top-level root with no source trace.
|
|
12627
|
+
...prev.origin ? { origin: prev.origin } : {},
|
|
12628
|
+
...prev.parentSessionId ? { parentSessionId: prev.parentSessionId } : {},
|
|
12629
|
+
...prev.depth !== void 0 ? { depth: prev.depth } : {},
|
|
12409
12630
|
// Verifiability echo (never the credential) — see the auth
|
|
12410
12631
|
// resolution block above. Absent when no credential resolved,
|
|
12411
12632
|
// same as session-spawn.ts.
|
|
@@ -13981,6 +14202,13 @@ function registerSessionTools(rawServer, opts) {
|
|
|
13981
14202
|
rows: input.rows ?? 24,
|
|
13982
14203
|
...prev.name ? { name: prev.name } : {},
|
|
13983
14204
|
...prev.label ? { label: prev.label } : {},
|
|
14205
|
+
// Lineage carry-forward (#session-visibility) — same reasoning as
|
|
14206
|
+
// the agent branch in session-restart-core.ts: a restart keeps the
|
|
14207
|
+
// logical session's origin/parent/depth rather than resetting it to
|
|
14208
|
+
// a bare root.
|
|
14209
|
+
...prev.origin ? { origin: prev.origin } : {},
|
|
14210
|
+
...prev.parentSessionId ? { parentSessionId: prev.parentSessionId } : {},
|
|
14211
|
+
...prev.depth !== void 0 ? { depth: prev.depth } : {},
|
|
13984
14212
|
resumedFrom: prev.id,
|
|
13985
14213
|
resumeVia: describeResumePath(augmented)
|
|
13986
14214
|
});
|
|
@@ -19551,11 +19779,13 @@ async function monitorSessionWait(opts) {
|
|
|
19551
19779
|
return new Promise((resolve22) => {
|
|
19552
19780
|
const unsubs = [];
|
|
19553
19781
|
let settled = false;
|
|
19782
|
+
for (const id of resolvedIds) registry.incWatchers(id);
|
|
19554
19783
|
const finish = (result) => {
|
|
19555
19784
|
if (settled) return;
|
|
19556
19785
|
settled = true;
|
|
19557
19786
|
clearTimeout(timer);
|
|
19558
19787
|
for (const u of unsubs) u();
|
|
19788
|
+
for (const id of resolvedIds) registry.decWatchers(id);
|
|
19559
19789
|
resolve22(result);
|
|
19560
19790
|
};
|
|
19561
19791
|
const relevantTypes = targetEvent === "any" ? ["session:turn-end", "session:awaiting-input", "session:exited"] : targetEvent === "turn-end" ? ["session:turn-end", "session:awaiting-input"] : targetEvent === "awaiting-input" ? ["session:awaiting-input"] : ["session:exited"];
|
|
@@ -20914,11 +21144,18 @@ async function startHttpServer(opts) {
|
|
|
20914
21144
|
const raw = new URLSearchParams(url.slice(qIdx + 1)).get("callerSessionId");
|
|
20915
21145
|
return raw && raw.length > 0 ? raw : void 0;
|
|
20916
21146
|
}
|
|
21147
|
+
function parseOriginQuery(url) {
|
|
21148
|
+
const qIdx = url.indexOf("?");
|
|
21149
|
+
if (qIdx === -1) return void 0;
|
|
21150
|
+
const raw = new URLSearchParams(url.slice(qIdx + 1)).get("origin");
|
|
21151
|
+
return raw && raw.length > 0 ? raw : void 0;
|
|
21152
|
+
}
|
|
20917
21153
|
async function handleMcp(req, res) {
|
|
20918
21154
|
if (!authorizeMcp(req, res)) return;
|
|
20919
21155
|
const denyTools = parseDenyToolsQuery(req.url ?? "");
|
|
20920
21156
|
const callerSessionId = parseCallerSessionIdQuery(req.url ?? "");
|
|
20921
|
-
const
|
|
21157
|
+
const origin = parseOriginQuery(req.url ?? "");
|
|
21158
|
+
const server2 = await opts.mcpServerFactory(denyTools, callerSessionId, origin);
|
|
20922
21159
|
await serveMcp(req, res, server2);
|
|
20923
21160
|
}
|
|
20924
21161
|
async function handleOrchestratorMcp(req, res) {
|
|
@@ -20968,7 +21205,8 @@ async function startHttpServer(opts) {
|
|
|
20968
21205
|
resumeSessionsOnBoot: opts.meta.resumeSessionsOnBoot === true,
|
|
20969
21206
|
idleReapAfterMs: opts.meta.idleReapAfterMs ?? 0,
|
|
20970
21207
|
crashDetectIntervalMs: opts.meta.crashDetectIntervalMs ?? 0,
|
|
20971
|
-
restartSweepIntervalMs: opts.meta.restartSweepIntervalMs ?? 0
|
|
21208
|
+
restartSweepIntervalMs: opts.meta.restartSweepIntervalMs ?? 0,
|
|
21209
|
+
turnStallAfterMs: opts.meta.turnStallAfterMs ?? 0
|
|
20972
21210
|
})
|
|
20973
21211
|
);
|
|
20974
21212
|
}
|
|
@@ -24414,6 +24652,49 @@ function runCrashDetectPass(opts) {
|
|
|
24414
24652
|
return summary;
|
|
24415
24653
|
}
|
|
24416
24654
|
|
|
24655
|
+
// src/stall-watchdog.ts
|
|
24656
|
+
function lastActivityMsOf(desc) {
|
|
24657
|
+
const tsStr = desc.lastActivityAt ?? desc.startedAt;
|
|
24658
|
+
const ts = tsStr ? Date.parse(tsStr) : Number.NaN;
|
|
24659
|
+
return Number.isFinite(ts) ? ts : null;
|
|
24660
|
+
}
|
|
24661
|
+
function isStallCandidate(desc, nowMs, thresholdMs) {
|
|
24662
|
+
if (desc.kind !== "agent-cli") return false;
|
|
24663
|
+
if (desc.status !== "running") return false;
|
|
24664
|
+
if (desc.busy !== true) return false;
|
|
24665
|
+
if (desc.blockedOn !== void 0) return false;
|
|
24666
|
+
if (desc.stalledSinceMs !== void 0) return false;
|
|
24667
|
+
const lastMs = lastActivityMsOf(desc);
|
|
24668
|
+
if (lastMs === null) return false;
|
|
24669
|
+
return nowMs - lastMs > thresholdMs;
|
|
24670
|
+
}
|
|
24671
|
+
function runStallWatchdogPass(opts) {
|
|
24672
|
+
const { registry, isServed } = opts;
|
|
24673
|
+
const thresholdMs = opts.turnStallAfterMs;
|
|
24674
|
+
if (!thresholdMs || thresholdMs <= 0) {
|
|
24675
|
+
return { enabled: false, candidates: 0, stalled: 0, ids: [] };
|
|
24676
|
+
}
|
|
24677
|
+
const nowMs = opts.now ? opts.now() : Date.now();
|
|
24678
|
+
const all = registry.list({ includeArchived: true });
|
|
24679
|
+
const candidates = all.filter(
|
|
24680
|
+
(d) => (isServed?.(d) ?? true) && isStallCandidate(d, nowMs, thresholdMs)
|
|
24681
|
+
);
|
|
24682
|
+
const summary = {
|
|
24683
|
+
enabled: true,
|
|
24684
|
+
candidates: candidates.length,
|
|
24685
|
+
stalled: 0,
|
|
24686
|
+
ids: []
|
|
24687
|
+
};
|
|
24688
|
+
for (const d of candidates) {
|
|
24689
|
+
const lastMs = lastActivityMsOf(d) ?? nowMs;
|
|
24690
|
+
if (registry.markStalled(d.id, lastMs)) {
|
|
24691
|
+
summary.stalled++;
|
|
24692
|
+
summary.ids.push(d.id);
|
|
24693
|
+
}
|
|
24694
|
+
}
|
|
24695
|
+
return summary;
|
|
24696
|
+
}
|
|
24697
|
+
|
|
24417
24698
|
// src/restart-scheduler.ts
|
|
24418
24699
|
function isEligibleForRestart(desc) {
|
|
24419
24700
|
const policy = desc.restartPolicy;
|
|
@@ -25513,6 +25794,13 @@ function createAppRegistry(opts) {
|
|
|
25513
25794
|
listApps() {
|
|
25514
25795
|
return [...state.apps];
|
|
25515
25796
|
},
|
|
25797
|
+
removeApp(appId) {
|
|
25798
|
+
const idx = state.apps.findIndex((a) => a.appId === appId);
|
|
25799
|
+
if (idx === -1) return void 0;
|
|
25800
|
+
const [removed] = state.apps.splice(idx, 1);
|
|
25801
|
+
persist();
|
|
25802
|
+
return removed;
|
|
25803
|
+
},
|
|
25516
25804
|
createRun(input) {
|
|
25517
25805
|
const run = {
|
|
25518
25806
|
appRunId: `apprun_${randomUUID()}`,
|
|
@@ -25569,6 +25857,31 @@ function createAppRegistry(opts) {
|
|
|
25569
25857
|
}
|
|
25570
25858
|
};
|
|
25571
25859
|
}
|
|
25860
|
+
var EMPTY_CATALOG = { apps: [] };
|
|
25861
|
+
function defaultAppCatalogPath() {
|
|
25862
|
+
return join(homedir(), ".agentproto", "app-catalog.json");
|
|
25863
|
+
}
|
|
25864
|
+
async function loadAppCatalogFile(path) {
|
|
25865
|
+
const catalogPath = path ?? defaultAppCatalogPath();
|
|
25866
|
+
let raw;
|
|
25867
|
+
try {
|
|
25868
|
+
raw = await readFile(catalogPath, "utf8");
|
|
25869
|
+
} catch {
|
|
25870
|
+
return EMPTY_CATALOG;
|
|
25871
|
+
}
|
|
25872
|
+
try {
|
|
25873
|
+
const parsed = JSON.parse(raw);
|
|
25874
|
+
if (!Array.isArray(parsed.apps)) return EMPTY_CATALOG;
|
|
25875
|
+
const apps = parsed.apps.filter((e) => {
|
|
25876
|
+
if (typeof e !== "object" || e === null) return false;
|
|
25877
|
+
const rec = e;
|
|
25878
|
+
return typeof rec.appId === "string" && typeof rec.dir === "string";
|
|
25879
|
+
});
|
|
25880
|
+
return { apps };
|
|
25881
|
+
} catch {
|
|
25882
|
+
return EMPTY_CATALOG;
|
|
25883
|
+
}
|
|
25884
|
+
}
|
|
25572
25885
|
|
|
25573
25886
|
// src/app-tools.ts
|
|
25574
25887
|
var DEFAULT_AGENT_ADAPTER = "mastra-agent";
|
|
@@ -25601,7 +25914,12 @@ async function readAppRefs(dir) {
|
|
|
25601
25914
|
const toRefs = (v) => Array.isArray(v) ? v.filter(
|
|
25602
25915
|
(e) => typeof e === "object" && e !== null && typeof e.id === "string" && typeof e.path === "string"
|
|
25603
25916
|
).map((e) => ({ id: e.id, path: resolveRef(dir, e.path) })) : [];
|
|
25604
|
-
|
|
25917
|
+
let ui;
|
|
25918
|
+
if (typeof data.ui === "object" && data.ui !== null && typeof data.ui.path === "string") {
|
|
25919
|
+
const uiData = data.ui;
|
|
25920
|
+
ui = { ...uiData, path: resolveRef(dir, uiData.path) };
|
|
25921
|
+
}
|
|
25922
|
+
return { agents: toRefs(data.agents), workflows: toRefs(data.workflows), ...ui ? { ui } : {} };
|
|
25605
25923
|
}
|
|
25606
25924
|
async function performInstall(dir, appRegistry, listRegisteredToolIds, resolveAgentAdapter) {
|
|
25607
25925
|
let handle;
|
|
@@ -25639,20 +25957,31 @@ async function performInstall(dir, appRegistry, listRegisteredToolIds, resolveAg
|
|
|
25639
25957
|
const unvalidatedAgentTools = [
|
|
25640
25958
|
...new Set(handle.agents.flatMap((e) => (e.agent.tools ?? []).map(refIdOf)))
|
|
25641
25959
|
];
|
|
25960
|
+
const ui = refs.ui ? {
|
|
25961
|
+
path: refs.ui.path,
|
|
25962
|
+
...handle.ui?.title !== void 0 ? { title: handle.ui.title } : {},
|
|
25963
|
+
...handle.ui?.description !== void 0 ? { description: handle.ui.description } : {},
|
|
25964
|
+
...handle.ui?.tools !== void 0 ? { tools: handle.ui.tools } : {},
|
|
25965
|
+
...handle.ui?.csp !== void 0 ? { csp: handle.ui.csp } : {}
|
|
25966
|
+
} : void 0;
|
|
25642
25967
|
const record2 = appRegistry.upsertApp({
|
|
25643
25968
|
appId: handle.id,
|
|
25644
25969
|
dir,
|
|
25645
25970
|
...handle.version ? { version: handle.version } : {},
|
|
25646
25971
|
...handle.name ? { name: handle.name } : {},
|
|
25972
|
+
...handle.description ? { description: handle.description } : {},
|
|
25647
25973
|
agents: refs.agents,
|
|
25648
25974
|
workflows: refs.workflows,
|
|
25649
25975
|
unvalidatedAgentTools,
|
|
25650
|
-
...handle.requires ? { requires: handle.requires } : {}
|
|
25976
|
+
...handle.requires ? { requires: handle.requires } : {},
|
|
25977
|
+
...ui ? { ui } : {},
|
|
25978
|
+
...handle.artifacts ? { artifacts: handle.artifacts } : {},
|
|
25979
|
+
...handle.dev ? { dev: handle.dev } : {}
|
|
25651
25980
|
});
|
|
25652
25981
|
return { ok: true, record: record2 };
|
|
25653
25982
|
}
|
|
25654
25983
|
function registerAppTools(server, opts) {
|
|
25655
|
-
const { registry, resolveAgentAdapter, listRegisteredToolIds, workflowRunner } = opts;
|
|
25984
|
+
const { registry, resolveAgentAdapter, listRegisteredToolIds, workflowRunner, dispatchTool, callImportedTool } = opts;
|
|
25656
25985
|
const appRegistry = opts.appRegistry ?? createAppRegistry({
|
|
25657
25986
|
...opts.persistPath !== void 0 ? { persistPath: opts.persistPath } : {},
|
|
25658
25987
|
...opts.persist !== void 0 ? { persist: opts.persist } : {}
|
|
@@ -25901,6 +26230,167 @@ function registerAppTools(server, opts) {
|
|
|
25901
26230
|
return textResult(result);
|
|
25902
26231
|
}
|
|
25903
26232
|
);
|
|
26233
|
+
server.tool(
|
|
26234
|
+
"app_tool_call",
|
|
26235
|
+
"Call one of an installed app's UI-exposed tools \u2014 the allowlist set at `defineApp({ ui: { tools: [...] } })` time (`app_install`'s `record.ui.tools`). A tool id prefixed `imported:<alias>/<toolName>` dispatches through an imported MCP server (same proxy `mcp_imported_call` uses); every other id dispatches through the daemon's own registered tools (same reach-in routine/cron `target.tool` dispatch uses).",
|
|
26236
|
+
{
|
|
26237
|
+
appId: z.string(),
|
|
26238
|
+
tool: z.string().describe("A tool id from the app's `ui.tools` allowlist."),
|
|
26239
|
+
args: z.record(z.string(), z.unknown()).optional().describe("Tool arguments. Default: empty object.")
|
|
26240
|
+
},
|
|
26241
|
+
async (input) => {
|
|
26242
|
+
const installed = appRegistry.getApp(input.appId);
|
|
26243
|
+
if (!installed || !installed.ui) {
|
|
26244
|
+
return errorResult(`app_tool_call: app "${input.appId}" is not installed or has no UI.`);
|
|
26245
|
+
}
|
|
26246
|
+
const allowlist = installed.ui.tools ?? [];
|
|
26247
|
+
if (!allowlist.includes(input.tool)) {
|
|
26248
|
+
return errorResult(
|
|
26249
|
+
`app_tool_call: tool "${input.tool}" is not in app "${input.appId}"'s ui.tools allowlist: ${allowlist.length > 0 ? allowlist.join(", ") : "(empty)"}`
|
|
26250
|
+
);
|
|
26251
|
+
}
|
|
26252
|
+
const args = input.args ?? {};
|
|
26253
|
+
try {
|
|
26254
|
+
if (input.tool.startsWith("imported:")) {
|
|
26255
|
+
if (!callImportedTool) return notEnabled("app_tool_call");
|
|
26256
|
+
const rest = input.tool.slice("imported:".length);
|
|
26257
|
+
const slash = rest.indexOf("/");
|
|
26258
|
+
if (slash === -1) {
|
|
26259
|
+
return errorResult(
|
|
26260
|
+
`app_tool_call: malformed imported tool id "${input.tool}" \u2014 expected "imported:<alias>/<toolName>".`
|
|
26261
|
+
);
|
|
26262
|
+
}
|
|
26263
|
+
const result2 = await callImportedTool(rest.slice(0, slash), rest.slice(slash + 1), args);
|
|
26264
|
+
return textResult(result2);
|
|
26265
|
+
}
|
|
26266
|
+
if (!dispatchTool) return notEnabled("app_tool_call");
|
|
26267
|
+
const result = await dispatchTool(input.tool, args);
|
|
26268
|
+
return textResult(result);
|
|
26269
|
+
} catch (err) {
|
|
26270
|
+
return errorResult(`app_tool_call: ${err instanceof Error ? err.message : String(err)}`);
|
|
26271
|
+
}
|
|
26272
|
+
}
|
|
26273
|
+
);
|
|
26274
|
+
server.tool(
|
|
26275
|
+
"app_uninstall",
|
|
26276
|
+
"Remove an installed app's record. Refuses if the app is applied to any scope (unapply first via app_unapply) or has a running app_run (stop it first via app_stop).",
|
|
26277
|
+
{ appId: z.string() },
|
|
26278
|
+
async (input) => {
|
|
26279
|
+
const applied = appRegistry.listApplied().filter((m) => m.appId === input.appId);
|
|
26280
|
+
if (applied.length > 0) {
|
|
26281
|
+
return errorResult(
|
|
26282
|
+
`app_uninstall: app "${input.appId}" is applied to scope(s) ${applied.map((m) => m.scopeId).join(", ")} \u2014 unapply from scopes first.`
|
|
26283
|
+
);
|
|
26284
|
+
}
|
|
26285
|
+
const runningRuns = appRegistry.listRuns().filter((r) => r.appId === input.appId && r.status === "running");
|
|
26286
|
+
if (runningRuns.length > 0) {
|
|
26287
|
+
return errorResult(
|
|
26288
|
+
`app_uninstall: app "${input.appId}" has running app_run(s) ${runningRuns.map((r) => r.appRunId).join(", ")} \u2014 stop app runs first.`
|
|
26289
|
+
);
|
|
26290
|
+
}
|
|
26291
|
+
const removed = appRegistry.removeApp(input.appId);
|
|
26292
|
+
if (!removed) {
|
|
26293
|
+
return errorResult(`app_uninstall: no installed app "${input.appId}".`);
|
|
26294
|
+
}
|
|
26295
|
+
return textResult({ appId: removed.appId });
|
|
26296
|
+
}
|
|
26297
|
+
);
|
|
26298
|
+
server.tool(
|
|
26299
|
+
"app_catalog",
|
|
26300
|
+
"List browsable apps from the catalog file (default `~/.agentproto/app-catalog.json`, tolerates a missing file), merged with installed-app status \u2014 every entry reports `installed` and `hasUi`. Installed apps absent from the catalog file are included too.",
|
|
26301
|
+
{
|
|
26302
|
+
scopeId: z.string().optional().describe("Reserved for future scope-aware filtering. Currently unused.")
|
|
26303
|
+
},
|
|
26304
|
+
async () => {
|
|
26305
|
+
const catalog = await loadAppCatalogFile(opts.catalogPath);
|
|
26306
|
+
const installedApps = appRegistry.listApps();
|
|
26307
|
+
const installedById = new Map(installedApps.map((a) => [a.appId, a]));
|
|
26308
|
+
const seen = /* @__PURE__ */ new Set();
|
|
26309
|
+
const entries = catalog.apps.map((entry) => {
|
|
26310
|
+
const installed = installedById.get(entry.appId);
|
|
26311
|
+
seen.add(entry.appId);
|
|
26312
|
+
const name = entry.name ?? installed?.name;
|
|
26313
|
+
const description = entry.description ?? installed?.description;
|
|
26314
|
+
return {
|
|
26315
|
+
appId: entry.appId,
|
|
26316
|
+
...name ? { name } : {},
|
|
26317
|
+
...description ? { description } : {},
|
|
26318
|
+
dir: entry.dir,
|
|
26319
|
+
...entry.category ? { category: entry.category } : {},
|
|
26320
|
+
installed: installed !== void 0,
|
|
26321
|
+
hasUi: installed?.ui !== void 0
|
|
26322
|
+
};
|
|
26323
|
+
});
|
|
26324
|
+
for (const app of installedApps) {
|
|
26325
|
+
if (seen.has(app.appId)) continue;
|
|
26326
|
+
entries.push({
|
|
26327
|
+
appId: app.appId,
|
|
26328
|
+
...app.name ? { name: app.name } : {},
|
|
26329
|
+
...app.description ? { description: app.description } : {},
|
|
26330
|
+
dir: app.dir,
|
|
26331
|
+
installed: true,
|
|
26332
|
+
hasUi: app.ui !== void 0
|
|
26333
|
+
});
|
|
26334
|
+
}
|
|
26335
|
+
return textResult(entries);
|
|
26336
|
+
}
|
|
26337
|
+
);
|
|
26338
|
+
}
|
|
26339
|
+
function appUiToolId(appId) {
|
|
26340
|
+
const slug = appId.replace(/^@[^/]+\//, "").replace(/[^a-z0-9]/g, "_");
|
|
26341
|
+
return `app_ui_${slug}`;
|
|
26342
|
+
}
|
|
26343
|
+
function createUiHtmlCache() {
|
|
26344
|
+
const cache = /* @__PURE__ */ new Map();
|
|
26345
|
+
return {
|
|
26346
|
+
async get(path, version) {
|
|
26347
|
+
const cached = cache.get(path);
|
|
26348
|
+
if (cached && cached.version === version) return cached.html;
|
|
26349
|
+
const html = await readFile(path, "utf8");
|
|
26350
|
+
cache.set(path, { version, html });
|
|
26351
|
+
return html;
|
|
26352
|
+
}
|
|
26353
|
+
};
|
|
26354
|
+
}
|
|
26355
|
+
async function makeInstalledAppUiApps(appRegistry, cache, existingToolNames) {
|
|
26356
|
+
const apps = [];
|
|
26357
|
+
const seen = new Set(existingToolNames);
|
|
26358
|
+
for (const app of appRegistry.listApps()) {
|
|
26359
|
+
const ui = app.ui;
|
|
26360
|
+
if (!ui) continue;
|
|
26361
|
+
const toolId = appUiToolId(app.appId);
|
|
26362
|
+
if (seen.has(toolId)) {
|
|
26363
|
+
console.warn(
|
|
26364
|
+
`[app-ui-apps] skipping UI panel for app "${app.appId}": tool id "${toolId}" collides with an existing tool or another installed app's panel.`
|
|
26365
|
+
);
|
|
26366
|
+
continue;
|
|
26367
|
+
}
|
|
26368
|
+
let html;
|
|
26369
|
+
try {
|
|
26370
|
+
html = await cache.get(ui.path, app.updatedAt);
|
|
26371
|
+
} catch (err) {
|
|
26372
|
+
console.warn(
|
|
26373
|
+
`[app-ui-apps] skipping UI panel for app "${app.appId}": could not read "${ui.path}": ${err instanceof Error ? err.message : String(err)}`
|
|
26374
|
+
);
|
|
26375
|
+
continue;
|
|
26376
|
+
}
|
|
26377
|
+
seen.add(toolId);
|
|
26378
|
+
apps.push({
|
|
26379
|
+
id: toolId,
|
|
26380
|
+
title: ui.title ?? app.name ?? app.appId,
|
|
26381
|
+
...ui.description ? { description: ui.description } : {},
|
|
26382
|
+
inputSchema: z.object({}),
|
|
26383
|
+
execute: async () => ({ appId: app.appId, tools: ui.tools ?? [] }),
|
|
26384
|
+
html,
|
|
26385
|
+
...ui.csp ? {
|
|
26386
|
+
csp: {
|
|
26387
|
+
...ui.csp.connectDomains ? { connectDomains: [...ui.csp.connectDomains] } : {},
|
|
26388
|
+
...ui.csp.resourceDomains ? { resourceDomains: [...ui.csp.resourceDomains] } : {}
|
|
26389
|
+
}
|
|
26390
|
+
} : {}
|
|
26391
|
+
});
|
|
26392
|
+
}
|
|
26393
|
+
return apps;
|
|
25904
26394
|
}
|
|
25905
26395
|
function createSessionEventBus() {
|
|
25906
26396
|
const ee = new EventEmitter();
|
|
@@ -27825,6 +28315,11 @@ var DEFAULT_ORCHESTRATOR_TOOLS = [
|
|
|
27825
28315
|
"agent_prompt",
|
|
27826
28316
|
"agent_output",
|
|
27827
28317
|
"agent_kill",
|
|
28318
|
+
// Child→parent report-back. NOT a delegation tool (takes no session id;
|
|
28319
|
+
// the daemon resolves the caller's own recorded parent, and it can reach
|
|
28320
|
+
// nothing else) — it's also the sole tool of the minimal report-only
|
|
28321
|
+
// scope `session-spawn.ts` mints for a gateway-less child with a parent.
|
|
28322
|
+
"message_parent",
|
|
27828
28323
|
"session_monitor",
|
|
27829
28324
|
"session_events_poll",
|
|
27830
28325
|
"session_list",
|
|
@@ -29081,7 +29576,8 @@ function registerDaemonHealthTools(server, opts) {
|
|
|
29081
29576
|
resumeSessionsOnBoot: opts.resumeSessionsOnBoot,
|
|
29082
29577
|
idleReapAfterMs: opts.idleReapAfterMs,
|
|
29083
29578
|
crashDetectIntervalMs: opts.crashDetectIntervalMs ?? 0,
|
|
29084
|
-
restartSweepIntervalMs: opts.restartSweepIntervalMs ?? 0
|
|
29579
|
+
restartSweepIntervalMs: opts.restartSweepIntervalMs ?? 0,
|
|
29580
|
+
turnStallAfterMs: opts.turnStallAfterMs ?? 0
|
|
29085
29581
|
});
|
|
29086
29582
|
}
|
|
29087
29583
|
);
|
|
@@ -31226,6 +31722,7 @@ async function isAgentCliAuthConfigured(slug, descriptor, model) {
|
|
|
31226
31722
|
|
|
31227
31723
|
// src/index.ts
|
|
31228
31724
|
var DEFAULT_CRASH_DETECT_INTERVAL_MS = 3e4;
|
|
31725
|
+
var DEFAULT_TURN_STALL_AFTER_MS = 5 * 6e4;
|
|
31229
31726
|
var DEFAULT_ALWAYS_ON_TOOLS = [
|
|
31230
31727
|
"daemon_health",
|
|
31231
31728
|
"agent_start",
|
|
@@ -31236,7 +31733,8 @@ var DEFAULT_ALWAYS_ON_TOOLS = [
|
|
|
31236
31733
|
"session_monitor",
|
|
31237
31734
|
"session_events_poll",
|
|
31238
31735
|
"permissions_list",
|
|
31239
|
-
"permissions_respond"
|
|
31736
|
+
"permissions_respond",
|
|
31737
|
+
"app_tool_call"
|
|
31240
31738
|
];
|
|
31241
31739
|
async function createGateway(opts) {
|
|
31242
31740
|
const startedAt = Date.now();
|
|
@@ -31244,6 +31742,7 @@ async function createGateway(opts) {
|
|
|
31244
31742
|
const idleReapAfterMs = typeof opts.idleReapAfterMs === "number" && opts.idleReapAfterMs > 0 ? opts.idleReapAfterMs : 0;
|
|
31245
31743
|
const crashDetectIntervalMs = typeof opts.crashDetectIntervalMs === "number" ? opts.crashDetectIntervalMs > 0 ? opts.crashDetectIntervalMs : 0 : DEFAULT_CRASH_DETECT_INTERVAL_MS;
|
|
31246
31744
|
const restartSweepIntervalMs = typeof opts.restartSweepIntervalMs === "number" && opts.restartSweepIntervalMs > 0 ? opts.restartSweepIntervalMs : 0;
|
|
31745
|
+
const turnStallAfterMs = typeof opts.turnStallAfterMs === "number" ? opts.turnStallAfterMs > 0 ? opts.turnStallAfterMs : 0 : DEFAULT_TURN_STALL_AFTER_MS;
|
|
31247
31746
|
const workspace = resolve(opts.workspace);
|
|
31248
31747
|
if (!existsSync(workspace)) {
|
|
31249
31748
|
throw new Error(`runtime: workspace dir does not exist: ${workspace}`);
|
|
@@ -31420,7 +31919,8 @@ async function createGateway(opts) {
|
|
|
31420
31919
|
cronScheduler,
|
|
31421
31920
|
dispatchTool
|
|
31422
31921
|
});
|
|
31423
|
-
const appRegistry = createAppRegistry();
|
|
31922
|
+
const appRegistry = createAppRegistry({ persist });
|
|
31923
|
+
const appUiHtmlCache = createUiHtmlCache();
|
|
31424
31924
|
const workflowRunner = opts.resolveAgentAdapter ? createWorkflowRunner({
|
|
31425
31925
|
registry: sessions,
|
|
31426
31926
|
sessionEvents,
|
|
@@ -31541,7 +32041,7 @@ async function createGateway(opts) {
|
|
|
31541
32041
|
...opts.listAgentAdapters ? { listAgentAdapters: opts.listAgentAdapters } : {},
|
|
31542
32042
|
...opts.listHarnessCapabilities ? { listHarnessCapabilities: opts.listHarnessCapabilities } : {}
|
|
31543
32043
|
});
|
|
31544
|
-
const mcpServerFactory = async (denyTools, callerSessionId) => {
|
|
32044
|
+
const mcpServerFactory = async (denyTools, callerSessionId, origin) => {
|
|
31545
32045
|
const { server: rawServer } = await createMcpServer({
|
|
31546
32046
|
specs: opts.specs,
|
|
31547
32047
|
workspace,
|
|
@@ -31560,7 +32060,8 @@ async function createGateway(opts) {
|
|
|
31560
32060
|
resumeSessionsOnBoot: opts.resumeSessionsOnBoot === true,
|
|
31561
32061
|
idleReapAfterMs,
|
|
31562
32062
|
crashDetectIntervalMs,
|
|
31563
|
-
restartSweepIntervalMs
|
|
32063
|
+
restartSweepIntervalMs,
|
|
32064
|
+
turnStallAfterMs
|
|
31564
32065
|
});
|
|
31565
32066
|
registerCommandTools(server, {
|
|
31566
32067
|
workspace,
|
|
@@ -31584,6 +32085,9 @@ async function createGateway(opts) {
|
|
|
31584
32085
|
// a spawn made by an agent session attaches under it by default (see
|
|
31585
32086
|
// spawn-attach.ts). Absent on a human/root `/mcp` call → no auto-parent.
|
|
31586
32087
|
...callerSessionId ? { callerSessionId } : {},
|
|
32088
|
+
// `?origin=` query (#session-visibility) — the connecting client's source
|
|
32089
|
+
// label, used as the default origin for a spawn that doesn't set its own.
|
|
32090
|
+
...origin ? { mcpBridgeOrigin: origin } : {},
|
|
31587
32091
|
webhookNotifier,
|
|
31588
32092
|
daemonMcpUrl,
|
|
31589
32093
|
resolveSandboxProvider: resolveSandboxProviderResolved,
|
|
@@ -31623,6 +32127,16 @@ async function createGateway(opts) {
|
|
|
31623
32127
|
registry: sessions,
|
|
31624
32128
|
listRegisteredToolIds,
|
|
31625
32129
|
appRegistry,
|
|
32130
|
+
dispatchTool,
|
|
32131
|
+
// Same proxy `mcp_imported_call` (session-tools.ts) dispatches
|
|
32132
|
+
// through — unwraps `{ok,result}|{ok:false,error}` into a plain
|
|
32133
|
+
// return-or-throw for `app_tool_call`'s `imported:<alias>/<toolName>`
|
|
32134
|
+
// ids.
|
|
32135
|
+
callImportedTool: async (alias, tool, args) => {
|
|
32136
|
+
const out = await mcpProxy.callTool(alias, tool, args);
|
|
32137
|
+
if (!out.ok) throw new Error(`app_tool_call: imported "${alias}".${tool}: ${out.error}`);
|
|
32138
|
+
return out.result;
|
|
32139
|
+
},
|
|
31626
32140
|
...opts.resolveAgentAdapter ? { resolveAgentAdapter: opts.resolveAgentAdapter } : {},
|
|
31627
32141
|
...workflowRunner ? { workflowRunner } : {}
|
|
31628
32142
|
});
|
|
@@ -31634,7 +32148,7 @@ async function createGateway(opts) {
|
|
|
31634
32148
|
}
|
|
31635
32149
|
return rows;
|
|
31636
32150
|
};
|
|
31637
|
-
|
|
32151
|
+
const builtinPanelApps = [
|
|
31638
32152
|
makeSessionsPanelApp({ listSessions: listSessionsFiltered }),
|
|
31639
32153
|
makeAgentsOverviewApp({ listSessions: listSessionsFiltered }),
|
|
31640
32154
|
makeBureauSessionsApp({ listSessions: listSessionsFiltered }),
|
|
@@ -31684,7 +32198,13 @@ async function createGateway(opts) {
|
|
|
31684
32198
|
}
|
|
31685
32199
|
})
|
|
31686
32200
|
] : []
|
|
31687
|
-
]
|
|
32201
|
+
];
|
|
32202
|
+
const installedAppUiApps = await makeInstalledAppUiApps(
|
|
32203
|
+
appRegistry,
|
|
32204
|
+
appUiHtmlCache,
|
|
32205
|
+
new Set(builtinPanelApps.map((app) => app.id))
|
|
32206
|
+
);
|
|
32207
|
+
registerMcpApps(server, [...builtinPanelApps, ...installedAppUiApps]);
|
|
31688
32208
|
registerSummarizeSessionTool(server, {
|
|
31689
32209
|
getSession: (id) => sessions.get(id),
|
|
31690
32210
|
tailLines: (id, lastN) => {
|
|
@@ -31837,7 +32357,8 @@ async function createGateway(opts) {
|
|
|
31837
32357
|
resumeSessionsOnBoot: opts.resumeSessionsOnBoot === true,
|
|
31838
32358
|
idleReapAfterMs,
|
|
31839
32359
|
crashDetectIntervalMs,
|
|
31840
|
-
restartSweepIntervalMs
|
|
32360
|
+
restartSweepIntervalMs,
|
|
32361
|
+
turnStallAfterMs
|
|
31841
32362
|
},
|
|
31842
32363
|
cronScheduler,
|
|
31843
32364
|
routineRegistrar
|
|
@@ -31882,6 +32403,27 @@ async function createGateway(opts) {
|
|
|
31882
32403
|
}, crashDetectIntervalMs);
|
|
31883
32404
|
crashDetectTimer.unref?.();
|
|
31884
32405
|
}
|
|
32406
|
+
let turnStallTimer = null;
|
|
32407
|
+
if (turnStallAfterMs > 0) {
|
|
32408
|
+
const rawInterval = process.env.AGENTPROTO_TURN_STALL_INTERVAL_MS;
|
|
32409
|
+
const parsedInterval = rawInterval ? Number.parseInt(rawInterval, 10) : NaN;
|
|
32410
|
+
const intervalMs = Number.isFinite(parsedInterval) && parsedInterval > 0 ? parsedInterval : Math.min(turnStallAfterMs, 6e4);
|
|
32411
|
+
turnStallTimer = setInterval(() => {
|
|
32412
|
+
try {
|
|
32413
|
+
const summary = runStallWatchdogPass({ registry: sessions, turnStallAfterMs });
|
|
32414
|
+
if (summary.stalled > 0) {
|
|
32415
|
+
console.log(
|
|
32416
|
+
`[stall-watchdog] flagged ${summary.stalled}/${summary.candidates} stalled agent session(s): ${summary.ids.join(", ")}`
|
|
32417
|
+
);
|
|
32418
|
+
}
|
|
32419
|
+
} catch (err) {
|
|
32420
|
+
console.warn(
|
|
32421
|
+
`[stall-watchdog] sweep failed: ${err instanceof Error ? err.message : String(err)}`
|
|
32422
|
+
);
|
|
32423
|
+
}
|
|
32424
|
+
}, intervalMs);
|
|
32425
|
+
turnStallTimer.unref?.();
|
|
32426
|
+
}
|
|
31885
32427
|
let restartSweepTimer = null;
|
|
31886
32428
|
if (restartSweepIntervalMs > 0) {
|
|
31887
32429
|
restartSweepTimer = setInterval(() => {
|
|
@@ -31942,6 +32484,7 @@ async function createGateway(opts) {
|
|
|
31942
32484
|
heartbeat.stop();
|
|
31943
32485
|
if (idleReapTimer) clearInterval(idleReapTimer);
|
|
31944
32486
|
if (crashDetectTimer) clearInterval(crashDetectTimer);
|
|
32487
|
+
if (turnStallTimer) clearInterval(turnStallTimer);
|
|
31945
32488
|
if (restartSweepTimer) clearInterval(restartSweepTimer);
|
|
31946
32489
|
restartScheduler.dispose();
|
|
31947
32490
|
inboundWatcher?.shutdown();
|
|
@@ -32001,6 +32544,6 @@ var export_providersPath = providers_store_exports.providersPath;
|
|
|
32001
32544
|
var export_removeProviderKey = providers_store_exports.removeProviderKey;
|
|
32002
32545
|
var export_setProviderKey = providers_store_exports.setProviderKey;
|
|
32003
32546
|
|
|
32004
|
-
export { AnthropicRemainingQuotaReader, AuthResolutionError, BUCKETS_ROOT, CLAUDE_CODE_OAUTH_SOURCE, DEFAULT_BUCKET, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, INBOUND_PROVIDERS, LEGACY_SESSIONS_FILE, PAIRINGS_VERSION, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, export_PROVIDER_ENV_VARS as PROVIDER_ENV_VARS, ResumeDisabledError, SESSION_ID_ENV, SubscriptionSourceError, TASK_STATUSES, WORKSPACE_SLUG_ENV, WORKTREE_ISOLATION_ENV, activityCounts, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogModels, buildCatalogProviderModels, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, composeMode, composeSessionObservers, conversationIndexPath, createActivityProjector, createFileStepCache, createGateway, createInboundEndpointStore, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPairingRegistry, createPrProvenanceReconciler, createReconnectLogGate, createScopeTokenRegistry, createSupervisorTaskGateRunner, createTaskLedger, createWorkspaceFs, credentialFingerprint, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, decomposeMode, deleteUserPreset, deriveSessionUsage, enrichRollupWithProviderQuota, enrichWithRemainingQuota, evaluateCostBudget, fileConversationStore, filterActivities, findConversationRecord, findNativeMode, formatToolCall, formatToolResult, getMcpCredentialDeps, export_getProviderKey as getProviderKey, getUserPreset, export_injectProviderKeysIntoEnv as injectProviderKeysIntoEnv, isAgentCliAuthConfigured, isClosedTaskStatus, isSafeBucketSlug, isTerminalActivityState, listBuckets, listPresets, listUserPresets, export_loadProviders as loadProviders, loadQuotaStore, loadUserPresets, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, migrateLegacySessionsFile, migrationMarkerPath, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeInbound, normalizeModeId, normalizeSkillsOption, normalizeWorktreeField, parseAnthropicRateLimitHeaders, parseDuration, parseTaskStatus, parseWindow, parseWorktreeIsolationMode, policyToActivities, policyWatchesSession, prToActivities, projectSessionUsage, export_providerEnvVar as providerEnvVar, export_providersPath as providersPath, readConversationIndex, readDaemonRegistry, readProfileQuota, readRegisteredSlugs, readRuntimeMeta, readUsageSnapshots, reapOrphanedDescendants, recordProfileQuota, registerBuiltinRoutes, registerPairingTools, registerSandboxAttachTool, export_removeProviderKey as removeProviderKey, resolveAuthSpec, resolveBucketSlug, resolveNativeLink, resolvePosture, resolveSpawnDefaults, resolveSubscriptionCredential, rollupUsage, runCrashDetectPass, runEagerResumePass, runIdleReapPass, saveUserPreset, setMcpCredentialDeps, export_setProviderKey as setProviderKey, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, userPresetsPath, verifyInboundSignature, workflowToActivities, writeDaemonRegistryEntry };
|
|
32547
|
+
export { AnthropicRemainingQuotaReader, AuthResolutionError, BUCKETS_ROOT, CLAUDE_CODE_OAUTH_SOURCE, DEFAULT_BUCKET, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, INBOUND_PROVIDERS, LEGACY_SESSIONS_FILE, PAIRINGS_VERSION, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, export_PROVIDER_ENV_VARS as PROVIDER_ENV_VARS, ResumeDisabledError, SESSION_ID_ENV, SubscriptionSourceError, TASK_STATUSES, WORKSPACE_SLUG_ENV, WORKTREE_ISOLATION_ENV, activityCounts, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogModels, buildCatalogProviderModels, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, composeMode, composeSessionObservers, conversationIndexPath, createActivityProjector, createFileStepCache, createGateway, createInboundEndpointStore, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPairingRegistry, createPrProvenanceReconciler, createReconnectLogGate, createScopeTokenRegistry, createSupervisorTaskGateRunner, createTaskLedger, createWorkspaceFs, credentialFingerprint, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, decomposeMode, deleteUserPreset, deriveSessionUsage, enrichRollupWithProviderQuota, enrichWithRemainingQuota, evaluateCostBudget, fileConversationStore, filterActivities, findConversationRecord, findNativeMode, formatToolCall, formatToolResult, getMcpCredentialDeps, export_getProviderKey as getProviderKey, getUserPreset, export_injectProviderKeysIntoEnv as injectProviderKeysIntoEnv, isAgentCliAuthConfigured, isClosedTaskStatus, isSafeBucketSlug, isTerminalActivityState, listBuckets, listPresets, listUserPresets, export_loadProviders as loadProviders, loadQuotaStore, loadUserPresets, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, migrateLegacySessionsFile, migrationMarkerPath, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeInbound, normalizeModeId, normalizeSkillsOption, normalizeWorktreeField, parseAnthropicRateLimitHeaders, parseDuration, parseTaskStatus, parseWindow, parseWorktreeIsolationMode, policyToActivities, policyWatchesSession, prToActivities, projectSessionUsage, export_providerEnvVar as providerEnvVar, export_providersPath as providersPath, readConversationIndex, readDaemonRegistry, readProfileQuota, readRegisteredSlugs, readRuntimeMeta, readUsageSnapshots, reapOrphanedDescendants, recordProfileQuota, registerBuiltinRoutes, registerPairingTools, registerSandboxAttachTool, export_removeProviderKey as removeProviderKey, resolveAuthSpec, resolveBucketSlug, resolveNativeLink, resolvePosture, resolveSpawnDefaults, resolveSubscriptionCredential, rollupUsage, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runStallWatchdogPass, saveUserPreset, setMcpCredentialDeps, export_setProviderKey as setProviderKey, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, userPresetsPath, verifyInboundSignature, workflowToActivities, writeDaemonRegistryEntry };
|
|
32005
32548
|
//# sourceMappingURL=index.mjs.map
|
|
32006
32549
|
//# sourceMappingURL=index.mjs.map
|