Skip to content

Conversation

@zikajk
Copy link
Member

@zikajk zikajk commented Jan 13, 2026

  • I added a entry in changelog under unreleased section.

Handle OpenAI-compatible providers that send finish_reason=stop
alongside tool_calls by deferring :finish, return executed tools
from the accumulator, and emit a finish only when no valid tools
can run to prevent hung prompts.
Emit string :content for text-only messages (including reason/tag fallback)
to improve Gemini/OpenAI-compat payload shape, and update tests to expect
string content.
@zikajk zikajk requested a review from ericdallo January 13, 2026 12:15
@zikajk
Copy link
Member Author

zikajk commented Jan 13, 2026

@ericdallo Do you think the failing build can be related to my changes?

@ericdallo
Copy link
Member

no, I did a mistake in master that I'm taking a look, I let you know when fixed

(string? content)
[{:type "text"
:text (string/trim content)}]
(string/trim content)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used maps to keep consistency in the data structure, but I'm ok if that fix problems, I just hope to not cause any other

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is supported, but often not recommended so I decided to take the safe route here :-).
And I suppose it will save some tokens as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think tokens are calculated based on the structure, but on the chars content, but I'm ok with that

@zikajk
Copy link
Member Author

zikajk commented Jan 13, 2026

@ericdallo The Gemini is still buggy though. It looks like its OPENAI api isn't perfect.
E.g. it sends us though> with missing < which is fed back to the model and it gets very confused.

charmbracelet/crush#1698

image image

@zikajk
Copy link
Member Author

zikajk commented Jan 13, 2026

@ericdallo Regarding the rare problem with broken gemini thinking tag. It is not something I will fix in this PR.

@ericdallo
Copy link
Member

@zikajk does that means it's a bug only with gemini or other providers? is it possible to repro with other providers so I can try?

@zikajk
Copy link
Member Author

zikajk commented Jan 14, 2026

@zikajk does that means it's a bug only with gemini or other providers? is it possible to repro with other providers so I can try?

Only with Gemini. I have an experimental branch where reasoning is purged from history (user can opt-out via provider config).
And what I have found so far, it is quite possible that Gemini (and maybe other models as well?) doesn't even like to have reasoning returned in the same turn (nothing in official docs though...).
I want to see if the problem is gone when i won't send ANY reasoning back. If yes, then I would send "turn reasoning" only for models doing delta-reasoning (Deepseek) - again with a opt-out via provider config.

@ericdallo
Copy link
Member

it is quite possible that Gemini (and maybe other models as well?) doesn't even like to have reasoning returned in the same turn (nothing in official docs though...).

I see, but for other models I'd say this is unlikely, as at least major models like openai and anthropic this is required, but let's test, but I'd say it should affect model quality

@zikajk
Copy link
Member Author

zikajk commented Jan 14, 2026

it is quite possible that Gemini (and maybe other models as well?) doesn't even like to have reasoning returned in the same turn (nothing in official docs though...).

I see, but for other models I'd say this is unlikely, as at least major models like openai and anthropic this is required, but let's test, but I'd say it should affect model quality

Can you point me to the documentation? I know they use different API but I am curious.

@ericdallo
Copy link
Member

Can you point me to the documentation? I know they use different API but I am curious.

https://platform.openai.com/docs/api-reference/responses/create

Includes an encrypted version of reasoning tokens in reasoning item outputs. This enables reasoning items to be used in multi-turn conversations when using the Responses API statelessly (like when the store parameter is set to false, or when an organization is enrolled in the zero data retention program).

Anthropic has the same here, mentioning to pass back thinking blocks

@zikajk
Copy link
Member Author

zikajk commented Jan 14, 2026

@ericdallo

Can you point me to the documentation? I know they use different API but I am curious.

https://platform.openai.com/docs/api-reference/responses/create

Includes an encrypted version of reasoning tokens in reasoning item outputs. This enables reasoning items to be used in multi-turn conversations when using the Responses API statelessly (like when the store parameter is set to false, or when an organization is enrolled in the zero data retention program).

Anthropic has the same here, mentioning to pass back thinking blocks

The Gemini also requires to keep the encrypted version (thought_signatures).
And the Anthropic behavior is the one I consider to be the best default. Only this part is something I wonder about (if other providers throws past thinking tokens away):

While you can omit thinking blocks from prior assistant role turns, we suggest always passing back all thinking blocks to the API for any multi-turn conversation. The API will:

Automatically filter the provided thinking blocks
Use the relevant thinking blocks necessary to preserve the model's reasoning
Only bill for the input tokens for the blocks shown to Claude

But yeah, I am keeping the mentioned branch experimental and I don't plan it to make it PR until I am absolutely sure that it helps.
Not related to this branch though :-)

Copy link
Member

@ericdallo ericdallo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this done? can you add changelog entry please?

@zikajk
Copy link
Member Author

zikajk commented Jan 14, 2026

@ericdallo Done.

@ericdallo ericdallo merged commit dbdf726 into master Jan 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants