Repository navigation
en plugin dev apis llm requests
These options require a Core build containing Core #2661. A merged PR does not imply a published release. Pass them through the existing extra_args; plugin and Runner signatures, message types and authorization remain unchanged. See LangBot API and Context APIs.
The following non-streaming example configures the request and reads complete usage:
from langbot_plugin.api.entities.builtin.provider.message import Message
result = await self.plugin.invoke_llm_with_usage(
llm_model_uuid=model_uuid,
messages=[Message(role="user", content="Hello!")],
timeout=110,
extra_args={
"request_policy": {
"retries": 1,
"total_timeout": 90,
"first_event_timeout": 30,
"stream_idle_timeout": 30,
"connect_timeout": 10,
"read_timeout": 60,
},
},
)
print(result.message.content)
if result.usage is not None:
print(result.usage.model_dump())Runner ctx.api.invoke_llm* accepts the same extra_args, subject to run authorization and remaining time. Calls through self.plugin also inherit these restrictions inside a run context.
timeout= is the SDK/RPC waiting limit (120 seconds by default for non-streaming calls). Core's request_policy controls the inner request. Keep its total budget within the enclosing RPC/Runner deadline; raising it cannot extend that deadline. Streaming methods have no timeout= argument and remain bounded by SDK/Runner waiting limits.
request_policy field |
Default | Meaning |
|---|---|---|
retries |
0 |
Additional attempts after the first, integer 0–5 |
total_timeout |
300 |
Whole invocation budget, including backoff |
first_event_timeout |
120 |
Wait for the first upstream event, not the first visible text |
stream_idle_timeout |
120 |
Idle time between stream events |
connect_timeout |
10 |
Connection timeout |
read_timeout |
120 |
Transport read timeout |
write_timeout |
30 |
Transport write timeout |
pool_timeout |
10 |
Connection pool acquisition timeout |
backoff_base / backoff_max
|
0.5 / 8
|
Exponential backoff base and cap, with full jitter |
attribution |
True |
Automatic application attribution headers |
conversation_header |
None |
Generated session header name, described below |
Times are seconds; timeouts must be finite and positive. Unknown policy fields are rejected. Precedence: instance llm_request_policy, model extra_args, then call extra_args. Within one layer, request_policy.retries wins over legacy num_retries / max_retries. A call-level legacy value still overrides model policy; 0 disables retries. Legacy numeric extra_args["timeout"] sets read, first-event and stream-idle limits without extending the total budget.
Authentication, invalid-request and exhausted-quota failures are not retried. Retries stop after any upstream event, including reasoning or usage. Retry-After is bounded by the remaining budget. Core disables LiteLLM and provider SDK retries for managed calls; gateways may independently retry. This adds no tool replay, model fallback or embedding/rerank retries. Legacy third-party requesters still own their transport configuration.
Existing reasoning_level behavior is unchanged. For a numeric budget, pass this object as extra_args or save it in model advanced parameters. Omitting level means enabled:
{
"reasoning_config": {"budget_tokens": 2048},
"max_tokens": 4096
}Do not combine a budget with an effort level such as medium, disabled, or native reasoning parameters. Direct Anthropic calls require explicit max_tokens greater than the budget; Core never raises that limit automatically.
Precedence: persisted model reasoning_config, model extra_args.reasoning_config, call extra_args.reasoning_config, then an explicit Runner level override. Each object replaces the previous one; an effort override clears a lower-priority budget.
Numeric budgets map to native Anthropic, Gemini 2.5, supported Qwen models and OpenRouter routes. Direct OpenAI/Codex and adaptive-only Claude models retain effort control. Check the model's reasoning_capabilities.budget_tokens for support and bounds. Unsupported budgets fail before HTTP. Providers/gateways may impose stricter limits; OpenRouter may translate a numeric budget into effort.
extra_args.prompt_caching is consumed by Core, not forwarded unchanged. Call configuration replaces model configuration. The default {"mode": "provider_default"} adds no fields. This is not a local response cache.
| Configuration | Behavior |
|---|---|
{"mode": "openai", "retention": "in_memory"} |
Generates a model-and-conversation-scoped prompt_cache_key when conversation context exists; optional retention also accepts 24h if supported by the target |
{"mode": "anthropic", "ttl": "5m"} |
Adds an ephemeral breakpoint to the last text block of the leading system/developer prefix; ttl accepts 5m or 1h
|
OpenAI mode applies to compatible routes and OpenRouter OpenAI models supporting these options. Explicit native prompt_cache_key, prompt_cache_retention and prompt_cache_options win. Anthropic mode supports native Claude and OpenRouter Claude. Existing native cache markers are preserved without adding duplicates. Core does not reorder tools/history or mark user messages, and inserts nothing without an eligible prefix.
Hints do not guarantee hits. Inspect usage.model_dump() for provider fields such as prompt_tokens_details.cached_tokens or cache_read_input_tokens; missing counts are not zero. Minimum prefix lengths, retention eligibility and pricing are provider-controlled. Codex's restricted Responses body does not accept this configuration object; existing server caching remains. General Responses migration and Gemini explicit cache-resource management are outside this change.
Direct OpenRouter calls receive HTTP-Referer: https://langbot.app, X-OpenRouter-Title: LangBot, and, with conversation context, x-session-id: lb-<opaque scoped hash>. Custom gateway addresses do not automatically inherit these headers. request_policy.attribution=False disables only automatic application attribution. Explicit extra_headers remain and take precedence case-insensitively.
A gateway can use an explicitly configured session header:
{
"request_policy": {"conversation_header": "x-litellm-session-id"},
"extra_headers": {
"HTTP-Referer": "https://langbot.app",
"X-OpenRouter-Title": "LangBot"
}
}Supported names: x-session-id, x-litellm-session-id, x-langbot-conversation-id. The last is a custom convention, not a universal provider standard, and provides no automatic routing or caching benefit. Generated identifiers are scoped by workspace/bot/pipeline/session and contain no raw session ID or prompt. They are pseudonymous, not a guarantee of anonymization, and are omitted without context. New API and other gateways may filter or rewrite headers; verify forwarding rules and actual outbound requests.
Use aclosing when leaving a stream early. Allow task cancellation exceptions to propagate:
from contextlib import aclosing
from langbot_plugin.api.entities.builtin.provider.message import Message
async with aclosing(self.plugin.invoke_llm_stream_events(
llm_model_uuid=model_uuid,
messages=[Message(role="user", content="Hello!")],
extra_args={"request_policy": {"retries": 0, "total_timeout": 90}},
)) as events:
async for event in events:
if event.usage is not None:
print(event.usage.model_dump())
if event.chunk is not None and event.chunk.content:
print(event.chunk.content)
breakThis example intentionally stops after the first nonempty content chunk and may miss final usage. For a complete response, remove break; a final event can have usage without a chunk. invoke_llm still returns Message, and invoke_llm_stream still yields MessageChunk. Choose invoke_llm_with_usage or invoke_llm_stream_events for accounting. Usage may be None; nested cache/reasoning counts and provider-specific fields are preserved.
SDK ≤0.7.11 has a proxy-layer defect that delays upstream cancellation on early close. Deterministic close requires langbot-plugin ≥0.7.12, which publishes the fix from SDK #177. A Core dependency pin does not automatically upgrade a separately deployed Runtime or plugin development environment; upgrade those executing environments too. Ordinary signatures, payloads and return types remain compatible. Total deadlines include consumer time, but cannot interrupt a consumer while the generator is suspended at yield; expiration is enforced on the next pull.
Core monitoring records expose details.timing, complete usage and structured error; legacy SDK exception transport is unchanged. Structured errors include code, status_code, retryable, retry_after, request_id and phase. Do not assume these fields exist on legacy exceptions received by plugins.
Millisecond timings include preparation_ms, transport_setup_ms, first_event_ms, first_reasoning_ms, first_content_ms, first_visible_chunk_ms, total_ms, plus attempts and retry_wait_ms. The first event may be reasoning/control, and the first visible chunk may include reasoning. request_started_ms marks the SDK call, not a packet leaving the socket. Missing fields mean unobserved, not zero. Monitoring retains partial usage received before cancellation but cannot reconstruct missing upstream accounting.
Automatically synchronized from langbot-app/langbot-docs.
简体中文
指南
开发者
- 插件开发
- 插件 SDK API
- 核心开发
文章
- 浏览
- 产品动态
- 在线体验
- 技术解析
- 教程与集成
- 公告
API 参考
- Service API
English
Guides
- Quick Start
- Installation
-
Configure Bots
- Bots
- Discord
- Telegram
- Slack
- Mattermost
- LINE
- Web Page Bot
- HTTP Bot
- KOOK
- Feishu
- DingTalk
- WeChat Official Account
- QQ (OneBot v11)
- Satori (QQ & Multi-Platform)
- QQ Official Bot
- WeCom (Enterprise WeChat)
- AI Configuration
- Advanced Operations
- Using Plugins
- Enterprise support
Developers
-
Plugin Development
- Plugin Development Tutorial
- Completing Plugin Configuration Information
- Plugin Directory Structure
- Component Development
- Code Style Guide
- Certified plugins and shared runtime
- Publish Plugin
- Migration Guide
- Plugin SDK API
- Core Development
Articles
- Browse
- Product Updates
- Engineering
-
Tutorials & Integrations
- LangTARS: Open-Source AI Agent for Remote PC Control — Works with Dify, n8n & 10+ Messaging Platforms
- How to Connect DeepSeek R1 to WeChat, Discord & Telegram in 5 Minutes (FREE)
- Deploy Your Own AI Bot to Discord, Telegram & WeChat in 5 Minutes
- Finally Got My Dify Agent Working in Discord, Telegram and Slack
- How I Built a Multi-Platform AI Bot with Langflow's Drag-and-Drop Workflows
- How I Built a Multi-Platform AI Chatbot with n8n and LangBot
- LangBot 4.6.0 External Knowledge Base Tutorial: Integrating Dify with LangBot for RAG-powered Conversations
- Announcements
API Reference
- Service API
Other pages
日本語
ガイド
開発者
- プラグイン開発
- プラグイン SDK API
- コア開発
記事
- 一覧
- 製品アップデート
- エンジニアリング
-
チュートリアルと連携
- LangTARS:Dify・n8n と連携するオープンソース PC 操作 Agent
- DeepSeek R1 を WeChat・Discord・Telegram に5分で接続する方法
- AI Bot を Discord・Telegram・WeChat に5分でデプロイ
- Dify Agent を Discord・Telegram・Slack で動かす
- Langflow のドラッグ&ドロップでマルチプラットフォーム AI Bot を構築
- n8n と LangBot でマルチプラットフォーム AI Chatbot を構築
- LangBot 4.6.0 外部ナレッジベース入門:Dify と連携した RAG 会話
- お知らせ
API リファレンス
- Service API