diff --git a/backend/.env.example b/backend/.env.example index e7a3cba..e22ddba 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -21,6 +21,9 @@ OPENCAD_AGENT_LIVE_KERNEL=false OPENCAD_TREE_LIVE_KERNEL=true OPENCAD_AGENT_LIVE_KERNEL=true +OPENCAD_LLM_PROVIDER= +OPENCAD_LLM_MODEL= + # Optional multi-provider LLM support for code generation uses LiteLLM. # Provider-specific credentials are still read from each provider's standard env vars. # Example request fields: llm_provider="openai", llm_model="gpt-4o-mini", generate_code=true diff --git a/backend/opencad_agent/llm.py b/backend/opencad_agent/llm.py index 4b74d72..cf17d17 100644 --- a/backend/opencad_agent/llm.py +++ b/backend/opencad_agent/llm.py @@ -20,12 +20,6 @@ def _default_completion(**kwargs: Any) -> Any: return completion(**kwargs) -def _resolve_model_name(provider: str | None, model: str) -> str: - if provider and "/" not in model: - return f"{provider}/{model}" - return model - - def _strip_code_fences(code: str) -> str: code = code.strip() if code.startswith("```python"): @@ -68,7 +62,6 @@ def __init__(self, completion_func: LiteLlmCompletion | None = None) -> None: def generate_code( self, *, - provider: str | None, model: str, system_prompt: str, user_message: str, @@ -79,9 +72,10 @@ def generate_code( messages.extend({"role": item.role, "content": item.content} for item in conversation_history) messages.append({"role": "user", "content": user_message}) response = self._completion( - model=_resolve_model_name(provider, model), + model=model, messages=messages, temperature=HIGH_REASONING_CODE_TEMPERATURE if reasoning else DEFAULT_CODE_TEMPERATURE, ) logger.debug("Received LLM code-generation response") - return _strip_code_fences(_extract_message_content(response)) + cleaned_response = _strip_code_fences(_extract_message_content(response)) + return cleaned_response diff --git a/backend/opencad_agent/models.py b/backend/opencad_agent/models.py index c3720b7..b6de661 100644 --- a/backend/opencad_agent/models.py +++ b/backend/opencad_agent/models.py @@ -17,15 +17,8 @@ class ChatRequest(BaseModel): tree_state: FeatureTree conversation_history: list[ChatHistoryItem] = Field(default_factory=list) reasoning: bool = False - llm_provider: str | None = None - llm_model: str | None = None generate_code: bool = False - @model_validator(mode="after") - def _validate_llm_configuration(self) -> ChatRequest: - if self.llm_provider and not self.llm_model: - raise ValueError("llm_model is required when llm_provider is set.") - return self class OperationExecution(BaseModel): diff --git a/backend/opencad_agent/service.py b/backend/opencad_agent/service.py index c29a802..7971498 100644 --- a/backend/opencad_agent/service.py +++ b/backend/opencad_agent/service.py @@ -124,11 +124,10 @@ def _execute_code_in_context(code: str, ctx: object) -> None: reset_default_context() def _generate_code(self, request: ChatRequest) -> str: - provider = request.llm_provider or os.environ.get("OPENCAD_LLM_PROVIDER") - model = request.llm_model or os.environ.get("OPENCAD_LLM_MODEL") + model = os.environ.get("OPENCAD_LLM_MODEL") + if model: return self.llm_client.generate_code( - provider=provider, model=model, system_prompt=build_code_generation_prompt(request.tree_state), user_message=request.message,