@jini-ai/chat 0.5.0 → 0.5.2
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 +17 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/surface-expiry.d.ts +42 -0
- package/dist/core/surface-expiry.js +42 -0
- package/dist/react/chat-pane.d.ts +2 -2
- package/dist/react/chat-pane.js +1 -1
- package/dist/react/components/AttachmentPreviewModal.hooks.d.ts +19 -2
- package/dist/react/components/AttachmentPreviewModal.hooks.js +53 -38
- package/dist/react/components/McpUiSurfaceCard.d.ts +7 -1
- package/dist/react/components/McpUiSurfaceCard.js +23 -38
- package/dist/react/components/MessageList.d.ts +11 -0
- package/dist/react/components/MessageList.hooks.d.ts +19 -0
- package/dist/react/components/MessageList.hooks.js +76 -0
- package/dist/react/components/MessageList.js +3 -71
- package/dist/react/components/MessageList.rules.d.ts +25 -0
- package/dist/react/components/MessageList.rules.js +23 -0
- package/dist/react/components/mcp-ui-surface-state.d.ts +27 -0
- package/dist/react/components/mcp-ui-surface-state.js +33 -0
- package/dist/react/features/chat-pane/components/ChatPane.d.ts +1 -1
- package/dist/react/features/chat-pane/components/ChatPane.js +6 -5
- package/dist/react/features/chat-pane/create-typed-answer-poster.d.ts +54 -0
- package/dist/react/features/chat-pane/create-typed-answer-poster.js +46 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts +17 -1
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +120 -4
- package/dist/react/features/chat-pane/index.d.ts +2 -1
- package/dist/react/features/chat-pane/index.js +1 -0
- package/dist/react/features/chat-pane/rules.d.ts +56 -1
- package/dist/react/features/chat-pane/rules.js +71 -0
- package/dist/react/features/chat-pane/types.d.ts +34 -0
- package/dist/react/hooks/useSurfaceExpiry.d.ts +20 -0
- package/dist/react/hooks/useSurfaceExpiry.js +35 -0
- package/dist/react/index.d.ts +4 -2
- package/dist/react/index.js +2 -1
- package/package.json +8 -8
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ChatMessage } from '@jini-ai/chat';
|
|
2
|
+
import type { ByokRuntimeSummary, ChatPaneAgent, ChatPaneAgentSelection, TypedAnswerNotice } from './types.js';
|
|
2
3
|
export declare function defaultChatPaneSelection({ agent }: {
|
|
3
4
|
agent: ChatPaneAgent;
|
|
4
5
|
}): ChatPaneAgentSelection;
|
|
@@ -71,6 +72,60 @@ export declare function describeChatPaneSendBlocker(blocker: ChatPaneSendBlocker
|
|
|
71
72
|
export declare function isChatPaneQueueableBlocker({ blocker }: {
|
|
72
73
|
blocker: ChatPaneSendBlocker | null;
|
|
73
74
|
}): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Whether the run in flight is holding a question open for the human: the newest message is the
|
|
77
|
+
* assistant's, and it carries an interactive surface (`kind: 'ext'`, e.g. an MCP-UI card) that
|
|
78
|
+
* arrived inside a still-open call to the host's question tool (`toolName`). That is the one moment
|
|
79
|
+
* text typed into the composer is an ANSWER rather than a next turn — the tool is parked waiting on
|
|
80
|
+
* it, and queueing the text behind the run would only deliver it after the question had expired, as
|
|
81
|
+
* a new paid run.
|
|
82
|
+
*
|
|
83
|
+
* Only the question tool counts. Other tools park on cards too — a delete confirm, an approval —
|
|
84
|
+
* but they take no typed answer: the server routes typed text only to the question tool, so treating
|
|
85
|
+
* those as waiting would refuse the text with "no longer waiting" and drop it instead of queueing.
|
|
86
|
+
* A call is the question tool when ANY `tool_use` for its id names it, since a vendor's wrapper row
|
|
87
|
+
* (`execute_delegated_tool`) and the daemon's canonical row share the id and may arrive in either
|
|
88
|
+
* order.
|
|
89
|
+
*
|
|
90
|
+
* A surface is attributed to the newest call still open when it arrived — the same rule
|
|
91
|
+
* `useExtEventGroups` uses to give a card its `call` — so an older call returning does not settle
|
|
92
|
+
* it. Once its call returns (answered, expired, abandoned), typing is a next turn again.
|
|
93
|
+
*
|
|
94
|
+
* @complexity O(e·c): e events in the newest message, c calls open at once (one or two in practice).
|
|
95
|
+
*/
|
|
96
|
+
export declare function isAwaitingTypedAnswer({ messages, toolName }: {
|
|
97
|
+
messages: readonly ChatMessage[];
|
|
98
|
+
toolName: string;
|
|
99
|
+
}): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* The tool-use id of the question {@link isAwaitingTypedAnswer} sees waiting, or `null` — the newest
|
|
102
|
+
* one when several are open. The id lets the pane tell one question from the next: a draft typed
|
|
103
|
+
* for a question stays tied to THAT question after it closes (see `useChatPane`'s held answer).
|
|
104
|
+
*
|
|
105
|
+
* @complexity O(e·c), as {@link isAwaitingTypedAnswer}.
|
|
106
|
+
*/
|
|
107
|
+
export declare function findAwaitedTypedAnswerId({ messages, toolName }: {
|
|
108
|
+
messages: readonly ChatMessage[];
|
|
109
|
+
toolName: string;
|
|
110
|
+
}): string | null;
|
|
111
|
+
/**
|
|
112
|
+
* Whether a composer send is an answer to a waiting question rather than a next turn: a run is
|
|
113
|
+
* streaming ({@link isChatPaneQueueableBlocker}), the turn has no attachments (a typed answer
|
|
114
|
+
* carries text only), and that run is holding the `toolName` question open
|
|
115
|
+
* ({@link isAwaitingTypedAnswer}).
|
|
116
|
+
*
|
|
117
|
+
* @complexity O(e·c), from {@link isAwaitingTypedAnswer}.
|
|
118
|
+
*/
|
|
119
|
+
export declare function isTypedAnswerTurn({ blocker, attachmentCount, messages, toolName }: {
|
|
120
|
+
blocker: ChatPaneSendBlocker | null;
|
|
121
|
+
attachmentCount: number;
|
|
122
|
+
messages: readonly ChatMessage[];
|
|
123
|
+
toolName: string;
|
|
124
|
+
}): boolean;
|
|
125
|
+
/** The English copy (and i18n key) for why a typed answer was not sent. */
|
|
126
|
+
export declare function describeTypedAnswerNotice({ notice }: {
|
|
127
|
+
notice: TypedAnswerNotice;
|
|
128
|
+
}): string;
|
|
74
129
|
export declare function orderChatPaneAgents({ agents }: {
|
|
75
130
|
agents: readonly ChatPaneAgent[];
|
|
76
131
|
}): ChatPaneAgent[];
|
|
@@ -105,6 +105,77 @@ export function describeChatPaneSendBlocker(blocker) {
|
|
|
105
105
|
export function isChatPaneQueueableBlocker({ blocker }) {
|
|
106
106
|
return blocker === 'streaming';
|
|
107
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Whether the run in flight is holding a question open for the human: the newest message is the
|
|
110
|
+
* assistant's, and it carries an interactive surface (`kind: 'ext'`, e.g. an MCP-UI card) that
|
|
111
|
+
* arrived inside a still-open call to the host's question tool (`toolName`). That is the one moment
|
|
112
|
+
* text typed into the composer is an ANSWER rather than a next turn — the tool is parked waiting on
|
|
113
|
+
* it, and queueing the text behind the run would only deliver it after the question had expired, as
|
|
114
|
+
* a new paid run.
|
|
115
|
+
*
|
|
116
|
+
* Only the question tool counts. Other tools park on cards too — a delete confirm, an approval —
|
|
117
|
+
* but they take no typed answer: the server routes typed text only to the question tool, so treating
|
|
118
|
+
* those as waiting would refuse the text with "no longer waiting" and drop it instead of queueing.
|
|
119
|
+
* A call is the question tool when ANY `tool_use` for its id names it, since a vendor's wrapper row
|
|
120
|
+
* (`execute_delegated_tool`) and the daemon's canonical row share the id and may arrive in either
|
|
121
|
+
* order.
|
|
122
|
+
*
|
|
123
|
+
* A surface is attributed to the newest call still open when it arrived — the same rule
|
|
124
|
+
* `useExtEventGroups` uses to give a card its `call` — so an older call returning does not settle
|
|
125
|
+
* it. Once its call returns (answered, expired, abandoned), typing is a next turn again.
|
|
126
|
+
*
|
|
127
|
+
* @complexity O(e·c): e events in the newest message, c calls open at once (one or two in practice).
|
|
128
|
+
*/
|
|
129
|
+
export function isAwaitingTypedAnswer({ messages, toolName }) {
|
|
130
|
+
return findAwaitedTypedAnswerId({ messages, toolName }) !== null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The tool-use id of the question {@link isAwaitingTypedAnswer} sees waiting, or `null` — the newest
|
|
134
|
+
* one when several are open. The id lets the pane tell one question from the next: a draft typed
|
|
135
|
+
* for a question stays tied to THAT question after it closes (see `useChatPane`'s held answer).
|
|
136
|
+
*
|
|
137
|
+
* @complexity O(e·c), as {@link isAwaitingTypedAnswer}.
|
|
138
|
+
*/
|
|
139
|
+
export function findAwaitedTypedAnswerId({ messages, toolName }) {
|
|
140
|
+
const newest = messages.at(-1);
|
|
141
|
+
if (newest?.role !== 'assistant')
|
|
142
|
+
return null;
|
|
143
|
+
// Open call id -> whether it is the question tool. Insertion-ordered, so the last entry is the
|
|
144
|
+
// newest call still open; a repeat id keeps its slot and only ORs in its name.
|
|
145
|
+
const openCalls = new Map();
|
|
146
|
+
const awaited = new Set();
|
|
147
|
+
for (const event of newest.events ?? []) {
|
|
148
|
+
if (event.kind === 'tool_use')
|
|
149
|
+
openCalls.set(event.id, openCalls.get(event.id) === true || event.name === toolName);
|
|
150
|
+
if (event.kind === 'tool_result') {
|
|
151
|
+
openCalls.delete(event.toolUseId);
|
|
152
|
+
awaited.delete(event.toolUseId);
|
|
153
|
+
}
|
|
154
|
+
const owner = event.kind === 'ext' ? [...openCalls].at(-1) : undefined;
|
|
155
|
+
if (owner?.[1] === true)
|
|
156
|
+
awaited.add(owner[0]);
|
|
157
|
+
}
|
|
158
|
+
return [...awaited].at(-1) ?? null;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Whether a composer send is an answer to a waiting question rather than a next turn: a run is
|
|
162
|
+
* streaming ({@link isChatPaneQueueableBlocker}), the turn has no attachments (a typed answer
|
|
163
|
+
* carries text only), and that run is holding the `toolName` question open
|
|
164
|
+
* ({@link isAwaitingTypedAnswer}).
|
|
165
|
+
*
|
|
166
|
+
* @complexity O(e·c), from {@link isAwaitingTypedAnswer}.
|
|
167
|
+
*/
|
|
168
|
+
export function isTypedAnswerTurn({ blocker, attachmentCount, messages, toolName }) {
|
|
169
|
+
return isChatPaneQueueableBlocker({ blocker }) && attachmentCount === 0 && isAwaitingTypedAnswer({ messages, toolName });
|
|
170
|
+
}
|
|
171
|
+
const TYPED_ANSWER_NOTICES = {
|
|
172
|
+
'not-pending': 'That question is no longer waiting for an answer, so your message was not sent.',
|
|
173
|
+
failed: 'Your answer could not be delivered. Try sending it again.',
|
|
174
|
+
};
|
|
175
|
+
/** The English copy (and i18n key) for why a typed answer was not sent. */
|
|
176
|
+
export function describeTypedAnswerNotice({ notice }) {
|
|
177
|
+
return TYPED_ANSWER_NOTICES[notice];
|
|
178
|
+
}
|
|
108
179
|
export function orderChatPaneAgents({ agents }) {
|
|
109
180
|
return [...agents].sort((left, right) => {
|
|
110
181
|
const availability = Number(left.available === false) - Number(right.available === false);
|
|
@@ -120,6 +120,28 @@ export interface ChatPaneComposerHandle {
|
|
|
120
120
|
*/
|
|
121
121
|
insertText: (text: string) => void;
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* What happened to text typed while the running agent waits on a question (see
|
|
125
|
+
* {@link ChatPaneProps.deliverTypedAnswer}): `'delivered'` — the question took it as its answer;
|
|
126
|
+
* `'not-pending'` — nothing is waiting any more (already answered, expired, or never open);
|
|
127
|
+
* `'failed'` — the host could not tell (network error, unexpected status).
|
|
128
|
+
*/
|
|
129
|
+
export type TypedAnswerDelivery = 'delivered' | 'not-pending' | 'failed';
|
|
130
|
+
/** Why the pane did not send a typed answer — shown to the human until the next send or reset. */
|
|
131
|
+
export type TypedAnswerNotice = Exclude<TypedAnswerDelivery, 'delivered'>;
|
|
132
|
+
/**
|
|
133
|
+
* Delivers text typed into the composer to the question the running agent is waiting on.
|
|
134
|
+
*
|
|
135
|
+
* Carries `toolName`, the host's question tool id, so the pane routes typed text here only while a
|
|
136
|
+
* card raised by THAT tool is open — any other pending card (a confirm, an approval) still queues the
|
|
137
|
+
* text behind the run. One value, so the tool the pane waits on and the tool the answer is posted to
|
|
138
|
+
* cannot drift apart; `createTypedAnswerPoster` sets it.
|
|
139
|
+
*/
|
|
140
|
+
export type DeliverTypedAnswer = ((input: {
|
|
141
|
+
text: string;
|
|
142
|
+
}) => Promise<TypedAnswerDelivery>) & {
|
|
143
|
+
readonly toolName: string;
|
|
144
|
+
};
|
|
123
145
|
export interface ChatPaneProps {
|
|
124
146
|
transport: ChatTransport;
|
|
125
147
|
agents?: readonly ChatPaneAgent[];
|
|
@@ -170,6 +192,18 @@ export interface ChatPaneProps {
|
|
|
170
192
|
* before the pane exists has nothing to call.
|
|
171
193
|
*/
|
|
172
194
|
composerHandle?: RefObject<ChatPaneComposerHandle | null>;
|
|
195
|
+
/**
|
|
196
|
+
* Called instead of queueing when the human types while the running agent is holding a question
|
|
197
|
+
* open in the transcript (an interactive surface whose call to `deliverTypedAnswer.toolName` has
|
|
198
|
+
* not returned — `isAwaitingTypedAnswer`) and the turn carries no attachments. `'delivered'` clears the draft
|
|
199
|
+
* (only if unchanged since it went out); any other outcome, or a throw, leaves the draft in place with a
|
|
200
|
+
* notice and NEVER queues it — a queued answer would go out after the run ends as a new, paid run
|
|
201
|
+
* answering nothing. A draft typed while the question waited stays held after it closes, until the
|
|
202
|
+
* human clears it or picks "Send as a new message" (`useChatPane`'s `sendAsNewMessage`).
|
|
203
|
+
*
|
|
204
|
+
* Omit it and typing while a run streams queues exactly as before.
|
|
205
|
+
*/
|
|
206
|
+
deliverTypedAnswer?: DeliverTypedAnswer;
|
|
173
207
|
placeholder?: string;
|
|
174
208
|
/**
|
|
175
209
|
* Rotating composer suggestions, cycled every few seconds in place of one fixed `placeholder` —
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type SurfaceExpiry } from '../../core/index.js';
|
|
2
|
+
/** The clock port: the current time, and a repeating ticker that returns its own stop function. */
|
|
3
|
+
export interface SurfaceExpiryClock {
|
|
4
|
+
nowMs(): number;
|
|
5
|
+
every(intervalMs: number, tick: () => void): () => void;
|
|
6
|
+
}
|
|
7
|
+
/** The wall clock and `setInterval`; the default when a caller injects none. */
|
|
8
|
+
export declare const SYSTEM_SURFACE_EXPIRY_CLOCK: SurfaceExpiryClock;
|
|
9
|
+
/**
|
|
10
|
+
* @param input.expiresAtMs - The card's deadline (epoch ms), or `undefined` when it has none.
|
|
11
|
+
* @param options.clock - Time source and ticker. Defaults to {@link SYSTEM_SURFACE_EXPIRY_CLOCK}.
|
|
12
|
+
* @returns The deadline's state at the last tick, or `undefined` when there is no deadline.
|
|
13
|
+
* @complexity O(1) per render; one ticker while live.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useSurfaceExpiry({ expiresAtMs }: {
|
|
16
|
+
expiresAtMs: number | undefined;
|
|
17
|
+
}, { clock }?: {
|
|
18
|
+
clock?: SurfaceExpiryClock;
|
|
19
|
+
}): SurfaceExpiry | undefined;
|
|
20
|
+
//# sourceMappingURL=useSurfaceExpiry.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module useSurfaceExpiry
|
|
3
|
+
*
|
|
4
|
+
* The live countdown for a pending MCP-UI card: `describeSurfaceExpiry` re-read once a second on an
|
|
5
|
+
* injected clock. Ticks only while the card is answerable and has a deadline; an expired card or one
|
|
6
|
+
* without a deadline runs no timer.
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect, useState } from 'react';
|
|
9
|
+
import { describeSurfaceExpiry, SURFACE_EXPIRY_TICK_MS } from '../../core/index.js';
|
|
10
|
+
/** The wall clock and `setInterval`; the default when a caller injects none. */
|
|
11
|
+
export const SYSTEM_SURFACE_EXPIRY_CLOCK = {
|
|
12
|
+
nowMs: () => Date.now(),
|
|
13
|
+
every: (intervalMs, tick) => {
|
|
14
|
+
const timer = setInterval(tick, intervalMs);
|
|
15
|
+
return () => clearInterval(timer);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* @param input.expiresAtMs - The card's deadline (epoch ms), or `undefined` when it has none.
|
|
20
|
+
* @param options.clock - Time source and ticker. Defaults to {@link SYSTEM_SURFACE_EXPIRY_CLOCK}.
|
|
21
|
+
* @returns The deadline's state at the last tick, or `undefined` when there is no deadline.
|
|
22
|
+
* @complexity O(1) per render; one ticker while live.
|
|
23
|
+
*/
|
|
24
|
+
export function useSurfaceExpiry({ expiresAtMs }, { clock = SYSTEM_SURFACE_EXPIRY_CLOCK } = {}) {
|
|
25
|
+
const [nowMs, setNowMs] = useState(() => clock.nowMs());
|
|
26
|
+
const expiry = expiresAtMs === undefined ? undefined : describeSurfaceExpiry({ expiresAtMs, nowMs });
|
|
27
|
+
const live = expiry?.expired === false;
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!live)
|
|
30
|
+
return undefined;
|
|
31
|
+
return clock.every(SURFACE_EXPIRY_TICK_MS, () => setNowMs(clock.nowMs()));
|
|
32
|
+
}, [live, clock]);
|
|
33
|
+
return expiry;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=useSurfaceExpiry.js.map
|
package/dist/react/index.d.ts
CHANGED
|
@@ -36,8 +36,8 @@ export type { ExtEventRenderProps, ExtEventRenderer, ExtEventRendererOptions, Ex
|
|
|
36
36
|
* This alias has no removal date scheduled yet; see `chat-pane.ts` for the canonical surface and
|
|
37
37
|
* the module doc there for why the split exists.
|
|
38
38
|
*/
|
|
39
|
-
export { AgentRuntimePicker, CHAT_PANE_AGENT_TOOLS, ChatPane, createDaemonAttachmentUploader, createMcpUiToolCaller, defaultChatPaneSelection, orderChatPaneAgents, resolveChatPaneSelection, useChatPane, useChatPaneAgentControl, useChatPaneRuntimeInventory, useChatPaneWorkingDirectory, } from './chat-pane.js';
|
|
40
|
-
export type { AgentRuntimePickerProps, ByokRuntimeSummary, ChatPaneActivity, ChatPaneAgent, ChatPaneAgentBridgeAccess, ChatPaneAgentControlOptions, ChatPaneAgentOption, ChatPaneAgentSelection, ChatPaneAgentToolAction, ChatPaneAgentToolDef, ChatPaneAgentToolInputSchema, ChatPaneAgentToolRisk, ChatPaneAttachmentUploadOptions, ChatPaneComposerHandle, ChatPaneProps, ChatPaneRunContext, ChatPaneRunContextInput, ChatPaneRuntimeAccess, ChatPaneVariant, ChatPaneWorkingDirectoryAccess, CreateDaemonAttachmentUploaderOptions, CreateMcpUiToolCallerOptions, McpUiToolCallRequest, RuntimePickerPlacement, UseChatPaneAgentControlOptions, UseChatPaneOptions, UseChatPaneResult, UseChatPaneRuntimeInventoryOptions, UseChatPaneRuntimeInventoryResult, UseChatPaneWorkingDirectoryOptions, UseChatPaneWorkingDirectoryResult, } from './chat-pane.js';
|
|
39
|
+
export { AgentRuntimePicker, CHAT_PANE_AGENT_TOOLS, ChatPane, createDaemonAttachmentUploader, createMcpUiToolCaller, createTypedAnswerPoster, defaultChatPaneSelection, orderChatPaneAgents, resolveChatPaneSelection, useChatPane, useChatPaneAgentControl, useChatPaneRuntimeInventory, useChatPaneWorkingDirectory, } from './chat-pane.js';
|
|
40
|
+
export type { AgentRuntimePickerProps, ByokRuntimeSummary, ChatPaneActivity, ChatPaneAgent, ChatPaneAgentBridgeAccess, ChatPaneAgentControlOptions, ChatPaneAgentOption, ChatPaneAgentSelection, ChatPaneAgentToolAction, ChatPaneAgentToolDef, ChatPaneAgentToolInputSchema, ChatPaneAgentToolRisk, ChatPaneAttachmentUploadOptions, ChatPaneComposerHandle, ChatPaneProps, ChatPaneRunContext, ChatPaneRunContextInput, ChatPaneRuntimeAccess, ChatPaneVariant, ChatPaneWorkingDirectoryAccess, CreateDaemonAttachmentUploaderOptions, CreateMcpUiToolCallerOptions, CreateTypedAnswerPosterOptions, DeliverTypedAnswer, McpUiToolCallRequest, RuntimePickerPlacement, TypedAnswerDelivery, TypedAnswerNotice, UseChatPaneAgentControlOptions, UseChatPaneOptions, UseChatPaneResult, UseChatPaneRuntimeInventoryOptions, UseChatPaneRuntimeInventoryResult, UseChatPaneWorkingDirectoryOptions, UseChatPaneWorkingDirectoryResult, } from './chat-pane.js';
|
|
41
41
|
export { useRunStream, } from './hooks/useRunStream.js';
|
|
42
42
|
export type { RunStreamState, RunStreamStatus, StartRunOptions, UseRunStreamResult, } from './hooks/useRunStream.js';
|
|
43
43
|
export { useConversation, } from './hooks/useConversation.js';
|
|
@@ -48,6 +48,8 @@ export { useToolTimeline, } from './hooks/useToolTimeline.js';
|
|
|
48
48
|
export type { ToolTimelineRow, UseToolTimelineOptions, UseToolTimelineResult, } from './hooks/useToolTimeline.js';
|
|
49
49
|
export { useExtEventGroups, } from './hooks/useExtEventGroups.js';
|
|
50
50
|
export type { ExtEventGroup, } from './hooks/useExtEventGroups.js';
|
|
51
|
+
export { SYSTEM_SURFACE_EXPIRY_CLOCK, useSurfaceExpiry, } from './hooks/useSurfaceExpiry.js';
|
|
52
|
+
export type { SurfaceExpiryClock, } from './hooks/useSurfaceExpiry.js';
|
|
51
53
|
export { usePinnedTodos, } from './hooks/usePinnedTodos.js';
|
|
52
54
|
export type { UsePinnedTodosResult, } from './hooks/usePinnedTodos.js';
|
|
53
55
|
export { parseSubmittedAnswers, useQuestionForms, } from './hooks/useQuestionForms.js';
|
package/dist/react/index.js
CHANGED
|
@@ -26,12 +26,13 @@ export { clearExtEventRenderers, extEventSlot, getExtEventRenderer, registerExtE
|
|
|
26
26
|
* This alias has no removal date scheduled yet; see `chat-pane.ts` for the canonical surface and
|
|
27
27
|
* the module doc there for why the split exists.
|
|
28
28
|
*/
|
|
29
|
-
export { AgentRuntimePicker, CHAT_PANE_AGENT_TOOLS, ChatPane, createDaemonAttachmentUploader, createMcpUiToolCaller, defaultChatPaneSelection, orderChatPaneAgents, resolveChatPaneSelection, useChatPane, useChatPaneAgentControl, useChatPaneRuntimeInventory, useChatPaneWorkingDirectory, } from './chat-pane.js';
|
|
29
|
+
export { AgentRuntimePicker, CHAT_PANE_AGENT_TOOLS, ChatPane, createDaemonAttachmentUploader, createMcpUiToolCaller, createTypedAnswerPoster, defaultChatPaneSelection, orderChatPaneAgents, resolveChatPaneSelection, useChatPane, useChatPaneAgentControl, useChatPaneRuntimeInventory, useChatPaneWorkingDirectory, } from './chat-pane.js';
|
|
30
30
|
export { useRunStream, } from './hooks/useRunStream.js';
|
|
31
31
|
export { useConversation, } from './hooks/useConversation.js';
|
|
32
32
|
export { useComposer, } from './hooks/useComposer.js';
|
|
33
33
|
export { useToolTimeline, } from './hooks/useToolTimeline.js';
|
|
34
34
|
export { useExtEventGroups, } from './hooks/useExtEventGroups.js';
|
|
35
|
+
export { SYSTEM_SURFACE_EXPIRY_CLOCK, useSurfaceExpiry, } from './hooks/useSurfaceExpiry.js';
|
|
35
36
|
export { usePinnedTodos, } from './hooks/usePinnedTodos.js';
|
|
36
37
|
export { parseSubmittedAnswers, useQuestionForms, } from './hooks/useQuestionForms.js';
|
|
37
38
|
export { useArtifactStream, } from './hooks/useArtifactStream.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/chat",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
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,15 +145,15 @@
|
|
|
145
145
|
"registry": "https://registry.npmjs.org"
|
|
146
146
|
},
|
|
147
147
|
"dependencies": {
|
|
148
|
-
"@jini-ai/
|
|
149
|
-
"@jini-ai/
|
|
150
|
-
"@jini-ai/
|
|
151
|
-
"@jini-ai/
|
|
148
|
+
"@jini-ai/agentic": "^0.4.1",
|
|
149
|
+
"@jini-ai/ui": "^0.4.3",
|
|
150
|
+
"@jini-ai/core": "^0.4.1",
|
|
151
|
+
"@jini-ai/protocol": "^0.4.0"
|
|
152
152
|
},
|
|
153
153
|
"peerDependencies": {
|
|
154
154
|
"react": "^18.3.0 || ^19.0.0",
|
|
155
155
|
"react-dom": "^18.3.0 || ^19.0.0",
|
|
156
|
-
"@jini-ai/db": "^0.2.0",
|
|
156
|
+
"@jini-ai/db": "^0.2.0 || ^0.3.0",
|
|
157
157
|
"kysely": "^0.29.6",
|
|
158
158
|
"better-sqlite3": "^13.0.0",
|
|
159
159
|
"@electric-sql/pglite": "0.5.8",
|
|
@@ -238,8 +238,8 @@
|
|
|
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/
|
|
242
|
-
"@jini-ai/
|
|
241
|
+
"@jini-ai/agent-runtime": "0.4.0",
|
|
242
|
+
"@jini-ai/db": "0.3.0"
|
|
243
243
|
},
|
|
244
244
|
"typesVersions": {
|
|
245
245
|
"*": {
|