feat(provider.anthropic): Add extended thinking modes to AnthropicProvider and apply thinking budgets to API calls
This commit is contained in:
@@ -20,6 +20,7 @@ export interface IAnthropicProviderOptions {
|
||||
enableWebSearch?: boolean;
|
||||
searchDomainAllowList?: string[];
|
||||
searchDomainBlockList?: string[];
|
||||
extendedThinking?: 'quick' | 'normal' | 'deep' | 'off';
|
||||
}
|
||||
|
||||
export class AnthropicProvider extends MultiModalModel {
|
||||
@@ -42,6 +43,25 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
await super.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the thinking configuration based on provider options.
|
||||
* Defaults to 'normal' mode (8000 tokens) if not specified.
|
||||
*/
|
||||
private getThinkingConfig(): { type: 'enabled'; budget_tokens: number } | undefined {
|
||||
const mode = this.options.extendedThinking ?? 'normal';
|
||||
|
||||
const budgetMap = {
|
||||
quick: 2048,
|
||||
normal: 8000,
|
||||
deep: 16000,
|
||||
off: 0,
|
||||
};
|
||||
|
||||
const budget = budgetMap[mode];
|
||||
|
||||
return budget > 0 ? { type: 'enabled', budget_tokens: budget } : undefined;
|
||||
}
|
||||
|
||||
public async chatStream(input: ReadableStream<Uint8Array>): Promise<ReadableStream<string>> {
|
||||
// Create a TextDecoder to handle incoming chunks
|
||||
const decoder = new TextDecoder();
|
||||
@@ -76,12 +96,14 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
|
||||
// If we have a complete message, send it to Anthropic
|
||||
if (currentMessage) {
|
||||
const thinkingConfig = this.getThinkingConfig();
|
||||
const stream = await this.anthropicApiClient.messages.create({
|
||||
model: 'claude-sonnet-4-5-20250929',
|
||||
messages: [{ role: currentMessage.role, content: currentMessage.content }],
|
||||
system: '',
|
||||
stream: true,
|
||||
max_tokens: 4000,
|
||||
max_tokens: 20000,
|
||||
...(thinkingConfig && { thinking: thinkingConfig }),
|
||||
});
|
||||
|
||||
// Process each chunk from Anthropic
|
||||
@@ -120,6 +142,7 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
content: msg.content
|
||||
}));
|
||||
|
||||
const thinkingConfig = this.getThinkingConfig();
|
||||
const result = await this.anthropicApiClient.messages.create({
|
||||
model: 'claude-sonnet-4-5-20250929',
|
||||
system: optionsArg.systemMessage,
|
||||
@@ -127,7 +150,8 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
...messages,
|
||||
{ role: 'user' as const, content: optionsArg.userMessage }
|
||||
],
|
||||
max_tokens: 4000,
|
||||
max_tokens: 20000,
|
||||
...(thinkingConfig && { thinking: thinkingConfig }),
|
||||
});
|
||||
|
||||
// Extract text content from the response
|
||||
@@ -167,13 +191,15 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
}
|
||||
];
|
||||
|
||||
const thinkingConfig = this.getThinkingConfig();
|
||||
const result = await this.anthropicApiClient.messages.create({
|
||||
model: 'claude-sonnet-4-5-20250929',
|
||||
messages: [{
|
||||
role: 'user',
|
||||
content
|
||||
}],
|
||||
max_tokens: 1024
|
||||
max_tokens: 10000,
|
||||
...(thinkingConfig && { thinking: thinkingConfig }),
|
||||
});
|
||||
|
||||
// Extract text content from the response
|
||||
@@ -229,6 +255,7 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
});
|
||||
}
|
||||
|
||||
const thinkingConfig = this.getThinkingConfig();
|
||||
const result = await this.anthropicApiClient.messages.create({
|
||||
model: 'claude-sonnet-4-5-20250929',
|
||||
system: optionsArg.systemMessage,
|
||||
@@ -236,7 +263,8 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
...messages,
|
||||
{ role: 'user', content }
|
||||
],
|
||||
max_tokens: 4096
|
||||
max_tokens: 20000,
|
||||
...(thinkingConfig && { thinking: thinkingConfig }),
|
||||
});
|
||||
|
||||
// Extract text content from the response
|
||||
@@ -286,8 +314,8 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
}
|
||||
|
||||
// Configure the request based on search depth
|
||||
const maxTokens = optionsArg.searchDepth === 'deep' ? 8192 :
|
||||
optionsArg.searchDepth === 'advanced' ? 6144 : 4096;
|
||||
const maxTokens = optionsArg.searchDepth === 'deep' ? 20000 :
|
||||
optionsArg.searchDepth === 'advanced' ? 20000 : 20000;
|
||||
|
||||
// Create the research request
|
||||
const requestParams: any = {
|
||||
@@ -308,6 +336,12 @@ export class AnthropicProvider extends MultiModalModel {
|
||||
requestParams.tools = tools;
|
||||
}
|
||||
|
||||
// Add thinking configuration if enabled
|
||||
const thinkingConfig = this.getThinkingConfig();
|
||||
if (thinkingConfig) {
|
||||
requestParams.thinking = thinkingConfig;
|
||||
}
|
||||
|
||||
// Execute the research request
|
||||
const result = await this.anthropicApiClient.messages.create(requestParams);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user