Skip to content

v4.0.1

Latest

Choose a tag to compare

@solidlime solidlime released this 20 Sep 04:39
· 87 commits to main since this release

nous v4.0.1 リリースノート

バージョニングは Semantic Versioning に従う。リポジトリ直下の
CHANGELOG.md は .gitignore で「自動生成物」扱いになっているため、リリースノートは
docs/releases/<version>.md として追跡する(v4.0.0 と同じ方式)。

概要(2026-09-20)

パッチリリース。v4.0.0 のリリース検証中に見つかった、ペルソナ解決失敗時に C1 の
エラー envelope をすり抜ける
不具合を修正した。API の互換性は保たれる(挙動の追加のみ)。

修正: ペルソナ未検出・不正名が envelope をすり抜けていた

  • 症状(v4.0.0): 未知の X-Persona(存在しないペルソナ名)を指定して MCP ツールを
    呼ぶと、クライアントは Error executing tool <name> という機械可読なコードの無い
    ツールエラーを受け取っていた。error.code(NOT_FOUND)も元メッセージも届かない。

  • 原因: AppContextRegistry.get() が素の ValueError を送出し、SDK がそれを
    UnexpectedToolError に包むため、C1(共通 envelope)の翻訳経路に乗っていなかった。
    ペルソナ解決は全ツールの手前で起きるので、どのツール実装でも拾えなかった。

  • 修正:

    • AppContextRegistry.get() が型付きドメインエラー
      PersonaNotFoundError / PersonaValidationError
      (nous/domain/shared/errors.py)を送出する。
      どちらも後方互換のため ValueError を継承する(既存の呼び出し側・テストは無変更で動く)。
    • nous/main.py の Tool.run() パッチが例外連鎖を辿り、
      これらのエラーを共通 envelope に翻訳する。convert_result の経路も維持する。
  • 修正後の応答:

    入力 応答
    X-Persona: <存在しない名前> {"ok": false, "data": null, "error": {"code": "NOT_FOUND", "message": "Persona '<名前>' not found"}}
    X-Persona: ../etc(パス分離子) {"ok": false, "data": null, "error": {"code": "VALIDATION_ERROR", ...}}
  • 翻訳の対象を限定: 写像は型付きペルソナエラーのみを対象とし、メッセージ文字列では
    判定しない(無関係な ValueError は従来どおりクラッシュとして扱う)。この境界は
    tests/unit/test_mcp_persona_error_envelope.py::test_unrelated_crash_is_not_enveloped
    で固定している。

テスト

tests/unit/test_mcp_persona_error_envelope.py(新規 3 件):

  • 未知ペルソナ → NOT_FOUND envelope
  • パス分離子入りペルソナ → VALIDATION_ERROR envelope
  • 無関係なクラッシュ(似た文字列の ValueError)→ envelope 化されない

3 件とも、修正前に実行すると失敗することを確認済み(UnexpectedToolError: Error executing tool session_begin が出る)。

アップグレード

  • コードの互換性変更なし。マイグレーション不要(v4.0.0 の移行手順は
    v4.0.0 を参照)。
  • envelope のエラーコードを見ているクライアントは、ペルソナ未検出時に
    is_error テキストから error.code == "NOT_FOUND" へ分岐できるようになる。