Pi running inside the docker containers

This commit is contained in:
2026-02-22 22:21:47 +00:00
parent 99a27e5b13
commit 09cff3f763
15 changed files with 315 additions and 26 deletions
+56 -14
View File
@@ -6,26 +6,67 @@ import { logger } from "./logger";
export type PiEventHandler = (event: PiEvent) => void;
type SandboxOptions = {
userId: number;
};
const CONTAINER_HOME = '/home/officer';
const CONTAINER_PI_CONFIG = '/home/officer/.pi/agent';
export async function spawnPi(
cwd: string,
model: string,
onEvent: PiEventHandler
onEvent: PiEventHandler,
sandbox?: SandboxOptions,
): Promise<Subprocess> {
const storedKeys = await readApiKeys();
const args = ['pi', '--mode', 'rpc', '--no-extensions', '--no-skills', '--no-prompt-templates', '--no-themes'];
if (model) args.push('--model', model);
let proc: Subprocess;
const proc = Bun.spawn(args, {
cwd,
stdin: 'pipe',
stdout: 'pipe',
stderr: 'pipe',
env: { ...process.env, ...storedKeys, PI_CODING_AGENT_DIR: PI_CONFIG_DIR },
});
if (sandbox) {
const storedKeys = await readApiKeys();
const dockerPath = Bun.which('docker') ?? 'docker';
const containerId = `officer-terminal-${sandbox.userId}`;
const piArgs = ['pi', '--mode', 'rpc', '--no-extensions', '--no-skills', '--no-prompt-templates', '--no-themes'];
if (model) piArgs.push('--model', model);
// Build env flags: Pi config dir + all stored API keys
const envFlags = [
'-e', `PI_CODING_AGENT_DIR=${CONTAINER_PI_CONFIG}`,
'-e', `HOME=${CONTAINER_HOME}`,
];
for (const [key, value] of Object.entries(storedKeys)) {
if (value?.trim()) envFlags.push('-e', `${key}=${value.trim()}`);
}
proc = Bun.spawn([
dockerPath, 'exec', '-i',
'-w', CONTAINER_HOME,
...envFlags,
containerId,
...piArgs,
], {
stdin: 'pipe',
stdout: 'pipe',
stderr: 'pipe',
});
logger.info('Spawned Pi in container', { containerId, model });
} else {
const storedKeys = await readApiKeys();
const args = ['pi', '--mode', 'rpc', '--no-extensions', '--no-skills', '--no-prompt-templates', '--no-themes'];
if (model) args.push('--model', model);
proc = Bun.spawn(args, {
cwd,
stdin: 'pipe',
stdout: 'pipe',
stderr: 'pipe',
env: { ...process.env, ...storedKeys, PI_CODING_AGENT_DIR: PI_CONFIG_DIR },
});
}
// Read stdout JSON event stream (runs in background)
const reader = proc.stdout.getReader();
const stdout = proc.stdout as ReadableStream<Uint8Array>;
const reader = stdout.getReader();
const decoder = new TextDecoder();
let buffer = '';
let streamBuffer = '';
@@ -63,7 +104,8 @@ export async function spawnPi(
})();
// Stderr → debug log
const stderrReader = proc.stderr.getReader();
const stderr = proc.stderr as ReadableStream<Uint8Array>;
const stderrReader = stderr.getReader();
const stderrDecoder = new TextDecoder();
(async () => {
try {