Part of #142.
Summary
Python SDK client calls to Google Gemini are not detected. In sapling, services/gemini_service.py:74 — _client.models.generate_content(...) (the google.genai SDK) — produced zero endpoints; the entire Gemini-backed backend scanned as 0 external calls.
Root cause
PACKAGE_TO_PROVIDER (src/ast/ast-scanner.ts:98-114) and CLASS_TO_PACKAGE (src/ast/import-resolver.ts:47-73) are JS-centric. The Python Google-AI packages — google.genai (new from google import genai → genai.Client()) and google.generativeai — have no entry. processPythonAssignment (import-resolver.ts:497) resolves _client = genai.Client() to package "google" (the import segment); "google" maps to no provider, so resolveProvider yields provider "google", no fingerprint matches, and the gate at core-scanner.ts:269 drops it.
- Even with the mapping, client-var binding only happens for top-level assignments. Clients created inside a function body or
async with httpx.AsyncClient() as client: / with genai.Client() as c: are never recorded — buildExtendedMaps (ast-scanner.ts:315) and resolveImportsCore (import-resolver.ts:531) only walk top-level tree.rootNode statements.
Proposed fix
- Add Python AI packages to the package→provider map:
google.genai / google.generativeai → gemini; confirm openai, anthropic, cohere, mistralai Python roots resolve. Add the genai.Client / genai.GenerativeModel constructor names to CLASS_TO_PACKAGE.
- Track client-var assignments in nested scopes (function bodies,
with / async with aliases), not just module top-level.
- Ensure the registry has the SDK method chains:
lookupMethod("gemini", "models.generate_content" | "models.generateContent" | "GenerativeModel.generate_content"). gemini.json already has the REST endpoints; add the SDK chains.
Evidence
node dist/cli/scan.js /path/to/sapling/backend --format json → 215 endpoints, all provider:internal, 0 Gemini. Manual scan found ~26 Gemini sites incl. services/gemini_service.py:74, services/flashcard_import_service.py:240/251/259/266, services/course_context_service.py:56.
Acceptance criteria
Part of #142.
Summary
Python SDK client calls to Google Gemini are not detected. In
sapling,services/gemini_service.py:74—_client.models.generate_content(...)(thegoogle.genaiSDK) — produced zero endpoints; the entire Gemini-backed backend scanned as 0 external calls.Root cause
PACKAGE_TO_PROVIDER(src/ast/ast-scanner.ts:98-114) andCLASS_TO_PACKAGE(src/ast/import-resolver.ts:47-73) are JS-centric. The Python Google-AI packages —google.genai(newfrom google import genai→genai.Client()) andgoogle.generativeai— have no entry.processPythonAssignment(import-resolver.ts:497) resolves_client = genai.Client()to package"google"(the import segment);"google"maps to no provider, soresolveProvideryields provider"google", no fingerprint matches, and the gate atcore-scanner.ts:269drops it.async with httpx.AsyncClient() as client:/with genai.Client() as c:are never recorded —buildExtendedMaps(ast-scanner.ts:315) andresolveImportsCore(import-resolver.ts:531) only walk top-leveltree.rootNodestatements.Proposed fix
google.genai/google.generativeai→gemini; confirmopenai,anthropic,cohere,mistralaiPython roots resolve. Add thegenai.Client/genai.GenerativeModelconstructor names toCLASS_TO_PACKAGE.with/async withaliases), not just module top-level.lookupMethod("gemini", "models.generate_content" | "models.generateContent" | "GenerativeModel.generate_content").gemini.jsonalready has the REST endpoints; add the SDK chains.Evidence
node dist/cli/scan.js /path/to/sapling/backend --format json→ 215 endpoints, allprovider:internal, 0 Gemini. Manual scan found ~26 Gemini sites incl.services/gemini_service.py:74,services/flashcard_import_service.py:240/251/259/266,services/course_context_service.py:56.Acceptance criteria
_client = genai.Client(); _client.models.generate_content(...)resolves to providergemini.withblock is attributed.sapling/backendsurfaces thegemini_service+flashcard_import_serviceGemini calls.