fix startup packaging and content guardrails

This commit is contained in:
Advait Paliwal
2026-04-09 10:09:05 -07:00
parent 554350cc0e
commit 3148f2e62b
39 changed files with 518 additions and 43 deletions

View File

@@ -1,7 +1,7 @@
import { spawn } from "node:child_process";
import { existsSync } from "node:fs";
import { buildPiArgs, buildPiEnv, type PiRuntimeOptions, resolvePiPaths } from "./runtime.js";
import { buildPiArgs, buildPiEnv, type PiRuntimeOptions, resolvePiPaths, toNodeImportSpecifier } from "./runtime.js";
import { ensureSupportedNodeVersion } from "../system/node-version.js";
export async function launchPiChat(options: PiRuntimeOptions): Promise<void> {
@@ -23,8 +23,8 @@ export async function launchPiChat(options: PiRuntimeOptions): Promise<void> {
}
const importArgs = useDevPolyfill
? ["--import", tsxLoaderPath, "--import", promisePolyfillSourcePath]
: ["--import", promisePolyfillPath];
? ["--import", toNodeImportSpecifier(tsxLoaderPath), "--import", toNodeImportSpecifier(promisePolyfillSourcePath)]
: ["--import", toNodeImportSpecifier(promisePolyfillPath)];
const child = spawn(process.execPath, [...importArgs, piCliPath, ...buildPiArgs(options)], {
cwd: options.workingDir,

View File

@@ -1,5 +1,6 @@
import { existsSync, readFileSync } from "node:fs";
import { delimiter, dirname, resolve } from "node:path";
import { delimiter, dirname, isAbsolute, resolve } from "node:path";
import { pathToFileURL } from "node:url";
import {
BROWSER_FALLBACK_PATHS,
@@ -47,6 +48,10 @@ export function resolvePiPaths(appRoot: string) {
};
}
export function toNodeImportSpecifier(modulePath: string): string {
return isAbsolute(modulePath) ? pathToFileURL(modulePath).href : modulePath;
}
export function validatePiInstallation(appRoot: string): string[] {
const paths = resolvePiPaths(appRoot);
const missing: string[] = [];
@@ -97,6 +102,7 @@ export function buildPiEnv(options: PiRuntimeOptions): NodeJS.ProcessEnv {
const paths = resolvePiPaths(options.appRoot);
const feynmanNpmPrefixPath = getFeynmanNpmPrefixPath(options.feynmanAgentDir);
const feynmanNpmBinPath = resolve(feynmanNpmPrefixPath, "bin");
const feynmanWebSearchConfigPath = resolve(dirname(options.feynmanAgentDir), "web-search.json");
const currentPath = process.env.PATH ?? "";
const binEntries = [paths.nodeModulesBinPath, resolve(paths.piWorkspaceNodeModulesPath, ".bin"), feynmanNpmBinPath];
@@ -108,6 +114,7 @@ export function buildPiEnv(options: PiRuntimeOptions): NodeJS.ProcessEnv {
FEYNMAN_VERSION: options.feynmanVersion,
FEYNMAN_SESSION_DIR: options.sessionDir,
FEYNMAN_MEMORY_DIR: resolve(dirname(options.feynmanAgentDir), "memory"),
FEYNMAN_WEB_SEARCH_CONFIG: feynmanWebSearchConfigPath,
FEYNMAN_NODE_EXECUTABLE: process.execPath,
FEYNMAN_BIN_PATH: resolve(options.appRoot, "bin", "feynman.js"),
FEYNMAN_NPM_PREFIX: feynmanNpmPrefixPath,

View File

@@ -5,6 +5,7 @@ import { resolve } from "node:path";
export type PiWebSearchProvider = "auto" | "perplexity" | "exa" | "gemini";
export type PiWebAccessConfig = Record<string, unknown> & {
route?: PiWebSearchProvider;
provider?: PiWebSearchProvider;
searchProvider?: PiWebSearchProvider;
perplexityApiKey?: string;
@@ -80,8 +81,9 @@ export function getPiWebAccessStatus(
config: PiWebAccessConfig = loadPiWebAccessConfig(),
configPath = getPiWebSearchConfigPath(),
): PiWebAccessStatus {
const searchProvider = normalizeProvider(config.searchProvider) ?? "auto";
const requestProvider = normalizeProvider(config.provider) ?? searchProvider;
const searchProvider =
normalizeProvider(config.searchProvider) ?? normalizeProvider(config.route) ?? normalizeProvider(config.provider) ?? "auto";
const requestProvider = normalizeProvider(config.provider) ?? normalizeProvider(config.route) ?? searchProvider;
const perplexityConfigured = Boolean(normalizeNonEmptyString(config.perplexityApiKey));
const exaConfigured = Boolean(normalizeNonEmptyString(config.exaApiKey));
const geminiApiConfigured = Boolean(normalizeNonEmptyString(config.geminiApiKey));