Add unified tool lookup method that searches both plugin and MCP loaders.
Also add _get_tool method to MCPLoader for consistency with PluginToolLoader.
- Add invoke_rerank action handler in plugin handler
- Validate rerank model access via run session
- Cap documents at 64 for API limit
- Return sorted results by relevance score
- Add DEPRECATED docstring to all legacy runners in pkg/provider/runners/
- Mark migration target for each runner (local-agent, dify, n8n, coze, dashscope, langflow, tbox)
- Add PROGRESS.md to track agent-runner-pluginization implementation status
- Remove completed PHASE0_INTEGRATION_RECORD.md
- Add pre-computed _authorized_ids (frozenset) at session registration for O(1) lookup
- Refactor is_resource_allowed() from linear search to set membership check
- Add thread-safe locking to get_session_registry() singleton
- Cache _session_registry and _state_store references in orchestrator __init__
- Add asyncio.gather() for parallel resource building in AgentResourceBuilder
- Create shared test fixtures in tests/unit_tests/agent/conftest.py
- Update test files to import from shared conftest.py
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 0 integration complete - verified minimal loop with local-agent stub runner.
Changes:
- Add AgentRunOrchestrator for plugin-based agent execution
- Add AgentResultNormalizer for Protocol v1 result conversion
- Add AgentRunnerDescriptor for runner ID parsing (plugin:author/name/runner)
- Update chat handler to use new orchestrator instead of direct runner lookup
- Add plugin handler methods for list_agent_runners and run_agent
- Add connector methods for AgentRunner protocol forwarding
- Update pipeline API to include runner options in metadata
- Add integration docs and implementation plan
Integration verified:
- Runner: plugin:langbot/local-agent/default
- Input: "你好"
- Output: [stub] Echo: 你好
- Date: 2026-05-10 10:09
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add one-click app creation for Feishu with QR code support
* feat: implement WeChat QR code login functionality and update related configurations
* feat: add qrcode dependency for QR code generation support
* feat: enhance QR code login UI and add internationalization support for new labels
* feat: new ui back
* feat: add DingTalk one-click app creation and QR code login support
* feat: add WeComBot one-click creation support and enhance QR code login functionality
* feat: Update the robot creation function and bind the most recently updated pipeline
Add business-agnostic validation for knowledge base creation:
- Backend: dynamically validate required fields from plugin's creation_schema
and retrieval_schema, with support for show_if conditional fields
- Frontend: expose validation function from DynamicFormComponent and
validate before KBForm submission
- Add i18n translations for validation error messages
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* add conversation expire config
* add user query text to card
* fix(pipeline): move session limit to AI config
* test(pipeline): cover AI session limit config
* refactor(pipeline): merge session expire-time into AI runner stage
Move the session validity duration field out of the standalone
session-limit stage into the runner stage so it actually renders in the
AI tab (the tab only shows the runner stage and the stage matching the
selected runner — any other stage is filtered out). Read path, default
config, metadata description, and tests updated accordingly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(pipeline): expire conversations from last update time
* fix(n8n): sync generated conversation id into payload
---------
Co-authored-by: RockChinQ <rockchinq@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
File messages from platforms like Telegram carry base64 data with an
empty url. The unconditional from_file_url(me.url) call passed an empty
string downstream, causing httpx to fail with "Request URL is missing
an 'http://' or 'https://' protocol" when uploading to Dify.
Mirror the existing Voice handling pattern: check base64 first, fall
back to url. Applied in both the main message chain and the Quote path.
Closes#2079
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add _safe_resolve() helper that uses os.path.realpath() to canonicalize
the joined path and verifies it stays within LOCAL_STORAGE_PATH.
All six public methods (save, load, exists, delete, size,
delete_dir_recursive) now validate the key before performing any I/O.
This prevents absolute-path injection (e.g. key="/etc/passwd") and
relative traversal (e.g. key="../../etc/passwd") from escaping the
storage root directory.
CWE-22
* feat: add web_page_bot adapter and embed widget
- Implemented a new `web_page_bot` adapter for embedding chat widgets on websites.
- Created a new YAML configuration file for `web_page_bot` with necessary metadata and execution details.
- Developed the `WebPageBotAdapter` class to handle message events and manage listeners.
- Added a JavaScript widget for embedding the chat interface, including styles and functionality for user interaction.
- Updated WebSocket handling to support the new bot adapter and manage connections.
- Enhanced the bot form to include pipeline UUID and adapter configuration in the system context.
- Introduced a new dynamic form item type for embed code in the form entity.
* feat(embed): add feedback submission and image upload functionality to embed widget
* feat(embed): add reset session endpoint for embed widget and improve WebSocket image handling
* feat(widget): remove typing indicator display logic from message handling
* fix(embed): security hardening for embed widget
- Add UUID format validation for pipeline_uuid parameters
- Add Cloudflare Turnstile integration for bot protection (optional)
- Add HMAC-signed session tokens for /messages, /reset, /feedback endpoints
- Sanitize error responses (remove internal exception details)
- Sanitize base_url before JS injection
- Fix XSS in markdown link rendering (only allow http/https protocols)
- Fix XSS in image URL extraction (only allow http/https/data protocols)
- Escape widget title in embed code snippet (HTML entity encoding)
- Remove class-level mutable default in WebPageBotAdapter
- Remove duplicate config line and console.log in widget.js
- Add turnstile_site_key and turnstile_secret_key config fields
* style: fix prettier formatting for chained replace calls
* fix(embed): declare listeners as Pydantic field in WebPageBotAdapter
The base class is a Pydantic BaseModel, so listeners must be declared
as a field (with default_factory) rather than assigned in __init__.
Also keep the __init__ to convert positional args to keyword args for
Pydantic compatibility with botmgr's calling convention.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(embed): use bot_uuid instead of pipeline_uuid in all embed URLs
Replace pipeline_uuid with bot_uuid in all user-facing embed widget
URLs so internal pipeline identifiers are never exposed. The server
resolves bot_uuid to the owning web_page_bot, validates it is enabled
and has a pipeline bound, then routes internally using pipeline_uuid.
Add a dedicated WebSocket endpoint at /api/v1/embed/<bot_uuid>/ws/connect
instead of reusing the pipeline debug path. Wire WebPageBotAdapter to
proxy reply_message calls through the WebSocket adapter so dashboard
shows the correct adapter name while replies are still delivered.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(embed): improve Turnstile config field descriptions
Add guidance on where to obtain the keys (Cloudflare dashboard) and
clarify that leaving them empty disables the feature.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(embed): add multi-language support for embed widget
Add a language selector to the web_page_bot config with 8 locales
(en, zh-Hans, zh-Hant, ja, es, ru, th, vi). The backend injects the
locale into widget.js which uses a built-in i18n dictionary for all
user-facing strings (welcome message, placeholder, aria labels, error
messages, powered-by footer).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(embed): use correct select option format for language selector
Options must use name/label (i18n object) format, not value/label
(plain string), to match the dynamic form renderer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style(embed): adjust footer padding and link to langbot.app
Increase footer padding for more breathing room from the bottom edge.
Change powered-by link from GitHub repo to langbot.app.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(embed): ignore Enter key during IME composition
Check e.isComposing before treating Enter as send, so confirming
an IME candidate (e.g. Chinese/Japanese input) does not also fire
the message.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(embed): center bubble icon and fill entire circle
Make .lb-chat-icon span fill the full bubble area so the logo image
covers the circle completely without exposing the blue background.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(embed): add bubble icon presets selector
Add 6 bubble icon options (LangBot logo, chat bubble, robot, headset,
sparkle, message) configurable in the bot settings. Icons are inline
SVGs in widget.js, selected via a config field injected by the backend.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: RockChinQ <rockchinq@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Space API defaults to page_size=20, but the model catalog has grown
beyond 20 entries (currently 26), causing models to be silently dropped
during sync.
Migration 0003 failed when rerank_models table already exists from create_all().
Add table existence check to prevent duplicate creation error in CI environments with cached database.
* feat(provider): add rerank model management as a core model type
* feat(provider): add rerank support to existing requesters and new rerank providers
* feat(web): add rerank model management UI and pipeline config
* fix(provider): correct rerank support_type after verification
- Add rerank to OpenRouter (confirmed /api/v1/rerank endpoint)
- Remove rerank from Ollama (no native support, PR #7219 unmerged)
- Remove rerank from JiekouAI (no rerank docs found, URL path mismatch)
* fix(provider): remove alru_cache from model getters and add rerank param hints
* fix: resolve lint errors
- Remove unused alru_cache import from modelmgr.py
- Remove unused error_message variable in invoke_rerank
- Fix prettier formatting in frontend files
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: remove unused exception variable
- Change `except Exception as e:` to `except Exception:` since e is not used
- Fix prettier formatting in ProviderCard.tsx
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: apply ruff format
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(template): add rerank config fields to default pipeline config
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore: remove PR.md
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(ui): remove duplicate rerank model form in AddModelPopover
The form was being rendered twice: once in TabsContent manual mode
and again in a separate conditional block for rerank tab.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>