@vegintech/langchain-react-agent 0.0.23 → 0.0.25

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
@@ -2,10 +2,28 @@ import * as react from "react";
2
2
  import React$1, { ReactNode } from "react";
3
3
  import { ThoughtChainItemProps } from "@ant-design/x";
4
4
  import { Components } from "streamdown";
5
- import * as _langchain_langgraph_sdk_react0 from "@langchain/langgraph-sdk/react";
5
+ import { UseStreamOptions, useStream } from "@langchain/langgraph-sdk/react";
6
6
  import { BaseNode, InsertPosition, NodeRender, SenderProps, SkillType, SlotConfigType } from "@ant-design/x/es/sender/interface.ts";
7
7
  import { Message } from "@langchain/langgraph-sdk";
8
8
 
9
+ //#region src/hooks/useAgentStream.d.ts
10
+ type AgentStreamOptions = UseStreamOptions;
11
+ type AgentStream = ReturnType<typeof useStream>;
12
+ /**
13
+ * 包装 useStream hook,为 AgentChat 提供统一的 stream 实例创建方式
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * const stream = useAgentStream({
18
+ * apiUrl: "http://localhost:2026",
19
+ * assistantId: "demo",
20
+ * });
21
+ *
22
+ * <AgentChat stream={stream} />
23
+ * ```
24
+ */
25
+ declare function useAgentStream(options: AgentStreamOptions): AgentStream;
26
+ //#endregion
9
27
  //#region src/types.d.ts
10
28
  /** ToolCard 组件 Props */
11
29
  interface ToolCardProps extends Omit<ThoughtChainItemProps, "children"> {
@@ -211,8 +229,6 @@ interface MessageConfig {
211
229
  literalTagContent?: string[];
212
230
  /** Loading 动画颜色,支持 CSS 颜色值 */
213
231
  loadingColor?: string;
214
- /** 空状态配置 */
215
- emptyState?: EmptyStateConfig;
216
232
  }
217
233
  /** 输入框配置 */
218
234
  interface InputConfig extends SenderCustomizationProps {
@@ -222,24 +238,23 @@ interface InputConfig extends SenderCustomizationProps {
222
238
  placeholder?: string;
223
239
  }
224
240
  interface AgentChatProps {
225
- apiUrl?: string;
226
- assistantId: string;
227
- threadId?: string;
228
- headers?: Record<string, string | undefined | null>;
229
- onThreadIdChange?: (threadId: string) => void;
241
+ /**
242
+ * Stream 实例
243
+ * 由外部通过 useAgentStream hook 创建并传入
244
+ */
245
+ stream: AgentStream;
230
246
  className?: string;
231
247
  tools?: ToolDefinition<any>[];
232
248
  contexts?: ContextItem[];
233
249
  messageConfig?: MessageConfig;
234
250
  inputConfig?: InputConfig;
235
- onError?: (error: Error) => void;
236
251
  interruptConfig?: InterruptConfig;
237
252
  /** Agent 状态值 */
238
253
  agentState?: Record<string, unknown>;
239
- /** Agent 状态变化回调 */
240
- onAgentStateChange?: (state: Record<string, unknown>) => void;
241
254
  /** 是否显示调试面板,默认 false。仅在开发环境生效 */
242
255
  showDebug?: boolean;
256
+ /** 欢迎组件,当消息列表为空且非加载状态时显示 */
257
+ welcome?: ReactNode;
243
258
  }
244
259
  /** AgentChat 组件对外暴露的方法 */
245
260
  interface AgentChatRef {
@@ -251,19 +266,6 @@ interface AgentChatRef {
251
266
  clearInput: () => void;
252
267
  /** 聚焦输入框 */
253
268
  focusInput: () => void;
254
- /**
255
- * LangGraph Stream 实例
256
- * 提供对底层流式连接的完整访问,包括:
257
- * - messages: 当前消息列表
258
- * - values: Agent 状态值
259
- * - isLoading: 是否正在加载
260
- * - submit: 提交消息
261
- * - stop: 停止流
262
- * - interrupt: 中断事件
263
- * - client: LangGraph 客户端(可通过 client.threads.create() 创建新线程)
264
- * 等完整功能
265
- */
266
- stream: ReturnType<typeof _langchain_langgraph_sdk_react0.useStream> | null;
267
269
  }
268
270
  /** Streamdown 安全过滤配置 */
269
271
  interface StreamdownSecurityConfig {
@@ -288,12 +290,6 @@ interface MessageListProps {
288
290
  loadingColor?: string;
289
291
  /** Interrupt 渲染函数,用于在消息列表中渲染中断 UI */
290
292
  interruptRender?: () => ReactNode;
291
- /** 空状态配置 */
292
- emptyState?: {
293
- /** 空状态标题 */title?: string; /** 空状态描述 */
294
- description?: string; /** 自定义渲染 */
295
- render?: () => ReactNode;
296
- };
297
293
  }
298
294
  //#endregion
299
295
  //#region src/components/AgentChat.d.ts
@@ -315,4 +311,4 @@ interface MessageContentRendererProps {
315
311
  /** 消息内容渲染组件 - 支持字符串和多模态内容块 */
316
312
  declare const MessageContentRenderer: React$1.FC<MessageContentRendererProps>;
317
313
  //#endregion
318
- export { AgentChat, type AgentChatInputRef, type AgentChatProps, type AgentChatRef, type BackendTool, type ChatMessage, type ContextItem, type EmptyStateConfig, type FrontendTool, type InputConfig, type InterruptConfig, type InterruptEvent, type InterruptManagerProps, type InterruptRenderProps, type MessageConfig, type MessageContent, type MessageContentBlock, MessageContentRenderer, type MessageContentRendererProps, type MessageType, type SenderCustomizationProps, type SenderSlotConfig, type SenderSubmitParams, type ToolCallInput, ToolCard, type ToolCardProps, type ToolDefinition, type ToolExecutionRecord, type ToolExecutionStatus, type ToolParameterSchema, type ToolRenderProps };
314
+ export { AgentChat, type AgentChatInputRef, type AgentChatProps, type AgentChatRef, type AgentStream, type AgentStreamOptions, type BackendTool, type ChatMessage, type ContextItem, type EmptyStateConfig, type FrontendTool, type InputConfig, type InterruptConfig, type InterruptEvent, type InterruptManagerProps, type InterruptRenderProps, type MessageConfig, type MessageContent, type MessageContentBlock, MessageContentRenderer, type MessageContentRendererProps, type MessageType, type SenderCustomizationProps, type SenderSlotConfig, type SenderSubmitParams, type ToolCallInput, ToolCard, type ToolCardProps, type ToolDefinition, type ToolExecutionRecord, type ToolExecutionStatus, type ToolParameterSchema, type ToolRenderProps, useAgentStream };
package/dist/index.mjs CHANGED
@@ -314,7 +314,7 @@ const renderMessageContent = (message, isLastMessage, isLoading, tools, toolExec
314
314
  children: /* @__PURE__ */ jsx(ReasoningContent, { content: message.reasoningContent })
315
315
  }),
316
316
  !isContentEmpty && /* @__PURE__ */ jsx("div", {
317
- style: { marginTop: message.reasoningContent ? "8px" : "3px" },
317
+ style: { marginTop: message.type == "human" ? "0px" : "8px" },
318
318
  children: /* @__PURE__ */ jsx(MessageContentRenderer, {
319
319
  content: message.content,
320
320
  components,
@@ -378,7 +378,7 @@ const roleConfig = {
378
378
  }
379
379
  }
380
380
  };
381
- const MessageList = ({ messages, isLoading = false, className = "", tools, toolExecutions, components, securityConfig, loadingColor, interruptRender, emptyState }) => {
381
+ const MessageList = ({ messages, isLoading = false, className = "", tools, toolExecutions, components, securityConfig, loadingColor, interruptRender }) => {
382
382
  const reasoningCacheRef = useRef(/* @__PURE__ */ new Map());
383
383
  const processedMessages = useMemo(() => {
384
384
  const cache = reasoningCacheRef.current;
@@ -444,19 +444,10 @@ const MessageList = ({ messages, isLoading = false, className = "", tools, toolE
444
444
  placement: "start",
445
445
  style: { paddingBlock: 0 }
446
446
  }] : items;
447
- if (allItems.length === 0) {
448
- if (emptyState?.render) return /* @__PURE__ */ jsx("div", {
449
- className: `agent-message-list empty ${className}`,
450
- children: emptyState.render()
451
- });
452
- return /* @__PURE__ */ jsx("div", {
453
- className: `agent-message-list empty ${className}`,
454
- children: /* @__PURE__ */ jsxs("div", {
455
- className: "agent-message-empty",
456
- children: [emptyState?.title && /* @__PURE__ */ jsx("h4", { children: emptyState.title }), emptyState?.description ? /* @__PURE__ */ jsx("p", { children: emptyState.description }) : /* @__PURE__ */ jsx("p", { children: "开始对话吧" })]
457
- })
458
- });
459
- }
447
+ if (allItems.length === 0) return /* @__PURE__ */ jsx("div", {
448
+ className: `agent-message-list empty ${className}`,
449
+ children: /* @__PURE__ */ jsx("div", { className: "agent-message-empty" })
450
+ });
460
451
  return /* @__PURE__ */ jsx(Bubble.List, {
461
452
  className: `agent-message-list ${className}`,
462
453
  items: allItems,
@@ -1358,33 +1349,15 @@ function injectStyles() {
1358
1349
  //#endregion
1359
1350
  //#region src/components/AgentChat.tsx
1360
1351
  injectStyles();
1361
- const AgentChat = forwardRef(({ apiUrl, assistantId, headers, threadId, onThreadIdChange, className = "", tools, contexts, messageConfig, inputConfig, onError, interruptConfig, agentState, onAgentStateChange, showDebug }, ref) => {
1352
+ const AgentChat = forwardRef(({ stream, className = "", tools, contexts, messageConfig, inputConfig, interruptConfig, agentState, showDebug, welcome }, ref) => {
1362
1353
  const { onPreSend, ...chatInputConfig } = inputConfig || {};
1363
1354
  const chatInputRef = useRef(null);
1364
- const stream = useStream({
1365
- apiUrl,
1366
- assistantId,
1367
- threadId,
1368
- onThreadId: (newThreadId) => {
1369
- onThreadIdChange?.(newThreadId);
1370
- },
1371
- defaultHeaders: headers,
1372
- messagesKey: "messages",
1373
- onError: (error) => {
1374
- const err = error instanceof Error ? error : new Error(String(error));
1375
- onError?.(err);
1376
- }
1377
- });
1378
1355
  useImperativeHandle(ref, () => ({
1379
1356
  input: chatInputRef.current,
1380
1357
  setSkill: (skill) => chatInputRef.current?.setSkill?.(skill),
1381
1358
  clearInput: () => chatInputRef.current?.clear?.(),
1382
- focusInput: () => chatInputRef.current?.focus?.(),
1383
- stream
1359
+ focusInput: () => chatInputRef.current?.focus?.()
1384
1360
  }));
1385
- useEffect(() => {
1386
- if (stream.values && onAgentStateChange) onAgentStateChange(stream.values);
1387
- }, [stream.values, onAgentStateChange]);
1388
1361
  const { renderInterrupt: interruptRender } = useInterrupt({
1389
1362
  interrupt: stream.interrupt,
1390
1363
  config: interruptConfig,
@@ -1475,13 +1448,16 @@ const AgentChat = forwardRef(({ apiUrl, assistantId, headers, threadId, onThread
1475
1448
  onToolResultsBatch: handleToolResultsBatch,
1476
1449
  completedToolResults: toolResults
1477
1450
  });
1451
+ const shouldRenderWelcome = messages.length === 0 && !isLoading && welcome;
1478
1452
  return /* @__PURE__ */ jsxs("div", {
1479
1453
  className: `agent-chat-container ${className}`,
1480
1454
  children: [
1481
- /* @__PURE__ */ jsx(MessageList, {
1455
+ shouldRenderWelcome ? /* @__PURE__ */ jsx("div", {
1456
+ className: "agent-message-list agent-chat-welcome",
1457
+ children: welcome
1458
+ }) : /* @__PURE__ */ jsx(MessageList, {
1482
1459
  messages,
1483
1460
  isLoading: stream.isLoading,
1484
- className: "agent-chat-messages",
1485
1461
  tools,
1486
1462
  toolExecutions,
1487
1463
  components: messageConfig?.components,
@@ -1490,8 +1466,7 @@ const AgentChat = forwardRef(({ apiUrl, assistantId, headers, threadId, onThread
1490
1466
  literalTagContent: messageConfig?.literalTagContent
1491
1467
  },
1492
1468
  loadingColor: messageConfig?.loadingColor,
1493
- interruptRender,
1494
- emptyState: messageConfig?.emptyState
1469
+ interruptRender
1495
1470
  }),
1496
1471
  /* @__PURE__ */ jsx(ChatInput, {
1497
1472
  ref: chatInputRef,
@@ -1527,4 +1502,22 @@ const ToolCard = ({ children, style, ...rest }) => {
1527
1502
  }), children] });
1528
1503
  };
1529
1504
  //#endregion
1530
- export { AgentChat, MessageContentRenderer, ToolCard };
1505
+ //#region src/hooks/useAgentStream.ts
1506
+ /**
1507
+ * 包装 useStream hook,为 AgentChat 提供统一的 stream 实例创建方式
1508
+ *
1509
+ * @example
1510
+ * ```tsx
1511
+ * const stream = useAgentStream({
1512
+ * apiUrl: "http://localhost:2026",
1513
+ * assistantId: "demo",
1514
+ * });
1515
+ *
1516
+ * <AgentChat stream={stream} />
1517
+ * ```
1518
+ */
1519
+ function useAgentStream(options) {
1520
+ return useStream(options);
1521
+ }
1522
+ //#endregion
1523
+ export { AgentChat, MessageContentRenderer, ToolCard, useAgentStream };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vegintech/langchain-react-agent",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "description": "LangChain Agent UI component library for React",
5
5
  "license": "MIT",
6
6
  "files": [