@jini-ai/chat 0.1.0

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 (444) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +109 -0
  3. package/dist/core/agentic/chat-capabilities.d.ts +19 -0
  4. package/dist/core/agentic/chat-capabilities.d.ts.map +1 -0
  5. package/dist/core/agentic/chat-capabilities.js +106 -0
  6. package/dist/core/agentic/chat-capabilities.js.map +1 -0
  7. package/dist/core/agentic/index.d.ts +22 -0
  8. package/dist/core/agentic/index.d.ts.map +1 -0
  9. package/dist/core/agentic/index.js +21 -0
  10. package/dist/core/agentic/index.js.map +1 -0
  11. package/dist/core/events.d.ts +84 -0
  12. package/dist/core/events.d.ts.map +1 -0
  13. package/dist/core/events.js +14 -0
  14. package/dist/core/events.js.map +1 -0
  15. package/dist/core/index.d.ts +40 -0
  16. package/dist/core/index.d.ts.map +1 -0
  17. package/dist/core/index.js +40 -0
  18. package/dist/core/index.js.map +1 -0
  19. package/dist/core/messages.d.ts +53 -0
  20. package/dist/core/messages.d.ts.map +1 -0
  21. package/dist/core/messages.js +16 -0
  22. package/dist/core/messages.js.map +1 -0
  23. package/dist/core/partial-json.d.ts +36 -0
  24. package/dist/core/partial-json.d.ts.map +1 -0
  25. package/dist/core/partial-json.js +119 -0
  26. package/dist/core/partial-json.js.map +1 -0
  27. package/dist/core/persistence/index.d.ts +11 -0
  28. package/dist/core/persistence/index.d.ts.map +1 -0
  29. package/dist/core/persistence/index.js +11 -0
  30. package/dist/core/persistence/index.js.map +1 -0
  31. package/dist/core/persistence/ports.d.ts +124 -0
  32. package/dist/core/persistence/ports.d.ts.map +1 -0
  33. package/dist/core/persistence/ports.js +2 -0
  34. package/dist/core/persistence/ports.js.map +1 -0
  35. package/dist/core/persistence/title.d.ts +35 -0
  36. package/dist/core/persistence/title.d.ts.map +1 -0
  37. package/dist/core/persistence/title.js +137 -0
  38. package/dist/core/persistence/title.js.map +1 -0
  39. package/dist/core/question-form/format.d.ts +27 -0
  40. package/dist/core/question-form/format.d.ts.map +1 -0
  41. package/dist/core/question-form/format.js +45 -0
  42. package/dist/core/question-form/format.js.map +1 -0
  43. package/dist/core/question-form/normalize.d.ts +30 -0
  44. package/dist/core/question-form/normalize.d.ts.map +1 -0
  45. package/dist/core/question-form/normalize.js +192 -0
  46. package/dist/core/question-form/normalize.js.map +1 -0
  47. package/dist/core/question-form/scan.d.ts +50 -0
  48. package/dist/core/question-form/scan.d.ts.map +1 -0
  49. package/dist/core/question-form/scan.js +404 -0
  50. package/dist/core/question-form/scan.js.map +1 -0
  51. package/dist/core/question-form/types.d.ts +83 -0
  52. package/dist/core/question-form/types.d.ts.map +1 -0
  53. package/dist/core/question-form/types.js +11 -0
  54. package/dist/core/question-form/types.js.map +1 -0
  55. package/dist/core/question-form.d.ts +39 -0
  56. package/dist/core/question-form.d.ts.map +1 -0
  57. package/dist/core/question-form.js +4 -0
  58. package/dist/core/question-form.js.map +1 -0
  59. package/dist/core/todos.d.ts +70 -0
  60. package/dist/core/todos.d.ts.map +1 -0
  61. package/dist/core/todos.js +175 -0
  62. package/dist/core/todos.js.map +1 -0
  63. package/dist/core/tool-events.d.ts +18 -0
  64. package/dist/core/tool-events.d.ts.map +1 -0
  65. package/dist/core/tool-events.js +36 -0
  66. package/dist/core/tool-events.js.map +1 -0
  67. package/dist/core/tools.d.ts +51 -0
  68. package/dist/core/tools.d.ts.map +1 -0
  69. package/dist/core/tools.js +41 -0
  70. package/dist/core/tools.js.map +1 -0
  71. package/dist/core/transcript.d.ts +81 -0
  72. package/dist/core/transcript.d.ts.map +1 -0
  73. package/dist/core/transcript.js +133 -0
  74. package/dist/core/transcript.js.map +1 -0
  75. package/dist/core/transport.d.ts +109 -0
  76. package/dist/core/transport.d.ts.map +1 -0
  77. package/dist/core/transport.js +2 -0
  78. package/dist/core/transport.js.map +1 -0
  79. package/dist/core/util/index.d.ts +16 -0
  80. package/dist/core/util/index.d.ts.map +1 -0
  81. package/dist/core/util/index.js +16 -0
  82. package/dist/core/util/index.js.map +1 -0
  83. package/dist/core/util/manifest.d.ts +39 -0
  84. package/dist/core/util/manifest.d.ts.map +1 -0
  85. package/dist/core/util/manifest.js +173 -0
  86. package/dist/core/util/manifest.js.map +1 -0
  87. package/dist/core/util/markdown-context.d.ts +47 -0
  88. package/dist/core/util/markdown-context.d.ts.map +1 -0
  89. package/dist/core/util/markdown-context.js +125 -0
  90. package/dist/core/util/markdown-context.js.map +1 -0
  91. package/dist/core/util/markup-attributes.d.ts +20 -0
  92. package/dist/core/util/markup-attributes.d.ts.map +1 -0
  93. package/dist/core/util/markup-attributes.js +33 -0
  94. package/dist/core/util/markup-attributes.js.map +1 -0
  95. package/dist/core/util/parser.d.ts +42 -0
  96. package/dist/core/util/parser.d.ts.map +1 -0
  97. package/dist/core/util/parser.js +238 -0
  98. package/dist/core/util/parser.js.map +1 -0
  99. package/dist/core/util/pointer.d.ts +28 -0
  100. package/dist/core/util/pointer.d.ts.map +1 -0
  101. package/dist/core/util/pointer.js +75 -0
  102. package/dist/core/util/pointer.js.map +1 -0
  103. package/dist/core/util/recover.d.ts +40 -0
  104. package/dist/core/util/recover.d.ts.map +1 -0
  105. package/dist/core/util/recover.js +117 -0
  106. package/dist/core/util/recover.js.map +1 -0
  107. package/dist/core/util/strip.d.ts +112 -0
  108. package/dist/core/util/strip.d.ts.map +1 -0
  109. package/dist/core/util/strip.js +333 -0
  110. package/dist/core/util/strip.js.map +1 -0
  111. package/dist/core/util/types.d.ts +31 -0
  112. package/dist/core/util/types.d.ts.map +1 -0
  113. package/dist/core/util/types.js +2 -0
  114. package/dist/core/util/types.js.map +1 -0
  115. package/dist/core/util/validate.d.ts +50 -0
  116. package/dist/core/util/validate.d.ts.map +1 -0
  117. package/dist/core/util/validate.js +202 -0
  118. package/dist/core/util/validate.js.map +1 -0
  119. package/dist/react/agent-bridge/frontend-session-bridge.d.ts +45 -0
  120. package/dist/react/agent-bridge/frontend-session-bridge.d.ts.map +1 -0
  121. package/dist/react/agent-bridge/frontend-session-bridge.js +214 -0
  122. package/dist/react/agent-bridge/frontend-session-bridge.js.map +1 -0
  123. package/dist/react/artifact-types.d.ts +61 -0
  124. package/dist/react/artifact-types.d.ts.map +1 -0
  125. package/dist/react/artifact-types.js +33 -0
  126. package/dist/react/artifact-types.js.map +1 -0
  127. package/dist/react/chat-pane.d.ts +21 -0
  128. package/dist/react/chat-pane.d.ts.map +1 -0
  129. package/dist/react/chat-pane.js +20 -0
  130. package/dist/react/chat-pane.js.map +1 -0
  131. package/dist/react/components/A2uiSurfaceCard.d.ts +35 -0
  132. package/dist/react/components/A2uiSurfaceCard.d.ts.map +1 -0
  133. package/dist/react/components/A2uiSurfaceCard.js +272 -0
  134. package/dist/react/components/A2uiSurfaceCard.js.map +1 -0
  135. package/dist/react/components/AttachmentTray.d.ts +6 -0
  136. package/dist/react/components/AttachmentTray.d.ts.map +1 -0
  137. package/dist/react/components/AttachmentTray.js +30 -0
  138. package/dist/react/components/AttachmentTray.js.map +1 -0
  139. package/dist/react/components/ChatFab.d.ts +8 -0
  140. package/dist/react/components/ChatFab.d.ts.map +1 -0
  141. package/dist/react/components/ChatFab.js +24 -0
  142. package/dist/react/components/ChatFab.js.map +1 -0
  143. package/dist/react/components/Composer.d.ts +34 -0
  144. package/dist/react/components/Composer.d.ts.map +1 -0
  145. package/dist/react/components/Composer.js +300 -0
  146. package/dist/react/components/Composer.js.map +1 -0
  147. package/dist/react/components/ComposerDiscovery.d.ts +46 -0
  148. package/dist/react/components/ComposerDiscovery.d.ts.map +1 -0
  149. package/dist/react/components/ComposerDiscovery.js +38 -0
  150. package/dist/react/components/ComposerDiscovery.js.map +1 -0
  151. package/dist/react/components/ConversationList.d.ts +31 -0
  152. package/dist/react/components/ConversationList.d.ts.map +1 -0
  153. package/dist/react/components/ConversationList.js +221 -0
  154. package/dist/react/components/ConversationList.js.map +1 -0
  155. package/dist/react/components/ExtEventErrorBoundary.d.ts +35 -0
  156. package/dist/react/components/ExtEventErrorBoundary.d.ts.map +1 -0
  157. package/dist/react/components/ExtEventErrorBoundary.js +38 -0
  158. package/dist/react/components/ExtEventErrorBoundary.js.map +1 -0
  159. package/dist/react/components/Icon.d.ts +17 -0
  160. package/dist/react/components/Icon.d.ts.map +1 -0
  161. package/dist/react/components/Icon.js +46 -0
  162. package/dist/react/components/Icon.js.map +1 -0
  163. package/dist/react/components/JiniChatProvider.d.ts +45 -0
  164. package/dist/react/components/JiniChatProvider.d.ts.map +1 -0
  165. package/dist/react/components/JiniChatProvider.js +44 -0
  166. package/dist/react/components/JiniChatProvider.js.map +1 -0
  167. package/dist/react/components/Markdown.d.ts +5 -0
  168. package/dist/react/components/Markdown.d.ts.map +1 -0
  169. package/dist/react/components/Markdown.js +390 -0
  170. package/dist/react/components/Markdown.js.map +1 -0
  171. package/dist/react/components/McpUiSurfaceCard.d.ts +51 -0
  172. package/dist/react/components/McpUiSurfaceCard.d.ts.map +1 -0
  173. package/dist/react/components/McpUiSurfaceCard.js +159 -0
  174. package/dist/react/components/McpUiSurfaceCard.js.map +1 -0
  175. package/dist/react/components/MessageList.d.ts +15 -0
  176. package/dist/react/components/MessageList.d.ts.map +1 -0
  177. package/dist/react/components/MessageList.js +81 -0
  178. package/dist/react/components/MessageList.js.map +1 -0
  179. package/dist/react/components/MessageRow.d.ts +60 -0
  180. package/dist/react/components/MessageRow.d.ts.map +1 -0
  181. package/dist/react/components/MessageRow.js +156 -0
  182. package/dist/react/components/MessageRow.js.map +1 -0
  183. package/dist/react/components/NextStepActions.d.ts +34 -0
  184. package/dist/react/components/NextStepActions.d.ts.map +1 -0
  185. package/dist/react/components/NextStepActions.js +9 -0
  186. package/dist/react/components/NextStepActions.js.map +1 -0
  187. package/dist/react/components/QuestionForm.d.ts +26 -0
  188. package/dist/react/components/QuestionForm.d.ts.map +1 -0
  189. package/dist/react/components/QuestionForm.js +238 -0
  190. package/dist/react/components/QuestionForm.js.map +1 -0
  191. package/dist/react/components/QuestionsPanel.d.ts +13 -0
  192. package/dist/react/components/QuestionsPanel.d.ts.map +1 -0
  193. package/dist/react/components/QuestionsPanel.js +33 -0
  194. package/dist/react/components/QuestionsPanel.js.map +1 -0
  195. package/dist/react/components/TodoCard.d.ts +8 -0
  196. package/dist/react/components/TodoCard.d.ts.map +1 -0
  197. package/dist/react/components/TodoCard.js +29 -0
  198. package/dist/react/components/TodoCard.js.map +1 -0
  199. package/dist/react/components/ToolCard.d.ts +22 -0
  200. package/dist/react/components/ToolCard.d.ts.map +1 -0
  201. package/dist/react/components/ToolCard.js +298 -0
  202. package/dist/react/components/ToolCard.js.map +1 -0
  203. package/dist/react/components/composer-discovery.d.ts +107 -0
  204. package/dist/react/components/composer-discovery.d.ts.map +1 -0
  205. package/dist/react/components/composer-discovery.js +176 -0
  206. package/dist/react/components/composer-discovery.js.map +1 -0
  207. package/dist/react/ext-event-renderer-registry.d.ts +51 -0
  208. package/dist/react/ext-event-renderer-registry.d.ts.map +1 -0
  209. package/dist/react/ext-event-renderer-registry.js +20 -0
  210. package/dist/react/ext-event-renderer-registry.js.map +1 -0
  211. package/dist/react/features/chat-pane/agent-tools.d.ts +14 -0
  212. package/dist/react/features/chat-pane/agent-tools.d.ts.map +1 -0
  213. package/dist/react/features/chat-pane/agent-tools.js +22 -0
  214. package/dist/react/features/chat-pane/agent-tools.js.map +1 -0
  215. package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts +12 -0
  216. package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts.map +1 -0
  217. package/dist/react/features/chat-pane/components/AgentRuntimePicker.js +106 -0
  218. package/dist/react/features/chat-pane/components/AgentRuntimePicker.js.map +1 -0
  219. package/dist/react/features/chat-pane/components/ChatPane.d.ts +10 -0
  220. package/dist/react/features/chat-pane/components/ChatPane.d.ts.map +1 -0
  221. package/dist/react/features/chat-pane/components/ChatPane.js +169 -0
  222. package/dist/react/features/chat-pane/components/ChatPane.js.map +1 -0
  223. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts +21 -0
  224. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts.map +1 -0
  225. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js +213 -0
  226. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js.map +1 -0
  227. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts +70 -0
  228. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts.map +1 -0
  229. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js +76 -0
  230. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js.map +1 -0
  231. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts +133 -0
  232. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts.map +1 -0
  233. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js +258 -0
  234. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js.map +1 -0
  235. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts +66 -0
  236. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts.map +1 -0
  237. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +224 -0
  238. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js.map +1 -0
  239. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts +38 -0
  240. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts.map +1 -0
  241. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js +252 -0
  242. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js.map +1 -0
  243. package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.d.ts +16 -0
  244. package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.d.ts.map +1 -0
  245. package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.js +59 -0
  246. package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.js.map +1 -0
  247. package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.d.ts +26 -0
  248. package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.d.ts.map +1 -0
  249. package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.js +74 -0
  250. package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.js.map +1 -0
  251. package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.d.ts +25 -0
  252. package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.d.ts.map +1 -0
  253. package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js +88 -0
  254. package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js.map +1 -0
  255. package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.d.ts +38 -0
  256. package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.d.ts.map +1 -0
  257. package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js +184 -0
  258. package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js.map +1 -0
  259. package/dist/react/features/chat-pane/index.d.ts +12 -0
  260. package/dist/react/features/chat-pane/index.d.ts.map +1 -0
  261. package/dist/react/features/chat-pane/index.js +11 -0
  262. package/dist/react/features/chat-pane/index.js.map +1 -0
  263. package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.d.ts +12 -0
  264. package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.d.ts.map +1 -0
  265. package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.js +102 -0
  266. package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.js.map +1 -0
  267. package/dist/react/features/chat-pane/react/components/ChatPane.d.ts +10 -0
  268. package/dist/react/features/chat-pane/react/components/ChatPane.d.ts.map +1 -0
  269. package/dist/react/features/chat-pane/react/components/ChatPane.js +137 -0
  270. package/dist/react/features/chat-pane/react/components/ChatPane.js.map +1 -0
  271. package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.d.ts +133 -0
  272. package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.d.ts.map +1 -0
  273. package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.js +258 -0
  274. package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.js.map +1 -0
  275. package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.d.ts +66 -0
  276. package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.d.ts.map +1 -0
  277. package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.js +223 -0
  278. package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.js.map +1 -0
  279. package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.d.ts +38 -0
  280. package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.d.ts.map +1 -0
  281. package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.js +252 -0
  282. package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.js.map +1 -0
  283. package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.d.ts +26 -0
  284. package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.d.ts.map +1 -0
  285. package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.js +60 -0
  286. package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.js.map +1 -0
  287. package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.d.ts +25 -0
  288. package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.d.ts.map +1 -0
  289. package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.js +83 -0
  290. package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.js.map +1 -0
  291. package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.d.ts +38 -0
  292. package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.d.ts.map +1 -0
  293. package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.js +184 -0
  294. package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.js.map +1 -0
  295. package/dist/react/features/chat-pane/react/styles.d.ts +2 -0
  296. package/dist/react/features/chat-pane/react/styles.d.ts.map +1 -0
  297. package/dist/react/features/chat-pane/react/styles.js +863 -0
  298. package/dist/react/features/chat-pane/react/styles.js.map +1 -0
  299. package/dist/react/features/chat-pane/rules.d.ts +31 -0
  300. package/dist/react/features/chat-pane/rules.d.ts.map +1 -0
  301. package/dist/react/features/chat-pane/rules.js +81 -0
  302. package/dist/react/features/chat-pane/rules.js.map +1 -0
  303. package/dist/react/features/chat-pane/styles.d.ts +2 -0
  304. package/dist/react/features/chat-pane/styles.d.ts.map +1 -0
  305. package/dist/react/features/chat-pane/styles.js +1327 -0
  306. package/dist/react/features/chat-pane/styles.js.map +1 -0
  307. package/dist/react/features/chat-pane/types.d.ts +248 -0
  308. package/dist/react/features/chat-pane/types.d.ts.map +1 -0
  309. package/dist/react/features/chat-pane/types.js +2 -0
  310. package/dist/react/features/chat-pane/types.js.map +1 -0
  311. package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts +7 -0
  312. package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts.map +1 -0
  313. package/dist/react/features/model-picker/components/CredentialStatusBadge.js +20 -0
  314. package/dist/react/features/model-picker/components/CredentialStatusBadge.js.map +1 -0
  315. package/dist/react/features/model-picker/components/ModelPicker.d.ts +9 -0
  316. package/dist/react/features/model-picker/components/ModelPicker.d.ts.map +1 -0
  317. package/dist/react/features/model-picker/components/ModelPicker.js +34 -0
  318. package/dist/react/features/model-picker/components/ModelPicker.js.map +1 -0
  319. package/dist/react/features/model-picker/constants.d.ts +6 -0
  320. package/dist/react/features/model-picker/constants.d.ts.map +1 -0
  321. package/dist/react/features/model-picker/constants.js +9 -0
  322. package/dist/react/features/model-picker/constants.js.map +1 -0
  323. package/dist/react/features/model-picker/dependencies.d.ts +11 -0
  324. package/dist/react/features/model-picker/dependencies.d.ts.map +1 -0
  325. package/dist/react/features/model-picker/dependencies.js +10 -0
  326. package/dist/react/features/model-picker/dependencies.js.map +1 -0
  327. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts +27 -0
  328. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts.map +1 -0
  329. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js +62 -0
  330. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js.map +1 -0
  331. package/dist/react/features/model-picker/index.d.ts +32 -0
  332. package/dist/react/features/model-picker/index.d.ts.map +1 -0
  333. package/dist/react/features/model-picker/index.js +29 -0
  334. package/dist/react/features/model-picker/index.js.map +1 -0
  335. package/dist/react/features/model-picker/ports.d.ts +11 -0
  336. package/dist/react/features/model-picker/ports.d.ts.map +1 -0
  337. package/dist/react/features/model-picker/ports.js +2 -0
  338. package/dist/react/features/model-picker/ports.js.map +1 -0
  339. package/dist/react/features/model-picker/react/components/CredentialStatusBadge.d.ts +7 -0
  340. package/dist/react/features/model-picker/react/components/CredentialStatusBadge.d.ts.map +1 -0
  341. package/dist/react/features/model-picker/react/components/CredentialStatusBadge.js +20 -0
  342. package/dist/react/features/model-picker/react/components/CredentialStatusBadge.js.map +1 -0
  343. package/dist/react/features/model-picker/react/components/ModelPicker.d.ts +9 -0
  344. package/dist/react/features/model-picker/react/components/ModelPicker.d.ts.map +1 -0
  345. package/dist/react/features/model-picker/react/components/ModelPicker.js +34 -0
  346. package/dist/react/features/model-picker/react/components/ModelPicker.js.map +1 -0
  347. package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.d.ts +27 -0
  348. package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.d.ts.map +1 -0
  349. package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.js +62 -0
  350. package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.js.map +1 -0
  351. package/dist/react/features/model-picker/rules.d.ts +26 -0
  352. package/dist/react/features/model-picker/rules.d.ts.map +1 -0
  353. package/dist/react/features/model-picker/rules.js +84 -0
  354. package/dist/react/features/model-picker/rules.js.map +1 -0
  355. package/dist/react/features/model-picker/types.d.ts +38 -0
  356. package/dist/react/features/model-picker/types.d.ts.map +1 -0
  357. package/dist/react/features/model-picker/types.js +2 -0
  358. package/dist/react/features/model-picker/types.js.map +1 -0
  359. package/dist/react/hooks/composer-draft-cache.d.ts +65 -0
  360. package/dist/react/hooks/composer-draft-cache.d.ts.map +1 -0
  361. package/dist/react/hooks/composer-draft-cache.js +89 -0
  362. package/dist/react/hooks/composer-draft-cache.js.map +1 -0
  363. package/dist/react/hooks/context.d.ts +18 -0
  364. package/dist/react/hooks/context.d.ts.map +1 -0
  365. package/dist/react/hooks/context.js +60 -0
  366. package/dist/react/hooks/context.js.map +1 -0
  367. package/dist/react/hooks/testing/fake-transport.d.ts +34 -0
  368. package/dist/react/hooks/testing/fake-transport.d.ts.map +1 -0
  369. package/dist/react/hooks/testing/fake-transport.js +46 -0
  370. package/dist/react/hooks/testing/fake-transport.js.map +1 -0
  371. package/dist/react/hooks/useArtifactStream.d.ts +18 -0
  372. package/dist/react/hooks/useArtifactStream.d.ts.map +1 -0
  373. package/dist/react/hooks/useArtifactStream.js +55 -0
  374. package/dist/react/hooks/useArtifactStream.js.map +1 -0
  375. package/dist/react/hooks/useChatFabDrag.d.ts +25 -0
  376. package/dist/react/hooks/useChatFabDrag.d.ts.map +1 -0
  377. package/dist/react/hooks/useChatFabDrag.js +88 -0
  378. package/dist/react/hooks/useChatFabDrag.js.map +1 -0
  379. package/dist/react/hooks/useComposer.d.ts +48 -0
  380. package/dist/react/hooks/useComposer.d.ts.map +1 -0
  381. package/dist/react/hooks/useComposer.js +121 -0
  382. package/dist/react/hooks/useComposer.js.map +1 -0
  383. package/dist/react/hooks/useConversation.d.ts +34 -0
  384. package/dist/react/hooks/useConversation.d.ts.map +1 -0
  385. package/dist/react/hooks/useConversation.js +163 -0
  386. package/dist/react/hooks/useConversation.js.map +1 -0
  387. package/dist/react/hooks/useCopyToClipboard.d.ts +14 -0
  388. package/dist/react/hooks/useCopyToClipboard.d.ts.map +1 -0
  389. package/dist/react/hooks/useCopyToClipboard.js +98 -0
  390. package/dist/react/hooks/useCopyToClipboard.js.map +1 -0
  391. package/dist/react/hooks/useExtEventGroups.d.ts +7 -0
  392. package/dist/react/hooks/useExtEventGroups.d.ts.map +1 -0
  393. package/dist/react/hooks/useExtEventGroups.js +32 -0
  394. package/dist/react/hooks/useExtEventGroups.js.map +1 -0
  395. package/dist/react/hooks/useLatestOperation.d.ts +31 -0
  396. package/dist/react/hooks/useLatestOperation.d.ts.map +1 -0
  397. package/dist/react/hooks/useLatestOperation.js +74 -0
  398. package/dist/react/hooks/useLatestOperation.js.map +1 -0
  399. package/dist/react/hooks/usePinnedTodos.d.ts +15 -0
  400. package/dist/react/hooks/usePinnedTodos.d.ts.map +1 -0
  401. package/dist/react/hooks/usePinnedTodos.js +43 -0
  402. package/dist/react/hooks/usePinnedTodos.js.map +1 -0
  403. package/dist/react/hooks/useQuestionForms.d.ts +28 -0
  404. package/dist/react/hooks/useQuestionForms.d.ts.map +1 -0
  405. package/dist/react/hooks/useQuestionForms.js +113 -0
  406. package/dist/react/hooks/useQuestionForms.js.map +1 -0
  407. package/dist/react/hooks/useRunStream.d.ts +27 -0
  408. package/dist/react/hooks/useRunStream.d.ts.map +1 -0
  409. package/dist/react/hooks/useRunStream.js +180 -0
  410. package/dist/react/hooks/useRunStream.js.map +1 -0
  411. package/dist/react/hooks/useToolTimeline.d.ts +33 -0
  412. package/dist/react/hooks/useToolTimeline.d.ts.map +1 -0
  413. package/dist/react/hooks/useToolTimeline.js +47 -0
  414. package/dist/react/hooks/useToolTimeline.js.map +1 -0
  415. package/dist/react/index.d.ts +158 -0
  416. package/dist/react/index.d.ts.map +1 -0
  417. package/dist/react/index.js +118 -0
  418. package/dist/react/index.js.map +1 -0
  419. package/dist/react/message-blocks.d.ts +86 -0
  420. package/dist/react/message-blocks.d.ts.map +1 -0
  421. package/dist/react/message-blocks.js +78 -0
  422. package/dist/react/message-blocks.js.map +1 -0
  423. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts +9 -0
  424. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts.map +1 -0
  425. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js +29 -0
  426. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js.map +1 -0
  427. package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts +30 -0
  428. package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts.map +1 -0
  429. package/dist/react/poc-mcp-ui-official/create-poc-resource.js +44 -0
  430. package/dist/react/poc-mcp-ui-official/create-poc-resource.js.map +1 -0
  431. package/dist/react/slots.d.ts +215 -0
  432. package/dist/react/slots.d.ts.map +1 -0
  433. package/dist/react/slots.js +2 -0
  434. package/dist/react/slots.js.map +1 -0
  435. package/dist/react/styles/reference.css +298 -0
  436. package/dist/react/tool-renderer-registry.d.ts +41 -0
  437. package/dist/react/tool-renderer-registry.d.ts.map +1 -0
  438. package/dist/react/tool-renderer-registry.js +22 -0
  439. package/dist/react/tool-renderer-registry.js.map +1 -0
  440. package/dist/react/util/defined-props.d.ts +31 -0
  441. package/dist/react/util/defined-props.d.ts.map +1 -0
  442. package/dist/react/util/defined-props.js +28 -0
  443. package/dist/react/util/defined-props.js.map +1 -0
  444. package/package.json +99 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC;;;;;;GAMG;AACH,cAAc,oBAAoB,CAAC;AACnC;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `@jini-ai/chat/core` — framework-free chat vocabulary + pure parsers.
3
+ *
4
+ * Zero React, zero DOM/browser globals, zero Node built-ins, zero imports
5
+ * from any product package's scope. See ADS-memory/reports/jini-port/extraction-plan.md
6
+ * §12 C2/C3 and ADS-memory/reports/jini-port/recon/r4b-webui-design.md §1 for the design
7
+ * this package targets, and source-map.md for exact provenance.
8
+ *
9
+ * Was `@jini-ai/chat-core` (its own top-level package, one entry point) through npm 0.1.2 —
10
+ * consolidated 2026-08-03 into `@jini-ai/chat`'s `./core` subpath alongside `./react` (formerly
11
+ * `@jini-ai/ui`'s `./chat` export), following `@jini-ai/admin`'s umbrella-with-subpaths precedent.
12
+ * `@jini-ai/chat-core` is retired, not deprecated-and-kept — its published npm versions
13
+ * (0.1.0–0.1.2) go end-of-life as-is; `@jini-ai/chat` supersedes it.
14
+ */
15
+ export * from './events.js';
16
+ export * from './messages.js';
17
+ export * from './partial-json.js';
18
+ export * from './tool-events.js';
19
+ export * from './transport.js';
20
+ export * from './tools.js';
21
+ export * from './todos.js';
22
+ export * from './question-form.js';
23
+ export * from './util/index.js';
24
+ export * from './transcript.js';
25
+ /**
26
+ * The chat pane's own capability manifest (`CHAT_CAPABILITIES`). The framework-free agent-control
27
+ * vocabulary this used to sit alongside — `CapabilityDef`, `PAGE_CAPABILITIES`, the
28
+ * `data-agent-*` convention, the policy gate, the protocol projections — moved to `@jini-ai/agentic`
29
+ * on 2026-07-26; import it directly rather than through this package. See
30
+ * `packages/agentic/source-map.md` and this package's own source-map.md for the extraction.
31
+ */
32
+ export * from './agentic/index.js';
33
+ /**
34
+ * Durable chat history — the storage-neutral `ChatHistoryStore` port and the local title
35
+ * heuristic. Types and pure functions only, so this package stays framework-free and
36
+ * `runtime: universal`; the SQLite implementation lives in `@jini-ai/sqlite`'s `chat-history`
37
+ * module, and a host binds it to its own authentication.
38
+ */
39
+ export * from './persistence/index.js';
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC;;;;;;GAMG;AACH,cAAc,oBAAoB,CAAC;AACnC;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { AgentEvent } from './events.js';
2
+ /** Who authored a `ChatMessage`. */
3
+ export type ChatRole = 'user' | 'assistant';
4
+ /**
5
+ * Terminal/non-terminal lifecycle of the run backing an assistant message.
6
+ *
7
+ * Named `ChatRunStatus`, not `RunStatus` (renamed 2026-07-29): `@jini-ai/protocol` owns
8
+ * `RunStatus` for a different shape at a different layer — a richer `{ id, state, ... }` record.
9
+ * This is the flat string union a chat message stamps on itself. While both were called
10
+ * `RunStatus`, every consumer importing both packages had to alias one on import, and nothing
11
+ * stopped the two from being confused at a glance. See source-map.md.
12
+ */
13
+ export declare const CHAT_RUN_STATUSES: readonly ["queued", "running", "succeeded", "failed", "canceled"];
14
+ export type ChatRunStatus = (typeof CHAT_RUN_STATUSES)[number];
15
+ /** `true` once a run has reached a terminal status (no further events will arrive). */
16
+ export declare function isTerminalRunStatus(status: ChatRunStatus | undefined): boolean;
17
+ /** A file or image a user turn carries alongside its text. */
18
+ export interface ChatAttachment {
19
+ path: string;
20
+ name: string;
21
+ kind: 'image' | 'file';
22
+ size?: number;
23
+ /** User-visible attachment order for this turn; older items may omit it. */
24
+ order?: number;
25
+ }
26
+ /**
27
+ * A single turn in a conversation. This is the generic subset of OD's
28
+ * `ChatMessage` (`packages/contracts/src/api/chat.ts`): product-shaped
29
+ * fields (`sessionMode`, `runContext`, `appliedPluginSnapshot`,
30
+ * `producedFiles`, `commentAttachments`, `feedback`, ...) are dropped — a
31
+ * host layers those on top via its own message extension, not this type.
32
+ */
33
+ export interface ChatMessage {
34
+ id: string;
35
+ role: ChatRole;
36
+ content: string;
37
+ agentId?: string;
38
+ agentName?: string;
39
+ events?: AgentEvent[];
40
+ createdAt?: number;
41
+ runId?: string;
42
+ runStatus?: ChatRunStatus;
43
+ /**
44
+ * True when this message's failed run can be recovered by resuming the
45
+ * agent's existing session rather than only restarting from scratch.
46
+ */
47
+ resumable?: boolean;
48
+ lastRunEventId?: string;
49
+ startedAt?: number;
50
+ endedAt?: number;
51
+ attachments?: ChatAttachment[];
52
+ }
53
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,oCAAoC;AACpC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5C;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,mEAAoE,CAAC;AACnG,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAI/D,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAE9E;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Terminal/non-terminal lifecycle of the run backing an assistant message.
3
+ *
4
+ * Named `ChatRunStatus`, not `RunStatus` (renamed 2026-07-29): `@jini-ai/protocol` owns
5
+ * `RunStatus` for a different shape at a different layer — a richer `{ id, state, ... }` record.
6
+ * This is the flat string union a chat message stamps on itself. While both were called
7
+ * `RunStatus`, every consumer importing both packages had to alias one on import, and nothing
8
+ * stopped the two from being confused at a glance. See source-map.md.
9
+ */
10
+ export const CHAT_RUN_STATUSES = ['queued', 'running', 'succeeded', 'failed', 'canceled'];
11
+ const TERMINAL_RUN_STATUSES = new Set(['succeeded', 'failed', 'canceled']);
12
+ /** `true` once a run has reached a terminal status (no further events will arrive). */
13
+ export function isTerminalRunStatus(status) {
14
+ return status !== undefined && TERMINAL_RUN_STATUSES.has(status);
15
+ }
16
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;AAGnG,MAAM,qBAAqB,GAA+B,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAEvG,uFAAuF;AACvF,MAAM,UAAU,mBAAmB,CAAC,MAAiC;IACnE,OAAO,MAAM,KAAK,SAAS,IAAI,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @module partial-json
3
+ *
4
+ * Truncation-tolerant JSON parsing for streamed LLM output. A streaming
5
+ * `<question-form>` (or any other structured artifact) needs to render a
6
+ * JSON *prefix* that grows one token at a time, so callers rely on this
7
+ * repair pass instead of waiting for the closing brace.
8
+ *
9
+ * Deliberately handles only the shapes a streaming model emits — balanced
10
+ * structure that simply hasn't finished — not arbitrary corruption. Callers
11
+ * should still keep their last good parsed result as a fallback.
12
+ */
13
+ /**
14
+ * Repair a truncated JSON prefix into the largest valid JSON text that can be
15
+ * parsed, by walking the buffer once to track string/escape state and the
16
+ * open-container stack, then closing whatever is still open.
17
+ *
18
+ * @param buf - A possibly-incomplete JSON text (a streamed prefix).
19
+ * @returns A best-effort syntactically-closed JSON text. Not guaranteed to
20
+ * parse (e.g. an empty buffer round-trips unchanged) — callers should still
21
+ * wrap consumption in `JSON.parse`/try-catch (see {@link parsePartialJson}).
22
+ * @complexity O(n) time / O(d) space in the input length `n` and max nesting
23
+ * depth `d` — one linear scan plus a bounded fixed-point cleanup loop over
24
+ * the (already shrinking) tail.
25
+ */
26
+ export declare function repairJsonPrefix(buf: string): string;
27
+ /**
28
+ * Best-effort parse of a (possibly truncated) JSON prefix.
29
+ *
30
+ * @param buf - A possibly-incomplete JSON text.
31
+ * @returns The parsed value, or `null` on empty input or an unrecoverable
32
+ * parse failure — callers should fall back to their last good value.
33
+ * @complexity O(n) — dominated by {@link repairJsonPrefix}.
34
+ */
35
+ export declare function parsePartialJson(buf: string): unknown;
36
+ //# sourceMappingURL=partial-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partial-json.d.ts","sourceRoot":"","sources":["../../src/core/partial-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiEpD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQrD"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @module partial-json
3
+ *
4
+ * Truncation-tolerant JSON parsing for streamed LLM output. A streaming
5
+ * `<question-form>` (or any other structured artifact) needs to render a
6
+ * JSON *prefix* that grows one token at a time, so callers rely on this
7
+ * repair pass instead of waiting for the closing brace.
8
+ *
9
+ * Deliberately handles only the shapes a streaming model emits — balanced
10
+ * structure that simply hasn't finished — not arbitrary corruption. Callers
11
+ * should still keep their last good parsed result as a fallback.
12
+ */
13
+ /**
14
+ * Repair a truncated JSON prefix into the largest valid JSON text that can be
15
+ * parsed, by walking the buffer once to track string/escape state and the
16
+ * open-container stack, then closing whatever is still open.
17
+ *
18
+ * @param buf - A possibly-incomplete JSON text (a streamed prefix).
19
+ * @returns A best-effort syntactically-closed JSON text. Not guaranteed to
20
+ * parse (e.g. an empty buffer round-trips unchanged) — callers should still
21
+ * wrap consumption in `JSON.parse`/try-catch (see {@link parsePartialJson}).
22
+ * @complexity O(n) time / O(d) space in the input length `n` and max nesting
23
+ * depth `d` — one linear scan plus a bounded fixed-point cleanup loop over
24
+ * the (already shrinking) tail.
25
+ */
26
+ export function repairJsonPrefix(buf) {
27
+ const stack = []; // closers owed, e.g. ['}', ']']
28
+ let inStr = false;
29
+ let esc = false;
30
+ for (let i = 0; i < buf.length; i++) {
31
+ const c = buf[i];
32
+ if (inStr) {
33
+ if (esc)
34
+ esc = false;
35
+ else if (c === '\\')
36
+ esc = true;
37
+ else if (c === '"')
38
+ inStr = false;
39
+ continue;
40
+ }
41
+ if (c === '"')
42
+ inStr = true;
43
+ else if (c === '{')
44
+ stack.push('}');
45
+ else if (c === '[')
46
+ stack.push(']');
47
+ else if (c === '}' || c === ']')
48
+ stack.pop();
49
+ }
50
+ let out = buf;
51
+ // 1. Close a string cut off mid-value (or mid-key). First neutralize a
52
+ // dangling escape at the cut point, otherwise the closing quote would be
53
+ // swallowed (`...x\` + `"` → escaped quote) or a partial `\uXXXX` would
54
+ // be an invalid escape — either makes JSON.parse fail and collapses the
55
+ // live preview. Common in prompts that mention Windows paths, regexes,
56
+ // or escaped quotes.
57
+ if (inStr) {
58
+ out = out.replace(/\\u[0-9a-fA-F]{0,3}$/, ''); // incomplete \uXXXX
59
+ if (/(?:^|[^\\])(?:\\\\)*\\$/.test(out))
60
+ out = out.slice(0, -1); // lone trailing backslash
61
+ out += '"';
62
+ }
63
+ // 2. Trim trailing structural noise that can't be completed into a value:
64
+ // a dangling comma, a `"key":` with no value yet, and an unfinished
65
+ // *scalar* value cut mid-token (a partial `true`/`false`/`null`, or a
66
+ // number ending on `.`/`e`/sign). Leaving those makes `{… :f}` etc.
67
+ // unparseable, collapsing the live preview whenever a literal splits
68
+ // across deltas. Each trim leaves a `"key":` / `,` / `[` boundary that
69
+ // the next loop iteration cleans up. Complete literals (`true`, `12`,
70
+ // `1.5`, `1e3`) are not prefixes of these patterns, so they survive.
71
+ const valueStart = '([:[,]\\s*)';
72
+ let prev;
73
+ do {
74
+ prev = out;
75
+ out = out.replace(/[,\s]+$/, '');
76
+ out = out.replace(/"(?:[^"\\]|\\.)*"\s*:\s*$/, ''); // key + colon, no value
77
+ out = out.replace(new RegExp(`${valueStart}(?:tru|tr|t|fals|fal|fa|f|nul|nu|n)$`), '$1'); // partial bool/null
78
+ out = out.replace(new RegExp(`${valueStart}-?(?:\\d+\\.?\\d*|\\d*\\.\\d+)?[eE][+-]?$`), '$1'); // dangling exponent
79
+ out = out.replace(new RegExp(`${valueStart}-?\\d*\\.$`), '$1'); // number ending in '.'
80
+ out = out.replace(new RegExp(`${valueStart}-$`), '$1'); // lone minus
81
+ out = out.replace(/"(?:[^"\\]|\\.)*"\s*:\s*$/, ''); // key + colon exposed by the trims above
82
+ out = out.replace(/[,\s]+$/, '');
83
+ } while (out !== prev);
84
+ // A bare trailing key (string with no following colon) only happens when
85
+ // the *innermost* open container is an object. Drop it so we don't emit
86
+ // `{"hea"}` which is invalid (key without value).
87
+ if (stack[stack.length - 1] === '}' && /"(?:[^"\\]|\\.)*"\s*$/.test(out)) {
88
+ const trimmed = out.replace(/"(?:[^"\\]|\\.)*"\s*$/, '');
89
+ // Only drop it if what precedes is a container/comma boundary (i.e. the
90
+ // string really is a pending key, not a completed value like `:"x"`).
91
+ if (/[{,]\s*$/.test(trimmed)) {
92
+ out = trimmed.replace(/[,\s]+$/, '');
93
+ }
94
+ }
95
+ // 3. Close every still-open container, innermost first.
96
+ for (let i = stack.length - 1; i >= 0; i--)
97
+ out += stack[i];
98
+ return out;
99
+ }
100
+ /**
101
+ * Best-effort parse of a (possibly truncated) JSON prefix.
102
+ *
103
+ * @param buf - A possibly-incomplete JSON text.
104
+ * @returns The parsed value, or `null` on empty input or an unrecoverable
105
+ * parse failure — callers should fall back to their last good value.
106
+ * @complexity O(n) — dominated by {@link repairJsonPrefix}.
107
+ */
108
+ export function parsePartialJson(buf) {
109
+ const trimmed = buf.trim();
110
+ if (!trimmed)
111
+ return null;
112
+ try {
113
+ return JSON.parse(repairJsonPrefix(trimmed));
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ //# sourceMappingURL=partial-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partial-json.js","sourceRoot":"","sources":["../../src/core/partial-json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @module persistence
3
+ *
4
+ * Durable chat history: the storage-neutral port plus the local title heuristic. No driver, no
5
+ * DDL, no I/O — a SQLite implementation lives in `@jini-ai/sqlite`'s `chat-history` module, and
6
+ * a host binds it to its own auth. See `./ports.ts` for why the owner scope is bound into the
7
+ * store rather than passed per call.
8
+ */
9
+ export * from './ports.js';
10
+ export * from './title.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/persistence/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @module persistence
3
+ *
4
+ * Durable chat history: the storage-neutral port plus the local title heuristic. No driver, no
5
+ * DDL, no I/O — a SQLite implementation lives in `@jini-ai/sqlite`'s `chat-history` module, and
6
+ * a host binds it to its own auth. See `./ports.ts` for why the owner scope is bound into the
7
+ * store rather than passed per call.
8
+ */
9
+ export * from './ports.js';
10
+ export * from './title.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/persistence/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @module persistence/ports
3
+ *
4
+ * The storage-neutral contract for durable chat history: conversations and their messages,
5
+ * scoped to an owner. Types and signatures only — this module imports no driver, opens no
6
+ * file, and issues no DDL, so it stays inside `chat-core`'s `runtime: universal` promise.
7
+ *
8
+ * Why here and not in `@jini-ai/agentic`: `chat-core` already depends on `agentic`, so a port
9
+ * living in `agentic` could not import {@link ChatMessage} — the type it exists to persist —
10
+ * without inverting that edge. It would have to redefine the message shape (two sources of
11
+ * truth) or be generic over an opaque type (a persistence abstraction naming nothing).
12
+ *
13
+ * Why the owner scope is baked into the port rather than passed per call: every read must be
14
+ * `WHERE scope = ? AND owner = ? AND id = ?`, never `WHERE id = ?`. A port whose methods take
15
+ * a bare id invites exactly one bug — a handler that forgets the predicate — and that bug is
16
+ * an omission, so review does not reliably catch it. {@link ChatHistoryStore} is obtained
17
+ * already-bound to a {@link ChatOwnerScope}; there is no method on it that can read across
18
+ * owners. Hosts bind the scope from their own auth, which is the one part of this that cannot
19
+ * be reused.
20
+ */
21
+ import type { ChatMessage } from '../messages.js';
22
+ /**
23
+ * Which kind of principal owns a conversation.
24
+ *
25
+ * `user` is an authenticated account; `guest` is an anonymous visitor identified only by an
26
+ * opaque bearer token. They are separated rather than collapsed into one `ownerId` because the
27
+ * retention and disclosure rules differ: guest history expires, user history does not, and a
28
+ * guest's identifier is a credential that must be stored hashed.
29
+ */
30
+ export type ChatOwnerKind = 'user' | 'guest';
31
+ /**
32
+ * The isolation predicate, resolved by the host from its own authentication, and bound into a
33
+ * store before any query runs.
34
+ *
35
+ * `scopeId` is the host's partition key — a workspace, a tenant, a project, whatever that host
36
+ * partitions by. This package does not interpret it; it only guarantees every statement filters
37
+ * on it.
38
+ *
39
+ * `ownerId` for a `guest` MUST already be hashed by the host. This package never sees, stores,
40
+ * or logs a raw bearer token, and cannot verify that a caller honored this — it is stated here
41
+ * because the constraint is real and the type system cannot express it.
42
+ */
43
+ export interface ChatOwnerScope {
44
+ readonly scopeId: string;
45
+ readonly ownerKind: ChatOwnerKind;
46
+ readonly ownerId: string;
47
+ }
48
+ /** Where a conversation's current title came from — see {@link ChatHistoryStore.rename}. */
49
+ export type ChatTitleSource = 'fallback' | 'generated' | 'manual';
50
+ /**
51
+ * A conversation as the list UI needs it: enough to render a row without loading any messages.
52
+ *
53
+ * `messageCount` is computed by the adapter in the same round-trip as the list itself, so a
54
+ * list of N conversations costs one query rather than N+1.
55
+ */
56
+ export interface ChatConversation {
57
+ readonly id: string;
58
+ readonly title: string | null;
59
+ readonly titleSource: ChatTitleSource;
60
+ readonly messageCount: number;
61
+ readonly createdAt: number;
62
+ readonly updatedAt: number;
63
+ /** Absent means no expiry — the row is retained until explicitly deleted. */
64
+ readonly expiresAt?: number;
65
+ }
66
+ /** Everything a host may specify when starting a conversation. */
67
+ export interface CreateChatConversationInput {
68
+ readonly id: string;
69
+ readonly title?: string | null;
70
+ readonly titleSource?: ChatTitleSource;
71
+ /** Epoch ms. Omit for history that never expires. */
72
+ readonly expiresAt?: number;
73
+ }
74
+ /**
75
+ * Durable chat history for exactly one {@link ChatOwnerScope}.
76
+ *
77
+ * Every method is already scoped. `get(id)` for an id belonging to another owner resolves to
78
+ * `null` rather than throwing — a caller must not be able to distinguish "does not exist" from
79
+ * "exists but is not yours", since that distinction is itself an enumeration oracle.
80
+ */
81
+ export interface ChatHistoryStore {
82
+ /** Most-recently-updated first. */
83
+ list(): Promise<ChatConversation[]>;
84
+ /** `null` when the id does not exist *or* is not owned by this scope. */
85
+ get(id: string): Promise<ChatConversation | null>;
86
+ create(input: CreateChatConversationInput): Promise<ChatConversation>;
87
+ /**
88
+ * Sets the title and stamps `titleSource`. A `manual` title is never overwritten by a
89
+ * `generated` one — that rule lives in the adapter so no host can forget it, and it is the
90
+ * reason `titleSource` is a column rather than a UI concern.
91
+ */
92
+ rename(id: string, title: string, source?: ChatTitleSource): Promise<ChatConversation | null>;
93
+ /** Bumps `updatedAt`, optionally extending expiry for a still-active guest session. */
94
+ touch(id: string, options?: {
95
+ readonly expiresAt?: number;
96
+ }): Promise<void>;
97
+ /** Cascades to the conversation's messages. No-op when the id is not owned by this scope. */
98
+ delete(id: string): Promise<void>;
99
+ /** Ordered by position. Empty when the id is not owned by this scope. */
100
+ messages(conversationId: string): Promise<ChatMessage[]>;
101
+ /**
102
+ * Inserts or updates one message, assigning the next position on insert.
103
+ *
104
+ * `null` when the conversation is not owned by this scope — so a mis-scoped write is a
105
+ * no-op rather than a cross-owner insert.
106
+ */
107
+ appendMessage(conversationId: string, message: ChatMessage): Promise<ChatMessage | null>;
108
+ }
109
+ /**
110
+ * Retention. Deliberately NOT on {@link ChatHistoryStore}: a sweep runs across every owner, so
111
+ * putting it on a per-owner store would require an unscoped store to exist, which is the exact
112
+ * escape hatch this design removes.
113
+ */
114
+ export interface ChatHistoryMaintenance {
115
+ /**
116
+ * Hard-deletes conversations whose `expiresAt` is at or before `now`, cascading to messages.
117
+ *
118
+ * `limit` bounds one call so a large backlog is drained in chunks rather than held in a
119
+ * single long write transaction — an unbounded `DELETE` is what starves concurrent inserts.
120
+ * Returns the number of conversations deleted, so a caller can loop until it reports 0.
121
+ */
122
+ sweepExpired(now: number, limit?: number): Promise<number>;
123
+ }
124
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../../src/core/persistence/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,4FAA4F;AAC5F,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,kEAAkE;AAClE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;IACvC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACpC,yEAAyE;IACzE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC9F,uFAAuF;IACvF,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,6FAA6F;IAC7F,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD;;;;;OAKG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC1F;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../../src/core/persistence/ports.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @module persistence/title
3
+ *
4
+ * Derives a conversation's working title from its first user message, synchronously and with no
5
+ * model call.
6
+ *
7
+ * The point of doing this locally is latency and cost: a conversation needs a name the instant
8
+ * it appears in a list, and for an anonymous-visitor surface a per-conversation LLM call to name
9
+ * a chat is a real cost against a session that may be one message long. A host that wants a
10
+ * better title asks its agent for one later and calls `rename(id, title, 'generated')`; the
11
+ * store refuses to overwrite a `manual` title, so a user's own rename always wins.
12
+ *
13
+ * Ported from Open Design's `summarizeProjectNameFromPrompt` (`apps/web/src/utils/projectName.ts`),
14
+ * which this generalizes from project names to conversation titles. Its behaviour is preserved
15
+ * deliberately — including the CJK path, which is not decoration: the filler and punctuation
16
+ * rules for Chinese prompts differ enough from the Latin ones that a shared code path produced
17
+ * visibly worse titles in both.
18
+ *
19
+ * Two intentional divergences from the original, both fixing output the original gets wrong; each
20
+ * is documented at its own declaration below:
21
+ * 1. `LEADING_LATIN_FILLER` requires the separator inside the article group. The original's form
22
+ * let a bare `a` eat the first letter of the next word ("update app.tsx" → "Pp Tsx").
23
+ * 2. `LATIN_NEVER_TRAILING` trims function words off the end. The original's word cap lands
24
+ * mid-clause on question-shaped prompts and strands them ("...Posts Do I").
25
+ */
26
+ /**
27
+ * Returns a short display title for a conversation, or `''` when the prompt yields nothing
28
+ * usable (a bare URL, a lone code fence, pure punctuation). Callers should treat `''` as "leave
29
+ * the conversation untitled" rather than substituting the raw prompt — a list row showing 400
30
+ * characters of pasted code is worse than one showing "Untitled".
31
+ *
32
+ * @complexity O(n) in prompt length; no allocation beyond the intermediate strings.
33
+ */
34
+ export declare function deriveConversationTitle(prompt: string): string;
35
+ //# sourceMappingURL=title.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"title.d.ts","sourceRoot":"","sources":["../../../src/core/persistence/title.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAuGH;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAS9D"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * @module persistence/title
3
+ *
4
+ * Derives a conversation's working title from its first user message, synchronously and with no
5
+ * model call.
6
+ *
7
+ * The point of doing this locally is latency and cost: a conversation needs a name the instant
8
+ * it appears in a list, and for an anonymous-visitor surface a per-conversation LLM call to name
9
+ * a chat is a real cost against a session that may be one message long. A host that wants a
10
+ * better title asks its agent for one later and calls `rename(id, title, 'generated')`; the
11
+ * store refuses to overwrite a `manual` title, so a user's own rename always wins.
12
+ *
13
+ * Ported from Open Design's `summarizeProjectNameFromPrompt` (`apps/web/src/utils/projectName.ts`),
14
+ * which this generalizes from project names to conversation titles. Its behaviour is preserved
15
+ * deliberately — including the CJK path, which is not decoration: the filler and punctuation
16
+ * rules for Chinese prompts differ enough from the Latin ones that a shared code path produced
17
+ * visibly worse titles in both.
18
+ *
19
+ * Two intentional divergences from the original, both fixing output the original gets wrong; each
20
+ * is documented at its own declaration below:
21
+ * 1. `LEADING_LATIN_FILLER` requires the separator inside the article group. The original's form
22
+ * let a bare `a` eat the first letter of the next word ("update app.tsx" → "Pp Tsx").
23
+ * 2. `LATIN_NEVER_TRAILING` trims function words off the end. The original's word cap lands
24
+ * mid-clause on question-shaped prompts and strands them ("...Posts Do I").
25
+ */
26
+ const MAX_LATIN_WORDS = 6;
27
+ const MAX_CJK_LENGTH = 18;
28
+ /**
29
+ * Hard character ceiling, because a word cap is not a length cap.
30
+ *
31
+ * Six "words" says nothing about their size: a pasted base64 blob or minified bundle is a single
32
+ * enormous token, so it survived the word cap intact and became the title verbatim. That title is
33
+ * then stored, listed, and re-rendered on every conversation-list read — megabytes of it. Applied to
34
+ * the finished title so both the Latin and CJK paths are covered.
35
+ */
36
+ const MAX_TITLE_CHARS = 80;
37
+ const CJK_PATTERN = /[㐀-鿿]/;
38
+ /**
39
+ * Leading politeness/imperative filler — "can you build a dashboard" is a dashboard.
40
+ *
41
+ * The trailing article group requires `\s+` *inside* it rather than the original's
42
+ * `(an|a|the|…)?\s*`. That form is subtly wrong: with the whitespace outside the optional group,
43
+ * the bare `a` alternative happily matches the first letter of the following word, so
44
+ * "update app.tsx" became "Pp Tsx" and "build analytics" became "Nalytics". Any word starting
45
+ * with `a` after a verb silently lost its first character. Requiring the separator as part of the
46
+ * article makes an article an article rather than a prefix.
47
+ */
48
+ const LEADING_LATIN_FILLER = /^(please\s+)?(can\s+you\s+|could\s+you\s+|help\s+me\s+|i\s+want\s+to\s+|i\s+need\s+to\s+)?(create|build|make|design|implement|add|fix|update|improve|optimize|generate|write|search|find|show|list|turn)\s+((this|that)\s+into\s+)?((an|a|the|this|that|my|me)\s+)?/i;
49
+ const LEADING_CJK_FILLER = [
50
+ /^先?(帮我|帮忙|麻烦|请|可以|能不能|能否|给我|我想要|我要)/,
51
+ /^(先)?(实现|做|做一下|创建|生成|设计|开发|新增|添加|优化|修复|改|更改|调整)(一下|一个|一版|下)?/,
52
+ /^(一个|一份|这个|那个)/,
53
+ ];
54
+ const LATIN_STOP_WORDS = new Set([
55
+ 'a', 'an', 'and', 'for', 'in', 'of', 'on', 'please', 'the', 'to', 'with', 'my',
56
+ ]);
57
+ /**
58
+ * Function words that are fine *inside* a title but never acceptable as its last word.
59
+ *
60
+ * These cannot go in `LATIN_STOP_WORDS`, because removing them everywhere mangles real titles —
61
+ * "how many posts do I have" would lose the "how many" that makes it a question, and a prompt like
62
+ * "make it work" would reduce to "Work". The problem is specifically the word-cap boundary: a
63
+ * question-shaped prompt reliably spends its six words before reaching the noun, so the title got
64
+ * cut mid-clause. Observed live: "how many published posts do I have?" produced
65
+ * "How Many Published Posts Do I" — a dangling auxiliary plus a stranded pronoun, which in a narrow
66
+ * dock also wrapped to leave a lone "I" on its own line.
67
+ *
68
+ * Trimming only the tail is what makes this safe: it can never shorten a title that already ended
69
+ * on a content word, so no existing good title changes.
70
+ */
71
+ const LATIN_NEVER_TRAILING = new Set([
72
+ 'do', 'does', 'did', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
73
+ 'have', 'has', 'had', 'can', 'could', 'should', 'would', 'will', 'shall', 'may', 'might', 'must',
74
+ 'i', 'me', 'you', 'we', 'us', 'it', 'they', 'them', 'he', 'she',
75
+ 'that', 'this', 'these', 'those', 'but', 'or', 'if', 'then', 'than', 'as', 'at', 'by',
76
+ 'from', 'into', 'about', 'so', 'just', 'also', 'too', 'up', 'out',
77
+ ]);
78
+ /**
79
+ * Strips the parts of a prompt that are never a good title: fenced and inline code, URLs, and
80
+ * `@handle`/`#tag` tokens. Each of these is high-entropy and low-meaning in a six-word summary.
81
+ */
82
+ function cleanPrompt(prompt) {
83
+ return prompt
84
+ .replace(/```[\s\S]*?```/g, ' ')
85
+ .replace(/`[^`]*`/g, ' ')
86
+ .replace(/https?:\/\/\S+/g, ' ')
87
+ .replace(/[@#][\w.-]+/g, ' ')
88
+ .replace(/[“”"']/g, '')
89
+ .replace(/\s+/g, ' ')
90
+ .trim();
91
+ }
92
+ function toTitleCase(word) {
93
+ return word ? word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() : word;
94
+ }
95
+ function trimLatinTitle(input) {
96
+ const words = input
97
+ .replace(LEADING_LATIN_FILLER, '')
98
+ .replace(/[^\p{L}\p{N}\s-]/gu, ' ')
99
+ .split(/\s+/)
100
+ .filter(Boolean)
101
+ .filter((word) => !LATIN_STOP_WORDS.has(word.toLowerCase()))
102
+ .slice(0, MAX_LATIN_WORDS);
103
+ // Applied after the cap, because the cap is what strands these words in the first place.
104
+ while (words.length > 0 && LATIN_NEVER_TRAILING.has(words[words.length - 1].toLowerCase())) {
105
+ words.pop();
106
+ }
107
+ return words.map(toTitleCase).join(' ');
108
+ }
109
+ function trimCjkTitle(input) {
110
+ let title = input.trim();
111
+ for (const pattern of LEADING_CJK_FILLER)
112
+ title = title.replace(pattern, '').trim();
113
+ // Cut at the first sentence-ending punctuation, then drop spacing — CJK titles do not use it.
114
+ title = title.replace(/[,。!?;:,.!?;:].*$/, '').replace(/\s+/g, '');
115
+ return title.slice(0, MAX_CJK_LENGTH);
116
+ }
117
+ /**
118
+ * Returns a short display title for a conversation, or `''` when the prompt yields nothing
119
+ * usable (a bare URL, a lone code fence, pure punctuation). Callers should treat `''` as "leave
120
+ * the conversation untitled" rather than substituting the raw prompt — a list row showing 400
121
+ * characters of pasted code is worse than one showing "Untitled".
122
+ *
123
+ * @complexity O(n) in prompt length; no allocation beyond the intermediate strings.
124
+ */
125
+ export function deriveConversationTitle(prompt) {
126
+ const cleaned = cleanPrompt(prompt);
127
+ if (!cleaned)
128
+ return '';
129
+ const firstClause = cleaned.split(/[\n\r。!?!?]/)[0]?.trim() ?? cleaned;
130
+ if (!firstClause)
131
+ return '';
132
+ const title = CJK_PATTERN.test(firstClause) ? trimCjkTitle(firstClause) : trimLatinTitle(firstClause);
133
+ // Truncated without an ellipsis: this is a working title, not prose, and a `…` would end up stored
134
+ // and shown as if the author wrote it.
135
+ return title.length > MAX_TITLE_CHARS ? title.slice(0, MAX_TITLE_CHARS).trimEnd() : title;
136
+ }
137
+ //# sourceMappingURL=title.js.map