free-pi-cli 0.2.6 → 0.2.8

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 CHANGED
@@ -30,4 +30,4 @@ if (err) {
30
30
  console.error(err);
31
31
  process.exit(1);
32
32
  }
33
- await import("./main-swfaagjj.js");
33
+ await import("./main-wd2zxa5n.js");
@@ -14453,7 +14453,8 @@ var ClientVersionResponseSchema = exports_external.object({
14453
14453
  min: exports_external.string(),
14454
14454
  latest: exports_external.string(),
14455
14455
  model: exports_external.string().optional(),
14456
- notice: exports_external.string().optional()
14456
+ notice: exports_external.string().optional(),
14457
+ models: exports_external.array(exports_external.object({ id: exports_external.string(), name: exports_external.string() })).optional()
14457
14458
  });
14458
14459
  var SessionResetResponseSchema = exports_external.object({
14459
14460
  released: exports_external.boolean()
@@ -14504,7 +14505,8 @@ var ConfigSchema = exports_external.object({
14504
14505
  abuseFlipAlertThreshold: exports_external.number().int().default(10),
14505
14506
  abuseAdBypassMinRequests: exports_external.number().int().default(20),
14506
14507
  abuseAdBypassRatio: exports_external.number().int().default(10),
14507
- traceMaxInflightWrites: exports_external.number().int().default(32)
14508
+ traceMaxInflightWrites: exports_external.number().int().default(32),
14509
+ catalogCacheTtlSeconds: exports_external.number().int().default(60)
14508
14510
  });
14509
14511
  function envNumber(value) {
14510
14512
  if (value === undefined || value === "")
@@ -14565,7 +14567,8 @@ function loadConfig(env = process.env) {
14565
14567
  abuseFlipAlertThreshold: envNumber(env.ABUSE_FLIP_ALERT_THRESHOLD),
14566
14568
  abuseAdBypassMinRequests: envNumber(env.ABUSE_AD_BYPASS_MIN_REQUESTS),
14567
14569
  abuseAdBypassRatio: envNumber(env.ABUSE_AD_BYPASS_RATIO),
14568
- traceMaxInflightWrites: envNumber(env.TRACE_MAX_INFLIGHT_WRITES)
14570
+ traceMaxInflightWrites: envNumber(env.TRACE_MAX_INFLIGHT_WRITES),
14571
+ catalogCacheTtlSeconds: envNumber(env.CATALOG_CACHE_TTL_SECONDS)
14569
14572
  });
14570
14573
  }
14571
14574
  // ../shared/src/version.ts
@@ -14843,7 +14846,7 @@ import { join as join2, resolve } from "node:path";
14843
14846
  // package.json
14844
14847
  var package_default = {
14845
14848
  name: "free-pi-cli",
14846
- version: "0.2.6",
14849
+ version: "0.2.8",
14847
14850
  description: "Free, ad-supported distribution of the pi coding agent. Inference paid for by ads.",
14848
14851
  license: "MIT",
14849
14852
  type: "module",
@@ -14882,24 +14885,22 @@ function completionsBaseUrl(baseUrl) {
14882
14885
  const trimmed = baseUrl.replace(/\/+$/, "");
14883
14886
  return trimmed.endsWith("/v1") ? trimmed : `${trimmed}/v1`;
14884
14887
  }
14885
- function buildProviderConfig(baseUrl, jwt2, sessionId, modelId = MODEL_ID) {
14888
+ function buildProviderConfig(baseUrl, jwt2, sessionId, models) {
14886
14889
  return {
14887
14890
  name: "free-pi",
14888
14891
  baseUrl: completionsBaseUrl(baseUrl),
14889
14892
  apiKey: jwt2,
14890
14893
  api: "openai-completions",
14891
14894
  headers: { "x-session-id": sessionId, "x-client-version": CLI_VERSION },
14892
- models: [
14893
- {
14894
- id: modelId,
14895
- name: modelId === MODEL_ID ? "DeepSeek V4 Flash (free-pi)" : modelId,
14896
- reasoning: false,
14897
- input: ["text"],
14898
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
14899
- contextWindow: 1048576,
14900
- maxTokens: 8192
14901
- }
14902
- ]
14895
+ models: models.map((m) => ({
14896
+ id: m.id,
14897
+ name: m.name,
14898
+ reasoning: false,
14899
+ input: ["text"],
14900
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
14901
+ contextWindow: 1048576,
14902
+ maxTokens: 8192
14903
+ }))
14903
14904
  };
14904
14905
  }
14905
14906
 
@@ -19244,6 +19245,18 @@ function createToolGuardExtension(opts) {
19244
19245
 
19245
19246
  // src/changelog.ts
19246
19247
  var CHANGELOG_HIGHLIGHTS = [
19248
+ {
19249
+ version: "0.2.8",
19250
+ highlights: [
19251
+ "You can now pick between models — run /model to see the list and switch (when the server offers more than one)."
19252
+ ]
19253
+ },
19254
+ {
19255
+ version: "0.2.7",
19256
+ highlights: [
19257
+ "The model list now reliably shows just the free-pi model — including HuggingFace, AWS, and Vertex — while leaving every credential in your shell untouched."
19258
+ ]
19259
+ },
19247
19260
  {
19248
19261
  version: "0.2.6",
19249
19262
  highlights: [
@@ -19346,29 +19359,33 @@ function createFreePiCommandsExtension(opts) {
19346
19359
  };
19347
19360
  }
19348
19361
 
19349
- // src/provider-scrub.ts
19350
- var EXTRA_PROVIDER_KEYS = ["GOOGLE_APPLICATION_CREDENTIALS"];
19351
- function scrubAmbientProviderKeys(env = process.env) {
19362
+ // src/provider-lock.ts
19363
+ function resolveFreePiScope(modelRuntime, providerName, modelIds, env = process.env) {
19352
19364
  if (env.FREEPI_KEEP_ENV_PROVIDERS)
19353
19365
  return [];
19354
- const removed = [];
19355
- for (const key of Object.keys(env)) {
19356
- if (key.endsWith("_API_KEY") || EXTRA_PROVIDER_KEYS.includes(key)) {
19357
- delete env[key];
19358
- removed.push(key);
19359
- }
19366
+ const scoped = [];
19367
+ for (const id of modelIds) {
19368
+ const model = modelRuntime.getModel(providerName, id);
19369
+ if (model)
19370
+ scoped.push({ model });
19360
19371
  }
19361
- return removed;
19372
+ return scoped;
19362
19373
  }
19363
19374
 
19364
19375
  // src/pi-launch.ts
19376
+ function catalogModelsFor(opts) {
19377
+ if (opts.models && opts.models.length > 0)
19378
+ return opts.models;
19379
+ const id = opts.model || MODEL_ID;
19380
+ return [{ id, name: id }];
19381
+ }
19365
19382
  var ALLOWED_TOOL_NAMES = [...SAFE_TOOLS, USAGE_TOOL_NAME];
19366
19383
  function buildRuntimeOptions(opts, sessionId) {
19367
- const modelId = opts.model || MODEL_ID;
19384
+ const models = catalogModelsFor(opts);
19368
19385
  const providerExtension = {
19369
19386
  name: "free-pi-provider",
19370
19387
  factory: (pi) => {
19371
- pi.registerProvider(PROVIDER_NAME, buildProviderConfig(opts.baseUrl, opts.jwt, sessionId, modelId));
19388
+ pi.registerProvider(PROVIDER_NAME, buildProviderConfig(opts.baseUrl, opts.jwt, sessionId, models));
19372
19389
  }
19373
19390
  };
19374
19391
  const adsExtension = createAdsExtension({
@@ -19398,7 +19415,7 @@ function buildRuntimeOptions(opts, sessionId) {
19398
19415
  ];
19399
19416
  const settingsManager = SettingsManager.inMemory({
19400
19417
  defaultProvider: PROVIDER_NAME,
19401
- defaultModel: modelId,
19418
+ defaultModel: models[0].id,
19402
19419
  defaultTools: [...SAFE_TOOLS],
19403
19420
  packages: []
19404
19421
  });
@@ -19426,11 +19443,11 @@ async function createSessionManager(cwd, sessionDir, sessionId, api3 = SessionMa
19426
19443
  return api3.create(cwd, sessionDir);
19427
19444
  }
19428
19445
  async function launchPi(opts) {
19429
- scrubAmbientProviderKeys();
19430
19446
  const cwd = process.cwd();
19431
19447
  const sessionDir = getSessionDir(cwd, opts.agentDir);
19432
19448
  const sm = await createSessionManager(cwd, sessionDir, opts.session);
19433
19449
  const sessionId = sm.getSessionId();
19450
+ const scopeIds = catalogModelsFor(opts).map((m) => m.id);
19434
19451
  const { settingsManager, resourceLoaderOptions, tools } = buildRuntimeOptions(opts, sessionId);
19435
19452
  const createRuntime = async ({
19436
19453
  cwd: rtCwd,
@@ -19443,12 +19460,14 @@ async function launchPi(opts) {
19443
19460
  settingsManager,
19444
19461
  resourceLoaderOptions
19445
19462
  });
19463
+ const scopedModels = resolveFreePiScope(services.modelRuntime, PROVIDER_NAME, scopeIds);
19446
19464
  return {
19447
19465
  ...await createAgentSessionFromServices({
19448
19466
  services,
19449
19467
  sessionManager,
19450
19468
  sessionStartEvent,
19451
- tools: [...tools]
19469
+ tools: [...tools],
19470
+ scopedModels
19452
19471
  }),
19453
19472
  services,
19454
19473
  diagnostics: services.diagnostics
@@ -19739,7 +19758,8 @@ async function run(deps, argv = process.argv) {
19739
19758
  jwt: jwt2,
19740
19759
  agentDir: deps.agentDir,
19741
19760
  session: sessionArg.session,
19742
- model: versionCheck.model
19761
+ model: versionCheck.model,
19762
+ models: versionCheck.models
19743
19763
  });
19744
19764
  deps.log(finalSessionId ? `
19745
19765
  free-pi session ended. Start it again anytime: npx free-pi-cli --session ${finalSessionId}` : `
@@ -19794,10 +19814,12 @@ async function checkClientVersion(baseUrl, cliVersion, fetchImpl = fetch) {
19794
19814
  const parsed = ClientVersionResponseSchema.safeParse(await res.json());
19795
19815
  if (!parsed.success)
19796
19816
  return { action: "ok" };
19797
- const { min, latest, model, notice } = parsed.data;
19817
+ const { min, latest, model, models, notice } = parsed.data;
19798
19818
  const extra = {};
19799
19819
  if (model !== undefined)
19800
19820
  extra.model = model;
19821
+ if (models !== undefined)
19822
+ extra.models = models;
19801
19823
  if (notice !== undefined)
19802
19824
  extra.notice = notice;
19803
19825
  if (compareVersions(cliVersion, min) === -1)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "free-pi-cli",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "Free, ad-supported distribution of the pi coding agent. Inference paid for by ads.",
5
5
  "license": "MIT",
6
6
  "type": "module",