@companion-ai/feynman 0.5.41 → 0.5.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.feynman/settings.json +2 -1
- package/.feynman/themes/feynman.json +1 -1
- package/RELEASES.md +15 -0
- package/dist/cli.js +7 -1
- package/dist/model/commands.js +91 -96
- package/dist/pi/runtime.js +3 -2
- package/package.json +8 -9
package/.feynman/settings.json
CHANGED
package/RELEASES.md
CHANGED
|
@@ -6,6 +6,21 @@ GitHub release notes are generated from the matching `## vX.Y.Z` section in this
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## v0.5.42 - 2026-10-13
|
|
10
|
+
|
|
11
|
+
- **Pi 1.2.0 and pi-subagents 0.78.0.**
|
|
12
|
+
- With an OpenRouter key, `/model` lists only the models that key can use, with their real context sizes and prices.
|
|
13
|
+
- "The upstream provider returned an error" is retried instead of ending the turn, and Anthropic requests rejected for too many strict tools are retried once.
|
|
14
|
+
- `feynman -p` warns and exits 1 when the answer was cut off at the model's output limit.
|
|
15
|
+
- On Windows, reading or writing saved logins no longer fails with `EPERM` while an old lock is cleaned up.
|
|
16
|
+
- Pressing `Esc` keeps a research run stopped; a subagent finishing a moment later no longer restarts it.
|
|
17
|
+
- Reports are no longer overwritten when a subagent run is resumed, and a timed-out subagent's partial output reaches the lead agent.
|
|
18
|
+
- The `workflowScript contains dynamic child launches` warning no longer prints on every parallel run.
|
|
19
|
+
- **`feynman model login` offers every provider Pi supports with an API key.** That is 41 providers instead of Feynman's own list of 16, adding DeepSeek, Fireworks, Together, NVIDIA, Google Vertex, Cloudflare, Qwen and others. Pi now asks for what each provider needs, so Cloudflare's extra fields and Bedrock's profile or bearer-token options work. Pressing Enter on an empty key no longer saves an empty credential.
|
|
20
|
+
- **Turning off Feynman's telemetry also turns off Pi's.** `FEYNMAN_TELEMETRY=off` (or `DO_NOT_TRACK=1`) now sets Pi's own `PI_TELEMETRY=0` for its install reporting.
|
|
21
|
+
- Feynman now honors Pi's own `sessionDir` setting and `PI_CODING_AGENT_SESSION_DIR` when you don't pass `--session-dir`.
|
|
22
|
+
- `feynman model set` and the default-model check use Pi's settings API, so they match what Pi launches with (including trusted project settings).
|
|
23
|
+
|
|
9
24
|
## v0.5.41 - 2026-10-12
|
|
10
25
|
|
|
11
26
|
- **A fresh `npm install` works again.** Pi 1.2.0, released today, made new npm installs of Feynman 0.5.40 fail on every command except `-v` (`does not provide an export named 'MCP_TYPESCRIPT_PREAMBLE'`). Pi 1.1.0 asks for its own sub-packages with open version ranges, so npm pulled Pi 1.2.0's copies. Feynman now pins those sub-packages to the Pi version it ships. The curl and PowerShell installers were not affected.
|
package/dist/cli.js
CHANGED
|
@@ -29,6 +29,7 @@ import { fetchLatestFeynmanVersion, getFeynmanUpgradeLines, isNewerVersion } fro
|
|
|
29
29
|
import { runDoctor, runStatus } from "./setup/doctor.js";
|
|
30
30
|
import { setupPreviewDependencies } from "./setup/preview.js";
|
|
31
31
|
import { runSetup } from "./setup/setup.js";
|
|
32
|
+
import { SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
32
33
|
import { noModelMessage } from "./setup/prompts.js";
|
|
33
34
|
import { captureTelemetryEvent, captureTelemetryException, getCliTelemetryMetadata, initializePostHogTelemetry, shutdownPostHogTelemetry, telemetryErrorProperties, telemetryFirstRunNotice, } from "./telemetry/posthog.js";
|
|
34
35
|
import { ASH, printAsciiHeader, printInfo, printPanel, printSection, RESET, SAGE } from "./ui/terminal.js";
|
|
@@ -516,7 +517,12 @@ async function runMain(input) {
|
|
|
516
517
|
throw new Error("Unable to determine the installed Feynman version.");
|
|
517
518
|
}
|
|
518
519
|
const workingDir = resolve(values.cwd ?? process.cwd());
|
|
519
|
-
|
|
520
|
+
// Pi's order: --session-dir, then PI_CODING_AGENT_SESSION_DIR, then the sessionDir
|
|
521
|
+
// setting; Feynman's own default comes last.
|
|
522
|
+
const sessionDir = resolve(workingDir, values["session-dir"] ??
|
|
523
|
+
process.env.PI_CODING_AGENT_SESSION_DIR ??
|
|
524
|
+
SettingsManager.create(workingDir, feynmanAgentDir).getSessionDir() ??
|
|
525
|
+
getDefaultSessionDir(feynmanHome));
|
|
520
526
|
const feynmanSettingsPath = resolve(feynmanAgentDir, "settings.json");
|
|
521
527
|
const feynmanAuthPath = resolve(feynmanAgentDir, "auth.json");
|
|
522
528
|
const { defaultThinkingLevel, launchThinkingLevel } = resolveThinkingConfig(values.thinking ?? process.env.FEYNMAN_THINKING);
|
package/dist/model/commands.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { readFileSync
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
3
|
import { exec as execCallback } from "node:child_process";
|
|
4
4
|
import { dirname } from "node:path";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
|
-
import { readJson } from "../pi/settings.js";
|
|
7
6
|
import { promptChoice, promptSecret, promptSelect, promptText, SetupCancelledError, validateApiKeyInput } from "../setup/prompts.js";
|
|
8
7
|
import { openUrl } from "../system/open-url.js";
|
|
9
8
|
import { printInfo, printSection, printSuccess, printWarning } from "../ui/terminal.js";
|
|
@@ -54,19 +53,32 @@ async function selectOAuthProvider(authPath, action) {
|
|
|
54
53
|
}
|
|
55
54
|
return selection;
|
|
56
55
|
}
|
|
57
|
-
|
|
56
|
+
// Endpoints Pi has no API-key sign-in for: Feynman writes their models.json entry.
|
|
57
|
+
const LOCAL_API_KEY_SETUPS = MODEL_API_KEY_PROVIDERS.filter((provider) => ["lm-studio", "litellm", "__custom__"].includes(provider.id));
|
|
58
|
+
// Every provider Pi can sign in to with an API key (its own list, labels and
|
|
59
|
+
// prompts), plus Feynman's local and custom endpoint setups.
|
|
60
|
+
export async function listApiKeyProviders(authPath) {
|
|
61
|
+
const envVars = new Map(MODEL_API_KEY_PROVIDERS.map((provider) => [provider.id, provider.envVar]));
|
|
62
|
+
const piProviders = (await createModelRuntime(authPath))
|
|
63
|
+
.getProviders()
|
|
64
|
+
.filter((provider) => provider.auth.apiKey)
|
|
65
|
+
.map((provider) => ({ id: provider.id, label: provider.name, envVar: envVars.get(provider.id) }))
|
|
66
|
+
.sort((left, right) => left.label.localeCompare(right.label));
|
|
67
|
+
return [...piProviders, ...LOCAL_API_KEY_SETUPS];
|
|
68
|
+
}
|
|
69
|
+
async function resolveApiKeyProvider(authPath, input) {
|
|
58
70
|
const normalizedInput = normalizeProviderId(input);
|
|
59
71
|
if (!normalizedInput) {
|
|
60
72
|
return undefined;
|
|
61
73
|
}
|
|
62
|
-
return
|
|
74
|
+
return (await listApiKeyProviders(authPath)).find((provider) => provider.id === normalizedInput);
|
|
63
75
|
}
|
|
64
76
|
export async function resolveModelProviderForCommand(authPath, input) {
|
|
65
77
|
const oauthProvider = await resolveOAuthProvider(authPath, input);
|
|
66
78
|
if (oauthProvider) {
|
|
67
79
|
return { kind: "oauth", id: oauthProvider.id };
|
|
68
80
|
}
|
|
69
|
-
const apiKeyProvider = resolveApiKeyProvider(input);
|
|
81
|
+
const apiKeyProvider = await resolveApiKeyProvider(authPath, input);
|
|
70
82
|
if (apiKeyProvider) {
|
|
71
83
|
return { kind: "api-key", id: apiKeyProvider.id };
|
|
72
84
|
}
|
|
@@ -84,14 +96,15 @@ function apiKeyProviderHint(provider) {
|
|
|
84
96
|
}
|
|
85
97
|
return provider.envVar ?? provider.id;
|
|
86
98
|
}
|
|
87
|
-
async function selectApiKeyProvider() {
|
|
88
|
-
const
|
|
99
|
+
async function selectApiKeyProvider(authPath) {
|
|
100
|
+
const providers = await listApiKeyProviders(authPath);
|
|
101
|
+
const options = providers.map((provider) => ({
|
|
89
102
|
value: provider,
|
|
90
103
|
label: provider.label,
|
|
91
104
|
hint: apiKeyProviderHint(provider),
|
|
92
105
|
}));
|
|
93
106
|
options.push({ value: "cancel", label: "Cancel" });
|
|
94
|
-
const defaultProvider =
|
|
107
|
+
const defaultProvider = providers.find((provider) => provider.id === "openai") ?? providers[0];
|
|
95
108
|
const selection = await promptSelect("Choose an API-key provider:", options, defaultProvider);
|
|
96
109
|
if (selection === "cancel") {
|
|
97
110
|
return undefined;
|
|
@@ -501,36 +514,6 @@ async function verifyCustomProvider(setup, authPath) {
|
|
|
501
514
|
}
|
|
502
515
|
printInfo("Verification: skipped network probe for this API mode.");
|
|
503
516
|
}
|
|
504
|
-
async function verifyBedrockCredentialChain() {
|
|
505
|
-
const { defaultProvider } = await import("@aws-sdk/credential-provider-node");
|
|
506
|
-
const credentials = await defaultProvider({})();
|
|
507
|
-
if (!credentials?.accessKeyId || !credentials?.secretAccessKey) {
|
|
508
|
-
throw new Error("AWS credential chain resolved without usable Bedrock credentials.");
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
async function configureBedrockProvider(authPath) {
|
|
512
|
-
printSection("AWS Credentials: Amazon Bedrock");
|
|
513
|
-
printInfo("Feynman will verify the AWS SDK credential chain used by Pi's Bedrock provider.");
|
|
514
|
-
printInfo("Supported sources include AWS_PROFILE, ~/.aws credentials/config, SSO, ECS/IRSA, and EC2 instance roles.");
|
|
515
|
-
try {
|
|
516
|
-
await verifyBedrockCredentialChain();
|
|
517
|
-
const modelRuntime = await createModelRuntime(authPath);
|
|
518
|
-
if (!(await modelRuntime.checkAuth("amazon-bedrock"))) {
|
|
519
|
-
throw new Error("Pi could not resolve the verified AWS credential chain for Amazon Bedrock.");
|
|
520
|
-
}
|
|
521
|
-
printSuccess("Verified the AWS credential chain used by Amazon Bedrock.");
|
|
522
|
-
printInfo("Use `feynman model list` to see available Bedrock models.");
|
|
523
|
-
return true;
|
|
524
|
-
}
|
|
525
|
-
catch (error) {
|
|
526
|
-
printWarning(`AWS credential verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
527
|
-
printInfo("Configure AWS credentials first, for example:");
|
|
528
|
-
printInfo(" export AWS_PROFILE=default");
|
|
529
|
-
printInfo(" # or set AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY");
|
|
530
|
-
printInfo(" # or use an EC2/ECS/IRSA role with valid Bedrock access");
|
|
531
|
-
return false;
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
517
|
async function maybeSetRecommendedDefaultModel(settingsPath, authPath) {
|
|
535
518
|
if (!settingsPath) {
|
|
536
519
|
return;
|
|
@@ -546,7 +529,7 @@ async function maybeSetRecommendedDefaultModel(settingsPath, authPath) {
|
|
|
546
529
|
}
|
|
547
530
|
}
|
|
548
531
|
async function configureApiKeyProvider(authPath, providerId) {
|
|
549
|
-
const provider = providerId ? resolveApiKeyProvider(providerId) : await selectApiKeyProvider();
|
|
532
|
+
const provider = providerId ? await resolveApiKeyProvider(authPath, providerId) : await selectApiKeyProvider(authPath);
|
|
550
533
|
if (!provider) {
|
|
551
534
|
if (providerId) {
|
|
552
535
|
throw new Error(`Unknown API-key model provider: ${providerId}`);
|
|
@@ -554,9 +537,6 @@ async function configureApiKeyProvider(authPath, providerId) {
|
|
|
554
537
|
printInfo("API key setup cancelled.");
|
|
555
538
|
return false;
|
|
556
539
|
}
|
|
557
|
-
if (provider.id === "amazon-bedrock") {
|
|
558
|
-
return configureBedrockProvider(authPath);
|
|
559
|
-
}
|
|
560
540
|
if (provider.id === "lm-studio") {
|
|
561
541
|
const setup = await promptLmStudioProviderSetup();
|
|
562
542
|
if (!setup) {
|
|
@@ -627,22 +607,34 @@ async function configureApiKeyProvider(authPath, providerId) {
|
|
|
627
607
|
if (provider.envVar) {
|
|
628
608
|
printInfo(`Tip: to avoid writing secrets to disk, set ${provider.envVar} in your shell or .env.`);
|
|
629
609
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (provider.envVar) {
|
|
633
|
-
printInfo(`Set ${provider.envVar} and rerun setup (or run \`feynman model list\`).`);
|
|
634
|
-
}
|
|
635
|
-
else {
|
|
636
|
-
printInfo("No API key provided.");
|
|
637
|
-
}
|
|
638
|
-
return false;
|
|
639
|
-
}
|
|
610
|
+
// Pi asks for whatever this provider needs (a key, or e.g. Cloudflare's account
|
|
611
|
+
// and gateway, Bedrock's profile or token). Esc cancels.
|
|
640
612
|
const modelRuntime = await createModelRuntime(authPath);
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
613
|
+
const interaction = terminalAuthInteraction(provider.label, new AbortController().signal);
|
|
614
|
+
const signedIn = await modelRuntime
|
|
615
|
+
.login(provider.id, "api_key", {
|
|
616
|
+
...interaction,
|
|
617
|
+
prompt: async (prompt) => {
|
|
618
|
+
if (prompt.type !== "secret")
|
|
619
|
+
return interaction.prompt(prompt);
|
|
620
|
+
const secret = await promptSecret(prompt.message, prompt.signal, validateApiKeyInput);
|
|
621
|
+
// An empty key would be saved as a credential that fails every request.
|
|
622
|
+
if (!secret)
|
|
623
|
+
throw new SetupCancelledError("no API key entered");
|
|
624
|
+
return secret;
|
|
625
|
+
},
|
|
626
|
+
})
|
|
627
|
+
.then(() => true)
|
|
628
|
+
.catch((error) => {
|
|
629
|
+
if (!(error instanceof SetupCancelledError))
|
|
630
|
+
throw error;
|
|
631
|
+
if (provider.envVar)
|
|
632
|
+
printInfo(`Or set ${provider.envVar} and run feynman again.`);
|
|
633
|
+
return false;
|
|
644
634
|
});
|
|
645
|
-
|
|
635
|
+
if (!signedIn)
|
|
636
|
+
return false;
|
|
637
|
+
printSuccess(`Saved ${provider.label} credentials in auth storage.`);
|
|
646
638
|
const baseUrl = await promptText("Base URL override (optional, include /v1 for OpenAI-compatible endpoints)", "");
|
|
647
639
|
if (baseUrl) {
|
|
648
640
|
const modelsJsonPath = getModelsJsonPath(authPath);
|
|
@@ -683,12 +675,12 @@ async function resolveAvailableModelSpec(authPath, input) {
|
|
|
683
675
|
}
|
|
684
676
|
return undefined;
|
|
685
677
|
}
|
|
678
|
+
// The default model Pi will launch with, read through Pi's SettingsManager.
|
|
686
679
|
export function getCurrentModelSpec(settingsPath) {
|
|
687
|
-
const settings =
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
}
|
|
691
|
-
return undefined;
|
|
680
|
+
const settings = SettingsManager.create(process.cwd(), dirname(settingsPath));
|
|
681
|
+
const provider = settings.getDefaultProvider();
|
|
682
|
+
const model = settings.getDefaultModel();
|
|
683
|
+
return provider && model ? `${provider}/${model}` : undefined;
|
|
692
684
|
}
|
|
693
685
|
export async function printModelList(settingsPath, authPath) {
|
|
694
686
|
const status = await collectModelStatus(settingsPath, authPath);
|
|
@@ -758,32 +750,9 @@ export function describeOAuthLoginFailure(providerId, error) {
|
|
|
758
750
|
async function refreshProviderModels(modelRuntime, providerId) {
|
|
759
751
|
await modelRuntime.refresh({ providers: [providerId], allowNetwork: true, signal: AbortSignal.timeout(15_000) }).catch(() => undefined);
|
|
760
752
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
if (!resolvedProvider) {
|
|
765
|
-
throw new Error(`Unknown model provider: ${providerId}`);
|
|
766
|
-
}
|
|
767
|
-
if (resolvedProvider.kind === "api-key") {
|
|
768
|
-
const configured = await configureApiKeyProvider(authPath, resolvedProvider.id);
|
|
769
|
-
if (configured) {
|
|
770
|
-
await maybeSetRecommendedDefaultModel(settingsPath, authPath);
|
|
771
|
-
}
|
|
772
|
-
return configured;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
const provider = providerId ? await resolveOAuthProvider(authPath, providerId) : await selectOAuthProvider(authPath, "login");
|
|
776
|
-
if (!provider) {
|
|
777
|
-
if (providerId) {
|
|
778
|
-
throw new Error(`Unknown model provider: ${providerId}`);
|
|
779
|
-
}
|
|
780
|
-
printInfo("Login cancelled.");
|
|
781
|
-
return false;
|
|
782
|
-
}
|
|
783
|
-
const modelRuntime = await createModelRuntime(authPath);
|
|
784
|
-
const abortController = new AbortController();
|
|
785
|
-
const deviceId = await getOrCreateDeviceId(authPath);
|
|
786
|
-
await modelRuntime.login(provider.id, "oauth", {
|
|
753
|
+
// Runs Pi's own login prompts (selects, secrets, text, browser URLs) in the terminal.
|
|
754
|
+
function terminalAuthInteraction(providerLabel, signal) {
|
|
755
|
+
return {
|
|
787
756
|
prompt: async (prompt) => {
|
|
788
757
|
if (prompt.type === "select") {
|
|
789
758
|
return promptSelect(prompt.message, prompt.options.map((option) => ({
|
|
@@ -802,7 +771,7 @@ export async function loginModelProvider(authPath, providerId, settingsPath) {
|
|
|
802
771
|
},
|
|
803
772
|
notify: (event) => {
|
|
804
773
|
if (event.type === "auth_url") {
|
|
805
|
-
printSection(`Login: ${
|
|
774
|
+
printSection(`Login: ${providerLabel}`);
|
|
806
775
|
if (openUrl(event.url)) {
|
|
807
776
|
printInfo("Opened the login URL in your browser.");
|
|
808
777
|
}
|
|
@@ -816,7 +785,7 @@ export async function loginModelProvider(authPath, providerId, settingsPath) {
|
|
|
816
785
|
return;
|
|
817
786
|
}
|
|
818
787
|
if (event.type === "device_code") {
|
|
819
|
-
printSection(`Login: ${
|
|
788
|
+
printSection(`Login: ${providerLabel}`);
|
|
820
789
|
printInfo(`Visit ${event.verificationUri} and enter code: ${event.userCode}`);
|
|
821
790
|
openUrl(event.verificationUri);
|
|
822
791
|
return;
|
|
@@ -825,8 +794,35 @@ export async function loginModelProvider(authPath, providerId, settingsPath) {
|
|
|
825
794
|
printInfo(event.message);
|
|
826
795
|
}
|
|
827
796
|
},
|
|
828
|
-
signal
|
|
829
|
-
}
|
|
797
|
+
signal,
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
export async function loginModelProvider(authPath, providerId, settingsPath) {
|
|
801
|
+
if (providerId) {
|
|
802
|
+
const resolvedProvider = await resolveModelProviderForCommand(authPath, providerId);
|
|
803
|
+
if (!resolvedProvider) {
|
|
804
|
+
throw new Error(`Unknown model provider: ${providerId}`);
|
|
805
|
+
}
|
|
806
|
+
if (resolvedProvider.kind === "api-key") {
|
|
807
|
+
const configured = await configureApiKeyProvider(authPath, resolvedProvider.id);
|
|
808
|
+
if (configured) {
|
|
809
|
+
await maybeSetRecommendedDefaultModel(settingsPath, authPath);
|
|
810
|
+
}
|
|
811
|
+
return configured;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
const provider = providerId ? await resolveOAuthProvider(authPath, providerId) : await selectOAuthProvider(authPath, "login");
|
|
815
|
+
if (!provider) {
|
|
816
|
+
if (providerId) {
|
|
817
|
+
throw new Error(`Unknown model provider: ${providerId}`);
|
|
818
|
+
}
|
|
819
|
+
printInfo("Login cancelled.");
|
|
820
|
+
return false;
|
|
821
|
+
}
|
|
822
|
+
const modelRuntime = await createModelRuntime(authPath);
|
|
823
|
+
const abortController = new AbortController();
|
|
824
|
+
const deviceId = await getOrCreateDeviceId(authPath);
|
|
825
|
+
await modelRuntime.login(provider.id, "oauth", terminalAuthInteraction(provider.name ?? provider.id, abortController.signal), { getDeviceId: () => deviceId }).catch((error) => {
|
|
830
826
|
throw describeOAuthLoginFailure(provider.id, error);
|
|
831
827
|
});
|
|
832
828
|
printSuccess(`Model provider login complete: ${provider.id}`);
|
|
@@ -888,11 +884,10 @@ export async function setDefaultModelSpec(settingsPath, authPath, spec) {
|
|
|
888
884
|
throw new Error(await describeUnavailableModelSpec(authPath, spec));
|
|
889
885
|
}
|
|
890
886
|
const [provider, ...rest] = resolvedSpec.split("/");
|
|
891
|
-
|
|
892
|
-
const settings =
|
|
893
|
-
settings.
|
|
894
|
-
settings.
|
|
895
|
-
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
887
|
+
// Pi's SettingsManager merges only the changed keys under its lock.
|
|
888
|
+
const settings = SettingsManager.create(process.cwd(), dirname(settingsPath));
|
|
889
|
+
settings.setDefaultModelAndProvider(provider, rest.join("/"));
|
|
890
|
+
await settings.flush();
|
|
896
891
|
printSuccess(`Research default model set to ${resolvedSpec}`);
|
|
897
892
|
}
|
|
898
893
|
export async function selectDefaultModel(settingsPath, authPath) {
|
package/dist/pi/runtime.js
CHANGED
|
@@ -2,7 +2,7 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "n
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { delimiter, dirname, resolve, win32 } from "node:path";
|
|
4
4
|
import { MERMAID_FALLBACK_PATHS, PANDOC_FALLBACK_PATHS, resolveBrowser, resolveExecutable, } from "../system/executables.js";
|
|
5
|
-
import { getPostHogChildEnv } from "../telemetry/posthog.js";
|
|
5
|
+
import { getPostHogChildEnv, isTelemetryDisabled } from "../telemetry/posthog.js";
|
|
6
6
|
// Pi packages shipped as Feynman dependencies and loaded from their install
|
|
7
7
|
// paths through settings.json `packages` (Pi's documented local-path source).
|
|
8
8
|
export const BUNDLED_PI_PACKAGES = ["pi-subagents", "pi-web-access", "pi-docparser", "pi-btw"];
|
|
@@ -156,8 +156,9 @@ export function buildPiEnv(options, executables) {
|
|
|
156
156
|
FEYNMAN_BIN_PATH: getFeynmanCliBinPath(options.appRoot),
|
|
157
157
|
PI_CODING_AGENT_DIR: options.feynmanAgentDir,
|
|
158
158
|
PANDOC_PATH: pandocPath,
|
|
159
|
-
PI_HARDWARE_CURSOR: process.env.PI_HARDWARE_CURSOR ?? "1",
|
|
160
159
|
PI_SKIP_VERSION_CHECK: process.env.PI_SKIP_VERSION_CHECK ?? "1",
|
|
160
|
+
// A Feynman telemetry opt-out also turns off Pi's install telemetry (docs/environment-variables.md).
|
|
161
|
+
...(isTelemetryDisabled() && process.env.PI_TELEMETRY === undefined ? { PI_TELEMETRY: "0" } : {}),
|
|
161
162
|
MERMAID_CLI_PATH: mermaidPath,
|
|
162
163
|
PUPPETEER_EXECUTABLE_PATH: browserPath,
|
|
163
164
|
...getPostHogChildEnv(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@companion-ai/feynman",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.42",
|
|
4
4
|
"description": "The open source AI research agent.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -79,21 +79,20 @@
|
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"@clack/prompts": "^1.8.1",
|
|
81
81
|
"@companion-ai/alpha-hub": "0.1.7",
|
|
82
|
-
"@earendil-works/
|
|
83
|
-
"@earendil-works/pi-
|
|
84
|
-
"@earendil-works/pi-
|
|
85
|
-
"@earendil-works/pi-telemetry": "1.1.0",
|
|
82
|
+
"@earendil-works/pi-codemode": "1.2.0",
|
|
83
|
+
"@earendil-works/pi-mcp": "1.2.0",
|
|
84
|
+
"@earendil-works/pi-telemetry": "1.2.0",
|
|
86
85
|
"fast-xml-parser": "5.11.1",
|
|
87
86
|
"pi-btw": "0.8.0",
|
|
88
87
|
"pi-docparser": "4.0.0",
|
|
89
|
-
"pi-subagents": "0.
|
|
88
|
+
"pi-subagents": "0.78.0",
|
|
90
89
|
"pi-web-access": "0.39.0",
|
|
91
90
|
"posthog-node": "^5.53.0"
|
|
92
91
|
},
|
|
93
92
|
"peerDependencies": {
|
|
94
|
-
"@earendil-works/pi-agent-core": "1.
|
|
95
|
-
"@earendil-works/pi-ai": "1.
|
|
96
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
93
|
+
"@earendil-works/pi-agent-core": "1.2.0",
|
|
94
|
+
"@earendil-works/pi-ai": "1.2.0",
|
|
95
|
+
"@earendil-works/pi-coding-agent": "1.2.0",
|
|
97
96
|
"@earendil-works/pi-tui": "*",
|
|
98
97
|
"typebox": "*"
|
|
99
98
|
},
|