Skip to content

Commit a3dff2b

Browse files
committed
add integ test
1 parent 3162bc1 commit a3dff2b

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

tests_integ/bedrock.test.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { Message } from '@strands-agents/sdk'
66
import type { ToolSpec } from '@strands-agents/sdk'
77
import type { ModelStreamEvent } from '@strands-agents/sdk'
88
import { ValidationException } from '@aws-sdk/client-bedrock-runtime'
9+
import { fail } from 'assert/strict'
910

1011
/**
1112
* Helper function to collect all events from a stream.
@@ -30,6 +31,104 @@ try {
3031
console.log('⏭️ AWS credentials not available - integration tests will be skipped')
3132
}
3233

34+
describe.skipIf(!hasCredentials)('BedrockModel Integration Tests (Non-Streaming)', () => {
35+
it('gets a simple text response', async () => {
36+
const provider = new BedrockModel({
37+
stream: false,
38+
maxTokens: 100,
39+
})
40+
41+
const messages: Message[] = [
42+
{
43+
role: 'user',
44+
content: [{ type: 'textBlock', text: 'Say hello in exactly one word.' }],
45+
},
46+
]
47+
48+
const events = await collectEvents(provider.stream(messages))
49+
50+
expect(events[0]?.type).toBe('modelMessageStartEvent')
51+
expect(events[1]?.type).toBe('modelContentBlockStartEvent')
52+
expect(events[2]?.type).toBe('modelContentBlockDeltaEvent')
53+
expect(events[3]?.type).toBe('modelContentBlockStopEvent')
54+
expect(events[4]?.type).toBe('modelMessageStopEvent')
55+
expect(events[5]?.type).toBe('modelMetadataEvent')
56+
57+
let responseText = ''
58+
for (const event of events) {
59+
if (event.type === 'modelContentBlockDeltaEvent' && event.delta.type === 'textDelta') {
60+
responseText += event.delta.text
61+
}
62+
}
63+
expect(responseText.trim().toUpperCase()).toContain('HELLO')
64+
65+
const stopEvent = events.find((e) => e.type === 'modelMessageStopEvent')
66+
expect(stopEvent?.stopReason).toBe('endTurn')
67+
68+
const metadataEvent = events.find((e) => e.type === 'modelMetadataEvent')
69+
if (metadataEvent?.type === 'modelMetadataEvent') {
70+
expect(metadataEvent.usage?.outputTokens).toBeGreaterThan(0)
71+
} else {
72+
fail('Metadata event not found')
73+
}
74+
})
75+
76+
it('requests tool use when appropriate', async () => {
77+
const provider = new BedrockModel({
78+
stream: false,
79+
maxTokens: 200,
80+
})
81+
82+
const calculatorTool: ToolSpec = {
83+
name: 'calculator',
84+
description: 'Performs basic arithmetic operations',
85+
inputSchema: {
86+
type: 'object',
87+
properties: {
88+
operation: { type: 'string', enum: ['add', 'subtract', 'multiply', 'divide'] },
89+
a: { type: 'number' },
90+
b: { type: 'number' },
91+
},
92+
required: ['operation', 'a', 'b'],
93+
},
94+
}
95+
96+
const messages: Message[] = [
97+
{
98+
role: 'user',
99+
content: [{ type: 'textBlock', text: 'What is 15 plus 27?' }],
100+
},
101+
]
102+
103+
const events = await collectEvents(provider.stream(messages, { toolSpecs: [calculatorTool] }))
104+
105+
const startEvent = events.find((e) => e.type === 'modelContentBlockStartEvent')
106+
expect(startEvent).toBeDefined()
107+
108+
if (startEvent?.type === 'modelContentBlockStartEvent') {
109+
expect(startEvent.start?.type).toBe('toolUseStart')
110+
expect(startEvent.start?.name).toBe('calculator')
111+
} else {
112+
fail('Content block start event not found')
113+
}
114+
115+
const deltaEvent = events.find((e) => e.type === 'modelContentBlockDeltaEvent')
116+
expect(deltaEvent).toBeDefined()
117+
118+
if (deltaEvent?.type === 'modelContentBlockDeltaEvent' && deltaEvent.delta.type === 'toolUseInputDelta') {
119+
const input = JSON.parse(deltaEvent.delta.input)
120+
expect(input.operation).toBe('add')
121+
expect(input.a).toBe(15)
122+
expect(input.b).toBe(27)
123+
} else {
124+
fail('Tool use input delta event not found')
125+
}
126+
127+
const stopEvent = events.find((e) => e.type === 'modelMessageStopEvent')
128+
expect(stopEvent?.stopReason).toBe('toolUse')
129+
})
130+
})
131+
33132
describe.skipIf(!hasCredentials)('BedrockModel Integration Tests', () => {
34133
describe('Basic Streaming', () => {
35134
it.concurrent('streams a simple text response', async () => {

0 commit comments

Comments
 (0)