From 0f3083a2adebb3f54f3aa2502b2e9108185890ac Mon Sep 17 00:00:00 2001 From: Kevin Gilpin Date: Thu, 3 Oct 2024 13:35:42 -0400 Subject: [PATCH 1/3] feat: Add setting appMap.navie.contextTokenLimit --- package.json | 5 +++++ src/configuration/extensionSettings.ts | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/package.json b/package.json index 9e988753..4fa06314 100644 --- a/package.json +++ b/package.json @@ -315,6 +315,11 @@ "type": "number", "description": "Port number to pass to the Navie UI (used for extension development and debugging only)" }, + "appMap.navie.contextTokenLimit": { + "type": "number", + "default": 8000, + "description": "Default size of the context to send to Navie AI" + }, "appMap.scannerEnabled": { "type": "boolean", "default": false, diff --git a/src/configuration/extensionSettings.ts b/src/configuration/extensionSettings.ts index fe776936..6171af5f 100644 --- a/src/configuration/extensionSettings.ts +++ b/src/configuration/extensionSettings.ts @@ -52,6 +52,11 @@ export default class ExtensionSettings { if (port && typeof port === 'number' && port > 0) return port; } + public static get navieContextTokenLimit(): number | undefined { + const limit = vscode.workspace.getConfiguration('appMap').get('navie.contextTokenLimit'); + if (limit && typeof limit === 'number' && limit > 0) return limit; + } + public static get useVsCodeLM(): boolean { return [true, 'true'].includes( vscode.workspace.getConfiguration('appMap').get('navie.useVSCodeLM') || false From d5c1bc43590b385871d5715da84fa1ede5145d3e Mon Sep 17 00:00:00 2001 From: Kevin Gilpin Date: Thu, 3 Oct 2024 13:36:36 -0400 Subject: [PATCH 2/3] fix: Apply user token limit, with a default of 8_000 --- src/services/chatCompletion.ts | 16 +++++++++++-- test/unit/services/chatCompletion.test.ts | 29 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/services/chatCompletion.ts b/src/services/chatCompletion.ts index f3456f3a..e651f50c 100644 --- a/src/services/chatCompletion.ts +++ b/src/services/chatCompletion.ts @@ -76,12 +76,24 @@ export default class ChatCompletion implements Disposable { get env(): Record { const pref = ChatCompletion.preferredModel; - return { + + const modelTokenLimit = pref?.maxInputTokens ?? 3926; + const tokenLimitSetting = ExtensionSettings.navieContextTokenLimit; + const tokenLimits = [modelTokenLimit, tokenLimitSetting].filter( + (limit) => limit && limit > 0 + ) as number[]; + + const env: Record = { OPENAI_API_KEY: this.key, OPENAI_BASE_URL: this.url, - APPMAP_NAVIE_TOKEN_LIMIT: String(pref?.maxInputTokens ?? 3926), APPMAP_NAVIE_MODEL: pref?.family ?? 'gpt-4o', }; + + if (tokenLimits.length) { + env['APPMAP_NAVIE_TOKEN_LIMIT'] = Math.min(...tokenLimits).toString(); + } + + return env; } private static models: vscode.LanguageModelChat[] = []; diff --git a/test/unit/services/chatCompletion.test.ts b/test/unit/services/chatCompletion.test.ts index 16569945..a287805f 100644 --- a/test/unit/services/chatCompletion.test.ts +++ b/test/unit/services/chatCompletion.test.ts @@ -9,6 +9,7 @@ import type { LanguageModelChatMessage, LanguageModelChatResponse, } from 'vscode'; +import { workspace } from 'vscode'; import ChatCompletion from '../../../src/services/chatCompletion'; import { addMockChatModel, resetModelMocks } from '../mock/vscode/lm'; @@ -33,9 +34,19 @@ describe('ChatCompletion', () => { beforeEach(async () => { resetModelMocks(); addMockChatModel(mockModel); + await ChatCompletion.refreshModels(); }); + function mockTokenLimitSetting(limit: number | undefined) { + sinon.stub(workspace, 'getConfiguration').returns({ + get: sinon.stub().callsFake((key) => { + if (key === 'navie.contextTokenLimit') return limit; + return undefined; + }), + } as any); // eslint-disable-line @typescript-eslint/no-explicit-any + } + before(async () => { mockModel.sendRequest = sendRequestEcho; chatCompletion = new ChatCompletion(0, 'test-key'); @@ -57,6 +68,24 @@ describe('ChatCompletion', () => { }); }); + describe('when token limit is configured below the LLM default', () => { + beforeEach(() => mockTokenLimitSetting(100)); + + it('applies the configuration setting', () => { + const env = chatCompletion.env; + expect(env['APPMAP_NAVIE_TOKEN_LIMIT']).to.equal('100'); + }); + }); + + describe('when token limit is configured above the LLM default', () => { + beforeEach(() => mockTokenLimitSetting(100_000)); + + it('uses the LLM limit', () => { + const env = chatCompletion.env; + expect(env['APPMAP_NAVIE_TOKEN_LIMIT']).to.equal('325'); + }); + }); + it('should refresh models and set the preferred model', async () => { resetModelMocks(); const mockModel1 = { From f251a0cc9c1fd36aad4aa291bb222714878d860b Mon Sep 17 00:00:00 2001 From: Kevin Gilpin Date: Thu, 3 Oct 2024 13:53:51 -0400 Subject: [PATCH 3/3] chore: Add canned navie prompts --- .gitignore | 1 + .navie/prompts/pr_description.md | 9 +++++++++ .navie/prompts/review_vs_plan.md | 28 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 .navie/prompts/pr_description.md create mode 100644 .navie/prompts/review_vs_plan.md diff --git a/.gitignore b/.gitignore index 3d4862ae..43e94bd1 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,5 @@ resources/*.jar # AppMap tmp/appmap +.navie/**/diff.txt diff --git a/.navie/prompts/pr_description.md b/.navie/prompts/pr_description.md new file mode 100644 index 00000000..8d2b4387 --- /dev/null +++ b/.navie/prompts/pr_description.md @@ -0,0 +1,9 @@ +Describe the changes in the manner of a PR description. + +In the initial section, describe the changes that directly address the issue description and/or +plan, if provided. + +In a subsequent section, describe any changes that were not part of the original plan or issue +description, if provided. + +Do not emit any code snippets; just a description of the changes made. diff --git a/.navie/prompts/review_vs_plan.md b/.navie/prompts/review_vs_plan.md new file mode 100644 index 00000000..7386cf97 --- /dev/null +++ b/.navie/prompts/review_vs_plan.md @@ -0,0 +1,28 @@ +/nocontext + +Compare a set of code changes with an implementation plan. + +If no code changes are provided, emit a message indicating that the code changes are missing. + +If no implementation plan is provided, emit a message indicating that the implementation plan is +missing. + +If both code changes and an implementation plan are provided, compare the code changes with the +implementation plan and emit a list of differences between the two. + +Output your analysis in the following sections: + +## As planned + +- A change that is present in the implementation plan and also present in the code changes. +- Another change that is present in the implementation plan and also present in the code changes. + +## Unplanned changes + +- A change that is present in the code changes but not in the implementation plan. +- Another change that is present in the code changes but not in the implementation plan. + +## Unimplemented changes + +- A change that is present in the implementation plan but not in the code changes. +- Another change that is present in the implementation plan but not in the code changes.