Răsfoiți Sursa

fix(e2e): decode packed history records

kingwl 3 săptămâni în urmă
părinte
comite
4f02717ebc

+ 17 - 11
apps/cli/tests/github-webhook-real.e2e.ts

@@ -11,6 +11,7 @@ import { tmpdir } from 'node:os'
 import { join } from 'node:path'
 import { setTimeout as delay } from 'node:timers/promises'
 import { fileURLToPath } from 'node:url'
+import { decodeStorageRecord } from '@deepseek-ai/dsh-session/chunk-rows'
 import { describe, expect, it } from 'vitest'
 import WebSocket from 'ws'
 
@@ -59,15 +60,15 @@ interface WorkspaceBaseline {
 }
 
 interface HistoryPage {
-  events: Array<{
-    event: {
-      type: string
-      data: unknown
-    }
-  }>
+  records: Array<{ event: HistoryEvent } | { chunks: unknown }>
   hasMore: boolean
 }
 
+interface HistoryEvent {
+  type: string
+  data: unknown
+}
+
 interface ProcessObservation {
   readonly ready: Promise<string>
   readonly text: () => string
@@ -255,10 +256,10 @@ async function history(baseUrl: string, sessionId: string): Promise<HistoryPage>
     { request: { address: { kind: 'session', sessionId }, maxMessages: 100 } },
     value => isRecord(value)
       && value.type === 'snapshot'
-      && Array.isArray(value.events)
+      && Array.isArray(value.records)
       && typeof value.hasMore === 'boolean',
   )
-  return { events: frame.events as HistoryPage['events'], hasMore: frame.hasMore as boolean }
+  return { records: frame.records as HistoryPage['records'], hasMore: frame.hasMore as boolean }
 }
 
 /** Poll a public observation until it satisfies the test's behavior predicate. */
@@ -294,7 +295,7 @@ async function eventually<T>(
 /** Return every text block from durable assistant messages. */
 function assistantText(page: HistoryPage): string {
   const text: string[] = []
-  for (const { event } of page.events) {
+  for (const event of historyEvents(page)) {
     if (event.type !== 'assistant/message' || !isRecord(event.data) || !isRecord(event.data.message)) continue
     const content = event.data.message.content
     if (!Array.isArray(content)) continue
@@ -305,6 +306,11 @@ function assistantText(page: HistoryPage): string {
   return text.join('\n')
 }
 
+/** Expand lossless history records for assertions over the public event stream. */
+function historyEvents(page: HistoryPage): HistoryEvent[] {
+  return page.records.flatMap(record => 'event' in record ? [record.event] : decodeStorageRecord(record.chunks))
+}
+
 /** Stop the spawned CLI through its normal signal path, escalating only on a stuck teardown. */
 async function stop(child: ChildProcess): Promise<void> {
   if (child.exitCode !== null) return
@@ -410,7 +416,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('GitHub webhook through the real
         'webhook provenance, title, and permission events',
         async () => await history(baseUrl, sessionId),
         (page) => {
-          const events = page.events.map(item => item.event)
+          const events = historyEvents(page)
           const title = events.find(event => event.type === 'session/title')
           const permission = events.find(event =>
             event.type === 'permission/preset'
@@ -429,7 +435,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('GitHub webhook through the real
         },
         30_000,
       )
-      const webhookMessage = admitted.events.map(item => item.event)
+      const webhookMessage = historyEvents(admitted)
         .find(event => event.type === 'user/message'
           && isRecord(event.data)
           && isRecord(event.data.source)

+ 1 - 1
docs/event-producer-consumer.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write docs/event-producer-consumer.md
-event-producer-consumer.md: 6f971f5470c34093dd3774650ad191f9a3516df7
+event-producer-consumer.md: ce914f90821adc09c59dca15f202831a51655565
 event-producer-consumer.zh.md: ca375c98b6c0552f255e5d2604c9ad0c1d968aad

+ 5 - 5
docs/event-producer-consumer.md

@@ -21,11 +21,11 @@ This matrix shows which packages dispatch each harness-owned event and which pac
 | `agent/session-start` | `emit` | [`packages/core/agent/src/runtime-types.ts:224`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | `agent-team`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
 | `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:185`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server`, `session-controller` |
 | `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:285`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
-| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:482`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
-| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:462`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
-| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:489`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
-| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:468`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
-| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:475`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
+| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:491`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
+| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:471`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
+| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:498`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
+| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:477`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
+| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:484`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
 | `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:85`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes` |
 | `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | [`authorization`](../packages/credentials/authorization) |
 | `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:80`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `remotes` |

+ 1 - 1
docs/persistence-catalog.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write docs/persistence-catalog.md
-persistence-catalog.md: 12558eeadc009b498c9a178cfcc79116bf1b7c2b
+persistence-catalog.md: 7c63cd8dfdb181fac09cf3ce2e4bcec96d2bd59c
 persistence-catalog.zh.md: f855d6969aa2dcade159ac8d6549e5f0350a7f0f

+ 1 - 1
docs/persistence-catalog.md

@@ -512,7 +512,7 @@ Source: [`packages/llm/llm-retry/src/types.ts:11`](../packages/llm/llm-retry/src
 'model/selection': ModelSelection
 ```
 
-Source: [`packages/api/session-controller/src/types.ts:39`](../packages/api/session-controller/src/types.ts)
+Source: [`packages/api/session-controller/src/types.ts:40`](../packages/api/session-controller/src/types.ts)
 
 ### `permission/*`