@downcity/agent 1.1.7 → 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 +1 -0
- package/bin/host/sdk/Agent.d.ts.map +1 -1
- package/bin/host/sdk/Agent.js +24 -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/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 +26 -2
- package/src/host/sdk/AgentSdkTypes.ts +10 -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
|
@@ -1,466 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory Indexer(SQLite FTS)。
|
|
3
|
-
*
|
|
4
|
-
* 关键点(中文)
|
|
5
|
-
* - 使用 SQLite + FTS5 做本地检索加速。
|
|
6
|
-
* - Markdown 仍是事实源,索引可重建。
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import crypto from "node:crypto";
|
|
10
|
-
import fs from "node:fs/promises";
|
|
11
|
-
import { mkdirSync } from "node:fs";
|
|
12
|
-
import path from "node:path";
|
|
13
|
-
import Database from "better-sqlite3";
|
|
14
|
-
import type {
|
|
15
|
-
MemorySearchResultItem,
|
|
16
|
-
MemorySourceType,
|
|
17
|
-
MemorySourceStat,
|
|
18
|
-
} from "@/service/builtins/memory/types/Memory.js";
|
|
19
|
-
import type { MemorySourceFile } from "./Store.js";
|
|
20
|
-
|
|
21
|
-
const INDEX_SCHEMA_VERSION = 1;
|
|
22
|
-
const SNIPPET_MAX_CHARS = 700;
|
|
23
|
-
const CHUNK_MAX_CHARS = 1600;
|
|
24
|
-
const CHUNK_OVERLAP_CHARS = 240;
|
|
25
|
-
|
|
26
|
-
type IndexedFileRow = {
|
|
27
|
-
path: string;
|
|
28
|
-
hash: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
type MemoryChunk = {
|
|
32
|
-
startLine: number;
|
|
33
|
-
endLine: number;
|
|
34
|
-
text: string;
|
|
35
|
-
hash: string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export type MemoryIndexSyncResult = {
|
|
39
|
-
/**
|
|
40
|
-
* 扫描文件总数。
|
|
41
|
-
*/
|
|
42
|
-
totalFiles: number;
|
|
43
|
-
/**
|
|
44
|
-
* 重建文件数。
|
|
45
|
-
*/
|
|
46
|
-
reindexedFiles: number;
|
|
47
|
-
/**
|
|
48
|
-
* 删除失效文件数。
|
|
49
|
-
*/
|
|
50
|
-
removedFiles: number;
|
|
51
|
-
/**
|
|
52
|
-
* 重建写入 chunk 总数。
|
|
53
|
-
*/
|
|
54
|
-
totalChunks: number;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export type MemoryIndexStatus = {
|
|
58
|
-
/**
|
|
59
|
-
* 当前文件数。
|
|
60
|
-
*/
|
|
61
|
-
files: number;
|
|
62
|
-
/**
|
|
63
|
-
* 当前 chunk 数。
|
|
64
|
-
*/
|
|
65
|
-
chunks: number;
|
|
66
|
-
/**
|
|
67
|
-
* 按来源统计。
|
|
68
|
-
*/
|
|
69
|
-
sourceCounts: MemorySourceStat[];
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
function hashText(value: string): string {
|
|
73
|
-
return crypto.createHash("sha256").update(value).digest("hex");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function normalizeText(input: string): string {
|
|
77
|
-
return String(input || "").replace(/\r\n/g, "\n");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function quoteFtsToken(token: string): string {
|
|
81
|
-
return `"${token.replace(/"/g, '""')}"`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* 构建 FTS 查询表达式。
|
|
86
|
-
*/
|
|
87
|
-
export function buildFtsQuery(raw: string): string | null {
|
|
88
|
-
const normalized = String(raw || "").trim();
|
|
89
|
-
if (!normalized) return null;
|
|
90
|
-
const tokens = normalized
|
|
91
|
-
.replace(/[^\p{L}\p{N}_-]+/gu, " ")
|
|
92
|
-
.split(/\s+/)
|
|
93
|
-
.map((item) => item.trim())
|
|
94
|
-
.filter(Boolean)
|
|
95
|
-
.slice(0, 12);
|
|
96
|
-
if (tokens.length === 0) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
return tokens.map((token) => `${quoteFtsToken(token)}*`).join(" ");
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function bm25RankToScore(rank: number): number {
|
|
103
|
-
if (!Number.isFinite(rank)) {
|
|
104
|
-
return 0;
|
|
105
|
-
}
|
|
106
|
-
return 1 / (1 + Math.abs(rank));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function truncateText(value: string, maxChars: number): string {
|
|
110
|
-
if (value.length <= maxChars) {
|
|
111
|
-
return value;
|
|
112
|
-
}
|
|
113
|
-
return value.slice(0, maxChars);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function chunkMarkdown(content: string): MemoryChunk[] {
|
|
117
|
-
const lines = normalizeText(content).split("\n");
|
|
118
|
-
if (lines.length === 0) {
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
const out: MemoryChunk[] = [];
|
|
122
|
-
let bucket: Array<{ line: string; lineNo: number }> = [];
|
|
123
|
-
let chars = 0;
|
|
124
|
-
|
|
125
|
-
const flush = () => {
|
|
126
|
-
if (bucket.length === 0) return;
|
|
127
|
-
const startLine = bucket[0]?.lineNo ?? 1;
|
|
128
|
-
const endLine = bucket[bucket.length - 1]?.lineNo ?? startLine;
|
|
129
|
-
const text = bucket.map((item) => item.line).join("\n").trim();
|
|
130
|
-
if (text) {
|
|
131
|
-
out.push({
|
|
132
|
-
startLine,
|
|
133
|
-
endLine,
|
|
134
|
-
text,
|
|
135
|
-
hash: hashText(text),
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
const carryOverlap = () => {
|
|
141
|
-
if (bucket.length === 0 || CHUNK_OVERLAP_CHARS <= 0) {
|
|
142
|
-
bucket = [];
|
|
143
|
-
chars = 0;
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
let acc = 0;
|
|
147
|
-
const next: Array<{ line: string; lineNo: number }> = [];
|
|
148
|
-
for (let i = bucket.length - 1; i >= 0; i -= 1) {
|
|
149
|
-
const row = bucket[i];
|
|
150
|
-
if (!row) continue;
|
|
151
|
-
acc += row.line.length + 1;
|
|
152
|
-
next.unshift(row);
|
|
153
|
-
if (acc >= CHUNK_OVERLAP_CHARS) break;
|
|
154
|
-
}
|
|
155
|
-
bucket = next;
|
|
156
|
-
chars = bucket.reduce((sum, item) => sum + item.line.length + 1, 0);
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
for (let i = 0; i < lines.length; i += 1) {
|
|
160
|
-
const line = lines[i] ?? "";
|
|
161
|
-
const rowSize = line.length + 1;
|
|
162
|
-
if (bucket.length > 0 && chars + rowSize > CHUNK_MAX_CHARS) {
|
|
163
|
-
flush();
|
|
164
|
-
carryOverlap();
|
|
165
|
-
}
|
|
166
|
-
bucket.push({ line, lineNo: i + 1 });
|
|
167
|
-
chars += rowSize;
|
|
168
|
-
}
|
|
169
|
-
flush();
|
|
170
|
-
return out;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* MemoryIndexManager(单项目单实例)。
|
|
175
|
-
*/
|
|
176
|
-
export class MemoryIndexer {
|
|
177
|
-
private readonly dbPath: string;
|
|
178
|
-
private readonly db: Database.Database;
|
|
179
|
-
|
|
180
|
-
constructor(private readonly rootPath: string) {
|
|
181
|
-
this.dbPath = path.join(rootPath, ".downcity", "memory", "index.sqlite");
|
|
182
|
-
const dir = path.dirname(this.dbPath);
|
|
183
|
-
// 同步创建目录,保证 sqlite 可打开。
|
|
184
|
-
// 关键点(中文):这里是启动路径,避免引入异步竞态。
|
|
185
|
-
mkdirSync(dir, { recursive: true });
|
|
186
|
-
this.db = new Database(this.dbPath);
|
|
187
|
-
// 关键点(中文):使用 WAL 改善并发读写稳定性,避免长事务阻塞查询。
|
|
188
|
-
this.db.pragma("journal_mode = WAL");
|
|
189
|
-
this.ensureSchema();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
getRelativeDbPath(): string {
|
|
193
|
-
return path.relative(this.rootPath, this.dbPath).replace(/\\/g, "/");
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
close(): void {
|
|
197
|
-
this.db.close();
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
private ensureSchema(): void {
|
|
201
|
-
this.db.exec(`
|
|
202
|
-
CREATE TABLE IF NOT EXISTS meta (
|
|
203
|
-
key TEXT PRIMARY KEY,
|
|
204
|
-
value TEXT NOT NULL
|
|
205
|
-
);
|
|
206
|
-
`);
|
|
207
|
-
this.db.exec(`
|
|
208
|
-
CREATE TABLE IF NOT EXISTS files (
|
|
209
|
-
path TEXT PRIMARY KEY,
|
|
210
|
-
source TEXT NOT NULL,
|
|
211
|
-
hash TEXT NOT NULL,
|
|
212
|
-
mtime INTEGER NOT NULL,
|
|
213
|
-
size INTEGER NOT NULL
|
|
214
|
-
);
|
|
215
|
-
`);
|
|
216
|
-
this.db.exec(`
|
|
217
|
-
CREATE TABLE IF NOT EXISTS chunks (
|
|
218
|
-
id TEXT PRIMARY KEY,
|
|
219
|
-
path TEXT NOT NULL,
|
|
220
|
-
source TEXT NOT NULL,
|
|
221
|
-
start_line INTEGER NOT NULL,
|
|
222
|
-
end_line INTEGER NOT NULL,
|
|
223
|
-
text TEXT NOT NULL,
|
|
224
|
-
hash TEXT NOT NULL,
|
|
225
|
-
updated_at INTEGER NOT NULL
|
|
226
|
-
);
|
|
227
|
-
`);
|
|
228
|
-
this.db.exec(`
|
|
229
|
-
CREATE INDEX IF NOT EXISTS idx_chunks_path ON chunks(path);
|
|
230
|
-
`);
|
|
231
|
-
this.db.exec(`
|
|
232
|
-
CREATE INDEX IF NOT EXISTS idx_chunks_source ON chunks(source);
|
|
233
|
-
`);
|
|
234
|
-
this.db.exec(`
|
|
235
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(
|
|
236
|
-
text,
|
|
237
|
-
id UNINDEXED,
|
|
238
|
-
path UNINDEXED,
|
|
239
|
-
source UNINDEXED,
|
|
240
|
-
start_line UNINDEXED,
|
|
241
|
-
end_line UNINDEXED
|
|
242
|
-
);
|
|
243
|
-
`);
|
|
244
|
-
const schemaVersion = this.db
|
|
245
|
-
.prepare(`SELECT value FROM meta WHERE key = ?`)
|
|
246
|
-
.get("schema_version") as { value?: string } | undefined;
|
|
247
|
-
if (schemaVersion?.value !== String(INDEX_SCHEMA_VERSION)) {
|
|
248
|
-
this.db
|
|
249
|
-
.prepare(
|
|
250
|
-
`INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
|
|
251
|
-
)
|
|
252
|
-
.run("schema_version", String(INDEX_SCHEMA_VERSION));
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
private listIndexedFiles(): IndexedFileRow[] {
|
|
257
|
-
return this.db
|
|
258
|
-
.prepare(`SELECT path, hash FROM files`)
|
|
259
|
-
.all() as IndexedFileRow[];
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
private deleteFileIndex(relPath: string): void {
|
|
263
|
-
this.db.prepare(`DELETE FROM chunks_fts WHERE path = ?`).run(relPath);
|
|
264
|
-
this.db.prepare(`DELETE FROM chunks WHERE path = ?`).run(relPath);
|
|
265
|
-
this.db.prepare(`DELETE FROM files WHERE path = ?`).run(relPath);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
private writeFileChunks(file: MemorySourceFile, chunks: MemoryChunk[]): void {
|
|
269
|
-
const now = Date.now();
|
|
270
|
-
const insertChunk = this.db.prepare(
|
|
271
|
-
`INSERT INTO chunks (id, path, source, start_line, end_line, text, hash, updated_at)
|
|
272
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
273
|
-
);
|
|
274
|
-
const insertFts = this.db.prepare(
|
|
275
|
-
`INSERT INTO chunks_fts (text, id, path, source, start_line, end_line)
|
|
276
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
277
|
-
);
|
|
278
|
-
for (const chunk of chunks) {
|
|
279
|
-
const id = hashText(
|
|
280
|
-
`${file.relPath}:${file.source}:${chunk.startLine}:${chunk.endLine}:${chunk.hash}`,
|
|
281
|
-
);
|
|
282
|
-
insertChunk.run(
|
|
283
|
-
id,
|
|
284
|
-
file.relPath,
|
|
285
|
-
file.source,
|
|
286
|
-
chunk.startLine,
|
|
287
|
-
chunk.endLine,
|
|
288
|
-
chunk.text,
|
|
289
|
-
chunk.hash,
|
|
290
|
-
now,
|
|
291
|
-
);
|
|
292
|
-
insertFts.run(
|
|
293
|
-
chunk.text,
|
|
294
|
-
id,
|
|
295
|
-
file.relPath,
|
|
296
|
-
file.source,
|
|
297
|
-
chunk.startLine,
|
|
298
|
-
chunk.endLine,
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
async sync(
|
|
304
|
-
files: MemorySourceFile[],
|
|
305
|
-
options?: { force?: boolean },
|
|
306
|
-
): Promise<MemoryIndexSyncResult> {
|
|
307
|
-
const totalFiles = files.length;
|
|
308
|
-
const force = options?.force === true;
|
|
309
|
-
const existing = new Map(
|
|
310
|
-
this.listIndexedFiles().map((item) => [item.path, item.hash]),
|
|
311
|
-
);
|
|
312
|
-
const activePaths = new Set(files.map((item) => item.relPath));
|
|
313
|
-
let reindexedFiles = 0;
|
|
314
|
-
let removedFiles = 0;
|
|
315
|
-
let totalChunks = 0;
|
|
316
|
-
|
|
317
|
-
this.db.exec("BEGIN");
|
|
318
|
-
try {
|
|
319
|
-
for (const file of files) {
|
|
320
|
-
const stat = await fs.stat(file.absPath);
|
|
321
|
-
const content = normalizeText(await fs.readFile(file.absPath, "utf-8"));
|
|
322
|
-
const hash = hashText(content);
|
|
323
|
-
const prevHash = existing.get(file.relPath);
|
|
324
|
-
if (!force && prevHash === hash) {
|
|
325
|
-
continue;
|
|
326
|
-
}
|
|
327
|
-
this.deleteFileIndex(file.relPath);
|
|
328
|
-
const chunks = chunkMarkdown(content);
|
|
329
|
-
this.writeFileChunks(file, chunks);
|
|
330
|
-
this.db
|
|
331
|
-
.prepare(
|
|
332
|
-
`INSERT INTO files (path, source, hash, mtime, size)
|
|
333
|
-
VALUES (?, ?, ?, ?, ?)
|
|
334
|
-
ON CONFLICT(path) DO UPDATE SET
|
|
335
|
-
source = excluded.source,
|
|
336
|
-
hash = excluded.hash,
|
|
337
|
-
mtime = excluded.mtime,
|
|
338
|
-
size = excluded.size`,
|
|
339
|
-
)
|
|
340
|
-
.run(file.relPath, file.source, hash, stat.mtimeMs, stat.size);
|
|
341
|
-
reindexedFiles += 1;
|
|
342
|
-
totalChunks += chunks.length;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
for (const stale of existing.keys()) {
|
|
346
|
-
if (activePaths.has(stale)) continue;
|
|
347
|
-
this.deleteFileIndex(stale);
|
|
348
|
-
removedFiles += 1;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
this.db
|
|
352
|
-
.prepare(
|
|
353
|
-
`INSERT INTO meta (key, value) VALUES (?, ?)
|
|
354
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
|
|
355
|
-
)
|
|
356
|
-
.run("last_indexed_at", String(Date.now()));
|
|
357
|
-
|
|
358
|
-
this.db.exec("COMMIT");
|
|
359
|
-
} catch (error) {
|
|
360
|
-
this.db.exec("ROLLBACK");
|
|
361
|
-
throw error;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return {
|
|
365
|
-
totalFiles,
|
|
366
|
-
reindexedFiles,
|
|
367
|
-
removedFiles,
|
|
368
|
-
totalChunks,
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
search(params: {
|
|
373
|
-
query: string;
|
|
374
|
-
maxResults: number;
|
|
375
|
-
minScore: number;
|
|
376
|
-
maxInjectedChars: number;
|
|
377
|
-
}): MemorySearchResultItem[] {
|
|
378
|
-
const ftsQuery = buildFtsQuery(params.query);
|
|
379
|
-
if (!ftsQuery) {
|
|
380
|
-
return [];
|
|
381
|
-
}
|
|
382
|
-
const rows = this.db
|
|
383
|
-
.prepare(
|
|
384
|
-
`SELECT path, source, start_line, end_line, text, bm25(chunks_fts) AS rank
|
|
385
|
-
FROM chunks_fts
|
|
386
|
-
WHERE chunks_fts MATCH ?
|
|
387
|
-
ORDER BY rank ASC
|
|
388
|
-
LIMIT ?`,
|
|
389
|
-
)
|
|
390
|
-
.all(ftsQuery, Math.max(1, params.maxResults * 3)) as Array<{
|
|
391
|
-
path: string;
|
|
392
|
-
source: MemorySourceType;
|
|
393
|
-
start_line: number;
|
|
394
|
-
end_line: number;
|
|
395
|
-
text: string;
|
|
396
|
-
rank: number;
|
|
397
|
-
}>;
|
|
398
|
-
const mapped: MemorySearchResultItem[] = rows
|
|
399
|
-
.map((row) => {
|
|
400
|
-
const score = bm25RankToScore(row.rank);
|
|
401
|
-
const citation =
|
|
402
|
-
row.start_line === row.end_line
|
|
403
|
-
? `${row.path}#L${row.start_line}`
|
|
404
|
-
: `${row.path}#L${row.start_line}-L${row.end_line}`;
|
|
405
|
-
return {
|
|
406
|
-
path: row.path,
|
|
407
|
-
source: row.source,
|
|
408
|
-
startLine: row.start_line,
|
|
409
|
-
endLine: row.end_line,
|
|
410
|
-
score,
|
|
411
|
-
snippet: truncateText(row.text, SNIPPET_MAX_CHARS),
|
|
412
|
-
citation,
|
|
413
|
-
};
|
|
414
|
-
})
|
|
415
|
-
.filter((item) => item.score >= params.minScore)
|
|
416
|
-
.slice(0, params.maxResults);
|
|
417
|
-
|
|
418
|
-
let remain = Math.max(0, params.maxInjectedChars);
|
|
419
|
-
const clamped: MemorySearchResultItem[] = [];
|
|
420
|
-
for (const item of mapped) {
|
|
421
|
-
if (remain <= 0) break;
|
|
422
|
-
if (item.snippet.length <= remain) {
|
|
423
|
-
clamped.push(item);
|
|
424
|
-
remain -= item.snippet.length;
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
|
-
clamped.push({
|
|
428
|
-
...item,
|
|
429
|
-
snippet: item.snippet.slice(0, remain),
|
|
430
|
-
});
|
|
431
|
-
break;
|
|
432
|
-
}
|
|
433
|
-
return clamped;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
status(): MemoryIndexStatus {
|
|
437
|
-
const filesRow = this.db
|
|
438
|
-
.prepare(`SELECT COUNT(*) as c FROM files`)
|
|
439
|
-
.get() as { c: number } | undefined;
|
|
440
|
-
const chunksRow = this.db
|
|
441
|
-
.prepare(`SELECT COUNT(*) as c FROM chunks`)
|
|
442
|
-
.get() as { c: number } | undefined;
|
|
443
|
-
const sourceRows = this.db
|
|
444
|
-
.prepare(
|
|
445
|
-
`SELECT source, COUNT(*) as files,
|
|
446
|
-
(SELECT COUNT(*) FROM chunks c WHERE c.source = f.source) AS chunks
|
|
447
|
-
FROM files f
|
|
448
|
-
GROUP BY source`,
|
|
449
|
-
)
|
|
450
|
-
.all() as Array<{ source: MemorySourceType; files: number; chunks: number }>;
|
|
451
|
-
const orderedSources: MemorySourceType[] = ["longterm", "daily", "working"];
|
|
452
|
-
const sourceCounts: MemorySourceStat[] = orderedSources.map((source) => {
|
|
453
|
-
const found = sourceRows.find((item) => item.source === source);
|
|
454
|
-
return {
|
|
455
|
-
source,
|
|
456
|
-
files: found?.files ?? 0,
|
|
457
|
-
chunks: found?.chunks ?? 0,
|
|
458
|
-
};
|
|
459
|
-
});
|
|
460
|
-
return {
|
|
461
|
-
files: filesRow?.c ?? 0,
|
|
462
|
-
chunks: chunksRow?.c ?? 0,
|
|
463
|
-
sourceCounts,
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service Schedule SQLite schema。
|
|
3
|
-
*
|
|
4
|
-
* 关键点(中文)
|
|
5
|
-
* - 使用 Drizzle 定义本地调度任务表。
|
|
6
|
-
* - 仅保留 MVP 所需字段:任务目标、执行时间、状态与错误摘要。
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 调度任务表。
|
|
13
|
-
*/
|
|
14
|
-
export const scheduledJobsTable = sqliteTable(
|
|
15
|
-
"scheduled_jobs",
|
|
16
|
-
{
|
|
17
|
-
id: text("id").primaryKey(),
|
|
18
|
-
serviceName: text("service_name").notNull(),
|
|
19
|
-
actionName: text("action_name").notNull(),
|
|
20
|
-
payloadJson: text("payload_json").notNull(),
|
|
21
|
-
runAtMs: integer("run_at_ms").notNull(),
|
|
22
|
-
status: text("status").notNull(),
|
|
23
|
-
error: text("error"),
|
|
24
|
-
createdAt: integer("created_at").notNull(),
|
|
25
|
-
updatedAt: integer("updated_at").notNull(),
|
|
26
|
-
},
|
|
27
|
-
(table) => ({
|
|
28
|
-
statusRunAtIdx: index("scheduled_jobs_status_run_at_idx").on(
|
|
29
|
-
table.status,
|
|
30
|
-
table.runAtMs,
|
|
31
|
-
),
|
|
32
|
-
runAtIdx: index("scheduled_jobs_run_at_idx").on(table.runAtMs),
|
|
33
|
-
}),
|
|
34
|
-
);
|