Generate Stream with Thinking - #1873
Conversation
- Add Streaming Line Classifier - Add Generate Stream with Thinking API
|
@jstar0 / @arnabnandy7 - please integrate with your PR and test e2e In your PR, please use StreamingLlmOperationsImp from this PR Thank you |
|
@jorander forwarded your request on Claude to Alex H. |
|
|
@igordayen #1864 is a replacement for #1819, not sure why we are treating it separately. @arnabnandy7 Got it, then please integrate #1864. I assume #1819 should be closed then. Any inquiries - let me know. Thanks. |
|
Thanks, @igordayen . I reviewed the The placement is compatible with #1864: However, I don’t think we can use the implementation unchanged because its current classification contract comes from object streaming:
For example: the implementation in #1873 produces two thinking events. The contract in #1864 requires: There are also a few streaming differences to reconcile:
I suggest we reuse the architectural direction from #1873, but first evolve I’m happy to integrate that version and add end-to-end coverage across the tool loop. Also, #1819 can be closed because #1864 replaces it. |
jorander
left a comment
There was a problem hiding this comment.
One request on deferred line-accumulation.
| // Buffer raw LLM chunks into complete newline-delimited lines before classifying. | ||
| // The LLM streams arbitrary byte chunks; thinking tags and JSON objects only make | ||
| // sense as whole lines, so we must reassemble them first. | ||
| .transform { rawChunksToLines(it) } |
There was a problem hiding this comment.
What if we have pure streaming text content, with no thinking tags included? We would still buffer that stream until we find a newline character. I don't think that is a good behavior. Would it be possible to hold of buffering until we identify a chunk that could be the start of a thinking tag?
The use-case I'm thinking of is where we use this method to get StreamingEvent but the thinking we are looking for is native thinking triggered by setting a thinking budget. (I know, not yet implemented or designed, but given the name of the methods I think it is reasonable to assume they should pick up both types of thinking.) ==> that complies with the current behavior for object creation, when Thinking by definition is having tagType=as {XML-tag, PREFIX, NO-PREFIX}. in object creation - everything that is not a JSON is modelled as thinking, see PROMPT definition, for blocking and streaming events.
In summary: replicate the same logic as for object creation and drop any object creation.
Thanks
There was a problem hiding this comment.
@jorander The intent here is to model every line as a ThinkingEvent - as the method states "withThinking".
Fully aligned with object creation. Same behavior.
Native thinking is a very challenging area; eager to start after release 2.0.0, main focus this week.
Intentionally made this simple.
Headups, I'm reviewing discussion forums; new items coming. One of them is related to providing the user with both:
- streaming event without buffering + additional interceptor (in parallel for buffering). So the user can define StreamingEventsAggregatorInterceptor, but it will not block the user from getting low-level streaming events.
Thinking type is having tagType=as {XML-tag, PREFIX, NO-PREFIX}. In object creation, everything that is not JSON is modelled as thinking; see PROMPT definition for blocking and streaming events.
User can opt to use just createObject if needed; mix of thinking + String (final response)
@arnabnandy7 - yes, that is the intent. Just buffering per line + emitting every line as a thinking event. |
Thanks, @igordayen. Understood that emitting every non-JSON line as The distinction I want to clarify is that For example: needs to expose both channels to the caller: If every line is emitted as I also saw @jorander's concern about buffering pure text until a newline. That is another reason I don’t think #1864 can adopt It looks like we currently have two different intended APIs:
Before integrating them, I think we need agreement on which contract |
==> intent was not to mix concepts. Object creation is the responsibility of the "objectCreate" API. Thanks |
==> Do you see a practical need there? Perhaps consider createObject instead? |
|
@igordayen it's done, open for review. cc @jorander |
|
@igordayen I add a link between the discussion in #1881 and this PR since I think they are very much connected. |



#OVERVIEW
Related PR: #1819 , #1864