@jini-ai/chat 0.3.11 → 0.5.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 (205) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +152 -6
  3. package/dist/core/ag-ui/entry.d.ts +53 -0
  4. package/dist/core/ag-ui/entry.js +135 -0
  5. package/dist/core/agentic/chat-capabilities.d.ts +1 -1
  6. package/dist/core/agentic/index.d.ts +1 -1
  7. package/dist/core/agentic/index.js +1 -1
  8. package/dist/core/assistant-content.d.ts +6 -2
  9. package/dist/core/assistant-content.js +2 -2
  10. package/dist/core/compact-events.d.ts +3 -1
  11. package/dist/core/compact-events.js +1 -1
  12. package/dist/core/events.d.ts +1 -1
  13. package/dist/core/events.js +1 -1
  14. package/dist/core/index.d.ts +3 -3
  15. package/dist/core/index.js +3 -3
  16. package/dist/core/messages.d.ts +4 -2
  17. package/dist/core/messages.js +2 -2
  18. package/dist/core/partial-json.d.ts +6 -2
  19. package/dist/core/partial-json.js +3 -3
  20. package/dist/core/persistence/index.d.ts +1 -1
  21. package/dist/core/persistence/index.js +1 -1
  22. package/dist/core/persistence/ports.d.ts +2 -123
  23. package/dist/core/persistence/title.d.ts +3 -1
  24. package/dist/core/persistence/title.js +1 -1
  25. package/dist/core/question-form/format.d.ts +16 -7
  26. package/dist/core/question-form/format.js +3 -3
  27. package/dist/core/question-form/normalize.d.ts +7 -2
  28. package/dist/core/question-form/normalize.js +5 -5
  29. package/dist/core/question-form/scan.d.ts +18 -6
  30. package/dist/core/question-form/scan.js +14 -14
  31. package/dist/core/run-activity.d.ts +16 -4
  32. package/dist/core/run-activity.js +11 -11
  33. package/dist/core/run-events/entry.d.ts +121 -0
  34. package/dist/core/run-events/entry.js +290 -0
  35. package/dist/core/todos.d.ts +20 -8
  36. package/dist/core/todos.js +11 -11
  37. package/dist/core/tool-events.d.ts +3 -1
  38. package/dist/core/tool-events.js +1 -1
  39. package/dist/core/tool-output.d.ts +3 -1
  40. package/dist/core/tool-output.js +1 -1
  41. package/dist/core/tools.d.ts +14 -3
  42. package/dist/core/tools.js +3 -3
  43. package/dist/core/transcript.d.ts +13 -5
  44. package/dist/core/transcript.js +5 -5
  45. package/dist/core/util/manifest.d.ts +9 -3
  46. package/dist/core/util/manifest.js +3 -3
  47. package/dist/core/util/markdown-context.d.ts +11 -3
  48. package/dist/core/util/markdown-context.js +3 -3
  49. package/dist/core/util/markup-attributes.d.ts +3 -1
  50. package/dist/core/util/markup-attributes.js +1 -1
  51. package/dist/core/util/parser.d.ts +9 -5
  52. package/dist/core/util/parser.js +13 -13
  53. package/dist/core/util/recover.d.ts +6 -2
  54. package/dist/core/util/recover.js +6 -6
  55. package/dist/core/util/strip.d.ts +19 -5
  56. package/dist/core/util/strip.js +17 -17
  57. package/dist/core/util/validate.d.ts +3 -1
  58. package/dist/core/util/validate.js +1 -1
  59. package/dist/embed-widget/browser/page-actions.d.ts +121 -0
  60. package/dist/embed-widget/browser/page-actions.js +113 -0
  61. package/dist/embed-widget/browser/session-store.d.ts +44 -0
  62. package/dist/embed-widget/browser/session-store.js +103 -0
  63. package/dist/embed-widget/react/embed.d.ts +45 -0
  64. package/dist/embed-widget/react/embed.js +87 -0
  65. package/dist/embed-widget/react/header.d.ts +21 -0
  66. package/dist/embed-widget/react/header.js +18 -0
  67. package/dist/embed-widget/transports/fetch-sse.d.ts +75 -0
  68. package/dist/embed-widget/transports/fetch-sse.js +175 -0
  69. package/dist/react/agent-bridge/frontend-session-bridge.d.ts +15 -3
  70. package/dist/react/agent-bridge/frontend-session-bridge.js +13 -6
  71. package/dist/react/artifact-types.d.ts +3 -3
  72. package/dist/react/artifact-types.js +3 -3
  73. package/dist/react/components/A2uiSurfaceCard.js +34 -13
  74. package/dist/react/components/AttachmentPreviewModal.hooks.d.ts +7 -2
  75. package/dist/react/components/AttachmentPreviewModal.hooks.js +5 -5
  76. package/dist/react/components/AttachmentPreviewModal.js +2 -2
  77. package/dist/react/components/AttachmentTray.d.ts +3 -1
  78. package/dist/react/components/AttachmentTray.js +2 -2
  79. package/dist/react/components/ChatFab.js +1 -1
  80. package/dist/react/components/Composer.js +9 -9
  81. package/dist/react/components/ConversationList.js +1 -1
  82. package/dist/react/components/McpUiSurfaceCard.d.ts +4 -2
  83. package/dist/react/components/McpUiSurfaceCard.js +5 -5
  84. package/dist/react/components/MessageList.js +1 -1
  85. package/dist/react/components/MessageRow.js +9 -9
  86. package/dist/react/components/QuestionForm.js +5 -5
  87. package/dist/react/components/ToolCard.js +9 -9
  88. package/dist/react/components/composer-discovery.d.ts +29 -8
  89. package/dist/react/components/composer-discovery.js +10 -10
  90. package/dist/react/ext-event-renderer-registry.d.ts +15 -5
  91. package/dist/react/ext-event-renderer-registry.js +4 -4
  92. package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts +3 -1
  93. package/dist/react/features/chat-pane/components/AgentRuntimePicker.js +3 -3
  94. package/dist/react/features/chat-pane/components/ChatPane.js +43 -43
  95. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts +4 -1
  96. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js +5 -35
  97. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts +5 -2
  98. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js +1 -1
  99. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts +38 -10
  100. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js +15 -15
  101. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +31 -31
  102. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts +3 -1
  103. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js +3 -3
  104. package/dist/react/features/chat-pane/hooks/useChatPaneComposerPlaceholder.hooks.d.ts +4 -1
  105. package/dist/react/features/chat-pane/hooks/useChatPaneComposerPlaceholder.hooks.js +1 -1
  106. package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js +30 -30
  107. package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js +57 -57
  108. package/dist/react/features/chat-pane/rules.d.ts +13 -4
  109. package/dist/react/features/chat-pane/rules.js +5 -5
  110. package/dist/react/features/chat-pane/types.d.ts +1 -1
  111. package/dist/react/hooks/attachment-preview-cache.d.ts +7 -2
  112. package/dist/react/hooks/attachment-preview-cache.js +2 -2
  113. package/dist/react/hooks/composer-draft-cache.d.ts +17 -5
  114. package/dist/react/hooks/composer-draft-cache.js +6 -6
  115. package/dist/react/hooks/useArtifactStream.d.ts +5 -1
  116. package/dist/react/hooks/useArtifactStream.js +3 -3
  117. package/dist/react/hooks/useChatFabDrag.d.ts +9 -4
  118. package/dist/react/hooks/useChatFabDrag.js +4 -4
  119. package/dist/react/hooks/useComposer.js +8 -8
  120. package/dist/react/hooks/useConversation.js +56 -4
  121. package/dist/react/hooks/useExtEventGroups.d.ts +5 -1
  122. package/dist/react/hooks/useExtEventGroups.js +1 -1
  123. package/dist/react/hooks/useLatestOperation.d.ts +8 -3
  124. package/dist/react/hooks/useLatestOperation.js +4 -4
  125. package/dist/react/hooks/usePinnedTodos.d.ts +3 -1
  126. package/dist/react/hooks/usePinnedTodos.js +3 -3
  127. package/dist/react/hooks/useQuestionForms.d.ts +7 -2
  128. package/dist/react/hooks/useQuestionForms.js +7 -7
  129. package/dist/react/hooks/useRunActivity.d.ts +6 -1
  130. package/dist/react/hooks/useRunActivity.js +3 -3
  131. package/dist/react/hooks/useRunStream.d.ts +3 -1
  132. package/dist/react/hooks/useRunStream.js +1 -1
  133. package/dist/react/hooks/useToolTimeline.d.ts +3 -1
  134. package/dist/react/hooks/useToolTimeline.js +3 -3
  135. package/dist/react/index.d.ts +4 -4
  136. package/dist/react/index.js +6 -6
  137. package/dist/react/message-blocks.d.ts +10 -4
  138. package/dist/react/message-blocks.js +2 -2
  139. package/dist/react/styles/reference.css +3 -3
  140. package/dist/react/tool-renderer-registry.d.ts +8 -3
  141. package/dist/react/tool-renderer-registry.js +3 -3
  142. package/dist/react/util/defined-props.d.ts +3 -1
  143. package/dist/react/util/defined-props.js +1 -1
  144. package/dist/server/run-finalizer/entry.d.ts +47 -0
  145. package/dist/server/run-finalizer/entry.js +156 -0
  146. package/dist/server/run-finalizer/ports.d.ts +52 -0
  147. package/dist/store/contracts/index.d.ts +5 -0
  148. package/dist/store/contracts/index.js +5 -0
  149. package/dist/store/errors.d.ts +12 -0
  150. package/dist/store/errors.js +18 -0
  151. package/dist/store/index.d.ts +4 -0
  152. package/dist/store/index.js +2 -0
  153. package/dist/store/legacy/index.d.ts +3 -0
  154. package/dist/store/legacy/index.js +2 -0
  155. package/dist/store/legacy/sqlite/conversations.d.ts +129 -0
  156. package/dist/store/legacy/sqlite/conversations.js +274 -0
  157. package/dist/store/legacy/sqlite/index.d.ts +6 -0
  158. package/dist/store/legacy/sqlite/index.js +5 -0
  159. package/dist/store/legacy/sqlite/messages.d.ts +156 -0
  160. package/dist/store/legacy/sqlite/messages.js +246 -0
  161. package/dist/store/legacy/sqlite/schema.d.ts +3 -0
  162. package/dist/store/legacy/sqlite/schema.js +40 -0
  163. package/dist/store/pglite/index.d.ts +21 -0
  164. package/dist/store/pglite/index.js +17 -0
  165. package/dist/store/ports.d.ts +121 -0
  166. package/dist/store/ports.js +2 -0
  167. package/dist/store/postgres/index.d.ts +21 -0
  168. package/dist/store/postgres/index.js +17 -0
  169. package/dist/store/sql/boundary.d.ts +28 -0
  170. package/dist/store/sql/boundary.js +32 -0
  171. package/dist/store/sql/cursor.d.ts +24 -0
  172. package/dist/store/sql/cursor.js +49 -0
  173. package/dist/store/sql/maintenance.d.ts +9 -0
  174. package/dist/store/sql/maintenance.js +16 -0
  175. package/dist/store/sql/store.d.ts +22 -0
  176. package/dist/store/sql/store.js +340 -0
  177. package/dist/store/sql/tables.d.ts +34 -0
  178. package/dist/store/sql/tables.js +2 -0
  179. package/dist/store/sqlite/index.d.ts +36 -0
  180. package/dist/store/sqlite/index.js +29 -0
  181. package/dist/store/sqlite/schema.d.ts +49 -0
  182. package/dist/store/sqlite/schema.js +80 -0
  183. package/package.json +211 -14
  184. package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts +0 -7
  185. package/dist/react/features/model-picker/components/CredentialStatusBadge.js +0 -20
  186. package/dist/react/features/model-picker/components/ModelPicker.d.ts +0 -9
  187. package/dist/react/features/model-picker/components/ModelPicker.js +0 -34
  188. package/dist/react/features/model-picker/constants.d.ts +0 -6
  189. package/dist/react/features/model-picker/constants.js +0 -9
  190. package/dist/react/features/model-picker/dependencies.d.ts +0 -11
  191. package/dist/react/features/model-picker/dependencies.js +0 -10
  192. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts +0 -27
  193. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js +0 -62
  194. package/dist/react/features/model-picker/index.d.ts +0 -32
  195. package/dist/react/features/model-picker/index.js +0 -29
  196. package/dist/react/features/model-picker/ports.d.ts +0 -11
  197. package/dist/react/features/model-picker/rules.d.ts +0 -26
  198. package/dist/react/features/model-picker/rules.js +0 -84
  199. package/dist/react/features/model-picker/types.d.ts +0 -38
  200. package/dist/react/features/model-picker/types.js +0 -2
  201. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts +0 -9
  202. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js +0 -29
  203. package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts +0 -30
  204. package/dist/react/poc-mcp-ui-official/create-poc-resource.js +0 -44
  205. /package/dist/{react/features/model-picker → server/run-finalizer}/ports.js +0 -0
@@ -34,8 +34,8 @@ export function useChatPaneRuntimeInventory({ access, initialAgents = EMPTY_AGEN
34
34
  const [connectingAgents, setConnectingAgents] = useState(false);
35
35
  const [daemonOnline, setDaemonOnline] = useState(false);
36
36
  const [runtimeInventoryError, setRuntimeInventoryError] = useState(null);
37
- const inventory = useLatestOperation();
38
- const health = useLatestOperation();
37
+ const inventory = useLatestOperation({});
38
+ const health = useLatestOperation({});
39
39
  const retry = useInventoryRetry(retryDelaysMs);
40
40
  useEffect(() => {
41
41
  if (access !== undefined)
@@ -53,24 +53,24 @@ export function useChatPaneRuntimeInventory({ access, initialAgents = EMPTY_AGEN
53
53
  retry.cancel();
54
54
  setScanningAgents(true);
55
55
  setRuntimeInventoryError(null);
56
- await inventory.run(async (token) => {
57
- const nextAgents = await (rescan ? access.rescanAgents() : access.listAgents());
58
- token.ensureCurrent();
59
- retry.answered();
60
- setAgents([...nextAgents]);
61
- setConnectingAgents(false);
62
- setScanningAgents(false);
63
- }, (error) => {
64
- // A failed load after a good answer keeps that inventory on screen. Before one there is no
65
- // last-good to keep: clear to empty, report "connecting", and try again on the backoff.
66
- if (!retry.hasAnswer()) {
67
- setAgents([]);
68
- setConnectingAgents(true);
69
- retry.schedule(() => void loadAgents(false));
70
- }
71
- setRuntimeInventoryError(error);
72
- setScanningAgents(false);
73
- });
56
+ await inventory.run({ body: async (token) => {
57
+ const nextAgents = await (rescan ? access.rescanAgents() : access.listAgents());
58
+ token.ensureCurrent();
59
+ retry.answered();
60
+ setAgents([...nextAgents]);
61
+ setConnectingAgents(false);
62
+ setScanningAgents(false);
63
+ }, onError: (error) => {
64
+ // A failed load after a good answer keeps that inventory on screen. Before one there is no
65
+ // last-good to keep: clear to empty, report "connecting", and try again on the backoff.
66
+ if (!retry.hasAnswer()) {
67
+ setAgents([]);
68
+ setConnectingAgents(true);
69
+ retry.schedule(() => void loadAgents(false));
70
+ }
71
+ setRuntimeInventoryError(error);
72
+ setScanningAgents(false);
73
+ } });
74
74
  }, [access, inventory, retry]);
75
75
  /** A fresh attempt now, with the backoff restarted — only while nothing has answered yet. */
76
76
  const reloadIfUnanswered = useCallback(() => {
@@ -86,16 +86,16 @@ export function useChatPaneRuntimeInventory({ access, initialAgents = EMPTY_AGEN
86
86
  // below) all sit behind their own `if (!access) return` — `access` is guaranteed defined by
87
87
  // the time any one runs.
88
88
  const runtimeAccess = access;
89
- await health.run(async (token) => {
90
- const online = await runtimeAccess.daemonOnline();
91
- token.ensureCurrent();
92
- setDaemonOnline(online);
93
- if (retry.observeOnline(online))
94
- reloadIfUnanswered();
95
- }, () => {
96
- retry.observeOnline(false);
97
- setDaemonOnline(false);
98
- });
89
+ await health.run({ body: async (token) => {
90
+ const online = await runtimeAccess.daemonOnline();
91
+ token.ensureCurrent();
92
+ setDaemonOnline(online);
93
+ if (retry.observeOnline(online))
94
+ reloadIfUnanswered();
95
+ }, onError: () => {
96
+ retry.observeOnline(false);
97
+ setDaemonOnline(false);
98
+ } });
99
99
  }, [access, health, reloadIfUnanswered, retry]);
100
100
  useEffect(() => {
101
101
  if (!access)
@@ -25,7 +25,7 @@ export function useChatPaneWorkingDirectory(options) {
25
25
  const [workingDirectoryInvalid, setWorkingDirectoryInvalid] = useState(false);
26
26
  const [workingDirectoryPending, setWorkingDirectoryPending] = useState(false);
27
27
  const [workingDirectoryError, setWorkingDirectoryError] = useState(null);
28
- const operation = useLatestOperation();
28
+ const operation = useLatestOperation({});
29
29
  const observedDirectoryRef = useRef(undefined);
30
30
  const workingDirectory = controlled
31
31
  ? options.workingDirectory ?? null
@@ -55,29 +55,29 @@ export function useChatPaneWorkingDirectory(options) {
55
55
  }
56
56
  let validationSettled = false;
57
57
  setWorkingDirectoryPending(true);
58
- void operation.run(async (token) => {
59
- const normalized = access.normalizeWorkingDirectory
60
- ? await access.normalizeWorkingDirectory(workingDirectory)
61
- : workingDirectory;
62
- token.ensureCurrent();
63
- if (normalized === null) {
58
+ void operation.run({ body: async (token) => {
59
+ const normalized = access.normalizeWorkingDirectory
60
+ ? await access.normalizeWorkingDirectory(workingDirectory)
61
+ : workingDirectory;
62
+ token.ensureCurrent();
63
+ if (normalized === null) {
64
+ validationSettled = true;
65
+ setWorkingDirectoryInvalid(true);
66
+ setWorkingDirectoryPending(false);
67
+ return;
68
+ }
69
+ const exists = await access.directoryExists(normalized);
70
+ token.ensureCurrent();
71
+ if (normalized !== workingDirectory)
72
+ reportWorkingDirectory(normalized);
64
73
  validationSettled = true;
65
- setWorkingDirectoryInvalid(true);
74
+ setWorkingDirectoryInvalid(!exists);
66
75
  setWorkingDirectoryPending(false);
67
- return;
68
- }
69
- const exists = await access.directoryExists(normalized);
70
- token.ensureCurrent();
71
- if (normalized !== workingDirectory)
72
- reportWorkingDirectory(normalized);
73
- validationSettled = true;
74
- setWorkingDirectoryInvalid(!exists);
75
- setWorkingDirectoryPending(false);
76
- }, (error) => {
77
- validationSettled = true;
78
- setWorkingDirectoryInvalid(true);
79
- reportFailure(error);
80
- });
76
+ }, onError: (error) => {
77
+ validationSettled = true;
78
+ setWorkingDirectoryInvalid(true);
79
+ reportFailure(error);
80
+ } });
81
81
  return () => {
82
82
  operation.supersede();
83
83
  // React Strict Mode replays this effect while preserving refs. Release
@@ -102,18 +102,18 @@ export function useChatPaneWorkingDirectory(options) {
102
102
  return;
103
103
  setWorkingDirectoryError(null);
104
104
  setWorkingDirectoryPending(true);
105
- await operation.run(async (token) => {
106
- const [recent, exists] = await Promise.all([
107
- access.recentDirectories(),
108
- workingDirectory === null
109
- ? Promise.resolve(true)
110
- : access.directoryExists(workingDirectory),
111
- ]);
112
- token.ensureCurrent();
113
- setRecentDirectories([...recent]);
114
- setWorkingDirectoryInvalid(!exists);
115
- setWorkingDirectoryPending(false);
116
- }, reportFailure);
105
+ await operation.run({ body: async (token) => {
106
+ const [recent, exists] = await Promise.all([
107
+ access.recentDirectories(),
108
+ workingDirectory === null
109
+ ? Promise.resolve(true)
110
+ : access.directoryExists(workingDirectory),
111
+ ]);
112
+ token.ensureCurrent();
113
+ setRecentDirectories([...recent]);
114
+ setWorkingDirectoryInvalid(!exists);
115
+ setWorkingDirectoryPending(false);
116
+ }, onError: reportFailure });
117
117
  }, [operation, options.workingDirectoryAccess, reportFailure, workingDirectory]);
118
118
  const pickWorkingDirectory = useCallback(async () => {
119
119
  const access = options.workingDirectoryAccess;
@@ -121,23 +121,23 @@ export function useChatPaneWorkingDirectory(options) {
121
121
  return;
122
122
  setWorkingDirectoryError(null);
123
123
  setWorkingDirectoryPending(true);
124
- await operation.run(async (token) => {
125
- const selected = await access.pickWorkingDirectory(workingDirectory ?? undefined);
126
- token.ensureCurrent();
127
- if (selected === null) {
124
+ await operation.run({ body: async (token) => {
125
+ const selected = await access.pickWorkingDirectory(workingDirectory ?? undefined);
126
+ token.ensureCurrent();
127
+ if (selected === null) {
128
+ setWorkingDirectoryPending(false);
129
+ return;
130
+ }
131
+ const [exists, recent] = await Promise.all([
132
+ access.directoryExists(selected),
133
+ access.recentDirectories(),
134
+ ]);
135
+ token.ensureCurrent();
136
+ reportWorkingDirectory(selected);
137
+ setWorkingDirectoryInvalid(!exists);
138
+ setRecentDirectories([...recent]);
128
139
  setWorkingDirectoryPending(false);
129
- return;
130
- }
131
- const [exists, recent] = await Promise.all([
132
- access.directoryExists(selected),
133
- access.recentDirectories(),
134
- ]);
135
- token.ensureCurrent();
136
- reportWorkingDirectory(selected);
137
- setWorkingDirectoryInvalid(!exists);
138
- setRecentDirectories([...recent]);
139
- setWorkingDirectoryPending(false);
140
- }, reportFailure);
140
+ }, onError: reportFailure });
141
141
  }, [
142
142
  operation,
143
143
  options.workingDirectoryAccess,
@@ -154,13 +154,13 @@ export function useChatPaneWorkingDirectory(options) {
154
154
  return;
155
155
  }
156
156
  setWorkingDirectoryPending(true);
157
- await operation.run(async (token) => {
158
- const exists = await access.directoryExists(directory);
159
- token.ensureCurrent();
160
- reportWorkingDirectory(directory);
161
- setWorkingDirectoryInvalid(!exists);
162
- setWorkingDirectoryPending(false);
163
- }, reportFailure);
157
+ await operation.run({ body: async (token) => {
158
+ const exists = await access.directoryExists(directory);
159
+ token.ensureCurrent();
160
+ reportWorkingDirectory(directory);
161
+ setWorkingDirectoryInvalid(!exists);
162
+ setWorkingDirectoryPending(false);
163
+ }, onError: reportFailure });
164
164
  }, [operation, options.workingDirectoryAccess, reportFailure, reportWorkingDirectory]);
165
165
  const clearWorkingDirectory = useCallback(() => {
166
166
  operation.supersede();
@@ -1,6 +1,11 @@
1
1
  import type { ByokRuntimeSummary, ChatPaneAgent, ChatPaneAgentSelection } from './types.js';
2
- export declare function defaultChatPaneSelection(agent: ChatPaneAgent): ChatPaneAgentSelection;
3
- export declare function resolveChatPaneSelection(agents: readonly ChatPaneAgent[], requested: ChatPaneAgentSelection): ChatPaneAgentSelection;
2
+ export declare function defaultChatPaneSelection({ agent }: {
3
+ agent: ChatPaneAgent;
4
+ }): ChatPaneAgentSelection;
5
+ export declare function resolveChatPaneSelection({ agents, requested }: {
6
+ agents: readonly ChatPaneAgent[];
7
+ requested: ChatPaneAgentSelection;
8
+ }): ChatPaneAgentSelection;
4
9
  /**
5
10
  * Why a send would be refused, or `null` when the pane is ready to send.
6
11
  *
@@ -63,6 +68,10 @@ export declare function describeChatPaneSendBlocker(blocker: ChatPaneSendBlocker
63
68
  * those are clear. A flush path must therefore wait for a fully `null` blocker before sending,
64
69
  * not merely for streaming to end.
65
70
  */
66
- export declare function isChatPaneQueueableBlocker(blocker: ChatPaneSendBlocker | null): boolean;
67
- export declare function orderChatPaneAgents(agents: readonly ChatPaneAgent[]): ChatPaneAgent[];
71
+ export declare function isChatPaneQueueableBlocker({ blocker }: {
72
+ blocker: ChatPaneSendBlocker | null;
73
+ }): boolean;
74
+ export declare function orderChatPaneAgents({ agents }: {
75
+ agents: readonly ChatPaneAgent[];
76
+ }): ChatPaneAgent[];
68
77
  //# sourceMappingURL=rules.d.ts.map
@@ -6,7 +6,7 @@ function validatedOptionId(options, requested, fallback) {
6
6
  return requested;
7
7
  return fallback;
8
8
  }
9
- export function defaultChatPaneSelection(agent) {
9
+ export function defaultChatPaneSelection({ agent }) {
10
10
  const model = preferredOptionId(agent.models);
11
11
  const reasoning = preferredOptionId(agent.reasoningOptions);
12
12
  return {
@@ -15,12 +15,12 @@ export function defaultChatPaneSelection(agent) {
15
15
  ...(reasoning === undefined ? {} : { reasoning }),
16
16
  };
17
17
  }
18
- export function resolveChatPaneSelection(agents, requested) {
18
+ export function resolveChatPaneSelection({ agents, requested }) {
19
19
  const requestedAgent = agents.find((agent) => agent.id === requested.agentId && agent.available !== false);
20
20
  const agent = requestedAgent ?? agents.find((candidate) => candidate.available !== false);
21
21
  if (!agent)
22
22
  return { agentId: '' };
23
- const defaults = defaultChatPaneSelection(agent);
23
+ const defaults = defaultChatPaneSelection({ agent: agent });
24
24
  if (agent !== requestedAgent)
25
25
  return defaults;
26
26
  const model = requested.model
@@ -102,10 +102,10 @@ export function describeChatPaneSendBlocker(blocker) {
102
102
  * those are clear. A flush path must therefore wait for a fully `null` blocker before sending,
103
103
  * not merely for streaming to end.
104
104
  */
105
- export function isChatPaneQueueableBlocker(blocker) {
105
+ export function isChatPaneQueueableBlocker({ blocker }) {
106
106
  return blocker === 'streaming';
107
107
  }
108
- export function orderChatPaneAgents(agents) {
108
+ export function orderChatPaneAgents({ agents }) {
109
109
  return [...agents].sort((left, right) => {
110
110
  const availability = Number(left.available === false) - Number(right.available === false);
111
111
  return availability
@@ -22,7 +22,7 @@ export interface ChatPaneAgent {
22
22
  supportsCustomModel?: boolean;
23
23
  diagnostic?: string;
24
24
  /**
25
- * Whether this runtime can receive external MCP servers (Tovu/Jini tools) at all — mirrors
25
+ * Whether this runtime can receive external MCP servers (host/Jini tools) at all — mirrors
26
26
  * `@jini-ai/http-kit`'s `AgentSummary.supportsTools`, itself derived from
27
27
  * `@jini-ai/agent-runtime`'s `runtimeSupportsExternalTools(def)`. `AgentRuntimePicker` reads this
28
28
  * to show a "No tools" badge; `undefined` (a host on an older wire payload) is treated the same
@@ -34,14 +34,19 @@ export declare const MAX_CACHED_ATTACHMENT_PREVIEWS = 50;
34
34
  * if this would introduce a new entry past {@link MAX_CACHED_ATTACHMENT_PREVIEWS}.
35
35
  * @complexity Time/space: O(1) amortized.
36
36
  */
37
- export declare function cacheAttachmentPreviewSource(path: string, file: File): void;
37
+ export declare function cacheAttachmentPreviewSource({ path, file }: {
38
+ path: string;
39
+ file: File;
40
+ }): void;
38
41
  /**
39
42
  * Reads back the `File` cached for `path`, or `undefined` when this browser never staged it (a
40
43
  * different session, a reload, or eviction past the cap) - the only signal a preview needs to fall
41
44
  * back to an honest metadata view instead of pretending to render content it does not have.
42
45
  * @complexity Time/space: O(1).
43
46
  */
44
- export declare function getAttachmentPreviewSource(path: string): File | undefined;
47
+ export declare function getAttachmentPreviewSource({ path }: {
48
+ path: string;
49
+ }): File | undefined;
45
50
  /** Test-only: empties the module-level cache so test cases cannot leak attachments into each other. */
46
51
  export declare function __resetAttachmentPreviewCacheForTests(): void;
47
52
  //# sourceMappingURL=attachment-preview-cache.d.ts.map
@@ -35,7 +35,7 @@ const sources = new Map();
35
35
  * if this would introduce a new entry past {@link MAX_CACHED_ATTACHMENT_PREVIEWS}.
36
36
  * @complexity Time/space: O(1) amortized.
37
37
  */
38
- export function cacheAttachmentPreviewSource(path, file) {
38
+ export function cacheAttachmentPreviewSource({ path, file }) {
39
39
  if (!sources.has(path) && sources.size >= MAX_CACHED_ATTACHMENT_PREVIEWS) {
40
40
  const oldest = sources.keys().next().value;
41
41
  if (oldest !== undefined)
@@ -49,7 +49,7 @@ export function cacheAttachmentPreviewSource(path, file) {
49
49
  * back to an honest metadata view instead of pretending to render content it does not have.
50
50
  * @complexity Time/space: O(1).
51
51
  */
52
- export function getAttachmentPreviewSource(path) {
52
+ export function getAttachmentPreviewSource({ path }) {
53
53
  return sources.get(path);
54
54
  }
55
55
  /** Test-only: empties the module-level cache so test cases cannot leak attachments into each other. */
@@ -72,7 +72,9 @@ export declare const COMPOSER_ATTACHMENTS_STORAGE_PREFIX = "jini.chat.composer-a
72
72
  * treat `null` as "nothing to restore".
73
73
  * @complexity Time/space: O(1) on an in-memory hit, O(n) in the stored draft's length otherwise.
74
74
  */
75
- export declare function readCachedDraft(conversationId: string | null | undefined): string | null;
75
+ export declare function readCachedDraft({ conversationId }: {
76
+ conversationId: string | null | undefined;
77
+ }): string | null;
76
78
  /**
77
79
  * Stores `draft` for `conversationId` in both tiers.
78
80
  *
@@ -83,7 +85,10 @@ export declare function readCachedDraft(conversationId: string | null | undefine
83
85
  * writes `''` here.
84
86
  * @complexity Time/space: O(n) in the draft's length; see {@link writeStoredDraft}.
85
87
  */
86
- export declare function writeCachedDraft(conversationId: string | null | undefined, draft: string): void;
88
+ export declare function writeCachedDraft({ conversationId, draft }: {
89
+ conversationId: string | null | undefined;
90
+ draft: string;
91
+ }): void;
87
92
  /**
88
93
  * Explicitly evicts `conversationId`'s draft from both tiers, for a host that wants to free it
89
94
  * immediately (e.g. on conversation delete) rather than waiting for the cap-triggered eviction.
@@ -91,7 +96,9 @@ export declare function writeCachedDraft(conversationId: string | null | undefin
91
96
  * follow-up caller, out of scope here (that flow lives outside this package).
92
97
  * @complexity Time/space: O(1).
93
98
  */
94
- export declare function clearCachedDraft(conversationId: string | null | undefined): void;
99
+ export declare function clearCachedDraft({ conversationId }: {
100
+ conversationId: string | null | undefined;
101
+ }): void;
95
102
  /**
96
103
  * Reads the cached attachment references for `conversationId`, in memory first, storage second.
97
104
  *
@@ -105,7 +112,9 @@ export declare function clearCachedDraft(conversationId: string | null | undefin
105
112
  * @returns The cached references, or `null` when there are none.
106
113
  * @complexity Time/space: O(1) on an in-memory hit, O(n) in the stored count otherwise.
107
114
  */
108
- export declare function readCachedAttachments(conversationId: string | null | undefined): readonly ChatAttachment[] | null;
115
+ export declare function readCachedAttachments({ conversationId }: {
116
+ conversationId: string | null | undefined;
117
+ }): readonly ChatAttachment[] | null;
109
118
  /**
110
119
  * Stores `attachments` for `conversationId` in both tiers.
111
120
  *
@@ -113,7 +122,10 @@ export declare function readCachedAttachments(conversationId: string | null | un
113
122
  * restore — the same rule the draft text follows.
114
123
  * @complexity Time/space: O(n) in the number of references.
115
124
  */
116
- export declare function writeCachedAttachments(conversationId: string | null | undefined, attachments: readonly ChatAttachment[]): void;
125
+ export declare function writeCachedAttachments({ conversationId, attachments }: {
126
+ conversationId: string | null | undefined;
127
+ attachments: readonly ChatAttachment[];
128
+ }): void;
117
129
  /**
118
130
  * Test-only: empties the cache so test cases cannot leak drafts into each other.
119
131
  *
@@ -210,7 +210,7 @@ function rememberInMemory(conversationId, draft) {
210
210
  * treat `null` as "nothing to restore".
211
211
  * @complexity Time/space: O(1) on an in-memory hit, O(n) in the stored draft's length otherwise.
212
212
  */
213
- export function readCachedDraft(conversationId) {
213
+ export function readCachedDraft({ conversationId }) {
214
214
  if (!conversationId)
215
215
  return null;
216
216
  const remembered = drafts.get(conversationId);
@@ -232,7 +232,7 @@ export function readCachedDraft(conversationId) {
232
232
  * writes `''` here.
233
233
  * @complexity Time/space: O(n) in the draft's length; see {@link writeStoredDraft}.
234
234
  */
235
- export function writeCachedDraft(conversationId, draft) {
235
+ export function writeCachedDraft({ conversationId, draft }) {
236
236
  if (!conversationId)
237
237
  return;
238
238
  if (draft.trim() === '') {
@@ -250,12 +250,12 @@ export function writeCachedDraft(conversationId, draft) {
250
250
  * follow-up caller, out of scope here (that flow lives outside this package).
251
251
  * @complexity Time/space: O(1).
252
252
  */
253
- export function clearCachedDraft(conversationId) {
253
+ export function clearCachedDraft({ conversationId }) {
254
254
  if (!conversationId)
255
255
  return;
256
256
  drafts.delete(conversationId);
257
257
  writeStoredDraft(conversationId, '');
258
- writeCachedAttachments(conversationId, []);
258
+ writeCachedAttachments({ conversationId: conversationId, attachments: [] });
259
259
  }
260
260
  /**
261
261
  * Narrows one parsed array element to a `ChatAttachment`.
@@ -336,7 +336,7 @@ function readStoredAttachments(conversationId) {
336
336
  * @returns The cached references, or `null` when there are none.
337
337
  * @complexity Time/space: O(1) on an in-memory hit, O(n) in the stored count otherwise.
338
338
  */
339
- export function readCachedAttachments(conversationId) {
339
+ export function readCachedAttachments({ conversationId }) {
340
340
  if (!conversationId)
341
341
  return null;
342
342
  const remembered = stagedAttachments.get(conversationId);
@@ -355,7 +355,7 @@ export function readCachedAttachments(conversationId) {
355
355
  * restore — the same rule the draft text follows.
356
356
  * @complexity Time/space: O(n) in the number of references.
357
357
  */
358
- export function writeCachedAttachments(conversationId, attachments) {
358
+ export function writeCachedAttachments({ conversationId, attachments }) {
359
359
  if (!conversationId)
360
360
  return;
361
361
  const key = `${COMPOSER_ATTACHMENTS_STORAGE_PREFIX}${conversationId}`;
@@ -14,5 +14,9 @@ export interface UseArtifactStreamResult {
14
14
  /** The last item — the one most likely to be "the artifact this turn produced". */
15
15
  current: ArtifactStreamItem | null;
16
16
  }
17
- export declare function useArtifactStream(content: string, registry?: RendererRegistry): UseArtifactStreamResult;
17
+ export declare function useArtifactStream({ content }: {
18
+ content: string;
19
+ }, { registry }?: {
20
+ registry?: (RendererRegistry) | undefined;
21
+ }): UseArtifactStreamResult;
18
22
  //# sourceMappingURL=useArtifactStream.d.ts.map
@@ -17,7 +17,7 @@ import { parseArtifacts, splitStreamingArtifact } from '../../core/index.js';
17
17
  function toFile(item) {
18
18
  return { name: item.identifier || item.title || 'artifact', kind: item.artifactType, content: item.content };
19
19
  }
20
- export function useArtifactStream(content, registry) {
20
+ export function useArtifactStream({ content }, { registry } = {}) {
21
21
  return useMemo(() => {
22
22
  const items = [];
23
23
  // `splitStreamingArtifact` is the authority on "is there a trailing,
@@ -28,9 +28,9 @@ export function useArtifactStream(content, registry) {
28
28
  // Running it on the raw `content` would double-count a live artifact:
29
29
  // once (wrongly) as "complete" via the synthetic flush, and again (correctly)
30
30
  // as "streaming" below.
31
- const { head, live } = splitStreamingArtifact(content);
31
+ const { head, live } = splitStreamingArtifact({ content: content });
32
32
  let current = null;
33
- for (const ev of parseArtifacts(head)) {
33
+ for (const ev of parseArtifacts({ content: head })) {
34
34
  if (ev.type === 'artifact:start') {
35
35
  current = { identifier: ev.identifier, artifactType: ev.artifactType, title: ev.title, content: '' };
36
36
  }
@@ -17,9 +17,14 @@ export interface UseChatFabDragResult {
17
17
  onPointerCancel: (event: ReactPointerEvent<HTMLButtonElement>) => void;
18
18
  }
19
19
  /** Keeps a dragged position fully on screen, re-clamped on drag and on viewport resize. */
20
- export declare function clampChatFabToViewport(position: ChatFabPosition, size: {
21
- width: number;
22
- height: number;
20
+ export declare function clampChatFabToViewport({ position, size }: {
21
+ position: ChatFabPosition;
22
+ size: {
23
+ width: number;
24
+ height: number;
25
+ };
23
26
  }): ChatFabPosition;
24
- export declare function useChatFabDrag(onClick: () => void): UseChatFabDragResult;
27
+ export declare function useChatFabDrag({ onClick }: {
28
+ onClick: () => void;
29
+ }): UseChatFabDragResult;
25
30
  //# sourceMappingURL=useChatFabDrag.d.ts.map
@@ -13,7 +13,7 @@ export const CHAT_FAB_DRAG_THRESHOLD_PX = 4;
13
13
  /** Keeps the button fully on screen with a small margin. */
14
14
  export const CHAT_FAB_EDGE_MARGIN_PX = 8;
15
15
  /** Keeps a dragged position fully on screen, re-clamped on drag and on viewport resize. */
16
- export function clampChatFabToViewport(position, size) {
16
+ export function clampChatFabToViewport({ position, size }) {
17
17
  const maxX = Math.max(CHAT_FAB_EDGE_MARGIN_PX, globalThis.innerWidth - size.width - CHAT_FAB_EDGE_MARGIN_PX);
18
18
  const maxY = Math.max(CHAT_FAB_EDGE_MARGIN_PX, globalThis.innerHeight - size.height - CHAT_FAB_EDGE_MARGIN_PX);
19
19
  return {
@@ -21,7 +21,7 @@ export function clampChatFabToViewport(position, size) {
21
21
  y: Math.min(Math.max(position.y, CHAT_FAB_EDGE_MARGIN_PX), maxY),
22
22
  };
23
23
  }
24
- export function useChatFabDrag(onClick) {
24
+ export function useChatFabDrag({ onClick }) {
25
25
  const buttonRef = useRef(null);
26
26
  const [position, setPosition] = useState(null);
27
27
  const drag = useRef(null);
@@ -32,7 +32,7 @@ export function useChatFabDrag(onClick) {
32
32
  return;
33
33
  setPosition((current) => (current === null
34
34
  ? null
35
- : clampChatFabToViewport(current, { width: element.offsetWidth, height: element.offsetHeight })));
35
+ : clampChatFabToViewport({ position: current, size: { width: element.offsetWidth, height: element.offsetHeight } })));
36
36
  };
37
37
  globalThis.addEventListener('resize', onResize);
38
38
  return () => globalThis.removeEventListener('resize', onResize);
@@ -54,7 +54,7 @@ export function useChatFabDrag(onClick) {
54
54
  if (state === null || state.pointerId !== event.pointerId)
55
55
  return;
56
56
  const element = event.currentTarget;
57
- const next = clampChatFabToViewport({ x: event.clientX - state.offsetX, y: event.clientY - state.offsetY }, { width: element.offsetWidth, height: element.offsetHeight });
57
+ const next = clampChatFabToViewport({ position: { x: event.clientX - state.offsetX, y: event.clientY - state.offsetY }, size: { width: element.offsetWidth, height: element.offsetHeight } });
58
58
  const rect = element.getBoundingClientRect();
59
59
  if (Math.abs(next.x - rect.left) > CHAT_FAB_DRAG_THRESHOLD_PX || Math.abs(next.y - rect.top) > CHAT_FAB_DRAG_THRESHOLD_PX) {
60
60
  state.moved = true;
@@ -33,14 +33,14 @@ import { cacheAttachmentPreviewSource } from './attachment-preview-cache.js';
33
33
  const EMPTY_MENTION = { open: false, query: '', results: [] };
34
34
  export function useComposer(options = {}) {
35
35
  const { project, composerSlots, persistence, conversationId, validateAttachments } = options;
36
- const [draft, setDraftState] = useState(() => options.initialDraft ?? persistence?.read() ?? readCachedDraft(conversationId) ?? '');
36
+ const [draft, setDraftState] = useState(() => options.initialDraft ?? persistence?.read() ?? readCachedDraft({ conversationId: conversationId }) ?? '');
37
37
  const [attachments, setAttachments] = useState([]);
38
38
  const [agent, setAgent] = useState(options.initialAgent);
39
39
  const [mention, setMention] = useState(EMPTY_MENTION);
40
40
  const setDraft = useCallback((next) => {
41
41
  setDraftState(next);
42
42
  persistence?.write(next);
43
- writeCachedDraft(conversationId, next);
43
+ writeCachedDraft({ conversationId: conversationId, draft: next });
44
44
  }, [persistence, conversationId]);
45
45
  // Lets the conversation-change effect below read the live draft without taking `draft` as a
46
46
  // dependency, which would re-run it on every keystroke.
@@ -57,7 +57,7 @@ export function useComposer(options = {}) {
57
57
  if (conversationId === previousConversationIdRef.current)
58
58
  return;
59
59
  previousConversationIdRef.current = conversationId;
60
- const restored = readCachedDraft(conversationId);
60
+ const restored = readCachedDraft({ conversationId: conversationId });
61
61
  // An id arriving where there was none is NOT a switch between two conversations — it is the one
62
62
  // the operator is already looking at finally getting a key (a new chat created server-side
63
63
  // mid-compose, or a host that resolves the active id asynchronously after mount). Adopt what
@@ -68,7 +68,7 @@ export function useComposer(options = {}) {
68
68
  // message into another. Attachments and the mention popover are left alone here for the same
69
69
  // reason — nothing was switched away from.
70
70
  if (previousConversationId == null && conversationId != null && restored === null && draftRef.current.trim() !== '') {
71
- writeCachedDraft(conversationId, draftRef.current);
71
+ writeCachedDraft({ conversationId: conversationId, draft: draftRef.current });
72
72
  return;
73
73
  }
74
74
  setDraftState(restored ?? '');
@@ -93,7 +93,7 @@ export function useComposer(options = {}) {
93
93
  attachmentsHydratedForRef.current = conversationId;
94
94
  return;
95
95
  }
96
- const cached = readCachedAttachments(conversationId);
96
+ const cached = readCachedAttachments({ conversationId: conversationId });
97
97
  if (cached === null || cached.length === 0) {
98
98
  attachmentsHydratedForRef.current = conversationId;
99
99
  return;
@@ -118,7 +118,7 @@ export function useComposer(options = {}) {
118
118
  }
119
119
  else {
120
120
  // Every reference was dead. Purge them so the next load does not pay for this again.
121
- writeCachedAttachments(conversationId, []);
121
+ writeCachedAttachments({ conversationId: conversationId, attachments: [] });
122
122
  }
123
123
  attachmentsHydratedForRef.current = conversationId;
124
124
  })();
@@ -135,7 +135,7 @@ export function useComposer(options = {}) {
135
135
  return;
136
136
  if (attachmentsHydratedForRef.current !== conversationId)
137
137
  return;
138
- writeCachedAttachments(conversationId, attachments);
138
+ writeCachedAttachments({ conversationId: conversationId, attachments: attachments });
139
139
  }, [attachments, conversationId]);
140
140
  const addAttachment = useCallback((attachment) => {
141
141
  setAttachments((prev) => [...prev, attachment]);
@@ -157,7 +157,7 @@ export function useComposer(options = {}) {
157
157
  uploaded.forEach((a, i) => {
158
158
  const file = files[i];
159
159
  if (file)
160
- cacheAttachmentPreviewSource(a.path, file);
160
+ cacheAttachmentPreviewSource({ path: a.path, file });
161
161
  });
162
162
  for (const a of uploaded)
163
163
  composerSlots?.onAttach?.(a);