74 lines
3.0 KiB
TOML
74 lines
3.0 KiB
TOML
# DeepSeek (chat.deepseek.com) provider configuration, driven entirely by this
|
|
# file. Selectors change when the web UI is updated: edit them here (reloaded
|
|
# live), never in the Rust source. Validate with: llm-gateway selftest deepseek
|
|
#
|
|
# The values below combine the public chat.deepseek.com DOM with published
|
|
# selector lists (May 2026). They are a starting point, not a guarantee: run
|
|
# 'llm-gateway selftest deepseek' before relying on them.
|
|
|
|
[provider]
|
|
name = "deepseek"
|
|
display_name = "DeepSeek"
|
|
web_url = "https://chat.deepseek.com/"
|
|
new_conversation_url = "https://chat.deepseek.com/"
|
|
# Captures the web conversation id from the current URL (one capture group).
|
|
conversation_url_pattern = '^https://chat\.deepseek\.com/a/chat/s/([0-9a-zA-Z-]{8,})'
|
|
default_models = ["deepseek-chat", "deepseek-reasoner"]
|
|
enabled = true
|
|
|
|
[selectors]
|
|
# The composer is a plain <textarea>. DeepSeek localises its placeholder and the
|
|
# id seen in older builds is gone, so the wording observed on the live page comes
|
|
# first and the older guesses are kept as fallbacks.
|
|
input_field = "textarea#chat-input, textarea[placeholder*='Message DeepSeek'], textarea[placeholder*='Envoyer'], textarea[placeholder*='Send a message'], textarea[placeholder*='message']"
|
|
send_button = "div[role='button'][aria-label='Send'], button[aria-label='Send message'], button[data-testid='send-button']"
|
|
# The answer body is rendered by the "ds-markdown" component; the attribute
|
|
# first variant mirrors the ChatGPT markup.
|
|
response_container = "div[data-message-author-role='assistant'], div.ds-markdown, div[class*='markdown-body']"
|
|
streaming_indicator = "div[role='button'][aria-label*='Stop'], button[aria-label*='Stop'], div[class*='_stop']"
|
|
file_input = "input[type='file']"
|
|
new_chat_button = "a[href='/'], div[class*='new-chat'], button[aria-label='New chat']"
|
|
login_page_indicator = "div[class*='ds-modal'], a[href*='sign_in'], button[data-testid='login-button']"
|
|
captcha_indicator = "iframe[src*='captcha'], div[class*='captcha'], div#challenge-form"
|
|
error_banner = "[role='alert'], div[class*='ds-toast'], div[class*='error']"
|
|
# Relative to the answer node: the toolbar button that copies the answer.
|
|
copy_button = "[aria-label='Copy'], [data-testid='copy-button'], div[class*='ds-icon-button'][role='button']"
|
|
|
|
[login]
|
|
url_patterns = ["/sign_in", "/login", "account.deepseek.com"]
|
|
text_patterns = ["log in", "sign in", "log in with google", "se connecter"]
|
|
|
|
[rate_limit]
|
|
text_patterns = [
|
|
"too many requests",
|
|
"rate limit",
|
|
"please try again later",
|
|
"请求过于频繁",
|
|
"服务器繁忙",
|
|
"trop de requêtes",
|
|
]
|
|
|
|
[timeouts]
|
|
page_load = 30
|
|
response_generation = 120
|
|
# DeepSeek R1 reasons for a long time before answering: keep a generous budget.
|
|
response_timeout = 300
|
|
|
|
[input]
|
|
poll_interval_ms = 400
|
|
quiet_ms = 1500
|
|
inject_method = "auto"
|
|
|
|
[options]
|
|
supports_images = true
|
|
supports_streaming = true
|
|
supports_new_chat = true
|
|
|
|
# Multi-account: each account is a separate browser profile. Address them with
|
|
# model = "deepseek@perso".
|
|
#
|
|
# [[accounts]]
|
|
# id = "perso"
|
|
# email = "[email protected]"
|
|
# default = true
|