Skip to content
Closed
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Only write entries that are worth mentioning to users.
## Unreleased

- Core: Pass session ID as `user_id` metadata to Anthropic API
- Core: Strip whitespace from OAuth header values to prevent encoding errors

## 1.17.0 (2026-03-03)

Expand Down
1 change: 1 addition & 0 deletions docs/en/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This page documents the changes in each Kimi Code CLI release.
## Unreleased

- Core: Pass session ID as `user_id` metadata to Anthropic API
- Core: Strip whitespace from OAuth header values to prevent encoding errors

## 1.17.0 (2026-03-03)

Expand Down
1 change: 1 addition & 0 deletions docs/zh/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
## 未发布

- Core:将会话 ID 作为 `user_id` 元数据传递给 Anthropic API
- Core:对 OAuth 头字段值去除首尾空白,避免编码错误

## 1.17.0 (2026-03-03)

Expand Down
3 changes: 2 additions & 1 deletion src/kimi_cli/auth/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,10 @@ def get_device_id() -> str:


def _ascii_header_value(value: str, *, fallback: str = "unknown") -> str:
value = value.strip()
try:
value.encode("ascii")
return value
return value or fallback
except UnicodeEncodeError:
sanitized = value.encode("ascii", errors="ignore").decode("ascii").strip()
return sanitized or fallback
Expand Down
27 changes: 27 additions & 0 deletions tests/utils/test_utils_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import pytest
from kaos.path import KaosPath

from kimi_cli.auth.oauth import _ascii_header_value, _common_headers


@pytest.mark.skipif(platform.system() == "Windows", reason="Skipping test on Windows")
async def test_environment_detection(monkeypatch):
Expand Down Expand Up @@ -39,3 +41,28 @@ async def test_environment_detection_windows(monkeypatch):
assert env.os_version == "10.0.19044"
assert env.shell_name == "Windows PowerShell"
assert str(env.shell_path) == "powershell.exe"


def test_ascii_header_value_strips_ascii_whitespace():
assert _ascii_header_value(" value ") == "value"
assert _ascii_header_value(" ") == "unknown"


def test_common_headers_strip_os_version(monkeypatch):
monkeypatch.setattr(platform, "node", lambda: "host")
Comment on lines +46 to +52

Copilot AI Mar 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new OAuth header sanitization tests are placed in test_utils_environment.py, which makes them harder to discover/maintain since they are unrelated to environment detection. Consider moving these tests into a dedicated auth/oauth test module (e.g., tests/auth/test_oauth_headers.py or similar) and keeping this file focused on Environment.detect().

Copilot uses AI. Check for mistakes.
monkeypatch.setattr(platform, "system", lambda: "Linux")
monkeypatch.setattr(platform, "machine", lambda: "x86_64")
monkeypatch.setattr(platform, "release", lambda: "6.8.0-101-generic")
monkeypatch.setattr(
platform,
"version",
lambda: "#101~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 11 13:19:54 UTC ",
)
monkeypatch.setattr("kimi_cli.auth.oauth.get_device_id", lambda: "device-id")

headers = _common_headers()

assert (
headers["X-Msh-Os-Version"]
== "#101~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 11 13:19:54 UTC"
)
Loading