Skip to content

Commit bf1aa4c

Browse files
committed
Add settings
1 parent 543b68f commit bf1aa4c

File tree

2 files changed

+55
-13
lines changed

2 files changed

+55
-13
lines changed

src/api/providers/anthropic.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
3333
let stream: AnthropicStream<Anthropic.Messages.RawMessageStreamEvent>
3434
const cacheControl: CacheControlEphemeral = { type: "ephemeral" }
3535
const modelId = this.getModel().id
36+
const maxTokens = this.getModel().info.maxTokens || 8192
37+
let temperature = this.options.modelTemperature ?? ANTHROPIC_DEFAULT_TEMPERATURE
3638
let thinking: BetaThinkingConfigParam | undefined = undefined
3739

3840
if (THINKING_MODELS.includes(modelId)) {
3941
thinking = this.options.anthropicThinking
4042
? { type: "enabled", budget_tokens: this.options.anthropicThinking }
4143
: { type: "disabled" }
44+
45+
temperature = 1.0
4246
}
4347

4448
switch (modelId) {
@@ -62,22 +66,18 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
6266
stream = await this.client.messages.create(
6367
{
6468
model: modelId,
65-
max_tokens: this.getModel().info.maxTokens || 8192,
66-
temperature: this.options.modelTemperature ?? ANTHROPIC_DEFAULT_TEMPERATURE,
67-
system: [{ text: systemPrompt, type: "text", cache_control: { type: "ephemeral" } }], // setting cache breakpoint for system prompt so new tasks can reuse it
69+
max_tokens: maxTokens,
70+
temperature,
71+
thinking,
72+
// Setting cache breakpoint for system prompt so new tasks can reuse it.
73+
system: [{ text: systemPrompt, type: "text", cache_control: cacheControl }],
6874
messages: messages.map((message, index) => {
6975
if (index === lastUserMsgIndex || index === secondLastMsgUserIndex) {
7076
return {
7177
...message,
7278
content:
7379
typeof message.content === "string"
74-
? [
75-
{
76-
type: "text",
77-
text: message.content,
78-
cache_control: cacheControl,
79-
},
80-
]
80+
? [{ type: "text", text: message.content, cache_control: cacheControl }]
8181
: message.content.map((content, contentIndex) =>
8282
contentIndex === message.content.length - 1
8383
? { ...content, cache_control: cacheControl }
@@ -91,7 +91,6 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
9191
// tool_choice: { type: "auto" },
9292
// tools: tools,
9393
stream: true,
94-
thinking,
9594
},
9695
(() => {
9796
// prompt caching: https://x.com/alexalbert__/status/1823751995901272068
@@ -132,6 +131,7 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
132131
case "message_start":
133132
// Tells us cache reads/writes/input/output.
134133
const usage = chunk.message.usage
134+
console.log("usage", usage)
135135

136136
yield {
137137
type: "usage",
@@ -158,6 +158,12 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
158158
case "content_block_start":
159159
switch (chunk.content_block.type) {
160160
case "thinking":
161+
// We may receive multiple text blocks, in which
162+
// case just insert a line break between them.
163+
if (chunk.index > 0) {
164+
yield { type: "reasoning", text: "\n" }
165+
}
166+
161167
yield { type: "reasoning", text: chunk.content_block.thinking }
162168
break
163169
case "text":
@@ -173,10 +179,14 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
173179
break
174180
case "content_block_delta":
175181
switch (chunk.delta.type) {
182+
case "thinking_delta":
183+
yield { type: "reasoning", text: chunk.delta.thinking }
184+
break
176185
case "text_delta":
177186
yield { type: "text", text: chunk.delta.text }
178187
break
179188
}
189+
180190
break
181191
case "content_block_stop":
182192
break
@@ -186,10 +196,12 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
186196

187197
getModel(): { id: AnthropicModelId; info: ModelInfo } {
188198
const modelId = this.options.apiModelId
199+
189200
if (modelId && modelId in anthropicModels) {
190201
const id = modelId as AnthropicModelId
191202
return { id, info: anthropicModels[id] }
192203
}
204+
193205
return { id: anthropicDefaultModelId, info: anthropicModels[anthropicDefaultModelId] }
194206
}
195207

@@ -204,14 +216,17 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
204216
})
205217

206218
const content = response.content[0]
219+
207220
if (content.type === "text") {
208221
return content.text
209222
}
223+
210224
return ""
211225
} catch (error) {
212226
if (error instanceof Error) {
213227
throw new Error(`Anthropic completion error: ${error.message}`)
214228
}
229+
215230
throw error
216231
}
217232
}

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { UnboundModelPicker } from "./UnboundModelPicker"
4343
import { ModelInfoView } from "./ModelInfoView"
4444
import { DROPDOWN_Z_INDEX } from "./styles"
4545
import { RequestyModelPicker } from "./RequestyModelPicker"
46+
import { Slider } from "../ui"
4647

4748
interface ApiOptionsProps {
4849
uriScheme: string | undefined
@@ -65,6 +66,8 @@ const ApiOptions = ({
6566
const [lmStudioModels, setLmStudioModels] = useState<string[]>([])
6667
const [vsCodeLmModels, setVsCodeLmModels] = useState<vscodemodels.LanguageModelChatSelector[]>([])
6768
const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl)
69+
const [anthropicThinkingEnabled, setAnthropicThinkingEnabled] = useState(!!apiConfiguration?.anthropicThinking)
70+
const [anthropicThinkingBudget, setAnthropicThinkingBudget] = useState(apiConfiguration?.anthropicThinking ?? 1024)
6871
const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion)
6972
const [openRouterBaseUrlSelected, setOpenRouterBaseUrlSelected] = useState(!!apiConfiguration?.openRouterBaseUrl)
7073
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false)
@@ -1224,7 +1227,6 @@ const ApiOptions = ({
12241227
)}
12251228

12261229
{selectedProvider === "glama" && <GlamaModelPicker />}
1227-
12281230
{selectedProvider === "openrouter" && <OpenRouterModelPicker />}
12291231
{selectedProvider === "requesty" && <RequestyModelPicker />}
12301232

@@ -1258,8 +1260,33 @@ const ApiOptions = ({
12581260
</>
12591261
)}
12601262

1263+
{selectedProvider === "anthropic" && (
1264+
<div className="flex flex-col gap-2 mt-2">
1265+
<Checkbox checked={anthropicThinkingEnabled} onChange={setAnthropicThinkingEnabled}>
1266+
Thinking?
1267+
</Checkbox>
1268+
{anthropicThinkingEnabled && (
1269+
<>
1270+
<div className="text-muted-foreground text-sm">
1271+
Number of tokens Claude is allowed use for its internal reasoning process
1272+
</div>
1273+
<div className="flex items-center gap-2">
1274+
<Slider
1275+
min={1024}
1276+
max={6399}
1277+
step={100}
1278+
value={[anthropicThinkingBudget]}
1279+
onValueChange={(value) => setAnthropicThinkingBudget(value[0])}
1280+
/>
1281+
<div className="w-10">{anthropicThinkingBudget}</div>
1282+
</div>
1283+
</>
1284+
)}
1285+
</div>
1286+
)}
1287+
12611288
{!fromWelcomeView && (
1262-
<div style={{ marginTop: "10px" }}>
1289+
<div className="mt-2">
12631290
<TemperatureControl
12641291
value={apiConfiguration?.modelTemperature}
12651292
onChange={handleInputChange("modelTemperature", noTransform)}

0 commit comments

Comments
 (0)