@journeyrewards/hive-vercel 1.1.0 → 1.2.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.
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,79 @@ function MessageBubble({ role, content, timestamp }) {
331
397
  ) : null
332
398
  );
333
399
  }
400
+ function isSafeUrl(url) {
401
+ try {
402
+ const parsed = new URL(url);
403
+ return parsed.protocol === "https:" || parsed.protocol === "http:";
404
+ } catch {
405
+ return false;
406
+ }
407
+ }
408
+ function ChartEmbed({ embedUrl, imageUrl, title, chartId, width, height, className }) {
409
+ const containerStyle = {
410
+ margin: "8px 0 16px",
411
+ borderRadius: "12px",
412
+ overflow: "hidden",
413
+ border: "1px solid #e2e2ea",
414
+ maxWidth: width || "640px"
415
+ };
416
+ if (embedUrl && isSafeUrl(embedUrl)) {
417
+ return (0, import_react2.createElement)(
418
+ "div",
419
+ { className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
420
+ (0, import_react2.createElement)("iframe", {
421
+ src: embedUrl,
422
+ title: title || "Chart",
423
+ style: { width: "100%", height: height || "400px", border: "none" },
424
+ loading: "lazy",
425
+ sandbox: "allow-scripts allow-same-origin",
426
+ referrerPolicy: "no-referrer"
427
+ })
428
+ );
429
+ }
430
+ if (imageUrl && isSafeUrl(imageUrl)) {
431
+ return (0, import_react2.createElement)(
432
+ "div",
433
+ { className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
434
+ (0, import_react2.createElement)("img", {
435
+ src: imageUrl,
436
+ alt: title || "Chart",
437
+ style: { width: "100%", height: "auto", display: "block" },
438
+ loading: "lazy",
439
+ referrerPolicy: "no-referrer"
440
+ })
441
+ );
442
+ }
443
+ return null;
444
+ }
445
+ function RichMessage({ role, content, timestamp, className }) {
446
+ const isUser = role === "user";
447
+ const textParts = content.filter((c) => c.type === "output_text");
448
+ const chartParts = content.filter((c) => c.type === "output_chart");
449
+ const text = textParts.map((c) => c.text).join("");
450
+ return (0, import_react2.createElement)(
451
+ "div",
452
+ {
453
+ className: `jh-rich-message ${className || ""}`.trim(),
454
+ style: {
455
+ display: "flex",
456
+ flexDirection: "column",
457
+ alignItems: isUser ? "flex-end" : "flex-start",
458
+ marginBottom: "8px"
459
+ }
460
+ },
461
+ text ? (0, import_react2.createElement)(MessageBubble, { role, content: text, timestamp }) : null,
462
+ ...chartParts.map(
463
+ (chart) => (0, import_react2.createElement)(ChartEmbed, {
464
+ key: chart.chart_id,
465
+ embedUrl: chart.embed_url,
466
+ imageUrl: chart.image_url,
467
+ title: chart.title,
468
+ chartId: chart.chart_id
469
+ })
470
+ )
471
+ );
472
+ }
334
473
  function ConversationView({ conversationId, agentId, className }) {
335
474
  const { messages, isLoading, error, sendMessage } = useConversation(conversationId);
336
475
  const [inputValue, setInputValue] = (0, import_react2.useState)("");
@@ -362,33 +501,14 @@ function ConversationView({ conversationId, agentId, className }) {
362
501
  className: "jh-messages",
363
502
  style: { flex: 1, overflowY: "auto", padding: "16px" }
364
503
  },
365
- isLoading ? (0, import_react2.createElement)("div", { className: "jh-loading" }, "Loading messages...") : messages.map((msg) => {
366
- const parts = msg.content || [];
367
- const text = parts.map((c) => c.type === "output_text" ? c.text : "").join("") || "";
368
- const chartParts = parts.filter((c) => c.type === "output_chart");
369
- return (0, import_react2.createElement)(
370
- "div",
371
- { key: msg.id },
372
- (0, import_react2.createElement)(MessageBubble, {
373
- key: `text-${msg.id}`,
374
- role: msg.role,
375
- content: text,
376
- timestamp: msg.created_at
377
- }),
378
- ...chartParts.map(
379
- (chart) => (0, import_react2.createElement)("div", {
380
- key: `chart-${chart.chart_id}`,
381
- className: "jh-chart-embed",
382
- style: { margin: "8px 0 16px", borderRadius: "12px", overflow: "hidden", border: "1px solid #e2e2ea", maxWidth: "640px" }
383
- }, (0, import_react2.createElement)("iframe", {
384
- src: chart.embed_url,
385
- title: chart.title,
386
- style: { width: "100%", height: "400px", border: "none" },
387
- loading: "lazy"
388
- }))
389
- )
390
- );
391
- }),
504
+ isLoading ? (0, import_react2.createElement)("div", { className: "jh-loading" }, "Loading messages...") : messages.map(
505
+ (msg) => (0, import_react2.createElement)(RichMessage, {
506
+ key: msg.id,
507
+ role: msg.role,
508
+ content: msg.content || [],
509
+ timestamp: msg.created_at
510
+ })
511
+ ),
392
512
  (0, import_react2.createElement)("div", { ref: messagesEndRef })
393
513
  ),
394
514
  (0, import_react2.createElement)(
@@ -457,13 +577,18 @@ function AgentStatus({ agent }) {
457
577
  // Annotate the CommonJS export names for ESM import in node:
458
578
  0 && (module.exports = {
459
579
  AgentStatus,
580
+ ChartEmbed,
460
581
  ConversationView,
461
582
  JourneyHiveProvider,
462
583
  MessageBubble,
463
584
  ResponseStream,
585
+ RichMessage,
464
586
  useAgent,
465
587
  useAgents,
588
+ useChartUrl,
466
589
  useConversation,
590
+ useConversationActions,
591
+ useConversations,
467
592
  useJourneyHive,
468
593
  useResponse
469
594
  });
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,79 @@ function MessageBubble({ role, content, timestamp }) {
310
371
  ) : null
311
372
  );
312
373
  }
374
+ function isSafeUrl(url) {
375
+ try {
376
+ const parsed = new URL(url);
377
+ return parsed.protocol === "https:" || parsed.protocol === "http:";
378
+ } catch {
379
+ return false;
380
+ }
381
+ }
382
+ function ChartEmbed({ embedUrl, imageUrl, title, chartId, width, height, className }) {
383
+ const containerStyle = {
384
+ margin: "8px 0 16px",
385
+ borderRadius: "12px",
386
+ overflow: "hidden",
387
+ border: "1px solid #e2e2ea",
388
+ maxWidth: width || "640px"
389
+ };
390
+ if (embedUrl && isSafeUrl(embedUrl)) {
391
+ return createElement2(
392
+ "div",
393
+ { className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
394
+ createElement2("iframe", {
395
+ src: embedUrl,
396
+ title: title || "Chart",
397
+ style: { width: "100%", height: height || "400px", border: "none" },
398
+ loading: "lazy",
399
+ sandbox: "allow-scripts allow-same-origin",
400
+ referrerPolicy: "no-referrer"
401
+ })
402
+ );
403
+ }
404
+ if (imageUrl && isSafeUrl(imageUrl)) {
405
+ return createElement2(
406
+ "div",
407
+ { className: `jh-chart-embed ${className || ""}`.trim(), style: containerStyle },
408
+ createElement2("img", {
409
+ src: imageUrl,
410
+ alt: title || "Chart",
411
+ style: { width: "100%", height: "auto", display: "block" },
412
+ loading: "lazy",
413
+ referrerPolicy: "no-referrer"
414
+ })
415
+ );
416
+ }
417
+ return null;
418
+ }
419
+ function RichMessage({ role, content, timestamp, className }) {
420
+ const isUser = role === "user";
421
+ const textParts = content.filter((c) => c.type === "output_text");
422
+ const chartParts = content.filter((c) => c.type === "output_chart");
423
+ const text = textParts.map((c) => c.text).join("");
424
+ return createElement2(
425
+ "div",
426
+ {
427
+ className: `jh-rich-message ${className || ""}`.trim(),
428
+ style: {
429
+ display: "flex",
430
+ flexDirection: "column",
431
+ alignItems: isUser ? "flex-end" : "flex-start",
432
+ marginBottom: "8px"
433
+ }
434
+ },
435
+ text ? createElement2(MessageBubble, { role, content: text, timestamp }) : null,
436
+ ...chartParts.map(
437
+ (chart) => createElement2(ChartEmbed, {
438
+ key: chart.chart_id,
439
+ embedUrl: chart.embed_url,
440
+ imageUrl: chart.image_url,
441
+ title: chart.title,
442
+ chartId: chart.chart_id
443
+ })
444
+ )
445
+ );
446
+ }
313
447
  function ConversationView({ conversationId, agentId, className }) {
314
448
  const { messages, isLoading, error, sendMessage } = useConversation(conversationId);
315
449
  const [inputValue, setInputValue] = useState2("");
@@ -341,33 +475,14 @@ function ConversationView({ conversationId, agentId, className }) {
341
475
  className: "jh-messages",
342
476
  style: { flex: 1, overflowY: "auto", padding: "16px" }
343
477
  },
344
- isLoading ? createElement2("div", { className: "jh-loading" }, "Loading messages...") : messages.map((msg) => {
345
- const parts = msg.content || [];
346
- const text = parts.map((c) => c.type === "output_text" ? c.text : "").join("") || "";
347
- const chartParts = parts.filter((c) => c.type === "output_chart");
348
- return createElement2(
349
- "div",
350
- { key: msg.id },
351
- createElement2(MessageBubble, {
352
- key: `text-${msg.id}`,
353
- role: msg.role,
354
- content: text,
355
- timestamp: msg.created_at
356
- }),
357
- ...chartParts.map(
358
- (chart) => createElement2("div", {
359
- key: `chart-${chart.chart_id}`,
360
- className: "jh-chart-embed",
361
- style: { margin: "8px 0 16px", borderRadius: "12px", overflow: "hidden", border: "1px solid #e2e2ea", maxWidth: "640px" }
362
- }, createElement2("iframe", {
363
- src: chart.embed_url,
364
- title: chart.title,
365
- style: { width: "100%", height: "400px", border: "none" },
366
- loading: "lazy"
367
- }))
368
- )
369
- );
370
- }),
478
+ isLoading ? createElement2("div", { className: "jh-loading" }, "Loading messages...") : messages.map(
479
+ (msg) => createElement2(RichMessage, {
480
+ key: msg.id,
481
+ role: msg.role,
482
+ content: msg.content || [],
483
+ timestamp: msg.created_at
484
+ })
485
+ ),
371
486
  createElement2("div", { ref: messagesEndRef })
372
487
  ),
373
488
  createElement2(
@@ -435,13 +550,18 @@ function AgentStatus({ agent }) {
435
550
  }
436
551
  export {
437
552
  AgentStatus,
553
+ ChartEmbed,
438
554
  ConversationView,
439
555
  JourneyHiveProvider,
440
556
  MessageBubble,
441
557
  ResponseStream,
558
+ RichMessage,
442
559
  useAgent,
443
560
  useAgents,
561
+ useChartUrl,
444
562
  useConversation,
563
+ useConversationActions,
564
+ useConversations,
445
565
  useJourneyHive,
446
566
  useResponse
447
567
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@journeyrewards/hive-vercel",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Vercel/Next.js SDK for Journey Hive Agent Orchestration",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",