negotium 0.22.6 → 0.22.7
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/agent-helpers.js +1349 -410
- package/dist/agent-helpers.js.map +7 -7
- package/dist/background-bash.js +12 -12
- package/dist/background-bash.js.map +2 -2
- package/dist/browser-runtime.js +81 -52
- package/dist/browser-runtime.js.map +4 -4
- package/dist/canonical-mcp-bridge.js +9 -8
- package/dist/canonical-mcp-bridge.js.map +1 -1
- package/dist/{chunk-e59kzyvy.js → chunk-1gznvrth.js} +5 -4
- package/dist/{chunk-e59kzyvy.js.map → chunk-1gznvrth.js.map} +2 -2
- package/dist/chunk-2mx7fq49.js +6 -0
- package/dist/{chunk-bnyvxss3.js.map → chunk-2mx7fq49.js.map} +1 -1
- package/dist/{chunk-1mba9m1j.js → chunk-9zn0bkc9.js} +116 -77
- package/dist/{chunk-1mba9m1j.js.map → chunk-9zn0bkc9.js.map} +2 -2
- package/dist/{chunk-ww8a4ej4.js → chunk-f7p0h1gs.js} +5 -5
- package/dist/{chunk-ww8a4ej4.js.map → chunk-f7p0h1gs.js.map} +2 -2
- package/dist/{chunk-9a50csg6.js → chunk-pr8p6pap.js} +125 -116
- package/dist/{chunk-9a50csg6.js.map → chunk-pr8p6pap.js.map} +7 -7
- package/dist/chunk-q5djsg78.js +200 -0
- package/dist/chunk-q5djsg78.js.map +9 -0
- package/dist/{chunk-1e0nxy7p.js → chunk-z4r7tt2p.js} +12 -12
- package/dist/{chunk-1e0nxy7p.js.map → chunk-z4r7tt2p.js.map} +2 -2
- package/dist/hosted-agent.js +128 -120
- package/dist/hosted-agent.js.map +4 -4
- package/dist/main.js +5174 -3278
- package/dist/main.js.map +9 -9
- package/dist/mcp-catalog.js +4 -4
- package/dist/mcp-catalog.js.map +1 -1
- package/dist/mcp-factories.js +1563 -632
- package/dist/mcp-factories.js.map +7 -7
- package/dist/mcp-servers.js +5 -5
- package/dist/mcp-servers.js.map +1 -1
- package/dist/media.js +3 -3
- package/dist/media.js.map +1 -1
- package/dist/outbox.js +15 -15
- package/dist/outbox.js.map +2 -2
- package/dist/platform-runtime.js +7 -7
- package/dist/platform-runtime.js.map +1 -1
- package/dist/prompts.js +6 -6
- package/dist/prompts.js.map +2 -2
- package/dist/query-runtime.js +18 -16
- package/dist/query-runtime.js.map +2 -2
- package/dist/registry.js +20 -19
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +41 -41
- package/dist/rollout.js.map +2 -2
- package/dist/runtime/src/platform/playwright/manager.ts +77 -15
- package/dist/runtime/src/storage/api-topics.ts +6 -0
- package/dist/runtime/src/storage/browser-profiles.ts +18 -0
- package/dist/runtime/src/topics/lifecycle.ts +2 -5
- package/dist/runtime/src/topics/update.ts +17 -0
- package/dist/runtime/src/types/api.ts +6 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-gateway.js +12 -12
- package/dist/runtime-gateway.js.map +2 -2
- package/dist/runtime-helpers.js +54 -52
- package/dist/runtime-helpers.js.map +2 -2
- package/dist/sqlite.js +5 -3
- package/dist/sqlite.js.map +2 -2
- package/dist/storage.js +640 -664
- package/dist/storage.js.map +3 -3
- package/dist/types/packages/core/src/platform/playwright/manager.d.ts +8 -0
- package/dist/types/packages/core/src/storage/api-topics.d.ts +1 -0
- package/dist/types/packages/core/src/storage/browser-profiles.d.ts +4 -0
- package/dist/types/packages/core/src/types/api.d.ts +6 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js +22 -20
- package/dist/vault.js.map +2 -2
- package/package.json +1 -1
- package/dist/chunk-bnyvxss3.js +0 -77
package/dist/agent-helpers.js
CHANGED
|
@@ -13,18 +13,9 @@ var __export = (target, all) => {
|
|
|
13
13
|
set: __exportSetter.bind(all, name)
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
|
-
var __esm = (fn, res
|
|
17
|
-
if (fn)
|
|
18
|
-
try {
|
|
19
|
-
res = fn(fn = 0);
|
|
20
|
-
} catch (e) {
|
|
21
|
-
err = [e];
|
|
22
|
-
}
|
|
23
|
-
if (err)
|
|
24
|
-
throw err[0];
|
|
25
|
-
return res;
|
|
26
|
-
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
27
17
|
var __promiseAll = (args) => Promise.all(args);
|
|
18
|
+
var __require = import.meta.require;
|
|
28
19
|
|
|
29
20
|
// ../../packages/core/src/platform/paths.ts
|
|
30
21
|
import { existsSync, realpathSync } from "fs";
|
|
@@ -193,6 +184,105 @@ var init_logger = __esm(() => {
|
|
|
193
184
|
});
|
|
194
185
|
|
|
195
186
|
// ../../packages/core/src/platform/config.ts
|
|
187
|
+
var exports_config = {};
|
|
188
|
+
__export(exports_config, {
|
|
189
|
+
resolveTopicWorkspaceDir: () => resolveTopicWorkspaceDir,
|
|
190
|
+
resolveOutputLanguage: () => resolveOutputLanguage,
|
|
191
|
+
resolveBrowserRsBin: () => resolveBrowserRsBin,
|
|
192
|
+
resolveBrowserProxy: () => resolveBrowserProxy,
|
|
193
|
+
resolveBrowserMcpBin: () => resolveBrowserMcpBin,
|
|
194
|
+
resolveBashRsBin: () => resolveBashRsBin,
|
|
195
|
+
isProductionEnv: () => isProductionEnv,
|
|
196
|
+
hostname: () => hostname,
|
|
197
|
+
getCleanEnv: () => getCleanEnv,
|
|
198
|
+
envText: () => envText,
|
|
199
|
+
codexAuthFilePath: () => codexAuthFilePath,
|
|
200
|
+
WORKSPACE_DIR: () => WORKSPACE_DIR,
|
|
201
|
+
WIKI_SERVER: () => WIKI_SERVER,
|
|
202
|
+
WHISPER_MODEL_MLX: () => WHISPER_MODEL_MLX,
|
|
203
|
+
WHISPER_MODEL: () => WHISPER_MODEL,
|
|
204
|
+
WHISPER_BACKEND: () => WHISPER_BACKEND,
|
|
205
|
+
VAULT_SERVER: () => VAULT_SERVER,
|
|
206
|
+
VAULT_MASTER_KEY: () => VAULT_MASTER_KEY,
|
|
207
|
+
VAULT_DIR: () => VAULT_DIR,
|
|
208
|
+
USERS_LOG_DIR: () => USERS_LOG_DIR,
|
|
209
|
+
UPLOADS_DIR: () => UPLOADS_DIR,
|
|
210
|
+
TSX_LOADER: () => TSX_LOADER,
|
|
211
|
+
TSX_BIN: () => TSX_BIN,
|
|
212
|
+
TSCONFIG_PATH: () => TSCONFIG_PATH,
|
|
213
|
+
TOPIC_WORKSPACE_DIR: () => TOPIC_WORKSPACE_DIR,
|
|
214
|
+
TOKEN_STATS_SERVER: () => TOKEN_STATS_SERVER,
|
|
215
|
+
TESSERACT_BIN: () => TESSERACT_BIN,
|
|
216
|
+
TASK_SERVER: () => TASK_SERVER,
|
|
217
|
+
SYSTEM_HEALTH_SERVER: () => SYSTEM_HEALTH_SERVER,
|
|
218
|
+
STATE_DIR: () => STATE_DIR,
|
|
219
|
+
SNIPPETS_API_URL: () => SNIPPETS_API_URL,
|
|
220
|
+
SHARED_WIKI_DIR: () => SHARED_WIKI_DIR,
|
|
221
|
+
SESSION_WORKSPACE_DIR: () => SESSION_WORKSPACE_DIR,
|
|
222
|
+
SESSION_INBOX_DIR: () => SESSION_INBOX_DIR,
|
|
223
|
+
SESSION_COMM_SERVER: () => SESSION_COMM_SERVER,
|
|
224
|
+
SESSION_ASKS_DIR: () => SESSION_ASKS_DIR,
|
|
225
|
+
SESSIONS_DB: () => SESSIONS_DB,
|
|
226
|
+
SECRETS_DIR: () => SECRETS_DIR,
|
|
227
|
+
RUN_DIR: () => RUN_DIR,
|
|
228
|
+
RUNTIME_MCP_SECRET: () => RUNTIME_MCP_SECRET,
|
|
229
|
+
RUNTIME_DIR: () => RUNTIME_DIR,
|
|
230
|
+
RESOURCES_DIR: () => RESOURCES_DIR,
|
|
231
|
+
PYTHON_BIN: () => PYTHON_BIN,
|
|
232
|
+
PROJECT_ROOT: () => PROJECT_ROOT,
|
|
233
|
+
PROGRESS_DIR: () => PROGRESS_DIR,
|
|
234
|
+
PLAYWRIGHT_PORTS_DIR: () => PLAYWRIGHT_PORTS_DIR,
|
|
235
|
+
PLAYWRIGHT_MCP_BIN: () => PLAYWRIGHT_MCP_BIN,
|
|
236
|
+
PLAYWRIGHT_MAX_PORT: () => PLAYWRIGHT_MAX_PORT,
|
|
237
|
+
PLAYWRIGHT_BASE_PORT: () => PLAYWRIGHT_BASE_PORT,
|
|
238
|
+
PDFTOTEXT_BIN: () => PDFTOTEXT_BIN,
|
|
239
|
+
NODE_ID: () => NODE_ID,
|
|
240
|
+
NODE_CONTROL_TOKEN: () => NODE_CONTROL_TOKEN,
|
|
241
|
+
NEGOTIUM_PORT: () => NEGOTIUM_PORT,
|
|
242
|
+
MODEL_SONNET: () => MODEL_SONNET,
|
|
243
|
+
MODEL_OPUS: () => MODEL_OPUS,
|
|
244
|
+
MODEL_HAIKU: () => MODEL_HAIKU,
|
|
245
|
+
MODEL_FABLE: () => MODEL_FABLE,
|
|
246
|
+
MODEL_DEEPSEEK_V4_PRO: () => MODEL_DEEPSEEK_V4_PRO,
|
|
247
|
+
MODEL_DEEPSEEK_V4_FLASH: () => MODEL_DEEPSEEK_V4_FLASH,
|
|
248
|
+
MLX_WHISPER_BIN: () => MLX_WHISPER_BIN,
|
|
249
|
+
MAX_TELL_DEPTH: () => MAX_TELL_DEPTH,
|
|
250
|
+
LOG_DIR: () => LOG_DIR,
|
|
251
|
+
FILE_TAG_REGEX: () => FILE_TAG_REGEX,
|
|
252
|
+
FILE_EXTENSIONS_REGEX: () => FILE_EXTENSIONS_REGEX,
|
|
253
|
+
FFPROBE_BIN: () => FFPROBE_BIN,
|
|
254
|
+
FFMPEG_BIN: () => FFMPEG_BIN,
|
|
255
|
+
FASTER_WHISPER_WRAPPER: () => FASTER_WHISPER_WRAPPER,
|
|
256
|
+
FALLBACK_MODEL: () => FALLBACK_MODEL,
|
|
257
|
+
FALLBACK_AGENT: () => FALLBACK_AGENT,
|
|
258
|
+
DM_WORKSPACE_DIR: () => DM_WORKSPACE_DIR,
|
|
259
|
+
DM_RESP_DIR: () => DM_RESP_DIR,
|
|
260
|
+
DM_CMD_DIR: () => DM_CMD_DIR,
|
|
261
|
+
DEFAULT_TOPIC_EFFORT: () => DEFAULT_TOPIC_EFFORT,
|
|
262
|
+
DEFAULT_OUTPUT_LANGUAGE: () => DEFAULT_OUTPUT_LANGUAGE,
|
|
263
|
+
DECISION_SERVER: () => DECISION_SERVER,
|
|
264
|
+
DEBUG_FILE: () => DEBUG_FILE,
|
|
265
|
+
DATA_DIR: () => DATA_DIR,
|
|
266
|
+
CRON_WORKSPACE_DIR: () => CRON_WORKSPACE_DIR,
|
|
267
|
+
COMPACTION_LOG_SERVER: () => COMPACTION_LOG_SERVER,
|
|
268
|
+
CLAUDE_EXECUTABLE: () => CLAUDE_EXECUTABLE,
|
|
269
|
+
CANONICAL_MCP_PROXY_SERVER: () => CANONICAL_MCP_PROXY_SERVER,
|
|
270
|
+
BROWSER_RS_VERSION: () => BROWSER_RS_VERSION,
|
|
271
|
+
BROWSER_RS_MIN_SECURE_VERSION: () => BROWSER_RS_MIN_SECURE_VERSION,
|
|
272
|
+
BROWSER_RS_BIN: () => BROWSER_RS_BIN,
|
|
273
|
+
BROWSER_PROFILES_DIR: () => BROWSER_PROFILES_DIR,
|
|
274
|
+
BROWSER_DIR: () => BROWSER_DIR,
|
|
275
|
+
BINARY_EXTENSION: () => BINARY_EXTENSION,
|
|
276
|
+
BINARIES_DIR: () => BINARIES_DIR,
|
|
277
|
+
BG_BASH_MAX_PORT: () => BG_BASH_MAX_PORT,
|
|
278
|
+
BG_BASH_BASE_PORT: () => BG_BASH_BASE_PORT,
|
|
279
|
+
BASH_RS_VERSION: () => BASH_RS_VERSION,
|
|
280
|
+
BASH_RS_BIN: () => BASH_RS_BIN,
|
|
281
|
+
BASHRS_SPILL_ROOT: () => BASHRS_SPILL_ROOT,
|
|
282
|
+
AGENT_HEALTH_SERVER: () => AGENT_HEALTH_SERVER,
|
|
283
|
+
AGENTS_PROMPTS_DIR: () => AGENTS_PROMPTS_DIR,
|
|
284
|
+
ACTIVE_QUERY_STALE_MS: () => ACTIVE_QUERY_STALE_MS
|
|
285
|
+
});
|
|
196
286
|
import { execFileSync } from "child_process";
|
|
197
287
|
import { randomBytes } from "crypto";
|
|
198
288
|
import {
|
|
@@ -342,6 +432,9 @@ function safeWorkspaceSegment(value, fallback) {
|
|
|
342
432
|
function resolveTopicWorkspaceDir(topicId) {
|
|
343
433
|
return join(TOPIC_WORKSPACE_DIR, safeWorkspaceSegment(topicId, "topic"));
|
|
344
434
|
}
|
|
435
|
+
function isProductionEnv() {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
345
438
|
function loadOrCreateLocalSecret(envKey, filename, options = {}) {
|
|
346
439
|
const envValue = envText(envKey);
|
|
347
440
|
const secretFile = resolve3(SECRETS_DIR, filename);
|
|
@@ -376,13 +469,18 @@ function loadOrCreateLocalSecret(envKey, filename, options = {}) {
|
|
|
376
469
|
return stored;
|
|
377
470
|
}
|
|
378
471
|
}
|
|
472
|
+
function getCleanEnv() {
|
|
473
|
+
const env = { ...process.env };
|
|
474
|
+
delete env.CLAUDECODE;
|
|
475
|
+
return env;
|
|
476
|
+
}
|
|
379
477
|
function resolveWhisperBackend() {
|
|
380
478
|
return envText("WHISPER_BACKEND") === "mlx-whisper" ? "mlx-whisper" : "faster-whisper";
|
|
381
479
|
}
|
|
382
480
|
function codexAuthFilePath() {
|
|
383
481
|
return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
|
|
384
482
|
}
|
|
385
|
-
var HOME, PROJECT_ROOT, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BINARY_EXTENSION, BROWSER_RS_VERSION = "v0.7.7", BROWSER_RS_MIN_SECURE_VERSION = "0.2.1", BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000, SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.10", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER_PATH, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, DECISION_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, NODE_ID, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, ABSOLUTE_PATH_PREFIX, FILE_EXTENSIONS_REGEX, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5-5", MODEL_FABLE = "claude-fable-5-1", FALLBACK_AGENT, FALLBACK_MODEL, DEFAULT_TOPIC_EFFORT, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, WHISPER_BACKEND, MLX_WHISPER_BIN, WHISPER_MODEL_MLX, _envMaxTellDepth, MAX_TELL_DEPTH;
|
|
483
|
+
var HOME, PROJECT_ROOT, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BINARY_EXTENSION, BROWSER_RS_VERSION = "v0.7.7", BROWSER_RS_MIN_SECURE_VERSION = "0.2.1", BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000, SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.10", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER_PATH, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, DECISION_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, NODE_ID, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, RUNTIME_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, ABSOLUTE_PATH_PREFIX, FILE_EXTENSIONS_REGEX, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5-5", MODEL_HAIKU = "claude-haiku-4-5-20251001", MODEL_FABLE = "claude-fable-5-1", MODEL_DEEPSEEK_V4_PRO = "deepseek-v4-pro", MODEL_DEEPSEEK_V4_FLASH = "deepseek-v4-flash", FALLBACK_AGENT, FALLBACK_MODEL, DEFAULT_TOPIC_EFFORT, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, WHISPER_BACKEND, MLX_WHISPER_BIN, WHISPER_MODEL_MLX, _envMaxTellDepth, MAX_TELL_DEPTH;
|
|
386
484
|
var init_config = __esm(() => {
|
|
387
485
|
init_config_helpers();
|
|
388
486
|
init_logger();
|
|
@@ -438,6 +536,7 @@ var init_config = __esm(() => {
|
|
|
438
536
|
DEBUG_FILE = resolve3(DATA_DIR, "debug-users.json");
|
|
439
537
|
USERS_LOG_DIR = resolve3(DATA_DIR, "users");
|
|
440
538
|
RUN_DIR = resolveLocalStateDir("NEGOTIUM_RUN_DIR", "runtime");
|
|
539
|
+
RUNTIME_DIR = RUN_DIR;
|
|
441
540
|
PROGRESS_DIR = resolve3(RUN_DIR, "progress");
|
|
442
541
|
DM_CMD_DIR = resolve3(RUN_DIR, "dm-commands");
|
|
443
542
|
DM_RESP_DIR = resolve3(RUN_DIR, "dm-responses");
|
|
@@ -670,6 +769,13 @@ function validateActorTopicScope(value) {
|
|
|
670
769
|
}
|
|
671
770
|
return { ok: true, scope };
|
|
672
771
|
}
|
|
772
|
+
function parseActorTopicScope(value) {
|
|
773
|
+
const validated = validateActorTopicScope(value);
|
|
774
|
+
return validated.ok ? validated.scope : null;
|
|
775
|
+
}
|
|
776
|
+
function actorTopicScopeFrom(value) {
|
|
777
|
+
return parseActorTopicScope(value) ?? undefined;
|
|
778
|
+
}
|
|
673
779
|
function intersectActorTopicScopes(scopes) {
|
|
674
780
|
if (scopes.length === 0 || scopes.some((scope) => scope === undefined))
|
|
675
781
|
return;
|
|
@@ -780,6 +886,13 @@ function validateRemoteSessionGrant(value) {
|
|
|
780
886
|
}
|
|
781
887
|
return { ok: true, grant: { hubUrl: hubUrl.url, capability } };
|
|
782
888
|
}
|
|
889
|
+
function parseRemoteSessionGrant(value) {
|
|
890
|
+
const validated = validateRemoteSessionGrant(value);
|
|
891
|
+
return validated.ok ? validated.grant : null;
|
|
892
|
+
}
|
|
893
|
+
function remoteSessionGrantFrom(value) {
|
|
894
|
+
return parseRemoteSessionGrant(value) ?? undefined;
|
|
895
|
+
}
|
|
783
896
|
function remoteSessionGrantExpiry(grant) {
|
|
784
897
|
const payload = grant.capability.split(".")[1];
|
|
785
898
|
if (!payload)
|
|
@@ -818,7 +931,7 @@ function encodeRemoteSessionGrantArg(grant) {
|
|
|
818
931
|
throw new Error("remoteSession is required");
|
|
819
932
|
return Buffer.from(JSON.stringify(validated.grant), "utf-8").toString("base64url");
|
|
820
933
|
}
|
|
821
|
-
var REMOTE_SESSION_GRANT_LIMITS, GRANT_KEYS, LOOPBACK_HOSTS, MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH;
|
|
934
|
+
var REMOTE_SESSION_GRANT_LIMITS, GRANT_KEYS, LOOPBACK_HOSTS, REMOTE_SESSION_REPLY_TOKEN_PATTERN, MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH;
|
|
822
935
|
var init_remote_session_grant = __esm(() => {
|
|
823
936
|
REMOTE_SESSION_GRANT_LIMITS = Object.freeze({
|
|
824
937
|
maxHubUrlLength: 512,
|
|
@@ -827,6 +940,7 @@ var init_remote_session_grant = __esm(() => {
|
|
|
827
940
|
});
|
|
828
941
|
GRANT_KEYS = ["hubUrl", "capability"];
|
|
829
942
|
LOOPBACK_HOSTS = new Set(["127.0.0.1", "::1", "[::1]", "localhost"]);
|
|
943
|
+
REMOTE_SESSION_REPLY_TOKEN_PATTERN = /^rsr1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
830
944
|
MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH = REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength;
|
|
831
945
|
});
|
|
832
946
|
|
|
@@ -1171,12 +1285,12 @@ function createBackgroundBashManager(options = {}) {
|
|
|
1171
1285
|
usedPorts.clear();
|
|
1172
1286
|
knownContexts.clear();
|
|
1173
1287
|
const deadline = now() + 3000;
|
|
1174
|
-
await Promise.all(entries.map((instance) => new Promise((
|
|
1288
|
+
await Promise.all(entries.map((instance) => new Promise((resolve4) => {
|
|
1175
1289
|
if (instance.process.exitCode !== null || instance.process.killed)
|
|
1176
|
-
return
|
|
1177
|
-
instance.process.once("exit",
|
|
1178
|
-
instance.process.once("error",
|
|
1179
|
-
const timer = setTimeout(
|
|
1290
|
+
return resolve4();
|
|
1291
|
+
instance.process.once("exit", resolve4);
|
|
1292
|
+
instance.process.once("error", resolve4);
|
|
1293
|
+
const timer = setTimeout(resolve4, Math.max(0, deadline - now()));
|
|
1180
1294
|
timer.unref?.();
|
|
1181
1295
|
})));
|
|
1182
1296
|
}
|
|
@@ -1878,7 +1992,7 @@ var init_api_messages = __esm(async () => {
|
|
|
1878
1992
|
|
|
1879
1993
|
// ../../packages/core/src/storage/topic-link-records.ts
|
|
1880
1994
|
function topicLinkSchemaIsCurrent(database, nodeId) {
|
|
1881
|
-
const objects = new Map(database.query("SELECT name, sql FROM sqlite_master WHERE type IN ('table','index','trigger')").all().map((
|
|
1995
|
+
const objects = new Map(database.query("SELECT name, sql FROM sqlite_master WHERE type IN ('table','index','trigger')").all().map((row2) => [row2.name, row2.sql ?? ""]));
|
|
1882
1996
|
for (const name of [...SCHEMA_TABLES, ...SCHEMA_INDEXES, ...SCHEMA_INDEXES_TOMBSTONES]) {
|
|
1883
1997
|
if (!objects.has(name))
|
|
1884
1998
|
return false;
|
|
@@ -1895,7 +2009,7 @@ function topicLinkSchemaIsCurrent(database, nodeId) {
|
|
|
1895
2009
|
return false;
|
|
1896
2010
|
}
|
|
1897
2011
|
const identity = database.query("SELECT node_id, epoch_id FROM api_node_identity WHERE singleton = 1").all();
|
|
1898
|
-
if (identity.some((
|
|
2012
|
+
if (identity.some((row2) => row2.epoch_id === null))
|
|
1899
2013
|
return false;
|
|
1900
2014
|
if (nodeId && identity[0]?.node_id !== nodeId)
|
|
1901
2015
|
return false;
|
|
@@ -2369,6 +2483,7 @@ function initializeApiTopicsSchema() {
|
|
|
2369
2483
|
surface_scope TEXT,
|
|
2370
2484
|
browser_profile TEXT NOT NULL DEFAULT 'default',
|
|
2371
2485
|
browser_profile_owner TEXT,
|
|
2486
|
+
browser_connect_port INTEGER,
|
|
2372
2487
|
session_id TEXT,
|
|
2373
2488
|
CHECK (
|
|
2374
2489
|
(kind = 'channel' AND response_policy = 'off' AND agent IS NULL) OR
|
|
@@ -2486,6 +2601,9 @@ function initializeApiTopicsSchema() {
|
|
|
2486
2601
|
if (!tableColumns("api_topics").has("browser_profile_owner")) {
|
|
2487
2602
|
db.exec("ALTER TABLE api_topics ADD COLUMN browser_profile_owner TEXT");
|
|
2488
2603
|
}
|
|
2604
|
+
if (!tableColumns("api_topics").has("browser_connect_port")) {
|
|
2605
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN browser_connect_port INTEGER");
|
|
2606
|
+
}
|
|
2489
2607
|
if (!tableColumns("api_topics").has("subagent_report_mode")) {
|
|
2490
2608
|
db.exec("ALTER TABLE api_topics ADD COLUMN subagent_report_mode TEXT NOT NULL DEFAULT 'auto'");
|
|
2491
2609
|
}
|
|
@@ -2723,12 +2841,16 @@ function rowToDto2(r, participants = getTopicParticipants(r.id), tellTargets) {
|
|
|
2723
2841
|
} : {},
|
|
2724
2842
|
visibility: normalizeTopicVisibility(r.visibility),
|
|
2725
2843
|
surface: normalizeTopicSurface(r.surface),
|
|
2726
|
-
surfaceScope: normalizeSurfaceScope(r.surface_scope)
|
|
2844
|
+
surfaceScope: normalizeSurfaceScope(r.surface_scope),
|
|
2845
|
+
...r.browser_connect_port != null ? { browserConnectPort: r.browser_connect_port } : {}
|
|
2727
2846
|
};
|
|
2728
2847
|
}
|
|
2729
2848
|
function normalizeTopicVisibility(value) {
|
|
2730
2849
|
return value === "hidden" ? "hidden" : "visible";
|
|
2731
2850
|
}
|
|
2851
|
+
function isTopicVisible(topic) {
|
|
2852
|
+
return topic.visibility !== "hidden";
|
|
2853
|
+
}
|
|
2732
2854
|
function normalizeTopicKind(value) {
|
|
2733
2855
|
return value === "channel" || value === "agent" || value === "manager" ? value : null;
|
|
2734
2856
|
}
|
|
@@ -5119,7 +5241,7 @@ var init_codex = __esm(async () => {
|
|
|
5119
5241
|
});
|
|
5120
5242
|
|
|
5121
5243
|
// ../../packages/core/src/version.ts
|
|
5122
|
-
var NEGOTIUM_VERSION = "0.22.
|
|
5244
|
+
var NEGOTIUM_VERSION = "0.22.7";
|
|
5123
5245
|
|
|
5124
5246
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
5125
5247
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -5195,7 +5317,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
5195
5317
|
stdio: ["pipe", "pipe", "pipe"],
|
|
5196
5318
|
windowsHide: true
|
|
5197
5319
|
});
|
|
5198
|
-
const refreshed = new Promise((
|
|
5320
|
+
const refreshed = new Promise((resolve7, reject) => {
|
|
5199
5321
|
let settled = false;
|
|
5200
5322
|
let stdoutBuffer = "";
|
|
5201
5323
|
let stderr = "";
|
|
@@ -5214,7 +5336,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
5214
5336
|
else if (!existsSync6(cachePath))
|
|
5215
5337
|
reject(new Error("Codex did not create its model cache"));
|
|
5216
5338
|
else
|
|
5217
|
-
|
|
5339
|
+
resolve7();
|
|
5218
5340
|
};
|
|
5219
5341
|
const send = (message) => {
|
|
5220
5342
|
child.stdin.write(`${JSON.stringify(message)}
|
|
@@ -5280,12 +5402,12 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
5280
5402
|
function waitForChildExit(child, timeoutMs) {
|
|
5281
5403
|
if (child.exitCode !== null || child.signalCode !== null)
|
|
5282
5404
|
return Promise.resolve();
|
|
5283
|
-
return new Promise((
|
|
5284
|
-
const timer = setTimeout(
|
|
5405
|
+
return new Promise((resolve7) => {
|
|
5406
|
+
const timer = setTimeout(resolve7, timeoutMs);
|
|
5285
5407
|
timer.unref?.();
|
|
5286
5408
|
child.once("exit", () => {
|
|
5287
5409
|
clearTimeout(timer);
|
|
5288
|
-
|
|
5410
|
+
resolve7();
|
|
5289
5411
|
});
|
|
5290
5412
|
});
|
|
5291
5413
|
}
|
|
@@ -5375,11 +5497,16 @@ var init_codex_native_multi_agent = __esm(() => {
|
|
|
5375
5497
|
});
|
|
5376
5498
|
|
|
5377
5499
|
// ../../packages/core/src/agents/codex-app-server.ts
|
|
5500
|
+
var exports_codex_app_server = {};
|
|
5501
|
+
__export(exports_codex_app_server, {
|
|
5502
|
+
forkCodexSession: () => forkCodexSession,
|
|
5503
|
+
createCodexAppServerForker: () => createCodexAppServerForker
|
|
5504
|
+
});
|
|
5378
5505
|
import { spawn as spawn3 } from "child_process";
|
|
5379
5506
|
function createCodexAppServerForker(host) {
|
|
5380
5507
|
return async (parentThreadId) => {
|
|
5381
5508
|
const child = host.spawnServer();
|
|
5382
|
-
return await new Promise((
|
|
5509
|
+
return await new Promise((resolve7, reject) => {
|
|
5383
5510
|
let settled = false;
|
|
5384
5511
|
let stdoutBuffer = "";
|
|
5385
5512
|
let stderr = "";
|
|
@@ -5396,7 +5523,7 @@ function createCodexAppServerForker(host) {
|
|
|
5396
5523
|
if (error)
|
|
5397
5524
|
reject(error);
|
|
5398
5525
|
else if (result)
|
|
5399
|
-
|
|
5526
|
+
resolve7(result);
|
|
5400
5527
|
else
|
|
5401
5528
|
reject(new Error("Codex thread fork returned no result"));
|
|
5402
5529
|
};
|
|
@@ -5533,8 +5660,8 @@ var init_codex_registry = __esm(async () => {
|
|
|
5533
5660
|
return { sessionId: threadId, rolloutPath };
|
|
5534
5661
|
},
|
|
5535
5662
|
async forkSession({ parentSessionId }) {
|
|
5536
|
-
await init_codex_app_server();
|
|
5537
|
-
return await
|
|
5663
|
+
const { forkCodexSession: forkCodexSession2 } = await init_codex_app_server().then(() => exports_codex_app_server);
|
|
5664
|
+
return await forkCodexSession2(parentSessionId);
|
|
5538
5665
|
},
|
|
5539
5666
|
async cleanupRollouts({ sessionIds }) {
|
|
5540
5667
|
if (sessionIds.length === 0)
|
|
@@ -5715,6 +5842,11 @@ var init_maestro_registry = __esm(() => {
|
|
|
5715
5842
|
});
|
|
5716
5843
|
|
|
5717
5844
|
// ../../packages/core/src/agents/registry.ts
|
|
5845
|
+
var exports_registry = {};
|
|
5846
|
+
__export(exports_registry, {
|
|
5847
|
+
getRegistryOperations: () => getRegistryOperations,
|
|
5848
|
+
getRegistry: () => getRegistry
|
|
5849
|
+
});
|
|
5718
5850
|
function getRegistry(agent) {
|
|
5719
5851
|
return REGISTRIES[agent];
|
|
5720
5852
|
}
|
|
@@ -6101,11 +6233,11 @@ var DEFAULT_CONTEXT_WARNING_RATIO = 0.8;
|
|
|
6101
6233
|
// ../../packages/core/src/agents/claude-provider.ts
|
|
6102
6234
|
var exports_claude_provider = {};
|
|
6103
6235
|
__export(exports_claude_provider, {
|
|
6104
|
-
|
|
6105
|
-
claudeBuiltInTools: () => claudeBuiltInTools,
|
|
6106
|
-
claudeProvider: () => claudeProvider,
|
|
6236
|
+
substituteClaudeToolInput: () => substituteClaudeToolInput,
|
|
6107
6237
|
spawnClaudeCodeProcessWithTreeKill: () => spawnClaudeCodeProcessWithTreeKill,
|
|
6108
|
-
|
|
6238
|
+
claudeProvider: () => claudeProvider,
|
|
6239
|
+
claudeBuiltInTools: () => claudeBuiltInTools,
|
|
6240
|
+
buildClaudeDisallowedTools: () => buildClaudeDisallowedTools
|
|
6109
6241
|
});
|
|
6110
6242
|
import { spawn as spawn4 } from "child_process";
|
|
6111
6243
|
import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
|
|
@@ -6186,8 +6318,8 @@ function buildClaudePrompt(opts) {
|
|
|
6186
6318
|
}
|
|
6187
6319
|
function watchClaudeProcessExit(signal) {
|
|
6188
6320
|
let listener;
|
|
6189
|
-
const exited = new Promise((
|
|
6190
|
-
listener =
|
|
6321
|
+
const exited = new Promise((resolve8) => {
|
|
6322
|
+
listener = resolve8;
|
|
6191
6323
|
const listeners = claudeProcessExitListeners.get(signal) ?? new Set;
|
|
6192
6324
|
listeners.add(listener);
|
|
6193
6325
|
claudeProcessExitListeners.set(signal, listeners);
|
|
@@ -6712,12 +6844,12 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
6712
6844
|
const previous = spawnChain;
|
|
6713
6845
|
let release;
|
|
6714
6846
|
let released = false;
|
|
6715
|
-
spawnChain = new Promise((
|
|
6847
|
+
spawnChain = new Promise((resolve8) => {
|
|
6716
6848
|
release = () => {
|
|
6717
6849
|
if (released)
|
|
6718
6850
|
return;
|
|
6719
6851
|
released = true;
|
|
6720
|
-
|
|
6852
|
+
resolve8();
|
|
6721
6853
|
};
|
|
6722
6854
|
});
|
|
6723
6855
|
await previous;
|
|
@@ -6824,7 +6956,7 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
6824
6956
|
return;
|
|
6825
6957
|
const deadline = Date.now() + Math.max(0, graceMs);
|
|
6826
6958
|
while (Date.now() < deadline && hasSurvivors(plan.targets)) {
|
|
6827
|
-
await new Promise((
|
|
6959
|
+
await new Promise((resolve8) => setTimeout(resolve8, Math.min(100, Math.max(1, deadline - Date.now()))));
|
|
6828
6960
|
}
|
|
6829
6961
|
killStragglers(plan);
|
|
6830
6962
|
}
|
|
@@ -7152,8 +7284,8 @@ async function createCodexVaultHookBridge(userId) {
|
|
|
7152
7284
|
});
|
|
7153
7285
|
restrictIpcEndpoint(socketPath);
|
|
7154
7286
|
if (IS_WINDOWS2) {
|
|
7155
|
-
await Promise.resolve().then(() => init_config());
|
|
7156
|
-
const cached = await ensureCodexWindowsWrapperExe(join13(
|
|
7287
|
+
const { BINARIES_DIR: BINARIES_DIR2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
7288
|
+
const cached = await ensureCodexWindowsWrapperExe(join13(BINARIES_DIR2, "codex-hook-wrapper"));
|
|
7157
7289
|
await copyFile(cached, wrapperPath);
|
|
7158
7290
|
await writeFile2(join13(root, "codex-with-hooks.cfg"), [process.execPath, codexCliScriptPath(), socketPath, token].join(`
|
|
7159
7291
|
`), { encoding: "utf8", mode: 384 });
|
|
@@ -7725,9 +7857,9 @@ var init_tool_format = __esm(() => {
|
|
|
7725
7857
|
// ../../packages/core/src/agents/codex-provider.ts
|
|
7726
7858
|
var exports_codex_provider = {};
|
|
7727
7859
|
__export(exports_codex_provider, {
|
|
7728
|
-
|
|
7860
|
+
toCodexMcpServers: () => toCodexMcpServers,
|
|
7729
7861
|
normalizeCodexTurnUsage: () => normalizeCodexTurnUsage,
|
|
7730
|
-
|
|
7862
|
+
codexProvider: () => codexProvider
|
|
7731
7863
|
});
|
|
7732
7864
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
7733
7865
|
import { existsSync as existsSync14, readFileSync as readFileSync11, realpathSync as realpathSync4, statSync as statSync5 } from "fs";
|
|
@@ -8027,9 +8159,9 @@ async function startStreamedWithTracking(thread, prompt, abortSignal, trackedPid
|
|
|
8027
8159
|
nextP.catch(() => {});
|
|
8028
8160
|
first = await Promise.race([nextP, startupTimeout]);
|
|
8029
8161
|
} catch (err) {
|
|
8030
|
-
const
|
|
8031
|
-
if (
|
|
8032
|
-
killCodexTrees(
|
|
8162
|
+
const novel2 = findNewCodexChildren(baseline);
|
|
8163
|
+
if (novel2.length > 0) {
|
|
8164
|
+
killCodexTrees(novel2);
|
|
8033
8165
|
}
|
|
8034
8166
|
await closeIterator(iter);
|
|
8035
8167
|
throw err;
|
|
@@ -8447,11 +8579,11 @@ var init_maestro_bootstrap_env = __esm(() => {
|
|
|
8447
8579
|
// ../../packages/core/src/agents/maestro-provider.ts
|
|
8448
8580
|
var exports_maestro_provider = {};
|
|
8449
8581
|
__export(exports_maestro_provider, {
|
|
8450
|
-
|
|
8451
|
-
buildMaestroToolHooks: () => buildMaestroToolHooks,
|
|
8452
|
-
buildMaestroToolResultTruncation: () => buildMaestroToolResultTruncation,
|
|
8582
|
+
resolveMaestroApiKeyOverrides: () => resolveMaestroApiKeyOverrides,
|
|
8453
8583
|
maestroProvider: () => maestroProvider,
|
|
8454
|
-
|
|
8584
|
+
buildMaestroToolResultTruncation: () => buildMaestroToolResultTruncation,
|
|
8585
|
+
buildMaestroToolHooks: () => buildMaestroToolHooks,
|
|
8586
|
+
buildMaestroDisallowedTools: () => buildMaestroDisallowedTools
|
|
8455
8587
|
});
|
|
8456
8588
|
import { resolve as resolve11 } from "path";
|
|
8457
8589
|
import { maestroProvider as sdkMaestroProvider, setMcpResolver } from "maestro-agent-sdk";
|
|
@@ -8579,18 +8711,18 @@ import { join as join15 } from "path";
|
|
|
8579
8711
|
async function* dispatchAgent(opts) {
|
|
8580
8712
|
switch (opts.agent) {
|
|
8581
8713
|
case "claude": {
|
|
8582
|
-
const { claudeProvider } = await loadClaudeProvider();
|
|
8583
|
-
yield*
|
|
8714
|
+
const { claudeProvider: claudeProvider2 } = await loadClaudeProvider();
|
|
8715
|
+
yield* claudeProvider2(opts);
|
|
8584
8716
|
return;
|
|
8585
8717
|
}
|
|
8586
8718
|
case "codex": {
|
|
8587
|
-
const { codexProvider } = await loadCodexProvider();
|
|
8588
|
-
yield*
|
|
8719
|
+
const { codexProvider: codexProvider2 } = await loadCodexProvider();
|
|
8720
|
+
yield* codexProvider2(opts);
|
|
8589
8721
|
return;
|
|
8590
8722
|
}
|
|
8591
8723
|
case "maestro": {
|
|
8592
|
-
const { maestroProvider } = await loadMaestroProvider();
|
|
8593
|
-
yield*
|
|
8724
|
+
const { maestroProvider: maestroProvider2 } = await loadMaestroProvider();
|
|
8725
|
+
yield* maestroProvider2(opts);
|
|
8594
8726
|
return;
|
|
8595
8727
|
}
|
|
8596
8728
|
default: {
|
|
@@ -8621,8 +8753,8 @@ async function resolveSessionFileMissing(agent, sessionId, cwd) {
|
|
|
8621
8753
|
return true;
|
|
8622
8754
|
}
|
|
8623
8755
|
case "maestro": {
|
|
8624
|
-
const { hasActiveMaestroSession, maestroSessionPath } = await import("maestro-agent-sdk");
|
|
8625
|
-
return !existsSync15(
|
|
8756
|
+
const { hasActiveMaestroSession, maestroSessionPath: maestroSessionPath2 } = await import("maestro-agent-sdk");
|
|
8757
|
+
return !existsSync15(maestroSessionPath2(sessionId)) && !hasActiveMaestroSession(sessionId);
|
|
8626
8758
|
}
|
|
8627
8759
|
default: {
|
|
8628
8760
|
const _exhaustive = agent;
|
|
@@ -8701,6 +8833,24 @@ var init_agents = __esm(async () => {
|
|
|
8701
8833
|
});
|
|
8702
8834
|
|
|
8703
8835
|
// ../../packages/core/src/agents/model-catalog.ts
|
|
8836
|
+
var exports_model_catalog = {};
|
|
8837
|
+
__export(exports_model_catalog, {
|
|
8838
|
+
selectableModel: () => selectableModel,
|
|
8839
|
+
resolveWorkerModel: () => resolveWorkerModel,
|
|
8840
|
+
resolveWorkerDefaultModel: () => resolveWorkerDefaultModel,
|
|
8841
|
+
resolveModelForAgent: () => resolveModelForAgent,
|
|
8842
|
+
resolveDefaultModel: () => resolveDefaultModel,
|
|
8843
|
+
resolveCompactionExecution: () => resolveCompactionExecution,
|
|
8844
|
+
modelOwner: () => modelOwner,
|
|
8845
|
+
formatSelectableModel: () => formatSelectableModel,
|
|
8846
|
+
canonicalModelId: () => canonicalModelId,
|
|
8847
|
+
SELECTABLE_MODELS: () => SELECTABLE_MODELS,
|
|
8848
|
+
MODEL_OWNER: () => MODEL_OWNER,
|
|
8849
|
+
MODEL_COST_ROUTING_SUMMARY: () => MODEL_COST_ROUTING_SUMMARY,
|
|
8850
|
+
MODEL_COST_RESEARCHED_AT: () => MODEL_COST_RESEARCHED_AT,
|
|
8851
|
+
FALLBACK_ORDER: () => FALLBACK_ORDER,
|
|
8852
|
+
AGENT_DISPLAY_NAME: () => AGENT_DISPLAY_NAME
|
|
8853
|
+
});
|
|
8704
8854
|
function canonicalModelId(value) {
|
|
8705
8855
|
const trimmed = value.trim();
|
|
8706
8856
|
const lower = trimmed.toLowerCase();
|
|
@@ -8710,6 +8860,10 @@ function formatSelectableModel(candidate) {
|
|
|
8710
8860
|
const tier = `${candidate.intelligenceTier[0].toUpperCase()}${candidate.intelligenceTier.slice(1)}`;
|
|
8711
8861
|
return `${candidate.agent} / \`${candidate.model}\` [${tier}-level]: ${candidate.routingSummary}`;
|
|
8712
8862
|
}
|
|
8863
|
+
function selectableModel(value) {
|
|
8864
|
+
const canonical = canonicalModelId(value).toLowerCase();
|
|
8865
|
+
return SELECTABLE_MODELS.find((candidate) => candidate.model === canonical);
|
|
8866
|
+
}
|
|
8713
8867
|
function modelOwner(model) {
|
|
8714
8868
|
const lower = model.toLowerCase();
|
|
8715
8869
|
if (lower.startsWith("claude-"))
|
|
@@ -8762,7 +8916,7 @@ function resolveCompactionExecution(agent, registry) {
|
|
|
8762
8916
|
const effort = registry.validateEffort("medium") ? "medium" : registry.defaultEffort;
|
|
8763
8917
|
return { model, ...effort ? { effort } : {} };
|
|
8764
8918
|
}
|
|
8765
|
-
var MODEL_OWNER, MODEL_COST_ROUTING_SUMMARY = "Cost basis (2026-09-05): Codex Pro 20x and Claude Max 20x are each $200/month; Maestro models are pay-per-token. DeepSeek Flash is cheapest. gpt-6-astra and Claude Fable 5.1 are the newest flagships, both priced at $10/M input / $50/M output.", CODEX_PRO_20X_COST = "ChatGPT Pro 20x subscription: $200/month", CODEX_COMMUNITY_WEEKLY = "Community plan-level observation: roughly 2\u20134B raw/cached tokens per week; fresh-input equivalent is much lower and unstable (low confidence)", CLAUDE_MAX_20X_COST = "Claude Max 20x subscription: $200/month", CLAUDE_COMMUNITY_SESSION = "Community observations vary from roughly 220\u2013250K locally displayed tokens per 5-hour session to billions of cache-heavy raw tokens per week; calibrated reports value a full weekly allowance around $680\u2013$1,900 at API rates. Recent heavy-model reports reach the weekly cap after about 4\u20135 full sessions (low confidence; not a token cap)", SELECTABLE_MODELS, SELECTABLE_MODEL_ALIASES, CANONICAL_MODEL_CASING, AGENT_DISPLAY_NAME;
|
|
8919
|
+
var MODEL_OWNER, MODEL_COST_RESEARCHED_AT = "2026-09-05", MODEL_COST_ROUTING_SUMMARY = "Cost basis (2026-09-05): Codex Pro 20x and Claude Max 20x are each $200/month; Maestro models are pay-per-token. DeepSeek Flash is cheapest. gpt-6-astra and Claude Fable 5.1 are the newest flagships, both priced at $10/M input / $50/M output.", CODEX_PRO_20X_COST = "ChatGPT Pro 20x subscription: $200/month", CODEX_COMMUNITY_WEEKLY = "Community plan-level observation: roughly 2\u20134B raw/cached tokens per week; fresh-input equivalent is much lower and unstable (low confidence)", CLAUDE_MAX_20X_COST = "Claude Max 20x subscription: $200/month", CLAUDE_COMMUNITY_SESSION = "Community observations vary from roughly 220\u2013250K locally displayed tokens per 5-hour session to billions of cache-heavy raw tokens per week; calibrated reports value a full weekly allowance around $680\u2013$1,900 at API rates. Recent heavy-model reports reach the weekly cap after about 4\u20135 full sessions (low confidence; not a token cap)", SELECTABLE_MODELS, SELECTABLE_MODEL_ALIASES, CANONICAL_MODEL_CASING, FALLBACK_ORDER, AGENT_DISPLAY_NAME;
|
|
8766
8920
|
var init_model_catalog = __esm(() => {
|
|
8767
8921
|
init_config();
|
|
8768
8922
|
MODEL_OWNER = {
|
|
@@ -8934,6 +9088,20 @@ var init_model_catalog = __esm(() => {
|
|
|
8934
9088
|
"glm-flash": "glm-5.3-flash"
|
|
8935
9089
|
};
|
|
8936
9090
|
CANONICAL_MODEL_CASING = Object.fromEntries(SELECTABLE_MODELS.map((candidate) => [candidate.model.toLowerCase(), candidate.model]));
|
|
9091
|
+
FALLBACK_ORDER = {
|
|
9092
|
+
claude: [
|
|
9093
|
+
{ agent: "maestro", model: "deepseek-pro" },
|
|
9094
|
+
{ agent: "codex", model: "gpt-6-luna" }
|
|
9095
|
+
],
|
|
9096
|
+
codex: [
|
|
9097
|
+
{ agent: "maestro", model: "deepseek-pro" },
|
|
9098
|
+
{ agent: "claude", model: "sonnet" }
|
|
9099
|
+
],
|
|
9100
|
+
maestro: [
|
|
9101
|
+
{ agent: "codex", model: "gpt-6-luna" },
|
|
9102
|
+
{ agent: "claude", model: "sonnet" }
|
|
9103
|
+
]
|
|
9104
|
+
};
|
|
8937
9105
|
AGENT_DISPLAY_NAME = {
|
|
8938
9106
|
claude: "Claude",
|
|
8939
9107
|
codex: "Codex",
|
|
@@ -9682,9 +9850,9 @@ function resolveTopicBrief(topicId, legacyTitle) {
|
|
|
9682
9850
|
const titleBrief = getTopicBrief(titleKey);
|
|
9683
9851
|
if (titleBrief)
|
|
9684
9852
|
return { brief: titleBrief, storageKey: titleKey };
|
|
9685
|
-
const
|
|
9686
|
-
if (
|
|
9687
|
-
return { brief:
|
|
9853
|
+
const current2 = getTopicBrief(topicId);
|
|
9854
|
+
if (current2)
|
|
9855
|
+
return { brief: current2, storageKey: topicId };
|
|
9688
9856
|
const legacy = titleKey === legacyTitle ? null : getTopicBrief(legacyTitle);
|
|
9689
9857
|
return legacy ? { brief: legacy, storageKey: legacyTitle } : null;
|
|
9690
9858
|
}
|
|
@@ -10304,6 +10472,11 @@ var init_archiver = __esm(async () => {
|
|
|
10304
10472
|
});
|
|
10305
10473
|
|
|
10306
10474
|
// ../../packages/core/src/agents/auth-check.ts
|
|
10475
|
+
var exports_auth_check = {};
|
|
10476
|
+
__export(exports_auth_check, {
|
|
10477
|
+
checkAgentModelAuth: () => checkAgentModelAuth,
|
|
10478
|
+
checkAgentAuth: () => checkAgentAuth
|
|
10479
|
+
});
|
|
10307
10480
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
10308
10481
|
import { existsSync as existsSync17 } from "fs";
|
|
10309
10482
|
import { homedir as homedir8, platform } from "os";
|
|
@@ -10635,8 +10808,8 @@ function createRoomQueryRegistry(host) {
|
|
|
10635
10808
|
clearInterval(previousMonitor);
|
|
10636
10809
|
activeByRoom.set(roomId, control);
|
|
10637
10810
|
const monitor = setInterval(() => {
|
|
10638
|
-
const
|
|
10639
|
-
if (!
|
|
10811
|
+
const current2 = activeByRoom.get(roomId);
|
|
10812
|
+
if (!current2 || current2.queryId !== control.queryId) {
|
|
10640
10813
|
clearInterval(monitor);
|
|
10641
10814
|
if (leaseMonitors.get(roomId) === monitor)
|
|
10642
10815
|
leaseMonitors.delete(roomId);
|
|
@@ -10658,8 +10831,8 @@ function createRoomQueryRegistry(host) {
|
|
|
10658
10831
|
return true;
|
|
10659
10832
|
}
|
|
10660
10833
|
function clear(roomId, queryId) {
|
|
10661
|
-
const
|
|
10662
|
-
if (
|
|
10834
|
+
const current2 = activeByRoom.get(roomId);
|
|
10835
|
+
if (current2?.queryId === queryId) {
|
|
10663
10836
|
activeByRoom.delete(roomId);
|
|
10664
10837
|
const monitor = leaseMonitors.get(roomId);
|
|
10665
10838
|
if (monitor)
|
|
@@ -10722,12 +10895,43 @@ var init_room_query_registry = () => {};
|
|
|
10722
10895
|
var init_types2 = () => {};
|
|
10723
10896
|
|
|
10724
10897
|
// ../../packages/core/src/query/active-rooms.ts
|
|
10898
|
+
var exports_active_rooms = {};
|
|
10899
|
+
__export(exports_active_rooms, {
|
|
10900
|
+
wsAbortReason: () => wsAbortReason,
|
|
10901
|
+
takeDeferredInject: () => takeDeferredInject,
|
|
10902
|
+
setRoomQuery: () => setRoomQuery,
|
|
10903
|
+
listRunningTopicQueries: () => listRunningTopicQueries,
|
|
10904
|
+
listRunningTopicIds: () => listRunningTopicIds,
|
|
10905
|
+
isolatedTurnRoomId: () => isolatedTurnRoomId,
|
|
10906
|
+
isUserOrigin: () => isUserOrigin,
|
|
10907
|
+
isTopicRunning: () => isTopicRunning,
|
|
10908
|
+
interSessionQueue: () => interSessionQueue,
|
|
10909
|
+
getRoomQueryStatus: () => getRoomQueryStatus,
|
|
10910
|
+
getRoomQuery: () => getRoomQuery,
|
|
10911
|
+
deferInject: () => deferInject,
|
|
10912
|
+
decideNewQuery: () => decideNewQuery,
|
|
10913
|
+
clearRoomQuery: () => clearRoomQuery,
|
|
10914
|
+
cancelDeferredInject: () => cancelDeferredInject,
|
|
10915
|
+
abortRoom: () => abortRoom,
|
|
10916
|
+
abortAllRooms: () => abortAllRooms,
|
|
10917
|
+
InterSessionQueue: () => InterSessionQueue,
|
|
10918
|
+
DeferredInjectBatcher: () => DeferredInjectBatcher
|
|
10919
|
+
});
|
|
10725
10920
|
function getRoomQuery(roomId) {
|
|
10726
10921
|
return roomQueryRegistry.get(roomId);
|
|
10727
10922
|
}
|
|
10923
|
+
function listRunningTopicQueries() {
|
|
10924
|
+
return roomQueryRegistry.listRunningTopicQueries();
|
|
10925
|
+
}
|
|
10926
|
+
function listRunningTopicIds() {
|
|
10927
|
+
return roomQueryRegistry.listRunningTopicIds();
|
|
10928
|
+
}
|
|
10728
10929
|
function isTopicRunning(topicId) {
|
|
10729
10930
|
return roomQueryRegistry.isTopicRunning(topicId);
|
|
10730
10931
|
}
|
|
10932
|
+
function getRoomQueryStatus(topicId, queryId) {
|
|
10933
|
+
return roomQueryRegistry.status(topicId, queryId);
|
|
10934
|
+
}
|
|
10731
10935
|
function setRoomQuery(control) {
|
|
10732
10936
|
return roomQueryRegistry.set(control);
|
|
10733
10937
|
}
|
|
@@ -10737,6 +10941,9 @@ function clearRoomQuery(roomId, queryId) {
|
|
|
10737
10941
|
function abortRoom(roomId, reason = "external" /* External */) {
|
|
10738
10942
|
return roomQueryRegistry.abort(roomId, reason);
|
|
10739
10943
|
}
|
|
10944
|
+
function abortAllRooms(reason = "external" /* External */) {
|
|
10945
|
+
return roomQueryRegistry.abortAll(reason);
|
|
10946
|
+
}
|
|
10740
10947
|
function decideNewQuery(topicId, incomingOrigin) {
|
|
10741
10948
|
return roomQueryRegistry.decide(topicId, incomingOrigin);
|
|
10742
10949
|
}
|
|
@@ -10902,6 +11109,9 @@ function deferInject(inject) {
|
|
|
10902
11109
|
function takeDeferredInject(topicId) {
|
|
10903
11110
|
return interSessionQueue.dequeueAll(topicId);
|
|
10904
11111
|
}
|
|
11112
|
+
function cancelDeferredInject(topicId, requestId) {
|
|
11113
|
+
return interSessionQueue.remove(topicId, requestId) !== undefined;
|
|
11114
|
+
}
|
|
10905
11115
|
function wsAbortReason(reason) {
|
|
10906
11116
|
return reason === "internal" /* Internal */ ? "superseded" : "stopped";
|
|
10907
11117
|
}
|
|
@@ -11194,8 +11404,8 @@ function settleTopicArchiveJob(topicId, archivePath, success) {
|
|
|
11194
11404
|
db.query("UPDATE api_topic_archive_jobs SET status = 'pending', updated_at = ? WHERE topic_id = ? AND archive_path = ?").run(new Date().toISOString(), topicId, archivePath);
|
|
11195
11405
|
return;
|
|
11196
11406
|
}
|
|
11197
|
-
const
|
|
11198
|
-
setTopicArchiveState(topicId, Math.max(
|
|
11407
|
+
const current2 = getTopicArchiveState(topicId)?.lastArchivedRowid ?? 0;
|
|
11408
|
+
setTopicArchiveState(topicId, Math.max(current2, job.last_rowid), job.archive_path);
|
|
11199
11409
|
db.query("DELETE FROM api_topic_archive_jobs WHERE topic_id = ? AND archive_path = ?").run(topicId, archivePath);
|
|
11200
11410
|
})();
|
|
11201
11411
|
}
|
|
@@ -11867,7 +12077,7 @@ function createAskUserRuntime(host) {
|
|
|
11867
12077
|
if (ask.expired || ask.selectedLabel) {
|
|
11868
12078
|
return { ok: false, error: "This question is no longer awaiting an answer." };
|
|
11869
12079
|
}
|
|
11870
|
-
if (!ask.choices.some((
|
|
12080
|
+
if (!ask.choices.some((choice2) => choice2.label === label)) {
|
|
11871
12081
|
return { ok: false, error: "Invalid choice." };
|
|
11872
12082
|
}
|
|
11873
12083
|
const pending = pendingAsks.get(messageId);
|
|
@@ -12020,8 +12230,8 @@ function createAskUserRuntime(host) {
|
|
|
12020
12230
|
return errorResult(`Error: failed to persist ask_user_question: ${error instanceof Error ? error.message : String(error)}`);
|
|
12021
12231
|
}
|
|
12022
12232
|
let resolveAnswer;
|
|
12023
|
-
const promise = new Promise((
|
|
12024
|
-
resolveAnswer =
|
|
12233
|
+
const promise = new Promise((resolve13) => {
|
|
12234
|
+
resolveAnswer = resolve13;
|
|
12025
12235
|
});
|
|
12026
12236
|
pendingAsks.set(message.id, {
|
|
12027
12237
|
topicId: ctx.topicId,
|
|
@@ -12223,8 +12433,8 @@ var init_self_schedules = __esm(async () => {
|
|
|
12223
12433
|
});
|
|
12224
12434
|
|
|
12225
12435
|
// ../../packages/core/src/platform/playwright/manager-utils.ts
|
|
12226
|
-
function isLiveOwnedChildProcess(
|
|
12227
|
-
return
|
|
12436
|
+
function isLiveOwnedChildProcess(current2, expected) {
|
|
12437
|
+
return current2?.process === expected && expected.exitCode === null && expected.signalCode === null && !expected.killed;
|
|
12228
12438
|
}
|
|
12229
12439
|
function matchesSpawnedBrowserHealth(health, expectedSpawnNonce) {
|
|
12230
12440
|
if (!health || typeof health !== "object")
|
|
@@ -12468,10 +12678,10 @@ function findExecutableOnPath(command, environment = process.env) {
|
|
|
12468
12678
|
return null;
|
|
12469
12679
|
}
|
|
12470
12680
|
function resolveHeadedPlaywrightSpawn(command, args, options = {}) {
|
|
12471
|
-
const
|
|
12681
|
+
const platform2 = options.platform ?? process.platform;
|
|
12472
12682
|
const environment = options.environment ?? process.env;
|
|
12473
12683
|
const hasDisplay = Boolean(environment.DISPLAY?.trim() || environment.WAYLAND_DISPLAY?.trim());
|
|
12474
|
-
if (
|
|
12684
|
+
if (platform2 !== "linux" || hasDisplay) {
|
|
12475
12685
|
return { command, args: [...args], virtualDisplay: false };
|
|
12476
12686
|
}
|
|
12477
12687
|
const xvfbRun = (options.findExecutable ?? findExecutableOnPath)("xvfb-run", environment);
|
|
@@ -12520,7 +12730,7 @@ async function probeMcpTransport(transport, options = {}) {
|
|
|
12520
12730
|
}
|
|
12521
12731
|
}
|
|
12522
12732
|
async function probePlaywrightMcpTransports(port, capability, fetchImpl = fetch) {
|
|
12523
|
-
const
|
|
12733
|
+
const query2 = new URLSearchParams({ owner: PROBE_OWNER });
|
|
12524
12734
|
const baseUrl = `http://127.0.0.1:${port}`;
|
|
12525
12735
|
const ownerCapability = browserOwnerCapability(capability, PROBE_OWNER);
|
|
12526
12736
|
const capabilityHeaders = { "X-Browser-Capability": ownerCapability };
|
|
@@ -12529,14 +12739,14 @@ async function probePlaywrightMcpTransports(port, capability, fetchImpl = fetch)
|
|
|
12529
12739
|
headers.set("X-Browser-Capability", ownerCapability);
|
|
12530
12740
|
return fetchImpl(input, { ...init, headers });
|
|
12531
12741
|
};
|
|
12532
|
-
const sseTransport = new SSEClientTransport(new URL(`${baseUrl}/sse?${
|
|
12742
|
+
const sseTransport = new SSEClientTransport(new URL(`${baseUrl}/sse?${query2}`), {
|
|
12533
12743
|
fetch: authenticatedFetch,
|
|
12534
12744
|
eventSourceInit: { fetch: authenticatedFetch },
|
|
12535
12745
|
requestInit: { headers: capabilityHeaders }
|
|
12536
12746
|
});
|
|
12537
12747
|
if (!await probeMcpTransport(sseTransport))
|
|
12538
12748
|
return false;
|
|
12539
|
-
const streamableTransport = new StreamableHTTPClientTransport(new URL(`${baseUrl}/mcp?${
|
|
12749
|
+
const streamableTransport = new StreamableHTTPClientTransport(new URL(`${baseUrl}/mcp?${query2}`), {
|
|
12540
12750
|
fetch: authenticatedFetch,
|
|
12541
12751
|
requestInit: { headers: capabilityHeaders }
|
|
12542
12752
|
});
|
|
@@ -12666,9 +12876,9 @@ async function createBrowserVaultBroker(userId) {
|
|
|
12666
12876
|
if (typeof request.tool !== "string")
|
|
12667
12877
|
return { id, ok: false, error: "invalid tool" };
|
|
12668
12878
|
const leaseCutoff = Date.now() - LEASE_TTL_MS;
|
|
12669
|
-
for (const [
|
|
12879
|
+
for (const [lease2, binding] of leases) {
|
|
12670
12880
|
if (binding.createdAt < leaseCutoff)
|
|
12671
|
-
leases.delete(
|
|
12881
|
+
leases.delete(lease2);
|
|
12672
12882
|
}
|
|
12673
12883
|
if (leases.size >= MAX_ACTIVE_LEASES) {
|
|
12674
12884
|
return { id, ok: false, error: "too many active leases" };
|
|
@@ -12802,6 +13012,16 @@ function getTopicBrowserProfile(topicId) {
|
|
|
12802
13012
|
const value = db.query("SELECT browser_profile FROM api_topics WHERE id = ?").get(topicId)?.browser_profile;
|
|
12803
13013
|
return value || DEFAULT_BROWSER_PROFILE;
|
|
12804
13014
|
}
|
|
13015
|
+
function isBrowserConnectPort(value) {
|
|
13016
|
+
return Number.isInteger(value) && value >= 1024 && value <= 65535;
|
|
13017
|
+
}
|
|
13018
|
+
function getTopicBrowserConnectPort(topicId) {
|
|
13019
|
+
const value = db.query("SELECT browser_connect_port FROM api_topics WHERE id = ?").get(topicId)?.browser_connect_port;
|
|
13020
|
+
return isBrowserConnectPort(value) ? value : undefined;
|
|
13021
|
+
}
|
|
13022
|
+
function setTopicBrowserConnectPort(topicId, port) {
|
|
13023
|
+
db.query("UPDATE api_topics SET browser_connect_port = ? WHERE id = ?").run(port, topicId);
|
|
13024
|
+
}
|
|
12805
13025
|
function hasBrowserProfileTopic(topicId) {
|
|
12806
13026
|
return Boolean(db.query("SELECT id FROM api_topics WHERE id = ?").get(topicId));
|
|
12807
13027
|
}
|
|
@@ -12878,6 +13098,9 @@ function resolvePlaywrightTopicBinding(userId, topic) {
|
|
|
12878
13098
|
function defaultTopicBinding(userId, topic) {
|
|
12879
13099
|
if (!topic)
|
|
12880
13100
|
return managerHost.resolveNamedBinding(userId, "default");
|
|
13101
|
+
const connectPort = getTopicBrowserConnectPort(topic);
|
|
13102
|
+
if (connectPort !== undefined)
|
|
13103
|
+
return connectBinding(connectPort);
|
|
12881
13104
|
const ownerId = getBrowserProfileOwner(topic, userId);
|
|
12882
13105
|
const profile = getTopicBrowserProfile(topic);
|
|
12883
13106
|
return managerHost.resolveNamedBinding(ownerId, profile);
|
|
@@ -12891,6 +13114,26 @@ function validateProfileBinding(binding) {
|
|
|
12891
13114
|
}
|
|
12892
13115
|
return Object.freeze({ ...binding });
|
|
12893
13116
|
}
|
|
13117
|
+
function connectBinding(port) {
|
|
13118
|
+
return { instanceKey: `connect:${port}`, ownerId: "local", profile: `connect-${port}` };
|
|
13119
|
+
}
|
|
13120
|
+
function parseConnectInstanceKey(instanceKey) {
|
|
13121
|
+
const match = /^connect:(\d+)$/.exec(instanceKey);
|
|
13122
|
+
return match ? Number(match[1]) : undefined;
|
|
13123
|
+
}
|
|
13124
|
+
function browserRsArgs(instanceKey, port, userDataDir) {
|
|
13125
|
+
const connectPort = parseConnectInstanceKey(instanceKey);
|
|
13126
|
+
return [
|
|
13127
|
+
"--port",
|
|
13128
|
+
String(port),
|
|
13129
|
+
"--host",
|
|
13130
|
+
"127.0.0.1",
|
|
13131
|
+
"--headed",
|
|
13132
|
+
"--user-data-dir",
|
|
13133
|
+
userDataDir,
|
|
13134
|
+
...connectPort === undefined ? [] : ["--connect", String(connectPort)]
|
|
13135
|
+
];
|
|
13136
|
+
}
|
|
12894
13137
|
function defaultNamedBinding(_ownerId, rawProfile) {
|
|
12895
13138
|
const profile = normalizeBrowserProfileName(rawProfile);
|
|
12896
13139
|
const instanceKey = `profile:${profile}`;
|
|
@@ -12910,6 +13153,9 @@ function defaultChildEnvironment(context) {
|
|
|
12910
13153
|
return childEnvironment;
|
|
12911
13154
|
}
|
|
12912
13155
|
function parseInstanceKey(instanceKey) {
|
|
13156
|
+
const connectPort = parseConnectInstanceKey(instanceKey);
|
|
13157
|
+
if (connectPort !== undefined)
|
|
13158
|
+
return { ownerId: "local", profile: `_connect-${connectPort}` };
|
|
12913
13159
|
const shared = /^profile:(.+)$/.exec(instanceKey);
|
|
12914
13160
|
if (shared && !shared[1].includes(":")) {
|
|
12915
13161
|
return { ownerId: "local", profile: normalizeBrowserProfileName(shared[1]) };
|
|
@@ -13137,15 +13383,7 @@ async function spawnPlaywright(instanceKey, ownerId, reservedPort, browserBin =
|
|
|
13137
13383
|
const userDataDir = resolveUserDataDir(instanceKey);
|
|
13138
13384
|
const port = reservedPort ?? await allocatePort();
|
|
13139
13385
|
mkdirSync11(userDataDir, { recursive: true });
|
|
13140
|
-
const mcpArgs =
|
|
13141
|
-
"--port",
|
|
13142
|
-
String(port),
|
|
13143
|
-
"--host",
|
|
13144
|
-
"127.0.0.1",
|
|
13145
|
-
"--headed",
|
|
13146
|
-
"--user-data-dir",
|
|
13147
|
-
userDataDir
|
|
13148
|
-
];
|
|
13386
|
+
const mcpArgs = browserRsArgs(instanceKey, port, userDataDir);
|
|
13149
13387
|
const proxy = managerHost.resolveProxy();
|
|
13150
13388
|
if (proxy) {
|
|
13151
13389
|
releasePort(port);
|
|
@@ -13201,9 +13439,9 @@ async function spawnPlaywright(instanceKey, ownerId, reservedPort, browserBin =
|
|
|
13201
13439
|
const stderrTail = captureBoundedStderr(proc);
|
|
13202
13440
|
const startup = watchChildStartup(proc, stderrTail);
|
|
13203
13441
|
const reapCrashedBrowser = () => {
|
|
13204
|
-
const
|
|
13205
|
-
managerHost.cleanupBrowserProcessesForDataDir(
|
|
13206
|
-
cleanSingletonFiles(
|
|
13442
|
+
const userDataDir2 = resolveUserDataDir(instanceKey);
|
|
13443
|
+
managerHost.cleanupBrowserProcessesForDataDir(userDataDir2);
|
|
13444
|
+
cleanSingletonFiles(userDataDir2);
|
|
13207
13445
|
};
|
|
13208
13446
|
proc.once("error", (err) => {
|
|
13209
13447
|
logger.error({ err, instanceKey, stderr: stderrTail() || undefined }, "Playwright MCP error");
|
|
@@ -13272,8 +13510,8 @@ ${stderrTail()}` : ""));
|
|
|
13272
13510
|
}
|
|
13273
13511
|
async function supportsOwnerCleanup(port, capability) {
|
|
13274
13512
|
try {
|
|
13275
|
-
const
|
|
13276
|
-
const response = await fetch(`http://127.0.0.1:${port}/owners?${
|
|
13513
|
+
const query2 = new URLSearchParams({ owner: "__negotium_capability_probe__" });
|
|
13514
|
+
const response = await fetch(`http://127.0.0.1:${port}/owners?${query2}`, {
|
|
13277
13515
|
method: "DELETE",
|
|
13278
13516
|
headers: {
|
|
13279
13517
|
"X-Browser-Capability": capability
|
|
@@ -13333,8 +13571,12 @@ async function waitForPortRelease(port, timeoutMs = 3000) {
|
|
|
13333
13571
|
await delay(200);
|
|
13334
13572
|
}
|
|
13335
13573
|
}
|
|
13336
|
-
|
|
13337
|
-
const
|
|
13574
|
+
function closeTopicBrowserTabs(userId, topicId) {
|
|
13575
|
+
const connectPort = getTopicBrowserConnectPort(topicId);
|
|
13576
|
+
const binding = connectPort === undefined ? resolvePlaywrightProfileBinding(getBrowserProfileOwner(topicId, userId), getTopicBrowserProfile(topicId)) : connectBinding(connectPort);
|
|
13577
|
+
return closeBindingOwnerTabs(binding, `topic:${topicId}`);
|
|
13578
|
+
}
|
|
13579
|
+
async function closeBindingOwnerTabs(binding, owner) {
|
|
13338
13580
|
const instanceKey = binding.instanceKey;
|
|
13339
13581
|
const inProgress = spawning.get(instanceKey);
|
|
13340
13582
|
if (inProgress)
|
|
@@ -13344,8 +13586,8 @@ async function closeBrowserOwnerTabs(ownerId, rawProfile, owner) {
|
|
|
13344
13586
|
if (!instance)
|
|
13345
13587
|
return 0;
|
|
13346
13588
|
const port = instance.port;
|
|
13347
|
-
const
|
|
13348
|
-
const response = await fetch(`http://127.0.0.1:${port}/owners?${
|
|
13589
|
+
const query2 = new URLSearchParams({ owner });
|
|
13590
|
+
const response = await fetch(`http://127.0.0.1:${port}/owners?${query2}`, {
|
|
13349
13591
|
method: "DELETE",
|
|
13350
13592
|
headers: {
|
|
13351
13593
|
"X-Browser-Capability": instance.capability
|
|
@@ -13408,6 +13650,7 @@ async function cloneProfileForChild(opts) {
|
|
|
13408
13650
|
if (srcOwner === dstOwner && hasBrowserProfileTopic(opts.dstTopic)) {
|
|
13409
13651
|
const profile = getTopicBrowserProfile(opts.srcTopic);
|
|
13410
13652
|
assignTopicBrowserProfile({ topicId: opts.dstTopic, actorUserId: dstOwner, profile });
|
|
13653
|
+
setTopicBrowserConnectPort(opts.dstTopic, getTopicBrowserConnectPort(opts.srcTopic) ?? null);
|
|
13411
13654
|
const binding = resolvePlaywrightProfileBinding(srcOwner, profile);
|
|
13412
13655
|
const sharedDir = resolveUserDataDir(binding.instanceKey);
|
|
13413
13656
|
return {
|
|
@@ -13424,6 +13667,9 @@ async function cloneProfileForChild(opts) {
|
|
|
13424
13667
|
if (srcDir === dstDir) {
|
|
13425
13668
|
return { copied: false, srcDir, dstDir, reason: "same-dir" };
|
|
13426
13669
|
}
|
|
13670
|
+
if (parseConnectInstanceKey(srcKey) !== undefined || parseConnectInstanceKey(dstKey) !== undefined) {
|
|
13671
|
+
return { copied: false, srcDir, dstDir, reason: "connect-binding" };
|
|
13672
|
+
}
|
|
13427
13673
|
return withPlaywrightInstanceMaintenance([srcKey, dstKey], async () => {
|
|
13428
13674
|
const parentWasLive = instances.has(srcKey);
|
|
13429
13675
|
if (parentWasLive) {
|
|
@@ -14040,7 +14286,7 @@ async function runIdleCompactForTopic(topicId, userId, options = {}) {
|
|
|
14040
14286
|
return "below-threshold";
|
|
14041
14287
|
}
|
|
14042
14288
|
const compact = options.compact ?? (async (id, actorId, reason) => {
|
|
14043
|
-
await init_session();
|
|
14289
|
+
const { compactTopicSession } = await init_session().then(() => exports_session);
|
|
14044
14290
|
return compactTopicSession(id, actorId, reason, { preemptive: false });
|
|
14045
14291
|
});
|
|
14046
14292
|
try {
|
|
@@ -14240,40 +14486,40 @@ function beginTransientBackgroundSession(userId, session) {
|
|
|
14240
14486
|
update(status, step) {
|
|
14241
14487
|
if (finished)
|
|
14242
14488
|
return;
|
|
14243
|
-
const
|
|
14244
|
-
if (
|
|
14489
|
+
const current2 = transientSessions.get(record.id);
|
|
14490
|
+
if (current2 !== record)
|
|
14245
14491
|
return;
|
|
14246
14492
|
const nextStatus = text(status, 160);
|
|
14247
14493
|
if (nextStatus)
|
|
14248
|
-
|
|
14494
|
+
current2.status = nextStatus;
|
|
14249
14495
|
const nextStep = text(step);
|
|
14250
|
-
if (nextStep &&
|
|
14251
|
-
|
|
14496
|
+
if (nextStep && current2.steps.at(-1) !== nextStep) {
|
|
14497
|
+
current2.steps.push(nextStep);
|
|
14252
14498
|
}
|
|
14253
14499
|
},
|
|
14254
14500
|
setOutput(output) {
|
|
14255
14501
|
if (finished)
|
|
14256
14502
|
return;
|
|
14257
|
-
const
|
|
14258
|
-
if (
|
|
14503
|
+
const current2 = transientSessions.get(record.id);
|
|
14504
|
+
if (current2 !== record)
|
|
14259
14505
|
return;
|
|
14260
|
-
|
|
14506
|
+
current2.output = output;
|
|
14261
14507
|
},
|
|
14262
14508
|
finish(status, step) {
|
|
14263
14509
|
if (finished)
|
|
14264
14510
|
return;
|
|
14265
14511
|
this.update(status ?? record.status, step);
|
|
14266
14512
|
finished = true;
|
|
14267
|
-
const
|
|
14268
|
-
if (
|
|
14513
|
+
const current2 = transientSessions.get(record.id);
|
|
14514
|
+
if (current2 !== record)
|
|
14269
14515
|
return;
|
|
14270
|
-
|
|
14271
|
-
|
|
14272
|
-
|
|
14516
|
+
current2.active = false;
|
|
14517
|
+
current2.expiresAt = Date.now() + Math.max(0, retentionMs);
|
|
14518
|
+
current2.expiryTimer = setTimeout(() => {
|
|
14273
14519
|
if (transientSessions.get(record.id) === record)
|
|
14274
14520
|
transientSessions.delete(record.id);
|
|
14275
14521
|
}, Math.max(0, retentionMs));
|
|
14276
|
-
|
|
14522
|
+
current2.expiryTimer.unref?.();
|
|
14277
14523
|
}
|
|
14278
14524
|
};
|
|
14279
14525
|
}
|
|
@@ -14531,8 +14777,8 @@ function markRuntimeUserTurnMessagesLogged(topicId, requestId, ownerId, loggedUs
|
|
|
14531
14777
|
return false;
|
|
14532
14778
|
return db.transaction(() => {
|
|
14533
14779
|
const requests = db.query("SELECT * FROM runtime_user_turn_requests WHERE topic_id = ? ORDER BY created_at ASC, rowid ASC").all(topicId).map(rowToRequest);
|
|
14534
|
-
const hasLoggedPrefix = (
|
|
14535
|
-
const candidate =
|
|
14780
|
+
const hasLoggedPrefix = (request2) => loggedUserMessages.length <= request2.userMessages.length && loggedUserMessages.every((message, index) => {
|
|
14781
|
+
const candidate = request2.userMessages[index];
|
|
14536
14782
|
return candidate?.prompt === message.prompt && candidate.actorUserId === message.actorUserId && candidate.actorLabel === message.actorLabel && JSON.stringify(candidate.attachments ?? []) === JSON.stringify(message.attachments ?? []);
|
|
14537
14783
|
});
|
|
14538
14784
|
const request = requests.find((candidate) => candidate.requestId === requestId && candidate.claimedBy === ownerId && hasLoggedPrefix(candidate)) ?? requests.find((candidate) => candidate.execution?.supersededRequestIds?.includes(requestId) && hasLoggedPrefix(candidate));
|
|
@@ -14550,6 +14796,60 @@ function markRuntimeUserTurnMessagesLogged(topicId, requestId, ownerId, loggedUs
|
|
|
14550
14796
|
return result.changes === 1;
|
|
14551
14797
|
}).immediate();
|
|
14552
14798
|
}
|
|
14799
|
+
function claimNextRuntimeUserTurnRequest(ownerId, now = Date.now()) {
|
|
14800
|
+
return db.transaction(() => {
|
|
14801
|
+
const row = db.query(`SELECT r.*
|
|
14802
|
+
FROM runtime_user_turn_requests r
|
|
14803
|
+
LEFT JOIN runtime_turn_leases l ON l.topic_id = r.topic_id
|
|
14804
|
+
LEFT JOIN runtime_topic_state s ON s.topic_id = r.topic_id
|
|
14805
|
+
WHERE (l.topic_id IS NULL OR l.heartbeat_at < ?)
|
|
14806
|
+
AND (s.topic_id IS NULL OR s.maintenance = 0 OR s.heartbeat_at < ?)
|
|
14807
|
+
AND r.topic_epoch = COALESCE(s.epoch, 0)
|
|
14808
|
+
AND NOT EXISTS (
|
|
14809
|
+
SELECT 1
|
|
14810
|
+
FROM runtime_user_turn_requests active
|
|
14811
|
+
WHERE active.topic_id = r.topic_id
|
|
14812
|
+
AND active.request_id <> r.request_id
|
|
14813
|
+
AND active.claimed_at IS NOT NULL
|
|
14814
|
+
AND active.claimed_at >= ?
|
|
14815
|
+
)
|
|
14816
|
+
AND (
|
|
14817
|
+
(r.status = 'pending' AND (r.claimed_at IS NULL OR r.claimed_at < ?))
|
|
14818
|
+
OR (r.status = 'running' AND (r.claimed_at IS NULL OR r.claimed_at < ?))
|
|
14819
|
+
)
|
|
14820
|
+
ORDER BY r.created_at ASC, r.rowid ASC
|
|
14821
|
+
LIMIT 1`).get(now - TURN_LEASE_STALE_MS, now - TOPIC_MAINTENANCE_STALE_MS, now - REQUEST_CLAIM_STALE_MS, now - REQUEST_CLAIM_STALE_MS, now - REQUEST_CLAIM_STALE_MS);
|
|
14822
|
+
if (!row)
|
|
14823
|
+
return null;
|
|
14824
|
+
const updated = db.query(`UPDATE runtime_user_turn_requests
|
|
14825
|
+
SET claimed_by = ?, claimed_at = ?
|
|
14826
|
+
WHERE request_id = ? AND topic_id = ?
|
|
14827
|
+
AND (
|
|
14828
|
+
(status = 'pending' AND (claimed_at IS NULL OR claimed_at < ?))
|
|
14829
|
+
OR (status = 'running' AND (claimed_at IS NULL OR claimed_at < ?))
|
|
14830
|
+
)`).run(ownerId, now, row.request_id, row.topic_id, now - REQUEST_CLAIM_STALE_MS, now - REQUEST_CLAIM_STALE_MS);
|
|
14831
|
+
if (Number(updated.changes ?? 0) === 0)
|
|
14832
|
+
return null;
|
|
14833
|
+
return rowToRequest({ ...row, claimed_by: ownerId, claimed_at: now });
|
|
14834
|
+
}).immediate();
|
|
14835
|
+
}
|
|
14836
|
+
function markRuntimeUserTurnRunning(topicId, requestId, ownerId, queryId) {
|
|
14837
|
+
const result = db.query(`UPDATE runtime_user_turn_requests
|
|
14838
|
+
SET status = 'running', running_query_id = ?, claimed_at = ?
|
|
14839
|
+
WHERE topic_id = ? AND request_id = ? AND claimed_by = ?`).run(queryId, Date.now(), topicId, requestId, ownerId);
|
|
14840
|
+
return Number(result.changes ?? 0) > 0;
|
|
14841
|
+
}
|
|
14842
|
+
function releaseRuntimeUserTurnClaim(topicId, requestId, ownerId) {
|
|
14843
|
+
const result = db.query(`UPDATE runtime_user_turn_requests
|
|
14844
|
+
SET status = 'pending', claimed_by = NULL, claimed_at = NULL, running_query_id = NULL
|
|
14845
|
+
WHERE topic_id = ? AND request_id = ? AND claimed_by = ?`).run(topicId, requestId, ownerId);
|
|
14846
|
+
return Number(result.changes ?? 0) > 0;
|
|
14847
|
+
}
|
|
14848
|
+
function completeRuntimeUserTurnRequest(topicId, requestId, ownerId) {
|
|
14849
|
+
const result = db.query(`DELETE FROM runtime_user_turn_requests
|
|
14850
|
+
WHERE topic_id = ? AND request_id = ? AND claimed_by = ?`).run(topicId, requestId, ownerId);
|
|
14851
|
+
return Number(result.changes ?? 0) > 0;
|
|
14852
|
+
}
|
|
14553
14853
|
function cancelRuntimeUserTurnRequestsBeforeEpoch(topicId, epoch) {
|
|
14554
14854
|
const rows = db.query("SELECT request_id FROM runtime_user_turn_requests WHERE topic_id = ? AND topic_epoch < ?").all(topicId, epoch);
|
|
14555
14855
|
db.query("DELETE FROM runtime_user_turn_requests WHERE topic_id = ? AND topic_epoch < ?").run(topicId, epoch);
|
|
@@ -14587,10 +14887,36 @@ var init_runtime_turn_requests = __esm(async () => {
|
|
|
14587
14887
|
});
|
|
14588
14888
|
|
|
14589
14889
|
// ../../packages/core/src/topics/session.ts
|
|
14890
|
+
var exports_session = {};
|
|
14891
|
+
__export(exports_session, {
|
|
14892
|
+
splitCompactionPairs: () => splitCompactionPairs,
|
|
14893
|
+
shouldUseCompactionLog: () => shouldUseCompactionLog,
|
|
14894
|
+
shouldCompactForkEntries: () => shouldCompactForkEntries,
|
|
14895
|
+
restartTopicSession: () => restartTopicSession,
|
|
14896
|
+
createCompactedRolloutEntries: () => createCompactedRolloutEntries,
|
|
14897
|
+
compactTopicSession: () => compactTopicSession,
|
|
14898
|
+
COMPACTION_RETAINED_TAIL_TOKENS: () => COMPACTION_RETAINED_TAIL_TOKENS,
|
|
14899
|
+
AUTO_FORK_COMPACTION_TOKENS: () => AUTO_FORK_COMPACTION_TOKENS
|
|
14900
|
+
});
|
|
14590
14901
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
14591
14902
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
|
|
14592
14903
|
import { tmpdir as tmpdir4 } from "os";
|
|
14593
14904
|
import { join as join23 } from "path";
|
|
14905
|
+
async function waitForMemoryArchive(settled, timeoutMs) {
|
|
14906
|
+
let timer;
|
|
14907
|
+
try {
|
|
14908
|
+
return await Promise.race([
|
|
14909
|
+
settled.then(() => true),
|
|
14910
|
+
new Promise((resolve17) => {
|
|
14911
|
+
timer = setTimeout(() => resolve17(false), timeoutMs);
|
|
14912
|
+
timer.unref?.();
|
|
14913
|
+
})
|
|
14914
|
+
]);
|
|
14915
|
+
} finally {
|
|
14916
|
+
if (timer)
|
|
14917
|
+
clearTimeout(timer);
|
|
14918
|
+
}
|
|
14919
|
+
}
|
|
14594
14920
|
async function fenceTopicWork(topicId, maintenance) {
|
|
14595
14921
|
for (const queryId of cancelRuntimeUserTurnRequestsBeforeEpoch(topicId, maintenance.epoch)) {
|
|
14596
14922
|
WsHub.get().broadcastAborted(topicId, queryId, "stopped");
|
|
@@ -14615,6 +14941,97 @@ function hasTopicWorkInFlight(topicId) {
|
|
|
14615
14941
|
function topicIsQuiescedForNonPreemptiveWork(topicId) {
|
|
14616
14942
|
return !hasTopicWorkInFlight(topicId);
|
|
14617
14943
|
}
|
|
14944
|
+
async function restartTopicSession(topicId, userId, reason = "topic-session-restart", options = {}) {
|
|
14945
|
+
const topic = getTopic(topicId);
|
|
14946
|
+
if (!topic)
|
|
14947
|
+
return { text: "Topic not found.", isError: true };
|
|
14948
|
+
if (isLegacySharedGeneral(topic.id)) {
|
|
14949
|
+
return { text: "The legacy shared General session cannot be reset.", isError: true };
|
|
14950
|
+
}
|
|
14951
|
+
const owner = topic.participants.some((participant) => participant.userId === userId && participant.role === "owner");
|
|
14952
|
+
if (!owner)
|
|
14953
|
+
return { text: "Only the topic owner can reset the session.", isError: true };
|
|
14954
|
+
const maintenance = beginRuntimeTopicMaintenance(topicId);
|
|
14955
|
+
if (!maintenance)
|
|
14956
|
+
return { text: "Topic maintenance is already in progress.", isError: true };
|
|
14957
|
+
try {
|
|
14958
|
+
const fenceError = await fenceTopicWork(topicId, maintenance);
|
|
14959
|
+
if (fenceError)
|
|
14960
|
+
return { text: fenceError, isError: true };
|
|
14961
|
+
cancelIdleArchiveForTopic(topicId);
|
|
14962
|
+
cancelIdleCompactForTopic(topicId);
|
|
14963
|
+
const rawArchivePaths = [];
|
|
14964
|
+
try {
|
|
14965
|
+
for (const participantUserId of new Set([
|
|
14966
|
+
userId,
|
|
14967
|
+
...topic.participants.map((participant) => participant.userId)
|
|
14968
|
+
])) {
|
|
14969
|
+
const archived = archiveConversationEvents(topicId, topic.title, participantUserId, {
|
|
14970
|
+
reason: "reset"
|
|
14971
|
+
});
|
|
14972
|
+
if (archived)
|
|
14973
|
+
rawArchivePaths.push(archived.path);
|
|
14974
|
+
}
|
|
14975
|
+
} catch (error) {
|
|
14976
|
+
return {
|
|
14977
|
+
text: `Session reset could not archive the raw conversation: ${error instanceof Error ? error.message : String(error)}`,
|
|
14978
|
+
isError: true
|
|
14979
|
+
};
|
|
14980
|
+
}
|
|
14981
|
+
let settleMemoryArchive;
|
|
14982
|
+
const memoryArchiveSettled = new Promise((resolve17) => {
|
|
14983
|
+
settleMemoryArchive = resolve17;
|
|
14984
|
+
});
|
|
14985
|
+
const archiveStatus = (options.archiveMemory ?? archiveActiveTopicForMemory)(topicId, options.memoryUserId ?? userId, {
|
|
14986
|
+
reason: "reset",
|
|
14987
|
+
minMessages: 1,
|
|
14988
|
+
minExchanges: MIN_MEMORY_ARCHIVE_EXCHANGES,
|
|
14989
|
+
allowMentionOnly: true,
|
|
14990
|
+
skipBusyCheck: true,
|
|
14991
|
+
rawArchivePaths,
|
|
14992
|
+
onSettled: () => settleMemoryArchive?.()
|
|
14993
|
+
});
|
|
14994
|
+
if (archiveStatus === "archived") {
|
|
14995
|
+
const archiveFinished = await waitForMemoryArchive(memoryArchiveSettled, options.memoryArchiveWaitMs ?? RESET_MEMORY_ARCHIVE_WAIT_MS);
|
|
14996
|
+
if (!archiveFinished) {
|
|
14997
|
+
return {
|
|
14998
|
+
text: "Memory archiving did not finish in time. The session was not reset.",
|
|
14999
|
+
isError: true
|
|
15000
|
+
};
|
|
15001
|
+
}
|
|
15002
|
+
}
|
|
15003
|
+
if (!maintenance.isOwned()) {
|
|
15004
|
+
return { text: "Topic maintenance ownership was lost. Try again.", isError: true };
|
|
15005
|
+
}
|
|
15006
|
+
const sessionId = getTopicSessionId(topicId);
|
|
15007
|
+
const purgeLogs = options.purgeLogs ?? purgeTopicLogs;
|
|
15008
|
+
const participantUserIds = Array.from(new Set([userId, ...topic.participants.map((participant) => participant.userId)]));
|
|
15009
|
+
for (const [index, participantUserId] of participantUserIds.entries()) {
|
|
15010
|
+
let purged = false;
|
|
15011
|
+
try {
|
|
15012
|
+
purged = await purgeLogs({
|
|
15013
|
+
userId: participantUserId,
|
|
15014
|
+
topicName: topic.title,
|
|
15015
|
+
cwd: resolveTopicWorkspaceDir(topicId),
|
|
15016
|
+
extraSessions: index === 0 && topic.agent && sessionId ? [{ agent: topic.agent, sessionId }] : []
|
|
15017
|
+
});
|
|
15018
|
+
} catch (error) {
|
|
15019
|
+
logger.warn({ err: error, topicId, userId: participantUserId }, "restartTopicSession: participant context cleanup failed");
|
|
15020
|
+
}
|
|
15021
|
+
if (!purged) {
|
|
15022
|
+
return {
|
|
15023
|
+
text: "Session reset could not remove all provider context. The current session was kept.",
|
|
15024
|
+
isError: true
|
|
15025
|
+
};
|
|
15026
|
+
}
|
|
15027
|
+
}
|
|
15028
|
+
clearTopicSessionId(topicId, reason);
|
|
15029
|
+
clearQueryUsageAlert(userId, topicId);
|
|
15030
|
+
return { text: `Session reset for "${topic.title}". The next message starts fresh.` };
|
|
15031
|
+
} finally {
|
|
15032
|
+
maintenance.finish();
|
|
15033
|
+
}
|
|
15034
|
+
}
|
|
14618
15035
|
function previousCompactedSummary(entries) {
|
|
14619
15036
|
for (let index = entries.length - 2;index >= 0; index -= 1) {
|
|
14620
15037
|
const request = entries[index]?.event;
|
|
@@ -14629,9 +15046,9 @@ The assistant response is the authoritative summary of all earlier context.` &&
|
|
|
14629
15046
|
function withoutCompactionSentinels(entries) {
|
|
14630
15047
|
const filtered = [];
|
|
14631
15048
|
for (let index = 0;index < entries.length; index++) {
|
|
14632
|
-
const
|
|
15049
|
+
const current2 = entries[index]?.event;
|
|
14633
15050
|
const next = entries[index + 1]?.event;
|
|
14634
|
-
if (
|
|
15051
|
+
if (current2?.type === "user_message" && current2.synthetic === "compaction" && next?.type === "result") {
|
|
14635
15052
|
index += 1;
|
|
14636
15053
|
continue;
|
|
14637
15054
|
}
|
|
@@ -14681,18 +15098,18 @@ function retainedPairEntries(agent, pairs) {
|
|
|
14681
15098
|
}
|
|
14682
15099
|
return entries;
|
|
14683
15100
|
}
|
|
14684
|
-
function fitCompactionChunk(
|
|
14685
|
-
if (
|
|
14686
|
-
return
|
|
15101
|
+
function fitCompactionChunk(text2, limit) {
|
|
15102
|
+
if (text2.length <= limit)
|
|
15103
|
+
return text2;
|
|
14687
15104
|
const marker = `
|
|
14688
15105
|
[\u2026]
|
|
14689
15106
|
`;
|
|
14690
15107
|
if (limit <= marker.length)
|
|
14691
|
-
return
|
|
15108
|
+
return text2.slice(0, limit);
|
|
14692
15109
|
const available = limit - marker.length;
|
|
14693
15110
|
const headChars = Math.ceil(available * 0.6);
|
|
14694
15111
|
const tailChars = available - headChars;
|
|
14695
|
-
return `${
|
|
15112
|
+
return `${text2.slice(0, headChars)}${marker}${text2.slice(-tailChars)}`;
|
|
14696
15113
|
}
|
|
14697
15114
|
function buildCompactionSource(topicId, userId, entries, visibleMessages, providerPairs) {
|
|
14698
15115
|
const sections = [];
|
|
@@ -15093,9 +15510,9 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
15093
15510
|
const compactionExecution = resolveCompactionExecution(agent, registry);
|
|
15094
15511
|
const cwd = resolveTopicWorkspaceDir(topicId);
|
|
15095
15512
|
const oldEntries = readConversation(userId, topic.title);
|
|
15096
|
-
let
|
|
15513
|
+
let compactEntries2;
|
|
15097
15514
|
try {
|
|
15098
|
-
|
|
15515
|
+
compactEntries2 = await createCompactedRolloutEntries({
|
|
15099
15516
|
topicId,
|
|
15100
15517
|
topicTitle: topic.title,
|
|
15101
15518
|
userId,
|
|
@@ -15121,7 +15538,7 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
15121
15538
|
try {
|
|
15122
15539
|
replacement = getRegistryOperations(agent).writeRollout({
|
|
15123
15540
|
cwd,
|
|
15124
|
-
entries:
|
|
15541
|
+
entries: compactEntries2,
|
|
15125
15542
|
model,
|
|
15126
15543
|
...effort ? { effort } : {}
|
|
15127
15544
|
});
|
|
@@ -15151,7 +15568,7 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
15151
15568
|
}
|
|
15152
15569
|
try {
|
|
15153
15570
|
replaceConversationStrict(userId, topic.title, [
|
|
15154
|
-
...
|
|
15571
|
+
...compactEntries2,
|
|
15155
15572
|
...priorSessionEntries,
|
|
15156
15573
|
replacementSessionEntry
|
|
15157
15574
|
]);
|
|
@@ -15188,7 +15605,7 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
15188
15605
|
} else {
|
|
15189
15606
|
try {
|
|
15190
15607
|
replaceConversationStrict(userId, topic.title, [
|
|
15191
|
-
...
|
|
15608
|
+
...compactEntries2,
|
|
15192
15609
|
replacementSessionEntry
|
|
15193
15610
|
]);
|
|
15194
15611
|
} catch (manifestError) {
|
|
@@ -15242,11 +15659,45 @@ var init_session = __esm(async () => {
|
|
|
15242
15659
|
});
|
|
15243
15660
|
|
|
15244
15661
|
// ../../packages/core/src/topics/derive.ts
|
|
15662
|
+
var exports_derive = {};
|
|
15663
|
+
__export(exports_derive, {
|
|
15664
|
+
updateTopic: () => updateTopic,
|
|
15665
|
+
isParticipant: () => isParticipant,
|
|
15666
|
+
getVisibleTopics: () => getVisibleTopics,
|
|
15667
|
+
getTopics: () => getTopics,
|
|
15668
|
+
createDerivedTopic: () => createDerivedTopic,
|
|
15669
|
+
TopicTitleConflictError: () => TopicTitleConflictError,
|
|
15670
|
+
TopicForkCompactionError: () => TopicForkCompactionError,
|
|
15671
|
+
TopicDeriveBusyError: () => TopicDeriveBusyError
|
|
15672
|
+
});
|
|
15245
15673
|
import { createHash as createHash9, randomUUID as randomUUID13 } from "crypto";
|
|
15246
15674
|
import { mkdirSync as mkdirSync14, rmSync as rmSync5, unlinkSync as unlinkSync13 } from "fs";
|
|
15247
15675
|
function getTopics(opts = {}) {
|
|
15248
15676
|
return listTopics(opts).filter((topic) => !isLegacySharedGeneral(topic.id));
|
|
15249
15677
|
}
|
|
15678
|
+
function getVisibleTopics(opts = {}) {
|
|
15679
|
+
return getTopics(opts).filter(isTopicVisible).map((topic) => {
|
|
15680
|
+
if (!topic.agent)
|
|
15681
|
+
return topic;
|
|
15682
|
+
const registry = getRegistry(topic.agent);
|
|
15683
|
+
const config = getApiTopicConfig(topic.id);
|
|
15684
|
+
const requestedEffort = config?.effort ?? topic.defaultEffort;
|
|
15685
|
+
return {
|
|
15686
|
+
...topic,
|
|
15687
|
+
effectiveModel: resolveModelForAgent(topic.agent, config?.model ?? topic.defaultModel, registry),
|
|
15688
|
+
effectiveEffort: requestedEffort && registry.validateEffort(requestedEffort) ? requestedEffort : registry.defaultEffort
|
|
15689
|
+
};
|
|
15690
|
+
});
|
|
15691
|
+
}
|
|
15692
|
+
function updateTopic(topicId, patch) {
|
|
15693
|
+
const topic = getTopic(topicId);
|
|
15694
|
+
if (!topic)
|
|
15695
|
+
return false;
|
|
15696
|
+
Object.assign(topic, patch);
|
|
15697
|
+
upsertTopic(topic);
|
|
15698
|
+
WsHub.get().broadcastTopicUpdated(topicId);
|
|
15699
|
+
return true;
|
|
15700
|
+
}
|
|
15250
15701
|
function isParticipant(topic, userId) {
|
|
15251
15702
|
return topic.participants.some((p) => p.userId === userId);
|
|
15252
15703
|
}
|
|
@@ -15662,9 +16113,9 @@ function subagentLineageTopicIds(currentTopicId) {
|
|
|
15662
16113
|
const children = new Set;
|
|
15663
16114
|
if (!currentTopicId)
|
|
15664
16115
|
return { reachable, children };
|
|
15665
|
-
const
|
|
15666
|
-
if (
|
|
15667
|
-
reachable.add(
|
|
16116
|
+
const current2 = getTopic(currentTopicId);
|
|
16117
|
+
if (current2?.isSubagent && current2.parentTopicId) {
|
|
16118
|
+
reachable.add(current2.parentTopicId);
|
|
15668
16119
|
for (const id of listSubagentTellTargetIds(currentTopicId))
|
|
15669
16120
|
reachable.add(id);
|
|
15670
16121
|
}
|
|
@@ -15790,9 +16241,9 @@ function cleanupSessionInboxFiles(userId, topicId, legacyTopicTitle) {
|
|
|
15790
16241
|
try {
|
|
15791
16242
|
unlinkSync15(path);
|
|
15792
16243
|
deleted++;
|
|
15793
|
-
} catch (
|
|
15794
|
-
if (
|
|
15795
|
-
logger.warn({ err, path, topicId, userId }, "topic cleanup: inbox unlink failed");
|
|
16244
|
+
} catch (err2) {
|
|
16245
|
+
if (err2?.code !== "ENOENT") {
|
|
16246
|
+
logger.warn({ err: err2, path, topicId, userId }, "topic cleanup: inbox unlink failed");
|
|
15796
16247
|
}
|
|
15797
16248
|
}
|
|
15798
16249
|
}
|
|
@@ -15917,9 +16368,9 @@ function hubHeaders(bearer) {
|
|
|
15917
16368
|
};
|
|
15918
16369
|
}
|
|
15919
16370
|
function errorText(status, body, fallback) {
|
|
15920
|
-
const
|
|
15921
|
-
if (typeof
|
|
15922
|
-
return
|
|
16371
|
+
const text2 = body?.error;
|
|
16372
|
+
if (typeof text2 === "string" && text2.trim())
|
|
16373
|
+
return text2.trim();
|
|
15923
16374
|
return `${fallback} (hub answered ${status})`;
|
|
15924
16375
|
}
|
|
15925
16376
|
function describeFailure(status, body) {
|
|
@@ -16015,6 +16466,19 @@ var init_actor_policy = __esm(async () => {
|
|
|
16015
16466
|
await init_actor_topic_reach();
|
|
16016
16467
|
});
|
|
16017
16468
|
// ../../packages/core/src/storage/session-asks.ts
|
|
16469
|
+
var exports_session_asks = {};
|
|
16470
|
+
__export(exports_session_asks, {
|
|
16471
|
+
releasePendingAsk: () => releasePendingAsk,
|
|
16472
|
+
markPendingAskState: () => markPendingAskState,
|
|
16473
|
+
markPendingAskSources: () => markPendingAskSources,
|
|
16474
|
+
listPendingAsksForCaller: () => listPendingAsksForCaller,
|
|
16475
|
+
describePendingAskState: () => describePendingAskState,
|
|
16476
|
+
deletePendingAsksForTopic: () => deletePendingAsksForTopic,
|
|
16477
|
+
createPendingAsk: () => createPendingAsk,
|
|
16478
|
+
clearPendingAskSources: () => clearPendingAskSources,
|
|
16479
|
+
clearPendingAsk: () => clearPendingAsk,
|
|
16480
|
+
PENDING_ASK_TTL_MS: () => PENDING_ASK_TTL_MS
|
|
16481
|
+
});
|
|
16018
16482
|
import { createHash as createHash10 } from "crypto";
|
|
16019
16483
|
import {
|
|
16020
16484
|
closeSync as closeSync2,
|
|
@@ -16036,8 +16500,8 @@ function encodeAskKey(key) {
|
|
|
16036
16500
|
return JSON.stringify([key.from, key.to]);
|
|
16037
16501
|
}
|
|
16038
16502
|
function pendingAskPath(key) {
|
|
16039
|
-
const
|
|
16040
|
-
return join28(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${
|
|
16503
|
+
const digest2 = createHash10("sha256").update(encodeAskKey(key)).digest("hex");
|
|
16504
|
+
return join28(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest2}.pending`);
|
|
16041
16505
|
}
|
|
16042
16506
|
function v2PendingAskPath(key) {
|
|
16043
16507
|
const encoded = Buffer.from(encodeAskKey(key), "utf8").toString("base64url");
|
|
@@ -16063,10 +16527,10 @@ function parsePendingAskFilename(fileName) {
|
|
|
16063
16527
|
}
|
|
16064
16528
|
} catch {}
|
|
16065
16529
|
}
|
|
16066
|
-
const
|
|
16067
|
-
if (
|
|
16530
|
+
const sep3 = raw.indexOf("___");
|
|
16531
|
+
if (sep3 < 0)
|
|
16068
16532
|
return null;
|
|
16069
|
-
return { from: raw.slice(0,
|
|
16533
|
+
return { from: raw.slice(0, sep3), to: raw.slice(sep3 + 3) };
|
|
16070
16534
|
}
|
|
16071
16535
|
function readPendingAskFile(path, fallback) {
|
|
16072
16536
|
try {
|
|
@@ -16109,6 +16573,16 @@ function readPendingAskFile(path, fallback) {
|
|
|
16109
16573
|
return null;
|
|
16110
16574
|
}
|
|
16111
16575
|
}
|
|
16576
|
+
function isStale(record, path) {
|
|
16577
|
+
const ts = record ? Date.parse(record.updatedAt || record.createdAt) : Number.NaN;
|
|
16578
|
+
if (Number.isFinite(ts))
|
|
16579
|
+
return Date.now() - ts > PENDING_ASK_TTL_MS;
|
|
16580
|
+
try {
|
|
16581
|
+
return Date.now() - statSync8(path).mtimeMs > PENDING_ASK_TTL_MS;
|
|
16582
|
+
} catch {
|
|
16583
|
+
return false;
|
|
16584
|
+
}
|
|
16585
|
+
}
|
|
16112
16586
|
function writePendingAsk(record) {
|
|
16113
16587
|
const path = pendingAskPath(record);
|
|
16114
16588
|
mkdirSync16(pendingAskDir(record.userId), { recursive: true });
|
|
@@ -16134,10 +16608,10 @@ function writePendingAskIfAbsent(record) {
|
|
|
16134
16608
|
}
|
|
16135
16609
|
}
|
|
16136
16610
|
function readPendingAsk(key) {
|
|
16137
|
-
const
|
|
16138
|
-
const canonical = readPendingAskFile(
|
|
16611
|
+
const canonicalPath2 = pendingAskPath(key);
|
|
16612
|
+
const canonical = readPendingAskFile(canonicalPath2, key);
|
|
16139
16613
|
if (canonical && canonical.from === key.from && canonical.to === key.to) {
|
|
16140
|
-
return { path:
|
|
16614
|
+
return { path: canonicalPath2, record: canonical };
|
|
16141
16615
|
}
|
|
16142
16616
|
for (const compatibilityPath of [v2PendingAskPath(key), legacyPendingAskPath(key)]) {
|
|
16143
16617
|
if (!compatibilityPath)
|
|
@@ -16146,17 +16620,67 @@ function readPendingAsk(key) {
|
|
|
16146
16620
|
if (!legacy || legacy.from !== key.from || legacy.to !== key.to)
|
|
16147
16621
|
continue;
|
|
16148
16622
|
const migrated = writePendingAskIfAbsent(legacy);
|
|
16149
|
-
const next = migrated ? legacy : readPendingAskFile(
|
|
16623
|
+
const next = migrated ? legacy : readPendingAskFile(canonicalPath2, key);
|
|
16150
16624
|
if (next && next.from === key.from && next.to === key.to) {
|
|
16151
16625
|
try {
|
|
16152
16626
|
unlinkSync16(compatibilityPath);
|
|
16153
16627
|
} catch {}
|
|
16154
|
-
return { path:
|
|
16628
|
+
return { path: canonicalPath2, record: next };
|
|
16155
16629
|
}
|
|
16156
16630
|
return { path: compatibilityPath, record: legacy };
|
|
16157
16631
|
}
|
|
16158
16632
|
return null;
|
|
16159
16633
|
}
|
|
16634
|
+
function createPendingAsk(args) {
|
|
16635
|
+
const migrated = readPendingAsk(args);
|
|
16636
|
+
if (migrated && !isStale(migrated.record, migrated.path)) {
|
|
16637
|
+
return { ok: false, existing: migrated.record, stale: false };
|
|
16638
|
+
}
|
|
16639
|
+
if (migrated) {
|
|
16640
|
+
try {
|
|
16641
|
+
unlinkSync16(migrated.path);
|
|
16642
|
+
} catch {
|
|
16643
|
+
return { ok: false, existing: migrated.record, stale: true };
|
|
16644
|
+
}
|
|
16645
|
+
}
|
|
16646
|
+
const path = pendingAskPath(args);
|
|
16647
|
+
const now = new Date().toISOString();
|
|
16648
|
+
const record = {
|
|
16649
|
+
userId: args.userId,
|
|
16650
|
+
from: args.from,
|
|
16651
|
+
to: args.to,
|
|
16652
|
+
requestId: args.requestId,
|
|
16653
|
+
contextId: args.contextId,
|
|
16654
|
+
state: "requested",
|
|
16655
|
+
createdAt: now,
|
|
16656
|
+
updatedAt: now
|
|
16657
|
+
};
|
|
16658
|
+
mkdirSync16(pendingAskDir(args.userId), { recursive: true });
|
|
16659
|
+
for (let attempt = 0;attempt < 2; attempt++) {
|
|
16660
|
+
let fd = null;
|
|
16661
|
+
try {
|
|
16662
|
+
fd = openSync2(path, "wx");
|
|
16663
|
+
writeFileSync14(fd, `${JSON.stringify(record)}
|
|
16664
|
+
`);
|
|
16665
|
+
return { ok: true, record };
|
|
16666
|
+
} catch (err2) {
|
|
16667
|
+
if (err2.code !== "EEXIST")
|
|
16668
|
+
throw err2;
|
|
16669
|
+
const existing = readPendingAskFile(path, args);
|
|
16670
|
+
if (!isStale(existing, path))
|
|
16671
|
+
return { ok: false, existing, stale: false };
|
|
16672
|
+
try {
|
|
16673
|
+
unlinkSync16(path);
|
|
16674
|
+
} catch {
|
|
16675
|
+
return { ok: false, existing, stale: true };
|
|
16676
|
+
}
|
|
16677
|
+
} finally {
|
|
16678
|
+
if (fd !== null)
|
|
16679
|
+
closeSync2(fd);
|
|
16680
|
+
}
|
|
16681
|
+
}
|
|
16682
|
+
return { ok: false, existing: readPendingAskFile(path, args), stale: true };
|
|
16683
|
+
}
|
|
16160
16684
|
function markPendingAskState(args) {
|
|
16161
16685
|
const pending = readPendingAsk(args);
|
|
16162
16686
|
if (!pending)
|
|
@@ -16190,6 +16714,83 @@ function clearPendingAsk(args) {
|
|
|
16190
16714
|
return false;
|
|
16191
16715
|
}
|
|
16192
16716
|
}
|
|
16717
|
+
function releasePendingAsk(args) {
|
|
16718
|
+
if (clearPendingAsk(args))
|
|
16719
|
+
return true;
|
|
16720
|
+
const still = readPendingAsk(args);
|
|
16721
|
+
return !still || still.record.requestId !== args.requestId;
|
|
16722
|
+
}
|
|
16723
|
+
function markPendingAskSources(args) {
|
|
16724
|
+
for (const source of args.sources ?? []) {
|
|
16725
|
+
if (!source.from)
|
|
16726
|
+
continue;
|
|
16727
|
+
markPendingAskState({
|
|
16728
|
+
userId: args.userId,
|
|
16729
|
+
from: args.callerTopic,
|
|
16730
|
+
to: source.from,
|
|
16731
|
+
requestId: source.requestId,
|
|
16732
|
+
state: args.state
|
|
16733
|
+
});
|
|
16734
|
+
}
|
|
16735
|
+
}
|
|
16736
|
+
function clearPendingAskSources(args) {
|
|
16737
|
+
for (const source of args.sources ?? []) {
|
|
16738
|
+
if (!source.from)
|
|
16739
|
+
continue;
|
|
16740
|
+
clearPendingAsk({
|
|
16741
|
+
userId: args.userId,
|
|
16742
|
+
from: args.callerTopic,
|
|
16743
|
+
to: source.from,
|
|
16744
|
+
requestId: source.requestId
|
|
16745
|
+
});
|
|
16746
|
+
}
|
|
16747
|
+
}
|
|
16748
|
+
function listPendingAsksForCaller(args) {
|
|
16749
|
+
const dir = pendingAskDir(args.userId);
|
|
16750
|
+
let files;
|
|
16751
|
+
try {
|
|
16752
|
+
files = readdirSync4(dir);
|
|
16753
|
+
} catch {
|
|
16754
|
+
return [];
|
|
16755
|
+
}
|
|
16756
|
+
const records = new Map;
|
|
16757
|
+
for (const fileName of files) {
|
|
16758
|
+
const isV3 = fileName.startsWith(ASK_FILENAME_PREFIX);
|
|
16759
|
+
const parsed = isV3 ? { from: args.from, to: "" } : parsePendingAskFilename(fileName);
|
|
16760
|
+
if (!parsed)
|
|
16761
|
+
continue;
|
|
16762
|
+
const path = join28(dir, fileName);
|
|
16763
|
+
const record = readPendingAskFile(path, {
|
|
16764
|
+
userId: args.userId,
|
|
16765
|
+
from: parsed.from,
|
|
16766
|
+
to: parsed.to
|
|
16767
|
+
});
|
|
16768
|
+
if (!record || record.from !== args.from)
|
|
16769
|
+
continue;
|
|
16770
|
+
if (isStale(record, path)) {
|
|
16771
|
+
try {
|
|
16772
|
+
unlinkSync16(path);
|
|
16773
|
+
} catch {}
|
|
16774
|
+
continue;
|
|
16775
|
+
}
|
|
16776
|
+
const canonical = readPendingAsk(record);
|
|
16777
|
+
if (!canonical || canonical.record.from !== args.from)
|
|
16778
|
+
continue;
|
|
16779
|
+
if (path !== canonical.path) {
|
|
16780
|
+
try {
|
|
16781
|
+
unlinkSync16(path);
|
|
16782
|
+
} catch {}
|
|
16783
|
+
}
|
|
16784
|
+
if (isStale(canonical.record, canonical.path)) {
|
|
16785
|
+
try {
|
|
16786
|
+
unlinkSync16(canonical.path);
|
|
16787
|
+
} catch {}
|
|
16788
|
+
continue;
|
|
16789
|
+
}
|
|
16790
|
+
records.set(encodeAskKey(canonical.record), canonical.record);
|
|
16791
|
+
}
|
|
16792
|
+
return [...records.values()];
|
|
16793
|
+
}
|
|
16193
16794
|
function deletePendingAsksForTopic(args) {
|
|
16194
16795
|
const dir = pendingAskDir(args.userId);
|
|
16195
16796
|
let files;
|
|
@@ -16218,6 +16819,18 @@ function deletePendingAsksForTopic(args) {
|
|
|
16218
16819
|
}
|
|
16219
16820
|
return deleted;
|
|
16220
16821
|
}
|
|
16822
|
+
function describePendingAskState(state) {
|
|
16823
|
+
switch (state) {
|
|
16824
|
+
case "requested":
|
|
16825
|
+
return "\uB300\uC0C1 \uC138\uC158 \uCC98\uB9AC \uC911";
|
|
16826
|
+
case "reply_ready":
|
|
16827
|
+
return "\uC751\uB2F5 \uC0DD\uC131 \uC644\uB8CC, \uC774 \uC138\uC158 \uC8FC\uC785 \uC900\uBE44 \uC911";
|
|
16828
|
+
case "queued_for_caller":
|
|
16829
|
+
return "\uC751\uB2F5 \uC0DD\uC131 \uC644\uB8CC, \uC774 \uC138\uC158 \uC2E4\uD589 \uC885\uB8CC \uD6C4 \uC8FC\uC785 \uB300\uAE30 \uC911";
|
|
16830
|
+
case "injecting_to_caller":
|
|
16831
|
+
return "\uC751\uB2F5\uC744 \uC774 \uC138\uC158\uC5D0 \uC8FC\uC785 \uC911";
|
|
16832
|
+
}
|
|
16833
|
+
}
|
|
16221
16834
|
var PENDING_ASK_TTL_MS, ASK_FILENAME_PREFIX = "v3-", V2_ASK_FILENAME_PREFIX = "v2-";
|
|
16222
16835
|
var init_session_asks = __esm(async () => {
|
|
16223
16836
|
await init_storage_host();
|
|
@@ -16319,10 +16932,10 @@ function deferRemoteSessionReplyOutbox(args) {
|
|
|
16319
16932
|
if (!row)
|
|
16320
16933
|
return;
|
|
16321
16934
|
const attempts = Number(row.attempts) + 1;
|
|
16322
|
-
const
|
|
16935
|
+
const delay2 = args.retryMs ?? remoteSessionRetryDelayMs(attempts, args.random);
|
|
16323
16936
|
db.query(`UPDATE remote_session_reply_outbox
|
|
16324
16937
|
SET attempts = ?, next_attempt_at = ?, last_error = ?
|
|
16325
|
-
WHERE request_id = ?`).run(attempts, now +
|
|
16938
|
+
WHERE request_id = ?`).run(attempts, now + delay2, args.error.slice(0, 500), args.requestId);
|
|
16326
16939
|
})();
|
|
16327
16940
|
}
|
|
16328
16941
|
function purgeExpiredRemoteSessionReplyOutbox(now = Date.now()) {
|
|
@@ -16493,9 +17106,37 @@ var init_remote_session_reply_outbox = __esm(async () => {
|
|
|
16493
17106
|
});
|
|
16494
17107
|
|
|
16495
17108
|
// ../../packages/core/src/mcp/session-comm/peer-forward.ts
|
|
17109
|
+
var exports_peer_forward = {};
|
|
17110
|
+
__export(exports_peer_forward, {
|
|
17111
|
+
registerPeerSessionBridge: () => registerPeerSessionBridge,
|
|
17112
|
+
peerSessionsForUser: () => peerSessionsForUser,
|
|
17113
|
+
parseHubRemoteReplyRoute: () => parseHubRemoteReplyRoute,
|
|
17114
|
+
isHubRemoteReplyRoute: () => isHubRemoteReplyRoute,
|
|
17115
|
+
forwardToPeer: () => forwardToPeer,
|
|
17116
|
+
deliverPeerReply: () => deliverPeerReply
|
|
17117
|
+
});
|
|
16496
17118
|
function isHubRemoteReplyRoute(route) {
|
|
16497
17119
|
return route.via === "hub";
|
|
16498
17120
|
}
|
|
17121
|
+
function parseHubRemoteReplyRoute(value) {
|
|
17122
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
17123
|
+
return null;
|
|
17124
|
+
const route = value;
|
|
17125
|
+
if (route.via !== "hub" || typeof route.hubUrl !== "string" || typeof route.token !== "string" || typeof route.nodeName !== "string" || typeof route.topicId !== "string" || typeof route.requestId !== "string") {
|
|
17126
|
+
return null;
|
|
17127
|
+
}
|
|
17128
|
+
const requestId = route.requestId.trim();
|
|
17129
|
+
const nodeName = route.nodeName.trim();
|
|
17130
|
+
const topicId = route.topicId.trim();
|
|
17131
|
+
const token = route.token.trim();
|
|
17132
|
+
if (!requestId || requestId.length > MAX_ROUTE_REQUEST_ID_LENGTH || !nodeName || nodeName.length > MAX_ROUTE_LABEL_LENGTH || !topicId || topicId.length > MAX_ROUTE_LABEL_LENGTH || token.length > MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH || !REMOTE_SESSION_REPLY_TOKEN_PATTERN.test(token)) {
|
|
17133
|
+
return null;
|
|
17134
|
+
}
|
|
17135
|
+
const hubUrl = normalizeHubUrl(route.hubUrl.trim(), "remoteReply.hubUrl");
|
|
17136
|
+
if ("error" in hubUrl)
|
|
17137
|
+
return null;
|
|
17138
|
+
return { via: "hub", hubUrl: hubUrl.url, token, nodeName, topicId, requestId };
|
|
17139
|
+
}
|
|
16499
17140
|
function loopbackBridgeConfig() {
|
|
16500
17141
|
const rawUrl = process.env[PEER_BRIDGE_URL_ENV]?.trim();
|
|
16501
17142
|
const token = process.env[PEER_BRIDGE_TOKEN_ENV]?.trim();
|
|
@@ -16532,6 +17173,39 @@ async function callLoopbackBridge(request) {
|
|
|
16532
17173
|
return { configured: true, result: null };
|
|
16533
17174
|
}
|
|
16534
17175
|
}
|
|
17176
|
+
function registerPeerSessionBridge(bridge) {
|
|
17177
|
+
activeBridge = bridge;
|
|
17178
|
+
return () => {
|
|
17179
|
+
if (activeBridge === bridge)
|
|
17180
|
+
activeBridge = null;
|
|
17181
|
+
};
|
|
17182
|
+
}
|
|
17183
|
+
async function forwardToPeer(args) {
|
|
17184
|
+
if (activeBridge)
|
|
17185
|
+
return activeBridge.forward(args);
|
|
17186
|
+
const forwarded = await callLoopbackBridge({ action: "forward", args });
|
|
17187
|
+
if (forwarded.result)
|
|
17188
|
+
return forwarded.result;
|
|
17189
|
+
return {
|
|
17190
|
+
ok: false,
|
|
17191
|
+
error: forwarded.configured ? "remote session bridge is configured but unavailable" : "remote nodes are not connected on this negotium node (standalone mode)"
|
|
17192
|
+
};
|
|
17193
|
+
}
|
|
17194
|
+
async function peerSessionsForUser(userId, sourceQueryId, fromTopicId) {
|
|
17195
|
+
if (activeBridge)
|
|
17196
|
+
return activeBridge.sessions(userId, sourceQueryId, fromTopicId);
|
|
17197
|
+
const sessions = await callLoopbackBridge({
|
|
17198
|
+
action: "sessions",
|
|
17199
|
+
userId,
|
|
17200
|
+
sourceQueryId,
|
|
17201
|
+
fromTopicId
|
|
17202
|
+
});
|
|
17203
|
+
if (sessions.result)
|
|
17204
|
+
return sessions.result;
|
|
17205
|
+
if (sessions.configured)
|
|
17206
|
+
return { ok: false, nodes: [] };
|
|
17207
|
+
return { ok: true, nodes: [] };
|
|
17208
|
+
}
|
|
16535
17209
|
async function deliverPeerReply(route, sourceTitle, replyText, kind) {
|
|
16536
17210
|
if (isHubRemoteReplyRoute(route)) {
|
|
16537
17211
|
return deliverHubRemoteReply(route, sourceTitle, replyText, kind);
|
|
@@ -16546,13 +17220,40 @@ async function deliverPeerReply(route, sourceTitle, replyText, kind) {
|
|
|
16546
17220
|
kind
|
|
16547
17221
|
})).result ?? false;
|
|
16548
17222
|
}
|
|
16549
|
-
var activeBridge = null, PEER_BRIDGE_URL_ENV = "NEGOTIUM_PEER_SESSION_BRIDGE_URL", PEER_BRIDGE_TOKEN_ENV = "NEGOTIUM_PEER_SESSION_BRIDGE_TOKEN", PEER_BRIDGE_TIMEOUT_MS = 5000;
|
|
17223
|
+
var MAX_ROUTE_REQUEST_ID_LENGTH = 200, MAX_ROUTE_LABEL_LENGTH = 300, activeBridge = null, PEER_BRIDGE_URL_ENV = "NEGOTIUM_PEER_SESSION_BRIDGE_URL", PEER_BRIDGE_TOKEN_ENV = "NEGOTIUM_PEER_SESSION_BRIDGE_TOKEN", PEER_BRIDGE_TIMEOUT_MS = 5000;
|
|
16550
17224
|
var init_peer_forward = __esm(async () => {
|
|
16551
17225
|
init_remote_session_grant();
|
|
16552
17226
|
await init_remote_session_reply_outbox();
|
|
16553
17227
|
});
|
|
16554
17228
|
|
|
16555
17229
|
// ../../packages/core/src/runtime/ask-callbacks.ts
|
|
17230
|
+
var exports_ask_callbacks = {};
|
|
17231
|
+
__export(exports_ask_callbacks, {
|
|
17232
|
+
resolveAskCallback: () => resolveAskCallback,
|
|
17233
|
+
registerAskCallback: () => registerAskCallback,
|
|
17234
|
+
purgeStaleAsks: () => purgeStaleAsks,
|
|
17235
|
+
failInterruptedRemoteAskCallbacks: () => failInterruptedRemoteAskCallbacks,
|
|
17236
|
+
deleteHubRemoteAskCallbackRow: () => deleteHubRemoteAskCallbackRow,
|
|
17237
|
+
cancelAskCallbacksForTopic: () => cancelAskCallbacksForTopic
|
|
17238
|
+
});
|
|
17239
|
+
function registerAskCallback(entry) {
|
|
17240
|
+
pendingAsks.set(entry.targetQueryId, entry);
|
|
17241
|
+
if (entry.remoteReply) {
|
|
17242
|
+
const route = entry.remoteReply;
|
|
17243
|
+
const hub = isHubRemoteReplyRoute(route);
|
|
17244
|
+
db.query(`INSERT INTO remote_ask_callbacks
|
|
17245
|
+
(target_query_id, request_id, node_name, node_cell_id, topic_id, user_id, created_at, route_json)
|
|
17246
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
17247
|
+
ON CONFLICT(target_query_id) DO UPDATE SET
|
|
17248
|
+
request_id = excluded.request_id,
|
|
17249
|
+
node_name = excluded.node_name,
|
|
17250
|
+
node_cell_id = excluded.node_cell_id,
|
|
17251
|
+
topic_id = excluded.topic_id,
|
|
17252
|
+
user_id = excluded.user_id,
|
|
17253
|
+
created_at = excluded.created_at,
|
|
17254
|
+
route_json = excluded.route_json`).run(entry.targetQueryId, route.requestId, route.nodeName, hub ? "" : route.nodeCellId, route.topicId, hub ? "" : route.userId, entry.createdAt, hub ? JSON.stringify(route) : null);
|
|
17255
|
+
}
|
|
17256
|
+
}
|
|
16556
17257
|
function resolveAskCallback(queryId) {
|
|
16557
17258
|
const entry = pendingAsks.get(queryId);
|
|
16558
17259
|
if (!entry)
|
|
@@ -16569,6 +17270,13 @@ function resolveAskCallback(queryId) {
|
|
|
16569
17270
|
function deleteHubRemoteAskCallbackRow(requestId) {
|
|
16570
17271
|
db.query("DELETE FROM remote_ask_callbacks WHERE request_id = ? AND route_json IS NOT NULL").run(requestId);
|
|
16571
17272
|
}
|
|
17273
|
+
function purgeStaleAsks(now = Date.now()) {
|
|
17274
|
+
for (const [id, entry] of pendingAsks) {
|
|
17275
|
+
if (now - entry.createdAt > MAX_ASK_AGE_MS)
|
|
17276
|
+
pendingAsks.delete(id);
|
|
17277
|
+
}
|
|
17278
|
+
db.query("DELETE FROM remote_ask_callbacks WHERE created_at < ?").run(now - MAX_ASK_AGE_MS);
|
|
17279
|
+
}
|
|
16572
17280
|
function cancelAskCallbacksForTopic(topicId) {
|
|
16573
17281
|
let cancelled = 0;
|
|
16574
17282
|
for (const [queryId, entry] of pendingAsks) {
|
|
@@ -16580,6 +17288,43 @@ function cancelAskCallbacksForTopic(topicId) {
|
|
|
16580
17288
|
}
|
|
16581
17289
|
return cancelled;
|
|
16582
17290
|
}
|
|
17291
|
+
function durableRoute(row) {
|
|
17292
|
+
if (row.route_json) {
|
|
17293
|
+
try {
|
|
17294
|
+
return parseHubRemoteReplyRoute(JSON.parse(row.route_json));
|
|
17295
|
+
} catch {
|
|
17296
|
+
return null;
|
|
17297
|
+
}
|
|
17298
|
+
}
|
|
17299
|
+
return {
|
|
17300
|
+
nodeName: row.node_name,
|
|
17301
|
+
nodeCellId: row.node_cell_id,
|
|
17302
|
+
topicId: row.topic_id,
|
|
17303
|
+
userId: row.user_id,
|
|
17304
|
+
requestId: row.request_id
|
|
17305
|
+
};
|
|
17306
|
+
}
|
|
17307
|
+
async function failInterruptedRemoteAskCallbacks(options = {}) {
|
|
17308
|
+
const rows = db.query(`SELECT target_query_id, request_id, node_name, node_cell_id, topic_id, user_id, route_json
|
|
17309
|
+
FROM remote_ask_callbacks
|
|
17310
|
+
ORDER BY created_at ASC`).all();
|
|
17311
|
+
let failed = 0;
|
|
17312
|
+
for (const row of rows) {
|
|
17313
|
+
const route = durableRoute(row);
|
|
17314
|
+
if (!route) {
|
|
17315
|
+
db.query("DELETE FROM remote_ask_callbacks WHERE target_query_id = ?").run(row.target_query_id);
|
|
17316
|
+
continue;
|
|
17317
|
+
}
|
|
17318
|
+
if (options.routes === "hub" && !isHubRemoteReplyRoute(route))
|
|
17319
|
+
continue;
|
|
17320
|
+
const delivered = await deliverPeerReply(route, "peer", "The remote worker restarted before this ask completed. Please retry the request.", "error");
|
|
17321
|
+
if (!delivered)
|
|
17322
|
+
continue;
|
|
17323
|
+
db.query("DELETE FROM remote_ask_callbacks WHERE target_query_id = ?").run(row.target_query_id);
|
|
17324
|
+
failed++;
|
|
17325
|
+
}
|
|
17326
|
+
return failed;
|
|
17327
|
+
}
|
|
16583
17328
|
var pendingAsks, MAX_ASK_AGE_MS;
|
|
16584
17329
|
var init_ask_callbacks = __esm(async () => {
|
|
16585
17330
|
await __promiseAll([
|
|
@@ -17005,6 +17750,14 @@ var init_topic_tool_capabilities = __esm(async () => {
|
|
|
17005
17750
|
});
|
|
17006
17751
|
|
|
17007
17752
|
// ../../packages/core/src/topics/lifecycle.ts
|
|
17753
|
+
var exports_lifecycle = {};
|
|
17754
|
+
__export(exports_lifecycle, {
|
|
17755
|
+
deleteTopicCascade: () => deleteTopicCascade,
|
|
17756
|
+
TopicTurnStillActiveError: () => TopicTurnStillActiveError,
|
|
17757
|
+
TopicDeleteVetoedError: () => TopicDeleteVetoedError,
|
|
17758
|
+
TopicCleanupRequiredError: () => TopicCleanupRequiredError,
|
|
17759
|
+
TopicArchiveRequiredError: () => TopicArchiveRequiredError
|
|
17760
|
+
});
|
|
17008
17761
|
import { rmSync as rmSync6 } from "fs";
|
|
17009
17762
|
async function abortAndWaitForTopic(topicId) {
|
|
17010
17763
|
interSessionQueue.drop(topicId);
|
|
@@ -17037,8 +17790,8 @@ async function cleanupParticipantResources(topic, userIds, sessionId, cwd, purge
|
|
|
17037
17790
|
cwd,
|
|
17038
17791
|
extraSessions: index === 0 ? currentSessionRef(topic, sessionId) : []
|
|
17039
17792
|
});
|
|
17040
|
-
} catch (
|
|
17041
|
-
logger.warn({ err, topicId: topic.id, userId: participantUserId }, "deleteTopicCascade: participant rollout cleanup failed");
|
|
17793
|
+
} catch (err2) {
|
|
17794
|
+
logger.warn({ err: err2, topicId: topic.id, userId: participantUserId }, "deleteTopicCascade: participant rollout cleanup failed");
|
|
17042
17795
|
}
|
|
17043
17796
|
if (!purged)
|
|
17044
17797
|
return false;
|
|
@@ -17094,12 +17847,12 @@ async function deleteTopicCascadeImpl(topic, userId, options, deletingAncestorId
|
|
|
17094
17847
|
if (rawArchive)
|
|
17095
17848
|
rawArchives.push(rawArchive.path);
|
|
17096
17849
|
}
|
|
17097
|
-
} catch (
|
|
17850
|
+
} catch (err2) {
|
|
17098
17851
|
if (!force) {
|
|
17099
|
-
logger.warn({ err, topicId }, "deleteTopicCascade: archive failed - blocking delete unless force=true");
|
|
17100
|
-
throw new TopicArchiveRequiredError(topicId,
|
|
17852
|
+
logger.warn({ err: err2, topicId }, "deleteTopicCascade: archive failed - blocking delete unless force=true");
|
|
17853
|
+
throw new TopicArchiveRequiredError(topicId, err2);
|
|
17101
17854
|
}
|
|
17102
|
-
logger.warn({ err, topicId }, "deleteTopicCascade: archive failed but force=true - continuing with hard delete");
|
|
17855
|
+
logger.warn({ err: err2, topicId }, "deleteTopicCascade: archive failed but force=true - continuing with hard delete");
|
|
17103
17856
|
}
|
|
17104
17857
|
}
|
|
17105
17858
|
if (archived && meetsMemoryArchiveExchangeThreshold(archived.exchangeCount, MIN_MEMORY_ARCHIVE_EXCHANGES, topic)) {
|
|
@@ -17115,8 +17868,8 @@ async function deleteTopicCascadeImpl(topic, userId, options, deletingAncestorId
|
|
|
17115
17868
|
...rawArchives.length > 0 ? { rawArchivePaths: rawArchives } : {},
|
|
17116
17869
|
messageCount: archived.messageCount
|
|
17117
17870
|
});
|
|
17118
|
-
} catch (
|
|
17119
|
-
logger.warn({ err, topicId, archive: archived.path }, "deleteTopicCascade: background archiver launch failed - raw archive preserved");
|
|
17871
|
+
} catch (err2) {
|
|
17872
|
+
logger.warn({ err: err2, topicId, archive: archived.path }, "deleteTopicCascade: background archiver launch failed - raw archive preserved");
|
|
17120
17873
|
}
|
|
17121
17874
|
}
|
|
17122
17875
|
const sessionId = getTopicSessionId(topicId);
|
|
@@ -17131,25 +17884,23 @@ async function deleteTopicCascadeImpl(topic, userId, options, deletingAncestorId
|
|
|
17131
17884
|
await deleteTopicCascadeImpl(child, userId, childOptions, deletingTopicIds);
|
|
17132
17885
|
}
|
|
17133
17886
|
killBgBash(userId, topicId);
|
|
17134
|
-
const browserProfileOwner = getBrowserProfileOwner(topicId, userId);
|
|
17135
|
-
const browserProfile = getTopicBrowserProfile(topicId);
|
|
17136
17887
|
try {
|
|
17137
|
-
await
|
|
17138
|
-
} catch (
|
|
17139
|
-
logger.warn({ err, topicId }, "deleteTopicCascade: browser owner cleanup failed");
|
|
17888
|
+
await closeTopicBrowserTabs(userId, topicId);
|
|
17889
|
+
} catch (err2) {
|
|
17890
|
+
logger.warn({ err: err2, topicId }, "deleteTopicCascade: browser owner cleanup failed");
|
|
17140
17891
|
}
|
|
17141
17892
|
deleteTopicProfileDir(userId, topicId);
|
|
17142
17893
|
cancelAskCallbacksForTopic(topicId);
|
|
17143
17894
|
deleteSelfSchedulesForTopic(topicId);
|
|
17144
17895
|
try {
|
|
17145
17896
|
await deleteFilesForTopic(topicId);
|
|
17146
|
-
} catch (
|
|
17147
|
-
logger.warn({ err, topicId }, "deleteTopicCascade: host file cleanup failed");
|
|
17897
|
+
} catch (err2) {
|
|
17898
|
+
logger.warn({ err: err2, topicId }, "deleteTopicCascade: host file cleanup failed");
|
|
17148
17899
|
}
|
|
17149
17900
|
try {
|
|
17150
17901
|
rmSync6(cwd, { recursive: true, force: true });
|
|
17151
|
-
} catch (
|
|
17152
|
-
logger.warn({ err, topicId, cwd }, "deleteTopicCascade: workspace cleanup failed");
|
|
17902
|
+
} catch (err2) {
|
|
17903
|
+
logger.warn({ err: err2, topicId, cwd }, "deleteTopicCascade: workspace cleanup failed");
|
|
17153
17904
|
}
|
|
17154
17905
|
deleteTopicVisuals(topicId);
|
|
17155
17906
|
deleteTopicHostMcpGrant(topicId);
|
|
@@ -17191,7 +17942,7 @@ async function deleteTopicCascadeImpl(topic, userId, options, deletingAncestorId
|
|
|
17191
17942
|
}
|
|
17192
17943
|
}
|
|
17193
17944
|
}
|
|
17194
|
-
var DELETE_TURN_WAIT_MS = 5000, TopicArchiveRequiredError, TopicTurnStillActiveError, TopicCleanupRequiredError;
|
|
17945
|
+
var DELETE_TURN_WAIT_MS = 5000, TopicArchiveRequiredError, TopicTurnStillActiveError, TopicCleanupRequiredError, TopicDeleteVetoedError;
|
|
17195
17946
|
var init_lifecycle = __esm(async () => {
|
|
17196
17947
|
init_manager();
|
|
17197
17948
|
init_config();
|
|
@@ -17216,7 +17967,6 @@ var init_lifecycle = __esm(async () => {
|
|
|
17216
17967
|
init_api_topic_brief(),
|
|
17217
17968
|
init_api_topic_config(),
|
|
17218
17969
|
init_api_topics(),
|
|
17219
|
-
init_browser_profiles(),
|
|
17220
17970
|
init_forum_db(),
|
|
17221
17971
|
init_runtime_leases(),
|
|
17222
17972
|
init_runtime_topic_state(),
|
|
@@ -17258,9 +18008,19 @@ var init_lifecycle = __esm(async () => {
|
|
|
17258
18008
|
this.topicId = topicId;
|
|
17259
18009
|
}
|
|
17260
18010
|
};
|
|
18011
|
+
TopicDeleteVetoedError = class TopicDeleteVetoedError extends Error {
|
|
18012
|
+
code = "TOPIC_DELETE_VETOED";
|
|
18013
|
+
topicId;
|
|
18014
|
+
constructor(topicId, reason) {
|
|
18015
|
+
super(`Topic delete was vetoed: ${reason}`);
|
|
18016
|
+
this.name = "TopicDeleteVetoedError";
|
|
18017
|
+
this.topicId = topicId;
|
|
18018
|
+
}
|
|
18019
|
+
};
|
|
17261
18020
|
});
|
|
17262
18021
|
|
|
17263
18022
|
// ../../packages/core/src/runtime/attachments.ts
|
|
18023
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
17264
18024
|
import { copyFileSync as copyFileSync2, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
17265
18025
|
import { basename as basename6, join as join29 } from "path";
|
|
17266
18026
|
function workspaceCwdFor(topicId) {
|
|
@@ -17302,8 +18062,8 @@ function materializePromptAttachments(topicId, queryId, attachmentIds) {
|
|
|
17302
18062
|
sizeBytes: attachment.sizeBytes,
|
|
17303
18063
|
path: destPath
|
|
17304
18064
|
});
|
|
17305
|
-
} catch (
|
|
17306
|
-
logger.warn({ topicId, queryId, fileId, err }, "ai: failed to materialize attachment");
|
|
18065
|
+
} catch (err2) {
|
|
18066
|
+
logger.warn({ topicId, queryId, fileId, err: err2 }, "ai: failed to materialize attachment");
|
|
17307
18067
|
}
|
|
17308
18068
|
}
|
|
17309
18069
|
return out;
|
|
@@ -17321,6 +18081,24 @@ function composeAttachmentPrompt(prompt, promptLines) {
|
|
|
17321
18081
|
function promptWithAttachments(prompt, attachments) {
|
|
17322
18082
|
return composeAttachmentPrompt(prompt, attachments.map(({ filename, path }) => attachmentPromptLine(filename, path)));
|
|
17323
18083
|
}
|
|
18084
|
+
function ingestAttachment(args) {
|
|
18085
|
+
const destDir = join29(UPLOADS_DIR, args.topicId);
|
|
18086
|
+
mkdirSync17(destDir, { recursive: true });
|
|
18087
|
+
const safeName = safeAttachmentFilename(args.filename, "upload");
|
|
18088
|
+
const destPath = join29(destDir, `${Date.now()}-${randomUUID16().slice(0, 8)}-${safeName}`);
|
|
18089
|
+
if (args.sourcePath !== undefined) {
|
|
18090
|
+
copyFileSync2(args.sourcePath, destPath);
|
|
18091
|
+
} else if (args.bytes !== undefined) {
|
|
18092
|
+
writeFileSync15(destPath, args.bytes);
|
|
18093
|
+
} else {
|
|
18094
|
+
throw new Error("ingestAttachment: provide sourcePath or bytes");
|
|
18095
|
+
}
|
|
18096
|
+
return {
|
|
18097
|
+
path: destPath,
|
|
18098
|
+
filename: args.filename,
|
|
18099
|
+
promptLine: attachmentPromptLine(args.filename, destPath)
|
|
18100
|
+
};
|
|
18101
|
+
}
|
|
17324
18102
|
function parseAttachmentNames(raw) {
|
|
17325
18103
|
if (!raw)
|
|
17326
18104
|
return [];
|
|
@@ -17361,13 +18139,13 @@ function isLikelyCurrentChannelTrigger(row, userId, prompt) {
|
|
|
17361
18139
|
return Number.isFinite(createdMs) && Date.now() - createdMs <= CHANNEL_CONTEXT_CURRENT_MESSAGE_MATCH_MS;
|
|
17362
18140
|
}
|
|
17363
18141
|
function formatChannelTranscriptLine(row) {
|
|
17364
|
-
const
|
|
18142
|
+
const text2 = row.text.trim();
|
|
17365
18143
|
const attachments = parseAttachmentNames(row.attachments);
|
|
17366
18144
|
const attachmentSuffix = attachments.length > 0 ? `
|
|
17367
18145
|
[attachments: ${attachments.join(", ")}]` : "";
|
|
17368
18146
|
const edited = row.edited_at ? " (edited)" : "";
|
|
17369
18147
|
const thread = row.thread_root_id ? ` (in thread ${threadTag(row.thread_root_id)})` : "";
|
|
17370
|
-
return `[${row.created_at}] ${channelTranscriptSpeaker(row)}${edited}${thread}: ${
|
|
18148
|
+
return `[${row.created_at}] ${channelTranscriptSpeaker(row)}${edited}${thread}: ${text2}${attachmentSuffix}`;
|
|
17371
18149
|
}
|
|
17372
18150
|
function buildMentionOnlyChannelPrompt(params) {
|
|
17373
18151
|
const rows = getAllMessagesForTopic(params.topicId).filter((row) => {
|
|
@@ -17412,6 +18190,14 @@ function buildMentionOnlyChannelPrompt(params) {
|
|
|
17412
18190
|
].filter((line) => line !== undefined).join(`
|
|
17413
18191
|
`);
|
|
17414
18192
|
}
|
|
18193
|
+
function escapeRegExp3(s) {
|
|
18194
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18195
|
+
}
|
|
18196
|
+
function mentionsAi(text2, label) {
|
|
18197
|
+
const names = ["ai", "bot", "\uBD07", label.trim()].filter(Boolean);
|
|
18198
|
+
const alt = names.map(escapeRegExp3).join("|");
|
|
18199
|
+
return new RegExp(`(^|\\s)@(${alt})(?![\\p{L}\\p{N}])`, "iu").test(text2);
|
|
18200
|
+
}
|
|
17415
18201
|
var CHANNEL_CONTEXT_CURRENT_MESSAGE_MATCH_MS, CHANNEL_CONTEXT_MAX_MESSAGES = 500, CHANNEL_CONTEXT_MAX_CHARS = 120000;
|
|
17416
18202
|
var init_channel_context = __esm(async () => {
|
|
17417
18203
|
init_attachments();
|
|
@@ -17420,13 +18206,13 @@ var init_channel_context = __esm(async () => {
|
|
|
17420
18206
|
});
|
|
17421
18207
|
|
|
17422
18208
|
// ../../packages/core/src/runtime/errors.ts
|
|
17423
|
-
function stringifyError(
|
|
17424
|
-
if (
|
|
17425
|
-
return
|
|
17426
|
-
if (typeof
|
|
17427
|
-
return
|
|
18209
|
+
function stringifyError(err2) {
|
|
18210
|
+
if (err2 instanceof Error)
|
|
18211
|
+
return err2.message;
|
|
18212
|
+
if (typeof err2 === "string")
|
|
18213
|
+
return err2;
|
|
17428
18214
|
try {
|
|
17429
|
-
return JSON.stringify(
|
|
18215
|
+
return JSON.stringify(err2) ?? String(err2);
|
|
17430
18216
|
} catch {
|
|
17431
18217
|
return "Unknown agent error";
|
|
17432
18218
|
}
|
|
@@ -17441,19 +18227,19 @@ function authRecoveryHint(agent) {
|
|
|
17441
18227
|
return "Please check the DEEPSEEK_API_KEY, MOONSHOT_API_KEY, or GLM_API_KEY environment variable";
|
|
17442
18228
|
}
|
|
17443
18229
|
}
|
|
17444
|
-
function classifyAgentError(
|
|
18230
|
+
function classifyAgentError(err2, agent) {
|
|
17445
18231
|
const name = AGENT_DISPLAY_NAME[agent];
|
|
17446
18232
|
const hint = authRecoveryHint(agent);
|
|
17447
|
-
const ctor = typeof
|
|
18233
|
+
const ctor = typeof err2 === "object" && err2 !== null ? err2.constructor?.name : undefined;
|
|
17448
18234
|
if (ctor === "AuthenticationError")
|
|
17449
18235
|
return `${name} authentication expired. ${hint}. (401)`;
|
|
17450
18236
|
if (ctor === "RateLimitError")
|
|
17451
18237
|
return `${name} request limit exceeded. Please try again in a moment. (429)`;
|
|
17452
18238
|
if (ctor === "InternalServerError") {
|
|
17453
|
-
const status =
|
|
18239
|
+
const status = err2.status;
|
|
17454
18240
|
return status === 529 ? `${name} server is overloaded. Please try again in a moment. (529)` : `${name} server error occurred. Please try again in a moment. (500)`;
|
|
17455
18241
|
}
|
|
17456
|
-
const s = stringifyError(
|
|
18242
|
+
const s = stringifyError(err2);
|
|
17457
18243
|
if (/401|authentication.error|invalid.*api.key|not logged|ANTHROPIC_API_KEY|DEEPSEEK_API_KEY|MOONSHOT_API_KEY|GLM_API_KEY/i.test(s)) {
|
|
17458
18244
|
return `${name} authentication expired. ${hint}. (401)`;
|
|
17459
18245
|
}
|
|
@@ -17476,12 +18262,12 @@ var init_errors = __esm(() => {
|
|
|
17476
18262
|
|
|
17477
18263
|
// ../../packages/core/src/runtime/event-heartbeat.ts
|
|
17478
18264
|
function nextOrHeartbeat(pending, intervalMs) {
|
|
17479
|
-
return new Promise((
|
|
17480
|
-
const timer = setTimeout(() =>
|
|
18265
|
+
return new Promise((resolve17, reject) => {
|
|
18266
|
+
const timer = setTimeout(() => resolve17({ kind: "heartbeat" }), intervalMs);
|
|
17481
18267
|
timer.unref?.();
|
|
17482
18268
|
pending.then((result) => {
|
|
17483
18269
|
clearTimeout(timer);
|
|
17484
|
-
|
|
18270
|
+
resolve17({ kind: "event", result });
|
|
17485
18271
|
}, (error) => {
|
|
17486
18272
|
clearTimeout(timer);
|
|
17487
18273
|
reject(error);
|
|
@@ -17775,7 +18561,7 @@ var init_vault_request_gates = __esm(async () => {
|
|
|
17775
18561
|
});
|
|
17776
18562
|
|
|
17777
18563
|
// ../../packages/core/src/agents/mcp-tools/request-vault.ts
|
|
17778
|
-
import { createHash as createHash12, randomUUID as
|
|
18564
|
+
import { createHash as createHash12, randomUUID as randomUUID17 } from "crypto";
|
|
17779
18565
|
import { z as z4 } from "zod";
|
|
17780
18566
|
function requestBodyHash(key, description) {
|
|
17781
18567
|
return createHash12("sha256").update(JSON.stringify({ key, description })).digest("hex");
|
|
@@ -18011,8 +18797,8 @@ function createRequestVaultRuntime(host) {
|
|
|
18011
18797
|
return errorResult(`Error: failed to persist request_vault_secret: ${error instanceof Error ? error.message : String(error)}`);
|
|
18012
18798
|
}
|
|
18013
18799
|
let resolveAnswer;
|
|
18014
|
-
const promise = new Promise((
|
|
18015
|
-
resolveAnswer =
|
|
18800
|
+
const promise = new Promise((resolve17) => {
|
|
18801
|
+
resolveAnswer = resolve17;
|
|
18016
18802
|
});
|
|
18017
18803
|
pendingRequests.set(message.id, {
|
|
18018
18804
|
topicId: ctx.topicId,
|
|
@@ -18073,7 +18859,7 @@ var init_request_vault = __esm(async () => {
|
|
|
18073
18859
|
init_vault_request_gates()
|
|
18074
18860
|
]);
|
|
18075
18861
|
MAX_DESCRIPTION_CHARS = VAULT_DESCRIPTION_MAX_LENGTH;
|
|
18076
|
-
VAULT_GATE_OWNER_ID = `request-vault-${process.pid}-${
|
|
18862
|
+
VAULT_GATE_OWNER_ID = `request-vault-${process.pid}-${randomUUID17()}`;
|
|
18077
18863
|
defaultRequestVaultDurabilityHost = {
|
|
18078
18864
|
gates: {
|
|
18079
18865
|
prepare: prepareVaultRequestGate,
|
|
@@ -18114,7 +18900,7 @@ var init_request_vault = __esm(async () => {
|
|
|
18114
18900
|
durability: defaultRequestVaultDurabilityHost,
|
|
18115
18901
|
runtime: {
|
|
18116
18902
|
ownerId: VAULT_GATE_OWNER_ID,
|
|
18117
|
-
createId:
|
|
18903
|
+
createId: randomUUID17,
|
|
18118
18904
|
now: () => new Date().toISOString()
|
|
18119
18905
|
}
|
|
18120
18906
|
});
|
|
@@ -18151,24 +18937,24 @@ function taskPanelMessageId(queryId) {
|
|
|
18151
18937
|
// ../../packages/core/src/runtime/tasks.ts
|
|
18152
18938
|
function upsertTaskPanelMessage(topicId, queryId, tasks, lastRenderedText) {
|
|
18153
18939
|
if (tasks.length === 0) {
|
|
18154
|
-
const
|
|
18155
|
-
for (const
|
|
18156
|
-
|
|
18940
|
+
const hub2 = WsHub.get();
|
|
18941
|
+
for (const messageId2 of softDeleteApiMessagesByIdPrefix(topicId, "tasks-")) {
|
|
18942
|
+
hub2.broadcastMessageUpdated(topicId, messageId2, { deleted: true, text: "" });
|
|
18157
18943
|
}
|
|
18158
18944
|
return null;
|
|
18159
18945
|
}
|
|
18160
|
-
const
|
|
18161
|
-
if (
|
|
18946
|
+
const text2 = renderTaskPanel(tasks);
|
|
18947
|
+
if (text2 === lastRenderedText)
|
|
18162
18948
|
return lastRenderedText;
|
|
18163
18949
|
const hub = WsHub.get();
|
|
18164
18950
|
const messageId = taskPanelMessageId(queryId);
|
|
18165
18951
|
const existing = getApiMessage(topicId, messageId);
|
|
18166
18952
|
if (existing && !existing.deleted) {
|
|
18167
18953
|
const editedAt = new Date().toISOString();
|
|
18168
|
-
const updated = updateApiMessageText(topicId, messageId,
|
|
18954
|
+
const updated = updateApiMessageText(topicId, messageId, text2, editedAt);
|
|
18169
18955
|
if (updated) {
|
|
18170
|
-
hub.broadcastMessageUpdated(topicId, messageId, { text, editedAt });
|
|
18171
|
-
return
|
|
18956
|
+
hub.broadcastMessageUpdated(topicId, messageId, { text: text2, editedAt });
|
|
18957
|
+
return text2;
|
|
18172
18958
|
}
|
|
18173
18959
|
}
|
|
18174
18960
|
const createdAt = new Date().toISOString();
|
|
@@ -18176,12 +18962,12 @@ function upsertTaskPanelMessage(topicId, queryId, tasks, lastRenderedText) {
|
|
|
18176
18962
|
id: messageId,
|
|
18177
18963
|
topicId,
|
|
18178
18964
|
authorId: "system",
|
|
18179
|
-
text,
|
|
18965
|
+
text: text2,
|
|
18180
18966
|
createdAt
|
|
18181
18967
|
};
|
|
18182
18968
|
appendApiMessage(message, { notify: false });
|
|
18183
18969
|
hub.broadcastMessage(topicId, message);
|
|
18184
|
-
return
|
|
18970
|
+
return text2;
|
|
18185
18971
|
}
|
|
18186
18972
|
var init_tasks2 = __esm(async () => {
|
|
18187
18973
|
await __promiseAll([
|
|
@@ -18440,14 +19226,14 @@ function resolveVisualMediaInput(topicId, input) {
|
|
|
18440
19226
|
if (!topicAllowsVisualFileId(topicId, fileId)) {
|
|
18441
19227
|
return { error: "file_id is not attached to this topic" };
|
|
18442
19228
|
}
|
|
18443
|
-
const
|
|
18444
|
-
const
|
|
18445
|
-
if (!
|
|
19229
|
+
const attachment2 = resolveAttachmentByFileId(fileId);
|
|
19230
|
+
const filePath2 = resolveUploadedFilePathByFileId(fileId);
|
|
19231
|
+
if (!attachment2 || !filePath2)
|
|
18446
19232
|
return { error: `uploaded file not found: ${fileId}` };
|
|
18447
19233
|
return {
|
|
18448
|
-
fileId:
|
|
18449
|
-
mimeType:
|
|
18450
|
-
source: `file_id:${
|
|
19234
|
+
fileId: attachment2.id,
|
|
19235
|
+
mimeType: attachment2.mimeType,
|
|
19236
|
+
source: `file_id:${attachment2.id}`
|
|
18451
19237
|
};
|
|
18452
19238
|
}
|
|
18453
19239
|
if (typeof input.file_path !== "string" || !input.file_path.trim()) {
|
|
@@ -18494,7 +19280,7 @@ var init_visuals = __esm(async () => {
|
|
|
18494
19280
|
});
|
|
18495
19281
|
|
|
18496
19282
|
// ../../packages/core/src/runtime/turn-event-stream.ts
|
|
18497
|
-
import { randomUUID as
|
|
19283
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
18498
19284
|
import { realpathSync as realpathSync6, statSync as statSync9 } from "fs";
|
|
18499
19285
|
import { isAbsolute as isAbsolute7, resolve as resolve18 } from "path";
|
|
18500
19286
|
function sessionEventMatchesCurrentExecution(topicId, queryId, agent, model) {
|
|
@@ -18563,9 +19349,9 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
|
|
|
18563
19349
|
const existing = providerToolIds.get(providerId);
|
|
18564
19350
|
if (existing)
|
|
18565
19351
|
return existing;
|
|
18566
|
-
const
|
|
18567
|
-
providerToolIds.set(providerId,
|
|
18568
|
-
return
|
|
19352
|
+
const clientId2 = fallback ?? providerId;
|
|
19353
|
+
providerToolIds.set(providerId, clientId2);
|
|
19354
|
+
return clientId2;
|
|
18569
19355
|
}
|
|
18570
19356
|
const clientId = fallback ?? nextSyntheticToolUseId();
|
|
18571
19357
|
anonymousToolIds.push(clientId);
|
|
@@ -18596,15 +19382,15 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
|
|
|
18596
19382
|
return providerId ? handledVisualToolResultIds.has(providerId) : false;
|
|
18597
19383
|
};
|
|
18598
19384
|
const emitPendingAssistantMessage = (usage) => {
|
|
18599
|
-
const
|
|
19385
|
+
const text2 = pendingText.trimEnd();
|
|
18600
19386
|
pendingText = "";
|
|
18601
|
-
if (silent || !
|
|
19387
|
+
if (silent || !text2.trim())
|
|
18602
19388
|
return null;
|
|
18603
19389
|
const message = {
|
|
18604
|
-
id:
|
|
19390
|
+
id: randomUUID18(),
|
|
18605
19391
|
topicId,
|
|
18606
19392
|
authorId: "ai",
|
|
18607
|
-
text,
|
|
19393
|
+
text: text2,
|
|
18608
19394
|
queryId,
|
|
18609
19395
|
agentType,
|
|
18610
19396
|
model,
|
|
@@ -18824,8 +19610,8 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
18824
19610
|
hub.broadcastVisual(topicId, queryId, url, vizId, title ?? null, kind);
|
|
18825
19611
|
hub.broadcastToolOutput(topicId, queryId, toolUseId, `Displayed: ${url}`);
|
|
18826
19612
|
markVisualToolResultHandled(event.toolUseId);
|
|
18827
|
-
} catch (
|
|
18828
|
-
const reason =
|
|
19613
|
+
} catch (err2) {
|
|
19614
|
+
const reason = err2 instanceof Error ? err2.message : String(err2);
|
|
18829
19615
|
failMediaVisual(reason);
|
|
18830
19616
|
}
|
|
18831
19617
|
} else {
|
|
@@ -18936,8 +19722,8 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
18936
19722
|
}
|
|
18937
19723
|
terminalEmitted = true;
|
|
18938
19724
|
{
|
|
18939
|
-
await init_ask_callbacks();
|
|
18940
|
-
const pending =
|
|
19725
|
+
const { resolveAskCallback: resolveAskCallback2 } = await init_ask_callbacks().then(() => exports_ask_callbacks);
|
|
19726
|
+
const pending = resolveAskCallback2(queryId);
|
|
18941
19727
|
if (pending) {
|
|
18942
19728
|
const sourceLabel = pending.sourceLabel ?? topicTitle;
|
|
18943
19729
|
const replyText = pending.timedOut ? `\u26A0\uFE0F [Timeout - reply from ${sourceLabel} took too long and was dropped]` : accumulatedText.trim() || "(\uCC98\uB9AC\uB428, \uBCC4\uB3C4 \uC751\uB2F5 \uC5C6\uC74C)";
|
|
@@ -19010,8 +19796,8 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
19010
19796
|
if (control.injectParams)
|
|
19011
19797
|
control.injectParams.sessionId = event.sessionId;
|
|
19012
19798
|
onSessionId(event.sessionId);
|
|
19013
|
-
} catch (
|
|
19014
|
-
logger.warn({ err, topicId, queryId, agentType }, "ai: isolated session owner rejected provider session id");
|
|
19799
|
+
} catch (err2) {
|
|
19800
|
+
logger.warn({ err: err2, topicId, queryId, agentType }, "ai: isolated session owner rejected provider session id");
|
|
19015
19801
|
}
|
|
19016
19802
|
} else if (!silent && sessionEventMatchesCurrentExecution(topicId, queryId, agentType, model)) {
|
|
19017
19803
|
setTopicSessionId(topicId, event.sessionId, {
|
|
@@ -19044,14 +19830,14 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
19044
19830
|
settleSubagentFailure(queryId, "\uC911\uC9C0\uB428 (\uC0AC\uC6A9\uC790\uAC00 \uC2E4\uD589\uC744 \uBA48\uCDC4\uC2B5\uB2C8\uB2E4)");
|
|
19045
19831
|
} else {
|
|
19046
19832
|
if (control.abortReason === "internal" /* Internal */) {
|
|
19047
|
-
await init_ask_callbacks();
|
|
19048
|
-
|
|
19833
|
+
const { resolveAskCallback: resolveAskCallback2 } = await init_ask_callbacks().then(() => exports_ask_callbacks);
|
|
19834
|
+
resolveAskCallback2(queryId);
|
|
19049
19835
|
}
|
|
19050
19836
|
}
|
|
19051
19837
|
}
|
|
19052
|
-
} catch (
|
|
19053
|
-
const msg = stringifyError(
|
|
19054
|
-
logger.warn({ err, topicId, queryId, agentType, model, silent }, "ai: stream failed");
|
|
19838
|
+
} catch (err2) {
|
|
19839
|
+
const msg = stringifyError(err2) || "Unknown agent error";
|
|
19840
|
+
logger.warn({ err: err2, topicId, queryId, agentType, model, silent }, "ai: stream failed");
|
|
19055
19841
|
terminalEmitted = true;
|
|
19056
19842
|
if (retryableSessionExpired && isSessionExpiredError(msg)) {
|
|
19057
19843
|
outcome = { kind: "session-expired", error: msg };
|
|
@@ -19202,7 +19988,85 @@ var init_app_settings = __esm(async () => {
|
|
|
19202
19988
|
});
|
|
19203
19989
|
|
|
19204
19990
|
// ../../packages/core/src/runtime/turn-runner.ts
|
|
19205
|
-
|
|
19991
|
+
var exports_turn_runner = {};
|
|
19992
|
+
__export(exports_turn_runner, {
|
|
19993
|
+
workspaceCwdFor: () => workspaceCwdFor,
|
|
19994
|
+
withDefaultPlaywright: () => withDefaultPlaywright,
|
|
19995
|
+
wasLocallyRequeuedAfterUserPreemption: () => wasLocallyRequeuedAfterUserPreemption,
|
|
19996
|
+
userConversationPromptsToRecord: () => userConversationPromptsToRecord,
|
|
19997
|
+
upsertTaskPanelMessage: () => upsertTaskPanelMessage,
|
|
19998
|
+
tryReconstructTopicRollout: () => tryReconstructTopicRollout,
|
|
19999
|
+
triggerTopicAiTurn: () => triggerTopicAiTurn,
|
|
20000
|
+
topicAllowsVisualFileId: () => topicAllowsVisualFileId,
|
|
20001
|
+
taskPanelMessageId: () => taskPanelMessageId,
|
|
20002
|
+
stripMermaidFence: () => stripMermaidFence,
|
|
20003
|
+
stringifyError: () => stringifyError,
|
|
20004
|
+
streamAgentEvents: () => streamAgentEvents,
|
|
20005
|
+
startDurableTurnRequestWorker: () => startDurableTurnRequestWorker,
|
|
20006
|
+
startAiTurn: () => startAiTurn,
|
|
20007
|
+
selectableModel: () => selectableModel,
|
|
20008
|
+
sameTurnActor: () => sameTurnActor,
|
|
20009
|
+
safeAttachmentFilename: () => safeAttachmentFilename,
|
|
20010
|
+
resolveWorkerModel: () => resolveWorkerModel,
|
|
20011
|
+
resolveWorkerDefaultModel: () => resolveWorkerDefaultModel,
|
|
20012
|
+
resolveWikiMirrorPath: () => resolveWikiMirrorPath,
|
|
20013
|
+
resolveWikiMemoryMirror: () => resolveWikiMemoryMirror,
|
|
20014
|
+
resolveVisualMediaInput: () => resolveVisualMediaInput,
|
|
20015
|
+
resolveTurnToolCapabilities: () => resolveTurnToolCapabilities,
|
|
20016
|
+
resolveTurnHostMcpServers: () => resolveTurnHostMcpServers,
|
|
20017
|
+
resolveTopicTurnSession: () => resolveTopicTurnSession,
|
|
20018
|
+
resolveTopicTurnExecution: () => resolveTopicTurnExecution,
|
|
20019
|
+
resolveSessionRetry: () => resolveSessionRetry,
|
|
20020
|
+
resolveModelForAgent: () => resolveModelForAgent,
|
|
20021
|
+
resolveInitialTurnSessionId: () => resolveInitialTurnSessionId,
|
|
20022
|
+
resolveDefaultModel: () => resolveDefaultModel,
|
|
20023
|
+
resolveCompactionExecution: () => resolveCompactionExecution,
|
|
20024
|
+
renderUserTurnBatch: () => renderUserTurnBatch,
|
|
20025
|
+
renderUserPromptBatch: () => renderUserPromptBatch,
|
|
20026
|
+
renderTaskPanel: () => renderTaskPanel,
|
|
20027
|
+
promptWithAttachments: () => promptWithAttachments,
|
|
20028
|
+
prepareInjectReplayAfterUserPreemption: () => prepareInjectReplayAfterUserPreemption,
|
|
20029
|
+
parseAttachmentNames: () => parseAttachmentNames,
|
|
20030
|
+
normalizeToolUseId: () => normalizeToolUseId,
|
|
20031
|
+
normalizeMermaidTheme: () => normalizeMermaidTheme,
|
|
20032
|
+
modelOwner: () => modelOwner,
|
|
20033
|
+
mergeSupersedingUserTurn: () => mergeSupersedingUserTurn,
|
|
20034
|
+
mentionsAi: () => mentionsAi,
|
|
20035
|
+
materializePromptAttachments: () => materializePromptAttachments,
|
|
20036
|
+
isVisualsShowMermaidTool: () => isVisualsShowMermaidTool,
|
|
20037
|
+
isVisualsShowImageTool: () => isVisualsShowImageTool,
|
|
20038
|
+
isVisualsShowHtmlTool: () => isVisualsShowHtmlTool,
|
|
20039
|
+
isSessionExpiredError: () => isSessionExpiredError,
|
|
20040
|
+
isRuntimeTool: () => isRuntimeTool,
|
|
20041
|
+
isPathInside: () => isPathInside,
|
|
20042
|
+
isLikelyCurrentChannelTrigger: () => isLikelyCurrentChannelTrigger,
|
|
20043
|
+
ingestAttachment: () => ingestAttachment,
|
|
20044
|
+
formatSelectableModel: () => formatSelectableModel,
|
|
20045
|
+
formatChannelTranscriptLine: () => formatChannelTranscriptLine,
|
|
20046
|
+
escapeRegExp: () => escapeRegExp3,
|
|
20047
|
+
escapeHtml: () => escapeHtml2,
|
|
20048
|
+
deliverAskCallbackToCaller: () => deliverAskCallbackToCaller,
|
|
20049
|
+
composeAttachmentPrompt: () => composeAttachmentPrompt,
|
|
20050
|
+
classifyAgentError: () => classifyAgentError,
|
|
20051
|
+
channelTranscriptSpeaker: () => channelTranscriptSpeaker,
|
|
20052
|
+
canonicalModelId: () => canonicalModelId,
|
|
20053
|
+
buildVideoHtml: () => buildVideoHtml,
|
|
20054
|
+
buildTurnReminderQuery: () => buildTurnReminderQuery,
|
|
20055
|
+
buildMermaidHtml: () => buildMermaidHtml,
|
|
20056
|
+
buildMentionOnlyChannelPrompt: () => buildMentionOnlyChannelPrompt,
|
|
20057
|
+
buildImageHtml: () => buildImageHtml,
|
|
20058
|
+
authRecoveryHint: () => authRecoveryHint,
|
|
20059
|
+
attachmentPromptLine: () => attachmentPromptLine,
|
|
20060
|
+
activeVisualHtmlForPrompt: () => activeVisualHtmlForPrompt,
|
|
20061
|
+
SESSION_EXPIRED_MSG: () => SESSION_EXPIRED_MSG,
|
|
20062
|
+
SELECTABLE_MODELS: () => SELECTABLE_MODELS,
|
|
20063
|
+
MODEL_OWNER: () => MODEL_OWNER,
|
|
20064
|
+
MODEL_COST_ROUTING_SUMMARY: () => MODEL_COST_ROUTING_SUMMARY,
|
|
20065
|
+
MODEL_COST_RESEARCHED_AT: () => MODEL_COST_RESEARCHED_AT,
|
|
20066
|
+
FALLBACK_ORDER: () => FALLBACK_ORDER,
|
|
20067
|
+
AGENT_DISPLAY_NAME: () => AGENT_DISPLAY_NAME
|
|
20068
|
+
});
|
|
20069
|
+
import { randomUUID as randomUUID19 } from "crypto";
|
|
19206
20070
|
import { existsSync as existsSync22, mkdirSync as mkdirSync19, readdirSync as readdirSync5, statSync as statSync10 } from "fs";
|
|
19207
20071
|
import { join as join31 } from "path";
|
|
19208
20072
|
function withDefaultPlaywright(configuredMcp, isManager) {
|
|
@@ -19225,12 +20089,12 @@ function buildTurnReminderQuery(agent, prompt, reminders) {
|
|
|
19225
20089
|
|
|
19226
20090
|
${reminderPrompt}` };
|
|
19227
20091
|
}
|
|
19228
|
-
function appendSystemMessage(topicId,
|
|
20092
|
+
function appendSystemMessage(topicId, text2, threadRootId) {
|
|
19229
20093
|
const message = {
|
|
19230
|
-
id:
|
|
20094
|
+
id: randomUUID19(),
|
|
19231
20095
|
topicId,
|
|
19232
20096
|
authorId: "system",
|
|
19233
|
-
text,
|
|
20097
|
+
text: text2,
|
|
19234
20098
|
...threadRootId ? { threadRootId } : {},
|
|
19235
20099
|
createdAt: new Date().toISOString()
|
|
19236
20100
|
};
|
|
@@ -19247,12 +20111,12 @@ function notifyPlaywrightUnavailable(topicId) {
|
|
|
19247
20111
|
appendSystemMessage(topicId, "Playwright browser tools are unavailable this turn. Browser automation was removed from the tool catalog; retry shortly if browser interaction is required.");
|
|
19248
20112
|
WsHub.get().broadcastTopicNotice(topicId, "info", "Playwright \uC0AC\uC6A9 \uBD88\uAC00");
|
|
19249
20113
|
}
|
|
19250
|
-
function appendAskReplyMessage(topicId,
|
|
20114
|
+
function appendAskReplyMessage(topicId, text2, sourceLabel, body, kind, agentType, threadRootId) {
|
|
19251
20115
|
const message = {
|
|
19252
|
-
id:
|
|
20116
|
+
id: randomUUID19(),
|
|
19253
20117
|
topicId,
|
|
19254
20118
|
authorId: "ai",
|
|
19255
|
-
text,
|
|
20119
|
+
text: text2,
|
|
19256
20120
|
kind: "tell",
|
|
19257
20121
|
tellCard: {
|
|
19258
20122
|
fromLabel: sourceLabel,
|
|
@@ -19313,8 +20177,8 @@ function redispatchInject(inject) {
|
|
|
19313
20177
|
kind: "error",
|
|
19314
20178
|
error: "topic gone or AI no longer invited"
|
|
19315
20179
|
});
|
|
19316
|
-
} catch (
|
|
19317
|
-
logger.warn({ err, topicId: inject.topicId }, "ai: deferred settlement hook failed");
|
|
20180
|
+
} catch (err2) {
|
|
20181
|
+
logger.warn({ err: err2, topicId: inject.topicId }, "ai: deferred settlement hook failed");
|
|
19318
20182
|
}
|
|
19319
20183
|
if (inject.forkHandle)
|
|
19320
20184
|
cleanupAgentFork(inject.forkHandle);
|
|
@@ -19372,28 +20236,28 @@ async function clearPendingAskFile(pending, state) {
|
|
|
19372
20236
|
if (!pending.pendingAsk)
|
|
19373
20237
|
return;
|
|
19374
20238
|
try {
|
|
19375
|
-
await init_session_asks();
|
|
20239
|
+
const { clearPendingAsk: clearPendingAsk2, markPendingAskState: markPendingAskState2 } = await init_session_asks().then(() => exports_session_asks);
|
|
19376
20240
|
if (state)
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
} catch (
|
|
19380
|
-
logger.warn({ err, pendingAsk: pending.pendingAsk }, "sessions: pending ask cleanup failed");
|
|
20241
|
+
markPendingAskState2({ ...pending.pendingAsk, state });
|
|
20242
|
+
clearPendingAsk2(pending.pendingAsk);
|
|
20243
|
+
} catch (err2) {
|
|
20244
|
+
logger.warn({ err: err2, pendingAsk: pending.pendingAsk }, "sessions: pending ask cleanup failed");
|
|
19381
20245
|
}
|
|
19382
20246
|
}
|
|
19383
20247
|
async function markPendingAskFile(pending, state) {
|
|
19384
20248
|
if (!pending.pendingAsk)
|
|
19385
20249
|
return;
|
|
19386
20250
|
try {
|
|
19387
|
-
await init_session_asks();
|
|
19388
|
-
|
|
19389
|
-
} catch (
|
|
19390
|
-
logger.warn({ err, pendingAsk: pending.pendingAsk, state }, "sessions: pending ask mark failed");
|
|
20251
|
+
const { markPendingAskState: markPendingAskState2 } = await init_session_asks().then(() => exports_session_asks);
|
|
20252
|
+
markPendingAskState2({ ...pending.pendingAsk, state });
|
|
20253
|
+
} catch (err2) {
|
|
20254
|
+
logger.warn({ err: err2, pendingAsk: pending.pendingAsk, state }, "sessions: pending ask mark failed");
|
|
19391
20255
|
}
|
|
19392
20256
|
}
|
|
19393
20257
|
async function deliverAskCallbackToCaller(pending, sourceLabel, body, kind, options = {}) {
|
|
19394
20258
|
if (pending.remoteReply) {
|
|
19395
|
-
await init_peer_forward();
|
|
19396
|
-
const delivered = await
|
|
20259
|
+
const { deliverPeerReply: deliverPeerReply2 } = await init_peer_forward().then(() => exports_peer_forward);
|
|
20260
|
+
const delivered = await deliverPeerReply2(pending.remoteReply, sourceLabel, body, kind);
|
|
19397
20261
|
if (delivered)
|
|
19398
20262
|
options.onRecorded?.();
|
|
19399
20263
|
return delivered;
|
|
@@ -19413,8 +20277,8 @@ ${body}`;
|
|
|
19413
20277
|
record(undefined);
|
|
19414
20278
|
await clearPendingAskFile(pending);
|
|
19415
20279
|
return true;
|
|
19416
|
-
} catch (
|
|
19417
|
-
logger.warn({ err, requestId: pending.requestId, callerTopicId: pending.callerTopicId }, "sessions: ask callback direct delivery failed");
|
|
20280
|
+
} catch (err2) {
|
|
20281
|
+
logger.warn({ err: err2, requestId: pending.requestId, callerTopicId: pending.callerTopicId }, "sessions: ask callback direct delivery failed");
|
|
19418
20282
|
return false;
|
|
19419
20283
|
}
|
|
19420
20284
|
}
|
|
@@ -19443,9 +20307,9 @@ ${body}`;
|
|
|
19443
20307
|
if (queued) {
|
|
19444
20308
|
try {
|
|
19445
20309
|
record(callerTopic.agent);
|
|
19446
|
-
} catch (
|
|
20310
|
+
} catch (err2) {
|
|
19447
20311
|
interSessionQueue.remove(pending.callerTopicId, pending.requestId);
|
|
19448
|
-
logger.warn({ err, requestId: pending.requestId, callerTopicId: pending.callerTopicId }, "sessions: ask callback record failed after enqueue; queue entry withdrawn");
|
|
20312
|
+
logger.warn({ err: err2, requestId: pending.requestId, callerTopicId: pending.callerTopicId }, "sessions: ask callback record failed after enqueue; queue entry withdrawn");
|
|
19449
20313
|
return false;
|
|
19450
20314
|
}
|
|
19451
20315
|
await markPendingAskFile(pending, "queued_for_caller");
|
|
@@ -19465,8 +20329,8 @@ ${body}`;
|
|
|
19465
20329
|
}
|
|
19466
20330
|
async function deliverAskError(queryId, sourceLabel, error) {
|
|
19467
20331
|
try {
|
|
19468
|
-
await init_ask_callbacks();
|
|
19469
|
-
const pending =
|
|
20332
|
+
const { resolveAskCallback: resolveAskCallback2 } = await init_ask_callbacks().then(() => exports_ask_callbacks);
|
|
20333
|
+
const pending = resolveAskCallback2(queryId);
|
|
19470
20334
|
if (pending) {
|
|
19471
20335
|
const prefix = pending.timedOut ? `\u26A0\uFE0F [Timeout - error notification was dropped]
|
|
19472
20336
|
|
|
@@ -19496,9 +20360,9 @@ function tryReconstructTopicRollout(opts) {
|
|
|
19496
20360
|
entries: entries.length
|
|
19497
20361
|
}, sessionId ? "ai: session expired \u2014 rollout reconstructed from unified log" : "ai: provider session bridged from shared conversation log");
|
|
19498
20362
|
return { kind: "rebuilt", sessionId: result.sessionId };
|
|
19499
|
-
} catch (
|
|
19500
|
-
logger.warn({ err, topicId, agent, sessionId }, "ai: session reconstruct failed");
|
|
19501
|
-
return { kind: "failed", error: stringifyError(
|
|
20363
|
+
} catch (err2) {
|
|
20364
|
+
logger.warn({ err: err2, topicId, agent, sessionId }, "ai: session reconstruct failed");
|
|
20365
|
+
return { kind: "failed", error: stringifyError(err2) };
|
|
19502
20366
|
}
|
|
19503
20367
|
}
|
|
19504
20368
|
function resolveSessionRetry(opts) {
|
|
@@ -19607,8 +20471,8 @@ function waitToStartRemoteUserTurn(params, queryId, options) {
|
|
|
19607
20471
|
function announceQueuedUserTurn(params, queryId) {
|
|
19608
20472
|
try {
|
|
19609
20473
|
params.onDispatched?.(queryId);
|
|
19610
|
-
} catch (
|
|
19611
|
-
logger.warn({ err, topicId: params.topic.id, queryId }, "ai: queued dispatch hook failed");
|
|
20474
|
+
} catch (err2) {
|
|
20475
|
+
logger.warn({ err: err2, topicId: params.topic.id, queryId }, "ai: queued dispatch hook failed");
|
|
19612
20476
|
}
|
|
19613
20477
|
if (!params.silent)
|
|
19614
20478
|
WsHub.get().broadcastAiActive(params.topic.id, queryId);
|
|
@@ -19629,6 +20493,81 @@ function waitToDrainRemoteInject(topicId) {
|
|
|
19629
20493
|
timer.unref?.();
|
|
19630
20494
|
remoteInjectWaiters.set(topicId, timer);
|
|
19631
20495
|
}
|
|
20496
|
+
async function drainOneDurableUserTurn() {
|
|
20497
|
+
if (durableTurnWorkerBusy)
|
|
20498
|
+
return;
|
|
20499
|
+
durableTurnWorkerBusy = true;
|
|
20500
|
+
try {
|
|
20501
|
+
const request = claimNextRuntimeUserTurnRequest(RUNTIME_INSTANCE_ID);
|
|
20502
|
+
if (!request)
|
|
20503
|
+
return;
|
|
20504
|
+
const topic = getTopic(request.topicId);
|
|
20505
|
+
if (!topic?.agent) {
|
|
20506
|
+
completeRuntimeUserTurnRequest(request.topicId, request.requestId, RUNTIME_INSTANCE_ID);
|
|
20507
|
+
return;
|
|
20508
|
+
}
|
|
20509
|
+
const execution = request.execution;
|
|
20510
|
+
const queryId = startAiTurn({
|
|
20511
|
+
topic,
|
|
20512
|
+
userId: request.userId,
|
|
20513
|
+
actorUserId: execution?.actorUserId,
|
|
20514
|
+
actorTopicScope: actorTopicScopeFrom(execution?.actorTopicScope),
|
|
20515
|
+
remoteSession: remoteSessionGrantFrom(execution?.remoteSession),
|
|
20516
|
+
vaultUserId: execution?.vaultUserId,
|
|
20517
|
+
prompt: request.prompt,
|
|
20518
|
+
_userMessages: request.userMessages,
|
|
20519
|
+
_conversationPrompts: execution?.conversationPrompts ?? [request.prompt],
|
|
20520
|
+
_loggedUserMessageCount: execution?.loggedUserMessageCount ?? Math.max(0, request.userMessages.length - (execution?.conversationPrompts?.length ?? 1)),
|
|
20521
|
+
_durableRequestIds: [request.requestId],
|
|
20522
|
+
attachments: request.attachments,
|
|
20523
|
+
allowAutoContinue: request.allowAutoContinue,
|
|
20524
|
+
origin: "user",
|
|
20525
|
+
requestId: execution?.sourceRequestId,
|
|
20526
|
+
agentOverride: execution?.agentOverride,
|
|
20527
|
+
modelOverride: execution?.modelOverride,
|
|
20528
|
+
effortOverride: execution?.effortOverride,
|
|
20529
|
+
...execution?.sessionIdSpecified ? { sessionId: execution.sessionId } : {},
|
|
20530
|
+
sessionScope: execution?.sessionScope,
|
|
20531
|
+
cwd: execution?.cwd,
|
|
20532
|
+
sessionName: execution?.sessionName,
|
|
20533
|
+
sessionType: execution?.sessionType,
|
|
20534
|
+
visualTools: execution?.visualTools,
|
|
20535
|
+
fileDeliveryTools: execution?.fileDeliveryTools,
|
|
20536
|
+
silent: execution?.silent,
|
|
20537
|
+
bridgeSessionFromHistory: execution?.bridgeSessionFromHistory,
|
|
20538
|
+
peerBridge: execution?.peerBridge,
|
|
20539
|
+
from: execution?.from,
|
|
20540
|
+
threadRootId: execution?.threadRootId,
|
|
20541
|
+
_queryId: request.requestId,
|
|
20542
|
+
_runtimeEpoch: execution?.runtimeEpoch ?? request.topicEpoch,
|
|
20543
|
+
onSettled: () => {
|
|
20544
|
+
completeRuntimeUserTurnRequest(request.topicId, request.requestId, RUNTIME_INSTANCE_ID);
|
|
20545
|
+
}
|
|
20546
|
+
});
|
|
20547
|
+
if (!queryId) {
|
|
20548
|
+
releaseRuntimeUserTurnClaim(request.topicId, request.requestId, RUNTIME_INSTANCE_ID);
|
|
20549
|
+
return;
|
|
20550
|
+
}
|
|
20551
|
+
markRuntimeUserTurnRunning(request.topicId, request.requestId, RUNTIME_INSTANCE_ID, queryId);
|
|
20552
|
+
} finally {
|
|
20553
|
+
durableTurnWorkerBusy = false;
|
|
20554
|
+
}
|
|
20555
|
+
}
|
|
20556
|
+
function startDurableTurnRequestWorker() {
|
|
20557
|
+
if (durableTurnWorker)
|
|
20558
|
+
return () => {};
|
|
20559
|
+
durableTurnWorker = setInterval(() => {
|
|
20560
|
+
drainOneDurableUserTurn();
|
|
20561
|
+
}, 100);
|
|
20562
|
+
durableTurnWorker.unref?.();
|
|
20563
|
+
drainOneDurableUserTurn();
|
|
20564
|
+
return () => {
|
|
20565
|
+
if (!durableTurnWorker)
|
|
20566
|
+
return;
|
|
20567
|
+
clearInterval(durableTurnWorker);
|
|
20568
|
+
durableTurnWorker = null;
|
|
20569
|
+
};
|
|
20570
|
+
}
|
|
19632
20571
|
function startAiTurn(params) {
|
|
19633
20572
|
const storedTopic = getTopic(params.topic.id);
|
|
19634
20573
|
if (!storedTopic || !storedTopic.agent && !params.agentOverride) {
|
|
@@ -19640,8 +20579,8 @@ function startAiTurn(params) {
|
|
|
19640
20579
|
kind: "error",
|
|
19641
20580
|
error: storedTopic ? "topic no longer has an AI agent" : "topic no longer exists"
|
|
19642
20581
|
});
|
|
19643
|
-
} catch (
|
|
19644
|
-
logger.warn({ err, topicId: params.topic.id }, "ai: rejected-turn settlement hook failed");
|
|
20582
|
+
} catch (err2) {
|
|
20583
|
+
logger.warn({ err: err2, topicId: params.topic.id }, "ai: rejected-turn settlement hook failed");
|
|
19645
20584
|
}
|
|
19646
20585
|
return null;
|
|
19647
20586
|
}
|
|
@@ -19697,7 +20636,7 @@ function startAiTurn(params) {
|
|
|
19697
20636
|
const askReplySources = params.askReplySources;
|
|
19698
20637
|
const sessionRetried = params._sessionRetried === true;
|
|
19699
20638
|
const emptyResponseRetried = params._emptyResponseRetried === true;
|
|
19700
|
-
const queryId = asTurnId(params._queryId ??
|
|
20639
|
+
const queryId = asTurnId(params._queryId ?? randomUUID19());
|
|
19701
20640
|
const roomId = turnConcurrency === "isolated" ? isolatedTurnRoomId(topicId, queryId) : asTurnSlotKey(topicId);
|
|
19702
20641
|
const currentRuntimeEpoch = getRuntimeTopicEpoch(topic.id);
|
|
19703
20642
|
const runtimeEpoch = params._runtimeEpoch ?? currentRuntimeEpoch;
|
|
@@ -19709,8 +20648,8 @@ function startAiTurn(params) {
|
|
|
19709
20648
|
}
|
|
19710
20649
|
try {
|
|
19711
20650
|
params.onSettled?.({ queryId, kind: "aborted", abortReason: "external" /* External */ });
|
|
19712
|
-
} catch (
|
|
19713
|
-
logger.warn({ err, topicId: topic.id, queryId }, "ai: stale-turn settlement hook failed");
|
|
20651
|
+
} catch (err2) {
|
|
20652
|
+
logger.warn({ err: err2, topicId: topic.id, queryId }, "ai: stale-turn settlement hook failed");
|
|
19714
20653
|
}
|
|
19715
20654
|
logger.info({ topicId: topic.id, queryId, queuedEpoch: params._runtimeEpoch, currentRuntimeEpoch }, "ai: dropped work queued before topic reset");
|
|
19716
20655
|
return null;
|
|
@@ -19760,8 +20699,8 @@ function startAiTurn(params) {
|
|
|
19760
20699
|
cleanupAgentFork(forkHandle);
|
|
19761
20700
|
try {
|
|
19762
20701
|
onSettled?.({ queryId: "", kind: "error", error });
|
|
19763
|
-
} catch (
|
|
19764
|
-
logger.warn({ err, topicId, queryId }, "ai: isolated-turn rejection hook failed");
|
|
20702
|
+
} catch (err2) {
|
|
20703
|
+
logger.warn({ err: err2, topicId, queryId }, "ai: isolated-turn rejection hook failed");
|
|
19765
20704
|
}
|
|
19766
20705
|
return null;
|
|
19767
20706
|
};
|
|
@@ -19808,7 +20747,7 @@ function startAiTurn(params) {
|
|
|
19808
20747
|
if (decision.action === "abort-replace") {
|
|
19809
20748
|
const running = decision.running;
|
|
19810
20749
|
if (isUserOrigin(running.origin) && !sameTurnActor(running.actorUserId, params.actorUserId)) {
|
|
19811
|
-
const
|
|
20750
|
+
const queuedQueryId2 = waitToStartRemoteUserTurn({
|
|
19812
20751
|
...params,
|
|
19813
20752
|
topic,
|
|
19814
20753
|
prompt,
|
|
@@ -19820,9 +20759,9 @@ function startAiTurn(params) {
|
|
|
19820
20759
|
_durableRequestIds: durableRequestIds,
|
|
19821
20760
|
_runtimeEpoch: runtimeEpoch
|
|
19822
20761
|
}, queryId);
|
|
19823
|
-
announceQueuedUserTurn({ ...params, topic },
|
|
19824
|
-
logger.info({ topicId, queryId:
|
|
19825
|
-
return
|
|
20762
|
+
announceQueuedUserTurn({ ...params, topic }, queuedQueryId2);
|
|
20763
|
+
logger.info({ topicId, queryId: queuedQueryId2, runningQueryId: running.queryId }, "ai: user turn from another actor queued behind the running turn");
|
|
20764
|
+
return queuedQueryId2;
|
|
19826
20765
|
}
|
|
19827
20766
|
let omitRequestIds;
|
|
19828
20767
|
if (isUserOrigin(running.origin)) {
|
|
@@ -19954,14 +20893,14 @@ function startAiTurn(params) {
|
|
|
19954
20893
|
if (turnConcurrency === "topic") {
|
|
19955
20894
|
try {
|
|
19956
20895
|
writeQueryState(userId, topic.id, topic.title, prompt);
|
|
19957
|
-
} catch (
|
|
19958
|
-
logger.warn({ err, topicId, userId }, "ai: failed to write active query state");
|
|
20896
|
+
} catch (err2) {
|
|
20897
|
+
logger.warn({ err: err2, topicId, userId }, "ai: failed to write active query state");
|
|
19959
20898
|
}
|
|
19960
20899
|
}
|
|
19961
20900
|
try {
|
|
19962
20901
|
onDispatched?.(queryId);
|
|
19963
|
-
} catch (
|
|
19964
|
-
logger.warn({ err, topicId, queryId }, "ai: dispatch hook failed");
|
|
20902
|
+
} catch (err2) {
|
|
20903
|
+
logger.warn({ err: err2, topicId, queryId }, "ai: dispatch hook failed");
|
|
19965
20904
|
}
|
|
19966
20905
|
const override = getTopicConfig(topicId);
|
|
19967
20906
|
const agentKind = execution.agent;
|
|
@@ -19988,8 +20927,8 @@ function startAiTurn(params) {
|
|
|
19988
20927
|
control.injectParams.sessionId = bridge.sessionId;
|
|
19989
20928
|
try {
|
|
19990
20929
|
onSessionId?.(bridge.sessionId);
|
|
19991
|
-
} catch (
|
|
19992
|
-
logger.warn({ err, topicId, queryId, agent: agentKind }, "ai: isolated session owner rejected bridged provider session id");
|
|
20930
|
+
} catch (err2) {
|
|
20931
|
+
logger.warn({ err: err2, topicId, queryId, agent: agentKind }, "ai: isolated session owner rejected bridged provider session id");
|
|
19993
20932
|
}
|
|
19994
20933
|
} else if (bridge.kind === "failed") {
|
|
19995
20934
|
historyBridgeError = "Conversation history could not be encoded into a provider session; no fresh session was started.";
|
|
@@ -20058,8 +20997,8 @@ function startAiTurn(params) {
|
|
|
20058
20997
|
const wikiDir = getSharedWikiDir();
|
|
20059
20998
|
const { latestSummaryFile } = resolveWikiMemoryMirror(wikiDir, memoryTopic.id, memoryTitle);
|
|
20060
20999
|
hasMemoryArchive = Boolean(resolvedBrief?.brief.latestSummaryMd || latestSummaryFile);
|
|
20061
|
-
} catch (
|
|
20062
|
-
logger.warn({ topicId, err }, "ai: failed to inject topic brief");
|
|
21000
|
+
} catch (err2) {
|
|
21001
|
+
logger.warn({ topicId, err: err2 }, "ai: failed to inject topic brief");
|
|
20063
21002
|
}
|
|
20064
21003
|
systemPrompt += buildMemoryPromptSection({
|
|
20065
21004
|
topicTitle: topic.title,
|
|
@@ -20135,8 +21074,8 @@ function startAiTurn(params) {
|
|
|
20135
21074
|
control.injectParams.sessionId = prepared.forkId;
|
|
20136
21075
|
control.injectParams.forkHandle = prepared;
|
|
20137
21076
|
}
|
|
20138
|
-
} catch (
|
|
20139
|
-
throw new Error(`failed to prepare isolated session: ${stringifyError(
|
|
21077
|
+
} catch (err2) {
|
|
21078
|
+
throw new Error(`failed to prepare isolated session: ${stringifyError(err2)}`);
|
|
20140
21079
|
}
|
|
20141
21080
|
if (abortController.signal.aborted)
|
|
20142
21081
|
return;
|
|
@@ -20155,8 +21094,8 @@ function startAiTurn(params) {
|
|
|
20155
21094
|
throw new Error("browser MCP capability was not registered");
|
|
20156
21095
|
}
|
|
20157
21096
|
trackPlaywrightTurn(playwrightInstanceKey, control);
|
|
20158
|
-
} catch (
|
|
20159
|
-
logger.warn({ topicId, err }, "ai: ensurePlaywright failed \u2014 proceeding without browser tools");
|
|
21097
|
+
} catch (err2) {
|
|
21098
|
+
logger.warn({ topicId, err: err2 }, "ai: ensurePlaywright failed \u2014 proceeding without browser tools");
|
|
20160
21099
|
markPlaywrightUnavailable({
|
|
20161
21100
|
userId,
|
|
20162
21101
|
topic: topic.title,
|
|
@@ -20169,8 +21108,8 @@ function startAiTurn(params) {
|
|
|
20169
21108
|
if (wantsBgBash) {
|
|
20170
21109
|
try {
|
|
20171
21110
|
bgBashPort = await ensureBgBash(userId, topic.id);
|
|
20172
|
-
} catch (
|
|
20173
|
-
logger.warn({ topicId, err }, "ai: ensureBgBash failed \u2014 proceeding without background bash tools");
|
|
21111
|
+
} catch (err2) {
|
|
21112
|
+
logger.warn({ topicId, err: err2 }, "ai: ensureBgBash failed \u2014 proceeding without background bash tools");
|
|
20174
21113
|
turnReminders.push("<system-reminder>Background bash tools are UNAVAILABLE this turn. The `background_bash_*` tools could not be prepared, most often because the bash-rs binary is not installed on this host. Do not attempt to call them; run short commands in the foreground instead, and tell the user if the work genuinely needs a background job.</system-reminder>");
|
|
20175
21114
|
}
|
|
20176
21115
|
}
|
|
@@ -20383,8 +21322,8 @@ function startAiTurn(params) {
|
|
|
20383
21322
|
await settleSubagentFailure(queryId, error);
|
|
20384
21323
|
try {
|
|
20385
21324
|
onSettled?.({ queryId, kind: "error", error });
|
|
20386
|
-
} catch (
|
|
20387
|
-
logger.warn({ err, topicId, queryId }, "ai: turn settlement hook failed");
|
|
21325
|
+
} catch (err2) {
|
|
21326
|
+
logger.warn({ err: err2, topicId, queryId }, "ai: turn settlement hook failed");
|
|
20388
21327
|
}
|
|
20389
21328
|
return;
|
|
20390
21329
|
}
|
|
@@ -20400,8 +21339,8 @@ function startAiTurn(params) {
|
|
|
20400
21339
|
await settleSubagentFailure(queryId, classifyAgentError(outcome.error, agentKind));
|
|
20401
21340
|
try {
|
|
20402
21341
|
onSettled?.({ queryId, kind: "error", error: outcome.error });
|
|
20403
|
-
} catch (
|
|
20404
|
-
logger.warn({ err, topicId, queryId }, "ai: turn settlement hook failed");
|
|
21342
|
+
} catch (err2) {
|
|
21343
|
+
logger.warn({ err: err2, topicId, queryId }, "ai: turn settlement hook failed");
|
|
20405
21344
|
}
|
|
20406
21345
|
return;
|
|
20407
21346
|
}
|
|
@@ -20414,12 +21353,12 @@ function startAiTurn(params) {
|
|
|
20414
21353
|
kind: outcome.kind === "aborted" ? "aborted" : "completed",
|
|
20415
21354
|
...outcome.kind === "aborted" ? { abortReason: control.abortReason } : {}
|
|
20416
21355
|
});
|
|
20417
|
-
} catch (
|
|
20418
|
-
logger.warn({ err, topicId, queryId }, "ai: turn settlement hook failed");
|
|
21356
|
+
} catch (err2) {
|
|
21357
|
+
logger.warn({ err: err2, topicId, queryId }, "ai: turn settlement hook failed");
|
|
20419
21358
|
}
|
|
20420
|
-
}).catch(async (
|
|
20421
|
-
const error =
|
|
20422
|
-
logger.warn({ err, topicId, queryId, agent: agentKind, model: resolvedModel, silent }, "ai: background stream task failed");
|
|
21359
|
+
}).catch(async (err2) => {
|
|
21360
|
+
const error = err2 instanceof Error ? err2.message : "Agent process crashed";
|
|
21361
|
+
logger.warn({ err: err2, topicId, queryId, agent: agentKind, model: resolvedModel, silent }, "ai: background stream task failed");
|
|
20423
21362
|
if (!silent) {
|
|
20424
21363
|
WsHub.get().broadcastError(topicId, queryId, error);
|
|
20425
21364
|
WsHub.get().broadcastTopicNotice(topicId, "error", "\uC751\uB2F5 \uC2E4\uD328");
|
|
@@ -20468,7 +21407,7 @@ function triggerTopicAiTurn(topicId, userId, prompt, agentType, opts) {
|
|
|
20468
21407
|
if (!opts?.silent && !opts?.hideInjectMessage) {
|
|
20469
21408
|
const now = new Date().toISOString();
|
|
20470
21409
|
const injectMsg = {
|
|
20471
|
-
id: opts?.requestId ? `tell-${opts.requestId}` : `tell-${
|
|
21410
|
+
id: opts?.requestId ? `tell-${opts.requestId}` : `tell-${randomUUID19()}`,
|
|
20472
21411
|
topicId,
|
|
20473
21412
|
authorId: opts?.injectAuthorId ?? userId,
|
|
20474
21413
|
sourceAdapter: opts?.injectSourceAdapter,
|
|
@@ -20525,7 +21464,7 @@ function triggerTopicAiTurn(topicId, userId, prompt, agentType, opts) {
|
|
|
20525
21464
|
from: opts?.from
|
|
20526
21465
|
});
|
|
20527
21466
|
}
|
|
20528
|
-
var PLAYWRIGHT_UNAVAILABLE_NOTICE_COOLDOWN_MS, ASK_REPLY_INJECT_BATCH_MS = 500, playwrightUnavailableNoticeAt, askReplyInjectBatcher, remoteInjectWaiters;
|
|
21467
|
+
var PLAYWRIGHT_UNAVAILABLE_NOTICE_COOLDOWN_MS, ASK_REPLY_INJECT_BATCH_MS = 500, playwrightUnavailableNoticeAt, askReplyInjectBatcher, remoteInjectWaiters, durableTurnWorker = null, durableTurnWorkerBusy = false;
|
|
20529
21468
|
var init_turn_runner = __esm(async () => {
|
|
20530
21469
|
init_manager();
|
|
20531
21470
|
init_constants();
|
|
@@ -20656,29 +21595,29 @@ function createSubagentLifecycle(host) {
|
|
|
20656
21595
|
}
|
|
20657
21596
|
function computeSubagentDepth(topicId) {
|
|
20658
21597
|
let depth = 0;
|
|
20659
|
-
let
|
|
21598
|
+
let current3 = host.storage.getTopic(topicId);
|
|
20660
21599
|
const visited = new Set;
|
|
20661
|
-
while (
|
|
20662
|
-
if (visited.has(
|
|
21600
|
+
while (current3) {
|
|
21601
|
+
if (visited.has(current3.id))
|
|
20663
21602
|
return limits.maxDepth;
|
|
20664
|
-
visited.add(
|
|
20665
|
-
if (
|
|
21603
|
+
visited.add(current3.id);
|
|
21604
|
+
if (current3.isSubagent)
|
|
20666
21605
|
depth += 1;
|
|
20667
|
-
if (!
|
|
21606
|
+
if (!current3.parentTopicId || current3.parentTopicId === current3.id)
|
|
20668
21607
|
break;
|
|
20669
|
-
|
|
21608
|
+
current3 = host.storage.getTopic(current3.parentTopicId);
|
|
20670
21609
|
}
|
|
20671
21610
|
return depth;
|
|
20672
21611
|
}
|
|
20673
|
-
function
|
|
21612
|
+
function canSpawnSubagentsFromTopic2(topicId) {
|
|
20674
21613
|
const topic = host.storage.getTopic(topicId);
|
|
20675
21614
|
return topic?.kind === "agent" && computeSubagentDepth(topicId) < limits.maxDepth;
|
|
20676
21615
|
}
|
|
20677
21616
|
function patchSubagentCard(parentTopicId, cardMessageId, patch) {
|
|
20678
|
-
const
|
|
20679
|
-
if (!
|
|
21617
|
+
const current3 = host.storage.getMessage(parentTopicId, cardMessageId)?.subagentCard;
|
|
21618
|
+
if (!current3)
|
|
20680
21619
|
return;
|
|
20681
|
-
const next = { ...
|
|
21620
|
+
const next = { ...current3, ...patch };
|
|
20682
21621
|
const editedAt = host.runtime.now();
|
|
20683
21622
|
if (!host.storage.updateSubagentCard(parentTopicId, cardMessageId, next, editedAt))
|
|
20684
21623
|
return;
|
|
@@ -20698,7 +21637,7 @@ function createSubagentLifecycle(host) {
|
|
|
20698
21637
|
patchSubagentCard(watch.parentTopicId, watch.cardMessageId, { status: "running" });
|
|
20699
21638
|
}
|
|
20700
21639
|
}
|
|
20701
|
-
function
|
|
21640
|
+
function takeSubagentWatch2(queryId) {
|
|
20702
21641
|
const childTopicId = childByQueryId.get(queryId);
|
|
20703
21642
|
if (!childTopicId)
|
|
20704
21643
|
return recoverPersistedSubagentWatch(queryId);
|
|
@@ -20742,7 +21681,7 @@ function createSubagentLifecycle(host) {
|
|
|
20742
21681
|
if (watch.queryId)
|
|
20743
21682
|
childByQueryId.delete(watch.queryId);
|
|
20744
21683
|
}
|
|
20745
|
-
function
|
|
21684
|
+
function cancelSubagentWatchForDeletedTopic2(childTopicId) {
|
|
20746
21685
|
const watch = watchesByChild.get(childTopicId);
|
|
20747
21686
|
if (!watch)
|
|
20748
21687
|
return;
|
|
@@ -20772,8 +21711,8 @@ function createSubagentLifecycle(host) {
|
|
|
20772
21711
|
if (!await host.sessionCommunication.notifyParent({ watch, prompt, requestId })) {
|
|
20773
21712
|
appendParentSystemNote(watch, prompt);
|
|
20774
21713
|
}
|
|
20775
|
-
} catch (
|
|
20776
|
-
logger.warn({ err, parentTopicId: watch.parentTopicId, childTopicId: watch.childTopicId, noteKind }, "subagent: parent AI notify failed \u2014 falling back to system message");
|
|
21714
|
+
} catch (err2) {
|
|
21715
|
+
logger.warn({ err: err2, parentTopicId: watch.parentTopicId, childTopicId: watch.childTopicId, noteKind }, "subagent: parent AI notify failed \u2014 falling back to system message");
|
|
20777
21716
|
try {
|
|
20778
21717
|
appendParentSystemNote(watch, prompt);
|
|
20779
21718
|
} catch (fallbackErr) {
|
|
@@ -20785,7 +21724,7 @@ function createSubagentLifecycle(host) {
|
|
|
20785
21724
|
}
|
|
20786
21725
|
}
|
|
20787
21726
|
}
|
|
20788
|
-
async function
|
|
21727
|
+
async function settleSubagentSuccess2(watch, finalText) {
|
|
20789
21728
|
const summary = finalText.replace(/\s+/g, " ").trim().slice(0, RESULT_SUMMARY_CHARS);
|
|
20790
21729
|
try {
|
|
20791
21730
|
patchSubagentCard(watch.parentTopicId, watch.cardMessageId, {
|
|
@@ -20793,8 +21732,8 @@ function createSubagentLifecycle(host) {
|
|
|
20793
21732
|
resultSummary: summary || "(no text response)",
|
|
20794
21733
|
finishedAt: host.runtime.now()
|
|
20795
21734
|
});
|
|
20796
|
-
} catch (
|
|
20797
|
-
logger.warn({ err, parentTopicId: watch.parentTopicId, cardMessageId: watch.cardMessageId }, "subagent: completed-card update failed");
|
|
21735
|
+
} catch (err2) {
|
|
21736
|
+
logger.warn({ err: err2, parentTopicId: watch.parentTopicId, cardMessageId: watch.cardMessageId }, "subagent: completed-card update failed");
|
|
20798
21737
|
}
|
|
20799
21738
|
if (watch.reportMode === "auto") {
|
|
20800
21739
|
await notifyParent(watch, `[Subagent completed \u2190 ${watch.name}]
|
|
@@ -20803,8 +21742,8 @@ function createSubagentLifecycle(host) {
|
|
|
20803
21742
|
${finalText || "(no text response)"}`, "done");
|
|
20804
21743
|
}
|
|
20805
21744
|
}
|
|
20806
|
-
async function
|
|
20807
|
-
const watch =
|
|
21745
|
+
async function settleSubagentFailure2(queryId, reason) {
|
|
21746
|
+
const watch = takeSubagentWatch2(queryId);
|
|
20808
21747
|
if (!watch)
|
|
20809
21748
|
return;
|
|
20810
21749
|
try {
|
|
@@ -20813,8 +21752,8 @@ ${finalText || "(no text response)"}`, "done");
|
|
|
20813
21752
|
errorMessage: reason,
|
|
20814
21753
|
finishedAt: host.runtime.now()
|
|
20815
21754
|
});
|
|
20816
|
-
} catch (
|
|
20817
|
-
logger.warn({ err, parentTopicId: watch.parentTopicId, cardMessageId: watch.cardMessageId }, "subagent: failed-card update failed");
|
|
21755
|
+
} catch (err2) {
|
|
21756
|
+
logger.warn({ err: err2, parentTopicId: watch.parentTopicId, cardMessageId: watch.cardMessageId }, "subagent: failed-card update failed");
|
|
20818
21757
|
}
|
|
20819
21758
|
if (watch.reportMode === "auto") {
|
|
20820
21759
|
await notifyParent(watch, `[Subagent failed \u2190 ${watch.name}]
|
|
@@ -20851,7 +21790,7 @@ spawn_subagent\uB85C \uC704\uC784\uD55C \uC791\uC5C5\uC774 \uC2E4\uD328\uD588\uC
|
|
|
20851
21790
|
function findSubagentCardMessage(childTopicId) {
|
|
20852
21791
|
return host.storage.listSubagentMessages().filter((message) => message.subagentCard?.subagentTopicId === childTopicId).at(-1);
|
|
20853
21792
|
}
|
|
20854
|
-
function
|
|
21793
|
+
function subagentReportMode2(childTopicId) {
|
|
20855
21794
|
return host.storage.getTopic(childTopicId)?.subagentReportMode ?? findSubagentCardMessage(childTopicId)?.subagentCard?.reportMode ?? "auto";
|
|
20856
21795
|
}
|
|
20857
21796
|
async function startSubagentCard(ctx, cardMessage) {
|
|
@@ -21059,7 +21998,7 @@ ${card.task}${reportInstruction}`;
|
|
|
21059
21998
|
for (const siblings of byParent.values()) {
|
|
21060
21999
|
siblings.sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id));
|
|
21061
22000
|
}
|
|
21062
|
-
const
|
|
22001
|
+
const descendants2 = [];
|
|
21063
22002
|
const visited = new Set([ctx.topicId]);
|
|
21064
22003
|
const visit = (parentId) => {
|
|
21065
22004
|
for (const child of byParent.get(parentId) ?? []) {
|
|
@@ -21069,12 +22008,12 @@ ${card.task}${reportInstruction}`;
|
|
|
21069
22008
|
if (!child.participants.some((participant) => participant.userId === rootOwnerId && participant.role === "owner")) {
|
|
21070
22009
|
continue;
|
|
21071
22010
|
}
|
|
21072
|
-
|
|
22011
|
+
descendants2.push(child);
|
|
21073
22012
|
visit(child.id);
|
|
21074
22013
|
}
|
|
21075
22014
|
};
|
|
21076
22015
|
visit(ctx.topicId);
|
|
21077
|
-
return
|
|
22016
|
+
return descendants2;
|
|
21078
22017
|
})() : [];
|
|
21079
22018
|
const children = actorScope ? descendants.filter((child) => actorScope.visible.has(child.id)) : descendants;
|
|
21080
22019
|
return {
|
|
@@ -21098,10 +22037,10 @@ ${card.task}${reportInstruction}`;
|
|
|
21098
22037
|
return card?.status ?? "unknown";
|
|
21099
22038
|
}
|
|
21100
22039
|
function listMemoryTopicNames(ctx) {
|
|
21101
|
-
const
|
|
21102
|
-
if (!
|
|
22040
|
+
const current3 = host.storage.getTopic(ctx.topicId);
|
|
22041
|
+
if (!current3)
|
|
21103
22042
|
return { error: `Error: topic '${ctx.topicId}' not found.` };
|
|
21104
|
-
if (!
|
|
22043
|
+
if (!current3.participants.some((participant) => participant.userId === ctx.userId)) {
|
|
21105
22044
|
return { error: "Error: user is not a member of this topic." };
|
|
21106
22045
|
}
|
|
21107
22046
|
const sources = new Map;
|
|
@@ -21191,8 +22130,8 @@ ${card.task}${reportInstruction}`;
|
|
|
21191
22130
|
try {
|
|
21192
22131
|
await host.topic.delete(child, ctx.userId);
|
|
21193
22132
|
return textResult(`Subagent deleted: ${child.title} (${child.id})`);
|
|
21194
|
-
} catch (
|
|
21195
|
-
const message =
|
|
22133
|
+
} catch (err2) {
|
|
22134
|
+
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
21196
22135
|
return errorResult(`Error: failed to delete subagent '${child.title}': ${message}`);
|
|
21197
22136
|
}
|
|
21198
22137
|
}
|
|
@@ -21289,13 +22228,13 @@ ${card.task}${reportInstruction}`;
|
|
|
21289
22228
|
}
|
|
21290
22229
|
return {
|
|
21291
22230
|
computeSubagentDepth,
|
|
21292
|
-
canSpawnSubagentsFromTopic,
|
|
21293
|
-
takeSubagentWatch,
|
|
21294
|
-
cancelSubagentWatchForDeletedTopic,
|
|
21295
|
-
settleSubagentSuccess,
|
|
21296
|
-
settleSubagentFailure,
|
|
22231
|
+
canSpawnSubagentsFromTopic: canSpawnSubagentsFromTopic2,
|
|
22232
|
+
takeSubagentWatch: takeSubagentWatch2,
|
|
22233
|
+
cancelSubagentWatchForDeletedTopic: cancelSubagentWatchForDeletedTopic2,
|
|
22234
|
+
settleSubagentSuccess: settleSubagentSuccess2,
|
|
22235
|
+
settleSubagentFailure: settleSubagentFailure2,
|
|
21297
22236
|
sweepStaleSubagentCards,
|
|
21298
|
-
subagentReportMode,
|
|
22237
|
+
subagentReportMode: subagentReportMode2,
|
|
21299
22238
|
createSubagentManagementToolDefinitions,
|
|
21300
22239
|
createSpawnSubagentToolDefinition,
|
|
21301
22240
|
createPrepareSubagentToolDefinition
|
|
@@ -21342,9 +22281,9 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
21342
22281
|
},
|
|
21343
22282
|
topic: {
|
|
21344
22283
|
async createDerived(input) {
|
|
21345
|
-
await init_derive();
|
|
22284
|
+
const { createDerivedTopic: createDerivedTopic2, TopicDeriveBusyError: TopicDeriveBusyError2, TopicTitleConflictError: TopicTitleConflictError2 } = await init_derive().then(() => exports_derive);
|
|
21346
22285
|
try {
|
|
21347
|
-
const topic = await
|
|
22286
|
+
const topic = await createDerivedTopic2(input.parentTopicId, input.userId, false, {
|
|
21348
22287
|
name: input.name,
|
|
21349
22288
|
subagent: {
|
|
21350
22289
|
agent: input.agent,
|
|
@@ -21354,30 +22293,30 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
21354
22293
|
});
|
|
21355
22294
|
return { ok: true, topic };
|
|
21356
22295
|
} catch (error) {
|
|
21357
|
-
if (error instanceof
|
|
22296
|
+
if (error instanceof TopicTitleConflictError2) {
|
|
21358
22297
|
return { ok: false, reason: "title-conflict", message: error.message };
|
|
21359
22298
|
}
|
|
21360
|
-
if (error instanceof
|
|
22299
|
+
if (error instanceof TopicDeriveBusyError2)
|
|
21361
22300
|
return { ok: false, reason: "busy" };
|
|
21362
22301
|
throw error;
|
|
21363
22302
|
}
|
|
21364
22303
|
},
|
|
21365
22304
|
async delete(topic, userId) {
|
|
21366
|
-
await init_lifecycle();
|
|
21367
|
-
await
|
|
22305
|
+
const { deleteTopicCascade: deleteTopicCascade2 } = await init_lifecycle().then(() => exports_lifecycle);
|
|
22306
|
+
await deleteTopicCascade2(topic, userId);
|
|
21368
22307
|
}
|
|
21369
22308
|
},
|
|
21370
22309
|
task: {
|
|
21371
22310
|
async dispatch(input) {
|
|
21372
|
-
await init_turn_runner();
|
|
21373
|
-
await init_active_rooms();
|
|
21374
|
-
const queryId =
|
|
22311
|
+
const { triggerTopicAiTurn: triggerTopicAiTurn2 } = await init_turn_runner().then(() => exports_turn_runner);
|
|
22312
|
+
const { getRoomQuery: getRoomQuery2 } = await init_active_rooms().then(() => exports_active_rooms);
|
|
22313
|
+
const queryId = triggerTopicAiTurn2(input.child.id, input.userId, input.prompt, undefined, {
|
|
21375
22314
|
origin: `subagent-task:${input.parent.title}`,
|
|
21376
22315
|
requestId: input.requestId,
|
|
21377
22316
|
injectAuthorId: "ai",
|
|
21378
22317
|
onDispatched: input.onDispatched
|
|
21379
22318
|
});
|
|
21380
|
-
return { accepted: Boolean(queryId ||
|
|
22319
|
+
return { accepted: Boolean(queryId || getRoomQuery2(input.child.id)) };
|
|
21381
22320
|
}
|
|
21382
22321
|
},
|
|
21383
22322
|
sessionCommunication: {
|
|
@@ -21385,16 +22324,16 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
21385
22324
|
const parent = getTopic(watch.parentTopicId);
|
|
21386
22325
|
if (!parent)
|
|
21387
22326
|
return true;
|
|
21388
|
-
await init_turn_runner();
|
|
21389
|
-
const queryId = parent.agent ?
|
|
22327
|
+
const { triggerTopicAiTurn: triggerTopicAiTurn2 } = await init_turn_runner().then(() => exports_turn_runner);
|
|
22328
|
+
const queryId = parent.agent ? triggerTopicAiTurn2(watch.parentTopicId, watch.userId, prompt, undefined, {
|
|
21390
22329
|
origin: `subagent:${watch.name}`,
|
|
21391
22330
|
requestId,
|
|
21392
22331
|
hideInjectMessage: true
|
|
21393
22332
|
}) : null;
|
|
21394
22333
|
if (queryId)
|
|
21395
22334
|
return true;
|
|
21396
|
-
await init_active_rooms();
|
|
21397
|
-
return Boolean(parent.agent &&
|
|
22335
|
+
const { interSessionQueue: interSessionQueue2 } = await init_active_rooms().then(() => exports_active_rooms);
|
|
22336
|
+
return Boolean(parent.agent && interSessionQueue2.hasRequest(parent.id, requestId));
|
|
21398
22337
|
},
|
|
21399
22338
|
listTellTargetIds: listSubagentTellTargetIds,
|
|
21400
22339
|
grantTellTarget: grantSubagentTellTarget,
|
|
@@ -21423,19 +22362,19 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
21423
22362
|
async resolveAgentModel({ context, agent, model, hasOverride }) {
|
|
21424
22363
|
let resolvedModel = model;
|
|
21425
22364
|
if (model) {
|
|
21426
|
-
await Promise.resolve().then(() => init_model_catalog());
|
|
21427
|
-
await init_registry();
|
|
21428
|
-
const registry =
|
|
22365
|
+
const { resolveModelForAgent: resolveModelForAgent2 } = await Promise.resolve().then(() => (init_model_catalog(), exports_model_catalog));
|
|
22366
|
+
const { getRegistry: getRegistry2 } = await init_registry().then(() => exports_registry);
|
|
22367
|
+
const registry = getRegistry2(agent);
|
|
21429
22368
|
if (!registry.validateModel(model)) {
|
|
21430
22369
|
return { error: `Error: model '${model}' is not valid for agent '${agent}'.` };
|
|
21431
22370
|
}
|
|
21432
|
-
resolvedModel =
|
|
22371
|
+
resolvedModel = resolveModelForAgent2(agent, model, registry);
|
|
21433
22372
|
}
|
|
21434
22373
|
if (hasOverride) {
|
|
21435
|
-
await init_auth_check();
|
|
21436
|
-
await init_registry();
|
|
21437
|
-
const targetModel = resolvedModel ??
|
|
21438
|
-
const auth =
|
|
22374
|
+
const { checkAgentModelAuth: checkAgentModelAuth2 } = await init_auth_check().then(() => exports_auth_check);
|
|
22375
|
+
const { getRegistry: getRegistry2 } = await init_registry().then(() => exports_registry);
|
|
22376
|
+
const targetModel = resolvedModel ?? getRegistry2(agent).defaultModel;
|
|
22377
|
+
const auth = checkAgentModelAuth2(agent, targetModel, undefined, context.userId);
|
|
21439
22378
|
if (!auth.ok) {
|
|
21440
22379
|
return { error: `Error: agent '${agent}' is not available: ${auth.error}` };
|
|
21441
22380
|
}
|
|
@@ -21865,11 +22804,11 @@ var DEFAULT_SELF_CONFIG_PRODUCT = {
|
|
|
21865
22804
|
derivedTopicLimit: SELF_CONFIG_DERIVED_TOPIC_LIMIT,
|
|
21866
22805
|
toolDescriptions: {}
|
|
21867
22806
|
};
|
|
21868
|
-
function ok(
|
|
21869
|
-
return { text };
|
|
22807
|
+
function ok(text2) {
|
|
22808
|
+
return { text: text2 };
|
|
21870
22809
|
}
|
|
21871
|
-
function err(
|
|
21872
|
-
return { text, isError: true };
|
|
22810
|
+
function err(text2) {
|
|
22811
|
+
return { text: text2, isError: true };
|
|
21873
22812
|
}
|
|
21874
22813
|
function errorMessage(error) {
|
|
21875
22814
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -22186,8 +23125,8 @@ var defaultSelfConfigHost = {
|
|
|
22186
23125
|
},
|
|
22187
23126
|
derivedTopics: {
|
|
22188
23127
|
async create(sourceTopicId, userId, copyHistory, options) {
|
|
22189
|
-
await init_derive();
|
|
22190
|
-
return
|
|
23128
|
+
const { createDerivedTopic: createDerivedTopic2 } = await init_derive().then(() => exports_derive);
|
|
23129
|
+
return createDerivedTopic2(sourceTopicId, userId, copyHistory, options);
|
|
22191
23130
|
},
|
|
22192
23131
|
link: topicMarkdownLink,
|
|
22193
23132
|
isTitleConflict: (error) => error instanceof Error && error.name === "TopicTitleConflictError",
|
|
@@ -22467,58 +23406,58 @@ await __promiseAll([
|
|
|
22467
23406
|
init_topic_cleanup()
|
|
22468
23407
|
]);
|
|
22469
23408
|
export {
|
|
22470
|
-
|
|
22471
|
-
MIN_MEMORY_ARCHIVE_EXCHANGES,
|
|
22472
|
-
SELF_CONFIG_CAPABILITIES,
|
|
22473
|
-
VISUALS_MCP_KEY,
|
|
22474
|
-
acquireCodexSpawnLock,
|
|
22475
|
-
applySelfConfigCapabilityFilter,
|
|
22476
|
-
archiveActiveTopicForMemory,
|
|
22477
|
-
buildNumberedDiffSummary,
|
|
22478
|
-
checkAgentAuth,
|
|
22479
|
-
checkAgentModelAuth,
|
|
22480
|
-
classifyShellToolName,
|
|
22481
|
-
cleanupAgentFork,
|
|
22482
|
-
cleanupTopicRollouts,
|
|
22483
|
-
cleanupTopicRolloutsFromEntries,
|
|
22484
|
-
createAgentForkHelpers,
|
|
22485
|
-
createArchiverRuntime,
|
|
22486
|
-
createAskUserRuntime,
|
|
22487
|
-
createCodexTreeManager,
|
|
22488
|
-
createPublishHtmlToolDefinitions,
|
|
22489
|
-
createSelfConfigCore,
|
|
22490
|
-
createSelfConfigRuntime,
|
|
22491
|
-
createSelfConfigToolDefinitionsForCore,
|
|
22492
|
-
createSubagentLifecycle,
|
|
22493
|
-
createTopicLogMaintenance,
|
|
22494
|
-
defaultAskUserDurabilityHost,
|
|
22495
|
-
explicitAgentSwitchTargets,
|
|
22496
|
-
findNewCodexChildren,
|
|
22497
|
-
forkAgentSession,
|
|
22498
|
-
formatToolUse,
|
|
22499
|
-
hasExplicitAgentSwitchRequest,
|
|
22500
|
-
isExplicitAgentSwitchTargets,
|
|
22501
|
-
killCodexTrees,
|
|
22502
|
-
killOwnedCodexTreesForShutdown,
|
|
22503
|
-
normalizeAskUserChoices,
|
|
22504
|
-
normalizeAskUserQuestionInput,
|
|
22505
|
-
otiumVisualToolDefinitions,
|
|
22506
|
-
purgeTopicLogs,
|
|
22507
|
-
registerOwnedCodexPids,
|
|
22508
|
-
resolveTaskEventScope,
|
|
22509
|
-
rotateTopicLogs,
|
|
22510
|
-
showHtmlTool,
|
|
22511
|
-
showImageTool,
|
|
22512
|
-
showMermaidTool,
|
|
22513
|
-
showPngTool,
|
|
22514
|
-
snapshotCodexChildren,
|
|
22515
|
-
summarizeDisplayText,
|
|
22516
|
-
summarizeShellCommand,
|
|
22517
|
-
summarizeToolInput,
|
|
22518
|
-
unregisterOwnedCodexPids,
|
|
22519
|
-
visualToolDefinitions,
|
|
23409
|
+
withTaskSnapshots,
|
|
22520
23410
|
withCodexSpawnSerial,
|
|
22521
|
-
|
|
23411
|
+
visualToolDefinitions,
|
|
23412
|
+
unregisterOwnedCodexPids,
|
|
23413
|
+
summarizeToolInput,
|
|
23414
|
+
summarizeShellCommand,
|
|
23415
|
+
summarizeDisplayText,
|
|
23416
|
+
snapshotCodexChildren,
|
|
23417
|
+
showPngTool,
|
|
23418
|
+
showMermaidTool,
|
|
23419
|
+
showImageTool,
|
|
23420
|
+
showHtmlTool,
|
|
23421
|
+
rotateTopicLogs,
|
|
23422
|
+
resolveTaskEventScope,
|
|
23423
|
+
registerOwnedCodexPids,
|
|
23424
|
+
purgeTopicLogs,
|
|
23425
|
+
otiumVisualToolDefinitions,
|
|
23426
|
+
normalizeAskUserQuestionInput,
|
|
23427
|
+
normalizeAskUserChoices,
|
|
23428
|
+
killOwnedCodexTreesForShutdown,
|
|
23429
|
+
killCodexTrees,
|
|
23430
|
+
isExplicitAgentSwitchTargets,
|
|
23431
|
+
hasExplicitAgentSwitchRequest,
|
|
23432
|
+
formatToolUse,
|
|
23433
|
+
forkAgentSession,
|
|
23434
|
+
findNewCodexChildren,
|
|
23435
|
+
explicitAgentSwitchTargets,
|
|
23436
|
+
defaultAskUserDurabilityHost,
|
|
23437
|
+
createTopicLogMaintenance,
|
|
23438
|
+
createSubagentLifecycle,
|
|
23439
|
+
createSelfConfigToolDefinitionsForCore,
|
|
23440
|
+
createSelfConfigRuntime,
|
|
23441
|
+
createSelfConfigCore,
|
|
23442
|
+
createPublishHtmlToolDefinitions,
|
|
23443
|
+
createCodexTreeManager,
|
|
23444
|
+
createAskUserRuntime,
|
|
23445
|
+
createArchiverRuntime,
|
|
23446
|
+
createAgentForkHelpers,
|
|
23447
|
+
cleanupTopicRolloutsFromEntries,
|
|
23448
|
+
cleanupTopicRollouts,
|
|
23449
|
+
cleanupAgentFork,
|
|
23450
|
+
classifyShellToolName,
|
|
23451
|
+
checkAgentModelAuth,
|
|
23452
|
+
checkAgentAuth,
|
|
23453
|
+
buildNumberedDiffSummary,
|
|
23454
|
+
archiveActiveTopicForMemory,
|
|
23455
|
+
applySelfConfigCapabilityFilter,
|
|
23456
|
+
acquireCodexSpawnLock,
|
|
23457
|
+
VISUALS_MCP_KEY,
|
|
23458
|
+
SELF_CONFIG_CAPABILITIES,
|
|
23459
|
+
MIN_MEMORY_ARCHIVE_EXCHANGES,
|
|
23460
|
+
DEFAULT_SELF_CONFIG_PRODUCT
|
|
22522
23461
|
};
|
|
22523
23462
|
|
|
22524
|
-
//# debugId=
|
|
23463
|
+
//# debugId=E43DD0B32649A10364756E2164756E21
|