3532 Commits
Author SHA1 Message Date
Pranit 9b558ed785 Merge pull request #1477 from vercel-labs/fazxes/fuzzy-model-search
Make model search fuzzy across provider and model names
2026-10-27 22:09:01 -04:00
Pranit 63540de785 Merge pull request #1414 from vercel-labs/fazxes/consolidate-provider-and-session-code
Consolidate duplicated provider and session code
2026-10-27 21:14:26 -04:00
Pranit f9ddaff828 Make model search fuzzy across provider and model names
- The model menu and the inline `/model <query>` suggestions match each query word against the full `provider/model` ID, so `anthropic opus` and `claude sonnet 4.5` find their models.
- Punctuation inside a query word is ignored, so `sonnet45` finds `claude-sonnet-4.5` and `z.ai glm` finds the `zai/glm-*` models.
- A query word also matches when its letters appear in order from the start of a word in the ID, so `cs45` finds `anthropic/claude-sonnet-4.5`.
- Results that contain the query as typed come first, then word matches, then fuzzy matches, each in catalog order, so queries that already worked keep the same top results.
2026-10-27 21:01:23 -04:00
Pranit 7f2383af70 Merge pull request #1471 from vercel-labs/prepare-v0.0.15-refresh-20261027
Prepare v0.0.15 release
v0.0.15
2026-10-27 14:17:34 -04:00
Pranit ec872b150f Prepare v0.0.15 release 2026-10-27 14:09:55 -04:00
Pranit 404b5ed7b7 Merge pull request #1466 from vercel-labs/fazxes/run-mcp-tools-across-turns
Run MCP tools across turns and recover from empty cut-off replies
2026-10-27 13:53:54 -04:00
Pranit 8122faa1d2 Keep the empty-reply retry inside known limits
The retry of an empty reply cut short by the provider's default used a
flat 32,768-token limit and kept it for every later step, even when the
catalog named a limit of its own. A known context window now bounds the
limit, as it bounds a full-window limit, and a catalog limit wins on
later steps.

ChatGPT's Codex endpoint chooses its own output limit, so a retry there
sent the same request again and said it was raising the limit. Providers
now say whether a request carries fx's limit, and the retry runs only
through one that does.

The model cache and command replay comments now describe the bounded
wait and the run id in each handle.
2026-10-27 12:56:05 -04:00
Pranit 50c641e6e3 Merge main into the MCP tool fixes
Main now pluralizes subagent counts in tool group summaries the same way
this branch pluralizes MCP calls, so the label keeps both: "subagents"
and "MCP calls".
2026-10-27 12:21:35 -04:00
Pranit d521b9aa84 Merge pull request #1467 from vercel-labs/fazxes/pluralize-subagent-summary
Pluralize subagent counts in tool group summaries
2026-10-27 12:18:52 -04:00
Pranit e874c63a36 Update tests and the design record for the new handle, label, and retry
Tests that read command replays matched the old handle, fx-command-replay-
and the hash, so they found none once each run's handle gained a run id.
They now accept the run id and take the blob's name from the hash after
it. D91 in the session manager's design record amends D44 with the new
handle shape.

A name the registry lacks but that has the mcp_ prefix now counts as an
MCP call, so the unsupported-tool test expects "1 command · 1 MCP call".
The ACP length test scripts the retry's reply and checks that the retry
carries a 32,768-token limit and never asks for a summary.
2026-10-27 11:42:45 -04:00
Pranit 8625c8f600 Pluralize subagent counts in tool group summaries
A tool group with several subagent calls now reads "4 subagents"
instead of "4 subagent". A group with one subagent call still reads
"1 subagent".
2026-10-27 11:20:30 -04:00
Pranit 4f5153c8c4 Give each command run its own output handle
A command's full_output_handle named the blob that holds its output, so
two commands with identical output got the same handle, and a later
result looked like a replay of an earlier one.

The handle now starts with a random id for the run and still ends with
the blob's hash. Runs with the same output keep sharing one stored copy
under handles of their own, and existing handles still resolve.
2026-10-27 11:13:33 -04:00
Pranit bedc0e7cf3 Ask again once when a reply runs out of output before any text
When a request named no output limit and the provider's own default ran
out before any text or tool call, fx ended the turn with "Done." for an
empty reply.

fx now sends the request again once, with a limit of 32,768 tokens, and
says it is retrying. If that reply is also empty, or the request already
had the catalog's limit, the turn ends with "The reply ran out of output
tokens before any text." instead of "Done.".
2026-10-27 11:13:22 -04:00
Pranit 65846154c9 Wait briefly for a failed model catalog's retry
When the model catalog failed to load, the retry a submitted prompt
starts ran behind the failed state, so the prompt's first request went
out without the model's limits. With no output limit, some providers
stop a reply at 4,096 tokens.

A request now waits up to two seconds for that retry, as it waits for a
first load. A retry that lands in time gives the request the catalog's
limits. A slower one leaves the request as it was before, so a retry
that hangs never holds a prompt for longer than that.
2026-10-27 11:13:01 -04:00
Pranit 0fb5cb8e6f Run MCP tools the model calls without loading them first
A tool the model loads with capability_search or mcp_select_tool stays
loaded only for that turn. When the model called it again in a later
turn, or after a resume, the terminal app and fx ask failed the call
with "Dynamic MCP tool not selected for this model step", and the model
had to load the tool again before it could use it.

ACP already loads such a call's current definition from the live
catalog and sends the call through normal validation and permission
review. The terminal app and fx ask now do the same. A name that no live
server has still fails without reaching any server.
2026-10-27 11:12:53 -04:00
Pranit 1ce845071e Label MCP tool calls in tool group summaries
A tool the registry does not hold was counted as a command, so a turn's
MCP calls showed up as "2 commands" in its tool group summary and as
commands started in the status line.

Every MCP tool name has the mcp_ prefix, so those calls now have their
own activity kind. The summary reads "1 MCP call" or "2 MCP calls", and
the status line counts MCP calls made.
2026-10-27 11:12:46 -04:00
Pranit 70866b2712 Merge pull request #1464 from vercel-labs/fazxes/refresh-pgso-corpus-expectations 2026-10-26 23:26:56 -04:00
Pranit 99b8ad47d7 Refresh PGSO corpus expectations 2026-10-26 18:17:33 -04:00
Pranit e71a663b95 Merge pull request #1462 from vercel-labs/prepare-v0.0.15
Prepare v0.0.15 release
2026-10-26 16:20:02 -04:00
Pranit a13511634f Prepare v0.0.15 release 2026-10-26 16:17:21 -04:00
Pranit de8e919056 Merge pull request #1460 from vercel-labs/esteban/mcp-menu-sign-in-link
Link a waiting sign-in in one line on the server screen
2026-10-26 16:16:02 -04:00
Esteban Suarez 040d5bbbf2 Link a waiting sign-in in one line on the server screen
While a sign-in waits, the server screen in /mcp now reads "Didn't open?
Open the sign-in page." with the label linking the whole address, as the
transcript does since the sign-in links change. A long address no longer
fills the panel. An address that can't be a link target, or a screen too
narrow for the label, still shows the whole address. The transcript and
the screen share the label from menu.sign_in_link_label.
2026-10-26 11:18:56 -03:00
Pranit f0732a02c3 Merge pull request #1457 from vercel-labs/fazxes/reconnect-dropped-mcp-connections
Reconnect when an MCP server drops an idle connection
2026-10-25 22:38:54 -04:00
Pranit a97f9d9e2f Reconnect when an MCP server drops an idle connection
- An MCP tool call over HTTP after the server dropped an idle connection now goes out on a new connection, instead of failing with "the server went away" on every call until fx restarts.
- Renewing an MCP login after the sign-in server dropped an idle connection now goes through, instead of failing with "the sign-in server didn't answer" until fx restarts.
- A connection the server closed cleanly while idle is replaced before the call is sent, so the call no longer fails once with "the tool may have run".
- Connections unused for more than a minute are replaced instead of reused, so a call after the network silently dropped one no longer waits out its timeout.
- A request whose send fails goes out once more on a new connection. A request that was fully sent is still never sent twice.
2026-10-25 21:37:17 -04:00
Pranit a2e11d98f6 Merge pull request #1453 from vercel-labs/fazxes/link-sign-in-addresses
Link sign-in addresses instead of printing them
2026-10-24 23:00:30 -04:00
Pranit 0840784f9e Read the sign-in driver's addresses from their links
The repeated-login driver read the sign-in address the transcript printed.
The transcript now links it, so the driver records the shell's output and
reads each link's target instead.
2026-10-24 20:07:29 -04:00
Pranit 2d61cc038d Link sign-in addresses instead of printing them
A typed /mcp login and the Vercel sign-in picker printed the whole sign-in
address. Both now show a few underlined words whose OSC 8 link is the
address: "Open the sign-in page" for MCP and "Authorize with Vercel", the
way Codex and Grok already link theirs. Notices underline a link on every
row it wraps onto. An address that can't be a link target is still printed
so it can be copied.
2026-10-24 19:25:50 -04:00
Pranit 7d854a42c6 Merge pull request #1452 from vercel-labs/fazxes/effort-menu
Add /effort to choose the reasoning effort
2026-10-24 14:33:52 -04:00
Pranit fefb9d9a51 Merge pull request #1444 from vercel-labs/fazxes/restart-only-changed-mcp-servers
Restart only the MCP servers a config change affects
2026-10-24 14:31:27 -04:00
Pranit 04a5e3af6a Add /effort to choose the reasoning effort
- `/effort` opens a menu of the current model's reasoning effort levels with the one in use marked. ↑↓ moves, Enter applies the highlighted level, and Esc closes it.
- `/effort <level>` applies a level without the menu, and `/effort default` goes back to the model's default.
- Tab after `/effort` opens a level column under the prompt, as Tab after `/model` opens the model column. ↑↓ previews the level in the status line, typing filters the list, Tab fills in the highlighted level, and Enter applies it.
- A new level is saved like a level chosen in `/settings`, and fx prints `Reasoning effort set to <level> for <model>`.
- During a response, the line reads `Next turn will use reasoning effort <level> for <model>`. The running turn keeps its level.
- A model without levels, a level the model doesn't offer, or a malformed level prints a notice and leaves the effort unchanged. If the model list is still loading, the notice asks to try again.
- In a short terminal, the menu leaves the end of the conversation in view and scrolls.
- `/model` still asks for the effort after a model is chosen.
- `/help` lists `/effort` with the model commands.
2026-10-24 13:28:03 -04:00
Pranit 2327e3cb8e Merge pull request #1445 from vercel-labs/fazxes/permissions-panel
Show /permissions in a footer panel
2026-10-23 22:26:36 -04:00
Pranit 5f9aed6634 Merge pull request #1441 from vercel-labs/fazxes/status-session-panel
Show the session ID in a /status panel
2026-10-23 22:26:05 -04:00
Pranit 45abf082ae Merge pull request #1446 from vercel-labs/fazxes/ask-twenty-questions
Allow up to 20 questions in one ask_user_question call
2026-10-23 22:23:12 -04:00
Pranit ea13c33573 Model sign-ins across in-place MCP reloads
The SignIn model and its driver still had every reload replace the host and
end the sign-in. A reload now keeps a sign-in when it leaves that server
alone and ends it when it removes or changes the server; the host swap
remains for reloads the loader can't apply in place. KeptSignInGoesOn checks
the first, with a planted bug for the old behavior.
2026-10-23 20:20:18 -04:00
Pranit 28cf53b548 Allow up to 20 questions in one ask_user_question call
- The model can ask up to 20 questions in one ask_user_question call, so a related set of questions opens as one prompt instead of several prompts of 4.
- The tool schema and description tell the model the new limit.
- A call with more than 20 questions is rejected with "provide 1 to 20 questions", and no prompt opens.
- Resumed sessions show every answer from a batch of up to 20 questions.
2026-10-23 20:16:15 -04:00
Pranit 915d439bd2 Show /permissions in a footer panel
Running /permissions with no arguments printed the mode, configured
rules, session grants, and saved rules to the transcript. It now opens a
read-only panel in the footer, like /status, and prints nothing. Each
configured rule, session grant, and saved rule is a bullet, and saved
rules show the ID that /permissions revoke takes. The panel updates when
an approval adds a grant. Subcommands such as /permissions auto and
/permissions remember still confirm in the transcript.

The /status panel becomes a shared info panel that both commands use.
Tests that ran /permissions only to put text in the transcript now run
/allowlist.
2026-10-23 19:29:02 -04:00
Pranit 13ff1ab627 Keep the MCP catalog generation 32-bit for wasm32
wasm32 has no 64-bit atomics, so the SDK's WASM builds failed to compile
the catalog's generation counter. Bindings only compare it for equality,
so 32 bits is enough.
2026-10-23 19:28:46 -04:00
Pranit b31b528760 Check the transcript's last row under a short /status panel
With FX_RECORD set, fx prints a recording notice under the banner, so a
12-row terminal has no room left for the banner above the panel. The
tests now check that the last row of the transcript stays in view.
2026-10-23 19:24:29 -04:00
Pranit 333d476456 Restart only the MCP servers a config change affects
An /mcp add, remove, approve, or reject used to build a new MCP host and
restart every server. The runtime now applies the change in place through
Engine.reload: servers with the same config keep their process, connection,
sign-in, and calls; removed or changed servers stop and their calls end;
a changed or re-added server starts once its own old process has exited.

The engine copies each server's environment and compares it by content, so
reading the same config again no longer looks like a change.
2026-10-23 19:10:17 -04:00
Pranit 20331680eb Keep the transcript in view under the /status panel
In a short terminal the panel could take every row but three and cover
the turn in progress. Closing it redrew the rows it had covered, which a
terminal could already have scrolled into history, so they showed twice.
Output written while the panel was open could lose them instead.

The panel now gets the rows an inline picker gets, which leave the end of
the transcript in view, and scrolls the rest with the arrow keys. The E2E
reader scrolls a panel that does not fit to read every line.
2026-10-23 18:54:07 -04:00
Pranit 8a964aca1d Show the session ID in a /status panel
- /status opens a panel in the footer instead of writing a notice to the transcript. Esc or Enter closes it and leaves nothing behind.
- The panel's first line shows the open session's ID and whether it is saved yet, so it can be resumed with fx --resume <id>. A shell that can't save sessions shows none.
- The open panel updates when a running turn saves the session or finishes.
- When the panel doesn't fit, the arrow keys scroll it and the hint says so. Long values such as the workspace path wrap instead of being cut off.
- When profile settings can't be read, the panel shows a Settings line and leaves out auth, instead of printing an error with no status.
- A fork made before the first prompt now counts as saved: /status shows it as saved, and the exit line prints its resume command.
2026-10-23 15:59:13 -04:00
Pranit 314c01479c Merge pull request #1435 from vercel-labs/esteban/reanchor-variation-selector-glyphs
Keep cells aligned after glyphs with a variation selector
2026-10-23 14:02:33 -04:00
Pranit 3f312edcd6 Merge pull request #1417 from vercel-labs/esteban/mcp-status-line-startup
Show the MCP attention count once servers start and clear it after a prompt
2026-10-23 14:02:03 -04:00
Pranit 2f8503970d Merge pull request #1416 from vercel-labs/esteban/mcp-menu-attention-group
Group the /mcp list and tidy each server screen
2026-10-23 14:01:21 -04:00
Pranit 6ba6b47621 Merge pull request #1437 from vercel-labs/fazxes/mcp-oversized-replies
Explain oversized MCP replies and stop fetching them again
2026-10-23 13:55:26 -04:00
Pranit 6d6a4e271f Merge pull request #1436 from vercel-labs/fazxes/mcp-logout-everywhere
Keep MCP logouts in effect across terminals
2026-10-23 13:55:19 -04:00
Pranit 7a64a790c2 Merge pull request #1421 from vercel-labs/fazxes/withhold-earlier-images
Keep earlier images from blocking new messages
2026-10-23 13:44:51 -04:00
Pranit e38fa77e8d Describe the oversized call flag for HTTP answers too
The flag on a call's end covers an HTTP answer over the message limit as
well as a stdio line, so its comments now say so.
2026-10-23 12:20:44 -04:00
Pranit 80b2bbecfb Explain oversized MCP replies and stop fetching them again
- When a stdio MCP server replies with more than 16 MiB, the model is told the reply was too large and fx restarted the server, instead of "the server went away".
- When an HTTP MCP server replies with more than 16 MiB, fx ends the call at once and tells the model the reply was too large, instead of "the server went away".
- fx no longer resumes an HTTP stream (2025 protocol) to fetch an oversized reply again. Before, it downloaded the same reply up to two more times.
- fx no longer requests an oversized tool list again from an HTTP server on the 2026 protocol.
- The debug trace logs each dropped reply with the server, transport, and reason.
2026-10-23 12:10:32 -04:00
Pranit edb1505f8b Keep MCP logouts in effect across terminals
- /mcp logout in a shell now also revokes the login another terminal saved after the shell started. Before, that login stayed valid at the server.
- After another terminal logs out of an MCP server, a shell that still holds the login revokes it the next time it would renew it, instead of renewing it and saving it back.
2026-10-23 12:06:10 -04:00