refactor(agent): unify sourced message delivery
This commit is contained in:
@@ -101,7 +101,7 @@ describe('real Loader composition', () => {
|
||||
const adapter = new TransientOnceAdapter()
|
||||
loaded.llm.registerAdapter(['mock'], adapter)
|
||||
const agent = loaded.agentLoop.create(SessionId('loader-retry'), { provider: 'mock', model: 'mock' })
|
||||
agent.followup([{ type: 'text', text: 'recover' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'recover' }], source: { kind: 'user' } })
|
||||
await agent.whenIdle()
|
||||
|
||||
expect(adapter.requests).toBe(2)
|
||||
|
||||
@@ -138,7 +138,7 @@ describe('bounded transient retry policy', () => {
|
||||
})
|
||||
})
|
||||
|
||||
agent.followup([{ type: 'text', text: 'go' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
const event = await scheduled
|
||||
|
||||
expect(event.data).toEqual({
|
||||
@@ -187,7 +187,7 @@ describe('bounded transient retry policy', () => {
|
||||
const agent = context.agentLoop.create(SessionId('retry-partial'), { provider: 'mock', model: 'mock' })
|
||||
const scheduled = waitForRetry(context, agent, 1)
|
||||
|
||||
agent.followup([{ type: 'text', text: 'go' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
await scheduled
|
||||
const idle = waitForIdle(context, agent)
|
||||
await vi.advanceTimersByTimeAsync(500)
|
||||
@@ -224,7 +224,7 @@ describe('bounded transient retry policy', () => {
|
||||
const agent = context.agentLoop.create(SessionId('retry-exhausted'), { provider: 'mock', model: 'mock' })
|
||||
const first = waitForRetry(context, agent, 1)
|
||||
|
||||
agent.followup([{ type: 'text', text: 'go' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
expect((await first).data.delayMs).toBe(450)
|
||||
|
||||
const second = waitForRetry(context, agent, 2)
|
||||
@@ -255,14 +255,14 @@ describe('bounded transient retry policy', () => {
|
||||
const agent = context.agentLoop.create(SessionId('retry-reset'), { provider: 'mock', model: 'mock' })
|
||||
|
||||
const firstRetry = waitForRetry(context, agent, 1)
|
||||
agent.followup([{ type: 'text', text: 'first' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'first' }], source: { kind: 'user' } })
|
||||
await firstRetry
|
||||
const firstIdle = waitForIdle(context, agent)
|
||||
await vi.advanceTimersByTimeAsync(500)
|
||||
await firstIdle
|
||||
|
||||
const secondRetry = waitForRetry(context, agent, 1)
|
||||
agent.followup([{ type: 'text', text: 'second' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'second' }], source: { kind: 'user' } })
|
||||
await secondRetry
|
||||
const secondIdle = waitForIdle(context, agent)
|
||||
await vi.advanceTimersByTimeAsync(500)
|
||||
@@ -296,7 +296,7 @@ describe('bounded transient retry policy', () => {
|
||||
})
|
||||
|
||||
const firstRetry = waitForRetry(context, agent, 1)
|
||||
agent.followup([{ type: 'text', text: 'go' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
await firstRetry
|
||||
const secondRetry = waitForRetry(context, agent, 1)
|
||||
await vi.advanceTimersByTimeAsync(500)
|
||||
@@ -324,7 +324,7 @@ describe('bounded transient retry policy', () => {
|
||||
const agent = context.agentLoop.create(SessionId('retry-zero-delay'), { provider: 'mock', model: 'mock' })
|
||||
const scheduled = waitForRetry(context, agent, 1)
|
||||
|
||||
agent.followup([{ type: 'text', text: 'go' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
expect((await scheduled).data.delayMs).toBe(0)
|
||||
|
||||
const idle = waitForIdle(context, agent)
|
||||
@@ -342,7 +342,7 @@ describe('bounded transient retry policy', () => {
|
||||
;({ ctx: context } = await harness(accepted, { jitterRatio: 1 }))
|
||||
const acceptedAgent = context.agentLoop.create(SessionId('retry-after-accepted'), { provider: 'mock', model: 'mock' })
|
||||
const scheduled = waitForRetry(context, acceptedAgent, 1)
|
||||
acceptedAgent.followup([{ type: 'text', text: 'go' }])
|
||||
acceptedAgent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
expect((await scheduled).data.delayMs).toBe(2_000)
|
||||
const acceptedIdle = waitForIdle(context, acceptedAgent)
|
||||
await vi.advanceTimersByTimeAsync(2_000)
|
||||
@@ -356,7 +356,7 @@ describe('bounded transient retry policy', () => {
|
||||
;({ ctx: context } = await harness(rejected))
|
||||
const rejectedAgent = context.agentLoop.create(SessionId('retry-after-rejected'), { provider: 'mock', model: 'mock' })
|
||||
const rejectedIdle = waitForIdle(context, rejectedAgent)
|
||||
rejectedAgent.followup([{ type: 'text', text: 'go' }])
|
||||
rejectedAgent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
await rejectedIdle
|
||||
expect(rejected.requests).toHaveLength(1)
|
||||
expect(rejectedAgent.session.events.some(event => event.type === 'llm/retry')).toBe(false)
|
||||
@@ -368,7 +368,7 @@ describe('bounded transient retry policy', () => {
|
||||
;({ ctx: context } = await harness(adapter))
|
||||
const agent = context.agentLoop.create(SessionId('retry-auth'), { provider: 'mock', model: 'mock' })
|
||||
const idle = waitForIdle(context, agent)
|
||||
agent.followup([{ type: 'text', text: 'go' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
await idle
|
||||
expect(adapter.requests).toHaveLength(1)
|
||||
expect(agent.session.events.some(event => event.type === 'llm/retry')).toBe(false)
|
||||
@@ -385,7 +385,7 @@ describe('bounded transient retry policy', () => {
|
||||
context = mounted.ctx
|
||||
const agent = context.agentLoop.create(SessionId('retry-hmr'), { provider: 'mock', model: 'mock' })
|
||||
const scheduled = waitForRetry(context, agent, 1)
|
||||
agent.followup([{ type: 'text', text: 'go' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })
|
||||
await scheduled
|
||||
const idle = waitForIdle(context, agent)
|
||||
await mounted.retryFiber.dispose()
|
||||
|
||||
@@ -183,7 +183,7 @@ describe('TokenMeterService pricing', () => {
|
||||
expect(snapshot.nodes).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('prices header, prefix, tools, and surface when no reusable usage exists', () => {
|
||||
it('prices header, tools, and surface when no reusable usage exists', () => {
|
||||
const service = meter()
|
||||
const session = new Session(SessionId('heuristic'))
|
||||
session.append('user/message', {
|
||||
@@ -192,7 +192,6 @@ describe('TokenMeterService pricing', () => {
|
||||
}, { surfaceOp: 'append' })
|
||||
appendHeader(session, header('deepseek-v4-flash', {
|
||||
system: 'system',
|
||||
messagePrefix: [textMessage('prefix')],
|
||||
tools: [{ name: 'read', description: 'read', parameters: { type: 'object' } }],
|
||||
}))
|
||||
const result = service.measure(session)
|
||||
@@ -354,10 +353,6 @@ describe('replay anchors and surface folds', () => {
|
||||
...anchoredHeader,
|
||||
config: { ...anchoredHeader.config, temperature: 0.2 },
|
||||
}).baseline.kind).toBe('estimated')
|
||||
expect(service.measure(session, {
|
||||
...anchoredHeader,
|
||||
messagePrefix: [textMessage('prefix')],
|
||||
}).baseline.kind).toBe('estimated')
|
||||
expect(service.measure(session, {
|
||||
...anchoredHeader,
|
||||
tools: [{ name: 'read', description: 'read', parameters: { type: 'object' } }],
|
||||
|
||||
Reference in New Issue
Block a user