From feec17f3e33b0c6977235dbd8d73906c90bc1a20 Mon Sep 17 00:00:00 2001 From: Youzini-afk <13153778771cx@gmail.com> Date: Wed, 8 Apr 2026 01:17:47 +0800 Subject: [PATCH] Reorganize modules into layered directories --- ena-planner/ena-planner.js | 2 +- .../graph-persistence.js | 2 +- graph.js => graph/graph.js | 4 +- memory-scope.js => graph/memory-scope.js | 0 node-labels.js => graph/node-labels.js | 0 schema.js => graph/schema.js | 0 .../adapter}/capabilities.js | 0 {host-adapter => host/adapter}/context.js | 2 +- {host-adapter => host/adapter}/index.js | 0 {host-adapter => host/adapter}/injection.js | 2 +- {host-adapter => host/adapter}/regex.js | 2 +- {host-adapter => host/adapter}/worldbook.js | 2 +- event-binding.js => host/event-binding.js | 0 st-context.js => host/st-context.js | 0 .../st-native-render.js | 2 +- index.js | 66 +++++++++---------- .../llm-preset-utils.js | 0 llm.js => llm/llm.js | 10 +-- .../chat-history.js | 8 +-- compressor.js => maintenance/compressor.js | 20 +++--- .../consolidator.js | 18 ++--- .../extraction-controller.js | 2 +- extractor.js => maintenance/extractor.js | 22 +++---- package.json | 5 +- .../default-task-profile-templates.js | 0 .../injection-sanitizer.js | 0 mvu-compat.js => prompting/mvu-compat.js | 0 .../prompt-builder.js | 2 +- .../prompt-profiles.js | 0 task-ejs.js => prompting/task-ejs.js | 6 +- task-regex.js => prompting/task-regex.js | 4 +- .../task-worldinfo.js | 6 +- diffusion.js => retrieval/diffusion.js | 0 dynamics.js => retrieval/dynamics.js | 0 injector.js => retrieval/injector.js | 4 +- .../recall-controller.js | 2 +- .../recall-persistence.js | 0 .../retrieval-enhancer.js | 6 +- retriever.js => retrieval/retriever.js | 16 ++--- debug-logging.js => runtime/debug-logging.js | 0 .../generation-options.js | 2 +- .../planner-tag-utils.js | 0 .../request-timeout.js | 0 runtime-debug.js => runtime/runtime-debug.js | 0 runtime-state.js => runtime/runtime-state.js | 25 +++++-- .../bme-chat-manager.js | 0 bme-db.js => sync/bme-db.js | 6 +- bme-sync.js => sync/bme-sync.js | 2 +- tests/chat-history.mjs | 4 +- tests/generation-options-filter.mjs | 4 +- tests/graph-persistence.mjs | 39 ++++++++--- tests/graph-retrieval.mjs | 4 +- tests/helpers/generation-recall-harness.mjs | 10 +-- tests/hide-engine.mjs | 2 +- tests/indexeddb-migration.mjs | 4 +- tests/indexeddb-persistence.mjs | 6 +- tests/indexeddb-sync.mjs | 2 +- tests/injector-format.mjs | 4 +- tests/llm-model-fetch.mjs | 4 +- tests/llm-preset-utils.mjs | 2 +- tests/llm-streaming.mjs | 4 +- tests/maintenance-journal.mjs | 2 +- tests/mobile-status-regressions.mjs | 4 +- tests/mvu-compat.mjs | 2 +- tests/p0-regressions.mjs | 39 +++++------ tests/prompt-builder-defaults.mjs | 4 +- tests/prompt-builder-mvu.mjs | 6 +- tests/retrieval-config.mjs | 3 +- tests/retrieval-enhancer.mjs | 4 +- tests/runtime-history.mjs | 4 +- tests/scoped-memory.mjs | 2 +- tests/st-context-task-ejs.mjs | 4 +- tests/task-profile-migration.mjs | 2 +- tests/task-profile-storage.mjs | 2 +- tests/task-regex.mjs | 8 +-- tests/task-worldinfo.mjs | 8 +-- tests/trivial-user-input.mjs | 38 +++++++++-- tests/vector-config.mjs | 2 +- graph-renderer.js => ui/graph-renderer.js | 4 +- hide-engine.js => ui/hide-engine.js | 0 notice.js => ui/notice.js | 0 panel-bridge.js => ui/panel-bridge.js | 2 +- panel.html => ui/panel.html | 0 panel.js => ui/panel.js | 12 ++-- .../recall-message-ui.js | 0 themes.js => ui/themes.js | 0 .../ui-actions-controller.js | 0 ui-status.js => ui/ui-status.js | 2 +- embedding.js => vector/embedding.js | 2 +- vector-index.js => vector/vector-index.js | 8 +-- 90 files changed, 284 insertions(+), 219 deletions(-) rename graph-persistence.js => graph/graph-persistence.js (99%) rename graph.js => graph/graph.js (99%) rename memory-scope.js => graph/memory-scope.js (100%) rename node-labels.js => graph/node-labels.js (100%) rename schema.js => graph/schema.js (100%) rename {host-adapter => host/adapter}/capabilities.js (100%) rename {host-adapter => host/adapter}/context.js (97%) rename {host-adapter => host/adapter}/index.js (100%) rename {host-adapter => host/adapter}/injection.js (97%) rename {host-adapter => host/adapter}/regex.js (99%) rename {host-adapter => host/adapter}/worldbook.js (99%) rename event-binding.js => host/event-binding.js (100%) rename st-context.js => host/st-context.js (100%) rename st-native-render.js => host/st-native-render.js (98%) rename llm-preset-utils.js => llm/llm-preset-utils.js (100%) rename llm.js => llm/llm.js (99%) rename chat-history.js => maintenance/chat-history.js (96%) rename compressor.js => maintenance/compressor.js (97%) rename consolidator.js => maintenance/consolidator.js (97%) rename extraction-controller.js => maintenance/extraction-controller.js (99%) rename extractor.js => maintenance/extractor.js (98%) rename default-task-profile-templates.js => prompting/default-task-profile-templates.js (100%) rename injection-sanitizer.js => prompting/injection-sanitizer.js (100%) rename mvu-compat.js => prompting/mvu-compat.js (100%) rename prompt-builder.js => prompting/prompt-builder.js (99%) rename prompt-profiles.js => prompting/prompt-profiles.js (100%) rename task-ejs.js => prompting/task-ejs.js (99%) rename task-regex.js => prompting/task-regex.js (99%) rename task-worldinfo.js => prompting/task-worldinfo.js (99%) rename diffusion.js => retrieval/diffusion.js (100%) rename dynamics.js => retrieval/dynamics.js (100%) rename injector.js => retrieval/injector.js (98%) rename recall-controller.js => retrieval/recall-controller.js (99%) rename recall-persistence.js => retrieval/recall-persistence.js (100%) rename retrieval-enhancer.js => retrieval/retrieval-enhancer.js (99%) rename retriever.js => retrieval/retriever.js (99%) rename debug-logging.js => runtime/debug-logging.js (100%) rename generation-options.js => runtime/generation-options.js (98%) rename planner-tag-utils.js => runtime/planner-tag-utils.js (100%) rename request-timeout.js => runtime/request-timeout.js (100%) rename runtime-debug.js => runtime/runtime-debug.js (100%) rename runtime-state.js => runtime/runtime-state.js (97%) rename bme-chat-manager.js => sync/bme-chat-manager.js (100%) rename bme-db.js => sync/bme-db.js (99%) rename bme-sync.js => sync/bme-sync.js (99%) rename graph-renderer.js => ui/graph-renderer.js (99%) rename hide-engine.js => ui/hide-engine.js (100%) rename notice.js => ui/notice.js (100%) rename panel-bridge.js => ui/panel-bridge.js (98%) rename panel.html => ui/panel.html (100%) rename panel.js => ui/panel.js (99%) rename recall-message-ui.js => ui/recall-message-ui.js (100%) rename themes.js => ui/themes.js (100%) rename ui-actions-controller.js => ui/ui-actions-controller.js (100%) rename ui-status.js => ui/ui-status.js (99%) rename embedding.js => vector/embedding.js (99%) rename vector-index.js => vector/vector-index.js (98%) diff --git a/ena-planner/ena-planner.js b/ena-planner/ena-planner.js index d14f393..46396b7 100644 --- a/ena-planner/ena-planner.js +++ b/ena-planner/ena-planner.js @@ -2,7 +2,7 @@ import { extension_settings } from '../../../../extensions.js'; import { getRequestHeaders, saveSettingsDebounced, substituteParamsExtended } from '../../../../../script.js'; import { EnaPlannerStorage, migrateFromLWBIfNeeded } from './ena-planner-storage.js'; import { DEFAULT_PROMPT_BLOCKS, BUILTIN_TEMPLATES } from './ena-planner-presets.js'; -import { debugLog } from '../debug-logging.js'; +import { debugLog } from '../runtime/debug-logging.js'; import jsyaml from '../vendor/js-yaml.mjs'; const EXT_NAME = 'ena-planner'; diff --git a/graph-persistence.js b/graph/graph-persistence.js similarity index 99% rename from graph-persistence.js rename to graph/graph-persistence.js index 1984671..87add57 100644 --- a/graph-persistence.js +++ b/graph/graph-persistence.js @@ -2,7 +2,7 @@ // 不依赖 index.js 模块级可变状态(currentGraph / graphPersistenceState 等) import { deserializeGraph, serializeGraph } from "./graph.js"; -import { normalizeGraphRuntimeState } from "./runtime-state.js"; +import { normalizeGraphRuntimeState } from "../runtime/runtime-state.js"; // ═══════════════════════════════════════════════════════════ // 常量 diff --git a/graph.js b/graph/graph.js similarity index 99% rename from graph.js rename to graph/graph.js index 59b780c..1bc729b 100644 --- a/graph.js +++ b/graph/graph.js @@ -7,7 +7,7 @@ import { createDefaultVectorIndexState, normalizeGraphRuntimeState, PROCESSED_MESSAGE_HASH_VERSION, -} from "./runtime-state.js"; +} from "../runtime/runtime-state.js"; import { hasSameScopeIdentity, normalizeEdgeMemoryScope, @@ -15,7 +15,7 @@ import { normalizeNodeMemoryScope, isSameLatestScopeBucket, } from "./memory-scope.js"; -import { debugLog } from "./debug-logging.js"; +import { debugLog } from "../runtime/debug-logging.js"; /** * 图状态版本号 diff --git a/memory-scope.js b/graph/memory-scope.js similarity index 100% rename from memory-scope.js rename to graph/memory-scope.js diff --git a/node-labels.js b/graph/node-labels.js similarity index 100% rename from node-labels.js rename to graph/node-labels.js diff --git a/schema.js b/graph/schema.js similarity index 100% rename from schema.js rename to graph/schema.js diff --git a/host-adapter/capabilities.js b/host/adapter/capabilities.js similarity index 100% rename from host-adapter/capabilities.js rename to host/adapter/capabilities.js diff --git a/host-adapter/context.js b/host/adapter/context.js similarity index 97% rename from host-adapter/context.js rename to host/adapter/context.js index 6acfa23..a1e383b 100644 --- a/host-adapter/context.js +++ b/host/adapter/context.js @@ -1,7 +1,7 @@ import { getContext as extensionGetContext } from "../../../../extensions.js"; import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js"; -import { debugDebug } from "../debug-logging.js"; +import { debugDebug } from "../../runtime/debug-logging.js"; function resolveContextGetter(providedGetter = null) { if (typeof providedGetter === "function") { diff --git a/host-adapter/index.js b/host/adapter/index.js similarity index 100% rename from host-adapter/index.js rename to host/adapter/index.js diff --git a/host-adapter/injection.js b/host/adapter/injection.js similarity index 97% rename from host-adapter/injection.js rename to host/adapter/injection.js index 65fd963..e187ddd 100644 --- a/host-adapter/injection.js +++ b/host/adapter/injection.js @@ -1,6 +1,6 @@ import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js"; import { createContextHostFacade } from "./context.js"; -import { debugDebug } from "../debug-logging.js"; +import { debugDebug } from "../../runtime/debug-logging.js"; function resolvePromptSetter(providedSetter = null, contextHost = null) { if (typeof providedSetter === "function") { diff --git a/host-adapter/regex.js b/host/adapter/regex.js similarity index 99% rename from host-adapter/regex.js rename to host/adapter/regex.js index c022aee..f730791 100644 --- a/host-adapter/regex.js +++ b/host/adapter/regex.js @@ -1,6 +1,6 @@ import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js"; import { createContextHostFacade } from "./context.js"; -import { debugDebug } from "../debug-logging.js"; +import { debugDebug } from "../../runtime/debug-logging.js"; const REGEX_API_NAMES = [ "getTavernRegexes", diff --git a/host-adapter/worldbook.js b/host/adapter/worldbook.js similarity index 99% rename from host-adapter/worldbook.js rename to host/adapter/worldbook.js index 39af207..f697505 100644 --- a/host-adapter/worldbook.js +++ b/host/adapter/worldbook.js @@ -1,6 +1,6 @@ import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js"; import { createContextHostFacade } from "./context.js"; -import { debugDebug } from "../debug-logging.js"; +import { debugDebug } from "../../runtime/debug-logging.js"; const WORLDBOOK_API_NAMES = [ "getWorldbook", diff --git a/event-binding.js b/host/event-binding.js similarity index 100% rename from event-binding.js rename to host/event-binding.js diff --git a/st-context.js b/host/st-context.js similarity index 100% rename from st-context.js rename to host/st-context.js diff --git a/st-native-render.js b/host/st-native-render.js similarity index 98% rename from st-native-render.js rename to host/st-native-render.js index 3056931..5223cbc 100644 --- a/st-native-render.js +++ b/host/st-native-render.js @@ -1,5 +1,5 @@ import { substituteParamsExtended } from "../../../../script.js"; -import jsyaml from "./vendor/js-yaml.mjs"; +import jsyaml from "../vendor/js-yaml.mjs"; function getTemplateRuntime() { return globalThis.window?.EjsTemplate || globalThis.EjsTemplate || null; diff --git a/index.js b/index.js index 7ef058d..3d14091 100644 --- a/index.js +++ b/index.js @@ -16,20 +16,20 @@ import { saveMetadataDebounced, } from "../../../extensions.js"; -import { BmeChatManager } from "./bme-chat-manager.js"; +import { BmeChatManager } from "./sync/bme-chat-manager.js"; import { BmeDatabase, buildBmeDbName, buildGraphFromSnapshot, buildSnapshotFromGraph, ensureDexieLoaded, -} from "./bme-db.js"; +} from "./sync/bme-db.js"; import { autoSyncOnChatChange, autoSyncOnVisibility, scheduleUpload, syncNow, -} from "./bme-sync.js"; +} from "./sync/bme-sync.js"; import { buildExtractionMessages, clampRecoveryStartFloor, @@ -39,16 +39,16 @@ import { pruneProcessedMessageHashesFromFloor, resolveDirtyFloorFromMutationMeta, rollbackAffectedJournals, -} from "./chat-history.js"; +} from "./maintenance/chat-history.js"; import { compressAll, inspectAutoCompressionCandidates, sleepCycle, -} from "./compressor.js"; +} from "./maintenance/compressor.js"; import { analyzeAutoConsolidationGate, consolidateMemories, -} from "./consolidator.js"; +} from "./maintenance/consolidator.js"; import { installSendIntentHooksController, onBeforeCombinePromptsController, @@ -67,23 +67,23 @@ import { registerCoreEventHooksController, registerGenerationAfterCommandsController, scheduleSendIntentHookRetryController, -} from "./event-binding.js"; +} from "./host/event-binding.js"; import { executeExtractionBatchController, onManualExtractController, onRerollController, resolveAutoExtractionPlanController, runExtractionController, -} from "./extraction-controller.js"; +} from "./maintenance/extraction-controller.js"; import { debugDebug, debugLog, -} from "./debug-logging.js"; +} from "./runtime/debug-logging.js"; import { extractMemories, generateReflection, generateSynopsis, -} from "./extractor.js"; +} from "./maintenance/extractor.js"; import { findGraphShadowSnapshotByIntegrity, GRAPH_LOAD_PENDING_CHAT_ID, @@ -103,7 +103,7 @@ import { stampGraphPersistenceMeta, writeChatMetadataPatch, writeGraphShadowSnapshot, -} from "./graph-persistence.js"; +} from "./graph/graph-persistence.js"; import { applyHideSettings, getHideStateSnapshot, @@ -111,7 +111,7 @@ import { runIncrementalHideCheck, scheduleHideSettingsApply, unhideAll, -} from "./hide-engine.js"; +} from "./ui/hide-engine.js"; import { createEmptyGraph, deserializeGraph, @@ -121,7 +121,7 @@ import { importGraph, removeNode, updateNode, -} from "./graph.js"; +} from "./graph/graph.js"; import { HOST_ADAPTER_STATE_SEMANTICS, getHostAdapter, @@ -129,33 +129,33 @@ import { initializeHostAdapter, readHostCapability, refreshHostCapabilitySnapshot, -} from "./host-adapter/index.js"; -import { estimateTokens, formatInjection } from "./injector.js"; -import { fetchMemoryLLMModels, testLLMConnection } from "./llm.js"; -import { getNodeDisplayName } from "./node-labels.js"; -import { showManagedBmeNotice } from "./notice.js"; +} from "./host/adapter/index.js"; +import { estimateTokens, formatInjection } from "./retrieval/injector.js"; +import { fetchMemoryLLMModels, testLLMConnection } from "./llm/llm.js"; +import { getNodeDisplayName } from "./graph/node-labels.js"; +import { showManagedBmeNotice } from "./ui/notice.js"; import { createNoticePanelActionController, initializePanelBridgeController, refreshPanelLiveStateController, -} from "./panel-bridge.js"; +} from "./ui/panel-bridge.js"; import { createDefaultTaskProfiles, migrateLegacyTaskProfiles, -} from "./prompt-profiles.js"; -import { inspectTaskRegexReuse } from "./task-regex.js"; +} from "./prompting/prompt-profiles.js"; +import { inspectTaskRegexReuse } from "./prompting/task-regex.js"; import { applyRecallInjectionController, buildRecallRecentMessagesController, getRecallUserMessageSourceLabelController, resolveRecallInputController, runRecallController, -} from "./recall-controller.js"; +} from "./retrieval/recall-controller.js"; import { createRecallCardElement, openRecallSidebar, updateRecallCardData, -} from "./recall-message-ui.js"; +} from "./ui/recall-message-ui.js"; import { buildPersistedRecallRecord, bumpPersistedRecallGenerationCount, @@ -165,9 +165,9 @@ import { resolveFinalRecallInjectionSource, resolveGenerationTargetUserMessageIndex, writePersistedRecallToUserMessage, -} from "./recall-persistence.js"; -import { resolveConfiguredTimeoutMs } from "./request-timeout.js"; -import { retrieve } from "./retriever.js"; +} from "./retrieval/recall-persistence.js"; +import { resolveConfiguredTimeoutMs } from "./runtime/request-timeout.js"; +import { retrieve } from "./retrieval/retriever.js"; import { appendBatchJournal, appendMaintenanceJournal, @@ -185,8 +185,8 @@ import { rebindProcessedHistoryStateToChat, snapshotProcessedMessageHashes, undoLatestMaintenance, -} from "./runtime-state.js"; -import { DEFAULT_NODE_SCHEMA, validateSchema } from "./schema.js"; +} from "./runtime/runtime-state.js"; +import { DEFAULT_NODE_SCHEMA, validateSchema } from "./graph/schema.js"; import { onExportGraphController, onFetchEmbeddingModelsController, @@ -204,7 +204,7 @@ import { onTestMemoryLLMController, onViewGraphController, onViewLastInjectionController, -} from "./ui-actions-controller.js"; +} from "./ui/ui-actions-controller.js"; import { clampInt, createBatchStatusSkeleton, @@ -226,7 +226,7 @@ import { pushBatchStageArtifact, setBatchStageOutcome, shouldRunRecallForTransaction, -} from "./ui-status.js"; +} from "./ui/ui-status.js"; import { deleteBackendVectorHashesForRecovery, fetchAvailableEmbeddingModels, @@ -237,7 +237,7 @@ import { syncGraphVectorIndex, testVectorConnection, validateVectorConfig, -} from "./vector-index.js"; +} from "./vector/vector-index.js"; // 操控面板模块(动态加载,防止加载失败崩溃整个扩展) let _panelModule = null; @@ -11330,8 +11330,8 @@ async function onReembedDirect() { getRuntimeStatus: () => getPanelRuntimeStatus(), getSettings, getThemesModule: () => _themesModule, - importPanelModule: async () => await import("./panel.js"), - importThemesModule: async () => await import("./themes.js"), + importPanelModule: async () => await import("./ui/panel.js"), + importThemesModule: async () => await import("./ui/themes.js"), setPanelModule: (module) => { _panelModule = module; }, diff --git a/llm-preset-utils.js b/llm/llm-preset-utils.js similarity index 100% rename from llm-preset-utils.js rename to llm/llm-preset-utils.js diff --git a/llm.js b/llm/llm.js similarity index 99% rename from llm.js rename to llm/llm.js index b51b5b8..46a13d4 100644 --- a/llm.js +++ b/llm/llm.js @@ -4,12 +4,12 @@ import { getRequestHeaders } from "../../../../script.js"; import { extension_settings } from "../../../extensions.js"; import { chat_completion_sources, sendOpenAIRequest } from "../../../openai.js"; -import { debugLog, debugWarn } from "./debug-logging.js"; -import { resolveTaskGenerationOptions } from "./generation-options.js"; +import { debugLog, debugWarn } from "../runtime/debug-logging.js"; +import { resolveTaskGenerationOptions } from "../runtime/generation-options.js"; import { resolveLlmConfigSelection } from "./llm-preset-utils.js"; -import { getActiveTaskProfile } from "./prompt-profiles.js"; -import { resolveConfiguredTimeoutMs } from "./request-timeout.js"; -import { applyTaskRegex } from "./task-regex.js"; +import { getActiveTaskProfile } from "../prompting/prompt-profiles.js"; +import { resolveConfiguredTimeoutMs } from "../runtime/request-timeout.js"; +import { applyTaskRegex } from "../prompting/task-regex.js"; const MODULE_NAME = "st_bme"; const LLM_REQUEST_TIMEOUT_MS = 300000; diff --git a/chat-history.js b/maintenance/chat-history.js similarity index 96% rename from chat-history.js rename to maintenance/chat-history.js index 161eed1..9ef3ab5 100644 --- a/chat-history.js +++ b/maintenance/chat-history.js @@ -2,10 +2,10 @@ // 此模块中的函数均不依赖 index.js 模块级可变状态, // 可被 index.js 及其他模块安全导入。 -import { clampInt } from "./ui-status.js"; -import { sanitizePlannerMessageText } from "./planner-tag-utils.js"; -import { rollbackBatch } from "./runtime-state.js"; -import { isInManagedHideRange } from "./hide-engine.js"; +import { clampInt } from "../ui/ui-status.js"; +import { sanitizePlannerMessageText } from "../runtime/planner-tag-utils.js"; +import { rollbackBatch } from "../runtime/runtime-state.js"; +import { isInManagedHideRange } from "../ui/hide-engine.js"; export function isBmeManagedHiddenMessage( message, diff --git a/compressor.js b/maintenance/compressor.js similarity index 97% rename from compressor.js rename to maintenance/compressor.js index 7b38afc..1d0be43 100644 --- a/compressor.js +++ b/maintenance/compressor.js @@ -1,8 +1,8 @@ // ST-BME: 层级压缩引擎 // 超过阈值的节点被 LLM 总结为更高层级的压缩节点 -import { debugLog } from "./debug-logging.js"; -import { embedText } from "./embedding.js"; +import { debugLog } from "../runtime/debug-logging.js"; +import { embedText } from "../vector/embedding.js"; import { addEdge, addNode, @@ -10,22 +10,22 @@ import { createNode, getActiveNodes, getNode, -} from "./graph.js"; -import { callLLMForJSON } from "./llm.js"; +} from "../graph/graph.js"; +import { callLLMForJSON } from "../llm/llm.js"; import { getScopeOwnerKey, getScopeRegionKey, normalizeMemoryScope, -} from "./memory-scope.js"; -import { ensureEventTitle, getNodeDisplayName } from "./node-labels.js"; +} from "../graph/memory-scope.js"; +import { ensureEventTitle, getNodeDisplayName } from "../graph/node-labels.js"; import { buildTaskExecutionDebugContext, buildTaskLlmPayload, buildTaskPrompt, -} from "./prompt-builder.js"; -import { getSTContextForPrompt } from "./st-context.js"; -import { applyTaskRegex } from "./task-regex.js"; -import { isDirectVectorConfig } from "./vector-index.js"; +} from "../prompting/prompt-builder.js"; +import { getSTContextForPrompt } from "../host/st-context.js"; +import { applyTaskRegex } from "../prompting/task-regex.js"; +import { isDirectVectorConfig } from "../vector/vector-index.js"; function createAbortError(message = "操作已终止") { const error = new Error(message); diff --git a/consolidator.js b/maintenance/consolidator.js similarity index 97% rename from consolidator.js rename to maintenance/consolidator.js index 48f58b1..532e8aa 100644 --- a/consolidator.js +++ b/maintenance/consolidator.js @@ -2,28 +2,28 @@ // 合并 Mem0 精确对照 + A-MEM 记忆进化为单一阶段 // 批量 embed + 批量查近邻 + 单次 LLM 调用 -import { debugLog } from "./debug-logging.js"; -import { embedBatch, searchSimilar } from "./embedding.js"; -import { addEdge, createEdge, getActiveNodes, getNode } from "./graph.js"; -import { callLLMForJSON } from "./llm.js"; +import { debugLog } from "../runtime/debug-logging.js"; +import { embedBatch, searchSimilar } from "../vector/embedding.js"; +import { addEdge, createEdge, getActiveNodes, getNode } from "../graph/graph.js"; +import { callLLMForJSON } from "../llm/llm.js"; import { buildScopeBadgeText, canMergeScopedMemories, describeMemoryScope, -} from "./memory-scope.js"; +} from "../graph/memory-scope.js"; import { buildTaskExecutionDebugContext, buildTaskLlmPayload, buildTaskPrompt, -} from "./prompt-builder.js"; -import { getSTContextForPrompt } from "./st-context.js"; -import { applyTaskRegex } from "./task-regex.js"; +} from "../prompting/prompt-builder.js"; +import { getSTContextForPrompt } from "../host/st-context.js"; +import { applyTaskRegex } from "../prompting/task-regex.js"; import { buildNodeVectorText, findSimilarNodesByText, isDirectVectorConfig, validateVectorConfig, -} from "./vector-index.js"; +} from "../vector/vector-index.js"; function createAbortError(message = "操作已终止") { const error = new Error(message); diff --git a/extraction-controller.js b/maintenance/extraction-controller.js similarity index 99% rename from extraction-controller.js rename to maintenance/extraction-controller.js index e199b94..08fbe4d 100644 --- a/extraction-controller.js +++ b/maintenance/extraction-controller.js @@ -1,7 +1,7 @@ // ST-BME: 提取编排控制器(纯函数) // 通过 runtime 依赖注入,避免直接访问 index.js 模块级状态。 -import { debugLog } from "./debug-logging.js"; +import { debugLog } from "../runtime/debug-logging.js"; function toSafeFloor(value, fallback = null) { if (value == null || value === "") return fallback; diff --git a/extractor.js b/maintenance/extractor.js similarity index 98% rename from extractor.js rename to maintenance/extractor.js index f0d9b35..dc65e78 100644 --- a/extractor.js +++ b/maintenance/extractor.js @@ -2,8 +2,8 @@ // 分析对话 → 提取节点和关系 → 更新图谱 // v2: 融合 Mem0 精确对照 + Graphiti 时序边 + MemoRAG 全局概要 -import { embedBatch } from "./embedding.js"; -import { debugLog, debugWarn } from "./debug-logging.js"; +import { embedBatch } from "../vector/embedding.js"; +import { debugLog, debugWarn } from "../runtime/debug-logging.js"; import { addEdge, addNode, @@ -14,22 +14,22 @@ import { getNode, invalidateEdge, updateNode, -} from "./graph.js"; -import { callLLMForJSON } from "./llm.js"; -import { ensureEventTitle, getNodeDisplayName } from "./node-labels.js"; +} from "../graph/graph.js"; +import { callLLMForJSON } from "../llm/llm.js"; +import { ensureEventTitle, getNodeDisplayName } from "../graph/node-labels.js"; import { normalizeMemoryScope, isObjectiveScope, -} from "./memory-scope.js"; +} from "../graph/memory-scope.js"; import { buildTaskExecutionDebugContext, buildTaskLlmPayload, buildTaskPrompt, -} from "./prompt-builder.js"; -import { RELATION_TYPES } from "./schema.js"; -import { applyTaskRegex } from "./task-regex.js"; -import { getSTContextForPrompt, getSTContextSnapshot } from "./st-context.js"; -import { buildNodeVectorText, isDirectVectorConfig } from "./vector-index.js"; +} from "../prompting/prompt-builder.js"; +import { RELATION_TYPES } from "../graph/schema.js"; +import { applyTaskRegex } from "../prompting/task-regex.js"; +import { getSTContextForPrompt, getSTContextSnapshot } from "../host/st-context.js"; +import { buildNodeVectorText, isDirectVectorConfig } from "../vector/vector-index.js"; function createAbortError(message = "操作已终止") { const error = new Error(message); diff --git a/package.json b/package.json index a5a5143..50632f2 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,15 @@ "test:runtime-history": "node tests/runtime-history.mjs", "test:graph-persistence": "node tests/graph-persistence.mjs", "test:hide-engine": "node tests/hide-engine.mjs", + "test:maintenance-journal": "node tests/maintenance-journal.mjs", "test:indexeddb-persistence": "node tests/indexeddb-persistence.mjs", "test:indexeddb-sync": "node tests/indexeddb-sync.mjs", "test:indexeddb-migration": "node tests/indexeddb-migration.mjs", "test:trivial-input": "node tests/trivial-user-input.mjs", "test:indexeddb": "npm run test:indexeddb-persistence && npm run test:indexeddb-sync && npm run test:indexeddb-migration", "test:persistence-matrix": "npm run test:p0 && npm run test:runtime-history && npm run test:graph-persistence && npm run test:indexeddb", - "test:all": "npm run test:persistence-matrix && npm run test:trivial-input", - "check": "node --check index.js && node --check bme-db.js && node --check hide-engine.js && node --check panel.js && node --check ui-status.js && node --check event-binding.js" + "test:all": "npm run test:persistence-matrix && npm run test:maintenance-journal && npm run test:trivial-input", + "check": "node --check index.js && node --check sync/bme-db.js && node --check ui/hide-engine.js && node --check ui/panel.js && node --check ui/ui-status.js && node --check host/event-binding.js" }, "dependencies": { "triviumdb": "^0.4.41" diff --git a/default-task-profile-templates.js b/prompting/default-task-profile-templates.js similarity index 100% rename from default-task-profile-templates.js rename to prompting/default-task-profile-templates.js diff --git a/injection-sanitizer.js b/prompting/injection-sanitizer.js similarity index 100% rename from injection-sanitizer.js rename to prompting/injection-sanitizer.js diff --git a/mvu-compat.js b/prompting/mvu-compat.js similarity index 100% rename from mvu-compat.js rename to prompting/mvu-compat.js diff --git a/prompt-builder.js b/prompting/prompt-builder.js similarity index 99% rename from prompt-builder.js rename to prompting/prompt-builder.js index 4f2eb96..9a0e6da 100644 --- a/prompt-builder.js +++ b/prompting/prompt-builder.js @@ -1,7 +1,7 @@ // ST-BME: Prompt Builder // 统一负责任务预设块排序、变量渲染,以及世界书/EJS 上下文接入。 -import { debugLog, debugWarn } from "./debug-logging.js"; +import { debugLog, debugWarn } from "../runtime/debug-logging.js"; import { getActiveTaskProfile, getLegacyPromptForTask } from "./prompt-profiles.js"; import { createEmptyInjectionSanitizerDebug, diff --git a/prompt-profiles.js b/prompting/prompt-profiles.js similarity index 100% rename from prompt-profiles.js rename to prompting/prompt-profiles.js diff --git a/task-ejs.js b/prompting/task-ejs.js similarity index 99% rename from task-ejs.js rename to prompting/task-ejs.js index 75d4896..312468f 100644 --- a/task-ejs.js +++ b/prompting/task-ejs.js @@ -1,7 +1,7 @@ // ST-BME: 任务级 EJS / 世界书渲染引擎 // 仅用于世界书条目渲染,不开放给用户自定义 prompt 块。 -import { getSTContextSnapshot } from "./st-context.js"; +import { getSTContextSnapshot } from "../host/st-context.js"; const DEFAULT_MAX_RECURSION = 10; let ejsRuntimeStatePromise = null; @@ -89,10 +89,10 @@ async function ensureEjsRuntime() { } try { - await import("./vendor/ejs.js"); + await import("../vendor/ejs.js"); } catch (error) { importError = error; - console.warn("[ST-BME] task-ejs 加载 vendor/ejs.js 失败:", error); + console.warn("[ST-BME] task-ejs 加载 ../vendor/ejs.js 失败:", error); } finally { if (!hadWindow) { delete globalThis.window; diff --git a/task-regex.js b/prompting/task-regex.js similarity index 99% rename from task-regex.js rename to prompting/task-regex.js index 9a5d03f..0b58193 100644 --- a/task-regex.js +++ b/prompting/task-regex.js @@ -3,8 +3,8 @@ // 同时叠加任务本地规则,并按任务阶段执行。 import { extension_settings, getContext } from "../../../extensions.js"; -import { debugDebug } from "./debug-logging.js"; -import { getHostAdapter } from "./host-adapter/index.js"; +import { debugDebug } from "../runtime/debug-logging.js"; +import { getHostAdapter } from "../host/adapter/index.js"; import { getActiveTaskProfile, isTaskRegexStageEnabled, diff --git a/task-worldinfo.js b/prompting/task-worldinfo.js similarity index 99% rename from task-worldinfo.js rename to prompting/task-worldinfo.js index b8482fd..71d9dfc 100644 --- a/task-worldinfo.js +++ b/prompting/task-worldinfo.js @@ -12,13 +12,13 @@ import { getLatestMessageVarTable, prepareStNativeEjsEnv, renderTemplateWithStSupport, -} from "./st-native-render.js"; +} from "../host/st-native-render.js"; import { isLikelyMvuWorldInfoContent, isMvuTaggedWorldInfoNameOrComment, sanitizeMvuContent, } from "./mvu-compat.js"; -import { debugDebug } from "./debug-logging.js"; +import { debugDebug } from "../runtime/debug-logging.js"; const WI_POSITION = { before: 0, @@ -320,7 +320,7 @@ async function getWorldbookHost() { ); try { - const { getHostAdapter } = await import("./host-adapter/index.js"); + const { getHostAdapter } = await import("../host/adapter/index.js"); const adapter = getHostAdapter?.() || null; const adapterSnapshot = adapter?.getSnapshot?.() || null; const worldbookHost = adapter?.worldbook || null; diff --git a/diffusion.js b/retrieval/diffusion.js similarity index 100% rename from diffusion.js rename to retrieval/diffusion.js diff --git a/dynamics.js b/retrieval/dynamics.js similarity index 100% rename from dynamics.js rename to retrieval/dynamics.js diff --git a/injector.js b/retrieval/injector.js similarity index 98% rename from injector.js rename to retrieval/injector.js index 9c59109..3d14ea1 100644 --- a/injector.js +++ b/retrieval/injector.js @@ -1,8 +1,8 @@ // ST-BME: Prompt 注入模块 // 将检索结果格式化为表格注入到 LLM 上下文中 -import { getSchemaType } from "./schema.js"; -import { normalizeMemoryScope } from "./memory-scope.js"; +import { getSchemaType } from "../graph/schema.js"; +import { normalizeMemoryScope } from "../graph/memory-scope.js"; /** * 将检索结果转换为注入文本 diff --git a/recall-controller.js b/retrieval/recall-controller.js similarity index 99% rename from recall-controller.js rename to retrieval/recall-controller.js index 8a74407..c2f190c 100644 --- a/recall-controller.js +++ b/retrieval/recall-controller.js @@ -1,6 +1,6 @@ // ST-BME: 召回输入解析与注入控制器(纯函数) -import { debugLog } from "./debug-logging.js"; +import { debugLog } from "../runtime/debug-logging.js"; export function buildRecallRecentMessagesController( chat, diff --git a/recall-persistence.js b/retrieval/recall-persistence.js similarity index 100% rename from recall-persistence.js rename to retrieval/recall-persistence.js diff --git a/retrieval-enhancer.js b/retrieval/retrieval-enhancer.js similarity index 99% rename from retrieval-enhancer.js rename to retrieval/retrieval-enhancer.js index c8878f8..4e34356 100644 --- a/retrieval-enhancer.js +++ b/retrieval/retrieval-enhancer.js @@ -1,6 +1,6 @@ -import { embedText, searchSimilar } from "./embedding.js"; -import { getNode } from "./graph.js"; -import { isDirectVectorConfig } from "./vector-index.js"; +import { embedText, searchSimilar } from "../vector/embedding.js"; +import { getNode } from "../graph/graph.js"; +import { isDirectVectorConfig } from "../vector/vector-index.js"; const COOCCURRENCE_EXCLUDED_TYPES = new Set([ "event", diff --git a/retriever.js b/retrieval/retriever.js similarity index 99% rename from retriever.js rename to retrieval/retriever.js index f761cb5..4797c65 100644 --- a/retriever.js +++ b/retrieval/retriever.js @@ -2,7 +2,7 @@ // 融合向量预筛(PeroCore)+ 图扩散(PeroCore PEDSA)+ 可选 LLM 精确召回 // v2: + 认知边界过滤(RoleRAG) + 双记忆交叉检索(AriGraph) + 概率触发 -import { debugLog } from "./debug-logging.js"; +import { debugLog } from "../runtime/debug-logging.js"; import { diffuseAndRank } from "./diffusion.js"; import { hybridScore, reinforceAccessBatch } from "./dynamics.js"; import { @@ -10,13 +10,13 @@ import { getActiveNodes, getNode, getNodeEdges, -} from "./graph.js"; -import { callLLMForJSON } from "./llm.js"; +} from "../graph/graph.js"; +import { callLLMForJSON } from "../llm/llm.js"; import { buildTaskExecutionDebugContext, buildTaskLlmPayload, buildTaskPrompt, -} from "./prompt-builder.js"; +} from "../prompting/prompt-builder.js"; import { applyCooccurrenceBoost, applyDiversitySampling, @@ -35,10 +35,10 @@ import { getScopeRegionKey, normalizeMemoryScope, resolveScopeBucketWeight, -} from "./memory-scope.js"; -import { applyTaskRegex } from "./task-regex.js"; -import { getSTContextForPrompt } from "./st-context.js"; -import { findSimilarNodesByText, validateVectorConfig } from "./vector-index.js"; +} from "../graph/memory-scope.js"; +import { applyTaskRegex } from "../prompting/task-regex.js"; +import { getSTContextForPrompt } from "../host/st-context.js"; +import { findSimilarNodesByText, validateVectorConfig } from "../vector/vector-index.js"; function createAbortError(message = "操作已终止") { const error = new Error(message); diff --git a/debug-logging.js b/runtime/debug-logging.js similarity index 100% rename from debug-logging.js rename to runtime/debug-logging.js diff --git a/generation-options.js b/runtime/generation-options.js similarity index 98% rename from generation-options.js rename to runtime/generation-options.js index 835e40a..7ab50e4 100644 --- a/generation-options.js +++ b/runtime/generation-options.js @@ -1,6 +1,6 @@ // ST-BME: 任务级生成参数过滤层(Phase 1) -import { getActiveTaskProfile } from "./prompt-profiles.js"; +import { getActiveTaskProfile } from "../prompting/prompt-profiles.js"; const SUPPORTED_FIELDS = [ "max_context_tokens", diff --git a/planner-tag-utils.js b/runtime/planner-tag-utils.js similarity index 100% rename from planner-tag-utils.js rename to runtime/planner-tag-utils.js diff --git a/request-timeout.js b/runtime/request-timeout.js similarity index 100% rename from request-timeout.js rename to runtime/request-timeout.js diff --git a/runtime-debug.js b/runtime/runtime-debug.js similarity index 100% rename from runtime-debug.js rename to runtime/runtime-debug.js diff --git a/runtime-state.js b/runtime/runtime-state.js similarity index 97% rename from runtime-state.js rename to runtime/runtime-state.js index 61bbbdf..b30fe85 100644 --- a/runtime-state.js +++ b/runtime/runtime-state.js @@ -2,7 +2,7 @@ import { normalizeEdgeMemoryScope, normalizeNodeMemoryScope, -} from "./memory-scope.js"; +} from "../graph/memory-scope.js"; const BATCH_JOURNAL_LIMIT = 96; const MAINTENANCE_JOURNAL_LIMIT = 20; @@ -700,10 +700,25 @@ export function createMaintenanceJournalEntry( snapshotAfter, meta = {}, ) { - const beforeNodes = buildNodeMap(snapshotBefore?.nodes || []); - const afterNodes = buildNodeMap(snapshotAfter?.nodes || []); - const beforeEdges = buildEdgeMap(snapshotBefore?.edges || []); - const afterEdges = buildEdgeMap(snapshotAfter?.edges || []); + const normalizedChatId = String( + meta.chatId || + snapshotAfter?.historyState?.chatId || + snapshotBefore?.historyState?.chatId || + "", + ).trim(); + const normalizedBefore = normalizeGraphRuntimeState( + cloneGraphSnapshot(snapshotBefore || { nodes: [], edges: [] }), + normalizedChatId, + ); + const normalizedAfter = normalizeGraphRuntimeState( + cloneGraphSnapshot(snapshotAfter || { nodes: [], edges: [] }), + normalizedChatId, + ); + + const beforeNodes = buildNodeMap(normalizedBefore?.nodes || []); + const afterNodes = buildNodeMap(normalizedAfter?.nodes || []); + const beforeEdges = buildEdgeMap(normalizedBefore?.edges || []); + const afterEdges = buildEdgeMap(normalizedAfter?.edges || []); const restoreNodes = []; const restoreEdges = []; diff --git a/bme-chat-manager.js b/sync/bme-chat-manager.js similarity index 100% rename from bme-chat-manager.js rename to sync/bme-chat-manager.js diff --git a/bme-db.js b/sync/bme-db.js similarity index 99% rename from bme-db.js rename to sync/bme-db.js index c36b534..456010e 100644 --- a/bme-db.js +++ b/sync/bme-db.js @@ -1,12 +1,12 @@ -import { createEmptyGraph, deserializeGraph } from "./graph.js"; +import { createEmptyGraph, deserializeGraph } from "../graph/graph.js"; import { buildVectorCollectionId, normalizeGraphRuntimeState, -} from "./runtime-state.js"; +} from "../runtime/runtime-state.js"; const DEXIE_LOAD_PROMISE_KEY = "__stBmeDexieLoadPromise"; const DEXIE_SCRIPT_MARKER = "data-st-bme-dexie"; -const DEXIE_SCRIPT_SOURCE = "./lib/dexie.min.js"; +const DEXIE_SCRIPT_SOURCE = "../lib/dexie.min.js"; const META_DEFAULT_LAST_PROCESSED_FLOOR = -1; const META_DEFAULT_EXTRACTION_COUNT = 0; diff --git a/bme-sync.js b/sync/bme-sync.js similarity index 99% rename from bme-sync.js rename to sync/bme-sync.js index d6f5585..75ff3b7 100644 --- a/bme-sync.js +++ b/sync/bme-sync.js @@ -1,4 +1,4 @@ -import { PROCESSED_MESSAGE_HASH_VERSION } from "./runtime-state.js"; +import { PROCESSED_MESSAGE_HASH_VERSION } from "../runtime/runtime-state.js"; const BME_SYNC_FILE_PREFIX = "ST-BME_sync_"; const BME_SYNC_FILE_SUFFIX = ".json"; diff --git a/tests/chat-history.mjs b/tests/chat-history.mjs index 7a06920..9f565fd 100644 --- a/tests/chat-history.mjs +++ b/tests/chat-history.mjs @@ -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, diff --git a/tests/generation-options-filter.mjs b/tests/generation-options-filter.mjs index a48fa5a..f7b786f 100644 --- a/tests/generation-options-filter.mjs +++ b/tests/generation-options-filter.mjs @@ -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(); diff --git a/tests/graph-persistence.mjs b/tests/graph-persistence.mjs index 39c5d2d..2cfb247 100644 --- a/tests/graph-persistence.mjs +++ b/tests/graph-persistence.mjs @@ -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, diff --git a/tests/graph-retrieval.mjs b/tests/graph-retrieval.mjs index 6dc04b7..7b852b3 100644 --- a/tests/graph-retrieval.mjs +++ b/tests/graph-retrieval.mjs @@ -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(); diff --git a/tests/helpers/generation-recall-harness.mjs b/tests/helpers/generation-recall-harness.mjs index 5989781..a2eaad2 100644 --- a/tests/helpers/generation-recall-harness.mjs +++ b/tests/helpers/generation-recall-harness.mjs @@ -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"); diff --git a/tests/hide-engine.mjs b/tests/hide-engine.mjs index 33745f9..229f6c5 100644 --- a/tests/hide-engine.mjs +++ b/tests/hide-engine.mjs @@ -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 = []; diff --git a/tests/indexeddb-migration.mjs b/tests/indexeddb-migration.mjs index 2ecc184..2e1d46d 100644 --- a/tests/indexeddb-migration.mjs +++ b/tests/indexeddb-migration.mjs @@ -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]"; diff --git a/tests/indexeddb-persistence.mjs b/tests/indexeddb-persistence.mjs index 8cf4780..2346a60 100644 --- a/tests/indexeddb-persistence.mjs +++ b/tests/indexeddb-persistence.mjs @@ -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]"; diff --git a/tests/indexeddb-sync.mjs b/tests/indexeddb-sync.mjs index 1073aaf..b03a6d5 100644 --- a/tests/indexeddb-sync.mjs +++ b/tests/indexeddb-sync.mjs @@ -14,7 +14,7 @@ import { scheduleUpload, syncNow, upload, -} from "../bme-sync.js"; +} from "../sync/bme-sync.js"; const PREFIX = "[ST-BME][indexeddb-sync]"; diff --git a/tests/injector-format.mjs b/tests/injector-format.mjs index dfa002e..20cd036 100644 --- a/tests/injector-format.mjs +++ b/tests/injector-format.mjs @@ -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", diff --git a/tests/llm-model-fetch.mjs b/tests/llm-model-fetch.mjs index a0cdda7..f8d9fcf 100644 --- a/tests/llm-model-fetch.mjs +++ b/tests/llm-model-fetch.mjs @@ -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) { diff --git a/tests/llm-preset-utils.mjs b/tests/llm-preset-utils.mjs index 7d5f3c1..8ad92ea 100644 --- a/tests/llm-preset-utils.mjs +++ b/tests/llm-preset-utils.mjs @@ -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 ", diff --git a/tests/llm-streaming.mjs b/tests/llm-streaming.mjs index 55d705e..b96215e 100644 --- a/tests/llm-streaming.mjs +++ b/tests/llm-streaming.mjs @@ -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) { diff --git a/tests/maintenance-journal.mjs b/tests/maintenance-journal.mjs index ed01b85..9986aad 100644 --- a/tests/maintenance-journal.mjs +++ b/tests/maintenance-journal.mjs @@ -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)); diff --git a/tests/mobile-status-regressions.mjs b/tests/mobile-status-regressions.mjs index 20374d6..1748bae 100644 --- a/tests/mobile-status-regressions.mjs +++ b/tests/mobile-status-regressions.mjs @@ -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"); diff --git a/tests/mvu-compat.mjs b/tests/mvu-compat.mjs index 68819d6..564221d 100644 --- a/tests/mvu-compat.mjs +++ b/tests/mvu-compat.mjs @@ -4,7 +4,7 @@ const { isLikelyMvuWorldInfoContent, isMvuTaggedWorldInfoNameOrComment, sanitizeMvuContent, -} = await import("../mvu-compat.js"); +} = await import("../prompting/mvu-compat.js"); assert.equal( isMvuTaggedWorldInfoNameOrComment("[mvu_update] 状态", ""), diff --git a/tests/p0-regressions.mjs b/tests/p0-regressions.mjs index 2faa430..bdea718 100644 --- a/tests/p0-regressions.mjs +++ b/tests/p0-regressions.mjs @@ -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: [ diff --git a/tests/prompt-builder-defaults.mjs b/tests/prompt-builder-defaults.mjs index 6fa9120..49f3331 100644 --- a/tests/prompt-builder-defaults.mjs +++ b/tests/prompt-builder-defaults.mjs @@ -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, diff --git a/tests/prompt-builder-mvu.mjs b/tests/prompt-builder-mvu.mjs index 45d54aa..369b97a 100644 --- a/tests/prompt-builder-mvu.mjs +++ b/tests/prompt-builder-mvu.mjs @@ -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 { diff --git a/tests/retrieval-config.mjs b/tests/retrieval-config.mjs index ec36163..8f1a342 100644 --- a/tests/retrieval-config.mjs +++ b/tests/retrieval-config.mjs @@ -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); diff --git a/tests/retrieval-enhancer.mjs b/tests/retrieval-enhancer.mjs index 5b5e54a..f04c974 100644 --- a/tests/retrieval-enhancer.mjs +++ b/tests/retrieval-enhancer.mjs @@ -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, "") diff --git a/tests/runtime-history.mjs b/tests/runtime-history.mjs index 529ffc7..e361047 100644 --- a/tests/runtime-history.mjs +++ b/tests/runtime-history.mjs @@ -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: "你好" }, diff --git a/tests/scoped-memory.mjs b/tests/scoped-memory.mjs index abd36bc..63792e2 100644 --- a/tests/scoped-memory.mjs +++ b/tests/scoped-memory.mjs @@ -7,7 +7,7 @@ import { deserializeGraph, findLatestNode, serializeGraph, -} from "../graph.js"; +} from "../graph/graph.js"; const graph = createEmptyGraph(); const objectiveNode = createNode({ diff --git a/tests/st-context-task-ejs.mjs b/tests/st-context-task-ejs.mjs index e861ddc..5b66ebf 100644 --- a/tests/st-context-task-ejs.mjs +++ b/tests/st-context-task-ejs.mjs @@ -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, { diff --git a/tests/task-profile-migration.mjs b/tests/task-profile-migration.mjs index 5b61614..5aaac34 100644 --- a/tests/task-profile-migration.mjs +++ b/tests/task-profile-migration.mjs @@ -4,7 +4,7 @@ import { ensureTaskProfiles, getActiveTaskProfile, migrateLegacyTaskProfiles, -} from "../prompt-profiles.js"; +} from "../prompting/prompt-profiles.js"; const legacySettings = { extractPrompt: "旧提取提示", diff --git a/tests/task-profile-storage.mjs b/tests/task-profile-storage.mjs index 58bad98..b392f3e 100644 --- a/tests/task-profile-storage.mjs +++ b/tests/task-profile-storage.mjs @@ -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]; diff --git a/tests/task-regex.mjs b/tests/task-regex.mjs index c95793c..77a2e92 100644 --- a/tests/task-regex.mjs +++ b/tests/task-regex.mjs @@ -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 diff --git a/tests/task-worldinfo.mjs b/tests/task-worldinfo.mjs index ee5054d..4d2ee92 100644 --- a/tests/task-worldinfo.mjs +++ b/tests/task-worldinfo.mjs @@ -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 diff --git a/tests/trivial-user-input.mjs b/tests/trivial-user-input.mjs index 3ce7c74..658099e 100644 --- a/tests/trivial-user-input.mjs +++ b/tests/trivial-user-input.mjs @@ -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() { diff --git a/tests/vector-config.mjs b/tests/vector-config.mjs index 16c4648..f3e077e 100644 --- a/tests/vector-config.mjs +++ b/tests/vector-config.mjs @@ -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 = [ diff --git a/graph-renderer.js b/ui/graph-renderer.js similarity index 99% rename from graph-renderer.js rename to ui/graph-renderer.js index 12f4f61..ef381a3 100644 --- a/graph-renderer.js +++ b/ui/graph-renderer.js @@ -2,8 +2,8 @@ // 零依赖:客观层 / 角色 POV / 用户 POV 分区内 Vogel 初值 + 一次性力导向稳定,无帧循环抖动 import { getNodeColors } from './themes.js'; -import { getGraphNodeLabel, getNodeDisplayName } from './node-labels.js'; -import { normalizeMemoryScope } from './memory-scope.js'; +import { getGraphNodeLabel, getNodeDisplayName } from '../graph/node-labels.js'; +import { normalizeMemoryScope } from '../graph/memory-scope.js'; /** * @typedef {Object} GraphNode diff --git a/hide-engine.js b/ui/hide-engine.js similarity index 100% rename from hide-engine.js rename to ui/hide-engine.js diff --git a/notice.js b/ui/notice.js similarity index 100% rename from notice.js rename to ui/notice.js diff --git a/panel-bridge.js b/ui/panel-bridge.js similarity index 98% rename from panel-bridge.js rename to ui/panel-bridge.js index 78de4a1..4408176 100644 --- a/panel-bridge.js +++ b/ui/panel-bridge.js @@ -1,4 +1,4 @@ -import { debugLog } from "./debug-logging.js"; +import { debugLog } from "../runtime/debug-logging.js"; function resolvePanelTheme(settings) { return settings?.panelTheme || "crimson"; diff --git a/panel.html b/ui/panel.html similarity index 100% rename from panel.html rename to ui/panel.html diff --git a/panel.js b/ui/panel.js similarity index 99% rename from panel.js rename to ui/panel.js index 6e90da6..3c7b1ee 100644 --- a/panel.js +++ b/ui/panel.js @@ -4,16 +4,16 @@ import { callGenericPopup, POPUP_TYPE } from "../../../popup.js"; import { getContext } from "../../../extensions.js"; import { renderTemplateAsync } from "../../../templates.js"; import { GraphRenderer } from "./graph-renderer.js"; -import { getNodeDisplayName } from "./node-labels.js"; +import { getNodeDisplayName } from "../graph/node-labels.js"; import { buildRegionLine, buildScopeBadgeText, normalizeMemoryScope, -} from "./memory-scope.js"; +} from "../graph/memory-scope.js"; import { resolveActiveLlmPresetName, sanitizeLlmPresetSettings, -} from "./llm-preset-utils.js"; +} from "../llm/llm-preset-utils.js"; import { cloneTaskProfile, createBuiltinPromptBlock, @@ -31,12 +31,12 @@ import { restoreDefaultTaskProfile, setActiveTaskProfileId, upsertTaskProfile, -} from "./prompt-profiles.js"; +} from "../prompting/prompt-profiles.js"; import { getNodeColors } from "./themes.js"; import { getSuggestedBackendModel, getVectorIndexStats, -} from "./vector-index.js"; +} from "../vector/vector-index.js"; let defaultPromptCache = null; @@ -1205,7 +1205,7 @@ async function _refreshInjectionPreview() { } try { - const { estimateTokens } = await import("./injector.js"); + const { estimateTokens } = await import("../retrieval/injector.js"); const totalTokens = estimateTokens(injection); const preview = _buildInjectionPreviewNode(injection); container.replaceChildren(preview); diff --git a/recall-message-ui.js b/ui/recall-message-ui.js similarity index 100% rename from recall-message-ui.js rename to ui/recall-message-ui.js diff --git a/themes.js b/ui/themes.js similarity index 100% rename from themes.js rename to ui/themes.js diff --git a/ui-actions-controller.js b/ui/ui-actions-controller.js similarity index 100% rename from ui-actions-controller.js rename to ui/ui-actions-controller.js diff --git a/ui-status.js b/ui/ui-status.js similarity index 99% rename from ui-status.js rename to ui/ui-status.js index aca4616..24b6742 100644 --- a/ui-status.js +++ b/ui/ui-status.js @@ -1,7 +1,7 @@ // ST-BME: UI 状态工厂、纯工具函数 // 此模块中的函数均不依赖 index.js 模块级可变状态, // 可被 index.js 及其他模块安全导入。 -import { sanitizePlannerMessageText } from "./planner-tag-utils.js"; +import { sanitizePlannerMessageText } from "../runtime/planner-tag-utils.js"; // ═══════════════════════════════════════════════════════════ // 常量 diff --git a/embedding.js b/vector/embedding.js similarity index 99% rename from embedding.js rename to vector/embedding.js index 1a41f59..f09de68 100644 --- a/embedding.js +++ b/vector/embedding.js @@ -7,7 +7,7 @@ */ import { extension_settings } from "../../../extensions.js"; -import { resolveConfiguredTimeoutMs } from "./request-timeout.js"; +import { resolveConfiguredTimeoutMs } from "../runtime/request-timeout.js"; const MODULE_NAME = "st_bme"; const EMBEDDING_REQUEST_TIMEOUT_MS = 300000; diff --git a/vector-index.js b/vector/vector-index.js similarity index 98% rename from vector-index.js rename to vector/vector-index.js index a68ffef..dd98736 100644 --- a/vector-index.js +++ b/vector/vector-index.js @@ -2,10 +2,10 @@ import { getRequestHeaders } from "../../../../script.js"; import { embedBatch, embedText, searchSimilar } from "./embedding.js"; -import { getActiveNodes } from "./graph.js"; -import { describeMemoryScope, normalizeMemoryScope } from "./memory-scope.js"; -import { resolveConfiguredTimeoutMs } from "./request-timeout.js"; -import { buildVectorCollectionId, stableHashString } from "./runtime-state.js"; +import { getActiveNodes } from "../graph/graph.js"; +import { describeMemoryScope, normalizeMemoryScope } from "../graph/memory-scope.js"; +import { resolveConfiguredTimeoutMs } from "../runtime/request-timeout.js"; +import { buildVectorCollectionId, stableHashString } from "../runtime/runtime-state.js"; export const BACKEND_VECTOR_SOURCES = [ "openai",