2887 Commits

Author SHA1 Message Date
tangtaizhong666
eb25df9b49 fix(session): never persist tool results without a declared tool call 2026-06-13 00:05:03 +08:00
tangtaizhong666
2ebf7e2eef fix(session): keep placeholder for tool results filtered to empty 2026-06-13 00:05:03 +08:00
tangtaizhong666
ac5e84d453 fix(session): anchor save boundary to prompt prefix size (#4006)
build_messages merges the current message into a same-role history tail,
shrinking the prompt prefix to 1 + history_count. The save boundary
assumed a standalone current message and skipped one message too many,
cutting the first new-turn assistant message (with its tool_calls) from
persistence while keeping its tool results - producing orphaned tool
results in session history.
2026-06-13 00:05:03 +08:00
tangtaizhong666
df832a37e9 test(session): reproduce orphaned tool results from save-boundary overshoot (#4006) 2026-06-13 00:05:03 +08:00
chengyongru
30640e9e00 docs: clarify model prefix provider resolution 2026-06-13 00:04:13 +08:00
chengyongru
c282012607 fix: resolve auto custom provider settings state
maintainer edit: use the resolved provider row when WebUI settings evaluates auto-selected providers, so named custom providers follow their apiBase-based configured state instead of the legacy has_api_key fallback.
2026-06-13 00:04:13 +08:00
chengyongru
af9f9ebfd7 fix: reject custom provider alias conflicts
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.
2026-06-13 00:04:13 +08:00
chengyongru
b2d00a4ce0 fix: strip dynamic custom provider route prefixes
maintainer edit: preserve provider-prefix CLI routing for named custom providers by stripping only the matched dynamic route prefix before sending the model id to OpenAI-compatible endpoints. This keeps ordinary namespaced model ids intact when the provider is selected explicitly.
2026-06-13 00:04:13 +08:00
chengyongru
09d24e6c25 fix: validate named custom provider endpoints 2026-06-13 00:04:13 +08:00
chengyongru
a9308eb8e2 docs: clarify custom provider protocol support
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.
2026-06-13 00:04:13 +08:00
chengyongru
69d66e0d6a docs: document named custom providers
maintainer edit: explain how to configure arbitrary OpenAI-compatible provider names, including multiple endpoints, model presets, and troubleshooting guidance.
2026-06-13 00:04:13 +08:00
chengyongru
57ced7930d refactor: simplify dynamic provider settings tests
maintainer edit: keep the WebUI dynamic-provider behavior unchanged while reducing repeated test setup and tightening the small dynamic-provider helper.
2026-06-13 00:04:13 +08:00
chengyongru
37ae655fa6 fix: expose dynamic custom providers in WebUI settings
maintainer edit: WebUI settings still treated non-registry custom providers as unknown, so users could not select them in model configurations or fetch their model list. Reuse dynamic provider specs for settings payloads, model-list requests, and provider updates.
2026-06-13 00:04:13 +08:00
chengyongru
68c6844c0b fix: preserve dynamic custom provider semantics
maintainer edit: treat arbitrary custom provider names as direct OpenAI-compatible providers, validate their api_type consistently, and avoid Pydantic instance-field warnings in fallback routing.
2026-06-13 00:04:13 +08:00
wangjingguang002
e9e1489cee feat: support multiple custom OpenAI-compatible providers
This change allows users to define arbitrary custom providers in config:

providers:
  my_provider:
    api_base: ...
    api_key: sk-xxx

Usage:
  nanobot /my_provider/gpt-4 hello
  nanobot --provider my_provider hello

Changes:
- ProvidersConfig: add extra=allow to accept arbitrary fields
- _match_provider: check for custom provider by prefix and by fallback
- registry: add create_dynamic_spec() for dynamic provider specs
2026-06-13 00:04:13 +08:00
brendanlevy
2d9260cb9f feat(slack): add groupRequireMention for allowlist channels
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>
2026-06-12 00:23:27 +08:00
chengyongru
ffae1dca6d fix: keep Telegram streamed code blocks balanced
Maintainer edit: split final streamed Telegram markdown before rendering to HTML so long fenced code blocks do not produce unbalanced <pre><code> chunks while still respecting Telegram's rendered HTML limit.
2026-06-11 13:52:19 +08:00
axelray-dev
a5a816abaf fix(telegram): move fenced-code-block splitting into Telegram-specific helper
Move the fenced-code-block-aware splitting logic out of the shared
split_message helper (used by Signal, Slack, Discord, Weixin, etc.)
and into a Telegram-specific _split_telegram_markdown function.

The shared split_message remains a plain-text chunker. The Telegram
channel now uses _split_telegram_markdown for its raw Markdown paths
that feed _markdown_to_telegram_html, preventing broken HTML rendering
when splits fall inside fenced code blocks.

Also fixes a regression where content beginning with whitespace before
a fence could emit a whitespace-only chunk.

Addresses review feedback on #4257.
2026-06-11 13:52:19 +08:00
axelray-dev
131446fa61 fix(utils): make split_message fenced-code-block-aware
When split_message splits a long message, it now checks whether the
split point falls inside a fenced code block. If so, it either moves
the split to before the opening fence or closes/reopens the fence
across chunks, preventing broken HTML rendering.

Addresses #4250
2026-06-11 13:52:19 +08:00
Xubin Ren
b8a4ceb30c test(webui): cover siliconflow transcription settings 2026-06-10 23:05:12 +08:00
moran
9ed638ad70 feat(transcription): add SiliconFlow as transcription provider
- Register SiliconFlow in transcription registry with default model
  FunAudioLLM/SenseVoiceSmall and alias 'silicon'
- Reuse existing OpenAITranscriptionProvider adapter (Whisper-compatible)
- Add generic key/base resolution: fallback to registry env_key and
  default_api_base when provider config is absent
- Add tests for registry entry, alias, adapter, default model, and
  config resolution with env var fallback
2026-06-10 23:05:12 +08:00
Xubin Ren
ddbd7ca39e
Merge PR #4278: feat(webui): segment transcript storage
feat(webui): segment transcript storage
2026-06-10 21:02:10 +08:00
Xubin Ren
e1e643de2a refactor(webui): keep sidebar index out of session manager 2026-06-10 20:45:29 +08:00
Xubin Ren
1f5ecf36ca fix(webui): align chat action menu hover inset 2026-06-10 20:30:32 +08:00
Xubin Ren
999552b998 perf(webui): index session list metadata 2026-06-10 20:02:22 +08:00
Xubin Ren
603feef3aa Merge remote-tracking branch 'origin/main' into codex/webui-segmented-transcript-store 2026-06-10 19:11:37 +08:00
Xubin Ren
e168bb2754 feat(webui): segment transcript storage 2026-06-10 18:28:55 +08:00
Jiajun Xie
4255656089 refactor(webui): replace real-time polling with click-to-check version updates
- Remove background PyPI polling loop and WebSocket broadcast
- Remove UpdateBanner from ThreadHeader (keep main page clean)
- Add on-demand version check endpoint (GET /api/settings/version-check)
- Add 'About' section in Settings > Overview with check-for-updates button
- Design: no auto-fetch, user initiates check explicitly via button click
2026-06-10 18:11:06 +08:00
chengyongru
c00371c761 docs: clarify streamed timeout fallback behavior
maintainer edit: update fallback docs and provider docstring to describe the new stream-stall timeout recovery exception.
2026-06-10 18:10:44 +08:00
chengyongru
bc4bb508a1 fix: continue recovered streams in a new segment
maintainer edit: streamed timeout recovery was returning the retried response internally while the channel still treated the final outbound as already streamed. End the current stream segment before retry/fallback recovery so subsequent deltas are delivered in a new segment.
2026-06-10 18:10:44 +08:00
aiguozhi123456
2c5a4e0703 fix(providers): allow retry and fallback on stream stalled timeout
When a stream stalls mid-response, both the retry layer and
FallbackProvider blocked recovery because content had already been
emitted via on_content_delta. This left users with truncated replies
and no automatic recovery.

For error_kind="timeout" specifically:
- _run_with_retry now suppresses delta callbacks and retries the same
  model instead of returning immediately
- FallbackProvider now allows failover to a different model with
  delta callbacks suppressed

Non-timeout errors retain the original "skip retry/failover after
streamed content" behavior to avoid duplicate output.
2026-06-10 18:10:44 +08:00
chengyongru
dadb35af49 feat(exec): add path prepend config 2026-06-10 18:09:57 +08:00
chengyongru
8c30dc5a57 Preserve session key when archiving new sessions 2026-06-10 18:09:45 +08:00
chengyongru
bfc6febddc Scope prompt recent history by session
Fixes #4259
2026-06-10 18:09:45 +08:00
chengyongru
aee656eb9f Fail fast on invalid config files 2026-06-10 18:09:36 +08:00
chengyongru
5d7f2e60c2 fix(feishu): lazy-load lark sdk during gateway startup 2026-06-10 18:09:27 +08:00
Xubin Ren
7186039be1 fix(websocket): limit final stream text to inline endings 2026-06-10 15:52:39 +08:00
Syoc
4dd5b62f11 fix(websocket): always send text in stream_end when stream had content
The channel manager coalesces consecutive _stream_delta messages and
forwards a single merged message with _stream_end=True. In that path
no individual delta events ever reach the WebUI client, so the
stream_end frame is the only carrier of the text. The previous guard
only attached text when media-URL rewriting changed the string, which
silently dropped entire turns of plain-text output whenever the
agent generated tokens faster than the queue drained.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 15:52:39 +08:00
Moran
9c492143b4 search: add Bocha web search provider 2026-06-10 15:51:15 +08:00
primit1v0
ce887772e9 fix(sandbox): set HOME inside bwrap 2026-06-10 15:50:53 +08:00
Xubin Ren
62a35c21b8 fix(asr): normalize StepFun transcription endpoint 2026-06-10 15:50:38 +08:00
moran
7930058348 feat(asr): add StepFun ASR SSE transcription provider
- 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.
2026-06-10 15:50:38 +08:00
erikmackinnon
31bfec58d0 Add Exa web search provider 2026-06-10 15:02:07 +08:00
chengyongru
5d91d59cf7 fix(agent): finalize max-iteration turns without tools 2026-06-10 14:47:20 +08:00
chengyongru
99f7f371fa fix: cover o1 max-completion token fallback
Maintainer edit: keep the GPT-5/o-series fallback on slug-boundary matching so unrelated model names are not caught by substring checks, and include o1 alongside o3/o4 because it is also an o-series chat model.
2026-06-10 14:47:10 +08:00
04cb
a779e7c29e fix(providers): use max_completion_tokens for gpt-5/o-series on flagless specs (#4261) 2026-06-10 14:47:10 +08:00
yu-xin-c
fd9fc38f41 fix(tools): keep apply_patch additions line-separated 2026-06-10 14:47:01 +08:00
Xubin Ren
1b5f5b94d5 fix(webui): use tabler fork icon 2026-06-10 04:26:06 +08:00
Xubin Ren
ea791f605c fix(webui): restore fork action icon 2026-06-10 04:26:06 +08:00
Xubin Ren
fd947a1fd8 fix(webui): normalize action tooltips 2026-06-10 04:26:06 +08:00