Add system resource detection, Docker execution skill, and environment-aware recommendations
- TUI header now shows CPU cores, RAM, GPU, and Docker availability - System prompt uses resource info to recommend execution environments - Docker skill for running experiment code in isolated containers - Renamed docker-sandbox skill to docker (Feynman stays on host, code runs in containers) - Updated README and website to cite Docker alongside Agent Computer Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { readdir } from "node:fs/promises";
|
||||
import { homedir } from "node:os";
|
||||
import { cpus, freemem, homedir, totalmem } from "node:os";
|
||||
import { execSync } from "node:child_process";
|
||||
import { resolve as resolvePath } from "node:path";
|
||||
|
||||
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
||||
@@ -123,6 +124,44 @@ async function buildAgentCatalogSummary(): Promise<{ agents: string[]; chains: s
|
||||
return { agents, chains };
|
||||
}
|
||||
|
||||
type SystemResources = {
|
||||
cpu: string;
|
||||
cores: number;
|
||||
ramTotal: string;
|
||||
ramFree: string;
|
||||
gpu: string | null;
|
||||
docker: boolean;
|
||||
};
|
||||
|
||||
function detectSystemResources(): SystemResources {
|
||||
const cores = cpus().length;
|
||||
const cpu = cpus()[0]?.model?.trim() ?? "unknown";
|
||||
const totalBytes = totalmem();
|
||||
const freeBytes = freemem();
|
||||
const ramTotal = `${Math.round(totalBytes / (1024 ** 3))}GB`;
|
||||
const ramFree = `${Math.round(freeBytes / (1024 ** 3))}GB`;
|
||||
|
||||
let gpu: string | null = null;
|
||||
try {
|
||||
if (process.platform === "darwin") {
|
||||
const out = execSync("system_profiler SPDisplaysDataType 2>/dev/null | grep 'Chipset Model\\|Chip Model'", { encoding: "utf8", timeout: 3000 }).trim();
|
||||
const match = out.match(/:\s*(.+)/);
|
||||
if (match) gpu = match[1]!.trim();
|
||||
} else {
|
||||
const out = execSync("nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null", { encoding: "utf8", timeout: 3000 }).trim();
|
||||
if (out) gpu = out.split("\n")[0]!.trim();
|
||||
}
|
||||
} catch {}
|
||||
|
||||
let docker = false;
|
||||
try {
|
||||
execSync("docker info 2>/dev/null", { timeout: 3000 });
|
||||
docker = true;
|
||||
} catch {}
|
||||
|
||||
return { cpu, cores, ramTotal, ramFree, gpu, docker };
|
||||
}
|
||||
|
||||
type WorkflowInfo = { name: string; description: string };
|
||||
|
||||
function getResearchWorkflows(pi: ExtensionAPI): WorkflowInfo[] {
|
||||
@@ -150,6 +189,7 @@ export function installFeynmanHeader(
|
||||
cache.agentSummaryPromise ??= buildAgentCatalogSummary();
|
||||
|
||||
return cache.agentSummaryPromise.then((agentData) => {
|
||||
const resources = detectSystemResources();
|
||||
const workflows = getResearchWorkflows(pi);
|
||||
const toolCount = pi.getAllTools().length;
|
||||
const commandCount = pi.getCommands().length;
|
||||
@@ -228,6 +268,11 @@ export function installFeynmanHeader(
|
||||
pushLabeled("directory", dirLabel, "text");
|
||||
pushLabeled("session", sessionId, "dim");
|
||||
leftLines.push("");
|
||||
pushLabeled("cpu", `${resources.cores} cores`, "dim");
|
||||
pushLabeled("ram", `${resources.ramFree} free / ${resources.ramTotal}`, "dim");
|
||||
if (resources.gpu) pushLabeled("gpu", resources.gpu, "dim");
|
||||
pushLabeled("docker", resources.docker ? "available" : "not found", "dim");
|
||||
leftLines.push("");
|
||||
leftLines.push(theme.fg("dim", `${toolCount} tools · ${agentCount} agents`));
|
||||
|
||||
const pushList = (heading: string, items: string[]) => {
|
||||
@@ -298,6 +343,8 @@ export function installFeynmanHeader(
|
||||
push(row(`${theme.fg("dim", "model".padEnd(10))} ${theme.fg("text", truncateVisible(modelLabel, narrowValW))}`));
|
||||
push(row(`${theme.fg("dim", "directory".padEnd(10))} ${theme.fg("text", truncateVisible(dirLabel, narrowValW))}`));
|
||||
push(row(`${theme.fg("dim", "session".padEnd(10))} ${theme.fg("dim", truncateVisible(sessionId, narrowValW))}`));
|
||||
const resourceLine = `${resources.cores} cores · ${resources.ramTotal} ram${resources.gpu ? ` · ${resources.gpu}` : ""}${resources.docker ? " · docker" : ""}`;
|
||||
push(row(theme.fg("dim", truncateVisible(resourceLine, contentW))));
|
||||
push(row(theme.fg("dim", truncateVisible(`${toolCount} tools · ${agentCount} agents · ${commandCount} commands`, contentW))));
|
||||
push(emptyRow());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user