assistant-stream 0.3.27 → 0.3.29
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/dist/core/accumulators/AssistantMessageStream.d.ts.map +1 -1
- package/dist/core/accumulators/AssistantMessageStream.js +0 -1
- package/dist/core/accumulators/AssistantMessageStream.js.map +1 -1
- package/dist/core/modules/tool-call.d.ts.map +1 -1
- package/dist/core/modules/tool-call.js +1 -1
- package/dist/core/modules/tool-call.js.map +1 -1
- package/dist/core/serialization/PlainText.d.ts.map +1 -1
- package/dist/core/serialization/PlainText.js +4 -18
- package/dist/core/serialization/PlainText.js.map +1 -1
- package/dist/core/serialization/data-stream/DataStream.js +48 -48
- package/dist/core/serialization/data-stream/DataStream.js.map +1 -1
- package/dist/core/serialization/data-stream/chunk-types.d.ts +23 -22
- package/dist/core/serialization/data-stream/chunk-types.d.ts.map +1 -1
- package/dist/core/serialization/data-stream/chunk-types.js +22 -23
- package/dist/core/serialization/data-stream/chunk-types.js.map +1 -1
- package/dist/core/serialization/data-stream/serialization.d.ts.map +1 -1
- package/dist/core/serialization/data-stream/serialization.js +14 -2
- package/dist/core/serialization/data-stream/serialization.js.map +1 -1
- package/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts.map +1 -1
- package/dist/core/serialization/ui-message-stream/UIMessageStream.js +2 -1
- package/dist/core/serialization/ui-message-stream/UIMessageStream.js.map +1 -1
- package/dist/core/tool/ToolCallReader.d.ts.map +1 -1
- package/dist/core/tool/ToolCallReader.js.map +1 -1
- package/dist/core/tool/tool-types.d.ts +6 -0
- package/dist/core/tool/tool-types.d.ts.map +1 -1
- package/dist/core/utils/stream/SSE.d.ts.map +1 -1
- package/dist/core/utils/stream/SSE.js +11 -2
- package/dist/core/utils/stream/SSE.js.map +1 -1
- package/package.json +2 -2
- package/src/core/accumulators/AssistantMessageStream.ts +3 -1
- package/src/core/converters/toGenericMessages.test.ts +3 -39
- package/src/core/gorp/GorpStreamDeltaTracker.test.ts +30 -0
- package/src/core/modules/tool-call.ts +4 -1
- package/src/core/serialization/PlainText.test.ts +54 -0
- package/src/core/serialization/PlainText.ts +8 -27
- package/src/core/serialization/data-stream/DataStream.ts +1 -1
- package/src/core/serialization/data-stream/chunk-types.ts +24 -22
- package/src/core/serialization/data-stream/serialization.test.ts +133 -0
- package/src/core/serialization/data-stream/serialization.ts +20 -2
- package/src/core/serialization/ui-message-stream/UIMessageStream.test.ts +24 -0
- package/src/core/serialization/ui-message-stream/UIMessageStream.ts +2 -1
- package/src/core/tool/ToolCallReader.ts +5 -1
- package/src/core/tool/tool-types.ts +7 -0
- package/src/core/utils/stream/SSE.test.ts +97 -0
- package/src/core/utils/stream/SSE.ts +13 -2
- package/src/gorp.test.ts +0 -10
- package/src/core/accumulators/TimingTracker.test.ts +0 -100
- package/src/core/gorp/changeTree.test.ts +0 -168
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
diffKeys,
|
|
4
|
-
lookupChange,
|
|
5
|
-
markChanged,
|
|
6
|
-
mergeChanged,
|
|
7
|
-
type ChangeNode,
|
|
8
|
-
} from "./changeTree";
|
|
9
|
-
|
|
10
|
-
describe("markChanged", () => {
|
|
11
|
-
it("collapses to true when path is empty", () => {
|
|
12
|
-
expect(markChanged({}, [])).toBe(true);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("keeps `true` after attempting to descend into it", () => {
|
|
16
|
-
const node: ChangeNode = { a: true };
|
|
17
|
-
const result = markChanged(node, ["a", "b"]);
|
|
18
|
-
expect(result).toBe(node);
|
|
19
|
-
expect(node.a).toBe(true);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("overwrites a nested subtree with `true` when the path collapses to the parent", () => {
|
|
23
|
-
const node: ChangeNode = { a: { b: true } };
|
|
24
|
-
markChanged(node, ["a"]);
|
|
25
|
-
expect(node.a).toBe(true);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("creates intermediate nodes lazily without disturbing siblings", () => {
|
|
29
|
-
const node: ChangeNode = { a: { existing: true } };
|
|
30
|
-
markChanged(node, ["a", "b", "c"]);
|
|
31
|
-
expect(node).toEqual({
|
|
32
|
-
a: { existing: true, b: { c: true } },
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("is idempotent when the same leaf is marked twice", () => {
|
|
37
|
-
const node: ChangeNode = {};
|
|
38
|
-
markChanged(node, ["a", "b"]);
|
|
39
|
-
markChanged(node, ["a", "b"]);
|
|
40
|
-
expect(node).toEqual({ a: { b: true } });
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("rejects unsafe path segments", () => {
|
|
44
|
-
const node: ChangeNode = {};
|
|
45
|
-
expect(() => markChanged(node, ["__proto__", "polluted"])).toThrow(
|
|
46
|
-
/Unsafe gorp path segment/,
|
|
47
|
-
);
|
|
48
|
-
expect(({} as Record<string, unknown>).polluted).toBeUndefined();
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe("mergeChanged", () => {
|
|
53
|
-
it("returns true when either side is true", () => {
|
|
54
|
-
expect(mergeChanged(true, {})).toBe(true);
|
|
55
|
-
expect(mergeChanged({}, true)).toBe(true);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("merges disjoint subtrees in place", () => {
|
|
59
|
-
const target: ChangeNode = { a: true };
|
|
60
|
-
const source: ChangeNode = { b: true };
|
|
61
|
-
const result = mergeChanged(target, source);
|
|
62
|
-
expect(result).toBe(target);
|
|
63
|
-
expect(target).toEqual({ a: true, b: true });
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("clones source subtrees before assigning them", () => {
|
|
67
|
-
const target: ChangeNode = {};
|
|
68
|
-
const source: ChangeNode = { a: { b: true } };
|
|
69
|
-
mergeChanged(target, source);
|
|
70
|
-
(source as { a: { c?: true } }).a.c = true;
|
|
71
|
-
expect(target).toEqual({ a: { b: true } });
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("deep-merges overlapping subtrees", () => {
|
|
75
|
-
const target: ChangeNode = { a: { x: true } };
|
|
76
|
-
const source: ChangeNode = { a: { y: true } };
|
|
77
|
-
mergeChanged(target, source);
|
|
78
|
-
expect(target).toEqual({ a: { x: true, y: true } });
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("propagates `true` upward when one side has it at a shared key", () => {
|
|
82
|
-
const target: ChangeNode = { a: { x: true } };
|
|
83
|
-
const source: ChangeNode = { a: true };
|
|
84
|
-
mergeChanged(target, source);
|
|
85
|
-
expect(target).toEqual({ a: true });
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("rejects unsafe source keys", () => {
|
|
89
|
-
const target: ChangeNode = {};
|
|
90
|
-
const source = JSON.parse('{"__proto__":true}') as ChangeNode;
|
|
91
|
-
expect(() => mergeChanged(target, source)).toThrow(
|
|
92
|
-
/Unsafe gorp path segment/,
|
|
93
|
-
);
|
|
94
|
-
expect(({} as Record<string, unknown>).polluted).toBeUndefined();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("rejects nested unsafe source keys before assigning a subtree", () => {
|
|
98
|
-
const target: ChangeNode = {};
|
|
99
|
-
const source = JSON.parse('{"a":{"constructor":true}}') as ChangeNode;
|
|
100
|
-
expect(() => mergeChanged(target, source)).toThrow(
|
|
101
|
-
/Unsafe gorp path segment/,
|
|
102
|
-
);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe("lookupChange", () => {
|
|
107
|
-
it("returns false for paths that don't exist", () => {
|
|
108
|
-
expect(lookupChange({ a: true }, ["b"])).toBe(false);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("returns true when traversal hits a `true` sentinel", () => {
|
|
112
|
-
expect(lookupChange({ a: true }, ["a", "b", "c"])).toBe(true);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it("returns the subtree when the path lands on an interior node", () => {
|
|
116
|
-
const node: ChangeNode = { a: { b: true } };
|
|
117
|
-
const result = lookupChange(node, ["a"]);
|
|
118
|
-
expect(result).toEqual({ b: true });
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it("returns the root node for the empty path", () => {
|
|
122
|
-
const node: ChangeNode = { a: true };
|
|
123
|
-
expect(lookupChange(node, [])).toBe(node);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("returns false for inherited object members", () => {
|
|
127
|
-
expect(lookupChange({}, ["toString"])).toBe(false);
|
|
128
|
-
expect(lookupChange({ a: {} }, ["a", "hasOwnProperty"])).toBe(false);
|
|
129
|
-
expect(lookupChange({ a: true }, ["constructor"])).toBe(false);
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
describe("inherited object members", () => {
|
|
134
|
-
it("markChanged does not descend into inherited members", () => {
|
|
135
|
-
const node: ChangeNode = {};
|
|
136
|
-
markChanged(node, ["toString", "x"]);
|
|
137
|
-
expect(node).toEqual({ toString: { x: true } });
|
|
138
|
-
expect(lookupChange(node, ["toString", "x"])).toBe(true);
|
|
139
|
-
expect(lookupChange(node, ["valueOf"])).toBe(false);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("mergeChanged ignores inherited target members", () => {
|
|
143
|
-
const target: ChangeNode = {};
|
|
144
|
-
const source: ChangeNode = { toString: { x: true } };
|
|
145
|
-
mergeChanged(target, source);
|
|
146
|
-
expect(target).toEqual({ toString: { x: true } });
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
describe("diffKeys", () => {
|
|
151
|
-
it("returns new keys in order, then deleted keys in reverse", () => {
|
|
152
|
-
expect(diffKeys({ b: 1, c: 2 }, { a: 1, b: 2, d: 3 })).toEqual([
|
|
153
|
-
"b",
|
|
154
|
-
"c",
|
|
155
|
-
"d",
|
|
156
|
-
"a",
|
|
157
|
-
]);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("returns new keys when the old value is not an object", () => {
|
|
161
|
-
expect(diffKeys({ a: 1 }, null)).toEqual(["a"]);
|
|
162
|
-
expect(diffKeys({ a: 1 }, "str")).toEqual(["a"]);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it("returns deleted keys when the new value is not an object", () => {
|
|
166
|
-
expect(diffKeys(null, { a: 1, b: 2 })).toEqual(["b", "a"]);
|
|
167
|
-
});
|
|
168
|
-
});
|