mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-09 22:31:41 +00:00
feat(ui/agents): add Authentication Headers section to agent create/edit form
Add a new "Authentication Headers" panel to AgentFormFields: - Static Headers: key-value Form.List (always sent to the backend agent, static wins on conflict with dynamic) - Forward Client Headers: Select[tags] of header names to extract from the client request and forward (extra_headers) Update buildAgentDataFromForm to serialize both fields for the API. Update parseAgentForForm to deserialize them back for editing. Covers both the create wizard (add_agent_form) and the edit view (agent_info). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fd53678898
commit
36d279ab42
2 changed files with 94 additions and 2 deletions
|
|
@ -269,6 +269,23 @@ export const buildAgentDataFromForm = (values: any, existingAgent?: any) => {
|
|||
agentData.litellm_params = params;
|
||||
}
|
||||
|
||||
// static_headers: convert [{header, value}, ...] → {header: value, ...}
|
||||
if (Array.isArray(values.static_headers) && values.static_headers.length > 0) {
|
||||
const staticHeaders: Record<string, string> = {};
|
||||
values.static_headers.forEach((entry: { header?: string; value?: string }) => {
|
||||
const key = entry?.header?.trim();
|
||||
if (key) staticHeaders[key] = entry?.value ?? "";
|
||||
});
|
||||
if (Object.keys(staticHeaders).length > 0) {
|
||||
agentData.static_headers = staticHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
// extra_headers: already an array of strings from Select tags
|
||||
if (Array.isArray(values.extra_headers) && values.extra_headers.length > 0) {
|
||||
agentData.extra_headers = values.extra_headers;
|
||||
}
|
||||
|
||||
return agentData;
|
||||
};
|
||||
|
||||
|
|
@ -302,5 +319,14 @@ export const parseAgentForForm = (agent: any) => {
|
|||
cost_per_query: agent.litellm_params?.cost_per_query,
|
||||
input_cost_per_token: agent.litellm_params?.input_cost_per_token,
|
||||
output_cost_per_token: agent.litellm_params?.output_cost_per_token,
|
||||
// static_headers: {key: value} → [{header, value}, ...]
|
||||
static_headers: agent.static_headers
|
||||
? Object.entries(agent.static_headers as Record<string, string>).map(([header, value]) => ({
|
||||
header,
|
||||
value,
|
||||
}))
|
||||
: [],
|
||||
// extra_headers: already an array of strings
|
||||
extra_headers: agent.extra_headers ?? [],
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import { Form, Input, Switch, Collapse } from "antd";
|
||||
import { Form, Input, Switch, Collapse, Select, Space, Tooltip } from "antd";
|
||||
import { Button as AntButton } from "antd";
|
||||
import { PlusOutlined, MinusCircleOutlined } from "@ant-design/icons";
|
||||
import { PlusOutlined, MinusCircleOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { AGENT_FORM_CONFIG, SKILL_FIELD_CONFIG } from "./agent_config";
|
||||
|
||||
import CostConfigFields from "./cost_config_fields";
|
||||
|
|
@ -188,6 +188,72 @@ const AgentFormFields: React.FC<AgentFormFieldsProps> = ({ showAgentName = true,
|
|||
))}
|
||||
</Panel>
|
||||
)}
|
||||
|
||||
{/* Authentication Headers */}
|
||||
{shouldShow("auth_headers") && (
|
||||
<Panel header="Authentication Headers" key="auth_headers">
|
||||
{/* Static Headers */}
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Static Headers{" "}
|
||||
<Tooltip title="Headers always sent to the backend agent, regardless of the client request. Admin-configured, static wins on conflict.">
|
||||
<InfoCircleOutlined style={{ color: "#8c8c8c" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Form.List name="static_headers">
|
||||
{(fields, { add, remove }) => (
|
||||
<>
|
||||
{fields.map(({ key, name, ...restField }) => (
|
||||
<Space key={key} style={{ display: "flex", marginBottom: 8 }} align="baseline">
|
||||
<Form.Item
|
||||
{...restField}
|
||||
name={[name, "header"]}
|
||||
rules={[{ required: true, message: "Header name required" }]}
|
||||
>
|
||||
<Input placeholder="Header name (e.g. Authorization)" style={{ width: 220 }} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...restField}
|
||||
name={[name, "value"]}
|
||||
rules={[{ required: true, message: "Value required" }]}
|
||||
>
|
||||
<Input placeholder="Value (e.g. Bearer token123)" style={{ width: 260 }} />
|
||||
</Form.Item>
|
||||
<MinusCircleOutlined onClick={() => remove(name)} style={{ color: "#ff4d4f" }} />
|
||||
</Space>
|
||||
))}
|
||||
<AntButton type="dashed" onClick={() => add()} icon={<PlusOutlined />} style={{ width: "100%" }}>
|
||||
Add Static Header
|
||||
</AntButton>
|
||||
</>
|
||||
)}
|
||||
</Form.List>
|
||||
</Form.Item>
|
||||
|
||||
{/* Extra Headers (dynamic forwarding) */}
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Forward Client Headers{" "}
|
||||
<Tooltip title="Header names to extract from the client's request and forward to the agent. Type a name and press Enter.">
|
||||
<InfoCircleOutlined style={{ color: "#8c8c8c" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="extra_headers"
|
||||
>
|
||||
<Select
|
||||
mode="tags"
|
||||
style={{ width: "100%" }}
|
||||
placeholder="e.g. x-api-key, Authorization"
|
||||
tokenSeparators={[","]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Panel>
|
||||
)}
|
||||
</Collapse>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue