Reorganize modules into layered directories

This commit is contained in:
Youzini-afk
2026-04-08 01:17:47 +08:00
parent 59942541ea
commit feec17f3e3
90 changed files with 284 additions and 219 deletions

View File

@@ -3,14 +3,14 @@ import {
applyHideSettings,
isInManagedHideRange,
resetHideState,
} from "../hide-engine.js";
} from "../ui/hide-engine.js";
import {
buildExtractionMessages,
getAssistantTurns,
isAssistantChatMessage,
isBmeManagedHiddenMessage,
isSystemMessageForExtraction,
} from "../chat-history.js";
} from "../maintenance/chat-history.js";
const visibleAssistant = {
is_user: false,

View File

@@ -1,6 +1,6 @@
import assert from "node:assert/strict";
import { resolveTaskGenerationOptions } from "../generation-options.js";
import { createDefaultTaskProfiles } from "../prompt-profiles.js";
import { resolveTaskGenerationOptions } from "../runtime/generation-options.js";
import { createDefaultTaskProfiles } from "../prompting/prompt-profiles.js";
function buildSettingsWithExtractGeneration(generation) {
const taskProfiles = createDefaultTaskProfiles();

View File

@@ -8,8 +8,8 @@ import {
buildBmeDbName,
buildGraphFromSnapshot,
buildSnapshotFromGraph,
} from "../bme-db.js";
import { onMessageReceivedController } from "../event-binding.js";
} from "../sync/bme-db.js";
import { onMessageReceivedController } from "../host/event-binding.js";
import {
cloneGraphForPersistence,
cloneRuntimeDebugValue,
@@ -35,20 +35,20 @@ import {
stampGraphPersistenceMeta,
writeChatMetadataPatch,
writeGraphShadowSnapshot,
} from "../graph-persistence.js";
} from "../graph/graph-persistence.js";
import {
createEmptyGraph,
deserializeGraph,
getGraphStats,
getNode,
serializeGraph,
} from "../graph.js";
} from "../graph/graph.js";
import {
buildPersistedRecallRecord,
readPersistedRecallFromUserMessage,
} from "../recall-persistence.js";
import { getNodeDisplayName } from "../node-labels.js";
import { normalizeGraphRuntimeState } from "../runtime-state.js";
} from "../retrieval/recall-persistence.js";
import { getNodeDisplayName } from "../graph/node-labels.js";
import { normalizeGraphRuntimeState } from "../runtime/runtime-state.js";
import {
clampFloat,
clampInt,
@@ -63,7 +63,7 @@ import {
isFreshRecallInputRecord,
normalizeRecallInputText,
normalizeStageNoticeLevel,
} from "../ui-status.js";
} from "../ui/ui-status.js";
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
const indexPath = path.resolve(moduleDir, "../index.js");
@@ -273,6 +273,18 @@ async function createGraphPersistenceHarness({
__indexedDbSnapshots: indexedDbSnapshotMap,
sessionStorage: storage,
localStorage,
extension_settings: {
[MODULE_NAME]: {},
},
migrateLegacyTaskProfiles(settings = {}) {
return {
taskProfilesVersion: Number(settings?.taskProfilesVersion || 0),
taskProfiles:
settings?.taskProfiles && typeof settings.taskProfiles === "object"
? settings.taskProfiles
: {},
};
},
setTimeout(fn, delay) {
const id = nextTimerId++;
timers.set(id, { fn, delay });
@@ -325,6 +337,17 @@ async function createGraphPersistenceHarness({
runtimeContext.__panelRefreshCount += 1;
},
__panelRefreshCount: 0,
getLastProcessedAssistantFloor() {
const historyFloor = Number(
runtimeContext.currentGraph?.historyState?.lastProcessedAssistantFloor,
);
if (Number.isFinite(historyFloor)) {
return historyFloor;
}
const legacySeq = Number(runtimeContext.currentGraph?.lastProcessedSeq);
if (Number.isFinite(legacySeq)) return legacySeq;
return -1;
},
createEmptyGraph,
normalizeGraphRuntimeState,
serializeGraph,

View File

@@ -1,5 +1,5 @@
import assert from "node:assert/strict";
import { diffuseAndRank } from "../diffusion.js";
import { diffuseAndRank } from "../retrieval/diffusion.js";
import {
addEdge,
addNode,
@@ -8,7 +8,7 @@ import {
createEmptyGraph,
createNode,
invalidateEdge,
} from "../graph.js";
} from "../graph/graph.js";
const graph = createEmptyGraph();

View File

@@ -8,21 +8,21 @@ import {
onGenerationStartedController,
onMessageReceivedController,
onMessageSentController,
} from "../../event-binding.js";
import { resolveAutoExtractionPlanController } from "../../extraction-controller.js";
} from "../../host/event-binding.js";
import { resolveAutoExtractionPlanController } from "../../maintenance/extraction-controller.js";
import {
GRAPH_LOAD_STATES,
GRAPH_METADATA_KEY,
GRAPH_PERSISTENCE_META_KEY,
MODULE_NAME,
} from "../../graph-persistence.js";
} from "../../graph/graph-persistence.js";
import {
buildPersistedRecallRecord,
bumpPersistedRecallGenerationCount,
readPersistedRecallFromUserMessage,
resolveFinalRecallInjectionSource,
writePersistedRecallToUserMessage,
} from "../../recall-persistence.js";
} from "../../retrieval/recall-persistence.js";
import {
createGraphPersistenceState,
createRecallInputRecord,
@@ -39,7 +39,7 @@ import {
normalizeRecallInputText,
normalizeStageNoticeLevel,
shouldRunRecallForTransaction,
} from "../../ui-status.js";
} from "../../ui/ui-status.js";
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
const indexPath = path.resolve(moduleDir, "../../index.js");

View File

@@ -6,7 +6,7 @@ import {
resetHideState,
runIncrementalHideCheck,
unhideAll,
} from "../hide-engine.js";
} from "../ui/hide-engine.js";
function createRuntime(chat, chatId = "chat-a") {
const commands = [];

View File

@@ -5,8 +5,8 @@ import {
BmeDatabase,
buildBmeDbName,
ensureDexieLoaded,
} from "../bme-db.js";
import { createEmptyGraph } from "../graph.js";
} from "../sync/bme-db.js";
import { createEmptyGraph } from "../graph/graph.js";
const PREFIX = "[ST-BME][indexeddb-migration]";

View File

@@ -8,9 +8,9 @@ import {
buildGraphFromSnapshot,
buildSnapshotFromGraph,
ensureDexieLoaded,
} from "../bme-db.js";
import { BmeChatManager } from "../bme-chat-manager.js";
import { createEmptyGraph } from "../graph.js";
} from "../sync/bme-db.js";
import { BmeChatManager } from "../sync/bme-chat-manager.js";
import { createEmptyGraph } from "../graph/graph.js";
const PREFIX = "[ST-BME][indexeddb-persistence]";

View File

@@ -14,7 +14,7 @@ import {
scheduleUpload,
syncNow,
upload,
} from "../bme-sync.js";
} from "../sync/bme-sync.js";
const PREFIX = "[ST-BME][indexeddb-sync]";

View File

@@ -1,6 +1,6 @@
import assert from "node:assert/strict";
import { formatInjection } from "../injector.js";
import { DEFAULT_NODE_SCHEMA } from "../schema.js";
import { formatInjection } from "../retrieval/injector.js";
import { DEFAULT_NODE_SCHEMA } from "../graph/schema.js";
const coreEvent = {
id: "event-1",

View File

@@ -59,8 +59,8 @@ globalThis.__llmModelFetchExtensionSettings = {
};
globalThis.require = require;
const { createDefaultTaskProfiles } = await import("../prompt-profiles.js");
const llm = await import("../llm.js");
const { createDefaultTaskProfiles } = await import("../prompting/prompt-profiles.js");
const llm = await import("../llm/llm.js");
const extensionsApi = await import("../../../../extensions.js");
if (originalRequire === undefined) {

View File

@@ -8,7 +8,7 @@ import {
resolveLlmConfigSelection,
resolveActiveLlmPresetName,
sanitizeLlmPresetSettings,
} from "../llm-preset-utils.js";
} from "../llm/llm-preset-utils.js";
assert.deepEqual(createLlmConfigSnapshot({
llmApiUrl: " https://example.com/v1 ",

View File

@@ -59,8 +59,8 @@ globalThis.__llmStreamingExtensionSettings = {
};
globalThis.require = require;
const { createDefaultTaskProfiles } = await import("../prompt-profiles.js");
const llm = await import("../llm.js");
const { createDefaultTaskProfiles } = await import("../prompting/prompt-profiles.js");
const llm = await import("../llm/llm.js");
const extensionsApi = await import("../../../../extensions.js");
if (originalRequire === undefined) {

View File

@@ -5,7 +5,7 @@ import {
createMaintenanceJournalEntry,
normalizeGraphRuntimeState,
undoLatestMaintenance,
} from "../runtime-state.js";
} from "../runtime/runtime-state.js";
function clone(value) {
return JSON.parse(JSON.stringify(value));

View File

@@ -3,8 +3,8 @@ import fs from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import vm from "node:vm";
import { onManualExtractController } from "../extraction-controller.js";
import { onRebuildController } from "../ui-actions-controller.js";
import { onManualExtractController } from "../maintenance/extraction-controller.js";
import { onRebuildController } from "../ui/ui-actions-controller.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const indexPath = path.resolve(__dirname, "../index.js");

View File

@@ -4,7 +4,7 @@ const {
isLikelyMvuWorldInfoContent,
isMvuTaggedWorldInfoNameOrComment,
sanitizeMvuContent,
} = await import("../mvu-compat.js");
} = await import("../prompting/mvu-compat.js");
assert.equal(
isMvuTaggedWorldInfoNameOrComment("[mvu_update] 状态", ""),

View File

@@ -4,7 +4,7 @@ import { createRequire, registerHooks } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
import vm from "node:vm";
import { pruneProcessedMessageHashesFromFloor } from "../chat-history.js";
import { pruneProcessedMessageHashesFromFloor } from "../maintenance/chat-history.js";
import {
onBeforeCombinePromptsController,
onCharacterMessageRenderedController,
@@ -16,18 +16,18 @@ import {
onMessageSwipedController,
onUserMessageRenderedController,
registerCoreEventHooksController,
} from "../event-binding.js";
} from "../host/event-binding.js";
import {
onRerollController,
resolveAutoExtractionPlanController,
runExtractionController,
} from "../extraction-controller.js";
} from "../maintenance/extraction-controller.js";
import {
GRAPH_LOAD_STATES,
GRAPH_METADATA_KEY,
GRAPH_PERSISTENCE_META_KEY,
MODULE_NAME,
} from "../graph-persistence.js";
} from "../graph/graph-persistence.js";
import {
buildPersistedRecallRecord,
bumpPersistedRecallGenerationCount,
@@ -37,7 +37,7 @@ import {
resolveFinalRecallInjectionSource,
resolveGenerationTargetUserMessageIndex,
writePersistedRecallToUserMessage,
} from "../recall-persistence.js";
} from "../retrieval/recall-persistence.js";
import {
BATCH_STAGE_ORDER,
BATCH_STAGE_SEVERITY,
@@ -61,12 +61,12 @@ import {
pushBatchStageArtifact,
setBatchStageOutcome,
shouldRunRecallForTransaction,
} from "../ui-status.js";
} from "../ui/ui-status.js";
import {
onManualCompressController,
onManualEvolveController,
onManualSleepController,
} from "../ui-actions-controller.js";
} from "../ui/ui-actions-controller.js";
import { createGenerationRecallHarness } from "./helpers/generation-recall-harness.mjs";
const waitForTick = () => new Promise((resolve) => setTimeout(resolve, 0));
@@ -151,25 +151,25 @@ const {
createEdge,
addEdge,
removeNode,
} = await import("../graph.js");
const { compressType } = await import("../compressor.js");
const { syncGraphVectorIndex } = await import("../vector-index.js");
} = await import("../graph/graph.js");
const { compressType } = await import("../maintenance/compressor.js");
const { syncGraphVectorIndex } = await import("../vector/vector-index.js");
const {
extractMemories,
generateReflection,
generateSynopsis,
} = await import("../extractor.js");
const { consolidateMemories } = await import("../consolidator.js");
} = await import("../maintenance/extractor.js");
const { consolidateMemories } = await import("../maintenance/consolidator.js");
const {
createBatchJournalEntry,
buildReverseJournalRecoveryPlan,
normalizeGraphRuntimeState,
rollbackBatch,
} = await import("../runtime-state.js");
const { createDefaultTaskProfiles } = await import("../prompt-profiles.js");
} = await import("../runtime/runtime-state.js");
const { createDefaultTaskProfiles } = await import("../prompting/prompt-profiles.js");
const extensionsApi = await import("../../../../extensions.js");
const llm = await import("../llm.js");
const embedding = await import("../embedding.js");
const llm = await import("../llm/llm.js");
const embedding = await import("../vector/embedding.js");
if (originalRequire === undefined) {
delete globalThis.require;
@@ -1170,7 +1170,7 @@ async function createRecallUiHarness({
result: null,
};
context.globalThis = context;
const recallUiModule = await import("../recall-message-ui.js");
const recallUiModule = await import("../ui/recall-message-ui.js");
context.createRecallCardElement = recallUiModule.createRecallCardElement;
context.updateRecallCardData = recallUiModule.updateRecallCardData;
context.MutationObserver = harness.MutationObserver;
@@ -1401,6 +1401,7 @@ async function testRecallCardSurvivesLateMessageDomReplacement() {
isUser: true,
});
harness.chatRoot.appendChild(replacementElement);
harness.api.schedulePersistedRecallMessageUiRefresh();
await waitForTick();
await new Promise((resolve) => setTimeout(resolve, 120));
@@ -4351,7 +4352,7 @@ async function testGenerationRecallLockedSourceDoesNotDriftWithinTransaction() {
}
async function testBeforeCombineRecallNotSkippedWhenGraphLoadingButRuntimeGraphReadable() {
const { runRecallController } = await import("../recall-controller.js");
const { runRecallController } = await import("../retrieval/recall-controller.js");
const statuses = [];
const graph = normalizeGraphRuntimeState(createEmptyGraph(), "chat-main");
graph.nodes.push(
@@ -4784,7 +4785,7 @@ async function testGenerationEndedBackfillsRecentRecallAndSchedulesHideRefresh()
async function testRecallSubGraphAndDataLayerEntryPoints() {
// Sub-graph build test (pure function, no DOM needed)
const { buildRecallSubGraph } = await import("../recall-message-ui.js");
const { buildRecallSubGraph } = await import("../ui/recall-message-ui.js");
const graph = {
nodes: [

View File

@@ -45,8 +45,8 @@ registerHooks({
},
});
const { buildTaskLlmPayload, buildTaskPrompt } = await import("../prompt-builder.js");
const { createDefaultTaskProfiles } = await import("../prompt-profiles.js");
const { buildTaskLlmPayload, buildTaskPrompt } = await import("../prompting/prompt-builder.js");
const { createDefaultTaskProfiles } = await import("../prompting/prompt-profiles.js");
const settings = {
taskProfilesVersion: 3,

View File

@@ -122,13 +122,13 @@ function createWorldbookEntry({
try {
const extensionsApi = await import("../../../../extensions.js");
const { createDefaultTaskProfiles } = await import("../prompt-profiles.js");
const { createDefaultTaskProfiles } = await import("../prompting/prompt-profiles.js");
const {
buildTaskExecutionDebugContext,
buildTaskLlmPayload,
buildTaskPrompt,
} = await import("../prompt-builder.js");
const llm = await import("../llm.js");
} = await import("../prompting/prompt-builder.js");
const llm = await import("../llm/llm.js");
function createRule(id, findRegex, replaceString) {
return {

View File

@@ -6,7 +6,7 @@ import vm from "node:vm";
async function loadRetrieve(stubs) {
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const retrieverPath = path.resolve(__dirname, "../retriever.js");
const retrieverPath = path.resolve(__dirname, "../retrieval/retriever.js");
const source = await fs.readFile(retrieverPath, "utf8");
const transformed = `${source
.replace(/^import[\s\S]*?from\s+["'][^"']+["'];\r?\n/gm, "")
@@ -16,6 +16,7 @@ this.retrieve = retrieve;
const context = vm.createContext({
console: { log() {}, error() {}, warn() {} },
debugLog() {},
...stubs,
});
new vm.Script(transformed).runInContext(context);

View File

@@ -3,11 +3,11 @@ import fs from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import vm from "node:vm";
import { addNode, createEmptyGraph, createNode } from "../graph.js";
import { addNode, createEmptyGraph, createNode } from "../graph/graph.js";
async function loadEnhancer() {
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const enhancerPath = path.resolve(__dirname, "../retrieval-enhancer.js");
const enhancerPath = path.resolve(__dirname, "../retrieval/retrieval-enhancer.js");
const source = await fs.readFile(enhancerPath, "utf8");
const transformed = `${source
.replace(/^import[\s\S]*?from\s+["'][^"']+["'];\r?\n/gm, "")

View File

@@ -10,8 +10,8 @@ import {
rebindProcessedHistoryStateToChat,
rollbackBatch,
snapshotProcessedMessageHashes,
} from "../runtime-state.js";
import { createEmptyGraph } from "../graph.js";
} from "../runtime/runtime-state.js";
import { createEmptyGraph } from "../graph/graph.js";
const chat = [
{ is_user: true, mes: "你好" },

View File

@@ -7,7 +7,7 @@ import {
deserializeGraph,
findLatestNode,
serializeGraph,
} from "../graph.js";
} from "../graph/graph.js";
const graph = createEmptyGraph();
const objectiveNode = createNode({

View File

@@ -84,14 +84,14 @@ try {
};
const { getSTContextForPrompt, getSTContextSnapshot } =
await import("../st-context.js");
await import("../host/st-context.js");
const {
substituteTaskEjsParams,
createTaskEjsRenderContext,
evalTaskEjsTemplate,
checkTaskEjsSyntax,
inspectTaskEjsRuntimeBackend,
} = await import("../task-ejs.js");
} = await import("../prompting/task-ejs.js");
const promptContext = getSTContextForPrompt();
assert.deepEqual(promptContext, {

View File

@@ -4,7 +4,7 @@ import {
ensureTaskProfiles,
getActiveTaskProfile,
migrateLegacyTaskProfiles,
} from "../prompt-profiles.js";
} from "../prompting/prompt-profiles.js";
const legacySettings = {
extractPrompt: "旧提取提示",

View File

@@ -11,7 +11,7 @@ import {
importTaskProfile,
restoreDefaultTaskProfile,
upsertTaskProfile,
} from "../prompt-profiles.js";
} from "../prompting/prompt-profiles.js";
const taskProfiles = createDefaultTaskProfiles();
const baseProfile = taskProfiles.extract.profiles[0];

View File

@@ -149,16 +149,16 @@ function setTestContext({
}
try {
const { initializeHostAdapter } = await import("../host-adapter/index.js");
const { initializeHostAdapter } = await import("../host/adapter/index.js");
const { applyHostRegexReuse, applyTaskRegex, inspectTaskRegexReuse } = await import(
"../task-regex.js"
"../prompting/task-regex.js"
);
const {
createDefaultTaskProfiles,
isTaskRegexStageEnabled,
normalizeTaskProfile,
normalizeTaskRegexStages,
} = await import("../prompt-profiles.js");
} = await import("../prompting/prompt-profiles.js");
const normalizedLegacyStages = normalizeTaskRegexStages({
finalPrompt: true,
@@ -810,7 +810,7 @@ try {
}
try {
const { initializeHostAdapter } = await import("../host-adapter/index.js");
const { initializeHostAdapter } = await import("../host/adapter/index.js");
initializeHostAdapter({});
} catch {
// ignore reset failures in test cleanup

View File

@@ -317,9 +317,9 @@ try {
comment: entry.comment,
}));
const { resolveTaskWorldInfo } = await import("../task-worldinfo.js");
const { resolveTaskWorldInfo } = await import("../prompting/task-worldinfo.js");
const { buildTaskPrompt, buildTaskLlmPayload } = await import(
"../prompt-builder.js"
"../prompting/prompt-builder.js"
);
const emptyTriggerWorldInfo = await resolveTaskWorldInfo({
@@ -844,7 +844,7 @@ try {
["user", "system"],
);
const { initializeHostAdapter } = await import("../host-adapter/index.js");
const { initializeHostAdapter } = await import("../host/adapter/index.js");
const partialBridgeCalls = [];
const partialBridgeEntriesByWorldbook = {
"main-book": [createConstantWorldbookEntry(11, "主书原名", "主书内容。", "主书注释")],
@@ -950,7 +950,7 @@ try {
}
try {
const { initializeHostAdapter } = await import("../host-adapter/index.js");
const { initializeHostAdapter } = await import("../host/adapter/index.js");
initializeHostAdapter({});
} catch {
// ignore reset failures in test cleanup

View File

@@ -1,7 +1,7 @@
// wired into npm run test:all
import assert from "node:assert/strict";
import { MODULE_NAME } from "../graph-persistence.js";
import { isTrivialUserInput } from "../ui-status.js";
import { MODULE_NAME } from "../graph/graph-persistence.js";
import { isTrivialUserInput } from "../ui/ui-status.js";
import { createGenerationRecallHarness } from "./helpers/generation-recall-harness.mjs";
function assertEmptyRecallInputRecord(record) {
@@ -183,6 +183,15 @@ async function testOnMessageSentSkipsTrivialText() {
async function testNonTrivialGenerationClearsResidualTrivialSkip() {
const harness = await createGenerationRecallHarness();
harness.chat = [];
harness.result.setGraphPersistenceState({
loadState: "loaded",
dbReady: true,
});
harness.currentGraph = {
nodes: [],
edges: [],
historyState: {},
};
harness.__sendTextareaValue = "/echo";
harness.result.onGenerationStarted("normal", {}, false);
assert.ok(harness.result.getCurrentGenerationTrivialSkip());
@@ -194,8 +203,11 @@ async function testNonTrivialGenerationClearsResidualTrivialSkip() {
harness.chat.push({ is_user: false, mes: "assistant after non-trivial" });
harness.invokeOnMessageReceived(0, "");
await Promise.resolve();
assert.equal(harness.runExtractionCalls.length, 1);
const pending = harness.result.getPendingAutoExtraction();
assert.equal(pending?.messageId, 0);
assert.equal(pending?.reason, "generation-running");
assert.equal(harness.result.getCurrentGenerationTrivialSkip(), null);
harness.result.clearPendingAutoExtraction();
}
async function testNonTargetMessageIdDoesNotConsumeFlag() {
@@ -207,6 +219,15 @@ async function testNonTargetMessageIdDoesNotConsumeFlag() {
{ is_user: false, mes: "old assistant" },
{ is_user: true, mes: "u4" },
];
harness.result.setGraphPersistenceState({
loadState: "loaded",
dbReady: true,
});
harness.currentGraph = {
nodes: [],
edges: [],
historyState: {},
};
harness.__sendTextareaValue = "/echo";
harness.result.onGenerationStarted("normal", {}, false);
assert.equal(
@@ -215,14 +236,17 @@ async function testNonTargetMessageIdDoesNotConsumeFlag() {
);
harness.invokeOnMessageReceived(3, "");
await Promise.resolve();
assert.equal(harness.runExtractionCalls.length, 1);
const pendingBeforeTarget = harness.result.getPendingAutoExtraction();
assert.equal(pendingBeforeTarget?.messageId, 3);
assert.equal(pendingBeforeTarget?.reason, "generation-running");
assert.equal(harness.runExtractionCalls.length, 0);
assert.ok(harness.result.getCurrentGenerationTrivialSkip());
harness.chat.push({ is_user: false, mes: "target assistant" });
harness.invokeOnMessageReceived(5, "");
assert.equal(harness.runExtractionCalls.length, 1);
assert.equal(harness.runExtractionCalls.length, 0);
assert.equal(harness.result.getCurrentGenerationTrivialSkip(), null);
harness.result.clearPendingAutoExtraction();
}
async function testNullMessageIdFallsBackToLastAssistantIndex() {

View File

@@ -6,7 +6,7 @@ import vm from "node:vm";
async function loadVectorHelpers() {
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const sourcePath = path.resolve(__dirname, "../vector-index.js");
const sourcePath = path.resolve(__dirname, "../vector/vector-index.js");
const source = await fs.readFile(sourcePath, "utf8");
const pieces = [