Skip to content

Commit febe0c9

Browse files
committed
feat(amazonq): skip registering run command log file
1 parent c3ea31d commit febe0c9

File tree

5 files changed

+162
-2
lines changed

5 files changed

+162
-2
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": "The logs emitted by the Agent during user command execution will be accepted and written to .amazonq/dev/run_command.log file in the user's local repository."
4+
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { prepareRepoData, getDeletedFileInfos, registerNewFiles, PrepareRepoData
2929
import { uploadCode } from '../util/upload'
3030

3131
export const EmptyCodeGenID = 'EMPTY_CURRENT_CODE_GENERATION_ID'
32+
export const RunCommandLogFileName = '.amazonq/dev/run_command.log'
3233

3334
export interface BaseMessenger {
3435
sendAnswer(params: any): void
@@ -103,6 +104,16 @@ export abstract class CodeGenBase {
103104
case CodeGenerationStatus.COMPLETE: {
104105
const { newFileContents, deletedFiles, references } =
105106
await this.config.proxyClient.exportResultArchive(this.conversationId)
107+
108+
const logFileInfo = newFileContents.find(
109+
(file: { zipFilePath: string; fileContent: string }) =>
110+
file.zipFilePath === RunCommandLogFileName
111+
)
112+
if (logFileInfo) {
113+
getLogger().info(`Run Command logs: \n ${logFileInfo.fileContent}`)
114+
newFileContents.splice(newFileContents.indexOf(logFileInfo), 1)
115+
}
116+
106117
const newFileInfo = registerNewFiles(
107118
fs,
108119
newFileContents,

packages/core/src/shared/virtualFilesystem.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export class VirtualFileSystem implements vscode.FileSystemProvider {
4646
if (this.fileProviders[key] !== undefined) {
4747
throw new Error('Cannot re-register a provider for the same URI')
4848
}
49-
5049
this.fileProviders[key] = provider
5150
const onDidChange = provider.onDidChange(() => {
5251
this._onDidChangeFile.fire([{ uri, type: vscode.FileChangeType.Changed }])
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import sinon from 'sinon'
7+
import { CodeGenBase } from '../../../amazonq/session/sessionState'
8+
import { RunCommandLogFileName } from '../../../amazonq/session/sessionState'
9+
import assert from 'assert'
10+
11+
describe('CodeGenBase generateCode log file handling', () => {
12+
class TestCodeGen extends CodeGenBase {
13+
public generatedFiles: any[] = []
14+
constructor(config: any, tabID: string) {
15+
super(config, tabID)
16+
}
17+
protected handleProgress(_messenger: any): void {
18+
// No-op for test.
19+
}
20+
protected getScheme(): string {
21+
return 'file'
22+
}
23+
protected getTimeoutErrorCode(): string {
24+
return 'test_timeout'
25+
}
26+
protected handleGenerationComplete(_messenger: any, newFileInfo: any[]): void {
27+
this.generatedFiles = newFileInfo
28+
}
29+
protected handleError(_messenger: any, _codegenResult: any): Error {
30+
throw new Error('handleError called')
31+
}
32+
}
33+
34+
let fakeProxyClient: any
35+
let testConfig: any
36+
let fsMock: any
37+
let messengerMock: any
38+
let telemetryMock: any
39+
let loggerMock: any
40+
let testAction: any
41+
42+
beforeEach(() => {
43+
fakeProxyClient = {
44+
getCodeGeneration: sinon.stub().resolves({
45+
codeGenerationStatus: { status: 'Complete' },
46+
codeGenerationRemainingIterationCount: 0,
47+
codeGenerationTotalIterationCount: 1,
48+
}),
49+
exportResultArchive: sinon.stub(),
50+
}
51+
52+
testConfig = {
53+
conversationId: 'conv_test',
54+
uploadId: 'upload_test',
55+
workspaceRoots: ['/workspace'],
56+
proxyClient: fakeProxyClient,
57+
}
58+
59+
fsMock = {
60+
writeFile: sinon.stub().resolves(),
61+
registerProvider: sinon.stub().resolves(),
62+
}
63+
64+
messengerMock = { sendAnswer: sinon.spy() }
65+
66+
telemetryMock = {
67+
setCodeGenerationResult: sinon.spy(),
68+
setNumberOfFilesGenerated: sinon.spy(),
69+
setAmazonqNumberOfReferences: sinon.spy(),
70+
setGenerateCodeIteration: sinon.spy(),
71+
setGenerateCodeLastInvocationTime: sinon.spy(),
72+
recordUserCodeGenerationTelemetry: sinon.spy(),
73+
toolkit_trackScenario: {
74+
emit: sinon.spy(),
75+
},
76+
}
77+
78+
loggerMock = {
79+
info: sinon.spy(),
80+
}
81+
82+
testAction = {
83+
fs: fsMock,
84+
messenger: messengerMock,
85+
logger: loggerMock,
86+
tokenSource: { token: { isCancellationRequested: false, onCancellationRequested: () => {} } },
87+
}
88+
})
89+
90+
afterEach(() => {
91+
sinon.restore()
92+
})
93+
94+
it('adds the log content to logger if present and excludes it from new files', async () => {
95+
const logFileInfo = {
96+
zipFilePath: RunCommandLogFileName,
97+
fileContent: 'newLog',
98+
}
99+
const otherFile = { zipFilePath: 'other.ts', fileContent: 'other content' }
100+
fakeProxyClient.exportResultArchive.resolves({
101+
newFileContents: [logFileInfo, otherFile],
102+
deletedFiles: [],
103+
references: [],
104+
})
105+
106+
const testCodeGen = new TestCodeGen(testConfig, 'tab1')
107+
108+
const result = await testCodeGen.generateCode({
109+
messenger: messengerMock,
110+
fs: fsMock,
111+
codeGenerationId: 'codegen1',
112+
telemetry: {} as any,
113+
workspaceFolders: [] as any,
114+
action: testAction,
115+
})
116+
117+
sinon.assert.calledWith(loggerMock.info, `Run Command logs: \n ${logFileInfo.fileContent}`)
118+
119+
sinon.assert.calledWith(fsMock, [otherFile], testConfig.uploadId, [] as any, testConfig.conversationId, 'file')
120+
121+
assert.deepStrictEqual(result.newFiles, [otherFile])
122+
})
123+
124+
it('skips log file handling if log file is not present', async () => {
125+
const file1 = { zipFilePath: 'file1.ts', fileContent: 'content1' }
126+
fakeProxyClient.exportResultArchive.resolves({
127+
newFileContents: [file1],
128+
deletedFiles: [],
129+
references: [],
130+
})
131+
132+
const testCodeGen = new TestCodeGen(testConfig, 'tab1')
133+
134+
const result = await testCodeGen.generateCode({
135+
messenger: messengerMock,
136+
fs: fsMock,
137+
codeGenerationId: 'codegen2',
138+
telemetry: telemetryMock,
139+
workspaceFolders: [] as any,
140+
action: testAction,
141+
})
142+
143+
sinon.assert.notCalled(loggerMock.info)
144+
sinon.assert.calledWith(fsMock, [file1], testConfig.uploadId, [] as any, testConfig.conversationId, 'file')
145+
assert.deepStrictEqual(result.newFiles, [file1])
146+
})
147+
})

packages/core/src/test/amazonqDoc/session/sessionState.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import assert from 'assert'
88
import sinon from 'sinon'
99
import { DocPrepareCodeGenState } from '../../../amazonqDoc'
1010
import { createMockSessionStateAction } from '../../amazonq/utils'
11-
1211
import { createTestContext, setupTestHooks } from '../../amazonq/session/testSetup'
1312

1413
describe('sessionStateDoc', () => {

0 commit comments

Comments
 (0)