@langgraph-js/sdk 2.0.1 → 3.0.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/README.md +93 -34
- package/dist/LangGraphClient.d.ts +24 -63
- package/dist/LangGraphClient.js +16 -3
- package/dist/TestKit.d.ts +95 -4
- package/dist/client/LanggraphServer.d.ts +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/react/ChatContext.d.ts +61 -0
- package/dist/react/ChatContext.js +49 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/time-travel/index.d.ts +11 -0
- package/dist/time-travel/index.js +30 -0
- package/dist/types.d.ts +1 -1
- package/dist/ui-store/createChatStore.d.ts +8 -3
- package/dist/ui-store/createChatStore.js +33 -6
- package/dist/vue/ChatContext.d.ts +161 -0
- package/dist/vue/ChatContext.js +121 -0
- package/dist/vue/index.d.ts +1 -0
- package/dist/vue/index.js +1 -0
- package/package.json +43 -3
- package/src/LangGraphClient.ts +21 -12
- package/src/client/LanggraphServer.ts +2 -2
- package/src/index.ts +0 -1
- package/src/react/ChatContext.ts +81 -0
- package/src/react/index.ts +1 -0
- package/src/time-travel/index.ts +32 -0
- package/src/ui-store/createChatStore.ts +27 -7
- package/src/vue/ChatContext.ts +161 -0
- package/src/vue/index.ts +1 -0
- package/src/types.ts +0 -129
package/README.md
CHANGED
|
@@ -97,40 +97,10 @@ First, install the nanostores React integration:
|
|
|
97
97
|
pnpm i @nanostores/react
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
Then
|
|
100
|
+
Then use the ChatProvider in your components:
|
|
101
101
|
|
|
102
102
|
```tsx
|
|
103
|
-
import
|
|
104
|
-
import { globalChatStore } from "../store"; // Import your store
|
|
105
|
-
import { UnionStore, useUnionStore } from "@langgraph-js/sdk";
|
|
106
|
-
import { useStore } from "@nanostores/react";
|
|
107
|
-
|
|
108
|
-
type ChatContextType = UnionStore<typeof globalChatStore>;
|
|
109
|
-
|
|
110
|
-
const ChatContext = createContext<ChatContextType | undefined>(undefined);
|
|
111
|
-
|
|
112
|
-
export const useChat = () => {
|
|
113
|
-
const context = useContext(ChatContext);
|
|
114
|
-
if (!context) {
|
|
115
|
-
throw new Error("useChat must be used within a ChatProvider");
|
|
116
|
-
}
|
|
117
|
-
return context;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export const ChatProvider = ({ children }) => {
|
|
121
|
-
// Use store to ensure React gets reactive state updates
|
|
122
|
-
const store = useUnionStore(globalChatStore, useStore);
|
|
123
|
-
|
|
124
|
-
useEffect(() => {
|
|
125
|
-
// Initialize client
|
|
126
|
-
store.initClient().then(() => {
|
|
127
|
-
// Initialize conversation history
|
|
128
|
-
store.refreshHistoryList();
|
|
129
|
-
});
|
|
130
|
-
}, [store.currentAgent]);
|
|
131
|
-
|
|
132
|
-
return <ChatContext.Provider value={store}>{children}</ChatContext.Provider>;
|
|
133
|
-
};
|
|
103
|
+
import { ChatProvider, useChat } from "@langgraph-js/sdk/react";
|
|
134
104
|
```
|
|
135
105
|
|
|
136
106
|
Use it in your components:
|
|
@@ -138,8 +108,19 @@ Use it in your components:
|
|
|
138
108
|
```tsx
|
|
139
109
|
export const MyChat = () => {
|
|
140
110
|
return (
|
|
141
|
-
<ChatProvider
|
|
142
|
-
|
|
111
|
+
<ChatProvider
|
|
112
|
+
defaultAgent="agent"
|
|
113
|
+
apiUrl="http://localhost:8123"
|
|
114
|
+
defaultHeaders={{}}
|
|
115
|
+
withCredentials={false}
|
|
116
|
+
showHistory={true}
|
|
117
|
+
showGraph={false}
|
|
118
|
+
onInitError={(error, currentAgent) => {
|
|
119
|
+
console.error(`Failed to initialize ${currentAgent}:`, error);
|
|
120
|
+
// Handle initialization error
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
<ChatComp />
|
|
143
124
|
</ChatProvider>
|
|
144
125
|
);
|
|
145
126
|
};
|
|
@@ -150,6 +131,84 @@ function ChatComp() {
|
|
|
150
131
|
}
|
|
151
132
|
```
|
|
152
133
|
|
|
134
|
+
### Vue Integration
|
|
135
|
+
|
|
136
|
+
First, install the nanostores Vue integration:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pnpm i @nanostores/vue
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Then use the ChatProvider in your components:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { ChatProvider, useChat, useChatProvider } from "@langgraph-js/sdk/vue";
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Option 1: Using ChatProvider Component
|
|
149
|
+
|
|
150
|
+
Use it in your components:
|
|
151
|
+
|
|
152
|
+
```vue
|
|
153
|
+
<template>
|
|
154
|
+
<ChatProvider
|
|
155
|
+
:default-agent="'agent'"
|
|
156
|
+
:api-url="'http://localhost:8123'"
|
|
157
|
+
:default-headers="{}"
|
|
158
|
+
:with-credentials="false"
|
|
159
|
+
:show-history="true"
|
|
160
|
+
:show-graph="false"
|
|
161
|
+
:on-init-error="
|
|
162
|
+
(error, currentAgent) => {
|
|
163
|
+
console.error(`Failed to initialize ${currentAgent}:`, error);
|
|
164
|
+
// Handle initialization error
|
|
165
|
+
}
|
|
166
|
+
"
|
|
167
|
+
>
|
|
168
|
+
<ChatComp />
|
|
169
|
+
</ChatProvider>
|
|
170
|
+
</template>
|
|
171
|
+
|
|
172
|
+
<script setup lang="ts">
|
|
173
|
+
import { ChatProvider } from "@langgraph-js/sdk/vue";
|
|
174
|
+
|
|
175
|
+
function ChatComp() {
|
|
176
|
+
const chat = useChat();
|
|
177
|
+
// Use chat store methods and state here
|
|
178
|
+
}
|
|
179
|
+
</script>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### Option 2: Using useChatProvider Hook Directly
|
|
183
|
+
|
|
184
|
+
For more flexibility, you can use the hook directly in your setup:
|
|
185
|
+
|
|
186
|
+
```vue
|
|
187
|
+
<script setup lang="ts">
|
|
188
|
+
import { useChatProvider } from "@langgraph-js/sdk/vue";
|
|
189
|
+
|
|
190
|
+
const props = {
|
|
191
|
+
defaultAgent: "agent",
|
|
192
|
+
apiUrl: "http://localhost:8123",
|
|
193
|
+
defaultHeaders: {},
|
|
194
|
+
withCredentials: false,
|
|
195
|
+
showHistory: true,
|
|
196
|
+
showGraph: false,
|
|
197
|
+
onInitError: (error: any, currentAgent: string) => {
|
|
198
|
+
console.error(`Failed to initialize ${currentAgent}:`, error);
|
|
199
|
+
// Handle initialization error
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const { unionStore } = useChatProvider(props);
|
|
204
|
+
// Use unionStore methods and state here
|
|
205
|
+
</script>
|
|
206
|
+
|
|
207
|
+
<template>
|
|
208
|
+
<ChatComp />
|
|
209
|
+
</template>
|
|
210
|
+
```
|
|
211
|
+
|
|
153
212
|
## Documentation
|
|
154
213
|
|
|
155
214
|
For complete documentation, visit our [official docs](https://langgraph-js.netlify.app).
|
|
@@ -2,7 +2,7 @@ import type { Thread, Message, Assistant, Command } from "@langchain/langgraph-s
|
|
|
2
2
|
import { EventEmitter } from "eventemitter3";
|
|
3
3
|
import { ToolManager } from "./ToolManager.js";
|
|
4
4
|
import { CallToolResult } from "./tool/createTool.js";
|
|
5
|
-
import { ILangGraphClient } from "
|
|
5
|
+
import { type ILangGraphClient } from "@langgraph-js/pure-graph/dist/types.js";
|
|
6
6
|
export type RenderMessage = Message & {
|
|
7
7
|
/** 对于 AIMessage 来说是节点名称,对于工具节点来说是工具名称 */
|
|
8
8
|
name?: string;
|
|
@@ -68,7 +68,7 @@ export interface LangGraphClientConfig {
|
|
|
68
68
|
timeoutMs?: number;
|
|
69
69
|
defaultHeaders?: Record<string, string | null | undefined>;
|
|
70
70
|
/** 自定义客户端实现,如果不提供则使用官方 Client */
|
|
71
|
-
client: ILangGraphClient<any
|
|
71
|
+
client: ILangGraphClient<any>;
|
|
72
72
|
}
|
|
73
73
|
export interface LangGraphEvents {
|
|
74
74
|
/** 流开始事件 */
|
|
@@ -108,7 +108,7 @@ export interface LangGraphEvents {
|
|
|
108
108
|
* @zh LangGraphClient 类是与 LangGraph 后端交互的主要客户端。
|
|
109
109
|
* @en The LangGraphClient class is the main client for interacting with the LangGraph backend.
|
|
110
110
|
*/
|
|
111
|
-
export declare class LangGraphClient<TStateType = unknown
|
|
111
|
+
export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGraphEvents> {
|
|
112
112
|
private client;
|
|
113
113
|
private currentAssistant;
|
|
114
114
|
private currentThread;
|
|
@@ -128,11 +128,15 @@ export declare class LangGraphClient<TStateType = unknown, TUpdateType = TStateT
|
|
|
128
128
|
get assistants(): {
|
|
129
129
|
search(query?: {
|
|
130
130
|
graphId?: string;
|
|
131
|
-
metadata
|
|
131
|
+
metadata? /**
|
|
132
|
+
* Specify a custom fetch implementation.
|
|
133
|
+
*
|
|
134
|
+
* By default we expect the `fetch` is available in the global scope.
|
|
135
|
+
*/: import("@langchain/langgraph-sdk").Metadata;
|
|
132
136
|
limit?: number;
|
|
133
137
|
offset?: number;
|
|
134
|
-
sortBy?: import("
|
|
135
|
-
sortOrder?: import("
|
|
138
|
+
sortBy?: import("@langgraph-js/pure-graph/dist/types.js").AssistantSortBy;
|
|
139
|
+
sortOrder?: import("@langgraph-js/pure-graph/dist/types.js").SortOrder;
|
|
136
140
|
}): Promise<Assistant[]>;
|
|
137
141
|
getGraph(assistantId: string, options?: {
|
|
138
142
|
xray?: boolean | number;
|
|
@@ -145,72 +149,21 @@ export declare class LangGraphClient<TStateType = unknown, TUpdateType = TStateT
|
|
|
145
149
|
threadId?: string;
|
|
146
150
|
ifExists?: import("@langchain/langgraph-sdk").OnConflictBehavior;
|
|
147
151
|
graphId?: string;
|
|
148
|
-
supersteps?: Array<{
|
|
149
|
-
updates: Array<{
|
|
150
|
-
values: unknown;
|
|
151
|
-
command? /** 值更新事件 */: Command;
|
|
152
|
-
asNode: string;
|
|
153
|
-
}>;
|
|
154
|
-
}>;
|
|
155
152
|
}): Promise<Thread<TStateType>>;
|
|
156
153
|
search(query?: {
|
|
157
|
-
metadata
|
|
158
|
-
/** Thread 创建事件 */
|
|
159
|
-
? /** Thread 创建事件 */: import("@langchain/langgraph-sdk").Metadata;
|
|
154
|
+
metadata?: import("@langchain/langgraph-sdk").Metadata;
|
|
160
155
|
limit?: number;
|
|
161
156
|
offset?: number;
|
|
162
157
|
status?: import("@langchain/langgraph-sdk").ThreadStatus;
|
|
163
|
-
sortBy?: import("
|
|
164
|
-
sortOrder?: import("
|
|
158
|
+
sortBy?: import("@langgraph-js/pure-graph/dist/types.js").ThreadSortBy;
|
|
159
|
+
sortOrder?: import("@langgraph-js/pure-graph/dist/types.js").SortOrder;
|
|
165
160
|
}): Promise<Thread<TStateType>[]>;
|
|
166
161
|
get(threadId: string): Promise<Thread<TStateType>>;
|
|
167
162
|
delete(threadId: string): Promise<void>;
|
|
163
|
+
updateState(threadId: string, thread: Partial<Thread<TStateType>>): Promise<Pick<import("@langchain/langgraph-sdk").Config, "configurable">>;
|
|
168
164
|
};
|
|
169
165
|
/** 代理 runs 属性到内部 client */
|
|
170
|
-
get runs():
|
|
171
|
-
list(threadId: string, options?: {
|
|
172
|
-
limit?: number;
|
|
173
|
-
offset?: number;
|
|
174
|
-
status?: import("./types.js").RunStatus;
|
|
175
|
-
}): Promise<import("@langchain/langgraph-sdk").Run[]>;
|
|
176
|
-
stream<TSubgraphs extends boolean = false>(threadId: string, assistantId: string, payload?: {
|
|
177
|
-
input?: Record<string, unknown> | null;
|
|
178
|
-
metadata?: import("@langchain/langgraph-sdk").Metadata;
|
|
179
|
-
config?: import("@langchain/langgraph-sdk").Config;
|
|
180
|
-
checkpointId?: string;
|
|
181
|
-
checkpoint?: Omit<import("@langchain/langgraph-sdk").Checkpoint, "thread_id">;
|
|
182
|
-
checkpointDuring?: boolean;
|
|
183
|
-
interruptBefore?: "*" | string[];
|
|
184
|
-
interruptAfter?: "*" | string[];
|
|
185
|
-
multitaskStrategy?: import("./types.js").MultitaskStrategy;
|
|
186
|
-
onCompletion?: import("./types.js").OnCompletionBehavior;
|
|
187
|
-
signal?: AbortController["signal"];
|
|
188
|
-
webhook?: string;
|
|
189
|
-
onDisconnect?: import("./types.js").DisconnectMode;
|
|
190
|
-
afterSeconds?: number;
|
|
191
|
-
ifNotExists?: "create" | "reject";
|
|
192
|
-
command?: Command;
|
|
193
|
-
onRunCreated?: (params: {
|
|
194
|
-
run_id: string;
|
|
195
|
-
thread_id?: string;
|
|
196
|
-
}) => void;
|
|
197
|
-
streamMode?: import("@langchain/langgraph-sdk").StreamMode[];
|
|
198
|
-
streamSubgraphs?: TSubgraphs | undefined;
|
|
199
|
-
streamResumable?: boolean;
|
|
200
|
-
feedbackKeys?: string[];
|
|
201
|
-
} | undefined): import("./types.js").TypedAsyncGenerator<TSubgraphs, TStateType, TUpdateType>;
|
|
202
|
-
joinStream(threadId: string, runId: string, options?: {
|
|
203
|
-
signal?: AbortSignal;
|
|
204
|
-
cancelOnDisconnect?: boolean;
|
|
205
|
-
lastEventId?: string;
|
|
206
|
-
streamMode?: import("@langchain/langgraph-sdk").StreamMode | import("@langchain/langgraph-sdk").StreamMode[];
|
|
207
|
-
} | AbortSignal): AsyncGenerator<{
|
|
208
|
-
id?: string;
|
|
209
|
-
event: import("@langchain/core/tracers/log_stream").StreamEvent;
|
|
210
|
-
data: any;
|
|
211
|
-
}>;
|
|
212
|
-
cancel(threadId: string, runId: string, wait?: boolean, action?: import("./types.js").CancelAction): Promise<void>;
|
|
213
|
-
};
|
|
166
|
+
get runs(): ILangGraphClient["runs"];
|
|
214
167
|
private listAssistants;
|
|
215
168
|
/**
|
|
216
169
|
* @zh 初始化 Assistant。
|
|
@@ -221,8 +174,9 @@ export declare class LangGraphClient<TStateType = unknown, TUpdateType = TStateT
|
|
|
221
174
|
* @zh 创建一个新的 Thread。
|
|
222
175
|
* @en Creates a new Thread.
|
|
223
176
|
*/
|
|
224
|
-
createThread({ threadId, }?: {
|
|
177
|
+
createThread({ threadId, graphId }?: {
|
|
225
178
|
threadId?: string;
|
|
179
|
+
graphId?: string;
|
|
226
180
|
}): Promise<Thread<TStateType>>;
|
|
227
181
|
graphVisualize(): Promise<import("@langchain/langgraph-sdk").AssistantGraph>;
|
|
228
182
|
/**
|
|
@@ -259,6 +213,13 @@ export declare class LangGraphClient<TStateType = unknown, TUpdateType = TStateT
|
|
|
259
213
|
* @en Cancels the current Run.
|
|
260
214
|
*/
|
|
261
215
|
cancelRun(): void;
|
|
216
|
+
/**
|
|
217
|
+
* @zh 回滚到指定的消息。但是不会触发数据的重新更新
|
|
218
|
+
* @en Reverts to the specified message.
|
|
219
|
+
*/
|
|
220
|
+
revertChatTo(messageId: string): Promise<{
|
|
221
|
+
messages: Message[];
|
|
222
|
+
}>;
|
|
262
223
|
/**
|
|
263
224
|
* @zh 发送消息到 LangGraph 后端。
|
|
264
225
|
* @en Sends a message to the LangGraph backend.
|
package/dist/LangGraphClient.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
import { ToolManager } from "./ToolManager.js";
|
|
3
3
|
import { MessageProcessor } from "./MessageProcessor.js";
|
|
4
|
+
import { revertChatTo } from "./time-travel/index.js";
|
|
4
5
|
/**
|
|
5
6
|
* @zh LangGraphClient 类是与 LangGraph 后端交互的主要客户端。
|
|
6
7
|
* @en The LangGraphClient class is the main client for interacting with the LangGraph backend.
|
|
@@ -73,10 +74,11 @@ export class LangGraphClient extends EventEmitter {
|
|
|
73
74
|
* @zh 创建一个新的 Thread。
|
|
74
75
|
* @en Creates a new Thread.
|
|
75
76
|
*/
|
|
76
|
-
async createThread({ threadId, } = {}) {
|
|
77
|
+
async createThread({ threadId, graphId } = {}) {
|
|
77
78
|
try {
|
|
78
79
|
this.currentThread = await this.threads.create({
|
|
79
80
|
threadId,
|
|
81
|
+
graphId,
|
|
80
82
|
});
|
|
81
83
|
return this.currentThread;
|
|
82
84
|
}
|
|
@@ -185,6 +187,17 @@ export class LangGraphClient extends EventEmitter {
|
|
|
185
187
|
this.runs.cancel(this.currentThread.thread_id, this.currentRun.run_id);
|
|
186
188
|
}
|
|
187
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* @zh 回滚到指定的消息。但是不会触发数据的重新更新
|
|
192
|
+
* @en Reverts to the specified message.
|
|
193
|
+
*/
|
|
194
|
+
async revertChatTo(messageId) {
|
|
195
|
+
const { state, checkpoint } = await revertChatTo(this.client, this.currentThread.thread_id, messageId);
|
|
196
|
+
this.graphState = state;
|
|
197
|
+
this.messageProcessor.clearStreamingMessages();
|
|
198
|
+
this.messageProcessor.setGraphMessages(state.messages);
|
|
199
|
+
return state;
|
|
200
|
+
}
|
|
188
201
|
/**
|
|
189
202
|
* @zh 发送消息到 LangGraph 后端。
|
|
190
203
|
* @en Sends a message to the LangGraph backend.
|
|
@@ -195,7 +208,7 @@ export class LangGraphClient extends EventEmitter {
|
|
|
195
208
|
throw new Error("Thread or Assistant not initialized");
|
|
196
209
|
}
|
|
197
210
|
if (!this.currentThread) {
|
|
198
|
-
await this.createThread();
|
|
211
|
+
await this.createThread({ graphId: this.currentAssistant.graph_id, threadId: this.currentThread.thread_id });
|
|
199
212
|
this.emit("thread", {
|
|
200
213
|
event: "thread/create",
|
|
201
214
|
data: {
|
|
@@ -241,7 +254,7 @@ export class LangGraphClient extends EventEmitter {
|
|
|
241
254
|
if (chunk.event === "metadata") {
|
|
242
255
|
this.currentRun = chunk.data;
|
|
243
256
|
}
|
|
244
|
-
else if (chunk.event === "error") {
|
|
257
|
+
else if (chunk.event === "error" || chunk.event === "Error" || chunk.event === "__stream_error__") {
|
|
245
258
|
this.emit("error", chunk);
|
|
246
259
|
}
|
|
247
260
|
else if (chunk.event === "messages/partial") {
|
package/dist/TestKit.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ export declare class TestLangGraphChat {
|
|
|
89
89
|
* @zh 准备测试环境,初始化客户端连接
|
|
90
90
|
* @en Prepare test environment, initialize client connection
|
|
91
91
|
*/
|
|
92
|
-
ready(): Promise<import("./LangGraphClient.js").LangGraphClient<unknown
|
|
92
|
+
ready(): Promise<import("./LangGraphClient.js").LangGraphClient<unknown>> | undefined;
|
|
93
93
|
/**
|
|
94
94
|
* @zh 模拟人类输入消息并等待测试任务完成,这是测试的核心方法
|
|
95
95
|
* @en Simulate human input and wait for test tasks to complete, this is the core test method
|
|
@@ -146,7 +146,27 @@ export declare class TestLangGraphChat {
|
|
|
146
146
|
*/
|
|
147
147
|
findLast(type: "human" | "ai" | "tool", options?: {
|
|
148
148
|
before?: (item: RenderMessage) => boolean;
|
|
149
|
-
}): (
|
|
149
|
+
}): ({
|
|
150
|
+
additional_kwargs?: {
|
|
151
|
+
[x: string]: unknown;
|
|
152
|
+
} | undefined;
|
|
153
|
+
content: string | ({
|
|
154
|
+
type: "text";
|
|
155
|
+
text: string;
|
|
156
|
+
} | {
|
|
157
|
+
type: "image_url";
|
|
158
|
+
image_url: string | {
|
|
159
|
+
url: string;
|
|
160
|
+
detail?: ("auto" | "low" | "high") | undefined;
|
|
161
|
+
};
|
|
162
|
+
})[];
|
|
163
|
+
id?: string | undefined;
|
|
164
|
+
name?: string | undefined;
|
|
165
|
+
response_metadata?: Record<string, unknown> | undefined;
|
|
166
|
+
} & {
|
|
167
|
+
type: "human";
|
|
168
|
+
example?: boolean | undefined;
|
|
169
|
+
} & {
|
|
150
170
|
name?: string;
|
|
151
171
|
node_name?: string;
|
|
152
172
|
tool_input?: string;
|
|
@@ -171,7 +191,56 @@ export declare class TestLangGraphChat {
|
|
|
171
191
|
spend_time?: number;
|
|
172
192
|
unique_id?: string;
|
|
173
193
|
done?: boolean;
|
|
174
|
-
}) | (
|
|
194
|
+
}) | ({
|
|
195
|
+
additional_kwargs?: {
|
|
196
|
+
[x: string]: unknown;
|
|
197
|
+
} | undefined;
|
|
198
|
+
content: string | ({
|
|
199
|
+
type: "text";
|
|
200
|
+
text: string;
|
|
201
|
+
} | {
|
|
202
|
+
type: "image_url";
|
|
203
|
+
image_url: string | {
|
|
204
|
+
url: string;
|
|
205
|
+
detail?: ("auto" | "low" | "high") | undefined;
|
|
206
|
+
};
|
|
207
|
+
})[];
|
|
208
|
+
id?: string | undefined;
|
|
209
|
+
name?: string | undefined;
|
|
210
|
+
response_metadata?: Record<string, unknown> | undefined;
|
|
211
|
+
} & {
|
|
212
|
+
type: "ai";
|
|
213
|
+
example?: boolean | undefined;
|
|
214
|
+
tool_calls?: {
|
|
215
|
+
name: string;
|
|
216
|
+
args: {
|
|
217
|
+
[x: string]: any;
|
|
218
|
+
};
|
|
219
|
+
id?: string | undefined;
|
|
220
|
+
type?: "tool_call" | undefined;
|
|
221
|
+
}[] | undefined;
|
|
222
|
+
invalid_tool_calls?: {
|
|
223
|
+
name?: string | undefined;
|
|
224
|
+
args?: string | undefined;
|
|
225
|
+
id?: string | undefined;
|
|
226
|
+
error?: string | undefined;
|
|
227
|
+
type?: "invalid_tool_call" | undefined;
|
|
228
|
+
}[] | undefined;
|
|
229
|
+
usage_metadata?: {
|
|
230
|
+
input_tokens: number;
|
|
231
|
+
output_tokens: number;
|
|
232
|
+
total_tokens: number;
|
|
233
|
+
input_token_details?: {
|
|
234
|
+
audio?: number | undefined;
|
|
235
|
+
cache_read?: number | undefined;
|
|
236
|
+
cache_creation?: number | undefined;
|
|
237
|
+
} | undefined;
|
|
238
|
+
output_token_details?: {
|
|
239
|
+
audio?: number | undefined;
|
|
240
|
+
reasoning?: number | undefined;
|
|
241
|
+
} | undefined;
|
|
242
|
+
} | undefined;
|
|
243
|
+
} & {
|
|
175
244
|
name?: string;
|
|
176
245
|
node_name?: string;
|
|
177
246
|
tool_input?: string;
|
|
@@ -196,7 +265,29 @@ export declare class TestLangGraphChat {
|
|
|
196
265
|
spend_time?: number;
|
|
197
266
|
unique_id?: string;
|
|
198
267
|
done?: boolean;
|
|
199
|
-
}) | (
|
|
268
|
+
}) | ({
|
|
269
|
+
additional_kwargs?: {
|
|
270
|
+
[x: string]: unknown;
|
|
271
|
+
} | undefined;
|
|
272
|
+
content: string | ({
|
|
273
|
+
type: "text";
|
|
274
|
+
text: string;
|
|
275
|
+
} | {
|
|
276
|
+
type: "image_url";
|
|
277
|
+
image_url: string | {
|
|
278
|
+
url: string;
|
|
279
|
+
detail?: ("auto" | "low" | "high") | undefined;
|
|
280
|
+
};
|
|
281
|
+
})[];
|
|
282
|
+
id?: string | undefined;
|
|
283
|
+
name?: string | undefined;
|
|
284
|
+
response_metadata?: Record<string, unknown> | undefined;
|
|
285
|
+
} & {
|
|
286
|
+
type: "tool";
|
|
287
|
+
status?: "error" | "success" | undefined;
|
|
288
|
+
tool_call_id: string;
|
|
289
|
+
artifact?: any;
|
|
290
|
+
} & {
|
|
200
291
|
name?: string;
|
|
201
292
|
node_name?: string;
|
|
202
293
|
tool_input?: string;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { LangGraphClientConfig } from "../LangGraphClient.js";
|
|
2
|
-
import { ILangGraphClient } from "
|
|
2
|
+
import { type ILangGraphClient } from "@langgraph-js/pure-graph/dist/types.js";
|
|
3
3
|
export declare const createLangGraphServerClient: (config: LangGraphClientConfig) => Promise<ILangGraphClient>;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { UnionStore } from "../ui-store/index.js";
|
|
3
|
+
export declare const useChat: () => UnionStore<{
|
|
4
|
+
data: {
|
|
5
|
+
client: import("nanostores").PreinitializedWritableAtom<import("../LangGraphClient.js").LangGraphClient<unknown> | null> & object;
|
|
6
|
+
renderMessages: import("nanostores").PreinitializedWritableAtom<import("../LangGraphClient.js").RenderMessage[]> & object;
|
|
7
|
+
userInput: import("nanostores").PreinitializedWritableAtom<string> & object;
|
|
8
|
+
loading: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
9
|
+
inChatError: import("nanostores").PreinitializedWritableAtom<string | null> & object;
|
|
10
|
+
currentAgent: import("nanostores").PreinitializedWritableAtom<string> & object;
|
|
11
|
+
collapsedTools: import("nanostores").PreinitializedWritableAtom<string[]> & object;
|
|
12
|
+
showHistory: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
13
|
+
historyList: import("nanostores").PreinitializedWritableAtom<import("@langchain/langgraph-sdk").Thread<{
|
|
14
|
+
messages: import("@langchain/langgraph-sdk").Message[];
|
|
15
|
+
}>[]> & object;
|
|
16
|
+
currentChatId: import("nanostores").PreinitializedWritableAtom<string | null> & object;
|
|
17
|
+
showGraph: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
18
|
+
graphVisualize: import("nanostores").PreinitializedWritableAtom<import("@langchain/langgraph-sdk").AssistantGraph | null> & object;
|
|
19
|
+
currentNodeName: import("nanostores").PreinitializedWritableAtom<string> & object;
|
|
20
|
+
tools: import("nanostores").PreinitializedWritableAtom<import("../index.js").UnionTool<any, Object, any>[]> & object;
|
|
21
|
+
};
|
|
22
|
+
mutations: {
|
|
23
|
+
refreshTools: () => Promise<void>;
|
|
24
|
+
setTools(new_tools: import("../index.js").UnionTool<any>[]): void;
|
|
25
|
+
isFELocking(): boolean | undefined;
|
|
26
|
+
initClient: () => Promise<import("../LangGraphClient.js").LangGraphClient<unknown>>;
|
|
27
|
+
sendMessage: (message?: import("@langchain/langgraph-sdk").Message[], extraData?: import("../LangGraphClient.js").SendMessageOptions, withoutCheck?: boolean) => Promise<void>;
|
|
28
|
+
stopGeneration: () => void;
|
|
29
|
+
toggleToolCollapse: (toolId: string) => void;
|
|
30
|
+
toggleHistoryVisible: () => void;
|
|
31
|
+
refreshHistoryList: () => Promise<void>;
|
|
32
|
+
addToHistory: (thread: import("@langchain/langgraph-sdk").Thread<{
|
|
33
|
+
messages: import("@langchain/langgraph-sdk").Message[];
|
|
34
|
+
}>) => void;
|
|
35
|
+
revertChatTo(messageId: string, resend?: boolean, sendOptions?: import("../LangGraphClient.js").SendMessageOptions): Promise<void>;
|
|
36
|
+
setUserInput(input: string): void;
|
|
37
|
+
setCurrentAgent(agent: string): Promise<void>;
|
|
38
|
+
toggleGraphVisible(): void;
|
|
39
|
+
refreshGraph: () => Promise<void>;
|
|
40
|
+
createNewChat(): void;
|
|
41
|
+
toHistoryChat(thread: import("@langchain/langgraph-sdk").Thread<{
|
|
42
|
+
messages: import("@langchain/langgraph-sdk").Message[];
|
|
43
|
+
}>): Promise<import("@langchain/langgraph-sdk").Thread<unknown> | undefined>;
|
|
44
|
+
deleteHistoryChat(thread: import("@langchain/langgraph-sdk").Thread<{
|
|
45
|
+
messages: import("@langchain/langgraph-sdk").Message[];
|
|
46
|
+
}>): Promise<void>;
|
|
47
|
+
getToolUIRender: (tool_name: string) => ((message: import("../LangGraphClient.js").RenderMessage) => Object) | null;
|
|
48
|
+
};
|
|
49
|
+
}>;
|
|
50
|
+
interface ChatProviderProps {
|
|
51
|
+
children: ReactNode;
|
|
52
|
+
defaultAgent?: string;
|
|
53
|
+
apiUrl?: string;
|
|
54
|
+
defaultHeaders?: Record<string, string>;
|
|
55
|
+
withCredentials?: boolean;
|
|
56
|
+
showHistory?: boolean;
|
|
57
|
+
showGraph?: boolean;
|
|
58
|
+
onInitError?: (error: any, currentAgent: string) => void;
|
|
59
|
+
}
|
|
60
|
+
export declare const ChatProvider: React.FC<ChatProviderProps>;
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { createElement, createContext, useContext, useMemo, useEffect } from "react";
|
|
2
|
+
import { createChatStore, useUnionStore } from "../ui-store/index.js";
|
|
3
|
+
import { useStore } from "@nanostores/react";
|
|
4
|
+
const ChatContext = createContext(undefined);
|
|
5
|
+
export const useChat = () => {
|
|
6
|
+
const context = useContext(ChatContext);
|
|
7
|
+
if (!context) {
|
|
8
|
+
throw new Error("useChat must be used within a ChatProvider");
|
|
9
|
+
}
|
|
10
|
+
return context;
|
|
11
|
+
};
|
|
12
|
+
export const ChatProvider = ({ children, defaultAgent = "", apiUrl = "http://localhost:8123", defaultHeaders = {}, withCredentials = false, showHistory = false, showGraph = false, onInitError, }) => {
|
|
13
|
+
const store = useMemo(() => {
|
|
14
|
+
const F = withCredentials
|
|
15
|
+
? (url, options) => {
|
|
16
|
+
options.credentials = "include";
|
|
17
|
+
return fetch(url, options);
|
|
18
|
+
}
|
|
19
|
+
: fetch;
|
|
20
|
+
return createChatStore(defaultAgent, {
|
|
21
|
+
apiUrl,
|
|
22
|
+
defaultHeaders,
|
|
23
|
+
callerOptions: {
|
|
24
|
+
fetch: F,
|
|
25
|
+
maxRetries: 1,
|
|
26
|
+
},
|
|
27
|
+
}, {
|
|
28
|
+
showHistory,
|
|
29
|
+
showGraph,
|
|
30
|
+
});
|
|
31
|
+
}, [defaultAgent, apiUrl, defaultHeaders, withCredentials, showHistory, showGraph]);
|
|
32
|
+
const unionStore = useUnionStore(store, useStore);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
unionStore
|
|
35
|
+
.initClient()
|
|
36
|
+
.then((res) => {
|
|
37
|
+
if (unionStore.showHistory) {
|
|
38
|
+
unionStore.refreshHistoryList();
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
.catch((err) => {
|
|
42
|
+
console.error(err);
|
|
43
|
+
if (onInitError) {
|
|
44
|
+
onInitError(err, unionStore.currentAgent);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}, [unionStore, onInitError]);
|
|
48
|
+
return createElement(ChatContext.Provider, { value: unionStore }, children);
|
|
49
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ChatContext.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ChatContext.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Client, Message } from "@langchain/langgraph-sdk";
|
|
2
|
+
export declare function revertChatTo(client: Client<{
|
|
3
|
+
messages: Message[];
|
|
4
|
+
}, {
|
|
5
|
+
messages: Message[];
|
|
6
|
+
}, unknown>, threadId: string, messageId: string): Promise<{
|
|
7
|
+
state: {
|
|
8
|
+
messages: Message[];
|
|
9
|
+
};
|
|
10
|
+
checkpoint: Pick<import("@langchain/langgraph-sdk").Config, "configurable">;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export async function revertChatTo(client, threadId, messageId) {
|
|
2
|
+
const thread = await client.threads.get(threadId);
|
|
3
|
+
const messages = thread.values.messages;
|
|
4
|
+
const idx = messages.findIndex((message) => message.id === messageId);
|
|
5
|
+
if (idx === -1) {
|
|
6
|
+
throw new Error(`Message id ${messageId} not found`);
|
|
7
|
+
}
|
|
8
|
+
const removeMessages = messages.slice(idx + 1);
|
|
9
|
+
const state = {
|
|
10
|
+
...thread.values,
|
|
11
|
+
messages: removeMessages.map((i) => {
|
|
12
|
+
// sb langgraph 官方实现都不能正常工作
|
|
13
|
+
// return new RemoveMessage({ id: i.id! }).toJSON();
|
|
14
|
+
return {
|
|
15
|
+
type: "remove",
|
|
16
|
+
id: i.id,
|
|
17
|
+
};
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
const res = await client.threads.updateState(threadId, {
|
|
21
|
+
values: state,
|
|
22
|
+
});
|
|
23
|
+
// client.runs.wait();
|
|
24
|
+
return {
|
|
25
|
+
state: {
|
|
26
|
+
messages: messages.slice(0, idx + 1),
|
|
27
|
+
},
|
|
28
|
+
checkpoint: res,
|
|
29
|
+
};
|
|
30
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export type TypedAsyncGenerator<TStateType = unknown, TUpdateType = TStateType,
|
|
|
20
20
|
/**
|
|
21
21
|
* 兼容 LangGraph SDK 的接口定义,方便进行无侵入式的扩展
|
|
22
22
|
*/
|
|
23
|
-
export interface ILangGraphClient<TStateType =
|
|
23
|
+
export interface ILangGraphClient<TStateType = {}, TUpdateType = TStateType> {
|
|
24
24
|
assistants: {
|
|
25
25
|
search(query?: {
|
|
26
26
|
graphId?: string;
|