(
prompt_id: string,
force: boolean = false,
)
| 762 | } |
| 763 | |
| 764 | async tryCompressChat( |
| 765 | prompt_id: string, |
| 766 | force: boolean = false, |
| 767 | ): Promise<ChatCompressionInfo | null> { |
| 768 | const curatedHistory = this.getChat().getHistory(true); |
| 769 | |
| 770 | // Regardless of `force`, don't do anything if the history is empty. |
| 771 | if (curatedHistory.length === 0) { |
| 772 | return null; |
| 773 | } |
| 774 | |
| 775 | const model = this.config.getModel(); |
| 776 | |
| 777 | const { totalTokens: originalTokenCount } = |
| 778 | await this.getContentGenerator().countTokens({ |
| 779 | model, |
| 780 | contents: curatedHistory, |
| 781 | }); |
| 782 | if (originalTokenCount === undefined) { |
| 783 | console.warn(`Could not determine token count for model ${model}.`); |
| 784 | return null; |
| 785 | } |
| 786 | |
| 787 | const contextPercentageThreshold = |
| 788 | this.config.getChatCompression()?.contextPercentageThreshold; |
| 789 | |
| 790 | // Don't compress if not forced and we are under the limit. |
| 791 | if (!force) { |
| 792 | const threshold = |
| 793 | contextPercentageThreshold ?? COMPRESSION_TOKEN_THRESHOLD; |
| 794 | if (originalTokenCount < threshold * tokenLimit(model)) { |
| 795 | return null; |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | let compressBeforeIndex = findIndexAfterFraction( |
| 800 | curatedHistory, |
| 801 | 1 - COMPRESSION_PRESERVE_THRESHOLD, |
| 802 | ); |
| 803 | // Find the first user message after the index. This is the start of the next turn. |
| 804 | while ( |
| 805 | compressBeforeIndex < curatedHistory.length && |
| 806 | (curatedHistory[compressBeforeIndex]?.role === 'model' || |
| 807 | isFunctionResponse(curatedHistory[compressBeforeIndex])) |
| 808 | ) { |
| 809 | compressBeforeIndex++; |
| 810 | } |
| 811 | |
| 812 | const historyToCompress = curatedHistory.slice(0, compressBeforeIndex); |
| 813 | const historyToKeep = curatedHistory.slice(compressBeforeIndex); |
| 814 | |
| 815 | this.getChat().setHistory(historyToCompress); |
| 816 | |
| 817 | const { text: summary } = await this.getChat().sendMessage( |
| 818 | { |
| 819 | message: { |
| 820 | text: 'First, reason in your scratchpad. Then, generate the <state_snapshot>.', |
| 821 | }, |
no test coverage detected