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