@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,1000 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
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);
|
|
24
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
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;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
|
+
};
|
|
52
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
exports.FlinkApp = exports.autoRegisteredAgents = exports.autoRegisteredTools = exports.autoRegisteredJobs = exports.autoRegisteredRepos = exports.autoRegisteredHandlers = exports.expressFn = void 0;
|
|
54
|
+
var ajv_1 = __importDefault(require("ajv"));
|
|
55
|
+
var ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
56
|
+
var body_parser_1 = __importDefault(require("body-parser"));
|
|
57
|
+
var cors_1 = __importDefault(require("cors"));
|
|
58
|
+
var express_1 = __importDefault(require("express"));
|
|
59
|
+
var mongodb_1 = require("mongodb");
|
|
60
|
+
var morgan_1 = __importDefault(require("morgan"));
|
|
61
|
+
var ms_1 = __importDefault(require("ms"));
|
|
62
|
+
var toad_scheduler_1 = require("toad-scheduler");
|
|
63
|
+
var uuid_1 = require("uuid");
|
|
64
|
+
var FlinkErrors_1 = require("./FlinkErrors");
|
|
65
|
+
var FlinkHttpHandler_1 = require("./FlinkHttpHandler");
|
|
66
|
+
var FlinkLog_1 = require("./FlinkLog");
|
|
67
|
+
var FlinkLogFactory_1 = require("./FlinkLogFactory");
|
|
68
|
+
var FlinkRequestContext_1 = require("./FlinkRequestContext");
|
|
69
|
+
var StreamWriterFactory_1 = require("./handlers/StreamWriterFactory");
|
|
70
|
+
var mock_data_generator_1 = __importDefault(require("./mock-data-generator"));
|
|
71
|
+
var utils_1 = require("./utils");
|
|
72
|
+
var ajv = new ajv_1.default();
|
|
73
|
+
(0, ajv_formats_1.default)(ajv);
|
|
74
|
+
var defaultCorsOptions = {
|
|
75
|
+
allowedHeaders: "",
|
|
76
|
+
credentials: true,
|
|
77
|
+
origin: [/.*/],
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Re-export express factory function so sub packages
|
|
81
|
+
* do not need its own express
|
|
82
|
+
*/
|
|
83
|
+
exports.expressFn = express_1.default;
|
|
84
|
+
/**
|
|
85
|
+
* This will be populated at compile time when the apps handlers
|
|
86
|
+
* are picked up by TypeScript compiler
|
|
87
|
+
*/
|
|
88
|
+
exports.autoRegisteredHandlers = [];
|
|
89
|
+
/**
|
|
90
|
+
* This will be populated at compile time when the apps repos
|
|
91
|
+
* are picked up by TypeScript compiler
|
|
92
|
+
*/
|
|
93
|
+
exports.autoRegisteredRepos = [];
|
|
94
|
+
/**
|
|
95
|
+
* This will be populated at compile time when the apps jobs
|
|
96
|
+
* are picked up by TypeScript compiler
|
|
97
|
+
*/
|
|
98
|
+
exports.autoRegisteredJobs = [];
|
|
99
|
+
/**
|
|
100
|
+
* This will be populated at compile time when the apps tools
|
|
101
|
+
* are picked up by TypeScript compiler
|
|
102
|
+
*/
|
|
103
|
+
exports.autoRegisteredTools = [];
|
|
104
|
+
/**
|
|
105
|
+
* This will be populated at compile time when the apps agents
|
|
106
|
+
* are picked up by TypeScript compiler
|
|
107
|
+
*/
|
|
108
|
+
exports.autoRegisteredAgents = [];
|
|
109
|
+
var FlinkApp = /** @class */ (function () {
|
|
110
|
+
function FlinkApp(opts) {
|
|
111
|
+
var _a;
|
|
112
|
+
this.handlers = [];
|
|
113
|
+
this.started = false;
|
|
114
|
+
this.debug = false;
|
|
115
|
+
this.plugins = [];
|
|
116
|
+
this.routingConfigured = false;
|
|
117
|
+
this.disableHttpServer = false;
|
|
118
|
+
this.repos = {};
|
|
119
|
+
this.llmAdapters = new Map();
|
|
120
|
+
this.tools = {};
|
|
121
|
+
this.agents = {}; // FlinkAgent<C> instances
|
|
122
|
+
/**
|
|
123
|
+
* Internal cache used to track registered handlers and potentially any overlapping routes
|
|
124
|
+
*/
|
|
125
|
+
this.handlerRouteCache = new Map();
|
|
126
|
+
// Performance logger for tracking application startup and operations
|
|
127
|
+
this.perfLog = FlinkLogFactory_1.FlinkLogFactory.createLogger("flink.perf");
|
|
128
|
+
// Initialize logging from environment variables (LOG_LEVEL, DEBUG, LOG_LEVELS, etc.)
|
|
129
|
+
FlinkLogFactory_1.FlinkLogFactory.configure();
|
|
130
|
+
this.name = opts.name;
|
|
131
|
+
this.port = opts.port || 3333;
|
|
132
|
+
this.dbOpts = opts.db;
|
|
133
|
+
this.debug = !!opts.debug;
|
|
134
|
+
this.onDbConnection = opts.onDbConnection;
|
|
135
|
+
this.plugins = opts.plugins || [];
|
|
136
|
+
this.corsOpts = __assign(__assign({}, defaultCorsOptions), opts.cors);
|
|
137
|
+
this.rawContentTypes = Array.isArray(opts.rawContentTypes)
|
|
138
|
+
? opts.rawContentTypes
|
|
139
|
+
: typeof opts.rawContentTypes === "string"
|
|
140
|
+
? [opts.rawContentTypes]
|
|
141
|
+
: undefined;
|
|
142
|
+
this.auth = opts.auth;
|
|
143
|
+
this.jsonOptions = opts.jsonOptions || { limit: "1mb" };
|
|
144
|
+
this.schedulingOptions = opts.scheduling;
|
|
145
|
+
this.disableHttpServer = !!opts.disableHttpServer;
|
|
146
|
+
this.accessLog = __assign({ enabled: true, format: "dev" }, opts.accessLog);
|
|
147
|
+
this.onError = opts.onError;
|
|
148
|
+
// Register LLM adapters if configured
|
|
149
|
+
if ((_a = opts.ai) === null || _a === void 0 ? void 0 : _a.llms) {
|
|
150
|
+
// Convert plain object to Map for internal use
|
|
151
|
+
this.llmAdapters = new Map(Object.entries(opts.ai.llms));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
Object.defineProperty(FlinkApp.prototype, "ctx", {
|
|
155
|
+
get: function () {
|
|
156
|
+
if (!this._ctx) {
|
|
157
|
+
throw new Error("Context is not yet initialized");
|
|
158
|
+
}
|
|
159
|
+
return this._ctx;
|
|
160
|
+
},
|
|
161
|
+
enumerable: false,
|
|
162
|
+
configurable: true
|
|
163
|
+
});
|
|
164
|
+
FlinkApp.prototype.start = function () {
|
|
165
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
166
|
+
var startTime, offsetTime, dbStartTime, contextStartTime, toolsStartTime, agentsStartTime, agentInitStartTime, _i, _a, type, pluginsStartTime, _b, _c, plugin, db, handlersStartTime, jobsStartTime, totalStartTime;
|
|
167
|
+
var _this = this;
|
|
168
|
+
var _d;
|
|
169
|
+
return __generator(this, function (_e) {
|
|
170
|
+
switch (_e.label) {
|
|
171
|
+
case 0:
|
|
172
|
+
startTime = Date.now();
|
|
173
|
+
offsetTime = startTime;
|
|
174
|
+
dbStartTime = Date.now();
|
|
175
|
+
return [4 /*yield*/, this.initDb()];
|
|
176
|
+
case 1:
|
|
177
|
+
_e.sent();
|
|
178
|
+
this.perfLog.debug("Init db took ".concat(Date.now() - dbStartTime, "ms"));
|
|
179
|
+
contextStartTime = Date.now();
|
|
180
|
+
return [4 /*yield*/, this.buildContext()];
|
|
181
|
+
case 2:
|
|
182
|
+
_e.sent();
|
|
183
|
+
this.perfLog.debug("Build context took ".concat(Date.now() - contextStartTime, "ms"));
|
|
184
|
+
toolsStartTime = Date.now();
|
|
185
|
+
return [4 /*yield*/, this.registerAutoRegisterableTools()];
|
|
186
|
+
case 3:
|
|
187
|
+
_e.sent();
|
|
188
|
+
this.perfLog.debug("Register tools took ".concat(Date.now() - toolsStartTime, "ms"));
|
|
189
|
+
agentsStartTime = Date.now();
|
|
190
|
+
return [4 /*yield*/, this.registerAutoRegisterableAgents()];
|
|
191
|
+
case 4:
|
|
192
|
+
_e.sent();
|
|
193
|
+
this.perfLog.debug("Register agents took ".concat(Date.now() - agentsStartTime, "ms"));
|
|
194
|
+
agentInitStartTime = Date.now();
|
|
195
|
+
return [4 /*yield*/, this.initializeAgents()];
|
|
196
|
+
case 5:
|
|
197
|
+
_e.sent();
|
|
198
|
+
this.perfLog.debug("Initialize agents took ".concat(Date.now() - agentInitStartTime, "ms"));
|
|
199
|
+
if (this.isSchedulingEnabled) {
|
|
200
|
+
this.scheduler = new toad_scheduler_1.ToadScheduler();
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
FlinkLog_1.log.info("🚫 Scheduling is disabled");
|
|
204
|
+
}
|
|
205
|
+
if (!this.disableHttpServer) {
|
|
206
|
+
this.expressApp = (0, express_1.default)();
|
|
207
|
+
this.expressApp.use((0, cors_1.default)(this.corsOpts));
|
|
208
|
+
if (this.rawContentTypes) {
|
|
209
|
+
for (_i = 0, _a = this.rawContentTypes; _i < _a.length; _i++) {
|
|
210
|
+
type = _a[_i];
|
|
211
|
+
this.expressApp.use(express_1.default.raw({ type: type }));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
this.expressApp.use(body_parser_1.default.json(this.jsonOptions));
|
|
215
|
+
if (this.accessLog.enabled) {
|
|
216
|
+
this.expressApp.use((0, morgan_1.default)(this.accessLog.format));
|
|
217
|
+
}
|
|
218
|
+
this.expressApp.use(function (req, res, next) {
|
|
219
|
+
req.reqId = (0, uuid_1.v4)();
|
|
220
|
+
next();
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
pluginsStartTime = Date.now();
|
|
224
|
+
_b = 0, _c = this.plugins;
|
|
225
|
+
_e.label = 6;
|
|
226
|
+
case 6:
|
|
227
|
+
if (!(_b < _c.length)) return [3 /*break*/, 12];
|
|
228
|
+
plugin = _c[_b];
|
|
229
|
+
db = void 0;
|
|
230
|
+
if (!plugin.db) return [3 /*break*/, 8];
|
|
231
|
+
return [4 /*yield*/, this.initPluginDb(plugin)];
|
|
232
|
+
case 7:
|
|
233
|
+
db = _e.sent();
|
|
234
|
+
_e.label = 8;
|
|
235
|
+
case 8:
|
|
236
|
+
if (!plugin.init) return [3 /*break*/, 10];
|
|
237
|
+
return [4 /*yield*/, plugin.init(this, db)];
|
|
238
|
+
case 9:
|
|
239
|
+
_e.sent();
|
|
240
|
+
_e.label = 10;
|
|
241
|
+
case 10:
|
|
242
|
+
FlinkLog_1.log.info("Initialized plugin '".concat(plugin.id, "'"));
|
|
243
|
+
_e.label = 11;
|
|
244
|
+
case 11:
|
|
245
|
+
_b++;
|
|
246
|
+
return [3 /*break*/, 6];
|
|
247
|
+
case 12:
|
|
248
|
+
if (this.plugins.length > 0) {
|
|
249
|
+
this.perfLog.debug("Initialize plugins took ".concat(Date.now() - pluginsStartTime, "ms (").concat(this.plugins.length, " plugins)"));
|
|
250
|
+
}
|
|
251
|
+
handlersStartTime = Date.now();
|
|
252
|
+
return [4 /*yield*/, this.registerAutoRegisterableHandlers()];
|
|
253
|
+
case 13:
|
|
254
|
+
_e.sent();
|
|
255
|
+
this.perfLog.debug("Register handlers took ".concat(Date.now() - handlersStartTime, "ms"));
|
|
256
|
+
if (!this.isSchedulingEnabled) return [3 /*break*/, 15];
|
|
257
|
+
jobsStartTime = Date.now();
|
|
258
|
+
return [4 /*yield*/, this.registerAutoRegisterableJobs()];
|
|
259
|
+
case 14:
|
|
260
|
+
_e.sent();
|
|
261
|
+
this.perfLog.debug("Register jobs took ".concat(Date.now() - jobsStartTime, "ms"));
|
|
262
|
+
_e.label = 15;
|
|
263
|
+
case 15:
|
|
264
|
+
// Register 404 with slight delay to allow all manually added routes to be added
|
|
265
|
+
// TODO: Is there a better solution to force this handler to always run last?
|
|
266
|
+
setTimeout(function () {
|
|
267
|
+
if (!_this.disableHttpServer) {
|
|
268
|
+
_this.expressApp.use(function (req, res, next) {
|
|
269
|
+
res.status(404).json((0, FlinkErrors_1.notFound)());
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
_this.routingConfigured = true;
|
|
273
|
+
});
|
|
274
|
+
if (this.disableHttpServer) {
|
|
275
|
+
FlinkLog_1.log.info("🚧 HTTP server is disabled, but flink app is running");
|
|
276
|
+
this.started = true;
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
this.expressServer = (_d = this.expressApp) === null || _d === void 0 ? void 0 : _d.listen(this.port, function () {
|
|
280
|
+
FlinkLog_1.log.fontColorLog("magenta", "\u26A1\uFE0F HTTP server '".concat(_this.name, "' is running and waiting for connections on ").concat(_this.port));
|
|
281
|
+
_this.started = true;
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
totalStartTime = Date.now() - startTime;
|
|
285
|
+
this.perfLog.info("\u2713 FlinkApp started in ".concat(totalStartTime, "ms"));
|
|
286
|
+
return [2 /*return*/, this];
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
FlinkApp.prototype.stop = function () {
|
|
292
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
293
|
+
var _this = this;
|
|
294
|
+
return __generator(this, function (_a) {
|
|
295
|
+
switch (_a.label) {
|
|
296
|
+
case 0:
|
|
297
|
+
FlinkLog_1.log.info("🛑 Stopping Flink app...");
|
|
298
|
+
if (!this.scheduler) return [3 /*break*/, 2];
|
|
299
|
+
return [4 /*yield*/, this.scheduler.stop()];
|
|
300
|
+
case 1:
|
|
301
|
+
_a.sent();
|
|
302
|
+
_a.label = 2;
|
|
303
|
+
case 2:
|
|
304
|
+
if (this.expressServer) {
|
|
305
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
306
|
+
var int = setTimeout(function () {
|
|
307
|
+
reject("Failed to stop HTTP server in time");
|
|
308
|
+
}, 2000);
|
|
309
|
+
_this.expressServer.close(function () {
|
|
310
|
+
clearInterval(int);
|
|
311
|
+
FlinkLog_1.log.info("HTTP server stopped");
|
|
312
|
+
resolve();
|
|
313
|
+
});
|
|
314
|
+
})];
|
|
315
|
+
}
|
|
316
|
+
return [2 /*return*/];
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Manually registers a handler.
|
|
323
|
+
*
|
|
324
|
+
* Typescript compiler will scan handler function and set schemas
|
|
325
|
+
* which are derived from handler function type arguments.
|
|
326
|
+
*/
|
|
327
|
+
FlinkApp.prototype.addHandler = function (handler, routePropsOverride) {
|
|
328
|
+
var _a, _b, _c, _d, _e, _f;
|
|
329
|
+
if (this.routingConfigured) {
|
|
330
|
+
throw new Error("Cannot add handler after routes has been registered, make sure to invoke earlier");
|
|
331
|
+
}
|
|
332
|
+
var routeProps = __assign(__assign({}, (handler.Route || {})), routePropsOverride);
|
|
333
|
+
if (!routeProps.method) {
|
|
334
|
+
FlinkLog_1.log.error("Failed to register handler '".concat(handler.__file, "': Missing 'method' in route props, either set it or name handler file with HTTP method as prefix"));
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (!routeProps.path) {
|
|
338
|
+
FlinkLog_1.log.error("Failed to register handler '".concat(handler.__file, "': Missing 'path' in route props"));
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
var dup = this.handlers.find(function (h) { return h.routeProps.path === routeProps.path && h.routeProps.method === routeProps.method; });
|
|
342
|
+
var methodAndPath = "".concat(routeProps.method.toUpperCase(), " ").concat(routeProps.path);
|
|
343
|
+
if (dup) {
|
|
344
|
+
// TODO: Not sure if there is a case where you'd want to overwrite a route?
|
|
345
|
+
FlinkLog_1.log.warn("".concat(methodAndPath, " overlaps existing route"));
|
|
346
|
+
}
|
|
347
|
+
var handlerConfig = {
|
|
348
|
+
routeProps: __assign(__assign({}, routeProps), { method: routeProps.method, path: routeProps.path }),
|
|
349
|
+
schema: {
|
|
350
|
+
reqSchema: (_a = handler.__schemas) === null || _a === void 0 ? void 0 : _a.reqSchema,
|
|
351
|
+
resSchema: (_b = handler.__schemas) === null || _b === void 0 ? void 0 : _b.resSchema,
|
|
352
|
+
},
|
|
353
|
+
queryMetadata: handler.__query || [],
|
|
354
|
+
paramsMetadata: handler.__params || [],
|
|
355
|
+
};
|
|
356
|
+
if (((_c = handler.__schemas) === null || _c === void 0 ? void 0 : _c.reqSchema) && !((_d = handlerConfig.schema) === null || _d === void 0 ? void 0 : _d.reqSchema)) {
|
|
357
|
+
FlinkLog_1.log.warn("Expected request schema ".concat(handler.__schemas.reqSchema, " for handler ").concat(methodAndPath, " but no such schema was found"));
|
|
358
|
+
}
|
|
359
|
+
if (((_e = handler.__schemas) === null || _e === void 0 ? void 0 : _e.resSchema) && !((_f = handlerConfig.schema) === null || _f === void 0 ? void 0 : _f.resSchema)) {
|
|
360
|
+
FlinkLog_1.log.warn("Expected response schema ".concat(handler.__schemas.resSchema, " for handler ").concat(methodAndPath, " but no such schema was found"));
|
|
361
|
+
}
|
|
362
|
+
this.registerHandler(handlerConfig, handler.default);
|
|
363
|
+
};
|
|
364
|
+
FlinkApp.prototype.registerHandler = function (handlerConfig, handler) {
|
|
365
|
+
var _this = this;
|
|
366
|
+
this.handlers.push(handlerConfig);
|
|
367
|
+
var routeProps = handlerConfig.routeProps, _a = handlerConfig.schema, schema = _a === void 0 ? {} : _a;
|
|
368
|
+
var method = routeProps.method, streamFormat = routeProps.streamFormat;
|
|
369
|
+
if (!method) {
|
|
370
|
+
FlinkLog_1.log.error("Route ".concat(routeProps.path, " is missing http method"));
|
|
371
|
+
}
|
|
372
|
+
if (method) {
|
|
373
|
+
var methodAndRoute_1 = "".concat(method.toUpperCase(), " ").concat(routeProps.path);
|
|
374
|
+
if (this.disableHttpServer) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
var validateReq_1;
|
|
378
|
+
var validateRes_1;
|
|
379
|
+
// Determine validation mode (default to Validate if not specified)
|
|
380
|
+
var validationMode = routeProps.validation || FlinkHttpHandler_1.ValidationMode.Validate;
|
|
381
|
+
// Compile request schema if validation mode requires it
|
|
382
|
+
if (schema.reqSchema && validationMode !== FlinkHttpHandler_1.ValidationMode.SkipValidation && validationMode !== FlinkHttpHandler_1.ValidationMode.ValidateResponse) {
|
|
383
|
+
validateReq_1 = ajv.compile(schema.reqSchema);
|
|
384
|
+
}
|
|
385
|
+
// Skip response validation for streaming handlers (responses are stream chunks, not final JSON)
|
|
386
|
+
// Skip response validation for non-JSON response types (html, csv, etc.)
|
|
387
|
+
if (!streamFormat &&
|
|
388
|
+
!routeProps.responseType &&
|
|
389
|
+
schema.resSchema &&
|
|
390
|
+
validationMode !== FlinkHttpHandler_1.ValidationMode.SkipValidation &&
|
|
391
|
+
validationMode !== FlinkHttpHandler_1.ValidationMode.ValidateRequest) {
|
|
392
|
+
validateRes_1 = ajv.compile(schema.resSchema);
|
|
393
|
+
}
|
|
394
|
+
this.expressApp[method](routeProps.path, function (req, res) { return __awaiter(_this, void 0, void 0, function () {
|
|
395
|
+
var valid, formattedErrors, data, normalizedQuery, _i, _a, _b, key, value, stream, handlerRes, flinkReq_1, err_1, errorResponse, result, valid, formattedErrors;
|
|
396
|
+
var _this = this;
|
|
397
|
+
return __generator(this, function (_c) {
|
|
398
|
+
switch (_c.label) {
|
|
399
|
+
case 0:
|
|
400
|
+
if (!routeProps.permissions) return [3 /*break*/, 2];
|
|
401
|
+
return [4 /*yield*/, this.authenticate(req, routeProps.permissions)];
|
|
402
|
+
case 1:
|
|
403
|
+
if (!(_c.sent())) {
|
|
404
|
+
return [2 /*return*/, res.status(401).json((0, FlinkErrors_1.unauthorized)())];
|
|
405
|
+
}
|
|
406
|
+
_c.label = 2;
|
|
407
|
+
case 2:
|
|
408
|
+
if (validateReq_1) {
|
|
409
|
+
valid = validateReq_1(req.body);
|
|
410
|
+
if (!valid) {
|
|
411
|
+
formattedErrors = (0, utils_1.formatValidationErrors)(validateReq_1.errors, req.body);
|
|
412
|
+
FlinkLog_1.log.warn("[".concat(req.reqId, "] ").concat(methodAndRoute_1, ": Bad request\n").concat(formattedErrors));
|
|
413
|
+
return [2 /*return*/, res.status(400).json({
|
|
414
|
+
status: 400,
|
|
415
|
+
error: {
|
|
416
|
+
id: (0, uuid_1.v4)(),
|
|
417
|
+
title: "Bad request",
|
|
418
|
+
detail: formattedErrors,
|
|
419
|
+
},
|
|
420
|
+
})];
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
// Skip mock API for streaming handlers
|
|
424
|
+
if (routeProps.mockApi && schema.resSchema && !streamFormat) {
|
|
425
|
+
FlinkLog_1.log.warn("Mock response for ".concat(req.method.toUpperCase(), " ").concat(req.path));
|
|
426
|
+
data = (0, mock_data_generator_1.default)(schema.resSchema);
|
|
427
|
+
res.status(200).json({
|
|
428
|
+
status: 200,
|
|
429
|
+
data: data,
|
|
430
|
+
});
|
|
431
|
+
return [2 /*return*/];
|
|
432
|
+
}
|
|
433
|
+
// Normalize query parameters to predictable string or string[] types
|
|
434
|
+
// Express query parser can produce numbers, booleans, objects, etc.
|
|
435
|
+
// We normalize everything to strings or string arrays for consistency
|
|
436
|
+
if (req.query && typeof req.query === "object") {
|
|
437
|
+
normalizedQuery = {};
|
|
438
|
+
for (_i = 0, _a = Object.entries(req.query); _i < _a.length; _i++) {
|
|
439
|
+
_b = _a[_i], key = _b[0], value = _b[1];
|
|
440
|
+
if (Array.isArray(value)) {
|
|
441
|
+
// Handle array values (e.g., ?tag=a&tag=b)
|
|
442
|
+
normalizedQuery[key] = value.map(function (v) { return String(v); });
|
|
443
|
+
}
|
|
444
|
+
else if (value !== undefined && value !== null) {
|
|
445
|
+
// Convert single values to strings
|
|
446
|
+
normalizedQuery[key] = String(value);
|
|
447
|
+
}
|
|
448
|
+
// Skip undefined/null values - they won't appear in the normalized query
|
|
449
|
+
}
|
|
450
|
+
req.query = normalizedQuery;
|
|
451
|
+
}
|
|
452
|
+
stream = streamFormat ? StreamWriterFactory_1.StreamWriterFactory.create(res, streamFormat) : undefined;
|
|
453
|
+
_c.label = 3;
|
|
454
|
+
case 3:
|
|
455
|
+
_c.trys.push([3, 5, , 6]);
|
|
456
|
+
flinkReq_1 = req;
|
|
457
|
+
return [4 /*yield*/, FlinkRequestContext_1.requestContext.run({
|
|
458
|
+
reqId: flinkReq_1.reqId,
|
|
459
|
+
user: flinkReq_1.user,
|
|
460
|
+
userPermissions: flinkReq_1.userPermissions,
|
|
461
|
+
method: method,
|
|
462
|
+
path: routeProps.path,
|
|
463
|
+
timestamp: Date.now(),
|
|
464
|
+
isStreaming: !!streamFormat,
|
|
465
|
+
}, function () { return __awaiter(_this, void 0, void 0, function () {
|
|
466
|
+
return __generator(this, function (_a) {
|
|
467
|
+
switch (_a.label) {
|
|
468
|
+
case 0: return [4 /*yield*/, handler({
|
|
469
|
+
req: flinkReq_1,
|
|
470
|
+
ctx: this.ctx,
|
|
471
|
+
origin: routeProps.origin,
|
|
472
|
+
stream: stream,
|
|
473
|
+
})];
|
|
474
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
}); })];
|
|
478
|
+
case 4:
|
|
479
|
+
handlerRes = _c.sent();
|
|
480
|
+
return [3 /*break*/, 6];
|
|
481
|
+
case 5:
|
|
482
|
+
err_1 = _c.sent();
|
|
483
|
+
// Handle errors for streaming handlers
|
|
484
|
+
if (streamFormat && stream) {
|
|
485
|
+
FlinkLog_1.log.error("Streaming handler error on ".concat(req.method.toUpperCase(), " ").concat(req.path, ": ").concat(err_1.message), {
|
|
486
|
+
error: err_1,
|
|
487
|
+
path: req.path,
|
|
488
|
+
method: req.method,
|
|
489
|
+
});
|
|
490
|
+
stream.error(err_1);
|
|
491
|
+
return [2 /*return*/];
|
|
492
|
+
}
|
|
493
|
+
errorResponse = void 0;
|
|
494
|
+
// duck typing to check if it is a FlinkError
|
|
495
|
+
if (typeof err_1.status === "number" && err_1.status >= 400 && err_1.status < 600 && err_1.error) {
|
|
496
|
+
errorResponse = {
|
|
497
|
+
status: err_1.status,
|
|
498
|
+
error: {
|
|
499
|
+
id: err_1.error.id || (0, uuid_1.v4)(),
|
|
500
|
+
title: err_1.error.title || "Unhandled error: ".concat(err_1.error.code || err_1.status),
|
|
501
|
+
detail: err_1.error.detail,
|
|
502
|
+
code: err_1.error.code,
|
|
503
|
+
},
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
FlinkLog_1.log.warn("Handler '".concat(methodAndRoute_1, "' threw unhandled exception ").concat(err_1));
|
|
508
|
+
console.error(err_1);
|
|
509
|
+
errorResponse = (0, FlinkErrors_1.internalServerError)(err_1);
|
|
510
|
+
}
|
|
511
|
+
// Invoke onError callback if provided
|
|
512
|
+
if (this.onError) {
|
|
513
|
+
try {
|
|
514
|
+
result = this.onError(errorResponse, {
|
|
515
|
+
req: req,
|
|
516
|
+
method: method,
|
|
517
|
+
path: routeProps.path,
|
|
518
|
+
reqId: req.reqId,
|
|
519
|
+
});
|
|
520
|
+
// Handle async callbacks - don't wait for them
|
|
521
|
+
if (result instanceof Promise) {
|
|
522
|
+
result.catch(function (callbackErr) {
|
|
523
|
+
FlinkLog_1.log.error("onError callback rejected with: ".concat(callbackErr));
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
catch (callbackErr) {
|
|
528
|
+
FlinkLog_1.log.error("onError callback threw an exception: ".concat(callbackErr));
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return [2 /*return*/, res.status(errorResponse.status || 500).json(errorResponse)];
|
|
532
|
+
case 6:
|
|
533
|
+
// Skip response handling for streaming handlers (stream controls response lifecycle)
|
|
534
|
+
if (streamFormat) {
|
|
535
|
+
return [2 /*return*/];
|
|
536
|
+
}
|
|
537
|
+
// Ensure handlerRes is defined for non-streaming handlers
|
|
538
|
+
if (!handlerRes) {
|
|
539
|
+
return [2 /*return*/, res.status(204).send()];
|
|
540
|
+
}
|
|
541
|
+
if (validateRes_1 && !(0, utils_1.isError)(handlerRes)) {
|
|
542
|
+
valid = validateRes_1(JSON.parse(JSON.stringify(handlerRes.data)));
|
|
543
|
+
if (!valid) {
|
|
544
|
+
formattedErrors = (0, utils_1.formatValidationErrors)(validateRes_1.errors, handlerRes.data);
|
|
545
|
+
FlinkLog_1.log.warn("[".concat(req.reqId, "] ").concat(methodAndRoute_1, ": Bad response\n").concat(formattedErrors));
|
|
546
|
+
return [2 /*return*/, res.status(500).json({
|
|
547
|
+
status: 500,
|
|
548
|
+
error: {
|
|
549
|
+
id: (0, uuid_1.v4)(),
|
|
550
|
+
title: "Bad response",
|
|
551
|
+
detail: formattedErrors,
|
|
552
|
+
},
|
|
553
|
+
})];
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
res.set(handlerRes.headers);
|
|
557
|
+
if (routeProps.responseType) {
|
|
558
|
+
return [2 /*return*/, res
|
|
559
|
+
.status(handlerRes.status || 200)
|
|
560
|
+
.type(routeProps.responseType)
|
|
561
|
+
.send(handlerRes.data)];
|
|
562
|
+
}
|
|
563
|
+
res.status(handlerRes.status || 200).json(handlerRes);
|
|
564
|
+
return [2 /*return*/];
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
}); });
|
|
568
|
+
if (this.handlerRouteCache.has(methodAndRoute_1)) {
|
|
569
|
+
FlinkLog_1.log.error("Cannot register handler ".concat(methodAndRoute_1, " - route already registered"));
|
|
570
|
+
return process.exit(1); // TODO: Do we need to exit?
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
this.handlerRouteCache.set(methodAndRoute_1, JSON.stringify(routeProps));
|
|
574
|
+
FlinkLog_1.log.info("Registered ".concat(streamFormat ? "streaming " : "", "route ").concat(methodAndRoute_1).concat(streamFormat ? " (".concat(streamFormat, ")") : ""));
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
/**
|
|
579
|
+
* Register handlers found within the `/src/handlers`
|
|
580
|
+
* directory in Flink App.
|
|
581
|
+
*
|
|
582
|
+
* Will not register any handlers added programmatically.
|
|
583
|
+
*/
|
|
584
|
+
FlinkApp.prototype.registerAutoRegisterableHandlers = function () {
|
|
585
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
586
|
+
var _i, _a, _b, handler, assumedHttpMethod, pathParams, _c, _d, param;
|
|
587
|
+
var _e, _f, _g;
|
|
588
|
+
return __generator(this, function (_h) {
|
|
589
|
+
for (_i = 0, _a = exports.autoRegisteredHandlers.sort(function (a, b) { var _a, _b; return (((_a = a.handler.Route) === null || _a === void 0 ? void 0 : _a.order) || 0) - (((_b = b.handler.Route) === null || _b === void 0 ? void 0 : _b.order) || 0); }); _i < _a.length; _i++) {
|
|
590
|
+
_b = _a[_i], handler = _b.handler, assumedHttpMethod = _b.assumedHttpMethod;
|
|
591
|
+
if (!handler.Route) {
|
|
592
|
+
FlinkLog_1.log.error("Missing Props in handler ".concat(handler.__file));
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
if (!handler.default) {
|
|
596
|
+
FlinkLog_1.log.error("Missing exported handler function in handler ".concat(handler.__file));
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
if (!!((_e = handler.__params) === null || _e === void 0 ? void 0 : _e.length)) {
|
|
600
|
+
pathParams = (0, utils_1.getPathParams)(handler.Route.path);
|
|
601
|
+
for (_c = 0, _d = handler.__params; _c < _d.length; _c++) {
|
|
602
|
+
param = _d[_c];
|
|
603
|
+
if (!pathParams.includes(param.name)) {
|
|
604
|
+
FlinkLog_1.log.error("Handler ".concat(handler.__file, " has param ").concat(param.name, " but it is not present in the path '").concat(handler.Route.path, "'"));
|
|
605
|
+
throw new Error("Invalid/missing handler path param");
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (pathParams.length !== handler.__params.length) {
|
|
609
|
+
FlinkLog_1.log.warn("Handler ".concat(handler.__file, " has ").concat(handler.__params.length, " typed params but the path '").concat(handler.Route.path, "' has ").concat(pathParams.length, " params"));
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
this.registerHandler({
|
|
613
|
+
routeProps: __assign(__assign({}, handler.Route), { method: handler.Route.method || assumedHttpMethod, origin: this.name }),
|
|
614
|
+
schema: {
|
|
615
|
+
reqSchema: (_f = handler.__schemas) === null || _f === void 0 ? void 0 : _f.reqSchema,
|
|
616
|
+
resSchema: (_g = handler.__schemas) === null || _g === void 0 ? void 0 : _g.resSchema,
|
|
617
|
+
},
|
|
618
|
+
queryMetadata: handler.__query || [],
|
|
619
|
+
paramsMetadata: handler.__params || [],
|
|
620
|
+
}, handler.default);
|
|
621
|
+
}
|
|
622
|
+
return [2 /*return*/];
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
};
|
|
626
|
+
FlinkApp.prototype.registerAutoRegisterableJobs = function () {
|
|
627
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
628
|
+
var _loop_1, this_1, _i, autoRegisteredJobs_1, _a, jobProps, jobFn, __file;
|
|
629
|
+
var _this = this;
|
|
630
|
+
return __generator(this, function (_b) {
|
|
631
|
+
if (!this.scheduler) {
|
|
632
|
+
throw new Error("Scheduler not initialized"); // should never happen
|
|
633
|
+
}
|
|
634
|
+
_loop_1 = function (jobProps, jobFn, __file) {
|
|
635
|
+
if (jobProps.cron && jobProps.interval) {
|
|
636
|
+
FlinkLog_1.log.error("Cannot register job ".concat(jobProps.id, " - both cron and interval are set in ").concat(__file));
|
|
637
|
+
return "continue";
|
|
638
|
+
}
|
|
639
|
+
if (jobProps.cron && jobProps.afterDelay) {
|
|
640
|
+
FlinkLog_1.log.error("Cannot register job ".concat(jobProps.id, " - both cron and afterDelay are set in ").concat(__file));
|
|
641
|
+
return "continue";
|
|
642
|
+
}
|
|
643
|
+
if (jobProps.interval && jobProps.afterDelay) {
|
|
644
|
+
FlinkLog_1.log.error("Cannot register job ".concat(jobProps.id, " - both interval and afterDelay are set in ").concat(__file));
|
|
645
|
+
return "continue";
|
|
646
|
+
}
|
|
647
|
+
if (this_1.scheduler.existsById(jobProps.id)) {
|
|
648
|
+
FlinkLog_1.log.error("Job with id ".concat(jobProps.id, " is already registered, found duplicate in ").concat(__file));
|
|
649
|
+
return "continue";
|
|
650
|
+
}
|
|
651
|
+
FlinkLog_1.log.debug("Registering job ".concat(jobProps.id, ": ").concat(JSON.stringify(jobProps), " from ").concat(__file));
|
|
652
|
+
var task = new toad_scheduler_1.AsyncTask(jobProps.id, function () { return __awaiter(_this, void 0, void 0, function () {
|
|
653
|
+
return __generator(this, function (_a) {
|
|
654
|
+
switch (_a.label) {
|
|
655
|
+
case 0: return [4 /*yield*/, jobFn({ ctx: this.ctx })];
|
|
656
|
+
case 1:
|
|
657
|
+
_a.sent();
|
|
658
|
+
FlinkLog_1.log.debug("Job ".concat(jobProps.id, " completed"));
|
|
659
|
+
if (jobProps.afterDelay) {
|
|
660
|
+
// afterDelay runs only once, so we remove the job
|
|
661
|
+
this.scheduler.removeById(jobProps.id);
|
|
662
|
+
}
|
|
663
|
+
return [2 /*return*/];
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}); }, function (err) {
|
|
667
|
+
FlinkLog_1.log.error("Job ".concat(jobProps.id, " threw unhandled exception ").concat(err));
|
|
668
|
+
console.error(err);
|
|
669
|
+
});
|
|
670
|
+
if (jobProps.cron) {
|
|
671
|
+
var job = new toad_scheduler_1.CronJob({ timezone: jobProps.timezone, cronExpression: jobProps.cron }, task, {
|
|
672
|
+
id: jobProps.id,
|
|
673
|
+
preventOverrun: jobProps.singleton,
|
|
674
|
+
});
|
|
675
|
+
this_1.scheduler.addCronJob(job);
|
|
676
|
+
}
|
|
677
|
+
else if (jobProps.interval) {
|
|
678
|
+
var job = new toad_scheduler_1.SimpleIntervalJob({
|
|
679
|
+
milliseconds: (0, ms_1.default)(jobProps.interval),
|
|
680
|
+
runImmediately: false, // TODO: Expose to props?
|
|
681
|
+
}, task, {
|
|
682
|
+
id: jobProps.id,
|
|
683
|
+
preventOverrun: jobProps.singleton,
|
|
684
|
+
});
|
|
685
|
+
this_1.scheduler.addSimpleIntervalJob(job);
|
|
686
|
+
}
|
|
687
|
+
else if (jobProps.afterDelay !== undefined) {
|
|
688
|
+
var job = new toad_scheduler_1.SimpleIntervalJob({
|
|
689
|
+
milliseconds: (0, ms_1.default)(jobProps.afterDelay),
|
|
690
|
+
runImmediately: false,
|
|
691
|
+
}, task, {
|
|
692
|
+
id: jobProps.id,
|
|
693
|
+
preventOverrun: jobProps.singleton,
|
|
694
|
+
});
|
|
695
|
+
this_1.scheduler.addSimpleIntervalJob(job);
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
FlinkLog_1.log.error("Cannot register job ".concat(jobProps.id, " - no cron, interval or once set in ").concat(__file));
|
|
699
|
+
return "continue";
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
this_1 = this;
|
|
703
|
+
for (_i = 0, autoRegisteredJobs_1 = exports.autoRegisteredJobs; _i < autoRegisteredJobs_1.length; _i++) {
|
|
704
|
+
_a = autoRegisteredJobs_1[_i], jobProps = _a.Job, jobFn = _a.default, __file = _a.__file;
|
|
705
|
+
_loop_1(jobProps, jobFn, __file);
|
|
706
|
+
}
|
|
707
|
+
return [2 /*return*/];
|
|
708
|
+
});
|
|
709
|
+
});
|
|
710
|
+
};
|
|
711
|
+
FlinkApp.prototype.addRepo = function (instanceName, repoInstance) {
|
|
712
|
+
this.repos[instanceName] = repoInstance;
|
|
713
|
+
// TODO: Find out if we need to set ctx here or wanted not to if plugin has its own context
|
|
714
|
+
// repoInstance.ctx = this.ctx;
|
|
715
|
+
};
|
|
716
|
+
FlinkApp.prototype.registerAutoRegisterableTools = function () {
|
|
717
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
718
|
+
var ToolExecutor, getRepoInstanceName, _i, autoRegisteredTools_1, toolFile, toolId, toolInstanceName, toolExecutor;
|
|
719
|
+
return __generator(this, function (_a) {
|
|
720
|
+
ToolExecutor = require("./ai/ToolExecutor").ToolExecutor;
|
|
721
|
+
getRepoInstanceName = require("./utils").getRepoInstanceName;
|
|
722
|
+
for (_i = 0, autoRegisteredTools_1 = exports.autoRegisteredTools; _i < autoRegisteredTools_1.length; _i++) {
|
|
723
|
+
toolFile = autoRegisteredTools_1[_i];
|
|
724
|
+
if (!toolFile.Tool) {
|
|
725
|
+
FlinkLog_1.log.error("Missing FlinkToolProps export in tool ".concat(toolFile.__file));
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
if (!toolFile.default) {
|
|
729
|
+
FlinkLog_1.log.error("Missing exported tool function in tool ".concat(toolFile.__file));
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
toolId = toolFile.Tool.id;
|
|
733
|
+
if (!toolId) {
|
|
734
|
+
FlinkLog_1.log.error("Tool ".concat(toolFile.__file, " missing 'id' property"));
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
toolInstanceName = getRepoInstanceName(toolId);
|
|
738
|
+
toolExecutor = new ToolExecutor(toolFile.Tool, toolFile.default, this.ctx, toolFile.__schemas // Auto-generated schemas from type parameters
|
|
739
|
+
);
|
|
740
|
+
this.tools[toolInstanceName] = toolExecutor;
|
|
741
|
+
FlinkLog_1.log.info("Registered tool ".concat(toolInstanceName, " (").concat(toolId, ")"));
|
|
742
|
+
}
|
|
743
|
+
return [2 /*return*/];
|
|
744
|
+
});
|
|
745
|
+
});
|
|
746
|
+
};
|
|
747
|
+
FlinkApp.prototype.registerAutoRegisterableAgents = function () {
|
|
748
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
749
|
+
var _a, getRepoInstanceName, toKebabCase, _loop_2, this_2, _i, autoRegisteredAgents_1, agentFile;
|
|
750
|
+
return __generator(this, function (_b) {
|
|
751
|
+
_a = require("./utils"), getRepoInstanceName = _a.getRepoInstanceName, toKebabCase = _a.toKebabCase;
|
|
752
|
+
_loop_2 = function (agentFile) {
|
|
753
|
+
// agentFile now exports a class, not a config object
|
|
754
|
+
var AgentClass = agentFile.default;
|
|
755
|
+
if (!AgentClass) {
|
|
756
|
+
FlinkLog_1.log.error("Missing default export in agent ".concat(agentFile.__file));
|
|
757
|
+
return "continue";
|
|
758
|
+
}
|
|
759
|
+
// Instantiate agent (similar to repo instantiation)
|
|
760
|
+
var agentInstance = new AgentClass();
|
|
761
|
+
// Derive instance name from class name (camelCase)
|
|
762
|
+
var agentInstanceName = getRepoInstanceName(AgentClass.name);
|
|
763
|
+
// Get agent ID (kebab-case) - either explicit or derived
|
|
764
|
+
var agentId = agentInstance.id;
|
|
765
|
+
// Check for duplicate instance name
|
|
766
|
+
if (this_2.agents[agentInstanceName]) {
|
|
767
|
+
var existingAgent = this_2.agents[agentInstanceName];
|
|
768
|
+
throw new Error("Duplicate agent instance name: \"".concat(agentInstanceName, "\". ") +
|
|
769
|
+
"Agent class \"".concat(AgentClass.name, "\" conflicts with existing agent \"").concat(existingAgent.constructor.name, "\". ") +
|
|
770
|
+
"Instance names are derived by lowercasing the first letter of the class name. " +
|
|
771
|
+
"Rename one of the classes or use a unique explicit 'id' property.");
|
|
772
|
+
}
|
|
773
|
+
// Check for duplicate agent ID
|
|
774
|
+
var existingAgentWithSameId = Object.values(this_2.agents).find(function (agent) { return agent.id === agentId; });
|
|
775
|
+
if (existingAgentWithSameId) {
|
|
776
|
+
throw new Error("Duplicate agent ID: \"".concat(agentId, "\". ") +
|
|
777
|
+
"Agent class \"".concat(AgentClass.name, "\" conflicts with existing agent \"").concat(existingAgentWithSameId.constructor.name, "\". ") +
|
|
778
|
+
"Change the 'id' property on one of them to resolve the conflict.");
|
|
779
|
+
}
|
|
780
|
+
// Validate tools exist
|
|
781
|
+
if (agentInstance.tools) {
|
|
782
|
+
for (var _c = 0, _d = agentInstance.tools; _c < _d.length; _c++) {
|
|
783
|
+
var toolRef = _d[_c];
|
|
784
|
+
// Handle string IDs, tool file references, and tool props
|
|
785
|
+
var toolId = void 0;
|
|
786
|
+
if (typeof toolRef === "string") {
|
|
787
|
+
toolId = toolRef;
|
|
788
|
+
}
|
|
789
|
+
else if ("Tool" in toolRef) {
|
|
790
|
+
// FlinkToolFile - extract ID from Tool property
|
|
791
|
+
toolId = toolRef.Tool.id;
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
// FlinkToolProps - extract ID directly
|
|
795
|
+
toolId = toolRef.id;
|
|
796
|
+
}
|
|
797
|
+
var tool = this_2.tools[toolId];
|
|
798
|
+
if (!tool) {
|
|
799
|
+
FlinkLog_1.log.error("Agent ".concat(AgentClass.name, " references tool ").concat(toolId, " which is not registered"));
|
|
800
|
+
throw new Error("Invalid tool reference in agent ".concat(AgentClass.name));
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
// Register agent (duplicate checks already performed above)
|
|
805
|
+
this_2.agents[agentInstanceName] = agentInstance;
|
|
806
|
+
FlinkLog_1.log.info("Registered agent ".concat(agentInstanceName, " (").concat(AgentClass.name, ") with ID: ").concat(agentId));
|
|
807
|
+
};
|
|
808
|
+
this_2 = this;
|
|
809
|
+
for (_i = 0, autoRegisteredAgents_1 = exports.autoRegisteredAgents; _i < autoRegisteredAgents_1.length; _i++) {
|
|
810
|
+
agentFile = autoRegisteredAgents_1[_i];
|
|
811
|
+
_loop_2(agentFile);
|
|
812
|
+
}
|
|
813
|
+
return [2 /*return*/];
|
|
814
|
+
});
|
|
815
|
+
});
|
|
816
|
+
};
|
|
817
|
+
/**
|
|
818
|
+
* Constructs the app context. Will inject context in all components
|
|
819
|
+
* except for handlers which are handled in later stage.
|
|
820
|
+
*/
|
|
821
|
+
FlinkApp.prototype.buildContext = function () {
|
|
822
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
823
|
+
var _i, autoRegisteredRepos_1, _a, collectionName, repoInstanceName, Repo, repoInstance, pluginCtx, _b, _c, repo;
|
|
824
|
+
return __generator(this, function (_d) {
|
|
825
|
+
if (this.dbOpts) {
|
|
826
|
+
for (_i = 0, autoRegisteredRepos_1 = exports.autoRegisteredRepos; _i < autoRegisteredRepos_1.length; _i++) {
|
|
827
|
+
_a = autoRegisteredRepos_1[_i], collectionName = _a.collectionName, repoInstanceName = _a.repoInstanceName, Repo = _a.Repo;
|
|
828
|
+
repoInstance = new Repo(collectionName, this.db, this.dbClient);
|
|
829
|
+
this.repos[repoInstanceName] = repoInstance;
|
|
830
|
+
FlinkLog_1.log.info("Registered repo ".concat(repoInstanceName));
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
else if (exports.autoRegisteredRepos.length > 0) {
|
|
834
|
+
FlinkLog_1.log.warn("No db configured but found repo(s)");
|
|
835
|
+
}
|
|
836
|
+
pluginCtx = this.plugins.reduce(function (out, plugin) {
|
|
837
|
+
if (out[plugin.id]) {
|
|
838
|
+
throw new Error("Plugin ".concat(plugin.id, " is already registered"));
|
|
839
|
+
}
|
|
840
|
+
out[plugin.id] = plugin.ctx;
|
|
841
|
+
return out;
|
|
842
|
+
}, {});
|
|
843
|
+
this._ctx = {
|
|
844
|
+
repos: this.repos,
|
|
845
|
+
plugins: pluginCtx,
|
|
846
|
+
auth: this.auth,
|
|
847
|
+
agents: this.agents,
|
|
848
|
+
};
|
|
849
|
+
for (_b = 0, _c = Object.values(this.repos); _b < _c.length; _b++) {
|
|
850
|
+
repo = _c[_b];
|
|
851
|
+
repo.ctx = this.ctx;
|
|
852
|
+
}
|
|
853
|
+
return [2 /*return*/];
|
|
854
|
+
});
|
|
855
|
+
});
|
|
856
|
+
};
|
|
857
|
+
/**
|
|
858
|
+
* Initialize agents after they've been registered and context is ready
|
|
859
|
+
* Must be called after registerAutoRegisterableAgents()
|
|
860
|
+
*/
|
|
861
|
+
FlinkApp.prototype.initializeAgents = function () {
|
|
862
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
863
|
+
var _i, _a, agent;
|
|
864
|
+
return __generator(this, function (_b) {
|
|
865
|
+
// Inject context and initialize agents
|
|
866
|
+
for (_i = 0, _a = Object.values(this.agents); _i < _a.length; _i++) {
|
|
867
|
+
agent = _a[_i];
|
|
868
|
+
agent.ctx = this.ctx;
|
|
869
|
+
agent.__init(this.llmAdapters, this.tools);
|
|
870
|
+
}
|
|
871
|
+
return [2 /*return*/];
|
|
872
|
+
});
|
|
873
|
+
});
|
|
874
|
+
};
|
|
875
|
+
/**
|
|
876
|
+
* Connects to database.
|
|
877
|
+
*/
|
|
878
|
+
FlinkApp.prototype.initDb = function () {
|
|
879
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
880
|
+
var client, err_2;
|
|
881
|
+
return __generator(this, function (_a) {
|
|
882
|
+
switch (_a.label) {
|
|
883
|
+
case 0:
|
|
884
|
+
if (!this.dbOpts) return [3 /*break*/, 6];
|
|
885
|
+
_a.label = 1;
|
|
886
|
+
case 1:
|
|
887
|
+
_a.trys.push([1, 3, , 4]);
|
|
888
|
+
FlinkLog_1.log.debug("Connecting to db");
|
|
889
|
+
return [4 /*yield*/, mongodb_1.MongoClient.connect(this.dbOpts.uri, this.getMongoConnectionOptions())];
|
|
890
|
+
case 2:
|
|
891
|
+
client = _a.sent();
|
|
892
|
+
this.db = client.db();
|
|
893
|
+
this.dbClient = client;
|
|
894
|
+
return [3 /*break*/, 4];
|
|
895
|
+
case 3:
|
|
896
|
+
err_2 = _a.sent();
|
|
897
|
+
FlinkLog_1.log.error("Failed to connect to db: " + err_2);
|
|
898
|
+
process.exit(1);
|
|
899
|
+
return [3 /*break*/, 4];
|
|
900
|
+
case 4:
|
|
901
|
+
if (!this.onDbConnection) return [3 /*break*/, 6];
|
|
902
|
+
return [4 /*yield*/, this.onDbConnection(this.db)];
|
|
903
|
+
case 5:
|
|
904
|
+
_a.sent();
|
|
905
|
+
_a.label = 6;
|
|
906
|
+
case 6: return [2 /*return*/];
|
|
907
|
+
}
|
|
908
|
+
});
|
|
909
|
+
});
|
|
910
|
+
};
|
|
911
|
+
/**
|
|
912
|
+
* Connects plugin to database.
|
|
913
|
+
*/
|
|
914
|
+
FlinkApp.prototype.initPluginDb = function (plugin) {
|
|
915
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
916
|
+
var client, err_3;
|
|
917
|
+
return __generator(this, function (_a) {
|
|
918
|
+
switch (_a.label) {
|
|
919
|
+
case 0:
|
|
920
|
+
if (!plugin.db) {
|
|
921
|
+
return [2 /*return*/];
|
|
922
|
+
}
|
|
923
|
+
if (!plugin.db) return [3 /*break*/, 5];
|
|
924
|
+
if (!plugin.db.useHostDb) return [3 /*break*/, 1];
|
|
925
|
+
if (!this.db) {
|
|
926
|
+
FlinkLog_1.log.error("Plugin '".concat(this.name, " configured to use host app db, but no db exists in FlinkApp'"));
|
|
927
|
+
}
|
|
928
|
+
else {
|
|
929
|
+
return [2 /*return*/, this.db];
|
|
930
|
+
}
|
|
931
|
+
return [3 /*break*/, 5];
|
|
932
|
+
case 1:
|
|
933
|
+
if (!plugin.db.uri) return [3 /*break*/, 5];
|
|
934
|
+
_a.label = 2;
|
|
935
|
+
case 2:
|
|
936
|
+
_a.trys.push([2, 4, , 5]);
|
|
937
|
+
FlinkLog_1.log.debug("Connecting to '".concat(plugin.id, "' db"));
|
|
938
|
+
return [4 /*yield*/, mongodb_1.MongoClient.connect(plugin.db.uri, this.getMongoConnectionOptions())];
|
|
939
|
+
case 3:
|
|
940
|
+
client = _a.sent();
|
|
941
|
+
return [2 /*return*/, client.db()];
|
|
942
|
+
case 4:
|
|
943
|
+
err_3 = _a.sent();
|
|
944
|
+
FlinkLog_1.log.error("Failed to connect to db defined in plugin '".concat(plugin.id, "': ") + err_3);
|
|
945
|
+
return [3 /*break*/, 5];
|
|
946
|
+
case 5: return [2 /*return*/];
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
});
|
|
950
|
+
};
|
|
951
|
+
FlinkApp.prototype.authenticate = function (req, permissions) {
|
|
952
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
953
|
+
return __generator(this, function (_a) {
|
|
954
|
+
switch (_a.label) {
|
|
955
|
+
case 0:
|
|
956
|
+
if (!this.auth) {
|
|
957
|
+
throw new Error("Attempting to authenticate request (".concat(req.method, " ").concat(req.path, ") but no authPlugin is set"));
|
|
958
|
+
}
|
|
959
|
+
return [4 /*yield*/, this.auth.authenticateRequest(req, permissions)];
|
|
960
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
};
|
|
965
|
+
FlinkApp.prototype.getRegisteredRoutes = function () {
|
|
966
|
+
return Array.from(this.handlerRouteCache.values());
|
|
967
|
+
};
|
|
968
|
+
Object.defineProperty(FlinkApp.prototype, "isSchedulingEnabled", {
|
|
969
|
+
get: function () {
|
|
970
|
+
var _a;
|
|
971
|
+
return ((_a = this.schedulingOptions) === null || _a === void 0 ? void 0 : _a.enabled) !== false;
|
|
972
|
+
},
|
|
973
|
+
enumerable: false,
|
|
974
|
+
configurable: true
|
|
975
|
+
});
|
|
976
|
+
FlinkApp.prototype.getMongoConnectionOptions = function () {
|
|
977
|
+
if (!this.dbOpts) {
|
|
978
|
+
throw new Error("No db configured");
|
|
979
|
+
}
|
|
980
|
+
var driverVersion = require("mongodb/package.json").version;
|
|
981
|
+
if (driverVersion.startsWith("3")) {
|
|
982
|
+
FlinkLog_1.log.debug("Using legacy mongodb connection options as mongo client is version ".concat(driverVersion));
|
|
983
|
+
return {
|
|
984
|
+
useNewUrlParser: true,
|
|
985
|
+
useUnifiedTopology: true,
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
FlinkLog_1.log.debug("Using modern MongoDB client options (driver version ".concat(driverVersion, ")"));
|
|
989
|
+
return {
|
|
990
|
+
serverApi: {
|
|
991
|
+
version: mongodb_1.ServerApiVersion.v1,
|
|
992
|
+
strict: process.env.FLINK_MONGO_SERVER_API_DISABLE_STRICT !== "true",
|
|
993
|
+
deprecationErrors: process.env.FLINK_MONGO_SERVER_API_DISABLE_DEPRECATION !== "true",
|
|
994
|
+
},
|
|
995
|
+
connectTimeoutMS: 10 * 1000,
|
|
996
|
+
};
|
|
997
|
+
};
|
|
998
|
+
return FlinkApp;
|
|
999
|
+
}());
|
|
1000
|
+
exports.FlinkApp = FlinkApp;
|