Remove the PR changes that made nanobot onboard default to the wizard, added --defaults, added non-TTY fallback behavior, and changed the Docker smoke command. Keep Quick Start available through nanobot onboard --wizard.
Maintainer edit: replace Quick Start key/base detection with an explicit provider-first flow. Users choose the provider that issued the API key, paste the key, and only custom OpenAI-compatible setups ask for a base URL.
Maintainer edit: restart the Quick Start flow around an API-key-first path without recommending OpenRouter or DeepSeek. Detect unique key prefixes locally, fall back to a user-provided base URL, and only fetch models from that approved URL.
Maintainer edit: restart the Quick Start default around a mainland-friendly provider instead of making OpenRouter the first-run dependency. Update wizard copy, default preset, focused tests, and beginner docs to use DeepSeek with the current deepseek-v4-flash model.
Maintainer edit: continue the wizard simplification pass by making Quick Start save after the API key path, hiding save/summary actions until they are needed, removing failed-key side effects, and aligning beginner docs with the local WebUI path.
Maintainer edit: collapse the first-run wizard to an API-key-only Quick Start and move lower-frequency provider, model, channel, gateway, and tool settings behind Advanced Settings.
Maintainer edit: reduce the default onboarding path to a recommended local WebUI setup that only asks for an OpenRouter key, while keeping the detailed provider/channel flow available for advanced setup.
Maintainer edit: make explicit --defaults refresh existing configs without prompting when no TTY is available, preserving user values for CI and Docker runs.
Keenable's public endpoint serves the free tier (1000 req/hour) without
auth. Route to /v1/search/public with the X-Keenable-Title header when no
key is configured, instead of falling back to DuckDuckGo; keep the
authenticated /v1/search path when an apiKey or KEENABLE_API_KEY is set.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
WhatsApp can deliver a sender LID instead of a phone number. The channel
already learns the LID->phone mapping at runtime, but only after a message
that carries both values, so the first message from a contact can't be
resolved to a phone number.
Seed the mapping on startup from two sources:
- reverse mapping files the bridge persists in the auth directory
(lid-mapping-<lid>_reverse.json), resolved via get_runtime_subdir so it
respects a custom runtime dir
- a new optional channels.whatsapp.lidMappings config dict for static
mappings (takes precedence over the on-disk files)
Malformed/empty mapping files are ignored rather than failing startup.
Adds tests for both sources, precedence, malformed files and the
no-auth-dir case, plus docs for the new config field.
Manual testing against the live API showed the Keenable REST endpoint
(/v1/search) returns 401 without a key — the keyless "free tier" applies
only to the CLI, not the HTTP API. Treat Keenable like every other
key-based provider: fall back to DuckDuckGo when no key is configured,
and drop the now-inaccurate free-tier wording from the docs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bring the Keenable search provider in line with the established
multi-file provider pattern so it surfaces everywhere the others do:
- settings_api.py: register in the web-search provider options so it
appears in the WebUI settings dropdown (credential: api_key, optional).
- WebUI provider-brand: add keenable brand entry + brand test.
- docs/configuration.md: provider table row + config example.
- Harden _search_keenable: honor config.timeout and return explicit
messages on HTTP status errors (429 / other), matching peer providers.
- Add env-key and HTTP-error tests; add the websocket settings whitelist
assertion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace `sh -c "$(curl ...)"` with `curl ... | sh` across all
documentation. The subshell pattern breaks when users embed the
command inside other scripts (e.g. Dockerfiles using here-docs),
because the outer shell eagerly expands `$(curl ...)` before writing
the script to disk, mangling the installer contents.
The pipe pattern avoids this problem and is friendlier to further
scripting. For commands that pass arguments (--dry-run, --dev),
`sh -s --` is used to forward them through stdin.
maintainer edit: reject arbitrary custom provider keys that normalize to built-in provider names so runtime and WebUI settings cannot disagree about whether a provider is dynamic or built in.
maintainer edit: spell out that arbitrary named custom providers use the OpenAI-compatible request format only, and point Anthropic-compatible proxies to the built-in anthropic provider with apiBase.
maintainer edit: explain how to configure arbitrary OpenAI-compatible provider names, including multiple endpoints, model presets, and troubleshooting guidance.
Slack's groupPolicy could either restrict to specific channels
("allowlist") or require an @mention ("mention"), but not both: in
allowlist mode the bot replied to every message in approved channels.
Add a groupRequireMention flag so that, when groupPolicy is "allowlist",
the bot only responds in channels listed in groupAllowFrom AND only when
@mentioned. Mirrors Signal's group.requireMention. No effect for the
"mention"/"open" policies, so existing configs are unchanged.
Extract the mention check into _is_mention and reuse it from both the
mention and allowlist branches.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add StepFunTranscriptionProvider class in nanobot/providers/transcription.py
- New _post_stepfun_asr_with_retry() function handling SSE stream parsing
(transcript.text.delta → transcript.text.done event sequence)
- Register 'stepfun' in transcription_registry.py with default model stepaudio-2.5-asr
- Reuse existing stepfun provider config (apiBase can point to Plan endpoint)
- Add 17 tests covering SSE parsing, retry contract, empty-text edge case, and registry integration
- Update docs/configuration.md with stepfun ASR documentation
StepFun ASR uses a dedicated SSE endpoint (/v1/audio/asr/sse) rather
than the chat-completions or Whisper multipart formats used by other
providers. Users on Step Plan can set apiBase to the Plan endpoint.
* docs: make onboarding friendlier for beginners
* docs: build clearer documentation paths
Maintainer edit: turn the onboarding follow-up into a layered docs structure for first-time setup, provider selection, troubleshooting, CLI reference, and source-level architecture. This keeps quick start focused while giving advanced users precise reference paths.
* docs: render architecture flow with mermaid
Maintainer edit: replace the ASCII architecture sketch with a GitHub-rendered Mermaid flowchart so the core runtime path is easier to scan in the PR and README docs.
* docs: recommend model presets for model config
Maintainer edit: make named modelPresets the primary model configuration path and expand fallback preset examples so string fallbacks are clearly preset names, not raw model IDs.
* docs: document api base urls and langfuse setup
Maintainer edit: explain when users need apiBase/base URL in quick start and provider docs, and add Langfuse tracing setup with troubleshooting links.
* docs: use python module pip consistently
Maintainer edit: keep install commands tied to the active Python interpreter by using python -m pip in the Azure optional dependency notes too.
* docs: add non-technical getting started path
Maintainer edit: add a wizard-first guide for users without terminal or JSON background, including a text TUI menu example and links from the main docs entrypoints.
* docs: avoid hard-wrapped prose in user docs
Maintainer edit: unwrap ordinary prose across user-facing documentation while preserving markdown structure, code blocks, tables, lists, and prompt/template files.
* docs: keep desktop list continuations nested
Maintainer edit: preserve list nesting after unwrapping prose in the desktop WebUI sync guide.
* docs: add one-command installer
Maintainer edit: add auditable macOS/Linux and Windows install scripts that install nanobot-ai and start the onboarding wizard, then document the commands in the main onboarding entrypoints.
* docs: add installer dry run mode
Maintainer edit: add --dry-run to the one-command installer scripts so users can preview Python detection, install source, pip command, and wizard behavior without changing their environment.
* docs: clean installer error output
Maintainer edit: make PowerShell installer failures print a concise Error: message instead of Write-Error call-site details.
* docs: add provider setup cookbook
Maintainer edit: add pasteable provider recipes for common hosted, local, fallback, runtime switching, and Langfuse setups, then link the cookbook from onboarding and troubleshooting entrypoints.
* docs: address review feedback
* docs: clarify reader paths
* docs: explain terminal basics for beginners
* docs: clarify wizard navigation
* docs: avoid duplicate onboarding steps
* docs: add setup status check
* docs: explain status output
* docs: remove provider recommendation wording
* docs: explain status diagnostics
* docs: reduce hard-wrapped guidance
* docs: migrate config examples to presets
* docs: clarify python command fallbacks
* docs: improve installer failure recovery
* docs: expand install troubleshooting
* docs: cover installer download failures
* docs: put stable install paths first
* docs: add bundled webui quick path
* docs: clarify provider-neutral setup
* docs: clarify gateway setup for chat surfaces
* docs: improve docs navigation paths
* docs: add configuration quick jump
* docs: clarify provider secret variables
* chore: request PR review acknowledgement
Empty commit: please read the PR review comments and reply on the PR to confirm that you have received them.
This commit intentionally changes no files; it exists only to notify the remote Codex run so it can end its active goal.
* docs: add README start here guide
* docs: avoid provider recommendation wording
* docs: guide next steps after first reply
* docs: explain merging JSON snippets
* docs: add CLI command chooser
* docs: add configuration task map
* docs: add deployment readiness guide
* docs: simplify WebUI entry paths
* docs: add provider recipe chooser
* docs: fix provider factual references
Update OpenRouter and LongCat model examples, align Bedrock guidance, and make fallback snippets schema-valid.
Also correct group policy wording and image-generation provider lists to match the current code.
* fix: keep PowerShell installer from closing caller shell
* docs: mention self-guided configuration
Add AssemblyAI as a third transcription provider option alongside
OpenAI and Groq. AssemblyAI offers better accuracy for certain
audio types (distant voices, noisy environments) and serves as a
reliable fallback when other providers struggle.
Changes:
- Add AssemblyAITranscriptionProvider class in providers/transcription.py
- Add 'assemblyai' option in base channel's transcribe_audio()
- Per-channel configuration via transcriptionProvider in config
Usage:
Set transcriptionProvider: 'assemblyai' and provide an AssemblyAI
API key via transcriptionApiKey in the channel config.
Add support for Xiaomi MiMo ASR as a third transcription backend alongside
Groq and OpenAI Whisper. Xiaomi ASR uses the /v1/chat/completions endpoint
with base64-encoded audio input, rather than the standard Whisper multipart
upload format.
Co-Authored-By:连 <lian@tangping.homes>
Add a `transcriptionModel` channel setting and an OpenRouter transcription
backend so voice messages can be transcribed through OpenRouter's
speech-to-text endpoint (e.g. nvidia/parakeet-tdt-0.6b-v3, openai/whisper-1),
alongside the existing Groq/OpenAI Whisper providers.
- schema: add channels.transcriptionModel (None = provider default)
- providers/transcription: extract a shared POST/retry skeleton; add a
JSON+base64 OpenRouterTranscriptionProvider; make the STT model a
constructor param on all providers instead of hardcoding it
- channels: route transcriptionProvider="openrouter" and thread the model
through the manager to each channel
- docs + tests
Only dedicated STT models work on OpenRouter's transcription endpoint;
chat LLMs (e.g. google/gemini-3.5-flash) are rejected there.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Maintainer edit: explain that HTTP/SSE MCP now uses the shared SSRF guard before connecting and before following redirects, so local or private HTTP MCP endpoints require an explicit tools.ssrfWhitelist entry.