@flink-app/flink 2.0.0-alpha.91 → 2.0.0-alpha.92

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 CHANGED
@@ -1,5 +1,50 @@
1
1
  # @flink-app/flink
2
2
 
3
+ ## 2.0.0-alpha.92
4
+
5
+ ### Minor Changes
6
+
7
+ - 8d23d56: Add global `AgentObserver` for app-level agent tracing
8
+
9
+ A new `observer` option on `FlinkOptions.ai` lets applications register a single, app-wide hook that fires for every agent execution — covering both streamed and awaited (`response.result`) callers without per-agent plumbing.
10
+
11
+ Events expose data that was previously only internal to `AgentRunner`:
12
+
13
+ - `onRun` — pre-loop, with resolved system instructions and initial messages.
14
+ - `onLlmCall` — per step, immediately before the adapter call. `messages` reflects post-compaction state and `tools` reflects per-step permission filtering.
15
+ - `onStep` — per step end, with `assistantText`, per-step `toolCalls`, and `usage`.
16
+ - `onFinish` — post-loop (success or error), with the final result, total `durationMs`, and the error message on failure.
17
+
18
+ All events share a stable `runId` per execution; the same ID is now also returned on `AgentExecuteResult.runId` so apps can correlate persisted results with observer traces.
19
+
20
+ Observer callbacks are fire-and-forget: they may return a promise but the framework does not await them, and any thrown/rejected errors are caught and logged without affecting agent execution.
21
+
22
+ The existing per-agent `beforeRun` / `onStep` / `afterRun` hooks remain unchanged — use the observer for cross-cutting concerns (tracing, APM, cost accounting, dev tools) and per-agent hooks for business logic that needs to block or mutate state (conversation persistence, guardrails).
23
+
24
+ Example:
25
+
26
+ ```typescript
27
+ new FlinkApp({
28
+ ai: {
29
+ llms: { default: new AnthropicAdapter({ ... }) },
30
+ observer: {
31
+ onRun(e) {
32
+ trace.start(e.runId, { agentId: e.agentId, instructions: e.instructions });
33
+ },
34
+ onLlmCall(e) {
35
+ trace.recordLlmCall(e.runId, e.step, e.messages, e.tools);
36
+ },
37
+ onStep(e) {
38
+ trace.recordStep(e.runId, e.step, e.assistantText, e.toolCalls, e.usage);
39
+ },
40
+ onFinish(e) {
41
+ trace.finish(e.runId, { result: e.result, error: e.error, durationMs: e.durationMs });
42
+ },
43
+ },
44
+ },
45
+ });
46
+ ```
47
+
3
48
  ## 2.0.0-alpha.91
4
49
 
5
50
  ## 2.0.0-alpha.90
@@ -6,6 +6,7 @@ import { Db, MongoClient } from "mongodb";
6
6
  import { ToadScheduler } from "toad-scheduler";
7
7
  import { FlinkAgentFile } from "./ai/FlinkAgent";
8
8
  import { FlinkToolFile } from "./ai/FlinkTool";
9
+ import { AgentObserver } from "./ai/FlinkAgent";
9
10
  import { LLMAdapter } from "./ai/LLMAdapter";
10
11
  import { FlinkAuthPlugin } from "./auth/FlinkAuthPlugin";
11
12
  import { FlinkContext } from "./FlinkContext";
@@ -178,6 +179,21 @@ export interface FlinkOptions {
178
179
  llms?: {
179
180
  [id: string]: LLMAdapter;
180
181
  };
182
+ /**
183
+ * Global agent observer for app-level tracing, APM, cost accounting, dev tools, etc.
184
+ *
185
+ * Fires for every agent execution in the app. Observer callbacks are invoked
186
+ * fire-and-forget — they may return a Promise but the framework does not await
187
+ * them, and any thrown/rejected errors are caught and logged without affecting
188
+ * agent execution.
189
+ *
190
+ * Events: `onRun` (pre-loop), `onLlmCall` (per step, pre-adapter call),
191
+ * `onStep` (per step end), `onFinish` (post-loop, including error path).
192
+ *
193
+ * For agent-local business logic (conversation persistence, guardrails) use the
194
+ * per-agent `beforeRun` / `onStep` / `afterRun` hooks on `FlinkAgent` instead.
195
+ */
196
+ observer?: AgentObserver;
181
197
  };
182
198
  /**
183
199
  * If true, the HTTP server will be disabled.
@@ -290,6 +306,7 @@ export declare class FlinkApp<C extends FlinkContext> {
290
306
  private repos;
291
307
  private services;
292
308
  private llmAdapters;
309
+ private agentObserver?;
293
310
  private tools;
294
311
  private agents;
295
312
  /**
@@ -117,7 +117,7 @@ exports.autoRegisteredAgents = [];
117
117
  exports.autoRegisteredServices = [];
118
118
  var FlinkApp = /** @class */ (function () {
119
119
  function FlinkApp(opts) {
120
- var _a;
120
+ var _a, _b;
121
121
  this.handlers = [];
122
122
  this.started = false;
123
123
  this.debug = false;
@@ -160,6 +160,8 @@ var FlinkApp = /** @class */ (function () {
160
160
  // Convert plain object to Map for internal use
161
161
  this.llmAdapters = new Map(Object.entries(opts.ai.llms));
162
162
  }
163
+ // Register global agent observer if configured
164
+ this.agentObserver = (_b = opts.ai) === null || _b === void 0 ? void 0 : _b.observer;
163
165
  }
164
166
  Object.defineProperty(FlinkApp.prototype, "ctx", {
165
167
  get: function () {
@@ -1208,7 +1210,7 @@ var FlinkApp = /** @class */ (function () {
1208
1210
  for (_i = 0, _a = Object.values(this.agents); _i < _a.length; _i++) {
1209
1211
  agent = _a[_i];
1210
1212
  agent.ctx = this.ctx;
1211
- agent.__init(this.llmAdapters, this.tools);
1213
+ agent.__init(this.llmAdapters, this.tools, this.agentObserver);
1212
1214
  }
1213
1215
  return [2 /*return*/];
1214
1216
  });
@@ -1,4 +1,4 @@
1
- import { FlinkAgentProps, AgentExecuteInput, StreamChunk } from "./FlinkAgent";
1
+ import { FlinkAgentProps, AgentExecuteInput, StreamChunk, AgentObserver } from "./FlinkAgent";
2
2
  import { ToolExecutor } from "./ToolExecutor";
3
3
  import { LLMAdapter } from "./LLMAdapter";
4
4
  export declare class AgentRunner {
@@ -6,14 +6,21 @@ export declare class AgentRunner {
6
6
  private tools;
7
7
  private agentName?;
8
8
  private ctx?;
9
+ private observer?;
9
10
  private llmAdapter;
10
11
  private maxTokens;
11
12
  private temperature;
12
13
  private maxSteps;
13
14
  private timeoutMs;
14
15
  constructor(agentProps: FlinkAgentProps<any>, tools: Map<string, ToolExecutor<any>>, llmAdapters: Map<string, LLMAdapter>, agentName?: string | undefined, // Optional agent name for logging
15
- ctx?: any);
16
+ ctx?: any, // FlinkContext for instruction callbacks (any for flexibility)
17
+ observer?: AgentObserver | undefined);
16
18
  streamGenerator(input: AgentExecuteInput): AsyncGenerator<StreamChunk>;
19
+ /**
20
+ * Fire-and-forget observer dispatch: catches synchronous throws and
21
+ * rejected promises so observer failures never break agent execution.
22
+ */
23
+ private safeDispatch;
17
24
  /**
18
25
  * Convert Message[] to LLM message format
19
26
  * Supports multi-turn conversations with history