The LiteLLM streaming requester only captured usage when a chunk had an
empty `choices` list. Many OpenAI-compatible gateways (e.g. new-api) and
providers send the final usage payload in a chunk that still carries an
empty-delta choice, so streamed calls always recorded 0 tokens in the
monitoring logs/dashboard (non-streaming worked).
- Capture stream usage whenever a chunk carries it, regardless of choices
- Add robust _normalize_usage (dict/obj shapes, derive missing total_tokens)
- Register litellm in bootutils/deps.py (was in pyproject only)
- Add MonitoringService.get_token_statistics + /monitoring/token-statistics
endpoint: summary, per-model breakdown, token timeseries, and a
zero-token-success data-quality signal
- Add TokenMonitoring dashboard tab (summary tiles, stacked token chart,
per-model table) + i18n (en/zh)
- Regression tests for stream usage capture and usage normalization
Verified end-to-end against a real OpenAI-compatible endpoint with
gpt-5.5 and claude-opus-4-8: tokens now recorded non-zero for both
streaming and non-streaming paths.
- Added `litellm_provider` field to various requesters' YAML configurations.
- Removed obsolete Python requester files for OpenRouter, PPIO, QHAIGC, ShengSuanYun, SiliconFlow, Space, TokenPony, VolcArk, and Xai.
- Introduced new requesters for Tencent and Together AI with corresponding YAML configurations and SVG icons.
- Enhanced the ProviderForm component to include a searchable dropdown for selecting providers, improving user experience.
- Updated localization files to include search provider text for both English and Chinese.
Restore individual provider requester implementations that were
removed in de61b5d3. These files coexist with the unified
litellmchat.py backend.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace 23+ individual requester implementations with unified litellmchat.py
- Add litellm_provider field to 27 YAML manifests for provider routing
- Delete redundant requester subclasses
- Add unit tests for LiteLLMRequester (29 tests)
- Fix num_retries parameter name (was max_retries)
- Fix exception handling order for subclass exceptions
LiteLLM provides unified API for 100+ providers, eliminating need for
provider-specific requesters.
* 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: 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
* 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>
* 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>