@mrciphersmith/keryx 0.2.23 → 0.2.25

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.
Files changed (2) hide show
  1. package/dist/cli.js +81 -13
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -8068,7 +8068,7 @@ function providerByName(name) {
8068
8068
  async function fetchOpenAiCompatModelsDetailed(fetchFn, provider, apiKey, opts) {
8069
8069
  const url = `${provider.baseUrl.replace(/\/+$/, "")}${provider.modelsPath ?? DEFAULT_MODELS_PATH}`;
8070
8070
  const timeoutMs = opts?.timeoutMs ?? MODELS_FETCH_TIMEOUT_MS;
8071
- const fallback = { models: [...provider.models], source: "fallback" };
8071
+ const fallback = { models: [], source: "fallback" };
8072
8072
  const controller = new AbortController;
8073
8073
  const timer = setTimeout(() => controller.abort(), timeoutMs);
8074
8074
  try {
@@ -8188,7 +8188,7 @@ var init_providers = __esm(() => {
8188
8188
  requiresApiKey: false,
8189
8189
  allowLoopback: true,
8190
8190
  platforms: ["darwin"],
8191
- models: ["qwen3.5-9b-4bit"],
8191
+ models: [],
8192
8192
  note: "local \xB7 no key"
8193
8193
  },
8194
8194
  {
@@ -9908,6 +9908,7 @@ var exports_shell_config = {};
9908
9908
  __export(exports_shell_config, {
9909
9909
  shellConfigPath: () => shellConfigPath,
9910
9910
  saveShellConfig: () => saveShellConfig,
9911
+ saveProviderBaseUrl: () => saveProviderBaseUrl,
9911
9912
  saveApiKey: () => saveApiKey,
9912
9913
  loadShellConfig: () => loadShellConfig,
9913
9914
  envWithSavedApiKeys: () => envWithSavedApiKeys,
@@ -9946,6 +9947,10 @@ function saveApiKey(envKey, value, dir) {
9946
9947
  const existing = loadShellConfig(dir).apiKeys ?? {};
9947
9948
  saveShellConfig({ apiKeys: { ...existing, [envKey]: value } }, dir);
9948
9949
  }
9950
+ function saveProviderBaseUrl(provider, baseUrl, dir) {
9951
+ const existing = loadShellConfig(dir).baseUrls ?? {};
9952
+ saveShellConfig({ baseUrls: { ...existing, [provider]: baseUrl } }, dir);
9953
+ }
9949
9954
  function envWithSavedApiKeys(env = process.env, dir) {
9950
9955
  const merged = { ...env };
9951
9956
  try {
@@ -40353,14 +40358,17 @@ var AGENT_SLASH_COMMANDS = [
40353
40358
  description: "Switch provider / API key",
40354
40359
  modes: BOTH,
40355
40360
  modeDescriptions: {
40356
- agent: "Switch provider / API key (interactive picker, key entry)",
40361
+ agent: "Switch connected provider (interactive picker)",
40357
40362
  chat: "Show how to set a provider API key in the environment"
40358
40363
  }
40359
40364
  },
40360
40365
  {
40361
40366
  name: "/provider",
40362
40367
  description: "Switch provider \u2014 /provider <name>, or no arg to re-select",
40363
- modes: CHAT_ONLY
40368
+ modes: BOTH,
40369
+ modeDescriptions: {
40370
+ agent: "Add or configure a provider (interactive picker)"
40371
+ }
40364
40372
  },
40365
40373
  { name: "/think", description: "Expand the last reasoning block", modes: AGENT_ONLY },
40366
40374
  { name: "/expand", description: "Expand the last tool output block", modes: AGENT_ONLY },
@@ -43533,6 +43541,34 @@ function onKeypress3(r, handler) {
43533
43541
  r._internalKeyInput.onInternal("keypress", handler);
43534
43542
  return () => r._internalKeyInput.offInternal("keypress", handler);
43535
43543
  }
43544
+ function promptBaseUrlStep(otui, r, label, baseUrl) {
43545
+ return new Promise((resolve3) => {
43546
+ const box = overlayBox(otui, r, "base-url-picker");
43547
+ r.root.add(box);
43548
+ box.add(new otui.TextRenderable(r, { id: "bp-title", content: otui.t`${otui.bold(`${label} endpoint URL`)} ${otui.dim("(Enter \xB7 Esc to go back)")}` }));
43549
+ box.add(new otui.TextRenderable(r, { id: "bp-note", content: otui.t`${otui.dim("Edit host and port before discovering models")}`, marginTop: 1 }));
43550
+ const input2 = new otui.InputRenderable(r, { id: "bp-input", value: baseUrl, marginTop: 1 });
43551
+ box.add(input2);
43552
+ input2.focus();
43553
+ const cleanup = () => {
43554
+ unsub();
43555
+ r.root.remove(box);
43556
+ };
43557
+ const unsub = onKeypress3(r, (key) => {
43558
+ if (key.name === "escape") {
43559
+ cleanup();
43560
+ resolve3(undefined);
43561
+ key.preventDefault();
43562
+ key.stopPropagation();
43563
+ }
43564
+ });
43565
+ input2.on(otui.InputRenderableEvents.ENTER, () => {
43566
+ const value = input2.value.trim();
43567
+ cleanup();
43568
+ resolve3(value.length > 0 ? value : undefined);
43569
+ });
43570
+ });
43571
+ }
43536
43572
  function promptApiKeyStep(otui, r, opts) {
43537
43573
  return new Promise((resolve3) => {
43538
43574
  const box = overlayBox(otui, r, "key-picker");
@@ -43619,6 +43655,13 @@ function selectProviderModelInTui(otui, r, detected) {
43619
43655
  resolve3(undefined);
43620
43656
  return;
43621
43657
  }
43658
+ const selectedBaseUrl = prov.baseUrl !== undefined ? await promptBaseUrlStep(otui, r, prov.label ?? prov.name, prov.baseUrl) : prov.baseUrl;
43659
+ if (prov.baseUrl !== undefined && selectedBaseUrl === undefined) {
43660
+ continue;
43661
+ }
43662
+ if (selectedBaseUrl !== undefined)
43663
+ saveProviderBaseUrl(prov.name, selectedBaseUrl);
43664
+ const selectedProvider = selectedBaseUrl === undefined ? prov : { ...prov, baseUrl: selectedBaseUrl };
43622
43665
  const envKey = prov.envKey;
43623
43666
  if (envKey !== undefined) {
43624
43667
  const existingKey = process.env[envKey];
@@ -43633,12 +43676,12 @@ function selectProviderModelInTui(otui, r, detected) {
43633
43676
  }
43634
43677
  }
43635
43678
  }
43636
- const models = await modelsForPicker(prov);
43679
+ const models = await modelsForPicker(selectedProvider);
43637
43680
  const model = await pickModelInTui(otui, r, models);
43638
43681
  if (model === undefined) {
43639
43682
  continue;
43640
43683
  }
43641
- resolve3(prov.baseUrl === undefined ? { provider: prov.name, model } : { provider: prov.name, model, baseUrl: prov.baseUrl });
43684
+ resolve3(selectedBaseUrl === undefined ? { provider: prov.name, model } : { provider: prov.name, model, baseUrl: selectedBaseUrl });
43642
43685
  return;
43643
43686
  }
43644
43687
  })();
@@ -43646,7 +43689,8 @@ function selectProviderModelInTui(otui, r, detected) {
43646
43689
  }
43647
43690
  function pickModelInTui(otui, r, models) {
43648
43691
  return new Promise((resolve3) => {
43649
- const all = models.length > 0 ? models : ["fake-echo"];
43692
+ const all = models;
43693
+ const NO_MODELS = "(no models found)";
43650
43694
  const box = overlayBox(otui, r, "model-picker");
43651
43695
  r.root.add(box);
43652
43696
  box.add(new otui.TextRenderable(r, { id: "mp-title", content: otui.t`${otui.bold("Select a model")}` }));
@@ -43660,7 +43704,7 @@ function pickModelInTui(otui, r, models) {
43660
43704
  height: 14,
43661
43705
  showScrollIndicator: true,
43662
43706
  wrapSelection: true,
43663
- options: all.map((m) => ({ name: m, description: "" })),
43707
+ options: (all.length > 0 ? all : [NO_MODELS]).map((m) => ({ name: m, description: "" })),
43664
43708
  selectedTextColor: "#ffd166"
43665
43709
  });
43666
43710
  box.add(sel);
@@ -43703,7 +43747,7 @@ function pickModelInTui(otui, r, models) {
43703
43747
  sel.on(otui.SelectRenderableEvents.ITEM_SELECTED, () => {
43704
43748
  const chosen = sel.getSelectedOption();
43705
43749
  cleanup();
43706
- resolve3(chosen === null || chosen.name === NO_MATCH ? undefined : chosen.name);
43750
+ resolve3(chosen === null || chosen.name === NO_MATCH || chosen.name === NO_MODELS ? undefined : chosen.name);
43707
43751
  });
43708
43752
  });
43709
43753
  }
@@ -44674,10 +44718,27 @@ Staying in the current session.
44674
44718
  `);
44675
44719
  return;
44676
44720
  }
44677
- if (command.name === "/connect") {
44721
+ if (command.name === "/connect" || command.name === "/provider") {
44678
44722
  (async () => {
44679
44723
  const detected = opts.redetect !== undefined ? await opts.redetect() : opts.detected;
44680
- const ns = await chrome.withOverlay(() => selectProviderModelInTui(otui, r, detected));
44724
+ const candidates = command.name === "/provider" ? detected : (await Promise.all(detected.map(async (provider) => {
44725
+ if (provider.name === "fake")
44726
+ return;
44727
+ if (provider.name === "rapid-mlx") {
44728
+ return (await modelsForPicker(provider)).length > 0 ? provider : undefined;
44729
+ }
44730
+ if (provider.envKey !== undefined) {
44731
+ return process.env[provider.envKey]?.length ? provider : undefined;
44732
+ }
44733
+ return provider;
44734
+ }))).filter((provider) => provider !== undefined);
44735
+ if (candidates.length === 0) {
44736
+ io.onSystem?.(`No connected providers found. Use /provider to add or configure one.
44737
+ `);
44738
+ input2.focus();
44739
+ return;
44740
+ }
44741
+ const ns = await chrome.withOverlay(() => selectProviderModelInTui(otui, r, candidates));
44681
44742
  if (ns !== undefined) {
44682
44743
  await switchTo(ns);
44683
44744
  } else {
@@ -45195,7 +45256,7 @@ init_shell_config();
45195
45256
  // package.json
45196
45257
  var package_default = {
45197
45258
  name: "@mrciphersmith/keryx",
45198
- version: "0.2.23",
45259
+ version: "0.2.25",
45199
45260
  description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
45200
45261
  private: false,
45201
45262
  publishConfig: {
@@ -46306,7 +46367,14 @@ async function resolveTuiStartup(opts) {
46306
46367
  appliedKeys
46307
46368
  };
46308
46369
  }
46309
- return { detected: await opts.detect(), appliedKeys };
46370
+ const detected = await opts.detect();
46371
+ return {
46372
+ detected: detected.map((provider) => {
46373
+ const savedBaseUrl = savedCfg.baseUrls?.[provider.name];
46374
+ return typeof savedBaseUrl === "string" && savedBaseUrl.length > 0 ? { ...provider, baseUrl: savedBaseUrl } : provider;
46375
+ }),
46376
+ appliedKeys
46377
+ };
46310
46378
  }
46311
46379
  function parseShellCliFlags(args2) {
46312
46380
  let providerArg;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrciphersmith/keryx",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
4
4
  "description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
5
5
  "private": false,
6
6
  "publishConfig": {