agency-lang 0.0.43 → 0.0.45

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.
@@ -71,6 +71,7 @@ export declare class BaseGenerator {
71
71
  protected postprocess(): string;
72
72
  protected startScope(scope: Scope): void;
73
73
  protected endScope(): void;
74
+ protected getCurrentScope(): Scope;
74
75
  protected getScopeVar(): string;
75
76
  }
76
77
  export {};
@@ -261,6 +261,9 @@ export class BaseGenerator {
261
261
  endScope() {
262
262
  this.currentScope.pop();
263
263
  }
264
+ getCurrentScope() {
265
+ return this.currentScope[this.currentScope.length - 1];
266
+ }
264
267
  getScopeVar() {
265
268
  const currentScope = this.currentScope[this.currentScope.length - 1];
266
269
  switch (currentScope) {
@@ -115,8 +115,13 @@ export class TypeScriptGenerator extends BaseGenerator {
115
115
  }
116
116
  processAssignment(node) {
117
117
  const { variableName, typeHint, value } = node;
118
- // Track this variable as in scope
119
- this.functionScopedVariables.push(variableName);
118
+ const _currentScope = this.getCurrentScope();
119
+ if (_currentScope === "global") {
120
+ this.globalScopedVariables.push(variableName);
121
+ }
122
+ else {
123
+ this.functionScopedVariables.push(variableName);
124
+ }
120
125
  const typeAnnotation = typeHint
121
126
  ? `: ${variableTypeToString(typeHint, this.typeAliases)}`
122
127
  : "";
@@ -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, messageFromJSON } from \"smoltalk\";\nimport type { Message } 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\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: false,\n },\n statelog: statelogConfig,\n};\n\nconst graph = new PieMachine<State>(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);\nconst empty = <T>(arr: T[]): boolean => arr.length === 0;\n\n// interrupts\n\nexport type Interrupt<T> = {\n type: \"interrupt\";\n data: T;\n __state?: PackagedState;\n};\n\nexport function interrupt<T>(data: T): Interrupt<T> {\n return {\n type: \"interrupt\",\n data,\n };\n}\n\nexport function isInterrupt<T>(obj: any): obj is Interrupt<T> {\n return obj && obj.type === \"interrupt\";\n}\n\nfunction printJSON(obj: any) {\n console.log(JSON.stringify(obj, null, 2));\n}\n\nexport type InterruptResponseType = InterruptResponseApprove | InterruptResponseReject | InterruptResponseModify;\nexport type InterruptResponseApprove = {\n type: \"approve\";\n};\nexport type InterruptResponseReject = {\n type: \"reject\";\n};\nexport type InterruptResponseModify = {\n type: \"modify\";\n newArguments: Record<string, any>;\n};\n\n\nexport async function respondToInterrupt(_interrupt: Interrupt, _interruptResponse: InterruptResponseType) {\n const interrupt = structuredClone(_interrupt);\n const interruptResponse = structuredClone(_interruptResponse);\n __stateStack = StateStack.fromJSON(interrupt.__state || {});\n __stateStack.setMode(\"deserialize\");\n const messages = (__stateStack.other.messages || []).map((json: any) => {\n return messageFromJSON(json);\n });\n\n const nodesTraversed = __stateStack.other.nodesTraversed || [];\n const nodeName = nodesTraversed[nodesTraversed.length - 1];\n const result = await graph.run(nodeName, {\n messages: messages,\n __metadata: {\n graph: graph,\n statelogClient: __statelogClient,\n interruptResponse: interruptResponse,\n state: interrupt.__state,\n __stateStack: __stateStack,\n },\n data: \"<from-stack>\"\n });\n //console.log(`Result of graph.run(\"${nodeName}\"):`, JSON.stringify(result, null, 2));\n return result.data;\n}\n\n\nclass PackagedState {\n public messages?: Message[];\n public nodesTraversed?: string[];\n public toolCall?: Record<string, any>;\n public step?: number;\n public self?: Record<string, any>;\n public global?: Record<string, any>;\n public args?: any;\n constructor(_state: Record<string, any>, args?: any) {\n const state = structuredClone(_state);\n this.messages = state.messages;\n this.nodesTraversed = state.graph?.getNodesTraversed();\n this.toolCall = state.toolCall;\n this.step = state.part;\n this.self = state.self;\n this.global = state.global;\n this.args = state.args;\n }\n\n toJSON() {\n return {\n messages: this.messages,\n nodesTraversed: this.nodesTraversed,\n toolCall: this.toolCall,\n step: this.step,\n self: this.self,\n global: this.global,\n args: this.args,\n };\n }\n\n nextStep() {\n this.step ||= 0;\n this.step += 1;\n }\n}\n\n\nclass StateStack {\n public stack: StateItem[] = [];\n public mode: \"serialize\" | \"deserialize\" = \"serialize\";\n public globals: Record<string, any> = {};\n public other: Record<string, any> = {};\n\n constructor(stack: StateItem[] = [], mode: \"serialize\" | \"deserialize\" = \"serialize\") {\n this.stack = stack;\n this.mode = mode;\n }\n\n getNewState(): StateItem | null {\n if (this.stack.length === 0 && this.mode !== \"serialize\") {\n console.log(\"Forcing mode to serialize, nothing left to deserialize\");\n this.mode = \"serialize\";\n }\n if (this.mode === \"serialize\") {\n const newState: StateItem = {\n args: {},\n locals: {},\n step: 0,\n };\n this.stack.push(newState);\n return newState;\n } else if (this.mode === \"deserialize\") {\n const item = this.stack.shift();\n this.stack.push(item);\n return item;\n }\n return null;\n }\n\n setMode(mode: \"serialize\" | \"deserialize\") {\n this.mode = mode;\n }\n\n pop(): StateItem | undefined {\n return this.stack.pop();\n }\n\n toJSON() {\n return structuredClone({\n stack: this.stack,\n globals: this.globals,\n other: this.other,\n mode: this.mode,\n });\n }\n\n static fromJSON(json: any): StateStack {\n const stateStack = new StateStack([], \"serialize\");\n stateStack.stack = json.stack || [];\n stateStack.globals = json.globals || {};\n stateStack.other = json.other || {};\n stateStack.mode = json.mode || \"serialize\";\n return stateStack;\n }\n}\n\nlet __stateStack = new StateStack();";
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, messageFromJSON } from \"smoltalk\";\nimport type { Message } 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\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: false,\n },\n statelog: statelogConfig,\n};\n\nconst graph = new PieMachine<State>(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);\nconst empty = <T>(arr: T[]): boolean => arr.length === 0;\n\n// interrupts\n\nexport type Interrupt<T> = {\n type: \"interrupt\";\n data: T;\n __state?: PackagedState;\n};\n\nexport function interrupt<T>(data: T): Interrupt<T> {\n return {\n type: \"interrupt\",\n data,\n };\n}\n\nexport function isInterrupt<T>(obj: any): obj is Interrupt<T> {\n return obj && obj.type === \"interrupt\";\n}\n\nfunction printJSON(obj: any) {\n console.log(JSON.stringify(obj, null, 2));\n}\n\nexport type InterruptResponseType = InterruptResponseApprove | InterruptResponseReject | InterruptResponseModify;\nexport type InterruptResponseApprove = {\n type: \"approve\";\n};\nexport type InterruptResponseReject = {\n type: \"reject\";\n};\nexport type InterruptResponseModify = {\n type: \"modify\";\n newArguments: Record<string, any>;\n};\n\n\nexport async function respondToInterrupt(_interrupt: Interrupt, _interruptResponse: InterruptResponseType) {\n const interrupt = structuredClone(_interrupt);\n const interruptResponse = structuredClone(_interruptResponse);\n __stateStack = StateStack.fromJSON(interrupt.__state || {});\n __stateStack.deserializeMode();\n const messages = (__stateStack.other.messages || []).map((json: any) => {\n return messageFromJSON(json);\n });\n\n const nodesTraversed = __stateStack.other.nodesTraversed || [];\n const nodeName = nodesTraversed[nodesTraversed.length - 1];\n const result = await graph.run(nodeName, {\n messages: messages,\n __metadata: {\n graph: graph,\n statelogClient: __statelogClient,\n interruptResponse: interruptResponse,\n state: interrupt.__state,\n __stateStack: __stateStack,\n },\n data: \"<from-stack>\"\n });\n //console.log(`Result of graph.run(\"${nodeName}\"):`, JSON.stringify(result, null, 2));\n return result.data;\n}\n\n\nclass PackagedState {\n public messages?: Message[];\n public nodesTraversed?: string[];\n public toolCall?: Record<string, any>;\n public step?: number;\n public self?: Record<string, any>;\n public global?: Record<string, any>;\n public args?: any;\n constructor(_state: Record<string, any>, args?: any) {\n const state = structuredClone(_state);\n this.messages = state.messages;\n this.nodesTraversed = state.graph?.getNodesTraversed();\n this.toolCall = state.toolCall;\n this.step = state.part;\n this.self = state.self;\n this.global = state.global;\n this.args = state.args;\n }\n\n toJSON() {\n return {\n messages: this.messages,\n nodesTraversed: this.nodesTraversed,\n toolCall: this.toolCall,\n step: this.step,\n self: this.self,\n global: this.global,\n args: this.args,\n };\n }\n\n nextStep() {\n this.step ||= 0;\n this.step += 1;\n }\n}\n\n\nclass StateStack {\n public stack: StateItem[] = [];\n private mode: \"serialize\" | \"deserialize\" = \"serialize\";\n public globals: Record<string, any> = {};\n public other: Record<string, any> = {};\n\n private deserializeStackLength = 0;\n\n constructor(stack: StateItem[] = [], mode: \"serialize\" | \"deserialize\" = \"serialize\") {\n this.stack = stack;\n this.mode = mode;\n }\n\n getNewState(): StateItem | null {\n if (this.mode === \"deserialize\" && this.deserializeStackLength <= 0) {\n console.log(\"Forcing mode to serialize, nothing left to deserialize\");\n this.mode = \"serialize\";\n }\n if (this.mode === \"serialize\") {\n const newState: StateItem = {\n args: {},\n locals: {},\n step: 0,\n };\n this.stack.push(newState);\n return newState;\n } else if (this.mode === \"deserialize\") {\n this.deserializeStackLength -= 1;\n const item = this.stack.shift();\n this.stack.push(item);\n return item;\n }\n return null;\n }\n\n deserializeMode() {\n this.mode = \"deserialize\";\n this.deserializeStackLength = this.stack.length;\n }\n\n pop(): StateItem | undefined {\n return this.stack.pop();\n }\n\n toJSON() {\n return structuredClone({\n stack: this.stack,\n globals: this.globals,\n other: this.other,\n mode: this.mode,\n deserializeStackLength: this.deserializeStackLength,\n });\n }\n\n static fromJSON(json: any): StateStack {\n const stateStack = new StateStack([], \"serialize\");\n stateStack.stack = json.stack || [];\n stateStack.globals = json.globals || {};\n stateStack.other = json.other || {};\n stateStack.mode = json.mode || \"serialize\";\n stateStack.deserializeStackLength = json.deserializeStackLength || 0;\n return stateStack;\n }\n}\n\nlet __stateStack = new StateStack();";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -107,7 +107,7 @@ export async function respondToInterrupt(_interrupt: Interrupt, _interruptRespon
107
107
  const interrupt = structuredClone(_interrupt);
108
108
  const interruptResponse = structuredClone(_interruptResponse);
109
109
  __stateStack = StateStack.fromJSON(interrupt.__state || {});
110
- __stateStack.setMode("deserialize");
110
+ __stateStack.deserializeMode();
111
111
  const messages = (__stateStack.other.messages || []).map((json: any) => {
112
112
  return messageFromJSON(json);
113
113
  });
@@ -170,17 +170,19 @@ class PackagedState {
170
170
 
171
171
  class StateStack {
172
172
  public stack: StateItem[] = [];
173
- public mode: "serialize" | "deserialize" = "serialize";
173
+ private mode: "serialize" | "deserialize" = "serialize";
174
174
  public globals: Record<string, any> = {};
175
175
  public other: Record<string, any> = {};
176
176
 
177
+ private deserializeStackLength = 0;
178
+
177
179
  constructor(stack: StateItem[] = [], mode: "serialize" | "deserialize" = "serialize") {
178
180
  this.stack = stack;
179
181
  this.mode = mode;
180
182
  }
181
183
 
182
184
  getNewState(): StateItem | null {
183
- if (this.stack.length === 0 && this.mode !== "serialize") {
185
+ if (this.mode === "deserialize" && this.deserializeStackLength <= 0) {
184
186
  console.log("Forcing mode to serialize, nothing left to deserialize");
185
187
  this.mode = "serialize";
186
188
  }
@@ -193,6 +195,7 @@ class StateStack {
193
195
  this.stack.push(newState);
194
196
  return newState;
195
197
  } else if (this.mode === "deserialize") {
198
+ this.deserializeStackLength -= 1;
196
199
  const item = this.stack.shift();
197
200
  this.stack.push(item);
198
201
  return item;
@@ -200,8 +203,9 @@ class StateStack {
200
203
  return null;
201
204
  }
202
205
 
203
- setMode(mode: "serialize" | "deserialize") {
204
- this.mode = mode;
206
+ deserializeMode() {
207
+ this.mode = "deserialize";
208
+ this.deserializeStackLength = this.stack.length;
205
209
  }
206
210
 
207
211
  pop(): StateItem | undefined {
@@ -214,6 +218,7 @@ class StateStack {
214
218
  globals: this.globals,
215
219
  other: this.other,
216
220
  mode: this.mode,
221
+ deserializeStackLength: this.deserializeStackLength,
217
222
  });
218
223
  }
219
224
 
@@ -223,6 +228,7 @@ class StateStack {
223
228
  stateStack.globals = json.globals || {};
224
229
  stateStack.other = json.other || {};
225
230
  stateStack.mode = json.mode || "serialize";
231
+ stateStack.deserializeStackLength = json.deserializeStackLength || 0;
226
232
  return stateStack;
227
233
  }
228
234
  }
@@ -77,11 +77,11 @@ function getImports(program) {
77
77
  .filter((node) => node.type === "importNodeStatement" ||
78
78
  node.type === "importToolStatement")
79
79
  .map((node) => node.agencyFile.trim());
80
- /* const importStatements = program.nodes
81
- .filter((node) => node.type === "importStatement")
82
- .map((node) => (node as ImportStatement).modulePath.trim());
83
- */
84
- return [...toolAndNodeImports]; //, ...importStatements];
80
+ // this makes compile() try to parse non-agency files
81
+ const importStatements = program.nodes
82
+ .filter((node) => node.type === "importStatement" && node.modulePath.endsWith(".agency"))
83
+ .map((node) => node.modulePath.trim());
84
+ return [...toolAndNodeImports, ...importStatements];
85
85
  }
86
86
  const compiledFiles = new Set();
87
87
  const dirSearched = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agency-lang",
3
- "version": "0.0.43",
3
+ "version": "0.0.45",
4
4
  "description": "The Agency language",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -56,4 +56,4 @@
56
56
  "typescript": "^5.9.3",
57
57
  "vitest": "^4.0.16"
58
58
  }
59
- }
59
+ }