@langgraph-js/sdk 4.3.3 → 4.3.4

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.
@@ -349,7 +349,6 @@ export class LangGraphClient extends EventEmitter {
349
349
  else if (chunk.event === "values") {
350
350
  const data = chunk.data;
351
351
  if (data?.__interrupt__) {
352
- this._status = "interrupted";
353
352
  const humanInTheLoopData = this.getHumanInTheLoopData(data?.__interrupt__);
354
353
  if (humanInTheLoopData) {
355
354
  this.humanInTheLoop = humanInTheLoopData;
@@ -357,9 +356,6 @@ export class LangGraphClient extends EventEmitter {
357
356
  else {
358
357
  this.interruptData = data.__interrupt__;
359
358
  }
360
- this.emit("interruptChange", {
361
- event: "interruptChange",
362
- });
363
359
  }
364
360
  else if (data?.messages) {
365
361
  const isResume = !!command?.resume;
@@ -396,9 +392,13 @@ export class LangGraphClient extends EventEmitter {
396
392
  // json 校验
397
393
  return this.callFETool(toolMessage, tool.args);
398
394
  });
395
+ console.log("batch call tools", result.length);
396
+ // 只有当卡住流程时,才改变状态为 interrupted
399
397
  this._status = "interrupted";
400
398
  this.currentThread.status = "interrupted"; // 修复某些机制下,状态不为 interrupted 与后端有差异
401
- console.log("batch call tools", result.length);
399
+ this.emit("interruptChange", {
400
+ event: "interruptChange",
401
+ });
402
402
  return Promise.all(result);
403
403
  }
404
404
  }
@@ -16,6 +16,7 @@ export declare const useChat: () => UnionStore<{
16
16
  currentAgent: import("nanostores").PreinitializedWritableAtom<string> & object;
17
17
  currentChatId: import("nanostores").PreinitializedWritableAtom<string | null> & object;
18
18
  currentNodeName: import("nanostores").PreinitializedWritableAtom<string> & object;
19
+ currentStatus: import("nanostores").PreinitializedWritableAtom<string> & object;
19
20
  interruptData: import("nanostores").PreinitializedWritableAtom<import("../humanInTheLoop.js").InterruptData | null> & object;
20
21
  isInterrupted: import("nanostores").PreinitializedWritableAtom<boolean> & object;
21
22
  tools: import("nanostores").PreinitializedWritableAtom<import("../index.js").UnionTool<any, Object, any>[]> & object;
@@ -16,6 +16,7 @@ export declare const useChat: () => UnionStoreSolid<{
16
16
  currentAgent: PreinitializedWritableAtom<string> & object;
17
17
  currentChatId: PreinitializedWritableAtom<string | null> & object;
18
18
  currentNodeName: PreinitializedWritableAtom<string> & object;
19
+ currentStatus: PreinitializedWritableAtom<string> & object;
19
20
  interruptData: PreinitializedWritableAtom<import("../humanInTheLoop.js").InterruptData | null> & object;
20
21
  isInterrupted: PreinitializedWritableAtom<boolean> & object;
21
22
  tools: PreinitializedWritableAtom<import("../index.js").UnionTool<any, Object, any>[]> & object;
@@ -32,6 +32,7 @@ export declare const createChatStore: (initClientName: string, config: Partial<L
32
32
  currentAgent: import("nanostores").PreinitializedWritableAtom<string> & object;
33
33
  currentChatId: import("nanostores").PreinitializedWritableAtom<string | null> & object;
34
34
  currentNodeName: import("nanostores").PreinitializedWritableAtom<string> & object;
35
+ currentStatus: import("nanostores").PreinitializedWritableAtom<string> & object;
35
36
  interruptData: import("nanostores").PreinitializedWritableAtom<InterruptData | null> & object;
36
37
  isInterrupted: import("nanostores").PreinitializedWritableAtom<boolean> & object;
37
38
  tools: import("nanostores").PreinitializedWritableAtom<UnionTool<any, Object, any>[]> & object;
@@ -58,6 +58,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
58
58
  const currentAgent = atom(initClientName);
59
59
  const currentChatId = atom(null);
60
60
  const currentNodeName = atom("__start__");
61
+ const currentStatus = atom("idle");
61
62
  // Interrupt 状态
62
63
  const interruptData = atom(null);
63
64
  const isInterrupted = atom(false);
@@ -87,6 +88,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
87
88
  const lastMessage = messages[messages.length - 1];
88
89
  currentNodeName.set(lastMessage?.node_name || lastMessage?.name || "__start__");
89
90
  renderMessages.set(messages);
91
+ currentStatus.set(newClient.status);
90
92
  }, 10);
91
93
  // ============ 工具和图表辅助函数 ============
92
94
  const refreshTools = async () => {
@@ -212,6 +214,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
212
214
  isInterrupted.set(false);
213
215
  }
214
216
  updateUI(newClient);
217
+ client.set(client.get());
215
218
  };
216
219
  newClient.on("start", onStart);
217
220
  newClient.on("thread", onThread);
@@ -325,9 +328,8 @@ export const createChatStore = (initClientName, config, context = {}) => {
325
328
  const c = client.get();
326
329
  if (!c)
327
330
  return null;
328
- const toolsDefine = c.tools.getAllTools();
329
- const tool = toolsDefine.find((i) => i.name === tool_name)?.render;
330
- return tool ? (message) => tool(new ToolRenderData(message, c)) : null;
331
+ const toolRender = c.tools.getTool(tool_name)?.render;
332
+ return toolRender ? (message) => toolRender(new ToolRenderData(message, c)) : null;
331
333
  }
332
334
  // ============ 返回 Store API ============
333
335
  const artifactHook = useArtifacts(renderMessages, client);
@@ -345,6 +347,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
345
347
  currentAgent,
346
348
  currentChatId,
347
349
  currentNodeName,
350
+ currentStatus,
348
351
  // Interrupt 状态
349
352
  interruptData,
350
353
  isInterrupted,
@@ -59,6 +59,7 @@ export declare const useChatProvider: (props: ChatProviderProps) => {
59
59
  currentAgent: PreinitializedWritableAtom<string> & object;
60
60
  currentChatId: PreinitializedWritableAtom<string | null> & object;
61
61
  currentNodeName: PreinitializedWritableAtom<string> & object;
62
+ currentStatus: PreinitializedWritableAtom<string> & object;
62
63
  interruptData: PreinitializedWritableAtom<import("../humanInTheLoop.js").InterruptData | null> & object;
63
64
  isInterrupted: PreinitializedWritableAtom<boolean> & object;
64
65
  tools: PreinitializedWritableAtom<import("../index.js").UnionTool<any, Object, any>[]> & object;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langgraph-js/sdk",
3
- "version": "4.3.3",
3
+ "version": "4.3.4",
4
4
  "description": "The UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -472,16 +472,12 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
472
472
  }
473
473
  | undefined;
474
474
  if (data?.__interrupt__) {
475
- this._status = "interrupted";
476
475
  const humanInTheLoopData = this.getHumanInTheLoopData(data?.__interrupt__);
477
476
  if (humanInTheLoopData) {
478
477
  this.humanInTheLoop = humanInTheLoopData;
479
478
  } else {
480
479
  this.interruptData = data.__interrupt__;
481
480
  }
482
- this.emit("interruptChange", {
483
- event: "interruptChange",
484
- });
485
481
  } else if (data?.messages) {
486
482
  const isResume = !!command?.resume;
487
483
  const isLongerThanLocal = data.messages.length >= this.messageProcessor.getGraphMessages().length;
@@ -516,9 +512,13 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
516
512
  // json 校验
517
513
  return this.callFETool(toolMessage, tool.args);
518
514
  });
515
+ console.log("batch call tools", result.length);
516
+ // 只有当卡住流程时,才改变状态为 interrupted
519
517
  this._status = "interrupted";
520
518
  this.currentThread!.status = "interrupted"; // 修复某些机制下,状态不为 interrupted 与后端有差异
521
- console.log("batch call tools", result.length);
519
+ this.emit("interruptChange", {
520
+ event: "interruptChange",
521
+ });
522
522
  return Promise.all(result);
523
523
  }
524
524
  }
@@ -50,6 +50,7 @@ export class ToolRenderData<I, D> {
50
50
 
51
51
  return this.client.doneHumanInTheLoopWaiting(this.message.id!, this.getToolActionRequestID(), response);
52
52
  }
53
+
53
54
  get state() {
54
55
  if (this.message.type === "tool" && this.message?.additional_kwargs?.done) {
55
56
  return "done";
@@ -78,7 +78,7 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
78
78
  const currentAgent = atom<string>(initClientName);
79
79
  const currentChatId = atom<string | null>(null);
80
80
  const currentNodeName = atom<string>("__start__");
81
-
81
+ const currentStatus = atom<string>("idle");
82
82
  // Interrupt 状态
83
83
  const interruptData = atom<InterruptData | null>(null);
84
84
  const isInterrupted = atom<boolean>(false);
@@ -117,6 +117,7 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
117
117
 
118
118
  currentNodeName.set(lastMessage?.node_name || lastMessage?.name || "__start__");
119
119
  renderMessages.set(messages);
120
+ currentStatus.set(newClient.status);
120
121
  }, 10);
121
122
  // ============ 工具和图表辅助函数 ============
122
123
 
@@ -256,6 +257,7 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
256
257
  isInterrupted.set(false);
257
258
  }
258
259
  updateUI(newClient);
260
+ client.set(client.get());
259
261
  };
260
262
 
261
263
  newClient.on("start", onStart);
@@ -383,9 +385,8 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
383
385
  function getToolUIRender(tool_name: string) {
384
386
  const c = client.get();
385
387
  if (!c) return null;
386
- const toolsDefine = c.tools.getAllTools();
387
- const tool = toolsDefine.find((i) => i.name === tool_name!)?.render;
388
- return tool ? (message: RenderMessage) => tool(new ToolRenderData(message, c)) : null;
388
+ const toolRender = c.tools.getTool(tool_name)?.render;
389
+ return toolRender ? (message: RenderMessage) => toolRender(new ToolRenderData(message, c)) : null;
389
390
  }
390
391
 
391
392
  // ============ 返回 Store API ============
@@ -407,6 +408,7 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
407
408
  currentAgent,
408
409
  currentChatId,
409
410
  currentNodeName,
411
+ currentStatus,
410
412
 
411
413
  // Interrupt 状态
412
414
  interruptData,
@@ -1,13 +0,0 @@
1
- import { AnnotationRoot, StateDefinition } from "@langchain/langgraph";
2
- /**
3
- * create state for langgraph
4
- * @example
5
- * export const GraphState = createState(createReactAgentAnnotation(), ModelState, SwarmState).build({
6
- * current_plan: createDefaultAnnotation<Plan | null>(() => null),
7
- * title: createDefaultAnnotation<string>(() => ""),
8
- *});
9
- */
10
- export declare const createState: <T extends readonly AnnotationRoot<any>[]>(...parents: T) => {
11
- build: <D extends StateDefinition>(state?: D) => any;
12
- };
13
- export declare const createDefaultAnnotation: <T>(defaultValue: () => T) => any;
@@ -1,20 +0,0 @@
1
- import { Annotation } from "@langchain/langgraph";
2
- /**
3
- * create state for langgraph
4
- * @example
5
- * export const GraphState = createState(createReactAgentAnnotation(), ModelState, SwarmState).build({
6
- * current_plan: createDefaultAnnotation<Plan | null>(() => null),
7
- * title: createDefaultAnnotation<string>(() => ""),
8
- *});
9
- */
10
- export const createState = (...parents) => {
11
- return {
12
- build: (state = {}) => {
13
- return Annotation.Root(Object.assign({}, ...parents.map((p) => p.spec), state));
14
- },
15
- };
16
- };
17
- export const createDefaultAnnotation = (defaultValue) => Annotation({
18
- reducer: (_, a) => a,
19
- default: defaultValue,
20
- });
@@ -1,16 +0,0 @@
1
- import { DynamicStructuredTool } from "@langchain/core/tools";
2
- export declare const FEToolsState: any;
3
- export interface FEToolParameters {
4
- name: string;
5
- type: string;
6
- description: string;
7
- required: boolean;
8
- }
9
- export interface FETool {
10
- name: string;
11
- description: string;
12
- parameters: FEToolParameters[];
13
- }
14
- export declare const createFETool: (tool: FETool) => FETool;
15
- export declare const createFeTools: (tools: FETool[]) => DynamicStructuredTool[];
16
- export declare const actionToTool: (tool: FETool) => DynamicStructuredTool;
@@ -1,37 +0,0 @@
1
- import { interrupt } from "@langchain/langgraph";
2
- import { createDefaultAnnotation } from "./createState.js";
3
- import { DynamicStructuredTool } from "@langchain/core/tools";
4
- import { createState } from "./createState.js";
5
- export const FEToolsState = createState().build({
6
- fe_tools: createDefaultAnnotation(() => []),
7
- });
8
- export const createFETool = (tool) => {
9
- return tool;
10
- };
11
- export const createFeTools = (tools) => {
12
- return tools
13
- .map((tool) => {
14
- try {
15
- return actionToTool(tool);
16
- }
17
- catch (e) {
18
- console.error(e);
19
- return null;
20
- }
21
- })
22
- .filter((tool) => tool !== null);
23
- };
24
- export const actionToTool = (tool) => {
25
- const callTool = async (args) => {
26
- const data = interrupt(JSON.stringify(args));
27
- return [data, null];
28
- };
29
- const schema = tool.parameters;
30
- return new DynamicStructuredTool({
31
- name: tool.name,
32
- description: tool.description || "",
33
- schema,
34
- func: callTool,
35
- responseFormat: "content_and_artifact",
36
- });
37
- };
@@ -1,3 +0,0 @@
1
- export * from "./createState.js";
2
- export * from "./feTools.js";
3
- export * from "./tools/index.js";
@@ -1,3 +0,0 @@
1
- export * from "./createState.js";
2
- export * from "./feTools.js";
3
- export * from "./tools/index.js";
@@ -1,23 +0,0 @@
1
- import { AIMessage, HumanMessage } from "@langchain/core/messages";
2
- export declare class InterruptModal {
3
- private inputParams;
4
- constructor(inputParams: {
5
- action: "prompt" | string;
6
- });
7
- rawResponse?: {
8
- response: string;
9
- request: {
10
- message: string;
11
- action: "prompt" | string;
12
- };
13
- };
14
- get response(): {
15
- answer?: string;
16
- };
17
- interrupt(message: string): this;
18
- isApprove(): string | undefined;
19
- isReject(): boolean;
20
- toMessages(options?: {
21
- AIAskMessage?: boolean;
22
- }): (false | HumanMessage | AIMessage | undefined)[];
23
- }
@@ -1,36 +0,0 @@
1
- import { AIMessage, HumanMessage } from "@langchain/core/messages";
2
- import { interrupt } from "@langchain/langgraph";
3
- export class InterruptModal {
4
- constructor(inputParams) {
5
- this.inputParams = inputParams;
6
- }
7
- get response() {
8
- if (!this.rawResponse)
9
- throw new Error("rawResponse is undefined");
10
- return JSON.parse(this.rawResponse.response);
11
- }
12
- interrupt(message) {
13
- const inputData = Object.assign({ message }, this.inputParams);
14
- const input = JSON.stringify(inputData);
15
- const response = interrupt(input);
16
- this.rawResponse = {
17
- request: inputData,
18
- response,
19
- };
20
- return this;
21
- }
22
- isApprove() {
23
- return this.response.answer;
24
- }
25
- isReject() {
26
- return !this.response.answer;
27
- }
28
- toMessages(options) {
29
- if (!this.rawResponse)
30
- throw new Error("rawResponse is undefined");
31
- return [
32
- (options === null || options === void 0 ? void 0 : options.AIAskMessage) && new AIMessage(this.rawResponse.request.message),
33
- new HumanMessage(this.response.answer),
34
- ].filter(Boolean);
35
- }
36
- }
@@ -1,11 +0,0 @@
1
- import { z } from "zod";
2
- import { AnnotationRoot, CompiledStateGraph } from "@langchain/langgraph";
3
- declare const METADATA_KEY_HANDOFF_DESTINATION = "__handoff_destination";
4
- interface CreateHandoffToolParams {
5
- agentName: string;
6
- description?: string;
7
- updateState?: (state: any) => Record<string, any>;
8
- }
9
- declare const createHandoffTool: ({ agentName, description, updateState }: CreateHandoffToolParams) => import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>, {}, {}, any>;
10
- declare const getHandoffDestinations: <AnnotationRootT extends AnnotationRoot<any>>(agent: CompiledStateGraph<AnnotationRootT["State"], AnnotationRootT["Update"], string, AnnotationRootT["spec"], AnnotationRootT["spec"]>, toolNodeName?: string) => string[];
11
- export { createHandoffTool, getHandoffDestinations, METADATA_KEY_HANDOFF_DESTINATION };
@@ -1,84 +0,0 @@
1
- import { z } from "zod";
2
- import { ToolMessage } from "@langchain/core/messages";
3
- import { tool } from "@langchain/core/tools";
4
- import { Command, getCurrentTaskInput, } from "@langchain/langgraph";
5
- const WHITESPACE_RE = /\s+/g;
6
- const METADATA_KEY_HANDOFF_DESTINATION = "__handoff_destination";
7
- function _normalizeAgentName(agentName) {
8
- /**
9
- * Normalize an agent name to be used inside the tool name.
10
- */
11
- return agentName.trim().replace(WHITESPACE_RE, "_").toLowerCase();
12
- }
13
- // type guard
14
- function isDynamicTool(tool) {
15
- return "schema" in tool && "name" in tool && "description" in tool && "responseFormat" in tool;
16
- }
17
- const createHandoffTool = ({ agentName, description, updateState }) => {
18
- /**
19
- * Create a tool that can handoff control to the requested agent.
20
- *
21
- * @param agentName - The name of the agent to handoff control to, i.e.
22
- * the name of the agent node in the multi-agent graph.
23
- * Agent names should be simple, clear and unique, preferably in snake_case,
24
- * although you are only limited to the names accepted by LangGraph
25
- * nodes as well as the tool names accepted by LLM providers
26
- * (the tool name will look like this: `transfer_to_<agent_name>`).
27
- * @param description - Optional description for the handoff tool.
28
- * @param updateState - Optional function to customize state updates during handoff.
29
- */
30
- const toolName = `transfer_to_${_normalizeAgentName(agentName)}`;
31
- const toolDescription = description || `Ask agent '${agentName}' for help`;
32
- const handoffTool = tool(async (_, config) => {
33
- /**
34
- * Ask another agent for help.
35
- */
36
- const toolMessage = new ToolMessage({
37
- content: `Successfully transferred to ${agentName}`,
38
- name: toolName,
39
- tool_call_id: config.toolCall.id,
40
- });
41
- // inject the current agent state
42
- const state = getCurrentTaskInput();
43
- // Base update object containing essential state updates
44
- const baseUpdate = {
45
- messages: state.messages.concat(toolMessage),
46
- activeAgent: agentName,
47
- };
48
- // Merge custom updates with base updates if updateState function is provided
49
- const finalUpdate = updateState ? { ...baseUpdate, ...updateState(state) } : baseUpdate;
50
- return new Command({
51
- goto: agentName,
52
- graph: Command.PARENT,
53
- update: finalUpdate,
54
- });
55
- }, {
56
- name: toolName,
57
- schema: z.object({}),
58
- description: toolDescription,
59
- });
60
- handoffTool.metadata = { [METADATA_KEY_HANDOFF_DESTINATION]: agentName };
61
- return handoffTool;
62
- };
63
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
- const getHandoffDestinations = (agent, toolNodeName = "tools") => {
65
- /**
66
- * Get a list of destinations from agent's handoff tools.
67
- *
68
- * @param agent - The compiled state graph
69
- * @param toolNodeName - The name of the tool node in the graph
70
- */
71
- const { nodes } = agent.getGraph();
72
- if (!(toolNodeName in nodes)) {
73
- return [];
74
- }
75
- const toolNode = nodes[toolNodeName].data;
76
- if (!toolNode || !("tools" in toolNode) || !toolNode.tools) {
77
- return [];
78
- }
79
- const { tools } = toolNode;
80
- return tools
81
- .filter((tool) => isDynamicTool(tool) && tool.metadata !== undefined && METADATA_KEY_HANDOFF_DESTINATION in tool.metadata)
82
- .map((tool) => tool.metadata[METADATA_KEY_HANDOFF_DESTINATION]);
83
- };
84
- export { createHandoffTool, getHandoffDestinations, METADATA_KEY_HANDOFF_DESTINATION };
@@ -1,6 +0,0 @@
1
- import { SwarmState } from "@langchain/langgraph-swarm";
2
- /**
3
- * 保留 langgraph-swarm 在 handoff 时丢失的 state
4
- */
5
- export declare const keepAllStateInHandOff: (state: typeof SwarmState.State) => any;
6
- export declare const createHandoffCommand: <T>(name: string, state: T) => any;
@@ -1,21 +0,0 @@
1
- import { Command } from "@langchain/langgraph";
2
- /**
3
- * 保留 langgraph-swarm 在 handoff 时丢失的 state
4
- */
5
- export const keepAllStateInHandOff = (state) => {
6
- // omit activeAgent and messages
7
- const { activeAgent, messages, ...rest } = state;
8
- return {
9
- ...rest,
10
- };
11
- };
12
- export const createHandoffCommand = (name, state) => {
13
- return new Command({
14
- goto: name,
15
- graph: Command.PARENT,
16
- update: {
17
- active_agent: name,
18
- ...state,
19
- },
20
- });
21
- };
@@ -1 +0,0 @@
1
- export * from "./sequential-thinking.js";
@@ -1 +0,0 @@
1
- export * from "./sequential-thinking.js";
@@ -1,52 +0,0 @@
1
- import { z } from "zod";
2
- export declare const SequentialThinkingTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
3
- thought: z.ZodString;
4
- nextThoughtNeeded: z.ZodBoolean;
5
- thoughtNumber: z.ZodNumber;
6
- totalThoughts: z.ZodNumber;
7
- isRevision: z.ZodOptional<z.ZodBoolean>;
8
- revisesThought: z.ZodOptional<z.ZodNumber>;
9
- branchFromThought: z.ZodOptional<z.ZodNumber>;
10
- branchId: z.ZodOptional<z.ZodString>;
11
- needsMoreThoughts: z.ZodOptional<z.ZodBoolean>;
12
- }, "strip", z.ZodTypeAny, {
13
- thought: string;
14
- nextThoughtNeeded: boolean;
15
- thoughtNumber: number;
16
- totalThoughts: number;
17
- isRevision?: boolean | undefined;
18
- revisesThought?: number | undefined;
19
- branchFromThought?: number | undefined;
20
- branchId?: string | undefined;
21
- needsMoreThoughts?: boolean | undefined;
22
- }, {
23
- thought: string;
24
- nextThoughtNeeded: boolean;
25
- thoughtNumber: number;
26
- totalThoughts: number;
27
- isRevision?: boolean | undefined;
28
- revisesThought?: number | undefined;
29
- branchFromThought?: number | undefined;
30
- branchId?: string | undefined;
31
- needsMoreThoughts?: boolean | undefined;
32
- }>, {
33
- thought: string;
34
- nextThoughtNeeded: boolean;
35
- thoughtNumber: number;
36
- totalThoughts: number;
37
- isRevision?: boolean | undefined;
38
- revisesThought?: number | undefined;
39
- branchFromThought?: number | undefined;
40
- branchId?: string | undefined;
41
- needsMoreThoughts?: boolean | undefined;
42
- }, {
43
- thought: string;
44
- nextThoughtNeeded: boolean;
45
- thoughtNumber: number;
46
- totalThoughts: number;
47
- isRevision?: boolean | undefined;
48
- revisesThought?: number | undefined;
49
- branchFromThought?: number | undefined;
50
- branchId?: string | undefined;
51
- needsMoreThoughts?: boolean | undefined;
52
- }, string>;
@@ -1,69 +0,0 @@
1
- import { tool } from "@langchain/core/tools";
2
- import { z } from "zod";
3
- const schema = z.object({
4
- thought: z.string().describe("Your current thinking step"),
5
- nextThoughtNeeded: z.boolean().describe("Whether another thought step is needed"),
6
- thoughtNumber: z.number().min(1).describe("Current thought number"),
7
- totalThoughts: z.number().min(1).describe("Estimated total thoughts needed"),
8
- isRevision: z.boolean().optional().describe("Whether this revises previous thinking"),
9
- revisesThought: z.number().min(1).optional().describe("Which thought is being reconsidered"),
10
- branchFromThought: z.number().min(1).optional().describe("Branching point thought number"),
11
- branchId: z.string().optional().describe("Branch identifier"),
12
- needsMoreThoughts: z.boolean().optional().describe("If more thoughts are needed"),
13
- });
14
- // 存储思考历史
15
- const thoughtHistory = [];
16
- const branches = {};
17
- export const SequentialThinkingTool = tool(async (args) => {
18
- try {
19
- if (args.thoughtNumber > args.totalThoughts) {
20
- args.totalThoughts = args.thoughtNumber;
21
- }
22
- thoughtHistory.push(args);
23
- if (args.branchFromThought && args.branchId) {
24
- if (!branches[args.branchId]) {
25
- branches[args.branchId] = [];
26
- }
27
- branches[args.branchId].push(args);
28
- }
29
- return JSON.stringify({
30
- thoughtNumber: args.thoughtNumber,
31
- totalThoughts: args.totalThoughts,
32
- nextThoughtNeeded: args.nextThoughtNeeded,
33
- branches: Object.keys(branches),
34
- thoughtHistoryLength: thoughtHistory.length,
35
- }, null, 2);
36
- }
37
- catch (error) {
38
- return JSON.stringify({
39
- error: error instanceof Error ? error.message : String(error),
40
- status: "failed",
41
- }, null, 2);
42
- }
43
- }, {
44
- name: "sequential-thinking",
45
- description: `A detailed tool for dynamic and reflective problem-solving through thoughts.
46
- This tool helps analyze problems through a flexible thinking process that can adapt and evolve.
47
- Each thought can build on, question, or revise previous insights as understanding deepens.
48
-
49
- When to use this tool:
50
- - Breaking down complex problems into steps
51
- - Planning and design with room for revision
52
- - Analysis that might need course correction
53
- - Problems where the full scope might not be clear initially
54
- - Problems that require a multi-step solution
55
- - Tasks that need to maintain context over multiple steps
56
- - Situations where irrelevant information needs to be filtered out
57
-
58
- Key features:
59
- - You can adjust total_thoughts up or down as you progress
60
- - You can question or revise previous thoughts
61
- - You can add more thoughts even after reaching what seemed like the end
62
- - You can express uncertainty and explore alternative approaches
63
- - Not every thought needs to build linearly - you can branch or backtrack
64
- - Generates a solution hypothesis
65
- - Verifies the hypothesis based on the Chain of Thought steps
66
- - Repeats the process until satisfied
67
- - Provides a correct answer`,
68
- schema,
69
- });
@@ -1,3 +0,0 @@
1
- import { BaseMessage, HumanMessage } from "@langchain/core/messages";
2
- export declare const getTextMessageContent: (message: BaseMessage) => string;
3
- export declare function getLastHumanMessage(messages: BaseMessage[]): HumanMessage | undefined;
@@ -1,24 +0,0 @@
1
- import { isHumanMessage } from "@langchain/core/messages";
2
- export const getTextMessageContent = (message) => {
3
- if (typeof message.content === "string") {
4
- return message.content;
5
- }
6
- else {
7
- return message.content
8
- .filter((i) => i.type === "text")
9
- .map((i) => i.text)
10
- .join("\n");
11
- }
12
- };
13
- export function getLastHumanMessage(messages) {
14
- // 从后往前遍历消息列表
15
- for (let i = messages.length - 1; i >= 0; i--) {
16
- const message = messages[i];
17
- // 检查消息是否是 HumanMessage 的实例
18
- if (isHumanMessage(message)) {
19
- return message;
20
- }
21
- }
22
- // 如果没有找到 HumanMessage,则返回 undefined
23
- return undefined;
24
- }
@@ -1 +0,0 @@
1
- export {};
package/dist/test-type.js DELETED
@@ -1,5 +0,0 @@
1
- const t = {
2
- type: "tool",
3
- tool_call_id: "123"
4
- };
5
- export {};
package/dist/types.d.ts DELETED
@@ -1,106 +0,0 @@
1
- import { Thread, Assistant, Run, StreamMode, Command, Metadata, AssistantGraph, OnConflictBehavior, ThreadStatus, ValuesStreamEvent, UpdatesStreamEvent, DebugStreamEvent, MessagesStreamEvent, MessagesTupleStreamEvent, CustomStreamEvent, EventsStreamEvent, ErrorStreamEvent, MetadataStreamEvent, FeedbackStreamEvent, Config, Checkpoint } from "@langchain/langgraph-sdk";
2
- import { StreamEvent } from "@langchain/core/tracers/log_stream";
3
- export type AssistantSortBy = "assistant_id" | "graph_id" | "name" | "created_at" | "updated_at";
4
- export type ThreadSortBy = "thread_id" | "status" | "created_at" | "updated_at";
5
- export type SortOrder = "asc" | "desc";
6
- export type RunStatus = "pending" | "running" | "error" | "success" | "timeout" | "interrupted";
7
- export type MultitaskStrategy = "reject" | "interrupt" | "rollback" | "enqueue";
8
- export type DisconnectMode = "cancel" | "continue";
9
- export type OnCompletionBehavior = "complete" | "continue";
10
- export type CancelAction = "interrupt" | "rollback";
11
- export type TypedAsyncGenerator<TStateType = unknown, TUpdateType = TStateType, TCustomType = unknown> = AsyncGenerator<{
12
- values: ValuesStreamEvent<TStateType>;
13
- updates: UpdatesStreamEvent<TUpdateType>;
14
- custom: CustomStreamEvent<TCustomType>;
15
- debug: DebugStreamEvent;
16
- messages: MessagesStreamEvent;
17
- "messages-tuple": MessagesTupleStreamEvent;
18
- events: EventsStreamEvent;
19
- }[StreamMode] | ErrorStreamEvent | MetadataStreamEvent | FeedbackStreamEvent>;
20
- /**
21
- * 兼容 LangGraph SDK 的接口定义,方便进行无侵入式的扩展
22
- */
23
- export interface ILangGraphClient<TStateType = {}, TUpdateType = TStateType> {
24
- assistants: {
25
- search(query?: {
26
- graphId?: string;
27
- metadata?: Metadata;
28
- limit?: number;
29
- offset?: number;
30
- sortBy?: AssistantSortBy;
31
- sortOrder?: SortOrder;
32
- }): Promise<Assistant[]>;
33
- getGraph(assistantId: string, options?: {
34
- xray?: boolean | number;
35
- }): Promise<AssistantGraph>;
36
- };
37
- threads: {
38
- create(payload?: {
39
- metadata?: Metadata;
40
- threadId?: string;
41
- ifExists?: OnConflictBehavior;
42
- graphId?: string;
43
- supersteps?: Array<{
44
- updates: Array<{
45
- values: unknown;
46
- command?: Command;
47
- asNode: string;
48
- }>;
49
- }>;
50
- }): Promise<Thread<TStateType>>;
51
- search(query?: {
52
- metadata?: Metadata;
53
- limit?: number;
54
- offset?: number;
55
- status?: ThreadStatus;
56
- sortBy?: ThreadSortBy;
57
- sortOrder?: SortOrder;
58
- }): Promise<Thread<TStateType>[]>;
59
- get(threadId: string): Promise<Thread<TStateType>>;
60
- delete(threadId: string): Promise<void>;
61
- };
62
- runs: {
63
- list(threadId: string, options?: {
64
- limit?: number;
65
- offset?: number;
66
- status?: RunStatus;
67
- }): Promise<Run[]>;
68
- stream<TSubgraphs extends boolean = false>(threadId: string, assistantId: string, payload?: {
69
- input?: Record<string, unknown> | null;
70
- metadata?: Metadata;
71
- config?: Config;
72
- checkpointId?: string;
73
- checkpoint?: Omit<Checkpoint, "thread_id">;
74
- checkpointDuring?: boolean;
75
- interruptBefore?: "*" | string[];
76
- interruptAfter?: "*" | string[];
77
- multitaskStrategy?: MultitaskStrategy;
78
- onCompletion?: OnCompletionBehavior;
79
- signal?: AbortController["signal"];
80
- webhook?: string;
81
- onDisconnect?: DisconnectMode;
82
- afterSeconds?: number;
83
- ifNotExists?: "create" | "reject";
84
- command?: Command;
85
- onRunCreated?: (params: {
86
- run_id: string;
87
- thread_id?: string;
88
- }) => void;
89
- streamMode?: StreamMode[];
90
- streamSubgraphs?: TSubgraphs;
91
- streamResumable?: boolean;
92
- feedbackKeys?: string[];
93
- }): TypedAsyncGenerator<TSubgraphs, TStateType, TUpdateType>;
94
- joinStream(threadId: string, runId: string, options?: {
95
- signal?: AbortSignal;
96
- cancelOnDisconnect?: boolean;
97
- lastEventId?: string;
98
- streamMode?: StreamMode | StreamMode[];
99
- } | AbortSignal): AsyncGenerator<{
100
- id?: string;
101
- event: StreamEvent;
102
- data: any;
103
- }>;
104
- cancel(threadId: string, runId: string, wait?: boolean, action?: CancelAction): Promise<void>;
105
- };
106
- }
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,6 +0,0 @@
1
- /**
2
- * Creates a debounced function that executes once per animation frame
3
- * @param callback - The function to debounce
4
- * @returns A function that executes the callback on the next animation frame
5
- */
6
- export declare function rafDebounce<T extends (...args: any[]) => any>(callback: T): (...args: Parameters<T>) => void;
@@ -1,26 +0,0 @@
1
- /**
2
- * Creates a debounced function that executes once per animation frame
3
- * @param callback - The function to debounce
4
- * @returns A function that executes the callback on the next animation frame
5
- */
6
- export function rafDebounce(callback) {
7
- let rafId = null;
8
- let lastArgs = null;
9
- // Return the debounced function
10
- return function (...args) {
11
- // Store the most recent arguments
12
- lastArgs = args;
13
- // Cancel any pending animation frame
14
- if (rafId !== null) {
15
- cancelAnimationFrame(rafId);
16
- }
17
- // Schedule execution on the next animation frame
18
- rafId = requestAnimationFrame(() => {
19
- if (lastArgs !== null) {
20
- callback(...lastArgs);
21
- lastArgs = null;
22
- }
23
- rafId = null;
24
- });
25
- };
26
- }