negotium 0.22.4 → 0.22.6
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 +408 -1301
- package/dist/agent-helpers.js.map +6 -6
- package/dist/background-bash.js +12 -12
- package/dist/background-bash.js.map +2 -2
- package/dist/browser-runtime.js +42 -44
- package/dist/browser-runtime.js.map +2 -2
- package/dist/canonical-mcp-bridge.js +8 -9
- package/dist/canonical-mcp-bridge.js.map +1 -1
- package/dist/{chunk-y4tyc603.js → chunk-1e0nxy7p.js} +13 -13
- package/dist/chunk-1e0nxy7p.js.map +10 -0
- package/dist/{chunk-9zn0bkc9.js → chunk-1mba9m1j.js} +77 -116
- package/dist/{chunk-9zn0bkc9.js.map → chunk-1mba9m1j.js.map} +2 -2
- package/dist/{chunk-rwj7x5pg.js → chunk-9a50csg6.js} +123 -121
- package/dist/{chunk-rwj7x5pg.js.map → chunk-9a50csg6.js.map} +7 -7
- package/dist/chunk-bnyvxss3.js +77 -0
- package/dist/{chunk-q5djsg78.js.map → chunk-bnyvxss3.js.map} +1 -1
- package/dist/{chunk-0jtan6fd.js → chunk-e59kzyvy.js} +4 -5
- package/dist/{chunk-0jtan6fd.js.map → chunk-e59kzyvy.js.map} +2 -2
- package/dist/{chunk-f7p0h1gs.js → chunk-ww8a4ej4.js} +5 -5
- package/dist/{chunk-f7p0h1gs.js.map → chunk-ww8a4ej4.js.map} +2 -2
- package/dist/hosted-agent.js +127 -124
- package/dist/hosted-agent.js.map +4 -4
- package/dist/main.js +3327 -5138
- package/dist/main.js.map +10 -10
- package/dist/mcp-catalog.js +4 -4
- package/dist/mcp-catalog.js.map +1 -1
- package/dist/mcp-factories.js +630 -1515
- package/dist/mcp-factories.js.map +6 -6
- 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 +16 -18
- package/dist/query-runtime.js.map +2 -2
- package/dist/registry.js +19 -20
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +41 -41
- package/dist/rollout.js.map +2 -2
- package/dist/runtime/src/agents/rollout/claude.ts +6 -1
- package/dist/runtime/src/application/submit-runtime-gateway-turn.ts +6 -4
- package/dist/runtime/src/node-host.ts +1 -0
- package/dist/runtime/src/platform/mcp-config.ts +60 -28
- package/dist/runtime/src/runtime/turn-runner.ts +9 -4
- package/dist/runtime/src/topics/update.ts +20 -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 +52 -54
- package/dist/runtime-helpers.js.map +2 -2
- package/dist/sqlite.js +3 -5
- package/dist/sqlite.js.map +2 -2
- package/dist/storage.js +4831 -4802
- package/dist/storage.js.map +2 -2
- package/dist/types/packages/core/src/agents/rollout/claude.d.ts +5 -0
- package/dist/types/packages/core/src/platform/mcp-config.d.ts +8 -0
- package/dist/types/packages/core/src/runtime/turn-runner.d.ts +6 -2
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js +20 -22
- package/dist/vault.js.map +2 -2
- package/package.json +1 -1
- package/dist/chunk-2mx7fq49.js +0 -6
- package/dist/chunk-2mx7fq49.js.map +0 -9
- package/dist/chunk-q5djsg78.js +0 -200
- package/dist/chunk-y4tyc603.js.map +0 -10
package/dist/mcp-factories.js
CHANGED
|
@@ -13,9 +13,18 @@ var __export = (target, all) => {
|
|
|
13
13
|
set: __exportSetter.bind(all, name)
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
|
-
var __esm = (fn, res) => () =>
|
|
16
|
+
var __esm = (fn, res, err) => () => {
|
|
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
|
+
};
|
|
17
27
|
var __promiseAll = (args) => Promise.all(args);
|
|
18
|
-
var __require = import.meta.require;
|
|
19
28
|
|
|
20
29
|
// ../../packages/core/src/runtime/actor-topic-scope.ts
|
|
21
30
|
function actorTopicScopeMaxAgeMs(env = process.env) {
|
|
@@ -104,9 +113,6 @@ function parseActorTopicScope(value) {
|
|
|
104
113
|
const validated = validateActorTopicScope(value);
|
|
105
114
|
return validated.ok ? validated.scope : null;
|
|
106
115
|
}
|
|
107
|
-
function actorTopicScopeFrom(value) {
|
|
108
|
-
return parseActorTopicScope(value) ?? undefined;
|
|
109
|
-
}
|
|
110
116
|
function intersectActorTopicScopes(scopes) {
|
|
111
117
|
if (scopes.length === 0 || scopes.some((scope) => scope === undefined))
|
|
112
118
|
return;
|
|
@@ -221,9 +227,6 @@ function parseRemoteSessionGrant(value) {
|
|
|
221
227
|
const validated = validateRemoteSessionGrant(value);
|
|
222
228
|
return validated.ok ? validated.grant : null;
|
|
223
229
|
}
|
|
224
|
-
function remoteSessionGrantFrom(value) {
|
|
225
|
-
return parseRemoteSessionGrant(value) ?? undefined;
|
|
226
|
-
}
|
|
227
230
|
function remoteSessionGrantExpiry(grant) {
|
|
228
231
|
const payload = grant.capability.split(".")[1];
|
|
229
232
|
if (!payload)
|
|
@@ -270,7 +273,7 @@ function decodeRemoteSessionGrantArg(value) {
|
|
|
270
273
|
return null;
|
|
271
274
|
}
|
|
272
275
|
}
|
|
273
|
-
var REMOTE_SESSION_GRANT_LIMITS, GRANT_KEYS, LOOPBACK_HOSTS,
|
|
276
|
+
var REMOTE_SESSION_GRANT_LIMITS, GRANT_KEYS, LOOPBACK_HOSTS, MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH;
|
|
274
277
|
var init_remote_session_grant = __esm(() => {
|
|
275
278
|
REMOTE_SESSION_GRANT_LIMITS = Object.freeze({
|
|
276
279
|
maxHubUrlLength: 512,
|
|
@@ -279,7 +282,6 @@ var init_remote_session_grant = __esm(() => {
|
|
|
279
282
|
});
|
|
280
283
|
GRANT_KEYS = ["hubUrl", "capability"];
|
|
281
284
|
LOOPBACK_HOSTS = new Set(["127.0.0.1", "::1", "[::1]", "localhost"]);
|
|
282
|
-
REMOTE_SESSION_REPLY_TOKEN_PATTERN = /^rsr1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
283
285
|
MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH = REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength;
|
|
284
286
|
});
|
|
285
287
|
|
|
@@ -366,21 +368,21 @@ var init_sqlite = __esm(async () => {
|
|
|
366
368
|
|
|
367
369
|
// ../../packages/core/src/platform/config-helpers.ts
|
|
368
370
|
function readEnvText(env, key) {
|
|
369
|
-
const
|
|
370
|
-
return
|
|
371
|
+
const value = env[key]?.trim();
|
|
372
|
+
return value || undefined;
|
|
371
373
|
}
|
|
372
374
|
function resolveFallbackAgent(env = process.env) {
|
|
373
|
-
const
|
|
374
|
-
return isAgentKind(
|
|
375
|
+
const value = readEnvText(env, "FALLBACK_AGENT") ?? readEnvText(env, "DEFAULT_AGENT");
|
|
376
|
+
return isAgentKind(value) ? value : "claude";
|
|
375
377
|
}
|
|
376
|
-
function parseRuntimePort(
|
|
377
|
-
if (!
|
|
378
|
+
function parseRuntimePort(value, fallback) {
|
|
379
|
+
if (!value)
|
|
378
380
|
return fallback;
|
|
379
|
-
const port = Number.parseInt(
|
|
381
|
+
const port = Number.parseInt(value, 10);
|
|
380
382
|
return Number.isInteger(port) && port > 0 && port <= 65535 ? port : fallback;
|
|
381
383
|
}
|
|
382
|
-
function safeRuntimePathSegment(
|
|
383
|
-
const cleaned =
|
|
384
|
+
function safeRuntimePathSegment(value, fallback, maxLength = 160) {
|
|
385
|
+
const cleaned = value.trim().replace(/[^A-Za-z0-9._-]/g, "_").replace(/^_+|_+$/g, "").slice(0, maxLength);
|
|
384
386
|
return cleaned || fallback;
|
|
385
387
|
}
|
|
386
388
|
var init_config_helpers = __esm(() => {
|
|
@@ -409,105 +411,6 @@ var init_logger = __esm(() => {
|
|
|
409
411
|
});
|
|
410
412
|
|
|
411
413
|
// ../../packages/core/src/platform/config.ts
|
|
412
|
-
var exports_config = {};
|
|
413
|
-
__export(exports_config, {
|
|
414
|
-
resolveTopicWorkspaceDir: () => resolveTopicWorkspaceDir,
|
|
415
|
-
resolveOutputLanguage: () => resolveOutputLanguage,
|
|
416
|
-
resolveBrowserRsBin: () => resolveBrowserRsBin,
|
|
417
|
-
resolveBrowserProxy: () => resolveBrowserProxy,
|
|
418
|
-
resolveBrowserMcpBin: () => resolveBrowserMcpBin,
|
|
419
|
-
resolveBashRsBin: () => resolveBashRsBin,
|
|
420
|
-
isProductionEnv: () => isProductionEnv,
|
|
421
|
-
hostname: () => hostname,
|
|
422
|
-
getCleanEnv: () => getCleanEnv,
|
|
423
|
-
envText: () => envText,
|
|
424
|
-
codexAuthFilePath: () => codexAuthFilePath,
|
|
425
|
-
WORKSPACE_DIR: () => WORKSPACE_DIR,
|
|
426
|
-
WIKI_SERVER: () => WIKI_SERVER,
|
|
427
|
-
WHISPER_MODEL_MLX: () => WHISPER_MODEL_MLX,
|
|
428
|
-
WHISPER_MODEL: () => WHISPER_MODEL,
|
|
429
|
-
WHISPER_BACKEND: () => WHISPER_BACKEND,
|
|
430
|
-
VAULT_SERVER: () => VAULT_SERVER,
|
|
431
|
-
VAULT_MASTER_KEY: () => VAULT_MASTER_KEY,
|
|
432
|
-
VAULT_DIR: () => VAULT_DIR,
|
|
433
|
-
USERS_LOG_DIR: () => USERS_LOG_DIR,
|
|
434
|
-
UPLOADS_DIR: () => UPLOADS_DIR,
|
|
435
|
-
TSX_LOADER: () => TSX_LOADER,
|
|
436
|
-
TSX_BIN: () => TSX_BIN,
|
|
437
|
-
TSCONFIG_PATH: () => TSCONFIG_PATH,
|
|
438
|
-
TOPIC_WORKSPACE_DIR: () => TOPIC_WORKSPACE_DIR,
|
|
439
|
-
TOKEN_STATS_SERVER: () => TOKEN_STATS_SERVER,
|
|
440
|
-
TESSERACT_BIN: () => TESSERACT_BIN,
|
|
441
|
-
TASK_SERVER: () => TASK_SERVER,
|
|
442
|
-
SYSTEM_HEALTH_SERVER: () => SYSTEM_HEALTH_SERVER,
|
|
443
|
-
STATE_DIR: () => STATE_DIR,
|
|
444
|
-
SNIPPETS_API_URL: () => SNIPPETS_API_URL,
|
|
445
|
-
SHARED_WIKI_DIR: () => SHARED_WIKI_DIR,
|
|
446
|
-
SESSION_WORKSPACE_DIR: () => SESSION_WORKSPACE_DIR,
|
|
447
|
-
SESSION_INBOX_DIR: () => SESSION_INBOX_DIR,
|
|
448
|
-
SESSION_COMM_SERVER: () => SESSION_COMM_SERVER,
|
|
449
|
-
SESSION_ASKS_DIR: () => SESSION_ASKS_DIR,
|
|
450
|
-
SESSIONS_DB: () => SESSIONS_DB,
|
|
451
|
-
SECRETS_DIR: () => SECRETS_DIR,
|
|
452
|
-
RUN_DIR: () => RUN_DIR,
|
|
453
|
-
RUNTIME_MCP_SECRET: () => RUNTIME_MCP_SECRET,
|
|
454
|
-
RUNTIME_DIR: () => RUNTIME_DIR,
|
|
455
|
-
RESOURCES_DIR: () => RESOURCES_DIR,
|
|
456
|
-
PYTHON_BIN: () => PYTHON_BIN,
|
|
457
|
-
PROJECT_ROOT: () => PROJECT_ROOT,
|
|
458
|
-
PROGRESS_DIR: () => PROGRESS_DIR,
|
|
459
|
-
PLAYWRIGHT_PORTS_DIR: () => PLAYWRIGHT_PORTS_DIR,
|
|
460
|
-
PLAYWRIGHT_MCP_BIN: () => PLAYWRIGHT_MCP_BIN,
|
|
461
|
-
PLAYWRIGHT_MAX_PORT: () => PLAYWRIGHT_MAX_PORT,
|
|
462
|
-
PLAYWRIGHT_BASE_PORT: () => PLAYWRIGHT_BASE_PORT,
|
|
463
|
-
PDFTOTEXT_BIN: () => PDFTOTEXT_BIN,
|
|
464
|
-
NODE_ID: () => NODE_ID,
|
|
465
|
-
NODE_CONTROL_TOKEN: () => NODE_CONTROL_TOKEN,
|
|
466
|
-
NEGOTIUM_PORT: () => NEGOTIUM_PORT,
|
|
467
|
-
MODEL_SONNET: () => MODEL_SONNET,
|
|
468
|
-
MODEL_OPUS: () => MODEL_OPUS,
|
|
469
|
-
MODEL_HAIKU: () => MODEL_HAIKU,
|
|
470
|
-
MODEL_FABLE: () => MODEL_FABLE,
|
|
471
|
-
MODEL_DEEPSEEK_V4_PRO: () => MODEL_DEEPSEEK_V4_PRO,
|
|
472
|
-
MODEL_DEEPSEEK_V4_FLASH: () => MODEL_DEEPSEEK_V4_FLASH,
|
|
473
|
-
MLX_WHISPER_BIN: () => MLX_WHISPER_BIN,
|
|
474
|
-
MAX_TELL_DEPTH: () => MAX_TELL_DEPTH,
|
|
475
|
-
LOG_DIR: () => LOG_DIR,
|
|
476
|
-
FILE_TAG_REGEX: () => FILE_TAG_REGEX,
|
|
477
|
-
FILE_EXTENSIONS_REGEX: () => FILE_EXTENSIONS_REGEX,
|
|
478
|
-
FFPROBE_BIN: () => FFPROBE_BIN,
|
|
479
|
-
FFMPEG_BIN: () => FFMPEG_BIN,
|
|
480
|
-
FASTER_WHISPER_WRAPPER: () => FASTER_WHISPER_WRAPPER,
|
|
481
|
-
FALLBACK_MODEL: () => FALLBACK_MODEL,
|
|
482
|
-
FALLBACK_AGENT: () => FALLBACK_AGENT,
|
|
483
|
-
DM_WORKSPACE_DIR: () => DM_WORKSPACE_DIR,
|
|
484
|
-
DM_RESP_DIR: () => DM_RESP_DIR,
|
|
485
|
-
DM_CMD_DIR: () => DM_CMD_DIR,
|
|
486
|
-
DEFAULT_TOPIC_EFFORT: () => DEFAULT_TOPIC_EFFORT,
|
|
487
|
-
DEFAULT_OUTPUT_LANGUAGE: () => DEFAULT_OUTPUT_LANGUAGE,
|
|
488
|
-
DECISION_SERVER: () => DECISION_SERVER,
|
|
489
|
-
DEBUG_FILE: () => DEBUG_FILE,
|
|
490
|
-
DATA_DIR: () => DATA_DIR,
|
|
491
|
-
CRON_WORKSPACE_DIR: () => CRON_WORKSPACE_DIR,
|
|
492
|
-
COMPACTION_LOG_SERVER: () => COMPACTION_LOG_SERVER,
|
|
493
|
-
CLAUDE_EXECUTABLE: () => CLAUDE_EXECUTABLE,
|
|
494
|
-
CANONICAL_MCP_PROXY_SERVER: () => CANONICAL_MCP_PROXY_SERVER,
|
|
495
|
-
BROWSER_RS_VERSION: () => BROWSER_RS_VERSION,
|
|
496
|
-
BROWSER_RS_MIN_SECURE_VERSION: () => BROWSER_RS_MIN_SECURE_VERSION,
|
|
497
|
-
BROWSER_RS_BIN: () => BROWSER_RS_BIN,
|
|
498
|
-
BROWSER_PROFILES_DIR: () => BROWSER_PROFILES_DIR,
|
|
499
|
-
BROWSER_DIR: () => BROWSER_DIR,
|
|
500
|
-
BINARY_EXTENSION: () => BINARY_EXTENSION,
|
|
501
|
-
BINARIES_DIR: () => BINARIES_DIR,
|
|
502
|
-
BG_BASH_MAX_PORT: () => BG_BASH_MAX_PORT,
|
|
503
|
-
BG_BASH_BASE_PORT: () => BG_BASH_BASE_PORT,
|
|
504
|
-
BASH_RS_VERSION: () => BASH_RS_VERSION,
|
|
505
|
-
BASH_RS_BIN: () => BASH_RS_BIN,
|
|
506
|
-
BASHRS_SPILL_ROOT: () => BASHRS_SPILL_ROOT,
|
|
507
|
-
AGENT_HEALTH_SERVER: () => AGENT_HEALTH_SERVER,
|
|
508
|
-
AGENTS_PROMPTS_DIR: () => AGENTS_PROMPTS_DIR,
|
|
509
|
-
ACTIVE_QUERY_STALE_MS: () => ACTIVE_QUERY_STALE_MS
|
|
510
|
-
});
|
|
511
414
|
import { execFileSync } from "child_process";
|
|
512
415
|
import { randomBytes } from "crypto";
|
|
513
416
|
import {
|
|
@@ -651,15 +554,12 @@ function resolveBrowserProxy() {
|
|
|
651
554
|
proxy.bypass = bypass;
|
|
652
555
|
return proxy;
|
|
653
556
|
}
|
|
654
|
-
function safeWorkspaceSegment(
|
|
655
|
-
return safeRuntimePathSegment(
|
|
557
|
+
function safeWorkspaceSegment(value, fallback) {
|
|
558
|
+
return safeRuntimePathSegment(value, fallback);
|
|
656
559
|
}
|
|
657
560
|
function resolveTopicWorkspaceDir(topicId) {
|
|
658
561
|
return join(TOPIC_WORKSPACE_DIR, safeWorkspaceSegment(topicId, "topic"));
|
|
659
562
|
}
|
|
660
|
-
function isProductionEnv() {
|
|
661
|
-
return false;
|
|
662
|
-
}
|
|
663
563
|
function loadOrCreateLocalSecret(envKey, filename, options = {}) {
|
|
664
564
|
const envValue = envText(envKey);
|
|
665
565
|
const secretFile = resolve(SECRETS_DIR, filename);
|
|
@@ -694,18 +594,13 @@ function loadOrCreateLocalSecret(envKey, filename, options = {}) {
|
|
|
694
594
|
return stored;
|
|
695
595
|
}
|
|
696
596
|
}
|
|
697
|
-
function getCleanEnv() {
|
|
698
|
-
const env = { ...process.env };
|
|
699
|
-
delete env.CLAUDECODE;
|
|
700
|
-
return env;
|
|
701
|
-
}
|
|
702
597
|
function resolveWhisperBackend() {
|
|
703
598
|
return envText("WHISPER_BACKEND") === "mlx-whisper" ? "mlx-whisper" : "faster-whisper";
|
|
704
599
|
}
|
|
705
600
|
function codexAuthFilePath() {
|
|
706
601
|
return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
|
|
707
602
|
}
|
|
708
|
-
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,
|
|
603
|
+
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;
|
|
709
604
|
var init_config = __esm(() => {
|
|
710
605
|
init_config_helpers();
|
|
711
606
|
init_logger();
|
|
@@ -761,7 +656,6 @@ var init_config = __esm(() => {
|
|
|
761
656
|
DEBUG_FILE = resolve(DATA_DIR, "debug-users.json");
|
|
762
657
|
USERS_LOG_DIR = resolve(DATA_DIR, "users");
|
|
763
658
|
RUN_DIR = resolveLocalStateDir("NEGOTIUM_RUN_DIR", "runtime");
|
|
764
|
-
RUNTIME_DIR = RUN_DIR;
|
|
765
659
|
PROGRESS_DIR = resolve(RUN_DIR, "progress");
|
|
766
660
|
DM_CMD_DIR = resolve(RUN_DIR, "dm-commands");
|
|
767
661
|
DM_RESP_DIR = resolve(RUN_DIR, "dm-responses");
|
|
@@ -819,8 +713,8 @@ var init_config = __esm(() => {
|
|
|
819
713
|
});
|
|
820
714
|
|
|
821
715
|
// ../../packages/core/src/storage/wiki-summary-names.ts
|
|
822
|
-
function wikiSummarySlug(
|
|
823
|
-
return
|
|
716
|
+
function wikiSummarySlug(value) {
|
|
717
|
+
return value.replaceAll(/[^a-zA-Z0-9\uAC00-\uD7A3_-]+/g, "-").slice(0, 120) || "_";
|
|
824
718
|
}
|
|
825
719
|
function wikiSummaryStorageSlug(rawTopic, _topicId) {
|
|
826
720
|
return wikiSummarySlug(rawTopic);
|
|
@@ -849,8 +743,8 @@ function isTopicBriefFile(filename, topicId, topicTitle) {
|
|
|
849
743
|
const idSlug = wikiSummarySlug(topicId);
|
|
850
744
|
return filename === `${idSlug}.md` || filename.endsWith(`--${idSlug}.md`);
|
|
851
745
|
}
|
|
852
|
-
function escapeRegExp(
|
|
853
|
-
return
|
|
746
|
+
function escapeRegExp(value) {
|
|
747
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
854
748
|
}
|
|
855
749
|
var WIKI_SUMMARY_DATE_PREFIX;
|
|
856
750
|
var init_wiki_summary_names = __esm(() => {
|
|
@@ -910,13 +804,13 @@ function elideMiddle(raw, limit = THREAD_EXCERPT_MAX_CHARS) {
|
|
|
910
804
|
const tailText = units.slice(units.length - tail).join("").trimStart();
|
|
911
805
|
return `${headText}${ELLIPSIS}${tailText}`;
|
|
912
806
|
}
|
|
913
|
-
function segmentGraphemes(
|
|
807
|
+
function segmentGraphemes(value) {
|
|
914
808
|
const Segmenter = Intl.Segmenter;
|
|
915
809
|
if (!Segmenter)
|
|
916
|
-
return Array.from(
|
|
810
|
+
return Array.from(value);
|
|
917
811
|
const segmenter = new Segmenter(undefined, { granularity: "grapheme" });
|
|
918
812
|
const out = [];
|
|
919
|
-
for (const { segment } of segmenter.segment(
|
|
813
|
+
for (const { segment } of segmenter.segment(value))
|
|
920
814
|
out.push(segment);
|
|
921
815
|
return out;
|
|
922
816
|
}
|
|
@@ -973,9 +867,9 @@ import { resolve as resolve4 } from "path";
|
|
|
973
867
|
function clone(obj) {
|
|
974
868
|
return structuredClone(obj);
|
|
975
869
|
}
|
|
976
|
-
function assertUuidLike(label,
|
|
977
|
-
if (!UUID_RE.test(
|
|
978
|
-
throw new Error(`rollout: ${label} is not a UUID-shaped string: ${
|
|
870
|
+
function assertUuidLike(label, value) {
|
|
871
|
+
if (!UUID_RE.test(value)) {
|
|
872
|
+
throw new Error(`rollout: ${label} is not a UUID-shaped string: ${value}`);
|
|
979
873
|
}
|
|
980
874
|
}
|
|
981
875
|
function assertCwdInWorkspace(cwd) {
|
|
@@ -1311,7 +1205,7 @@ function loadClaudeAttachments() {
|
|
|
1311
1205
|
}
|
|
1312
1206
|
function encodeClaudeCwd(cwd) {
|
|
1313
1207
|
const realCwd = cwd.startsWith("/tmp/") ? cwd.replace(/^\/tmp\//, "/private/tmp/") : cwd;
|
|
1314
|
-
return
|
|
1208
|
+
return realCwd.replaceAll(/[^a-zA-Z0-9]/g, "-");
|
|
1315
1209
|
}
|
|
1316
1210
|
function writeClaudeRollout(opts) {
|
|
1317
1211
|
const sessionId = opts.sessionId ?? randomUUID2();
|
|
@@ -1543,17 +1437,17 @@ function shouldSubstituteVaultToolInput(toolName) {
|
|
|
1543
1437
|
const leaf = leafToolName(toolName);
|
|
1544
1438
|
return leaf.startsWith("browser_") || DIRECT_VAULT_EXECUTION_TOOLS.has(leaf);
|
|
1545
1439
|
}
|
|
1546
|
-
function referencesRuntimeSecretStorage(
|
|
1547
|
-
if (typeof
|
|
1548
|
-
const lower =
|
|
1440
|
+
function referencesRuntimeSecretStorage(value) {
|
|
1441
|
+
if (typeof value === "string") {
|
|
1442
|
+
const lower = value.toLowerCase();
|
|
1549
1443
|
if (SENSITIVE_RUNTIME_NAMES.some((name) => lower.includes(name)))
|
|
1550
1444
|
return true;
|
|
1551
|
-
return
|
|
1445
|
+
return value.startsWith("/") && isSensitivePath(value);
|
|
1552
1446
|
}
|
|
1553
|
-
if (Array.isArray(
|
|
1554
|
-
return
|
|
1555
|
-
if (
|
|
1556
|
-
return Object.values(
|
|
1447
|
+
if (Array.isArray(value))
|
|
1448
|
+
return value.some(referencesRuntimeSecretStorage);
|
|
1449
|
+
if (value && typeof value === "object") {
|
|
1450
|
+
return Object.values(value).some(referencesRuntimeSecretStorage);
|
|
1557
1451
|
}
|
|
1558
1452
|
return false;
|
|
1559
1453
|
}
|
|
@@ -1570,8 +1464,8 @@ var init_vault_tool_policy = __esm(() => {
|
|
|
1570
1464
|
});
|
|
1571
1465
|
|
|
1572
1466
|
// ../../packages/core/src/agents/explicit-agent-switch.ts
|
|
1573
|
-
function escapeRegExp2(
|
|
1574
|
-
return
|
|
1467
|
+
function escapeRegExp2(value) {
|
|
1468
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1575
1469
|
}
|
|
1576
1470
|
function agentAliases(agent) {
|
|
1577
1471
|
switch (agent) {
|
|
@@ -1658,8 +1552,8 @@ var init_canonical_bridge_config = __esm(() => {
|
|
|
1658
1552
|
|
|
1659
1553
|
// ../../packages/core/src/mcp/runtime-spec.ts
|
|
1660
1554
|
import { createHash, createHmac, timingSafeEqual } from "crypto";
|
|
1661
|
-
function encodeTokenPart(
|
|
1662
|
-
return Buffer.from(JSON.stringify(
|
|
1555
|
+
function encodeTokenPart(value) {
|
|
1556
|
+
return Buffer.from(JSON.stringify(value), "utf-8").toString("base64url");
|
|
1663
1557
|
}
|
|
1664
1558
|
function signTokenPayload(payloadPart) {
|
|
1665
1559
|
return createHmac("sha256", RUNTIME_MCP_SECRET).update(payloadPart).digest("base64url");
|
|
@@ -1997,12 +1891,12 @@ function createBackgroundBashManager(options = {}) {
|
|
|
1997
1891
|
usedPorts.clear();
|
|
1998
1892
|
knownContexts.clear();
|
|
1999
1893
|
const deadline = now() + 3000;
|
|
2000
|
-
await Promise.all(entries.map((instance) => new Promise((
|
|
1894
|
+
await Promise.all(entries.map((instance) => new Promise((resolve) => {
|
|
2001
1895
|
if (instance.process.exitCode !== null || instance.process.killed)
|
|
2002
|
-
return
|
|
2003
|
-
instance.process.once("exit",
|
|
2004
|
-
instance.process.once("error",
|
|
2005
|
-
const timer = setTimeout(
|
|
1896
|
+
return resolve();
|
|
1897
|
+
instance.process.once("exit", resolve);
|
|
1898
|
+
instance.process.once("error", resolve);
|
|
1899
|
+
const timer = setTimeout(resolve, Math.max(0, deadline - now()));
|
|
2006
1900
|
timer.unref?.();
|
|
2007
1901
|
})));
|
|
2008
1902
|
}
|
|
@@ -2140,8 +2034,8 @@ function storageState() {
|
|
|
2140
2034
|
return created;
|
|
2141
2035
|
}
|
|
2142
2036
|
function envPath(name, fallback) {
|
|
2143
|
-
const
|
|
2144
|
-
return resolve6(
|
|
2037
|
+
const value = process.env[name]?.trim();
|
|
2038
|
+
return resolve6(value || fallback);
|
|
2145
2039
|
}
|
|
2146
2040
|
function defaultStateDir() {
|
|
2147
2041
|
return envPath("NEGOTIUM_STATE_DIR", join5(homedir4(), ".negotium"));
|
|
@@ -2259,13 +2153,13 @@ var init_storage_host = __esm(async () => {
|
|
|
2259
2153
|
get(_target, property) {
|
|
2260
2154
|
const database = resolveStorageDatabase();
|
|
2261
2155
|
ensureStorageSchemas(database);
|
|
2262
|
-
const
|
|
2263
|
-
return typeof
|
|
2156
|
+
const value = Reflect.get(database, property, database);
|
|
2157
|
+
return typeof value === "function" ? value.bind(database) : value;
|
|
2264
2158
|
},
|
|
2265
|
-
set(_target, property,
|
|
2159
|
+
set(_target, property, value) {
|
|
2266
2160
|
const database = resolveStorageDatabase();
|
|
2267
2161
|
ensureStorageSchemas(database);
|
|
2268
|
-
return Reflect.set(database, property,
|
|
2162
|
+
return Reflect.set(database, property, value, database);
|
|
2269
2163
|
}
|
|
2270
2164
|
});
|
|
2271
2165
|
});
|
|
@@ -2642,7 +2536,7 @@ var init_api_messages = __esm(async () => {
|
|
|
2642
2536
|
|
|
2643
2537
|
// ../../packages/core/src/storage/topic-link-records.ts
|
|
2644
2538
|
function topicLinkSchemaIsCurrent(database, nodeId) {
|
|
2645
|
-
const objects = new Map(database.query("SELECT name, sql FROM sqlite_master WHERE type IN ('table','index','trigger')").all().map((
|
|
2539
|
+
const objects = new Map(database.query("SELECT name, sql FROM sqlite_master WHERE type IN ('table','index','trigger')").all().map((row) => [row.name, row.sql ?? ""]));
|
|
2646
2540
|
for (const name of [...SCHEMA_TABLES, ...SCHEMA_INDEXES, ...SCHEMA_INDEXES_TOMBSTONES]) {
|
|
2647
2541
|
if (!objects.has(name))
|
|
2648
2542
|
return false;
|
|
@@ -2659,7 +2553,7 @@ function topicLinkSchemaIsCurrent(database, nodeId) {
|
|
|
2659
2553
|
return false;
|
|
2660
2554
|
}
|
|
2661
2555
|
const identity = database.query("SELECT node_id, epoch_id FROM api_node_identity WHERE singleton = 1").all();
|
|
2662
|
-
if (identity.some((
|
|
2556
|
+
if (identity.some((row) => row.epoch_id === null))
|
|
2663
2557
|
return false;
|
|
2664
2558
|
if (nodeId && identity[0]?.node_id !== nodeId)
|
|
2665
2559
|
return false;
|
|
@@ -2987,13 +2881,13 @@ var init_topic_link_records = __esm(async () => {
|
|
|
2987
2881
|
function defaultTopicSurface() {
|
|
2988
2882
|
return normalizeTopicSurface(process.env.NEGOTIUM_DEFAULT_SURFACE);
|
|
2989
2883
|
}
|
|
2990
|
-
function normalizeTopicSurface(
|
|
2991
|
-
return
|
|
2884
|
+
function normalizeTopicSurface(value) {
|
|
2885
|
+
return value === "telegram" || value === "otium" || value === "terminal" ? value : "terminal";
|
|
2992
2886
|
}
|
|
2993
|
-
function normalizeSurfaceScope(
|
|
2994
|
-
if (typeof
|
|
2887
|
+
function normalizeSurfaceScope(value) {
|
|
2888
|
+
if (typeof value !== "string")
|
|
2995
2889
|
return null;
|
|
2996
|
-
const trimmed =
|
|
2890
|
+
const trimmed = value.trim();
|
|
2997
2891
|
return trimmed ? trimmed : null;
|
|
2998
2892
|
}
|
|
2999
2893
|
function defaultSurfaceScope() {
|
|
@@ -3483,17 +3377,14 @@ function rowToDto2(r, participants = getTopicParticipants(r.id), tellTargets) {
|
|
|
3483
3377
|
surfaceScope: normalizeSurfaceScope(r.surface_scope)
|
|
3484
3378
|
};
|
|
3485
3379
|
}
|
|
3486
|
-
function normalizeTopicVisibility(
|
|
3487
|
-
return
|
|
3380
|
+
function normalizeTopicVisibility(value) {
|
|
3381
|
+
return value === "hidden" ? "hidden" : "visible";
|
|
3488
3382
|
}
|
|
3489
|
-
function
|
|
3490
|
-
return
|
|
3383
|
+
function normalizeTopicKind(value) {
|
|
3384
|
+
return value === "channel" || value === "agent" || value === "manager" ? value : null;
|
|
3491
3385
|
}
|
|
3492
|
-
function
|
|
3493
|
-
return
|
|
3494
|
-
}
|
|
3495
|
-
function normalizeAiMode(value2) {
|
|
3496
|
-
return value2 === "off" || value2 === "mention" || value2 === "always" ? value2 : null;
|
|
3386
|
+
function normalizeAiMode(value) {
|
|
3387
|
+
return value === "off" || value === "mention" || value === "always" ? value : null;
|
|
3497
3388
|
}
|
|
3498
3389
|
function aiMentionFromMode(mode) {
|
|
3499
3390
|
return mode === "mention";
|
|
@@ -3891,6 +3782,11 @@ function refreshForumCatalogViews() {
|
|
|
3891
3782
|
function isReservedRuntimeMcpServerName(name) {
|
|
3892
3783
|
return Object.hasOwn(MCP_CATALOG, name) || nodeMcpEntries.some((entry) => entry.key === name);
|
|
3893
3784
|
}
|
|
3785
|
+
function withoutManagerOnlyHostMcpServers(hostMcpServers) {
|
|
3786
|
+
if (!hostMcpServers)
|
|
3787
|
+
return;
|
|
3788
|
+
return Object.fromEntries(Object.entries(hostMcpServers).filter(([name]) => !MANAGER_ONLY_HOST_MCP_NAMES.has(name)));
|
|
3789
|
+
}
|
|
3894
3790
|
function mergeHostMcpServers(base, hostMcpServers) {
|
|
3895
3791
|
if (!hostMcpServers)
|
|
3896
3792
|
return base;
|
|
@@ -4151,7 +4047,7 @@ function getMcpServersForQuery(opts) {
|
|
|
4151
4047
|
fileDeliveryTools: opts.fileDeliveryTools
|
|
4152
4048
|
}), opts.hostMcpServers), opts.topicId);
|
|
4153
4049
|
}
|
|
4154
|
-
return hideProviderIntrospectionForOtium(getForumMcpServers({
|
|
4050
|
+
return hideProviderIntrospectionForOtium(mergeHostMcpServers(getForumMcpServers({
|
|
4155
4051
|
userId: opts.userId || "local",
|
|
4156
4052
|
actorUserId: opts.actorUserId,
|
|
4157
4053
|
actorTopicScope: opts.actorTopicScope,
|
|
@@ -4178,7 +4074,7 @@ function getMcpServersForQuery(opts) {
|
|
|
4178
4074
|
extra: opts.mcpExtra,
|
|
4179
4075
|
silent: opts.silent,
|
|
4180
4076
|
peerBridge: opts.peerBridge
|
|
4181
|
-
}), opts.topicId);
|
|
4077
|
+
}), withoutManagerOnlyHostMcpServers(opts.hostMcpServers)), opts.topicId);
|
|
4182
4078
|
}
|
|
4183
4079
|
function hideProviderIntrospectionForOtium(servers, topicId) {
|
|
4184
4080
|
if (!topicId || getTopic(topicId)?.surface !== "otium")
|
|
@@ -4188,7 +4084,7 @@ function hideProviderIntrospectionForOtium(servers, topicId) {
|
|
|
4188
4084
|
delete filtered["token-stats"];
|
|
4189
4085
|
return filtered;
|
|
4190
4086
|
}
|
|
4191
|
-
var _playwrightUnavailableNotifier, _playwrightUnavailableLastNotifiedAt, _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS, _playwrightUnavailableThisTurn, cuaRsMcpPort, cuaRsMcpToken, MCP_CATALOG, nodeMcpEntries, resolvedNodeMcpPorts, allForumMcpServerNames, requiredForumMcpServers, REQUIRED_FORUM_MCP_SERVERS, optionalForumMcpServers;
|
|
4087
|
+
var _playwrightUnavailableNotifier, _playwrightUnavailableLastNotifiedAt, _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS, _playwrightUnavailableThisTurn, cuaRsMcpPort, cuaRsMcpToken, MCP_CATALOG, nodeMcpEntries, resolvedNodeMcpPorts, allForumMcpServerNames, requiredForumMcpServers, REQUIRED_FORUM_MCP_SERVERS, optionalForumMcpServers, MANAGER_ONLY_HOST_MCP_NAMES;
|
|
4192
4088
|
var init_mcp_config = __esm(async () => {
|
|
4193
4089
|
init_explicit_agent_switch();
|
|
4194
4090
|
init_canonical_bridge_config();
|
|
@@ -4444,6 +4340,7 @@ var init_mcp_config = __esm(async () => {
|
|
|
4444
4340
|
REQUIRED_FORUM_MCP_SERVERS = requiredForumMcpServers;
|
|
4445
4341
|
optionalForumMcpServers = [];
|
|
4446
4342
|
refreshForumCatalogViews();
|
|
4343
|
+
MANAGER_ONLY_HOST_MCP_NAMES = new Set(["topic-admin"]);
|
|
4447
4344
|
});
|
|
4448
4345
|
|
|
4449
4346
|
// ../../packages/core/src/storage/vault-crypto-core.ts
|
|
@@ -4454,14 +4351,14 @@ function encryptionKey(masterKey) {
|
|
|
4454
4351
|
function aad(userId, key) {
|
|
4455
4352
|
return Buffer.from(`${userId}\x00${key.toUpperCase()}`, "utf8");
|
|
4456
4353
|
}
|
|
4457
|
-
function isEncryptedVaultValue(
|
|
4458
|
-
return
|
|
4354
|
+
function isEncryptedVaultValue(value) {
|
|
4355
|
+
return value.startsWith(ENVELOPE_PREFIX);
|
|
4459
4356
|
}
|
|
4460
|
-
function encryptVaultValueWithKey(userId, key,
|
|
4357
|
+
function encryptVaultValueWithKey(userId, key, value, masterKey) {
|
|
4461
4358
|
const iv = randomBytes3(IV_BYTES);
|
|
4462
4359
|
const cipher = createCipheriv("aes-256-gcm", encryptionKey(masterKey), iv);
|
|
4463
4360
|
cipher.setAAD(aad(userId, key));
|
|
4464
|
-
const ciphertext = Buffer.concat([cipher.update(
|
|
4361
|
+
const ciphertext = Buffer.concat([cipher.update(value, "utf8"), cipher.final()]);
|
|
4465
4362
|
const tag = cipher.getAuthTag();
|
|
4466
4363
|
return `${ENVELOPE_PREFIX}${iv.toString("base64url")}.${ciphertext.toString("base64url")}.${tag.toString("base64url")}`;
|
|
4467
4364
|
}
|
|
@@ -4490,8 +4387,8 @@ var ENVELOPE_PREFIX = "otium-vault:v1:", IV_BYTES = 12, KEY_BYTES = 32;
|
|
|
4490
4387
|
var init_vault_crypto_core = () => {};
|
|
4491
4388
|
|
|
4492
4389
|
// ../../packages/core/src/storage/vault-crypto.ts
|
|
4493
|
-
function encryptVaultValue(userId, key,
|
|
4494
|
-
return encryptVaultValueWithKey(userId, key,
|
|
4390
|
+
function encryptVaultValue(userId, key, value, masterKey = VAULT_MASTER_KEY) {
|
|
4391
|
+
return encryptVaultValueWithKey(userId, key, value, masterKey);
|
|
4495
4392
|
}
|
|
4496
4393
|
function decryptVaultValue(userId, key, storedValue, masterKey = VAULT_MASTER_KEY) {
|
|
4497
4394
|
return decryptVaultValueWithKey(userId, key, storedValue, masterKey);
|
|
@@ -4577,11 +4474,11 @@ function vaultListDecryptableValues(userId) {
|
|
|
4577
4474
|
}
|
|
4578
4475
|
return entries;
|
|
4579
4476
|
}
|
|
4580
|
-
function vaultSet(userId, key,
|
|
4477
|
+
function vaultSet(userId, key, value, description = "") {
|
|
4581
4478
|
const normalizedKey = normalizeVaultKey(key);
|
|
4582
4479
|
activeVaultDatabase().prepare(`INSERT INTO vault (user_id, key, value, description) VALUES (?, ?, ?, ?)
|
|
4583
4480
|
ON CONFLICT (user_id, key) DO UPDATE
|
|
4584
|
-
SET value = excluded.value, description = excluded.description`).run(userId, normalizedKey, encryptVaultValue(userId, normalizedKey,
|
|
4481
|
+
SET value = excluded.value, description = excluded.description`).run(userId, normalizedKey, encryptVaultValue(userId, normalizedKey, value, vaultMasterKey), description);
|
|
4585
4482
|
}
|
|
4586
4483
|
function vaultHasKey(userId, key) {
|
|
4587
4484
|
const row = activeVaultDatabase().prepare("SELECT 1 FROM vault WHERE user_id = ? AND key = ?").get(userId, normalizeVaultKey(key));
|
|
@@ -4599,21 +4496,21 @@ function vaultSubstituteDetailed(userId, text) {
|
|
|
4599
4496
|
const key = normalizeVaultKey(rawKey);
|
|
4600
4497
|
if (!entries.has(key))
|
|
4601
4498
|
entries.set(key, vaultGetValue(userId, key));
|
|
4602
|
-
const
|
|
4603
|
-
if (
|
|
4499
|
+
const value = entries.get(key);
|
|
4500
|
+
if (value === undefined)
|
|
4604
4501
|
return match;
|
|
4605
4502
|
usedKeys.add(key);
|
|
4606
|
-
return
|
|
4503
|
+
return value;
|
|
4607
4504
|
});
|
|
4608
4505
|
return { text: substituted, usedKeys: [...usedKeys] };
|
|
4609
4506
|
}
|
|
4610
|
-
function encodedSecretForms(
|
|
4507
|
+
function encodedSecretForms(value) {
|
|
4611
4508
|
const forms = new Set([
|
|
4612
|
-
|
|
4613
|
-
encodeURIComponent(
|
|
4614
|
-
Buffer.from(
|
|
4615
|
-
Buffer.from(
|
|
4616
|
-
Buffer.from(
|
|
4509
|
+
value,
|
|
4510
|
+
encodeURIComponent(value),
|
|
4511
|
+
Buffer.from(value, "utf8").toString("base64"),
|
|
4512
|
+
Buffer.from(value, "utf8").toString("base64url"),
|
|
4513
|
+
Buffer.from(value, "utf8").toString("hex")
|
|
4617
4514
|
]);
|
|
4618
4515
|
forms.delete("");
|
|
4619
4516
|
return [...forms].sort((a, b) => b.length - a.length);
|
|
@@ -4679,14 +4576,14 @@ function hostedMcpServers(opts) {
|
|
|
4679
4576
|
}
|
|
4680
4577
|
return activeHost().getMcpServersForQuery(opts);
|
|
4681
4578
|
}
|
|
4682
|
-
function redactHostedSecrets(userId,
|
|
4683
|
-
return activeHost().redactVaultSecrets(userId,
|
|
4579
|
+
function redactHostedSecrets(userId, value) {
|
|
4580
|
+
return activeHost().redactVaultSecrets(userId, value);
|
|
4684
4581
|
}
|
|
4685
|
-
function substituteHostedSecrets(userId,
|
|
4686
|
-
return activeHost().substituteVaultSecrets(userId,
|
|
4582
|
+
function substituteHostedSecrets(userId, value) {
|
|
4583
|
+
return activeHost().substituteVaultSecrets(userId, value);
|
|
4687
4584
|
}
|
|
4688
|
-
function referencesHostedSecretStorage(
|
|
4689
|
-
return activeHost().referencesRuntimeSecretStorage(
|
|
4585
|
+
function referencesHostedSecretStorage(value) {
|
|
4586
|
+
return activeHost().referencesRuntimeSecretStorage(value);
|
|
4690
4587
|
}
|
|
4691
4588
|
function hostedClaudeCodeExecutablePath() {
|
|
4692
4589
|
return activeHost().claudeCodeExecutablePath();
|
|
@@ -4708,7 +4605,7 @@ var init_execution_host = __esm(async () => {
|
|
|
4708
4605
|
defaultHost = {
|
|
4709
4606
|
getMcpServersForQuery,
|
|
4710
4607
|
redactVaultSecrets,
|
|
4711
|
-
substituteVaultSecrets: (userId,
|
|
4608
|
+
substituteVaultSecrets: (userId, value) => vaultSubstituteDetailed(userId, value).text,
|
|
4712
4609
|
referencesRuntimeSecretStorage,
|
|
4713
4610
|
claudeCodeExecutablePath: () => CLAUDE_EXECUTABLE,
|
|
4714
4611
|
codexAuthFilePath
|
|
@@ -4809,14 +4706,14 @@ function canonicalFilePath(path) {
|
|
|
4809
4706
|
}
|
|
4810
4707
|
}
|
|
4811
4708
|
}
|
|
4812
|
-
function changedPatchLines(
|
|
4709
|
+
function changedPatchLines(value) {
|
|
4813
4710
|
const removed = [];
|
|
4814
4711
|
const added = [];
|
|
4815
4712
|
const diffPreview = [];
|
|
4816
4713
|
let oldLine = 0;
|
|
4817
4714
|
let newLine = 0;
|
|
4818
4715
|
let sawHunk = false;
|
|
4819
|
-
for (const line of
|
|
4716
|
+
for (const line of value.split(`
|
|
4820
4717
|
`)) {
|
|
4821
4718
|
const hunk = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(line);
|
|
4822
4719
|
if (hunk) {
|
|
@@ -4964,7 +4861,7 @@ function extractLatestCodexTokenTotals(jsonl) {
|
|
|
4964
4861
|
usage.cached_input_tokens,
|
|
4965
4862
|
usage.cache_write_input_tokens
|
|
4966
4863
|
];
|
|
4967
|
-
if (values.some((
|
|
4864
|
+
if (values.some((value) => value !== undefined && (!Number.isFinite(value) || value < 0))) {
|
|
4968
4865
|
continue;
|
|
4969
4866
|
}
|
|
4970
4867
|
return {
|
|
@@ -5268,7 +5165,7 @@ var init_codex = __esm(async () => {
|
|
|
5268
5165
|
});
|
|
5269
5166
|
|
|
5270
5167
|
// ../../packages/core/src/version.ts
|
|
5271
|
-
var NEGOTIUM_VERSION = "0.22.
|
|
5168
|
+
var NEGOTIUM_VERSION = "0.22.6";
|
|
5272
5169
|
|
|
5273
5170
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
5274
5171
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -5344,7 +5241,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
5344
5241
|
stdio: ["pipe", "pipe", "pipe"],
|
|
5345
5242
|
windowsHide: true
|
|
5346
5243
|
});
|
|
5347
|
-
const refreshed = new Promise((
|
|
5244
|
+
const refreshed = new Promise((resolve, reject) => {
|
|
5348
5245
|
let settled = false;
|
|
5349
5246
|
let stdoutBuffer = "";
|
|
5350
5247
|
let stderr = "";
|
|
@@ -5363,7 +5260,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
5363
5260
|
else if (!existsSync8(cachePath))
|
|
5364
5261
|
reject(new Error("Codex did not create its model cache"));
|
|
5365
5262
|
else
|
|
5366
|
-
|
|
5263
|
+
resolve();
|
|
5367
5264
|
};
|
|
5368
5265
|
const send = (message) => {
|
|
5369
5266
|
child.stdin.write(`${JSON.stringify(message)}
|
|
@@ -5429,12 +5326,12 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
5429
5326
|
function waitForChildExit(child, timeoutMs) {
|
|
5430
5327
|
if (child.exitCode !== null || child.signalCode !== null)
|
|
5431
5328
|
return Promise.resolve();
|
|
5432
|
-
return new Promise((
|
|
5433
|
-
const timer = setTimeout(
|
|
5329
|
+
return new Promise((resolve) => {
|
|
5330
|
+
const timer = setTimeout(resolve, timeoutMs);
|
|
5434
5331
|
timer.unref?.();
|
|
5435
5332
|
child.once("exit", () => {
|
|
5436
5333
|
clearTimeout(timer);
|
|
5437
|
-
|
|
5334
|
+
resolve();
|
|
5438
5335
|
});
|
|
5439
5336
|
});
|
|
5440
5337
|
}
|
|
@@ -5524,16 +5421,11 @@ var init_codex_native_multi_agent = __esm(() => {
|
|
|
5524
5421
|
});
|
|
5525
5422
|
|
|
5526
5423
|
// ../../packages/core/src/agents/codex-app-server.ts
|
|
5527
|
-
var exports_codex_app_server = {};
|
|
5528
|
-
__export(exports_codex_app_server, {
|
|
5529
|
-
forkCodexSession: () => forkCodexSession,
|
|
5530
|
-
createCodexAppServerForker: () => createCodexAppServerForker
|
|
5531
|
-
});
|
|
5532
5424
|
import { spawn as spawn3 } from "child_process";
|
|
5533
5425
|
function createCodexAppServerForker(host) {
|
|
5534
5426
|
return async (parentThreadId) => {
|
|
5535
5427
|
const child = host.spawnServer();
|
|
5536
|
-
return await new Promise((
|
|
5428
|
+
return await new Promise((resolve, reject) => {
|
|
5537
5429
|
let settled = false;
|
|
5538
5430
|
let stdoutBuffer = "";
|
|
5539
5431
|
let stderr = "";
|
|
@@ -5550,7 +5442,7 @@ function createCodexAppServerForker(host) {
|
|
|
5550
5442
|
if (error)
|
|
5551
5443
|
reject(error);
|
|
5552
5444
|
else if (result)
|
|
5553
|
-
|
|
5445
|
+
resolve(result);
|
|
5554
5446
|
else
|
|
5555
5447
|
reject(new Error("Codex thread fork returned no result"));
|
|
5556
5448
|
};
|
|
@@ -5687,8 +5579,8 @@ var init_codex_registry = __esm(async () => {
|
|
|
5687
5579
|
return { sessionId: threadId, rolloutPath };
|
|
5688
5580
|
},
|
|
5689
5581
|
async forkSession({ parentSessionId }) {
|
|
5690
|
-
|
|
5691
|
-
return await
|
|
5582
|
+
await init_codex_app_server();
|
|
5583
|
+
return await forkCodexSession(parentSessionId);
|
|
5692
5584
|
},
|
|
5693
5585
|
async cleanupRollouts({ sessionIds }) {
|
|
5694
5586
|
if (sessionIds.length === 0)
|
|
@@ -5869,26 +5761,8 @@ var init_maestro_registry = __esm(() => {
|
|
|
5869
5761
|
});
|
|
5870
5762
|
|
|
5871
5763
|
// ../../packages/core/src/agents/model-catalog.ts
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
selectableModel: () => selectableModel,
|
|
5875
|
-
resolveWorkerModel: () => resolveWorkerModel,
|
|
5876
|
-
resolveWorkerDefaultModel: () => resolveWorkerDefaultModel,
|
|
5877
|
-
resolveModelForAgent: () => resolveModelForAgent,
|
|
5878
|
-
resolveDefaultModel: () => resolveDefaultModel,
|
|
5879
|
-
resolveCompactionExecution: () => resolveCompactionExecution,
|
|
5880
|
-
modelOwner: () => modelOwner,
|
|
5881
|
-
formatSelectableModel: () => formatSelectableModel,
|
|
5882
|
-
canonicalModelId: () => canonicalModelId,
|
|
5883
|
-
SELECTABLE_MODELS: () => SELECTABLE_MODELS,
|
|
5884
|
-
MODEL_OWNER: () => MODEL_OWNER,
|
|
5885
|
-
MODEL_COST_ROUTING_SUMMARY: () => MODEL_COST_ROUTING_SUMMARY,
|
|
5886
|
-
MODEL_COST_RESEARCHED_AT: () => MODEL_COST_RESEARCHED_AT,
|
|
5887
|
-
FALLBACK_ORDER: () => FALLBACK_ORDER,
|
|
5888
|
-
AGENT_DISPLAY_NAME: () => AGENT_DISPLAY_NAME
|
|
5889
|
-
});
|
|
5890
|
-
function canonicalModelId(value2) {
|
|
5891
|
-
const trimmed = value2.trim();
|
|
5764
|
+
function canonicalModelId(value) {
|
|
5765
|
+
const trimmed = value.trim();
|
|
5892
5766
|
const lower = trimmed.toLowerCase();
|
|
5893
5767
|
return SELECTABLE_MODEL_ALIASES[lower] ?? CANONICAL_MODEL_CASING[lower] ?? trimmed;
|
|
5894
5768
|
}
|
|
@@ -5896,10 +5770,6 @@ function formatSelectableModel(candidate) {
|
|
|
5896
5770
|
const tier = `${candidate.intelligenceTier[0].toUpperCase()}${candidate.intelligenceTier.slice(1)}`;
|
|
5897
5771
|
return `${candidate.agent} / \`${candidate.model}\` [${tier}-level]: ${candidate.routingSummary}`;
|
|
5898
5772
|
}
|
|
5899
|
-
function selectableModel(value2) {
|
|
5900
|
-
const canonical = canonicalModelId(value2).toLowerCase();
|
|
5901
|
-
return SELECTABLE_MODELS.find((candidate) => candidate.model === canonical);
|
|
5902
|
-
}
|
|
5903
5773
|
function modelOwner(model) {
|
|
5904
5774
|
const lower = model.toLowerCase();
|
|
5905
5775
|
if (lower.startsWith("claude-"))
|
|
@@ -5952,7 +5822,7 @@ function resolveCompactionExecution(agent, registry) {
|
|
|
5952
5822
|
const effort = registry.validateEffort("medium") ? "medium" : registry.defaultEffort;
|
|
5953
5823
|
return { model, ...effort ? { effort } : {} };
|
|
5954
5824
|
}
|
|
5955
|
-
var MODEL_OWNER,
|
|
5825
|
+
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;
|
|
5956
5826
|
var init_model_catalog = __esm(() => {
|
|
5957
5827
|
init_config();
|
|
5958
5828
|
MODEL_OWNER = {
|
|
@@ -6124,20 +5994,6 @@ var init_model_catalog = __esm(() => {
|
|
|
6124
5994
|
"glm-flash": "glm-5.3-flash"
|
|
6125
5995
|
};
|
|
6126
5996
|
CANONICAL_MODEL_CASING = Object.fromEntries(SELECTABLE_MODELS.map((candidate) => [candidate.model.toLowerCase(), candidate.model]));
|
|
6127
|
-
FALLBACK_ORDER = {
|
|
6128
|
-
claude: [
|
|
6129
|
-
{ agent: "maestro", model: "deepseek-pro" },
|
|
6130
|
-
{ agent: "codex", model: "gpt-6-luna" }
|
|
6131
|
-
],
|
|
6132
|
-
codex: [
|
|
6133
|
-
{ agent: "maestro", model: "deepseek-pro" },
|
|
6134
|
-
{ agent: "claude", model: "sonnet" }
|
|
6135
|
-
],
|
|
6136
|
-
maestro: [
|
|
6137
|
-
{ agent: "codex", model: "gpt-6-luna" },
|
|
6138
|
-
{ agent: "claude", model: "sonnet" }
|
|
6139
|
-
]
|
|
6140
|
-
};
|
|
6141
5997
|
AGENT_DISPLAY_NAME = {
|
|
6142
5998
|
claude: "Claude",
|
|
6143
5999
|
codex: "Codex",
|
|
@@ -6529,9 +6385,9 @@ function subagentLineageTopicIds(currentTopicId) {
|
|
|
6529
6385
|
const children = new Set;
|
|
6530
6386
|
if (!currentTopicId)
|
|
6531
6387
|
return { reachable, children };
|
|
6532
|
-
const
|
|
6533
|
-
if (
|
|
6534
|
-
reachable.add(
|
|
6388
|
+
const current = getTopic(currentTopicId);
|
|
6389
|
+
if (current?.isSubagent && current.parentTopicId) {
|
|
6390
|
+
reachable.add(current.parentTopicId);
|
|
6535
6391
|
for (const id of listSubagentTellTargetIds(currentTopicId))
|
|
6536
6392
|
reachable.add(id);
|
|
6537
6393
|
}
|
|
@@ -6741,13 +6597,13 @@ function ensureRuntimeUserTurnRequestsSchema(database) {
|
|
|
6741
6597
|
}
|
|
6742
6598
|
database.exec("CREATE INDEX IF NOT EXISTS idx_runtime_user_turn_requests_ready ON runtime_user_turn_requests(status, created_at)");
|
|
6743
6599
|
}
|
|
6744
|
-
function isValidReplyContext(
|
|
6745
|
-
if (
|
|
6600
|
+
function isValidReplyContext(value) {
|
|
6601
|
+
if (value === undefined)
|
|
6746
6602
|
return true;
|
|
6747
|
-
if (!
|
|
6603
|
+
if (!value || typeof value !== "object")
|
|
6748
6604
|
return false;
|
|
6749
6605
|
const optionalText = (field) => field === undefined || typeof field === "string";
|
|
6750
|
-
return (
|
|
6606
|
+
return (value.kind === "thread" || value.kind === "quote") && optionalText(value.rootId) && optionalText(value.label) && optionalText(value.text);
|
|
6751
6607
|
}
|
|
6752
6608
|
function rowToRequest(row) {
|
|
6753
6609
|
let attachments;
|
|
@@ -6909,8 +6765,8 @@ function markRuntimeUserTurnMessagesLogged(topicId, requestId, ownerId, loggedUs
|
|
|
6909
6765
|
return false;
|
|
6910
6766
|
return db.transaction(() => {
|
|
6911
6767
|
const requests = db.query("SELECT * FROM runtime_user_turn_requests WHERE topic_id = ? ORDER BY created_at ASC, rowid ASC").all(topicId).map(rowToRequest);
|
|
6912
|
-
const hasLoggedPrefix = (
|
|
6913
|
-
const candidate =
|
|
6768
|
+
const hasLoggedPrefix = (request) => loggedUserMessages.length <= request.userMessages.length && loggedUserMessages.every((message, index) => {
|
|
6769
|
+
const candidate = request.userMessages[index];
|
|
6914
6770
|
return candidate?.prompt === message.prompt && candidate.actorUserId === message.actorUserId && candidate.actorLabel === message.actorLabel && JSON.stringify(candidate.attachments ?? []) === JSON.stringify(message.attachments ?? []);
|
|
6915
6771
|
});
|
|
6916
6772
|
const request = requests.find((candidate) => candidate.requestId === requestId && candidate.claimedBy === ownerId && hasLoggedPrefix(candidate)) ?? requests.find((candidate) => candidate.execution?.supersededRequestIds?.includes(requestId) && hasLoggedPrefix(candidate));
|
|
@@ -6928,60 +6784,6 @@ function markRuntimeUserTurnMessagesLogged(topicId, requestId, ownerId, loggedUs
|
|
|
6928
6784
|
return result.changes === 1;
|
|
6929
6785
|
}).immediate();
|
|
6930
6786
|
}
|
|
6931
|
-
function claimNextRuntimeUserTurnRequest(ownerId, now = Date.now()) {
|
|
6932
|
-
return db.transaction(() => {
|
|
6933
|
-
const row = db.query(`SELECT r.*
|
|
6934
|
-
FROM runtime_user_turn_requests r
|
|
6935
|
-
LEFT JOIN runtime_turn_leases l ON l.topic_id = r.topic_id
|
|
6936
|
-
LEFT JOIN runtime_topic_state s ON s.topic_id = r.topic_id
|
|
6937
|
-
WHERE (l.topic_id IS NULL OR l.heartbeat_at < ?)
|
|
6938
|
-
AND (s.topic_id IS NULL OR s.maintenance = 0 OR s.heartbeat_at < ?)
|
|
6939
|
-
AND r.topic_epoch = COALESCE(s.epoch, 0)
|
|
6940
|
-
AND NOT EXISTS (
|
|
6941
|
-
SELECT 1
|
|
6942
|
-
FROM runtime_user_turn_requests active
|
|
6943
|
-
WHERE active.topic_id = r.topic_id
|
|
6944
|
-
AND active.request_id <> r.request_id
|
|
6945
|
-
AND active.claimed_at IS NOT NULL
|
|
6946
|
-
AND active.claimed_at >= ?
|
|
6947
|
-
)
|
|
6948
|
-
AND (
|
|
6949
|
-
(r.status = 'pending' AND (r.claimed_at IS NULL OR r.claimed_at < ?))
|
|
6950
|
-
OR (r.status = 'running' AND (r.claimed_at IS NULL OR r.claimed_at < ?))
|
|
6951
|
-
)
|
|
6952
|
-
ORDER BY r.created_at ASC, r.rowid ASC
|
|
6953
|
-
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);
|
|
6954
|
-
if (!row)
|
|
6955
|
-
return null;
|
|
6956
|
-
const updated = db.query(`UPDATE runtime_user_turn_requests
|
|
6957
|
-
SET claimed_by = ?, claimed_at = ?
|
|
6958
|
-
WHERE request_id = ? AND topic_id = ?
|
|
6959
|
-
AND (
|
|
6960
|
-
(status = 'pending' AND (claimed_at IS NULL OR claimed_at < ?))
|
|
6961
|
-
OR (status = 'running' AND (claimed_at IS NULL OR claimed_at < ?))
|
|
6962
|
-
)`).run(ownerId, now, row.request_id, row.topic_id, now - REQUEST_CLAIM_STALE_MS, now - REQUEST_CLAIM_STALE_MS);
|
|
6963
|
-
if (Number(updated.changes ?? 0) === 0)
|
|
6964
|
-
return null;
|
|
6965
|
-
return rowToRequest({ ...row, claimed_by: ownerId, claimed_at: now });
|
|
6966
|
-
}).immediate();
|
|
6967
|
-
}
|
|
6968
|
-
function markRuntimeUserTurnRunning(topicId, requestId, ownerId, queryId) {
|
|
6969
|
-
const result = db.query(`UPDATE runtime_user_turn_requests
|
|
6970
|
-
SET status = 'running', running_query_id = ?, claimed_at = ?
|
|
6971
|
-
WHERE topic_id = ? AND request_id = ? AND claimed_by = ?`).run(queryId, Date.now(), topicId, requestId, ownerId);
|
|
6972
|
-
return Number(result.changes ?? 0) > 0;
|
|
6973
|
-
}
|
|
6974
|
-
function releaseRuntimeUserTurnClaim(topicId, requestId, ownerId) {
|
|
6975
|
-
const result = db.query(`UPDATE runtime_user_turn_requests
|
|
6976
|
-
SET status = 'pending', claimed_by = NULL, claimed_at = NULL, running_query_id = NULL
|
|
6977
|
-
WHERE topic_id = ? AND request_id = ? AND claimed_by = ?`).run(topicId, requestId, ownerId);
|
|
6978
|
-
return Number(result.changes ?? 0) > 0;
|
|
6979
|
-
}
|
|
6980
|
-
function completeRuntimeUserTurnRequest(topicId, requestId, ownerId) {
|
|
6981
|
-
const result = db.query(`DELETE FROM runtime_user_turn_requests
|
|
6982
|
-
WHERE topic_id = ? AND request_id = ? AND claimed_by = ?`).run(topicId, requestId, ownerId);
|
|
6983
|
-
return Number(result.changes ?? 0) > 0;
|
|
6984
|
-
}
|
|
6985
6787
|
function cancelRuntimeUserTurnRequestsBeforeEpoch(topicId, epoch) {
|
|
6986
6788
|
const rows = db.query("SELECT request_id FROM runtime_user_turn_requests WHERE topic_id = ? AND topic_epoch < ?").all(topicId, epoch);
|
|
6987
6789
|
db.query("DELETE FROM runtime_user_turn_requests WHERE topic_id = ? AND topic_epoch < ?").run(topicId, epoch);
|
|
@@ -7019,11 +6821,6 @@ var init_runtime_turn_requests = __esm(async () => {
|
|
|
7019
6821
|
});
|
|
7020
6822
|
|
|
7021
6823
|
// ../../packages/core/src/agents/registry.ts
|
|
7022
|
-
var exports_registry = {};
|
|
7023
|
-
__export(exports_registry, {
|
|
7024
|
-
getRegistryOperations: () => getRegistryOperations,
|
|
7025
|
-
getRegistry: () => getRegistry
|
|
7026
|
-
});
|
|
7027
6824
|
function getRegistry(agent) {
|
|
7028
6825
|
return REGISTRIES[agent];
|
|
7029
6826
|
}
|
|
@@ -7092,8 +6889,8 @@ var init_fork = __esm(async () => {
|
|
|
7092
6889
|
});
|
|
7093
6890
|
|
|
7094
6891
|
// ../../packages/core/src/platform/playwright/manager-utils.ts
|
|
7095
|
-
function isLiveOwnedChildProcess(
|
|
7096
|
-
return
|
|
6892
|
+
function isLiveOwnedChildProcess(current, expected) {
|
|
6893
|
+
return current?.process === expected && expected.exitCode === null && expected.signalCode === null && !expected.killed;
|
|
7097
6894
|
}
|
|
7098
6895
|
function matchesSpawnedBrowserHealth(health, expectedSpawnNonce) {
|
|
7099
6896
|
if (!health || typeof health !== "object")
|
|
@@ -7604,37 +7401,37 @@ import { randomBytes as randomBytes5, timingSafeEqual as timingSafeEqual2 } from
|
|
|
7604
7401
|
import { createServer as createServer2 } from "net";
|
|
7605
7402
|
import { tmpdir as tmpdir2 } from "os";
|
|
7606
7403
|
import { join as join14 } from "path";
|
|
7607
|
-
function deepMapStrings(
|
|
7608
|
-
if (typeof
|
|
7609
|
-
return transform(
|
|
7610
|
-
if (Array.isArray(
|
|
7611
|
-
return
|
|
7612
|
-
if (!
|
|
7613
|
-
return
|
|
7614
|
-
const prototype = Object.getPrototypeOf(
|
|
7404
|
+
function deepMapStrings(value, transform) {
|
|
7405
|
+
if (typeof value === "string")
|
|
7406
|
+
return transform(value);
|
|
7407
|
+
if (Array.isArray(value))
|
|
7408
|
+
return value.map((entry) => deepMapStrings(entry, transform));
|
|
7409
|
+
if (!value || typeof value !== "object")
|
|
7410
|
+
return value;
|
|
7411
|
+
const prototype = Object.getPrototypeOf(value);
|
|
7615
7412
|
if (prototype !== Object.prototype && prototype !== null)
|
|
7616
|
-
return
|
|
7617
|
-
return Object.fromEntries(Object.entries(
|
|
7413
|
+
return value;
|
|
7414
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, deepMapStrings(entry, transform)]));
|
|
7618
7415
|
}
|
|
7619
|
-
function encodedSecretForms2(
|
|
7416
|
+
function encodedSecretForms2(value) {
|
|
7620
7417
|
return [
|
|
7621
7418
|
...new Set([
|
|
7622
|
-
|
|
7623
|
-
encodeURIComponent(
|
|
7624
|
-
Buffer.from(
|
|
7625
|
-
Buffer.from(
|
|
7626
|
-
Buffer.from(
|
|
7419
|
+
value,
|
|
7420
|
+
encodeURIComponent(value),
|
|
7421
|
+
Buffer.from(value, "utf8").toString("base64"),
|
|
7422
|
+
Buffer.from(value, "utf8").toString("base64url"),
|
|
7423
|
+
Buffer.from(value, "utf8").toString("hex")
|
|
7627
7424
|
])
|
|
7628
7425
|
].filter(Boolean).sort((left, right) => right.length - left.length);
|
|
7629
7426
|
}
|
|
7630
|
-
function prepareInput(tool,
|
|
7427
|
+
function prepareInput(tool, value) {
|
|
7631
7428
|
const config = BOUNDED_OUTPUTS[tool];
|
|
7632
|
-
if (!config || !
|
|
7633
|
-
return { value
|
|
7634
|
-
const input =
|
|
7429
|
+
if (!config || !value || typeof value !== "object" || Array.isArray(value))
|
|
7430
|
+
return { value };
|
|
7431
|
+
const input = value;
|
|
7635
7432
|
const requested = input[config.argument];
|
|
7636
7433
|
if (requested !== undefined && (!Number.isSafeInteger(requested) || Number(requested) <= 0)) {
|
|
7637
|
-
return { value
|
|
7434
|
+
return { value };
|
|
7638
7435
|
}
|
|
7639
7436
|
const limit = requested === undefined ? DEFAULT_OUTPUT_LIMIT : Number(requested);
|
|
7640
7437
|
return {
|
|
@@ -7701,7 +7498,7 @@ async function createBrowserVaultBroker(userId) {
|
|
|
7701
7498
|
}
|
|
7702
7499
|
return output;
|
|
7703
7500
|
};
|
|
7704
|
-
const redact = (
|
|
7501
|
+
const redact = (value) => deepMapStrings(value, (text) => redactRetained(redactVaultSecrets(userId, text)));
|
|
7705
7502
|
const handleRequest = (request) => {
|
|
7706
7503
|
const id = request.id;
|
|
7707
7504
|
if (!authorized(request.token, token))
|
|
@@ -7710,9 +7507,9 @@ async function createBrowserVaultBroker(userId) {
|
|
|
7710
7507
|
if (typeof request.tool !== "string")
|
|
7711
7508
|
return { id, ok: false, error: "invalid tool" };
|
|
7712
7509
|
const leaseCutoff = Date.now() - LEASE_TTL_MS;
|
|
7713
|
-
for (const [
|
|
7510
|
+
for (const [lease, binding] of leases) {
|
|
7714
7511
|
if (binding.createdAt < leaseCutoff)
|
|
7715
|
-
leases.delete(
|
|
7512
|
+
leases.delete(lease);
|
|
7716
7513
|
}
|
|
7717
7514
|
if (leases.size >= MAX_ACTIVE_LEASES) {
|
|
7718
7515
|
return { id, ok: false, error: "too many active leases" };
|
|
@@ -7749,12 +7546,12 @@ async function createBrowserVaultBroker(userId) {
|
|
|
7749
7546
|
return { id, ok: false, error: "invalid lease" };
|
|
7750
7547
|
}
|
|
7751
7548
|
try {
|
|
7752
|
-
const
|
|
7753
|
-
const serialized = JSON.stringify(
|
|
7549
|
+
const value = secureOutput(request.value, redact, binding.boundary);
|
|
7550
|
+
const serialized = JSON.stringify(value);
|
|
7754
7551
|
if (redactRetained(serialized) !== serialized) {
|
|
7755
7552
|
return { id, ok: false, error: "redaction verification failed" };
|
|
7756
7553
|
}
|
|
7757
|
-
return { id, ok: true, value
|
|
7554
|
+
return { id, ok: true, value };
|
|
7758
7555
|
} catch {
|
|
7759
7556
|
return { id, ok: false, error: "redaction failed" };
|
|
7760
7557
|
}
|
|
@@ -7830,11 +7627,11 @@ var init_vault_broker = __esm(async () => {
|
|
|
7830
7627
|
|
|
7831
7628
|
// ../../packages/core/src/storage/browser-profiles.ts
|
|
7832
7629
|
function normalizeBrowserProfileName(name) {
|
|
7833
|
-
const
|
|
7834
|
-
if (!/^[a-z0-9][a-z0-9_-]{0,47}$/.test(
|
|
7630
|
+
const value = name.trim().toLowerCase();
|
|
7631
|
+
if (!/^[a-z0-9][a-z0-9_-]{0,47}$/.test(value)) {
|
|
7835
7632
|
throw new Error("Profile name must be 1-48 lowercase letters, numbers, '-' or '_'.");
|
|
7836
7633
|
}
|
|
7837
|
-
return
|
|
7634
|
+
return value;
|
|
7838
7635
|
}
|
|
7839
7636
|
function getBrowserProfileOwner(topicId, fallbackUserId) {
|
|
7840
7637
|
return db.query("SELECT browser_profile_owner FROM api_topics WHERE id = ?").get(topicId)?.browser_profile_owner ?? fallbackUserId;
|
|
@@ -7843,8 +7640,8 @@ function isTopicBrowserProfileOwner(topicId, userId) {
|
|
|
7843
7640
|
return getBrowserProfileOwner(topicId, "") === userId;
|
|
7844
7641
|
}
|
|
7845
7642
|
function getTopicBrowserProfile(topicId) {
|
|
7846
|
-
const
|
|
7847
|
-
return
|
|
7643
|
+
const value = db.query("SELECT browser_profile FROM api_topics WHERE id = ?").get(topicId)?.browser_profile;
|
|
7644
|
+
return value || DEFAULT_BROWSER_PROFILE;
|
|
7848
7645
|
}
|
|
7849
7646
|
function hasBrowserProfileTopic(topicId) {
|
|
7850
7647
|
return Boolean(db.query("SELECT id FROM api_topics WHERE id = ?").get(topicId));
|
|
@@ -8245,9 +8042,9 @@ async function spawnPlaywright(instanceKey, ownerId, reservedPort, browserBin =
|
|
|
8245
8042
|
const stderrTail = captureBoundedStderr(proc);
|
|
8246
8043
|
const startup = watchChildStartup(proc, stderrTail);
|
|
8247
8044
|
const reapCrashedBrowser = () => {
|
|
8248
|
-
const
|
|
8249
|
-
managerHost.cleanupBrowserProcessesForDataDir(
|
|
8250
|
-
cleanSingletonFiles(
|
|
8045
|
+
const userDataDir = resolveUserDataDir(instanceKey);
|
|
8046
|
+
managerHost.cleanupBrowserProcessesForDataDir(userDataDir);
|
|
8047
|
+
cleanSingletonFiles(userDataDir);
|
|
8251
8048
|
};
|
|
8252
8049
|
proc.once("error", (err) => {
|
|
8253
8050
|
logger.error({ err, instanceKey, stderr: stderrTail() || undefined }, "Playwright MCP error");
|
|
@@ -8607,11 +8404,11 @@ var init_manager2 = __esm(async () => {
|
|
|
8607
8404
|
});
|
|
8608
8405
|
|
|
8609
8406
|
// ../../packages/core/src/identifiers.ts
|
|
8610
|
-
function asTurnId(
|
|
8611
|
-
return
|
|
8407
|
+
function asTurnId(value) {
|
|
8408
|
+
return value;
|
|
8612
8409
|
}
|
|
8613
|
-
function asTurnSlotKey(
|
|
8614
|
-
return
|
|
8410
|
+
function asTurnSlotKey(value) {
|
|
8411
|
+
return value;
|
|
8615
8412
|
}
|
|
8616
8413
|
|
|
8617
8414
|
// ../../packages/core/src/query/room-query-registry.ts
|
|
@@ -8664,8 +8461,8 @@ function createRoomQueryRegistry(host) {
|
|
|
8664
8461
|
clearInterval(previousMonitor);
|
|
8665
8462
|
activeByRoom.set(roomId, control);
|
|
8666
8463
|
const monitor = setInterval(() => {
|
|
8667
|
-
const
|
|
8668
|
-
if (!
|
|
8464
|
+
const current = activeByRoom.get(roomId);
|
|
8465
|
+
if (!current || current.queryId !== control.queryId) {
|
|
8669
8466
|
clearInterval(monitor);
|
|
8670
8467
|
if (leaseMonitors.get(roomId) === monitor)
|
|
8671
8468
|
leaseMonitors.delete(roomId);
|
|
@@ -8687,8 +8484,8 @@ function createRoomQueryRegistry(host) {
|
|
|
8687
8484
|
return true;
|
|
8688
8485
|
}
|
|
8689
8486
|
function clear(roomId, queryId) {
|
|
8690
|
-
const
|
|
8691
|
-
if (
|
|
8487
|
+
const current = activeByRoom.get(roomId);
|
|
8488
|
+
if (current?.queryId === queryId) {
|
|
8692
8489
|
activeByRoom.delete(roomId);
|
|
8693
8490
|
const monitor = leaseMonitors.get(roomId);
|
|
8694
8491
|
if (monitor)
|
|
@@ -8751,43 +8548,12 @@ var init_room_query_registry = () => {};
|
|
|
8751
8548
|
var init_types2 = () => {};
|
|
8752
8549
|
|
|
8753
8550
|
// ../../packages/core/src/query/active-rooms.ts
|
|
8754
|
-
var exports_active_rooms = {};
|
|
8755
|
-
__export(exports_active_rooms, {
|
|
8756
|
-
wsAbortReason: () => wsAbortReason,
|
|
8757
|
-
takeDeferredInject: () => takeDeferredInject,
|
|
8758
|
-
setRoomQuery: () => setRoomQuery,
|
|
8759
|
-
listRunningTopicQueries: () => listRunningTopicQueries,
|
|
8760
|
-
listRunningTopicIds: () => listRunningTopicIds,
|
|
8761
|
-
isolatedTurnRoomId: () => isolatedTurnRoomId,
|
|
8762
|
-
isUserOrigin: () => isUserOrigin,
|
|
8763
|
-
isTopicRunning: () => isTopicRunning,
|
|
8764
|
-
interSessionQueue: () => interSessionQueue,
|
|
8765
|
-
getRoomQueryStatus: () => getRoomQueryStatus,
|
|
8766
|
-
getRoomQuery: () => getRoomQuery,
|
|
8767
|
-
deferInject: () => deferInject,
|
|
8768
|
-
decideNewQuery: () => decideNewQuery,
|
|
8769
|
-
clearRoomQuery: () => clearRoomQuery,
|
|
8770
|
-
cancelDeferredInject: () => cancelDeferredInject,
|
|
8771
|
-
abortRoom: () => abortRoom,
|
|
8772
|
-
abortAllRooms: () => abortAllRooms,
|
|
8773
|
-
InterSessionQueue: () => InterSessionQueue,
|
|
8774
|
-
DeferredInjectBatcher: () => DeferredInjectBatcher
|
|
8775
|
-
});
|
|
8776
8551
|
function getRoomQuery(roomId) {
|
|
8777
8552
|
return roomQueryRegistry.get(roomId);
|
|
8778
8553
|
}
|
|
8779
|
-
function listRunningTopicQueries() {
|
|
8780
|
-
return roomQueryRegistry.listRunningTopicQueries();
|
|
8781
|
-
}
|
|
8782
|
-
function listRunningTopicIds() {
|
|
8783
|
-
return roomQueryRegistry.listRunningTopicIds();
|
|
8784
|
-
}
|
|
8785
8554
|
function isTopicRunning(topicId) {
|
|
8786
8555
|
return roomQueryRegistry.isTopicRunning(topicId);
|
|
8787
8556
|
}
|
|
8788
|
-
function getRoomQueryStatus(topicId, queryId) {
|
|
8789
|
-
return roomQueryRegistry.status(topicId, queryId);
|
|
8790
|
-
}
|
|
8791
8557
|
function setRoomQuery(control) {
|
|
8792
8558
|
return roomQueryRegistry.set(control);
|
|
8793
8559
|
}
|
|
@@ -8797,9 +8563,6 @@ function clearRoomQuery(roomId, queryId) {
|
|
|
8797
8563
|
function abortRoom(roomId, reason = "external" /* External */) {
|
|
8798
8564
|
return roomQueryRegistry.abort(roomId, reason);
|
|
8799
8565
|
}
|
|
8800
|
-
function abortAllRooms(reason = "external" /* External */) {
|
|
8801
|
-
return roomQueryRegistry.abortAll(reason);
|
|
8802
|
-
}
|
|
8803
8566
|
function decideNewQuery(topicId, incomingOrigin) {
|
|
8804
8567
|
return roomQueryRegistry.decide(topicId, incomingOrigin);
|
|
8805
8568
|
}
|
|
@@ -8965,9 +8728,6 @@ function deferInject(inject) {
|
|
|
8965
8728
|
function takeDeferredInject(topicId) {
|
|
8966
8729
|
return interSessionQueue.dequeueAll(topicId);
|
|
8967
8730
|
}
|
|
8968
|
-
function cancelDeferredInject(topicId, requestId) {
|
|
8969
|
-
return interSessionQueue.remove(topicId, requestId) !== undefined;
|
|
8970
|
-
}
|
|
8971
8731
|
function wsAbortReason(reason) {
|
|
8972
8732
|
return reason === "internal" /* Internal */ ? "superseded" : "stopped";
|
|
8973
8733
|
}
|
|
@@ -9369,24 +9129,24 @@ RULES:
|
|
|
9369
9129
|
|
|
9370
9130
|
// ../../packages/core/src/agents/compaction-tool-projection.ts
|
|
9371
9131
|
import { createHash as createHash5 } from "crypto";
|
|
9372
|
-
function digest(
|
|
9373
|
-
return createHash5("sha256").update(
|
|
9374
|
-
}
|
|
9375
|
-
function boundedEdges(
|
|
9376
|
-
if (
|
|
9377
|
-
return
|
|
9378
|
-
const omitted =
|
|
9379
|
-
return `${
|
|
9132
|
+
function digest(value) {
|
|
9133
|
+
return createHash5("sha256").update(value).digest("hex").slice(0, 16);
|
|
9134
|
+
}
|
|
9135
|
+
function boundedEdges(value, edgeChars) {
|
|
9136
|
+
if (value.length <= edgeChars * 2)
|
|
9137
|
+
return value;
|
|
9138
|
+
const omitted = value.length - edgeChars * 2;
|
|
9139
|
+
return `${value.slice(0, edgeChars)}
|
|
9380
9140
|
[\u2026 omitted ${omitted.toLocaleString()} chars \u2026]
|
|
9381
|
-
${
|
|
9141
|
+
${value.slice(-edgeChars)}`;
|
|
9382
9142
|
}
|
|
9383
|
-
function quoted(
|
|
9384
|
-
return JSON.stringify(
|
|
9143
|
+
function quoted(value) {
|
|
9144
|
+
return JSON.stringify(value);
|
|
9385
9145
|
}
|
|
9386
|
-
function salientLines(
|
|
9146
|
+
function salientLines(value) {
|
|
9387
9147
|
const selected = [];
|
|
9388
9148
|
let chars = 0;
|
|
9389
|
-
for (const line of
|
|
9149
|
+
for (const line of value.split(`
|
|
9390
9150
|
`)) {
|
|
9391
9151
|
if (!SALIENT_LINE_RE.test(line))
|
|
9392
9152
|
continue;
|
|
@@ -9664,19 +9424,19 @@ function memoizeImport(loader) {
|
|
|
9664
9424
|
}
|
|
9665
9425
|
|
|
9666
9426
|
// ../../packages/core/src/agents/deep-map.ts
|
|
9667
|
-
function deepMapStrings2(
|
|
9668
|
-
if (typeof
|
|
9669
|
-
return fn(
|
|
9670
|
-
if (Array.isArray(
|
|
9671
|
-
return
|
|
9672
|
-
if (
|
|
9427
|
+
function deepMapStrings2(value, fn) {
|
|
9428
|
+
if (typeof value === "string")
|
|
9429
|
+
return fn(value);
|
|
9430
|
+
if (Array.isArray(value))
|
|
9431
|
+
return value.map((v) => deepMapStrings2(v, fn));
|
|
9432
|
+
if (value && typeof value === "object") {
|
|
9673
9433
|
const out = {};
|
|
9674
|
-
for (const [k, v] of Object.entries(
|
|
9434
|
+
for (const [k, v] of Object.entries(value)) {
|
|
9675
9435
|
out[k] = deepMapStrings2(v, fn);
|
|
9676
9436
|
}
|
|
9677
9437
|
return out;
|
|
9678
9438
|
}
|
|
9679
|
-
return
|
|
9439
|
+
return value;
|
|
9680
9440
|
}
|
|
9681
9441
|
|
|
9682
9442
|
// ../../packages/core/src/media/file-events.ts
|
|
@@ -9710,10 +9470,10 @@ function shouldWarnForContext(usage, thresholdRatio = DEFAULT_CONTEXT_WARNING_RA
|
|
|
9710
9470
|
const ratio = contextUsageRatio(usage);
|
|
9711
9471
|
return ratio !== null && ratio >= thresholdRatio;
|
|
9712
9472
|
}
|
|
9713
|
-
function formatContextTokenCount(
|
|
9714
|
-
if (!Number.isFinite(
|
|
9473
|
+
function formatContextTokenCount(value) {
|
|
9474
|
+
if (!Number.isFinite(value) || value < 0)
|
|
9715
9475
|
return "0K";
|
|
9716
|
-
return
|
|
9476
|
+
return value >= 1e6 ? `${(value / 1e6).toFixed(1)}M` : `${Math.round(value / 1000)}K`;
|
|
9717
9477
|
}
|
|
9718
9478
|
function buildContextWarningText(options) {
|
|
9719
9479
|
const ratio = contextUsageRatio(options.usage) ?? 0;
|
|
@@ -9747,23 +9507,23 @@ function claudeRequestContextTokens(usage) {
|
|
|
9747
9507
|
usage.cache_read_input_tokens,
|
|
9748
9508
|
usage.output_tokens
|
|
9749
9509
|
];
|
|
9750
|
-
if (values.every((
|
|
9510
|
+
if (values.every((value) => value === undefined || value === null))
|
|
9751
9511
|
return null;
|
|
9752
|
-
if (values.some((
|
|
9512
|
+
if (values.some((value) => value !== undefined && value !== null && (!Number.isFinite(value) || value < 0))) {
|
|
9753
9513
|
return null;
|
|
9754
9514
|
}
|
|
9755
|
-
return values.reduce((sum,
|
|
9515
|
+
return values.reduce((sum, value) => sum + (value ?? 0), 0);
|
|
9756
9516
|
}
|
|
9757
9517
|
var DEFAULT_CONTEXT_WARNING_RATIO = 0.8;
|
|
9758
9518
|
|
|
9759
9519
|
// ../../packages/core/src/agents/claude-provider.ts
|
|
9760
9520
|
var exports_claude_provider = {};
|
|
9761
9521
|
__export(exports_claude_provider, {
|
|
9762
|
-
|
|
9763
|
-
spawnClaudeCodeProcessWithTreeKill: () => spawnClaudeCodeProcessWithTreeKill,
|
|
9764
|
-
claudeProvider: () => claudeProvider,
|
|
9522
|
+
buildClaudeDisallowedTools: () => buildClaudeDisallowedTools,
|
|
9765
9523
|
claudeBuiltInTools: () => claudeBuiltInTools,
|
|
9766
|
-
|
|
9524
|
+
claudeProvider: () => claudeProvider,
|
|
9525
|
+
spawnClaudeCodeProcessWithTreeKill: () => spawnClaudeCodeProcessWithTreeKill,
|
|
9526
|
+
substituteClaudeToolInput: () => substituteClaudeToolInput
|
|
9767
9527
|
});
|
|
9768
9528
|
import { spawn as spawn6 } from "child_process";
|
|
9769
9529
|
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
|
|
@@ -9774,7 +9534,7 @@ function claudeBuiltInTools(opts) {
|
|
|
9774
9534
|
function substituteClaudeToolInput(userId, toolName, input) {
|
|
9775
9535
|
if (!shouldSubstituteVaultToolInput(toolName))
|
|
9776
9536
|
return input;
|
|
9777
|
-
return deepMapStrings2(input, (
|
|
9537
|
+
return deepMapStrings2(input, (value) => substituteHostedSecrets(userId, value));
|
|
9778
9538
|
}
|
|
9779
9539
|
function buildClaudeDisallowedTools(extra = undefined) {
|
|
9780
9540
|
return [
|
|
@@ -9844,8 +9604,8 @@ function buildClaudePrompt(opts) {
|
|
|
9844
9604
|
}
|
|
9845
9605
|
function watchClaudeProcessExit(signal) {
|
|
9846
9606
|
let listener;
|
|
9847
|
-
const exited = new Promise((
|
|
9848
|
-
listener =
|
|
9607
|
+
const exited = new Promise((resolve) => {
|
|
9608
|
+
listener = resolve;
|
|
9849
9609
|
const listeners = claudeProcessExitListeners.get(signal) ?? new Set;
|
|
9850
9610
|
listeners.add(listener);
|
|
9851
9611
|
claudeProcessExitListeners.set(signal, listeners);
|
|
@@ -10073,7 +9833,7 @@ async function* claudeProvider(opts) {
|
|
|
10073
9833
|
async (input) => {
|
|
10074
9834
|
const { tool_response } = input;
|
|
10075
9835
|
const userId = opts.vaultUserId ?? opts.userId ?? "";
|
|
10076
|
-
const redacted = deepMapStrings2(tool_response, (
|
|
9836
|
+
const redacted = deepMapStrings2(tool_response, (value) => redactHostedSecrets(userId, value));
|
|
10077
9837
|
if (JSON.stringify(redacted) === JSON.stringify(tool_response)) {
|
|
10078
9838
|
return { continue: true };
|
|
10079
9839
|
}
|
|
@@ -10370,12 +10130,12 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
10370
10130
|
const previous = spawnChain;
|
|
10371
10131
|
let release;
|
|
10372
10132
|
let released = false;
|
|
10373
|
-
spawnChain = new Promise((
|
|
10133
|
+
spawnChain = new Promise((resolve) => {
|
|
10374
10134
|
release = () => {
|
|
10375
10135
|
if (released)
|
|
10376
10136
|
return;
|
|
10377
10137
|
released = true;
|
|
10378
|
-
|
|
10138
|
+
resolve();
|
|
10379
10139
|
};
|
|
10380
10140
|
});
|
|
10381
10141
|
await previous;
|
|
@@ -10482,7 +10242,7 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
10482
10242
|
return;
|
|
10483
10243
|
const deadline = Date.now() + Math.max(0, graceMs);
|
|
10484
10244
|
while (Date.now() < deadline && hasSurvivors(plan.targets)) {
|
|
10485
|
-
await new Promise((
|
|
10245
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(100, Math.max(1, deadline - Date.now()))));
|
|
10486
10246
|
}
|
|
10487
10247
|
killStragglers(plan);
|
|
10488
10248
|
}
|
|
@@ -10556,8 +10316,8 @@ function cscPath() {
|
|
|
10556
10316
|
throw new Error("csc.exe (.NET Framework 4) was not found, so the Codex hook wrapper cannot be built");
|
|
10557
10317
|
}
|
|
10558
10318
|
async function ensureCodexWindowsWrapperExe(cacheDir) {
|
|
10559
|
-
const
|
|
10560
|
-
const exePath = join18(cacheDir, `codex-hook-wrapper-${
|
|
10319
|
+
const digest = createHash6("sha256").update(CODEX_WINDOWS_WRAPPER_SOURCE).digest("hex").slice(0, 12);
|
|
10320
|
+
const exePath = join18(cacheDir, `codex-hook-wrapper-${digest}.exe`);
|
|
10561
10321
|
if (existsSync18(exePath))
|
|
10562
10322
|
return exePath;
|
|
10563
10323
|
await mkdir(cacheDir, { recursive: true });
|
|
@@ -10694,7 +10454,7 @@ function evaluateCodexVaultPreToolUse(input, userId, operations) {
|
|
|
10694
10454
|
}
|
|
10695
10455
|
if (!shouldSubstituteVaultToolInput(input.tool_name))
|
|
10696
10456
|
return {};
|
|
10697
|
-
const updatedInput = deepMapStrings2(input.tool_input, (
|
|
10457
|
+
const updatedInput = deepMapStrings2(input.tool_input, (value) => operations.substitute(userId, value));
|
|
10698
10458
|
if (JSON.stringify(updatedInput) === JSON.stringify(input.tool_input))
|
|
10699
10459
|
return {};
|
|
10700
10460
|
return {
|
|
@@ -10705,8 +10465,8 @@ function evaluateCodexVaultPreToolUse(input, userId, operations) {
|
|
|
10705
10465
|
}
|
|
10706
10466
|
};
|
|
10707
10467
|
}
|
|
10708
|
-
function shellQuote(
|
|
10709
|
-
return `'${
|
|
10468
|
+
function shellQuote(value) {
|
|
10469
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
10710
10470
|
}
|
|
10711
10471
|
function hookClientPath() {
|
|
10712
10472
|
const moduleDir = dirname13(fileURLToPath2(import.meta.url));
|
|
@@ -10732,8 +10492,8 @@ function privateCodexWrapper(codexScript, socketPath, token) {
|
|
|
10732
10492
|
].join(`
|
|
10733
10493
|
`);
|
|
10734
10494
|
}
|
|
10735
|
-
function windowsQuote(
|
|
10736
|
-
return `"${
|
|
10495
|
+
function windowsQuote(value) {
|
|
10496
|
+
return `"${value.replaceAll('"', "\\\"")}"`;
|
|
10737
10497
|
}
|
|
10738
10498
|
async function createCodexVaultHookBridge(userId) {
|
|
10739
10499
|
const root = await mkdtemp(join19(tmpdir3(), "negotium-codex-vault-"));
|
|
@@ -10789,8 +10549,8 @@ async function createCodexVaultHookBridge(userId) {
|
|
|
10789
10549
|
});
|
|
10790
10550
|
restrictIpcEndpoint(socketPath);
|
|
10791
10551
|
if (IS_WINDOWS2) {
|
|
10792
|
-
|
|
10793
|
-
const cached = await ensureCodexWindowsWrapperExe(join19(
|
|
10552
|
+
await Promise.resolve().then(() => init_config());
|
|
10553
|
+
const cached = await ensureCodexWindowsWrapperExe(join19(BINARIES_DIR, "codex-hook-wrapper"));
|
|
10794
10554
|
await copyFile(cached, wrapperPath);
|
|
10795
10555
|
await writeFile2(join19(root, "codex-with-hooks.cfg"), [process.execPath, codexCliScriptPath(), socketPath, token].join(`
|
|
10796
10556
|
`), { encoding: "utf8", mode: 384 });
|
|
@@ -10847,16 +10607,16 @@ var init_codex_vault_hook_bridge = __esm(async () => {
|
|
|
10847
10607
|
import { readFileSync as readFileSync15, statSync as statSync5 } from "fs";
|
|
10848
10608
|
import { isAbsolute as isAbsolute3, resolve as resolve13 } from "path";
|
|
10849
10609
|
import { diffLines as computeLineDiff } from "diff";
|
|
10850
|
-
function summarizeDisplayText(
|
|
10851
|
-
const normalized =
|
|
10610
|
+
function summarizeDisplayText(value) {
|
|
10611
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
10852
10612
|
if (!normalized)
|
|
10853
10613
|
return "";
|
|
10854
10614
|
if (normalized.length <= TOOL_SUMMARY_MAX_CHARS)
|
|
10855
10615
|
return normalized;
|
|
10856
10616
|
return `${normalized.slice(0, TOOL_SUMMARY_HEAD_CHARS).trimEnd()}...${normalized.slice(-TOOL_SUMMARY_TAIL_CHARS).trimStart()}`;
|
|
10857
10617
|
}
|
|
10858
|
-
function unwrapShellCommand(
|
|
10859
|
-
const normalized =
|
|
10618
|
+
function unwrapShellCommand(value) {
|
|
10619
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
10860
10620
|
const match = normalized.match(/^(?:\/[^\s]+\/)?(?:zsh|bash|sh)\s+-[a-z]*c\s+(.+)$/i);
|
|
10861
10621
|
if (!match?.[1])
|
|
10862
10622
|
return normalized;
|
|
@@ -10864,41 +10624,41 @@ function unwrapShellCommand(value2) {
|
|
|
10864
10624
|
const quote = payload[0];
|
|
10865
10625
|
return (quote === '"' || quote === "'") && payload.at(-1) === quote ? payload.slice(1, -1).trim() : payload;
|
|
10866
10626
|
}
|
|
10867
|
-
function splitShellCommands(
|
|
10627
|
+
function splitShellCommands(value) {
|
|
10868
10628
|
const commands = [];
|
|
10869
|
-
let
|
|
10629
|
+
let current = "";
|
|
10870
10630
|
let quote = "";
|
|
10871
10631
|
let escaped = false;
|
|
10872
10632
|
const flush = () => {
|
|
10873
|
-
const command =
|
|
10633
|
+
const command = current.trim();
|
|
10874
10634
|
if (command)
|
|
10875
10635
|
commands.push(command);
|
|
10876
|
-
|
|
10636
|
+
current = "";
|
|
10877
10637
|
};
|
|
10878
|
-
for (let i = 0;i <
|
|
10879
|
-
const char =
|
|
10638
|
+
for (let i = 0;i < value.length; i++) {
|
|
10639
|
+
const char = value[i] ?? "";
|
|
10880
10640
|
if (escaped) {
|
|
10881
|
-
|
|
10641
|
+
current += char;
|
|
10882
10642
|
escaped = false;
|
|
10883
10643
|
continue;
|
|
10884
10644
|
}
|
|
10885
10645
|
if (char === "\\" && quote !== "'") {
|
|
10886
|
-
|
|
10646
|
+
current += char;
|
|
10887
10647
|
escaped = true;
|
|
10888
10648
|
continue;
|
|
10889
10649
|
}
|
|
10890
10650
|
if (quote) {
|
|
10891
|
-
|
|
10651
|
+
current += char;
|
|
10892
10652
|
if (char === quote)
|
|
10893
10653
|
quote = "";
|
|
10894
10654
|
continue;
|
|
10895
10655
|
}
|
|
10896
10656
|
if (char === '"' || char === "'") {
|
|
10897
10657
|
quote = char;
|
|
10898
|
-
|
|
10658
|
+
current += char;
|
|
10899
10659
|
continue;
|
|
10900
10660
|
}
|
|
10901
|
-
const pair =
|
|
10661
|
+
const pair = value.slice(i, i + 2);
|
|
10902
10662
|
if (pair === "&&" || pair === "||") {
|
|
10903
10663
|
flush();
|
|
10904
10664
|
i += 1;
|
|
@@ -10908,24 +10668,24 @@ function splitShellCommands(value2) {
|
|
|
10908
10668
|
flush();
|
|
10909
10669
|
continue;
|
|
10910
10670
|
}
|
|
10911
|
-
|
|
10671
|
+
current += char;
|
|
10912
10672
|
}
|
|
10913
10673
|
flush();
|
|
10914
10674
|
return commands;
|
|
10915
10675
|
}
|
|
10916
|
-
function shellWords(
|
|
10676
|
+
function shellWords(value) {
|
|
10917
10677
|
const words = [];
|
|
10918
|
-
let
|
|
10678
|
+
let current = "";
|
|
10919
10679
|
let quote = "";
|
|
10920
10680
|
let escaped = false;
|
|
10921
10681
|
const flush = () => {
|
|
10922
|
-
if (
|
|
10923
|
-
words.push(
|
|
10924
|
-
|
|
10682
|
+
if (current)
|
|
10683
|
+
words.push(current);
|
|
10684
|
+
current = "";
|
|
10925
10685
|
};
|
|
10926
|
-
for (const char of
|
|
10686
|
+
for (const char of value) {
|
|
10927
10687
|
if (escaped) {
|
|
10928
|
-
|
|
10688
|
+
current += char;
|
|
10929
10689
|
escaped = false;
|
|
10930
10690
|
continue;
|
|
10931
10691
|
}
|
|
@@ -10937,7 +10697,7 @@ function shellWords(value2) {
|
|
|
10937
10697
|
if (char === quote)
|
|
10938
10698
|
quote = "";
|
|
10939
10699
|
else
|
|
10940
|
-
|
|
10700
|
+
current += char;
|
|
10941
10701
|
continue;
|
|
10942
10702
|
}
|
|
10943
10703
|
if (char === '"' || char === "'") {
|
|
@@ -10948,23 +10708,23 @@ function shellWords(value2) {
|
|
|
10948
10708
|
flush();
|
|
10949
10709
|
continue;
|
|
10950
10710
|
}
|
|
10951
|
-
|
|
10711
|
+
current += char;
|
|
10952
10712
|
}
|
|
10953
10713
|
flush();
|
|
10954
10714
|
return words;
|
|
10955
10715
|
}
|
|
10956
|
-
function commandName(
|
|
10957
|
-
return
|
|
10716
|
+
function commandName(value) {
|
|
10717
|
+
return value.replace(/\\/g, "/").split("/").at(-1) || value;
|
|
10958
10718
|
}
|
|
10959
|
-
function compactPath(
|
|
10960
|
-
const normalized =
|
|
10719
|
+
function compactPath(value) {
|
|
10720
|
+
const normalized = value.replace(/\\/g, "/").replace(/\/$/, "");
|
|
10961
10721
|
return normalized.split("/").at(-1) || normalized;
|
|
10962
10722
|
}
|
|
10963
|
-
function looksLikePath(
|
|
10964
|
-
return
|
|
10723
|
+
function looksLikePath(value) {
|
|
10724
|
+
return value.includes("/") || /^\.?[A-Za-z0-9_-]+\.(?:[A-Za-z0-9_-]+)$/.test(value) || /^(?:CLAUDE|AGENTS|README|STYLE)(?:\.[A-Za-z0-9_-]+)?$/i.test(value);
|
|
10965
10725
|
}
|
|
10966
10726
|
function summarizeTargets(values) {
|
|
10967
|
-
const targets = values.filter((
|
|
10727
|
+
const targets = values.filter((value) => value && !value.startsWith("-")).map(compactPath);
|
|
10968
10728
|
if (targets.length === 0)
|
|
10969
10729
|
return "";
|
|
10970
10730
|
if (targets.length === 1)
|
|
@@ -10994,8 +10754,8 @@ function summarizeSsh(words) {
|
|
|
10994
10754
|
const remoteSummary = remoteCommand ? summarizeShellCommand(remoteCommand) : "";
|
|
10995
10755
|
return ["ssh", destination, remoteSummary].filter(Boolean).join(" \xB7 ");
|
|
10996
10756
|
}
|
|
10997
|
-
function summarizeShellPart(
|
|
10998
|
-
const words = shellWords(
|
|
10757
|
+
function summarizeShellPart(value) {
|
|
10758
|
+
const words = shellWords(value).filter((word) => !/^\d*>/.test(word));
|
|
10999
10759
|
while (words[0] === "sudo")
|
|
11000
10760
|
words.shift();
|
|
11001
10761
|
if (words[0] === "env") {
|
|
@@ -11052,8 +10812,8 @@ function summarizeShellPart(value2) {
|
|
|
11052
10812
|
const detail = words.find((word) => !word.startsWith("-"));
|
|
11053
10813
|
return [executable, detail ? compactPath(detail) : ""].filter(Boolean).join(" ");
|
|
11054
10814
|
}
|
|
11055
|
-
function summarizeShellCommand(
|
|
11056
|
-
const payload = unwrapShellCommand(
|
|
10815
|
+
function summarizeShellCommand(value) {
|
|
10816
|
+
const payload = unwrapShellCommand(value);
|
|
11057
10817
|
const parts = splitShellCommands(payload).map(summarizeShellPart).filter(Boolean);
|
|
11058
10818
|
if (parts.length === 0)
|
|
11059
10819
|
return summarizeDisplayText(payload);
|
|
@@ -11061,10 +10821,10 @@ function summarizeShellCommand(value2) {
|
|
|
11061
10821
|
const remainder = parts.length - visible.length;
|
|
11062
10822
|
return summarizeDisplayText(`${visible.join(" \xB7 ")}${remainder > 0 ? ` \xB7 +${remainder}` : ""}`);
|
|
11063
10823
|
}
|
|
11064
|
-
function classifyShellToolName(
|
|
11065
|
-
if (/[\r\n]/.test(
|
|
10824
|
+
function classifyShellToolName(value) {
|
|
10825
|
+
if (/[\r\n]/.test(value))
|
|
11066
10826
|
return "Bash";
|
|
11067
|
-
const payload = unwrapShellCommand(
|
|
10827
|
+
const payload = unwrapShellCommand(value);
|
|
11068
10828
|
if (/[|;&><`]/.test(payload) || payload.includes("$("))
|
|
11069
10829
|
return "Bash";
|
|
11070
10830
|
const words = shellWords(payload);
|
|
@@ -11103,17 +10863,17 @@ function classifyShellToolName(value2) {
|
|
|
11103
10863
|
}
|
|
11104
10864
|
return "Bash";
|
|
11105
10865
|
}
|
|
11106
|
-
function summarizePrimitive(
|
|
11107
|
-
if (typeof
|
|
11108
|
-
return
|
|
11109
|
-
if (typeof
|
|
10866
|
+
function summarizePrimitive(value) {
|
|
10867
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
10868
|
+
return value;
|
|
10869
|
+
if (typeof value !== "string")
|
|
11110
10870
|
return;
|
|
11111
|
-
return summarizeDisplayText(
|
|
10871
|
+
return summarizeDisplayText(value) || undefined;
|
|
11112
10872
|
}
|
|
11113
|
-
function summarizeDiffText(
|
|
11114
|
-
if (typeof
|
|
10873
|
+
function summarizeDiffText(value) {
|
|
10874
|
+
if (typeof value !== "string")
|
|
11115
10875
|
return;
|
|
11116
|
-
const normalized =
|
|
10876
|
+
const normalized = value.replace(/\r\n?/g, `
|
|
11117
10877
|
`);
|
|
11118
10878
|
if (!normalized.trim())
|
|
11119
10879
|
return;
|
|
@@ -11122,8 +10882,8 @@ function summarizeDiffText(value2) {
|
|
|
11122
10882
|
return `${normalized.slice(0, TOOL_DIFF_MAX_CHARS - 2)}
|
|
11123
10883
|
\u2026`;
|
|
11124
10884
|
}
|
|
11125
|
-
function changedDiffLines(
|
|
11126
|
-
const lines =
|
|
10885
|
+
function changedDiffLines(value) {
|
|
10886
|
+
const lines = value.split(`
|
|
11127
10887
|
`);
|
|
11128
10888
|
if (lines.at(-1) === "")
|
|
11129
10889
|
lines.pop();
|
|
@@ -11184,8 +10944,8 @@ function sourceStartLine(input, before, after, cwd) {
|
|
|
11184
10944
|
} catch {}
|
|
11185
10945
|
return 1;
|
|
11186
10946
|
}
|
|
11187
|
-
function logicalLineCount(
|
|
11188
|
-
const normalized =
|
|
10947
|
+
function logicalLineCount(value) {
|
|
10948
|
+
const normalized = value.replace(/\r\n?/g, `
|
|
11189
10949
|
`);
|
|
11190
10950
|
if (!normalized)
|
|
11191
10951
|
return 0;
|
|
@@ -11194,10 +10954,10 @@ function logicalLineCount(value2) {
|
|
|
11194
10954
|
return withoutFinalTerminator.split(`
|
|
11195
10955
|
`).length;
|
|
11196
10956
|
}
|
|
11197
|
-
function summarizeAskChoices(
|
|
11198
|
-
if (!Array.isArray(
|
|
10957
|
+
function summarizeAskChoices(value) {
|
|
10958
|
+
if (!Array.isArray(value))
|
|
11199
10959
|
return;
|
|
11200
|
-
const choices =
|
|
10960
|
+
const choices = value.map((choice) => {
|
|
11201
10961
|
if (!choice || typeof choice !== "object")
|
|
11202
10962
|
return null;
|
|
11203
10963
|
const record = choice;
|
|
@@ -11226,9 +10986,9 @@ function summarizeToolInput(name, input, options = {}) {
|
|
|
11226
10986
|
}
|
|
11227
10987
|
for (const key of SUMMARY_KEYS) {
|
|
11228
10988
|
const raw = input[key];
|
|
11229
|
-
const
|
|
11230
|
-
if (
|
|
11231
|
-
summary[key] =
|
|
10989
|
+
const value = (key === "command" || key === "cmd") && typeof raw === "string" ? summarizeShellCommand(raw) : summarizePrimitive(raw);
|
|
10990
|
+
if (value !== undefined)
|
|
10991
|
+
summary[key] = value;
|
|
11232
10992
|
}
|
|
11233
10993
|
if (shortName === "ask_session" || shortName === "tell_session") {
|
|
11234
10994
|
const message = summarizePrimitive(input.message);
|
|
@@ -11362,9 +11122,9 @@ var init_tool_format = __esm(() => {
|
|
|
11362
11122
|
// ../../packages/core/src/agents/codex-provider.ts
|
|
11363
11123
|
var exports_codex_provider = {};
|
|
11364
11124
|
__export(exports_codex_provider, {
|
|
11365
|
-
|
|
11125
|
+
codexProvider: () => codexProvider,
|
|
11366
11126
|
normalizeCodexTurnUsage: () => normalizeCodexTurnUsage,
|
|
11367
|
-
|
|
11127
|
+
toCodexMcpServers: () => toCodexMcpServers
|
|
11368
11128
|
});
|
|
11369
11129
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
11370
11130
|
import { existsSync as existsSync20, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync6 } from "fs";
|
|
@@ -11377,7 +11137,7 @@ function sameCodexUsage(usage, total) {
|
|
|
11377
11137
|
function normalizeCodexTurnUsage(usage, baseline, rolloutTotal) {
|
|
11378
11138
|
if (!baseline || !rolloutTotal || !sameCodexUsage(usage, rolloutTotal))
|
|
11379
11139
|
return usage;
|
|
11380
|
-
const delta = (
|
|
11140
|
+
const delta = (current, previous) => current >= previous ? current - previous : current;
|
|
11381
11141
|
return {
|
|
11382
11142
|
input_tokens: delta(rolloutTotal.inputTokens, baseline.inputTokens),
|
|
11383
11143
|
output_tokens: delta(rolloutTotal.outputTokens, baseline.outputTokens),
|
|
@@ -11424,10 +11184,10 @@ function globalCodexMcpServerNames(authFilePath) {
|
|
|
11424
11184
|
return [];
|
|
11425
11185
|
}
|
|
11426
11186
|
}
|
|
11427
|
-
function parsePositiveInt(
|
|
11428
|
-
if (!
|
|
11187
|
+
function parsePositiveInt(value, fallback) {
|
|
11188
|
+
if (!value)
|
|
11429
11189
|
return fallback;
|
|
11430
|
-
const parsed = Number.parseInt(
|
|
11190
|
+
const parsed = Number.parseInt(value, 10);
|
|
11431
11191
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
11432
11192
|
}
|
|
11433
11193
|
function withCodexMcpServerOverrides(_name, server) {
|
|
@@ -11664,9 +11424,9 @@ async function startStreamedWithTracking(thread, prompt, abortSignal, trackedPid
|
|
|
11664
11424
|
nextP.catch(() => {});
|
|
11665
11425
|
first = await Promise.race([nextP, startupTimeout]);
|
|
11666
11426
|
} catch (err) {
|
|
11667
|
-
const
|
|
11668
|
-
if (
|
|
11669
|
-
killCodexTrees(
|
|
11427
|
+
const novel = findNewCodexChildren(baseline);
|
|
11428
|
+
if (novel.length > 0) {
|
|
11429
|
+
killCodexTrees(novel);
|
|
11670
11430
|
}
|
|
11671
11431
|
await closeIterator(iter);
|
|
11672
11432
|
throw err;
|
|
@@ -11702,11 +11462,11 @@ function prependFirstEvent(iter, firstEvent, alreadyDone) {
|
|
|
11702
11462
|
exhausted = true;
|
|
11703
11463
|
return r;
|
|
11704
11464
|
},
|
|
11705
|
-
async return(
|
|
11465
|
+
async return(value) {
|
|
11706
11466
|
exhausted = true;
|
|
11707
11467
|
if (iter.return)
|
|
11708
|
-
return iter.return(
|
|
11709
|
-
return { value
|
|
11468
|
+
return iter.return(value);
|
|
11469
|
+
return { value, done: true };
|
|
11710
11470
|
}
|
|
11711
11471
|
};
|
|
11712
11472
|
}
|
|
@@ -11901,7 +11661,7 @@ async function* codexProvider(opts) {
|
|
|
11901
11661
|
yield {
|
|
11902
11662
|
type: "tool_use",
|
|
11903
11663
|
name: String(item.tool ?? "unknown"),
|
|
11904
|
-
input: deepMapStrings2(input, (
|
|
11664
|
+
input: deepMapStrings2(input, (value) => redactHostedSecrets(opts.vaultUserId ?? opts.userId ?? "", value)),
|
|
11905
11665
|
toolUseId: String(item.id ?? "")
|
|
11906
11666
|
};
|
|
11907
11667
|
}
|
|
@@ -12084,11 +11844,11 @@ var init_maestro_bootstrap_env = __esm(() => {
|
|
|
12084
11844
|
// ../../packages/core/src/agents/maestro-provider.ts
|
|
12085
11845
|
var exports_maestro_provider = {};
|
|
12086
11846
|
__export(exports_maestro_provider, {
|
|
12087
|
-
|
|
12088
|
-
maestroProvider: () => maestroProvider,
|
|
12089
|
-
buildMaestroToolResultTruncation: () => buildMaestroToolResultTruncation,
|
|
11847
|
+
buildMaestroDisallowedTools: () => buildMaestroDisallowedTools,
|
|
12090
11848
|
buildMaestroToolHooks: () => buildMaestroToolHooks,
|
|
12091
|
-
|
|
11849
|
+
buildMaestroToolResultTruncation: () => buildMaestroToolResultTruncation,
|
|
11850
|
+
maestroProvider: () => maestroProvider,
|
|
11851
|
+
resolveMaestroApiKeyOverrides: () => resolveMaestroApiKeyOverrides
|
|
12092
11852
|
});
|
|
12093
11853
|
import { resolve as resolve15 } from "path";
|
|
12094
11854
|
import { maestroProvider as sdkMaestroProvider, setMcpResolver } from "maestro-agent-sdk";
|
|
@@ -12109,7 +11869,7 @@ function buildVaultHook(userId) {
|
|
|
12109
11869
|
}
|
|
12110
11870
|
if (!shouldSubstituteVaultToolInput(toolName))
|
|
12111
11871
|
return { decision: "allow" };
|
|
12112
|
-
const substituted = deepMapStrings2(input, (
|
|
11872
|
+
const substituted = deepMapStrings2(input, (value) => substituteHostedSecrets(userId, value));
|
|
12113
11873
|
return JSON.stringify(substituted) === JSON.stringify(input) ? { decision: "allow" } : { decision: "modify", input: substituted };
|
|
12114
11874
|
},
|
|
12115
11875
|
post({ output }) {
|
|
@@ -12216,18 +11976,18 @@ import { join as join21 } from "path";
|
|
|
12216
11976
|
async function* dispatchAgent(opts) {
|
|
12217
11977
|
switch (opts.agent) {
|
|
12218
11978
|
case "claude": {
|
|
12219
|
-
const { claudeProvider
|
|
12220
|
-
yield*
|
|
11979
|
+
const { claudeProvider } = await loadClaudeProvider();
|
|
11980
|
+
yield* claudeProvider(opts);
|
|
12221
11981
|
return;
|
|
12222
11982
|
}
|
|
12223
11983
|
case "codex": {
|
|
12224
|
-
const { codexProvider
|
|
12225
|
-
yield*
|
|
11984
|
+
const { codexProvider } = await loadCodexProvider();
|
|
11985
|
+
yield* codexProvider(opts);
|
|
12226
11986
|
return;
|
|
12227
11987
|
}
|
|
12228
11988
|
case "maestro": {
|
|
12229
|
-
const { maestroProvider
|
|
12230
|
-
yield*
|
|
11989
|
+
const { maestroProvider } = await loadMaestroProvider();
|
|
11990
|
+
yield* maestroProvider(opts);
|
|
12231
11991
|
return;
|
|
12232
11992
|
}
|
|
12233
11993
|
default: {
|
|
@@ -12258,8 +12018,8 @@ async function resolveSessionFileMissing(agent, sessionId, cwd) {
|
|
|
12258
12018
|
return true;
|
|
12259
12019
|
}
|
|
12260
12020
|
case "maestro": {
|
|
12261
|
-
const { hasActiveMaestroSession, maestroSessionPath
|
|
12262
|
-
return !existsSync21(
|
|
12021
|
+
const { hasActiveMaestroSession, maestroSessionPath } = await import("maestro-agent-sdk");
|
|
12022
|
+
return !existsSync21(maestroSessionPath(sessionId)) && !hasActiveMaestroSession(sessionId);
|
|
12263
12023
|
}
|
|
12264
12024
|
default: {
|
|
12265
12025
|
const _exhaustive = agent;
|
|
@@ -12346,8 +12106,8 @@ function loadPrompt(filename, dir = SESSIONS_DIR) {
|
|
|
12346
12106
|
}
|
|
12347
12107
|
function replaceVars(template, vars) {
|
|
12348
12108
|
let out = template;
|
|
12349
|
-
for (const [key,
|
|
12350
|
-
out = out.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), () =>
|
|
12109
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
12110
|
+
out = out.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), () => value);
|
|
12351
12111
|
}
|
|
12352
12112
|
return out;
|
|
12353
12113
|
}
|
|
@@ -12420,9 +12180,9 @@ function loadAgentPrompt(filename) {
|
|
|
12420
12180
|
currentKey = null;
|
|
12421
12181
|
const colonIdx = line.indexOf(":");
|
|
12422
12182
|
const key = line.slice(0, colonIdx).trim();
|
|
12423
|
-
const
|
|
12424
|
-
if (key &&
|
|
12425
|
-
meta[key] =
|
|
12183
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
12184
|
+
if (key && value)
|
|
12185
|
+
meta[key] = value;
|
|
12426
12186
|
}
|
|
12427
12187
|
}
|
|
12428
12188
|
return {
|
|
@@ -12595,9 +12355,9 @@ function createPromptBuilders(host = {}) {
|
|
|
12595
12355
|
if (cached !== undefined)
|
|
12596
12356
|
return cached;
|
|
12597
12357
|
const loaded = loadTemplate?.(request);
|
|
12598
|
-
const
|
|
12599
|
-
templateCache.set(cacheKey,
|
|
12600
|
-
return
|
|
12358
|
+
const value = loaded ?? (request.kind === "topic-system" ? topicSystemPromptTemplate() : request.kind === "channel-system" ? channelSystemPromptTemplate() : request.kind === "manager-system" ? managerSystemPromptTemplate() : request.kind === "surface-profile" ? loadSessionPrompt(request.filename, request.fallback) : visualDesignGuide());
|
|
12359
|
+
templateCache.set(cacheKey, value);
|
|
12360
|
+
return value;
|
|
12601
12361
|
};
|
|
12602
12362
|
const build = (sessionKind, opts, sessionTemplate) => {
|
|
12603
12363
|
const context = Object.freeze({ ...opts, sessionKind });
|
|
@@ -12776,9 +12536,9 @@ function resolveTopicBrief(topicId, legacyTitle) {
|
|
|
12776
12536
|
const titleBrief = getTopicBrief(titleKey);
|
|
12777
12537
|
if (titleBrief)
|
|
12778
12538
|
return { brief: titleBrief, storageKey: titleKey };
|
|
12779
|
-
const
|
|
12780
|
-
if (
|
|
12781
|
-
return { brief:
|
|
12539
|
+
const current = getTopicBrief(topicId);
|
|
12540
|
+
if (current)
|
|
12541
|
+
return { brief: current, storageKey: topicId };
|
|
12782
12542
|
const legacy = titleKey === legacyTitle ? null : getTopicBrief(legacyTitle);
|
|
12783
12543
|
return legacy ? { brief: legacy, storageKey: legacyTitle } : null;
|
|
12784
12544
|
}
|
|
@@ -12836,8 +12596,8 @@ function resolveMemoryLanguage() {
|
|
|
12836
12596
|
const override = process.env.NEGOTIUM_MEMORY_LANG?.trim();
|
|
12837
12597
|
return override && override.length > 0 ? override : resolveOutputLanguage();
|
|
12838
12598
|
}
|
|
12839
|
-
function sessionText(
|
|
12840
|
-
const normalized =
|
|
12599
|
+
function sessionText(value, maxLength) {
|
|
12600
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
12841
12601
|
return maxLength === undefined ? normalized : normalized.slice(0, maxLength);
|
|
12842
12602
|
}
|
|
12843
12603
|
function formatArchiverBytes(bytes) {
|
|
@@ -12848,8 +12608,8 @@ function formatArchiverBytes(bytes) {
|
|
|
12848
12608
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
12849
12609
|
}
|
|
12850
12610
|
function formatArchiverTool(name, input) {
|
|
12851
|
-
const params = Object.entries(input).map(([key,
|
|
12852
|
-
const rendered = typeof
|
|
12611
|
+
const params = Object.entries(input).map(([key, value]) => {
|
|
12612
|
+
const rendered = typeof value === "string" ? value : JSON.stringify(value);
|
|
12853
12613
|
return `${key}: ${summarizeDisplayText(sessionText(rendered ?? ""))}`;
|
|
12854
12614
|
}).join(", ");
|
|
12855
12615
|
return summarizeDisplayText(`${name}${params ? `(${params})` : ""}`);
|
|
@@ -13253,13 +13013,13 @@ function countMemoryArchiveExchanges(rows) {
|
|
|
13253
13013
|
var MIN_MEMORY_ARCHIVE_EXCHANGES = 6;
|
|
13254
13014
|
|
|
13255
13015
|
// ../../packages/core/src/storage/topic-transcript.ts
|
|
13256
|
-
function parseJsonField(
|
|
13257
|
-
if (!
|
|
13016
|
+
function parseJsonField(value) {
|
|
13017
|
+
if (!value)
|
|
13258
13018
|
return;
|
|
13259
13019
|
try {
|
|
13260
|
-
return JSON.parse(
|
|
13020
|
+
return JSON.parse(value);
|
|
13261
13021
|
} catch {
|
|
13262
|
-
return
|
|
13022
|
+
return value;
|
|
13263
13023
|
}
|
|
13264
13024
|
}
|
|
13265
13025
|
function transcriptRole(row) {
|
|
@@ -13520,8 +13280,8 @@ function settleTopicArchiveJob(topicId, archivePath, success) {
|
|
|
13520
13280
|
db.query("UPDATE api_topic_archive_jobs SET status = 'pending', updated_at = ? WHERE topic_id = ? AND archive_path = ?").run(new Date().toISOString(), topicId, archivePath);
|
|
13521
13281
|
return;
|
|
13522
13282
|
}
|
|
13523
|
-
const
|
|
13524
|
-
setTopicArchiveState(topicId, Math.max(
|
|
13283
|
+
const current = getTopicArchiveState(topicId)?.lastArchivedRowid ?? 0;
|
|
13284
|
+
setTopicArchiveState(topicId, Math.max(current, job.last_rowid), job.archive_path);
|
|
13525
13285
|
db.query("DELETE FROM api_topic_archive_jobs WHERE topic_id = ? AND archive_path = ?").run(topicId, archivePath);
|
|
13526
13286
|
})();
|
|
13527
13287
|
}
|
|
@@ -13575,8 +13335,8 @@ function envFlagEnabled(name, fallback) {
|
|
|
13575
13335
|
return !["0", "false", "off", "no"].includes(raw);
|
|
13576
13336
|
}
|
|
13577
13337
|
function envPositiveInt(name, fallback) {
|
|
13578
|
-
const
|
|
13579
|
-
return Number.isFinite(
|
|
13338
|
+
const value = Number.parseInt(process.env[name] ?? "", 10);
|
|
13339
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
13580
13340
|
}
|
|
13581
13341
|
function idleArchiveDelayMs() {
|
|
13582
13342
|
return envPositiveInt("NEGOTIUM_IDLE_ARCHIVE_DELAY_MS", DEFAULT_IDLE_DELAY_MS);
|
|
@@ -13772,10 +13532,10 @@ function estimateUsageCost(agent, model, usage) {
|
|
|
13772
13532
|
return 0;
|
|
13773
13533
|
return (usage.inputTokens * prices.input + usage.outputTokens * prices.output + (agent === "claude" ? usage.cacheCreationInputTokens * (prices.cacheWrite ?? prices.input) : 0) + usage.cacheReadInputTokens * prices.cacheRead) / 1e6;
|
|
13774
13534
|
}
|
|
13775
|
-
function isQueryRecord(
|
|
13776
|
-
if (!
|
|
13535
|
+
function isQueryRecord(value) {
|
|
13536
|
+
if (!value || typeof value !== "object")
|
|
13777
13537
|
return false;
|
|
13778
|
-
const record =
|
|
13538
|
+
const record = value;
|
|
13779
13539
|
return record.schemaVersion === 2 && typeof record.timestamp === "string" && typeof record.session === "string" && typeof record.topicId === "string" && typeof record.agent === "string" && typeof record.model === "string" && typeof record.inputTokens === "number" && typeof record.outputTokens === "number" && typeof record.cacheCreationInputTokens === "number" && typeof record.cacheReadInputTokens === "number" && typeof record.estimatedCostUsd === "number";
|
|
13780
13540
|
}
|
|
13781
13541
|
function previousCumulativeCost(userId, providerSessionId) {
|
|
@@ -13999,8 +13759,8 @@ function envFlagEnabled2(name, fallback) {
|
|
|
13999
13759
|
return !["0", "false", "off", "no"].includes(raw);
|
|
14000
13760
|
}
|
|
14001
13761
|
function envPositiveInt2(name, fallback) {
|
|
14002
|
-
const
|
|
14003
|
-
return Number.isFinite(
|
|
13762
|
+
const value = Number.parseInt(process.env[name] ?? "", 10);
|
|
13763
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
14004
13764
|
}
|
|
14005
13765
|
function idleCompactDelayMs() {
|
|
14006
13766
|
return envPositiveInt2("NEGOTIUM_IDLE_COMPACT_DELAY_MS", DEFAULT_IDLE_DELAY_MS2);
|
|
@@ -14098,7 +13858,7 @@ async function runIdleCompactForTopic(topicId, userId, options = {}) {
|
|
|
14098
13858
|
return "below-threshold";
|
|
14099
13859
|
}
|
|
14100
13860
|
const compact = options.compact ?? (async (id, actorId, reason) => {
|
|
14101
|
-
|
|
13861
|
+
await init_session();
|
|
14102
13862
|
return compactTopicSession(id, actorId, reason, { preemptive: false });
|
|
14103
13863
|
});
|
|
14104
13864
|
try {
|
|
@@ -14298,47 +14058,47 @@ function beginTransientBackgroundSession(userId, session) {
|
|
|
14298
14058
|
update(status, step) {
|
|
14299
14059
|
if (finished)
|
|
14300
14060
|
return;
|
|
14301
|
-
const
|
|
14302
|
-
if (
|
|
14061
|
+
const current = transientSessions.get(record.id);
|
|
14062
|
+
if (current !== record)
|
|
14303
14063
|
return;
|
|
14304
14064
|
const nextStatus = text(status, 160);
|
|
14305
14065
|
if (nextStatus)
|
|
14306
|
-
|
|
14066
|
+
current.status = nextStatus;
|
|
14307
14067
|
const nextStep = text(step);
|
|
14308
|
-
if (nextStep &&
|
|
14309
|
-
|
|
14068
|
+
if (nextStep && current.steps.at(-1) !== nextStep) {
|
|
14069
|
+
current.steps.push(nextStep);
|
|
14310
14070
|
}
|
|
14311
14071
|
},
|
|
14312
14072
|
setOutput(output) {
|
|
14313
14073
|
if (finished)
|
|
14314
14074
|
return;
|
|
14315
|
-
const
|
|
14316
|
-
if (
|
|
14075
|
+
const current = transientSessions.get(record.id);
|
|
14076
|
+
if (current !== record)
|
|
14317
14077
|
return;
|
|
14318
|
-
|
|
14078
|
+
current.output = output;
|
|
14319
14079
|
},
|
|
14320
14080
|
finish(status, step) {
|
|
14321
14081
|
if (finished)
|
|
14322
14082
|
return;
|
|
14323
14083
|
this.update(status ?? record.status, step);
|
|
14324
14084
|
finished = true;
|
|
14325
|
-
const
|
|
14326
|
-
if (
|
|
14085
|
+
const current = transientSessions.get(record.id);
|
|
14086
|
+
if (current !== record)
|
|
14327
14087
|
return;
|
|
14328
|
-
|
|
14329
|
-
|
|
14330
|
-
|
|
14088
|
+
current.active = false;
|
|
14089
|
+
current.expiresAt = Date.now() + Math.max(0, retentionMs);
|
|
14090
|
+
current.expiryTimer = setTimeout(() => {
|
|
14331
14091
|
if (transientSessions.get(record.id) === record)
|
|
14332
14092
|
transientSessions.delete(record.id);
|
|
14333
14093
|
}, Math.max(0, retentionMs));
|
|
14334
|
-
|
|
14094
|
+
current.expiryTimer.unref?.();
|
|
14335
14095
|
}
|
|
14336
14096
|
};
|
|
14337
14097
|
}
|
|
14338
|
-
function text(
|
|
14339
|
-
if (typeof
|
|
14098
|
+
function text(value, maxLen) {
|
|
14099
|
+
if (typeof value !== "string")
|
|
14340
14100
|
return "";
|
|
14341
|
-
const normalized =
|
|
14101
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
14342
14102
|
return maxLen === undefined ? normalized : normalized.slice(0, maxLen);
|
|
14343
14103
|
}
|
|
14344
14104
|
var providers2, transientSessions;
|
|
@@ -14369,36 +14129,10 @@ var init_usage_alert = __esm(() => {
|
|
|
14369
14129
|
});
|
|
14370
14130
|
|
|
14371
14131
|
// ../../packages/core/src/topics/session.ts
|
|
14372
|
-
var exports_session = {};
|
|
14373
|
-
__export(exports_session, {
|
|
14374
|
-
splitCompactionPairs: () => splitCompactionPairs,
|
|
14375
|
-
shouldUseCompactionLog: () => shouldUseCompactionLog,
|
|
14376
|
-
shouldCompactForkEntries: () => shouldCompactForkEntries,
|
|
14377
|
-
restartTopicSession: () => restartTopicSession,
|
|
14378
|
-
createCompactedRolloutEntries: () => createCompactedRolloutEntries,
|
|
14379
|
-
compactTopicSession: () => compactTopicSession,
|
|
14380
|
-
COMPACTION_RETAINED_TAIL_TOKENS: () => COMPACTION_RETAINED_TAIL_TOKENS,
|
|
14381
|
-
AUTO_FORK_COMPACTION_TOKENS: () => AUTO_FORK_COMPACTION_TOKENS
|
|
14382
|
-
});
|
|
14383
14132
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
14384
14133
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync4, writeFileSync as writeFileSync15 } from "fs";
|
|
14385
14134
|
import { tmpdir as tmpdir4 } from "os";
|
|
14386
14135
|
import { join as join26 } from "path";
|
|
14387
|
-
async function waitForMemoryArchive(settled, timeoutMs) {
|
|
14388
|
-
let timer;
|
|
14389
|
-
try {
|
|
14390
|
-
return await Promise.race([
|
|
14391
|
-
settled.then(() => true),
|
|
14392
|
-
new Promise((resolve17) => {
|
|
14393
|
-
timer = setTimeout(() => resolve17(false), timeoutMs);
|
|
14394
|
-
timer.unref?.();
|
|
14395
|
-
})
|
|
14396
|
-
]);
|
|
14397
|
-
} finally {
|
|
14398
|
-
if (timer)
|
|
14399
|
-
clearTimeout(timer);
|
|
14400
|
-
}
|
|
14401
|
-
}
|
|
14402
14136
|
async function fenceTopicWork(topicId, maintenance) {
|
|
14403
14137
|
for (const queryId of cancelRuntimeUserTurnRequestsBeforeEpoch(topicId, maintenance.epoch)) {
|
|
14404
14138
|
WsHub.get().broadcastAborted(topicId, queryId, "stopped");
|
|
@@ -14423,97 +14157,6 @@ function hasTopicWorkInFlight(topicId) {
|
|
|
14423
14157
|
function topicIsQuiescedForNonPreemptiveWork(topicId) {
|
|
14424
14158
|
return !hasTopicWorkInFlight(topicId);
|
|
14425
14159
|
}
|
|
14426
|
-
async function restartTopicSession(topicId, userId, reason = "topic-session-restart", options = {}) {
|
|
14427
|
-
const topic = getTopic(topicId);
|
|
14428
|
-
if (!topic)
|
|
14429
|
-
return { text: "Topic not found.", isError: true };
|
|
14430
|
-
if (isLegacySharedGeneral(topic.id)) {
|
|
14431
|
-
return { text: "The legacy shared General session cannot be reset.", isError: true };
|
|
14432
|
-
}
|
|
14433
|
-
const owner = topic.participants.some((participant) => participant.userId === userId && participant.role === "owner");
|
|
14434
|
-
if (!owner)
|
|
14435
|
-
return { text: "Only the topic owner can reset the session.", isError: true };
|
|
14436
|
-
const maintenance = beginRuntimeTopicMaintenance(topicId);
|
|
14437
|
-
if (!maintenance)
|
|
14438
|
-
return { text: "Topic maintenance is already in progress.", isError: true };
|
|
14439
|
-
try {
|
|
14440
|
-
const fenceError = await fenceTopicWork(topicId, maintenance);
|
|
14441
|
-
if (fenceError)
|
|
14442
|
-
return { text: fenceError, isError: true };
|
|
14443
|
-
cancelIdleArchiveForTopic(topicId);
|
|
14444
|
-
cancelIdleCompactForTopic(topicId);
|
|
14445
|
-
const rawArchivePaths = [];
|
|
14446
|
-
try {
|
|
14447
|
-
for (const participantUserId of new Set([
|
|
14448
|
-
userId,
|
|
14449
|
-
...topic.participants.map((participant) => participant.userId)
|
|
14450
|
-
])) {
|
|
14451
|
-
const archived = archiveConversationEvents(topicId, topic.title, participantUserId, {
|
|
14452
|
-
reason: "reset"
|
|
14453
|
-
});
|
|
14454
|
-
if (archived)
|
|
14455
|
-
rawArchivePaths.push(archived.path);
|
|
14456
|
-
}
|
|
14457
|
-
} catch (error) {
|
|
14458
|
-
return {
|
|
14459
|
-
text: `Session reset could not archive the raw conversation: ${error instanceof Error ? error.message : String(error)}`,
|
|
14460
|
-
isError: true
|
|
14461
|
-
};
|
|
14462
|
-
}
|
|
14463
|
-
let settleMemoryArchive;
|
|
14464
|
-
const memoryArchiveSettled = new Promise((resolve17) => {
|
|
14465
|
-
settleMemoryArchive = resolve17;
|
|
14466
|
-
});
|
|
14467
|
-
const archiveStatus = (options.archiveMemory ?? archiveActiveTopicForMemory)(topicId, options.memoryUserId ?? userId, {
|
|
14468
|
-
reason: "reset",
|
|
14469
|
-
minMessages: 1,
|
|
14470
|
-
minExchanges: MIN_MEMORY_ARCHIVE_EXCHANGES,
|
|
14471
|
-
allowMentionOnly: true,
|
|
14472
|
-
skipBusyCheck: true,
|
|
14473
|
-
rawArchivePaths,
|
|
14474
|
-
onSettled: () => settleMemoryArchive?.()
|
|
14475
|
-
});
|
|
14476
|
-
if (archiveStatus === "archived") {
|
|
14477
|
-
const archiveFinished = await waitForMemoryArchive(memoryArchiveSettled, options.memoryArchiveWaitMs ?? RESET_MEMORY_ARCHIVE_WAIT_MS);
|
|
14478
|
-
if (!archiveFinished) {
|
|
14479
|
-
return {
|
|
14480
|
-
text: "Memory archiving did not finish in time. The session was not reset.",
|
|
14481
|
-
isError: true
|
|
14482
|
-
};
|
|
14483
|
-
}
|
|
14484
|
-
}
|
|
14485
|
-
if (!maintenance.isOwned()) {
|
|
14486
|
-
return { text: "Topic maintenance ownership was lost. Try again.", isError: true };
|
|
14487
|
-
}
|
|
14488
|
-
const sessionId = getTopicSessionId(topicId);
|
|
14489
|
-
const purgeLogs = options.purgeLogs ?? purgeTopicLogs;
|
|
14490
|
-
const participantUserIds = Array.from(new Set([userId, ...topic.participants.map((participant) => participant.userId)]));
|
|
14491
|
-
for (const [index, participantUserId] of participantUserIds.entries()) {
|
|
14492
|
-
let purged = false;
|
|
14493
|
-
try {
|
|
14494
|
-
purged = await purgeLogs({
|
|
14495
|
-
userId: participantUserId,
|
|
14496
|
-
topicName: topic.title,
|
|
14497
|
-
cwd: resolveTopicWorkspaceDir(topicId),
|
|
14498
|
-
extraSessions: index === 0 && topic.agent && sessionId ? [{ agent: topic.agent, sessionId }] : []
|
|
14499
|
-
});
|
|
14500
|
-
} catch (error) {
|
|
14501
|
-
logger.warn({ err: error, topicId, userId: participantUserId }, "restartTopicSession: participant context cleanup failed");
|
|
14502
|
-
}
|
|
14503
|
-
if (!purged) {
|
|
14504
|
-
return {
|
|
14505
|
-
text: "Session reset could not remove all provider context. The current session was kept.",
|
|
14506
|
-
isError: true
|
|
14507
|
-
};
|
|
14508
|
-
}
|
|
14509
|
-
}
|
|
14510
|
-
clearTopicSessionId(topicId, reason);
|
|
14511
|
-
clearQueryUsageAlert(userId, topicId);
|
|
14512
|
-
return { text: `Session reset for "${topic.title}". The next message starts fresh.` };
|
|
14513
|
-
} finally {
|
|
14514
|
-
maintenance.finish();
|
|
14515
|
-
}
|
|
14516
|
-
}
|
|
14517
14160
|
function previousCompactedSummary(entries) {
|
|
14518
14161
|
for (let index = entries.length - 2;index >= 0; index -= 1) {
|
|
14519
14162
|
const request = entries[index]?.event;
|
|
@@ -14528,9 +14171,9 @@ The assistant response is the authoritative summary of all earlier context.` &&
|
|
|
14528
14171
|
function withoutCompactionSentinels(entries) {
|
|
14529
14172
|
const filtered = [];
|
|
14530
14173
|
for (let index = 0;index < entries.length; index++) {
|
|
14531
|
-
const
|
|
14174
|
+
const current = entries[index]?.event;
|
|
14532
14175
|
const next = entries[index + 1]?.event;
|
|
14533
|
-
if (
|
|
14176
|
+
if (current?.type === "user_message" && current.synthetic === "compaction" && next?.type === "result") {
|
|
14534
14177
|
index += 1;
|
|
14535
14178
|
continue;
|
|
14536
14179
|
}
|
|
@@ -14580,18 +14223,18 @@ function retainedPairEntries(agent, pairs) {
|
|
|
14580
14223
|
}
|
|
14581
14224
|
return entries;
|
|
14582
14225
|
}
|
|
14583
|
-
function fitCompactionChunk(
|
|
14584
|
-
if (
|
|
14585
|
-
return
|
|
14226
|
+
function fitCompactionChunk(text, limit) {
|
|
14227
|
+
if (text.length <= limit)
|
|
14228
|
+
return text;
|
|
14586
14229
|
const marker = `
|
|
14587
14230
|
[\u2026]
|
|
14588
14231
|
`;
|
|
14589
14232
|
if (limit <= marker.length)
|
|
14590
|
-
return
|
|
14233
|
+
return text.slice(0, limit);
|
|
14591
14234
|
const available = limit - marker.length;
|
|
14592
14235
|
const headChars = Math.ceil(available * 0.6);
|
|
14593
14236
|
const tailChars = available - headChars;
|
|
14594
|
-
return `${
|
|
14237
|
+
return `${text.slice(0, headChars)}${marker}${text.slice(-tailChars)}`;
|
|
14595
14238
|
}
|
|
14596
14239
|
function buildCompactionSource(topicId, userId, entries, visibleMessages, providerPairs) {
|
|
14597
14240
|
const sections = [];
|
|
@@ -14992,9 +14635,9 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
14992
14635
|
const compactionExecution = resolveCompactionExecution(agent, registry);
|
|
14993
14636
|
const cwd = resolveTopicWorkspaceDir(topicId);
|
|
14994
14637
|
const oldEntries = readConversation(userId, topic.title);
|
|
14995
|
-
let
|
|
14638
|
+
let compactEntries;
|
|
14996
14639
|
try {
|
|
14997
|
-
|
|
14640
|
+
compactEntries = await createCompactedRolloutEntries({
|
|
14998
14641
|
topicId,
|
|
14999
14642
|
topicTitle: topic.title,
|
|
15000
14643
|
userId,
|
|
@@ -15020,7 +14663,7 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
15020
14663
|
try {
|
|
15021
14664
|
replacement = getRegistryOperations(agent).writeRollout({
|
|
15022
14665
|
cwd,
|
|
15023
|
-
entries:
|
|
14666
|
+
entries: compactEntries,
|
|
15024
14667
|
model,
|
|
15025
14668
|
...effort ? { effort } : {}
|
|
15026
14669
|
});
|
|
@@ -15050,7 +14693,7 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
15050
14693
|
}
|
|
15051
14694
|
try {
|
|
15052
14695
|
replaceConversationStrict(userId, topic.title, [
|
|
15053
|
-
...
|
|
14696
|
+
...compactEntries,
|
|
15054
14697
|
...priorSessionEntries,
|
|
15055
14698
|
replacementSessionEntry
|
|
15056
14699
|
]);
|
|
@@ -15087,7 +14730,7 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
15087
14730
|
} else {
|
|
15088
14731
|
try {
|
|
15089
14732
|
replaceConversationStrict(userId, topic.title, [
|
|
15090
|
-
...
|
|
14733
|
+
...compactEntries,
|
|
15091
14734
|
replacementSessionEntry
|
|
15092
14735
|
]);
|
|
15093
14736
|
} catch (manifestError) {
|
|
@@ -15141,45 +14784,11 @@ var init_session = __esm(async () => {
|
|
|
15141
14784
|
});
|
|
15142
14785
|
|
|
15143
14786
|
// ../../packages/core/src/topics/derive.ts
|
|
15144
|
-
var exports_derive = {};
|
|
15145
|
-
__export(exports_derive, {
|
|
15146
|
-
updateTopic: () => updateTopic,
|
|
15147
|
-
isParticipant: () => isParticipant,
|
|
15148
|
-
getVisibleTopics: () => getVisibleTopics,
|
|
15149
|
-
getTopics: () => getTopics,
|
|
15150
|
-
createDerivedTopic: () => createDerivedTopic,
|
|
15151
|
-
TopicTitleConflictError: () => TopicTitleConflictError,
|
|
15152
|
-
TopicForkCompactionError: () => TopicForkCompactionError,
|
|
15153
|
-
TopicDeriveBusyError: () => TopicDeriveBusyError
|
|
15154
|
-
});
|
|
15155
14787
|
import { createHash as createHash8, randomUUID as randomUUID12 } from "crypto";
|
|
15156
14788
|
import { mkdirSync as mkdirSync17, rmSync as rmSync5, unlinkSync as unlinkSync15 } from "fs";
|
|
15157
14789
|
function getTopics(opts = {}) {
|
|
15158
14790
|
return listTopics(opts).filter((topic) => !isLegacySharedGeneral(topic.id));
|
|
15159
14791
|
}
|
|
15160
|
-
function getVisibleTopics(opts = {}) {
|
|
15161
|
-
return getTopics(opts).filter(isTopicVisible).map((topic) => {
|
|
15162
|
-
if (!topic.agent)
|
|
15163
|
-
return topic;
|
|
15164
|
-
const registry = getRegistry(topic.agent);
|
|
15165
|
-
const config = getApiTopicConfig(topic.id);
|
|
15166
|
-
const requestedEffort = config?.effort ?? topic.defaultEffort;
|
|
15167
|
-
return {
|
|
15168
|
-
...topic,
|
|
15169
|
-
effectiveModel: resolveModelForAgent(topic.agent, config?.model ?? topic.defaultModel, registry),
|
|
15170
|
-
effectiveEffort: requestedEffort && registry.validateEffort(requestedEffort) ? requestedEffort : registry.defaultEffort
|
|
15171
|
-
};
|
|
15172
|
-
});
|
|
15173
|
-
}
|
|
15174
|
-
function updateTopic(topicId, patch) {
|
|
15175
|
-
const topic = getTopic(topicId);
|
|
15176
|
-
if (!topic)
|
|
15177
|
-
return false;
|
|
15178
|
-
Object.assign(topic, patch);
|
|
15179
|
-
upsertTopic(topic);
|
|
15180
|
-
WsHub.get().broadcastTopicUpdated(topicId);
|
|
15181
|
-
return true;
|
|
15182
|
-
}
|
|
15183
14792
|
function isParticipant(topic, userId) {
|
|
15184
14793
|
return topic.participants.some((p) => p.userId === userId);
|
|
15185
14794
|
}
|
|
@@ -15608,13 +15217,13 @@ var init_session_inbox_cleanup = __esm(async () => {
|
|
|
15608
15217
|
});
|
|
15609
15218
|
|
|
15610
15219
|
// ../../packages/core/src/mcp/session-comm/hub-remote-session.ts
|
|
15611
|
-
function isPlainRecord(
|
|
15612
|
-
return Boolean(
|
|
15220
|
+
function isPlainRecord(value) {
|
|
15221
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
15613
15222
|
}
|
|
15614
|
-
function parseListedRoom(
|
|
15615
|
-
if (!isPlainRecord(
|
|
15223
|
+
function parseListedRoom(value, mode) {
|
|
15224
|
+
if (!isPlainRecord(value))
|
|
15616
15225
|
return null;
|
|
15617
|
-
const { name, agent, status, description, role } =
|
|
15226
|
+
const { name, agent, status, description, role } = value;
|
|
15618
15227
|
if (typeof name !== "string" || !name.trim())
|
|
15619
15228
|
return null;
|
|
15620
15229
|
if (agent !== undefined && agent !== null && typeof agent !== "string")
|
|
@@ -15638,10 +15247,10 @@ function parseListedRoom(value2, mode) {
|
|
|
15638
15247
|
...role !== undefined ? { role } : {}
|
|
15639
15248
|
};
|
|
15640
15249
|
}
|
|
15641
|
-
function parseNodeListing(
|
|
15642
|
-
if (!isPlainRecord(
|
|
15250
|
+
function parseNodeListing(value, mode) {
|
|
15251
|
+
if (!isPlainRecord(value))
|
|
15643
15252
|
return null;
|
|
15644
|
-
const { node, sessions, error } =
|
|
15253
|
+
const { node, sessions, error } = value;
|
|
15645
15254
|
if (typeof node !== "string" || !node.trim() || node.includes("/"))
|
|
15646
15255
|
return null;
|
|
15647
15256
|
if (error !== undefined && (typeof error !== "string" || !error.trim()))
|
|
@@ -15661,11 +15270,11 @@ function parseNodeListing(value2, mode) {
|
|
|
15661
15270
|
}
|
|
15662
15271
|
return { node, sessions: parsed };
|
|
15663
15272
|
}
|
|
15664
|
-
function parseNodeListings(
|
|
15665
|
-
if (!Array.isArray(
|
|
15273
|
+
function parseNodeListings(value, mode) {
|
|
15274
|
+
if (!Array.isArray(value))
|
|
15666
15275
|
return null;
|
|
15667
15276
|
const listings = [];
|
|
15668
|
-
for (const entry of
|
|
15277
|
+
for (const entry of value) {
|
|
15669
15278
|
const listing = parseNodeListing(entry, mode);
|
|
15670
15279
|
if (!listing)
|
|
15671
15280
|
return null;
|
|
@@ -15673,11 +15282,11 @@ function parseNodeListings(value2, mode) {
|
|
|
15673
15282
|
}
|
|
15674
15283
|
return listings;
|
|
15675
15284
|
}
|
|
15676
|
-
function parsePendingAsks(
|
|
15677
|
-
if (!Array.isArray(
|
|
15285
|
+
function parsePendingAsks(value) {
|
|
15286
|
+
if (!Array.isArray(value))
|
|
15678
15287
|
return null;
|
|
15679
15288
|
const asks = [];
|
|
15680
|
-
for (const entry of
|
|
15289
|
+
for (const entry of value) {
|
|
15681
15290
|
if (!isPlainRecord(entry))
|
|
15682
15291
|
return null;
|
|
15683
15292
|
const { to, requestId, status } = entry;
|
|
@@ -15719,9 +15328,9 @@ function hubHeaders(bearer) {
|
|
|
15719
15328
|
};
|
|
15720
15329
|
}
|
|
15721
15330
|
function errorText(status, body, fallback) {
|
|
15722
|
-
const
|
|
15723
|
-
if (typeof
|
|
15724
|
-
return
|
|
15331
|
+
const text = body?.error;
|
|
15332
|
+
if (typeof text === "string" && text.trim())
|
|
15333
|
+
return text.trim();
|
|
15725
15334
|
return `${fallback} (hub answered ${status})`;
|
|
15726
15335
|
}
|
|
15727
15336
|
function describeFailure(status, body) {
|
|
@@ -15817,19 +15426,6 @@ var init_actor_policy = __esm(async () => {
|
|
|
15817
15426
|
await init_actor_topic_reach();
|
|
15818
15427
|
});
|
|
15819
15428
|
// ../../packages/core/src/storage/session-asks.ts
|
|
15820
|
-
var exports_session_asks = {};
|
|
15821
|
-
__export(exports_session_asks, {
|
|
15822
|
-
releasePendingAsk: () => releasePendingAsk,
|
|
15823
|
-
markPendingAskState: () => markPendingAskState,
|
|
15824
|
-
markPendingAskSources: () => markPendingAskSources,
|
|
15825
|
-
listPendingAsksForCaller: () => listPendingAsksForCaller,
|
|
15826
|
-
describePendingAskState: () => describePendingAskState,
|
|
15827
|
-
deletePendingAsksForTopic: () => deletePendingAsksForTopic,
|
|
15828
|
-
createPendingAsk: () => createPendingAsk,
|
|
15829
|
-
clearPendingAskSources: () => clearPendingAskSources,
|
|
15830
|
-
clearPendingAsk: () => clearPendingAsk,
|
|
15831
|
-
PENDING_ASK_TTL_MS: () => PENDING_ASK_TTL_MS
|
|
15832
|
-
});
|
|
15833
15429
|
import { createHash as createHash9 } from "crypto";
|
|
15834
15430
|
import {
|
|
15835
15431
|
closeSync as closeSync3,
|
|
@@ -15851,8 +15447,8 @@ function encodeAskKey(key) {
|
|
|
15851
15447
|
return JSON.stringify([key.from, key.to]);
|
|
15852
15448
|
}
|
|
15853
15449
|
function pendingAskPath(key) {
|
|
15854
|
-
const
|
|
15855
|
-
return join30(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${
|
|
15450
|
+
const digest = createHash9("sha256").update(encodeAskKey(key)).digest("hex");
|
|
15451
|
+
return join30(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest}.pending`);
|
|
15856
15452
|
}
|
|
15857
15453
|
function v2PendingAskPath(key) {
|
|
15858
15454
|
const encoded = Buffer.from(encodeAskKey(key), "utf8").toString("base64url");
|
|
@@ -15878,10 +15474,10 @@ function parsePendingAskFilename(fileName) {
|
|
|
15878
15474
|
}
|
|
15879
15475
|
} catch {}
|
|
15880
15476
|
}
|
|
15881
|
-
const
|
|
15882
|
-
if (
|
|
15477
|
+
const sep = raw.indexOf("___");
|
|
15478
|
+
if (sep < 0)
|
|
15883
15479
|
return null;
|
|
15884
|
-
return { from: raw.slice(0,
|
|
15480
|
+
return { from: raw.slice(0, sep), to: raw.slice(sep + 3) };
|
|
15885
15481
|
}
|
|
15886
15482
|
function readPendingAskFile(path, fallback) {
|
|
15887
15483
|
try {
|
|
@@ -15924,16 +15520,6 @@ function readPendingAskFile(path, fallback) {
|
|
|
15924
15520
|
return null;
|
|
15925
15521
|
}
|
|
15926
15522
|
}
|
|
15927
|
-
function isStale(record, path) {
|
|
15928
|
-
const ts = record ? Date.parse(record.updatedAt || record.createdAt) : Number.NaN;
|
|
15929
|
-
if (Number.isFinite(ts))
|
|
15930
|
-
return Date.now() - ts > PENDING_ASK_TTL_MS;
|
|
15931
|
-
try {
|
|
15932
|
-
return Date.now() - statSync8(path).mtimeMs > PENDING_ASK_TTL_MS;
|
|
15933
|
-
} catch {
|
|
15934
|
-
return false;
|
|
15935
|
-
}
|
|
15936
|
-
}
|
|
15937
15523
|
function writePendingAsk(record) {
|
|
15938
15524
|
const path = pendingAskPath(record);
|
|
15939
15525
|
mkdirSync18(pendingAskDir(record.userId), { recursive: true });
|
|
@@ -15959,10 +15545,10 @@ function writePendingAskIfAbsent(record) {
|
|
|
15959
15545
|
}
|
|
15960
15546
|
}
|
|
15961
15547
|
function readPendingAsk(key) {
|
|
15962
|
-
const
|
|
15963
|
-
const canonical = readPendingAskFile(
|
|
15548
|
+
const canonicalPath = pendingAskPath(key);
|
|
15549
|
+
const canonical = readPendingAskFile(canonicalPath, key);
|
|
15964
15550
|
if (canonical && canonical.from === key.from && canonical.to === key.to) {
|
|
15965
|
-
return { path:
|
|
15551
|
+
return { path: canonicalPath, record: canonical };
|
|
15966
15552
|
}
|
|
15967
15553
|
for (const compatibilityPath of [v2PendingAskPath(key), legacyPendingAskPath(key)]) {
|
|
15968
15554
|
if (!compatibilityPath)
|
|
@@ -15971,67 +15557,17 @@ function readPendingAsk(key) {
|
|
|
15971
15557
|
if (!legacy || legacy.from !== key.from || legacy.to !== key.to)
|
|
15972
15558
|
continue;
|
|
15973
15559
|
const migrated = writePendingAskIfAbsent(legacy);
|
|
15974
|
-
const next = migrated ? legacy : readPendingAskFile(
|
|
15560
|
+
const next = migrated ? legacy : readPendingAskFile(canonicalPath, key);
|
|
15975
15561
|
if (next && next.from === key.from && next.to === key.to) {
|
|
15976
15562
|
try {
|
|
15977
15563
|
unlinkSync17(compatibilityPath);
|
|
15978
15564
|
} catch {}
|
|
15979
|
-
return { path:
|
|
15565
|
+
return { path: canonicalPath, record: next };
|
|
15980
15566
|
}
|
|
15981
15567
|
return { path: compatibilityPath, record: legacy };
|
|
15982
15568
|
}
|
|
15983
15569
|
return null;
|
|
15984
15570
|
}
|
|
15985
|
-
function createPendingAsk(args) {
|
|
15986
|
-
const migrated = readPendingAsk(args);
|
|
15987
|
-
if (migrated && !isStale(migrated.record, migrated.path)) {
|
|
15988
|
-
return { ok: false, existing: migrated.record, stale: false };
|
|
15989
|
-
}
|
|
15990
|
-
if (migrated) {
|
|
15991
|
-
try {
|
|
15992
|
-
unlinkSync17(migrated.path);
|
|
15993
|
-
} catch {
|
|
15994
|
-
return { ok: false, existing: migrated.record, stale: true };
|
|
15995
|
-
}
|
|
15996
|
-
}
|
|
15997
|
-
const path = pendingAskPath(args);
|
|
15998
|
-
const now = new Date().toISOString();
|
|
15999
|
-
const record = {
|
|
16000
|
-
userId: args.userId,
|
|
16001
|
-
from: args.from,
|
|
16002
|
-
to: args.to,
|
|
16003
|
-
requestId: args.requestId,
|
|
16004
|
-
contextId: args.contextId,
|
|
16005
|
-
state: "requested",
|
|
16006
|
-
createdAt: now,
|
|
16007
|
-
updatedAt: now
|
|
16008
|
-
};
|
|
16009
|
-
mkdirSync18(pendingAskDir(args.userId), { recursive: true });
|
|
16010
|
-
for (let attempt = 0;attempt < 2; attempt++) {
|
|
16011
|
-
let fd = null;
|
|
16012
|
-
try {
|
|
16013
|
-
fd = openSync3(path, "wx");
|
|
16014
|
-
writeFileSync16(fd, `${JSON.stringify(record)}
|
|
16015
|
-
`);
|
|
16016
|
-
return { ok: true, record };
|
|
16017
|
-
} catch (err) {
|
|
16018
|
-
if (err.code !== "EEXIST")
|
|
16019
|
-
throw err;
|
|
16020
|
-
const existing = readPendingAskFile(path, args);
|
|
16021
|
-
if (!isStale(existing, path))
|
|
16022
|
-
return { ok: false, existing, stale: false };
|
|
16023
|
-
try {
|
|
16024
|
-
unlinkSync17(path);
|
|
16025
|
-
} catch {
|
|
16026
|
-
return { ok: false, existing, stale: true };
|
|
16027
|
-
}
|
|
16028
|
-
} finally {
|
|
16029
|
-
if (fd !== null)
|
|
16030
|
-
closeSync3(fd);
|
|
16031
|
-
}
|
|
16032
|
-
}
|
|
16033
|
-
return { ok: false, existing: readPendingAskFile(path, args), stale: true };
|
|
16034
|
-
}
|
|
16035
15571
|
function markPendingAskState(args) {
|
|
16036
15572
|
const pending = readPendingAsk(args);
|
|
16037
15573
|
if (!pending)
|
|
@@ -16065,83 +15601,6 @@ function clearPendingAsk(args) {
|
|
|
16065
15601
|
return false;
|
|
16066
15602
|
}
|
|
16067
15603
|
}
|
|
16068
|
-
function releasePendingAsk(args) {
|
|
16069
|
-
if (clearPendingAsk(args))
|
|
16070
|
-
return true;
|
|
16071
|
-
const still = readPendingAsk(args);
|
|
16072
|
-
return !still || still.record.requestId !== args.requestId;
|
|
16073
|
-
}
|
|
16074
|
-
function markPendingAskSources(args) {
|
|
16075
|
-
for (const source of args.sources ?? []) {
|
|
16076
|
-
if (!source.from)
|
|
16077
|
-
continue;
|
|
16078
|
-
markPendingAskState({
|
|
16079
|
-
userId: args.userId,
|
|
16080
|
-
from: args.callerTopic,
|
|
16081
|
-
to: source.from,
|
|
16082
|
-
requestId: source.requestId,
|
|
16083
|
-
state: args.state
|
|
16084
|
-
});
|
|
16085
|
-
}
|
|
16086
|
-
}
|
|
16087
|
-
function clearPendingAskSources(args) {
|
|
16088
|
-
for (const source of args.sources ?? []) {
|
|
16089
|
-
if (!source.from)
|
|
16090
|
-
continue;
|
|
16091
|
-
clearPendingAsk({
|
|
16092
|
-
userId: args.userId,
|
|
16093
|
-
from: args.callerTopic,
|
|
16094
|
-
to: source.from,
|
|
16095
|
-
requestId: source.requestId
|
|
16096
|
-
});
|
|
16097
|
-
}
|
|
16098
|
-
}
|
|
16099
|
-
function listPendingAsksForCaller(args) {
|
|
16100
|
-
const dir = pendingAskDir(args.userId);
|
|
16101
|
-
let files;
|
|
16102
|
-
try {
|
|
16103
|
-
files = readdirSync6(dir);
|
|
16104
|
-
} catch {
|
|
16105
|
-
return [];
|
|
16106
|
-
}
|
|
16107
|
-
const records = new Map;
|
|
16108
|
-
for (const fileName of files) {
|
|
16109
|
-
const isV3 = fileName.startsWith(ASK_FILENAME_PREFIX);
|
|
16110
|
-
const parsed = isV3 ? { from: args.from, to: "" } : parsePendingAskFilename(fileName);
|
|
16111
|
-
if (!parsed)
|
|
16112
|
-
continue;
|
|
16113
|
-
const path = join30(dir, fileName);
|
|
16114
|
-
const record = readPendingAskFile(path, {
|
|
16115
|
-
userId: args.userId,
|
|
16116
|
-
from: parsed.from,
|
|
16117
|
-
to: parsed.to
|
|
16118
|
-
});
|
|
16119
|
-
if (!record || record.from !== args.from)
|
|
16120
|
-
continue;
|
|
16121
|
-
if (isStale(record, path)) {
|
|
16122
|
-
try {
|
|
16123
|
-
unlinkSync17(path);
|
|
16124
|
-
} catch {}
|
|
16125
|
-
continue;
|
|
16126
|
-
}
|
|
16127
|
-
const canonical = readPendingAsk(record);
|
|
16128
|
-
if (!canonical || canonical.record.from !== args.from)
|
|
16129
|
-
continue;
|
|
16130
|
-
if (path !== canonical.path) {
|
|
16131
|
-
try {
|
|
16132
|
-
unlinkSync17(path);
|
|
16133
|
-
} catch {}
|
|
16134
|
-
}
|
|
16135
|
-
if (isStale(canonical.record, canonical.path)) {
|
|
16136
|
-
try {
|
|
16137
|
-
unlinkSync17(canonical.path);
|
|
16138
|
-
} catch {}
|
|
16139
|
-
continue;
|
|
16140
|
-
}
|
|
16141
|
-
records.set(encodeAskKey(canonical.record), canonical.record);
|
|
16142
|
-
}
|
|
16143
|
-
return [...records.values()];
|
|
16144
|
-
}
|
|
16145
15604
|
function deletePendingAsksForTopic(args) {
|
|
16146
15605
|
const dir = pendingAskDir(args.userId);
|
|
16147
15606
|
let files;
|
|
@@ -16170,18 +15629,6 @@ function deletePendingAsksForTopic(args) {
|
|
|
16170
15629
|
}
|
|
16171
15630
|
return deleted;
|
|
16172
15631
|
}
|
|
16173
|
-
function describePendingAskState(state) {
|
|
16174
|
-
switch (state) {
|
|
16175
|
-
case "requested":
|
|
16176
|
-
return "\uB300\uC0C1 \uC138\uC158 \uCC98\uB9AC \uC911";
|
|
16177
|
-
case "reply_ready":
|
|
16178
|
-
return "\uC751\uB2F5 \uC0DD\uC131 \uC644\uB8CC, \uC774 \uC138\uC158 \uC8FC\uC785 \uC900\uBE44 \uC911";
|
|
16179
|
-
case "queued_for_caller":
|
|
16180
|
-
return "\uC751\uB2F5 \uC0DD\uC131 \uC644\uB8CC, \uC774 \uC138\uC158 \uC2E4\uD589 \uC885\uB8CC \uD6C4 \uC8FC\uC785 \uB300\uAE30 \uC911";
|
|
16181
|
-
case "injecting_to_caller":
|
|
16182
|
-
return "\uC751\uB2F5\uC744 \uC774 \uC138\uC158\uC5D0 \uC8FC\uC785 \uC911";
|
|
16183
|
-
}
|
|
16184
|
-
}
|
|
16185
15632
|
var PENDING_ASK_TTL_MS, ASK_FILENAME_PREFIX = "v3-", V2_ASK_FILENAME_PREFIX = "v2-";
|
|
16186
15633
|
var init_session_asks = __esm(async () => {
|
|
16187
15634
|
await init_storage_host();
|
|
@@ -16283,10 +15730,10 @@ function deferRemoteSessionReplyOutbox(args) {
|
|
|
16283
15730
|
if (!row)
|
|
16284
15731
|
return;
|
|
16285
15732
|
const attempts = Number(row.attempts) + 1;
|
|
16286
|
-
const
|
|
15733
|
+
const delay = args.retryMs ?? remoteSessionRetryDelayMs(attempts, args.random);
|
|
16287
15734
|
db.query(`UPDATE remote_session_reply_outbox
|
|
16288
15735
|
SET attempts = ?, next_attempt_at = ?, last_error = ?
|
|
16289
|
-
WHERE request_id = ?`).run(attempts, now +
|
|
15736
|
+
WHERE request_id = ?`).run(attempts, now + delay, args.error.slice(0, 500), args.requestId);
|
|
16290
15737
|
})();
|
|
16291
15738
|
}
|
|
16292
15739
|
function purgeExpiredRemoteSessionReplyOutbox(now = Date.now()) {
|
|
@@ -16457,37 +15904,9 @@ var init_remote_session_reply_outbox = __esm(async () => {
|
|
|
16457
15904
|
});
|
|
16458
15905
|
|
|
16459
15906
|
// ../../packages/core/src/mcp/session-comm/peer-forward.ts
|
|
16460
|
-
var exports_peer_forward = {};
|
|
16461
|
-
__export(exports_peer_forward, {
|
|
16462
|
-
registerPeerSessionBridge: () => registerPeerSessionBridge,
|
|
16463
|
-
peerSessionsForUser: () => peerSessionsForUser,
|
|
16464
|
-
parseHubRemoteReplyRoute: () => parseHubRemoteReplyRoute,
|
|
16465
|
-
isHubRemoteReplyRoute: () => isHubRemoteReplyRoute,
|
|
16466
|
-
forwardToPeer: () => forwardToPeer,
|
|
16467
|
-
deliverPeerReply: () => deliverPeerReply
|
|
16468
|
-
});
|
|
16469
15907
|
function isHubRemoteReplyRoute(route) {
|
|
16470
15908
|
return route.via === "hub";
|
|
16471
15909
|
}
|
|
16472
|
-
function parseHubRemoteReplyRoute(value2) {
|
|
16473
|
-
if (!value2 || typeof value2 !== "object" || Array.isArray(value2))
|
|
16474
|
-
return null;
|
|
16475
|
-
const route = value2;
|
|
16476
|
-
if (route.via !== "hub" || typeof route.hubUrl !== "string" || typeof route.token !== "string" || typeof route.nodeName !== "string" || typeof route.topicId !== "string" || typeof route.requestId !== "string") {
|
|
16477
|
-
return null;
|
|
16478
|
-
}
|
|
16479
|
-
const requestId = route.requestId.trim();
|
|
16480
|
-
const nodeName = route.nodeName.trim();
|
|
16481
|
-
const topicId = route.topicId.trim();
|
|
16482
|
-
const token = route.token.trim();
|
|
16483
|
-
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)) {
|
|
16484
|
-
return null;
|
|
16485
|
-
}
|
|
16486
|
-
const hubUrl = normalizeHubUrl(route.hubUrl.trim(), "remoteReply.hubUrl");
|
|
16487
|
-
if ("error" in hubUrl)
|
|
16488
|
-
return null;
|
|
16489
|
-
return { via: "hub", hubUrl: hubUrl.url, token, nodeName, topicId, requestId };
|
|
16490
|
-
}
|
|
16491
15910
|
function loopbackBridgeConfig() {
|
|
16492
15911
|
const rawUrl = process.env[PEER_BRIDGE_URL_ENV]?.trim();
|
|
16493
15912
|
const token = process.env[PEER_BRIDGE_TOKEN_ENV]?.trim();
|
|
@@ -16524,39 +15943,6 @@ async function callLoopbackBridge(request) {
|
|
|
16524
15943
|
return { configured: true, result: null };
|
|
16525
15944
|
}
|
|
16526
15945
|
}
|
|
16527
|
-
function registerPeerSessionBridge(bridge) {
|
|
16528
|
-
activeBridge = bridge;
|
|
16529
|
-
return () => {
|
|
16530
|
-
if (activeBridge === bridge)
|
|
16531
|
-
activeBridge = null;
|
|
16532
|
-
};
|
|
16533
|
-
}
|
|
16534
|
-
async function forwardToPeer(args) {
|
|
16535
|
-
if (activeBridge)
|
|
16536
|
-
return activeBridge.forward(args);
|
|
16537
|
-
const forwarded = await callLoopbackBridge({ action: "forward", args });
|
|
16538
|
-
if (forwarded.result)
|
|
16539
|
-
return forwarded.result;
|
|
16540
|
-
return {
|
|
16541
|
-
ok: false,
|
|
16542
|
-
error: forwarded.configured ? "remote session bridge is configured but unavailable" : "remote nodes are not connected on this negotium node (standalone mode)"
|
|
16543
|
-
};
|
|
16544
|
-
}
|
|
16545
|
-
async function peerSessionsForUser(userId, sourceQueryId, fromTopicId) {
|
|
16546
|
-
if (activeBridge)
|
|
16547
|
-
return activeBridge.sessions(userId, sourceQueryId, fromTopicId);
|
|
16548
|
-
const sessions = await callLoopbackBridge({
|
|
16549
|
-
action: "sessions",
|
|
16550
|
-
userId,
|
|
16551
|
-
sourceQueryId,
|
|
16552
|
-
fromTopicId
|
|
16553
|
-
});
|
|
16554
|
-
if (sessions.result)
|
|
16555
|
-
return sessions.result;
|
|
16556
|
-
if (sessions.configured)
|
|
16557
|
-
return { ok: false, nodes: [] };
|
|
16558
|
-
return { ok: true, nodes: [] };
|
|
16559
|
-
}
|
|
16560
15946
|
async function deliverPeerReply(route, sourceTitle, replyText, kind) {
|
|
16561
15947
|
if (isHubRemoteReplyRoute(route)) {
|
|
16562
15948
|
return deliverHubRemoteReply(route, sourceTitle, replyText, kind);
|
|
@@ -16571,40 +15957,13 @@ async function deliverPeerReply(route, sourceTitle, replyText, kind) {
|
|
|
16571
15957
|
kind
|
|
16572
15958
|
})).result ?? false;
|
|
16573
15959
|
}
|
|
16574
|
-
var
|
|
15960
|
+
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;
|
|
16575
15961
|
var init_peer_forward = __esm(async () => {
|
|
16576
15962
|
init_remote_session_grant();
|
|
16577
15963
|
await init_remote_session_reply_outbox();
|
|
16578
15964
|
});
|
|
16579
15965
|
|
|
16580
15966
|
// ../../packages/core/src/runtime/ask-callbacks.ts
|
|
16581
|
-
var exports_ask_callbacks = {};
|
|
16582
|
-
__export(exports_ask_callbacks, {
|
|
16583
|
-
resolveAskCallback: () => resolveAskCallback,
|
|
16584
|
-
registerAskCallback: () => registerAskCallback,
|
|
16585
|
-
purgeStaleAsks: () => purgeStaleAsks,
|
|
16586
|
-
failInterruptedRemoteAskCallbacks: () => failInterruptedRemoteAskCallbacks,
|
|
16587
|
-
deleteHubRemoteAskCallbackRow: () => deleteHubRemoteAskCallbackRow,
|
|
16588
|
-
cancelAskCallbacksForTopic: () => cancelAskCallbacksForTopic
|
|
16589
|
-
});
|
|
16590
|
-
function registerAskCallback(entry) {
|
|
16591
|
-
pendingAsks.set(entry.targetQueryId, entry);
|
|
16592
|
-
if (entry.remoteReply) {
|
|
16593
|
-
const route = entry.remoteReply;
|
|
16594
|
-
const hub = isHubRemoteReplyRoute(route);
|
|
16595
|
-
db.query(`INSERT INTO remote_ask_callbacks
|
|
16596
|
-
(target_query_id, request_id, node_name, node_cell_id, topic_id, user_id, created_at, route_json)
|
|
16597
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
16598
|
-
ON CONFLICT(target_query_id) DO UPDATE SET
|
|
16599
|
-
request_id = excluded.request_id,
|
|
16600
|
-
node_name = excluded.node_name,
|
|
16601
|
-
node_cell_id = excluded.node_cell_id,
|
|
16602
|
-
topic_id = excluded.topic_id,
|
|
16603
|
-
user_id = excluded.user_id,
|
|
16604
|
-
created_at = excluded.created_at,
|
|
16605
|
-
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);
|
|
16606
|
-
}
|
|
16607
|
-
}
|
|
16608
15967
|
function resolveAskCallback(queryId) {
|
|
16609
15968
|
const entry = pendingAsks.get(queryId);
|
|
16610
15969
|
if (!entry)
|
|
@@ -16621,13 +15980,6 @@ function resolveAskCallback(queryId) {
|
|
|
16621
15980
|
function deleteHubRemoteAskCallbackRow(requestId) {
|
|
16622
15981
|
db.query("DELETE FROM remote_ask_callbacks WHERE request_id = ? AND route_json IS NOT NULL").run(requestId);
|
|
16623
15982
|
}
|
|
16624
|
-
function purgeStaleAsks(now = Date.now()) {
|
|
16625
|
-
for (const [id, entry] of pendingAsks) {
|
|
16626
|
-
if (now - entry.createdAt > MAX_ASK_AGE_MS)
|
|
16627
|
-
pendingAsks.delete(id);
|
|
16628
|
-
}
|
|
16629
|
-
db.query("DELETE FROM remote_ask_callbacks WHERE created_at < ?").run(now - MAX_ASK_AGE_MS);
|
|
16630
|
-
}
|
|
16631
15983
|
function cancelAskCallbacksForTopic(topicId) {
|
|
16632
15984
|
let cancelled = 0;
|
|
16633
15985
|
for (const [queryId, entry] of pendingAsks) {
|
|
@@ -16639,43 +15991,6 @@ function cancelAskCallbacksForTopic(topicId) {
|
|
|
16639
15991
|
}
|
|
16640
15992
|
return cancelled;
|
|
16641
15993
|
}
|
|
16642
|
-
function durableRoute(row) {
|
|
16643
|
-
if (row.route_json) {
|
|
16644
|
-
try {
|
|
16645
|
-
return parseHubRemoteReplyRoute(JSON.parse(row.route_json));
|
|
16646
|
-
} catch {
|
|
16647
|
-
return null;
|
|
16648
|
-
}
|
|
16649
|
-
}
|
|
16650
|
-
return {
|
|
16651
|
-
nodeName: row.node_name,
|
|
16652
|
-
nodeCellId: row.node_cell_id,
|
|
16653
|
-
topicId: row.topic_id,
|
|
16654
|
-
userId: row.user_id,
|
|
16655
|
-
requestId: row.request_id
|
|
16656
|
-
};
|
|
16657
|
-
}
|
|
16658
|
-
async function failInterruptedRemoteAskCallbacks(options = {}) {
|
|
16659
|
-
const rows = db.query(`SELECT target_query_id, request_id, node_name, node_cell_id, topic_id, user_id, route_json
|
|
16660
|
-
FROM remote_ask_callbacks
|
|
16661
|
-
ORDER BY created_at ASC`).all();
|
|
16662
|
-
let failed = 0;
|
|
16663
|
-
for (const row of rows) {
|
|
16664
|
-
const route = durableRoute(row);
|
|
16665
|
-
if (!route) {
|
|
16666
|
-
db.query("DELETE FROM remote_ask_callbacks WHERE target_query_id = ?").run(row.target_query_id);
|
|
16667
|
-
continue;
|
|
16668
|
-
}
|
|
16669
|
-
if (options.routes === "hub" && !isHubRemoteReplyRoute(route))
|
|
16670
|
-
continue;
|
|
16671
|
-
const delivered = await deliverPeerReply(route, "peer", "The remote worker restarted before this ask completed. Please retry the request.", "error");
|
|
16672
|
-
if (!delivered)
|
|
16673
|
-
continue;
|
|
16674
|
-
db.query("DELETE FROM remote_ask_callbacks WHERE target_query_id = ?").run(row.target_query_id);
|
|
16675
|
-
failed++;
|
|
16676
|
-
}
|
|
16677
|
-
return failed;
|
|
16678
|
-
}
|
|
16679
15994
|
var pendingAsks, MAX_ASK_AGE_MS;
|
|
16680
15995
|
var init_ask_callbacks = __esm(async () => {
|
|
16681
15996
|
await __promiseAll([
|
|
@@ -16705,8 +16020,8 @@ var init_ask_callbacks = __esm(async () => {
|
|
|
16705
16020
|
});
|
|
16706
16021
|
|
|
16707
16022
|
// ../../packages/core/src/runtime/file-hooks.ts
|
|
16708
|
-
function isUploadFileId(
|
|
16709
|
-
return UPLOAD_FILE_ID_RE.test(
|
|
16023
|
+
function isUploadFileId(value) {
|
|
16024
|
+
return UPLOAD_FILE_ID_RE.test(value);
|
|
16710
16025
|
}
|
|
16711
16026
|
function resolveAttachmentByFileId(fileId) {
|
|
16712
16027
|
return current2.resolveAttachmentByFileId(fileId);
|
|
@@ -16733,16 +16048,16 @@ var init_file_hooks = __esm(() => {
|
|
|
16733
16048
|
|
|
16734
16049
|
// ../../packages/core/src/runtime/visual-store.ts
|
|
16735
16050
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
16736
|
-
function normalizeVisualTitle(
|
|
16737
|
-
if (typeof
|
|
16051
|
+
function normalizeVisualTitle(value) {
|
|
16052
|
+
if (typeof value !== "string")
|
|
16738
16053
|
return;
|
|
16739
|
-
const normalized =
|
|
16054
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
16740
16055
|
if (!normalized)
|
|
16741
16056
|
return;
|
|
16742
16057
|
return normalized.length > MAX_VISUAL_TITLE_CHARS ? `${normalized.slice(0, MAX_VISUAL_TITLE_CHARS).trimEnd()}...` : normalized;
|
|
16743
16058
|
}
|
|
16744
|
-
function normalizeVisualKind(
|
|
16745
|
-
return VISUAL_KINDS.includes(
|
|
16059
|
+
function normalizeVisualKind(value) {
|
|
16060
|
+
return VISUAL_KINDS.includes(value) ? value : "html";
|
|
16746
16061
|
}
|
|
16747
16062
|
function insertVisual(input) {
|
|
16748
16063
|
const result = db.query(`INSERT INTO api_topic_visuals
|
|
@@ -17013,14 +16328,14 @@ var init_self_schedules = __esm(async () => {
|
|
|
17013
16328
|
});
|
|
17014
16329
|
|
|
17015
16330
|
// ../../packages/core/src/runtime-gateway.ts
|
|
17016
|
-
function parseHostMcpServers(
|
|
17017
|
-
if (
|
|
16331
|
+
function parseHostMcpServers(value) {
|
|
16332
|
+
if (value === undefined)
|
|
17018
16333
|
return;
|
|
17019
|
-
if (!
|
|
16334
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17020
16335
|
throw new TypeError("hostMcpServers must be an object");
|
|
17021
16336
|
}
|
|
17022
16337
|
const parsedEntries = [];
|
|
17023
|
-
for (const [name, raw] of Object.entries(
|
|
16338
|
+
for (const [name, raw] of Object.entries(value)) {
|
|
17024
16339
|
if (!HOST_MCP_SERVER_NAME.test(name)) {
|
|
17025
16340
|
throw new TypeError(`invalid host MCP server name: ${name}`);
|
|
17026
16341
|
}
|
|
@@ -17141,14 +16456,6 @@ var init_topic_tool_capabilities = __esm(async () => {
|
|
|
17141
16456
|
});
|
|
17142
16457
|
|
|
17143
16458
|
// ../../packages/core/src/topics/lifecycle.ts
|
|
17144
|
-
var exports_lifecycle = {};
|
|
17145
|
-
__export(exports_lifecycle, {
|
|
17146
|
-
deleteTopicCascade: () => deleteTopicCascade,
|
|
17147
|
-
TopicTurnStillActiveError: () => TopicTurnStillActiveError,
|
|
17148
|
-
TopicDeleteVetoedError: () => TopicDeleteVetoedError,
|
|
17149
|
-
TopicCleanupRequiredError: () => TopicCleanupRequiredError,
|
|
17150
|
-
TopicArchiveRequiredError: () => TopicArchiveRequiredError
|
|
17151
|
-
});
|
|
17152
16459
|
import { rmSync as rmSync6 } from "fs";
|
|
17153
16460
|
async function abortAndWaitForTopic(topicId) {
|
|
17154
16461
|
interSessionQueue.drop(topicId);
|
|
@@ -17335,7 +16642,7 @@ async function deleteTopicCascadeImpl(topic, userId, options, deletingAncestorId
|
|
|
17335
16642
|
}
|
|
17336
16643
|
}
|
|
17337
16644
|
}
|
|
17338
|
-
var DELETE_TURN_WAIT_MS = 5000, TopicArchiveRequiredError, TopicTurnStillActiveError, TopicCleanupRequiredError
|
|
16645
|
+
var DELETE_TURN_WAIT_MS = 5000, TopicArchiveRequiredError, TopicTurnStillActiveError, TopicCleanupRequiredError;
|
|
17339
16646
|
var init_lifecycle = __esm(async () => {
|
|
17340
16647
|
init_manager();
|
|
17341
16648
|
init_config();
|
|
@@ -17402,19 +16709,9 @@ var init_lifecycle = __esm(async () => {
|
|
|
17402
16709
|
this.topicId = topicId;
|
|
17403
16710
|
}
|
|
17404
16711
|
};
|
|
17405
|
-
TopicDeleteVetoedError = class TopicDeleteVetoedError extends Error {
|
|
17406
|
-
code = "TOPIC_DELETE_VETOED";
|
|
17407
|
-
topicId;
|
|
17408
|
-
constructor(topicId, reason) {
|
|
17409
|
-
super(`Topic delete was vetoed: ${reason}`);
|
|
17410
|
-
this.name = "TopicDeleteVetoedError";
|
|
17411
|
-
this.topicId = topicId;
|
|
17412
|
-
}
|
|
17413
|
-
};
|
|
17414
16712
|
});
|
|
17415
16713
|
|
|
17416
16714
|
// ../../packages/core/src/runtime/attachments.ts
|
|
17417
|
-
import { randomUUID as randomUUID15 } from "crypto";
|
|
17418
16715
|
import { copyFileSync as copyFileSync2, mkdirSync as mkdirSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
17419
16716
|
import { basename as basename7, join as join31 } from "path";
|
|
17420
16717
|
function workspaceCwdFor(topicId) {
|
|
@@ -17475,24 +16772,6 @@ function composeAttachmentPrompt(prompt, promptLines) {
|
|
|
17475
16772
|
function promptWithAttachments(prompt, attachments) {
|
|
17476
16773
|
return composeAttachmentPrompt(prompt, attachments.map(({ filename, path }) => attachmentPromptLine(filename, path)));
|
|
17477
16774
|
}
|
|
17478
|
-
function ingestAttachment(args) {
|
|
17479
|
-
const destDir = join31(UPLOADS_DIR, args.topicId);
|
|
17480
|
-
mkdirSync19(destDir, { recursive: true });
|
|
17481
|
-
const safeName = safeAttachmentFilename(args.filename, "upload");
|
|
17482
|
-
const destPath = join31(destDir, `${Date.now()}-${randomUUID15().slice(0, 8)}-${safeName}`);
|
|
17483
|
-
if (args.sourcePath !== undefined) {
|
|
17484
|
-
copyFileSync2(args.sourcePath, destPath);
|
|
17485
|
-
} else if (args.bytes !== undefined) {
|
|
17486
|
-
writeFileSync17(destPath, args.bytes);
|
|
17487
|
-
} else {
|
|
17488
|
-
throw new Error("ingestAttachment: provide sourcePath or bytes");
|
|
17489
|
-
}
|
|
17490
|
-
return {
|
|
17491
|
-
path: destPath,
|
|
17492
|
-
filename: args.filename,
|
|
17493
|
-
promptLine: attachmentPromptLine(args.filename, destPath)
|
|
17494
|
-
};
|
|
17495
|
-
}
|
|
17496
16775
|
function parseAttachmentNames(raw) {
|
|
17497
16776
|
if (!raw)
|
|
17498
16777
|
return [];
|
|
@@ -17533,13 +16812,13 @@ function isLikelyCurrentChannelTrigger(row, userId, prompt) {
|
|
|
17533
16812
|
return Number.isFinite(createdMs) && Date.now() - createdMs <= CHANNEL_CONTEXT_CURRENT_MESSAGE_MATCH_MS;
|
|
17534
16813
|
}
|
|
17535
16814
|
function formatChannelTranscriptLine(row) {
|
|
17536
|
-
const
|
|
16815
|
+
const text = row.text.trim();
|
|
17537
16816
|
const attachments = parseAttachmentNames(row.attachments);
|
|
17538
16817
|
const attachmentSuffix = attachments.length > 0 ? `
|
|
17539
16818
|
[attachments: ${attachments.join(", ")}]` : "";
|
|
17540
16819
|
const edited = row.edited_at ? " (edited)" : "";
|
|
17541
16820
|
const thread = row.thread_root_id ? ` (in thread ${threadTag(row.thread_root_id)})` : "";
|
|
17542
|
-
return `[${row.created_at}] ${channelTranscriptSpeaker(row)}${edited}${thread}: ${
|
|
16821
|
+
return `[${row.created_at}] ${channelTranscriptSpeaker(row)}${edited}${thread}: ${text}${attachmentSuffix}`;
|
|
17543
16822
|
}
|
|
17544
16823
|
function buildMentionOnlyChannelPrompt(params) {
|
|
17545
16824
|
const rows = getAllMessagesForTopic(params.topicId).filter((row) => {
|
|
@@ -17584,14 +16863,6 @@ function buildMentionOnlyChannelPrompt(params) {
|
|
|
17584
16863
|
].filter((line) => line !== undefined).join(`
|
|
17585
16864
|
`);
|
|
17586
16865
|
}
|
|
17587
|
-
function escapeRegExp3(s) {
|
|
17588
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
17589
|
-
}
|
|
17590
|
-
function mentionsAi(text2, label) {
|
|
17591
|
-
const names = ["ai", "bot", "\uBD07", label.trim()].filter(Boolean);
|
|
17592
|
-
const alt = names.map(escapeRegExp3).join("|");
|
|
17593
|
-
return new RegExp(`(^|\\s)@(${alt})(?![\\p{L}\\p{N}])`, "iu").test(text2);
|
|
17594
|
-
}
|
|
17595
16866
|
var CHANNEL_CONTEXT_CURRENT_MESSAGE_MATCH_MS, CHANNEL_CONTEXT_MAX_MESSAGES = 500, CHANNEL_CONTEXT_MAX_CHARS = 120000;
|
|
17596
16867
|
var init_channel_context = __esm(async () => {
|
|
17597
16868
|
init_attachments();
|
|
@@ -17656,12 +16927,12 @@ var init_errors = __esm(() => {
|
|
|
17656
16927
|
|
|
17657
16928
|
// ../../packages/core/src/runtime/event-heartbeat.ts
|
|
17658
16929
|
function nextOrHeartbeat(pending, intervalMs) {
|
|
17659
|
-
return new Promise((
|
|
17660
|
-
const timer = setTimeout(() =>
|
|
16930
|
+
return new Promise((resolve, reject) => {
|
|
16931
|
+
const timer = setTimeout(() => resolve({ kind: "heartbeat" }), intervalMs);
|
|
17661
16932
|
timer.unref?.();
|
|
17662
16933
|
pending.then((result) => {
|
|
17663
16934
|
clearTimeout(timer);
|
|
17664
|
-
|
|
16935
|
+
resolve({ kind: "event", result });
|
|
17665
16936
|
}, (error) => {
|
|
17666
16937
|
clearTimeout(timer);
|
|
17667
16938
|
reject(error);
|
|
@@ -17955,20 +17226,20 @@ var init_ask_user_gates = __esm(async () => {
|
|
|
17955
17226
|
});
|
|
17956
17227
|
|
|
17957
17228
|
// ../../packages/core/src/agents/mcp-tools/ask-user.ts
|
|
17958
|
-
import { createHash as createHash11, randomUUID as
|
|
17229
|
+
import { createHash as createHash11, randomUUID as randomUUID15 } from "crypto";
|
|
17959
17230
|
import { z as z4 } from "zod";
|
|
17960
|
-
function normalizeAskText(
|
|
17961
|
-
if (typeof
|
|
17231
|
+
function normalizeAskText(value, maxChars) {
|
|
17232
|
+
if (typeof value !== "string")
|
|
17962
17233
|
return;
|
|
17963
|
-
const normalized =
|
|
17234
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
17964
17235
|
if (!normalized)
|
|
17965
17236
|
return;
|
|
17966
17237
|
return normalized.length > maxChars ? `${normalized.slice(0, maxChars).trimEnd()}...` : normalized;
|
|
17967
17238
|
}
|
|
17968
|
-
function normalizeAskUserChoices(
|
|
17969
|
-
if (!Array.isArray(
|
|
17239
|
+
function normalizeAskUserChoices(value) {
|
|
17240
|
+
if (!Array.isArray(value))
|
|
17970
17241
|
return [];
|
|
17971
|
-
return
|
|
17242
|
+
return value.map((choice) => {
|
|
17972
17243
|
if (!choice || typeof choice !== "object")
|
|
17973
17244
|
return null;
|
|
17974
17245
|
const record = choice;
|
|
@@ -18003,7 +17274,7 @@ Description: ${answer.description}` : "";
|
|
|
18003
17274
|
Continue from this selection and finish the current turn.`);
|
|
18004
17275
|
}
|
|
18005
17276
|
function createAskUserRuntime(host) {
|
|
18006
|
-
const
|
|
17277
|
+
const pendingAsks = new Map;
|
|
18007
17278
|
const { ownerId } = host.runtime;
|
|
18008
17279
|
const createId = () => host.runtime.createId();
|
|
18009
17280
|
const now = () => host.runtime.now();
|
|
@@ -18033,7 +17304,7 @@ function createAskUserRuntime(host) {
|
|
|
18033
17304
|
return updates.length;
|
|
18034
17305
|
}
|
|
18035
17306
|
function hasPendingQuestion(topicId, messageId) {
|
|
18036
|
-
const pending =
|
|
17307
|
+
const pending = pendingAsks.get(messageId);
|
|
18037
17308
|
return Boolean(pending && pending.topicId === topicId);
|
|
18038
17309
|
}
|
|
18039
17310
|
function answerPendingQuestion(topicId, messageId, label, userId) {
|
|
@@ -18050,10 +17321,10 @@ function createAskUserRuntime(host) {
|
|
|
18050
17321
|
if (ask.expired || ask.selectedLabel) {
|
|
18051
17322
|
return { ok: false, error: "This question is no longer awaiting an answer." };
|
|
18052
17323
|
}
|
|
18053
|
-
if (!ask.choices.some((
|
|
17324
|
+
if (!ask.choices.some((choice) => choice.label === label)) {
|
|
18054
17325
|
return { ok: false, error: "Invalid choice." };
|
|
18055
17326
|
}
|
|
18056
|
-
const pending =
|
|
17327
|
+
const pending = pendingAsks.get(messageId);
|
|
18057
17328
|
if (!pending || pending.topicId !== topicId) {
|
|
18058
17329
|
return { ok: false, error: "This question is no longer awaiting an answer." };
|
|
18059
17330
|
}
|
|
@@ -18077,7 +17348,7 @@ function createAskUserRuntime(host) {
|
|
|
18077
17348
|
if (claim.outcome !== "claimed") {
|
|
18078
17349
|
return { ok: false, error: "This question is no longer awaiting an answer." };
|
|
18079
17350
|
}
|
|
18080
|
-
|
|
17351
|
+
pendingAsks.delete(messageId);
|
|
18081
17352
|
const answerMessage = {
|
|
18082
17353
|
id: createId(),
|
|
18083
17354
|
topicId,
|
|
@@ -18101,9 +17372,9 @@ function createAskUserRuntime(host) {
|
|
|
18101
17372
|
return { ok: true, queryId: pending.queryId, answerMessage };
|
|
18102
17373
|
}
|
|
18103
17374
|
function cancelPendingQuestions(topicId, queryId) {
|
|
18104
|
-
for (const [messageId, pending] of
|
|
17375
|
+
for (const [messageId, pending] of pendingAsks) {
|
|
18105
17376
|
if (pending.topicId === topicId && pending.queryId === queryId) {
|
|
18106
|
-
|
|
17377
|
+
pendingAsks.delete(messageId);
|
|
18107
17378
|
const update = host.durability.gates.cancel(topicId, messageId, ownerId, now());
|
|
18108
17379
|
if (update)
|
|
18109
17380
|
broadcastGateUpdates([update]);
|
|
@@ -18181,7 +17452,7 @@ function createAskUserRuntime(host) {
|
|
|
18181
17452
|
if (prepared.gate.ownerId !== ownerId) {
|
|
18182
17453
|
return errorResult("Error: this ask_user_question is pending in another healthy runtime process.");
|
|
18183
17454
|
}
|
|
18184
|
-
const existingPending =
|
|
17455
|
+
const existingPending = pendingAsks.get(prepared.gate.messageId);
|
|
18185
17456
|
if (existingPending)
|
|
18186
17457
|
return answerToolResult(await existingPending.promise);
|
|
18187
17458
|
if (prepared.gate.state === "claimed") {
|
|
@@ -18203,10 +17474,10 @@ function createAskUserRuntime(host) {
|
|
|
18203
17474
|
return errorResult(`Error: failed to persist ask_user_question: ${error instanceof Error ? error.message : String(error)}`);
|
|
18204
17475
|
}
|
|
18205
17476
|
let resolveAnswer;
|
|
18206
|
-
const promise = new Promise((
|
|
18207
|
-
resolveAnswer =
|
|
17477
|
+
const promise = new Promise((resolve) => {
|
|
17478
|
+
resolveAnswer = resolve;
|
|
18208
17479
|
});
|
|
18209
|
-
|
|
17480
|
+
pendingAsks.set(message.id, {
|
|
18210
17481
|
topicId: ctx.topicId,
|
|
18211
17482
|
queryId: ctx.queryId,
|
|
18212
17483
|
messageId: message.id,
|
|
@@ -18218,7 +17489,7 @@ function createAskUserRuntime(host) {
|
|
|
18218
17489
|
try {
|
|
18219
17490
|
host.messaging.publication.publishMessage(ctx.topicId, message);
|
|
18220
17491
|
} catch (error) {
|
|
18221
|
-
|
|
17492
|
+
pendingAsks.delete(message.id);
|
|
18222
17493
|
try {
|
|
18223
17494
|
host.durability.gates.quarantine(prepared.gate.gateId, ownerId, now());
|
|
18224
17495
|
} catch {}
|
|
@@ -18267,7 +17538,7 @@ var init_ask_user = __esm(async () => {
|
|
|
18267
17538
|
init_ask_user_gates(),
|
|
18268
17539
|
init_runtime_process_leases()
|
|
18269
17540
|
]);
|
|
18270
|
-
ASK_GATE_OWNER_ID = `ask-user-${process.pid}-${
|
|
17541
|
+
ASK_GATE_OWNER_ID = `ask-user-${process.pid}-${randomUUID15()}`;
|
|
18271
17542
|
defaultAskUserDurabilityHost = {
|
|
18272
17543
|
gates: {
|
|
18273
17544
|
prepare: prepareAskUserGate,
|
|
@@ -18304,7 +17575,7 @@ var init_ask_user = __esm(async () => {
|
|
|
18304
17575
|
durability: defaultAskUserDurabilityHost,
|
|
18305
17576
|
runtime: {
|
|
18306
17577
|
ownerId: ASK_GATE_OWNER_ID,
|
|
18307
|
-
createId:
|
|
17578
|
+
createId: randomUUID15,
|
|
18308
17579
|
now: () => new Date().toISOString()
|
|
18309
17580
|
}
|
|
18310
17581
|
});
|
|
@@ -18507,7 +17778,7 @@ var init_vault_request_gates = __esm(async () => {
|
|
|
18507
17778
|
});
|
|
18508
17779
|
|
|
18509
17780
|
// ../../packages/core/src/agents/mcp-tools/request-vault.ts
|
|
18510
|
-
import { createHash as createHash12, randomUUID as
|
|
17781
|
+
import { createHash as createHash12, randomUUID as randomUUID16 } from "crypto";
|
|
18511
17782
|
import { z as z5 } from "zod";
|
|
18512
17783
|
function requestBodyHash(key, description) {
|
|
18513
17784
|
return createHash12("sha256").update(JSON.stringify({ key, description })).digest("hex");
|
|
@@ -18551,7 +17822,7 @@ function createRequestVaultRuntime(host) {
|
|
|
18551
17822
|
broadcastGateUpdates(updates);
|
|
18552
17823
|
return updates.length;
|
|
18553
17824
|
}
|
|
18554
|
-
function answerPendingRequest(topicId, messageId, userId,
|
|
17825
|
+
function answerPendingRequest(topicId, messageId, userId, value) {
|
|
18555
17826
|
reconcilePendingGates();
|
|
18556
17827
|
const topic = host.topics.getTopic(topicId);
|
|
18557
17828
|
if (!topic?.participants.some((participant) => participant.userId === userId)) {
|
|
@@ -18569,9 +17840,9 @@ function createRequestVaultRuntime(host) {
|
|
|
18569
17840
|
if (!pending || pending.topicId !== topicId) {
|
|
18570
17841
|
return { ok: false, error: "This request is no longer awaiting an answer." };
|
|
18571
17842
|
}
|
|
18572
|
-
const declining =
|
|
17843
|
+
const declining = value === null;
|
|
18573
17844
|
if (!declining) {
|
|
18574
|
-
const bytes = Buffer.byteLength(
|
|
17845
|
+
const bytes = Buffer.byteLength(value, "utf8");
|
|
18575
17846
|
if (bytes < VAULT_VALUE_MIN_BYTES || bytes > VAULT_VALUE_MAX_BYTES) {
|
|
18576
17847
|
return {
|
|
18577
17848
|
ok: false,
|
|
@@ -18581,7 +17852,7 @@ function createRequestVaultRuntime(host) {
|
|
|
18581
17852
|
}
|
|
18582
17853
|
if (!declining) {
|
|
18583
17854
|
try {
|
|
18584
|
-
host.vault.set(userId, pending.key,
|
|
17855
|
+
host.vault.set(userId, pending.key, value, pending.description);
|
|
18585
17856
|
} catch (error) {
|
|
18586
17857
|
return {
|
|
18587
17858
|
ok: false,
|
|
@@ -18743,8 +18014,8 @@ function createRequestVaultRuntime(host) {
|
|
|
18743
18014
|
return errorResult(`Error: failed to persist request_vault_secret: ${error instanceof Error ? error.message : String(error)}`);
|
|
18744
18015
|
}
|
|
18745
18016
|
let resolveAnswer;
|
|
18746
|
-
const promise = new Promise((
|
|
18747
|
-
resolveAnswer =
|
|
18017
|
+
const promise = new Promise((resolve) => {
|
|
18018
|
+
resolveAnswer = resolve;
|
|
18748
18019
|
});
|
|
18749
18020
|
pendingRequests.set(message.id, {
|
|
18750
18021
|
topicId: ctx.topicId,
|
|
@@ -18805,7 +18076,7 @@ var init_request_vault = __esm(async () => {
|
|
|
18805
18076
|
init_vault_request_gates()
|
|
18806
18077
|
]);
|
|
18807
18078
|
MAX_DESCRIPTION_CHARS = VAULT_DESCRIPTION_MAX_LENGTH;
|
|
18808
|
-
VAULT_GATE_OWNER_ID = `request-vault-${process.pid}-${
|
|
18079
|
+
VAULT_GATE_OWNER_ID = `request-vault-${process.pid}-${randomUUID16()}`;
|
|
18809
18080
|
defaultRequestVaultDurabilityHost = {
|
|
18810
18081
|
gates: {
|
|
18811
18082
|
prepare: prepareVaultRequestGate,
|
|
@@ -18846,7 +18117,7 @@ var init_request_vault = __esm(async () => {
|
|
|
18846
18117
|
durability: defaultRequestVaultDurabilityHost,
|
|
18847
18118
|
runtime: {
|
|
18848
18119
|
ownerId: VAULT_GATE_OWNER_ID,
|
|
18849
|
-
createId:
|
|
18120
|
+
createId: randomUUID16,
|
|
18850
18121
|
now: () => new Date().toISOString()
|
|
18851
18122
|
}
|
|
18852
18123
|
});
|
|
@@ -18883,24 +18154,24 @@ function taskPanelMessageId(queryId) {
|
|
|
18883
18154
|
// ../../packages/core/src/runtime/tasks.ts
|
|
18884
18155
|
function upsertTaskPanelMessage(topicId, queryId, tasks, lastRenderedText) {
|
|
18885
18156
|
if (tasks.length === 0) {
|
|
18886
|
-
const
|
|
18887
|
-
for (const
|
|
18888
|
-
|
|
18157
|
+
const hub = WsHub.get();
|
|
18158
|
+
for (const messageId of softDeleteApiMessagesByIdPrefix(topicId, "tasks-")) {
|
|
18159
|
+
hub.broadcastMessageUpdated(topicId, messageId, { deleted: true, text: "" });
|
|
18889
18160
|
}
|
|
18890
18161
|
return null;
|
|
18891
18162
|
}
|
|
18892
|
-
const
|
|
18893
|
-
if (
|
|
18163
|
+
const text = renderTaskPanel(tasks);
|
|
18164
|
+
if (text === lastRenderedText)
|
|
18894
18165
|
return lastRenderedText;
|
|
18895
18166
|
const hub = WsHub.get();
|
|
18896
18167
|
const messageId = taskPanelMessageId(queryId);
|
|
18897
18168
|
const existing = getApiMessage(topicId, messageId);
|
|
18898
18169
|
if (existing && !existing.deleted) {
|
|
18899
18170
|
const editedAt = new Date().toISOString();
|
|
18900
|
-
const updated = updateApiMessageText(topicId, messageId,
|
|
18171
|
+
const updated = updateApiMessageText(topicId, messageId, text, editedAt);
|
|
18901
18172
|
if (updated) {
|
|
18902
|
-
hub.broadcastMessageUpdated(topicId, messageId, { text
|
|
18903
|
-
return
|
|
18173
|
+
hub.broadcastMessageUpdated(topicId, messageId, { text, editedAt });
|
|
18174
|
+
return text;
|
|
18904
18175
|
}
|
|
18905
18176
|
}
|
|
18906
18177
|
const createdAt = new Date().toISOString();
|
|
@@ -18908,12 +18179,12 @@ function upsertTaskPanelMessage(topicId, queryId, tasks, lastRenderedText) {
|
|
|
18908
18179
|
id: messageId,
|
|
18909
18180
|
topicId,
|
|
18910
18181
|
authorId: "system",
|
|
18911
|
-
text
|
|
18182
|
+
text,
|
|
18912
18183
|
createdAt
|
|
18913
18184
|
};
|
|
18914
18185
|
appendApiMessage(message, { notify: false });
|
|
18915
18186
|
hub.broadcastMessage(topicId, message);
|
|
18916
|
-
return
|
|
18187
|
+
return text;
|
|
18917
18188
|
}
|
|
18918
18189
|
var init_tasks2 = __esm(async () => {
|
|
18919
18190
|
await __promiseAll([
|
|
@@ -18923,11 +18194,11 @@ var init_tasks2 = __esm(async () => {
|
|
|
18923
18194
|
});
|
|
18924
18195
|
|
|
18925
18196
|
// ../../packages/core/src/runtime/visual-html.ts
|
|
18926
|
-
function escapeHtml(
|
|
18927
|
-
return
|
|
18197
|
+
function escapeHtml(value) {
|
|
18198
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
18928
18199
|
}
|
|
18929
|
-
function normalizeMermaidTheme(
|
|
18930
|
-
return
|
|
18200
|
+
function normalizeMermaidTheme(value) {
|
|
18201
|
+
return value === "default" || value === "dark" || value === "forest" ? value : "neutral";
|
|
18931
18202
|
}
|
|
18932
18203
|
function buildMermaidHtml(code, theme, scriptUrl = MERMAID_BROWSER_ASSET_RELATIVE_URL) {
|
|
18933
18204
|
const safeCode = escapeHtml(code);
|
|
@@ -19108,15 +18379,15 @@ function isVisualsShowMermaidTool(name) {
|
|
|
19108
18379
|
function isVisualsShowImageTool(name) {
|
|
19109
18380
|
return isRuntimeTool(name, "show_image") || isRuntimeTool(name, "show_png");
|
|
19110
18381
|
}
|
|
19111
|
-
function normalizeToolUseId(
|
|
19112
|
-
const normalized =
|
|
18382
|
+
function normalizeToolUseId(value) {
|
|
18383
|
+
const normalized = value?.trim();
|
|
19113
18384
|
return normalized ? normalized : undefined;
|
|
19114
18385
|
}
|
|
19115
|
-
function escapeHtml2(
|
|
19116
|
-
return
|
|
18386
|
+
function escapeHtml2(value) {
|
|
18387
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
19117
18388
|
}
|
|
19118
|
-
function stripMermaidFence(
|
|
19119
|
-
const trimmed =
|
|
18389
|
+
function stripMermaidFence(value) {
|
|
18390
|
+
const trimmed = value.trim();
|
|
19120
18391
|
const fenced = trimmed.match(/^```(?:mermaid)?\s*\n([\s\S]*?)\n```$/i);
|
|
19121
18392
|
return (fenced ? fenced[1] : trimmed).trim();
|
|
19122
18393
|
}
|
|
@@ -19172,14 +18443,14 @@ function resolveVisualMediaInput(topicId, input) {
|
|
|
19172
18443
|
if (!topicAllowsVisualFileId(topicId, fileId)) {
|
|
19173
18444
|
return { error: "file_id is not attached to this topic" };
|
|
19174
18445
|
}
|
|
19175
|
-
const
|
|
19176
|
-
const
|
|
19177
|
-
if (!
|
|
18446
|
+
const attachment = resolveAttachmentByFileId(fileId);
|
|
18447
|
+
const filePath = resolveUploadedFilePathByFileId(fileId);
|
|
18448
|
+
if (!attachment || !filePath)
|
|
19178
18449
|
return { error: `uploaded file not found: ${fileId}` };
|
|
19179
18450
|
return {
|
|
19180
|
-
fileId:
|
|
19181
|
-
mimeType:
|
|
19182
|
-
source: `file_id:${
|
|
18451
|
+
fileId: attachment.id,
|
|
18452
|
+
mimeType: attachment.mimeType,
|
|
18453
|
+
source: `file_id:${attachment.id}`
|
|
19183
18454
|
};
|
|
19184
18455
|
}
|
|
19185
18456
|
if (typeof input.file_path !== "string" || !input.file_path.trim()) {
|
|
@@ -19226,7 +18497,7 @@ var init_visuals = __esm(async () => {
|
|
|
19226
18497
|
});
|
|
19227
18498
|
|
|
19228
18499
|
// ../../packages/core/src/runtime/turn-event-stream.ts
|
|
19229
|
-
import { randomUUID as
|
|
18500
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
19230
18501
|
import { realpathSync as realpathSync7, statSync as statSync9 } from "fs";
|
|
19231
18502
|
import { isAbsolute as isAbsolute6, resolve as resolve18 } from "path";
|
|
19232
18503
|
function sessionEventMatchesCurrentExecution(topicId, queryId, agent, model) {
|
|
@@ -19295,9 +18566,9 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
|
|
|
19295
18566
|
const existing = providerToolIds.get(providerId);
|
|
19296
18567
|
if (existing)
|
|
19297
18568
|
return existing;
|
|
19298
|
-
const
|
|
19299
|
-
providerToolIds.set(providerId,
|
|
19300
|
-
return
|
|
18569
|
+
const clientId = fallback ?? providerId;
|
|
18570
|
+
providerToolIds.set(providerId, clientId);
|
|
18571
|
+
return clientId;
|
|
19301
18572
|
}
|
|
19302
18573
|
const clientId = fallback ?? nextSyntheticToolUseId();
|
|
19303
18574
|
anonymousToolIds.push(clientId);
|
|
@@ -19328,15 +18599,15 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
|
|
|
19328
18599
|
return providerId ? handledVisualToolResultIds.has(providerId) : false;
|
|
19329
18600
|
};
|
|
19330
18601
|
const emitPendingAssistantMessage = (usage) => {
|
|
19331
|
-
const
|
|
18602
|
+
const text = pendingText.trimEnd();
|
|
19332
18603
|
pendingText = "";
|
|
19333
|
-
if (silent || !
|
|
18604
|
+
if (silent || !text.trim())
|
|
19334
18605
|
return null;
|
|
19335
18606
|
const message = {
|
|
19336
|
-
id:
|
|
18607
|
+
id: randomUUID17(),
|
|
19337
18608
|
topicId,
|
|
19338
18609
|
authorId: "ai",
|
|
19339
|
-
text
|
|
18610
|
+
text,
|
|
19340
18611
|
queryId,
|
|
19341
18612
|
agentType,
|
|
19342
18613
|
model,
|
|
@@ -19668,8 +18939,8 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
19668
18939
|
}
|
|
19669
18940
|
terminalEmitted = true;
|
|
19670
18941
|
{
|
|
19671
|
-
|
|
19672
|
-
const pending =
|
|
18942
|
+
await init_ask_callbacks();
|
|
18943
|
+
const pending = resolveAskCallback(queryId);
|
|
19673
18944
|
if (pending) {
|
|
19674
18945
|
const sourceLabel = pending.sourceLabel ?? topicTitle;
|
|
19675
18946
|
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)";
|
|
@@ -19776,8 +19047,8 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
19776
19047
|
settleSubagentFailure(queryId, "\uC911\uC9C0\uB428 (\uC0AC\uC6A9\uC790\uAC00 \uC2E4\uD589\uC744 \uBA48\uCDC4\uC2B5\uB2C8\uB2E4)");
|
|
19777
19048
|
} else {
|
|
19778
19049
|
if (control.abortReason === "internal" /* Internal */) {
|
|
19779
|
-
|
|
19780
|
-
|
|
19050
|
+
await init_ask_callbacks();
|
|
19051
|
+
resolveAskCallback(queryId);
|
|
19781
19052
|
}
|
|
19782
19053
|
}
|
|
19783
19054
|
}
|
|
@@ -19934,85 +19205,7 @@ var init_app_settings = __esm(async () => {
|
|
|
19934
19205
|
});
|
|
19935
19206
|
|
|
19936
19207
|
// ../../packages/core/src/runtime/turn-runner.ts
|
|
19937
|
-
|
|
19938
|
-
__export(exports_turn_runner, {
|
|
19939
|
-
workspaceCwdFor: () => workspaceCwdFor,
|
|
19940
|
-
withDefaultPlaywright: () => withDefaultPlaywright,
|
|
19941
|
-
wasLocallyRequeuedAfterUserPreemption: () => wasLocallyRequeuedAfterUserPreemption,
|
|
19942
|
-
userConversationPromptsToRecord: () => userConversationPromptsToRecord,
|
|
19943
|
-
upsertTaskPanelMessage: () => upsertTaskPanelMessage,
|
|
19944
|
-
tryReconstructTopicRollout: () => tryReconstructTopicRollout,
|
|
19945
|
-
triggerTopicAiTurn: () => triggerTopicAiTurn,
|
|
19946
|
-
topicAllowsVisualFileId: () => topicAllowsVisualFileId,
|
|
19947
|
-
taskPanelMessageId: () => taskPanelMessageId,
|
|
19948
|
-
stripMermaidFence: () => stripMermaidFence,
|
|
19949
|
-
stringifyError: () => stringifyError,
|
|
19950
|
-
streamAgentEvents: () => streamAgentEvents,
|
|
19951
|
-
startDurableTurnRequestWorker: () => startDurableTurnRequestWorker,
|
|
19952
|
-
startAiTurn: () => startAiTurn,
|
|
19953
|
-
selectableModel: () => selectableModel,
|
|
19954
|
-
sameTurnActor: () => sameTurnActor,
|
|
19955
|
-
safeAttachmentFilename: () => safeAttachmentFilename,
|
|
19956
|
-
resolveWorkerModel: () => resolveWorkerModel,
|
|
19957
|
-
resolveWorkerDefaultModel: () => resolveWorkerDefaultModel,
|
|
19958
|
-
resolveWikiMirrorPath: () => resolveWikiMirrorPath,
|
|
19959
|
-
resolveWikiMemoryMirror: () => resolveWikiMemoryMirror,
|
|
19960
|
-
resolveVisualMediaInput: () => resolveVisualMediaInput,
|
|
19961
|
-
resolveTurnToolCapabilities: () => resolveTurnToolCapabilities,
|
|
19962
|
-
resolveTurnHostMcpServers: () => resolveTurnHostMcpServers,
|
|
19963
|
-
resolveTopicTurnSession: () => resolveTopicTurnSession,
|
|
19964
|
-
resolveTopicTurnExecution: () => resolveTopicTurnExecution,
|
|
19965
|
-
resolveSessionRetry: () => resolveSessionRetry,
|
|
19966
|
-
resolveModelForAgent: () => resolveModelForAgent,
|
|
19967
|
-
resolveInitialTurnSessionId: () => resolveInitialTurnSessionId,
|
|
19968
|
-
resolveDefaultModel: () => resolveDefaultModel,
|
|
19969
|
-
resolveCompactionExecution: () => resolveCompactionExecution,
|
|
19970
|
-
renderUserTurnBatch: () => renderUserTurnBatch,
|
|
19971
|
-
renderUserPromptBatch: () => renderUserPromptBatch,
|
|
19972
|
-
renderTaskPanel: () => renderTaskPanel,
|
|
19973
|
-
promptWithAttachments: () => promptWithAttachments,
|
|
19974
|
-
prepareInjectReplayAfterUserPreemption: () => prepareInjectReplayAfterUserPreemption,
|
|
19975
|
-
parseAttachmentNames: () => parseAttachmentNames,
|
|
19976
|
-
normalizeToolUseId: () => normalizeToolUseId,
|
|
19977
|
-
normalizeMermaidTheme: () => normalizeMermaidTheme,
|
|
19978
|
-
modelOwner: () => modelOwner,
|
|
19979
|
-
mergeSupersedingUserTurn: () => mergeSupersedingUserTurn,
|
|
19980
|
-
mentionsAi: () => mentionsAi,
|
|
19981
|
-
materializePromptAttachments: () => materializePromptAttachments,
|
|
19982
|
-
isVisualsShowMermaidTool: () => isVisualsShowMermaidTool,
|
|
19983
|
-
isVisualsShowImageTool: () => isVisualsShowImageTool,
|
|
19984
|
-
isVisualsShowHtmlTool: () => isVisualsShowHtmlTool,
|
|
19985
|
-
isSessionExpiredError: () => isSessionExpiredError,
|
|
19986
|
-
isRuntimeTool: () => isRuntimeTool,
|
|
19987
|
-
isPathInside: () => isPathInside,
|
|
19988
|
-
isLikelyCurrentChannelTrigger: () => isLikelyCurrentChannelTrigger,
|
|
19989
|
-
ingestAttachment: () => ingestAttachment,
|
|
19990
|
-
formatSelectableModel: () => formatSelectableModel,
|
|
19991
|
-
formatChannelTranscriptLine: () => formatChannelTranscriptLine,
|
|
19992
|
-
escapeRegExp: () => escapeRegExp3,
|
|
19993
|
-
escapeHtml: () => escapeHtml2,
|
|
19994
|
-
deliverAskCallbackToCaller: () => deliverAskCallbackToCaller,
|
|
19995
|
-
composeAttachmentPrompt: () => composeAttachmentPrompt,
|
|
19996
|
-
classifyAgentError: () => classifyAgentError,
|
|
19997
|
-
channelTranscriptSpeaker: () => channelTranscriptSpeaker,
|
|
19998
|
-
canonicalModelId: () => canonicalModelId,
|
|
19999
|
-
buildVideoHtml: () => buildVideoHtml,
|
|
20000
|
-
buildTurnReminderQuery: () => buildTurnReminderQuery,
|
|
20001
|
-
buildMermaidHtml: () => buildMermaidHtml,
|
|
20002
|
-
buildMentionOnlyChannelPrompt: () => buildMentionOnlyChannelPrompt,
|
|
20003
|
-
buildImageHtml: () => buildImageHtml,
|
|
20004
|
-
authRecoveryHint: () => authRecoveryHint,
|
|
20005
|
-
attachmentPromptLine: () => attachmentPromptLine,
|
|
20006
|
-
activeVisualHtmlForPrompt: () => activeVisualHtmlForPrompt,
|
|
20007
|
-
SESSION_EXPIRED_MSG: () => SESSION_EXPIRED_MSG,
|
|
20008
|
-
SELECTABLE_MODELS: () => SELECTABLE_MODELS,
|
|
20009
|
-
MODEL_OWNER: () => MODEL_OWNER,
|
|
20010
|
-
MODEL_COST_ROUTING_SUMMARY: () => MODEL_COST_ROUTING_SUMMARY,
|
|
20011
|
-
MODEL_COST_RESEARCHED_AT: () => MODEL_COST_RESEARCHED_AT,
|
|
20012
|
-
FALLBACK_ORDER: () => FALLBACK_ORDER,
|
|
20013
|
-
AGENT_DISPLAY_NAME: () => AGENT_DISPLAY_NAME
|
|
20014
|
-
});
|
|
20015
|
-
import { randomUUID as randomUUID19 } from "crypto";
|
|
19208
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
20016
19209
|
import { existsSync as existsSync24, mkdirSync as mkdirSync21, readdirSync as readdirSync7, statSync as statSync10 } from "fs";
|
|
20017
19210
|
import { join as join33 } from "path";
|
|
20018
19211
|
function withDefaultPlaywright(configuredMcp, isManager) {
|
|
@@ -20035,12 +19228,12 @@ function buildTurnReminderQuery(agent, prompt, reminders) {
|
|
|
20035
19228
|
|
|
20036
19229
|
${reminderPrompt}` };
|
|
20037
19230
|
}
|
|
20038
|
-
function appendSystemMessage(topicId,
|
|
19231
|
+
function appendSystemMessage(topicId, text, threadRootId) {
|
|
20039
19232
|
const message = {
|
|
20040
|
-
id:
|
|
19233
|
+
id: randomUUID18(),
|
|
20041
19234
|
topicId,
|
|
20042
19235
|
authorId: "system",
|
|
20043
|
-
text
|
|
19236
|
+
text,
|
|
20044
19237
|
...threadRootId ? { threadRootId } : {},
|
|
20045
19238
|
createdAt: new Date().toISOString()
|
|
20046
19239
|
};
|
|
@@ -20057,12 +19250,12 @@ function notifyPlaywrightUnavailable(topicId) {
|
|
|
20057
19250
|
appendSystemMessage(topicId, "Playwright browser tools are unavailable this turn. Browser automation was removed from the tool catalog; retry shortly if browser interaction is required.");
|
|
20058
19251
|
WsHub.get().broadcastTopicNotice(topicId, "info", "Playwright \uC0AC\uC6A9 \uBD88\uAC00");
|
|
20059
19252
|
}
|
|
20060
|
-
function appendAskReplyMessage(topicId,
|
|
19253
|
+
function appendAskReplyMessage(topicId, text, sourceLabel, body, kind, agentType, threadRootId) {
|
|
20061
19254
|
const message = {
|
|
20062
|
-
id:
|
|
19255
|
+
id: randomUUID18(),
|
|
20063
19256
|
topicId,
|
|
20064
19257
|
authorId: "ai",
|
|
20065
|
-
text
|
|
19258
|
+
text,
|
|
20066
19259
|
kind: "tell",
|
|
20067
19260
|
tellCard: {
|
|
20068
19261
|
fromLabel: sourceLabel,
|
|
@@ -20182,10 +19375,10 @@ async function clearPendingAskFile(pending, state) {
|
|
|
20182
19375
|
if (!pending.pendingAsk)
|
|
20183
19376
|
return;
|
|
20184
19377
|
try {
|
|
20185
|
-
|
|
19378
|
+
await init_session_asks();
|
|
20186
19379
|
if (state)
|
|
20187
|
-
|
|
20188
|
-
|
|
19380
|
+
markPendingAskState({ ...pending.pendingAsk, state });
|
|
19381
|
+
clearPendingAsk(pending.pendingAsk);
|
|
20189
19382
|
} catch (err) {
|
|
20190
19383
|
logger.warn({ err, pendingAsk: pending.pendingAsk }, "sessions: pending ask cleanup failed");
|
|
20191
19384
|
}
|
|
@@ -20194,16 +19387,16 @@ async function markPendingAskFile(pending, state) {
|
|
|
20194
19387
|
if (!pending.pendingAsk)
|
|
20195
19388
|
return;
|
|
20196
19389
|
try {
|
|
20197
|
-
|
|
20198
|
-
|
|
19390
|
+
await init_session_asks();
|
|
19391
|
+
markPendingAskState({ ...pending.pendingAsk, state });
|
|
20199
19392
|
} catch (err) {
|
|
20200
19393
|
logger.warn({ err, pendingAsk: pending.pendingAsk, state }, "sessions: pending ask mark failed");
|
|
20201
19394
|
}
|
|
20202
19395
|
}
|
|
20203
19396
|
async function deliverAskCallbackToCaller(pending, sourceLabel, body, kind, options = {}) {
|
|
20204
19397
|
if (pending.remoteReply) {
|
|
20205
|
-
|
|
20206
|
-
const delivered = await
|
|
19398
|
+
await init_peer_forward();
|
|
19399
|
+
const delivered = await deliverPeerReply(pending.remoteReply, sourceLabel, body, kind);
|
|
20207
19400
|
if (delivered)
|
|
20208
19401
|
options.onRecorded?.();
|
|
20209
19402
|
return delivered;
|
|
@@ -20275,8 +19468,8 @@ ${body}`;
|
|
|
20275
19468
|
}
|
|
20276
19469
|
async function deliverAskError(queryId, sourceLabel, error) {
|
|
20277
19470
|
try {
|
|
20278
|
-
|
|
20279
|
-
const pending =
|
|
19471
|
+
await init_ask_callbacks();
|
|
19472
|
+
const pending = resolveAskCallback(queryId);
|
|
20280
19473
|
if (pending) {
|
|
20281
19474
|
const prefix = pending.timedOut ? `\u26A0\uFE0F [Timeout - error notification was dropped]
|
|
20282
19475
|
|
|
@@ -20334,8 +19527,10 @@ function resolveTurnToolCapabilities(topicId, params) {
|
|
|
20334
19527
|
};
|
|
20335
19528
|
}
|
|
20336
19529
|
function resolveTurnHostMcpServers(topic, sessionType) {
|
|
20337
|
-
|
|
20338
|
-
|
|
19530
|
+
if (topic.isSubagent)
|
|
19531
|
+
return;
|
|
19532
|
+
const ownScope = topic.kind === "manager" ? "manager" : "forum";
|
|
19533
|
+
if ((sessionType ?? ownScope) !== ownScope)
|
|
20339
19534
|
return;
|
|
20340
19535
|
return getTopicHostMcpGrant(topic.id) ?? undefined;
|
|
20341
19536
|
}
|
|
@@ -20437,81 +19632,6 @@ function waitToDrainRemoteInject(topicId) {
|
|
|
20437
19632
|
timer.unref?.();
|
|
20438
19633
|
remoteInjectWaiters.set(topicId, timer);
|
|
20439
19634
|
}
|
|
20440
|
-
async function drainOneDurableUserTurn() {
|
|
20441
|
-
if (durableTurnWorkerBusy)
|
|
20442
|
-
return;
|
|
20443
|
-
durableTurnWorkerBusy = true;
|
|
20444
|
-
try {
|
|
20445
|
-
const request = claimNextRuntimeUserTurnRequest(RUNTIME_INSTANCE_ID);
|
|
20446
|
-
if (!request)
|
|
20447
|
-
return;
|
|
20448
|
-
const topic = getTopic(request.topicId);
|
|
20449
|
-
if (!topic?.agent) {
|
|
20450
|
-
completeRuntimeUserTurnRequest(request.topicId, request.requestId, RUNTIME_INSTANCE_ID);
|
|
20451
|
-
return;
|
|
20452
|
-
}
|
|
20453
|
-
const execution = request.execution;
|
|
20454
|
-
const queryId = startAiTurn({
|
|
20455
|
-
topic,
|
|
20456
|
-
userId: request.userId,
|
|
20457
|
-
actorUserId: execution?.actorUserId,
|
|
20458
|
-
actorTopicScope: actorTopicScopeFrom(execution?.actorTopicScope),
|
|
20459
|
-
remoteSession: remoteSessionGrantFrom(execution?.remoteSession),
|
|
20460
|
-
vaultUserId: execution?.vaultUserId,
|
|
20461
|
-
prompt: request.prompt,
|
|
20462
|
-
_userMessages: request.userMessages,
|
|
20463
|
-
_conversationPrompts: execution?.conversationPrompts ?? [request.prompt],
|
|
20464
|
-
_loggedUserMessageCount: execution?.loggedUserMessageCount ?? Math.max(0, request.userMessages.length - (execution?.conversationPrompts?.length ?? 1)),
|
|
20465
|
-
_durableRequestIds: [request.requestId],
|
|
20466
|
-
attachments: request.attachments,
|
|
20467
|
-
allowAutoContinue: request.allowAutoContinue,
|
|
20468
|
-
origin: "user",
|
|
20469
|
-
requestId: execution?.sourceRequestId,
|
|
20470
|
-
agentOverride: execution?.agentOverride,
|
|
20471
|
-
modelOverride: execution?.modelOverride,
|
|
20472
|
-
effortOverride: execution?.effortOverride,
|
|
20473
|
-
...execution?.sessionIdSpecified ? { sessionId: execution.sessionId } : {},
|
|
20474
|
-
sessionScope: execution?.sessionScope,
|
|
20475
|
-
cwd: execution?.cwd,
|
|
20476
|
-
sessionName: execution?.sessionName,
|
|
20477
|
-
sessionType: execution?.sessionType,
|
|
20478
|
-
visualTools: execution?.visualTools,
|
|
20479
|
-
fileDeliveryTools: execution?.fileDeliveryTools,
|
|
20480
|
-
silent: execution?.silent,
|
|
20481
|
-
bridgeSessionFromHistory: execution?.bridgeSessionFromHistory,
|
|
20482
|
-
peerBridge: execution?.peerBridge,
|
|
20483
|
-
from: execution?.from,
|
|
20484
|
-
threadRootId: execution?.threadRootId,
|
|
20485
|
-
_queryId: request.requestId,
|
|
20486
|
-
_runtimeEpoch: execution?.runtimeEpoch ?? request.topicEpoch,
|
|
20487
|
-
onSettled: () => {
|
|
20488
|
-
completeRuntimeUserTurnRequest(request.topicId, request.requestId, RUNTIME_INSTANCE_ID);
|
|
20489
|
-
}
|
|
20490
|
-
});
|
|
20491
|
-
if (!queryId) {
|
|
20492
|
-
releaseRuntimeUserTurnClaim(request.topicId, request.requestId, RUNTIME_INSTANCE_ID);
|
|
20493
|
-
return;
|
|
20494
|
-
}
|
|
20495
|
-
markRuntimeUserTurnRunning(request.topicId, request.requestId, RUNTIME_INSTANCE_ID, queryId);
|
|
20496
|
-
} finally {
|
|
20497
|
-
durableTurnWorkerBusy = false;
|
|
20498
|
-
}
|
|
20499
|
-
}
|
|
20500
|
-
function startDurableTurnRequestWorker() {
|
|
20501
|
-
if (durableTurnWorker)
|
|
20502
|
-
return () => {};
|
|
20503
|
-
durableTurnWorker = setInterval(() => {
|
|
20504
|
-
drainOneDurableUserTurn();
|
|
20505
|
-
}, 100);
|
|
20506
|
-
durableTurnWorker.unref?.();
|
|
20507
|
-
drainOneDurableUserTurn();
|
|
20508
|
-
return () => {
|
|
20509
|
-
if (!durableTurnWorker)
|
|
20510
|
-
return;
|
|
20511
|
-
clearInterval(durableTurnWorker);
|
|
20512
|
-
durableTurnWorker = null;
|
|
20513
|
-
};
|
|
20514
|
-
}
|
|
20515
19635
|
function startAiTurn(params) {
|
|
20516
19636
|
const storedTopic = getTopic(params.topic.id);
|
|
20517
19637
|
if (!storedTopic || !storedTopic.agent && !params.agentOverride) {
|
|
@@ -20580,7 +19700,7 @@ function startAiTurn(params) {
|
|
|
20580
19700
|
const askReplySources = params.askReplySources;
|
|
20581
19701
|
const sessionRetried = params._sessionRetried === true;
|
|
20582
19702
|
const emptyResponseRetried = params._emptyResponseRetried === true;
|
|
20583
|
-
const queryId = asTurnId(params._queryId ??
|
|
19703
|
+
const queryId = asTurnId(params._queryId ?? randomUUID18());
|
|
20584
19704
|
const roomId = turnConcurrency === "isolated" ? isolatedTurnRoomId(topicId, queryId) : asTurnSlotKey(topicId);
|
|
20585
19705
|
const currentRuntimeEpoch = getRuntimeTopicEpoch(topic.id);
|
|
20586
19706
|
const runtimeEpoch = params._runtimeEpoch ?? currentRuntimeEpoch;
|
|
@@ -20691,7 +19811,7 @@ function startAiTurn(params) {
|
|
|
20691
19811
|
if (decision.action === "abort-replace") {
|
|
20692
19812
|
const running = decision.running;
|
|
20693
19813
|
if (isUserOrigin(running.origin) && !sameTurnActor(running.actorUserId, params.actorUserId)) {
|
|
20694
|
-
const
|
|
19814
|
+
const queuedQueryId = waitToStartRemoteUserTurn({
|
|
20695
19815
|
...params,
|
|
20696
19816
|
topic,
|
|
20697
19817
|
prompt,
|
|
@@ -20703,9 +19823,9 @@ function startAiTurn(params) {
|
|
|
20703
19823
|
_durableRequestIds: durableRequestIds,
|
|
20704
19824
|
_runtimeEpoch: runtimeEpoch
|
|
20705
19825
|
}, queryId);
|
|
20706
|
-
announceQueuedUserTurn({ ...params, topic },
|
|
20707
|
-
logger.info({ topicId, queryId:
|
|
20708
|
-
return
|
|
19826
|
+
announceQueuedUserTurn({ ...params, topic }, queuedQueryId);
|
|
19827
|
+
logger.info({ topicId, queryId: queuedQueryId, runningQueryId: running.queryId }, "ai: user turn from another actor queued behind the running turn");
|
|
19828
|
+
return queuedQueryId;
|
|
20709
19829
|
}
|
|
20710
19830
|
let omitRequestIds;
|
|
20711
19831
|
if (isUserOrigin(running.origin)) {
|
|
@@ -21351,7 +20471,7 @@ function triggerTopicAiTurn(topicId, userId, prompt, agentType, opts) {
|
|
|
21351
20471
|
if (!opts?.silent && !opts?.hideInjectMessage) {
|
|
21352
20472
|
const now = new Date().toISOString();
|
|
21353
20473
|
const injectMsg = {
|
|
21354
|
-
id: opts?.requestId ? `tell-${opts.requestId}` : `tell-${
|
|
20474
|
+
id: opts?.requestId ? `tell-${opts.requestId}` : `tell-${randomUUID18()}`,
|
|
21355
20475
|
topicId,
|
|
21356
20476
|
authorId: opts?.injectAuthorId ?? userId,
|
|
21357
20477
|
sourceAdapter: opts?.injectSourceAdapter,
|
|
@@ -21408,7 +20528,7 @@ function triggerTopicAiTurn(topicId, userId, prompt, agentType, opts) {
|
|
|
21408
20528
|
from: opts?.from
|
|
21409
20529
|
});
|
|
21410
20530
|
}
|
|
21411
|
-
var PLAYWRIGHT_UNAVAILABLE_NOTICE_COOLDOWN_MS, ASK_REPLY_INJECT_BATCH_MS = 500, playwrightUnavailableNoticeAt, askReplyInjectBatcher, remoteInjectWaiters
|
|
20531
|
+
var PLAYWRIGHT_UNAVAILABLE_NOTICE_COOLDOWN_MS, ASK_REPLY_INJECT_BATCH_MS = 500, playwrightUnavailableNoticeAt, askReplyInjectBatcher, remoteInjectWaiters;
|
|
21412
20532
|
var init_turn_runner = __esm(async () => {
|
|
21413
20533
|
init_manager();
|
|
21414
20534
|
init_constants();
|
|
@@ -21473,11 +20593,6 @@ var init_turn_runner = __esm(async () => {
|
|
|
21473
20593
|
});
|
|
21474
20594
|
|
|
21475
20595
|
// ../../packages/core/src/agents/auth-check.ts
|
|
21476
|
-
var exports_auth_check = {};
|
|
21477
|
-
__export(exports_auth_check, {
|
|
21478
|
-
checkAgentModelAuth: () => checkAgentModelAuth,
|
|
21479
|
-
checkAgentAuth: () => checkAgentAuth
|
|
21480
|
-
});
|
|
21481
20596
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
21482
20597
|
import { existsSync as existsSync25 } from "fs";
|
|
21483
20598
|
import { homedir as homedir8, platform } from "os";
|
|
@@ -21589,8 +20704,8 @@ function createSubagentLifecycle(host) {
|
|
|
21589
20704
|
maxLiveChildrenPerParent: host.config.limits?.maxLiveChildrenPerParent ?? MAX_LIVE_CHILDREN_PER_PARENT,
|
|
21590
20705
|
maxPreparedChildrenPerParent: host.config.limits?.maxPreparedChildrenPerParent ?? MAX_PREPARED_CHILDREN_PER_PARENT
|
|
21591
20706
|
});
|
|
21592
|
-
for (const [name,
|
|
21593
|
-
if (!Number.isInteger(
|
|
20707
|
+
for (const [name, value] of Object.entries(limits)) {
|
|
20708
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
21594
20709
|
throw new Error(`subagent lifecycle ${name} must be a positive integer`);
|
|
21595
20710
|
}
|
|
21596
20711
|
}
|
|
@@ -21641,29 +20756,29 @@ function createSubagentLifecycle(host) {
|
|
|
21641
20756
|
}
|
|
21642
20757
|
function computeSubagentDepth(topicId) {
|
|
21643
20758
|
let depth = 0;
|
|
21644
|
-
let
|
|
20759
|
+
let current = host.storage.getTopic(topicId);
|
|
21645
20760
|
const visited = new Set;
|
|
21646
|
-
while (
|
|
21647
|
-
if (visited.has(
|
|
20761
|
+
while (current) {
|
|
20762
|
+
if (visited.has(current.id))
|
|
21648
20763
|
return limits.maxDepth;
|
|
21649
|
-
visited.add(
|
|
21650
|
-
if (
|
|
20764
|
+
visited.add(current.id);
|
|
20765
|
+
if (current.isSubagent)
|
|
21651
20766
|
depth += 1;
|
|
21652
|
-
if (!
|
|
20767
|
+
if (!current.parentTopicId || current.parentTopicId === current.id)
|
|
21653
20768
|
break;
|
|
21654
|
-
|
|
20769
|
+
current = host.storage.getTopic(current.parentTopicId);
|
|
21655
20770
|
}
|
|
21656
20771
|
return depth;
|
|
21657
20772
|
}
|
|
21658
|
-
function
|
|
20773
|
+
function canSpawnSubagentsFromTopic(topicId) {
|
|
21659
20774
|
const topic = host.storage.getTopic(topicId);
|
|
21660
20775
|
return topic?.kind === "agent" && computeSubagentDepth(topicId) < limits.maxDepth;
|
|
21661
20776
|
}
|
|
21662
20777
|
function patchSubagentCard(parentTopicId, cardMessageId, patch) {
|
|
21663
|
-
const
|
|
21664
|
-
if (!
|
|
20778
|
+
const current = host.storage.getMessage(parentTopicId, cardMessageId)?.subagentCard;
|
|
20779
|
+
if (!current)
|
|
21665
20780
|
return;
|
|
21666
|
-
const next = { ...
|
|
20781
|
+
const next = { ...current, ...patch };
|
|
21667
20782
|
const editedAt = host.runtime.now();
|
|
21668
20783
|
if (!host.storage.updateSubagentCard(parentTopicId, cardMessageId, next, editedAt))
|
|
21669
20784
|
return;
|
|
@@ -21683,7 +20798,7 @@ function createSubagentLifecycle(host) {
|
|
|
21683
20798
|
patchSubagentCard(watch.parentTopicId, watch.cardMessageId, { status: "running" });
|
|
21684
20799
|
}
|
|
21685
20800
|
}
|
|
21686
|
-
function
|
|
20801
|
+
function takeSubagentWatch(queryId) {
|
|
21687
20802
|
const childTopicId = childByQueryId.get(queryId);
|
|
21688
20803
|
if (!childTopicId)
|
|
21689
20804
|
return recoverPersistedSubagentWatch(queryId);
|
|
@@ -21727,7 +20842,7 @@ function createSubagentLifecycle(host) {
|
|
|
21727
20842
|
if (watch.queryId)
|
|
21728
20843
|
childByQueryId.delete(watch.queryId);
|
|
21729
20844
|
}
|
|
21730
|
-
function
|
|
20845
|
+
function cancelSubagentWatchForDeletedTopic(childTopicId) {
|
|
21731
20846
|
const watch = watchesByChild.get(childTopicId);
|
|
21732
20847
|
if (!watch)
|
|
21733
20848
|
return;
|
|
@@ -21770,7 +20885,7 @@ function createSubagentLifecycle(host) {
|
|
|
21770
20885
|
}
|
|
21771
20886
|
}
|
|
21772
20887
|
}
|
|
21773
|
-
async function
|
|
20888
|
+
async function settleSubagentSuccess(watch, finalText) {
|
|
21774
20889
|
const summary = finalText.replace(/\s+/g, " ").trim().slice(0, RESULT_SUMMARY_CHARS);
|
|
21775
20890
|
try {
|
|
21776
20891
|
patchSubagentCard(watch.parentTopicId, watch.cardMessageId, {
|
|
@@ -21788,8 +20903,8 @@ function createSubagentLifecycle(host) {
|
|
|
21788
20903
|
${finalText || "(no text response)"}`, "done");
|
|
21789
20904
|
}
|
|
21790
20905
|
}
|
|
21791
|
-
async function
|
|
21792
|
-
const watch =
|
|
20906
|
+
async function settleSubagentFailure(queryId, reason) {
|
|
20907
|
+
const watch = takeSubagentWatch(queryId);
|
|
21793
20908
|
if (!watch)
|
|
21794
20909
|
return;
|
|
21795
20910
|
try {
|
|
@@ -21836,7 +20951,7 @@ spawn_subagent\uB85C \uC704\uC784\uD55C \uC791\uC5C5\uC774 \uC2E4\uD328\uD588\uC
|
|
|
21836
20951
|
function findSubagentCardMessage(childTopicId) {
|
|
21837
20952
|
return host.storage.listSubagentMessages().filter((message) => message.subagentCard?.subagentTopicId === childTopicId).at(-1);
|
|
21838
20953
|
}
|
|
21839
|
-
function
|
|
20954
|
+
function subagentReportMode(childTopicId) {
|
|
21840
20955
|
return host.storage.getTopic(childTopicId)?.subagentReportMode ?? findSubagentCardMessage(childTopicId)?.subagentCard?.reportMode ?? "auto";
|
|
21841
20956
|
}
|
|
21842
20957
|
async function startSubagentCard(ctx, cardMessage) {
|
|
@@ -22044,7 +21159,7 @@ ${card.task}${reportInstruction}`;
|
|
|
22044
21159
|
for (const siblings of byParent.values()) {
|
|
22045
21160
|
siblings.sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id));
|
|
22046
21161
|
}
|
|
22047
|
-
const
|
|
21162
|
+
const descendants = [];
|
|
22048
21163
|
const visited = new Set([ctx.topicId]);
|
|
22049
21164
|
const visit = (parentId) => {
|
|
22050
21165
|
for (const child of byParent.get(parentId) ?? []) {
|
|
@@ -22054,12 +21169,12 @@ ${card.task}${reportInstruction}`;
|
|
|
22054
21169
|
if (!child.participants.some((participant) => participant.userId === rootOwnerId && participant.role === "owner")) {
|
|
22055
21170
|
continue;
|
|
22056
21171
|
}
|
|
22057
|
-
|
|
21172
|
+
descendants.push(child);
|
|
22058
21173
|
visit(child.id);
|
|
22059
21174
|
}
|
|
22060
21175
|
};
|
|
22061
21176
|
visit(ctx.topicId);
|
|
22062
|
-
return
|
|
21177
|
+
return descendants;
|
|
22063
21178
|
})() : [];
|
|
22064
21179
|
const children = actorScope ? descendants.filter((child) => actorScope.visible.has(child.id)) : descendants;
|
|
22065
21180
|
return {
|
|
@@ -22083,10 +21198,10 @@ ${card.task}${reportInstruction}`;
|
|
|
22083
21198
|
return card?.status ?? "unknown";
|
|
22084
21199
|
}
|
|
22085
21200
|
function listMemoryTopicNames(ctx) {
|
|
22086
|
-
const
|
|
22087
|
-
if (!
|
|
21201
|
+
const current = host.storage.getTopic(ctx.topicId);
|
|
21202
|
+
if (!current)
|
|
22088
21203
|
return { error: `Error: topic '${ctx.topicId}' not found.` };
|
|
22089
|
-
if (!
|
|
21204
|
+
if (!current.participants.some((participant) => participant.userId === ctx.userId)) {
|
|
22090
21205
|
return { error: "Error: user is not a member of this topic." };
|
|
22091
21206
|
}
|
|
22092
21207
|
const sources = new Map;
|
|
@@ -22274,13 +21389,13 @@ ${card.task}${reportInstruction}`;
|
|
|
22274
21389
|
}
|
|
22275
21390
|
return {
|
|
22276
21391
|
computeSubagentDepth,
|
|
22277
|
-
canSpawnSubagentsFromTopic
|
|
22278
|
-
takeSubagentWatch
|
|
22279
|
-
cancelSubagentWatchForDeletedTopic
|
|
22280
|
-
settleSubagentSuccess
|
|
22281
|
-
settleSubagentFailure
|
|
21392
|
+
canSpawnSubagentsFromTopic,
|
|
21393
|
+
takeSubagentWatch,
|
|
21394
|
+
cancelSubagentWatchForDeletedTopic,
|
|
21395
|
+
settleSubagentSuccess,
|
|
21396
|
+
settleSubagentFailure,
|
|
22282
21397
|
sweepStaleSubagentCards,
|
|
22283
|
-
subagentReportMode
|
|
21398
|
+
subagentReportMode,
|
|
22284
21399
|
createSubagentManagementToolDefinitions,
|
|
22285
21400
|
createSpawnSubagentToolDefinition,
|
|
22286
21401
|
createPrepareSubagentToolDefinition
|
|
@@ -22327,9 +21442,9 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
22327
21442
|
},
|
|
22328
21443
|
topic: {
|
|
22329
21444
|
async createDerived(input) {
|
|
22330
|
-
|
|
21445
|
+
await init_derive();
|
|
22331
21446
|
try {
|
|
22332
|
-
const topic = await
|
|
21447
|
+
const topic = await createDerivedTopic(input.parentTopicId, input.userId, false, {
|
|
22333
21448
|
name: input.name,
|
|
22334
21449
|
subagent: {
|
|
22335
21450
|
agent: input.agent,
|
|
@@ -22339,30 +21454,30 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
22339
21454
|
});
|
|
22340
21455
|
return { ok: true, topic };
|
|
22341
21456
|
} catch (error) {
|
|
22342
|
-
if (error instanceof
|
|
21457
|
+
if (error instanceof TopicTitleConflictError) {
|
|
22343
21458
|
return { ok: false, reason: "title-conflict", message: error.message };
|
|
22344
21459
|
}
|
|
22345
|
-
if (error instanceof
|
|
21460
|
+
if (error instanceof TopicDeriveBusyError)
|
|
22346
21461
|
return { ok: false, reason: "busy" };
|
|
22347
21462
|
throw error;
|
|
22348
21463
|
}
|
|
22349
21464
|
},
|
|
22350
21465
|
async delete(topic, userId) {
|
|
22351
|
-
|
|
22352
|
-
await
|
|
21466
|
+
await init_lifecycle();
|
|
21467
|
+
await deleteTopicCascade(topic, userId);
|
|
22353
21468
|
}
|
|
22354
21469
|
},
|
|
22355
21470
|
task: {
|
|
22356
21471
|
async dispatch(input) {
|
|
22357
|
-
|
|
22358
|
-
|
|
22359
|
-
const queryId =
|
|
21472
|
+
await init_turn_runner();
|
|
21473
|
+
await init_active_rooms();
|
|
21474
|
+
const queryId = triggerTopicAiTurn(input.child.id, input.userId, input.prompt, undefined, {
|
|
22360
21475
|
origin: `subagent-task:${input.parent.title}`,
|
|
22361
21476
|
requestId: input.requestId,
|
|
22362
21477
|
injectAuthorId: "ai",
|
|
22363
21478
|
onDispatched: input.onDispatched
|
|
22364
21479
|
});
|
|
22365
|
-
return { accepted: Boolean(queryId ||
|
|
21480
|
+
return { accepted: Boolean(queryId || getRoomQuery(input.child.id)) };
|
|
22366
21481
|
}
|
|
22367
21482
|
},
|
|
22368
21483
|
sessionCommunication: {
|
|
@@ -22370,16 +21485,16 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
22370
21485
|
const parent = getTopic(watch.parentTopicId);
|
|
22371
21486
|
if (!parent)
|
|
22372
21487
|
return true;
|
|
22373
|
-
|
|
22374
|
-
const queryId = parent.agent ?
|
|
21488
|
+
await init_turn_runner();
|
|
21489
|
+
const queryId = parent.agent ? triggerTopicAiTurn(watch.parentTopicId, watch.userId, prompt, undefined, {
|
|
22375
21490
|
origin: `subagent:${watch.name}`,
|
|
22376
21491
|
requestId,
|
|
22377
21492
|
hideInjectMessage: true
|
|
22378
21493
|
}) : null;
|
|
22379
21494
|
if (queryId)
|
|
22380
21495
|
return true;
|
|
22381
|
-
|
|
22382
|
-
return Boolean(parent.agent &&
|
|
21496
|
+
await init_active_rooms();
|
|
21497
|
+
return Boolean(parent.agent && interSessionQueue.hasRequest(parent.id, requestId));
|
|
22383
21498
|
},
|
|
22384
21499
|
listTellTargetIds: listSubagentTellTargetIds,
|
|
22385
21500
|
grantTellTarget: grantSubagentTellTarget,
|
|
@@ -22408,19 +21523,19 @@ var init_spawn_subagent = __esm(async () => {
|
|
|
22408
21523
|
async resolveAgentModel({ context, agent, model, hasOverride }) {
|
|
22409
21524
|
let resolvedModel = model;
|
|
22410
21525
|
if (model) {
|
|
22411
|
-
|
|
22412
|
-
|
|
22413
|
-
const registry =
|
|
21526
|
+
await Promise.resolve().then(() => init_model_catalog());
|
|
21527
|
+
await init_registry();
|
|
21528
|
+
const registry = getRegistry(agent);
|
|
22414
21529
|
if (!registry.validateModel(model)) {
|
|
22415
21530
|
return { error: `Error: model '${model}' is not valid for agent '${agent}'.` };
|
|
22416
21531
|
}
|
|
22417
|
-
resolvedModel =
|
|
21532
|
+
resolvedModel = resolveModelForAgent(agent, model, registry);
|
|
22418
21533
|
}
|
|
22419
21534
|
if (hasOverride) {
|
|
22420
|
-
|
|
22421
|
-
|
|
22422
|
-
const targetModel = resolvedModel ??
|
|
22423
|
-
const auth =
|
|
21535
|
+
await init_auth_check();
|
|
21536
|
+
await init_registry();
|
|
21537
|
+
const targetModel = resolvedModel ?? getRegistry(agent).defaultModel;
|
|
21538
|
+
const auth = checkAgentModelAuth(agent, targetModel, undefined, context.userId);
|
|
22424
21539
|
if (!auth.ok) {
|
|
22425
21540
|
return { error: `Error: agent '${agent}' is not available: ${auth.error}` };
|
|
22426
21541
|
}
|
|
@@ -22480,11 +21595,11 @@ function parseSessionCommContext(args, defaults) {
|
|
|
22480
21595
|
actorTopicScope = parsed;
|
|
22481
21596
|
}
|
|
22482
21597
|
const maxAgeValue = value(args, "actor-topic-scope-max-age-ms");
|
|
22483
|
-
let
|
|
21598
|
+
let actorTopicScopeMaxAgeMs;
|
|
22484
21599
|
if (maxAgeValue !== undefined) {
|
|
22485
21600
|
if (!/^\d+$/.test(maxAgeValue))
|
|
22486
21601
|
throw new Error(`Invalid --actor-topic-scope-max-age-ms arg`);
|
|
22487
|
-
|
|
21602
|
+
actorTopicScopeMaxAgeMs = Math.min(Number(maxAgeValue), ACTOR_TOPIC_SCOPE_MAX_AGE_CEILING_MS);
|
|
22488
21603
|
}
|
|
22489
21604
|
const grantValue = value(args, "remote-session-grant");
|
|
22490
21605
|
let remoteSession;
|
|
@@ -22498,7 +21613,7 @@ function parseSessionCommContext(args, defaults) {
|
|
|
22498
21613
|
userId: value(args, "user-id") ?? defaults.userId,
|
|
22499
21614
|
actorUserId: value(args, "actor-user-id") || undefined,
|
|
22500
21615
|
...actorTopicScope ? { actorTopicScope } : {},
|
|
22501
|
-
...
|
|
21616
|
+
...actorTopicScopeMaxAgeMs !== undefined ? { actorTopicScopeMaxAgeMs } : {},
|
|
22502
21617
|
...remoteSession ? { remoteSession } : {},
|
|
22503
21618
|
currentTopic: value(args, "topic") ?? "",
|
|
22504
21619
|
currentTopicId: value(args, "topic-id") || undefined,
|
|
@@ -22937,9 +22052,9 @@ function safeExt(obj, keys, fallback) {
|
|
|
22937
22052
|
if (!obj || typeof obj !== "object")
|
|
22938
22053
|
return fallback;
|
|
22939
22054
|
for (const key of keys) {
|
|
22940
|
-
const
|
|
22941
|
-
if (
|
|
22942
|
-
return
|
|
22055
|
+
const value = obj[key];
|
|
22056
|
+
if (value !== undefined && value !== null)
|
|
22057
|
+
return value;
|
|
22943
22058
|
}
|
|
22944
22059
|
return fallback;
|
|
22945
22060
|
}
|
|
@@ -22949,14 +22064,14 @@ function topicNameFrom(topicIdStr) {
|
|
|
22949
22064
|
function slugify(topic) {
|
|
22950
22065
|
return wikiSummarySlug(topic);
|
|
22951
22066
|
}
|
|
22952
|
-
function normalizeSearchText(
|
|
22953
|
-
return
|
|
22067
|
+
function normalizeSearchText(value) {
|
|
22068
|
+
return value.toLowerCase().replaceAll(/[^a-z0-9\uAC00-\uD7A3]+/g, " ").trim().replaceAll(/\s+/g, " ");
|
|
22954
22069
|
}
|
|
22955
|
-
function compactSearchText(
|
|
22956
|
-
return normalizeSearchText(
|
|
22070
|
+
function compactSearchText(value) {
|
|
22071
|
+
return normalizeSearchText(value).replaceAll(" ", "");
|
|
22957
22072
|
}
|
|
22958
|
-
function trigrams(
|
|
22959
|
-
const compact = compactSearchText(
|
|
22073
|
+
function trigrams(value) {
|
|
22074
|
+
const compact = compactSearchText(value);
|
|
22960
22075
|
if (compact.length < 3)
|
|
22961
22076
|
return new Set(compact ? [compact] : []);
|
|
22962
22077
|
const result = new Set;
|
|
@@ -23044,14 +22159,14 @@ var SEARCH_RECENCY_TERMS = new Set([
|
|
|
23044
22159
|
"\uCD5C\uCD08",
|
|
23045
22160
|
"\uC624\uB798\uB41C"
|
|
23046
22161
|
]);
|
|
23047
|
-
function meaningfulSearchTokens(
|
|
23048
|
-
return normalizeSearchText(
|
|
22162
|
+
function meaningfulSearchTokens(value) {
|
|
22163
|
+
return normalizeSearchText(value).split(" ").filter((token) => (token.length >= 2 || /^\d+$/.test(token)) && !SEARCH_STOP_WORDS.has(token));
|
|
23049
22164
|
}
|
|
23050
22165
|
function canonicalSearchToken(token) {
|
|
23051
22166
|
return token.length > 4 && token.endsWith("s") ? token.slice(0, -1) : token;
|
|
23052
22167
|
}
|
|
23053
|
-
function canonicalSearchTokens(
|
|
23054
|
-
return meaningfulSearchTokens(
|
|
22168
|
+
function canonicalSearchTokens(value) {
|
|
22169
|
+
return meaningfulSearchTokens(value).map(canonicalSearchToken);
|
|
23055
22170
|
}
|
|
23056
22171
|
function countToken(tokens, token) {
|
|
23057
22172
|
let count = 0;
|
|
@@ -23324,11 +22439,11 @@ function wikiQuery(args) {
|
|
|
23324
22439
|
const runnerUp = indexCandidates[1];
|
|
23325
22440
|
const ambiguous = strongestIndex.keyScore < 100 && runnerUp !== undefined && runnerUp.score >= strongestIndex.score * 0.9;
|
|
23326
22441
|
if (ambiguous) {
|
|
23327
|
-
const
|
|
22442
|
+
const lines = ["Found 2 ambiguous wiki candidates:", ""];
|
|
23328
22443
|
for (const { candidate, score } of [strongestIndex, runnerUp]) {
|
|
23329
|
-
|
|
22444
|
+
lines.push(`- kind: ${candidate.kind}`, ` key: ${candidate.key}`, ` score: ${score.toFixed(2)}`, ` description: ${candidate.description || "(none)"}`, ...candidate.date ? [` date: ${candidate.date}`] : []);
|
|
23330
22445
|
}
|
|
23331
|
-
return { content: [{ type: "text", text:
|
|
22446
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
23332
22447
|
`) }] };
|
|
23333
22448
|
}
|
|
23334
22449
|
const lines = ["Found 1 wiki candidate:", ""];
|
|
@@ -23744,14 +22859,14 @@ function wikiLastConversation(args) {
|
|
|
23744
22859
|
const raw = readFileSync3(actualPath, "utf-8");
|
|
23745
22860
|
const lines = raw.trim().split(`
|
|
23746
22861
|
`).filter(Boolean);
|
|
23747
|
-
const
|
|
22862
|
+
const turns = [];
|
|
23748
22863
|
let currentUser = "";
|
|
23749
22864
|
let currentAssistant = "";
|
|
23750
22865
|
const truncate = (s, max) => s.length > max ? `${s.slice(0, max)}
|
|
23751
22866
|
...(truncated)` : s;
|
|
23752
22867
|
const flush = () => {
|
|
23753
22868
|
if (currentUser || currentAssistant) {
|
|
23754
|
-
|
|
22869
|
+
turns.push(`**User**: ${truncate(currentUser || "(no prompt)", 500)}
|
|
23755
22870
|
|
|
23756
22871
|
**Assistant**: ${truncate(currentAssistant || "(no response)", 1000)}`);
|
|
23757
22872
|
currentUser = "";
|
|
@@ -23770,12 +22885,12 @@ function wikiLastConversation(args) {
|
|
|
23770
22885
|
} catch {}
|
|
23771
22886
|
}
|
|
23772
22887
|
flush();
|
|
23773
|
-
if (
|
|
22888
|
+
if (turns.length === 0) {
|
|
23774
22889
|
return {
|
|
23775
22890
|
content: [{ type: "text", text: `Archive file found but no valid entries.` }]
|
|
23776
22891
|
};
|
|
23777
22892
|
}
|
|
23778
|
-
const recent =
|
|
22893
|
+
const recent = turns.slice(-maxTurns);
|
|
23779
22894
|
return {
|
|
23780
22895
|
content: [
|
|
23781
22896
|
{
|
|
@@ -24002,22 +23117,22 @@ function wikiWrite(args) {
|
|
|
24002
23117
|
};
|
|
24003
23118
|
}
|
|
24004
23119
|
const { existed } = writeArticleDocument(slugResult.slug, content);
|
|
24005
|
-
const
|
|
23120
|
+
const link = indexRowOrPartialWrite("article", {
|
|
24006
23121
|
kind: "article",
|
|
24007
23122
|
slug: slugResult.slug,
|
|
24008
23123
|
description,
|
|
24009
23124
|
date: rawDate ?? today,
|
|
24010
23125
|
section: section.trim()
|
|
24011
23126
|
});
|
|
24012
|
-
if (typeof
|
|
24013
|
-
return
|
|
23127
|
+
if (typeof link !== "string")
|
|
23128
|
+
return link;
|
|
24014
23129
|
const searched = indexWikiSearchDocument("article", slugResult.slug, content);
|
|
24015
23130
|
return {
|
|
24016
23131
|
content: [
|
|
24017
23132
|
{
|
|
24018
23133
|
type: "text",
|
|
24019
23134
|
text: `Saved article: articles/${slugResult.slug}.md (${existed ? "updated" : "created"})
|
|
24020
|
-
Indexed: ${
|
|
23135
|
+
Indexed: ${link}` + (searched ? "" : `
|
|
24021
23136
|
${SEARCH_CACHE_SKIPPED_NOTE}`)
|
|
24022
23137
|
}
|
|
24023
23138
|
]
|
|
@@ -24029,22 +23144,22 @@ ${SEARCH_CACHE_SKIPPED_NOTE}`)
|
|
|
24029
23144
|
}
|
|
24030
23145
|
if (rawKind === "summary") {
|
|
24031
23146
|
const dateStr = rawDate ?? today;
|
|
24032
|
-
const
|
|
24033
|
-
const
|
|
23147
|
+
const written = writeSummaryDocument(topic, content, dateStr);
|
|
23148
|
+
const link = indexRowOrPartialWrite("summary", {
|
|
24034
23149
|
kind: "summary",
|
|
24035
|
-
slug:
|
|
23150
|
+
slug: written.slug,
|
|
24036
23151
|
description,
|
|
24037
23152
|
date: dateStr
|
|
24038
23153
|
});
|
|
24039
|
-
if (typeof
|
|
24040
|
-
return
|
|
24041
|
-
const searched = indexWikiSearchDocument("summary",
|
|
23154
|
+
if (typeof link !== "string")
|
|
23155
|
+
return link;
|
|
23156
|
+
const searched = indexWikiSearchDocument("summary", written.slug, content);
|
|
24042
23157
|
return {
|
|
24043
23158
|
content: [
|
|
24044
23159
|
{
|
|
24045
23160
|
type: "text",
|
|
24046
|
-
text: `Saved summary: summaries/${
|
|
24047
|
-
Indexed: ${
|
|
23161
|
+
text: `Saved summary: summaries/${written.slug}.md
|
|
23162
|
+
Indexed: ${link}` + (written.sqliteUpdated ? `
|
|
24048
23163
|
SQLite latest-summary also updated.` : "") + (searched ? "" : `
|
|
24049
23164
|
${SEARCH_CACHE_SKIPPED_NOTE}`)
|
|
24050
23165
|
}
|
|
@@ -24534,7 +23649,7 @@ function signalProcessTree(child, signal) {
|
|
|
24534
23649
|
}
|
|
24535
23650
|
}
|
|
24536
23651
|
function spawnCapture(cmd, args, timeoutMs, signal, env) {
|
|
24537
|
-
return new Promise((
|
|
23652
|
+
return new Promise((resolve, reject) => {
|
|
24538
23653
|
const child = spawn4(cmd, args, {
|
|
24539
23654
|
env: env ?? process.env,
|
|
24540
23655
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -24593,7 +23708,7 @@ function spawnCapture(cmd, args, timeoutMs, signal, env) {
|
|
|
24593
23708
|
if (killTimer)
|
|
24594
23709
|
clearTimeout(killTimer);
|
|
24595
23710
|
if (code === 0)
|
|
24596
|
-
|
|
23711
|
+
resolve({ stdout, stderr });
|
|
24597
23712
|
else
|
|
24598
23713
|
reject(new Error(stderr.trim() || `${cmd} exited with ${code ?? exitSignal}`));
|
|
24599
23714
|
});
|
|
@@ -24671,11 +23786,11 @@ async function checkMaestro(model, timeoutMs, signal) {
|
|
|
24671
23786
|
const remaining = deadline - Date.now();
|
|
24672
23787
|
if (remaining <= 0)
|
|
24673
23788
|
throw new Error("timeout");
|
|
24674
|
-
const eventResult = await new Promise((
|
|
23789
|
+
const eventResult = await new Promise((resolve, reject) => {
|
|
24675
23790
|
const timeout = setTimeout(() => reject(new Error("timeout")), remaining);
|
|
24676
23791
|
const onAbort = () => reject(new Error("aborted"));
|
|
24677
23792
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
24678
|
-
activeIterator.next().then(
|
|
23793
|
+
activeIterator.next().then(resolve, reject).finally(() => {
|
|
24679
23794
|
clearTimeout(timeout);
|
|
24680
23795
|
signal.removeEventListener("abort", onAbort);
|
|
24681
23796
|
});
|
|
@@ -24714,7 +23829,7 @@ var checkWaiters = [];
|
|
|
24714
23829
|
var activeCheckAllUsers = new Set;
|
|
24715
23830
|
async function withCheckSlot(operation) {
|
|
24716
23831
|
if (activeChecks >= MAX_CONCURRENT_CHECKS) {
|
|
24717
|
-
await new Promise((
|
|
23832
|
+
await new Promise((resolve) => checkWaiters.push(resolve));
|
|
24718
23833
|
}
|
|
24719
23834
|
activeChecks += 1;
|
|
24720
23835
|
try {
|
|
@@ -24818,8 +23933,8 @@ var DEFAULT_MAX_TOTAL_BYTES = 512 * 1024;
|
|
|
24818
23933
|
var DEFAULT_MAX_CHUNK_BYTES = 64 * 1024;
|
|
24819
23934
|
var DEFAULT_LINE_LIMIT = 300;
|
|
24820
23935
|
var MAX_LINE_LIMIT = 500;
|
|
24821
|
-
function positiveInt(
|
|
24822
|
-
return Number.isFinite(
|
|
23936
|
+
function positiveInt(value, fallback) {
|
|
23937
|
+
return Number.isFinite(value) && value && value > 0 ? Math.floor(value) : fallback;
|
|
24823
23938
|
}
|
|
24824
23939
|
function fitUtf8(text, maxBytes) {
|
|
24825
23940
|
if (Buffer.byteLength(text, "utf8") <= maxBytes)
|
|
@@ -25502,18 +24617,18 @@ function createTaskMcpServer(context, host = defaultTaskMcpHost) {
|
|
|
25502
24617
|
if (guard)
|
|
25503
24618
|
return guard;
|
|
25504
24619
|
try {
|
|
25505
|
-
const
|
|
25506
|
-
const { tasks
|
|
24620
|
+
const current = host.readTasks(context.userId, scopeKey);
|
|
24621
|
+
const { tasks, created } = createTasks(current, inputs.map((task) => ({
|
|
25507
24622
|
subject: task.subject,
|
|
25508
24623
|
activeForm: task.active_form,
|
|
25509
24624
|
blockedBy: task.blocked_by,
|
|
25510
24625
|
owner: task.owner
|
|
25511
24626
|
})));
|
|
25512
|
-
host.writeTasks(context.userId, scopeKey,
|
|
24627
|
+
host.writeTasks(context.userId, scopeKey, tasks);
|
|
25513
24628
|
const ids = created.map((task) => `#${task.id}`).join(", ");
|
|
25514
24629
|
return mcpOk(`${created.length} task(s) created (${ids})
|
|
25515
24630
|
|
|
25516
|
-
${renderTaskList(
|
|
24631
|
+
${renderTaskList(tasks)}`);
|
|
25517
24632
|
} catch (error) {
|
|
25518
24633
|
return mcpError(`task_create failed: ${errMsg(error)}`);
|
|
25519
24634
|
}
|
|
@@ -25532,8 +24647,8 @@ ${renderTaskList(tasks2)}`);
|
|
|
25532
24647
|
if (guard)
|
|
25533
24648
|
return guard;
|
|
25534
24649
|
try {
|
|
25535
|
-
const
|
|
25536
|
-
const { tasks
|
|
24650
|
+
const current = host.readTasks(context.userId, scopeKey);
|
|
24651
|
+
const { tasks, missing } = updateTasks(current, updates.map((update) => ({
|
|
25537
24652
|
id: update.id,
|
|
25538
24653
|
status: update.status,
|
|
25539
24654
|
subject: update.subject,
|
|
@@ -25541,10 +24656,10 @@ ${renderTaskList(tasks2)}`);
|
|
|
25541
24656
|
blockedBy: update.blocked_by,
|
|
25542
24657
|
owner: update.owner
|
|
25543
24658
|
})));
|
|
25544
|
-
host.writeTasks(context.userId, scopeKey,
|
|
24659
|
+
host.writeTasks(context.userId, scopeKey, tasks);
|
|
25545
24660
|
const warning = missing.length > 0 ? `
|
|
25546
24661
|
Missing ids ignored: ${missing.join(", ")}` : "";
|
|
25547
|
-
return mcpOk(`${renderTaskList(
|
|
24662
|
+
return mcpOk(`${renderTaskList(tasks)}${warning}`);
|
|
25548
24663
|
} catch (error) {
|
|
25549
24664
|
return mcpError(`task_update failed: ${errMsg(error)}`);
|
|
25550
24665
|
}
|
|
@@ -25582,12 +24697,12 @@ Missing ids ignored: ${missing.join(", ")}` : "";
|
|
|
25582
24697
|
if (!all && (!ids || ids.length === 0))
|
|
25583
24698
|
return mcpError("Provide ids or all=true.");
|
|
25584
24699
|
try {
|
|
25585
|
-
const
|
|
25586
|
-
const { tasks
|
|
25587
|
-
host.writeTasks(context.userId, scopeKey,
|
|
24700
|
+
const current = host.readTasks(context.userId, scopeKey);
|
|
24701
|
+
const { tasks, removed } = deleteTasks(current, { ids, all });
|
|
24702
|
+
host.writeTasks(context.userId, scopeKey, tasks);
|
|
25588
24703
|
return mcpOk(`${removed} task(s) deleted
|
|
25589
24704
|
|
|
25590
|
-
${renderTaskList(
|
|
24705
|
+
${renderTaskList(tasks)}`);
|
|
25591
24706
|
} catch (error) {
|
|
25592
24707
|
return mcpError(`task_delete failed: ${errMsg(error)}`);
|
|
25593
24708
|
}
|
|
@@ -25646,9 +24761,9 @@ function createTokenStatsMcpServer(context, host = defaultTokenStatsMcpHost) {
|
|
|
25646
24761
|
}
|
|
25647
24762
|
if (currentSessions.length > 0) {
|
|
25648
24763
|
lines.push("", `\uD83D\uDCD0 \uD604\uC7AC context (${currentSessions.length}\uAC1C provider session)`);
|
|
25649
|
-
for (const
|
|
25650
|
-
const percent =
|
|
25651
|
-
lines.push(` ${
|
|
24764
|
+
for (const current of currentSessions) {
|
|
24765
|
+
const percent = current.contextTokens / current.contextWindow * 100;
|
|
24766
|
+
lines.push(` ${current.topicTitle} \xB7 ${current.agent}/${current.model} ${current.contextTokens.toLocaleString()} / ${current.contextWindow.toLocaleString()} (${percent.toFixed(1)}%)`);
|
|
25652
24767
|
}
|
|
25653
24768
|
}
|
|
25654
24769
|
const extraSummaryLines = host.extraSummaryLines?.(context.userId) ?? [];
|
|
@@ -25711,22 +24826,22 @@ ${lines.join(`
|
|
|
25711
24826
|
return server;
|
|
25712
24827
|
}
|
|
25713
24828
|
export {
|
|
25714
|
-
|
|
25715
|
-
parseSessionCommContext,
|
|
25716
|
-
defaultTokenStatsMcpHost,
|
|
25717
|
-
defaultTaskMcpHost,
|
|
25718
|
-
defaultSystemHealthMcpHost,
|
|
25719
|
-
defaultDecisionMcpHost,
|
|
25720
|
-
createWikiMcpServer,
|
|
25721
|
-
createVaultMcpServer,
|
|
25722
|
-
createTokenStatsMcpServer,
|
|
25723
|
-
createTaskMcpServer,
|
|
25724
|
-
createSystemHealthMcpServer,
|
|
25725
|
-
createSessionTargetCatalog,
|
|
25726
|
-
createSessionCommMcpServer,
|
|
25727
|
-
createDecisionMcpServer,
|
|
24829
|
+
createAgentHealthMcpServer,
|
|
25728
24830
|
createCompactionLogMcpServer,
|
|
25729
|
-
|
|
24831
|
+
createDecisionMcpServer,
|
|
24832
|
+
createSessionCommMcpServer,
|
|
24833
|
+
createSessionTargetCatalog,
|
|
24834
|
+
createSystemHealthMcpServer,
|
|
24835
|
+
createTaskMcpServer,
|
|
24836
|
+
createTokenStatsMcpServer,
|
|
24837
|
+
createVaultMcpServer,
|
|
24838
|
+
createWikiMcpServer,
|
|
24839
|
+
defaultDecisionMcpHost,
|
|
24840
|
+
defaultSystemHealthMcpHost,
|
|
24841
|
+
defaultTaskMcpHost,
|
|
24842
|
+
defaultTokenStatsMcpHost,
|
|
24843
|
+
parseSessionCommContext,
|
|
24844
|
+
protectMcpStdio
|
|
25730
24845
|
};
|
|
25731
24846
|
|
|
25732
|
-
//# debugId=
|
|
24847
|
+
//# debugId=F6A0130246CB507C64756E2164756E21
|