diff --git a/pyproject.toml b/pyproject.toml index 660fc11f..aa0c0cf0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,6 +93,11 @@ asyncio_default_fixture_loop_scope = "session" addopts = "--strict-markers --cov=src/ --cov=sdks/python/src/honcho --cov-report=term-missing --ignore=tests/alembic" testpaths = ["tests"] pythonpath = ["src"] +filterwarnings = [ + "ignore::DeprecationWarning:cashews.*:", + "ignore::DeprecationWarning:websockets.*:", + "ignore::DeprecationWarning:uvicorn.*:", +] [tool.coverage.report] exclude_lines = [ diff --git a/src/config.py b/src/config.py index f01c451b..a500df5a 100644 --- a/src/config.py +++ b/src/config.py @@ -251,6 +251,9 @@ class DeriverSettings(BackupLLMSettingsMixin, HonchoSettings): PROVIDER: SupportedProviders = "google" MODEL: str = "gemini-2.5-flash-lite" TEMPERATURE: float | None = None + TOP_P: float | None = None + REPETITION_PENALTY: float | None = None + NO_REPEAT_NGRAM_SIZE: int | None = None # Whether to deduplicate documents when creating them DEDUPLICATE: bool = True diff --git a/src/deriver/deriver.py b/src/deriver/deriver.py index b8735e3c..022e0d77 100644 --- a/src/deriver/deriver.py +++ b/src/deriver/deriver.py @@ -131,6 +131,9 @@ async def process_representation_tasks_batch( response_model=PromptRepresentation, json_mode=True, temperature=settings.DERIVER.TEMPERATURE, + top_p=settings.DERIVER.TOP_P, + repetition_penalty=settings.DERIVER.REPETITION_PENALTY, + no_repeat_ngram_size=settings.DERIVER.NO_REPEAT_NGRAM_SIZE, stop_seqs=[" \n", "\n\n\n\n"], thinking_budget_tokens=settings.DERIVER.THINKING_BUDGET_TOKENS, max_input_tokens=settings.DERIVER.MAX_INPUT_TOKENS, diff --git a/src/utils/clients.py b/src/utils/clients.py index ae1beadd..39dac35d 100644 --- a/src/utils/clients.py +++ b/src/utils/clients.py @@ -573,6 +573,9 @@ async def _stream_final_response( response_model: type[BaseModel] | None, json_mode: bool, temperature: float | None, + top_p: float | None, + repetition_penalty: float | None, + no_repeat_ngram_size: int | None, stop_seqs: list[str] | None, reasoning_effort: ReasoningEffortType, verbosity: VerbosityType, @@ -616,6 +619,9 @@ async def _stream_final_response( response_model, json_mode, _get_effective_temperature(temperature), + top_p, + repetition_penalty, + no_repeat_ngram_size, stop_seqs, reasoning_effort, verbosity, @@ -643,6 +649,9 @@ async def _execute_tool_loop( response_model: type[BaseModel] | None, json_mode: bool, temperature: float | None, + top_p: float | None, + repetition_penalty: float | None, + no_repeat_ngram_size: int | None, stop_seqs: list[str] | None, reasoning_effort: ReasoningEffortType, verbosity: VerbosityType, @@ -745,6 +754,9 @@ async def _execute_tool_loop( response_model, json_mode, _get_effective_temperature(temperature), + top_p, + repetition_penalty, + no_repeat_ngram_size, stop_seqs, gpt5_reasoning_effort, gpt5_verbosity, @@ -808,6 +820,9 @@ async def _execute_tool_loop( response_model=response_model, json_mode=json_mode, temperature=temperature, + top_p=top_p, + repetition_penalty=repetition_penalty, + no_repeat_ngram_size=no_repeat_ngram_size, stop_seqs=stop_seqs, reasoning_effort=reasoning_effort, verbosity=verbosity, @@ -941,6 +956,9 @@ async def _execute_tool_loop( response_model=response_model, json_mode=json_mode, temperature=temperature, + top_p=top_p, + repetition_penalty=repetition_penalty, + no_repeat_ngram_size=no_repeat_ngram_size, stop_seqs=stop_seqs, reasoning_effort=reasoning_effort, verbosity=verbosity, @@ -977,6 +995,9 @@ async def _execute_tool_loop( response_model, json_mode, _get_effective_temperature(temperature), + top_p, + repetition_penalty, + no_repeat_ngram_size, stop_seqs, reasoning_effort, verbosity, @@ -1182,6 +1203,9 @@ async def honcho_llm_call( response_model: type[M], json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1211,6 +1235,9 @@ async def honcho_llm_call( response_model: None = None, json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1240,6 +1267,9 @@ async def honcho_llm_call( response_model: type[BaseModel] | None = None, json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1269,6 +1299,9 @@ async def honcho_llm_call( response_model: type[BaseModel] | None = None, json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1422,6 +1455,9 @@ async def honcho_llm_call( response_model, json_mode, _get_effective_temperature(temperature), + top_p, + repetition_penalty, + no_repeat_ngram_size, stop_seqs, gpt5_reasoning_effort, gpt5_verbosity, @@ -1439,6 +1475,9 @@ async def honcho_llm_call( response_model, json_mode, _get_effective_temperature(temperature), + top_p, + repetition_penalty, + no_repeat_ngram_size, stop_seqs, gpt5_reasoning_effort, gpt5_verbosity, @@ -1522,6 +1561,9 @@ async def honcho_llm_call( response_model=response_model, json_mode=json_mode, temperature=temperature, + top_p=top_p, + repetition_penalty=repetition_penalty, + no_repeat_ngram_size=no_repeat_ngram_size, stop_seqs=stop_seqs, reasoning_effort=reasoning_effort, verbosity=verbosity, @@ -1559,6 +1601,9 @@ async def honcho_llm_call_inner( response_model: type[M], json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1580,6 +1625,9 @@ async def honcho_llm_call_inner( response_model: None = None, json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1601,6 +1649,9 @@ async def honcho_llm_call_inner( response_model: type[BaseModel] | None = None, json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1621,6 +1672,9 @@ async def honcho_llm_call_inner( response_model: type[BaseModel] | None = None, json_mode: bool = False, temperature: float | None = None, + top_p: float | None = None, + repetition_penalty: float | None = None, + no_repeat_ngram_size: int | None = None, stop_seqs: list[str] | None = None, reasoning_effort: Literal["low", "medium", "high", "minimal"] | None = None, # OpenAI only @@ -1865,6 +1919,21 @@ async def honcho_llm_call_inner( if temperature is not None and "gpt-5" not in model: openai_params["temperature"] = temperature + # Add generation parameters for explicit control + if top_p is not None: + openai_params["top_p"] = top_p + + # Add vLLM-specific parameters only for vLLM provider + # These are not standard OpenAI API parameters and must be passed via extra_body + if provider == "vllm": + extra_body: dict[str, Any] = {} + if repetition_penalty is not None: + extra_body["repetition_penalty"] = repetition_penalty + if no_repeat_ngram_size is not None: + extra_body["no_repeat_ngram_size"] = no_repeat_ngram_size + if extra_body: + openai_params["extra_body"] = extra_body + if "gpt-5" in model: openai_params["max_completion_tokens"] = params["max_tokens"] if reasoning_effort: