Files
llm-bridge/providers/chatgpt.toml
T
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

87 lines
3.4 KiB
TOML

# ChatGPT 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 chatgpt
[provider]
name = "chatgpt"
display_name = "OpenAI ChatGPT"
web_url = "https://chatgpt.com/"
new_conversation_url = "https://chatgpt.com/"
# Captures the web conversation id from the current URL (one capture group).
conversation_url_pattern = "^https://chatgpt\\.com/c/([0-9a-zA-Z-]{8,})"
default_models = ["gpt-4o", "gpt-4o-mini", "gpt-4.1"]
enabled = true
[selectors]
input_field = "div#prompt-textarea, div.ProseMirror[contenteditable='true']"
# The id and the data-testid are language independent; the aria-label fallbacks
# only match an English UI (see providers/selectors.md, "Localised user
# interfaces").
send_button = "button[data-testid='send-button'], button#composer-submit-button, button[aria-label='Send prompt'], button[aria-label='Envoyer la requête']"
response_container = "div[data-message-author-role='assistant']"
streaming_indicator = "button[data-testid='stop-button']"
file_input = "input[type='file']"
new_chat_button = "a[data-testid='create-new-chat-button']"
# Clicked once the answer has settled, to read the provider's own Markdown
# through the clipboard. Looked up inside the answer node, so it must be
# relative to it. Leave empty to always convert the DOM instead.
copy_button = "button[data-testid='copy-turn-action-button'], button[aria-label='Copy'], button[aria-label='Copier']"
login_page_indicator = "button[data-testid='login'], form[action*='login'], a[href*='auth/login'], a[href*='auth/0']"
captcha_indicator = "iframe[src*='captcha'], iframe[src*='challenges.cloudflare.com'], div#challenge-form"
error_banner = "[data-testid='error-message'], div[role='alert']"
[login]
url_patterns = ["/auth/login", "/login", "accounts.google.com", "/auth/0"]
# The page a signed-out visitor lands on (title "ChatGPT: Chat, Work, Create &
# Code with AI") has no prompt field and shows these call to action buttons.
# The text patterns are only used when that field is missing, so a signed-in
# conversation is never mistaken for a sign-in screen.
text_patterns = ["log in", "sign up", "create an account"]
[rate_limit]
text_patterns = [
"too many requests",
"rate limit",
"trop de requêtes",
"réessayez plus tard",
"you've reached",
]
[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. A ChatGPT account is a browser profile, so declaring two
# accounts gives two independent sessions, each with its own tab pool, driven
# side by side. Address them with the model string:
#
# {"model": "chatgpt"} -> the default account
# {"model": "chatgpt@perso"} -> by account id
# {"model": "[email protected]@gmail.com"} -> by address
# {"model": "chatgpt@perso/gpt-4o"} -> account and model
#
# Sign each one in once: llm-gateway login chatgpt --account perso
# Their profiles live in profiles/chatgpt/accounts/<account>/user-data-dir.
#
# [[accounts]]
# id = "perso"
# email = "[email protected]"
# label = "Personal"
# default = true
#
# [[accounts]]
# id = "pro"
# email = "[email protected]"
# label = "Work"