* 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>
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>
* 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>
* 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>
* 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>
* 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.
* 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