* feat(model): add `picoclaw model add` for custom OpenAI-compatible endpoints
Onboards a model from a user-supplied API base + key by hitting
GET <base>/models, prompting the user to pick one, and writing the entry
into model_list[] (with api_keys) plus setting it as the default model.
This was previously only available in the TUI launcher (issue #2208) and
is now accessible from the CLI:
picoclaw model add -b URL -k KEY [-m MODEL] [-n ALIAS]
* chore: remove deprecated picoclaw-launcher-tui
Per RFC #2208, the TUI launcher is deprecated in favor of the CLI; its
"online model picker" feature has been ported to `picoclaw model add` in
the previous commit. This drops the binary and all build/release/docs
references:
- delete cmd/picoclaw-launcher-tui/ and assets/launcher-tui.jpg
- Makefile: remove the `build-launcher-tui` target
- .goreleaser.yaml: drop the build entry plus the `picoclaw-launcher-tui`
ids from the launcher docker image, macOS notarize list, and nfpms
contents
- docker/Dockerfile.goreleaser.launcher: drop the COPY for the TUI binary
- READMEs (root + 8 locales): remove the "TUI Launcher" section and
screenshot link
- docs/guides/docker.*: update the "launcher image includes …" sentence
to reflect the two remaining binaries
`make build` still succeeds; `go build ./web/backend` (the launcher
target) still succeeds. `picoclaw-launcher` (web console) is unaffected.
Change incorrect object format model.primary/fallbacks to correct
flat format model_name/model_fallbacks in Agent defaults example.
The AgentDefaults struct does not support the object format used
in AgentConfig, so the documentation example was misleading.
Replace leftover SubTurnOrphanResultEvent and short subturn event references with runtime event kinds in comments, tests, and hook design notes.
Validation: GOCACHE=/tmp/picoclaw-go-cache go test ./pkg/agent -run TestSpawnSubTurn_OrphanResultRouting; make lint
Emit gateway.start, gateway.ready, and gateway.shutdown on the shared runtime event bus, while keeping reload events on the same helper path.
Update subturn architecture docs to refer to runtime event kinds instead of the removed agent EventBus names.
Validation: GOCACHE=/tmp/picoclaw-go-cache go test ./pkg/gateway ./pkg/events; GOCACHE=/tmp/picoclaw-go-cache go test ./pkg/bus ./pkg/channels ./pkg/mcp ./pkg/tools/integration ./pkg/events ./pkg/gateway; make lint
Remove the legacy EventKind/Event envelope mapping and let agent event emission build pkg/events.Event values directly.
Keep HookMeta as the shared hook metadata shape and preserve legacy observe string aliases by mapping them to runtime event kinds.
Validation: GOCACHE=/tmp/picoclaw-go-cache go test ./pkg/agent; make lint
Mark the original hook design as an early record and update observer examples to pkg/events runtime events and hook.runtime_event.
Validation: make lint
Migrate hook observation to runtime events and update the process hook notification protocol. Add runtime event publication for message bus failures, channel lifecycle/outbound flow, gateway reloads, MCP server state, and MCP tool calls.
Validation: go test ./pkg/events/... ./pkg/bus ./pkg/agent ./pkg/channels ./pkg/mcp ./pkg/tools/integration ./pkg/gateway; make lint
* refactor: support explicit model list providers
* fix(web): preserve explicit model providers
* fix(web): preserve legacy provider prefixes on model updates
fix(models): normalize explicit provider-prefixed ids
fix(api): preserve legacy model updates across providers
fix(agent): preserve config identity for explicit provider refs
* fix ci
- stop exposing the raw Pico token to the frontend
- add /api/pico/info for non-secret Pico connection metadata
- proxy /pico/ws through the launcher with same-origin and dashboard auth checks
- inject the upstream Pico websocket protocol server-side
- update frontend chat connection flow and Vite websocket proxy path
- refresh related docs and tests
Introduce a lint-docs script and Makefile target for common
documentation naming and placement checks. Expand docs/README.md
with layout and translation conventions, and update CONTRIBUTING.md
to point contributors to the new docs guidance and validation step.
Add loop-split.md explaining the 12-file split of the original
4384-line loop.go, covering the file map, extraction method,
and future phase 2 plans.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix hiddenValues in manager_channel.go — use comma-ok type assertions to avoid panics │
Add GetDecoded() error handling in weixin.go saveWeixinConfig for consistency with wecom.go │
Fix stray quotes in docs/configuration.md JSON examples │
Add V2→V3 migration section to docs/config-versioning.md
Fix feishu init with 32bit wrong signature cause build fail
* feat(hooks): add respond action for tool execution bypass
Add a new HookActionRespond that allows hooks to return tool results directly, skipping actual tool execution. This enables plugin tool injection, caching, and mocking capabilities.
- Add HookActionRespond constant and support in HookManager
- Extend ToolCallHookRequest with HookResult field
- Implement respond action handling in process hooks and agent loop
- Add comprehensive tests for respond and deny_tool actions
- Update documentation with hook actions table and examples
* docs(hooks): add JSON-RPC protocol and plugin tool injection documentation
Add comprehensive documentation for hook JSON-RPC protocol and plugin tool injection capabilities:
- Add "Hook Actions" section to README.zh.md explaining respond action for tool execution bypass
- Create hook-json-protocol.md/.zh.md detailing JSON-RPC 2.0 protocol for all hook methods
- Create plugin-tool-injection.md/.zh.md with complete examples for external tool implementation
- Document how hooks can inject tool definitions and return results via respond action
- Include Python and Go examples for weather query plugin implementation
* feat(agent): emit tool events and feedback for hook results
Add ToolExecStart event emission and tool feedback for hook results to ensure consistent behavior between normal tool execution and hook bypass scenarios. This maintains parity in event tracking and user feedback when tools are executed via hooks.
* style(agent): format whitespace in hook structs and constants
Remove trailing whitespace and standardize spacing in JSON struct tags, constants, and test data for improved code consistency.
* feat(hooks): add media support for plugin tool injection
Extend the hook respond action to support media file handling:
- Add `media` field for returning images and files from hooks
- Add `response_handled` field to control turn completion behavior
- When response_handled=true, media is automatically delivered to user
- When response_handled=false, media is passed to LLM for vision requests
This enables plugins to directly return generated images, downloaded
files, and other media content either to users or for LLM analysis.
* docs(hooks): document security implications of respond action
Add security boundary documentation explaining that the respond action
bypasses ApproveTool checks, allowing hooks to return results for any
tool without approval. Include recommendations for secure hook
implementation and code comments marking the security considerations.
Changes:
- Add "Security Boundaries" section to plugin-tool-injection docs
- Document bypass of approval checks and associated risks
- Provide security recommendations and example code
- Add inline security comments in hooks.go and loop.go
* refactor(agent): improve completeness of tool result cloning and hook processing
Extend cloneToolResult to properly copy ArtifactTags and Messages fields,
ensuring deep copies of all ToolResult data. Consolidate event emission
and user message handling to match the normal tool execution flow.
* fix(agent): align hook respond path with normal tool execution flow
The hook respond code path was missing several critical behaviors that
existed in normal tool execution:
- Add logging for tool calls with arguments preview
- Add is_tool_call metadata to user-facing messages
- Handle attachment delivery failures by setting error state and
notifying LLM
- Set ResponseHandled=false when using bus for media delivery
- Check for steering messages and graceful interrupts after tool
execution, skipping remaining tools when appropriate
- Poll for SubTurn results that arrived during tool execution
This ensures consistent behavior between hook-responded tool calls and
normally executed tool calls.
* test(agent): add tests for hook respond media error handling
Add comprehensive tests for the hook respond code path when media
delivery fails. Tests cover error media channel scenarios and verify
proper error state handling.
Also document that AfterTool is not called when using respond action,
as it provides the final answer directly (design decision).
* 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
* 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