Skip to content

Commit 5c3b12c

Browse files
authored
feat(amazonq): handle invalidStateEvent response, show error #4448
Problem: CodeWhispererStreaming has a new field in the ChatResponseStream payload which is not currently handled in the toolkit. The field is used whenever the response comes to an invalid state, and contains a message explaining the reasons for the invalid state. Solution: Update the CodeWhispererStreaming generated client, so it includes this new field. Add the correct handling of the invalid state event in the featureDev's client.
1 parent 3c912a0 commit 5c3b12c

File tree

11 files changed

+253
-1893
lines changed

11 files changed

+253
-1893
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Feature",
3+
"description": "Amazon Q: /dev command now supports the InvalidState event during the GenerateApproach step. The reason for the Approach to reach an Invalid State is printed in /dev's chat response."
4+
}

package-lock.json

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

packages/toolkit/src/amazonqFeatureDev/client/featureDev.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,20 @@ export class FeatureDevClient {
159159
return undefined
160160
}
161161

162-
const assistantResponse = []
162+
const assistantResponse: string[] = []
163163
for await (const responseItem of response.planningResponseStream) {
164164
if (responseItem.error !== undefined) {
165165
throw responseItem.error
166+
} else if (responseItem.invalidStateEvent !== undefined) {
167+
getLogger().debug('Received Invalid State Event: %O', responseItem.invalidStateEvent)
168+
assistantResponse.splice(0)
169+
assistantResponse.push(responseItem.invalidStateEvent.message ?? '')
170+
break
171+
} else if (responseItem.assistantResponseEvent !== undefined) {
172+
assistantResponse.push(responseItem.assistantResponseEvent.content ?? '')
166173
}
167-
assistantResponse.push(responseItem.assistantResponseEvent!.content)
168174
}
169-
return assistantResponse.join(' ')
175+
return assistantResponse.join('')
170176
} catch (e) {
171177
if (isCodeWhispererStreamingServiceException(e)) {
172178
getLogger().error(

src.gen/@amzn/codewhisperer-streaming/LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
189+
Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

src.gen/@amzn/codewhisperer-streaming/package-lock.json

Lines changed: 0 additions & 1621 deletions
This file was deleted.

src.gen/@amzn/codewhisperer-streaming/package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
"tslib": "^2.5.0",
2121
"@aws-crypto/sha256-browser": "3.0.0",
2222
"@aws-crypto/sha256-js": "3.0.0",
23-
"@aws-sdk/middleware-host-header": "3.489.0",
24-
"@aws-sdk/middleware-logger": "3.489.0",
25-
"@aws-sdk/middleware-recursion-detection": "3.489.0",
26-
"@aws-sdk/middleware-token": "3.489.0",
27-
"@aws-sdk/middleware-user-agent": "3.489.0",
28-
"@aws-sdk/region-config-resolver": "3.489.0",
29-
"@aws-sdk/types": "3.489.0",
30-
"@aws-sdk/util-user-agent-browser": "3.489.0",
31-
"@aws-sdk/util-user-agent-node": "3.489.0",
23+
"@aws-sdk/middleware-host-header": "3.425.0",
24+
"@aws-sdk/middleware-logger": "3.425.0",
25+
"@aws-sdk/middleware-recursion-detection": "3.425.0",
26+
"@aws-sdk/middleware-token": "3.425.0",
27+
"@aws-sdk/middleware-user-agent": "3.425.0",
28+
"@aws-sdk/region-config-resolver": "3.425.0",
29+
"@aws-sdk/types": "3.425.0",
30+
"@aws-sdk/util-user-agent-browser": "3.425.0",
31+
"@aws-sdk/util-user-agent-node": "3.425.0",
3232
"@smithy/config-resolver": "^2.0.11",
3333
"@smithy/eventstream-serde-browser": "^2.0.10",
3434
"@smithy/eventstream-serde-config-resolver": "^2.0.10",

src.gen/@amzn/codewhisperer-streaming/src/commands/GenerateAssistantResponseCommand.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ export interface GenerateAssistantResponseCommandOutput extends GenerateAssistan
268268
* // userIntent: "SUGGEST_ALTERNATE_IMPLEMENTATION" || "APPLY_COMMON_BEST_PRACTICES" || "IMPROVE_CODE" || "SHOW_EXAMPLES" || "CITE_SOURCES" || "EXPLAIN_LINE_BY_LINE" || "EXPLAIN_CODE_SELECTION",
269269
* // },
270270
* // },
271+
* // invalidStateEvent: { // InvalidStateEvent
272+
* // reason: "INVALID_TASK_ASSIST_PLAN", // required
273+
* // message: "STRING_VALUE", // required
274+
* // },
271275
* // error: { // InternalServerException
272276
* // message: "STRING_VALUE", // required
273277
* // },

src.gen/@amzn/codewhisperer-streaming/src/commands/GenerateTaskAssistPlanCommand.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ export interface GenerateTaskAssistPlanCommandOutput extends GenerateTaskAssistP
272272
* // userIntent: "SUGGEST_ALTERNATE_IMPLEMENTATION" || "APPLY_COMMON_BEST_PRACTICES" || "IMPROVE_CODE" || "SHOW_EXAMPLES" || "CITE_SOURCES" || "EXPLAIN_LINE_BY_LINE" || "EXPLAIN_CODE_SELECTION",
273273
* // },
274274
* // },
275+
* // invalidStateEvent: { // InvalidStateEvent
276+
* // reason: "INVALID_TASK_ASSIST_PLAN", // required
277+
* // message: "STRING_VALUE", // required
278+
* // },
275279
* // error: { // InternalServerException
276280
* // message: "STRING_VALUE", // required
277281
* // },

src.gen/@amzn/codewhisperer-streaming/src/models/models_0.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,31 @@ import {
55
ExceptionOptionType as __ExceptionOptionType,
66
} from "@smithy/smithy-client";
77

8+
/**
9+
* @public
10+
* @enum
11+
*/
12+
export const AccessDeniedExceptionReason = {
13+
UNAUTHORIZED_CUSTOMIZATION_RESOURCE_ACCESS: "UNAUTHORIZED_CUSTOMIZATION_RESOURCE_ACCESS",
14+
} as const
15+
/**
16+
* @public
17+
*/
18+
export type AccessDeniedExceptionReason = typeof AccessDeniedExceptionReason[keyof typeof AccessDeniedExceptionReason]
19+
820
/**
921
* @public
1022
* This exception is thrown when the user does not have sufficient access to perform this action.
1123
*/
1224
export class AccessDeniedException extends __BaseException {
1325
readonly name: "AccessDeniedException" = "AccessDeniedException";
1426
readonly $fault: "client" = "client";
27+
/**
28+
* @public
29+
* Reason for AccessDeniedException
30+
*/
31+
reason?: AccessDeniedExceptionReason | string;
32+
1533
/**
1634
* @internal
1735
*/
@@ -22,6 +40,7 @@ export class AccessDeniedException extends __BaseException {
2240
...opts
2341
});
2442
Object.setPrototypeOf(this, AccessDeniedException.prototype);
43+
this.reason = opts.reason;
2544
}
2645
}
2746

@@ -1006,6 +1025,32 @@ export const FollowupPromptEventFilterSensitiveLog = (obj: FollowupPromptEvent):
10061025
}),
10071026
})
10081027

1028+
/**
1029+
* @public
1030+
* @enum
1031+
*/
1032+
export const InvalidStateReason = {
1033+
INVALID_TASK_ASSIST_PLAN: "INVALID_TASK_ASSIST_PLAN",
1034+
} as const
1035+
/**
1036+
* @public
1037+
*/
1038+
export type InvalidStateReason = typeof InvalidStateReason[keyof typeof InvalidStateReason]
1039+
1040+
/**
1041+
* @public
1042+
* Streaming Response Event when an Invalid State is reached
1043+
*/
1044+
export interface InvalidStateEvent {
1045+
/**
1046+
* @public
1047+
* Reasons for Invalid State Event
1048+
*/
1049+
reason: InvalidStateReason | string | undefined;
1050+
1051+
message: string | undefined;
1052+
}
1053+
10091054
/**
10101055
* @public
10111056
* Streaming Response Event for AssistantResponse Metadata
@@ -1052,6 +1097,7 @@ export type ChatResponseStream =
10521097
| ChatResponseStream.CodeReferenceEventMember
10531098
| ChatResponseStream.ErrorMember
10541099
| ChatResponseStream.FollowupPromptEventMember
1100+
| ChatResponseStream.InvalidStateEventMember
10551101
| ChatResponseStream.MessageMetadataEventMember
10561102
| ChatResponseStream.SupplementaryWebLinksEventMember
10571103
| ChatResponseStream.$UnknownMember
@@ -1071,6 +1117,7 @@ export namespace ChatResponseStream {
10711117
codeReferenceEvent?: never;
10721118
supplementaryWebLinksEvent?: never;
10731119
followupPromptEvent?: never;
1120+
invalidStateEvent?: never;
10741121
error?: never;
10751122
$unknown?: never;
10761123
}
@@ -1085,6 +1132,7 @@ export namespace ChatResponseStream {
10851132
codeReferenceEvent?: never;
10861133
supplementaryWebLinksEvent?: never;
10871134
followupPromptEvent?: never;
1135+
invalidStateEvent?: never;
10881136
error?: never;
10891137
$unknown?: never;
10901138
}
@@ -1099,6 +1147,7 @@ export namespace ChatResponseStream {
10991147
codeReferenceEvent: CodeReferenceEvent;
11001148
supplementaryWebLinksEvent?: never;
11011149
followupPromptEvent?: never;
1150+
invalidStateEvent?: never;
11021151
error?: never;
11031152
$unknown?: never;
11041153
}
@@ -1113,6 +1162,7 @@ export namespace ChatResponseStream {
11131162
codeReferenceEvent?: never;
11141163
supplementaryWebLinksEvent: SupplementaryWebLinksEvent;
11151164
followupPromptEvent?: never;
1165+
invalidStateEvent?: never;
11161166
error?: never;
11171167
$unknown?: never;
11181168
}
@@ -1127,6 +1177,22 @@ export namespace ChatResponseStream {
11271177
codeReferenceEvent?: never;
11281178
supplementaryWebLinksEvent?: never;
11291179
followupPromptEvent: FollowupPromptEvent;
1180+
invalidStateEvent?: never;
1181+
error?: never;
1182+
$unknown?: never;
1183+
}
1184+
1185+
/**
1186+
* @public
1187+
* Invalid State event
1188+
*/
1189+
export interface InvalidStateEventMember {
1190+
messageMetadataEvent?: never;
1191+
assistantResponseEvent?: never;
1192+
codeReferenceEvent?: never;
1193+
supplementaryWebLinksEvent?: never;
1194+
followupPromptEvent?: never;
1195+
invalidStateEvent: InvalidStateEvent;
11301196
error?: never;
11311197
$unknown?: never;
11321198
}
@@ -1141,6 +1207,7 @@ export namespace ChatResponseStream {
11411207
codeReferenceEvent?: never;
11421208
supplementaryWebLinksEvent?: never;
11431209
followupPromptEvent?: never;
1210+
invalidStateEvent?: never;
11441211
error: InternalServerException;
11451212
$unknown?: never;
11461213
}
@@ -1154,6 +1221,7 @@ export namespace ChatResponseStream {
11541221
codeReferenceEvent?: never;
11551222
supplementaryWebLinksEvent?: never;
11561223
followupPromptEvent?: never;
1224+
invalidStateEvent?: never;
11571225
error?: never;
11581226
$unknown: [string, any];
11591227
}
@@ -1164,6 +1232,7 @@ export namespace ChatResponseStream {
11641232
codeReferenceEvent: (value: CodeReferenceEvent) => T;
11651233
supplementaryWebLinksEvent: (value: SupplementaryWebLinksEvent) => T;
11661234
followupPromptEvent: (value: FollowupPromptEvent) => T;
1235+
invalidStateEvent: (value: InvalidStateEvent) => T;
11671236
error: (value: InternalServerException) => T;
11681237
_: (name: string, value: any) => T;
11691238
}
@@ -1177,6 +1246,7 @@ export namespace ChatResponseStream {
11771246
if (value.codeReferenceEvent !== undefined) return visitor.codeReferenceEvent(value.codeReferenceEvent);
11781247
if (value.supplementaryWebLinksEvent !== undefined) return visitor.supplementaryWebLinksEvent(value.supplementaryWebLinksEvent);
11791248
if (value.followupPromptEvent !== undefined) return visitor.followupPromptEvent(value.followupPromptEvent);
1249+
if (value.invalidStateEvent !== undefined) return visitor.invalidStateEvent(value.invalidStateEvent);
11801250
if (value.error !== undefined) return visitor.error(value.error);
11811251
return visitor._(value.$unknown[0], value.$unknown[1]);
11821252
}
@@ -1201,6 +1271,9 @@ export const ChatResponseStreamFilterSensitiveLog = (obj: ChatResponseStream): a
12011271
if (obj.followupPromptEvent !== undefined) return {followupPromptEvent:
12021272
FollowupPromptEventFilterSensitiveLog(obj.followupPromptEvent)
12031273
};
1274+
if (obj.invalidStateEvent !== undefined) return {invalidStateEvent:
1275+
obj.invalidStateEvent
1276+
};
12041277
if (obj.error !== undefined) return {error:
12051278
obj.error
12061279
};

src.gen/@amzn/codewhisperer-streaming/src/protocols/Aws_restJson1.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
FollowupPrompt,
3131
FollowupPromptEvent,
3232
InternalServerException,
33+
InvalidStateEvent,
3334
MessageMetadataEvent,
3435
Position,
3536
ProgrammingLanguage,
@@ -338,6 +339,7 @@ const de_ExportResultArchiveCommandError = async(
338339
const data: any = parsedOutput.body;
339340
const doc = take(data, {
340341
'message': __expectString,
342+
'reason': __expectString,
341343
});
342344
Object.assign(contents, doc);
343345
const exception = new AccessDeniedException({
@@ -488,6 +490,11 @@ const de_ExportResultArchiveCommandError = async(
488490
followupPromptEvent: await de_FollowupPromptEvent_event(event["followupPromptEvent"], context),
489491
};
490492
}
493+
if (event["invalidStateEvent"] != null) {
494+
return {
495+
invalidStateEvent: await de_InvalidStateEvent_event(event["invalidStateEvent"], context),
496+
};
497+
}
491498
if (event["error"] != null) {
492499
return {
493500
error: await de_InternalServerException_event(event["error"], context),
@@ -581,6 +588,15 @@ const de_ExportResultArchiveCommandError = async(
581588
};
582589
return de_InternalServerExceptionRes(parsedOutput, context);
583590
}
591+
const de_InvalidStateEvent_event = async (
592+
output: any,
593+
context: __SerdeContext
594+
): Promise<InvalidStateEvent> => {
595+
const contents: InvalidStateEvent = {} as any;
596+
const data: any = await parseBody(output.body, context);
597+
Object.assign(contents, _json(data));
598+
return contents;
599+
}
584600
const de_MessageMetadataEvent_event = async (
585601
output: any,
586602
context: __SerdeContext
@@ -669,6 +685,8 @@ const de_ExportResultArchiveCommandError = async(
669685

670686
// de_FollowupPromptEvent omitted.
671687

688+
// de_InvalidStateEvent omitted.
689+
672690
// de_MessageMetadataEvent omitted.
673691

674692
// de_Reference omitted.

0 commit comments

Comments
 (0)