mirror of
https://github.com/sune-org/us.proxy.sune.chat.git
synced 2026-04-07 02:02:13 +00:00
Feat: Wire up Claude adaptive thinking + effort
Co-authored-by: Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
66
providers.js
66
providers.js
@@ -143,10 +143,6 @@ export async function streamClaude({ apiKey, body, signal, onDelta, isRunning })
|
|||||||
const online = (body.model ?? '').endsWith(':online')
|
const online = (body.model ?? '').endsWith(':online')
|
||||||
const model = online ? body.model.slice(0, -7) : body.model
|
const model = online ? body.model.slice(0, -7) : body.model
|
||||||
|
|
||||||
const includeThoughts = body.reasoning?.exclude !== true
|
|
||||||
const effort = body.reasoning?.effort
|
|
||||||
const useAdaptive = effort && effort !== 'default'
|
|
||||||
|
|
||||||
const system = body.messages
|
const system = body.messages
|
||||||
.filter(m => m.role === 'system')
|
.filter(m => m.role === 'system')
|
||||||
.map(extractText)
|
.map(extractText)
|
||||||
@@ -165,18 +161,17 @@ export async function streamClaude({ apiKey, body, signal, onDelta, isRunning })
|
|||||||
}).filter(Boolean),
|
}).filter(Boolean),
|
||||||
})).filter(m => m.content.length),
|
})).filter(m => m.content.length),
|
||||||
max_tokens: body.max_tokens || 64000,
|
max_tokens: body.max_tokens || 64000,
|
||||||
stream: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useAdaptive) {
|
|
||||||
payload.thinking = { type: 'adaptive' }
|
|
||||||
if (!includeThoughts) payload.thinking.display = 'omitted'
|
|
||||||
payload.output_config = { effort }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (system) payload.system = system
|
if (system) payload.system = system
|
||||||
|
|
||||||
|
const effort = body.reasoning?.effort
|
||||||
|
if (effort && effort !== 'default') {
|
||||||
|
payload.thinking = { type: 'adaptive' }
|
||||||
|
payload.output_config = { effort }
|
||||||
|
} else {
|
||||||
if (Number.isFinite(+body.temperature)) payload.temperature = +body.temperature
|
if (Number.isFinite(+body.temperature)) payload.temperature = +body.temperature
|
||||||
if (Number.isFinite(+body.top_p)) payload.top_p = +body.top_p
|
if (Number.isFinite(+body.top_p)) payload.top_p = +body.top_p
|
||||||
|
}
|
||||||
|
|
||||||
if (online) {
|
if (online) {
|
||||||
payload.tools = [
|
payload.tools = [
|
||||||
@@ -185,53 +180,26 @@ export async function streamClaude({ apiKey, body, signal, onDelta, isRunning })
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const resp = await fetch('https://api.anthropic.com/v1/messages', {
|
const includeThoughts = body.reasoning?.exclude !== true
|
||||||
method: 'POST',
|
let hasThinking = false, hasContent = false
|
||||||
headers: {
|
|
||||||
'x-api-key': apiKey,
|
|
||||||
'anthropic-version': '2023-06-01',
|
|
||||||
'content-type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(payload),
|
|
||||||
signal,
|
|
||||||
})
|
|
||||||
if (!resp.ok) throw new Error(`Claude API error: ${resp.status} ${await resp.text()}`)
|
|
||||||
|
|
||||||
const reader = resp.body.getReader()
|
const stream = client.messages.stream(payload)
|
||||||
const dec = new TextDecoder()
|
|
||||||
let buf = '', hasThinking = false, hasContent = false
|
|
||||||
|
|
||||||
while (isRunning()) {
|
|
||||||
const { done, value } = await reader.read()
|
|
||||||
if (done) break
|
|
||||||
buf += dec.decode(value, { stream: true })
|
|
||||||
const lines = buf.split('\n')
|
|
||||||
buf = lines.pop()
|
|
||||||
for (const line of lines) {
|
|
||||||
if (!line.startsWith('data: ')) continue
|
|
||||||
const data = line.substring(6).trim()
|
|
||||||
if (!data) continue
|
|
||||||
try {
|
try {
|
||||||
const event = JSON.parse(data)
|
for await (const event of stream) {
|
||||||
if (event.type === 'content_block_delta') {
|
if (!isRunning()) break
|
||||||
|
if (event.type !== 'content_block_delta') continue
|
||||||
const delta = event.delta
|
const delta = event.delta
|
||||||
if (delta?.type === 'thinking_delta' && delta.thinking && includeThoughts) {
|
if (delta.type === 'thinking_delta' && includeThoughts) {
|
||||||
onDelta(delta.thinking)
|
onDelta(delta.thinking)
|
||||||
hasThinking = true
|
hasThinking = true
|
||||||
} else if (delta?.type === 'text_delta' && delta.text) {
|
} else if (delta.type === 'text_delta') {
|
||||||
if (hasThinking && !hasContent) onDelta('\n')
|
if (hasThinking && !hasContent) onDelta('\n')
|
||||||
onDelta(delta.text)
|
onDelta(delta.text)
|
||||||
hasContent = true
|
hasContent = true
|
||||||
}
|
}
|
||||||
} else if (event.type === 'message_delta' && event.delta?.stop_reason) {
|
|
||||||
break
|
|
||||||
} else if (event.type === 'error') {
|
|
||||||
throw new Error(event.error?.message || 'Claude stream error')
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message?.includes('Claude')) throw e
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
try { stream.controller?.abort() } catch {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user