Просмотр исходного кода

Merge branch 'codex/simp-agent-entry-state' into codex/simp-unify-agent-session-id

Tianyi Cui 2 месяцев назад
Родитель
Сommit
d6ba1fef26

+ 5 - 1
packages/compact/compact-basic/src/index.ts

@@ -426,9 +426,13 @@ export class BasicCompactService extends CompactService {
       // compact/start and here leaves a detectable orphaned lock (a compact/start
       // with no matching compact/end) rather than a compact/end that falsely
       // claims compaction finished before the surface replacement landed.
-      session.append('compact/end', { turn: openTurn })
+      const endEvent = session.append('compact/end', { turn: openTurn })
 
       return {
+        startSeq: startEvent.seq,
+        summarySeq: summaryEvent.seq,
+        endSeq: endEvent.seq,
+        summary,
         shadowedRange: { start, end },
         shadowedSeqs,
         shadowedTokenCount,

+ 3 - 1
packages/compact/compact-basic/tests/compact-basic.spec.ts

@@ -346,6 +346,7 @@ describe('BasicCompactService.compactRegion', () => {
     expect(result.shadowedSeqs).toEqual([firstSeq, secondSeq])
     expect(result.shadowedRange.start).toBe(firstSeq)
     expect(result.shadowedRange.end).toBe(secondSeq)
+    expect(result.summary).toEqual(svc.mockSummary)
     expect(result.shadowedTokenCount).toBe(20)
 
     const events = session.events
@@ -1057,7 +1058,8 @@ describe('BasicCompactService.summarize (real ctx.llm.stream)', () => {
     const session = multiTurnSession(2, 1)
     const nodes = session.surface.nodes
 
-    await compactRegion(svc, session, nodes[0]!, nodes[1]!, 'test-model')
+    const result = await compactRegion(svc, session, nodes[0]!, nodes[1]!, 'test-model')
+    expect(result.summary).toEqual([{ type: 'text', text: 'CONDENSED' }])
     const summaryEvent = session.events.findLast(e => e.type === 'compact/summary')!
     expect(summaryEvent.data.summary).toEqual([{ type: 'text', text: 'CONDENSED' }])
     // The raw summary is wrapped in the checkpoint framing on the surface.

+ 1 - 1
packages/compact/compact/src/index.ts

@@ -73,7 +73,7 @@ export abstract class CompactService extends Service {
    * @param agent - context whose session is mutated and whose routing options guide summarization.
    * @param signal - optional cancellation; model-backed implementations must forward it.
    * @throws when compaction is active or the range is missing, reversed, or unbalanced.
-   * @returns the replaced range and token accounting; the durable event owns the summary.
+   * @returns the appended event seqs, summary, replaced range, and token accounting.
    */
   abstract compactRegion(
     start: number,

+ 8 - 0
packages/compact/compact/src/types.ts

@@ -41,6 +41,14 @@ declare module '@deepseek-ai/dsh-session' {
 
 /** Result of a successful compaction operation. */
 export interface CompactionResult {
+  /** The seq of the appended `compact/start` event. */
+  startSeq: number
+  /** The seq of the appended `compact/summary` event. */
+  summarySeq: number
+  /** The seq of the appended `compact/end` event. */
+  endSeq: number
+  /** The summary content blocks produced by the backend. */
+  summary: ContentBlock[]
   /**
    * The surface-boundary pair that was shadowed: the seqs of the first
    * (`start`) and last (`end`) surface nodes of the replaced range. A

+ 12 - 4
packages/compact/compact/tests/compact.spec.ts

@@ -34,17 +34,22 @@ class StubCompactService extends CompactService {
   ): Promise<CompactionResult> {
     this.lastSignal = signal
     const session = agent.session
+    const summary = [{ type: 'text' as const, text: 'stub' }]
     // Minimal stub honoring the lock + log-only event contract.
-    session.append('compact/start', { turn: 0 })
-    session.append('compact/summary', {
-      summary: [{ type: 'text', text: 'stub' }],
+    const startEvent = session.append('compact/start', { turn: 0 })
+    const summaryEvent = session.append('compact/summary', {
+      summary,
       shadowedRange: { start, end },
       shadowedSeqs: [],
       shadowedTokenCount: 0,
       model: 'stub',
     })
-    session.append('compact/end', { turn: 0 })
+    const endEvent = session.append('compact/end', { turn: 0 })
     return {
+      startSeq: startEvent.seq,
+      summarySeq: summaryEvent.seq,
+      endSeq: endEvent.seq,
+      summary,
       shadowedRange: { start, end },
       shadowedSeqs: [],
       shadowedTokenCount: 0,
@@ -92,6 +97,9 @@ describe('CompactService seam', () => {
     // verify the runtime value is absent.
     const raw = startEvent as unknown as { surfaceOp?: unknown }
     expect(raw.surfaceOp).toBeUndefined()
+    expect(result.summary).toEqual([{ type: 'text', text: 'stub' }])
+    expect(result.summarySeq).toBeGreaterThan(result.startSeq)
+    expect(result.endSeq).toBeGreaterThan(result.summarySeq)
     expect(result.shadowedRange).toEqual({ start: 0, end: 0 })
     expect(session.events.filter(e => e.type.startsWith('compact/')).map(e => e.type))
       .toEqual(['compact/start', 'compact/summary', 'compact/end'])