@flink-app/flink 0.14.3 → 2.0.0-alpha.48

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 (112) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/cli/build.ts +8 -1
  3. package/cli/run.ts +8 -1
  4. package/dist/cli/build.js +8 -1
  5. package/dist/cli/run.js +8 -1
  6. package/dist/src/FlinkApp.d.ts +33 -0
  7. package/dist/src/FlinkApp.js +279 -35
  8. package/dist/src/FlinkContext.d.ts +21 -0
  9. package/dist/src/FlinkHttpHandler.d.ts +152 -9
  10. package/dist/src/FlinkHttpHandler.js +37 -1
  11. package/dist/src/TypeScriptCompiler.d.ts +42 -0
  12. package/dist/src/TypeScriptCompiler.js +346 -4
  13. package/dist/src/TypeScriptUtils.js +4 -0
  14. package/dist/src/ai/AgentRunner.d.ts +39 -0
  15. package/dist/src/ai/AgentRunner.js +625 -0
  16. package/dist/src/ai/FlinkAgent.d.ts +446 -0
  17. package/dist/src/ai/FlinkAgent.js +633 -0
  18. package/dist/src/ai/FlinkTool.d.ts +37 -0
  19. package/dist/src/ai/FlinkTool.js +2 -0
  20. package/dist/src/ai/LLMAdapter.d.ts +119 -0
  21. package/dist/src/ai/LLMAdapter.js +2 -0
  22. package/dist/src/ai/SubAgentExecutor.d.ts +36 -0
  23. package/dist/src/ai/SubAgentExecutor.js +220 -0
  24. package/dist/src/ai/ToolExecutor.d.ts +35 -0
  25. package/dist/src/ai/ToolExecutor.js +237 -0
  26. package/dist/src/ai/index.d.ts +5 -0
  27. package/dist/src/ai/index.js +21 -0
  28. package/dist/src/handlers/StreamWriterFactory.d.ts +20 -0
  29. package/dist/src/handlers/StreamWriterFactory.js +83 -0
  30. package/dist/src/index.d.ts +4 -0
  31. package/dist/src/index.js +4 -0
  32. package/dist/src/utils.d.ts +30 -0
  33. package/dist/src/utils.js +52 -0
  34. package/package.json +16 -2
  35. package/readme.md +425 -0
  36. package/spec/AgentDuplicateDetection.spec.ts +112 -0
  37. package/spec/AgentRunner.spec.ts +527 -0
  38. package/spec/ConversationHooks.spec.ts +290 -0
  39. package/spec/FlinkAgent.spec.ts +310 -0
  40. package/spec/FlinkApp.onError.spec.ts +1 -2
  41. package/spec/FlinkApp.query.spec.ts +107 -0
  42. package/spec/FlinkApp.validationMode.spec.ts +155 -0
  43. package/spec/StreamingIntegration.spec.ts +138 -0
  44. package/spec/SubAgentSupport.spec.ts +941 -0
  45. package/spec/ToolExecutor.spec.ts +360 -0
  46. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar.js +57 -0
  47. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar2.js +59 -0
  48. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema.js +53 -0
  49. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema2.js +53 -0
  50. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema3.js +53 -0
  51. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema.js +55 -0
  52. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema2.js +55 -0
  53. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile.js +58 -0
  54. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile2.js +58 -0
  55. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler.js +53 -0
  56. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler2.js +55 -0
  57. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchCar.js +58 -0
  58. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOnboardingSession.js +76 -0
  59. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.js +58 -0
  60. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchProductWithIntersection.js +59 -0
  61. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchUserWithUnion.js +59 -0
  62. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostCar.js +55 -0
  63. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogin.js +56 -0
  64. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogout.js +55 -0
  65. package/spec/mock-project/dist/spec/mock-project/src/handlers/PutCar.js +55 -0
  66. package/spec/mock-project/dist/spec/mock-project/src/index.js +83 -0
  67. package/spec/mock-project/dist/spec/mock-project/src/repos/CarRepo.js +26 -0
  68. package/spec/mock-project/dist/spec/mock-project/src/schemas/Car.js +2 -0
  69. package/spec/mock-project/dist/spec/mock-project/src/schemas/DefaultExportSchema.js +2 -0
  70. package/spec/mock-project/dist/spec/mock-project/src/schemas/FileWithTwoSchemas.js +2 -0
  71. package/spec/mock-project/dist/src/FlinkApp.js +1012 -0
  72. package/spec/mock-project/dist/src/FlinkContext.js +2 -0
  73. package/spec/mock-project/dist/src/FlinkErrors.js +143 -0
  74. package/spec/mock-project/dist/src/FlinkHttpHandler.js +47 -0
  75. package/spec/mock-project/dist/src/FlinkJob.js +2 -0
  76. package/spec/mock-project/dist/src/FlinkLog.js +26 -0
  77. package/spec/mock-project/dist/src/FlinkPlugin.js +2 -0
  78. package/spec/mock-project/dist/src/FlinkRepo.js +224 -0
  79. package/spec/mock-project/dist/src/FlinkResponse.js +2 -0
  80. package/spec/mock-project/dist/src/ai/AgentExecutor.js +279 -0
  81. package/spec/mock-project/dist/src/ai/AgentRunner.js +625 -0
  82. package/spec/mock-project/dist/src/ai/FlinkAgent.js +633 -0
  83. package/spec/mock-project/dist/src/ai/FlinkTool.js +2 -0
  84. package/spec/mock-project/dist/src/ai/LLMAdapter.js +2 -0
  85. package/spec/mock-project/dist/src/ai/SubAgentExecutor.js +220 -0
  86. package/spec/mock-project/dist/src/ai/ToolExecutor.js +237 -0
  87. package/spec/mock-project/dist/src/auth/FlinkAuthPlugin.js +2 -0
  88. package/spec/mock-project/dist/src/auth/FlinkAuthUser.js +2 -0
  89. package/spec/mock-project/dist/src/handlers/StreamWriterFactory.js +83 -0
  90. package/spec/mock-project/dist/src/index.js +17 -69
  91. package/spec/mock-project/dist/src/mock-data-generator.js +9 -0
  92. package/spec/mock-project/dist/src/utils.js +290 -0
  93. package/spec/mock-project/tsconfig.json +6 -1
  94. package/spec/testHelpers.ts +49 -0
  95. package/spec/utils.caseConversion.spec.ts +80 -0
  96. package/spec/utils.spec.ts +13 -13
  97. package/src/FlinkApp.ts +275 -8
  98. package/src/FlinkContext.ts +22 -0
  99. package/src/FlinkHttpHandler.ts +164 -10
  100. package/src/TypeScriptCompiler.ts +398 -7
  101. package/src/TypeScriptUtils.ts +5 -0
  102. package/src/ai/AgentRunner.ts +549 -0
  103. package/src/ai/FlinkAgent.ts +770 -0
  104. package/src/ai/FlinkTool.ts +40 -0
  105. package/src/ai/LLMAdapter.ts +96 -0
  106. package/src/ai/SubAgentExecutor.ts +199 -0
  107. package/src/ai/ToolExecutor.ts +193 -0
  108. package/src/ai/index.ts +5 -0
  109. package/src/handlers/StreamWriterFactory.ts +84 -0
  110. package/src/index.ts +4 -0
  111. package/src/utils.ts +52 -0
  112. package/tsconfig.json +6 -1
@@ -130,11 +130,100 @@ var TypeScriptCompiler = /** @class */ (function () {
130
130
  this.project = new ts_morph_1.Project({
131
131
  tsConfigFilePath: tsConfigPath,
132
132
  compilerOptions: compilerOptions,
133
+ skipAddingFilesFromTsConfig: true, // Don't auto-load all files - we'll add specific directories we need
133
134
  });
135
+ // Load Flink-specific source paths from tsconfig.json if available
136
+ var additionalSourcePaths = this.getFlinkSourcePaths(tsConfigPath);
137
+ // Only add source files from directories we actually need to process
138
+ // This prevents loading all files from tsconfig include patterns and reduces memory usage
139
+ var defaultSourcePaths = [
140
+ (0, path_1.join)(cwd, "src/handlers/**/*.ts"),
141
+ (0, path_1.join)(cwd, "src/repos/**/*.ts"),
142
+ (0, path_1.join)(cwd, "src/tools/**/*.ts"),
143
+ (0, path_1.join)(cwd, "src/agents/**/*.ts"),
144
+ (0, path_1.join)(cwd, "src/jobs/**/*.ts"),
145
+ (0, path_1.join)(cwd, "src/index.ts"),
146
+ (0, path_1.join)(cwd, "src/schemas/**/*.ts"), // Include schemas for type resolution
147
+ ];
148
+ var allSourcePaths = __spreadArray(__spreadArray([], defaultSourcePaths, true), additionalSourcePaths, true);
149
+ this.project.addSourceFilesAtPaths(allSourcePaths);
150
+ // Resolve imports: add any files imported by our source files
151
+ // This ensures schemas that import types from other locations work correctly
152
+ this.resolveImportedFiles();
134
153
  console.log("Loaded", this.project.getSourceFiles().length, "source file(s) from", cwd);
135
154
  console.log("Module system:", this.isEsm ? "ESM" : "CommonJS");
136
155
  console.log("Using module:", compilerOptions.module === ts_morph_1.ts.ModuleKind.ESNext ? "ESNext" : "CommonJS");
137
156
  }
157
+ /**
158
+ * Loads additional source paths from tsconfig.json's flink configuration.
159
+ * Allows projects to specify extra directories to include in compilation.
160
+ *
161
+ * Example tsconfig.json:
162
+ * {
163
+ * "flink": {
164
+ * "sourcePaths": ["src/custom-types/**\/*.ts", "src/utils/**\/*.ts"]
165
+ * }
166
+ * }
167
+ */
168
+ TypeScriptCompiler.prototype.getFlinkSourcePaths = function (tsConfigPath) {
169
+ var _this = this;
170
+ try {
171
+ if (fs_1.default.existsSync(tsConfigPath)) {
172
+ var tsConfigContent = fs_1.default.readFileSync(tsConfigPath, "utf8");
173
+ var tsConfig = JSON.parse(tsConfigContent);
174
+ if (tsConfig.flink && Array.isArray(tsConfig.flink.sourcePaths)) {
175
+ console.log("Found Flink-specific source paths:", tsConfig.flink.sourcePaths);
176
+ return tsConfig.flink.sourcePaths.map(function (path) { return (0, path_1.join)(_this.cwd, path); });
177
+ }
178
+ }
179
+ }
180
+ catch (error) {
181
+ console.warn("Error reading Flink source paths from tsconfig.json:", error);
182
+ }
183
+ return [];
184
+ };
185
+ /**
186
+ * Recursively resolves and adds imported files to the project.
187
+ * This ensures that files imported by handlers, schemas, etc. are available for type resolution.
188
+ *
189
+ * Handles three types of imports:
190
+ * 1. Relative imports (./foo, ../bar) - always resolved
191
+ * 2. Workspace package imports (@mycompany/shared) - resolved if symlinked outside node_modules
192
+ * 3. External packages (lodash, express) - skipped to avoid loading entire dependency trees
193
+ */
194
+ TypeScriptCompiler.prototype.resolveImportedFiles = function () {
195
+ var processedFiles = new Set();
196
+ var filesToProcess = __spreadArray([], this.project.getSourceFiles(), true);
197
+ while (filesToProcess.length > 0) {
198
+ var sourceFile = filesToProcess.pop();
199
+ var filePath = sourceFile.getFilePath();
200
+ if (processedFiles.has(filePath)) {
201
+ continue;
202
+ }
203
+ processedFiles.add(filePath);
204
+ // Get all import declarations
205
+ var importDeclarations = sourceFile.getImportDeclarations();
206
+ for (var _i = 0, importDeclarations_1 = importDeclarations; _i < importDeclarations_1.length; _i++) {
207
+ var importDecl = importDeclarations_1[_i];
208
+ var moduleSpecifier = importDecl.getModuleSpecifierValue();
209
+ // Try to resolve the imported file
210
+ var moduleSourceFile = importDecl.getModuleSpecifierSourceFile();
211
+ if (moduleSourceFile) {
212
+ var importedPath = moduleSourceFile.getFilePath();
213
+ // For relative imports (./foo, ../bar), always include
214
+ var isRelativeImport = moduleSpecifier.startsWith(".") || moduleSpecifier.startsWith("/");
215
+ // For package imports (@foo/bar, foo), check if resolved path is outside node_modules
216
+ // This handles workspace packages that are symlinked (pnpm, yarn workspaces)
217
+ var isWorkspacePackage = !isRelativeImport && !importedPath.includes("node_modules");
218
+ // Skip if it's in node_modules (external package) or already processed
219
+ if ((isRelativeImport || isWorkspacePackage) && !processedFiles.has(importedPath)) {
220
+ filesToProcess.push(moduleSourceFile);
221
+ }
222
+ }
223
+ }
224
+ }
225
+ console.log("Resolved imports, total files loaded:", processedFiles.size);
226
+ };
138
227
  /**
139
228
  * Detects if the project is using ESM (ECMAScript Modules)
140
229
  * by checking type in package.json.
@@ -244,6 +333,48 @@ var TypeScriptCompiler = /** @class */ (function () {
244
333
  }
245
334
  return true;
246
335
  };
336
+ /**
337
+ * Finds a variable declaration by its TypeScript type name.
338
+ * This allows finding variables based on their type annotation rather than variable name.
339
+ *
340
+ * @param sf Source file to search in
341
+ * @param typeName Name of the type to search for (e.g., "FlinkToolProps", "FlinkAgentProps")
342
+ * @returns The first matching variable declaration, or undefined if not found
343
+ */
344
+ TypeScriptCompiler.prototype.findVariableDeclarationByType = function (sf, typeName) {
345
+ var _a;
346
+ // Get all variable declarations from the source file
347
+ var variableDeclarations = sf.getVariableDeclarations();
348
+ for (var _i = 0, variableDeclarations_1 = variableDeclarations; _i < variableDeclarations_1.length; _i++) {
349
+ var varDecl = variableDeclarations_1[_i];
350
+ // Check if the variable is exported
351
+ var variableStatement = varDecl.getVariableStatement();
352
+ if (!(variableStatement === null || variableStatement === void 0 ? void 0 : variableStatement.isExported())) {
353
+ continue;
354
+ }
355
+ // Check if it's a const declaration
356
+ if (((_a = varDecl.getVariableStatement()) === null || _a === void 0 ? void 0 : _a.getDeclarationKind()) !== ts_morph_1.VariableDeclarationKind.Const) {
357
+ continue;
358
+ }
359
+ // Get the type node (explicit type annotation)
360
+ var typeNode = varDecl.getTypeNode();
361
+ if (!typeNode) {
362
+ continue;
363
+ }
364
+ // Check if it's a type reference
365
+ if (typeNode.getKind() === ts_morph_1.SyntaxKind.TypeReference) {
366
+ var typeRef = typeNode;
367
+ var typeRefName = typeRef.getTypeName();
368
+ // Handle both simple type references (FlinkToolProps) and qualified names (flink.FlinkToolProps)
369
+ var typeRefText = typeRefName.getText();
370
+ // Check if the type name matches (either exact match or ends with the type name for qualified references)
371
+ if (typeRefText === typeName || typeRefText.endsWith(".".concat(typeName))) {
372
+ return varDecl;
373
+ }
374
+ }
375
+ }
376
+ return undefined;
377
+ };
247
378
  /**
248
379
  * Scans project for handlers and add those to Flink
249
380
  * "singleton" property `autoRegisteredHandlers` so they can
@@ -408,6 +539,217 @@ var TypeScriptCompiler = /** @class */ (function () {
408
539
  });
409
540
  });
410
541
  };
542
+ /**
543
+ * Scans project for tools and adds those to Flink
544
+ * "singleton" property `autoRegisteredTools` so they can
545
+ * be registered during start.
546
+ */
547
+ TypeScriptCompiler.prototype.parseTools = function () {
548
+ return __awaiter(this, void 0, void 0, function () {
549
+ var generatedFile, toolsArr, imports, i, _i, _a, sf, namespaceImport, toolPropsVar, toolPropsExportName, existingFile;
550
+ return __generator(this, function (_b) {
551
+ switch (_b.label) {
552
+ case 0:
553
+ generatedFile = this.createSourceFile(["generatedTools.ts"], "// Generated ".concat(new Date(), "\nimport { autoRegisteredTools } from \"@flink-app/flink\";\nexport const tools = [];\nautoRegisteredTools.push(...tools);\n "));
554
+ toolsArr = generatedFile.getVariableDeclarationOrThrow("tools").getFirstDescendantByKindOrThrow(ts_morph_1.SyntaxKind.ArrayLiteralExpression);
555
+ imports = [];
556
+ i = 0;
557
+ for (_i = 0, _a = this.project.getSourceFiles(); _i < _a.length; _i++) {
558
+ sf = _a[_i];
559
+ if (!sf.getFilePath().includes("src/tools/")) {
560
+ continue;
561
+ }
562
+ console.log("Detected tool ".concat(sf.getBaseName()));
563
+ namespaceImport = sf.getBaseNameWithoutExtension().replace(/\./g, "_") + "_" + i;
564
+ imports.push({
565
+ defaultImport: "* as " + namespaceImport,
566
+ moduleSpecifier: this.getModuleSpecifier(generatedFile, sf),
567
+ });
568
+ toolPropsVar = this.findVariableDeclarationByType(sf, "FlinkToolProps");
569
+ toolPropsExportName = (toolPropsVar === null || toolPropsVar === void 0 ? void 0 : toolPropsVar.getName()) || "Tool";
570
+ existingFile = sf.getVariableStatements().filter(function (vs) {
571
+ var varNames = vs.getDeclarations().map(function (d) { return d.getName(); });
572
+ return varNames.includes("__file");
573
+ });
574
+ existingFile.forEach(function (v) { return v.remove(); });
575
+ // Append metadata to source file
576
+ sf.addVariableStatement({
577
+ declarationKind: ts_morph_1.VariableDeclarationKind.Const,
578
+ isExported: true,
579
+ declarations: [
580
+ {
581
+ name: "__file",
582
+ initializer: "\"".concat(sf.getBaseName(), "\""),
583
+ },
584
+ ],
585
+ });
586
+ // Create an object that wraps the namespace and provides named access to the tool props
587
+ toolsArr.insertElement(i, "{...".concat(namespaceImport, ", Tool: ").concat(namespaceImport, ".").concat(toolPropsExportName, "}"));
588
+ i++;
589
+ }
590
+ generatedFile.addImportDeclarations(imports);
591
+ return [4 /*yield*/, generatedFile.save()];
592
+ case 1:
593
+ _b.sent();
594
+ return [2 /*return*/, generatedFile];
595
+ }
596
+ });
597
+ });
598
+ };
599
+ /**
600
+ * Scans project for agents and validates tool references.
601
+ * Agents are declarative (no default function).
602
+ */
603
+ TypeScriptCompiler.prototype.parseAgents = function () {
604
+ return __awaiter(this, void 0, void 0, function () {
605
+ var generatedFile, agentsArr, imports, registeredToolIds, _i, _a, sf, toolExport, props, idProp, idValue, i, _b, _c, sf, agentClass, toolsProperty, initializer, toolsArray, toolElements, _loop_1, _d, toolElements_1, toolElement, className, existingFile;
606
+ var _e;
607
+ return __generator(this, function (_f) {
608
+ switch (_f.label) {
609
+ case 0:
610
+ generatedFile = this.createSourceFile(["generatedAgents.ts"], "// Generated ".concat(new Date(), "\nimport { autoRegisteredAgents } from \"@flink-app/flink\";\nexport const agents = [];\nautoRegisteredAgents.push(...agents);\n "));
611
+ agentsArr = generatedFile.getVariableDeclarationOrThrow("agents").getFirstDescendantByKindOrThrow(ts_morph_1.SyntaxKind.ArrayLiteralExpression);
612
+ imports = [];
613
+ registeredToolIds = new Set();
614
+ for (_i = 0, _a = this.project.getSourceFiles(); _i < _a.length; _i++) {
615
+ sf = _a[_i];
616
+ if (sf.getFilePath().includes("src/tools/")) {
617
+ toolExport = this.findVariableDeclarationByType(sf, "FlinkToolProps");
618
+ if (toolExport) {
619
+ props = toolExport.getFirstDescendantByKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
620
+ idProp = (props === null || props === void 0 ? void 0 : props.getProperty("id")) || (props === null || props === void 0 ? void 0 : props.getProperty("name"));
621
+ if (idProp) {
622
+ idValue = idProp.getLastChildByKind(ts_morph_1.SyntaxKind.StringLiteral);
623
+ if (idValue) {
624
+ registeredToolIds.add(idValue.getLiteralText());
625
+ }
626
+ }
627
+ }
628
+ }
629
+ }
630
+ i = 0;
631
+ for (_b = 0, _c = this.project.getSourceFiles(); _b < _c.length; _b++) {
632
+ sf = _c[_b];
633
+ if (!sf.getFilePath().includes("src/agents/")) {
634
+ continue;
635
+ }
636
+ agentClass = sf.getClasses().find(function (cls) {
637
+ var baseClass = cls.getBaseClass();
638
+ return (baseClass === null || baseClass === void 0 ? void 0 : baseClass.getName()) === "FlinkAgent";
639
+ });
640
+ if (!agentClass) {
641
+ // Skip files without FlinkAgent class
642
+ continue;
643
+ }
644
+ console.log("Detected agent ".concat(sf.getBaseName()));
645
+ toolsProperty = agentClass.getProperty("tools");
646
+ if (toolsProperty) {
647
+ initializer = toolsProperty.getInitializer();
648
+ if (initializer && initializer.getKind() === ts_morph_1.SyntaxKind.ArrayLiteralExpression) {
649
+ toolsArray = initializer;
650
+ toolElements = toolsArray.getElements();
651
+ _loop_1 = function (toolElement) {
652
+ var toolName = void 0;
653
+ // Handle string literals, method calls, and identifier references (tool imports)
654
+ if (toolElement.getKind() === ts_morph_1.SyntaxKind.StringLiteral) {
655
+ // Direct string: "tool-name"
656
+ toolName = toolElement.getText().replace(/['"]/g, "");
657
+ }
658
+ else if (toolElement.getKind() === ts_morph_1.SyntaxKind.CallExpression) {
659
+ // Method call: this.useTool("tool-name")
660
+ var args = toolElement.getArguments();
661
+ if (args.length > 0 && args[0].getKind() === ts_morph_1.SyntaxKind.StringLiteral) {
662
+ toolName = args[0].getText().replace(/['"]/g, "");
663
+ }
664
+ else {
665
+ console.warn("Agent ".concat(sf.getBaseName(), " has non-string tool reference, skipping validation"));
666
+ return "continue";
667
+ }
668
+ }
669
+ else if (toolElement.getKind() === ts_morph_1.SyntaxKind.Identifier) {
670
+ // Tool file reference (imported): SearchCarsByBrandTool
671
+ // Look up the import to find the actual tool file
672
+ var importName_1 = toolElement.getText();
673
+ var importDecl = sf.getImportDeclarations().find(function (imp) {
674
+ var namedImports = imp.getNamedImports();
675
+ return namedImports.some(function (ni) { return ni.getName() === importName_1; });
676
+ });
677
+ if (!importDecl) {
678
+ // Try namespace import (* as Foo)
679
+ var namespaceImport = sf.getImportDeclarations().find(function (imp) {
680
+ var _a;
681
+ return ((_a = imp.getNamespaceImport()) === null || _a === void 0 ? void 0 : _a.getText()) === importName_1;
682
+ });
683
+ if (namespaceImport) {
684
+ var moduleSpecifier = namespaceImport.getModuleSpecifierValue();
685
+ // Extract tool ID from the tool file path
686
+ // e.g., "../tools/SearchCarsByBrandTool" -> find in registeredToolIds
687
+ var toolFileName = (_e = moduleSpecifier.split("/").pop()) === null || _e === void 0 ? void 0 : _e.replace(/\.ts$/, "");
688
+ var matchingTool = Array.from(registeredToolIds).find(function (id) {
689
+ // Try to match by searching for the tool ID
690
+ // This is a heuristic - we'll validate it exists
691
+ return true; // Skip validation for imported tools for now
692
+ });
693
+ return "continue";
694
+ }
695
+ console.warn("Agent ".concat(sf.getBaseName(), " references tool \"").concat(importName_1, "\" but it's not imported, skipping validation"));
696
+ return "continue";
697
+ }
698
+ return "continue";
699
+ }
700
+ else {
701
+ console.warn("Agent ".concat(sf.getBaseName(), " has unexpected tool reference format: ").concat(toolElement.getText()));
702
+ return "continue";
703
+ }
704
+ if (!registeredToolIds.has(toolName)) {
705
+ console.error("Agent ".concat(sf.getBaseName(), " references tool \"").concat(toolName, "\" which does not exist"));
706
+ throw new Error("Invalid tool reference in agent ".concat(sf.getBaseName()));
707
+ }
708
+ };
709
+ for (_d = 0, toolElements_1 = toolElements; _d < toolElements_1.length; _d++) {
710
+ toolElement = toolElements_1[_d];
711
+ _loop_1(toolElement);
712
+ }
713
+ }
714
+ }
715
+ className = agentClass.getName();
716
+ if (!className) {
717
+ console.error("Agent class in ".concat(sf.getBaseName(), " has no name"));
718
+ continue;
719
+ }
720
+ imports.push({
721
+ defaultImport: className,
722
+ moduleSpecifier: this.getModuleSpecifier(generatedFile, sf),
723
+ });
724
+ existingFile = sf.getVariableStatements().filter(function (vs) {
725
+ var varNames = vs.getDeclarations().map(function (d) { return d.getName(); });
726
+ return varNames.includes("__file");
727
+ });
728
+ existingFile.forEach(function (v) { return v.remove(); });
729
+ // Append metadata
730
+ sf.addVariableStatement({
731
+ declarationKind: ts_morph_1.VariableDeclarationKind.Const,
732
+ isExported: true,
733
+ declarations: [
734
+ {
735
+ name: "__file",
736
+ initializer: "\"".concat(sf.getBaseName(), "\""),
737
+ },
738
+ ],
739
+ });
740
+ // Register the agent class
741
+ agentsArr.insertElement(i, "{ default: ".concat(className, ", __file: \"").concat(sf.getBaseName(), "\" }"));
742
+ i++;
743
+ }
744
+ generatedFile.addImportDeclarations(imports);
745
+ return [4 /*yield*/, generatedFile.save()];
746
+ case 1:
747
+ _f.sent();
748
+ return [2 /*return*/, generatedFile];
749
+ }
750
+ });
751
+ });
752
+ };
411
753
  /**
412
754
  * Generates a start script that will import references to handlers, repos and the
413
755
  * actual Flink app to start.
@@ -426,7 +768,7 @@ var TypeScriptCompiler = /** @class */ (function () {
426
768
  console.error("Cannot find entry script '".concat(appEntryScript, "'"));
427
769
  return [2 /*return*/, process.exit(1)];
428
770
  }
429
- sf = this.createSourceFile(["start.ts"], "// Generated ".concat(new Date(), "\nimport \"./generatedHandlers").concat(this.isEsm ? ".js" : "", "\";\nimport \"./generatedRepos").concat(this.isEsm ? ".js" : "", "\";\nimport \"./generatedJobs").concat(this.isEsm ? ".js" : "", "\";\nimport \"..").concat(appEntryScript.replace(/\.ts/g, "")).concat(this.isEsm ? ".js" : "", "\";\nexport default {}; // Export an empty object to make it a module\n"));
771
+ sf = this.createSourceFile(["start.ts"], "// Generated ".concat(new Date(), "\nimport \"./generatedHandlers").concat(this.isEsm ? ".js" : "", "\";\nimport \"./generatedRepos").concat(this.isEsm ? ".js" : "", "\";\nimport \"./generatedTools").concat(this.isEsm ? ".js" : "", "\";\nimport \"./generatedAgents").concat(this.isEsm ? ".js" : "", "\";\nimport \"./generatedJobs").concat(this.isEsm ? ".js" : "", "\";\nimport \"..").concat(appEntryScript.replace(/\.ts/g, "")).concat(this.isEsm ? ".js" : "", "\";\nexport default {}; // Export an empty object to make it a module\n"));
430
772
  return [4 /*yield*/, sf.save()];
431
773
  case 1:
432
774
  _a.sent();
@@ -528,7 +870,7 @@ var TypeScriptCompiler = /** @class */ (function () {
528
870
  return [2 /*return*/]; // 'any' indicates that no schema is used
529
871
  }
530
872
  schemaText = schema.getText();
531
- if (schemaText === 'void' || schemaText === 'undefined') {
873
+ if (schemaText === "void" || schemaText === "undefined") {
532
874
  return [2 /*return*/];
533
875
  }
534
876
  handlerFileName = handlerFile.getBaseNameWithoutExtension().replace(/\./g, "_");
@@ -564,7 +906,7 @@ var TypeScriptCompiler = /** @class */ (function () {
564
906
  if (interfaceNameMatches) {
565
907
  for (_d = 0, interfaceNameMatches_1 = interfaceNameMatches; _d < interfaceNameMatches_1.length; _d++) {
566
908
  match = interfaceNameMatches_1[_d];
567
- referencedInterfaceName = match.replace(/\s*\[$/, '').trim();
909
+ referencedInterfaceName = match.replace(/\s*\[$/, "").trim();
568
910
  referencedInterfaceDecl = handlerFile.getInterface(referencedInterfaceName) || handlerFile.getTypeAlias(referencedInterfaceName);
569
911
  if (referencedInterfaceDecl) {
570
912
  // Interface is in same file - copy it and all its dependencies recursively
@@ -663,7 +1005,7 @@ var TypeScriptCompiler = /** @class */ (function () {
663
1005
  if (interfaceNameMatches) {
664
1006
  for (_j = 0, interfaceNameMatches_2 = interfaceNameMatches; _j < interfaceNameMatches_2.length; _j++) {
665
1007
  match = interfaceNameMatches_2[_j];
666
- interfaceName = match.replace(/\s*\[$/, '').trim();
1008
+ interfaceName = match.replace(/\s*\[$/, "").trim();
667
1009
  interfaceDecl = handlerFile.getInterface(interfaceName) || handlerFile.getTypeAlias(interfaceName);
668
1010
  if (interfaceDecl) {
669
1011
  // Interface is in same file - copy it and all its dependencies recursively
@@ -191,6 +191,10 @@ function getTypeMetadata(type) {
191
191
  if (!type || ["void", "any"].includes(type.getText())) {
192
192
  return [];
193
193
  }
194
+ // Handle empty object literal {} (used in streaming handlers)
195
+ if (type.getText() === "{}") {
196
+ return [];
197
+ }
194
198
  var symbol = getSymbolOrAlias(type);
195
199
  if (!symbol) {
196
200
  throw new Error("Could not get type symbol for type: " + type.getText());
@@ -0,0 +1,39 @@
1
+ import { FlinkAgentProps, AgentExecuteInput, StreamChunk } from "./FlinkAgent";
2
+ import { ToolExecutor } from "./ToolExecutor";
3
+ import { LLMAdapter } from "./LLMAdapter";
4
+ export declare class AgentRunner {
5
+ private agentProps;
6
+ private tools;
7
+ private agentName?;
8
+ private llmAdapter;
9
+ private maxTokens;
10
+ private temperature;
11
+ private maxSteps;
12
+ private timeoutMs;
13
+ private maxSubAgentDepth;
14
+ constructor(agentProps: FlinkAgentProps, tools: Map<string, ToolExecutor<any>>, llmAdapters: Map<string, LLMAdapter>, agentName?: string | undefined);
15
+ /**
16
+ * Phase 1: Stream generator that yields complete event on finish
17
+ * Phase 2: Will yield text_delta and tool events during execution
18
+ */
19
+ streamGenerator(input: AgentExecuteInput): AsyncGenerator<StreamChunk>;
20
+ /**
21
+ * Convert Message[] to LLM message format
22
+ * Supports multi-turn conversations with history
23
+ */
24
+ private convertMessages;
25
+ private getToolSchemas;
26
+ /**
27
+ * Filter tools based on user permissions
28
+ * Only returns schemas for tools the user has permission to use
29
+ *
30
+ * @param user - User object
31
+ * @param userPermissions - Optional resolved permissions from auth plugin (preferred)
32
+ */
33
+ private filterToolsByPermissions;
34
+ /**
35
+ * Build delegation chain from metadata for error messages
36
+ * Extracts parent agent IDs to show the full call stack
37
+ */
38
+ private buildDelegationChain;
39
+ }