Add Sonnet 3.7

This commit is contained in:
Kwaroran
2025-02-25 05:25:34 +09:00
parent 21e311b7a4
commit 6c72d78157
5 changed files with 160 additions and 17 deletions

View File

@@ -1057,4 +1057,5 @@ export const languageEnglish = {
paste: "Paste", paste: "Paste",
depth: "Depth", depth: "Depth",
returnCSSError: "Return CSS Error", returnCSSError: "Return CSS Error",
thinkingTokens: "Thinking Tokens",
} }

View File

@@ -288,9 +288,15 @@
<NumberInput min={0} max={2048} marginBottom={true} bind:value={DBState.db.maxResponse}/> <NumberInput min={0} max={2048} marginBottom={true} bind:value={DBState.db.maxResponse}/>
{#if DBState.db.aiModel.startsWith('gpt') || DBState.db.aiModel === 'reverse_proxy' || DBState.db.aiModel === 'openrouter'} {#if DBState.db.aiModel.startsWith('gpt') || DBState.db.aiModel === 'reverse_proxy' || DBState.db.aiModel === 'openrouter'}
<span class="text-textcolor">{language.seed}</span> <span class="text-textcolor">{language.seed}</span>
<NumberInput bind:value={DBState.db.generationSeed} marginBottom={true}/>
{/if}
{#if modelInfo.parameters.includes('thinking_tokens')}
<span class="text-textcolor">{language.thinkingTokens}</span>
<SliderInput min={0} max={64000} marginBottom step={200} bind:value={DBState.db.thinkingTokens} disableable/>
<NumberInput bind:value={DBState.db.generationSeed} marginBottom={true}/>
{/if} {/if}
<span class="text-textcolor">{language.temperature} <Help key="tempature"/></span> <span class="text-textcolor">{language.temperature} <Help key="tempature"/></span>
<SliderInput min={0} max={200} marginBottom bind:value={DBState.db.temperature} multiple={0.01} fixed={2} disableable/> <SliderInput min={0} max={200} marginBottom bind:value={DBState.db.temperature} multiple={0.01} fixed={2} disableable/>
@@ -315,7 +321,6 @@
{#if modelInfo.parameters.includes('reasoning_effort')} {#if modelInfo.parameters.includes('reasoning_effort')}
<span class="text-textcolor">Reasoning Effort</span> <span class="text-textcolor">Reasoning Effort</span>
<SliderInput min={0} max={2} marginBottom step={1} fixed={0} bind:value={DBState.db.reasoningEffort} disableable/> <SliderInput min={0} max={2} marginBottom step={1} fixed={0} bind:value={DBState.db.reasoningEffort} disableable/>
{/if} {/if}
{#if DBState.db.aiModel === 'textgen_webui' || DBState.db.aiModel === 'mancer' || DBState.db.aiModel.startsWith('local_') || DBState.db.aiModel.startsWith('hf:::')} {#if DBState.db.aiModel === 'textgen_webui' || DBState.db.aiModel === 'mancer' || DBState.db.aiModel.startsWith('local_') || DBState.db.aiModel.startsWith('hf:::')}
<span class="text-textcolor">Repetition Penalty</span> <span class="text-textcolor">Repetition Penalty</span>
@@ -485,6 +490,8 @@
<SliderInput min={0} max={200} marginBottom step={0.01} fixed={2} bind:value={DBState.db.seperateParameters[param].frequency_penalty} disableable/> <SliderInput min={0} max={200} marginBottom step={0.01} fixed={2} bind:value={DBState.db.seperateParameters[param].frequency_penalty} disableable/>
<span class="text-textcolor">Presence Penalty</span> <span class="text-textcolor">Presence Penalty</span>
<SliderInput min={0} max={200} marginBottom step={0.01} fixed={2} bind:value={DBState.db.seperateParameters[param].presence_penalty} disableable/> <SliderInput min={0} max={200} marginBottom step={0.01} fixed={2} bind:value={DBState.db.seperateParameters[param].presence_penalty} disableable/>
<span class="text-textcolor">{language.thinkingTokens}</span>
<SliderInput min={0} max={64000} marginBottom step={200} fixed={0} bind:value={DBState.db.seperateParameters[param].thinking_tokens} disableable/>
</Arcodion> </Arcodion>
{/each} {/each}

View File

@@ -22,7 +22,8 @@ export enum LLMFlags{
deepSeekPrefix, deepSeekPrefix,
deepSeekThinkingInput, deepSeekThinkingInput,
deepSeekThinkingOutput, deepSeekThinkingOutput,
noCivilIntegrity noCivilIntegrity,
claudeThinking,
} }
export enum LLMProvider{ export enum LLMProvider{
@@ -522,6 +523,23 @@ export const LLMModels: LLMModel[] = [
parameters: ClaudeParameters, parameters: ClaudeParameters,
tokenizer: LLMTokenizer.Claude tokenizer: LLMTokenizer.Claude
}, },
{
name: "Claude 3.7 Sonnet",
id: 'claude-3-7-sonnet-latest',
shortName: "3.7 Sonnet",
provider: LLMProvider.Anthropic,
format: LLMFormat.Anthropic,
flags: [
LLMFlags.hasPrefill,
LLMFlags.hasImageInput,
LLMFlags.hasFirstSystemPrompt,
LLMFlags.hasStreaming,
LLMFlags.claudeThinking
],
recommended: true,
parameters: [...ClaudeParameters, 'thinking_tokens'],
tokenizer: LLMTokenizer.Claude
},
{ {
name: "Claude 3.5 Haiku", name: "Claude 3.5 Haiku",
id: 'claude-3-5-haiku-latest', id: 'claude-3-5-haiku-latest',
@@ -598,6 +616,22 @@ export const LLMModels: LLMModel[] = [
parameters: ClaudeParameters, parameters: ClaudeParameters,
tokenizer: LLMTokenizer.Claude tokenizer: LLMTokenizer.Claude
}, },
{
name: "Claude 3.7 Sonnet (20250219)",
id: 'claude-3-7-sonnet-20250219',
shortName: "3.7 Sonnet",
provider: LLMProvider.Anthropic,
format: LLMFormat.Anthropic,
flags: [
LLMFlags.hasPrefill,
LLMFlags.hasImageInput,
LLMFlags.hasFirstSystemPrompt,
LLMFlags.hasStreaming,
LLMFlags.claudeThinking
],
parameters: [...ClaudeParameters, 'thinking_tokens'],
tokenizer: LLMTokenizer.Claude
},
{ {
name: 'Claude 3 Opus (20240229)', name: 'Claude 3 Opus (20240229)',
id: 'claude-3-opus-20240229', id: 'claude-3-opus-20240229',

View File

@@ -92,12 +92,28 @@ interface OaiFunctions {
} }
export type Parameter = 'temperature'|'top_k'|'repetition_penalty'|'min_p'|'top_a'|'top_p'|'frequency_penalty'|'presence_penalty'|'reasoning_effort' export type Parameter = 'temperature'|'top_k'|'repetition_penalty'|'min_p'|'top_a'|'top_p'|'frequency_penalty'|'presence_penalty'|'reasoning_effort'|'thinking_tokens'
export type ModelModeExtended = 'model'|'submodel'|'memory'|'emotion'|'otherAx'|'translate' export type ModelModeExtended = 'model'|'submodel'|'memory'|'emotion'|'otherAx'|'translate'
type ParameterMap = { type ParameterMap = {
[key in Parameter]?: string; [key in Parameter]?: string;
}; };
function setObjectValue<T>(obj: T, key: string, value: any): T {
const splitKey = key.split('.');
if(splitKey.length > 1){
const firstKey = splitKey.shift()
if(!obj[firstKey]){
obj[firstKey] = {};
}
obj[firstKey] = setObjectValue(obj[firstKey], splitKey.join('.'), value);
return obj;
}
obj[key] = value;
return obj;
}
function applyParameters(data: { [key: string]: any }, parameters: Parameter[], rename: ParameterMap, ModelMode:ModelModeExtended, arg:{ function applyParameters(data: { [key: string]: any }, parameters: Parameter[], rename: ParameterMap, ModelMode:ModelModeExtended, arg:{
ignoreTopKIfZero?:boolean ignoreTopKIfZero?:boolean
} = {}): { [key: string]: any } { } = {}): { [key: string]: any } {
@@ -157,6 +173,10 @@ function applyParameters(data: { [key: string]: any }, parameters: Parameter[],
value = db.seperateParameters[ModelMode].top_p value = db.seperateParameters[ModelMode].top_p
break break
} }
case 'thinking_tokens':{
value = db.seperateParameters[ModelMode].thinking_tokens
break
}
case 'frequency_penalty':{ case 'frequency_penalty':{
value = db.seperateParameters[ModelMode].frequency_penalty === -1000 ? -1000 : (db.seperateParameters[ModelMode].frequency_penalty / 100) value = db.seperateParameters[ModelMode].frequency_penalty === -1000 ? -1000 : (db.seperateParameters[ModelMode].frequency_penalty / 100)
break break
@@ -175,7 +195,7 @@ function applyParameters(data: { [key: string]: any }, parameters: Parameter[],
continue continue
} }
data[rename[parameter] ?? parameter] = value data = setObjectValue(data, rename[parameter] ?? parameter, value)
} }
return data return data
} }
@@ -223,13 +243,17 @@ function applyParameters(data: { [key: string]: any }, parameters: Parameter[],
value = db.PresensePenalty === -1000 ? -1000 : (db.PresensePenalty / 100) value = db.PresensePenalty === -1000 ? -1000 : (db.PresensePenalty / 100)
break break
} }
case 'thinking_tokens':{
value = db.thinkingTokens
break
}
} }
if(value === -1000){ if(value === -1000){
continue continue
} }
data[rename[parameter] ?? parameter] = value data = setObjectValue(data, rename[parameter] ?? parameter, value)
} }
return data return data
} }
@@ -2530,14 +2554,23 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise<requestDat
}) })
} }
console.log(arg.modelInfo.parameters)
let body = applyParameters({ let body = applyParameters({
model: arg.modelInfo.internalID, model: arg.modelInfo.internalID,
messages: finalChat, messages: finalChat,
system: systemPrompt.trim(), system: systemPrompt.trim(),
max_tokens: maxTokens, max_tokens: maxTokens,
stream: useStreaming ?? false stream: useStreaming ?? false
}, ['temperature', 'top_k', 'top_p'], {}, arg.mode) }, arg.modelInfo.parameters, {
'thinking_tokens': 'thinking.budget_tokens'
}, arg.mode)
if(body?.thinking?.budget_tokens === 0){
delete body.thinking
}
else if(body?.thinking?.budget_tokens && body?.thinking?.budget_tokens > 0){
body.thinking.type = 'enabled'
}
if(systemPrompt === ''){ if(systemPrompt === ''){
delete body.system delete body.system
@@ -2634,8 +2667,18 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise<requestDat
"accept": "application/json", "accept": "application/json",
} }
let betas:string[] = []
if(db.claudeCachingExperimental){ if(db.claudeCachingExperimental){
headers['anthropic-beta'] = 'prompt-caching-2024-07-31' betas.push('prompt-caching-2024-07-31')
}
if(body.max_tokens > 8192){
betas.push('output-128k-2025-02-19')
}
if(betas.length > 0){
headers['anthropic-beta'] = betas.join(',')
} }
if(db.usePlainFetch){ if(db.usePlainFetch){
@@ -2659,7 +2702,7 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise<requestDat
} }
let rerequesting = false let rerequesting = false
let breakError = '' let breakError = ''
let thinking = false
const stream = new ReadableStream<StreamResponseChunk>({ const stream = new ReadableStream<StreamResponseChunk>({
async start(controller){ async start(controller){
@@ -2672,10 +2715,39 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise<requestDat
switch(e.event){ switch(e.event){
case 'content_block_delta': { case 'content_block_delta': {
if(e.data){ if(e.data){
text += JSON.parse(e.data).delta?.text const parsedData = JSON.parse(e.data)
controller.enqueue({ if(parsedData.delta?.type === 'text' || parsedData.delta?.type === 'text_delta'){
"0": text if(thinking){
}) text += "</Thoughts>\n\n"
thinking = false
}
text += parsedData.delta?.text ?? ''
controller.enqueue({
"0": text
})
}
if(parsedData.delta?.type === 'thinking' || parsedData.delta?.type === 'thinking_delta'){
if(!thinking){
text += "<Thoughts>\n"
thinking = true
}
text += parsedData.delta?.thinking ?? ''
controller.enqueue({
"0": text
})
}
if(parsedData?.delta?.type === 'redacted_thinking'){
if(!thinking){
text += "<Thoughts>\n"
thinking = true
}
text += '\n{{redacted_thinking}}\n'
controller.enqueue({
"0": text
})
}
} }
break break
} }
@@ -2799,13 +2871,40 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise<requestDat
result: JSON.stringify(res.data.error) result: JSON.stringify(res.data.error)
} }
} }
const resText = res?.data?.content?.[0]?.text const contents = res?.data?.content
if(!resText){ if(!contents || contents.length === 0){
return { return {
type: 'fail', type: 'fail',
result: JSON.stringify(res.data) result: JSON.stringify(res.data)
} }
} }
let resText = ''
let thinking = false
for(const content of contents){
if(content.type === 'text'){
if(thinking){
resText += "</Thoughts>\n\n"
thinking = false
}
resText += content.text
}
if(content.type === 'thinking'){
if(!thinking){
resText += "<Thoughts>\n"
thinking = true
}
resText += content.thinking ?? ''
}
if(content.type === 'redacted_thinking'){
if(!thinking){
resText += "<Thoughts>\n"
thinking = true
}
resText += '\n{{redacted_thinking}}\n'
}
}
if(arg.extractJson && db.jsonSchemaEnabled){ if(arg.extractJson && db.jsonSchemaEnabled){
return { return {
type: 'success', type: 'success',

View File

@@ -907,6 +907,7 @@ export interface Database{
showDeprecatedTriggerV1:boolean showDeprecatedTriggerV1:boolean
returnCSSError:boolean returnCSSError:boolean
useExperimentalGoogleTranslator:boolean useExperimentalGoogleTranslator:boolean
thinkingTokens: number
} }
interface SeparateParameters{ interface SeparateParameters{
@@ -919,6 +920,7 @@ interface SeparateParameters{
frequency_penalty?:number frequency_penalty?:number
presence_penalty?:number presence_penalty?:number
reasoning_effort?:number reasoning_effort?:number
thinking_tokens?:number
} }
export interface customscript{ export interface customscript{