Repository navigation
Make heavy integrations optional dependencies (lite core install) - #196
Merged
Merged
Conversation
`pip install sgr-agent-core` pulled ~75 packages transitively, though the SGR core -- agent loop, schemas, config, registries, skills -- used five of them. tavily, fastmcp, fastapi/uvicorn, agent-client-protocol and langfuse were all hard requirements. Core now installs PyYAML, pydantic, pydantic-settings, openai and httpx[socks] only: 21 packages. Integrations move to extras (mcp, search, server, acp, langfuse, plus meta-extras all/examples) and are imported at call time, so a missing one surfaces as an actionable message naming the install command instead of a bare ModuleNotFoundError. Decoupling notes: - AgentConfig.mcp was typed with fastmcp's MCPConfig, which a lazy import cannot fix. Core now ships its own lightweight MCPConfig (same shape, including the wrap-servers-at-root validator); mcp_service converts it to the fastmcp model only when servers are actually configured. - tavily moves inside _search_tavily and _extract. The brave and perplexity engines already speak plain HTTP, so web search still works on core. - sgr and sgracp report the missing extra and exit 1. This needed acp/__init__.py to resolve its exports through PEP 562 __getattr__, otherwise the subpackage import itself died first. - python-dateutil was unused anywhere and is dropped; rank-bm25 is used only by examples/progressive_discovery and moves to the examples extra. Docker installs .[examples] so the image keeps its full dependency set. A new CI job installs bare core and fails if a top-level import of an optional package creeps back in. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The agent selector passed category="_agent". agent-client-protocol 0.12 narrowed SessionConfigOptionSelect.category to "mode" | "model" | "model_config" | "thought_level" | a free-form dict, and its schema salvages invalid values to None instead of raising -- so the option silently lost its category and test_acp_new_session_advertises_agent_and_model_options failed. "_agent" was never a standard value, so clients already treated it as an unknown category. Drop it and assert None, which matches what they see. The model selector keeps category="model", which is still valid. Pre-existing on main: reproduces on the commit before the extras split. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GlobalConfig caches its instance on the class, and TestLangfuseConfiguration clears that cache before building a config with langfuse.enabled=True but never after -- so every test that ran later inherited it. Where the optional langfuse package is absent that surfaced as 23 failures in test_agent_factory.py, since AgentFactory._create_client then took the Langfuse path and raised. Where langfuse is installed, as on CI, the same pollution was silent: later tests ran with tracing enabled and passed for the wrong reason. An autouse fixture resets the singleton on both sides of every test. The suite is now order-independent and green on Windows too: 614 passed. The per-test resets already scattered through three test modules are left alone -- they are redundant now but harmless. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
hijera
added a commit
to googio/sgr-agent-core
that referenced
this pull request
Sep 16, 2026
vamplabAI#196 documents brave and perplexity as the engines that work without the [search] extra; serply also only needs httpx, so add it to those lists. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
pip install sgr-agent-corepulls ~75 packages transitively, though the SGR core — agent loop, schemas, config, registries, skills — uses five of them.tavily,fastmcp,fastapi/uvicorn,agent-client-protocolandlangfuseare all hard requirements today, so anyone who wants "just SGR" gets the MCP stack, a web framework, an OpenTelemetry stack,cryptography,tiktoken,numpy,pywin32and the rest.What changed
Core install is now
PyYAML,pydantic,pydantic-settings,openai,httpx[socks]— 21 packages. Everything else is an extra:mcpfastmcp,jambomcp:config keysearchtavily-pythonWebSearchToolwithengine: tavily,ExtractPageContentToolserverfastapi,uvicornsgrHTTP API serveracpagent-client-protocolsgracpstdio serverlangfuselangfuselangfuse.enabled: trueallexamplesall+rank-bm25examples/needMissing extras surface as an actionable message, never a bare
ModuleNotFoundError:Decoupling notes
fastmcpwas the hard part.AgentConfig.mcpwas typed with fastmcp'sMCPConfig, and a pydantic field type cannot be made lazy. Core now ships its own lightweightMCPConfig(sgr_agent_core/mcp_config.py) with the same shape, including the wrap-servers-at-root validator;mcp_serviceconverts it to the fastmcp model only when servers are actually configured.agent_def.mcphad exactly one consumer, so the change is contained.tavilymoves inside_search_tavilyand_extract. Thebraveandperplexityengines already speak plain HTTP, so web search still works on a core-only install.sgr/sgracpreport the missing extra and exit 1. This requiredacp/__init__.pyto resolve its exports through PEP 562__getattr__— otherwise the subpackage import died before the entrypoint could say anything useful.langfusewas already imported lazily inagent_factory; it was simply listed as a hard dependency for no reason. Only the error text changed.python-dateutilis unused anywhere in the repo and is dropped.rank-bm25is used only byexamples/progressive_discoveryand moves to theexamplesextra.Docker / CI
Dockerfileinstalls.[examples]— the image keeps its full dependency set, includingrank-bm25for the bundled examples. No capability change.test-core-onlyCI job installs bare core and fails if an optional package is present or gets imported at module scope. Without it, one stray top-level import silently puts every heavy dependency back.Second commit: unrelated CI breakage, fixed here to get green
test_acp_new_session_advertises_agent_and_model_optionswas already failing onmainbefore this PR (verified by running it against the previous commit).agent-client-protocol0.12 narrowedSessionConfigOptionSelect.categoryto"mode" | "model" | "model_config" | "thought_level" | dict, and its schema salvages invalid values toNonerather than raising — so the bridge'scategory="_agent"was being silently dropped."_agent"was never a standard value, so clients already treated the option as uncategorised. The fix removes it and assertsNone, matching what clients actually see. The model selector keepscategory="model", which is still valid. Happy to split this out if you'd rather land it separately.Verification
Clean venv,
pip install .:fastmcp/tavily/fastapi/uvicorn/acp/langfuse/rank-bm25/dateutilinstalled or importedAgentFactory.createbuilds a workingSGRToolCallingAgent; all 13 tools registersgrsh --helpworks;sgrandsgracpname their extra and exit 1pip install ".[mcp,search]"restores the fastmcp client and Tavily;server/acp/langfusestay absentall,examples,tests,dev) resolve correctly (needs pip ≥ 21.2)New
tests/test_optional_deps.py— 26 tests covering install hints, the coreMCPConfig, both tavily call sites, MCP with fastmcp blocked, and both entrypoints. CI is green: 614 passed, and the suite now also runs clean on Windows (it did not before this branch).Reviewer notes
sgrserver and MCP. Worth a minor version bump and a release note pointing atpip install "sgr-agent-core[all]".openaideliberately stays in core. Its types (ChatCompletionMessageParam,ChatCompletionChunk,AsyncOpenAI) run throughbase_agent,stream,models,prompt_loaderand the public API; removing it means rewriting the core typing, not adding a lazy import.test_extract_calls_tavily_apipatched the now-absent module attributeAsyncTavilyClient; it patchestavily.AsyncTavilyClientat the source instead.GlobalConfigcaches its instance on the class, andTestLangfuseConfigurationcleared that cache before building a config withlangfuse.enabled=Truebut never after, so every later test inherited it. On a machine without the optionallangfusepackage that surfaced as 23 failures intest_agent_factory.py; on CI, wherelangfuseis installed, the pollution was silent — later tests ran with tracing enabled and passed for the wrong reason. An autouse fixture inconftest.pynow resets the singleton around every test, making the suite order-independent. Happy to split this out too.рџ¤– Generated with Claude Code