@agentproto/runtime 3.1.0 → 3.3.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/dist/credential-discovery.d.ts +161 -0
- package/dist/credential-discovery.mjs +305 -0
- package/dist/credential-discovery.mjs.map +1 -0
- package/dist/index.d.ts +184 -14
- package/dist/index.mjs +655 -182
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -7
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join, resolve, dirname, basename, isAbsolute, normalize, relative, extname, sep, delimiter } from 'path';
|
|
2
|
-
import { createReadStream, promises,
|
|
2
|
+
import { createReadStream, promises, readFileSync, mkdirSync, writeFileSync, renameSync, readdirSync, existsSync, chmodSync, openSync, closeSync, realpathSync, statSync, createWriteStream } from 'fs';
|
|
3
3
|
import { homedir, hostname, tmpdir } from 'os';
|
|
4
4
|
import { createInterface } from 'readline';
|
|
5
5
|
import { timingSafeEqual, createHmac, randomBytes, randomUUID, createHash } from 'crypto';
|
|
@@ -15,7 +15,7 @@ import { resolveCustomRoute, registerCustomRoute, formatModelRef, resolveLlmMode
|
|
|
15
15
|
import { findAnthropicGatewayPreset, anthropicGatewayPresetList, getAnthropicGatewayPreset } from '@agentproto/provider-presets';
|
|
16
16
|
import * as providers_store_star from '@agentproto/providers-store';
|
|
17
17
|
import { makeCredsStore, makeAdapterResolver, makeAdapterLister, discoverAdapterPackages, makeSetupLedger, makeListTool, makeSetupTool } from '@agentproto/provider-kit';
|
|
18
|
-
import { SandboxSpecSchema, resolveLifecyclePolicy, createSandboxAgentSessionHost } from '@agentproto/sandbox';
|
|
18
|
+
import { SandboxSpecSchema, resolveLifecyclePolicy, createSandboxAgentSessionHost, isSandboxBoxGoneError, SandboxHostBootFailedError } from '@agentproto/sandbox';
|
|
19
19
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
20
20
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
21
21
|
import { createServer as createServer$1 } from 'net';
|
|
@@ -25,7 +25,7 @@ import { inferLegacyModeKind, parseModelSwitchCommand, isModelSwitchAcknowledgem
|
|
|
25
25
|
import { loadSandboxConfig, resolveCommandSandbox, COMMAND_SANDBOX_MODE_ENV } from '@agentproto/command-sandbox';
|
|
26
26
|
import { createBrainManager, parseKnowledgeConfig } from '@agentproto/workspace-brain';
|
|
27
27
|
import { defineHttpDriver } from '@agentproto/driver-http';
|
|
28
|
-
import { makeSessionsPanelApp, makeAgentsOverviewApp, makeBureauSessionsApp, makeSessionStoryPanelApp,
|
|
28
|
+
import { liveSessionApp, makeLiveSessionApp, sessionsPanelApp, agentsOverviewApp, bureauSessionsApp, sessionStoryApp, workBoardApp, makeSessionsPanelApp, makeAgentsOverviewApp, makeBureauSessionsApp, makeSessionStoryPanelApp, makeSessionChatApp, makeWorkBoardApp, SESSION_CHAT_APP_ID, sessionChatApp } from '@agentproto/apps';
|
|
29
29
|
import matter2 from 'gray-matter';
|
|
30
30
|
import { createServer } from 'http';
|
|
31
31
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
@@ -2647,6 +2647,135 @@ async function readCommandLogEntry(sessionId, baseDir) {
|
|
|
2647
2647
|
return null;
|
|
2648
2648
|
}
|
|
2649
2649
|
}
|
|
2650
|
+
var sandboxLedgerPath = () => process.env.AGENTPROTO_SANDBOX_LEDGER ?? resolve(homedir(), ".agentproto", "sandboxes.json");
|
|
2651
|
+
var tmpSeq = 0;
|
|
2652
|
+
var serialize = (snapshot) => JSON.stringify(snapshot, null, 2) + "\n";
|
|
2653
|
+
var isLedgerState = (value) => value === "booted" || value === "paused" || value === "connected" || value === "stopped" || value === "gone";
|
|
2654
|
+
var isEntry = (value) => {
|
|
2655
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2656
|
+
if (!("sandboxId" in value) || !("provider" in value) || !("state" in value) || !("createdAt" in value) || !("updatedAt" in value)) {
|
|
2657
|
+
return false;
|
|
2658
|
+
}
|
|
2659
|
+
return typeof value.sandboxId === "string" && value.sandboxId.length > 0 && typeof value.provider === "string" && isLedgerState(value.state) && typeof value.createdAt === "string" && typeof value.updatedAt === "string";
|
|
2660
|
+
};
|
|
2661
|
+
function readSandboxLedger(path) {
|
|
2662
|
+
try {
|
|
2663
|
+
const parsed = JSON.parse(
|
|
2664
|
+
readFileSync(path ?? sandboxLedgerPath(), "utf8")
|
|
2665
|
+
);
|
|
2666
|
+
if (!Array.isArray(parsed.sandboxes)) return [];
|
|
2667
|
+
return parsed.sandboxes.filter(isEntry);
|
|
2668
|
+
} catch {
|
|
2669
|
+
return [];
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
function upsertSandboxLedger(entry, path) {
|
|
2673
|
+
try {
|
|
2674
|
+
const target = path ?? sandboxLedgerPath();
|
|
2675
|
+
const dir = join(target, "..");
|
|
2676
|
+
mkdirSync(dir, { recursive: true });
|
|
2677
|
+
const existing = readSandboxLedger(target);
|
|
2678
|
+
const merged = [entry, ...existing.filter((e) => e.sandboxId !== entry.sandboxId)];
|
|
2679
|
+
const snapshot = {
|
|
2680
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2681
|
+
sandboxes: merged
|
|
2682
|
+
};
|
|
2683
|
+
const tmp = `${target}.tmp.${process.pid}.${++tmpSeq}`;
|
|
2684
|
+
writeFileSync(tmp, serialize(snapshot), "utf8");
|
|
2685
|
+
renameSync(tmp, target);
|
|
2686
|
+
} catch {
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
function removeSandboxLedgerEntry(sandboxId, path) {
|
|
2690
|
+
try {
|
|
2691
|
+
const target = path ?? sandboxLedgerPath();
|
|
2692
|
+
const existing = readSandboxLedger(target);
|
|
2693
|
+
if (!existing.some((e) => e.sandboxId === sandboxId)) return false;
|
|
2694
|
+
const snapshot = {
|
|
2695
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2696
|
+
sandboxes: existing.filter((e) => e.sandboxId !== sandboxId)
|
|
2697
|
+
};
|
|
2698
|
+
const tmp = `${target}.tmp.${process.pid}.${++tmpSeq}`;
|
|
2699
|
+
writeFileSync(tmp, serialize(snapshot), "utf8");
|
|
2700
|
+
renameSync(tmp, target);
|
|
2701
|
+
return true;
|
|
2702
|
+
} catch {
|
|
2703
|
+
return false;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
var nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
2707
|
+
function recordSandboxBoot(opts) {
|
|
2708
|
+
try {
|
|
2709
|
+
const target = opts.path ?? sandboxLedgerPath();
|
|
2710
|
+
const existing = readSandboxLedger(target);
|
|
2711
|
+
const prior = existing.find((e) => e.sandboxId === opts.sandboxId);
|
|
2712
|
+
const ts = nowIso();
|
|
2713
|
+
const entry = {
|
|
2714
|
+
sandboxId: opts.sandboxId,
|
|
2715
|
+
provider: opts.provider,
|
|
2716
|
+
state: opts.state,
|
|
2717
|
+
createdAt: prior?.createdAt ?? ts,
|
|
2718
|
+
updatedAt: ts,
|
|
2719
|
+
...opts.label ? { label: opts.label } : prior?.label ? { label: prior.label } : {},
|
|
2720
|
+
...opts.cwd ? { cwd: opts.cwd } : prior?.cwd ? { cwd: prior.cwd } : {},
|
|
2721
|
+
...opts.originSessionId ? { originSessionId: opts.originSessionId } : prior?.originSessionId ? { originSessionId: prior.originSessionId } : {},
|
|
2722
|
+
...opts.expiresAt ? { expiresAt: opts.expiresAt } : {}
|
|
2723
|
+
};
|
|
2724
|
+
upsertSandboxLedger(entry, target);
|
|
2725
|
+
} catch {
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
function recordSandboxState(sandboxId, state, path) {
|
|
2729
|
+
try {
|
|
2730
|
+
const target = path ?? sandboxLedgerPath();
|
|
2731
|
+
const prior = readSandboxLedger(target).find((e) => e.sandboxId === sandboxId);
|
|
2732
|
+
if (!prior) return;
|
|
2733
|
+
upsertSandboxLedger(
|
|
2734
|
+
{ ...prior, state, updatedAt: nowIso() },
|
|
2735
|
+
target
|
|
2736
|
+
);
|
|
2737
|
+
} catch {
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
function recordSandboxLiveness(sandboxId, alive, path) {
|
|
2741
|
+
try {
|
|
2742
|
+
const target = path ?? sandboxLedgerPath();
|
|
2743
|
+
const prior = readSandboxLedger(target).find((e) => e.sandboxId === sandboxId);
|
|
2744
|
+
if (!prior) return;
|
|
2745
|
+
upsertSandboxLedger(
|
|
2746
|
+
{
|
|
2747
|
+
...prior,
|
|
2748
|
+
...alive ? {} : { state: "gone" },
|
|
2749
|
+
sandboxAlive: alive,
|
|
2750
|
+
sandboxCheckedAt: nowIso(),
|
|
2751
|
+
updatedAt: nowIso()
|
|
2752
|
+
},
|
|
2753
|
+
target
|
|
2754
|
+
);
|
|
2755
|
+
} catch {
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
function recordSandboxOrigin(sandboxId, originSessionId, path) {
|
|
2759
|
+
try {
|
|
2760
|
+
const target = path ?? sandboxLedgerPath();
|
|
2761
|
+
const prior = readSandboxLedger(target).find((e) => e.sandboxId === sandboxId);
|
|
2762
|
+
if (!prior) return;
|
|
2763
|
+
upsertSandboxLedger(
|
|
2764
|
+
{ ...prior, originSessionId, updatedAt: nowIso() },
|
|
2765
|
+
target
|
|
2766
|
+
);
|
|
2767
|
+
} catch {
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
function resolveReuseFromLedger(reuse, entries) {
|
|
2771
|
+
const matches = entries.filter(
|
|
2772
|
+
(e) => e.label === reuse || e.sandboxId.startsWith(reuse)
|
|
2773
|
+
);
|
|
2774
|
+
const sole = matches.length === 1 ? matches[0] : void 0;
|
|
2775
|
+
if (sole) return { kind: "resolved", sandboxId: sole.sandboxId, entry: sole };
|
|
2776
|
+
if (matches.length > 1) return { kind: "ambiguous", candidates: matches };
|
|
2777
|
+
return { kind: "unresolved" };
|
|
2778
|
+
}
|
|
2650
2779
|
|
|
2651
2780
|
// src/tool-call-log.ts
|
|
2652
2781
|
init_transcript_writer();
|
|
@@ -4997,15 +5126,15 @@ function listBuckets(root) {
|
|
|
4997
5126
|
return [];
|
|
4998
5127
|
}
|
|
4999
5128
|
}
|
|
5000
|
-
var
|
|
5001
|
-
var
|
|
5002
|
-
var tmpPathFor = (target) => `${target}.tmp.${process.pid}.${++
|
|
5129
|
+
var serialize2 = (snapshot) => JSON.stringify(snapshot, null, 2) + "\n";
|
|
5130
|
+
var tmpSeq2 = 0;
|
|
5131
|
+
var tmpPathFor = (target) => `${target}.tmp.${process.pid}.${++tmpSeq2}`;
|
|
5003
5132
|
async function writeBucketSnapshot(root, slug, snapshot) {
|
|
5004
5133
|
const dir = bucketDir(root, slug);
|
|
5005
5134
|
await promises.mkdir(dir, { recursive: true });
|
|
5006
5135
|
const target = bucketSessionsFile(root, slug);
|
|
5007
5136
|
const tmp = tmpPathFor(target);
|
|
5008
|
-
await promises.writeFile(tmp,
|
|
5137
|
+
await promises.writeFile(tmp, serialize2(snapshot), "utf8");
|
|
5009
5138
|
await promises.rename(tmp, target);
|
|
5010
5139
|
}
|
|
5011
5140
|
function writeBucketSnapshotSync(root, slug, snapshot) {
|
|
@@ -5013,7 +5142,7 @@ function writeBucketSnapshotSync(root, slug, snapshot) {
|
|
|
5013
5142
|
mkdirSync(dir, { recursive: true });
|
|
5014
5143
|
const target = bucketSessionsFile(root, slug);
|
|
5015
5144
|
const tmp = tmpPathFor(target);
|
|
5016
|
-
writeFileSync(tmp,
|
|
5145
|
+
writeFileSync(tmp, serialize2(snapshot), "utf8");
|
|
5017
5146
|
renameSync(tmp, target);
|
|
5018
5147
|
}
|
|
5019
5148
|
function migrateLegacySessionsFile(opts) {
|
|
@@ -5181,117 +5310,6 @@ function setMcpCredentialDeps(d) {
|
|
|
5181
5310
|
function getMcpCredentialDeps() {
|
|
5182
5311
|
return deps;
|
|
5183
5312
|
}
|
|
5184
|
-
var sandboxLedgerPath = () => process.env.AGENTPROTO_SANDBOX_LEDGER ?? resolve(homedir(), ".agentproto", "sandboxes.json");
|
|
5185
|
-
var tmpSeq2 = 0;
|
|
5186
|
-
var serialize2 = (snapshot) => JSON.stringify(snapshot, null, 2) + "\n";
|
|
5187
|
-
var isLedgerState = (value) => value === "booted" || value === "paused" || value === "connected" || value === "stopped";
|
|
5188
|
-
var isEntry = (value) => {
|
|
5189
|
-
if (typeof value !== "object" || value === null) return false;
|
|
5190
|
-
if (!("sandboxId" in value) || !("provider" in value) || !("state" in value) || !("createdAt" in value) || !("updatedAt" in value)) {
|
|
5191
|
-
return false;
|
|
5192
|
-
}
|
|
5193
|
-
return typeof value.sandboxId === "string" && value.sandboxId.length > 0 && typeof value.provider === "string" && isLedgerState(value.state) && typeof value.createdAt === "string" && typeof value.updatedAt === "string";
|
|
5194
|
-
};
|
|
5195
|
-
function readSandboxLedger(path) {
|
|
5196
|
-
try {
|
|
5197
|
-
const parsed = JSON.parse(
|
|
5198
|
-
readFileSync(path ?? sandboxLedgerPath(), "utf8")
|
|
5199
|
-
);
|
|
5200
|
-
if (!Array.isArray(parsed.sandboxes)) return [];
|
|
5201
|
-
return parsed.sandboxes.filter(isEntry);
|
|
5202
|
-
} catch {
|
|
5203
|
-
return [];
|
|
5204
|
-
}
|
|
5205
|
-
}
|
|
5206
|
-
function upsertSandboxLedger(entry, path) {
|
|
5207
|
-
try {
|
|
5208
|
-
const target = path ?? sandboxLedgerPath();
|
|
5209
|
-
const dir = join(target, "..");
|
|
5210
|
-
mkdirSync(dir, { recursive: true });
|
|
5211
|
-
const existing = readSandboxLedger(target);
|
|
5212
|
-
const merged = [entry, ...existing.filter((e) => e.sandboxId !== entry.sandboxId)];
|
|
5213
|
-
const snapshot = {
|
|
5214
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5215
|
-
sandboxes: merged
|
|
5216
|
-
};
|
|
5217
|
-
const tmp = `${target}.tmp.${process.pid}.${++tmpSeq2}`;
|
|
5218
|
-
writeFileSync(tmp, serialize2(snapshot), "utf8");
|
|
5219
|
-
renameSync(tmp, target);
|
|
5220
|
-
} catch {
|
|
5221
|
-
}
|
|
5222
|
-
}
|
|
5223
|
-
function removeSandboxLedgerEntry(sandboxId, path) {
|
|
5224
|
-
try {
|
|
5225
|
-
const target = path ?? sandboxLedgerPath();
|
|
5226
|
-
const existing = readSandboxLedger(target);
|
|
5227
|
-
if (!existing.some((e) => e.sandboxId === sandboxId)) return false;
|
|
5228
|
-
const snapshot = {
|
|
5229
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5230
|
-
sandboxes: existing.filter((e) => e.sandboxId !== sandboxId)
|
|
5231
|
-
};
|
|
5232
|
-
const tmp = `${target}.tmp.${process.pid}.${++tmpSeq2}`;
|
|
5233
|
-
writeFileSync(tmp, serialize2(snapshot), "utf8");
|
|
5234
|
-
renameSync(tmp, target);
|
|
5235
|
-
return true;
|
|
5236
|
-
} catch {
|
|
5237
|
-
return false;
|
|
5238
|
-
}
|
|
5239
|
-
}
|
|
5240
|
-
var nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
5241
|
-
function recordSandboxBoot(opts) {
|
|
5242
|
-
try {
|
|
5243
|
-
const target = opts.path ?? sandboxLedgerPath();
|
|
5244
|
-
const existing = readSandboxLedger(target);
|
|
5245
|
-
const prior = existing.find((e) => e.sandboxId === opts.sandboxId);
|
|
5246
|
-
const ts = nowIso();
|
|
5247
|
-
const entry = {
|
|
5248
|
-
sandboxId: opts.sandboxId,
|
|
5249
|
-
provider: opts.provider,
|
|
5250
|
-
state: opts.state,
|
|
5251
|
-
createdAt: prior?.createdAt ?? ts,
|
|
5252
|
-
updatedAt: ts,
|
|
5253
|
-
...opts.label ? { label: opts.label } : prior?.label ? { label: prior.label } : {},
|
|
5254
|
-
...opts.cwd ? { cwd: opts.cwd } : prior?.cwd ? { cwd: prior.cwd } : {},
|
|
5255
|
-
...opts.originSessionId ? { originSessionId: opts.originSessionId } : prior?.originSessionId ? { originSessionId: prior.originSessionId } : {},
|
|
5256
|
-
...opts.expiresAt ? { expiresAt: opts.expiresAt } : {}
|
|
5257
|
-
};
|
|
5258
|
-
upsertSandboxLedger(entry, target);
|
|
5259
|
-
} catch {
|
|
5260
|
-
}
|
|
5261
|
-
}
|
|
5262
|
-
function recordSandboxState(sandboxId, state, path) {
|
|
5263
|
-
try {
|
|
5264
|
-
const target = path ?? sandboxLedgerPath();
|
|
5265
|
-
const prior = readSandboxLedger(target).find((e) => e.sandboxId === sandboxId);
|
|
5266
|
-
if (!prior) return;
|
|
5267
|
-
upsertSandboxLedger(
|
|
5268
|
-
{ ...prior, state, updatedAt: nowIso() },
|
|
5269
|
-
target
|
|
5270
|
-
);
|
|
5271
|
-
} catch {
|
|
5272
|
-
}
|
|
5273
|
-
}
|
|
5274
|
-
function recordSandboxOrigin(sandboxId, originSessionId, path) {
|
|
5275
|
-
try {
|
|
5276
|
-
const target = path ?? sandboxLedgerPath();
|
|
5277
|
-
const prior = readSandboxLedger(target).find((e) => e.sandboxId === sandboxId);
|
|
5278
|
-
if (!prior) return;
|
|
5279
|
-
upsertSandboxLedger(
|
|
5280
|
-
{ ...prior, originSessionId, updatedAt: nowIso() },
|
|
5281
|
-
target
|
|
5282
|
-
);
|
|
5283
|
-
} catch {
|
|
5284
|
-
}
|
|
5285
|
-
}
|
|
5286
|
-
function resolveReuseFromLedger(reuse, entries) {
|
|
5287
|
-
const matches = entries.filter(
|
|
5288
|
-
(e) => e.label === reuse || e.sandboxId.startsWith(reuse)
|
|
5289
|
-
);
|
|
5290
|
-
const sole = matches.length === 1 ? matches[0] : void 0;
|
|
5291
|
-
if (sole) return { kind: "resolved", sandboxId: sole.sandboxId, entry: sole };
|
|
5292
|
-
if (matches.length > 1) return { kind: "ambiguous", candidates: matches };
|
|
5293
|
-
return { kind: "unresolved" };
|
|
5294
|
-
}
|
|
5295
5313
|
|
|
5296
5314
|
// src/sandbox-agent-session-proxy.ts
|
|
5297
5315
|
var MAX_POLL_MS = 49e3;
|
|
@@ -5648,6 +5666,24 @@ async function installApp(client, dir) {
|
|
|
5648
5666
|
}
|
|
5649
5667
|
return appId;
|
|
5650
5668
|
}
|
|
5669
|
+
function serveLogPath(dir) {
|
|
5670
|
+
return `${dir.replace(/\/+$/, "")}/.agentproto/app-serve.log`;
|
|
5671
|
+
}
|
|
5672
|
+
function extractServeError(logText) {
|
|
5673
|
+
const lines = logText.split("\n").map((l) => l.trimEnd()).filter((l) => l.includes("agentproto app serve:") && !l.includes("serving "));
|
|
5674
|
+
if (lines.length === 0) return void 0;
|
|
5675
|
+
return lines[lines.length - 1];
|
|
5676
|
+
}
|
|
5677
|
+
async function readServeError(client, dir) {
|
|
5678
|
+
try {
|
|
5679
|
+
const res = await client.callTool("file_read", { path: serveLogPath(dir) });
|
|
5680
|
+
const text10 = firstText(res);
|
|
5681
|
+
if (text10 === void 0) return void 0;
|
|
5682
|
+
return extractServeError(text10);
|
|
5683
|
+
} catch {
|
|
5684
|
+
return void 0;
|
|
5685
|
+
}
|
|
5686
|
+
}
|
|
5651
5687
|
async function launchServeProcess(client, dir, port) {
|
|
5652
5688
|
const script = buildServeLaunchScript(dir, port);
|
|
5653
5689
|
const res = await client.callTool("command_execute", {
|
|
@@ -5703,9 +5739,13 @@ async function startSandboxAppServe(host, req, opts) {
|
|
|
5703
5739
|
...opts?.timeoutMs !== void 0 ? { timeoutMs: opts.timeoutMs } : {},
|
|
5704
5740
|
...opts?.intervalMs !== void 0 ? { intervalMs: opts.intervalMs } : {}
|
|
5705
5741
|
});
|
|
5742
|
+
let message;
|
|
5743
|
+
if (!ready) {
|
|
5744
|
+
message = await readServeError(client, req.dir);
|
|
5745
|
+
}
|
|
5706
5746
|
return {
|
|
5707
5747
|
ok: true,
|
|
5708
|
-
appServe: { appId, dir: req.dir, port, url, ready }
|
|
5748
|
+
appServe: { appId, dir: req.dir, port, url, ready, ...message !== void 0 ? { message } : {} }
|
|
5709
5749
|
};
|
|
5710
5750
|
} catch (err) {
|
|
5711
5751
|
return {
|
|
@@ -6452,6 +6492,12 @@ function gcSpawnClaims(claims, now) {
|
|
|
6452
6492
|
resolved.sort((a, b) => a[1].resolvedAt - b[1].resolvedAt);
|
|
6453
6493
|
for (const [k] of resolved.slice(0, excess)) claims.delete(k);
|
|
6454
6494
|
}
|
|
6495
|
+
function findWorktreeLabelCwdCollision(registry, excludeId, label, cwd) {
|
|
6496
|
+
if (!label) return void 0;
|
|
6497
|
+
return registry.list().find(
|
|
6498
|
+
(s) => s.id !== excludeId && s.label === label && s.cwd === cwd && (s.status === "running" || s.status === "starting")
|
|
6499
|
+
);
|
|
6500
|
+
}
|
|
6455
6501
|
function profileMethodToAuthMode(method) {
|
|
6456
6502
|
return method === "oauth-bearer" ? "subscription" : "api-key";
|
|
6457
6503
|
}
|
|
@@ -6844,6 +6890,9 @@ async function spawnAgentSession(deps2, input) {
|
|
|
6844
6890
|
};
|
|
6845
6891
|
}
|
|
6846
6892
|
worktreeRequest = decision.request;
|
|
6893
|
+
if (worktreeRequest.async === void 0) {
|
|
6894
|
+
worktreeRequest = { ...worktreeRequest, async: !input.wait };
|
|
6895
|
+
}
|
|
6847
6896
|
worktreeAutoProvisioned = decision.implicit;
|
|
6848
6897
|
}
|
|
6849
6898
|
}
|
|
@@ -7347,6 +7396,16 @@ async function spawnAgentSession(deps2, input) {
|
|
|
7347
7396
|
return;
|
|
7348
7397
|
}
|
|
7349
7398
|
const finalCwd = outcome.isolated ? outcome.cwd : baseCwd;
|
|
7399
|
+
if (outcome.isolated) {
|
|
7400
|
+
const dupe = findWorktreeLabelCwdCollision(registry, pendingDesc.id, input.label, finalCwd);
|
|
7401
|
+
if (dupe) {
|
|
7402
|
+
registry.settlePendingAgent(pendingDesc.id, {
|
|
7403
|
+
ok: false,
|
|
7404
|
+
message: `agent_start: refused \u2014 another LIVE session ("${dupe.id}") already has the same label ("${input.label}") and cwd ("${finalCwd}") as this worktree spawn. Not starting a second agent in the same worktree.`
|
|
7405
|
+
});
|
|
7406
|
+
return;
|
|
7407
|
+
}
|
|
7408
|
+
}
|
|
7350
7409
|
try {
|
|
7351
7410
|
const agentSession2 = await resolved.startSession({
|
|
7352
7411
|
cwd: finalCwd,
|
|
@@ -7382,16 +7441,6 @@ ${asyncPrompt}`;
|
|
|
7382
7441
|
}
|
|
7383
7442
|
const commandPreview2 = resolved.commandPreview;
|
|
7384
7443
|
const readUsage2 = resolved.readUsage ? () => resolved.readUsage(agentSession2.sessionId) : void 0;
|
|
7385
|
-
if (pendingDesc.label) {
|
|
7386
|
-
const dupe = registry.list().find(
|
|
7387
|
-
(s) => s.id !== pendingDesc.id && s.label === pendingDesc.label && s.cwd === finalCwd && (s.status === "running" || s.status === "starting")
|
|
7388
|
-
);
|
|
7389
|
-
if (dupe) {
|
|
7390
|
-
console.warn(
|
|
7391
|
-
`[agent_start] another LIVE session ("${dupe.id}") already has the same label ("${pendingDesc.label}") and cwd ("${finalCwd}") as this one. If this is a retried spawn rather than a deliberate parallel run, both are now editing the same working directory concurrently \u2014 check before proceeding.`
|
|
7392
|
-
);
|
|
7393
|
-
}
|
|
7394
|
-
}
|
|
7395
7444
|
registry.settlePendingAgent(pendingDesc.id, {
|
|
7396
7445
|
ok: true,
|
|
7397
7446
|
agentSession: agentSession2,
|
|
@@ -7428,13 +7477,26 @@ ${asyncPrompt}`;
|
|
|
7428
7477
|
message: `agent_start: worktree provisioning failed \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
7429
7478
|
});
|
|
7430
7479
|
}
|
|
7431
|
-
if (outcome.isolated)
|
|
7480
|
+
if (outcome.isolated) {
|
|
7481
|
+
cwd = outcome.cwd;
|
|
7482
|
+
const dupe = findWorktreeLabelCwdCollision(registry, mintedSessionId, input.label, cwd);
|
|
7483
|
+
if (dupe) {
|
|
7484
|
+
return finish({
|
|
7485
|
+
ok: true,
|
|
7486
|
+
descriptor: dupe,
|
|
7487
|
+
deduped: true,
|
|
7488
|
+
dedupeSource: "worktree-cwd",
|
|
7489
|
+
...spawnWarnings.length ? { warnings: spawnWarnings } : {}
|
|
7490
|
+
});
|
|
7491
|
+
}
|
|
7492
|
+
}
|
|
7432
7493
|
}
|
|
7433
7494
|
let liveSessionId;
|
|
7434
7495
|
let agentSession;
|
|
7435
7496
|
let commandPreview;
|
|
7436
7497
|
let readUsage;
|
|
7437
7498
|
let sandboxId;
|
|
7499
|
+
let sandboxProvider;
|
|
7438
7500
|
let sandboxTeardown;
|
|
7439
7501
|
let sandboxPorts;
|
|
7440
7502
|
let appServe;
|
|
@@ -7471,6 +7533,7 @@ ${asyncPrompt}`;
|
|
|
7471
7533
|
agentSession = booted.agentSession;
|
|
7472
7534
|
commandPreview = booted.commandPreview;
|
|
7473
7535
|
sandboxId = booted.sandboxId;
|
|
7536
|
+
sandboxProvider = booted.provider;
|
|
7474
7537
|
sandboxTeardown = booted.sandboxTeardown;
|
|
7475
7538
|
sandboxPorts = booted.sandboxPorts;
|
|
7476
7539
|
appServe = booted.appServe;
|
|
@@ -7635,6 +7698,7 @@ ${effectivePrompt}`;
|
|
|
7635
7698
|
}
|
|
7636
7699
|
} : {},
|
|
7637
7700
|
...sandboxId ? { remote: true, sandboxId } : {},
|
|
7701
|
+
...sandboxProvider ? { sandboxProvider } : {},
|
|
7638
7702
|
...sandboxTeardown ? { sandboxTeardown } : {},
|
|
7639
7703
|
...sandboxPorts ? { sandboxPorts } : {},
|
|
7640
7704
|
...appServe ? { appServe } : {},
|
|
@@ -7864,6 +7928,18 @@ async function bootSandboxAgentSession(opts) {
|
|
|
7864
7928
|
secrets: { slugs, resolver: resolveSandboxSecret }
|
|
7865
7929
|
});
|
|
7866
7930
|
} catch (err) {
|
|
7931
|
+
if (reuseSandboxId !== void 0 && isSandboxBoxGoneError(err)) {
|
|
7932
|
+
recordSandboxLiveness(reuseSandboxId, false);
|
|
7933
|
+
}
|
|
7934
|
+
if (err instanceof SandboxHostBootFailedError) {
|
|
7935
|
+
markFailedBootLedger({
|
|
7936
|
+
sandboxId: err.sandboxId,
|
|
7937
|
+
provider: providerSlug,
|
|
7938
|
+
state: err.cleanedUp,
|
|
7939
|
+
...opts.label ? { label: opts.label } : {},
|
|
7940
|
+
...opts.cwd ? { cwd: opts.cwd } : {}
|
|
7941
|
+
});
|
|
7942
|
+
}
|
|
7867
7943
|
return reuseSandboxId !== void 0 ? {
|
|
7868
7944
|
ok: false,
|
|
7869
7945
|
code: "sandbox_reconnect_failed",
|
|
@@ -7897,6 +7973,7 @@ async function bootSandboxAgentSession(opts) {
|
|
|
7897
7973
|
remoteSessionId = remoteDesc.id;
|
|
7898
7974
|
} catch (err) {
|
|
7899
7975
|
await host.stop().catch(() => void 0);
|
|
7976
|
+
recordSandboxState(host.sandboxId, "stopped");
|
|
7900
7977
|
return {
|
|
7901
7978
|
ok: false,
|
|
7902
7979
|
code: "sandbox_proxy_failed",
|
|
@@ -7908,6 +7985,7 @@ async function bootSandboxAgentSession(opts) {
|
|
|
7908
7985
|
const serve = await startSandboxAppServe(host, opts.appServe);
|
|
7909
7986
|
if (!serve.ok) {
|
|
7910
7987
|
await host.stop().catch(() => void 0);
|
|
7988
|
+
recordSandboxState(host.sandboxId, "stopped");
|
|
7911
7989
|
return {
|
|
7912
7990
|
ok: false,
|
|
7913
7991
|
code: "sandbox_app_serve_failed",
|
|
@@ -7926,6 +8004,7 @@ async function bootSandboxAgentSession(opts) {
|
|
|
7926
8004
|
}),
|
|
7927
8005
|
commandPreview: `sandbox:${providerSlug} \u2192 ${opts.adapter}`,
|
|
7928
8006
|
sandboxId: host.sandboxId,
|
|
8007
|
+
provider: providerSlug,
|
|
7929
8008
|
sandboxTeardown: lifecyclePolicy.teardown,
|
|
7930
8009
|
...host.ports && Object.keys(host.ports).length > 0 ? { sandboxPorts: host.ports } : {},
|
|
7931
8010
|
...appServe ? { appServe } : {},
|
|
@@ -7955,6 +8034,27 @@ function sandboxAuthFromResolved(auth) {
|
|
|
7955
8034
|
...auth.mode === "api-key" ? auth.credential !== void 0 ? { apiKey: auth.credential } : {} : auth.credential !== void 0 ? { token: auth.credential } : {}
|
|
7956
8035
|
};
|
|
7957
8036
|
}
|
|
8037
|
+
function markFailedBootLedger(opts) {
|
|
8038
|
+
try {
|
|
8039
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
8040
|
+
const prior = readSandboxLedger().find((e) => e.sandboxId === opts.sandboxId);
|
|
8041
|
+
if (prior) {
|
|
8042
|
+
recordSandboxState(opts.sandboxId, opts.state);
|
|
8043
|
+
return;
|
|
8044
|
+
}
|
|
8045
|
+
const entry = {
|
|
8046
|
+
sandboxId: opts.sandboxId,
|
|
8047
|
+
provider: opts.provider,
|
|
8048
|
+
state: opts.state,
|
|
8049
|
+
createdAt: ts,
|
|
8050
|
+
updatedAt: ts,
|
|
8051
|
+
...opts.label ? { label: opts.label } : {},
|
|
8052
|
+
...opts.cwd ? { cwd: opts.cwd } : {}
|
|
8053
|
+
};
|
|
8054
|
+
upsertSandboxLedger(entry);
|
|
8055
|
+
} catch {
|
|
8056
|
+
}
|
|
8057
|
+
}
|
|
7958
8058
|
async function resolveSandboxSecret(slug) {
|
|
7959
8059
|
const { resolveSandboxSecret: resolve31 } = getMcpCredentialDeps();
|
|
7960
8060
|
if (!resolve31) return null;
|
|
@@ -8201,7 +8301,7 @@ function registerAgentTools(server, opts) {
|
|
|
8201
8301
|
"Caller-declared 'this is the same logical spawn' token \u2014 a PROMISE, not a guess. A retried agent_start call (e.g. after a slow/lost response) that repeats the same `idempotencyKey` for the same `adapter`+`cwd` within ~10min of a successful spawn gets that SAME session's descriptor back instead of forking a second process \u2014 the response carries `deduped: true` and `dedupeSource: \"explicit\"` so you can tell. Always wins over the daemon's own derived key (see `dedupe` below) when both would apply. Omitting this does NOT mean 'spawn unconditionally' \u2014 see `dedupe`."
|
|
8202
8302
|
),
|
|
8203
8303
|
dedupe: mcpBool.optional().describe(
|
|
8204
|
-
'Per-call override for the daemon\'s `spawn.dedupe` policy \u2014 what happens when NO `idempotencyKey` is supplied. By DEFAULT (`spawn.dedupe: "always"`) a spawn that carries a `label` gets an IMPLICIT key derived from that label plus a hash of `prompt`, and dedupes against it exactly like an explicit key \u2014 set `dedupeSource: "implicit"` on the response (alongside `deduped: true`) so you can tell it wasn\'t your own promise that matched. A spawn with no `label` is never touched by this \u2014 deliberate parallel fan-out into one cwd (a real, exercised pattern here) needs no label and stays exactly as many sessions as you asked for. Pass `dedupe: false` to opt this ONE spawn out of implicit derivation regardless of policy \u2014 the escape hatch, mirroring `attach: false` / `worktree: false`. `dedupe: true` forces derivation even under an `"on-request"` daemon policy, mirroring `attach: true`.'
|
|
8304
|
+
'Per-call override for the daemon\'s `spawn.dedupe` policy \u2014 what happens when NO `idempotencyKey` is supplied. By DEFAULT (`spawn.dedupe: "always"`) a spawn that carries a `label` gets an IMPLICIT key derived from that label plus a hash of `prompt`, and dedupes against it exactly like an explicit key \u2014 set `dedupeSource: "implicit"` on the response (alongside `deduped: true`) so you can tell it wasn\'t your own promise that matched. A spawn with no `label` is never touched by this \u2014 deliberate parallel fan-out into one cwd (a real, exercised pattern here) needs no label and stays exactly as many sessions as you asked for. Pass `dedupe: false` to opt this ONE spawn out of implicit derivation regardless of policy \u2014 the escape hatch, mirroring `attach: false` / `worktree: false`. `dedupe: true` forces derivation even under an `"on-request"` daemon policy, mirroring `attach: true`. Unrelated and NOT covered by this flag: a `worktree` spawn that lands in a worktree another LIVE session already occupies under the same `label` is always refused (`dedupeSource: "worktree-cwd"`) \u2014 a shared worktree, unlike a shared plain cwd, is never a legitimate fan-out.'
|
|
8205
8305
|
),
|
|
8206
8306
|
permissionHold: mcpBool.optional().describe(
|
|
8207
8307
|
"Start the session in permission-hold mode: every ACP permission request the agent raises (Write, Bash, \u2026) is SURFACED and HELD in the cross-session inbox (`permissions_list` / `permissions_respond`) instead of auto-answered, and the agent blocks until a human/orchestrator approves or denies it. Default false = today's auto-answer behaviour. ACP adapters only; others ignore it."
|
|
@@ -8381,7 +8481,7 @@ function registerAgentTools(server, opts) {
|
|
|
8381
8481
|
),
|
|
8382
8482
|
base: z.string().min(1).optional().describe("Git ref the worktree branch is cut from. Default 'origin/main'."),
|
|
8383
8483
|
async: z.boolean().optional().describe(
|
|
8384
|
-
'Return a real, registered session as soon as it\'s minted (status "starting") instead of blocking `agent_start`\'s response on `git worktree add` + the repo\'s setup hooks, which can run minutes. Provisioning + the driver spawn continue in the background; poll the session\'s `status` (flips to "running" on success, "error" with a readable `lastError` on failure \u2014 it never sits in "starting" forever). Any `prompt` is held and dispatched only once the tree and the driver session both exist. Incompatible with `wait` (there is no first-turn output to block on yet) \u2014 combining the two is rejected.
|
|
8484
|
+
'Return a real, registered session as soon as it\'s minted (status "starting") instead of blocking `agent_start`\'s response on `git worktree add` + the repo\'s setup hooks, which can run minutes. Provisioning + the driver spawn continue in the background; poll the session\'s `status` (flips to "running" on success, "error" with a readable `lastError` on failure \u2014 it never sits in "starting" forever). Any `prompt` is held and dispatched only once the tree and the driver session both exist. Incompatible with `wait` (there is no first-turn output to block on yet) \u2014 combining the two is rejected. Defaults to true for any spawn that provisions a worktree, UNLESS this call also sets `wait` (which falls back to the old synchronous path instead of conflicting). Pass `false` explicitly to force the old blocking ok/fail contract even without `wait`.'
|
|
8385
8485
|
)
|
|
8386
8486
|
}).strict()
|
|
8387
8487
|
])
|
|
@@ -8503,13 +8603,16 @@ function registerAgentTools(server, opts) {
|
|
|
8503
8603
|
);
|
|
8504
8604
|
server.tool(
|
|
8505
8605
|
"agent_prompt",
|
|
8506
|
-
"Send a follow-up prompt to a live agent session \u2014 multi-turn continuity without re-spawning. The session id comes from `agent_start` (or `agent_sessions_list`). Returns immediately; tail output via `agent_output` or the SSE /sessions/:id/stream endpoint.
|
|
8606
|
+
"Send a follow-up prompt to a live agent session \u2014 multi-turn continuity without re-spawning. The session id comes from `agent_start` (or `agent_sessions_list`). Returns immediately; tail output via `agent_output` or the SSE /sessions/:id/stream endpoint. If the session is mid-turn, the prompt is queued (FIFO) and dispatched automatically when the current turn ends \u2014 so fan-in bursts are delivered in order instead of rejected. Pass `interrupt: true` to cancel the in-flight turn and redirect the SAME session onto this prompt instead, without losing its context (unlike `agent_kill`, which ends the session entirely). `interrupt` is a no-op on an already-idle session.",
|
|
8507
8607
|
{
|
|
8508
8608
|
sessionId: sessionIdField,
|
|
8509
8609
|
id: sessionIdAliasField,
|
|
8510
8610
|
prompt: z.string().min(1).describe("The next user turn (plain text)."),
|
|
8511
8611
|
interrupt: z.boolean().optional().describe(
|
|
8512
8612
|
"When true and the session is mid-turn, cancel the in-flight turn and deliver this prompt on the same session instead of rejecting. No-op when the session is already idle. Default false (mid-turn rejects, as today)."
|
|
8613
|
+
),
|
|
8614
|
+
queue: z.boolean().optional().describe(
|
|
8615
|
+
"When the session is mid-turn, queue this prompt (FIFO) and dispatch it automatically once the current turn ends instead of rejecting. Default true. Explicit false restores the old reject-when-busy behavior."
|
|
8513
8616
|
)
|
|
8514
8617
|
},
|
|
8515
8618
|
async (input) => {
|
|
@@ -8519,6 +8622,11 @@ function registerAgentTools(server, opts) {
|
|
|
8519
8622
|
const promptSource = callerScope?.ownerSessionId ?? callerSessionId;
|
|
8520
8623
|
await registry.enqueuePrompt(sessionId, input.prompt, {
|
|
8521
8624
|
interrupt: input.interrupt,
|
|
8625
|
+
// Queue by default: a mid-turn session holds the prompt in its
|
|
8626
|
+
// FIFO queue and dispatches it at turn end, so callers never
|
|
8627
|
+
// lose a prompt to the busy rejection. Explicit `queue: false`
|
|
8628
|
+
// restores the old reject-when-busy behavior.
|
|
8629
|
+
queue: input.queue ?? true,
|
|
8522
8630
|
...promptSource ? { source: `agent:${promptSource}` } : {}
|
|
8523
8631
|
});
|
|
8524
8632
|
return {
|
|
@@ -8534,11 +8642,18 @@ function registerAgentTools(server, opts) {
|
|
|
8534
8642
|
]
|
|
8535
8643
|
};
|
|
8536
8644
|
} catch (err) {
|
|
8645
|
+
let message = err instanceof Error ? err.message : String(err);
|
|
8646
|
+
if (input.queue === false && message.includes("is mid-turn")) {
|
|
8647
|
+
message = message.replace(
|
|
8648
|
+
"wait for it to finish or cancel",
|
|
8649
|
+
"pass queue: true, or use `agentproto sessions prompt`"
|
|
8650
|
+
);
|
|
8651
|
+
}
|
|
8537
8652
|
return {
|
|
8538
8653
|
content: [
|
|
8539
8654
|
{
|
|
8540
8655
|
type: "text",
|
|
8541
|
-
text: `agent_prompt: ${
|
|
8656
|
+
text: `agent_prompt: ${message}`
|
|
8542
8657
|
}
|
|
8543
8658
|
],
|
|
8544
8659
|
isError: true
|
|
@@ -10861,7 +10976,9 @@ function toSessionSummary(desc) {
|
|
|
10861
10976
|
sandboxId: desc.sandboxId,
|
|
10862
10977
|
sandboxTeardown: desc.sandboxTeardown,
|
|
10863
10978
|
sandboxPorts: desc.sandboxPorts,
|
|
10864
|
-
appServe: desc.appServe
|
|
10979
|
+
appServe: desc.appServe,
|
|
10980
|
+
sandboxAlive: desc.sandboxAlive,
|
|
10981
|
+
sandboxCheckedAt: desc.sandboxCheckedAt
|
|
10865
10982
|
};
|
|
10866
10983
|
}
|
|
10867
10984
|
var BRACKETED_PASTE_ON = "\x1B[?2004h";
|
|
@@ -10924,7 +11041,15 @@ function markHeldId(map, slug, id) {
|
|
|
10924
11041
|
}
|
|
10925
11042
|
var HISTORY_CAP = 200;
|
|
10926
11043
|
var INTERRUPT_SETTLE_TIMEOUT_MS = 6e4;
|
|
11044
|
+
function stampAlive(desc) {
|
|
11045
|
+
desc.alive = desc.status === "running" || desc.status === "starting";
|
|
11046
|
+
}
|
|
11047
|
+
function stampReadLiveness(desc) {
|
|
11048
|
+
stampProcessAlive(desc);
|
|
11049
|
+
stampSandboxLiveness(desc);
|
|
11050
|
+
}
|
|
10927
11051
|
function stampProcessAlive(desc) {
|
|
11052
|
+
stampAlive(desc);
|
|
10928
11053
|
if (desc.pid === null || desc.pid === void 0) {
|
|
10929
11054
|
delete desc.processAlive;
|
|
10930
11055
|
return;
|
|
@@ -10936,6 +11061,21 @@ function stampProcessAlive(desc) {
|
|
|
10936
11061
|
desc.processAlive = false;
|
|
10937
11062
|
}
|
|
10938
11063
|
}
|
|
11064
|
+
function stampSandboxLiveness(desc) {
|
|
11065
|
+
if (!desc.sandboxId) {
|
|
11066
|
+
delete desc.sandboxAlive;
|
|
11067
|
+
delete desc.sandboxCheckedAt;
|
|
11068
|
+
return;
|
|
11069
|
+
}
|
|
11070
|
+
const row = readSandboxLedger().find((e) => e.sandboxId === desc.sandboxId);
|
|
11071
|
+
if (!row || row.sandboxAlive === void 0) {
|
|
11072
|
+
delete desc.sandboxAlive;
|
|
11073
|
+
delete desc.sandboxCheckedAt;
|
|
11074
|
+
return;
|
|
11075
|
+
}
|
|
11076
|
+
desc.sandboxAlive = row.sandboxAlive;
|
|
11077
|
+
desc.sandboxCheckedAt = row.sandboxCheckedAt;
|
|
11078
|
+
}
|
|
10939
11079
|
function killChildIfSpawned(child, signal) {
|
|
10940
11080
|
if (!child) return;
|
|
10941
11081
|
if (typeof child.pid !== "number" || child.pid <= 0) return;
|
|
@@ -12602,6 +12742,7 @@ ${message}`;
|
|
|
12602
12742
|
...priorCommandSessionId ? { priorCommandSessionId } : {},
|
|
12603
12743
|
...input.remote ? { remote: true } : {},
|
|
12604
12744
|
...input.sandboxId ? { sandboxId: input.sandboxId } : {},
|
|
12745
|
+
...input.sandboxProvider ? { sandboxProvider: input.sandboxProvider } : {},
|
|
12605
12746
|
...input.sandboxTeardown ? { sandboxTeardown: input.sandboxTeardown } : {},
|
|
12606
12747
|
...input.sandboxPorts ? { sandboxPorts: input.sandboxPorts } : {},
|
|
12607
12748
|
...input.appServe ? { appServe: input.appServe } : {},
|
|
@@ -12710,6 +12851,7 @@ ${message}`;
|
|
|
12710
12851
|
...priorCommandSessionId ? { priorCommandSessionId } : {},
|
|
12711
12852
|
...input.remote ? { remote: true } : {},
|
|
12712
12853
|
...input.sandboxId ? { sandboxId: input.sandboxId } : {},
|
|
12854
|
+
...input.sandboxProvider ? { sandboxProvider: input.sandboxProvider } : {},
|
|
12713
12855
|
...input.sandboxTeardown ? { sandboxTeardown: input.sandboxTeardown } : {},
|
|
12714
12856
|
...input.sandboxPorts ? { sandboxPorts: input.sandboxPorts } : {},
|
|
12715
12857
|
...input.resumedFrom ? { resumedFrom: input.resumedFrom } : {},
|
|
@@ -13383,7 +13525,7 @@ ${message}`;
|
|
|
13383
13525
|
const childrenBusy = childrenBusyCounts();
|
|
13384
13526
|
return Array.from(sessions.values()).filter((rt) => includeArchived || !rt.desc.archived).sort((a, b) => b.desc.startedAt.localeCompare(a.desc.startedAt)).map((rt) => {
|
|
13385
13527
|
const desc = rt.desc;
|
|
13386
|
-
|
|
13528
|
+
stampReadLiveness(desc);
|
|
13387
13529
|
stampInterrupted(desc);
|
|
13388
13530
|
stampCurrentStatus(rt);
|
|
13389
13531
|
stampWatchers(desc);
|
|
@@ -13401,7 +13543,7 @@ ${message}`;
|
|
|
13401
13543
|
const slice = all.slice(offset, offset + limit);
|
|
13402
13544
|
const summaries = slice.map((rt) => {
|
|
13403
13545
|
const desc = rt.desc;
|
|
13404
|
-
|
|
13546
|
+
stampReadLiveness(desc);
|
|
13405
13547
|
stampInterrupted(desc);
|
|
13406
13548
|
stampCurrentStatus(rt);
|
|
13407
13549
|
stampWatchers(desc);
|
|
@@ -13415,7 +13557,7 @@ ${message}`;
|
|
|
13415
13557
|
const rt = sessions.get(id);
|
|
13416
13558
|
const desc = rt?.desc;
|
|
13417
13559
|
if (rt && desc) {
|
|
13418
|
-
|
|
13560
|
+
stampReadLiveness(desc);
|
|
13419
13561
|
stampInterrupted(desc);
|
|
13420
13562
|
stampCurrentStatus(rt);
|
|
13421
13563
|
stampWatchers(desc);
|
|
@@ -13491,14 +13633,14 @@ ${message}`;
|
|
|
13491
13633
|
findByIdOrName(query) {
|
|
13492
13634
|
const direct = sessions.get(query);
|
|
13493
13635
|
if (direct) {
|
|
13494
|
-
|
|
13636
|
+
stampReadLiveness(direct.desc);
|
|
13495
13637
|
stampInterrupted(direct.desc);
|
|
13496
13638
|
stampCurrentStatus(direct);
|
|
13497
13639
|
return direct.desc;
|
|
13498
13640
|
}
|
|
13499
13641
|
for (const rt of sessions.values()) {
|
|
13500
13642
|
if (rt.desc.name === query) {
|
|
13501
|
-
|
|
13643
|
+
stampReadLiveness(rt.desc);
|
|
13502
13644
|
stampInterrupted(rt.desc);
|
|
13503
13645
|
stampCurrentStatus(rt);
|
|
13504
13646
|
return rt.desc;
|
|
@@ -13696,7 +13838,7 @@ ${message}`;
|
|
|
13696
13838
|
}
|
|
13697
13839
|
rt.desc.archived = true;
|
|
13698
13840
|
schedulePersist();
|
|
13699
|
-
|
|
13841
|
+
stampReadLiveness(rt.desc);
|
|
13700
13842
|
return rt.desc;
|
|
13701
13843
|
},
|
|
13702
13844
|
unarchiveSession(id) {
|
|
@@ -13704,7 +13846,7 @@ ${message}`;
|
|
|
13704
13846
|
if (!rt) throw new Error(`unarchiveSession: no session "${id}"`);
|
|
13705
13847
|
rt.desc.archived = false;
|
|
13706
13848
|
schedulePersist();
|
|
13707
|
-
|
|
13849
|
+
stampReadLiveness(rt.desc);
|
|
13708
13850
|
return rt.desc;
|
|
13709
13851
|
},
|
|
13710
13852
|
gcSessions(opts2) {
|
|
@@ -13752,7 +13894,7 @@ ${message}`;
|
|
|
13752
13894
|
renamedByUser: true,
|
|
13753
13895
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
13754
13896
|
});
|
|
13755
|
-
|
|
13897
|
+
stampReadLiveness(rt.desc);
|
|
13756
13898
|
return rt.desc;
|
|
13757
13899
|
},
|
|
13758
13900
|
setKeepAlive(id, keepAlive) {
|
|
@@ -13760,7 +13902,7 @@ ${message}`;
|
|
|
13760
13902
|
if (!rt) throw new Error(`setKeepAlive: no session "${id}"`);
|
|
13761
13903
|
rt.desc.keepAlive = keepAlive;
|
|
13762
13904
|
schedulePersist();
|
|
13763
|
-
|
|
13905
|
+
stampReadLiveness(rt.desc);
|
|
13764
13906
|
return rt.desc;
|
|
13765
13907
|
},
|
|
13766
13908
|
setPinned(id, pinned) {
|
|
@@ -13774,7 +13916,7 @@ ${message}`;
|
|
|
13774
13916
|
pinned,
|
|
13775
13917
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
13776
13918
|
});
|
|
13777
|
-
|
|
13919
|
+
stampReadLiveness(rt.desc);
|
|
13778
13920
|
return rt.desc;
|
|
13779
13921
|
},
|
|
13780
13922
|
flagAwaitingInput(id, patch) {
|
|
@@ -13798,7 +13940,7 @@ ${message}`;
|
|
|
13798
13940
|
...rt.desc.label ? { label: rt.desc.label } : {},
|
|
13799
13941
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
13800
13942
|
});
|
|
13801
|
-
|
|
13943
|
+
stampReadLiveness(rt.desc);
|
|
13802
13944
|
return rt.desc;
|
|
13803
13945
|
},
|
|
13804
13946
|
listPendingPermissions(filter) {
|
|
@@ -15565,6 +15707,7 @@ async function restartAgentSession(registry, resolveAgentAdapter, prev, opts = {
|
|
|
15565
15707
|
} : {},
|
|
15566
15708
|
remote: true,
|
|
15567
15709
|
sandboxId: host.sandboxId,
|
|
15710
|
+
sandboxProvider: providerSlug,
|
|
15568
15711
|
sandboxTeardown: lifecyclePolicy.teardown,
|
|
15569
15712
|
...host.ports && Object.keys(host.ports).length > 0 ? { sandboxPorts: host.ports } : {},
|
|
15570
15713
|
commandPreview: `sandbox:${providerSlug} \u2192 ${adapterSlug}`,
|
|
@@ -16255,6 +16398,7 @@ var compactSessionItem = (s) => ({
|
|
|
16255
16398
|
name: s.name,
|
|
16256
16399
|
label: s.label,
|
|
16257
16400
|
status: s.status,
|
|
16401
|
+
alive: s.alive,
|
|
16258
16402
|
pty: s.pty,
|
|
16259
16403
|
command: s.command,
|
|
16260
16404
|
cwd: s.cwd,
|
|
@@ -20176,7 +20320,18 @@ function makeBuiltinPanelApps(ops) {
|
|
|
20176
20320
|
// Live-session widget — resource ui://live_session/view, also bound to
|
|
20177
20321
|
// `agent_start` via _meta.ui.resourceUri (agent-tools.ts) so a launch
|
|
20178
20322
|
// auto-renders it.
|
|
20179
|
-
makeLiveSessionApp({ httpBaseUrl: ops.httpBaseUrl })
|
|
20323
|
+
makeLiveSessionApp({ httpBaseUrl: ops.httpBaseUrl }),
|
|
20324
|
+
// Session-chat widget — thin launcher for the installed
|
|
20325
|
+
// `@agentik/session-chat` app's standalone UI (deep-linked iframe when
|
|
20326
|
+
// installed, install notice otherwise; see apps/src/session-chat).
|
|
20327
|
+
makeSessionChatApp({
|
|
20328
|
+
httpBaseUrl: ops.httpBaseUrl,
|
|
20329
|
+
isSessionChatInstalled: ops.isSessionChatInstalled
|
|
20330
|
+
}),
|
|
20331
|
+
// Work-board widget — kanban over the Task ledger (see apps/src/
|
|
20332
|
+
// work-board). Read path only; writes go through task_claim/
|
|
20333
|
+
// task_update/task_create over the bridge, same as every other caller.
|
|
20334
|
+
makeWorkBoardApp({ listTasks: ops.listTasks })
|
|
20180
20335
|
];
|
|
20181
20336
|
}
|
|
20182
20337
|
var PANEL_APP_HANDLES = [
|
|
@@ -20184,12 +20339,28 @@ var PANEL_APP_HANDLES = [
|
|
|
20184
20339
|
agentsOverviewApp,
|
|
20185
20340
|
bureauSessionsApp,
|
|
20186
20341
|
sessionStoryApp,
|
|
20187
|
-
liveSessionApp
|
|
20342
|
+
liveSessionApp,
|
|
20343
|
+
sessionChatApp,
|
|
20344
|
+
workBoardApp
|
|
20188
20345
|
];
|
|
20346
|
+
function resolveBuiltinPanelUi(appId, httpBaseUrl) {
|
|
20347
|
+
if (appId === liveSessionApp.id) {
|
|
20348
|
+
const app = makeLiveSessionApp({ httpBaseUrl });
|
|
20349
|
+
const html = typeof app.html === "function" ? app.html({ httpBaseUrl }) : app.html;
|
|
20350
|
+
return { html, tools: liveSessionApp.ui?.tools ?? [] };
|
|
20351
|
+
}
|
|
20352
|
+
const handle = [sessionsPanelApp, agentsOverviewApp, bureauSessionsApp, sessionStoryApp, workBoardApp].find(
|
|
20353
|
+
(h) => h.id === appId
|
|
20354
|
+
);
|
|
20355
|
+
if (!handle?.ui) return void 0;
|
|
20356
|
+
return { html: handle.ui.html, tools: handle.ui.tools ?? [] };
|
|
20357
|
+
}
|
|
20189
20358
|
function builtinPanelCatalogEntries() {
|
|
20190
20359
|
const apps = makeBuiltinPanelApps({
|
|
20191
20360
|
listSessions: () => [],
|
|
20192
|
-
httpBaseUrl: "http://127.0.0.1:0"
|
|
20361
|
+
httpBaseUrl: "http://127.0.0.1:0",
|
|
20362
|
+
isSessionChatInstalled: () => false,
|
|
20363
|
+
listTasks: (boardId) => ({ boardId: boardId ?? "ws:default", tasks: [] })
|
|
20193
20364
|
});
|
|
20194
20365
|
return apps.map((app, i) => {
|
|
20195
20366
|
const handle = PANEL_APP_HANDLES[i];
|
|
@@ -21794,12 +21965,7 @@ function notEnabled(tool) {
|
|
|
21794
21965
|
`${tool} is not enabled \u2014 the daemon was started without an adapter resolver. Re-run the daemon with the \`@agentproto/cli\` shim wired (see playground/scripts/gateway.ts).`
|
|
21795
21966
|
);
|
|
21796
21967
|
}
|
|
21797
|
-
async function
|
|
21798
|
-
const installed = appRegistry.getApp(input.appId);
|
|
21799
|
-
if (!installed || !installed.ui) {
|
|
21800
|
-
return errorResult2(`app_tool_call: app "${input.appId}" is not installed or has no UI.`);
|
|
21801
|
-
}
|
|
21802
|
-
const declaredAllowlist = installed.ui.tools ?? [];
|
|
21968
|
+
async function dispatchAllowlistedAppTool(declaredAllowlist, input, deps2) {
|
|
21803
21969
|
const effectiveAllowlist = [...declaredAllowlist, ...APP_UI_DISCOVERY_TOOLS];
|
|
21804
21970
|
if (!effectiveAllowlist.includes(input.tool)) {
|
|
21805
21971
|
return errorResult2(
|
|
@@ -21827,6 +21993,19 @@ async function performAppToolCall(appRegistry, input, deps2) {
|
|
|
21827
21993
|
return errorResult2(`app_tool_call: ${err instanceof Error ? err.message : String(err)}`);
|
|
21828
21994
|
}
|
|
21829
21995
|
}
|
|
21996
|
+
async function performAppToolCall(appRegistry, input, deps2) {
|
|
21997
|
+
const installed = appRegistry.getApp(input.appId);
|
|
21998
|
+
if (!installed || !installed.ui) {
|
|
21999
|
+
return errorResult2(`app_tool_call: app "${input.appId}" is not installed or has no UI.`);
|
|
22000
|
+
}
|
|
22001
|
+
return dispatchAllowlistedAppTool(installed.ui.tools ?? [], input, deps2);
|
|
22002
|
+
}
|
|
22003
|
+
async function performBuiltinPanelToolCall(tools, input, deps2) {
|
|
22004
|
+
if (tools === void 0) {
|
|
22005
|
+
return errorResult2(`app_tool_call: app "${input.appId}" is not installed or has no UI.`);
|
|
22006
|
+
}
|
|
22007
|
+
return dispatchAllowlistedAppTool(tools, input, deps2);
|
|
22008
|
+
}
|
|
21830
22009
|
function refIdOf(ref) {
|
|
21831
22010
|
if (typeof ref === "string") return ref;
|
|
21832
22011
|
return ref.ref ?? ref.file ?? "inline";
|
|
@@ -22785,7 +22964,8 @@ async function makeInstalledAppUiApps(appRegistry, cache, existingToolNames) {
|
|
|
22785
22964
|
...ui.csp ? {
|
|
22786
22965
|
csp: {
|
|
22787
22966
|
...ui.csp.connectDomains ? { connectDomains: [...ui.csp.connectDomains] } : {},
|
|
22788
|
-
...ui.csp.resourceDomains ? { resourceDomains: [...ui.csp.resourceDomains] } : {}
|
|
22967
|
+
...ui.csp.resourceDomains ? { resourceDomains: [...ui.csp.resourceDomains] } : {},
|
|
22968
|
+
...ui.csp.frameDomains ? { frameDomains: [...ui.csp.frameDomains] } : {}
|
|
22789
22969
|
}
|
|
22790
22970
|
} : {}
|
|
22791
22971
|
});
|
|
@@ -23414,6 +23594,8 @@ function buildMsg(body, ctx, fields) {
|
|
|
23414
23594
|
const source = ctx.sourceOverride ?? (typeof fields.source === "function" ? fields.source() : fields.source);
|
|
23415
23595
|
const contactRef = typeof fields.contactRef === "function" ? fields.contactRef() : fields.contactRef;
|
|
23416
23596
|
const text10 = typeof fields.text === "function" ? fields.text() : fields.text;
|
|
23597
|
+
const displayName = typeof fields.displayName === "function" ? fields.displayName() : fields.displayName;
|
|
23598
|
+
const surface = typeof fields.surface === "function" ? fields.surface() : fields.surface;
|
|
23417
23599
|
const providerMessageId = typeof fields.providerMessageId === "function" ? fields.providerMessageId() : fields.providerMessageId;
|
|
23418
23600
|
if (!source) return { ok: false, error: "missing_source" };
|
|
23419
23601
|
if (!contactRef) return { ok: false, error: "missing_contact_ref" };
|
|
@@ -23423,6 +23605,10 @@ function buildMsg(body, ctx, fields) {
|
|
|
23423
23605
|
source,
|
|
23424
23606
|
contactRef,
|
|
23425
23607
|
text: text10,
|
|
23608
|
+
// Opt-in attribution — only set when the dialect knows a sender name,
|
|
23609
|
+
// so 1:1 bindings keep receiving the raw text unprefixed.
|
|
23610
|
+
...displayName ? { displayName } : {},
|
|
23611
|
+
...surface ? { surface } : {},
|
|
23426
23612
|
...Array.isArray(body) ? { messages: body } : {}
|
|
23427
23613
|
};
|
|
23428
23614
|
return { ok: true, msg, providerMessageId };
|
|
@@ -23476,10 +23662,13 @@ function normalizeTelegram(body, ctx) {
|
|
|
23476
23662
|
const contactRef = chat && typeof chat.id === "number" ? String(chat.id) : void 0;
|
|
23477
23663
|
const text10 = typeof message.text === "string" ? message.text : void 0;
|
|
23478
23664
|
const providerMessageId = typeof message.message_id === "number" ? String(message.message_id) : void 0;
|
|
23665
|
+
const displayName = typeof from?.first_name === "string" && from.first_name ? from.first_name : typeof from?.username === "string" && from.username ? from.username : void 0;
|
|
23479
23666
|
return buildMsg(body, ctx, {
|
|
23480
23667
|
source,
|
|
23481
23668
|
contactRef,
|
|
23482
23669
|
text: text10,
|
|
23670
|
+
displayName,
|
|
23671
|
+
surface: "telegram",
|
|
23483
23672
|
providerMessageId
|
|
23484
23673
|
});
|
|
23485
23674
|
}
|
|
@@ -26519,6 +26708,7 @@ var DEFAULT_ALLOWED_ORIGINS = [
|
|
|
26519
26708
|
// matching how guilde.work is trusted. Drop it via `strictOrigins`.
|
|
26520
26709
|
"https://cli.agentproto.sh"
|
|
26521
26710
|
];
|
|
26711
|
+
var DEFAULT_FRAME_ANCESTORS = ["vscode-webview:"];
|
|
26522
26712
|
var PROXY_FORWARDING_HEADERS = [
|
|
26523
26713
|
"x-forwarded-for",
|
|
26524
26714
|
"forwarded",
|
|
@@ -27447,6 +27637,11 @@ async function startHttpServer(opts) {
|
|
|
27447
27637
|
return;
|
|
27448
27638
|
}
|
|
27449
27639
|
if (path === "/mcps/imports" && req.method === "POST") {
|
|
27640
|
+
const gate = checkSessionsToken(req);
|
|
27641
|
+
if (gate !== "ok") {
|
|
27642
|
+
rejectUnauthorizedSession(req, res, gate);
|
|
27643
|
+
return;
|
|
27644
|
+
}
|
|
27450
27645
|
const body = await readJsonBody(req);
|
|
27451
27646
|
if (!body || typeof body.sourceMcpId !== "string") {
|
|
27452
27647
|
res.writeHead(400, { "content-type": "application/json" });
|
|
@@ -27477,6 +27672,11 @@ async function startHttpServer(opts) {
|
|
|
27477
27672
|
}
|
|
27478
27673
|
const importMatch = path.match(/^\/mcps\/imports\/(.+)$/);
|
|
27479
27674
|
if (importMatch && req.method === "DELETE") {
|
|
27675
|
+
const gate = checkSessionsToken(req);
|
|
27676
|
+
if (gate !== "ok") {
|
|
27677
|
+
rejectUnauthorizedSession(req, res, gate);
|
|
27678
|
+
return;
|
|
27679
|
+
}
|
|
27480
27680
|
const id = decodeURIComponent(importMatch[1] ?? "");
|
|
27481
27681
|
const cfg = await loadImportedMcps();
|
|
27482
27682
|
if (!cfg.imports.some((e) => e.id === id)) {
|
|
@@ -27542,6 +27742,11 @@ async function startHttpServer(opts) {
|
|
|
27542
27742
|
return;
|
|
27543
27743
|
}
|
|
27544
27744
|
if (path === "/mcps/proxy/call" && req.method === "POST") {
|
|
27745
|
+
const gate = checkSessionsToken(req);
|
|
27746
|
+
if (gate !== "ok") {
|
|
27747
|
+
rejectUnauthorizedSession(req, res, gate);
|
|
27748
|
+
return;
|
|
27749
|
+
}
|
|
27545
27750
|
if (!opts.mcpProxy) {
|
|
27546
27751
|
res.writeHead(501, { "content-type": "application/json" });
|
|
27547
27752
|
res.end(JSON.stringify({ error: "mcp_proxy_not_configured" }));
|
|
@@ -27815,6 +28020,17 @@ async function startHttpServer(opts) {
|
|
|
27815
28020
|
const handled = await handleTasks(req, res, path, opts.taskLedger);
|
|
27816
28021
|
if (handled) return;
|
|
27817
28022
|
}
|
|
28023
|
+
if (path.startsWith("/sandboxes")) {
|
|
28024
|
+
if ((req.method ?? "GET") !== "GET") {
|
|
28025
|
+
const gate = checkSessionsToken(req);
|
|
28026
|
+
if (gate !== "ok") {
|
|
28027
|
+
rejectUnauthorizedSession(req, res, gate);
|
|
28028
|
+
return;
|
|
28029
|
+
}
|
|
28030
|
+
}
|
|
28031
|
+
const handled = await handleSandboxes(req, res, path, opts.resolveSandboxProvider);
|
|
28032
|
+
if (handled) return;
|
|
28033
|
+
}
|
|
27818
28034
|
if (opts.sessions && path.startsWith("/permissions")) {
|
|
27819
28035
|
if ((req.method ?? "GET") !== "GET") {
|
|
27820
28036
|
const gate = checkSessionsToken(req);
|
|
@@ -27848,9 +28064,16 @@ async function startHttpServer(opts) {
|
|
|
27848
28064
|
if (opts.appRegistry && path.startsWith("/apps/")) {
|
|
27849
28065
|
const uiMatch = path.match(/^\/apps\/(.+)\/ui$/);
|
|
27850
28066
|
if (uiMatch && req.method === "GET") {
|
|
27851
|
-
|
|
28067
|
+
const uiApp = opts.appRegistry.getApp(decodeURIComponent(uiMatch[1]));
|
|
28068
|
+
if (!iframeEmbedOriginAllowed(req, uiApp ?? {}) && guardBrowserOrigin(req, res)) return;
|
|
27852
28069
|
if (!authorize(req, res)) return;
|
|
27853
|
-
await handleAppUiPage(
|
|
28070
|
+
await handleAppUiPage(
|
|
28071
|
+
req,
|
|
28072
|
+
res,
|
|
28073
|
+
decodeURIComponent(uiMatch[1]),
|
|
28074
|
+
opts.appRegistry,
|
|
28075
|
+
[...DEFAULT_FRAME_ANCESTORS, ...opts.frameAncestors ?? []]
|
|
28076
|
+
);
|
|
27854
28077
|
return;
|
|
27855
28078
|
}
|
|
27856
28079
|
const toolCallMatch = path.match(/^\/apps\/(.+)\/tool-call$/);
|
|
@@ -28218,6 +28441,12 @@ async function* transcriptDiskRecords(id) {
|
|
|
28218
28441
|
}
|
|
28219
28442
|
}
|
|
28220
28443
|
function buildSpawnSessionHttpArgs(b, adapter, preset) {
|
|
28444
|
+
const maxCostUsdCap = b.maxCostUsd !== void 0 ? parseMaxCostUsdField(b.maxCostUsd) : void 0;
|
|
28445
|
+
const costBudgetCap = b.costBudget !== void 0 ? parseCostBudgetField(b.costBudget) : void 0;
|
|
28446
|
+
const spendCaps = {
|
|
28447
|
+
...maxCostUsdCap !== void 0 ? maxCostUsdCap : {},
|
|
28448
|
+
...costBudgetCap !== void 0 ? { costBudget: costBudgetCap } : {}
|
|
28449
|
+
};
|
|
28221
28450
|
return {
|
|
28222
28451
|
adapter,
|
|
28223
28452
|
...typeof b.origin === "string" && b.origin.length > 0 ? { origin: b.origin } : {},
|
|
@@ -28247,6 +28476,8 @@ function buildSpawnSessionHttpArgs(b, adapter, preset) {
|
|
|
28247
28476
|
const parsed = parseAuthField(b.auth);
|
|
28248
28477
|
return parsed !== void 0 ? { auth: parsed } : {};
|
|
28249
28478
|
})() : {},
|
|
28479
|
+
// Spend caps (parsed above) — see `spendCaps`.
|
|
28480
|
+
...spendCaps,
|
|
28250
28481
|
...typeof b.prompt === "string" ? { prompt: b.prompt } : {},
|
|
28251
28482
|
...typeof b.label === "string" ? { label: b.label } : {},
|
|
28252
28483
|
// Explicit title override (SPEC-3 FIX C, `--title`) — wins over the
|
|
@@ -28392,7 +28623,9 @@ function parseMcpServersField(raw) {
|
|
|
28392
28623
|
servers.push({
|
|
28393
28624
|
name: o.name,
|
|
28394
28625
|
transport: o.transport,
|
|
28395
|
-
...typeof o.ref === "string" ? { ref: o.ref } : {}
|
|
28626
|
+
...typeof o.ref === "string" ? { ref: o.ref } : {},
|
|
28627
|
+
...isStringRecord(o.headers) ? { headers: o.headers } : {},
|
|
28628
|
+
...typeof o.credentialRef === "string" ? { credentialRef: o.credentialRef } : {}
|
|
28396
28629
|
});
|
|
28397
28630
|
}
|
|
28398
28631
|
return servers;
|
|
@@ -28431,6 +28664,20 @@ function parseRouteField(raw) {
|
|
|
28431
28664
|
...typeof obj.baseUrl === "string" && obj.baseUrl.length > 0 ? { baseUrl: obj.baseUrl } : {}
|
|
28432
28665
|
};
|
|
28433
28666
|
}
|
|
28667
|
+
function parseMaxCostUsdField(raw) {
|
|
28668
|
+
const n = typeof raw === "string" ? Number(raw) : raw;
|
|
28669
|
+
return typeof n === "number" && Number.isFinite(n) && n > 0 ? { maxCostUsd: n } : void 0;
|
|
28670
|
+
}
|
|
28671
|
+
function parseCostBudgetField(raw) {
|
|
28672
|
+
const value = typeof raw === "string" ? tryParseJson(raw) : raw;
|
|
28673
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
28674
|
+
const obj = value;
|
|
28675
|
+
const usd = typeof obj.maxCostUsd === "string" ? Number(obj.maxCostUsd) : obj.maxCostUsd;
|
|
28676
|
+
if (typeof usd !== "number" || !Number.isFinite(usd) || usd <= 0) return void 0;
|
|
28677
|
+
if (typeof obj.window !== "string" || obj.window.length === 0) return void 0;
|
|
28678
|
+
if (obj.scope !== "session" && obj.scope !== "profile") return void 0;
|
|
28679
|
+
return { maxCostUsd: usd, window: obj.window, scope: obj.scope };
|
|
28680
|
+
}
|
|
28434
28681
|
function parseAccessField(raw) {
|
|
28435
28682
|
const value = typeof raw === "string" ? tryParseJson(raw) : raw;
|
|
28436
28683
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
@@ -28491,6 +28738,61 @@ async function resolveSlugFromCwd(cwd) {
|
|
|
28491
28738
|
return void 0;
|
|
28492
28739
|
}
|
|
28493
28740
|
}
|
|
28741
|
+
async function handleSandboxes(_req, res, path, resolveSandboxProvider2) {
|
|
28742
|
+
const json = (status, body) => {
|
|
28743
|
+
res.writeHead(status, { "content-type": "application/json" });
|
|
28744
|
+
res.end(JSON.stringify(body));
|
|
28745
|
+
};
|
|
28746
|
+
const match = path.match(/^\/sandboxes\/([^/]+)\/alive$/);
|
|
28747
|
+
if (!match || _req.method !== "GET") return false;
|
|
28748
|
+
const sandboxId = decodeURIComponent(match[1]);
|
|
28749
|
+
const row = readSandboxLedger().find((e) => e.sandboxId === sandboxId);
|
|
28750
|
+
if (!row) {
|
|
28751
|
+
json(404, {
|
|
28752
|
+
error: `sandbox "${sandboxId}" is not in the sandbox ledger (~/.agentproto/sandboxes.json)`
|
|
28753
|
+
});
|
|
28754
|
+
return true;
|
|
28755
|
+
}
|
|
28756
|
+
const resolver = resolveSandboxProvider2 ?? makeSandboxResolver(makeSandboxCredsStore());
|
|
28757
|
+
let handle;
|
|
28758
|
+
try {
|
|
28759
|
+
handle = await resolver(row.provider);
|
|
28760
|
+
} catch (err) {
|
|
28761
|
+
json(502, {
|
|
28762
|
+
alive: null,
|
|
28763
|
+
state: row.state,
|
|
28764
|
+
error: `sandbox provider "${row.provider}" could not be resolved \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
28765
|
+
});
|
|
28766
|
+
return true;
|
|
28767
|
+
}
|
|
28768
|
+
if (!handle?.provider?.probe) {
|
|
28769
|
+
json(501, {
|
|
28770
|
+
alive: null,
|
|
28771
|
+
state: row.state,
|
|
28772
|
+
error: `sandbox provider "${row.provider}" has no probe() \u2014 liveness unknown`
|
|
28773
|
+
});
|
|
28774
|
+
return true;
|
|
28775
|
+
}
|
|
28776
|
+
let probe;
|
|
28777
|
+
try {
|
|
28778
|
+
probe = await handle.provider.probe(row.sandboxId);
|
|
28779
|
+
} catch (err) {
|
|
28780
|
+
json(502, {
|
|
28781
|
+
alive: null,
|
|
28782
|
+
state: row.state,
|
|
28783
|
+
error: `liveness probe failed \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
28784
|
+
});
|
|
28785
|
+
return true;
|
|
28786
|
+
}
|
|
28787
|
+
recordSandboxLiveness(row.sandboxId, probe.alive);
|
|
28788
|
+
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
28789
|
+
if (!probe.alive) {
|
|
28790
|
+
json(410, { alive: false, state: "gone", checkedAt });
|
|
28791
|
+
return true;
|
|
28792
|
+
}
|
|
28793
|
+
json(200, { alive: true, ...probe.state ? { state: probe.state } : { state: row.state }, checkedAt });
|
|
28794
|
+
return true;
|
|
28795
|
+
}
|
|
28494
28796
|
async function handleSessions(req, res, path, registry, resolveAgentAdapter, ptyEnabled = false, resolveBrowserAdapter, listBrowserAdapters, sessionEvents, eventRing, buildOrchestratorMcp, daemonMcpUrl, provisionWorktree, listCatalogModels, resolveSandboxProvider2) {
|
|
28495
28797
|
const json = (status, body) => {
|
|
28496
28798
|
res.writeHead(status, { "content-type": "application/json" });
|
|
@@ -29187,7 +29489,7 @@ async function handleSessions(req, res, path, registry, resolveAgentAdapter, pty
|
|
|
29187
29489
|
return true;
|
|
29188
29490
|
}
|
|
29189
29491
|
const idMatch = path.match(
|
|
29190
|
-
/^\/sessions\/([^/]+)(\/events\/stream|\/stream|\/kill|\/pin|\/preview|\/export|\/conversation|\/events|\/wait|\/chat)?$/
|
|
29492
|
+
/^\/sessions\/([^/]+)(\/events\/stream|\/stream|\/kill|\/pin|\/preview|\/export|\/conversation|\/events|\/wait|\/chat|\/alive)?$/
|
|
29191
29493
|
);
|
|
29192
29494
|
if (!idMatch) return false;
|
|
29193
29495
|
const [, rawIdOrName, suffix] = idMatch;
|
|
@@ -29546,6 +29848,15 @@ async function handleSessions(req, res, path, registry, resolveAgentAdapter, pty
|
|
|
29546
29848
|
}
|
|
29547
29849
|
return true;
|
|
29548
29850
|
}
|
|
29851
|
+
if (suffix === "/alive" && req.method === "GET") {
|
|
29852
|
+
if (!resolvedDesc) {
|
|
29853
|
+
json(404, { error: "session_not_found", id: rawIdOrName });
|
|
29854
|
+
return true;
|
|
29855
|
+
}
|
|
29856
|
+
const alive = resolvedDesc.status === "running" || resolvedDesc.status === "starting";
|
|
29857
|
+
json(alive ? 200 : 410, { alive, status: resolvedDesc.status });
|
|
29858
|
+
return true;
|
|
29859
|
+
}
|
|
29549
29860
|
if (!suffix && req.method === "GET") {
|
|
29550
29861
|
if (!resolvedDesc) {
|
|
29551
29862
|
json(404, { error: "session_not_found", id: rawIdOrName });
|
|
@@ -30296,6 +30607,16 @@ async function handleNativeInbound(req, res, deps2) {
|
|
|
30296
30607
|
res.end(JSON.stringify({ error: "missing_text" }));
|
|
30297
30608
|
return;
|
|
30298
30609
|
}
|
|
30610
|
+
if (body.display_name !== void 0 && typeof body.display_name !== "string") {
|
|
30611
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
30612
|
+
res.end(JSON.stringify({ error: "invalid_display_name" }));
|
|
30613
|
+
return;
|
|
30614
|
+
}
|
|
30615
|
+
if (body.surface !== void 0 && typeof body.surface !== "string") {
|
|
30616
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
30617
|
+
res.end(JSON.stringify({ error: "invalid_surface" }));
|
|
30618
|
+
return;
|
|
30619
|
+
}
|
|
30299
30620
|
let mode = "route-or-spawn";
|
|
30300
30621
|
if (body.mode !== void 0) {
|
|
30301
30622
|
if (!isInboundRouteMode(String(body.mode))) {
|
|
@@ -30325,6 +30646,10 @@ async function handleNativeInbound(req, res, deps2) {
|
|
|
30325
30646
|
source: body.source,
|
|
30326
30647
|
contactRef: body.contact_ref,
|
|
30327
30648
|
text: body.text,
|
|
30649
|
+
// Attribution is opt-in — an absent field must not exist on the message
|
|
30650
|
+
// at all, or attributeInboundText would prefix every 1:1 turn.
|
|
30651
|
+
...typeof body.display_name === "string" ? { displayName: body.display_name } : {},
|
|
30652
|
+
...typeof body.surface === "string" ? { surface: body.surface } : {},
|
|
30328
30653
|
...Array.isArray(body.messages) ? { messages: body.messages } : {}
|
|
30329
30654
|
};
|
|
30330
30655
|
const result = await deps2.routeInboundMessage(msg, mode);
|
|
@@ -30448,33 +30773,88 @@ async function handleProviderInbound(req, res, slug, deps2) {
|
|
|
30448
30773
|
res.writeHead(200, { "content-type": "application/json" });
|
|
30449
30774
|
res.end(JSON.stringify(result));
|
|
30450
30775
|
}
|
|
30451
|
-
|
|
30776
|
+
function requestHttpBaseUrl(req) {
|
|
30777
|
+
return `http://${req.headers.host ?? "127.0.0.1"}`;
|
|
30778
|
+
}
|
|
30779
|
+
async function handleAppUiPage(req, res, appId, appRegistry, frameAncestors) {
|
|
30452
30780
|
const app = appRegistry.getApp(appId);
|
|
30453
|
-
|
|
30781
|
+
const builtin = app?.ui ? void 0 : resolveBuiltinPanelUi(appId, requestHttpBaseUrl(req));
|
|
30782
|
+
if (!app?.ui && !builtin) {
|
|
30454
30783
|
res.writeHead(404, { "content-type": "application/json" });
|
|
30455
30784
|
res.end(JSON.stringify({ error: `app "${appId}" is not installed or has no UI.` }));
|
|
30456
30785
|
return;
|
|
30457
30786
|
}
|
|
30458
30787
|
let raw;
|
|
30459
|
-
|
|
30460
|
-
|
|
30461
|
-
|
|
30462
|
-
|
|
30463
|
-
|
|
30464
|
-
|
|
30465
|
-
|
|
30466
|
-
|
|
30467
|
-
|
|
30468
|
-
|
|
30788
|
+
if (app?.ui) {
|
|
30789
|
+
try {
|
|
30790
|
+
raw = await readFile(app.ui.path, "utf8");
|
|
30791
|
+
} catch (err) {
|
|
30792
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
30793
|
+
res.end(
|
|
30794
|
+
JSON.stringify({
|
|
30795
|
+
error: `could not read app "${appId}"'s ui html at "${app.ui.path}": ${err instanceof Error ? err.message : String(err)}`
|
|
30796
|
+
})
|
|
30797
|
+
);
|
|
30798
|
+
return;
|
|
30799
|
+
}
|
|
30800
|
+
} else {
|
|
30801
|
+
raw = builtin.html;
|
|
30469
30802
|
}
|
|
30470
|
-
|
|
30803
|
+
const embedRequested = new URL(req.url ?? "/", "http://localhost").searchParams.get("embed") === "1";
|
|
30804
|
+
const headers = {
|
|
30471
30805
|
"content-type": "text/html; charset=utf-8",
|
|
30472
|
-
"cache-control": "no-store"
|
|
30473
|
-
|
|
30474
|
-
|
|
30475
|
-
|
|
30806
|
+
"cache-control": "no-store"
|
|
30807
|
+
};
|
|
30808
|
+
if (!(embedRequested && iframeEmbedAllowed(req, app ?? {}))) {
|
|
30809
|
+
headers["content-security-policy"] = `frame-ancestors 'self' ${frameAncestors.join(" ")}`.trimEnd();
|
|
30810
|
+
if (frameAncestors.length === 0) {
|
|
30811
|
+
headers["x-frame-options"] = "SAMEORIGIN";
|
|
30812
|
+
}
|
|
30813
|
+
}
|
|
30814
|
+
res.writeHead(200, headers);
|
|
30476
30815
|
res.end(injectStandaloneAppBridge(raw));
|
|
30477
30816
|
}
|
|
30817
|
+
function iframeEmbedAllowed(req, app) {
|
|
30818
|
+
const secFetchDest = req.headers["sec-fetch-dest"];
|
|
30819
|
+
if (secFetchDest !== void 0 && secFetchDest !== "iframe") return false;
|
|
30820
|
+
const origin = typeof req.headers.origin === "string" && req.headers.origin.length > 0 ? req.headers.origin : null;
|
|
30821
|
+
const referer = typeof req.headers.referer === "string" && req.headers.referer.length > 0 ? req.headers.referer : null;
|
|
30822
|
+
if (!origin && !referer) return false;
|
|
30823
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
30824
|
+
if (origin) candidates.add(origin);
|
|
30825
|
+
if (referer) {
|
|
30826
|
+
try {
|
|
30827
|
+
candidates.add(new URL(referer).origin);
|
|
30828
|
+
} catch {
|
|
30829
|
+
}
|
|
30830
|
+
}
|
|
30831
|
+
const host = req.headers.host;
|
|
30832
|
+
const daemonOrigins = host ? [`http://${host}`, `https://${host}`] : [];
|
|
30833
|
+
for (const candidate of candidates) {
|
|
30834
|
+
if (candidate.startsWith("vscode-webview://")) return true;
|
|
30835
|
+
if (daemonOrigins.includes(candidate)) return true;
|
|
30836
|
+
if ((app.ui?.csp?.frameDomains ?? []).includes(candidate)) return true;
|
|
30837
|
+
}
|
|
30838
|
+
return false;
|
|
30839
|
+
}
|
|
30840
|
+
function iframeEmbedOriginAllowed(req, app) {
|
|
30841
|
+
const origin = typeof req.headers.origin === "string" && req.headers.origin.length > 0 ? req.headers.origin : null;
|
|
30842
|
+
const referer = typeof req.headers.referer === "string" && req.headers.referer.length > 0 ? req.headers.referer : null;
|
|
30843
|
+
if (!origin && !referer) return false;
|
|
30844
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
30845
|
+
if (origin) candidates.add(origin);
|
|
30846
|
+
if (referer) {
|
|
30847
|
+
try {
|
|
30848
|
+
candidates.add(new URL(referer).origin);
|
|
30849
|
+
} catch {
|
|
30850
|
+
}
|
|
30851
|
+
}
|
|
30852
|
+
for (const candidate of candidates) {
|
|
30853
|
+
if (candidate.startsWith("vscode-webview://")) return true;
|
|
30854
|
+
if ((app.ui?.csp?.frameDomains ?? []).includes(candidate)) return true;
|
|
30855
|
+
}
|
|
30856
|
+
return false;
|
|
30857
|
+
}
|
|
30478
30858
|
function outboundKindForExt(ext) {
|
|
30479
30859
|
const e = ext.toLowerCase();
|
|
30480
30860
|
if ([".png", ".jpg", ".jpeg", ".gif", ".webp"].includes(e)) return "photo";
|
|
@@ -30565,7 +30945,12 @@ async function handleAppUiToolCall(req, res, appId, appRegistry, deps2) {
|
|
|
30565
30945
|
tool = inner.tool;
|
|
30566
30946
|
args = inner.args && typeof inner.args === "object" && !Array.isArray(inner.args) ? inner.args : {};
|
|
30567
30947
|
}
|
|
30568
|
-
const
|
|
30948
|
+
const installed = appRegistry.getApp(appId);
|
|
30949
|
+
const result = installed?.ui ? await performAppToolCall(appRegistry, { appId, tool, args }, deps2) : await performBuiltinPanelToolCall(
|
|
30950
|
+
resolveBuiltinPanelUi(appId, requestHttpBaseUrl(req))?.tools,
|
|
30951
|
+
{ appId, tool, args },
|
|
30952
|
+
deps2
|
|
30953
|
+
);
|
|
30569
30954
|
res.writeHead(200, { "content-type": "application/json" });
|
|
30570
30955
|
res.end(JSON.stringify(result));
|
|
30571
30956
|
}
|
|
@@ -31177,6 +31562,14 @@ function createInboundEndpointStore(opts) {
|
|
|
31177
31562
|
}
|
|
31178
31563
|
|
|
31179
31564
|
// src/inbound-router.ts
|
|
31565
|
+
function attributeInboundText(msg) {
|
|
31566
|
+
const displayName = typeof msg.displayName === "string" && msg.displayName.trim() !== "" ? msg.displayName : void 0;
|
|
31567
|
+
const surface = typeof msg.surface === "string" && msg.surface.trim() !== "" ? msg.surface : void 0;
|
|
31568
|
+
if (!displayName && !surface) return msg.text;
|
|
31569
|
+
if (!surface) return `[${displayName}] ${msg.text}`;
|
|
31570
|
+
const name = displayName ?? msg.contactRef;
|
|
31571
|
+
return `[${name} \xB7 ${surface}] ${msg.text}`;
|
|
31572
|
+
}
|
|
31180
31573
|
async function routeInboundMessage(deps2, msg, mode) {
|
|
31181
31574
|
const log = deps2.log ?? (() => {
|
|
31182
31575
|
});
|
|
@@ -31199,7 +31592,7 @@ async function routeInboundMessage(deps2, msg, mode) {
|
|
|
31199
31592
|
return { action: "skipped" };
|
|
31200
31593
|
}
|
|
31201
31594
|
const routeInto = async (sessionId) => {
|
|
31202
|
-
await deps2.enqueuePrompt(sessionId, msg
|
|
31595
|
+
await deps2.enqueuePrompt(sessionId, attributeInboundText(msg), { queue: true });
|
|
31203
31596
|
deps2.bindings.upsert({
|
|
31204
31597
|
alias: binding.alias,
|
|
31205
31598
|
source: binding.source,
|
|
@@ -34728,6 +35121,63 @@ function registerSandboxAttachTool(server, opts = {}) {
|
|
|
34728
35121
|
);
|
|
34729
35122
|
}
|
|
34730
35123
|
|
|
35124
|
+
// src/sandbox-gc.ts
|
|
35125
|
+
var DEAD_SESSION_STATUSES = /* @__PURE__ */ new Set(["error", "killed", "exited"]);
|
|
35126
|
+
function collectGcCandidates(entries, sessionStatuses) {
|
|
35127
|
+
return entries.filter((e) => e.originSessionId !== void 0 && e.state !== "stopped").map((entry) => ({
|
|
35128
|
+
entry,
|
|
35129
|
+
sessionStatus: sessionStatuses.get(entry.originSessionId)
|
|
35130
|
+
})).filter(
|
|
35131
|
+
(c) => c.sessionStatus !== void 0 && DEAD_SESSION_STATUSES.has(c.sessionStatus)
|
|
35132
|
+
);
|
|
35133
|
+
}
|
|
35134
|
+
async function reapGcEntry(entry, opts) {
|
|
35135
|
+
let handle;
|
|
35136
|
+
try {
|
|
35137
|
+
handle = await opts.resolveProvider(entry.provider);
|
|
35138
|
+
} catch (err) {
|
|
35139
|
+
return {
|
|
35140
|
+
ok: false,
|
|
35141
|
+
error: `provider "${entry.provider}" could not be resolved \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
35142
|
+
};
|
|
35143
|
+
}
|
|
35144
|
+
if (!handle) return { ok: false, error: `provider "${entry.provider}" not found.` };
|
|
35145
|
+
if (!handle.provider.connect) {
|
|
35146
|
+
return {
|
|
35147
|
+
ok: false,
|
|
35148
|
+
error: `provider "${entry.provider}" has no connect() \u2014 cannot reach the existing box.`
|
|
35149
|
+
};
|
|
35150
|
+
}
|
|
35151
|
+
let booted;
|
|
35152
|
+
try {
|
|
35153
|
+
booted = await handle.provider.connect(
|
|
35154
|
+
entry.sandboxId,
|
|
35155
|
+
{ provider: entry.provider, config: {} },
|
|
35156
|
+
{ env: {} }
|
|
35157
|
+
);
|
|
35158
|
+
} catch (err) {
|
|
35159
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35160
|
+
if (/\b404\b|doesn't exist|does not exist|not found|no such/i.test(message)) {
|
|
35161
|
+
recordSandboxState(entry.sandboxId, "stopped", opts.ledgerPath);
|
|
35162
|
+
return { ok: true, action: "stopped" };
|
|
35163
|
+
}
|
|
35164
|
+
return { ok: false, error: `connect to "${entry.sandboxId}" failed \u2014 ${message}` };
|
|
35165
|
+
}
|
|
35166
|
+
const action = opts.pause === true && booted.pause ? "paused" : "stopped";
|
|
35167
|
+
try {
|
|
35168
|
+
if (action === "paused") await booted.pause();
|
|
35169
|
+
else await booted.stop();
|
|
35170
|
+
} catch (err) {
|
|
35171
|
+
return {
|
|
35172
|
+
ok: false,
|
|
35173
|
+
error: `tearing down "${entry.sandboxId}" failed \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
35174
|
+
};
|
|
35175
|
+
}
|
|
35176
|
+
recordSandboxState(entry.sandboxId, action, opts.ledgerPath);
|
|
35177
|
+
return { ok: true, action };
|
|
35178
|
+
}
|
|
35179
|
+
var GC_REAPABLE_STATES = ["booted", "connected", "paused"];
|
|
35180
|
+
|
|
34731
35181
|
// src/index.ts
|
|
34732
35182
|
init_tool_presenter();
|
|
34733
35183
|
var POLL_INTERVAL_MS2 = 200;
|
|
@@ -37909,7 +38359,30 @@ async function createGateway(opts) {
|
|
|
37909
38359
|
listSessions: listSessionsFiltered,
|
|
37910
38360
|
// httpBaseUrl = this daemon's own origin (SSE stream + bridge
|
|
37911
38361
|
// fallback for the live-session widget).
|
|
37912
|
-
httpBaseUrl: `http://127.0.0.1:${port}
|
|
38362
|
+
httpBaseUrl: `http://127.0.0.1:${port}`,
|
|
38363
|
+
// The session-chat widget is a thin launcher for the installed
|
|
38364
|
+
// `@agentik/session-chat` studio app — resolve installed-ness from
|
|
38365
|
+
// the AppRegistry at call time (not boot) so `app_install`/
|
|
38366
|
+
// `app_uninstall` of that app is reflected without a daemon restart.
|
|
38367
|
+
isSessionChatInstalled: () => {
|
|
38368
|
+
try {
|
|
38369
|
+
return appRegistry.getApp(SESSION_CHAT_APP_ID)?.ui != null;
|
|
38370
|
+
} catch {
|
|
38371
|
+
return false;
|
|
38372
|
+
}
|
|
38373
|
+
},
|
|
38374
|
+
// Work-board widget's read path — the root `/mcp` endpoint has no
|
|
38375
|
+
// scope, so this mount is always the operator caller (default
|
|
38376
|
+
// board `ws:<slug>`); `canAccessBoard` lets the operator read any
|
|
38377
|
+
// board (including a `tree:*` one) when an explicit boardId is
|
|
38378
|
+
// passed in from the panel's board switcher.
|
|
38379
|
+
listTasks: (boardId) => ({
|
|
38380
|
+
boardId: taskLedger.resolveBoardId({ kind: "operator" }, boardId),
|
|
38381
|
+
tasks: taskLedger.list(
|
|
38382
|
+
{ ...boardId ? { boardId } : {}, includeClosed: true },
|
|
38383
|
+
{ kind: "operator" }
|
|
38384
|
+
)
|
|
38385
|
+
})
|
|
37913
38386
|
}),
|
|
37914
38387
|
// Same ptyEnabled gate as terminal_start/terminal_input/… in
|
|
37915
38388
|
// session-tools.ts — the panel would be able to open the WS but
|
|
@@ -38312,6 +38785,6 @@ var export_providersPath = providers_store_exports.providersPath;
|
|
|
38312
38785
|
var export_removeProviderKey = providers_store_exports.removeProviderKey;
|
|
38313
38786
|
var export_setProviderKey = providers_store_exports.setProviderKey;
|
|
38314
38787
|
|
|
38315
|
-
export { AnthropicRemainingQuotaReader, AuthResolutionError, BUCKETS_ROOT, CLAUDE_CODE_OAUTH_SOURCE, DEFAULT_BUCKET, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, HarnessPresetValidationError, 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, addHarnessPreset, 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, createWorkspaceBrainSubscriber, createWorkspaceBrains, createWorkspaceFs, credentialFingerprint, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, decomposeMode, defineBraveSearchHttpDriver, defineSerperHttpDriver, deleteUserPreset, deriveSessionUsage, enrichRollupWithProviderQuota, enrichWithRemainingQuota, evaluateCostBudget, fileConversationStore, filterActivities, findConversationRecord, findNativeMode, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getMcpCredentialDeps, export_getProviderKey as getProviderKey, getUserPreset, harnessPresetsPath, export_injectProviderKeysIntoEnv as injectProviderKeysIntoEnv, isAgentCliAuthConfigured, isClosedTaskStatus, isSafeBucketSlug, isTerminalActivityState, listBuckets, listHarnessPresets, listPresets, listUserPresets, loadHarnessPresets, export_loadProviders as loadProviders, loadQuotaStore, loadUserPresets, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, 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, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapOrphanedDescendants, recordProfileQuota, registerBrainTools, registerBuiltinRoutes, registerPairingTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, export_removeProviderKey as removeProviderKey, removeSandboxLedgerEntry, resolveAuthSpec, resolveBucketSlug, resolveNativeLink, resolvePosture, resolveReuseFromLedger, resolveSpawnDefaults, resolveSubscriptionCredential, rollupUsage, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runStallWatchdogPass, sandboxLedgerPath, saveUserPreset, setDefaultPreset, setMcpCredentialDeps, export_setProviderKey as setProviderKey, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, userPresetsPath, verifyInboundSignature, webSearchTool, workflowToActivities, writeDaemonRegistryEntry };
|
|
38788
|
+
export { AnthropicRemainingQuotaReader, AuthResolutionError, BUCKETS_ROOT, CLAUDE_CODE_OAUTH_SOURCE, DEAD_SESSION_STATUSES, DEFAULT_BUCKET, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, GC_REAPABLE_STATES, HarnessPresetValidationError, 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, addHarnessPreset, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogModels, buildCatalogProviderModels, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, collectGcCandidates, composeMode, composeSessionObservers, conversationIndexPath, createActivityProjector, createFileStepCache, createGateway, createInboundEndpointStore, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPairingRegistry, createPrProvenanceReconciler, createReconnectLogGate, createScopeTokenRegistry, createSupervisorTaskGateRunner, createTaskLedger, createWorkspaceBrainSubscriber, createWorkspaceBrains, createWorkspaceFs, credentialFingerprint, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, decomposeMode, defineBraveSearchHttpDriver, defineSerperHttpDriver, deleteUserPreset, deriveSessionUsage, enrichRollupWithProviderQuota, enrichWithRemainingQuota, evaluateCostBudget, fileConversationStore, filterActivities, findConversationRecord, findNativeMode, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getMcpCredentialDeps, export_getProviderKey as getProviderKey, getUserPreset, harnessPresetsPath, export_injectProviderKeysIntoEnv as injectProviderKeysIntoEnv, isAgentCliAuthConfigured, isClosedTaskStatus, isSafeBucketSlug, isTerminalActivityState, listBuckets, listHarnessPresets, listPresets, listUserPresets, loadHarnessPresets, export_loadProviders as loadProviders, loadQuotaStore, loadUserPresets, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, 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, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, recordProfileQuota, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerPairingTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, export_removeProviderKey as removeProviderKey, removeSandboxLedgerEntry, resolveAuthSpec, resolveBucketSlug, resolveNativeLink, resolvePosture, resolveReuseFromLedger, resolveSpawnDefaults, resolveSubscriptionCredential, rollupUsage, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runStallWatchdogPass, sandboxLedgerPath, saveUserPreset, setDefaultPreset, setMcpCredentialDeps, export_setProviderKey as setProviderKey, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, userPresetsPath, verifyInboundSignature, webSearchTool, workflowToActivities, writeDaemonRegistryEntry };
|
|
38316
38789
|
//# sourceMappingURL=index.mjs.map
|
|
38317
38790
|
//# sourceMappingURL=index.mjs.map
|