Skip to content

Conversation

@MrGeniusProgrammer
Copy link

Type

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Description

This pull request adds 3 new ai response parts--TextAccumulatedPart, ReasoningAccumulatedPart, and ToolPart--and utilities to convert from streaming and normal parts to accumulated parts.

  • TextAccumulatedPart: same as TextPart but with state field representing either "streaming" or "done"
  • ReasoningAccumulatedPart: same as ReasoningPart but with state field representing either "streaming" or "done"
  • ToolPart combines all of the other tool parts into one part, keeping each previous context, and distinguish each state by their value.state field, where it holds values such as:
    • "params-start": when params are started to streaming in
    • "params-streaming": when params are streaming in
    • "params-malformed": when params are malformed
    • "params-done": when params are done streaming
    • "result-error": when the tool returned an error result
    • "result-done": when the tool call result is returned

These all accumulated parts and other necessary parts are represented by AccumulatedPart.

utilities:

  • mergeAccumulatedParts: merges two accumulated parts into one accumulated parts
  • accumulateParts: accumulate over normal parts given already existing accumulated parts
  • accumulateStreamParts: accumulate over stream parts given already existing accumulated parts

Related

  • Related Issue #
  • Closes #

@changeset-bot
Copy link

changeset-bot bot commented Oct 31, 2025

🦋 Changeset detected

Latest commit: 62f307f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@effect/ai Minor
@effect/ai-amazon-bedrock Major
@effect/ai-anthropic Major
@effect/ai-google Major
@effect/ai-openai Major
@effect/ai-openrouter Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@IMax153
Copy link
Member

IMax153 commented Nov 7, 2025

@MrGeniusProgrammer - what is the concrete use case for this? Can you provide an example of how you would use it?

@MrGeniusProgrammer
Copy link
Author

MrGeniusProgrammer commented Nov 7, 2025

This is valuable to display a UI streaming part for the frontend where accumulated parts are more suited as it is necessary to get the status of the streaming part (are they finished? did it error? did the tool started streaming in?).

// rpcClient("ChatGenerate") returns a Stream.Stream<Response.StreamPart[]>
rpcClient("ChatGenerate").pipe(
	// throttle the streaming response to not aggresively update the UI
	Stream.throttle({
		cost: Chunk.size,
		duration: "250 millis",
		units: 32
	}),
	// accumulate the stream parts
	Stream.scanEffect([], Response.accumulateStreamParts),
	// create a UI Assistant message with the accumulated parts
	Stream.map((accumulatedParts) =>
		UiAssistantMessage.make({
			role: "assistant",
			content: accumulatedParts
		})
	)
);

@IMax153
Copy link
Member

IMax153 commented Nov 7, 2025

Gotcha ok - that makes sense. Would you be willing to add some test cases to cover these new methods? I'm trying to be more diligent about testing in the AI packages now as I add new functionality.

@MrGeniusProgrammer
Copy link
Author

@IMax153 I believe discussing whether to accumulate parts based on window or by id is needed. As of right now, the current implementation goes with the former for the text and reasoning part and latter for the tool part. For example, mergeAccumulatedParts accumulates text part by merging the adjacent text parts into one text part. If a different part is found on the adjacent pair or if it has a status 'done', the text part ends. Another consideration is the order preservation of the parts. Also, what is your take on the naming of state in the TextAccumulatedPart, ReasoningAccumulatedPart, and ToolPart? Should it be renamed to status instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Discussion Ongoing

Development

Successfully merging this pull request may close these issues.

2 participants