* feat(skills): enhance skill installation to support multiple top-level folders and add duplicate handling
closes: #6949
* refactor(skill_manager): streamline skill name normalization and validation logic
* fix(skill_manager): update skill name regex to allow underscores in skill names
* fix(skill_manager): improve skill name normalization and validation logic
* fix(provider): add missing index field to streaming tool_call deltas
- Fix#6661: Streaming tool_call arguments lost when OpenAI-compatible proxy omits index field
- Gemini and some proxies (e.g. Continue) don't include index field in tool_call deltas
- Add default index=0 when missing to prevent ChatCompletionStreamState.handle_chunk() from rejecting chunks
Fixes#6661
* fix(provider): use enumerate for multi-tool-call index assignment
- Use enumerate() to assign correct index based on list position
- Iterate over all choices (not just the first) for completeness
- Addresses review feedback from sourcery-ai and gemini-code-assist
---------
Co-authored-by: Yaohua-Leo <3067173925@qq.com>
Co-authored-by: Soulter <905617992@qq.com>
Remove msg_id from payload to prevent errors with proactive tool-call path and avoid permission issues.
Co-authored-by: Naer <88199249+V-YOP@users.noreply.github.com>
* fix: auto-append /v1 to embedding_api_base in OpenAI embedding provider (#6855)
When users configure `embedding_api_base` without the `/v1` suffix,
the OpenAI SDK does not auto-complete it, causing request path errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: ensure API base URL for OpenAI embedding ends with /v1 or /v4
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Soulter <905617992@qq.com>
Add the radiobox icons used indirectly by Vuetify internals
to the required MDI subset so they are kept during font
generation.
Regenerate the subset CSS and font files to prevent missing
radio button icons at runtime.
* fix: wrong index in ObjectEditor updateKey causing false 'key exists' error
* fix: same index mismatch issue in updateJSON
* fix(ui): stabilize ObjectEditor pair keys
Use generated ids for key-value pairs instead of array indexes to
prevent mismatch issues during editing and rendering.
Also replace duplicate-key alerts with toast warnings for a more
consistent UI experience.
---------
Co-authored-by: RC-CHN <1051989940@qq.com>
* fix(t2i): sync active template across all configs
apply template activation and reset to every config profile instead of only
the default one, and reload each pipeline scheduler so changes take effect
consistently in multi-config setups
add a dashboard test that creates extra configs and verifies active template
updates and scheduler reload coverage across all config ids
* fix(t2i): reload all schedulers on template changes
extract a shared helper to reload pipeline schedulers for every config.
when syncing or resetting the active template, persist each config and
then reload all schedulers to keep mappings consistent.
also reload all schedulers when updating the currently active template,
and add dashboard tests to verify cross-config sync and scheduler
replacement behavior.
* feat(dashboard): add log and cache cleanup in settings
* refactor: simplify storage cleaner log config handling
* fix: Repair abnormal indentation
* fix(storage): harden cleanup config handling
Use typed config value access to avoid treating invalid values as
enabled flags or log paths during storage cleanup.
Also stop exposing raw backend exceptions in the dashboard storage
status API and direct users to server logs for details.
---------
Co-authored-by: RC-CHN <1051989940@qq.com>
* refactor(persona): replace local folder components with shared folder components
* feat(webui): implement draggable reordering with animation for pinned plugins
* refactor(webui): extract PinnedPluginItem into a standalone component
* feat: supports weixin personal account
* feat(weixin): update documentation for personal WeChat integration and add QR code image
* feat(weixin): refactor send method to streamline message handling
* fix(weixin): correct AES key encoding in media payload construction
* feat(weixin): update weixin_oc_base_url description for clarity in config metadata
* feat(weixin): enhance WeChat integration with QR code support and configuration updates
* feat(weixin): implement WeixinOCClient for improved media handling and API requests
* feat(platform): update platform status refresh interval to 5 seconds
* fix(lark): defer streaming card creation and renew card on tool call break
- Defer CardKit streaming card creation until the first text token
arrives, preventing an empty card from rendering before content.
- Handle `type="break"` signal in send_streaming: close the current
card and lazily create a new one for post-tool-call text, so the
new card appears below the tool status message in correct order.
- Only emit "break" signal when show_tool_use is enabled; when tool
output is hidden, the AI response continues on the same card.
* style: format ruff
* fix: cr bug
* fix: cr
* fix(skills): use actual sandbox path from cache instead of hardcoded workspace root
Fixes#6273
When using Shipyard booter, the sandbox workspace directory is
`/home/ship_{session_id}/workspace/` instead of the hardcoded `/workspace`.
This caused Agent to fail reading SKILL.md files with 'No such file or directory'.
Changes:
- In build_skills_prompt: prefer skill.path (from sandbox cache) over
hardcoded SANDBOX_WORKSPACE_ROOT for sandbox_only skills
- In list_skills: always prefer sandbox_cached_paths over hardcoded path
for sandbox_only skills
The actual path is resolved at sandbox scan time via Path.resolve() in
_build_scan_command, which returns the correct absolute path based on
the sandbox's actual working directory.
* docs: add comment explaining show_sandbox_path behavior for sandbox_only skills
Address Sourcery AI review comment:
- Clarify that show_sandbox_path is implicitly True for sandbox_only skills
- Explain why the flag is effectively ignored (no local path exists)
* refactor: simplify path_str fallback using or operator
Address review feedback: use single-line fallback instead of if-not pattern.
* style: format skill_manager.py with ruff
Fix ruff format-check failure
* fix(skills): sanitize cached sandbox skill paths
Normalize sandbox cache paths before reading or writing them so invalid,
empty, or mismatched entries fall back to a safe default SKILL.md path.
This avoids using malformed cached paths, keeps path rendering
consistent, and ensures sandbox skill listings always point to the
expected workspace location.
---------
Co-authored-by: ccsang <ccsang@users.noreply.github.com>
Co-authored-by: RC-CHN <1051989940@qq.com>
* fix(agent): pass tool_call_timeout to SubAgent handoff execution
- Add tool_call_timeout parameter to _execute_handoff method
- Pass run_context.tool_call_timeout to ctx.tool_loop_agent
- Add unit test to verify tool_call_timeout is correctly passed
- Fixes#6711: SubAgent MCP tool call timeout now respects configured timeout
The SubAgent handoff execution was using the default 60-second timeout
instead of the configured tool_call_timeout from provider settings.
This change ensures that SubAgent MCP tool calls respect the user's
configured timeout settings.
* test: add unit test for tool_call_timeout in SubAgent handoff
* fix: restore deleted test and fix test assertion
- Restore test_collect_handoff_image_urls_filters_extensionless_missing_event_file
- Fix test_collect_handoff_image_urls_keeps_extensionless_existing_event_file assertion
- Keep new test_execute_handoff_passes_tool_call_timeout_to_tool_loop_agent
* refactor: simplify tool_call_timeout passing in _execute_handoff
- Pass run_context.tool_call_timeout directly to ctx.tool_loop_agent
- Remove unnecessary local variable assignment
- Addresses review feedback from Sourcery AI
* fix(config): increase default tool call timeout from 60 to 120 seconds
---------
Co-authored-by: LehaoLin <linlehao@cuhk.edu.cn>
Co-authored-by: Soulter <905617992@qq.com>