@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.
Files changed (284) hide show
  1. package/bin/agent/AgentContext.d.ts.map +1 -1
  2. package/bin/agent/AgentContext.js +1 -0
  3. package/bin/agent/AgentContext.js.map +1 -1
  4. package/bin/agent/AgentContextTypes.d.ts +5 -1
  5. package/bin/agent/AgentContextTypes.d.ts.map +1 -1
  6. package/bin/agent/AgentRuntime.d.ts +6 -1
  7. package/bin/agent/AgentRuntime.d.ts.map +1 -1
  8. package/bin/agent/AgentRuntime.js +22 -3
  9. package/bin/agent/AgentRuntime.js.map +1 -1
  10. package/bin/agent/AgentRuntimeState.d.ts.map +1 -1
  11. package/bin/agent/AgentRuntimeState.js +58 -2
  12. package/bin/agent/AgentRuntimeState.js.map +1 -1
  13. package/bin/agent/AgentRuntimeTypes.d.ts +5 -1
  14. package/bin/agent/AgentRuntimeTypes.d.ts.map +1 -1
  15. package/bin/agent/project/AgentInitializer.d.ts +3 -2
  16. package/bin/agent/project/AgentInitializer.d.ts.map +1 -1
  17. package/bin/agent/project/AgentInitializer.js +34 -44
  18. package/bin/agent/project/AgentInitializer.js.map +1 -1
  19. package/bin/config/Config.d.ts.map +1 -1
  20. package/bin/config/Config.js +2 -21
  21. package/bin/config/Config.js.map +1 -1
  22. package/bin/config/Paths.d.ts +1 -5
  23. package/bin/config/Paths.d.ts.map +1 -1
  24. package/bin/config/Paths.js +2 -8
  25. package/bin/config/Paths.js.map +1 -1
  26. package/bin/host/daemon/ProjectSetup.d.ts +2 -1
  27. package/bin/host/daemon/ProjectSetup.d.ts.map +1 -1
  28. package/bin/host/daemon/ProjectSetup.js +14 -21
  29. package/bin/host/daemon/ProjectSetup.js.map +1 -1
  30. package/bin/host/runtime/AgentHostRuntime.d.ts.map +1 -1
  31. package/bin/host/runtime/AgentHostRuntime.js +1 -2
  32. package/bin/host/runtime/AgentHostRuntime.js.map +1 -1
  33. package/bin/host/runtime/CityPaths.d.ts +0 -3
  34. package/bin/host/runtime/CityPaths.d.ts.map +1 -1
  35. package/bin/host/runtime/CityPaths.js +0 -3
  36. package/bin/host/runtime/CityPaths.js.map +1 -1
  37. package/bin/host/sdk/Agent.d.ts +4 -0
  38. package/bin/host/sdk/Agent.d.ts.map +1 -1
  39. package/bin/host/sdk/Agent.js +71 -2
  40. package/bin/host/sdk/Agent.js.map +1 -1
  41. package/bin/host/sdk/AgentSdkTypes.d.ts +9 -0
  42. package/bin/host/sdk/AgentSdkTypes.d.ts.map +1 -1
  43. package/bin/host/sdk/SdkSessionSystemComposer.d.ts +11 -2
  44. package/bin/host/sdk/SdkSessionSystemComposer.d.ts.map +1 -1
  45. package/bin/host/sdk/SdkSessionSystemComposer.js +19 -2
  46. package/bin/host/sdk/SdkSessionSystemComposer.js.map +1 -1
  47. package/bin/host/sdk/Session.d.ts +10 -0
  48. package/bin/host/sdk/Session.d.ts.map +1 -1
  49. package/bin/host/sdk/Session.js +8 -0
  50. package/bin/host/sdk/Session.js.map +1 -1
  51. package/bin/http/Server.d.ts.map +1 -1
  52. package/bin/http/Server.js +1 -11
  53. package/bin/http/Server.js.map +1 -1
  54. package/bin/http/auth/AuthEnv.d.ts +0 -9
  55. package/bin/http/auth/AuthEnv.d.ts.map +1 -1
  56. package/bin/http/auth/AuthEnv.js +0 -9
  57. package/bin/http/auth/AuthEnv.js.map +1 -1
  58. package/bin/http/auth/CliAuthStateStore.d.ts +0 -4
  59. package/bin/http/auth/CliAuthStateStore.d.ts.map +1 -1
  60. package/bin/http/auth/CliAuthStateStore.js +0 -4
  61. package/bin/http/auth/CliAuthStateStore.js.map +1 -1
  62. package/bin/http/control/ModelRoutes.d.ts.map +1 -1
  63. package/bin/http/control/ModelRoutes.js +3 -8
  64. package/bin/http/control/ModelRoutes.js.map +1 -1
  65. package/bin/index.d.ts +2 -6
  66. package/bin/index.d.ts.map +1 -1
  67. package/bin/index.js +2 -6
  68. package/bin/index.js.map +1 -1
  69. package/bin/model/CreateModel.d.ts +2 -2
  70. package/bin/model/CreateModel.d.ts.map +1 -1
  71. package/bin/model/CreateModel.js +13 -12
  72. package/bin/model/CreateModel.js.map +1 -1
  73. package/bin/plugin/Activation.d.ts +4 -0
  74. package/bin/plugin/Activation.d.ts.map +1 -1
  75. package/bin/plugin/Activation.js +2 -2
  76. package/bin/plugin/Activation.js.map +1 -1
  77. package/bin/plugin/LocalExecution.d.ts.map +1 -1
  78. package/bin/plugin/LocalExecution.js +23 -2
  79. package/bin/plugin/LocalExecution.js.map +1 -1
  80. package/bin/plugin/PluginRegistry.js +2 -2
  81. package/bin/plugin/PluginRegistry.js.map +1 -1
  82. package/bin/plugins/asr/Plugin.d.ts.map +1 -1
  83. package/bin/plugins/asr/Plugin.js +4 -5
  84. package/bin/plugins/asr/Plugin.js.map +1 -1
  85. package/bin/plugins/auth/Plugin.d.ts.map +1 -1
  86. package/bin/plugins/auth/Plugin.js +1 -0
  87. package/bin/plugins/auth/Plugin.js.map +1 -1
  88. package/bin/plugins/auth/runtime/AuthorizationConfig.d.ts +4 -4
  89. package/bin/plugins/auth/runtime/AuthorizationConfig.d.ts.map +1 -1
  90. package/bin/plugins/auth/runtime/AuthorizationConfig.js +28 -26
  91. package/bin/plugins/auth/runtime/AuthorizationConfig.js.map +1 -1
  92. package/bin/plugins/auth/runtime/AuthorizationPolicy.d.ts +2 -0
  93. package/bin/plugins/auth/runtime/AuthorizationPolicy.d.ts.map +1 -1
  94. package/bin/plugins/auth/runtime/AuthorizationPolicy.js +3 -2
  95. package/bin/plugins/auth/runtime/AuthorizationPolicy.js.map +1 -1
  96. package/bin/plugins/auth/runtime/AuthorizationStore.d.ts +1 -1
  97. package/bin/plugins/auth/runtime/AuthorizationStore.d.ts.map +1 -1
  98. package/bin/plugins/auth/runtime/AuthorizationStore.js +3 -4
  99. package/bin/plugins/auth/runtime/AuthorizationStore.js.map +1 -1
  100. package/bin/plugins/skill/Plugin.js +2 -2
  101. package/bin/plugins/skill/Plugin.js.map +1 -1
  102. package/bin/plugins/tts/Plugin.d.ts.map +1 -1
  103. package/bin/plugins/tts/Plugin.js +4 -5
  104. package/bin/plugins/tts/Plugin.js.map +1 -1
  105. package/bin/plugins/web/Plugin.d.ts.map +1 -1
  106. package/bin/plugins/web/Plugin.js +4 -5
  107. package/bin/plugins/web/Plugin.js.map +1 -1
  108. package/bin/plugins/workboard/Plugin.js +2 -2
  109. package/bin/plugins/workboard/Plugin.js.map +1 -1
  110. package/bin/service/builtins/chat/accounts/ChannelAccountService.d.ts +4 -1
  111. package/bin/service/builtins/chat/accounts/ChannelAccountService.d.ts.map +1 -1
  112. package/bin/service/builtins/chat/accounts/ChannelAccountService.js +64 -91
  113. package/bin/service/builtins/chat/accounts/ChannelAccountService.js.map +1 -1
  114. package/bin/service/builtins/chat/runtime/ChatChannelActions.d.ts.map +1 -1
  115. package/bin/service/builtins/chat/runtime/ChatChannelActions.js +11 -18
  116. package/bin/service/builtins/chat/runtime/ChatChannelActions.js.map +1 -1
  117. package/bin/service/builtins/chat/runtime/ChatChannelCore.d.ts +1 -1
  118. package/bin/service/builtins/chat/runtime/ChatChannelCore.d.ts.map +1 -1
  119. package/bin/service/builtins/chat/runtime/ChatChannelCore.js +9 -17
  120. package/bin/service/builtins/chat/runtime/ChatChannelCore.js.map +1 -1
  121. package/bin/service/builtins/memory/Action.d.ts +1 -5
  122. package/bin/service/builtins/memory/Action.d.ts.map +1 -1
  123. package/bin/service/builtins/memory/Action.js +4 -42
  124. package/bin/service/builtins/memory/Action.js.map +1 -1
  125. package/bin/service/builtins/memory/MemoryService.d.ts.map +1 -1
  126. package/bin/service/builtins/memory/MemoryService.js +2 -32
  127. package/bin/service/builtins/memory/MemoryService.js.map +1 -1
  128. package/bin/service/builtins/memory/runtime/Search.d.ts +7 -3
  129. package/bin/service/builtins/memory/runtime/Search.d.ts.map +1 -1
  130. package/bin/service/builtins/memory/runtime/Search.js +220 -16
  131. package/bin/service/builtins/memory/runtime/Search.js.map +1 -1
  132. package/bin/service/builtins/memory/runtime/Store.d.ts +9 -50
  133. package/bin/service/builtins/memory/runtime/Store.d.ts.map +1 -1
  134. package/bin/service/builtins/memory/runtime/Store.js +10 -130
  135. package/bin/service/builtins/memory/runtime/Store.js.map +1 -1
  136. package/bin/service/builtins/memory/runtime/Writer.d.ts.map +1 -1
  137. package/bin/service/builtins/memory/runtime/Writer.js +1 -2
  138. package/bin/service/builtins/memory/runtime/Writer.js.map +1 -1
  139. package/bin/service/builtins/memory/types/Memory.d.ts +3 -57
  140. package/bin/service/builtins/memory/types/Memory.d.ts.map +1 -1
  141. package/bin/service/schedule/Store.d.ts +22 -25
  142. package/bin/service/schedule/Store.d.ts.map +1 -1
  143. package/bin/service/schedule/Store.js +172 -154
  144. package/bin/service/schedule/Store.js.map +1 -1
  145. package/bin/session/composer/system/default/SystemDomain.d.ts.map +1 -1
  146. package/bin/session/composer/system/default/SystemDomain.js +1 -0
  147. package/bin/session/composer/system/default/SystemDomain.js.map +1 -1
  148. package/bin/shared/types/AgentHost.d.ts +120 -4
  149. package/bin/shared/types/AgentHost.d.ts.map +1 -1
  150. package/bin/shared/types/Plugin.d.ts +5 -1
  151. package/bin/shared/types/Plugin.d.ts.map +1 -1
  152. package/package.json +1 -4
  153. package/src/agent/AgentContext.ts +1 -0
  154. package/src/agent/AgentContextTypes.ts +5 -0
  155. package/src/agent/AgentRuntime.ts +32 -3
  156. package/src/agent/AgentRuntimeState.ts +66 -2
  157. package/src/agent/AgentRuntimeTypes.ts +5 -0
  158. package/src/agent/project/AgentInitializer.ts +40 -42
  159. package/src/config/Config.ts +2 -17
  160. package/src/config/Paths.ts +2 -9
  161. package/src/host/daemon/ProjectSetup.ts +19 -21
  162. package/src/host/runtime/AgentHostRuntime.ts +0 -2
  163. package/src/host/runtime/CityPaths.ts +0 -3
  164. package/src/host/sdk/Agent.ts +67 -2
  165. package/src/host/sdk/AgentSdkTypes.ts +10 -0
  166. package/src/host/sdk/SdkSessionSystemComposer.ts +39 -2
  167. package/src/host/sdk/Session.ts +18 -0
  168. package/src/http/Server.ts +0 -13
  169. package/src/http/auth/AuthEnv.ts +0 -9
  170. package/src/http/auth/CliAuthStateStore.ts +0 -4
  171. package/src/http/control/ModelRoutes.ts +3 -9
  172. package/src/index.ts +2 -12
  173. package/src/model/CreateModel.ts +15 -13
  174. package/src/plugin/Activation.ts +6 -2
  175. package/src/plugin/LocalExecution.ts +24 -2
  176. package/src/plugin/PluginRegistry.ts +2 -2
  177. package/src/plugins/asr/Plugin.ts +4 -5
  178. package/src/plugins/auth/Plugin.ts +1 -0
  179. package/src/plugins/auth/runtime/AuthorizationConfig.ts +47 -37
  180. package/src/plugins/auth/runtime/AuthorizationPolicy.ts +5 -2
  181. package/src/plugins/auth/runtime/AuthorizationStore.ts +6 -5
  182. package/src/plugins/skill/Plugin.ts +2 -2
  183. package/src/plugins/tts/Plugin.ts +4 -5
  184. package/src/plugins/web/Plugin.ts +4 -5
  185. package/src/plugins/workboard/Plugin.ts +2 -2
  186. package/src/service/builtins/chat/accounts/ChannelAccountService.ts +42 -62
  187. package/src/service/builtins/chat/runtime/ChatChannelActions.ts +12 -18
  188. package/src/service/builtins/chat/runtime/ChatChannelCore.ts +9 -14
  189. package/src/service/builtins/memory/Action.ts +6 -47
  190. package/src/service/builtins/memory/MemoryService.ts +1 -33
  191. package/src/service/builtins/memory/runtime/Search.ts +256 -16
  192. package/src/service/builtins/memory/runtime/Store.ts +13 -185
  193. package/src/service/builtins/memory/runtime/Writer.ts +1 -2
  194. package/src/service/builtins/memory/types/Memory.ts +2 -59
  195. package/src/service/schedule/Store.ts +215 -175
  196. package/src/session/composer/system/default/SystemDomain.ts +1 -0
  197. package/src/shared/types/AgentHost.ts +138 -4
  198. package/src/shared/types/Plugin.ts +5 -0
  199. package/tsconfig.tsbuildinfo +1 -1
  200. package/bin/http/auth/AuthMiddleware.d.ts +0 -36
  201. package/bin/http/auth/AuthMiddleware.d.ts.map +0 -1
  202. package/bin/http/auth/AuthMiddleware.js +0 -37
  203. package/bin/http/auth/AuthMiddleware.js.map +0 -1
  204. package/bin/http/auth/AuthRoutes.d.ts +0 -17
  205. package/bin/http/auth/AuthRoutes.d.ts.map +0 -1
  206. package/bin/http/auth/AuthRoutes.js +0 -78
  207. package/bin/http/auth/AuthRoutes.js.map +0 -1
  208. package/bin/http/auth/AuthService.d.ts +0 -119
  209. package/bin/http/auth/AuthService.d.ts.map +0 -1
  210. package/bin/http/auth/AuthService.js +0 -307
  211. package/bin/http/auth/AuthService.js.map +0 -1
  212. package/bin/http/auth/AuthStore.d.ts +0 -165
  213. package/bin/http/auth/AuthStore.d.ts.map +0 -1
  214. package/bin/http/auth/AuthStore.js +0 -442
  215. package/bin/http/auth/AuthStore.js.map +0 -1
  216. package/bin/http/auth/RoutePolicy.d.ts +0 -30
  217. package/bin/http/auth/RoutePolicy.d.ts.map +0 -1
  218. package/bin/http/auth/RoutePolicy.js +0 -229
  219. package/bin/http/auth/RoutePolicy.js.map +0 -1
  220. package/bin/plugin/Lifecycle.d.ts +0 -33
  221. package/bin/plugin/Lifecycle.d.ts.map +0 -1
  222. package/bin/plugin/Lifecycle.js +0 -102
  223. package/bin/plugin/Lifecycle.js.map +0 -1
  224. package/bin/service/builtins/memory/runtime/Indexer.d.ts +0 -71
  225. package/bin/service/builtins/memory/runtime/Indexer.d.ts.map +0 -1
  226. package/bin/service/builtins/memory/runtime/Indexer.js +0 -345
  227. package/bin/service/builtins/memory/runtime/Indexer.js.map +0 -1
  228. package/bin/service/schedule/Schema.d.ts +0 -171
  229. package/bin/service/schedule/Schema.d.ts.map +0 -1
  230. package/bin/service/schedule/Schema.js +0 -26
  231. package/bin/service/schedule/Schema.js.map +0 -1
  232. package/bin/shared/utils/store/StoreChannelAccountRepository.d.ts +0 -34
  233. package/bin/shared/utils/store/StoreChannelAccountRepository.d.ts.map +0 -1
  234. package/bin/shared/utils/store/StoreChannelAccountRepository.js +0 -198
  235. package/bin/shared/utils/store/StoreChannelAccountRepository.js.map +0 -1
  236. package/bin/shared/utils/store/StoreEnvRepository.d.ts +0 -98
  237. package/bin/shared/utils/store/StoreEnvRepository.d.ts.map +0 -1
  238. package/bin/shared/utils/store/StoreEnvRepository.js +0 -334
  239. package/bin/shared/utils/store/StoreEnvRepository.js.map +0 -1
  240. package/bin/shared/utils/store/StoreModelRepository.d.ts +0 -61
  241. package/bin/shared/utils/store/StoreModelRepository.d.ts.map +0 -1
  242. package/bin/shared/utils/store/StoreModelRepository.js +0 -278
  243. package/bin/shared/utils/store/StoreModelRepository.js.map +0 -1
  244. package/bin/shared/utils/store/StoreSchema.d.ts +0 -13
  245. package/bin/shared/utils/store/StoreSchema.d.ts.map +0 -1
  246. package/bin/shared/utils/store/StoreSchema.js +0 -319
  247. package/bin/shared/utils/store/StoreSchema.js.map +0 -1
  248. package/bin/shared/utils/store/StoreSecureSettings.d.ts +0 -33
  249. package/bin/shared/utils/store/StoreSecureSettings.d.ts.map +0 -1
  250. package/bin/shared/utils/store/StoreSecureSettings.js +0 -91
  251. package/bin/shared/utils/store/StoreSecureSettings.js.map +0 -1
  252. package/bin/shared/utils/store/StoreShared.d.ts +0 -44
  253. package/bin/shared/utils/store/StoreShared.d.ts.map +0 -1
  254. package/bin/shared/utils/store/StoreShared.js +0 -40
  255. package/bin/shared/utils/store/StoreShared.js.map +0 -1
  256. package/bin/shared/utils/store/crypto.d.ts +0 -24
  257. package/bin/shared/utils/store/crypto.d.ts.map +0 -1
  258. package/bin/shared/utils/store/crypto.js +0 -101
  259. package/bin/shared/utils/store/crypto.js.map +0 -1
  260. package/bin/shared/utils/store/index.d.ts +0 -230
  261. package/bin/shared/utils/store/index.d.ts.map +0 -1
  262. package/bin/shared/utils/store/index.js +0 -360
  263. package/bin/shared/utils/store/index.js.map +0 -1
  264. package/bin/shared/utils/store/schema.d.ts +0 -690
  265. package/bin/shared/utils/store/schema.d.ts.map +0 -1
  266. package/bin/shared/utils/store/schema.js +0 -81
  267. package/bin/shared/utils/store/schema.js.map +0 -1
  268. package/src/http/auth/AuthMiddleware.ts +0 -61
  269. package/src/http/auth/AuthRoutes.ts +0 -100
  270. package/src/http/auth/AuthService.ts +0 -367
  271. package/src/http/auth/AuthStore.ts +0 -572
  272. package/src/http/auth/RoutePolicy.ts +0 -255
  273. package/src/plugin/Lifecycle.ts +0 -116
  274. package/src/service/builtins/memory/runtime/Indexer.ts +0 -466
  275. package/src/service/schedule/Schema.ts +0 -34
  276. package/src/shared/utils/store/StoreChannelAccountRepository.ts +0 -269
  277. package/src/shared/utils/store/StoreEnvRepository.ts +0 -452
  278. package/src/shared/utils/store/StoreModelRepository.ts +0 -324
  279. package/src/shared/utils/store/StoreSchema.ts +0 -344
  280. package/src/shared/utils/store/StoreSecureSettings.ts +0 -126
  281. package/src/shared/utils/store/StoreShared.ts +0 -67
  282. package/src/shared/utils/store/crypto.ts +0 -112
  283. package/src/shared/utils/store/index.ts +0 -497
  284. package/src/shared/utils/store/schema.ts +0 -103
@@ -17,9 +17,9 @@ export type MemorySourceType = "longterm" | "daily" | "working";
17
17
  * 查询模式。
18
18
  *
19
19
  * 说明(中文)
20
- * - 当前实现以 FTS 为主,保留字段用于后续向量扩展。
20
+ * - 当前实现直接扫描 Markdown 文件,不再维护额外索引库。
21
21
  */
22
- export type MemorySearchMode = "fts";
22
+ export type MemorySearchMode = "scan";
23
23
 
24
24
  /**
25
25
  * 单条记忆检索结果。
@@ -175,38 +175,6 @@ export interface MemoryStoreResponse {
175
175
  writtenChars: number;
176
176
  }
177
177
 
178
- /**
179
- * 手动索引请求。
180
- */
181
- export interface MemoryIndexPayload {
182
- /**
183
- * 是否强制全量重建。
184
- */
185
- force?: boolean;
186
- }
187
-
188
- /**
189
- * 手动索引响应。
190
- */
191
- export interface MemoryIndexResponse {
192
- /**
193
- * 本轮扫描文件总数。
194
- */
195
- totalFiles: number;
196
- /**
197
- * 本轮新增/变更并完成重建的文件数。
198
- */
199
- reindexedFiles: number;
200
- /**
201
- * 本轮删除的失效文件数。
202
- */
203
- removedFiles: number;
204
- /**
205
- * 本轮写入 chunk 总数。
206
- */
207
- totalChunks: number;
208
- }
209
-
210
178
  /**
211
179
  * Flush 请求。
212
180
  */
@@ -273,14 +241,6 @@ export interface MemoryStatusResponse {
273
241
  * 当前检索模式。
274
242
  */
275
243
  mode: MemorySearchMode;
276
- /**
277
- * 索引文件路径(相对项目根目录)。
278
- */
279
- dbPath: string;
280
- /**
281
- * 当前是否为 dirty 状态。
282
- */
283
- dirty: boolean;
284
244
  /**
285
245
  * 文件总数。
286
246
  */
@@ -293,14 +253,6 @@ export interface MemoryStatusResponse {
293
253
  * 按来源统计。
294
254
  */
295
255
  sourceCounts: MemorySourceStat[];
296
- /**
297
- * 最近一次同步时间戳(ms)。
298
- */
299
- lastSyncAt?: number;
300
- /**
301
- * 最近一次同步错误。
302
- */
303
- lastError?: string;
304
256
  }
305
257
 
306
258
  /**
@@ -319,14 +271,6 @@ export interface MemoryDefaults {
319
271
  * 注入预算(字符)。
320
272
  */
321
273
  maxInjectedChars: number;
322
- /**
323
- * 文件变更 debounce 时间(毫秒)。
324
- */
325
- watchDebounceMs: number;
326
- /**
327
- * 后台同步周期(分钟)。
328
- */
329
- intervalMinutes: number;
330
274
  }
331
275
 
332
276
  /**
@@ -336,6 +280,5 @@ export type MemoryActionPayload =
336
280
  | MemorySearchPayload
337
281
  | MemoryGetPayload
338
282
  | MemoryStorePayload
339
- | MemoryIndexPayload
340
283
  | MemoryFlushPayload
341
284
  | Record<string, JsonValue>;
@@ -2,16 +2,13 @@
2
2
  * Service Schedule 持久化存储。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 使用项目内 SQLite 持久化 one-shot service action 调度任务。
6
- * - 当前模块只维护“当前状态”,不维护额外审计事件流。
5
+ * - 调度任务改为使用项目内 `jsonl` 事件流持久化,不再依赖 SQLite。
6
+ * - 这里采用“全量重放 + 内存归并”的最简实现,保持职责清晰且易于迁移。
7
+ * - 文件只记录状态事件;对外仍暴露稳定的调度任务查询与状态更新接口。
7
8
  */
8
9
 
9
10
  import fs from "fs-extra";
10
- import Database from "better-sqlite3";
11
11
  import path from "node:path";
12
- import { and, asc, desc, eq, inArray, lte } from "drizzle-orm";
13
- import { drizzle } from "drizzle-orm/better-sqlite3";
14
- import { scheduledJobsTable } from "./Schema.js";
15
12
  import type {
16
13
  CreateScheduledJobInput,
17
14
  ScheduledJobRecord,
@@ -21,80 +18,137 @@ import type { JsonValue } from "@/shared/types/Json.js";
21
18
  import { generateId } from "@shared/utils/Id.js";
22
19
  import { getDowncityScheduleDbPath } from "@/config/Paths.js";
23
20
 
24
- type ScheduledJobRow = typeof scheduledJobsTable.$inferSelect;
21
+ type ScheduledJobEvent =
22
+ | {
23
+ /**
24
+ * 事件版本号。
25
+ */
26
+ v: 1;
27
+ /**
28
+ * 事件类型:创建任务。
29
+ */
30
+ type: "created";
31
+ /**
32
+ * 调度任务快照。
33
+ */
34
+ job: ScheduledJobRecord;
35
+ }
36
+ | {
37
+ /**
38
+ * 事件版本号。
39
+ */
40
+ v: 1;
41
+ /**
42
+ * 事件类型:状态更新。
43
+ */
44
+ type: "status";
45
+ /**
46
+ * 目标任务 ID。
47
+ */
48
+ jobId: string;
49
+ /**
50
+ * 新状态。
51
+ */
52
+ status: ScheduledJobStatus;
53
+ /**
54
+ * 最新更新时间。
55
+ */
56
+ updatedAt: number;
57
+ /**
58
+ * 可选错误信息。
59
+ */
60
+ error?: string;
61
+ };
62
+
63
+ function readJsonlLines(filePath: string): string[] {
64
+ if (!fs.existsSync(filePath)) return [];
65
+ const raw = fs.readFileSync(filePath, "utf-8");
66
+ return raw
67
+ .split(/\r?\n/)
68
+ .map((line) => line.trim())
69
+ .filter(Boolean);
70
+ }
71
+
72
+ function normalizeJobRecord(input: ScheduledJobRecord): ScheduledJobRecord {
73
+ return {
74
+ id: String(input.id || "").trim(),
75
+ serviceName: String(input.serviceName || "").trim(),
76
+ actionName: String(input.actionName || "").trim(),
77
+ payload: input.payload ?? null,
78
+ runAtMs: Math.trunc(input.runAtMs),
79
+ status: input.status,
80
+ ...(typeof input.error === "string" && input.error ? { error: input.error } : {}),
81
+ createdAt: Math.trunc(input.createdAt),
82
+ updatedAt: Math.trunc(input.updatedAt),
83
+ };
84
+ }
85
+
86
+ function parseEvent(line: string): ScheduledJobEvent | null {
87
+ try {
88
+ const raw = JSON.parse(line) as Partial<ScheduledJobEvent> | null;
89
+ if (!raw || typeof raw !== "object") return null;
90
+ if (raw.type === "created" && raw.job) {
91
+ return {
92
+ v: 1,
93
+ type: "created",
94
+ job: normalizeJobRecord(raw.job as ScheduledJobRecord),
95
+ };
96
+ }
97
+ if (
98
+ raw.type === "status" &&
99
+ typeof raw.jobId === "string" &&
100
+ typeof raw.status === "string" &&
101
+ typeof raw.updatedAt === "number"
102
+ ) {
103
+ return {
104
+ v: 1,
105
+ type: "status",
106
+ jobId: raw.jobId,
107
+ status: raw.status as ScheduledJobStatus,
108
+ updatedAt: Math.trunc(raw.updatedAt),
109
+ ...(typeof raw.error === "string" ? { error: raw.error } : {}),
110
+ };
111
+ }
112
+ return null;
113
+ } catch {
114
+ return null;
115
+ }
116
+ }
117
+
118
+ function compareJobs(a: ScheduledJobRecord, b: ScheduledJobRecord): number {
119
+ if (a.runAtMs !== b.runAtMs) return a.runAtMs - b.runAtMs;
120
+ return b.createdAt - a.createdAt;
121
+ }
25
122
 
26
123
  /**
27
124
  * Service Schedule Store。
28
125
  */
29
126
  export class ServiceScheduleStore {
30
- private readonly sqlite: Database.Database;
31
-
32
- private readonly db: ReturnType<typeof drizzle>;
127
+ private readonly filePath: string;
33
128
 
34
129
  constructor(projectRoot: string) {
35
- const dbPath = getDowncityScheduleDbPath(projectRoot);
36
- fs.ensureDirSync(path.dirname(dbPath));
37
- this.sqlite = new Database(dbPath);
38
- this.sqlite.pragma("journal_mode = WAL");
39
- this.db = drizzle(this.sqlite);
40
- this.ensureSchema();
41
- }
42
-
43
- /**
44
- * 初始化表结构。
45
- */
46
- private ensureSchema(): void {
47
- this.sqlite.exec(`
48
- CREATE TABLE IF NOT EXISTS scheduled_jobs (
49
- id TEXT PRIMARY KEY NOT NULL,
50
- service_name TEXT NOT NULL,
51
- action_name TEXT NOT NULL,
52
- payload_json TEXT NOT NULL,
53
- run_at_ms INTEGER NOT NULL,
54
- status TEXT NOT NULL,
55
- error TEXT,
56
- created_at INTEGER NOT NULL,
57
- updated_at INTEGER NOT NULL
58
- );
59
- `);
60
- this.sqlite.exec(`
61
- CREATE INDEX IF NOT EXISTS scheduled_jobs_status_run_at_idx
62
- ON scheduled_jobs(status, run_at_ms);
63
- `);
64
- this.sqlite.exec(`
65
- CREATE INDEX IF NOT EXISTS scheduled_jobs_run_at_idx
66
- ON scheduled_jobs(run_at_ms);
67
- `);
130
+ this.filePath = getDowncityScheduleDbPath(projectRoot);
131
+ fs.ensureDirSync(path.dirname(this.filePath));
132
+ if (!fs.existsSync(this.filePath)) {
133
+ fs.writeFileSync(this.filePath, "", "utf-8");
134
+ }
68
135
  }
69
136
 
70
137
  /**
71
- * 关闭数据库连接。
138
+ * 关闭存储。
139
+ *
140
+ * 说明(中文)
141
+ * - jsonl 版本无需保持长连接,因此 close 为 no-op。
72
142
  */
73
- close(): void {
74
- this.sqlite.close();
75
- }
143
+ close(): void {}
76
144
 
77
145
  /**
78
146
  * 创建调度任务。
79
147
  */
80
148
  createJob(input: CreateScheduledJobInput): ScheduledJobRecord {
81
149
  const now = Date.now();
82
- const id = `sched_${generateId()}`;
83
- const payloadJson = JSON.stringify(input.payload ?? null);
84
- this.db.insert(scheduledJobsTable).values({
85
- id,
86
- serviceName: String(input.serviceName || "").trim(),
87
- actionName: String(input.actionName || "").trim(),
88
- payloadJson,
89
- runAtMs: Math.trunc(input.runAtMs),
90
- status: "pending",
91
- error: null,
92
- createdAt: now,
93
- updatedAt: now,
94
- }).run();
95
-
96
- return {
97
- id,
150
+ const job: ScheduledJobRecord = {
151
+ id: `sched_${generateId()}`,
98
152
  serviceName: String(input.serviceName || "").trim(),
99
153
  actionName: String(input.actionName || "").trim(),
100
154
  payload: input.payload ?? null,
@@ -103,16 +157,21 @@ export class ServiceScheduleStore {
103
157
  createdAt: now,
104
158
  updatedAt: now,
105
159
  };
160
+ this.appendEvent({
161
+ v: 1,
162
+ type: "created",
163
+ job,
164
+ });
165
+ return job;
106
166
  }
107
167
 
108
168
  /**
109
169
  * 获取单个任务。
110
170
  */
111
171
  getJobById(jobId: string): ScheduledJobRecord | null {
112
- const row = this.db.select().from(scheduledJobsTable)
113
- .where(eq(scheduledJobsTable.id, String(jobId || "").trim()))
114
- .get();
115
- return row ? this.toJobRecord(row) : null;
172
+ const key = String(jobId || "").trim();
173
+ if (!key) return null;
174
+ return this.readJobMap().get(key) || null;
116
175
  }
117
176
 
118
177
  /**
@@ -120,19 +179,14 @@ export class ServiceScheduleStore {
120
179
  */
121
180
  listJobsByStatus(statuses: ScheduledJobStatus[]): ScheduledJobRecord[] {
122
181
  if (statuses.length === 0) return [];
123
- const rows = this.db.select().from(scheduledJobsTable)
124
- .where(inArray(scheduledJobsTable.status, statuses))
125
- .orderBy(asc(scheduledJobsTable.runAtMs))
126
- .all();
127
- return rows.map((row) => this.toJobRecord(row));
182
+ const allowed = new Set(statuses);
183
+ return this.readJobs()
184
+ .filter((job) => allowed.has(job.status))
185
+ .sort(compareJobs);
128
186
  }
129
187
 
130
188
  /**
131
189
  * 列出任务。
132
- *
133
- * 说明(中文)
134
- * - 默认按 `runAtMs` 升序返回,便于排查“接下来会执行什么”。
135
- * - 可选状态过滤与数量限制,避免一次输出过多记录。
136
190
  */
137
191
  listJobs(params?: {
138
192
  status?: ScheduledJobStatus;
@@ -142,75 +196,44 @@ export class ServiceScheduleStore {
142
196
  typeof params?.limit === "number" && Number.isFinite(params.limit)
143
197
  ? Math.max(1, Math.trunc(params.limit))
144
198
  : 100;
145
- const status = params?.status;
146
- const query = this.db.select().from(scheduledJobsTable);
147
- const rows =
148
- typeof status === "string" && status
149
- ? query
150
- .where(eq(scheduledJobsTable.status, status))
151
- .orderBy(asc(scheduledJobsTable.runAtMs), desc(scheduledJobsTable.createdAt))
152
- .limit(limit)
153
- .all()
154
- : query
155
- .orderBy(asc(scheduledJobsTable.runAtMs), desc(scheduledJobsTable.createdAt))
156
- .limit(limit)
157
- .all();
158
- return rows.map((row) => this.toJobRecord(row));
199
+ const jobs = this.readJobs()
200
+ .filter((job) => !params?.status || job.status === params.status)
201
+ .sort(compareJobs);
202
+ return jobs.slice(0, limit);
159
203
  }
160
204
 
161
205
  /**
162
206
  * 列出已到点且待执行的任务。
163
207
  */
164
208
  listDuePendingJobs(nowMs: number): ScheduledJobRecord[] {
165
- const rows = this.db.select().from(scheduledJobsTable)
166
- .where(
167
- and(
168
- eq(scheduledJobsTable.status, "pending"),
169
- lte(scheduledJobsTable.runAtMs, Math.trunc(nowMs)),
170
- ),
171
- )
172
- .orderBy(asc(scheduledJobsTable.runAtMs))
173
- .all();
174
- return rows.map((row) => this.toJobRecord(row));
209
+ return this.readJobs()
210
+ .filter((job) => job.status === "pending" && job.runAtMs <= Math.trunc(nowMs))
211
+ .sort(compareJobs);
175
212
  }
176
213
 
177
214
  /**
178
215
  * 启动恢复时,把历史 `running` 回退到 `pending`。
179
216
  */
180
217
  resetRunningJobsToPending(): number {
218
+ const runningJobs = this.readJobs().filter((job) => job.status === "running");
181
219
  const now = Date.now();
182
- const result = this.db.update(scheduledJobsTable)
183
- .set({
220
+ for (const job of runningJobs) {
221
+ this.appendEvent({
222
+ v: 1,
223
+ type: "status",
224
+ jobId: job.id,
184
225
  status: "pending",
185
226
  updatedAt: now,
186
- error: null,
187
- })
188
- .where(eq(scheduledJobsTable.status, "running"))
189
- .run();
190
- return Number(result.changes || 0);
227
+ });
228
+ }
229
+ return runningJobs.length;
191
230
  }
192
231
 
193
232
  /**
194
233
  * 将任务标记为执行中。
195
- *
196
- * 关键点(中文)
197
- * - 仅允许从 `pending` 进入 `running`,避免重复领取。
198
234
  */
199
235
  markJobRunning(jobId: string): boolean {
200
- const result = this.db.update(scheduledJobsTable)
201
- .set({
202
- status: "running",
203
- updatedAt: Date.now(),
204
- error: null,
205
- })
206
- .where(
207
- and(
208
- eq(scheduledJobsTable.id, String(jobId || "").trim()),
209
- eq(scheduledJobsTable.status, "pending"),
210
- ),
211
- )
212
- .run();
213
- return Number(result.changes || 0) > 0;
236
+ return this.transitionPendingJob(jobId, "running");
214
237
  }
215
238
 
216
239
  /**
@@ -246,71 +269,88 @@ export class ServiceScheduleStore {
246
269
 
247
270
  /**
248
271
  * 取消待执行任务。
249
- *
250
- * 关键点(中文)
251
- * - 仅允许取消 `pending`,避免打断已经开始执行的任务。
252
272
  */
253
273
  cancelPendingJob(jobId: string): boolean {
254
- const result = this.db.update(scheduledJobsTable)
255
- .set({
256
- status: "cancelled",
257
- updatedAt: Date.now(),
258
- error: null,
259
- })
260
- .where(
261
- and(
262
- eq(scheduledJobsTable.id, String(jobId || "").trim()),
263
- eq(scheduledJobsTable.status, "pending"),
264
- ),
265
- )
266
- .run();
267
- return Number(result.changes || 0) > 0;
274
+ return this.transitionPendingJob(jobId, "cancelled");
268
275
  }
269
276
 
270
277
  /**
271
- * 统一写入终态。
278
+ * 仅读取当前任务快照。
272
279
  */
273
- private updateTerminalStatus(params: {
274
- jobId: string;
275
- status: Exclude<ScheduledJobStatus, "pending" | "running">;
276
- error?: string;
277
- }): boolean {
278
- const result = this.db.update(scheduledJobsTable)
279
- .set({
280
- status: params.status,
281
- updatedAt: Date.now(),
282
- error: params.error ? String(params.error) : null,
283
- })
284
- .where(eq(scheduledJobsTable.id, String(params.jobId || "").trim()))
285
- .run();
286
- return Number(result.changes || 0) > 0;
280
+ private readJobs(): ScheduledJobRecord[] {
281
+ return [...this.readJobMap().values()];
287
282
  }
288
283
 
289
284
  /**
290
- * 行转业务对象。
285
+ * 重放事件流,构造当前任务快照。
291
286
  */
292
- private toJobRecord(row: ScheduledJobRow): ScheduledJobRecord {
293
- return {
294
- id: row.id,
295
- serviceName: row.serviceName,
296
- actionName: row.actionName,
297
- payload: this.parsePayloadJson(row.payloadJson),
298
- runAtMs: row.runAtMs,
299
- status: row.status as ScheduledJobStatus,
300
- ...(typeof row.error === "string" && row.error ? { error: row.error } : {}),
301
- createdAt: row.createdAt,
302
- updatedAt: row.updatedAt,
303
- };
287
+ private readJobMap(): Map<string, ScheduledJobRecord> {
288
+ const jobs = new Map<string, ScheduledJobRecord>();
289
+ for (const line of readJsonlLines(this.filePath)) {
290
+ const event = parseEvent(line);
291
+ if (!event) continue;
292
+ if (event.type === "created") {
293
+ jobs.set(event.job.id, normalizeJobRecord(event.job));
294
+ continue;
295
+ }
296
+ const current = jobs.get(event.jobId);
297
+ if (!current) continue;
298
+ jobs.set(event.jobId, {
299
+ ...current,
300
+ status: event.status,
301
+ updatedAt: event.updatedAt,
302
+ ...(event.error ? { error: event.error } : {}),
303
+ ...(event.status === "succeeded" || event.status === "cancelled"
304
+ ? { error: undefined }
305
+ : {}),
306
+ });
307
+ }
308
+ return jobs;
304
309
  }
305
310
 
306
311
  /**
307
- * 安全解析 payload JSON。
312
+ * 追加单条事件。
308
313
  */
309
- private parsePayloadJson(input: string): JsonValue {
310
- try {
311
- return JSON.parse(String(input || "null")) as JsonValue;
312
- } catch {
313
- return null;
314
+ private appendEvent(event: ScheduledJobEvent): void {
315
+ fs.appendFileSync(this.filePath, `${JSON.stringify(event)}\n`, "utf-8");
316
+ }
317
+
318
+ /**
319
+ * 执行 pending -> target 的状态迁移。
320
+ */
321
+ private transitionPendingJob(jobId: string, status: "running" | "cancelled"): boolean {
322
+ const current = this.getJobById(jobId);
323
+ if (!current || current.status !== "pending") {
324
+ return false;
314
325
  }
326
+ this.appendEvent({
327
+ v: 1,
328
+ type: "status",
329
+ jobId: current.id,
330
+ status,
331
+ updatedAt: Date.now(),
332
+ });
333
+ return true;
334
+ }
335
+
336
+ /**
337
+ * 统一写入终态。
338
+ */
339
+ private updateTerminalStatus(params: {
340
+ jobId: string;
341
+ status: Exclude<ScheduledJobStatus, "pending" | "running">;
342
+ error?: string;
343
+ }): boolean {
344
+ const current = this.getJobById(params.jobId);
345
+ if (!current) return false;
346
+ this.appendEvent({
347
+ v: 1,
348
+ type: "status",
349
+ jobId: current.id,
350
+ status: params.status,
351
+ updatedAt: Date.now(),
352
+ ...(params.error ? { error: String(params.error) } : {}),
353
+ });
354
+ return true;
315
355
  }
316
356
  }
@@ -244,6 +244,7 @@ export async function loadPluginSystemPrompts(input: {
244
244
  if (
245
245
  !isPluginEnabled({
246
246
  plugin,
247
+ context: input.context,
247
248
  })
248
249
  ) {
249
250
  continue;