Repository navigation
[PR] feat: host-side conversation delete co-deletes compression artifacts (#2935) - #2937
ranxianglei wants to merge 12 commits into
Conversation
📦 Built Package ArtifactBranch: Latest build — install this exact versionnpm install -g billion-context@0.0.6205-pr.2937.7df24f7This exact version is immutable and reproducible. The rolling Recent builds (commit → version)
Download artifact
tar xzf billion-context-pr2937.tgz
npm install -g packageInstall instructions are refreshed on each push. |
3d6f964 to
af6e2d9
Compare
[bot] 🏷 冲突已解决,分支已核对。PR #2937(head 现为 本轮做了什么
代码核对(对照 PR 描述逐项):一致。 本地证据(定向验证,全量回归交给 CI):typecheck ✓ · build ✓ · issue2935 套件 4/4 ✓ · master 侧相关套件 fork-nudge-deadzone 3/3 ✓、session-transient-memory 5/5 ✓(plugin.ts 合并文件的保险)· unused-exports gate ✓。 八问
CI:新 head 上 guards/kernel/lock/docs/config-surface/lane 全绿,e2e 各 lane(codex/dsh/opencode/pi/registry…)已过, 待你拍板(PR 正文遗留):host 端触发器(dsh 删会话时调 endpoint)刻意未接。①事件驱动:订阅 dsh |
[bot] 🏷 CI 全绿,收工确认。
结论:冲突已解、代码与描述逐项核对一致、无回归、无新配置面——可合并。合并按仓库规则由人来:#2937 唯一悬而未决项仍是上一条评论里的拍板题:host 端触发器选 ①(dsh |
…eletes a session Wires the host-side trigger for #2935: when the dsh host deletes a conversation, bili tears down that session's compression artifacts via POST /__bili/plugin/delete. Event-driven (zero false-positive): subscribes session/event deletion types plus the top-level session/deleted event; matches an evidence-permitlist of destructive spellings since the shim types the event payload unknown. Non-deletion events never touch the delete lane.
…storage drift) Rebased onto current master for the #2937 conflict wake. Master's storage layer now persists to a unified SQLite store (index.db) in addition to the legacy JSON envelope, and loadSync serves from the unified store when readsUnified is set. The original co-delete called store.removeSessionFiles(id, meta), which removed only the legacy/CCR files and left the unified rows behind, so the persisted record survived teardown and the #2935 regression test failed against current master. Switch deleteSessionArtifacts to store.removeSession(id) (#3928 full cascade: clears unified-store rows plus media/CAS refcounts AND the legacy files). This also removes the need to make removeSessionFiles public, so src/persist.ts is reverted to master-verbatim (no net change).
50fe619 to
09d5760
Compare
(ai: vllm-qwen/qwen3.8-27b) 冲突已解决并推送。 PR #2935 分支 按结构化问题作答:
注:master 在处理期间多次前进(我逐次 rebase 到最新 tip,最终落在 判定:冲突已清、本地验证绿,可进入 review / CI。 |
(ai: vllm-qwen/qwen3.8-27b) CI
判定:改动为单行、定向、已本地复跑门禁通过,符合 auto-fix 车道范围;新 head 的全量 CI 会做最终确认。 |
(ai: vllm-qwen/qwen3.8-27b) CI 判定:继承性失败(非本 PR 代码问题)——按 auto-fix 车道规则停手,等 master 修复后 rebase。
怎么解(需要 owner 的一个动作):合并 #4606。合并后 master 自身检查转绿,本 PR rebase 到 master 重触发即可全绿,分支侧无需任何改动。 补充:attempt 1 的 结论:这是继承自 master 的 LIVE_FILES tripwire 红,不是 #2935 的问题;等 #4606 合并后 rebase / 重触发即可,auto-fix 车道到此停手。 |
master window commits 293ae65/de5e03659 bumped kernel/package.json to 0.0.165 without regenerating the lockfiles; lock-sync re-resolution then rewrites the stale recorded versions (root 0.0.163, kernel 0.0.164) and fails. Pure recorded-version sync via npm install --package-lock-only; no dependency or semantic change.
Part of #2935
What
Lands the missing compression-artifact teardown mechanism for #2935 ("when the user deletes the original session, also delete the corresponding compressed session"), plus the dsh host-side trigger that fires it when the host deletes a conversation.
Previously no path existed at all to delete a session's compression artifacts (the opt-in
BILI_SESSION_GConly removes uncompressed files >7d old; compressed-session data had zero cleanup). A single conversation's artifacts are scattered across six co-lifecycle locations and nothing removed them together.Changes
src/session-delete.ts(new) —deleteSessionArtifacts(id): one routine tearing down every artifact bound to a session id: session file, lossless CCR content-store companion, image-spill dir, unified-store rows (+CAS refcount release), in-memory resident session, prefix-affinity chain. Compression-state-agnostic. Defers (not deletes) while a request is in-flight or a save is pending, so it never yanks a file out from under a live writer.POST /__bili/plugin/delete {conversationId}(src/plugin.ts+src/server/admin.ts) — generic, loopback+trusted-origin gated like every/__bili/plugin/*. Resolves the conversation's sessions: verbatim id + persona forks (<id>|sub:<fp>) cascade; independent child conversations (own ids) are left alone. Always returns200 {ok,conversationId,deleted[],deferred[]}even when empty.src/agent/dsh-native.ts— the host-side trigger (event-driven): on a dsh session-deletion event it POSTs the exact conversation id to the endpoint. Subscribes both shapes —session/eventwhosetypeis a destructive spelling, and the top-levelsession/deletedevent. Matches an evidence-permitlist of destructive spellings (session/deleted,session/removed,session/cleared,deleted,removed,cleared) because the shim types the event payloadunknown. Fire-and-forget, one-shot (no dedup/re-arm — the endpoint is idempotent and deletion is not retriable). Non-deletion events never touch the delete lane.src/persist.ts— extracted publicremoveSessionFiles(id, meta?)from the private legacy remover (same candidate set); reused by the new routine.PLUGIN.md §9; Teststests/issue2935-session-delete.test.ts(fork-prefix guard, full artifact teardown incl. disk/spill/memory/affinity, busy-defer, e2e rig: validation, real host-session cleanup via binding, fork cascade, sibling isolation) plus two new cases intests/dsh-native.test.ts(deletion events → teardown POST on both event shapes; non-deletion events leave the delete lane alone; permitlist predicate pin) — all green.Why event-driven (not reconcile-poll)
The issue's stated priority is preventing accidental deletion ("防止误删除"). Event-driven carries zero false-positive risk: it acts only on an explicit per-session signal from the host, so a wrong type guess degrades to a no-op rather than a spurious data delete. Reconcile-poll (diff remembered sids vs
ctx.sessions.list()) would be unsafe unlesslist()is guaranteed to return all sessions, not just currently-open ones — otherwise it would delete idle-but-not-deleted conversations' data.One residual (non-blocking)
The exact
typestring dsh emits on deletion is not discoverable in-repo (typedunknownin the shim; onlysession/titlereferenced anywhere; dsh source lives in a separate repo). The permitlist therefore covers the convention-consistent destructive spellings. If you confirm dsh's actual single spelling I will tighten the list to exactly that value (one-line change on this same branch).No web-UI delete is added (per the issue). No config surface added.
versionuntouched.Fixes #2935
(孤儿认领:标题本已指向 #2935,补上关闭关键字 —— 第三批清理)