-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdispatch.test.ts
More file actions
69 lines (63 loc) · 2.67 KB
/
Copy pathdispatch.test.ts
File metadata and controls
69 lines (63 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { describe, expect, it } from 'vitest'
import { producedFromToolEvents } from '../eval/index'
import { dispatchAppTool } from './dispatch'
import type { AppToolHandlers, AppToolProducedEvent, AppToolTaxonomy } from './types'
const taxonomy: AppToolTaxonomy = { proposalTypes: ['other'], regulatedTypes: [] }
const ctx = { userId: 'u', workspaceId: 'w', threadId: 't' }
function handlers(): AppToolHandlers {
return {
async submitProposal() {
return { proposalId: 'p1', deduped: false }
},
async scheduleFollowup() {
return { id: 'f1', dueDate: '2026-01-01', deduped: false }
},
async renderUi() {
return { path: 'ui/x.json', content: '{}' }
},
async addCitation() {
return { citationId: 'c1', path: 'v/x.md' }
},
}
}
describe('dispatchAppTool — proposal body flows in-band', () => {
it('carries the submit_proposal description as the produced event content', async () => {
const produced: AppToolProducedEvent[] = []
const description =
'Transcript TR-90041 has no client_id and cannot be resolved. A named human must attach the correct client before any note is filed.'
const outcome = await dispatchAppTool(
'submit_proposal',
{ type: 'other', title: 'Orphan transcript flag', description },
ctx,
{ handlers: handlers(), taxonomy, onProduced: (e) => produced.push(e) },
)
expect(outcome.ok).toBe(true)
expect(produced).toHaveLength(1)
const ev = produced[0]!
expect(ev.type).toBe('proposal_created')
// The body reaches the produced event — no out-of-band DB read needed.
expect(ev.type === 'proposal_created' && ev.content).toBe(description)
})
it('omits content for a title-only proposal', async () => {
const produced: AppToolProducedEvent[] = []
await dispatchAppTool(
'submit_proposal',
{ type: 'other', title: 'Bare filing' },
ctx,
{ handlers: handlers(), taxonomy, onProduced: (e) => produced.push(e) },
)
const ev = produced[0]!
expect(ev.type === 'proposal_created' && ev.content).toBeUndefined()
})
})
describe('producedFromToolEvents — body threads to the runtime event shape', () => {
it('maps proposal content onto the RuntimeEventLike the completion oracle reads', () => {
const events: AppToolProducedEvent[] = [
{ type: 'proposal_created', proposalId: 'p1', title: 'Orphan flag', status: 'pending', content: 'the body' },
{ type: 'artifact', path: 'ui/x.json', content: '{"k":1}' },
]
const mapped = producedFromToolEvents(events)
const proposal = mapped.find((e) => e.type === 'proposal_created')
expect(proposal && 'content' in proposal && proposal.content).toBe('the body')
})
})