@flink-app/flink 2.0.0-alpha.56 → 2.0.0-alpha.58

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 (204) hide show
  1. package/CHANGELOG.md +568 -0
  2. package/SCHEMA_EXTRACTION_ANALYSIS.md +494 -0
  3. package/SIMPLE_AST_FEASIBILITY.md +570 -0
  4. package/bin/flink.ts +13 -2
  5. package/cli/build.ts +24 -51
  6. package/cli/clean.ts +13 -25
  7. package/cli/cli-utils.ts +188 -17
  8. package/cli/dev.ts +212 -0
  9. package/cli/run.ts +36 -74
  10. package/dist/bin/flink.js +61 -2
  11. package/dist/cli/build.js +20 -32
  12. package/dist/cli/clean.js +12 -10
  13. package/dist/cli/cli-utils.d.ts +34 -3
  14. package/dist/cli/cli-utils.js +187 -12
  15. package/dist/cli/dev.d.ts +2 -0
  16. package/dist/cli/dev.js +243 -0
  17. package/dist/cli/run.js +35 -52
  18. package/dist/src/DependencyTracker.d.ts +44 -0
  19. package/dist/src/DependencyTracker.js +239 -0
  20. package/dist/src/FlinkApp.d.ts +46 -2
  21. package/dist/src/FlinkApp.js +367 -146
  22. package/dist/src/FlinkHttpHandler.d.ts +47 -17
  23. package/dist/src/FlinkLog.d.ts +82 -18
  24. package/dist/src/FlinkLog.js +165 -13
  25. package/dist/src/FlinkLogFactory.d.ts +288 -0
  26. package/dist/src/FlinkLogFactory.js +619 -0
  27. package/dist/src/FlinkRequestContext.d.ts +63 -0
  28. package/dist/src/FlinkRequestContext.js +74 -0
  29. package/dist/src/SchemaCache.d.ts +84 -0
  30. package/dist/src/SchemaCache.js +289 -0
  31. package/dist/src/TypeScriptCompiler.d.ts +100 -63
  32. package/dist/src/TypeScriptCompiler.js +949 -847
  33. package/dist/src/ai/AgentRunner.d.ts +2 -11
  34. package/dist/src/ai/AgentRunner.js +249 -263
  35. package/dist/src/ai/ConversationAgent.d.ts +279 -0
  36. package/dist/src/ai/ConversationAgent.js +402 -0
  37. package/dist/src/ai/ConversationFlinkAgent.d.ts +278 -0
  38. package/dist/src/ai/ConversationFlinkAgent.js +404 -0
  39. package/dist/src/ai/FlinkAgent.d.ts +186 -98
  40. package/dist/src/ai/FlinkAgent.js +140 -75
  41. package/dist/src/ai/FlinkTool.d.ts +100 -2
  42. package/dist/src/ai/InMemoryConversationAgent.d.ts +121 -0
  43. package/dist/src/ai/InMemoryConversationAgent.js +209 -0
  44. package/dist/src/ai/LLMAdapter.d.ts +33 -4
  45. package/dist/src/ai/PersistentFlinkAgent.d.ts +278 -0
  46. package/dist/src/ai/PersistentFlinkAgent.js +403 -0
  47. package/dist/src/ai/SubAgentExecutor.d.ts +5 -3
  48. package/dist/src/ai/SubAgentExecutor.js +14 -11
  49. package/dist/src/ai/ToolExecutor.d.ts +24 -8
  50. package/dist/src/ai/ToolExecutor.js +268 -82
  51. package/dist/src/ai/agentInstructions.d.ts +68 -0
  52. package/dist/src/ai/agentInstructions.js +246 -0
  53. package/dist/src/ai/index.d.ts +3 -0
  54. package/dist/src/ai/index.js +5 -0
  55. package/dist/src/index.d.ts +7 -0
  56. package/dist/src/index.js +10 -0
  57. package/dist/src/loadPluginSchemas.d.ts +45 -0
  58. package/dist/src/loadPluginSchemas.js +143 -0
  59. package/dist/src/schema-extraction/ComplexTypeDetection.d.ts +40 -0
  60. package/dist/src/schema-extraction/ComplexTypeDetection.js +75 -0
  61. package/dist/src/schema-extraction/TypeScriptSourceParser.d.ts +307 -0
  62. package/dist/src/schema-extraction/TypeScriptSourceParser.js +858 -0
  63. package/dist/src/schema-extraction/TypeScriptSourceParser.spec.d.ts +1 -0
  64. package/dist/src/schema-extraction/TypeScriptSourceParser.spec.js +233 -0
  65. package/dist/src/schema-extraction/TypeScriptTokenizer.d.ts +57 -0
  66. package/dist/src/schema-extraction/TypeScriptTokenizer.js +177 -0
  67. package/dist/src/schema-extraction/index.d.ts +2 -0
  68. package/dist/src/schema-extraction/index.js +20 -0
  69. package/dist/src/schema-extraction/types.d.ts +31 -0
  70. package/dist/src/schema-extraction/types.js +2 -0
  71. package/dist/src/utils/loadFlinkConfig.d.ts +29 -0
  72. package/dist/src/utils/loadFlinkConfig.js +77 -0
  73. package/examples/logging-hierarchical-example.ts +125 -0
  74. package/package.json +14 -4
  75. package/readme.md +74 -0
  76. package/spec/AgentDescendantDetection.spec.ts +335 -0
  77. package/spec/AgentRunner.spec.ts +343 -61
  78. package/spec/AsyncLocalStorageContext.spec.ts +223 -0
  79. package/spec/ConversationHooks.spec.ts +5 -38
  80. package/spec/FlinkAgent.spec.ts +183 -2
  81. package/spec/FlinkApp.htmlResponse.spec.ts +131 -0
  82. package/spec/FlinkLogFactory.spec.ts +337 -0
  83. package/spec/StreamingIntegration.spec.ts +1 -0
  84. package/spec/ToolExecutor.spec.ts +14 -22
  85. package/spec/TypeScriptCompiler.spec.ts +1 -1
  86. package/spec/TypeScriptSourceParser.spec.ts +1079 -0
  87. package/spec/TypeScriptTokenizer.spec.ts +366 -0
  88. package/spec/ai/ContextCompaction.spec.ts +405 -0
  89. package/spec/ai/ConversationAgent.spec.ts +491 -0
  90. package/spec/ai/InMemoryConversationAgent.spec.ts +144 -0
  91. package/spec/ai/agentInstructions.spec.ts +338 -0
  92. package/spec/fixtures/agent-instructions/TestAgent.ts +22 -0
  93. package/spec/fixtures/agent-instructions/simple.md +3 -0
  94. package/spec/fixtures/agent-instructions/template.md +18 -0
  95. package/spec/fixtures/agent-instructions/yaml-format.yaml +9 -0
  96. package/spec/mock-project/dist/.tsbuildinfo +1 -0
  97. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar.js +2 -3
  98. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar2.js +1 -2
  99. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema.js +1 -2
  100. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema2.js +1 -2
  101. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema3.js +1 -2
  102. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema.js +1 -2
  103. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema2.js +1 -2
  104. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile.js +1 -2
  105. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile2.js +1 -2
  106. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchCar.js +1 -2
  107. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOnboardingSession.js +1 -2
  108. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.js +1 -2
  109. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchProductWithIntersection.js +1 -2
  110. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchUserWithUnion.js +1 -2
  111. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostCar.js +1 -2
  112. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogin.js +1 -2
  113. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogout.js +1 -2
  114. package/spec/mock-project/dist/spec/mock-project/src/handlers/PutCar.js +1 -2
  115. package/spec/mock-project/dist/src/FlinkApp.js +95 -107
  116. package/spec/mock-project/dist/src/FlinkLog.js +94 -1
  117. package/spec/mock-project/dist/src/FlinkLogFactory.js +617 -0
  118. package/spec/mock-project/dist/src/FlinkRequestContext.js +74 -0
  119. package/spec/mock-project/dist/src/ai/AgentRunner.js +249 -263
  120. package/spec/mock-project/dist/src/ai/ConversationAgent.js +402 -0
  121. package/spec/mock-project/dist/src/ai/ConversationFlinkAgent.js +422 -0
  122. package/spec/mock-project/dist/src/ai/FlinkAgent.js +140 -75
  123. package/spec/mock-project/dist/src/ai/InMemoryConversationAgent.js +209 -0
  124. package/spec/mock-project/dist/src/ai/SubAgentExecutor.js +13 -10
  125. package/spec/mock-project/dist/src/ai/ToolExecutor.js +234 -82
  126. package/spec/mock-project/dist/src/ai/agentInstructions.js +246 -0
  127. package/spec/mock-project/dist/src/handlers/GetCar.js +26 -52
  128. package/spec/mock-project/dist/src/handlers/GetCar.js.map +1 -0
  129. package/spec/mock-project/dist/src/handlers/GetCar2.js +32 -54
  130. package/spec/mock-project/dist/src/handlers/GetCar2.js.map +1 -0
  131. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +26 -48
  132. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js.map +1 -0
  133. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +28 -48
  134. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js.map +1 -0
  135. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +29 -48
  136. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js.map +1 -0
  137. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +26 -50
  138. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js.map +1 -0
  139. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +28 -50
  140. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js.map +1 -0
  141. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +27 -53
  142. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js.map +1 -0
  143. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +29 -53
  144. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js.map +1 -0
  145. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +16 -49
  146. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js.map +1 -0
  147. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +25 -50
  148. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js.map +1 -0
  149. package/spec/mock-project/dist/src/handlers/PatchCar.js +27 -53
  150. package/spec/mock-project/dist/src/handlers/PatchCar.js.map +1 -0
  151. package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js +44 -70
  152. package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js.map +1 -0
  153. package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js +27 -53
  154. package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js.map +1 -0
  155. package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js +28 -54
  156. package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js.map +1 -0
  157. package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js +28 -54
  158. package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js.map +1 -0
  159. package/spec/mock-project/dist/src/handlers/PostCar.js +24 -50
  160. package/spec/mock-project/dist/src/handlers/PostCar.js.map +1 -0
  161. package/spec/mock-project/dist/src/handlers/PostLogin.js +25 -51
  162. package/spec/mock-project/dist/src/handlers/PostLogin.js.map +1 -0
  163. package/spec/mock-project/dist/src/handlers/PostLogout.js +24 -50
  164. package/spec/mock-project/dist/src/handlers/PostLogout.js.map +1 -0
  165. package/spec/mock-project/dist/src/handlers/PutCar.js +24 -50
  166. package/spec/mock-project/dist/src/handlers/PutCar.js.map +1 -0
  167. package/spec/mock-project/dist/src/index.js +57 -29
  168. package/spec/mock-project/dist/src/index.js.map +1 -0
  169. package/spec/mock-project/dist/src/repos/CarRepo.js +12 -24
  170. package/spec/mock-project/dist/src/repos/CarRepo.js.map +1 -0
  171. package/spec/mock-project/dist/src/schemas/Car.js +3 -1
  172. package/spec/mock-project/dist/src/schemas/Car.js.map +1 -0
  173. package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js +3 -1
  174. package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js.map +1 -0
  175. package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js +3 -1
  176. package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js.map +1 -0
  177. package/spec/schema-generation-nested-objects.spec.ts +97 -0
  178. package/spec/utils.caseConversion.spec.ts +4 -6
  179. package/src/DependencyTracker.ts +166 -0
  180. package/src/FlinkApp.ts +439 -151
  181. package/src/FlinkHttpHandler.ts +50 -18
  182. package/src/FlinkLog.ts +119 -12
  183. package/src/FlinkLogFactory.ts +699 -0
  184. package/src/FlinkRequestContext.ts +95 -0
  185. package/src/SchemaCache.ts +232 -0
  186. package/src/TypeScriptCompiler.ts +908 -787
  187. package/src/ai/AgentRunner.ts +492 -519
  188. package/src/ai/ConversationAgent.ts +411 -0
  189. package/src/ai/FlinkAgent.ts +269 -156
  190. package/src/ai/FlinkTool.ts +129 -4
  191. package/src/ai/InMemoryConversationAgent.ts +149 -0
  192. package/src/ai/LLMAdapter.ts +31 -1
  193. package/src/ai/ToolExecutor.ts +286 -67
  194. package/src/ai/agentInstructions.ts +199 -0
  195. package/src/ai/index.ts +3 -0
  196. package/src/index.ts +7 -0
  197. package/src/loadPluginSchemas.ts +141 -0
  198. package/src/schema-extraction/TypeScriptSourceParser.ts +980 -0
  199. package/src/schema-extraction/TypeScriptTokenizer.ts +205 -0
  200. package/src/schema-extraction/index.ts +2 -0
  201. package/src/schema-extraction/types.ts +34 -0
  202. package/src/utils/loadFlinkConfig.ts +64 -0
  203. package/spec/SubAgentSupport.spec.ts +0 -955
  204. package/src/ai/SubAgentExecutor.ts +0 -199
package/CHANGELOG.md CHANGED
@@ -1,5 +1,573 @@
1
1
  # @flink-app/flink
2
2
 
3
+ ## 2.0.0-alpha.58
4
+
5
+ ### Patch Changes
6
+
7
+ - Move @flink-app/ts-source-to-json-schema to dependencies (was incorrectly in devDependencies) and make @swc/core an optional peer dependency with graceful fallback to tsc
8
+
9
+ ## 2.0.0-alpha.57
10
+
11
+ ### Minor Changes
12
+
13
+ - ef7f495: Add AsyncLocalStorage for automatic user/permissions injection in tools
14
+
15
+ **New Features:**
16
+
17
+ - Tools now receive `user` and `permissions` parameters automatically from AsyncLocalStorage
18
+ - Declarative permissions in tool definitions - framework checks before execution
19
+ - No more need for explicit `agent.withUser()` bindings
20
+ - Context flows automatically: handler → agent → tools
21
+
22
+ **API Changes:**
23
+
24
+ - `ToolExecutor.execute()` signature: `(input, overrides?)` instead of `(input, user?, permissions?)`
25
+ - `FlinkTool` handler signature includes `user?` and `permissions?` parameters
26
+ - Permission checking supports explicit permissions without requiring user object
27
+
28
+ **Testing:**
29
+
30
+ - New test utilities: `withRequestContext()`, `createMockUser()`, `createMockRequestContext()`
31
+ - Override support for unit testing: `execute(input, { user, permissions })`
32
+ - 13 new AsyncLocalStorage integration tests
33
+
34
+ **Developer Experience:**
35
+
36
+ ```typescript
37
+ // Before: Manual user passing
38
+ await agent.withUser(req.user).execute({ message: "..." });
39
+
40
+ // After: Automatic context flow
41
+ await agent.execute({ message: "..." });
42
+
43
+ // Tools with declarative permissions
44
+ export const Tool: FlinkToolProps = {
45
+ permissions: ["car:read"], // ✨ Checked by framework
46
+ };
47
+
48
+ const handler: FlinkTool<Ctx, In, Out> = async ({
49
+ input,
50
+ ctx,
51
+ user,
52
+ permissions, // ✨ Auto-injected
53
+ }) => {
54
+ // Permission already verified - just implement logic
55
+ };
56
+ ```
57
+
58
+ - 2d53aa4: feat: automatic schema derivation for FlinkTools
59
+
60
+ FlinkTools now support automatic schema generation from TypeScript type parameters, eliminating the need for manual Zod or JSON Schema definitions.
61
+
62
+ **New Features:**
63
+
64
+ - Auto-generate input/output schemas from `FlinkTool<Ctx, Input, Output>` type parameters
65
+ - Support for TypeScript interfaces, inline types, and primitive types
66
+ - Three-tier validation precedence: Manual Zod > Manual JSON > Auto-generated
67
+ - Automatic ToolResult unwrapping (extracts `T` from `ToolResult<T>`)
68
+
69
+ **Breaking Changes:** None - fully backward compatible with existing tools
70
+
71
+ **Migration:**
72
+
73
+ ```typescript
74
+ // Before (manual schemas required)
75
+ export const Tool: FlinkToolProps = {
76
+ id: "search-cars",
77
+ description: "Search for cars",
78
+ inputSchema: z.object({ brand: z.string() }),
79
+ outputSchema: z.string(),
80
+ };
81
+
82
+ const SearchTool: FlinkTool<AppCtx, z.infer<typeof Tool.inputSchema>, z.infer<typeof Tool.outputSchema>> = async ({ input }) => {
83
+ return { success: true, data: "result" };
84
+ };
85
+
86
+ // After (schemas auto-generated from types)
87
+ interface SearchInput {
88
+ brand: string;
89
+ }
90
+
91
+ export const Tool: FlinkToolProps = {
92
+ id: "search-cars",
93
+ description: "Search for cars",
94
+ // No schemas needed!
95
+ };
96
+
97
+ const SearchTool: FlinkTool<AppCtx, SearchInput, string> = async ({ input }) => {
98
+ return { success: true, data: "result" };
99
+ };
100
+ ```
101
+
102
+ **Technical Details:**
103
+
104
+ - Schemas extracted during TypeScript compilation via ts-morph
105
+ - JSON schemas generated via ts-json-schema-generator
106
+ - `__schemas` export automatically added to tool source files
107
+ - JSDoc comments preserved in generated schemas
108
+
109
+ - b3cc5d1: feat(ai): add comprehensive cache metrics support for token usage tracking
110
+
111
+ ## Overview
112
+
113
+ Added detailed cache metrics to LLM adapters for better cost optimization and performance tracking. Both OpenAI and Anthropic adapters now capture and expose cache-related token counts.
114
+
115
+ ## What's New
116
+
117
+ ### LLMUsage Interface
118
+
119
+ - New `LLMUsage` interface with cache-related fields:
120
+ - `cachedInputTokens`: Tokens served from cache (lower cost)
121
+ - `cacheCreationInputTokens`: Tokens written to cache (Anthropic only, higher cost)
122
+
123
+ ### OpenAI Adapter
124
+
125
+ - Captures `cached_tokens` from `input_tokens_details`
126
+ - Provides 10% cost savings for cached tokens
127
+ - Includes cache metrics in usage logs
128
+
129
+ ### Anthropic Adapter
130
+
131
+ - Captures `cache_read_input_tokens` (10% cost)
132
+ - Captures `cache_creation_input_tokens` (125% cost)
133
+ - Full visibility into cache economics
134
+
135
+ ### AgentRunner
136
+
137
+ - Automatically aggregates cache metrics across multi-turn conversations
138
+ - Includes cache data in sub-agent call tracking
139
+ - Available in `AgentExecuteResult.usage`
140
+
141
+ ## Cache Economics
142
+
143
+ **OpenAI:**
144
+
145
+ - Cached tokens: ~10% of regular token cost
146
+ - Significant savings for repeated context
147
+
148
+ **Anthropic:**
149
+
150
+ - Cache read: 10% of regular token cost
151
+ - Cache write: 125% of regular token cost (one-time cost, then 10% on reads)
152
+ - Minimum cache threshold: 2048 tokens
153
+
154
+ ## Example Usage
155
+
156
+ ```typescript
157
+ const result = await agent.execute({ message: "Hello" });
158
+
159
+ console.log(result.usage);
160
+ // {
161
+ // inputTokens: 2006,
162
+ // outputTokens: 300,
163
+ // cachedInputTokens: 1920, // 95% cache hit!
164
+ // }
165
+
166
+ // Calculate actual billed input tokens
167
+ const billedTokens = result.usage.inputTokens - (result.usage.cachedInputTokens || 0);
168
+ console.log(`Only ${billedTokens} tokens charged at full rate`);
169
+ ```
170
+
171
+ ## Breaking Changes
172
+
173
+ None - all cache fields are optional and backwards compatible.
174
+
175
+ - d377fac: Add context compaction feature for automatic message history management in agents
176
+
177
+ Agents can now automatically manage message history size during long-running conversations using two new optional callbacks: `shouldCompact` and `compactHistory`. This prevents context window overflow and helps control token costs.
178
+
179
+ Features:
180
+
181
+ - `shouldCompact` callback to determine when compaction is needed (message count, size, token estimation, or custom logic)
182
+ - `compactHistory` callback to perform the actual compaction (sliding window, keep first+last, summarization, or custom strategy)
183
+ - Default compaction strategy (keep last 10 messages) when only `shouldCompact` is provided
184
+ - Async support for both callbacks
185
+ - Comprehensive error handling - failures are logged but don't break execution
186
+ - Debug logging to monitor compaction events
187
+ - Compaction occurs before each LLM call in the agentic loop
188
+
189
+ Example usage:
190
+
191
+ ```typescript
192
+ export default class ChatAgent extends FlinkAgent<AppCtx> {
193
+ id = "chat-agent";
194
+ description = "Chat assistant with history management";
195
+ instructions = "You are a helpful assistant...";
196
+
197
+ // Compact when history exceeds 20 messages
198
+ shouldCompact = (messages, step) => messages.length > 20;
199
+
200
+ // Keep only last 10 messages
201
+ compactHistory = (messages, step) => messages.slice(-10);
202
+ }
203
+ ```
204
+
205
+ This is a fully opt-in feature with no impact on existing agents.
206
+
207
+ - 90f80c7: Add `responseType` route option for non-JSON responses
208
+
209
+ Set `responseType` in `RouteProps` to send the handler's `data` field as a raw
210
+ response with the given content type instead of the standard JSON envelope.
211
+ Response schema validation is automatically skipped.
212
+
213
+ Accepts Express shorthand names (`"html"`, `"csv"`, `"text"`, `"xml"`) or any
214
+ full MIME type string.
215
+
216
+ ```typescript
217
+ export const Route: RouteProps = {
218
+ path: "/dashboard",
219
+ responseType: "html",
220
+ };
221
+
222
+ const handler: GetHandler<Ctx, void> = async ({ ctx }) => {
223
+ return {
224
+ data: `<!DOCTYPE html><html><body><h1>Dashboard</h1></body></html>`,
225
+ };
226
+ };
227
+
228
+ export default handler;
229
+ ```
230
+
231
+ ```typescript
232
+ export const Route: RouteProps = {
233
+ path: "/export",
234
+ responseType: "csv",
235
+ };
236
+
237
+ const handler: GetHandler<Ctx, void> = async ({ ctx }) => {
238
+ return { data: `id,name\n1,Alice\n2,Bob` };
239
+ };
240
+
241
+ export default handler;
242
+ ```
243
+
244
+ - f0887e7: feat: simplified conversation persistence with InMemoryConversationAgent
245
+
246
+ **New Features:**
247
+
248
+ 1. **ConversationAgent Base Class** - Abstract base class for automatic conversation persistence:
249
+
250
+ ```typescript
251
+ export default class ChatAgent extends ConversationAgent<AppContext> {
252
+ id = "chat-agent";
253
+ description = "Chat assistant with automatic persistence";
254
+ instructions = "You are a helpful assistant...";
255
+ tools = ["search-knowledge"];
256
+
257
+ protected async loadConversation(conversationId: string) {
258
+ const conv = await this.ctx.repos.conversationRepo.getById(conversationId);
259
+ return conv
260
+ ? {
261
+ messages: conv.messages,
262
+ providerMetadata: conv.providerMetadata,
263
+ }
264
+ : null;
265
+ }
266
+
267
+ protected async saveConversation(conversationId: string, data: ConversationData) {
268
+ await this.ctx.repos.conversationRepo.upsert({
269
+ _id: conversationId,
270
+ messages: data.messages,
271
+ providerMetadata: data.providerMetadata,
272
+ });
273
+ }
274
+ }
275
+ ```
276
+
277
+ 2. **InMemoryConversationAgent** - Opinionated convenience class for rapid prototyping:
278
+
279
+ ```typescript
280
+ export default class MyAgent extends InMemoryConversationAgent<AppContext> {
281
+ id = "my-agent";
282
+ description = "Quick prototype agent";
283
+ instructions = "You are a helpful assistant...";
284
+ tools = ["search-knowledge"];
285
+ // That's it! Storage already implemented
286
+ }
287
+
288
+ // Testing utilities
289
+ InMemoryConversationAgent.clearAll();
290
+ InMemoryConversationAgent.getConversationCount();
291
+ InMemoryConversationAgent.getAllConversationIds();
292
+ ```
293
+
294
+ 3. **Provider Metadata Tracking** - Framework preserves provider-specific metadata:
295
+
296
+ ```typescript
297
+ const result = await agent.execute({
298
+ message: "Hello",
299
+ conversationId: "conv-123",
300
+ }).result;
301
+
302
+ // Metadata preserved for debugging/future use
303
+ console.log(result.providerMetadata); // { openai: { ... } }
304
+ ```
305
+
306
+ **Simplified Architecture:**
307
+
308
+ Removed persistence strategies in favor of always sending full conversation history:
309
+
310
+ - ❌ Removed: `ConversationPersistenceStrategy` type ("auto" | "provider-optimized" | "full-history")
311
+ - ❌ Removed: `persistenceStrategy` property from ConversationAgent
312
+ - ❌ Removed: `persistenceStrategy` parameter from LLMAdapter.stream()
313
+ - ❌ Removed: OpenAI's previousResponseId optimization and instruction hashing
314
+ - ✅ Kept: Provider metadata preservation (for tracking/debugging/future use)
315
+ - ✅ Kept: Full conversation history always sent for reliability
316
+
317
+ **Benefits:**
318
+
319
+ - **Simplicity**: Single code path, easier to understand and maintain
320
+ - **Reliability**: No optimization edge cases or hybrid logic bugs
321
+ - **Debuggability**: Full conversation history always available
322
+ - **Rapid Prototyping**: InMemoryConversationAgent removes boilerplate
323
+ - **Future-Proof**: Can re-introduce optimizations with different architecture if needed
324
+
325
+ **Breaking Changes:**
326
+
327
+ For LLM Adapter Implementers:
328
+
329
+ - Must remove `persistenceStrategy` parameter from `stream()` method signature
330
+
331
+ For Agent Users (Optional Cleanup):
332
+
333
+ - Remove `persistenceStrategy` property from ConversationAgent subclasses (no longer used)
334
+ - Remove `persistenceStrategy` from execute options (no longer supported)
335
+
336
+ **Migration:**
337
+
338
+ Existing ConversationAgent implementations continue to work - just remove any `persistenceStrategy` references:
339
+
340
+ ```typescript
341
+ // Before
342
+ export default class MyAgent extends ConversationAgent<AppContext> {
343
+ persistenceStrategy = "full-history"; // ❌ Remove this
344
+
345
+ protected async loadConversation(conversationId: string) { ... }
346
+ protected async saveConversation(conversationId: string, data: ConversationData) { ... }
347
+ }
348
+
349
+ // After
350
+ export default class MyAgent extends ConversationAgent<AppContext> {
351
+ // ✅ Just implement storage methods
352
+ protected async loadConversation(conversationId: string) { ... }
353
+ protected async saveConversation(conversationId: string, data: ConversationData) { ... }
354
+ }
355
+ ```
356
+
357
+ For rapid prototyping, use InMemoryConversationAgent instead:
358
+
359
+ ```typescript
360
+ // New option: Zero boilerplate
361
+ export default class MyAgent extends InMemoryConversationAgent<AppContext> {
362
+ id = "my-agent";
363
+ description = "Quick prototype";
364
+ instructions = "...";
365
+ tools = [];
366
+ // Storage already implemented!
367
+ }
368
+ ```
369
+
370
+ - 68c46d3: feat(logging): add Java-style hierarchical prefix matching for component logging
371
+
372
+ Introduces hierarchical prefix matching inspired by Java logging frameworks (Log4j, Logback):
373
+
374
+ **Key Features:**
375
+
376
+ - **Dot notation**: `flink.ai.openai` (like Java packages)
377
+ - **Lowercase naming**: All logger names normalized to lowercase
378
+ - **Case-insensitive**: `Flink.AI.OpenAI` → `flink.ai.openai`
379
+ - **Hierarchical matching**: `flink.ai` matches all `flink.ai.*` loggers
380
+ - **Precedence**: More specific configs override less specific (Java inheritance)
381
+
382
+ **Usage:**
383
+
384
+ Environment variables:
385
+
386
+ ```bash
387
+ # Simple hierarchical config (recommended)
388
+ LOG_LEVELS=flink.ai:debug,flink.database:warn
389
+
390
+ # Fine-grained overrides
391
+ LOG_LEVELS=flink.ai:debug,flink.ai.openai:trace
392
+
393
+ # Wildcard patterns (advanced)
394
+ LOG_LEVELS=flink.ai.*:debug,flink.database.**:warn
395
+ ```
396
+
397
+ Programmatic API:
398
+
399
+ ```typescript
400
+ // Hierarchical prefix (Java-style)
401
+ FlinkLogFactory.setHierarchicalLevel("flink.ai", "debug");
402
+
403
+ // Exact match
404
+ FlinkLogFactory.setComponentLevel("flink.ai.openai", "trace");
405
+
406
+ // Wildcard pattern
407
+ FlinkLogFactory.setWildcardLevel("flink.database.*", "warn");
408
+
409
+ // Get effective level
410
+ FlinkLogFactory.getEffectiveLevel("flink.ai.openai"); // "trace"
411
+ ```
412
+
413
+ **Breaking Changes:**
414
+
415
+ - None - fully backward compatible with existing exact match configurations
416
+
417
+ **Migration:**
418
+ Existing logger names can be migrated to dot notation for hierarchical matching:
419
+
420
+ ```typescript
421
+ // Before: FlinkLogFactory.createLogger("OpenAI")
422
+ // After: FlinkLogFactory.createLogger("flink.ai.openai")
423
+ ```
424
+
425
+ - ### `flink dev` - Fast development mode with SWC
426
+
427
+ - Add `flink dev` command with fast watch mode using SWC for near-instant recompilation
428
+ - Migrate compilation from `ts.emit()` to SWC for ~20x faster builds
429
+ - Add background `tsc --watch` for async type checking during dev mode
430
+ - Add build timing logs for performance visibility
431
+
432
+ ### Logging configuration via `flink.config.js`
433
+
434
+ - Add support for `flink.config.js` configuration file for logging setup
435
+ - Refactor `FlinkLogFactory` for simpler log export and configuration
436
+
437
+ ### Plugin handler JSON schema support
438
+
439
+ - Add direct JSON schema support for plugin handlers via `inputJsonSchema`/`outputJsonSchema`
440
+ - Allows plugins (generic-auth, management-api) to define handler schemas without TypeScript type extraction
441
+
442
+ ### CLI improvements
443
+
444
+ - Fix tsc binary resolution by walking up directory tree (monorepo support)
445
+ - Put tsc watch buildinfo in `.flink/` instead of project root
446
+ - Extract shared CLI utilities and deduplicate compiler pipeline
447
+
448
+ ### Compiler fixes
449
+
450
+ - Fix void/any type handling in schema extraction
451
+ - Use project source files for SWC emit instead of disk globs
452
+ - Move `__file` metadata to registration objects instead of source files
453
+
454
+ ### `create-flink-app` updates
455
+
456
+ - Modernize default template with `flink dev` and `flink.config.js` logging config
457
+
458
+ ### Patch Changes
459
+
460
+ - 4ad44c0: fix: preserve assistant messages in conversation history
461
+
462
+ Fixed critical bugs where assistant messages were being filtered out:
463
+
464
+ **Core Framework Fix:**
465
+
466
+ - `AgentRunner.convertMessages()` now properly converts `toolCalls` array to `LLMContentBlock[]` format
467
+ - Assistant messages with tool calls are preserved with correct content block structure
468
+
469
+ **OpenAI Adapter Fix:**
470
+
471
+ - Removed incorrect code that was skipping assistant text messages
472
+ - OpenAI Responses API DOES support `{ role: "assistant", content: "..." }` in input
473
+ - Full conversation history now works correctly (both with and without `previousResponseId`)
474
+
475
+ **Result:**
476
+
477
+ - ✅ Multi-turn conversations work with full history (client-side)
478
+ - ✅ Multi-turn conversations work with `previousResponseId` (server-side, optimal)
479
+ - ✅ No more consecutive user messages violating API requirements
480
+ - ✅ Assistant messages preserved in all scenarios
481
+
482
+ - 4ad44c0: fix: enable JSDoc descriptions in generated JSON schemas
483
+
484
+ **Changed `jsDoc` mode from "basic" to "extended"** in TypeScript schema generator to properly extract JSDoc comments from source files.
485
+
486
+ **What works now:**
487
+
488
+ - ✅ JSDoc comments are now included as `description` fields in generated JSON schemas
489
+ - ✅ Works for schemas using direct type references: `GetHandler<Ctx, Car>`
490
+ - ✅ Works for schemas using `extends`: `interface Foo extends Car {}`
491
+
492
+ **Example:**
493
+
494
+ ```typescript
495
+ // Schema with JSDoc
496
+ interface Car {
497
+ /**
498
+ * Vehicle model name
499
+ */
500
+ model: string;
501
+ }
502
+
503
+ // Generated JSON Schema now includes:
504
+ {
505
+ "properties": {
506
+ "model": {
507
+ "type": "string",
508
+ "description": "Vehicle model name" // ✅ Description preserved!
509
+ }
510
+ }
511
+ }
512
+ ```
513
+
514
+ **Limitations:**
515
+
516
+ - ❌ Doesn't work for utility types like `Partial<Car>`, `Omit<Car, "id">` where inline properties are generated
517
+ - For these cases, define explicit intermediate interfaces with JSDoc instead
518
+
519
+ **Migration:** No action required - existing schemas without JSDoc continue to work. Add JSDoc block comments to schema properties to get descriptions in generated JSON schemas.
520
+
521
+ ## 2.0.0-alpha.57
522
+
523
+ ### Minor Changes
524
+
525
+ - feat: add content-hash-based schema caching for 70% faster builds
526
+
527
+ Implements intelligent schema caching to dramatically improve build performance when schemas and their dependencies haven't changed. This provides **70% faster schema generation** on subsequent builds with accurate, content-based cache invalidation.
528
+
529
+ **Performance Impact:**
530
+
531
+ - First build: Baseline (generates all schemas)
532
+ - Subsequent builds: 70% faster schema generation when schemas unchanged
533
+ - Partial changes: Only regenerates affected schemas and their dependents
534
+
535
+ **How It Works:**
536
+
537
+ - Computes SHA-256 content hashes of schema files and all dependencies
538
+ - Cache stored in `.flink/schema-cache.json` (automatically gitignored)
539
+ - Tracks handler/tool source files and their transitive dependencies
540
+ - Cache invalidates when:
541
+ - Schema file content changes
542
+ - Any dependency content changes (imports, types, etc.)
543
+ - Dependency set changes (imports added/removed)
544
+ - TypeScript version changes (major/minor)
545
+
546
+ **Example Build Output:**
547
+
548
+ ```bash
549
+ # First build (cache miss)
550
+ ✓ Schema generation completed in 510ms (28 handlers, 4 tools)
551
+ [Cache: 0 hits, 28 misses, 0 invalidated]
552
+
553
+ # Second build (cache hit)
554
+ ✓ Schema generation completed in 153ms (28 handlers, 4 tools)
555
+ [Cache: 28 hits, 0 misses, 0 invalidated]
556
+
557
+ # After modifying Car.ts
558
+ ✓ Schema generation completed in 250ms (28 handlers, 4 tools)
559
+ [Cache: 5 hits, 0 misses, 23 invalidated]
560
+ ```
561
+
562
+ **Benefits:**
563
+
564
+ - Zero configuration - automatic and transparent
565
+ - Git-friendly - content-based hashing works correctly with git operations
566
+ - Accurate invalidation - only regenerates when actual content changes
567
+ - Smart dependency tracking - tracks all imported types and their dependencies
568
+
569
+ **Migration:** No action needed - caching is automatic. The cache file is gitignored and can be safely deleted if needed.
570
+
3
571
  ## 2.0.0-alpha.56
4
572
 
5
573
  ### Patch Changes