Skip to content

Commit 3fa5519

Browse files
committed
feat: enhance reasoning handling in tool calls and change the thinking order when stream=false and exclude reasoning_opaque from token calculation in calculateMessageTokens
1 parent 58f7a45 commit 3fa5519

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

src/lib/tokenizer.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ const calculateMessageTokens = (
7373
const tokensPerName = 1
7474
let tokens = tokensPerMessage
7575
for (const [key, value] of Object.entries(message)) {
76+
if (key === "reasoning_opaque") {
77+
continue
78+
}
7679
if (typeof value === "string") {
7780
tokens += encoder.encode(value).length
7881
}

src/routes/messages/non-stream-translation.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ export function translateToAnthropic(
287287
)
288288
const toolUseBlocks = getAnthropicToolUseBlocks(choice.message.tool_calls)
289289

290-
assistantContentBlocks.push(...textBlocks, ...thingBlocks, ...toolUseBlocks)
290+
assistantContentBlocks.push(...thingBlocks, ...textBlocks, ...toolUseBlocks)
291291

292292
// Use the finish_reason from the first choice, or prioritize tool_calls
293293
if (choice.finish_reason === "tool_calls" || stopReason === "stop") {
@@ -320,7 +320,7 @@ export function translateToAnthropic(
320320
function getAnthropicTextBlocks(
321321
messageContent: Message["content"],
322322
): Array<AnthropicTextBlock> {
323-
if (typeof messageContent === "string") {
323+
if (typeof messageContent === "string" && messageContent.length > 0) {
324324
return [{ type: "text", text: messageContent }]
325325
}
326326

@@ -337,16 +337,16 @@ function getAnthropicThinkBlocks(
337337
reasoningText: string | null | undefined,
338338
reasoningOpaque: string | null | undefined,
339339
): Array<AnthropicThinkingBlock> {
340-
if (reasoningText) {
340+
if (reasoningText && reasoningText.length > 0) {
341341
return [
342342
{
343343
type: "thinking",
344344
thinking: reasoningText,
345-
signature: "",
345+
signature: reasoningOpaque || "",
346346
},
347347
]
348348
}
349-
if (reasoningOpaque) {
349+
if (reasoningOpaque && reasoningOpaque.length > 0) {
350350
return [
351351
{
352352
type: "thinking",

src/routes/messages/stream-translation.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ function handleFinish(
6262
index: state.contentBlockIndex,
6363
})
6464
state.contentBlockOpen = false
65+
state.contentBlockIndex++
66+
handleReasoningOpaque(choice.delta, events, state)
6567
}
6668

6769
events.push(
@@ -96,7 +98,9 @@ function handleToolCalls(
9698
events: Array<AnthropicStreamEventData>,
9799
) {
98100
if (delta.tool_calls && delta.tool_calls.length > 0) {
99-
closeThinkingBlockIfOpen(delta, state, events)
101+
closeThinkingBlockIfOpen(state, events)
102+
103+
handleReasoningOpaqueInToolCalls(state, events, delta)
100104

101105
for (const toolCall of delta.tool_calls) {
102106
if (toolCall.id && toolCall.function?.name) {
@@ -150,13 +154,29 @@ function handleToolCalls(
150154
}
151155
}
152156

157+
function handleReasoningOpaqueInToolCalls(
158+
state: AnthropicStreamState,
159+
events: Array<AnthropicStreamEventData>,
160+
delta: Delta,
161+
) {
162+
if (state.contentBlockOpen) {
163+
events.push({
164+
type: "content_block_stop",
165+
index: state.contentBlockIndex,
166+
})
167+
state.contentBlockIndex++
168+
state.contentBlockOpen = false
169+
}
170+
handleReasoningOpaque(delta, events, state)
171+
}
172+
153173
function handleContent(
154174
delta: Delta,
155175
state: AnthropicStreamState,
156176
events: Array<AnthropicStreamEventData>,
157177
) {
158178
if (delta.content && delta.content.length > 0) {
159-
closeThinkingBlockIfOpen(delta, state, events)
179+
closeThinkingBlockIfOpen(state, events)
160180

161181
if (isToolBlockOpen(state)) {
162182
// A tool block was open, so close it before starting a text block.
@@ -260,6 +280,7 @@ function handleReasoningOpaque(
260280
index: state.contentBlockIndex,
261281
},
262282
)
283+
state.contentBlockIndex++
263284
}
264285
}
265286

@@ -312,7 +333,6 @@ function handleThinkingText(
312333
}
313334

314335
function closeThinkingBlockIfOpen(
315-
delta: Delta,
316336
state: AnthropicStreamState,
317337
events: Array<AnthropicStreamEventData>,
318338
): void {
@@ -334,7 +354,6 @@ function closeThinkingBlockIfOpen(
334354
state.contentBlockIndex++
335355
state.thinkingBlockOpen = false
336356
}
337-
handleReasoningOpaque(delta, events, state)
338357
}
339358

340359
export function translateErrorToAnthropicErrorEvent(): AnthropicStreamEventData {

0 commit comments

Comments
 (0)