mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-13 08:52:02 +00:00
fix: preserve relocated script readers and SDK env scan scope
This commit is contained in:
parent
6f23f880bb
commit
b7d38b5475
6 changed files with 46 additions and 9 deletions
|
|
@ -24,7 +24,7 @@ import {
|
|||
type Schema,
|
||||
} from "./classify-issue";
|
||||
import { MANIFEST, NAMESPACES } from "./issue-labels";
|
||||
import schemaJson from "../.github/prompts/issue-classifier.schema.json";
|
||||
import schemaJson from "../../.github/prompts/issue-classifier.schema.json";
|
||||
|
||||
const schema = schemaJson as Schema;
|
||||
const routes = routesOf(schema);
|
||||
|
|
@ -133,7 +133,7 @@ describe("sections", () => {
|
|||
test("the known headings are exactly the field labels of the two issue forms", async () => {
|
||||
const labels = await Promise.all(
|
||||
["bug_report.yml", "feature_request.yml"].map(async (file) => {
|
||||
const form = Bun.YAML.parse(await Bun.file(`${import.meta.dir}/../.github/ISSUE_TEMPLATE/${file}`).text()) as {
|
||||
const form = Bun.YAML.parse(await Bun.file(`${import.meta.dir}/../../.github/ISSUE_TEMPLATE/${file}`).text()) as {
|
||||
readonly body: readonly { readonly attributes?: { readonly label?: string } }[];
|
||||
};
|
||||
return form.body.flatMap((field) => (field.attributes?.label === undefined ? [] : [field.attributes.label.trim()]));
|
||||
|
|
|
|||
|
|
@ -376,8 +376,8 @@ export function readConfig(
|
|||
|
||||
if (import.meta.main) {
|
||||
const { token, apiBase, apiKey, ...config } = readConfig(process.env, new Date());
|
||||
const prompt = await Bun.file(`${import.meta.dir}/../.github/prompts/issue-classifier.md`).text();
|
||||
const schema = (await Bun.file(`${import.meta.dir}/../.github/prompts/issue-classifier.schema.json`).json()) as Schema;
|
||||
const prompt = await Bun.file(`${import.meta.dir}/../../.github/prompts/issue-classifier.md`).text();
|
||||
const schema = (await Bun.file(`${import.meta.dir}/../../.github/prompts/issue-classifier.schema.json`).json()) as Schema;
|
||||
const verdict = await classifyIssue(githubApi(token), litellmClient(apiBase, apiKey), config, prompt, schema);
|
||||
if (verdict === null) {
|
||||
console.error(`#${config.issueNumber}: edit ignored, the issue is already classified or older than the edit window`);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import manifest from "../.github/issue-labels.json";
|
||||
import manifest from "../../.github/issue-labels.json";
|
||||
|
||||
export const NAMESPACES = ["domain", "provider", "kind", "priority", "lift", "needs"] as const;
|
||||
export type Namespace = (typeof NAMESPACES)[number];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import os
|
||||
import re
|
||||
from collections.abc import Iterator
|
||||
from typing import Final
|
||||
|
||||
# Define the base directory for the litellm repository and documentation path
|
||||
repo_base = "./litellm" # Change this to your actual path
|
||||
|
|
@ -76,6 +77,10 @@ SKIP_DIRS = {
|
|||
"build",
|
||||
}
|
||||
|
||||
NON_SDK_SOURCE_DIRS: Final = frozenset(
|
||||
{"cli", "deploy", "enterprise", "packaging", "proxy-extras", "runtime", "rust", "scripts", "ui", "vscode-extension"}
|
||||
)
|
||||
|
||||
|
||||
def extract_env_keys(source: str) -> frozenset[str]:
|
||||
"""Return every documentable env var name read by the given Python source."""
|
||||
|
|
@ -87,14 +92,18 @@ def extract_env_keys(source: str) -> frozenset[str]:
|
|||
def collect_env_keys(base_dir: str) -> frozenset[str]:
|
||||
"""Return every documentable env var name read anywhere under ``base_dir``."""
|
||||
return frozenset(
|
||||
key for file_path in _files_with_suffix(base_dir, (".py",)) for key in extract_env_keys(_read_text(file_path))
|
||||
key
|
||||
for file_path in _files_with_suffix(base_dir, (".py",), NON_SDK_SOURCE_DIRS)
|
||||
for key in extract_env_keys(_read_text(file_path))
|
||||
)
|
||||
|
||||
|
||||
def _files_with_suffix(base_dir: str, suffixes: tuple[str, ...]) -> Iterator[str]:
|
||||
def _files_with_suffix(
|
||||
base_dir: str, suffixes: tuple[str, ...], skip_root_dirs: frozenset[str] = frozenset()
|
||||
) -> Iterator[str]:
|
||||
for root, dirs, files in os.walk(base_dir):
|
||||
# Skip dependency/venv directories - prevents picking up env vars from installed packages
|
||||
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
|
||||
dirs[:] = [d for d in dirs if d not in SKIP_DIRS and (root != base_dir or d not in skip_root_dirs)]
|
||||
yield from (os.path.join(root, name) for name in files if name.endswith(suffixes))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ def dispatch(scripts: Scripts) -> Responder:
|
|||
return Reply(body=_MODEL_DISCOVERY_BODY)
|
||||
if request.target.startswith(TAVILY_TARGET):
|
||||
return tavily_reply(request)
|
||||
script: Final = litellm.scripts.lookup(request.body)
|
||||
script: Final = scripts.lookup(request.body)
|
||||
if script is None:
|
||||
return Reply(
|
||||
status=500, body=json.dumps({"error": {"message": f"no script for {request.target}"}}).encode()
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ than in the central reference table still counts as documented.
|
|||
import importlib.util
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
import pytest
|
||||
|
||||
_REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
_MODULE_PATH = _REPO_ROOT / "tests" / "documentation_tests" / "test_env_keys.py"
|
||||
|
|
@ -188,3 +191,28 @@ def test_only_documentation_pages_are_scanned_for_mentions(tmp_path: Path) -> No
|
|||
(tmp_path / "notes.txt").write_text("QSTASH_ALPHA\n", encoding="utf-8")
|
||||
(tmp_path / "example.py").write_text('get_secret("QSTASH_BRAVO")\n', encoding="utf-8")
|
||||
assert gate.collect_documented_keys(str(tmp_path)) == frozenset()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"directory",
|
||||
("cli", "deploy", "enterprise", "packaging", "proxy-extras", "runtime", "rust", "scripts", "ui", "vscode-extension"),
|
||||
)
|
||||
def test_relocated_sources_are_excluded_without_hiding_nested_sdk_sources(tmp_path: Path, directory: str) -> None:
|
||||
source_dir, docs_dir = _write_tree(tmp_path, 'os.getenv("SDK_DOCUMENTED_KEY")', "SDK_DOCUMENTED_KEY")
|
||||
relocated: Final = Path(source_dir) / directory
|
||||
relocated.mkdir()
|
||||
(relocated / "tool.py").write_text('os.getenv("NON_SDK_UNDOCUMENTED_KEY")', encoding="utf-8")
|
||||
assert gate.undocumented_env_keys(source_dir, docs_dir) == frozenset()
|
||||
|
||||
sdk_source: Final = Path(source_dir) / "llms" / directory
|
||||
sdk_source.mkdir(parents=True)
|
||||
(sdk_source / "provider.py").write_text('os.getenv("SDK_UNDOCUMENTED_KEY")', encoding="utf-8")
|
||||
assert gate.undocumented_env_keys(source_dir, docs_dir) == {"SDK_UNDOCUMENTED_KEY"}
|
||||
|
||||
|
||||
def test_source_exclusions_do_not_hide_documentation_pages(tmp_path: Path) -> None:
|
||||
source_dir, docs_dir = _write_tree(tmp_path, 'os.getenv("SDK_DOCUMENTED_KEY")', "")
|
||||
docs: Final = Path(docs_dir) / "scripts"
|
||||
docs.mkdir()
|
||||
(docs / "settings.md").write_text("SDK_DOCUMENTED_KEY", encoding="utf-8")
|
||||
assert gate.undocumented_env_keys(source_dir, docs_dir) == frozenset()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue