* feat(mcp): store oversized text results as artifacts
* feat(mcp): fix doc
* fix(mcp): preserve raw MCP payload in text artifacts
* fix(mcp): avoid leaking large text when artifact persistence fails
* chore(mcp): clarify inline text limit and cover artifact edge cases
* feat: add VK channel support
- Add VK channel implementation using vksdk
- Support text messages and media attachments
- Implement Long Poll API for real-time messaging
- Add group chat support with trigger prefixes
- Add user whitelist (allow_from) configuration
- Add VK channel documentation
Files:
- pkg/channels/vk/: VK channel implementation
- pkg/config/config.go: Add VKConfig structure
- pkg/channels/manager.go: Register VK channel
- pkg/gateway/gateway.go: Import VK channel package
- docs/channels/vk/: Usage documentation
* test: add unit tests for VK channel
- Test channel initialization with various configurations
- Test allow_from whitelist functionality
- Test group trigger configuration
- Test max message length (4000 chars)
- Test message splitting logic
- Test attachment processing
All tests passing ✓
* fix: resolve linting issues in VK channel
- Format VKConfig struct tags to comply with golines
- Remove unused mu sync.Mutex field
- Remove unused stripPrefix method
All tests passing ✓
* style: format VKConfig with golines
- Align struct tags to match project style
- Match formatting with other channel configs (Telegram, etc.)
- Fix golines linting error
* style: fix struct tag formatting in config.go
* docs: update VK channel docs to use secure token storage
* feat(vk): add voice capabilities support
- Implement VoiceCapabilities() method for VK channel
- Add audio_message attachment handling in processAttachments
- Add comprehensive tests for voice capabilities
- Support both ASR (speech-to-text) and TTS (text-to-speech)
* docs: add VK channel to documentation and update voice support
- Add VK channel to README.md and README.zh.md channel lists
- Update VK channel documentation with voice message support
- Document ASR and TTS capabilities for VK channel
- Add voice transcription configuration reference
* refactor(web): load channel configs without exposing secret values
- add a dedicated channel config API that returns sanitized config plus
configured secret metadata
- update channel config pages and forms to use secret presence for
placeholders, validation, reset, and save behavior
- refresh the channel settings layout and clean up related i18n copy
- add backend tests for the new channel config endpoint
* fix(config): restore missing strings import
* feat(provider): add Venice AI support and update related documentation
* revert(asr): restore asr files to previous commit
* feat(config): add Venice API base URL and local LM Studio configuration
* fix(config): update Venice API base URL to correct endpoint
- centralize gateway log level resolution and normalization
- propagate debug flags to spawned launcher and gateway processes
- add a log level selector to the logs page
- cover the new behavior with backend and config tests
Add token-based authentication for the Launcher's embedded Web Dashboard.
- Ephemeral token generated in-memory each run (or via PICOCLAW_LAUNCHER_TOKEN env var)
- HMAC-SHA256 session cookie (HttpOnly, SameSite=Lax, Secure when HTTPS)
- Bearer token support for API/script access
- Rate limiting on login (10 attempts/IP/min)
- Referrer-Policy: no-referrer on all responses
- POST-only logout with JSON content-type (CSRF-safe)
- System tray "Copy dashboard token" action
- Login page shows contextual help (console/tray/log file path)
- Path traversal protection via path.Clean
- X-Forwarded-Host/Port/Proto support for reverse proxy deployments
- Full i18n support (English, Chinese)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add multi-message sending via split marker
* Add marker and length split integration tests
Tests that SplitByMarker and SplitMessage work together correctly, and
that code block boundaries are preserved during marker splitting.
* Simplify message chunking logic in channel worker
Extract splitByLength helper function and remove goto-based control
flow.
The logic now flows more naturally - try marker splitting first, then
fall
back to length-based splitting.
* Update multi-message output instructions in agent context
* Add split_on_marker to config defaults
* Add split_on_marker config option
* Rename 'Multi-Message Sending' setting to 'Chatty Mode'
* Add SplitOnMarker config option
Allow PlaceholderConfig.Text to accept either a single string or an
array of strings, from which one is randomly selected at runtime.
This maintains backward compatibility with existing single-string configs
while enabling random placeholder selection.
Changes:
- Modify PlaceholderConfig.Text type from string to FlexibleStringSlice
- Add GetRandomText() helper method for random selection
- Update SendPlaceholder in all channels to use GetRandomText()
- Update config.example.json with array placeholder examples
- Update Matrix channel documentation
Virtual models generated from multi-key expansion are now marked and
filtered during config persistence. Virtual models display with a badge
in the UI and cannot be set as default.
- Add `crypto_database_path` and `crypto_passphrase` configuration
- Integrate cryptohelper for decrypting `m.room.encrypted` events
- Handle both plaintext and encrypted messages in `handleMessageEvent`
- Enable `goolm` build tag for libsignal crypto support
Fixes#1840.
Normalize missing security sections when attaching, loading, and saving
security config so existing config files without `.security.yml` can still
be updated safely. This fixes Pico channel setup for legacy/existing configs
and adds coverage for the missing security file path and unexported JSON
field behavior.
* feat: add ElevenLabs Scribe STT transcriber and Telegram SendVoice support
Add ElevenLabsTranscriber as an alternative speech-to-text provider using
the ElevenLabs Scribe API (scribe_v1). This enables voice message
transcription for users who already have an ElevenLabs API key, without
requiring a separate Groq account.
Changes:
- Add ElevenLabsTranscriber implementing the Transcriber interface
- Update DetectTranscriber to check providers.elevenlabs.api_key first,
falling back to Groq for backward compatibility
- Add ElevenLabs to ProvidersConfig
- Add "voice" media type for OGG files with "voice" in filename
- Add SendVoice support in Telegram channel for voice bubble messages
- Add comprehensive tests for ElevenLabs transcriber
Configuration:
"providers": {
"elevenlabs": {
"api_key": "sk_your_key_here"
}
}
Closes#1503 (partial)
* fix: move voice-bubble detection into Telegram channel to avoid regression in other channels
Address review feedback: keep inferMediaType returning "audio" for all
OGG files. Voice-bubble detection (SendVoice vs SendAudio) is now done
inside the Telegram channel based on filename, so other channels that
map "audio" explicitly are unaffected.
* fix: align VoiceConfig struct tags to pass golines formatter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(agent): use ModelName in loop test added by upstream
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
LLM
Prevent LLM from seeing its own credentials (API keys, tokens, secrets)
by filtering sensitive values from tool call results before sending to
the
model. Values are collected from .security.yml and replaced with
[FILTERED] using an efficient strings.Replacer (O(n+m)).
- Add FilterSensitiveData and FilterMinLength to ToolsConfig
- Implement SensitiveDataReplacer() with sync.Once caching in
SecurityConfig
- Use reflection to collect all sensitive values (Model API keys,
channel
tokens, web tool API keys, skills tokens)
- Apply filtering in agent loop at 4 tool result locations
- Add comprehensive tests covering all token types
- Move SecurityCopyFrom() before validateConfig() in PUT and PATCH handlers
- Make SecurityCopyFrom() call applySecurityConfig() to populate private fields
- Add tests for config save with security-only channel tokens
Without this fix, saving config via the web UI fails with 'channels.pico.token
is required' (and similar for Telegram/Discord) when tokens are stored in
.security.yml, because the validation ran before security credentials were
copied to the config struct.
Allow configuring provider-specific fields like reasoning_split for minimax via
the model config's extra_body map. These fields are merged into the request
body last, giving them precedence over default values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow configuring provider-specific fields like reasoning_split for minimax via
the model config's extra_body map. These fields are merged into the request
body last, giving them precedence over default values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>