Skip to content

Commit 3603cc7

Browse files
authored
Include padding from bedrock in AI chunked responses (#2453)
1 parent e8cf16c commit 3603cc7

File tree

7 files changed

+186
-151
lines changed

7 files changed

+186
-151
lines changed

.changeset/hip-hairs-rescue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@aws-amplify/ai-constructs': patch
3+
---
4+
5+
Include padding from bedrock in AI chunked responses

package-lock.json

Lines changed: 150 additions & 150 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/ai-constructs/src/conversation/runtime/bedrock_converse_adapter.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ void describe('Bedrock converse adapter', () => {
116116
contentBlockText: 'b',
117117
contentBlockIndex: 0,
118118
contentBlockDeltaIndex: 0,
119+
p: 'testPadding',
119120
},
120121
{
121122
accumulatedTurnContent: [
@@ -128,6 +129,7 @@ void describe('Bedrock converse adapter', () => {
128129
contentBlockText: 'lock1',
129130
contentBlockIndex: 0,
130131
contentBlockDeltaIndex: 1,
132+
p: 'testPadding',
131133
},
132134
{
133135
accumulatedTurnContent: [
@@ -154,6 +156,7 @@ void describe('Bedrock converse adapter', () => {
154156
contentBlockText: 'b',
155157
contentBlockIndex: 1,
156158
contentBlockDeltaIndex: 0,
159+
p: 'testPadding',
157160
},
158161
{
159162
accumulatedTurnContent: [
@@ -169,6 +172,7 @@ void describe('Bedrock converse adapter', () => {
169172
contentBlockText: 'lock2',
170173
contentBlockIndex: 1,
171174
contentBlockDeltaIndex: 1,
175+
p: 'testPadding',
172176
},
173177
{
174178
accumulatedTurnContent: [
@@ -1202,6 +1206,8 @@ const mockConverseStreamCommandOutput = (
12021206
// simulate chunked input
12031207
text: input.substring(0, 1),
12041208
},
1209+
// @ts-expect-error padding is sent by Bedrock but not in their API.
1210+
p: 'testPadding',
12051211
},
12061212
});
12071213
if (input.length > 1) {
@@ -1212,6 +1218,8 @@ const mockConverseStreamCommandOutput = (
12121218
// simulate chunked input
12131219
text: input.substring(1),
12141220
},
1221+
// @ts-expect-error padding is sent by Bedrock but not in their API.
1222+
p: 'testPadding',
12151223
},
12161224
});
12171225
}

packages/ai-constructs/src/conversation/runtime/bedrock_converse_adapter.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,22 @@ export class BedrockConverseAdapter {
239239
}
240240
} else if (chunk.contentBlockDelta.delta?.text) {
241241
text += chunk.contentBlockDelta.delta.text;
242-
yield {
242+
const amplifyChunk: StreamingResponseChunk = {
243243
accumulatedTurnContent: [...accumulatedTurnContent, { text }],
244244
conversationId: this.event.conversationId,
245245
associatedUserMessageId: this.event.currentMessageId,
246246
contentBlockText: chunk.contentBlockDelta.delta.text,
247247
contentBlockIndex: blockIndex,
248248
contentBlockDeltaIndex: blockDeltaIndex,
249249
};
250+
// padding is sent from Bedrock but not included in the API.
251+
if ('p' in chunk.contentBlockDelta) {
252+
const bedrockPadding = chunk.contentBlockDelta.p;
253+
if (typeof bedrockPadding === 'string') {
254+
amplifyChunk.p = bedrockPadding;
255+
}
256+
}
257+
yield amplifyChunk;
250258
lastBlockDeltaIndex = blockDeltaIndex;
251259
blockDeltaIndex++;
252260
}

packages/ai-constructs/src/conversation/runtime/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ export type StreamingResponseChunk = {
106106
associatedUserMessageId: string;
107107
contentBlockIndex: number;
108108
accumulatedTurnContent: Array<bedrock.ContentBlock>;
109+
110+
// optional padding
111+
// it is a random string included in text chunks,
112+
// the value does not matter, but we need to pass it through to AppSync
113+
p?: string;
109114
} & (
110115
| {
111116
// text chunk

packages/integration-tests/src/test-project-setup/conversation_handler_project.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ type ConversationTurnAppSyncResponseChunk = {
9595
contentBlockDoneAtIndex?: number;
9696
contentBlockToolUse?: string;
9797
stopReason?: string;
98+
p?: string;
9899
errors?: Array<ConversationTurnError>;
99100
};
100101

@@ -698,6 +699,7 @@ class ConversationHandlerTestProject extends TestProjectBase {
698699
errorType
699700
message
700701
}
702+
p
701703
id
702704
owner
703705
stopReason
@@ -747,6 +749,10 @@ class ConversationHandlerTestProject extends TestProjectBase {
747749

748750
const content = chunks.reduce((accumulated, current) => {
749751
if (current.contentBlockText) {
752+
assert.ok(
753+
current.p && current.p.length > 0,
754+
'Text chunks must include padding'
755+
);
750756
accumulated += current.contentBlockText;
751757
}
752758
if (current.contentBlockToolUse) {

packages/integration-tests/src/test-projects/conversation-handler/amplify/data/resource.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ const schema = a.schema({
108108
contentBlockIndex: a.integer(),
109109
accumulatedTurnContent: a.ref('MockContentBlock').array(),
110110

111+
// padding
112+
p: a.string(),
113+
111114
// these describe chunks or end of block
112115
contentBlockText: a.string(),
113116
contentBlockToolUse: a.string(),

0 commit comments

Comments
 (0)