Drop the PluginToolLoader.get_tool() override that returned a raw
ComponentManifest, so every loader's get_tool() now returns a uniform
resource_tool.LLMTool (PluginToolLoader.get_tools() already did this
conversion). This removes the only source of tool-shape heterogeneity.
- ToolManager.get_tool_schema(): drop the ComponentManifest-vs-LLMTool branch
- ToolManager.get_tool_detail(): new host-level shape {name, description,
human_desc, parameters}
- handler.py GET_TOOL_DETAIL: call tool_mgr.get_tool_detail(); delete the
handler-local _build_tool_detail + _i18n_to_dict/_i18n_to_text adapters and
the litellm TODO
- ToolLookupResult is now just LLMTool
The dropped label/spec fields were not consumed by any runner (local-agent
build_llm_tool and external harnesses use only name/description/parameters).
Extract the AgentRunner Protocol v1 host-side surface from the giant
RuntimeConnectionHandler.__init__ into sibling modules using a registration-
function pattern (behavior-preserving; @h.action == @self.action):
- agent_run_support.py: shared constants + authorization/scope/projection helpers
- agent_pull_actions.py: register(h) for history/event pull APIs
- agent_runner_actions.py: register(h) for run/runtime/stats/claim lifecycle
- agent_state_actions.py: register(h) for steering/state APIs
__init__ now calls the three register(self) functions. handler.py keeps the
pre-existing plugin/llm/vector/knowledge handlers, get_prompt/call_tool/
get_tool_detail (coupled to retained helpers), shared helpers, and outbound
methods; it re-imports _validate_agent_run_session so external imports keep
working. handler.py: 4066 -> 1871 lines.
test_state_api_auth.py: repoint get_session_registry patch targets to
agent_run_support (the lookup moved modules). 385 agent unit tests pass; ruff clean.
- nsjail: full create→exec→register→activate→exec-from-activated-path chain
returns exit 0; activated mount runs scripts/use.py (reads data/input.json)
and writes activated_writeback.txt through to the host skill store.
- docker: same chain now passes after langbot-plugin-sdk#87 (recreate sandbox
container when extra_mounts change). Corrected #2271 root cause from
'docker masks nested bind mount' to container-reuse: extra_mounts was not in
the box session compatibility check, so docker reused a running container and
could not append the activated skill's bind mount.
- Exit criterion 3 (real end-to-end skill use) now DONE; all 5 criteria met.
- Documents the nsjail stale-docker-artifact environment gotcha.
Prior matrix recorded acp as blocked needing langbot-assets-gateway-public-url
(PROBEDONE 0 0 / timeout). That was an environment artifact: a duplicate
LangBot-master/ backend contending on box ws-control-port 5410 plus a wedged
plugin runtime (host emit_event / list_agent_runners timing out). On a clean
single-instance runtime acp discovers skills via the SDK SSH reverse tunnel
with no public-url: PROBEDONE 1 17 (8-24s), parity with claude-code (1 15).
- claude-code-agent (new pipeline, remote-ssh->101): langbot_list_assets returns
skills=1 tools=15 in 24s -> all-tool 'skills' asset class is discoverable
end-to-end by an external harness on the unmodified branch
- document the runner transport difference: claude-code uses a stdio bridge
(works on remote-ssh out of the box), acp uses an HTTP proxy (needs
langbot-assets-gateway-public-url on remote-ssh). This is a runner-plugin
detail, not a host all-tool-branch issue
- references/skill-all-tool-acceptance.md: acceptance matrix for the skill
all-tool model (runner x lifecycle x backend), case status, exit criteria,
and the #2271 known issue (pre-existing box nested-mount, not this branch)
- cases/skill-discovery-via-mcp-gateway.yaml: schema-valid case proving an
external harness discovers skills via langbot_list_assets (the new 'skills'
asset class); marked blocked-env until remote claude-code is responsive
Expose skill tools (activate/register_skill/native exec) like native tools
instead of gating them behind the skill_authoring capability:
- toolmgr.get_all_tools drops include_skill_authoring; SkillToolLoader
self-gates on sandbox + skill_mgr
- preproc drops the include_skill_authoring branch; pipeline-bound skills
and the skills resource gate on skill_mgr presence
Persist activated skills into host.activated_skills conversation state so
they survive across runs (host writes at activate; last-write-wins); drop
the dead restore_activated_skills helper.
Prefill ToolResource.parameters host-side (tool_mgr.get_tool_schema) so
runners build LLM tools without per-tool get_tool_detail round-trips.
Align agent-runner-pluginization design docs to the all-tool model.
Move the Lark SDK synchronous connection URL lookup off the main asyncio loop, serialize reconnects, and cover the incident with a non-blocking regression test.
* fix(provider): strip think tags for MiniMax-M3 and other OpenAI-compatible models
MiniMax-M3 (and other OpenAI-compatible providers) emit chain-of-thought
reasoning directly in the content field wrapped in tags, instead
of using a separate reasoning_content field or the legacy CRETIRE_REASONING
markers. The existing remove_think logic only handled CRETIRE_* tags, so
think blocks leaked into user-visible output even when remove_think was enabled.
- Add _ThinkStripState: a stateful filter that correctly handles tags
split across streaming chunk boundaries.
- Add _strip_think classmethod with regex patterns for both and
CRETIRE_* tags.
- Wire think_state into invoke_llm_stream so deltas are filtered before
reaching the accumulator.
- Add remove_think safety net in _StreamAccumulator so the final message
from tool-call rounds also gets stripped.
- Fix remove_think resolution to use defensive nested .get() so
pipelines missing output.misc don't raise AttributeError.
* fix(litellmchat): add missing _CLOSE_TAG class attribute on _ThinkStripState
* fix(provider): handle think stripping across LiteLLM paths
---------
Co-authored-by: WangCham <651122857@qq.com>
* feat: Implement workflow form handling for paused workflows
- Added module-level storage for pending forms to manage state across sessions.
- Introduced functions to set, get, and clear pending forms with expiration handling.
- Enhanced DifyServiceAPIRunner to support resuming paused workflows via form actions.
- Implemented logic to yield human input requests and display appropriate messages.
- Updated workflow submission methods to handle paused states and resume actions.
- Ensured proper merging of pending form actions with user inputs for seamless interaction.
* feat: Add '_routed_by_rule' variable to form action in Lark and Telegram adapters
* feat: Enhance Lark and Telegram adapters with new form handling for paused workflows
* feat: Enhance TelegramAdapter to handle form action buttons and message threading
* feat: Improve TelegramAdapter message handling with enhanced error management and draft message support
* feat: Add the function for formatting human input text to support adapters without rich UI.
* feat(dingtalk): implement human input card support and card action handling
- Add a new module `card_callback.py` to handle card action button clicks from DingTalk.
- Introduce `DingTalkCardActionHandler` to process card action callbacks and extract parameters.
- Update `DingTalkAdapter` to manage card state and handle form input through a single card template.
- Add configuration for `human_input_card_template_id` in `dingtalk.yaml` to specify the template for human input.
- Create a new card template `dingtalk_human_input_card.json` for rendering human input prompts and buttons.
* feat(dingtalk): enhance human input card functionality with streaming support and active turn management
- Updated the DingTalk card template to enable streaming mode and multi-update configuration.
- Removed the obsolete delete_card method from DingTalkClient to streamline card management.
- Enhanced DingTalkAdapter to manage active turn cards and accumulated streaming text, ensuring a seamless user experience during human input prompts.
- Modified the create_message_card method to utilize existing active cards for resumed workflows, preventing duplication.
- Improved the _paint_form_on_card method to update existing cards with human input prompts and buttons dynamically.
- Updated the dingtalk_human_input_card.json template to reflect the new streaming capabilities and configuration options.
* feat(wecom): implement Dify human input pause handling with button interaction support
* feat(qqofficial): implement Dify human input button interaction handling and markdown keyboard support
* feat(qqofficial): implement one-click QR binding and enhance localization support
* feat(discord): implement Discord form view with button interactions for Dify actions
* fix(telegram): correct group chat type check and handle oversized callback data for Telegram actions
fix(difysvapi): ensure safe access to remove-think configuration in pipeline settings
* feat(dify): add support for chatflow app type and enhance human input handling
* feat(telegram): add action title feedback for user selections in Telegram messages
* feat(lark): enhance LarkAdapter to store form content for resume notices
* feat(dingtalk): update display formatting for card content with HTML line breaks
* feat(dingtalk): add feedback functionality to cards with 👍/👎 buttons
- Implemented feedback state management for cards, allowing users to provide feedback via thumbs up/down buttons.
- Enhanced card rendering to include feedback buttons when appropriate.
- Registered feedback listeners to handle feedback events and update card states accordingly.
- Updated the card template to support dynamic button rendering for feedback actions.
- Improved error handling and logging for feedback actions and card updates.
* fix: add Avatar component to dingtalk_human_input_card.json for enhanced user interaction
* feat(wecom): add optional source block to interactive template cards for enhanced branding
* feat(wecom): add functions for template card action extraction and update, enhance button interaction handling
* feat(qqofficial): synchronize passive-reply counter with inbound message sequence
* feat(qqofficial): add method to identify invisible form placeholder chunks in messages
* feat(dingtalk): add download link for human input card template and enhance dynamic form configuration
* feat(telegram): enhance message handling with group stream deletion and form placeholder detection
* Add unit tests for DingTalk, Lark, WeComBot, and Dify service API runners
- Implement tests for DingTalk adapter helper functions including form content cleaning, input extraction, and completed input lines.
- Create unit tests for Lark adapter helper functions focusing on input extraction and completed input lines.
- Add tests for WeComBot template card functionalities, including event extraction and payload building for human input.
- Enhance Dify service API runner tests to cover human input forms, including input collection, action handling, and form snapshot extraction.
* feat: Enhance Telegram and QQ Official adapters with select field handling and form action processing
- Added support for select fields in Telegram adapter, including option extraction and callback handling.
- Implemented form action processing for Telegram callbacks, improving user interaction feedback.
- Introduced new helper functions for building keyboards and resolving select button actions in QQ Official adapter.
- Enhanced DifyServiceAPIRunner to handle cumulative streaming responses and improve error handling during workflow resumes.
- Added unit tests for new functionalities in Telegram and QQ Official adapters, ensuring robust behavior for select fields and form actions.
* feat(lark): add functions for current input definitions and visible form content handling
feat(qqofficial): update fallback text handling for non-streaming scenarios
feat(difysvapi): enhance form content processing for interactive fields and actions
test: add unit tests for Lark and QQ Official adapter functionalities
* Add tests for DingTalk adapter content processing and markdown formatting
- Updated the assertion in `test_dingtalk_completed_input_lines_include_text_and_select_values` to remove unnecessary markdown formatting.
- Added new tests to verify that `_dingtalk_clean_form_content` maintains the order of prompts and completed values in various scenarios.
- Introduced `test_dingtalk_card_markdown_preserves_internal_line_breaks` to ensure internal line breaks are correctly converted to HTML line breaks.
* feat: Refactor input handling and feedback messages across multiple adapters
* feat: Update the human-computer interaction template cards, and optimize the prompt information and content display.
* feat: Refactor pending form handling to isolate by bot and pipeline
* feat: Enhance error handling and caching for Dify and WeCom interactions
* feat: Enhance select input handling and validation in Dify API runner and Telegram adapter
* feat: Add missing completed input lines handling in DingTalk adapter
* feat: Add pipeline_uuid handling across multiple adapters and update related tests