@@ -190,39 +190,107 @@ export const myChat = chat.task({
190190});
191191```
192192
193- ## Low-level compaction
193+ ## Using with chat.createSession()
194194
195- For ` chat.createSession() ` or raw task mode, use ` chat.compact () ` and ` chat.compactionStep() ` directly inside a custom ` prepareStep ` :
195+ Pass the same ` compaction ` config to ` chat.createSession () ` . The session handles outer-loop compaction automatically inside ` turn.complete() ` :
196196
197197``` ts
198- const result = streamText ({
199- model: openai (" gpt-4o" ),
200- messages ,
201- prepareStep : async ({ messages : stepMessages , steps }) => {
202- const result = await chat .compact (stepMessages , steps , {
203- threshold: 80_000 ,
204- summarize : async (msgs ) =>
205- generateText ({ model: openai (" gpt-4o-mini" ), messages: msgs }).then ((r ) => r .text ),
206- });
207- return result .type === " skipped" ? undefined : result ;
198+ const session = chat .createSession (payload , {
199+ signal ,
200+ idleTimeoutInSeconds: 60 ,
201+ timeout: " 1h" ,
202+ compaction: {
203+ shouldCompact : ({ totalTokens }) => (totalTokens ?? 0 ) > 80_000 ,
204+ summarize : async ({ messages }) =>
205+ generateText ({ model: openai (" gpt-4o-mini" ), messages }).then ((r ) => r .text ),
206+ compactUIMessages : ({ uiMessages , summary }) => [
207+ { id: generateId (), role: " assistant" ,
208+ parts: [{ type: " text" , text: ` [Summary]\n\n ${summary } ` }] },
209+ ... uiMessages .slice (- 4 ),
210+ ],
208211 },
209212});
213+
214+ for await (const turn of session ) {
215+ const result = streamText ({
216+ model: openai (" gpt-4o" ),
217+ messages: turn .messages ,
218+ abortSignal: turn .signal ,
219+ });
220+
221+ await turn .complete (result );
222+ // Outer-loop compaction runs automatically after complete()
223+
224+ await db .chat .update ({
225+ where: { id: turn .chatId },
226+ data: { messages: turn .uiMessages },
227+ });
228+ }
210229```
211230
212- Or use the higher-level ` chat.compactionStep() ` factory:
231+ ## Using with raw tasks (MessageAccumulator)
232+
233+ Pass ` compaction ` to the ` MessageAccumulator ` constructor. Use ` prepareStep() ` for inner-loop compaction and ` compactIfNeeded() ` for the outer loop:
213234
214235``` ts
215- const result = streamText ({
216- model: openai (" gpt-4o" ),
217- messages ,
218- prepareStep: chat .compactionStep ({
236+ const conversation = new chat .MessageAccumulator ({
237+ compaction: {
238+ shouldCompact : ({ totalTokens }) => (totalTokens ?? 0 ) > 80_000 ,
239+ summarize : async ({ messages }) =>
240+ generateText ({ model: openai (" gpt-4o-mini" ), messages }).then ((r ) => r .text ),
241+ compactUIMessages : ({ summary }) => [
242+ { id: generateId (), role: " assistant" ,
243+ parts: [{ type: " text" , text: ` [Summary]\n\n ${summary } ` }] },
244+ ],
245+ },
246+ });
247+
248+ for (let turn = 0 ; turn < 100 ; turn ++ ) {
249+ const messages = await conversation .addIncoming (payload .messages , payload .trigger , turn );
250+
251+ const result = streamText ({
252+ model: openai (" gpt-4o" ),
253+ messages ,
254+ prepareStep: conversation .prepareStep (), // Inner-loop compaction
255+ });
256+
257+ const response = await chat .pipeAndCapture (result );
258+ if (response ) await conversation .addResponse (response );
259+
260+ // Outer-loop compaction
261+ const usage = await result .totalUsage ;
262+ await conversation .compactIfNeeded (usage , { chatId: payload .chatId , turn });
263+
264+ await db .chat .update ({ data: { messages: conversation .uiMessages } });
265+ await chat .writeTurnComplete ();
266+ }
267+ ```
268+
269+ ## Fully manual compaction
270+
271+ For maximum control, use ` chat.compact() ` directly inside a custom ` prepareStep ` :
272+
273+ ``` ts
274+ prepareStep : async ({ messages : stepMessages , steps }) => {
275+ const result = await chat .compact (stepMessages , steps , {
219276 threshold: 80_000 ,
220277 summarize : async (msgs ) =>
221278 generateText ({ model: openai (" gpt-4o-mini" ), messages: msgs }).then ((r ) => r .text ),
222- }),
223- });
279+ });
280+ return result .type === " skipped" ? undefined : result ;
281+ },
282+ ```
283+
284+ Or use the ` chat.compactionStep() ` factory:
285+
286+ ``` ts
287+ prepareStep : chat .compactionStep ({
288+ threshold: 80_000 ,
289+ summarize : async (msgs ) =>
290+ generateText ({ model: openai (" gpt-4o-mini" ), messages: msgs }).then ((r ) => r .text ),
291+ }),
224292```
225293
226294<Note >
227- The low-level APIs only handle inner-loop compaction (between tool-call steps). For full coverage including single-step turns , use the ` compaction ` option on ` chat.task() ` .
295+ The fully manual APIs only handle inner-loop compaction (between tool-call steps). For outer-loop coverage , use the ` compaction ` option on ` chat.task() ` , ` chat.createSession() ` , or ` MessageAccumulator ` .
228296</Note >
0 commit comments