agency-lang 0.0.28 → 0.0.30

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.
@@ -32,6 +32,7 @@ export declare class AgencyGenerator extends BaseGenerator {
32
32
  protected generateLiteral(literal: Literal): string;
33
33
  private generatePromptLiteral;
34
34
  private generateStringLiteral;
35
+ private generateMultiLineStringLiteral;
35
36
  protected processPromptLiteral(variableName: string, variableType: VariableType | undefined, node: PromptLiteral): string;
36
37
  protected processFunctionDefinition(node: FunctionDefinition): string;
37
38
  protected processFunctionCall(node: FunctionCall): string;
@@ -86,8 +86,7 @@ export class AgencyGenerator extends BaseGenerator {
86
86
  case "variableName":
87
87
  return literal.value;
88
88
  case "multiLineString":
89
- const escapedMultiLine = literal.value;
90
- return `"""${escapedMultiLine}"""`;
89
+ return this.generateMultiLineStringLiteral(literal);
91
90
  case "prompt":
92
91
  return this.generatePromptLiteral(literal);
93
92
  default:
@@ -120,6 +119,19 @@ export class AgencyGenerator extends BaseGenerator {
120
119
  result += '"';
121
120
  return result;
122
121
  }
122
+ generateMultiLineStringLiteral(node) {
123
+ let result = '"""';
124
+ for (const segment of node.segments) {
125
+ if (segment.type === "text") {
126
+ result += segment.value;
127
+ }
128
+ else if (segment.type === "interpolation") {
129
+ result += `\${${segment.variableName}}`;
130
+ }
131
+ }
132
+ result += '"""';
133
+ return result;
134
+ }
123
135
  processPromptLiteral(variableName, variableType, node) {
124
136
  // For agency code, prompts are just part of assignments
125
137
  // This shouldn't be called directly, but return empty string
@@ -282,7 +282,7 @@ export class TypeScriptGenerator extends BaseGenerator {
282
282
  case "string":
283
283
  return this.generateStringLiteral(literal.segments);
284
284
  case "multiLineString":
285
- return `\`${escape(literal.value)}\``;
285
+ return this.generateStringLiteral(literal.segments);
286
286
  case "variableName":
287
287
  return literal.value;
288
288
  case "prompt":
@@ -1,13 +1,14 @@
1
- import { InterpolationSegment, Literal, NumberLiteral, PromptLiteral, StringLiteral, TextSegment, VariableNameLiteral } from "../types.js";
1
+ import { InterpolationSegment, Literal, MultiLineStringLiteral, NumberLiteral, PromptLiteral, StringLiteral, TextSegment, VariableNameLiteral } from "../types.js";
2
2
  import { Parser } from "tarsec";
3
3
  export declare const textSegmentParser: Parser<TextSegment>;
4
4
  export declare const stringTextSegmentParser: Parser<TextSegment>;
5
+ export declare const multiLineStringTextSegmentParser: Parser<TextSegment>;
5
6
  export declare const interpolationSegmentParser: Parser<InterpolationSegment>;
6
7
  export declare const promptParserBackticks: Parser<PromptLiteral>;
7
8
  export declare const promptParserLlmFunction: Parser<PromptLiteral>;
8
9
  export declare const promptParser: Parser<PromptLiteral>;
9
10
  export declare const numberParser: Parser<NumberLiteral>;
10
11
  export declare const stringParser: Parser<StringLiteral>;
11
- export declare const multiLineStringParser: Parser<StringLiteral>;
12
+ export declare const multiLineStringParser: Parser<MultiLineStringLiteral>;
12
13
  export declare const variableNameParser: Parser<VariableNameLiteral>;
13
14
  export declare const literalParser: Parser<Literal>;
@@ -8,6 +8,10 @@ export const stringTextSegmentParser = map(many1Till(or(char('"'), char("$"))),
8
8
  type: "text",
9
9
  value: text,
10
10
  }));
11
+ export const multiLineStringTextSegmentParser = map(many1Till(or(str('"""'), char("$"))), (text) => ({
12
+ type: "text",
13
+ value: text,
14
+ }));
11
15
  export const interpolationSegmentParser = seqC(set("type", "interpolation"), char("$"), char("{"), capture(manyTillStr("}"), "variableName"), char("}"));
12
16
  export const promptParserBackticks = seqC(set("type", "prompt"), backtick, capture(many(or(textSegmentParser, interpolationSegmentParser)), "segments"), backtick);
13
17
  export const promptParserLlmFunction = (input) => {
@@ -17,7 +21,7 @@ export const promptParserLlmFunction = (input) => {
17
21
  export const promptParser = or(promptParserBackticks, promptParserLlmFunction);
18
22
  export const numberParser = seqC(set("type", "number"), capture(many1WithJoin(or(char("-"), char("."), digit)), "value"));
19
23
  export const stringParser = seqC(set("type", "string"), char('"'), capture(many(or(stringTextSegmentParser, interpolationSegmentParser)), "segments"), char('"'));
20
- export const multiLineStringParser = seqC(set("type", "string"), str('"""'), capture(many(or(stringTextSegmentParser, interpolationSegmentParser)), "segments"), str('"""'));
24
+ export const multiLineStringParser = seqC(set("type", "multiLineString"), str('"""'), capture(many(or(multiLineStringTextSegmentParser, interpolationSegmentParser)), "segments"), str('"""'));
21
25
  export const variableNameParser = seq([
22
26
  set("type", "variableName"),
23
27
  capture(letter, "init"),
@@ -534,14 +534,20 @@ describe("literals parsers", () => {
534
534
  input: '"""hello"""',
535
535
  expected: {
536
536
  success: true,
537
- result: { type: "multiLineString", value: "hello" },
537
+ result: {
538
+ type: "multiLineString",
539
+ segments: [{ type: "text", value: "hello" }],
540
+ },
538
541
  },
539
542
  },
540
543
  {
541
544
  input: '"""world"""',
542
545
  expected: {
543
546
  success: true,
544
- result: { type: "multiLineString", value: "world" },
547
+ result: {
548
+ type: "multiLineString",
549
+ segments: [{ type: "text", value: "world" }],
550
+ },
545
551
  },
546
552
  },
547
553
  // Empty multi-line string
@@ -549,7 +555,7 @@ describe("literals parsers", () => {
549
555
  input: '""""""',
550
556
  expected: {
551
557
  success: true,
552
- result: { type: "multiLineString", value: "" },
558
+ result: { type: "multiLineString", segments: [] },
553
559
  },
554
560
  },
555
561
  // Multi-line strings with actual newlines
@@ -557,28 +563,40 @@ describe("literals parsers", () => {
557
563
  input: '"""line1\nline2"""',
558
564
  expected: {
559
565
  success: true,
560
- result: { type: "multiLineString", value: "line1\nline2" },
566
+ result: {
567
+ type: "multiLineString",
568
+ segments: [{ type: "text", value: "line1\nline2" }],
569
+ },
561
570
  },
562
571
  },
563
572
  {
564
573
  input: '"""line1\nline2\nline3"""',
565
574
  expected: {
566
575
  success: true,
567
- result: { type: "multiLineString", value: "line1\nline2\nline3" },
576
+ result: {
577
+ type: "multiLineString",
578
+ segments: [{ type: "text", value: "line1\nline2\nline3" }],
579
+ },
568
580
  },
569
581
  },
570
582
  {
571
583
  input: '"""\nstarts with newline"""',
572
584
  expected: {
573
585
  success: true,
574
- result: { type: "multiLineString", value: "\nstarts with newline" },
586
+ result: {
587
+ type: "multiLineString",
588
+ segments: [{ type: "text", value: "\nstarts with newline" }],
589
+ },
575
590
  },
576
591
  },
577
592
  {
578
593
  input: '"""ends with newline\n"""',
579
594
  expected: {
580
595
  success: true,
581
- result: { type: "multiLineString", value: "ends with newline\n" },
596
+ result: {
597
+ type: "multiLineString",
598
+ segments: [{ type: "text", value: "ends with newline\n" }],
599
+ },
582
600
  },
583
601
  },
584
602
  // Strings with special characters
@@ -586,28 +604,30 @@ describe("literals parsers", () => {
586
604
  input: '"""Hello, World!"""',
587
605
  expected: {
588
606
  success: true,
589
- result: { type: "multiLineString", value: "Hello, World!" },
607
+ result: {
608
+ type: "multiLineString",
609
+ segments: [{ type: "text", value: "Hello, World!" }],
610
+ },
590
611
  },
591
612
  },
592
613
  {
593
614
  input: '"""123"""',
594
615
  expected: {
595
616
  success: true,
596
- result: { type: "multiLineString", value: "123" },
617
+ result: {
618
+ type: "multiLineString",
619
+ segments: [{ type: "text", value: "123" }],
620
+ },
597
621
  },
598
622
  },
599
623
  {
600
624
  input: '""" spaces and tabs\t\t"""',
601
625
  expected: {
602
626
  success: true,
603
- result: { type: "multiLineString", value: " spaces and tabs\t\t" },
604
- },
605
- },
606
- {
607
- input: '"""special!@#$%^&*()"""',
608
- expected: {
609
- success: true,
610
- result: { type: "multiLineString", value: "special!@#$%^&*()" },
627
+ result: {
628
+ type: "multiLineString",
629
+ segments: [{ type: "text", value: " spaces and tabs\t\t" }],
630
+ },
611
631
  },
612
632
  },
613
633
  // Strings containing single and double quotes
@@ -615,36 +635,94 @@ describe("literals parsers", () => {
615
635
  input: '"""single\'quotes\'here"""',
616
636
  expected: {
617
637
  success: true,
618
- result: { type: "multiLineString", value: "single'quotes'here" },
638
+ result: {
639
+ type: "multiLineString",
640
+ segments: [{ type: "text", value: "single'quotes'here" }],
641
+ },
619
642
  },
620
643
  },
621
644
  {
622
645
  input: '"""double"quotes"here"""',
623
646
  expected: {
624
647
  success: true,
625
- result: { type: "multiLineString", value: 'double"quotes"here' },
648
+ result: {
649
+ type: "multiLineString",
650
+ segments: [{ type: "text", value: 'double"quotes"here' }],
651
+ },
626
652
  },
627
653
  },
628
654
  {
629
655
  input: '"""mixed"and\'quotes"""',
630
656
  expected: {
631
657
  success: true,
632
- result: { type: "multiLineString", value: `mixed"and'quotes` },
658
+ result: {
659
+ type: "multiLineString",
660
+ segments: [{ type: "text", value: `mixed"and'quotes` }],
661
+ },
633
662
  },
634
663
  },
635
- // Strings containing backticks and interpolation-like syntax
664
+ // Strings containing backticks
636
665
  {
637
666
  input: '"""`backtick`"""',
638
667
  expected: {
639
668
  success: true,
640
- result: { type: "multiLineString", value: "`backtick`" },
669
+ result: {
670
+ type: "multiLineString",
671
+ segments: [{ type: "text", value: "`backtick`" }],
672
+ },
673
+ },
674
+ },
675
+ // String interpolation support
676
+ {
677
+ input: '"""${name}"""',
678
+ expected: {
679
+ success: true,
680
+ result: {
681
+ type: "multiLineString",
682
+ segments: [{ type: "interpolation", variableName: "name" }],
683
+ },
641
684
  },
642
685
  },
643
686
  {
644
- input: '"""${notInterpolation}"""',
687
+ input: '"""Hello, ${name}!"""',
645
688
  expected: {
646
689
  success: true,
647
- result: { type: "multiLineString", value: "${notInterpolation}" },
690
+ result: {
691
+ type: "multiLineString",
692
+ segments: [
693
+ { type: "text", value: "Hello, " },
694
+ { type: "interpolation", variableName: "name" },
695
+ { type: "text", value: "!" },
696
+ ],
697
+ },
698
+ },
699
+ },
700
+ {
701
+ input: '"""${firstName} ${lastName}"""',
702
+ expected: {
703
+ success: true,
704
+ result: {
705
+ type: "multiLineString",
706
+ segments: [
707
+ { type: "interpolation", variableName: "firstName" },
708
+ { type: "text", value: " " },
709
+ { type: "interpolation", variableName: "lastName" },
710
+ ],
711
+ },
712
+ },
713
+ },
714
+ {
715
+ input: '"""line1\n${variable}\nline3"""',
716
+ expected: {
717
+ success: true,
718
+ result: {
719
+ type: "multiLineString",
720
+ segments: [
721
+ { type: "text", value: "line1\n" },
722
+ { type: "interpolation", variableName: "variable" },
723
+ { type: "text", value: "\nline3" },
724
+ ],
725
+ },
648
726
  },
649
727
  },
650
728
  // Multiple consecutive newlines
@@ -652,7 +730,10 @@ describe("literals parsers", () => {
652
730
  input: '"""line1\n\n\nline2"""',
653
731
  expected: {
654
732
  success: true,
655
- result: { type: "multiLineString", value: "line1\n\n\nline2" },
733
+ result: {
734
+ type: "multiLineString",
735
+ segments: [{ type: "text", value: "line1\n\n\nline2" }],
736
+ },
656
737
  },
657
738
  },
658
739
  // Mixed whitespace
@@ -660,7 +741,10 @@ describe("literals parsers", () => {
660
741
  input: '""" \n\t\n """',
661
742
  expected: {
662
743
  success: true,
663
- result: { type: "multiLineString", value: " \n\t\n " },
744
+ result: {
745
+ type: "multiLineString",
746
+ segments: [{ type: "text", value: " \n\t\n " }],
747
+ },
664
748
  },
665
749
  },
666
750
  // Failure cases
@@ -1,4 +1,4 @@
1
- export declare const template = "import { z } from \"zod\";\nimport * as readline from \"readline\";\nimport fs from \"fs\";\nimport { PieMachine, goToNode } from \"piemachine\";\nimport { StatelogClient } from \"statelog-client\";\nimport { nanoid } from \"nanoid\";\nimport { assistantMessage, getClient, userMessage, toolMessage } from \"smoltalk\";\n\nconst statelogHost = \"https://statelog.adit.io\";\nconst traceId = nanoid();\nconst statelogConfig = {\n host: statelogHost,\n traceId: traceId,\n apiKey: process.env.STATELOG_API_KEY || \"\",\n projectId: \"agency-lang\",\n debugMode: false,\n };\nconst statelogClient = new StatelogClient(statelogConfig);\nconst __model: ModelName = \"gpt-4o-mini\";\n\n\nconst getClientWithConfig = (config = {}) => {\n const defaultConfig = {\n openAiApiKey: process.env.OPENAI_API_KEY || \"\",\n googleApiKey: process.env.GEMINI_API_KEY || \"\",\n model: __model,\n logLevel: \"warn\",\n };\n\n return getClient({ ...defaultConfig, ...config });\n};\n\nlet __client = getClientWithConfig();\n\ntype State = {\n messages: string[];\n data: any;\n}\n\n// enable debug logging\nconst graphConfig = {\n debug: {\n log: true,\n logData: true,\n },\n statelog: statelogConfig,\n};\n\n// Define the names of the nodes in the graph\n// Useful for type safety\nconst __nodes = {{{nodes:string}}} as const;\ntype Node = (typeof __nodes)[number];\n\nconst graph = new PieMachine<State, Node>(__nodes, graphConfig);\n\n// builtins\n\nconst not = (val: any): boolean => !val;\nconst eq = (a: any, b: any): boolean => a === b;\nconst neq = (a: any, b: any): boolean => a !== b;\nconst lt = (a: any, b: any): boolean => a < b;\nconst lte = (a: any, b: any): boolean => a <= b;\nconst gt = (a: any, b: any): boolean => a > b;\nconst gte = (a: any, b: any): boolean => a >= b;\nconst and = (a: any, b: any): boolean => a && b;\nconst or = (a: any, b: any): boolean => a || b;\n";
1
+ export declare const template = "import { z } from \"zod\";\nimport * as readline from \"readline\";\nimport fs from \"fs\";\nimport { PieMachine, goToNode } from \"piemachine\";\nimport { StatelogClient } from \"statelog-client\";\nimport { nanoid } from \"nanoid\";\nimport { assistantMessage, getClient, userMessage, toolMessage } from \"smoltalk\";\n\nconst statelogHost = \"https://statelog.adit.io\";\nconst traceId = nanoid();\nconst statelogConfig = {\n host: statelogHost,\n traceId: traceId,\n apiKey: process.env.STATELOG_API_KEY || \"\",\n projectId: \"agency-lang\",\n debugMode: false,\n };\nconst statelogClient = new StatelogClient(statelogConfig);\nconst __model: ModelName = \"gpt-4o-mini\";\n\n\nconst getClientWithConfig = (config = {}) => {\n const defaultConfig = {\n openAiApiKey: process.env.OPENAI_API_KEY || \"\",\n googleApiKey: process.env.GEMINI_API_KEY || \"\",\n model: __model,\n logLevel: \"warn\",\n };\n\n return getClient({ ...defaultConfig, ...config });\n};\n\nlet __client = getClientWithConfig();\n\ntype State = {\n messages: string[];\n data: any;\n}\n\n// enable debug logging\nconst graphConfig = {\n debug: {\n log: true,\n logData: true,\n },\n statelog: statelogConfig,\n};\n\n// Define the names of the nodes in the graph\n// Useful for type safety\nconst __nodes = {{{nodes:string}}} as const;\ntype Node = (typeof __nodes)[number];\n\nconst graph = new PieMachine<State, Node>(__nodes, graphConfig);\n\n// builtins\n\nconst not = (val: any): boolean => !val;\nconst eq = (a: any, b: any): boolean => a === b;\nconst neq = (a: any, b: any): boolean => a !== b;\nconst lt = (a: any, b: any): boolean => a < b;\nconst lte = (a: any, b: any): boolean => a <= b;\nconst gt = (a: any, b: any): boolean => a > b;\nconst gte = (a: any, b: any): boolean => a >= b;\nconst and = (a: any, b: any): boolean => a && b;\nconst or = (a: any, b: any): boolean => a || b;\nconst head = <T>(arr: T[]): T | undefined => arr[0];\nconst tail = <T>(arr: T[]): T[] => arr.slice(1);";
2
2
  export type TemplateType = {
3
3
  nodes: string;
4
4
  };
@@ -68,7 +68,8 @@ const gt = (a: any, b: any): boolean => a > b;
68
68
  const gte = (a: any, b: any): boolean => a >= b;
69
69
  const and = (a: any, b: any): boolean => a && b;
70
70
  const or = (a: any, b: any): boolean => a || b;
71
- `;
71
+ const head = <T>(arr: T[]): T | undefined => arr[0];
72
+ const tail = <T>(arr: T[]): T[] => arr.slice(1);`;
72
73
  const render = (args) => {
73
74
  return apply(template, args);
74
75
  };
@@ -9,7 +9,7 @@ export type StringLiteral = {
9
9
  };
10
10
  export type MultiLineStringLiteral = {
11
11
  type: "multiLineString";
12
- value: string;
12
+ segments: PromptSegment[];
13
13
  };
14
14
  export type VariableNameLiteral = {
15
15
  type: "variableName";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agency-lang",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "description": "The Agency language",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {