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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +6 -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 +346 -4
  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 +398 -7
  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,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
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);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./FlinkTool"), exports);
18
+ __exportStar(require("./FlinkAgent"), exports);
19
+ __exportStar(require("./ToolExecutor"), exports);
20
+ __exportStar(require("./AgentRunner"), exports);
21
+ __exportStar(require("./LLMAdapter"), exports);
@@ -0,0 +1,20 @@
1
+ import { Response } from "express";
2
+ import { StreamWriter, StreamFormat } from "../FlinkHttpHandler";
3
+ /**
4
+ * Factory for creating StreamWriter instances for SSE and NDJSON streaming.
5
+ *
6
+ * Handles HTTP headers, connection lifecycle, and format-specific serialization.
7
+ */
8
+ export declare class StreamWriterFactory {
9
+ /**
10
+ * Create a StreamWriter for the given format.
11
+ *
12
+ * Sets appropriate HTTP headers and manages the stream lifecycle including
13
+ * client disconnect detection.
14
+ *
15
+ * @param res - Express response object
16
+ * @param format - Stream format (sse or ndjson)
17
+ * @returns StreamWriter instance for writing data to the stream
18
+ */
19
+ static create<T = any>(res: Response, format: StreamFormat): StreamWriter<T>;
20
+ }
@@ -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;
@@ -9,4 +9,8 @@ export * from "./FlinkPlugin";
9
9
  export * from "./FlinkJob";
10
10
  export * from "./auth/FlinkAuthUser";
11
11
  export * from "./auth/FlinkAuthPlugin";
12
+ export * from "./ai/FlinkTool";
13
+ export * from "./ai/FlinkAgent";
14
+ export * from "./ai/ToolExecutor";
15
+ export * from "./ai/LLMAdapter";
12
16
  export type { Request as ExpressRequest, Response as ExpressResponse, NextFunction as ExpressNextFunction, RequestHandler as ExpressRequestHandler, ErrorRequestHandler as ExpressErrorRequestHandler, Express, static as expressStatic, } from "express";
package/dist/src/index.js CHANGED
@@ -25,3 +25,7 @@ __exportStar(require("./FlinkPlugin"), exports);
25
25
  __exportStar(require("./FlinkJob"), exports);
26
26
  __exportStar(require("./auth/FlinkAuthUser"), exports);
27
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);
@@ -12,6 +12,31 @@ export declare function getHandlerFiles(appRoot: string): Promise<string[]>;
12
12
  export declare function getSchemaFiles(appRoot: string): Promise<string[]>;
13
13
  export declare function getCollectionNameForRepo(repoFilename: string): string;
14
14
  export declare function getRepoInstanceName(fn: string): string;
15
+ /**
16
+ * Convert PascalCase or camelCase to kebab-case
17
+ *
18
+ * Examples:
19
+ * - FooBarBaz → foo-bar-baz
20
+ * - CarAgent → car-agent
21
+ * - APIAgent → api-agent
22
+ * - HTMLParser → html-parser
23
+ * - IOManager → io-manager
24
+ *
25
+ * Handles:
26
+ * - Single uppercase followed by lowercase: CarAgent → car-agent
27
+ * - Multiple consecutive uppercase: APIAgent → api-agent
28
+ * - All caps: HTML → html
29
+ */
30
+ export declare function toKebabCase(str: string): string;
31
+ /**
32
+ * Convert kebab-case to snake_case
33
+ *
34
+ * Examples:
35
+ * - car-agent → car_agent
36
+ * - api-agent → api_agent
37
+ * - html-parser → html_parser
38
+ */
39
+ export declare function toSnakeCase(str: string): string;
15
40
  /**
16
41
  * Get http method from props or convention based on file name
17
42
  * if it starts with i.e "GetFoo"
@@ -37,3 +62,8 @@ export declare function getDataAtPath(data: any, instancePath: string): any;
37
62
  * @param maxDataLength Maximum length of data to show (default 500)
38
63
  */
39
64
  export declare function formatValidationErrors(errors: any[] | null | undefined, data: any, maxDataLength?: number): string;
65
+ /**
66
+ * Generate a short random ID for nested conversations
67
+ * Format: 8 character alphanumeric string (e.g., "a3b7c9d2")
68
+ */
69
+ export declare function generateShortId(): string;
package/dist/src/utils.js CHANGED
@@ -47,11 +47,14 @@ exports.getHandlerFiles = getHandlerFiles;
47
47
  exports.getSchemaFiles = getSchemaFiles;
48
48
  exports.getCollectionNameForRepo = getCollectionNameForRepo;
49
49
  exports.getRepoInstanceName = getRepoInstanceName;
50
+ exports.toKebabCase = toKebabCase;
51
+ exports.toSnakeCase = toSnakeCase;
50
52
  exports.getHttpMethodFromHandlerName = getHttpMethodFromHandlerName;
51
53
  exports.getJsDocComment = getJsDocComment;
52
54
  exports.getPathParams = getPathParams;
53
55
  exports.getDataAtPath = getDataAtPath;
54
56
  exports.formatValidationErrors = formatValidationErrors;
57
+ exports.generateShortId = generateShortId;
55
58
  var path_1 = require("path");
56
59
  var tiny_glob_1 = __importDefault(require("tiny-glob"));
57
60
  var FlinkHttpHandler_1 = require("./FlinkHttpHandler");
@@ -122,6 +125,43 @@ function getRepoInstanceName(fn) {
122
125
  var name = fn.split(".ts")[0];
123
126
  return name.charAt(0).toLowerCase() + name.substr(1);
124
127
  }
128
+ /**
129
+ * Convert PascalCase or camelCase to kebab-case
130
+ *
131
+ * Examples:
132
+ * - FooBarBaz → foo-bar-baz
133
+ * - CarAgent → car-agent
134
+ * - APIAgent → api-agent
135
+ * - HTMLParser → html-parser
136
+ * - IOManager → io-manager
137
+ *
138
+ * Handles:
139
+ * - Single uppercase followed by lowercase: CarAgent → car-agent
140
+ * - Multiple consecutive uppercase: APIAgent → api-agent
141
+ * - All caps: HTML → html
142
+ */
143
+ function toKebabCase(str) {
144
+ return str
145
+ // Insert hyphen before uppercase letters that follow lowercase letters
146
+ // CarAgent → Car-Agent
147
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
148
+ // Insert hyphen before uppercase letter that follows uppercase and precedes lowercase
149
+ // APIAgent → API-Agent
150
+ .replace(/([A-Z])([A-Z][a-z])/g, "$1-$2")
151
+ // Convert to lowercase
152
+ .toLowerCase();
153
+ }
154
+ /**
155
+ * Convert kebab-case to snake_case
156
+ *
157
+ * Examples:
158
+ * - car-agent → car_agent
159
+ * - api-agent → api_agent
160
+ * - html-parser → html_parser
161
+ */
162
+ function toSnakeCase(str) {
163
+ return str.replace(/-/g, "_");
164
+ }
125
165
  /**
126
166
  * Get http method from props or convention based on file name
127
167
  * if it starts with i.e "GetFoo"
@@ -236,3 +276,15 @@ function formatValidationErrors(errors, data, maxDataLength) {
236
276
  });
237
277
  return formatted.join("\n");
238
278
  }
279
+ /**
280
+ * Generate a short random ID for nested conversations
281
+ * Format: 8 character alphanumeric string (e.g., "a3b7c9d2")
282
+ */
283
+ function generateShortId() {
284
+ var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
285
+ var result = "";
286
+ for (var i = 0; i < 8; i++) {
287
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
288
+ }
289
+ return result;
290
+ }
package/package.json CHANGED
@@ -1,9 +1,19 @@
1
1
  {
2
2
  "name": "@flink-app/flink",
3
- "version": "1.0.0",
3
+ "version": "2.0.0-alpha.48",
4
4
  "description": "Typescript only framework for creating REST-like APIs on top of Express and mongodb",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "main": "dist/src/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/src/index.d.ts",
10
+ "default": "./dist/src/index.js"
11
+ },
12
+ "./ai": {
13
+ "types": "./dist/src/ai/index.d.ts",
14
+ "default": "./dist/src/ai/index.js"
15
+ }
16
+ },
7
17
  "repository": "FrostDigital/flink",
8
18
  "bin": {
9
19
  "flink": "./dist/bin/flink.js"
@@ -41,7 +51,9 @@
41
51
  "toad-scheduler": "^2.2.0",
42
52
  "ts-json-schema-generator": "2.3.0",
43
53
  "ts-morph": "24.0.0",
44
- "uuid": "^8.3.2"
54
+ "uuid": "^8.3.2",
55
+ "zod": "^4.3.6",
56
+ "zod-to-json-schema": "^3.25.1"
45
57
  },
46
58
  "devDependencies": {
47
59
  "@types/folder-hash": "^4.0.0",