klaude-code 2.8.1__py3-none-any.whl → 2.9.0__py3-none-any.whl
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.
- klaude_code/app/runtime.py +2 -1
- klaude_code/auth/antigravity/oauth.py +0 -9
- klaude_code/auth/antigravity/token_manager.py +0 -18
- klaude_code/auth/base.py +53 -0
- klaude_code/auth/codex/exceptions.py +0 -4
- klaude_code/auth/codex/oauth.py +32 -28
- klaude_code/auth/codex/token_manager.py +0 -18
- klaude_code/cli/cost_cmd.py +128 -39
- klaude_code/cli/list_model.py +27 -10
- klaude_code/cli/main.py +14 -3
- klaude_code/config/assets/builtin_config.yaml +8 -24
- klaude_code/config/config.py +47 -25
- klaude_code/config/sub_agent_model_helper.py +18 -13
- klaude_code/config/thinking.py +0 -8
- klaude_code/const.py +1 -1
- klaude_code/core/agent_profile.py +10 -52
- klaude_code/core/compaction/overflow.py +0 -4
- klaude_code/core/executor.py +33 -5
- klaude_code/core/manager/llm_clients.py +9 -1
- klaude_code/core/prompts/prompt-claude-code.md +4 -4
- klaude_code/core/reminders.py +21 -23
- klaude_code/core/task.py +0 -4
- klaude_code/core/tool/__init__.py +3 -2
- klaude_code/core/tool/file/apply_patch.py +0 -27
- klaude_code/core/tool/file/read_tool.md +3 -2
- klaude_code/core/tool/file/read_tool.py +15 -2
- klaude_code/core/tool/offload.py +0 -35
- klaude_code/core/tool/sub_agent/__init__.py +6 -0
- klaude_code/core/tool/sub_agent/image_gen.md +16 -0
- klaude_code/core/tool/sub_agent/image_gen.py +146 -0
- klaude_code/core/tool/sub_agent/task.md +20 -0
- klaude_code/core/tool/sub_agent/task.py +205 -0
- klaude_code/core/tool/tool_registry.py +0 -16
- klaude_code/core/turn.py +1 -1
- klaude_code/llm/anthropic/input.py +6 -5
- klaude_code/llm/antigravity/input.py +14 -7
- klaude_code/llm/codex/client.py +22 -0
- klaude_code/llm/codex/prompt_sync.py +237 -0
- klaude_code/llm/google/client.py +8 -6
- klaude_code/llm/google/input.py +20 -12
- klaude_code/llm/image.py +18 -11
- klaude_code/llm/input_common.py +14 -6
- klaude_code/llm/json_stable.py +37 -0
- klaude_code/llm/openai_compatible/input.py +0 -10
- klaude_code/llm/openai_compatible/stream.py +16 -1
- klaude_code/llm/registry.py +0 -5
- klaude_code/llm/responses/input.py +15 -5
- klaude_code/llm/usage.py +0 -8
- klaude_code/protocol/events.py +2 -1
- klaude_code/protocol/message.py +2 -2
- klaude_code/protocol/model.py +20 -1
- klaude_code/protocol/op.py +13 -0
- klaude_code/protocol/op_handler.py +5 -0
- klaude_code/protocol/sub_agent/AGENTS.md +5 -5
- klaude_code/protocol/sub_agent/__init__.py +13 -34
- klaude_code/protocol/sub_agent/explore.py +7 -34
- klaude_code/protocol/sub_agent/image_gen.py +3 -74
- klaude_code/protocol/sub_agent/task.py +3 -47
- klaude_code/protocol/sub_agent/web.py +8 -52
- klaude_code/protocol/tools.py +2 -0
- klaude_code/session/session.py +58 -21
- klaude_code/session/store.py +0 -4
- klaude_code/skill/assets/deslop/SKILL.md +9 -0
- klaude_code/skill/system_skills.py +0 -20
- klaude_code/tui/command/fork_session_cmd.py +5 -2
- klaude_code/tui/command/resume_cmd.py +9 -2
- klaude_code/tui/command/sub_agent_model_cmd.py +85 -18
- klaude_code/tui/components/assistant.py +0 -26
- klaude_code/tui/components/command_output.py +3 -1
- klaude_code/tui/components/developer.py +3 -0
- klaude_code/tui/components/diffs.py +2 -208
- klaude_code/tui/components/errors.py +4 -0
- klaude_code/tui/components/mermaid_viewer.py +2 -2
- klaude_code/tui/components/rich/markdown.py +0 -54
- klaude_code/tui/components/rich/theme.py +2 -0
- klaude_code/tui/components/sub_agent.py +2 -46
- klaude_code/tui/components/thinking.py +0 -33
- klaude_code/tui/components/tools.py +43 -21
- klaude_code/tui/input/images.py +21 -18
- klaude_code/tui/input/key_bindings.py +2 -2
- klaude_code/tui/input/prompt_toolkit.py +49 -49
- klaude_code/tui/machine.py +15 -11
- klaude_code/tui/renderer.py +11 -20
- klaude_code/tui/runner.py +2 -1
- klaude_code/tui/terminal/image.py +6 -34
- klaude_code/ui/common.py +0 -70
- {klaude_code-2.8.1.dist-info → klaude_code-2.9.0.dist-info}/METADATA +3 -6
- {klaude_code-2.8.1.dist-info → klaude_code-2.9.0.dist-info}/RECORD +90 -86
- klaude_code/core/tool/sub_agent_tool.py +0 -126
- klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -108
- klaude_code/tui/components/rich/searchable_text.py +0 -68
- {klaude_code-2.8.1.dist-info → klaude_code-2.9.0.dist-info}/WHEEL +0 -0
- {klaude_code-2.8.1.dist-info → klaude_code-2.9.0.dist-info}/entry_points.txt +0 -0
klaude_code/tui/machine.py
CHANGED
|
@@ -49,7 +49,7 @@ from klaude_code.tui.commands import (
|
|
|
49
49
|
from klaude_code.tui.components.rich import status as r_status
|
|
50
50
|
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
51
51
|
from klaude_code.tui.components.thinking import extract_last_bold_header, normalize_thinking_content
|
|
52
|
-
from klaude_code.tui.components.tools import get_tool_active_form, is_sub_agent_tool
|
|
52
|
+
from klaude_code.tui.components.tools import get_task_active_form, get_tool_active_form, is_sub_agent_tool
|
|
53
53
|
|
|
54
54
|
# Tools that complete quickly and don't benefit from streaming activity display.
|
|
55
55
|
# For models without fine-grained tool JSON streaming (e.g., Gemini), showing these
|
|
@@ -97,10 +97,6 @@ class ActivityState:
|
|
|
97
97
|
self._sub_agent_tool_calls: dict[str, int] = {}
|
|
98
98
|
self._sub_agent_tool_calls_by_id: dict[str, str] = {}
|
|
99
99
|
|
|
100
|
-
@property
|
|
101
|
-
def is_composing(self) -> bool:
|
|
102
|
-
return self._composing and not self._tool_calls and not self._sub_agent_tool_calls
|
|
103
|
-
|
|
104
100
|
def set_composing(self, composing: bool) -> None:
|
|
105
101
|
self._composing = composing
|
|
106
102
|
if not composing:
|
|
@@ -321,7 +317,7 @@ class _SessionState:
|
|
|
321
317
|
|
|
322
318
|
@property
|
|
323
319
|
def should_show_sub_agent_thinking_header(self) -> bool:
|
|
324
|
-
return bool(self.sub_agent_state and self.sub_agent_state.sub_agent_type ==
|
|
320
|
+
return bool(self.sub_agent_state and self.sub_agent_state.sub_agent_type == tools.IMAGE_GEN)
|
|
325
321
|
|
|
326
322
|
@property
|
|
327
323
|
def should_extract_reasoning_header(self) -> bool:
|
|
@@ -607,11 +603,14 @@ class DisplayStateMachine:
|
|
|
607
603
|
# Skip activity state for fast tools on non-streaming models (e.g., Gemini)
|
|
608
604
|
# to avoid flash-and-disappear effect
|
|
609
605
|
if not is_replay and not s.should_skip_tool_activity(e.tool_name):
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
self._spinner.add_sub_agent_tool_call(e.tool_call_id, tool_active_form)
|
|
606
|
+
if e.tool_name == tools.TASK:
|
|
607
|
+
pass
|
|
613
608
|
else:
|
|
614
|
-
|
|
609
|
+
tool_active_form = get_tool_active_form(e.tool_name)
|
|
610
|
+
if is_sub_agent_tool(e.tool_name):
|
|
611
|
+
self._spinner.add_sub_agent_tool_call(e.tool_call_id, tool_active_form)
|
|
612
|
+
else:
|
|
613
|
+
self._spinner.add_tool_call(tool_active_form)
|
|
615
614
|
|
|
616
615
|
if not is_replay:
|
|
617
616
|
cmds.extend(self._spinner_update_commands())
|
|
@@ -629,12 +628,17 @@ class DisplayStateMachine:
|
|
|
629
628
|
primary.thinking_stream_active = False
|
|
630
629
|
cmds.append(EndThinkingStream(session_id=primary.session_id))
|
|
631
630
|
|
|
631
|
+
if not is_replay and e.tool_name == tools.TASK and not s.should_skip_tool_activity(e.tool_name):
|
|
632
|
+
tool_active_form = get_task_active_form(e.arguments)
|
|
633
|
+
self._spinner.add_sub_agent_tool_call(e.tool_call_id, tool_active_form)
|
|
634
|
+
cmds.extend(self._spinner_update_commands())
|
|
635
|
+
|
|
632
636
|
cmds.append(RenderToolCall(e))
|
|
633
637
|
return cmds
|
|
634
638
|
|
|
635
639
|
case events.ToolResultEvent() as e:
|
|
636
640
|
if not is_replay and is_sub_agent_tool(e.tool_name):
|
|
637
|
-
self._spinner.finish_sub_agent_tool_call(e.tool_call_id
|
|
641
|
+
self._spinner.finish_sub_agent_tool_call(e.tool_call_id)
|
|
638
642
|
cmds.extend(self._spinner_update_commands())
|
|
639
643
|
|
|
640
644
|
if s.is_sub_agent and not e.is_error:
|
klaude_code/tui/renderer.py
CHANGED
|
@@ -184,13 +184,6 @@ class TUICommandRenderer:
|
|
|
184
184
|
def is_sub_agent_session(self, session_id: str) -> bool:
|
|
185
185
|
return session_id in self._sessions and self._sessions[session_id].sub_agent_state is not None
|
|
186
186
|
|
|
187
|
-
def _should_display_sub_agent_thinking_header(self, session_id: str) -> bool:
|
|
188
|
-
# Hardcoded: only show sub-agent thinking headers for ImageGen.
|
|
189
|
-
st = self._sessions.get(session_id)
|
|
190
|
-
if st is None or st.sub_agent_state is None:
|
|
191
|
-
return False
|
|
192
|
-
return st.sub_agent_state.sub_agent_type == "ImageGen"
|
|
193
|
-
|
|
194
187
|
def _advance_sub_agent_color_index(self) -> None:
|
|
195
188
|
palette_size = len(self.themes.sub_agent_colors)
|
|
196
189
|
if palette_size == 0:
|
|
@@ -417,21 +410,12 @@ class TUICommandRenderer:
|
|
|
417
410
|
if image_path is not None:
|
|
418
411
|
self.display_image(str(image_path))
|
|
419
412
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
self.print(renderable)
|
|
413
|
+
if not is_sub_agent and isinstance(e.ui_extra, model.ImageUIExtra):
|
|
414
|
+
self.display_image(e.ui_extra.file_path)
|
|
423
415
|
|
|
424
|
-
|
|
425
|
-
renderable = c_thinking.render_thinking(
|
|
426
|
-
content,
|
|
427
|
-
code_theme=self.themes.code_theme,
|
|
428
|
-
style=ThemeKey.THINKING,
|
|
429
|
-
)
|
|
416
|
+
renderable = c_tools.render_tool_result(e, code_theme=self.themes.code_theme, session_id=e.session_id)
|
|
430
417
|
if renderable is not None:
|
|
431
|
-
self.console.push_theme(theme=self.themes.thinking_markdown_theme)
|
|
432
418
|
self.print(renderable)
|
|
433
|
-
self.console.pop_theme()
|
|
434
|
-
self.print()
|
|
435
419
|
|
|
436
420
|
def display_thinking_header(self, header: str) -> None:
|
|
437
421
|
stripped = header.strip()
|
|
@@ -451,6 +435,13 @@ class TUICommandRenderer:
|
|
|
451
435
|
with self.session_print_context(e.session_id):
|
|
452
436
|
self.print(c_developer.render_developer_message(e))
|
|
453
437
|
|
|
438
|
+
# Display images from @ file references and user attachments
|
|
439
|
+
if e.item.ui_extra:
|
|
440
|
+
for ui_item in e.item.ui_extra.items:
|
|
441
|
+
if isinstance(ui_item, (model.AtFileImagesUIItem, model.UserImagesUIItem)):
|
|
442
|
+
for image_path in ui_item.paths:
|
|
443
|
+
self.display_image(image_path)
|
|
444
|
+
|
|
454
445
|
def display_command_output(self, e: events.CommandOutputEvent) -> None:
|
|
455
446
|
with self.session_print_context(e.session_id):
|
|
456
447
|
self.print(c_command_output.render_command_output(e))
|
|
@@ -690,7 +681,7 @@ class TUICommandRenderer:
|
|
|
690
681
|
case PrintBlankLine():
|
|
691
682
|
self.print()
|
|
692
683
|
case PrintRuleLine():
|
|
693
|
-
self.console.print(Rule(characters="─", style=ThemeKey.
|
|
684
|
+
self.console.print(Rule(characters="─", style=ThemeKey.LINES_DIM))
|
|
694
685
|
case EmitOsc94Error():
|
|
695
686
|
emit_osc94(OSC94States.ERROR)
|
|
696
687
|
case EmitTmuxSignal():
|
klaude_code/tui/runner.py
CHANGED
|
@@ -327,5 +327,6 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
|
|
|
327
327
|
if not exit_hint_printed:
|
|
328
328
|
active_session_id = components.executor.context.current_session_id()
|
|
329
329
|
if active_session_id and Session.exists(active_session_id):
|
|
330
|
+
short_id = Session.shortest_unique_prefix(active_session_id)
|
|
330
331
|
log(f"Session ID: {active_session_id}")
|
|
331
|
-
log(f"Resume with: klaude
|
|
332
|
+
log(f"Resume with: klaude -r {short_id}")
|
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import base64
|
|
4
4
|
import shutil
|
|
5
|
-
import struct
|
|
6
5
|
import subprocess
|
|
7
6
|
import sys
|
|
8
7
|
import tempfile
|
|
@@ -12,8 +11,8 @@ from typing import IO
|
|
|
12
11
|
# Kitty graphics protocol chunk size (4096 is the recommended max)
|
|
13
12
|
_CHUNK_SIZE = 4096
|
|
14
13
|
|
|
15
|
-
# Max columns for
|
|
16
|
-
_MAX_COLS =
|
|
14
|
+
# Max columns for image display
|
|
15
|
+
_MAX_COLS = 80
|
|
17
16
|
|
|
18
17
|
# Image formats that need conversion to PNG
|
|
19
18
|
_NEEDS_CONVERSION = {".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".tiff", ".tif"}
|
|
@@ -40,26 +39,10 @@ def _convert_to_png(path: Path) -> bytes | None:
|
|
|
40
39
|
return None
|
|
41
40
|
|
|
42
41
|
|
|
43
|
-
def _get_png_dimensions(data: bytes) -> tuple[int, int] | None:
|
|
44
|
-
"""Extract width and height from PNG file header."""
|
|
45
|
-
# PNG: 8-byte signature + IHDR chunk (4 len + 4 type + 4 width + 4 height)
|
|
46
|
-
if len(data) < 24 or data[:8] != b"\x89PNG\r\n\x1a\n":
|
|
47
|
-
return None
|
|
48
|
-
width, height = struct.unpack(">II", data[16:24])
|
|
49
|
-
return width, height
|
|
50
|
-
|
|
51
|
-
|
|
52
42
|
def print_kitty_image(file_path: str | Path, *, file: IO[str] | None = None) -> None:
|
|
53
43
|
"""Print an image to the terminal using Kitty graphics protocol.
|
|
54
44
|
|
|
55
|
-
|
|
56
|
-
with raw escape sequences. Image size adapts based on aspect ratio:
|
|
57
|
-
- Landscape images: fill terminal width
|
|
58
|
-
- Portrait images: limit height to avoid oversized display
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
file_path: Path to the image file (PNG recommended).
|
|
62
|
-
file: Output file stream. Defaults to stdout.
|
|
45
|
+
Only specifies column width; Kitty auto-scales height to preserve aspect ratio.
|
|
63
46
|
"""
|
|
64
47
|
path = Path(file_path) if isinstance(file_path, str) else file_path
|
|
65
48
|
if not path.exists():
|
|
@@ -80,20 +63,9 @@ def print_kitty_image(file_path: str | Path, *, file: IO[str] | None = None) ->
|
|
|
80
63
|
out = file or sys.stdout
|
|
81
64
|
|
|
82
65
|
term_size = shutil.get_terminal_size()
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if dimensions is not None:
|
|
87
|
-
img_width, img_height = dimensions
|
|
88
|
-
if img_width > 2 * img_height:
|
|
89
|
-
# Wide landscape (width > 2x height): fill terminal width
|
|
90
|
-
size_param = f"c={term_size.columns}"
|
|
91
|
-
else:
|
|
92
|
-
# Other images: limit width to 80% of terminal
|
|
93
|
-
size_param = f"c={min(_MAX_COLS, term_size.columns * 4 // 5)}"
|
|
94
|
-
else:
|
|
95
|
-
# Fallback: limit width to 80% of terminal
|
|
96
|
-
size_param = f"c={min(_MAX_COLS, term_size.columns * 4 // 5)}"
|
|
66
|
+
# Only specify columns, let Kitty auto-scale height to preserve aspect ratio
|
|
67
|
+
target_cols = min(_MAX_COLS, term_size.columns)
|
|
68
|
+
size_param = f"c={target_cols}"
|
|
97
69
|
print("", file=out)
|
|
98
70
|
_write_kitty_graphics(out, encoded, size_param=size_param)
|
|
99
71
|
print("", file=out)
|
klaude_code/ui/common.py
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import re
|
|
2
|
-
import subprocess
|
|
3
|
-
from pathlib import Path
|
|
4
1
|
from typing import TYPE_CHECKING
|
|
5
2
|
|
|
6
3
|
if TYPE_CHECKING:
|
|
7
4
|
from klaude_code.protocol.llm_param import LLMConfigModelParameter, OpenRouterProviderRouting
|
|
8
5
|
|
|
9
|
-
LEADING_NEWLINES_REGEX = re.compile(r"^\n{2,}")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def remove_leading_newlines(text: str) -> str:
|
|
13
|
-
return text.lstrip("\n")
|
|
14
|
-
|
|
15
6
|
|
|
16
7
|
def format_number(tokens: int) -> str:
|
|
17
8
|
if tokens < 1000:
|
|
@@ -33,67 +24,6 @@ def format_number(tokens: int) -> str:
|
|
|
33
24
|
return f"{m}M{remaining}k"
|
|
34
25
|
|
|
35
26
|
|
|
36
|
-
def get_current_git_branch(path: Path | None = None) -> str | None:
|
|
37
|
-
"""Get current git branch name, return None if not in a git repository"""
|
|
38
|
-
if path is None:
|
|
39
|
-
path = Path.cwd()
|
|
40
|
-
|
|
41
|
-
try:
|
|
42
|
-
# Check if in git repository
|
|
43
|
-
git_dir = subprocess.run(
|
|
44
|
-
["git", "rev-parse", "--git-dir"],
|
|
45
|
-
cwd=path,
|
|
46
|
-
capture_output=True,
|
|
47
|
-
text=True,
|
|
48
|
-
timeout=2,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
if git_dir.returncode != 0:
|
|
52
|
-
return None
|
|
53
|
-
|
|
54
|
-
# Get current branch name
|
|
55
|
-
result = subprocess.run(
|
|
56
|
-
["git", "branch", "--show-current"],
|
|
57
|
-
cwd=path,
|
|
58
|
-
capture_output=True,
|
|
59
|
-
text=True,
|
|
60
|
-
timeout=2,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
if result.returncode == 0:
|
|
64
|
-
branch = result.stdout.strip()
|
|
65
|
-
return branch if branch else None
|
|
66
|
-
|
|
67
|
-
# Fallback: get HEAD reference
|
|
68
|
-
head_file = subprocess.run(
|
|
69
|
-
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
70
|
-
cwd=path,
|
|
71
|
-
capture_output=True,
|
|
72
|
-
text=True,
|
|
73
|
-
timeout=2,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
if head_file.returncode == 0:
|
|
77
|
-
branch = head_file.stdout.strip()
|
|
78
|
-
return branch if branch and branch != "HEAD" else None
|
|
79
|
-
|
|
80
|
-
except (subprocess.TimeoutExpired, subprocess.SubprocessError, FileNotFoundError):
|
|
81
|
-
pass
|
|
82
|
-
|
|
83
|
-
return None
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def show_path_with_tilde(path: Path | None = None):
|
|
87
|
-
if path is None:
|
|
88
|
-
path = Path.cwd()
|
|
89
|
-
|
|
90
|
-
try:
|
|
91
|
-
relative_path = path.relative_to(Path.home())
|
|
92
|
-
return f"~/{relative_path}"
|
|
93
|
-
except ValueError:
|
|
94
|
-
return str(path)
|
|
95
|
-
|
|
96
|
-
|
|
97
27
|
def format_model_params(model_params: "LLMConfigModelParameter") -> list[str]:
|
|
98
28
|
"""Format model parameters in a concise style.
|
|
99
29
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: klaude-code
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: Minimal code agent CLI
|
|
5
5
|
Requires-Dist: anthropic>=0.66.0
|
|
6
6
|
Requires-Dist: chardet>=5.2.0
|
|
7
7
|
Requires-Dist: ddgs>=9.9.3
|
|
8
8
|
Requires-Dist: diff-match-patch>=20241021
|
|
9
|
+
Requires-Dist: filelock>=3.20.3
|
|
9
10
|
Requires-Dist: google-genai>=1.56.0
|
|
10
11
|
Requires-Dist: markdown-it-py>=4.0.0
|
|
11
12
|
Requires-Dist: openai>=1.102.0
|
|
@@ -23,7 +24,7 @@ Description-Content-Type: text/markdown
|
|
|
23
24
|
Minimal code agent CLI.
|
|
24
25
|
|
|
25
26
|
## Features
|
|
26
|
-
- **Multi-provider**: Anthropic Message API, OpenAI Responses API, OpenRouter,
|
|
27
|
+
- **Multi-provider**: Anthropic Message API, OpenAI Responses API, OpenRouter, ChatGPT Codex OAuth etc.
|
|
27
28
|
- **Keep reasoning item in context**: Interleaved thinking support
|
|
28
29
|
- **Model-aware tools**: Claude Code tool set for Opus, `apply_patch` for GPT-5/Codex
|
|
29
30
|
- **Reminders**: Cooldown-based todo tracking, instruction reinforcement and external file change reminder
|
|
@@ -107,7 +108,6 @@ On first run, you'll be prompted to select a model. Your choice is saved as `mai
|
|
|
107
108
|
| Provider | Env Variable | Models |
|
|
108
109
|
|-------------|-----------------------|-------------------------------------------------------------------------------|
|
|
109
110
|
| anthropic | `ANTHROPIC_API_KEY` | sonnet, opus |
|
|
110
|
-
| claude | N/A (OAuth) | sonnet@claude, opus@claude (requires Claude Pro/Max subscription) |
|
|
111
111
|
| openai | `OPENAI_API_KEY` | gpt-5.2 |
|
|
112
112
|
| openrouter | `OPENROUTER_API_KEY` | gpt-5.2, gpt-5.2-fast, gpt-5.1-codex-max, sonnet, opus, haiku, kimi, gemini-* |
|
|
113
113
|
| deepseek | `DEEPSEEK_API_KEY` | deepseek |
|
|
@@ -139,7 +139,6 @@ klaude auth login deepseek # Set DEEPSEEK_API_KEY
|
|
|
139
139
|
klaude auth login moonshot # Set MOONSHOT_API_KEY
|
|
140
140
|
|
|
141
141
|
# OAuth login for subscription-based providers
|
|
142
|
-
klaude auth login claude # Claude Pro/Max subscription
|
|
143
142
|
klaude auth login codex # ChatGPT Pro subscription
|
|
144
143
|
```
|
|
145
144
|
|
|
@@ -148,7 +147,6 @@ API keys are stored in `~/.klaude/klaude-auth.json` and used as fallback when en
|
|
|
148
147
|
To logout from OAuth providers:
|
|
149
148
|
|
|
150
149
|
```bash
|
|
151
|
-
klaude auth logout claude
|
|
152
150
|
klaude auth logout codex
|
|
153
151
|
```
|
|
154
152
|
|
|
@@ -201,7 +199,6 @@ provider_list:
|
|
|
201
199
|
##### Supported Protocols
|
|
202
200
|
|
|
203
201
|
- `anthropic` - Anthropic Messages API
|
|
204
|
-
- `claude_oauth` - Claude OAuth (for Claude Pro/Max subscribers)
|
|
205
202
|
- `openai` - OpenAI Chat Completion API
|
|
206
203
|
- `responses` - OpenAI Responses API (for o-series, GPT-5, Codex)
|
|
207
204
|
- `codex_oauth` - OpenAI Codex CLI (OAuth-based, for ChatGPT Pro subscribers)
|