klaude-code 2.3.0__tar.gz → 2.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. {klaude_code-2.3.0 → klaude_code-2.4.1}/PKG-INFO +21 -74
  2. {klaude_code-2.3.0 → klaude_code-2.4.1}/README.md +20 -73
  3. {klaude_code-2.3.0 → klaude_code-2.4.1}/pyproject.toml +1 -1
  4. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/list_model.py +3 -3
  5. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/main.py +2 -2
  6. klaude_code-2.4.1/src/klaude_code/config/assets/builtin_config.yaml +236 -0
  7. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/config/config.py +17 -17
  8. klaude_code-2.3.0/src/klaude_code/config/select_model.py → klaude_code-2.4.1/src/klaude_code/config/model_matcher.py +7 -7
  9. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/config/sub_agent_model_helper.py +1 -10
  10. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/config/thinking.py +2 -2
  11. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/agent_profile.py +9 -23
  12. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/executor.py +72 -70
  13. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/diff_builder.py +25 -18
  14. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/anthropic/client.py +5 -5
  15. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/client.py +1 -1
  16. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/codex/client.py +2 -2
  17. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/google/client.py +6 -6
  18. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/input_common.py +2 -2
  19. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openai_compatible/client.py +3 -3
  20. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openai_compatible/stream.py +1 -1
  21. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openrouter/client.py +4 -4
  22. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openrouter/input.py +1 -3
  23. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/responses/client.py +5 -5
  24. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/__init__.py +7 -1
  25. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/chat.py +10 -0
  26. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/llm_param.py +1 -1
  27. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/model.py +0 -26
  28. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/op.py +0 -5
  29. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/session.py +4 -2
  30. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/clear_cmd.py +0 -1
  31. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/command_abc.py +6 -4
  32. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/copy_cmd.py +10 -10
  33. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/debug_cmd.py +11 -10
  34. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/export_online_cmd.py +18 -23
  35. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/fork_session_cmd.py +39 -43
  36. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/model_cmd.py +5 -7
  37. klaude_code-2.3.0/src/klaude_code/tui/command/model_select.py → klaude_code-2.4.1/src/klaude_code/tui/command/model_picker.py +3 -5
  38. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/refresh_cmd.py +0 -1
  39. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/registry.py +15 -21
  40. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/resume_cmd.py +10 -16
  41. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/status_cmd.py +8 -12
  42. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/sub_agent_model_cmd.py +11 -16
  43. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/terminal_setup_cmd.py +8 -11
  44. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/thinking_cmd.py +4 -6
  45. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/commands.py +5 -0
  46. klaude_code-2.4.1/src/klaude_code/tui/components/command_output.py +96 -0
  47. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/developer.py +3 -110
  48. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/welcome.py +2 -2
  49. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/input/prompt_toolkit.py +6 -8
  50. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/machine.py +5 -0
  51. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/renderer.py +5 -5
  52. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/runner.py +0 -6
  53. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/terminal/selector.py +7 -8
  54. klaude_code-2.3.0/src/klaude_code/config/assets/builtin_config.yaml +0 -378
  55. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/__init__.py +0 -0
  56. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/app/__init__.py +0 -0
  57. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/app/runtime.py +0 -0
  58. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/__init__.py +0 -0
  59. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/base.py +0 -0
  60. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/claude/__init__.py +0 -0
  61. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/claude/exceptions.py +0 -0
  62. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/claude/oauth.py +0 -0
  63. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/claude/token_manager.py +0 -0
  64. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/codex/__init__.py +0 -0
  65. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/codex/exceptions.py +0 -0
  66. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
  67. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/codex/oauth.py +0 -0
  68. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/auth/codex/token_manager.py +0 -0
  69. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/__init__.py +0 -0
  70. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/auth_cmd.py +0 -0
  71. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/config_cmd.py +0 -0
  72. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/cost_cmd.py +0 -0
  73. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/debug.py +0 -0
  74. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/self_update.py +0 -0
  75. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/cli/session_cmd.py +0 -0
  76. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/config/__init__.py +0 -0
  77. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/config/assets/__init__.py +0 -0
  78. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/config/builtin_config.py +0 -0
  79. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/const.py +0 -0
  80. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/__init__.py +0 -0
  81. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/agent.py +0 -0
  82. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/manager/__init__.py +0 -0
  83. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/manager/llm_clients.py +0 -0
  84. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
  85. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
  86. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
  87. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
  88. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +0 -0
  89. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-codex.md +0 -0
  90. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
  91. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
  92. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-nano-banana.md +0 -0
  93. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
  94. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-sub-agent-image-gen.md +0 -0
  95. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +0 -0
  96. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
  97. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/reminders.py +0 -0
  98. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/task.py +0 -0
  99. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/__init__.py +0 -0
  100. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/context.py +0 -0
  101. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/__init__.py +0 -0
  102. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/_utils.py +0 -0
  103. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
  104. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
  105. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
  106. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
  107. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
  108. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/read_tool.md +0 -0
  109. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/read_tool.py +0 -0
  110. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/write_tool.md +0 -0
  111. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/file/write_tool.py +0 -0
  112. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/report_back_tool.py +0 -0
  113. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/shell/__init__.py +0 -0
  114. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
  115. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
  116. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
  117. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
  118. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/todo/__init__.py +0 -0
  119. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
  120. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
  121. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
  122. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
  123. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
  124. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/tool_abc.py +0 -0
  125. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/tool_registry.py +0 -0
  126. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/tool_runner.py +0 -0
  127. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/truncation.py +0 -0
  128. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/web/__init__.py +0 -0
  129. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
  130. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
  131. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
  132. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
  133. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
  134. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
  135. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/core/turn.py +0 -0
  136. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/__init__.py +0 -0
  137. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/anthropic/__init__.py +0 -0
  138. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/anthropic/input.py +0 -0
  139. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/bedrock/__init__.py +0 -0
  140. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/bedrock/client.py +0 -0
  141. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/claude/__init__.py +0 -0
  142. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/claude/client.py +0 -0
  143. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/codex/__init__.py +0 -0
  144. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/google/__init__.py +0 -0
  145. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/google/input.py +0 -0
  146. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/image.py +0 -0
  147. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
  148. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openai_compatible/input.py +0 -0
  149. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
  150. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openrouter/__init__.py +0 -0
  151. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/openrouter/reasoning.py +0 -0
  152. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/registry.py +0 -0
  153. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/responses/__init__.py +0 -0
  154. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/responses/input.py +0 -0
  155. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/llm/usage.py +0 -0
  156. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/log.py +0 -0
  157. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/__init__.py +0 -0
  158. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/commands.py +0 -0
  159. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/base.py +0 -0
  160. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/lifecycle.py +0 -0
  161. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/metadata.py +0 -0
  162. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/streaming.py +0 -0
  163. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/system.py +0 -0
  164. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/events/tools.py +0 -0
  165. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/message.py +0 -0
  166. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/op_handler.py +0 -0
  167. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/sub_agent/AGENTS.md +0 -0
  168. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
  169. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
  170. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/sub_agent/image_gen.py +0 -0
  171. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/sub_agent/task.py +0 -0
  172. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/sub_agent/web.py +0 -0
  173. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/protocol/tools.py +0 -0
  174. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/__init__.py +0 -0
  175. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/codec.py +0 -0
  176. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/export.py +0 -0
  177. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/selector.py +0 -0
  178. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/store.py +0 -0
  179. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/templates/export_session.html +0 -0
  180. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/session/templates/mermaid_viewer.html +0 -0
  181. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/__init__.py +0 -0
  182. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/assets/create-plan/SKILL.md +0 -0
  183. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/assets/deslop/SKILL.md +0 -0
  184. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/assets/handoff/SKILL.md +0 -0
  185. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/assets/jj-workspace/SKILL.md +0 -0
  186. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
  187. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/loader.py +0 -0
  188. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/manager.py +0 -0
  189. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/skill/system_skills.py +0 -0
  190. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/__init__.py +0 -0
  191. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/__init__.py +0 -0
  192. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/export_cmd.py +0 -0
  193. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/prompt-init.md +0 -0
  194. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/command/prompt_command.py +0 -0
  195. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/__init__.py +0 -0
  196. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/assistant.py +0 -0
  197. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/bash_syntax.py +0 -0
  198. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/common.py +0 -0
  199. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/diffs.py +0 -0
  200. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/errors.py +0 -0
  201. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/mermaid_viewer.py +0 -0
  202. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/metadata.py +0 -0
  203. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/__init__.py +0 -0
  204. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/cjk_wrap.py +0 -0
  205. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/code_panel.py +0 -0
  206. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/live.py +0 -0
  207. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/markdown.py +0 -0
  208. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/quote.py +0 -0
  209. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/searchable_text.py +0 -0
  210. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/status.py +0 -0
  211. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/rich/theme.py +0 -0
  212. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/sub_agent.py +0 -0
  213. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/thinking.py +0 -0
  214. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/tools.py +0 -0
  215. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/components/user_input.py +0 -0
  216. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/display.py +0 -0
  217. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/input/__init__.py +0 -0
  218. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/input/clipboard.py +0 -0
  219. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/input/completers.py +0 -0
  220. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/input/key_bindings.py +0 -0
  221. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/terminal/__init__.py +0 -0
  222. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/terminal/color.py +0 -0
  223. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/terminal/control.py +0 -0
  224. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/terminal/image.py +0 -0
  225. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/terminal/notifier.py +0 -0
  226. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/tui/terminal/progress_bar.py +0 -0
  227. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/__init__.py +0 -0
  228. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/common.py +0 -0
  229. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/core/__init__.py +0 -0
  230. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/core/display.py +0 -0
  231. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/core/input.py +0 -0
  232. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/debug_mode.py +0 -0
  233. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/terminal/__init__.py +0 -0
  234. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/ui/terminal/title.py +0 -0
  235. {klaude_code-2.3.0 → klaude_code-2.4.1}/src/klaude_code/update.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: klaude-code
3
- Version: 2.3.0
3
+ Version: 2.4.1
4
4
  Summary: Minimal code agent CLI
5
5
  Requires-Dist: anthropic>=0.66.0
6
6
  Requires-Dist: chardet>=5.2.0
@@ -155,95 +155,42 @@ Open in editor:
155
155
  klaude config
156
156
  ```
157
157
 
158
- ##### Adding Models to Built-in Providers
158
+ ##### Model Configuration
159
159
 
160
- You can add custom models to existing built-in providers without redefining the entire provider. Just reference the `provider_name` and add your `model_list`:
160
+ You can add custom models to built-in providers or define new ones. Configuration is inherited from built-in providers by matching `provider_name`.
161
161
 
162
162
  ```yaml
163
163
  # ~/.klaude/klaude-config.yaml
164
164
  provider_list:
165
- - provider_name: openrouter # Reference existing built-in provider
166
- model_list:
167
- - model_name: seed
168
- model_params:
169
- model: bytedance-seed/seed-1.6 # Model ID from OpenRouter
170
- context_limit: 262000
171
- cost:
172
- input: 0.25
173
- output: 2
174
- ```
175
-
176
- **How merging works:**
177
- - Your models are merged with the built-in models for that provider
178
- - You only need `provider_name` and `model_list` - protocol, api_key, etc. are inherited from the built-in config
179
- - To override a built-in model, use the same `model_name` (e.g., `sonnet` to customize the built-in sonnet)
180
-
181
- **More examples:**
182
-
183
- ```yaml
184
- provider_list:
185
- # Add multiple models to OpenRouter
165
+ # Add/Override models for built-in OpenRouter provider
186
166
  - provider_name: openrouter
187
167
  model_list:
188
168
  - model_name: qwen-coder
189
- model_params:
190
- model: qwen/qwen-2.5-coder-32b-instruct
191
- context_limit: 131072
192
- cost:
193
- input: 0.3
194
- output: 0.9
195
- - model_name: llama-405b
196
- model_params:
197
- model: meta-llama/llama-3.1-405b-instruct
198
- context_limit: 131072
199
- cost:
200
- input: 0.8
201
- output: 0.8
202
-
203
- # Add models to Anthropic provider
204
- - provider_name: anthropic
205
- model_list:
206
- - model_name: haiku@ant
207
- model_params:
208
- model: claude-3-5-haiku-20241022
209
- context_limit: 200000
210
- cost:
211
- input: 1.0
212
- output: 5.0
213
- ```
214
-
215
- After adding models, run `klaude list` to verify they appear in the model list.
216
-
217
- ##### Overriding Provider Settings
218
-
219
- Override provider-level settings (like api_key) while keeping built-in models:
220
-
221
- ```yaml
222
- provider_list:
223
- - provider_name: anthropic
224
- api_key: sk-my-custom-key # Override the default ${ANTHROPIC_API_KEY}
225
- # Built-in models (sonnet, opus) are still available
226
- ```
227
-
228
- ##### Adding New Providers
229
-
230
- For providers not in the built-in list, you must specify `protocol`:
231
-
232
- ```yaml
233
- provider_list:
234
- - provider_name: my-azure-openai
169
+ model_id: qwen/qwen-2.5-coder-32b-instruct
170
+ context_limit: 131072
171
+ cost: { input: 0.3, output: 0.9 }
172
+ - model_name: sonnet # Override built-in sonnet params
173
+ model_id: anthropic/claude-3.5-sonnet
174
+ context_limit: 200000
175
+
176
+ # Add a completely new provider
177
+ - provider_name: my-azure
235
178
  protocol: openai
236
179
  api_key: ${AZURE_OPENAI_KEY}
237
180
  base_url: https://my-instance.openai.azure.com/
238
181
  is_azure: true
239
182
  azure_api_version: "2024-02-15-preview"
240
183
  model_list:
241
- - model_name: gpt-4-azure
242
- model_params:
243
- model: gpt-4
244
- context_limit: 128000
184
+ - model_name: gpt-4
185
+ model_id: gpt-4-deploy-name
186
+ context_limit: 128000
245
187
  ```
246
188
 
189
+ **Key Tips:**
190
+ - **Merging**: If `provider_name` matches a built-in provider, settings like `protocol` and `api_key` are inherited.
191
+ - **Overriding**: Use the same `model_name` as a built-in model to override its parameters.
192
+ - **Environment Variables**: Use `${VAR_NAME}` syntax for secrets.
193
+
247
194
  ##### Supported Protocols
248
195
 
249
196
  - `anthropic` - Anthropic Messages API
@@ -133,95 +133,42 @@ Open in editor:
133
133
  klaude config
134
134
  ```
135
135
 
136
- ##### Adding Models to Built-in Providers
136
+ ##### Model Configuration
137
137
 
138
- You can add custom models to existing built-in providers without redefining the entire provider. Just reference the `provider_name` and add your `model_list`:
138
+ You can add custom models to built-in providers or define new ones. Configuration is inherited from built-in providers by matching `provider_name`.
139
139
 
140
140
  ```yaml
141
141
  # ~/.klaude/klaude-config.yaml
142
142
  provider_list:
143
- - provider_name: openrouter # Reference existing built-in provider
144
- model_list:
145
- - model_name: seed
146
- model_params:
147
- model: bytedance-seed/seed-1.6 # Model ID from OpenRouter
148
- context_limit: 262000
149
- cost:
150
- input: 0.25
151
- output: 2
152
- ```
153
-
154
- **How merging works:**
155
- - Your models are merged with the built-in models for that provider
156
- - You only need `provider_name` and `model_list` - protocol, api_key, etc. are inherited from the built-in config
157
- - To override a built-in model, use the same `model_name` (e.g., `sonnet` to customize the built-in sonnet)
158
-
159
- **More examples:**
160
-
161
- ```yaml
162
- provider_list:
163
- # Add multiple models to OpenRouter
143
+ # Add/Override models for built-in OpenRouter provider
164
144
  - provider_name: openrouter
165
145
  model_list:
166
146
  - model_name: qwen-coder
167
- model_params:
168
- model: qwen/qwen-2.5-coder-32b-instruct
169
- context_limit: 131072
170
- cost:
171
- input: 0.3
172
- output: 0.9
173
- - model_name: llama-405b
174
- model_params:
175
- model: meta-llama/llama-3.1-405b-instruct
176
- context_limit: 131072
177
- cost:
178
- input: 0.8
179
- output: 0.8
180
-
181
- # Add models to Anthropic provider
182
- - provider_name: anthropic
183
- model_list:
184
- - model_name: haiku@ant
185
- model_params:
186
- model: claude-3-5-haiku-20241022
187
- context_limit: 200000
188
- cost:
189
- input: 1.0
190
- output: 5.0
191
- ```
192
-
193
- After adding models, run `klaude list` to verify they appear in the model list.
194
-
195
- ##### Overriding Provider Settings
196
-
197
- Override provider-level settings (like api_key) while keeping built-in models:
198
-
199
- ```yaml
200
- provider_list:
201
- - provider_name: anthropic
202
- api_key: sk-my-custom-key # Override the default ${ANTHROPIC_API_KEY}
203
- # Built-in models (sonnet, opus) are still available
204
- ```
205
-
206
- ##### Adding New Providers
207
-
208
- For providers not in the built-in list, you must specify `protocol`:
209
-
210
- ```yaml
211
- provider_list:
212
- - provider_name: my-azure-openai
147
+ model_id: qwen/qwen-2.5-coder-32b-instruct
148
+ context_limit: 131072
149
+ cost: { input: 0.3, output: 0.9 }
150
+ - model_name: sonnet # Override built-in sonnet params
151
+ model_id: anthropic/claude-3.5-sonnet
152
+ context_limit: 200000
153
+
154
+ # Add a completely new provider
155
+ - provider_name: my-azure
213
156
  protocol: openai
214
157
  api_key: ${AZURE_OPENAI_KEY}
215
158
  base_url: https://my-instance.openai.azure.com/
216
159
  is_azure: true
217
160
  azure_api_version: "2024-02-15-preview"
218
161
  model_list:
219
- - model_name: gpt-4-azure
220
- model_params:
221
- model: gpt-4
222
- context_limit: 128000
162
+ - model_name: gpt-4
163
+ model_id: gpt-4-deploy-name
164
+ context_limit: 128000
223
165
  ```
224
166
 
167
+ **Key Tips:**
168
+ - **Merging**: If `provider_name` matches a built-in provider, settings like `protocol` and `api_key` are inherited.
169
+ - **Overriding**: Use the same `model_name` as a built-in model to override its parameters.
170
+ - **Environment Variables**: Use `${VAR_NAME}` syntax for secrets.
171
+
225
172
  ##### Supported Protocols
226
173
 
227
174
  - `anthropic` - Anthropic Messages API
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "klaude-code"
7
- version = "2.3.0"
7
+ version = "2.4.1"
8
8
  description = "Minimal code agent CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -181,7 +181,7 @@ def format_env_var_display(value: str | None) -> Text:
181
181
 
182
182
  def _get_model_params_display(model: ModelConfig) -> list[Text]:
183
183
  """Get display elements for model parameters."""
184
- param_strings = format_model_params(model.model_params)
184
+ param_strings = format_model_params(model)
185
185
  if param_strings:
186
186
  return [Text(s) for s in param_strings]
187
187
  return [Text("")]
@@ -286,7 +286,7 @@ def _build_models_table(
286
286
 
287
287
  if not provider_available:
288
288
  name = Text.assemble((prefix, ThemeKey.LINES), (model.model_name, "dim"))
289
- model_id = Text(model.model_params.model or "", style="dim")
289
+ model_id = Text(model.model_id or "", style="dim")
290
290
  params = Text("(unavailable)", style="dim")
291
291
  else:
292
292
  # Build role tags for this model
@@ -305,7 +305,7 @@ def _build_models_table(
305
305
  )
306
306
  else:
307
307
  name = Text.assemble((prefix, ThemeKey.LINES), (model.model_name, ThemeKey.CONFIG_ITEM_NAME))
308
- model_id = Text(model.model_params.model or "")
308
+ model_id = Text(model.model_id or "")
309
309
  params = Text(" · ").join(_get_model_params_display(model))
310
310
 
311
311
  models_table.add_row(name, model_id, params)
@@ -124,7 +124,7 @@ def main_callback(
124
124
  raise typer.Exit(2)
125
125
 
126
126
  from klaude_code.app.runtime import AppInitConfig
127
- from klaude_code.tui.command.model_select import ModelSelectStatus, select_model_interactive
127
+ from klaude_code.tui.command.model_picker import ModelSelectStatus, select_model_interactive
128
128
  from klaude_code.tui.runner import run_interactive
129
129
 
130
130
  update_terminal_title()
@@ -193,7 +193,7 @@ def main_callback(
193
193
  matches = [
194
194
  m.selector
195
195
  for m in cfg.iter_model_entries()
196
- if (m.model_params.model or "").strip().lower() == raw_model.lower()
196
+ if (m.model_id or "").strip().lower() == raw_model.lower()
197
197
  ]
198
198
  if len(matches) == 1:
199
199
  chosen_model = matches[0]
@@ -0,0 +1,236 @@
1
+ ---
2
+ # Built-in provider and model configurations
3
+ # Users can start using klaude by simply setting environment variables
4
+ # (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) without manual configuration.
5
+ provider_list:
6
+ - provider_name: anthropic
7
+ protocol: anthropic
8
+ api_key: ${ANTHROPIC_API_KEY}
9
+ model_list:
10
+ - model_name: sonnet
11
+ model_id: claude-sonnet-4-5-20250929
12
+ context_limit: 200000
13
+ provider_routing:
14
+ sort: throughput
15
+ cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
16
+ - model_name: opus
17
+ model_id: claude-opus-4-5-20251101
18
+ context_limit: 200000
19
+ verbosity: high
20
+ thinking:
21
+ type: enabled
22
+ budget_tokens: 2048
23
+ cost: {input: 5, output: 25, cache_read: 0.5, cache_write: 6.25}
24
+ - provider_name: openai
25
+ protocol: responses
26
+ api_key: ${OPENAI_API_KEY}
27
+ model_list:
28
+ - model_name: gpt-5.2
29
+ model_id: gpt-5.2
30
+ max_tokens: 128000
31
+ context_limit: 400000
32
+ verbosity: high
33
+ thinking:
34
+ reasoning_effort: high
35
+ cost: {input: 1.75, output: 14, cache_read: 0.17}
36
+ - provider_name: openrouter
37
+ protocol: openrouter
38
+ api_key: ${OPENROUTER_API_KEY}
39
+ model_list:
40
+ - model_name: gpt-5.1-codex-max
41
+ model_id: openai/gpt-5.1-codex-max
42
+ max_tokens: 128000
43
+ context_limit: 400000
44
+ thinking:
45
+ reasoning_effort: medium
46
+ cost: {input: 1.25, output: 10, cache_read: 0.13}
47
+ - model_name: gpt-5.2
48
+ model_id: openai/gpt-5.2
49
+ max_tokens: 128000
50
+ context_limit: 400000
51
+ verbosity: high
52
+ thinking:
53
+ reasoning_effort: high
54
+ cost: {input: 1.75, output: 14, cache_read: 0.17}
55
+ - model_name: gpt-5.2-medium
56
+ model_id: openai/gpt-5.2
57
+ max_tokens: 128000
58
+ context_limit: 400000
59
+ verbosity: high
60
+ thinking:
61
+ reasoning_effort: medium
62
+ cost: {input: 1.75, output: 14, cache_read: 0.17}
63
+ - model_name: gpt-5.2-low
64
+ model_id: openai/gpt-5.2
65
+ max_tokens: 128000
66
+ context_limit: 400000
67
+ verbosity: low
68
+ thinking:
69
+ reasoning_effort: low
70
+ cost: {input: 1.75, output: 14, cache_read: 0.17}
71
+ - model_name: gpt-5.2-fast
72
+ model_id: openai/gpt-5.2
73
+ max_tokens: 128000
74
+ context_limit: 400000
75
+ verbosity: low
76
+ thinking:
77
+ reasoning_effort: none
78
+ cost: {input: 1.75, output: 14, cache_read: 0.17}
79
+ - model_name: kimi
80
+ model_id: moonshotai/kimi-k2-thinking
81
+ context_limit: 262144
82
+ provider_routing:
83
+ only:
84
+ - moonshotai/turbo
85
+ cost: {input: 0.6, output: 2.5, cache_read: 0.15}
86
+ - model_name: haiku
87
+ model_id: anthropic/claude-haiku-4.5
88
+ context_limit: 200000
89
+ cost: {input: 1, output: 5, cache_read: 0.1, cache_write: 1.25}
90
+ - model_name: sonnet
91
+ model_id: anthropic/claude-4.5-sonnet
92
+ context_limit: 200000
93
+ provider_routing:
94
+ sort: throughput
95
+ cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
96
+ - model_name: opus
97
+ model_id: anthropic/claude-4.5-opus
98
+ context_limit: 200000
99
+ verbosity: high
100
+ thinking:
101
+ type: enabled
102
+ budget_tokens: 2048
103
+ cost: {input: 5, output: 25, cache_read: 0.5, cache_write: 6.25}
104
+ - model_name: gemini-pro
105
+ model_id: google/gemini-3-pro-preview
106
+ context_limit: 1048576
107
+ thinking:
108
+ reasoning_effort: high
109
+ cost: {input: 2, output: 12, cache_read: 0.2}
110
+ - model_name: gemini-flash
111
+ model_id: google/gemini-3-flash-preview
112
+ context_limit: 1048576
113
+ thinking:
114
+ reasoning_effort: medium
115
+ cost: {input: 0.5, output: 3, cache_read: 0.05}
116
+ - model_name: nano-banana-pro
117
+ model_id: google/gemini-3-pro-image-preview
118
+ context_limit: 66000
119
+ modalities:
120
+ - image
121
+ - text
122
+ cost: {input: 2, output: 12, cache_read: 0.2, image: 120}
123
+ - model_name: nano-banana
124
+ model_id: google/gemini-2.5-flash-image
125
+ context_limit: 33000
126
+ modalities:
127
+ - image
128
+ - text
129
+ cost: {input: 0.3, output: 2.5, cache_read: 0.03, image: 30}
130
+ - model_name: grok
131
+ model_id: x-ai/grok-4.1-fast
132
+ context_limit: 2000000
133
+ thinking:
134
+ type: enabled
135
+ budget_tokens: 2048
136
+ cost: {input: 0.2, output: 0.5, cache_read: 0.05}
137
+ - model_name: minimax
138
+ model_id: minimax/minimax-m2.1
139
+ context_limit: 204800
140
+ cost: {input: 0.3, output: 1.2, cache_read: 0.03}
141
+ - model_name: glm
142
+ model_id: z-ai/glm-4.7
143
+ context_limit: 200000
144
+ provider_routing:
145
+ only:
146
+ - z-ai
147
+ cost: {input: 0.44, output: 1.74, cache_read: 0.04}
148
+ - model_name: seedream
149
+ model_id: bytedance-seed/seedream-4.5
150
+ context_limit: 4000
151
+ cost: {input: 0, output: 9.581, image: 9.581}
152
+ modalities:
153
+ - image
154
+ - text
155
+ - provider_name: google
156
+ protocol: google
157
+ api_key: ${GOOGLE_API_KEY}
158
+ model_list:
159
+ - model_name: gemini-pro
160
+ model_id: gemini-3-pro-preview
161
+ context_limit: 1048576
162
+ cost: {input: 2, output: 12, cache_read: 0.2}
163
+ - model_name: gemini-flash
164
+ model_id: gemini-3-flash-preview
165
+ context_limit: 1048576
166
+ cost: {input: 0.5, output: 3, cache_read: 0.05}
167
+ - model_name: nano-banana-pro
168
+ model_id: gemini-3-pro-image-preview
169
+ context_limit: 66000
170
+ modalities:
171
+ - image
172
+ - text
173
+ cost: {input: 2, output: 12, cache_read: 0.2, image: 120}
174
+ - provider_name: bedrock
175
+ protocol: bedrock
176
+ aws_access_key: ${AWS_ACCESS_KEY_ID}
177
+ aws_secret_key: ${AWS_SECRET_ACCESS_KEY}
178
+ aws_region: ${AWS_REGION}
179
+ model_list:
180
+ - model_name: sonnet
181
+ model_id: us.anthropic.claude-sonnet-4-5-20250929-v1:0
182
+ context_limit: 200000
183
+ cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
184
+ - provider_name: deepseek
185
+ protocol: anthropic
186
+ api_key: ${DEEPSEEK_API_KEY}
187
+ base_url: https://api.deepseek.com/anthropic
188
+ model_list:
189
+ - model_name: deepseek
190
+ model_id: deepseek-reasoner
191
+ context_limit: 128000
192
+ thinking:
193
+ type: enabled
194
+ budget_tokens: 2048
195
+ cost: {input: 2, output: 3, cache_read: 0.2, currency: CNY}
196
+ - provider_name: moonshot
197
+ protocol: anthropic
198
+ api_key: ${MOONSHOT_API_KEY}
199
+ base_url: https://api.moonshot.cn/anthropic
200
+ model_list:
201
+ - model_name: kimi
202
+ model_id: kimi-k2-thinking
203
+ context_limit: 262144
204
+ thinking:
205
+ type: enabled
206
+ budget_tokens: 8192
207
+ cost: {input: 4, output: 16, cache_read: 1, currency: CNY}
208
+ - provider_name: claude-max
209
+ protocol: claude_oauth
210
+ model_list:
211
+ - model_name: sonnet
212
+ model_id: claude-sonnet-4-5-20250929
213
+ context_limit: 200000
214
+ cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
215
+ - model_name: opus
216
+ model_id: claude-opus-4-5-20251101
217
+ context_limit: 200000
218
+ verbosity: high
219
+ thinking:
220
+ type: enabled
221
+ budget_tokens: 2048
222
+ cost: {input: 5, output: 25, cache_read: 0.5, cache_write: 6.25}
223
+ - model_name: haiku
224
+ model_id: claude-haiku-4-5-20251001
225
+ context_limit: 200000
226
+ cost: {input: 1, output: 5, cache_read: 0.1, cache_write: 1.25}
227
+ - provider_name: codex
228
+ protocol: codex_oauth
229
+ model_list:
230
+ - model_name: gpt-5.2-codex
231
+ model_id: gpt-5.2-codex
232
+ thinking:
233
+ reasoning_effort: medium
234
+ context_limit: 400000
235
+ max_tokens: 128000
236
+ cost: {input: 1.75, output: 14, cache_read: 0.17}
@@ -58,9 +58,10 @@ config_path = Path.home() / ".klaude" / "klaude-config.yaml"
58
58
  example_config_path = Path.home() / ".klaude" / "klaude-config.example.yaml"
59
59
 
60
60
 
61
- class ModelConfig(BaseModel):
61
+ class ModelConfig(llm_param.LLMConfigModelParameter):
62
+ """Model configuration that flattens LLMConfigModelParameter fields."""
63
+
62
64
  model_name: str
63
- model_params: llm_param.LLMConfigModelParameter
64
65
 
65
66
 
66
67
  class ProviderConfig(llm_param.LLMConfigProviderParameter):
@@ -135,10 +136,11 @@ class UserProviderConfig(BaseModel):
135
136
  model_list: list[ModelConfig] = Field(default_factory=lambda: [])
136
137
 
137
138
 
138
- class ModelEntry(BaseModel):
139
+ class ModelEntry(llm_param.LLMConfigModelParameter):
140
+ """Model entry with provider info, flattens LLMConfigModelParameter fields."""
141
+
139
142
  model_name: str
140
143
  provider: str
141
- model_params: llm_param.LLMConfigModelParameter
142
144
 
143
145
  @property
144
146
  def selector(self) -> str:
@@ -325,7 +327,7 @@ class Config(BaseModel):
325
327
  provider_dump["api_key"] = api_key
326
328
  return llm_param.LLMConfigParameter(
327
329
  **provider_dump,
328
- **model.model_params.model_dump(),
330
+ **model.model_dump(exclude={"model_name"}),
329
331
  )
330
332
 
331
333
  raise ValueError(f"Unknown model: {model_name}")
@@ -340,7 +342,7 @@ class Config(BaseModel):
340
342
  ModelEntry(
341
343
  model_name=model.model_name,
342
344
  provider=provider.provider_name,
343
- model_params=model.model_params,
345
+ **model.model_dump(exclude={"model_name"}),
344
346
  )
345
347
  for provider in self.provider_list
346
348
  if not only_available or not provider.is_api_key_missing()
@@ -350,7 +352,7 @@ class Config(BaseModel):
350
352
  def has_available_image_model(self) -> bool:
351
353
  """Check if any image generation model is available."""
352
354
  for entry in self.iter_model_entries(only_available=True):
353
- if entry.model_params.modalities and "image" in entry.model_params.modalities:
355
+ if entry.modalities and "image" in entry.modalities:
354
356
  return True
355
357
  return False
356
358
 
@@ -364,7 +366,7 @@ class Config(BaseModel):
364
366
  def get_first_available_image_model(self) -> str | None:
365
367
  """Get the first available image generation model, or None."""
366
368
  for entry in self.iter_model_entries(only_available=True):
367
- if entry.model_params.modalities and "image" in entry.model_params.modalities:
369
+ if entry.modalities and "image" in entry.modalities:
368
370
  return entry.model_name
369
371
  return None
370
372
 
@@ -409,15 +411,13 @@ def get_example_config() -> UserConfig:
409
411
  model_list=[
410
412
  ModelConfig(
411
413
  model_name="my-model",
412
- model_params=llm_param.LLMConfigModelParameter(
413
- model="model-id-from-provider",
414
- max_tokens=16000,
415
- context_limit=200000,
416
- cost=llm_param.Cost(
417
- input=1,
418
- output=10,
419
- cache_read=0.1,
420
- ),
414
+ model_id="model-id-from-provider",
415
+ max_tokens=16000,
416
+ context_limit=200000,
417
+ cost=llm_param.Cost(
418
+ input=1,
419
+ output=10,
420
+ cache_read=0.1,
421
421
  ),
422
422
  ),
423
423
  ],
@@ -51,7 +51,7 @@ def match_model_from_config(preferred: str | None = None) -> ModelMatchResult:
51
51
  # Only show models from providers with valid API keys
52
52
  models: list[ModelEntry] = sorted(
53
53
  config.iter_model_entries(only_available=True),
54
- key=lambda m: (m.model_name.lower(), m.provider.lower()),
54
+ key=lambda m: (m.provider.lower(), m.model_name.lower()),
55
55
  )
56
56
 
57
57
  if not models:
@@ -86,13 +86,13 @@ def match_model_from_config(preferred: str | None = None) -> ModelMatchResult:
86
86
  return ModelMatchResult(matched_model=None, filtered_models=exact_base_matches, filter_hint=filter_hint)
87
87
 
88
88
  preferred_lower = preferred.lower()
89
- # Case-insensitive exact match (selector/model_name/model_params.model)
89
+ # Case-insensitive exact match (selector/model_name/model_id)
90
90
  exact_ci_matches = [
91
91
  m
92
92
  for m in models
93
93
  if preferred_lower == m.selector.lower()
94
94
  or preferred_lower == m.model_name.lower()
95
- or preferred_lower == (m.model_params.model or "").lower()
95
+ or preferred_lower == (m.model_id or "").lower()
96
96
  ]
97
97
  if len(exact_ci_matches) == 1:
98
98
  return ModelMatchResult(
@@ -110,7 +110,7 @@ def match_model_from_config(preferred: str | None = None) -> ModelMatchResult:
110
110
  for m in models
111
111
  if preferred_norm == _normalize_model_key(m.selector)
112
112
  or preferred_norm == _normalize_model_key(m.model_name)
113
- or preferred_norm == _normalize_model_key(m.model_params.model or "")
113
+ or preferred_norm == _normalize_model_key(m.model_id or "")
114
114
  ]
115
115
  if len(normalized_matches) == 1:
116
116
  return ModelMatchResult(
@@ -125,7 +125,7 @@ def match_model_from_config(preferred: str | None = None) -> ModelMatchResult:
125
125
  for m in models
126
126
  if preferred_norm in _normalize_model_key(m.selector)
127
127
  or preferred_norm in _normalize_model_key(m.model_name)
128
- or preferred_norm in _normalize_model_key(m.model_params.model or "")
128
+ or preferred_norm in _normalize_model_key(m.model_id or "")
129
129
  ]
130
130
  if len(normalized_matches) == 1:
131
131
  return ModelMatchResult(
@@ -134,14 +134,14 @@ def match_model_from_config(preferred: str | None = None) -> ModelMatchResult:
134
134
  filter_hint=None,
135
135
  )
136
136
 
137
- # Partial match (case-insensitive) on model_name or model_params.model.
137
+ # Partial match (case-insensitive) on model_name or model_id.
138
138
  # If normalized matching found candidates (even if multiple), prefer those as the filter set.
139
139
  matches = normalized_matches or [
140
140
  m
141
141
  for m in models
142
142
  if preferred_lower in m.selector.lower()
143
143
  or preferred_lower in m.model_name.lower()
144
- or preferred_lower in (m.model_params.model or "").lower()
144
+ or preferred_lower in (m.model_id or "").lower()
145
145
  ]
146
146
  if len(matches) == 1:
147
147
  return ModelMatchResult(matched_model=matches[0].selector, filtered_models=models, filter_hint=None)