klaude-code 2.5.2__py3-none-any.whl → 2.6.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/auth/__init__.py +10 -0
- klaude_code/auth/env.py +77 -0
- klaude_code/cli/auth_cmd.py +89 -21
- klaude_code/cli/config_cmd.py +5 -5
- klaude_code/cli/cost_cmd.py +167 -68
- klaude_code/cli/main.py +51 -27
- klaude_code/cli/self_update.py +7 -7
- klaude_code/config/assets/builtin_config.yaml +45 -24
- klaude_code/config/builtin_config.py +23 -9
- klaude_code/config/config.py +19 -9
- klaude_code/config/model_matcher.py +1 -1
- klaude_code/const.py +2 -1
- klaude_code/core/tool/file/edit_tool.py +1 -1
- klaude_code/core/tool/file/read_tool.py +2 -2
- klaude_code/core/tool/file/write_tool.py +1 -1
- klaude_code/core/turn.py +21 -4
- klaude_code/llm/anthropic/client.py +75 -50
- klaude_code/llm/anthropic/input.py +20 -9
- klaude_code/llm/google/client.py +235 -148
- klaude_code/llm/google/input.py +44 -36
- klaude_code/llm/openai_compatible/stream.py +114 -100
- klaude_code/llm/openrouter/client.py +1 -0
- klaude_code/llm/openrouter/reasoning.py +4 -29
- klaude_code/llm/partial_message.py +2 -32
- klaude_code/llm/responses/client.py +99 -81
- klaude_code/llm/responses/input.py +11 -25
- klaude_code/llm/stream_parts.py +94 -0
- klaude_code/log.py +57 -0
- klaude_code/protocol/events.py +214 -0
- klaude_code/protocol/sub_agent/image_gen.py +0 -4
- klaude_code/session/session.py +51 -18
- klaude_code/tui/command/fork_session_cmd.py +14 -23
- klaude_code/tui/command/model_picker.py +2 -17
- klaude_code/tui/command/resume_cmd.py +2 -18
- klaude_code/tui/command/sub_agent_model_cmd.py +5 -19
- klaude_code/tui/command/thinking_cmd.py +2 -14
- klaude_code/tui/commands.py +0 -5
- klaude_code/tui/components/common.py +1 -1
- klaude_code/tui/components/metadata.py +21 -21
- klaude_code/tui/components/rich/quote.py +36 -8
- klaude_code/tui/components/rich/theme.py +2 -0
- klaude_code/tui/components/sub_agent.py +6 -0
- klaude_code/tui/display.py +11 -1
- klaude_code/tui/input/completers.py +11 -7
- klaude_code/tui/input/prompt_toolkit.py +3 -1
- klaude_code/tui/machine.py +108 -56
- klaude_code/tui/renderer.py +4 -65
- klaude_code/tui/terminal/selector.py +174 -31
- {klaude_code-2.5.2.dist-info → klaude_code-2.6.0.dist-info}/METADATA +23 -31
- {klaude_code-2.5.2.dist-info → klaude_code-2.6.0.dist-info}/RECORD +52 -58
- klaude_code/cli/session_cmd.py +0 -96
- klaude_code/protocol/events/__init__.py +0 -63
- klaude_code/protocol/events/base.py +0 -18
- klaude_code/protocol/events/chat.py +0 -30
- klaude_code/protocol/events/lifecycle.py +0 -23
- klaude_code/protocol/events/metadata.py +0 -16
- klaude_code/protocol/events/streaming.py +0 -43
- klaude_code/protocol/events/system.py +0 -56
- klaude_code/protocol/events/tools.py +0 -27
- {klaude_code-2.5.2.dist-info → klaude_code-2.6.0.dist-info}/WHEEL +0 -0
- {klaude_code-2.5.2.dist-info → klaude_code-2.6.0.dist-info}/entry_points.txt +0 -0
klaude_code/cli/session_cmd.py
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
|
|
3
|
-
import typer
|
|
4
|
-
|
|
5
|
-
from klaude_code.log import log
|
|
6
|
-
from klaude_code.session import Session
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def _session_confirm(sessions: list[Session.SessionMetaBrief], message: str) -> bool:
|
|
10
|
-
"""Show session list and confirm deletion using prompt_toolkit."""
|
|
11
|
-
|
|
12
|
-
from prompt_toolkit.styles import Style
|
|
13
|
-
|
|
14
|
-
from klaude_code.tui.terminal.selector import SelectItem, select_one
|
|
15
|
-
|
|
16
|
-
def _fmt(ts: float) -> str:
|
|
17
|
-
try:
|
|
18
|
-
return time.strftime("%m-%d %H:%M:%S", time.localtime(ts))
|
|
19
|
-
except (OSError, OverflowError, ValueError):
|
|
20
|
-
return str(ts)
|
|
21
|
-
|
|
22
|
-
log(f"Sessions to delete ({len(sessions)}):")
|
|
23
|
-
for s in sessions:
|
|
24
|
-
msg_count_display = "N/A" if s.messages_count == -1 else str(s.messages_count)
|
|
25
|
-
first_msg_text = s.user_messages[0] if s.user_messages else ""
|
|
26
|
-
first_msg = first_msg_text.strip().replace("\n", " ")[:50]
|
|
27
|
-
if len(first_msg_text) > 50:
|
|
28
|
-
first_msg += "…"
|
|
29
|
-
log(f" {_fmt(s.updated_at)} {msg_count_display:>3} msgs {first_msg}")
|
|
30
|
-
|
|
31
|
-
items: list[SelectItem[bool]] = [
|
|
32
|
-
SelectItem(title=[("class:text", "No\n")], value=False, search_text="No"),
|
|
33
|
-
SelectItem(title=[("class:text", "Yes\n")], value=True, search_text="Yes"),
|
|
34
|
-
]
|
|
35
|
-
|
|
36
|
-
result = select_one(
|
|
37
|
-
message=message,
|
|
38
|
-
items=items,
|
|
39
|
-
pointer="→",
|
|
40
|
-
style=Style(
|
|
41
|
-
[
|
|
42
|
-
("question", "bold"),
|
|
43
|
-
("pointer", "ansigreen"),
|
|
44
|
-
("highlighted", "ansigreen"),
|
|
45
|
-
("text", ""),
|
|
46
|
-
]
|
|
47
|
-
),
|
|
48
|
-
use_search_filter=False,
|
|
49
|
-
)
|
|
50
|
-
return bool(result)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def session_clean(
|
|
54
|
-
min_messages: int = typer.Option(5, "--min", "-n", help="Minimum messages to keep a session"),
|
|
55
|
-
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt"),
|
|
56
|
-
) -> None:
|
|
57
|
-
"""Remove sessions with fewer than N messages (default: 5)"""
|
|
58
|
-
sessions = Session.list_sessions()
|
|
59
|
-
to_delete = [s for s in sessions if 0 <= s.messages_count < min_messages]
|
|
60
|
-
|
|
61
|
-
if not to_delete:
|
|
62
|
-
log(f"No sessions with fewer than {min_messages} messages found.")
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
if not yes and not _session_confirm(to_delete, "Delete these sessions?"):
|
|
66
|
-
log("Aborted.")
|
|
67
|
-
return
|
|
68
|
-
|
|
69
|
-
deleted = Session.clean_small_sessions(min_messages)
|
|
70
|
-
log(f"Deleted {deleted} session(s).")
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def session_clean_all(
|
|
74
|
-
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt"),
|
|
75
|
-
) -> None:
|
|
76
|
-
"""Remove all sessions for the current project"""
|
|
77
|
-
sessions = Session.list_sessions()
|
|
78
|
-
|
|
79
|
-
if not sessions:
|
|
80
|
-
log("No sessions found.")
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
if not yes and not _session_confirm(sessions, "Delete ALL sessions? This cannot be undone."):
|
|
84
|
-
log("Aborted.")
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
deleted = Session.clean_all_sessions()
|
|
88
|
-
log(f"Deleted {deleted} session(s).")
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def register_session_commands(app: typer.Typer) -> None:
|
|
92
|
-
"""Register session subcommands to the given Typer app."""
|
|
93
|
-
session_app = typer.Typer(help="Manage sessions for the current project")
|
|
94
|
-
session_app.command("clean")(session_clean)
|
|
95
|
-
session_app.command("clean-all")(session_clean_all)
|
|
96
|
-
app.add_typer(session_app, name="session")
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from klaude_code.protocol.events.base import Event, ResponseEvent
|
|
4
|
-
from klaude_code.protocol.events.chat import (
|
|
5
|
-
CommandOutputEvent,
|
|
6
|
-
DeveloperMessageEvent,
|
|
7
|
-
TodoChangeEvent,
|
|
8
|
-
UserMessageEvent,
|
|
9
|
-
)
|
|
10
|
-
from klaude_code.protocol.events.lifecycle import TaskFinishEvent, TaskStartEvent, TurnEndEvent, TurnStartEvent
|
|
11
|
-
from klaude_code.protocol.events.metadata import TaskMetadataEvent, UsageEvent
|
|
12
|
-
from klaude_code.protocol.events.streaming import (
|
|
13
|
-
AssistantImageDeltaEvent,
|
|
14
|
-
AssistantTextDeltaEvent,
|
|
15
|
-
AssistantTextEndEvent,
|
|
16
|
-
AssistantTextStartEvent,
|
|
17
|
-
ResponseCompleteEvent,
|
|
18
|
-
ThinkingDeltaEvent,
|
|
19
|
-
ThinkingEndEvent,
|
|
20
|
-
ThinkingStartEvent,
|
|
21
|
-
ToolCallStartEvent,
|
|
22
|
-
)
|
|
23
|
-
from klaude_code.protocol.events.system import (
|
|
24
|
-
EndEvent,
|
|
25
|
-
ErrorEvent,
|
|
26
|
-
InterruptEvent,
|
|
27
|
-
ReplayEventUnion,
|
|
28
|
-
ReplayHistoryEvent,
|
|
29
|
-
WelcomeEvent,
|
|
30
|
-
)
|
|
31
|
-
from klaude_code.protocol.events.tools import ToolCallEvent, ToolResultEvent
|
|
32
|
-
|
|
33
|
-
__all__ = [
|
|
34
|
-
"AssistantImageDeltaEvent",
|
|
35
|
-
"AssistantTextDeltaEvent",
|
|
36
|
-
"AssistantTextEndEvent",
|
|
37
|
-
"AssistantTextStartEvent",
|
|
38
|
-
"CommandOutputEvent",
|
|
39
|
-
"DeveloperMessageEvent",
|
|
40
|
-
"EndEvent",
|
|
41
|
-
"ErrorEvent",
|
|
42
|
-
"Event",
|
|
43
|
-
"InterruptEvent",
|
|
44
|
-
"ReplayEventUnion",
|
|
45
|
-
"ReplayHistoryEvent",
|
|
46
|
-
"ResponseCompleteEvent",
|
|
47
|
-
"ResponseEvent",
|
|
48
|
-
"TaskFinishEvent",
|
|
49
|
-
"TaskMetadataEvent",
|
|
50
|
-
"TaskStartEvent",
|
|
51
|
-
"ThinkingDeltaEvent",
|
|
52
|
-
"ThinkingEndEvent",
|
|
53
|
-
"ThinkingStartEvent",
|
|
54
|
-
"TodoChangeEvent",
|
|
55
|
-
"ToolCallEvent",
|
|
56
|
-
"ToolCallStartEvent",
|
|
57
|
-
"ToolResultEvent",
|
|
58
|
-
"TurnEndEvent",
|
|
59
|
-
"TurnStartEvent",
|
|
60
|
-
"UsageEvent",
|
|
61
|
-
"UserMessageEvent",
|
|
62
|
-
"WelcomeEvent",
|
|
63
|
-
]
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import time
|
|
4
|
-
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Event(BaseModel):
|
|
9
|
-
"""Base event."""
|
|
10
|
-
|
|
11
|
-
session_id: str
|
|
12
|
-
timestamp: float = Field(default_factory=time.time)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ResponseEvent(Event):
|
|
16
|
-
"""Event associated with a single model response."""
|
|
17
|
-
|
|
18
|
-
response_id: str | None = None
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from klaude_code.protocol import message, model
|
|
4
|
-
from klaude_code.protocol.commands import CommandName
|
|
5
|
-
|
|
6
|
-
from .base import Event
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class UserMessageEvent(Event):
|
|
10
|
-
content: str
|
|
11
|
-
images: list[message.ImageURLPart] | None = None
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class DeveloperMessageEvent(Event):
|
|
15
|
-
"""DeveloperMessages are reminders in user messages or tool results."""
|
|
16
|
-
|
|
17
|
-
item: message.DeveloperMessage
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class TodoChangeEvent(Event):
|
|
21
|
-
todos: list[model.TodoItem]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class CommandOutputEvent(Event):
|
|
25
|
-
"""Event for command output display. Not persisted to session history."""
|
|
26
|
-
|
|
27
|
-
command_name: CommandName | str
|
|
28
|
-
content: str = ""
|
|
29
|
-
ui_extra: model.ToolResultUIExtra | None = None
|
|
30
|
-
is_error: bool = False
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from klaude_code.protocol import model
|
|
4
|
-
|
|
5
|
-
from .base import Event
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class TaskStartEvent(Event):
|
|
9
|
-
sub_agent_state: model.SubAgentState | None = None
|
|
10
|
-
model_id: str | None = None
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class TaskFinishEvent(Event):
|
|
14
|
-
task_result: str
|
|
15
|
-
has_structured_output: bool = False
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class TurnStartEvent(Event):
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class TurnEndEvent(Event):
|
|
23
|
-
pass
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"""Metadata-related protocol events."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from klaude_code.protocol import model
|
|
6
|
-
|
|
7
|
-
from .base import Event, ResponseEvent
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class UsageEvent(ResponseEvent):
|
|
11
|
-
usage: model.Usage
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class TaskMetadataEvent(Event):
|
|
15
|
-
metadata: model.TaskMetadataItem
|
|
16
|
-
cancelled: bool = False
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from .base import ResponseEvent
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ThinkingStartEvent(ResponseEvent):
|
|
7
|
-
pass
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ThinkingDeltaEvent(ResponseEvent):
|
|
11
|
-
content: str
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class ThinkingEndEvent(ResponseEvent):
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class AssistantTextStartEvent(ResponseEvent):
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class AssistantTextDeltaEvent(ResponseEvent):
|
|
23
|
-
content: str
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class AssistantTextEndEvent(ResponseEvent):
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class AssistantImageDeltaEvent(ResponseEvent):
|
|
31
|
-
file_path: str
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class ToolCallStartEvent(ResponseEvent):
|
|
35
|
-
tool_call_id: str
|
|
36
|
-
tool_name: str
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class ResponseCompleteEvent(ResponseEvent):
|
|
40
|
-
"""Final snapshot of the model response."""
|
|
41
|
-
|
|
42
|
-
content: str
|
|
43
|
-
thinking_text: str | None = None
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from pydantic import Field
|
|
4
|
-
|
|
5
|
-
from klaude_code.protocol import llm_param
|
|
6
|
-
from klaude_code.protocol.events.chat import DeveloperMessageEvent, UserMessageEvent
|
|
7
|
-
from klaude_code.protocol.events.lifecycle import TaskFinishEvent, TaskStartEvent, TurnStartEvent
|
|
8
|
-
from klaude_code.protocol.events.metadata import TaskMetadataEvent
|
|
9
|
-
from klaude_code.protocol.events.streaming import AssistantImageDeltaEvent, ResponseCompleteEvent
|
|
10
|
-
from klaude_code.protocol.events.tools import ToolCallEvent, ToolResultEvent
|
|
11
|
-
|
|
12
|
-
from .base import Event
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class WelcomeEvent(Event):
|
|
16
|
-
work_dir: str
|
|
17
|
-
llm_config: llm_param.LLMConfigParameter
|
|
18
|
-
show_klaude_code_info: bool = True
|
|
19
|
-
loaded_skills: dict[str, list[str]] = Field(default_factory=dict)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class ErrorEvent(Event):
|
|
23
|
-
error_message: str
|
|
24
|
-
can_retry: bool = False
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class InterruptEvent(Event):
|
|
28
|
-
pass
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class EndEvent(Event):
|
|
32
|
-
"""Global display shutdown."""
|
|
33
|
-
|
|
34
|
-
session_id: str = "__app__"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
type ReplayEventUnion = (
|
|
38
|
-
TaskStartEvent
|
|
39
|
-
| TaskFinishEvent
|
|
40
|
-
| TurnStartEvent
|
|
41
|
-
| AssistantImageDeltaEvent
|
|
42
|
-
| ResponseCompleteEvent
|
|
43
|
-
| ToolCallEvent
|
|
44
|
-
| ToolResultEvent
|
|
45
|
-
| UserMessageEvent
|
|
46
|
-
| TaskMetadataEvent
|
|
47
|
-
| InterruptEvent
|
|
48
|
-
| DeveloperMessageEvent
|
|
49
|
-
| ErrorEvent
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class ReplayHistoryEvent(Event):
|
|
54
|
-
events: list[ReplayEventUnion]
|
|
55
|
-
updated_at: float
|
|
56
|
-
is_load: bool = True
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Literal
|
|
4
|
-
|
|
5
|
-
from klaude_code.protocol import model
|
|
6
|
-
|
|
7
|
-
from .base import ResponseEvent
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ToolCallEvent(ResponseEvent):
|
|
11
|
-
tool_call_id: str
|
|
12
|
-
tool_name: str
|
|
13
|
-
arguments: str
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class ToolResultEvent(ResponseEvent):
|
|
17
|
-
tool_call_id: str
|
|
18
|
-
tool_name: str
|
|
19
|
-
result: str
|
|
20
|
-
ui_extra: model.ToolResultUIExtra | None = None
|
|
21
|
-
status: Literal["success", "error", "aborted"]
|
|
22
|
-
task_metadata: model.TaskMetadata | None = None
|
|
23
|
-
is_last_in_turn: bool = True
|
|
24
|
-
|
|
25
|
-
@property
|
|
26
|
-
def is_error(self) -> bool:
|
|
27
|
-
return self.status in ("error", "aborted")
|
|
File without changes
|
|
File without changes
|