@langchain/langgraph-sdk 0.0.112 → 0.1.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/CHANGELOG.md +12 -0
- package/dist/react/branching.cjs +149 -0
- package/dist/react/branching.d.ts +35 -0
- package/dist/react/branching.js +144 -0
- package/dist/react/errors.cjs +13 -0
- package/dist/react/errors.d.ts +12 -0
- package/dist/react/errors.js +9 -0
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +1 -1
- package/dist/react/manager.cjs +219 -0
- package/dist/react/manager.d.ts +86 -0
- package/dist/react/manager.js +215 -0
- package/dist/react/messages.cjs +69 -0
- package/dist/react/messages.d.ts +18 -0
- package/dist/react/messages.js +64 -0
- package/dist/react/stream.cjs +167 -435
- package/dist/react/stream.d.ts +1 -323
- package/dist/react/stream.js +166 -434
- package/dist/react/types.cjs +2 -0
- package/dist/react/types.d.ts +316 -0
- package/dist/react/types.js +1 -0
- package/dist/react/utils.cjs +14 -0
- package/dist/react/utils.d.ts +2 -0
- package/dist/react/utils.js +10 -0
- package/dist/react-ui/client.d.ts +1 -1
- package/package.json +1 -1
- package/dist/react/debug.cjs +0 -31
- package/dist/react/debug.d.ts +0 -23
- package/dist/react/debug.js +0 -28
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @langchain/langgraph-sdk
|
|
2
2
|
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 35a0f1c: feat(sdk): set default limit of fetch history to 10
|
|
8
|
+
- 35a0f1c: feat(sdk): set default of `fetchStateHistory` to `false`
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- 35a0f1c: chore(sdk): decouple stream manager from React
|
|
13
|
+
- 35a0f1c: fix(sdk): prevent partial history from hiding all values
|
|
14
|
+
|
|
3
15
|
## 0.0.112
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBranchSequence = getBranchSequence;
|
|
4
|
+
exports.getBranchView = getBranchView;
|
|
5
|
+
exports.getBranchContext = getBranchContext;
|
|
6
|
+
function getBranchSequence(history) {
|
|
7
|
+
const nodeIds = new Set();
|
|
8
|
+
const childrenMap = {};
|
|
9
|
+
// Short circuit if there's only a singular one state
|
|
10
|
+
if (history.length <= 1) {
|
|
11
|
+
return {
|
|
12
|
+
rootSequence: {
|
|
13
|
+
type: "sequence",
|
|
14
|
+
items: history.map((value) => ({ type: "node", value, path: [] })),
|
|
15
|
+
},
|
|
16
|
+
paths: [],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
// First pass - collect nodes for each checkpoint
|
|
20
|
+
history.forEach((state) => {
|
|
21
|
+
const checkpointId = state.parent_checkpoint?.checkpoint_id ?? "$";
|
|
22
|
+
childrenMap[checkpointId] ??= [];
|
|
23
|
+
childrenMap[checkpointId].push(state);
|
|
24
|
+
if (state.checkpoint?.checkpoint_id != null) {
|
|
25
|
+
nodeIds.add(state.checkpoint.checkpoint_id);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
// If dealing with partial history, take the branch
|
|
29
|
+
// with the latest checkpoint and mark it as the root.
|
|
30
|
+
const maxId = (...ids) => ids
|
|
31
|
+
.filter((i) => i != null)
|
|
32
|
+
.sort((a, b) => a.localeCompare(b))
|
|
33
|
+
.at(-1);
|
|
34
|
+
const lastOrphanedNode = childrenMap.$ == null
|
|
35
|
+
? Object.keys(childrenMap)
|
|
36
|
+
.filter((parentId) => !nodeIds.has(parentId))
|
|
37
|
+
.map((parentId) => {
|
|
38
|
+
const queue = [parentId];
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
let lastId = parentId;
|
|
41
|
+
while (queue.length > 0) {
|
|
42
|
+
const current = queue.shift();
|
|
43
|
+
if (seen.has(current))
|
|
44
|
+
continue;
|
|
45
|
+
seen.add(current);
|
|
46
|
+
const children = (childrenMap[current] ?? []).flatMap((i) => i.checkpoint?.checkpoint_id ?? []);
|
|
47
|
+
lastId = maxId(lastId, ...children);
|
|
48
|
+
queue.push(...children);
|
|
49
|
+
}
|
|
50
|
+
return { parentId, lastId };
|
|
51
|
+
})
|
|
52
|
+
.sort((a, b) => a.lastId.localeCompare(b.lastId))
|
|
53
|
+
.at(-1)?.parentId
|
|
54
|
+
: undefined;
|
|
55
|
+
if (lastOrphanedNode != null)
|
|
56
|
+
childrenMap.$ = childrenMap[lastOrphanedNode];
|
|
57
|
+
const rootSequence = { type: "sequence", items: [] };
|
|
58
|
+
const queue = [{ id: "$", sequence: rootSequence, path: [] }];
|
|
59
|
+
const paths = [];
|
|
60
|
+
const visited = new Set();
|
|
61
|
+
while (queue.length > 0) {
|
|
62
|
+
const task = queue.shift();
|
|
63
|
+
if (visited.has(task.id))
|
|
64
|
+
continue;
|
|
65
|
+
visited.add(task.id);
|
|
66
|
+
const children = childrenMap[task.id];
|
|
67
|
+
if (children == null || children.length === 0)
|
|
68
|
+
continue;
|
|
69
|
+
// If we've encountered a fork (2+ children), push the fork
|
|
70
|
+
// to the sequence and add a new sequence for each child
|
|
71
|
+
let fork;
|
|
72
|
+
if (children.length > 1) {
|
|
73
|
+
fork = { type: "fork", items: [] };
|
|
74
|
+
task.sequence.items.push(fork);
|
|
75
|
+
}
|
|
76
|
+
for (const value of children) {
|
|
77
|
+
const id = value.checkpoint?.checkpoint_id;
|
|
78
|
+
if (id == null)
|
|
79
|
+
continue;
|
|
80
|
+
let { sequence } = task;
|
|
81
|
+
let { path } = task;
|
|
82
|
+
if (fork != null) {
|
|
83
|
+
sequence = { type: "sequence", items: [] };
|
|
84
|
+
fork.items.unshift(sequence);
|
|
85
|
+
path = path.slice();
|
|
86
|
+
path.push(id);
|
|
87
|
+
paths.push(path);
|
|
88
|
+
}
|
|
89
|
+
sequence.items.push({ type: "node", value, path });
|
|
90
|
+
queue.push({ id, sequence, path });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { rootSequence, paths };
|
|
94
|
+
}
|
|
95
|
+
const PATH_SEP = ">";
|
|
96
|
+
const ROOT_ID = "$";
|
|
97
|
+
// Get flat view
|
|
98
|
+
function getBranchView(sequence, paths, branch) {
|
|
99
|
+
const path = branch.split(PATH_SEP);
|
|
100
|
+
const pathMap = {};
|
|
101
|
+
for (const path of paths) {
|
|
102
|
+
const parent = path.at(-2) ?? ROOT_ID;
|
|
103
|
+
pathMap[parent] ??= [];
|
|
104
|
+
pathMap[parent].unshift(path);
|
|
105
|
+
}
|
|
106
|
+
const history = [];
|
|
107
|
+
const branchByCheckpoint = {};
|
|
108
|
+
const forkStack = path.slice();
|
|
109
|
+
const queue = [...sequence.items];
|
|
110
|
+
while (queue.length > 0) {
|
|
111
|
+
const item = queue.shift();
|
|
112
|
+
if (item.type === "node") {
|
|
113
|
+
history.push(item.value);
|
|
114
|
+
const checkpointId = item.value.checkpoint?.checkpoint_id;
|
|
115
|
+
if (checkpointId == null)
|
|
116
|
+
continue;
|
|
117
|
+
branchByCheckpoint[checkpointId] = {
|
|
118
|
+
branch: item.path.join(PATH_SEP),
|
|
119
|
+
branchOptions: (item.path.length > 0
|
|
120
|
+
? pathMap[item.path.at(-2) ?? ROOT_ID] ?? []
|
|
121
|
+
: []).map((p) => p.join(PATH_SEP)),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (item.type === "fork") {
|
|
125
|
+
const forkId = forkStack.shift();
|
|
126
|
+
const index = forkId != null
|
|
127
|
+
? item.items.findIndex((value) => {
|
|
128
|
+
const firstItem = value.items.at(0);
|
|
129
|
+
if (!firstItem || firstItem.type !== "node")
|
|
130
|
+
return false;
|
|
131
|
+
return firstItem.value.checkpoint?.checkpoint_id === forkId;
|
|
132
|
+
})
|
|
133
|
+
: -1;
|
|
134
|
+
const nextItems = item.items.at(index)?.items ?? [];
|
|
135
|
+
queue.push(...nextItems);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return { history, branchByCheckpoint };
|
|
139
|
+
}
|
|
140
|
+
function getBranchContext(branch, history) {
|
|
141
|
+
const { rootSequence: branchTree, paths } = getBranchSequence(history ?? []);
|
|
142
|
+
const { history: flatHistory, branchByCheckpoint } = getBranchView(branchTree, paths, branch);
|
|
143
|
+
return {
|
|
144
|
+
branchTree,
|
|
145
|
+
flatHistory,
|
|
146
|
+
branchByCheckpoint,
|
|
147
|
+
threadHead: flatHistory.at(-1),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ThreadState } from "../schema.js";
|
|
2
|
+
interface Node<StateType = any> {
|
|
3
|
+
type: "node";
|
|
4
|
+
value: ThreadState<StateType>;
|
|
5
|
+
path: string[];
|
|
6
|
+
}
|
|
7
|
+
interface Fork<StateType = any> {
|
|
8
|
+
type: "fork";
|
|
9
|
+
items: Array<Sequence<StateType>>;
|
|
10
|
+
}
|
|
11
|
+
export interface Sequence<StateType = any> {
|
|
12
|
+
type: "sequence";
|
|
13
|
+
items: Array<Node<StateType> | Fork<StateType>>;
|
|
14
|
+
}
|
|
15
|
+
export declare function getBranchSequence<StateType extends Record<string, unknown>>(history: ThreadState<StateType>[]): {
|
|
16
|
+
rootSequence: Sequence<any>;
|
|
17
|
+
paths: string[][];
|
|
18
|
+
};
|
|
19
|
+
export declare function getBranchView<StateType extends Record<string, unknown>>(sequence: Sequence<StateType>, paths: string[][], branch: string): {
|
|
20
|
+
history: ThreadState<StateType>[];
|
|
21
|
+
branchByCheckpoint: Record<string, {
|
|
22
|
+
branch: string | undefined;
|
|
23
|
+
branchOptions: string[] | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
export declare function getBranchContext<StateType extends Record<string, unknown>>(branch: string, history: ThreadState<StateType>[] | undefined): {
|
|
27
|
+
branchTree: Sequence<any>;
|
|
28
|
+
flatHistory: ThreadState<any>[];
|
|
29
|
+
branchByCheckpoint: Record<string, {
|
|
30
|
+
branch: string | undefined;
|
|
31
|
+
branchOptions: string[] | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
threadHead: ThreadState<any> | undefined;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export function getBranchSequence(history) {
|
|
2
|
+
const nodeIds = new Set();
|
|
3
|
+
const childrenMap = {};
|
|
4
|
+
// Short circuit if there's only a singular one state
|
|
5
|
+
if (history.length <= 1) {
|
|
6
|
+
return {
|
|
7
|
+
rootSequence: {
|
|
8
|
+
type: "sequence",
|
|
9
|
+
items: history.map((value) => ({ type: "node", value, path: [] })),
|
|
10
|
+
},
|
|
11
|
+
paths: [],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
// First pass - collect nodes for each checkpoint
|
|
15
|
+
history.forEach((state) => {
|
|
16
|
+
const checkpointId = state.parent_checkpoint?.checkpoint_id ?? "$";
|
|
17
|
+
childrenMap[checkpointId] ??= [];
|
|
18
|
+
childrenMap[checkpointId].push(state);
|
|
19
|
+
if (state.checkpoint?.checkpoint_id != null) {
|
|
20
|
+
nodeIds.add(state.checkpoint.checkpoint_id);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
// If dealing with partial history, take the branch
|
|
24
|
+
// with the latest checkpoint and mark it as the root.
|
|
25
|
+
const maxId = (...ids) => ids
|
|
26
|
+
.filter((i) => i != null)
|
|
27
|
+
.sort((a, b) => a.localeCompare(b))
|
|
28
|
+
.at(-1);
|
|
29
|
+
const lastOrphanedNode = childrenMap.$ == null
|
|
30
|
+
? Object.keys(childrenMap)
|
|
31
|
+
.filter((parentId) => !nodeIds.has(parentId))
|
|
32
|
+
.map((parentId) => {
|
|
33
|
+
const queue = [parentId];
|
|
34
|
+
const seen = new Set();
|
|
35
|
+
let lastId = parentId;
|
|
36
|
+
while (queue.length > 0) {
|
|
37
|
+
const current = queue.shift();
|
|
38
|
+
if (seen.has(current))
|
|
39
|
+
continue;
|
|
40
|
+
seen.add(current);
|
|
41
|
+
const children = (childrenMap[current] ?? []).flatMap((i) => i.checkpoint?.checkpoint_id ?? []);
|
|
42
|
+
lastId = maxId(lastId, ...children);
|
|
43
|
+
queue.push(...children);
|
|
44
|
+
}
|
|
45
|
+
return { parentId, lastId };
|
|
46
|
+
})
|
|
47
|
+
.sort((a, b) => a.lastId.localeCompare(b.lastId))
|
|
48
|
+
.at(-1)?.parentId
|
|
49
|
+
: undefined;
|
|
50
|
+
if (lastOrphanedNode != null)
|
|
51
|
+
childrenMap.$ = childrenMap[lastOrphanedNode];
|
|
52
|
+
const rootSequence = { type: "sequence", items: [] };
|
|
53
|
+
const queue = [{ id: "$", sequence: rootSequence, path: [] }];
|
|
54
|
+
const paths = [];
|
|
55
|
+
const visited = new Set();
|
|
56
|
+
while (queue.length > 0) {
|
|
57
|
+
const task = queue.shift();
|
|
58
|
+
if (visited.has(task.id))
|
|
59
|
+
continue;
|
|
60
|
+
visited.add(task.id);
|
|
61
|
+
const children = childrenMap[task.id];
|
|
62
|
+
if (children == null || children.length === 0)
|
|
63
|
+
continue;
|
|
64
|
+
// If we've encountered a fork (2+ children), push the fork
|
|
65
|
+
// to the sequence and add a new sequence for each child
|
|
66
|
+
let fork;
|
|
67
|
+
if (children.length > 1) {
|
|
68
|
+
fork = { type: "fork", items: [] };
|
|
69
|
+
task.sequence.items.push(fork);
|
|
70
|
+
}
|
|
71
|
+
for (const value of children) {
|
|
72
|
+
const id = value.checkpoint?.checkpoint_id;
|
|
73
|
+
if (id == null)
|
|
74
|
+
continue;
|
|
75
|
+
let { sequence } = task;
|
|
76
|
+
let { path } = task;
|
|
77
|
+
if (fork != null) {
|
|
78
|
+
sequence = { type: "sequence", items: [] };
|
|
79
|
+
fork.items.unshift(sequence);
|
|
80
|
+
path = path.slice();
|
|
81
|
+
path.push(id);
|
|
82
|
+
paths.push(path);
|
|
83
|
+
}
|
|
84
|
+
sequence.items.push({ type: "node", value, path });
|
|
85
|
+
queue.push({ id, sequence, path });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return { rootSequence, paths };
|
|
89
|
+
}
|
|
90
|
+
const PATH_SEP = ">";
|
|
91
|
+
const ROOT_ID = "$";
|
|
92
|
+
// Get flat view
|
|
93
|
+
export function getBranchView(sequence, paths, branch) {
|
|
94
|
+
const path = branch.split(PATH_SEP);
|
|
95
|
+
const pathMap = {};
|
|
96
|
+
for (const path of paths) {
|
|
97
|
+
const parent = path.at(-2) ?? ROOT_ID;
|
|
98
|
+
pathMap[parent] ??= [];
|
|
99
|
+
pathMap[parent].unshift(path);
|
|
100
|
+
}
|
|
101
|
+
const history = [];
|
|
102
|
+
const branchByCheckpoint = {};
|
|
103
|
+
const forkStack = path.slice();
|
|
104
|
+
const queue = [...sequence.items];
|
|
105
|
+
while (queue.length > 0) {
|
|
106
|
+
const item = queue.shift();
|
|
107
|
+
if (item.type === "node") {
|
|
108
|
+
history.push(item.value);
|
|
109
|
+
const checkpointId = item.value.checkpoint?.checkpoint_id;
|
|
110
|
+
if (checkpointId == null)
|
|
111
|
+
continue;
|
|
112
|
+
branchByCheckpoint[checkpointId] = {
|
|
113
|
+
branch: item.path.join(PATH_SEP),
|
|
114
|
+
branchOptions: (item.path.length > 0
|
|
115
|
+
? pathMap[item.path.at(-2) ?? ROOT_ID] ?? []
|
|
116
|
+
: []).map((p) => p.join(PATH_SEP)),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (item.type === "fork") {
|
|
120
|
+
const forkId = forkStack.shift();
|
|
121
|
+
const index = forkId != null
|
|
122
|
+
? item.items.findIndex((value) => {
|
|
123
|
+
const firstItem = value.items.at(0);
|
|
124
|
+
if (!firstItem || firstItem.type !== "node")
|
|
125
|
+
return false;
|
|
126
|
+
return firstItem.value.checkpoint?.checkpoint_id === forkId;
|
|
127
|
+
})
|
|
128
|
+
: -1;
|
|
129
|
+
const nextItems = item.items.at(index)?.items ?? [];
|
|
130
|
+
queue.push(...nextItems);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return { history, branchByCheckpoint };
|
|
134
|
+
}
|
|
135
|
+
export function getBranchContext(branch, history) {
|
|
136
|
+
const { rootSequence: branchTree, paths } = getBranchSequence(history ?? []);
|
|
137
|
+
const { history: flatHistory, branchByCheckpoint } = getBranchView(branchTree, paths, branch);
|
|
138
|
+
return {
|
|
139
|
+
branchTree,
|
|
140
|
+
flatHistory,
|
|
141
|
+
branchByCheckpoint,
|
|
142
|
+
threadHead: flatHistory.at(-1),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamError = void 0;
|
|
4
|
+
class StreamError extends Error {
|
|
5
|
+
constructor(data) {
|
|
6
|
+
super(data.message);
|
|
7
|
+
this.name = data.name ?? data.error ?? "StreamError";
|
|
8
|
+
}
|
|
9
|
+
static isStructuredError(error) {
|
|
10
|
+
return typeof error === "object" && error != null && "message" in error;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.StreamError = StreamError;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export class StreamError extends Error {
|
|
2
|
+
constructor(data) {
|
|
3
|
+
super(data.message);
|
|
4
|
+
this.name = data.name ?? data.error ?? "StreamError";
|
|
5
|
+
}
|
|
6
|
+
static isStructuredError(error) {
|
|
7
|
+
return typeof error === "object" && error != null && "message" in error;
|
|
8
|
+
}
|
|
9
|
+
}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { useStream
|
|
1
|
+
export { useStream } from "./stream.js";
|
|
2
|
+
export type { MessageMetadata, UseStream, UseStreamOptions } from "./types.js";
|
package/dist/react/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { useStream
|
|
1
|
+
export { useStream } from "./stream.js";
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamManager = void 0;
|
|
4
|
+
const messages_js_1 = require("./messages.cjs");
|
|
5
|
+
const errors_js_1 = require("./errors.cjs");
|
|
6
|
+
class StreamManager {
|
|
7
|
+
constructor(messages) {
|
|
8
|
+
Object.defineProperty(this, "abortRef", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: new AbortController()
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(this, "messages", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "listeners", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: new Set()
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "state", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "setState", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: (newState) => {
|
|
37
|
+
this.state = { ...this.state, ...newState };
|
|
38
|
+
this.notifyListeners();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "notifyListeners", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: () => {
|
|
46
|
+
this.listeners.forEach((listener) => listener());
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
Object.defineProperty(this, "subscribe", {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
configurable: true,
|
|
52
|
+
writable: true,
|
|
53
|
+
value: (listener) => {
|
|
54
|
+
this.listeners.add(listener);
|
|
55
|
+
return () => this.listeners.delete(listener);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
Object.defineProperty(this, "getSnapshot", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
configurable: true,
|
|
61
|
+
writable: true,
|
|
62
|
+
value: () => this.state
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(this, "setStreamValues", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
configurable: true,
|
|
67
|
+
writable: true,
|
|
68
|
+
value: (values, kind = "stream") => {
|
|
69
|
+
if (typeof values === "function") {
|
|
70
|
+
const [prevValues, prevKind] = this.state.values ?? [null, "stream"];
|
|
71
|
+
const nextValues = values(prevValues, prevKind);
|
|
72
|
+
this.setState({ values: nextValues != null ? [nextValues, kind] : null });
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const nextValues = values != null ? [values, kind] : null;
|
|
76
|
+
this.setState({ values: nextValues });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
Object.defineProperty(this, "getMutateFn", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
configurable: true,
|
|
83
|
+
writable: true,
|
|
84
|
+
value: (kind, historyValues) => {
|
|
85
|
+
return (update) => {
|
|
86
|
+
const prev = { ...historyValues, ...this.state.values };
|
|
87
|
+
const next = typeof update === "function" ? update(prev) : update;
|
|
88
|
+
this.setStreamValues({ ...prev, ...next }, kind);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
Object.defineProperty(this, "matchEventType", {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
configurable: true,
|
|
95
|
+
writable: true,
|
|
96
|
+
value: (expected, actual, _data) => {
|
|
97
|
+
return expected === actual || actual.startsWith(`${expected}|`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(this, "start", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
configurable: true,
|
|
103
|
+
writable: true,
|
|
104
|
+
value: async (action, options) => {
|
|
105
|
+
if (this.state.isLoading)
|
|
106
|
+
return;
|
|
107
|
+
try {
|
|
108
|
+
this.setState({ isLoading: true, error: undefined });
|
|
109
|
+
this.abortRef = new AbortController();
|
|
110
|
+
const run = await action(this.abortRef.signal);
|
|
111
|
+
let streamError;
|
|
112
|
+
for await (const { event, data } of run) {
|
|
113
|
+
if (event === "error") {
|
|
114
|
+
streamError = new errors_js_1.StreamError(data);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
const namespace = event.includes("|")
|
|
118
|
+
? event.split("|").slice(1)
|
|
119
|
+
: undefined;
|
|
120
|
+
const mutate = this.getMutateFn("stream", options.initialValues);
|
|
121
|
+
if (event === "metadata")
|
|
122
|
+
options.callbacks.onMetadataEvent?.(data);
|
|
123
|
+
if (event === "events")
|
|
124
|
+
options.callbacks.onLangChainEvent?.(data);
|
|
125
|
+
if (this.matchEventType("updates", event, data)) {
|
|
126
|
+
options.callbacks.onUpdateEvent?.(data, { namespace, mutate });
|
|
127
|
+
}
|
|
128
|
+
if (this.matchEventType("custom", event, data)) {
|
|
129
|
+
options.callbacks.onCustomEvent?.(data, { namespace, mutate });
|
|
130
|
+
}
|
|
131
|
+
if (this.matchEventType("checkpoints", event, data)) {
|
|
132
|
+
options.callbacks.onCheckpointEvent?.(data, { namespace });
|
|
133
|
+
}
|
|
134
|
+
if (this.matchEventType("tasks", event, data)) {
|
|
135
|
+
options.callbacks.onTaskEvent?.(data, { namespace });
|
|
136
|
+
}
|
|
137
|
+
if (this.matchEventType("debug", event, data)) {
|
|
138
|
+
options.callbacks.onDebugEvent?.(data, { namespace });
|
|
139
|
+
}
|
|
140
|
+
if (event === "values") {
|
|
141
|
+
// don't update values on interrupt values event
|
|
142
|
+
if ("__interrupt__" in data)
|
|
143
|
+
continue;
|
|
144
|
+
this.setStreamValues(data);
|
|
145
|
+
}
|
|
146
|
+
if (this.matchEventType("messages", event, data)) {
|
|
147
|
+
const [serialized, metadata] = data;
|
|
148
|
+
const messageId = this.messages.add(serialized, metadata);
|
|
149
|
+
if (!messageId) {
|
|
150
|
+
console.warn("Failed to add message to manager, no message ID found");
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
this.setStreamValues((streamValues) => {
|
|
154
|
+
const values = { ...options.initialValues, ...streamValues };
|
|
155
|
+
// Assumption: we're concatenating the message
|
|
156
|
+
const messages = options.getMessages(values).slice();
|
|
157
|
+
const { chunk, index } = this.messages.get(messageId, messages.length) ?? {};
|
|
158
|
+
if (!chunk || index == null)
|
|
159
|
+
return values;
|
|
160
|
+
messages[index] = (0, messages_js_1.toMessageDict)(chunk);
|
|
161
|
+
return options.setMessages(values, messages);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (streamError != null)
|
|
166
|
+
throw streamError;
|
|
167
|
+
const values = await options.onSuccess?.();
|
|
168
|
+
if (typeof values !== "undefined")
|
|
169
|
+
this.setStreamValues(values);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
if (!(error instanceof Error && // eslint-disable-line no-instanceof/no-instanceof
|
|
173
|
+
(error.name === "AbortError" || error.name === "TimeoutError"))) {
|
|
174
|
+
console.error(error);
|
|
175
|
+
this.setState({ error });
|
|
176
|
+
await options.onError?.(error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
this.setState({ isLoading: false });
|
|
181
|
+
this.abortRef = new AbortController();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
Object.defineProperty(this, "stop", {
|
|
186
|
+
enumerable: true,
|
|
187
|
+
configurable: true,
|
|
188
|
+
writable: true,
|
|
189
|
+
value: async (historyValues, options) => {
|
|
190
|
+
if (this.abortRef) {
|
|
191
|
+
this.abortRef.abort();
|
|
192
|
+
this.abortRef = new AbortController();
|
|
193
|
+
}
|
|
194
|
+
options.onStop?.({ mutate: this.getMutateFn("stop", historyValues) });
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
Object.defineProperty(this, "clear", {
|
|
198
|
+
enumerable: true,
|
|
199
|
+
configurable: true,
|
|
200
|
+
writable: true,
|
|
201
|
+
value: () => {
|
|
202
|
+
this.setState({ error: undefined, values: null });
|
|
203
|
+
this.messages.clear();
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
this.messages = messages;
|
|
207
|
+
this.state = { isLoading: false, values: null, error: undefined };
|
|
208
|
+
}
|
|
209
|
+
get isLoading() {
|
|
210
|
+
return this.state.isLoading;
|
|
211
|
+
}
|
|
212
|
+
get values() {
|
|
213
|
+
return this.state.values?.[0] ?? null;
|
|
214
|
+
}
|
|
215
|
+
get error() {
|
|
216
|
+
return this.state.error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.StreamManager = StreamManager;
|