akanjs 3.0.0-alpha.2 → 3.0.0-alpha.21

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 (388) hide show
  1. package/README.ko.md +1 -1
  2. package/README.md +1 -1
  3. package/base/symbols.ts +4 -0
  4. package/client/clientRuntime.ts +8 -0
  5. package/client/cn.ts +7 -0
  6. package/client/csrTypes.ts +2 -0
  7. package/client/frameDebug.ts +3 -2
  8. package/common/Logger.ts +4 -0
  9. package/common/deepObjectify.ts +21 -7
  10. package/common/index.ts +14 -0
  11. package/common/mcpExposure.ts +99 -0
  12. package/common/pathSet.ts +17 -5
  13. package/common/routeConvention.ts +30 -0
  14. package/constant/crystalize.ts +3 -1
  15. package/constant/fieldInfo.ts +6 -0
  16. package/constant/getDefault.ts +37 -9
  17. package/constant/immerify.ts +1 -1
  18. package/constant/index.ts +2 -0
  19. package/constant/labelOf.ts +17 -0
  20. package/constant/mask.ts +60 -0
  21. package/constant/purify.ts +17 -11
  22. package/constant/types.ts +14 -12
  23. package/dictionary/DictionaryLookup.ts +30 -0
  24. package/dictionary/agent.dictionary.ts +31 -0
  25. package/dictionary/agentTurn.dictionary.ts +29 -0
  26. package/dictionary/base.dictionary.ts +8 -0
  27. package/dictionary/dictInfo.ts +8 -0
  28. package/dictionary/dictionary.ts +9 -3
  29. package/dictionary/index.ts +1 -0
  30. package/document/database.ts +21 -0
  31. package/document/filterMeta.ts +7 -0
  32. package/document/index.ts +1 -0
  33. package/document/into.ts +7 -1
  34. package/document/noDocumentError.ts +12 -0
  35. package/fetch/agentTurn.ts +19 -0
  36. package/fetch/client/fetchClient.ts +71 -13
  37. package/fetch/client/wsClient.ts +17 -2
  38. package/fetch/fetchType/endpointFetch.type.ts +10 -4
  39. package/fetch/index.ts +1 -0
  40. package/local/apps/serverLifecycle/serverLifecycle-local.db +0 -0
  41. package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
  42. package/local/apps/serverLifecycle/serverLifecycle-local.db-wal +0 -0
  43. package/local/apps/serverLifecycle/serverLifecycle-local_solid.db +0 -0
  44. package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
  45. package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-wal +0 -0
  46. package/package.json +11 -9
  47. package/server/akanApp.ts +30 -34
  48. package/server/akanOption.ts +65 -7
  49. package/server/akanServer.ts +172 -7
  50. package/server/animatedImage.ts +83 -0
  51. package/server/artifact/routeClientCache.ts +14 -0
  52. package/server/assetEncoding.ts +47 -0
  53. package/server/devtools/signalSerializer.ts +2 -2
  54. package/server/devtools/types.ts +2 -2
  55. package/server/di/diLifecycle.ts +31 -3
  56. package/server/di/predefinedAdaptor.ts +6 -0
  57. package/server/imageOptimizer.ts +33 -46
  58. package/server/index.ts +1 -2
  59. package/server/mcp/McpAuth.ts +177 -0
  60. package/server/mcp/McpDispatcher.ts +245 -0
  61. package/server/mcp/McpEventStream.ts +76 -0
  62. package/server/mcp/McpExecutionContext.ts +105 -0
  63. package/server/mcp/McpRouter.ts +591 -0
  64. package/server/mcp/index.ts +5 -0
  65. package/server/resolver/CascadeRunner.ts +1 -1
  66. package/server/resolver/database.resolver.ts +42 -5
  67. package/server/resolver/service.resolver.ts +29 -0
  68. package/server/resolver/signal.resolver.ts +16 -1
  69. package/server/routeTreeBuilder.ts +2 -44
  70. package/server/rscWorker.tsx +6 -2
  71. package/server/subRouteIndexDocument.tsx +61 -0
  72. package/server/systemPageDocument.tsx +2 -2
  73. package/server/systemPages.tsx +49 -16
  74. package/server/vendor/akanjs-fetch.ts +1 -0
  75. package/server/webRouter.ts +159 -35
  76. package/service/agent.service.ts +14 -0
  77. package/service/base.service.ts +2 -1
  78. package/service/index.ts +1 -0
  79. package/service/predefinedAdaptor/database.adaptor.ts +78 -24
  80. package/service/predefinedAdaptor/deepseekLlm.ts +230 -0
  81. package/service/predefinedAdaptor/index.ts +3 -0
  82. package/service/predefinedAdaptor/insightQuery.ts +183 -0
  83. package/service/predefinedAdaptor/llm.adaptor.ts +76 -0
  84. package/service/predefinedAdaptor/role.adaptor.ts +2 -0
  85. package/service/predefinedAdaptor/schedule.adaptor.ts +12 -5
  86. package/service/serviceModule.ts +17 -0
  87. package/service/types.ts +4 -0
  88. package/signal/agent/AgentCatalogue.ts +165 -0
  89. package/signal/agent/index.ts +1 -0
  90. package/signal/agent.signal.ts +42 -0
  91. package/signal/agentTurn.ts +8 -0
  92. package/signal/agentTurnStream.ts +48 -0
  93. package/signal/base.signal.ts +2 -1
  94. package/signal/endpointInfo.ts +38 -2
  95. package/signal/guard.ts +13 -1
  96. package/signal/guards.ts +52 -1
  97. package/signal/index.ts +6 -0
  98. package/signal/mcp/McpDocument.ts +286 -0
  99. package/signal/mcp/McpProgress.ts +106 -0
  100. package/signal/mcp/McpUriTemplate.ts +85 -0
  101. package/signal/mcp/Msg.ts +368 -0
  102. package/signal/mcp/index.ts +5 -0
  103. package/signal/mcp/mcpProtocol.ts +120 -0
  104. package/signal/middleware.ts +7 -3
  105. package/signal/openapi/openapi.ts +32 -171
  106. package/signal/schema/JsonSchemaBuilder.ts +211 -0
  107. package/signal/schema/index.ts +1 -0
  108. package/signal/signalContext.ts +85 -9
  109. package/signal/slice.ts +9 -9
  110. package/signal/types.ts +1 -1
  111. package/store/action.ts +11 -22
  112. package/store/actionTag.ts +33 -0
  113. package/store/agent/AgentBridge.ts +323 -0
  114. package/store/agent/AgentContext.ts +74 -0
  115. package/store/agent/AgentPrompts.ts +82 -0
  116. package/store/agent/AgentVisibility.ts +68 -0
  117. package/store/agent/ScreenReader.ts +208 -0
  118. package/store/agent/StoreCatalogue.ts +351 -0
  119. package/store/agent/StoreSurfaceSource.ts +122 -0
  120. package/store/agent/index.ts +9 -0
  121. package/store/agent/storeSurface.ts +28 -0
  122. package/store/agent/types.ts +50 -0
  123. package/store/agentic/StToolBuilder.ts +199 -0
  124. package/store/agentic/attachAgentic.ts +22 -0
  125. package/store/agentic/index.ts +5 -0
  126. package/store/agentic/readableValue.ts +17 -0
  127. package/store/agentic/useStExpose.ts +18 -0
  128. package/store/agentic/useStState.ts +35 -0
  129. package/store/baseSt.ts +7 -0
  130. package/store/databaseStateNames.ts +31 -0
  131. package/store/formSetterNames.ts +21 -0
  132. package/store/index.ts +8 -0
  133. package/store/rootStore.ts +3 -1
  134. package/store/sliceRole.ts +36 -0
  135. package/store/state.ts +2 -12
  136. package/store/store.ts +19 -1
  137. package/store/storeInstance.ts +165 -20
  138. package/store/storeRegistry.ts +16 -1
  139. package/store/types.ts +18 -0
  140. package/store/withSelector.ts +7 -8
  141. package/test/registerDom.ts +4 -0
  142. package/types/base/symbols.d.ts +4 -0
  143. package/types/client/cn.d.ts +5 -0
  144. package/types/client/csrTypes.d.ts +2 -0
  145. package/types/common/Logger.d.ts +2 -0
  146. package/types/common/deepObjectify.d.ts +4 -2
  147. package/types/common/index.d.ts +2 -1
  148. package/types/common/mcpExposure.d.ts +60 -0
  149. package/types/common/routeConvention.d.ts +8 -0
  150. package/types/constant/fieldInfo.d.ts +1 -0
  151. package/types/constant/getDefault.d.ts +5 -0
  152. package/types/constant/index.d.ts +2 -0
  153. package/types/constant/labelOf.d.ts +6 -0
  154. package/types/constant/mask.d.ts +34 -0
  155. package/types/constant/purify.d.ts +2 -2
  156. package/types/constant/types.d.ts +2 -2
  157. package/types/dictionary/DictionaryLookup.d.ts +14 -0
  158. package/types/dictionary/agent.dictionary.d.ts +1 -0
  159. package/types/dictionary/agentTurn.dictionary.d.ts +1 -0
  160. package/types/dictionary/base.dictionary.d.ts +1 -1
  161. package/types/dictionary/dictInfo.d.ts +6 -0
  162. package/types/dictionary/dictionary.d.ts +11 -9
  163. package/types/dictionary/index.d.ts +1 -0
  164. package/types/document/database.d.ts +20 -0
  165. package/types/document/filterMeta.d.ts +1 -0
  166. package/types/document/index.d.ts +1 -0
  167. package/types/document/into.d.ts +6 -1
  168. package/types/document/noDocumentError.d.ts +12 -0
  169. package/types/fetch/agentTurn.d.ts +593 -0
  170. package/types/fetch/client/fetchClient.d.ts +10 -0
  171. package/types/fetch/fetchType/endpointFetch.type.d.ts +5 -3
  172. package/types/fetch/index.d.ts +1 -0
  173. package/types/server/akanOption.d.ts +35 -7
  174. package/types/server/akanServer.d.ts +44 -1
  175. package/types/server/animatedImage.d.ts +7 -0
  176. package/types/server/artifact/routeClientCache.d.ts +6 -0
  177. package/types/server/assetEncoding.d.ts +7 -0
  178. package/types/server/devtools/types.d.ts +2 -2
  179. package/types/server/di/predefinedAdaptor.d.ts +4 -1
  180. package/types/server/index.d.ts +0 -2
  181. package/types/server/mcp/McpAuth.d.ts +62 -0
  182. package/types/server/mcp/McpDispatcher.d.ts +54 -0
  183. package/types/server/mcp/McpEventStream.d.ts +18 -0
  184. package/types/server/mcp/McpExecutionContext.d.ts +44 -0
  185. package/types/server/mcp/McpRouter.d.ts +60 -0
  186. package/types/server/mcp/index.d.ts +5 -0
  187. package/types/server/mcp.d.ts +1 -0
  188. package/types/server/subRouteIndexDocument.d.ts +8 -0
  189. package/types/server/systemPageDocument.d.ts +1 -0
  190. package/types/server/systemPages.d.ts +5 -0
  191. package/types/server/vendor/akanjs-fetch.d.ts +1 -0
  192. package/types/service/agent.service.d.ts +12 -0
  193. package/types/service/base.service.d.ts +4 -0
  194. package/types/service/index.d.ts +1 -0
  195. package/types/service/predefinedAdaptor/database.adaptor.d.ts +24 -2
  196. package/types/service/predefinedAdaptor/deepseekLlm.d.ts +64 -0
  197. package/types/service/predefinedAdaptor/index.d.ts +3 -0
  198. package/types/service/predefinedAdaptor/insightQuery.d.ts +50 -0
  199. package/types/service/predefinedAdaptor/llm.adaptor.d.ts +68 -0
  200. package/types/service/predefinedAdaptor/role.adaptor.d.ts +2 -0
  201. package/types/service/predefinedAdaptor/schedule.adaptor.d.ts +10 -6
  202. package/types/service/types.d.ts +4 -1
  203. package/types/signal/agent/AgentCatalogue.d.ts +100 -0
  204. package/types/signal/agent/index.d.ts +1 -0
  205. package/types/signal/agent.d.ts +1 -0
  206. package/types/signal/agent.signal.d.ts +29 -0
  207. package/types/signal/agentTurn.d.ts +9 -0
  208. package/types/signal/agentTurnStream.d.ts +16 -0
  209. package/types/signal/base.signal.d.ts +1 -1
  210. package/types/signal/endpointInfo.d.ts +21 -3
  211. package/types/signal/guard.d.ts +11 -0
  212. package/types/signal/guards.d.ts +22 -1
  213. package/types/signal/index.d.ts +6 -0
  214. package/types/signal/mcp/McpDocument.d.ts +65 -0
  215. package/types/signal/mcp/McpProgress.d.ts +40 -0
  216. package/types/signal/mcp/McpUriTemplate.d.ts +26 -0
  217. package/types/signal/mcp/Msg.d.ts +143 -0
  218. package/types/signal/mcp/index.d.ts +5 -0
  219. package/types/signal/mcp/mcpProtocol.d.ts +107 -0
  220. package/types/signal/mcp.d.ts +1 -0
  221. package/types/signal/openapi/openapi.d.ts +3 -3
  222. package/types/signal/schema/JsonSchemaBuilder.d.ts +47 -0
  223. package/types/signal/schema/index.d.ts +1 -0
  224. package/types/signal/schema.d.ts +1 -0
  225. package/types/signal/signalContext.d.ts +16 -1
  226. package/types/signal/slice.d.ts +8 -8
  227. package/types/signal/types.d.ts +1 -1
  228. package/types/store/actionTag.d.ts +21 -0
  229. package/types/store/agent/AgentBridge.d.ts +77 -0
  230. package/types/store/agent/AgentContext.d.ts +16 -0
  231. package/types/store/agent/AgentPrompts.d.ts +31 -0
  232. package/types/store/agent/AgentVisibility.d.ts +21 -0
  233. package/types/store/agent/ScreenReader.d.ts +11 -0
  234. package/types/store/agent/StoreCatalogue.d.ts +26 -0
  235. package/types/store/agent/StoreSurfaceSource.d.ts +18 -0
  236. package/types/store/agent/index.d.ts +9 -0
  237. package/types/store/agent/storeSurface.d.ts +14 -0
  238. package/types/store/agent/types.d.ts +49 -0
  239. package/types/store/agent.d.ts +1 -0
  240. package/types/store/agentic/StToolBuilder.d.ts +41 -0
  241. package/types/store/agentic/attachAgentic.d.ts +14 -0
  242. package/types/store/agentic/index.d.ts +5 -0
  243. package/types/store/agentic/readableValue.d.ts +3 -0
  244. package/types/store/agentic/useStExpose.d.ts +8 -0
  245. package/types/store/agentic/useStState.d.ts +12 -0
  246. package/types/store/agentic.d.ts +1 -0
  247. package/types/store/baseSt.d.ts +29 -22
  248. package/types/store/databaseStateNames.d.ts +25 -0
  249. package/types/store/formSetterNames.d.ts +16 -0
  250. package/types/store/index.d.ts +7 -0
  251. package/types/store/rootStore.d.ts +5 -1
  252. package/types/store/sliceRole.d.ts +25 -0
  253. package/types/store/store.d.ts +7 -2
  254. package/types/store/storeInstance.d.ts +33 -1
  255. package/types/store/storeRegistry.d.ts +5 -0
  256. package/types/store/types.d.ts +15 -0
  257. package/types/store/withSelector.d.ts +7 -8
  258. package/types/test/registerDom.d.ts +1 -0
  259. package/types/ui/Agent/Approval.d.ts +7 -0
  260. package/types/ui/Agent/Bubble.d.ts +13 -0
  261. package/types/ui/Agent/Chat.d.ts +24 -0
  262. package/types/ui/Agent/Context.d.ts +9 -0
  263. package/types/ui/Agent/Dock.d.ts +16 -0
  264. package/types/ui/Agent/Guide.d.ts +9 -0
  265. package/types/ui/Agent/Section.d.ts +10 -0
  266. package/types/ui/Agent/StateKey.d.ts +16 -0
  267. package/types/ui/Agent/Tool.d.ts +15 -0
  268. package/types/ui/Agent/Transcript.d.ts +13 -0
  269. package/types/ui/Agent/Zone.d.ts +23 -0
  270. package/types/ui/Agent/fetchRunner.d.ts +12 -0
  271. package/types/ui/Agent/index.d.ts +17 -0
  272. package/types/ui/Agent/index_.d.ts +1 -0
  273. package/types/ui/Agent/sessionHistory.d.ts +12 -0
  274. package/types/ui/Agent.d.ts +1 -0
  275. package/types/ui/Badge.d.ts +1 -1
  276. package/types/ui/Button.d.ts +1 -1
  277. package/types/ui/CsrImage.d.ts +1 -1
  278. package/types/ui/Dropdown.d.ts +2 -0
  279. package/types/ui/Image.d.ts +3 -3
  280. package/types/ui/Layout/BottomInset.d.ts +2 -1
  281. package/types/ui/Layout/index.d.ts +1 -1
  282. package/types/ui/Signal/style.d.ts +4 -1
  283. package/types/ui/UiOverride/context.d.ts +14 -2
  284. package/types/ui/agentAttrs.d.ts +14 -0
  285. package/types/ui/index.d.ts +4 -1
  286. package/types/ui/overlayLayer.d.ts +24 -0
  287. package/types/ui/recipe/badgeRecipe.d.ts +7 -3
  288. package/types/ui/recipe/buttonRecipe.d.ts +7 -3
  289. package/types/ui/recipe/inputRecipe.d.ts +5 -1
  290. package/types/vendor/use-agentic/AgentProvider.d.ts +18 -0
  291. package/types/vendor/use-agentic/AgentScope.d.ts +9 -0
  292. package/types/vendor/use-agentic/AgentSession.d.ts +50 -0
  293. package/types/vendor/use-agentic/Agentic.d.ts +21 -0
  294. package/types/vendor/use-agentic/AgenticSurface.d.ts +44 -0
  295. package/types/vendor/use-agentic/httpRunner.d.ts +15 -0
  296. package/types/vendor/use-agentic/index.d.ts +13 -0
  297. package/types/vendor/use-agentic/surfaceContext.d.ts +5 -0
  298. package/types/vendor/use-agentic/types.d.ts +133 -0
  299. package/types/vendor/use-agentic/useAgent.d.ts +4 -0
  300. package/types/vendor/use-agentic/useAgentGuide.d.ts +6 -0
  301. package/types/vendor/use-agentic/useAgentResource.d.ts +7 -0
  302. package/types/vendor/use-agentic/useAgentState.d.ts +13 -0
  303. package/types/vendor/use-agentic/useAgentTool.d.ts +16 -0
  304. package/types/vendor/use-agentic.d.ts +1 -0
  305. package/types/webkit/index.d.ts +3 -0
  306. package/types/webkit/lazy.d.ts +12 -0
  307. package/types/webkit/useCsrValues.d.ts +3 -3
  308. package/types/webkit/useEscapeKey.d.ts +5 -0
  309. package/types/webkit/useFrameRuntime.d.ts +6 -1
  310. package/types/webkit/useScreenScope.d.ts +18 -0
  311. package/ui/Agent/Approval.tsx +29 -0
  312. package/ui/Agent/Bubble.tsx +74 -0
  313. package/ui/Agent/Chat.tsx +225 -0
  314. package/ui/Agent/Context.tsx +38 -0
  315. package/ui/Agent/Dock.tsx +72 -0
  316. package/ui/Agent/Guide.tsx +16 -0
  317. package/ui/Agent/Section.tsx +24 -0
  318. package/ui/Agent/StateKey.tsx +44 -0
  319. package/ui/Agent/Tool.tsx +66 -0
  320. package/ui/Agent/Transcript.tsx +33 -0
  321. package/ui/Agent/Zone.tsx +48 -0
  322. package/ui/Agent/fetchRunner.ts +30 -0
  323. package/ui/Agent/index.ts +12 -0
  324. package/ui/Agent/index_.tsx +4 -0
  325. package/ui/Agent/sessionHistory.ts +33 -0
  326. package/ui/Badge.tsx +3 -3
  327. package/ui/BottomSheet.tsx +5 -0
  328. package/ui/Button.tsx +6 -2
  329. package/ui/Constant/Doc.tsx +1 -1
  330. package/ui/CsrImage.tsx +1 -1
  331. package/ui/Data/ListContainer.tsx +1 -1
  332. package/ui/DatePicker.tsx +5 -4
  333. package/ui/Dialog/Modal.tsx +12 -15
  334. package/ui/DraggableList.tsx +3 -1
  335. package/ui/Dropdown.tsx +33 -11
  336. package/ui/Field.tsx +30 -16
  337. package/ui/Image.tsx +3 -3
  338. package/ui/Input.tsx +14 -5
  339. package/ui/Layout/BottomInset.tsx +6 -1
  340. package/ui/Load/Units.tsx +11 -2
  341. package/ui/Load/View.tsx +7 -2
  342. package/ui/Loading/ProgressBar.tsx +8 -1
  343. package/ui/Menu.tsx +7 -8
  344. package/ui/Model/EditModal.tsx +37 -2
  345. package/ui/Model/SureToRemove.tsx +2 -1
  346. package/ui/Model/index_.tsx +42 -15
  347. package/ui/ObjectId.tsx +3 -4
  348. package/ui/Pagination.tsx +3 -4
  349. package/ui/Popconfirm.tsx +8 -7
  350. package/ui/Select.tsx +6 -4
  351. package/ui/Signal/RestApi.tsx +43 -16
  352. package/ui/Signal/WebSocket.tsx +1 -1
  353. package/ui/Signal/style.ts +6 -1
  354. package/ui/Switch.tsx +2 -0
  355. package/ui/System/CSR.tsx +6 -2
  356. package/ui/System/ThemeToggle.tsx +55 -33
  357. package/ui/ToggleSelect.tsx +4 -3
  358. package/ui/Tooltip.tsx +2 -1
  359. package/ui/UiOverride/context.ts +14 -2
  360. package/ui/agentAttrs.ts +19 -0
  361. package/ui/index.ts +10 -1
  362. package/ui/overlayLayer.ts +39 -0
  363. package/ui/recipe/badgeRecipe.ts +22 -3
  364. package/ui/recipe/buttonRecipe.ts +51 -2
  365. package/ui/recipe/factory.ts +2 -2
  366. package/ui/recipe/inputRecipe.ts +18 -4
  367. package/vendor/use-agentic/AgentProvider.tsx +39 -0
  368. package/vendor/use-agentic/AgentScope.tsx +20 -0
  369. package/vendor/use-agentic/AgentSession.ts +292 -0
  370. package/vendor/use-agentic/Agentic.tsx +44 -0
  371. package/vendor/use-agentic/AgenticSurface.ts +294 -0
  372. package/vendor/use-agentic/WIRE.md +57 -0
  373. package/vendor/use-agentic/httpRunner.ts +115 -0
  374. package/vendor/use-agentic/index.ts +14 -0
  375. package/vendor/use-agentic/surfaceContext.ts +9 -0
  376. package/vendor/use-agentic/types.ts +144 -0
  377. package/vendor/use-agentic/useAgent.ts +17 -0
  378. package/vendor/use-agentic/useAgentGuide.ts +16 -0
  379. package/vendor/use-agentic/useAgentResource.ts +30 -0
  380. package/vendor/use-agentic/useAgentState.ts +61 -0
  381. package/vendor/use-agentic/useAgentTool.ts +55 -0
  382. package/webkit/bootCsr.tsx +2 -33
  383. package/webkit/index.ts +3 -0
  384. package/webkit/lazy.tsx +27 -3
  385. package/webkit/useCsrValues.ts +121 -4
  386. package/webkit/useEscapeKey.tsx +42 -0
  387. package/webkit/useFrameRuntime.ts +65 -32
  388. package/webkit/useScreenScope.tsx +49 -0
@@ -0,0 +1,31 @@
1
+ import type { AgentEndpoint } from "akanjs/signal";
2
+
3
+ import { serviceDictionary } from "./dictInfo";
4
+
5
+ export const agentDictionary = serviceDictionary(["en", "ko"])
6
+ .endpoint<AgentEndpoint>((fn) => ({
7
+ runAgentTurn: fn(["Run Agent Turn", "에이전트 턴 실행"])
8
+ .desc([
9
+ "Relays one in-page agent turn to the model and returns its answer; tools execute in the caller's browser",
10
+ "인페이지 에이전트 턴 하나를 모델에 릴레이하고 응답을 돌려준다. 툴 실행은 호출자의 브라우저에서 한다",
11
+ ])
12
+ .arg((t) => ({
13
+ messages: t(["Messages", "메시지"]).desc(["The whole transcript in wire shape", "와이어 형태의 전체 대화"]),
14
+ tools: t(["Tools", "툴"]).desc(["The published tool catalogue, schemas only", "게시된 툴 카탈로그 (스키마만)"]),
15
+ context: t(["Context", "컨텍스트"]).desc([
16
+ "Screen context blocks, forwarded as data",
17
+ "화면 컨텍스트 블록 (데이터로 전달)",
18
+ ]),
19
+ instructions: t(["Instructions", "지시문"]).desc(["App-level system instructions", "앱 수준 시스템 지시문"]),
20
+ })),
21
+ }))
22
+ .error({
23
+ llmUnavailable: [
24
+ "The agent model is unavailable — no LLM adaptor answered this turn",
25
+ "에이전트 모델을 사용할 수 없습니다. 이번 턴에 응답한 LLM 어댑터가 없습니다",
26
+ ],
27
+ deepseekRequestFailed: [
28
+ "DeepSeek request failed with status {status}",
29
+ "DeepSeek 요청이 실패했습니다 (status {status})",
30
+ ],
31
+ });
@@ -0,0 +1,29 @@
1
+ import type { AgentStop, AgentTurn } from "akanjs/signal";
2
+
3
+ import { scalarDictionary } from "./dictInfo";
4
+
5
+ export const agentTurnDictionary = scalarDictionary(["en", "ko"])
6
+ .of((t) =>
7
+ t(["Agent Turn", "에이전트 턴"]).desc([
8
+ "One assistant answer of an in-page agent turn",
9
+ "인페이지 에이전트 턴의 어시스턴트 응답 하나",
10
+ ]),
11
+ )
12
+ .model<AgentTurn>((t) => ({
13
+ text: t(["Text", "텍스트"]).desc([
14
+ "What the assistant said; empty when the turn is only tool calls",
15
+ "어시스턴트가 말한 내용. 툴 호출뿐인 턴에서는 비어 있다",
16
+ ]),
17
+ toolCalls: t(["Tool Calls", "툴 호출"]).desc([
18
+ "Tool calls the client should execute, as { id, name, args }",
19
+ "클라이언트가 실행할 툴 호출 목록 ({ id, name, args })",
20
+ ]),
21
+ stop: t(["Stop", "종료 사유"]).desc([
22
+ "Why the turn ended — end, or toolUse when tool results are awaited",
23
+ "턴이 끝난 이유 — end 또는 툴 결과를 기다리는 toolUse",
24
+ ]),
25
+ }))
26
+ .enum<AgentStop>("agentStop", (t) => ({
27
+ end: t(["End", "종료"]).desc(["The final answer", "최종 응답"]),
28
+ toolUse: t(["Tool Use", "툴 사용"]).desc(["The model awaits tool results", "모델이 툴 결과를 기다린다"]),
29
+ }));
@@ -48,6 +48,14 @@ export const baseDictionary = serviceDictionary(["en", "ko"])
48
48
  ok: ["OK", "확인"],
49
49
  cancel: ["Cancel", "취소"],
50
50
  unauthorized: ["Unauthorized", "권한 없음"],
51
+ agent: ["Agent", "에이전트"],
52
+ agentIntro: ["Ask about this page or tell the agent what to do.", "이 화면에 대해 묻거나 할 일을 지시해 보세요."],
53
+ agentPlaceholder: ["Message the agent...", "에이전트에게 메시지..."],
54
+ agentClear: ["Clear conversation", "대화 비우기"],
55
+ send: ["Send", "보내기"],
56
+ stop: ["Stop", "중지"],
57
+ approve: ["Approve", "승인"],
58
+ decline: ["Decline", "거절"],
51
59
  confirmClose: ["Are you sure you want to close the modal?", "모달을 닫으시겠습니까?"],
52
60
  textTooShortError: ["More than {minlength} characters needed.", "{minlength}자 이상 필요합니다."],
53
61
  textTooLongError: ["Less than {maxlength} characters needed.", "{maxlength}자 이하로 필요합니다."],
@@ -777,6 +777,7 @@ export class ModelDictInfo<
777
777
  });
778
778
  });
779
779
  }
780
+ /** Under its own `store` node rather than beside `signal`, because the two hold the same key by design. */
780
781
  #registerErrorToRoot(refName: string, rootDict: RootDictionary) {
781
782
  this.languages.forEach((language) => {
782
783
  ensureNode(getRootModelNode(rootDict, language, refName), "error");
@@ -803,6 +804,13 @@ export class ModelDictInfo<
803
804
  }
804
805
  }
805
806
 
807
+ /**
808
+ * Every parameter of `ModelDictInfo` is listed here positionally, so a parameter added to the class has to be
809
+ * added to all three lists below in the same slot. Omitting one does not fail to compile — inference silently
810
+ * shifts, so the last parameter falls off the end and becomes its default `never`, which reads at the call site
811
+ * as `l("<model>.<key>")` no longer existing.
812
+ */
813
+
806
814
  type AnyModelDictInfo = ModelDictInfo<any, any, any, any, any, any, any, any, any, any, any>;
807
815
 
808
816
  type MergeTwoModelDicts<ModelDict1, ModelDict2> =
@@ -1,10 +1,16 @@
1
- import type { BaseEndpoint } from "akanjs/signal";
1
+ import type { AgentEndpoint, AgentTurn, BaseEndpoint } from "akanjs/signal";
2
2
 
3
+ import { agentDictionary } from "./agent.dictionary";
4
+ import { agentTurnDictionary } from "./agentTurn.dictionary";
3
5
  import { baseDictionary } from "./base.dictionary";
4
- import { registerServiceTrans } from "./locale";
6
+ import { registerScalarTrans, registerServiceTrans } from "./locale";
5
7
  import { makeTrans } from "./trans";
6
8
 
7
- export const dictionary = { base: registerServiceTrans<"base", BaseEndpoint, typeof baseDictionary>(baseDictionary) };
9
+ export const dictionary = {
10
+ base: registerServiceTrans<"base", BaseEndpoint, typeof baseDictionary>(baseDictionary),
11
+ agentTurn: registerScalarTrans<"agentTurn", AgentTurn, typeof agentTurnDictionary>(agentTurnDictionary),
12
+ agent: registerServiceTrans<"agent", AgentEndpoint, typeof agentDictionary>(agentDictionary),
13
+ };
8
14
 
9
15
  export const { Err, translate, msg, getDictionary, getAllDictionary, __Dict_Key__, __Error_Key__ } =
10
16
  makeTrans(dictionary);
@@ -1,3 +1,4 @@
1
+ export * from "./DictionaryLookup";
1
2
  export * from "./dictInfo";
2
3
  export {
3
4
  __Dict_Key__,
@@ -3,6 +3,7 @@ import { Logger } from "akanjs/common";
3
3
  import type { DocumentModel, QueryOf } from "akanjs/constant";
4
4
  import type { CacheAdaptor, CacheSetOptions } from "akanjs/service";
5
5
  import type { DataLoader } from "./dataLoader";
6
+ import type { DocumentUpdateInput } from "./documentQuery";
6
7
  import type { ExtractQuery, ExtractSort, FilterInstance } from "./filterMeta";
7
8
  import type { CRUDEventType, Mdl, SaveEventType, UpdateResult } from "./into";
8
9
  import type { DataInputOf, FindQueryOption, ListQueryOption } from "./types";
@@ -25,6 +26,15 @@ export class CacheDatabase<T = unknown> {
25
26
  await this.cache.delete(this.refName, `${topic}:${key}`);
26
27
  }
27
28
  }
29
+ /**
30
+ * What `update<Filter>` returns. The patch cannot be a trailing parameter — a filter's own args may be optional,
31
+ * and no tuple type puts a required element after those — and leading it reads backwards. So it lands here, on a
32
+ * terminal `.set()` that mirrors the `UPDATE … SET …` it compiles to.
33
+ */
34
+ export interface UpdateChain<Doc = any> {
35
+ set(update: DocumentUpdateInput<Doc>): Promise<UpdateResult>;
36
+ }
37
+
28
38
  type QueryMethodOfKey<
29
39
  CapitalizedK extends string,
30
40
  Doc,
@@ -53,6 +63,14 @@ type QueryMethodOfKey<
53
63
  [K in `insight${CapitalizedK}`]: (...args: _Args) => Promise<Insight>;
54
64
  } & {
55
65
  [K in `query${CapitalizedK}`]: (...args: _Args) => _QueryOfDoc;
66
+ } & {
67
+ [K in `remove${CapitalizedK}`]: (...args: _Args) => Promise<UpdateResult>;
68
+ } & {
69
+ [K in `removeOne${CapitalizedK}`]: (...args: _Args) => Promise<UpdateResult>;
70
+ } & {
71
+ [K in `update${CapitalizedK}`]: (...args: _Args) => UpdateChain<Doc>;
72
+ } & {
73
+ [K in `updateOne${CapitalizedK}`]: (...args: _Args) => UpdateChain<Doc>;
56
74
  };
57
75
  type QueryMethodMap<Query, Doc, Insight, _FindQueryOption, _ListQueryOption, _QueryOfDoc> = {
58
76
  [K in keyof Query]: K extends string
@@ -106,6 +124,9 @@ type DatabaseModelWithQuerySort<
106
124
  __update: (id: string, data: Partial<Doc>) => Promise<Doc>;
107
125
  __remove: (id: string) => Promise<Doc>;
108
126
  __removeMany: (query: _QueryOfDoc) => Promise<UpdateResult>;
127
+ __removeOne: (query: _QueryOfDoc) => Promise<UpdateResult>;
128
+ __updateMany: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
129
+ __updateOne: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
109
130
  __list(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
110
131
  __listIds(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
111
132
  __find(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
@@ -98,6 +98,13 @@ export const fillMissingFilterArgs = (filterInfo: FilterInfo, args: unknown[]) =
98
98
  return [...args, ...Array(filterInfo.args.length - args.length).fill(undefined)];
99
99
  };
100
100
 
101
+ export const assertFilterFitsCrud = (refName: string, queryKey: string, className: string) => {
102
+ if (queryKey.toLowerCase() !== refName.toLowerCase()) return;
103
+ throw new Error(
104
+ `Filter "${queryKey}" on "${refName}" generates remove${className}/update${className}, which are the generated CRUD methods; rename the filter`,
105
+ );
106
+ };
107
+
101
108
  export type BaseFilterSortKey = "latest" | "oldest" | "relevance";
102
109
  export type BaseFilterQueryKey = "any";
103
110
  export type BaseFilterKey = BaseFilterSortKey | BaseFilterQueryKey;
package/document/index.ts CHANGED
@@ -7,5 +7,6 @@ export * from "./documentSchema";
7
7
  export * from "./filterMeta";
8
8
  export * from "./into";
9
9
  export * from "./loaderInfo";
10
+ export * from "./noDocumentError";
10
11
  export * from "./schema";
11
12
  export * from "./types";
package/document/into.ts CHANGED
@@ -77,16 +77,22 @@ export type Mdl<
77
77
  find(query: _RawQuery, projection?: _Projection): FindManyChain<Doc>;
78
78
  findOne(query: _RawQuery, projection?: _Projection): FindOneChain<Doc>;
79
79
  findById(id: string | undefined, projection?: _Projection): Promise<Doc | null>;
80
- countDocuments(query: _RawQuery): Promise<number>;
80
+ count(query: _RawQuery): Promise<number>;
81
81
  exists(query: _RawQuery): Promise<string | null>;
82
+
82
83
  updateOne(
83
84
  query: _RawQuery,
84
85
  update: DocumentUpdateInput<_RawDoc>,
85
86
  options?: DocumentUpdateOptions,
86
87
  ): Promise<UpdateResult>;
87
88
  updateMany(query: _RawQuery, update: DocumentUpdateInput<_RawDoc>): Promise<UpdateResult>;
89
+ removeOne(query: _RawQuery): Promise<UpdateResult>;
88
90
  removeMany(query: _RawQuery): Promise<UpdateResult>;
91
+ updateById(id: string, update: DocumentUpdateInput<_RawDoc>, options?: DocumentUpdateOptions): Promise<UpdateResult>;
92
+ removeById(id: string): Promise<UpdateResult>;
89
93
  bulkWrite(operations: BulkWriteOperation<Raw, _RawDoc, _RawQuery>[]): Promise<UpdateResult>;
94
+ /** @deprecated Renamed to `count`. */
95
+ countDocuments(query: _RawQuery): Promise<number>;
90
96
  };
91
97
 
92
98
  interface IntoConstantModel<T extends string, _CapitalizedRefName extends string, Raw, Insight> {
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A `pick` or a `get` that matched nothing. Typed so a caller can tell "you asked for something that is not
3
+ * there" from "we broke" — an agent-facing transport in particular must not log a stack and answer "the server
4
+ * failed" every time a model guesses an id.
5
+ *
6
+ * The message is unchanged from the bare `Error` this replaces, because callers already match on it, and the
7
+ * `statusCode` does not reach the HTTP layer: `isExceptionLike` wants a `toJSON` too, so a missing document
8
+ * stays a 500 there until someone decides framework-wide that it should be a 404.
9
+ */
10
+ export class NoDocumentError extends Error {
11
+ readonly statusCode = 404;
12
+ }
@@ -0,0 +1,19 @@
1
+ import { Any, enumOf } from "akanjs/base";
2
+ import { ConstantRegistry, via } from "akanjs/constant";
3
+
4
+ export class AgentStop extends enumOf("agentStop", ["end", "toolUse"] as const) {}
5
+
6
+ export class AgentTurn extends via((field) => ({
7
+ text: field(String, { default: "" }), // the assistant's words; empty when the turn is only tool calls
8
+ toolCalls: field([Any]), // { id, name, args } per call — args carries the tool's own schema, not a model's
9
+ stop: field(AgentStop, { default: "end" }),
10
+ })) {
11
+ isToolUse() {
12
+ return this.stop === "toolUse";
13
+ }
14
+ }
15
+
16
+ export const agentTurnConstant = ConstantRegistry.buildScalar("agentTurn" as const, AgentTurn, {
17
+ AgentTurn,
18
+ AgentStop,
19
+ });
@@ -10,6 +10,7 @@ import type {
10
10
  SerializedSlice,
11
11
  ServiceSignal,
12
12
  } from "akanjs/signal";
13
+ import { agentTurnConstant } from "../agentTurn";
13
14
  import type { ClientSignal, FetchClientType, FetchSignalInput, MergeAllFetchTypes, SliceMeta } from "../fetchType";
14
15
  import { memoizeRequestQuery, cookies as requestCookies, headers as requestHeaders } from "../requestStorage";
15
16
  import type { GetSliceMetaObjFromDatabaseSignals } from "../types";
@@ -37,6 +38,29 @@ export type FetchProxy<
37
38
  FetchClient &
38
39
  FetchType & { slice: SliceMetaObj; instance: FetchClient; _FetchType: FetchType; _SliceMetaObj: SliceMetaObj };
39
40
 
41
+ interface SharedClientState {
42
+ proxy: FetchProxy | null;
43
+ origin: string | null;
44
+ }
45
+
46
+ const SHARED_CLIENT_KEY = Symbol.for("akanjs.fetch.sharedClient");
47
+ const globalWithSharedClient = globalThis as typeof globalThis & { [SHARED_CLIENT_KEY]?: SharedClientState };
48
+ const sharedClientState: SharedClientState = globalWithSharedClient[SHARED_CLIENT_KEY] ?? { proxy: null, origin: null };
49
+ globalWithSharedClient[SHARED_CLIENT_KEY] = sharedClientState;
50
+
51
+ interface SharedSignalRegistry {
52
+ signal: { [key: string]: SerializedSignal };
53
+ version: number;
54
+ }
55
+
56
+ const SHARED_SIGNAL_KEY = Symbol.for("akanjs.fetch.sharedSignalRegistry");
57
+ const globalWithSharedSignal = globalThis as typeof globalThis & { [SHARED_SIGNAL_KEY]?: SharedSignalRegistry };
58
+ const sharedSignalRegistry: SharedSignalRegistry = globalWithSharedSignal[SHARED_SIGNAL_KEY] ?? {
59
+ signal: {},
60
+ version: 0,
61
+ };
62
+ globalWithSharedSignal[SHARED_SIGNAL_KEY] = sharedSignalRegistry;
63
+
40
64
  type ClientSignalMap<SigType extends { fetch: any }> = {
41
65
  [K in keyof SigType as SigType[K] extends DatabaseSignal<any, any, any, any>
42
66
  ? K
@@ -47,8 +71,9 @@ type ClientSignalMap<SigType extends { fetch: any }> = {
47
71
 
48
72
  /** Runtime fetch client that registers serialized Akan signals as HTTP/WebSocket methods. */
49
73
  export class FetchClient {
50
- static #sharedSerializedSignal: { [key: string]: SerializedSignal } = {};
51
- static #sharedRegistryVersion = 0;
74
+ static {
75
+ ConstantRegistry.setScalar(agentTurnConstant.refName, agentTurnConstant);
76
+ }
52
77
  readonly logger = new Logger("FetchClient");
53
78
  readonly origin: string;
54
79
  readonly http: HttpClient;
@@ -76,9 +101,31 @@ export class FetchClient {
76
101
  this.handler = this.#makeHandlerProxy();
77
102
  this.applySignal(serializedSignal);
78
103
  }
104
+ /**
105
+ * Every signal any client in this process has applied, which is the whole callable surface of the app.
106
+ *
107
+ * A copy, because this is the registry each client merges its own signals into and a reader that mutated it
108
+ * would change what the next client applies. Read by the agent catalogue, which needs the argument schemas.
109
+ */
110
+ static get sharedSerializedSignal(): { [key: string]: SerializedSignal } {
111
+ return { ...sharedSignalRegistry.signal };
112
+ }
79
113
  static resetSharedRegistry() {
80
- FetchClient.#sharedSerializedSignal = {};
81
- FetchClient.#sharedRegistryVersion++;
114
+ sharedSignalRegistry.signal = {};
115
+ sharedSignalRegistry.version++;
116
+ }
117
+ static resetSharedClient() {
118
+ sharedClientState.proxy = null;
119
+ sharedClientState.origin = null;
120
+ }
121
+ static #resolveSharedClientProxy(origin: string, Err?: ErrorConstructor) {
122
+ if (typeof window === "undefined") return null;
123
+
124
+ if (sharedClientState.proxy) return sharedClientState.origin === origin ? sharedClientState.proxy : null;
125
+ const proxy = FetchClient.#makeProxy<unknown, Record<string, SliceMeta>>(new FetchClient(origin, {}, {}, Err));
126
+ sharedClientState.proxy = proxy;
127
+ sharedClientState.origin = origin;
128
+ return proxy;
82
129
  }
83
130
  static #mergeSerializedSignalInto(
84
131
  serializedSignal: { [key: string]: SerializedSignal },
@@ -115,9 +162,9 @@ export class FetchClient {
115
162
  applySignal(serializedSignal: { [key: string]: SerializedSignal }, { share = true }: { share?: boolean } = {}) {
116
163
  if (share && Object.keys(serializedSignal).length > 0) {
117
164
  for (const [refName, signal] of Object.entries(serializedSignal))
118
- FetchClient.#mergeSerializedSignalInto(FetchClient.#sharedSerializedSignal, refName, signal);
119
- FetchClient.#sharedRegistryVersion++;
120
- this.#sharedRegistryAppliedVersion = FetchClient.#sharedRegistryVersion;
165
+ FetchClient.#mergeSerializedSignalInto(sharedSignalRegistry.signal, refName, signal);
166
+ sharedSignalRegistry.version++;
167
+ this.#sharedRegistryAppliedVersion = sharedSignalRegistry.version;
121
168
  }
122
169
  for (const [refName, signal] of Object.entries(serializedSignal))
123
170
  FetchClient.#mergeSerializedSignalInto(this.serializedSignal, refName, signal);
@@ -151,9 +198,9 @@ export class FetchClient {
151
198
  });
152
199
  }
153
200
  #syncSharedRegistry() {
154
- if (this.#sharedRegistryAppliedVersion === FetchClient.#sharedRegistryVersion) return;
155
- this.applySignal(FetchClient.#sharedSerializedSignal, { share: false });
156
- this.#sharedRegistryAppliedVersion = FetchClient.#sharedRegistryVersion;
201
+ if (this.#sharedRegistryAppliedVersion === sharedSignalRegistry.version) return;
202
+ this.applySignal(sharedSignalRegistry.signal, { share: false });
203
+ this.#sharedRegistryAppliedVersion = sharedSignalRegistry.version;
157
204
  }
158
205
  #getOrCreateHandler(key: string): FetchHandler | undefined {
159
206
  const current = this.#handlerStore[key];
@@ -223,6 +270,8 @@ export class FetchClient {
223
270
  const parseReturn = this.#makeReturnParser(endpoint.returns);
224
271
  const { bodyArgs, uploadArgs } = FetchClient.classifyHttpArgs(endpoint.args);
225
272
  switch (endpoint.type) {
273
+
274
+ case "prompt":
226
275
  case "query": {
227
276
  const queryFn = async (...argData: unknown[]) => {
228
277
  const args = argData.slice(0, argLength);
@@ -263,6 +312,7 @@ export class FetchClient {
263
312
  }
264
313
  #registerEndpoint(key: string, endpoint: SerializedEndpoint, prefix?: string) {
265
314
  switch (endpoint.type) {
315
+ case "prompt":
266
316
  case "query": {
267
317
  this.#setHandlerFactory(key, () => this.#makeHttpFn(key, endpoint, prefix));
268
318
  return;
@@ -684,9 +734,16 @@ export class FetchClient {
684
734
  });
685
735
  }
686
736
  });
687
- const instance = new FetchClient(getEnv().serverHttpUri, handler, serializedSignal);
737
+ const instance = new FetchClient(FetchClient.#originFromEnv(), handler, serializedSignal);
688
738
  return FetchClient.#makeProxy<MergeAllFetchTypes<Signals>, GetSliceMetaObjFromDatabaseSignals<Signals>>(instance);
689
739
  }
740
+ static #originFromEnv() {
741
+ try {
742
+ return getEnv().serverHttpUri;
743
+ } catch {
744
+ return "";
745
+ }
746
+ }
690
747
  static build<SigType extends { fetch: any }>(
691
748
  constant: object,
692
749
  serializedSignal: { [key: string]: SerializedSignal },
@@ -700,10 +757,11 @@ export class FetchClient {
700
757
  sig: ClientSignalMap<SigType>;
701
758
  fetch: SigType["fetch"];
702
759
  } {
703
- if (base) base.instance.applySignal(serializedSignal);
760
+ const shared = base ?? FetchClient.#resolveSharedClientProxy(origin, Err);
761
+ if (shared) shared.instance.applySignal(serializedSignal);
704
762
  if (base && Err) base.instance.setErrorConstructor(Err);
705
763
  const proxy =
706
- base ??
764
+ shared ??
707
765
  FetchClient.#makeProxy<unknown, Record<string, SliceMeta>>(new FetchClient(origin, {}, serializedSignal, Err));
708
766
  if (connect) proxy.instance.connect();
709
767
  const sig = {} as any;
@@ -40,6 +40,8 @@ export class WsClient {
40
40
  #roomSubscribeMap = new Map<string, SubscribeOption>();
41
41
  #listenerMap = new Map<string, Set<Listener>>();
42
42
  #destroyed = false;
43
+ #connectRequested = false;
44
+ #unconnectedWarnTimers = new Map<string, ReturnType<typeof setTimeout>>();
43
45
  #jwt: string | null = null;
44
46
  connected = false;
45
47
 
@@ -70,6 +72,7 @@ export class WsClient {
70
72
  }
71
73
 
72
74
  connect() {
75
+ this.#connectRequested = true;
73
76
  if (this.#ws && this.#ws.readyState !== WebSocket.CLOSED) return;
74
77
  this.logger.debug(`Connecting to ${this.url}`);
75
78
  this.#destroyed = false;
@@ -187,10 +190,13 @@ export class WsClient {
187
190
  destroy() {
188
191
  this.logger.debug(`WebSocket destroying`);
189
192
  this.#destroyed = true;
193
+ this.#connectRequested = false;
190
194
  if (this.#reconnectTimer) {
191
195
  clearTimeout(this.#reconnectTimer);
192
196
  this.#reconnectTimer = null;
193
197
  }
198
+ for (const timer of this.#unconnectedWarnTimers.values()) clearTimeout(timer);
199
+ this.#unconnectedWarnTimers.clear();
194
200
  this.#ws?.close();
195
201
  this.#ws = null;
196
202
  }
@@ -231,9 +237,18 @@ export class WsClient {
231
237
  }
232
238
  #warnNotConnected(action: "emit" | "subscribe", key: string) {
233
239
  console.warn(
234
- `[akanjs] WebSocket is not connected. Call fetch.instance.connect() or enable root layout "wsConnect" before ${action} "${key}".`,
240
+ `[akanjs] WebSocket is not connected. Call fetch.instance.connect(), or drop the root layout "wsConnect = false", before ${action} "${key}".`,
235
241
  );
236
242
  }
243
+ #warnUnconnectedSubscribe(key: string) {
244
+ if (this.#connectRequested || this.#unconnectedWarnTimers.has(key)) return;
245
+ const timer = setTimeout(() => {
246
+ this.#unconnectedWarnTimers.delete(key);
247
+ if (this.#connectRequested || this.#destroyed) return;
248
+ this.#warnNotConnected("subscribe", key);
249
+ }, 0);
250
+ this.#unconnectedWarnTimers.set(key, timer);
251
+ }
237
252
  emit(key: string, data: WsRequestPayload) {
238
253
  if (this.#ws?.readyState !== WebSocket.OPEN) {
239
254
  this.logger.warn("WebSocket not connected");
@@ -246,7 +261,7 @@ export class WsClient {
246
261
  }
247
262
  subscribe(option: { key: string; data: unknown[]; handleEvent: (data: unknown) => void }) {
248
263
  const roomId = WsClient.makeRoomId(option.key, option.data);
249
- if (!this.#ws) this.#warnNotConnected("subscribe", option.key);
264
+ if (!this.#ws) this.#warnUnconnectedSubscribe(option.key);
250
265
  if (!this.#roomSubscribeMap.has(roomId)) {
251
266
  this.#roomSubscribeMap.set(roomId, { key: option.key, data: option.data, listener: new Set() });
252
267
  if (this.#ws?.readyState === WebSocket.OPEN) {
@@ -7,6 +7,7 @@ import type {
7
7
  EndpInfoReqType,
8
8
  EndpointCls,
9
9
  EndpointInfo,
10
+ PromptMessage,
10
11
  SlceCnstFull,
11
12
  SlceCnstInsight,
12
13
  SlceCnstLight,
@@ -40,6 +41,9 @@ type QueryOrMutationFetchFn<E, SlceCls extends SliceCls | never> = (
40
41
  ...args: [...EndpInfoArgs<E>, fetchPolicy?: FetchPolicy]
41
42
  ) => Promise<EndpInfoReturns<E, SlceCls>>;
42
43
 
44
+ /** Typed off `PromptResult` rather than the endpoint's return ref, which is the `Any` carrier a prompt rides on. */
45
+ type PromptFetchFn<E> = (...args: [...EndpInfoArgs<E>, fetchPolicy?: FetchPolicy]) => Promise<PromptMessage[]>;
46
+
43
47
  type MessageEmitFn<E> = (...args: EndpInfoArgs<E>) => void;
44
48
 
45
49
  type MessageListenFn<E, SlceCls extends SliceCls | never> = (
@@ -58,12 +62,14 @@ type PubsubSubscribeFn<E, SlceCls extends SliceCls | never> = (
58
62
  type PrimaryFetchFn<E, SlceCls extends SliceCls | never> =
59
63
  EndpInfoReqType<E> extends "query" | "mutation"
60
64
  ? QueryOrMutationFetchFn<E, SlceCls>
61
- : EndpInfoReqType<E> extends "message"
62
- ? MessageEmitFn<E>
63
- : never;
65
+ : EndpInfoReqType<E> extends "prompt"
66
+ ? PromptFetchFn<E>
67
+ : EndpInfoReqType<E> extends "message"
68
+ ? MessageEmitFn<E>
69
+ : never;
64
70
 
65
71
  type PrimaryFetchType<EInfoObj extends { [key: string]: EndpointInfo }, SlceCls extends SliceCls | never> = {
66
- [K in keyof EInfoObj as EndpInfoReqType<EInfoObj[K]> extends "query" | "mutation" | "message"
72
+ [K in keyof EInfoObj as EndpInfoReqType<EInfoObj[K]> extends "query" | "mutation" | "prompt" | "message"
67
73
  ? K
68
74
  : never]: PrimaryFetchFn<EInfoObj[K], SlceCls>;
69
75
  };
package/fetch/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./agentTurn";
1
2
  export * from "./client";
2
3
  export * from "./fetchType";
3
4
  export * from "./requestStorage";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akanjs",
3
- "version": "3.0.0-alpha.2",
3
+ "version": "3.0.0-alpha.21",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -180,7 +180,6 @@
180
180
  "dependencies": {
181
181
  "dayjs": "^1.11.20",
182
182
  "immer": "^11.1.8",
183
- "sharp": "^0.34.5",
184
183
  "tailwind-merge": "^3.3.1",
185
184
  "tailwind-variants": "^3.3.0"
186
185
  },
@@ -202,6 +201,7 @@
202
201
  "@capacitor/preferences": "^8.0.1",
203
202
  "@capacitor/push-notifications": "^8.1.1",
204
203
  "@capgo/capacitor-updater": "^8.46.1",
204
+ "@happy-dom/global-registrator": "^20.11.2",
205
205
  "@libsql/client": "^0.17.3",
206
206
  "@playwright/test": "^1.60.0",
207
207
  "@react-spring/web": "^10.1.0",
@@ -210,8 +210,8 @@
210
210
  "capacitor-plugin-safe-area": "^5.0.0",
211
211
  "chance": "^1.1.13",
212
212
  "cordova-plugin-purchase": "^13.16.0",
213
- "croner": "^10.0.1",
214
213
  "firebase": "^12.13.0",
214
+ "happy-dom": "^20.11.2",
215
215
  "ioredis": "^5.10.1",
216
216
  "mermaid": "^11.15.0",
217
217
  "postgres": "^3.4.9",
@@ -225,7 +225,6 @@
225
225
  "react-simple-pull-to-refresh": "^1.3.4",
226
226
  "react-spring": "^10.0.4",
227
227
  "scheduler": "^0.27.0",
228
- "sharp": "^0.34.5",
229
228
  "tailwind-scrollbar": "^4.0.2",
230
229
  "typescript": "^6.0.3"
231
230
  },
@@ -281,6 +280,9 @@
281
280
  "@capgo/capacitor-updater": {
282
281
  "optional": true
283
282
  },
283
+ "@happy-dom/global-registrator": {
284
+ "optional": true
285
+ },
284
286
  "@libsql/client": {
285
287
  "optional": true
286
288
  },
@@ -305,10 +307,10 @@
305
307
  "cordova-plugin-purchase": {
306
308
  "optional": true
307
309
  },
308
- "croner": {
310
+ "firebase": {
309
311
  "optional": true
310
312
  },
311
- "firebase": {
313
+ "happy-dom": {
312
314
  "optional": true
313
315
  },
314
316
  "ioredis": {
@@ -358,14 +360,14 @@
358
360
  }
359
361
  },
360
362
  "devDependencies": {
361
- "@biomejs/biome": "2.4.4",
362
- "@types/bun": "^1.3.14"
363
+ "@biomejs/biome": "2.5.8",
364
+ "@types/bun": "^1.4.0"
363
365
  },
364
366
  "bun": {
365
367
  "platform": "bun"
366
368
  },
367
369
  "engines": {
368
- "bun": ">=1.3.13"
370
+ "bun": ">=1.4.0"
369
371
  },
370
372
  "main": "./index.ts"
371
373
  }