chore: rename orchestrator to server (#6898)
This commit is contained in:
committed by
GitHub
parent
9e7582aa03
commit
8495f9d0d6
Generated
+7
-15
@@ -798,25 +798,14 @@
|
|||||||
"resolved": "packages/coding-agent",
|
"resolved": "packages/coding-agent",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@earendil-works/pi-orchestrator": {
|
"node_modules/@earendil-works/pi-server": {
|
||||||
"resolved": "packages/orchestrator",
|
"resolved": "packages/server",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@earendil-works/pi-tui": {
|
"node_modules/@earendil-works/pi-tui": {
|
||||||
"resolved": "packages/tui",
|
"resolved": "packages/tui",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@emnapi/wasi-threads": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
"version": "0.28.1",
|
"version": "0.28.1",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
|
||||||
@@ -6086,13 +6075,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/orchestrator": {
|
"packages/server": {
|
||||||
"name": "@earendil-works/pi-orchestrator",
|
"name": "@earendil-works/pi-server",
|
||||||
"version": "0.80.10",
|
"version": "0.80.10",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@earendil-works/pi-coding-agent": "^0.80.10"
|
"@earendil-works/pi-coding-agent": "^0.80.10"
|
||||||
},
|
},
|
||||||
|
"bin": {
|
||||||
|
"server": "dist/cli.js"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"shx": "0.4.0"
|
"shx": "0.4.0"
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-2
@@ -13,8 +13,8 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "npm run clean --workspaces",
|
"clean": "npm run clean --workspaces",
|
||||||
"build": "cd packages/tui && npm run build && cd ../ai && npm run build && cd ../agent && npm run build && cd ../storage/sqlite-node && npm run build && cd ../../coding-agent && npm run build && cd ../orchestrator && npm run build",
|
"build": "cd packages/tui && npm run build && cd ../ai && npm run build && cd ../agent && npm run build && cd ../storage/sqlite-node && npm run build && cd ../../coding-agent && npm run build && cd ../server && npm run build",
|
||||||
"build:offline": "cd packages/tui && npm run build && cd ../ai && npm run build:offline && cd ../agent && npm run build && cd ../storage/sqlite-node && npm run build && cd ../../coding-agent && npm run build && cd ../orchestrator && npm run build",
|
"build:offline": "cd packages/tui && npm run build && cd ../ai && npm run build:offline && cd ../agent && npm run build && cd ../storage/sqlite-node && npm run build && cd ../../coding-agent && npm run build && cd ../server && npm run build",
|
||||||
"check": "biome check --write --error-on-warnings . && npm run check:pinned-deps && npm run check:ts-imports && npm run check:shrinkwrap && npm run check:install-lock:coding-agent && tsgo --noEmit && npm run check:browser-smoke",
|
"check": "biome check --write --error-on-warnings . && npm run check:pinned-deps && npm run check:ts-imports && npm run check:shrinkwrap && npm run check:install-lock:coding-agent && tsgo --noEmit && npm run check:browser-smoke",
|
||||||
"check:browser-smoke": "node scripts/check-browser-smoke.mjs",
|
"check:browser-smoke": "node scripts/check-browser-smoke.mjs",
|
||||||
"check:pinned-deps": "node scripts/check-pinned-deps.mjs",
|
"check:pinned-deps": "node scripts/check-pinned-deps.mjs",
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Renamed the orchestrator workspace package and internal server references to server.
|
||||||
|
|
||||||
## [0.80.10] - 2026-07-16
|
## [0.80.10] - 2026-07-16
|
||||||
|
|
||||||
## [0.80.9] - 2026-07-16
|
## [0.80.9] - 2026-07-16
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
# @earendil-works/pi-orchestrator
|
# @earendil-works/pi-server
|
||||||
|
|
||||||
Experimental. This package is under active development and may change or be removed without notice. Its CLI, APIs, and behavior are not yet stable.
|
Experimental. This package is under active development and may change or be removed without notice. Its CLI, APIs, and behavior are not yet stable.
|
||||||
|
|
||||||
Orchestrator package for pi.
|
Server package for pi.
|
||||||
|
|
||||||
## CLI
|
## CLI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
orchestrator --help
|
server --help
|
||||||
```
|
```
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@earendil-works/pi-orchestrator",
|
"name": "@earendil-works/pi-server",
|
||||||
"version": "0.80.10",
|
"version": "0.80.10",
|
||||||
"description": "experimental orchestrator package for pi",
|
"description": "experimental server package for pi",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -11,6 +11,9 @@
|
|||||||
"import": "./dist/index.js"
|
"import": "./dist/index.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bin": {
|
||||||
|
"server": "./dist/cli.js"
|
||||||
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"README.md",
|
"README.md",
|
||||||
@@ -24,14 +27,14 @@
|
|||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"pi",
|
"pi",
|
||||||
"orchestrator"
|
"server"
|
||||||
],
|
],
|
||||||
"author": "Earendil Works",
|
"author": "Earendil Works",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/earendil-works/pi.git",
|
"url": "git+https://github.com/earendil-works/pi.git",
|
||||||
"directory": "packages/orchestrator"
|
"directory": "packages/server"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.19.0"
|
"node": ">=22.19.0"
|
||||||
@@ -18,7 +18,7 @@ const packageJson = JSON.parse(readFileSync(join(__dirname, "../package.json"),
|
|||||||
|
|
||||||
function printHelp(): void {
|
function printHelp(): void {
|
||||||
console.log(
|
console.log(
|
||||||
`orchestrator v${packageJson.version}\n\nUsage:\n orchestrator serve\n orchestrator list\n orchestrator spawn [--cwd <path>] [--label <label>]\n orchestrator status <instance-id>\n orchestrator stop <instance-id>\n orchestrator rpc <instance-id> <json-command>\n orchestrator rpc-stream <instance-id>\n orchestrator --help\n orchestrator --version\n\nRPC stream stdin expects JSONL RpcCommand or extension_ui_response messages.`,
|
`server v${packageJson.version}\n\nUsage:\n server serve\n server list\n server spawn [--cwd <path>] [--label <label>]\n server status <instance-id>\n server stop <instance-id>\n server rpc <instance-id> <json-command>\n server rpc-stream <instance-id>\n server --help\n server --version\n\nRPC stream stdin expects JSONL RpcCommand or extension_ui_response messages.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ async function main(): Promise<void> {
|
|||||||
if (args[0] === "status") {
|
if (args[0] === "status") {
|
||||||
const instanceId = args[1];
|
const instanceId = args[1];
|
||||||
if (!instanceId) {
|
if (!instanceId) {
|
||||||
console.error("Usage: orchestrator status <instance-id>");
|
console.error("Usage: server status <instance-id>");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
printResponse(await sendIpcRequest({ type: "status", instanceId }));
|
printResponse(await sendIpcRequest({ type: "status", instanceId }));
|
||||||
@@ -119,7 +119,7 @@ async function main(): Promise<void> {
|
|||||||
if (args[0] === "stop") {
|
if (args[0] === "stop") {
|
||||||
const instanceId = args[1];
|
const instanceId = args[1];
|
||||||
if (!instanceId) {
|
if (!instanceId) {
|
||||||
console.error("Usage: orchestrator stop <instance-id>");
|
console.error("Usage: server stop <instance-id>");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
printResponse(await sendIpcRequest({ type: "stop", instanceId }));
|
printResponse(await sendIpcRequest({ type: "stop", instanceId }));
|
||||||
@@ -130,7 +130,7 @@ async function main(): Promise<void> {
|
|||||||
const instanceId = args[1];
|
const instanceId = args[1];
|
||||||
const commandJson = args[2];
|
const commandJson = args[2];
|
||||||
if (!instanceId || !commandJson) {
|
if (!instanceId || !commandJson) {
|
||||||
console.error("Usage: orchestrator rpc <instance-id> <json-command>");
|
console.error("Usage: server rpc <instance-id> <json-command>");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
printResponse(
|
printResponse(
|
||||||
@@ -146,7 +146,7 @@ async function main(): Promise<void> {
|
|||||||
if (args[0] === "rpc-stream") {
|
if (args[0] === "rpc-stream") {
|
||||||
const instanceId = args[1];
|
const instanceId = args[1];
|
||||||
if (!instanceId) {
|
if (!instanceId) {
|
||||||
console.error("Usage: orchestrator rpc-stream <instance-id>");
|
console.error("Usage: server rpc-stream <instance-id>");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
await rpcStream(instanceId);
|
await rpcStream(instanceId);
|
||||||
@@ -4,7 +4,7 @@ import { dirname, join } from "node:path";
|
|||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
const CONFIG_DIR_NAME = ".pi";
|
const CONFIG_DIR_NAME = ".pi";
|
||||||
const ENV_ORCHESTRATOR_DIR = "PI_ORCHESTRATOR_DIR";
|
const ENV_SERVER_DIR = "PI_SERVER_DIR";
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
@@ -42,28 +42,28 @@ try {
|
|||||||
|
|
||||||
export const VERSION: string = pkg.version || "0.0.0";
|
export const VERSION: string = pkg.version || "0.0.0";
|
||||||
|
|
||||||
export function getOrchestratorDir(): string {
|
export function getServerDir(): string {
|
||||||
const envDir = process.env[ENV_ORCHESTRATOR_DIR];
|
const envDir = process.env[ENV_SERVER_DIR];
|
||||||
if (envDir) {
|
if (envDir) {
|
||||||
return envDir;
|
return envDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
const piDir = process.env.PI_CONFIG_DIR || join(homedir(), CONFIG_DIR_NAME);
|
const piDir = process.env.PI_CONFIG_DIR || join(homedir(), CONFIG_DIR_NAME);
|
||||||
return join(piDir, "orchestrator");
|
return join(piDir, "server");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAuthPath(): string {
|
export function getAuthPath(): string {
|
||||||
return join(getOrchestratorDir(), "auth.json");
|
return join(getServerDir(), "auth.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMachinePath(): string {
|
export function getMachinePath(): string {
|
||||||
return join(getOrchestratorDir(), "machine.json");
|
return join(getServerDir(), "machine.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInstancesPath(): string {
|
export function getInstancesPath(): string {
|
||||||
return join(getOrchestratorDir(), "instances.json");
|
return join(getServerDir(), "instances.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSocketPath(): string {
|
export function getSocketPath(): string {
|
||||||
return join(getOrchestratorDir(), "orchestrator.sock");
|
return join(getServerDir(), "server.sock");
|
||||||
}
|
}
|
||||||
@@ -10,12 +10,12 @@ import type {
|
|||||||
InstanceSummary,
|
InstanceSummary,
|
||||||
ListRequest,
|
ListRequest,
|
||||||
ListResponse,
|
ListResponse,
|
||||||
OrchestratorRequest,
|
|
||||||
OrchestratorResponse,
|
|
||||||
RpcBridgeResponse,
|
RpcBridgeResponse,
|
||||||
RpcReadyResponse,
|
RpcReadyResponse,
|
||||||
RpcRequest,
|
RpcRequest,
|
||||||
RpcStreamRequest,
|
RpcStreamRequest,
|
||||||
|
ServerRequest,
|
||||||
|
ServerResponse,
|
||||||
SpawnRequest,
|
SpawnRequest,
|
||||||
SpawnResponse,
|
SpawnResponse,
|
||||||
StatusRequest,
|
StatusRequest,
|
||||||
@@ -53,8 +53,8 @@ export async function handleIpcRequest(request: StopRequest): Promise<StopRespon
|
|||||||
export async function handleIpcRequest(request: StatusRequest): Promise<StatusResponse | ErrorResponse>;
|
export async function handleIpcRequest(request: StatusRequest): Promise<StatusResponse | ErrorResponse>;
|
||||||
export async function handleIpcRequest(request: RpcRequest): Promise<RpcBridgeResponse | ErrorResponse>;
|
export async function handleIpcRequest(request: RpcRequest): Promise<RpcBridgeResponse | ErrorResponse>;
|
||||||
export async function handleIpcRequest(request: RpcStreamRequest): Promise<RpcReadyResponse | ErrorResponse>;
|
export async function handleIpcRequest(request: RpcStreamRequest): Promise<RpcReadyResponse | ErrorResponse>;
|
||||||
export async function handleIpcRequest(request: OrchestratorRequest): Promise<OrchestratorResponse>;
|
export async function handleIpcRequest(request: ServerRequest): Promise<ServerResponse>;
|
||||||
export async function handleIpcRequest(request: OrchestratorRequest): Promise<OrchestratorResponse> {
|
export async function handleIpcRequest(request: ServerRequest): Promise<ServerResponse> {
|
||||||
switch (request.type) {
|
switch (request.type) {
|
||||||
case "spawn": {
|
case "spawn": {
|
||||||
const instance = await supervisor.spawnInstance({
|
const instance = await supervisor.spawnInstance({
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { createConnection } from "node:net";
|
import { createConnection } from "node:net";
|
||||||
import { getSocketPath } from "../config.ts";
|
import { getSocketPath } from "../config.ts";
|
||||||
import { encodeMessage, type OrchestratorRequest, type OrchestratorResponse, parseResponseLine } from "./protocol.ts";
|
import { encodeMessage, parseResponseLine, type ServerRequest, type ServerResponse } from "./protocol.ts";
|
||||||
|
|
||||||
export async function sendIpcRequest(request: OrchestratorRequest): Promise<OrchestratorResponse> {
|
export async function sendIpcRequest(request: ServerRequest): Promise<ServerResponse> {
|
||||||
const socketPath = getSocketPath();
|
const socketPath = getSocketPath();
|
||||||
|
|
||||||
return new Promise<OrchestratorResponse>((resolve, reject) => {
|
return new Promise<ServerResponse>((resolve, reject) => {
|
||||||
const socket = createConnection(socketPath);
|
const socket = createConnection(socketPath);
|
||||||
let buffer = "";
|
let buffer = "";
|
||||||
let settled = false;
|
let settled = false;
|
||||||
@@ -56,7 +56,7 @@ export async function sendIpcRequest(request: OrchestratorRequest): Promise<Orch
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
settled = true;
|
settled = true;
|
||||||
reject(new Error(`Orchestrator socket closed before a response was received: ${socketPath}`));
|
reject(new Error(`Server socket closed before a response was received: ${socketPath}`));
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -49,7 +49,7 @@ export interface RequestMap {
|
|||||||
rpc_stream: RpcStreamRequest;
|
rpc_stream: RpcStreamRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OrchestratorRequest = RequestMap[keyof RequestMap];
|
export type ServerRequest = RequestMap[keyof RequestMap];
|
||||||
|
|
||||||
export interface InstanceSummary {
|
export interface InstanceSummary {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -111,7 +111,7 @@ export interface ResponseMap {
|
|||||||
rpc_stream: RpcReadyResponse;
|
rpc_stream: RpcReadyResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OrchestratorResponse = ResponseMap[keyof ResponseMap] | ErrorResponse;
|
export type ServerResponse = ResponseMap[keyof ResponseMap] | ErrorResponse;
|
||||||
export type RpcClientMessage = RpcCommand | RpcExtensionUIResponse;
|
export type RpcClientMessage = RpcCommand | RpcExtensionUIResponse;
|
||||||
export type RpcServerMessage =
|
export type RpcServerMessage =
|
||||||
| RpcReadyResponse
|
| RpcReadyResponse
|
||||||
@@ -119,9 +119,9 @@ export type RpcServerMessage =
|
|||||||
| AgentSessionEvent
|
| AgentSessionEvent
|
||||||
| RpcExtensionUIRequest
|
| RpcExtensionUIRequest
|
||||||
| ErrorResponse;
|
| ErrorResponse;
|
||||||
export type ProtocolMessage = OrchestratorRequest | OrchestratorResponse | RpcClientMessage | RpcServerMessage;
|
export type ProtocolMessage = ServerRequest | ServerResponse | RpcClientMessage | RpcServerMessage;
|
||||||
|
|
||||||
export type ResponseFor<T extends OrchestratorRequest> = T extends { type: infer K }
|
export type ResponseFor<T extends ServerRequest> = T extends { type: infer K }
|
||||||
? K extends keyof ResponseMap
|
? K extends keyof ResponseMap
|
||||||
? ResponseMap[K] | ErrorResponse
|
? ResponseMap[K] | ErrorResponse
|
||||||
: ErrorResponse
|
: ErrorResponse
|
||||||
@@ -131,12 +131,12 @@ export function encodeMessage(message: ProtocolMessage): string {
|
|||||||
return `${JSON.stringify(message)}\n`;
|
return `${JSON.stringify(message)}\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseRequestLine(line: string): OrchestratorRequest {
|
export function parseRequestLine(line: string): ServerRequest {
|
||||||
const value = JSON.parse(line) as OrchestratorRequest;
|
const value = JSON.parse(line) as ServerRequest;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseResponseLine(line: string): OrchestratorResponse {
|
export function parseResponseLine(line: string): ServerResponse {
|
||||||
const value = JSON.parse(line) as OrchestratorResponse;
|
const value = JSON.parse(line) as ServerResponse;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -7,13 +7,13 @@ import {
|
|||||||
encodeMessage,
|
encodeMessage,
|
||||||
type ListRequest,
|
type ListRequest,
|
||||||
type ListResponse,
|
type ListResponse,
|
||||||
type OrchestratorRequest,
|
|
||||||
type OrchestratorResponse,
|
|
||||||
parseRequestLine,
|
parseRequestLine,
|
||||||
type RpcBridgeResponse,
|
type RpcBridgeResponse,
|
||||||
type RpcReadyResponse,
|
type RpcReadyResponse,
|
||||||
type RpcRequest,
|
type RpcRequest,
|
||||||
type RpcStreamRequest,
|
type RpcStreamRequest,
|
||||||
|
type ServerRequest,
|
||||||
|
type ServerResponse,
|
||||||
type SpawnRequest,
|
type SpawnRequest,
|
||||||
type SpawnResponse,
|
type SpawnResponse,
|
||||||
type StatusRequest,
|
type StatusRequest,
|
||||||
@@ -29,7 +29,7 @@ export interface IpcRequestHandler {
|
|||||||
(request: StatusRequest): Promise<StatusResponse | ErrorResponse> | StatusResponse | ErrorResponse;
|
(request: StatusRequest): Promise<StatusResponse | ErrorResponse> | StatusResponse | ErrorResponse;
|
||||||
(request: RpcRequest): Promise<RpcBridgeResponse | ErrorResponse> | RpcBridgeResponse | ErrorResponse;
|
(request: RpcRequest): Promise<RpcBridgeResponse | ErrorResponse> | RpcBridgeResponse | ErrorResponse;
|
||||||
(request: RpcStreamRequest): Promise<RpcReadyResponse | ErrorResponse> | RpcReadyResponse | ErrorResponse;
|
(request: RpcStreamRequest): Promise<RpcReadyResponse | ErrorResponse> | RpcReadyResponse | ErrorResponse;
|
||||||
(request: OrchestratorRequest): Promise<OrchestratorResponse> | OrchestratorResponse;
|
(request: ServerRequest): Promise<ServerResponse> | ServerResponse;
|
||||||
openRpcStream(
|
openRpcStream(
|
||||||
instanceId: string,
|
instanceId: string,
|
||||||
onResponse: (response: RpcResponse) => void,
|
onResponse: (response: RpcResponse) => void,
|
||||||
@@ -166,7 +166,7 @@ async function removeStaleSocketIfNeeded(socketPath: string): Promise<void> {
|
|||||||
|
|
||||||
const isLive = await isSocketLive(socketPath);
|
const isLive = await isSocketLive(socketPath);
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
throw new Error(`orchestrator is already running: ${socketPath}`);
|
throw new Error(`server is already running: ${socketPath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlinkSync(socketPath);
|
unlinkSync(socketPath);
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import { hostname, platform } from "node:os";
|
import { hostname, platform } from "node:os";
|
||||||
import type { OAuthCredential } from "@earendil-works/pi-ai";
|
import type { OAuthCredential } from "@earendil-works/pi-ai";
|
||||||
import { readStoredCredential } from "@earendil-works/pi-coding-agent";
|
import { readStoredCredential } from "@earendil-works/pi-coding-agent";
|
||||||
import { getOrchestratorDir, getSocketPath, VERSION } from "./config.ts";
|
import { getServerDir, getSocketPath, VERSION } from "./config.ts";
|
||||||
import { loadMachine, saveMachine } from "./storage.ts";
|
import { loadMachine, saveMachine } from "./storage.ts";
|
||||||
import type { InstanceRecord, MachineRecord, RadiusRegistration } from "./types.ts";
|
import type { InstanceRecord, MachineRecord, RadiusRegistration } from "./types.ts";
|
||||||
|
|
||||||
const DEFAULT_RADIUS_URL = "https://radius.pi.dev/";
|
const DEFAULT_RADIUS_URL = "https://radius.pi.dev/";
|
||||||
const DEFAULT_ORCHESTRATOR_BASE_PATH = "/v1/";
|
const DEFAULT_SERVER_BASE_PATH = "/v1/";
|
||||||
const NOT_FOUND_RETRY_THRESHOLD = 3;
|
const NOT_FOUND_RETRY_THRESHOLD = 3;
|
||||||
const HEARTBEAT_BACKOFF_BASE_MS = 1_000;
|
const HEARTBEAT_BACKOFF_BASE_MS = 1_000;
|
||||||
const HEARTBEAT_BACKOFF_MAX_MS = 30_000;
|
const HEARTBEAT_BACKOFF_MAX_MS = 30_000;
|
||||||
@@ -45,7 +45,7 @@ class RadiusHttpError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function post<T>(path: string, body: unknown): Promise<T> {
|
async function post<T>(path: string, body: unknown): Promise<T> {
|
||||||
const response = await fetch(new URL(path, getRadiusOrchestratorBaseUrl()), {
|
const response = await fetch(new URL(path, getRadiusServerBaseUrl()), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${getRadiusAccessToken()}`,
|
Authorization: `Bearer ${getRadiusAccessToken()}`,
|
||||||
@@ -62,7 +62,7 @@ async function post<T>(path: string, body: unknown): Promise<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function maybePost(path: string, body: unknown): Promise<void> {
|
async function maybePost(path: string, body: unknown): Promise<void> {
|
||||||
const response = await fetch(new URL(path, getRadiusOrchestratorBaseUrl()), {
|
const response = await fetch(new URL(path, getRadiusServerBaseUrl()), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${getRadiusAccessToken()}`,
|
Authorization: `Bearer ${getRadiusAccessToken()}`,
|
||||||
@@ -108,13 +108,13 @@ export function getRadiusUrl(): string {
|
|||||||
return process.env.PI_RADIUS_URL || DEFAULT_RADIUS_URL;
|
return process.env.PI_RADIUS_URL || DEFAULT_RADIUS_URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRadiusOrchestratorBaseUrl(): string {
|
export function getRadiusServerBaseUrl(): string {
|
||||||
const explicitUrl = process.env.PI_RADIUS_ORCHESTRATOR_URL;
|
const explicitUrl = process.env.PI_RADIUS_SERVER_URL;
|
||||||
if (explicitUrl) {
|
if (explicitUrl) {
|
||||||
return explicitUrl;
|
return explicitUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new URL(DEFAULT_ORCHESTRATOR_BASE_PATH, getRadiusUrl()).toString();
|
return new URL(DEFAULT_SERVER_BASE_PATH, getRadiusUrl()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStoredRadiusCredential(): OAuthCredential | undefined {
|
function getStoredRadiusCredential(): OAuthCredential | undefined {
|
||||||
@@ -307,7 +307,7 @@ export class RadiusPresence {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await maybePost(`machines/${this.machine.id}/heartbeat`, {
|
await maybePost(`machines/${this.machine.id}/heartbeat`, {
|
||||||
cwd: getOrchestratorDir(),
|
cwd: getServerDir(),
|
||||||
socketPath: getSocketPath(),
|
socketPath: getSocketPath(),
|
||||||
});
|
});
|
||||||
this.machineConsecutiveNotFoundCount = 0;
|
this.machineConsecutiveNotFoundCount = 0;
|
||||||
@@ -144,7 +144,7 @@ export class RpcProcessInstance {
|
|||||||
if (this.exited) {
|
if (this.exited) {
|
||||||
throw new Error(`RPC process is not running. Stderr: ${this.stderrBuffer}`);
|
throw new Error(`RPC process is not running. Stderr: ${this.stderrBuffer}`);
|
||||||
}
|
}
|
||||||
const id = command.id ?? `orchestrator_${++this.nextRequestId}_${randomUUID()}`;
|
const id = command.id ?? `server_${++this.nextRequestId}_${randomUUID()}`;
|
||||||
const fullCommand = { ...command, id };
|
const fullCommand = { ...command, id };
|
||||||
return new Promise<RpcResponse>((resolve, reject) => {
|
return new Promise<RpcResponse>((resolve, reject) => {
|
||||||
this.pendingRequests.set(id, { resolve, reject });
|
this.pendingRequests.set(id, { resolve, reject });
|
||||||
@@ -3,7 +3,7 @@ import { dirname } from "node:path";
|
|||||||
import { getSocketPath } from "./config.ts";
|
import { getSocketPath } from "./config.ts";
|
||||||
import { handleIpcRequest, openRpcStream } from "./handler.ts";
|
import { handleIpcRequest, openRpcStream } from "./handler.ts";
|
||||||
import { startIpcServer } from "./ipc/server.ts";
|
import { startIpcServer } from "./ipc/server.ts";
|
||||||
import { getRadiusOrchestratorBaseUrl, isRadiusEnabled, radiusPresence } from "./radius.ts";
|
import { getRadiusServerBaseUrl, isRadiusEnabled, radiusPresence } from "./radius.ts";
|
||||||
import { supervisor } from "./supervisor.ts";
|
import { supervisor } from "./supervisor.ts";
|
||||||
|
|
||||||
export async function serve(): Promise<void> {
|
export async function serve(): Promise<void> {
|
||||||
@@ -19,7 +19,7 @@ export async function serve(): Promise<void> {
|
|||||||
await supervisor.recoverAfterRestart();
|
await supervisor.recoverAfterRestart();
|
||||||
if (isRadiusEnabled()) {
|
if (isRadiusEnabled()) {
|
||||||
const machine = await radiusPresence.start();
|
const machine = await radiusPresence.start();
|
||||||
console.log(`radius integration enabled: ${socketPath} -> ${getRadiusOrchestratorBaseUrl()}`);
|
console.log(`radius integration enabled: ${socketPath} -> ${getRadiusServerBaseUrl()}`);
|
||||||
if (machine) {
|
if (machine) {
|
||||||
console.log(`radius machine id: ${machine.id}`);
|
console.log(`radius machine id: ${machine.id}`);
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ export async function serve(): Promise<void> {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`orchestrator listening on ${socketPath}`);
|
console.log(`server listening on ${socketPath}`);
|
||||||
|
|
||||||
let shutdownPromise: Promise<void> | undefined;
|
let shutdownPromise: Promise<void> | undefined;
|
||||||
const shutdown = async (exitCode: number) => {
|
const shutdown = async (exitCode: number) => {
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||||
import { getInstancesPath, getMachinePath, getOrchestratorDir } from "./config.ts";
|
import { getInstancesPath, getMachinePath, getServerDir } from "./config.ts";
|
||||||
import type { InstanceRecord, MachineRecord } from "./types.ts";
|
import type { InstanceRecord, MachineRecord } from "./types.ts";
|
||||||
|
|
||||||
function ensureOrchestratorDir(): void {
|
function ensureServerDir(): void {
|
||||||
const orchestratorDir = getOrchestratorDir();
|
const serverDir = getServerDir();
|
||||||
if (!existsSync(orchestratorDir)) {
|
if (!existsSync(serverDir)) {
|
||||||
mkdirSync(orchestratorDir, { recursive: true });
|
mkdirSync(serverDir, { recursive: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ export function loadMachine(): MachineRecord | undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function saveMachine(machine: MachineRecord): void {
|
export function saveMachine(machine: MachineRecord): void {
|
||||||
ensureOrchestratorDir();
|
ensureServerDir();
|
||||||
writeFileSync(getMachinePath(), JSON.stringify(machine, null, 2));
|
writeFileSync(getMachinePath(), JSON.stringify(machine, null, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ export function loadInstances(): InstanceRecord[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function saveInstances(instances: InstanceRecord[]): void {
|
export function saveInstances(instances: InstanceRecord[]): void {
|
||||||
ensureOrchestratorDir();
|
ensureServerDir();
|
||||||
writeFileSync(getInstancesPath(), JSON.stringify(instances, null, 2));
|
writeFileSync(getInstancesPath(), JSON.stringify(instances, null, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ function isGetStateSuccess(
|
|||||||
return response.success === true && response.command === "get_state" && "data" in response;
|
return response.success === true && response.command === "get_state" && "data" in response;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OrchestratorSupervisor {
|
export class ServerSupervisor {
|
||||||
private readonly liveInstances = new Map<string, LiveInstance>();
|
private readonly liveInstances = new Map<string, LiveInstance>();
|
||||||
|
|
||||||
private setStatus(live: LiveInstance, status: InstanceStatus): void {
|
private setStatus(live: LiveInstance, status: InstanceStatus): void {
|
||||||
@@ -339,7 +339,7 @@ export class OrchestratorSupervisor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const supervisor = new OrchestratorSupervisor();
|
export const supervisor = new ServerSupervisor();
|
||||||
|
|
||||||
radiusPresence.setCoordinator({
|
radiusPresence.setCoordinator({
|
||||||
getLiveInstance(instanceId) {
|
getLiveInstance(instanceId) {
|
||||||
+2
-2
@@ -16,8 +16,8 @@
|
|||||||
"@earendil-works/pi-coding-agent": ["./packages/coding-agent/src/index.ts"],
|
"@earendil-works/pi-coding-agent": ["./packages/coding-agent/src/index.ts"],
|
||||||
"@earendil-works/pi-coding-agent/hooks": ["./packages/coding-agent/src/core/hooks/index.ts"],
|
"@earendil-works/pi-coding-agent/hooks": ["./packages/coding-agent/src/core/hooks/index.ts"],
|
||||||
"@earendil-works/pi-coding-agent/*": ["./packages/coding-agent/src/*"],
|
"@earendil-works/pi-coding-agent/*": ["./packages/coding-agent/src/*"],
|
||||||
"@earendil-works/pi-orchestrator": ["./packages/orchestrator/src/index.ts"],
|
"@earendil-works/pi-server": ["./packages/server/src/index.ts"],
|
||||||
"@earendil-works/pi-orchestrator/*": ["./packages/orchestrator/src/*"],
|
"@earendil-works/pi-server/*": ["./packages/server/src/*"],
|
||||||
"typebox": ["./node_modules/typebox"],
|
"typebox": ["./node_modules/typebox"],
|
||||||
"@earendil-works/pi-tui": ["./packages/tui/src/index.ts"],
|
"@earendil-works/pi-tui": ["./packages/tui/src/index.ts"],
|
||||||
"@earendil-works/pi-tui/*": ["./packages/tui/src/*"],
|
"@earendil-works/pi-tui/*": ["./packages/tui/src/*"],
|
||||||
|
|||||||
Reference in New Issue
Block a user