Model-turn telemetry
Bonus: model-turn telemetry
Section titled “Bonus: model-turn telemetry”Time: 5 minutes
Checkpoint 6 uses built-in agent tracing and needs no application observer. In
this experiment, add a focused runtime-event subscriber that exports model tokens,
duration, failures, and the provider’s gatewayLogId to Workers Logs.
1. Add a model-turn observer
Section titled “1. Add a model-turn observer”Update src/app.ts to register the observer before creating the route map. The
diff starts from completed checkpoint 6; Complete file retains every route:
src/app.ts+21−0Changes from Checkpoint 6 (guide) → Model-turn telemetry bonus
===================================================================--- a/src/app.ts Checkpoint 6 (guide)+++ b/src/app.ts Model-turn telemetry bonus@@ -1,8 +1,29 @@ import { Hono } from 'hono'; import { createAgentRouter } from '@flue/runtime/routing';+import { observe } from '@flue/runtime'; import { FieldTrip } from './agents/field-trip.ts'; import chatUi from './ui/index.html?raw';
+observe((event) => {+ if (event.type !== 'turn') return;+ const usage = event.response.usage;+ console.log({+ event: 'flue_model_turn',+ agent: event.agentName ?? null,+ conversationId: event.conversationId ?? null,+ submissionId: event.submissionId ?? null,+ turnId: event.turnId,+ model: event.request.requestedModel,+ durationMs: event.durationMs,+ inputTokens: usage?.input ?? null,+ outputTokens: usage?.output ?? null,+ totalTokens: usage?.totalTokens ?? null,+ gatewayLogId: event.response.gatewayLogId ?? null,+ isError: event.isError,+ error: event.response.error?.message ?? null,+ });+});+ // src/app.ts is the Flue route map. Its default export owns every HTTP request // the Worker receives. Agents get mounted here with createAgentRouter(...) // starting in checkpoint 1.import { Hono } from 'hono';import { createAgentRouter } from '@flue/runtime/routing';import { observe } from '@flue/runtime';import { FieldTrip } from './agents/field-trip.ts';import chatUi from './ui/index.html?raw';
observe((event) => { if (event.type !== 'turn') return; const usage = event.response.usage; console.log({ event: 'flue_model_turn', agent: event.agentName ?? null, conversationId: event.conversationId ?? null, submissionId: event.submissionId ?? null, turnId: event.turnId, model: event.request.requestedModel, durationMs: event.durationMs, inputTokens: usage?.input ?? null, outputTokens: usage?.output ?? null, totalTokens: usage?.totalTokens ?? null, gatewayLogId: event.response.gatewayLogId ?? null, isError: event.isError, error: event.response.error?.message ?? null, });});
// src/app.ts is the Flue route map. Its default export owns every HTTP request// the Worker receives. Agents get mounted here with createAgentRouter(...)// starting in checkpoint 1.const app = new Hono();
// A small chat UI for trying the agent in a browser, locally and on workers.dev.app.get('/', (c) => c.html(chatUi));app.get('/api/ping', (c) => c.text('pong'));app.route('/agents/field-trip', createAgentRouter(FieldTrip));
export default app;2. Run one turn
Section titled “2. Run one turn”npm run typechecknpm run deploysleep 5npm run smoke -- https://field-trip-agent.<subdomain>.workers.dev telemetry-live-1 "Describe what you do in one sentence."Open Workers & Pages → field-trip-agent → Observability → Logs
and filter event = flue_model_turn.
Copy a non-null gatewayLogId, then locate that request in
AI → AI Gateway → Logs.
If the provider does not return this ID, the field remains null; it is not
evidence of a failed model call.
Save your workers.dev subdomain to open this test ↗https://field-trip-agent.<subdomain>.workers.dev/?id=telemetry-live-1
This opens the same conversation as the smoke test. If you repeat this checkpoint, before copying its commands.
Restart npm run dev in Terminal A, then run in Terminal B:
npm run typechecknpm run smoke -- http://localhost:5173 telemetry-1 "Describe what you do in one sentence."The dev terminal prints the flue_model_turn object.
Open local chat in your browser ↗http://localhost:5173/?id=telemetry-1
This opens the same conversation as the smoke test. If you repeat this checkpoint, before copying its commands.
Verification gate
Prove it works
- Workers Logs contains an object with
event: ‘flue_model_turn’. - The object identifies the Gemma model and reports token counts.
gatewayLogIdcorrelates the turn with its AI Gateway log when available.
Remove the observe import and callback, then redeploy (or restart Vite for Local dev).
Checkpoint 6’s built-in agent tracing continues to work without this observer.
Reference: Flue observability.