mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
feat(coding-agent): move experimental runtime outside CLI
Keep command parsing under cli/experimental and adapt missing model identities to the current Harness shape.
This commit is contained in:
parent
e5960aeb31
commit
33dac36236
19 changed files with 49 additions and 33 deletions
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env node
|
||||
import { runCoordinatorProcess } from "../cli/experimental/coordinator.ts";
|
||||
import { consumeInternalProcessRole, getInternalProcessRole } from "../cli/experimental/process.ts";
|
||||
import { runCoordinatorProcess } from "../experimental/coordinator.ts";
|
||||
import { consumeInternalProcessRole, getInternalProcessRole } from "../experimental/process.ts";
|
||||
import { restoreSandboxEnv } from "./restore-sandbox-env.ts";
|
||||
|
||||
restoreSandboxEnv();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#!/usr/bin/env node
|
||||
import { consumeInternalProcessRole } from "./cli/experimental/process.ts";
|
||||
import { runServerProcess } from "./cli/experimental/server.ts";
|
||||
import { runSessionWorkerProcess } from "./cli/experimental/session-worker.ts";
|
||||
import { APP_NAME } from "./config.ts";
|
||||
import { configureHttpDispatcher } from "./core/http-dispatcher.ts";
|
||||
import { consumeInternalProcessRole } from "./experimental/process.ts";
|
||||
import { runServerProcess } from "./experimental/server.ts";
|
||||
import { runSessionWorkerProcess } from "./experimental/session-worker.ts";
|
||||
import { main } from "./main.ts";
|
||||
|
||||
const internalProcessRole = consumeInternalProcessRole();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { basename } from "node:path";
|
|||
import { PiClient } from "@earendil-works/pi-client";
|
||||
import { createUnixTransportFactory, discoverUnixServers, type UnixServerRoute } from "@earendil-works/pi-client/unix";
|
||||
import { isServerId } from "@earendil-works/pi-protocol";
|
||||
import type { ClientCommand } from "./commands/client.ts";
|
||||
import type { ClientCommand } from "../cli/experimental/commands/client.ts";
|
||||
import { activateServer, ENV_SERVER_ID, resolveServerDirectory, resolveSessionDirectory } from "./server.ts";
|
||||
|
||||
export type ClientResult =
|
||||
|
|
@ -294,7 +294,10 @@ function toWireRunValue(value: Extract<HarnessRunResult, { ok: true }>["value"])
|
|||
reason: "missing_identities",
|
||||
runId: value.runId,
|
||||
leafId: value.leafId,
|
||||
missing: { tools: [...value.missing.tools], models: [...value.missing.models] },
|
||||
missing: {
|
||||
tools: [...value.missing.tools],
|
||||
models: value.missing.model === undefined ? [] : [value.missing.model],
|
||||
},
|
||||
};
|
||||
default:
|
||||
return assertNever(value);
|
||||
|
|
@ -316,7 +319,7 @@ function toWireRunError(error: Extract<HarnessRunResult, { ok: false }>["error"]
|
|||
_tag: "MissingIdentities",
|
||||
lane: error.lane,
|
||||
tools: [...error.tools],
|
||||
models: [...error.models],
|
||||
models: error.model === undefined ? [] : [error.model],
|
||||
message: error.message,
|
||||
};
|
||||
case "InvalidMessage":
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { type ChildProcess, spawn } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { isBunBinary } from "../../config.ts";
|
||||
import { isBunBinary } from "../config.ts";
|
||||
|
||||
export const INTERNAL_PROCESS_ENV = "__PI_INTERNAL_SPAWN";
|
||||
|
||||
|
|
@ -11,8 +11,8 @@ import { isServerId, type ServerId } from "@earendil-works/pi-protocol";
|
|||
import type { PiServer, PiServerHost } from "@earendil-works/pi-server";
|
||||
import { createUnixServer, getUnixSocketPath } from "@earendil-works/pi-server/unix";
|
||||
import lockfile from "proper-lockfile";
|
||||
import { getAgentDir } from "../../config.ts";
|
||||
import { resolvePath } from "../../utils/paths.ts";
|
||||
import { getAgentDir } from "../config.ts";
|
||||
import { resolvePath } from "../utils/paths.ts";
|
||||
import { CoordinatorConnection, type CoordinatorStartupLease, ensureCoordinator } from "./coordinator.ts";
|
||||
import { consumeInternalProcessRole, spawnInternalProcess, terminateInternalProcess } from "./process.ts";
|
||||
import { SessionWorkerManager } from "./session-worker-manager.ts";
|
||||
|
|
@ -22,7 +22,7 @@ import {
|
|||
import lockfile from "proper-lockfile";
|
||||
import Type, { type Static } from "typebox";
|
||||
import { Check } from "typebox/value";
|
||||
import { ModelRuntime } from "../../core/model-runtime.ts";
|
||||
import { ModelRuntime } from "../core/model-runtime.ts";
|
||||
import { toHarnessPromptArguments, toWireRunResult } from "./harness-wire-adapter.ts";
|
||||
import { consumeInternalProcessRole, encodeControlLine, MAX_CONTROL_LINE_BYTES } from "./process.ts";
|
||||
|
||||
|
|
@ -27,10 +27,8 @@ import {
|
|||
} from "./cli/auth-command.ts";
|
||||
import { resolveCredentialForPrint } from "./cli/credential-print.ts";
|
||||
import { cli as experimentalCli } from "./cli/experimental/cli.ts";
|
||||
import { runClient } from "./cli/experimental/client.ts";
|
||||
import type { ClientCommand } from "./cli/experimental/commands/client.ts";
|
||||
import type { ServerCommand } from "./cli/experimental/commands/server.ts";
|
||||
import { startForegroundServer } from "./cli/experimental/server.ts";
|
||||
import { processFileArguments } from "./cli/file-processor.ts";
|
||||
import { buildInitialMessage } from "./cli/initial-message.ts";
|
||||
import { listModels } from "./cli/list-models.ts";
|
||||
|
|
@ -65,6 +63,8 @@ import { assertValidSessionId, SessionManager } from "./core/session-manager.ts"
|
|||
import { SettingsManager } from "./core/settings-manager.ts";
|
||||
import { printTimings, resetTimings, time } from "./core/timings.ts";
|
||||
import { hasTrustRequiringProjectResources, ProjectTrustStore } from "./core/trust-manager.ts";
|
||||
import { runClient } from "./experimental/client.ts";
|
||||
import { startForegroundServer } from "./experimental/server.ts";
|
||||
import { builtInExtensions } from "./extensions/index.ts";
|
||||
import { runMigrations, showDeprecationWarnings } from "./migrations.ts";
|
||||
import { InteractiveMode, runPrintMode, runRpcMode } from "./modes/index.ts";
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|||
import { type PromptArguments, type PromptMessage, RunResultSchema } from "@earendil-works/pi-protocol";
|
||||
import { Check } from "typebox/value";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { toHarnessPromptArguments, toWireRunResult } from "../src/cli/experimental/harness-wire-adapter.ts";
|
||||
import { toHarnessPromptArguments, toWireRunResult } from "../src/experimental/harness-wire-adapter.ts";
|
||||
|
||||
const usage = {
|
||||
input: 1,
|
||||
|
|
@ -165,20 +165,33 @@ describe("Harness wire adapter", () => {
|
|||
deferred: { provider: "test", modelId: "model", api: "test", id: "deferred-1", data: { row: 1 } },
|
||||
},
|
||||
},
|
||||
{
|
||||
] satisfies HarnessRunResult[])("projects every Run outcome %#", (result) => {
|
||||
const wire = toWireRunResult(result);
|
||||
expect(Check(RunResultSchema, wire)).toBe(true);
|
||||
expect(wire).toEqual(result);
|
||||
});
|
||||
|
||||
test("projects singular Harness model identities to the wire list", () => {
|
||||
const wire = toWireRunResult({
|
||||
ok: true,
|
||||
value: {
|
||||
kind: "suspended",
|
||||
reason: "missing_identities",
|
||||
runId: "run-1",
|
||||
leafId: "leaf-1",
|
||||
missing: { tools: ["read"], models: [] },
|
||||
missing: { tools: ["read"], model: "missing-model" },
|
||||
},
|
||||
},
|
||||
] satisfies HarnessRunResult[])("projects every Run outcome %#", (result) => {
|
||||
const wire = toWireRunResult(result);
|
||||
expect(Check(RunResultSchema, wire)).toBe(true);
|
||||
expect(wire).toEqual(result);
|
||||
});
|
||||
expect(wire).toEqual({
|
||||
ok: true,
|
||||
value: {
|
||||
kind: "suspended",
|
||||
reason: "missing_identities",
|
||||
runId: "run-1",
|
||||
leafId: "leaf-1",
|
||||
missing: { tools: ["read"], models: ["missing-model"] },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
|
|
@ -188,7 +201,7 @@ describe("Harness wire adapter", () => {
|
|||
operationKind: "run",
|
||||
message: "busy",
|
||||
}),
|
||||
new MissingIdentities({ lane: "main", tools: ["read"], models: [], message: "missing" }),
|
||||
new MissingIdentities({ lane: "main", tools: ["read"], model: "missing-model", message: "missing" }),
|
||||
new InvalidMessage({ lane: "main", reason: "invalid", message: "invalid" }),
|
||||
new UnknownSkill({ name: "skill", message: "unknown" }),
|
||||
new UnknownTemplate({ name: "template", message: "unknown" }),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { createConnection } from "node:net";
|
|||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, describe, expect, test } from "vitest";
|
||||
import { spawnInternalProcess, terminateInternalProcess } from "../src/cli/experimental/process.ts";
|
||||
import { spawnInternalProcess, terminateInternalProcess } from "../src/experimental/process.ts";
|
||||
|
||||
const children = new Set<ChildProcess>();
|
||||
const directories = new Set<string>();
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { join, resolve } from "node:path";
|
|||
import { PiClient } from "@earendil-works/pi-client";
|
||||
import { createUnixTransportFactory } from "@earendil-works/pi-client/unix";
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import { runClient } from "../src/cli/experimental/client.ts";
|
||||
import { type RunningServer, startServer } from "../src/cli/experimental/server.ts";
|
||||
import { runClient } from "../src/experimental/client.ts";
|
||||
import { type RunningServer, startServer } from "../src/experimental/server.ts";
|
||||
import { configureExperimentalWorkerModel, createExperimentalSessions } from "./experimental-session-support.ts";
|
||||
|
||||
const servers = new Set<RunningServer>();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { afterEach, describe, expect, test, vi } from "vitest";
|
||||
import { ServerLifetime } from "../src/cli/experimental/server.ts";
|
||||
import { ServerLifetime } from "../src/experimental/server.ts";
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { mkdtemp, readdir, readFile, rm, writeFile } from "node:fs/promises";
|
|||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, describe, expect, test } from "vitest";
|
||||
import { acquireServerProfile } from "../src/cli/experimental/server.ts";
|
||||
import { acquireServerProfile } from "../src/experimental/server.ts";
|
||||
|
||||
const directories = new Set<string>();
|
||||
const FIRST_SERVER_ID = "00000000-0000-4000-8000-000000000001";
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { lstat, mkdir, mkdtemp, rm } from "node:fs/promises";
|
|||
import { join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { afterEach, describe, expect, test } from "vitest";
|
||||
import { runClient } from "../src/cli/experimental/client.ts";
|
||||
import { runClient } from "../src/experimental/client.ts";
|
||||
import { configureExperimentalWorkerModel, createExperimentalSessions } from "./experimental-session-support.ts";
|
||||
|
||||
const cliPath = fileURLToPath(new URL("../src/cli.ts", import.meta.url));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { homedir } from "node:os";
|
||||
import { resolve } from "node:path";
|
||||
import { afterEach, describe, expect, test, vi } from "vitest";
|
||||
import { resolveSessionDirectory } from "../src/cli/experimental/server.ts";
|
||||
import { resolveSessionDirectory } from "../src/experimental/server.ts";
|
||||
|
||||
afterEach(() => vi.unstubAllEnvs());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { afterEach, describe, expect, test, vi } from "vitest";
|
||||
import { WorkerLifecycle } from "../src/cli/experimental/session-worker.ts";
|
||||
import { WorkerLifecycle } from "../src/experimental/session-worker.ts";
|
||||
|
||||
const GENERATION = "generation-1";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { JsonlSessionMetadata } from "@earendil-works/pi-agent-core";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import type { CoordinatorConnectionEvent } from "../src/cli/experimental/coordinator.ts";
|
||||
import { SessionWorkerManager } from "../src/cli/experimental/session-worker-manager.ts";
|
||||
import type { CoordinatorConnectionEvent } from "../src/experimental/coordinator.ts";
|
||||
import { SessionWorkerManager } from "../src/experimental/session-worker-manager.ts";
|
||||
|
||||
const metadata: JsonlSessionMetadata = {
|
||||
id: "session-1",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue