Skip to content

aish v1.0.0-rc1

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Nov 05:43
f187b19

Changed

  • temperature values retain their configured decimal precision in provider requests instead of being rounded through f32. (#616)
  • max_tokens is no longer sent by default: when the config leaves it unset, the field is omitted from the request so the provider applies the model's own output limit (previously a global 4096/40960 constant, which truncated large-output models and was rejected outright by 16k-output ones). An explicit max_tokens at or above 16384 is forwarded as max_completion_tokens unchanged. The Anthropic Messages API requires the field, so that path sends a 64k fallback when unset (the lowest output ceiling among current Claude models). A value below 16384 is removed on load with one warning: older releases wrote their own default into the file (the Python shell's pydantic 1000 and the v0.3.0-v0.3.6 wizard's 4096 were released; the 40960 floor of #619 never shipped), and any handwritten cap that small truncates a long reasoning turn into an incomplete response. 16384 is the smallest output ceiling among models in use (GPT-4o); current models sit far above it (GLM-5.3 65,536 default / 131,072 max, DeepSeek V4.1 64K default / 393,216 max, Kimi K3 131,072 default, Claude 5.5 and GPT-5.1-Codex-Max 128K, Gemini 3.1 Pro 65,536), so a cap at or above the minimum is a workable deliberate choice. null and 0 (both already meaning "no cap") are dropped silently, and /setting max_tokens rejects a below-minimum value instead of writing one the next start would erase. (#627)

Added

  • MCP client (crates/aish-mcp, issue #564). Servers are declared under mcp.servers in ~/.config/aish/config.yaml with the stdio or Streamable HTTP transport, ${VAR} expansion in env/headers, and per-server/per-tool trust and side_effects declarations. Servers connect in the background; /mcp status|list|tools|reload|reconnect shows state, and /status carries a one-line summary. Credentials never reach status output, logs or audit records.
  • MCP tools are discovered on demand instead of being injected into every request: each server exposes one gateway tool (mcp__<server>) with the list / describe / call actions, so only the catalogue names that the model asks for enter the context.
  • Every MCP call goes through the normal preflight/approval path. It is auto-approved only when the user declared the server (or that tool) trust: allow and its effective side effects are read; undeclared, write and network tools ask, trust: block refuses, and server annotations can only narrow a declaration. An approval is bound to the exact argument set (mcp:<server>:<tool>#<digest>), so changed arguments need a new approval.
  • MCP calls honor the same timeout, cancellation, truncation and audit rules as built-in tools: a per-request deadline (default 30s, 0 disables), cancellation through the session token, output capped by max_output_bytes then by the shared 4 KB message cap, and AiTool audit events that now carry duration_ms and an outcome. Server exit, protocol errors and timeouts report a classified failure (connect/timeout/eof/malformed_response/json_rpc/http_status/cancelled) and child processes are reaped with SIGTERM then SIGKILL.
  • /mcp manages servers without hand-editing YAML: add (interactive wizard, or quick add with --transport/--trust/--side-effects/--timeout/--max-output/--env/--header/--url/--token/-- <command…>), remove|rm, enable, disable, trust <server> <tool|*>, test <server>, tool <server> <tool> and tools [server], plus /mcp help. Edits are written to config.yaml atomically (unknown keys preserved) and take effect immediately: the runtime connects or drops just that server and its tool is registered or unregistered in the session. /mcp <sub> <Tab> completes server names, and /mcp test reports the server version, tool count and the first tools, with a hint for the common failure classes.
  • mcp.servers[].expose: tools (opt-in) additionally exposes one tool per remote tool (mcp__<server>_<tool>) with its real schema, so the model can call it directly instead of discovering through the gateway; the default stays gateway so a server's whole catalogue is never injected into the prompt. /mcp status now also lists configured-but-disabled servers as disabled instead of hiding them.
  • Bare /mcp prints the status block and then opens a nine-row interactive menu (every row is reachable by number 1-9): add a server (wizard), tools, test, trust, enable/disable, reconnect, reload, remove, help. Each row opens its own panel — pick the server (rows show name [transport] status · tools: N), then the tool or the trust level; the tools row's first entry lists the whole catalogue and its remaining entries print the per-tool detail, the trust row's first entry is * for the whole server, and enable/disable is one row that flips the server according to its current runtime state. Esc leaves the menu and no action runs without a selection, so every MCP operation is reachable without recalling arguments or hand-editing config.yaml; with nothing configured the menu is the add row alone (the wizard). The explicit subcommands (/mcp status|list|tools|tool|add|remove|enable|disable|trust|test|reload|reconnect) are unchanged, and /mcp help now documents the menu.

Fixed

  • aish -c preselects the session the user attached to most often instead of defaulting to "create new session" or to a single remembered id. Attach counts live in ~/.cache/aish/session-usage.json (the previous last-attach-session file is imported once with that id and removed), the update is guarded by an advisory lock, and with no history the newest live session is preselected. "Create new session" stays selectable but is never the default row: with no live session the picker is skipped entirely and a session is spawned directly. Sessions whose daemon has exited are ignored.