Skip to content

Commit 71f4a44

Browse files
authored
feat(amazonq): support context commands in agentic chat (#948)
* feat(amazonq): chat context commands for prompts feat(amazonq): integrate with local context server fix(amazonq): fixes and refactor * fix(amazonq): pr comments * fix(amazonq): dispose contextCommandProvider * fix(amazonq): fix test
1 parent dd49420 commit 71f4a44

19 files changed

+1229
-66
lines changed

package-lock.json

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

server/aws-lsp-codewhisperer/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"adm-zip": "^0.5.10",
3939
"archiver": "^7.0.1",
4040
"aws-sdk": "^2.1403.0",
41+
"chokidar": "^4.0.3",
4142
"deepmerge": "^4.3.1",
4243
"diff": "^7.0.0",
4344
"fastest-levenshtein": "^1.0.16",

server/aws-lsp-codewhisperer/src/language-server/agenticChat/agenticChatController.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Will be deleted or merged.
44
*/
55

6+
import * as path from 'path'
67
import {
78
ChatResponseStream,
89
CodeWhispererStreaming,
@@ -36,6 +37,8 @@ import { DEFAULT_HELP_FOLLOW_UP_PROMPT, HELP_MESSAGE } from '../chat/constants'
3637
import { TelemetryService } from '../../shared/telemetry/telemetryService'
3738
import { AmazonQTokenServiceManager } from '../../shared/amazonQServiceManager/AmazonQTokenServiceManager'
3839
import { TabBarController } from './tabBarController'
40+
import { getUserPromptsDirectory } from './context/contextUtils'
41+
import { AdditionalContextProvider } from './context/addtionalContextProvider'
3942

4043
describe('AgenticChatController', () => {
4144
const mockTabId = 'tab-1'
@@ -97,11 +100,13 @@ describe('AgenticChatController', () => {
97100

98101
let sendMessageStub: sinon.SinonStub
99102
let generateAssistantResponseStub: sinon.SinonStub
103+
let additionalContextProviderStub: sinon.SinonStub
100104
let disposeStub: sinon.SinonStub
101105
let activeTabSpy: {
102106
get: sinon.SinonSpy<[], string | undefined>
103107
set: sinon.SinonSpy<[string | undefined], void>
104108
}
109+
let fsWriteFileStub: sinon.SinonStub
105110
let removeConversationSpy: sinon.SinonSpy
106111
let emitConversationMetricStub: sinon.SinonStub
107112

@@ -144,13 +149,14 @@ describe('AgenticChatController', () => {
144149
})
145150

146151
testFeatures = new TestFeatures()
152+
fsWriteFileStub = sinon.stub()
147153

148154
testFeatures.workspace.fs = {
149155
...testFeatures.workspace.fs,
150156
getServerDataDirPath: sinon.stub().returns('/mock/server/data/path'),
151157
mkdir: sinon.stub().resolves(),
152158
readFile: sinon.stub().resolves(),
153-
writeFile: sinon.stub().resolves(),
159+
writeFile: fsWriteFileStub.resolves(),
154160
rm: sinon.stub().resolves(),
155161
}
156162

@@ -161,6 +167,8 @@ describe('AgenticChatController', () => {
161167
addTool: sinon.stub().resolves(),
162168
}
163169

170+
additionalContextProviderStub = sinon.stub(AdditionalContextProvider.prototype, 'getAdditionalContext')
171+
additionalContextProviderStub.resolves([])
164172
// @ts-ignore
165173
const cachedInitializeParams: InitializeParams = {
166174
initializationOptions: {
@@ -173,6 +181,7 @@ describe('AgenticChatController', () => {
173181
},
174182
},
175183
}
184+
testFeatures.lsp.window.showDocument = sinon.stub()
176185
testFeatures.lsp.getClientInitializeParams.returns(cachedInitializeParams)
177186
setCredentials('builderId')
178187

@@ -1001,6 +1010,25 @@ describe('AgenticChatController', () => {
10011010
})
10021011
})
10031012

1013+
describe('onCreatePrompt', () => {
1014+
it('should create prompt file with given name', async () => {
1015+
const promptName = 'testPrompt'
1016+
const expectedPath = path.join(getUserPromptsDirectory(), 'testPrompt.prompt.md')
1017+
1018+
await chatController.onCreatePrompt({ promptName })
1019+
1020+
sinon.assert.calledOnceWithExactly(fsWriteFileStub, expectedPath, '', { mode: 0o600 })
1021+
})
1022+
1023+
it('should create default prompt file when no name provided', async () => {
1024+
const expectedPath = path.join(getUserPromptsDirectory(), 'default.prompt.md')
1025+
1026+
await chatController.onCreatePrompt({ promptName: '' })
1027+
1028+
sinon.assert.calledOnceWithExactly(fsWriteFileStub, expectedPath, '', { mode: 0o600 })
1029+
})
1030+
})
1031+
10041032
describe('onInlineChatPrompt', () => {
10051033
it('read all the response streams and return compiled results', async () => {
10061034
const chatResultPromise = chatController.onInlineChatPrompt(

0 commit comments

Comments
 (0)