@journeyrewards/hive-vercel 1.0.0 → 1.2.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/dist/index.d.mts +59 -2
- package/dist/index.d.ts +59 -2
- package/dist/index.js +139 -7
- package/dist/index.mjs +134 -7
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { JourneyHiveConfig, CreateResponseParams, Response, Conversation, Message, Agent } from '@journeyrewards/hive-sdk';
|
|
3
|
+
import { JourneyHiveConfig, CreateResponseParams, Response, Conversation, Message, ListResponse, UpdateConversationParams, Agent, ContentPart } from '@journeyrewards/hive-sdk';
|
|
4
4
|
|
|
5
5
|
interface JourneyHiveClient {
|
|
6
6
|
config: JourneyHiveConfig;
|
|
@@ -15,6 +15,13 @@ interface JourneyHiveClient {
|
|
|
15
15
|
messages(id: string): Promise<{
|
|
16
16
|
data: Message[];
|
|
17
17
|
}>;
|
|
18
|
+
list(params?: {
|
|
19
|
+
agent_id?: string;
|
|
20
|
+
status?: string;
|
|
21
|
+
limit?: number;
|
|
22
|
+
cursor?: string;
|
|
23
|
+
}): Promise<ListResponse<Conversation>>;
|
|
24
|
+
update(id: string, params: UpdateConversationParams): Promise<Conversation>;
|
|
18
25
|
};
|
|
19
26
|
agents: {
|
|
20
27
|
get(id: string): Promise<Agent>;
|
|
@@ -61,6 +68,22 @@ interface UseAgentsReturn {
|
|
|
61
68
|
error: Error | null;
|
|
62
69
|
}
|
|
63
70
|
declare function useAgents(): UseAgentsReturn;
|
|
71
|
+
interface UseConversationsReturn {
|
|
72
|
+
conversations: Conversation[];
|
|
73
|
+
isLoading: boolean;
|
|
74
|
+
error: Error | null;
|
|
75
|
+
refetch: () => void;
|
|
76
|
+
}
|
|
77
|
+
declare function useConversations(agentId: string): UseConversationsReturn;
|
|
78
|
+
interface UseConversationActionsReturn {
|
|
79
|
+
star: (id: string, starred: boolean) => Promise<Conversation>;
|
|
80
|
+
rename: (id: string, title: string) => Promise<Conversation>;
|
|
81
|
+
update: (id: string, params: UpdateConversationParams) => Promise<Conversation>;
|
|
82
|
+
isUpdating: boolean;
|
|
83
|
+
error: Error | null;
|
|
84
|
+
}
|
|
85
|
+
declare function useConversationActions(): UseConversationActionsReturn;
|
|
86
|
+
declare function useChartUrl(chartId: string): string;
|
|
64
87
|
|
|
65
88
|
interface ResponseStreamProps {
|
|
66
89
|
agentId: string;
|
|
@@ -85,6 +108,40 @@ declare function MessageBubble({ role, content, timestamp }: MessageBubbleProps)
|
|
|
85
108
|
marginBottom: string;
|
|
86
109
|
};
|
|
87
110
|
}, HTMLElement>;
|
|
111
|
+
interface ChartEmbedProps {
|
|
112
|
+
embedUrl?: string;
|
|
113
|
+
imageUrl?: string;
|
|
114
|
+
title?: string;
|
|
115
|
+
chartId?: string;
|
|
116
|
+
width?: string;
|
|
117
|
+
height?: string;
|
|
118
|
+
className?: string;
|
|
119
|
+
}
|
|
120
|
+
declare function ChartEmbed({ embedUrl, imageUrl, title, chartId, width, height, className }: ChartEmbedProps): react.DetailedReactHTMLElement<{
|
|
121
|
+
className: string;
|
|
122
|
+
style: {
|
|
123
|
+
margin: string;
|
|
124
|
+
borderRadius: string;
|
|
125
|
+
overflow: string;
|
|
126
|
+
border: string;
|
|
127
|
+
maxWidth: string;
|
|
128
|
+
};
|
|
129
|
+
}, HTMLElement> | null;
|
|
130
|
+
interface RichMessageProps {
|
|
131
|
+
role: string;
|
|
132
|
+
content: ContentPart[];
|
|
133
|
+
timestamp?: number;
|
|
134
|
+
className?: string;
|
|
135
|
+
}
|
|
136
|
+
declare function RichMessage({ role, content, timestamp, className }: RichMessageProps): react.DetailedReactHTMLElement<{
|
|
137
|
+
className: string;
|
|
138
|
+
style: {
|
|
139
|
+
display: "flex";
|
|
140
|
+
flexDirection: "column";
|
|
141
|
+
alignItems: "flex-end" | "flex-start";
|
|
142
|
+
marginBottom: string;
|
|
143
|
+
};
|
|
144
|
+
}, HTMLElement>;
|
|
88
145
|
interface ConversationViewProps {
|
|
89
146
|
conversationId: string;
|
|
90
147
|
agentId?: string;
|
|
@@ -111,4 +168,4 @@ declare function AgentStatus({ agent }: AgentStatusProps): react.DetailedReactHT
|
|
|
111
168
|
};
|
|
112
169
|
}, HTMLElement>;
|
|
113
170
|
|
|
114
|
-
export { AgentStatus, ConversationView, JourneyHiveProvider, MessageBubble, ResponseStream, useAgent, useAgents, useConversation, useJourneyHive, useResponse };
|
|
171
|
+
export { AgentStatus, ChartEmbed, ConversationView, JourneyHiveProvider, MessageBubble, ResponseStream, RichMessage, useAgent, useAgents, useChartUrl, useConversation, useConversationActions, useConversations, useJourneyHive, useResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { JourneyHiveConfig, CreateResponseParams, Response, Conversation, Message, Agent } from '@journeyrewards/hive-sdk';
|
|
3
|
+
import { JourneyHiveConfig, CreateResponseParams, Response, Conversation, Message, ListResponse, UpdateConversationParams, Agent, ContentPart } from '@journeyrewards/hive-sdk';
|
|
4
4
|
|
|
5
5
|
interface JourneyHiveClient {
|
|
6
6
|
config: JourneyHiveConfig;
|
|
@@ -15,6 +15,13 @@ interface JourneyHiveClient {
|
|
|
15
15
|
messages(id: string): Promise<{
|
|
16
16
|
data: Message[];
|
|
17
17
|
}>;
|
|
18
|
+
list(params?: {
|
|
19
|
+
agent_id?: string;
|
|
20
|
+
status?: string;
|
|
21
|
+
limit?: number;
|
|
22
|
+
cursor?: string;
|
|
23
|
+
}): Promise<ListResponse<Conversation>>;
|
|
24
|
+
update(id: string, params: UpdateConversationParams): Promise<Conversation>;
|
|
18
25
|
};
|
|
19
26
|
agents: {
|
|
20
27
|
get(id: string): Promise<Agent>;
|
|
@@ -61,6 +68,22 @@ interface UseAgentsReturn {
|
|
|
61
68
|
error: Error | null;
|
|
62
69
|
}
|
|
63
70
|
declare function useAgents(): UseAgentsReturn;
|
|
71
|
+
interface UseConversationsReturn {
|
|
72
|
+
conversations: Conversation[];
|
|
73
|
+
isLoading: boolean;
|
|
74
|
+
error: Error | null;
|
|
75
|
+
refetch: () => void;
|
|
76
|
+
}
|
|
77
|
+
declare function useConversations(agentId: string): UseConversationsReturn;
|
|
78
|
+
interface UseConversationActionsReturn {
|
|
79
|
+
star: (id: string, starred: boolean) => Promise<Conversation>;
|
|
80
|
+
rename: (id: string, title: string) => Promise<Conversation>;
|
|
81
|
+
update: (id: string, params: UpdateConversationParams) => Promise<Conversation>;
|
|
82
|
+
isUpdating: boolean;
|
|
83
|
+
error: Error | null;
|
|
84
|
+
}
|
|
85
|
+
declare function useConversationActions(): UseConversationActionsReturn;
|
|
86
|
+
declare function useChartUrl(chartId: string): string;
|
|
64
87
|
|
|
65
88
|
interface ResponseStreamProps {
|
|
66
89
|
agentId: string;
|
|
@@ -85,6 +108,40 @@ declare function MessageBubble({ role, content, timestamp }: MessageBubbleProps)
|
|
|
85
108
|
marginBottom: string;
|
|
86
109
|
};
|
|
87
110
|
}, HTMLElement>;
|
|
111
|
+
interface ChartEmbedProps {
|
|
112
|
+
embedUrl?: string;
|
|
113
|
+
imageUrl?: string;
|
|
114
|
+
title?: string;
|
|
115
|
+
chartId?: string;
|
|
116
|
+
width?: string;
|
|
117
|
+
height?: string;
|
|
118
|
+
className?: string;
|
|
119
|
+
}
|
|
120
|
+
declare function ChartEmbed({ embedUrl, imageUrl, title, chartId, width, height, className }: ChartEmbedProps): react.DetailedReactHTMLElement<{
|
|
121
|
+
className: string;
|
|
122
|
+
style: {
|
|
123
|
+
margin: string;
|
|
124
|
+
borderRadius: string;
|
|
125
|
+
overflow: string;
|
|
126
|
+
border: string;
|
|
127
|
+
maxWidth: string;
|
|
128
|
+
};
|
|
129
|
+
}, HTMLElement> | null;
|
|
130
|
+
interface RichMessageProps {
|
|
131
|
+
role: string;
|
|
132
|
+
content: ContentPart[];
|
|
133
|
+
timestamp?: number;
|
|
134
|
+
className?: string;
|
|
135
|
+
}
|
|
136
|
+
declare function RichMessage({ role, content, timestamp, className }: RichMessageProps): react.DetailedReactHTMLElement<{
|
|
137
|
+
className: string;
|
|
138
|
+
style: {
|
|
139
|
+
display: "flex";
|
|
140
|
+
flexDirection: "column";
|
|
141
|
+
alignItems: "flex-end" | "flex-start";
|
|
142
|
+
marginBottom: string;
|
|
143
|
+
};
|
|
144
|
+
}, HTMLElement>;
|
|
88
145
|
interface ConversationViewProps {
|
|
89
146
|
conversationId: string;
|
|
90
147
|
agentId?: string;
|
|
@@ -111,4 +168,4 @@ declare function AgentStatus({ agent }: AgentStatusProps): react.DetailedReactHT
|
|
|
111
168
|
};
|
|
112
169
|
}, HTMLElement>;
|
|
113
170
|
|
|
114
|
-
export { AgentStatus, ConversationView, JourneyHiveProvider, MessageBubble, ResponseStream, useAgent, useAgents, useConversation, useJourneyHive, useResponse };
|
|
171
|
+
export { AgentStatus, ChartEmbed, ConversationView, JourneyHiveProvider, MessageBubble, ResponseStream, RichMessage, useAgent, useAgents, useChartUrl, useConversation, useConversationActions, useConversations, useJourneyHive, useResponse };
|
package/dist/index.js
CHANGED
|
@@ -21,13 +21,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
AgentStatus: () => AgentStatus,
|
|
24
|
+
ChartEmbed: () => ChartEmbed,
|
|
24
25
|
ConversationView: () => ConversationView,
|
|
25
26
|
JourneyHiveProvider: () => JourneyHiveProvider,
|
|
26
27
|
MessageBubble: () => MessageBubble,
|
|
27
28
|
ResponseStream: () => ResponseStream,
|
|
29
|
+
RichMessage: () => RichMessage,
|
|
28
30
|
useAgent: () => useAgent,
|
|
29
31
|
useAgents: () => useAgents,
|
|
32
|
+
useChartUrl: () => useChartUrl,
|
|
30
33
|
useConversation: () => useConversation,
|
|
34
|
+
useConversationActions: () => useConversationActions,
|
|
35
|
+
useConversations: () => useConversations,
|
|
31
36
|
useJourneyHive: () => useJourneyHive,
|
|
32
37
|
useResponse: () => useResponse
|
|
33
38
|
});
|
|
@@ -100,7 +105,17 @@ function createClient(config) {
|
|
|
100
105
|
},
|
|
101
106
|
conversations: {
|
|
102
107
|
get: (id) => request("GET", `/v1/conversations/${id}`),
|
|
103
|
-
messages: (id) => request("GET", `/v1/conversations/${id}/messages`)
|
|
108
|
+
messages: (id) => request("GET", `/v1/conversations/${id}/messages`),
|
|
109
|
+
list: (params) => {
|
|
110
|
+
const searchParams = new URLSearchParams();
|
|
111
|
+
if (params?.agent_id) searchParams.set("agent_id", params.agent_id);
|
|
112
|
+
if (params?.status) searchParams.set("status", params.status);
|
|
113
|
+
if (params?.limit) searchParams.set("limit", String(params.limit));
|
|
114
|
+
if (params?.cursor) searchParams.set("cursor", params.cursor);
|
|
115
|
+
const query = searchParams.toString();
|
|
116
|
+
return request("GET", `/v1/conversations${query ? `?${query}` : ""}`);
|
|
117
|
+
},
|
|
118
|
+
update: (id, params) => request("PATCH", `/v1/conversations/${id}`, params)
|
|
104
119
|
},
|
|
105
120
|
agents: {
|
|
106
121
|
get: (id) => request("GET", `/v1/agents/${id}`),
|
|
@@ -262,6 +277,57 @@ function useAgents() {
|
|
|
262
277
|
}, [client]);
|
|
263
278
|
return { agents, isLoading, error };
|
|
264
279
|
}
|
|
280
|
+
function useConversations(agentId) {
|
|
281
|
+
const client = useJourneyHive();
|
|
282
|
+
const [conversations, setConversations] = (0, import_react.useState)([]);
|
|
283
|
+
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
284
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
285
|
+
const fetchConversations = (0, import_react.useCallback)(() => {
|
|
286
|
+
if (!agentId) return;
|
|
287
|
+
setIsLoading(true);
|
|
288
|
+
client.conversations.list({ agent_id: agentId }).then((result) => setConversations(result.data)).catch((err) => setError(err instanceof Error ? err : new Error(String(err)))).finally(() => setIsLoading(false));
|
|
289
|
+
}, [agentId, client]);
|
|
290
|
+
(0, import_react.useEffect)(() => {
|
|
291
|
+
fetchConversations();
|
|
292
|
+
}, [fetchConversations]);
|
|
293
|
+
return { conversations, isLoading, error, refetch: fetchConversations };
|
|
294
|
+
}
|
|
295
|
+
function useConversationActions() {
|
|
296
|
+
const client = useJourneyHive();
|
|
297
|
+
const [isUpdating, setIsUpdating] = (0, import_react.useState)(false);
|
|
298
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
299
|
+
const update = (0, import_react.useCallback)(
|
|
300
|
+
async (id, params) => {
|
|
301
|
+
setIsUpdating(true);
|
|
302
|
+
setError(null);
|
|
303
|
+
try {
|
|
304
|
+
const result = await client.conversations.update(id, params);
|
|
305
|
+
return result;
|
|
306
|
+
} catch (err) {
|
|
307
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
308
|
+
setError(error2);
|
|
309
|
+
throw error2;
|
|
310
|
+
} finally {
|
|
311
|
+
setIsUpdating(false);
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
[client]
|
|
315
|
+
);
|
|
316
|
+
const star = (0, import_react.useCallback)(
|
|
317
|
+
(id, starred) => update(id, { starred }),
|
|
318
|
+
[update]
|
|
319
|
+
);
|
|
320
|
+
const rename = (0, import_react.useCallback)(
|
|
321
|
+
(id, title) => update(id, { title }),
|
|
322
|
+
[update]
|
|
323
|
+
);
|
|
324
|
+
return { star, rename, update, isUpdating, error };
|
|
325
|
+
}
|
|
326
|
+
function useChartUrl(chartId) {
|
|
327
|
+
const client = useJourneyHive();
|
|
328
|
+
const baseUrl = client.config.baseUrl || "https://journey-hive.replit.app";
|
|
329
|
+
return `${baseUrl}/charts/${chartId}.png`;
|
|
330
|
+
}
|
|
265
331
|
|
|
266
332
|
// src/components.tsx
|
|
267
333
|
var import_react2 = require("react");
|
|
@@ -331,6 +397,68 @@ function MessageBubble({ role, content, timestamp }) {
|
|
|
331
397
|
) : null
|
|
332
398
|
);
|
|
333
399
|
}
|
|
400
|
+
function ChartEmbed({ embedUrl, imageUrl, title, chartId, width, height, className }) {
|
|
401
|
+
const containerStyle = {
|
|
402
|
+
margin: "8px 0 16px",
|
|
403
|
+
borderRadius: "12px",
|
|
404
|
+
overflow: "hidden",
|
|
405
|
+
border: "1px solid #e2e2ea",
|
|
406
|
+
maxWidth: width || "640px"
|
|
407
|
+
};
|
|
408
|
+
if (embedUrl) {
|
|
409
|
+
return (0, import_react2.createElement)(
|
|
410
|
+
"div",
|
|
411
|
+
{ className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
|
|
412
|
+
(0, import_react2.createElement)("iframe", {
|
|
413
|
+
src: embedUrl,
|
|
414
|
+
title: title || "Chart",
|
|
415
|
+
style: { width: "100%", height: height || "400px", border: "none" },
|
|
416
|
+
loading: "lazy"
|
|
417
|
+
})
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
if (imageUrl) {
|
|
421
|
+
return (0, import_react2.createElement)(
|
|
422
|
+
"div",
|
|
423
|
+
{ className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
|
|
424
|
+
(0, import_react2.createElement)("img", {
|
|
425
|
+
src: imageUrl,
|
|
426
|
+
alt: title || "Chart",
|
|
427
|
+
style: { width: "100%", height: "auto", display: "block" },
|
|
428
|
+
loading: "lazy"
|
|
429
|
+
})
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
function RichMessage({ role, content, timestamp, className }) {
|
|
435
|
+
const isUser = role === "user";
|
|
436
|
+
const textParts = content.filter((c) => c.type === "output_text");
|
|
437
|
+
const chartParts = content.filter((c) => c.type === "output_chart");
|
|
438
|
+
const text = textParts.map((c) => c.text).join("");
|
|
439
|
+
return (0, import_react2.createElement)(
|
|
440
|
+
"div",
|
|
441
|
+
{
|
|
442
|
+
className: `jh-rich-message ${className || ""}`.trim(),
|
|
443
|
+
style: {
|
|
444
|
+
display: "flex",
|
|
445
|
+
flexDirection: "column",
|
|
446
|
+
alignItems: isUser ? "flex-end" : "flex-start",
|
|
447
|
+
marginBottom: "8px"
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
text ? (0, import_react2.createElement)(MessageBubble, { role, content: text, timestamp }) : null,
|
|
451
|
+
...chartParts.map(
|
|
452
|
+
(chart) => (0, import_react2.createElement)(ChartEmbed, {
|
|
453
|
+
key: chart.chart_id,
|
|
454
|
+
embedUrl: chart.embed_url,
|
|
455
|
+
imageUrl: chart.image_url,
|
|
456
|
+
title: chart.title,
|
|
457
|
+
chartId: chart.chart_id
|
|
458
|
+
})
|
|
459
|
+
)
|
|
460
|
+
);
|
|
461
|
+
}
|
|
334
462
|
function ConversationView({ conversationId, agentId, className }) {
|
|
335
463
|
const { messages, isLoading, error, sendMessage } = useConversation(conversationId);
|
|
336
464
|
const [inputValue, setInputValue] = (0, import_react2.useState)("");
|
|
@@ -362,15 +490,14 @@ function ConversationView({ conversationId, agentId, className }) {
|
|
|
362
490
|
className: "jh-messages",
|
|
363
491
|
style: { flex: 1, overflowY: "auto", padding: "16px" }
|
|
364
492
|
},
|
|
365
|
-
isLoading ? (0, import_react2.createElement)("div", { className: "jh-loading" }, "Loading messages...") : messages.map(
|
|
366
|
-
|
|
367
|
-
return (0, import_react2.createElement)(MessageBubble, {
|
|
493
|
+
isLoading ? (0, import_react2.createElement)("div", { className: "jh-loading" }, "Loading messages...") : messages.map(
|
|
494
|
+
(msg) => (0, import_react2.createElement)(RichMessage, {
|
|
368
495
|
key: msg.id,
|
|
369
496
|
role: msg.role,
|
|
370
|
-
content:
|
|
497
|
+
content: msg.content || [],
|
|
371
498
|
timestamp: msg.created_at
|
|
372
|
-
})
|
|
373
|
-
|
|
499
|
+
})
|
|
500
|
+
),
|
|
374
501
|
(0, import_react2.createElement)("div", { ref: messagesEndRef })
|
|
375
502
|
),
|
|
376
503
|
(0, import_react2.createElement)(
|
|
@@ -439,13 +566,18 @@ function AgentStatus({ agent }) {
|
|
|
439
566
|
// Annotate the CommonJS export names for ESM import in node:
|
|
440
567
|
0 && (module.exports = {
|
|
441
568
|
AgentStatus,
|
|
569
|
+
ChartEmbed,
|
|
442
570
|
ConversationView,
|
|
443
571
|
JourneyHiveProvider,
|
|
444
572
|
MessageBubble,
|
|
445
573
|
ResponseStream,
|
|
574
|
+
RichMessage,
|
|
446
575
|
useAgent,
|
|
447
576
|
useAgents,
|
|
577
|
+
useChartUrl,
|
|
448
578
|
useConversation,
|
|
579
|
+
useConversationActions,
|
|
580
|
+
useConversations,
|
|
449
581
|
useJourneyHive,
|
|
450
582
|
useResponse
|
|
451
583
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -73,7 +73,17 @@ function createClient(config) {
|
|
|
73
73
|
},
|
|
74
74
|
conversations: {
|
|
75
75
|
get: (id) => request("GET", `/v1/conversations/${id}`),
|
|
76
|
-
messages: (id) => request("GET", `/v1/conversations/${id}/messages`)
|
|
76
|
+
messages: (id) => request("GET", `/v1/conversations/${id}/messages`),
|
|
77
|
+
list: (params) => {
|
|
78
|
+
const searchParams = new URLSearchParams();
|
|
79
|
+
if (params?.agent_id) searchParams.set("agent_id", params.agent_id);
|
|
80
|
+
if (params?.status) searchParams.set("status", params.status);
|
|
81
|
+
if (params?.limit) searchParams.set("limit", String(params.limit));
|
|
82
|
+
if (params?.cursor) searchParams.set("cursor", params.cursor);
|
|
83
|
+
const query = searchParams.toString();
|
|
84
|
+
return request("GET", `/v1/conversations${query ? `?${query}` : ""}`);
|
|
85
|
+
},
|
|
86
|
+
update: (id, params) => request("PATCH", `/v1/conversations/${id}`, params)
|
|
77
87
|
},
|
|
78
88
|
agents: {
|
|
79
89
|
get: (id) => request("GET", `/v1/agents/${id}`),
|
|
@@ -235,6 +245,57 @@ function useAgents() {
|
|
|
235
245
|
}, [client]);
|
|
236
246
|
return { agents, isLoading, error };
|
|
237
247
|
}
|
|
248
|
+
function useConversations(agentId) {
|
|
249
|
+
const client = useJourneyHive();
|
|
250
|
+
const [conversations, setConversations] = useState([]);
|
|
251
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
252
|
+
const [error, setError] = useState(null);
|
|
253
|
+
const fetchConversations = useCallback(() => {
|
|
254
|
+
if (!agentId) return;
|
|
255
|
+
setIsLoading(true);
|
|
256
|
+
client.conversations.list({ agent_id: agentId }).then((result) => setConversations(result.data)).catch((err) => setError(err instanceof Error ? err : new Error(String(err)))).finally(() => setIsLoading(false));
|
|
257
|
+
}, [agentId, client]);
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
fetchConversations();
|
|
260
|
+
}, [fetchConversations]);
|
|
261
|
+
return { conversations, isLoading, error, refetch: fetchConversations };
|
|
262
|
+
}
|
|
263
|
+
function useConversationActions() {
|
|
264
|
+
const client = useJourneyHive();
|
|
265
|
+
const [isUpdating, setIsUpdating] = useState(false);
|
|
266
|
+
const [error, setError] = useState(null);
|
|
267
|
+
const update = useCallback(
|
|
268
|
+
async (id, params) => {
|
|
269
|
+
setIsUpdating(true);
|
|
270
|
+
setError(null);
|
|
271
|
+
try {
|
|
272
|
+
const result = await client.conversations.update(id, params);
|
|
273
|
+
return result;
|
|
274
|
+
} catch (err) {
|
|
275
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
276
|
+
setError(error2);
|
|
277
|
+
throw error2;
|
|
278
|
+
} finally {
|
|
279
|
+
setIsUpdating(false);
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
[client]
|
|
283
|
+
);
|
|
284
|
+
const star = useCallback(
|
|
285
|
+
(id, starred) => update(id, { starred }),
|
|
286
|
+
[update]
|
|
287
|
+
);
|
|
288
|
+
const rename = useCallback(
|
|
289
|
+
(id, title) => update(id, { title }),
|
|
290
|
+
[update]
|
|
291
|
+
);
|
|
292
|
+
return { star, rename, update, isUpdating, error };
|
|
293
|
+
}
|
|
294
|
+
function useChartUrl(chartId) {
|
|
295
|
+
const client = useJourneyHive();
|
|
296
|
+
const baseUrl = client.config.baseUrl || "https://journey-hive.replit.app";
|
|
297
|
+
return `${baseUrl}/charts/${chartId}.png`;
|
|
298
|
+
}
|
|
238
299
|
|
|
239
300
|
// src/components.tsx
|
|
240
301
|
import {
|
|
@@ -310,6 +371,68 @@ function MessageBubble({ role, content, timestamp }) {
|
|
|
310
371
|
) : null
|
|
311
372
|
);
|
|
312
373
|
}
|
|
374
|
+
function ChartEmbed({ embedUrl, imageUrl, title, chartId, width, height, className }) {
|
|
375
|
+
const containerStyle = {
|
|
376
|
+
margin: "8px 0 16px",
|
|
377
|
+
borderRadius: "12px",
|
|
378
|
+
overflow: "hidden",
|
|
379
|
+
border: "1px solid #e2e2ea",
|
|
380
|
+
maxWidth: width || "640px"
|
|
381
|
+
};
|
|
382
|
+
if (embedUrl) {
|
|
383
|
+
return createElement2(
|
|
384
|
+
"div",
|
|
385
|
+
{ className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
|
|
386
|
+
createElement2("iframe", {
|
|
387
|
+
src: embedUrl,
|
|
388
|
+
title: title || "Chart",
|
|
389
|
+
style: { width: "100%", height: height || "400px", border: "none" },
|
|
390
|
+
loading: "lazy"
|
|
391
|
+
})
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
if (imageUrl) {
|
|
395
|
+
return createElement2(
|
|
396
|
+
"div",
|
|
397
|
+
{ className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
|
|
398
|
+
createElement2("img", {
|
|
399
|
+
src: imageUrl,
|
|
400
|
+
alt: title || "Chart",
|
|
401
|
+
style: { width: "100%", height: "auto", display: "block" },
|
|
402
|
+
loading: "lazy"
|
|
403
|
+
})
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
function RichMessage({ role, content, timestamp, className }) {
|
|
409
|
+
const isUser = role === "user";
|
|
410
|
+
const textParts = content.filter((c) => c.type === "output_text");
|
|
411
|
+
const chartParts = content.filter((c) => c.type === "output_chart");
|
|
412
|
+
const text = textParts.map((c) => c.text).join("");
|
|
413
|
+
return createElement2(
|
|
414
|
+
"div",
|
|
415
|
+
{
|
|
416
|
+
className: `jh-rich-message ${className || ""}`.trim(),
|
|
417
|
+
style: {
|
|
418
|
+
display: "flex",
|
|
419
|
+
flexDirection: "column",
|
|
420
|
+
alignItems: isUser ? "flex-end" : "flex-start",
|
|
421
|
+
marginBottom: "8px"
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
text ? createElement2(MessageBubble, { role, content: text, timestamp }) : null,
|
|
425
|
+
...chartParts.map(
|
|
426
|
+
(chart) => createElement2(ChartEmbed, {
|
|
427
|
+
key: chart.chart_id,
|
|
428
|
+
embedUrl: chart.embed_url,
|
|
429
|
+
imageUrl: chart.image_url,
|
|
430
|
+
title: chart.title,
|
|
431
|
+
chartId: chart.chart_id
|
|
432
|
+
})
|
|
433
|
+
)
|
|
434
|
+
);
|
|
435
|
+
}
|
|
313
436
|
function ConversationView({ conversationId, agentId, className }) {
|
|
314
437
|
const { messages, isLoading, error, sendMessage } = useConversation(conversationId);
|
|
315
438
|
const [inputValue, setInputValue] = useState2("");
|
|
@@ -341,15 +464,14 @@ function ConversationView({ conversationId, agentId, className }) {
|
|
|
341
464
|
className: "jh-messages",
|
|
342
465
|
style: { flex: 1, overflowY: "auto", padding: "16px" }
|
|
343
466
|
},
|
|
344
|
-
isLoading ? createElement2("div", { className: "jh-loading" }, "Loading messages...") : messages.map(
|
|
345
|
-
|
|
346
|
-
return createElement2(MessageBubble, {
|
|
467
|
+
isLoading ? createElement2("div", { className: "jh-loading" }, "Loading messages...") : messages.map(
|
|
468
|
+
(msg) => createElement2(RichMessage, {
|
|
347
469
|
key: msg.id,
|
|
348
470
|
role: msg.role,
|
|
349
|
-
content:
|
|
471
|
+
content: msg.content || [],
|
|
350
472
|
timestamp: msg.created_at
|
|
351
|
-
})
|
|
352
|
-
|
|
473
|
+
})
|
|
474
|
+
),
|
|
353
475
|
createElement2("div", { ref: messagesEndRef })
|
|
354
476
|
),
|
|
355
477
|
createElement2(
|
|
@@ -417,13 +539,18 @@ function AgentStatus({ agent }) {
|
|
|
417
539
|
}
|
|
418
540
|
export {
|
|
419
541
|
AgentStatus,
|
|
542
|
+
ChartEmbed,
|
|
420
543
|
ConversationView,
|
|
421
544
|
JourneyHiveProvider,
|
|
422
545
|
MessageBubble,
|
|
423
546
|
ResponseStream,
|
|
547
|
+
RichMessage,
|
|
424
548
|
useAgent,
|
|
425
549
|
useAgents,
|
|
550
|
+
useChartUrl,
|
|
426
551
|
useConversation,
|
|
552
|
+
useConversationActions,
|
|
553
|
+
useConversations,
|
|
427
554
|
useJourneyHive,
|
|
428
555
|
useResponse
|
|
429
556
|
};
|