@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.
- package/CHANGELOG.md +18 -0
- package/dist/core/composer-history.d.ts +54 -0
- package/dist/core/composer-history.js +57 -0
- package/dist/core/durable-projection.d.ts +28 -0
- package/dist/core/durable-projection.js +71 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +2 -0
- package/dist/core/run-activity.d.ts +12 -20
- package/dist/core/run-activity.js +59 -7
- package/dist/core/tool-events.d.ts +34 -0
- package/dist/core/tool-events.js +61 -0
- package/dist/core/tools.d.ts +1 -1
- package/dist/core/tools.js +1 -1
- package/dist/core/transport.d.ts +4 -0
- package/dist/react/components/Composer.js +6 -0
- package/dist/react/components/Markdown.js +37 -6
- package/dist/react/components/MessageList.hooks.js +8 -2
- package/dist/react/components/MessageList.rules.d.ts +18 -0
- package/dist/react/components/MessageList.rules.js +15 -0
- package/dist/react/components/MessageRow.js +26 -11
- package/dist/react/components/ToolCard.js +10 -7
- package/dist/react/ext-event-renderer-registry.d.ts +7 -0
- package/dist/react/features/chat-pane/components/ChatPane.d.ts +1 -1
- package/dist/react/features/chat-pane/components/ChatPane.js +5 -3
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts +3 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +42 -9
- package/dist/react/features/chat-pane/rules.d.ts +6 -3
- package/dist/react/features/chat-pane/rules.js +6 -3
- package/dist/react/features/chat-pane/types.d.ts +5 -0
- package/dist/react/hooks/composer-draft-cache.d.ts +28 -0
- package/dist/react/hooks/composer-draft-cache.js +56 -6
- package/dist/react/hooks/composer-history-storage.d.ts +8 -0
- package/dist/react/hooks/composer-history-storage.js +40 -0
- package/dist/react/hooks/last-conversation-store.d.ts +58 -0
- package/dist/react/hooks/last-conversation-store.js +112 -0
- package/dist/react/hooks/useComposer.d.ts +10 -1
- package/dist/react/hooks/useComposer.js +14 -2
- package/dist/react/hooks/useComposerHistory.hooks.d.ts +15 -0
- package/dist/react/hooks/useComposerHistory.hooks.js +90 -0
- package/dist/react/hooks/useComposerHistoryKeys.hooks.d.ts +9 -0
- package/dist/react/hooks/useComposerHistoryKeys.hooks.js +90 -0
- package/dist/react/hooks/useConversation.js +6 -2
- package/dist/react/hooks/useRunStream.js +12 -2
- package/dist/react/hooks/useToolTimeline.js +6 -3
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.js +6 -0
- 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
|
|
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
|
-
|
|
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) {
|
package/dist/react/index.d.ts
CHANGED
|
@@ -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
|
package/dist/react/index.js
CHANGED
|
@@ -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.
|
|
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/
|
|
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/
|
|
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.
|
|
241
|
+
"@jini-ai/agent-runtime": "0.4.1",
|
|
242
242
|
"@jini-ai/db": "0.3.0"
|
|
243
243
|
},
|
|
244
244
|
"typesVersions": {
|