@flink-app/flink 0.14.3 → 2.0.0-alpha.100
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.
- package/CHANGELOG.md +1051 -0
- package/SCHEMA_EXTRACTION_ANALYSIS.md +494 -0
- package/SIMPLE_AST_FEASIBILITY.md +570 -0
- package/bin/flink.ts +13 -2
- package/cli/build.ts +24 -44
- package/cli/clean.ts +13 -25
- package/cli/cli-utils.ts +190 -17
- package/cli/dev.ts +252 -0
- package/cli/loadEnvFiles.ts +116 -0
- package/cli/run.ts +45 -62
- package/dist/bin/flink.js +61 -2
- package/dist/cli/build.js +20 -25
- package/dist/cli/clean.js +12 -10
- package/dist/cli/cli-utils.d.ts +34 -3
- package/dist/cli/cli-utils.js +193 -12
- package/dist/cli/dev.d.ts +2 -0
- package/dist/cli/dev.js +279 -0
- package/dist/cli/loadEnvFiles.d.ts +30 -0
- package/dist/cli/loadEnvFiles.js +113 -0
- package/dist/cli/run.js +47 -46
- package/dist/src/DependencyTracker.d.ts +44 -0
- package/dist/src/DependencyTracker.js +239 -0
- package/dist/src/FlinkApp.d.ts +163 -10
- package/dist/src/FlinkApp.js +847 -184
- package/dist/src/FlinkContext.d.ts +41 -0
- package/dist/src/FlinkErrors.d.ts +19 -6
- package/dist/src/FlinkErrors.js +36 -42
- package/dist/src/FlinkHttpHandler.d.ts +219 -26
- package/dist/src/FlinkHttpHandler.js +37 -1
- package/dist/src/FlinkJob.d.ts +10 -0
- package/dist/src/FlinkLog.d.ts +82 -18
- package/dist/src/FlinkLog.js +165 -13
- package/dist/src/FlinkLogFactory.d.ts +288 -0
- package/dist/src/FlinkLogFactory.js +619 -0
- package/dist/src/FlinkRepo.d.ts +10 -2
- package/dist/src/FlinkRepo.js +11 -1
- package/dist/src/FlinkRequestContext.d.ts +63 -0
- package/dist/src/FlinkRequestContext.js +74 -0
- package/dist/src/FlinkResponse.d.ts +6 -0
- package/dist/src/FlinkService.d.ts +38 -0
- package/dist/src/FlinkService.js +46 -0
- package/dist/src/LeaderElection.d.ts +45 -0
- package/dist/src/LeaderElection.js +269 -0
- package/dist/src/SchemaCache.d.ts +84 -0
- package/dist/src/SchemaCache.js +289 -0
- package/dist/src/TypeScriptCompiler.d.ts +161 -51
- package/dist/src/TypeScriptCompiler.js +1253 -617
- package/dist/src/TypeScriptUtils.js +4 -0
- package/dist/src/ai/AgentRunner.d.ts +39 -0
- package/dist/src/ai/AgentRunner.js +760 -0
- package/dist/src/ai/ConversationAgent.d.ts +279 -0
- package/dist/src/ai/ConversationAgent.js +404 -0
- package/dist/src/ai/ConversationFlinkAgent.d.ts +278 -0
- package/dist/src/ai/ConversationFlinkAgent.js +404 -0
- package/dist/src/ai/FlinkAgent.d.ts +690 -0
- package/dist/src/ai/FlinkAgent.js +729 -0
- package/dist/src/ai/FlinkTool.d.ts +135 -0
- package/dist/src/ai/FlinkTool.js +2 -0
- package/dist/src/ai/InMemoryConversationAgent.d.ts +121 -0
- package/dist/src/ai/InMemoryConversationAgent.js +209 -0
- package/dist/src/ai/LLMAdapter.d.ts +148 -0
- package/dist/src/ai/LLMAdapter.js +2 -0
- package/dist/src/ai/PersistentFlinkAgent.d.ts +278 -0
- package/dist/src/ai/PersistentFlinkAgent.js +403 -0
- package/dist/src/ai/SubAgentExecutor.d.ts +38 -0
- package/dist/src/ai/SubAgentExecutor.js +223 -0
- package/dist/src/ai/ToolExecutor.d.ts +64 -0
- package/dist/src/ai/ToolExecutor.js +497 -0
- package/dist/src/ai/agentInstructions.d.ts +68 -0
- package/dist/src/ai/agentInstructions.js +286 -0
- package/dist/src/ai/index.d.ts +8 -0
- package/dist/src/ai/index.js +26 -0
- package/dist/src/ai/instructionFileLoader.d.ts +44 -0
- package/dist/src/ai/instructionFileLoader.js +179 -0
- package/dist/src/auth/FlinkAuthPlugin.d.ts +1 -1
- package/dist/src/handlers/StreamWriterFactory.d.ts +20 -0
- package/dist/src/handlers/StreamWriterFactory.js +83 -0
- package/dist/src/index.d.ts +14 -0
- package/dist/src/index.js +17 -0
- package/dist/src/loadPluginSchemas.d.ts +45 -0
- package/dist/src/loadPluginSchemas.js +143 -0
- package/dist/src/schema-extraction/ComplexTypeDetection.d.ts +40 -0
- package/dist/src/schema-extraction/ComplexTypeDetection.js +75 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.d.ts +321 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.js +925 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.spec.d.ts +1 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.spec.js +233 -0
- package/dist/src/schema-extraction/TypeScriptTokenizer.d.ts +57 -0
- package/dist/src/schema-extraction/TypeScriptTokenizer.js +177 -0
- package/dist/src/schema-extraction/index.d.ts +2 -0
- package/dist/src/schema-extraction/index.js +20 -0
- package/dist/src/schema-extraction/types.d.ts +31 -0
- package/dist/src/schema-extraction/types.js +2 -0
- package/dist/src/utils/loadFlinkConfig.d.ts +53 -0
- package/dist/src/utils/loadFlinkConfig.js +77 -0
- package/dist/src/utils.d.ts +30 -0
- package/dist/src/utils.js +52 -0
- package/dist/src/workers/SchemaGeneratorWorker.d.ts +1 -0
- package/dist/src/workers/SchemaGeneratorWorker.js +49 -0
- package/dist/src/workers/WorkerPool.d.ts +60 -0
- package/dist/src/workers/WorkerPool.js +306 -0
- package/examples/logging-hierarchical-example.ts +125 -0
- package/package.json +29 -4
- package/readme.md +499 -0
- package/spec/AgentDescendantDetection.spec.ts +335 -0
- package/spec/AgentDuplicateDetection.spec.ts +112 -0
- package/spec/AgentObserver.spec.ts +266 -0
- package/spec/AgentRunner.spec.ts +1062 -0
- package/spec/AsyncLocalStorageContext.spec.ts +223 -0
- package/spec/ConversationHooks.spec.ts +257 -0
- package/spec/FlinkAgent.spec.ts +681 -0
- package/spec/FlinkApp.htmlResponse.spec.ts +260 -0
- package/spec/FlinkApp.onError.invocation.spec.ts +151 -0
- package/spec/FlinkApp.onError.spec.ts +1 -2
- package/spec/FlinkApp.query.spec.ts +107 -0
- package/spec/FlinkApp.routeOrdering.spec.ts +61 -0
- package/spec/FlinkApp.undefinedResponse.spec.ts +123 -0
- package/spec/FlinkApp.validationMode.spec.ts +155 -0
- package/spec/FlinkJob.spec.ts +171 -0
- package/spec/FlinkLogFactory.spec.ts +337 -0
- package/spec/FlinkRepo.spec.ts +1 -1
- package/spec/LeaderElection.spec.ts +174 -0
- package/spec/StreamingIntegration.spec.ts +139 -0
- package/spec/ToolExecutor.spec.ts +465 -0
- package/spec/TypeScriptCompiler.spec.ts +1 -1
- package/spec/TypeScriptSourceParser.spec.ts +1215 -0
- package/spec/TypeScriptTokenizer.spec.ts +366 -0
- package/spec/ai/ContextCompaction.spec.ts +405 -0
- package/spec/ai/ConversationAgent.spec.ts +520 -0
- package/spec/ai/InMemoryConversationAgent.spec.ts +144 -0
- package/spec/ai/agentInstructions.spec.ts +358 -0
- package/spec/fixtures/agent-instructions/TestAgent.ts +24 -0
- package/spec/fixtures/agent-instructions/simple.md +3 -0
- package/spec/fixtures/agent-instructions/template.md +18 -0
- package/spec/fixtures/agent-instructions/yaml-format.yaml +9 -0
- package/spec/mock-project/dist/.tsbuildinfo +1 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar.js +56 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar2.js +58 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema.js +52 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema2.js +52 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema3.js +52 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema.js +54 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema2.js +54 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile.js +57 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile2.js +57 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler.js +53 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler2.js +55 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchCar.js +57 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOnboardingSession.js +75 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.js +57 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchProductWithIntersection.js +58 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchUserWithUnion.js +58 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PostCar.js +54 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogin.js +55 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogout.js +54 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PutCar.js +54 -0
- package/spec/mock-project/dist/spec/mock-project/src/index.js +83 -0
- package/spec/mock-project/dist/spec/mock-project/src/repos/CarRepo.js +26 -0
- package/spec/mock-project/dist/spec/mock-project/src/schemas/Car.js +2 -0
- package/spec/mock-project/dist/spec/mock-project/src/schemas/DefaultExportSchema.js +2 -0
- package/spec/mock-project/dist/spec/mock-project/src/schemas/FileWithTwoSchemas.js +2 -0
- package/spec/mock-project/dist/src/FlinkApp.js +1000 -0
- package/spec/mock-project/dist/src/FlinkContext.js +2 -0
- package/spec/mock-project/dist/src/FlinkErrors.js +143 -0
- package/spec/mock-project/dist/src/FlinkHttpHandler.js +47 -0
- package/spec/mock-project/dist/src/FlinkJob.js +2 -0
- package/spec/mock-project/dist/src/FlinkLog.js +119 -0
- package/spec/mock-project/dist/src/FlinkLogFactory.js +617 -0
- package/spec/mock-project/dist/src/FlinkPlugin.js +2 -0
- package/spec/mock-project/dist/src/FlinkRepo.js +224 -0
- package/spec/mock-project/dist/src/FlinkRequestContext.js +74 -0
- package/spec/mock-project/dist/src/FlinkResponse.js +2 -0
- package/spec/mock-project/dist/src/ai/AgentExecutor.js +279 -0
- package/spec/mock-project/dist/src/ai/AgentRunner.js +632 -0
- package/spec/mock-project/dist/src/ai/ConversationAgent.js +402 -0
- package/spec/mock-project/dist/src/ai/ConversationFlinkAgent.js +422 -0
- package/spec/mock-project/dist/src/ai/FlinkAgent.js +699 -0
- package/spec/mock-project/dist/src/ai/FlinkTool.js +2 -0
- package/spec/mock-project/dist/src/ai/InMemoryConversationAgent.js +209 -0
- package/spec/mock-project/dist/src/ai/LLMAdapter.js +2 -0
- package/spec/mock-project/dist/src/ai/SubAgentExecutor.js +223 -0
- package/spec/mock-project/dist/src/ai/ToolExecutor.js +412 -0
- package/spec/mock-project/dist/src/ai/agentInstructions.js +246 -0
- package/spec/mock-project/dist/src/auth/FlinkAuthPlugin.js +2 -0
- package/spec/mock-project/dist/src/auth/FlinkAuthUser.js +2 -0
- package/spec/mock-project/dist/src/handlers/GetCar.js +26 -52
- package/spec/mock-project/dist/src/handlers/GetCar.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCar2.js +32 -54
- package/spec/mock-project/dist/src/handlers/GetCar2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +26 -48
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +28 -48
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +29 -48
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +26 -50
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +28 -50
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +27 -53
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +29 -53
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +16 -49
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +25 -50
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchCar.js +27 -53
- package/spec/mock-project/dist/src/handlers/PatchCar.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js +44 -70
- package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js +27 -53
- package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js +28 -54
- package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js +28 -54
- package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PostCar.js +24 -50
- package/spec/mock-project/dist/src/handlers/PostCar.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PostLogin.js +25 -51
- package/spec/mock-project/dist/src/handlers/PostLogin.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PostLogout.js +24 -50
- package/spec/mock-project/dist/src/handlers/PostLogout.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PutCar.js +24 -50
- package/spec/mock-project/dist/src/handlers/PutCar.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/StreamWriterFactory.js +83 -0
- package/spec/mock-project/dist/src/index.js +52 -76
- package/spec/mock-project/dist/src/index.js.map +1 -0
- package/spec/mock-project/dist/src/mock-data-generator.js +9 -0
- package/spec/mock-project/dist/src/repos/CarRepo.js +12 -24
- package/spec/mock-project/dist/src/repos/CarRepo.js.map +1 -0
- package/spec/mock-project/dist/src/schemas/Car.js +3 -1
- package/spec/mock-project/dist/src/schemas/Car.js.map +1 -0
- package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js +3 -1
- package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js.map +1 -0
- package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js +3 -1
- package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js.map +1 -0
- package/spec/mock-project/dist/src/utils.js +290 -0
- package/spec/mock-project/tsconfig.json +6 -1
- package/spec/schema-generation-nested-objects.spec.ts +97 -0
- package/spec/testHelpers.ts +49 -0
- package/spec/utils.caseConversion.spec.ts +78 -0
- package/spec/utils.spec.ts +13 -13
- package/src/DependencyTracker.ts +166 -0
- package/src/FlinkApp.ts +919 -155
- package/src/FlinkContext.ts +43 -0
- package/src/FlinkErrors.ts +32 -12
- package/src/FlinkHttpHandler.ts +246 -28
- package/src/FlinkJob.ts +11 -0
- package/src/FlinkLog.ts +119 -12
- package/src/FlinkLogFactory.ts +699 -0
- package/src/FlinkRepo.ts +10 -3
- package/src/FlinkRequestContext.ts +95 -0
- package/src/FlinkResponse.ts +6 -0
- package/src/FlinkService.ts +49 -0
- package/src/LeaderElection.ts +203 -0
- package/src/SchemaCache.ts +232 -0
- package/src/TypeScriptCompiler.ts +1347 -610
- package/src/TypeScriptUtils.ts +5 -0
- package/src/ai/AgentRunner.ts +646 -0
- package/src/ai/ConversationAgent.ts +413 -0
- package/src/ai/FlinkAgent.ts +1069 -0
- package/src/ai/FlinkTool.ts +165 -0
- package/src/ai/InMemoryConversationAgent.ts +149 -0
- package/src/ai/LLMAdapter.ts +126 -0
- package/src/ai/ToolExecutor.ts +485 -0
- package/src/ai/agentInstructions.ts +245 -0
- package/src/ai/index.ts +8 -0
- package/src/ai/instructionFileLoader.ts +156 -0
- package/src/auth/FlinkAuthPlugin.ts +2 -1
- package/src/handlers/StreamWriterFactory.ts +84 -0
- package/src/index.ts +14 -0
- package/src/loadPluginSchemas.ts +141 -0
- package/src/schema-extraction/TypeScriptSourceParser.ts +1058 -0
- package/src/schema-extraction/TypeScriptTokenizer.ts +205 -0
- package/src/schema-extraction/index.ts +2 -0
- package/src/schema-extraction/types.ts +34 -0
- package/src/utils/loadFlinkConfig.ts +89 -0
- package/src/utils.ts +52 -0
- package/tsconfig.json +6 -1
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.ToolExecutor = void 0;
|
|
43
|
+
var ajv_1 = __importDefault(require("ajv"));
|
|
44
|
+
var FlinkErrors_1 = require("../FlinkErrors");
|
|
45
|
+
var FlinkLogFactory_1 = require("../FlinkLogFactory");
|
|
46
|
+
var FlinkRequestContext_1 = require("../FlinkRequestContext");
|
|
47
|
+
var toolLog = FlinkLogFactory_1.FlinkLogFactory.createLogger("flink.ai.tool");
|
|
48
|
+
var ToolExecutor = /** @class */ (function () {
|
|
49
|
+
function ToolExecutor(toolProps, toolFn, ctx, autoSchemas) {
|
|
50
|
+
this.toolProps = toolProps;
|
|
51
|
+
this.toolFn = toolFn;
|
|
52
|
+
this.ctx = ctx;
|
|
53
|
+
this.autoSchemas = autoSchemas;
|
|
54
|
+
this.ajv = new ajv_1.default({ allErrors: true });
|
|
55
|
+
// Validate that either manual schemas or auto-generated schemas are provided
|
|
56
|
+
var hasInputSchema = toolProps.inputSchema || toolProps.inputJsonSchema || (autoSchemas === null || autoSchemas === void 0 ? void 0 : autoSchemas.inputSchema);
|
|
57
|
+
if (!hasInputSchema) {
|
|
58
|
+
throw new Error("Tool ".concat(toolProps.id, ": No input schema provided. Either define 'inputSchema' (Zod), ") +
|
|
59
|
+
"'inputJsonSchema' (JSON Schema), or use TypeScript type parameters for auto-generation.");
|
|
60
|
+
}
|
|
61
|
+
// Log when using auto-schemas
|
|
62
|
+
if ((autoSchemas === null || autoSchemas === void 0 ? void 0 : autoSchemas.inputSchema) && !toolProps.inputSchema && !toolProps.inputJsonSchema) {
|
|
63
|
+
toolLog.debug("Tool ".concat(toolProps.id, ": Using auto-generated schemas from type parameters"));
|
|
64
|
+
}
|
|
65
|
+
// Warn if both manual and auto provided (manual takes precedence)
|
|
66
|
+
if ((toolProps.inputSchema || toolProps.inputJsonSchema) && (autoSchemas === null || autoSchemas === void 0 ? void 0 : autoSchemas.inputSchema)) {
|
|
67
|
+
toolLog.debug("Tool ".concat(toolProps.id, ": Manual schemas take precedence over auto-generated schemas"));
|
|
68
|
+
}
|
|
69
|
+
// Log warning if both manual Zod and JSON schemas are provided
|
|
70
|
+
if (toolProps.inputSchema && toolProps.inputJsonSchema) {
|
|
71
|
+
toolLog.warn("Tool ".concat(toolProps.id, ": Both 'inputSchema' (Zod) and 'inputJsonSchema' are provided. ") + "Using 'inputSchema' for validation.");
|
|
72
|
+
}
|
|
73
|
+
if (toolProps.outputSchema && toolProps.outputJsonSchema) {
|
|
74
|
+
toolLog.warn("Tool ".concat(toolProps.id, ": Both 'outputSchema' (Zod) and 'outputJsonSchema' are provided. ") + "Using 'outputSchema' for validation.");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Execute the tool with input
|
|
79
|
+
* @param input - Tool input data
|
|
80
|
+
* @param overrides - Optional overrides for user/permissions/conversationContext (for testing)
|
|
81
|
+
*/
|
|
82
|
+
ToolExecutor.prototype.execute = function (input, overrides) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
84
|
+
var user, userPermissions, conversationContext, hasPermission, validatedInput, validate, valid, errorDetails, validate, valid, errorDetails, errorDetails, result, err_1, validatedData, validate, valid, errorDetails, validate, valid, errorDetails;
|
|
85
|
+
var _a, _b, _c, _d;
|
|
86
|
+
return __generator(this, function (_e) {
|
|
87
|
+
switch (_e.label) {
|
|
88
|
+
case 0:
|
|
89
|
+
user = (_a = overrides === null || overrides === void 0 ? void 0 : overrides.user) !== null && _a !== void 0 ? _a : (0, FlinkRequestContext_1.getRequestUser)();
|
|
90
|
+
userPermissions = (_b = overrides === null || overrides === void 0 ? void 0 : overrides.permissions) !== null && _b !== void 0 ? _b : (0, FlinkRequestContext_1.getRequestPermissions)();
|
|
91
|
+
conversationContext = overrides === null || overrides === void 0 ? void 0 : overrides.conversationContext;
|
|
92
|
+
if (!this.toolProps.permissions) return [3 /*break*/, 2];
|
|
93
|
+
return [4 /*yield*/, this.checkPermissionsInternal(input, user, userPermissions)];
|
|
94
|
+
case 1:
|
|
95
|
+
hasPermission = _e.sent();
|
|
96
|
+
if (!hasPermission) {
|
|
97
|
+
toolLog.debug("Tool invocator is missing required permission(s)", this.toolProps.permissions, "user has", userPermissions);
|
|
98
|
+
throw (0, FlinkErrors_1.forbidden)("Permission denied for tool ".concat(this.toolProps.id), "PERMISSION_DENIED");
|
|
99
|
+
}
|
|
100
|
+
_e.label = 2;
|
|
101
|
+
case 2:
|
|
102
|
+
try {
|
|
103
|
+
if (this.toolProps.inputSchema) {
|
|
104
|
+
// Priority 1: Use Zod validation
|
|
105
|
+
validatedInput = this.toolProps.inputSchema.parse(input);
|
|
106
|
+
}
|
|
107
|
+
else if (this.toolProps.inputJsonSchema) {
|
|
108
|
+
validate = this.ajv.compile(this.toolProps.inputJsonSchema);
|
|
109
|
+
valid = validate(input);
|
|
110
|
+
if (!valid) {
|
|
111
|
+
errorDetails = this.formatAjvErrors(validate.errors || [], input);
|
|
112
|
+
toolLog.warn("Tool ".concat(this.toolProps.id, " input validation failed:"), errorDetails);
|
|
113
|
+
return [2 /*return*/, {
|
|
114
|
+
success: false,
|
|
115
|
+
error: "Invalid input for tool '".concat(this.toolProps.id, "': ").concat(errorDetails),
|
|
116
|
+
code: "VALIDATION_ERROR",
|
|
117
|
+
}];
|
|
118
|
+
}
|
|
119
|
+
validatedInput = input;
|
|
120
|
+
}
|
|
121
|
+
else if ((_c = this.autoSchemas) === null || _c === void 0 ? void 0 : _c.inputSchema) {
|
|
122
|
+
validate = this.ajv.compile(this.autoSchemas.inputSchema);
|
|
123
|
+
valid = validate(input);
|
|
124
|
+
if (!valid) {
|
|
125
|
+
errorDetails = this.formatAjvErrors(validate.errors || [], input);
|
|
126
|
+
toolLog.warn("Tool ".concat(this.toolProps.id, " input validation failed (auto-generated schema):"), errorDetails);
|
|
127
|
+
return [2 /*return*/, {
|
|
128
|
+
success: false,
|
|
129
|
+
error: "Invalid input for tool '".concat(this.toolProps.id, "': ").concat(errorDetails),
|
|
130
|
+
code: "VALIDATION_ERROR",
|
|
131
|
+
}];
|
|
132
|
+
}
|
|
133
|
+
validatedInput = input;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// No schema available - skip validation
|
|
137
|
+
validatedInput = input;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
toolLog.warn("Tool ".concat(this.toolProps.id, " input validation failed:"), err.message);
|
|
142
|
+
errorDetails = this.formatZodError(err, input);
|
|
143
|
+
return [2 /*return*/, {
|
|
144
|
+
success: false,
|
|
145
|
+
error: "Invalid input for tool '".concat(this.toolProps.id, "': ").concat(errorDetails),
|
|
146
|
+
code: "VALIDATION_ERROR",
|
|
147
|
+
}];
|
|
148
|
+
}
|
|
149
|
+
// 3. Execute tool
|
|
150
|
+
toolLog.debug("Executing tool ".concat(this.toolProps.id));
|
|
151
|
+
_e.label = 3;
|
|
152
|
+
case 3:
|
|
153
|
+
_e.trys.push([3, 5, , 6]);
|
|
154
|
+
toolLog.trace(this.toolFn.name + " input:", validatedInput);
|
|
155
|
+
return [4 /*yield*/, this.toolFn({
|
|
156
|
+
input: validatedInput,
|
|
157
|
+
ctx: this.ctx,
|
|
158
|
+
user: user,
|
|
159
|
+
permissions: userPermissions,
|
|
160
|
+
conversationCtx: conversationContext,
|
|
161
|
+
})];
|
|
162
|
+
case 4:
|
|
163
|
+
result = _e.sent();
|
|
164
|
+
return [3 /*break*/, 6];
|
|
165
|
+
case 5:
|
|
166
|
+
err_1 = _e.sent();
|
|
167
|
+
toolLog.error("Tool ".concat(this.toolProps.id, " threw error:"), err_1.message);
|
|
168
|
+
return [2 /*return*/, {
|
|
169
|
+
success: false,
|
|
170
|
+
error: "Tool execution failed: ".concat(err_1.message),
|
|
171
|
+
code: "EXECUTION_ERROR",
|
|
172
|
+
}];
|
|
173
|
+
case 6:
|
|
174
|
+
// 4. Handle error results
|
|
175
|
+
if (!result.success) {
|
|
176
|
+
toolLog.warn("Tool ".concat(this.toolProps.id, " returned error:"), result.error);
|
|
177
|
+
return [2 /*return*/, result]; // Return error result as-is
|
|
178
|
+
}
|
|
179
|
+
// 5. Output validation (priority: Zod > JSON Schema > Auto-generated)
|
|
180
|
+
if (this.toolProps.outputSchema) {
|
|
181
|
+
// Priority 1: Use Zod validation
|
|
182
|
+
try {
|
|
183
|
+
validatedData = this.toolProps.outputSchema.parse(result.data);
|
|
184
|
+
return [2 /*return*/, { success: true, data: validatedData }];
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
toolLog.error("Tool ".concat(this.toolProps.id, " output validation failed:"), err.message);
|
|
188
|
+
return [2 /*return*/, {
|
|
189
|
+
success: false,
|
|
190
|
+
error: "Invalid output from tool ".concat(this.toolProps.id, ": ").concat(err.message),
|
|
191
|
+
code: "OUTPUT_VALIDATION_ERROR",
|
|
192
|
+
}];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else if (this.toolProps.outputJsonSchema) {
|
|
196
|
+
// Priority 2: Use manual JSON Schema validation
|
|
197
|
+
try {
|
|
198
|
+
validate = this.ajv.compile(this.toolProps.outputJsonSchema);
|
|
199
|
+
valid = validate(result.data);
|
|
200
|
+
if (!valid) {
|
|
201
|
+
errorDetails = this.formatAjvErrors(validate.errors || []);
|
|
202
|
+
toolLog.error("Tool ".concat(this.toolProps.id, " output validation failed:"), errorDetails);
|
|
203
|
+
return [2 /*return*/, {
|
|
204
|
+
success: false,
|
|
205
|
+
error: "Invalid output from tool ".concat(this.toolProps.id, ": ").concat(errorDetails),
|
|
206
|
+
code: "OUTPUT_VALIDATION_ERROR",
|
|
207
|
+
}];
|
|
208
|
+
}
|
|
209
|
+
return [2 /*return*/, { success: true, data: result.data }];
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
toolLog.error("Tool ".concat(this.toolProps.id, " output validation failed:"), err.message);
|
|
213
|
+
return [2 /*return*/, {
|
|
214
|
+
success: false,
|
|
215
|
+
error: "Invalid output from tool ".concat(this.toolProps.id, ": ").concat(err.message),
|
|
216
|
+
code: "OUTPUT_VALIDATION_ERROR",
|
|
217
|
+
}];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if ((_d = this.autoSchemas) === null || _d === void 0 ? void 0 : _d.outputSchema) {
|
|
221
|
+
// Priority 3: Use auto-generated JSON Schema validation
|
|
222
|
+
try {
|
|
223
|
+
validate = this.ajv.compile(this.autoSchemas.outputSchema);
|
|
224
|
+
valid = validate(result.data);
|
|
225
|
+
if (!valid) {
|
|
226
|
+
errorDetails = this.formatAjvErrors(validate.errors || []);
|
|
227
|
+
toolLog.error("Tool ".concat(this.toolProps.id, " output validation failed (auto-generated schema):"), errorDetails);
|
|
228
|
+
return [2 /*return*/, {
|
|
229
|
+
success: false,
|
|
230
|
+
error: "Invalid output from tool ".concat(this.toolProps.id, ": ").concat(errorDetails),
|
|
231
|
+
code: "OUTPUT_VALIDATION_ERROR",
|
|
232
|
+
}];
|
|
233
|
+
}
|
|
234
|
+
return [2 /*return*/, { success: true, data: result.data }];
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
toolLog.error("Tool ".concat(this.toolProps.id, " output validation failed:"), err.message);
|
|
238
|
+
return [2 /*return*/, {
|
|
239
|
+
success: false,
|
|
240
|
+
error: "Invalid output from tool ".concat(this.toolProps.id, ": ").concat(err.message),
|
|
241
|
+
code: "OUTPUT_VALIDATION_ERROR",
|
|
242
|
+
}];
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// No output validation - return result as-is
|
|
246
|
+
return [2 /*return*/, result];
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
ToolExecutor.prototype.getToolSchema = function () {
|
|
252
|
+
// Priority order: inputJsonSchema > inputSchema (Zod 4.x) > autoSchemas
|
|
253
|
+
var _a;
|
|
254
|
+
// Priority 1: Manual JSON schema
|
|
255
|
+
if (this.toolProps.inputJsonSchema) {
|
|
256
|
+
return {
|
|
257
|
+
name: this.toolProps.id,
|
|
258
|
+
description: this.toolProps.description,
|
|
259
|
+
inputSchema: this.toolProps.inputJsonSchema,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
// Priority 2: Zod schema (convert to JSON Schema using Zod 4.x)
|
|
263
|
+
if (this.toolProps.inputSchema) {
|
|
264
|
+
var z = require("zod");
|
|
265
|
+
if (!z.toJSONSchema) {
|
|
266
|
+
throw new Error("Tool ".concat(this.toolProps.id, ": Zod 4.x is required for automatic schema generation. ") +
|
|
267
|
+
"Either upgrade to Zod 4.x or provide 'inputJsonSchema' in your tool definition, " +
|
|
268
|
+
"or use TypeScript type parameters for auto-generation.");
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
name: this.toolProps.id,
|
|
272
|
+
description: this.toolProps.description,
|
|
273
|
+
inputSchema: z.toJSONSchema(this.toolProps.inputSchema),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
// Priority 3: Auto-generated schema from type parameters
|
|
277
|
+
if ((_a = this.autoSchemas) === null || _a === void 0 ? void 0 : _a.inputSchema) {
|
|
278
|
+
return {
|
|
279
|
+
name: this.toolProps.id,
|
|
280
|
+
description: this.toolProps.description,
|
|
281
|
+
inputSchema: this.autoSchemas.inputSchema,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
// Should never reach here due to constructor validation
|
|
285
|
+
throw new Error("Tool ".concat(this.toolProps.id, ": No input schema provided"));
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* Get tool result for AI consumption
|
|
289
|
+
* Formats ToolResult into string for AI context
|
|
290
|
+
*/
|
|
291
|
+
ToolExecutor.prototype.formatResultForAI = function (result) {
|
|
292
|
+
if (result.success) {
|
|
293
|
+
return JSON.stringify(result.data);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
return "Error: ".concat(result.error).concat(result.code ? " (".concat(result.code, ")") : "");
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
/**
|
|
300
|
+
* Check if user has permission to use this tool
|
|
301
|
+
* Used by AgentRunner to filter tools before showing to LLM
|
|
302
|
+
*
|
|
303
|
+
* @param user - User object
|
|
304
|
+
* @param input - Tool input (for function-based permissions)
|
|
305
|
+
* @param userPermissions - Optional resolved permissions from auth plugin (preferred)
|
|
306
|
+
* @param conversationContext - Optional conversation context
|
|
307
|
+
*/
|
|
308
|
+
ToolExecutor.prototype.checkPermissions = function (user, input, userPermissions, conversationContext) {
|
|
309
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
310
|
+
var perms, effectivePerms, requiredPerms;
|
|
311
|
+
return __generator(this, function (_a) {
|
|
312
|
+
switch (_a.label) {
|
|
313
|
+
case 0:
|
|
314
|
+
perms = this.toolProps.permissions;
|
|
315
|
+
if (!perms)
|
|
316
|
+
return [2 /*return*/, true];
|
|
317
|
+
if (!(typeof perms === "function")) return [3 /*break*/, 2];
|
|
318
|
+
return [4 /*yield*/, perms(input !== null && input !== void 0 ? input : {}, user)];
|
|
319
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
320
|
+
case 2:
|
|
321
|
+
effectivePerms = userPermissions || (user === null || user === void 0 ? void 0 : user.permissions) || [];
|
|
322
|
+
// If no user and no explicit permissions, deny access
|
|
323
|
+
if (!user && !userPermissions)
|
|
324
|
+
return [2 /*return*/, false];
|
|
325
|
+
requiredPerms = Array.isArray(perms) ? perms : [perms];
|
|
326
|
+
return [2 /*return*/, requiredPerms.every(function (p) { return effectivePerms.includes(p); })];
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
ToolExecutor.prototype.checkPermissionsInternal = function (input, user, userPermissions, conversationContext) {
|
|
332
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
333
|
+
return __generator(this, function (_a) {
|
|
334
|
+
return [2 /*return*/, this.checkPermissions(user, input, userPermissions, conversationContext)];
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* Format Zod validation errors into LLM-friendly error messages
|
|
340
|
+
* Provides specific guidance on what's missing or incorrect
|
|
341
|
+
*/
|
|
342
|
+
ToolExecutor.prototype.formatZodError = function (err, receivedInput) {
|
|
343
|
+
// Check if it's a Zod error with issues array
|
|
344
|
+
if (err.issues && Array.isArray(err.issues)) {
|
|
345
|
+
var issues = err.issues.map(function (issue) {
|
|
346
|
+
var path = issue.path.join(".");
|
|
347
|
+
var field = path || "input";
|
|
348
|
+
if (issue.code === "invalid_type") {
|
|
349
|
+
if (issue.received === "undefined") {
|
|
350
|
+
return "Missing required field '".concat(field, "' (expected ").concat(issue.expected, ")");
|
|
351
|
+
}
|
|
352
|
+
return "Field '".concat(field, "' has wrong type: expected ").concat(issue.expected, ", got ").concat(issue.received);
|
|
353
|
+
}
|
|
354
|
+
if (issue.code === "too_small") {
|
|
355
|
+
if (issue.type === "string") {
|
|
356
|
+
return "Field '".concat(field, "' is too short (minimum ").concat(issue.minimum, " characters)");
|
|
357
|
+
}
|
|
358
|
+
return "Field '".concat(field, "' is too small (minimum ").concat(issue.minimum, ")");
|
|
359
|
+
}
|
|
360
|
+
if (issue.code === "too_big") {
|
|
361
|
+
if (issue.type === "string") {
|
|
362
|
+
return "Field '".concat(field, "' is too long (maximum ").concat(issue.maximum, " characters)");
|
|
363
|
+
}
|
|
364
|
+
return "Field '".concat(field, "' is too large (maximum ").concat(issue.maximum, ")");
|
|
365
|
+
}
|
|
366
|
+
// Generic fallback
|
|
367
|
+
return "".concat(field, ": ").concat(issue.message);
|
|
368
|
+
});
|
|
369
|
+
if (receivedInput) {
|
|
370
|
+
var inputInfo = Object.keys(receivedInput || {}).length === 0 ? "You provided an empty object {}." : "You provided: ".concat(JSON.stringify(receivedInput));
|
|
371
|
+
return "".concat(issues.join("; "), ". ").concat(inputInfo);
|
|
372
|
+
}
|
|
373
|
+
return issues.join("; ");
|
|
374
|
+
}
|
|
375
|
+
// Fallback for non-Zod errors
|
|
376
|
+
return err.message || "Unknown validation error";
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Format AJV validation errors into LLM-friendly error messages
|
|
380
|
+
*/
|
|
381
|
+
ToolExecutor.prototype.formatAjvErrors = function (errors, receivedInput) {
|
|
382
|
+
var issues = errors.map(function (error) {
|
|
383
|
+
var field = error.instancePath ? error.instancePath.substring(1).replace(/\//g, ".") : "input";
|
|
384
|
+
if (error.keyword === "required") {
|
|
385
|
+
return "Missing required field '".concat(error.params.missingProperty, "'");
|
|
386
|
+
}
|
|
387
|
+
if (error.keyword === "type") {
|
|
388
|
+
return "Field '".concat(field, "' has wrong type: expected ").concat(error.params.type);
|
|
389
|
+
}
|
|
390
|
+
if (error.keyword === "minLength") {
|
|
391
|
+
return "Field '".concat(field, "' is too short (minimum ").concat(error.params.limit, " characters)");
|
|
392
|
+
}
|
|
393
|
+
if (error.keyword === "maxLength") {
|
|
394
|
+
return "Field '".concat(field, "' is too long (maximum ").concat(error.params.limit, " characters)");
|
|
395
|
+
}
|
|
396
|
+
if (error.keyword === "minimum") {
|
|
397
|
+
return "Field '".concat(field, "' is too small (minimum ").concat(error.params.limit, ")");
|
|
398
|
+
}
|
|
399
|
+
if (error.keyword === "maximum") {
|
|
400
|
+
return "Field '".concat(field, "' is too large (maximum ").concat(error.params.limit, ")");
|
|
401
|
+
}
|
|
402
|
+
return "".concat(field, ": ").concat(error.message);
|
|
403
|
+
});
|
|
404
|
+
if (receivedInput) {
|
|
405
|
+
var inputInfo = Object.keys(receivedInput || {}).length === 0 ? "You provided an empty object {}." : "You provided: ".concat(JSON.stringify(receivedInput));
|
|
406
|
+
return "".concat(issues.join("; "), ". ").concat(inputInfo);
|
|
407
|
+
}
|
|
408
|
+
return issues.join("; ");
|
|
409
|
+
};
|
|
410
|
+
return ToolExecutor;
|
|
411
|
+
}());
|
|
412
|
+
exports.ToolExecutor = ToolExecutor;
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
37
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
38
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
39
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
40
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
41
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
42
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
46
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
47
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
48
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
49
|
+
function step(op) {
|
|
50
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
51
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
52
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
53
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
54
|
+
switch (op[0]) {
|
|
55
|
+
case 0: case 1: t = op; break;
|
|
56
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
57
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
58
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
59
|
+
default:
|
|
60
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
61
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
62
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
63
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
64
|
+
if (t[2]) _.ops.pop();
|
|
65
|
+
_.trys.pop(); continue;
|
|
66
|
+
}
|
|
67
|
+
op = body.call(thisArg, _);
|
|
68
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
69
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
73
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
74
|
+
};
|
|
75
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
76
|
+
exports.agentInstructions = agentInstructions;
|
|
77
|
+
var fs = __importStar(require("fs"));
|
|
78
|
+
var path = __importStar(require("path"));
|
|
79
|
+
var handlebars_1 = __importDefault(require("handlebars"));
|
|
80
|
+
/**
|
|
81
|
+
* In-memory file cache (per-process, not persistent)
|
|
82
|
+
*/
|
|
83
|
+
var fileCache = new Map();
|
|
84
|
+
/**
|
|
85
|
+
* Get caller's file location using stack trace API
|
|
86
|
+
* This enables agent-relative path resolution for ./ and ../ prefixes
|
|
87
|
+
*/
|
|
88
|
+
function getCallerFilePath() {
|
|
89
|
+
var originalPrepareStackTrace = Error.prepareStackTrace;
|
|
90
|
+
Error.prepareStackTrace = function (_, stack) { return stack; };
|
|
91
|
+
var stack = new Error().stack;
|
|
92
|
+
Error.prepareStackTrace = originalPrepareStackTrace;
|
|
93
|
+
// Stack: [0] getCallerFilePath, [1] agentInstructions, [2] agent class
|
|
94
|
+
var callerFrame = stack[2];
|
|
95
|
+
var fileName = callerFrame === null || callerFrame === void 0 ? void 0 : callerFrame.getFileName();
|
|
96
|
+
if (!fileName) {
|
|
97
|
+
throw new Error("Could not determine caller file location for agent-relative path");
|
|
98
|
+
}
|
|
99
|
+
return fileName;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Resolve file path based on prefix:
|
|
103
|
+
* - ./ or ../ = agent-relative (using caller's location)
|
|
104
|
+
* - otherwise = project root-relative
|
|
105
|
+
*/
|
|
106
|
+
function resolveFilePath(filePath) {
|
|
107
|
+
if (filePath.startsWith("./") || filePath.startsWith("../")) {
|
|
108
|
+
// Agent-relative: get caller's file location via stack trace
|
|
109
|
+
var callerFile = getCallerFilePath();
|
|
110
|
+
return path.resolve(path.dirname(callerFile), filePath);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// Project root-relative
|
|
114
|
+
return path.join(process.cwd(), filePath);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Load file contents with smart caching
|
|
119
|
+
* Cache is invalidated when file modification time changes
|
|
120
|
+
*/
|
|
121
|
+
function loadFile(resolvedPath, originalPath) {
|
|
122
|
+
try {
|
|
123
|
+
var stats = fs.statSync(resolvedPath);
|
|
124
|
+
var mtime = stats.mtimeMs;
|
|
125
|
+
// Check cache
|
|
126
|
+
var cached = fileCache.get(resolvedPath);
|
|
127
|
+
if (cached && cached.mtime === mtime) {
|
|
128
|
+
return cached.content;
|
|
129
|
+
}
|
|
130
|
+
// Read file and update cache
|
|
131
|
+
var content = fs.readFileSync(resolvedPath, "utf-8");
|
|
132
|
+
fileCache.set(resolvedPath, { content: content, mtime: mtime });
|
|
133
|
+
return content;
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err.code === "ENOENT") {
|
|
137
|
+
throw new Error("Agent instructions file not found: ".concat(resolvedPath, " (from: ").concat(originalPath, ")"));
|
|
138
|
+
}
|
|
139
|
+
throw new Error("Failed to load agent instructions file: ".concat(resolvedPath, " - ").concat(err.message));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Render template using Handlebars
|
|
144
|
+
*/
|
|
145
|
+
function renderTemplate(content, data, filePath) {
|
|
146
|
+
try {
|
|
147
|
+
var template = handlebars_1.default.compile(content);
|
|
148
|
+
return template(data);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
throw new Error("Failed to render template in ".concat(filePath, ": ").concat(err.message));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Load agent instructions from external files with template variable support
|
|
156
|
+
*
|
|
157
|
+
* Supports multiple file types: .md, .yaml, .txt, etc. (loaded as plain text)
|
|
158
|
+
*
|
|
159
|
+
* ## Path Resolution
|
|
160
|
+
*
|
|
161
|
+
* - `./` or `../` prefix: Agent-relative path (based on caller's file location)
|
|
162
|
+
* - Otherwise: Project root-relative path
|
|
163
|
+
*
|
|
164
|
+
* ## Template Variables
|
|
165
|
+
*
|
|
166
|
+
* Uses Handlebars templating with automatic context helpers:
|
|
167
|
+
* - `ctx`: Full FlinkContext
|
|
168
|
+
* - `agentContext`: AgentExecuteContext
|
|
169
|
+
* - `user`: Shortcut to agentContext.user
|
|
170
|
+
* - Custom variables from static object or callback
|
|
171
|
+
*
|
|
172
|
+
* ## Caching
|
|
173
|
+
*
|
|
174
|
+
* Files are cached in-memory and reloaded only when modification time changes
|
|
175
|
+
*
|
|
176
|
+
* @example Agent-relative path with static variables
|
|
177
|
+
* ```typescript
|
|
178
|
+
* export default class CarAgent extends FlinkAgent<AppCtx> {
|
|
179
|
+
* id = "car-agent";
|
|
180
|
+
* instructions = agentInstructions("./instructions/car-agent.md");
|
|
181
|
+
* tools = [SearchCarsTool];
|
|
182
|
+
* }
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
185
|
+
* @example Dynamic variables with callback
|
|
186
|
+
* ```typescript
|
|
187
|
+
* export default class SupportAgent extends FlinkAgent<AppCtx> {
|
|
188
|
+
* id = "support-agent";
|
|
189
|
+
* instructions = agentInstructions(
|
|
190
|
+
* "./instructions/support-agent.md",
|
|
191
|
+
* (ctx, agentContext) => ({
|
|
192
|
+
* isBusinessHours: new Date().getHours() >= 9 && new Date().getHours() < 17,
|
|
193
|
+
* customerTier: agentContext.user?.tier || "standard",
|
|
194
|
+
* })
|
|
195
|
+
* );
|
|
196
|
+
* tools = [CreateTicketTool];
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @example Template file (instructions/support-agent.md)
|
|
201
|
+
* ```markdown
|
|
202
|
+
* You are a customer support agent.
|
|
203
|
+
*
|
|
204
|
+
* Customer: {{user.name}} ({{customerTier}})
|
|
205
|
+
* {{#if user.isPremium}}
|
|
206
|
+
* ⭐ VIP CUSTOMER - Provide white-glove service!
|
|
207
|
+
* {{/if}}
|
|
208
|
+
*
|
|
209
|
+
* {{#unless isBusinessHours}}
|
|
210
|
+
* NOTE: Outside business hours. Suggest emergency contact.
|
|
211
|
+
* {{/unless}}
|
|
212
|
+
* ```
|
|
213
|
+
*
|
|
214
|
+
* @param filePath - Path to instructions file (./ for agent-relative, otherwise project root)
|
|
215
|
+
* @param variables - Static object or callback returning template variables
|
|
216
|
+
* @returns InstructionsCallback compatible with FlinkAgent.instructions property
|
|
217
|
+
*/
|
|
218
|
+
function agentInstructions(filePath, variables) {
|
|
219
|
+
var _this = this;
|
|
220
|
+
// Resolve path once at definition time for early validation
|
|
221
|
+
var resolvedPath = resolveFilePath(filePath);
|
|
222
|
+
// Return callback that will be invoked by FlinkAgent
|
|
223
|
+
return function (ctx, agentContext) { return __awaiter(_this, void 0, void 0, function () {
|
|
224
|
+
var content, vars, templateData;
|
|
225
|
+
return __generator(this, function (_a) {
|
|
226
|
+
switch (_a.label) {
|
|
227
|
+
case 0:
|
|
228
|
+
content = loadFile(resolvedPath, filePath);
|
|
229
|
+
vars = {};
|
|
230
|
+
if (!variables) return [3 /*break*/, 3];
|
|
231
|
+
if (!(typeof variables === "function")) return [3 /*break*/, 2];
|
|
232
|
+
return [4 /*yield*/, Promise.resolve(variables(ctx, agentContext))];
|
|
233
|
+
case 1:
|
|
234
|
+
vars = _a.sent();
|
|
235
|
+
return [3 /*break*/, 3];
|
|
236
|
+
case 2:
|
|
237
|
+
vars = variables;
|
|
238
|
+
_a.label = 3;
|
|
239
|
+
case 3:
|
|
240
|
+
templateData = __assign(__assign({}, vars), { ctx: ctx, agentContext: agentContext, user: agentContext.user });
|
|
241
|
+
// Render template
|
|
242
|
+
return [2 /*return*/, renderTemplate(content, templateData, resolvedPath)];
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}); };
|
|
246
|
+
}
|