mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-18 07:43:00 -07:00
!feat(core): clarify agent session resume boundaries
This commit is contained in:
@@ -209,7 +209,7 @@ describe('AgentSession', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should complete immediately when resuming from an event on a stream with no agent activity', async () => {
|
||||
it('should throw when resuming from an event before agent_start on a stream with no agent activity', async () => {
|
||||
const protocol = new MockAgentProtocol();
|
||||
const session = new AgentSession(protocol);
|
||||
|
||||
@@ -225,10 +225,30 @@ describe('AgentSession', () => {
|
||||
const iterator = session.stream({ eventId: updateEvent!.id })[
|
||||
Symbol.asyncIterator
|
||||
]();
|
||||
await expect(iterator.next()).resolves.toEqual({
|
||||
value: undefined,
|
||||
done: true,
|
||||
});
|
||||
await expect(iterator.next()).rejects.toThrow(
|
||||
`Cannot resume from eventId ${updateEvent!.id} before agent_start; use stream({ streamId }) instead`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw when resuming from a pre-agent_start event even if agent activity may start later', async () => {
|
||||
const protocol = new MockAgentProtocol([
|
||||
{
|
||||
id: 'e-1',
|
||||
timestamp: '2026-01-01T00:00:00.000Z',
|
||||
streamId: 'stream-1',
|
||||
type: 'message',
|
||||
role: 'user',
|
||||
content: [{ type: 'text', text: 'request' }],
|
||||
},
|
||||
]);
|
||||
const session = new AgentSession(protocol);
|
||||
|
||||
const iterator = session.stream({ eventId: 'e-1' })[
|
||||
Symbol.asyncIterator
|
||||
]();
|
||||
await expect(iterator.next()).rejects.toThrow(
|
||||
'Cannot resume from eventId e-1 before agent_start; use stream({ streamId }) instead',
|
||||
);
|
||||
});
|
||||
|
||||
it('should resume from an in-stream event within the same stream only', async () => {
|
||||
|
||||
@@ -148,16 +148,16 @@ export class AgentSession implements AgentProtocol {
|
||||
done = true;
|
||||
} else if (streamHasStarted) {
|
||||
agentActivityStarted = true;
|
||||
} else if (
|
||||
!currentEvents
|
||||
.slice(index + 1)
|
||||
.some(
|
||||
(event) =>
|
||||
event.type === 'agent_start' &&
|
||||
event.streamId === trackedStreamId,
|
||||
)
|
||||
) {
|
||||
done = true;
|
||||
} else {
|
||||
// Consumers can only resume by eventId once the stream has entered the
|
||||
// agent_start -> agent_end lifecycle. For pre-start events, use
|
||||
// stream({ streamId }) instead because this wrapper cannot
|
||||
// distinguish "agent activity will start later" from "this send was
|
||||
// acknowledged without agent activity" without risking an infinite
|
||||
// wait.
|
||||
throw new Error(
|
||||
`Cannot resume from eventId ${options.eventId} before agent_start; use stream({ streamId }) instead`,
|
||||
);
|
||||
}
|
||||
} else if (options.streamId) {
|
||||
const index = currentEvents.findIndex(
|
||||
|
||||
Reference in New Issue
Block a user