Skip to content

Commit 2b047ac

Browse files
authored
fix(amazonq): use server-side data to decide remaining code generations #6370
## Problem Previously remaining code generation iterations are always displayed. ## Solution Only display when it goes down to 2 or less.
1 parent 63fafe3 commit 2b047ac

File tree

5 files changed

+116
-62
lines changed

5 files changed

+116
-62
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Amazon q /dev: Remove hard-coded limits and instead rely server-side data to communicate number of code generations remaining"
4+
}

packages/core/src/amazonqFeatureDev/controllers/chat/controller.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ import { FollowUpTypes } from '../../../amazonq/commons/types'
4949
import { Messenger } from '../../../amazonq/commons/connector/baseMessenger'
5050
import { BaseChatSessionStorage } from '../../../amazonq/commons/baseChatStorage'
5151

52-
export const TotalSteps = 3
53-
5452
export interface ChatControllerEventEmitters {
5553
readonly processHumanChatMessage: EventEmitter<any>
5654
readonly followUpClicked: EventEmitter<any>
@@ -462,12 +460,17 @@ export class FeatureDevController {
462460

463461
if (remainingIterations !== undefined && totalIterations !== undefined) {
464462
this.messenger.sendAnswer({
465-
type: 'answer',
463+
type: 'answer' as const,
466464
tabID: tabID,
467-
message:
468-
remainingIterations === 0
469-
? 'Would you like me to add this code to your project?'
470-
: `Would you like me to add this code to your project, or provide feedback for new code? You have ${remainingIterations} out of ${totalIterations} code generations left.`,
465+
message: (() => {
466+
if (remainingIterations > 2) {
467+
return 'Would you like me to add this code to your project, or provide feedback for new code?'
468+
} else if (remainingIterations > 0) {
469+
return `Would you like me to add this code to your project, or provide feedback for new code? You have ${remainingIterations} out of ${totalIterations} code generations left.`
470+
} else {
471+
return 'Would you like me to add this code to your project?'
472+
}
473+
})(),
471474
})
472475
}
473476

@@ -518,9 +521,8 @@ export class FeatureDevController {
518521
if (session?.state?.tokenSource?.token.isCancellationRequested) {
519522
this.workOnNewTask(
520523
session.tabID,
521-
session.state.codeGenerationRemainingIterationCount ||
522-
TotalSteps - (session.state?.currentIteration || 0),
523-
session.state.codeGenerationTotalIterationCount || TotalSteps,
524+
session.state.codeGenerationRemainingIterationCount,
525+
session.state.codeGenerationTotalIterationCount,
524526
session?.state?.tokenSource?.token.isCancellationRequested
525527
)
526528
this.disposeToken(session)
@@ -563,10 +565,16 @@ export class FeatureDevController {
563565
) {
564566
if (isStoppedGeneration) {
565567
this.messenger.sendAnswer({
566-
message:
567-
(remainingIterations ?? 0) <= 0
568-
? "I stopped generating your code. You don't have more iterations left, however, you can start a new session."
569-
: `I stopped generating your code. If you want to continue working on this task, provide another description. You have ${remainingIterations} out of ${totalIterations} code generations left.`,
568+
message: ((remainingIterations) => {
569+
if (remainingIterations && totalIterations) {
570+
if (remainingIterations <= 0) {
571+
return "I stopped generating your code. You don't have more iterations left, however, you can start a new session."
572+
} else if (remainingIterations <= 2) {
573+
return `I stopped generating your code. If you want to continue working on this task, provide another description. You have ${remainingIterations} out of ${totalIterations} code generations left.`
574+
}
575+
}
576+
return 'I stopped generating your code. If you want to continue working on this task, provide another description.'
577+
})(remainingIterations),
570578
type: 'answer-part',
571579
tabID,
572580
})

packages/core/src/amazonqFeatureDev/session/sessionState.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,16 @@ abstract class CodeGenBase {
175175
codeGenerationRemainingIterationCount?: number
176176
codeGenerationTotalIterationCount?: number
177177
}> {
178+
let codeGenerationRemainingIterationCount = undefined
179+
let codeGenerationTotalIterationCount = undefined
178180
for (
179181
let pollingIteration = 0;
180182
pollingIteration < this.pollCount && !this.isCancellationRequested;
181183
++pollingIteration
182184
) {
183185
const codegenResult = await this.config.proxyClient.getCodeGeneration(this.conversationId, codeGenerationId)
184-
const codeGenerationRemainingIterationCount = codegenResult.codeGenerationRemainingIterationCount
185-
const codeGenerationTotalIterationCount = codegenResult.codeGenerationTotalIterationCount
186+
codeGenerationRemainingIterationCount = codegenResult.codeGenerationRemainingIterationCount
187+
codeGenerationTotalIterationCount = codegenResult.codeGenerationTotalIterationCount
186188

187189
getLogger().debug(`Codegen response: %O`, codegenResult)
188190
telemetry.setCodeGenerationResult(codegenResult.codeGenerationStatus.status)
@@ -272,6 +274,8 @@ abstract class CodeGenBase {
272274
newFiles: [],
273275
deletedFiles: [],
274276
references: [],
277+
codeGenerationRemainingIterationCount: codeGenerationRemainingIterationCount,
278+
codeGenerationTotalIterationCount: codeGenerationTotalIterationCount,
275279
}
276280
}
277281
}
@@ -345,8 +349,13 @@ export class CodeGenState extends CodeGenBase implements SessionState {
345349
this.filePaths = codeGeneration.newFiles
346350
this.deletedFiles = codeGeneration.deletedFiles
347351
this.references = codeGeneration.references
352+
348353
this.codeGenerationRemainingIterationCount = codeGeneration.codeGenerationRemainingIterationCount
349354
this.codeGenerationTotalIterationCount = codeGeneration.codeGenerationTotalIterationCount
355+
this.currentIteration =
356+
this.codeGenerationRemainingIterationCount && this.codeGenerationTotalIterationCount
357+
? this.codeGenerationTotalIterationCount - this.codeGenerationRemainingIterationCount
358+
: this.currentIteration + 1
350359

351360
if (action.uploadHistory && !action.uploadHistory[codeGenerationId] && codeGenerationId) {
352361
action.uploadHistory[codeGenerationId] = {
@@ -366,7 +375,7 @@ export class CodeGenState extends CodeGenBase implements SessionState {
366375
this.deletedFiles,
367376
this.references,
368377
this.tabID,
369-
this.currentIteration + 1,
378+
this.currentIteration,
370379
this.codeGenerationRemainingIterationCount,
371380
this.codeGenerationTotalIterationCount,
372381
action.uploadHistory,

packages/core/src/test/amazonqFeatureDev/controllers/chat/controller.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,29 @@ describe('Controller', () => {
526526
await waitUntil(() => Promise.resolve(sendMetricDataTelemetrySpy.callCount >= 2), {})
527527
}
528528

529+
async function verifyAddCodeMessage(
530+
remainingIterations: number,
531+
totalIterations: number,
532+
expectedMessage: string
533+
) {
534+
sinon.stub(session, 'send').resolves()
535+
sinon.stub(session, 'sendLinesOfCodeGeneratedTelemetry').resolves() // Avoid sending extra telemetry
536+
const sendAnswerSpy = sinon.stub(controllerSetup.messenger, 'sendAnswer')
537+
sinon.stub(session.state, 'codeGenerationRemainingIterationCount').value(remainingIterations)
538+
sinon.stub(session.state, 'codeGenerationTotalIterationCount').value(totalIterations)
539+
540+
await fireChatMessage(session)
541+
await verifyMetricsCalled()
542+
543+
assert.ok(
544+
sendAnswerSpy.calledWith({
545+
type: 'answer',
546+
tabID,
547+
message: expectedMessage,
548+
})
549+
)
550+
}
551+
529552
beforeEach(async () => {
530553
session = await createCodeGenState()
531554
sinon.stub(session, 'preloader').resolves()
@@ -558,6 +581,23 @@ describe('Controller', () => {
558581
await verifyException(error)
559582
})
560583
}
584+
585+
// Using 3 to avoid spamming the tests
586+
for (let remainingIterations = 0; remainingIterations <= 3; remainingIterations++) {
587+
it(`verifies add code messages for remaining iterations at ${remainingIterations}`, async () => {
588+
const totalIterations = 10
589+
const expectedMessage = (() => {
590+
if (remainingIterations > 2) {
591+
return 'Would you like me to add this code to your project, or provide feedback for new code?'
592+
} else if (remainingIterations > 0) {
593+
return `Would you like me to add this code to your project, or provide feedback for new code? You have ${remainingIterations} out of ${totalIterations} code generations left.`
594+
} else {
595+
return 'Would you like me to add this code to your project?'
596+
}
597+
})()
598+
await verifyAddCodeMessage(remainingIterations, totalIterations, expectedMessage)
599+
})
600+
}
561601
})
562602

563603
describe('processErrorChatMessage', function () {

0 commit comments

Comments
 (0)