Overhaul Feynman harness: streamline agents, prompts, and extensions
Remove legacy chains, skills, and config modules. Add citation agent, SYSTEM.md, modular research-tools extension, and web-access layer. Add ralph-wiggum to Pi package stack for long-running loops. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,60 +0,0 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import {
|
||||
configureWebSearchProvider,
|
||||
getConfiguredWebSearchProvider,
|
||||
loadFeynmanConfig,
|
||||
saveFeynmanConfig,
|
||||
} from "../src/config/feynman-config.js";
|
||||
|
||||
test("loadFeynmanConfig falls back to legacy web-search config", () => {
|
||||
const root = mkdtempSync(join(tmpdir(), "feynman-config-"));
|
||||
const configPath = join(root, "config.json");
|
||||
const legacyDir = join(process.env.HOME ?? root, ".pi");
|
||||
const legacyPath = join(legacyDir, "web-search.json");
|
||||
mkdirSync(legacyDir, { recursive: true });
|
||||
writeFileSync(
|
||||
legacyPath,
|
||||
JSON.stringify({
|
||||
feynmanWebProvider: "perplexity",
|
||||
perplexityApiKey: "legacy-key",
|
||||
}),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const config = loadFeynmanConfig(configPath);
|
||||
assert.equal(config.version, 1);
|
||||
assert.equal(config.webSearch?.feynmanWebProvider, "perplexity");
|
||||
assert.equal(config.webSearch?.perplexityApiKey, "legacy-key");
|
||||
});
|
||||
|
||||
test("saveFeynmanConfig persists sessionDir and webSearch", () => {
|
||||
const root = mkdtempSync(join(tmpdir(), "feynman-config-"));
|
||||
const configPath = join(root, "config.json");
|
||||
const webSearch = configureWebSearchProvider({}, "gemini-browser", { chromeProfile: "Profile 2" });
|
||||
|
||||
saveFeynmanConfig(
|
||||
{
|
||||
version: 1,
|
||||
sessionDir: "/tmp/feynman-sessions",
|
||||
webSearch,
|
||||
},
|
||||
configPath,
|
||||
);
|
||||
|
||||
const config = loadFeynmanConfig(configPath);
|
||||
assert.equal(config.sessionDir, "/tmp/feynman-sessions");
|
||||
assert.equal(config.webSearch?.feynmanWebProvider, "gemini-browser");
|
||||
assert.equal(config.webSearch?.chromeProfile, "Profile 2");
|
||||
});
|
||||
|
||||
test("default web provider falls back to Pi web via gemini-browser", () => {
|
||||
const provider = getConfiguredWebSearchProvider({});
|
||||
|
||||
assert.equal(provider.id, "gemini-browser");
|
||||
assert.equal(provider.runtimeProvider, "gemini");
|
||||
});
|
||||
@@ -9,7 +9,6 @@ test("buildPiArgs includes configured runtime paths and prompt", () => {
|
||||
workingDir: "/workspace",
|
||||
sessionDir: "/sessions",
|
||||
feynmanAgentDir: "/home/.feynman/agent",
|
||||
systemPrompt: "system",
|
||||
initialPrompt: "hello",
|
||||
explicitModelSpec: "openai:gpt-5.4",
|
||||
thinkingLevel: "medium",
|
||||
@@ -20,12 +19,8 @@ test("buildPiArgs includes configured runtime paths and prompt", () => {
|
||||
"/sessions",
|
||||
"--extension",
|
||||
"/repo/feynman/extensions/research-tools.ts",
|
||||
"--skill",
|
||||
"/repo/feynman/skills",
|
||||
"--prompt-template",
|
||||
"/repo/feynman/prompts",
|
||||
"--system-prompt",
|
||||
"system",
|
||||
"--model",
|
||||
"openai:gpt-5.4",
|
||||
"--thinking",
|
||||
@@ -40,14 +35,11 @@ test("buildPiEnv wires Feynman paths into the Pi environment", () => {
|
||||
workingDir: "/workspace",
|
||||
sessionDir: "/sessions",
|
||||
feynmanAgentDir: "/home/.feynman/agent",
|
||||
systemPrompt: "system",
|
||||
feynmanVersion: "0.1.5",
|
||||
});
|
||||
|
||||
assert.equal(env.PI_CODING_AGENT_DIR, "/home/.feynman/agent");
|
||||
assert.equal(env.FEYNMAN_SESSION_DIR, "/sessions");
|
||||
assert.equal(env.FEYNMAN_BIN_PATH, "/repo/feynman/bin/feynman.js");
|
||||
assert.equal(env.FEYNMAN_PI_NPM_ROOT, "/repo/feynman/.pi/npm/node_modules");
|
||||
assert.equal(env.FEYNMAN_MEMORY_DIR, "/home/.feynman/memory");
|
||||
});
|
||||
|
||||
|
||||
54
tests/pi-web-access.test.ts
Normal file
54
tests/pi-web-access.test.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import {
|
||||
formatPiWebAccessDoctorLines,
|
||||
getPiWebAccessStatus,
|
||||
getPiWebSearchConfigPath,
|
||||
loadPiWebAccessConfig,
|
||||
} from "../src/pi/web-access.js";
|
||||
|
||||
test("loadPiWebAccessConfig returns empty config when Pi web config is missing", () => {
|
||||
const root = mkdtempSync(join(tmpdir(), "feynman-pi-web-"));
|
||||
const configPath = getPiWebSearchConfigPath(root);
|
||||
|
||||
assert.deepEqual(loadPiWebAccessConfig(configPath), {});
|
||||
});
|
||||
|
||||
test("getPiWebAccessStatus reads Pi web-access config directly", () => {
|
||||
const root = mkdtempSync(join(tmpdir(), "feynman-pi-web-"));
|
||||
const configPath = getPiWebSearchConfigPath(root);
|
||||
mkdirSync(join(root, ".pi"), { recursive: true });
|
||||
writeFileSync(
|
||||
configPath,
|
||||
JSON.stringify({
|
||||
provider: "gemini",
|
||||
searchProvider: "gemini",
|
||||
chromeProfile: "Profile 2",
|
||||
geminiApiKey: "AIza...",
|
||||
}),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const status = getPiWebAccessStatus(loadPiWebAccessConfig(configPath), configPath);
|
||||
assert.equal(status.routeLabel, "Gemini");
|
||||
assert.equal(status.requestProvider, "gemini");
|
||||
assert.equal(status.geminiApiConfigured, true);
|
||||
assert.equal(status.perplexityConfigured, false);
|
||||
assert.equal(status.chromeProfile, "Profile 2");
|
||||
});
|
||||
|
||||
test("formatPiWebAccessDoctorLines reports Pi-managed web access", () => {
|
||||
const lines = formatPiWebAccessDoctorLines(
|
||||
getPiWebAccessStatus({
|
||||
provider: "auto",
|
||||
searchProvider: "auto",
|
||||
}, "/tmp/pi-web-search.json"),
|
||||
);
|
||||
|
||||
assert.equal(lines[0], "web access: pi-web-access");
|
||||
assert.ok(lines.some((line) => line.includes("/tmp/pi-web-search.json")));
|
||||
});
|
||||
Reference in New Issue
Block a user