Replies: 4 comments 1 reply
|
I hit this same wall from the plugin side while building out-of-tree plugins, so here is what the mechanism actually is — read out of the tree at the commit you quoted ( One writer per session, enforced in two layers
Both raise the same Only a write open claims. The read branch of ( So the error means: an activation for that session already exists and is holding the handle. Your sequence — DSH opened the session, then your plugin resumed — is precisely the case that comment names. Why "just opening" claims it. The asymmetry that bites plugin authors. The Host API's resolve path returns an already-live agent before it attempts anything ( What a plugin can do today (first-party precedents, all in-tree) const live = ctx.agents.get(id) // public: AgentRegistry.get
if (live !== undefined) live.followup(message) // deliver to the live agent — no write claim
else await ctx.agents.resume(ctx, { resumeSessionId: id, ... }) // safe: nobody holds it
That is your "claim only when you actually run" — it already exists at the agent-object level; what does not exist is a Which of the two layers you are on (they produce the same message): at the moment of failure, is
Boundary on the core side. There is no read-only live-open path: every activation claims write up front, by design, and nothing today lets a plugin make the UI release it. Your proposal — claim on prompt rather than on open — is therefore a core change (either a lazily-claimed write, or a genuinely read-only follow path), and that is worth stating explicitly as the ask if this becomes an upstream report. The plugin-side pattern only protects the plugin's own resume; it cannot make "just looking" free. On the observability half: One fact would sharpen this a lot: does your trigger run inside the |
|
Two corrections to what I wrote above, and a plugin that removes the wall. Correction 1 — await ctx.agents.resume({ // packages/core/agent/src/index.ts:407
resumeSessionId: id,
agentOptions: ctx.agentDefaultModel.currentSelection(), // optional; this is what the Host API passes
setup: composition.setup, // optional
})Checked against the canonical call site ( Correction 2 — the diagnostic sentence about "which layer" needed a sharper form, now that I have read A plugin now exists for this gap.
import { deliverToSession } from '@argszero/cordis-plugin-session-trigger'
const { path } = await deliverToSession({ agents: ctx.agents }, { sessionId, message })
// 'live' | 'live-after-race' | 'resumed'
Mounted ( The package imports no Its suite runs against a real The boundary, stated plainly: this makes your plugin's delivery robust. It does not make "just looking" free. Nothing in the harness today releases the claim an activation takes on open, so if the ask is "the UI should not claim a session merely because it is displayed", that is still a core change — the plugin only stops plugin authors from being the casualty of it. |
|
A correction to my own announcement above, and a fix: 0.1.0 could not be installed. If you followed the link and ran The built Fixed in 0.1.1 (npm
Verified on 0.1.1: 18/18 tests (15 behaviour + 3 guard); the guard fails on the real 0.1.0 defect and passes on the fix; the packed tarball installs and imports cleanly; and the 15 behaviour tests pass against the installed artifact, with the import resolving to The by-name install is now the leading check, not the tarball: The plugin's behaviour is unchanged from what I described above — this was a packaging defect, not a logic one. Apologies for the broken first version. (If you would like the same check for your own package before publishing: the scan is ~80 lines and depends on nothing but |
|
@argszero My plugin runs inside the dsh host process. This is really helpful, thanks a lot! |
Uh oh!
There was an error while loading. Please reload this page.
我有一个DSH插件,触发运行后会dispose;
然后如果在DSH里打开这个session,只是打开,什么都不做;
然后插件触发resume就会报错:session "dsh-xxxxxx-032b77e23bc41872" is already owned by an active write handle
分析了下是DSH打开session时就占了写锁session.lock,感觉这个不合理,打开session只是看看,应该是发送prompt时再去占session.lock比较合理点。
以下是codex的分析:
结论:我按远端 master 的最新源码核对后,DSH 仍是之前的逻辑。
正常打开 session 的链路是:
所以:
因此,之前判断仍成立:插件持有 reservation 时,DSH 可以先显示 session snapshot,但后台激活会失败并提示 session/writer-held;要让 DSH 真正“只读打开”,仍需要 DSH 提供或使用 read-only open 模式。
All reactions