Skip to content

Commit 26fcbc9

Browse files
authored
Merge pull request BerriAI#26044 from BerriAI/litellm_internal_staging
[Infra] Promote staging to main
2 parents 850fe59 + 2f22a12 commit 26fcbc9

2,065 files changed

Lines changed: 62202 additions & 43302 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,7 +1707,7 @@ jobs:
17071707
export PATH="$HOME/miniconda/bin:$PATH"
17081708
conda init bash
17091709
source ~/.bashrc
1710-
conda create -n myenv python=3.9 -y
1710+
conda create -n myenv python=3.10 -y
17111711
conda activate myenv
17121712
python --version
17131713
- run:
@@ -1822,7 +1822,7 @@ jobs:
18221822
export PATH="$HOME/miniconda/bin:$PATH"
18231823
conda init bash
18241824
source ~/.bashrc
1825-
conda create -n myenv python=3.9 -y
1825+
conda create -n myenv python=3.10 -y
18261826
conda activate myenv
18271827
python --version
18281828
- run:
@@ -2057,7 +2057,7 @@ jobs:
20572057
export PATH="$HOME/miniconda/bin:$PATH"
20582058
conda init bash
20592059
source ~/.bashrc
2060-
conda create -n myenv python=3.9 -y
2060+
conda create -n myenv python=3.10 -y
20612061
conda activate myenv
20622062
python --version
20632063
- run:
@@ -2208,7 +2208,7 @@ jobs:
22082208
export PATH="$HOME/miniconda/bin:$PATH"
22092209
conda init bash
22102210
source ~/.bashrc
2211-
conda create -n myenv python=3.9 -y
2211+
conda create -n myenv python=3.10 -y
22122212
conda activate myenv
22132213
python --version
22142214
- run:
@@ -2319,7 +2319,7 @@ jobs:
23192319
export PATH="$HOME/miniconda/bin:$PATH"
23202320
conda init bash
23212321
source ~/.bashrc
2322-
conda create -n myenv python=3.9 -y
2322+
conda create -n myenv python=3.10 -y
23232323
conda activate myenv
23242324
python --version
23252325
- run:
@@ -2444,7 +2444,7 @@ jobs:
24442444
export PATH="$HOME/miniconda/bin:$PATH"
24452445
conda init bash
24462446
source ~/.bashrc
2447-
conda create -n myenv python=3.9 -y
2447+
conda create -n myenv python=3.10 -y
24482448
conda activate myenv
24492449
python --version
24502450
- run:

.github/scripts/close_duplicate_issues.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ def gh(*args: str) -> str:
4242
def fetch_open_issues(repo: str | None) -> list[dict]:
4343
"""Fetch all open issues (excluding PRs) via gh api --paginate."""
4444
if repo:
45-
endpoint = f"repos/{repo}/issues?state=open&per_page=100&sort=created&direction=asc"
45+
endpoint = (
46+
f"repos/{repo}/issues?state=open&per_page=100&sort=created&direction=asc"
47+
)
4648
else:
4749
endpoint = "repos/{owner}/{repo}/issues?state=open&per_page=100&sort=created&direction=asc"
4850
cmd = ["api", "--paginate", endpoint]
@@ -71,7 +73,9 @@ def close_as_duplicate(
7173
repo_args = ["--repo", repo] if repo else []
7274

7375
if dry_run:
74-
print(f" [DRY RUN] Would close #{issue_number} as duplicate of #{duplicate_of}")
76+
print(
77+
f" [DRY RUN] Would close #{issue_number} as duplicate of #{duplicate_of}"
78+
)
7579
return
7680

7781
# Add comment
@@ -115,7 +119,9 @@ def find_duplicate(
115119
return None
116120

117121

118-
def scan_all(issues: list[dict], threshold: float, repo: str | None, dry_run: bool) -> int:
122+
def scan_all(
123+
issues: list[dict], threshold: float, repo: str | None, dry_run: bool
124+
) -> int:
119125
"""Compare every issue against all older issues. Returns count of duplicates found."""
120126
# Sort oldest first
121127
issues.sort(key=lambda i: i["number"])
@@ -144,7 +150,11 @@ def scan_all(issues: list[dict], threshold: float, repo: str | None, dry_run: bo
144150

145151

146152
def check_single(
147-
issue_number: int, issues: list[dict], threshold: float, repo: str | None, dry_run: bool
153+
issue_number: int,
154+
issues: list[dict],
155+
threshold: float,
156+
repo: str | None,
157+
dry_run: bool,
148158
) -> bool:
149159
"""Check a single issue against all older open issues. Returns True if duplicate found."""
150160
target = None
@@ -178,13 +188,23 @@ def check_single(
178188

179189

180190
def main() -> None:
181-
parser = argparse.ArgumentParser(description="Detect and close duplicate GitHub issues")
191+
parser = argparse.ArgumentParser(
192+
description="Detect and close duplicate GitHub issues"
193+
)
182194
mode = parser.add_mutually_exclusive_group(required=True)
183195
mode.add_argument("--scan", action="store_true", help="Scan all open issues")
184196
mode.add_argument("--issue-number", type=int, help="Check a single issue number")
185-
parser.add_argument("--threshold", type=float, default=0.85, help="Similarity threshold (0-1)")
186-
parser.add_argument("--close", action="store_true", help="Actually close duplicates (default is dry-run)")
187-
parser.add_argument("--repo", type=str, help="Repository (owner/repo). Auto-detected if omitted.")
197+
parser.add_argument(
198+
"--threshold", type=float, default=0.85, help="Similarity threshold (0-1)"
199+
)
200+
parser.add_argument(
201+
"--close",
202+
action="store_true",
203+
help="Actually close duplicates (default is dry-run)",
204+
)
205+
parser.add_argument(
206+
"--repo", type=str, help="Repository (owner/repo). Auto-detected if omitted."
207+
)
188208
args = parser.parse_args()
189209

190210
dry_run = not args.close
@@ -200,7 +220,9 @@ def main() -> None:
200220
count = scan_all(issues, args.threshold, args.repo, dry_run)
201221
print(f"\nTotal duplicates {'found' if dry_run else 'closed'}: {count}")
202222
else:
203-
found = check_single(args.issue_number, issues, args.threshold, args.repo, dry_run)
223+
found = check_single(
224+
args.issue_number, issues, args.threshold, args.repo, dry_run
225+
)
204226
sys.exit(0 if found else 0) # Always exit 0; finding no dup is not an error
205227

206228

.github/scripts/scan_keywords.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,13 @@ def send_webhook(webhook_url: str, payload: dict) -> None:
6767
def _excerpt(text: str, max_len: int = 400) -> str:
6868
if not text:
6969
return ""
70-
70+
7171
# Keep original formatting
7272
if len(text) <= max_len:
7373
return text
7474
return text[: max_len - 1] + "…"
7575

7676

77-
7877
def main() -> int:
7978
event = read_event_payload()
8079
if not event:
@@ -87,8 +86,19 @@ def main() -> int:
8786

8887
# Keywords from env or defaults
8988
keywords_env = os.environ.get("KEYWORDS", "")
90-
default_keywords = ["azure", "openai", "bedrock", "vertexai", "vertex ai", "anthropic"]
91-
keywords = [k.strip() for k in keywords_env.split(",")] if keywords_env else default_keywords
89+
default_keywords = [
90+
"azure",
91+
"openai",
92+
"bedrock",
93+
"vertexai",
94+
"vertex ai",
95+
"anthropic",
96+
]
97+
keywords = (
98+
[k.strip() for k in keywords_env.split(",")]
99+
if keywords_env
100+
else default_keywords
101+
)
92102

93103
matches = detect_keywords(combined_text, keywords)
94104
found = bool(matches)
@@ -129,5 +139,3 @@ def main() -> int:
129139

130140
if __name__ == "__main__":
131141
raise SystemExit(main())
132-
133-

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ LiteLLM is a unified interface for 100+ LLM providers with two main components:
110110
- When wiring a new UI entity type to an existing backend endpoint, verify the backend API contract (single value vs. array, required vs. optional params) and ensure the UI controls match — e.g., use a single-select dropdown when the backend accepts a single value, not a multi-select
111111

112112
### UI Component Library
113-
- **Always use `antd` for new UI components** — we are migrating off of `@tremor/react`. Do not introduce new `Badge`, `Text`, `Card`, `Grid`, `Title`, or other imports from `@tremor/react` in any new or modified file. Use `antd` equivalents: `Tag` for labels, plain `<span>`/`<div>` with Tailwind classes (or `Typography.Text`) for text, `Card` from `antd`, etc. Note that `antd` has no `"yellow"` Tag color — use `"gold"` for amber/yellow.
113+
- **Always use `antd` for new UI components** — we are migrating off of `@tremor/react`. Do not introduce new `Badge`, `Text`, `Card`, `Grid`, `Title`, or other imports from `@tremor/react` in any new or modified file. Use `antd` equivalents: `Tag` for labels, `Typography.Text` / `Typography.Title` / `Typography.Paragraph` for textual content (avoid plain text-only `<span>`, `<p>`, `<h*>` when Typography fits), and `Card` from `antd`. Note that `antd` has no `"yellow"` Tag color — use `"gold"` for amber/yellow.
114114

115115
### MCP OAuth / OpenAPI Transport Mapping
116116
- `TRANSPORT.OPENAPI` is a UI-only concept. The backend only accepts `"http"`, `"sse"`, or `"stdio"`. Always map it to `"http"` before any API call (including pre-OAuth temp-session calls).

ci_cd/run_migration.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ def create_migration(migration_name: str = None):
1717
try:
1818
# Get paths
1919
root_dir = Path(__file__).parent.parent
20-
migrations_dir = root_dir / "litellm-proxy-extras" / "litellm_proxy_extras" / "migrations"
20+
migrations_dir = (
21+
root_dir / "litellm-proxy-extras" / "litellm_proxy_extras" / "migrations"
22+
)
2123
schema_path = root_dir / "schema.prisma"
2224

2325
# Create temporary PostgreSQL database

cookbook/anthropic_agent_sdk/agent_with_mcp.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,26 @@ async def interactive_chat_with_mcp():
2424
Interactive CLI chat with the agent and MCP server
2525
"""
2626
config = Config()
27-
27+
2828
# Configure Anthropic SDK to point to LiteLLM gateway
2929
litellm_base_url = setup_litellm_env(config)
30-
30+
3131
# Fetch available models from proxy
32-
available_models = await fetch_available_models(litellm_base_url, config.LITELLM_API_KEY)
33-
32+
available_models = await fetch_available_models(
33+
litellm_base_url, config.LITELLM_API_KEY
34+
)
35+
3436
current_model = config.LITELLM_MODEL
35-
37+
3638
# MCP server configuration
3739
mcp_server_url = f"{litellm_base_url}/mcp/deepwiki2"
3840
use_mcp = os.getenv("USE_MCP", "true").lower() == "true"
39-
41+
4042
if not use_mcp:
4143
print("⚠️ MCP disabled via USE_MCP=false")
42-
44+
4345
print_header(litellm_base_url, current_model, has_mcp=use_mcp)
44-
46+
4547
while True:
4648
# Configure agent options
4749
if use_mcp:
@@ -58,7 +60,7 @@ async def interactive_chat_with_mcp():
5860
"url": mcp_server_url,
5961
"headers": {
6062
"Authorization": f"Bearer {config.LITELLM_API_KEY}"
61-
}
63+
},
6264
}
6365
},
6466
)
@@ -78,47 +80,49 @@ async def interactive_chat_with_mcp():
7880
model=current_model,
7981
max_turns=50,
8082
)
81-
83+
8284
# Create agent client
8385
try:
8486
async with ClaudeSDKClient(options=options) as client:
8587
conversation_active = True
86-
88+
8789
while conversation_active:
8890
# Get user input
8991
try:
9092
user_input = input("\n👤 You: ").strip()
9193
except (EOFError, KeyboardInterrupt):
9294
print("\n\n👋 Goodbye!")
9395
return
94-
96+
9597
# Handle commands
96-
if user_input.lower() in ['quit', 'exit']:
98+
if user_input.lower() in ["quit", "exit"]:
9799
print("\n👋 Goodbye!")
98100
return
99-
100-
if user_input.lower() == 'clear':
101+
102+
if user_input.lower() == "clear":
101103
print("\n🔄 Starting new conversation...\n")
102104
conversation_active = False
103105
continue
104-
105-
if user_input.lower() == 'models':
106+
107+
if user_input.lower() == "models":
106108
handle_model_list(available_models, current_model)
107109
continue
108-
109-
if user_input.lower() == 'model':
110-
new_model, should_restart = handle_model_switch(available_models, current_model)
110+
111+
if user_input.lower() == "model":
112+
new_model, should_restart = handle_model_switch(
113+
available_models, current_model
114+
)
111115
if should_restart:
112116
current_model = new_model
113117
conversation_active = False
114118
continue
115-
119+
116120
if not user_input:
117121
continue
118-
122+
119123
# Stream response from agent
120124
await stream_response(client, user_input)
121-
125+
122126
except Exception as e:
123127
print(f"\n❌ Error creating agent client: {e}")
124128
print("This might be an MCP configuration issue. Try running without MCP:")

0 commit comments

Comments
 (0)