From af6c96c7b2dcf5677763042851eb216878667b50 Mon Sep 17 00:00:00 2001 From: lironsh Date: Mon, 21 Oct 2024 14:55:30 +0300 Subject: [PATCH 1/2] feat: add option to ignore cache - Introduced a new environment variable to bypass cache. - Updated README to include usage instructions. --- README.md | 15 +++++++++++++++ src/actions/StepPerformer.test.ts | 22 ++++++++++++++++++++++ src/actions/StepPerformer.ts | 7 ++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 11d4a76..a7ef8b5 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,21 @@ reset: () => void; perform: (steps: string | string[]) => Promise; ``` +### Additional Note + +In addition to the operations history, Copilot maintains a repository-level cache. If you need to ignore the current cache for any reason (e.g., when adding an action to the testing framework driver), you can set the environment variable `COPILOT_OVERRIDE_CACHE` to "true" before running your tests. This will ensure that the current cache is not taken into consideration and will override the existing one. + +```shell +export COPILOT_OVERRIDE_CACHE=true +``` + +If you want to disable the override after setting it to "true" and revert to using the cache, you can set `COPILOT_OVERRIDE_CACHE` to "false" + +```shell +export COPILOT_OVERRIDE_CACHE=false +``` + + ## Integration with Testing Frameworks Detox Copilot requires two main components to work: diff --git a/src/actions/StepPerformer.test.ts b/src/actions/StepPerformer.test.ts index af0fbc2..f634613 100644 --- a/src/actions/StepPerformer.test.ts +++ b/src/actions/StepPerformer.test.ts @@ -73,6 +73,7 @@ describe('StepPerformer', () => { promptResult?: string; codeEvaluationResult?: any; cacheExists?: boolean; + overrideCache?: boolean; } const setupMocks = ({ @@ -82,6 +83,7 @@ describe('StepPerformer', () => { promptResult = 'generated code', codeEvaluationResult = 'success', cacheExists = false, + overrideCache = false, }: SetupMockOptions = {}) => { mockPromptHandler.isSnapshotImageSupported.mockReturnValue(isSnapshotSupported); mockSnapshotManager.captureSnapshotImage.mockResolvedValue( @@ -92,6 +94,10 @@ describe('StepPerformer', () => { mockPromptHandler.runPrompt.mockResolvedValue(promptResult); mockCodeEvaluator.evaluate.mockResolvedValue(codeEvaluationResult); + if (overrideCache) { + process.env.COPILOT_OVERRIDE_CACHE = "true"; + } + const viewHierarchyHash = 'hash'; (crypto.createHash as jest.Mock).mockReturnValue({ update: jest.fn().mockReturnValue({ @@ -244,4 +250,20 @@ describe('StepPerformer', () => { expect(mockCodeEvaluator.evaluate).not.toHaveBeenCalled(); expect(fs.writeFileSync).not.toHaveBeenCalled(); }); + + it('should not use cached prompt result if COPILOT_OVERRIDE_CACHE is enabled', async () => { + const intent = 'tap button'; + setupMocks({ cacheExists: true, overrideCache: true }); + + const result = await stepPerformer.perform(intent); + + expect(result).toBe('success'); + // Should call runPrompt or createPrompt. Shouldn't use current cache, but override it + expect(mockPromptCreator.createPrompt).toHaveBeenCalled(); + expect(mockPromptHandler.runPrompt).toHaveBeenCalled(); + expect(mockCodeEvaluator.evaluate).toHaveBeenCalledWith('generated code', mockContext); + expect(fs.writeFileSync).toHaveBeenCalled(); // Need to save cache + + + }); }); diff --git a/src/actions/StepPerformer.ts b/src/actions/StepPerformer.ts index 066db6a..eef2bcc 100644 --- a/src/actions/StepPerformer.ts +++ b/src/actions/StepPerformer.ts @@ -7,6 +7,7 @@ import * as path from 'path'; import * as crypto from 'crypto'; import {extractCodeBlock} from '@/utils/extractCodeBlock'; + export class StepPerformer { private cache: Map = new Map(); private readonly cacheFilePath: string; @@ -62,6 +63,10 @@ export class StepPerformer { return { snapshot, viewHierarchy, isSnapshotImageAttached }; } + private shouldOverrideCache() { + return process.env.COPILOT_OVERRIDE_CACHE === "true" || process.env.COPILOT_OVERRIDE_CACHE === "1"; + } + private async generateCode( step: string, previous: PreviousStep[], @@ -71,7 +76,7 @@ export class StepPerformer { ): Promise { const cacheKey = this.generateCacheKey(step, previous, viewHierarchy); - if (this.cache.has(cacheKey)) { + if (!this.shouldOverrideCache() && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } else { const prompt = this.promptCreator.createPrompt(step, viewHierarchy, isSnapshotImageAttached, previous); From fff2115a199d42ad687c39965e5c88fe001225ed Mon Sep 17 00:00:00 2001 From: LironMShemen Date: Tue, 22 Oct 2024 16:12:41 +0300 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Asaf Korem <55082339+asafkorem@users.noreply.github.com> --- src/actions/StepPerformer.test.ts | 2 -- src/actions/StepPerformer.ts | 1 - 2 files changed, 3 deletions(-) diff --git a/src/actions/StepPerformer.test.ts b/src/actions/StepPerformer.test.ts index f634613..179f2a1 100644 --- a/src/actions/StepPerformer.test.ts +++ b/src/actions/StepPerformer.test.ts @@ -263,7 +263,5 @@ describe('StepPerformer', () => { expect(mockPromptHandler.runPrompt).toHaveBeenCalled(); expect(mockCodeEvaluator.evaluate).toHaveBeenCalledWith('generated code', mockContext); expect(fs.writeFileSync).toHaveBeenCalled(); // Need to save cache - - }); }); diff --git a/src/actions/StepPerformer.ts b/src/actions/StepPerformer.ts index eef2bcc..3a430bf 100644 --- a/src/actions/StepPerformer.ts +++ b/src/actions/StepPerformer.ts @@ -7,7 +7,6 @@ import * as path from 'path'; import * as crypto from 'crypto'; import {extractCodeBlock} from '@/utils/extractCodeBlock'; - export class StepPerformer { private cache: Map = new Map(); private readonly cacheFilePath: string;