@undefineds.co/xpod 0.2.45 → 0.3.1

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 (414) hide show
  1. package/dist/agents/AgentExecutorFactory.js +12 -13
  2. package/dist/agents/AgentExecutorFactory.js.map +1 -1
  3. package/dist/agents/config/agent-meta-schema.d.ts +31 -3
  4. package/dist/agents/config/agent-meta-schema.js +37 -3
  5. package/dist/agents/config/agent-meta-schema.js.map +1 -1
  6. package/dist/agents/config/index.d.ts +5 -5
  7. package/dist/agents/config/index.js +7 -6
  8. package/dist/agents/config/index.js.map +1 -1
  9. package/dist/agents/config/parse-agent-instructions.d.ts +12 -0
  10. package/dist/agents/config/parse-agent-instructions.js +23 -0
  11. package/dist/agents/config/parse-agent-instructions.js.map +1 -0
  12. package/dist/agents/config/resolve.d.ts +7 -12
  13. package/dist/agents/config/resolve.js +272 -156
  14. package/dist/agents/config/resolve.js.map +1 -1
  15. package/dist/agents/config/types.d.ts +33 -36
  16. package/dist/agents/config/types.js +4 -4
  17. package/dist/agents/config/types.js.map +1 -1
  18. package/dist/agents/index.d.ts +2 -7
  19. package/dist/agents/index.js +4 -14
  20. package/dist/agents/index.js.map +1 -1
  21. package/dist/agents/types.d.ts +2 -2
  22. package/dist/agents/types.js.map +1 -1
  23. package/dist/ai/service/CredentialReaderImpl.js +9 -14
  24. package/dist/ai/service/CredentialReaderImpl.js.map +1 -1
  25. package/dist/api/ApiServer.d.ts +7 -0
  26. package/dist/api/ApiServer.js +5 -1
  27. package/dist/api/ApiServer.js.map +1 -1
  28. package/dist/api/chatkit/default-agent.js +1 -1
  29. package/dist/api/chatkit/default-agent.js.map +1 -1
  30. package/dist/api/chatkit/index.d.ts +8 -0
  31. package/dist/api/chatkit/index.js +15 -1
  32. package/dist/api/chatkit/index.js.map +1 -1
  33. package/dist/api/chatkit/pod-store.d.ts +80 -17
  34. package/dist/api/chatkit/pod-store.js +816 -162
  35. package/dist/api/chatkit/pod-store.js.map +1 -1
  36. package/dist/api/chatkit/runtime/AcpAgentRuntime.d.ts +41 -0
  37. package/dist/api/chatkit/runtime/AcpAgentRuntime.js +573 -0
  38. package/dist/api/chatkit/runtime/AcpAgentRuntime.js.map +1 -0
  39. package/dist/api/chatkit/runtime/CodexRuntimeProjector.d.ts +27 -0
  40. package/dist/api/chatkit/runtime/CodexRuntimeProjector.js +157 -0
  41. package/dist/api/chatkit/runtime/CodexRuntimeProjector.js.map +1 -0
  42. package/dist/api/chatkit/schema.d.ts +53 -133
  43. package/dist/api/chatkit/schema.js +11 -175
  44. package/dist/api/chatkit/schema.js.map +1 -1
  45. package/dist/api/chatkit/service.d.ts +15 -9
  46. package/dist/api/chatkit/service.js +82 -234
  47. package/dist/api/chatkit/service.js.map +1 -1
  48. package/dist/api/chatkit/store.d.ts +35 -3
  49. package/dist/api/chatkit/store.js +157 -3
  50. package/dist/api/chatkit/store.js.map +1 -1
  51. package/dist/api/chatkit/types.d.ts +16 -2
  52. package/dist/api/chatkit/types.js +24 -5
  53. package/dist/api/chatkit/types.js.map +1 -1
  54. package/dist/api/container/common.js +59 -2
  55. package/dist/api/container/common.js.map +1 -1
  56. package/dist/api/container/index.js +15 -0
  57. package/dist/api/container/index.js.map +1 -1
  58. package/dist/api/container/routes.js +11 -0
  59. package/dist/api/container/routes.js.map +1 -1
  60. package/dist/api/container/types.d.ts +26 -0
  61. package/dist/api/container/types.js.map +1 -1
  62. package/dist/api/handlers/InngestHandler.d.ts +11 -0
  63. package/dist/api/handlers/InngestHandler.js +19 -0
  64. package/dist/api/handlers/InngestHandler.js.map +1 -0
  65. package/dist/api/handlers/RunHandler.d.ts +7 -0
  66. package/dist/api/handlers/RunHandler.js +169 -0
  67. package/dist/api/handlers/RunHandler.js.map +1 -0
  68. package/dist/api/handlers/index.d.ts +1 -0
  69. package/dist/api/handlers/index.js +1 -0
  70. package/dist/api/handlers/index.js.map +1 -1
  71. package/dist/api/models/namespaces.d.ts +2 -2
  72. package/dist/api/models/namespaces.js +1 -4
  73. package/dist/api/models/namespaces.js.map +1 -1
  74. package/dist/api/runs/AgentRuntimeTypes.d.ts +83 -0
  75. package/dist/api/runs/AgentRuntimeTypes.js +3 -0
  76. package/dist/api/runs/AgentRuntimeTypes.js.map +1 -0
  77. package/dist/api/runs/EmbeddedInngestService.d.ts +47 -0
  78. package/dist/api/runs/EmbeddedInngestService.js +203 -0
  79. package/dist/api/runs/EmbeddedInngestService.js.map +1 -0
  80. package/dist/api/runs/InngestRunExecutionBackend.d.ts +416 -0
  81. package/dist/api/runs/InngestRunExecutionBackend.js +225 -0
  82. package/dist/api/runs/InngestRunExecutionBackend.js.map +1 -0
  83. package/dist/api/runs/ManagedRunWorker.d.ts +52 -0
  84. package/dist/api/runs/ManagedRunWorker.js +452 -0
  85. package/dist/api/runs/ManagedRunWorker.js.map +1 -0
  86. package/dist/api/runs/PiAgentRuntimeDriver.d.ts +66 -0
  87. package/dist/api/runs/PiAgentRuntimeDriver.js +614 -0
  88. package/dist/api/runs/PiAgentRuntimeDriver.js.map +1 -0
  89. package/dist/api/runs/PiAgentRuntimeWorker.d.ts +1 -0
  90. package/dist/api/runs/PiAgentRuntimeWorker.js +33 -0
  91. package/dist/api/runs/PiAgentRuntimeWorker.js.map +1 -0
  92. package/dist/api/runs/RunAuthContextRegistry.d.ts +19 -0
  93. package/dist/api/runs/RunAuthContextRegistry.js +59 -0
  94. package/dist/api/runs/RunAuthContextRegistry.js.map +1 -0
  95. package/dist/api/runs/RunExecutionBackend.d.ts +57 -0
  96. package/dist/api/runs/RunExecutionBackend.js +3 -0
  97. package/dist/api/runs/RunExecutionBackend.js.map +1 -0
  98. package/dist/api/runs/RunStateCenter.d.ts +82 -0
  99. package/dist/api/runs/RunStateCenter.js +665 -0
  100. package/dist/api/runs/RunStateCenter.js.map +1 -0
  101. package/dist/api/runs/schema.d.ts +55 -0
  102. package/dist/api/runs/schema.js +14 -0
  103. package/dist/api/runs/schema.js.map +1 -0
  104. package/dist/api/runs/store.d.ts +105 -0
  105. package/dist/api/runs/store.js +116 -0
  106. package/dist/api/runs/store.js.map +1 -0
  107. package/dist/api/runtime.d.ts +2 -0
  108. package/dist/api/runtime.js +40 -1
  109. package/dist/api/runtime.js.map +1 -1
  110. package/dist/api/service/VectorStoreService.d.ts +1 -0
  111. package/dist/api/service/VectorStoreService.js +27 -34
  112. package/dist/api/service/VectorStoreService.js.map +1 -1
  113. package/dist/api/service/provider-registry.d.ts +1 -1
  114. package/dist/api/service/provider-registry.js +1 -1
  115. package/dist/api/service/provider-registry.js.map +1 -1
  116. package/dist/api/tasks/InngestTaskScheduler.d.ts +751 -0
  117. package/dist/api/tasks/InngestTaskScheduler.js +209 -0
  118. package/dist/api/tasks/InngestTaskScheduler.js.map +1 -0
  119. package/dist/api/tasks/TaskAuthBinding.d.ts +68 -0
  120. package/dist/api/tasks/TaskAuthBinding.js +162 -0
  121. package/dist/api/tasks/TaskAuthBinding.js.map +1 -0
  122. package/dist/api/tasks/TaskMaterializer.d.ts +55 -0
  123. package/dist/api/tasks/TaskMaterializer.js +452 -0
  124. package/dist/api/tasks/TaskMaterializer.js.map +1 -0
  125. package/dist/api/tasks/TaskService.d.ts +57 -0
  126. package/dist/api/tasks/TaskService.js +235 -0
  127. package/dist/api/tasks/TaskService.js.map +1 -0
  128. package/dist/api/tasks/index.d.ts +6 -0
  129. package/dist/api/tasks/index.js +25 -0
  130. package/dist/api/tasks/index.js.map +1 -0
  131. package/dist/api/tasks/schema.d.ts +23 -0
  132. package/dist/api/tasks/schema.js +8 -0
  133. package/dist/api/tasks/schema.js.map +1 -0
  134. package/dist/api/tasks/store.d.ts +40 -0
  135. package/dist/api/tasks/store.js +34 -0
  136. package/dist/api/tasks/store.js.map +1 -0
  137. package/dist/api/workspace/types.d.ts +3 -0
  138. package/dist/api/workspace/types.js +23 -0
  139. package/dist/api/workspace/types.js.map +1 -0
  140. package/dist/cli/commands/config.d.ts +8 -7
  141. package/dist/cli/commands/config.js +72 -48
  142. package/dist/cli/commands/config.js.map +1 -1
  143. package/dist/cli/commands/login.d.ts +10 -8
  144. package/dist/cli/commands/login.js +84 -84
  145. package/dist/cli/commands/login.js.map +1 -1
  146. package/dist/cli/index.js +3 -124
  147. package/dist/cli/index.js.map +1 -1
  148. package/dist/http/search/SearchHttpHandler.js +13 -18
  149. package/dist/http/search/SearchHttpHandler.js.map +1 -1
  150. package/dist/storage/vector/VectorIndexingListener.js +13 -18
  151. package/dist/storage/vector/VectorIndexingListener.js.map +1 -1
  152. package/dist/vocab/index.d.ts +2 -6
  153. package/dist/vocab/index.js +2 -6
  154. package/dist/vocab/index.js.map +1 -1
  155. package/dist/vocab/udfs.d.ts +12 -0
  156. package/dist/vocab/udfs.js +12 -0
  157. package/dist/vocab/udfs.js.map +1 -1
  158. package/node_modules/@undefineds.co/drizzle-solid/README.md +52 -24
  159. package/node_modules/@undefineds.co/drizzle-solid/README.zh-CN.md +30 -24
  160. package/node_modules/@undefineds.co/drizzle-solid/dist/core/discovery/types.d.ts +6 -2
  161. package/node_modules/@undefineds.co/drizzle-solid/dist/core/discovery/types.d.ts.map +1 -1
  162. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-executor.d.ts +1 -0
  163. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-executor.d.ts.map +1 -1
  164. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-executor.js +43 -10
  165. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-executor.js.map +1 -1
  166. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-strategy.d.ts.map +1 -1
  167. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-strategy.js +1 -0
  168. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-strategy.js.map +1 -1
  169. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/pod-executor.d.ts +5 -0
  170. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/pod-executor.d.ts.map +1 -1
  171. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/pod-executor.js +44 -13
  172. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/pod-executor.js.map +1 -1
  173. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/sparql-strategy.d.ts +1 -0
  174. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/sparql-strategy.d.ts.map +1 -1
  175. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/sparql-strategy.js +21 -2
  176. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/sparql-strategy.js.map +1 -1
  177. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/types.d.ts +1 -0
  178. package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/types.d.ts.map +1 -1
  179. package/node_modules/@undefineds.co/drizzle-solid/dist/core/expressions.d.ts +1 -1
  180. package/node_modules/@undefineds.co/drizzle-solid/dist/core/expressions.d.ts.map +1 -1
  181. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.d.ts +76 -41
  182. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.d.ts.map +1 -1
  183. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.js +443 -114
  184. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.js.map +1 -1
  185. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-dialect.d.ts +28 -1
  186. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-dialect.d.ts.map +1 -1
  187. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-dialect.js +142 -31
  188. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-dialect.js.map +1 -1
  189. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-session.d.ts +3 -0
  190. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-session.d.ts.map +1 -1
  191. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-session.js +84 -6
  192. package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-session.js.map +1 -1
  193. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.d.ts +3 -0
  194. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.d.ts.map +1 -1
  195. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js +29 -9
  196. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js.map +1 -1
  197. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.d.ts +2 -8
  198. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.d.ts.map +1 -1
  199. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.js +19 -51
  200. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.js.map +1 -1
  201. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/types.d.ts +1 -0
  202. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/types.d.ts.map +1 -1
  203. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-conditions.d.ts +2 -2
  204. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-conditions.d.ts.map +1 -1
  205. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-where-policy.js +6 -6
  206. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-where-policy.js.map +1 -1
  207. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts +4 -4
  208. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts.map +1 -1
  209. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js +56 -23
  210. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js.map +1 -1
  211. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/base-resolver.d.ts +14 -10
  212. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/base-resolver.d.ts.map +1 -1
  213. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/base-resolver.js +55 -23
  214. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/base-resolver.js.map +1 -1
  215. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/document-resolver.d.ts +3 -3
  216. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/document-resolver.js +6 -6
  217. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/document-resolver.js.map +1 -1
  218. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/fragment-resolver.d.ts +3 -3
  219. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/fragment-resolver.js +4 -4
  220. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-resolver/fragment-resolver.js.map +1 -1
  221. package/node_modules/@undefineds.co/drizzle-solid/dist/core/runtime/pod-runtime.d.ts.map +1 -1
  222. package/node_modules/@undefineds.co/drizzle-solid/dist/core/runtime/pod-runtime.js +33 -8
  223. package/node_modules/@undefineds.co/drizzle-solid/dist/core/runtime/pod-runtime.js.map +1 -1
  224. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/defs.d.ts +11 -2
  225. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/defs.d.ts.map +1 -1
  226. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/factories.d.ts.map +1 -1
  227. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/factories.js +3 -2
  228. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/factories.js.map +1 -1
  229. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts +13 -8
  230. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts.map +1 -1
  231. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js +24 -22
  232. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js.map +1 -1
  233. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/solid-schema.d.ts +3 -0
  234. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/solid-schema.d.ts.map +1 -1
  235. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/solid-schema.js.map +1 -1
  236. package/node_modules/@undefineds.co/drizzle-solid/dist/core/subject/resolver.d.ts +3 -2
  237. package/node_modules/@undefineds.co/drizzle-solid/dist/core/subject/resolver.d.ts.map +1 -1
  238. package/node_modules/@undefineds.co/drizzle-solid/dist/core/subject/resolver.js +28 -14
  239. package/node_modules/@undefineds.co/drizzle-solid/dist/core/subject/resolver.js.map +1 -1
  240. package/node_modules/@undefineds.co/drizzle-solid/dist/core/triple/handlers/inline.d.ts.map +1 -1
  241. package/node_modules/@undefineds.co/drizzle-solid/dist/core/triple/handlers/inline.js +3 -2
  242. package/node_modules/@undefineds.co/drizzle-solid/dist/core/triple/handlers/inline.js.map +1 -1
  243. package/node_modules/@undefineds.co/drizzle-solid/dist/core/uri/resolver.d.ts +9 -9
  244. package/node_modules/@undefineds.co/drizzle-solid/dist/core/uri/resolver.d.ts.map +1 -1
  245. package/node_modules/@undefineds.co/drizzle-solid/dist/core/uri/resolver.js +56 -22
  246. package/node_modules/@undefineds.co/drizzle-solid/dist/core/uri/resolver.js.map +1 -1
  247. package/node_modules/@undefineds.co/drizzle-solid/dist/driver.d.ts +9 -1
  248. package/node_modules/@undefineds.co/drizzle-solid/dist/driver.d.ts.map +1 -1
  249. package/node_modules/@undefineds.co/drizzle-solid/dist/driver.js +2 -0
  250. package/node_modules/@undefineds.co/drizzle-solid/dist/driver.js.map +1 -1
  251. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/discovery/types.d.ts +6 -2
  252. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/discovery/types.d.ts.map +1 -1
  253. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-executor.d.ts +1 -0
  254. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-executor.d.ts.map +1 -1
  255. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-executor.js +43 -10
  256. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-executor.js.map +1 -1
  257. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-strategy.d.ts.map +1 -1
  258. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-strategy.js +1 -0
  259. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-strategy.js.map +1 -1
  260. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/pod-executor.d.ts +5 -0
  261. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/pod-executor.d.ts.map +1 -1
  262. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/pod-executor.js +44 -13
  263. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/pod-executor.js.map +1 -1
  264. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/sparql-strategy.d.ts +1 -0
  265. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/sparql-strategy.d.ts.map +1 -1
  266. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/sparql-strategy.js +21 -2
  267. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/sparql-strategy.js.map +1 -1
  268. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/types.d.ts +1 -0
  269. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/types.d.ts.map +1 -1
  270. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/expressions.d.ts +1 -1
  271. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/expressions.d.ts.map +1 -1
  272. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.d.ts +76 -41
  273. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.d.ts.map +1 -1
  274. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.js +443 -114
  275. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.js.map +1 -1
  276. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-dialect.d.ts +28 -1
  277. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-dialect.d.ts.map +1 -1
  278. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-dialect.js +142 -31
  279. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-dialect.js.map +1 -1
  280. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-session.d.ts +3 -0
  281. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-session.d.ts.map +1 -1
  282. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-session.js +84 -6
  283. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-session.js.map +1 -1
  284. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.d.ts +3 -0
  285. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.d.ts.map +1 -1
  286. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js +29 -9
  287. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js.map +1 -1
  288. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.d.ts +2 -8
  289. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.d.ts.map +1 -1
  290. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.js +19 -51
  291. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.js.map +1 -1
  292. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/types.d.ts +1 -0
  293. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/types.d.ts.map +1 -1
  294. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-conditions.d.ts +2 -2
  295. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-conditions.d.ts.map +1 -1
  296. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-where-policy.js +6 -6
  297. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-where-policy.js.map +1 -1
  298. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts +4 -4
  299. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts.map +1 -1
  300. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js +56 -23
  301. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js.map +1 -1
  302. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/base-resolver.d.ts +14 -10
  303. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/base-resolver.d.ts.map +1 -1
  304. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/base-resolver.js +55 -23
  305. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/base-resolver.js.map +1 -1
  306. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/document-resolver.d.ts +3 -3
  307. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/document-resolver.js +6 -6
  308. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/document-resolver.js.map +1 -1
  309. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/fragment-resolver.d.ts +3 -3
  310. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/fragment-resolver.js +4 -4
  311. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-resolver/fragment-resolver.js.map +1 -1
  312. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/runtime/pod-runtime.d.ts.map +1 -1
  313. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/runtime/pod-runtime.js +33 -8
  314. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/runtime/pod-runtime.js.map +1 -1
  315. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/defs.d.ts +11 -2
  316. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/defs.d.ts.map +1 -1
  317. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/factories.d.ts.map +1 -1
  318. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/factories.js +3 -2
  319. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/factories.js.map +1 -1
  320. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts +13 -8
  321. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts.map +1 -1
  322. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js +24 -22
  323. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js.map +1 -1
  324. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/solid-schema.d.ts +3 -0
  325. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/solid-schema.d.ts.map +1 -1
  326. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/solid-schema.js.map +1 -1
  327. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/subject/resolver.d.ts +3 -2
  328. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/subject/resolver.d.ts.map +1 -1
  329. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/subject/resolver.js +28 -14
  330. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/subject/resolver.js.map +1 -1
  331. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/triple/handlers/inline.d.ts.map +1 -1
  332. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/triple/handlers/inline.js +3 -2
  333. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/triple/handlers/inline.js.map +1 -1
  334. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/uri/resolver.d.ts +9 -9
  335. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/uri/resolver.d.ts.map +1 -1
  336. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/uri/resolver.js +56 -22
  337. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/uri/resolver.js.map +1 -1
  338. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/driver.d.ts +9 -1
  339. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/driver.d.ts.map +1 -1
  340. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/driver.js +2 -0
  341. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/driver.js.map +1 -1
  342. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/pod.d.ts +16 -2
  343. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/pod.d.ts.map +1 -1
  344. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/utils/find-by-iri.js +1 -1
  345. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/utils/find-by-iri.js.map +1 -1
  346. package/node_modules/@undefineds.co/drizzle-solid/dist/pod.d.ts +16 -2
  347. package/node_modules/@undefineds.co/drizzle-solid/dist/pod.d.ts.map +1 -1
  348. package/node_modules/@undefineds.co/drizzle-solid/dist/utils/find-by-iri.js +1 -1
  349. package/node_modules/@undefineds.co/drizzle-solid/dist/utils/find-by-iri.js.map +1 -1
  350. package/node_modules/@undefineds.co/drizzle-solid/package.json +1 -1
  351. package/package.json +9 -3
  352. package/dist/agents/AgentManager.d.ts +0 -116
  353. package/dist/agents/AgentManager.js +0 -290
  354. package/dist/agents/AgentManager.js.map +0 -1
  355. package/dist/agents/IndexAgent.d.ts +0 -70
  356. package/dist/agents/IndexAgent.js +0 -417
  357. package/dist/agents/IndexAgent.js.map +0 -1
  358. package/dist/agents/config/parse-agent-md.d.ts +0 -33
  359. package/dist/agents/config/parse-agent-md.js +0 -75
  360. package/dist/agents/config/parse-agent-md.js.map +0 -1
  361. package/dist/agents/schema/agent-config.d.ts +0 -2
  362. package/dist/agents/schema/agent-config.js +0 -32
  363. package/dist/agents/schema/agent-config.js.map +0 -1
  364. package/dist/agents/schema/create-agent-schema.d.ts +0 -25
  365. package/dist/agents/schema/create-agent-schema.js +0 -35
  366. package/dist/agents/schema/create-agent-schema.js.map +0 -1
  367. package/dist/api/chatkit/runtime/PtyThreadRuntime.d.ts +0 -127
  368. package/dist/api/chatkit/runtime/PtyThreadRuntime.js +0 -791
  369. package/dist/api/chatkit/runtime/PtyThreadRuntime.js.map +0 -1
  370. package/dist/cli/lib/agent-session.d.ts +0 -37
  371. package/dist/cli/lib/agent-session.js +0 -211
  372. package/dist/cli/lib/agent-session.js.map +0 -1
  373. package/dist/cli/lib/ensure-ai-credentials.d.ts +0 -13
  374. package/dist/cli/lib/ensure-ai-credentials.js +0 -40
  375. package/dist/cli/lib/ensure-ai-credentials.js.map +0 -1
  376. package/dist/cli/lib/model-manager.d.ts +0 -37
  377. package/dist/cli/lib/model-manager.js +0 -251
  378. package/dist/cli/lib/model-manager.js.map +0 -1
  379. package/dist/cli/lib/oauth-credential-manager.d.ts +0 -37
  380. package/dist/cli/lib/oauth-credential-manager.js +0 -129
  381. package/dist/cli/lib/oauth-credential-manager.js.map +0 -1
  382. package/dist/cli/lib/oauth-providers/codebuddy.d.ts +0 -25
  383. package/dist/cli/lib/oauth-providers/codebuddy.js +0 -69
  384. package/dist/cli/lib/oauth-providers/codebuddy.js.map +0 -1
  385. package/dist/cli/lib/oauth-providers/index.d.ts +0 -12
  386. package/dist/cli/lib/oauth-providers/index.js +0 -23
  387. package/dist/cli/lib/oauth-providers/index.js.map +0 -1
  388. package/dist/cli/lib/pi-optional.d.ts +0 -84
  389. package/dist/cli/lib/pi-optional.js +0 -35
  390. package/dist/cli/lib/pi-optional.js.map +0 -1
  391. package/dist/cli/lib/pod-ai-config.d.ts +0 -26
  392. package/dist/cli/lib/pod-ai-config.js +0 -99
  393. package/dist/cli/lib/pod-ai-config.js.map +0 -1
  394. package/dist/cli/lib/pod-thread-store.d.ts +0 -57
  395. package/dist/cli/lib/pod-thread-store.js +0 -312
  396. package/dist/cli/lib/pod-thread-store.js.map +0 -1
  397. package/dist/cli/lib/secretary-prompt.d.ts +0 -6
  398. package/dist/cli/lib/secretary-prompt.js +0 -85
  399. package/dist/cli/lib/secretary-prompt.js.map +0 -1
  400. package/dist/task/DrizzleTaskQueue.d.ts +0 -56
  401. package/dist/task/DrizzleTaskQueue.js +0 -171
  402. package/dist/task/DrizzleTaskQueue.js.map +0 -1
  403. package/dist/task/TaskExecutor.d.ts +0 -82
  404. package/dist/task/TaskExecutor.js +0 -198
  405. package/dist/task/TaskExecutor.js.map +0 -1
  406. package/dist/task/index.d.ts +0 -10
  407. package/dist/task/index.js +0 -20
  408. package/dist/task/index.js.map +0 -1
  409. package/dist/task/schema.d.ts +0 -53
  410. package/dist/task/schema.js +0 -71
  411. package/dist/task/schema.js.map +0 -1
  412. package/dist/task/types.d.ts +0 -186
  413. package/dist/task/types.js +0 -12
  414. package/dist/task/types.js.map +0 -1
@@ -7,7 +7,7 @@ exports.PodChatKitStore = void 0;
7
7
  * 将 ChatKit 数据存储到 Solid Pod。
8
8
  *
9
9
  * 存储结构:
10
- * /.data/chat/{chatId}/
10
+ * /.data/{chat|task}/{surfaceId}/
11
11
  * index.ttl
12
12
  * #this # Chat (meeting:LongChat)
13
13
  * #{threadId} # Thread (sioc:Thread)
@@ -17,15 +17,24 @@ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
17
17
  const global_logger_factory_1 = require("global-logger-factory");
18
18
  const types_1 = require("./types");
19
19
  const schema_1 = require("./schema");
20
+ const schema_2 = require("../runs/schema");
21
+ const store_1 = require("../runs/store");
22
+ const schema_3 = require("../tasks/schema");
23
+ const store_2 = require("../tasks/store");
24
+ const TaskAuthBinding_1 = require("../tasks/TaskAuthBinding");
20
25
  const AuthContext_1 = require("../auth/AuthContext");
21
26
  const provider_1 = require("../../ai/schema/provider");
22
27
  const model_1 = require("../../ai/schema/model");
23
28
  const tables_1 = require("../../credential/schema/tables");
24
29
  const types_2 = require("../../credential/schema/types");
30
+ const models_1 = require("@undefineds.co/models");
25
31
  const schema = {
26
32
  chat: schema_1.Chat,
27
33
  thread: schema_1.Thread,
28
34
  message: schema_1.Message,
35
+ run: schema_2.Run,
36
+ runStep: schema_2.RunStep,
37
+ task: schema_3.Task,
29
38
  provider: provider_1.Provider,
30
39
  model: model_1.Model,
31
40
  credential: tables_1.Credential,
@@ -36,7 +45,7 @@ const schema = {
36
45
  * 数据模型映射:
37
46
  * - ChatKit thread = Thread (sioc:Thread)
38
47
  * - ChatKit thread item = Message (meeting:Message)
39
- * - Chat (meeting:LongChat) 是容器/Agent,通过 metadata.chat_id 暴露
48
+ * - ChatKit 协议里的 chat_id 在内部映射为 surfaceId
40
49
  *
41
50
  * 每个 Thread 属于一个 Chat 容器。默认使用 'default' Chat。
42
51
  */
@@ -75,7 +84,7 @@ class PodChatKitStore {
75
84
  const db = (0, drizzle_solid_1.drizzle)({ fetch: authFetch, info: { webId: auth.webId, isLoggedIn: true } }, { schema });
76
85
  this.logger.info(`Initializing tables for Pod (access token): ${auth.webId}`);
77
86
  try {
78
- await db.init(schema_1.Chat, schema_1.Thread, schema_1.Message);
87
+ await db.init(schema_1.Chat, schema_1.Thread, schema_1.Message, schema_2.Run, schema_2.RunStep, schema_3.Task, tables_1.Credential);
79
88
  this.logger.info('Tables initialized successfully');
80
89
  }
81
90
  catch (initError) {
@@ -108,7 +117,7 @@ class PodChatKitStore {
108
117
  const authFetch = this.createAccessTokenFetch(token.accessToken, token.tokenType);
109
118
  this.logger.info(`Initializing tables for Pod: ${webId}`);
110
119
  try {
111
- await db.init(schema_1.Chat, schema_1.Thread, schema_1.Message);
120
+ await db.init(schema_1.Chat, schema_1.Thread, schema_1.Message, schema_2.Run, schema_2.RunStep, schema_3.Task, tables_1.Credential);
112
121
  this.logger.info('Tables initialized successfully');
113
122
  }
114
123
  catch (initError) {
@@ -228,15 +237,53 @@ class PodChatKitStore {
228
237
  return { type: 'active' };
229
238
  }
230
239
  }
231
- /**
232
- * 从 ThreadMetadata.metadata 中获取 chat_id,如果没有则返回默认值
233
- */
234
- getChatIdFromMetadata(metadata) {
240
+ getCommandKindFromMetadata(metadata) {
241
+ return metadata?.commandKind === 'task' ? 'task' : 'chat';
242
+ }
243
+ getSurfaceIdFromMetadata(metadata) {
244
+ if (metadata && typeof metadata.surface_id === 'string') {
245
+ return metadata.surface_id;
246
+ }
235
247
  if (metadata && typeof metadata.chat_id === 'string') {
236
248
  return metadata.chat_id;
237
249
  }
238
250
  return PodChatKitStore.DEFAULT_CHAT_ID;
239
251
  }
252
+ isBaseRelativeChatResourceId(value) {
253
+ return typeof value === 'string'
254
+ && !/^https?:\/\//.test(value)
255
+ && !value.startsWith('/')
256
+ && /^[^/]+\/index\.ttl#this$/.test(value);
257
+ }
258
+ buildChatResourceId(chatId) {
259
+ if (this.isBaseRelativeChatResourceId(chatId)) {
260
+ return chatId;
261
+ }
262
+ return `${chatId.replace(/^#/, '')}/index.ttl#this`;
263
+ }
264
+ chatSurfaceIdFromResourceId(chatId) {
265
+ if (!chatId) {
266
+ return undefined;
267
+ }
268
+ const match = chatId.match(/^([^/]+)\/index\.ttl#this$/);
269
+ return match ? decodeURIComponent(match[1]) : undefined;
270
+ }
271
+ chatSurfaceIdFromIri(chatIri) {
272
+ if (!chatIri) {
273
+ return undefined;
274
+ }
275
+ try {
276
+ const url = new URL(chatIri);
277
+ const match = url.pathname.match(/\/\.data\/chat\/([^/]+)\/index\.ttl$/);
278
+ if (match && url.hash === '#this') {
279
+ return decodeURIComponent(match[1]);
280
+ }
281
+ }
282
+ catch {
283
+ // Fall through to base-relative parsing.
284
+ }
285
+ return this.chatSurfaceIdFromResourceId(chatIri);
286
+ }
240
287
  /**
241
288
  * 确保 Chat 容器存在,如果不存在则创建
242
289
  */
@@ -246,49 +293,258 @@ class PodChatKitStore {
246
293
  throw new Error('Cannot access Pod: invalid credentials');
247
294
  }
248
295
  const webId = this.getWebId(context);
296
+ const chatResourceId = this.buildChatResourceId(chatId);
297
+ const surfaceId = this.chatSurfaceIdFromResourceId(chatResourceId) ?? chatId;
249
298
  // 检查是否存在
250
- const existing = await db.findByLocator(schema_1.Chat, { id: chatId });
299
+ const existing = await db.findById(schema_1.Chat, chatResourceId);
251
300
  if (!existing) {
252
301
  // 创建 Chat 容器
253
302
  const now = new Date().toISOString();
254
303
  await db.insert(schema_1.Chat).values({
255
- id: chatId,
256
- title: chatId === PodChatKitStore.DEFAULT_CHAT_ID ? 'Default Chat' : chatId,
304
+ id: chatResourceId,
305
+ title: surfaceId === PodChatKitStore.DEFAULT_CHAT_ID ? 'Default Chat' : surfaceId,
257
306
  author: webId || null,
258
307
  status: 'active',
259
308
  createdAt: now,
260
309
  updatedAt: now,
261
310
  });
262
- this.logger.info(`Created Chat container: ${chatId}`);
311
+ this.logger.info(`Created Chat container: ${surfaceId}`);
263
312
  }
264
313
  }
265
314
  /**
266
315
  * 将 ThreadRecord 转为 ThreadMetadata
267
- * 包含 metadata.chat_id 暴露 Chat 容器 ID
316
+ * ChatKit 边界继续暴露 metadata.chat_id;内部同一值叫 surface_id。
268
317
  */
269
318
  threadRecordToMetadata(record, chatUriMap) {
270
- const chatId = this.resolveChatIdFromUri(record.chatId, chatUriMap, PodChatKitStore.DEFAULT_CHAT_ID);
271
- let extra;
272
- if (record.metadata) {
273
- try {
274
- extra = JSON.parse(record.metadata);
275
- }
276
- catch {
277
- // ignore invalid metadata
278
- }
279
- }
319
+ const commandKind = record.commandKind === 'task' ? 'task' : 'chat';
320
+ const surfaceId = record.surfaceId || this.resolveChatSurfaceFromUri(record.chat, chatUriMap, PodChatKitStore.DEFAULT_CHAT_ID);
321
+ const extra = this.parseJsonObject(record.metadata);
280
322
  return {
281
323
  id: record.id,
282
324
  title: record.title || undefined,
283
325
  status: this.stringToStatus(record.status),
326
+ workspace: record.workspace || undefined,
284
327
  created_at: record.createdAt ? Math.floor(new Date(record.createdAt).getTime() / 1000) : (0, types_1.nowTimestamp)(),
285
328
  updated_at: record.updatedAt ? Math.floor(new Date(record.updatedAt).getTime() / 1000) : (0, types_1.nowTimestamp)(),
286
329
  metadata: {
287
- chat_id: chatId,
288
330
  ...(extra ?? {}),
331
+ chat_id: surfaceId,
332
+ commandKind,
333
+ surface_id: surfaceId,
289
334
  },
290
335
  };
291
336
  }
337
+ timestampToIso(timestamp) {
338
+ return typeof timestamp === 'number' ? new Date(timestamp * 1000).toISOString() : null;
339
+ }
340
+ isoToTimestamp(value) {
341
+ if (!value) {
342
+ return undefined;
343
+ }
344
+ const date = value instanceof Date ? value : new Date(value);
345
+ const time = date.getTime();
346
+ return Number.isNaN(time) ? undefined : Math.floor(time / 1000);
347
+ }
348
+ parseJsonObject(value) {
349
+ if (!value) {
350
+ return undefined;
351
+ }
352
+ if (typeof value === 'object' && !Array.isArray(value)) {
353
+ return value;
354
+ }
355
+ if (typeof value !== 'string') {
356
+ return undefined;
357
+ }
358
+ try {
359
+ const parsed = JSON.parse(value);
360
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
361
+ ? parsed
362
+ : undefined;
363
+ }
364
+ catch {
365
+ return undefined;
366
+ }
367
+ }
368
+ jsonObjectOrNull(value) {
369
+ return value && Object.keys(value).length > 0 ? value : null;
370
+ }
371
+ withTaskAuthBindingMetadata(metadata, authBinding) {
372
+ if (!authBinding) {
373
+ return metadata;
374
+ }
375
+ return {
376
+ ...(metadata ?? {}),
377
+ authBinding,
378
+ };
379
+ }
380
+ parseTaskAuthBinding(value) {
381
+ if (!value || typeof value !== 'object') {
382
+ return undefined;
383
+ }
384
+ const candidate = value;
385
+ if (typeof candidate.id !== 'string'
386
+ || typeof candidate.kind !== 'string'
387
+ || typeof candidate.webId !== 'string'
388
+ || typeof candidate.clientId !== 'string'
389
+ || typeof candidate.status !== 'string'
390
+ || typeof candidate.createdAt !== 'number') {
391
+ return undefined;
392
+ }
393
+ return {
394
+ id: candidate.id,
395
+ kind: candidate.kind,
396
+ webId: candidate.webId,
397
+ clientId: candidate.clientId,
398
+ displayName: typeof candidate.displayName === 'string' ? candidate.displayName : undefined,
399
+ status: candidate.status,
400
+ createdAt: candidate.createdAt,
401
+ expiresAt: typeof candidate.expiresAt === 'number' ? candidate.expiresAt : undefined,
402
+ };
403
+ }
404
+ isBaseRelativeDataResourceId(value) {
405
+ return typeof value === 'string'
406
+ && !/^https?:\/\//.test(value)
407
+ && !value.startsWith('/')
408
+ && value.includes('#')
409
+ && !value.startsWith('#');
410
+ }
411
+ isResourceLikeId(value) {
412
+ return typeof value === 'string'
413
+ && !/^https?:\/\//.test(value)
414
+ && !value.startsWith('/')
415
+ && !value.startsWith('#')
416
+ && (value.includes('/') || /\.ttl(?:#|$)/i.test(value) || value.includes('#'));
417
+ }
418
+ isThreadResourceId(value) {
419
+ return typeof value === 'string'
420
+ && /^(chat|task)\/[^/]+\/index\.ttl#[^#/]+$/.test(value);
421
+ }
422
+ isMessageResourceId(value) {
423
+ return typeof value === 'string'
424
+ && /^(chat|task)\/[^/]+\/\d{4}\/\d{2}\/\d{2}\/messages\.ttl#[^#/]+$/.test(value);
425
+ }
426
+ buildThreadResourceId(input) {
427
+ void input.commandKind;
428
+ void input.surfaceId;
429
+ if (!this.isThreadResourceId(input.id)) {
430
+ throw new Error(`Thread id must be a complete Thread resource id: ${input.id}`);
431
+ }
432
+ return input.id;
433
+ }
434
+ generateThreadResourceId(input) {
435
+ if ((0, store_1.isBaseRelativeResourceId)(input.key)) {
436
+ throw new Error(`Thread id generator requires a local key, got resource id: ${input.key}`);
437
+ }
438
+ if (this.isResourceLikeId(input.key)) {
439
+ throw new Error(`Thread id generator requires a local key: ${input.key}`);
440
+ }
441
+ return `${input.commandKind}/${input.surfaceId}/index.ttl#${(0, store_1.extractResourceLocalId)(input.key)}`;
442
+ }
443
+ buildMessageResourceId(input) {
444
+ void input.commandKind;
445
+ void input.surfaceId;
446
+ void input.createdAt;
447
+ if (!this.isMessageResourceId(input.id)) {
448
+ throw new Error(`Message id must be a complete Message resource id: ${input.id}`);
449
+ }
450
+ return input.id;
451
+ }
452
+ generateMessageResourceId(input) {
453
+ if ((0, store_1.isBaseRelativeResourceId)(input.key)) {
454
+ throw new Error(`Message id generator requires a local key, got resource id: ${input.key}`);
455
+ }
456
+ if (this.isResourceLikeId(input.key)) {
457
+ throw new Error(`Message id generator requires a local key: ${input.key}`);
458
+ }
459
+ const { yyyy, MM, dd } = this.datePathFromTimestamp(input.createdAt);
460
+ return `${input.commandKind}/${input.surfaceId}/${yyyy}/${MM}/${dd}/messages.ttl#${(0, store_1.extractResourceLocalId)(input.key)}`;
461
+ }
462
+ resolveDataResourceUriFromId(resourceId, context) {
463
+ if (/^https?:\/\//.test(resourceId)) {
464
+ return resourceId;
465
+ }
466
+ const podBaseUrl = this.getCachedPodBaseUrl(context)
467
+ ?? this.derivePodBaseUrl(this.getWebId(context));
468
+ if (!podBaseUrl) {
469
+ throw new Error(`Cannot resolve Pod base URL for resource id: ${resourceId}`);
470
+ }
471
+ return (0, store_1.resolveDataResourceIri)(podBaseUrl, resourceId);
472
+ }
473
+ baseRelativeIdFromSubjectUri(subjectUri, context) {
474
+ const podBaseUrl = this.getCachedPodBaseUrl(context)
475
+ ?? this.derivePodBaseUrl(this.getWebId(context));
476
+ if (podBaseUrl) {
477
+ const dataPrefix = `${podBaseUrl.replace(/\/$/, '')}/.data/`;
478
+ if (subjectUri.startsWith(dataPrefix)) {
479
+ return subjectUri.slice(dataPrefix.length);
480
+ }
481
+ }
482
+ const marker = '/.data/';
483
+ const markerIndex = subjectUri.indexOf(marker);
484
+ if (markerIndex >= 0) {
485
+ return subjectUri.slice(markerIndex + marker.length);
486
+ }
487
+ return subjectUri;
488
+ }
489
+ runRecordToData(record) {
490
+ return {
491
+ id: record.id || '',
492
+ surfaceId: record.surfaceId || 'default',
493
+ task: record.task || undefined,
494
+ thread: record.thread || '',
495
+ workspace: record.workspace || '',
496
+ commandKind: record.commandKind === 'task' ? 'task' : 'chat',
497
+ status: (record.status || 'queued'),
498
+ runner: record.runner || '',
499
+ prompt: record.prompt || undefined,
500
+ externalRunId: record.externalRunId || undefined,
501
+ leaseOwner: record.leaseOwner || undefined,
502
+ leaseExpiresAt: this.isoToTimestamp(record.leaseExpiresAt),
503
+ heartbeatAt: this.isoToTimestamp(record.heartbeatAt),
504
+ cancelRequestedAt: this.isoToTimestamp(record.cancelRequestedAt),
505
+ error: record.error || undefined,
506
+ metadata: this.parseJsonObject(record.metadata),
507
+ createdAt: this.isoToTimestamp(record.createdAt) ?? (0, types_1.nowTimestamp)(),
508
+ startedAt: this.isoToTimestamp(record.startedAt),
509
+ completedAt: this.isoToTimestamp(record.completedAt),
510
+ updatedAt: this.isoToTimestamp(record.updatedAt) ?? (0, types_1.nowTimestamp)(),
511
+ };
512
+ }
513
+ runStepRecordToData(record) {
514
+ return {
515
+ id: record.id || '',
516
+ commandKind: record.commandKind === 'task' ? 'task' : 'chat',
517
+ surfaceId: record.surfaceId || 'default',
518
+ runId: record.runId || '',
519
+ run: record.run || '',
520
+ type: record.type || 'runtime.event',
521
+ message: record.message || undefined,
522
+ data: this.parseJsonObject(record.data),
523
+ createdAt: this.isoToTimestamp(record.createdAt) ?? (0, types_1.nowTimestamp)(),
524
+ };
525
+ }
526
+ taskRecordToData(record) {
527
+ return {
528
+ id: record.id || '',
529
+ surfaceId: record.surfaceId || 'default',
530
+ title: record.title || undefined,
531
+ prompt: record.prompt || '',
532
+ thread: record.thread || '',
533
+ workspace: record.workspace || '',
534
+ runner: record.runner || '',
535
+ status: (record.status || 'active'),
536
+ triggerKind: (record.triggerKind || 'once'),
537
+ cron: record.cron || undefined,
538
+ intervalSeconds: typeof record.intervalSeconds === 'number' ? record.intervalSeconds : undefined,
539
+ eventName: record.eventName || undefined,
540
+ nextRunAt: this.isoToTimestamp(record.nextRunAt),
541
+ lastRunAt: this.isoToTimestamp(record.lastRunAt),
542
+ authBinding: this.parseTaskAuthBinding(this.parseJsonObject(record.metadata)?.authBinding),
543
+ metadata: this.parseJsonObject(record.metadata),
544
+ createdAt: this.isoToTimestamp(record.createdAt) ?? (0, types_1.nowTimestamp)(),
545
+ updatedAt: this.isoToTimestamp(record.updatedAt) ?? (0, types_1.nowTimestamp)(),
546
+ };
547
+ }
292
548
  /**
293
549
  * 将 MessageRecord 转为 ThreadItem
294
550
  * thread_id 返回 Message 所属的 Thread ID
@@ -304,7 +560,22 @@ class PodChatKitStore {
304
560
  created_at: createdAt,
305
561
  };
306
562
  }
307
- else {
563
+ if (record.role === schema_1.MessageRole.SYSTEM && record.toolName) {
564
+ const metadata = this.parseJsonObject(record.metadata) ?? {};
565
+ return {
566
+ id: record.id,
567
+ thread_id: threadId,
568
+ type: 'client_tool_call',
569
+ name: record.toolName,
570
+ arguments: typeof metadata.arguments === 'string' ? metadata.arguments : '',
571
+ call_id: record.toolCallId || '',
572
+ status: (record.status === 'completed' ? 'completed' : 'pending'),
573
+ output: typeof metadata.output === 'string' ? metadata.output : undefined,
574
+ metadata,
575
+ created_at: createdAt,
576
+ };
577
+ }
578
+ {
308
579
  return {
309
580
  id: record.id,
310
581
  thread_id: threadId,
@@ -316,8 +587,8 @@ class PodChatKitStore {
316
587
  }
317
588
  }
318
589
  /**
319
- * 获取或构建 chatUri bare chatId 的映射缓存。
320
- * drizzle-solid 的 uri() 字段返回完整 URI,通过 Chat 的 @id 比对来还原 bare ID。
590
+ * 获取或构建 Chat IRI -> surface id 的映射缓存。
591
+ * drizzle-solid 的 uri().link(Chat) 字段返回完整 URI,通过 Chat 的 @id 比对还原路径槽位。
321
592
  */
322
593
  async getChatUriMap(context) {
323
594
  if (context._chatUriMap) {
@@ -330,8 +601,9 @@ class PodChatKitStore {
330
601
  const chats = await db.select().from(schema_1.Chat);
331
602
  for (const c of chats) {
332
603
  const uri = c['@id'];
604
+ const surfaceId = this.chatSurfaceIdFromResourceId(c.id) ?? c.id;
333
605
  if (uri)
334
- map.set(uri, c.id);
606
+ map.set(uri, surfaceId);
335
607
  }
336
608
  }
337
609
  catch {
@@ -342,17 +614,19 @@ class PodChatKitStore {
342
614
  return map;
343
615
  }
344
616
  /**
345
- * 从 chatId URI 还原 bare chatId
346
- * 优先通过 @id 映射,fallback 处理裸 ID
617
+ * 从 Chat URI 还原 surface id
618
+ * 优先通过 @id 映射;若调用方本来给的是裸 ID,则原样使用。
347
619
  */
348
- resolveChatIdFromUri(chatIdUri, chatUriMap, fallback) {
349
- if (!chatIdUri)
350
- return fallback;
351
- const bare = chatUriMap.get(chatIdUri);
620
+ resolveChatSurfaceFromUri(chatUri, chatUriMap, defaultSurfaceId) {
621
+ if (!chatUri)
622
+ return defaultSurfaceId;
623
+ const bare = chatUriMap.get(chatUri);
352
624
  if (bare)
353
625
  return bare;
354
- // Bare ID passed directly (not a URI)
355
- return chatIdUri.includes('/') ? fallback : chatIdUri;
626
+ const parsed = this.chatSurfaceIdFromIri(chatUri);
627
+ if (parsed)
628
+ return parsed;
629
+ return chatUri.includes('/') ? defaultSurfaceId : chatUri;
356
630
  }
357
631
  isAbsoluteHttpIri(value) {
358
632
  try {
@@ -366,14 +640,17 @@ class PodChatKitStore {
366
640
  parseThreadIri(threadIri) {
367
641
  try {
368
642
  const url = new URL(threadIri);
369
- const match = url.pathname.match(/\/\.data\/chat\/([^/]+)\/index\.ttl$/);
370
- const threadId = url.hash.startsWith('#') ? decodeURIComponent(url.hash.slice(1)) : '';
371
- if (!match || !threadId) {
643
+ const match = url.pathname.match(/\/\.data\/(chat|task)\/([^/]+)\/index\.ttl$/);
644
+ const localThreadId = url.hash.startsWith('#') ? decodeURIComponent(url.hash.slice(1)) : '';
645
+ if (!match || !localThreadId) {
372
646
  return null;
373
647
  }
648
+ const commandKind = match[1] === 'task' ? 'task' : 'chat';
649
+ const surfaceId = decodeURIComponent(match[2]);
374
650
  return {
375
- threadId,
376
- chatId: decodeURIComponent(match[1]),
651
+ threadId: `${commandKind}/${surfaceId}/index.ttl#${localThreadId}`,
652
+ commandKind,
653
+ surfaceId,
377
654
  threadUri: url.toString(),
378
655
  };
379
656
  }
@@ -384,14 +661,18 @@ class PodChatKitStore {
384
661
  normalizeThreadCacheKey(thread) {
385
662
  return (0, types_1.getThreadIdFromRef)(thread);
386
663
  }
387
- async buildThreadUri(threadId, chatId, context) {
388
- await this.getDb(context);
389
- const podBaseUrl = this.getCachedPodBaseUrl(context)
390
- ?? this.derivePodBaseUrl(this.getWebId(context));
391
- if (!podBaseUrl) {
392
- throw new Error('Cannot resolve Pod base URL for thread locator');
664
+ parseThreadResourceId(threadId) {
665
+ const match = threadId.match(/^(chat|task)\/([^/]+)\/index\.ttl#(.+)$/);
666
+ if (!match) {
667
+ return null;
393
668
  }
394
- return `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;
669
+ const commandKind = match[1] === 'task' ? 'task' : 'chat';
670
+ const surfaceId = decodeURIComponent(match[2]);
671
+ return {
672
+ threadId,
673
+ commandKind,
674
+ surfaceId,
675
+ };
395
676
  }
396
677
  async resolveThreadRef(thread, context) {
397
678
  const threadIdOrIri = thread.thread_id;
@@ -400,29 +681,45 @@ class PodChatKitStore {
400
681
  if (!parsed) {
401
682
  throw new Error(`Invalid thread IRI: ${threadIdOrIri}`);
402
683
  }
403
- this.cacheThreadChatId(context, parsed.threadId, parsed.chatId);
684
+ this.cacheThreadSurfaceId(context, parsed.threadId, parsed.surfaceId);
404
685
  return parsed;
405
686
  }
406
- if (!('chat_id' in thread) || !thread.chat_id) {
407
- throw new Error(`chat_id is required when thread_id "${threadIdOrIri}" is not a full thread IRI`);
687
+ const parsedResourceId = this.parseThreadResourceId(threadIdOrIri);
688
+ if (parsedResourceId) {
689
+ const threadUri = this.resolveDataResourceUriFromId(parsedResourceId.threadId, context);
690
+ this.cacheThreadSurfaceId(context, parsedResourceId.threadId, parsedResourceId.surfaceId);
691
+ return {
692
+ ...parsedResourceId,
693
+ threadUri,
694
+ };
408
695
  }
409
- const chatId = thread.chat_id;
410
- const threadUri = await this.buildThreadUri(threadIdOrIri, chatId, context);
411
- this.cacheThreadChatId(context, threadIdOrIri, chatId);
696
+ if (!('chat_id' in thread) || !thread.chat_id) {
697
+ throw new Error(`chat_id is required when thread_id "${threadIdOrIri}" is not a full thread resource id`);
698
+ }
699
+ const surfaceId = thread.chat_id;
700
+ const commandKind = 'chat';
701
+ const threadId = this.generateThreadResourceId({
702
+ key: threadIdOrIri,
703
+ commandKind,
704
+ surfaceId,
705
+ });
706
+ const threadUri = this.resolveDataResourceUriFromId(threadId, context);
707
+ this.cacheThreadSurfaceId(context, threadId, surfaceId);
412
708
  return {
413
- threadId: threadIdOrIri,
414
- chatId,
709
+ threadId,
710
+ commandKind,
711
+ surfaceId,
415
712
  threadUri,
416
713
  };
417
714
  }
418
715
  /**
419
- * 缓存 Thread -> chatId 映射
716
+ * 缓存 Thread -> surfaceId 映射
420
717
  */
421
- cacheThreadChatId(context, threadId, chatId) {
422
- if (!context._threadChatIdCache) {
423
- context._threadChatIdCache = new Map();
718
+ cacheThreadSurfaceId(context, threadId, surfaceId) {
719
+ if (!context._threadSurfaceIdCache) {
720
+ context._threadSurfaceIdCache = new Map();
424
721
  }
425
- context._threadChatIdCache.set(threadId, chatId);
722
+ context._threadSurfaceIdCache.set(threadId, surfaceId);
426
723
  }
427
724
  /**
428
725
  * 缓存完整的 Thread metadata
@@ -447,14 +744,6 @@ class PodChatKitStore {
447
744
  const cachedWebId = context._cachedWebId;
448
745
  return this.derivePodBaseUrl(cachedWebId);
449
746
  }
450
- extractFragmentId(subjectUri) {
451
- const hashIndex = subjectUri.lastIndexOf('#');
452
- if (hashIndex >= 0 && hashIndex < subjectUri.length - 1) {
453
- return subjectUri.slice(hashIndex + 1);
454
- }
455
- const slashIndex = subjectUri.lastIndexOf('/');
456
- return slashIndex >= 0 && slashIndex < subjectUri.length - 1 ? subjectUri.slice(slashIndex + 1) : subjectUri;
457
- }
458
747
  parseSparqlBindingValue(binding, key) {
459
748
  return binding?.[key]?.value ?? null;
460
749
  }
@@ -471,16 +760,20 @@ class PodChatKitStore {
471
760
  PREFIX meeting: <http://www.w3.org/ns/pim/meeting#>
472
761
  PREFIX sioc: <http://rdfs.org/sioc/ns#>
473
762
  PREFIX foaf: <http://xmlns.com/foaf/0.1/>
763
+ PREFIX dcterms: <http://purl.org/dc/terms/>
474
764
  PREFIX udfs: <https://undefineds.co/ns#>
475
- SELECT ?msg ?maker ?role ?content ?status ?createdAt ?toolName ?toolCallId ?metadata
765
+ SELECT ?msg ?maker ?messageType ?legacyRole ?content ?messageStatus ?legacyStatus ?createdAt ?legacyCreatedAt ?toolName ?toolCallId ?metadata
476
766
  WHERE {
477
767
  ?msg a meeting:Message ;
478
768
  sioc:has_container <${resolvedThread.threadUri}> .
479
769
  OPTIONAL { ?msg foaf:maker ?maker . }
480
- OPTIONAL { ?msg udfs:role ?role . }
770
+ OPTIONAL { ?msg udfs:messageType ?messageType . }
771
+ OPTIONAL { ?msg udfs:role ?legacyRole . }
481
772
  OPTIONAL { ?msg sioc:content ?content . }
482
- OPTIONAL { ?msg udfs:status ?status . }
483
- OPTIONAL { ?msg udfs:createdAt ?createdAt . }
773
+ OPTIONAL { ?msg udfs:messageStatus ?messageStatus . }
774
+ OPTIONAL { ?msg udfs:status ?legacyStatus . }
775
+ OPTIONAL { ?msg dcterms:created ?createdAt . }
776
+ OPTIONAL { ?msg udfs:createdAt ?legacyCreatedAt . }
484
777
  OPTIONAL { ?msg udfs:toolName ?toolName . }
485
778
  OPTIONAL { ?msg udfs:toolCallId ?toolCallId . }
486
779
  OPTIONAL { ?msg udfs:metadata ?metadata . }
@@ -502,28 +795,46 @@ class PodChatKitStore {
502
795
  const json = await response.json();
503
796
  const bindings = json.results?.bindings ?? [];
504
797
  return bindings.map((binding) => ({
505
- id: this.extractFragmentId(this.parseSparqlBindingValue(binding, 'msg') ?? ''),
798
+ id: this.baseRelativeIdFromSubjectUri(this.parseSparqlBindingValue(binding, 'msg') ?? '', context),
506
799
  chat: null,
507
800
  thread: resolvedThread.threadUri,
508
801
  maker: this.parseSparqlBindingValue(binding, 'maker'),
509
- role: this.parseSparqlBindingValue(binding, 'role'),
802
+ role: this.parseSparqlBindingValue(binding, 'messageType') ?? this.parseSparqlBindingValue(binding, 'legacyRole'),
510
803
  content: this.parseSparqlBindingValue(binding, 'content'),
511
- status: this.parseSparqlBindingValue(binding, 'status'),
512
- createdAt: this.parseSparqlBindingValue(binding, 'createdAt'),
804
+ status: this.parseSparqlBindingValue(binding, 'messageStatus') ?? this.parseSparqlBindingValue(binding, 'legacyStatus'),
805
+ createdAt: this.parseSparqlBindingValue(binding, 'createdAt') ?? this.parseSparqlBindingValue(binding, 'legacyCreatedAt'),
513
806
  toolName: this.parseSparqlBindingValue(binding, 'toolName'),
514
807
  toolCallId: this.parseSparqlBindingValue(binding, 'toolCallId'),
515
808
  metadata: this.parseSparqlBindingValue(binding, 'metadata'),
516
809
  subjectUri: this.parseSparqlBindingValue(binding, 'msg'),
517
810
  }));
518
811
  }
812
+ datePathFromTimestamp(timestamp) {
813
+ const date = typeof timestamp === 'number' ? new Date(timestamp * 1000) : new Date();
814
+ return {
815
+ yyyy: String(date.getUTCFullYear()),
816
+ MM: String(date.getUTCMonth() + 1).padStart(2, '0'),
817
+ dd: String(date.getUTCDate()).padStart(2, '0'),
818
+ };
819
+ }
519
820
  // =========================================================================
520
821
  // ID Generation
521
822
  // =========================================================================
522
823
  generateThreadId(_context) {
523
- return (0, types_1.generateId)('thread');
824
+ return this.generateThreadResourceId({
825
+ key: (0, types_1.generateId)('thread'),
826
+ commandKind: 'chat',
827
+ surfaceId: PodChatKitStore.DEFAULT_CHAT_ID,
828
+ });
524
829
  }
525
- generateItemId(itemType, _thread, _context) {
526
- return (0, types_1.generateId)(itemType.replace('_', '-'));
830
+ generateItemId(itemType, thread, _context) {
831
+ const commandKind = thread.metadata?.commandKind === 'task' ? 'task' : 'chat';
832
+ const surfaceId = this.getSurfaceIdFromMetadata(thread.metadata);
833
+ return this.generateMessageResourceId({
834
+ key: (0, types_1.generateId)(itemType.replace('_', '-')),
835
+ commandKind,
836
+ surfaceId,
837
+ });
527
838
  }
528
839
  // =========================================================================
529
840
  // Thread Operations (ChatKit thread = our Thread)
@@ -548,7 +859,7 @@ class PodChatKitStore {
548
859
  const metadata = this.threadRecordToMetadata(threadRecord, chatUriMap);
549
860
  // 缓存结果
550
861
  this.cacheThreadMetadata(context, metadata);
551
- this.cacheThreadChatId(context, metadata.id, resolvedThread.chatId);
862
+ this.cacheThreadSurfaceId(context, metadata.id, resolvedThread.surfaceId);
552
863
  return metadata;
553
864
  }
554
865
  async saveThread(thread, context) {
@@ -557,48 +868,70 @@ class PodChatKitStore {
557
868
  throw new Error('Cannot access Pod: invalid credentials');
558
869
  }
559
870
  const now = new Date().toISOString();
560
- // metadata 获取 chat_id
561
- const chatId = this.getChatIdFromMetadata(thread.metadata);
562
- thread.metadata = { ...(thread.metadata ?? {}), chat_id: chatId };
563
- // Persist all metadata except chat_id (which is derived from storage location).
871
+ const commandKind = this.getCommandKindFromMetadata(thread.metadata);
872
+ const surfaceId = this.getSurfaceIdFromMetadata(thread.metadata);
873
+ thread.metadata = {
874
+ ...(thread.metadata ?? {}),
875
+ commandKind,
876
+ surface_id: surfaceId,
877
+ chat_id: surfaceId,
878
+ };
879
+ // Persist extended metadata except fields that are derived from first-class columns.
564
880
  const metadataToPersist = { ...(thread.metadata ?? {}) };
565
881
  delete metadataToPersist.chat_id;
566
- const metadataJson = Object.keys(metadataToPersist).length > 0 ? JSON.stringify(metadataToPersist) : null;
567
- // 确保 Chat 容器存在
568
- await this.ensureChat(chatId, context);
569
- // 缓存 Thread -> chatId 映射,避免后续查询
570
- this.cacheThreadChatId(context, thread.id, chatId);
571
- const threadUri = await this.buildThreadUri(thread.id, chatId, context);
882
+ delete metadataToPersist.commandKind;
883
+ delete metadataToPersist.surface_id;
884
+ const metadataObject = this.jsonObjectOrNull(metadataToPersist);
885
+ if (commandKind === 'chat') {
886
+ await this.ensureChat(surfaceId, context);
887
+ }
888
+ const threadResourceId = this.buildThreadResourceId({
889
+ id: thread.id,
890
+ commandKind,
891
+ surfaceId,
892
+ });
893
+ thread.id = threadResourceId;
894
+ this.cacheThreadSurfaceId(context, thread.id, surfaceId);
895
+ const threadUri = this.resolveDataResourceUriFromId(threadResourceId, context);
572
896
  // 检查 Thread 是否存在
573
897
  const existing = await db.findByIri(schema_1.Thread, threadUri);
574
898
  if (existing) {
575
899
  // Update
576
- await db.updateByLocator(schema_1.Thread, {
577
- id: thread.id,
578
- chatId,
579
- }, {
900
+ await db.updateByIri(schema_1.Thread, threadUri, {
901
+ commandKind,
902
+ surfaceId,
903
+ chat: commandKind === 'chat' ? this.buildChatResourceId(surfaceId) : null,
580
904
  title: thread.title || null,
581
905
  status: this.statusToString(thread.status),
582
- metadata: metadataJson,
906
+ workspace: thread.workspace || null,
907
+ metadata: metadataObject,
583
908
  updatedAt: now,
584
909
  });
585
910
  }
586
911
  else {
587
912
  // Insert
588
913
  await db.insert(schema_1.Thread).values({
589
- id: thread.id,
590
- chatId, // 关联到 Chat 容器
914
+ id: threadResourceId,
915
+ commandKind,
916
+ surfaceId,
917
+ chat: commandKind === 'chat' ? this.buildChatResourceId(surfaceId) : null,
591
918
  title: thread.title || null,
592
919
  status: this.statusToString(thread.status),
593
- metadata: metadataJson,
920
+ workspace: thread.workspace || null,
921
+ metadata: metadataObject,
594
922
  createdAt: new Date(thread.created_at * 1000).toISOString(),
595
923
  updatedAt: now,
596
924
  });
597
925
  }
598
- // 缓存完整的 Thread metadata,确保 metadata.chat_id 包含正确的值
926
+ // 缓存完整的 Thread metadata,确保 ChatKit metadata.chat_id 包含正确的 surface。
599
927
  const threadMetadata = {
600
928
  ...thread,
601
- metadata: { ...(thread.metadata ?? {}), chat_id: chatId },
929
+ metadata: {
930
+ ...(thread.metadata ?? {}),
931
+ commandKind,
932
+ surface_id: surfaceId,
933
+ chat_id: surfaceId,
934
+ },
602
935
  };
603
936
  this.cacheThreadMetadata(context, threadMetadata);
604
937
  }
@@ -655,10 +988,7 @@ class PodChatKitStore {
655
988
  }
656
989
  // 删除 Thread
657
990
  try {
658
- await db.deleteByLocator(schema_1.Thread, {
659
- id: resolvedThread.threadId,
660
- chatId: resolvedThread.chatId,
661
- });
991
+ await db.deleteByIri(schema_1.Thread, resolvedThread.threadUri);
662
992
  }
663
993
  catch (err) {
664
994
  if (!err.message?.includes('404') && !err.message?.includes('Could not retrieve') && !err.message?.includes('Parse error')) {
@@ -668,9 +998,9 @@ class PodChatKitStore {
668
998
  }
669
999
  // 清除缓存
670
1000
  const metadataCache = context._threadMetadataCache;
671
- const chatIdCache = context._threadChatIdCache;
1001
+ const surfaceIdCache = context._threadSurfaceIdCache;
672
1002
  metadataCache?.delete(resolvedThread.threadId);
673
- chatIdCache?.delete(resolvedThread.threadId);
1003
+ surfaceIdCache?.delete(resolvedThread.threadId);
674
1004
  }
675
1005
  // =========================================================================
676
1006
  // Thread Item Operations (ChatKit items = our Messages)
@@ -712,10 +1042,21 @@ class PodChatKitStore {
712
1042
  throw new Error('Cannot access Pod: invalid credentials');
713
1043
  }
714
1044
  const resolvedThread = await this.resolveThreadRef(thread, context);
1045
+ const itemResourceId = this.buildMessageResourceId({
1046
+ id: item.id,
1047
+ commandKind: resolvedThread.commandKind,
1048
+ surfaceId: resolvedThread.surfaceId,
1049
+ createdAt: item.created_at,
1050
+ });
1051
+ item.id = itemResourceId;
1052
+ item.thread_id = resolvedThread.threadId;
715
1053
  const webId = this.getWebId(context);
716
1054
  let content = '';
717
1055
  let role = schema_1.MessageRole.USER;
718
1056
  let status = null;
1057
+ let toolName = null;
1058
+ let toolCallId = null;
1059
+ let metadata = null;
719
1060
  if (item.type === 'user_message') {
720
1061
  const userItem = item;
721
1062
  content = userItem.content
@@ -733,24 +1074,42 @@ class PodChatKitStore {
733
1074
  role = schema_1.MessageRole.ASSISTANT;
734
1075
  status = assistantItem.status || schema_1.MessageStatus.COMPLETED;
735
1076
  }
1077
+ else if (item.type === 'client_tool_call') {
1078
+ const toolItem = item;
1079
+ content = toolItem.output ?? '';
1080
+ role = schema_1.MessageRole.SYSTEM;
1081
+ status = toolItem.status ?? 'pending';
1082
+ toolName = toolItem.name;
1083
+ toolCallId = toolItem.call_id;
1084
+ metadata = {
1085
+ ...(toolItem.metadata ?? {}),
1086
+ arguments: toolItem.arguments,
1087
+ output: toolItem.output,
1088
+ };
1089
+ }
736
1090
  else {
737
1091
  // 其他类型暂时存储为 JSON
738
1092
  content = JSON.stringify(item);
739
1093
  role = schema_1.MessageRole.SYSTEM;
740
1094
  }
741
1095
  const messageRecord = {
742
- id: item.id,
743
- chat: resolvedThread.chatId, // bare ID,用于路径构建
744
- thread: resolvedThread.threadUri, // 完整 URI,用于 RDF 引用
1096
+ id: itemResourceId,
1097
+ commandKind: resolvedThread.commandKind,
1098
+ surfaceId: resolvedThread.surfaceId,
1099
+ chat: resolvedThread.commandKind === 'chat' ? this.buildChatResourceId(resolvedThread.surfaceId) : null,
1100
+ thread: resolvedThread.threadUri,
745
1101
  maker: role === schema_1.MessageRole.USER ? webId : null,
746
1102
  role,
747
1103
  content,
748
1104
  status,
1105
+ toolName,
1106
+ toolCallId,
1107
+ metadata: this.jsonObjectOrNull(metadata ?? undefined),
749
1108
  createdAt: new Date(item.created_at * 1000).toISOString(),
750
1109
  };
751
1110
  await db.insert(schema_1.Message).values(messageRecord);
752
1111
  // Track this ID to avoid cache timing issues in saveItem
753
- this.recentlyCreatedIds.add(messageRecord.id);
1112
+ this.recentlyCreatedIds.add(item.id);
754
1113
  }
755
1114
  async saveItem(thread, item, context) {
756
1115
  const db = await this.getDb(context);
@@ -761,6 +1120,7 @@ class PodChatKitStore {
761
1120
  // 准备更新数据
762
1121
  let content = '';
763
1122
  let status = null;
1123
+ let metadata = null;
764
1124
  if (item.type === 'user_message') {
765
1125
  const userItem = item;
766
1126
  content = userItem.content
@@ -776,25 +1136,40 @@ class PodChatKitStore {
776
1136
  .join('\n');
777
1137
  status = assistantItem.status || schema_1.MessageStatus.COMPLETED;
778
1138
  }
779
- // 获取 createdAt 用于计算资源路径(与 drizzle-solid 模板填充保持一致)
780
- const createdAt = item.created_at ? new Date(item.created_at * 1000).toISOString() : undefined;
1139
+ else if (item.type === 'client_tool_call') {
1140
+ const toolItem = item;
1141
+ content = toolItem.output ?? '';
1142
+ status = toolItem.status ?? 'pending';
1143
+ metadata = {
1144
+ ...(toolItem.metadata ?? {}),
1145
+ arguments: toolItem.arguments,
1146
+ output: toolItem.output,
1147
+ };
1148
+ }
1149
+ const itemResourceId = this.buildMessageResourceId({
1150
+ id: item.id,
1151
+ commandKind: resolvedThread.commandKind,
1152
+ surfaceId: resolvedThread.surfaceId,
1153
+ createdAt: item.created_at,
1154
+ });
781
1155
  // 如果是最近创建的消息,使用直接 PATCH 更新(避免 drizzle-solid UPDATE 的 bug)
782
- const wasRecentlyCreated = this.recentlyCreatedIds.has(item.id);
1156
+ const wasRecentlyCreated = this.recentlyCreatedIds.has(itemResourceId);
783
1157
  if (wasRecentlyCreated) {
784
- this.recentlyCreatedIds.delete(item.id);
785
- await this.directPatchMessage(context, resolvedThread.chatId, item.id, content, status, createdAt);
1158
+ this.recentlyCreatedIds.delete(itemResourceId);
1159
+ item.id = itemResourceId;
1160
+ item.thread_id = resolvedThread.threadId;
1161
+ await this.directPatchMessage(context, itemResourceId, content, status, metadata);
786
1162
  return;
787
1163
  }
788
1164
  // 对于非最近创建的消息,使用普通流程
789
1165
  const existingItems = (await this.selectMessagesForThread(thread, context))
790
- .filter((message) => message.id === item.id);
1166
+ .filter((message) => message.id === itemResourceId);
791
1167
  const existing = existingItems.length > 0 ? existingItems[0] : null;
792
1168
  if (existing) {
793
1169
  // 使用直接 PATCH 更新
794
- const existingCreatedAt = existing.createdAt
795
- ? (existing.createdAt instanceof Date ? existing.createdAt.toISOString() : String(existing.createdAt))
796
- : undefined;
797
- await this.directPatchMessage(context, resolvedThread.chatId, item.id, content, status, existingCreatedAt);
1170
+ item.id = itemResourceId;
1171
+ item.thread_id = resolvedThread.threadId;
1172
+ await this.directPatchMessage(context, existing.id, content, status, metadata);
798
1173
  }
799
1174
  else {
800
1175
  // Create new record
@@ -805,25 +1180,15 @@ class PodChatKitStore {
805
1180
  * 直接使用 SPARQL UPDATE PATCH 更新消息内容
806
1181
  * 避免 drizzle-solid UPDATE 的 bug
807
1182
  */
808
- async directPatchMessage(context, chatId, messageId, content, status, createdAt) {
1183
+ async directPatchMessage(context, messageResourceId, content, status, metadata = null) {
809
1184
  // 使用缓存的 fetch 和 webId(由 getDb 时创建的 session)
810
1185
  const cachedFetch = context._cachedFetch;
811
- const cachedWebId = context._cachedWebId;
812
- if (!cachedFetch || !cachedWebId) {
1186
+ if (!cachedFetch) {
813
1187
  throw new Error('No cached session for direct PATCH - call getDb first');
814
1188
  }
815
- // 构建资源 URL subject URI
816
- // Template: {chatId}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
817
- const podBaseUrl = this.derivePodBaseUrl(cachedWebId);
818
- if (!podBaseUrl) {
819
- throw new Error(`Cannot resolve Pod base URL from cached WebID: ${cachedWebId}`);
820
- }
821
- const messageDate = createdAt ? new Date(createdAt) : new Date();
822
- const yyyy = String(messageDate.getUTCFullYear());
823
- const MM = String(messageDate.getUTCMonth() + 1).padStart(2, '0');
824
- const dd = String(messageDate.getUTCDate()).padStart(2, '0');
825
- const resourceUrl = `${podBaseUrl}/.data/chat/${chatId}/${yyyy}/${MM}/${dd}/messages.ttl`;
826
- const subjectUri = `${resourceUrl}#${messageId}`;
1189
+ const subjectUri = this.resolveDataResourceUriFromId(messageResourceId, context);
1190
+ const hashIndex = subjectUri.lastIndexOf('#');
1191
+ const resourceUrl = hashIndex >= 0 ? subjectUri.slice(0, hashIndex) : subjectUri;
827
1192
  // 构建 SPARQL UPDATE:删除旧值,插入新值
828
1193
  const deletePatterns = [];
829
1194
  const insertTriples = [];
@@ -851,8 +1216,12 @@ class PodChatKitStore {
851
1216
  insertTriples.push(`<${subjectUri}> <http://rdfs.org/sioc/ns#content> ${escapeForSparql(content)} .`);
852
1217
  // Status 更新
853
1218
  if (status) {
854
- deletePatterns.push(`<${subjectUri}> <https://undefineds.co/ns#status> ?oldStatus .`);
855
- insertTriples.push(`<${subjectUri}> <https://undefineds.co/ns#status> "${status}" .`);
1219
+ deletePatterns.push(`<${subjectUri}> <https://undefineds.co/ns#messageStatus> ?oldStatus .`);
1220
+ insertTriples.push(`<${subjectUri}> <https://undefineds.co/ns#messageStatus> "${status}" .`);
1221
+ }
1222
+ if (metadata) {
1223
+ deletePatterns.push(`<${subjectUri}> <https://undefineds.co/ns#metadata> ?oldMetadata .`);
1224
+ insertTriples.push(`<${subjectUri}> <https://undefineds.co/ns#metadata> ${escapeForSparql(JSON.stringify(metadata))} .`);
856
1225
  }
857
1226
  const sparql = `
858
1227
  DELETE { ${deletePatterns.join(' ')} }
@@ -923,19 +1292,276 @@ WHERE { ${deletePatterns.join(' ')} }
923
1292
  async deleteAttachment(attachmentId, _context) {
924
1293
  this.logger.info(`Attachment deleted: ${attachmentId}`);
925
1294
  }
1295
+ // =========================================================================
1296
+ // Run Operations
1297
+ // =========================================================================
1298
+ async saveRun(run, context) {
1299
+ const db = await this.getDb(context);
1300
+ if (!db) {
1301
+ throw new Error('Cannot access Pod: invalid credentials');
1302
+ }
1303
+ run.id = (0, store_1.buildRunResourceId)(run);
1304
+ const existing = await db.findById(schema_2.Run, run.id);
1305
+ const values = {
1306
+ surfaceId: run.surfaceId,
1307
+ task: run.task || null,
1308
+ thread: run.thread,
1309
+ workspace: run.workspace,
1310
+ commandKind: run.commandKind,
1311
+ status: run.status,
1312
+ runner: run.runner || null,
1313
+ prompt: run.prompt || null,
1314
+ externalRunId: run.externalRunId || null,
1315
+ leaseOwner: run.leaseOwner || null,
1316
+ leaseExpiresAt: this.timestampToIso(run.leaseExpiresAt),
1317
+ heartbeatAt: this.timestampToIso(run.heartbeatAt),
1318
+ cancelRequestedAt: this.timestampToIso(run.cancelRequestedAt),
1319
+ error: run.error || null,
1320
+ metadata: this.jsonObjectOrNull(run.metadata),
1321
+ createdAt: this.timestampToIso(run.createdAt) ?? new Date().toISOString(),
1322
+ startedAt: this.timestampToIso(run.startedAt),
1323
+ completedAt: this.timestampToIso(run.completedAt),
1324
+ updatedAt: this.timestampToIso(run.updatedAt) ?? new Date().toISOString(),
1325
+ };
1326
+ if (existing) {
1327
+ await db.updateById(schema_2.Run, run.id, values);
1328
+ return;
1329
+ }
1330
+ await db.insert(schema_2.Run).values({
1331
+ id: run.id,
1332
+ ...values,
1333
+ });
1334
+ }
1335
+ async loadRun(id, context) {
1336
+ const db = await this.getDb(context);
1337
+ if (!db) {
1338
+ throw new Error('Cannot access Pod: invalid credentials');
1339
+ }
1340
+ const record = await db.findById(schema_2.Run, id);
1341
+ if (!record) {
1342
+ throw new Error(`Run not found: ${id}`);
1343
+ }
1344
+ return this.runRecordToData(record);
1345
+ }
1346
+ async listRuns(options, context) {
1347
+ const db = await this.getDb(context);
1348
+ if (!db) {
1349
+ throw new Error('Cannot access Pod: invalid credentials');
1350
+ }
1351
+ const conditions = [];
1352
+ if (options.task) {
1353
+ conditions.push((0, drizzle_solid_1.eq)(schema_2.Run.task, options.task));
1354
+ }
1355
+ if (options.thread) {
1356
+ conditions.push((0, drizzle_solid_1.eq)(schema_2.Run.thread, options.thread));
1357
+ }
1358
+ if (options.workspace) {
1359
+ conditions.push((0, drizzle_solid_1.eq)(schema_2.Run.workspace, options.workspace));
1360
+ }
1361
+ if (options.commandKind) {
1362
+ conditions.push((0, drizzle_solid_1.eq)(schema_2.Run.commandKind, options.commandKind));
1363
+ }
1364
+ if (options.status) {
1365
+ conditions.push((0, drizzle_solid_1.eq)(schema_2.Run.status, options.status));
1366
+ }
1367
+ const query = db.select().from(schema_2.Run);
1368
+ const records = conditions.length > 0
1369
+ ? await query.where((0, drizzle_solid_1.and)(...conditions))
1370
+ : await query;
1371
+ return records
1372
+ .map((record) => this.runRecordToData(record))
1373
+ .sort((a, b) => b.createdAt - a.createdAt || b.id.localeCompare(a.id))
1374
+ .slice(0, options.limit ?? records.length);
1375
+ }
1376
+ async appendRunStep(event, context) {
1377
+ const db = await this.getDb(context);
1378
+ if (!db) {
1379
+ throw new Error('Cannot access Pod: invalid credentials');
1380
+ }
1381
+ if (!(0, store_1.isRunResourceId)(event.runId)) {
1382
+ throw new Error(`RunStep runId must be a complete Run resource id: ${event.runId}`);
1383
+ }
1384
+ event.id = (0, store_1.buildRunStepResourceId)(event);
1385
+ await db.insert(schema_2.RunStep).values({
1386
+ id: event.id,
1387
+ commandKind: event.commandKind,
1388
+ surfaceId: event.surfaceId,
1389
+ runId: event.runId,
1390
+ run: event.run,
1391
+ type: event.type,
1392
+ message: event.message || null,
1393
+ data: this.jsonObjectOrNull(event.data),
1394
+ createdAt: this.timestampToIso(event.createdAt) ?? new Date().toISOString(),
1395
+ });
1396
+ }
1397
+ async loadRunSteps(runId, context) {
1398
+ const db = await this.getDb(context);
1399
+ if (!db) {
1400
+ throw new Error('Cannot access Pod: invalid credentials');
1401
+ }
1402
+ if (!(0, store_1.isRunResourceId)(runId)) {
1403
+ throw new Error(`loadRunSteps requires a base-relative Run id: ${runId}`);
1404
+ }
1405
+ // runId is a local query field; RunStep.run remains the semantic RDF URI relation.
1406
+ const records = await db.select().from(schema_2.RunStep).where((0, drizzle_solid_1.eq)(schema_2.RunStep.runId, runId));
1407
+ return records
1408
+ .map((record) => this.runStepRecordToData(record))
1409
+ .sort((a, b) => a.createdAt - b.createdAt || a.id.localeCompare(b.id));
1410
+ }
1411
+ async claimRun(input, context) {
1412
+ const run = await this.loadRun(input.runId, context);
1413
+ if (!(0, store_1.canClaimRun)(run, input)) {
1414
+ return undefined;
1415
+ }
1416
+ run.leaseOwner = input.leaseOwner;
1417
+ run.leaseExpiresAt = input.leaseExpiresAt;
1418
+ run.heartbeatAt = input.now;
1419
+ run.updatedAt = input.now;
1420
+ await this.saveRun(run, context);
1421
+ const claimed = await this.loadRun(input.runId, context);
1422
+ return claimed.leaseOwner === input.leaseOwner ? claimed : undefined;
1423
+ }
1424
+ // =========================================================================
1425
+ // Task Operations
1426
+ // =========================================================================
1427
+ async saveTask(task, context) {
1428
+ const db = await this.getDb(context);
1429
+ if (!db) {
1430
+ throw new Error('Cannot access Pod: invalid credentials');
1431
+ }
1432
+ task.id = (0, store_2.buildTaskResourceId)(task.id);
1433
+ const existing = await db.findById(schema_3.Task, task.id);
1434
+ const values = {
1435
+ surfaceId: task.surfaceId,
1436
+ title: task.title || null,
1437
+ prompt: task.prompt,
1438
+ thread: task.thread,
1439
+ workspace: task.workspace,
1440
+ runner: task.runner,
1441
+ status: task.status,
1442
+ triggerKind: task.triggerKind,
1443
+ cron: task.cron || null,
1444
+ intervalSeconds: task.intervalSeconds ?? null,
1445
+ eventName: task.eventName || null,
1446
+ nextRunAt: this.timestampToIso(task.nextRunAt),
1447
+ lastRunAt: this.timestampToIso(task.lastRunAt),
1448
+ metadata: this.jsonObjectOrNull(this.withTaskAuthBindingMetadata(task.metadata, task.authBinding)),
1449
+ createdAt: this.timestampToIso(task.createdAt) ?? new Date().toISOString(),
1450
+ updatedAt: this.timestampToIso(task.updatedAt) ?? new Date().toISOString(),
1451
+ };
1452
+ if (existing) {
1453
+ await db.updateById(schema_3.Task, task.id, values);
1454
+ return;
1455
+ }
1456
+ await db.insert(schema_3.Task).values({
1457
+ id: task.id,
1458
+ ...values,
1459
+ });
1460
+ }
1461
+ async loadTask(taskId, context) {
1462
+ const db = await this.getDb(context);
1463
+ if (!db) {
1464
+ throw new Error('Cannot access Pod: invalid credentials');
1465
+ }
1466
+ const record = await db.findById(schema_3.Task, taskId);
1467
+ if (!record) {
1468
+ throw new Error(`Task not found: ${taskId}`);
1469
+ }
1470
+ return this.taskRecordToData(record);
1471
+ }
1472
+ async listTasks(options, context) {
1473
+ const db = await this.getDb(context);
1474
+ if (!db) {
1475
+ throw new Error('Cannot access Pod: invalid credentials');
1476
+ }
1477
+ const records = await db.select().from(schema_3.Task);
1478
+ const dueAt = options.dueAt ?? (0, types_1.nowTimestamp)();
1479
+ let tasks = records.map((record) => this.taskRecordToData(record));
1480
+ if (options.status) {
1481
+ tasks = tasks.filter((task) => task.status === options.status);
1482
+ }
1483
+ if (options.triggerKind) {
1484
+ tasks = tasks.filter((task) => task.triggerKind === options.triggerKind);
1485
+ }
1486
+ if (options.eventName) {
1487
+ tasks = tasks.filter((task) => task.eventName === options.eventName);
1488
+ }
1489
+ if (typeof options.dueAt === 'number') {
1490
+ tasks = tasks.filter((task) => typeof task.nextRunAt === 'number' && task.nextRunAt <= dueAt);
1491
+ }
1492
+ tasks.sort((a, b) => (a.nextRunAt ?? a.createdAt) - (b.nextRunAt ?? b.createdAt) || a.id.localeCompare(b.id));
1493
+ return tasks.slice(0, options.limit ?? tasks.length);
1494
+ }
1495
+ async saveTaskAuthCredential(input, context) {
1496
+ const db = await this.getDb(context);
1497
+ if (!db) {
1498
+ throw new Error('Cannot access Pod: invalid credentials');
1499
+ }
1500
+ const values = {
1501
+ service: TaskAuthBinding_1.TASK_AUTH_CREDENTIAL_SERVICE,
1502
+ status: types_2.CredentialStatus.ACTIVE,
1503
+ apiKey: input.apiKey,
1504
+ label: input.displayName ?? null,
1505
+ oauthExpiresAt: this.timestampToIso(input.expiresAt),
1506
+ };
1507
+ const existing = await db.findById(tables_1.Credential, input.id);
1508
+ if (existing) {
1509
+ await db.updateById(tables_1.Credential, input.id, values);
1510
+ return {
1511
+ ...existing,
1512
+ ...values,
1513
+ id: input.id,
1514
+ };
1515
+ }
1516
+ await db.insert(tables_1.Credential).values({
1517
+ id: input.id,
1518
+ ...values,
1519
+ });
1520
+ return {
1521
+ id: input.id,
1522
+ ...values,
1523
+ createdAt: new Date().toISOString(),
1524
+ };
1525
+ }
1526
+ async loadTaskAuthCredential(id, context) {
1527
+ const db = await this.getDb(context);
1528
+ if (!db) {
1529
+ throw new Error('Cannot access Pod: invalid credentials');
1530
+ }
1531
+ const credential = await db.findById(tables_1.Credential, id);
1532
+ if (!credential || credential.service !== TaskAuthBinding_1.TASK_AUTH_CREDENTIAL_SERVICE) {
1533
+ return undefined;
1534
+ }
1535
+ return credential;
1536
+ }
926
1537
  /**
927
1538
  * 从 Pod 获取 AI 配置(Provider + Credential)
928
1539
  * 复用已缓存的 Session,避免重复登录
929
1540
  */
930
1541
  extractProviderId(provider) {
931
- if (!provider) {
1542
+ const value = provider?.trim();
1543
+ if (!value) {
932
1544
  return '';
933
1545
  }
934
- const hashIndex = provider.lastIndexOf('#');
935
- if (hashIndex >= 0 && hashIndex < provider.length - 1) {
936
- return provider.slice(hashIndex + 1);
937
- }
938
- return provider;
1546
+ const hashIndex = value.lastIndexOf('#');
1547
+ const hashless = hashIndex >= 0 && hashIndex < value.length - 1
1548
+ ? value.slice(hashIndex + 1)
1549
+ : value;
1550
+ const clean = hashless.replace(/\/+$/, '');
1551
+ const slashIndex = clean.lastIndexOf('/');
1552
+ const tail = slashIndex >= 0 ? clean.slice(slashIndex + 1) : clean;
1553
+ const ttlFragmentIndex = tail.lastIndexOf('.ttl#');
1554
+ if (ttlFragmentIndex >= 0) {
1555
+ return tail.slice(ttlFragmentIndex + '.ttl#'.length);
1556
+ }
1557
+ if (tail.endsWith('.ttl')) {
1558
+ return tail.slice(0, -'.ttl'.length);
1559
+ }
1560
+ const fragmentIndex = tail.lastIndexOf('#');
1561
+ if (fragmentIndex >= 0 && fragmentIndex < tail.length - 1) {
1562
+ return tail.slice(fragmentIndex + 1);
1563
+ }
1564
+ return tail;
939
1565
  }
940
1566
  pushAvailableModel(models, seenModelIds, model) {
941
1567
  const id = typeof model.id === 'string' ? model.id.trim() : '';
@@ -964,6 +1590,44 @@ WHERE { ${deletePatterns.join(' ')} }
964
1590
  }
965
1591
  models.push(item);
966
1592
  }
1593
+ resolvePodResourceIri(context, resource) {
1594
+ if (/^https?:\/\//.test(resource)) {
1595
+ return resource;
1596
+ }
1597
+ const podBaseUrl = this.getCachedPodBaseUrl(context)
1598
+ ?? this.derivePodBaseUrl(this.getWebId(context));
1599
+ if (!podBaseUrl) {
1600
+ throw new Error(`Cannot resolve Pod base URL for resource: ${resource}`);
1601
+ }
1602
+ return `${podBaseUrl.replace(/\/$/, '')}/${resource.replace(/^\//, '')}`;
1603
+ }
1604
+ async findProviderForCredential(db, context, providerRef) {
1605
+ const candidates = new Set();
1606
+ candidates.add(providerRef);
1607
+ if (!/^https?:\/\//.test(providerRef)) {
1608
+ candidates.add(this.resolvePodResourceIri(context, providerRef));
1609
+ }
1610
+ const providerId = (0, models_1.normalizeAIConfigProviderId)(providerRef);
1611
+ if (providerId) {
1612
+ candidates.add(providerId);
1613
+ candidates.add(`/settings/providers/${providerId}.ttl`);
1614
+ candidates.add(this.resolvePodResourceIri(context, `/settings/providers/${providerId}.ttl`));
1615
+ }
1616
+ for (const candidate of candidates) {
1617
+ try {
1618
+ const provider = /^https?:\/\//.test(candidate)
1619
+ ? await db.findByIri(provider_1.Provider, candidate)
1620
+ : await db.findById(provider_1.Provider, candidate);
1621
+ if (provider) {
1622
+ return provider;
1623
+ }
1624
+ }
1625
+ catch {
1626
+ // Try the next canonical form.
1627
+ }
1628
+ }
1629
+ return null;
1630
+ }
967
1631
  async getAiConfig(context) {
968
1632
  const db = await this.getDb(context);
969
1633
  if (!db) {
@@ -977,23 +1641,11 @@ WHERE { ${deletePatterns.join(' ')} }
977
1641
  if (credentials.length === 0) {
978
1642
  return undefined;
979
1643
  }
980
- // Build provider @id → record map for URI matching
981
- const allProviders = await db.select().from(provider_1.Provider);
982
- const providerByUri = new Map();
983
- for (const p of allProviders) {
984
- const uri = p['@id'];
985
- if (uri)
986
- providerByUri.set(uri, p);
987
- // Also index by bare id for fallback
988
- providerByUri.set(p.id, p);
989
- }
990
1644
  // 遍历凭据,找到有效的 Provider
991
1645
  for (const cred of credentials) {
992
1646
  if (!cred.provider)
993
1647
  continue;
994
- // Match provider by full URI first, then fallback to bare fragment id.
995
- const provider = providerByUri.get(cred.provider)
996
- ?? providerByUri.get(this.extractProviderId(cred.provider));
1648
+ const provider = await this.findProviderForCredential(db, context, cred.provider);
997
1649
  if (!provider)
998
1650
  continue;
999
1651
  const baseUrl = provider.baseUrl;
@@ -1003,9 +1655,10 @@ WHERE { ${deletePatterns.join(' ')} }
1003
1655
  const defaultModel = defaultModelRef
1004
1656
  ? (await db.findByIri(model_1.Model, defaultModelRef))?.id ?? undefined
1005
1657
  : undefined;
1006
- this.logger.debug(`Using credential ${cred.id} with provider ${provider.id}`);
1658
+ const providerId = this.extractProviderId(provider.id || cred.provider);
1659
+ this.logger.debug(`Using credential ${cred.id} with provider ${providerId}`);
1007
1660
  return {
1008
- providerId: provider.id,
1661
+ providerId,
1009
1662
  baseUrl,
1010
1663
  proxyUrl: provider.proxyUrl || undefined,
1011
1664
  defaultModel,
@@ -1042,6 +1695,7 @@ WHERE { ${deletePatterns.join(' ')} }
1042
1695
  }
1043
1696
  if (typeof provider?.id === 'string' && provider.id) {
1044
1697
  providerByKey.set(provider.id, provider);
1698
+ providerByKey.set(this.extractProviderId(provider.id), provider);
1045
1699
  }
1046
1700
  }
1047
1701
  const currentProvider = providerByKey.get(config.providerId)
@@ -1105,12 +1759,12 @@ WHERE { ${deletePatterns.join(' ')} }
1105
1759
  }
1106
1760
  // 如果需要递增 failCount,先查询当前值
1107
1761
  if (options?.incrementFailCount) {
1108
- const currentCred = await db.findByLocator(tables_1.Credential, { id: credentialId });
1762
+ const currentCred = await db.findById(tables_1.Credential, credentialId);
1109
1763
  if (currentCred) {
1110
1764
  updateData.failCount = (currentCred.failCount ?? 0) + 1;
1111
1765
  }
1112
1766
  }
1113
- await db.updateByLocator(tables_1.Credential, { id: credentialId }, updateData);
1767
+ await db.updateById(tables_1.Credential, credentialId, updateData);
1114
1768
  this.logger.info(`Credential ${credentialId} status updated to ${status}`);
1115
1769
  }
1116
1770
  catch (error) {
@@ -1126,7 +1780,7 @@ WHERE { ${deletePatterns.join(' ')} }
1126
1780
  return;
1127
1781
  }
1128
1782
  try {
1129
- await db.updateByLocator(tables_1.Credential, { id: credentialId }, {
1783
+ await db.updateById(tables_1.Credential, credentialId, {
1130
1784
  lastUsedAt: new Date(),
1131
1785
  failCount: 0,
1132
1786
  status: types_2.CredentialStatus.ACTIVE,