@jini-ai/chat 0.5.2 → 0.5.4

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 (47) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/core/composer-history.d.ts +54 -0
  3. package/dist/core/composer-history.js +57 -0
  4. package/dist/core/durable-projection.d.ts +28 -0
  5. package/dist/core/durable-projection.js +71 -0
  6. package/dist/core/index.d.ts +3 -0
  7. package/dist/core/index.js +2 -0
  8. package/dist/core/run-activity.d.ts +12 -20
  9. package/dist/core/run-activity.js +59 -7
  10. package/dist/core/tool-events.d.ts +34 -0
  11. package/dist/core/tool-events.js +61 -0
  12. package/dist/core/tools.d.ts +1 -1
  13. package/dist/core/tools.js +1 -1
  14. package/dist/core/transport.d.ts +4 -0
  15. package/dist/react/components/Composer.js +6 -0
  16. package/dist/react/components/Markdown.js +37 -6
  17. package/dist/react/components/MessageList.hooks.js +8 -2
  18. package/dist/react/components/MessageList.rules.d.ts +18 -0
  19. package/dist/react/components/MessageList.rules.js +15 -0
  20. package/dist/react/components/MessageRow.js +26 -11
  21. package/dist/react/components/ToolCard.js +10 -7
  22. package/dist/react/ext-event-renderer-registry.d.ts +7 -0
  23. package/dist/react/features/chat-pane/components/ChatPane.d.ts +1 -1
  24. package/dist/react/features/chat-pane/components/ChatPane.js +5 -3
  25. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts +3 -0
  26. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +42 -9
  27. package/dist/react/features/chat-pane/rules.d.ts +6 -3
  28. package/dist/react/features/chat-pane/rules.js +6 -3
  29. package/dist/react/features/chat-pane/types.d.ts +5 -0
  30. package/dist/react/hooks/composer-draft-cache.d.ts +28 -0
  31. package/dist/react/hooks/composer-draft-cache.js +56 -6
  32. package/dist/react/hooks/composer-history-storage.d.ts +8 -0
  33. package/dist/react/hooks/composer-history-storage.js +40 -0
  34. package/dist/react/hooks/last-conversation-store.d.ts +58 -0
  35. package/dist/react/hooks/last-conversation-store.js +112 -0
  36. package/dist/react/hooks/useComposer.d.ts +10 -1
  37. package/dist/react/hooks/useComposer.js +14 -2
  38. package/dist/react/hooks/useComposerHistory.hooks.d.ts +15 -0
  39. package/dist/react/hooks/useComposerHistory.hooks.js +90 -0
  40. package/dist/react/hooks/useComposerHistoryKeys.hooks.d.ts +9 -0
  41. package/dist/react/hooks/useComposerHistoryKeys.hooks.js +90 -0
  42. package/dist/react/hooks/useConversation.js +6 -2
  43. package/dist/react/hooks/useRunStream.js +12 -2
  44. package/dist/react/hooks/useToolTimeline.js +6 -3
  45. package/dist/react/index.d.ts +8 -0
  46. package/dist/react/index.js +6 -0
  47. package/package.json +5 -5
@@ -17,6 +17,7 @@
17
17
  * comparison can't do this — `start()`'s handlers must exist before the
18
18
  * transport's promise resolves with the real id).
19
19
  */
20
+ import { mergeRunEvents } from '../../core/durable-projection.js';
20
21
  import { useCallback, useEffect, useRef, useState } from 'react';
21
22
  function reportRunStreamHostEffectFailure(effectName, error) {
22
23
  console.error(`[@jini-ai/chat] useRunStream ${effectName} host effect failed:`, error);
@@ -77,6 +78,15 @@ export function useRunStream({ transport }) {
77
78
  const makeHandlers = useCallback((generation) => {
78
79
  const isStale = () => generationRef.current !== generation;
79
80
  return {
81
+ onCheckpoint: (message) => {
82
+ if (isStale())
83
+ return;
84
+ const statuses = { queued: 'streaming', running: 'streaming', succeeded: 'done', failed: 'error', canceled: 'canceled' };
85
+ setState((prev) => ({ ...prev, runId: message.runId ?? prev.runId,
86
+ status: message.runStatus ? statuses[message.runStatus] : prev.status,
87
+ events: mergeRunEvents({ saved: prev.events, incoming: message.events ?? [] }, {}),
88
+ }));
89
+ },
80
90
  onEvent: (ev) => {
81
91
  if (isStale())
82
92
  return;
@@ -93,12 +103,12 @@ export function useRunStream({ transport }) {
93
103
  onError: (err) => {
94
104
  if (isStale())
95
105
  return;
96
- setState((prev) => ({ ...prev, status: 'error', error: err }));
106
+ setState((prev) => ({ ...prev, status: 'error', error: err, events: [...prev.events, { kind: 'status', code: 'run_terminal', label: err.message }] }));
97
107
  },
98
108
  onDone: (finalEvents) => {
99
109
  if (isStale())
100
110
  return;
101
- setState((prev) => ({ ...prev, status: prev.status === 'error' ? prev.status : 'done', events: finalEvents }));
111
+ setState((prev) => ({ ...prev, status: prev.status === 'error' || prev.status === 'canceled' ? prev.status : 'done', events: mergeRunEvents({ saved: prev.events, incoming: finalEvents }, {}) }));
102
112
  },
103
113
  };
104
114
  }, []);
@@ -3,17 +3,20 @@
3
3
  *
4
4
  * Per-tool lifecycle rows for a message's events: pairs each `tool_use` with
5
5
  * its `tool_result` (deduped by id via `@jini-ai/chat/core`'s
6
- * `dedupeToolUsesById`), derives a four-state status via
6
+ * `dedupeToolUsesById`, delegated wrapper calls folded onto their canonical
7
+ * rows via `foldDelegatedWrapperCalls`), derives a four-state status via
7
8
  * `deriveToolStatus`, and tracks per-row expand/collapse UI state. Pure over
8
9
  * `AgentEvent[]` — zero I/O. Per
9
10
  * `ADS-memory/reports/jini-port/recon/r4b-webui-design.md` §4.
10
11
  */
11
12
  import { useCallback, useMemo, useState } from 'react';
12
- import { dedupeToolUsesById, deriveToolStatus } from '../../core/index.js';
13
+ import { dedupeToolUsesById, deriveToolStatus, foldDelegatedWrapperCalls } from '../../core/index.js';
13
14
  export function useToolTimeline({ events }, options = {}) {
14
15
  const { runStreaming = false, runSucceeded = false, defaultExpanded = false } = options;
15
16
  const [overrides, setOverrides] = useState({});
16
- const deduped = useMemo(() => dedupeToolUsesById({ events: events }), [events]);
17
+ // A delegated call's wrapper row and the daemon's canonical row have different ids, so dedupe
18
+ // alone leaves both; the fold keeps the canonical one (see `foldDelegatedWrapperCalls`).
19
+ const deduped = useMemo(() => foldDelegatedWrapperCalls({ events: dedupeToolUsesById({ events: events }) }), [events]);
17
20
  const rows = useMemo(() => {
18
21
  const out = [];
19
22
  for (const ev of deduped) {
@@ -112,6 +112,12 @@ export type { TodoCardProps } from './components/TodoCard.js';
112
112
  */
113
113
  export { ConversationList } from './components/ConversationList.js';
114
114
  export type { ConversationListProps, ConversationListItem } from './components/ConversationList.js';
115
+ /**
116
+ * The conversation an operator last had open, per caller identity — so a host's switcher lands
117
+ * back on it after a reload instead of an empty new chat. See the module doc for the contract.
118
+ */
119
+ export { createLastConversationStore, LAST_CONVERSATION_STORAGE_PREFIX } from './hooks/last-conversation-store.js';
120
+ export type { LastConversationStorage, LastConversationStore } from './hooks/last-conversation-store.js';
115
121
  export { ToolCard } from './components/ToolCard.js';
116
122
  export type { ToolCardProps } from './components/ToolCard.js';
117
123
  export { A2uiSurfaceCard } from './components/A2uiSurfaceCard.js';
@@ -157,4 +163,6 @@ export type { JiniChatProviderProps, JiniChatSlots } from './components/JiniChat
157
163
  export { createFrontendSessionBridge } from './agent-bridge/frontend-session-bridge.js';
158
164
  export type { FrontendSessionBridge, FrontendSessionBridgeArgs, FrontendSessionBridgeOptions, } from './agent-bridge/frontend-session-bridge.js';
159
165
  export { createDomPageDriver, currentAgentPage, type DomPageDriverOptions } from '@jini-ai/agentic/dom';
166
+ export { createBrowserComposerHistoryStorage } from './hooks/composer-history-storage.js';
167
+ export type { ComposerHistoryStoragePort } from '../core/composer-history.js';
160
168
  //# sourceMappingURL=index.d.ts.map
@@ -86,6 +86,11 @@ export { TodoCard } from './components/TodoCard.js';
86
86
  * `leadingAccessory` slot; it needs no changes to `ChatPane` itself.
87
87
  */
88
88
  export { ConversationList } from './components/ConversationList.js';
89
+ /**
90
+ * The conversation an operator last had open, per caller identity — so a host's switcher lands
91
+ * back on it after a reload instead of an empty new chat. See the module doc for the contract.
92
+ */
93
+ export { createLastConversationStore, LAST_CONVERSATION_STORAGE_PREFIX } from './hooks/last-conversation-store.js';
89
94
  export { ToolCard } from './components/ToolCard.js';
90
95
  export { A2uiSurfaceCard } from './components/A2uiSurfaceCard.js';
91
96
  /**
@@ -116,4 +121,5 @@ export { JiniChatProvider, useJiniChatSlots, useOnFeedback } from './components/
116
121
  */
117
122
  export { createFrontendSessionBridge } from './agent-bridge/frontend-session-bridge.js';
118
123
  export { createDomPageDriver, currentAgentPage } from '@jini-ai/agentic/dom';
124
+ export { createBrowserComposerHistoryStorage } from './hooks/composer-history-storage.js';
119
125
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jini-ai/chat",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Jini's chat/artifact frontend, consolidated into one package with two subpaths: framework-free chat vocabulary and pure parsers in `/core`, headless hooks + presentational components + slots in `/react`. Import only the layer you need.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -145,10 +145,10 @@
145
145
  "registry": "https://registry.npmjs.org"
146
146
  },
147
147
  "dependencies": {
148
- "@jini-ai/agentic": "^0.4.1",
149
- "@jini-ai/ui": "^0.4.3",
148
+ "@jini-ai/protocol": "^0.4.1",
150
149
  "@jini-ai/core": "^0.4.1",
151
- "@jini-ai/protocol": "^0.4.0"
150
+ "@jini-ai/ui": "^0.4.4",
151
+ "@jini-ai/agentic": "^0.4.2"
152
152
  },
153
153
  "peerDependencies": {
154
154
  "react": "^18.3.0 || ^19.0.0",
@@ -238,7 +238,7 @@
238
238
  "@electric-sql/pglite": "0.5.8",
239
239
  "pg": "8.23.0",
240
240
  "@ag-ui/core": "0.0.58",
241
- "@jini-ai/agent-runtime": "0.4.0",
241
+ "@jini-ai/agent-runtime": "0.4.1",
242
242
  "@jini-ai/db": "0.3.0"
243
243
  },
244
244
  "typesVersions": {