From 9e18139b162453c96f7fa6878ee628665638fa7d Mon Sep 17 00:00:00 2001 From: HiranoMasaaki Date: Mon, 16 Feb 2026 05:41:31 +0000 Subject: [PATCH 1/3] refactor: rename SingleRunExecutor to CoordinatorExecutor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Better naming symmetry with DelegationExecutor — "Coordinator" vs "Delegation" clearly conveys the contrasting roles. Co-Authored-By: Claude Opus 4.6 --- ...r.test.ts => coordinator-executor.test.ts} | 28 +++++++++---------- ...un-executor.ts => coordinator-executor.ts} | 12 ++++---- packages/runtime/src/orchestration/index.ts | 8 +++--- packages/runtime/src/run.test.ts | 4 +-- packages/runtime/src/run.ts | 6 ++-- 5 files changed, 29 insertions(+), 29 deletions(-) rename packages/runtime/src/orchestration/{single-run-executor.test.ts => coordinator-executor.test.ts} (89%) rename packages/runtime/src/orchestration/{single-run-executor.ts => coordinator-executor.ts} (93%) diff --git a/packages/runtime/src/orchestration/single-run-executor.test.ts b/packages/runtime/src/orchestration/coordinator-executor.test.ts similarity index 89% rename from packages/runtime/src/orchestration/single-run-executor.test.ts rename to packages/runtime/src/orchestration/coordinator-executor.test.ts index f8952426..3eead3bd 100644 --- a/packages/runtime/src/orchestration/single-run-executor.test.ts +++ b/packages/runtime/src/orchestration/coordinator-executor.test.ts @@ -1,6 +1,6 @@ import type { Checkpoint, Expert, RunSetting } from "@perstack/core" import { describe, expect, it, vi } from "vitest" -import { SingleRunExecutor } from "./single-run-executor.js" +import { CoordinatorExecutor } from "./coordinator-executor.js" // Mock dependencies vi.mock("../helpers/index.js", () => ({ @@ -105,15 +105,15 @@ const createMockCheckpoint = (overrides?: Partial): Checkpoint => ...overrides, }) as Checkpoint -describe("@perstack/runtime: single-run-executor", () => { - describe("SingleRunExecutor", () => { +describe("@perstack/runtime: coordinator-executor", () => { + describe("CoordinatorExecutor", () => { it("can be instantiated with no options", () => { - const executor = new SingleRunExecutor() + const executor = new CoordinatorExecutor() expect(executor).toBeDefined() }) it("can be instantiated with options", () => { - const executor = new SingleRunExecutor({ + const executor = new CoordinatorExecutor({ shouldContinueRun: async () => true, storeCheckpoint: async () => {}, eventListener: () => {}, @@ -123,7 +123,7 @@ describe("@perstack/runtime: single-run-executor", () => { }) it("executes and returns run result with checkpoint", async () => { - const executor = new SingleRunExecutor() + const executor = new CoordinatorExecutor() const setting = createMockSetting() const result = await executor.execute(setting) @@ -138,7 +138,7 @@ describe("@perstack/runtime: single-run-executor", () => { it("creates initial checkpoint when no checkpoint provided", async () => { const { createInitialCheckpoint } = await import("../helpers/index.js") - const executor = new SingleRunExecutor() + const executor = new CoordinatorExecutor() const setting = createMockSetting() await executor.execute(setting) @@ -148,7 +148,7 @@ describe("@perstack/runtime: single-run-executor", () => { it("creates next step checkpoint when checkpoint provided", async () => { const { createNextStepCheckpoint } = await import("../helpers/index.js") - const executor = new SingleRunExecutor() + const executor = new CoordinatorExecutor() const setting = createMockSetting() const checkpoint = createMockCheckpoint() @@ -159,7 +159,7 @@ describe("@perstack/runtime: single-run-executor", () => { it("emits init event when eventListener is provided", async () => { const eventListener = vi.fn() - const executor = new SingleRunExecutor({ eventListener }) + const executor = new CoordinatorExecutor({ eventListener }) const setting = createMockSetting() await executor.execute(setting) @@ -170,7 +170,7 @@ describe("@perstack/runtime: single-run-executor", () => { }) it("does not emit init event when eventListener is not provided", async () => { - const executor = new SingleRunExecutor() + const executor = new CoordinatorExecutor() const setting = createMockSetting() // Should not throw @@ -179,7 +179,7 @@ describe("@perstack/runtime: single-run-executor", () => { it("passes isDelegatedRun flag to getSkillManagers", async () => { const { getSkillManagers } = await import("../skill-manager/index.js") - const executor = new SingleRunExecutor() + const executor = new CoordinatorExecutor() const setting = createMockSetting() const checkpoint = createMockCheckpoint({ delegatedBy: { @@ -205,7 +205,7 @@ describe("@perstack/runtime: single-run-executor", () => { it("passes resolveExpertToRun to setupExperts", async () => { const { setupExperts } = await import("../helpers/index.js") const resolveExpertToRun = vi.fn().mockResolvedValue({} as Expert) - const executor = new SingleRunExecutor({ resolveExpertToRun }) + const executor = new CoordinatorExecutor({ resolveExpertToRun }) const setting = createMockSetting() await executor.execute(setting) @@ -216,7 +216,7 @@ describe("@perstack/runtime: single-run-executor", () => { it("passes shouldContinueRun to executeStateMachine", async () => { const { executeStateMachine } = await import("../state-machine/index.js") const shouldContinueRun = vi.fn().mockResolvedValue(true) - const executor = new SingleRunExecutor({ shouldContinueRun }) + const executor = new CoordinatorExecutor({ shouldContinueRun }) const setting = createMockSetting() await executor.execute(setting) @@ -231,7 +231,7 @@ describe("@perstack/runtime: single-run-executor", () => { it("passes storeCheckpoint to executeStateMachine", async () => { const { executeStateMachine } = await import("../state-machine/index.js") const storeCheckpoint = vi.fn() - const executor = new SingleRunExecutor({ storeCheckpoint }) + const executor = new CoordinatorExecutor({ storeCheckpoint }) const setting = createMockSetting() await executor.execute(setting) diff --git a/packages/runtime/src/orchestration/single-run-executor.ts b/packages/runtime/src/orchestration/coordinator-executor.ts similarity index 93% rename from packages/runtime/src/orchestration/single-run-executor.ts rename to packages/runtime/src/orchestration/coordinator-executor.ts index 3200f268..e433fde3 100644 --- a/packages/runtime/src/orchestration/single-run-executor.ts +++ b/packages/runtime/src/orchestration/coordinator-executor.ts @@ -26,7 +26,7 @@ import { LLMExecutor } from "../llm/index.js" import { getSkillManagers, getSkillManagersFromLockfile } from "../skill-manager/index.js" import { executeStateMachine } from "../state-machine/index.js" -export type SingleRunExecutorOptions = { +export type CoordinatorExecutorOptions = { shouldContinueRun?: (setting: RunSetting, checkpoint: Checkpoint, step: Step) => Promise storeCheckpoint?: (checkpoint: Checkpoint) => Promise storeEvent?: (event: RunEvent) => Promise @@ -35,23 +35,23 @@ export type SingleRunExecutorOptions = { lockfile?: Lockfile } -export type SingleRunResult = { +export type CoordinatorResult = { checkpoint: Checkpoint expertToRun: Expert experts: Record } /** - * Executes a single run (state machine execution) without any loop or delegation handling. + * Executes a single coordinator run (state machine execution) without any loop or delegation handling. * This is the core orchestration unit that should NOT call run() recursively. * * Note: This executes a complete state machine run until it reaches a terminal state * (completed, stoppedByInteractiveTool, stoppedByDelegate, etc.), not just a single step. */ -export class SingleRunExecutor { - constructor(private options: SingleRunExecutorOptions = {}) {} +export class CoordinatorExecutor { + constructor(private options: CoordinatorExecutorOptions = {}) {} - async execute(setting: RunSetting, checkpoint?: Checkpoint): Promise { + async execute(setting: RunSetting, checkpoint?: Checkpoint): Promise { const adapter = await createProviderAdapter(setting.providerConfig, { proxyUrl: setting.proxyUrl, }) diff --git a/packages/runtime/src/orchestration/index.ts b/packages/runtime/src/orchestration/index.ts index a2b00f8f..2de3fe5a 100644 --- a/packages/runtime/src/orchestration/index.ts +++ b/packages/runtime/src/orchestration/index.ts @@ -8,7 +8,7 @@ export { extractDelegationContext, } from "./delegation-executor.js" export { - SingleRunExecutor, - type SingleRunExecutorOptions, - type SingleRunResult, -} from "./single-run-executor.js" + CoordinatorExecutor, + type CoordinatorExecutorOptions, + type CoordinatorResult, +} from "./coordinator-executor.js" diff --git a/packages/runtime/src/run.test.ts b/packages/runtime/src/run.test.ts index be592ae3..4212a68b 100644 --- a/packages/runtime/src/run.test.ts +++ b/packages/runtime/src/run.test.ts @@ -7,12 +7,12 @@ import { run } from "./run.js" const mockExecute = vi.fn() const mockBuildReturnFromDelegation = vi.fn() -// Mock SingleRunExecutor as a class +// Mock CoordinatorExecutor as a class vi.mock("./orchestration/index.js", async (importOriginal) => { const original = await importOriginal() return { ...original, - SingleRunExecutor: class MockSingleRunExecutor { + CoordinatorExecutor: class MockCoordinatorExecutor { execute = mockExecute }, buildReturnFromDelegation: (...args: unknown[]) => mockBuildReturnFromDelegation(...args), diff --git a/packages/runtime/src/run.ts b/packages/runtime/src/run.ts index ff740a19..d54bf790 100755 --- a/packages/runtime/src/run.ts +++ b/packages/runtime/src/run.ts @@ -17,9 +17,9 @@ import { } from "./helpers/index.js" import { buildReturnFromDelegation, + CoordinatorExecutor, DelegationExecutor, extractDelegationContext, - SingleRunExecutor, } from "./orchestration/index.js" export type RunOptions = { @@ -61,7 +61,7 @@ const defaultCreateJob = ( * - Delegation routing (single vs parallel) * - Terminal state detection * - * Each run execution is delegated to SingleRunExecutor. + * Each run execution is delegated to CoordinatorExecutor. */ export async function run(runInput: RunParamsInput, options?: RunOptions): Promise { const runParams = runParamsSchema.parse(runInput) @@ -83,7 +83,7 @@ export async function run(runInput: RunParamsInput, options?: RunOptions): Promi } storeJob(job) - const runExecutor = new SingleRunExecutor({ + const runExecutor = new CoordinatorExecutor({ shouldContinueRun: options?.shouldContinueRun, storeCheckpoint: options?.storeCheckpoint, storeEvent: options?.storeEvent, From 320cd2f6527cb0b21061882414388738d6672d39 Mon Sep 17 00:00:00 2001 From: HiranoMasaaki Date: Mon, 16 Feb 2026 05:43:02 +0000 Subject: [PATCH 2/3] chore: add empty changeset Co-Authored-By: Claude Opus 4.6 --- .changeset/good-adults-heal.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changeset/good-adults-heal.md diff --git a/.changeset/good-adults-heal.md b/.changeset/good-adults-heal.md new file mode 100644 index 00000000..a845151c --- /dev/null +++ b/.changeset/good-adults-heal.md @@ -0,0 +1,2 @@ +--- +--- From ee5395b2562006b44e860eeb02f2c3cb1f5c4c13 Mon Sep 17 00:00:00 2001 From: HiranoMasaaki Date: Mon, 16 Feb 2026 05:45:51 +0000 Subject: [PATCH 3/3] chore: fix import order for biome lint Co-Authored-By: Claude Opus 4.6 --- packages/runtime/src/orchestration/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/runtime/src/orchestration/index.ts b/packages/runtime/src/orchestration/index.ts index 2de3fe5a..ea57b86c 100644 --- a/packages/runtime/src/orchestration/index.ts +++ b/packages/runtime/src/orchestration/index.ts @@ -1,3 +1,8 @@ +export { + CoordinatorExecutor, + type CoordinatorExecutorOptions, + type CoordinatorResult, +} from "./coordinator-executor.js" export { buildReturnFromDelegation, type DelegationContext, @@ -7,8 +12,3 @@ export { type DelegationRunOptions, extractDelegationContext, } from "./delegation-executor.js" -export { - CoordinatorExecutor, - type CoordinatorExecutorOptions, - type CoordinatorResult, -} from "./coordinator-executor.js"