What: swap sessions_list for agents_list in /tools/invoke tests
Why: avoid nested gateway calls that can hang under CI; still validates tool invocation + allowlist
Tests: not run (CI should cover)
OAuth credentials with a refresh token auto-renew on first API call,
so the doctor should not warn about access token expiration when a
refresh token is present. This avoids unnecessary "expired" warnings
that prompt users to re-auth when no action is needed.
Fixes#3032
Co-authored-by: Ayush Ojha <ayushozha@outlook.com>
Unify style and link closing in render.ts to use LIFO order across
both element types, fixing cases where bold/italic spans containing
autolinks produced invalid HTML like <b><a></b></a>.
The react action used readStringParam for messageId and chatId, which
rejected numeric values with a misleading "messageId required" error.
Switched to readStringOrNumberParam to match the delete/edit actions.
Closes#1459
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes#4038
The global fetch in Node.js doesn't support undici's dispatcher option,
which is required for ProxyAgent to work. This fix imports fetch from
undici directly to enable proper proxy support for Telegram API calls.
Root cause: makeProxyFetch() was using global fetch with { dispatcher: agent },
but Node.js's global fetch ignores the dispatcher option. Using undici.fetch
ensures the ProxyAgent dispatcher is properly respected.
Tested: Build passes, TypeScript compilation successful.
registerTelegramNativeCommands() calls listSkillCommandsForAgents()
without passing agentIds, causing ALL agents' skill commands to be
registered on EVERY Telegram bot. When multiple agents share skill
names (e.g. two agents both have a "butler" skill), the shared `used`
Set in listSkillCommandsForAgents causes de-duplication suffixes
(_2, _3) and all commands appear on every bot regardless of agent
binding.
This fix uses the existing resolveAgentRoute() (already imported) to
find the bound agent for the current Telegram accountId, then passes
that agentId to listSkillCommandsForAgents(). The function already
accepts an optional agentIds parameter — it just wasn't wired from
the Telegram registration path.
Before: All agents' skill commands registered on every Telegram bot,
causing /butler_2, /housekeeper_2 dedup suffixes and potential
BOT_COMMANDS_TOO_MUCH errors when total exceeds 100.
After: Each Telegram bot only registers skill commands for its own
bound agent. No cross-agent dedup, no command limit overflow.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add Kimi K2.5 model to synthetic catalog
Add hf:moonshotai/Kimi-K2.5 to the synthetic model catalog.
This model is available via dev.synthetic.new API.
- 256k context window
- 8192 max tokens
- Supports reasoning
* chore: fix formatting in onboard-helpers.ts
* fix: update config candidate ordering test (#4407) (thanks @manikv12)
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Replaces the previous ASCII art in both the CLI banner and the wizard header with a new, wider design and updates the label to 'OPENCLAW' for consistency.
What:
- resolve shell from PATH in bash-tools tests (avoid /bin/bash dependency)
- mock DNS for web-fetch SSRF tests (no real network)
- stub a2ui bundle in canvas-host server test when missing
Why:
- keep gateway test suite deterministic on Nix/Garnix Linux
Tests:
- not run locally (known missing deps in unit test run)
What:
- stub resolvePinnedHostname in web-fetch tests to avoid DNS flake
- close lock file handles via FileHandle.close during cleanup to avoid EBADF
Why:
- make CI deterministic without network/DNS dependence
- prevent double-close errors from GC
Tests:
- pnpm vitest run --config vitest.unit.config.ts src/agents/tools/web-tools.fetch.test.ts src/agents/session-write-lock.test.ts (failed: missing @aws-sdk/client-bedrock)
NTFS does not allow < or > in filenames, causing the XML filename
escaping test to fail on Windows CI with ENOENT.
Replace file<test>.txt with file&test.txt — & is valid on all platforms
and still requires XML escaping (&), preserving the test's intent.
Fixes#3748
Previous fix only checked skippedEmpty > 0, but when model returns
content: [] no payloads are created at all. Now also checks
replies.length === 0 to catch this case.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When running multiple Telegram bot accounts bound to different agents,
the /new command (and other slash commands) would send confirmation
messages via the wrong bot because the context was missing AccountId.
The fix adds AccountId: route.accountId to the context payload in
registerTelegramNativeCommands, matching how bot-message-context.ts
handles regular messages.
Fixes#2537
- Add msg.video_note to media extraction chain in bot/delivery.ts
- Add placeholder detection for video notes in bot-message-context.ts
- Video notes (rounded square video messages) are now processed and downloaded like regular videos
Fixes issue where video note messages were silently dropped because they weren't in the media handling logic.
Native slash commands (e.g. /verbose, /status) should not emit tool
summaries. Gate onToolResult behind CommandSource !== 'native' in
addition to the existing ChatType !== 'group' check.
Add test for native command exclusion.
- provides onToolResult in DM sessions (ChatType=direct)
- does not provide onToolResult in group sessions (ChatType=group)
- sends tool results via dispatcher in DM sessions
Replaces the old cross-provider test that expected onToolResult to
always be undefined.
875b018ea removed onToolResult from dispatch-from-config.ts to prevent
tool summaries leaking into group channels. However, this also broke
verbose tool summaries in DM/private sessions where they are expected.
This restores onToolResult but gates it behind ChatType !== 'group',
so group channels remain unaffected while DM verbose works again.
mirror=false is passed to sendPayloadAsync to avoid duplicating tool
summaries in the session transcript (matching the block reply behavior).
Fixes#2665
Add a `paths` option to `memorySearch` config, allowing users to
explicitly specify additional directories or files to include in
memory search.
Follow-up to #2961 as suggested by @gumadeiras — instead of auto-following
symlinks (which has security implications), users can now explicitly
declare additional search paths.
- Add `memorySearch.paths` config option (array of strings)
- Paths can be absolute or relative (resolved from workspace)
- Directories are recursively scanned for `.md` files
- Single `.md` files can also be specified
- Paths from defaults and agent overrides are merged
- Added 4 test cases for listMemoryFiles
* fix: Prevent XML attribute injection by escaping special characters in file name and MIME type attributes.
* fix: text attachment MIME misclassification with security hardening (#3628)
- Fix CSV/TSV inference from content heuristics
- Add UTF-16 detection and BOM handling
- Add XML attribute escaping for file output (security)
- Add MIME override logging for auditability
- Add comprehensive test coverage for edge cases
Thanks @frankekn
The pairing CLI calls listPairingChannels() at registration time,
which requires the plugin registry to be populated. Without this,
plugin-provided channels like Matrix fail with "does not support
pairing" even though they have pairing adapters defined.
This mirrors the existing pattern used by the plugins CLI entry.
Co-authored-by: Shakker <165377636+shakkernerd@users.noreply.github.com>
Add mappings for audio/x-m4a, audio/mp4, and video/quicktime to ensure
media files sent as documents are saved with proper extensions, enabling
automatic transcription/analysis tools to work correctly.
- audio/x-m4a → .m4a
- audio/mp4 → .m4a
- video/quicktime → .mov
Also adds comprehensive test coverage for extensionForMime().