@@ -7,6 +7,7 @@ import { IMemoryService, MemoryToolProvider } from "../../Memory";
77import { IWikiService } from "../../Wiki" ;
88import { WikiToolProvider } from "../../Wiki" ;
99import { IAgentSaverService } from "../../Saver" ;
10+ import { ConversationCompactor , IConversationCompactor , METADATA_KEY_INPUT_TOKENS } from "../../Saver/ConversationCompactor" ;
1011import { IAgentToolService } from "../../AgentTool" ;
1112import { ILoggerService } from "../../Logger" ;
1213import { normalizeToMCPResult , MCPContentType , type MCPToolResult } from '../../Tools' ;
@@ -57,6 +58,7 @@ export class SingleAgentService extends AgentServiceBase {
5758 protected systemMessages : ChatMessage [ ] ;
5859 protected memorySystemPromptTemplate ?: string ;
5960 protected modelCallTimeout ?: number ;
61+ protected compactor ?: ConversationCompactor ;
6062
6163 constructor (
6264 @inject ( IModelService ) modelService : IModelService ,
@@ -70,6 +72,7 @@ export class SingleAgentService extends AgentServiceBase {
7072 @inject ( T_MemorySystemPromptTemplate , { optional : true } ) memorySystemPromptTemplate ?: string ,
7173 @inject ( T_WikiSystemPromptTemplate , { optional : true } ) protected wikiSystemPromptTemplate ?: string ,
7274 @inject ( T_ModelCallTimeout , { optional : true } ) modelCallTimeout ?: number ,
75+ @inject ( IConversationCompactor , { optional : true } ) compactor ?: ConversationCompactor ,
7376 ) {
7477 super ( loggerService , agentSaver , memoryServices ) ;
7578 this . modelService = modelService ;
@@ -78,6 +81,7 @@ export class SingleAgentService extends AgentServiceBase {
7881 this . systemMessages = ( systemPrompts ?? [ ] ) . map ( p => ( { role : MessageRole . System , content : p } ) ) ;
7982 this . memorySystemPromptTemplate = memorySystemPromptTemplate ;
8083 this . modelCallTimeout = modelCallTimeout ;
84+ this . compactor = compactor ;
8185 }
8286
8387 override addSystemPrompts ( prompts : string [ ] ) : void {
@@ -148,8 +152,19 @@ export class SingleAgentService extends AgentServiceBase {
148152 this . modelService . bindTools ( state . tools ) ;
149153 }
150154
155+ // 自动 compact:input_tokens 超过阈值时压缩早期消息
156+ const contextWindow = this . modelService . contextWindow ?? DEFAULT_MAX_HISTORY_TOKENS ;
157+ if ( this . compactor ) {
158+ const allMessages = await this . saverService . getAllMessages ( ) ;
159+ const savedTokens = parseInt ( await this . saverService . getMetadata ( METADATA_KEY_INPUT_TOKENS ) ?? '0' , 10 ) ;
160+ if ( this . compactor . shouldCompact ( savedTokens , allMessages , contextWindow ) ) {
161+ const result = await this . compactor . compact ( allMessages ) ;
162+ await this . saverService . replaceAllMessages ( result . messages ) ;
163+ }
164+ }
165+
151166 // 每次调用都从 saver 重新取(含 token 截断),防止多轮工具调用后 state.messages 超限
152- const savedHistory = await this . saverService . getMessages ( this . modelService . contextWindow ?? DEFAULT_MAX_HISTORY_TOKENS ) ;
167+ const savedHistory = await this . saverService . getMessages ( contextWindow ) ;
153168 if ( ! savedHistory || savedHistory . length === 0 ) {
154169 throw new Error ( 'historyMessages is empty, cannot call model' ) ;
155170 }
@@ -192,6 +207,9 @@ export class SingleAgentService extends AgentServiceBase {
192207 if ( ! lastChunk ) return { messages : [ ] } ;
193208
194209 if ( lastChunk . usage ) {
210+ if ( this . compactor ) {
211+ await this . saverService . setMetadata ( METADATA_KEY_INPUT_TOKENS , String ( lastChunk . usage . input_tokens ) ) ;
212+ }
195213 await callback ?. onUsage ?.( lastChunk . usage ) ;
196214 delete lastChunk . usage ;
197215 }
0 commit comments