fix: preserve relocated script readers and SDK env scan scope

This commit is contained in:
Devin AI 2026-11-10 20:44:16 +00:00
parent 6f23f880bb
commit b7d38b5475
6 changed files with 46 additions and 9 deletions

View file

@ -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()]));

View file

@ -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`);

View file

@ -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];

View file

@ -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))

View file

@ -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()

View file

@ -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()