Dify Agent
Run a Dify application as a LangBot AgentRunner.
Dify Agent
Run a Dify application as a LangBot AgentRunner.
Runner ID
plugin:langbot-team/DifyAgent/default
Configuration (Static)
Configuration is static and should not contain runtime state. Only the following static fields are supported:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| base-url | string | yes | https://api.dify.ai/v1 | Dify API base URL |
| api-key | secret | yes | '' | Dify Service API key |
| app-type | select | yes | chat | Application type (chat/agent/workflow) |
| base-prompt | text | yes | File-handling instruction | Instruction prepended to LangBot input |
| timeout | integer | no | 30 | Request timeout (seconds) |
| langbot-assets-enabled | boolean | no | false | Register a short-lived LangBot asset token for each run and pass it to Dify inputs |
| langbot-assets-gateway-host | string | no | 0.0.0.0 | Host for the local LangBot Asset Gateway |
| langbot-assets-gateway-port | integer | no | 8765 | Port for the local LangBot Asset Gateway |
| langbot-assets-gateway-request-timeout | integer | no | 60 | Timeout for individual gateway tool calls |
| langbot-assets-token-ttl | integer | no | 3600 | Lifetime of each run token in seconds |
| langbot-assets-input-name | string | no | langbot_asset_run_token | Dify input variable that receives the run token |
Note: Do not put conversation_id in config. Use AgentRunContext.state for conversation state.
Capabilities
streaming: yesmultimodal_input: yes
Runtime State
Conversation state is managed through AgentRunContext.state and AgentRunResult.state_updated:
Reading State
The runner reads external.conversation_id from scoped state:
conversation_id = ctx.state.conversation.get("external.conversation_id")
Priority:
ctx.state.conversation["external.conversation_id"]when it is a Dify UUID- Empty string (start a new Dify conversation)
Host-provided LangBot conversation IDs are intentionally not sent to Dify,
because Dify rejects non-UUID conversation_id values.
Updating State
The runner outputs state.updated with proper scope:
yield AgentRunResult.state_updated(
ctx.run_id,
"external.conversation_id",
dify_conversation_id,
scope="conversation",
)
LangBot host persists this state and loads it on the next run.
LangBot Asset Callback Through Dify MCP
Dify can call back into LangBot assets through the SDK Asset Gateway when the Dify app has an MCP provider registered against the gateway URL.
Prerequisites
- The Dify app must be an Agent app with MCP tools enabled.
- The LangBot runner must be installed from this plugin and selected by the
pipeline as
plugin:langbot-team/DifyAgent/default. - The SDK Asset Gateway must be reachable by Dify. For Dify Cloud, this means a
public HTTPS URL that forwards to the gateway
/mcpendpoint. A temporary tunnel is fine for testing, but use a stable domain or reverse proxy for production. - The Dify app needs a Service API key for LangBot to call
https://api.dify.ai/v1.
For Dify Cloud, the MCP provider URL should look like:
https://example.com/mcp
Configure Dify Cloud
- Open Dify Cloud and go to Tools -> MCP.
- Create an MCP provider for the LangBot Asset Gateway.
- Set the provider URL to the public gateway URL, for example
https://example.com/mcp. - Confirm Dify can discover the LangBot tools. The expected tool set is:
langbot_list_assets,langbot_get_current_event,langbot_history_page,langbot_retrieve_knowledge,langbot_get_tool_detail, andlangbot_call_tool. - Open the target Dify Agent app configuration and attach the LangBot MCP tools.
- Add a hidden text input variable matching
langbot-assets-input-name, defaulting to:
langbot_asset_run_token
- Add prompt guidance telling the app to pass that input value as the
run_tokenargument on every LangBot MCP tool call. A minimal prompt pattern is:
For every LangBot MCP tool call, set run_token exactly to:
{{langbot_asset_run_token}}
Call langbot_list_assets first when you need to discover available LangBot
assets for the current run.
- Use a tool-compatible chat model. For example,
gpt-4o-miniworks for this flow. Avoid models that reject Dify's tool result message format;o3-minihas been observed to fail with:
Unsupported value: 'messages[3].role' does not support 'function' with this model.
Configure LangBot
Select the Dify runner on the LangBot pipeline and set:
base-url = https://api.dify.ai/v1
api-key = <Dify app Service API key>
app-type = agent
timeout = 120
langbot-assets-enabled = true
langbot-assets-gateway-host = 0.0.0.0
langbot-assets-gateway-port = 8765
langbot-assets-gateway-request-timeout = 60
langbot-assets-token-ttl = 3600
langbot-assets-input-name = langbot_asset_run_token
The runner registers a run-scoped token before calling Dify and removes it when the run ends. Tool calls without a valid token are rejected by the gateway.
The public Dify MCP provider URL must route to this same gateway instance. The runner only injects the short-lived token into Dify inputs; it does not create or update the Dify MCP provider.
Verify the Flow
Use LangBot Debug Chat or another real LangBot run. Do not rely on Dify Cloud
preview alone, because preview does not automatically receive a live
langbot_asset_run_token.
Send a prompt like:
Call LangBot MCP tool langbot_list_assets first, using the injected run_token.
If the tool call succeeds, reply only LANGBOT_DIFY_MCP_OK.
If the token is missing or invalid, reply RUN_TOKEN_FAILED.
A passing run should show the sentinel response in LangBot and backend logs similar to:
assistant: requested tools: langbot_list_assets
Limitations
- Dify Cloud cannot reach
localhostor a private LAN gateway. Use public HTTPS for the MCP provider URL. - Temporary tunnel URLs such as
trycloudflare.comare only suitable for testing. When the tunnel stops or changes, the Dify MCP provider URL becomes invalid. - The run token is short-lived and run-scoped. It is injected only when LangBot calls Dify through this runner, then stopped when the run finishes.
- Dify Cloud preview calls usually fail for LangBot MCP tools unless a valid token from a live LangBot run is supplied manually.
- The Dify app prompt must consistently pass
run_tokento every LangBot MCP tool call. Missing or invalid tokens are rejected by the gateway. - Model compatibility matters. The Dify Agent model must support the function or tool message roles produced by Dify's tool executor.
- The gateway exposes only the assets permitted by the current LangBot run: current event, history page, knowledge retrieval, tool detail, and tool call.
- The gateway lifetime is tied to the LangBot process and configured port. Port conflicts or process restarts will break the public MCP endpoint until the proxy points at the new live gateway.
- Keep the gateway behind HTTPS and avoid logging or exposing run tokens. Tune
langbot-assets-token-ttlto the minimum value that still covers expected Dify tool latency.
Workflow Inputs
Workflow inputs are passed through ctx.adapter.extra.params:
# Runner uses adapter params as Dify inputs
inputs = dict((ctx.adapter.extra or {}).get("params") or {})
Legacy input variables are derived from context:
| Variable | Source |
|---|---|
| langbot_user_message_text | ctx.input.to_text() |
| langbot_session_id | ctx.conversation.session_id or ctx.run_id |
| langbot_conversation_id | ctx.state.conversation.get("external.conversation_id") when it is a Dify UUID |
| langbot_msg_create_time | ctx.adapter.extra.params["msg_create_time"] if provided |
Example Usage
Chat/Agent Mode with Stateful Session
LangBot host provides state snapshot:
ctx = AgentRunContext(
run_id="run_001",
input=AgentInput(text="Hello"),
config={
"base-url": "https://api.dify.ai/v1",
"api-key": "app-xxx",
"app-type": "chat",
},
state=AgentRunState(
conversation={"external.conversation_id": "4f4f8c1b-b1f4-4c9f-9e9f-0f144af69f10"},
),
params={},
)
Runner will use the Dify UUID as the Dify conversation ID, maintaining session continuity.
Workflow Mode with Custom Inputs
ctx = AgentRunContext(
run_id="run_002",
input=AgentInput(text="Process this"),
config={
"base-url": "https://api.dify.ai/v1",
"api-key": "app-yyy",
"app-type": "workflow",
},
params={
"custom_var": "value1",
"workflow_input": "data",
},
)
Runner passes params to Dify workflow inputs.
Replaced Runner
Migrated from dify-service-api in LangBot.
Key Changes
- Config is static only: No
conversation_idin config - State via protocol: Use
ctx.stateandstate.updated - Inputs via adapter params: Use
ctx.adapter.extra.paramsfor workflow inputs - Scoped state:
external.conversation_idwithscope="conversation"
Use Dify Agent in Feishu/Lark bots, DingTalk bots, WeCom bots, WeChat bots, QQ bots, Slack bots, Discord bots, Telegram bots, LINE Bots, and Matrix Bots.
Host your bot on LangBot Cloud and connect this extension to the collaboration platforms your team already uses.