single source of truth for pi config via ~/.pi/agent
auth.json stores api keys, models.json stores local providers directly. no more copies, sync layers, or per-user config generation. docker containers mount pi config read-only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ const parseSize = (s?: string): number => {
|
||||
return Math.round(num);
|
||||
};
|
||||
|
||||
export async function listPiModels(envKeys: Record<string, string>): Promise<ModelInfo[]> {
|
||||
export async function listPiModels(): Promise<ModelInfo[]> {
|
||||
if (cachedModels && Date.now() - cacheTimestamp < CACHE_TTL_MS) {
|
||||
return cachedModels;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ export async function listPiModels(envKeys: Record<string, string>): Promise<Mod
|
||||
const proc = Bun.spawn(['pi', '--list-models'], {
|
||||
stdout: 'pipe',
|
||||
stderr: 'pipe',
|
||||
env: { ...process.env, ...envKeys, PI_CODING_AGENT_DIR: PI_CONFIG_DIR },
|
||||
env: { ...process.env, PI_CODING_AGENT_DIR: PI_CONFIG_DIR },
|
||||
});
|
||||
|
||||
const output = await new Response(proc.stdout).text();
|
||||
|
||||
@@ -3,7 +3,6 @@ import { homedir } from "node:os";
|
||||
import { readdirSync, existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
|
||||
import type { Subprocess } from "bun";
|
||||
import type { PiEvent, MessageCost } from "./types";
|
||||
import { readApiKeys } from "../server-settings/pi-mono";
|
||||
import { readSearxngConfig } from "../server-settings/searxng";
|
||||
import { PI_CONFIG_DIR, DATA_PATH, SERVER_CONFIG_DIR, getHomeDir, getGlobalSkillsDir, getUserSkillsDir, getGlobalExtensionsDir, getUserExtensionsDir, getGlobalToolsDir, getUserToolsDir, getNativeResourcesDir, getGlobalResourcesDir } from "../../data-path";
|
||||
import { ensureDockerContainer } from "../terminal/websocket";
|
||||
@@ -208,12 +207,10 @@ export async function spawnPi(
|
||||
|
||||
if (sandbox) {
|
||||
const container = await ensureDockerContainer(sandbox.email, sandbox.userId, sandbox.homeDir, sandbox.username);
|
||||
const storedKeys = await readApiKeys();
|
||||
const searxng = await readSearxngConfig();
|
||||
const dockerPath = Bun.which('docker') ?? 'docker';
|
||||
const containerId = container.dockerId;
|
||||
const containerHome = `/home/${sandbox.username}`;
|
||||
const containerPiConfig = `${containerHome}/.pi/agent`;
|
||||
|
||||
// Collect skill/extension flags using container-side paths
|
||||
const skillFlags = collectSkillFlags(sandbox.email, {
|
||||
@@ -244,7 +241,7 @@ export async function spawnPi(
|
||||
await ensureGoogleTokenFile(sandbox.userId, sandbox.email);
|
||||
|
||||
const envFlags = [
|
||||
'-e', `PI_CODING_AGENT_DIR=${containerPiConfig}`,
|
||||
'-e', `PI_CODING_AGENT_DIR=/officer/pi-config`,
|
||||
'-e', `HOME=${containerHome}`,
|
||||
'-e', `OFFICER_USER_HOME=${containerHome}`,
|
||||
'-e', `OFFICER_USER_ROOT=/officer/user`,
|
||||
@@ -255,9 +252,6 @@ export async function spawnPi(
|
||||
'-e', `OFFICER_GOOGLE_TOKEN_PATH=/officer/user/integrations/google.json`,
|
||||
'-e', `OFFICER_EMAIL_DB=/officer/emails.db`,
|
||||
];
|
||||
for (const [key, value] of Object.entries(storedKeys)) {
|
||||
if (value?.trim()) envFlags.push('-e', `${key}=${value.trim()}`);
|
||||
}
|
||||
|
||||
const rel = relative(sandbox.homeDir, cwd);
|
||||
const workdir = rel && !rel.startsWith('..') ? join(containerHome, rel) : containerHome;
|
||||
@@ -281,7 +275,6 @@ export async function spawnPi(
|
||||
extensions: extensionFlags.filter((f) => f !== '--extension').length,
|
||||
});
|
||||
} else {
|
||||
const storedKeys = await readApiKeys();
|
||||
const searxng = await readSearxngConfig();
|
||||
const skillFlags = collectSkillFlags(email);
|
||||
const extensionFlags = collectExtensionFlags(email);
|
||||
@@ -308,7 +301,6 @@ export async function spawnPi(
|
||||
stderr: 'pipe',
|
||||
env: {
|
||||
...process.env,
|
||||
...storedKeys,
|
||||
HOME: getHomeDir(email),
|
||||
OFFICER_USER_HOME: getHomeDir(email),
|
||||
OFFICER_USER_ROOT: join(DATA_PATH, email),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Context } from 'hono';
|
||||
import { createRouter } from '../../create-router';
|
||||
import * as storage from './storage';
|
||||
import { readApiKeys, readLocalProviders } from '../server-settings/pi-mono';
|
||||
import { readLocalProviders } from '../server-settings/pi-mono';
|
||||
import { readSttConfig } from '../server-settings/stt';
|
||||
import { listPiModels } from './list-models';
|
||||
import { getHomeDir } from '../../data-path';
|
||||
@@ -21,8 +21,7 @@ export const piRestRouter = createRouter();
|
||||
*/
|
||||
piRestRouter.get('/pi/models', async (ctx: Context) => {
|
||||
try {
|
||||
const storedKeys = await readApiKeys();
|
||||
const models = await listPiModels(storedKeys);
|
||||
const models = await listPiModels();
|
||||
|
||||
// Build providerNames map for officer-local-* providers
|
||||
const providerNames: Record<string, string> = {};
|
||||
|
||||
Reference in New Issue
Block a user