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.
Maintainer edit: preserve provider-specific size hints for custom image generation endpoints while keeping the default 1K mapping compatible. Clarify the custom provider contract in docs and cover response_format/size overrides in tests.
Maintainer edit: require providers.custom.apiBase before making custom image requests and allow unauthenticated local endpoints by omitting Authorization when no apiKey is configured.
* refactor(dream): replace two-phase Dream class with simple cron + process_direct
- Remove the heavyweight Dream class (AgentRunner-based two-phase system)
from nanobot/agent/memory.py
- Delete dream_phase1.md and dream_phase2.md templates
- New dream.md template serves as the consolidation prompt
- Cron callback uses agent.process_direct(prompt, session_key=\"dream\")
instead of agent.dream.run()
- Always performs git auto_commit after execution
- /dream command updated to use process_direct + git commit
- DreamConfig kept for backward compatibility; deprecated fields
(model_override, max_batch_size, max_iterations, annotate_line_ages)
are ignored but accepted in config
- interval_h remains configurable via agents.defaults.dream.interval_h
- Update tests and webui settings to match new architecture
* feat(loop): add ephemeral mode to process_direct, skip history writes for Dream
When ephemeral=True, _state_save skips enforce_file_cap (which calls
raw_archive -> append_history) and consolidator.maybe_consolidate_by_tokens.
This prevents Dream sessions from creating a positive feedback loop where
they process their own output. The session IS still saved to disk.
* fix(loop): skip extra hooks for ephemeral sessions (Dream)
* feat(dream): per-run timestamped sessions with rotation for WebUI
* test(config): restore DreamConfig schedule and alias tests
* fix(dream): include LLM response summary in git auto-commit message
The old two-phase Dream class included the Phase 1 analysis in the git
commit message body. The new single-phase version lost this. Restore it
by extracting resp.content from the process_direct return value and
appending it to the commit message in both the cron handler and the
/dream command.
* fix(test): accept ephemeral kwarg in test_openai_api fake_process
* refactor(dream): merge dream_session.py into MemoryStore
The standalone dream_session.py module only contained three small helpers
that all revolve around MemoryStore concerns (session keys, commit messages,
file pruning). Fold them into MemoryStore as @staticmethod to reduce
indirection and avoid a 35-line module with no independent reason to exist.
* fix(test): address code review — patch correct instance, use actual function
- Fix test_ephemeral_skips_raw_archive to patch loop.context.memory
instead of the fixture's separate MemoryStore instance
- Fix TestDreamCommitMessage to call MemoryStore.build_dream_commit_message
instead of reimplementing the logic inline
- Move Dream helpers in memory.py above the Consolidator section comment
to avoid misleading visual boundary
* fix(dream): gate cursor advancement and restrict tools
maintainer edit: Dream now processes backlog from the oldest unprocessed entries, only advances the cursor after a completed ephemeral run, and uses a restricted file-only tool registry for background consolidation.
* fix(dream): skip idle compact for dream sessions
Dream runs use internal dream:* sessions that are pruned by Dream retention. Exclude them from AutoCompact scheduling, archive execution, and summary injection so idle-session compaction cannot truncate Dream transcripts.
* fix(dream): keep batched history isolated
* feat(dream): tag archived memory for single-phase Dream
---------
Co-authored-by: Xubin Ren <52506698+Re-bin@users.noreply.github.com>
- Remove ## Completed section from HEARTBEAT.md template; completed
tasks should be deleted, not accumulated
- Change in_active_section from tri-state (None/True/False) to bool
(True/False) so stray text before any ## heading no longer triggers
heartbeat
- Add test cases for stray pre-heading text and ## Notes section
- Update docs/chat-commands.md to reference ## Active Tasks
Remove standalone nanobot/heartbeat/ service and replace it with an
auto-registered system cron job on gateway startup. Key behaviors preserved:
- HeartbeatConfig (enabled, interval_s, keep_recent_messages) remains in
GatewayConfig for backward compatibility.
- On startup, if enabled, a system cron job "heartbeat" is registered with
schedule derived from interval_s.
- HEARTBEAT.md is checked on each tick; empty/template-identical files skip
to avoid wasting LLM calls.
- Post-run evaluate_response and session history truncation
(keep_recent_messages) are retained.
- Delivery target selection, deliverable filtering, and preamble guidance
are preserved.
Files removed:
- nanobot/heartbeat/__init__.py
- nanobot/heartbeat/service.py
- tests/heartbeat/*
- tests/agent/test_heartbeat_service.py
Templates and docs updated to reflect cron-based usage.
Introduce webhook mode for the Telegram channel and implement a session-based message reordering mechanism.
Key changes:
- Update `python-telegram-bot` dependency to include the `webhooks` extra.
- Add `TelegramConfig` fields for webhook configuration, with validation rules for public HTTPS URLs and Telegram's secret token.
- Implement `_enqueue_ordered_update` and `_drain_ordered_updates` in `TelegramChannel` to stage incoming messages and commands behind a short per-session reorder
window, ensuring sequential delivery based on message and update IDs.
- Configure `start_webhook` in `TelegramChannel.start()` when webhook mode is enabled.
- Add unit tests for webhook config validations, webhook startup, and message reordering.
- Document webhook configuration and reverse proxy details in `docs/chat-apps.md`.
Document how to use StepFun's Step Plan subscription endpoint with the
existing `stepfun` provider by overriding `apiBase`, following the same
pattern as the `zhipu` provider's coding plan documentation.
- **Base URL**: `https://api.stepfun.com/step_plan/v1` (dedicated endpoint)
- **API Key**: same `STEPFUN_API_KEY` as the regular `stepfun` provider
- **Models**: `step-3.5-flash`, `step-3.5-flash-2603`, `step-router-v1`
Changes:
- `docs/configuration.md` — provider tip, and config example showing
`apiBase` override on the existing `stepfun` provider
Test: 488/488 provider tests passed.
Replace standalone 'Token Plan' section with general Xiaomi MiMo
section using the built-in xiaomi_mimo provider. Token plan becomes
a note within the section, since it's just an apiBase override.
Key changes:
- Use xiaomi_mimo provider (auto-matches via 'mimo' keyword in model name)
- Drop redundant provider field (auto-detected)
- Add token plan tip to provider tips block
- Restructure as general Xiaomi MiMo section with token plan as note
Override _handle_message to publish directly to the bus for messages
that have already passed _check_inbound_policy. The denied DM pairing
path calls super()._handle_message() to issue pairing codes via the
base class. This avoids cross-policy leakage where e.g. group open
policy would cause is_allowed to incorrectly allow denied DM senders.
Also includes:
- SSE: strip one optional leading space after 'data:' per spec
- Convert 20+ f-string log calls to loguru lazy formatting
- Add end-to-end tests for DM/group routing through the full chain
- Add cross-policy test (dm allowlist + group open) for pairing
- Add Signal channel documentation to docs/chat-apps.md
Add APIFree as a built-in OpenAI-compatible provider. APIFree offers
agent-optimised models such as skywork-ai/skyclaw-v1 through an
OpenAI-compatible API at https://api.apifree.ai/agent/v1.
Changes:
- Register apifree provider in the provider registry
- Add config schema field
- Add documentation with configuration example
- Add provider tests, websocket channel tests, and webui tests
- Add provider icon in settings UI
Updates docs/image-generation.md and skills/image-generation/SKILL.md to
include MiniMax configuration examples, supported aspect ratios, and
troubleshooting references. Also updates the supported provider list to
include minimax alongside openrouter, aihubmix, and gemini.
Adds GeminiImageGenerationClient covering both Imagen 4 (:predict) and
Gemini Flash (:generateContent), wires the gemini ProviderConfig through
the SDK, API server, and gateway entry points, and updates the
image-generation docs and skill. Errors from the Gemini endpoints are
logged and surface with the HTTP status and parsed message instead of an
empty string.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The `docker run` example for `gateway` in `docs/deployment.md` had drifted from
the canonical configuration in `docker-compose.yml`:
- It omitted the security flags that `docker-compose.yml` already declares
(`cap_drop: ALL` + `cap_add: SYS_ADMIN` + unconfined apparmor/seccomp).
These are required whenever `tools.exec.sandbox: "bwrap"` is enabled, because
bwrap needs CAP_SYS_ADMIN for user namespaces; without them bwrap exits with
`clone3: Operation not permitted` and exec tools silently fail.
- It omitted `-p 8765:8765`, even though both the bundled `docker-compose.yml`
and `Dockerfile` (`EXPOSE 18790 8765`) already expose the WebSocket channel
/ WebUI port; users following the docs would get a reachable gateway health
endpoint but an unreachable WebUI.
This change keeps the two paths in sync so anyone reading deployment.md and
using `docker run` directly gets the same security posture and port surface
as the Compose path.
Also adds a short `!IMPORTANT` note documenting that `gateway.host` and
`channels.websocket.host` default to `127.0.0.1` (set in
`nanobot/config/schema.py:GatewayConfig`). Docker `-p` cannot forward to the
container's loopback interface, so the user must set both binds to `0.0.0.0`
in `config.json` for the published ports to actually be reachable. This is
the symptom reported as items 2 + 3 of #3873; items 1 + 4 of that issue are
already resolved on `main` (`Dockerfile` line 49 already exposes both ports,
and README.md lines 218-220 already reflect that the WebUI ships in the wheel).
Docs only, no code changes.
Signed-off-by: voidborne-d <258577966+voidborne-d@users.noreply.github.com>
- Note that any string field supports ${VAR_NAME} and resolved values are
never written back to disk.
- Document the failure mode for unset variables.
- Add MCP (stdio env + HTTP headers) and web-search examples.
- Add Docker, direnv, and secret-manager (1Password / pass / Bitwarden)
delivery patterns alongside the existing systemd example.
- Replace plaintext apiKey values in tools.web.search examples (Brave,
Tavily, Jina, Kagi, Olostep) with ${PROVIDER_API_KEY} placeholders so
the docs stop modelling the anti-pattern.
- Cross-link from the Security section.
Refs: HKUDS/nanobot#2172
Resolve fallbackModels as preset references or explicit inline provider configs so failover uses complete model settings without exposing fallback logic to the agent loop.
Co-authored-by: Cursor <cursoragent@cursor.com>