@flink-app/flink 1.0.0 → 2.0.0-alpha.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/cli/build.ts +8 -1
  3. package/cli/run.ts +8 -1
  4. package/dist/cli/build.js +8 -1
  5. package/dist/cli/run.js +8 -1
  6. package/dist/src/FlinkApp.d.ts +33 -0
  7. package/dist/src/FlinkApp.js +247 -27
  8. package/dist/src/FlinkContext.d.ts +21 -0
  9. package/dist/src/FlinkHttpHandler.d.ts +90 -1
  10. package/dist/src/TypeScriptCompiler.d.ts +42 -0
  11. package/dist/src/TypeScriptCompiler.js +366 -8
  12. package/dist/src/TypeScriptUtils.js +4 -0
  13. package/dist/src/ai/AgentRunner.d.ts +39 -0
  14. package/dist/src/ai/AgentRunner.js +625 -0
  15. package/dist/src/ai/FlinkAgent.d.ts +446 -0
  16. package/dist/src/ai/FlinkAgent.js +633 -0
  17. package/dist/src/ai/FlinkTool.d.ts +37 -0
  18. package/dist/src/ai/FlinkTool.js +2 -0
  19. package/dist/src/ai/LLMAdapter.d.ts +119 -0
  20. package/dist/src/ai/LLMAdapter.js +2 -0
  21. package/dist/src/ai/SubAgentExecutor.d.ts +36 -0
  22. package/dist/src/ai/SubAgentExecutor.js +220 -0
  23. package/dist/src/ai/ToolExecutor.d.ts +35 -0
  24. package/dist/src/ai/ToolExecutor.js +237 -0
  25. package/dist/src/ai/index.d.ts +5 -0
  26. package/dist/src/ai/index.js +21 -0
  27. package/dist/src/handlers/StreamWriterFactory.d.ts +20 -0
  28. package/dist/src/handlers/StreamWriterFactory.js +83 -0
  29. package/dist/src/index.d.ts +4 -0
  30. package/dist/src/index.js +4 -0
  31. package/dist/src/utils.d.ts +30 -0
  32. package/dist/src/utils.js +52 -0
  33. package/package.json +14 -2
  34. package/readme.md +425 -0
  35. package/spec/AgentDuplicateDetection.spec.ts +112 -0
  36. package/spec/AgentRunner.spec.ts +527 -0
  37. package/spec/ConversationHooks.spec.ts +290 -0
  38. package/spec/FlinkAgent.spec.ts +310 -0
  39. package/spec/FlinkApp.onError.spec.ts +1 -2
  40. package/spec/StreamingIntegration.spec.ts +138 -0
  41. package/spec/SubAgentSupport.spec.ts +941 -0
  42. package/spec/ToolExecutor.spec.ts +360 -0
  43. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar.js +57 -0
  44. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar2.js +59 -0
  45. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema.js +53 -0
  46. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema2.js +53 -0
  47. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema3.js +53 -0
  48. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema.js +55 -0
  49. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema2.js +55 -0
  50. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile.js +58 -0
  51. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile2.js +58 -0
  52. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler.js +53 -0
  53. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler2.js +55 -0
  54. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchCar.js +58 -0
  55. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOnboardingSession.js +76 -0
  56. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.js +58 -0
  57. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchProductWithIntersection.js +59 -0
  58. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchUserWithUnion.js +59 -0
  59. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostCar.js +55 -0
  60. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogin.js +56 -0
  61. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogout.js +55 -0
  62. package/spec/mock-project/dist/spec/mock-project/src/handlers/PutCar.js +55 -0
  63. package/spec/mock-project/dist/spec/mock-project/src/index.js +83 -0
  64. package/spec/mock-project/dist/spec/mock-project/src/repos/CarRepo.js +26 -0
  65. package/spec/mock-project/dist/spec/mock-project/src/schemas/Car.js +2 -0
  66. package/spec/mock-project/dist/spec/mock-project/src/schemas/DefaultExportSchema.js +2 -0
  67. package/spec/mock-project/dist/spec/mock-project/src/schemas/FileWithTwoSchemas.js +2 -0
  68. package/spec/mock-project/dist/src/FlinkApp.js +1012 -0
  69. package/spec/mock-project/dist/src/FlinkContext.js +2 -0
  70. package/spec/mock-project/dist/src/FlinkErrors.js +143 -0
  71. package/spec/mock-project/dist/src/FlinkHttpHandler.js +47 -0
  72. package/spec/mock-project/dist/src/FlinkJob.js +2 -0
  73. package/spec/mock-project/dist/src/FlinkLog.js +26 -0
  74. package/spec/mock-project/dist/src/FlinkPlugin.js +2 -0
  75. package/spec/mock-project/dist/src/FlinkRepo.js +224 -0
  76. package/spec/mock-project/dist/src/FlinkResponse.js +2 -0
  77. package/spec/mock-project/dist/src/ai/AgentExecutor.js +279 -0
  78. package/spec/mock-project/dist/src/ai/AgentRunner.js +625 -0
  79. package/spec/mock-project/dist/src/ai/FlinkAgent.js +633 -0
  80. package/spec/mock-project/dist/src/ai/FlinkTool.js +2 -0
  81. package/spec/mock-project/dist/src/ai/LLMAdapter.js +2 -0
  82. package/spec/mock-project/dist/src/ai/SubAgentExecutor.js +220 -0
  83. package/spec/mock-project/dist/src/ai/ToolExecutor.js +237 -0
  84. package/spec/mock-project/dist/src/auth/FlinkAuthPlugin.js +2 -0
  85. package/spec/mock-project/dist/src/auth/FlinkAuthUser.js +2 -0
  86. package/spec/mock-project/dist/src/handlers/StreamWriterFactory.js +83 -0
  87. package/spec/mock-project/dist/src/index.js +17 -69
  88. package/spec/mock-project/dist/src/mock-data-generator.js +9 -0
  89. package/spec/mock-project/dist/src/utils.js +290 -0
  90. package/spec/mock-project/tsconfig.json +6 -1
  91. package/spec/testHelpers.ts +49 -0
  92. package/spec/utils.caseConversion.spec.ts +80 -0
  93. package/spec/utils.spec.ts +13 -13
  94. package/src/FlinkApp.ts +251 -7
  95. package/src/FlinkContext.ts +22 -0
  96. package/src/FlinkHttpHandler.ts +100 -2
  97. package/src/TypeScriptCompiler.ts +420 -9
  98. package/src/TypeScriptUtils.ts +5 -0
  99. package/src/ai/AgentRunner.ts +549 -0
  100. package/src/ai/FlinkAgent.ts +770 -0
  101. package/src/ai/FlinkTool.ts +40 -0
  102. package/src/ai/LLMAdapter.ts +96 -0
  103. package/src/ai/SubAgentExecutor.ts +199 -0
  104. package/src/ai/ToolExecutor.ts +193 -0
  105. package/src/ai/index.ts +5 -0
  106. package/src/handlers/StreamWriterFactory.ts +84 -0
  107. package/src/index.ts +4 -0
  108. package/src/utils.ts +52 -0
  109. package/tsconfig.json +6 -1
@@ -0,0 +1,220 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.SubAgentExecutor = void 0;
51
+ var zod_1 = require("zod");
52
+ var FlinkLog_1 = require("../FlinkLog");
53
+ var utils_1 = require("../utils");
54
+ var uuid_1 = require("uuid");
55
+ /**
56
+ * Special tool executor that wraps a sub-agent
57
+ * Automatically created for each agent reference in parent agent's `agents` array
58
+ */
59
+ var SubAgentExecutor = /** @class */ (function () {
60
+ function SubAgentExecutor(subAgentInstanceName, ctx) {
61
+ this.ctx = ctx;
62
+ this.subAgentInstanceName = subAgentInstanceName;
63
+ // Convert instance name to kebab-case for consistency with agent IDs
64
+ this.subAgentId = (0, utils_1.toKebabCase)(subAgentInstanceName);
65
+ }
66
+ /**
67
+ * Execute the sub-agent with the given input
68
+ */
69
+ SubAgentExecutor.prototype.execute = function (input, user, parentContext, // NEW: parent agent context
70
+ userPermissions // Resolved permissions from auth plugin
71
+ ) {
72
+ return __awaiter(this, void 0, void 0, function () {
73
+ var agents, subAgent, boundAgent, strategy, conversationId, response, result, err_1;
74
+ var _a;
75
+ return __generator(this, function (_b) {
76
+ switch (_b.label) {
77
+ case 0:
78
+ _b.trys.push([0, 2, , 3]);
79
+ agents = this.ctx.agents;
80
+ if (!agents) {
81
+ return [2 /*return*/, {
82
+ success: false,
83
+ error: "Agents not available in context",
84
+ code: "NO_AGENTS",
85
+ }];
86
+ }
87
+ subAgent = agents[this.subAgentInstanceName];
88
+ if (!subAgent) {
89
+ return [2 /*return*/, {
90
+ success: false,
91
+ error: "Sub-agent ".concat(this.subAgentInstanceName, " not found"),
92
+ code: "AGENT_NOT_FOUND",
93
+ }];
94
+ }
95
+ boundAgent = subAgent;
96
+ if (user) {
97
+ boundAgent = boundAgent.withUser(user);
98
+ }
99
+ if (userPermissions) {
100
+ boundAgent = boundAgent.withPermissions(userPermissions);
101
+ }
102
+ strategy = subAgent.conversationStrategy || "inherit";
103
+ conversationId = void 0;
104
+ if (strategy === "inherit") {
105
+ // Use parent's conversation ID
106
+ conversationId = parentContext === null || parentContext === void 0 ? void 0 : parentContext.conversationId;
107
+ }
108
+ else if (strategy === "independent") {
109
+ // Create nested conversation
110
+ conversationId = (parentContext === null || parentContext === void 0 ? void 0 : parentContext.conversationId)
111
+ ? "".concat(parentContext.conversationId, ":").concat(this.subAgentInstanceName, ":").concat((0, utils_1.generateShortId)())
112
+ : (0, uuid_1.v4)();
113
+ }
114
+ else {
115
+ // strategy === "none"
116
+ conversationId = undefined;
117
+ }
118
+ FlinkLog_1.log.debug("Delegating to sub-agent ".concat(this.subAgentInstanceName, " from parent ").concat((parentContext === null || parentContext === void 0 ? void 0 : parentContext.agentId) || "unknown", ", ") +
119
+ "strategy: \"".concat(strategy, "\", conversationId: ").concat(conversationId || "none"));
120
+ response = boundAgent.run({
121
+ message: input.query || input.message || JSON.stringify(input),
122
+ user: user,
123
+ userPermissions: userPermissions,
124
+ conversationId: conversationId,
125
+ metadata: __assign(__assign({}, input.metadata), { parentConversationId: parentContext === null || parentContext === void 0 ? void 0 : parentContext.conversationId, parentAgentId: parentContext === null || parentContext === void 0 ? void 0 : parentContext.agentId, parentMetadata: parentContext === null || parentContext === void 0 ? void 0 : parentContext.metadata, isSubAgentCall: true, subAgentDepth: ((_a = parentContext === null || parentContext === void 0 ? void 0 : parentContext.subAgentDepth) !== null && _a !== void 0 ? _a : 0) + 1 }),
126
+ });
127
+ return [4 /*yield*/, response.result];
128
+ case 1:
129
+ result = _b.sent();
130
+ FlinkLog_1.log.debug("Sub-agent ".concat(this.subAgentInstanceName, " completed with ").concat(result.stepsUsed, " steps"));
131
+ return [2 /*return*/, {
132
+ success: true,
133
+ data: result,
134
+ }];
135
+ case 2:
136
+ err_1 = _b.sent();
137
+ FlinkLog_1.log.error("Sub-agent ".concat(this.subAgentInstanceName, " execution failed:"), err_1.message);
138
+ return [2 /*return*/, {
139
+ success: false,
140
+ error: "Sub-agent execution failed: ".concat(err_1.message),
141
+ code: "SUB_AGENT_ERROR",
142
+ }];
143
+ case 3: return [2 /*return*/];
144
+ }
145
+ });
146
+ });
147
+ };
148
+ /**
149
+ * Generate tool schema for this sub-agent
150
+ * LLM sees this as a regular tool
151
+ */
152
+ SubAgentExecutor.prototype.getToolSchema = function () {
153
+ var agents = this.ctx.agents;
154
+ if (!(agents === null || agents === void 0 ? void 0 : agents[this.subAgentInstanceName])) {
155
+ throw new Error("Missing subagent: " + this.subAgentInstanceName);
156
+ }
157
+ var subAgent = agents === null || agents === void 0 ? void 0 : agents[this.subAgentInstanceName];
158
+ var description = subAgent ? "Delegate to ".concat(this.subAgentId, ": ").concat(subAgent.description) : "Delegate to ".concat(this.subAgentId);
159
+ // Simple schema - accepts a query string
160
+ var inputSchema = zod_1.z.object({
161
+ query: zod_1.z.string().describe("The question or task to send to the specialist agent"),
162
+ });
163
+ // Convert kebab-case ID to snake_case for tool name (ask_car_agent, not ask_car-agent)
164
+ var toolName = "ask_".concat((0, utils_1.toSnakeCase)(this.subAgentId));
165
+ return {
166
+ name: toolName,
167
+ description: description,
168
+ input_schema: inputSchema.schema
169
+ ? inputSchema.schema()
170
+ : {
171
+ type: "object",
172
+ properties: {
173
+ query: { type: "string" },
174
+ },
175
+ required: ["query"],
176
+ },
177
+ };
178
+ };
179
+ /**
180
+ * Format sub-agent result for AI consumption
181
+ */
182
+ SubAgentExecutor.prototype.formatResultForAI = function (result) {
183
+ var _a, _b;
184
+ if (result.success) {
185
+ var agentResult = result.data;
186
+ // Return the agent's final message as the tool result
187
+ return JSON.stringify({
188
+ answer: agentResult.message,
189
+ stepsUsed: agentResult.stepsUsed,
190
+ tokensUsed: (((_a = agentResult.usage) === null || _a === void 0 ? void 0 : _a.inputTokens) || 0) + (((_b = agentResult.usage) === null || _b === void 0 ? void 0 : _b.outputTokens) || 0),
191
+ });
192
+ }
193
+ else {
194
+ return "Error: ".concat(result.error).concat(result.code ? " (".concat(result.code, ")") : "");
195
+ }
196
+ };
197
+ /**
198
+ * Check permissions - sub-agents handle their own permissions
199
+ */
200
+ SubAgentExecutor.prototype.checkPermissions = function (_user, _input, _userPermissions) {
201
+ return __awaiter(this, void 0, void 0, function () {
202
+ return __generator(this, function (_a) {
203
+ // Sub-agents manage their own permissions
204
+ // The sub-agent's permissions will be checked when executed
205
+ return [2 /*return*/, true];
206
+ });
207
+ });
208
+ };
209
+ /**
210
+ * Mark this as a sub-agent executor
211
+ */
212
+ SubAgentExecutor.prototype.isSubAgentExecutor = function () {
213
+ return true;
214
+ };
215
+ SubAgentExecutor.prototype.getSubAgentId = function () {
216
+ return this.subAgentId;
217
+ };
218
+ return SubAgentExecutor;
219
+ }());
220
+ exports.SubAgentExecutor = SubAgentExecutor;
@@ -0,0 +1,237 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ToolExecutor = void 0;
40
+ var FlinkLog_1 = require("../FlinkLog");
41
+ var ToolExecutor = /** @class */ (function () {
42
+ function ToolExecutor(toolProps, toolFn, ctx) {
43
+ this.toolProps = toolProps;
44
+ this.toolFn = toolFn;
45
+ this.ctx = ctx;
46
+ }
47
+ ToolExecutor.prototype.execute = function (input, user, userPermissions) {
48
+ return __awaiter(this, void 0, void 0, function () {
49
+ var hasPermission, validatedInput, errorDetails, result, err_1, validatedData;
50
+ return __generator(this, function (_a) {
51
+ switch (_a.label) {
52
+ case 0:
53
+ if (!this.toolProps.permissions) return [3 /*break*/, 2];
54
+ return [4 /*yield*/, this.checkPermissionsInternal(input, user, userPermissions)];
55
+ case 1:
56
+ hasPermission = _a.sent();
57
+ if (!hasPermission) {
58
+ return [2 /*return*/, {
59
+ success: false,
60
+ error: "Permission denied for tool ".concat(this.toolProps.id),
61
+ code: "PERMISSION_DENIED",
62
+ }];
63
+ }
64
+ _a.label = 2;
65
+ case 2:
66
+ try {
67
+ validatedInput = this.toolProps.inputSchema.parse(input);
68
+ }
69
+ catch (err) {
70
+ FlinkLog_1.log.warn("Tool ".concat(this.toolProps.id, " input validation failed:"), err.message);
71
+ errorDetails = this.formatValidationError(err, input);
72
+ return [2 /*return*/, {
73
+ success: false,
74
+ error: "Invalid input for tool '".concat(this.toolProps.id, "': ").concat(errorDetails),
75
+ code: "VALIDATION_ERROR",
76
+ }];
77
+ }
78
+ // 3. Execute tool
79
+ FlinkLog_1.log.debug("Executing tool ".concat(this.toolProps.id));
80
+ _a.label = 3;
81
+ case 3:
82
+ _a.trys.push([3, 5, , 6]);
83
+ return [4 /*yield*/, this.toolFn({
84
+ input: validatedInput,
85
+ ctx: this.ctx,
86
+ user: user,
87
+ })];
88
+ case 4:
89
+ result = _a.sent();
90
+ return [3 /*break*/, 6];
91
+ case 5:
92
+ err_1 = _a.sent();
93
+ FlinkLog_1.log.error("Tool ".concat(this.toolProps.id, " threw error:"), err_1.message);
94
+ return [2 /*return*/, {
95
+ success: false,
96
+ error: "Tool execution failed: ".concat(err_1.message),
97
+ code: "EXECUTION_ERROR",
98
+ }];
99
+ case 6:
100
+ // 4. Handle error results
101
+ if (!result.success) {
102
+ FlinkLog_1.log.warn("Tool ".concat(this.toolProps.id, " returned error:"), result.error);
103
+ return [2 /*return*/, result]; // Return error result as-is
104
+ }
105
+ // 5. Output validation (if schema provided)
106
+ if (this.toolProps.outputSchema) {
107
+ try {
108
+ validatedData = this.toolProps.outputSchema.parse(result.data);
109
+ return [2 /*return*/, { success: true, data: validatedData }];
110
+ }
111
+ catch (err) {
112
+ FlinkLog_1.log.error("Tool ".concat(this.toolProps.id, " output validation failed:"), err.message);
113
+ return [2 /*return*/, {
114
+ success: false,
115
+ error: "Invalid output from tool ".concat(this.toolProps.id, ": ").concat(err.message),
116
+ code: "OUTPUT_VALIDATION_ERROR",
117
+ }];
118
+ }
119
+ }
120
+ return [2 /*return*/, result];
121
+ }
122
+ });
123
+ });
124
+ };
125
+ ToolExecutor.prototype.getToolSchema = function () {
126
+ // Use Zod 4's built-in z.toJSONSchema()
127
+ var zodSchema = this.toolProps.inputSchema;
128
+ var z = require("zod");
129
+ return {
130
+ name: this.toolProps.id,
131
+ description: this.toolProps.description,
132
+ inputSchema: z.toJSONSchema ? z.toJSONSchema(zodSchema) : this.fallbackSchema(zodSchema),
133
+ };
134
+ };
135
+ /**
136
+ * Fallback schema generation if toJSONSchema is not available
137
+ */
138
+ ToolExecutor.prototype.fallbackSchema = function (zodSchema) {
139
+ // Try to use _def to extract basic schema info
140
+ FlinkLog_1.log.warn("Tool ".concat(this.toolProps.id, ": z.toJSONSchema() not available, using fallback schema generation"));
141
+ return {
142
+ type: "object",
143
+ properties: {},
144
+ required: [],
145
+ };
146
+ };
147
+ /**
148
+ * Get tool result for AI consumption
149
+ * Formats ToolResult into string for AI context
150
+ */
151
+ ToolExecutor.prototype.formatResultForAI = function (result) {
152
+ if (result.success) {
153
+ return JSON.stringify(result.data);
154
+ }
155
+ else {
156
+ return "Error: ".concat(result.error).concat(result.code ? " (".concat(result.code, ")") : "");
157
+ }
158
+ };
159
+ /**
160
+ * Check if user has permission to use this tool
161
+ * Used by AgentRunner to filter tools before showing to LLM
162
+ *
163
+ * @param user - User object
164
+ * @param input - Tool input (for function-based permissions)
165
+ * @param userPermissions - Optional resolved permissions from auth plugin (preferred)
166
+ */
167
+ ToolExecutor.prototype.checkPermissions = function (user, input, userPermissions) {
168
+ return __awaiter(this, void 0, void 0, function () {
169
+ var perms, effectivePerms, requiredPerms;
170
+ return __generator(this, function (_a) {
171
+ switch (_a.label) {
172
+ case 0:
173
+ perms = this.toolProps.permissions;
174
+ if (!perms)
175
+ return [2 /*return*/, true];
176
+ if (!(typeof perms === "function")) return [3 /*break*/, 2];
177
+ return [4 /*yield*/, perms(input !== null && input !== void 0 ? input : {}, user)];
178
+ case 1: return [2 /*return*/, _a.sent()];
179
+ case 2:
180
+ if (!user)
181
+ return [2 /*return*/, false];
182
+ effectivePerms = userPermissions || user.permissions || [];
183
+ requiredPerms = Array.isArray(perms) ? perms : [perms];
184
+ return [2 /*return*/, requiredPerms.every(function (p) { return effectivePerms.includes(p); })];
185
+ }
186
+ });
187
+ });
188
+ };
189
+ ToolExecutor.prototype.checkPermissionsInternal = function (input, user, userPermissions) {
190
+ return __awaiter(this, void 0, void 0, function () {
191
+ return __generator(this, function (_a) {
192
+ return [2 /*return*/, this.checkPermissions(user, input, userPermissions)];
193
+ });
194
+ });
195
+ };
196
+ /**
197
+ * Format Zod validation errors into LLM-friendly error messages
198
+ * Provides specific guidance on what's missing or incorrect
199
+ */
200
+ ToolExecutor.prototype.formatValidationError = function (err, receivedInput) {
201
+ // Check if it's a Zod error with issues array
202
+ if (err.issues && Array.isArray(err.issues)) {
203
+ var issues = err.issues.map(function (issue) {
204
+ var path = issue.path.join('.');
205
+ var field = path || 'input';
206
+ if (issue.code === 'invalid_type') {
207
+ if (issue.received === 'undefined') {
208
+ return "Missing required field '".concat(field, "' (expected ").concat(issue.expected, ")");
209
+ }
210
+ return "Field '".concat(field, "' has wrong type: expected ").concat(issue.expected, ", got ").concat(issue.received);
211
+ }
212
+ if (issue.code === 'too_small') {
213
+ if (issue.type === 'string') {
214
+ return "Field '".concat(field, "' is too short (minimum ").concat(issue.minimum, " characters)");
215
+ }
216
+ return "Field '".concat(field, "' is too small (minimum ").concat(issue.minimum, ")");
217
+ }
218
+ if (issue.code === 'too_big') {
219
+ if (issue.type === 'string') {
220
+ return "Field '".concat(field, "' is too long (maximum ").concat(issue.maximum, " characters)");
221
+ }
222
+ return "Field '".concat(field, "' is too large (maximum ").concat(issue.maximum, ")");
223
+ }
224
+ // Generic fallback
225
+ return "".concat(field, ": ").concat(issue.message);
226
+ });
227
+ var inputInfo = Object.keys(receivedInput || {}).length === 0
228
+ ? 'You provided an empty object {}.'
229
+ : "You provided: ".concat(JSON.stringify(receivedInput));
230
+ return "".concat(issues.join('; '), ". ").concat(inputInfo);
231
+ }
232
+ // Fallback for non-Zod errors
233
+ return err.message || 'Unknown validation error';
234
+ };
235
+ return ToolExecutor;
236
+ }());
237
+ exports.ToolExecutor = ToolExecutor;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamWriterFactory = void 0;
4
+ var FlinkLog_1 = require("../FlinkLog");
5
+ /**
6
+ * Factory for creating StreamWriter instances for SSE and NDJSON streaming.
7
+ *
8
+ * Handles HTTP headers, connection lifecycle, and format-specific serialization.
9
+ */
10
+ var StreamWriterFactory = /** @class */ (function () {
11
+ function StreamWriterFactory() {
12
+ }
13
+ /**
14
+ * Create a StreamWriter for the given format.
15
+ *
16
+ * Sets appropriate HTTP headers and manages the stream lifecycle including
17
+ * client disconnect detection.
18
+ *
19
+ * @param res - Express response object
20
+ * @param format - Stream format (sse or ndjson)
21
+ * @returns StreamWriter instance for writing data to the stream
22
+ */
23
+ StreamWriterFactory.create = function (res, format) {
24
+ // Set appropriate headers based on format
25
+ if (format === "sse") {
26
+ res.setHeader("Content-Type", "text/event-stream");
27
+ res.setHeader("Cache-Control", "no-cache");
28
+ res.setHeader("Connection", "keep-alive");
29
+ res.flushHeaders();
30
+ }
31
+ else if (format === "ndjson") {
32
+ res.setHeader("Content-Type", "application/x-ndjson");
33
+ res.setHeader("Cache-Control", "no-cache");
34
+ res.flushHeaders();
35
+ }
36
+ var isOpen = true;
37
+ // Detect client disconnect
38
+ res.on("close", function () {
39
+ isOpen = false;
40
+ });
41
+ return {
42
+ write: function (data) {
43
+ if (!isOpen)
44
+ return;
45
+ try {
46
+ var json = JSON.stringify(data);
47
+ if (format === "sse") {
48
+ res.write("data: ".concat(json, "\n\n"));
49
+ }
50
+ else if (format === "ndjson") {
51
+ res.write("".concat(json, "\n"));
52
+ }
53
+ }
54
+ catch (err) {
55
+ FlinkLog_1.log.error("StreamWriter serialization error:", { error: err });
56
+ isOpen = false;
57
+ }
58
+ },
59
+ error: function (error) {
60
+ if (!isOpen)
61
+ return;
62
+ var errorMessage = typeof error === "string" ? error : error.message;
63
+ if (format === "sse") {
64
+ res.write("event: error\ndata: ".concat(JSON.stringify({ error: errorMessage }), "\n\n"));
65
+ }
66
+ else if (format === "ndjson") {
67
+ res.write("".concat(JSON.stringify({ error: errorMessage }), "\n"));
68
+ }
69
+ res.end();
70
+ isOpen = false;
71
+ },
72
+ end: function () {
73
+ if (isOpen) {
74
+ res.end();
75
+ isOpen = false;
76
+ }
77
+ },
78
+ isOpen: function () { return isOpen; },
79
+ };
80
+ };
81
+ return StreamWriterFactory;
82
+ }());
83
+ exports.StreamWriterFactory = StreamWriterFactory;
@@ -10,74 +10,22 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
12
  }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
- var __generator = (this && this.__generator) || function (thisArg, body) {
35
- 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);
36
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37
- function verb(n) { return function (v) { return step([n, v]); }; }
38
- function step(op) {
39
- if (f) throw new TypeError("Generator is already executing.");
40
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
41
- 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;
42
- if (y = 0, t) op = [op[0] & 2, t.value];
43
- switch (op[0]) {
44
- case 0: case 1: t = op; break;
45
- case 4: _.label++; return { value: op[1], done: false };
46
- case 5: _.label++; y = op[1]; op = [0]; continue;
47
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
48
- default:
49
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53
- if (t[2]) _.ops.pop();
54
- _.trys.pop(); continue;
55
- }
56
- op = body.call(thisArg, _);
57
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59
- }
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
60
15
  };
61
16
  Object.defineProperty(exports, "__esModule", { value: true });
62
- var flink_1 = require("@flink-app/flink");
63
- var ManuallyAddedHandler = __importStar(require("./handlers/ManuallyAddedHandler"));
64
- var ManuallyAddedHandler2 = __importStar(require("./handlers/ManuallyAddedHandler2"));
65
- function start() {
66
- return __awaiter(this, void 0, void 0, function () {
67
- var app;
68
- return __generator(this, function (_a) {
69
- switch (_a.label) {
70
- case 0: return [4 /*yield*/, new flink_1.FlinkApp({
71
- name: "Test app",
72
- plugins: [],
73
- }).start()];
74
- case 1:
75
- app = _a.sent();
76
- app.addHandler(ManuallyAddedHandler);
77
- app.addHandler(ManuallyAddedHandler2, { path: "/override" });
78
- return [2 /*return*/];
79
- }
80
- });
81
- });
82
- }
83
- start();
17
+ __exportStar(require("./FlinkLog"), exports);
18
+ __exportStar(require("./FlinkApp"), exports);
19
+ __exportStar(require("./FlinkHttpHandler"), exports);
20
+ __exportStar(require("./FlinkContext"), exports);
21
+ __exportStar(require("./FlinkRepo"), exports);
22
+ __exportStar(require("./FlinkResponse"), exports);
23
+ __exportStar(require("./FlinkErrors"), exports);
24
+ __exportStar(require("./FlinkPlugin"), exports);
25
+ __exportStar(require("./FlinkJob"), exports);
26
+ __exportStar(require("./auth/FlinkAuthUser"), exports);
27
+ __exportStar(require("./auth/FlinkAuthPlugin"), exports);
28
+ __exportStar(require("./ai/FlinkTool"), exports);
29
+ __exportStar(require("./ai/FlinkAgent"), exports);
30
+ __exportStar(require("./ai/ToolExecutor"), exports);
31
+ __exportStar(require("./ai/LLMAdapter"), exports);
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mock_json_schema_1 = require("mock-json-schema");
4
+ var generateMockData = function (schema) {
5
+ // TODO: mock-json-schema does not seem to handle `examples` array, might want to switch to json-schema-faker
6
+ var mockData = (0, mock_json_schema_1.mock)(schema);
7
+ return mockData;
8
+ };
9
+ exports.default = generateMockData;