@positronic/core 0.0.3 → 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.
@@ -1,733 +0,0 @@
1
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
- try {
3
- var info = gen[key](arg);
4
- var value = info.value;
5
- } catch (error) {
6
- reject(error);
7
- return;
8
- }
9
- if (info.done) {
10
- resolve(value);
11
- } else {
12
- Promise.resolve(value).then(_next, _throw);
13
- }
14
- }
15
- function _async_to_generator(fn) {
16
- return function() {
17
- var self = this, args = arguments;
18
- return new Promise(function(resolve, reject) {
19
- var gen = fn.apply(self, args);
20
- function _next(value) {
21
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
- }
23
- function _throw(err) {
24
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
- }
26
- _next(undefined);
27
- });
28
- };
29
- }
30
- function _define_property(obj, key, value) {
31
- if (key in obj) {
32
- Object.defineProperty(obj, key, {
33
- value: value,
34
- enumerable: true,
35
- configurable: true,
36
- writable: true
37
- });
38
- } else {
39
- obj[key] = value;
40
- }
41
- return obj;
42
- }
43
- function _object_spread(target) {
44
- for(var i = 1; i < arguments.length; i++){
45
- var source = arguments[i] != null ? arguments[i] : {};
46
- var ownKeys = Object.keys(source);
47
- if (typeof Object.getOwnPropertySymbols === "function") {
48
- ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
49
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
50
- }));
51
- }
52
- ownKeys.forEach(function(key) {
53
- _define_property(target, key, source[key]);
54
- });
55
- }
56
- return target;
57
- }
58
- function ownKeys(object, enumerableOnly) {
59
- var keys = Object.keys(object);
60
- if (Object.getOwnPropertySymbols) {
61
- var symbols = Object.getOwnPropertySymbols(object);
62
- if (enumerableOnly) {
63
- symbols = symbols.filter(function(sym) {
64
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
65
- });
66
- }
67
- keys.push.apply(keys, symbols);
68
- }
69
- return keys;
70
- }
71
- function _object_spread_props(target, source) {
72
- source = source != null ? source : {};
73
- if (Object.getOwnPropertyDescriptors) {
74
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
75
- } else {
76
- ownKeys(Object(source)).forEach(function(key) {
77
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
78
- });
79
- }
80
- return target;
81
- }
82
- function _ts_generator(thisArg, body) {
83
- var f, y, t, _ = {
84
- label: 0,
85
- sent: function() {
86
- if (t[0] & 1) throw t[1];
87
- return t[1];
88
- },
89
- trys: [],
90
- ops: []
91
- }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
92
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
93
- return this;
94
- }), g;
95
- function verb(n) {
96
- return function(v) {
97
- return step([
98
- n,
99
- v
100
- ]);
101
- };
102
- }
103
- function step(op) {
104
- if (f) throw new TypeError("Generator is already executing.");
105
- while(g && (g = 0, op[0] && (_ = 0)), _)try {
106
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
107
- if (y = 0, t) op = [
108
- op[0] & 2,
109
- t.value
110
- ];
111
- switch(op[0]){
112
- case 0:
113
- case 1:
114
- t = op;
115
- break;
116
- case 4:
117
- _.label++;
118
- return {
119
- value: op[1],
120
- done: false
121
- };
122
- case 5:
123
- _.label++;
124
- y = op[1];
125
- op = [
126
- 0
127
- ];
128
- continue;
129
- case 7:
130
- op = _.ops.pop();
131
- _.trys.pop();
132
- continue;
133
- default:
134
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
135
- _ = 0;
136
- continue;
137
- }
138
- if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
139
- _.label = op[1];
140
- break;
141
- }
142
- if (op[0] === 6 && _.label < t[1]) {
143
- _.label = t[1];
144
- t = op;
145
- break;
146
- }
147
- if (t && _.label < t[2]) {
148
- _.label = t[2];
149
- _.ops.push(op);
150
- break;
151
- }
152
- if (t[2]) _.ops.pop();
153
- _.trys.pop();
154
- continue;
155
- }
156
- op = body.call(thisArg, _);
157
- } catch (e) {
158
- op = [
159
- 6,
160
- e
161
- ];
162
- y = 0;
163
- } finally{
164
- f = t = 0;
165
- }
166
- if (op[0] & 5) throw op[1];
167
- return {
168
- value: op[0] ? op[1] : void 0,
169
- done: true
170
- };
171
- }
172
- }
173
- import { BrainRunner } from './brain-runner.js';
174
- import { brain } from './brain.js';
175
- import { BRAIN_EVENTS, STATUS } from './constants.js';
176
- import { jest, describe, it, expect, beforeEach } from '@jest/globals';
177
- import { createResources } from '../resources/resources.js';
178
- import { z } from 'zod';
179
- describe('BrainRunner', function() {
180
- var mockGenerateObject = jest.fn();
181
- var mockClient = {
182
- generateObject: mockGenerateObject
183
- };
184
- var mockDispatch = jest.fn();
185
- var mockAdapter = {
186
- dispatch: mockDispatch
187
- };
188
- beforeEach(function() {
189
- jest.clearAllMocks();
190
- });
191
- it('should run a brain and dispatch events to adapters', function() {
192
- return _async_to_generator(function() {
193
- var runner, testBrain, stepCompletions;
194
- return _ts_generator(this, function(_state) {
195
- switch(_state.label){
196
- case 0:
197
- runner = new BrainRunner({
198
- adapters: [
199
- mockAdapter
200
- ],
201
- client: mockClient
202
- });
203
- testBrain = brain('Test Brain').step('First Step', function() {
204
- return {
205
- value: 42
206
- };
207
- }).step('Async Step', function(param) {
208
- var state = param.state;
209
- return _async_to_generator(function() {
210
- return _ts_generator(this, function(_state) {
211
- switch(_state.label){
212
- case 0:
213
- return [
214
- 4,
215
- new Promise(function(resolve) {
216
- return setTimeout(resolve, 10);
217
- })
218
- ];
219
- case 1:
220
- _state.sent();
221
- return [
222
- 2,
223
- _object_spread_props(_object_spread({}, state), {
224
- asyncValue: 'completed'
225
- })
226
- ];
227
- }
228
- });
229
- })();
230
- }).step('Final Step', function(param) {
231
- var state = param.state;
232
- return _object_spread_props(_object_spread({}, state), {
233
- finalValue: state.value * 2
234
- });
235
- });
236
- return [
237
- 4,
238
- runner.run(testBrain)
239
- ];
240
- case 1:
241
- _state.sent();
242
- // Verify adapter received all events in correct order
243
- expect(mockAdapter.dispatch).toHaveBeenCalledWith(expect.objectContaining({
244
- type: BRAIN_EVENTS.START,
245
- brainTitle: 'Test Brain'
246
- }));
247
- expect(mockAdapter.dispatch).toHaveBeenCalledWith(expect.objectContaining({
248
- type: BRAIN_EVENTS.STEP_COMPLETE,
249
- stepTitle: 'First Step'
250
- }));
251
- expect(mockAdapter.dispatch).toHaveBeenCalledWith(expect.objectContaining({
252
- type: BRAIN_EVENTS.STEP_COMPLETE,
253
- stepTitle: 'Async Step'
254
- }));
255
- expect(mockAdapter.dispatch).toHaveBeenCalledWith(expect.objectContaining({
256
- type: BRAIN_EVENTS.STEP_COMPLETE,
257
- stepTitle: 'Final Step'
258
- }));
259
- expect(mockAdapter.dispatch).toHaveBeenCalledWith(expect.objectContaining({
260
- type: BRAIN_EVENTS.COMPLETE,
261
- status: STATUS.COMPLETE
262
- }));
263
- // Verify the order of events
264
- stepCompletions = mockAdapter.dispatch.mock.calls.filter(function(call) {
265
- return call[0].type === BRAIN_EVENTS.STEP_COMPLETE;
266
- }).map(function(call) {
267
- return call[0].stepTitle;
268
- });
269
- expect(stepCompletions).toEqual([
270
- 'First Step',
271
- 'Async Step',
272
- 'Final Step'
273
- ]);
274
- return [
275
- 2
276
- ];
277
- }
278
- });
279
- })();
280
- });
281
- it('should handle brain errors', function() {
282
- return _async_to_generator(function() {
283
- var runner, errorBrain, error;
284
- return _ts_generator(this, function(_state) {
285
- switch(_state.label){
286
- case 0:
287
- runner = new BrainRunner({
288
- adapters: [
289
- mockAdapter
290
- ],
291
- client: mockClient
292
- });
293
- errorBrain = brain('Error Brain').step('Error Step', function() {
294
- throw new Error('Test error');
295
- });
296
- _state.label = 1;
297
- case 1:
298
- _state.trys.push([
299
- 1,
300
- 3,
301
- ,
302
- 4
303
- ]);
304
- return [
305
- 4,
306
- runner.run(errorBrain)
307
- ];
308
- case 2:
309
- _state.sent();
310
- return [
311
- 3,
312
- 4
313
- ];
314
- case 3:
315
- error = _state.sent();
316
- return [
317
- 3,
318
- 4
319
- ];
320
- case 4:
321
- // Verify error event was dispatched
322
- expect(mockAdapter.dispatch).toHaveBeenCalledWith(expect.objectContaining({
323
- type: BRAIN_EVENTS.ERROR,
324
- error: expect.objectContaining({
325
- message: 'Test error'
326
- })
327
- }));
328
- return [
329
- 2
330
- ];
331
- }
332
- });
333
- })();
334
- });
335
- it('should maintain state between steps', function() {
336
- return _async_to_generator(function() {
337
- var runner, testBrain, result;
338
- return _ts_generator(this, function(_state) {
339
- switch(_state.label){
340
- case 0:
341
- runner = new BrainRunner({
342
- adapters: [],
343
- client: mockClient
344
- });
345
- testBrain = brain('Test Brain').step('First Step', function() {
346
- return {
347
- count: 1
348
- };
349
- }).step('Second Step', function(param) {
350
- var state = param.state;
351
- return {
352
- count: state.count + 1
353
- };
354
- });
355
- return [
356
- 4,
357
- runner.run(testBrain)
358
- ];
359
- case 1:
360
- result = _state.sent();
361
- expect(result.count).toEqual(2);
362
- return [
363
- 2
364
- ];
365
- }
366
- });
367
- })();
368
- });
369
- it('should pass resources to step actions', function() {
370
- return _async_to_generator(function() {
371
- var mockLoad, mockResourceLoader, testManifest, testResources, runner, textContent, binaryContent, resourceConsumingBrain;
372
- return _ts_generator(this, function(_state) {
373
- switch(_state.label){
374
- case 0:
375
- mockLoad = jest.fn(function(resourceName, type) {
376
- return _async_to_generator(function() {
377
- return _ts_generator(this, function(_state) {
378
- if (type === 'binary') {
379
- return [
380
- 2,
381
- Buffer.from("content of ".concat(resourceName))
382
- ];
383
- }
384
- return [
385
- 2,
386
- "content of ".concat(resourceName)
387
- ];
388
- });
389
- })();
390
- });
391
- mockResourceLoader = {
392
- load: mockLoad
393
- };
394
- testManifest = {
395
- myTextFile: {
396
- type: 'text',
397
- key: 'myTextFile',
398
- path: '/test/myTextFile.txt'
399
- },
400
- myBinaryFile: {
401
- type: 'binary',
402
- key: 'myBinaryFile',
403
- path: '/test/myBinaryFile.bin'
404
- }
405
- };
406
- testResources = createResources(mockResourceLoader, testManifest);
407
- runner = new BrainRunner({
408
- adapters: [],
409
- client: mockClient
410
- }).withResources(testResources);
411
- resourceConsumingBrain = brain('Resource Brain').step('Load Resources', function(param) {
412
- var resources = param.resources;
413
- return _async_to_generator(function() {
414
- return _ts_generator(this, function(_state) {
415
- switch(_state.label){
416
- case 0:
417
- return [
418
- 4,
419
- resources.myTextFile.loadText()
420
- ];
421
- case 1:
422
- textContent = _state.sent();
423
- return [
424
- 4,
425
- resources.myBinaryFile.loadBinary()
426
- ];
427
- case 2:
428
- binaryContent = _state.sent();
429
- return [
430
- 2,
431
- {}
432
- ];
433
- }
434
- });
435
- })();
436
- });
437
- return [
438
- 4,
439
- runner.run(resourceConsumingBrain)
440
- ];
441
- case 1:
442
- _state.sent();
443
- expect(mockLoad).toHaveBeenCalledWith('myTextFile', 'text');
444
- expect(mockLoad).toHaveBeenCalledWith('myBinaryFile', 'binary');
445
- expect(textContent).toBe('content of myTextFile');
446
- expect(binaryContent === null || binaryContent === void 0 ? void 0 : binaryContent.toString()).toBe('content of myBinaryFile');
447
- return [
448
- 2
449
- ];
450
- }
451
- });
452
- })();
453
- });
454
- it('should chain adapters with withAdapters method', function() {
455
- return _async_to_generator(function() {
456
- var mockAdapter2, mockAdapter3, runner, updatedRunner, testBrain;
457
- return _ts_generator(this, function(_state) {
458
- switch(_state.label){
459
- case 0:
460
- mockAdapter2 = {
461
- dispatch: jest.fn()
462
- };
463
- mockAdapter3 = {
464
- dispatch: jest.fn()
465
- };
466
- runner = new BrainRunner({
467
- adapters: [
468
- mockAdapter
469
- ],
470
- client: mockClient
471
- });
472
- // Chain additional adapters
473
- updatedRunner = runner.withAdapters([
474
- mockAdapter2,
475
- mockAdapter3
476
- ]);
477
- testBrain = brain('Test Brain').step('Step 1', function() {
478
- return {
479
- value: 1
480
- };
481
- });
482
- return [
483
- 4,
484
- updatedRunner.run(testBrain)
485
- ];
486
- case 1:
487
- _state.sent();
488
- // Verify all adapters received events
489
- expect(mockAdapter.dispatch).toHaveBeenCalledWith(expect.objectContaining({
490
- type: BRAIN_EVENTS.START
491
- }));
492
- expect(mockAdapter2.dispatch).toHaveBeenCalledWith(expect.objectContaining({
493
- type: BRAIN_EVENTS.START
494
- }));
495
- expect(mockAdapter3.dispatch).toHaveBeenCalledWith(expect.objectContaining({
496
- type: BRAIN_EVENTS.START
497
- }));
498
- // Verify all adapters received the same number of events
499
- expect(mockAdapter.dispatch).toHaveBeenCalledTimes(mockAdapter2.dispatch.mock.calls.length);
500
- expect(mockAdapter2.dispatch).toHaveBeenCalledTimes(mockAdapter3.dispatch.mock.calls.length);
501
- return [
502
- 2
503
- ];
504
- }
505
- });
506
- })();
507
- });
508
- it('should replace client with withClient method', function() {
509
- return _async_to_generator(function() {
510
- var originalClient, newClient, runner, updatedRunner, testSchema, testBrain, result;
511
- return _ts_generator(this, function(_state) {
512
- switch(_state.label){
513
- case 0:
514
- originalClient = {
515
- generateObject: jest.fn()
516
- };
517
- newClient = {
518
- generateObject: jest.fn()
519
- };
520
- // Configure the new client's response
521
- newClient.generateObject.mockResolvedValue({
522
- result: 'from new client'
523
- });
524
- runner = new BrainRunner({
525
- adapters: [],
526
- client: originalClient
527
- });
528
- // Replace the client
529
- updatedRunner = runner.withClient(newClient);
530
- // Define schema once to ensure same reference
531
- testSchema = z.object({
532
- result: z.string()
533
- });
534
- testBrain = brain('Test Brain').step('Generate', function(param) {
535
- var client = param.client;
536
- return _async_to_generator(function() {
537
- var response;
538
- return _ts_generator(this, function(_state) {
539
- switch(_state.label){
540
- case 0:
541
- return [
542
- 4,
543
- client.generateObject({
544
- prompt: 'test prompt',
545
- schema: testSchema,
546
- schemaName: 'TestSchema'
547
- })
548
- ];
549
- case 1:
550
- response = _state.sent();
551
- return [
552
- 2,
553
- {
554
- generated: response.result
555
- }
556
- ];
557
- }
558
- });
559
- })();
560
- });
561
- return [
562
- 4,
563
- updatedRunner.run(testBrain)
564
- ];
565
- case 1:
566
- result = _state.sent();
567
- // Verify new client was used, not the original
568
- expect(originalClient.generateObject).not.toHaveBeenCalled();
569
- expect(newClient.generateObject).toHaveBeenCalledWith({
570
- prompt: 'test prompt',
571
- schema: testSchema,
572
- schemaName: 'TestSchema'
573
- });
574
- expect(result.generated).toBe('from new client');
575
- return [
576
- 2
577
- ];
578
- }
579
- });
580
- })();
581
- });
582
- it('should apply patches from initialCompletedSteps and continue from correct state', function() {
583
- return _async_to_generator(function() {
584
- var runner, completedSteps, testBrain, result, stepCompleteEvents;
585
- return _ts_generator(this, function(_state) {
586
- switch(_state.label){
587
- case 0:
588
- runner = new BrainRunner({
589
- adapters: [
590
- mockAdapter
591
- ],
592
- client: mockClient
593
- });
594
- // Simulate completed steps with patches
595
- completedSteps = [
596
- {
597
- id: 'step-1',
598
- title: 'First Step',
599
- status: STATUS.COMPLETE,
600
- patch: [
601
- {
602
- op: 'add',
603
- path: '/count',
604
- value: 10
605
- }
606
- ]
607
- },
608
- {
609
- id: 'step-2',
610
- title: 'Second Step',
611
- status: STATUS.COMPLETE,
612
- patch: [
613
- {
614
- op: 'add',
615
- path: '/name',
616
- value: 'test'
617
- }
618
- ]
619
- }
620
- ];
621
- testBrain = brain('Test Brain').step('First Step', function() {
622
- return {
623
- count: 10
624
- };
625
- }).step('Second Step', function(param) {
626
- var state = param.state;
627
- return _object_spread_props(_object_spread({}, state), {
628
- name: 'test'
629
- });
630
- }).step('Third Step', function(param) {
631
- var state = param.state;
632
- return _object_spread_props(_object_spread({}, state), {
633
- count: state.count + 5,
634
- message: "".concat(state.name, " completed")
635
- });
636
- });
637
- return [
638
- 4,
639
- runner.run(testBrain, {
640
- initialCompletedSteps: completedSteps,
641
- brainRunId: 'test-run-123'
642
- })
643
- ];
644
- case 1:
645
- result = _state.sent();
646
- // Verify the final state includes patches from completed steps
647
- expect(result).toEqual({
648
- count: 15,
649
- name: 'test',
650
- message: 'test completed'
651
- });
652
- // Verify that the brain runner applied the patches correctly
653
- // The runner should have seen all steps execute, but the first two were already completed
654
- stepCompleteEvents = mockAdapter.dispatch.mock.calls.filter(function(call) {
655
- return call[0].type === BRAIN_EVENTS.STEP_COMPLETE;
656
- });
657
- // All steps will emit complete events in the current implementation
658
- expect(stepCompleteEvents.length).toBeGreaterThanOrEqual(1);
659
- return [
660
- 2
661
- ];
662
- }
663
- });
664
- })();
665
- });
666
- it('should stop execution after specified number of steps with endAfter parameter', function() {
667
- return _async_to_generator(function() {
668
- var runner, testBrain, result, stepCompleteEvents, completeEvents;
669
- return _ts_generator(this, function(_state) {
670
- switch(_state.label){
671
- case 0:
672
- runner = new BrainRunner({
673
- adapters: [
674
- mockAdapter
675
- ],
676
- client: mockClient
677
- });
678
- testBrain = brain('Test Brain').step('Step 1', function() {
679
- return {
680
- step1: 'done'
681
- };
682
- }).step('Step 2', function(param) {
683
- var state = param.state;
684
- return _object_spread_props(_object_spread({}, state), {
685
- step2: 'done'
686
- });
687
- }).step('Step 3', function(param) {
688
- var state = param.state;
689
- return _object_spread_props(_object_spread({}, state), {
690
- step3: 'done'
691
- });
692
- }).step('Step 4', function(param) {
693
- var state = param.state;
694
- return _object_spread_props(_object_spread({}, state), {
695
- step4: 'done'
696
- });
697
- });
698
- return [
699
- 4,
700
- runner.run(testBrain, {
701
- endAfter: 2
702
- })
703
- ];
704
- case 1:
705
- result = _state.sent();
706
- // Verify state only has results from first 2 steps
707
- expect(result).toEqual({
708
- step1: 'done',
709
- step2: 'done'
710
- });
711
- // Verify only 2 step complete events were dispatched
712
- stepCompleteEvents = mockAdapter.dispatch.mock.calls.filter(function(call) {
713
- return call[0].type === BRAIN_EVENTS.STEP_COMPLETE;
714
- }).map(function(call) {
715
- return call[0].stepTitle;
716
- });
717
- expect(stepCompleteEvents).toEqual([
718
- 'Step 1',
719
- 'Step 2'
720
- ]);
721
- // Verify that COMPLETE event was NOT dispatched (brain didn't finish)
722
- completeEvents = mockAdapter.dispatch.mock.calls.filter(function(call) {
723
- return call[0].type === BRAIN_EVENTS.COMPLETE;
724
- });
725
- expect(completeEvents.length).toBe(0);
726
- return [
727
- 2
728
- ];
729
- }
730
- });
731
- })();
732
- });
733
- });