fix(coding-agent): prevented race condition in concurrent createAgentSession calls

- Export AgentRegistry from the SDK to allow passing a private registry instance.
- Provide a dedicated AgentRegistry per in-process client in the benchmark runner.
This commit is contained in:
can1357
2026-07-30 06:03:32 +02:00
parent 00fedcf6ac
commit a6001c04a3
3 changed files with 11 additions and 0 deletions
+1
View File
@@ -22,6 +22,7 @@
### Fixed
- Fixed concurrent `createAgentSession` calls with the default agent id failing initialization with `Agent "Main" was replaced during session initialization` — each in-process embedder (e.g. the edit benchmark runner) can now pass a private registry via the newly exported `AgentRegistry`, keeping every top-level session's "Main" out of the process-global roster race.
- Fixed task tool blocks duplicating their per-agent progress rows into terminal scrollback on every update: live task frames now pin the transcript live region so mid-run rows are never recorded as frozen snapshots, and a detached background task freezes its progress the moment any of its rows commit to scrollback instead of mutating committed history.
- Fixed Codex reset fireworks comparing different quota tiers or plans, preventing false celebrations when usage reports switch between Spark and base weekly limits.
- Fixed Cursor ranged-read results losing the full file byte size after applying the requested window.
+4
View File
@@ -609,6 +609,10 @@ export type * from "./extensibility/extensions";
export type { Skill } from "./extensibility/skills";
export type { FileSlashCommand } from "./extensibility/slash-commands";
export type { MCPManager, MCPServerConfig, MCPServerConnection, MCPToolsLoadResult } from "./mcp";
// Agent registry: pass a private instance per `createAgentSession` when
// embedding several concurrent top-level sessions in one process (the default
// global registry admits only one "Main" per process generation).
export { type AgentRef, AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry";
export type { Tool } from "./tools";
export { buildDirectoryTree, buildWorkspaceTree, type DirectoryTree, type WorkspaceTree } from "./workspace-tree";
@@ -9,6 +9,7 @@ import type { AgentEvent, AgentMessage, ResolvedThinkingLevel, ThinkingLevel } f
import type { Model, ToolExample } from "@oh-my-pi/pi-ai";
import type { AgentSession, AgentSessionEvent, AuthStorage, SessionStats } from "@oh-my-pi/pi-coding-agent";
import {
AgentRegistry,
type CreateAgentSessionResult,
createAgentSession,
discoverAuthStorage,
@@ -97,6 +98,11 @@ export class InProcessClient {
authStorage: shared?.authStorage,
modelRegistry: shared?.modelRegistry,
sessionManager: SessionManager.inMemory(this.#options.cwd),
// Benchmark tasks run many top-level sessions concurrently in one
// process. The global registry admits only one "Main" per process
// generation (later registrations replace earlier refs, which then
// fail session initialization), so each client gets its own registry.
agentRegistry: new AgentRegistry(),
systemPrompt: this.#options.appendSystemPrompt
? (defaultPrompt: string[]) => [...defaultPrompt, this.#options.appendSystemPrompt!]
: undefined,