agentful 0.4.2 → 0.4.4
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.cjs +115 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3044,7 +3044,7 @@ var VERSION, brand, useColor, wrap, paint, tuiDesign, sym, ui;
|
|
|
3044
3044
|
var init_branding = __esm({
|
|
3045
3045
|
"src/branding.ts"() {
|
|
3046
3046
|
"use strict";
|
|
3047
|
-
VERSION = "0.4.
|
|
3047
|
+
VERSION = "0.4.4" ? "0.4.4" : null.version;
|
|
3048
3048
|
brand = {
|
|
3049
3049
|
name: "agentful",
|
|
3050
3050
|
// the command users type
|
|
@@ -3664,7 +3664,17 @@ const plugin = {
|
|
|
3664
3664
|
}
|
|
3665
3665
|
|
|
3666
3666
|
// \u2500\u2500 prompt \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3667
|
-
/**
|
|
3667
|
+
/**
|
|
3668
|
+
* Left half of the line under the input; replaces the engine's plain cwd.
|
|
3669
|
+
* Without a sessionID (the home screen) it falls back to the process
|
|
3670
|
+
* directory.
|
|
3671
|
+
*
|
|
3672
|
+
* The home screen needs it for a second reason: that line is
|
|
3673
|
+
* space-between, so with nothing on the left the engine's key hints
|
|
3674
|
+
* ("tab agents \xB7 ctrl+p commands") sit at column 0 \u2014 the one column the
|
|
3675
|
+
* clip below takes, which cost them their first character up to 0.4.2.
|
|
3676
|
+
* A hint on the left pushes them back to the right edge.
|
|
3677
|
+
*/
|
|
3668
3678
|
function Hint(props) {
|
|
3669
3679
|
const directory = () => safe(
|
|
3670
3680
|
() => api.state.session.get(props.sessionID).directory,
|
|
@@ -3689,16 +3699,34 @@ const plugin = {
|
|
|
3689
3699
|
* left, which puts the rail outside the visible area. Everything else
|
|
3690
3700
|
* keeps working because it is only a shift.
|
|
3691
3701
|
*
|
|
3692
|
-
* \u26A0\uFE0F
|
|
3693
|
-
*
|
|
3694
|
-
*
|
|
3695
|
-
*
|
|
3696
|
-
*
|
|
3702
|
+
* \u26A0\uFE0F The clip must NOT cover the whole component. api.ui.Prompt returns
|
|
3703
|
+
* TWO siblings: its own box, and the "/" + "@" completion list, which is
|
|
3704
|
+
* positioned absolutely ABOVE the input (a negative "top" against its
|
|
3705
|
+
* parent). A clip around both swallowed that list \u2014 the popup rendered
|
|
3706
|
+
* outside the clipped area, so it was never drawn and both triggers
|
|
3707
|
+
* looked dead while the keystrokes still went through (shipped in 0.4.2,
|
|
3708
|
+
* fixed here). So we take the children apart: the first goes inside the
|
|
3709
|
+
* clip, everything after it stays outside. The popup then anchors on the
|
|
3710
|
+
* outer box, which sits one column right of the shifted input \u2014 exactly
|
|
3711
|
+
* where its left edge belongs.
|
|
3712
|
+
*
|
|
3713
|
+
* \u26A0\uFE0F One column is the limit for the shift. The status line under the
|
|
3714
|
+
* input (our hint on the left) sits OUTSIDE that padded box and carries a
|
|
3715
|
+
* margin of just 1, so a wider clip eats the start of the working
|
|
3716
|
+
* directory \u2014 "/Users/\u2026" came out as "sers/\u2026" at -3. The rendering check
|
|
3717
|
+
* asserts the working directory, and the popup, for exactly this reason.
|
|
3697
3718
|
*/
|
|
3698
3719
|
function Field(props) {
|
|
3720
|
+
// Read once: in the engine's Solid runtime this getter runs the child
|
|
3721
|
+
// component, and each node may only be inserted into one parent.
|
|
3722
|
+
const parts = props.children
|
|
3723
|
+
const list = Array.isArray(parts) ? parts : [parts]
|
|
3699
3724
|
return (
|
|
3700
|
-
<box width="100%"
|
|
3701
|
-
<box
|
|
3725
|
+
<box width="100%">
|
|
3726
|
+
<box width="100%" overflow="hidden">
|
|
3727
|
+
<box marginLeft={-1} width="100%">{list[0]}</box>
|
|
3728
|
+
</box>
|
|
3729
|
+
{list.slice(1)}
|
|
3702
3730
|
</box>
|
|
3703
3731
|
)
|
|
3704
3732
|
}
|
|
@@ -3728,6 +3756,7 @@ const plugin = {
|
|
|
3728
3756
|
<Prompt
|
|
3729
3757
|
ref={data.ref}
|
|
3730
3758
|
placeholders={PLACEHOLDERS}
|
|
3759
|
+
hint={<Hint />}
|
|
3731
3760
|
right={<HostSlot name="home_prompt_right" />}
|
|
3732
3761
|
/>
|
|
3733
3762
|
</Field>
|
|
@@ -7387,6 +7416,21 @@ function skillsInstructionFor(framework, rootDir) {
|
|
|
7387
7416
|
}
|
|
7388
7417
|
|
|
7389
7418
|
// src/lib/models.ts
|
|
7419
|
+
var OAUTH_BYOK_PROVIDER = "github-copilot";
|
|
7420
|
+
async function fetchCopilotAccountModels(auth) {
|
|
7421
|
+
try {
|
|
7422
|
+
const res = await request(
|
|
7423
|
+
`${PB_URL}/api/llm/copilot/models`,
|
|
7424
|
+
{ token: auth.pb_token, timeoutMs: 15e3 }
|
|
7425
|
+
);
|
|
7426
|
+
return (res.models || []).map((m) => m?.id).filter((id) => !!id);
|
|
7427
|
+
} catch {
|
|
7428
|
+
return null;
|
|
7429
|
+
}
|
|
7430
|
+
}
|
|
7431
|
+
function supportsHostedModelInLocalEngine(id) {
|
|
7432
|
+
return !/^gemini-3(?:[.-]|$)/i.test(id.trim());
|
|
7433
|
+
}
|
|
7390
7434
|
async function fetchModelCatalog(auth, fallback) {
|
|
7391
7435
|
const regionDefaultsToBedrock = fallback.ai_region === "eu" || fallback.ai_region === "de";
|
|
7392
7436
|
const isAgenticCapable = (id) => id !== "auto" && !id.includes("bedrock");
|
|
@@ -7400,8 +7444,8 @@ async function fetchModelCatalog(auth, fallback) {
|
|
|
7400
7444
|
}
|
|
7401
7445
|
if (!catalog?.models?.length) {
|
|
7402
7446
|
return {
|
|
7403
|
-
models: fallback.models.map((id) => ({ id, name: id })),
|
|
7404
|
-
defaultModel: fallback.default_model,
|
|
7447
|
+
models: fallback.models.filter(supportsHostedModelInLocalEngine).map((id) => ({ id, name: id })),
|
|
7448
|
+
defaultModel: supportsHostedModelInLocalEngine(fallback.default_model) ? fallback.default_model : fallback.models.find(supportsHostedModelInLocalEngine) || "auto",
|
|
7405
7449
|
byokProviders: [],
|
|
7406
7450
|
canSelectModel: true,
|
|
7407
7451
|
inactiveByok: []
|
|
@@ -7411,6 +7455,7 @@ async function fetchModelCatalog(auth, fallback) {
|
|
|
7411
7455
|
let hasGenericByok = false;
|
|
7412
7456
|
for (const m of catalog.models) {
|
|
7413
7457
|
if (!m?.id) continue;
|
|
7458
|
+
if (!supportsHostedModelInLocalEngine(m.id)) continue;
|
|
7414
7459
|
if (m.id === "byok") {
|
|
7415
7460
|
if (m.has_active_keys) hasGenericByok = true;
|
|
7416
7461
|
continue;
|
|
@@ -7419,6 +7464,7 @@ async function fetchModelCatalog(auth, fallback) {
|
|
|
7419
7464
|
}
|
|
7420
7465
|
const byokProviders = [];
|
|
7421
7466
|
const inactiveByok = [];
|
|
7467
|
+
let byokNotice;
|
|
7422
7468
|
if (catalog.byok_enabled && catalog.has_byok_keys) {
|
|
7423
7469
|
try {
|
|
7424
7470
|
const res = await request(`${PB_URL}/api/llm/byok`, {
|
|
@@ -7431,8 +7477,23 @@ async function fetchModelCatalog(auth, fallback) {
|
|
|
7431
7477
|
inactiveByok.push({ provider: key.provider_type, models: key.models || [] });
|
|
7432
7478
|
continue;
|
|
7433
7479
|
}
|
|
7434
|
-
|
|
7435
|
-
|
|
7480
|
+
const selection = key.models || [];
|
|
7481
|
+
let models = selection;
|
|
7482
|
+
if (key.provider_type === OAUTH_BYOK_PROVIDER) {
|
|
7483
|
+
const live = await fetchCopilotAccountModels(auth);
|
|
7484
|
+
if (live === null) {
|
|
7485
|
+
byokNotice = selection.length ? `${key.provider_type}: account model list unavailable \u2014 showing your stored selection.` : `${key.provider_type}: account model list unavailable \u2014 no own-key model in this session.`;
|
|
7486
|
+
} else if (!selection.length) {
|
|
7487
|
+
models = live;
|
|
7488
|
+
} else {
|
|
7489
|
+
models = selection.filter((m) => live.includes(m));
|
|
7490
|
+
if (!models.length) {
|
|
7491
|
+
byokNotice = `${key.provider_type}: none of your selected models is served by the account right now \u2014 re-select them in Settings \u2192 BYOK.`;
|
|
7492
|
+
}
|
|
7493
|
+
}
|
|
7494
|
+
}
|
|
7495
|
+
if (models.length) byokProviders.push(key.provider_type);
|
|
7496
|
+
for (const model of models) {
|
|
7436
7497
|
entries.push({
|
|
7437
7498
|
id: `byok/${key.provider_type}/${model}`,
|
|
7438
7499
|
name: `${model} \xB7 your key (${key.provider_type})`,
|
|
@@ -7457,7 +7518,8 @@ async function fetchModelCatalog(auth, fallback) {
|
|
|
7457
7518
|
defaultModel,
|
|
7458
7519
|
byokProviders,
|
|
7459
7520
|
canSelectModel: catalog.can_select_model !== false,
|
|
7460
|
-
inactiveByok
|
|
7521
|
+
inactiveByok,
|
|
7522
|
+
byokNotice
|
|
7461
7523
|
};
|
|
7462
7524
|
}
|
|
7463
7525
|
|
|
@@ -7776,6 +7838,20 @@ async function listEngineModels(binPath, xdg, provider) {
|
|
|
7776
7838
|
});
|
|
7777
7839
|
return parseEngineModelsOutput(stdout);
|
|
7778
7840
|
}
|
|
7841
|
+
async function refreshEngineModelCache(binPath, xdg) {
|
|
7842
|
+
await execFileAsync(binPath, ["models", "--refresh"], {
|
|
7843
|
+
env: {
|
|
7844
|
+
...process.env,
|
|
7845
|
+
XDG_CONFIG_HOME: xdg.configHome,
|
|
7846
|
+
XDG_DATA_HOME: xdg.dataHome,
|
|
7847
|
+
XDG_STATE_HOME: xdg.stateHome,
|
|
7848
|
+
OPENCODE_DISABLE_AUTOUPDATE: "true"
|
|
7849
|
+
},
|
|
7850
|
+
encoding: "utf8",
|
|
7851
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
7852
|
+
timeout: 6e4
|
|
7853
|
+
});
|
|
7854
|
+
}
|
|
7779
7855
|
async function assertEngineModelAvailable(binPath, xdg, model, listModels = listEngineModels) {
|
|
7780
7856
|
const provider = modelProvider(model);
|
|
7781
7857
|
const models = await listModels(binPath, xdg, provider);
|
|
@@ -8170,6 +8246,9 @@ async function tuiCommand(opts = {}) {
|
|
|
8170
8246
|
"Resume model metadata is not readable locally; the engine keeps the session model unchanged."
|
|
8171
8247
|
));
|
|
8172
8248
|
}
|
|
8249
|
+
if (catalog.byokNotice) {
|
|
8250
|
+
ui.warn(catalog.byokNotice);
|
|
8251
|
+
}
|
|
8173
8252
|
if (catalog.byokProviders.length) {
|
|
8174
8253
|
ui.info(paint.dim(
|
|
8175
8254
|
`Includes your own keys (${catalog.byokProviders.join(", ")}): billed by that provider` + (session.ai_region && session.ai_region !== "all" ? `, outside your "${session.ai_region}" region setting.` : ".")
|
|
@@ -8446,6 +8525,10 @@ async function licensesCommand() {
|
|
|
8446
8525
|
|
|
8447
8526
|
// src/commands/models.ts
|
|
8448
8527
|
init_branding();
|
|
8528
|
+
function describeInactiveModels(key) {
|
|
8529
|
+
if (key.models.length) return key.models.join(", ");
|
|
8530
|
+
return key.provider === OAUTH_BYOK_PROVIDER ? "all account models" : "(no model)";
|
|
8531
|
+
}
|
|
8449
8532
|
async function modelsCommand(opts) {
|
|
8450
8533
|
console.log(banner());
|
|
8451
8534
|
const auth = await ensureAuth();
|
|
@@ -8463,18 +8546,30 @@ async function modelsCommand(opts) {
|
|
|
8463
8546
|
const decision = decideLocalProviders(policy);
|
|
8464
8547
|
const resolved = resolveLocalProviders(policy);
|
|
8465
8548
|
const configured = Object.keys(readLocalProviders());
|
|
8549
|
+
if (catalog.byokNotice) {
|
|
8550
|
+
console.log("");
|
|
8551
|
+
ui.warn(catalog.byokNotice);
|
|
8552
|
+
}
|
|
8466
8553
|
if (catalog.inactiveByok.length) {
|
|
8467
8554
|
console.log("");
|
|
8468
8555
|
console.log(paint.dim(" Configured but inactive (one own key can be active at a time \u2014"));
|
|
8469
8556
|
console.log(paint.dim(" switch it in Settings \u2192 BYOK to use another):"));
|
|
8470
8557
|
for (const k of catalog.inactiveByok) {
|
|
8471
|
-
console.log(paint.dim(` \u25CB ${k
|
|
8558
|
+
console.log(paint.dim(` \u25CB ${describeInactiveModels(k)} \xB7 ${k.provider}`));
|
|
8472
8559
|
}
|
|
8473
8560
|
}
|
|
8474
8561
|
const xdg = engineXdg();
|
|
8475
8562
|
const connectedProviders = readConnectedEngineProviders(xdg);
|
|
8476
8563
|
if (connectedProviders.length) {
|
|
8477
8564
|
const binPath = await ensureEngine();
|
|
8565
|
+
if (opts.refresh) {
|
|
8566
|
+
try {
|
|
8567
|
+
await refreshEngineModelCache(binPath, xdg);
|
|
8568
|
+
ui.step("Refreshed the engine model cache from models.dev.");
|
|
8569
|
+
} catch {
|
|
8570
|
+
ui.warn("Engine model cache could not be refreshed \u2014 listing the cached catalog.");
|
|
8571
|
+
}
|
|
8572
|
+
}
|
|
8478
8573
|
console.log("");
|
|
8479
8574
|
console.log(paint.bold("Direct TUI connections") + paint.dim(" (provider billing/terms; outside Agentful credits and region controls)"));
|
|
8480
8575
|
for (const provider of connectedProviders) {
|
|
@@ -8489,6 +8584,10 @@ async function modelsCommand(opts) {
|
|
|
8489
8584
|
console.log(` ${paint.warn("!")} ${provider} ${paint.dim("\u2014 catalog could not be read")}`);
|
|
8490
8585
|
}
|
|
8491
8586
|
}
|
|
8587
|
+
} else if (opts.refresh) {
|
|
8588
|
+
console.log("");
|
|
8589
|
+
ui.info("No provider is connected directly in the TUI, so nothing is cached \u2014");
|
|
8590
|
+
ui.info("the Agentful catalog and your own keys are read live on every run.");
|
|
8492
8591
|
}
|
|
8493
8592
|
console.log("");
|
|
8494
8593
|
console.log(paint.bold("Local providers") + paint.dim(" (your key, direct to the provider)"));
|
|
@@ -8606,7 +8705,7 @@ program2.command("tui").description("Start the Agentful coding TUI with your Age
|
|
|
8606
8705
|
program2.command("publish <subdomain>").description("Publish the built project at https://<subdomain>.agentful.dev").action(run(publishCommand));
|
|
8607
8706
|
program2.command("share").description("Make the live preview public (anyone with the link)").option("--private", "make the preview owner-only again").action(run((opts) => shareCommand(opts)));
|
|
8608
8707
|
program2.command("pull").description("Download the cloud workspace into this directory").option("--force", "overwrite files in a non-empty directory").action(run((opts) => pullCommand(opts)));
|
|
8609
|
-
program2.command("models").description("List available models and manage local providers with your own key").option("--add-local", "create/show the local provider file to edit").action(run((opts) => modelsCommand(opts)));
|
|
8708
|
+
program2.command("models").description("List available models and manage local providers with your own key").option("--add-local", "create/show the local provider file to edit").option("--refresh", "refresh the engine model cache from models.dev").action(run((opts) => modelsCommand(opts)));
|
|
8610
8709
|
program2.command("upgrade").description("Update the CLI to the latest version").action(run(upgradeCommand));
|
|
8611
8710
|
program2.command("licenses").description("Show licenses of the software distributed with this CLI").action(run(licensesCommand));
|
|
8612
8711
|
program2.parseAsync(process.argv);
|