@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.
- package/CHANGELOG.md +568 -0
- package/SCHEMA_EXTRACTION_ANALYSIS.md +494 -0
- package/SIMPLE_AST_FEASIBILITY.md +570 -0
- package/bin/flink.ts +13 -2
- package/cli/build.ts +24 -51
- package/cli/clean.ts +13 -25
- package/cli/cli-utils.ts +188 -17
- package/cli/dev.ts +212 -0
- package/cli/run.ts +36 -74
- package/dist/bin/flink.js +61 -2
- package/dist/cli/build.js +20 -32
- package/dist/cli/clean.js +12 -10
- package/dist/cli/cli-utils.d.ts +34 -3
- package/dist/cli/cli-utils.js +187 -12
- package/dist/cli/dev.d.ts +2 -0
- package/dist/cli/dev.js +243 -0
- package/dist/cli/run.js +35 -52
- package/dist/src/DependencyTracker.d.ts +44 -0
- package/dist/src/DependencyTracker.js +239 -0
- package/dist/src/FlinkApp.d.ts +46 -2
- package/dist/src/FlinkApp.js +367 -146
- package/dist/src/FlinkHttpHandler.d.ts +47 -17
- package/dist/src/FlinkLog.d.ts +82 -18
- package/dist/src/FlinkLog.js +165 -13
- package/dist/src/FlinkLogFactory.d.ts +288 -0
- package/dist/src/FlinkLogFactory.js +619 -0
- package/dist/src/FlinkRequestContext.d.ts +63 -0
- package/dist/src/FlinkRequestContext.js +74 -0
- package/dist/src/SchemaCache.d.ts +84 -0
- package/dist/src/SchemaCache.js +289 -0
- package/dist/src/TypeScriptCompiler.d.ts +100 -63
- package/dist/src/TypeScriptCompiler.js +949 -847
- package/dist/src/ai/AgentRunner.d.ts +2 -11
- package/dist/src/ai/AgentRunner.js +249 -263
- package/dist/src/ai/ConversationAgent.d.ts +279 -0
- package/dist/src/ai/ConversationAgent.js +402 -0
- package/dist/src/ai/ConversationFlinkAgent.d.ts +278 -0
- package/dist/src/ai/ConversationFlinkAgent.js +404 -0
- package/dist/src/ai/FlinkAgent.d.ts +186 -98
- package/dist/src/ai/FlinkAgent.js +140 -75
- package/dist/src/ai/FlinkTool.d.ts +100 -2
- package/dist/src/ai/InMemoryConversationAgent.d.ts +121 -0
- package/dist/src/ai/InMemoryConversationAgent.js +209 -0
- package/dist/src/ai/LLMAdapter.d.ts +33 -4
- package/dist/src/ai/PersistentFlinkAgent.d.ts +278 -0
- package/dist/src/ai/PersistentFlinkAgent.js +403 -0
- package/dist/src/ai/SubAgentExecutor.d.ts +5 -3
- package/dist/src/ai/SubAgentExecutor.js +14 -11
- package/dist/src/ai/ToolExecutor.d.ts +24 -8
- package/dist/src/ai/ToolExecutor.js +268 -82
- package/dist/src/ai/agentInstructions.d.ts +68 -0
- package/dist/src/ai/agentInstructions.js +246 -0
- package/dist/src/ai/index.d.ts +3 -0
- package/dist/src/ai/index.js +5 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.js +10 -0
- package/dist/src/loadPluginSchemas.d.ts +45 -0
- package/dist/src/loadPluginSchemas.js +143 -0
- package/dist/src/schema-extraction/ComplexTypeDetection.d.ts +40 -0
- package/dist/src/schema-extraction/ComplexTypeDetection.js +75 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.d.ts +307 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.js +858 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.spec.d.ts +1 -0
- package/dist/src/schema-extraction/TypeScriptSourceParser.spec.js +233 -0
- package/dist/src/schema-extraction/TypeScriptTokenizer.d.ts +57 -0
- package/dist/src/schema-extraction/TypeScriptTokenizer.js +177 -0
- package/dist/src/schema-extraction/index.d.ts +2 -0
- package/dist/src/schema-extraction/index.js +20 -0
- package/dist/src/schema-extraction/types.d.ts +31 -0
- package/dist/src/schema-extraction/types.js +2 -0
- package/dist/src/utils/loadFlinkConfig.d.ts +29 -0
- package/dist/src/utils/loadFlinkConfig.js +77 -0
- package/examples/logging-hierarchical-example.ts +125 -0
- package/package.json +14 -4
- package/readme.md +74 -0
- package/spec/AgentDescendantDetection.spec.ts +335 -0
- package/spec/AgentRunner.spec.ts +343 -61
- package/spec/AsyncLocalStorageContext.spec.ts +223 -0
- package/spec/ConversationHooks.spec.ts +5 -38
- package/spec/FlinkAgent.spec.ts +183 -2
- package/spec/FlinkApp.htmlResponse.spec.ts +131 -0
- package/spec/FlinkLogFactory.spec.ts +337 -0
- package/spec/StreamingIntegration.spec.ts +1 -0
- package/spec/ToolExecutor.spec.ts +14 -22
- package/spec/TypeScriptCompiler.spec.ts +1 -1
- package/spec/TypeScriptSourceParser.spec.ts +1079 -0
- package/spec/TypeScriptTokenizer.spec.ts +366 -0
- package/spec/ai/ContextCompaction.spec.ts +405 -0
- package/spec/ai/ConversationAgent.spec.ts +491 -0
- package/spec/ai/InMemoryConversationAgent.spec.ts +144 -0
- package/spec/ai/agentInstructions.spec.ts +338 -0
- package/spec/fixtures/agent-instructions/TestAgent.ts +22 -0
- package/spec/fixtures/agent-instructions/simple.md +3 -0
- package/spec/fixtures/agent-instructions/template.md +18 -0
- package/spec/fixtures/agent-instructions/yaml-format.yaml +9 -0
- package/spec/mock-project/dist/.tsbuildinfo +1 -0
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar.js +2 -3
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar2.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema2.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema3.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema2.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile2.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchCar.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOnboardingSession.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchProductWithIntersection.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchUserWithUnion.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PostCar.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogin.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogout.js +1 -2
- package/spec/mock-project/dist/spec/mock-project/src/handlers/PutCar.js +1 -2
- package/spec/mock-project/dist/src/FlinkApp.js +95 -107
- package/spec/mock-project/dist/src/FlinkLog.js +94 -1
- package/spec/mock-project/dist/src/FlinkLogFactory.js +617 -0
- package/spec/mock-project/dist/src/FlinkRequestContext.js +74 -0
- package/spec/mock-project/dist/src/ai/AgentRunner.js +249 -263
- package/spec/mock-project/dist/src/ai/ConversationAgent.js +402 -0
- package/spec/mock-project/dist/src/ai/ConversationFlinkAgent.js +422 -0
- package/spec/mock-project/dist/src/ai/FlinkAgent.js +140 -75
- package/spec/mock-project/dist/src/ai/InMemoryConversationAgent.js +209 -0
- package/spec/mock-project/dist/src/ai/SubAgentExecutor.js +13 -10
- package/spec/mock-project/dist/src/ai/ToolExecutor.js +234 -82
- package/spec/mock-project/dist/src/ai/agentInstructions.js +246 -0
- package/spec/mock-project/dist/src/handlers/GetCar.js +26 -52
- package/spec/mock-project/dist/src/handlers/GetCar.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCar2.js +32 -54
- package/spec/mock-project/dist/src/handlers/GetCar2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +26 -48
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +28 -48
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +29 -48
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +26 -50
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +28 -50
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +27 -53
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +29 -53
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +16 -49
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +25 -50
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchCar.js +27 -53
- package/spec/mock-project/dist/src/handlers/PatchCar.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js +44 -70
- package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js +27 -53
- package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js +28 -54
- package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js +28 -54
- package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PostCar.js +24 -50
- package/spec/mock-project/dist/src/handlers/PostCar.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PostLogin.js +25 -51
- package/spec/mock-project/dist/src/handlers/PostLogin.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PostLogout.js +24 -50
- package/spec/mock-project/dist/src/handlers/PostLogout.js.map +1 -0
- package/spec/mock-project/dist/src/handlers/PutCar.js +24 -50
- package/spec/mock-project/dist/src/handlers/PutCar.js.map +1 -0
- package/spec/mock-project/dist/src/index.js +57 -29
- package/spec/mock-project/dist/src/index.js.map +1 -0
- package/spec/mock-project/dist/src/repos/CarRepo.js +12 -24
- package/spec/mock-project/dist/src/repos/CarRepo.js.map +1 -0
- package/spec/mock-project/dist/src/schemas/Car.js +3 -1
- package/spec/mock-project/dist/src/schemas/Car.js.map +1 -0
- package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js +3 -1
- package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js.map +1 -0
- package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js +3 -1
- package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js.map +1 -0
- package/spec/schema-generation-nested-objects.spec.ts +97 -0
- package/spec/utils.caseConversion.spec.ts +4 -6
- package/src/DependencyTracker.ts +166 -0
- package/src/FlinkApp.ts +439 -151
- package/src/FlinkHttpHandler.ts +50 -18
- package/src/FlinkLog.ts +119 -12
- package/src/FlinkLogFactory.ts +699 -0
- package/src/FlinkRequestContext.ts +95 -0
- package/src/SchemaCache.ts +232 -0
- package/src/TypeScriptCompiler.ts +908 -787
- package/src/ai/AgentRunner.ts +492 -519
- package/src/ai/ConversationAgent.ts +411 -0
- package/src/ai/FlinkAgent.ts +269 -156
- package/src/ai/FlinkTool.ts +129 -4
- package/src/ai/InMemoryConversationAgent.ts +149 -0
- package/src/ai/LLMAdapter.ts +31 -1
- package/src/ai/ToolExecutor.ts +286 -67
- package/src/ai/agentInstructions.ts +199 -0
- package/src/ai/index.ts +3 -0
- package/src/index.ts +7 -0
- package/src/loadPluginSchemas.ts +141 -0
- package/src/schema-extraction/TypeScriptSourceParser.ts +980 -0
- package/src/schema-extraction/TypeScriptTokenizer.ts +205 -0
- package/src/schema-extraction/index.ts +2 -0
- package/src/schema-extraction/types.ts +34 -0
- package/src/utils/loadFlinkConfig.ts +64 -0
- package/spec/SubAgentSupport.spec.ts +0 -955
- 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
|