agency-lang 0.0.1

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.
Files changed (76) hide show
  1. package/README.md +7 -0
  2. package/dist/backends/baseGenerator.js +194 -0
  3. package/dist/backends/graphGenerator.integration.test.js +119 -0
  4. package/dist/backends/graphGenerator.js +308 -0
  5. package/dist/backends/index.js +3 -0
  6. package/dist/backends/typescriptGenerator/builtins.js +46 -0
  7. package/dist/backends/typescriptGenerator/typeToString.js +36 -0
  8. package/dist/backends/typescriptGenerator/typeToZodSchema.js +54 -0
  9. package/dist/backends/typescriptGenerator.integration.test.js +119 -0
  10. package/dist/backends/typescriptGenerator.js +340 -0
  11. package/dist/backends/typescriptGenerator.test.js +763 -0
  12. package/dist/backends/utils.js +6 -0
  13. package/dist/generate-graph-file.js +25 -0
  14. package/dist/generate-ts-file.js +26 -0
  15. package/dist/index.js +3 -0
  16. package/dist/parser.js +38 -0
  17. package/dist/parser.test.js +306 -0
  18. package/dist/parsers/access.js +19 -0
  19. package/dist/parsers/access.test.js +929 -0
  20. package/dist/parsers/assignment.js +8 -0
  21. package/dist/parsers/body.test.js +106 -0
  22. package/dist/parsers/comment.js +6 -0
  23. package/dist/parsers/comment.test.js +100 -0
  24. package/dist/parsers/dataStructures.js +14 -0
  25. package/dist/parsers/dataStructures.test.js +660 -0
  26. package/dist/parsers/function.js +22 -0
  27. package/dist/parsers/function.test.js +591 -0
  28. package/dist/parsers/functionCall.js +10 -0
  29. package/dist/parsers/functionCall.test.js +119 -0
  30. package/dist/parsers/importStatement.js +3 -0
  31. package/dist/parsers/importStatement.test.js +290 -0
  32. package/dist/parsers/literals.js +12 -0
  33. package/dist/parsers/literals.test.js +639 -0
  34. package/dist/parsers/matchBlock.js +24 -0
  35. package/dist/parsers/matchBlock.test.js +506 -0
  36. package/dist/parsers/parserUtils.js +2 -0
  37. package/dist/parsers/returnStatement.js +8 -0
  38. package/dist/parsers/tools.js +3 -0
  39. package/dist/parsers/tools.test.js +170 -0
  40. package/dist/parsers/typeHints.js +59 -0
  41. package/dist/parsers/typeHints.test.js +2754 -0
  42. package/dist/parsers/utils.js +5 -0
  43. package/dist/parsers/whileLoop.test.js +342 -0
  44. package/dist/templates/backends/graphGenerator/builtinTools.js +36 -0
  45. package/dist/templates/backends/graphGenerator/conditionalEdge.js +10 -0
  46. package/dist/templates/backends/graphGenerator/edge.js +10 -0
  47. package/dist/templates/backends/graphGenerator/goToNode.js +9 -0
  48. package/dist/templates/backends/graphGenerator/graphNode.js +15 -0
  49. package/dist/templates/backends/graphGenerator/imports.js +47 -0
  50. package/dist/templates/backends/graphGenerator/node.js +18 -0
  51. package/dist/templates/backends/graphGenerator/promptNode.js +16 -0
  52. package/dist/templates/backends/graphGenerator/startNode.js +10 -0
  53. package/dist/templates/backends/typescriptGenerator/builtinFunctions/fetch.js +17 -0
  54. package/dist/templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js +17 -0
  55. package/dist/templates/backends/typescriptGenerator/builtinFunctions/input.js +21 -0
  56. package/dist/templates/backends/typescriptGenerator/builtinFunctions/read.js +13 -0
  57. package/dist/templates/backends/typescriptGenerator/builtinTools.js +36 -0
  58. package/dist/templates/backends/typescriptGenerator/functionDefinition.js +11 -0
  59. package/dist/templates/backends/typescriptGenerator/imports.js +25 -0
  60. package/dist/templates/backends/typescriptGenerator/promptFunction.js +76 -0
  61. package/dist/templates/backends/typescriptGenerator/tool.js +23 -0
  62. package/dist/templates/backends/typescriptGenerator/toolCall.js +35 -0
  63. package/dist/types/access.js +1 -0
  64. package/dist/types/dataStructures.js +1 -0
  65. package/dist/types/function.js +1 -0
  66. package/dist/types/graphNode.js +1 -0
  67. package/dist/types/importStatement.js +1 -0
  68. package/dist/types/literals.js +1 -0
  69. package/dist/types/matchBlock.js +1 -0
  70. package/dist/types/returnStatement.js +1 -0
  71. package/dist/types/tools.js +1 -0
  72. package/dist/types/typeHints.js +1 -0
  73. package/dist/types/whileLoop.js +1 -0
  74. package/dist/types.js +11 -0
  75. package/dist/utils.js +18 -0
  76. package/package.json +52 -0
@@ -0,0 +1,660 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { agencyArrayParser, agencyObjectParser, agencyObjectKVParser, } from "./dataStructures.js";
3
+ describe("dataStructures parsers", () => {
4
+ describe("agencyArrayParser", () => {
5
+ const testCases = [
6
+ // Empty arrays
7
+ {
8
+ input: "[]",
9
+ expected: {
10
+ success: true,
11
+ result: {
12
+ type: "agencyArray",
13
+ items: [],
14
+ },
15
+ },
16
+ },
17
+ // Simple arrays with literals
18
+ {
19
+ input: "[1]",
20
+ expected: {
21
+ success: true,
22
+ result: {
23
+ type: "agencyArray",
24
+ items: [{ type: "number", value: "1" }],
25
+ },
26
+ },
27
+ },
28
+ {
29
+ input: "[1, 2, 3]",
30
+ expected: {
31
+ success: true,
32
+ result: {
33
+ type: "agencyArray",
34
+ items: [
35
+ { type: "number", value: "1" },
36
+ { type: "number", value: "2" },
37
+ { type: "number", value: "3" },
38
+ ],
39
+ },
40
+ },
41
+ },
42
+ {
43
+ input: '["hello", "world"]',
44
+ expected: {
45
+ success: true,
46
+ result: {
47
+ type: "agencyArray",
48
+ items: [
49
+ { type: "string", value: "hello" },
50
+ { type: "string", value: "world" },
51
+ ],
52
+ },
53
+ },
54
+ },
55
+ // Arrays with variables
56
+ {
57
+ input: "[x, y, z]",
58
+ expected: {
59
+ success: true,
60
+ result: {
61
+ type: "agencyArray",
62
+ items: [
63
+ { type: "variableName", value: "x" },
64
+ { type: "variableName", value: "y" },
65
+ { type: "variableName", value: "z" },
66
+ ],
67
+ },
68
+ },
69
+ },
70
+ // Mixed type arrays
71
+ {
72
+ input: '[1, "hello", foo]',
73
+ expected: {
74
+ success: true,
75
+ result: {
76
+ type: "agencyArray",
77
+ items: [
78
+ { type: "number", value: "1" },
79
+ { type: "string", value: "hello" },
80
+ { type: "variableName", value: "foo" },
81
+ ],
82
+ },
83
+ },
84
+ },
85
+ // Nested arrays
86
+ {
87
+ input: "[[1, 2], [3, 4]]",
88
+ expected: {
89
+ success: true,
90
+ result: {
91
+ type: "agencyArray",
92
+ items: [
93
+ {
94
+ type: "agencyArray",
95
+ items: [
96
+ { type: "number", value: "1" },
97
+ { type: "number", value: "2" },
98
+ ],
99
+ },
100
+ {
101
+ type: "agencyArray",
102
+ items: [
103
+ { type: "number", value: "3" },
104
+ { type: "number", value: "4" },
105
+ ],
106
+ },
107
+ ],
108
+ },
109
+ },
110
+ },
111
+ {
112
+ input: "[[[]]]",
113
+ expected: {
114
+ success: true,
115
+ result: {
116
+ type: "agencyArray",
117
+ items: [
118
+ {
119
+ type: "agencyArray",
120
+ items: [
121
+ {
122
+ type: "agencyArray",
123
+ items: [],
124
+ },
125
+ ],
126
+ },
127
+ ],
128
+ },
129
+ },
130
+ },
131
+ // Arrays with minimal whitespace
132
+ {
133
+ input: "[1,2,3]",
134
+ expected: {
135
+ success: true,
136
+ result: {
137
+ type: "agencyArray",
138
+ items: [
139
+ { type: "number", value: "1" },
140
+ { type: "number", value: "2" },
141
+ { type: "number", value: "3" },
142
+ ],
143
+ },
144
+ },
145
+ },
146
+ // Arrays with negative numbers
147
+ {
148
+ input: "[-1, -2.5, 3]",
149
+ expected: {
150
+ success: true,
151
+ result: {
152
+ type: "agencyArray",
153
+ items: [
154
+ { type: "number", value: "-1" },
155
+ { type: "number", value: "-2.5" },
156
+ { type: "number", value: "3" },
157
+ ],
158
+ },
159
+ },
160
+ },
161
+ // Failure cases
162
+ { input: "[", expected: { success: false } },
163
+ { input: "]", expected: { success: false } },
164
+ { input: "[1,", expected: { success: false } },
165
+ { input: "[,1]", expected: { success: false } },
166
+ { input: "", expected: { success: false } },
167
+ ];
168
+ testCases.forEach(({ input, expected }) => {
169
+ if (expected.success) {
170
+ it(`should parse "${input}" successfully`, () => {
171
+ const result = agencyArrayParser(input);
172
+ expect(result.success).toBe(true);
173
+ if (result.success) {
174
+ expect(result.result).toEqual(expected.result);
175
+ }
176
+ });
177
+ }
178
+ else {
179
+ it(`should fail to parse "${input}"`, () => {
180
+ const result = agencyArrayParser(input);
181
+ expect(result.success).toBe(false);
182
+ });
183
+ }
184
+ });
185
+ });
186
+ describe("agencyObjectKVParser", () => {
187
+ const testCases = [
188
+ // Simple key-value pairs
189
+ {
190
+ input: "foo: 1",
191
+ expected: {
192
+ success: true,
193
+ result: {
194
+ key: "foo",
195
+ value: { type: "number", value: "1" },
196
+ },
197
+ },
198
+ },
199
+ {
200
+ input: "bar: 2",
201
+ expected: {
202
+ success: true,
203
+ result: {
204
+ key: "bar",
205
+ value: { type: "number", value: "2" },
206
+ },
207
+ },
208
+ },
209
+ {
210
+ input: 'name: "Alice"',
211
+ expected: {
212
+ success: true,
213
+ result: {
214
+ key: "name",
215
+ value: { type: "string", value: "Alice" },
216
+ },
217
+ },
218
+ },
219
+ // Quoted keys
220
+ {
221
+ input: '"foo": 1',
222
+ expected: {
223
+ success: true,
224
+ result: {
225
+ key: "foo",
226
+ value: { type: "number", value: "1" },
227
+ },
228
+ },
229
+ },
230
+ {
231
+ input: '"name": "Alice"',
232
+ expected: {
233
+ success: true,
234
+ result: {
235
+ key: "name",
236
+ value: { type: "string", value: "Alice" },
237
+ },
238
+ },
239
+ },
240
+ // Keys with whitespace
241
+ {
242
+ input: " foo : 1 ",
243
+ expected: {
244
+ success: true,
245
+ result: {
246
+ key: "foo",
247
+ value: { type: "number", value: "1" },
248
+ },
249
+ },
250
+ },
251
+ {
252
+ input: "foo:1",
253
+ expected: {
254
+ success: true,
255
+ result: {
256
+ key: "foo",
257
+ value: { type: "number", value: "1" },
258
+ },
259
+ },
260
+ },
261
+ // Variable values
262
+ {
263
+ input: "foo: bar",
264
+ expected: {
265
+ success: true,
266
+ result: {
267
+ key: "foo",
268
+ value: { type: "variableName", value: "bar" },
269
+ },
270
+ },
271
+ },
272
+ // Nested object values
273
+ {
274
+ input: "foo: {bar: 1}",
275
+ expected: {
276
+ success: true,
277
+ result: {
278
+ key: "foo",
279
+ value: {
280
+ type: "agencyObject",
281
+ entries: [
282
+ {
283
+ key: "bar",
284
+ value: { type: "number", value: "1" },
285
+ },
286
+ ],
287
+ },
288
+ },
289
+ },
290
+ },
291
+ // Array values
292
+ {
293
+ input: "foo: [1, 2, 3]",
294
+ expected: {
295
+ success: true,
296
+ result: {
297
+ key: "foo",
298
+ value: {
299
+ type: "agencyArray",
300
+ items: [
301
+ { type: "number", value: "1" },
302
+ { type: "number", value: "2" },
303
+ { type: "number", value: "3" },
304
+ ],
305
+ },
306
+ },
307
+ },
308
+ },
309
+ // Failure cases
310
+ { input: "foo", expected: { success: false } },
311
+ { input: "foo:", expected: { success: false } },
312
+ { input: "", expected: { success: false } },
313
+ ];
314
+ testCases.forEach(({ input, expected }) => {
315
+ if (expected.success) {
316
+ it(`should parse "${input}" successfully`, () => {
317
+ const result = agencyObjectKVParser(input);
318
+ expect(result.success).toBe(true);
319
+ if (result.success) {
320
+ expect(result.result).toEqual(expected.result);
321
+ }
322
+ });
323
+ }
324
+ else {
325
+ it(`should fail to parse "${input}"`, () => {
326
+ const result = agencyObjectKVParser(input);
327
+ expect(result.success).toBe(false);
328
+ });
329
+ }
330
+ });
331
+ });
332
+ describe("agencyObjectParser", () => {
333
+ const testCases = [
334
+ // Empty objects
335
+ {
336
+ input: "{}",
337
+ expected: {
338
+ success: true,
339
+ result: {
340
+ type: "agencyObject",
341
+ entries: [],
342
+ },
343
+ },
344
+ },
345
+ {
346
+ input: "{ }",
347
+ expected: {
348
+ success: true,
349
+ result: {
350
+ type: "agencyObject",
351
+ entries: [],
352
+ },
353
+ },
354
+ },
355
+ // Single entry objects
356
+ {
357
+ input: "{foo: 1}",
358
+ expected: {
359
+ success: true,
360
+ result: {
361
+ type: "agencyObject",
362
+ entries: [
363
+ {
364
+ key: "foo",
365
+ value: { type: "number", value: "1" },
366
+ },
367
+ ],
368
+ },
369
+ },
370
+ },
371
+ {
372
+ input: '{"name": "Alice"}',
373
+ expected: {
374
+ success: true,
375
+ result: {
376
+ type: "agencyObject",
377
+ entries: [
378
+ {
379
+ key: "name",
380
+ value: { type: "string", value: "Alice" },
381
+ },
382
+ ],
383
+ },
384
+ },
385
+ },
386
+ // Multiple entries
387
+ {
388
+ input: "{foo: 1, bar: 2}",
389
+ expected: {
390
+ success: true,
391
+ result: {
392
+ type: "agencyObject",
393
+ entries: [
394
+ {
395
+ key: "foo",
396
+ value: { type: "number", value: "1" },
397
+ },
398
+ {
399
+ key: "bar",
400
+ value: { type: "number", value: "2" },
401
+ },
402
+ ],
403
+ },
404
+ },
405
+ },
406
+ {
407
+ input: '{name: "Alice", age: 30, city: "NYC"}',
408
+ expected: {
409
+ success: true,
410
+ result: {
411
+ type: "agencyObject",
412
+ entries: [
413
+ {
414
+ key: "name",
415
+ value: { type: "string", value: "Alice" },
416
+ },
417
+ {
418
+ key: "age",
419
+ value: { type: "number", value: "30" },
420
+ },
421
+ {
422
+ key: "city",
423
+ value: { type: "string", value: "NYC" },
424
+ },
425
+ ],
426
+ },
427
+ },
428
+ },
429
+ // Objects with trailing commas
430
+ {
431
+ input: "{foo: 1,}",
432
+ expected: {
433
+ success: true,
434
+ result: {
435
+ type: "agencyObject",
436
+ entries: [
437
+ {
438
+ key: "foo",
439
+ value: { type: "number", value: "1" },
440
+ },
441
+ ],
442
+ },
443
+ },
444
+ },
445
+ {
446
+ input: "{foo: 1, bar: 2,}",
447
+ expected: {
448
+ success: true,
449
+ result: {
450
+ type: "agencyObject",
451
+ entries: [
452
+ {
453
+ key: "foo",
454
+ value: { type: "number", value: "1" },
455
+ },
456
+ {
457
+ key: "bar",
458
+ value: { type: "number", value: "2" },
459
+ },
460
+ ],
461
+ },
462
+ },
463
+ },
464
+ // Objects with whitespace variations
465
+ {
466
+ input: "{ foo : 1 , bar : 2 }",
467
+ expected: {
468
+ success: true,
469
+ result: {
470
+ type: "agencyObject",
471
+ entries: [
472
+ {
473
+ key: "foo",
474
+ value: { type: "number", value: "1" },
475
+ },
476
+ {
477
+ key: "bar",
478
+ value: { type: "number", value: "2" },
479
+ },
480
+ ],
481
+ },
482
+ },
483
+ },
484
+ {
485
+ input: "{foo:1,bar:2}",
486
+ expected: {
487
+ success: true,
488
+ result: {
489
+ type: "agencyObject",
490
+ entries: [
491
+ {
492
+ key: "foo",
493
+ value: { type: "number", value: "1" },
494
+ },
495
+ {
496
+ key: "bar",
497
+ value: { type: "number", value: "2" },
498
+ },
499
+ ],
500
+ },
501
+ },
502
+ },
503
+ // Nested objects
504
+ {
505
+ input: "{outer: {inner: 1}}",
506
+ expected: {
507
+ success: true,
508
+ result: {
509
+ type: "agencyObject",
510
+ entries: [
511
+ {
512
+ key: "outer",
513
+ value: {
514
+ type: "agencyObject",
515
+ entries: [
516
+ {
517
+ key: "inner",
518
+ value: { type: "number", value: "1" },
519
+ },
520
+ ],
521
+ },
522
+ },
523
+ ],
524
+ },
525
+ },
526
+ },
527
+ {
528
+ input: "{a: {b: {c: 1}}}",
529
+ expected: {
530
+ success: true,
531
+ result: {
532
+ type: "agencyObject",
533
+ entries: [
534
+ {
535
+ key: "a",
536
+ value: {
537
+ type: "agencyObject",
538
+ entries: [
539
+ {
540
+ key: "b",
541
+ value: {
542
+ type: "agencyObject",
543
+ entries: [
544
+ {
545
+ key: "c",
546
+ value: { type: "number", value: "1" },
547
+ },
548
+ ],
549
+ },
550
+ },
551
+ ],
552
+ },
553
+ },
554
+ ],
555
+ },
556
+ },
557
+ },
558
+ // Objects with array values
559
+ {
560
+ input: "{nums: [1, 2, 3]}",
561
+ expected: {
562
+ success: true,
563
+ result: {
564
+ type: "agencyObject",
565
+ entries: [
566
+ {
567
+ key: "nums",
568
+ value: {
569
+ type: "agencyArray",
570
+ items: [
571
+ { type: "number", value: "1" },
572
+ { type: "number", value: "2" },
573
+ { type: "number", value: "3" },
574
+ ],
575
+ },
576
+ },
577
+ ],
578
+ },
579
+ },
580
+ },
581
+ // Objects with variable values
582
+ {
583
+ input: "{foo: bar, baz: qux}",
584
+ expected: {
585
+ success: true,
586
+ result: {
587
+ type: "agencyObject",
588
+ entries: [
589
+ {
590
+ key: "foo",
591
+ value: { type: "variableName", value: "bar" },
592
+ },
593
+ {
594
+ key: "baz",
595
+ value: { type: "variableName", value: "qux" },
596
+ },
597
+ ],
598
+ },
599
+ },
600
+ },
601
+ // Mixed types
602
+ {
603
+ input: '{name: "Alice", age: 30, active: true, tags: ["a", "b"]}',
604
+ expected: {
605
+ success: true,
606
+ result: {
607
+ type: "agencyObject",
608
+ entries: [
609
+ {
610
+ key: "name",
611
+ value: { type: "string", value: "Alice" },
612
+ },
613
+ {
614
+ key: "age",
615
+ value: { type: "number", value: "30" },
616
+ },
617
+ {
618
+ key: "active",
619
+ value: { type: "variableName", value: "true" },
620
+ },
621
+ {
622
+ key: "tags",
623
+ value: {
624
+ type: "agencyArray",
625
+ items: [
626
+ { type: "string", value: "a" },
627
+ { type: "string", value: "b" },
628
+ ],
629
+ },
630
+ },
631
+ ],
632
+ },
633
+ },
634
+ },
635
+ // Failure cases
636
+ { input: "{", expected: { success: false } },
637
+ { input: "}", expected: { success: false } },
638
+ { input: "{foo}", expected: { success: false } },
639
+ { input: "{foo:}", expected: { success: false } },
640
+ { input: "", expected: { success: false } },
641
+ ];
642
+ testCases.forEach(({ input, expected }) => {
643
+ if (expected.success) {
644
+ it(`should parse "${input}" successfully`, () => {
645
+ const result = agencyObjectParser(input);
646
+ expect(result.success).toBe(true);
647
+ if (result.success) {
648
+ expect(result.result).toEqual(expected.result);
649
+ }
650
+ });
651
+ }
652
+ else {
653
+ it(`should fail to parse "${input}"`, () => {
654
+ const result = agencyObjectParser(input);
655
+ expect(result.success).toBe(false);
656
+ });
657
+ }
658
+ });
659
+ });
660
+ });
@@ -0,0 +1,22 @@
1
+ import { capture, char, debug, many1, many1Till, many1WithJoin, map, or, sepBy, seqC, set, space, spaces, str, succeed, trace, } from "tarsec";
2
+ import { accessExpressionParser } from "./access.js";
3
+ import { assignmentParser } from "./assignment.js";
4
+ import { commentParser } from "./comment.js";
5
+ import { functionCallParser } from "./functionCall.js";
6
+ import { literalParser } from "./literals.js";
7
+ import { matchBlockParser } from "./matchBlock.js";
8
+ import { optionalSemicolon } from "./parserUtils.js";
9
+ import { typeAliasParser, typeHintParser } from "./typeHints.js";
10
+ import { comma, optionalSpaces, varNameChar } from "./utils.js";
11
+ import { returnStatementParser } from "./returnStatement.js";
12
+ import { usesToolParser } from "./tools.js";
13
+ const trim = (s) => s.trim();
14
+ export const docStringParser = trace("docStringParser", seqC(set("type", "docString"), str('"""'), capture(map(many1Till(str('"""')), trim), "value"), str('"""')));
15
+ export const bodyParser = trace("functionBodyParser", (input) => {
16
+ const parser = sepBy(spaces, or(usesToolParser, debug(typeAliasParser, "error in typeAliasParser"), debug(typeHintParser, "error in typeHintParser"), returnStatementParser, whileLoopParser, matchBlockParser, functionParser, accessExpressionParser, assignmentParser, functionCallParser, literalParser, commentParser));
17
+ const result = parser(input);
18
+ return result;
19
+ });
20
+ export const whileLoopParser = trace("whileLoopParser", seqC(set("type", "whileLoop"), str("while"), optionalSpaces, char("("), optionalSpaces, capture(or(functionCallParser, accessExpressionParser, literalParser), "condition"), optionalSpaces, char(")"), optionalSpaces, char("{"), spaces, capture(bodyParser, "body"), optionalSpaces, char("}")));
21
+ export const functionParser = trace("functionParser", seqC(set("type", "function"), str("def"), many1(space), capture(many1Till(char("(")), "functionName"), char("("), optionalSpaces, capture(sepBy(comma, many1WithJoin(varNameChar)), "parameters"), optionalSpaces, char(")"), optionalSpaces, char("{"), optionalSpaces, capture(or(docStringParser, succeed(undefined)), "docString"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
22
+ export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(or(sepBy(comma, many1WithJoin(varNameChar)), succeed([])), "parameters"), optionalSpaces, char(")"), optionalSpaces, char("{"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));