Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/agent/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Fixed

- Removed unnecessary `as any` casts when accessing `errorMessage` on `AssistantMessage` in `Agent` turn-end handling — the field is already on the type.

## [16.1.16] - 2026-06-23

### Added
Expand Down
4 changes: 2 additions & 2 deletions packages/agent/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1202,8 +1202,8 @@ export class Agent {
break;

case "turn_end":
if (event.message.role === "assistant" && (event.message as any).errorMessage) {
this.#state.error = (event.message as any).errorMessage;
if (event.message.role === "assistant" && event.message.errorMessage) {
this.#state.error = event.message.errorMessage;
}
break;

Expand Down
4 changes: 4 additions & 0 deletions packages/ai/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Changed

- Removed redundant `undefined as any` casts in `EventStream.end()` and `endWaiting()`. The waiter type is now explicitly `IteratorResult<T, undefined>` (instead of the default `IteratorResult<T, any>`), so the `undefined` value is type-checked without relying on the implicit `any` for `TReturn`.

## [16.1.16] - 2026-06-23

### Fixed
Expand Down
8 changes: 4 additions & 4 deletions packages/ai/src/utils/event-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { AssistantMessage, AssistantMessageEvent } from "../types";
// Generic event stream class for async iteration
export class EventStream<T, R = T> implements AsyncIterable<T> {
queue: T[] = [];
waiting: Array<{ resolve: (value: IteratorResult<T>) => void; reject: (err: unknown) => void }> = [];
waiting: Array<{ resolve: (value: IteratorResult<T, undefined>) => void; reject: (err: unknown) => void }> = [];
done = false;
/** True once finalResultPromise has been resolved or rejected. */
resultSettled = false;
Expand Down Expand Up @@ -68,14 +68,14 @@ export class EventStream<T, R = T> implements AsyncIterable<T> {
// Notify all waiting consumers that we're done
while (this.waiting.length > 0) {
const waiter = this.waiting.shift()!;
waiter.resolve({ value: undefined as any, done: true });
waiter.resolve({ value: undefined, done: true });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

should-fix This still type-checks because waiting.resolve is typed as IteratorResult<T>, whose TReturn defaults to any. That removes the as any text but keeps the same implicit any escape hatch for both done: true resolves. Could we type the waiter result and the promise in [Symbol.asyncIterator] as IteratorResult<T, undefined> instead, so undefined is checked without relying on any?

}
}

endWaiting(): void {
while (this.waiting.length > 0) {
const waiter = this.waiting.shift()!;
waiter.resolve({ value: undefined as any, done: true });
waiter.resolve({ value: undefined, done: true });
}
}

Expand All @@ -101,7 +101,7 @@ export class EventStream<T, R = T> implements AsyncIterable<T> {
} else if (this.done) {
return;
} else {
const result = await new Promise<IteratorResult<T>>((resolve, reject) =>
const result = await new Promise<IteratorResult<T, undefined>>((resolve, reject) =>
this.waiting.push({ resolve, reject }),
);
if (result.done) return;
Expand Down
Loading