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 <noreply@anthropic.com>
This commit is contained in:
Claude 2026-09-01 20:19:00 +10:00
parent a627fa5ac7
commit b50fed8794

View file

@ -23,7 +23,14 @@ import logging
from typing import Any, TypedDict from typing import Any, TypedDict
from langgraph.graph import END, StateGraph 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 classifier
import tools.equipment as equipment_tool import tools.equipment as equipment_tool