klaude-code 2.6.0__py3-none-any.whl → 2.8.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 +1 -1
- klaude_code/auth/AGENTS.md +325 -0
- klaude_code/auth/__init__.py +17 -1
- klaude_code/auth/antigravity/__init__.py +20 -0
- klaude_code/auth/antigravity/exceptions.py +17 -0
- klaude_code/auth/antigravity/oauth.py +320 -0
- klaude_code/auth/antigravity/pkce.py +25 -0
- klaude_code/auth/antigravity/token_manager.py +45 -0
- klaude_code/auth/base.py +4 -0
- klaude_code/auth/claude/oauth.py +29 -9
- klaude_code/auth/codex/exceptions.py +4 -0
- klaude_code/auth/env.py +19 -15
- klaude_code/cli/auth_cmd.py +54 -4
- klaude_code/cli/cost_cmd.py +83 -160
- klaude_code/cli/list_model.py +50 -0
- klaude_code/cli/main.py +99 -9
- klaude_code/config/assets/builtin_config.yaml +108 -0
- klaude_code/config/builtin_config.py +5 -11
- klaude_code/config/config.py +24 -10
- klaude_code/const.py +11 -1
- klaude_code/core/agent.py +5 -1
- klaude_code/core/agent_profile.py +28 -32
- klaude_code/core/compaction/AGENTS.md +112 -0
- klaude_code/core/compaction/__init__.py +11 -0
- klaude_code/core/compaction/compaction.py +707 -0
- klaude_code/core/compaction/overflow.py +30 -0
- klaude_code/core/compaction/prompts.py +97 -0
- klaude_code/core/executor.py +103 -2
- klaude_code/core/manager/llm_clients.py +5 -0
- klaude_code/core/manager/llm_clients_builder.py +14 -2
- klaude_code/core/prompts/prompt-antigravity.md +80 -0
- klaude_code/core/prompts/prompt-codex-gpt-5-2.md +335 -0
- klaude_code/core/reminders.py +11 -7
- klaude_code/core/task.py +126 -0
- klaude_code/core/tool/todo/todo_write_tool.py +1 -1
- klaude_code/core/turn.py +3 -1
- klaude_code/llm/antigravity/__init__.py +3 -0
- klaude_code/llm/antigravity/client.py +558 -0
- klaude_code/llm/antigravity/input.py +261 -0
- klaude_code/llm/registry.py +1 -0
- klaude_code/protocol/commands.py +0 -1
- klaude_code/protocol/events.py +18 -0
- klaude_code/protocol/llm_param.py +1 -0
- klaude_code/protocol/message.py +23 -1
- klaude_code/protocol/op.py +15 -1
- klaude_code/protocol/op_handler.py +5 -0
- klaude_code/session/session.py +36 -0
- klaude_code/skill/assets/create-plan/SKILL.md +6 -6
- klaude_code/skill/loader.py +12 -13
- klaude_code/skill/manager.py +3 -3
- klaude_code/tui/command/__init__.py +4 -4
- klaude_code/tui/command/compact_cmd.py +32 -0
- klaude_code/tui/command/copy_cmd.py +1 -1
- klaude_code/tui/command/fork_session_cmd.py +114 -18
- klaude_code/tui/command/model_picker.py +5 -1
- klaude_code/tui/command/thinking_cmd.py +1 -1
- klaude_code/tui/commands.py +6 -0
- klaude_code/tui/components/command_output.py +1 -1
- klaude_code/tui/components/rich/markdown.py +117 -1
- klaude_code/tui/components/rich/theme.py +18 -2
- klaude_code/tui/components/tools.py +39 -25
- klaude_code/tui/components/user_input.py +39 -28
- klaude_code/tui/input/AGENTS.md +44 -0
- klaude_code/tui/input/__init__.py +5 -2
- klaude_code/tui/input/completers.py +10 -14
- klaude_code/tui/input/drag_drop.py +146 -0
- klaude_code/tui/input/images.py +227 -0
- klaude_code/tui/input/key_bindings.py +183 -19
- klaude_code/tui/input/paste.py +71 -0
- klaude_code/tui/input/prompt_toolkit.py +32 -9
- klaude_code/tui/machine.py +26 -1
- klaude_code/tui/renderer.py +67 -4
- klaude_code/tui/runner.py +19 -3
- klaude_code/tui/terminal/image.py +103 -10
- klaude_code/tui/terminal/selector.py +81 -7
- {klaude_code-2.6.0.dist-info → klaude_code-2.8.0.dist-info}/METADATA +10 -10
- {klaude_code-2.6.0.dist-info → klaude_code-2.8.0.dist-info}/RECORD +79 -61
- klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -117
- klaude_code/tui/command/terminal_setup_cmd.py +0 -248
- klaude_code/tui/input/clipboard.py +0 -152
- {klaude_code-2.6.0.dist-info → klaude_code-2.8.0.dist-info}/WHEEL +0 -0
- {klaude_code-2.6.0.dist-info → klaude_code-2.8.0.dist-info}/entry_points.txt +0 -0
|
@@ -6,12 +6,14 @@ provider_list:
|
|
|
6
6
|
protocol: anthropic
|
|
7
7
|
api_key: ${ANTHROPIC_API_KEY}
|
|
8
8
|
model_list:
|
|
9
|
+
|
|
9
10
|
- model_name: sonnet
|
|
10
11
|
model_id: claude-sonnet-4-5-20250929
|
|
11
12
|
context_limit: 200000
|
|
12
13
|
provider_routing:
|
|
13
14
|
sort: throughput
|
|
14
15
|
cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
|
|
16
|
+
|
|
15
17
|
- model_name: opus
|
|
16
18
|
model_id: claude-opus-4-5-20251101
|
|
17
19
|
context_limit: 200000
|
|
@@ -20,10 +22,13 @@ provider_list:
|
|
|
20
22
|
type: enabled
|
|
21
23
|
budget_tokens: 2048
|
|
22
24
|
cost: {input: 5, output: 25, cache_read: 0.5, cache_write: 6.25}
|
|
25
|
+
|
|
26
|
+
|
|
23
27
|
- provider_name: openai
|
|
24
28
|
protocol: responses
|
|
25
29
|
api_key: ${OPENAI_API_KEY}
|
|
26
30
|
model_list:
|
|
31
|
+
|
|
27
32
|
- model_name: gpt-5.2-high
|
|
28
33
|
model_id: gpt-5.2
|
|
29
34
|
max_tokens: 128000
|
|
@@ -33,6 +38,7 @@ provider_list:
|
|
|
33
38
|
reasoning_effort: high
|
|
34
39
|
reasoning_summary: detailed
|
|
35
40
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
41
|
+
|
|
36
42
|
- model_name: gpt-5.2-medium
|
|
37
43
|
model_id: gpt-5.2
|
|
38
44
|
context_limit: 400000
|
|
@@ -41,6 +47,7 @@ provider_list:
|
|
|
41
47
|
reasoning_effort: medium
|
|
42
48
|
reasoning_summary: concise
|
|
43
49
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
50
|
+
|
|
44
51
|
- model_name: gpt-5.2-low
|
|
45
52
|
model_id: gpt-5.2
|
|
46
53
|
context_limit: 400000
|
|
@@ -49,6 +56,7 @@ provider_list:
|
|
|
49
56
|
reasoning_effort: low
|
|
50
57
|
reasoning_summary: concise
|
|
51
58
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
59
|
+
|
|
52
60
|
- model_name: gpt-5.2-fast
|
|
53
61
|
model_id: gpt-5.2
|
|
54
62
|
context_limit: 400000
|
|
@@ -56,6 +64,7 @@ provider_list:
|
|
|
56
64
|
thinking:
|
|
57
65
|
reasoning_effort: none
|
|
58
66
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
67
|
+
|
|
59
68
|
- model_name: gpt-5.1-codex-max
|
|
60
69
|
model_id: gpt-5.1-codex-max
|
|
61
70
|
max_tokens: 128000
|
|
@@ -64,10 +73,13 @@ provider_list:
|
|
|
64
73
|
reasoning_effort: medium
|
|
65
74
|
reasoning_summary: detailed
|
|
66
75
|
cost: {input: 1.25, output: 10, cache_read: 0.13}
|
|
76
|
+
|
|
77
|
+
|
|
67
78
|
- provider_name: openrouter
|
|
68
79
|
protocol: openrouter
|
|
69
80
|
api_key: ${OPENROUTER_API_KEY}
|
|
70
81
|
model_list:
|
|
82
|
+
|
|
71
83
|
- model_name: gpt-5.2-high
|
|
72
84
|
model_id: openai/gpt-5.2
|
|
73
85
|
max_tokens: 128000
|
|
@@ -77,6 +89,7 @@ provider_list:
|
|
|
77
89
|
reasoning_effort: high
|
|
78
90
|
reasoning_summary: detailed
|
|
79
91
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
92
|
+
|
|
80
93
|
- model_name: gpt-5.2-medium
|
|
81
94
|
model_id: openai/gpt-5.2
|
|
82
95
|
max_tokens: 128000
|
|
@@ -86,6 +99,7 @@ provider_list:
|
|
|
86
99
|
reasoning_effort: medium
|
|
87
100
|
reasoning_summary: concise
|
|
88
101
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
102
|
+
|
|
89
103
|
- model_name: kimi
|
|
90
104
|
model_id: moonshotai/kimi-k2-thinking
|
|
91
105
|
context_limit: 262144
|
|
@@ -93,16 +107,19 @@ provider_list:
|
|
|
93
107
|
only:
|
|
94
108
|
- moonshotai/turbo
|
|
95
109
|
cost: {input: 0.6, output: 2.5, cache_read: 0.15}
|
|
110
|
+
|
|
96
111
|
- model_name: haiku
|
|
97
112
|
model_id: anthropic/claude-haiku-4.5
|
|
98
113
|
context_limit: 200000
|
|
99
114
|
cost: {input: 1, output: 5, cache_read: 0.1, cache_write: 1.25}
|
|
115
|
+
|
|
100
116
|
- model_name: sonnet
|
|
101
117
|
model_id: anthropic/claude-4.5-sonnet
|
|
102
118
|
context_limit: 200000
|
|
103
119
|
provider_routing:
|
|
104
120
|
sort: throughput
|
|
105
121
|
cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
|
|
122
|
+
|
|
106
123
|
- model_name: opus
|
|
107
124
|
model_id: anthropic/claude-4.5-opus
|
|
108
125
|
context_limit: 200000
|
|
@@ -110,18 +127,21 @@ provider_list:
|
|
|
110
127
|
type: enabled
|
|
111
128
|
budget_tokens: 2048
|
|
112
129
|
cost: {input: 5, output: 25, cache_read: 0.5, cache_write: 6.25}
|
|
130
|
+
|
|
113
131
|
- model_name: gemini-pro
|
|
114
132
|
model_id: google/gemini-3-pro-preview
|
|
115
133
|
context_limit: 1048576
|
|
116
134
|
thinking:
|
|
117
135
|
reasoning_effort: high
|
|
118
136
|
cost: {input: 2, output: 12, cache_read: 0.2}
|
|
137
|
+
|
|
119
138
|
- model_name: gemini-flash
|
|
120
139
|
model_id: google/gemini-3-flash-preview
|
|
121
140
|
context_limit: 1048576
|
|
122
141
|
thinking:
|
|
123
142
|
reasoning_effort: medium
|
|
124
143
|
cost: {input: 0.5, output: 3, cache_read: 0.05}
|
|
144
|
+
|
|
125
145
|
- model_name: nano-banana-pro
|
|
126
146
|
model_id: google/gemini-3-pro-image-preview
|
|
127
147
|
context_limit: 66000
|
|
@@ -129,6 +149,7 @@ provider_list:
|
|
|
129
149
|
- image
|
|
130
150
|
- text
|
|
131
151
|
cost: {input: 2, output: 12, cache_read: 0.2, image: 120}
|
|
152
|
+
|
|
132
153
|
- model_name: nano-banana
|
|
133
154
|
model_id: google/gemini-2.5-flash-image
|
|
134
155
|
context_limit: 33000
|
|
@@ -136,6 +157,7 @@ provider_list:
|
|
|
136
157
|
- image
|
|
137
158
|
- text
|
|
138
159
|
cost: {input: 0.3, output: 2.5, cache_read: 0.03, image: 30}
|
|
160
|
+
|
|
139
161
|
- model_name: grok
|
|
140
162
|
model_id: x-ai/grok-4.1-fast
|
|
141
163
|
context_limit: 2000000
|
|
@@ -143,10 +165,12 @@ provider_list:
|
|
|
143
165
|
type: enabled
|
|
144
166
|
budget_tokens: 2048
|
|
145
167
|
cost: {input: 0.2, output: 0.5, cache_read: 0.05}
|
|
168
|
+
|
|
146
169
|
- model_name: minimax
|
|
147
170
|
model_id: minimax/minimax-m2.1
|
|
148
171
|
context_limit: 204800
|
|
149
172
|
cost: {input: 0.3, output: 1.2, cache_read: 0.03}
|
|
173
|
+
|
|
150
174
|
- model_name: glm
|
|
151
175
|
model_id: z-ai/glm-4.7
|
|
152
176
|
context_limit: 200000
|
|
@@ -154,6 +178,7 @@ provider_list:
|
|
|
154
178
|
only:
|
|
155
179
|
- z-ai
|
|
156
180
|
cost: {input: 0.44, output: 1.74, cache_read: 0.04}
|
|
181
|
+
|
|
157
182
|
- model_name: seedream
|
|
158
183
|
model_id: bytedance-seed/seedream-4.5
|
|
159
184
|
context_limit: 4000
|
|
@@ -161,6 +186,7 @@ provider_list:
|
|
|
161
186
|
modalities:
|
|
162
187
|
- image
|
|
163
188
|
- text
|
|
189
|
+
|
|
164
190
|
- model_name: flux
|
|
165
191
|
model_id: black-forest-labs/flux.2-max
|
|
166
192
|
context_limit: 47000
|
|
@@ -168,22 +194,27 @@ provider_list:
|
|
|
168
194
|
modalities:
|
|
169
195
|
- image
|
|
170
196
|
- text
|
|
197
|
+
|
|
198
|
+
|
|
171
199
|
- provider_name: google
|
|
172
200
|
protocol: google
|
|
173
201
|
api_key: ${GOOGLE_API_KEY}
|
|
174
202
|
model_list:
|
|
203
|
+
|
|
175
204
|
- model_name: gemini-pro
|
|
176
205
|
model_id: gemini-3-pro-preview
|
|
177
206
|
context_limit: 1048576
|
|
178
207
|
thinking:
|
|
179
208
|
reasoning_effort: high
|
|
180
209
|
cost: {input: 2, output: 12, cache_read: 0.2}
|
|
210
|
+
|
|
181
211
|
- model_name: gemini-flash
|
|
182
212
|
model_id: gemini-3-flash-preview
|
|
183
213
|
context_limit: 1048576
|
|
184
214
|
thinking:
|
|
185
215
|
reasoning_effort: medium
|
|
186
216
|
cost: {input: 0.5, output: 3, cache_read: 0.05}
|
|
217
|
+
|
|
187
218
|
- model_name: nano-banana-pro
|
|
188
219
|
model_id: gemini-3-pro-image-preview
|
|
189
220
|
context_limit: 66000
|
|
@@ -191,6 +222,7 @@ provider_list:
|
|
|
191
222
|
- image
|
|
192
223
|
- text
|
|
193
224
|
cost: {input: 2, output: 12, cache_read: 0.2, image: 120}
|
|
225
|
+
|
|
194
226
|
- model_name: nano-banana
|
|
195
227
|
model_id: gemini-2.5-flash-image
|
|
196
228
|
context_limit: 33000
|
|
@@ -198,21 +230,27 @@ provider_list:
|
|
|
198
230
|
- image
|
|
199
231
|
- text
|
|
200
232
|
cost: {input: 0.3, output: 2.5, cache_read: 0.03, image: 30}
|
|
233
|
+
|
|
234
|
+
|
|
201
235
|
- provider_name: bedrock
|
|
202
236
|
protocol: bedrock
|
|
203
237
|
aws_access_key: ${AWS_ACCESS_KEY_ID}
|
|
204
238
|
aws_secret_key: ${AWS_SECRET_ACCESS_KEY}
|
|
205
239
|
aws_region: ${AWS_REGION}
|
|
206
240
|
model_list:
|
|
241
|
+
|
|
207
242
|
- model_name: sonnet
|
|
208
243
|
model_id: us.anthropic.claude-sonnet-4-5-20250929-v1:0
|
|
209
244
|
context_limit: 200000
|
|
210
245
|
cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
|
|
246
|
+
|
|
247
|
+
|
|
211
248
|
- provider_name: deepseek
|
|
212
249
|
protocol: anthropic
|
|
213
250
|
api_key: ${DEEPSEEK_API_KEY}
|
|
214
251
|
base_url: https://api.deepseek.com/anthropic
|
|
215
252
|
model_list:
|
|
253
|
+
|
|
216
254
|
- model_name: deepseek
|
|
217
255
|
model_id: deepseek-reasoner
|
|
218
256
|
context_limit: 128000
|
|
@@ -220,11 +258,14 @@ provider_list:
|
|
|
220
258
|
type: enabled
|
|
221
259
|
budget_tokens: 2048
|
|
222
260
|
cost: {input: 2, output: 3, cache_read: 0.2, currency: CNY}
|
|
261
|
+
|
|
262
|
+
|
|
223
263
|
- provider_name: moonshot
|
|
224
264
|
protocol: anthropic
|
|
225
265
|
api_key: ${MOONSHOT_API_KEY}
|
|
226
266
|
base_url: https://api.moonshot.cn/anthropic
|
|
227
267
|
model_list:
|
|
268
|
+
|
|
228
269
|
- model_name: kimi
|
|
229
270
|
model_id: kimi-k2-thinking
|
|
230
271
|
context_limit: 262144
|
|
@@ -232,13 +273,17 @@ provider_list:
|
|
|
232
273
|
type: enabled
|
|
233
274
|
budget_tokens: 8192
|
|
234
275
|
cost: {input: 4, output: 16, cache_read: 1, currency: CNY}
|
|
276
|
+
|
|
277
|
+
|
|
235
278
|
- provider_name: claude-max
|
|
236
279
|
protocol: claude_oauth
|
|
237
280
|
model_list:
|
|
281
|
+
|
|
238
282
|
- model_name: sonnet
|
|
239
283
|
model_id: claude-sonnet-4-5-20250929
|
|
240
284
|
context_limit: 200000
|
|
241
285
|
cost: {input: 3, output: 15, cache_read: 0.3, cache_write: 3.75}
|
|
286
|
+
|
|
242
287
|
- model_name: opus
|
|
243
288
|
model_id: claude-opus-4-5-20251101
|
|
244
289
|
context_limit: 200000
|
|
@@ -246,17 +291,80 @@ provider_list:
|
|
|
246
291
|
type: enabled
|
|
247
292
|
budget_tokens: 2048
|
|
248
293
|
cost: {input: 5, output: 25, cache_read: 0.5, cache_write: 6.25}
|
|
294
|
+
|
|
249
295
|
- model_name: haiku
|
|
250
296
|
model_id: claude-haiku-4-5-20251001
|
|
251
297
|
context_limit: 200000
|
|
252
298
|
cost: {input: 1, output: 5, cache_read: 0.1, cache_write: 1.25}
|
|
299
|
+
|
|
300
|
+
|
|
253
301
|
- provider_name: codex
|
|
254
302
|
protocol: codex_oauth
|
|
255
303
|
model_list:
|
|
304
|
+
|
|
256
305
|
- model_name: gpt-5.2-codex
|
|
257
306
|
model_id: gpt-5.2-codex
|
|
258
307
|
thinking:
|
|
259
308
|
reasoning_effort: medium
|
|
309
|
+
reasoning_summary: auto
|
|
260
310
|
context_limit: 400000
|
|
261
311
|
max_tokens: 128000
|
|
262
312
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
313
|
+
|
|
314
|
+
- model_name: gpt-5.2-high
|
|
315
|
+
model_id: gpt-5.2
|
|
316
|
+
max_tokens: 128000
|
|
317
|
+
context_limit: 400000
|
|
318
|
+
verbosity: high
|
|
319
|
+
thinking:
|
|
320
|
+
reasoning_effort: high
|
|
321
|
+
reasoning_summary: detailed
|
|
322
|
+
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
- provider_name: antigravity
|
|
326
|
+
protocol: antigravity
|
|
327
|
+
model_list:
|
|
328
|
+
- model_name: opus
|
|
329
|
+
model_id: claude-opus-4-5-thinking
|
|
330
|
+
context_limit: 200000
|
|
331
|
+
max_tokens: 64000
|
|
332
|
+
thinking:
|
|
333
|
+
type: enabled
|
|
334
|
+
budget_tokens: 10240
|
|
335
|
+
- model_name: sonnet
|
|
336
|
+
model_id: claude-sonnet-4-5
|
|
337
|
+
context_limit: 200000
|
|
338
|
+
max_tokens: 64000
|
|
339
|
+
- model_name: sonnet-thinking
|
|
340
|
+
model_id: claude-sonnet-4-5-thinking
|
|
341
|
+
context_limit: 200000
|
|
342
|
+
max_tokens: 64000
|
|
343
|
+
thinking:
|
|
344
|
+
type: enabled
|
|
345
|
+
budget_tokens: 10240
|
|
346
|
+
- model_name: gemini-pro-high
|
|
347
|
+
model_id: gemini-3-pro-high
|
|
348
|
+
context_limit: 1048576
|
|
349
|
+
max_tokens: 65535
|
|
350
|
+
thinking:
|
|
351
|
+
reasoning_effort: high
|
|
352
|
+
- model_name: gemini-pro-low
|
|
353
|
+
model_id: gemini-3-pro-low
|
|
354
|
+
context_limit: 1048576
|
|
355
|
+
max_tokens: 65535
|
|
356
|
+
thinking:
|
|
357
|
+
reasoning_effort: low
|
|
358
|
+
- model_name: gemini-flash
|
|
359
|
+
model_id: gemini-3-flash
|
|
360
|
+
context_limit: 1048576
|
|
361
|
+
max_tokens: 65535
|
|
362
|
+
thinking:
|
|
363
|
+
reasoning_effort: medium
|
|
364
|
+
- model_name: gpt-oss
|
|
365
|
+
model_id: gpt-oss-120b-medium
|
|
366
|
+
context_limit: 131072
|
|
367
|
+
max_tokens: 32768
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
compact_model: gemini-flash
|
|
@@ -13,7 +13,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
13
13
|
import yaml
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
|
-
from klaude_code.config.config import
|
|
16
|
+
from klaude_code.config.config import Config
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
@dataclass(frozen=True)
|
|
@@ -48,16 +48,10 @@ def _load_builtin_yaml() -> dict[str, Any]:
|
|
|
48
48
|
return data
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
def
|
|
52
|
-
"""Load built-in
|
|
51
|
+
def get_builtin_config() -> "Config":
|
|
52
|
+
"""Load built-in configuration from YAML asset."""
|
|
53
53
|
# Import here to avoid circular import
|
|
54
|
-
from klaude_code.config.config import
|
|
54
|
+
from klaude_code.config.config import Config
|
|
55
55
|
|
|
56
56
|
data = _load_builtin_yaml()
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def get_builtin_sub_agent_models() -> dict[str, str]:
|
|
61
|
-
"""Load built-in sub agent model mappings from YAML asset."""
|
|
62
|
-
data = _load_builtin_yaml()
|
|
63
|
-
return data.get("sub_agent_models", {})
|
|
57
|
+
return Config.model_validate(data)
|
klaude_code/config/config.py
CHANGED
|
@@ -11,8 +11,7 @@ from pydantic import BaseModel, Field, ValidationError, model_validator
|
|
|
11
11
|
from klaude_code.auth.env import get_auth_env
|
|
12
12
|
from klaude_code.config.builtin_config import (
|
|
13
13
|
SUPPORTED_API_KEYS,
|
|
14
|
-
|
|
15
|
-
get_builtin_sub_agent_models,
|
|
14
|
+
get_builtin_config,
|
|
16
15
|
)
|
|
17
16
|
from klaude_code.log import log
|
|
18
17
|
from klaude_code.protocol import llm_param
|
|
@@ -108,6 +107,15 @@ class ProviderConfig(llm_param.LLMConfigProviderParameter):
|
|
|
108
107
|
# Consider available if logged in. Token refresh happens on-demand.
|
|
109
108
|
return state is None
|
|
110
109
|
|
|
110
|
+
if self.protocol == LLMClientProtocol.ANTIGRAVITY:
|
|
111
|
+
# Antigravity uses OAuth authentication, not API key
|
|
112
|
+
from klaude_code.auth.antigravity.token_manager import AntigravityTokenManager
|
|
113
|
+
|
|
114
|
+
token_manager = AntigravityTokenManager()
|
|
115
|
+
state = token_manager.get_state()
|
|
116
|
+
# Consider available if logged in. Token refresh happens on-demand.
|
|
117
|
+
return state is None
|
|
118
|
+
|
|
111
119
|
if self.protocol == LLMClientProtocol.BEDROCK:
|
|
112
120
|
# Bedrock uses AWS credentials, not API key. Region is always required.
|
|
113
121
|
_, resolved_profile = parse_env_var_syntax(self.aws_profile)
|
|
@@ -161,6 +169,7 @@ class UserConfig(BaseModel):
|
|
|
161
169
|
"""User configuration (what gets saved to disk)."""
|
|
162
170
|
|
|
163
171
|
main_model: str | None = None
|
|
172
|
+
compact_model: str | None = None
|
|
164
173
|
sub_agent_models: dict[str, str] = Field(default_factory=dict)
|
|
165
174
|
theme: str | None = None
|
|
166
175
|
provider_list: list[UserProviderConfig] = Field(default_factory=lambda: [])
|
|
@@ -183,6 +192,7 @@ class Config(BaseModel):
|
|
|
183
192
|
"""Merged configuration (builtin + user) for runtime use."""
|
|
184
193
|
|
|
185
194
|
main_model: str | None = None
|
|
195
|
+
compact_model: str | None = None
|
|
186
196
|
sub_agent_models: dict[str, str] = Field(default_factory=dict)
|
|
187
197
|
theme: str | None = None
|
|
188
198
|
provider_list: list[ProviderConfig] = Field(default_factory=lambda: [])
|
|
@@ -286,6 +296,7 @@ class Config(BaseModel):
|
|
|
286
296
|
not in {
|
|
287
297
|
llm_param.LLMClientProtocol.CODEX_OAUTH,
|
|
288
298
|
llm_param.LLMClientProtocol.CLAUDE_OAUTH,
|
|
299
|
+
llm_param.LLMClientProtocol.ANTIGRAVITY,
|
|
289
300
|
llm_param.LLMClientProtocol.BEDROCK,
|
|
290
301
|
}
|
|
291
302
|
and not api_key
|
|
@@ -313,6 +324,7 @@ class Config(BaseModel):
|
|
|
313
324
|
not in {
|
|
314
325
|
llm_param.LLMClientProtocol.CODEX_OAUTH,
|
|
315
326
|
llm_param.LLMClientProtocol.CLAUDE_OAUTH,
|
|
327
|
+
llm_param.LLMClientProtocol.ANTIGRAVITY,
|
|
316
328
|
llm_param.LLMClientProtocol.BEDROCK,
|
|
317
329
|
}
|
|
318
330
|
and not api_key
|
|
@@ -389,6 +401,7 @@ class Config(BaseModel):
|
|
|
389
401
|
|
|
390
402
|
# Sync user-modifiable fields from merged config to user config
|
|
391
403
|
user_config.main_model = self.main_model
|
|
404
|
+
user_config.compact_model = self.compact_model
|
|
392
405
|
user_config.sub_agent_models = self.sub_agent_models
|
|
393
406
|
user_config.theme = self.theme
|
|
394
407
|
# Note: provider_list is NOT synced - user providers are already in user_config
|
|
@@ -407,6 +420,7 @@ def get_example_config() -> UserConfig:
|
|
|
407
420
|
"""Generate example config for user reference (will be commented out)."""
|
|
408
421
|
return UserConfig(
|
|
409
422
|
main_model="opus",
|
|
423
|
+
compact_model="gemini-flash",
|
|
410
424
|
sub_agent_models={"explore": "haiku", "webagent": "sonnet", "task": "sonnet"},
|
|
411
425
|
provider_list=[
|
|
412
426
|
UserProviderConfig(
|
|
@@ -434,11 +448,7 @@ def get_example_config() -> UserConfig:
|
|
|
434
448
|
|
|
435
449
|
def _get_builtin_config() -> Config:
|
|
436
450
|
"""Load built-in provider configurations."""
|
|
437
|
-
|
|
438
|
-
# (needed for tests that may monkeypatch the class)
|
|
439
|
-
providers = [ProviderConfig.model_validate(p.model_dump()) for p in get_builtin_provider_configs()]
|
|
440
|
-
sub_agent_models = get_builtin_sub_agent_models()
|
|
441
|
-
return Config(provider_list=providers, sub_agent_models=sub_agent_models)
|
|
451
|
+
return get_builtin_config()
|
|
442
452
|
|
|
443
453
|
|
|
444
454
|
def _merge_model(builtin: ModelConfig, user: ModelConfig) -> ModelConfig:
|
|
@@ -485,7 +495,7 @@ def _merge_provider(builtin: ProviderConfig, user: UserProviderConfig) -> Provid
|
|
|
485
495
|
if value is not None:
|
|
486
496
|
merged_data[key] = value
|
|
487
497
|
|
|
488
|
-
merged_data["model_list"] =
|
|
498
|
+
merged_data["model_list"] = [m.model_dump() for m in merged_models.values()]
|
|
489
499
|
return ProviderConfig.model_validate(merged_data)
|
|
490
500
|
|
|
491
501
|
|
|
@@ -530,11 +540,14 @@ def _merge_configs(user_config: UserConfig | None, builtin_config: Config) -> Co
|
|
|
530
540
|
# Merge sub_agent_models
|
|
531
541
|
merged_sub_agent_models = {**builtin_config.sub_agent_models, **user_config.sub_agent_models}
|
|
532
542
|
|
|
543
|
+
# Re-validate providers to ensure compatibility (tests may monkeypatch the class)
|
|
544
|
+
revalidated_providers = [ProviderConfig.model_validate(p.model_dump()) for p in merged_providers.values()]
|
|
533
545
|
merged = Config(
|
|
534
546
|
main_model=user_config.main_model or builtin_config.main_model,
|
|
547
|
+
compact_model=user_config.compact_model or builtin_config.compact_model,
|
|
535
548
|
sub_agent_models=merged_sub_agent_models,
|
|
536
549
|
theme=user_config.theme or builtin_config.theme,
|
|
537
|
-
provider_list=
|
|
550
|
+
provider_list=revalidated_providers,
|
|
538
551
|
)
|
|
539
552
|
# Keep reference to user config for saving
|
|
540
553
|
merged.set_user_config(user_config)
|
|
@@ -555,7 +568,7 @@ def _load_user_config() -> UserConfig | None:
|
|
|
555
568
|
try:
|
|
556
569
|
return UserConfig.model_validate(config_dict)
|
|
557
570
|
except ValidationError as e:
|
|
558
|
-
log(f"Invalid config file: {config_path}", style="red
|
|
571
|
+
log(f"Invalid config file: {config_path}", style="red")
|
|
559
572
|
log(str(e), style="red")
|
|
560
573
|
raise ValueError(f"Invalid config file: {config_path}") from e
|
|
561
574
|
|
|
@@ -591,6 +604,7 @@ def create_example_config() -> bool:
|
|
|
591
604
|
def _load_config_uncached() -> Config:
|
|
592
605
|
"""Load and merge builtin + user config. Always returns a valid Config."""
|
|
593
606
|
builtin_config = _get_builtin_config()
|
|
607
|
+
|
|
594
608
|
user_config = _load_user_config()
|
|
595
609
|
|
|
596
610
|
return _merge_configs(user_config, builtin_config)
|
klaude_code/const.py
CHANGED
|
@@ -7,6 +7,8 @@ that were previously scattered across the codebase.
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
9
|
import os
|
|
10
|
+
import sys
|
|
11
|
+
import tempfile
|
|
10
12
|
from dataclasses import dataclass
|
|
11
13
|
from pathlib import Path
|
|
12
14
|
|
|
@@ -22,6 +24,13 @@ def _get_int_env(name: str, default: int) -> int:
|
|
|
22
24
|
return default
|
|
23
25
|
|
|
24
26
|
|
|
27
|
+
def get_system_temp() -> str:
|
|
28
|
+
"""Return system-level temp directory: /tmp on Unix, system temp on Windows."""
|
|
29
|
+
if sys.platform == "win32":
|
|
30
|
+
return tempfile.gettempdir()
|
|
31
|
+
return "/tmp"
|
|
32
|
+
|
|
33
|
+
|
|
25
34
|
# =============================================================================
|
|
26
35
|
# Agent / LLM Configuration
|
|
27
36
|
# =============================================================================
|
|
@@ -115,7 +124,7 @@ TOOL_OUTPUT_DISPLAY_TAIL = 10000 # Characters to show from the end of truncated
|
|
|
115
124
|
TOOL_OUTPUT_MAX_LINES = 2000 # Maximum lines for tool output before truncation
|
|
116
125
|
TOOL_OUTPUT_DISPLAY_HEAD_LINES = 1000 # Lines to show from the beginning of truncated output
|
|
117
126
|
TOOL_OUTPUT_DISPLAY_TAIL_LINES = 1000 # Lines to show from the end of truncated output
|
|
118
|
-
TOOL_OUTPUT_TRUNCATION_DIR =
|
|
127
|
+
TOOL_OUTPUT_TRUNCATION_DIR = get_system_temp() # Directory for saving full truncated output
|
|
119
128
|
|
|
120
129
|
|
|
121
130
|
# =============================================================================
|
|
@@ -161,6 +170,7 @@ STATUS_HINT_TEXT = " (esc to interrupt)" # Status hint text shown after spinner
|
|
|
161
170
|
STATUS_WAITING_TEXT = "Loading …"
|
|
162
171
|
STATUS_THINKING_TEXT = "Thinking …"
|
|
163
172
|
STATUS_COMPOSING_TEXT = "Composing"
|
|
173
|
+
STATUS_COMPACTING_TEXT = "Compacting"
|
|
164
174
|
|
|
165
175
|
# Backwards-compatible alias for the default spinner status text.
|
|
166
176
|
STATUS_DEFAULT_TEXT = STATUS_WAITING_TEXT
|
klaude_code/core/agent.py
CHANGED
|
@@ -18,9 +18,11 @@ class Agent:
|
|
|
18
18
|
self,
|
|
19
19
|
session: Session,
|
|
20
20
|
profile: AgentProfile,
|
|
21
|
+
compact_llm_client: LLMClientABC | None = None,
|
|
21
22
|
):
|
|
22
23
|
self.session: Session = session
|
|
23
24
|
self.profile: AgentProfile = profile
|
|
25
|
+
self.compact_llm_client: LLMClientABC | None = compact_llm_client
|
|
24
26
|
self._current_task: TaskExecutor | None = None
|
|
25
27
|
if not self.session.model_name:
|
|
26
28
|
self.session.model_name = profile.llm_client.model_name
|
|
@@ -43,18 +45,20 @@ class Agent:
|
|
|
43
45
|
) -> AsyncGenerator[events.Event]:
|
|
44
46
|
session_ctx = SessionContext(
|
|
45
47
|
session_id=self.session.id,
|
|
46
|
-
get_conversation_history=
|
|
48
|
+
get_conversation_history=self.session.get_llm_history,
|
|
47
49
|
append_history=self.session.append_history,
|
|
48
50
|
file_tracker=self.session.file_tracker,
|
|
49
51
|
todo_context=build_todo_context(self.session),
|
|
50
52
|
run_subtask=run_subtask,
|
|
51
53
|
)
|
|
52
54
|
context = TaskExecutionContext(
|
|
55
|
+
session=self.session,
|
|
53
56
|
session_ctx=session_ctx,
|
|
54
57
|
profile=self.profile,
|
|
55
58
|
tool_registry=get_registry(),
|
|
56
59
|
process_reminder=self._process_reminder,
|
|
57
60
|
sub_agent_state=self.session.sub_agent_state,
|
|
61
|
+
compact_llm_client=self.compact_llm_client,
|
|
58
62
|
)
|
|
59
63
|
|
|
60
64
|
task = TaskExecutor(context)
|
|
@@ -12,6 +12,7 @@ from typing import TYPE_CHECKING, Any, Protocol
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from klaude_code.config.config import Config
|
|
14
14
|
|
|
15
|
+
from klaude_code.auth.codex.exceptions import CodexUnsupportedModelError
|
|
15
16
|
from klaude_code.config.sub_agent_model_helper import SubAgentModelHelper
|
|
16
17
|
from klaude_code.core.reminders import (
|
|
17
18
|
at_file_reader_reminder,
|
|
@@ -53,15 +54,15 @@ COMMAND_DESCRIPTIONS: dict[str, str] = {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
|
|
56
|
-
#
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"main_gpt_5_2_codex": "prompts/prompt-codex-gpt-5-2-codex.md",
|
|
61
|
-
"main": "prompts/prompt-claude-code.md",
|
|
62
|
-
"main_gemini": "prompts/prompt-gemini.md", # https://ai.google.dev/gemini-api/docs/prompting-strategies?hl=zh-cn#agentic-si-template
|
|
57
|
+
# Prompts for codex_oauth protocol - must be used exactly as-is without any additions.
|
|
58
|
+
CODEX_OAUTH_PROMPTS: dict[str, str] = {
|
|
59
|
+
"gpt-5.2-codex": "prompts/prompt-codex-gpt-5-2-codex.md",
|
|
60
|
+
"gpt-5.2": "prompts/prompt-codex-gpt-5-2.md",
|
|
63
61
|
}
|
|
64
62
|
|
|
63
|
+
# Prompt for antigravity protocol - used exactly as-is without any additions.
|
|
64
|
+
ANTIGRAVITY_PROMPT_PATH = "prompts/prompt-antigravity.md"
|
|
65
|
+
|
|
65
66
|
|
|
66
67
|
STRUCTURED_OUTPUT_PROMPT_FOR_SUB_AGENT = """\
|
|
67
68
|
|
|
@@ -93,31 +94,20 @@ def _load_prompt_by_path(prompt_path: str) -> str:
|
|
|
93
94
|
return files(__package__).joinpath(prompt_path).read_text(encoding="utf-8").strip()
|
|
94
95
|
|
|
95
96
|
|
|
96
|
-
def
|
|
97
|
-
"""Load
|
|
98
|
-
|
|
99
|
-
try:
|
|
100
|
-
prompt_path = PROMPT_FILES[file_key]
|
|
101
|
-
except KeyError as exc:
|
|
102
|
-
raise ValueError(f"Unknown prompt key: {file_key}") from exc
|
|
103
|
-
|
|
104
|
-
return _load_prompt_by_path(prompt_path)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def _get_file_key(model_name: str, protocol: llm_param.LLMClientProtocol) -> str:
|
|
108
|
-
"""Determine which prompt file to use based on model."""
|
|
97
|
+
def _load_prompt_by_model(model_name: str) -> str:
|
|
98
|
+
"""Load base prompt content based on model name."""
|
|
109
99
|
|
|
110
100
|
match model_name:
|
|
111
101
|
case name if "gpt-5.2-codex" in name:
|
|
112
|
-
return "
|
|
113
|
-
case name if "gpt-5.
|
|
114
|
-
return "
|
|
102
|
+
return _load_prompt_by_path("prompts/prompt-codex-gpt-5-2-codex.md")
|
|
103
|
+
case name if "gpt-5.2" in name:
|
|
104
|
+
return _load_prompt_by_path("prompts/prompt-codex-gpt-5-2.md")
|
|
115
105
|
case name if "gpt-5" in name:
|
|
116
|
-
return "
|
|
106
|
+
return _load_prompt_by_path("prompts/prompt-codex.md")
|
|
117
107
|
case name if "gemini" in name:
|
|
118
|
-
return "
|
|
108
|
+
return _load_prompt_by_path("prompts/prompt-gemini.md")
|
|
119
109
|
case _:
|
|
120
|
-
return "
|
|
110
|
+
return _load_prompt_by_path("prompts/prompt-claude-code.md")
|
|
121
111
|
|
|
122
112
|
|
|
123
113
|
def _build_env_info(model_name: str) -> str:
|
|
@@ -175,16 +165,22 @@ def load_system_prompt(
|
|
|
175
165
|
) -> str:
|
|
176
166
|
"""Get system prompt content for the given model and sub-agent type."""
|
|
177
167
|
|
|
168
|
+
# For codex_oauth protocol, use exact prompts without any additions.
|
|
169
|
+
if protocol == llm_param.LLMClientProtocol.CODEX_OAUTH:
|
|
170
|
+
for model_key, prompt_path in CODEX_OAUTH_PROMPTS.items():
|
|
171
|
+
if model_key in model_name:
|
|
172
|
+
return _load_prompt_by_path(prompt_path)
|
|
173
|
+
raise CodexUnsupportedModelError(f"codex_oauth protocol does not support model: {model_name}")
|
|
174
|
+
|
|
175
|
+
# For antigravity protocol, use exact prompt without any additions.
|
|
176
|
+
if protocol == llm_param.LLMClientProtocol.ANTIGRAVITY:
|
|
177
|
+
return _load_prompt_by_path(ANTIGRAVITY_PROMPT_PATH)
|
|
178
|
+
|
|
178
179
|
if sub_agent_type is not None:
|
|
179
180
|
profile = get_sub_agent_profile(sub_agent_type)
|
|
180
181
|
base_prompt = _load_prompt_by_path(profile.prompt_file)
|
|
181
182
|
else:
|
|
182
|
-
|
|
183
|
-
base_prompt = _load_base_prompt(file_key)
|
|
184
|
-
|
|
185
|
-
if protocol == llm_param.LLMClientProtocol.CODEX_OAUTH:
|
|
186
|
-
# Do not append environment info or skills info for Codex protocol.
|
|
187
|
-
return base_prompt
|
|
183
|
+
base_prompt = _load_prompt_by_model(model_name)
|
|
188
184
|
|
|
189
185
|
skills_prompt = ""
|
|
190
186
|
sub_agent_prompt = ""
|