Skip to content
Open
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases)

## Unreleased

- Feature: the `kimi` backend now sends an explicit `reasoning_effort` (default `max`, overridable via `GRAPHIFY_KIMI_EFFORT`) for Kimi models that support it — K3 advertises `valid_efforts ["low","high","max"]` on `/models`, and sending nothing let the server default (`"high"` for K3) apply silently while the gemini backend already carried an effort setting. Forwarded by the existing request plumbing; no behaviour change for models that ignore the field.

## 0.9.49 (2026-08-24)

- Feature: `graphify merge-graphs` now links a type declaration that two repos share — same fully-qualified namespace and name, from different repos — with a `same_type_as` edge, so a shared contract type is navigable across the repo boundary; two unrelated types that merely share a short name are not linked (#3007, thanks @durmazoguzhan).
Expand Down
6 changes: 6 additions & 0 deletions graphify/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ def _resolve_ollama_base_url(default: str) -> str:
"pricing": {"input": 0.74, "output": 4.66}, # USD per 1M tokens
"temperature": None, # kimi-k2.6 enforces its own fixed temperature; sending any value raises 400
"max_tokens": 16384,
# Reasoning effort for Kimi models that support it (K3 advertises
# valid_efforts ["low","high","max"] on /models). Sending nothing lets the
# server default ("high" for K3) apply silently, while the gemini block
# above carries an effort setting. Forwarded as `reasoning_effort` by the
# existing request plumbing; models that ignore the field are unaffected.
"reasoning_effort": os.environ.get("GRAPHIFY_KIMI_EFFORT", "max"),
},
"ollama": {
"base_url": _resolve_ollama_base_url("http://localhost:11434/v1"),
Expand Down
31 changes: 31 additions & 0 deletions tests/test_kimi_reasoning_effort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Tests for the kimi backend's reasoning_effort config (GRAPHIFY_KIMI_EFFORT).

Kimi K3 advertises valid_efforts ["low","high","max"] on /models; sending
nothing let the server default ("high") apply silently. The backend config now
carries an explicit effort, defaulting to "max", overridable via env — the
same import-time pattern as ANTHROPIC_BASE_URL on the claude backend.
"""

import importlib

from graphify import llm


def test_kimi_reasoning_effort_defaults_to_max(monkeypatch):
monkeypatch.delenv("GRAPHIFY_KIMI_EFFORT", raising=False)
reloaded = importlib.reload(llm)
try:
assert reloaded.BACKENDS["kimi"]["reasoning_effort"] == "max"
finally:
monkeypatch.undo()
importlib.reload(llm)


def test_kimi_reasoning_effort_env_override(monkeypatch):
monkeypatch.setenv("GRAPHIFY_KIMI_EFFORT", "low")
reloaded = importlib.reload(llm)
try:
assert reloaded.BACKENDS["kimi"]["reasoning_effort"] == "low"
finally:
monkeypatch.undo()
importlib.reload(llm)