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,119 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { functionCallParser } from "./functionCall.js";
3
+ describe("functionCallParser", () => {
4
+ const testCases = [
5
+ {
6
+ input: "test()",
7
+ expected: {
8
+ success: true,
9
+ result: {
10
+ type: "functionCall",
11
+ functionName: "test",
12
+ arguments: [],
13
+ },
14
+ },
15
+ },
16
+ {
17
+ input: "greet(name)",
18
+ expected: {
19
+ success: true,
20
+ result: {
21
+ type: "functionCall",
22
+ functionName: "greet",
23
+ arguments: [{ type: "variableName", value: "name" }],
24
+ },
25
+ },
26
+ },
27
+ {
28
+ input: "add(x, y)",
29
+ expected: {
30
+ success: true,
31
+ result: {
32
+ type: "functionCall",
33
+ functionName: "add",
34
+ arguments: [
35
+ { type: "variableName", value: "x" },
36
+ { type: "variableName", value: "y" },
37
+ ],
38
+ },
39
+ },
40
+ },
41
+ {
42
+ input: "process(a, b, c)",
43
+ expected: {
44
+ success: true,
45
+ result: {
46
+ type: "functionCall",
47
+ functionName: "process",
48
+ arguments: [
49
+ { type: "variableName", value: "a" },
50
+ { type: "variableName", value: "b" },
51
+ { type: "variableName", value: "c" },
52
+ ],
53
+ },
54
+ },
55
+ },
56
+ {
57
+ input: "func(arg1,arg2)",
58
+ expected: {
59
+ success: true,
60
+ result: {
61
+ type: "functionCall",
62
+ functionName: "func",
63
+ arguments: [
64
+ { type: "variableName", value: "arg1" },
65
+ { type: "variableName", value: "arg2" },
66
+ ],
67
+ },
68
+ },
69
+ },
70
+ {
71
+ input: "call( arg )",
72
+ expected: {
73
+ success: true,
74
+ result: {
75
+ type: "functionCall",
76
+ functionName: "call",
77
+ arguments: [{ type: "variableName", value: "arg" }],
78
+ },
79
+ },
80
+ },
81
+ {
82
+ input: "test",
83
+ expected: { success: false },
84
+ },
85
+ {
86
+ input: "test(",
87
+ expected: { success: false },
88
+ },
89
+ {
90
+ input: "test)",
91
+ expected: { success: false },
92
+ },
93
+ {
94
+ input: "()",
95
+ expected: { success: false },
96
+ },
97
+ {
98
+ input: "",
99
+ expected: { success: false },
100
+ },
101
+ ];
102
+ testCases.forEach(({ input, expected }) => {
103
+ if (expected.success) {
104
+ it(`should parse "${input}" successfully`, () => {
105
+ const result = functionCallParser(input);
106
+ expect(result.success).toBe(true);
107
+ if (result.success) {
108
+ expect(result.result).toEqual(expected.result);
109
+ }
110
+ });
111
+ }
112
+ else {
113
+ it(`should fail to parse "${input}"`, () => {
114
+ const result = functionCallParser(input);
115
+ expect(result.success).toBe(false);
116
+ });
117
+ }
118
+ });
119
+ });
@@ -0,0 +1,3 @@
1
+ import { capture, many1Till, oneOf, seqC, set, spaces, str, trace, } from "tarsec";
2
+ import { optionalSemicolon } from "./parserUtils.js";
3
+ export const importStatmentParser = trace("importStatement", seqC(set("type", "importStatement"), str("import"), spaces, capture(many1Till(str("from")), "importedNames"), str("from"), spaces, capture(many1Till(oneOf(";\n")), "modulePath"), optionalSemicolon));
@@ -0,0 +1,290 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { importStatmentParser } from "./importStatement.js";
3
+ describe("importStatmentParser", () => {
4
+ const testCases = [
5
+ // Happy path - basic import
6
+ {
7
+ input: "import foo from bar;",
8
+ expected: {
9
+ success: true,
10
+ result: {
11
+ type: "importStatement",
12
+ importedNames: "foo ",
13
+ modulePath: "bar",
14
+ },
15
+ },
16
+ },
17
+ {
18
+ input: "import myModule from path/to/module;",
19
+ expected: {
20
+ success: true,
21
+ result: {
22
+ type: "importStatement",
23
+ importedNames: "myModule ",
24
+ modulePath: "path/to/module",
25
+ },
26
+ },
27
+ },
28
+ // Module paths with double quotes
29
+ {
30
+ input: 'import foo from "bar";',
31
+ expected: {
32
+ success: true,
33
+ result: {
34
+ type: "importStatement",
35
+ importedNames: "foo ",
36
+ modulePath: '"bar"',
37
+ },
38
+ },
39
+ },
40
+ {
41
+ input: 'import foo from "./local/path.js";',
42
+ expected: {
43
+ success: true,
44
+ result: {
45
+ type: "importStatement",
46
+ importedNames: "foo ",
47
+ modulePath: '"./local/path"',
48
+ },
49
+ },
50
+ },
51
+ {
52
+ input: 'import bar from "../utils/helper.js";',
53
+ expected: {
54
+ success: true,
55
+ result: {
56
+ type: "importStatement",
57
+ importedNames: "bar ",
58
+ modulePath: '"@/utils/helper"',
59
+ },
60
+ },
61
+ },
62
+ {
63
+ input: 'import { useState } from "react";',
64
+ expected: {
65
+ success: true,
66
+ result: {
67
+ type: "importStatement",
68
+ importedNames: "{ useState } ",
69
+ modulePath: '"react"',
70
+ },
71
+ },
72
+ },
73
+ // Module paths with single quotes
74
+ {
75
+ input: "import foo from 'bar';",
76
+ expected: {
77
+ success: true,
78
+ result: {
79
+ type: "importStatement",
80
+ importedNames: "foo ",
81
+ modulePath: "'bar'",
82
+ },
83
+ },
84
+ },
85
+ {
86
+ input: "import test from './module.js';",
87
+ expected: {
88
+ success: true,
89
+ result: {
90
+ type: "importStatement",
91
+ importedNames: "test ",
92
+ modulePath: "'./module'",
93
+ },
94
+ },
95
+ },
96
+ // Without semicolon (should still parse due to optionalSemicolon)
97
+ {
98
+ input: "import foo from bar\n",
99
+ expected: {
100
+ success: true,
101
+ result: {
102
+ type: "importStatement",
103
+ importedNames: "foo ",
104
+ modulePath: "bar",
105
+ },
106
+ },
107
+ },
108
+ {
109
+ input: "import test from module",
110
+ expected: {
111
+ success: true,
112
+ result: {
113
+ type: "importStatement",
114
+ importedNames: "test ",
115
+ modulePath: "module",
116
+ },
117
+ },
118
+ },
119
+ {
120
+ input: 'import foo from "bar"\n',
121
+ expected: {
122
+ success: true,
123
+ result: {
124
+ type: "importStatement",
125
+ importedNames: "foo ",
126
+ modulePath: '"bar"',
127
+ },
128
+ },
129
+ },
130
+ // Multiple imported names (destructured imports)
131
+ {
132
+ input: "import { foo, bar } from module;",
133
+ expected: {
134
+ success: true,
135
+ result: {
136
+ type: "importStatement",
137
+ importedNames: "{ foo, bar } ",
138
+ modulePath: "module",
139
+ },
140
+ },
141
+ },
142
+ {
143
+ input: 'import { foo, bar, baz } from "myModule";',
144
+ expected: {
145
+ success: true,
146
+ result: {
147
+ type: "importStatement",
148
+ importedNames: "{ foo, bar, baz } ",
149
+ modulePath: '"myModule"',
150
+ },
151
+ },
152
+ },
153
+ // Default and named imports
154
+ {
155
+ input: 'import React, { useState } from "react";',
156
+ expected: {
157
+ success: true,
158
+ result: {
159
+ type: "importStatement",
160
+ importedNames: "React, { useState } ",
161
+ modulePath: '"react"',
162
+ },
163
+ },
164
+ },
165
+ // Namespace imports
166
+ {
167
+ input: 'import * as utils from "utils";',
168
+ expected: {
169
+ success: true,
170
+ result: {
171
+ type: "importStatement",
172
+ importedNames: "* as utils ",
173
+ modulePath: '"utils"',
174
+ },
175
+ },
176
+ },
177
+ // Scoped packages
178
+ {
179
+ input: 'import { Parser } from "@typescript-eslint/parser";',
180
+ expected: {
181
+ success: true,
182
+ result: {
183
+ type: "importStatement",
184
+ importedNames: "{ Parser } ",
185
+ modulePath: '"@typescript-eslint/parser"',
186
+ },
187
+ },
188
+ },
189
+ // Spaces around keywords
190
+ {
191
+ input: "import foo from bar;",
192
+ expected: {
193
+ success: true,
194
+ result: {
195
+ type: "importStatement",
196
+ importedNames: "foo ",
197
+ modulePath: "bar",
198
+ },
199
+ },
200
+ },
201
+ // Edge cases - single character names
202
+ {
203
+ input: "import x from y;",
204
+ expected: {
205
+ success: true,
206
+ result: {
207
+ type: "importStatement",
208
+ importedNames: "x ",
209
+ modulePath: "y",
210
+ },
211
+ },
212
+ },
213
+ {
214
+ input: 'import x from "y";',
215
+ expected: {
216
+ success: true,
217
+ result: {
218
+ type: "importStatement",
219
+ importedNames: "x ",
220
+ modulePath: '"y"',
221
+ },
222
+ },
223
+ },
224
+ // Complex paths
225
+ {
226
+ input: "import foo from ../../../utils/helpers;",
227
+ expected: {
228
+ success: true,
229
+ result: {
230
+ type: "importStatement",
231
+ importedNames: "foo ",
232
+ modulePath: "../../../utils/helpers",
233
+ },
234
+ },
235
+ },
236
+ {
237
+ input: 'import foo from "../../../utils/helpers.js";',
238
+ expected: {
239
+ success: true,
240
+ result: {
241
+ type: "importStatement",
242
+ importedNames: "foo ",
243
+ modulePath: '"../../../utils/helpers"',
244
+ },
245
+ },
246
+ },
247
+ // Aliased imports
248
+ {
249
+ input: 'import { foo as bar } from "module";',
250
+ expected: {
251
+ success: true,
252
+ result: {
253
+ type: "importStatement",
254
+ importedNames: "{ foo as bar } ",
255
+ modulePath: '"module"',
256
+ },
257
+ },
258
+ },
259
+ // Failure cases - missing keywords
260
+ { input: "foo from bar;", expected: { success: false } },
261
+ { input: "from bar;", expected: { success: false } },
262
+ { input: "import foo bar;", expected: { success: false } },
263
+ // Failure cases - missing parts
264
+ { input: "import from bar;", expected: { success: false } },
265
+ { input: "import foo from;", expected: { success: false } },
266
+ { input: "import;", expected: { success: false } },
267
+ // Failure cases - empty input
268
+ { input: "", expected: { success: false } },
269
+ // Failure cases - just keyword
270
+ { input: "import", expected: { success: false } },
271
+ { input: "from", expected: { success: false } },
272
+ ];
273
+ testCases.forEach(({ input, expected }) => {
274
+ if (expected.success) {
275
+ it(`should parse "${input}" successfully`, () => {
276
+ const result = importStatmentParser(input);
277
+ expect(result.success).toBe(true);
278
+ if (result.success) {
279
+ expect(result.result).toEqual(expected.result);
280
+ }
281
+ });
282
+ }
283
+ else {
284
+ it(`should fail to parse "${input}"`, () => {
285
+ const result = importStatmentParser(input);
286
+ expect(result.success).toBe(false);
287
+ });
288
+ }
289
+ });
290
+ });
@@ -0,0 +1,12 @@
1
+ import { backtick, varNameChar } from "./utils.js";
2
+ import { capture, char, digit, many, many1Till, many1WithJoin, manyTill, map, or, seqC, set, } from "tarsec";
3
+ export const textSegmentParser = map(many1Till(or(backtick, char("$"))), (text) => ({
4
+ type: "text",
5
+ value: text,
6
+ }));
7
+ export const interpolationSegmentParser = seqC(set("type", "interpolation"), char("$"), char("{"), capture(many1Till(char("}")), "variableName"), char("}"));
8
+ export const promptParser = seqC(set("type", "prompt"), backtick, capture(many(or(textSegmentParser, interpolationSegmentParser)), "segments"), backtick);
9
+ export const numberParser = seqC(set("type", "number"), capture(many1WithJoin(or(char("-"), char("."), digit)), "value"));
10
+ export const stringParser = seqC(set("type", "string"), char('"'), capture(manyTill(char('"')), "value"), char('"'));
11
+ export const variableNameParser = seqC(set("type", "variableName"), capture(many1WithJoin(varNameChar), "value"));
12
+ export const literalParser = or(promptParser, numberParser, stringParser, variableNameParser);