Commit Graph
592 Commits
Author SHA1 Message Date
Tynwink2000 bc32eb3ca0 feat(api): add system context endpoint for lbctl 2026-09-07 14:22:27 +08:00
Hyuanddadachann 0f216a0d4d feat(provider): support Codex subscriptions with ChatGPT sign-in (#2513)
* feat(provider): support Codex subscriptions with ChatGPT sign-in

* style: format Codex live integration test

* fix(provider): preserve Codex identity in temporary model tests

* fix(web): portal provider selector without dialog overflow

* fix(web): allow native scrolling in provider dropdown

* fix(provider): surface safe Codex quota and upstream errors

* fix(web): provide reliable Codex copy feedback in dialogs

* feat(provider): confirm cascade deletion from edit dialog

* fix(persistence): discard connections after failed commit

* fix(web): polish provider loading and confirmation motion

---------

Co-authored-by: dadachann <[email protected]>
2026-09-06 23:31:02 +08:00
RockChinQ 75f117ae50 fix(provider): preserve explicit streaming finish reasons 2026-09-06 00:33:20 +08:00
RockChinQ f5d6a3b348 fix(agent): tolerate intent annotations on no-argument platform tools 2026-09-05 17:15:20 +08:00
Hyu 8f0a55a1f4 fix(agent-debug): stream execution traces with platform mocks and coverage 2026-09-05 15:34:29 +08:00
Hyuanddadachann ec63978ecf docs: replace legacy documentation shortlinks (#2510)
* docs: replace legacy documentation shortlinks

* style: format updated documentation URLs

---------

Co-authored-by: dadachann <[email protected]>
2026-09-05 01:19:28 +08:00
Hyuanddadachann 1cfe87186c docs: update published documentation links (#2509)
Co-authored-by: dadachann <[email protected]>
2026-09-05 00:55:18 +08:00
leonoxoanddadachann 9794df0933 feat(n8n-runner): support async response handling (#2487)
* feat(n8n-runner): support async response handling

* fix(n8n-runner): expose response handling in form

* fix(n8n-runner): preserve async response semantics

---------

Co-authored-by: dadachann <[email protected]>
2026-09-04 22:36:40 +08:00
Hyu a4d36aa2db feat(agent): add event-aware tool permissions 2026-09-04 15:37:41 +08:00
mintya de3c0b00ad fix(bot): roll back inserted bot row when adapter fails to load (#2497)
create_bot inserts the Bot row first and only then instantiates the
adapter via platform_mgr.load_bot. When the adapter constructor raises
(e.g. KeyError on a missing credential key), the insert is already
committed and nothing removes the row: the HTTP layer returns 500 but
a permanently disabled orphan bot stays in the DB. Callers never
receive the bot uuid, so they cannot compensate by deleting it, and
load_bots_from_db skips enable=False bots, so the orphan is never
loaded or surfaced anywhere.

Wrap load_bot in try/except and delete the inserted row before
re-raising. Add a regression test asserting the DELETE is issued when
the adapter constructor fails.
2026-09-04 13:06:12 +08:00
mintya cb45807b12 fix(qqofficial): tolerate missing optional token in adapter config (#2496)
Since b55f073e the token field is optional in qqofficial.yaml ("the
current adapter implementation does not use it either, so it can be
safely left blank"), but the adapter constructor still reads it with
config['token']. Creating a bot via QR binding (which only returns
appid/secret) or with the token field left blank raises KeyError and
the API returns 500.

Read it with config.get('token', '') instead. The value is never used
by QQOfficialClient beyond being stored, so an empty string default is
safe.
2026-09-04 13:05:36 +08:00
Amir Fathi d942bfe19a fix(wecom): read media_id instead of media in send_message() (#2447)
WecomMessageConverter.yiri2target() always emits {'media_id': ...} for
image/voice/file parts (never 'media'), matching the correct usage
already in reply_message(). send_message(), the entry point plugins
use via PluginToRuntimeAction.SEND_MESSAGE, instead read
content['media'], which is never set, so any image/voice/file part
raises KeyError and aborts the send.

Refs #1687

Signed-off-by: Amir Fathi <[email protected]>
2026-09-04 13:02:40 +08:00
Hyuanddadachann b44b8f474d fix(cloud): provision login workspace just in time (#2505)
* fix(cloud): provision login workspace just in time

* fix(oauth): send callback URI during code exchange

* fix(oauth): preserve callback URI through browser exchange

* fix(oauth): negotiate redirect-bound codes

---------

Co-authored-by: dadachann <[email protected]>
2026-09-03 23:14:44 +08:00
Hyu 7c64756203 fix(ui): improve agent debug and model test feedback 2026-09-03 14:51:01 +08:00
Hyuanddadachann ab52684a01 Revert "fix(cloud): request automatic Space launch (#2501)" (#2503)
This reverts commit d50957fc4f.

Co-authored-by: dadachann <[email protected]>
2026-09-03 12:16:21 +08:00
Hyuanddadachann d50957fc4f fix(cloud): request automatic Space launch (#2501)
Co-authored-by: dadachann <[email protected]>
2026-09-03 11:44:32 +08:00
Hyu be0214cf4d feat(storage): group usage by application and runtimes 2026-09-03 00:11:05 +08:00
Hyuanddadachann c8d8b1aac4 fix(cloud): serialize directory catch-up (#2500)
Co-authored-by: dadachann <[email protected]>
2026-09-02 21:57:53 +08:00
Hyuanddadachann 018dd7a363 fix(cloud): launch newly registered accounts through Space (#2499)
* fix(cloud): launch new accounts through Space

* style: format Cloud entry URL

* fix(cloud): wait for launch workspace projection

---------

Co-authored-by: dadachann <[email protected]>
2026-09-02 21:41:35 +08:00
huanghuoguoguo 7b7d3f04e8 feat(box): support explicit host backend (#2498) 2026-09-02 21:22:14 +08:00
CWTandzx90316 601c6975ea fix(ollama): use litellm's ollama_chat provider for native tool-calling (#2494)
The Ollama requester declared litellm_provider: ollama, which routes
every request through litellm's legacy /api/generate-based
OllamaConfig. That config's get_supported_openai_params() does not
include "tools"/"tool_choice" at all, so an Ollama-hosted model in a
local-agent pipeline could never receive a structured tool definition
or return a structured tool_calls response - it could only try to
express a tool call as free text (typically inside its own <think>
reasoning), which LangBot then has no way to execute.

litellm's "ollama_chat" provider targets Ollama's modern /api/chat
endpoint instead, which correctly forwards tools/tool_choice and
correctly surfaces the model's native message.tool_calls field.
Verified against a real local Ollama 0.33.2 instance with the exact
system prompt, RAG-augmented user message, and tool set a live
pipeline sends.

Two follow-on fixes needed because the Ollama requester definition is
shared by LLM and text-embedding models:

- get_reasoning_capabilities: match family in ('ollama', 'ollama_chat')
  so the reasoning-level UI still works for this provider.
- scan_models: retry {base_url}/v1/models on a 404 from {base_url}/models,
  since Ollama's base_url is a bare host (must not include /v1 - that
  would break OllamaChatConfig.get_complete_url, which appends /api/chat
  to it directly), unlike most other OpenAI-compatible providers whose
  base_url already ends in /v1.
- invoke_embedding: litellm's embedding routing has no "ollama_chat"
  case, only "ollama". Build the embedding model name with an explicit
  custom_llm_provider="ollama" override when the requester is configured
  for ollama_chat, so embedding models (e.g. bge-m3) keep working.

Co-authored-by: zx90316 <[email protected]>
2026-09-01 22:36:35 +08:00
mintya 5ca30133a3 fix(lark): stop duplicating final reply text in streaming card (#2490)
* fix(lark): stop duplicating final reply text in streaming card

* fix(lark): stop duplicating final reply text in streaming card
2026-09-01 21:24:54 +08:00
Hyuanddadachann 5c49cb60e3 fix(embed): preserve replies after empty assistant frames (#2492)
Co-authored-by: dadachann <[email protected]>
2026-09-01 20:11:21 +08:00
Hyuanddadachann 8cf0015502 fix(dingtalk): restore card auto layout (#2491)
Co-authored-by: dadachann <[email protected]>
2026-09-01 17:56:02 +08:00
Hyu a87c814dae feat(web): improve marketplace install workflows 2026-09-01 16:43:50 +08:00
Hyuanddadachann bf8d418ad4 feat(monitoring): paginate sessions and messages (#2489)
* feat(monitoring): paginate sessions and messages

* fix(monitoring): align detail pages with local dates

---------

Co-authored-by: dadachann <[email protected]>
2026-09-01 15:14:29 +08:00
Hyu e5e62c8fe9 fix(plugin): keep status responsive during installation 2026-09-01 12:46:16 +08:00
Hyu 91e09af76a fix(web): complete pluginized agent onboarding flows 2026-09-01 10:41:29 +08:00
Hyu 7e51044a87 Merge fix/box-reconnect-skill-context into dev/4.11.x 2026-08-31 19:18:34 +08:00
Hyu b4980ab536 fix(box): reload workspace-scoped skills after reconnect 2026-08-31 19:18:19 +08:00
Hyu fde04e64f6 Merge remote-tracking branch 'origin/master' into dev/4.11.x
# Conflicts:
#	src/langbot/pkg/api/http/controller/groups/pipelines/pipelines.py
#	src/langbot/pkg/api/http/service/bot.py
#	src/langbot/pkg/provider/runners/localagent.py
#	src/langbot/templates/metadata/pipeline/ai.yaml
#	tests/unit_tests/api/service/test_bot_service.py
#	tests/unit_tests/provider/runners/test_difysvapi_runner.py
#	tests/unit_tests/utils/test_safe_regex.py
#	web/src/app/infra/entities/adapter-categories.ts
#	web/src/app/wizard/page.tsx
#	web/src/i18n/locales/en-US.ts
#	web/src/i18n/locales/ja-JP.ts
#	web/src/i18n/locales/zh-Hans.ts
#	web/tests/e2e/plugin-page-auth.spec.ts
2026-08-31 17:17:47 +08:00
RockChinQandHyu 1b7ae791b3 fix(plugin): return not found after removal (#2483)
Co-authored-by: Hyu <[email protected]>
2026-08-31 13:40:03 +08:00
NeosandHyu e69a80f5e9 Windows 兼容性修复 + Dify API 适配 + 企微 WS 加载优化 (#2470)
* fix: Windows fsync requires write access to file descriptor

- _fsync_file: os.O_RDONLY -> os.O_RDWR (Windows _commit() requires write access)
- _fsync_directory: tolerate OSError on fsync and os.open (chmod 0o700 blocks access on Windows)

* fix: Dify SSE empty data lines and upload response format mismatch

- Skip malformed/flushed SSE data lines (JSONDecodeError)
- Accept HTTP 200 besides 201 for file upload response
- Unwrap data wrapper in upload response (resp.get('data', resp))

* feat: WeCom WS mode sends empty initial stream frame for loading spinner

Send an empty reply_stream frame immediately after stream session
creation so the WeCom client shows its built-in loading indicator
while the pipeline processes the message (e.g. RAG retrieval).

* fix(compat): harden Windows, Dify, and WeCom changes

* fix(migration): clean interrupted SQLite temp files

---------

Co-authored-by: Hyu <[email protected]>
2026-08-29 22:34:10 +08:00
Hyuanddadachann bafdaf0033 fix(monitoring): restore SQLite token statistics (#2479)
* fix(monitoring): restore SQLite token statistics

Allow the monitored SQLite strftime bucket expression through the tenant SQL guard and preserve structured backend errors in the token dashboard. Add persistence and frontend regressions.\n\nVerified-by: independent-review

* test(runtime): accept reconcile timeout in capacity stub

Keep the PostgreSQL capacity probe aligned with the runtime handler contract and assert the bounded reconcile timeout.

---------

Co-authored-by: dadachann <[email protected]>
2026-08-28 11:41:42 +08:00
be3734ffda feat(wizard): rework agent onboarding flow (#2471)
* feat(wizard): rework agent onboarding flow

* fix(web): support LAN development access

* fix(wizard): parse ranked model selection entries

* feat(wizard): add inbound bot verification

* feat(wizard): add floating page bot verification

* fix(wizard): repair HTTP bot inbound test setup

* feat(wizard): streamline custom model onboarding

* feat(wizard): label page bot test preview

* style(space): apply ruff formatting

* fix(wizard): polish AI engine onboarding

* fix(wizard): clarify local account message test

* feat(wizard): animate AI engine transitions

* fix(wizard): align AI engine setup headers

---------

Co-authored-by: langbot-dev <[email protected]>
Co-authored-by: RockChinQ <[email protected]>
2026-08-28 01:30:30 +08:00
leonoxo 855ae2bdba fix(line): map LINE mentions to At elements so the at-bot rule works (#2478)
The LINE adapter passed text through as a single Plain component,
ignoring the mention payload (mentions[].index/length/isSelf) that the
Line Messaging API includes in the webhook. As a result:

- At(target=bot_account_id) never appeared in the message chain, so the
  'at-bot' group respond rule silently dropped every @bot mention.
- The bot only replied when the message happened to match the prefix
  rule (e.g. starting with 'ai').

Now LINEMessageConverter reads message.message.mention and builds the
chain per mention position:

- Bot mention (isSelf) -> At(target=bot_account_id) so AtBotRule matches
  the same way as other adapters (dingtalk/lark etc.).
- Other mentions -> At(target=<line user id>, display=<mention text>).
  At.__str__ already prepends '@', so the display text carries no
  double '@' and the rendered text (prefix/regexp rules, quotes,
  session context) is byte-identical to before.
- Missing/out-of-bounds mentions are skipped defensively.

target2yiri becomes an instance method (like wechatpad/aiocqhttp) so
the converters can hold bot_account_id; LINEAdapter passes it in from
its own config.
2026-08-27 18:38:27 +08:00
fishzjp b66db86bff fix(provider): stringify MCP tool results for OpenAI-compatible APIs (#2476)
execute_func_call returns list[ContentElement] for MCP tools, but the
runner assigned that list directly to the tool-message content. The
OpenAI chat-completions spec requires tool-message content to be a
string, so OpenAI-compatible endpoints return HTTP 500 when the raw
list is sent.

Serialize the list to a string before building the tool message, using
ContentElement.__str__ which returns the text payload for text elements
and a human-readable placeholder for images and files. Fixes #2457.
2026-08-27 18:19:04 +08:00
fishzjp 95b8736e93 fix(provider): tolerate trimmed image parts in litellm message conversion (#2475)
SessionManager clears image_base64 on past turns to save memory, and
exclude_none serialization drops the hollowed field entirely, so a
replayed history part can arrive as {'type': 'image_base64'} with no
payload. The converter accessed the missing key unconditionally and
raised KeyError on every turn after an image was sent.

Prefer the base64 payload when present, fall back to an image_url that
survived on the same element, and drop hollow parts otherwise (same
strategy as the existing file-part handling). Fixes #2469.
2026-08-27 18:07:43 +08:00
Yanganddadachann cabde423a1 Fix wecomcs open_kfid msgid (#2449)
* Update wecomcs.py

fix bug wecomcs send_message open_kfid
event.receiver_id  is open_kfid

* Update wecomcs.py

fix bug msgid exceeds the 32-byte limit

* test(wecomcs): cover bounded message IDs and images

---------

Co-authored-by: dadachann <[email protected]>
2026-08-27 17:30:49 +08:00
RockChinQ 3d692fa8db feat(bots): add platform event debugger 2026-08-26 19:46:59 +08:00
RockChinQ 600a173918 refactor(bots): remove route execution test 2026-08-26 14:28:30 +08:00
RockChinQ 47f5515fa9 fix(pipelines): retain debug chat image history 2026-08-26 00:32:03 +08:00
ciri667anddadachann 08307790e5 fix(cntfilter): allow legacy sensitive-word lists over 64 patterns (#2467)
* fix(cntfilter): allow legacy sensitive-word lists over 64 patterns

Legacy sensitive-words.json files shipped ~70 rules. After v4.10.7,
BanWordFilter treated the 64-pattern safe_regex cap as a hard failure
and blocked every message. Raise the cap only on the sensitive-word
path, keep the 50ms CPU budget, and truncate oversized lists with a
one-time warning.

Fixes #2443

* fix(cntfilter): reject oversized sensitive-word lists

---------

Co-authored-by: dadachann <[email protected]>
2026-08-25 23:53:41 +08:00
RockChinQ 80f1790e1d refactor(agent): remove enabled state 2026-08-25 23:27:45 +08:00
RockChinQ db2a9155f8 feat(web): edit entity details from page titles 2026-08-25 22:31:23 +08:00
RockChinQ 69ca7e21cd fix(bots): explain unavailable route tests 2026-08-25 22:03:57 +08:00
RockChinQ 68620c4572 fix(bots): simplify event routing status 2026-08-25 21:18:01 +08:00
RockChinQ 6a6a2b865b fix(web): make processor debugging reliable 2026-08-25 15:52:59 +08:00
leonoxo 777fe1f20b fix(line): use stable source id for session identity (#2398)
LINEEventConverter.target2yiri() built Friend.id/Group.id from
event.message.id, which is unique per message. Every incoming message
therefore mapped to a new session key, so LINE users and groups lost
conversation context on every turn.

Use event.source.user_id/group_id/room_id instead, matching the stable
identifiers other adapters (e.g. Telegram) use for session identity.
Falls back to the group/room id when user_id is absent, per LINE's
documented behavior for some group/room members.
2026-08-25 12:30:29 +08:00
HyuandJunyan Qin f0ee57c1e0 style(email): use generic LangBot invitation branding (#2466)
Co-authored-by: Junyan Qin <[email protected]>
2026-08-24 14:53:59 +08:00