Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/deployment/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ The authenticated entity will have:
| **OPENAI_MODEL_NAME** | Model name to use for OpenAI requests | No | "gpt-4o-2024-08-06" | Valid OpenAI model name (e.g., "gpt-4o", "gpt-4o-mini", ...) | Both |
| **OPEN_AI_ORGANIZATION_ID** | Organization ID for OpenAI services | No | None | Valid OpenAI organization ID | Both |
| **OPENAI_BASE_URL** | Base URL for OpenAI API (useful for LiteLLM proxy) | No | None | Valid URL (e.g., "http://localhost:4000") | Both |
| **KEEP_AI_DISABLE_TEMPERATURE** | Omit the `temperature` parameter from AI requests (some models, e.g. reasoning models, only accept the default and reject explicit values) | No | false | true / false | Backend |

<Tip>
For various different LLM based features, we also require to set these
Expand Down
3 changes: 2 additions & 1 deletion keep/api/bl/ai_suggestion_bl.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
IncidentDto,
IncidentsClusteringSuggestion,
)
from keep.api.utils.ai_utils import get_ai_temperature_kwargs


class AISuggestionBl:
Expand Down Expand Up @@ -461,7 +462,7 @@ def _get_ai_completion(self, system_prompt: str, user_prompt: str):
},
},
},
temperature=0.2,
**get_ai_temperature_kwargs(0.2),
)

def _process_incidents(
Expand Down
3 changes: 2 additions & 1 deletion keep/api/bl/incident_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from keep.api.consts import OPENAI_MODEL_NAME
from keep.api.models.db.incident import IncidentStatus
from keep.api.models.incident import IncidentDto
from keep.api.utils.ai_utils import get_ai_temperature_kwargs


class IncidentMetrics(BaseModel):
Expand Down Expand Up @@ -163,7 +164,7 @@ def __calculate_report_in_openai(
},
},
seed=1239,
temperature=0.2,
**get_ai_temperature_kwargs(0.2),
)

model_response = response.choices[0].message.content
Expand Down
22 changes: 22 additions & 0 deletions keep/api/utils/ai_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os

_TRUTHY = {"1", "true", "yes", "on"}


def is_ai_temperature_disabled() -> bool:
"""Whether the ``temperature`` parameter should be omitted from AI requests.

Controlled by the ``KEEP_AI_DISABLE_TEMPERATURE`` environment variable. Some
models (e.g. OpenAI reasoning models) only accept the default temperature and
reject any explicit value with a 400 error, so this allows opting out.
"""
return os.environ.get("KEEP_AI_DISABLE_TEMPERATURE", "false").strip().lower() in _TRUTHY


def get_ai_temperature_kwargs(temperature: float = 0.2) -> dict:
"""Return the ``temperature`` kwargs for an AI completion request.

Returns an empty dict when temperature is disabled (see
:func:`is_ai_temperature_disabled`), so the parameter is omitted entirely.
"""
return {} if is_ai_temperature_disabled() else {"temperature": temperature}
27 changes: 27 additions & 0 deletions tests/test_ai_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest

from keep.api.utils.ai_utils import (
get_ai_temperature_kwargs,
is_ai_temperature_disabled,
)


def test_temperature_included_by_default(monkeypatch):
monkeypatch.delenv("KEEP_AI_DISABLE_TEMPERATURE", raising=False)
assert is_ai_temperature_disabled() is False
assert get_ai_temperature_kwargs() == {"temperature": 0.2}
assert get_ai_temperature_kwargs(0.7) == {"temperature": 0.7}


@pytest.mark.parametrize("value", ["true", "True", "TRUE", " 1 ", "yes", "on"])
def test_temperature_omitted_when_disabled(monkeypatch, value):
monkeypatch.setenv("KEEP_AI_DISABLE_TEMPERATURE", value)
assert is_ai_temperature_disabled() is True
assert get_ai_temperature_kwargs(0.2) == {}


@pytest.mark.parametrize("value", ["false", "0", "no", "off", ""])
def test_temperature_kept_for_falsy_values(monkeypatch, value):
monkeypatch.setenv("KEEP_AI_DISABLE_TEMPERATURE", value)
assert is_ai_temperature_disabled() is False
assert get_ai_temperature_kwargs(0.2) == {"temperature": 0.2}
Loading