diff --git a/packages/core/agent/src/index.ts b/packages/core/agent/src/index.ts index fc5ad371b4..6f6f3717fc 100644 --- a/packages/core/agent/src/index.ts +++ b/packages/core/agent/src/index.ts @@ -132,9 +132,6 @@ interface FactorySlot { */ export class AgentRegistry extends Service { private store = new Map() - // TODO(agent-entry-mirror): derive exact-object checks from store.get(agent.id) - // plus entry.agent identity; this WeakMap mirrors the authoritative id map. - private entries = new WeakMap() private factory: FactorySlot | undefined constructor(ctx: Context) { @@ -222,8 +219,9 @@ export class AgentRegistry extends Service { enter(agent: Agent): () => void { const id = agent.id const carrier = scopeTarget(agent, agent) - // Prepared transactions arbitrate identity at this publication boundary. - if (this.entries.has(agent) || this.store.has(id)) throw new Error(`agent "${id}" is already registered`) + // This is the authoritative collision boundary. Concurrent create/resume + // operations may both prepare, but only one exact entry can publish. + if (this.store.has(id)) throw new Error(`agent "${id}" is already registered`) const entry: AgentEntry = { id, agent, @@ -233,7 +231,6 @@ export class AgentRegistry extends Service { detachRequested: false, } this.store.set(id, entry) - this.entries.set(agent, entry) let entered = true const detach = (): void => { if (!entered) return @@ -256,7 +253,6 @@ export class AgentRegistry extends Service { /* v8 ignore next -- enter() rejects replacement while this single-shot detach capability is live. */ if (this.store.get(entry.id) !== entry) return this.store.delete(entry.id) - this.entries.delete(entry.agent) // An insertion rolled back before announce was never externally created, // so emitting disposed would invent an impossible lifecycle edge. Marking // happens before the created emit: if a later created listener throws, @@ -288,8 +284,8 @@ export class AgentRegistry extends Service { * creation listener). */ announce(agent: Agent): void { - const entry = this.entries.get(agent) - if (entry === undefined || this.store.get(entry.id) !== entry) { + const entry = this.store.get(agent.id) + if (entry === undefined || entry.agent !== agent) { throw new Error(`agent "${agent.id}" is not live in this registry`) } if (entry.announced || entry.announcing) { diff --git a/packages/sdk/helper/src/project/npm-dependency-policy.ts b/packages/sdk/helper/src/project/npm-dependency-policy.ts index a8877826e2..727bd6648a 100644 --- a/packages/sdk/helper/src/project/npm-dependency-policy.ts +++ b/packages/sdk/helper/src/project/npm-dependency-policy.ts @@ -23,7 +23,7 @@ const EXTERNAL_NPM_DEPENDENCY_SPECS: Readonly> = { '@cordisjs/plugin-timer': '^1.1.2', '@types/node': '^22.20.0', cordis: '^4.0.0-rc.7', - tsdown: '^0.22.2', + tsdown: '0.22.2', tsx: '^4.22.4', typescript: '^6.0.3', } diff --git a/packages/sdk/helper/tests/documents.spec.ts b/packages/sdk/helper/tests/documents.spec.ts index 1ba8b9bd68..1b8050b90f 100644 --- a/packages/sdk/helper/tests/documents.spec.ts +++ b/packages/sdk/helper/tests/documents.spec.ts @@ -282,6 +282,7 @@ describe('package manager strategies', () => { section: 'devDependencies', spec: '^4.0.0-rc.7', }) expect(resolveNpmDependency('@cordisjs/plugin-hmr', 'dependencies', '0.0.1').spec).toBe('^1.0.15') + expect(resolveNpmDependency('tsdown', 'devDependencies', '0.0.1').spec).toBe('0.22.2') expect(resolveNpmDependency('@deepseek-ai/dsh-tools', 'dependencies', '1.2.3').spec).toBe('^1.2.3') expect(() => resolveNpmDependency('unknown', 'dependencies', '0.0.1')).toThrow('no generated-project') }) diff --git a/website/zh-CN/api/harness/agents.md b/website/zh-CN/api/harness/agents.md index f6c9565d37..ef20c585d7 100644 --- a/website/zh-CN/api/harness/agents.md +++ b/website/zh-CN/api/harness/agents.md @@ -20,7 +20,7 @@ Register the effect-scoped creation factory, rejecting a duplicate. Service fact **Returns** the exact Cordis effect disposer. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L152) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L149) ### ctx.agents.create(options) @@ -34,7 +34,7 @@ Create and publish an owned agent and session through the active factory. Reject **Returns** the handle after setup, rollback-covered publication, and loop start complete. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L177) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L174) ### ctx.agents.resume(options) @@ -48,7 +48,7 @@ Load a persisted session and resume an agent on it through the registered factor **Returns** the handle after setup, rollback-covered publication, and loop start complete. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L193) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L190) ### ctx.agents.register(agent) @@ -62,7 +62,7 @@ Register a live agent in the calling effect scope, with scope-filtered creation **Returns** the exact Cordis effect disposer for nested teardown ordering. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L207) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L204) ### ctx.agents.enter(agent) @@ -76,7 +76,7 @@ Insert an unpublished agent for an ordered factory transaction. **Returns** an idempotent closure that removes this exact entry and emits the paired disposal edge; detachment during creation dispatch is deferred. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L222) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L219) ### ctx.agents.announce(agent) @@ -88,7 +88,7 @@ Announce an agent previously inserted with enter. - `agent` — the live inserted agent to announce. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L290) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L286) ### ctx.agents.get(id) @@ -102,7 +102,7 @@ Look up a live agent. **Returns** the agent, or undefined when no live agent has that id. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L324) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L320) ### ctx.agents.list() @@ -114,4 +114,4 @@ All live agents, in registration order. **Returns** a fresh array; mutating it does not affect the registry. -[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L332) +[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L328)