- run_from_query() now delegates to run(event, binding) instead of maintaining
a separate legacy execution path
- Pipeline Query is converted to AgentEventEnvelope via PipelineCompatAdapter
- Pipeline config is converted to AgentBinding with StatePolicy
- bound_plugins authorization preserved from Pipeline
- Legacy compatibility fields preserved:
- query_id → context.runtime.query_id → session registry
- prompt → context.compatibility.extra.prompt (not top-level)
- params → context.compatibility.extra.params (with proper filtering)
- max-round → bootstrap.messages and compatibility.legacy_messages
- Pipeline path gains event-first host capabilities:
- EventLog and Transcript writing
- ArtifactStore registration
- PersistentStateStore for state.updated
- Removed legacy handlers:
- _handle_artifact_created_query() (replaced by _handle_artifact_created)
- _handle_state_updated() (replaced by _handle_state_updated_event)
This change unifies the execution path while preserving backward compatibility
for Pipeline-based runners. EventGateway is not implemented in this branch;
only the event-first entry point is reserved.
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 engineSettingsInvalid and retrievalSettingsInvalid keys to all
locale files (zh-Hant, ja-JP, vi-VN, es-ES, ru-RU, th-TH) for the
new dynamic form validation feature.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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 'object' as a new value type for model extra parameters so users can
configure nested JSON like {"thinking": {"type": "disabled"}} required by
DeepSeek-v4 non-thinking mode (refs #2157).
UI: add 'Object' option to the type dropdown in ExtraArgsEditor; render a
full-width JSON Textarea (resize-y, monospace) with live JSON validation.
On save, JSON is parsed and rejected if not a plain object.
Also make the model edit and add-model popovers scrollable: cap height at
min(70vh, --radix-popover-content-available-height), stop wheel/touchmove
propagation so the dialog's react-remove-scroll lock doesn't swallow
events, and use overscroll-none to avoid the bottom border seam from
rubber-band overscroll.
i18n updated for all 8 locales.
Co-authored-by: Claude Opus 4.7 (1M context) <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>
Use invisible class instead of conditional rendering for save buttons
in bot, pipeline, and knowledge base detail pages, so the button always
occupies space and the tab list position stays stable across tab switches.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(web): 修复复制按钮和插件安装对话框UI问题
- 新增 clipboard.ts 工具函数支持 Clipboard API 降级
- 修复添加机器人页面 Webhook URL 复制按钮未生效
- 修复 API 集成对话框 API Key 复制按钮未生效
- 修复 Bot 会话监控用户 ID 复制按钮未生效
- 修复插件安装进度状态框横向溢出和小屏缩放问题
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(web): improve clipboard copy with Selection API fallback
Replace navigator.clipboard.writeText with Selection API + execCommand
for reliable copying in non-secure contexts. Remove duplicate dialog.
Fix scanProviderModels type signature to accept rerank model type.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(web): revert package-lock.json to match upstream
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(web): fix prettier formatting errors
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(web): unify all clipboard copy to use copyToClipboard utility
- Fix embed code copy button not working in non-secure contexts
- Add copy animation (check icon) to embed code button via EmbedCodeField component
- Replace raw navigator.clipboard calls in plugins/page.tsx and BotLogCard.tsx
- Remove duplicated inline fallback implementations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.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 sidebar.pluginPages, sidebar.pluginPagesTooltip, pluginPages
section, and plugins.componentName.Page to es-ES, ja-JP, ru-RU,
th-TH, vi-VN, zh-Hant to fix CI i18n key check.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Page toggle button with PanelTop icon to the in-app plugin
marketplace component filter bar.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show the per-page icon (emoji from page manifest metadata.icon)
in collapsible plugin page sub-items.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add PanelTop icon for Page components in the plugin detail component
list. Change zh-Hans label from '扩展页' to '页面' for consistency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace hardcoded Puzzle/LayoutDashboard icons with actual plugin icon
image loaded from the plugin icon API endpoint
- Add select-none to all plugin page sidebar entries to prevent
accidental text selection
- Add pluginIconURL to PluginPageItem data model
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Group pages by plugin when a plugin has multiple pages, collapse under
the plugin label; single-page plugins render directly without nesting
- Rename "Extension Pages" to "Plugin Pages" with tooltip explaining
these are visual pages provided by installed plugins
- Add pluginLabel to PluginPageItem for display
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>
* feat(models): add provider model scanning
* fix: double close button
* feat: update plugin module
* fix(monitoring): WeChat Work feedback recording bugs (#2108)
* fix(monitoring): fix WeChat Work feedback recording bugs
- Fix feedback events silently dropped when stream session expires:
dispatch feedback handlers regardless of session availability
- Fix IntegrityError on repeated feedback (like→dislike) for same
message: implement UPSERT logic in record_feedback()
- Fix cancel feedback (type=3) not removing records: add delete logic
- Fix inaccurate_reasons validation error: convert int reason codes
to strings before creating FeedbackEvent (Pydantic expects List[str])
- Fix feedback timestamps 8 hours off in frontend: use parseUTCTimestamp
instead of new Date() for UTC timestamp parsing
- Fix StreamSessionManager.cleanup missing _feedback_index cleanup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(monitoring): apply ruff format to wecom feedback files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: 6mvp6 <13727783693@163.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add feat for receive files in wecombot
* fix: ruff error
* fix: always show sidebar plus buttons on touch/mobile devices (#2115)
Agent-Logs-Url: https://github.com/langbot-app/LangBot/sessions/e27a4886-fbad-4a7a-8558-67a387852753
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* fix: SPA fallback for all frontend routes, not just /home/*
After migrating from Next.js to Vite SPA, routes like /auth/space/callback
returned 404 because the static file server only had SPA fallback for /home/*.
Now all non-API routes fall back to index.html for React Router to handle.
* style: ruff format main.py
* feat: add marketplace link when no parser available for file upload
Links to /home/market?category=Parser, same pattern as knowledge engine selector.
* fix: lint error
* fix(user): allow password login and password change for Space accounts with local password set
Previously, Space accounts were unconditionally blocked from password login
and password change based on account_type. Now the check verifies whether
the user actually has a local password set, allowing Space users who have
set a local password to authenticate and change it normally.
* feat: add edition field to telemetry payload
Sends constants.edition (community/saas) with each telemetry event
so Space can distinguish between community and SaaS instances.
* style: ruff format telemetry.py
* fix(dingtalk): use voice recognition text instead of raw audio binary
When DingTalk sends a voice message to the bot, the callback JSON contains
a 'recognition' field with the speech-to-text result (powered by Qwen).
Previously, LangBot only extracted the 'downloadCode' to download the raw
audio binary and passed it as 'file_base64' to LLM APIs, which caused
400 errors since most models don't support this content type.
This patch:
- Extracts the 'recognition' field from DingTalk audio message content
- Uses it as plain text input to the LLM instead of raw audio
- Falls back to audio binary only when no recognition text is available
- Fixes duplicate text issue for audio messages with recognition
Fixes voice messages returning 'Request failed' on all LLM models.
* feat: integrate Alembic for database migrations
Replace manual if-sqlite/if-postgres branching with Alembic:
- Add alembic dependency
- Create programmatic alembic env (no CLI/alembic.ini needed)
- Support async engines via run_sync passthrough
- render_as_batch=True for SQLite ALTER TABLE compatibility
- Auto-stamp baseline on first run (existing DB at version 25)
- Run alembic upgrade head after legacy migrations
- Include sample migration showing schema + data migration patterns
- Add alembic dir to package-data for distribution
* ci: add migration test workflow for SQLite and PostgreSQL
Tests alembic upgrade on both databases:
- Stamp baseline on existing schema
- Upgrade to head
- Idempotent re-upgrade
- Fresh DB upgrade from scratch
* feat: add autogenerate support and CLI entrypoint for alembic
- autogenerate: compare ORM models vs DB schema to generate migrations
- CLI: python -m langbot.pkg.persistence.alembic_runner <command>
- autogenerate, upgrade, stamp, current
- Reads data/config.yaml for DB connection
* fix: add filereader for dingtalk,lark (#2122)
* fix: add filereader for dingtalk
* feat: add lark
* feat: update uv.lock
* chore: update version to 4.9.6 in pyproject.toml, __init__.py, and uv.lock
* fix: update langbot-plugin version to 0.3.8
* fix: update langbot-plugin version to 0.3.8
* docs: update database migration instructions in AGENTS.md
* fix(dashscopeapi): fix null value check in reasoning content processing logic (#2128)
* fix(n8n-runner): fix output_key not applied when n8n returns plain JSON (#2119)
* fix: bump dependencies to resolve Dependabot security alerts (#2130)
* fix: bump dependencies to resolve Dependabot security alerts
Python:
- aiohttp: >=3.11.18 → >=3.13.4 (duplicate Host headers, header injection, redirect leak, multipart DoS)
- cryptography: >=44.0.3 → >=46.0.7 (buffer overflow with non-contiguous buffers)
- pillow: >=11.2.1 → >=12.2.0 (FITS GZIP decompression bomb, HIGH)
- langchain-text-splitters: >=0.0.1 → >=1.1.2 (SSRF redirect bypass)
- langchain-core: add >=1.2.28 (incomplete f-string validation)
- langsmith: add >=0.7.31 (streaming token redaction bypass)
- python-multipart: add >=0.0.26 (multipart DoS)
- Mako: add >=1.3.11 (path traversal)
- pytest: >=8.4.1 → >=9.0.3 (tmpdir handling)
- uv: >=0.7.11 → >=0.11.6 (arbitrary file deletion)
JavaScript (web/):
- vite: ^8.0.3 → ^8.0.5 (fs.deny bypass, WebSocket file read, path traversal, HIGH)
- axios: ^1.13.5 → ^1.15.0 (cloud metadata exfiltration)
- lodash: ^4.17.23 → ^4.18.0 (code injection via _.template, prototype pollution, HIGH)
* fix: update pnpm-lock.yaml for bumped dependencies
* feat(ci): add i18n key consistency check for frontend locales (#2133)
* feat(ci): add i18n key consistency check workflow
Agent-Logs-Url: https://github.com/langbot-app/LangBot/sessions/c7bf50da-189b-49a5-9671-dbe8e70ff9d0
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* feat(ci): replace eval with line-by-line parser, add permissions block
Agent-Logs-Url: https://github.com/langbot-app/LangBot/sessions/c7bf50da-189b-49a5-9671-dbe8e70ff9d0
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* feat(models): add provider model scanning
* feat(models): add 'select all' functionality and enrich model abilities
* fix:ruff
* fix:ruff
---------
Co-authored-by: WangCham <651122857@qq.com>
Co-authored-by: 6mvp6 <119733319+6mvp6@users.noreply.github.com>
Co-authored-by: 6mvp6 <13727783693@163.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Guanchao Wang <wangcham233@gmail.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
Co-authored-by: RockChinQ <rockchinq@gmail.com>
Co-authored-by: haiyangbg <zhouhaiyangaa@gmail.com>
Co-authored-by: Rock Chin <1010553892@qq.com>
Co-authored-by: Amadeus <115918672+AmadeusKurisu1@users.noreply.github.com>
Co-authored-by: hzhhong <hung.z.h916@gmail.com>
Co-authored-by: fdc310 <2213070223@qq.com>
Add chromaembed.py using Chroma's DefaultEmbeddingFunction (all-MiniLM-L6-v2)
for local embedding generation via ONNX Runtime. Also simplify seekdbembed.py
and add ndarray-to-list conversion for JSON serialization compatibility.
* feat(monitoring): link feedback to LangBot message ID and add feedback export
- Add pipeline→adapter notification hook so monitoring message ID is
passed back to WecomBotAdapter after creation
- Store stream_id→monitoring_message_id mapping with 10-min TTL cleanup
- Replace feedback record stream_id with LangBot monitoring message ID
so feedback can be linked to actual message records
- Rename streamId label to "Related Query ID" in all 7 i18n locales
- Remove non-functional message ID jump button from FeedbackList
- Add feedback export option to ExportDropdown (backend already implemented)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(monitoring): add combined refresh handler for monitoring and feedback data
* fix(wecombot): improve stream ID mapping and error logging in WecomBotAdapter
* feat(lark): add monitoring message ID mapping for feedback correlation
* feat(lark): rename monitoring message ID mappings for clarity and consistency
feat(feedback): add button to view conversation for feedback items
* feat(bot-session-monitor): add feedback handling for bot messages with visual indicators
* feat(bot-session-monitor): enhance feedback display with hover content for like/dislike indicators
* fix(dingtalk): use voice recognition text instead of raw audio binary
When DingTalk sends a voice message to the bot, the callback JSON contains
a 'recognition' field with the speech-to-text result (powered by Qwen).
Previously, LangBot only extracted the 'downloadCode' to download the raw
audio binary and passed it as 'file_base64' to LLM APIs, which caused
400 errors since most models don't support this content type.
This patch:
- Extracts the 'recognition' field from DingTalk audio message content
- Uses it as plain text input to the LLM instead of raw audio
- Falls back to audio binary only when no recognition text is available
- Fixes duplicate text issue for audio messages with recognition
Fixes voice messages returning 'Request failed' on all LLM models.
* fix: add filereader for dingtalk,lark (#2122)
* fix: add filereader for dingtalk
* feat: add lark
* feat: update uv.lock
* chore: update version to 4.9.6 in pyproject.toml, __init__.py, and uv.lock
* fix: update langbot-plugin version to 0.3.8
* fix: update langbot-plugin version to 0.3.8
* fix(wecombot): extend StreamSession TTL for feedback sessions to prevent context data loss
StreamSessionManager.cleanup() removes sessions after 60s TTL, but feedback
events (like → cancel → dislike) can arrive later. When the session expires
before the dislike event, all context fields (session_id, user_id, message_id,
stream_id) are lost because get_session_by_feedback_id() returns None.
Fix: Sessions with registered feedback_ids now use a 10-minute TTL, aligned
with the adapter's _stream_to_monitoring_msg TTL in wecombot.py.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: 6mvp6 <13727783693@163.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: fdc310 <2213070223@qq.com>
Co-authored-by: haiyangbg <zhouhaiyangaa@gmail.com>
Co-authored-by: Guanchao Wang <wangcham233@gmail.com>
Co-authored-by: Rock Chin <1010553892@qq.com>
- autogenerate: compare ORM models vs DB schema to generate migrations
- CLI: python -m langbot.pkg.persistence.alembic_runner <command>
- autogenerate, upgrade, stamp, current
- Reads data/config.yaml for DB connection
Replace manual if-sqlite/if-postgres branching with Alembic:
- Add alembic dependency
- Create programmatic alembic env (no CLI/alembic.ini needed)
- Support async engines via run_sync passthrough
- render_as_batch=True for SQLite ALTER TABLE compatibility
- Auto-stamp baseline on first run (existing DB at version 25)
- Run alembic upgrade head after legacy migrations
- Include sample migration showing schema + data migration patterns
- Add alembic dir to package-data for distribution
When DingTalk sends a voice message to the bot, the callback JSON contains
a 'recognition' field with the speech-to-text result (powered by Qwen).
Previously, LangBot only extracted the 'downloadCode' to download the raw
audio binary and passed it as 'file_base64' to LLM APIs, which caused
400 errors since most models don't support this content type.
This patch:
- Extracts the 'recognition' field from DingTalk audio message content
- Uses it as plain text input to the LLM instead of raw audio
- Falls back to audio binary only when no recognition text is available
- Fixes duplicate text issue for audio messages with recognition
Fixes voice messages returning 'Request failed' on all LLM models.
Previously, Space accounts were unconditionally blocked from password login
and password change based on account_type. Now the check verifies whether
the user actually has a local password set, allowing Space users who have
set a local password to authenticate and change it normally.
After migrating from Next.js to Vite SPA, routes like /auth/space/callback
returned 404 because the static file server only had SPA fallback for /home/*.
Now all non-API routes fall back to index.html for React Router to handle.
* fix(monitoring): fix WeChat Work feedback recording bugs
- Fix feedback events silently dropped when stream session expires:
dispatch feedback handlers regardless of session availability
- Fix IntegrityError on repeated feedback (like→dislike) for same
message: implement UPSERT logic in record_feedback()
- Fix cancel feedback (type=3) not removing records: add delete logic
- Fix inaccurate_reasons validation error: convert int reason codes
to strings before creating FeedbackEvent (Pydantic expects List[str])
- Fix feedback timestamps 8 hours off in frontend: use parseUTCTimestamp
instead of new Date() for UTC timestamp parsing
- Fix StreamSessionManager.cleanup missing _feedback_index cleanup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(monitoring): apply ruff format to wecom feedback files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: 6mvp6 <13727783693@163.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: pipeline routing rules - add routed_by_rule bypass and diagnostic logging
- Add routing rules editor (RoutingRulesEditor component)
- Add routed_by_rule bypass logic in response rules
- Add diagnostic logging for pipeline routing
- Database migration for bot pipeline routing rules
- Extract RoutingRulesEditor component from BotForm
- Revert log levels to debug
* feat: add message_has_element routing rule type
Support routing by message element type (Image, Voice, File, Forward,
Face, At, AtAll, Quote) with eq/neq operators.
* test: add unit tests for pipeline routing rules
20 tests covering _match_operator (eq/neq/contains/not_contains/
starts_with/regex/invalid) and resolve_pipeline_uuid (launcher_type/
launcher_id/message_content/message_has_element/first-match-wins/
skip-invalid/default-operator).
* fix(web): add missing 'message_has_element' to routing rule type validation
The Zod schema and TypeScript type for PipelineRoutingRule.type were
missing the 'message_has_element' variant, causing silent form validation
failure when saving routing rules with this type.
* feat: add pipeline discard functionality and localization support
* feat(web): improve drag-and-drop with DragOverlay, add discard monitoring and pipeline icons
- Add DragOverlay for smooth cursor-following drag in routing rules editor
- Remove transition to eliminate redundant swap animation on drop
- Record discarded messages in monitoring system via _record_discarded_message
- Display pipeline name (Workflow icon) and runner name (Play icon) on session monitor messages
- Show discard badge on discarded messages in session monitor
- Add i18n translations for discarded/userMessage/botMessage
* fix: ensure discarded messages appear in session monitor and improve icons
- Create/update monitoring session for discarded messages so they show in
the bot session monitor (was only inserting message rows, not sessions)
- Use human-readable 'Discarded' as pipeline_name instead of '__discard__'
- Change runner icon from Play to Bot for better AI Agent semantics
* fix: merge discarded messages into same session and remove session-level pipeline name
- Use LauncherTypes enum for session_id in discarded messages to match
the format used by monitoring_helper (fixes duplicate sessions)
- Don't overwrite session pipeline info on discard — a session can have
messages from multiple pipelines
- Remove pipeline_name from session list and chat header since it's
now shown per-message and a session is no longer single-pipeline
* fix(web): only show save button on config tab in bot detail page
* fix(web): scroll to bottom after messages render in session monitor
---------
Co-authored-by: RockChinQ <rockchinq@gmail.com>
* feat: add tools API endpoint and tools-selector form type
Backend:
- Add GET /api/v1/tools — list all available tools (plugin + MCP)
- Add GET /api/v1/tools/<tool_name> — get specific tool details
Frontend:
- Add TOOLS_SELECTOR form type for plugin config forms
- Multi-select dialog with tool name and description
- Add PluginTool entity type and API client methods
* fix: remove unused quart import, fix prettier formatting
* style: ruff format tools.py
* chore: bump langbot-plugin to 0.3.7
* refactor(web): migrate from Next.js to Vite + React Router
* fix: update build pipelines for Vite migration (out → dist)
- Dockerfile: npm run build → npx vite build, web/out → web/dist
- pyproject.toml: package-data web/out/** → web/dist/**
- paths.py: support both web/dist (Vite) and web/out (legacy) with fallback
* fix: remove .next from git tracking, add to .gitignore
1334 cached files from web/.next/ were accidentally committed.
Added .next/ to both root and web/.gitignore.
* fix: update build process to use Vite and correct output directory
* fix: update pnpm-lock.yaml and eslint config for Vite migration
* style: fix prettier formatting issues
* fix: add eslint-plugin-react-hooks for Vite migration
* fix: remove undefined eslint rule reference, downgrade react-hooks plugin to v5
* fix(web): clean up remaining Next.js artifacts in Vite migration
- Add vite-env.d.ts for import.meta.env and asset type declarations
- Remove dead layout.tsx (providers already in main.tsx)
- Fix useSearchParams destructuring to [searchParams] tuple (11 locations)
- Replace process.env.NEXT_PUBLIC_* with import.meta.env.VITE_*
- Fix langbotIcon.src to langbotIcon (Vite returns URL string)
- Fix Link href to Link to for react-router-dom
- Fix navigate({ scroll: false }) to { preventScrollReset: true }
- Fix [router] dependency arrays to [navigate]
- Remove Next.js plugin from tsconfig, set rsc: false in components.json
- Replace next lint with eslint in lint-staged
* feat: add tools API endpoint and tools-selector form type
Backend:
- Add GET /api/v1/tools — list all available tools (plugin + MCP)
- Add GET /api/v1/tools/<tool_name> — get specific tool details
Frontend:
- Add TOOLS_SELECTOR form type for plugin config forms
- Multi-select dialog with tool name and description
- Add PluginTool entity type and API client methods
* Revert "feat: add tools API endpoint and tools-selector form type"
This reverts commit 3c637fc563.
List-type config values can now be set via environment variables using
comma-separated strings. For example:
SYSTEM__DISABLED_ADAPTERS=aiocqhttp,dingtalk
Previously list and dict types were both skipped; now only dict is skipped.
Adds 'system.disabled_adapters' config option (list of adapter names).
Disabled adapters are excluded from both the adapter registry and API
responses, preventing users from creating bots with those adapters.
Example config:
system:
disabled_adapters:
- aiocqhttp
- dingtalk
* feat(wecom): add user feedback support for WeChat Work AI Bot
This commit implements user feedback functionality (like/dislike) for
WeChat Work AI Bot conversations, including:
Backend changes:
- Add feedback_id and stream_id fields to WecomBotEvent
- Implement feedback event handling in WecomBotClient (api.py)
- Add StreamSessionManager._feedback_index for feedback_id lookup
- Add on_feedback decorator for custom feedback handlers
- Create MonitoringFeedback entity for database persistence
- Add dbm025 migration for monitoring_feedback table
- Implement FeedbackMonitor helper class
- Update all platform adapters with ap parameter support
- Update botmgr to pass bot_info for monitoring context
Frontend changes:
- Add FeedbackCard and FeedbackList components
- Add useFeedbackData hook for feedback data fetching
- Add feedback tab to monitoring page
- Add feedback types and interfaces
- Add i18n translations (zh-Hans, en-US)
Other changes:
- Update Dockerfile with Chinese mirror for faster builds
- Update docker-compose.yaml with network configuration
- Update .gitignore for docker data and backup files
Note: Known issues that need future improvement:
- feedback_type=3 (cancel) is recorded but not properly handled
- Duplicate feedback records are not deduplicated
* chore: remove unnecessary migration for new table will be created automatically
* chore: ruff format
* chore: prettier
* feat: add feedback handling support across multiple platform adapters
* fix(web): remove unused imports and variables in monitoring module
---------
Co-authored-by: 6mvp6 <13727783693@163.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
Add 'View Docs' button that links to the corresponding adapter's
documentation page via link.langbot.app short links.
Appears in:
- Wizard adapter selection cards (Step 0)
- Wizard bot config card header (Step 1)
- Bot create/edit form (adapter config section)
Supports all 7 languages (en/zh-Hans/zh-Hant/ja/th/vi/es).
Doc links auto-resolve to the correct language based on UI locale.
All documentation URLs now go through Cloudflare Bulk Redirects
(link.langbot.app) so future doc path changes won't break
already-released versions.
Short link format: link.langbot.app/{lang}/docs/{topic}
Supported languages: zh, en, ja
- Add zh_Hant (Traditional Chinese) to all 17 adapter YAML metadata and config fields
- Add ja_JP translations to global adapters (Telegram, Discord, Slack, Lark, LINE)
- Fix buggy zh_Hant in line.yaml and slack.yaml (contained simplified Chinese)
- Add zh_Hant field to backend I18nString model
- Add adapter category grouping with locale-aware ordering
- Add webhook Cloud CTA for community edition users
- Fix wizard progress not clearing on skip/complete
* feat(wizard): persist wizard progress to backend for session resumption
Store wizard step, selected adapter, created bot UUID, and runner
selection in the metadata table. On revisit, the wizard restores
progress and verifies the bot still exists. Progress is cleared
automatically when the wizard is completed or skipped.
* feat(dynamic-form): optimize LLM model selection with space login CTA and improve localization strings
* feat(web): add LangBot Cloud CTA for webhook URL fields in community edition
Show a subtle hint below webhook URL fields prompting users about
LangBot Cloud's public endpoint, only visible in community edition.
Covers all 8 webhook-based adapters with i18n support (4 locales).
* fix(web): auto-redirect to wizard on first visit and change sidebar icons to blue
* refactor(wizard): use backend metadata table instead of localStorage for wizard completion state
- Add wizard_completed field to system info API (read from metadata table)
- Add POST /api/v1/system/wizard/completed endpoint to mark wizard done
- Frontend home layout checks systemInfo.wizard_completed for auto-redirect
- Wizard calls markWizardCompleted API on skip/finish
- Ensures consistent behavior across all browsers on the same instance
* fix(wizard): update systemInfo in memory before navigation to prevent redirect loop
* fix(monitoring): prevent horizontal overflow and unify empty state styles
* fix(wizard): use Object.assign for systemInfo and await wizard completion API
- Replace systemInfo reassignment with Object.assign in all 3 locations
to preserve object identity across module imports
- Await markWizardCompleted() POST in wizard skip/finish handlers
instead of fire-and-forget to ensure backend persistence
- Always re-fetch systemInfo in home layout to get latest
wizard_completed state from backend
* fix(wizard): prevent redirect loop by blocking navigation on failed status save
- Refactor wizard_completed (boolean) to wizard_status (string: none/skipped/completed)
- Remove ALL localStorage usage from wizard page (form state persistence)
- Replace AlertDialogAction with Button so skip dialog stays open during POST
- Add loading spinners for skip and complete actions
- If POST fails, show error toast and keep dialog/button active for retry
- If POST succeeds, update in-memory state and navigate
* fix(wizard): fix row[0].value bug causing GET /info to always return wizard_status=none
conn.execute(select(Entity)) returns Row with raw column values, not ORM
entities. row[0] is the key column (a string), so row[0].value raises
AttributeError which was silently swallowed by except-pass, making the
GET endpoint always return wizard_status=none regardless of DB state.
* fix(wizard): replace AlertDialog with Dialog for skip confirmation to remove slide animation
* chore: optimize toast in wizard
* fix(wizard): set default token value for Telegram adapter and initialize adapter config in wizard
* feat(web): move webhook URL to dynamic form system, add market category filter, fix layout overflow
- Add 'webhook-url' dynamic form field type rendered as read-only input
with copy button, defined in adapter YAML specs instead of hardcoded
in BotForm. Supports show_if conditions for optional-webhook adapters.
- Remove hardcoded webhook display logic from BotForm.tsx, pass webhook
URLs via systemContext to DynamicFormComponent.
- Fetch webhook URLs after bot creation in wizard and pass to Step 1.
- Support ?category= query param on /home/market page for filtering by
component type (mirrors langbot-space behavior).
- Link 'install knowledge engine' hint to /home/market?category=KnowledgeEngine.
- Fix SidebarInset missing min-w-0 causing content overflow when sidebar
is expanded.
- Add vertical divider between plugin detail config and readme panels.
- Fix infinite re-render loop in DynamicFormComponent by memoizing
editableItems array.
* fix: lint
* fix(web): change systemInfo to const to satisfy prefer-const lint rule
* fix: update adapter descriptions for clarity and usage requirements
* feat(web): add onboarding wizard for guided bot creation
Implement a full-screen 4-step wizard at /wizard that guides users
through selecting a platform, configuring a bot, choosing an AI engine,
and completing setup. The wizard uses DynamicFormComponent for adapter
and pipeline configuration, embeds BotLogListComponent for real-time
debugging, persists state to localStorage, and integrates with Space
OAuth flow. Also fixes a prompt-editor crash in DynamicFormComponent
when value is undefined.
* feat(wizard): redesign step 0/1 flow, add skip dialog, auto-expand log images
- Step 0: Remove bot name/description fields; auto-derive name from adapter
label; create disabled bot on confirm; advance to Step 1 automatically
- Step 1: Replace 'Create Bot' with 'Save & Enable Bot'; update adapter
config and enable bot; disable form fields after saving
- Add skip confirmation AlertDialog with i18n message
- Add LanguageSelector to wizard header
- Move wizard sidebar entry to last position to prevent fallback redirect loop
- Add defaultExpanded prop to BotLogCard; auto-expand entries with images
in wizard via autoExpandImages prop on BotLogListComponent
- Remove automatic default pipeline creation (write_default_pipeline) from
backend persistence manager since the wizard now handles pipeline creation
- Update all 4 locale files (en-US, zh-Hans, zh-Hant, ja-JP)
* fix(wizard): hide detailed logs link in wizard, allow re-editing bot config after save
- Add hideDetailedLogsLink prop to BotLogListComponent; pass it in wizard
- Remove isEditing on DynamicFormComponent so form stays editable after save
- Always show save button; label changes to 'Re-save' after first save
- Add resaveBot i18n key to all 4 locale files
* style(wizard): move save button into config card header
* fix(wizard): initialize userInfo/systemInfo so model selector works
The wizard runs outside /home layout, so userInfo was null. This caused
the model-fallback-selector to filter out all Space models, showing an
empty dropdown. Fix by calling initializeUserInfo() and
initializeSystemInfo() before fetching wizard data.
Also:
- Hide log toolbar in wizard via hideToolbar prop on BotLogListComponent
- Add empty state message for bot logs (noLogs i18n key, all 4 locales)
* feat(wizard): redesign AI Engine step with left-right split layout
Before selecting a runner: centered grid of runner cards.
After selecting: left panel shows compact runner list for switching,
right panel shows runner config form with slide-in animations.
Also fix prompt field default: add default value to prompt-editor field
in ai.yaml metadata so the prompt is pre-populated with
'You are a helpful assistant.' instead of being empty.
* feat(pipeline): add default values to ai.yaml runner configs and show_if for n8n auth fields
- Sync default values from default-pipeline-config.json to all runner
config fields in ai.yaml so wizard forms are pre-populated
- Add show_if conditions to n8n-service-api auth fields so only the
relevant credentials appear based on selected auth-type
- Fix prompt-editor crash in DynamicFormItemComponent when field.value
is undefined (Array.isArray guard + fallback)
- Improve wizard Step 2 split layout with fixed column widths,
independent scroll, ring clipping fix, and mobile responsiveness
- Use key={selected} on DynamicFormComponent to force remount on
runner switch
- Improve pipeline creation flow: create → fetch defaults → merge AI
section → update (preserves trigger/safety/output defaults)
* feat(dynamic-form): add systemContext prop with __system.* namespace for show_if conditions
- Add systemContext prop to DynamicFormComponent for injecting external
variables accessible via __system.* prefix in show_if conditions
- Extract resolveShowIfValue() helper for cleaner field resolution
- Pass { is_wizard: true } from wizard to hide knowledge-bases field
- Remove bot config save toast in wizard (keep inline indicator)
* feat(sidebar): render wizard as standalone item before Home group with fallback redirect fix
* fix(wizard): remove unused setBotDescription to fix lint error
Add '+' dropdown menu to plugins sidebar category with three install
options: marketplace, upload local, and install from GitHub. Use shared
React context (pendingPluginInstallAction) instead of URL params to
reliably trigger install actions across components. Add e.stopPropagation
on all DropdownMenuItem handlers to prevent React portal event bubbling
from triggering parent SidebarMenuButton navigation.
Use runtime_info.status from the API instead of only checking the enable
flag. Dots now show: green (connected), yellow (connecting), red (error),
gray (disabled or no status).
- Refactor MCP servers to be managed as collapsible sidebar sub-items with
?id= detail routing and inline form (matching bots/pipelines pattern)
- Add MCPDetailContent with create/edit modes, enable toggle, and danger zone
- Extract MCPForm as standalone inline form from MCPFormDialog
- Move API Integration to standalone sidebar footer button
- Add GitHub star CTA with live star count badge in user dropdown menu
- Add MCP server status dot indicators in sidebar (green/gray for enabled/disabled)
- Add i18n keys for MCP detail page and GitHub star CTA in all 4 locales
The onDeletePipeline callback was a no-op, causing the sidebar to
remain stale and the content area to stay on the deleted pipeline.
Now calls refreshPipelines() and navigates to /home/pipelines,
consistent with bot and knowledge base deletion behavior.
Remove .default('') from zod schemas to align input/output types,
preventing type conflict between zodResolver and useForm in
@hookform/resolvers v5. Use nullish coalescing at entity assignment
sites to ensure string type safety.
- Remove .min(1) validation on description field, replace with .optional().default('')
- Remove pre-filled default description text from all three create forms
- Remove required asterisk (*) marker from description labels
- No backend changes needed: Bot/Pipeline DB accepts empty string, KB DB allows null
- Remove vertical guide lines from collapsible sub-items (border-l)
- Move create button from list bottom to category header row as a hover-revealed + icon
- Remove active background highlight from category headers; only child entities show active state
- Remove unused CREATE_I18N_KEYS constant
- Bot adapter selector: show adapter icon in trigger and dropdown items
- Knowledge engine selector: show plugin icon derived from plugin_id
- Pipeline binding selector: show pipeline emoji in trigger and dropdown items
- Knowledge base selectors (single/multi): show KB emoji in all views
- Sidebar bot entries: show green/gray status dot on adapter icon for enable/disable state
- Sidebar plugin list: sync after install/uninstall from all entry points (PluginInstalledComponent, plugins page, marketplace page)
- Pipeline form: add cursor-pointer to left-side tab list buttons
- Clean up unused onBotDeleted prop from BotForm
- Restructure bot edit page from flat form to card-based layout (Basic Info, Pipeline Binding, Adapter Config, Danger Zone)
- Move enable switch and save button to sticky header for quick access
- Move webhook URL display into adapter config card (contextually related)
- Remove redundant adapter icon card; show description as FormDescription
- Add dedicated Danger Zone card with red border for delete action
- Remove duplicate delete dialog from BotForm (single source in BotDetailContent)
- Implement form dirty tracking: save button is disabled until user modifies content
- Add i18n keys for new card titles/descriptions across all 4 locales
* feat(web): migrate sidebar to shadcn and convert entity editors to page views
* feat(web): enhance sidebar with sections, collapsible persistence, sub-item sorting/limiting, and UI polish
- Reorganize sidebar into Home and Extensions sections with collapsible groups
- Split plugins page into plugins, market, and mcp as separate routes
- Add sidebar sub-items sorted by updatedAt with max 5 visible and expand/collapse toggle
- Persist collapsible section state and sidebar open state in localStorage
- Fix page refresh stripping query params by splitting handleChildClick/selectChild
- Swap plugin detail layout (config left, readme right)
- Add fixed headers with internal scroll for all detail and list pages
- Remove entity form borders and sidebar rail
- Improve dark mode sidebar/content contrast
- Rename monitoring to Dashboard, move to first position
- Update breadcrumb to show Home or Extensions based on current route
- Add i18n translations for more/less toggle in all 4 locales
* fix(web): fix scroll behavior - constrain layout to viewport, fix fixed headers and independent scroll areas
- Change SidebarProvider wrapper from min-h-svh to h-svh overflow-hidden to constrain layout to viewport height (root cause of all scroll issues)
- Fix create mode pages (bot, pipeline, knowledge): extract title bar out of scroll container so only form content scrolls
- Fix plugin detail: add overflow-x-hidden on both config and readme panels to prevent horizontal overflow
- Add min-h-0 to all TabsContent in edit mode for cross-browser flex shrink safety
- Change nested <main> to <div> in layout to avoid invalid nested <main> tags (SidebarInset already renders as <main>)
* style(web): polish UI - dashboard i18n, sidebar create text, cursor-pointer tabs, remove cancel buttons
* feat(web): add plugin context menu to sidebar sub-items
- Add hover-reveal dropdown menu (Ellipsis icon) on plugin sidebar items
- Menu items: Update (marketplace only), View Source (marketplace/github), Delete
- Add confirmation dialog with async task polling for delete/update operations
- Extend SidebarEntityItem with installSource and installInfo fields
- Fix PipelineFormComponent optional onCancel invocation
* fix(web): prevent plugin sidebar text from overlapping menu button
Add right padding on plugin sub-items and explicit truncate on text
span so long plugin names never overlap the hover menu button.
* feat(web): show update indicator on sidebar plugin menu
- Fetch marketplace plugin versions in SidebarDataContext.refreshPlugins
- Compare with installed version using isNewerVersion to set hasUpdate
- Show red dot on menu trigger when update available (always visible)
- Show 'New' badge on Update menu item when update available
- Marketplace fetch failure is silently caught to avoid blocking sidebar
* refactor(web): remove entity list pages, back buttons, and make sidebar toggle collapse
- Remove card grid list views from bots, pipelines, knowledge pages
- Show empty state placeholder when no entity is selected
- Preserve KB migration dialog at page level
- Remove back (ArrowLeft) buttons from all detail pages (bots, pipelines, knowledge, plugins)
- Sidebar parent click for bots/pipelines/knowledge now toggles collapse instead of navigating
- Breadcrumb second level is now non-clickable (always BreadcrumbPage)
- Add selectFromSidebar i18n keys in all 4 locales
* feat(web): enhance bot session monitor with refresh functionality and improve log card UI
* refactor(web): optimize pipeline detail page with vertical config nav and debug chat polish
- Convert pipeline config tab's horizontal sub-tabs to vertical left-side navigation with icons
- Replace hardcoded colors in PipelineFormComponent and DebugDialog with theme-aware Tailwind classes
- Replace custom SVG icons with lucide-react (User, Users, ImageIcon, Send, Reply, etc.)
- Replace hardcoded Chinese strings with i18n keys (allMembers, file, voice, uploadImage, uploading)
- Modernize chat bubbles to use bg-primary/10 and bg-muted instead of hardcoded blue/gray
- Translate all Chinese comments to English in both components
- Delete unused pipelineFormStyle.module.css
- Remove max-w-2xl constraint from config tab container
* fix(web): improve dark mode contrast and relocate WebSocket status indicator
Bump dark mode --muted, --accent, --secondary from oklch(0.18) to oklch(0.24)
to fix invisible TabsList, message bubbles, and selected items against the
oklch(0.17) background. Move WebSocket connection dot from pipeline title
into the Debug Chat tab trigger so it is always visible. Replace hardcoded
Quote border colors with theme-aware border-muted-foreground/50.
* fix(web): increase dark mode contrast for muted/accent/secondary to oklch(0.27)
Previous value of oklch(0.24) was still not distinguishable enough against
the oklch(0.17) background. Bump to oklch(0.27) for a 0.10 lightness gap,
matching the contrast ratio of the default shadcn zinc dark theme.
* style(web): replace hardcoded colors with theme tokens in monitoring dashboard
Convert all monitoring page components from hardcoded gray/white colors
to theme-aware CSS variable tokens (bg-card, text-foreground,
text-muted-foreground, bg-muted, bg-background, bg-accent, border).
Semantic colors (red/green/blue/purple for status badges and error
styling) are intentionally preserved.
* feat(web): show debug indicator for debugging plugins in sidebar
Add orange Bug icon next to plugin name in sidebar sub-items when the
plugin is connected via WebSocket debug mode. Hide context menu for
debug plugins since delete/update operations are not supported.
* feat(web): show install source and debug badge on plugin detail page
Display a badge next to the plugin title indicating the install source
(GitHub blue, Local green, Marketplace purple) or debugging status
(orange with Bug icon), matching the existing plugin card convention.
* fix(web): resolve eslint errors for CI - remove unused imports and variables
* fix(web): remove stale setSubtitle call and fix prettier formatting
* Refactor code formatting and improve readability
- Updated HomeSidebar.tsx to enhance clarity in conditional assignment.
- Adjusted CSS formatting in github-markdown.css for better alignment.
- Cleaned up tsconfig.json by consolidating array formatting for consistency.
* fix(ci): use local prettier instead of mirrors-prettier to avoid version mismatch (3.1.0 vs 3.8.1)
KnowledgeRetriever has been superseded by KnowledgeEngine. Filter out
plugins that only contain KnowledgeRetriever components from both the
main plugin list and recommendation lists, and remove the now-unused
deprecated badge UI.
Backend serializes monitoring timestamps as naive ISO strings without
timezone designator. JavaScript's new Date() treats such strings as
local time, causing displayed times to be off by the user's UTC offset.
Add parseUTCTimestamp() utility that appends 'Z' to ensure correct UTC
interpretation.
* feat: add wexin openclaw adapter
* feat: The new feature will store the token and other configurations after login.
* fix: wexin qc to base64 and in log image print
* feat: add image to base64
* feat: add update file and image and voice
The plugin SDK declares get_llm_models() -> list[str] (UUID strings),
but the host handler returned the full model dict list from
llm_model_service.get_llm_models(). This caused TypeError when
invoke_llm passed a dict to get_model_by_uuid (which is decorated
with @async_lru and requires hashable arguments).
Extract only the 'uuid' field to match the SDK contract.
* feat(web): merge plugin readme and config into single detail dialog
- Click plugin card directly opens combined dialog (left: readme, right: config)
- Remove hover overlay with separate readme/config buttons
- Dropdown menu (⋯) still available for update/delete/view source
* fix: prettier format for lucide import
Add handlers for LIST_KNOWLEDGE_BASES and RETRIEVE_KNOWLEDGE actions
that allow plugins to list and retrieve from any knowledge base without
pipeline scope restrictions, complementing the existing pipeline-scoped handlers.
* Fixed the issue where the at bot did not remove the at symbol, resulting in some commands not being activated in group chats. Also, adjusted the logic in the on_message section.
* fix:reply_message del bot_name
The Telegram adapter only handles TEXT, COMMAND, PHOTO, and VOICE
messages. Document files (docx, pdf, etc.) sent by users are silently
dropped because:
1. MessageHandler filters lack filters.Document.ALL
2. target2yiri() has no message.document branch
3. yiri2target() has no platform_message.File branch
4. send_message() has no 'document' component handler
Changes:
- Add filters.Document.ALL to the MessageHandler filter set
- Add message.document parsing in target2yiri() → platform_message.File
- Add platform_message.File handling in yiri2target() → document component
- Add 'document' type handling in send_message() via bot.send_document()
This allows Telegram document messages to flow through the existing
PreProcessor and Dify file upload pipeline, consistent with how other
adapters (Lark, KOOK, Discord, WeCom) already handle files.
Closes#2065
Previously, environment variable overrides (e.g. SYSTEM__INSTANCE_ID)
were silently skipped if the target key didn't already exist in
data/config.yaml. This caused SaaS pods running older LangBot images
(whose config template lacked system.instance_id) to ignore the
SYSTEM__INSTANCE_ID env var, falling back to a random UUID that
didn't match the pod UUID — breaking idle timeout tracking.
Now env overrides create missing keys (as strings) and missing
intermediate dicts, so they work regardless of template version.
Co-authored-by: rocksclawbot <rocksclawbot@users.noreply.github.com>
- If system.instance_id set in config (via env var), use it
- If not set but file exists, read from file (don't generate new)
- If neither, generate new and save to file
Add instance_id field to system section in config.yaml.
Can be set via SYSTEM__INSTANCE_ID env var (auto-mapped).
Falls back to data/labels/instance_id.json if not set.
In SaaS (cloud edition), the instance_id can now be injected via
environment variable to match the pod UUID. This enables zero-lookup
telemetry routing in Space - no need to reverse-lookup instance_id
to find the pod.
Extract knowledge base UUID list into query.variables['_knowledge_base_uuids']
in PreProcessor so plugins can modify it during PromptPreProcessing. Runner now
reads from variables instead of pipeline_config. Also pass session_name,
bot_uuid, and sender_id to kb.retrieve() in the RETRIEVE_KNOWLEDGE_BASE handler
so knowledge engines receive proper session context.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Implement WebSocket long connection client for WeChat Work AI Bot
- Added WecomBotWsClient to handle WebSocket connections for receiving messages and sending replies.
- Introduced a new migration (dbm022) to add 'enable-webhook' field to existing wecombot adapter configs, ensuring backward compatibility.
- Updated WecomBotAdapter to support both WebSocket and webhook modes based on the new configuration.
- Enhanced YAML configuration for WecomBot to include 'enable-webhook' and 'Secret' fields, adjusting requirements accordingly.
- Incremented database version to 22 to reflect schema changes.
* fix:db enable-webhook is false
* fix:add logic
* fix:Removed an unnecessary configuration check
* fix: migration
* fix: update migration
* fix:migration
* fix(database): Update database version requirement to 20
- Increase required_database_version from 19 to 20
- Add documentation on database schema version check
* feat(lark): Added support for message references and topic message grouping
- Implemented the function to extract reference message IDs from messages, supporting parent message identification
- Added a method to construct event messages from SDK message items
- Implemented the function to asynchronously obtain reference messages and convert them into message chains
- Integrated reference message injection logic into the message processing flow
- Added a mechanism to filter source components while retaining reference content
- Implemented a method to obtain the starter ID with topic awareness
- Provided session isolation support for topic range in group thread messages
- Supported stable maintenance of conversation context in group thread discussions
- Handled cases where topic messages cannot reliably detect reference targets
* feat(lark): Implement a duplicate prevention mechanism for Feishu topic message references
- Add class-level cache to store processed topic IDs and timestamps
- Implement a timed cleanup mechanism to remove expired topic records
- Add cache size limit to prevent memory from growing indefinitely
- Return the parent message ID and mark it as processed when the first reply is made to a topic
- Return None in subsequent replies to the same topic to avoid duplicate references
- Implement automatic cache trimming to ensure stable performance
* fix(market): sync plugin market UI from space - page size 12, full list display, fix double separator, adaptive tag display
* fix: lint and prettier formatting
* fix: prettier formatting for remaining files
- Add get_user_info() to WecomClient to fetch user name via /user/get API
- Update WecomEventConverter.target2yiri to accept bot param and fetch real user name
- Update register_listener call to pass self.bot for user name lookup
- URL-encode userid parameter for safety
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
- Implement full-text search via Chroma's $contains filter
- Implement hybrid search with RRF (Reciprocal Rank Fusion) combining
vector and full-text results, with min-max normalized distances
- Fix add_embeddings to use col.upsert instead of col.add for idempotency
- Bump chromadb dependency to >=1.0.0,<2.0.0
- Re-lock uv.lock with official PyPI source
* feat(rag): add knowledge base migration from v4.9.0 to plugin architecture
Rewrite dbm020 to backup old knowledge_bases data and preserve
external_knowledge_bases table. Add migration API endpoints and
frontend dialog so users can opt-in to auto-install LangRAG plugin
and restore their knowledge bases with original UUIDs preserved.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): query marketplace for actual plugin version instead of 'latest'
The marketplace API does not support 'latest' as a version string.
Fetch the plugin info first to get latest_version, then use that
concrete version for installation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(rag): add data-only migration option and fix dialog width
Add option to migrate knowledge base data without auto-installing
the LangRAG plugin (for offline/intranet environments). Also
narrow the migration dialog to match other confirmation dialogs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: to red and no more
* fix lint
* fix ruff lint
* feat: add external migration
* fix: show
* feat: add external plugin auto download
* feat: update migration messages for knowledge base in multiple languages
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* fix: coerce pipeline config types at load time using metadata definitions
Pipeline configs stored in SQLAlchemy JSON columns can have values turned
into strings after UI edits (e.g. "120" instead of 120), causing runtime
arithmetic/logic errors. Add centralized type coercion in load_pipeline()
that leverages existing metadata YAML type definitions (integer, number,
float, boolean) to convert values before they reach downstream stages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address review - defensive getattr + add unit tests for config_coercion
- Use getattr with defaults for pipeline_config_meta_* attributes to
avoid AttributeError when MockApplication lacks these fields
- Add 18 unit tests for config_coercion module covering all code paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add dynamic form stage tracking and snapshot management
* fix: standardize string formatting in config coercion and improve logging messages
---------
Co-authored-by: KPC <kpc@kpc.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
- Include websocket_proxy_bot in get_bot_by_uuid lookup so plugins can
find it by uuid
- Rewrite send_message to broadcast directly via ws_connection_manager
using the correct pipeline_uuid instead of misusing target_id
- Save messages to session history with unique IDs so they persist
across page reloads and don't overwrite each other
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Added dynamic column measurement to adjust the number of visible plugins based on the grid layout.
- Implemented auto-advance feature for pagination every 5 seconds when there are more plugins than the visible count.
- Updated pagination controls to reflect the current page accurately.
- Refactored code to improve readability and maintainability.
The getTitle fallback order was reversed, always showing the UUID
(file_id) since it's always truthy. Swap priority to document_name
first.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* [issue:1933] RAG engine plugin architecture (#1967)
* refactor: migrate RAG knowledge services to a plugin-oriented host service architecture.
* feat(rag): phase 2 core refactor with RPC Action handlers
* feat: 为 RAG 插件添加知识库创建和删除事件通知,并优化了 RAG 动作的参数传递和枚举使用。
* feat: 统一知识库管理为RAG引擎,支持动态配置并移除旧的外部知识库组件。
* refactor(rag): remove plugin_adapter, inline logic into RuntimeKnowledgeBase
BREAKING CHANGE: RAGPluginAdapter has been removed. All plugin
communication is now handled directly by RuntimeKnowledgeBase.
Architecture change:
- Before: RuntimeKnowledgeBase → RAGPluginAdapter → plugin_connector
- After: RuntimeKnowledgeBase → plugin_connector (direct)
Changes to kbmgr.py (RuntimeKnowledgeBase):
- Remove RAGPluginAdapter import and usage
- Inline plugin communication methods:
- _on_kb_create(): Notify plugin when KB is created
- _on_kb_delete(): Notify plugin when KB is deleted
- _ingest_document(): Call plugin for document ingestion
- _retrieve(): Call plugin for retrieval
- _delete_document(): Call plugin to delete document
- Simplify dispose(): Only notify plugin, no built-in VDB assumption
Changes to base.py (KnowledgeBaseInterface):
- Remove get_type() abstract method (outdated internal/external concept)
- Add get_rag_engine_plugin_id() abstract method
Changes to localagent.py:
- Remove get_type() call
- Simplify top_k retrieval from KB entity
Deleted files:
- pkg/rag/knowledge/plugin_adapter.py
Benefits:
- Reduced abstraction layer, simpler code
- Plugin communication logic centralized in RuntimeKnowledgeBase
- Easier to understand and maintain
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(api): remove ExternalKnowledgeBase infrastructure
BREAKING CHANGE: ExternalKnowledgeBase has been completely removed.
All knowledge bases are now unified under the single KnowledgeBase model,
differentiated by their rag_engine_plugin_id.
Deleted files:
- pkg/api/http/controller/groups/knowledge/external.py
(ExternalKBController with /external-bases routes)
- pkg/api/http/service/external_kb.py
(ExternalKnowledgeBaseService)
- pkg/rag/knowledge/external.py
(ExternalKnowledgeBase implementation)
Modified files:
- pkg/entity/persistence/rag.py:
Remove ExternalKnowledgeBase SQLAlchemy table definition
- pkg/core/app.py:
Remove external_kb_service attribute from LangBotApplication
- pkg/core/stages/build_app.py:
Remove external_kb_service initialization
Migration notes:
- Existing external knowledge base data should be migrated manually
- API consumers should use /api/v1/knowledge/bases for all KB operations
- Use /api/v1/knowledge/engines to discover available RAG engines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(plugin): remove list_knowledge_retrievers from connector
Remove deprecated list_knowledge_retrievers functionality from the
plugin communication layer. This aligns with the SDK change that
removed the LIST_KNOWLEDGE_RETRIEVERS action.
Changes:
- connector.py: Remove list_knowledge_retrievers() method
- handler.py: Remove list_knowledge_retrievers() handler
The functionality is replaced by the new /api/v1/knowledge/engines
endpoint which lists available RAGEngine components with their
capabilities and configuration schemas.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(service): update knowledge service with capability-based checks
Replace type-based checks with capability-based checks for file
operations, aligning with the unified knowledge base architecture.
Changes to knowledge.py:
- store_file(): Replace get_type() check with doc_ingestion capability check
- delete_file(): Replace get_type() check with doc_ingestion capability check
- list_rag_engines(): Remove list_knowledge_retrievers call, simplify to
only list RAGEngine components (KnowledgeRetriever type removed)
Changes to pipelines.py:
- Minor cleanup related to knowledge base references
The capability-based approach allows RAG engines to declare their
supported features (doc_ingestion, chunking_config, rerank, hybrid_search)
and the system responds accordingly, rather than hardcoding behavior
based on internal/external type distinction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(web): unify knowledge base UI, remove external KB components
BREAKING CHANGE: The internal/external knowledge base distinction
has been removed from the frontend. All knowledge bases are now
displayed in a unified list, differentiated by their RAG engine.
Changes to page.tsx:
- Remove Tab component (内置/外置 tabs)
- Remove selectedKbType state
- Unified knowledge base list display
- Single "Create Knowledge Base" button for all types
Changes to KBDetailDialog.tsx:
- Remove kbType prop
- Simplify dialog logic for unified KB handling
- Documents menu item conditionally shown based on doc_ingestion capability
Changes to KBForm.tsx:
- Remove retriever type handling code
- Simplify form for unified KB creation
- Dynamic form rendering based on RAG engine's creation_schema
Changes to KBCardVO.ts:
- Remove 'type' field from KBCardVO interface
Changes to BackendClient.ts:
- Remove all external KB related methods:
- getExternalKnowledgeBases()
- getExternalKnowledgeBase()
- createExternalKnowledgeBase()
- updateExternalKnowledgeBase()
- deleteExternalKnowledgeBase()
- retrieveFromExternalKnowledgeBase()
Changes to api/index.ts:
- Remove ExternalKnowledgeBase interface definition
UI/UX improvements:
- Users no longer need to understand internal vs external distinction
- RAG engine selection is now the primary differentiator
- Documents panel visibility is capability-driven (doc_ingestion)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(plugin): code review improvements for RAG handlers
- Unify embed_model field naming to embedding_model_uuid only
- Add structured error responses with error_type for RAG actions
- Fix file_size and mime_type detection in _store_file_task
- Improve error handling with detailed error context (error_type, original_error)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(rag): refactor KB dynamic form and vector manager
- Frontend: Refactor Knowledge Base form using DynamicForm components.
- Frontend: Remove obsolete jsonSchemaConverter utility.
- Backend: Update VectorManager and PluginHandler to support new RAG architecture.
- Chore: Update dependencies in pyproject.toml.
* fix: code review fixes for RAG refactor
- Remove DEBUG stderr outputs in handler.py
- Move repeated `import json` to file top
- Add warning log for unimplemented delete_by_filter
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(rag): consolidate valid_fields into entity constants
Define MUTABLE_FIELDS, CREATE_FIELDS, ALL_DB_FIELDS as class
constants in KnowledgeBase entity to eliminate duplication.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: 将知识库获取和RAG引擎信息丰富逻辑移至知识库管理器。
* refactor(rag): introduce RAGRuntimeService and clean up plugin handler
- Create RAGRuntimeService to encapsulate RAG capability implementation (Embedding, VectorOps).
- Refactor PluginHandler to delegate RAG actions to RAGRuntimeService.
- Move KnowledgeService enrichment and creation logic to RAGManager.
- Register RAGRuntimeService in Application and BuildAppStage.
- Clean up legacy code in KnowledgeService.
* refactor(rag): standardize logger and fix type hints
- Use self.ap.logger consistently in kbmgr.py and runtime.py, removing module-level loggers.
- Fix type hints for retrieve_knowledge in handler.py and connector.py to match implementation returning dict.
* refactor: 将引擎徽章的样式从 Tailwind CSS 类迁移到 CSS 模块。
* fix(web): resolve React rendering errors in plugins page
- Fix missing key prop in PluginComponentList by using ternary instead of Fragment
- Fix RAGEngine.name type to I18nObject and use extractI18nObject() for rendering
- Preserves multi-language support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(rag): update runtime service and web components
* refactor: 优化知识库设置结构并增强前端距离显示健壮性。
* fix: 处理前端距离显示中的空值。
* fix(rag): document retrieve ui and kbmgr top_k validation
* 更新 uv.lock 中的 PyPI 镜像源为官方地址。
* fix: address code review issues for RAG engine plugin architecture
P0 fixes:
- Fix ALL_DB_FIELDS missing collection_id and emoji fields
- Move rag_engine_plugin_id to CREATE_FIELDS (immutable after creation)
- Fix creation_settings mutable default value (dict -> None)
- Rename vector delete method to delete_by_file_id for correct semantics
- Fix delete_by_filter to raise NotImplementedError instead of silent no-op
- Add database migration script (dbm019) for new columns and table cleanup
P1 fixes:
- Clean up design-hesitation comments in connector.py
- Add _parse_plugin_id() with format validation for all RAG methods
- Make _retrieve() raise exceptions instead of silently returning empty results
- Extract _make_rag_error_response() helper for clean error formatting
- Remove unused imports from handler.py
P2 fixes:
- Fix runtime.py indentation inconsistencies
- Simplify get_file_stream to use storage abstraction uniformly
- Reduce redundant DB queries in knowledge service (extract _check_doc_capability)
- Fix engines.py URL encoding: use <path:plugin_id> instead of __ replacement
- Add read-only mode for engine settings in KBForm edit mode
- Simplify page.tsx handleKBCardClick to pass only kbId string
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: address code review findings for RAG plugin architecture
- Frontend: add retrieval_settings param to retrieveKnowledgeBase API call
- Backend: return {uuid} from PUT knowledge base to match frontend expectation
- Backend: validate query is non-empty in retrieve endpoint (400 on empty)
- Backend: rename vector_delete ids→file_ids for semantic clarity, keep
backward compat by accepting both 'file_ids' and 'ids' in RPC handler
- Backend: ensure rag_engine.name fallback is always I18nObject-compatible
dict, preventing frontend extractI18nObject from receiving plain strings
- Migration: fix misleading docstring about external_kb data migration
Co-authored-by: Cursor <cursoragent@cursor.com>
* Update langbot-plugin version to 0.2.6
* chore: update required database version from 18 to 19
* refactor: remove unused polymorphic component framework
* chore: fix lint and format issues for python and frontend
* fix(plugin): remove legacy `ids` fallback in rag_vector_delete handler
SDK now sends `file_ids` directly, the `ids` backward-compat fallback
is no longer needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): deep review fixes for critical bugs, security and quality
Critical:
- Fix StorageMgr.load() -> storage_provider.load() (C1, AttributeError)
- Update required_database_version 18 -> 19 (C2, migration never runs)
Security:
- Add path traversal validation in get_file_stream (C11)
- Add vectors/ids/metadata length validation in rag_vector_upsert (C12)
Logic fixes:
- Legacy KBs: set capabilities to [] instead of ['doc_ingestion'] (C4)
- Fix store_file return type int -> str (C5)
- Fix retrieve_knowledge return [] -> {'results': []} when disabled (C6)
- Re-raise exception in _on_kb_create instead of silently swallowing (C7)
- Log warning when KB not found in memory during delete (C8)
API fixes:
- Catch ValueError as 400 in create_knowledge_base endpoint (C15)
- Validate plugin_id format in engines endpoints (C16)
Quality:
- Remove dead if/else in migration with identical branches (C17)
- Fix variable shadowing: rag_context -> rag_context_text (C18)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: remove unused os import to fix ruff lint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(plugin): remove PolymorphicComponent sync from LangBot side
Remove sync_polymorphic_component_instances() from connector and handler,
and the post-connection sync call in initialize(). This dead code synced
an always-empty list of polymorphic instances that were never created.
Companion change to langbot-plugin-sdk PolymorphicComponent removal.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): fix vector_delete count bug and remove vestigial instance_id parameter
1. vector_delete: assign return value from delete_by_filter to count
instead of silently returning 0 for filter-based deletion.
2. Remove instance_id parameter from the entire retrieve_knowledge
call chain (kbmgr → connector → handler → runtime). This parameter
was a remnant of the PolymorphicComponent mechanism and is no longer
used — RAGEngine operates as a stateless singleton.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(web): 支持 creation_schema 字段级别的 editable 属性控制编辑模式可修改性
- IDynamicFormItemSchema 添加 editable 可选属性
- DynamicFormItemConfig 透传 editable 属性
- DynamicFormComponent 接收 isEditing prop,按字段 editable 值控制禁用
- KBForm 解析 editable 并传递 isEditing 给动态表单组件
- editable 未指定时默认可编辑,editable: false 时编辑模式下禁用该字段
* feat(storage): 添加 size() 抽象方法及 LocalStorage/S3 实现
支持获取存储对象大小,S3 使用 head_object 避免下载整个文件
* fix(migration): 删除 external_knowledge_bases 表前记录日志警告
- 迁移时如果表中存在数据,先 warning 日志记录避免无感数据丢失
- 添加 chunk 清理注释说明:仅对旧版非插件架构 KB 有效
* fix(web): 修复检索结果长文本撑大容器导致查询按钮不可见
KBDetailDialog 的 main 容器添加 min-w-0 overflow-x-hidden,
限制 flex-1 子容器宽度,防止 Dify RAG 长文本撑出 Dialog 边界
* fix(rag): address code review issues for plugin architecture PR
- Fix SQL injection in migration helpers by using bind parameters
- Move numpy import to module level in vector/mgr.py
- Improve path traversal validation using posixpath.normpath
- Add call_rag_retrieve to connector, eliminating duplicate plugin_id
parsing in kbmgr.py _retrieve
- Normalize typing style to modern dict/list/None syntax
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(web): fix prettier formatting errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(rag): update embedding handling in RuntimeConnectionHandler
- Renamed RAG_EMBED_DOCUMENTS and RAG_EMBED_QUERY actions to INVOKE_EMBEDDING for clarity.
- Removed embed_documents and embed_query methods from RuntimeEmbeddingModel and RAGRuntimeService.
- Integrated embedding model retrieval directly in the invoke_embedding method, improving error handling for missing models.
- Updated the embedding invocation logic to streamline the process and enhance error reporting.
* refactor(web): replace KnowledgeRetriever with RAGEngine across frontend and tests
KnowledgeRetriever component type has been removed in favor of the new
RAGEngine architecture. Update all remaining references in i18n locales,
plugin component icon mappings, marketplace filter, and unit tests.
Addresses reviewer notes from RockChinQ on PR #1967.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): address critical bugs found in deep review
- Fix path traversal bypass in runtime.py (check all path components for '..')
- Use normalized path for file loading instead of raw user input
- Change knowledge_bases from list to dict for O(1) lookup and race safety
- Add rollback on KB creation failure (clean up DB + runtime on plugin error)
- Add null check after KB update in knowledge service
- Fix file extension parsing to use os.path.splitext instead of split('.')
(handles multi-dot filenames like 'report.v2.pdf' correctly)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): address remaining review issues across frontend and backend
Frontend:
- Fix KB delete: use async/await with error handling instead of fire-and-forget
- Fix capabilities null check: add optional chaining to prevent crash
- Add toast.error on KB info load failure instead of silent console.error
- Replace hard-coded Chinese validation message with i18n key
- Replace hard-coded English error messages in DynamicFormItemComponent with i18n
- Optimize document polling: stop when all documents reach terminal state
- Add i18n keys (fieldRequired, loadKnowledgeBaseFailed,
deleteKnowledgeBaseFailed, getKnowledgeBaseListError) to all 4 locales
Backend:
- Fix KB delete atomicity: delete from DB first, then notify plugin
- Add RAG engine plugin existence validation before creating KB
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(rag): fix ruff formatting in kbmgr.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* chore: bump langbot-plugin to 0.3.0 (#1992)
* chore: correct sdk version to 0.3.0a1
* feat: normalize rag related actions' names
* refactor(rag): align IngestionContext fields with SDK changes
Remove redundant `chunking_strategy` field and rename `custom_settings`
to `creation_settings` to match the updated SDK entity definitions
(langbot-plugin-sdk#36).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: fix ruff formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): enforce immutability of embedding_model_uuid and non-editable creation_settings fields
Remove embedding_model_uuid from MUTABLE_FIELDS to prevent post-creation
modification via API. Add backend validation for creation_settings to
preserve fields marked editable:false in the plugin's creation schema.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(rag): fix ruff formatting in knowledge service
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(rag): split settings into immutable creation_settings and mutable retrieval_settings
- Remove standalone embedding_model_uuid and top_k columns from KB entity
- Add retrieval_settings column; update MUTABLE_FIELDS/CREATE_FIELDS accordingly
- Merge migration logic into dbm019 (add retrieval_settings, migrate top_k
and embedding_model_uuid into JSON settings, drop old columns on PostgreSQL)
- Remove _filter_creation_settings and per-field editable concept
- Frontend: creation_settings fields are all disabled when editing,
retrieval_settings fields are always editable via a second DynamicFormComponent
- Remove editable from IDynamicFormItemSchema, DynamicFormItemConfig
- Clean up KBCardVO, KnowledgeBase API type, and localagent runner
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* bugfix: if ingest_document failed,not raise exep
* fix: ruff lint
* refactor(rag): remove unused _get_kb_entity method from RAGRuntimeService
* feat(vector): implement metadata filters for vector_search and vector_delete (#1997)
Add functional metadata filter support across all 5 VDB backends using
Chroma-style where syntax as the canonical format. Previously the filters
parameter existed throughout the stack but was entirely ignored.
- Add filter_utils.py with normalize_filter() and strip_unsupported_fields()
- Implement filter in search() and add delete_by_filter() for all backends:
Chroma/SeekDB (native passthrough), Qdrant (translated to models.Filter),
Milvus (translated to expr string), pgvector (translated to SQLAlchemy conditions)
- Milvus/pgvector limited to {text, file_id, chunk_uuid}; other fields logged and ignored
- Replace delete_by_filter() NotImplementedError with backend delegation in mgr.py
- Populate retrieval_context['filters'] from settings in kbmgr._retrieve()
- Pass search_type/query_text/documents through handler and runtime service
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(vector): fix ruff formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(vector): remove numpy dependency and fix SeekDB search modes
- Remove numpy array conversion for query vectors; all VDB backends
accept list[float] directly
- Remove redundant get_or_create_collection call from upsert; backends
handle collection creation internally in add_embeddings
- Fix SeekDB to raise ValueError when vector dimension is unknown
instead of defaulting to 384
- Use hybrid_search() for full-text and hybrid search modes in SeekDB,
since pyseekdb's query() always requires embeddings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(vector): escape single quotes in SeekDB documents and metadata
Document text containing apostrophes (e.g. "don't", "it's") causes
SQL syntax errors in OceanBase because single quotes were not in the
escape table. Add single-quote escaping and apply the escape table to
the documents parameter in add_embeddings(), not just metadata.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(vector): use standard SQL escaping for single quotes in SeekDB
Change single quote escaping from MySQL-style \' to standard SQL ''
(doubled quote). The backslash escape is not recognized by OceanBase
in NO_BACKSLASH_ESCAPES mode, causing SQL syntax errors when metadata
text contains apostrophes (e.g. O'Shea in academic citations).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): persist retrieval_settings on knowledge base creation
retrieval_settings was not being passed from the service layer to
RAGManager.create_knowledge_base(), causing retrieval schema fields
(e.g. query_rewrite) to be lost on initial KB creation. They only
took effect after a subsequent edit/update.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(web): add show_if conditional rendering for dynamic forms
Support conditional field visibility in plugin-defined forms via
show_if rules (eq, neq, in operators). Fields can depend on values
from the same form or cross-reference between creation and retrieval
settings via externalDependentValues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(rag): replace base64 with chunked file transfer for get_rag_file_stream
Use send_file() instead of base64 encoding for returning file content
in the GET_RAG_FILE_STREAM handler, avoiding memory issues with large files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(parser): add parser plugin integration and capability-aware upload UI (#2000)
* feat(parser): add parser plugin integration and capability-aware upload UI
Backend: add parser plugin API endpoints (list/invoke), connector and
handler support for parser actions, and KB manager passthrough.
Frontend: thread ragEngineCapabilities prop to FileUploadZone and use
doc_parsing capability to conditionally show the RAG engine option in
the parser selector. When no parser is available, show a warning
prompting users to install a parser plugin.
Update i18n: rename builtInParser to "Provided by RAG engine" and add
noParserAvailable warning message in all 4 locales.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(parser): replace base64 with chunked file transfer and remove stale cache
- Remove @alru_cache from list_parsers() and list_rag_engines()
- Replace inline base64 file content with send_file/read_local_file
chunked transfer pattern in parse_document and invoke_parser flows
- Remove unused base64 import from kbmgr.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(web): add Parser component kind to plugin market UI and i18n
Add Parser to kindIconMap, market filter toggle, and all 4 locale files
so parser plugins are properly displayed and filterable in the plugin
market, matching the existing RAGEngine treatment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(web): fix prettier formatting from merge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: rename RAGEngine to KnowledgeEngine across frontend and backend
* fix(web): fix I18nObject import path in FileUploadZone and KBDoc
* chore: format files involved in RAGEngine to KnowledgeEngine refactor
* refactor: change rag engine to knowledge engine
* fix: update langbot-plugin version to 0.3.0rc1
* chore: disable migration 20 for now
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* feat(chat): add runner_url to payload for telemetry tracking
* feat(telemetry): add runner_url to sanitized fields in telemetry payload
* feat(telemetry): replace runner_url with runner_category in telemetry payload and add runner utility functions
* fix:ruff
- Add the _extract_dify_text_output method to uniformly handle the parsing of Dify output content
- Modify the content extraction method for the answer node in workflow mode
- Add workflow mode detection logic to support the workflow_started event
- Handle error state checks upon completion of the workflow
- Improve the message chunking logic for both basic and workflow modes
- Add a mechanism to capture answer content upon completion of a workflow node
* feat(telegram): enhance message handling with markdown support and draft messages
* fix(telegram): update draft message ID generation to use current timestamp
Add rehype-sanitize after rehypeRaw in all ReactMarkdown usages:
- PluginReadme.tsx (plugin README rendering)
- DebugDialog.tsx (debug chat message rendering)
- NewVersionDialog.tsx (release notes rendering)
This prevents injection of raw HTML (e.g. <iframe srcdoc>) that
could steal session tokens and API credentials from localStorage.
Fixes GHSA-w8gq-g4pc-xh3h
Fixes#2014
When using default local storage, the s3storage module was imported
at the top level, which triggered boto3/botocore import and caused
ModuleNotFoundError if those packages weren't installed.
Now s3storage is only imported when S3 storage is actually configured.
* perf: reduce memory usage by ~200MB+ at startup
Two key optimizations:
1. Use importlib.util.find_spec() instead of __import__() in dependency
checking. find_spec() only locates modules without executing them,
avoiding loading all 36 dependencies (~222MB) into memory at startup.
2. Introduce shared aiohttp.ClientSession via httpclient module.
Previously, every HTTP request created a new ClientSession, which
creates a new TCPConnector and SSL context, loading system root
certificates each time (~270MB total allocations observed via memray).
Now all HTTP client code reuses shared sessions.
- satori.py and coze_server_api/client.py are left unchanged as they
create one session per adapter lifecycle (not per-request).
Profiling data (memray):
- Peak memory: 403MB
- SSL context creation: 270MB / 6.7M allocations (67% of total)
- Dependency import: 222MB (55% of peak)
- Expected reduction: 150-350MB at startup
* fix: remove unused aiohttp imports (ruff F401)
* style: ruff format
- Updated BOOLEAN case to default to false when field.value is undefined.
- Updated SELECT case to default to an empty string when field.value is undefined.
- Updated BotForm to serialize adapter_config for stable useEffect dependency.
- Refactored DynamicFormComponent to track last emitted values, avoiding unnecessary re-renders when form values remain unchanged.
* feat: add in-product survey system
- SurveyManager: event-based trigger, Space API communication
- Trigger on first successful non-WebSocket response
- Backend API: /api/v1/survey/{pending,respond,dismiss}
- Frontend: floating survey widget with progressive questions
- Flat radio/checkbox style (not dropdown Select)
* fix: persist triggered survey events to disk across restarts
Store triggered events in data/survey_triggered_events.json so that
restarting the process doesn't re-query Space for already-triggered events.
* fix: use metadata table for survey event persistence instead of file
Store triggered events in the existing metadata KV table
(key='survey_triggered_events') instead of a standalone JSON file.
* fix: ruff format and prettier fixes
* feat: add session message monitoring tab to bot detail dialog
Add a new "Sessions" tab in the bot detail dialog that displays
sent & received messages grouped by sessions. Users can select
any session to view its messages in a chat-bubble style layout.
Backend changes:
- Add sessionId filter to monitoring messages endpoint
- Add role column to MonitoringMessage (user/assistant)
- Record bot responses in monitoring via record_query_response()
- Add DB migration (dbm019) for the new role column
Frontend changes:
- New BotSessionMonitor component with session list + message viewer
- Add Sessions sidebar tab to BotDetailDialog
- Add getBotSessions/getSessionMessages API methods to BackendClient
- Add i18n translations (en-US, zh-Hans, zh-Hant, ja-JP)
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* refactor: remove outdated version comment from PipelineManager class
* fix: bump required_database_version to 19 to trigger monitoring_messages.role migration
* fix: prevent session message auto-scroll from pushing dialog content out of view
Replace scrollIntoView (which scrolls all ancestor containers) with
direct scrollTop manipulation on the ScrollArea viewport. This keeps
the scroll contained within the messages panel only.
* ui: redesign BotSessionMonitor with polished chat UI
- Wider session list (w-72) with avatar circles and cleaner layout
- Richer chat header with avatar, platform info, and active indicator
- User messages now use blue-500 (solid) instead of blue-100 for
clear visual distinction
- Metadata (time, runner) shown on hover below bubbles, not inside
- Proper empty state illustrations for both panels
- Better spacing, rounded corners, and shadow treatment
- Consistent dark mode styling
* fix: infinite re-render loop in DynamicFormComponent
The useEffect depended on onSubmit which was a new closure every
parent render. Calling onSubmit inside the effect triggered parent
state update → re-render → new onSubmit ref → effect re-runs → loop.
Fix: use useRef to hold a stable reference to onSubmit, removing it
from the useEffect dependency array.
Also add DialogDescription to BotDetailDialog to suppress Radix
aria-describedby warning.
* fix: remove .html suffix from docs.langbot.app links (Mintlify migration)
* style: fix prettier and ruff formatting
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
* feat(platform): add Forward message support for aiocqhttp adapter
- Add _send_forward_message method to send merged forward cards via OneBot API
- Support NapCat's send_forward_msg API with fallback to send_group_forward_msg
- Fix MessageChain deserialization for Forward messages in handler.py
- Properly deserialize nested ForwardMessageNode.message_chain to preserve data
This enables plugins to send QQ merged forward cards through the standard
LangBot send_message API using the Forward message component.
* style: fix ruff lint and format issues
- Remove f-string prefix from log message without placeholders
- Apply ruff format to aiocqhttp.py and handler.py
* refactor: remove custom deserializer, rely on SDK for Forward deserialization
- Remove _deserialize_message_chain from handler.py; use standard
MessageChain.model_validate() (Forward handling fixed in SDK via
langbot-app/langbot-plugin-sdk#38)
- Fix group_id type: use int instead of str for OneBot compatibility
- Add warning log when Forward message is used with non-group target
* chore: bump langbot-plugin to 0.2.7 (Forward deserialization fix)
---------
Co-authored-by: RockChinQ <rockchinq@gmail.com>
DynamicFormComponent uses form.watch(callback) to notify parent of form
values, but react-hook-form's watch callback only fires on subsequent
changes, not on mount. This causes PluginForm's currentFormValues to
remain as {} if the user saves without modifying any field, overwriting
the existing plugin config with an empty object in the database.
* fix: Add the file upload function and optimize the media message processing
* fix: Optimize the message processing logic, improve the concatenation of text elements and the sending of media messages
* fix: Simplify the file request construction and message processing logic to enhance code readability
- Added checks for maximum allowed extensions, bots, and pipelines in the backend services (PluginsRouterGroup, BotService, MCPService, PipelineService).
- Updated system configuration to include limitation settings for max_bots, max_pipelines, and max_extensions.
- Enhanced frontend components to handle limitations, providing user feedback when limits are reached.
- Added internationalization support for limitation messages in English, Japanese, Simplified Chinese, and Traditional Chinese.
* Initial plan
* Add monitoring tab to pipeline dialog with i18n support
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Fix prettier formatting for monitoring tab component
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Fix code review issues: use functional state updates and add comment for delay
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Update dependencies and enhance monitoring tab functionality
- Updated various package versions in pnpm-lock.yaml for improved compatibility and performance.
- Refactored PipelineDetailDialog to streamline WebSocket connection status display.
- Enhanced PipelineMonitoringTab to support navigation to detailed logs and improved UI elements.
- Added i18n support for 'Detailed Logs' in English, Japanese, Simplified Chinese, and Traditional Chinese locales.
* Fix lint errors: remove unused Button import and format en-US.ts
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
Co-authored-by: RockChinQ <rockchinq@gmail.com>
* feat: add card auto layout configuration for DingTalk adapter
* fix: correct card auto layout configuration key and improve related logic
* fix: simplify card auto layout configuration logic in create_and_card method
* fix: correct card auto layout key in DingTalk migration configuration
* fix: correct migration class name for DingTalk card auto layout
* fix: update migration version for DingTalk card auto layout
* fix: correct key name for card auto layout in DingTalk configuration
* fix: improve formatting and consistency in DingTalk card auto layout methods
- Updated create_llm_model method to include auto_set_to_default_pipeline parameter.
- Adjusted ModelManager to set auto_set_to_default_pipeline to False when creating models.
- Improved logic for setting the default pipeline model based on the new parameter.
- Introduced TagsFilter component for selecting and filtering plugins by tags.
- Updated PluginMarketComponent to handle tag selection and display.
- Enhanced PluginMarketCardComponent to show selected tags.
- Modified CloudServiceClient to fetch available tags from the API.
- Updated localization files to support new tag-related strings.
* feat: add emoji support to knowledge bases and pipelines
* feat: add optional emoji property to ExternalKBCardVO for enhanced knowledge base representation
* feat: add GitHub Actions workflow for linting with Ruff
* refactor: rename lint job and add formatting step to Ruff workflow
* chore: run ruff format
* chore: rename Ruff lint job to 'Lint' and add frontend linting workflow
- Add Milvus db_name configuration and client parameter support.
- change kb_data uuid for Milvus. 3. add MAX_BATCH_SIZE for openai.
- support more vector_size.
* feat: add telemetry support for query execution tracking and configuration
* feat: integrate telemetry manager and enable telemetry data sending
* feat: integrate telemetry manager and enhance error handling for telemetry sending
* feat: update telemetry configuration to use 'space' instead of 'telemetry' and adjust related parameters
* feat: integrate telemetry manager and enable telemetry data sending
* feat: integrate telemetry manager and enhance error handling for telemetry sending
* feat: add instance id
* feat: enhance telemetry management with asynchronous task handling and improve model retrieval caching
---------
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* feat: add SeekDB vector database support for knowledge bases
This commit adds complete integration of OceanBase's SeekDB as a vector
database option for LangBot's knowledge base feature.
## Changes
### Core Implementation
- Add SeekDB adapter implementing VectorDatabase interface
- Support both embedded and server deployment modes
- HNSW indexing with cosine similarity
- Async operations with error handling
- Comprehensive logging
### System Integration
- Register SeekDB in VectorDBManager
- Add pyseekdb>=0.1.0 dependency
- Add SeekDB configuration template
- Update README with vector database section
### Documentation
- Complete integration guide with platform compatibility warnings
- Configuration examples for all deployment modes
- Troubleshooting guide for common issues
- Code examples demonstrating usage patterns
- Comprehensive test reports and status documentation
## Testing
Architecture validated end-to-end using ChromaDB:
- File upload → parsing → chunking → embedding → storage
- 828 bytes → 3 chunks → 3 vectors stored successfully
- BGE-M3 model (384 dimensions)
- Status: Completed ✅
## Platform Compatibility
### Embedded Mode
- ✅ Linux: Fully supported
- ❌ macOS: Not supported (pylibseekdb is Linux-only)
- ❌ Windows: Not supported (pylibseekdb is Linux-only)
### Server Mode
- ✅ Linux: Fully supported
- ⚠️ macOS: Known issue (oceanbase/seekdb#36)
- ⚠️ Windows: Untested
### Remote Connection
- ✅ All platforms supported
## Known Issues
macOS Docker server mode affected by upstream bug:
https://github.com/oceanbase/seekdb/issues/36
Workaround: Use ChromaDB/Qdrant or connect to remote SeekDB server.
## Files Added
- src/langbot/pkg/vector/vdbs/seekdb.py
- docs/SEEKDB_INTEGRATION.md
- examples/seekdb_example.py
- SEEKDB_INTEGRATION_SUMMARY.md
- SEEKDB_INTEGRATION_COMPLETE.md
- SEEKDB_TEST_STATUS.md
- SEEKDB_FINAL_SUMMARY.md
- SEEKDB_INTEGRATION_DONE.md
- GITHUB_ISSUE_36_COMMENT.md
## Files Modified
- src/langbot/pkg/vector/mgr.py
- src/langbot/pkg/vector/vdbs/__init__.py
- pyproject.toml
- src/langbot/templates/config.yaml
- README.md
- README_EN.md
🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* chore: remove unused docs
* feature: minimal seekdb change (#1866)
* feat: add SeekDB embedding requester and configuration
This commit introduces a new SeekDB embedding requester, which utilizes the local embedding function from pyseekdb. It includes the necessary Python implementation and a corresponding YAML configuration file for integration. Additionally, a new SVG icon for SeekDB is added to enhance the visual representation in the UI.
* fix: update EmbeddingForm to conditionally render URL field based on model provider
This commit modifies the EmbeddingForm component to conditionally display the URL input field only when the current model provider is not 'seekdb-embedding'. Additionally, it updates the condition for rendering the API key field to exclude both 'ollama-chat' and 'seekdb-embedding' providers.
* chore: update Python version requirement in pyproject.toml to support Python 3.11
* fix: add config default value, when it makes fronted not show spec
* fix: seekdb.py clean metadata. change api
* fix: enhance error handling in SeekDB embedding initialization
This commit adds improved error handling to the SeekDB embedding function. It ensures that a RuntimeError is raised if the embedding function fails to initialize, and wraps the embedding call in a try-except block to catch and raise a RequesterError with a descriptive message in case of failure.
* refactor: update SeekDB database management to use AdminClient
This commit refactors the SeekDB database management logic to utilize the AdminClient for database operations. It replaces the previous temp_client with admin_client for listing and creating databases, ensuring a more robust interaction with the SeekDB API.
* refactor: update SeekDB embedding model initialization to use task manager
This commit refactors the SeekDB embedding model initialization by replacing the direct asyncio task creation with the task manager's create_task method. This change enhances task management and provides a clearer naming convention for the embedding model initialization task.
* perf: integration
* chore: remove unnecessary files
* fix: linter errors
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
Co-authored-by: 名为a的全局变量 <1051233107@qq.com>
* Expanded WeCom message parsing to capture msgtype, inline voice/video/file/link data, bounded base64 downloads, and richer mixed-message attachments (src/langbot/libs/wecom_ai_bot_api/api.py); added event accessors for new fields (src/langbot/libs/wecom_ai_bot_api/wecombotevent.py).
Converter now maps richer WeCom payloads (text, images, files, voice, video, links) into platform message chain with fallbacks when nothing parsable is present (src/langbot/pkg/platform/sources/wecombot.py).
Preprocessor now turns voice inputs into file URLs for downstream runners (src/langbot/pkg/pipeline/preproc/preproc.py).
Dify runner uploads all incoming files (images/audio/video/docs) after downloading or decoding data URLs, infers MIME types, and passes typed file descriptors into chat/workflow calls (src/langbot/pkg/provider/runners/difysvapi.py).
* Update src/langbot/pkg/platform/sources/wecombot.py
Fixed the issue of duplicate text in the comments.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/langbot/libs/wecom_ai_bot_api/api.py
Modify the way you approach challenges.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/langbot/pkg/platform/sources/wecombot.py
Changing the variable names makes more sense.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat: use from_base64 for the voice file converting
---------
Co-authored-by: tabriswang <tabriswang@finecomn.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* feat(platform): add skip_pipeline parameter for webhook responses
Add support for skip_pipeline parameter in webhook responses, allowing
webhook targets to instruct LangBot to skip pipeline processing for
specific messages. When a webhook responds with skip_pipeline=true,
the message is treated as a notification only and bypasses the query pool.
Changes:
- webhook_pusher.py: Parse JSON responses and return skip_pipeline flag
- botmgr.py: Check skip_pipeline before adding messages to query pool
- docker-compose.yaml: Add DNS configuration to fix container networking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: webhook crud bug
* chore: revert docker-compose.yaml
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Initial plan
* Add backend support for external knowledge bases
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Add frontend support for external knowledge bases with tabs UI
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Add i18n translations for all languages (Traditional Chinese and Japanese)
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Update knowledge base tab list styling to match plugins page
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* perf: margin-top for kb page
* refactor: switch RetrievalResultEntry to langbot_plugin pkg ones
* feat: knowledge retriever listing and creating
* stash
* refactor: unify sync mechanism for polymorphic components
* feat: use unified retireval result struct in retrieval test page
* chore: remove unused methods
* feat: retriever icon displaying
* feat: localagent retrieval with external kbs
* chore: bump version of langbot-plugin to 0.2.0b1
* fix: i18n
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* Initial plan
* feat: add model_config parameter support for Dify assistant type
- Add model_config parameter to AsyncDifyServiceClient.chat_messages method
- Add _get_model_config helper method to DifyServiceAPIRunner
- Pass model_config from pipeline configuration to all chat_messages calls
- Add model-config configuration field to dify-service-api schema in ai.yaml
- Support optional model configuration for assistant type apps in open-source Dify
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* refactor: improve model_config implementation based on code review
- Simplify _get_model_config method logic
- Add more descriptive comment about model_config usage
- Clarify when model_config is used (assistant type apps)
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* feat: only modify client.py
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* fix: fix n8n streaming support issue
Add streaming support detection and proper message type handling for
n8n service API runner. Previously, when streaming was enabled, n8n
integration would fail due to incorrect message type usage.
1. Added streaming capability detection by checking adapter's
is_stream_output_supported method
2. Implemented conditional message generation using MessageChunk for
streaming mode and Message for non-streaming mode
3. Added proper error handling for adapters that don't support streaming
detection
* fix: add n8n webhook streaming model ,Optimized the streaming output when calling n8n.
---------
Co-authored-by: Dong_master <2213070223@qq.com>
- Replace plugin detail dialog with hover buttons interaction
- Add "Install" and "View Details" hover buttons on plugin cards
- Remove PluginDetailDialog component
- Update plugin marketplace URL format to /market/{author}/{plugin}
- Redirect all plugin detail views to LangBot Space
- Add i18n support for 4 languages (zh-Hans, en-US, zh-Hant, ja-JP)
- Optimize hover overlay styles for light/dark theme
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Initial plan
* Add package structure and resource path utilities
- Created langbot/ package with __init__.py and __main__.py entry point
- Added paths utility to find frontend and resource files from package installation
- Updated config loading to use resource paths
- Updated frontend serving to use resource paths
- Added MANIFEST.in for package data inclusion
- Updated pyproject.toml with build system and entry points
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Add PyPI publishing workflow and update license
- Created GitHub Actions workflow to build frontend and publish to PyPI
- Added license field to pyproject.toml to fix deprecation warning
- Updated .gitignore to exclude build artifacts
- Tested package building successfully
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Add PyPI installation documentation
- Created PYPI_INSTALLATION.md with detailed installation and usage instructions
- Updated README.md to feature uvx/pip installation as recommended method
- Updated README_EN.md with same changes for English documentation
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Address code review feedback
- Made package-data configuration more specific to langbot package only
- Improved path detection with caching to avoid repeated file I/O
- Removed sys.path searching which was incorrect for package data
- Removed interactive input() call for non-interactive environment compatibility
- Simplified error messages for version check
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Fix code review issues
- Use specific exception types instead of bare except
- Fix misleading comments about directory levels
- Remove redundant existence check before makedirs with exist_ok=True
- Use context manager for file opening to ensure proper cleanup
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Simplify package configuration and document behavioral differences
- Removed redundant package-data configuration, relying on MANIFEST.in
- Added documentation about behavioral differences between package and source installation
- Clarified that include-package-data=true uses MANIFEST.in for data files
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* chore: update pyproject.toml
* chore: try pack templates in langbot/
* chore: update
* chore: update
* chore: update
* chore: update
* chore: update
* chore: adjust dir structure
* chore: fix imports
* fix: read default-pipeline-config.json
* fix: read default-pipeline-config.json
* fix: tests
* ci: publish pypi
* chore: bump version 4.6.0-beta.1 for testing
* chore: add templates/**
* fix: send adapters and requesters icons
* chore: bump version 4.6.0b2 for testing
* chore: add platform field for docker-compose.yaml
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* Initial plan
* feat: Add hover card with model details to embedding model selector in KB form
- Updated KBForm.tsx to fetch full EmbeddingModel objects instead of simplified entities
- Added HoverCard component to show model details (icon, description, base URL, extra args) when hovering over embedding model options
- Removed unused IEmbeddingModelEntity import and embeddingModelNameList state
- Made the embedding model selector consistent with LLM model selector behavior
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* fix:Fixed the issue where the rich text processing in the DingTalk API did not account for multiple texts and images, as well as the presence of default line breaks. Also resolved the error in Dify caused by sending only images, which resulted in an empty query.
* fix:Considering the various possible scenarios, there are cases where plan_text is empty when there is file content, and there is no file (the message could not be parsed) and the content is empty.
* fix:Add the default modifiable prompt input for didify in the ai.yaml file to ensure that the error of query being empty occurs when receiving data.
* add: The config migration of Dify
* fix:Migration issue
* perf: minor fix
* chore: minor fix
---------
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* Initial plan
* Add multi-knowledge base support to pipelines
- Created database migration dbm010 to convert knowledge-base field from string to array
- Updated default pipeline config to use knowledge-bases array
- Updated pipeline metadata to use knowledge-base-multi-selector type
- Modified localagent.py to retrieve from multiple knowledge bases and concatenate results
- Added KNOWLEDGE_BASE_MULTI_SELECTOR type to frontend form entities
- Implemented multi-selector UI component with dialog for selecting multiple knowledge bases
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Add i18n translations for multi-knowledge base selector
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Fix prettier formatting errors in DynamicFormItemComponent
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* Add accessibility attributes to knowledge base selector checkbox
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
* fix: minor fix
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com>
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* feat:add coze api client and coze runner and coze config
* del print
* fix:Change the default setting of the plugin system to true
* fix:del multimodal-support config, default multimodal-support,and in cozeapi.py Obtain timeout and auto-save-history config
* chore: add comment for coze.com
---------
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* feat:add coze api client and coze runner and coze config
* del print
* fix:Change the default setting of the plugin system to true
* fix:del multimodal-support config, default multimodal-support,and in cozeapi.py Obtain timeout and auto-save-history config
* chore: add comment for coze.com
---------
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* feat: add comprehensive unit tests for pipeline stages
* fix: deps install in ci
* ci: use venv
* ci: run run_tests.sh
* fix: resolve circular import issues in pipeline tests
Update all test files to use lazy imports via importlib.import_module()
to avoid circular dependency errors. Fix mock_conversation fixture to
properly mock list.copy() method.
Changes:
- Use lazy import pattern in all test files
- Fix conftest.py fixture for conversation messages
- Add integration test file for full import tests
- Update documentation with known issues and workarounds
Tests now successfully avoid circular import errors while maintaining
full test coverage of pipeline stages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: add comprehensive testing summary
Document implementation details, challenges, solutions, and future
improvements for the pipeline unit test suite.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: rewrite unit tests to test actual pipeline stage code
Rewrote unit tests to properly test real stage implementations instead of
mock logic:
- Test actual BanSessionCheckStage with 7 test cases (100% coverage)
- Test actual RateLimit stage with 3 test cases (70% coverage)
- Test actual PipelineManager with 5 test cases
- Use lazy imports via import_module to avoid circular dependencies
- Import pipelinemgr first to ensure proper stage registration
- Use Query.model_construct() to bypass Pydantic validation in tests
- Remove obsolete pure unit tests that didn't test real code
- All 20 tests passing with 48% overall pipeline coverage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: add unit tests for GroupRespondRuleCheckStage
Added comprehensive unit tests for resprule stage:
- Test person message skips rule check
- Test group message with no matching rules (INTERRUPT)
- Test group message with matching rule (CONTINUE)
- Test AtBotRule removes At component correctly
- Test AtBotRule when no At component present
Coverage: 100% on resprule.py and atbot.py
All 25 tests passing with 51% overall pipeline coverage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: restructure tests to tests/unit_tests/pipeline
Reorganized test directory structure to support multiple test categories:
- Move tests/pipeline → tests/unit_tests/pipeline
- Rename .github/workflows/pipeline-tests.yml → run-tests.yml
- Update run_tests.sh to run all unit tests (not just pipeline)
- Update workflow to trigger on all pkg/** and tests/** changes
- Coverage now tracks entire pkg/ module instead of just pipeline
This structure allows for easy addition of more unit tests for other
modules in the future.
All 25 tests passing with 21% overall pkg coverage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* ci: upload codecov report
* ci: codecov file
* ci: coverage.xml
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat:line adapter and config
* fix:After receiving the message, decode it and handle it as "message_chain"
* feat:add line-bot-sdk
* del print
* feat: add image to base64
* fix: download image to base64
* del Convert binary data to a base64 string
* del print
* perf: i18n specs for zh_Hant and ja_JP
* fix:line adapter Plugin system
---------
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
* feat: add GitHub star count component to sidebar
- Add GitHub star component to sidebar bottom section
- Fetch star count from space.langbot.app API
- Display star count with proper internationalization
- Open GitHub repository in new tab when clicked
- Follow existing sidebar styling patterns
Co-Authored-By: Rock <rockchinq@gmail.com>
* perf: ui
* chore: remove githubStars text
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rock <rockchinq@gmail.com>
* feat: add ZIP file upload support for knowledge base
- Add _parse_zip method to FileParser class using zipfile library
- Support extraction and processing of TXT, PDF, DOCX, MD, HTML files from ZIP
- Update FileUploadZone to accept .zip files
- Add ZIP format to supported formats in internationalization files
- Implement error handling for invalid ZIP files and unsupported content
- Follow existing async parsing patterns and error handling conventions
Co-Authored-By: Rock <rockchinq@gmail.com>
* refactor: modify ZIP processing to store each document as separate file
- Remove _parse_zip method from FileParser as ZIP handling now occurs at knowledge base level
- Add _store_zip_file method to RuntimeKnowledgeBase to extract and store each document separately
- Each document in ZIP is now stored as individual file entry in knowledge base
- Process ZIP files in memory using io.BytesIO to avoid filesystem writes
- Generate unique file names for extracted documents to prevent conflicts
Co-Authored-By: Rock <rockchinq@gmail.com>
* perf: delete temp files
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rock <rockchinq@gmail.com>
* fix: update invoke_embedding to return only embeddings from client.embed
* fix: Fixed the incorrect extraction method of sender ID when converting aiocqhttp reply messages
- Add password change button to sidebar account menu
- Create PasswordChangeDialog component with shadcn UI components
- Implement backend API endpoint /api/v1/user/change-password
- Add form validation with current password verification
- Include internationalization support for Chinese and English
- Add proper error handling and success notifications
Co-Authored-By: Rock <rockchinq@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Junyan Qin <Chin>, u79E6u9A8Fu8A00 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* feat: add pipeline sorting functionality with three sort options
Co-Authored-By: Junyan Qin <Chin>, u79E6u9A8Fu8A00 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* perf: ui
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Junyan Qin <Chin>, u79E6u9A8Fu8A00 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* converters could use the application logger
* keep @targets in message for some plugins may need it to their functionality
* fix:form wxid in config
fix:传参问题,可以直接从config中拿到wxid
---------
Co-authored-by: fdc310 <82008029+fdc310@users.noreply.github.com>
- Implement DiscordMessageConverter for message conversion
- Support image handling from base64, URL, and file paths
- Add DiscordEventConverter for event conversion
- Implement DiscordAdapter for Discord bot integration
- Support DM and TextChannel message handling
* feat:add onebotv11 face send and accept but some face no name.
* add face annotation
* add face_code_dict
* add some face in image can't download,so pass on face
* fix:Pass the face_id to face
-In the ContentFilterStage, logic for handling empty messages has been added to ensure that the pipeline continues to process even when the message is empty.
- This change enhances the robustness of content filtering, preventing potential issues caused by empty messages.
- This optimization was implemented to address the issue where, when someone is @ in a group chat and a message is sent without any content, the Source type messages in the message chain are lost.
* feat: add Japanese (ja-JP) language support
- Add comprehensive Japanese translation file (ja-JP.ts)
- Update i18n configuration to include Japanese locale
- Add Japanese language option to login and register page dropdowns
- Implement Japanese language detection and switching logic
- Maintain fallback to en-US for missing translations in flexible components
Co-Authored-By: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* perf: ui for ja-JP
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
- Replace hardcoded base URL in HttpClient.ts with environment variable support
- Add NEXT_PUBLIC_API_BASE_URL environment variable for dynamic configuration
- Add dev:local script for development with localhost:5300 backend
- Development: uses localhost:5300, Production: uses / (relative path)
- Eliminates need for manual code changes when switching environments
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* feat: add WebChat adapter for pipeline debugging
- Create WebChatAdapter for handling debug messages in pipeline testing
- Add HTTP API endpoints for debug message sending and retrieval
- Implement frontend debug dialog with session switching (private/group chat)
- Add Chinese i18n translations for debug interface
- Auto-create default WebChat bot during database initialization
- Support fixed session IDs: webchatperson and webchatgroup for testing
Co-Authored-By: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* perf: ui for webchat
* feat: complete webchat backend
* feat: core chat apis
* perf: button style in pipeline card
* perf: log btn in bot card
* perf: webchat entities definition
* fix: bugs
* perf: web chat
* perf: dialog styles
* perf: styles
* perf: styles
* fix: group invalid in webchat
* perf: simulate real im message
* perf: group timeout toast
* feat(webchat): add supports for mentioning bot in group
* perf(webchat): at component styles
* perf: at badge display in message
* fix: linter errors
* fix: webchat was listed on adapter list
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* feat: add i18n support for initialization page and fix plugin loading text
- Add language selector to register/initialization page with Chinese and English options
- Add register section translations to both zh-Hans.ts and en-US.ts
- Replace hardcoded Chinese texts in register page with i18n translation calls
- Fix hardcoded '加载中...' text in plugin configuration dialog to use t('plugins.loading')
- Follow existing login page pattern for language selector implementation
- Maintain consistent UI/UX design with proper language switching functionality
Co-Authored-By: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* perf: language selecting logic
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
- Add language selector to register/initialization page with Chinese and English options
- Add register section translations to both zh-Hans.ts and en-US.ts
- Replace hardcoded Chinese texts in register page with i18n translation calls
- Fix hardcoded '加载中...' text in plugin configuration dialog to use t('plugins.loading')
- Follow existing login page pattern for language selector implementation
- Maintain consistent UI/UX design with proper language switching functionality
Co-Authored-By: Junyan Qin <Chin>, 秦骏言 in Chinese, you can call me my english name Rock Chin. <rockchinq@gmail.com>
* chore: set Python version to 3.10
* feat: add pyproject.toml for project configuration and dependencies
* style: streamline bot retrieval and update logic in PipelineService
* feat: update dependencies and configuration for ruff and pip
* chore: remove ruff configuration file
* style: change quote style from single to double in ruff configuration
* style: unify string quote style to double quotes across multiple files
* chore: update .gitignore to include .venv and uv.lock
* chore: remove unused configuration files and clean up project structure
* chore: revert quote-style to `single`
* chore: set default python version to 3.12
---------
Co-authored-by: Junyan Qin <rockchinq@gmail.com>
- Improved formatting and consistency in BotConfigPage, HomeSidebar, and Plugin components.
- Removed unnecessary Spin component to prevent layout collapse in BotConfigPage.
- Enhanced sidebar selection logic to reflect current URL path in HomeSidebar.
- Updated layout styles for better responsiveness and visual appeal.
- Implemented mock data fetching in PluginMarketComponent for improved testing and development.
- Added pagination and search functionality in PluginMarketComponent.
- Refactored PluginInstalledComponent to streamline plugin list rendering and modal handling.
- Adjusted CSS styles for better alignment and spacing in various components.
- Removed commented-out code in HttpClient for cleaner codebase.
- Enhanced NotFound component layout for better user experience.
- Create a custom SSL context using certifi for proper HTTPS certificate verification, meow - Add the ssl parameter to aiohttp requests to prevent download failure due to missing root certificates, meow - Improve error messages and enhance the overall plugin installation process, meow!
fix: ensure content is string in chatcmpl call method
- Ensure user message content is a string instead of an array
- Updated `call` method in `chatcmpl.py` to guarantee content is a string
- Resolves compatibility issue with the yi-large model
description:Report bugs or vulnerabilities using this template. For container network connection issues, refer to the documentation https://link.langbot.app/en/docs/network
title:"[Bug]: "
labels:["bug?"]
body:
- type:input
attributes:
label:Runtime environment
description:LangBot version, operating system, system architecture, **Python version**, **host location**
> Please paste the screenshots of changes before and after here (can be interface screenshots, console output, conversation screenshots, etc.):
>
> 修改前 / Before:
>
> 修改后 / After:
>
## 以下内容可在起草PR后、合并PR前逐步完成
## 检查清单 / Checklist
### 功能
### PR 作者完成 / For PR author
- [ ] 已编写完善的配置文件字段说明(若有新增)
- [ ] 已编写面向用户的新功能说明(若有必要)
- [ ] 已测试新功能或更改
*请在方括号间写`x`以打勾 / Please tick the box with `x`*
### 兼容性
- [ ] 阅读仓库[贡献指引](https://github.com/langbot-app/LangBot/blob/master/CONTRIBUTING.md)了吗? / Have you read the [contribution guide](https://github.com/langbot-app/LangBot/blob/master/CONTRIBUTING.md)?
- [ ] 与项目所有者沟通过了吗? / Have you communicated with the project maintainer?
- [ ] 我确定已自行测试所作的更改,确保功能符合预期。 / I have tested the changes and ensured they work as expected.
- [ ] 已处理版本兼容性
- [ ] 已处理插件兼容问题
### 项目维护者完成 / For project maintainer
### 风险
可能导致或已知的问题:
- [ ] 相关 issues 链接了吗? / Have you linked the related issues?
- [ ] 配置项写好了吗?迁移写好了吗?生效了吗? / Have you written the configuration items? Have you written the migration? Has it taken effect?
- [ ] 依赖加到 pyproject.toml 和 core/bootutils/deps.py 了吗 / Have you added the dependencies to pyproject.toml and core/bootutils/deps.py?
- [ ] 文档编写了吗? / Have you written the documentation?
This file is for guiding code agents (like Claude Code, GitHub Copilot, OpenAI Codex, etc.) to work in LangBot project.
## Project Overview
LangBot is a open-source LLM native instant messaging bot development platform, aiming to provide an out-of-the-box IM robot development experience, with Agent, RAG, MCP and other LLM application functions, supporting global instant messaging platforms, and providing rich API interfaces, supporting custom development.
LangBot has a comprehensive frontend, all operations can be performed through the frontend. The project splited into these major parts:
-`./src/langbot`: The main python package of the project, below are the main modules in this package:
-`./pkg`: The core python package of the project backend.
-`./pkg/platform`: The platform module of the project, containing the logic of message platform adapters, bot managers, message session managers, etc.
-`./pkg/provider`: The provider module of the project, containing the logic of LLM providers, tool providers, etc.
-`./pkg/pipeline`: The pipeline module of the project, containing the logic of pipelines, stages, query pool, etc.
-`./pkg/api`: The api module of the project, containing the http api controllers and services.
-`./pkg/plugin`: LangBot bridge for connecting with plugin system.
-`./libs`: Some SDKs we previously developed for the project, such as `qq_official_api`, `wecom_api`, etc.
-`./templates`: Templates of config files, components, etc.
-`./web`: Frontend codebase, built with Next.js + **shadcn** + **Tailwind CSS**.
-`./docker`: docker-compose deployment files.
## Backend Development
We use `uv` to manage dependencies.
```bash
pip install uv
uv sync --dev
```
Start the backend and run the project in development mode.
```bash
uv run main.py
```
Then you can access the project at `http://127.0.0.1:5300`.
## Frontend Development
We use `pnpm` to manage dependencies.
```bash
cd web
cp .env.example .env
pnpm install
pnpm dev
```
Then you can access the project at `http://127.0.0.1:3000`.
## Plugin System Architecture
LangBot is composed of various internal components such as Large Language Model tools, commands, messaging platform adapters, LLM requesters, and more. To meet extensibility and flexibility requirements, we have implemented a production-grade plugin system.
Each plugin runs in an independent process, managed uniformly by the Plugin Runtime. It has two operating modes: `stdio` and `websocket`. When LangBot is started directly by users (not running in a container), it uses `stdio` mode, which is common for personal users or lightweight environments. When LangBot runs in a container, it uses `websocket` mode, designed specifically for production environments.
Plugin Runtime automatically starts each installed plugin and interacts through stdio. In plugin development scenarios, developers can use the lbp command-line tool to start plugins and connect to the running Runtime via WebSocket for debugging.
> Plugin SDK, CLI, Runtime, and entities definitions shared between LangBot and plugins are contained in the [`langbot-plugin-sdk`](https://github.com/langbot-app/langbot-plugin-sdk) repository.
## Some Development Tips and Standards
- LangBot is a global project, any comments in code should be in English, and user experience should be considered in all aspects.
- Thus you should consider the i18n support in all aspects.
- LangBot is widely adopted in both toC and toB scenarios, so you should consider the compatibility and security in all aspects.
- If you were asked to make a commit, please follow the commit message format:
- format: <type>(<scope>): <subject>
- type: must be a specific type, such as feat (new feature), fix (bug fix), docs (documentation), style (code style), refactor (refactoring), perf (performance optimization), etc.
- scope: the scope of the commit, such as the package name, the file name, the function name, the class name, the module name, etc.
- subject: the subject of the commit, such as the description of the commit, the reason for the commit, the impact of the commit, etc.
- LangBot uses [Alembic](https://alembic.sqlalchemy.org/) to manage database migrations, supporting both SQLite and PostgreSQL. Migration files are located in `src/langbot/pkg/persistence/alembic/versions/`. If you changed the definition of database entities (ORM models), generate a new migration script by running `uv run python -m langbot.pkg.persistence.alembic_runner autogenerate "description of your change"` in the project root (requires `data/config.yaml` to exist). Review and edit the generated script before committing. Migrations are executed automatically on LangBot startup. For data migrations (e.g. modifying JSON field content), you need to manually add the migration code in the generated script.
[](https://github.com/langbot-app/LangBot/releases/latest)
[](https://github.com/RockChinQ/QChatGPT/releases/latest)
LangBot is an **open-source, production-grade platform** for building AI-powered instant messaging bots. It connects Large Language Models (LLMs) to any chat platform, enabling you to create intelligent agents that can converse, execute tasks, and integrate with your existing workflows.
- **AI Conversations & Agents** — Multi-turn dialogues, tool calling, multi-modal support, streaming output. Built-in RAG (knowledge base) with deep integration to [Dify](https://dify.ai), [Coze](https://coze.com), [n8n](https://n8n.io), [Langflow](https://langflow.org).
- **Universal IM Platform Support** — One codebase for Discord, Telegram, Slack, LINE, QQ, WeChat, WeCom, Lark, DingTalk, KOOK.
- **Production-Ready** — Access control, rate limiting, sensitive word filtering, comprehensive monitoring, and exception handling. Trusted by enterprises.
- **Plugin Ecosystem** — Hundreds of plugins, event-driven architecture, component extensions, and [MCP protocol](https://modelcontextprotocol.io/) support.
- **Web Management Panel** — Configure, manage, and monitor your bots through an intuitive browser interface. No YAML editing required.
- **Multi-Pipeline Architecture** — Different bots for different scenarios, with comprehensive monitoring and exception handling.
<details>
<summary>点击此处展开</summary>
[→ Learn more about all features](https://link.langbot.app/en/docs/features)
| Matrix | ✅ | Supports multiple bridged platforms such as Signal, WhatsApp, Messenger, iMessage, Mattermost, Google Chat, IRC, XMPP, Zulip, and more |
- 如报错`TypeError: As of 3.10, the *loop* parameter was removed from Lock() since it is no longer necessary`, 请参考 [此处](https://github.com/RockChinQ/QChatGPT/issues/5)
[](https://github.com/langbot-app/LangBot/releases/latest)
If you're a code agent based on LLM, you should read [AGENTS.md](AGENTS.md) to understand the project structure and development process before you start any development.
[](https://github.com/langbot-app/LangBot/releases/latest)
<a href="https://space.langbot.app">Mercado de Plugins</a> |
<a href="https://langbot.featurebase.app/roadmap">Hoja de Ruta</a>
</div>
</p>
---
## ¿Qué es LangBot?
LangBot es una **plataforma de código abierto y grado de producción** para construir bots de mensajería instantánea impulsados por IA. Conecta modelos de lenguaje de gran escala (LLMs) con cualquier plataforma de chat, permitiéndole crear agentes inteligentes que pueden conversar, ejecutar tareas e integrarse con sus flujos de trabajo existentes.
### Capacidades Clave
- **Conversaciones e Agentes IA** — Diálogos de múltiples turnos, llamadas a herramientas, soporte multimodal, salida en streaming. RAG (base de conocimientos) incorporado con integración profunda con [Dify](https://dify.ai), [Coze](https://coze.com), [n8n](https://n8n.io), [Langflow](https://langflow.org).
- **Soporte Universal de Plataformas de MI** — Un solo código base para Discord, Telegram, Slack, LINE, QQ, WeChat, WeCom, Lark, DingTalk, KOOK.
- **Listo para Producción** — Control de acceso, limitación de velocidad, filtrado de palabras sensibles, monitoreo completo y manejo de excepciones. De confianza para empresas.
- **Ecosistema de Plugins** — Cientos de plugins, arquitectura basada en eventos, extensiones de componentes y soporte del [protocolo MCP](https://modelcontextprotocol.io/).
- **Panel de Gestión Web** — Configure, gestione y monitoree sus bots a través de una interfaz de navegador intuitiva. Sin necesidad de editar YAML.
- **Arquitectura Multi-Pipeline** — Diferentes bots para diferentes escenarios, con monitoreo completo y manejo de excepciones.
[→ Conocer más sobre todas las funcionalidades](https://link.langbot.app/en/docs/features)
---
## Inicio Rápido
### ☁️ LangBot Cloud (Recomendado)
**[LangBot Cloud](https://space.langbot.app/cloud)** — Sin despliegue, listo para usar.
[](https://github.com/langbot-app/LangBot/releases/latest)
<a href="https://space.langbot.app">Marché des Plugins</a> |
<a href="https://langbot.featurebase.app/roadmap">Feuille de Route</a>
</div>
</p>
---
## Qu'est-ce que LangBot ?
LangBot est une **plateforme open-source de niveau production** pour créer des bots de messagerie instantanée alimentés par l'IA. Elle connecte les grands modèles de langage (LLMs) à n'importe quelle plateforme de chat, vous permettant de créer des agents intelligents capables de converser, d'exécuter des tâches et de s'intégrer à vos workflows existants.
### Capacités Clés
- **Conversations IA & Agents** — Dialogues multi-tours, appels d'outils, support multimodal, sortie en streaming. RAG (base de connaissances) intégré avec intégration profonde de [Dify](https://dify.ai), [Coze](https://coze.com), [n8n](https://n8n.io), [Langflow](https://langflow.org).
- **Support Universel des Plateformes de MI** — Un seul code pour Discord, Telegram, Slack, LINE, QQ, WeChat, WeCom, Lark, DingTalk, KOOK.
- **Prêt pour la Production** — Contrôle d'accès, limitation de débit, filtrage de mots sensibles, surveillance complète et gestion des exceptions. Approuvé par les entreprises.
- **Écosystème de Plugins** — Des centaines de plugins, architecture événementielle, extensions de composants, et support du [protocole MCP](https://modelcontextprotocol.io/).
- **Panneau de Gestion Web** — Configurez, gérez et surveillez vos bots via une interface navigateur intuitive. Aucune édition de YAML requise.
- **Architecture Multi-Pipeline** — Différents bots pour différents scénarios, avec surveillance complète et gestion des exceptions.
[→ En savoir plus sur toutes les fonctionnalités](https://link.langbot.app/en/docs/features)
---
## Démarrage Rapide
### ☁️ LangBot Cloud (Recommandé)
**[LangBot Cloud](https://space.langbot.app/cloud)** — Sans déploiement, prêt à utiliser.
### Lancement en une ligne
```bash
uvx langbot
```
> Nécessite [uv](https://docs.astral.sh/uv/getting-started/installation/). Visitez http://localhost:5300 — c'est prêt.
### Docker Compose
```bash
git clone https://github.com/langbot-app/LangBot
cd LangBot/docker
docker compose up -d
```
### Déploiement Cloud en un Clic
[](https://zeabur.com/en-US/templates/ZKTBDH)
[](https://railway.app/template/yRrAyL?referralCode=vogKPF)
| Matrix | ✅ | Prend en charge plusieurs plateformes via ponts, comme Signal, WhatsApp, Messenger, iMessage, Mattermost, Google Chat, IRC, XMPP, Zulip, etc. |
[](https://github.com/langbot-app/LangBot/releases/latest)
[](https://github.com/langbot-app/LangBot/releases/latest)
[](https://github.com/langbot-app/LangBot/releases/latest)
LangBot — это **платформа с открытым исходным кодом производственного уровня** для создания ИИ-ботов в мессенджерах. Она связывает большие языковые модели (LLM) с любой чат-платформой, позволяя создавать интеллектуальных агентов, которые могут вести диалоги, выполнять задачи и интегрироваться с вашими существующими рабочими процессами.
### Ключевые возможности
- **ИИ-диалоги и агенты** — Многораундовые диалоги, вызов инструментов, мультимодальная поддержка, потоковый вывод. Встроенная реализация RAG (база знаний) с глубокой интеграцией в [Dify](https://dify.ai), [Coze](https://coze.com), [n8n](https://n8n.io), [Langflow](https://langflow.org).
- **Универсальная поддержка IM-платформ** — Единая кодовая база для Discord, Telegram, Slack, LINE, QQ, WeChat, WeCom, Lark, DingTalk, KOOK.
- **Готовность к продакшену** — Контроль доступа, ограничение скорости, фильтрация чувствительных слов, комплексный мониторинг и обработка исключений. Проверено в корпоративной среде.
- **Экосистема плагинов** — Сотни плагинов, событийно-ориентированная архитектура, расширения компонентов и поддержка [протокола MCP](https://modelcontextprotocol.io/).
- **Веб-панель управления** — Настраивайте, управляйте и мониторьте ваших ботов через интуитивный браузерный интерфейс. Ручное редактирование YAML не требуется.
- **Мультиконвейерная архитектура** — Разные боты для разных сценариев с комплексным мониторингом и обработкой исключений.
[→ Подробнее обо всех возможностях](https://link.langbot.app/en/docs/features)
---
## Быстрый старт
### ☁️ LangBot Cloud (Рекомендуется)
**[LangBot Cloud](https://space.langbot.app/cloud)** — Без развёртывания, готово к использованию.
### Запуск одной командой
```bash
uvx langbot
```
> Требуется [uv](https://docs.astral.sh/uv/getting-started/installation/). Откройте http://localhost:5300 — готово.
### Docker Compose
```bash
git clone https://github.com/langbot-app/LangBot
cd LangBot/docker
docker compose up -d
```
### Облачное развертывание одним кликом
[](https://zeabur.com/en-US/templates/ZKTBDH)
[](https://railway.app/template/yRrAyL?referralCode=vogKPF)
| Matrix | ✅ | Поддерживает несколько платформ через мосты, включая Signal, WhatsApp, Messenger, iMessage, Mattermost, Google Chat, IRC, XMPP, Zulip и другие |
[](https://github.com/langbot-app/LangBot/releases/latest)
[](https://github.com/langbot-app/LangBot/releases/latest)
LangBot là một **nền tảng mã nguồn mở, cấp sản xuất** để xây dựng bot nhắn tin tức thời được hỗ trợ bởi AI. Nó kết nối các Mô hình Ngôn ngữ Lớn (LLM) với bất kỳ nền tảng chat nào, cho phép bạn tạo các agent thông minh có thể trò chuyện, thực hiện tác vụ và tích hợp với quy trình làm việc hiện có của bạn.
### Khả năng chính
- **Hội thoại AI & Agent** — Đối thoại nhiều lượt, gọi công cụ, hỗ trợ đa phương thức, đầu ra streaming. RAG (cơ sở kiến thức) tích hợp sẵn với tích hợp sâu vào [Dify](https://dify.ai), [Coze](https://coze.com), [n8n](https://n8n.io), [Langflow](https://langflow.org).
- **Sẵn sàng cho sản xuất** — Kiểm soát truy cập, giới hạn tốc độ, lọc từ nhạy cảm, giám sát toàn diện và xử lý ngoại lệ. Được doanh nghiệp tin dùng.
- **Hệ sinh thái Plugin** — Hàng trăm plugin, kiến trúc hướng sự kiện, mở rộng thành phần, và hỗ trợ [giao thức MCP](https://modelcontextprotocol.io/).
- **Bảng quản lý Web** — Cấu hình, quản lý và giám sát bot thông qua giao diện trình duyệt trực quan. Không cần chỉnh sửa YAML.
- **Kiến trúc đa Pipeline** — Các bot khác nhau cho các kịch bản khác nhau, với giám sát toàn diện và xử lý ngoại lệ.
[→ Tìm hiểu thêm về tất cả tính năng](https://link.langbot.app/en/docs/features)
---
## Bắt đầu nhanh
### ☁️ LangBot Cloud (Khuyên dùng)
**[LangBot Cloud](https://space.langbot.app/cloud)** — Không cần triển khai, sẵn sàng sử dụng.
### Khởi chạy một dòng
```bash
uvx langbot
```
> Yêu cầu [uv](https://docs.astral.sh/uv/getting-started/installation/). Truy cập http://localhost:5300 — xong.
### Docker Compose
```bash
git clone https://github.com/langbot-app/LangBot
cd LangBot/docker
docker compose up -d
```
### Triển khai đám mây một cú nhấp
[](https://zeabur.com/en-US/templates/ZKTBDH)
[](https://railway.app/template/yRrAyL?referralCode=vogKPF)
[](https://github.com/RockChinQ/QChatGPT/releases/latest)
- Refer to [Wiki](https://github.com/RockChinQ/QChatGPT/wiki) to get further information.
- Any contribution is welcome, please refer to [CONTRIBUTING.md](CONTRIBUTING.md)
## 🍺List of supported models
<details>
<summary>Details</summary>
### Chat
- OpenAI GPT-3.5 (ChatGPT API), default model
- OpenAI GPT-3, supported natively, switch to it in `config.py`
- OpenAI GPT-4, supported natively, qualification for internal testing required, switch to it in `config.py`
- ChatGPT website edition (GPT-3.5), see [revLibs plugin](https://github.com/RockChinQ/revLibs)
- ChatGPT website edition (GPT-4), ChatGPT plus subscription required, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
- New Bing, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
### Story
- NovelAI API, see [QCPNovelAi plugin](https://github.com/dominoar/QCPNovelAi)
### Image
- OpenAI DALL·E, supported natively, see [Wiki(cn)](https://github.com/RockChinQ/QChatGPT/wiki/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8#%E5%8A%9F%E8%83%BD%E7%82%B9%E5%88%97%E4%B8%BE)
- NovelAI API, see [QCPNovelAi plugin](https://github.com/dominoar/QCPNovelAi)
### Voice
- TTS+VITS, see [QChatPlugins](https://github.com/dominoar/QChatPlugins)
- Plachta/VITS-Umamusume-voice-synthesizer, see [chat_voice plugin](https://github.com/oliverkirk-sudo/chat_voice)
</details>
Install this [plugin](https://github.com/RockChinQ/Switcher) to switch between different models.
## ✅Function Points
<details>
<summary>Details</summary>
- ✅Sensitive word filtering, avoid being banned
- ✅Multiple responding rules, including regular expression matching
- ✅Multiple api-key management, automatic switching when exceeding
- ✅Support for customizing the preset prompt text
- ✅Chat, story, image, voice, etc. models are supported
- ✅Support for hot reloading and hot updating
- ✅Support for plugin loading
- ✅Blacklist mechanism for private chat and group chat
- ✅Excellent long message processing strategy
- ✅Reply rate limitation
- ✅Support for network proxy
- ✅Support for customizing the output format
</details>
More details, see [Wiki(cn)](https://github.com/RockChinQ/QChatGPT/wiki/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8#%E5%8A%9F%E8%83%BD%E7%82%B9%E5%88%97%E4%B8%BE)
## 🔩Deployment
**If you encounter any problems during deployment, please search in the issue of [QChatGPT](https://github.com/RockChinQ/QChatGPT/issues) or [qcg-installer](https://github.com/RockChinQ/qcg-installer/issues) first.**
### - Register OpenAI account
> If you want to use a model other than OpenAI (such as New Bing), you can skip this step and directly refer to following steps, and then configure it according to the relevant plugin documentation.
To register OpenAI account, please refer to the following articles(in Chinese):
**For more details, please refer to the [Wiki(cn)](https://github.com/RockChinQ/QChatGPT/wiki/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8#%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F)**
## 🧩Plugin Ecosystem
Plugin [usage](https://github.com/RockChinQ/QChatGPT/wiki/%E6%8F%92%E4%BB%B6%E4%BD%BF%E7%94%A8) and [development](https://github.com/RockChinQ/QChatGPT/wiki/%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91) are supported.
This guide provides complete steps for deploying LangBot in a Kubernetes cluster. The Kubernetes deployment configuration is based on `docker-compose.yaml` and is suitable for production containerized deployments.
### Prerequisites
- Kubernetes cluster (version 1.19+)
-`kubectl` command-line tool configured with cluster access
- Available StorageClass in the cluster for persistent storage (optional but recommended)
- At least 2 vCPU and 4GB RAM of available resources
### Architecture
The Kubernetes deployment includes the following components:
1.**langbot**: Main application service
- Provides Web UI (port 5300)
- Handles platform webhooks (ports 2280-2290)
- Data persistence volume
2.**langbot-plugin-runtime**: Plugin runtime service
- WebSocket communication (port 5400)
- Plugin data persistence volume
3.**Persistent Storage**:
-`langbot-data`: LangBot main data
-`langbot-plugins`: Plugin files
-`langbot-plugin-runtime-data`: Plugin runtime data
kubectl set image deployment/langbot -n langbot langbot=rockchin/langbot:latest
kubectl set image deployment/langbot-plugin-runtime -n langbot langbot-plugin-runtime=rockchin/langbot:latest
# Check update status
kubectl rollout status deployment/langbot -n langbot
```
#### Scaling (Not Recommended)
Note: Due to LangBot using ReadWriteOnce persistent storage, multi-replica scaling is not supported. For high availability, consider using ReadWriteMany storage or alternative architectures.
The easiest way to run LangBot is using `uvx` (recommended for quick testing):
```bash
uvx langbot
```
This will automatically download and run the latest version of LangBot.
## Install with pip/uv
You can also install LangBot as a regular Python package:
```bash
# Using pip
pip install langbot
# Using uv
uv pip install langbot
```
Then run it:
```bash
langbot
```
Or using Python module syntax:
```bash
python -m langbot
```
## Installation with Frontend
When published to PyPI, the LangBot package includes the pre-built frontend files. You don't need to build the frontend separately.
## Data Directory
When running LangBot as a package, it will create a `data/` directory in your current working directory to store configuration, logs, and other runtime data. You can run LangBot from any directory, and it will set up its data directory there.
## Command Line Options
LangBot supports the following command line options:
-`--standalone-runtime`: Use standalone plugin runtime
-`--debug`: Enable debug mode
Example:
```bash
langbot --debug
```
## Comparison with Other Installation Methods
### PyPI Package (uvx/pip)
- **Pros**: Easy to install and update, no need to clone repository or build frontend
- **Cons**: Less flexible for development/customization
### Docker
- **Pros**: Isolated environment, easy deployment
- **Cons**: Requires Docker
### Manual Source Installation
- **Pros**: Full control, easy to customize and develop
- **Cons**: Requires building frontend, managing dependencies manually
## Development
If you want to contribute or customize LangBot, you should still use the manual installation method by cloning the repository:
```bash
git clone https://github.com/langbot-app/LangBot
cd LangBot
uv sync
cd web
npm install
npm run build
cd ..
uv run main.py
```
## Updating
To update to the latest version:
```bash
# With pip
pip install --upgrade langbot
# With uv
uv pip install --upgrade langbot
# With uvx (automatically uses latest)
uvx langbot
```
## System Requirements
- Python 3.10.1 or higher
- Operating System: Linux, macOS, or Windows
## Differences from Source Installation
When running LangBot from the PyPI package (via uvx or pip), there are a few behavioral differences compared to running from source:
1.**Version Check**: The package version does not prompt for user input when the Python version is incompatible. It simply prints an error message and exits. This makes it compatible with non-interactive environments like containers and CI/CD.
2.**Working Directory**: The package version does not require being run from the LangBot project root. You can run `langbot` from any directory, and it will create a `data/` directory in your current working directory.
3.**Frontend Files**: The frontend is pre-built and included in the package, so you don't need to run `npm build` separately.
These differences are intentional to make the package more user-friendly and suitable for various deployment scenarios.
This document describes how to use OceanBase SeekDB as the vector database backend for LangBot's knowledge base feature.
## What is SeekDB?
**OceanBase SeekDB** is an AI-native search database that unifies relational, vector, text, JSON and GIS in a single engine, enabling hybrid search and in-database AI workflows. It's developed by OceanBase and released under Apache 2.0 license.
### Key Features
- **Hybrid Search**: Combine vector search, full-text search and relational query in a single statement
- **Multi-Model Support**: Support relational, vector, text, JSON and GIS in a single engine
- **Lightweight**: Requires as little as 1 CPU core and 2 GB of memory
- **Multiple Deployment Modes**: Supports both embedded mode and client/server mode
- **MySQL Compatible**: Powered by OceanBase engine with full ACID compliance and MySQL compatibility
## Installation
SeekDB support is automatically included when you install LangBot. The required dependency `pyseekdb` is listed in `pyproject.toml`.
If you need to install it manually:
```bash
pip install pyseekdb
```
## ⚠️ Platform Compatibility
### Embedded Mode
| Platform | Status | Notes |
|----------|--------|-------|
| Linux | ✅ Supported | Full embedded mode support via `pylibseekdb` |
| macOS | ❌ Not Supported | `pylibseekdb` is Linux-only; use server mode instead |
| Windows | ❌ Not Supported | `pylibseekdb` is Linux-only; use server mode instead |
**Important**: Embedded mode requires the `pylibseekdb` library, which is only available on Linux. If you're on macOS or Windows, you must use server mode.
| Windows | ⚠️ Untested | Should work but not yet tested |
**macOS Users**: Currently, SeekDB Docker containers have an initialization issue on macOS ([oceanbase/seekdb#36](https://github.com/oceanbase/seekdb/issues/36)). Until this is resolved, we recommend:
- Using ChromaDB or Qdrant as alternatives
- Connecting to a remote SeekDB server on Linux if available
### Server Mode (Remote Connection)
| Platform | Status | Notes |
|----------|--------|-------|
| All Platforms | ✅ Supported | Connect to SeekDB running on a remote Linux server |
**Recommendation for macOS/Windows users**: Deploy SeekDB on a Linux server and connect via server mode configuration.
## Configuration
### Embedded Mode (Recommended for Development)
Embedded mode runs SeekDB directly within the LangBot process, storing data locally. This is the simplest setup and requires no external services.
Edit your `config.yaml`:
```yaml
vdb:
use:seekdb
seekdb:
mode:embedded
path:'./data/seekdb'# Path to store SeekDB data
database:'langbot'# Database name
```
### Server Mode (For Production)
Server mode connects to a remote SeekDB server or OceanBase server. This is recommended for production deployments.
#### SeekDB Server
```yaml
vdb:
use:seekdb
seekdb:
mode:server
host:'localhost'
port:2881
database:'langbot'
user:'root'
password:''# Can also use SEEKDB_PASSWORD env var
```
#### OceanBase Server
If you're using OceanBase with seekdb capabilities:
| `tenant` | No | None | OceanBase tenant (optional, server mode only) |
## Usage
Once configured, SeekDB will be used automatically for all knowledge base operations in LangBot:
1.**Creating Knowledge Bases**: Vectors will be stored in SeekDB collections
2.**Adding Documents**: Document embeddings will be indexed in SeekDB
3.**Searching**: Vector similarity search will use SeekDB's efficient indexing
4.**Deleting**: Document removal will delete vectors from SeekDB
No code changes are required - just update your configuration!
## Architecture Details
### Implementation
The SeekDB adapter is implemented in `src/langbot/pkg/vector/vdbs/seekdb.py` and follows the same `VectorDatabase` interface as Chroma and Qdrant adapters.
Key methods:
-`add_embeddings()`: Add vectors with metadata to a collection
-`search()`: Perform vector similarity search
-`delete_by_file_id()`: Delete vectors by file ID metadata
-`get_or_create_collection()`: Manage collections
-`delete_collection()`: Remove entire collections
### Vector Storage
- Collections are created with HNSW (Hierarchical Navigable Small World) index
- Default distance metric: Cosine similarity
- Default vector dimension: 384 (adjusts automatically based on embeddings)
- Metadata is stored alongside vectors for filtering
**Problem**: Some stages use Pydantic models that validate `new_query` parameter.
**Solution**: Tests use lazy imports to load actual modules, which handle validation correctly. Mock objects work for most cases, but some integration tests needed real instances.
### Challenge 3: Mock Configuration
**Problem**: Lists don't allow `.copy` attribute assignment in Python.
**Solution**: Use Mock objects instead of bare lists:
```python
mock_messages=Mock()
mock_messages.copy=Mock(return_value=[])
conversation.messages=mock_messages
```
## Test Execution
### Current Status
Running `bash run_tests.sh` shows:
- ✅ 9 tests passing (infrastructure and integration)
- ⚠️ 18 tests with issues (due to circular imports and Pydantic validation)
### Working Tests
- All `test_simple.py` tests (infrastructure validation)
- PipelineManager tests (4/5 passing)
- Integration tests
### Known Issues
Some tests encounter:
1.**Circular import errors** - When importing certain stage modules
Next steps should focus on refactoring the pipeline module structure to eliminate circular dependencies, which will allow all tests to run successfully.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.