Commit Graph
35 Commits
Author SHA1 Message Date
chengyongruandXubin Ren b51da93cbb feat(agent): add SelfTool for runtime self-inspection and configuration
Add a built-in tool that lets the agent inspect and modify its own
runtime state (model, iterations, context window, etc.).

Key features:
- inspect: view current config, usage stats, and subagent status
- modify: adjust parameters at runtime (protected by type/range validation)
- Subagent observability: inspect running subagent tasks (phase,
  iteration, tool events, errors) — subagents are no longer a black box
- Watchdog corrects out-of-bounds values on each iteration
- Enabled by default in read-only mode (self_modify: false)
- All changes are in-memory only; restart restores defaults
- Comprehensive test suite (90 tests)

Includes a self-awareness skill (always-on) with progressive disclosure:
SKILL.md for core rules, references/examples.md for detailed scenarios.
2026-04-16 23:44:26 +08:00
chengyongruandXubin Ren 63753dbfea fix(msteams): remove optional deps from dev extras and gate tests
PyJWT and cryptography are optional msteams deps; they should not be
bundled into the generic dev install.  Tests now skip the entire file
when the deps are missing, following the dingtalk pattern.
2026-04-16 13:22:07 +08:00
chengyongruandXubin Ren a1e1eed2f1 refactor(runner): consolidate all injection drain paths and deduplicate tests
- Migrate "after tools" inline drain to use _try_drain_injections,
  completing the refactoring (all 6 drain sites now use the helper).
- Move checkpoint emission into _try_drain_injections via optional
  iteration parameter, eliminating the leaky split between helper
  and caller for the final-response path.
- Extract _make_injection_callback() test helper to replace 7
  identical inject_cb function bodies.
- Add test_injection_cycle_cap_on_error_path to verify the cycle
  cap is enforced on error exit paths.
2026-04-14 00:30:30 +08:00
chengyongruandXubin Ren d849a3fa06 fix(agent): drain injection queue on error/edge-case exit paths
When the agent runner exits due to LLM error, tool error, empty response,
or max_iterations, it breaks out of the iteration loop without draining
the pending injection queue. This causes leftover messages to be
re-published as independent inbound messages, resulting in duplicate or
confusing replies to the user.

Extract the injection drain logic into a `_try_drain_injections` helper
and call it before each break in the error/edge-case paths. If injections
are found, continue the loop instead of breaking. For max_iterations
(where the loop is exhausted), drain injections to prevent re-publish
without continuing.
2026-04-14 00:30:30 +08:00
2a243bfe4f feat(agent): integrate skill discovery into Dream consolidation
Instead of a separate skill discovery system, extend Dream's two-phase
pipeline to also detect reusable behavioral patterns from conversation
history and generate SKILL.md files.

Phase 1 gains a [SKILL] output type for pattern detection.
Phase 2 gains write_file (scoped to skills/) and read access to builtin
skills, enabling it to check for duplicates and follow skill-creator's
format conventions before creating new skills.

Inspired by PR #3039 by @wanghesong2019.

Co-authored-by: wanghesong2019 <wanghesong2019@users.noreply.github.com>
2026-04-12 16:49:55 +08:00
chengyongruandXubin Ren 9f433cab01 fix(wecom): use reply_stream for progress messages to avoid errcode=40008
The plain reply() uses cmd="reply" which does not support "text" msgtype
and causes WeCom API to return errcode=40008 (invalid message type).
Unify both progress and final text messages to use reply_stream()
(cmd="aibot_respond_msg"), differentiating via finish flag.

Fixes #2999
2026-04-11 21:47:19 +08:00
chengyongruandXubin Ren 401d1f57fa fix(dream): allow LLM to retry on tool errors instead of failing immediately
Dream Phase 2 uses fail_on_tool_error=True, which terminates the entire
run on the first tool error (e.g. old_text not found in edit_file).
Normal agent runs default to False so the LLM can self-correct and retry.
Dream should behave the same way.
2026-04-05 22:10:34 +08:00
chengyongruandXubin Ren 2cecaf0d5d fix(feishu): support video (media) download by converting type to 'file'
Feishu's GetMessageResource API only accepts 'image' or 'file' as the
type parameter. Video messages have msg_type='media', which was passed
through unchanged, causing error 234001 (Invalid request param). Now
both 'audio' and 'media' are converted to 'file' for download.
2026-04-05 16:53:05 +08:00
chengyongruandXubin Ren 3003cb8465 test(feishu): add unit tests for reaction add/remove and auto-cleanup 2026-04-05 16:53:05 +08:00
chengyongru 69624779dc fix(test): fix flaky test_fixed_session_requests_are_serialized
Remove the fragile barrier-based synchronization that could cause
deadlock when the second request is scheduled first. Instead, rely
on the session lock for serialization and handle either execution
order in assertions.
2026-03-31 21:50:33 +08:00
chengyongruandXubin Ren a6fb90291d feat(onboard): pass CLI args as initial config to interactive wizard
--workspace and --config now work as initial defaults in interactive mode:
- The wizard starts with these values pre-filled
- Users can view and modify them in the wizard
- Final saved config reflects user's choices

This makes the CLI args more useful for interactive sessions while
still allowing full customization through the wizard.
2026-03-20 18:46:13 +08:00
67528deb4c fix(tests): use --no-interactive for non-interactive onboard tests
Tests for non-interactive onboard mode now explicitly use --no-interactive
flag since the default changed to interactive mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 18:46:13 +08:00
chengyongruandXubin Ren 606e8fa450 feat(onboard): add field hints and Escape/Left navigation
- Add `_SELECT_FIELD_HINTS` for select fields with predefined choices
  (e.g., reasoning_effort: low/medium/high with hint text)
- Add `_select_with_back()` using prompt_toolkit for custom key bindings
- Support Escape and Left arrow keys to go back in menus
- Apply to field config, provider selection, and channel selection menus
2026-03-20 18:46:13 +08:00
chengyongruandXubin Ren 3369613727 feat(onboard): add model autocomplete and auto-fill context window
- Add model_info.py module with litellm-based model lookup
- Provide autocomplete suggestions for model names
- Auto-fill context_window_tokens when model changes (only at default)
- Add "Get recommended value" option for manual context lookup
- Dynamically load provider keywords from registry (no hardcoding)

Resolves #2018
2026-03-20 18:46:13 +08:00
chengyongruandXubin Ren f127af0481 feat: add interactive onboard wizard for LLM provider and channel configuration 2026-03-20 18:46:13 +08:00
chengyongruandXubin Ren 5a220959af docs: add branching strategy and CONTRIBUTING guide
- Add CONTRIBUTING.md with detailed contribution guidelines
- Add branching strategy section to README.md explaining main/nightly branches
- Include maintainer information and development setup instructions
2026-03-16 11:13:46 +08:00
chengyongruandXubin Ren a2acacd8f2 fix: add exception handling to prevent agent loop crash 2026-03-14 18:34:22 +08:00
chengyongruandXubin Ren 91d95f139e fix: cross-platform test compatibility
- test_channel_plugins: fix assertion logic for discoverable channels
- test_filesystem_tools: normalize path separators for Windows
- test_tool_validation: use python to generate output, avoid cmd line limits
2026-03-14 16:13:38 +08:00
chengyongru 64ab6309d5 fix: wecom-aibot-sdk-python should use pypi version 2026-03-12 00:38:28 +08:00
chengyongru 45c0eebae5 docs(wecom): add wecom configuration guide in readme 2026-03-10 00:53:23 +08:00
chengyongru a660a25504 feat(wecom): add wecom channel [wobsocket]
support text/audio[wecom support audio message by default]
2026-03-09 22:46:35 +08:00
chengyongru 4044b85d4b fix: ensure feishu audio file has .opus extension for Groq Whisper compatibility 2026-03-09 01:32:10 +08:00
chengyongruandSergio Sánchez Vallés 88d7642c1e test: fix test failures from refactored cron and context builder
- test_context_prompt_cache: Update test to reflect merged runtime
  context and user message (commit ad99d5a merged them into one)
- Remove test_cron_commands.py: cron add CLI command was removed
  in commit c05cb2e (unified scheduling via cron tool)
2026-03-04 17:13:25 +01:00
chengyongru bb8512ca84 test: fix test failures from refactored cron and context builder
- test_context_prompt_cache: Update test to reflect merged runtime
  context and user message (commit ad99d5a merged them into one)
- Remove test_cron_commands.py: cron add CLI command was removed
  in commit c05cb2e (unified scheduling via cron tool)
2026-03-04 20:49:02 +08:00
chengyongru 8f4baaa5ce feat(gateway): support multiple instances with --workspace and --config options
- Add --workspace/-w flag to specify workspace directory
- Add --config/-c flag to specify config file path
- Move cron store to workspace directory for per-instance isolation
- Enable running multiple nanobot instances simultaneously
2026-03-02 23:18:54 +08:00
chengyongru d447be5ca2 security: deny by default in is_allowed for all channels
When allow_from is not configured, block all access by default
instead of allowing everyone. This prevents unauthorized access
when channels are enabled without explicit allow lists.
2026-03-02 13:18:43 +08:00
chengyongruandClaude Opus 4.6 aed1ef5529 fix: add SIGTERM, SIGHUP handling and ignore SIGPIPE
- Add handler for SIGTERM to prevent "Terminated" message on Linux
- Add handler for SIGHUP for terminal closure handling
- Ignore SIGPIPE to prevent silent process termination
- Change os._exit(0) to sys.exit(0) for proper cleanup

Fixes issue #1365

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 11:04:53 +08:00
chengyongruandClaude Opus 4.6 ae788a17f8 chore: add .worktrees to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 11:03:54 +08:00
chengyongru 82be2ae1a5 feat(tool): add web search proxy 2026-03-01 16:51:54 +08:00
chengyongru fafd8d4eb8 fix(agent): only suppress final reply when message tool sends to same target
A refactoring in commit 132807a introduced a regression where the final
response was silently discarded whenever the message tool was used,
regardless of the target. This restored the original logic from PR #832
that only suppresses the final reply when the message tool sends to the
same (channel, chat_id) as the original message.

Changes:
- message.py: Replace _sent_in_turn: bool with _turn_sends: list[tuple]
  to track actual send targets, add get_turn_sends() method
- loop.py: Check if (msg.channel, msg.chat_id) is in sent_targets before
  suppressing final reply. Also move the "Response to" log after the
  suppress check to avoid misleading logs.
- Add unit tests for the suppress logic

This ensures:
- Email sent via message tool → Feishu still gets confirmation
- Message tool sends to same Feishu chat → No duplicate (suppressed)
2026-02-26 00:32:48 +08:00
chengyongru 91e13d91ac fix(email): allow proactive sends when autoReplyEnabled is false
Previously, `autoReplyEnabled=false` would block ALL email sends,
including proactive emails triggered from other channels (e.g., asking
nanobot on Feishu to send an email).

Now `autoReplyEnabled` only controls automatic replies to incoming
emails, not proactive sends. This allows users to disable auto-replies
while still being able to ask nanobot to send emails on demand.

Changes:
- Check if recipient is in `_last_subject_by_chat` to determine if
  it's a reply
- Only skip sending when it's a reply AND auto_reply_enabled is false
- Add test for proactive send with auto_reply_enabled=false
- Update existing test to verify reply behavior
2026-02-24 04:27:14 +08:00
chengyongru a3f4bb74ff fix: increase max_messages to 500 as temporary workaround
Temporarily increase default max_messages from 50 to 500 to allow
more context in conversations until a proper consolidation strategy
is implemented.
2026-02-13 22:10:53 +08:00
chengyongru afc8d50659 test: add comprehensive tests for consolidate offset functionality
Add 26 new test cases covering:
- Consolidation trigger conditions (exceed window, within keep count, no new messages)
- last_consolidated edge cases (exceeds message count, negative value, new messages after consolidation)
- archive_all mode (/new command behavior)
- Cache immutability (messages list never modified during consolidation)
- Slice logic (messages[last_consolidated:-keep_count])
- Empty and boundary sessions (empty, single message, exact keep count, very large)

Refactor tests with helper functions to reduce code duplication by 25%:
- create_session_with_messages() - creates session with specified message count
- assert_messages_content() - validates message content range
- get_old_messages() - encapsulates standard slice logic

All 35 tests passing.
2026-02-13 16:30:43 +08:00
chengyongru 98a762452a fix: useasyncio.create_task to avoid block 2026-02-13 15:36:04 +08:00
chengyongru 740294fd74 fix: history messages should not be change[kvcache] 2026-02-13 15:10:07 +08:00