Add initial llm-bridge project
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# Claude (claude.ai) 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 claude
|
||||
#
|
||||
# The values below come from the public claude.ai DOM observed in 2026 and from
|
||||
# published selector lists (May 2026). They are a starting point, not a
|
||||
# guarantee: run 'llm-gateway selftest claude' before relying on them.
|
||||
|
||||
[provider]
|
||||
name = "claude"
|
||||
display_name = "Anthropic Claude"
|
||||
web_url = "https://claude.ai/new"
|
||||
new_conversation_url = "https://claude.ai/new"
|
||||
# Captures the web conversation id from the current URL (one capture group).
|
||||
conversation_url_pattern = '^https://claude\.ai/chat/([0-9a-zA-Z-]{8,})'
|
||||
default_models = ["claude-sonnet-4", "claude-opus-4", "claude-haiku-4"]
|
||||
enabled = true
|
||||
|
||||
[selectors]
|
||||
# Claude uses ProseMirror, so the editor is a contenteditable div rather than a
|
||||
# textarea. The fallbacks cover the composer variants seen behind A/B tests.
|
||||
input_field = "div.ProseMirror[contenteditable='true'], div[contenteditable='true'][data-placeholder], [data-testid='composer-input']"
|
||||
send_button = "button[aria-label='Send Message'], button[aria-label='Send message'], button[data-testid='send-button'], button[type='submit']"
|
||||
# One node per assistant answer, in document order.
|
||||
response_container = "div.font-claude-response, div[data-is-streaming], div.font-claude-message"
|
||||
streaming_indicator = "button[aria-label='Stop response'], button[aria-label='Stop Response']"
|
||||
file_input = "input[type='file']"
|
||||
new_chat_button = "a[href='/new'], button[aria-label='New chat']"
|
||||
login_page_indicator = "a[href*='/login'], button[data-testid='login-button'], form[action*='login']"
|
||||
captcha_indicator = "iframe[src*='challenges.cloudflare.com'], iframe[title*='challenge'], div#challenge-form"
|
||||
error_banner = "[role='alert'], div[data-testid='error']"
|
||||
# Relative to the answer node: the hover toolbar button that copies the answer
|
||||
# as Markdown.
|
||||
copy_button = "button[aria-label='Copy'], button[data-testid='copy-button']"
|
||||
|
||||
[login]
|
||||
url_patterns = ["/login", "/magic-link", "accounts.google.com"]
|
||||
# Only consulted when the prompt field is missing, so a chat page that happens
|
||||
# to mention "log in" is never misclassified.
|
||||
text_patterns = ["sign in", "log in", "continue with google"]
|
||||
|
||||
[rate_limit]
|
||||
text_patterns = [
|
||||
"message limit",
|
||||
"rate limit",
|
||||
"too many requests",
|
||||
"you've reached",
|
||||
"limite de messages",
|
||||
"trop de requêtes",
|
||||
"réessayez plus tard",
|
||||
]
|
||||
|
||||
[timeouts]
|
||||
page_load = 30
|
||||
response_generation = 120
|
||||
response_timeout = 180
|
||||
|
||||
[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, so several
|
||||
# subscriptions can be driven side by side. Declare them like this and address
|
||||
# them with model = "claude@work".
|
||||
#
|
||||
# [[accounts]]
|
||||
# id = "perso"
|
||||
# email = "[email protected]"
|
||||
# default = true
|
||||
#
|
||||
# [[accounts]]
|
||||
# id = "work"
|
||||
# email = "[email protected]"
|
||||
Reference in New Issue
Block a user