@pikku/assistant-ui 0.12.0 → 0.12.1

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.
@@ -1,4 +1,4 @@
1
- export { usePikkuAgentRuntime } from './use-pikku-agent-runtime.js';
2
- export type { PikkuAgentRuntimeOptions } from './use-pikku-agent-runtime.js';
1
+ export { usePikkuAgentRuntime, usePikkuAgentNonStreamingRuntime, PikkuApprovalContext, usePikkuApproval, convertDbMessages, isDeniedResult, resolvePikkuToolStatus, } from './use-pikku-agent-runtime.js';
2
+ export type { PikkuAgentRuntimeOptions, PendingApproval, PikkuApprovalContextValue, PikkuToolStatusType, PikkuToolStatus, } from './use-pikku-agent-runtime.js';
3
3
  export { PikkuAgentChat } from './pikku-agent-chat.js';
4
4
  export type { PikkuAgentChatProps } from './pikku-agent-chat.js';
package/dist/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { usePikkuAgentRuntime } from './use-pikku-agent-runtime.js';
1
+ export { usePikkuAgentRuntime, usePikkuAgentNonStreamingRuntime, PikkuApprovalContext, usePikkuApproval, convertDbMessages, isDeniedResult, resolvePikkuToolStatus, } from './use-pikku-agent-runtime.js';
2
2
  export { PikkuAgentChat } from './pikku-agent-chat.js';
@@ -1,5 +1,11 @@
1
1
  import { type PikkuAgentRuntimeOptions } from './use-pikku-agent-runtime.js';
2
2
  export interface PikkuAgentChatProps extends PikkuAgentRuntimeOptions {
3
3
  emptyMessage?: string;
4
+ /** Hide tool calls from the chat display.
5
+ * - `true`: hide all non-approval tool calls
6
+ * - `string[]`: hide tool calls matching these names
7
+ */
8
+ hideToolCalls?: boolean | string[];
9
+ dark?: boolean;
4
10
  }
5
11
  export declare function PikkuAgentChat(props: PikkuAgentChatProps): import("react/jsx-runtime").JSX.Element;
@@ -1,21 +1,78 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState } from 'react';
2
+ import { createContext, useContext, useState, useMemo } from 'react';
3
+ import Markdown from 'react-markdown';
3
4
  import { AssistantRuntimeProvider, ThreadPrimitive, MessagePrimitive, ComposerPrimitive, } from '@assistant-ui/react';
4
- import { usePikkuAgentRuntime, } from './use-pikku-agent-runtime.js';
5
- const ToolCallDisplay = ({ toolName, args, result, status, addResult }) => {
5
+ import { usePikkuAgentRuntime, PikkuApprovalContext, usePikkuApproval, resolvePikkuToolStatus, } from './use-pikku-agent-runtime.js';
6
+ const lightColors = {
7
+ bg: '#ffffff',
8
+ userBubble: '#e3f2fd',
9
+ assistantBubble: '#f5f5f5',
10
+ text: '#1a1a1a',
11
+ textMuted: '#888',
12
+ border: '#ddd',
13
+ codeBg: '#f5f5f5',
14
+ inputBg: 'transparent',
15
+ sendBg: '#1976d2',
16
+ sendColor: '#fff',
17
+ approvalBg: '#fef9e7',
18
+ approvalBorder: '#e9a211',
19
+ successBg: '#e8f5e9',
20
+ successColor: '#2e7d32',
21
+ errorBg: '#ffebee',
22
+ errorColor: '#c62828',
23
+ };
24
+ const darkColors = {
25
+ bg: 'transparent',
26
+ userBubble: 'rgba(0, 230, 138, 0.1)',
27
+ assistantBubble: '#1e1e2e',
28
+ text: '#e0e0e8',
29
+ textMuted: '#8888a0',
30
+ border: '#2a2a3e',
31
+ codeBg: '#0e0e16',
32
+ inputBg: 'transparent',
33
+ sendBg: '#00cc7a',
34
+ sendColor: '#0a0a0f',
35
+ approvalBg: 'rgba(233, 162, 17, 0.1)',
36
+ approvalBorder: '#e9a211',
37
+ successBg: 'rgba(0, 230, 138, 0.1)',
38
+ successColor: '#00e68a',
39
+ errorBg: 'rgba(220, 38, 38, 0.1)',
40
+ errorColor: '#f87171',
41
+ };
42
+ const ColorsContext = createContext(lightColors);
43
+ const HideToolCallsContext = createContext(undefined);
44
+ function shouldHideToolCall(hideToolCalls, toolName) {
45
+ if (!hideToolCalls)
46
+ return false;
47
+ if (hideToolCalls === true)
48
+ return true;
49
+ return hideToolCalls.includes(toolName);
50
+ }
51
+ const ToolCallDisplay = ({ toolCallId, toolName, args, result, status, addResult }) => {
52
+ const colors = useContext(ColorsContext);
53
+ const hideToolCalls = useContext(HideToolCallsContext);
54
+ const { handleApproval } = usePikkuApproval();
6
55
  const [expanded, setExpanded] = useState(false);
7
56
  const isApproval = status.type === 'requires-action';
8
57
  const approvalReason = args?.__approvalReason;
9
58
  const displayArgs = { ...args };
10
59
  delete displayArgs.__approvalReason;
11
60
  const [responded, setResponded] = useState(null);
61
+ // Hide responded approval tool calls
62
+ if (isApproval && responded && shouldHideToolCall(hideToolCalls, toolName)) {
63
+ return null;
64
+ }
65
+ // Hide non-approval tool calls
66
+ if (!isApproval && shouldHideToolCall(hideToolCalls, toolName)) {
67
+ return null;
68
+ }
12
69
  if (isApproval && !responded) {
13
70
  return (_jsxs("div", { style: {
14
- border: '1px solid #e9a211',
71
+ border: `1px solid ${colors.approvalBorder}`,
15
72
  borderRadius: 6,
16
73
  padding: 12,
17
74
  margin: '4px 0',
18
- backgroundColor: '#fef9e7',
75
+ backgroundColor: colors.approvalBg,
19
76
  }, children: [_jsx("div", { style: {
20
77
  display: 'flex',
21
78
  alignItems: 'center',
@@ -23,40 +80,44 @@ const ToolCallDisplay = ({ toolName, args, result, status, addResult }) => {
23
80
  marginBottom: 8,
24
81
  fontWeight: 600,
25
82
  fontSize: 13,
26
- }, children: "Approval required" }), approvalReason && (_jsx("div", { style: { fontSize: 13, marginBottom: 4 }, children: approvalReason })), _jsxs("div", { style: { fontSize: 12, color: '#666', marginBottom: 4 }, children: ["The agent wants to call ", _jsx("code", { children: toolName })] }), _jsx("pre", { style: {
83
+ color: colors.text,
84
+ }, children: "Approval required" }), approvalReason && (_jsx("div", { style: { fontSize: 13, marginBottom: 4, color: colors.text }, children: approvalReason })), _jsxs("div", { style: { fontSize: 12, color: colors.textMuted, marginBottom: 4 }, children: ["The agent wants to call ", _jsx("code", { children: toolName })] }), _jsx("pre", { style: {
27
85
  fontSize: 11,
28
- background: '#f5f5f5',
86
+ background: colors.codeBg,
29
87
  padding: 8,
30
88
  borderRadius: 4,
31
89
  overflow: 'auto',
32
90
  marginBottom: 8,
91
+ color: colors.text,
33
92
  }, children: JSON.stringify(displayArgs, null, 2) }), _jsxs("div", { style: { display: 'flex', gap: 8 }, children: [_jsx("button", { onClick: () => {
34
93
  setResponded('approved');
94
+ handleApproval(toolCallId, true);
35
95
  addResult?.({ approved: true });
36
96
  }, style: {
37
97
  padding: '4px 12px',
38
98
  fontSize: 12,
39
- border: '1px solid #2e7d32',
99
+ border: `1px solid ${colors.successColor}`,
40
100
  borderRadius: 4,
41
- background: '#e8f5e9',
42
- color: '#2e7d32',
101
+ background: colors.successBg,
102
+ color: colors.successColor,
43
103
  cursor: 'pointer',
44
104
  }, children: "Approve" }), _jsx("button", { onClick: () => {
45
105
  setResponded('denied');
106
+ handleApproval(toolCallId, false);
46
107
  addResult?.({ approved: false });
47
108
  }, style: {
48
109
  padding: '4px 12px',
49
110
  fontSize: 12,
50
- border: '1px solid #c62828',
111
+ border: `1px solid ${colors.errorColor}`,
51
112
  borderRadius: 4,
52
- background: '#ffebee',
53
- color: '#c62828',
113
+ background: colors.errorBg,
114
+ color: colors.errorColor,
54
115
  cursor: 'pointer',
55
116
  }, children: "Deny" })] })] }));
56
117
  }
57
118
  if (isApproval && responded) {
58
119
  return (_jsxs("div", { style: {
59
- border: '1px solid #ddd',
120
+ border: `1px solid ${colors.border}`,
60
121
  borderRadius: 6,
61
122
  padding: 8,
62
123
  margin: '4px 0',
@@ -64,16 +125,17 @@ const ToolCallDisplay = ({ toolName, args, result, status, addResult }) => {
64
125
  alignItems: 'center',
65
126
  gap: 8,
66
127
  fontSize: 13,
128
+ color: colors.text,
67
129
  }, children: [_jsx("span", { style: { fontWeight: 500 }, children: toolName }), _jsx("span", { style: {
68
130
  fontSize: 11,
69
131
  padding: '2px 6px',
70
132
  borderRadius: 3,
71
- background: responded === 'approved' ? '#e8f5e9' : '#ffebee',
72
- color: responded === 'approved' ? '#2e7d32' : '#c62828',
133
+ background: responded === 'approved' ? colors.successBg : colors.errorBg,
134
+ color: responded === 'approved' ? colors.successColor : colors.errorColor,
73
135
  }, children: responded })] }));
74
136
  }
75
137
  return (_jsxs("div", { style: {
76
- border: '1px solid #ddd',
138
+ border: `1px solid ${colors.border}`,
77
139
  borderRadius: 6,
78
140
  padding: 8,
79
141
  margin: '4px 0',
@@ -87,133 +149,184 @@ const ToolCallDisplay = ({ toolName, args, result, status, addResult }) => {
87
149
  width: '100%',
88
150
  padding: 0,
89
151
  fontSize: 13,
90
- }, children: [_jsx("span", { children: expanded ? '\u25BC' : '\u25B6' }), _jsx("span", { style: { fontFamily: 'monospace', fontWeight: 500 }, children: toolName }), status.type === 'running' && (_jsx("span", { style: { fontSize: 11, color: '#888' }, children: "running..." })), status.type === 'complete' && (_jsx("span", { style: {
152
+ color: colors.text,
153
+ }, children: [_jsx("span", { children: expanded ? '\u25BC' : '\u25B6' }), _jsx("span", { style: { fontFamily: 'monospace', fontWeight: 500 }, children: toolName }), status.type === 'running' && (_jsx("span", { style: { fontSize: 11, color: colors.textMuted }, children: "running..." })), status.type === 'error' && (_jsx("span", { style: {
154
+ fontSize: 11,
155
+ padding: '1px 5px',
156
+ borderRadius: 3,
157
+ background: colors.errorBg,
158
+ color: colors.errorColor,
159
+ }, children: "error" })), status.type === 'denied' && (_jsx("span", { style: {
160
+ fontSize: 11,
161
+ padding: '1px 5px',
162
+ borderRadius: 3,
163
+ background: colors.errorBg,
164
+ color: colors.errorColor,
165
+ }, children: "denied" })), status.type === 'completed' && (_jsx("span", { style: {
91
166
  fontSize: 11,
92
167
  padding: '1px 5px',
93
168
  borderRadius: 3,
94
- background: '#e8f5e9',
95
- color: '#2e7d32',
96
- }, children: "done" }))] }), expanded && (_jsxs("div", { style: { marginTop: 8 }, children: [_jsx("div", { style: { fontSize: 12, color: '#888', marginBottom: 2 }, children: "Arguments:" }), _jsx("pre", { style: {
169
+ background: colors.successBg,
170
+ color: colors.successColor,
171
+ }, children: "done" }))] }), expanded && (_jsxs("div", { style: { marginTop: 8 }, children: [_jsx("div", { style: { fontSize: 12, color: colors.textMuted, marginBottom: 2 }, children: "Arguments:" }), _jsx("pre", { style: {
97
172
  fontSize: 11,
98
- background: '#f5f5f5',
173
+ background: colors.codeBg,
99
174
  padding: 8,
100
175
  borderRadius: 4,
101
176
  overflow: 'auto',
102
- }, children: JSON.stringify(displayArgs, null, 2) }), result !== undefined && (_jsxs(_Fragment, { children: [_jsx("div", { style: { fontSize: 12, color: '#888', marginTop: 8, marginBottom: 2 }, children: "Result:" }), _jsx("pre", { style: {
177
+ color: colors.text,
178
+ }, children: JSON.stringify(displayArgs, null, 2) }), result !== undefined && (_jsxs(_Fragment, { children: [_jsx("div", { style: { fontSize: 12, color: colors.textMuted, marginTop: 8, marginBottom: 2 }, children: "Result:" }), _jsx("pre", { style: {
103
179
  fontSize: 11,
104
- background: '#f5f5f5',
180
+ background: colors.codeBg,
105
181
  padding: 8,
106
182
  borderRadius: 4,
107
183
  overflow: 'auto',
184
+ color: colors.text,
108
185
  }, children: typeof result === 'string'
109
186
  ? result
110
187
  : JSON.stringify(result, null, 2) })] }))] }))] }));
111
188
  };
112
- const UserMessage = () => (_jsx("div", { style: {
113
- display: 'flex',
114
- justifyContent: 'flex-end',
115
- width: '100%',
116
- }, children: _jsxs("div", { style: { maxWidth: '80%' }, children: [_jsx("div", { style: {
117
- fontSize: 12,
118
- color: '#888',
119
- marginBottom: 4,
120
- textAlign: 'right',
121
- }, children: "You" }), _jsx("div", { style: {
122
- padding: 12,
123
- borderRadius: 12,
124
- backgroundColor: '#e3f2fd',
125
- }, children: _jsx(MessagePrimitive.Content, { components: {
126
- Text: ({ text }) => (_jsx("span", { style: { fontSize: 14, whiteSpace: 'pre-wrap' }, children: text })),
127
- } }) })] }) }));
128
- const AssistantMessage = () => (_jsx("div", { style: {
129
- display: 'flex',
130
- justifyContent: 'flex-start',
131
- width: '100%',
132
- }, children: _jsxs("div", { style: { maxWidth: '80%' }, children: [_jsx("div", { style: { fontSize: 12, color: '#888', marginBottom: 4 }, children: "Assistant" }), _jsxs("div", { style: {
133
- padding: 12,
189
+ const MarkdownText = ({ text, colors }) => {
190
+ const components = useMemo(() => ({
191
+ p: ({ children }) => (_jsx("p", { style: { margin: '0 0 8px', fontSize: 14, lineHeight: 1.6, color: colors.text }, children: children })),
192
+ strong: ({ children }) => (_jsx("strong", { style: { fontWeight: 600, color: colors.text }, children: children })),
193
+ em: ({ children }) => (_jsx("em", { style: { color: colors.text }, children: children })),
194
+ ul: ({ children }) => (_jsx("ul", { style: { margin: '4px 0 8px', paddingLeft: 20, fontSize: 14, color: colors.text }, children: children })),
195
+ ol: ({ children }) => (_jsx("ol", { style: { margin: '4px 0 8px', paddingLeft: 20, fontSize: 14, color: colors.text }, children: children })),
196
+ li: ({ children }) => (_jsx("li", { style: { marginBottom: 2, lineHeight: 1.6 }, children: children })),
197
+ code: ({ children, className }) => {
198
+ const isBlock = className?.startsWith('language-');
199
+ if (isBlock) {
200
+ return (_jsx("pre", { style: { background: colors.codeBg, padding: 10, borderRadius: 4, overflow: 'auto', margin: '4px 0 8px', fontSize: 12 }, children: _jsx("code", { style: { color: colors.text }, children: children }) }));
201
+ }
202
+ return (_jsx("code", { style: { background: colors.codeBg, padding: '1px 4px', borderRadius: 3, fontSize: 13, color: colors.text }, children: children }));
203
+ },
204
+ pre: ({ children }) => _jsx(_Fragment, { children: children }),
205
+ h1: ({ children }) => _jsx("h3", { style: { margin: '8px 0 4px', fontSize: 16, fontWeight: 600, color: colors.text }, children: children }),
206
+ h2: ({ children }) => _jsx("h4", { style: { margin: '8px 0 4px', fontSize: 15, fontWeight: 600, color: colors.text }, children: children }),
207
+ h3: ({ children }) => _jsx("h5", { style: { margin: '8px 0 4px', fontSize: 14, fontWeight: 600, color: colors.text }, children: children }),
208
+ a: ({ href, children }) => (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", style: { color: colors.textMuted, textDecoration: 'underline' }, children: children })),
209
+ }), [colors]);
210
+ return _jsx(Markdown, { components: components, children: text });
211
+ };
212
+ const UserMessage = () => {
213
+ const colors = useContext(ColorsContext);
214
+ return (_jsx("div", { style: {
215
+ display: 'flex',
216
+ justifyContent: 'flex-end',
217
+ width: '100%',
218
+ }, children: _jsxs("div", { style: { maxWidth: '80%' }, children: [_jsx("div", { style: {
219
+ fontSize: 12,
220
+ color: colors.textMuted,
221
+ marginBottom: 4,
222
+ textAlign: 'right',
223
+ }, children: "You" }), _jsx("div", { style: {
224
+ padding: 12,
225
+ borderRadius: 12,
226
+ backgroundColor: colors.userBubble,
227
+ }, children: _jsx(MessagePrimitive.Content, { components: {
228
+ Text: ({ text }) => (_jsx("span", { style: { fontSize: 14, whiteSpace: 'pre-wrap', color: colors.text }, children: text })),
229
+ } }) })] }) }));
230
+ };
231
+ const AssistantMessage = () => {
232
+ const colors = useContext(ColorsContext);
233
+ return (_jsx("div", { style: {
234
+ display: 'flex',
235
+ justifyContent: 'flex-start',
236
+ width: '100%',
237
+ }, children: _jsxs("div", { style: { maxWidth: '80%' }, children: [_jsx("div", { style: { fontSize: 12, color: colors.textMuted, marginBottom: 4 }, children: "Assistant" }), _jsxs("div", { style: {
238
+ padding: 12,
239
+ borderRadius: 12,
240
+ backgroundColor: colors.assistantBubble,
241
+ }, children: [_jsx(MessagePrimitive.Content, { components: {
242
+ Text: ({ text }) => (_jsx(MarkdownText, { text: text, colors: colors })),
243
+ tools: {
244
+ Fallback: (props) => (_jsx(ToolCallDisplay, { toolCallId: props.toolCallId, toolName: props.toolName, args: props.args, result: props.result, status: resolvePikkuToolStatus(props.status, props.result), addResult: props.addResult })),
245
+ },
246
+ } }), _jsx(MessagePrimitive.If, { last: true, children: _jsx(ThreadPrimitive.If, { running: true, children: _jsx("div", { style: {
247
+ display: 'flex',
248
+ alignItems: 'center',
249
+ gap: 6,
250
+ marginTop: 8,
251
+ fontSize: 13,
252
+ color: colors.textMuted,
253
+ }, children: "Thinking..." }) }) })] })] }) }));
254
+ };
255
+ const PikkuComposer = ({ disabled, }) => {
256
+ const colors = useContext(ColorsContext);
257
+ return (_jsx("div", { style: { padding: '8px 0 16px' }, children: _jsx(ComposerPrimitive.Root, { children: _jsxs("div", { style: {
258
+ border: `1px solid ${colors.border}`,
134
259
  borderRadius: 12,
135
- backgroundColor: '#f5f5f5',
136
- }, children: [_jsx(MessagePrimitive.Content, { components: {
137
- Text: ({ text }) => (_jsx("span", { style: { fontSize: 14, whiteSpace: 'pre-wrap' }, children: text })),
138
- tools: {
139
- Fallback: (props) => (_jsx(ToolCallDisplay, { toolName: props.toolName, args: props.args, result: props.result, status: props.status, addResult: props.addResult })),
140
- },
141
- } }), _jsx(MessagePrimitive.If, { last: true, children: _jsx(ThreadPrimitive.If, { running: true, children: _jsx("div", { style: {
142
- display: 'flex',
143
- alignItems: 'center',
144
- gap: 6,
145
- marginTop: 8,
146
- fontSize: 13,
147
- color: '#888',
148
- }, children: "Thinking..." }) }) })] })] }) }));
149
- const PikkuComposer = () => (_jsx("div", { style: { padding: '8px 0 16px' }, children: _jsx(ComposerPrimitive.Root, { children: _jsxs("div", { style: {
150
- border: '1px solid #ddd',
151
- borderRadius: 12,
152
- overflow: 'hidden',
153
- display: 'flex',
154
- alignItems: 'flex-end',
155
- padding: '6px 12px',
156
- gap: 8,
157
- }, children: [_jsx(ComposerPrimitive.Input, { placeholder: "Message...", rows: 2, style: {
158
- flex: 1,
159
- border: 'none',
160
- outline: 'none',
161
- resize: 'none',
162
- fontSize: 14,
163
- fontFamily: 'inherit',
164
- padding: '4px 0',
165
- background: 'transparent',
166
- } }), _jsx(ComposerPrimitive.Send, { style: {
167
- width: 28,
168
- height: 28,
169
- borderRadius: '50%',
170
- border: 'none',
171
- background: '#1976d2',
172
- color: '#fff',
173
- cursor: 'pointer',
174
- display: 'flex',
175
- alignItems: 'center',
176
- justifyContent: 'center',
177
- flexShrink: 0,
178
- marginBottom: 2,
179
- fontSize: 14,
180
- }, children: "\u25B6" })] }) }) }));
181
- export function PikkuAgentChat(props) {
182
- const { emptyMessage, ...runtimeOptions } = props;
183
- const runtime = usePikkuAgentRuntime(runtimeOptions);
184
- return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx("div", { style: {
185
- height: '100%',
186
- display: 'flex',
187
- flexDirection: 'column',
188
- }, children: _jsxs(ThreadPrimitive.Root, { style: {
260
+ overflow: 'hidden',
189
261
  display: 'flex',
190
- flexDirection: 'column',
191
- flex: 1,
192
- minHeight: 0,
193
- }, children: [_jsx(ThreadPrimitive.Viewport, { style: {
262
+ alignItems: 'flex-end',
263
+ padding: '6px 12px',
264
+ gap: 8,
265
+ ...(disabled ? { opacity: 0.5, pointerEvents: 'none' } : {}),
266
+ }, children: [_jsx(ComposerPrimitive.Input, { placeholder: disabled ? 'Respond to approval request above...' : 'Message...', rows: 2, disabled: disabled, style: {
194
267
  flex: 1,
195
- minHeight: 0,
196
- overflowY: 'auto',
197
- }, children: _jsxs("div", { style: {
198
- maxWidth: 768,
199
- margin: '0 auto',
200
- padding: 16,
268
+ border: 'none',
269
+ outline: 'none',
270
+ resize: 'none',
271
+ fontSize: 14,
272
+ fontFamily: 'inherit',
273
+ padding: '4px 0',
274
+ background: colors.inputBg,
275
+ color: colors.text,
276
+ } }), _jsx(ComposerPrimitive.Send, { disabled: disabled, style: {
277
+ width: 28,
278
+ height: 28,
279
+ borderRadius: '50%',
280
+ border: 'none',
281
+ background: disabled ? colors.textMuted : colors.sendBg,
282
+ color: colors.sendColor,
283
+ cursor: disabled ? 'not-allowed' : 'pointer',
284
+ display: 'flex',
285
+ alignItems: 'center',
286
+ justifyContent: 'center',
287
+ flexShrink: 0,
288
+ marginBottom: 2,
289
+ fontSize: 14,
290
+ }, children: "\u25B6" })] }) }) }));
291
+ };
292
+ export function PikkuAgentChat(props) {
293
+ const { emptyMessage, hideToolCalls, dark, ...runtimeOptions } = props;
294
+ const { runtime, isAwaitingApproval, pendingApprovals, handleApproval } = usePikkuAgentRuntime(runtimeOptions);
295
+ const colors = dark ? darkColors : lightColors;
296
+ return (_jsx(ColorsContext.Provider, { value: colors, children: _jsx(PikkuApprovalContext.Provider, { value: { pendingApprovals, handleApproval }, children: _jsx(HideToolCallsContext.Provider, { value: hideToolCalls, children: _jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx("div", { style: {
297
+ height: '100%',
298
+ display: 'flex',
299
+ flexDirection: 'column',
300
+ background: colors.bg,
301
+ }, children: _jsxs(ThreadPrimitive.Root, { style: {
201
302
  display: 'flex',
202
303
  flexDirection: 'column',
203
- gap: 16,
204
- }, children: [_jsx(ThreadPrimitive.Empty, { children: _jsx("div", { style: {
304
+ flex: 1,
305
+ minHeight: 0,
306
+ }, children: [_jsx(ThreadPrimitive.Viewport, { style: {
307
+ flex: 1,
308
+ minHeight: 0,
309
+ overflowY: 'auto',
310
+ }, children: _jsxs("div", { style: {
311
+ maxWidth: 768,
312
+ margin: '0 auto',
313
+ padding: 16,
205
314
  display: 'flex',
206
- alignItems: 'center',
207
- justifyContent: 'center',
208
- minHeight: 300,
209
- color: '#888',
210
- textAlign: 'center',
211
- fontSize: 14,
212
- }, children: emptyMessage ??
213
- (props.threadId
214
- ? 'Send a message to start the conversation.'
215
- : 'Start a new conversation.') }) }), _jsx(ThreadPrimitive.Messages, { components: {
216
- UserMessage,
217
- AssistantMessage,
218
- } })] }) }), _jsx("div", { style: { maxWidth: 768, margin: '0 auto', width: '100%', padding: '0 16px' }, children: _jsx(PikkuComposer, {}) })] }) }) }));
315
+ flexDirection: 'column',
316
+ gap: 16,
317
+ }, children: [_jsx(ThreadPrimitive.Empty, { children: _jsx("div", { style: {
318
+ display: 'flex',
319
+ alignItems: 'center',
320
+ justifyContent: 'center',
321
+ minHeight: 300,
322
+ color: colors.textMuted,
323
+ textAlign: 'center',
324
+ fontSize: 14,
325
+ }, children: emptyMessage ??
326
+ (props.threadId
327
+ ? 'Send a message to start the conversation.'
328
+ : 'Start a new conversation.') }) }), _jsx(ThreadPrimitive.Messages, { components: {
329
+ UserMessage,
330
+ AssistantMessage,
331
+ } })] }) }), _jsx("div", { style: { maxWidth: 768, margin: '0 auto', width: '100%', padding: '0 16px' }, children: _jsx(PikkuComposer, { disabled: isAwaitingApproval }) })] }) }) }) }) }) }));
219
332
  }
@@ -1,13 +1,47 @@
1
+ import { type ThreadMessageLike } from '@assistant-ui/react';
1
2
  export interface PikkuAgentRuntimeOptions {
2
3
  api: string;
3
- threadId?: string | null;
4
+ agentName: string;
5
+ threadId: string;
6
+ resourceId: string;
4
7
  initialMessages?: any[];
5
- onThreadCreated?: (id: string) => void;
6
8
  onFinish?: () => void;
7
- onApprovalRequest?: (data: {
8
- toolCallId: string;
9
- }) => void;
10
9
  credentials?: RequestCredentials;
11
10
  headers?: Record<string, string>;
11
+ model?: string;
12
+ temperature?: number;
12
13
  }
13
- export declare function usePikkuAgentRuntime(options: PikkuAgentRuntimeOptions): import("@assistant-ui/react").AssistantRuntime;
14
+ export interface PendingApproval {
15
+ toolCallId: string;
16
+ toolName: string;
17
+ args: unknown;
18
+ reason?: string;
19
+ runId: string;
20
+ }
21
+ export interface PikkuApprovalContextValue {
22
+ pendingApprovals: PendingApproval[];
23
+ handleApproval: (toolCallId: string, approved: boolean) => void;
24
+ }
25
+ export declare const PikkuApprovalContext: import("react").Context<PikkuApprovalContextValue>;
26
+ export declare const usePikkuApproval: () => PikkuApprovalContextValue;
27
+ export declare function isDeniedResult(result: unknown): boolean;
28
+ export type PikkuToolStatusType = 'running' | 'requires-action' | 'completed' | 'denied' | 'error';
29
+ export type PikkuToolStatus = {
30
+ type: PikkuToolStatusType;
31
+ };
32
+ export declare function resolvePikkuToolStatus(status: {
33
+ type: string;
34
+ }, result?: unknown): PikkuToolStatus;
35
+ export declare const convertDbMessages: (dbMessages: any[]) => ThreadMessageLike[];
36
+ export declare function usePikkuAgentRuntime(options: PikkuAgentRuntimeOptions): {
37
+ runtime: import("@assistant-ui/react").AssistantRuntime;
38
+ pendingApprovals: PendingApproval[];
39
+ isAwaitingApproval: boolean;
40
+ handleApproval: (toolCallId: string, approved: boolean) => void;
41
+ };
42
+ export declare function usePikkuAgentNonStreamingRuntime(options: PikkuAgentRuntimeOptions): {
43
+ runtime: import("@assistant-ui/react").AssistantRuntime;
44
+ pendingApprovals: PendingApproval[];
45
+ isAwaitingApproval: boolean;
46
+ handleApproval: (toolCallId: string, approved: boolean) => void;
47
+ };