@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,39 @@
1
+ import { FlinkAgentProps, AgentExecuteInput, StreamChunk } from "./FlinkAgent";
2
+ import { ToolExecutor } from "./ToolExecutor";
3
+ import { LLMAdapter } from "./LLMAdapter";
4
+ export declare class AgentRunner {
5
+ private agentProps;
6
+ private tools;
7
+ private agentName?;
8
+ private llmAdapter;
9
+ private maxTokens;
10
+ private temperature;
11
+ private maxSteps;
12
+ private timeoutMs;
13
+ private maxSubAgentDepth;
14
+ constructor(agentProps: FlinkAgentProps, tools: Map<string, ToolExecutor<any>>, llmAdapters: Map<string, LLMAdapter>, agentName?: string | undefined);
15
+ /**
16
+ * Phase 1: Stream generator that yields complete event on finish
17
+ * Phase 2: Will yield text_delta and tool events during execution
18
+ */
19
+ streamGenerator(input: AgentExecuteInput): AsyncGenerator<StreamChunk>;
20
+ /**
21
+ * Convert Message[] to LLM message format
22
+ * Supports multi-turn conversations with history
23
+ */
24
+ private convertMessages;
25
+ private getToolSchemas;
26
+ /**
27
+ * Filter tools based on user permissions
28
+ * Only returns schemas for tools the user has permission to use
29
+ *
30
+ * @param user - User object
31
+ * @param userPermissions - Optional resolved permissions from auth plugin (preferred)
32
+ */
33
+ private filterToolsByPermissions;
34
+ /**
35
+ * Build delegation chain from metadata for error messages
36
+ * Extracts parent agent IDs to show the full call stack
37
+ */
38
+ private buildDelegationChain;
39
+ }
@@ -0,0 +1,625 @@
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 __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
50
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
51
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
52
+ var m = o[Symbol.asyncIterator], i;
53
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
54
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
55
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
56
+ };
57
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
58
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
59
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
60
+ return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
61
+ function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
62
+ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
63
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
64
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
65
+ function fulfill(value) { resume("next", value); }
66
+ function reject(value) { resume("throw", value); }
67
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
68
+ };
69
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
70
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
71
+ if (ar || !(i in from)) {
72
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
73
+ ar[i] = from[i];
74
+ }
75
+ }
76
+ return to.concat(ar || Array.prototype.slice.call(from));
77
+ };
78
+ Object.defineProperty(exports, "__esModule", { value: true });
79
+ exports.AgentRunner = void 0;
80
+ var SubAgentExecutor_1 = require("./SubAgentExecutor");
81
+ var FlinkLog_1 = require("../FlinkLog");
82
+ var AgentRunner = /** @class */ (function () {
83
+ function AgentRunner(agentProps, tools, llmAdapters, agentName) {
84
+ var _a, _b, _c, _d, _e, _f;
85
+ this.agentProps = agentProps;
86
+ this.tools = tools;
87
+ this.agentName = agentName;
88
+ // Get appropriate LLM adapter based on adapterId
89
+ var adapterId = ((_a = agentProps.model) === null || _a === void 0 ? void 0 : _a.adapterId) || "default";
90
+ var adapter = llmAdapters.get(adapterId);
91
+ if (!adapter) {
92
+ throw new Error("LLM adapter \"".concat(adapterId, "\" not configured - register it in FlinkOptions.ai.llms"));
93
+ }
94
+ this.llmAdapter = adapter;
95
+ this.maxTokens = ((_b = agentProps.model) === null || _b === void 0 ? void 0 : _b.maxTokens) || 4096;
96
+ this.temperature = ((_c = agentProps.model) === null || _c === void 0 ? void 0 : _c.temperature) || 0.7;
97
+ this.maxSteps = ((_d = agentProps.limits) === null || _d === void 0 ? void 0 : _d.maxSteps) || 10;
98
+ this.timeoutMs = ((_e = agentProps.limits) === null || _e === void 0 ? void 0 : _e.timeoutMs) || 60000;
99
+ this.maxSubAgentDepth = ((_f = agentProps.limits) === null || _f === void 0 ? void 0 : _f.maxSubAgentDepth) || 5;
100
+ }
101
+ /**
102
+ * Phase 1: Stream generator that yields complete event on finish
103
+ * Phase 2: Will yield text_delta and tool events during execution
104
+ */
105
+ AgentRunner.prototype.streamGenerator = function (input) {
106
+ return __asyncGenerator(this, arguments, function streamGenerator_1() {
107
+ var maxSteps, toolCalls, subAgentCalls, currentDepth, chain, chainStr, execContext, messages, step, finalMessage, stoppedEarly, totalInputTokens, totalOutputTokens, availableTools, llmStream, textContent, toolCallsFromStream, usage, stopReason, _a, llmStream_1, llmStream_1_1, chunk, _b, e_1_1, llmResponse, assistantContent, _i, _c, toolCall, stepContext, toolResults, _d, _e, toolCall, toolExecutor, toolOutput, toolError, isSubAgent, subAgentId, transformedInput, err_1, toolResult, _f, formattedResult, subAgentId, agentResult, err_2, stepContext, result, finishContext;
108
+ var _g, e_1, _h, _j;
109
+ var _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
110
+ return __generator(this, function (_w) {
111
+ switch (_w.label) {
112
+ case 0:
113
+ maxSteps = ((_k = input.options) === null || _k === void 0 ? void 0 : _k.maxSteps) || this.maxSteps;
114
+ toolCalls = [];
115
+ subAgentCalls = [];
116
+ currentDepth = (_m = (_l = input.metadata) === null || _l === void 0 ? void 0 : _l.subAgentDepth) !== null && _m !== void 0 ? _m : 0;
117
+ // Check depth limit before execution
118
+ if (currentDepth > this.maxSubAgentDepth) {
119
+ chain = this.buildDelegationChain(input.metadata);
120
+ chainStr = chain.length > 0 ? " Delegation chain: ".concat(chain.join(" → "), " \u2192 ").concat(this.agentName || "unknown") : "";
121
+ throw new Error("Sub-agent recursion depth limit exceeded (max: ".concat(this.maxSubAgentDepth, ", current: ").concat(currentDepth, "). ") +
122
+ "This usually indicates a circular delegation loop.".concat(chainStr));
123
+ }
124
+ execContext = {
125
+ agentId: this.agentName || "unknown",
126
+ conversationId: input.conversationId,
127
+ user: input.user,
128
+ isSubAgent: ((_o = input.metadata) === null || _o === void 0 ? void 0 : _o.isSubAgentCall) === true,
129
+ parentAgentId: (_p = input.metadata) === null || _p === void 0 ? void 0 : _p.parentAgentId,
130
+ subAgentDepth: currentDepth,
131
+ metadata: input.metadata,
132
+ };
133
+ if (input.history && input.history.length > 0) {
134
+ // Start with history
135
+ messages = this.convertMessages(input.history);
136
+ }
137
+ else {
138
+ messages = [];
139
+ }
140
+ // Add new user message
141
+ if (typeof input.message === "string") {
142
+ messages.push({ role: "user", content: input.message });
143
+ }
144
+ else {
145
+ messages.push.apply(messages, this.convertMessages(input.message));
146
+ }
147
+ step = 0;
148
+ finalMessage = "";
149
+ stoppedEarly = false;
150
+ totalInputTokens = 0;
151
+ totalOutputTokens = 0;
152
+ _w.label = 1;
153
+ case 1:
154
+ if (!(step < maxSteps)) return [3 /*break*/, 57];
155
+ step++;
156
+ return [4 /*yield*/, __await(this.filterToolsByPermissions(input.user, input.userPermissions))];
157
+ case 2:
158
+ availableTools = _w.sent();
159
+ // Debug logging: Show what we're sending to the LLM
160
+ if (this.agentProps.debug) {
161
+ FlinkLog_1.log.debug("[Agent:".concat(this.agentName, "] Step ").concat(step, "/").concat(maxSteps, " - Calling LLM with:"), {
162
+ instructions: this.agentProps.instructions,
163
+ messageCount: messages.length,
164
+ messages: messages.map(function (m) { return ({
165
+ role: m.role,
166
+ contentPreview: typeof m.content === 'string'
167
+ ? m.content.substring(0, 100) + (m.content.length > 100 ? '...' : '')
168
+ : "".concat(m.content.length, " blocks"),
169
+ }); }),
170
+ toolCount: availableTools.length,
171
+ tools: availableTools.map(function (t) { return t.name; }),
172
+ maxTokens: this.maxTokens,
173
+ temperature: this.temperature,
174
+ });
175
+ }
176
+ llmStream = this.llmAdapter.stream({
177
+ instructions: this.agentProps.instructions,
178
+ messages: messages,
179
+ tools: availableTools,
180
+ maxTokens: this.maxTokens,
181
+ temperature: this.temperature,
182
+ });
183
+ textContent = "";
184
+ toolCallsFromStream = [];
185
+ usage = { inputTokens: 0, outputTokens: 0 };
186
+ stopReason = "end_turn";
187
+ _w.label = 3;
188
+ case 3:
189
+ _w.trys.push([3, 14, 15, 20]);
190
+ _a = true, llmStream_1 = (e_1 = void 0, __asyncValues(llmStream));
191
+ _w.label = 4;
192
+ case 4: return [4 /*yield*/, __await(llmStream_1.next())];
193
+ case 5:
194
+ if (!(llmStream_1_1 = _w.sent(), _g = llmStream_1_1.done, !_g)) return [3 /*break*/, 13];
195
+ _j = llmStream_1_1.value;
196
+ _a = false;
197
+ chunk = _j;
198
+ _b = chunk.type;
199
+ switch (_b) {
200
+ case "text": return [3 /*break*/, 6];
201
+ case "tool_call": return [3 /*break*/, 9];
202
+ case "usage": return [3 /*break*/, 10];
203
+ case "done": return [3 /*break*/, 11];
204
+ }
205
+ return [3 /*break*/, 12];
206
+ case 6:
207
+ textContent += chunk.delta;
208
+ return [4 /*yield*/, __await({ type: "text_delta", delta: chunk.delta })];
209
+ case 7:
210
+ // Yield text_delta event in real-time
211
+ return [4 /*yield*/, _w.sent()];
212
+ case 8:
213
+ // Yield text_delta event in real-time
214
+ _w.sent();
215
+ return [3 /*break*/, 12];
216
+ case 9:
217
+ toolCallsFromStream.push(chunk.toolCall);
218
+ return [3 /*break*/, 12];
219
+ case 10:
220
+ usage = chunk.usage;
221
+ totalInputTokens += chunk.usage.inputTokens;
222
+ totalOutputTokens += chunk.usage.outputTokens;
223
+ return [3 /*break*/, 12];
224
+ case 11:
225
+ stopReason = chunk.stopReason;
226
+ return [3 /*break*/, 12];
227
+ case 12:
228
+ _a = true;
229
+ return [3 /*break*/, 4];
230
+ case 13: return [3 /*break*/, 20];
231
+ case 14:
232
+ e_1_1 = _w.sent();
233
+ e_1 = { error: e_1_1 };
234
+ return [3 /*break*/, 20];
235
+ case 15:
236
+ _w.trys.push([15, , 18, 19]);
237
+ if (!(!_a && !_g && (_h = llmStream_1.return))) return [3 /*break*/, 17];
238
+ return [4 /*yield*/, __await(_h.call(llmStream_1))];
239
+ case 16:
240
+ _w.sent();
241
+ _w.label = 17;
242
+ case 17: return [3 /*break*/, 19];
243
+ case 18:
244
+ if (e_1) throw e_1.error;
245
+ return [7 /*endfinally*/];
246
+ case 19: return [7 /*endfinally*/];
247
+ case 20:
248
+ llmResponse = {
249
+ textContent: textContent || undefined,
250
+ toolCalls: toolCallsFromStream,
251
+ usage: usage,
252
+ stopReason: stopReason,
253
+ };
254
+ // Debug logging: Show what the LLM responded with
255
+ if (this.agentProps.debug) {
256
+ FlinkLog_1.log.debug("[Agent:".concat(this.agentName, "] Step ").concat(step, " - LLM Response:"), {
257
+ textLength: ((_q = llmResponse.textContent) === null || _q === void 0 ? void 0 : _q.length) || 0,
258
+ textPreview: ((_r = llmResponse.textContent) === null || _r === void 0 ? void 0 : _r.substring(0, 200)) + (llmResponse.textContent && llmResponse.textContent.length > 200 ? '...' : ''),
259
+ toolCallsCount: llmResponse.toolCalls.length,
260
+ toolCalls: llmResponse.toolCalls.map(function (tc) { return ({
261
+ name: tc.name,
262
+ inputKeys: Object.keys(tc.input),
263
+ input: tc.input,
264
+ }); }),
265
+ stopReason: llmResponse.stopReason,
266
+ usage: llmResponse.usage,
267
+ });
268
+ }
269
+ // Extract text response
270
+ if (llmResponse.textContent) {
271
+ finalMessage = llmResponse.textContent;
272
+ }
273
+ assistantContent = [];
274
+ if (llmResponse.textContent) {
275
+ assistantContent.push({
276
+ type: "text",
277
+ text: llmResponse.textContent,
278
+ });
279
+ }
280
+ for (_i = 0, _c = llmResponse.toolCalls; _i < _c.length; _i++) {
281
+ toolCall = _c[_i];
282
+ assistantContent.push({
283
+ type: "tool_use",
284
+ id: toolCall.id,
285
+ name: toolCall.name,
286
+ input: toolCall.input,
287
+ });
288
+ }
289
+ messages.push({
290
+ role: "assistant",
291
+ content: assistantContent,
292
+ });
293
+ if (!(llmResponse.toolCalls.length === 0)) return [3 /*break*/, 23];
294
+ if (!this.agentProps.onStep) return [3 /*break*/, 22];
295
+ stepContext = __assign(__assign({}, execContext), { step: step, maxSteps: maxSteps, messages: __spreadArray([], messages, true) });
296
+ return [4 /*yield*/, __await(this.agentProps.onStep(stepContext))];
297
+ case 21:
298
+ _w.sent();
299
+ _w.label = 22;
300
+ case 22: return [3 /*break*/, 57]; // No more tool calls - done
301
+ case 23:
302
+ toolResults = [];
303
+ _d = 0, _e = llmResponse.toolCalls;
304
+ _w.label = 24;
305
+ case 24:
306
+ if (!(_d < _e.length)) return [3 /*break*/, 54];
307
+ toolCall = _e[_d];
308
+ toolExecutor = this.tools.get(toolCall.name);
309
+ toolOutput = void 0;
310
+ toolError = void 0;
311
+ // Debug logging: Tool execution start
312
+ if (this.agentProps.debug) {
313
+ FlinkLog_1.log.debug("[Agent:".concat(this.agentName, "] Executing tool '").concat(toolCall.name, "':"), {
314
+ input: toolCall.input,
315
+ inputSize: JSON.stringify(toolCall.input).length,
316
+ });
317
+ }
318
+ _w.label = 25;
319
+ case 25:
320
+ _w.trys.push([25, 50, , 53]);
321
+ if (!toolExecutor) {
322
+ throw new Error("Tool ".concat(toolCall.name, " not found"));
323
+ }
324
+ isSubAgent = toolExecutor instanceof SubAgentExecutor_1.SubAgentExecutor ||
325
+ ((_t = (_s = toolExecutor).isSubAgentExecutor) === null || _t === void 0 ? void 0 : _t.call(_s));
326
+ if (!isSubAgent) return [3 /*break*/, 34];
327
+ subAgentId = toolExecutor.getSubAgentId();
328
+ transformedInput = toolCall.input;
329
+ if (!this.agentProps.transformSubAgentInput) return [3 /*break*/, 29];
330
+ _w.label = 26;
331
+ case 26:
332
+ _w.trys.push([26, 28, , 29]);
333
+ return [4 /*yield*/, __await(this.agentProps.transformSubAgentInput(subAgentId, toolCall.input, execContext))];
334
+ case 27:
335
+ transformedInput = _w.sent();
336
+ return [3 /*break*/, 29];
337
+ case 28:
338
+ err_1 = _w.sent();
339
+ FlinkLog_1.log.warn("transformSubAgentInput hook failed for ".concat(subAgentId, ":"), err_1.message);
340
+ return [3 /*break*/, 29];
341
+ case 29:
342
+ // Update the tool call input with transformed version
343
+ toolCall.input = transformedInput;
344
+ if (!this.agentProps.onSubAgentCall) return [3 /*break*/, 31];
345
+ return [4 /*yield*/, __await(this.agentProps.onSubAgentCall(subAgentId, transformedInput, execContext))];
346
+ case 30:
347
+ _w.sent();
348
+ _w.label = 31;
349
+ case 31: return [4 /*yield*/, __await({
350
+ type: "agent_call_start",
351
+ agentId: subAgentId,
352
+ input: transformedInput,
353
+ })];
354
+ case 32:
355
+ // Yield agent_call_start event
356
+ return [4 /*yield*/, _w.sent()];
357
+ case 33:
358
+ // Yield agent_call_start event
359
+ _w.sent();
360
+ return [3 /*break*/, 37];
361
+ case 34: return [4 /*yield*/, __await({
362
+ type: "tool_call_start",
363
+ toolCall: {
364
+ id: toolCall.id,
365
+ name: toolCall.name,
366
+ input: toolCall.input,
367
+ },
368
+ })];
369
+ case 35:
370
+ // Yield tool_call_start for regular tools
371
+ return [4 /*yield*/, _w.sent()];
372
+ case 36:
373
+ // Yield tool_call_start for regular tools
374
+ _w.sent();
375
+ _w.label = 37;
376
+ case 37:
377
+ if (!isSubAgent) return [3 /*break*/, 39];
378
+ return [4 /*yield*/, __await(toolExecutor.execute(toolCall.input, input.user, execContext, // Pass parent context to sub-agent
379
+ input.userPermissions))];
380
+ case 38:
381
+ _f = _w.sent();
382
+ return [3 /*break*/, 41];
383
+ case 39: return [4 /*yield*/, __await(toolExecutor.execute(toolCall.input, input.user, input.userPermissions))];
384
+ case 40:
385
+ _f = _w.sent();
386
+ _w.label = 41;
387
+ case 41:
388
+ toolResult = _f;
389
+ formattedResult = toolExecutor.formatResultForAI(toolResult);
390
+ toolResults.push({
391
+ type: "tool_result",
392
+ tool_use_id: toolCall.id,
393
+ content: formattedResult,
394
+ is_error: !toolResult.success,
395
+ });
396
+ if (!(isSubAgent && toolResult.success)) return [3 /*break*/, 46];
397
+ subAgentId = toolExecutor.getSubAgentId();
398
+ agentResult = toolResult.data;
399
+ // Merge token usage from sub-agent
400
+ totalInputTokens += ((_u = agentResult.usage) === null || _u === void 0 ? void 0 : _u.inputTokens) || 0;
401
+ totalOutputTokens += ((_v = agentResult.usage) === null || _v === void 0 ? void 0 : _v.outputTokens) || 0;
402
+ subAgentCalls.push({
403
+ agentId: subAgentId,
404
+ input: toolCall.input,
405
+ result: agentResult,
406
+ });
407
+ if (!this.agentProps.onSubAgentComplete) return [3 /*break*/, 43];
408
+ return [4 /*yield*/, __await(this.agentProps.onSubAgentComplete(subAgentId, agentResult, execContext))];
409
+ case 42:
410
+ _w.sent();
411
+ _w.label = 43;
412
+ case 43: return [4 /*yield*/, __await({
413
+ type: "agent_call_result",
414
+ agentId: subAgentId,
415
+ result: agentResult,
416
+ })];
417
+ case 44:
418
+ // Yield agent_call_result event
419
+ return [4 /*yield*/, _w.sent()];
420
+ case 45:
421
+ // Yield agent_call_result event
422
+ _w.sent();
423
+ return [3 /*break*/, 49];
424
+ case 46: return [4 /*yield*/, __await({
425
+ type: "tool_call_result",
426
+ toolCall: {
427
+ id: toolCall.id,
428
+ name: toolCall.name,
429
+ input: toolCall.input,
430
+ },
431
+ output: toolResult.success ? toolResult.data : null,
432
+ error: toolResult.success ? undefined : toolResult.error,
433
+ })];
434
+ case 47:
435
+ // Yield tool_call_result for regular tools
436
+ return [4 /*yield*/, _w.sent()];
437
+ case 48:
438
+ // Yield tool_call_result for regular tools
439
+ _w.sent();
440
+ _w.label = 49;
441
+ case 49:
442
+ toolCalls.push({
443
+ name: toolCall.name,
444
+ input: toolCall.input,
445
+ output: toolResult.success ? toolResult.data : null,
446
+ error: toolResult.success ? undefined : toolResult.error,
447
+ isAgentCall: isSubAgent,
448
+ agentId: isSubAgent ? toolExecutor.getSubAgentId() : undefined,
449
+ });
450
+ // Debug logging: Tool execution result
451
+ if (this.agentProps.debug) {
452
+ FlinkLog_1.log.debug("[Agent:".concat(this.agentName, "] Tool '").concat(toolCall.name, "' ").concat(toolResult.success ? 'succeeded' : 'failed', ":"), {
453
+ success: toolResult.success,
454
+ outputSize: toolResult.success ? JSON.stringify(toolResult.data).length : 0,
455
+ outputPreview: toolResult.success
456
+ ? JSON.stringify(toolResult.data).substring(0, 200) + (JSON.stringify(toolResult.data).length > 200 ? '...' : '')
457
+ : toolResult.error,
458
+ code: toolResult.code,
459
+ });
460
+ }
461
+ if (!toolResult.success) {
462
+ FlinkLog_1.log.warn("Tool ".concat(toolCall.name, " returned error:"), toolResult.error);
463
+ }
464
+ return [3 /*break*/, 53];
465
+ case 50:
466
+ err_2 = _w.sent();
467
+ // Unexpected errors (not from tool itself)
468
+ toolError = err_2.message;
469
+ return [4 /*yield*/, __await({
470
+ type: "tool_call_result",
471
+ toolCall: {
472
+ id: toolCall.id,
473
+ name: toolCall.name,
474
+ input: toolCall.input,
475
+ },
476
+ output: null,
477
+ error: toolError,
478
+ })];
479
+ case 51:
480
+ // Yield tool_call_result with error
481
+ return [4 /*yield*/, _w.sent()];
482
+ case 52:
483
+ // Yield tool_call_result with error
484
+ _w.sent();
485
+ toolResults.push({
486
+ type: "tool_result",
487
+ tool_use_id: toolCall.id,
488
+ content: "Error: ".concat(err_2.message),
489
+ is_error: true,
490
+ });
491
+ toolCalls.push({
492
+ name: toolCall.name,
493
+ input: toolCall.input,
494
+ output: null,
495
+ error: toolError,
496
+ });
497
+ FlinkLog_1.log.error("Tool ".concat(toolCall.name, " execution failed:"), err_2.message);
498
+ return [3 /*break*/, 53];
499
+ case 53:
500
+ _d++;
501
+ return [3 /*break*/, 24];
502
+ case 54:
503
+ // Add tool results to conversation
504
+ messages.push({
505
+ role: "user",
506
+ content: toolResults,
507
+ });
508
+ if (!this.agentProps.onStep) return [3 /*break*/, 56];
509
+ stepContext = __assign(__assign({}, execContext), { step: step, maxSteps: maxSteps, messages: __spreadArray([], messages, true) });
510
+ return [4 /*yield*/, __await(this.agentProps.onStep(stepContext))];
511
+ case 55:
512
+ _w.sent();
513
+ _w.label = 56;
514
+ case 56: return [3 /*break*/, 1];
515
+ case 57:
516
+ if (step >= maxSteps && toolCalls.length > 0) {
517
+ stoppedEarly = true;
518
+ FlinkLog_1.log.warn("Agent ".concat(this.agentName || "unknown", " stopped early after ").concat(maxSteps, " steps"));
519
+ }
520
+ result = {
521
+ message: finalMessage,
522
+ toolCalls: toolCalls,
523
+ stepsUsed: step,
524
+ stoppedEarly: stoppedEarly,
525
+ usage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens },
526
+ subAgentCalls: subAgentCalls.length > 0 ? subAgentCalls : undefined,
527
+ };
528
+ if (!this.agentProps.afterRun) return [3 /*break*/, 59];
529
+ finishContext = __assign(__assign({}, execContext), { messages: __spreadArray([], messages, true), result: result });
530
+ return [4 /*yield*/, __await(this.agentProps.afterRun(result, finishContext))];
531
+ case 58:
532
+ _w.sent();
533
+ _w.label = 59;
534
+ case 59: return [4 /*yield*/, __await({ type: "complete", result: result })];
535
+ case 60:
536
+ // Phase 1: Yield only complete event
537
+ // Phase 2: Will yield text_delta and tool events during loop
538
+ return [4 /*yield*/, _w.sent()];
539
+ case 61:
540
+ // Phase 1: Yield only complete event
541
+ // Phase 2: Will yield text_delta and tool events during loop
542
+ _w.sent();
543
+ return [4 /*yield*/, __await(result)];
544
+ case 62: return [2 /*return*/, _w.sent()];
545
+ }
546
+ });
547
+ });
548
+ };
549
+ /**
550
+ * Convert Message[] to LLM message format
551
+ * Supports multi-turn conversations with history
552
+ */
553
+ AgentRunner.prototype.convertMessages = function (messages) {
554
+ return messages.map(function (m) {
555
+ if (m.role === "user") {
556
+ return { role: "user", content: m.content };
557
+ }
558
+ else if (m.role === "assistant") {
559
+ return { role: "assistant", content: m.content };
560
+ }
561
+ else {
562
+ // For tool messages, convert to user message with tool result
563
+ return { role: "user", content: m.result };
564
+ }
565
+ });
566
+ };
567
+ AgentRunner.prototype.getToolSchemas = function () {
568
+ return Array.from(this.tools.values()).map(function (t) { return t.getToolSchema(); });
569
+ };
570
+ /**
571
+ * Filter tools based on user permissions
572
+ * Only returns schemas for tools the user has permission to use
573
+ *
574
+ * @param user - User object
575
+ * @param userPermissions - Optional resolved permissions from auth plugin (preferred)
576
+ */
577
+ AgentRunner.prototype.filterToolsByPermissions = function (user, userPermissions) {
578
+ return __awaiter(this, void 0, void 0, function () {
579
+ var allowedTools, toolExecutors, _i, toolExecutors_1, tool, hasPermission;
580
+ return __generator(this, function (_a) {
581
+ switch (_a.label) {
582
+ case 0:
583
+ allowedTools = [];
584
+ toolExecutors = Array.from(this.tools.values());
585
+ _i = 0, toolExecutors_1 = toolExecutors;
586
+ _a.label = 1;
587
+ case 1:
588
+ if (!(_i < toolExecutors_1.length)) return [3 /*break*/, 4];
589
+ tool = toolExecutors_1[_i];
590
+ return [4 /*yield*/, tool.checkPermissions(user, undefined, userPermissions)];
591
+ case 2:
592
+ hasPermission = _a.sent();
593
+ if (hasPermission) {
594
+ allowedTools.push(tool.getToolSchema());
595
+ }
596
+ _a.label = 3;
597
+ case 3:
598
+ _i++;
599
+ return [3 /*break*/, 1];
600
+ case 4: return [2 /*return*/, allowedTools];
601
+ }
602
+ });
603
+ });
604
+ };
605
+ /**
606
+ * Build delegation chain from metadata for error messages
607
+ * Extracts parent agent IDs to show the full call stack
608
+ */
609
+ AgentRunner.prototype.buildDelegationChain = function (metadata) {
610
+ if (!(metadata === null || metadata === void 0 ? void 0 : metadata.parentAgentId)) {
611
+ return [];
612
+ }
613
+ var chain = [];
614
+ var current = metadata;
615
+ // Walk up the parent chain
616
+ while (current === null || current === void 0 ? void 0 : current.parentAgentId) {
617
+ chain.unshift(current.parentAgentId);
618
+ // If parent metadata exists, continue walking up
619
+ current = current.parentMetadata;
620
+ }
621
+ return chain;
622
+ };
623
+ return AgentRunner;
624
+ }());
625
+ exports.AgentRunner = AgentRunner;