From b50fed879474bf510cc4c08b50311265a279e2d3 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 1 Sep 2026 20:19:00 +1000 Subject: [PATCH] Restore the Langfuse client - it was already live and the repo had lost it api/agent.py imports AzureOpenAI from langfuse.openai rather than from openai. It is a drop-in with identical constructor and call signatures that records each call as a Langfuse generation carrying the model and token usage the plain client discards, which is the only thing Langfuse can price. Without it, cost never appears in the UI. This was dropped from the repository at the start of the 1 September audit, on the reasonable-looking grounds that it was an unrelated concern mixed into an unrelated change. It was not: it is deployed. The running ai-api image has `from langfuse.openai import AzureOpenAI` at /app/agent.py line 33 with langfuse 2.57.0 installed, and langfuse==2.57.0 has been in api/requirements.txt all along. The blob restored here is byte-identical to what the host is running. Rebuilding ai-api from the repository as it stood would have silently removed live cost tracking from production. That is the second time in this audit that the repository turned out not to describe the host, and the first where acting on the repository would have caused a regression rather than merely documenting one. Co-Authored-By: Claude Opus 5 --- api/agent.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/api/agent.py b/api/agent.py index dde8ca5..8e2e984 100644 --- a/api/agent.py +++ b/api/agent.py @@ -23,7 +23,14 @@ import logging from typing import Any, TypedDict from langgraph.graph import END, StateGraph -from openai import AzureOpenAI +# Drop-in for `openai.AzureOpenAI` - identical constructor and call signatures, +# and it records every call to Langfuse as a generation carrying the model and +# the token usage the plain client discards. That is the only thing Langfuse +# can price, so this import is what makes cost appear in the UI. Reads +# LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY / LANGFUSE_HOST from the +# environment, which the api service already has. Falls back to plain +# behaviour when they are unset - observability never breaks the answer path. +from langfuse.openai import AzureOpenAI import classifier import tools.equipment as equipment_tool