Repository navigation
Flowise sunset: Flowise EOL 31 August 2026. This release defaults to bundled LangGraph.
ORCHESTRATOR=flowiseremains as a deprecated opt-in for one release.
Summary
Makes LangGraph the default orchestrator for the conversation bridge and renames chat-connector/ to bridge-service/. Flowise stays available for backward compatibility, with EOL 31 August 2026.
Breaking
- Renamed
chat-connector/tobridge-service/and the Cloud Run service name tobridge-service(create the new service and re-point callbacks; Cloud Run does not support renaming an existing service). - Default orchestrator is now
langgraphwhenORCHESTRATORand legacyAI_PROVIDER/CHAT_PROVIDERare unset (was implicit Flowise). - Prefer
ORCHESTRATORoverAI_PROVIDER/CHAT_PROVIDER(deprecated aliases still work for one release). - LangGraph with
STATE_BACKEND=memoryrequires--max-instances=1so conversation state is not fragmented across replicas. - LangGraph fails process startup if MCP discovery fails, an allowlisted tool is missing from the server, or no usable tools remain.
- Startup validation requires orchestrator credentials on first container boot (deploy-then-configure in Cloud Run console no longer works for LangGraph).
- LINE WORKS rejects callbacks with HTTP 401 when
LW_API_20_BOT_SECRETis unset (was fail-open).
Added
- Orchestration Interface with typed failures and async bridging
- Bundled LangGraph orchestrator (
ORCHESTRATOR=langgraph, default) with MCP allowlist and in-memory checkpointer MCP_TOOL_ALLOWLISTenv override (*allow-all; missing names fail startup)- LangGraph honors
LLM_SYSTEM_PROMPTwhen set (unset keeps the Workday prompt + datetime),LLM_MESSAGE_WINDOW(default 20), andLLM_REASONING_EFFORT - LangGraph and Direct LLM use the OpenAI Chat Completions API only (
POST {LLM_BASE_URL}/chat/completions) - Direct LLM orchestrator (
ORCHESTRATOR=direct_llm, formerly OpenRouter path) - Startup validation for required orchestrator settings
- Feishu (Lark) channel adapter (
/feishu/callback) - In-process webhook idempotency (Feishu
message_id, DingTalkmsgId, LINE WORKS body hash).release()runs on failed outbound sends (including Feishu IMcode != 0→ HTTP 502) so the platform can retry. A LangGraph wait_for timeout is different: the user gets a timeout chat message and the key stays claimed so the same turn is not retried (request_my_time_offis not end-to-end idempotent). An outer hang (TimeoutErrorafter wait_for + 30s) still releases. - Architecture diagram (
docs/assets/architecture.png) for LangGraph-first hub-and-spoke design - CI workflow: ruff, check scripts, Docker builds
- Outer orchestration
TimeoutErrorcancels the in-flight asyncio task so a released webhook retry cannot overlap a still-running invoke
Migration from v0.1.0
- Update local paths and
docker compose/ scripts tobridge-service - Deploy a new Cloud Run service named
bridge-service(do not attempt to renamechat-connector) - Deploy
mcp-demo-serverfirst; setMCP_SERVER_URLto its/mcpURL on the first bridge revision - Set
LLM_API_KEY(and optionalLLM_BASE_URL/LLM_MODEL) on first bridge deploy - Re-point LINE WORKS, DingTalk, and Feishu callbacks (
/lineworks/callback,/dingtalk/callback,/feishu/callback) - Set
LW_API_20_BOT_SECRET(LINE WORKS callbacks return 401 without it) - If still on Flowise: set
ORCHESTRATOR=flowiseandFLOWISE_API_URLexplicitly - Delete the old
chat-connectorCloud Run service after cutover
Known limitations
- DingTalk (
/dingtalk/callback) performs no inbound signature or timestamp verification. With a public URL, combineDINGTALK_ALLOW_ALL_USERS=false, a narrowDINGTALK_ALLOWED_USERSlist, andDINGTALK_REQUIRE_MENTION=true. NarrowMCP_TOOL_ALLOWLISTto read-only tools outside controlled tests — the reference allowlist includesrequest_my_time_off. - Feishu verifies the event token with plain
==, nothmac.compare_digest; noX-Lark-SignatureHMAC path. Encrypted payloads are rejected with 400. - Conversation state lives in process memory (
STATE_BACKEND=memory→InMemorySaver). Tool results can include HR data; there is no TTL or eviction.STATE_BACKEND=firestoreis unimplemented. - Single replica: use
--max-instances=1with in-memory state. Do not use gunicorn--preloador--workers > 1. - Timeouts: LangGraph
wait_for(default 240s) replies in-chat and keeps the idempotency key — send a new message; the same webhook is not retried.release()+ platform retry applies to failed sends (and a rarer outer hang), not that wait_for path. - LangGraph on Cloud Run was exercised at 256Mi memory; the deploy script does not pin memory.