@langgraph-js/sdk 2.2.0 → 3.0.2
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 +15 -60
- package/dist/LangGraphClient.js +2 -2
- 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 +62 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/ui-store/createChatStore.d.ts +2 -2
- package/dist/ui-store/createChatStore.js +3 -0
- 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 +8 -14
- package/src/client/LanggraphServer.ts +2 -2
- package/src/index.ts +0 -1
- package/src/react/ChatContext.ts +98 -0
- package/src/react/index.ts +1 -0
- package/src/time-travel/index.ts +0 -1
- package/src/ui-store/createChatStore.ts +2 -0
- 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,70 +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
154
|
metadata?: import("@langchain/langgraph-sdk").Metadata;
|
|
158
155
|
limit?: number;
|
|
159
156
|
offset?: number;
|
|
160
157
|
status?: import("@langchain/langgraph-sdk").ThreadStatus;
|
|
161
|
-
sortBy?: import("
|
|
162
|
-
sortOrder?: import("
|
|
158
|
+
sortBy?: import("@langgraph-js/pure-graph/dist/types.js").ThreadSortBy;
|
|
159
|
+
sortOrder?: import("@langgraph-js/pure-graph/dist/types.js").SortOrder;
|
|
163
160
|
}): Promise<Thread<TStateType>[]>;
|
|
164
161
|
get(threadId: string): Promise<Thread<TStateType>>;
|
|
165
162
|
delete(threadId: string): Promise<void>;
|
|
163
|
+
updateState(threadId: string, thread: Partial<Thread<TStateType>>): Promise<Pick<import("@langchain/langgraph-sdk").Config, "configurable">>;
|
|
166
164
|
};
|
|
167
165
|
/** 代理 runs 属性到内部 client */
|
|
168
|
-
get runs():
|
|
169
|
-
list(threadId: string, options?: {
|
|
170
|
-
limit?: number;
|
|
171
|
-
offset?: number;
|
|
172
|
-
status?: import("./types.js").RunStatus;
|
|
173
|
-
}): Promise<import("@langchain/langgraph-sdk").Run[]>;
|
|
174
|
-
stream<TSubgraphs extends boolean = false>(threadId: string, assistantId: string, payload?: {
|
|
175
|
-
input?: Record<string, unknown> | null;
|
|
176
|
-
metadata?: import("@langchain/langgraph-sdk").Metadata;
|
|
177
|
-
config?: import("@langchain/langgraph-sdk").Config;
|
|
178
|
-
checkpointId?: string;
|
|
179
|
-
checkpoint?: Omit<import("@langchain/langgraph-sdk").Checkpoint, "thread_id">;
|
|
180
|
-
checkpointDuring?: boolean;
|
|
181
|
-
interruptBefore?: "*" | string[];
|
|
182
|
-
interruptAfter?: "*" | string[];
|
|
183
|
-
multitaskStrategy?: import("./types.js").MultitaskStrategy;
|
|
184
|
-
onCompletion?: import("./types.js").OnCompletionBehavior;
|
|
185
|
-
signal?: AbortController["signal"];
|
|
186
|
-
webhook?: string;
|
|
187
|
-
onDisconnect?: import("./types.js").DisconnectMode;
|
|
188
|
-
afterSeconds?: number;
|
|
189
|
-
ifNotExists?: "create" | "reject";
|
|
190
|
-
command?: Command;
|
|
191
|
-
onRunCreated?: (params: {
|
|
192
|
-
run_id: string;
|
|
193
|
-
thread_id?: string;
|
|
194
|
-
}) => void;
|
|
195
|
-
streamMode?: import("@langchain/langgraph-sdk").StreamMode[];
|
|
196
|
-
streamSubgraphs?: TSubgraphs | undefined;
|
|
197
|
-
streamResumable?: boolean;
|
|
198
|
-
feedbackKeys?: string[];
|
|
199
|
-
} | undefined): import("./types.js").TypedAsyncGenerator<TSubgraphs, TStateType, TUpdateType>;
|
|
200
|
-
joinStream(threadId: string, runId: string, options?: {
|
|
201
|
-
signal?: AbortSignal;
|
|
202
|
-
cancelOnDisconnect?: boolean;
|
|
203
|
-
lastEventId?: string;
|
|
204
|
-
streamMode?: import("@langchain/langgraph-sdk").StreamMode | import("@langchain/langgraph-sdk").StreamMode[];
|
|
205
|
-
} | AbortSignal): AsyncGenerator<{
|
|
206
|
-
id?: string;
|
|
207
|
-
event: import("@langchain/core/tracers/log_stream").StreamEvent;
|
|
208
|
-
data: any;
|
|
209
|
-
}>;
|
|
210
|
-
cancel(threadId: string, runId: string, wait?: boolean, action?: import("./types.js").CancelAction): Promise<void>;
|
|
211
|
-
};
|
|
166
|
+
get runs(): ILangGraphClient["runs"];
|
|
212
167
|
private listAssistants;
|
|
213
168
|
/**
|
|
214
169
|
* @zh 初始化 Assistant。
|
|
@@ -219,7 +174,7 @@ export declare class LangGraphClient<TStateType = unknown, TUpdateType = TStateT
|
|
|
219
174
|
* @zh 创建一个新的 Thread。
|
|
220
175
|
* @en Creates a new Thread.
|
|
221
176
|
*/
|
|
222
|
-
createThread({ threadId, graphId
|
|
177
|
+
createThread({ threadId, graphId }?: {
|
|
223
178
|
threadId?: string;
|
|
224
179
|
graphId?: string;
|
|
225
180
|
}): Promise<Thread<TStateType>>;
|
package/dist/LangGraphClient.js
CHANGED
|
@@ -74,7 +74,7 @@ export class LangGraphClient extends EventEmitter {
|
|
|
74
74
|
* @zh 创建一个新的 Thread。
|
|
75
75
|
* @en Creates a new Thread.
|
|
76
76
|
*/
|
|
77
|
-
async createThread({ threadId, graphId
|
|
77
|
+
async createThread({ threadId, graphId } = {}) {
|
|
78
78
|
try {
|
|
79
79
|
this.currentThread = await this.threads.create({
|
|
80
80
|
threadId,
|
|
@@ -254,7 +254,7 @@ export class LangGraphClient extends EventEmitter {
|
|
|
254
254
|
if (chunk.event === "metadata") {
|
|
255
255
|
this.currentRun = chunk.data;
|
|
256
256
|
}
|
|
257
|
-
else if (chunk.event === "error") {
|
|
257
|
+
else if (chunk.event === "error" || chunk.event === "Error" || chunk.event === "__stream_error__") {
|
|
258
258
|
this.emit("error", chunk);
|
|
259
259
|
}
|
|
260
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,62 @@
|
|
|
1
|
+
import { createElement, createContext, useContext, useMemo, useEffect, useRef } 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
|
+
// 使用 useMemo 稳定 defaultHeaders 的引用
|
|
14
|
+
const stableHeaders = useMemo(() => defaultHeaders || {}, [defaultHeaders]);
|
|
15
|
+
// 使用 useRef 保存 onInitError 的最新引用
|
|
16
|
+
const onInitErrorRef = useRef(onInitError);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
onInitErrorRef.current = onInitError;
|
|
19
|
+
}, [onInitError]);
|
|
20
|
+
const store = useMemo(() => {
|
|
21
|
+
const F = withCredentials
|
|
22
|
+
? (url, options) => {
|
|
23
|
+
options.credentials = "include";
|
|
24
|
+
return fetch(url, options);
|
|
25
|
+
}
|
|
26
|
+
: fetch;
|
|
27
|
+
return createChatStore(defaultAgent, {
|
|
28
|
+
apiUrl,
|
|
29
|
+
defaultHeaders: stableHeaders,
|
|
30
|
+
callerOptions: {
|
|
31
|
+
fetch: F,
|
|
32
|
+
maxRetries: 1,
|
|
33
|
+
},
|
|
34
|
+
}, {
|
|
35
|
+
showHistory,
|
|
36
|
+
showGraph,
|
|
37
|
+
});
|
|
38
|
+
}, [defaultAgent, apiUrl, stableHeaders, withCredentials, showHistory, showGraph]);
|
|
39
|
+
const unionStore = useUnionStore(store, useStore);
|
|
40
|
+
// 使用 ref 标记是否已初始化
|
|
41
|
+
const initializedRef = useRef(false);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (initializedRef.current) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
initializedRef.current = true;
|
|
47
|
+
unionStore
|
|
48
|
+
.initClient()
|
|
49
|
+
.then((res) => {
|
|
50
|
+
if (unionStore.showHistory) {
|
|
51
|
+
unionStore.refreshHistoryList();
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
.catch((err) => {
|
|
55
|
+
console.error(err);
|
|
56
|
+
if (onInitErrorRef.current) {
|
|
57
|
+
onInitErrorRef.current(err, unionStore.currentAgent);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}, [unionStore]);
|
|
61
|
+
return createElement(ChatContext.Provider, { value: unionStore }, children);
|
|
62
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ChatContext.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ChatContext.js";
|
|
@@ -31,7 +31,7 @@ export declare const createChatStore: (initClientName: string, config: Partial<L
|
|
|
31
31
|
onInit?: (client: LangGraphClient) => void;
|
|
32
32
|
}) => {
|
|
33
33
|
data: {
|
|
34
|
-
client: import("nanostores").PreinitializedWritableAtom<LangGraphClient<unknown
|
|
34
|
+
client: import("nanostores").PreinitializedWritableAtom<LangGraphClient<unknown> | null> & object;
|
|
35
35
|
renderMessages: import("nanostores").PreinitializedWritableAtom<RenderMessage[]> & object;
|
|
36
36
|
userInput: import("nanostores").PreinitializedWritableAtom<string> & object;
|
|
37
37
|
loading: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
@@ -52,7 +52,7 @@ export declare const createChatStore: (initClientName: string, config: Partial<L
|
|
|
52
52
|
refreshTools: () => Promise<void>;
|
|
53
53
|
setTools(new_tools: UnionTool<any>[]): void;
|
|
54
54
|
isFELocking(): boolean | undefined;
|
|
55
|
-
initClient: () => Promise<LangGraphClient<unknown
|
|
55
|
+
initClient: () => Promise<LangGraphClient<unknown>>;
|
|
56
56
|
sendMessage: (message?: Message[], extraData?: SendMessageOptions, withoutCheck?: boolean) => Promise<void>;
|
|
57
57
|
stopGeneration: () => void;
|
|
58
58
|
toggleToolCollapse: (toolId: string) => void;
|
|
@@ -172,6 +172,9 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
172
172
|
if (isThreadRunning) {
|
|
173
173
|
await ((_b = client.get()) === null || _b === void 0 ? void 0 : _b.resetStream());
|
|
174
174
|
}
|
|
175
|
+
else {
|
|
176
|
+
throw e;
|
|
177
|
+
}
|
|
175
178
|
}
|
|
176
179
|
finally {
|
|
177
180
|
userInput.set("");
|