@providerprotocol/agents 0.0.2 → 0.0.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.
- package/LICENSE +21 -0
- package/dist/checkpoint/index.d.ts +43 -0
- package/dist/checkpoint/index.js +73 -0
- package/dist/checkpoint/index.js.map +1 -0
- package/{src/execution/loop.ts → dist/chunk-4ESYN66B.js} +54 -162
- package/dist/chunk-4ESYN66B.js.map +1 -0
- package/dist/chunk-EKRXMSDX.js +8 -0
- package/dist/chunk-EKRXMSDX.js.map +1 -0
- package/dist/chunk-T47B3VAF.js +427 -0
- package/dist/chunk-T47B3VAF.js.map +1 -0
- package/dist/execution/index.d.ts +105 -0
- package/dist/execution/index.js +679 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/index-qsPwbY86.d.ts +65 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/index.d.ts +23 -0
- package/dist/middleware/index.js +82 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/thread-tree/index.d.ts +115 -0
- package/dist/thread-tree/index.js +4 -0
- package/dist/thread-tree/index.js.map +1 -0
- package/dist/types-2Vsthzyu.d.ts +163 -0
- package/dist/types-BiyEVOnf.d.ts +65 -0
- package/dist/types-D1egxttz.d.ts +270 -0
- package/dist/types-DChRdQoX.d.ts +98 -0
- package/package.json +41 -9
- package/.claude/settings.local.json +0 -29
- package/AGENTS.md +0 -681
- package/CLAUDE.md +0 -681
- package/bun.lock +0 -472
- package/eslint.config.js +0 -75
- package/index.ts +0 -1
- package/llms.md +0 -796
- package/specs/UAP-1.0.md +0 -2355
- package/src/agent/index.ts +0 -384
- package/src/agent/types.ts +0 -91
- package/src/checkpoint/file.ts +0 -126
- package/src/checkpoint/index.ts +0 -40
- package/src/checkpoint/types.ts +0 -95
- package/src/execution/index.ts +0 -37
- package/src/execution/plan.ts +0 -497
- package/src/execution/react.ts +0 -340
- package/src/execution/tool-ordering.ts +0 -186
- package/src/execution/types.ts +0 -315
- package/src/index.ts +0 -80
- package/src/middleware/index.ts +0 -7
- package/src/middleware/logging.ts +0 -123
- package/src/middleware/types.ts +0 -69
- package/src/state/index.ts +0 -301
- package/src/state/types.ts +0 -173
- package/src/thread-tree/index.ts +0 -249
- package/src/thread-tree/types.ts +0 -29
- package/src/utils/uuid.ts +0 -7
- package/tests/live/agent-anthropic.test.ts +0 -288
- package/tests/live/agent-strategy-hooks.test.ts +0 -268
- package/tests/live/checkpoint.test.ts +0 -243
- package/tests/live/execution-strategies.test.ts +0 -255
- package/tests/live/plan-strategy.test.ts +0 -160
- package/tests/live/subagent-events.live.test.ts +0 -249
- package/tests/live/thread-tree.test.ts +0 -186
- package/tests/unit/agent.test.ts +0 -703
- package/tests/unit/checkpoint.test.ts +0 -232
- package/tests/unit/execution/equivalence.test.ts +0 -402
- package/tests/unit/execution/loop.test.ts +0 -437
- package/tests/unit/execution/plan.test.ts +0 -590
- package/tests/unit/execution/react.test.ts +0 -604
- package/tests/unit/execution/subagent-events.test.ts +0 -235
- package/tests/unit/execution/tool-ordering.test.ts +0 -310
- package/tests/unit/middleware/logging.test.ts +0 -276
- package/tests/unit/state.test.ts +0 -573
- package/tests/unit/thread-tree.test.ts +0 -249
- package/tsconfig.json +0 -29
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach } from 'bun:test';
|
|
2
|
-
import { UserMessage, AssistantMessage } from '@providerprotocol/ai';
|
|
3
|
-
import { ThreadTree, ThreadNode } from '../../src/thread-tree/index.ts';
|
|
4
|
-
import { AgentState } from '../../src/state/index.ts';
|
|
5
|
-
|
|
6
|
-
describe('ThreadNode', () => {
|
|
7
|
-
test('creates node with provided properties', () => {
|
|
8
|
-
const state = AgentState.initial();
|
|
9
|
-
const node = new ThreadNode('node-1', null, state, 'root');
|
|
10
|
-
|
|
11
|
-
expect(node.id).toBe('node-1');
|
|
12
|
-
expect(node.parentId).toBeNull();
|
|
13
|
-
expect(node.state).toBe(state);
|
|
14
|
-
expect(node.name).toBe('root');
|
|
15
|
-
expect(node.children).toEqual([]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('serializes to JSON', () => {
|
|
19
|
-
const state = AgentState.initial().withMessage(new UserMessage('Hello'));
|
|
20
|
-
const node = new ThreadNode('node-1', 'parent-1', state, 'branch', ['child-1']);
|
|
21
|
-
|
|
22
|
-
const json = node.toJSON();
|
|
23
|
-
|
|
24
|
-
expect(json.id).toBe('node-1');
|
|
25
|
-
expect(json.parentId).toBe('parent-1');
|
|
26
|
-
expect(json.name).toBe('branch');
|
|
27
|
-
expect(json.children).toEqual(['child-1']);
|
|
28
|
-
expect(json.state.messages).toHaveLength(1);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('deserializes from JSON', () => {
|
|
32
|
-
const state = AgentState.initial().withMessage(new UserMessage('Hello'));
|
|
33
|
-
const original = new ThreadNode('node-1', 'parent-1', state, 'branch', ['child-1']);
|
|
34
|
-
|
|
35
|
-
const json = original.toJSON();
|
|
36
|
-
const restored = ThreadNode.fromJSON(json);
|
|
37
|
-
|
|
38
|
-
expect(restored.id).toBe(original.id);
|
|
39
|
-
expect(restored.parentId).toBe(original.parentId);
|
|
40
|
-
expect(restored.name).toBe(original.name);
|
|
41
|
-
expect(restored.children).toEqual(original.children);
|
|
42
|
-
expect(restored.state.messages.length).toBe(original.state.messages.length);
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
describe('ThreadTree', () => {
|
|
47
|
-
let tree: ThreadTree;
|
|
48
|
-
|
|
49
|
-
beforeEach(() => {
|
|
50
|
-
tree = new ThreadTree();
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
describe('constructor', () => {
|
|
54
|
-
test('creates tree with root node', () => {
|
|
55
|
-
expect(tree.root).toBeDefined();
|
|
56
|
-
expect(tree.root.parentId).toBeNull();
|
|
57
|
-
expect(tree.root.name).toBe('root');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test('sets current to root initially', () => {
|
|
61
|
-
expect(tree.current).toBe(tree.root);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test('adds root to nodes map', () => {
|
|
65
|
-
expect(tree.nodes.has(tree.root.id)).toBe(true);
|
|
66
|
-
expect(tree.nodes.get(tree.root.id)).toBe(tree.root);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe('branch()', () => {
|
|
71
|
-
test('creates new node from specified parent', () => {
|
|
72
|
-
const newId = tree.branch(tree.root.id, 'feature-1');
|
|
73
|
-
|
|
74
|
-
expect(newId).toBeDefined();
|
|
75
|
-
expect(tree.nodes.has(newId)).toBe(true);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test('sets parent ID correctly', () => {
|
|
79
|
-
const newId = tree.branch(tree.root.id);
|
|
80
|
-
const newNode = tree.nodes.get(newId);
|
|
81
|
-
|
|
82
|
-
expect(newNode?.parentId).toBe(tree.root.id);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
test('adds child to parent', () => {
|
|
86
|
-
const newId = tree.branch(tree.root.id);
|
|
87
|
-
|
|
88
|
-
expect(tree.root.children).toContain(newId);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('copies parent state to child', () => {
|
|
92
|
-
tree.root.state = tree.root.state.withMessage(new UserMessage('Hello'));
|
|
93
|
-
const newId = tree.branch(tree.root.id);
|
|
94
|
-
const newNode = tree.nodes.get(newId);
|
|
95
|
-
|
|
96
|
-
expect(newNode?.state.messages.length).toBe(tree.root.state.messages.length);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
test('sets branch name', () => {
|
|
100
|
-
const newId = tree.branch(tree.root.id, 'my-branch');
|
|
101
|
-
const newNode = tree.nodes.get(newId);
|
|
102
|
-
|
|
103
|
-
expect(newNode?.name).toBe('my-branch');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test('throws on invalid parent ID', () => {
|
|
107
|
-
expect(() => tree.branch('invalid-id')).toThrow('Node not found');
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('checkout()', () => {
|
|
112
|
-
test('switches current node', () => {
|
|
113
|
-
const newId = tree.branch(tree.root.id, 'branch');
|
|
114
|
-
tree.checkout(newId);
|
|
115
|
-
|
|
116
|
-
expect(tree.current.id).toBe(newId);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test('throws on invalid node ID', () => {
|
|
120
|
-
expect(() => tree.checkout('invalid-id')).toThrow('Node not found');
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
describe('history()', () => {
|
|
125
|
-
test('returns empty state for root with no messages', () => {
|
|
126
|
-
const state = tree.history();
|
|
127
|
-
|
|
128
|
-
expect(state.messages).toHaveLength(0);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test('returns root messages when at root', () => {
|
|
132
|
-
tree.root.state = tree.root.state.withMessage(new UserMessage('Root message'));
|
|
133
|
-
const state = tree.history();
|
|
134
|
-
|
|
135
|
-
expect(state.messages).toHaveLength(1);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('merges messages from root to current', () => {
|
|
139
|
-
// Add message to root
|
|
140
|
-
tree.root.state = tree.root.state.withMessage(new UserMessage('Root'));
|
|
141
|
-
|
|
142
|
-
// Create branch and add message
|
|
143
|
-
const branchId = tree.branch(tree.root.id);
|
|
144
|
-
tree.checkout(branchId);
|
|
145
|
-
tree.current.state = tree.current.state.withMessage(new AssistantMessage('Branch'));
|
|
146
|
-
|
|
147
|
-
// Create child of branch and add message
|
|
148
|
-
const childId = tree.branch(branchId);
|
|
149
|
-
tree.checkout(childId);
|
|
150
|
-
tree.current.state = tree.current.state.withMessage(new UserMessage('Child'));
|
|
151
|
-
|
|
152
|
-
const state = tree.history();
|
|
153
|
-
|
|
154
|
-
// Should have messages from root + branch + child
|
|
155
|
-
// Note: Branch starts with copy of root's messages, so we have:
|
|
156
|
-
// root: [Root]
|
|
157
|
-
// branch: [Root, Branch] (inherited Root + added Branch)
|
|
158
|
-
// child: [Root, Branch, Child] (inherited [Root, Branch] + added Child)
|
|
159
|
-
expect(state.messages.length).toBeGreaterThanOrEqual(3);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
test('preserves current node metadata', () => {
|
|
163
|
-
const branchId = tree.branch(tree.root.id);
|
|
164
|
-
tree.checkout(branchId);
|
|
165
|
-
tree.current.state = tree.current.state.withStep(5);
|
|
166
|
-
|
|
167
|
-
const state = tree.history();
|
|
168
|
-
|
|
169
|
-
expect(state.step).toBe(5);
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
describe('getLeaves()', () => {
|
|
174
|
-
test('returns root as only leaf initially', () => {
|
|
175
|
-
const leaves = tree.getLeaves();
|
|
176
|
-
|
|
177
|
-
expect(leaves).toHaveLength(1);
|
|
178
|
-
expect(leaves).toContain(tree.root.id);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
test('returns only leaf nodes', () => {
|
|
182
|
-
const branch1 = tree.branch(tree.root.id);
|
|
183
|
-
const branch2 = tree.branch(tree.root.id);
|
|
184
|
-
tree.branch(branch1); // child of branch1
|
|
185
|
-
|
|
186
|
-
const leaves = tree.getLeaves();
|
|
187
|
-
|
|
188
|
-
expect(leaves).toHaveLength(2); // branch1's child and branch2
|
|
189
|
-
expect(leaves).not.toContain(tree.root.id);
|
|
190
|
-
expect(leaves).not.toContain(branch1);
|
|
191
|
-
expect(leaves).toContain(branch2);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe('getBranches()', () => {
|
|
196
|
-
test('returns named branches', () => {
|
|
197
|
-
tree.branch(tree.root.id, 'feature-1');
|
|
198
|
-
tree.branch(tree.root.id, 'feature-2');
|
|
199
|
-
tree.branch(tree.root.id); // unnamed
|
|
200
|
-
|
|
201
|
-
const branches = tree.getBranches();
|
|
202
|
-
|
|
203
|
-
expect(branches.size).toBeGreaterThanOrEqual(3); // includes root
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
describe('serialization', () => {
|
|
208
|
-
test('toJSON() serializes entire tree', () => {
|
|
209
|
-
const branch1 = tree.branch(tree.root.id, 'b1');
|
|
210
|
-
tree.branch(tree.root.id, 'b2'); // Create second branch for the test
|
|
211
|
-
tree.checkout(branch1);
|
|
212
|
-
|
|
213
|
-
const json = tree.toJSON();
|
|
214
|
-
|
|
215
|
-
expect(json.rootId).toBe(tree.root.id);
|
|
216
|
-
expect(json.currentId).toBe(branch1);
|
|
217
|
-
expect(json.nodes).toHaveLength(3);
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
test('fromJSON() restores tree', () => {
|
|
221
|
-
tree.root.state = tree.root.state.withMessage(new UserMessage('Root'));
|
|
222
|
-
const branch1 = tree.branch(tree.root.id, 'b1');
|
|
223
|
-
tree.checkout(branch1);
|
|
224
|
-
tree.current.state = tree.current.state.withMessage(new AssistantMessage('Branch'));
|
|
225
|
-
|
|
226
|
-
const json = tree.toJSON();
|
|
227
|
-
const restored = ThreadTree.fromJSON(json);
|
|
228
|
-
|
|
229
|
-
expect(restored.root.id).toBe(tree.root.id);
|
|
230
|
-
expect(restored.current.id).toBe(branch1);
|
|
231
|
-
expect(restored.nodes.size).toBe(tree.nodes.size);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
test('round-trip preserves structure', () => {
|
|
235
|
-
const b1 = tree.branch(tree.root.id, 'branch-1');
|
|
236
|
-
const b2 = tree.branch(tree.root.id, 'branch-2');
|
|
237
|
-
const b1c1 = tree.branch(b1, 'branch-1-child');
|
|
238
|
-
tree.checkout(b1c1);
|
|
239
|
-
|
|
240
|
-
const json = tree.toJSON();
|
|
241
|
-
const restored = ThreadTree.fromJSON(json);
|
|
242
|
-
|
|
243
|
-
expect(restored.root.children).toContain(b1);
|
|
244
|
-
expect(restored.root.children).toContain(b2);
|
|
245
|
-
expect(restored.nodes.get(b1)?.children).toContain(b1c1);
|
|
246
|
-
expect(restored.current.id).toBe(b1c1);
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
// Environment setup & latest features
|
|
4
|
-
"lib": ["ESNext"],
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"module": "Preserve",
|
|
7
|
-
"moduleDetection": "force",
|
|
8
|
-
"jsx": "react-jsx",
|
|
9
|
-
"allowJs": true,
|
|
10
|
-
|
|
11
|
-
// Bundler mode
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"allowImportingTsExtensions": true,
|
|
14
|
-
"verbatimModuleSyntax": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
|
|
17
|
-
// Best practices
|
|
18
|
-
"strict": true,
|
|
19
|
-
"skipLibCheck": true,
|
|
20
|
-
"noFallthroughCasesInSwitch": true,
|
|
21
|
-
"noUncheckedIndexedAccess": true,
|
|
22
|
-
"noImplicitOverride": true,
|
|
23
|
-
|
|
24
|
-
// Some stricter flags (disabled by default)
|
|
25
|
-
"noUnusedLocals": false,
|
|
26
|
-
"noUnusedParameters": false,
|
|
27
|
-
"noPropertyAccessFromIndexSignature": false
|
|
28
|
-
}
|
|
29
|
-
}
|