-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(commits): Implement cached response for chain responses (#530)
- Added `DocumentCache` class to handle caching of chain step responses based on workspace, config, and conversation. - Introduced `getCachedResponse` and `setCachedResponse` functions to retrieve and store cached responses. - Updated `runChain` function to utilize cached responses if available, reducing redundant calls to the AI module. - Added tests to verify the caching behavior and ensure correct functionality with various configurations and scenarios. This change improves performance by avoiding repeated AI calls for the same conversation and configuration, leveraging cached responses when appropriate.
- Loading branch information
Showing
4 changed files
with
414 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { beforeEach, describe, expect, it, vi } from 'vitest' | ||
|
||
import * as cacheModule from '../../cache' | ||
import { createProject } from '../../tests/factories' | ||
import { getCachedResponse, setCachedResponse } from './promptCache' | ||
|
||
describe('promptCache', async () => { | ||
const mockCache = { | ||
get: vi.fn(), | ||
set: vi.fn(), | ||
} | ||
|
||
beforeEach(() => { | ||
// @ts-expect-error - mock | ||
vi.spyOn(cacheModule, 'cache').mockResolvedValue(mockCache) | ||
vi.clearAllMocks() | ||
}) | ||
|
||
const { workspace } = await createProject() | ||
const config = { temperature: 0 } | ||
const conversation = { messages: [], config } | ||
const response = { | ||
streamType: 'text', | ||
text: 'cached response', | ||
usage: { | ||
promptTokens: 0, | ||
completionTokens: 0, | ||
totalTokens: 0, | ||
}, | ||
toolCalls: [], | ||
} | ||
|
||
describe('getCachedResponse', () => { | ||
it('returns undefined when temperature is not 0', async () => { | ||
const result = await getCachedResponse({ | ||
workspace, | ||
config: { temperature: 0.5 }, | ||
conversation, | ||
}) | ||
|
||
expect(result).toBeUndefined() | ||
expect(mockCache.get).not.toHaveBeenCalled() | ||
}) | ||
|
||
it('returns cached response when available', async () => { | ||
mockCache.get.mockResolvedValueOnce(JSON.stringify(response)) | ||
|
||
const result = await getCachedResponse({ | ||
workspace, | ||
config, | ||
conversation, | ||
}) | ||
|
||
expect(result).toEqual(response) | ||
expect(mockCache.get).toHaveBeenCalledTimes(1) | ||
}) | ||
|
||
it('returns undefined when cache throws error', async () => { | ||
mockCache.get.mockRejectedValueOnce(new Error('Cache error')) | ||
|
||
const result = await getCachedResponse({ | ||
workspace, | ||
config, | ||
conversation, | ||
}) | ||
|
||
expect(result).toBeUndefined() | ||
}) | ||
}) | ||
|
||
describe('setCachedResponse', () => { | ||
it('does not cache when temperature is not 0', async () => { | ||
await setCachedResponse({ | ||
workspace, | ||
config: { temperature: 0.5 }, | ||
conversation, | ||
// @ts-expect-error - mock | ||
response, | ||
}) | ||
|
||
expect(mockCache.set).not.toHaveBeenCalled() | ||
}) | ||
|
||
it('caches response when temperature is 0', async () => { | ||
await setCachedResponse({ | ||
workspace, | ||
config, | ||
conversation, | ||
// @ts-expect-error - mock | ||
response, | ||
}) | ||
|
||
expect(mockCache.set).toHaveBeenCalledTimes(1) | ||
expect(mockCache.set).toHaveBeenCalledWith( | ||
expect.stringContaining(`workspace:${workspace.id}:prompt:`), | ||
JSON.stringify(response), | ||
) | ||
}) | ||
|
||
it('silently fails when cache throws error', async () => { | ||
mockCache.set.mockRejectedValueOnce(new Error('Cache error')) | ||
|
||
await expect( | ||
setCachedResponse({ | ||
workspace, | ||
config, | ||
conversation, | ||
// @ts-expect-error - mock | ||
response, | ||
}), | ||
).resolves.toBeUndefined() | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.