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:
@@ -30,6 +30,7 @@ Operating rules:
|
|||||||
- For long-running local work such as experiments, crawls, or log-following, use the process package instead of blocking the main thread unnecessarily. Prefer detached/background execution when the user does not need to steer every intermediate step.
|
- For long-running local work such as experiments, crawls, or log-following, use the process package instead of blocking the main thread unnecessarily. Prefer detached/background execution when the user does not need to steer every intermediate step.
|
||||||
- Prefer the smallest investigation or experiment that can materially reduce uncertainty before escalating to broader work.
|
- Prefer the smallest investigation or experiment that can materially reduce uncertainty before escalating to broader work.
|
||||||
- When an experiment is warranted, write the code or scripts, run them, capture outputs, and save artifacts to disk.
|
- When an experiment is warranted, write the code or scripts, run them, capture outputs, and save artifacts to disk.
|
||||||
|
- Before recommending an execution environment, consider the system resources shown in the header (CPU, RAM, GPU, Docker availability). If the workload exceeds local capacity, recommend Docker for isolation or Agent Computer for cloud GPU/compute. Do not suggest GPU workloads locally if no GPU is detected.
|
||||||
- Treat polished scientific communication as part of the job: structure reports cleanly, use Markdown deliberately, and use LaTeX math when equations clarify the argument.
|
- Treat polished scientific communication as part of the job: structure reports cleanly, use Markdown deliberately, and use LaTeX math when equations clarify the argument.
|
||||||
- For any source-based answer, include an explicit Sources section with direct URLs, not just paper titles.
|
- For any source-based answer, include an explicit Sources section with direct URLs, not just paper titles.
|
||||||
- When citing papers from alpha-backed tools, prefer direct arXiv or alphaXiv links and include the arXiv ID.
|
- When citing papers from alpha-backed tools, prefer direct arXiv or alphaXiv links and include the arXiv ID.
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ Four bundled research agents, dispatched automatically or via subagent commands.
|
|||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
- **[AlphaXiv](https://www.alphaxiv.org/)** — paper search, Q&A, code reading, persistent annotations
|
- **[AlphaXiv](https://www.alphaxiv.org/)** — paper search, Q&A, code reading, persistent annotations
|
||||||
- **[Agent Computer](https://agentcomputer.ai)** — secure cloud execution for experiments, replications, and long-running research
|
- **Docker** — isolated container execution for safe experiments on your machine
|
||||||
|
- **[Agent Computer](https://agentcomputer.ai)** — secure cloud execution for long-running research and GPU workloads
|
||||||
- **Web search** — Gemini or Perplexity, zero-config default via signed-in Chromium
|
- **Web search** — Gemini or Perplexity, zero-config default via signed-in Chromium
|
||||||
- **Session search** — indexed recall across prior research sessions
|
- **Session search** — indexed recall across prior research sessions
|
||||||
- **Preview** — browser and PDF export of generated artifacts
|
- **Preview** — browser and PDF export of generated artifacts
|
||||||
@@ -82,9 +83,9 @@ feynman search status # web search config
|
|||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
Built on [Pi](https://github.com/mariozechner/pi-coding-agent), [alphaXiv](https://www.alphaxiv.org/), and [Agent Computer](https://agentcomputer.ai). Pi provides the agent runtime. alphaXiv powers paper search, Q&A, code reading, and annotations. Agent Computer provides secure cloud machines for running experiments and replications.
|
Built on [Pi](https://github.com/mariozechner/pi-coding-agent) for the agent runtime, [alphaXiv](https://www.alphaxiv.org/) for paper search and analysis, [Docker](https://www.docker.com/) for isolated local execution, and [Agent Computer](https://agentcomputer.ai) for secure cloud workloads
|
||||||
|
|
||||||
Every output is source-grounded. Claims link to papers, docs, or repos with direct URLs.
|
Every output is source-grounded — claims link to papers, docs, or repos with direct URLs
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -96,5 +97,3 @@ cd feynman && npm install && npm run start
|
|||||||
```
|
```
|
||||||
|
|
||||||
[Docs](https://feynman.companion.ai/docs) · [MIT License](LICENSE)
|
[Docs](https://feynman.companion.ai/docs) · [MIT License](LICENSE)
|
||||||
|
|
||||||
Built on [Pi](https://github.com/mariozechner/pi-coding-agent), [alphaXiv](https://www.alphaxiv.org/), and [Agent Computer](https://agentcomputer.ai).
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { readdir } from "node:fs/promises";
|
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 { resolve as resolvePath } from "node:path";
|
||||||
|
|
||||||
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
||||||
@@ -123,6 +124,44 @@ async function buildAgentCatalogSummary(): Promise<{ agents: string[]; chains: s
|
|||||||
return { agents, chains };
|
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 };
|
type WorkflowInfo = { name: string; description: string };
|
||||||
|
|
||||||
function getResearchWorkflows(pi: ExtensionAPI): WorkflowInfo[] {
|
function getResearchWorkflows(pi: ExtensionAPI): WorkflowInfo[] {
|
||||||
@@ -150,6 +189,7 @@ export function installFeynmanHeader(
|
|||||||
cache.agentSummaryPromise ??= buildAgentCatalogSummary();
|
cache.agentSummaryPromise ??= buildAgentCatalogSummary();
|
||||||
|
|
||||||
return cache.agentSummaryPromise.then((agentData) => {
|
return cache.agentSummaryPromise.then((agentData) => {
|
||||||
|
const resources = detectSystemResources();
|
||||||
const workflows = getResearchWorkflows(pi);
|
const workflows = getResearchWorkflows(pi);
|
||||||
const toolCount = pi.getAllTools().length;
|
const toolCount = pi.getAllTools().length;
|
||||||
const commandCount = pi.getCommands().length;
|
const commandCount = pi.getCommands().length;
|
||||||
@@ -228,6 +268,11 @@ export function installFeynmanHeader(
|
|||||||
pushLabeled("directory", dirLabel, "text");
|
pushLabeled("directory", dirLabel, "text");
|
||||||
pushLabeled("session", sessionId, "dim");
|
pushLabeled("session", sessionId, "dim");
|
||||||
leftLines.push("");
|
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`));
|
leftLines.push(theme.fg("dim", `${toolCount} tools · ${agentCount} agents`));
|
||||||
|
|
||||||
const pushList = (heading: string, items: string[]) => {
|
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", "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", "directory".padEnd(10))} ${theme.fg("text", truncateVisible(dirLabel, narrowValW))}`));
|
||||||
push(row(`${theme.fg("dim", "session".padEnd(10))} ${theme.fg("dim", truncateVisible(sessionId, 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(row(theme.fg("dim", truncateVisible(`${toolCount} tools · ${agentCount} agents · ${commandCount} commands`, contentW))));
|
||||||
push(emptyRow());
|
push(emptyRow());
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ Ask the user where to run:
|
|||||||
- **Local** — run in the current working directory
|
- **Local** — run in the current working directory
|
||||||
- **New git branch** — create a branch so main stays clean
|
- **New git branch** — create a branch so main stays clean
|
||||||
- **Virtual environment** — create an isolated venv/conda env first
|
- **Virtual environment** — create an isolated venv/conda env first
|
||||||
|
- **Docker** — run experiment code inside an isolated Docker container
|
||||||
- **Cloud** — delegate to a remote Agent Computer machine via `/delegate`
|
- **Cloud** — delegate to a remote Agent Computer machine via `/delegate`
|
||||||
|
|
||||||
Do not proceed without a clear answer.
|
Do not proceed without a clear answer.
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Design a replication plan for: $@
|
|||||||
3. **Environment** — Before running anything, ask the user where to execute:
|
3. **Environment** — Before running anything, ask the user where to execute:
|
||||||
- **Local** — run in the current working directory
|
- **Local** — run in the current working directory
|
||||||
- **Virtual environment** — create an isolated venv/conda env first
|
- **Virtual environment** — create an isolated venv/conda env first
|
||||||
|
- **Docker** — run experiment code inside an isolated Docker container
|
||||||
- **Cloud** — delegate to a remote Agent Computer machine via `/delegate`
|
- **Cloud** — delegate to a remote Agent Computer machine via `/delegate`
|
||||||
- **Plan only** — produce the replication plan without executing
|
- **Plan only** — produce the replication plan without executing
|
||||||
4. **Execute** — If the user chose an execution environment, implement and run the replication steps there. Save notes, scripts, and results to disk in a reproducible layout.
|
4. **Execute** — If the user chose an execution environment, implement and run the replication steps there. Save notes, scripts, and results to disk in a reproducible layout.
|
||||||
|
|||||||
10
skills-lock.json
Normal file
10
skills-lock.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"skills": {
|
||||||
|
"find-skills": {
|
||||||
|
"source": "vercel-labs/skills",
|
||||||
|
"sourceType": "github",
|
||||||
|
"computedHash": "d31e234f0c90694a670222cdd1dafa853e051d7066beda389f1097c22dadd461"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
skills/docker/SKILL.md
Normal file
84
skills/docker/SKILL.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
name: docker
|
||||||
|
description: Execute research code inside isolated Docker containers for safe replication, experiments, and benchmarks. Use when the user selects Docker as the execution environment or asks to run code safely, in isolation, or in a sandbox.
|
||||||
|
allowed-tools: Bash(docker:*)
|
||||||
|
---
|
||||||
|
|
||||||
|
# Docker Sandbox
|
||||||
|
|
||||||
|
Run research code inside Docker containers while Feynman stays on the host. The container gets the project files, runs the commands, and results sync back.
|
||||||
|
|
||||||
|
## When to use
|
||||||
|
|
||||||
|
- User selects "Docker Sandbox" as the execution environment in `/replicate` or `/autoresearch`
|
||||||
|
- Running untrusted code from a paper's repository
|
||||||
|
- Experiments that install packages or modify system state
|
||||||
|
- Any time the user asks to run something "safely" or "isolated"
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
1. Build or pull an appropriate base image for the research code
|
||||||
|
2. Mount the project directory into the container
|
||||||
|
3. Run experiment commands inside the container
|
||||||
|
4. Results write back to the mounted directory
|
||||||
|
|
||||||
|
## Running commands in a container
|
||||||
|
|
||||||
|
For Python research code (most common):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -v "$(pwd)":/workspace -w /workspace python:3.11 bash -c "
|
||||||
|
pip install -r requirements.txt &&
|
||||||
|
python train.py
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
For projects with a Dockerfile:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t feynman-experiment .
|
||||||
|
docker run --rm -v "$(pwd)/results":/workspace/results feynman-experiment
|
||||||
|
```
|
||||||
|
|
||||||
|
For GPU workloads:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm --gpus all -v "$(pwd)":/workspace -w /workspace pytorch/pytorch:latest bash -c "
|
||||||
|
pip install -r requirements.txt &&
|
||||||
|
python train.py
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Choosing the base image
|
||||||
|
|
||||||
|
| Research type | Base image |
|
||||||
|
| --- | --- |
|
||||||
|
| Python ML/DL | `pytorch/pytorch:latest` or `tensorflow/tensorflow:latest-gpu` |
|
||||||
|
| Python general | `python:3.11` |
|
||||||
|
| Node.js | `node:20` |
|
||||||
|
| R / statistics | `rocker/r-ver:4` |
|
||||||
|
| Julia | `julia:1.10` |
|
||||||
|
| Multi-language | `ubuntu:24.04` with manual installs |
|
||||||
|
|
||||||
|
## Persistent containers
|
||||||
|
|
||||||
|
For iterative experiments (like `/autoresearch`), create a named container instead of `--rm`. Choose a descriptive name based on the experiment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker create --name <name> -v "$(pwd)":/workspace -w /workspace python:3.11 tail -f /dev/null
|
||||||
|
docker start <name>
|
||||||
|
docker exec <name> bash -c "pip install -r requirements.txt"
|
||||||
|
docker exec <name> bash -c "python train.py"
|
||||||
|
```
|
||||||
|
|
||||||
|
This preserves installed packages across iterations. Clean up with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker stop <name> && docker rm <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The mounted workspace syncs results back to the host automatically
|
||||||
|
- Containers are network-enabled by default — add `--network none` for full isolation
|
||||||
|
- For GPU access, Docker must be configured with the NVIDIA Container Toolkit
|
||||||
File diff suppressed because one or more lines are too long
@@ -19,6 +19,7 @@ Before running code, Feynman asks you to choose an execution environment:
|
|||||||
|
|
||||||
- **Local** — run in the current working directory
|
- **Local** — run in the current working directory
|
||||||
- **Virtual environment** — create an isolated venv/conda env first
|
- **Virtual environment** — create an isolated venv/conda env first
|
||||||
|
- **Docker** — run experiment code inside an isolated Docker container
|
||||||
- **Cloud** — delegate to a remote Agent Computer machine
|
- **Cloud** — delegate to a remote Agent Computer machine
|
||||||
- **Plan only** — produce the replication plan without executing
|
- **Plan only** — produce the replication plan without executing
|
||||||
|
|
||||||
|
|||||||
@@ -116,9 +116,13 @@ import Base from '../layouts/Base.astro';
|
|||||||
<div class="font-semibold mb-1"><a href="https://www.alphaxiv.org/" class="text-accent hover:underline">AlphaXiv</a></div>
|
<div class="font-semibold mb-1"><a href="https://www.alphaxiv.org/" class="text-accent hover:underline">AlphaXiv</a></div>
|
||||||
<p class="text-sm text-text-muted">Paper search, Q&A, code reading, persistent annotations</p>
|
<p class="text-sm text-text-muted">Paper search, Q&A, code reading, persistent annotations</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bg-surface rounded-xl p-5">
|
||||||
|
<div class="font-semibold mb-1"><a href="https://www.docker.com/" class="text-accent hover:underline">Docker</a></div>
|
||||||
|
<p class="text-sm text-text-muted">Isolated container execution for safe local experiments</p>
|
||||||
|
</div>
|
||||||
<div class="bg-surface rounded-xl p-5">
|
<div class="bg-surface rounded-xl p-5">
|
||||||
<div class="font-semibold mb-1"><a href="https://agentcomputer.ai" class="text-accent hover:underline">Agent Computer</a></div>
|
<div class="font-semibold mb-1"><a href="https://agentcomputer.ai" class="text-accent hover:underline">Agent Computer</a></div>
|
||||||
<p class="text-sm text-text-muted">Secure cloud execution for experiments and replications</p>
|
<p class="text-sm text-text-muted">Secure cloud execution for GPU workloads and long-running research</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-surface rounded-xl p-5">
|
<div class="bg-surface rounded-xl p-5">
|
||||||
<div class="font-semibold mb-1">Web search</div>
|
<div class="font-semibold mb-1">Web search</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user