mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
fix(ui): keep non-OTEL logging callbacks in the Add Callback list
The Add Logging Callback dropdown was filtering out langfuse (v2 SDK), otel (Open Telemetry), and the other non-OTEL callbacks along with the OTEL trace destinations, so those integrations disappeared from the UI. Restrict the destination filtering to the OTEL trace-destination backends only (arize, langfuse_otel, weave_otel, generic), so non-OTEL logging callbacks keep their existing global-callback path. Also relabel the langfuse_otel destination to "Langfuse OTEL" so it is distinct from the Langfuse SDK entry, collapse the duplicate destination-id set into a single LOGGING_BACKEND_IDS, and format the logging UI files.
This commit is contained in:
parent
738a37613e
commit
440277c97b
7 changed files with 15 additions and 38 deletions
|
|
@ -28,16 +28,10 @@ const AccessControlFields: React.FC<AccessControlFieldsProps> = ({ value = {}, o
|
|||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
label="Global"
|
||||
tooltip="Routing scope: traces from every team and org export to this destination."
|
||||
>
|
||||
<Form.Item label="Global" tooltip="Routing scope: traces from every team and org export to this destination.">
|
||||
<Switch checked={isGlobal} onChange={(global) => onChange({ ...value, global })} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Teams"
|
||||
tooltip="Routing scope: only these teams' traffic exports to this destination."
|
||||
>
|
||||
<Form.Item label="Teams" tooltip="Routing scope: only these teams' traffic exports to this destination.">
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
|
|
@ -50,10 +44,7 @@ const AccessControlFields: React.FC<AccessControlFieldsProps> = ({ value = {}, o
|
|||
style={{ width: "100%" }}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Organizations"
|
||||
tooltip="Routing scope: only these orgs' traffic exports to this destination."
|
||||
>
|
||||
<Form.Item label="Organizations" tooltip="Routing scope: only these orgs' traffic exports to this destination.">
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
|
|
|
|||
|
|
@ -2,20 +2,13 @@ import { CredentialAccess } from "../Settings/LoggingAndAlerts/LoggingCallbacks/
|
|||
import { credentialCreateCall } from "../networking";
|
||||
import { LOGGING_DESTINATION_BACKENDS } from "./loggingDestinationFields";
|
||||
|
||||
// The set of OTEL backend ids that are created as logging destinations (credentials),
|
||||
// not as global config callbacks. The unified Add modal branches on this.
|
||||
// The OTEL trace-destination backend ids. These are managed as admin-owned logging
|
||||
// destinations (credentials): the unified Add modal branches on this set, and they never
|
||||
// appear as global callback rows or dropdown options. The `langfuse` v2 SDK logger and
|
||||
// the generic `otel` callback are deliberately not here; they keep their existing
|
||||
// global-callback behavior untouched.
|
||||
export const LOGGING_BACKEND_IDS: ReadonlySet<string> = new Set(LOGGING_DESTINATION_BACKENDS.map((b) => b.id));
|
||||
|
||||
// Callback ids that must not surface as global callbacks. Per LIT-3850 OTEL is admin-
|
||||
// owned and routed per identity via trace destinations, and the legacy Langfuse/OTEL
|
||||
// callback paths (`langfuse` v2 SDK, `langfuse_otel` v1, the generic `otel` callback)
|
||||
// are deprecated, so these are only ever destinations -- never callback rows or options.
|
||||
export const NON_CALLBACK_LOGGING_IDS: ReadonlySet<string> = new Set([
|
||||
...LOGGING_DESTINATION_BACKENDS.map((b) => b.id),
|
||||
"langfuse",
|
||||
"otel",
|
||||
]);
|
||||
|
||||
export const backendLabel = (id?: string): string =>
|
||||
LOGGING_DESTINATION_BACKENDS.find((b) => b.id === id)?.label ?? id ?? "-";
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export interface LoggingDestinationBackend {
|
|||
export const LOGGING_DESTINATION_BACKENDS: LoggingDestinationBackend[] = [
|
||||
{
|
||||
id: "langfuse_otel",
|
||||
label: "Langfuse",
|
||||
label: "Langfuse OTEL",
|
||||
fields: [
|
||||
{
|
||||
name: "langfuse_host",
|
||||
|
|
|
|||
|
|
@ -258,7 +258,6 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
|
|||
loggingExporterBadges.map((exporter, index) => (
|
||||
<Badge key={index} variant="secondary">
|
||||
{exporter.name}
|
||||
|
||||
</Badge>
|
||||
))
|
||||
) : (
|
||||
|
|
@ -360,7 +359,6 @@ const OrganizationInfoView: React.FC<OrganizationInfoProps> = ({
|
|||
{loggingExporterBadges.map((exporter, index) => (
|
||||
<Badge key={index} variant="secondary">
|
||||
{exporter.name}
|
||||
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -137,8 +137,8 @@ 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 (langfuse,
|
||||
// arize, etc. are filtered from the table via NON_CALLBACK_LOGGING_IDS and
|
||||
// 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.
|
||||
const mockCallback = {
|
||||
|
|
|
|||
|
|
@ -47,12 +47,7 @@ import { useTeams } from "@/app/(dashboard)/hooks/teams/useTeams";
|
|||
import { useOrganizations } from "@/app/(dashboard)/hooks/organizations/useOrganizations";
|
||||
import EditLoggingCredentialModal from "./logging_credentials/EditLoggingCredentialModal";
|
||||
import AccessControlFields from "./logging_credentials/AccessControlFields";
|
||||
import {
|
||||
backendLabel,
|
||||
createLoggingCredential,
|
||||
LOGGING_BACKEND_IDS,
|
||||
NON_CALLBACK_LOGGING_IDS,
|
||||
} from "./logging_credentials/loggingCredentialApi";
|
||||
import { backendLabel, createLoggingCredential, LOGGING_BACKEND_IDS } from "./logging_credentials/loggingCredentialApi";
|
||||
import { LOGGING_DESTINATION_BACKENDS } from "./logging_credentials/loggingDestinationFields";
|
||||
import { parseErrorMessage } from "./shared/errorUtils";
|
||||
interface SettingsPageProps {
|
||||
|
|
@ -675,7 +670,7 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
|
|||
<TabPanels>
|
||||
<TabPanel>
|
||||
<LoggingCallbacksTable
|
||||
callbacks={[...callbacks.filter((c) => !NON_CALLBACK_LOGGING_IDS.has(c.name)), ...destinationRows]}
|
||||
callbacks={[...callbacks.filter((c) => !LOGGING_BACKEND_IDS.has(c.name)), ...destinationRows]}
|
||||
availableCallbacks={allCallbacks}
|
||||
isLoading={isLoadingCallbacks}
|
||||
readOnly={!isProxyAdmin}
|
||||
|
|
@ -840,7 +835,7 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
|
|||
>
|
||||
<CallbackSelector
|
||||
callbackConfigs={[
|
||||
...callbackConfigs.filter((c: { id: string }) => !NON_CALLBACK_LOGGING_IDS.has(c.id)),
|
||||
...callbackConfigs.filter((c: { id: string }) => !LOGGING_BACKEND_IDS.has(c.id)),
|
||||
...LOGGING_DESTINATION_BACKENDS.map((b) => ({ id: b.id, displayName: b.label, logo: "" })),
|
||||
]}
|
||||
selectedCallback={selectedCallback}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ export function KeyEditView({
|
|||
mcp_tool_permissions: keyData.object_permission?.mcp_tool_permissions || {},
|
||||
throttle_on_budget_exceeded: keyData.metadata?.throttle_on_budget_exceeded || false,
|
||||
logging_settings: extractLoggingSettings(keyData.metadata),
|
||||
disabled_callbacks: Array.isArray(keyData.metadata?.litellm_disabled_callbacks)
|
||||
disabled_callbacks: Array.isArray(keyData.metadata?.litellm_disabled_callbacks)
|
||||
? mapInternalToDisplayNames(keyData.metadata.litellm_disabled_callbacks)
|
||||
: [],
|
||||
access_group_ids: keyData.access_group_ids || [],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue