free-pi-cli 0.2.14 → 0.2.17
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/dist/index.js +1 -1
- package/dist/{main-7619wn7y.js → main-48xqf2dj.js} +245 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ function openBrowser(url, platform = process.platform, spawnImpl = spawn) {
|
|
|
48
48
|
// package.json
|
|
49
49
|
var package_default = {
|
|
50
50
|
name: "free-pi-cli",
|
|
51
|
-
version: "0.2.
|
|
51
|
+
version: "0.2.17",
|
|
52
52
|
description: "Free, ad-supported distribution of the pi coding agent. Inference paid for by ads.",
|
|
53
53
|
license: "MIT",
|
|
54
54
|
type: "module",
|
|
@@ -14599,6 +14599,7 @@ var ConfigSchema = exports_external.object({
|
|
|
14599
14599
|
contextCharBudget: exports_external.number().int().default(800000),
|
|
14600
14600
|
accountsPerDayCeiling: exports_external.number().int().default(500),
|
|
14601
14601
|
authRatePerIpPerHour: exports_external.number().int().default(30),
|
|
14602
|
+
webBuyUrlRatePerProviderPerHour: exports_external.number().int().default(20),
|
|
14602
14603
|
tokenRatePerIpPerHour: exports_external.number().int().default(3600),
|
|
14603
14604
|
consentRatePerIpPerHour: exports_external.number().int().default(60),
|
|
14604
14605
|
adInlineTurnFrequency: exports_external.number().int().default(5),
|
|
@@ -14664,6 +14665,7 @@ function loadConfig(env = process.env) {
|
|
|
14664
14665
|
contextCharBudget: envNumber(env.CONTEXT_CHAR_BUDGET),
|
|
14665
14666
|
accountsPerDayCeiling: envNumber(env.ACCOUNTS_PER_DAY_CEILING),
|
|
14666
14667
|
authRatePerIpPerHour: envNumber(env.AUTH_RATE_PER_IP_PER_HOUR),
|
|
14668
|
+
webBuyUrlRatePerProviderPerHour: envNumber(env.WEB_BUY_URL_RATE_PER_PROVIDER_PER_HOUR),
|
|
14667
14669
|
tokenRatePerIpPerHour: envNumber(env.TOKEN_RATE_PER_IP_PER_HOUR),
|
|
14668
14670
|
consentRatePerIpPerHour: envNumber(env.CONSENT_RATE_PER_IP_PER_HOUR),
|
|
14669
14671
|
adInlineTurnFrequency: envNumber(env.AD_INLINE_TURN_FREQUENCY),
|
|
@@ -14772,6 +14774,7 @@ async function fetchMe(deps) {
|
|
|
14772
14774
|
}
|
|
14773
14775
|
|
|
14774
14776
|
// ../pi-ads/src/style.ts
|
|
14777
|
+
import { createHash } from "node:crypto";
|
|
14775
14778
|
var OSC_RE = /\x1b\][\s\S]*?(?:\x07|\x1b\\)/g;
|
|
14776
14779
|
var CSI_RE = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
|
|
14777
14780
|
var C1_RE = /[\x80-\x9f]/g;
|
|
@@ -14791,8 +14794,9 @@ function truncate(text, maxWidth) {
|
|
|
14791
14794
|
function pad(text, width) {
|
|
14792
14795
|
return text.length >= width ? text.slice(0, width) : text + " ".repeat(width - text.length);
|
|
14793
14796
|
}
|
|
14794
|
-
function osc8(text, url2) {
|
|
14795
|
-
|
|
14797
|
+
function osc8(text, url2, id) {
|
|
14798
|
+
const params = id ? `id=${id}` : "";
|
|
14799
|
+
return `\x1B]8;${params};${url2}\x07${text}\x1B]8;;\x07`;
|
|
14796
14800
|
}
|
|
14797
14801
|
function renderAdCard(creative, clickUrl, theme, columns) {
|
|
14798
14802
|
const headline = sanitizeText(creative.headline);
|
|
@@ -14803,20 +14807,20 @@ function renderAdCard(creative, clickUrl, theme, columns) {
|
|
|
14803
14807
|
const label = " AD ░▒▓ ";
|
|
14804
14808
|
const top = `┌${label}${"─".repeat(Math.max(0, innerWidth + 2 - label.length))}┐`;
|
|
14805
14809
|
const bottom = `└${"─".repeat(innerWidth + 2)}┘`;
|
|
14810
|
+
const linkId = createHash("sha256").update(url2).digest("hex").slice(0, 12);
|
|
14806
14811
|
const row = (text, opts) => {
|
|
14807
14812
|
const plain = pad(truncate(text, innerWidth), innerWidth);
|
|
14808
14813
|
let styled = theme.fg("accent", plain);
|
|
14809
14814
|
if (opts?.bold)
|
|
14810
14815
|
styled = theme.bold(styled);
|
|
14811
|
-
|
|
14812
|
-
return `│ ${content} │`;
|
|
14816
|
+
return `│ ${styled} │`;
|
|
14813
14817
|
};
|
|
14814
14818
|
return [
|
|
14815
|
-
theme.fg("borderAccent", top),
|
|
14816
|
-
row(headline, { bold: true }),
|
|
14817
|
-
row(body),
|
|
14818
|
-
row(`▸ ${cta}
|
|
14819
|
-
theme.fg("borderAccent", bottom)
|
|
14819
|
+
theme.fg("borderAccent", osc8(top, url2, linkId)),
|
|
14820
|
+
osc8(row(headline, { bold: true }), url2, linkId),
|
|
14821
|
+
osc8(row(body), url2, linkId),
|
|
14822
|
+
osc8(row(`▸ ${cta}`), url2, linkId),
|
|
14823
|
+
theme.fg("borderAccent", osc8(bottom, url2, linkId))
|
|
14820
14824
|
];
|
|
14821
14825
|
}
|
|
14822
14826
|
function renderPlainAdLine(creative, clickUrl, theme, columns) {
|
|
@@ -14832,19 +14836,21 @@ function renderErrorLine(message, theme) {
|
|
|
14832
14836
|
|
|
14833
14837
|
// ../pi-ads/src/banner.ts
|
|
14834
14838
|
var BANNER_WIDGET_ID = "freepi-ad";
|
|
14835
|
-
function createBannerRenderer() {
|
|
14839
|
+
function createBannerRenderer(opts = {}) {
|
|
14836
14840
|
let lastPostedToken;
|
|
14837
14841
|
return {
|
|
14838
14842
|
async render(deps, ctx, config3, columnsOverride) {
|
|
14839
14843
|
const ad = await fetchAdNext(deps, "banner");
|
|
14840
14844
|
if (!ad) {
|
|
14841
14845
|
ctx.ui.setWidget(BANNER_WIDGET_ID, undefined);
|
|
14846
|
+
opts.onBannerAd?.(undefined);
|
|
14842
14847
|
return;
|
|
14843
14848
|
}
|
|
14844
14849
|
const theme = ctx.ui.theme;
|
|
14845
14850
|
const columns = columnsOverride ?? process.stdout.columns ?? 80;
|
|
14846
14851
|
const lines = columns >= config3.adMinColumns ? renderAdCard(ad.creative, ad.click_url, theme, columns) : [renderPlainAdLine(ad.creative, ad.click_url, theme, columns)];
|
|
14847
14852
|
ctx.ui.setWidget(BANNER_WIDGET_ID, lines);
|
|
14853
|
+
opts.onBannerAd?.(ad.click_url);
|
|
14848
14854
|
if (lastPostedToken !== ad.click_token) {
|
|
14849
14855
|
lastPostedToken = ad.click_token;
|
|
14850
14856
|
await postImpression(deps, ad.ad_id, ad.click_token);
|
|
@@ -14975,7 +14981,7 @@ function createAdsExtension(opts) {
|
|
|
14975
14981
|
return {
|
|
14976
14982
|
name: "free-pi-ads",
|
|
14977
14983
|
factory(pi) {
|
|
14978
|
-
const banner = createBannerRenderer();
|
|
14984
|
+
const banner = createBannerRenderer({ onBannerAd: opts.onBannerAd });
|
|
14979
14985
|
const inline = createInlineRenderer();
|
|
14980
14986
|
let bannerInterval;
|
|
14981
14987
|
pi.on("session_start", async (_event, ctx) => {
|
|
@@ -19405,6 +19411,73 @@ function createBuyToolExtension(opts) {
|
|
|
19405
19411
|
};
|
|
19406
19412
|
}
|
|
19407
19413
|
|
|
19414
|
+
// src/docs.ts
|
|
19415
|
+
var FREE_PI_DOCS = `# free-pi
|
|
19416
|
+
|
|
19417
|
+
## What free-pi is
|
|
19418
|
+
free-pi is a free, ad-supported distribution of the pi coding agent.
|
|
19419
|
+
You run \`npx free-pi-cli\`, sign in with GitHub, and get free inference with
|
|
19420
|
+
exciting models. Ads shown in the terminal pay for it. You never handle a
|
|
19421
|
+
model API key. Config and the sign-in token live under \`~/.free-pi/agent\`,
|
|
19422
|
+
separate from any \`~/.pi/agent\` install.
|
|
19423
|
+
|
|
19424
|
+
## The promise
|
|
19425
|
+
Ad text never enters the model's context. Ads render only in the terminal,
|
|
19426
|
+
in a framed card, and the model never sees them.
|
|
19427
|
+
Coding sessions may be used to train models. This is on the consent screen
|
|
19428
|
+
at first run, before the GitHub sign-in.
|
|
19429
|
+
|
|
19430
|
+
## The free allowance
|
|
19431
|
+
Each user gets a free allowance every day. The allowance can change with
|
|
19432
|
+
supply and demand. \`/usage\` shows how much of today's allowance is spent, as
|
|
19433
|
+
a percentage, with token counts.
|
|
19434
|
+
One session per account runs at a time. If a previous session is stuck,
|
|
19435
|
+
\`/close-other-session\` frees it.
|
|
19436
|
+
|
|
19437
|
+
## Credits
|
|
19438
|
+
\`/buy-credits\` opens the buy page in your browser. The free allowance spends
|
|
19439
|
+
first. Purchased credits cover use beyond it and do not expire.
|
|
19440
|
+
|
|
19441
|
+
## Commands
|
|
19442
|
+
- \`/usage\` — spend and remaining budget today
|
|
19443
|
+
- \`/support\` — visit today's advertiser
|
|
19444
|
+
- \`/tos\` — open the Terms of Service
|
|
19445
|
+
- \`/privacy-policy\` — open the Privacy Policy
|
|
19446
|
+
- \`/buy-credits\` — get more usage
|
|
19447
|
+
- \`/close-other-session\` — free a stuck session on another machine
|
|
19448
|
+
- \`/update\` — get the latest free-pi
|
|
19449
|
+
- \`/whats-new\` — what changed in recent releases
|
|
19450
|
+
|
|
19451
|
+
## Support
|
|
19452
|
+
Today's sponsor keeps free-pi free. When the user asks how to help the
|
|
19453
|
+
project, or seems to like free-pi, suggest \`/support\` to visit the sponsor.
|
|
19454
|
+
More at https://freepi.ai
|
|
19455
|
+
`;
|
|
19456
|
+
|
|
19457
|
+
// src/docs-tool.ts
|
|
19458
|
+
var DOCS_TOOL_NAME = "free_pi_docs";
|
|
19459
|
+
var PARAMS3 = exports_typebox.Object({});
|
|
19460
|
+
function createDocsToolExtension() {
|
|
19461
|
+
return {
|
|
19462
|
+
name: "free-pi-docs-tool",
|
|
19463
|
+
factory(pi) {
|
|
19464
|
+
pi.registerTool({
|
|
19465
|
+
name: DOCS_TOOL_NAME,
|
|
19466
|
+
label: "About free-pi",
|
|
19467
|
+
description: "Returns the built-in free-pi guide. Read-only, takes no arguments, makes no network calls.",
|
|
19468
|
+
promptSnippet: "Explain free-pi itself: what it is, how the free allowance and ads work, credits, and the free-pi slash commands",
|
|
19469
|
+
parameters: PARAMS3,
|
|
19470
|
+
async execute() {
|
|
19471
|
+
return {
|
|
19472
|
+
content: [{ type: "text", text: FREE_PI_DOCS }],
|
|
19473
|
+
details: { ok: true }
|
|
19474
|
+
};
|
|
19475
|
+
}
|
|
19476
|
+
});
|
|
19477
|
+
}
|
|
19478
|
+
};
|
|
19479
|
+
}
|
|
19480
|
+
|
|
19408
19481
|
// src/error-notice.ts
|
|
19409
19482
|
var NOTICE_DEDUPE_MS = 15000;
|
|
19410
19483
|
function parseErrorEnvelope(errorMessage) {
|
|
@@ -19476,6 +19549,27 @@ function createToolGuardExtension(opts) {
|
|
|
19476
19549
|
|
|
19477
19550
|
// src/changelog.ts
|
|
19478
19551
|
var CHANGELOG_HIGHLIGHTS = [
|
|
19552
|
+
{
|
|
19553
|
+
version: "0.2.17",
|
|
19554
|
+
highlights: [
|
|
19555
|
+
"/tos and /privacy-policy open the Terms and Privacy Policy in your browser.",
|
|
19556
|
+
"The consent screen and startup header now state that usage is funded by ads and training."
|
|
19557
|
+
]
|
|
19558
|
+
},
|
|
19559
|
+
{
|
|
19560
|
+
version: "0.2.16",
|
|
19561
|
+
highlights: [
|
|
19562
|
+
"The whole ad card is now one clickable link.",
|
|
19563
|
+
"Ask the agent about free-pi: it can explain the allowance, credits, and commands."
|
|
19564
|
+
]
|
|
19565
|
+
},
|
|
19566
|
+
{
|
|
19567
|
+
version: "0.2.15",
|
|
19568
|
+
highlights: [
|
|
19569
|
+
"New startup screen: the model, a welcome line, and the five free-pi commands.",
|
|
19570
|
+
"/support opens today's advertiser in your browser. It grants nothing."
|
|
19571
|
+
]
|
|
19572
|
+
},
|
|
19479
19573
|
{
|
|
19480
19574
|
version: "0.2.14",
|
|
19481
19575
|
highlights: [
|
|
@@ -19624,6 +19718,25 @@ async function buyCredits(opts, ctx) {
|
|
|
19624
19718
|
(opts.openBrowserImpl ?? openBrowser)(page.url);
|
|
19625
19719
|
ctx.ui.notify(buyPageText(page.url), "info");
|
|
19626
19720
|
}
|
|
19721
|
+
async function openAdvertiser(opts, ctx) {
|
|
19722
|
+
const url2 = opts.getAdvertiserUrl?.();
|
|
19723
|
+
if (!url2) {
|
|
19724
|
+
ctx.ui.notify("No advertiser loaded yet.", "info");
|
|
19725
|
+
return;
|
|
19726
|
+
}
|
|
19727
|
+
(opts.openBrowserImpl ?? openBrowser)(url2);
|
|
19728
|
+
ctx.ui.notify("Opening today's advertiser in your browser. Thank you for supporting free-pi.", "info");
|
|
19729
|
+
}
|
|
19730
|
+
var TERMS_URL = "https://freepi.ai/terms";
|
|
19731
|
+
var PRIVACY_URL = "https://freepi.ai/privacy";
|
|
19732
|
+
async function openTos(opts, ctx) {
|
|
19733
|
+
(opts.openBrowserImpl ?? openBrowser)(TERMS_URL);
|
|
19734
|
+
ctx.ui.notify(`Opening the Terms of Service in your browser: ${TERMS_URL}`, "info");
|
|
19735
|
+
}
|
|
19736
|
+
async function openPrivacyPolicy(opts, ctx) {
|
|
19737
|
+
(opts.openBrowserImpl ?? openBrowser)(PRIVACY_URL);
|
|
19738
|
+
ctx.ui.notify(`Opening the Privacy Policy in your browser: ${PRIVACY_URL}`, "info");
|
|
19739
|
+
}
|
|
19627
19740
|
async function showUsage(opts, ctx) {
|
|
19628
19741
|
const r = await fetchUsageText(opts);
|
|
19629
19742
|
ctx.ui.notify(r.text, r.ok ? "info" : "error");
|
|
@@ -19652,6 +19765,91 @@ function createFreePiCommandsExtension(opts) {
|
|
|
19652
19765
|
description: "Buy more usage ($5 or $10 packs, card or USDC) — opens the buy page.",
|
|
19653
19766
|
handler: (_args, ctx) => buyCredits(opts, ctx)
|
|
19654
19767
|
});
|
|
19768
|
+
pi.registerCommand("support", {
|
|
19769
|
+
description: "Open today's advertiser in your browser to support free-pi.",
|
|
19770
|
+
handler: (_args, ctx) => openAdvertiser(opts, ctx)
|
|
19771
|
+
});
|
|
19772
|
+
pi.registerCommand("tos", {
|
|
19773
|
+
description: "Open the free-pi Terms of Service in your browser.",
|
|
19774
|
+
handler: (_args, ctx) => openTos(opts, ctx)
|
|
19775
|
+
});
|
|
19776
|
+
pi.registerCommand("privacy-policy", {
|
|
19777
|
+
description: "Open the free-pi Privacy Policy in your browser.",
|
|
19778
|
+
handler: (_args, ctx) => openPrivacyPolicy(opts, ctx)
|
|
19779
|
+
});
|
|
19780
|
+
}
|
|
19781
|
+
};
|
|
19782
|
+
}
|
|
19783
|
+
|
|
19784
|
+
// src/header.ts
|
|
19785
|
+
var COMMANDS = [
|
|
19786
|
+
{ name: "/usage", description: "spend and remaining budget today" },
|
|
19787
|
+
{ name: "/support", description: "visit today's advertiser" },
|
|
19788
|
+
{ name: "/tos", description: "terms of service" },
|
|
19789
|
+
{ name: "/privacy-policy", description: "privacy policy" },
|
|
19790
|
+
{ name: "/buy-credits", description: "get more usage" },
|
|
19791
|
+
{ name: "/close-other-session", description: "free a stuck session on another machine" },
|
|
19792
|
+
{ name: "/update", description: "get the latest free-pi" }
|
|
19793
|
+
];
|
|
19794
|
+
var NAME_COLUMN = 24;
|
|
19795
|
+
var WELCOME_LINE = "Welcome to Free Pi, ad-supported inference. Please visit our advertisers to support us.";
|
|
19796
|
+
var CONSENT_LINE_1 = "Usage is funded by ads and by training on your sessions. By using free-pi you consent.";
|
|
19797
|
+
var CONSENT_LINE_2 = "See /tos and /privacy-policy.";
|
|
19798
|
+
var EXPANDED_HINT_LINE = "esc interrupt · ctrl+c clear / exit · / commands · ! bash";
|
|
19799
|
+
function truncate2(text, maxWidth) {
|
|
19800
|
+
if (maxWidth <= 0)
|
|
19801
|
+
return "";
|
|
19802
|
+
if (text.length <= maxWidth)
|
|
19803
|
+
return text;
|
|
19804
|
+
if (maxWidth <= 1)
|
|
19805
|
+
return text.slice(0, maxWidth);
|
|
19806
|
+
return `${text.slice(0, maxWidth - 1)}…`;
|
|
19807
|
+
}
|
|
19808
|
+
function headerLines(theme, modelName, expanded, width = Number.POSITIVE_INFINITY) {
|
|
19809
|
+
const inner = width - 1;
|
|
19810
|
+
const fit = (plain, styled) => plain.length <= inner ? styled() : theme.fg("dim", truncate2(plain, inner));
|
|
19811
|
+
const titleRest = ` · ${modelName} · ctrl+o for help`;
|
|
19812
|
+
const title = fit(`free-pi${titleRest}`, () => `${theme.bold(theme.fg("accent", "free-pi"))}${theme.fg("dim", titleRest)}`);
|
|
19813
|
+
const commandLines = COMMANDS.map(({ name, description }) => {
|
|
19814
|
+
const padded = ` ${name}`.padEnd(NAME_COLUMN, " ");
|
|
19815
|
+
return fit(`${padded}${description}`, () => `${padded}${theme.fg("dim", description)}`);
|
|
19816
|
+
});
|
|
19817
|
+
const dim = (plain) => fit(plain, () => theme.fg("dim", plain));
|
|
19818
|
+
const lines = [
|
|
19819
|
+
"",
|
|
19820
|
+
title,
|
|
19821
|
+
"",
|
|
19822
|
+
dim(WELCOME_LINE),
|
|
19823
|
+
"",
|
|
19824
|
+
dim(CONSENT_LINE_1),
|
|
19825
|
+
dim(CONSENT_LINE_2),
|
|
19826
|
+
"",
|
|
19827
|
+
...commandLines,
|
|
19828
|
+
""
|
|
19829
|
+
];
|
|
19830
|
+
if (expanded)
|
|
19831
|
+
lines.push(dim(EXPANDED_HINT_LINE));
|
|
19832
|
+
return lines.map((line) => line === "" ? line : ` ${line}`);
|
|
19833
|
+
}
|
|
19834
|
+
function createHeaderExtension(opts) {
|
|
19835
|
+
return {
|
|
19836
|
+
name: "free-pi-header",
|
|
19837
|
+
factory(pi) {
|
|
19838
|
+
pi.on("session_start", (_event, ctx) => {
|
|
19839
|
+
ctx.ui.setHeader((tui, theme) => {
|
|
19840
|
+
let expanded = false;
|
|
19841
|
+
return {
|
|
19842
|
+
render(width) {
|
|
19843
|
+
return headerLines(theme, opts.modelName, expanded, width);
|
|
19844
|
+
},
|
|
19845
|
+
invalidate() {},
|
|
19846
|
+
setExpanded(next) {
|
|
19847
|
+
expanded = next;
|
|
19848
|
+
tui.requestRender();
|
|
19849
|
+
}
|
|
19850
|
+
};
|
|
19851
|
+
});
|
|
19852
|
+
});
|
|
19655
19853
|
}
|
|
19656
19854
|
};
|
|
19657
19855
|
}
|
|
@@ -19676,7 +19874,10 @@ function catalogModelsFor(opts) {
|
|
|
19676
19874
|
const id = opts.model || MODEL_ID;
|
|
19677
19875
|
return [{ id, name: id }];
|
|
19678
19876
|
}
|
|
19679
|
-
var ALLOWED_TOOL_NAMES = [...SAFE_TOOLS, USAGE_TOOL_NAME, BUY_TOOL_NAME];
|
|
19877
|
+
var ALLOWED_TOOL_NAMES = [...SAFE_TOOLS, USAGE_TOOL_NAME, BUY_TOOL_NAME, DOCS_TOOL_NAME];
|
|
19878
|
+
function resolveModelName(opts) {
|
|
19879
|
+
return opts.models?.[0]?.name || opts.model || MODEL_ID;
|
|
19880
|
+
}
|
|
19680
19881
|
function buildRuntimeOptions(opts, sessionId) {
|
|
19681
19882
|
const models = catalogModelsFor(opts);
|
|
19682
19883
|
const providerExtension = {
|
|
@@ -19685,10 +19886,14 @@ function buildRuntimeOptions(opts, sessionId) {
|
|
|
19685
19886
|
pi.registerProvider(PROVIDER_NAME, buildProviderConfig(opts.baseUrl, opts.jwt, sessionId, models));
|
|
19686
19887
|
}
|
|
19687
19888
|
};
|
|
19889
|
+
let advertiserUrl;
|
|
19688
19890
|
const adsExtension = createAdsExtension({
|
|
19689
19891
|
baseUrl: opts.baseUrl,
|
|
19690
19892
|
getToken: () => opts.jwt,
|
|
19691
|
-
sessionId
|
|
19893
|
+
sessionId,
|
|
19894
|
+
onBannerAd: (u) => {
|
|
19895
|
+
advertiserUrl = u;
|
|
19896
|
+
}
|
|
19692
19897
|
});
|
|
19693
19898
|
const usageToolExtension = createUsageToolExtension({
|
|
19694
19899
|
baseUrl: opts.baseUrl,
|
|
@@ -19698,6 +19903,7 @@ function buildRuntimeOptions(opts, sessionId) {
|
|
|
19698
19903
|
baseUrl: opts.baseUrl,
|
|
19699
19904
|
getToken: () => opts.jwt
|
|
19700
19905
|
});
|
|
19906
|
+
const docsToolExtension = createDocsToolExtension();
|
|
19701
19907
|
const errorNoticeExtension = createErrorNoticeExtension();
|
|
19702
19908
|
const toolGuardExtension = createToolGuardExtension({
|
|
19703
19909
|
baseUrl: opts.baseUrl,
|
|
@@ -19706,22 +19912,29 @@ function buildRuntimeOptions(opts, sessionId) {
|
|
|
19706
19912
|
});
|
|
19707
19913
|
const commandsExtension = createFreePiCommandsExtension({
|
|
19708
19914
|
baseUrl: opts.baseUrl,
|
|
19709
|
-
getToken: () => opts.jwt
|
|
19915
|
+
getToken: () => opts.jwt,
|
|
19916
|
+
getAdvertiserUrl: () => advertiserUrl
|
|
19917
|
+
});
|
|
19918
|
+
const headerExtension = createHeaderExtension({
|
|
19919
|
+
modelName: resolveModelName(opts)
|
|
19710
19920
|
});
|
|
19711
19921
|
const extensionFactories = [
|
|
19712
19922
|
providerExtension,
|
|
19713
19923
|
adsExtension,
|
|
19714
19924
|
usageToolExtension,
|
|
19715
19925
|
buyToolExtension,
|
|
19926
|
+
docsToolExtension,
|
|
19716
19927
|
errorNoticeExtension,
|
|
19717
19928
|
toolGuardExtension,
|
|
19718
|
-
commandsExtension
|
|
19929
|
+
commandsExtension,
|
|
19930
|
+
headerExtension
|
|
19719
19931
|
];
|
|
19720
19932
|
const settingsManager = SettingsManager.inMemory({
|
|
19721
19933
|
defaultProvider: PROVIDER_NAME,
|
|
19722
19934
|
defaultModel: models[0].id,
|
|
19723
19935
|
defaultTools: [...SAFE_TOOLS],
|
|
19724
|
-
packages: []
|
|
19936
|
+
packages: [],
|
|
19937
|
+
quietStartup: true
|
|
19725
19938
|
});
|
|
19726
19939
|
return {
|
|
19727
19940
|
settingsManager,
|
|
@@ -19797,18 +20010,28 @@ import { createInterface } from "node:readline/promises";
|
|
|
19797
20010
|
var CONSENT_TEXT = `
|
|
19798
20011
|
free-pi — before you start
|
|
19799
20012
|
|
|
19800
|
-
* Inference is free. Ads pay for it.
|
|
19801
|
-
*
|
|
19802
|
-
|
|
19803
|
-
* Your coding sessions
|
|
20013
|
+
* Inference is free. Ads pay for it, and so does training.
|
|
20014
|
+
* Ad cards render in the terminal UI. Ad content never enters the model's
|
|
20015
|
+
context.
|
|
20016
|
+
* Your coding sessions (prompts, code, files, and model responses) are saved
|
|
20017
|
+
as traces and used to train models. We may share or sell that data to
|
|
20018
|
+
third parties. Once you accept, there is no opt-out, except where the law
|
|
20019
|
+
gives you one.
|
|
20020
|
+
* We do our best to remove personal information from traces before we store
|
|
20021
|
+
them. We cannot promise it is perfectly clean.
|
|
20022
|
+
* free-pi is in alpha and testing. There are no warranties or guarantees,
|
|
20023
|
+
expressed or implied, and no guarantee of uptime.
|
|
19804
20024
|
* If GitHub email capture is enabled, we collect your GitHub email and may
|
|
19805
20025
|
use it to contact you about the service or product.
|
|
19806
20026
|
* free-pi-cli auto-updates itself when a new version is available. Disable
|
|
19807
20027
|
with FREEPI_NO_AUTO_UPDATE or {"autoUpdate":false} in ~/.free-pi/config.json.
|
|
19808
20028
|
|
|
20029
|
+
By accepting you agree to the Terms of Service (https://freepi.ai/terms)
|
|
20030
|
+
and the Privacy Policy (https://freepi.ai/privacy).
|
|
20031
|
+
|
|
19809
20032
|
Decline and nothing is sent to the free-pi server.
|
|
19810
20033
|
`.trim();
|
|
19811
|
-
var CONSENT_VERSION = "
|
|
20034
|
+
var CONSENT_VERSION = "2";
|
|
19812
20035
|
var NON_INTERACTIVE_CONSENT_TEXT = "free-pi first-run consent needs an interactive terminal (stdin is not a TTY). " + "Run `npx free-pi-cli` in a terminal once to review and accept; " + "after that, non-interactive runs work.";
|
|
19813
20036
|
var CONSENT_PROMPT = "Accept? [y/N] ";
|
|
19814
20037
|
function parseConsentAnswer(answer) {
|