klaude-code 1.2.1__py3-none-any.whl → 1.2.3__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/cli/main.py +9 -4
- klaude_code/cli/runtime.py +42 -43
- klaude_code/command/__init__.py +7 -5
- klaude_code/command/clear_cmd.py +6 -29
- klaude_code/command/command_abc.py +44 -8
- klaude_code/command/diff_cmd.py +33 -27
- klaude_code/command/export_cmd.py +18 -26
- klaude_code/command/help_cmd.py +10 -8
- klaude_code/command/model_cmd.py +11 -40
- klaude_code/command/{prompt-update-dev-doc.md → prompt-dev-docs-update.md} +3 -2
- klaude_code/command/{prompt-dev-doc.md → prompt-dev-docs.md} +3 -2
- klaude_code/command/prompt-init.md +2 -5
- klaude_code/command/prompt_command.py +6 -6
- klaude_code/command/refresh_cmd.py +4 -5
- klaude_code/command/registry.py +16 -19
- klaude_code/command/terminal_setup_cmd.py +12 -11
- klaude_code/config/__init__.py +4 -0
- klaude_code/config/config.py +25 -26
- klaude_code/config/list_model.py +8 -3
- klaude_code/config/select_model.py +1 -1
- klaude_code/const/__init__.py +1 -1
- klaude_code/core/__init__.py +0 -3
- klaude_code/core/agent.py +25 -50
- klaude_code/core/executor.py +268 -101
- klaude_code/core/prompt.py +12 -12
- klaude_code/core/{prompt → prompts}/prompt-gemini.md +1 -1
- klaude_code/core/reminders.py +76 -95
- klaude_code/core/task.py +21 -14
- klaude_code/core/tool/__init__.py +45 -11
- klaude_code/core/tool/file/apply_patch.py +5 -1
- klaude_code/core/tool/file/apply_patch_tool.py +11 -13
- klaude_code/core/tool/file/edit_tool.py +27 -23
- klaude_code/core/tool/file/multi_edit_tool.py +15 -17
- klaude_code/core/tool/file/read_tool.py +41 -36
- klaude_code/core/tool/file/write_tool.py +13 -15
- klaude_code/core/tool/memory/memory_tool.py +85 -68
- klaude_code/core/tool/memory/skill_tool.py +10 -12
- klaude_code/core/tool/shell/bash_tool.py +24 -22
- klaude_code/core/tool/shell/command_safety.py +12 -1
- klaude_code/core/tool/sub_agent_tool.py +11 -12
- klaude_code/core/tool/todo/todo_write_tool.py +21 -28
- klaude_code/core/tool/todo/update_plan_tool.py +14 -24
- klaude_code/core/tool/tool_abc.py +3 -4
- klaude_code/core/tool/tool_context.py +7 -7
- klaude_code/core/tool/tool_registry.py +30 -47
- klaude_code/core/tool/tool_runner.py +35 -43
- klaude_code/core/tool/truncation.py +14 -20
- klaude_code/core/tool/web/mermaid_tool.py +12 -14
- klaude_code/core/tool/web/web_fetch_tool.py +15 -17
- klaude_code/core/turn.py +19 -7
- klaude_code/llm/__init__.py +3 -4
- klaude_code/llm/anthropic/client.py +30 -46
- klaude_code/llm/anthropic/input.py +4 -11
- klaude_code/llm/client.py +29 -8
- klaude_code/llm/input_common.py +66 -36
- klaude_code/llm/openai_compatible/client.py +42 -84
- klaude_code/llm/openai_compatible/input.py +11 -16
- klaude_code/llm/openai_compatible/tool_call_accumulator.py +2 -2
- klaude_code/llm/openrouter/client.py +40 -289
- klaude_code/llm/openrouter/input.py +13 -35
- klaude_code/llm/openrouter/reasoning_handler.py +209 -0
- klaude_code/llm/registry.py +5 -75
- klaude_code/llm/responses/client.py +34 -55
- klaude_code/llm/responses/input.py +24 -26
- klaude_code/llm/usage.py +109 -0
- klaude_code/protocol/__init__.py +4 -0
- klaude_code/protocol/events.py +3 -2
- klaude_code/protocol/{llm_parameter.py → llm_param.py} +12 -32
- klaude_code/protocol/model.py +49 -4
- klaude_code/protocol/op.py +18 -16
- klaude_code/protocol/op_handler.py +28 -0
- klaude_code/{core → protocol}/sub_agent.py +7 -0
- klaude_code/session/export.py +150 -70
- klaude_code/session/session.py +28 -14
- klaude_code/session/templates/export_session.html +180 -42
- klaude_code/trace/__init__.py +2 -2
- klaude_code/trace/log.py +11 -5
- klaude_code/ui/__init__.py +91 -8
- klaude_code/ui/core/__init__.py +1 -0
- klaude_code/ui/core/display.py +103 -0
- klaude_code/ui/core/input.py +71 -0
- klaude_code/ui/modes/__init__.py +1 -0
- klaude_code/ui/modes/debug/__init__.py +1 -0
- klaude_code/ui/{base/debug_event_display.py → modes/debug/display.py} +9 -5
- klaude_code/ui/modes/exec/__init__.py +1 -0
- klaude_code/ui/{base/exec_display.py → modes/exec/display.py} +28 -2
- klaude_code/ui/{repl → modes/repl}/__init__.py +5 -6
- klaude_code/ui/modes/repl/clipboard.py +152 -0
- klaude_code/ui/modes/repl/completers.py +429 -0
- klaude_code/ui/modes/repl/display.py +60 -0
- klaude_code/ui/modes/repl/event_handler.py +375 -0
- klaude_code/ui/modes/repl/input_prompt_toolkit.py +198 -0
- klaude_code/ui/modes/repl/key_bindings.py +170 -0
- klaude_code/ui/{repl → modes/repl}/renderer.py +109 -132
- klaude_code/ui/renderers/assistant.py +21 -0
- klaude_code/ui/renderers/common.py +0 -16
- klaude_code/ui/renderers/developer.py +18 -18
- klaude_code/ui/renderers/diffs.py +36 -14
- klaude_code/ui/renderers/errors.py +1 -1
- klaude_code/ui/renderers/metadata.py +50 -27
- klaude_code/ui/renderers/sub_agent.py +43 -9
- klaude_code/ui/renderers/thinking.py +33 -1
- klaude_code/ui/renderers/tools.py +212 -20
- klaude_code/ui/renderers/user_input.py +19 -23
- klaude_code/ui/rich/__init__.py +1 -0
- klaude_code/ui/{rich_ext → rich}/searchable_text.py +3 -1
- klaude_code/ui/{renderers → rich}/status.py +29 -18
- klaude_code/ui/{base → rich}/theme.py +8 -2
- klaude_code/ui/terminal/__init__.py +1 -0
- klaude_code/ui/{base/terminal_color.py → terminal/color.py} +4 -1
- klaude_code/ui/{base/terminal_control.py → terminal/control.py} +1 -0
- klaude_code/ui/{base/terminal_notifier.py → terminal/notifier.py} +5 -2
- klaude_code/ui/utils/__init__.py +1 -0
- klaude_code/ui/{base/utils.py → utils/common.py} +35 -3
- {klaude_code-1.2.1.dist-info → klaude_code-1.2.3.dist-info}/METADATA +1 -1
- klaude_code-1.2.3.dist-info/RECORD +161 -0
- klaude_code/core/clipboard_manifest.py +0 -124
- klaude_code/llm/openrouter/tool_call_accumulator.py +0 -80
- klaude_code/ui/base/__init__.py +0 -1
- klaude_code/ui/base/display_abc.py +0 -36
- klaude_code/ui/base/input_abc.py +0 -20
- klaude_code/ui/repl/display.py +0 -36
- klaude_code/ui/repl/event_handler.py +0 -247
- klaude_code/ui/repl/input.py +0 -773
- klaude_code/ui/rich_ext/__init__.py +0 -1
- klaude_code-1.2.1.dist-info/RECORD +0 -151
- /klaude_code/core/{prompt → prompts}/prompt-claude-code.md +0 -0
- /klaude_code/core/{prompt → prompts}/prompt-codex.md +0 -0
- /klaude_code/core/{prompt → prompts}/prompt-subagent-explore.md +0 -0
- /klaude_code/core/{prompt → prompts}/prompt-subagent-oracle.md +0 -0
- /klaude_code/core/{prompt → prompts}/prompt-subagent-webfetch.md +0 -0
- /klaude_code/core/{prompt → prompts}/prompt-subagent.md +0 -0
- /klaude_code/ui/{base → core}/stage_manager.py +0 -0
- /klaude_code/ui/{rich_ext → rich}/live.py +0 -0
- /klaude_code/ui/{rich_ext → rich}/markdown.py +0 -0
- /klaude_code/ui/{rich_ext → rich}/quote.py +0 -0
- /klaude_code/ui/{base → terminal}/progress_bar.py +0 -0
- /klaude_code/ui/{base → utils}/debouncer.py +0 -0
- {klaude_code-1.2.1.dist-info → klaude_code-1.2.3.dist-info}/WHEEL +0 -0
- {klaude_code-1.2.1.dist-info → klaude_code-1.2.3.dist-info}/entry_points.txt +0 -0
|
@@ -1,49 +1,24 @@
|
|
|
1
1
|
import json
|
|
2
|
-
import time
|
|
3
2
|
from collections.abc import AsyncGenerator
|
|
4
|
-
from typing import
|
|
3
|
+
from typing import Literal, override
|
|
5
4
|
|
|
6
5
|
import httpx
|
|
7
6
|
import openai
|
|
8
7
|
from openai import APIError, RateLimitError
|
|
9
8
|
|
|
10
|
-
from klaude_code.llm.client import LLMClientABC
|
|
9
|
+
from klaude_code.llm.client import LLMClientABC, call_with_logged_payload
|
|
10
|
+
from klaude_code.llm.input_common import apply_config_defaults
|
|
11
11
|
from klaude_code.llm.openai_compatible.input import convert_history_to_input, convert_tool_schema
|
|
12
12
|
from klaude_code.llm.openai_compatible.tool_call_accumulator import BasicToolCallAccumulator, ToolCallAccumulatorABC
|
|
13
13
|
from klaude_code.llm.registry import register
|
|
14
|
-
from klaude_code.
|
|
15
|
-
from klaude_code.protocol
|
|
16
|
-
LLMCallParameter,
|
|
17
|
-
LLMClientProtocol,
|
|
18
|
-
LLMConfigParameter,
|
|
19
|
-
apply_config_defaults,
|
|
20
|
-
)
|
|
21
|
-
from klaude_code.protocol.model import StreamErrorItem
|
|
14
|
+
from klaude_code.llm.usage import MetadataTracker, convert_usage
|
|
15
|
+
from klaude_code.protocol import llm_param, model
|
|
22
16
|
from klaude_code.trace import DebugType, log_debug
|
|
23
17
|
|
|
24
|
-
P = ParamSpec("P")
|
|
25
|
-
R = TypeVar("R")
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
def call_with_logged_payload(func: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R:
|
|
29
|
-
"""Call an SDK function while logging the JSON payload.
|
|
30
|
-
|
|
31
|
-
The function reuses the original callable's type signature via ParamSpec
|
|
32
|
-
so static type checkers can validate arguments at the call site.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
payload = {k: v for k, v in kwargs.items() if v is not None}
|
|
36
|
-
log_debug(
|
|
37
|
-
json.dumps(payload, ensure_ascii=False, default=str),
|
|
38
|
-
style="yellow",
|
|
39
|
-
debug_type=DebugType.LLM_PAYLOAD,
|
|
40
|
-
)
|
|
41
|
-
return func(*args, **kwargs)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@register(LLMClientProtocol.OPENAI)
|
|
19
|
+
@register(llm_param.LLMClientProtocol.OPENAI)
|
|
45
20
|
class OpenAICompatibleClient(LLMClientABC):
|
|
46
|
-
def __init__(self, config: LLMConfigParameter):
|
|
21
|
+
def __init__(self, config: llm_param.LLMConfigParameter):
|
|
47
22
|
super().__init__(config)
|
|
48
23
|
if config.is_azure:
|
|
49
24
|
if not config.base_url:
|
|
@@ -64,18 +39,16 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
64
39
|
|
|
65
40
|
@classmethod
|
|
66
41
|
@override
|
|
67
|
-
def create(cls, config: LLMConfigParameter) -> "LLMClientABC":
|
|
42
|
+
def create(cls, config: llm_param.LLMConfigParameter) -> "LLMClientABC":
|
|
68
43
|
return cls(config)
|
|
69
44
|
|
|
70
45
|
@override
|
|
71
|
-
async def call(self, param: LLMCallParameter) -> AsyncGenerator[model.ConversationItem, None]:
|
|
46
|
+
async def call(self, param: llm_param.LLMCallParameter) -> AsyncGenerator[model.ConversationItem, None]:
|
|
72
47
|
param = apply_config_defaults(param, self.get_llm_config())
|
|
73
48
|
messages = convert_history_to_input(param.input, param.system, param.model)
|
|
74
49
|
tools = convert_tool_schema(param.tools)
|
|
75
50
|
|
|
76
|
-
|
|
77
|
-
first_token_time: float | None = None
|
|
78
|
-
last_token_time: float | None = None
|
|
51
|
+
metadata_tracker = MetadataTracker(cost_config=self._config.cost)
|
|
79
52
|
|
|
80
53
|
extra_body = {}
|
|
81
54
|
extra_headers = {"extra": json.dumps({"session_id": param.session_id})}
|
|
@@ -105,8 +78,8 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
105
78
|
accumulated_reasoning: list[str] = []
|
|
106
79
|
accumulated_content: list[str] = []
|
|
107
80
|
accumulated_tool_calls: ToolCallAccumulatorABC = BasicToolCallAccumulator()
|
|
81
|
+
emitted_tool_start_indices: set[int] = set()
|
|
108
82
|
response_id: str | None = None
|
|
109
|
-
metadata_item = model.ResponseMetadataItem()
|
|
110
83
|
|
|
111
84
|
def flush_reasoning_items() -> list[model.ConversationItem]:
|
|
112
85
|
nonlocal accumulated_reasoning
|
|
@@ -140,17 +113,23 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
140
113
|
|
|
141
114
|
try:
|
|
142
115
|
async for event in await stream:
|
|
143
|
-
log_debug(
|
|
116
|
+
log_debug(
|
|
117
|
+
event.model_dump_json(exclude_none=True),
|
|
118
|
+
style="blue",
|
|
119
|
+
debug_type=DebugType.LLM_STREAM,
|
|
120
|
+
)
|
|
144
121
|
if not response_id and event.id:
|
|
145
122
|
response_id = event.id
|
|
146
123
|
accumulated_tool_calls.response_id = response_id
|
|
147
124
|
yield model.StartItem(response_id=response_id)
|
|
148
|
-
if
|
|
149
|
-
|
|
125
|
+
if (
|
|
126
|
+
event.usage is not None and event.usage.completion_tokens is not None # pyright: ignore[reportUnnecessaryComparison] gcp gemini will return None usage field
|
|
127
|
+
):
|
|
128
|
+
metadata_tracker.set_usage(convert_usage(event.usage, param.context_limit))
|
|
150
129
|
if event.model:
|
|
151
|
-
|
|
130
|
+
metadata_tracker.set_model_name(event.model)
|
|
152
131
|
if provider := getattr(event, "provider", None):
|
|
153
|
-
|
|
132
|
+
metadata_tracker.set_provider(str(provider))
|
|
154
133
|
|
|
155
134
|
if len(event.choices) == 0:
|
|
156
135
|
continue
|
|
@@ -158,9 +137,11 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
158
137
|
|
|
159
138
|
# Support Kimi K2's usage field in choice
|
|
160
139
|
if hasattr(event.choices[0], "usage") and getattr(event.choices[0], "usage"):
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
140
|
+
metadata_tracker.set_usage(
|
|
141
|
+
convert_usage(
|
|
142
|
+
openai.types.CompletionUsage.model_validate(getattr(event.choices[0], "usage")),
|
|
143
|
+
param.context_limit,
|
|
144
|
+
)
|
|
164
145
|
)
|
|
165
146
|
|
|
166
147
|
# Reasoning
|
|
@@ -170,9 +151,7 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
170
151
|
if hasattr(delta, "reasoning_content") and getattr(delta, "reasoning_content"):
|
|
171
152
|
reasoning_content = getattr(delta, "reasoning_content")
|
|
172
153
|
if reasoning_content:
|
|
173
|
-
|
|
174
|
-
first_token_time = time.time()
|
|
175
|
-
last_token_time = time.time()
|
|
154
|
+
metadata_tracker.record_token()
|
|
176
155
|
stage = "reasoning"
|
|
177
156
|
accumulated_reasoning.append(reasoning_content)
|
|
178
157
|
|
|
@@ -180,9 +159,7 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
180
159
|
if delta.content and (
|
|
181
160
|
stage == "assistant" or delta.content.strip()
|
|
182
161
|
): # Process all content in assistant stage, filter empty content in reasoning stage
|
|
183
|
-
|
|
184
|
-
first_token_time = time.time()
|
|
185
|
-
last_token_time = time.time()
|
|
162
|
+
metadata_tracker.record_token()
|
|
186
163
|
if stage == "reasoning":
|
|
187
164
|
for item in flush_reasoning_items():
|
|
188
165
|
yield item
|
|
@@ -198,9 +175,7 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
198
175
|
|
|
199
176
|
# Tool
|
|
200
177
|
if delta.tool_calls and len(delta.tool_calls) > 0:
|
|
201
|
-
|
|
202
|
-
first_token_time = time.time()
|
|
203
|
-
last_token_time = time.time()
|
|
178
|
+
metadata_tracker.record_token()
|
|
204
179
|
if stage == "reasoning":
|
|
205
180
|
for item in flush_reasoning_items():
|
|
206
181
|
yield item
|
|
@@ -208,9 +183,18 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
208
183
|
for item in flush_assistant_items():
|
|
209
184
|
yield item
|
|
210
185
|
stage = "tool"
|
|
186
|
+
# Emit ToolCallStartItem for new tool calls
|
|
187
|
+
for tc in delta.tool_calls:
|
|
188
|
+
if tc.index not in emitted_tool_start_indices and tc.function and tc.function.name:
|
|
189
|
+
emitted_tool_start_indices.add(tc.index)
|
|
190
|
+
yield model.ToolCallStartItem(
|
|
191
|
+
response_id=response_id,
|
|
192
|
+
call_id=tc.id or "",
|
|
193
|
+
name=tc.function.name,
|
|
194
|
+
)
|
|
211
195
|
accumulated_tool_calls.add(delta.tool_calls)
|
|
212
196
|
except (RateLimitError, APIError) as e:
|
|
213
|
-
yield StreamErrorItem(error=f"{e.__class__.__name__} {str(e)}")
|
|
197
|
+
yield model.StreamErrorItem(error=f"{e.__class__.__name__} {str(e)}")
|
|
214
198
|
|
|
215
199
|
# Finalize
|
|
216
200
|
for item in flush_reasoning_items():
|
|
@@ -223,31 +207,5 @@ class OpenAICompatibleClient(LLMClientABC):
|
|
|
223
207
|
for tool_call_item in flush_tool_call_items():
|
|
224
208
|
yield tool_call_item
|
|
225
209
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
# Calculate performance metrics if we have timing data
|
|
229
|
-
if metadata_item.usage and first_token_time is not None:
|
|
230
|
-
metadata_item.usage.first_token_latency_ms = (first_token_time - request_start_time) * 1000
|
|
231
|
-
|
|
232
|
-
if last_token_time is not None and metadata_item.usage.output_tokens > 0:
|
|
233
|
-
time_duration = last_token_time - first_token_time
|
|
234
|
-
if time_duration >= 0.15:
|
|
235
|
-
metadata_item.usage.throughput_tps = metadata_item.usage.output_tokens / time_duration
|
|
236
|
-
|
|
237
|
-
yield metadata_item
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
def convert_usage(usage: openai.types.CompletionUsage, context_limit: int | None = None) -> model.Usage:
|
|
241
|
-
total_tokens = usage.total_tokens
|
|
242
|
-
context_usage_percent = (total_tokens / context_limit) * 100 if context_limit else None
|
|
243
|
-
return model.Usage(
|
|
244
|
-
input_tokens=usage.prompt_tokens,
|
|
245
|
-
cached_tokens=(usage.prompt_tokens_details.cached_tokens if usage.prompt_tokens_details else 0) or 0,
|
|
246
|
-
reasoning_tokens=(usage.completion_tokens_details.reasoning_tokens if usage.completion_tokens_details else 0)
|
|
247
|
-
or 0,
|
|
248
|
-
output_tokens=usage.completion_tokens,
|
|
249
|
-
total_tokens=total_tokens,
|
|
250
|
-
context_usage_percent=context_usage_percent,
|
|
251
|
-
throughput_tps=None,
|
|
252
|
-
first_token_latency_ms=None,
|
|
253
|
-
)
|
|
210
|
+
metadata_tracker.set_response_id(response_id)
|
|
211
|
+
yield metadata_tracker.finalize()
|
|
@@ -6,15 +6,8 @@
|
|
|
6
6
|
from openai.types import chat
|
|
7
7
|
from openai.types.chat import ChatCompletionContentPartParam
|
|
8
8
|
|
|
9
|
-
from klaude_code.llm.input_common import
|
|
10
|
-
|
|
11
|
-
ToolGroup,
|
|
12
|
-
UserGroup,
|
|
13
|
-
merge_reminder_text,
|
|
14
|
-
parse_message_groups,
|
|
15
|
-
)
|
|
16
|
-
from klaude_code.protocol.llm_parameter import ToolSchema
|
|
17
|
-
from klaude_code.protocol.model import ConversationItem, ImageURLPart
|
|
9
|
+
from klaude_code.llm.input_common import AssistantGroup, ToolGroup, UserGroup, merge_reminder_text, parse_message_groups
|
|
10
|
+
from klaude_code.protocol import llm_param, model
|
|
18
11
|
|
|
19
12
|
|
|
20
13
|
def _user_group_to_message(group: UserGroup) -> chat.ChatCompletionMessageParam:
|
|
@@ -39,7 +32,9 @@ def _tool_group_to_message(group: ToolGroup) -> chat.ChatCompletionMessageParam:
|
|
|
39
32
|
}
|
|
40
33
|
|
|
41
34
|
|
|
42
|
-
def _assistant_group_to_message(
|
|
35
|
+
def _assistant_group_to_message(
|
|
36
|
+
group: AssistantGroup,
|
|
37
|
+
) -> chat.ChatCompletionMessageParam:
|
|
43
38
|
assistant_message: dict[str, object] = {"role": "assistant"}
|
|
44
39
|
|
|
45
40
|
if group.text_content:
|
|
@@ -61,13 +56,15 @@ def _assistant_group_to_message(group: AssistantGroup) -> chat.ChatCompletionMes
|
|
|
61
56
|
return assistant_message
|
|
62
57
|
|
|
63
58
|
|
|
64
|
-
def build_user_content_parts(
|
|
59
|
+
def build_user_content_parts(
|
|
60
|
+
images: list[model.ImageURLPart],
|
|
61
|
+
) -> list[ChatCompletionContentPartParam]:
|
|
65
62
|
"""Build content parts for images only. Used by OpenRouter."""
|
|
66
63
|
return [{"type": "image_url", "image_url": {"url": image.image_url.url}} for image in images]
|
|
67
64
|
|
|
68
65
|
|
|
69
66
|
def convert_history_to_input(
|
|
70
|
-
history: list[ConversationItem],
|
|
67
|
+
history: list[model.ConversationItem],
|
|
71
68
|
system: str | None = None,
|
|
72
69
|
model_name: str | None = None,
|
|
73
70
|
) -> list[chat.ChatCompletionMessageParam]:
|
|
@@ -79,9 +76,7 @@ def convert_history_to_input(
|
|
|
79
76
|
system: System message.
|
|
80
77
|
model_name: Model name. Not used in OpenAI-compatible, kept for API consistency.
|
|
81
78
|
"""
|
|
82
|
-
messages: list[chat.ChatCompletionMessageParam] =
|
|
83
|
-
[{"role": "system", "content": system}] if system else []
|
|
84
|
-
)
|
|
79
|
+
messages: list[chat.ChatCompletionMessageParam] = [{"role": "system", "content": system}] if system else []
|
|
85
80
|
|
|
86
81
|
for group in parse_message_groups(history):
|
|
87
82
|
match group:
|
|
@@ -96,7 +91,7 @@ def convert_history_to_input(
|
|
|
96
91
|
|
|
97
92
|
|
|
98
93
|
def convert_tool_schema(
|
|
99
|
-
tools: list[ToolSchema] | None,
|
|
94
|
+
tools: list[llm_param.ToolSchema] | None,
|
|
100
95
|
) -> list[chat.ChatCompletionToolParam]:
|
|
101
96
|
if tools is None:
|
|
102
97
|
return []
|
|
@@ -8,7 +8,7 @@ from klaude_code.protocol import model
|
|
|
8
8
|
|
|
9
9
|
class ToolCallAccumulatorABC(ABC):
|
|
10
10
|
@abstractmethod
|
|
11
|
-
def add(self, chunks: list[ChoiceDeltaToolCall]):
|
|
11
|
+
def add(self, chunks: list[ChoiceDeltaToolCall]) -> None:
|
|
12
12
|
pass
|
|
13
13
|
|
|
14
14
|
@abstractmethod
|
|
@@ -50,7 +50,7 @@ class BasicToolCallAccumulator(ToolCallAccumulatorABC, BaseModel):
|
|
|
50
50
|
chunks_by_step: list[list[ChoiceDeltaToolCall]] = Field(default_factory=list) # pyright: ignore[reportUnknownVariableType]
|
|
51
51
|
response_id: str | None = None
|
|
52
52
|
|
|
53
|
-
def add(self, chunks: list[ChoiceDeltaToolCall]):
|
|
53
|
+
def add(self, chunks: list[ChoiceDeltaToolCall]) -> None:
|
|
54
54
|
self.chunks_by_step.append(chunks)
|
|
55
55
|
|
|
56
56
|
def get(self) -> list[model.ToolCallItem]:
|