@downcity/agent 1.1.6 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/agent/AgentContext.d.ts.map +1 -1
- package/bin/agent/AgentContext.js +1 -0
- package/bin/agent/AgentContext.js.map +1 -1
- package/bin/agent/AgentContextTypes.d.ts +5 -1
- package/bin/agent/AgentContextTypes.d.ts.map +1 -1
- package/bin/agent/AgentRuntime.d.ts +6 -1
- package/bin/agent/AgentRuntime.d.ts.map +1 -1
- package/bin/agent/AgentRuntime.js +22 -3
- package/bin/agent/AgentRuntime.js.map +1 -1
- package/bin/agent/AgentRuntimeState.d.ts.map +1 -1
- package/bin/agent/AgentRuntimeState.js +58 -2
- package/bin/agent/AgentRuntimeState.js.map +1 -1
- package/bin/agent/AgentRuntimeTypes.d.ts +5 -1
- package/bin/agent/AgentRuntimeTypes.d.ts.map +1 -1
- package/bin/agent/project/AgentInitializer.d.ts +3 -2
- package/bin/agent/project/AgentInitializer.d.ts.map +1 -1
- package/bin/agent/project/AgentInitializer.js +34 -44
- package/bin/agent/project/AgentInitializer.js.map +1 -1
- package/bin/config/Config.d.ts.map +1 -1
- package/bin/config/Config.js +2 -21
- package/bin/config/Config.js.map +1 -1
- package/bin/config/Paths.d.ts +1 -5
- package/bin/config/Paths.d.ts.map +1 -1
- package/bin/config/Paths.js +2 -8
- package/bin/config/Paths.js.map +1 -1
- package/bin/host/daemon/ProjectSetup.d.ts +2 -1
- package/bin/host/daemon/ProjectSetup.d.ts.map +1 -1
- package/bin/host/daemon/ProjectSetup.js +14 -21
- package/bin/host/daemon/ProjectSetup.js.map +1 -1
- package/bin/host/runtime/AgentHostRuntime.d.ts.map +1 -1
- package/bin/host/runtime/AgentHostRuntime.js +1 -2
- package/bin/host/runtime/AgentHostRuntime.js.map +1 -1
- package/bin/host/runtime/CityPaths.d.ts +0 -3
- package/bin/host/runtime/CityPaths.d.ts.map +1 -1
- package/bin/host/runtime/CityPaths.js +0 -3
- package/bin/host/runtime/CityPaths.js.map +1 -1
- package/bin/host/sdk/Agent.d.ts +4 -0
- package/bin/host/sdk/Agent.d.ts.map +1 -1
- package/bin/host/sdk/Agent.js +71 -2
- package/bin/host/sdk/Agent.js.map +1 -1
- package/bin/host/sdk/AgentSdkTypes.d.ts +9 -0
- package/bin/host/sdk/AgentSdkTypes.d.ts.map +1 -1
- package/bin/host/sdk/SdkSessionSystemComposer.d.ts +11 -2
- package/bin/host/sdk/SdkSessionSystemComposer.d.ts.map +1 -1
- package/bin/host/sdk/SdkSessionSystemComposer.js +19 -2
- package/bin/host/sdk/SdkSessionSystemComposer.js.map +1 -1
- package/bin/host/sdk/Session.d.ts +10 -0
- package/bin/host/sdk/Session.d.ts.map +1 -1
- package/bin/host/sdk/Session.js +8 -0
- package/bin/host/sdk/Session.js.map +1 -1
- package/bin/http/Server.d.ts.map +1 -1
- package/bin/http/Server.js +1 -11
- package/bin/http/Server.js.map +1 -1
- package/bin/http/auth/AuthEnv.d.ts +0 -9
- package/bin/http/auth/AuthEnv.d.ts.map +1 -1
- package/bin/http/auth/AuthEnv.js +0 -9
- package/bin/http/auth/AuthEnv.js.map +1 -1
- package/bin/http/auth/CliAuthStateStore.d.ts +0 -4
- package/bin/http/auth/CliAuthStateStore.d.ts.map +1 -1
- package/bin/http/auth/CliAuthStateStore.js +0 -4
- package/bin/http/auth/CliAuthStateStore.js.map +1 -1
- package/bin/http/control/ModelRoutes.d.ts.map +1 -1
- package/bin/http/control/ModelRoutes.js +3 -8
- package/bin/http/control/ModelRoutes.js.map +1 -1
- package/bin/index.d.ts +2 -6
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +2 -6
- package/bin/index.js.map +1 -1
- package/bin/model/CreateModel.d.ts +2 -2
- package/bin/model/CreateModel.d.ts.map +1 -1
- package/bin/model/CreateModel.js +13 -12
- package/bin/model/CreateModel.js.map +1 -1
- package/bin/plugin/Activation.d.ts +4 -0
- package/bin/plugin/Activation.d.ts.map +1 -1
- package/bin/plugin/Activation.js +2 -2
- package/bin/plugin/Activation.js.map +1 -1
- package/bin/plugin/LocalExecution.d.ts.map +1 -1
- package/bin/plugin/LocalExecution.js +23 -2
- package/bin/plugin/LocalExecution.js.map +1 -1
- package/bin/plugin/PluginRegistry.js +2 -2
- package/bin/plugin/PluginRegistry.js.map +1 -1
- package/bin/plugins/asr/Plugin.d.ts.map +1 -1
- package/bin/plugins/asr/Plugin.js +4 -5
- package/bin/plugins/asr/Plugin.js.map +1 -1
- package/bin/plugins/auth/Plugin.d.ts.map +1 -1
- package/bin/plugins/auth/Plugin.js +1 -0
- package/bin/plugins/auth/Plugin.js.map +1 -1
- package/bin/plugins/auth/runtime/AuthorizationConfig.d.ts +4 -4
- package/bin/plugins/auth/runtime/AuthorizationConfig.d.ts.map +1 -1
- package/bin/plugins/auth/runtime/AuthorizationConfig.js +28 -26
- package/bin/plugins/auth/runtime/AuthorizationConfig.js.map +1 -1
- package/bin/plugins/auth/runtime/AuthorizationPolicy.d.ts +2 -0
- package/bin/plugins/auth/runtime/AuthorizationPolicy.d.ts.map +1 -1
- package/bin/plugins/auth/runtime/AuthorizationPolicy.js +3 -2
- package/bin/plugins/auth/runtime/AuthorizationPolicy.js.map +1 -1
- package/bin/plugins/auth/runtime/AuthorizationStore.d.ts +1 -1
- package/bin/plugins/auth/runtime/AuthorizationStore.d.ts.map +1 -1
- package/bin/plugins/auth/runtime/AuthorizationStore.js +3 -4
- package/bin/plugins/auth/runtime/AuthorizationStore.js.map +1 -1
- package/bin/plugins/skill/Plugin.js +2 -2
- package/bin/plugins/skill/Plugin.js.map +1 -1
- package/bin/plugins/tts/Plugin.d.ts.map +1 -1
- package/bin/plugins/tts/Plugin.js +4 -5
- package/bin/plugins/tts/Plugin.js.map +1 -1
- package/bin/plugins/web/Plugin.d.ts.map +1 -1
- package/bin/plugins/web/Plugin.js +4 -5
- package/bin/plugins/web/Plugin.js.map +1 -1
- package/bin/plugins/workboard/Plugin.js +2 -2
- package/bin/plugins/workboard/Plugin.js.map +1 -1
- package/bin/service/builtins/chat/accounts/ChannelAccountService.d.ts +4 -1
- package/bin/service/builtins/chat/accounts/ChannelAccountService.d.ts.map +1 -1
- package/bin/service/builtins/chat/accounts/ChannelAccountService.js +64 -91
- package/bin/service/builtins/chat/accounts/ChannelAccountService.js.map +1 -1
- package/bin/service/builtins/chat/runtime/ChatChannelActions.d.ts.map +1 -1
- package/bin/service/builtins/chat/runtime/ChatChannelActions.js +11 -18
- package/bin/service/builtins/chat/runtime/ChatChannelActions.js.map +1 -1
- package/bin/service/builtins/chat/runtime/ChatChannelCore.d.ts +1 -1
- package/bin/service/builtins/chat/runtime/ChatChannelCore.d.ts.map +1 -1
- package/bin/service/builtins/chat/runtime/ChatChannelCore.js +9 -17
- package/bin/service/builtins/chat/runtime/ChatChannelCore.js.map +1 -1
- package/bin/service/builtins/memory/Action.d.ts +1 -5
- package/bin/service/builtins/memory/Action.d.ts.map +1 -1
- package/bin/service/builtins/memory/Action.js +4 -42
- package/bin/service/builtins/memory/Action.js.map +1 -1
- package/bin/service/builtins/memory/MemoryService.d.ts.map +1 -1
- package/bin/service/builtins/memory/MemoryService.js +2 -32
- package/bin/service/builtins/memory/MemoryService.js.map +1 -1
- package/bin/service/builtins/memory/runtime/Search.d.ts +7 -3
- package/bin/service/builtins/memory/runtime/Search.d.ts.map +1 -1
- package/bin/service/builtins/memory/runtime/Search.js +220 -16
- package/bin/service/builtins/memory/runtime/Search.js.map +1 -1
- package/bin/service/builtins/memory/runtime/Store.d.ts +9 -50
- package/bin/service/builtins/memory/runtime/Store.d.ts.map +1 -1
- package/bin/service/builtins/memory/runtime/Store.js +10 -130
- package/bin/service/builtins/memory/runtime/Store.js.map +1 -1
- package/bin/service/builtins/memory/runtime/Writer.d.ts.map +1 -1
- package/bin/service/builtins/memory/runtime/Writer.js +1 -2
- package/bin/service/builtins/memory/runtime/Writer.js.map +1 -1
- package/bin/service/builtins/memory/types/Memory.d.ts +3 -57
- package/bin/service/builtins/memory/types/Memory.d.ts.map +1 -1
- package/bin/service/schedule/Store.d.ts +22 -25
- package/bin/service/schedule/Store.d.ts.map +1 -1
- package/bin/service/schedule/Store.js +172 -154
- package/bin/service/schedule/Store.js.map +1 -1
- package/bin/session/composer/system/default/SystemDomain.d.ts.map +1 -1
- package/bin/session/composer/system/default/SystemDomain.js +1 -0
- package/bin/session/composer/system/default/SystemDomain.js.map +1 -1
- package/bin/shared/types/AgentHost.d.ts +120 -4
- package/bin/shared/types/AgentHost.d.ts.map +1 -1
- package/bin/shared/types/Plugin.d.ts +5 -1
- package/bin/shared/types/Plugin.d.ts.map +1 -1
- package/package.json +1 -4
- package/src/agent/AgentContext.ts +1 -0
- package/src/agent/AgentContextTypes.ts +5 -0
- package/src/agent/AgentRuntime.ts +32 -3
- package/src/agent/AgentRuntimeState.ts +66 -2
- package/src/agent/AgentRuntimeTypes.ts +5 -0
- package/src/agent/project/AgentInitializer.ts +40 -42
- package/src/config/Config.ts +2 -17
- package/src/config/Paths.ts +2 -9
- package/src/host/daemon/ProjectSetup.ts +19 -21
- package/src/host/runtime/AgentHostRuntime.ts +0 -2
- package/src/host/runtime/CityPaths.ts +0 -3
- package/src/host/sdk/Agent.ts +67 -2
- package/src/host/sdk/AgentSdkTypes.ts +10 -0
- package/src/host/sdk/SdkSessionSystemComposer.ts +39 -2
- package/src/host/sdk/Session.ts +18 -0
- package/src/http/Server.ts +0 -13
- package/src/http/auth/AuthEnv.ts +0 -9
- package/src/http/auth/CliAuthStateStore.ts +0 -4
- package/src/http/control/ModelRoutes.ts +3 -9
- package/src/index.ts +2 -12
- package/src/model/CreateModel.ts +15 -13
- package/src/plugin/Activation.ts +6 -2
- package/src/plugin/LocalExecution.ts +24 -2
- package/src/plugin/PluginRegistry.ts +2 -2
- package/src/plugins/asr/Plugin.ts +4 -5
- package/src/plugins/auth/Plugin.ts +1 -0
- package/src/plugins/auth/runtime/AuthorizationConfig.ts +47 -37
- package/src/plugins/auth/runtime/AuthorizationPolicy.ts +5 -2
- package/src/plugins/auth/runtime/AuthorizationStore.ts +6 -5
- package/src/plugins/skill/Plugin.ts +2 -2
- package/src/plugins/tts/Plugin.ts +4 -5
- package/src/plugins/web/Plugin.ts +4 -5
- package/src/plugins/workboard/Plugin.ts +2 -2
- package/src/service/builtins/chat/accounts/ChannelAccountService.ts +42 -62
- package/src/service/builtins/chat/runtime/ChatChannelActions.ts +12 -18
- package/src/service/builtins/chat/runtime/ChatChannelCore.ts +9 -14
- package/src/service/builtins/memory/Action.ts +6 -47
- package/src/service/builtins/memory/MemoryService.ts +1 -33
- package/src/service/builtins/memory/runtime/Search.ts +256 -16
- package/src/service/builtins/memory/runtime/Store.ts +13 -185
- package/src/service/builtins/memory/runtime/Writer.ts +1 -2
- package/src/service/builtins/memory/types/Memory.ts +2 -59
- package/src/service/schedule/Store.ts +215 -175
- package/src/session/composer/system/default/SystemDomain.ts +1 -0
- package/src/shared/types/AgentHost.ts +138 -4
- package/src/shared/types/Plugin.ts +5 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/http/auth/AuthMiddleware.d.ts +0 -36
- package/bin/http/auth/AuthMiddleware.d.ts.map +0 -1
- package/bin/http/auth/AuthMiddleware.js +0 -37
- package/bin/http/auth/AuthMiddleware.js.map +0 -1
- package/bin/http/auth/AuthRoutes.d.ts +0 -17
- package/bin/http/auth/AuthRoutes.d.ts.map +0 -1
- package/bin/http/auth/AuthRoutes.js +0 -78
- package/bin/http/auth/AuthRoutes.js.map +0 -1
- package/bin/http/auth/AuthService.d.ts +0 -119
- package/bin/http/auth/AuthService.d.ts.map +0 -1
- package/bin/http/auth/AuthService.js +0 -307
- package/bin/http/auth/AuthService.js.map +0 -1
- package/bin/http/auth/AuthStore.d.ts +0 -165
- package/bin/http/auth/AuthStore.d.ts.map +0 -1
- package/bin/http/auth/AuthStore.js +0 -442
- package/bin/http/auth/AuthStore.js.map +0 -1
- package/bin/http/auth/RoutePolicy.d.ts +0 -30
- package/bin/http/auth/RoutePolicy.d.ts.map +0 -1
- package/bin/http/auth/RoutePolicy.js +0 -229
- package/bin/http/auth/RoutePolicy.js.map +0 -1
- package/bin/plugin/Lifecycle.d.ts +0 -33
- package/bin/plugin/Lifecycle.d.ts.map +0 -1
- package/bin/plugin/Lifecycle.js +0 -102
- package/bin/plugin/Lifecycle.js.map +0 -1
- package/bin/service/builtins/memory/runtime/Indexer.d.ts +0 -71
- package/bin/service/builtins/memory/runtime/Indexer.d.ts.map +0 -1
- package/bin/service/builtins/memory/runtime/Indexer.js +0 -345
- package/bin/service/builtins/memory/runtime/Indexer.js.map +0 -1
- package/bin/service/schedule/Schema.d.ts +0 -171
- package/bin/service/schedule/Schema.d.ts.map +0 -1
- package/bin/service/schedule/Schema.js +0 -26
- package/bin/service/schedule/Schema.js.map +0 -1
- package/bin/shared/utils/store/StoreChannelAccountRepository.d.ts +0 -34
- package/bin/shared/utils/store/StoreChannelAccountRepository.d.ts.map +0 -1
- package/bin/shared/utils/store/StoreChannelAccountRepository.js +0 -198
- package/bin/shared/utils/store/StoreChannelAccountRepository.js.map +0 -1
- package/bin/shared/utils/store/StoreEnvRepository.d.ts +0 -98
- package/bin/shared/utils/store/StoreEnvRepository.d.ts.map +0 -1
- package/bin/shared/utils/store/StoreEnvRepository.js +0 -334
- package/bin/shared/utils/store/StoreEnvRepository.js.map +0 -1
- package/bin/shared/utils/store/StoreModelRepository.d.ts +0 -61
- package/bin/shared/utils/store/StoreModelRepository.d.ts.map +0 -1
- package/bin/shared/utils/store/StoreModelRepository.js +0 -278
- package/bin/shared/utils/store/StoreModelRepository.js.map +0 -1
- package/bin/shared/utils/store/StoreSchema.d.ts +0 -13
- package/bin/shared/utils/store/StoreSchema.d.ts.map +0 -1
- package/bin/shared/utils/store/StoreSchema.js +0 -319
- package/bin/shared/utils/store/StoreSchema.js.map +0 -1
- package/bin/shared/utils/store/StoreSecureSettings.d.ts +0 -33
- package/bin/shared/utils/store/StoreSecureSettings.d.ts.map +0 -1
- package/bin/shared/utils/store/StoreSecureSettings.js +0 -91
- package/bin/shared/utils/store/StoreSecureSettings.js.map +0 -1
- package/bin/shared/utils/store/StoreShared.d.ts +0 -44
- package/bin/shared/utils/store/StoreShared.d.ts.map +0 -1
- package/bin/shared/utils/store/StoreShared.js +0 -40
- package/bin/shared/utils/store/StoreShared.js.map +0 -1
- package/bin/shared/utils/store/crypto.d.ts +0 -24
- package/bin/shared/utils/store/crypto.d.ts.map +0 -1
- package/bin/shared/utils/store/crypto.js +0 -101
- package/bin/shared/utils/store/crypto.js.map +0 -1
- package/bin/shared/utils/store/index.d.ts +0 -230
- package/bin/shared/utils/store/index.d.ts.map +0 -1
- package/bin/shared/utils/store/index.js +0 -360
- package/bin/shared/utils/store/index.js.map +0 -1
- package/bin/shared/utils/store/schema.d.ts +0 -690
- package/bin/shared/utils/store/schema.d.ts.map +0 -1
- package/bin/shared/utils/store/schema.js +0 -81
- package/bin/shared/utils/store/schema.js.map +0 -1
- package/src/http/auth/AuthMiddleware.ts +0 -61
- package/src/http/auth/AuthRoutes.ts +0 -100
- package/src/http/auth/AuthService.ts +0 -367
- package/src/http/auth/AuthStore.ts +0 -572
- package/src/http/auth/RoutePolicy.ts +0 -255
- package/src/plugin/Lifecycle.ts +0 -116
- package/src/service/builtins/memory/runtime/Indexer.ts +0 -466
- package/src/service/schedule/Schema.ts +0 -34
- package/src/shared/utils/store/StoreChannelAccountRepository.ts +0 -269
- package/src/shared/utils/store/StoreEnvRepository.ts +0 -452
- package/src/shared/utils/store/StoreModelRepository.ts +0 -324
- package/src/shared/utils/store/StoreSchema.ts +0 -344
- package/src/shared/utils/store/StoreSecureSettings.ts +0 -126
- package/src/shared/utils/store/StoreShared.ts +0 -67
- package/src/shared/utils/store/crypto.ts +0 -112
- package/src/shared/utils/store/index.ts +0 -497
- package/src/shared/utils/store/schema.ts +0 -103
|
@@ -15,7 +15,6 @@ import { BaseService } from "@/service/builtins/BaseService.js";
|
|
|
15
15
|
import {
|
|
16
16
|
flushMemoryAction,
|
|
17
17
|
getMemoryAction,
|
|
18
|
-
indexMemoryAction,
|
|
19
18
|
searchMemoryAction,
|
|
20
19
|
statusMemoryAction,
|
|
21
20
|
storeMemoryAction,
|
|
@@ -76,11 +75,6 @@ function readOptionalNumber(body: JsonObject, key: string): number | undefined {
|
|
|
76
75
|
return typeof value === "number" ? value : undefined;
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
function readOptionalBoolean(body: JsonObject, key: string): boolean | undefined {
|
|
80
|
-
const value = body[key];
|
|
81
|
-
return typeof value === "boolean" ? value : undefined;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
78
|
/**
|
|
85
79
|
* Memory service 类实现。
|
|
86
80
|
*/
|
|
@@ -124,7 +118,7 @@ export class MemoryService extends BaseService {
|
|
|
124
118
|
readonly actions: ServiceActions = {
|
|
125
119
|
status: {
|
|
126
120
|
command: {
|
|
127
|
-
description: "查看 memory 状态(backend/files/chunks
|
|
121
|
+
description: "查看 memory 状态(backend/files/chunks)",
|
|
128
122
|
mapInput() {
|
|
129
123
|
return {};
|
|
130
124
|
},
|
|
@@ -137,32 +131,6 @@ export class MemoryService extends BaseService {
|
|
|
137
131
|
return await statusMemoryAction(params.context, state);
|
|
138
132
|
},
|
|
139
133
|
},
|
|
140
|
-
index: {
|
|
141
|
-
command: {
|
|
142
|
-
description: "重建 memory 索引",
|
|
143
|
-
configure(command: Command) {
|
|
144
|
-
command.option("--force", "强制全量重建", false);
|
|
145
|
-
},
|
|
146
|
-
mapInput({ opts }) {
|
|
147
|
-
return {
|
|
148
|
-
force: opts.force === true,
|
|
149
|
-
};
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
api: {
|
|
153
|
-
method: "POST",
|
|
154
|
-
mapInput(ctx) {
|
|
155
|
-
return ctx.req.json();
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
execute: async (params) => {
|
|
159
|
-
const body = readBodyObject(params.payload);
|
|
160
|
-
const state = this.getOrCreateRuntimeState(params.context);
|
|
161
|
-
return await indexMemoryAction(params.context, state, {
|
|
162
|
-
force: readOptionalBoolean(body, "force"),
|
|
163
|
-
});
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
134
|
search: {
|
|
167
135
|
command: {
|
|
168
136
|
description: "检索记忆片段",
|
|
@@ -2,26 +2,219 @@
|
|
|
2
2
|
* Memory Search 运行时。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
5
|
+
* - 直接扫描 Markdown 文件,不依赖额外索引库。
|
|
6
|
+
* - 统一收敛检索、分块、打分与状态统计逻辑。
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import fs from "node:fs/promises";
|
|
9
10
|
import type { AgentContext } from "@/agent/AgentContextTypes.js";
|
|
10
11
|
import type {
|
|
11
12
|
MemorySearchPayload,
|
|
12
13
|
MemorySearchResponse,
|
|
14
|
+
MemorySearchResultItem,
|
|
15
|
+
MemorySourceStat,
|
|
16
|
+
MemoryStatusResponse,
|
|
13
17
|
} from "@/service/builtins/memory/types/Memory.js";
|
|
14
18
|
import {
|
|
19
|
+
listMemorySourceFiles,
|
|
15
20
|
MEMORY_DEFAULTS,
|
|
16
|
-
ensureMemoryIndexed,
|
|
17
21
|
type MemoryRuntimeState,
|
|
18
22
|
} from "./Store.js";
|
|
19
23
|
|
|
24
|
+
const SNIPPET_MAX_CHARS = 700;
|
|
25
|
+
const CHUNK_MAX_CHARS = 1600;
|
|
26
|
+
const CHUNK_OVERLAP_CHARS = 240;
|
|
27
|
+
|
|
20
28
|
function clampNumber(value: number, min: number, max: number): number {
|
|
21
29
|
if (!Number.isFinite(value)) return min;
|
|
22
30
|
return Math.max(min, Math.min(max, value));
|
|
23
31
|
}
|
|
24
32
|
|
|
33
|
+
function normalizeText(input: string): string {
|
|
34
|
+
return String(input || "").replace(/\r\n/g, "\n");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function truncateText(value: string, maxChars: number): string {
|
|
38
|
+
if (value.length <= maxChars) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
return value.slice(0, maxChars);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function tokenizeQuery(raw: string): string[] {
|
|
45
|
+
return String(raw || "")
|
|
46
|
+
.toLowerCase()
|
|
47
|
+
.replace(/[^\p{L}\p{N}_-]+/gu, " ")
|
|
48
|
+
.split(/\s+/)
|
|
49
|
+
.map((item) => item.trim())
|
|
50
|
+
.filter(Boolean)
|
|
51
|
+
.slice(0, 12);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function countTokenOccurrences(text: string, token: string): number {
|
|
55
|
+
if (!token) return 0;
|
|
56
|
+
let hits = 0;
|
|
57
|
+
let start = 0;
|
|
58
|
+
while (start < text.length) {
|
|
59
|
+
const index = text.indexOf(token, start);
|
|
60
|
+
if (index < 0) break;
|
|
61
|
+
hits += 1;
|
|
62
|
+
start = index + token.length;
|
|
63
|
+
}
|
|
64
|
+
return hits;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function buildSnippetScore(text: string, tokens: string[]): number {
|
|
68
|
+
if (tokens.length === 0) return 0;
|
|
69
|
+
const normalized = normalizeText(text).toLowerCase();
|
|
70
|
+
let matchedTokens = 0;
|
|
71
|
+
let totalHits = 0;
|
|
72
|
+
for (const token of tokens) {
|
|
73
|
+
const hits = countTokenOccurrences(normalized, token);
|
|
74
|
+
if (hits > 0) {
|
|
75
|
+
matchedTokens += 1;
|
|
76
|
+
totalHits += Math.min(hits, 4);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (matchedTokens === 0) {
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
const coverageScore = matchedTokens / tokens.length;
|
|
83
|
+
const densityScore = Math.min(totalHits, tokens.length * 3) / (tokens.length * 3);
|
|
84
|
+
return Number((coverageScore * 0.75 + densityScore * 0.25).toFixed(4));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function chunkMarkdown(content: string): Array<{
|
|
88
|
+
startLine: number;
|
|
89
|
+
endLine: number;
|
|
90
|
+
text: string;
|
|
91
|
+
}> {
|
|
92
|
+
const lines = normalizeText(content).split("\n");
|
|
93
|
+
if (lines.length === 0) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
const out: Array<{
|
|
97
|
+
startLine: number;
|
|
98
|
+
endLine: number;
|
|
99
|
+
text: string;
|
|
100
|
+
}> = [];
|
|
101
|
+
let bucket: Array<{ line: string; lineNo: number }> = [];
|
|
102
|
+
let chars = 0;
|
|
103
|
+
|
|
104
|
+
const flush = () => {
|
|
105
|
+
if (bucket.length === 0) return;
|
|
106
|
+
const startLine = bucket[0]?.lineNo ?? 1;
|
|
107
|
+
const endLine = bucket[bucket.length - 1]?.lineNo ?? startLine;
|
|
108
|
+
const text = bucket.map((item) => item.line).join("\n").trim();
|
|
109
|
+
if (!text) return;
|
|
110
|
+
out.push({
|
|
111
|
+
startLine,
|
|
112
|
+
endLine,
|
|
113
|
+
text,
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const carryOverlap = () => {
|
|
118
|
+
if (bucket.length === 0 || CHUNK_OVERLAP_CHARS <= 0) {
|
|
119
|
+
bucket = [];
|
|
120
|
+
chars = 0;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
let acc = 0;
|
|
124
|
+
const next: Array<{ line: string; lineNo: number }> = [];
|
|
125
|
+
for (let i = bucket.length - 1; i >= 0; i -= 1) {
|
|
126
|
+
const row = bucket[i];
|
|
127
|
+
if (!row) continue;
|
|
128
|
+
acc += row.line.length + 1;
|
|
129
|
+
next.unshift(row);
|
|
130
|
+
if (acc >= CHUNK_OVERLAP_CHARS) break;
|
|
131
|
+
}
|
|
132
|
+
bucket = next;
|
|
133
|
+
chars = bucket.reduce((sum, item) => sum + item.line.length + 1, 0);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
137
|
+
const line = lines[i] ?? "";
|
|
138
|
+
const rowSize = line.length + 1;
|
|
139
|
+
if (bucket.length > 0 && chars + rowSize > CHUNK_MAX_CHARS) {
|
|
140
|
+
flush();
|
|
141
|
+
carryOverlap();
|
|
142
|
+
}
|
|
143
|
+
bucket.push({ line, lineNo: i + 1 });
|
|
144
|
+
chars += rowSize;
|
|
145
|
+
}
|
|
146
|
+
flush();
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function readMemoryChunks(context: AgentContext): Promise<Array<{
|
|
151
|
+
path: string;
|
|
152
|
+
source: "longterm" | "daily" | "working";
|
|
153
|
+
startLine: number;
|
|
154
|
+
endLine: number;
|
|
155
|
+
text: string;
|
|
156
|
+
}>> {
|
|
157
|
+
const files = await listMemorySourceFiles(context.rootPath);
|
|
158
|
+
const out: Array<{
|
|
159
|
+
path: string;
|
|
160
|
+
source: "longterm" | "daily" | "working";
|
|
161
|
+
startLine: number;
|
|
162
|
+
endLine: number;
|
|
163
|
+
text: string;
|
|
164
|
+
}> = [];
|
|
165
|
+
for (const file of files) {
|
|
166
|
+
const content = String(await fs.readFile(file.absPath, "utf-8"));
|
|
167
|
+
for (const chunk of chunkMarkdown(content)) {
|
|
168
|
+
out.push({
|
|
169
|
+
path: file.relPath,
|
|
170
|
+
source: file.source,
|
|
171
|
+
startLine: chunk.startLine,
|
|
172
|
+
endLine: chunk.endLine,
|
|
173
|
+
text: chunk.text,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 收集当前 memory Markdown 状态。
|
|
182
|
+
*/
|
|
183
|
+
export async function collectMemoryStatus(
|
|
184
|
+
context: AgentContext,
|
|
185
|
+
state: MemoryRuntimeState,
|
|
186
|
+
): Promise<MemoryStatusResponse> {
|
|
187
|
+
const files = await listMemorySourceFiles(context.rootPath);
|
|
188
|
+
const sourceCounts: MemorySourceStat[] = [
|
|
189
|
+
{ source: "longterm", files: 0, chunks: 0 },
|
|
190
|
+
{ source: "daily", files: 0, chunks: 0 },
|
|
191
|
+
{ source: "working", files: 0, chunks: 0 },
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
let totalChunks = 0;
|
|
195
|
+
for (const file of files) {
|
|
196
|
+
const bucket = sourceCounts.find((item) => item.source === file.source);
|
|
197
|
+
if (bucket) {
|
|
198
|
+
bucket.files += 1;
|
|
199
|
+
}
|
|
200
|
+
const content = String(await fs.readFile(file.absPath, "utf-8"));
|
|
201
|
+
const chunks = chunkMarkdown(content).length;
|
|
202
|
+
totalChunks += chunks;
|
|
203
|
+
if (bucket) {
|
|
204
|
+
bucket.chunks += chunks;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
enabled: state.enabled,
|
|
210
|
+
backend: "builtin",
|
|
211
|
+
mode: "scan",
|
|
212
|
+
files: files.length,
|
|
213
|
+
chunks: totalChunks,
|
|
214
|
+
sourceCounts,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
25
218
|
/**
|
|
26
219
|
* 执行检索。
|
|
27
220
|
*/
|
|
@@ -33,7 +226,7 @@ export async function searchMemory(
|
|
|
33
226
|
if (!state.enabled) {
|
|
34
227
|
return {
|
|
35
228
|
backend: "builtin",
|
|
36
|
-
mode: "
|
|
229
|
+
mode: "scan",
|
|
37
230
|
results: [],
|
|
38
231
|
disabled: true,
|
|
39
232
|
error: "memory service disabled",
|
|
@@ -45,7 +238,16 @@ export async function searchMemory(
|
|
|
45
238
|
if (!query) {
|
|
46
239
|
return {
|
|
47
240
|
backend: "builtin",
|
|
48
|
-
mode: "
|
|
241
|
+
mode: "scan",
|
|
242
|
+
results: [],
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const tokens = tokenizeQuery(query);
|
|
247
|
+
if (tokens.length === 0) {
|
|
248
|
+
return {
|
|
249
|
+
backend: "builtin",
|
|
250
|
+
mode: "scan",
|
|
49
251
|
results: [],
|
|
50
252
|
};
|
|
51
253
|
}
|
|
@@ -64,27 +266,65 @@ export async function searchMemory(
|
|
|
64
266
|
);
|
|
65
267
|
|
|
66
268
|
try {
|
|
67
|
-
await
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
269
|
+
const results = (await readMemoryChunks(context))
|
|
270
|
+
.map((chunk) => {
|
|
271
|
+
const score = buildSnippetScore(chunk.text, tokens);
|
|
272
|
+
const citation =
|
|
273
|
+
chunk.startLine === chunk.endLine
|
|
274
|
+
? `${chunk.path}#L${chunk.startLine}`
|
|
275
|
+
: `${chunk.path}#L${chunk.startLine}-L${chunk.endLine}`;
|
|
276
|
+
return {
|
|
277
|
+
path: chunk.path,
|
|
278
|
+
source: chunk.source,
|
|
279
|
+
startLine: chunk.startLine,
|
|
280
|
+
endLine: chunk.endLine,
|
|
281
|
+
score,
|
|
282
|
+
snippet: truncateText(chunk.text, SNIPPET_MAX_CHARS),
|
|
283
|
+
citation,
|
|
284
|
+
} satisfies MemorySearchResultItem;
|
|
285
|
+
})
|
|
286
|
+
.filter((item) => item.score >= minScore)
|
|
287
|
+
.sort((left, right) => {
|
|
288
|
+
if (right.score !== left.score) {
|
|
289
|
+
return right.score - left.score;
|
|
290
|
+
}
|
|
291
|
+
if (left.path !== right.path) {
|
|
292
|
+
return left.path.localeCompare(right.path);
|
|
293
|
+
}
|
|
294
|
+
return left.startLine - right.startLine;
|
|
295
|
+
})
|
|
296
|
+
.slice(0, maxResults * 3);
|
|
297
|
+
|
|
298
|
+
let remain = Math.max(0, MEMORY_DEFAULTS.maxInjectedChars);
|
|
299
|
+
const clamped: MemorySearchResultItem[] = [];
|
|
300
|
+
for (const item of results) {
|
|
301
|
+
if (remain <= 0 || clamped.length >= maxResults) break;
|
|
302
|
+
if (item.snippet.length <= remain) {
|
|
303
|
+
clamped.push(item);
|
|
304
|
+
remain -= item.snippet.length;
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
clamped.push({
|
|
308
|
+
...item,
|
|
309
|
+
snippet: item.snippet.slice(0, remain),
|
|
310
|
+
});
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
|
|
74
314
|
return {
|
|
75
315
|
backend: "builtin",
|
|
76
|
-
mode: "
|
|
77
|
-
results,
|
|
316
|
+
mode: "scan",
|
|
317
|
+
results: clamped,
|
|
78
318
|
};
|
|
79
319
|
} catch (error) {
|
|
80
320
|
const message = String(error);
|
|
81
321
|
return {
|
|
82
322
|
backend: "builtin",
|
|
83
|
-
mode: "
|
|
323
|
+
mode: "scan",
|
|
84
324
|
results: [],
|
|
85
325
|
disabled: true,
|
|
86
326
|
error: message,
|
|
87
|
-
action: "
|
|
327
|
+
action: "Check the Markdown memory files under `.downcity/memory/`.",
|
|
88
328
|
};
|
|
89
329
|
}
|
|
90
330
|
}
|
|
@@ -2,32 +2,25 @@
|
|
|
2
2
|
* Memory Store(文件与运行态管理)。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* - 管理 Memory service
|
|
6
|
-
* - 统一管理 memory
|
|
7
|
-
* - 不承载检索算法,检索在 Search
|
|
5
|
+
* - 管理 Memory service 的最小运行时状态。
|
|
6
|
+
* - 统一管理 memory 源文件枚举。
|
|
7
|
+
* - 不承载检索算法,检索在 Search 模块。
|
|
8
8
|
* - 新版本不再使用 module-global state,状态归属 MemoryService 实例。
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import
|
|
11
|
+
import type { Dirent } from "node:fs";
|
|
12
12
|
import fsp from "node:fs/promises";
|
|
13
13
|
import path from "node:path";
|
|
14
|
-
import type { FSWatcher } from "node:fs";
|
|
15
14
|
import type { AgentContext } from "@/agent/AgentContextTypes.js";
|
|
16
15
|
import type {
|
|
17
16
|
MemoryDefaults,
|
|
18
17
|
MemorySourceType,
|
|
19
18
|
} from "@/service/builtins/memory/types/Memory.js";
|
|
20
|
-
import {
|
|
21
|
-
MemoryIndexer,
|
|
22
|
-
type MemoryIndexSyncResult,
|
|
23
|
-
} from "./Indexer.js";
|
|
24
19
|
|
|
25
20
|
export const MEMORY_DEFAULTS: MemoryDefaults = {
|
|
26
21
|
maxResults: 6,
|
|
27
22
|
minScore: 0.35,
|
|
28
23
|
maxInjectedChars: 4000,
|
|
29
|
-
watchDebounceMs: 1500,
|
|
30
|
-
intervalMinutes: 5,
|
|
31
24
|
};
|
|
32
25
|
|
|
33
26
|
export type MemorySourceFile = {
|
|
@@ -54,38 +47,6 @@ export type MemoryRuntimeState = {
|
|
|
54
47
|
* Memory 是否启用。
|
|
55
48
|
*/
|
|
56
49
|
enabled: boolean;
|
|
57
|
-
/**
|
|
58
|
-
* 索引器实例。
|
|
59
|
-
*/
|
|
60
|
-
indexer: MemoryIndexer;
|
|
61
|
-
/**
|
|
62
|
-
* 当前是否 dirty。
|
|
63
|
-
*/
|
|
64
|
-
dirty: boolean;
|
|
65
|
-
/**
|
|
66
|
-
* 最近一次同步时间戳。
|
|
67
|
-
*/
|
|
68
|
-
lastSyncAt?: number;
|
|
69
|
-
/**
|
|
70
|
-
* 最近一次同步错误。
|
|
71
|
-
*/
|
|
72
|
-
lastError?: string;
|
|
73
|
-
/**
|
|
74
|
-
* 当前同步中的 Promise(用于并发合并)。
|
|
75
|
-
*/
|
|
76
|
-
syncing: Promise<void> | null;
|
|
77
|
-
/**
|
|
78
|
-
* watcher 列表。
|
|
79
|
-
*/
|
|
80
|
-
watchers: FSWatcher[];
|
|
81
|
-
/**
|
|
82
|
-
* debounce timer。
|
|
83
|
-
*/
|
|
84
|
-
watchDebounceTimer: NodeJS.Timeout | null;
|
|
85
|
-
/**
|
|
86
|
-
* interval timer。
|
|
87
|
-
*/
|
|
88
|
-
intervalTimer: NodeJS.Timeout | null;
|
|
89
50
|
};
|
|
90
51
|
|
|
91
52
|
function normalizeRelPath(rootPath: string, absPath: string): string {
|
|
@@ -107,7 +68,7 @@ async function pathExists(absPath: string): Promise<boolean> {
|
|
|
107
68
|
|
|
108
69
|
async function listMarkdownFilesRecursively(dirPath: string): Promise<string[]> {
|
|
109
70
|
const out: string[] = [];
|
|
110
|
-
let entries:
|
|
71
|
+
let entries: Dirent[] = [];
|
|
111
72
|
try {
|
|
112
73
|
entries = await fsp.readdir(dirPath, { withFileTypes: true });
|
|
113
74
|
} catch {
|
|
@@ -156,7 +117,7 @@ export async function listMemorySourceFiles(
|
|
|
156
117
|
}
|
|
157
118
|
|
|
158
119
|
const sessionRootDir = path.join(rootPath, ".downcity", "session");
|
|
159
|
-
let sessions:
|
|
120
|
+
let sessions: Dirent[] = [];
|
|
160
121
|
try {
|
|
161
122
|
sessions = await fsp.readdir(sessionRootDir, { withFileTypes: true });
|
|
162
123
|
} catch {
|
|
@@ -206,64 +167,15 @@ export function createMemoryRuntimeState(
|
|
|
206
167
|
return {
|
|
207
168
|
rootPath: context.rootPath,
|
|
208
169
|
enabled: isMemoryEnabled(context),
|
|
209
|
-
indexer: new MemoryIndexer(context.rootPath),
|
|
210
|
-
dirty: true,
|
|
211
|
-
syncing: null,
|
|
212
|
-
watchers: [],
|
|
213
|
-
watchDebounceTimer: null,
|
|
214
|
-
intervalTimer: null,
|
|
215
170
|
};
|
|
216
171
|
}
|
|
217
172
|
|
|
218
173
|
/**
|
|
219
|
-
*
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
reason: string,
|
|
225
|
-
): void {
|
|
226
|
-
state.dirty = true;
|
|
227
|
-
if (state.watchDebounceTimer) {
|
|
228
|
-
clearTimeout(state.watchDebounceTimer);
|
|
229
|
-
}
|
|
230
|
-
state.watchDebounceTimer = setTimeout(() => {
|
|
231
|
-
state.watchDebounceTimer = null;
|
|
232
|
-
void ensureMemoryIndexed(context, state, { reason: `watch:${reason}` });
|
|
233
|
-
}, MEMORY_DEFAULTS.watchDebounceMs);
|
|
234
|
-
if (typeof state.watchDebounceTimer.unref === "function") {
|
|
235
|
-
state.watchDebounceTimer.unref();
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function registerWatcher(
|
|
240
|
-
context: AgentContext,
|
|
241
|
-
state: MemoryRuntimeState,
|
|
242
|
-
watchPath: string,
|
|
243
|
-
): void {
|
|
244
|
-
try {
|
|
245
|
-
const watcher = fs.watch(
|
|
246
|
-
watchPath,
|
|
247
|
-
{ recursive: true },
|
|
248
|
-
(_event, fileName) => {
|
|
249
|
-
const name = String(fileName || "").toLowerCase();
|
|
250
|
-
if (!name.endsWith(".md")) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
markMemoryDirty(context, state, name || "unknown");
|
|
254
|
-
},
|
|
255
|
-
);
|
|
256
|
-
state.watchers.push(watcher);
|
|
257
|
-
} catch (error) {
|
|
258
|
-
context.logger.warn("[memory] watcher init skipped", {
|
|
259
|
-
watchPath,
|
|
260
|
-
error: String(error),
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* 启动 memory 运行时(watcher + interval)。
|
|
174
|
+
* 启动 memory 运行时。
|
|
175
|
+
*
|
|
176
|
+
* 关键点(中文)
|
|
177
|
+
* - Markdown-only 方案下不再维护后台索引同步。
|
|
178
|
+
* - 这里只负责根据配置刷新 enabled 状态。
|
|
267
179
|
*/
|
|
268
180
|
export async function startMemoryRuntime(
|
|
269
181
|
context: AgentContext,
|
|
@@ -274,97 +186,13 @@ export async function startMemoryRuntime(
|
|
|
274
186
|
context.logger.info("[memory] disabled by config");
|
|
275
187
|
return;
|
|
276
188
|
}
|
|
277
|
-
|
|
278
|
-
if (state.watchers.length === 0) {
|
|
279
|
-
registerWatcher(context, state, path.join(context.rootPath, ".downcity"));
|
|
280
|
-
}
|
|
281
|
-
if (!state.intervalTimer) {
|
|
282
|
-
state.intervalTimer = setInterval(() => {
|
|
283
|
-
void ensureMemoryIndexed(context, state, { reason: "interval" });
|
|
284
|
-
}, MEMORY_DEFAULTS.intervalMinutes * 60 * 1000);
|
|
285
|
-
if (typeof state.intervalTimer.unref === "function") {
|
|
286
|
-
state.intervalTimer.unref();
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
await ensureMemoryIndexed(context, state, { reason: "startup" });
|
|
291
189
|
}
|
|
292
190
|
|
|
293
191
|
/**
|
|
294
192
|
* 停止 memory 运行时。
|
|
295
193
|
*/
|
|
296
194
|
export async function stopMemoryRuntime(
|
|
297
|
-
|
|
195
|
+
_state: MemoryRuntimeState,
|
|
298
196
|
): Promise<void> {
|
|
299
|
-
|
|
300
|
-
clearTimeout(state.watchDebounceTimer);
|
|
301
|
-
state.watchDebounceTimer = null;
|
|
302
|
-
}
|
|
303
|
-
if (state.intervalTimer) {
|
|
304
|
-
clearInterval(state.intervalTimer);
|
|
305
|
-
state.intervalTimer = null;
|
|
306
|
-
}
|
|
307
|
-
for (const watcher of state.watchers) {
|
|
308
|
-
try {
|
|
309
|
-
watcher.close();
|
|
310
|
-
} catch {
|
|
311
|
-
// ignore
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
state.watchers = [];
|
|
315
|
-
|
|
316
|
-
if (state.syncing) {
|
|
317
|
-
try {
|
|
318
|
-
await state.syncing;
|
|
319
|
-
} catch {
|
|
320
|
-
// ignore
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
state.indexer.close();
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* 确保索引已同步。
|
|
328
|
-
*/
|
|
329
|
-
export async function ensureMemoryIndexed(
|
|
330
|
-
context: AgentContext,
|
|
331
|
-
state: MemoryRuntimeState,
|
|
332
|
-
params?: { force?: boolean; reason?: string },
|
|
333
|
-
): Promise<MemoryIndexSyncResult | null> {
|
|
334
|
-
if (!state.enabled) {
|
|
335
|
-
return null;
|
|
336
|
-
}
|
|
337
|
-
const force = params?.force === true;
|
|
338
|
-
if (!force && !state.dirty) {
|
|
339
|
-
return null;
|
|
340
|
-
}
|
|
341
|
-
if (state.syncing) {
|
|
342
|
-
await state.syncing;
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
let syncResult: MemoryIndexSyncResult | null = null;
|
|
346
|
-
state.syncing = (async () => {
|
|
347
|
-
try {
|
|
348
|
-
const files = await listMemorySourceFiles(context.rootPath);
|
|
349
|
-
syncResult = await state.indexer.sync(files, { force });
|
|
350
|
-
state.dirty = false;
|
|
351
|
-
state.lastError = undefined;
|
|
352
|
-
state.lastSyncAt = Date.now();
|
|
353
|
-
context.logger.info("[memory] index synced", {
|
|
354
|
-
reason: params?.reason || "manual",
|
|
355
|
-
files: files.length,
|
|
356
|
-
});
|
|
357
|
-
} catch (error) {
|
|
358
|
-
state.lastError = String(error);
|
|
359
|
-
context.logger.error("[memory] index sync failed", {
|
|
360
|
-
reason: params?.reason || "manual",
|
|
361
|
-
error: state.lastError,
|
|
362
|
-
});
|
|
363
|
-
throw error;
|
|
364
|
-
} finally {
|
|
365
|
-
state.syncing = null;
|
|
366
|
-
}
|
|
367
|
-
})();
|
|
368
|
-
await state.syncing;
|
|
369
|
-
return syncResult;
|
|
197
|
+
void _state;
|
|
370
198
|
}
|
|
@@ -17,7 +17,6 @@ import type {
|
|
|
17
17
|
MemoryStoreResponse,
|
|
18
18
|
} from "@/service/builtins/memory/types/Memory.js";
|
|
19
19
|
import type { MemoryRuntimeState } from "./Store.js";
|
|
20
|
-
import { markMemoryDirty } from "./Store.js";
|
|
21
20
|
|
|
22
21
|
function nowIso(): string {
|
|
23
22
|
return new Date().toISOString();
|
|
@@ -88,6 +87,7 @@ export async function storeMemory(
|
|
|
88
87
|
state: MemoryRuntimeState,
|
|
89
88
|
payload: MemoryStorePayload,
|
|
90
89
|
): Promise<MemoryStoreResponse> {
|
|
90
|
+
void state;
|
|
91
91
|
const target: MemorySourceType = payload.target ?? "daily";
|
|
92
92
|
const content = String(payload.content || "").trim();
|
|
93
93
|
if (!content) {
|
|
@@ -104,7 +104,6 @@ export async function storeMemory(
|
|
|
104
104
|
}
|
|
105
105
|
const entry = formatEntry(content);
|
|
106
106
|
await fs.appendFile(resolved.absPath, `\n${entry}`, "utf-8");
|
|
107
|
-
markMemoryDirty(context, state, `store:${resolved.relPath}`);
|
|
108
107
|
return {
|
|
109
108
|
path: resolved.relPath,
|
|
110
109
|
target,
|