@vegintech/langchain-react-agent 0.0.38 → 0.0.41

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.
Files changed (2) hide show
  1. package/dist/index.mjs +92 -16
  2. package/package.json +1 -2
package/dist/index.mjs CHANGED
@@ -2,7 +2,6 @@ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo
2
2
  import { Actions, Bubble, Sender, Think, ThoughtChain } from "@ant-design/x";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  import { Streamdown } from "streamdown";
5
- import { code } from "@streamdown/code";
6
5
  import { useStream } from "@langchain/langgraph-sdk/react";
7
6
  //#region src/components/ChatInput.tsx
8
7
  const slotConfig = [];
@@ -181,12 +180,17 @@ const ContentBlock = ({ block, index, components, securityConfig }) => {
181
180
  },
182
181
  allowedTags: securityConfig?.allowedTags,
183
182
  literalTagContent: securityConfig?.literalTagContent,
184
- plugins: { code },
185
- controls: { table: {
186
- copy: false,
187
- download: false,
188
- fullscreen: false
189
- } },
183
+ controls: {
184
+ table: {
185
+ copy: false,
186
+ download: false,
187
+ fullscreen: false
188
+ },
189
+ code: {
190
+ copy: false,
191
+ download: false
192
+ }
193
+ },
190
194
  children: String(block.text)
191
195
  }, index);
192
196
  if (block.type === "image_url" && "image_url" in block) {
@@ -243,11 +247,17 @@ const MessageContentRenderer = ({ content, components, securityConfig }) => {
243
247
  },
244
248
  allowedTags: securityConfig?.allowedTags,
245
249
  literalTagContent: securityConfig?.literalTagContent,
246
- controls: { table: {
247
- copy: false,
248
- download: false,
249
- fullscreen: false
250
- } },
250
+ controls: {
251
+ table: {
252
+ copy: false,
253
+ download: false,
254
+ fullscreen: false
255
+ },
256
+ code: {
257
+ copy: false,
258
+ download: false
259
+ }
260
+ },
251
261
  children: content
252
262
  });
253
263
  return /* @__PURE__ */ jsx(Fragment, { children: content.map((block, index) => /* @__PURE__ */ jsx(ContentBlock, {
@@ -742,11 +752,20 @@ function useToolExecution({ tools, toolCalls, isLoading = false, onExecutionChan
742
752
  //#endregion
743
753
  //#region src/utils/messageUtils.ts
744
754
  /**
755
+ * 生成标准 UUID v4(兼容非 HTTPS 环境,避免使用 crypto.randomUUID)
756
+ */
757
+ function generateId() {
758
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
759
+ const r = Math.random() * 16 | 0;
760
+ return (c === "x" ? r : r & 3 | 8).toString(16);
761
+ });
762
+ }
763
+ /**
745
764
  * 从 BaseMessage 中提取 tool_calls
746
765
  */
747
766
  function extractToolCalls(message) {
748
767
  if ("tool_calls" in message && Array.isArray(message.tool_calls)) return message.tool_calls.map((tc) => ({
749
- id: tc.id || crypto.randomUUID(),
768
+ id: tc.id || generateId(),
750
769
  name: tc.name || tc.function?.name || "",
751
770
  args: typeof tc.function?.args === "string" ? JSON.parse(tc.function.args) : tc.args || {}
752
771
  }));
@@ -797,7 +816,7 @@ function toChatMessage(message, toolResults) {
797
816
  });
798
817
  const reasoningContent = additionalKwargs.reasoning_content;
799
818
  return {
800
- id: message.id || crypto.randomUUID(),
819
+ id: message.id || generateId(),
801
820
  type: msgType,
802
821
  content: extractContent(message),
803
822
  name: message.name,
@@ -958,6 +977,59 @@ const styles = `
958
977
  .tool-call-wrapper {
959
978
  width: 100%;
960
979
  }
980
+
981
+ /* 代码块卡片 - 自适应任意主题背景 */
982
+ [data-streamdown="code-block"] {
983
+ margin: 12px 0;
984
+ border: 1px solid rgba(128, 128, 128, 0.25);
985
+ border-radius: 8px;
986
+ overflow: hidden;
987
+ background-color: rgba(128, 128, 128, 0.12);
988
+ color: inherit;
989
+ }
990
+
991
+ [data-streamdown="code-block-header"] {
992
+ display: flex;
993
+ align-items: center;
994
+ padding: 8px 16px;
995
+ background-color: rgba(128, 128, 128, 0.06);
996
+ border-bottom: 1px solid rgba(128, 128, 128, 0.2);
997
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
998
+ font-size: 12px;
999
+ color: inherit;
1000
+ min-height: 36px;
1001
+ box-sizing: border-box;
1002
+ }
1003
+
1004
+ [data-streamdown="code-block-header"] span {
1005
+ font-family: inherit;
1006
+ font-size: inherit;
1007
+ color: inherit;
1008
+ opacity: 0.65;
1009
+ text-transform: lowercase;
1010
+ }
1011
+
1012
+ [data-streamdown="code-block-body"] {
1013
+ background-color: transparent;
1014
+ padding: 16px;
1015
+ overflow-x: auto;
1016
+ max-width: 100%;
1017
+ }
1018
+
1019
+ [data-streamdown="code-block-body"] pre,
1020
+ [data-streamdown="code-block"] pre {
1021
+ margin: 0;
1022
+ padding: 0;
1023
+ background: transparent;
1024
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
1025
+ font-size: 13px;
1026
+ line-height: 1.6;
1027
+ color: inherit;
1028
+ white-space: pre-wrap;
1029
+ word-wrap: break-word;
1030
+ overflow-wrap: break-word;
1031
+ max-width: 100%;
1032
+ }
961
1033
  `;
962
1034
  let injected = false;
963
1035
  function injectStyles() {
@@ -1144,7 +1216,8 @@ function DebugPanel({ streamState, visible = true }) {
1144
1216
  startX: e.clientX,
1145
1217
  startY: e.clientY,
1146
1218
  initialX: buttonPos.x,
1147
- initialY: buttonPos.y
1219
+ initialY: buttonPos.y,
1220
+ hasMoved: false
1148
1221
  };
1149
1222
  setIsDraggingButton(true);
1150
1223
  }, [buttonPos]);
@@ -1164,6 +1237,7 @@ function DebugPanel({ streamState, visible = true }) {
1164
1237
  if (isDraggingButton && buttonDragRef.current) {
1165
1238
  const dx = e.clientX - buttonDragRef.current.startX;
1166
1239
  const dy = e.clientY - buttonDragRef.current.startY;
1240
+ if (Math.abs(dx) > 3 || Math.abs(dy) > 3) buttonDragRef.current.hasMoved = true;
1167
1241
  setButtonPos({
1168
1242
  x: buttonDragRef.current.initialX + dx,
1169
1243
  y: buttonDragRef.current.initialY + dy
@@ -1451,7 +1525,9 @@ function DebugPanel({ streamState, visible = true }) {
1451
1525
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
1452
1526
  style: buttonStyle,
1453
1527
  onMouseDown: handleButtonMouseDown,
1454
- onClick: () => !isDraggingButton && setIsOpen(true),
1528
+ onClick: () => {
1529
+ if (!buttonDragRef.current?.hasMoved) setIsOpen(true);
1530
+ },
1455
1531
  title: "打开调试面板",
1456
1532
  children: "🐛"
1457
1533
  }), isOpen && /* @__PURE__ */ jsxs("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vegintech/langchain-react-agent",
3
- "version": "0.0.38",
3
+ "version": "0.0.41",
4
4
  "description": "LangChain Agent UI component library for React",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -25,7 +25,6 @@
25
25
  "dependencies": {
26
26
  "@ant-design/x": "^2.4.0",
27
27
  "@langchain/langgraph-sdk": "^1.8.7",
28
- "@streamdown/code": "^1.1.1",
29
28
  "streamdown": "^2.5.0"
30
29
  },
31
30
  "devDependencies": {