Skip to content

fix(events): mark team session events ignorable so history survives unknown readers - #7

Open
EthanHuangEbor wants to merge 1 commit into
NanmiCoder:mainfrom
EthanHuangEbor:fix/mark-team-events-ignorable
Open

fix(events): mark team session events ignorable so history survives unknown readers#7
EthanHuangEbor wants to merge 1 commit into
NanmiCoder:mainfrom
EthanHuangEbor:fix/mark-team-events-ignorable

Conversation

@EthanHuangEbor

Copy link
Copy Markdown

fix(events): mark team session events ignorable so history survives unknown readers

Problem

Any session that runs AgentTeams becomes un-loadable afterwards. Opening that
session's history fails with:

SessionFormatUnsupportedError: session "…" contains event type
"agent-teams/team-created" (seq 25009) unknown to this harness and not marked
ignorable; refusing to interpret the log — it was likely written by a newer
harness (raw log: …/session.jsonl.zstd)

The whole session history is refused, not just the team events.

Root cause

appendTeamEvent records team state into the captain's Session via
session.append(type, data) for seven custom event types:

agent-teams/team-created, agent-teams/member-added,
agent-teams/member-removed, agent-teams/task-created,
agent-teams/task-updated, agent-teams/message-sent,
agent-teams/team-deleted.

These are downstream / out-of-repo types, so they are — by design — outside
the harness core's static KNOWN_SESSION_EVENT_TYPES catalog
(@deepseek-ai/dsh-session/known-event-types). The persistence read path
(assertEventsSupported) therefore refuses any log containing a type it does
not recognize unless the event carries the envelope's ignorable: true
marker.

That marker exists on the read side (SessionEvent.ignorable), but the harness
core's Session.append currently has no write-side support for emitting it, so
our events are written as required. A reader that does not know the type then
has to refuse the entire log rather than skip the informational record.

Why ignorable is correct here

Team events are purely informational for the conversation tree view. The
authoritative team state is already durably persisted separately under
.agent-teams/, so losing or skipping these events can never corrupt session
reconstruction. They are exactly the "purely informational records" the
ignorable marker was designed for.

Change

In src/events.ts, emit every team event with the marker:

session.append(type, data, { ignorable: true })

Dependency

This relies on the harness core accepting ignorable in Session.append.
Today the option is silently dropped at runtime and rejected by the TypeScript
signature for non-surface types
(...opts: T extends SurfaceEventType ? [opts: SurfaceIntent] : []). A
companion change on the harness side is required so the marker is actually
written and type-checks. See the corresponding deepseek-harness issue.

Testing

Reproduced against a real session log containing 40 agent-teams/* events
(first at seq 25009):

  • Before: the harness's own decode path
    (decodeStorageRecord + adoptSessionEvent + KNOWN_SESSION_EVENT_TYPES)
    reports 40 unsupported events → the log is refused.
  • After marking the events ignorable, the same replay decodes all
    128,664 events with 0 unsupported → the log loads cleanly.
  • node --check passes on the compiled output.

No behavior change for readers that do recognize the types: the web client's
agent-teams card matches on event.type and still renders identically.

agent-teams/* types are downstream/out-of-repo, so they are outside the
harness core's known-event catalog. Mark each team event ignorable so a
reader that does not recognize the type skips the informational record
instead of refusing the whole session log with SessionFormatUnsupportedError.
Team state is also durably persisted under .agent-teams/, so these records
are safe to skip.
@NanmiCoder

NanmiCoder commented Aug 14, 2026

Copy link
Copy Markdown
Owner

感谢贡献,问题判断是正确的。

不过官方目前还不支持通过 Session.append 写入 ignorable,这个参数会被类型检查拒绝,运行时也不会真正写入。

我们已在 18701c9 中通过跳过未知事件避免新日志损坏,因此这个 PR 暂时不需要合并。等官方提供正式接口后再采用这个方案。

@uluckystar

Copy link
Copy Markdown

harness 侧的 ignorable 写入面已经就绪了,这个方案现在可以落地 👇

背景:官方 harness 的 Session.append() 此前只对 surface 事件开放 opts,非 surface 事件(正是 agent-teams/* 的位置)无法传入 { ignorable: true }——这正是 #8 的根因,也是当前"harness 不认识就跳过写入"这个 workaround 存在的原因。

进展:我们已在本地给 harness 的 Session.append 增加了非 surface 事件的 { ignorable?: true } opts(事件信封带上标记后,读取端本就支持),并已向官方仓库提交 Discussion 建议采纳(deepseek-ai/deepseek-harness 讨论区)。等官方合入后,本插件可以从"跳过写入"升级为"带 ignorable: true 写入"——团队事件继续留在会话历史里(GUI 面板照常可用),且任意版本的 harness 读取端都不会拒读。

另外 #19 的存量日志迁移工具已提交 PR(#21),旧日志可一键修复。

如果官方写入面合入,我可以接着提一个把 appendTeamEvent 切换到 session.append(type, data, { ignorable: true }) 的 PR。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants