Commit Graph

1294 Commits

Author SHA1 Message Date
Zhang Rui 23f48d7c4e refactor(aibot): remove downloadAndDecryptImage function to streamline image handling 2026-03-02 18:21:53 +08:00
nayihz 9be6fb1a7d Merge branch 'main' into feat_discord_proxy 2026-03-02 18:15:20 +08:00
shikihane 18b36af934 feat(agent): add resolveMediaRefs to convert media:// refs to base64 data URLs
Without this function, media:// refs stored by MediaStore are passed
directly to the LLM API, which rejects them as invalid URLs.

resolveMediaRefs() runs after BuildMessages() and before the LLM call,
converting each media:// ref to a data:image/...;base64,... URL that
vision-capable models can process.

Also adds mimeFromExtension() helper for MIME type inference from
file extensions when ContentType metadata is not available.
2026-03-02 18:08:32 +08:00
Zhang Rui edd339e056 fix(wecom): handle empty response by encrypting and returning a default response 2026-03-02 17:42:54 +08:00
Zhang Rui 619948f8ff fix(wecom): improve error message for response_url delivery failure 2026-03-02 17:42:54 +08:00
Zhang Rui d4824a00b6 refactor(config): remove WebhookHost and WebhookPort from WeComAIBotConfig 2026-03-02 17:42:54 +08:00
Zhang Rui 55c556a4c5 fix(wecom): update CanonicalID generation to use identity.BuildCanonicalID for consistency 2026-03-02 17:42:54 +08:00
Zhang Rui 79b7fb7792 fix(wecom): improve error handling in sendViaResponseURL and remove task on failure 2026-03-02 17:42:54 +08:00
Zhang Rui 79bc06c0ba refactor(wecom): simplify stream message structure by introducing WeComAIBotMsgItem and WeComAIBotMsgItemImage types 2026-03-02 17:42:54 +08:00
Zhang Rui 880c402ab7 refactor(wecom): streamline AES encryption/decryption and improve task management logic 2026-03-02 17:42:54 +08:00
Zhang Rui 8f3d611a4c refactor(wecom): replace generateSignature with computeSignature and update related tests 2026-03-02 17:42:54 +08:00
Zhang Rui 81f6787dd5 fix(docs): update WeCom AI Bot timeout duration in README and improve streamTask comments 2026-03-02 17:42:54 +08:00
ZHANG RUI e88b39f21e Update pkg/channels/wecom/aibot.go
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-02 17:42:54 +08:00
Zhang Rui a87e6b0551 feat(wecom-aibot): enhance stream task management with StreamClosedAt and improved cleanup logic 2026-03-02 17:42:54 +08:00
Zhang Rui 4e09c91dda feat(wecom-aibot): add context management for stream tasks to improve agent cancellation 2026-03-02 17:42:54 +08:00
ZHANG RUI 0b6d913dfc Update pkg/channels/wecom/aibot.go
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-02 17:42:54 +08:00
ZHANG RUI aa9ce6955b Update pkg/channels/wecom/aibot.go
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-02 17:42:54 +08:00
ZHANG RUI e33712deff Update pkg/channels/wecom/aibot.go
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-02 17:42:54 +08:00
Zhang Rui e894f8d39a feat(wecom-aibot): add reasoning_channel_id to configuration and enhance message handling limits 2026-03-02 17:42:54 +08:00
Zhang Rui c7d4012fc9 fix(wecom-aibot): correct variable name in JSON parsing in message callback handler 2026-03-02 17:42:42 +08:00
Zhang Rui 6caee427bb Add WeCom AIBot channel implementation and tests
- Introduced WeCom AIBot channel configuration in config.go with relevant fields.
- Implemented WeCom AIBot channel factory registration in init.go.
- Created unit tests for WeCom AIBot channel functionalities including initialization, start/stop behavior, webhook path handling, message encryption/decryption, and signature generation.
- Set default values for WeCom AIBot configuration in defaults.go.
2026-03-02 17:42:42 +08:00
shikihane a4e5c391bd fix(openai_compat): preserve reasoning_content in serializeMessages
The serializeMessages() function was not preserving the reasoning_content
field when serializing messages for vision API calls. This caused the
TestProviderChat_PreservesReasoningContentInHistory test to fail.

This fix ensures reasoning_content is included in both text-only messages
and vision messages with media attachments.

Co-authored-by: Zachary Guerrero <zack.grrr@gmail.com>
2026-03-02 17:38:08 +08:00
shikihane 6997edc82e feat(agent): wire Media through agent pipeline (cherry-pick PR #555)
Add Media field to processOptions, pass msg.Media from inbound
messages through to BuildMessages and serializeMessages so
vision-capable LLMs receive image_url content parts.

Based on work by @as3k in sipeed/picoclaw#555.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 17:18:04 +08:00
Zachary Guerrero 3d54a77c40 feat: add Media field to Message struct and implement serializeMessages for vision API support
- Add Media []string field to Message struct for image/media URLs
- Implement serializeMessages() to format messages with image_url content parts
- Enables OpenAI-compatible vision APIs to receive image attachments
2026-03-02 17:18:04 +08:00
daming大铭 26d1b8e374 Merge pull request #946 from winterfx/fix/preserve-reasoning-content-in-history
fix: preserve reasoning_content in multi-turn conversation history
2026-03-02 16:31:03 +08:00
Huang Rui d5370c9605 fix(tools): allow /dev/null redirection and add read/write sandbox split (#967)
* fix(tools): allow /dev/null redirection and add read/write sandbox split

- Remove deny pattern that incorrectly blocked redirects to /dev/null
- Expand block device write pattern to cover nvme, mmcblk, vd, xvd,
  hd, loop, dm-, md, sr and nbd in addition to sd
- Add safe path whitelist for kernel pseudo-devices so workspace path
  check does not reject /dev/null, /dev/zero, /dev/random, /dev/urandom,
  /dev/stdin, /dev/stdout and /dev/stderr
- Add allow_read_outside_workspace config option (default true) so file
  read and list tools are unrestricted while write tools stay sandboxed

Closes https://github.com/sipeed/picoclaw/issues/964
Closes https://github.com/sipeed/picoclaw/issues/965

Signed-off-by: Huang Rui <vowstar@gmail.com>

* feat(tools): add configurable allow patterns and path whitelists

- Add custom_allow_patterns to exec config so users can exempt specific
  commands from deny pattern checks
- Add allow_read_paths and allow_write_paths regex lists to tools config
  for whitelisting specific paths outside the workspace
- Introduce whitelistFs that wraps sandboxFs and falls through to hostFs
  for paths matching whitelist patterns
- Use variadic constructor signatures to keep backward compatibility

Suggested-by: lxowalle
Signed-off-by: Huang Rui <vowstar@gmail.com>

---------

Signed-off-by: Huang Rui <vowstar@gmail.com>
2026-03-02 12:22:02 +08:00
Mauro b26337501c fix: error check on state (#864) 2026-03-02 11:59:26 +11:00
afjcjsbx e0667304d1 fixed conflicts 2026-03-01 23:44:21 +01:00
Mauro b86bf5b7ea Merge branch 'main' into fix/max-payload-size-in-web-fetch 2026-03-01 22:38:16 +01:00
Dimitrij Denissenko b74f92ed28 A more neutral and elegant voice.Transcriber interface 2026-03-01 21:02:16 +00:00
Luca Martinetti fc9f1ec921 fix: return fetched content to LLM in web_fetch tool (#833)
* fix: return fetched content to LLM in web_fetch tool

WebFetchTool.Execute was setting ForLLM to a summary string
("Fetched N bytes from URL ...") instead of the actual extracted
text. This meant the LLM never saw the page content and could not
answer questions based on fetched web pages.

Return the extracted text in ForLLM so the model can use it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: put full JSON result in ForLLM, summary in ForUser

Accept suggestion from afjcjsbx: the LLM should receive the full JSON
result (including extracted text) while the user sees a short summary.
Update tests to match the new field assignment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 07:48:11 +11:00
Keith d4bc28c113 feat(config): Add support for env var configuration (#896)
* feat(config): Add support for env var configuration

This commit introduces support for two environment variables,
allowing users to override the default paths for picoclaw's home
directory and configuration file.

- `PICOCLAW_CONFIG`: Directly specifies the path to the `config.json` file.
This is initialised first, takes precedence over the hardcoded path, and is ideal
for containerized deployments or custom config management.

- `PICOCLAW_HOME`: Overrides the root directory for all picoclaw data, (except the config)
(e.g., `~/.picoclaw`). This is useful for portable installations or placing
data in non-standard locations.

This change provides greater flexibility for running picoclaw in various environments without
being tied to the default home directory structure.

* `README.md` updated explain PICOCLAW_CONFIG and PICOCLAW_HOME

* docs: translate environment variables section to multiple languages

---------

Co-authored-by: picoclaw <picoclaw@sipeed.com>
2026-03-02 07:41:12 +11:00
美電球 3926585786 Merge pull request #916 from alexhoshina/fix/channel-config-cleanup
docs: sync READMEs, examples, and channel docs to match current config
2026-03-01 22:28:55 +08:00
Hoshina cd3a4e1d1e docs: fix review feedback from PR #916
- Remove Feishu from webhook channel list in README.md and README.zh.md;
  add clarifying note that Feishu uses WebSocket/SDK mode instead
- Replace Chinese text in README.vi.md header with Vietnamese equivalent
- Translate mixed-language WeCom note in README.vi.md to full Vietnamese
- Mark webhook_path as optional (否) in docs/channels/line/README.zh.md
- Remove incorrect yaml struct tags from new-channel example in
  pkg/channels/README.md and README.zh.md (config uses json tags only)
- Fix multi-mode initChannel example to use whatsapp/whatsapp_native
  (matching the "WhatsApp Bridge vs Native" comment) instead of matrix
- Correct ReasoningChannelID description: list the 12 channels that
  have the field and note that PicoConfig does not expose it
2026-03-01 22:21:49 +08:00
Tong Niu d6e88da8ba fix(pkg):do regex precompile insteadd on the fly (#911)
* fix(pkg/providers):do regex precompile insteadd on the fly

* fix(providers): replace HTTP-specific regex with standalone status code matcher

The precompiled HTTP regex used uppercase "HTTP" which never matched
because ClassifyError lowercases the input. Replace it with a
case-insensitive word-boundary pattern that matches any standalone
3-digit status code (300-599), which also subsumes the HTTP/x.x case.

Add test case for standalone status code extraction.

* fix(providers): restore http regex and add standalone status code matcher

Restore the http-prefixed regex (without unnecessary (?i) flag since
input is already lowercased by ClassifyError) as a mid-priority pattern
to reduce false positives. Add a standalone word-boundary matcher as a
fallback for bare status codes like "429". Fix test to use lowercased
input matching the actual calling convention.

* perf(tools): move path regex compilation from per-call to package init

The path regex in guardCommand was compiled on every call. Hoist it
to a package-level var (absolutePathPattern) alongside defaultDenyPatterns
in a single var block, so it is compiled once at init time.

* style(tools): move inline comment to fix golines formatting error
2026-03-01 23:06:31 +11:00
GhostC 71bdeb41c9 fix: improve error handling in GitHub Copilot provider (#919)
- Fix ignored error from SendAndWait call
- Improve error message for unimplemented stdio mode with helpful guidance
- Add TODO comment with reference link for future stdio implementation
2026-03-01 22:58:41 +11:00
Dimitrij Denissenko b1386ad71f Fix voice transcription 2026-03-01 08:39:05 +00:00
winterfx 9efdde25ad fix: preserve reasoning_content in multi-turn conversation history
The openaiMessage struct and stripSystemParts() were not carrying over
the ReasoningContent field when serializing conversation history for
API requests. This caused thinking models (e.g. kimi-k2.5) to receive
incomplete assistant messages on subsequent turns, resulting in 400
errors from the Moonshot API.

Add the ReasoningContent field to openaiMessage and copy it in
stripSystemParts(). Also add a test to verify reasoning_content is
preserved when sending conversation history.

Fixes #588
Related: #876

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:23:05 +08:00
Meng Zhuo f7136b6a5d Merge pull request #861 from p3ddd/refactor/modernize
refactor(modernize): apply safe modernize fixes
2026-03-01 15:38:59 +08:00
Kai Xia 434b03ed67 remove wrapper methods
Signed-off-by: Kai Xia <kaix+github@fastmail.com>
2026-03-01 18:24:11 +11:00
Kai Xia 32c864c309 enable dupl check
Signed-off-by: Kai Xia <kaix+github@fastmail.com>
2026-03-01 18:17:32 +11:00
xiaoen 6d894d6138 refactor(memory): use fileutil.WriteFileAtomic and log corrupt lines
- Replace manual temp+rename in writeMeta and rewriteJSONL with the
  project's standard fileutil.WriteFileAtomic. This adds fsync before
  rename, which is important for flash storage on embedded devices
  where power loss can leave zero-length files after an unsynced rename.
- Log a warning when readMessages skips a corrupt line, so operators
  can see that data was lost after a crash instead of silently dropping it.
- Document the lossy sanitizeKey mapping (telegram:123 → telegram_123)
  as an intentional tradeoff.
2026-03-01 14:46:54 +08:00
xiaoen cd500d2046 Merge branch 'main' into feat/jsonl-memory-store 2026-03-01 14:35:14 +08:00
Tong Niu 44a52c0cf6 fix(tools): close resp.Body on retry cancel and cache http.Client instances (#940)
* fix(tools): close resp.Body on retry cancel and cache http.Client instances

Fix resp.Body leak in DoRequestWithRetry where req.Body (request) was
incorrectly closed instead of resp.Body (response) on context cancel.
Cache http.Client on web search/fetch provider structs and channel
adapters (WeCom, LINE) to avoid per-call allocation overhead.

* fix(channels): preserve original http client timeouts for LINE and WeCom

Split LINE single 60s client into infoClient (10s) for bot info lookups
and apiClient (30s) for messaging API calls. Lower WeCom cached client
base timeout from 60s to 30s (matching uploadMedia), and ensure it is
always >= the configured ReplyTimeout so the per-request context
deadline remains the effective limit.

* refactor(tools): extract timeout consts and deduplicate WebFetchTool constructors

Address PR review feedback from xiaket:
- Define searchTimeout, perplexityTimeout, fetchTimeout, defaultMaxChars,
  and maxRedirects as package-level consts instead of magic numbers.
- Remove misleading "No proxy" comment in NewWebFetchTool.
- Deduplicate NewWebFetchTool by delegating to NewWebFetchToolWithProxy.

* test(utils): add context cancellation test for DoRequestWithRetry

Verify that resp.Body is properly closed when the context is canceled
during retry sleep, covering the C8 resp.Body leak fix.

* fix(utils): close resp in test to satisfy bodyclose linter

* fix(utils): eliminate flakiness in context cancellation retry test

Synchronize cancellation using an onRoundTrip callback from the
transport wrapper instead of a timing-based context timeout. This
ensures the first client.Do completes before cancel fires, so
cancellation always hits during sleepWithCtx.
2026-03-01 16:55:46 +11:00
DM cadcdc0b41 fix(skills): use registry-backed search for skills discovery (#929)
* fix(skills): use registry-backed search for skills discovery

Signed-off-by: dwizzle204 <25712917+dwizzle204@users.noreply.github.com>

* fix(skills): address review comments for registry search

Signed-off-by: dwizzle204 <25712917+dwizzle204@users.noreply.github.com>

---------

Signed-off-by: dwizzle204 <25712917+dwizzle204@users.noreply.github.com>
Co-authored-by: dwizzle204 <25712917+dwizzle204@users.noreply.github.com>
2026-03-01 15:20:20 +11:00
yuchou87 a2591e03a9 fix: improve MCP tool name collision safety and registry overwrite warning
- MCPTool.Name(): append FNV-32a hash of original (unsanitized) server+tool
  names whenever sanitization is lossy or total length exceeds 64 chars,
  ensuring names that differ only in disallowed characters remain distinct
- ToolRegistry.Register(): emit warn log when a tool registration overwrites
  an existing tool with the same name, making collisions observable
- scripts/test-docker-mcp.sh: switch shebang from #/bin/bash /Users/yuchou/Work/klook-calendar/klook-google-cal-sync/src/googlecalconversrv/bin/start.sh to #  for portability on minimal distros and Nix environments
2026-03-01 12:00:26 +08:00
daming大铭 33f67e8275 Merge pull request #918 from alexhoshina/fix/wecom-resource-leaks
fix(wecom): fix context leak in Start() and data race in processedMsgs
2026-03-01 10:57:07 +08:00
yuchou87 ef738f4787 fix: address PR review feedback for MCP tools support
- Avoid logging sensitive cfg.Args in ConnectServer; log args_count instead
- Sanitize server/tool name components in MCPTool.Name() to ensure valid
  identifiers for downstream providers (lowercase, [a-z0-9_-] only)
- Add slack as 5th MCP server example in config.example.json
- Move Dockerfile.full and docker-compose.full.yml into docker/ directory
  for consistency with existing docker/Dockerfile and docker/docker-compose.yml
- Fix all Makefile docker-* targets to reference correct compose file paths
- Fix docker/docker-compose.full.yml build context (.. ) and volume paths
- Fix scripts/test-docker-mcp.sh compose file path and replace cowsay test
  with actual @modelcontextprotocol/server-filesystem MCP server test
2026-03-01 10:56:02 +08:00
I Putu Eddy Irawan 2dccee5044 Address Copilot review feedback for Telegram message chunking
- Add early return for empty content to avoid silent no-op
- Split raw markdown before HTML conversion so SplitMessage's
  code-fence-aware logic works correctly and HTML tags/entities
  are never broken by mid-tag splitting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 09:40:09 +07:00
I Putu Eddy Irawan 9c91d66427 Address Copilot review feedback for Kimi/Opencode providers
- Allow APIBase-only config for opencode provider selection (like VLLM)
- Keep moonshot provider on moonshot.cn/v1 default, only use kimi.com/coding/v1 for kimi/kimi-code
- Use url.Parse hostname match for Kimi User-Agent check instead of strings.Contains
- Add opencode to DefaultAPIBase test cases in factory_provider_test.go
- Add opencode migration tests (full config + APIBase-only) in migration_test.go
- Update AllProviders test count to include opencode (18 -> 19)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 09:22:49 +07:00