oasis_test_v2 2.2.35 → 2.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1106 -721
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22503,6 +22503,43 @@ var init_sync_skills = __esm({
|
|
|
22503
22503
|
|
|
22504
22504
|
// ../adapters/src/_core/materialize-bundle.ts
|
|
22505
22505
|
function materializeBundle(dir, bundle) {
|
|
22506
|
+
for (const [rel, entry] of Object.entries(bundle.restoreFiles ?? {})) {
|
|
22507
|
+
try {
|
|
22508
|
+
const parts = rel.split("/");
|
|
22509
|
+
if (!rel || path3.isAbsolute(rel) || rel.includes("\\") || parts.some((p2) => !p2 || p2 === "." || p2 === "..")) {
|
|
22510
|
+
throw new Error("\u975E\u6CD5\u76F8\u5BF9\u8DEF\u5F84");
|
|
22511
|
+
}
|
|
22512
|
+
let parent = fs3.realpathSync(dir);
|
|
22513
|
+
for (const component of parts.slice(0, -1)) {
|
|
22514
|
+
parent = path3.join(parent, component);
|
|
22515
|
+
if (!fs3.existsSync(parent)) fs3.mkdirSync(parent);
|
|
22516
|
+
const st = fs3.lstatSync(parent);
|
|
22517
|
+
if (st.isSymbolicLink() || !st.isDirectory()) throw new Error("\u6062\u590D\u8DEF\u5F84\u5305\u542B\u975E\u76EE\u5F55\u6216\u8F6F\u94FE\u63A5");
|
|
22518
|
+
}
|
|
22519
|
+
const file = path3.join(parent, parts.at(-1));
|
|
22520
|
+
let exists = false;
|
|
22521
|
+
try {
|
|
22522
|
+
const st = fs3.lstatSync(file);
|
|
22523
|
+
if (!st.isFile() || st.isSymbolicLink()) throw new Error("\u6062\u590D\u76EE\u6807\u4E0D\u662F\u666E\u901A\u6587\u4EF6");
|
|
22524
|
+
exists = true;
|
|
22525
|
+
} catch (error2) {
|
|
22526
|
+
if (error2.code !== "ENOENT") throw error2;
|
|
22527
|
+
}
|
|
22528
|
+
if (entry.requireExisting && !exists) throw new Error("\u4E0A\u6B21\u672A\u4FDD\u5B58\u7684\u6587\u4EF6\u5DF2\u4E0D\u5728\u672C\u8282\u70B9\uFF0C\u65E0\u6CD5\u6062\u590D\u6700\u65B0\u7248");
|
|
22529
|
+
if (exists && !entry.overwrite) continue;
|
|
22530
|
+
const bytes2 = Buffer.from(entry.contentBase64, "base64");
|
|
22531
|
+
if ((0, import_node_crypto6.createHash)("sha256").update(bytes2).digest("hex") !== entry.sha256) throw new Error("\u5185\u5BB9\u6821\u9A8C\u5931\u8D25");
|
|
22532
|
+
const temp = path3.join(parent, `.oasis-restore-${(0, import_node_crypto6.randomUUID)()}`);
|
|
22533
|
+
try {
|
|
22534
|
+
fs3.writeFileSync(temp, bytes2, { flag: "wx", mode: 384 });
|
|
22535
|
+
fs3.renameSync(temp, file);
|
|
22536
|
+
} finally {
|
|
22537
|
+
fs3.rmSync(temp, { force: true });
|
|
22538
|
+
}
|
|
22539
|
+
} catch (error2) {
|
|
22540
|
+
throw new BundleRestoreError(rel, error2 instanceof Error ? error2.message : String(error2));
|
|
22541
|
+
}
|
|
22542
|
+
}
|
|
22506
22543
|
for (const [rel, content3] of Object.entries(bundle.files)) {
|
|
22507
22544
|
const file = path3.join(dir, rel);
|
|
22508
22545
|
fs3.mkdirSync(path3.dirname(file), { recursive: true });
|
|
@@ -22517,12 +22554,20 @@ function materializeBundle(dir, bundle) {
|
|
|
22517
22554
|
if (!task) throw new Error("bundle \u7F3A TASK.md\uFF08\u88C5\u914D\u5668\u5951\u7EA6\uFF09");
|
|
22518
22555
|
return task;
|
|
22519
22556
|
}
|
|
22520
|
-
var fs3, path3;
|
|
22557
|
+
var fs3, path3, import_node_crypto6, BundleRestoreError;
|
|
22521
22558
|
var init_materialize_bundle = __esm({
|
|
22522
22559
|
"../adapters/src/_core/materialize-bundle.ts"() {
|
|
22523
22560
|
"use strict";
|
|
22524
22561
|
fs3 = __toESM(require("node:fs"), 1);
|
|
22525
22562
|
path3 = __toESM(require("node:path"), 1);
|
|
22563
|
+
import_node_crypto6 = require("node:crypto");
|
|
22564
|
+
BundleRestoreError = class extends Error {
|
|
22565
|
+
constructor(filePath, detail) {
|
|
22566
|
+
super(`\u6587\u4EF6\u6062\u590D\u5931\u8D25 ${filePath}\uFF1A${detail}`);
|
|
22567
|
+
this.filePath = filePath;
|
|
22568
|
+
this.name = "BundleRestoreError";
|
|
22569
|
+
}
|
|
22570
|
+
};
|
|
22526
22571
|
}
|
|
22527
22572
|
});
|
|
22528
22573
|
|
|
@@ -22576,7 +22621,7 @@ function resolveWorkRoots(workRoot) {
|
|
|
22576
22621
|
}
|
|
22577
22622
|
function workdirSlug(workdirKey) {
|
|
22578
22623
|
const safe = workdirKey.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 48);
|
|
22579
|
-
const h = (0,
|
|
22624
|
+
const h = (0, import_node_crypto7.createHash)("sha256").update(workdirKey).digest("hex").slice(0, 8);
|
|
22580
22625
|
return `${safe}-${h}`;
|
|
22581
22626
|
}
|
|
22582
22627
|
function sessionDirFor(workRoot, runtimeKind, workdirKey) {
|
|
@@ -22708,11 +22753,11 @@ function prepareWorkdir(args) {
|
|
|
22708
22753
|
function legacyChatSessionDir(workRoot, rtId) {
|
|
22709
22754
|
return import_node_path.default.join(resolveLegacyWorkRoot(workRoot), "oasis-chat-sessions", rtId.replace(/[^a-zA-Z0-9_-]+/g, "_"));
|
|
22710
22755
|
}
|
|
22711
|
-
var
|
|
22756
|
+
var import_node_crypto7, import_node_fs2, import_node_os, import_node_path, META_FILE, LOCK_FILE, NEW_WORK_ROOT, slug3, LEGACY_ROOTS, LEGACY_ONESHOT_PREFIX;
|
|
22712
22757
|
var init_session_paths = __esm({
|
|
22713
22758
|
"../adapters/src/_core/session-paths.ts"() {
|
|
22714
22759
|
"use strict";
|
|
22715
|
-
|
|
22760
|
+
import_node_crypto7 = require("node:crypto");
|
|
22716
22761
|
import_node_fs2 = __toESM(require("node:fs"), 1);
|
|
22717
22762
|
import_node_os = __toESM(require("node:os"), 1);
|
|
22718
22763
|
import_node_path = __toESM(require("node:path"), 1);
|
|
@@ -22740,7 +22785,7 @@ function executionEnvHash(p2) {
|
|
|
22740
22785
|
binPkg: p2.binPackageDir ?? null,
|
|
22741
22786
|
extraRo: [...p2.extraRoBindDirs ?? []].sort()
|
|
22742
22787
|
});
|
|
22743
|
-
return (0,
|
|
22788
|
+
return (0, import_node_crypto8.createHash)("sha256").update(material).digest("hex").slice(0, 16);
|
|
22744
22789
|
}
|
|
22745
22790
|
function persistContainerName(workdirKey) {
|
|
22746
22791
|
return `oasis-wd-${workdirSlug(workdirKey)}`;
|
|
@@ -22860,11 +22905,11 @@ function wrapForContainer(p2) {
|
|
|
22860
22905
|
function killContainerArgs(containerName) {
|
|
22861
22906
|
return ["kill", containerName];
|
|
22862
22907
|
}
|
|
22863
|
-
var
|
|
22908
|
+
var import_node_crypto8, path5, CONTAINER_DEFAULT_PATH, CONTAINER_HOME, EE_HASH_LABEL;
|
|
22864
22909
|
var init_container_wrap = __esm({
|
|
22865
22910
|
"../adapters/src/_core/container-wrap.ts"() {
|
|
22866
22911
|
"use strict";
|
|
22867
|
-
|
|
22912
|
+
import_node_crypto8 = require("node:crypto");
|
|
22868
22913
|
path5 = __toESM(require("node:path"), 1);
|
|
22869
22914
|
init_session_paths();
|
|
22870
22915
|
CONTAINER_DEFAULT_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
|
|
@@ -23592,12 +23637,12 @@ function classifyExit(result) {
|
|
|
23592
23637
|
if (status === 429 || status === 529) return "rate-limit";
|
|
23593
23638
|
return "error";
|
|
23594
23639
|
}
|
|
23595
|
-
var import_node_child_process3,
|
|
23640
|
+
var import_node_child_process3, import_node_crypto9, fs7, path7, readline, CLAUDE_BLOCKED_FLAGS, SUBAGENT_TRANSCRIPT_MAX_BYTES, SUBAGENT_TERMINAL, ONE_SHOT_UNSAFE_TOOLS, ClaudeCodeAdapter;
|
|
23596
23641
|
var init_claude_code = __esm({
|
|
23597
23642
|
"../adapters/src/claude-code/index.ts"() {
|
|
23598
23643
|
"use strict";
|
|
23599
23644
|
import_node_child_process3 = require("node:child_process");
|
|
23600
|
-
|
|
23645
|
+
import_node_crypto9 = require("node:crypto");
|
|
23601
23646
|
fs7 = __toESM(require("node:fs"), 1);
|
|
23602
23647
|
path7 = __toESM(require("node:path"), 1);
|
|
23603
23648
|
readline = __toESM(require("node:readline"), 1);
|
|
@@ -23677,7 +23722,7 @@ var init_claude_code = __esm({
|
|
|
23677
23722
|
}
|
|
23678
23723
|
async spawn(job) {
|
|
23679
23724
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
23680
|
-
const id = `claude-${slug6}-${(0,
|
|
23725
|
+
const id = `claude-${slug6}-${(0, import_node_crypto9.randomUUID)().slice(0, 8)}`;
|
|
23681
23726
|
const dir = job.workdirKey ? prepareWorkdir({
|
|
23682
23727
|
workRoot: this.opts.workRoot,
|
|
23683
23728
|
runtimeKind: "claude",
|
|
@@ -24090,7 +24135,7 @@ var init_claude_code = __esm({
|
|
|
24090
24135
|
const outgoing = report.failed.length ? appendMaterializeWarning(input.text, report) : input.text;
|
|
24091
24136
|
if (input.interrupt) writeInterrupt();
|
|
24092
24137
|
diag("append_accepted", { writes, results, interrupt: !!input.interrupt, chars: input.text.length });
|
|
24093
|
-
const receiptId = input.requireConsumptionReceipt ? (0,
|
|
24138
|
+
const receiptId = input.requireConsumptionReceipt ? (0, import_node_crypto9.randomUUID)() : void 0;
|
|
24094
24139
|
if (receiptId) pendingInputReceipts.set(receiptId, input.clientMessageKey);
|
|
24095
24140
|
const ok3 = writeUserMessage(outgoing, receiptId);
|
|
24096
24141
|
if (!ok3 && receiptId) pendingInputReceipts.delete(receiptId);
|
|
@@ -24230,7 +24275,12 @@ function withResilience(inner, cfg = {}) {
|
|
|
24230
24275
|
try {
|
|
24231
24276
|
handle = await inner.spawn(job);
|
|
24232
24277
|
} catch (err) {
|
|
24233
|
-
finish({
|
|
24278
|
+
finish({
|
|
24279
|
+
code: null,
|
|
24280
|
+
reason: "error",
|
|
24281
|
+
errorMessage: errText(err),
|
|
24282
|
+
...err instanceof BundleRestoreError ? { fileRestoreError: { path: err.filePath, message: err.message } } : {}
|
|
24283
|
+
});
|
|
24234
24284
|
return;
|
|
24235
24285
|
}
|
|
24236
24286
|
const { info, produced } = await runOnce(handle);
|
|
@@ -24304,6 +24354,7 @@ var RETRYABLE, sleep2;
|
|
|
24304
24354
|
var init_resilient = __esm({
|
|
24305
24355
|
"../adapters/src/_core/resilient.ts"() {
|
|
24306
24356
|
"use strict";
|
|
24357
|
+
init_materialize_bundle();
|
|
24307
24358
|
init_src();
|
|
24308
24359
|
RETRYABLE = /* @__PURE__ */ new Set(["rate-limit", "timeout", "server-unreachable"]);
|
|
24309
24360
|
sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -24487,9 +24538,9 @@ function lockPathFor(cacheRoot, actorId) {
|
|
|
24487
24538
|
}
|
|
24488
24539
|
function aggregateSkillContentHash(files) {
|
|
24489
24540
|
const sorted = [...files].sort((a, b2) => a.path.localeCompare(b2.path));
|
|
24490
|
-
const hasher = (0,
|
|
24541
|
+
const hasher = (0, import_node_crypto10.createHash)("sha256");
|
|
24491
24542
|
for (const f2 of sorted) {
|
|
24492
|
-
const blob = (0,
|
|
24543
|
+
const blob = (0, import_node_crypto10.createHash)("sha256").update(f2.content).digest("hex");
|
|
24493
24544
|
hasher.update(f2.path);
|
|
24494
24545
|
hasher.update("\0");
|
|
24495
24546
|
hasher.update(blob);
|
|
@@ -24717,11 +24768,11 @@ async function verifyPendingLink(skillsDir, name, pend, log3) {
|
|
|
24717
24768
|
}
|
|
24718
24769
|
return true;
|
|
24719
24770
|
}
|
|
24720
|
-
var
|
|
24771
|
+
var import_node_crypto10, fsp, os4, path8, MANIFEST_SCHEMA_VERSION, STALE_LOCK_MS, LOCK_ACQUIRE_TIMEOUT_MS, LOCK_POLL_MS;
|
|
24721
24772
|
var init_skill_cache = __esm({
|
|
24722
24773
|
"../adapters/src/_core/skill-cache.ts"() {
|
|
24723
24774
|
"use strict";
|
|
24724
|
-
|
|
24775
|
+
import_node_crypto10 = require("node:crypto");
|
|
24725
24776
|
fsp = __toESM(require("node:fs/promises"), 1);
|
|
24726
24777
|
os4 = __toESM(require("node:os"), 1);
|
|
24727
24778
|
path8 = __toESM(require("node:path"), 1);
|
|
@@ -25370,7 +25421,7 @@ function isResponse(message) {
|
|
|
25370
25421
|
}
|
|
25371
25422
|
async function runProtocolSession(job, cfg) {
|
|
25372
25423
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
25373
|
-
const id = `${cfg.runtimeKind}-${slug6}-${(0,
|
|
25424
|
+
const id = `${cfg.runtimeKind}-${slug6}-${(0, import_node_crypto11.randomUUID)().slice(0, 8)}`;
|
|
25374
25425
|
const dir = job.workdirKey ? prepareWorkdir({
|
|
25375
25426
|
workRoot: cfg.workRoot,
|
|
25376
25427
|
runtimeKind: cfg.runtimeKind,
|
|
@@ -25613,12 +25664,12 @@ async function runProtocolSession(job, cfg) {
|
|
|
25613
25664
|
}
|
|
25614
25665
|
};
|
|
25615
25666
|
}
|
|
25616
|
-
var import_node_child_process6,
|
|
25667
|
+
var import_node_child_process6, import_node_crypto11, path9, ProtocolCommandRejected, ProtocolSessionClosing;
|
|
25617
25668
|
var init_protocol_session = __esm({
|
|
25618
25669
|
"../adapters/src/_core/protocol-session.ts"() {
|
|
25619
25670
|
"use strict";
|
|
25620
25671
|
import_node_child_process6 = require("node:child_process");
|
|
25621
|
-
|
|
25672
|
+
import_node_crypto11 = require("node:crypto");
|
|
25622
25673
|
path9 = __toESM(require("node:path"), 1);
|
|
25623
25674
|
init_claude_code();
|
|
25624
25675
|
init_container_runtime();
|
|
@@ -26077,13 +26128,13 @@ function codexTurnErrorMessage(value2) {
|
|
|
26077
26128
|
const detail = typeof error2?.additionalDetails === "string" ? error2.additionalDetails.trim() : "";
|
|
26078
26129
|
return [summary, detail].filter(Boolean).join("\n").slice(0, 4e3);
|
|
26079
26130
|
}
|
|
26080
|
-
var import_node_child_process7,
|
|
26131
|
+
var import_node_child_process7, import_node_crypto12, fs8, os5, path10, readline2, CODEX_BLOCKED_FLAGS, CODEX_ARGV_PROMPT_MAX_BYTES, CODEX_APP_SERVER_BLOCKED_FLAGS, CodexAdapter;
|
|
26081
26132
|
var init_codex = __esm({
|
|
26082
26133
|
"../adapters/src/codex/index.ts"() {
|
|
26083
26134
|
"use strict";
|
|
26084
26135
|
import_node_child_process7 = require("node:child_process");
|
|
26085
26136
|
init_container_runtime();
|
|
26086
|
-
|
|
26137
|
+
import_node_crypto12 = require("node:crypto");
|
|
26087
26138
|
fs8 = __toESM(require("node:fs"), 1);
|
|
26088
26139
|
os5 = __toESM(require("node:os"), 1);
|
|
26089
26140
|
path10 = __toESM(require("node:path"), 1);
|
|
@@ -26371,7 +26422,7 @@ ${task}` : task;
|
|
|
26371
26422
|
}
|
|
26372
26423
|
async spawnExec(job) {
|
|
26373
26424
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
26374
|
-
const id = `codex-${slug6}-${(0,
|
|
26425
|
+
const id = `codex-${slug6}-${(0, import_node_crypto12.randomUUID)().slice(0, 8)}`;
|
|
26375
26426
|
const startedAtMs = Date.now();
|
|
26376
26427
|
const dir = job.workdirKey ? prepareWorkdir({
|
|
26377
26428
|
workRoot: this.opts.workRoot,
|
|
@@ -27182,7 +27233,7 @@ async function runACPSession(job, cfg) {
|
|
|
27182
27233
|
}
|
|
27183
27234
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
27184
27235
|
const binTag = path11.basename(cfg.bin).replace(/[^a-zA-Z0-9]/g, "").slice(0, 12) || "acp";
|
|
27185
|
-
const id = `${binTag}-${slug6}-${(0,
|
|
27236
|
+
const id = `${binTag}-${slug6}-${(0, import_node_crypto13.randomUUID)().slice(0, 8)}`;
|
|
27186
27237
|
const dir = job.workdirKey ? prepareWorkdir({
|
|
27187
27238
|
workRoot: cfg.workRoot,
|
|
27188
27239
|
runtimeKind: cfg.runtimeKind ?? "subprocess",
|
|
@@ -27595,12 +27646,12 @@ ${task}` : task;
|
|
|
27595
27646
|
return run;
|
|
27596
27647
|
}
|
|
27597
27648
|
}
|
|
27598
|
-
var import_node_child_process8,
|
|
27649
|
+
var import_node_child_process8, import_node_crypto13, fs9, path11, readline3, ACPClient, LEGACY_APPROVE_OPTION_ID;
|
|
27599
27650
|
var init_acp = __esm({
|
|
27600
27651
|
"../adapters/src/_core/acp.ts"() {
|
|
27601
27652
|
"use strict";
|
|
27602
27653
|
import_node_child_process8 = require("node:child_process");
|
|
27603
|
-
|
|
27654
|
+
import_node_crypto13 = require("node:crypto");
|
|
27604
27655
|
fs9 = __toESM(require("node:fs"), 1);
|
|
27605
27656
|
path11 = __toESM(require("node:path"), 1);
|
|
27606
27657
|
readline3 = __toESM(require("node:readline"), 1);
|
|
@@ -28433,7 +28484,7 @@ var init_pdeathsig = __esm({
|
|
|
28433
28484
|
// ../adapters/src/_core/subprocess.ts
|
|
28434
28485
|
async function materialize(job, cfg) {
|
|
28435
28486
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
28436
|
-
const id = `${slug6}-${(0,
|
|
28487
|
+
const id = `${slug6}-${(0, import_node_crypto14.randomUUID)().slice(0, 8)}`;
|
|
28437
28488
|
const dir = job.workdirKey ? prepareWorkdir({
|
|
28438
28489
|
workRoot: cfg.workRoot,
|
|
28439
28490
|
runtimeKind: cfg.runtimeKind ?? "subprocess",
|
|
@@ -28726,12 +28777,12 @@ async function runOneShotText(job, cfg) {
|
|
|
28726
28777
|
}
|
|
28727
28778
|
});
|
|
28728
28779
|
}
|
|
28729
|
-
var import_node_child_process10,
|
|
28780
|
+
var import_node_child_process10, import_node_crypto14, fs11, path13, readline4;
|
|
28730
28781
|
var init_subprocess = __esm({
|
|
28731
28782
|
"../adapters/src/_core/subprocess.ts"() {
|
|
28732
28783
|
"use strict";
|
|
28733
28784
|
import_node_child_process10 = require("node:child_process");
|
|
28734
|
-
|
|
28785
|
+
import_node_crypto14 = require("node:crypto");
|
|
28735
28786
|
fs11 = __toESM(require("node:fs"), 1);
|
|
28736
28787
|
path13 = __toESM(require("node:path"), 1);
|
|
28737
28788
|
readline4 = __toESM(require("node:readline"), 1);
|
|
@@ -28788,11 +28839,11 @@ function normalizeOpenClaw(line, state) {
|
|
|
28788
28839
|
const text5 = (r.payloads ?? []).map((pl) => pl?.text ?? "").filter(Boolean).join("\n");
|
|
28789
28840
|
return text5 ? [{ kind: "message", payload: { text: text5 }, outputText: text5 }] : [];
|
|
28790
28841
|
}
|
|
28791
|
-
var
|
|
28842
|
+
var import_node_crypto15, isTopLevelClose, OpenClawAdapter;
|
|
28792
28843
|
var init_openclaw = __esm({
|
|
28793
28844
|
"../adapters/src/openclaw/index.ts"() {
|
|
28794
28845
|
"use strict";
|
|
28795
|
-
|
|
28846
|
+
import_node_crypto15 = require("node:crypto");
|
|
28796
28847
|
init_subprocess();
|
|
28797
28848
|
isTopLevelClose = (line) => line === "}" || line === "}\r";
|
|
28798
28849
|
OpenClawAdapter = class {
|
|
@@ -28801,7 +28852,7 @@ var init_openclaw = __esm({
|
|
|
28801
28852
|
}
|
|
28802
28853
|
spawn(job) {
|
|
28803
28854
|
const opts = this.opts;
|
|
28804
|
-
const sessionId = job.runtimeSessionId ?? `oasis-${(0,
|
|
28855
|
+
const sessionId = job.runtimeSessionId ?? `oasis-${(0, import_node_crypto15.randomUUID)().slice(0, 8)}`;
|
|
28805
28856
|
return runStreamJson(job, {
|
|
28806
28857
|
model: job.model ?? opts.model,
|
|
28807
28858
|
bin: opts.openClawBin ?? "openclaw",
|
|
@@ -29602,6 +29653,7 @@ var init_src6 = __esm({
|
|
|
29602
29653
|
init_workdir_gc();
|
|
29603
29654
|
init_gc_loop();
|
|
29604
29655
|
init_normalizer2();
|
|
29656
|
+
init_materialize_bundle();
|
|
29605
29657
|
}
|
|
29606
29658
|
});
|
|
29607
29659
|
|
|
@@ -29957,7 +30009,7 @@ function chatItemsDoubleWriteEnabled(env = process.env) {
|
|
|
29957
30009
|
return raw !== "" && raw !== "0" && raw !== "false" && raw !== "off" && raw !== "no";
|
|
29958
30010
|
}
|
|
29959
30011
|
function fallbackTurnId(runId) {
|
|
29960
|
-
return runId ? `chat-run-turn:${runId}` : `local-turn:${(0,
|
|
30012
|
+
return runId ? `chat-run-turn:${runId}` : `local-turn:${(0, import_node_crypto16.randomUUID)()}`;
|
|
29961
30013
|
}
|
|
29962
30014
|
async function resolveChatItemsTurnId(items, messageId, fallback) {
|
|
29963
30015
|
const existing = await items.listItemsByMessage(messageId).catch(() => []);
|
|
@@ -29976,20 +30028,20 @@ function projectsIntoContent(kind, role, origin, telemetryTextInContent, attrs =
|
|
|
29976
30028
|
return true;
|
|
29977
30029
|
}
|
|
29978
30030
|
}
|
|
29979
|
-
var
|
|
30031
|
+
var import_node_crypto16, CHAT_ITEMS_DOUBLE_WRITE_ENV, SEGMENT_END_NOTE, ChatItemLedger;
|
|
29980
30032
|
var init_chat_item_ledger = __esm({
|
|
29981
30033
|
"../server/src/chat-item-ledger.ts"() {
|
|
29982
30034
|
"use strict";
|
|
29983
30035
|
init_src();
|
|
29984
30036
|
init_subagent_cost();
|
|
29985
30037
|
init_chat_item();
|
|
29986
|
-
|
|
30038
|
+
import_node_crypto16 = require("node:crypto");
|
|
29987
30039
|
CHAT_ITEMS_DOUBLE_WRITE_ENV = "OASIS_CHAT_ITEMS_DOUBLE_WRITE";
|
|
29988
30040
|
SEGMENT_END_NOTE = "\u672C\u6BB5\u65E0\u8F93\u51FA\uFF08\u4EBA\u5728\u9996\u4E2A\u6B63\u6587\u4E4B\u524D\u63D2\u4E86\u8BDD\uFF09";
|
|
29989
30041
|
ChatItemLedger = class {
|
|
29990
30042
|
constructor(deps) {
|
|
29991
30043
|
this.deps = deps;
|
|
29992
|
-
this.newId = deps.newId ??
|
|
30044
|
+
this.newId = deps.newId ?? import_node_crypto16.randomUUID;
|
|
29993
30045
|
this.now = deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
29994
30046
|
this.log = deps.log ?? ((m2) => console.warn(m2));
|
|
29995
30047
|
this.messageId = deps.messageId ?? null;
|
|
@@ -30609,7 +30661,7 @@ var init_chat_parts = __esm({
|
|
|
30609
30661
|
async function openAssistantRunningRow(deps) {
|
|
30610
30662
|
const now = deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
30611
30663
|
if (typeof deps.chatStore.appendMessage !== "function") return void 0;
|
|
30612
|
-
const id = (0,
|
|
30664
|
+
const id = (0, import_node_crypto17.randomUUID)();
|
|
30613
30665
|
const at = now();
|
|
30614
30666
|
try {
|
|
30615
30667
|
await deps.chatStore.appendMessage({
|
|
@@ -30653,7 +30705,7 @@ async function finalizeAssistantRow(deps) {
|
|
|
30653
30705
|
if (typeof deps.chatStore.appendMessage !== "function") return;
|
|
30654
30706
|
try {
|
|
30655
30707
|
await deps.chatStore.appendMessage({
|
|
30656
|
-
id: (0,
|
|
30708
|
+
id: (0, import_node_crypto17.randomUUID)(),
|
|
30657
30709
|
sessionId: deps.chatSessionId,
|
|
30658
30710
|
role: "assistant",
|
|
30659
30711
|
content: deps.content,
|
|
@@ -30667,6 +30719,13 @@ async function finalizeAssistantRow(deps) {
|
|
|
30667
30719
|
} catch {
|
|
30668
30720
|
}
|
|
30669
30721
|
}
|
|
30722
|
+
function outputsPartProvider(scan2, chatSessionId, companyId) {
|
|
30723
|
+
if (!scan2) return void 0;
|
|
30724
|
+
return async () => {
|
|
30725
|
+
const files = await scan2({ chatSessionId, ...companyId !== void 0 ? { companyId } : {} });
|
|
30726
|
+
return files && files.length > 0 ? { type: "outputs", seq: 0, outputs: files } : null;
|
|
30727
|
+
};
|
|
30728
|
+
}
|
|
30670
30729
|
async function appendOutputsPart(parts, provider) {
|
|
30671
30730
|
if (!provider) return parts;
|
|
30672
30731
|
const part = await provider().catch(() => null);
|
|
@@ -30910,11 +30969,11 @@ function runBackgroundAssistantChatTurn(deps) {
|
|
|
30910
30969
|
});
|
|
30911
30970
|
})().catch(() => void 0);
|
|
30912
30971
|
}
|
|
30913
|
-
var
|
|
30972
|
+
var import_node_crypto17;
|
|
30914
30973
|
var init_chat_assistant_turn = __esm({
|
|
30915
30974
|
"../server/src/chat-assistant-turn.ts"() {
|
|
30916
30975
|
"use strict";
|
|
30917
|
-
|
|
30976
|
+
import_node_crypto17 = require("node:crypto");
|
|
30918
30977
|
init_src6();
|
|
30919
30978
|
init_chat_item_ledger();
|
|
30920
30979
|
init_chat_parts();
|
|
@@ -30932,7 +30991,7 @@ async function openChatTurn(args) {
|
|
|
30932
30991
|
const turns = args.turns;
|
|
30933
30992
|
if (!turns) return { ok: true, turn: null };
|
|
30934
30993
|
const nowIso = args.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
30935
|
-
const turnId = (args.newId ??
|
|
30994
|
+
const turnId = (args.newId ?? import_node_crypto18.randomUUID)();
|
|
30936
30995
|
const messageKey = localTurnMessageKey(args.source, turnId);
|
|
30937
30996
|
const claim = await turns.claimTurn({
|
|
30938
30997
|
turnId,
|
|
@@ -30966,7 +31025,7 @@ async function openChatTurn(args) {
|
|
|
30966
31025
|
}
|
|
30967
31026
|
};
|
|
30968
31027
|
}
|
|
30969
|
-
function assistantRowRecovery(chatStore) {
|
|
31028
|
+
function assistantRowRecovery(chatStore, opts = {}) {
|
|
30970
31029
|
const rowOf = async (turn) => {
|
|
30971
31030
|
const runId = turn.assistantRunId;
|
|
30972
31031
|
if (!runId) return null;
|
|
@@ -30982,20 +31041,27 @@ function assistantRowRecovery(chatStore) {
|
|
|
30982
31041
|
|
|
30983
31042
|
` : "";
|
|
30984
31043
|
const content3 = patch.status === "error" ? `${partial2}${ORPHANED_TURN_ASSISTANT_NOTICE}` : row.content ?? "";
|
|
31044
|
+
const outputsPart = opts.outputsPartFor?.(turn.chatSessionId);
|
|
30985
31045
|
await finalizeAssistantRow({
|
|
30986
31046
|
chatStore,
|
|
30987
31047
|
chatSessionId: turn.chatSessionId,
|
|
30988
31048
|
assistantMsgId: row.id,
|
|
30989
31049
|
content: content3,
|
|
30990
|
-
parts
|
|
31050
|
+
// 不扫产出时照旧传空:finalize 对空 parts 不写这一列,行上原有的 parts 不动。
|
|
31051
|
+
// 要扫就必须带上原有 parts——否则扫到产出时写回去的只剩一张卡,这一轮的过程记录被冲掉。
|
|
31052
|
+
parts: outputsPart ? existingParts(row.parts) : [],
|
|
30991
31053
|
status: patch.status,
|
|
30992
31054
|
...turn.assistantRunId ? { runId: turn.assistantRunId } : {},
|
|
30993
31055
|
turnId: turn.id,
|
|
30994
|
-
now: () => patch.completedAt
|
|
31056
|
+
now: () => patch.completedAt,
|
|
31057
|
+
...outputsPart ? { outputsPart } : {}
|
|
30995
31058
|
});
|
|
30996
31059
|
}
|
|
30997
31060
|
};
|
|
30998
31061
|
}
|
|
31062
|
+
function existingParts(parts) {
|
|
31063
|
+
return Array.isArray(parts) ? parts.filter((p2) => p2 && typeof p2 === "object" && typeof p2.type === "string") : [];
|
|
31064
|
+
}
|
|
30999
31065
|
async function reconcileChatTurn(turn, deps) {
|
|
31000
31066
|
if (deps.isOwned?.(turn)) return { settled: false, turnId: turn.id, reason: "owned" };
|
|
31001
31067
|
const rowStatus = deps.assistantRowStatus ? await deps.assistantRowStatus(turn).catch(() => null) : null;
|
|
@@ -31100,11 +31166,11 @@ async function sweepStaleChatTurnsAcrossCompanies(deps) {
|
|
|
31100
31166
|
}
|
|
31101
31167
|
return settled;
|
|
31102
31168
|
}
|
|
31103
|
-
var
|
|
31169
|
+
var import_node_crypto18, ORPHANED_TURN_ASSISTANT_NOTICE;
|
|
31104
31170
|
var init_chat_turn_gate = __esm({
|
|
31105
31171
|
"../server/src/chat-turn-gate.ts"() {
|
|
31106
31172
|
"use strict";
|
|
31107
|
-
|
|
31173
|
+
import_node_crypto18 = require("node:crypto");
|
|
31108
31174
|
init_chat_assistant_turn();
|
|
31109
31175
|
ORPHANED_TURN_ASSISTANT_NOTICE = "\u8FD9\u4E00\u8F6E\u6CA1\u6709\u6B63\u5E38\u7ED3\u675F\uFF08\u670D\u52A1\u7AEF\u8FDB\u7A0B\u4E2D\u65AD\uFF09\uFF0C\u6CA1\u6709\u4EA7\u751F\u56DE\u590D\u3002\u4F60\u53EF\u4EE5\u518D\u95EE\u4E00\u6B21\u3002";
|
|
31110
31176
|
}
|
|
@@ -31316,11 +31382,11 @@ var init_parse = __esm({
|
|
|
31316
31382
|
|
|
31317
31383
|
// ../channels/src/feishu/crypto.ts
|
|
31318
31384
|
function decryptFeishu(encrypt, encryptKey) {
|
|
31319
|
-
const key = (0,
|
|
31385
|
+
const key = (0, import_node_crypto19.createHash)("sha256").update(encryptKey).digest();
|
|
31320
31386
|
const data = Buffer.from(encrypt, "base64");
|
|
31321
31387
|
const iv = data.subarray(0, 16);
|
|
31322
31388
|
const ciphertext = data.subarray(16);
|
|
31323
|
-
const decipher = (0,
|
|
31389
|
+
const decipher = (0, import_node_crypto19.createDecipheriv)("aes-256-cbc", key, iv);
|
|
31324
31390
|
decipher.setAutoPadding(true);
|
|
31325
31391
|
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
31326
31392
|
}
|
|
@@ -31354,11 +31420,11 @@ function verifyToken(decoded, expected) {
|
|
|
31354
31420
|
const token = headerToken ?? decoded["token"];
|
|
31355
31421
|
return token === expected;
|
|
31356
31422
|
}
|
|
31357
|
-
var
|
|
31423
|
+
var import_node_crypto19;
|
|
31358
31424
|
var init_crypto = __esm({
|
|
31359
31425
|
"../channels/src/feishu/crypto.ts"() {
|
|
31360
31426
|
"use strict";
|
|
31361
|
-
|
|
31427
|
+
import_node_crypto19 = require("node:crypto");
|
|
31362
31428
|
}
|
|
31363
31429
|
});
|
|
31364
31430
|
|
|
@@ -31494,11 +31560,11 @@ var init_src7 = __esm({
|
|
|
31494
31560
|
function errMsg(e) {
|
|
31495
31561
|
return e instanceof Error ? e.message : String(e);
|
|
31496
31562
|
}
|
|
31497
|
-
var
|
|
31563
|
+
var import_node_crypto20, FEISHU, ChannelService, CardStreamer;
|
|
31498
31564
|
var init_service = __esm({
|
|
31499
31565
|
"../server/src/channels/service.ts"() {
|
|
31500
31566
|
"use strict";
|
|
31501
|
-
|
|
31567
|
+
import_node_crypto20 = require("node:crypto");
|
|
31502
31568
|
init_chat_turn_gate();
|
|
31503
31569
|
init_deletion();
|
|
31504
31570
|
init_src7();
|
|
@@ -31580,7 +31646,7 @@ var init_service = __esm({
|
|
|
31580
31646
|
return existing.chatSessionId;
|
|
31581
31647
|
}
|
|
31582
31648
|
}
|
|
31583
|
-
const id = (0,
|
|
31649
|
+
const id = (0, import_node_crypto20.randomUUID)();
|
|
31584
31650
|
const now = this.now();
|
|
31585
31651
|
if (cs) {
|
|
31586
31652
|
const rt = await this.deps.resolveRuntime?.(a.aiActorId).catch(() => null);
|
|
@@ -31616,7 +31682,7 @@ var init_service = __esm({
|
|
|
31616
31682
|
if (cs) {
|
|
31617
31683
|
const sess = await cs.getSession(intent.chatSessionId).catch(() => null);
|
|
31618
31684
|
resumeRt = sess?.runtimeSessionId ?? void 0;
|
|
31619
|
-
await cs.appendMessage({ id: (0,
|
|
31685
|
+
await cs.appendMessage({ id: (0, import_node_crypto20.randomUUID)(), sessionId: intent.chatSessionId, role: "user", content: intent.message, createdAt: this.now() }, { source: "channels" }).catch(() => void 0);
|
|
31620
31686
|
}
|
|
31621
31687
|
const opened = await openChatTurn({
|
|
31622
31688
|
turns: this.deps.chatTurns,
|
|
@@ -31654,7 +31720,7 @@ var init_service = __esm({
|
|
|
31654
31720
|
const reply = streamer.text();
|
|
31655
31721
|
if (reply || session.runId) {
|
|
31656
31722
|
await cs.appendMessage({
|
|
31657
|
-
id: (0,
|
|
31723
|
+
id: (0, import_node_crypto20.randomUUID)(),
|
|
31658
31724
|
sessionId: intent.chatSessionId,
|
|
31659
31725
|
role: "assistant",
|
|
31660
31726
|
content: reply,
|
|
@@ -52733,7 +52799,7 @@ var require_websocket = __commonJS({
|
|
|
52733
52799
|
var http2 = require("http");
|
|
52734
52800
|
var net = require("net");
|
|
52735
52801
|
var tls = require("tls");
|
|
52736
|
-
var { randomBytes: randomBytes13, createHash:
|
|
52802
|
+
var { randomBytes: randomBytes13, createHash: createHash41 } = require("crypto");
|
|
52737
52803
|
var { Duplex, Readable } = require("stream");
|
|
52738
52804
|
var { URL: URL2 } = require("url");
|
|
52739
52805
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -53401,7 +53467,7 @@ var require_websocket = __commonJS({
|
|
|
53401
53467
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
53402
53468
|
return;
|
|
53403
53469
|
}
|
|
53404
|
-
const digest =
|
|
53470
|
+
const digest = createHash41("sha1").update(key + GUID).digest("base64");
|
|
53405
53471
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
53406
53472
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
53407
53473
|
return;
|
|
@@ -53770,7 +53836,7 @@ var require_websocket_server = __commonJS({
|
|
|
53770
53836
|
var EventEmitter = require("events");
|
|
53771
53837
|
var http2 = require("http");
|
|
53772
53838
|
var { Duplex } = require("stream");
|
|
53773
|
-
var { createHash:
|
|
53839
|
+
var { createHash: createHash41 } = require("crypto");
|
|
53774
53840
|
var extension3 = require_extension();
|
|
53775
53841
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
53776
53842
|
var subprotocol2 = require_subprotocol();
|
|
@@ -54077,7 +54143,7 @@ var require_websocket_server = __commonJS({
|
|
|
54077
54143
|
);
|
|
54078
54144
|
}
|
|
54079
54145
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
54080
|
-
const digest =
|
|
54146
|
+
const digest = createHash41("sha1").update(key + GUID).digest("base64");
|
|
54081
54147
|
const headers = [
|
|
54082
54148
|
"HTTP/1.1 101 Switching Protocols",
|
|
54083
54149
|
"Upgrade: websocket",
|
|
@@ -162291,13 +162357,13 @@ var init_chat_attachment_files = __esm({
|
|
|
162291
162357
|
|
|
162292
162358
|
// ../server/src/domains/chat-sessions/append-now.ts
|
|
162293
162359
|
async function appendNowThroughQueue(chatSessionId, text5, deps, clientKey, attachments, retainLocallyOnFailure = false) {
|
|
162294
|
-
const newId = deps.newId ??
|
|
162360
|
+
const newId = deps.newId ?? import_node_crypto21.randomUUID;
|
|
162295
162361
|
const now = deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
162296
162362
|
if (!deps.store.claimPendingInsert) {
|
|
162297
162363
|
return { accepted: false, reason: "queue-unavailable", queued: false, delivered: "", batch: [] };
|
|
162298
162364
|
}
|
|
162299
162365
|
const { submitted, batch } = await deps.store.claimPendingInsert({
|
|
162300
|
-
id: clientKey ? `append-request:${(0,
|
|
162366
|
+
id: clientKey ? `append-request:${(0, import_node_crypto21.createHash)("sha256").update(JSON.stringify([chatSessionId, clientKey])).digest("hex")}` : newId(),
|
|
162301
162367
|
chatSessionId,
|
|
162302
162368
|
text: text5,
|
|
162303
162369
|
...attachments?.length ? { attachments } : {},
|
|
@@ -162353,11 +162419,11 @@ async function appendNowThroughQueue(chatSessionId, text5, deps, clientKey, atta
|
|
|
162353
162419
|
}
|
|
162354
162420
|
return { ...res, queued: !returnToClient, delivered: merged, batch, ...prepared.paths.length ? { attachmentPaths: prepared.paths } : {} };
|
|
162355
162421
|
}
|
|
162356
|
-
var
|
|
162422
|
+
var import_node_crypto21;
|
|
162357
162423
|
var init_append_now = __esm({
|
|
162358
162424
|
"../server/src/domains/chat-sessions/append-now.ts"() {
|
|
162359
162425
|
"use strict";
|
|
162360
|
-
|
|
162426
|
+
import_node_crypto21 = require("node:crypto");
|
|
162361
162427
|
init_chat_attachment_files();
|
|
162362
162428
|
}
|
|
162363
162429
|
});
|
|
@@ -163030,7 +163096,7 @@ function slug5(name) {
|
|
|
163030
163096
|
return s2 || "user";
|
|
163031
163097
|
}
|
|
163032
163098
|
function short6() {
|
|
163033
|
-
return (0,
|
|
163099
|
+
return (0, import_node_crypto22.randomBytes)(4).toString("hex").slice(0, 6);
|
|
163034
163100
|
}
|
|
163035
163101
|
async function assertBindingWritePermission(caller, targetHumanId, deps) {
|
|
163036
163102
|
if (caller === targetHumanId) return true;
|
|
@@ -163095,11 +163161,11 @@ async function resolveWorkorderPrincipals(caller, cliOverrides, deps) {
|
|
|
163095
163161
|
}
|
|
163096
163162
|
return { error: "UNBOUND_AGENT_NO_OWNER", message: `owner \u65E0\u6CD5\u89E3\u6790\uFF1A\u8C03\u7528\u65B9 ${caller} \u65E2\u975E\u5728\u5C97\u771F\u4EBA\u4E5F\u975E\u5DF2\u7ED1\u52A9\u7406` };
|
|
163097
163163
|
}
|
|
163098
|
-
var
|
|
163164
|
+
var import_node_crypto22, DEFAULT_ASSISTANT_PROMPT, DEFAULT_ASSISTANT_SKILLS, DEFAULT_ASSISTANT_RUNTIME_KIND, ASSISTANT_ARCHIVED_CODE, AssistantLazyCreateError, AssistantsService;
|
|
163099
163165
|
var init_assistants = __esm({
|
|
163100
163166
|
"../server/src/domains/actors/assistants.ts"() {
|
|
163101
163167
|
"use strict";
|
|
163102
|
-
|
|
163168
|
+
import_node_crypto22 = require("node:crypto");
|
|
163103
163169
|
init_src();
|
|
163104
163170
|
DEFAULT_ASSISTANT_PROMPT = "\u4F60\u662F\u8FD9\u540D\u771F\u4EBA\u5458\u5DE5\u7684\u4E13\u5C5E\u4E2A\u4EBA\u52A9\u7406\u3002\u4F60\u4EE5\u5176\u300C\u5DE5\u5355\u7BA1\u7406\u8005\u300D\u8EAB\u4EFD\u4EE3\u8DD1\uFF0C\u9075\u5FAA\u4E09\u6863\u6743\u9650\u6A21\u578B\uFF1A\u6863 A\uFF08\u52A0\u8FB9\u3001\u65B0\u5EFA\u8282\u70B9\u3001\u6539\u6807\u9898\u4E0E brief\u3001\u5E38\u89C4\u8BC4\u8BBA\u7B54\u7591\u3001\u63A8\u8FDB\u81EA\u5DF1\u63A5\u7684\u6D3B\uFF09\u53EF\u9006\u6539\u52A8\u76F4\u63A5\u751F\u6548\uFF1B\u6863 B\uFF08\u65AD\u8FB9\u3001\u5E9F\u8282\u70B9\u3001\u6539\u6D3E\u3001\u64A4\u90E8\u4EF6\uFF09\u9500\u6BC1\u6027\u6539\u52A8\u81EA\u52A8\u6253\u5305\u6210\u5F85\u786E\u8BA4\u63D0\u6848\uFF0C\u4EA4\u7531\u672C\u4EBA\u786E\u8BA4\u540E\u751F\u6548\uFF1B\u6863 C\uFF08force-conclude\u3001promote \u7B49\u6CBB\u7406\u547D\u4EE4\uFF09\u8D70\u4EBA\u5DE5\u6388\u6743\u5361\u3002\u4F60\u4E0D\u627F\u62C5\u4E1A\u52A1\u4E13\u4E1A\u5C97\u4F4D\u804C\u8D23\uFF0C\u53EA\u5728\u5176\u6388\u6743\u8303\u56F4\u5185\u534F\u52A9\u5EFA\u5355\u3001\u8DDF\u8FDB\u4E0E\u6C9F\u901A\u3002";
|
|
163105
163171
|
DEFAULT_ASSISTANT_SKILLS = [];
|
|
@@ -165509,7 +165575,7 @@ var init_continuation3 = __esm({
|
|
|
165509
165575
|
|
|
165510
165576
|
// ../server/src/chat-workorder-files.ts
|
|
165511
165577
|
function workOrderFileId(workOrderId, blobId, name) {
|
|
165512
|
-
return `wof:${(0,
|
|
165578
|
+
return `wof:${(0, import_node_crypto23.createHash)("sha256").update(`${workOrderId}|${blobId}|${name}`).digest("hex").slice(0, 32)}`;
|
|
165513
165579
|
}
|
|
165514
165580
|
async function linkChatAttachmentsToWorkOrder(input) {
|
|
165515
165581
|
const warnings = [];
|
|
@@ -165560,11 +165626,11 @@ async function linkChatAttachmentsToWorkOrder(input) {
|
|
|
165560
165626
|
}
|
|
165561
165627
|
return { linked, warnings };
|
|
165562
165628
|
}
|
|
165563
|
-
var
|
|
165629
|
+
var import_node_crypto23;
|
|
165564
165630
|
var init_chat_workorder_files = __esm({
|
|
165565
165631
|
"../server/src/chat-workorder-files.ts"() {
|
|
165566
165632
|
"use strict";
|
|
165567
|
-
|
|
165633
|
+
import_node_crypto23 = require("node:crypto");
|
|
165568
165634
|
}
|
|
165569
165635
|
});
|
|
165570
165636
|
|
|
@@ -166332,11 +166398,11 @@ var init_config_store = __esm({
|
|
|
166332
166398
|
function clone2(value2) {
|
|
166333
166399
|
return structuredClone(value2);
|
|
166334
166400
|
}
|
|
166335
|
-
var
|
|
166401
|
+
var import_node_crypto24, import_promises2, import_node_path5, MemoryKnowledgeRunStore, FileKnowledgeRunStore;
|
|
166336
166402
|
var init_run_store = __esm({
|
|
166337
166403
|
"../server/src/domains/knowledge/run-store.ts"() {
|
|
166338
166404
|
"use strict";
|
|
166339
|
-
|
|
166405
|
+
import_node_crypto24 = require("node:crypto");
|
|
166340
166406
|
import_promises2 = require("node:fs/promises");
|
|
166341
166407
|
import_node_path5 = require("node:path");
|
|
166342
166408
|
MemoryKnowledgeRunStore = class {
|
|
@@ -166453,7 +166519,7 @@ var init_run_store = __esm({
|
|
|
166453
166519
|
}
|
|
166454
166520
|
async persist(runs) {
|
|
166455
166521
|
const shape = { version: 1, runs };
|
|
166456
|
-
const temp = `${this.file}.${process.pid}.${(0,
|
|
166522
|
+
const temp = `${this.file}.${process.pid}.${(0, import_node_crypto24.randomUUID)()}.tmp`;
|
|
166457
166523
|
try {
|
|
166458
166524
|
await (0, import_promises2.writeFile)(temp, `${JSON.stringify(shape, null, 2)}
|
|
166459
166525
|
`, { mode: 384 });
|
|
@@ -167026,11 +167092,11 @@ function retryableKnowledgeRun(record8) {
|
|
|
167026
167092
|
const latestAnswerAttempt = [...record8.attempts ?? []].reverse().find((attempt) => attempt.kind !== "fast");
|
|
167027
167093
|
return record8.status === "succeeded" && record8.request.action === "ask" && record8.executionHealth === "degraded" && latestAnswerAttempt?.status === "failed";
|
|
167028
167094
|
}
|
|
167029
|
-
var
|
|
167095
|
+
var import_node_crypto25, ACTION_LABEL, STATUS_MARKER, FINAL_ANSWER_MARKER, ACTIVE_STATUSES, RETRYABLE_STATUSES, HEARTBEAT_INTERVAL_MS, LEASE_MS, MAX_CONCURRENT_READS, ACTION_FLOW, KnowledgeService;
|
|
167030
167096
|
var init_service2 = __esm({
|
|
167031
167097
|
"../server/src/domains/knowledge/service.ts"() {
|
|
167032
167098
|
"use strict";
|
|
167033
|
-
|
|
167099
|
+
import_node_crypto25 = require("node:crypto");
|
|
167034
167100
|
init_src5();
|
|
167035
167101
|
init_config_store();
|
|
167036
167102
|
init_run_store();
|
|
@@ -167073,7 +167139,7 @@ var init_service2 = __esm({
|
|
|
167073
167139
|
constructor(options) {
|
|
167074
167140
|
this.options = options;
|
|
167075
167141
|
this.now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
167076
|
-
this.id = options.id ??
|
|
167142
|
+
this.id = options.id ?? import_node_crypto25.randomUUID;
|
|
167077
167143
|
this.runStore = options.runStore ?? new MemoryKnowledgeRunStore();
|
|
167078
167144
|
this.heartbeatIntervalMs = options.heartbeatIntervalMs ?? HEARTBEAT_INTERVAL_MS;
|
|
167079
167145
|
this.leaseMs = options.leaseMs ?? LEASE_MS;
|
|
@@ -178020,7 +178086,7 @@ function stableJson(value2) {
|
|
|
178020
178086
|
return JSON.stringify(stableValue(value2));
|
|
178021
178087
|
}
|
|
178022
178088
|
function sha256(value2) {
|
|
178023
|
-
return (0,
|
|
178089
|
+
return (0, import_node_crypto26.createHash)("sha256").update(value2).digest("hex");
|
|
178024
178090
|
}
|
|
178025
178091
|
function normalizeKnowledgeContent(title, content3) {
|
|
178026
178092
|
const body2 = content3.normalize("NFC").replace(/\r\n?/gu, "\n").replace(PUBLISH_MARKER, "\n").split("\n").map((line) => line.replace(/[\t ]+$/gu, "")).join("\n").replace(/\n{3,}/gu, "\n\n").trim();
|
|
@@ -178259,11 +178325,11 @@ function renderUntrustedKnowledgeFragment(input) {
|
|
|
178259
178325
|
"</knowledge>"
|
|
178260
178326
|
].join("\n");
|
|
178261
178327
|
}
|
|
178262
|
-
var
|
|
178328
|
+
var import_node_crypto26, KNOWLEDGE_NORMALIZER_VERSION, KNOWLEDGE_PACK_TEMPLATE_VERSION, PUBLISH_MARKER, STOPWORDS, LEXICAL_STOPWORDS, lexicalSegmenters, KNOWLEDGE_LEXICAL_INDEX_VERSION, KNOWLEDGE_MAINTENANCE_RELEVANCE_THRESHOLD, KNOWLEDGE_LAYOUT_TERMS;
|
|
178263
178329
|
var init_governance_content = __esm({
|
|
178264
178330
|
"../server/src/domains/knowledge/governance-content.ts"() {
|
|
178265
178331
|
"use strict";
|
|
178266
|
-
|
|
178332
|
+
import_node_crypto26 = require("node:crypto");
|
|
178267
178333
|
init_mdast_util_from_markdown();
|
|
178268
178334
|
init_mdast_util_gfm();
|
|
178269
178335
|
init_micromark_extension_gfm();
|
|
@@ -188430,11 +188496,11 @@ function approvedSnapshotBody(title, content3) {
|
|
|
188430
188496
|
function uniqueStrings(values) {
|
|
188431
188497
|
return [...new Set(values)].sort();
|
|
188432
188498
|
}
|
|
188433
|
-
var
|
|
188499
|
+
var import_node_crypto27, KnowledgeGovernanceError, put2, REMEDIATION_ACTION_BY_TASK, KnowledgeGovernanceService;
|
|
188434
188500
|
var init_governance_service = __esm({
|
|
188435
188501
|
"../server/src/domains/knowledge/governance-service.ts"() {
|
|
188436
188502
|
"use strict";
|
|
188437
|
-
|
|
188503
|
+
import_node_crypto27 = require("node:crypto");
|
|
188438
188504
|
init_governance_content();
|
|
188439
188505
|
init_knowledge_policy();
|
|
188440
188506
|
init_network_maintenance();
|
|
@@ -188456,7 +188522,7 @@ var init_governance_service = __esm({
|
|
|
188456
188522
|
constructor(options) {
|
|
188457
188523
|
this.options = options;
|
|
188458
188524
|
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
188459
|
-
this.id = options.id ?? ((prefix) => `${prefix}_${(0,
|
|
188525
|
+
this.id = options.id ?? ((prefix) => `${prefix}_${(0, import_node_crypto27.randomUUID)()}`);
|
|
188460
188526
|
this.versionViewBaseUrl = (options.versionViewBaseUrl ?? "/api/knowledge/items").replace(/\/$/u, "");
|
|
188461
188527
|
this.projectProvisionRetryDelayMs = Math.max(0, options.projectProvisionRetryDelayMs ?? 6e4);
|
|
188462
188528
|
this.projectProvisionMaxRetryDelayMs = Math.max(this.projectProvisionRetryDelayMs, options.projectProvisionMaxRetryDelayMs ?? 36e5);
|
|
@@ -194147,7 +194213,7 @@ function trustedKnowledgeInvocationId(body2, turn) {
|
|
|
194147
194213
|
if (body2.action !== "ask") return void 0;
|
|
194148
194214
|
const scope = turn?.artifactId ?? turn?.dispatchId;
|
|
194149
194215
|
if (!scope) return void 0;
|
|
194150
|
-
const fingerprint2 = (0,
|
|
194216
|
+
const fingerprint2 = (0, import_node_crypto28.createHash)("sha256").update(JSON.stringify({
|
|
194151
194217
|
action: body2.action,
|
|
194152
194218
|
message: body2.message?.trim() ?? "",
|
|
194153
194219
|
queryMode: body2.queryMode === "deep" ? "deep" : "fast",
|
|
@@ -194302,11 +194368,11 @@ function knowledgeRoutes(service, options = {}) {
|
|
|
194302
194368
|
});
|
|
194303
194369
|
};
|
|
194304
194370
|
}
|
|
194305
|
-
var
|
|
194371
|
+
var import_node_crypto28, KNOWLEDGE_WORKORDER_ACTIONS;
|
|
194306
194372
|
var init_routes = __esm({
|
|
194307
194373
|
"../server/src/domains/knowledge/routes.ts"() {
|
|
194308
194374
|
"use strict";
|
|
194309
|
-
|
|
194375
|
+
import_node_crypto28 = require("node:crypto");
|
|
194310
194376
|
init_src5();
|
|
194311
194377
|
init_router();
|
|
194312
194378
|
init_governance_service();
|
|
@@ -195933,7 +195999,7 @@ async function resolveChatAttachmentDiscoverySource(input) {
|
|
|
195933
195999
|
sourceType: input.sourceType,
|
|
195934
196000
|
sourceId: session.id,
|
|
195935
196001
|
sourceVersionId: attachment.blobRef,
|
|
195936
|
-
sourceFingerprint: (0,
|
|
196002
|
+
sourceFingerprint: (0, import_node_crypto29.createHash)("sha256").update(bytes2).digest("hex"),
|
|
195937
196003
|
sourceContent: new TextDecoder().decode(bytes2),
|
|
195938
196004
|
sourceDisplayName: attachment.name,
|
|
195939
196005
|
...session.projectId ? { projectId: session.projectId } : {},
|
|
@@ -195944,11 +196010,11 @@ async function resolveChatAttachmentDiscoverySource(input) {
|
|
|
195944
196010
|
}
|
|
195945
196011
|
};
|
|
195946
196012
|
}
|
|
195947
|
-
var
|
|
196013
|
+
var import_node_crypto29, TEXT_CONTENT_TYPES;
|
|
195948
196014
|
var init_chat_attachment_discovery = __esm({
|
|
195949
196015
|
"../server/src/domains/knowledge/chat-attachment-discovery.ts"() {
|
|
195950
196016
|
"use strict";
|
|
195951
|
-
|
|
196017
|
+
import_node_crypto29 = require("node:crypto");
|
|
195952
196018
|
TEXT_CONTENT_TYPES = /* @__PURE__ */ new Set([
|
|
195953
196019
|
"application/json",
|
|
195954
196020
|
"application/xml",
|
|
@@ -196125,8 +196191,8 @@ function aad(snapshot) {
|
|
|
196125
196191
|
}
|
|
196126
196192
|
function sealKnowledgeSnapshot(snapshot, key) {
|
|
196127
196193
|
if (snapshot.content.startsWith(PREFIX)) return structuredClone(snapshot);
|
|
196128
|
-
const iv = (0,
|
|
196129
|
-
const cipher = (0,
|
|
196194
|
+
const iv = (0, import_node_crypto30.randomBytes)(12);
|
|
196195
|
+
const cipher = (0, import_node_crypto30.createCipheriv)("aes-256-gcm", keyBytes(key), iv);
|
|
196130
196196
|
cipher.setAAD(aad(snapshot));
|
|
196131
196197
|
const encrypted = Buffer.concat([cipher.update(snapshot.content, "utf8"), cipher.final()]);
|
|
196132
196198
|
return {
|
|
@@ -196139,17 +196205,17 @@ function openKnowledgeSnapshot(snapshot, key) {
|
|
|
196139
196205
|
const packed = snapshot.content.slice(PREFIX.length).split(".");
|
|
196140
196206
|
if (packed.length !== 3 || packed.some((part) => !part)) throw new Error(`knowledge snapshot ${snapshot.ref} ciphertext is malformed`);
|
|
196141
196207
|
const [iv, tag, data] = packed;
|
|
196142
|
-
const decipher = (0,
|
|
196208
|
+
const decipher = (0, import_node_crypto30.createDecipheriv)("aes-256-gcm", keyBytes(key), Buffer.from(iv, "base64url"));
|
|
196143
196209
|
decipher.setAAD(aad(snapshot));
|
|
196144
196210
|
decipher.setAuthTag(Buffer.from(tag, "base64url"));
|
|
196145
196211
|
const content3 = Buffer.concat([decipher.update(Buffer.from(data, "base64url")), decipher.final()]).toString("utf8");
|
|
196146
196212
|
return { ...structuredClone(snapshot), content: content3 };
|
|
196147
196213
|
}
|
|
196148
|
-
var
|
|
196214
|
+
var import_node_crypto30, PREFIX;
|
|
196149
196215
|
var init_snapshot_crypto = __esm({
|
|
196150
196216
|
"../server/src/domains/knowledge/snapshot-crypto.ts"() {
|
|
196151
196217
|
"use strict";
|
|
196152
|
-
|
|
196218
|
+
import_node_crypto30 = require("node:crypto");
|
|
196153
196219
|
PREFIX = "oasis-knowledge:v1:";
|
|
196154
196220
|
}
|
|
196155
196221
|
});
|
|
@@ -196232,11 +196298,11 @@ function uniquenessKeys(kind, record8) {
|
|
|
196232
196298
|
return [];
|
|
196233
196299
|
}
|
|
196234
196300
|
}
|
|
196235
|
-
var
|
|
196301
|
+
var import_node_crypto31, import_promises3, import_node_path6, RECORD_KINDS, MemoryKnowledgeGovernanceStore, FileKnowledgeGovernanceStore;
|
|
196236
196302
|
var init_governance_store = __esm({
|
|
196237
196303
|
"../server/src/domains/knowledge/governance-store.ts"() {
|
|
196238
196304
|
"use strict";
|
|
196239
|
-
|
|
196305
|
+
import_node_crypto31 = require("node:crypto");
|
|
196240
196306
|
import_promises3 = require("node:fs/promises");
|
|
196241
196307
|
import_node_path6 = require("node:path");
|
|
196242
196308
|
init_snapshot_crypto();
|
|
@@ -196454,7 +196520,7 @@ var init_governance_store = __esm({
|
|
|
196454
196520
|
return result;
|
|
196455
196521
|
}
|
|
196456
196522
|
async persist(shape) {
|
|
196457
|
-
const temp = `${this.file}.${process.pid}.${(0,
|
|
196523
|
+
const temp = `${this.file}.${process.pid}.${(0, import_node_crypto31.randomUUID)()}.tmp`;
|
|
196458
196524
|
try {
|
|
196459
196525
|
await (0, import_promises3.writeFile)(temp, `${JSON.stringify(this.sealSnapshots(shape), null, 2)}
|
|
196460
196526
|
`, { mode: 384 });
|
|
@@ -196490,7 +196556,7 @@ async function loadOrCreateKnowledgeDeploymentId(file) {
|
|
|
196490
196556
|
if (error2.code !== "ENOENT") throw error2;
|
|
196491
196557
|
}
|
|
196492
196558
|
await (0, import_promises4.mkdir)((0, import_node_path7.dirname)(file), { recursive: true });
|
|
196493
|
-
const generated = `oasis-${(0,
|
|
196559
|
+
const generated = `oasis-${(0, import_node_crypto32.randomUUID)()}`;
|
|
196494
196560
|
try {
|
|
196495
196561
|
await (0, import_promises4.writeFile)(file, `${generated}
|
|
196496
196562
|
`, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
@@ -196500,11 +196566,11 @@ async function loadOrCreateKnowledgeDeploymentId(file) {
|
|
|
196500
196566
|
return readDeploymentId(file);
|
|
196501
196567
|
}
|
|
196502
196568
|
}
|
|
196503
|
-
var
|
|
196569
|
+
var import_node_crypto32, import_promises4, import_node_path7, VALID_DEPLOYMENT_ID;
|
|
196504
196570
|
var init_deployment_id = __esm({
|
|
196505
196571
|
"../server/src/domains/knowledge/deployment-id.ts"() {
|
|
196506
196572
|
"use strict";
|
|
196507
|
-
|
|
196573
|
+
import_node_crypto32 = require("node:crypto");
|
|
196508
196574
|
import_promises4 = require("node:fs/promises");
|
|
196509
196575
|
import_node_path7 = require("node:path");
|
|
196510
196576
|
VALID_DEPLOYMENT_ID = /^oasis-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
@@ -197201,7 +197267,7 @@ var init_files = __esm({
|
|
|
197201
197267
|
|
|
197202
197268
|
// ../server/src/domains/delegations/service.ts
|
|
197203
197269
|
function deterministicUuid(seed) {
|
|
197204
|
-
const h = (0,
|
|
197270
|
+
const h = (0, import_node_crypto33.createHash)("sha256").update(seed).digest();
|
|
197205
197271
|
const b2 = Buffer.from(h.subarray(0, 16));
|
|
197206
197272
|
b2[6] = b2[6] & 15 | 80;
|
|
197207
197273
|
b2[8] = b2[8] & 63 | 128;
|
|
@@ -197258,11 +197324,11 @@ async function seedChildRoundRows(chatStore, childSessionId, round, prompt2, now
|
|
|
197258
197324
|
createdAt: now
|
|
197259
197325
|
});
|
|
197260
197326
|
}
|
|
197261
|
-
var
|
|
197327
|
+
var import_node_crypto33, DelegationError, TITLE_TASK_CHARS, DIGEST_CHARS, PENDING_QUEUE_OWNER, DISPATCH_LEASE_MS, CONSECUTIVE_FAIL_LIMIT, DelegationService;
|
|
197262
197328
|
var init_service3 = __esm({
|
|
197263
197329
|
"../server/src/domains/delegations/service.ts"() {
|
|
197264
197330
|
"use strict";
|
|
197265
|
-
|
|
197331
|
+
import_node_crypto33 = require("node:crypto");
|
|
197266
197332
|
init_src();
|
|
197267
197333
|
init_parent_conversation();
|
|
197268
197334
|
init_deletion();
|
|
@@ -198464,7 +198530,7 @@ var init_continue_outcome = __esm({
|
|
|
198464
198530
|
function trustedDelegationInvocationId(body2, turn) {
|
|
198465
198531
|
const scope = turn?.artifactId ?? turn?.dispatchId;
|
|
198466
198532
|
if (!scope) return void 0;
|
|
198467
|
-
const fingerprint2 = (0,
|
|
198533
|
+
const fingerprint2 = (0, import_node_crypto34.createHash)("sha256").update(JSON.stringify({ to: body2.to?.trim() ?? "", task: body2.task ?? "", as: body2.as?.trim() ?? "", files: body2.files ?? [] })).digest("hex").slice(0, 20);
|
|
198468
198534
|
return `dispatch:${scope}:delegation:${fingerprint2}`;
|
|
198469
198535
|
}
|
|
198470
198536
|
function callerOf(req, invocationId) {
|
|
@@ -198559,11 +198625,11 @@ function delegationRoutes(service) {
|
|
|
198559
198625
|
});
|
|
198560
198626
|
};
|
|
198561
198627
|
}
|
|
198562
|
-
var
|
|
198628
|
+
var import_node_crypto34;
|
|
198563
198629
|
var init_routes2 = __esm({
|
|
198564
198630
|
"../server/src/domains/delegations/routes.ts"() {
|
|
198565
198631
|
"use strict";
|
|
198566
|
-
|
|
198632
|
+
import_node_crypto34 = require("node:crypto");
|
|
198567
198633
|
init_router();
|
|
198568
198634
|
init_continue_outcome();
|
|
198569
198635
|
init_service3();
|
|
@@ -200517,7 +200583,7 @@ function createAppJwt(appId, privateKeyPem, nowMs) {
|
|
|
200517
200583
|
exp: nowSec + JWT_TTL_SEC,
|
|
200518
200584
|
iss: appId
|
|
200519
200585
|
}));
|
|
200520
|
-
const signer = (0,
|
|
200586
|
+
const signer = (0, import_node_crypto35.createSign)("RSA-SHA256");
|
|
200521
200587
|
signer.update(`${header}.${payload2}`);
|
|
200522
200588
|
signer.end();
|
|
200523
200589
|
try {
|
|
@@ -200680,11 +200746,11 @@ async function exchangeManifestCode(code2, deps = {}) {
|
|
|
200680
200746
|
...typeof body2["client_secret"] === "string" ? { clientSecret: body2["client_secret"] } : {}
|
|
200681
200747
|
};
|
|
200682
200748
|
}
|
|
200683
|
-
var
|
|
200749
|
+
var import_node_crypto35, GITHUB_API, JWT_TTL_SEC, JWT_IAT_SKEW_SEC, defaultDeps2;
|
|
200684
200750
|
var init_app_auth = __esm({
|
|
200685
200751
|
"../connectors/src/github/app-auth.ts"() {
|
|
200686
200752
|
"use strict";
|
|
200687
|
-
|
|
200753
|
+
import_node_crypto35 = require("node:crypto");
|
|
200688
200754
|
GITHUB_API = "https://api.github.com";
|
|
200689
200755
|
JWT_TTL_SEC = 9 * 60;
|
|
200690
200756
|
JWT_IAT_SKEW_SEC = 60;
|
|
@@ -201609,11 +201675,11 @@ function extractOutlineKnowledgeCandidateDrafts(events) {
|
|
|
201609
201675
|
}
|
|
201610
201676
|
return [...drafts.values()];
|
|
201611
201677
|
}
|
|
201612
|
-
var
|
|
201678
|
+
var import_node_crypto36, REQUEST_TIMEOUT_MS, WRITE_ENDPOINTS, DEFAULT_WRITE_INTERVAL_MS, DEFAULT_RATE_LIMIT_RETRIES, DEFAULT_MAX_RATE_LIMIT_DELAY_MS, OutlineKnowledgeApiError, writeCoordinators, OutlineKnowledgeApi, INIT_DEFINITIONS, REPAIRABLE_LINT_CODES;
|
|
201613
201679
|
var init_knowledge_api = __esm({
|
|
201614
201680
|
"../connectors/src/outline/knowledge-api.ts"() {
|
|
201615
201681
|
"use strict";
|
|
201616
|
-
|
|
201682
|
+
import_node_crypto36 = require("node:crypto");
|
|
201617
201683
|
REQUEST_TIMEOUT_MS = 2e4;
|
|
201618
201684
|
WRITE_ENDPOINTS = /* @__PURE__ */ new Set(["collections.create", "documents.create", "documents.update", "documents.publish"]);
|
|
201619
201685
|
DEFAULT_WRITE_INTERVAL_MS = process.env["NODE_ENV"] === "test" ? 0 : 250;
|
|
@@ -201640,7 +201706,7 @@ var init_knowledge_api = __esm({
|
|
|
201640
201706
|
this.baseUrl = canonicalUrl(baseUrl);
|
|
201641
201707
|
this.lastResponseBaseUrl = this.baseUrl;
|
|
201642
201708
|
this.token = token;
|
|
201643
|
-
this.coordinatorKey = `${this.baseUrl}:${(0,
|
|
201709
|
+
this.coordinatorKey = `${this.baseUrl}:${(0, import_node_crypto36.createHash)("sha256").update(token).digest("hex")}`;
|
|
201644
201710
|
this.writeIntervalMs = Math.max(0, options.writeIntervalMs ?? DEFAULT_WRITE_INTERVAL_MS);
|
|
201645
201711
|
this.maxRateLimitRetries = Math.max(0, options.maxRateLimitRetries ?? DEFAULT_RATE_LIMIT_RETRIES);
|
|
201646
201712
|
this.maxRateLimitDelayMs = Math.max(0, options.maxRateLimitDelayMs ?? DEFAULT_MAX_RATE_LIMIT_DELAY_MS);
|
|
@@ -203048,15 +203114,15 @@ function classifyOutlineGovernedMigrationDocument(document4) {
|
|
|
203048
203114
|
if (path41.startsWith("wiki/sources/")) return { mapping: "formal", metadata: legacyMetadata(document4, "source_note"), reason: "legacy_source_note" };
|
|
203049
203115
|
return { mapping: "excluded", reason: "legacy_unmapped_path" };
|
|
203050
203116
|
}
|
|
203051
|
-
var
|
|
203117
|
+
var import_node_crypto37, value, text4, hash, REVISION_VISIBILITY_RETRY_DELAYS_MS, governedProvisionRuns, PUBLISH_MARKER2, PUBLISH_MARKER_PRESENT;
|
|
203052
203118
|
var init_governed_knowledge = __esm({
|
|
203053
203119
|
"../connectors/src/outline/governed-knowledge.ts"() {
|
|
203054
203120
|
"use strict";
|
|
203055
|
-
|
|
203121
|
+
import_node_crypto37 = require("node:crypto");
|
|
203056
203122
|
init_knowledge_api();
|
|
203057
203123
|
value = (input) => input && typeof input === "object" && !Array.isArray(input) ? input : null;
|
|
203058
203124
|
text4 = (input) => typeof input === "string" && input.trim() ? input.trim() : null;
|
|
203059
|
-
hash = (input) => (0,
|
|
203125
|
+
hash = (input) => (0, import_node_crypto37.createHash)("sha256").update(input.normalize("NFC").replace(/\r\n?/gu, "\n")).digest("hex");
|
|
203060
203126
|
REVISION_VISIBILITY_RETRY_DELAYS_MS = [0, 100, 250, 500, 1e3, 2e3];
|
|
203061
203127
|
governedProvisionRuns = /* @__PURE__ */ new Map();
|
|
203062
203128
|
PUBLISH_MARKER2 = /\n?<!--\s*oasis-publish:[\s\S]*?-->\n?/giu;
|
|
@@ -205491,14 +205557,7 @@ async function startOasisServer(opts) {
|
|
|
205491
205557
|
}
|
|
205492
205558
|
return null;
|
|
205493
205559
|
};
|
|
205494
|
-
const outputsPartFor = (chatSessionId, companyId) =>
|
|
205495
|
-
const scan2 = opts.sessionOutputsScan;
|
|
205496
|
-
if (!scan2) return void 0;
|
|
205497
|
-
return async () => {
|
|
205498
|
-
const files = await scan2({ chatSessionId, ...companyId !== void 0 ? { companyId } : {} });
|
|
205499
|
-
return files && files.length > 0 ? { type: "outputs", seq: 0, outputs: files } : null;
|
|
205500
|
-
};
|
|
205501
|
-
};
|
|
205560
|
+
const outputsPartFor = (chatSessionId, companyId) => outputsPartProvider(opts.sessionOutputsScan, chatSessionId, companyId);
|
|
205502
205561
|
async function anchorMessageIdFor(origin, storeFor) {
|
|
205503
205562
|
if (!origin) return void 0;
|
|
205504
205563
|
const live = liveChat.messageFor(origin);
|
|
@@ -205737,10 +205796,10 @@ async function startOasisServer(opts) {
|
|
|
205737
205796
|
...fp(p2)
|
|
205738
205797
|
}))
|
|
205739
205798
|
] : [];
|
|
205740
|
-
const { randomUUID:
|
|
205799
|
+
const { randomUUID: randomUUID43 } = await import("node:crypto");
|
|
205741
205800
|
try {
|
|
205742
205801
|
await store.enqueuePendingMessage({
|
|
205743
|
-
id:
|
|
205802
|
+
id: randomUUID43(),
|
|
205744
205803
|
chatSessionId: input.chatSessionId,
|
|
205745
205804
|
text: input.text,
|
|
205746
205805
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -205773,11 +205832,11 @@ async function startOasisServer(opts) {
|
|
|
205773
205832
|
...f2?.mtime ? { srcMtime: f2.mtime } : {}
|
|
205774
205833
|
};
|
|
205775
205834
|
});
|
|
205776
|
-
const { randomUUID:
|
|
205835
|
+
const { randomUUID: randomUUID43 } = await import("node:crypto");
|
|
205777
205836
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
205778
205837
|
try {
|
|
205779
205838
|
await store.enqueuePendingMessage({
|
|
205780
|
-
id:
|
|
205839
|
+
id: randomUUID43(),
|
|
205781
205840
|
chatSessionId: input.chatSessionId,
|
|
205782
205841
|
text: "",
|
|
205783
205842
|
createdAt: nowIso,
|
|
@@ -207024,7 +207083,7 @@ async function startOasisServer(opts) {
|
|
|
207024
207083
|
entry = {
|
|
207025
207084
|
// 旧 CLI 未带 waiterId 时给它塞一个服务端本地生成的——它绝不可能出现在 leave 上,
|
|
207026
207085
|
// 也就绝不会误命中 leftWaiterIds、绝不会被别人的 leave 摘掉。行为与旧 CLI 相同。
|
|
207027
|
-
waiterId: clientWaiterId ?? `server:${(0,
|
|
207086
|
+
waiterId: clientWaiterId ?? `server:${(0, import_node_crypto38.randomUUID)()}`,
|
|
207028
207087
|
onResolve,
|
|
207029
207088
|
expiresAt: expiresAt2,
|
|
207030
207089
|
cleanup: () => clearTimeout(expiryTimer),
|
|
@@ -207105,7 +207164,7 @@ async function startOasisServer(opts) {
|
|
|
207105
207164
|
const openRoom = async () => {
|
|
207106
207165
|
let chatSessionId2;
|
|
207107
207166
|
if (chatStore) {
|
|
207108
|
-
const { randomUUID:
|
|
207167
|
+
const { randomUUID: randomUUID43 } = await import("node:crypto");
|
|
207109
207168
|
const known = discussSessions.get(itemKey);
|
|
207110
207169
|
const knownSession = known ? await chatStore.getSession(known) : null;
|
|
207111
207170
|
if (knownSession && knownSession.workspace === ctx.workspace && knownSession.humanActorId === ctx.ownerId && (!body2.escalationId || knownSession.escalationId === body2.escalationId)) chatSessionId2 = known;
|
|
@@ -207114,7 +207173,7 @@ async function startOasisServer(opts) {
|
|
|
207114
207173
|
chatSessionId2 = existing[0]?.id;
|
|
207115
207174
|
}
|
|
207116
207175
|
if (!chatSessionId2) {
|
|
207117
|
-
chatSessionId2 =
|
|
207176
|
+
chatSessionId2 = randomUUID43();
|
|
207118
207177
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
207119
207178
|
const title = `\u89E3\u51B3\uFF1A${ctx.seed.slice(ctx.seed.indexOf("\uFF1A") + 1, ctx.seed.indexOf("\uFF1A") + 25) || "\u5DE5\u5355\u5361\u70B9"}`;
|
|
207120
207179
|
const reg0 = (await resolveEngine(currentCompanyId).catch(() => null))?.registry ?? opts.registry;
|
|
@@ -207983,14 +208042,14 @@ ${composed}`;
|
|
|
207983
208042
|
runtimeSessionId: session.nativeSessionId ?? session.id
|
|
207984
208043
|
}).catch(() => void 0);
|
|
207985
208044
|
}
|
|
207986
|
-
const { randomUUID:
|
|
208045
|
+
const { randomUUID: randomUUID44 } = await import("node:crypto");
|
|
207987
208046
|
const persistAttachments = effectiveAttachments.map((a) => ({
|
|
207988
208047
|
name: a.name,
|
|
207989
208048
|
...a.blobRef !== void 0 ? { blobRef: a.blobRef } : {},
|
|
207990
208049
|
...a.contentType !== void 0 ? { contentType: a.contentType } : {}
|
|
207991
208050
|
}));
|
|
207992
208051
|
await chatStore.appendMessage({
|
|
207993
|
-
id:
|
|
208052
|
+
id: randomUUID44(),
|
|
207994
208053
|
sessionId: persistTarget.id,
|
|
207995
208054
|
role: "user",
|
|
207996
208055
|
content: persistedUserMessage,
|
|
@@ -208465,8 +208524,8 @@ ${composed}`;
|
|
|
208465
208524
|
}
|
|
208466
208525
|
}
|
|
208467
208526
|
const { spawn: spawn10 } = await import("node:child_process");
|
|
208468
|
-
const { randomUUID:
|
|
208469
|
-
const sessionId = body2.sessionId ??
|
|
208527
|
+
const { randomUUID: randomUUID43 } = await import("node:crypto");
|
|
208528
|
+
const sessionId = body2.sessionId ?? randomUUID43();
|
|
208470
208529
|
const args = [
|
|
208471
208530
|
"-p",
|
|
208472
208531
|
body2.message,
|
|
@@ -208762,8 +208821,8 @@ ${composed}`;
|
|
|
208762
208821
|
res.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: `\u56DE\u8C03\u5730\u5740\u4E0D\u53EF\u7528\uFF0C\u5DF2\u4E2D\u6B62\uFF08\u907F\u514D\u5728 GitHub \u4E0A\u7559\u4E0B\u5B64\u513F App\uFF09\uFF1A${e.message}` }));
|
|
208763
208822
|
return;
|
|
208764
208823
|
}
|
|
208765
|
-
const { randomUUID:
|
|
208766
|
-
const state =
|
|
208824
|
+
const { randomUUID: randomUUID43 } = await import("node:crypto");
|
|
208825
|
+
const state = randomUUID43();
|
|
208767
208826
|
const nameSlug = (actorName || actorId?.split(":").pop() || owner?.login || "bot").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-|-$/g, "").slice(0, 24) || "bot";
|
|
208768
208827
|
const manifest = buildAppManifest({
|
|
208769
208828
|
employeeSlug: nameSlug,
|
|
@@ -209539,12 +209598,12 @@ ${composed}`;
|
|
|
209539
209598
|
}
|
|
209540
209599
|
};
|
|
209541
209600
|
}
|
|
209542
|
-
var http,
|
|
209601
|
+
var http, import_node_crypto38, githubAppPending, connectorAuthSnapshots, CONNECTOR_AUTH_SNAPSHOT_TTL_MS, defaultResolveActor, enc, CHAT_OUTPUT_LIMIT, STREAMING_PATHS, PLANNER_BLOCKING_CODES, WILL_VERBS, GOVERNANCE_COMMANDS, READ_ONLY_COMMANDS, isAgent, isHuman;
|
|
209543
209602
|
var init_server3 = __esm({
|
|
209544
209603
|
"../server/src/server.ts"() {
|
|
209545
209604
|
"use strict";
|
|
209546
209605
|
http = __toESM(require("node:http"), 1);
|
|
209547
|
-
|
|
209606
|
+
import_node_crypto38 = require("node:crypto");
|
|
209548
209607
|
init_chat_session();
|
|
209549
209608
|
init_chat_system_message();
|
|
209550
209609
|
init_src();
|
|
@@ -209703,7 +209762,7 @@ function createNodeTokenStore(file) {
|
|
|
209703
209762
|
return {
|
|
209704
209763
|
issue(nodeId) {
|
|
209705
209764
|
const table = read();
|
|
209706
|
-
const token = `ont_${(0,
|
|
209765
|
+
const token = `ont_${(0, import_node_crypto39.randomBytes)(24).toString("base64url")}`;
|
|
209707
209766
|
table[token] = nodeId;
|
|
209708
209767
|
write(table);
|
|
209709
209768
|
return token;
|
|
@@ -209745,7 +209804,7 @@ function createEnrollTokenStore(defaultTtlMs = 30 * 60 * 1e3, file) {
|
|
|
209745
209804
|
return {
|
|
209746
209805
|
issue(name, ttlMs = defaultTtlMs, companyId) {
|
|
209747
209806
|
const m2 = prune();
|
|
209748
|
-
const token = `ent_${(0,
|
|
209807
|
+
const token = `ent_${(0, import_node_crypto39.randomBytes)(24).toString("base64url")}`;
|
|
209749
209808
|
const expiresAt2 = Date.now() + ttlMs;
|
|
209750
209809
|
m2.set(token, { name, expiresAt: expiresAt2, ...companyId !== void 0 ? { companyId } : {} });
|
|
209751
209810
|
write(m2);
|
|
@@ -209794,33 +209853,33 @@ function createEnrollTokenStore(defaultTtlMs = 30 * 60 * 1e3, file) {
|
|
|
209794
209853
|
}
|
|
209795
209854
|
};
|
|
209796
209855
|
}
|
|
209797
|
-
var
|
|
209856
|
+
var import_node_crypto39, fs18, path19, SESSION_TOKEN_PREFIX, b64url2, fromB64url, readOrCreateSecret, sign, signatureMatches, isTokenClaims;
|
|
209798
209857
|
var init_tokens = __esm({
|
|
209799
209858
|
"../server/src/tokens.ts"() {
|
|
209800
209859
|
"use strict";
|
|
209801
|
-
|
|
209860
|
+
import_node_crypto39 = require("node:crypto");
|
|
209802
209861
|
fs18 = __toESM(require("node:fs"), 1);
|
|
209803
209862
|
path19 = __toESM(require("node:path"), 1);
|
|
209804
209863
|
SESSION_TOKEN_PREFIX = "oat_v2_";
|
|
209805
209864
|
b64url2 = (value2) => Buffer.from(value2).toString("base64url");
|
|
209806
209865
|
fromB64url = (value2) => Buffer.from(value2, "base64url").toString("utf8");
|
|
209807
209866
|
readOrCreateSecret = (file) => {
|
|
209808
|
-
if (!file) return (0,
|
|
209867
|
+
if (!file) return (0, import_node_crypto39.randomBytes)(32);
|
|
209809
209868
|
try {
|
|
209810
209869
|
const raw = fs18.readFileSync(file, "utf8").trim();
|
|
209811
209870
|
if (raw) return Buffer.from(raw, "base64url");
|
|
209812
209871
|
} catch {
|
|
209813
209872
|
}
|
|
209814
|
-
const secret = (0,
|
|
209873
|
+
const secret = (0, import_node_crypto39.randomBytes)(32);
|
|
209815
209874
|
fs18.mkdirSync(path19.dirname(file), { recursive: true });
|
|
209816
209875
|
fs18.writeFileSync(file, secret.toString("base64url"), { mode: 384 });
|
|
209817
209876
|
return secret;
|
|
209818
209877
|
};
|
|
209819
|
-
sign = (secret, payload2) => (0,
|
|
209878
|
+
sign = (secret, payload2) => (0, import_node_crypto39.createHmac)("sha256", secret).update(payload2).digest("base64url");
|
|
209820
209879
|
signatureMatches = (actual, expected) => {
|
|
209821
209880
|
const a = Buffer.from(actual);
|
|
209822
209881
|
const b2 = Buffer.from(expected);
|
|
209823
|
-
return a.length === b2.length && (0,
|
|
209882
|
+
return a.length === b2.length && (0, import_node_crypto39.timingSafeEqual)(a, b2);
|
|
209824
209883
|
};
|
|
209825
209884
|
isTokenClaims = (value2) => {
|
|
209826
209885
|
if (value2 === null || typeof value2 !== "object") return false;
|
|
@@ -209867,31 +209926,31 @@ function createDataplaneTokenIssuer(opts = {}) {
|
|
|
209867
209926
|
}
|
|
209868
209927
|
};
|
|
209869
209928
|
}
|
|
209870
|
-
var
|
|
209929
|
+
var import_node_crypto40, fs19, path20, PREFIX2, b64url3, fromB64url2, sign2, sigMatches, readOrCreateSecret2, isClaims;
|
|
209871
209930
|
var init_session_dataplane_token = __esm({
|
|
209872
209931
|
"../server/src/session-dataplane-token.ts"() {
|
|
209873
209932
|
"use strict";
|
|
209874
|
-
|
|
209933
|
+
import_node_crypto40 = require("node:crypto");
|
|
209875
209934
|
fs19 = __toESM(require("node:fs"), 1);
|
|
209876
209935
|
path20 = __toESM(require("node:path"), 1);
|
|
209877
209936
|
init_src();
|
|
209878
209937
|
PREFIX2 = "osd_";
|
|
209879
209938
|
b64url3 = (v2) => Buffer.from(v2, "utf8").toString("base64url");
|
|
209880
209939
|
fromB64url2 = (v2) => Buffer.from(v2, "base64url").toString("utf8");
|
|
209881
|
-
sign2 = (secret, payload2) => (0,
|
|
209940
|
+
sign2 = (secret, payload2) => (0, import_node_crypto40.createHmac)("sha256", secret).update(payload2).digest("base64url");
|
|
209882
209941
|
sigMatches = (actual, expected) => {
|
|
209883
209942
|
const a = Buffer.from(actual);
|
|
209884
209943
|
const b2 = Buffer.from(expected);
|
|
209885
|
-
return a.length === b2.length && (0,
|
|
209944
|
+
return a.length === b2.length && (0, import_node_crypto40.timingSafeEqual)(a, b2);
|
|
209886
209945
|
};
|
|
209887
209946
|
readOrCreateSecret2 = (file) => {
|
|
209888
|
-
if (!file) return (0,
|
|
209947
|
+
if (!file) return (0, import_node_crypto40.randomBytes)(32);
|
|
209889
209948
|
try {
|
|
209890
209949
|
const raw = fs19.readFileSync(file, "utf8").trim();
|
|
209891
209950
|
if (raw) return Buffer.from(raw, "base64url");
|
|
209892
209951
|
} catch {
|
|
209893
209952
|
}
|
|
209894
|
-
const secret = (0,
|
|
209953
|
+
const secret = (0, import_node_crypto40.randomBytes)(32);
|
|
209895
209954
|
fs19.mkdirSync(path20.dirname(file), { recursive: true });
|
|
209896
209955
|
fs19.writeFileSync(file, secret.toString("base64url"), { mode: 384 });
|
|
209897
209956
|
return secret;
|
|
@@ -212037,11 +212096,11 @@ function onlyHits(pool, q2) {
|
|
|
212037
212096
|
if (!q2.requireMatch || q2.keywords.length === 0) return [...pool];
|
|
212038
212097
|
return pool.filter((r) => memoryMatchScore(r, q2.keywords) > 0);
|
|
212039
212098
|
}
|
|
212040
|
-
var
|
|
212099
|
+
var import_node_crypto41, MemoryActorMemoryStore, toIndexEntry;
|
|
212041
212100
|
var init_memory_actor_memory_store = __esm({
|
|
212042
212101
|
"../testkit/src/memory-actor-memory-store.ts"() {
|
|
212043
212102
|
"use strict";
|
|
212044
|
-
|
|
212103
|
+
import_node_crypto41 = require("node:crypto");
|
|
212045
212104
|
init_src();
|
|
212046
212105
|
MemoryActorMemoryStore = class {
|
|
212047
212106
|
rows = /* @__PURE__ */ new Map();
|
|
@@ -212095,7 +212154,7 @@ var init_memory_actor_memory_store = __esm({
|
|
|
212095
212154
|
async write(input, now) {
|
|
212096
212155
|
if (input.memId === void 0) {
|
|
212097
212156
|
const rec = {
|
|
212098
|
-
memId: `mem:${(0,
|
|
212157
|
+
memId: `mem:${(0, import_node_crypto41.randomUUID)()}`,
|
|
212099
212158
|
actorId: input.actorId,
|
|
212100
212159
|
projectId: input.projectId,
|
|
212101
212160
|
keywords: [...input.keywords],
|
|
@@ -212829,13 +212888,13 @@ var init_stats = __esm({
|
|
|
212829
212888
|
|
|
212830
212889
|
// ../server/src/domains/projects/project-id.ts
|
|
212831
212890
|
function randomProjectId() {
|
|
212832
|
-
return projectIdFromUuid((0,
|
|
212891
|
+
return projectIdFromUuid((0, import_node_crypto42.randomUUID)());
|
|
212833
212892
|
}
|
|
212834
|
-
var
|
|
212893
|
+
var import_node_crypto42;
|
|
212835
212894
|
var init_project_id = __esm({
|
|
212836
212895
|
"../server/src/domains/projects/project-id.ts"() {
|
|
212837
212896
|
"use strict";
|
|
212838
|
-
|
|
212897
|
+
import_node_crypto42 = require("node:crypto");
|
|
212839
212898
|
init_src();
|
|
212840
212899
|
}
|
|
212841
212900
|
});
|
|
@@ -212900,7 +212959,7 @@ function creatorKindOf(actorId) {
|
|
|
212900
212959
|
if (!actorId) return null;
|
|
212901
212960
|
return actorId.startsWith("actor:human:") ? "human" : "agent";
|
|
212902
212961
|
}
|
|
212903
|
-
function emitChatFolders(items, chatFiles, resolveName) {
|
|
212962
|
+
function emitChatFolders(items, chatFiles, resolveName, taskTitles = /* @__PURE__ */ new Map()) {
|
|
212904
212963
|
const groups = /* @__PURE__ */ new Map();
|
|
212905
212964
|
for (const file of chatFiles) {
|
|
212906
212965
|
const list2 = groups.get(file.chatSessionId) ?? [];
|
|
@@ -212920,14 +212979,15 @@ function emitChatFolders(items, chatFiles, resolveName) {
|
|
|
212920
212979
|
depth: 0,
|
|
212921
212980
|
type: "folder",
|
|
212922
212981
|
size: null,
|
|
212923
|
-
taskId: null,
|
|
212924
|
-
taskTitle: CHAT_FOLDER_TASK_LABEL,
|
|
212982
|
+
taskId: head.taskId ?? null,
|
|
212983
|
+
taskTitle: head.taskId ? taskTitles.get(head.taskId) ?? head.taskId : CHAT_FOLDER_TASK_LABEL,
|
|
212925
212984
|
creatorKind: creatorKindOf(head.chatOwnerId),
|
|
212926
212985
|
creatorId: head.chatOwnerId,
|
|
212927
212986
|
creatorName: resolveName(head.chatOwnerId),
|
|
212928
212987
|
updatedAt: latest,
|
|
212929
212988
|
folderKind: "chat",
|
|
212930
|
-
chatSessionId: sessionId
|
|
212989
|
+
chatSessionId: sessionId,
|
|
212990
|
+
...head.fileIssues?.length ? { fileIssues: head.fileIssues } : {}
|
|
212931
212991
|
});
|
|
212932
212992
|
for (const file of group) {
|
|
212933
212993
|
items.push({
|
|
@@ -212941,13 +213001,14 @@ function emitChatFolders(items, chatFiles, resolveName) {
|
|
|
212941
213001
|
blobRef: file.blobId,
|
|
212942
213002
|
contentType: file.contentType ?? null,
|
|
212943
213003
|
size: file.size,
|
|
212944
|
-
taskId: null,
|
|
212945
|
-
taskTitle: CHAT_FOLDER_TASK_LABEL,
|
|
213004
|
+
taskId: head.taskId ?? null,
|
|
213005
|
+
taskTitle: head.taskId ? taskTitles.get(head.taskId) ?? head.taskId : CHAT_FOLDER_TASK_LABEL,
|
|
212946
213006
|
creatorKind: creatorKindOf(file.uploadedBy),
|
|
212947
213007
|
creatorId: file.uploadedBy ?? null,
|
|
212948
213008
|
creatorName: file.uploadedBy ? resolveName(file.uploadedBy) : null,
|
|
212949
213009
|
updatedAt: file.uploadedAt,
|
|
212950
|
-
chatSessionId: sessionId
|
|
213010
|
+
chatSessionId: sessionId,
|
|
213011
|
+
...head.fileIssues?.length ? { fileIssues: head.fileIssues } : {}
|
|
212951
213012
|
});
|
|
212952
213013
|
}
|
|
212953
213014
|
}
|
|
@@ -214009,7 +214070,7 @@ var init_service4 = __esm({
|
|
|
214009
214070
|
updatedAt: file.uploadedAt
|
|
214010
214071
|
});
|
|
214011
214072
|
}
|
|
214012
|
-
emitChatFolders(items, chatFiles, (actorId) => this.resolveActorName(actorId));
|
|
214073
|
+
emitChatFolders(items, chatFiles, (actorId) => this.resolveActorName(actorId), workorderTitleById);
|
|
214013
214074
|
fillFolderSizes(items);
|
|
214014
214075
|
const chatFolderTime = new Map(items.filter((item) => item.folderKind === "chat" && item.chatSessionId).map((item) => [item.chatSessionId, item.updatedAt]));
|
|
214015
214076
|
items.sort((a, b2) => {
|
|
@@ -214860,12 +214921,12 @@ var init_service4 = __esm({
|
|
|
214860
214921
|
});
|
|
214861
214922
|
|
|
214862
214923
|
// ../server/src/dev-store.ts
|
|
214863
|
-
var
|
|
214924
|
+
var import_node_crypto43, fs20, path21, NdjsonOplogStore, DirBlobStore, MUTATORS, FileTypeRegistryStore, FileRoleRegistryStore, FileRegistryStore, FileAssistantBindStore, FileHumanPrefsStore, FileProjectStateStore, FileArtifactStateStore, FileTraceStore, MemoryChatSessionStore, FileChatSessionStore, MemoryChatTurnStore, FileChatTurnStore, MemoryReadMarkerStore, FileReadMarkerStore;
|
|
214864
214925
|
var init_dev_store = __esm({
|
|
214865
214926
|
"../server/src/dev-store.ts"() {
|
|
214866
214927
|
"use strict";
|
|
214867
214928
|
init_src();
|
|
214868
|
-
|
|
214929
|
+
import_node_crypto43 = require("node:crypto");
|
|
214869
214930
|
fs20 = __toESM(require("node:fs"), 1);
|
|
214870
214931
|
path21 = __toESM(require("node:path"), 1);
|
|
214871
214932
|
init_src();
|
|
@@ -214919,7 +214980,7 @@ var init_dev_store = __esm({
|
|
|
214919
214980
|
return path21.join(this.dir, hash2);
|
|
214920
214981
|
}
|
|
214921
214982
|
async put(bytes2) {
|
|
214922
|
-
const hash2 = (0,
|
|
214983
|
+
const hash2 = (0, import_node_crypto43.createHash)("sha256").update(bytes2).digest("hex");
|
|
214923
214984
|
const file = this.fileOf(hash2);
|
|
214924
214985
|
if (!fs20.existsSync(file)) fs20.writeFileSync(file, bytes2);
|
|
214925
214986
|
return hash2;
|
|
@@ -215347,6 +215408,8 @@ var init_dev_store = __esm({
|
|
|
215347
215408
|
pending = /* @__PURE__ */ new Map();
|
|
215348
215409
|
/** `outputs/` 产出文件的服务端副本表(2026-09-14):sessionId → 路径 → 副本。 */
|
|
215349
215410
|
outputCopies = /* @__PURE__ */ new Map();
|
|
215411
|
+
outputFingerprints = /* @__PURE__ */ new Map();
|
|
215412
|
+
fileIssues = /* @__PURE__ */ new Map();
|
|
215350
215413
|
pendingSeq = 0;
|
|
215351
215414
|
async claimPendingInsert(m2) {
|
|
215352
215415
|
const list2 = this.pending.get(m2.chatSessionId) ?? [];
|
|
@@ -215535,6 +215598,8 @@ var init_dev_store = __esm({
|
|
|
215535
215598
|
this.sessionWorkOrders.delete(id);
|
|
215536
215599
|
this.sessionWorkOrderKinds.delete(id);
|
|
215537
215600
|
this.outputCopies.delete(id);
|
|
215601
|
+
this.outputFingerprints.delete(id);
|
|
215602
|
+
this.fileIssues.delete(id);
|
|
215538
215603
|
}
|
|
215539
215604
|
async appendMessage(m2) {
|
|
215540
215605
|
return (await this.appendMessageOnce(m2)).message;
|
|
@@ -215663,6 +215728,22 @@ var init_dev_store = __esm({
|
|
|
215663
215728
|
}
|
|
215664
215729
|
return rows.sort((left, right) => left.createdAt.localeCompare(right.createdAt) || left.messageId.localeCompare(right.messageId));
|
|
215665
215730
|
}
|
|
215731
|
+
async readOutputFingerprints(sessionId) {
|
|
215732
|
+
return this.outputFingerprints.get(sessionId) ?? null;
|
|
215733
|
+
}
|
|
215734
|
+
async writeOutputFingerprints(sessionId, fingerprints) {
|
|
215735
|
+
if (this.sessions.has(sessionId)) this.outputFingerprints.set(sessionId, { ...fingerprints });
|
|
215736
|
+
}
|
|
215737
|
+
async readFileIssues(sessionId) {
|
|
215738
|
+
return (this.fileIssues.get(sessionId) ?? []).map((issue2) => ({ ...issue2 }));
|
|
215739
|
+
}
|
|
215740
|
+
async writeFileIssues(sessionId, phase, issues) {
|
|
215741
|
+
if (!this.sessions.has(sessionId)) return;
|
|
215742
|
+
this.fileIssues.set(sessionId, [...(this.fileIssues.get(sessionId) ?? []).filter((i) => i.phase !== phase), ...issues]);
|
|
215743
|
+
}
|
|
215744
|
+
async listFileSessionsByWorkspaces(workspaces) {
|
|
215745
|
+
return [...this.sessions.values()].filter((s2) => !!s2.workspace && workspaces.includes(s2.workspace) && s2.visibility !== "internal" && !s2.analyzedRunId).map((s2) => ({ ...s2 }));
|
|
215746
|
+
}
|
|
215666
215747
|
async readOutputCopies(sessionId) {
|
|
215667
215748
|
const hit = this.outputCopies.get(sessionId);
|
|
215668
215749
|
return hit ? { ...hit } : null;
|
|
@@ -215723,6 +215804,9 @@ var init_dev_store = __esm({
|
|
|
215723
215804
|
const store = new _FileChatSessionStore(file);
|
|
215724
215805
|
if (fs20.existsSync(file)) {
|
|
215725
215806
|
const snap = JSON.parse(fs20.readFileSync(file, "utf8"));
|
|
215807
|
+
for (const [sid, copies] of Object.entries(snap.outputCopies ?? {})) store.outputCopies.set(sid, copies);
|
|
215808
|
+
for (const [sid, fps] of Object.entries(snap.outputFingerprints ?? {})) store.outputFingerprints.set(sid, fps);
|
|
215809
|
+
for (const [sid, issues] of Object.entries(snap.fileIssues ?? {})) store.fileIssues.set(sid, issues);
|
|
215726
215810
|
for (const s2 of snap.sessions ?? []) store.sessions.set(s2.id, s2);
|
|
215727
215811
|
for (const [sid, list2] of Object.entries(snap.messages ?? {})) store.messages.set(sid, list2);
|
|
215728
215812
|
for (const [sid, ids2] of Object.entries(snap.sessionWorkOrders ?? {})) store.sessionWorkOrders.set(sid, new Set(ids2));
|
|
@@ -215734,6 +215818,18 @@ var init_dev_store = __esm({
|
|
|
215734
215818
|
}
|
|
215735
215819
|
return store;
|
|
215736
215820
|
}
|
|
215821
|
+
async mergeOutputCopies(id, copies) {
|
|
215822
|
+
await super.mergeOutputCopies(id, copies);
|
|
215823
|
+
this.save();
|
|
215824
|
+
}
|
|
215825
|
+
async writeOutputFingerprints(id, fps) {
|
|
215826
|
+
await super.writeOutputFingerprints(id, fps);
|
|
215827
|
+
this.save();
|
|
215828
|
+
}
|
|
215829
|
+
async writeFileIssues(id, phase, issues) {
|
|
215830
|
+
await super.writeFileIssues(id, phase, issues);
|
|
215831
|
+
this.save();
|
|
215832
|
+
}
|
|
215737
215833
|
async createSession(s2) {
|
|
215738
215834
|
await super.createSession(s2);
|
|
215739
215835
|
this.save();
|
|
@@ -215799,6 +215895,9 @@ var init_dev_store = __esm({
|
|
|
215799
215895
|
}
|
|
215800
215896
|
save() {
|
|
215801
215897
|
const snap = {
|
|
215898
|
+
outputCopies: Object.fromEntries(this.outputCopies),
|
|
215899
|
+
outputFingerprints: Object.fromEntries(this.outputFingerprints),
|
|
215900
|
+
fileIssues: Object.fromEntries(this.fileIssues),
|
|
215802
215901
|
sessions: [...this.sessions.values()],
|
|
215803
215902
|
messages: Object.fromEntries(this.messages),
|
|
215804
215903
|
sessionWorkOrders: Object.fromEntries([...this.sessionWorkOrders].map(([k2, v2]) => [k2, [...v2]])),
|
|
@@ -216119,7 +216218,7 @@ var init_company_engine_router = __esm({
|
|
|
216119
216218
|
|
|
216120
216219
|
// ../server/src/skill-market-client.ts
|
|
216121
216220
|
function digestOf2(bytes2) {
|
|
216122
|
-
return `sha256:${(0,
|
|
216221
|
+
return `sha256:${(0, import_node_crypto44.createHash)("sha256").update(bytes2).digest("hex")}`;
|
|
216123
216222
|
}
|
|
216124
216223
|
function createSkillMarketClientFromEnv(env = process.env) {
|
|
216125
216224
|
const base = env["SKILL_MARKET_BASE_URL"];
|
|
@@ -216130,11 +216229,11 @@ function createSkillMarketClientFromEnv(env = process.env) {
|
|
|
216130
216229
|
function sleep4(ms) {
|
|
216131
216230
|
return new Promise((r) => setTimeout(r, ms));
|
|
216132
216231
|
}
|
|
216133
|
-
var
|
|
216232
|
+
var import_node_crypto44, DisabledSkillMarketClient, HttpSkillMarketClient;
|
|
216134
216233
|
var init_skill_market_client = __esm({
|
|
216135
216234
|
"../server/src/skill-market-client.ts"() {
|
|
216136
216235
|
"use strict";
|
|
216137
|
-
|
|
216236
|
+
import_node_crypto44 = require("node:crypto");
|
|
216138
216237
|
init_src();
|
|
216139
216238
|
DisabledSkillMarketClient = class {
|
|
216140
216239
|
async listSkills(_input) {
|
|
@@ -216618,18 +216717,23 @@ async function scanSessionOutputs(bridge, loc, now = Date.now) {
|
|
|
216618
216717
|
if (!walked) return null;
|
|
216619
216718
|
if (walked.ok) {
|
|
216620
216719
|
const files2 = walked.entries.filter((entry) => entry.type === "file").map((entry) => ({ path: entry.path, size: entry.size, mtime: entry.mtime }));
|
|
216621
|
-
return { files: files2, via: "walk", tree: walked.entries };
|
|
216720
|
+
return { files: files2, via: "walk", tree: walked.entries, ...walked.truncated ? { incomplete: true } : {} };
|
|
216622
216721
|
}
|
|
216623
216722
|
if (walked.code === "NOT_FOUND") return { files: [], via: "walk", tree: [] };
|
|
216624
216723
|
if (walked.code !== "UNSUPPORTED") return null;
|
|
216625
216724
|
}
|
|
216725
|
+
let incomplete = false;
|
|
216626
216726
|
const files = await scanLayered(
|
|
216627
216727
|
(path41) => bridge.list(loc.nodeId, { ...locator, path: path41 }),
|
|
216628
|
-
now
|
|
216728
|
+
now,
|
|
216729
|
+
() => {
|
|
216730
|
+
incomplete = true;
|
|
216731
|
+
}
|
|
216629
216732
|
);
|
|
216630
|
-
return files === null ? null : { files, via: "layered" };
|
|
216733
|
+
return files === null ? null : { files, via: "layered", ...incomplete ? { incomplete: true } : {} };
|
|
216631
216734
|
}
|
|
216632
|
-
async function scanLayered(list2, now) {
|
|
216735
|
+
async function scanLayered(list2, now, markIncomplete = () => {
|
|
216736
|
+
}) {
|
|
216633
216737
|
const deadline = now() + BUDGET_MS;
|
|
216634
216738
|
const out = [];
|
|
216635
216739
|
let listCalls = 0;
|
|
@@ -216646,23 +216750,41 @@ async function scanLayered(list2, now) {
|
|
|
216646
216750
|
for (let depth = 0; depth <= MAX_DEPTH; depth += 1) {
|
|
216647
216751
|
const nextDirs = [];
|
|
216648
216752
|
for (const { path: dir, outcome } of level) {
|
|
216649
|
-
if (!outcome.ok)
|
|
216753
|
+
if (!outcome.ok) {
|
|
216754
|
+
markIncomplete();
|
|
216755
|
+
continue;
|
|
216756
|
+
}
|
|
216757
|
+
if (outcome.truncated) markIncomplete();
|
|
216650
216758
|
for (const entry of outcome.entries) {
|
|
216651
216759
|
if (entry.type === "dir") {
|
|
216652
216760
|
nextDirs.push(joinRel(dir, entry.name));
|
|
216653
216761
|
continue;
|
|
216654
216762
|
}
|
|
216655
|
-
if (out.length >= MAX_ENTRIES)
|
|
216763
|
+
if (out.length >= MAX_ENTRIES) {
|
|
216764
|
+
markIncomplete();
|
|
216765
|
+
continue;
|
|
216766
|
+
}
|
|
216656
216767
|
out.push({ path: joinRel(dir, entry.name), size: entry.size, mtime: entry.mtime });
|
|
216657
216768
|
}
|
|
216658
216769
|
}
|
|
216659
|
-
if (nextDirs.length === 0
|
|
216660
|
-
if (
|
|
216770
|
+
if (nextDirs.length === 0) break;
|
|
216771
|
+
if (depth === MAX_DEPTH) {
|
|
216772
|
+
markIncomplete();
|
|
216773
|
+
break;
|
|
216774
|
+
}
|
|
216775
|
+
if (out.length >= MAX_ENTRIES || listCalls >= MAX_LIST_CALLS || now() >= deadline) {
|
|
216776
|
+
markIncomplete();
|
|
216777
|
+
break;
|
|
216778
|
+
}
|
|
216661
216779
|
const batch = [];
|
|
216662
216780
|
for (const dir of nextDirs) {
|
|
216663
|
-
if (listCalls >= MAX_LIST_CALLS || now() >= deadline)
|
|
216781
|
+
if (listCalls >= MAX_LIST_CALLS || now() >= deadline) {
|
|
216782
|
+
markIncomplete();
|
|
216783
|
+
break;
|
|
216784
|
+
}
|
|
216664
216785
|
const outcome = await listDir(dir).catch(() => null);
|
|
216665
216786
|
if (outcome) batch.push({ path: dir, outcome });
|
|
216787
|
+
else markIncomplete();
|
|
216666
216788
|
}
|
|
216667
216789
|
level = batch;
|
|
216668
216790
|
}
|
|
@@ -216693,7 +216815,7 @@ async function settleSessionOutputs(deps) {
|
|
|
216693
216815
|
diff.fingerprints[WALK_TABLE_MARK] = { size: 0, mtime: "" };
|
|
216694
216816
|
}
|
|
216695
216817
|
await deps.writeFingerprints(deps.sessionId, diff.fingerprints).catch(() => void 0);
|
|
216696
|
-
return diff;
|
|
216818
|
+
return { ...diff, ...scan2.incomplete || scan2.files.some((f2) => f2.size == null || !f2.mtime) ? { scanIncomplete: true } : {} };
|
|
216697
216819
|
}
|
|
216698
216820
|
var WALK_MAX_ENTRIES, MAX_DEPTH, MAX_ENTRIES, MAX_LIST_CALLS, BUDGET_MS, WALK_TABLE_MARK;
|
|
216699
216821
|
var init_outputs_scan = __esm({
|
|
@@ -216748,11 +216870,17 @@ async function copySessionOutputs(deps) {
|
|
|
216748
216870
|
try {
|
|
216749
216871
|
existing = await deps.readCopies(deps.sessionId);
|
|
216750
216872
|
} catch {
|
|
216873
|
+
result.skipped = Object.keys(deps.fingerprints).filter(isOutputPath).map((path41) => ({ path: path41, code: "STORE_FAILED" }));
|
|
216751
216874
|
return result;
|
|
216752
216875
|
}
|
|
216876
|
+
const deadline = Date.now() + 2e4;
|
|
216753
216877
|
const plan = planOutputCopies(deps.fingerprints, existing, limits);
|
|
216754
216878
|
result.skipped.push(...plan.skipped);
|
|
216755
216879
|
for (const file of plan.toCopy) {
|
|
216880
|
+
if (Date.now() >= deadline) {
|
|
216881
|
+
result.skipped.push({ path: file.path, code: "BUDGET" });
|
|
216882
|
+
continue;
|
|
216883
|
+
}
|
|
216756
216884
|
let read;
|
|
216757
216885
|
try {
|
|
216758
216886
|
read = await deps.bridge.read(
|
|
@@ -216769,6 +216897,14 @@ async function copySessionOutputs(deps) {
|
|
|
216769
216897
|
continue;
|
|
216770
216898
|
}
|
|
216771
216899
|
const bytes2 = Buffer.from(read.contentBase64, "base64");
|
|
216900
|
+
if (bytes2.length > limits.maxFileBytes) {
|
|
216901
|
+
result.skipped.push({ path: file.path, code: "TOO_LARGE" });
|
|
216902
|
+
continue;
|
|
216903
|
+
}
|
|
216904
|
+
if (bytes2.length !== file.size || read.mtime && read.mtime !== file.mtime) {
|
|
216905
|
+
result.skipped.push({ path: file.path, code: "FILE_CHANGED" });
|
|
216906
|
+
continue;
|
|
216907
|
+
}
|
|
216772
216908
|
let blobRef;
|
|
216773
216909
|
try {
|
|
216774
216910
|
blobRef = await deps.putBlob(new Uint8Array(bytes2));
|
|
@@ -216798,7 +216934,7 @@ async function copySessionOutputs(deps) {
|
|
|
216798
216934
|
return result;
|
|
216799
216935
|
}
|
|
216800
216936
|
function createOutputCopyScheduler(deps) {
|
|
216801
|
-
const inFlight = /* @__PURE__ */ new
|
|
216937
|
+
const inFlight = /* @__PURE__ */ new Map();
|
|
216802
216938
|
return {
|
|
216803
216939
|
schedule(args) {
|
|
216804
216940
|
const { store, chatSessionId, companyId } = args;
|
|
@@ -216806,9 +216942,10 @@ function createOutputCopyScheduler(deps) {
|
|
|
216806
216942
|
const mergeCopies = store.mergeOutputCopies?.bind(store);
|
|
216807
216943
|
if (!readCopies || !mergeCopies) return Promise.resolve(null);
|
|
216808
216944
|
const key = `${companyId ?? ""}|${chatSessionId}`;
|
|
216809
|
-
|
|
216810
|
-
|
|
216811
|
-
|
|
216945
|
+
const prior = inFlight.get(key);
|
|
216946
|
+
let pending;
|
|
216947
|
+
pending = (async () => {
|
|
216948
|
+
await prior;
|
|
216812
216949
|
try {
|
|
216813
216950
|
const session = await store.getSession(chatSessionId);
|
|
216814
216951
|
if (!session || session.visibility === "internal" || session.analyzedRunId) return null;
|
|
@@ -216823,6 +216960,21 @@ function createOutputCopyScheduler(deps) {
|
|
|
216823
216960
|
putBlob: deps.putBlob,
|
|
216824
216961
|
...deps.limits ? { limits: deps.limits } : {}
|
|
216825
216962
|
});
|
|
216963
|
+
const messages = {
|
|
216964
|
+
TOO_LARGE: "\u8D85\u8FC7\u5355\u6587\u4EF6\u4FDD\u5B58\u4E0A\u9650 50 MiB",
|
|
216965
|
+
BUDGET: "\u672C\u8F6E\u4FDD\u5B58\u989D\u5EA6\u5DF2\u7528\u5B8C\uFF0C\u4E0B\u4E00\u8F6E\u91CD\u8BD5",
|
|
216966
|
+
READ_FAILED: "\u539F\u8282\u70B9\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25",
|
|
216967
|
+
STORE_FAILED: "\u670D\u52A1\u7AEF\u6587\u4EF6\u4FDD\u5B58\u5931\u8D25",
|
|
216968
|
+
FILE_CHANGED: "\u8BFB\u53D6\u671F\u95F4\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u8BD5"
|
|
216969
|
+
};
|
|
216970
|
+
const previousIssues = await store.readFileIssues?.(chatSessionId) ?? [];
|
|
216971
|
+
const settled = new Set(Object.keys(args.fingerprints));
|
|
216972
|
+
const issues = [
|
|
216973
|
+
...previousIssues.filter((i) => i.phase === "save" && i.path !== "outputs/" && !settled.has(i.path)),
|
|
216974
|
+
...result.skipped.map((s2) => ({ phase: "save", path: s2.path, code: s2.code, message: messages[s2.code] }))
|
|
216975
|
+
];
|
|
216976
|
+
if (args.scanIncomplete) issues.push({ phase: "save", path: "outputs/", code: "SCAN_INCOMPLETE", message: "\u4EA7\u51FA\u76EE\u5F55\u672A\u80FD\u5B8C\u6574\u626B\u63CF\uFF0C\u90E8\u5206\u6587\u4EF6\u53EF\u80FD\u5C1A\u672A\u4FDD\u5B58" });
|
|
216977
|
+
await store.writeFileIssues?.(chatSessionId, "save", issues);
|
|
216826
216978
|
if (result.skipped.length > 0) {
|
|
216827
216979
|
const head = result.skipped.slice(0, 5).map((s2) => `${s2.path}:${s2.code}`).join(", ");
|
|
216828
216980
|
deps.log?.(`[outputs-copy] ${chatSessionId}: \u590D\u5236 ${result.copied.length} \u4E2A\uFF0C\u8DF3\u8FC7 ${result.skipped.length} \u4E2A\uFF08${head}${result.skipped.length > 5 ? " \u2026" : ""}\uFF09`);
|
|
@@ -216830,11 +216982,14 @@ function createOutputCopyScheduler(deps) {
|
|
|
216830
216982
|
return result;
|
|
216831
216983
|
} catch (err) {
|
|
216832
216984
|
deps.log?.(`[outputs-copy] ${chatSessionId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
216985
|
+
await store.writeFileIssues?.(chatSessionId, "save", [{ phase: "save", path: "outputs/", code: "STORE_FAILED", message: "\u4EA7\u51FA\u4FDD\u5B58\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5" }]).catch(() => void 0);
|
|
216833
216986
|
return null;
|
|
216834
216987
|
} finally {
|
|
216835
|
-
inFlight.delete(key);
|
|
216988
|
+
if (inFlight.get(key) === pending) inFlight.delete(key);
|
|
216836
216989
|
}
|
|
216837
216990
|
})();
|
|
216991
|
+
inFlight.set(key, pending);
|
|
216992
|
+
return pending;
|
|
216838
216993
|
}
|
|
216839
216994
|
};
|
|
216840
216995
|
}
|
|
@@ -216844,9 +216999,9 @@ var init_outputs_copy = __esm({
|
|
|
216844
216999
|
"use strict";
|
|
216845
217000
|
init_src();
|
|
216846
217001
|
OUTPUT_COPY_LIMITS = {
|
|
216847
|
-
maxFileBytes:
|
|
217002
|
+
maxFileBytes: 50 * 1024 * 1024,
|
|
216848
217003
|
maxFiles: 50,
|
|
216849
|
-
maxTotalBytes:
|
|
217004
|
+
maxTotalBytes: 100 * 1024 * 1024
|
|
216850
217005
|
};
|
|
216851
217006
|
}
|
|
216852
217007
|
});
|
|
@@ -217056,11 +217211,11 @@ function typeDefError(def, mode) {
|
|
|
217056
217211
|
}
|
|
217057
217212
|
return null;
|
|
217058
217213
|
}
|
|
217059
|
-
var
|
|
217214
|
+
var import_node_crypto45, RESERVED_FIELD_NAMES, ARTIFACT_TYPE_ACCENTS, TYPE_DEF_SCHEMA, TypesAdminService;
|
|
217060
217215
|
var init_types_admin = __esm({
|
|
217061
217216
|
"../server/src/types-admin.ts"() {
|
|
217062
217217
|
"use strict";
|
|
217063
|
-
|
|
217218
|
+
import_node_crypto45 = require("node:crypto");
|
|
217064
217219
|
init_zod();
|
|
217065
217220
|
init_src5();
|
|
217066
217221
|
init_config_audit();
|
|
@@ -217187,7 +217342,7 @@ var init_types_admin = __esm({
|
|
|
217187
217342
|
async trace(change, target, by, detail) {
|
|
217188
217343
|
try {
|
|
217189
217344
|
await this.audit?.({
|
|
217190
|
-
id: `reg_${(0,
|
|
217345
|
+
id: `reg_${(0, import_node_crypto45.randomUUID)()}`,
|
|
217191
217346
|
actor: by ?? SYSTEM_CONFIG_ACTOR,
|
|
217192
217347
|
kind: "registry_change",
|
|
217193
217348
|
target,
|
|
@@ -217335,11 +217490,11 @@ function roleDefError(def, mode) {
|
|
|
217335
217490
|
}
|
|
217336
217491
|
return null;
|
|
217337
217492
|
}
|
|
217338
|
-
var
|
|
217493
|
+
var import_node_crypto46, ACCENTS, ROLE_DEF_SCHEMA, RolesAdminService;
|
|
217339
217494
|
var init_roles_admin = __esm({
|
|
217340
217495
|
"../server/src/roles-admin.ts"() {
|
|
217341
217496
|
"use strict";
|
|
217342
|
-
|
|
217497
|
+
import_node_crypto46 = require("node:crypto");
|
|
217343
217498
|
init_zod();
|
|
217344
217499
|
init_src5();
|
|
217345
217500
|
init_config_audit();
|
|
@@ -217364,7 +217519,7 @@ var init_roles_admin = __esm({
|
|
|
217364
217519
|
async trace(change, target, by, detail) {
|
|
217365
217520
|
try {
|
|
217366
217521
|
await this.deps.audit?.({
|
|
217367
|
-
id: `reg_${(0,
|
|
217522
|
+
id: `reg_${(0, import_node_crypto46.randomUUID)()}`,
|
|
217368
217523
|
actor: by ?? SYSTEM_CONFIG_ACTOR,
|
|
217369
217524
|
kind: "registry_change",
|
|
217370
217525
|
target,
|
|
@@ -218693,6 +218848,373 @@ var init_recovery_plan = __esm({
|
|
|
218693
218848
|
}
|
|
218694
218849
|
});
|
|
218695
218850
|
|
|
218851
|
+
// ../server/src/domains/chat-sessions/files-view.ts
|
|
218852
|
+
function reasonFromWorkdirCode(code2) {
|
|
218853
|
+
switch (code2) {
|
|
218854
|
+
case "NODE_OFFLINE":
|
|
218855
|
+
return "NODE_OFFLINE";
|
|
218856
|
+
case "TIMEOUT":
|
|
218857
|
+
return "TIMEOUT";
|
|
218858
|
+
default:
|
|
218859
|
+
return "ERROR";
|
|
218860
|
+
}
|
|
218861
|
+
}
|
|
218862
|
+
function joinRel2(dir, name) {
|
|
218863
|
+
return dir ? `${dir}/${name}` : name;
|
|
218864
|
+
}
|
|
218865
|
+
function workdirFileItem(rel, name, size, mtime) {
|
|
218866
|
+
return {
|
|
218867
|
+
id: `workdir:${rel}`,
|
|
218868
|
+
name,
|
|
218869
|
+
kind: "file",
|
|
218870
|
+
// 节点侧列目录只报 name/type/size/mtime,没有 MIME——诚实留 null,
|
|
218871
|
+
// 不拿后缀猜(红线:取不到就是取不到,别拿别的字段顶)。
|
|
218872
|
+
content_type: null,
|
|
218873
|
+
size,
|
|
218874
|
+
updated_at: mtime,
|
|
218875
|
+
source: "workdir",
|
|
218876
|
+
blob_ref: null,
|
|
218877
|
+
path: rel,
|
|
218878
|
+
message_id: null,
|
|
218879
|
+
// 工作区文件本期不开写回(brief §4①:要动 node↔server 协议帧,超预算)。
|
|
218880
|
+
// 这里是**按能力不渲染**的判据,不是置灰假钮。
|
|
218881
|
+
editable: false
|
|
218882
|
+
};
|
|
218883
|
+
}
|
|
218884
|
+
async function collectWorkdirFiles(bridge, loc, now = Date.now) {
|
|
218885
|
+
const items = [];
|
|
218886
|
+
if (typeof bridge.walk === "function") {
|
|
218887
|
+
const walked = await bridge.walk(
|
|
218888
|
+
loc.nodeId,
|
|
218889
|
+
{ workdirKey: loc.workdirKey, runtimeKind: loc.runtimeKind, rtId: loc.rtId, path: "" },
|
|
218890
|
+
WORKDIR_TREE_MAX_ENTRIES
|
|
218891
|
+
);
|
|
218892
|
+
if (walked.ok) {
|
|
218893
|
+
let truncated2 = walked.truncated === true;
|
|
218894
|
+
for (const entry of walked.entries) {
|
|
218895
|
+
if (entry.type !== "file") continue;
|
|
218896
|
+
if (items.length >= WORKDIR_WALK_MAX_ENTRIES) {
|
|
218897
|
+
truncated2 = true;
|
|
218898
|
+
break;
|
|
218899
|
+
}
|
|
218900
|
+
const slash = entry.path.lastIndexOf("/");
|
|
218901
|
+
items.push(workdirFileItem(entry.path, entry.path.slice(slash + 1), entry.size, entry.mtime));
|
|
218902
|
+
}
|
|
218903
|
+
return { ok: true, items, truncated: truncated2 };
|
|
218904
|
+
}
|
|
218905
|
+
if (walked.code === "NOT_FOUND") return { ok: true, items: [], truncated: false };
|
|
218906
|
+
if (walked.code !== "UNSUPPORTED") return { ok: false, reason: reasonFromWorkdirCode(walked.code) };
|
|
218907
|
+
}
|
|
218908
|
+
const deadline = now() + WORKDIR_WALK_BUDGET_MS;
|
|
218909
|
+
let listCalls = 0;
|
|
218910
|
+
let truncated = false;
|
|
218911
|
+
const listDir = (path41) => {
|
|
218912
|
+
listCalls += 1;
|
|
218913
|
+
return bridge.list(loc.nodeId, {
|
|
218914
|
+
workdirKey: loc.workdirKey,
|
|
218915
|
+
runtimeKind: loc.runtimeKind,
|
|
218916
|
+
rtId: loc.rtId,
|
|
218917
|
+
path: path41
|
|
218918
|
+
});
|
|
218919
|
+
};
|
|
218920
|
+
const root = await listDir("");
|
|
218921
|
+
if (!root.ok) {
|
|
218922
|
+
if (root.code === "NOT_FOUND") return { ok: true, items: [], truncated: false };
|
|
218923
|
+
return { ok: false, reason: reasonFromWorkdirCode(root.code) };
|
|
218924
|
+
}
|
|
218925
|
+
let level = [{ path: "", outcome: root }];
|
|
218926
|
+
for (let depth = 0; depth <= WORKDIR_WALK_MAX_DEPTH; depth += 1) {
|
|
218927
|
+
const nextDirs = [];
|
|
218928
|
+
for (const { path: dir, outcome } of level) {
|
|
218929
|
+
if (!outcome.ok) {
|
|
218930
|
+
truncated = true;
|
|
218931
|
+
continue;
|
|
218932
|
+
}
|
|
218933
|
+
if (outcome.truncated) truncated = true;
|
|
218934
|
+
for (const entry of outcome.entries) {
|
|
218935
|
+
if (entry.type === "dir") {
|
|
218936
|
+
nextDirs.push(joinRel2(dir, entry.name));
|
|
218937
|
+
continue;
|
|
218938
|
+
}
|
|
218939
|
+
if (items.length >= WORKDIR_WALK_MAX_ENTRIES) {
|
|
218940
|
+
truncated = true;
|
|
218941
|
+
continue;
|
|
218942
|
+
}
|
|
218943
|
+
items.push(workdirFileItem(joinRel2(dir, entry.name), entry.name, entry.size, entry.mtime));
|
|
218944
|
+
}
|
|
218945
|
+
}
|
|
218946
|
+
if (depth === WORKDIR_WALK_MAX_DEPTH || nextDirs.length === 0) {
|
|
218947
|
+
if (nextDirs.length > 0) truncated = true;
|
|
218948
|
+
break;
|
|
218949
|
+
}
|
|
218950
|
+
const budget = WORKDIR_WALK_MAX_LIST_CALLS - listCalls;
|
|
218951
|
+
if (budget <= 0 || now() >= deadline) {
|
|
218952
|
+
truncated = true;
|
|
218953
|
+
break;
|
|
218954
|
+
}
|
|
218955
|
+
const take = nextDirs.slice(0, budget);
|
|
218956
|
+
if (take.length < nextDirs.length) truncated = true;
|
|
218957
|
+
const outcomes = await Promise.all(take.map((p2) => listDir(p2)));
|
|
218958
|
+
level = take.map((p2, i) => ({ path: p2, outcome: outcomes[i] }));
|
|
218959
|
+
}
|
|
218960
|
+
return { ok: true, items, truncated };
|
|
218961
|
+
}
|
|
218962
|
+
async function collectMessageFiles(messages, blobs) {
|
|
218963
|
+
const rows = [];
|
|
218964
|
+
for (const message of messages) {
|
|
218965
|
+
if (!Array.isArray(message.attachments)) continue;
|
|
218966
|
+
message.attachments.forEach((attachment, index2) => {
|
|
218967
|
+
if (!attachment || typeof attachment.name !== "string" || !attachment.name) return;
|
|
218968
|
+
const blobRef = typeof attachment.blobRef === "string" && attachment.blobRef ? attachment.blobRef : null;
|
|
218969
|
+
rows.push({
|
|
218970
|
+
item: {
|
|
218971
|
+
id: `msg:${message.id}:${index2}`,
|
|
218972
|
+
name: attachment.name,
|
|
218973
|
+
kind: "file",
|
|
218974
|
+
updated_at: attachment.updatedAt ?? message.createdAt,
|
|
218975
|
+
source: "message",
|
|
218976
|
+
blob_ref: blobRef,
|
|
218977
|
+
path: null,
|
|
218978
|
+
message_id: message.id,
|
|
218979
|
+
// 没有 blobRef 的是**历史纯文本附件**(契约注释:legacy text attachments may only
|
|
218980
|
+
// contain `name`)——没有可写回的载体,一律不给编辑入口。
|
|
218981
|
+
editable: blobRef !== null && isEditableFileName(attachment.name)
|
|
218982
|
+
},
|
|
218983
|
+
blobRef,
|
|
218984
|
+
declaredType: typeof attachment.contentType === "string" && attachment.contentType ? attachment.contentType : null
|
|
218985
|
+
});
|
|
218986
|
+
});
|
|
218987
|
+
}
|
|
218988
|
+
const metaCache = /* @__PURE__ */ new Map();
|
|
218989
|
+
const metaOf = (ref2) => {
|
|
218990
|
+
if (!blobs) return Promise.resolve(null);
|
|
218991
|
+
let hit = metaCache.get(ref2);
|
|
218992
|
+
if (!hit) {
|
|
218993
|
+
hit = blobs.meta(ref2).catch(() => null);
|
|
218994
|
+
metaCache.set(ref2, hit);
|
|
218995
|
+
}
|
|
218996
|
+
return hit;
|
|
218997
|
+
};
|
|
218998
|
+
return Promise.all(rows.map(async ({ item, blobRef, declaredType }) => {
|
|
218999
|
+
const meta = blobRef ? await metaOf(blobRef) : null;
|
|
219000
|
+
return {
|
|
219001
|
+
...item,
|
|
219002
|
+
content_type: declaredType ?? meta?.contentType ?? null,
|
|
219003
|
+
size: meta?.size ?? null
|
|
219004
|
+
};
|
|
219005
|
+
}));
|
|
219006
|
+
}
|
|
219007
|
+
function mergeChatSessionFiles(messageItems, workdirItems, materializedCopies = /* @__PURE__ */ new Set()) {
|
|
219008
|
+
const out = [];
|
|
219009
|
+
const seenMessageKeys = /* @__PURE__ */ new Set();
|
|
219010
|
+
for (const item of [...messageItems].sort((a, b2) => b2.updated_at.localeCompare(a.updated_at))) {
|
|
219011
|
+
const key = `${item.name}\0${item.blob_ref ?? ""}`;
|
|
219012
|
+
if (seenMessageKeys.has(key)) continue;
|
|
219013
|
+
seenMessageKeys.add(key);
|
|
219014
|
+
out.push(item);
|
|
219015
|
+
}
|
|
219016
|
+
const seenWorkdirPaths = /* @__PURE__ */ new Set();
|
|
219017
|
+
for (const item of workdirItems) {
|
|
219018
|
+
if (item.path && materializedCopies.has(item.path)) continue;
|
|
219019
|
+
if (seenWorkdirPaths.has(item.id)) continue;
|
|
219020
|
+
seenWorkdirPaths.add(item.id);
|
|
219021
|
+
out.push(item);
|
|
219022
|
+
}
|
|
219023
|
+
out.sort((a, b2) => b2.updated_at.localeCompare(a.updated_at) || a.name.localeCompare(b2.name));
|
|
219024
|
+
return out;
|
|
219025
|
+
}
|
|
219026
|
+
async function findMaterializedAttachmentCopies(messageItems, workdirItems, read) {
|
|
219027
|
+
const copies = /* @__PURE__ */ new Set();
|
|
219028
|
+
const attachments = messageItems.filter((item) => item.blob_ref && /^[a-f0-9]{64}$/.test(item.blob_ref));
|
|
219029
|
+
let budget = CHAT_ATTACHMENT_MAX_BYTES;
|
|
219030
|
+
const deadline = Date.now() + WORKDIR_WALK_BUDGET_MS;
|
|
219031
|
+
let reads = 0;
|
|
219032
|
+
for (const file of workdirItems) {
|
|
219033
|
+
const rootFile = file.path === file.name;
|
|
219034
|
+
const inputFile = file.path?.startsWith("inputs/attachments/") && !file.path.slice("inputs/attachments/".length).includes("/");
|
|
219035
|
+
if (!file.path || !rootFile && !inputFile) continue;
|
|
219036
|
+
const candidates = attachments.filter((attachment) => {
|
|
219037
|
+
const safe = safeAttachmentName(attachment.name);
|
|
219038
|
+
const numbered = file.name.endsWith(`-${safe}`) && /^\d+$/.test(file.name.slice(0, -(safe.length + 1)));
|
|
219039
|
+
return (rootFile ? file.name === attachment.name : file.name === safe || numbered) && attachment.size !== null && attachment.size === file.size;
|
|
219040
|
+
});
|
|
219041
|
+
if (Date.now() >= deadline) break;
|
|
219042
|
+
if (!candidates.length || file.size === null || file.size > budget || reads >= 10) continue;
|
|
219043
|
+
reads += 1;
|
|
219044
|
+
budget -= file.size;
|
|
219045
|
+
let timer;
|
|
219046
|
+
try {
|
|
219047
|
+
const result = await Promise.race([
|
|
219048
|
+
read(file.path, file.size),
|
|
219049
|
+
new Promise((resolve10) => {
|
|
219050
|
+
timer = setTimeout(() => resolve10(null), Math.max(0, deadline - Date.now()));
|
|
219051
|
+
})
|
|
219052
|
+
]);
|
|
219053
|
+
if (!result?.ok) continue;
|
|
219054
|
+
const bytes2 = Buffer.from(result.contentBase64, "base64");
|
|
219055
|
+
if (bytes2.length !== file.size) continue;
|
|
219056
|
+
const hash2 = (0, import_node_crypto47.createHash)("sha256").update(bytes2).digest("hex");
|
|
219057
|
+
if (candidates.some((attachment) => attachment.blob_ref === hash2)) copies.add(file.path);
|
|
219058
|
+
} catch {
|
|
219059
|
+
} finally {
|
|
219060
|
+
if (timer) clearTimeout(timer);
|
|
219061
|
+
}
|
|
219062
|
+
}
|
|
219063
|
+
return copies;
|
|
219064
|
+
}
|
|
219065
|
+
var import_node_crypto47, WORKDIR_WALK_MAX_DEPTH, WORKDIR_WALK_MAX_ENTRIES, WORKDIR_WALK_MAX_LIST_CALLS, WORKDIR_WALK_BUDGET_MS, WORKDIR_TREE_MAX_ENTRIES;
|
|
219066
|
+
var init_files_view = __esm({
|
|
219067
|
+
"../server/src/domains/chat-sessions/files-view.ts"() {
|
|
219068
|
+
"use strict";
|
|
219069
|
+
import_node_crypto47 = require("node:crypto");
|
|
219070
|
+
init_chat_attachment_files();
|
|
219071
|
+
init_src();
|
|
219072
|
+
WORKDIR_WALK_MAX_DEPTH = 3;
|
|
219073
|
+
WORKDIR_WALK_MAX_ENTRIES = 200;
|
|
219074
|
+
WORKDIR_WALK_MAX_LIST_CALLS = 20;
|
|
219075
|
+
WORKDIR_WALK_BUDGET_MS = 1e4;
|
|
219076
|
+
WORKDIR_TREE_MAX_ENTRIES = 2e3;
|
|
219077
|
+
}
|
|
219078
|
+
});
|
|
219079
|
+
|
|
219080
|
+
// ../server/src/domains/chat-sessions/persistent-files.ts
|
|
219081
|
+
function outputDisplayName(path41) {
|
|
219082
|
+
return path41.startsWith("outputs/") ? path41.slice("outputs/".length) : path41;
|
|
219083
|
+
}
|
|
219084
|
+
async function collectPersistentSessionFiles(messages, copies, blobs, includeOutputAliases = false) {
|
|
219085
|
+
const attachments = mergeChatSessionFiles(await collectMessageFiles(messages, blobs), []);
|
|
219086
|
+
const outputs = Object.values(copies ?? {}).filter((copy) => Boolean(copy.blobRef)).filter((copy) => includeOutputAliases || !attachments.some((a) => a.name === outputDisplayName(copy.path) && a.blob_ref === copy.blobRef)).map((copy) => ({
|
|
219087
|
+
// 保留历史产出卡的 id;引用和读取来源升级为服务端副本。
|
|
219088
|
+
id: `workdir:${copy.path}`,
|
|
219089
|
+
name: outputDisplayName(copy.path),
|
|
219090
|
+
kind: "file",
|
|
219091
|
+
content_type: copy.contentType,
|
|
219092
|
+
size: copy.size,
|
|
219093
|
+
updated_at: Number.isNaN(Date.parse(copy.mtime)) ? copy.copiedAt : new Date(copy.mtime).toISOString(),
|
|
219094
|
+
source: "output",
|
|
219095
|
+
blob_ref: copy.blobRef,
|
|
219096
|
+
path: copy.path,
|
|
219097
|
+
message_id: null,
|
|
219098
|
+
editable: false
|
|
219099
|
+
}));
|
|
219100
|
+
return [...attachments, ...outputs].sort((a, b2) => b2.updated_at.localeCompare(a.updated_at) || a.id.localeCompare(b2.id));
|
|
219101
|
+
}
|
|
219102
|
+
async function readPersistentSessionFiles(store, sessionId, blobs, includeOutputAliases = false) {
|
|
219103
|
+
const [messages, copies] = await Promise.all([
|
|
219104
|
+
store.listSessionAttachmentMessages ? store.listSessionAttachmentMessages(sessionId) : store.listMessages(sessionId),
|
|
219105
|
+
store.readOutputCopies?.(sessionId) ?? Promise.resolve(null)
|
|
219106
|
+
]);
|
|
219107
|
+
return collectPersistentSessionFiles(messages, copies, blobs, includeOutputAliases);
|
|
219108
|
+
}
|
|
219109
|
+
var init_persistent_files = __esm({
|
|
219110
|
+
"../server/src/domains/chat-sessions/persistent-files.ts"() {
|
|
219111
|
+
"use strict";
|
|
219112
|
+
init_files_view();
|
|
219113
|
+
}
|
|
219114
|
+
});
|
|
219115
|
+
|
|
219116
|
+
// ../server/src/domains/chat-sessions/file-restore.ts
|
|
219117
|
+
async function recordSessionFileRestoreExit(store, sessionId, info) {
|
|
219118
|
+
if (info.fileRestoreError) await store.writeFileIssues?.(sessionId, "restore", [{
|
|
219119
|
+
phase: "restore",
|
|
219120
|
+
path: info.fileRestoreError.path,
|
|
219121
|
+
code: "MATERIALIZE_FAILED",
|
|
219122
|
+
message: info.fileRestoreError.message
|
|
219123
|
+
}]);
|
|
219124
|
+
}
|
|
219125
|
+
function attachmentRestorePath(name, ref2) {
|
|
219126
|
+
const key = (0, import_node_crypto48.createHash)("sha256").update(`${name}\0${ref2}`).digest("hex").slice(0, 12);
|
|
219127
|
+
return `inputs/history/${key}/${safeAttachmentName(name)}`;
|
|
219128
|
+
}
|
|
219129
|
+
async function prepareSessionFileRestore(input) {
|
|
219130
|
+
const issues = [];
|
|
219131
|
+
const restoreFiles = {};
|
|
219132
|
+
let items;
|
|
219133
|
+
try {
|
|
219134
|
+
items = await readPersistentSessionFiles(input.store, input.sessionId, void 0, true);
|
|
219135
|
+
} catch {
|
|
219136
|
+
const issue2 = { phase: "restore", path: "", code: "INDEX_UNAVAILABLE", message: "\u6587\u4EF6\u6E05\u5355\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5" };
|
|
219137
|
+
await input.store.writeFileIssues?.(input.sessionId, "restore", [issue2]);
|
|
219138
|
+
throw new ApiError(503, "CHAT_FILE_RESTORE_FAILED", issue2.message);
|
|
219139
|
+
}
|
|
219140
|
+
const saveIssues = (await input.store.readFileIssues?.(input.sessionId) ?? []).filter((i) => i.phase === "save");
|
|
219141
|
+
const fingerprints = await input.store.readOutputFingerprints?.(input.sessionId) ?? {};
|
|
219142
|
+
const copies = await input.store.readOutputCopies?.(input.sessionId) ?? {};
|
|
219143
|
+
const outputPaths = new Set(Object.keys(fingerprints).filter((p2) => p2.startsWith("outputs/")));
|
|
219144
|
+
for (const message of await input.store.listMessages(input.sessionId)) {
|
|
219145
|
+
if (!Array.isArray(message.parts)) continue;
|
|
219146
|
+
for (const part of message.parts) {
|
|
219147
|
+
if (!part || typeof part !== "object" || Array.isArray(part) || part.type !== "outputs" || !Array.isArray(part.outputs)) continue;
|
|
219148
|
+
for (const file of part.outputs) if (file && typeof file === "object" && !Array.isArray(file) && typeof file.path === "string" && file.path.startsWith("outputs/")) outputPaths.add(file.path);
|
|
219149
|
+
}
|
|
219150
|
+
}
|
|
219151
|
+
for (const path41 of outputPaths) {
|
|
219152
|
+
const copy = copies[path41], fp = fingerprints[path41];
|
|
219153
|
+
if ((!copy || fp && (copy.size !== fp.size || copy.mtime !== fp.mtime)) && !saveIssues.some((i) => i.path === path41)) {
|
|
219154
|
+
saveIssues.push({ phase: "save", path: path41, code: "UNSAVED_OUTPUT", message: "\u5386\u53F2\u4EA7\u51FA\u5C1A\u65E0\u6700\u65B0\u6301\u4E45\u526F\u672C\uFF0C\u8BF7\u5728\u539F\u8282\u70B9\u5B8C\u6210\u4FDD\u5B58\u540E\u518D\u5207\u6362" });
|
|
219155
|
+
}
|
|
219156
|
+
}
|
|
219157
|
+
if (input.fresh) issues.push(...saveIssues.map((i) => ({ ...i, phase: "restore", message: `\u539F\u6587\u4EF6\u5C1A\u672A\u4FDD\u5B58\uFF1A${i.message}` })));
|
|
219158
|
+
const lines = ["# \u4F1A\u8BDD\u6587\u4EF6", "", "\u4EE5\u4E0B\u6587\u4EF6\u6765\u81EA\u672C\u4F1A\u8BDD\u7684\u6301\u4E45\u8BB0\u5F55\u3002\u5386\u53F2\u8F93\u5165\u6309\u7248\u672C\u4FDD\u7559\uFF1Boutputs \u662F\u6700\u8FD1\u4FDD\u5B58\u7684\u4EA7\u51FA\u3002", ""];
|
|
219159
|
+
let total = 0;
|
|
219160
|
+
const seen = /* @__PURE__ */ new Set();
|
|
219161
|
+
const add = async (name, ref2, path41, replace2) => {
|
|
219162
|
+
if (seen.has(path41)) return;
|
|
219163
|
+
seen.add(path41);
|
|
219164
|
+
if (!ref2) {
|
|
219165
|
+
issues.push({ phase: "restore", path: path41, code: "MISSING_REFERENCE", message: `${name} \u6CA1\u6709\u53EF\u6062\u590D\u7684\u539F\u4EF6\uFF0C\u8BF7\u91CD\u65B0\u4E0A\u4F20` });
|
|
219166
|
+
return;
|
|
219167
|
+
}
|
|
219168
|
+
try {
|
|
219169
|
+
if (Object.keys(restoreFiles).length >= RESTORE_MAX_FILES) throw new Error("\u8D85\u8FC7\u5355\u8F6E\u6062\u590D\u6587\u4EF6\u6570\u91CF\u4E0A\u9650");
|
|
219170
|
+
const bytes2 = await input.readBlob(ref2);
|
|
219171
|
+
if (total + bytes2.byteLength > RESTORE_MAX_BYTES) throw new Error("\u8D85\u8FC7\u5355\u8F6E\u6062\u590D\u603B\u91CF 100 MiB");
|
|
219172
|
+
const hash2 = (0, import_node_crypto48.createHash)("sha256").update(bytes2).digest("hex");
|
|
219173
|
+
if (hash2 !== ref2.replace(/^blob:/, "")) throw new Error("\u539F\u4EF6\u5185\u5BB9\u6821\u9A8C\u5931\u8D25");
|
|
219174
|
+
total += bytes2.byteLength;
|
|
219175
|
+
restoreFiles[path41] = { contentBase64: Buffer.from(bytes2).toString("base64"), sha256: hash2, overwrite: replace2 };
|
|
219176
|
+
lines.push(`- ${JSON.stringify(name)} \u2192 ${JSON.stringify(path41)}`);
|
|
219177
|
+
} catch (error2) {
|
|
219178
|
+
issues.push({ phase: "restore", path: path41, code: "FILE_UNAVAILABLE", message: `${name}\uFF1A${error2 instanceof Error ? error2.message : "\u8BFB\u53D6\u5931\u8D25"}` });
|
|
219179
|
+
}
|
|
219180
|
+
};
|
|
219181
|
+
for (const item of items) {
|
|
219182
|
+
const path41 = item.source === "output" ? item.path : attachmentRestorePath(item.name, item.blob_ref ?? item.id);
|
|
219183
|
+
await add(item.name, item.blob_ref, path41, item.source === "message" || input.fresh);
|
|
219184
|
+
if (item.source === "message") {
|
|
219185
|
+
await add(item.name, item.blob_ref, `inputs/attachments/${safeAttachmentName(item.name)}`, true);
|
|
219186
|
+
}
|
|
219187
|
+
}
|
|
219188
|
+
if (!input.fresh) for (const issue2 of saveIssues) {
|
|
219189
|
+
if (!issue2.path.startsWith("outputs/")) continue;
|
|
219190
|
+
restoreFiles[issue2.path] = { contentBase64: "", sha256: (0, import_node_crypto48.createHash)("sha256").update("").digest("hex"), overwrite: false, requireExisting: true };
|
|
219191
|
+
lines.push(`- ${JSON.stringify(issue2.path)} \u5C1A\u672A\u4FDD\u5B58\uFF0C\u5FC5\u987B\u4FDD\u7559\u672C\u673A\u539F\u6587\u4EF6\uFF1A${issue2.message}`);
|
|
219192
|
+
}
|
|
219193
|
+
for (const attachment of input.attachments ?? []) {
|
|
219194
|
+
if (attachment.blobRef && !attachment.path) {
|
|
219195
|
+
await add(attachment.name, attachment.blobRef, attachmentRestorePath(attachment.name, attachment.blobRef), false);
|
|
219196
|
+
}
|
|
219197
|
+
}
|
|
219198
|
+
if (input.supportsFileRestore === false && Object.keys(restoreFiles).length) {
|
|
219199
|
+
issues.push({ phase: "restore", path: "", code: "NODE_UPGRADE_REQUIRED", message: "\u5F53\u524D\u8282\u70B9\u5C1A\u4E0D\u652F\u6301\u6587\u4EF6\u6062\u590D\uFF0C\u8BF7\u5347\u7EA7\u8282\u70B9\u540E\u91CD\u8BD5" });
|
|
219200
|
+
}
|
|
219201
|
+
await input.store.writeFileIssues?.(input.sessionId, "restore", issues);
|
|
219202
|
+
if (issues.length) throw new ApiError(409, "CHAT_FILE_RESTORE_FAILED", `\u6587\u4EF6\u6062\u590D\u672A\u5B8C\u6210\uFF1A${issues.map((i) => i.message).join("\uFF1B")}`);
|
|
219203
|
+
return { restoreFiles, index: lines.join("\n") };
|
|
219204
|
+
}
|
|
219205
|
+
var import_node_crypto48, RESTORE_MAX_BYTES, RESTORE_MAX_FILES;
|
|
219206
|
+
var init_file_restore = __esm({
|
|
219207
|
+
"../server/src/domains/chat-sessions/file-restore.ts"() {
|
|
219208
|
+
"use strict";
|
|
219209
|
+
import_node_crypto48 = require("node:crypto");
|
|
219210
|
+
init_chat_attachment_files();
|
|
219211
|
+
init_router();
|
|
219212
|
+
init_persistent_files();
|
|
219213
|
+
RESTORE_MAX_BYTES = 100 * 1024 * 1024;
|
|
219214
|
+
RESTORE_MAX_FILES = 500;
|
|
219215
|
+
}
|
|
219216
|
+
});
|
|
219217
|
+
|
|
218696
219218
|
// ../server/src/domains/trace/resilient-appender.ts
|
|
218697
219219
|
var ResilientTraceAppender;
|
|
218698
219220
|
var init_resilient_appender = __esm({
|
|
@@ -219615,7 +220137,7 @@ function wireRecoveredChatTurn(deps) {
|
|
|
219615
220137
|
const segText = itemLedger.projectContent();
|
|
219616
220138
|
const segParts = collectedParts();
|
|
219617
220139
|
const closingId = currentMsgId;
|
|
219618
|
-
const nextId = (0,
|
|
220140
|
+
const nextId = (0, import_node_crypto49.randomUUID)();
|
|
219619
220141
|
currentMsgId = nextId;
|
|
219620
220142
|
itemLedger.beginSegment();
|
|
219621
220143
|
live.setAssistantMessageId(nextId);
|
|
@@ -219629,7 +220151,7 @@ function wireRecoveredChatTurn(deps) {
|
|
|
219629
220151
|
...segParts.length ? { parts: segParts } : {}
|
|
219630
220152
|
}).catch(() => void 0);
|
|
219631
220153
|
await store.appendMessage({
|
|
219632
|
-
id: (0,
|
|
220154
|
+
id: (0, import_node_crypto49.randomUUID)(),
|
|
219633
220155
|
sessionId: plan.chatSessionId,
|
|
219634
220156
|
role: "user",
|
|
219635
220157
|
content: text5,
|
|
@@ -219661,6 +220183,7 @@ function wireRecoveredChatTurn(deps) {
|
|
|
219661
220183
|
const done = (async () => {
|
|
219662
220184
|
const info = await new Promise((resolve10) => handle.onExit(resolve10));
|
|
219663
220185
|
clearInterval(ckptTimer);
|
|
220186
|
+
await recordSessionFileRestoreExit(chatStore, plan.chatSessionId, info);
|
|
219664
220187
|
const failed = exitFailed(info);
|
|
219665
220188
|
if (failed) {
|
|
219666
220189
|
const errText2 = exitErrorText(info);
|
|
@@ -219690,11 +220213,12 @@ function wireRecoveredChatTurn(deps) {
|
|
|
219690
220213
|
log3
|
|
219691
220214
|
);
|
|
219692
220215
|
for (const item of closedItems) liveChat.publishItemStatus(plan.chatSessionId, item);
|
|
220216
|
+
const finalParts = await appendOutputsPart(parts, info.fileRestoreError ? void 0 : deps.outputsPart);
|
|
219693
220217
|
await chatStore.updateMessage(currentMsgId, {
|
|
219694
220218
|
content: itemLedger.projectContent(),
|
|
219695
220219
|
status: failed ? "error" : "done",
|
|
219696
220220
|
completedAt: finishedAt,
|
|
219697
|
-
...
|
|
220221
|
+
...finalParts.length ? { parts: finalParts } : {}
|
|
219698
220222
|
}).catch(() => void 0);
|
|
219699
220223
|
const nextRuntimeSessionId = info.runtimeSessionId ?? plan.runtimeSessionId;
|
|
219700
220224
|
await chatStore.updateSession(plan.chatSessionId, {
|
|
@@ -219768,10 +220292,11 @@ async function sweepDanglingChatTurns(deps) {
|
|
|
219768
220292
|
text: "\u8FD9\u4E00\u8F6E\u5728\u6267\u884C\u4E2D\u88AB\u6253\u65AD\uFF08serve \u91CD\u542F\u6216\u8282\u70B9\u9000\u51FA\uFF09\uFF0C\u672A\u80FD\u5B8C\u6210\u2014\u2014\u4EE5\u4E0A\u4E3A\u4E2D\u65AD\u524D\u5DF2\u751F\u6210\u7684\u5185\u5BB9\u3002"
|
|
219769
220293
|
});
|
|
219770
220294
|
}
|
|
220295
|
+
const finalParts = await appendOutputsPart(parts, deps.outputsPartFor?.(row.sessionId));
|
|
219771
220296
|
await deps.updateMessage(row.id, {
|
|
219772
220297
|
status,
|
|
219773
220298
|
completedAt,
|
|
219774
|
-
...
|
|
220299
|
+
...finalParts.length ? { parts: finalParts } : {}
|
|
219775
220300
|
});
|
|
219776
220301
|
closed.push(row.id);
|
|
219777
220302
|
deps.log?.(`[chat-sweep] \u884C ${row.id}\uFF08\u4F1A\u8BDD ${row.sessionId}\uFF09\u6536\u655B\u4E3A ${status}\uFF08${reason}\uFF09`);
|
|
@@ -219793,6 +220318,7 @@ async function reconcileChatExitFrame(deps) {
|
|
|
219793
220318
|
if (meta?.dispatchId !== deps.dispatchId) continue;
|
|
219794
220319
|
if (deps.ownedRunId?.(row.sessionId) === row.runId) return false;
|
|
219795
220320
|
const turn = await deps.getTurnForRun?.(row.sessionId, run.id);
|
|
220321
|
+
const outputsPart = deps.info.fileRestoreError ? void 0 : deps.outputsPartFor?.(row.sessionId);
|
|
219796
220322
|
if (turn && turn.status !== "reserved" && turn.status !== "running") {
|
|
219797
220323
|
await reconcileSettledChatTurn({
|
|
219798
220324
|
plan: {
|
|
@@ -219811,11 +220337,13 @@ async function reconcileChatExitFrame(deps) {
|
|
|
219811
220337
|
chatStore: deps.chatStore,
|
|
219812
220338
|
trace: deps.trace,
|
|
219813
220339
|
...deps.items ? { items: deps.items } : {},
|
|
220340
|
+
...outputsPart ? { outputsPart } : {},
|
|
219814
220341
|
...deps.log ? { log: deps.log } : {}
|
|
219815
220342
|
});
|
|
219816
220343
|
return true;
|
|
219817
220344
|
}
|
|
219818
220345
|
const { info } = deps;
|
|
220346
|
+
await recordSessionFileRestoreExit(deps.chatStore, row.sessionId, info);
|
|
219819
220347
|
const failed = exitFailed(info);
|
|
219820
220348
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
219821
220349
|
const stash = deps.drainStash(deps.dispatchId);
|
|
@@ -219863,11 +220391,12 @@ async function reconcileChatExitFrame(deps) {
|
|
|
219863
220391
|
failed ? "failed" : "completed",
|
|
219864
220392
|
deps.log ?? (() => void 0)
|
|
219865
220393
|
);
|
|
220394
|
+
const finalParts = await appendOutputsPart(parts, outputsPart);
|
|
219866
220395
|
await deps.chatStore.updateMessage(row.id, {
|
|
219867
220396
|
content: itemLedger.projectContent(),
|
|
219868
220397
|
status: failed ? "error" : "done",
|
|
219869
220398
|
completedAt: finishedAt,
|
|
219870
|
-
...
|
|
220399
|
+
...finalParts.length ? { parts: finalParts } : {}
|
|
219871
220400
|
});
|
|
219872
220401
|
const metaRsid = typeof meta?.runtimeSessionId === "string" ? meta.runtimeSessionId : void 0;
|
|
219873
220402
|
const nextRuntimeSessionId = info.runtimeSessionId ?? metaRsid;
|
|
@@ -219930,7 +220459,7 @@ async function planChatTurnRecoveryAcrossCompanies(deps) {
|
|
|
219930
220459
|
return { groups, settled, scanned, skipped };
|
|
219931
220460
|
}
|
|
219932
220461
|
async function sweepDanglingChatTurnsAcrossCompanies(deps) {
|
|
219933
|
-
const { listCompanies, storesFor, onCompanyError, onSessionClosed, log: log3, ...rest } = deps;
|
|
220462
|
+
const { listCompanies, storesFor, onCompanyError, onSessionClosed, sessionOutputsScan, log: log3, ...rest } = deps;
|
|
219934
220463
|
const closed = [];
|
|
219935
220464
|
for (const companyId of await listCompanies()) {
|
|
219936
220465
|
try {
|
|
@@ -219941,7 +220470,8 @@ async function sweepDanglingChatTurnsAcrossCompanies(deps) {
|
|
|
219941
220470
|
listMessages: (sid) => stores.chatStore.listMessages(sid),
|
|
219942
220471
|
updateMessage: (id, patch) => stores.chatStore.updateMessage(id, patch),
|
|
219943
220472
|
...log3 ? { log: (m2) => log3(companyId ? `${m2}\uFF3B${companyId}\uFF3D` : m2) } : {},
|
|
219944
|
-
...onSessionClosed ? { onSessionClosed: (sid, reason, messageId) => onSessionClosed(sid, reason, messageId, companyId) } : {}
|
|
220473
|
+
...onSessionClosed ? { onSessionClosed: (sid, reason, messageId) => onSessionClosed(sid, reason, messageId, companyId) } : {},
|
|
220474
|
+
...sessionOutputsScan ? { outputsPartFor: (sid) => outputsPartProvider(sessionOutputsScan, sid, companyId) } : {}
|
|
219945
220475
|
});
|
|
219946
220476
|
closed.push(...ids2);
|
|
219947
220477
|
} catch (err) {
|
|
@@ -219951,7 +220481,7 @@ async function sweepDanglingChatTurnsAcrossCompanies(deps) {
|
|
|
219951
220481
|
return closed;
|
|
219952
220482
|
}
|
|
219953
220483
|
async function reconcileChatExitFrameAcrossCompanies(deps) {
|
|
219954
|
-
const { listCompanies, storesFor, onCompanyError, log: log3, ...rest } = deps;
|
|
220484
|
+
const { listCompanies, storesFor, onCompanyError, sessionOutputsScan, log: log3, ...rest } = deps;
|
|
219955
220485
|
for (const companyId of await listCompanies()) {
|
|
219956
220486
|
try {
|
|
219957
220487
|
const stores = await storesFor(companyId);
|
|
@@ -219961,7 +220491,8 @@ async function reconcileChatExitFrameAcrossCompanies(deps) {
|
|
|
219961
220491
|
chatStore: stores.chatStore,
|
|
219962
220492
|
...stores.getTurnForRun ? { getTurnForRun: stores.getTurnForRun } : {},
|
|
219963
220493
|
...stores.items ? { items: stores.items } : {},
|
|
219964
|
-
...log3 ? { log: (m2) => log3(companyId ? `${m2}\uFF3B${companyId}\uFF3D` : m2) } : {}
|
|
220494
|
+
...log3 ? { log: (m2) => log3(companyId ? `${m2}\uFF3B${companyId}\uFF3D` : m2) } : {},
|
|
220495
|
+
...sessionOutputsScan ? { outputsPartFor: (sid) => outputsPartProvider(sessionOutputsScan, sid, companyId) } : {}
|
|
219965
220496
|
});
|
|
219966
220497
|
if (handled3) return true;
|
|
219967
220498
|
} catch (err) {
|
|
@@ -219983,9 +220514,11 @@ async function reconcileSettledChatTurn(deps) {
|
|
|
219983
220514
|
succeeded ? "completed" : "failed",
|
|
219984
220515
|
deps.log ?? (() => void 0)
|
|
219985
220516
|
);
|
|
220517
|
+
const withOutputs = await appendOutputsPart(plan.seedParts, deps.outputsPart);
|
|
219986
220518
|
await deps.chatStore.updateMessage(plan.assistantMsgId, {
|
|
219987
220519
|
status: succeeded ? "done" : "error",
|
|
219988
|
-
completedAt
|
|
220520
|
+
completedAt,
|
|
220521
|
+
...withOutputs !== plan.seedParts ? { parts: withOutputs } : {}
|
|
219989
220522
|
});
|
|
219990
220523
|
const run = await deps.trace.getRun(plan.runId);
|
|
219991
220524
|
if (run?.status === "running") {
|
|
@@ -220003,6 +220536,7 @@ async function recoverChatTurnsAcrossCompanies(deps) {
|
|
|
220003
220536
|
const { plan, turn, companyId, stores } = hit;
|
|
220004
220537
|
log3(`[chat-claim] company=${companyId ?? "<default>"} session=${plan.chatSessionId} run=${plan.runId} dispatch=${plan.dispatchId} \u7ED3\u8BBA=settled\uFF08\u4F9D\u636E\uFF1A\u540C\u516C\u53F8\u8F6E\u6B21 ${turn.id} \u5DF2 ${turn.status}\uFF0CcompletedAt=${turn.completedAt ?? "-"}\uFF09`);
|
|
220005
220538
|
deps.evict(plan.dispatchId);
|
|
220539
|
+
const outputsPart = outputsPartProvider(deps.sessionOutputsScan, plan.chatSessionId, companyId);
|
|
220006
220540
|
try {
|
|
220007
220541
|
await reconcileSettledChatTurn({
|
|
220008
220542
|
plan,
|
|
@@ -220010,6 +220544,7 @@ async function recoverChatTurnsAcrossCompanies(deps) {
|
|
|
220010
220544
|
chatStore: stores.chatStore,
|
|
220011
220545
|
trace: deps.trace,
|
|
220012
220546
|
...stores.items ? { items: stores.items } : {},
|
|
220547
|
+
...outputsPart ? { outputsPart } : {},
|
|
220013
220548
|
log: log3
|
|
220014
220549
|
});
|
|
220015
220550
|
} catch (err) {
|
|
@@ -220045,6 +220580,7 @@ async function recoverChatTurnsAcrossCompanies(deps) {
|
|
|
220045
220580
|
...companyId ? { companyId } : {}
|
|
220046
220581
|
});
|
|
220047
220582
|
} : void 0;
|
|
220583
|
+
const outputsPart = outputsPartProvider(deps.sessionOutputsScan, plan.chatSessionId, companyId);
|
|
220048
220584
|
const { done } = wireRecoveredChatTurn({
|
|
220049
220585
|
plan,
|
|
220050
220586
|
handle,
|
|
@@ -220055,6 +220591,7 @@ async function recoverChatTurnsAcrossCompanies(deps) {
|
|
|
220055
220591
|
unregister: () => deps.unregister(plan),
|
|
220056
220592
|
...deps.traceHealth ? { traceHealth: deps.traceHealth } : {},
|
|
220057
220593
|
...onTurnSettled ? { onTurnSettled } : {},
|
|
220594
|
+
...outputsPart ? { outputsPart } : {},
|
|
220058
220595
|
...stores.items ? { items: stores.items, itemsTurnId } : {},
|
|
220059
220596
|
log: log3
|
|
220060
220597
|
});
|
|
@@ -220068,15 +220605,17 @@ async function recoverChatTurnsAcrossCompanies(deps) {
|
|
|
220068
220605
|
}
|
|
220069
220606
|
return { ...result, recovered };
|
|
220070
220607
|
}
|
|
220071
|
-
var
|
|
220608
|
+
var import_node_crypto49, asObj3, partsOf, maxPartSeq, exitFailed, exitErrorText, runTerminalPatch;
|
|
220072
220609
|
var init_chat_recovery = __esm({
|
|
220073
220610
|
"../server/src/chat-recovery.ts"() {
|
|
220074
220611
|
"use strict";
|
|
220075
|
-
|
|
220612
|
+
init_file_restore();
|
|
220613
|
+
import_node_crypto49 = require("node:crypto");
|
|
220076
220614
|
init_chat_parts();
|
|
220077
220615
|
init_sink();
|
|
220078
220616
|
init_resilient_appender();
|
|
220079
220617
|
init_chat_item_ledger();
|
|
220618
|
+
init_chat_assistant_turn();
|
|
220080
220619
|
init_src6();
|
|
220081
220620
|
init_session_exit_outcome();
|
|
220082
220621
|
asObj3 = (v2) => v2 && typeof v2 === "object" && !Array.isArray(v2) ? v2 : void 0;
|
|
@@ -220102,8 +220641,8 @@ var init_chat_recovery = __esm({
|
|
|
220102
220641
|
|
|
220103
220642
|
// ../server/src/auth/crypto.ts
|
|
220104
220643
|
function hashPassword(password) {
|
|
220105
|
-
const salt = (0,
|
|
220106
|
-
const dk = (0,
|
|
220644
|
+
const salt = (0, import_node_crypto50.randomBytes)(16);
|
|
220645
|
+
const dk = (0, import_node_crypto50.scryptSync)(password, salt, SCRYPT_KEYLEN, { N: SCRYPT_N, maxmem: 64 * 1024 * 1024 });
|
|
220107
220646
|
return `scrypt$${SCRYPT_N}$${salt.toString("base64url")}$${dk.toString("base64url")}`;
|
|
220108
220647
|
}
|
|
220109
220648
|
function verifyPassword(password, stored) {
|
|
@@ -220120,8 +220659,8 @@ function verifyPassword(password, stored) {
|
|
|
220120
220659
|
return false;
|
|
220121
220660
|
}
|
|
220122
220661
|
if (expected.length === 0) return false;
|
|
220123
|
-
const dk = (0,
|
|
220124
|
-
return dk.length === expected.length && (0,
|
|
220662
|
+
const dk = (0, import_node_crypto50.scryptSync)(password, salt, expected.length, { N, maxmem: 64 * 1024 * 1024 });
|
|
220663
|
+
return dk.length === expected.length && (0, import_node_crypto50.timingSafeEqual)(dk, expected);
|
|
220125
220664
|
}
|
|
220126
220665
|
function b64urlJson(value2) {
|
|
220127
220666
|
return Buffer.from(JSON.stringify(value2)).toString("base64url");
|
|
@@ -220129,17 +220668,17 @@ function b64urlJson(value2) {
|
|
|
220129
220668
|
function signSession(claims, secret) {
|
|
220130
220669
|
const head = b64urlJson({ alg: "HS256", typ: "JWT" });
|
|
220131
220670
|
const body2 = b64urlJson(claims);
|
|
220132
|
-
const sig = (0,
|
|
220671
|
+
const sig = (0, import_node_crypto50.createHmac)("sha256", secret).update(`${head}.${body2}`).digest("base64url");
|
|
220133
220672
|
return `${head}.${body2}.${sig}`;
|
|
220134
220673
|
}
|
|
220135
220674
|
function verifySession(token, secret, nowMs) {
|
|
220136
220675
|
const parts = token.split(".");
|
|
220137
220676
|
if (parts.length !== 3) return null;
|
|
220138
220677
|
const [head, body2, sig] = parts;
|
|
220139
|
-
const expected = (0,
|
|
220678
|
+
const expected = (0, import_node_crypto50.createHmac)("sha256", secret).update(`${head}.${body2}`).digest("base64url");
|
|
220140
220679
|
const got = Buffer.from(sig);
|
|
220141
220680
|
const exp = Buffer.from(expected);
|
|
220142
|
-
if (got.length !== exp.length || !(0,
|
|
220681
|
+
if (got.length !== exp.length || !(0, import_node_crypto50.timingSafeEqual)(got, exp)) return null;
|
|
220143
220682
|
let claims;
|
|
220144
220683
|
try {
|
|
220145
220684
|
claims = JSON.parse(Buffer.from(body2, "base64url").toString("utf8"));
|
|
@@ -220151,21 +220690,21 @@ function verifySession(token, secret, nowMs) {
|
|
|
220151
220690
|
return claims;
|
|
220152
220691
|
}
|
|
220153
220692
|
function generateCode() {
|
|
220154
|
-
return String((0,
|
|
220693
|
+
return String((0, import_node_crypto50.randomInt)(0, 1e6)).padStart(6, "0");
|
|
220155
220694
|
}
|
|
220156
220695
|
function hashCode(code2, secret) {
|
|
220157
|
-
return (0,
|
|
220696
|
+
return (0, import_node_crypto50.createHmac)("sha256", secret).update(`code:${code2}`).digest("base64url");
|
|
220158
220697
|
}
|
|
220159
220698
|
function safeEqualHash(a, b2) {
|
|
220160
220699
|
const ba = Buffer.from(a);
|
|
220161
220700
|
const bb = Buffer.from(b2);
|
|
220162
|
-
return ba.length === bb.length && (0,
|
|
220701
|
+
return ba.length === bb.length && (0, import_node_crypto50.timingSafeEqual)(ba, bb);
|
|
220163
220702
|
}
|
|
220164
|
-
var
|
|
220703
|
+
var import_node_crypto50, SCRYPT_N, SCRYPT_KEYLEN;
|
|
220165
220704
|
var init_crypto2 = __esm({
|
|
220166
220705
|
"../server/src/auth/crypto.ts"() {
|
|
220167
220706
|
"use strict";
|
|
220168
|
-
|
|
220707
|
+
import_node_crypto50 = require("node:crypto");
|
|
220169
220708
|
SCRYPT_N = 16384;
|
|
220170
220709
|
SCRYPT_KEYLEN = 32;
|
|
220171
220710
|
}
|
|
@@ -221315,16 +221854,16 @@ function variableKeyFromEnv(env = process.env) {
|
|
|
221315
221854
|
return buf;
|
|
221316
221855
|
}
|
|
221317
221856
|
if (env.NODE_ENV === "production") throw new Error("OASIS_VAR_KEY is required in production");
|
|
221318
|
-
return (0,
|
|
221857
|
+
return (0, import_node_crypto51.createHash)("sha256").update("oasis-dev-only-variable-key").digest();
|
|
221319
221858
|
}
|
|
221320
221859
|
function dedupe(ids2) {
|
|
221321
221860
|
return [...new Set(ids2.filter((x2) => typeof x2 === "string" && x2.length > 0))];
|
|
221322
221861
|
}
|
|
221323
|
-
var
|
|
221862
|
+
var import_node_crypto51, REDACTED_MARKER, ActorsService, mask, changedKeys;
|
|
221324
221863
|
var init_service5 = __esm({
|
|
221325
221864
|
"../server/src/domains/actors/service.ts"() {
|
|
221326
221865
|
"use strict";
|
|
221327
|
-
|
|
221866
|
+
import_node_crypto51 = require("node:crypto");
|
|
221328
221867
|
init_skill_fetcher();
|
|
221329
221868
|
init_identity();
|
|
221330
221869
|
init_migrate();
|
|
@@ -221888,7 +222427,7 @@ ${input.description}
|
|
|
221888
222427
|
*/
|
|
221889
222428
|
buildSkillFile(skillId, path41, content3, now) {
|
|
221890
222429
|
const bytes2 = new TextEncoder().encode(content3);
|
|
221891
|
-
const blobHash = (0,
|
|
222430
|
+
const blobHash = (0, import_node_crypto51.createHash)("sha256").update(bytes2).digest("hex");
|
|
221892
222431
|
return { skillId, path: path41, content: content3, blobHash, size: bytes2.length, updatedAt: now };
|
|
221893
222432
|
}
|
|
221894
222433
|
/**
|
|
@@ -222540,15 +223079,15 @@ ${input.description}
|
|
|
222540
223079
|
return hit ? { value: hit.value, ...hit.origin ? { origin: hit.origin } : {} } : null;
|
|
222541
223080
|
}
|
|
222542
223081
|
encrypt(plain) {
|
|
222543
|
-
const iv = (0,
|
|
222544
|
-
const cipher = (0,
|
|
223082
|
+
const iv = (0, import_node_crypto51.randomBytes)(12);
|
|
223083
|
+
const cipher = (0, import_node_crypto51.createCipheriv)("aes-256-gcm", this.opts.variableKey, iv);
|
|
222545
223084
|
const enc4 = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
|
|
222546
223085
|
return [iv.toString("base64"), cipher.getAuthTag().toString("base64"), enc4.toString("base64")].join(".");
|
|
222547
223086
|
}
|
|
222548
223087
|
decrypt(packed) {
|
|
222549
223088
|
const [iv, tag, data] = packed.split(".");
|
|
222550
223089
|
if (!iv || !tag || typeof data !== "string") throw new Error("malformed ciphertext");
|
|
222551
|
-
const decipher = (0,
|
|
223090
|
+
const decipher = (0, import_node_crypto51.createDecipheriv)("aes-256-gcm", this.opts.variableKey, Buffer.from(iv, "base64"));
|
|
222552
223091
|
decipher.setAuthTag(Buffer.from(tag, "base64"));
|
|
222553
223092
|
return Buffer.concat([decipher.update(Buffer.from(data, "base64")), decipher.final()]).toString("utf8");
|
|
222554
223093
|
}
|
|
@@ -223166,7 +223705,7 @@ async function listSkillMetadataForActor(args) {
|
|
|
223166
223705
|
usedDirs.add(dir);
|
|
223167
223706
|
const sorted = [...metas].sort((a, b2) => a.path.localeCompare(b2.path));
|
|
223168
223707
|
let latest = "1970-01-01T00:00:00.000Z";
|
|
223169
|
-
const hasher = (0,
|
|
223708
|
+
const hasher = (0, import_node_crypto52.createHash)("sha256");
|
|
223170
223709
|
for (const m2 of sorted) {
|
|
223171
223710
|
if (m2.updatedAt > latest) latest = m2.updatedAt;
|
|
223172
223711
|
hasher.update(m2.path);
|
|
@@ -223191,11 +223730,11 @@ async function listSkillMetadataForActor(args) {
|
|
|
223191
223730
|
const dir = sanitizeSkillDir(c.name, c.slug);
|
|
223192
223731
|
if (usedDirs.has(dir)) continue;
|
|
223193
223732
|
usedDirs.add(dir);
|
|
223194
|
-
const hasher = (0,
|
|
223733
|
+
const hasher = (0, import_node_crypto52.createHash)("sha256");
|
|
223195
223734
|
for (const p2 of paths) {
|
|
223196
223735
|
hasher.update(p2);
|
|
223197
223736
|
hasher.update("\0");
|
|
223198
|
-
hasher.update((0,
|
|
223737
|
+
hasher.update((0, import_node_crypto52.createHash)("sha256").update(c.files[p2]).digest("hex"));
|
|
223199
223738
|
hasher.update("\0");
|
|
223200
223739
|
}
|
|
223201
223740
|
out.push({
|
|
@@ -223216,11 +223755,11 @@ async function listSkillMetadataForActor(args) {
|
|
|
223216
223755
|
const dir = sanitizeSkillDir(b2.name, b2.id);
|
|
223217
223756
|
if (usedDirs.has(dir)) continue;
|
|
223218
223757
|
usedDirs.add(dir);
|
|
223219
|
-
const hasher = (0,
|
|
223758
|
+
const hasher = (0, import_node_crypto52.createHash)("sha256");
|
|
223220
223759
|
for (const p2 of paths) {
|
|
223221
223760
|
hasher.update(p2);
|
|
223222
223761
|
hasher.update("\0");
|
|
223223
|
-
hasher.update((0,
|
|
223762
|
+
hasher.update((0, import_node_crypto52.createHash)("sha256").update(b2.files[p2]).digest("hex"));
|
|
223224
223763
|
hasher.update("\0");
|
|
223225
223764
|
}
|
|
223226
223765
|
out.push({
|
|
@@ -223240,7 +223779,7 @@ function builtinSkillToFiles(b2) {
|
|
|
223240
223779
|
skillId: `builtin:${b2.id}`,
|
|
223241
223780
|
path: path41,
|
|
223242
223781
|
content: content3,
|
|
223243
|
-
blobHash: (0,
|
|
223782
|
+
blobHash: (0, import_node_crypto52.createHash)("sha256").update(content3).digest("hex"),
|
|
223244
223783
|
size: Buffer.byteLength(content3, "utf8"),
|
|
223245
223784
|
updatedAt: "1970-01-01T00:00:00.000Z"
|
|
223246
223785
|
}));
|
|
@@ -223264,7 +223803,7 @@ function sanitizeSkillDir(name, fallbackId) {
|
|
|
223264
223803
|
if (byName) return byName;
|
|
223265
223804
|
const byId = fallbackId ? fold2(fallbackId) : "";
|
|
223266
223805
|
if (byId) return byId;
|
|
223267
|
-
return `skill-${(0,
|
|
223806
|
+
return `skill-${(0, import_node_crypto52.createHash)("sha256").update(name).digest("hex").slice(0, 8)}`;
|
|
223268
223807
|
}
|
|
223269
223808
|
async function materializeSkillFiles(args) {
|
|
223270
223809
|
const skills = await args.service.listInstalledSkillsForActor(args.actorId);
|
|
@@ -223297,7 +223836,7 @@ function connectorSkillToFiles(c) {
|
|
|
223297
223836
|
skillId: c.id,
|
|
223298
223837
|
path: path41,
|
|
223299
223838
|
content: content3,
|
|
223300
|
-
blobHash: (0,
|
|
223839
|
+
blobHash: (0, import_node_crypto52.createHash)("sha256").update(content3).digest("hex"),
|
|
223301
223840
|
size: Buffer.byteLength(content3, "utf8"),
|
|
223302
223841
|
updatedAt: "1970-01-01T00:00:00.000Z"
|
|
223303
223842
|
}));
|
|
@@ -223314,11 +223853,11 @@ function connectorSkillDisplayRows(connectorSkills, enabledConnectors) {
|
|
|
223314
223853
|
...s2.version !== void 0 ? { version: s2.version } : {}
|
|
223315
223854
|
}));
|
|
223316
223855
|
}
|
|
223317
|
-
var
|
|
223856
|
+
var import_node_crypto52;
|
|
223318
223857
|
var init_skill_materializer = __esm({
|
|
223319
223858
|
"../server/src/domains/actors/skill-materializer.ts"() {
|
|
223320
223859
|
"use strict";
|
|
223321
|
-
|
|
223860
|
+
import_node_crypto52 = require("node:crypto");
|
|
223322
223861
|
}
|
|
223323
223862
|
});
|
|
223324
223863
|
|
|
@@ -224829,7 +225368,7 @@ function createActorsDomain(opts) {
|
|
|
224829
225368
|
...kernel !== void 0 ? { onRolesChanged: (a, r) => kernel.setActorRoles(a, r) } : {},
|
|
224830
225369
|
audit: async (entry) => {
|
|
224831
225370
|
await opts.audit?.({
|
|
224832
|
-
id: `reg_${(0,
|
|
225371
|
+
id: `reg_${(0, import_node_crypto53.randomUUID)()}`,
|
|
224833
225372
|
actor: entry.by,
|
|
224834
225373
|
kind: "registry_change",
|
|
224835
225374
|
target: entry.actorId,
|
|
@@ -224869,11 +225408,11 @@ function createActorsDomain(opts) {
|
|
|
224869
225408
|
register: actorsDomain({ resolveCtx, ...opts.resolveTrace ? { resolveTrace: opts.resolveTrace } : {}, ...opts.trace ? { trace: opts.trace } : {}, ...opts.listBuiltinSkills ? { listBuiltinSkills: opts.listBuiltinSkills } : {}, ...opts.getBuiltinSkills ? { getBuiltinSkills: opts.getBuiltinSkills } : {}, ...opts.getConnectorSkills ? { getConnectorSkills: opts.getConnectorSkills } : {}, ...opts.refreshConnectorSkills ? { refreshConnectorSkills: opts.refreshConnectorSkills } : {}, ...opts.memory ? { memory: opts.memory } : {}, ...opts.resolveDispatchScope ? { resolveDispatchScope: opts.resolveDispatchScope } : {}, ...opts.projectExists ? { projectExists: opts.projectExists } : {}, ...opts.isCompanyManager ? { isCompanyManager: opts.isCompanyManager } : {}, ...opts.credentialAudit ? { credentialAudit: opts.credentialAudit } : {}, ...opts.readCredentialAudit ? { readCredentialAudit: opts.readCredentialAudit } : {}, ...opts.credentialRevealLimits ? { credentialRevealLimits: opts.credentialRevealLimits } : {}, ...opts.skillMarket ? { skillMarket: opts.skillMarket } : {}, ...opts.resolveNodeTenancy ? { resolveNodeTenancy: opts.resolveNodeTenancy } : {} })
|
|
224870
225409
|
};
|
|
224871
225410
|
}
|
|
224872
|
-
var
|
|
225411
|
+
var import_node_crypto53;
|
|
224873
225412
|
var init_actors = __esm({
|
|
224874
225413
|
"../server/src/domains/actors/index.ts"() {
|
|
224875
225414
|
"use strict";
|
|
224876
|
-
|
|
225415
|
+
import_node_crypto53 = require("node:crypto");
|
|
224877
225416
|
init_service5();
|
|
224878
225417
|
init_routes3();
|
|
224879
225418
|
init_service5();
|
|
@@ -225043,235 +225582,6 @@ var init_assistant_tier_dispatch = __esm({
|
|
|
225043
225582
|
}
|
|
225044
225583
|
});
|
|
225045
225584
|
|
|
225046
|
-
// ../server/src/domains/chat-sessions/files-view.ts
|
|
225047
|
-
function reasonFromWorkdirCode(code2) {
|
|
225048
|
-
switch (code2) {
|
|
225049
|
-
case "NODE_OFFLINE":
|
|
225050
|
-
return "NODE_OFFLINE";
|
|
225051
|
-
case "TIMEOUT":
|
|
225052
|
-
return "TIMEOUT";
|
|
225053
|
-
default:
|
|
225054
|
-
return "ERROR";
|
|
225055
|
-
}
|
|
225056
|
-
}
|
|
225057
|
-
function joinRel2(dir, name) {
|
|
225058
|
-
return dir ? `${dir}/${name}` : name;
|
|
225059
|
-
}
|
|
225060
|
-
function workdirFileItem(rel, name, size, mtime) {
|
|
225061
|
-
return {
|
|
225062
|
-
id: `workdir:${rel}`,
|
|
225063
|
-
name,
|
|
225064
|
-
kind: "file",
|
|
225065
|
-
// 节点侧列目录只报 name/type/size/mtime,没有 MIME——诚实留 null,
|
|
225066
|
-
// 不拿后缀猜(红线:取不到就是取不到,别拿别的字段顶)。
|
|
225067
|
-
content_type: null,
|
|
225068
|
-
size,
|
|
225069
|
-
updated_at: mtime,
|
|
225070
|
-
source: "workdir",
|
|
225071
|
-
blob_ref: null,
|
|
225072
|
-
path: rel,
|
|
225073
|
-
message_id: null,
|
|
225074
|
-
// 工作区文件本期不开写回(brief §4①:要动 node↔server 协议帧,超预算)。
|
|
225075
|
-
// 这里是**按能力不渲染**的判据,不是置灰假钮。
|
|
225076
|
-
editable: false
|
|
225077
|
-
};
|
|
225078
|
-
}
|
|
225079
|
-
async function collectWorkdirFiles(bridge, loc, now = Date.now) {
|
|
225080
|
-
const items = [];
|
|
225081
|
-
if (typeof bridge.walk === "function") {
|
|
225082
|
-
const walked = await bridge.walk(
|
|
225083
|
-
loc.nodeId,
|
|
225084
|
-
{ workdirKey: loc.workdirKey, runtimeKind: loc.runtimeKind, rtId: loc.rtId, path: "" },
|
|
225085
|
-
WORKDIR_TREE_MAX_ENTRIES
|
|
225086
|
-
);
|
|
225087
|
-
if (walked.ok) {
|
|
225088
|
-
let truncated2 = walked.truncated === true;
|
|
225089
|
-
for (const entry of walked.entries) {
|
|
225090
|
-
if (entry.type !== "file") continue;
|
|
225091
|
-
if (items.length >= WORKDIR_WALK_MAX_ENTRIES) {
|
|
225092
|
-
truncated2 = true;
|
|
225093
|
-
break;
|
|
225094
|
-
}
|
|
225095
|
-
const slash = entry.path.lastIndexOf("/");
|
|
225096
|
-
items.push(workdirFileItem(entry.path, entry.path.slice(slash + 1), entry.size, entry.mtime));
|
|
225097
|
-
}
|
|
225098
|
-
return { ok: true, items, truncated: truncated2 };
|
|
225099
|
-
}
|
|
225100
|
-
if (walked.code === "NOT_FOUND") return { ok: true, items: [], truncated: false };
|
|
225101
|
-
if (walked.code !== "UNSUPPORTED") return { ok: false, reason: reasonFromWorkdirCode(walked.code) };
|
|
225102
|
-
}
|
|
225103
|
-
const deadline = now() + WORKDIR_WALK_BUDGET_MS;
|
|
225104
|
-
let listCalls = 0;
|
|
225105
|
-
let truncated = false;
|
|
225106
|
-
const listDir = (path41) => {
|
|
225107
|
-
listCalls += 1;
|
|
225108
|
-
return bridge.list(loc.nodeId, {
|
|
225109
|
-
workdirKey: loc.workdirKey,
|
|
225110
|
-
runtimeKind: loc.runtimeKind,
|
|
225111
|
-
rtId: loc.rtId,
|
|
225112
|
-
path: path41
|
|
225113
|
-
});
|
|
225114
|
-
};
|
|
225115
|
-
const root = await listDir("");
|
|
225116
|
-
if (!root.ok) {
|
|
225117
|
-
if (root.code === "NOT_FOUND") return { ok: true, items: [], truncated: false };
|
|
225118
|
-
return { ok: false, reason: reasonFromWorkdirCode(root.code) };
|
|
225119
|
-
}
|
|
225120
|
-
let level = [{ path: "", outcome: root }];
|
|
225121
|
-
for (let depth = 0; depth <= WORKDIR_WALK_MAX_DEPTH; depth += 1) {
|
|
225122
|
-
const nextDirs = [];
|
|
225123
|
-
for (const { path: dir, outcome } of level) {
|
|
225124
|
-
if (!outcome.ok) {
|
|
225125
|
-
truncated = true;
|
|
225126
|
-
continue;
|
|
225127
|
-
}
|
|
225128
|
-
if (outcome.truncated) truncated = true;
|
|
225129
|
-
for (const entry of outcome.entries) {
|
|
225130
|
-
if (entry.type === "dir") {
|
|
225131
|
-
nextDirs.push(joinRel2(dir, entry.name));
|
|
225132
|
-
continue;
|
|
225133
|
-
}
|
|
225134
|
-
if (items.length >= WORKDIR_WALK_MAX_ENTRIES) {
|
|
225135
|
-
truncated = true;
|
|
225136
|
-
continue;
|
|
225137
|
-
}
|
|
225138
|
-
items.push(workdirFileItem(joinRel2(dir, entry.name), entry.name, entry.size, entry.mtime));
|
|
225139
|
-
}
|
|
225140
|
-
}
|
|
225141
|
-
if (depth === WORKDIR_WALK_MAX_DEPTH || nextDirs.length === 0) {
|
|
225142
|
-
if (nextDirs.length > 0) truncated = true;
|
|
225143
|
-
break;
|
|
225144
|
-
}
|
|
225145
|
-
const budget = WORKDIR_WALK_MAX_LIST_CALLS - listCalls;
|
|
225146
|
-
if (budget <= 0 || now() >= deadline) {
|
|
225147
|
-
truncated = true;
|
|
225148
|
-
break;
|
|
225149
|
-
}
|
|
225150
|
-
const take = nextDirs.slice(0, budget);
|
|
225151
|
-
if (take.length < nextDirs.length) truncated = true;
|
|
225152
|
-
const outcomes = await Promise.all(take.map((p2) => listDir(p2)));
|
|
225153
|
-
level = take.map((p2, i) => ({ path: p2, outcome: outcomes[i] }));
|
|
225154
|
-
}
|
|
225155
|
-
return { ok: true, items, truncated };
|
|
225156
|
-
}
|
|
225157
|
-
async function collectMessageFiles(messages, blobs) {
|
|
225158
|
-
const rows = [];
|
|
225159
|
-
for (const message of messages) {
|
|
225160
|
-
if (!Array.isArray(message.attachments)) continue;
|
|
225161
|
-
message.attachments.forEach((attachment, index2) => {
|
|
225162
|
-
if (!attachment || typeof attachment.name !== "string" || !attachment.name) return;
|
|
225163
|
-
const blobRef = typeof attachment.blobRef === "string" && attachment.blobRef ? attachment.blobRef : null;
|
|
225164
|
-
rows.push({
|
|
225165
|
-
item: {
|
|
225166
|
-
id: `msg:${message.id}:${index2}`,
|
|
225167
|
-
name: attachment.name,
|
|
225168
|
-
kind: "file",
|
|
225169
|
-
updated_at: attachment.updatedAt ?? message.createdAt,
|
|
225170
|
-
source: "message",
|
|
225171
|
-
blob_ref: blobRef,
|
|
225172
|
-
path: null,
|
|
225173
|
-
message_id: message.id,
|
|
225174
|
-
// 没有 blobRef 的是**历史纯文本附件**(契约注释:legacy text attachments may only
|
|
225175
|
-
// contain `name`)——没有可写回的载体,一律不给编辑入口。
|
|
225176
|
-
editable: blobRef !== null && isEditableFileName(attachment.name)
|
|
225177
|
-
},
|
|
225178
|
-
blobRef,
|
|
225179
|
-
declaredType: typeof attachment.contentType === "string" && attachment.contentType ? attachment.contentType : null
|
|
225180
|
-
});
|
|
225181
|
-
});
|
|
225182
|
-
}
|
|
225183
|
-
const metaCache = /* @__PURE__ */ new Map();
|
|
225184
|
-
const metaOf = (ref2) => {
|
|
225185
|
-
if (!blobs) return Promise.resolve(null);
|
|
225186
|
-
let hit = metaCache.get(ref2);
|
|
225187
|
-
if (!hit) {
|
|
225188
|
-
hit = blobs.meta(ref2).catch(() => null);
|
|
225189
|
-
metaCache.set(ref2, hit);
|
|
225190
|
-
}
|
|
225191
|
-
return hit;
|
|
225192
|
-
};
|
|
225193
|
-
return Promise.all(rows.map(async ({ item, blobRef, declaredType }) => {
|
|
225194
|
-
const meta = blobRef ? await metaOf(blobRef) : null;
|
|
225195
|
-
return {
|
|
225196
|
-
...item,
|
|
225197
|
-
content_type: declaredType ?? meta?.contentType ?? null,
|
|
225198
|
-
size: meta?.size ?? null
|
|
225199
|
-
};
|
|
225200
|
-
}));
|
|
225201
|
-
}
|
|
225202
|
-
function mergeChatSessionFiles(messageItems, workdirItems, materializedCopies = /* @__PURE__ */ new Set()) {
|
|
225203
|
-
const out = [];
|
|
225204
|
-
const seenMessageKeys = /* @__PURE__ */ new Set();
|
|
225205
|
-
for (const item of [...messageItems].sort((a, b2) => b2.updated_at.localeCompare(a.updated_at))) {
|
|
225206
|
-
const key = `${item.name}\0${item.blob_ref ?? ""}`;
|
|
225207
|
-
if (seenMessageKeys.has(key)) continue;
|
|
225208
|
-
seenMessageKeys.add(key);
|
|
225209
|
-
out.push(item);
|
|
225210
|
-
}
|
|
225211
|
-
const seenWorkdirPaths = /* @__PURE__ */ new Set();
|
|
225212
|
-
for (const item of workdirItems) {
|
|
225213
|
-
if (item.path && materializedCopies.has(item.path)) continue;
|
|
225214
|
-
if (seenWorkdirPaths.has(item.id)) continue;
|
|
225215
|
-
seenWorkdirPaths.add(item.id);
|
|
225216
|
-
out.push(item);
|
|
225217
|
-
}
|
|
225218
|
-
out.sort((a, b2) => b2.updated_at.localeCompare(a.updated_at) || a.name.localeCompare(b2.name));
|
|
225219
|
-
return out;
|
|
225220
|
-
}
|
|
225221
|
-
async function findMaterializedAttachmentCopies(messageItems, workdirItems, read) {
|
|
225222
|
-
const copies = /* @__PURE__ */ new Set();
|
|
225223
|
-
const attachments = messageItems.filter((item) => item.blob_ref && /^[a-f0-9]{64}$/.test(item.blob_ref));
|
|
225224
|
-
let budget = CHAT_ATTACHMENT_MAX_BYTES;
|
|
225225
|
-
const deadline = Date.now() + WORKDIR_WALK_BUDGET_MS;
|
|
225226
|
-
let reads = 0;
|
|
225227
|
-
for (const file of workdirItems) {
|
|
225228
|
-
const rootFile = file.path === file.name;
|
|
225229
|
-
const inputFile = file.path?.startsWith("inputs/attachments/") && !file.path.slice("inputs/attachments/".length).includes("/");
|
|
225230
|
-
if (!file.path || !rootFile && !inputFile) continue;
|
|
225231
|
-
const candidates = attachments.filter((attachment) => {
|
|
225232
|
-
const safe = safeAttachmentName(attachment.name);
|
|
225233
|
-
const numbered = file.name.endsWith(`-${safe}`) && /^\d+$/.test(file.name.slice(0, -(safe.length + 1)));
|
|
225234
|
-
return (rootFile ? file.name === attachment.name : file.name === safe || numbered) && attachment.size !== null && attachment.size === file.size;
|
|
225235
|
-
});
|
|
225236
|
-
if (Date.now() >= deadline) break;
|
|
225237
|
-
if (!candidates.length || file.size === null || file.size > budget || reads >= 10) continue;
|
|
225238
|
-
reads += 1;
|
|
225239
|
-
budget -= file.size;
|
|
225240
|
-
let timer;
|
|
225241
|
-
try {
|
|
225242
|
-
const result = await Promise.race([
|
|
225243
|
-
read(file.path, file.size),
|
|
225244
|
-
new Promise((resolve10) => {
|
|
225245
|
-
timer = setTimeout(() => resolve10(null), Math.max(0, deadline - Date.now()));
|
|
225246
|
-
})
|
|
225247
|
-
]);
|
|
225248
|
-
if (!result?.ok) continue;
|
|
225249
|
-
const bytes2 = Buffer.from(result.contentBase64, "base64");
|
|
225250
|
-
if (bytes2.length !== file.size) continue;
|
|
225251
|
-
const hash2 = (0, import_node_crypto51.createHash)("sha256").update(bytes2).digest("hex");
|
|
225252
|
-
if (candidates.some((attachment) => attachment.blob_ref === hash2)) copies.add(file.path);
|
|
225253
|
-
} catch {
|
|
225254
|
-
} finally {
|
|
225255
|
-
if (timer) clearTimeout(timer);
|
|
225256
|
-
}
|
|
225257
|
-
}
|
|
225258
|
-
return copies;
|
|
225259
|
-
}
|
|
225260
|
-
var import_node_crypto51, WORKDIR_WALK_MAX_DEPTH, WORKDIR_WALK_MAX_ENTRIES, WORKDIR_WALK_MAX_LIST_CALLS, WORKDIR_WALK_BUDGET_MS, WORKDIR_TREE_MAX_ENTRIES;
|
|
225261
|
-
var init_files_view = __esm({
|
|
225262
|
-
"../server/src/domains/chat-sessions/files-view.ts"() {
|
|
225263
|
-
"use strict";
|
|
225264
|
-
import_node_crypto51 = require("node:crypto");
|
|
225265
|
-
init_chat_attachment_files();
|
|
225266
|
-
init_src();
|
|
225267
|
-
WORKDIR_WALK_MAX_DEPTH = 3;
|
|
225268
|
-
WORKDIR_WALK_MAX_ENTRIES = 200;
|
|
225269
|
-
WORKDIR_WALK_MAX_LIST_CALLS = 20;
|
|
225270
|
-
WORKDIR_WALK_BUDGET_MS = 1e4;
|
|
225271
|
-
WORKDIR_TREE_MAX_ENTRIES = 2e3;
|
|
225272
|
-
}
|
|
225273
|
-
});
|
|
225274
|
-
|
|
225275
225585
|
// ../server/src/domains/projects/chat-files.ts
|
|
225276
225586
|
function isProjectChatSession(session) {
|
|
225277
225587
|
if (session.visibility === "internal") return false;
|
|
@@ -225283,79 +225593,45 @@ function chatFolderTitle(session) {
|
|
|
225283
225593
|
const title = session.title?.trim();
|
|
225284
225594
|
return title ? title : "\u672A\u547D\u540D\u5BF9\u8BDD";
|
|
225285
225595
|
}
|
|
225286
|
-
function outputDisplayName(path41) {
|
|
225287
|
-
return path41.startsWith("outputs/") ? path41.slice("outputs/".length) : path41;
|
|
225288
|
-
}
|
|
225289
225596
|
async function collectProjectChatFiles(chat, projectId2, meta, options = {}) {
|
|
225290
225597
|
const scope = isUncategorizedProjectId(projectId2) ? null : projectId2;
|
|
225291
|
-
const [attachmentMessages, outputSessions] = await Promise.all([
|
|
225292
|
-
chat.listAttachmentMessages
|
|
225293
|
-
chat.listOutputCopies
|
|
225598
|
+
const [attachmentMessages, outputSessions, taskSessions] = await Promise.all([
|
|
225599
|
+
chat.listAttachmentMessages?.(scope) ?? [],
|
|
225600
|
+
chat.listOutputCopies?.(scope) ?? [],
|
|
225601
|
+
chat.listFileSessionsByWorkspaces?.(options.workOrderIds ?? []) ?? []
|
|
225294
225602
|
]);
|
|
225295
|
-
const
|
|
225603
|
+
const ids2 = [.../* @__PURE__ */ new Set([
|
|
225296
225604
|
...attachmentMessages.map((m2) => m2.sessionId),
|
|
225297
|
-
...outputSessions.map((s2) => s2.sessionId)
|
|
225605
|
+
...outputSessions.map((s2) => s2.sessionId),
|
|
225606
|
+
...taskSessions.map((s2) => s2.id)
|
|
225298
225607
|
])];
|
|
225299
|
-
const sessions = /* @__PURE__ */ new Map();
|
|
225300
|
-
await Promise.all(sessionIds.map(async (id) => {
|
|
225301
|
-
const session = await chat.getSession(id);
|
|
225302
|
-
if (!session) return;
|
|
225303
|
-
if ((session.projectId ?? null) !== scope) return;
|
|
225304
|
-
if (!isProjectChatSession(session)) return;
|
|
225305
|
-
if (options.isDelegationChild && await options.isDelegationChild(id).catch(() => false)) return;
|
|
225306
|
-
sessions.set(id, session);
|
|
225307
|
-
}));
|
|
225308
225608
|
const out = [];
|
|
225309
|
-
const
|
|
225310
|
-
|
|
225311
|
-
|
|
225312
|
-
|
|
225313
|
-
|
|
225314
|
-
|
|
225315
|
-
|
|
225316
|
-
|
|
225317
|
-
|
|
225318
|
-
const
|
|
225319
|
-
|
|
225320
|
-
bySession.set(message.sessionId, list2);
|
|
225321
|
-
}
|
|
225322
|
-
for (const [sessionId, messages] of bySession) {
|
|
225323
|
-
const session = sessions.get(sessionId);
|
|
225324
|
-
const rows = await collectMessageFiles(messages.map((m2) => ({ ...m2, id: m2.messageId })), { meta });
|
|
225325
|
-
for (const row of mergeChatSessionFiles(rows, [])) {
|
|
225326
|
-
if (row.blob_ref === null) continue;
|
|
225327
|
-
out.push({
|
|
225328
|
-
...base(session),
|
|
225329
|
-
fileId: `chat:${sessionId}:${row.id}`,
|
|
225330
|
-
name: row.name,
|
|
225331
|
-
blobId: row.blob_ref,
|
|
225332
|
-
...row.content_type ? { contentType: row.content_type } : {},
|
|
225333
|
-
size: row.size,
|
|
225334
|
-
uploadedBy: session.humanActorId,
|
|
225335
|
-
uploadedAt: row.updated_at,
|
|
225336
|
-
chatSource: "attachment"
|
|
225337
|
-
});
|
|
225338
|
-
}
|
|
225339
|
-
}
|
|
225340
|
-
for (const record8 of outputSessions) {
|
|
225341
|
-
const session = sessions.get(record8.sessionId);
|
|
225342
|
-
if (!session) continue;
|
|
225343
|
-
const seen = new Set(out.filter((file) => file.chatSessionId === session.id).map((file) => `${file.name}\0${file.blobId}`));
|
|
225344
|
-
const copies = record8.copies ?? {};
|
|
225345
|
-
for (const path41 of Object.keys(copies).sort((a, b2) => a.localeCompare(b2))) {
|
|
225346
|
-
const copy = copies[path41];
|
|
225347
|
-
if (!copy?.blobRef) continue;
|
|
225348
|
-
if (seen.has(`${copy.name}\0${copy.blobRef}`)) continue;
|
|
225609
|
+
for (const id of ids2) {
|
|
225610
|
+
const session = await chat.getSession(id);
|
|
225611
|
+
if (!session || session.visibility === "internal" || session.analyzedRunId) continue;
|
|
225612
|
+
if (session.workspace) {
|
|
225613
|
+
if (!options.workOrderIds?.includes(session.workspace)) continue;
|
|
225614
|
+
} else if ((session.projectId ?? null) !== scope || !isProjectChatSession(session)) continue;
|
|
225615
|
+
if (options.isDelegationChild && await options.isDelegationChild(id)) continue;
|
|
225616
|
+
const items = await readPersistentSessionFiles(chat, id, { meta });
|
|
225617
|
+
const fileIssues = await chat.readFileIssues?.(id) ?? [];
|
|
225618
|
+
for (const item of items) {
|
|
225619
|
+
if (!item.blob_ref) continue;
|
|
225349
225620
|
out.push({
|
|
225350
|
-
|
|
225351
|
-
|
|
225352
|
-
|
|
225353
|
-
|
|
225354
|
-
|
|
225355
|
-
|
|
225356
|
-
|
|
225357
|
-
|
|
225358
|
-
|
|
225621
|
+
projectId: projectId2,
|
|
225622
|
+
...fileIssues.length ? { fileIssues } : {},
|
|
225623
|
+
chatSessionId: id,
|
|
225624
|
+
chatTitle: chatFolderTitle(session),
|
|
225625
|
+
chatOwnerId: session.humanActorId,
|
|
225626
|
+
fileId: `chat:${id}:${item.id}`,
|
|
225627
|
+
name: item.name,
|
|
225628
|
+
blobId: item.blob_ref,
|
|
225629
|
+
...item.content_type ? { contentType: item.content_type } : {},
|
|
225630
|
+
size: item.size,
|
|
225631
|
+
uploadedBy: item.source === "output" ? session.aiActorId : session.humanActorId,
|
|
225632
|
+
uploadedAt: item.updated_at,
|
|
225633
|
+
chatSource: item.source === "output" ? "output" : "attachment",
|
|
225634
|
+
...session.workspace ? { taskId: session.workspace } : {}
|
|
225359
225635
|
});
|
|
225360
225636
|
}
|
|
225361
225637
|
}
|
|
@@ -225364,7 +225640,8 @@ async function collectProjectChatFiles(chat, projectId2, meta, options = {}) {
|
|
|
225364
225640
|
var init_chat_files2 = __esm({
|
|
225365
225641
|
"../server/src/domains/projects/chat-files.ts"() {
|
|
225366
225642
|
"use strict";
|
|
225367
|
-
|
|
225643
|
+
init_persistent_files();
|
|
225644
|
+
init_persistent_files();
|
|
225368
225645
|
init_uncategorized_project();
|
|
225369
225646
|
}
|
|
225370
225647
|
});
|
|
@@ -226328,7 +226605,8 @@ function toApiProjectFilesView(view) {
|
|
|
226328
226605
|
// 对话文件夹(`"chat"`):前端据此换带对话气泡的文件夹图标。其余文件夹与文件行为 null。
|
|
226329
226606
|
folder_kind: item.folderKind ?? null,
|
|
226330
226607
|
// 对话文件夹及其子文件所属的对话;前端「所属任务」列的「对话」筛选档靠它。其余行为 null。
|
|
226331
|
-
chat_session_id: item.chatSessionId ?? null
|
|
226608
|
+
chat_session_id: item.chatSessionId ?? null,
|
|
226609
|
+
...item.fileIssues?.length ? { file_issues: item.fileIssues } : {}
|
|
226332
226610
|
}))
|
|
226333
226611
|
};
|
|
226334
226612
|
}
|
|
@@ -228652,11 +228930,11 @@ function fromRow(row) {
|
|
|
228652
228930
|
for (const [k2, v2] of opt) if (v2 !== void 0 && v2 !== null) r[k2] = v2;
|
|
228653
228931
|
return r;
|
|
228654
228932
|
}
|
|
228655
|
-
var
|
|
228933
|
+
var import_node_crypto54, import_node_fs14, DEFAULT_PAGE, MAX_PAGE, pageSize, MemoryNotificationStore, ident3, iso2, str2, PostgresNotificationStore;
|
|
228656
228934
|
var init_notification_store = __esm({
|
|
228657
228935
|
"../server/src/domains/collab/notification-store.ts"() {
|
|
228658
228936
|
"use strict";
|
|
228659
|
-
|
|
228937
|
+
import_node_crypto54 = require("node:crypto");
|
|
228660
228938
|
import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
228661
228939
|
DEFAULT_PAGE = 50;
|
|
228662
228940
|
MAX_PAGE = 200;
|
|
@@ -228689,7 +228967,7 @@ var init_notification_store = __esm({
|
|
|
228689
228967
|
async insert(n) {
|
|
228690
228968
|
const existing = this.findLive(n.recipient, n.sourceKey, n.category);
|
|
228691
228969
|
if (existing) return existing;
|
|
228692
|
-
const row = { ...n, id: `ntf:${(0,
|
|
228970
|
+
const row = { ...n, id: `ntf:${(0, import_node_crypto54.randomUUID)()}`, updatedAt: n.enteredAt };
|
|
228693
228971
|
this.rows.set(row.id, row);
|
|
228694
228972
|
this.save();
|
|
228695
228973
|
return row;
|
|
@@ -228812,7 +229090,7 @@ var init_notification_store = __esm({
|
|
|
228812
229090
|
return new _PostgresNotificationStore(sql, schema);
|
|
228813
229091
|
}
|
|
228814
229092
|
async insert(n) {
|
|
228815
|
-
const id = `ntf:${(0,
|
|
229093
|
+
const id = `ntf:${(0, import_node_crypto54.randomUUID)()}`;
|
|
228816
229094
|
const r = await this.sql.query(
|
|
228817
229095
|
`INSERT INTO ${this.t} (id, recipient, category, source_key, kind, workorder_id, node_id, card_id, actor_id,
|
|
228818
229096
|
title, workspace_title, entered_at, updated_at, status, read_at, item)
|
|
@@ -229763,13 +230041,13 @@ function nameKey(name) {
|
|
|
229763
230041
|
function cleanName(name) {
|
|
229764
230042
|
return name.trim().replace(/\s+/g, " ");
|
|
229765
230043
|
}
|
|
229766
|
-
var import_node_fs15, import_node_path20,
|
|
230044
|
+
var import_node_fs15, import_node_path20, import_node_crypto55, SEP, keyOf, prefixOf, MemoryWorkorderTagStore, FileWorkorderTagStore;
|
|
229767
230045
|
var init_tags = __esm({
|
|
229768
230046
|
"../server/src/domains/collab/tags.ts"() {
|
|
229769
230047
|
"use strict";
|
|
229770
230048
|
import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
229771
230049
|
import_node_path20 = __toESM(require("node:path"), 1);
|
|
229772
|
-
|
|
230050
|
+
import_node_crypto55 = __toESM(require("node:crypto"), 1);
|
|
229773
230051
|
SEP = "::";
|
|
229774
230052
|
keyOf = (companyId, id) => `${companyId}${SEP}${id}`;
|
|
229775
230053
|
prefixOf = (companyId) => `${companyId}${SEP}`;
|
|
@@ -229787,7 +230065,7 @@ var init_tags = __esm({
|
|
|
229787
230065
|
if (!name) return null;
|
|
229788
230066
|
if (this.entries(companyId).some((t) => nameKey(t.name) === nameKey(name))) return null;
|
|
229789
230067
|
const tag = {
|
|
229790
|
-
id: `tag-${
|
|
230068
|
+
id: `tag-${import_node_crypto55.default.randomBytes(6).toString("hex")}`,
|
|
229791
230069
|
name,
|
|
229792
230070
|
...input.color?.trim() ? { color: input.color.trim() } : {},
|
|
229793
230071
|
...input.description?.trim() ? { description: input.description.trim() } : {}
|
|
@@ -231033,11 +231311,11 @@ async function isEmployedElsewhere(store, companyId, accountId) {
|
|
|
231033
231311
|
const memberships = await store.listMembershipsForAccount(accountId);
|
|
231034
231312
|
return memberships.some((m2) => m2.companyId !== companyId);
|
|
231035
231313
|
}
|
|
231036
|
-
var
|
|
231314
|
+
var import_node_crypto56, ROLES, INVITABLE_ROLES, INVITATION_TTL_MS, INVITE_LINK_TTL_MS, INVITE_LINK_TOKEN_BYTES, INVITE_LINK_ROLE, SLUG_RE, CompanyError, CompaniesService;
|
|
231037
231315
|
var init_service6 = __esm({
|
|
231038
231316
|
"../server/src/domains/companies/service.ts"() {
|
|
231039
231317
|
"use strict";
|
|
231040
|
-
|
|
231318
|
+
import_node_crypto56 = require("node:crypto");
|
|
231041
231319
|
init_console_url();
|
|
231042
231320
|
ROLES = ["owner", "admin", "member"];
|
|
231043
231321
|
INVITABLE_ROLES = ["admin", "member"];
|
|
@@ -231129,7 +231407,7 @@ var init_service6 = __esm({
|
|
|
231129
231407
|
const existing = await this.store.getAccountByEmail(normalized4);
|
|
231130
231408
|
if (existing) return existing;
|
|
231131
231409
|
const account = {
|
|
231132
|
-
id: `actor:human:${(0,
|
|
231410
|
+
id: `actor:human:${(0, import_node_crypto56.randomUUID)()}`,
|
|
231133
231411
|
email: normalized4,
|
|
231134
231412
|
name: name ?? normalized4,
|
|
231135
231413
|
status: "active"
|
|
@@ -231338,7 +231616,7 @@ var init_service6 = __esm({
|
|
|
231338
231616
|
}
|
|
231339
231617
|
const nowMs = Date.parse(this.now());
|
|
231340
231618
|
const invitation = {
|
|
231341
|
-
id: `invitation:${(0,
|
|
231619
|
+
id: `invitation:${(0, import_node_crypto56.randomUUID)()}`,
|
|
231342
231620
|
companyId,
|
|
231343
231621
|
email: mail,
|
|
231344
231622
|
role,
|
|
@@ -231469,7 +231747,7 @@ var init_service6 = __esm({
|
|
|
231469
231747
|
const nowMs = Date.parse(this.now());
|
|
231470
231748
|
const link = {
|
|
231471
231749
|
companyId,
|
|
231472
|
-
token: (0,
|
|
231750
|
+
token: (0, import_node_crypto56.randomBytes)(INVITE_LINK_TOKEN_BYTES).toString("base64url"),
|
|
231473
231751
|
role: INVITE_LINK_ROLE,
|
|
231474
231752
|
createdAt: new Date(nowMs).toISOString(),
|
|
231475
231753
|
expiresAt: new Date(nowMs + INVITE_LINK_TTL_MS).toISOString(),
|
|
@@ -231526,7 +231804,7 @@ var init_service6 = __esm({
|
|
|
231526
231804
|
const reusable = existing.find((inv) => !this.isExpired(inv));
|
|
231527
231805
|
if (reusable) return reusable;
|
|
231528
231806
|
const invitation = {
|
|
231529
|
-
id: `invitation:${(0,
|
|
231807
|
+
id: `invitation:${(0, import_node_crypto56.randomUUID)()}`,
|
|
231530
231808
|
companyId: link.companyId,
|
|
231531
231809
|
email: mail,
|
|
231532
231810
|
role: link.role,
|
|
@@ -231764,11 +232042,11 @@ var init_service6 = __esm({
|
|
|
231764
232042
|
});
|
|
231765
232043
|
|
|
231766
232044
|
// ../server/src/domains/companies/offboarding.ts
|
|
231767
|
-
var
|
|
232045
|
+
var import_node_crypto57, MemberOffboardingService;
|
|
231768
232046
|
var init_offboarding = __esm({
|
|
231769
232047
|
"../server/src/domains/companies/offboarding.ts"() {
|
|
231770
232048
|
"use strict";
|
|
231771
|
-
|
|
232049
|
+
import_node_crypto57 = require("node:crypto");
|
|
231772
232050
|
init_service6();
|
|
231773
232051
|
MemberOffboardingService = class {
|
|
231774
232052
|
store;
|
|
@@ -231840,7 +232118,7 @@ var init_offboarding = __esm({
|
|
|
231840
232118
|
const { ownedAgents, inFlight } = await this.snapshot(companyId, accountId);
|
|
231841
232119
|
const at = this.now();
|
|
231842
232120
|
const started = await this.store.startMemberOffboarding({
|
|
231843
|
-
operationId: `off:${(0,
|
|
232121
|
+
operationId: `off:${(0, import_node_crypto57.randomUUID)()}`,
|
|
231844
232122
|
companyId,
|
|
231845
232123
|
accountId,
|
|
231846
232124
|
initiatedBy,
|
|
@@ -232350,18 +232628,18 @@ var init_routes6 = __esm({
|
|
|
232350
232628
|
|
|
232351
232629
|
// ../server/src/domains/companies/agent-credentials.ts
|
|
232352
232630
|
function hashAgentToken(token, secret) {
|
|
232353
|
-
return HASH_PREFIX + (0,
|
|
232631
|
+
return HASH_PREFIX + (0, import_node_crypto58.createHmac)("sha256", secret).update(`agent-token:${token}`).digest("base64url");
|
|
232354
232632
|
}
|
|
232355
232633
|
function safeEqual(a, b2) {
|
|
232356
232634
|
const ba = Buffer.from(a);
|
|
232357
232635
|
const bb = Buffer.from(b2);
|
|
232358
|
-
return ba.length === bb.length && (0,
|
|
232636
|
+
return ba.length === bb.length && (0, import_node_crypto58.timingSafeEqual)(ba, bb);
|
|
232359
232637
|
}
|
|
232360
|
-
var
|
|
232638
|
+
var import_node_crypto58, HASH_PREFIX, TOKEN_PREFIX, AgentCredentialService;
|
|
232361
232639
|
var init_agent_credentials = __esm({
|
|
232362
232640
|
"../server/src/domains/companies/agent-credentials.ts"() {
|
|
232363
232641
|
"use strict";
|
|
232364
|
-
|
|
232642
|
+
import_node_crypto58 = require("node:crypto");
|
|
232365
232643
|
init_service6();
|
|
232366
232644
|
HASH_PREFIX = "ac1$";
|
|
232367
232645
|
TOKEN_PREFIX = "oak_";
|
|
@@ -232386,7 +232664,7 @@ var init_agent_credentials = __esm({
|
|
|
232386
232664
|
if (employee.status !== "active") {
|
|
232387
232665
|
throw new CompanyError(409, "AGENT_LEFT", `\u6570\u5B57\u5458\u5DE5\u5DF2\u79BB\u5F00\uFF0C\u4E0D\u80FD\u7B7E\u53D1\u51ED\u8BC1\uFF1A${agentId}`);
|
|
232388
232666
|
}
|
|
232389
|
-
const token = `${TOKEN_PREFIX}${(0,
|
|
232667
|
+
const token = `${TOKEN_PREFIX}${(0, import_node_crypto58.randomBytes)(32).toString("base64url")}`;
|
|
232390
232668
|
const credential = {
|
|
232391
232669
|
tokenHash: hashAgentToken(token, this.secret),
|
|
232392
232670
|
companyId,
|
|
@@ -232806,7 +233084,7 @@ function gatewayInstanceSlug(gatewayUrl) {
|
|
|
232806
233084
|
}
|
|
232807
233085
|
function connectInstanceName(gatewayUrl, token, companyId) {
|
|
232808
233086
|
const scope = companyId?.trim();
|
|
232809
|
-
const suffix = scope ? `c${(0,
|
|
233087
|
+
const suffix = scope ? `c${(0, import_node_crypto59.createHash)("sha256").update(`${gatewayUrl}\0${scope}`).digest("hex").slice(0, 10)}` : token.replace(/[^a-z0-9]/gi, "").slice(-8).toLowerCase() || "enroll";
|
|
232810
233088
|
const base = gatewayInstanceSlug(gatewayUrl);
|
|
232811
233089
|
return base.slice(0, Math.max(1, 64 - suffix.length - 1)) + "-" + suffix;
|
|
232812
233090
|
}
|
|
@@ -233135,12 +233413,12 @@ function buildNpxCmd(p2) {
|
|
|
233135
233413
|
const prefix = daemonNpmPrefix();
|
|
233136
233414
|
return `npm install -g --prefer-online --prefix ${prefix} ${DAEMON_NPM_PACKAGE}@latest && ${prefix}/bin/oasis daemon start --instance ${shellQuote(instanceName)} --server-ws ${shellQuote(p2.gatewayUrl)}${companyPart}${namePart} --pkg ${shellQuote(DAEMON_NPM_PACKAGE)} --upgrade --enroll-token ${shellQuote(p2.token)}`;
|
|
233137
233415
|
}
|
|
233138
|
-
var
|
|
233416
|
+
var import_node_crypto59;
|
|
233139
233417
|
var init_connect_script = __esm({
|
|
233140
233418
|
"../server/src/domains/nodes/connect-script.ts"() {
|
|
233141
233419
|
"use strict";
|
|
233142
233420
|
init_src();
|
|
233143
|
-
|
|
233421
|
+
import_node_crypto59 = require("node:crypto");
|
|
233144
233422
|
}
|
|
233145
233423
|
});
|
|
233146
233424
|
|
|
@@ -233701,7 +233979,7 @@ function nodesDomain(deps) {
|
|
|
233701
233979
|
}
|
|
233702
233980
|
deps.enrollTokens.setIssuedNodeId(enrollToken, nodeId);
|
|
233703
233981
|
} else {
|
|
233704
|
-
nodeId = `node-${(0,
|
|
233982
|
+
nodeId = `node-${(0, import_node_crypto60.randomUUID)().slice(0, 8)}`;
|
|
233705
233983
|
deps.enrollTokens.setIssuedNodeId(enrollToken, nodeId);
|
|
233706
233984
|
}
|
|
233707
233985
|
const existingNode = await deps.nodeStore.getNode(nodeId);
|
|
@@ -233884,13 +234162,13 @@ function normalizeGatewayUrl(raw) {
|
|
|
233884
234162
|
}
|
|
233885
234163
|
}
|
|
233886
234164
|
function newNodeId() {
|
|
233887
|
-
return "node-" + (0,
|
|
234165
|
+
return "node-" + (0, import_node_crypto60.randomUUID)().replace(/-/g, "").slice(0, 12);
|
|
233888
234166
|
}
|
|
233889
|
-
var
|
|
234167
|
+
var import_node_crypto60, import_node_fs16, import_node_url6, import_node_path21;
|
|
233890
234168
|
var init_routes7 = __esm({
|
|
233891
234169
|
"../server/src/domains/nodes/routes.ts"() {
|
|
233892
234170
|
"use strict";
|
|
233893
|
-
|
|
234171
|
+
import_node_crypto60 = require("node:crypto");
|
|
233894
234172
|
import_node_fs16 = require("node:fs");
|
|
233895
234173
|
import_node_url6 = require("node:url");
|
|
233896
234174
|
import_node_path21 = require("node:path");
|
|
@@ -235081,7 +235359,7 @@ function createBundle(root, target, input) {
|
|
|
235081
235359
|
}
|
|
235082
235360
|
}
|
|
235083
235361
|
const bytes2 = fs26.statSync(absBundle).size;
|
|
235084
|
-
const digest = (0,
|
|
235362
|
+
const digest = (0, import_node_crypto61.createHash)("sha256").update(fs26.readFileSync(absBundle)).digest("hex");
|
|
235085
235363
|
const relBase = `inputs/git-bundles/${safeRepo}-${commit.slice(0, 12)}`;
|
|
235086
235364
|
return {
|
|
235087
235365
|
absoluteBundlePath: absBundle,
|
|
@@ -235177,12 +235455,12 @@ function classifyGitError(fallback, err, where) {
|
|
|
235177
235455
|
function oneLine(msg) {
|
|
235178
235456
|
return msg.split("\n").map((s2) => s2.trim()).filter(Boolean).slice(0, 3).join(" ");
|
|
235179
235457
|
}
|
|
235180
|
-
var import_node_child_process17,
|
|
235458
|
+
var import_node_child_process17, import_node_crypto61, fs26, os7, path25, GitReadonlyBundleError, HEX40, FETCH_TIMEOUT_MS2;
|
|
235181
235459
|
var init_readonly_bundle = __esm({
|
|
235182
235460
|
"../server/src/git/readonly-bundle.ts"() {
|
|
235183
235461
|
"use strict";
|
|
235184
235462
|
import_node_child_process17 = require("node:child_process");
|
|
235185
|
-
|
|
235463
|
+
import_node_crypto61 = require("node:crypto");
|
|
235186
235464
|
fs26 = __toESM(require("node:fs"), 1);
|
|
235187
235465
|
os7 = __toESM(require("node:os"), 1);
|
|
235188
235466
|
path25 = __toESM(require("node:path"), 1);
|
|
@@ -235202,7 +235480,7 @@ var init_readonly_bundle = __esm({
|
|
|
235202
235480
|
|
|
235203
235481
|
// ../server/src/domains/collab/create-seeded-workorder.ts
|
|
235204
235482
|
function makeSeededWorkorderCreator(deps) {
|
|
235205
|
-
const genWorkspace = deps.genWorkspace ?? (() => `ws:wo-${(0,
|
|
235483
|
+
const genWorkspace = deps.genWorkspace ?? (() => `ws:wo-${(0, import_node_crypto62.randomUUID)().slice(0, 8)}`);
|
|
235206
235484
|
return async (input) => {
|
|
235207
235485
|
const company = input.companyId && deps.resolveCompany ? await deps.resolveCompany(input.companyId) : void 0;
|
|
235208
235486
|
const kernel = company?.kernel ?? deps.kernel;
|
|
@@ -235295,7 +235573,7 @@ function makeSeededWorkorderCreator(deps) {
|
|
|
235295
235573
|
};
|
|
235296
235574
|
}
|
|
235297
235575
|
function workspaceForKey(key) {
|
|
235298
|
-
return `ws:wo-${(0,
|
|
235576
|
+
return `ws:wo-${(0, import_node_crypto62.createHash)("sha256").update(key).digest("hex").slice(0, 8)}`;
|
|
235299
235577
|
}
|
|
235300
235578
|
function existingWorkorder(kernel, workspace) {
|
|
235301
235579
|
const arts = [...kernel.model.artifacts.values()].filter((a) => a.workspace === workspace);
|
|
@@ -235308,11 +235586,11 @@ function existingWorkorder(kernel, workspace) {
|
|
|
235308
235586
|
spawned: arts.map((a) => ({ id: a.id, type: a.type, owner: a.owner }))
|
|
235309
235587
|
};
|
|
235310
235588
|
}
|
|
235311
|
-
var
|
|
235589
|
+
var import_node_crypto62, enc2;
|
|
235312
235590
|
var init_create_seeded_workorder = __esm({
|
|
235313
235591
|
"../server/src/domains/collab/create-seeded-workorder.ts"() {
|
|
235314
235592
|
"use strict";
|
|
235315
|
-
|
|
235593
|
+
import_node_crypto62 = require("node:crypto");
|
|
235316
235594
|
init_uncategorized_project();
|
|
235317
235595
|
init_src();
|
|
235318
235596
|
init_planner();
|
|
@@ -236742,12 +237020,12 @@ function stateFromAttempt(attempt, handoff, checkpoint, now, stalledAfterMs, ope
|
|
|
236742
237020
|
if (attempt.status === "no-output") return handoff?.unresolvedIssues.length ? "blocked" : "no_change";
|
|
236743
237021
|
return "failed";
|
|
236744
237022
|
}
|
|
236745
|
-
var
|
|
237023
|
+
var import_node_crypto63, BLOCKING_STATES, HANDOFF_OUTCOMES2, RESUME_EXTERNAL_EFFECT_LIMIT, RESUME_SNAPSHOT_PREFIX, RESUME_SNAPSHOT_SUFFIX, ExecutionContinuityService;
|
|
236746
237024
|
var init_service8 = __esm({
|
|
236747
237025
|
"../server/src/domains/execution-continuity/service.ts"() {
|
|
236748
237026
|
"use strict";
|
|
236749
237027
|
init_src();
|
|
236750
|
-
|
|
237028
|
+
import_node_crypto63 = require("node:crypto");
|
|
236751
237029
|
init_src5();
|
|
236752
237030
|
BLOCKING_STATES = /* @__PURE__ */ new Set(["stalled", "failed", "blocked"]);
|
|
236753
237031
|
HANDOFF_OUTCOMES2 = /* @__PURE__ */ new Set(["succeeded", "no-output", "failed", "cancelled", "timeout", "orphaned"]);
|
|
@@ -236978,7 +237256,7 @@ var init_service8 = __esm({
|
|
|
236978
237256
|
if (typeof expectedHash !== "string" || !this.readBundleFile) return null;
|
|
236979
237257
|
const injectedResume = this.readBundleFile(attempt.id, "execution/RESUME.md");
|
|
236980
237258
|
if (!injectedResume) return null;
|
|
236981
|
-
const actualHash = (0,
|
|
237259
|
+
const actualHash = (0, import_node_crypto63.createHash)("sha256").update(injectedResume).digest("hex");
|
|
236982
237260
|
if (actualHash !== expectedHash) return null;
|
|
236983
237261
|
const recoverySnapshot = parseResumePackSnapshot(injectedResume);
|
|
236984
237262
|
if (!recoverySnapshot || recoverySnapshot.scenario !== "redispatch" || !recoverySnapshot.previousAttempt || recoverySnapshot.node.nodeId !== attempt.nodeId || recoverySnapshot.jobKey !== attempt.jobKey || recoverySnapshot.part !== attempt.part) return null;
|
|
@@ -238082,7 +238360,7 @@ function createChatSessionsDomain(opts) {
|
|
|
238082
238360
|
if (!text5.trim()) throw new ApiError(400, "BAD_REQUEST", "text required");
|
|
238083
238361
|
const now = Date.now();
|
|
238084
238362
|
sweepDrafts(now);
|
|
238085
|
-
const id = `cd_${(0,
|
|
238363
|
+
const id = `cd_${(0, import_node_crypto64.randomUUID)()}`;
|
|
238086
238364
|
drafts.set(id, { text: text5, actor: req.auth.actor, expiresAt: now + DRAFT_TTL_MS });
|
|
238087
238365
|
return { status: 201, body: { id, expiresInMs: DRAFT_TTL_MS } };
|
|
238088
238366
|
});
|
|
@@ -238134,7 +238412,7 @@ function createChatSessionsDomain(opts) {
|
|
|
238134
238412
|
const runtimeId = await currentRuntimeId(body2.aiActorId) ?? "unknown";
|
|
238135
238413
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
238136
238414
|
const session = {
|
|
238137
|
-
id: (0,
|
|
238415
|
+
id: (0, import_node_crypto64.randomUUID)(),
|
|
238138
238416
|
humanActorId: req.auth.actor,
|
|
238139
238417
|
// 注:这里**刻意不写 companyId**。新会话要不要带公司归属,按 ws:wo-6d588f8e 的 ADR
|
|
238140
238418
|
// (每公司 schema、最终移除表内 company 列)统一定,不在本节点自行发明。
|
|
@@ -238240,7 +238518,7 @@ function createChatSessionsDomain(opts) {
|
|
|
238240
238518
|
if (body2.role !== "user" && body2.role !== "assistant") throw new ApiError(400, "BAD_REQUEST", "role must be user or assistant");
|
|
238241
238519
|
const role = body2.role;
|
|
238242
238520
|
const msg = await store2.appendMessage({
|
|
238243
|
-
id: (0,
|
|
238521
|
+
id: (0, import_node_crypto64.randomUUID)(),
|
|
238244
238522
|
sessionId: req.params.id,
|
|
238245
238523
|
role,
|
|
238246
238524
|
content: role === "user" ? stripInjectedChatContext(body2.content) : body2.content,
|
|
@@ -238281,7 +238559,7 @@ function createChatSessionsDomain(opts) {
|
|
|
238281
238559
|
const known = key ? cur.find((x2) => x2.clientKey === key) : void 0;
|
|
238282
238560
|
if (!known && cur.length >= QUEUE_MAX) throw new ApiError(409, "QUEUE_FULL", `\u961F\u5217\u5DF2\u6EE1\uFF08\u4E0A\u9650 ${QUEUE_MAX} \u6761\uFF09`);
|
|
238283
238561
|
const item = await store.enqueuePendingMessage({
|
|
238284
|
-
id: (0,
|
|
238562
|
+
id: (0, import_node_crypto64.randomUUID)(),
|
|
238285
238563
|
chatSessionId: sid,
|
|
238286
238564
|
text: text5,
|
|
238287
238565
|
...attachments.length ? { attachments } : {},
|
|
@@ -238598,6 +238876,20 @@ function createChatSessionsDomain(opts) {
|
|
|
238598
238876
|
return { status: 200, body: body2 };
|
|
238599
238877
|
});
|
|
238600
238878
|
router.get("/api/chat-sessions/:id/workdir/file", async (req) => {
|
|
238879
|
+
const store2 = await storeFor(req);
|
|
238880
|
+
const session = await store2.getSession(req.params.id);
|
|
238881
|
+
if (!session || session.humanActorId !== req.auth.actor) throw new ApiError(404, "NOT_FOUND", "session not found");
|
|
238882
|
+
const copy = (await store2.readOutputCopies?.(session.id))?.[req.query?.get("path") ?? ""];
|
|
238883
|
+
if (copy) {
|
|
238884
|
+
const blobs = opts.resolveBlobs ? await opts.resolveBlobs(req.auth.companyId) : opts.blobs;
|
|
238885
|
+
if (!blobs?.get) throw new ApiError(503, "BLOB_STORE_UNAVAILABLE", "\u6587\u4EF6\u5B58\u50A8\u6682\u4E0D\u53EF\u7528");
|
|
238886
|
+
const bytes2 = Buffer.from(await blobs.get(copy.blobRef));
|
|
238887
|
+
return { status: 200, body: bytes2, headers: {
|
|
238888
|
+
"content-type": copy.contentType ?? "application/octet-stream",
|
|
238889
|
+
"content-length": String(bytes2.length),
|
|
238890
|
+
"cache-control": "no-store"
|
|
238891
|
+
} };
|
|
238892
|
+
}
|
|
238601
238893
|
const bridge = opts.workdir?.();
|
|
238602
238894
|
if (!bridge) throw new ApiError(404, "NOT_FOUND", "\u5DE5\u4F5C\u533A\u6587\u4EF6\u6D4F\u89C8\u672A\u542F\u7528");
|
|
238603
238895
|
const loc = await locateWorkdir(await storeFor(req), req.auth.companyId, req.params.id, req.auth.actor);
|
|
@@ -238634,9 +238926,12 @@ function createChatSessionsDomain(opts) {
|
|
|
238634
238926
|
const store2 = await storeFor(req);
|
|
238635
238927
|
const session = await store2.getSession(req.params.id);
|
|
238636
238928
|
if (!session || session.humanActorId !== req.auth.actor) throw new ApiError(404, "NOT_FOUND", "session not found");
|
|
238637
|
-
const attachmentRows = store2.listSessionAttachmentMessages ? await store2.listSessionAttachmentMessages(session.id) : await store2.listMessages(session.id);
|
|
238638
238929
|
const blobAccess = opts.resolveBlobs ? await opts.resolveBlobs(req.auth?.companyId) : opts.blobs;
|
|
238639
|
-
const
|
|
238930
|
+
const persistentItems = await readPersistentSessionFiles(store2, session.id, blobAccess, true);
|
|
238931
|
+
const messageItems = persistentItems.filter((item) => item.source === "message");
|
|
238932
|
+
const allOutputs = persistentItems.filter((item) => item.source === "output");
|
|
238933
|
+
const savedOutputs = allOutputs.filter((output) => !messageItems.some((m2) => m2.name === output.name && m2.blob_ref === output.blob_ref));
|
|
238934
|
+
const fileIssues = await store2.readFileIssues?.(session.id) ?? [];
|
|
238640
238935
|
let workdirItems = [];
|
|
238641
238936
|
let materializedCopies = /* @__PURE__ */ new Set();
|
|
238642
238937
|
let workdirAvailable = false;
|
|
@@ -238663,8 +238958,13 @@ function createChatSessionsDomain(opts) {
|
|
|
238663
238958
|
}
|
|
238664
238959
|
}
|
|
238665
238960
|
}
|
|
238666
|
-
const
|
|
238961
|
+
const archivedPaths = new Set(allOutputs.map((item) => item.path));
|
|
238962
|
+
const items = mergeChatSessionFiles(messageItems, [
|
|
238963
|
+
...savedOutputs,
|
|
238964
|
+
...workdirItems.filter((item) => !archivedPaths.has(item.path) && !item.path?.startsWith("inputs/history/"))
|
|
238965
|
+
], materializedCopies);
|
|
238667
238966
|
const body2 = {
|
|
238967
|
+
...fileIssues.length ? { fileIssues } : {},
|
|
238668
238968
|
total: items.length,
|
|
238669
238969
|
items,
|
|
238670
238970
|
workdirAvailable,
|
|
@@ -238732,13 +239032,14 @@ function createChatSessionsDomain(opts) {
|
|
|
238732
239032
|
});
|
|
238733
239033
|
};
|
|
238734
239034
|
}
|
|
238735
|
-
var
|
|
239035
|
+
var import_node_crypto64, DEFAULT_SNAPSHOT_ITEMS, MAX_SNAPSHOT_ITEMS;
|
|
238736
239036
|
var init_chat_sessions2 = __esm({
|
|
238737
239037
|
"../server/src/domains/chat-sessions/index.ts"() {
|
|
238738
239038
|
"use strict";
|
|
238739
|
-
|
|
239039
|
+
import_node_crypto64 = require("node:crypto");
|
|
238740
239040
|
init_src();
|
|
238741
239041
|
init_chat_session();
|
|
239042
|
+
init_persistent_files();
|
|
238742
239043
|
init_files_view();
|
|
238743
239044
|
init_router();
|
|
238744
239045
|
init_collab();
|
|
@@ -240141,7 +240442,7 @@ function busyError(chatSessionId, blockedBy) {
|
|
|
240141
240442
|
return `\u76EE\u6807\u4F1A\u8BDD ${chatSessionId} \u6B63\u6709\u4E00\u8F6E\u5728\u8DD1${blockedBy ? `\uFF08${blockedBy}\uFF09` : ""}\u2014\u2014\u672C\u6B21\u89E6\u53D1\u5DF2\u4E22\u5F03\uFF0C\u4E0D\u6392\u961F\u3001\u4E0D\u8865\u8DD1`;
|
|
240142
240443
|
}
|
|
240143
240444
|
function genWebhookToken() {
|
|
240144
|
-
return `owt_${(0,
|
|
240445
|
+
return `owt_${(0, import_node_crypto65.randomBytes)(32).toString("base64url")}`;
|
|
240145
240446
|
}
|
|
240146
240447
|
function validateTitleTemplate(tpl) {
|
|
240147
240448
|
const residue = tpl.replace(DATE_TOKEN, "");
|
|
@@ -240197,11 +240498,11 @@ function appendSourceNote(brief, automation, source, atIso) {
|
|
|
240197
240498
|
---
|
|
240198
240499
|
\u672C\u5DE5\u5355\u7531\u81EA\u52A8\u5316\u300C${automation.name}\u300D\u4E8E ${atIso} \u89E6\u53D1\uFF08\u6765\u6E90\uFF1A${source}\uFF09\u3002\u5F00\u5DE5\u540E\u8BF7\u628A\u5DE5\u5355\u6807\u9898\u6539\u6210\u51C6\u786E\u53CD\u6620\u5B9E\u9645\u5DE5\u4F5C\u7684\u63CF\u8FF0\u3002`;
|
|
240199
240500
|
}
|
|
240200
|
-
var
|
|
240501
|
+
var import_node_crypto65, DATE_TOKEN, AutomationsService, EVENT_RETRY_BASE_MS, EVENT_RETRY_MAX_MS, EVENT_RETRY_MAX_ATTEMPTS, eventAttempts, eventLastAttemptAt, eventLastError, CHAT_REPLY_MAX;
|
|
240201
240502
|
var init_service9 = __esm({
|
|
240202
240503
|
"../server/src/domains/automations/service.ts"() {
|
|
240203
240504
|
"use strict";
|
|
240204
|
-
|
|
240505
|
+
import_node_crypto65 = require("node:crypto");
|
|
240205
240506
|
init_src();
|
|
240206
240507
|
init_registry3();
|
|
240207
240508
|
init_attribution();
|
|
@@ -241015,11 +241316,11 @@ function verifySignature(rawBody, headers, secret) {
|
|
|
241015
241316
|
if (!secret) return "not_required";
|
|
241016
241317
|
const given = header1(headers, "x-hub-signature-256");
|
|
241017
241318
|
if (!given) return "missing";
|
|
241018
|
-
const expected = `sha256=${(0,
|
|
241319
|
+
const expected = `sha256=${(0, import_node_crypto66.createHmac)("sha256", secret).update(rawBody).digest("hex")}`;
|
|
241019
241320
|
const a = Buffer.from(given);
|
|
241020
241321
|
const b2 = Buffer.from(expected);
|
|
241021
241322
|
if (a.length !== b2.length) return "invalid";
|
|
241022
|
-
return (0,
|
|
241323
|
+
return (0, import_node_crypto66.timingSafeEqual)(a, b2) ? "valid" : "invalid";
|
|
241023
241324
|
}
|
|
241024
241325
|
function eventAllowed(filters, envelope) {
|
|
241025
241326
|
if (!filters || filters.length === 0) return true;
|
|
@@ -241049,11 +241350,11 @@ function splitEvent(envelope) {
|
|
|
241049
241350
|
}
|
|
241050
241351
|
return { eventName, actionCandidates: candidates };
|
|
241051
241352
|
}
|
|
241052
|
-
var
|
|
241353
|
+
var import_node_crypto66, MAX_BODY_BYTES, AutomationWebhookService, header1, PROVIDER_PREFIXES;
|
|
241053
241354
|
var init_webhook = __esm({
|
|
241054
241355
|
"../server/src/domains/automations/webhook.ts"() {
|
|
241055
241356
|
"use strict";
|
|
241056
|
-
|
|
241357
|
+
import_node_crypto66 = require("node:crypto");
|
|
241057
241358
|
MAX_BODY_BYTES = 256 * 1024;
|
|
241058
241359
|
AutomationWebhookService = class {
|
|
241059
241360
|
store;
|
|
@@ -242209,7 +242510,7 @@ function playbooksDomain(opts) {
|
|
|
242209
242510
|
opts.overrides.set(companyOf(req), ref2, nodeKey, nextOverride);
|
|
242210
242511
|
try {
|
|
242211
242512
|
await opts.audit?.({
|
|
242212
|
-
id: `reg_${(0,
|
|
242513
|
+
id: `reg_${(0, import_node_crypto67.randomUUID)()}`,
|
|
242213
242514
|
actor: req.auth.actor,
|
|
242214
242515
|
kind: "registry_change",
|
|
242215
242516
|
target: `playbook:${ref2}#${nodeKey}`,
|
|
@@ -242226,11 +242527,11 @@ function playbooksDomain(opts) {
|
|
|
242226
242527
|
});
|
|
242227
242528
|
};
|
|
242228
242529
|
}
|
|
242229
|
-
var
|
|
242530
|
+
var import_node_crypto67;
|
|
242230
242531
|
var init_routes12 = __esm({
|
|
242231
242532
|
"../server/src/domains/playbooks/routes.ts"() {
|
|
242232
242533
|
"use strict";
|
|
242233
|
-
|
|
242534
|
+
import_node_crypto67 = require("node:crypto");
|
|
242234
242535
|
init_router();
|
|
242235
242536
|
init_registry3();
|
|
242236
242537
|
init_planner();
|
|
@@ -242344,17 +242645,17 @@ function completionFingerprint(workspace, members) {
|
|
|
242344
242645
|
workspace,
|
|
242345
242646
|
members: [...members].sort((a, b2) => a.artifactId < b2.artifactId ? -1 : a.artifactId > b2.artifactId ? 1 : 0).map((m2) => ({ artifactId: m2.artifactId, currentRevisionId: m2.currentRevisionId ?? null }))
|
|
242346
242647
|
});
|
|
242347
|
-
return (0,
|
|
242648
|
+
return (0, import_node_crypto68.createHash)("sha256").update(canonical).digest("hex");
|
|
242348
242649
|
}
|
|
242349
242650
|
function eventConsumptionKey(args) {
|
|
242350
242651
|
const raw = `project-event:${EVENT_KEY_VERSION}:${args.triggerId}:${args.event}:${args.workspace}:${args.fingerprint}`;
|
|
242351
|
-
return raw.length <= 200 ? raw : `project-event:${EVENT_KEY_VERSION}:sha256:${(0,
|
|
242652
|
+
return raw.length <= 200 ? raw : `project-event:${EVENT_KEY_VERSION}:sha256:${(0, import_node_crypto68.createHash)("sha256").update(raw).digest("hex")}`;
|
|
242352
242653
|
}
|
|
242353
|
-
var
|
|
242654
|
+
var import_node_crypto68, EVENT_KEY_VERSION, EMPTY_METRICS, AUTOMATION_EVENT_HANDLERS, ProjectEventPoller;
|
|
242354
242655
|
var init_project_event_poller = __esm({
|
|
242355
242656
|
"../server/src/automations/project-event-poller.ts"() {
|
|
242356
242657
|
"use strict";
|
|
242357
|
-
|
|
242658
|
+
import_node_crypto68 = require("node:crypto");
|
|
242358
242659
|
EVENT_KEY_VERSION = "v1";
|
|
242359
242660
|
EMPTY_METRICS = () => ({
|
|
242360
242661
|
scanDurationMs: 0,
|
|
@@ -242565,7 +242866,7 @@ function remoteAppendInput(hub, nodeId, dispatchId, entry, input, timeoutMs) {
|
|
|
242565
242866
|
if (input.requireConsumptionReceipt && !hub.supportsInputConsumptionReceipts?.(dispatchId)) {
|
|
242566
242867
|
return Promise.resolve({ accepted: false, reason: "consumption-unsupported" });
|
|
242567
242868
|
}
|
|
242568
|
-
const requestId = (0,
|
|
242869
|
+
const requestId = (0, import_node_crypto69.randomUUID)();
|
|
242569
242870
|
const sent = routeToSession(hub, nodeId, dispatchId, { type: "append_input", dispatchId, input, requestId });
|
|
242570
242871
|
if (!sent) return Promise.resolve({ accepted: false, reason: "session-closing", ...unknownIfInterrupting });
|
|
242571
242872
|
return new Promise((resolve10) => {
|
|
@@ -242578,11 +242879,11 @@ function remoteAppendInput(hub, nodeId, dispatchId, entry, input, timeoutMs) {
|
|
|
242578
242879
|
entry.appendWaiters.push({ requestId, requireConsumptionReceipt: input.requireConsumptionReceipt, resolve: resolve10, timer });
|
|
242579
242880
|
});
|
|
242580
242881
|
}
|
|
242581
|
-
var
|
|
242882
|
+
var import_node_crypto69, STASH_TTL_MS, STASH_MAX_FRAMES_PER_ID, STASH_MAX_IDS, DaemonHubAdapter, BindingRouterAdapter, WorkdirBridge;
|
|
242582
242883
|
var init_daemon_adapter = __esm({
|
|
242583
242884
|
"../server/src/daemon-adapter.ts"() {
|
|
242584
242885
|
"use strict";
|
|
242585
|
-
|
|
242886
|
+
import_node_crypto69 = require("node:crypto");
|
|
242586
242887
|
init_src();
|
|
242587
242888
|
STASH_TTL_MS = 5 * 6e4;
|
|
242588
242889
|
STASH_MAX_FRAMES_PER_ID = 500;
|
|
@@ -242932,7 +243233,7 @@ var init_daemon_adapter = __esm({
|
|
|
242932
243233
|
async spawn(job) {
|
|
242933
243234
|
const nodeId = job.binding?.nodeId;
|
|
242934
243235
|
if (!nodeId) throw new Error("DaemonHubAdapter \u9700\u8981 job.binding.nodeId\uFF08\u8DEF\u7531\u9519\u8BEF\uFF09");
|
|
242935
|
-
const dispatchId = job.dispatchId ?? `dispatch:${(0,
|
|
243236
|
+
const dispatchId = job.dispatchId ?? `dispatch:${(0, import_node_crypto69.randomUUID)()}`;
|
|
242936
243237
|
if (job.dispatchId && this.pending.has(dispatchId)) {
|
|
242937
243238
|
return this.recover(dispatchId, nodeId, job.binding?.runtimeKind, job.actor);
|
|
242938
243239
|
}
|
|
@@ -243169,7 +243470,7 @@ var init_daemon_adapter = __esm({
|
|
|
243169
243470
|
return daemon?.meta.supportsWorkdirWalk === true;
|
|
243170
243471
|
}
|
|
243171
243472
|
request(nodeId, buildFrame) {
|
|
243172
|
-
const requestId = (0,
|
|
243473
|
+
const requestId = (0, import_node_crypto69.randomUUID)();
|
|
243173
243474
|
const sent = this.hub.dispatch(nodeId, buildFrame(requestId));
|
|
243174
243475
|
if (!sent) return Promise.resolve({ ok: false, code: "NODE_OFFLINE" });
|
|
243175
243476
|
return new Promise((resolve10) => {
|
|
@@ -243277,13 +243578,13 @@ function classifyPage(page, lastPushedHash, serviceAccount) {
|
|
|
243277
243578
|
if (sha(body2) === lastPushedHash) return { kind: "echo" };
|
|
243278
243579
|
return { kind: "human-edit", content: body2, updatedBy: page.updatedBy };
|
|
243279
243580
|
}
|
|
243280
|
-
var
|
|
243581
|
+
var import_node_crypto70, sha, enc3, dec, MirrorEngine, MapMirrorIdentities;
|
|
243281
243582
|
var init_engine = __esm({
|
|
243282
243583
|
"../server/src/mirror/engine.ts"() {
|
|
243283
243584
|
"use strict";
|
|
243284
|
-
|
|
243585
|
+
import_node_crypto70 = require("node:crypto");
|
|
243285
243586
|
init_src();
|
|
243286
|
-
sha = (s2) => (0,
|
|
243587
|
+
sha = (s2) => (0, import_node_crypto70.createHash)("sha256").update(s2, "utf8").digest("hex");
|
|
243287
243588
|
enc3 = (s2) => new TextEncoder().encode(s2);
|
|
243288
243589
|
dec = (b2) => new TextDecoder().decode(b2);
|
|
243289
243590
|
MirrorEngine = class {
|
|
@@ -243530,11 +243831,11 @@ function humanExitCause(exit3) {
|
|
|
243530
243831
|
const base = (exit3.reason ? label[exit3.reason] : void 0) ?? `\u4F1A\u8BDD\u5F02\u5E38\u7ED3\u675F\uFF08${exit3.reason ?? "\u65E0\u9000\u51FA\u4FE1\u606F"}\uFF09`;
|
|
243531
243832
|
return exit3.errorMessage ? `${base}\uFF1A${exit3.errorMessage.slice(0, 200)}` : base;
|
|
243532
243833
|
}
|
|
243533
|
-
var
|
|
243834
|
+
var import_node_crypto71, AUTONOMOUS_ETHOS, CONVERSATIONAL_ETHOS, SHARED_GRAPH_BODY, AUTONOMOUS_RECOVERY_TOOLS, HIGH_RISK_COMMANDS, COORDINATOR_SYSTEM_PROMPT, CONVERSATIONAL_RECOVERY_TOOLS, CONVERSATIONAL_ESCALATION_TOOLS, CONVERSATIONAL_MANAGER_BODY, MACHINE_EXIT_CODES, CoordinatorWorker;
|
|
243534
243835
|
var init_worker = __esm({
|
|
243535
243836
|
"../server/src/coordinator/worker.ts"() {
|
|
243536
243837
|
"use strict";
|
|
243537
|
-
|
|
243838
|
+
import_node_crypto71 = require("node:crypto");
|
|
243538
243839
|
init_src5();
|
|
243539
243840
|
init_identity();
|
|
243540
243841
|
AUTONOMOUS_ETHOS = `\u4F60\u662F\u8FD9\u4E2A\u5DE5\u5355\u7684**\u7BA1\u7406\u8005**\u2014\u2014\u804C\u8D23\u662F\u8BA9\u5B83\u987A\u7545\u8DD1\u5B8C\u3002\u7CFB\u7EDF\u5728\u67D0\u4E2A\u8282\u70B9\u5361\u4F4F\u3001\u673A\u68B0\u5206\u8BCA\u786E\u8BA4"\u9700\u8981\u4F60"\u65F6\u5524\u8D77\u4F60\uFF08\u65E0\u4EBA\u5728\u573A\uFF0C\u4F60\u8FD9\u4E00\u8F6E\u628A\u80FD\u505A\u7684\u505A\u6389\uFF09\u3002\u4F60\u7684\u624B\u6BB5\u5F88\u5BBD\uFF1A
|
|
@@ -243803,7 +244104,7 @@ ${HIGH_RISK_COMMANDS}`;
|
|
|
243803
244104
|
return this.deps.kernel.model.lastSeq.get(artifactId) ?? 0;
|
|
243804
244105
|
}
|
|
243805
244106
|
evaluationKey(kind, artifactId, evidence) {
|
|
243806
|
-
const fingerprint2 = (0,
|
|
244107
|
+
const fingerprint2 = (0, import_node_crypto71.createHash)("sha256").update(JSON.stringify(evidence)).digest("hex");
|
|
243807
244108
|
return `${kind}:${artifactId}:${fingerprint2}`;
|
|
243808
244109
|
}
|
|
243809
244110
|
artifactEvidence(id) {
|
|
@@ -244182,8 +244483,8 @@ ${ctx.nodeFault}
|
|
|
244182
244483
|
this.deps.log?.(`[coordinator] ${workspace} \u5168\u5C40\u4E0A\u4E0B\u6587\u8BFB\u53D6\u5931\u8D25\uFF0C\u7EE7\u7EED\u6CBF\u7528\u539F\u534F\u8C03\u8005\u4EFB\u52A1\uFF1A${String(error2)}`);
|
|
244183
244484
|
}
|
|
244184
244485
|
}
|
|
244185
|
-
const runtimeSessionId = opts?.resumeSessionId ?? (0,
|
|
244186
|
-
const coordinatorRunId = `coordinate:${(0,
|
|
244486
|
+
const runtimeSessionId = opts?.resumeSessionId ?? (0, import_node_crypto71.randomUUID)();
|
|
244487
|
+
const coordinatorRunId = `coordinate:${(0, import_node_crypto71.randomUUID)()}`;
|
|
244187
244488
|
const taskWithContext = coordinatorContext ? [
|
|
244188
244489
|
task,
|
|
244189
244490
|
``,
|
|
@@ -244227,7 +244528,7 @@ ${ctx.nodeFault}
|
|
|
244227
244528
|
const startedAtMs = Date.now();
|
|
244228
244529
|
let trajectoryStarted = false;
|
|
244229
244530
|
if (this.deps.trajectory) {
|
|
244230
|
-
const bundleManifest = Object.fromEntries(Object.entries(job.bundle.files).map(([name, content3]) => [name, (0,
|
|
244531
|
+
const bundleManifest = Object.fromEntries(Object.entries(job.bundle.files).map(([name, content3]) => [name, (0, import_node_crypto71.createHash)("sha256").update(content3).digest("hex")]));
|
|
244231
244532
|
const session = {
|
|
244232
244533
|
runId: coordinatorRunId,
|
|
244233
244534
|
runtimeSessionId,
|
|
@@ -244432,11 +244733,11 @@ var init_pg_ident = __esm({
|
|
|
244432
244733
|
});
|
|
244433
244734
|
|
|
244434
244735
|
// ../storage/src/postgres.ts
|
|
244435
|
-
var
|
|
244736
|
+
var import_node_crypto72, ident4, isUniqueViolation, PostgresOplogStore, PostgresBlobStore;
|
|
244436
244737
|
var init_postgres = __esm({
|
|
244437
244738
|
"../storage/src/postgres.ts"() {
|
|
244438
244739
|
"use strict";
|
|
244439
|
-
|
|
244740
|
+
import_node_crypto72 = require("node:crypto");
|
|
244440
244741
|
init_pg_ident();
|
|
244441
244742
|
init_esm();
|
|
244442
244743
|
init_src();
|
|
@@ -244616,7 +244917,7 @@ var init_postgres = __esm({
|
|
|
244616
244917
|
return new _PostgresBlobStore(pool, schema);
|
|
244617
244918
|
}
|
|
244618
244919
|
async put(bytes2) {
|
|
244619
|
-
const hash2 = (0,
|
|
244920
|
+
const hash2 = (0, import_node_crypto72.createHash)("sha256").update(bytes2).digest("hex");
|
|
244620
244921
|
await this.pool.query(
|
|
244621
244922
|
`INSERT INTO ${this.t} (hash, bytes, size, content_type) VALUES ($1, $2, $3, $4) ON CONFLICT (hash) DO NOTHING`,
|
|
244622
244923
|
[hash2, Buffer.from(bytes2), bytes2.byteLength, sniffContentType(bytes2) ?? null]
|
|
@@ -250889,6 +251190,7 @@ var init_postgres_chat_sessions = __esm({
|
|
|
250889
251190
|
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS visibility text`);
|
|
250890
251191
|
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS outputs_fingerprints jsonb`);
|
|
250891
251192
|
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS outputs_copies jsonb`);
|
|
251193
|
+
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS file_sync_issues jsonb`);
|
|
250892
251194
|
await pool.query(`
|
|
250893
251195
|
WITH ranked AS (
|
|
250894
251196
|
SELECT id, row_number() OVER (PARTITION BY session_id ORDER BY seq, created_at, id) AS rn
|
|
@@ -251160,6 +251462,29 @@ var init_postgres_chat_sessions = __esm({
|
|
|
251160
251462
|
);
|
|
251161
251463
|
return r.rows[0]?.outputs_copies ?? null;
|
|
251162
251464
|
}
|
|
251465
|
+
async readFileIssues(sessionId) {
|
|
251466
|
+
const r = await this.pool.query(
|
|
251467
|
+
`SELECT file_sync_issues FROM ${this.s}.chat_sessions WHERE id = $1 AND company_id = $2`,
|
|
251468
|
+
[sessionId, this.companyId]
|
|
251469
|
+
);
|
|
251470
|
+
return Object.values(r.rows[0]?.file_sync_issues ?? {}).flat();
|
|
251471
|
+
}
|
|
251472
|
+
async writeFileIssues(sessionId, phase, issues) {
|
|
251473
|
+
await this.pool.query(
|
|
251474
|
+
`UPDATE ${this.s}.chat_sessions SET file_sync_issues = COALESCE(file_sync_issues, '{}'::jsonb) || $1::jsonb
|
|
251475
|
+
WHERE id = $2 AND company_id = $3`,
|
|
251476
|
+
[JSON.stringify({ [phase]: issues }), sessionId, this.companyId]
|
|
251477
|
+
);
|
|
251478
|
+
}
|
|
251479
|
+
async listFileSessionsByWorkspaces(workspaces) {
|
|
251480
|
+
if (!workspaces.length) return [];
|
|
251481
|
+
const r = await this.pool.query(
|
|
251482
|
+
`SELECT * FROM ${this.s}.chat_sessions WHERE company_id = $1 AND workspace = ANY($2::text[])
|
|
251483
|
+
AND visibility IS DISTINCT FROM 'internal' AND analyzed_run_id IS NULL ORDER BY id`,
|
|
251484
|
+
[this.companyId, workspaces]
|
|
251485
|
+
);
|
|
251486
|
+
return r.rows.map(rowToSession);
|
|
251487
|
+
}
|
|
251163
251488
|
/**
|
|
251164
251489
|
* 按路径**合并**写入:同一路径新副本覆盖旧副本,其余路径保留。合并在一条 UPDATE 里用 jsonb `||` 完成,
|
|
251165
251490
|
* 不是读出来改完再整份写回——两次收尾的复制前后脚落库时,后写的不会把先写的吞掉。
|
|
@@ -253243,11 +253568,11 @@ var init_postgres_delegations = __esm({
|
|
|
253243
253568
|
});
|
|
253244
253569
|
|
|
253245
253570
|
// ../storage/src/postgres-nodes.ts
|
|
253246
|
-
var
|
|
253571
|
+
var import_node_crypto73, ident13, PostgresNodeStore, PostgresNodeTokenStore, rowToNode, rowToRuntime;
|
|
253247
253572
|
var init_postgres_nodes = __esm({
|
|
253248
253573
|
"../storage/src/postgres-nodes.ts"() {
|
|
253249
253574
|
"use strict";
|
|
253250
|
-
|
|
253575
|
+
import_node_crypto73 = require("node:crypto");
|
|
253251
253576
|
init_pg_ident();
|
|
253252
253577
|
init_esm();
|
|
253253
253578
|
ident13 = (s2) => {
|
|
@@ -253464,7 +253789,7 @@ var init_postgres_nodes = __esm({
|
|
|
253464
253789
|
return store;
|
|
253465
253790
|
}
|
|
253466
253791
|
issue(nodeId) {
|
|
253467
|
-
const token = `ont_${(0,
|
|
253792
|
+
const token = `ont_${(0, import_node_crypto73.randomBytes)(24).toString("base64url")}`;
|
|
253468
253793
|
this.cache.set(token, nodeId);
|
|
253469
253794
|
void this.pool.query(`INSERT INTO ${this.s}.node_tokens (token,node_id) VALUES ($1,$2)`, [token, nodeId]);
|
|
253470
253795
|
return token;
|
|
@@ -253730,11 +254055,11 @@ var init_postgres_type_registry = __esm({
|
|
|
253730
254055
|
});
|
|
253731
254056
|
|
|
253732
254057
|
// ../storage/src/postgres-actor-memory.ts
|
|
253733
|
-
var
|
|
254058
|
+
var import_node_crypto74, matchClause, ident15, PostgresActorMemoryStore, rowToIndexEntry, rowToRecord;
|
|
253734
254059
|
var init_postgres_actor_memory = __esm({
|
|
253735
254060
|
"../storage/src/postgres-actor-memory.ts"() {
|
|
253736
254061
|
"use strict";
|
|
253737
|
-
|
|
254062
|
+
import_node_crypto74 = require("node:crypto");
|
|
253738
254063
|
init_pg_ident();
|
|
253739
254064
|
init_src();
|
|
253740
254065
|
matchClause = (q2) => q2.requireMatch && q2.keywords.length > 0 ? " WHERE m > 0" : "";
|
|
@@ -253944,7 +254269,7 @@ var init_postgres_actor_memory = __esm({
|
|
|
253944
254269
|
}
|
|
253945
254270
|
async write(input, now) {
|
|
253946
254271
|
if (input.memId === void 0) {
|
|
253947
|
-
const memId = `mem:${(0,
|
|
254272
|
+
const memId = `mem:${(0, import_node_crypto74.randomUUID)()}`;
|
|
253948
254273
|
const r2 = await this.pool.query(
|
|
253949
254274
|
`INSERT INTO ${this.s}.actor_memories
|
|
253950
254275
|
(mem_id, actor_id, project_id, keywords, content, version, created_at, updated_at, accessed_at, source_artifact_id, source_session_id)
|
|
@@ -255391,14 +255716,14 @@ function companySchemaName(companyId) {
|
|
|
255391
255716
|
if (typeof companyId !== "string" || !companyId.trim()) {
|
|
255392
255717
|
throw new Error("company schema mapping \u9700\u8981\u975E\u7A7A companyId\uFF08fail-closed\uFF1A\u4E0D\u56DE\u9000\u9ED8\u8BA4\u516C\u53F8\uFF09");
|
|
255393
255718
|
}
|
|
255394
|
-
const hex = (0,
|
|
255719
|
+
const hex = (0, import_node_crypto75.createHash)("sha256").update(companyId, "utf8").digest("hex");
|
|
255395
255720
|
return `${COMPANY_SCHEMA_PREFIX}${hex.slice(0, DIGEST_HEX_LEN)}`;
|
|
255396
255721
|
}
|
|
255397
|
-
var
|
|
255722
|
+
var import_node_crypto75, COMPANY_SCHEMA_PREFIX, DIGEST_HEX_LEN, SchemaMappingConflictError, TenantStorageLocationStore;
|
|
255398
255723
|
var init_tenant_schema_mapping = __esm({
|
|
255399
255724
|
"../storage/src/tenant-schema-mapping.ts"() {
|
|
255400
255725
|
"use strict";
|
|
255401
|
-
|
|
255726
|
+
import_node_crypto75 = require("node:crypto");
|
|
255402
255727
|
init_esm();
|
|
255403
255728
|
init_pg_ident();
|
|
255404
255729
|
COMPANY_SCHEMA_PREFIX = "c_";
|
|
@@ -255472,7 +255797,7 @@ var init_tenant_schema_mapping = __esm({
|
|
|
255472
255797
|
|
|
255473
255798
|
// ../storage/src/company-data-plane-schema.ts
|
|
255474
255799
|
function canonicalTypeDefHash(def) {
|
|
255475
|
-
return `sha256:${(0,
|
|
255800
|
+
return `sha256:${(0, import_node_crypto76.createHash)("sha256").update(JSON.stringify(def), "utf8").digest("hex")}`;
|
|
255476
255801
|
}
|
|
255477
255802
|
function defaultArtifactTypeTemplate() {
|
|
255478
255803
|
return [
|
|
@@ -255654,11 +255979,11 @@ async function seedDefaultArtifactTypes(pool, schema, templates = defaultArtifac
|
|
|
255654
255979
|
}
|
|
255655
255980
|
return { inserted };
|
|
255656
255981
|
}
|
|
255657
|
-
var
|
|
255982
|
+
var import_node_crypto76, DEFAULT_ARTIFACT_TYPE_TEMPLATE_VERSION;
|
|
255658
255983
|
var init_company_data_plane_schema = __esm({
|
|
255659
255984
|
"../storage/src/company-data-plane-schema.ts"() {
|
|
255660
255985
|
"use strict";
|
|
255661
|
-
|
|
255986
|
+
import_node_crypto76 = require("node:crypto");
|
|
255662
255987
|
init_esm();
|
|
255663
255988
|
init_pg_ident();
|
|
255664
255989
|
DEFAULT_ARTIFACT_TYPE_TEMPLATE_VERSION = "4c368e5c-types-v1";
|
|
@@ -255738,11 +256063,11 @@ function rowToFile2(row) {
|
|
|
255738
256063
|
updatedAt: new Date(row.updated_at).toISOString()
|
|
255739
256064
|
};
|
|
255740
256065
|
}
|
|
255741
|
-
var
|
|
256066
|
+
var import_node_crypto77, COMPANY_CONFLICT_MSG, CompanyIdentifierConflictError, CompanyOwnedRegistryStore;
|
|
255742
256067
|
var init_company_owned_registry_store = __esm({
|
|
255743
256068
|
"../storage/src/company-owned-registry-store.ts"() {
|
|
255744
256069
|
"use strict";
|
|
255745
|
-
|
|
256070
|
+
import_node_crypto77 = require("node:crypto");
|
|
255746
256071
|
init_esm();
|
|
255747
256072
|
init_src();
|
|
255748
256073
|
init_pg_ident();
|
|
@@ -256128,7 +256453,7 @@ var init_company_owned_registry_store = __esm({
|
|
|
256128
256453
|
enabled: skill.enabled,
|
|
256129
256454
|
files: files.map((f2) => ({ path: f2.path, blobHash: f2.blobHash }))
|
|
256130
256455
|
});
|
|
256131
|
-
return (0,
|
|
256456
|
+
return (0, import_node_crypto77.createHash)("sha256").update(body2).digest("hex");
|
|
256132
256457
|
}
|
|
256133
256458
|
};
|
|
256134
256459
|
}
|
|
@@ -258725,7 +259050,7 @@ function sourceSetConservation(input) {
|
|
|
258725
259050
|
return input.sourceFinal === input.copied + input.approvedRuntimeConversion + input.approvedArchive + input.approvedDiscard;
|
|
258726
259051
|
}
|
|
258727
259052
|
function payloadChecksum(value2) {
|
|
258728
|
-
return (0,
|
|
259053
|
+
return (0, import_node_crypto78.createHash)("sha256").update(JSON.stringify(value2)).digest("hex");
|
|
258729
259054
|
}
|
|
258730
259055
|
async function copyWorkorderDraftsIdempotent(pool, companyId, companySchema, manifestId, opts) {
|
|
258731
259056
|
const cs = quoteIdent2(companySchema);
|
|
@@ -259113,11 +259438,11 @@ async function copyTraceFamilyIdempotent(pool, companyId, companySchema, manifes
|
|
|
259113
259438
|
sequences
|
|
259114
259439
|
};
|
|
259115
259440
|
}
|
|
259116
|
-
var
|
|
259441
|
+
var import_node_crypto78, MissingInstallerActorsError, TypeCatalogNotCoveredError, ORG_REGISTRY_TABLES, TRACE_FAMILY;
|
|
259117
259442
|
var init_tenant_migration_operator = __esm({
|
|
259118
259443
|
"../storage/src/tenant-migration-operator.ts"() {
|
|
259119
259444
|
"use strict";
|
|
259120
|
-
|
|
259445
|
+
import_node_crypto78 = require("node:crypto");
|
|
259121
259446
|
init_esm();
|
|
259122
259447
|
init_pg_ident();
|
|
259123
259448
|
init_tenancy_attribution();
|
|
@@ -259349,8 +259674,8 @@ var init_tenant_new_company_provision = __esm({
|
|
|
259349
259674
|
// ../storage/src/knowledge-snapshot-crypto.ts
|
|
259350
259675
|
function sealSnapshot(snapshot, key) {
|
|
259351
259676
|
if (snapshot.content.startsWith(PREFIX3)) return structuredClone(snapshot);
|
|
259352
|
-
const iv = (0,
|
|
259353
|
-
const cipher = (0,
|
|
259677
|
+
const iv = (0, import_node_crypto79.randomBytes)(12);
|
|
259678
|
+
const cipher = (0, import_node_crypto79.createCipheriv)("aes-256-gcm", bytes(key), iv);
|
|
259354
259679
|
cipher.setAAD(aad2(snapshot));
|
|
259355
259680
|
const encrypted = Buffer.concat([cipher.update(snapshot.content, "utf8"), cipher.final()]);
|
|
259356
259681
|
return { ...structuredClone(snapshot), content: `${PREFIX3}${iv.toString("base64url")}.${cipher.getAuthTag().toString("base64url")}.${encrypted.toString("base64url")}` };
|
|
@@ -259360,7 +259685,7 @@ function openSnapshot(snapshot, key) {
|
|
|
259360
259685
|
const packed = snapshot.content.slice(PREFIX3.length).split(".");
|
|
259361
259686
|
if (packed.length !== 3 || packed.some((part) => !part)) throw new Error(`knowledge snapshot ${snapshot.ref} ciphertext is malformed`);
|
|
259362
259687
|
const [iv, tag, data] = packed;
|
|
259363
|
-
const decipher = (0,
|
|
259688
|
+
const decipher = (0, import_node_crypto79.createDecipheriv)("aes-256-gcm", bytes(key), Buffer.from(iv, "base64url"));
|
|
259364
259689
|
decipher.setAAD(aad2(snapshot));
|
|
259365
259690
|
decipher.setAuthTag(Buffer.from(tag, "base64url"));
|
|
259366
259691
|
return {
|
|
@@ -259368,11 +259693,11 @@ function openSnapshot(snapshot, key) {
|
|
|
259368
259693
|
content: Buffer.concat([decipher.update(Buffer.from(data, "base64url")), decipher.final()]).toString("utf8")
|
|
259369
259694
|
};
|
|
259370
259695
|
}
|
|
259371
|
-
var
|
|
259696
|
+
var import_node_crypto79, PREFIX3, bytes, aad2;
|
|
259372
259697
|
var init_knowledge_snapshot_crypto = __esm({
|
|
259373
259698
|
"../storage/src/knowledge-snapshot-crypto.ts"() {
|
|
259374
259699
|
"use strict";
|
|
259375
|
-
|
|
259700
|
+
import_node_crypto79 = require("node:crypto");
|
|
259376
259701
|
PREFIX3 = "oasis-knowledge:v1:";
|
|
259377
259702
|
bytes = (key) => {
|
|
259378
259703
|
const value2 = Buffer.from(key);
|
|
@@ -261402,6 +261727,7 @@ var init_src11 = __esm({
|
|
|
261402
261727
|
init_chat_recovery();
|
|
261403
261728
|
init_chat_system_message();
|
|
261404
261729
|
init_chat_turn_gate();
|
|
261730
|
+
init_chat_assistant_turn();
|
|
261405
261731
|
init_chat_workorder_files();
|
|
261406
261732
|
init_chat_broadcast();
|
|
261407
261733
|
init_workorder_terminal();
|
|
@@ -261484,6 +261810,7 @@ var init_src11 = __esm({
|
|
|
261484
261810
|
init_run_settlement_wiring();
|
|
261485
261811
|
init_deadline_clock();
|
|
261486
261812
|
init_read_model_clock();
|
|
261813
|
+
init_file_restore();
|
|
261487
261814
|
}
|
|
261488
261815
|
});
|
|
261489
261816
|
|
|
@@ -261619,20 +261946,20 @@ var fs45 = __toESM(require("node:fs"));
|
|
|
261619
261946
|
var os14 = __toESM(require("node:os"));
|
|
261620
261947
|
var path40 = __toESM(require("node:path"));
|
|
261621
261948
|
var import_node_child_process23 = require("node:child_process");
|
|
261622
|
-
var
|
|
261949
|
+
var import_node_crypto86 = require("node:crypto");
|
|
261623
261950
|
|
|
261624
261951
|
// ../cli/src/cli.ts
|
|
261625
261952
|
var fs40 = __toESM(require("node:fs"), 1);
|
|
261626
261953
|
var os12 = __toESM(require("node:os"), 1);
|
|
261627
261954
|
var path35 = __toESM(require("node:path"), 1);
|
|
261628
|
-
var
|
|
261955
|
+
var import_node_crypto84 = require("node:crypto");
|
|
261629
261956
|
|
|
261630
261957
|
// ../cli/src/serve.ts
|
|
261631
261958
|
var fs34 = __toESM(require("node:fs"), 1);
|
|
261632
261959
|
var os8 = __toESM(require("node:os"), 1);
|
|
261633
261960
|
var path29 = __toESM(require("node:path"), 1);
|
|
261634
261961
|
var import_node_child_process18 = require("node:child_process");
|
|
261635
|
-
var
|
|
261962
|
+
var import_node_crypto80 = require("node:crypto");
|
|
261636
261963
|
var import_node_url7 = require("node:url");
|
|
261637
261964
|
|
|
261638
261965
|
// ../cli/src/artifact-discovery-source.ts
|
|
@@ -262378,7 +262705,7 @@ init_src9();
|
|
|
262378
262705
|
init_src();
|
|
262379
262706
|
init_trajectory();
|
|
262380
262707
|
function deterministicUuid2(seed) {
|
|
262381
|
-
const h = (0,
|
|
262708
|
+
const h = (0, import_node_crypto80.createHash)("sha256").update(seed).digest();
|
|
262382
262709
|
const b2 = Buffer.from(h.subarray(0, 16));
|
|
262383
262710
|
b2[6] = b2[6] & 15 | 80;
|
|
262384
262711
|
b2[8] = b2[8] & 63 | 128;
|
|
@@ -262578,7 +262905,7 @@ function oasisWrapperScript() {
|
|
|
262578
262905
|
const repoRoot = (0, import_node_url7.fileURLToPath)(new URL("../../../", __esm_import_meta_url));
|
|
262579
262906
|
const tsx = path29.join(repoRoot, "node_modules/.bin/tsx");
|
|
262580
262907
|
const main = path29.join(repoRoot, "packages/cli/src/main.ts");
|
|
262581
|
-
const key = (0,
|
|
262908
|
+
const key = (0, import_node_crypto80.createHash)("sha256").update(repoRoot).digest("hex").slice(0, 12);
|
|
262582
262909
|
const uid = typeof process.getuid === "function" ? process.getuid() : "na";
|
|
262583
262910
|
const stable = path29.join(os8.tmpdir(), `oasis-cli-wrapper-${uid}-${key}`);
|
|
262584
262911
|
let dir;
|
|
@@ -262959,7 +263286,7 @@ async function startServe(opts) {
|
|
|
262959
263286
|
if (!hub) return Promise.resolve({ ok: false, reason: "\u672C\u8FDB\u7A0B\u6CA1\u6709\u8282\u70B9\u7F51\u5173" });
|
|
262960
263287
|
const online = hub.connectedDaemons().some((d) => d.daemonId === nodeId);
|
|
262961
263288
|
if (!online) return Promise.resolve({ ok: false, reason: "\u8282\u70B9\u5F53\u524D\u4E0D\u5728\u7EBF\uFF0C\u7528\u7684\u662F\u5B83\u4E0A\u6B21\u62A5\u7684\u6E05\u5355" });
|
|
262962
|
-
const requestId = (0,
|
|
263289
|
+
const requestId = (0, import_node_crypto80.randomUUID)();
|
|
262963
263290
|
const task = new Promise((resolve10) => {
|
|
262964
263291
|
const timer = setTimeout(() => {
|
|
262965
263292
|
modelRefreshWaiters.delete(requestId);
|
|
@@ -263230,6 +263557,8 @@ async function startServe(opts) {
|
|
|
263230
263557
|
listChatFiles: async (companyId, projectId2) => {
|
|
263231
263558
|
const chat = await chatStoreFor(companyId);
|
|
263232
263559
|
const facts = await blobStoreFor(companyId);
|
|
263560
|
+
const taskBindings = await (await artifactStateFor(companyId)).listWorkspaceBindings();
|
|
263561
|
+
const workOrderIds = taskBindings.filter((b2) => b2.projectId === projectId2 || isUncategorizedProjectId(projectId2) && !b2.projectId).map((b2) => b2.workOrderId);
|
|
263233
263562
|
return collectProjectChatFiles(chat, projectId2, async (ref2) => {
|
|
263234
263563
|
for (const cabinet of [assets, facts]) {
|
|
263235
263564
|
try {
|
|
@@ -263240,6 +263569,7 @@ async function startServe(opts) {
|
|
|
263240
263569
|
}
|
|
263241
263570
|
return null;
|
|
263242
263571
|
}, {
|
|
263572
|
+
workOrderIds,
|
|
263243
263573
|
// 委派子会话不进项目(ADR 0555:它的 outputs/ 是交给协调者的)。闭包在请求时才读
|
|
263244
263574
|
// `delegationStoreFor`,避开它在下方声明的 TDZ。
|
|
263245
263575
|
isDelegationChild: async (sessionId) => {
|
|
@@ -263711,7 +264041,7 @@ async function startServe(opts) {
|
|
|
263711
264041
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
263712
264042
|
if (buf || session.runId) {
|
|
263713
264043
|
await turnStore.appendMessage({
|
|
263714
|
-
id: (0,
|
|
264044
|
+
id: (0, import_node_crypto80.randomUUID)(),
|
|
263715
264045
|
sessionId: chatSessionId,
|
|
263716
264046
|
role: "assistant",
|
|
263717
264047
|
content: buf,
|
|
@@ -263757,7 +264087,7 @@ async function startServe(opts) {
|
|
|
263757
264087
|
chatTargets: {
|
|
263758
264088
|
inspect: inspectChatTarget,
|
|
263759
264089
|
createTargetSession: async ({ companyId, agentId, ownerHumanActorId, title }) => {
|
|
263760
|
-
const sessionId = (0,
|
|
264090
|
+
const sessionId = (0, import_node_crypto80.randomUUID)();
|
|
263761
264091
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
263762
264092
|
const binding = await registryStore.getBinding(agentId).catch(() => null);
|
|
263763
264093
|
await (await chatStoreFor(companyId)).createSession({
|
|
@@ -264424,6 +264754,16 @@ async function startServe(opts) {
|
|
|
264424
264754
|
delegationStores.set(id, store);
|
|
264425
264755
|
return store;
|
|
264426
264756
|
};
|
|
264757
|
+
const readChatFileBlob = async (companyId, ref2) => {
|
|
264758
|
+
const facts = await blobStoreFor(companyId);
|
|
264759
|
+
for (const cabinet of [assets, facts]) {
|
|
264760
|
+
try {
|
|
264761
|
+
return await cabinet.get(ref2);
|
|
264762
|
+
} catch {
|
|
264763
|
+
}
|
|
264764
|
+
}
|
|
264765
|
+
throw new Error("\u6587\u4EF6\u539F\u4EF6\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u8BD5\u6216\u91CD\u65B0\u4E0A\u4F20");
|
|
264766
|
+
};
|
|
264427
264767
|
const outputCopyScheduler = createOutputCopyScheduler({
|
|
264428
264768
|
putBlob: (bytes2) => assets.put(bytes2),
|
|
264429
264769
|
isDelegationChild: async (companyId, sessionId) => {
|
|
@@ -264697,6 +265037,41 @@ async function startServe(opts) {
|
|
|
264697
265037
|
const listCompanyMembers = (companyId) => controlPlaneStore.listMembers(companyId ?? defaultCompanyId);
|
|
264698
265038
|
let notificationLedgerWorker;
|
|
264699
265039
|
let notificationLedgerTimer;
|
|
265040
|
+
const sessionOutputsScan = async ({ chatSessionId, companyId }) => {
|
|
265041
|
+
const bridge = workdirBridge;
|
|
265042
|
+
if (!bridge) return null;
|
|
265043
|
+
const store = chatStoreRouter ? await chatStoreFor(companyId).catch(() => null) : chatSessionStore;
|
|
265044
|
+
const read = store?.readOutputFingerprints?.bind(store);
|
|
265045
|
+
const write = store?.writeOutputFingerprints?.bind(store);
|
|
265046
|
+
if (!read || !write) return null;
|
|
265047
|
+
const recorded = await store?.getSession(chatSessionId);
|
|
265048
|
+
const located = recorded?.runtimeId && recorded.runtimeKind ? { ok: true, loc: {
|
|
265049
|
+
nodeId: recorded.runtimeId,
|
|
265050
|
+
runtimeKind: recorded.runtimeKind,
|
|
265051
|
+
rtId: recorded.runtimeSessionId,
|
|
265052
|
+
workdirKey: `chat:${chatSessionId}`
|
|
265053
|
+
} } : await locateSessionWorkdir(delegationWorkdirLocator, { chatSessionId, ...companyId !== void 0 ? { companyId } : {} });
|
|
265054
|
+
if (located.ok && foreignNodeBlock(await nodeStore.getNode(located.loc.nodeId), companyId ?? defaultCompanyId)) return null;
|
|
265055
|
+
if (!located.ok) return null;
|
|
265056
|
+
const diff = await settleSessionOutputs({
|
|
265057
|
+
bridge,
|
|
265058
|
+
loc: located.loc,
|
|
265059
|
+
sessionId: chatSessionId,
|
|
265060
|
+
readFingerprints: read,
|
|
265061
|
+
writeFingerprints: write
|
|
265062
|
+
}).catch(() => null);
|
|
265063
|
+
if (diff && store) await outputCopyScheduler.schedule({
|
|
265064
|
+
store,
|
|
265065
|
+
bridge,
|
|
265066
|
+
loc: located.loc,
|
|
265067
|
+
chatSessionId,
|
|
265068
|
+
companyId,
|
|
265069
|
+
fingerprints: diff.fingerprints,
|
|
265070
|
+
scanIncomplete: diff.scanIncomplete
|
|
265071
|
+
});
|
|
265072
|
+
else await store?.writeFileIssues?.(chatSessionId, "save", [{ phase: "save", path: "outputs/", code: "SCAN_UNAVAILABLE", message: "\u539F\u8282\u70B9\u4EA7\u51FA\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25\uFF0C\u672A\u80FD\u786E\u8BA4\u672C\u8F6E\u6587\u4EF6\u5DF2\u4FDD\u5B58" }]);
|
|
265073
|
+
return diff?.changed ?? null;
|
|
265074
|
+
};
|
|
264700
265075
|
const server = await startOasisServer({
|
|
264701
265076
|
deployTargets,
|
|
264702
265077
|
onInterventionDraftResolved: (e) => notificationLedgerWorker?.draftResolved(e.companyId ?? defaultCompanyId, e.draftId, { by: e.by, approved: e.approved }),
|
|
@@ -264802,7 +265177,7 @@ async function startServe(opts) {
|
|
|
264802
265177
|
}));
|
|
264803
265178
|
}
|
|
264804
265179
|
const limits = { wallClockMs: wallClockForKind("planner") };
|
|
264805
|
-
const artifactId = `artifact:planner:${(0,
|
|
265180
|
+
const artifactId = `artifact:planner:${(0, import_node_crypto80.randomUUID)()}`;
|
|
264806
265181
|
const handle = await chatRemoteAdapter.spawn({
|
|
264807
265182
|
actor: planner.id,
|
|
264808
265183
|
// companyId 同协调者:planner 用的就是默认公司的 actors 服务,漏签会让它一调公司域端点就 404。
|
|
@@ -265034,6 +265409,7 @@ async function startServe(opts) {
|
|
|
265034
265409
|
// (于是每一行的「大小」都空掉)。顺序与 `/api/blobs/:hash` 那条读路同源。
|
|
265035
265410
|
// 写回也落资产柜,与附件上传同一个柜,否则新旧两版会分居两处。
|
|
265036
265411
|
blobs: {
|
|
265412
|
+
get: (ref2) => readChatFileBlob(void 0, ref2),
|
|
265037
265413
|
meta: async (blobRef) => {
|
|
265038
265414
|
for (const cabinet of [assets, blobs]) {
|
|
265039
265415
|
try {
|
|
@@ -265052,6 +265428,7 @@ async function startServe(opts) {
|
|
|
265052
265428
|
resolveBlobs: async (cid) => {
|
|
265053
265429
|
const factCabinet = await blobStoreFor(cid);
|
|
265054
265430
|
return {
|
|
265431
|
+
get: (ref2) => readChatFileBlob(cid, ref2),
|
|
265055
265432
|
meta: async (blobRef) => {
|
|
265056
265433
|
for (const cabinet of [assets, factCabinet]) {
|
|
265057
265434
|
try {
|
|
@@ -265139,40 +265516,8 @@ async function startServe(opts) {
|
|
|
265139
265516
|
// 三个方法的组合规则住在 `createDelegationWorkdirPort`(`@oasis/server`)——评审
|
|
265140
265517
|
// wo:acfee725 blocker ② 回归防线:**serve.ts 与单测走同一处**,那样「装配层退回全局 binding」
|
|
265141
265518
|
// 这类事故在单测里就能被复现。绝不许在这里再写一份。
|
|
265142
|
-
|
|
265143
|
-
|
|
265144
|
-
*
|
|
265145
|
-
* 复用 `delegationWorkdirLocator`(与派发、回流、chat 域**同一个 binding resolver 实例**)——
|
|
265146
|
-
* 委派回程读的就是子会话的 `outputs/`,主会话这条只是把同一套读口用到了自己身上。
|
|
265147
|
-
*
|
|
265148
|
-
* 三处 fail-closed,都返回 `null`(= 这一轮没有产出卡),一处都不猜:
|
|
265149
|
-
* · 桥还没建好 / 会话没绑定 / 节点离线 → 拿不到工作区;
|
|
265150
|
-
* · store 没有指纹方法(老 store / 文件态装配)→ 没地方记「上一轮长什么样」,
|
|
265151
|
-
* 硬扫会把整个 `outputs/` 每轮都当成新增,一口气刷几十张卡;
|
|
265152
|
-
* · 解析不出公司 → **绝不回落默认公司**(否则会去别家公司的库里读写指纹)。
|
|
265153
|
-
*/
|
|
265154
|
-
sessionOutputsScan: async ({ chatSessionId, companyId }) => {
|
|
265155
|
-
const bridge = workdirBridge;
|
|
265156
|
-
if (!bridge) return null;
|
|
265157
|
-
const store = chatStoreRouter ? await chatStoreFor(companyId).catch(() => null) : chatSessionStore;
|
|
265158
|
-
const read = store?.readOutputFingerprints?.bind(store);
|
|
265159
|
-
const write = store?.writeOutputFingerprints?.bind(store);
|
|
265160
|
-
if (!read || !write) return null;
|
|
265161
|
-
const located = await locateSessionWorkdir(delegationWorkdirLocator, {
|
|
265162
|
-
chatSessionId,
|
|
265163
|
-
...companyId !== void 0 ? { companyId } : {}
|
|
265164
|
-
});
|
|
265165
|
-
if (!located.ok) return null;
|
|
265166
|
-
const diff = await settleSessionOutputs({
|
|
265167
|
-
bridge,
|
|
265168
|
-
loc: located.loc,
|
|
265169
|
-
sessionId: chatSessionId,
|
|
265170
|
-
readFingerprints: read,
|
|
265171
|
-
writeFingerprints: write
|
|
265172
|
-
}).catch(() => null);
|
|
265173
|
-
if (diff && store) void outputCopyScheduler.schedule({ store, bridge, loc: located.loc, chatSessionId, companyId, fingerprints: diff.fingerprints });
|
|
265174
|
-
return diff?.changed ?? null;
|
|
265175
|
-
},
|
|
265519
|
+
// 会话产出扫描:实现见上方 `sessionOutputsScan`。serve 重启前后的恢复收尾用的是同一个函数。
|
|
265520
|
+
sessionOutputsScan,
|
|
265176
265521
|
delegationWorkdir: createDelegationWorkdirPort({
|
|
265177
265522
|
locator: delegationWorkdirLocator,
|
|
265178
265523
|
// 桥在 hub 建好后(本函数尾部)才赋值 → getter 每次调用时读最新值;早于此处的构造时 `workdirBridge`
|
|
@@ -265704,10 +266049,10 @@ async function startServe(opts) {
|
|
|
265704
266049
|
if (isDeletedActor(dispatchTarget)) {
|
|
265705
266050
|
throw new ApiError(409, ACTOR_DELETED_ERROR_CODE, ACTOR_DELETED_CHAT_MESSAGE);
|
|
265706
266051
|
}
|
|
265707
|
-
const runtimeSessionId = sessionId ?? (requestDispatchId ? deterministicUuid2(`chat-runtime:${requestDispatchId}`) : (0,
|
|
266052
|
+
const runtimeSessionId = sessionId ?? (requestDispatchId ? deterministicUuid2(`chat-runtime:${requestDispatchId}`) : (0, import_node_crypto80.randomUUID)());
|
|
265708
266053
|
const resumeRuntimeSession = Boolean(sessionId);
|
|
265709
|
-
const traceRunId = requestDispatchId ? `chat-run:${deterministicUuid2(`chat-trace:${requestDispatchId}`)}` : `chat-run:${(0,
|
|
265710
|
-
const artifactId = requestDispatchId ? `artifact:chat:${deterministicUuid2(`chat-artifact:${requestDispatchId}`)}` : `artifact:chat:${(0,
|
|
266054
|
+
const traceRunId = requestDispatchId ? `chat-run:${deterministicUuid2(`chat-trace:${requestDispatchId}`)}` : `chat-run:${(0, import_node_crypto80.randomUUID)()}`;
|
|
266055
|
+
const artifactId = requestDispatchId ? `artifact:chat:${deterministicUuid2(`chat-artifact:${requestDispatchId}`)}` : `artifact:chat:${(0, import_node_crypto80.randomUUID)()}`;
|
|
265711
266056
|
let stableDispatch = requestDispatchId ? await resolveStableChatDispatch({ store: await traceStoreFor(runCompanyId), runId: traceRunId }) : null;
|
|
265712
266057
|
if (stableDispatch && !stableDispatch.shouldDispatch) {
|
|
265713
266058
|
return {
|
|
@@ -265771,10 +266116,7 @@ async function startServe(opts) {
|
|
|
265771
266116
|
}
|
|
265772
266117
|
}
|
|
265773
266118
|
}
|
|
265774
|
-
const turnChatStore = chatSessionId ? await chatStoreFor(runCompanyId)
|
|
265775
|
-
console.warn(`[chat] \u53D6\u516C\u53F8 ${runCompanyId} \u7684\u4F1A\u8BDD\u5B58\u50A8\u5931\u8D25\uFF08\u672C\u8F6E\u6309\u65E0\u4F1A\u8BDD\u8BB0\u5F55\u5904\u7406\uFF09: ${String(err)}`);
|
|
265776
|
-
return null;
|
|
265777
|
-
}) : null;
|
|
266119
|
+
const turnChatStore = chatSessionId ? await chatStoreFor(runCompanyId) : null;
|
|
265778
266120
|
const analyzedRunId = chatSessionId ? (await turnChatStore?.getSession(chatSessionId).catch(() => null))?.analyzedRunId ?? void 0 : void 0;
|
|
265779
266121
|
const actorConfigVersion = await actorService.latestConfig(actorId).then((c) => c?.version ?? null).catch(() => null);
|
|
265780
266122
|
const candidateTraceStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -265805,6 +266147,22 @@ async function startServe(opts) {
|
|
|
265805
266147
|
...analyzedRunId ? { analyzedRunId } : {}
|
|
265806
266148
|
}
|
|
265807
266149
|
});
|
|
266150
|
+
const priorChatSession = chatSessionId ? await turnChatStore?.getSession(chatSessionId) : null;
|
|
266151
|
+
let freshChatWorkdir = chatSessionId ? chatNodeChanged(
|
|
266152
|
+
{ nodeId: priorChatSession?.runtimeId, runtimeKind: priorChatSession?.runtimeKind },
|
|
266153
|
+
{ nodeId: binding.nodeId, runtimeKind: binding.runtimeKind }
|
|
266154
|
+
) : false;
|
|
266155
|
+
let restore = !isolatedKnowledgeTurn && chatSessionId && turnChatStore ? await prepareSessionFileRestore({
|
|
266156
|
+
store: turnChatStore,
|
|
266157
|
+
sessionId: chatSessionId,
|
|
266158
|
+
readBlob: (ref2) => readChatFileBlob(runCompanyId, ref2),
|
|
266159
|
+
attachments,
|
|
266160
|
+
fresh: freshChatWorkdir,
|
|
266161
|
+
supportsFileRestore: node2.meta.supportsFileRestore === true
|
|
266162
|
+
}) : void 0;
|
|
266163
|
+
const usedRel = /* @__PURE__ */ new Set();
|
|
266164
|
+
const preparedAttachments = await buildChatAttachmentFiles(attachments, (ref2) => readChatFileBlob(runCompanyId, ref2), usedRel);
|
|
266165
|
+
if (preparedAttachments.missing.length) throw new ApiError(409, "CHAT_FILE_RESTORE_FAILED", preparedAttachments.missing.map((m2) => `${m2.name}\uFF1A${m2.error}`).join("\uFF1B"));
|
|
265808
266166
|
const stableTraceWasPresent = Boolean(stableDispatch);
|
|
265809
266167
|
if (requestDispatchId && !stableDispatch) {
|
|
265810
266168
|
stableDispatch = await resolveStableChatDispatch({
|
|
@@ -265827,13 +266185,20 @@ async function startServe(opts) {
|
|
|
265827
266185
|
binding = { actorId, ...stableDispatch.target, status: "active" };
|
|
265828
266186
|
node2 = await requireDispatchNode(binding);
|
|
265829
266187
|
requireNodeConnectors();
|
|
266188
|
+
freshChatWorkdir = chatNodeChanged(
|
|
266189
|
+
{ nodeId: priorChatSession?.runtimeId, runtimeKind: priorChatSession?.runtimeKind },
|
|
266190
|
+
{ nodeId: binding.nodeId, runtimeKind: binding.runtimeKind }
|
|
266191
|
+
);
|
|
266192
|
+
restore = !isolatedKnowledgeTurn && chatSessionId && turnChatStore ? await prepareSessionFileRestore({
|
|
266193
|
+
store: turnChatStore,
|
|
266194
|
+
sessionId: chatSessionId,
|
|
266195
|
+
readBlob: (ref2) => readChatFileBlob(runCompanyId, ref2),
|
|
266196
|
+
attachments,
|
|
266197
|
+
fresh: freshChatWorkdir,
|
|
266198
|
+
supportsFileRestore: node2.meta.supportsFileRestore === true
|
|
266199
|
+
}) : void 0;
|
|
265830
266200
|
}
|
|
265831
266201
|
}
|
|
265832
|
-
const priorChatSession = chatSessionId ? await turnChatStore?.getSession(chatSessionId).catch(() => null) : null;
|
|
265833
|
-
const freshChatWorkdir = chatSessionId ? chatNodeChanged(
|
|
265834
|
-
{ nodeId: priorChatSession?.runtimeId, runtimeKind: priorChatSession?.runtimeKind },
|
|
265835
|
-
{ nodeId: binding.nodeId, runtimeKind: binding.runtimeKind }
|
|
265836
|
-
) : false;
|
|
265837
266202
|
const existingTrace = stableDispatch?.run ?? null;
|
|
265838
266203
|
const existingEvents = existingTrace ? await (await traceStoreFor(runCompanyId)).listEvents(traceRunId, {}).catch(() => []) : [];
|
|
265839
266204
|
const traceStartedAt = existingTrace?.startedAt ?? candidateTraceStartedAt;
|
|
@@ -265879,18 +266244,13 @@ async function startServe(opts) {
|
|
|
265879
266244
|
const chatResolvedModel = sessionModelOverride ?? actorCtx?.config?.model ?? void 0;
|
|
265880
266245
|
const chatModel = chatResolvedModel ?? await registryStore.getRuntimeConfig(`runtime:${binding.nodeId}:${binding.runtimeKind}`).then((c) => c?.model).catch(() => void 0) ?? void 0;
|
|
265881
266246
|
const chatModelSource = sessionModelOverride ? "session_override" : chatResolvedModel ? "actor_config" : chatModel ? "runtime_default" : null;
|
|
265882
|
-
const
|
|
265883
|
-
const preparedAttachments = await buildChatAttachmentFiles(attachments, (ref2) => assets.get(ref2), usedRel);
|
|
265884
|
-
for (const miss of preparedAttachments.missing) {
|
|
265885
|
-
console.warn(`[chat] \u9644\u4EF6 blob ${miss.blobRef} \u8BFB\u53D6\u5931\u8D25: ${miss.error}`);
|
|
265886
|
-
}
|
|
265887
|
-
const attachmentFiles = { ...preparedAttachments.files };
|
|
266247
|
+
const attachmentFiles = { ...preparedAttachments.files, ...restore ? { "SESSION_FILES.md": restore.index } : {} };
|
|
265888
266248
|
const attachmentBinary = { ...preparedAttachments.binaryFiles };
|
|
265889
266249
|
const attachmentPaths = [...preparedAttachments.paths];
|
|
265890
266250
|
let turnProject = priorChatSession ? { state: "none" } : { state: "unknown" };
|
|
265891
266251
|
if (priorChatSession?.projectId) {
|
|
265892
266252
|
const projectId2 = priorChatSession.projectId;
|
|
265893
|
-
const projectBundle = await projectStateFor(runCompanyId).then((projects) => buildChatProjectBundle(projectId2, projects, (blobId) =>
|
|
266253
|
+
const projectBundle = await projectStateFor(runCompanyId).then((projects) => buildChatProjectBundle(projectId2, projects, (blobId) => readChatFileBlob(runCompanyId, blobId))).catch((err) => {
|
|
265894
266254
|
console.warn(`[chat] \u8BFB\u9879\u76EE ${projectId2} \u5931\u8D25\uFF08\u672C\u8F6E\u4E0D\u5199\u9879\u76EE\u6BB5\uFF09: ${String(err)}`);
|
|
265895
266255
|
return void 0;
|
|
265896
266256
|
});
|
|
@@ -265916,7 +266276,7 @@ async function startServe(opts) {
|
|
|
265916
266276
|
...actorCtx?.config?.prompt ? { personaPrompt: actorCtx.config.prompt } : {},
|
|
265917
266277
|
...extraSystemPrompt ? { expertSystemPrompt: extraSystemPrompt } : {}
|
|
265918
266278
|
});
|
|
265919
|
-
const taskHeader = chatPrompts.taskHeaderLines;
|
|
266279
|
+
const taskHeader = [...chatPrompts.taskHeaderLines, ...restore ? ["\u672C\u4F1A\u8BDD\u7684\u5386\u53F2\u6587\u4EF6\u4E0E\u5DF2\u4FDD\u5B58\u4EA7\u51FA\u89C1 SESSION_FILES.md\uFF0C\u53EF\u6309\u5217\u51FA\u7684\u76F8\u5BF9\u8DEF\u5F84\u8BFB\u53D6\u3002"] : []];
|
|
265920
266280
|
const chatMemoryEnabled = !isolatedKnowledgeTurn && actorCtx?.memoryEnabled !== false;
|
|
265921
266281
|
const chatMemorySvc = chatMemoryEnabled ? await actorMemoryFor(runCompanyId).catch(() => void 0) : void 0;
|
|
265922
266282
|
const chatMemoryLines = chatMemorySvc ? await chatMemorySvc.list({ actorId }, { scope: "all", keywords: ngramQueryTerms([message]), limit: MEMORY_INJECT_MAX, offset: 0 }).then((out) => [...memoryIndexLines(out.items), ...memoryHowToLines()]).catch(() => []) : [];
|
|
@@ -265961,7 +266321,7 @@ async function startServe(opts) {
|
|
|
265961
266321
|
actor: actorId,
|
|
265962
266322
|
actorToken: issueSessionToken(actorId, { artifactId, action: "chat", limits, binding, sessionId: runtimeSessionId, companyId: runCompanyId, ...requestDispatchId ? { dispatchId: requestDispatchId } : {}, ...chatSessionId !== void 0 ? { chatSessionId } : {} }),
|
|
265963
266323
|
artifactId,
|
|
265964
|
-
bundle: { files, ...Object.keys(attachmentBinary).length ? { binaryFiles: attachmentBinary } : {} },
|
|
266324
|
+
bundle: { files, ...Object.keys(attachmentBinary).length ? { binaryFiles: attachmentBinary } : {}, ...restore ? { restoreFiles: restore.restoreFiles } : {} },
|
|
265965
266325
|
// 人设在最前,固定规则接在它后面:助理那侧是分流正文(§6.5.3,只有普通脑暴那一支有),
|
|
265966
266326
|
// 专家那侧是 `EXPERT_DELEGATION_SYSTEM_PROMPT`(§6.5.7)。**三者都走 systemPrompt**——
|
|
265967
266327
|
// 放进 TASK.md 会随 `--resume` 每轮重复、O(N) 累积(§6.1.5)。
|
|
@@ -266094,10 +266454,11 @@ async function startServe(opts) {
|
|
|
266094
266454
|
}
|
|
266095
266455
|
});
|
|
266096
266456
|
const failed = !isHealthySessionExit(info);
|
|
266097
|
-
|
|
266098
|
-
|
|
266099
|
-
|
|
266100
|
-
|
|
266457
|
+
const recordRestore = turnChatStore && chatSessionId ? recordSessionFileRestoreExit(turnChatStore, chatSessionId, info) : Promise.resolve();
|
|
266458
|
+
void recordRestore.then(() => {
|
|
266459
|
+
if (!failed) resolve10();
|
|
266460
|
+
else reject(buildChatExitError(info));
|
|
266461
|
+
}, (error2) => reject(error2));
|
|
266101
266462
|
});
|
|
266102
266463
|
});
|
|
266103
266464
|
return {
|
|
@@ -266286,6 +266647,8 @@ async function startServe(opts) {
|
|
|
266286
266647
|
onCompanyError: chatRecoveryCompanyWarn(opts2.label),
|
|
266287
266648
|
// 重挂的那一轮收口时当场外报,与清扫拍同一个接收方(见 `notifyChatTurnSettled`)。
|
|
266288
266649
|
onTurnSettled: (info) => notifyChatTurnSettled(info),
|
|
266650
|
+
// 重挂 / 已收口两条路收尾时出产出卡(公司由扇出层按行绑)。
|
|
266651
|
+
sessionOutputsScan,
|
|
266289
266652
|
liveChat,
|
|
266290
266653
|
trace: runRoutedTrace,
|
|
266291
266654
|
traceHealth,
|
|
@@ -266441,6 +266804,7 @@ async function startServe(opts) {
|
|
|
266441
266804
|
listCompanies: chatRecoveryCompanies,
|
|
266442
266805
|
storesFor: chatRecoveryFor,
|
|
266443
266806
|
onCompanyError: chatRecoveryCompanyWarn("exit \u5BF9\u8D26"),
|
|
266807
|
+
sessionOutputsScan,
|
|
266444
266808
|
drainStash: (id) => chatRemoteAdapter?.drainStash(id) ?? { frames: [] },
|
|
266445
266809
|
log: (m2) => console.log(m2)
|
|
266446
266810
|
});
|
|
@@ -266509,6 +266873,7 @@ async function startServe(opts) {
|
|
|
266509
266873
|
listCompanies: chatRecoveryCompanies,
|
|
266510
266874
|
storesFor: chatRecoveryFor,
|
|
266511
266875
|
onCompanyError: chatRecoveryCompanyWarn("chat-sweep"),
|
|
266876
|
+
sessionOutputsScan,
|
|
266512
266877
|
getRun: (id) => fanOutTrace.getRun(id),
|
|
266513
266878
|
ownedRunId: (sid) => liveChat.runFor(sid),
|
|
266514
266879
|
now: Date.now(),
|
|
@@ -266541,7 +266906,12 @@ async function startServe(opts) {
|
|
|
266541
266906
|
storesFor: async (companyId) => {
|
|
266542
266907
|
const turns = await chatTurnsFor(companyId);
|
|
266543
266908
|
const messages = await chatStoreFor(companyId);
|
|
266544
|
-
return {
|
|
266909
|
+
return {
|
|
266910
|
+
turns,
|
|
266911
|
+
...assistantRowRecovery(messages, {
|
|
266912
|
+
outputsPartFor: (sid) => outputsPartProvider(sessionOutputsScan, sid, companyId)
|
|
266913
|
+
})
|
|
266914
|
+
};
|
|
266545
266915
|
},
|
|
266546
266916
|
getRun: (id) => fanOutTrace.getRun(id),
|
|
266547
266917
|
// 本进程在飞的轮不动——它自己的收尾路径会写终态(liveChat 只认人工/渠道那条,自动化轮
|
|
@@ -266834,7 +267204,7 @@ async function startServe(opts) {
|
|
|
266834
267204
|
console.log(`[new-engine] dispatchWork ${workId} \u662F human work\u2014\u2014\u4E0D\u6D3E runtime\uFF0C\u7B49\u5F85\u4EBA\u5DE5\u5904\u7406`);
|
|
266835
267205
|
return;
|
|
266836
267206
|
}
|
|
266837
|
-
const ledgerId = `dispatch:${(0,
|
|
267207
|
+
const ledgerId = `dispatch:${(0, import_node_crypto80.randomUUID)()}`;
|
|
266838
267208
|
try {
|
|
266839
267209
|
await (await dispatchLedgerFor(companyId)).insertOpen({
|
|
266840
267210
|
id: ledgerId,
|
|
@@ -266919,7 +267289,7 @@ async function startServe(opts) {
|
|
|
266919
267289
|
const kernelModel = newKernel.model;
|
|
266920
267290
|
const art = kernelModel.artifacts.get(nodeId);
|
|
266921
267291
|
const revWid = art?.workspace ?? "";
|
|
266922
|
-
const ledgerId = `dispatch:${(0,
|
|
267292
|
+
const ledgerId = `dispatch:${(0, import_node_crypto80.randomUUID)()}`;
|
|
266923
267293
|
try {
|
|
266924
267294
|
await (await dispatchLedgerFor(companyId)).insertOpen({
|
|
266925
267295
|
id: ledgerId,
|
|
@@ -267297,7 +267667,7 @@ async function startServe(opts) {
|
|
|
267297
267667
|
resolveSupplementalContext: server.knowledgeGovernance ? async ({ actorId, artifactId, workOrderId, action, part, runtimeKind, taskMarkdown }) => {
|
|
267298
267668
|
try {
|
|
267299
267669
|
const governance = server.knowledgeGovernance;
|
|
267300
|
-
const taskFingerprint = (0,
|
|
267670
|
+
const taskFingerprint = (0, import_node_crypto80.createHash)("sha256").update(JSON.stringify({ artifactId, workOrderId, action, part: part ?? null, taskMarkdown })).digest("hex");
|
|
267301
267671
|
const requestContext = {
|
|
267302
267672
|
organizationId: companyId,
|
|
267303
267673
|
actorId,
|
|
@@ -268935,7 +269305,9 @@ async function runSession(dispatchId, job, deps) {
|
|
|
268935
269305
|
deps.sink.stream({ type: "session_live_event", dispatchId, event });
|
|
268936
269306
|
normalizer.onLiveEvent(event);
|
|
268937
269307
|
});
|
|
269308
|
+
let restoreFailedBeforeStart = false;
|
|
268938
269309
|
handle.onExit((info) => {
|
|
269310
|
+
if (info.fileRestoreError) restoreFailedBeforeStart = true;
|
|
268939
269311
|
normalizer.turnFinished(isHealthySessionExit(info) ? "completed" : "failed");
|
|
268940
269312
|
log2("[node-cli]", ` \u25A0 session_exited id=${handle.id} code=${info.code ?? "killed"} total=${Date.now() - t0}ms`);
|
|
268941
269313
|
if (info.transcriptRef) log2("[node-cli]", ` transcript: ${info.transcriptRef}`);
|
|
@@ -268945,7 +269317,7 @@ async function runSession(dispatchId, job, deps) {
|
|
|
268945
269317
|
if (cancelledBeforeStart) {
|
|
268946
269318
|
log2("[node-cli]", ` dispatch ${dispatchId} \u5728 setup \u671F\u95F4\u5DF2\u88AB fencing\uFF0Cspawn \u540E\u7ACB\u5373 kill`);
|
|
268947
269319
|
await handle.kill();
|
|
268948
|
-
} else {
|
|
269320
|
+
} else if (!restoreFailedBeforeStart) {
|
|
268949
269321
|
log2("[node-cli]", ` \u2192 session_started id=${handle.id} setup=${Date.now() - t0}ms`);
|
|
268950
269322
|
deps.sink.keyFrame({ type: "session_started", dispatchId, sessionId: handle.id, jobArtifactId: job.artifactId });
|
|
268951
269323
|
}
|
|
@@ -268953,7 +269325,12 @@ async function runSession(dispatchId, job, deps) {
|
|
|
268953
269325
|
deps.onFailure?.();
|
|
268954
269326
|
log2("[node-cli]", ` spawn failed: ${err}`);
|
|
268955
269327
|
const errorMessage = String(err?.stack ?? err).slice(0, 8e3);
|
|
268956
|
-
deps.sink.keyFrame({ type: "session_exited", dispatchId, sessionId: "spawn-failed", info: {
|
|
269328
|
+
deps.sink.keyFrame({ type: "session_exited", dispatchId, sessionId: "spawn-failed", info: {
|
|
269329
|
+
code: null,
|
|
269330
|
+
reason: "error",
|
|
269331
|
+
errorMessage,
|
|
269332
|
+
...err instanceof BundleRestoreError ? { fileRestoreError: { path: err.filePath, message: err.message } } : {}
|
|
269333
|
+
} });
|
|
268957
269334
|
}
|
|
268958
269335
|
}
|
|
268959
269336
|
|
|
@@ -269244,8 +269621,9 @@ var SessionProcessState = class {
|
|
|
269244
269621
|
|
|
269245
269622
|
// ../cli/src/daemon/ws-client.ts
|
|
269246
269623
|
init_wrapper();
|
|
269624
|
+
init_src();
|
|
269247
269625
|
var import_node_os9 = require("node:os");
|
|
269248
|
-
var
|
|
269626
|
+
var import_node_crypto81 = require("node:crypto");
|
|
269249
269627
|
init_src8();
|
|
269250
269628
|
init_src6();
|
|
269251
269629
|
|
|
@@ -269526,10 +269904,15 @@ async function handleWorkdirRead(req) {
|
|
|
269526
269904
|
const fresh = await fh.stat().catch(() => null);
|
|
269527
269905
|
return { ok: false, code: "TOO_LARGE", size: Math.max(fresh?.size ?? 0, bytesRead), absPath: real };
|
|
269528
269906
|
}
|
|
269907
|
+
const afterRead = await fh.stat();
|
|
269908
|
+
if (afterRead.size !== st.size || afterRead.mtimeMs !== st.mtimeMs) {
|
|
269909
|
+
return { ok: false, code: "INTERNAL", message: "\u6587\u4EF6\u5728\u8BFB\u53D6\u671F\u95F4\u53D1\u751F\u53D8\u5316" };
|
|
269910
|
+
}
|
|
269529
269911
|
const bytes2 = buf.subarray(0, bytesRead);
|
|
269530
269912
|
return {
|
|
269531
269913
|
ok: true,
|
|
269532
269914
|
contentBase64: bytes2.toString("base64"),
|
|
269915
|
+
mtime: st.mtime.toISOString(),
|
|
269533
269916
|
contentType: contentTypeFor(real, bytes2),
|
|
269534
269917
|
size: bytes2.length
|
|
269535
269918
|
// 以实际读到的字节数为准,不用任何可能已过时的 stat size
|
|
@@ -269782,6 +270165,7 @@ var DaemonWsClient = class {
|
|
|
269782
270165
|
connect() {
|
|
269783
270166
|
if (this.stopped) return;
|
|
269784
270167
|
const ws = new import_websocket.default(this.serverUrl, {
|
|
270168
|
+
maxPayload: 4 * Math.ceil(FILE_CONTENT_MAX_BYTES / 3) + 64 * 1024,
|
|
269785
270169
|
headers: {
|
|
269786
270170
|
"x-daemon-id": this.daemonId,
|
|
269787
270171
|
// 经公网网关时鉴权靠它(对齐 multica:Authorization 头反代天然透传);内网直连可空
|
|
@@ -270017,7 +270401,7 @@ var DaemonWsClient = class {
|
|
|
270017
270401
|
*/
|
|
270018
270402
|
async queryArtifactStates(artifactIds, timeoutMs = 15e3) {
|
|
270019
270403
|
if (artifactIds.length === 0) return {};
|
|
270020
|
-
const requestId = (0,
|
|
270404
|
+
const requestId = (0, import_node_crypto81.randomUUID)();
|
|
270021
270405
|
return new Promise((resolve10, reject) => {
|
|
270022
270406
|
const timer = setTimeout(() => {
|
|
270023
270407
|
this.gcPending.delete(requestId);
|
|
@@ -270159,6 +270543,7 @@ var DaemonWsClient = class {
|
|
|
270159
270543
|
supportsNormalizedEvents: true,
|
|
270160
270544
|
// ADR 0554:本 daemon 认 `workdir_walk`。恒 true——handler 随包发,装了这版就一定有。
|
|
270161
270545
|
supportsWorkdirWalk: true,
|
|
270546
|
+
supportsFileRestore: true,
|
|
270162
270547
|
...activeSessions.length > 0 ? { activeSessions } : {},
|
|
270163
270548
|
// 始终带字段(空数组也带)作为新协议能力标志;服务端仅对支持该字段的节点做缺席确认。
|
|
270164
270549
|
pendingDispatchIds: [...this.pendingDispatchIds]
|
|
@@ -270419,7 +270804,7 @@ function forwardSignal(child, sig, killGroup = (pgid, signal) => {
|
|
|
270419
270804
|
// ../cli/src/daemon/machine-id.ts
|
|
270420
270805
|
var import_node_child_process21 = require("node:child_process");
|
|
270421
270806
|
var import_node_fs22 = require("node:fs");
|
|
270422
|
-
var
|
|
270807
|
+
var import_node_crypto82 = require("node:crypto");
|
|
270423
270808
|
var import_node_os12 = require("node:os");
|
|
270424
270809
|
function linuxMachineId() {
|
|
270425
270810
|
for (const p2 of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
@@ -270485,7 +270870,7 @@ var defaultSources = {
|
|
|
270485
270870
|
function resolveNodeId(sources = {}) {
|
|
270486
270871
|
const s2 = { ...defaultSources, ...sources };
|
|
270487
270872
|
const material = `${s2.machineFingerprint()}:${s2.osUser()}`;
|
|
270488
|
-
const digest = (0,
|
|
270873
|
+
const digest = (0, import_node_crypto82.createHash)("sha256").update(material).digest("hex").slice(0, 12);
|
|
270489
270874
|
return `node-${digest}`;
|
|
270490
270875
|
}
|
|
270491
270876
|
|
|
@@ -272256,13 +272641,13 @@ function ownFlagsFromDecl(command) {
|
|
|
272256
272641
|
}
|
|
272257
272642
|
|
|
272258
272643
|
// ../cli/src/connector-effect-runner.ts
|
|
272259
|
-
var
|
|
272644
|
+
var import_node_crypto83 = require("node:crypto");
|
|
272260
272645
|
var import_node_child_process22 = require("node:child_process");
|
|
272261
272646
|
init_src8();
|
|
272262
272647
|
function stableKey(effect) {
|
|
272263
272648
|
const keyFields = Object.fromEntries(Object.entries(effect.keyFields).sort(([a], [b2]) => a.localeCompare(b2)));
|
|
272264
272649
|
const canonical = JSON.stringify({ kind: effect.kind, target: effect.target, keyFields });
|
|
272265
|
-
return `sha256:${(0,
|
|
272650
|
+
return `sha256:${(0, import_node_crypto83.createHash)("sha256").update(canonical).digest("hex")}`;
|
|
272266
272651
|
}
|
|
272267
272652
|
async function runConnectorEffect(connector, toolArgs, deps) {
|
|
272268
272653
|
const effect = connector.describeExternalEffect?.(toolArgs) ?? null;
|
|
@@ -272498,7 +272883,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
|
272498
272883
|
const timeoutMs = resolveAuthWaitMs();
|
|
272499
272884
|
const controller = new AbortController();
|
|
272500
272885
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
272501
|
-
const waiterId = (0,
|
|
272886
|
+
const waiterId = (0, import_node_crypto84.randomUUID)();
|
|
272502
272887
|
process.stderr.write(
|
|
272503
272888
|
`\u7B49\u5F85\u4EBA\u5DE5\u6388\u6743\u4E2D\u2026\u2026\u6700\u591A ${Math.round(timeoutMs / 1e3)} \u79D2\uFF0C\u8D85\u65F6\u4F1A\u81EA\u52A8\u8F6C\u4E3A\u5F85\u5BA1\uFF1B\u8FD9\u4E0D\u662F\u9519\u8BEF\uFF0C\u8BF7\u52FF\u91CD\u8BD5\u540C\u4E00\u6761\u547D\u4EE4\u3002
|
|
272504
272889
|
`
|
|
@@ -272921,7 +273306,7 @@ async function runCli(argv, println = console.log, progressln = console.error) {
|
|
|
272921
273306
|
const store = createNodeTokenStore(path35.join(dir, "node-tokens.json"));
|
|
272922
273307
|
const sub = positional[0];
|
|
272923
273308
|
if (sub === "issue") {
|
|
272924
|
-
const id = flags.get("id") ?? `node-${(0,
|
|
273309
|
+
const id = flags.get("id") ?? `node-${(0, import_node_crypto84.randomUUID)()}`;
|
|
272925
273310
|
const token2 = store.issue(id);
|
|
272926
273311
|
println(token2);
|
|
272927
273312
|
process.stderr.write(
|
|
@@ -273946,7 +274331,7 @@ ${t.ref} ${t.name} [\u5267\u672C=${t.playbookRef}]`);
|
|
|
273946
274331
|
if (!name) throw new Error("\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
273947
274332
|
const goal = flags.get("goal")?.trim();
|
|
273948
274333
|
const slug6 = flags.get("slug");
|
|
273949
|
-
const id = slug6 !== void 0 ? projectSlug(slug6) : projectIdFromUuid((0,
|
|
274334
|
+
const id = slug6 !== void 0 ? projectSlug(slug6) : projectIdFromUuid((0, import_node_crypto84.randomUUID)());
|
|
273950
274335
|
const result = await api.request("POST", "/api/projects", {
|
|
273951
274336
|
...id ? { id } : {},
|
|
273952
274337
|
name,
|
|
@@ -275938,13 +276323,13 @@ var LEGACY_SYSTEMD_UNIT = "oasis-node.service";
|
|
|
275938
276323
|
var LEGACY_LAUNCHD_LABEL = "com.oasis.node";
|
|
275939
276324
|
|
|
275940
276325
|
// src/install.ts
|
|
275941
|
-
var
|
|
276326
|
+
var import_node_crypto85 = require("node:crypto");
|
|
275942
276327
|
var fs44 = __toESM(require("node:fs"));
|
|
275943
276328
|
var path39 = __toESM(require("node:path"));
|
|
275944
276329
|
function versionLabel(sourceFile, pkgVersion, npmPrefixDir, pkgName = LEGACY_PKG_NAME) {
|
|
275945
276330
|
const tag = pkgName === LEGACY_PKG_NAME ? "" : `+pkg.${pkgName.replace(/[^A-Za-z0-9-]/g, "-")}`;
|
|
275946
276331
|
if (isFromNpmPrefix(sourceFile, npmPrefixDir)) return `${pkgVersion}${tag}`;
|
|
275947
|
-
const digest = (0,
|
|
276332
|
+
const digest = (0, import_node_crypto85.createHash)("sha256").update(fs44.readFileSync(sourceFile)).digest("hex").slice(0, 8);
|
|
275948
276333
|
return tag ? `${pkgVersion}${tag}.local.${digest}` : `${pkgVersion}+local.${digest}`;
|
|
275949
276334
|
}
|
|
275950
276335
|
function isFromNpmPrefix(sourceFile, npmPrefixDir) {
|
|
@@ -276067,7 +276452,7 @@ function shimScript() {
|
|
|
276067
276452
|
}
|
|
276068
276453
|
|
|
276069
276454
|
// src/index.ts
|
|
276070
|
-
var PKG_VERSION = true ? "2.2.
|
|
276455
|
+
var PKG_VERSION = true ? "2.2.36" : "dev";
|
|
276071
276456
|
var LOCAL_BIN = localBin();
|
|
276072
276457
|
var NPM_PREFIX = npmPrefix();
|
|
276073
276458
|
var INSTANCE = DEFAULT_INSTANCE;
|
|
@@ -276352,7 +276737,7 @@ function newInstanceName() {
|
|
|
276352
276737
|
const existing = new Set(listInstances());
|
|
276353
276738
|
if (!existing.has(DEFAULT_INSTANCE)) return DEFAULT_INSTANCE;
|
|
276354
276739
|
for (; ; ) {
|
|
276355
|
-
const n = `inst-${(0,
|
|
276740
|
+
const n = `inst-${(0, import_node_crypto86.randomBytes)(3).toString("hex")}`;
|
|
276356
276741
|
if (!existing.has(n)) return n;
|
|
276357
276742
|
}
|
|
276358
276743
|
}
|