Add workflow-copilot lite LLM env key (#7194)
Some checks are pending
Run tests and pre-commit / Run tests and pre-commit hooks (push) Waiting to run
Run tests and pre-commit / Frontend Lint and Build (push) Waiting to run
Run tests and pre-commit / pip Package Smoke Tests (3.11) (push) Waiting to run
Run tests and pre-commit / pip Package Smoke Tests (3.13) (push) Waiting to run
Publish Fern Docs / run (push) Waiting to run

This commit is contained in:
Andrew Neilson 2026-07-07 23:46:19 -07:00 committed by GitHub
parent c78637ae87
commit 3fc353fe04
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 1 deletions

View file

@ -353,6 +353,7 @@ class Settings(BaseSettings):
WORKFLOW_COPILOT_LLM_KEY: str | None = None
WORKFLOW_COPILOT_AGENT_LLM_KEY: str | None = None
WORKFLOW_COPILOT_FAST_LLM_KEY: str | None = None
WORKFLOW_COPILOT_LITE_LLM_KEY: str | None = None
# COMMON
LLM_CONFIG_TIMEOUT: int = 300
LLM_CONFIG_MAX_TOKENS: int = 4096

View file

@ -92,6 +92,7 @@ class ForgeApp:
WORKFLOW_COPILOT_LLM_API_HANDLER: LLMAPIHandler
WORKFLOW_COPILOT_AGENT_LLM_API_HANDLER: LLMAPIHandler
WORKFLOW_COPILOT_FAST_LLM_API_HANDLER: LLMAPIHandler
WORKFLOW_COPILOT_LITE_LLM_API_HANDLER: LLMAPIHandler | None
WORKFLOW_CONTEXT_MANAGER: WorkflowContextManager
WORKFLOW_SERVICE: WorkflowService
AGENT_FUNCTION: AgentFunction
@ -274,6 +275,11 @@ def create_forge_app() -> ForgeApp:
if settings.WORKFLOW_COPILOT_FAST_LLM_KEY
else app.SECONDARY_LLM_API_HANDLER
)
app.WORKFLOW_COPILOT_LITE_LLM_API_HANDLER = (
LLMAPIHandlerFactory.get_llm_api_handler(settings.WORKFLOW_COPILOT_LITE_LLM_KEY)
if settings.WORKFLOW_COPILOT_LITE_LLM_KEY
else None
)
app.WORKFLOW_CONTEXT_MANAGER = WorkflowContextManager()
app.WORKFLOW_SERVICE = WorkflowService()

View file

@ -50,6 +50,13 @@ def get_fast_copilot_handler() -> Any | None:
return None
def get_lite_copilot_handler() -> Any | None:
try:
return app.WORKFLOW_COPILOT_LITE_LLM_API_HANDLER
except (RuntimeError, AttributeError):
return None
async def resolve_main_copilot_handler(workflow_permanent_id: str | None, organization_id: str | None) -> Any | None:
if workflow_permanent_id and organization_id:
try:
@ -105,4 +112,7 @@ async def resolve_lite_copilot_handler(workflow_permanent_id: str | None, organi
posthog_handler = None
if posthog_handler is not None:
return posthog_handler
handler = get_lite_copilot_handler()
if handler is not None:
return handler
return await resolve_workflow_copilot_handler(workflow_permanent_id, organization_id)

View file

@ -3,7 +3,8 @@
Optional settings give operators independent control over the main Copilot lane,
agent-specific lane, and fast-consumer lane:
``WORKFLOW_COPILOT_LLM_KEY``, ``WORKFLOW_COPILOT_AGENT_LLM_KEY``, and
``WORKFLOW_COPILOT_FAST_LLM_KEY``.
``WORKFLOW_COPILOT_FAST_LLM_KEY``. ``WORKFLOW_COPILOT_LITE_LLM_KEY`` controls
the dedicated RequestPolicy lite lane for local/dev fallback.
These tests cover the public contract: defaults, fallback chains, and
PostHog env-specific default resolution order.
"""
@ -36,6 +37,10 @@ def test_workflow_copilot_fast_llm_key_default_is_none() -> None:
assert Settings.model_fields["WORKFLOW_COPILOT_FAST_LLM_KEY"].default is None
def test_workflow_copilot_lite_llm_key_default_is_none() -> None:
assert Settings.model_fields["WORKFLOW_COPILOT_LITE_LLM_KEY"].default is None
# ---------------------------------------------------------------------------
# _get_narrator_handler fallback chain
# ---------------------------------------------------------------------------
@ -361,6 +366,30 @@ async def test_resolve_lite_copilot_handler_falls_back_to_workflow_copilot(
assert handler is workflow_handler
@pytest.mark.asyncio
async def test_resolve_lite_copilot_handler_prefers_dedicated_key_before_workflow_copilot(
monkeypatch: pytest.MonkeyPatch,
) -> None:
lite_handler = object()
async def _posthog_lookup(*_args: object, **_kwargs: object) -> None:
return None
async def _workflow_lookup(*_args: object, **_kwargs: object) -> object:
raise AssertionError("workflow fallback should not run when lite key is set")
monkeypatch.setattr(copilot_llm_config, "get_llm_handler_for_prompt_type", _posthog_lookup)
monkeypatch.setattr(copilot_llm_config, "resolve_workflow_copilot_handler", _workflow_lookup)
monkeypatch.setattr(
copilot_llm_config,
"app",
SimpleNamespace(WORKFLOW_COPILOT_LITE_LLM_API_HANDLER=lite_handler),
)
handler = await copilot_llm_config.resolve_lite_copilot_handler("wpid_1", "org_1")
assert handler is lite_handler
@pytest.mark.asyncio
async def test_resolve_lite_copilot_handler_fallback_ignores_agent_specific_key(
monkeypatch: pytest.MonkeyPatch,