agentlang 0.9.10 → 0.10.0

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 (66) hide show
  1. package/out/extension/main.cjs +38 -38
  2. package/out/extension/main.cjs.map +2 -2
  3. package/out/language/generated/ast.d.ts +1 -1
  4. package/out/language/generated/ast.js +1 -1
  5. package/out/language/generated/grammar.d.ts +1 -1
  6. package/out/language/generated/grammar.js +1 -1
  7. package/out/language/generated/module.d.ts +1 -1
  8. package/out/language/generated/module.js +1 -1
  9. package/out/language/main.cjs +850 -2388
  10. package/out/language/main.cjs.map +4 -4
  11. package/out/language/parser.d.ts.map +1 -1
  12. package/out/language/parser.js +10 -0
  13. package/out/language/parser.js.map +1 -1
  14. package/out/language/syntax.d.ts +8 -0
  15. package/out/language/syntax.d.ts.map +1 -1
  16. package/out/language/syntax.js +11 -2
  17. package/out/language/syntax.js.map +1 -1
  18. package/out/runtime/agents/common.d.ts +3 -1
  19. package/out/runtime/agents/common.d.ts.map +1 -1
  20. package/out/runtime/agents/common.js +35 -31
  21. package/out/runtime/agents/common.js.map +1 -1
  22. package/out/runtime/docs.d.ts +1 -0
  23. package/out/runtime/docs.d.ts.map +1 -1
  24. package/out/runtime/docs.js +16 -1
  25. package/out/runtime/docs.js.map +1 -1
  26. package/out/runtime/interpreter.d.ts +1 -0
  27. package/out/runtime/interpreter.d.ts.map +1 -1
  28. package/out/runtime/interpreter.js +123 -74
  29. package/out/runtime/interpreter.js.map +1 -1
  30. package/out/runtime/jsmodules.d.ts +2 -1
  31. package/out/runtime/jsmodules.d.ts.map +1 -1
  32. package/out/runtime/jsmodules.js +2 -1
  33. package/out/runtime/jsmodules.js.map +1 -1
  34. package/out/runtime/loader.d.ts.map +1 -1
  35. package/out/runtime/loader.js +3 -2
  36. package/out/runtime/loader.js.map +1 -1
  37. package/out/runtime/module.d.ts +1 -0
  38. package/out/runtime/module.d.ts.map +1 -1
  39. package/out/runtime/module.js +3 -0
  40. package/out/runtime/module.js.map +1 -1
  41. package/out/runtime/modules/ai.d.ts +11 -0
  42. package/out/runtime/modules/ai.d.ts.map +1 -1
  43. package/out/runtime/modules/ai.js +164 -11
  44. package/out/runtime/modules/ai.js.map +1 -1
  45. package/out/runtime/modules/core.d.ts.map +1 -1
  46. package/out/runtime/modules/core.js +7 -1
  47. package/out/runtime/modules/core.js.map +1 -1
  48. package/out/runtime/services/documentFetcher.d.ts +22 -14
  49. package/out/runtime/services/documentFetcher.d.ts.map +1 -1
  50. package/out/runtime/services/documentFetcher.js +348 -153
  51. package/out/runtime/services/documentFetcher.js.map +1 -1
  52. package/package.json +1 -1
  53. package/src/language/generated/ast.ts +1 -1
  54. package/src/language/generated/grammar.ts +1 -1
  55. package/src/language/generated/module.ts +1 -1
  56. package/src/language/parser.ts +12 -0
  57. package/src/language/syntax.ts +21 -2
  58. package/src/runtime/agents/common.ts +37 -31
  59. package/src/runtime/docs.ts +17 -1
  60. package/src/runtime/interpreter.ts +122 -69
  61. package/src/runtime/jsmodules.ts +3 -1
  62. package/src/runtime/loader.ts +3 -2
  63. package/src/runtime/module.ts +4 -0
  64. package/src/runtime/modules/ai.ts +196 -10
  65. package/src/runtime/modules/core.ts +7 -1
  66. package/src/runtime/services/documentFetcher.ts +372 -149
@@ -3731,6 +3731,10 @@ export function newInstanceAttributes(): InstanceAttributes {
3731
3731
  return new Map<string, any>();
3732
3732
  }
3733
3733
 
3734
+ export function objectToInstanceAttributes(obj: any): InstanceAttributes {
3735
+ return new Map(Object.entries(obj));
3736
+ }
3737
+
3734
3738
  const EmptyInstanceAttributes: InstanceAttributes = newInstanceAttributes();
3735
3739
 
3736
3740
  export class Instance {
@@ -1,4 +1,5 @@
1
1
  import {
2
+ DefaultModuleName,
2
3
  escapeSpecialChars,
3
4
  isFqName,
4
5
  isString,
@@ -16,6 +17,7 @@ import {
16
17
  parseAndEvaluateStatement,
17
18
  } from '../interpreter.js';
18
19
  import {
20
+ Agent,
19
21
  AgentEvaluator,
20
22
  asJSONSchema,
21
23
  Decision,
@@ -29,6 +31,7 @@ import {
29
31
  isModule,
30
32
  makeInstance,
31
33
  newInstanceAttributes,
34
+ objectToInstanceAttributes,
32
35
  Record,
33
36
  resolveDocumentAliases,
34
37
  Retry,
@@ -67,6 +70,7 @@ import Handlebars from 'handlebars';
67
70
  import { Statement } from '../../language/generated/ast.js';
68
71
  import { isMonitoringEnabled, TtlCache } from '../state.js';
69
72
  import { isNodeEnv } from '../../utils/runtime.js';
73
+ import { getFileSystem } from '../../utils/fs-utils.js';
70
74
 
71
75
  export const CoreAIModuleName = makeCoreModuleName('ai');
72
76
  export const AgentEntityName = 'Agent';
@@ -185,6 +189,27 @@ entity AgentLearningResult {
185
189
  workflow agentLearning {
186
190
  await ai.processAgentLearning(agentLearning.agentModuleName, agentLearning.agentName, agentLearning.instruction)
187
191
  }
192
+
193
+ entity AgentFlowStep {
194
+ id UUID @id @default(uuid()),
195
+ chatId String @indexed,
196
+ step String @indexed,
197
+ result String,
198
+ suspensionId String
199
+ }
200
+
201
+ @public event restartFlow {
202
+ chatId String,
203
+ step String,
204
+ userInput String
205
+ }
206
+
207
+ workflow restartFlow {
208
+ await ai.loadFlowStep(restartFlow.chatId, restartFlow.step) @as fs;
209
+ if (fs) {
210
+ {${DefaultModuleName}/restartSuspension {id fs.suspensionId, data restartFlow.userInput}}
211
+ }
212
+ }
188
213
  `;
189
214
 
190
215
  enum AgentCacheType {
@@ -614,7 +639,7 @@ export class AgentInstance {
614
639
  Only return a pure JSON object with no extra text, annotations etc.`;
615
640
  }
616
641
  const spad = env.getScratchPad();
617
- if (spad !== undefined) {
642
+ if (spad !== undefined && Object.keys(spad).length > 0) {
618
643
  if (finalInstruction.indexOf('{{') > 0) {
619
644
  return AgentInstance.maybeRewriteTemplatePatterns(spad, finalInstruction, env);
620
645
  } else {
@@ -685,7 +710,7 @@ Only return a pure JSON object with no extra text, annotations etc.`;
685
710
  ) {
686
711
  r = obj;
687
712
  } else {
688
- env.addToScratchPad(this.name, obj);
713
+ env.addToScratchPad(Agent.NormalizeName(this.name), obj);
689
714
  return this;
690
715
  }
691
716
  const scratchNames = this.getScratchNames();
@@ -1274,17 +1299,38 @@ function processScenarioResponse(resp: string): string {
1274
1299
  return resp;
1275
1300
  }
1276
1301
 
1302
+ type ExtractedCode = {
1303
+ language: string | null;
1304
+ code: string;
1305
+ };
1306
+
1307
+ export function extractFencedCodeBlocks(markdown: string): ExtractedCode[] {
1308
+ const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g;
1309
+ const blocks: ExtractedCode[] = [];
1310
+ let match;
1311
+
1312
+ while ((match = codeBlockRegex.exec(markdown)) !== null) {
1313
+ blocks.push({
1314
+ language: match[1] || null,
1315
+ code: match[2],
1316
+ });
1317
+ }
1318
+
1319
+ return blocks;
1320
+ }
1321
+
1277
1322
  export function normalizeGeneratedCode(code: string | undefined): string {
1278
1323
  if (code !== undefined) {
1279
- let s = code.trim();
1280
- if (s.startsWith('```')) {
1281
- const idx = s.indexOf('\n');
1282
- s = s.substring(idx).trimStart();
1283
- }
1284
- if (s.endsWith('```')) {
1285
- s = s.substring(0, s.length - 3);
1324
+ const blocks = extractFencedCodeBlocks(code);
1325
+ if (blocks.length > 0) {
1326
+ return blocks
1327
+ .map((v: ExtractedCode) => {
1328
+ return v.code;
1329
+ })
1330
+ .join('\n\n');
1331
+ } else {
1332
+ return code;
1286
1333
  }
1287
- return s;
1288
1334
  } else {
1289
1335
  return '';
1290
1336
  }
@@ -1385,6 +1431,146 @@ export async function processAgentLearning(
1385
1431
  return { agentLearning: { result: learning } };
1386
1432
  }
1387
1433
 
1434
+ const LocalAgentgFlow = true;
1435
+ const LocalFlowStepsRootDirName = 'flows';
1436
+ const AgentFlowStep = 'AgentFlowStep';
1437
+
1438
+ export async function saveFlowStepResultLocally(
1439
+ chatId: string,
1440
+ step: string,
1441
+ result: string,
1442
+ suspensionId: string
1443
+ ): Promise<Instance | undefined> {
1444
+ const fs = await getFileSystem();
1445
+ const attrs = newInstanceAttributes()
1446
+ .set('chatId', chatId)
1447
+ .set('step', step)
1448
+ .set('result', result)
1449
+ .set('suspensionId', suspensionId);
1450
+ const inst = makeInstance(CoreAIModuleName, AgentFlowStep, attrs);
1451
+ const rootDirName = LocalFlowStepsRootDirName;
1452
+ if (!(await fs.exists(rootDirName))) {
1453
+ await fs.mkdir(rootDirName);
1454
+ }
1455
+ const dirName = `${rootDirName}/${chatId}`;
1456
+ if (!(await fs.exists(dirName))) {
1457
+ await fs.mkdir(dirName);
1458
+ }
1459
+ const fileName = `${dirName}/${step}`;
1460
+ if (await fs.exists(fileName)) {
1461
+ await fs.unlink(fileName);
1462
+ }
1463
+ await fs.writeFile(fileName, JSON.stringify(inst.attributesAsObject(true)));
1464
+ return inst;
1465
+ }
1466
+
1467
+ export async function saveFlowStepResult(
1468
+ chatId: string,
1469
+ step: string,
1470
+ result: string,
1471
+ suspensionId: string,
1472
+ env: Environment
1473
+ ): Promise<Instance | undefined> {
1474
+ if (LocalAgentgFlow) {
1475
+ return await saveFlowStepResultLocally(chatId, step, result, suspensionId);
1476
+ } else {
1477
+ const t = `${CoreAIModuleName}/${AgentFlowStep}`;
1478
+ try {
1479
+ await parseAndEvaluateStatement(
1480
+ `purge {${t} {chatId? "${chatId}", step? "${step}"}}`,
1481
+ undefined,
1482
+ env
1483
+ );
1484
+ const inst: Instance = await parseAndEvaluateStatement(
1485
+ `{${t} {chatId "${chatId}", step "${step}", result "${escapeSpecialChars(result)}", suspensionId "${suspensionId}"}}`,
1486
+ undefined,
1487
+ env
1488
+ );
1489
+ if (isInstanceOfType(inst, t)) return inst;
1490
+ else return undefined;
1491
+ } catch (reason: any) {
1492
+ logger.error(`failed to save flow result for step ${step} - ${reason}`);
1493
+ return undefined;
1494
+ }
1495
+ }
1496
+ }
1497
+
1498
+ export async function loadLocalFlowStepResults(chatId: string): Promise<Instance[]> {
1499
+ const fs = await getFileSystem();
1500
+ const dirName = `${LocalFlowStepsRootDirName}/${chatId}`;
1501
+ if (await fs.exists(dirName)) {
1502
+ const fileNames = await fs.readdir(dirName);
1503
+ const result: Instance[] = new Array<Instance>();
1504
+ for (let i = 0; i < fileNames.length; ++i) {
1505
+ const fileName = fileNames[i];
1506
+ const attrs = objectToInstanceAttributes(
1507
+ JSON.parse(await fs.readFile(`${dirName}/${fileName}`))
1508
+ );
1509
+ result.push(makeInstance(CoreAIModuleName, AgentFlowStep, attrs));
1510
+ }
1511
+ return result;
1512
+ } else {
1513
+ return [];
1514
+ }
1515
+ }
1516
+
1517
+ export async function loadFlowStepResults(chatId: string): Promise<Instance[]> {
1518
+ if (LocalAgentgFlow) {
1519
+ return await loadLocalFlowStepResults(chatId);
1520
+ } else {
1521
+ try {
1522
+ return await parseAndEvaluateStatement(`{${CoreAIModuleName}/${AgentFlowStep} {
1523
+ chatId? "${chatId}"}}`);
1524
+ } catch (reason: any) {
1525
+ logger.error(`failed to query flow-steps for ${chatId} - ${reason}`);
1526
+ return [];
1527
+ }
1528
+ }
1529
+ }
1530
+
1531
+ export async function loadLocalFlowStep(
1532
+ chatId: string,
1533
+ step: string
1534
+ ): Promise<Instance | undefined> {
1535
+ const fs = await getFileSystem();
1536
+ const dirName = `${LocalFlowStepsRootDirName}/${chatId}`;
1537
+ if (await fs.exists(dirName)) {
1538
+ const fileNames = await fs.readdir(dirName);
1539
+ for (let i = 0; i < fileNames.length; ++i) {
1540
+ const fileName = fileNames[i];
1541
+ if (fileName === step) {
1542
+ const attrs = objectToInstanceAttributes(
1543
+ JSON.parse(await fs.readFile(`${dirName}/${fileName}`))
1544
+ );
1545
+ return makeInstance(CoreAIModuleName, AgentFlowStep, attrs);
1546
+ }
1547
+ }
1548
+ return undefined;
1549
+ } else {
1550
+ return undefined;
1551
+ }
1552
+ }
1553
+
1554
+ export async function loadFlowStep(chatId: string, step: string): Promise<Instance | undefined> {
1555
+ if (LocalAgentgFlow) {
1556
+ return await loadLocalFlowStep(chatId, step);
1557
+ } else {
1558
+ try {
1559
+ const insts: Instance[] =
1560
+ await parseAndEvaluateStatement(`{${CoreAIModuleName}/${AgentFlowStep} {
1561
+ chatId? "${chatId}", step? "${step}"}}`);
1562
+ if (insts.length > 0) {
1563
+ return insts[0];
1564
+ } else {
1565
+ return undefined;
1566
+ }
1567
+ } catch (reason: any) {
1568
+ logger.error(`failed to lookup step ${step} for flow ${chatId} - ${reason}`);
1569
+ return undefined;
1570
+ }
1571
+ }
1572
+ }
1573
+
1388
1574
  export async function fetchAndCreateDocument(
1389
1575
  title: string,
1390
1576
  url: string,
@@ -1,4 +1,4 @@
1
- import { default as ai } from './ai.js';
1
+ import { default as ai, normalizeGeneratedCode } from './ai.js';
2
2
  import { default as auth } from './auth.js';
3
3
  import { default as files } from './files.js';
4
4
  import { default as mcp } from './mcp.js';
@@ -527,6 +527,12 @@ export function eventMonitorsData(
527
527
  export async function validateModule(moduleDef: any): Promise<Instance> {
528
528
  try {
529
529
  if (isString(moduleDef)) {
530
+ moduleDef = normalizeGeneratedCode(moduleDef);
531
+ if (!moduleDef.startsWith('module')) {
532
+ moduleDef = `module Temp
533
+ ${moduleDef}
534
+ `;
535
+ }
530
536
  await parseModule(moduleDef);
531
537
  return makeInstance(
532
538
  'agentlang',