fix pre-step lifecycle regressions
This commit is contained in:
@@ -18,16 +18,20 @@ export const name = 'time-context-invariant'
|
||||
/** Service required before the companion can reserve package ownership. */
|
||||
export const inject = ['invariants']
|
||||
|
||||
/** Derive the next request boundary at which a time-context reading may append. */
|
||||
/** Derive the entered step boundary at which a time-context reading may append. */
|
||||
function preparationPosition(history: readonly SessionEvent[], fail: InvariantFailure): { turn: number; step: number } {
|
||||
for (const event of history.slice().reverse()) {
|
||||
switch (event.type) {
|
||||
case 'step/end':
|
||||
return { turn: event.data.turn, step: event.data.step + 1 }
|
||||
case 'turn/start':
|
||||
return { turn: event.data.turn, step: 1 }
|
||||
case 'step/start':
|
||||
return { turn: event.data.turn, step: event.data.step }
|
||||
case 'turn/start':
|
||||
case 'step/end':
|
||||
case 'turn/end':
|
||||
case 'request/header':
|
||||
case 'assistant/chunk':
|
||||
case 'assistant/message':
|
||||
case 'tool/call':
|
||||
case 'tool/result':
|
||||
fail('time-context reading must be appended at a prompt boundary')
|
||||
break
|
||||
default:
|
||||
|
||||
@@ -58,6 +58,7 @@ function preparing(turn: number, step: number): Session {
|
||||
session.append('step/start', { turn, step: priorStep })
|
||||
session.append('step/end', { turn, step: priorStep })
|
||||
}
|
||||
session.append('step/start', { turn, step })
|
||||
return session
|
||||
}
|
||||
|
||||
@@ -88,6 +89,7 @@ describe('time-context invariants', () => {
|
||||
await ctx.plugin(SessionStore)
|
||||
const session = ctx.sessions.create(SessionId('time-invariant-late-valid'))
|
||||
session.append('turn/start', { turn: 1 })
|
||||
session.append('step/start', { turn: 1, step: 1 })
|
||||
session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'prepare' }],
|
||||
source: { kind: 'user' },
|
||||
@@ -103,6 +105,7 @@ describe('time-context invariants', () => {
|
||||
await ctx.plugin(SessionStore)
|
||||
const session = ctx.sessions.create(SessionId('time-invariant-late-invalid'))
|
||||
session.append('turn/start', { turn: 1 })
|
||||
session.append('step/start', { turn: 1, step: 1 })
|
||||
session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'prepare' }],
|
||||
source: { kind: 'user' },
|
||||
@@ -132,7 +135,7 @@ describe('time-context invariants', () => {
|
||||
it('rejects a reading outside a prompt boundary', async () => {
|
||||
const ctx = await setup()
|
||||
const ended = preparing(1, 1)
|
||||
ended.append('step/start', { turn: 1, step: 1 })
|
||||
ended.append('step/end', { turn: 1, step: 1 })
|
||||
expect(() => { ctx.emit('session/event', ended, event(reading())) }).toThrow(/at a prompt boundary/)
|
||||
expect(() => {
|
||||
ctx.emit('session/event', new Session(SessionId('time-invariant-empty')), event(reading()))
|
||||
|
||||
@@ -17,7 +17,7 @@ const SIGNAL = new AbortController().signal
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['TZ'] = 'UTC'
|
||||
vi.useFakeTimers()
|
||||
vi.useFakeTimers({ toFake: ['Date'] })
|
||||
vi.setSystemTime(BASE)
|
||||
})
|
||||
|
||||
@@ -405,7 +405,7 @@ describe('real agent-loop request history', () => {
|
||||
expect(contexts).toHaveLength(adapter.requests.length)
|
||||
expect(starts).toHaveLength(adapter.requests.length)
|
||||
for (let index = 0; index < contexts.length; index += 1) {
|
||||
expect(contexts[index]!.seq).toBeLessThan(starts[index]!.seq)
|
||||
expect(contexts[index]!.seq).toBeGreaterThan(starts[index]!.seq)
|
||||
}
|
||||
expect(contexts.every(event => event.data.source.kind === 'plugin'
|
||||
&& event.data.source.plugin === 'time-context'
|
||||
|
||||
Reference in New Issue
Block a user