Files
bruno 7b5aa6fcc9
CI / fmt, clippy and tests (ubuntu-latest) (push) Successful in 21m0s
CI / browser end-to-end (Chromium + fixture) (push) Skipped
CI / fmt, clippy and tests (windows-latest) (push) Canceled after 0s
Add initial llm-bridge project
2026-09-18 18:01:07 -04:00

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