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