mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
fix(ui): keep config-owned OTEL callbacks visible in the logging table
The Active Logging Callbacks table filtered every callback whose name is an OTEL trace-destination backend (arize, langfuse_otel, weave_otel, generic) via LOGGING_BACKEND_IDS, intending to drop rows that duplicate a destination. But config-owned global callbacks (configured proxy-wide through /config/update) live in a separate namespace from the credential-backed destination rows, so nothing was ever a duplicate; the filter just removed the config rows, and an admin who had set up a global Arize/Langfuse-OTEL/Weave/generic callback lost all visibility and management of it in the dashboard even though it kept receiving traffic. Show config callbacks and destination rows together. Their name spaces don't overlap (config callbacks keyed by backend name, destinations by credential name), so no duplicate can arise. The other two LOGGING_BACKEND_IDS uses (the add-callback dropdown routing and the availableCallbacks catalog) are unchanged.
This commit is contained in:
parent
34cfd85a40
commit
0e766a19a2
2 changed files with 33 additions and 5 deletions
|
|
@ -137,10 +137,9 @@ describe("Settings", () => {
|
|||
});
|
||||
|
||||
it("should display edit modal with fields when edit is clicked", async () => {
|
||||
// Use a config callback that is NOT a logging-destination backend (arize,
|
||||
// langfuse_otel, etc. are filtered from the table via LOGGING_BACKEND_IDS and
|
||||
// edited through the destination flow instead). Datadog is a plain config
|
||||
// callback, so it still renders a row with the legacy Test/Edit/Delete actions.
|
||||
// Datadog is a plain config callback that renders a row with the legacy
|
||||
// Test/Edit/Delete actions. Config-owned OTEL callbacks (arize, langfuse_otel,
|
||||
// etc.) also render as their own rows now; see the regression test below.
|
||||
const mockCallback = {
|
||||
name: "datadog",
|
||||
variables: {
|
||||
|
|
@ -204,6 +203,35 @@ describe("Settings", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("should render a config-owned OTEL callback (langfuse_otel) as its own row", async () => {
|
||||
// Regression: a proxy-wide langfuse_otel/arize/weave/generic callback configured
|
||||
// via /config/update must stay visible and manageable in the table. It was being
|
||||
// filtered out by backend id, removing config-owned rows (not just duplicates).
|
||||
mockGetCallbacksCall.mockResolvedValue({
|
||||
callbacks: [{ name: "langfuse_otel", variables: { LANGFUSE_PUBLIC_KEY: "pk", LANGFUSE_SECRET_KEY: "sk" } }],
|
||||
available_callbacks: {
|
||||
langfuse_otel: {
|
||||
litellm_callback_name: "langfuse_otel",
|
||||
litellm_callback_params: ["LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY"],
|
||||
ui_callback_name: "Langfuse OTEL",
|
||||
},
|
||||
},
|
||||
alerts: [],
|
||||
});
|
||||
mockGetCallbackConfigsCall.mockResolvedValue([
|
||||
{ id: "langfuse_otel", displayName: "Langfuse OTEL", dynamic_params: {} },
|
||||
]);
|
||||
|
||||
const { getByText } = renderSettings(defaultProps);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText("Active Logging Callbacks")).toBeInTheDocument();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(getByText("Langfuse OTEL")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should hold the callbacks table in loading state until the fetch settles", async () => {
|
||||
let resolveCallbacks: (value: {
|
||||
callbacks: never[];
|
||||
|
|
|
|||
|
|
@ -670,7 +670,7 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
|
|||
<TabPanels>
|
||||
<TabPanel>
|
||||
<LoggingCallbacksTable
|
||||
callbacks={[...callbacks.filter((c) => !LOGGING_BACKEND_IDS.has(c.name)), ...destinationRows]}
|
||||
callbacks={[...callbacks, ...destinationRows]}
|
||||
availableCallbacks={allCallbacks}
|
||||
isLoading={isLoadingCallbacks}
|
||||
readOnly={!isProxyAdmin}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue