@mast-ai/react-ui 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.
- package/LICENSE +193 -0
- package/README.md +57 -0
- package/dist/approval.d.ts +82 -0
- package/dist/components/AssistantMessage.d.ts +44 -0
- package/dist/components/ChatInput.d.ts +41 -0
- package/dist/components/ConversationPanel.d.ts +43 -0
- package/dist/components/InlineApproval.d.ts +26 -0
- package/dist/components/MessageItem.d.ts +29 -0
- package/dist/components/MessageList.d.ts +38 -0
- package/dist/components/ThinkingBlock.d.ts +32 -0
- package/dist/components/ToolCallBlock.d.ts +11 -0
- package/dist/components/UserMessage.d.ts +19 -0
- package/dist/context.d.ts +113 -0
- package/dist/hooks/useAgentStream.d.ts +131 -0
- package/dist/icons.d.ts +21 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +1012 -0
- package/dist/mentions/MentionPicker.d.ts +30 -0
- package/dist/mentions/index.d.ts +6 -0
- package/dist/mentions/types.d.ts +63 -0
- package/dist/mentions/useMentions.d.ts +54 -0
- package/dist/mentions/utils.d.ts +33 -0
- package/dist/styles.css +631 -0
- package/dist/types.d.ts +162 -0
- package/package.json +71 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { AgentRunner } from '@mast-ai/core';
|
|
3
|
+
import type { AgentConfig, Message } from '@mast-ai/core';
|
|
4
|
+
import { type OnApprovalRequired, type PendingApproval } from './approval';
|
|
5
|
+
import type { ConversationEntry, IconMap } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Props accepted by {@link AgentProvider}.
|
|
8
|
+
*/
|
|
9
|
+
export interface AgentProviderProps {
|
|
10
|
+
/** The {@link AgentRunner} that will execute agent runs. */
|
|
11
|
+
runner: AgentRunner;
|
|
12
|
+
/** The agent configuration used for every turn. */
|
|
13
|
+
agent: AgentConfig;
|
|
14
|
+
/** The subtree that should have access to {@link useAgent}. */
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Optional overrides for the bundled inline SVG icons. Any keys left
|
|
18
|
+
* unspecified fall back to the defaults exported from `./icons`. Distributed
|
|
19
|
+
* to descendants through a dedicated icon context so updates do not flow
|
|
20
|
+
* through the agent state context.
|
|
21
|
+
*/
|
|
22
|
+
icons?: IconMap;
|
|
23
|
+
/**
|
|
24
|
+
* Called before executing any tool call whose effective `needsApproval`
|
|
25
|
+
* evaluates to `true`. Resolve with `true` to proceed, `false` to cancel
|
|
26
|
+
* (the runner receives a synthetic "user cancelled" result), a string to
|
|
27
|
+
* short-circuit execution with that string as the tool result, or
|
|
28
|
+
* {@link import('./approval').INLINE_APPROVAL} to defer to the inline
|
|
29
|
+
* approval queue exposed via `useAgent().pendingApprovals`.
|
|
30
|
+
*
|
|
31
|
+
* Not called when no tool requires approval, and not called when the prop
|
|
32
|
+
* is omitted — in which case `requiresApproval: true` tools execute silently.
|
|
33
|
+
*/
|
|
34
|
+
onApprovalRequired?: OnApprovalRequired;
|
|
35
|
+
/**
|
|
36
|
+
* Runtime override of the per-tool approval policy. Bare names add approval
|
|
37
|
+
* even when the tool's own `requiresApproval` is `false`; names prefixed with
|
|
38
|
+
* `!` suppress approval even when `requiresApproval` is `true`.
|
|
39
|
+
*
|
|
40
|
+
* @example ['third_party_tool', '!safe_tool']
|
|
41
|
+
*/
|
|
42
|
+
approvalOverride?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Seed `Conversation.history` with previously-saved messages so the LLM
|
|
45
|
+
* continues from where it left off. Read once when the provider mounts;
|
|
46
|
+
* later changes have no effect until `reset()` is called.
|
|
47
|
+
*/
|
|
48
|
+
initialHistory?: Message[];
|
|
49
|
+
/**
|
|
50
|
+
* Seed the rendered entry list with previously-saved entries so existing
|
|
51
|
+
* turns render immediately on mount. Read once when the provider mounts.
|
|
52
|
+
*/
|
|
53
|
+
initialEntries?: ConversationEntry[];
|
|
54
|
+
/**
|
|
55
|
+
* Called after each completed turn (i.e. after a `done` event) with the
|
|
56
|
+
* latest core message history and UI entry list. Use this to persist the
|
|
57
|
+
* conversation to localStorage, IndexedDB, a server, etc. Not invoked when
|
|
58
|
+
* a run is cancelled or errors before completion.
|
|
59
|
+
*/
|
|
60
|
+
onConversationChange?: (history: Message[], entries: ConversationEntry[]) => void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The value exposed by {@link useAgent}.
|
|
64
|
+
*/
|
|
65
|
+
export interface UseAgentReturn {
|
|
66
|
+
/** Ordered conversation entries, suitable for rendering. */
|
|
67
|
+
messages: ConversationEntry[];
|
|
68
|
+
/**
|
|
69
|
+
* Live mirror of the underlying `Conversation.history` — the raw core
|
|
70
|
+
* `Message[]` sent to the LLM. Updated after every completed turn. Read
|
|
71
|
+
* this to imperatively persist conversation state.
|
|
72
|
+
*/
|
|
73
|
+
history: Message[];
|
|
74
|
+
/**
|
|
75
|
+
* Sends a user message and starts a new agent run. The first argument is
|
|
76
|
+
* the prompt delivered to the LLM. The optional second argument overrides
|
|
77
|
+
* what is rendered in the user bubble; when omitted, the prompt is shown.
|
|
78
|
+
*/
|
|
79
|
+
sendMessage: (text: string, displayText?: string) => void;
|
|
80
|
+
/** Aborts the current run, if any. */
|
|
81
|
+
cancel: () => void;
|
|
82
|
+
/** `true` while a run is in progress. */
|
|
83
|
+
isRunning: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Aborts any in-flight run, clears the rendered conversation, and replaces
|
|
86
|
+
* the underlying {@link Conversation} with a fresh instance so the next
|
|
87
|
+
* `sendMessage` call starts with empty core history.
|
|
88
|
+
*/
|
|
89
|
+
reset: () => void;
|
|
90
|
+
/**
|
|
91
|
+
* Tool calls awaiting an inline approval decision. Populated when
|
|
92
|
+
* `onApprovalRequired` resolves to `INLINE_APPROVAL` for a call. Each entry
|
|
93
|
+
* carries `approve()`, `reject()`, and `respondWith()` callbacks that
|
|
94
|
+
* resolve the underlying tool execution; the runner is paused until one is
|
|
95
|
+
* called.
|
|
96
|
+
*/
|
|
97
|
+
pendingApprovals: PendingApproval[];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Wraps a subtree with agent context.
|
|
101
|
+
*
|
|
102
|
+
* Internally creates a {@link Conversation} via `runner.conversation(agent)`
|
|
103
|
+
* and drives it with {@link useAgentStream}. Children access the resulting
|
|
104
|
+
* state through {@link useAgent}.
|
|
105
|
+
*/
|
|
106
|
+
export declare function AgentProvider({ runner, agent, children, icons, onApprovalRequired, approvalOverride, initialHistory, initialEntries, onConversationChange, }: AgentProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
107
|
+
/**
|
|
108
|
+
* Reads the current agent state from {@link AgentProvider}.
|
|
109
|
+
*
|
|
110
|
+
* Throws when called outside an `<AgentProvider>` so misuse is caught at the
|
|
111
|
+
* call site rather than producing silent runtime bugs.
|
|
112
|
+
*/
|
|
113
|
+
export declare function useAgent(): UseAgentReturn;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Conversation, Message } from '@mast-ai/core';
|
|
2
|
+
import type { ConversationEntry, ToolCallStatus } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Options accepted by {@link useAgentStream}.
|
|
5
|
+
*/
|
|
6
|
+
export interface UseAgentStreamOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Initial UI entry list. Used to restore a previously-saved conversation
|
|
9
|
+
* so existing turns render immediately on mount. Read once when the hook
|
|
10
|
+
* first initialises; changes to this prop after mount are ignored.
|
|
11
|
+
*/
|
|
12
|
+
initialEntries?: ConversationEntry[];
|
|
13
|
+
/**
|
|
14
|
+
* Called after a turn ends with the `done` event, with the freshly
|
|
15
|
+
* committed `entries` and `history`. Not called when a run is cancelled
|
|
16
|
+
* or errors before `done` is received.
|
|
17
|
+
*/
|
|
18
|
+
onTurnComplete?: (entries: ConversationEntry[], history: Message[]) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The value returned by {@link useAgentStream}.
|
|
22
|
+
*/
|
|
23
|
+
export interface UseAgentStreamReturn {
|
|
24
|
+
/**
|
|
25
|
+
* Ordered list of conversation entries built from the `AgentEvent` stream.
|
|
26
|
+
* Each `sendMessage` call appends one user entry and one assistant entry.
|
|
27
|
+
* Entries are updated in-place as events stream in; their `id` values are
|
|
28
|
+
* stable across renders.
|
|
29
|
+
*/
|
|
30
|
+
entries: ConversationEntry[];
|
|
31
|
+
/**
|
|
32
|
+
* Live mirror of the underlying `Conversation.history`. Initialised from
|
|
33
|
+
* `conversation.history` and updated to `event.history` whenever a `done`
|
|
34
|
+
* event is observed. Use this to imperatively persist conversation state.
|
|
35
|
+
*/
|
|
36
|
+
history: Message[];
|
|
37
|
+
/**
|
|
38
|
+
* `true` while the agent is generating a response; `false` otherwise.
|
|
39
|
+
* Reflects the overall run state rather than the individual entry's streaming
|
|
40
|
+
* flag, which may differ briefly at the boundaries of a run.
|
|
41
|
+
*/
|
|
42
|
+
isRunning: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Sends a user message and starts a new agent run.
|
|
45
|
+
*
|
|
46
|
+
* Appends a user `ConversationEntry` and an empty streaming assistant
|
|
47
|
+
* `ConversationEntry`, then consumes the `AgentEvent` stream emitted by
|
|
48
|
+
* `conversation.runStream`. Calling `sendMessage` while a run is already in
|
|
49
|
+
* progress is a no-op (the caller should disable the input while `isRunning`
|
|
50
|
+
* is true).
|
|
51
|
+
*
|
|
52
|
+
* @param text - The prompt sent to the LLM via `Conversation.runStream`.
|
|
53
|
+
* @param displayText - Optional override for the text rendered in the user
|
|
54
|
+
* bubble. When provided, the user `ConversationEntry.text` is set to this
|
|
55
|
+
* value while `text` is still passed unchanged to the runner. An empty
|
|
56
|
+
* string is treated as a deliberate override (it does not fall back to
|
|
57
|
+
* `text`).
|
|
58
|
+
*/
|
|
59
|
+
sendMessage: (text: string, displayText?: string) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Aborts the current run.
|
|
62
|
+
*
|
|
63
|
+
* Signals the underlying `AbortController`, which causes the agent loop to
|
|
64
|
+
* stop and sets the last assistant entry's `isStreaming` flag to `false`.
|
|
65
|
+
* Has no effect when `isRunning` is false.
|
|
66
|
+
*/
|
|
67
|
+
cancel: () => void;
|
|
68
|
+
/**
|
|
69
|
+
* Aborts any in-flight run and clears all conversation entries.
|
|
70
|
+
*
|
|
71
|
+
* Note that this only resets the UI rendering state owned by this hook. It
|
|
72
|
+
* does not clear the underlying `Conversation.history`; callers wanting to
|
|
73
|
+
* start a fresh conversation should also replace the `Conversation` instance.
|
|
74
|
+
*/
|
|
75
|
+
reset: () => void;
|
|
76
|
+
/**
|
|
77
|
+
* Sets the `awaitingApproval` flag on the first matching streaming
|
|
78
|
+
* `ToolEventEntry` (by `name`) within the most recent assistant entry.
|
|
79
|
+
*
|
|
80
|
+
* Used by the approval proxy in `AgentProvider` to surface "awaiting human
|
|
81
|
+
* decision" as a first-class state on the entry, so renderers can show a
|
|
82
|
+
* pause indicator without correlating tool calls themselves.
|
|
83
|
+
*/
|
|
84
|
+
setToolAwaitingApproval: (name: string, awaiting: boolean) => void;
|
|
85
|
+
/**
|
|
86
|
+
* Sets the `status` field on the first matching streaming `ToolEventEntry`
|
|
87
|
+
* (by `name`). Used by the approval proxy to mark a call as `'cancelled'`
|
|
88
|
+
* before the runner emits `tool_call_completed` so the eventual completion
|
|
89
|
+
* event preserves the cancellation rather than defaulting to `'success'`.
|
|
90
|
+
*/
|
|
91
|
+
setToolStatus: (name: string, status: ToolCallStatus) => void;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Internal hook that drives the streaming state machine for a single
|
|
95
|
+
* `Conversation` instance.
|
|
96
|
+
*
|
|
97
|
+
* Subscribes to `AgentEvent`s emitted by `conversation.runStream` and
|
|
98
|
+
* maintains a `ConversationEntry[]` that reflects the current rendered state
|
|
99
|
+
* of the conversation. Sub-agent events are captured via `onToolEvent` and
|
|
100
|
+
* routed to the matching `ToolEventEntry` by tool name.
|
|
101
|
+
*
|
|
102
|
+
* This hook is consumed by `<AgentProvider>` and is not part of the public API.
|
|
103
|
+
* It is exported so that it can be used independently in advanced scenarios.
|
|
104
|
+
*
|
|
105
|
+
* ### State machine summary
|
|
106
|
+
*
|
|
107
|
+
* | Event | Action |
|
|
108
|
+
* |-------|--------|
|
|
109
|
+
* | `sendMessage(text)` | Append user entry; append assistant entry with `isStreaming: true` |
|
|
110
|
+
* | `text_delta` | Append delta to last assistant entry's `text` |
|
|
111
|
+
* | `thinking` | Append delta to last assistant entry's `thinking` |
|
|
112
|
+
* | `tool_call_started` | Push new `ToolEventEntry` with `isStreaming: true` |
|
|
113
|
+
* | `onToolEvent` → `thinking` | Append delta to matching `ToolEventEntry.subThinking` |
|
|
114
|
+
* | `onToolEvent` → `text_delta` | Append delta to matching `ToolEventEntry.subText` |
|
|
115
|
+
* | `onToolEvent` → `tool_call_started` | Push new nested `ToolEventEntry` onto parent's `nestedToolEvents` |
|
|
116
|
+
* | `onToolEvent` → `tool_call_completed` | Set `result` and `isStreaming: false` on matching nested entry |
|
|
117
|
+
* | `onToolEvent` → `done` | Ignored |
|
|
118
|
+
* | `tool_call_completed` | Set `result` and `isStreaming: false` on matching entry |
|
|
119
|
+
* | `done` | Set `text = output` and `isStreaming: false` on assistant entry |
|
|
120
|
+
* | Error / cancel | Set `isStreaming: false` on last assistant entry |
|
|
121
|
+
*
|
|
122
|
+
* @param conversation - A `Conversation` instance obtained from
|
|
123
|
+
* `AgentRunner.conversation(agentConfig)`.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```tsx
|
|
127
|
+
* const conversation = useMemo(() => runner.conversation(agentConfig), [runner, agentConfig]);
|
|
128
|
+
* const { entries, sendMessage, cancel, isRunning } = useAgentStream(conversation);
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export declare function useAgentStream(conversation: Conversation, options?: UseAgentStreamOptions): UseAgentStreamReturn;
|
package/dist/icons.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { IconMap } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Bundled defaults for every icon slot. Every key is populated, so callers
|
|
5
|
+
* receive a `Required<IconMap>` from {@link useIcons}.
|
|
6
|
+
*/
|
|
7
|
+
export declare const defaultIcons: Required<IconMap>;
|
|
8
|
+
/**
|
|
9
|
+
* Internal provider used by `<AgentProvider>` to merge consumer overrides on
|
|
10
|
+
* top of the bundled defaults before publishing the resulting map.
|
|
11
|
+
*/
|
|
12
|
+
export declare function IconProvider({ icons, children }: {
|
|
13
|
+
icons?: IconMap;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* Internal hook used by components that render an icon slot. Always returns
|
|
18
|
+
* a fully populated map, falling back to the bundled defaults for any slot
|
|
19
|
+
* the consumer did not override.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useIcons(): Required<IconMap>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type { ConversationEntry, ToolEventEntry, ToolCallStatus, IconMap } from './types';
|
|
2
|
+
export { useAgentStream } from './hooks/useAgentStream';
|
|
3
|
+
export type { UseAgentStreamOptions, UseAgentStreamReturn } from './hooks/useAgentStream';
|
|
4
|
+
export { AgentProvider, useAgent } from './context';
|
|
5
|
+
export type { AgentProviderProps, UseAgentReturn } from './context';
|
|
6
|
+
export { INLINE_APPROVAL } from './approval';
|
|
7
|
+
export type { OnApprovalRequired, PendingApproval } from './approval';
|
|
8
|
+
export { InlineApproval } from './components/InlineApproval';
|
|
9
|
+
export type { InlineApprovalProps } from './components/InlineApproval';
|
|
10
|
+
export { ThinkingBlock } from './components/ThinkingBlock';
|
|
11
|
+
export type { ThinkingBlockProps } from './components/ThinkingBlock';
|
|
12
|
+
export { ToolCallBlock } from './components/ToolCallBlock';
|
|
13
|
+
export type { ToolCallBlockProps } from './components/ToolCallBlock';
|
|
14
|
+
export { UserMessage } from './components/UserMessage';
|
|
15
|
+
export type { UserMessageProps } from './components/UserMessage';
|
|
16
|
+
export { AssistantMessage } from './components/AssistantMessage';
|
|
17
|
+
export type { AssistantMessageProps } from './components/AssistantMessage';
|
|
18
|
+
export { ChatInput } from './components/ChatInput';
|
|
19
|
+
export type { ChatInputProps } from './components/ChatInput';
|
|
20
|
+
export { MessageItem } from './components/MessageItem';
|
|
21
|
+
export type { MessageItemProps } from './components/MessageItem';
|
|
22
|
+
export { MessageList } from './components/MessageList';
|
|
23
|
+
export type { MessageListProps } from './components/MessageList';
|
|
24
|
+
export { ConversationPanel } from './components/ConversationPanel';
|
|
25
|
+
export type { ConversationPanelProps } from './components/ConversationPanel';
|
|
26
|
+
export { useMentions } from './mentions/useMentions';
|
|
27
|
+
export type { UseMentionsReturn } from './mentions/useMentions';
|
|
28
|
+
export { buildInlineMentionPrompt, extractMentionQuery, removeMentionTrigger, } from './mentions/utils';
|
|
29
|
+
export type { MentionItem, MentionSegment, MentionsConfig } from './mentions/types';
|