SuperAPI AI Directory

AgentChat-OneWeb

Agents & models

View repository

Updated 10-15 20:07

About this skill

AI Fallback Chain — Multi-Provider CDP Bridge

Last updated: 2026-08-23 Core features: Automatically degrade along the priority chain to ensure there is always an available large model Changelog: See CHANGELOG.md

⚠️ Mandatory rule — invoking means executing (primary action contract)

When this skill is invoked (e.g., /AgentChat-OneWeb <问题>), you must execute the node command to send the user's question to the web AI. It is forbidden to only explain the usage without executing, and it is forbidden to replace the web AI's answer with the model's own knowledge.

1. Primary action contract

After reading this SKILL.md, thenext tool callmust be:

node ~/.agents/skills/AgentChat-OneWeb/index.js "<用户prompt>"

In between, it is not allowed to insert file browsing, architecture analysis, or "I will..."-style planning narration (at most one line stating the command about to be executed). Only after the web AI returns a result may you add your own analysis.

2. Execution receipt — whether execution occurred is determined by this, not by narration

Every real execution (including failures) will output a machine-generated receipt line at stderr :

[receipt] AGENTCHAT_RUN {"run_id":"ac-xxxxxxxxxxxx","skill":"AgentChat-OneWeb","exit":0,"provider_used":"Gemini",...}
  • The end of the final answer must quote this receipt line verbatim(at least including run_id, provider_used, exit).
  • No receipt = no execution = violation, and you must go back and execute.
  • run_id is randomly generated and synchronously written to disk at ~/.agents/skills/AgentChat-OneWeb/data/receipts.jsonl, and the user can verify it with grep <run_id> —fabrication cannot pass verification.
  • Execution failure (exit≠0) also has a receipt: you must quote the failure receipt and explain the reason (rate limiting/not logged in/timeout...), and only after that may you answer using the model's own capabilities, and you must clearly mark "web AI did not participate in this answer".

3. Violation patterns (all prohibited)

  • ❌ After reading SKILL.md, describing the fallback chain, listing CLI parameters, and explaining the architecture—but not running node index.js
  • ❌ Skipping execution on the grounds that "the question is too simple/I already know the answer" and answering directly with the model's knowledge
  • ❌ The answer has no [receipt] AGENTCHAT_RUN line but claims "already processed via web AI"

4. Exceptions

Limited to:--smoke、--doctor, or the user explicitly requests "only check the environment, do not send". These two modes do not produce a receipt and are expected behavior.

5. Local context

Web AI cannot access the local file system. When local files/code/images are involved, Claude Code must first read the content into the prompt before sending it, and it is forbidden to pass only the file path.

📐 Output formatting specification — mandatory format for the final answer

The constraint applies to thefinal delivered textwritten by Claude Code; the worker's raw output, code blocks, diffs, tables, and receipt lines are not constrained.

  1. Conclusion first: The first paragraph at the beginning is a core conclusion of ≤50 characters (TL;DR), directly answering the user's fundamental need, with no pleasantries and no methodological preamble.
  2. Heading levels: Use ##for main modules and ###for sub-points; level-one headings #are prohibited. Dimensions should be logically clustered into 3–5 blocks (e.g., background/current state/analysis/conclusion); it is forbidden to write a chronological account in retrieval order.
  3. Visual focus: Mark data, times, proper nouns, and core arguments with **加粗** ; bold is only used for focus guidance, no more than 2 places per natural paragraph.
  4. List discipline: Only single-level unordered lists are allowed *, multi-level nested lists are prohibited (to ensure a good reading experience in terminals/chat boxes).
  5. Text density: narrative paragraphs ≤3 sentences, new logical branches must start a new line and new paragraph; transitional sentences with no substantive information such as "in conclusion," "based on the above search results," "as an AI" are prohibited.
  6. Information isolation: when quoting original snippets from web AI or external links, they must be placed in > quote blocks and the source provider must be indicated, strictly distinguishing them from your own analysis.
  7. Exemption clauses (priority higher than items 1–6):
    • [receipt] AGENTCHAT_RUN {...} lines (or the run_id list for each step) must be preserved verbatim in a code block at the end of the answer; rewriting, bolding, or omitting them is prohibited — governed by mandatory rule §2.
    • Degradation/failure disclosure (e.g., "N roles degraded," "web AI did not participate in this answer") is a process transparency requirement, does not count as a redundant transitional sentence, and must not be deleted.
    • Code blocks, diffs, and tables are not subject to paragraph length or list level restrictions.

🖼️ Image Generation Protocol

Trigger conditions

When a user request involves any of the following keywords, the image generation protocol is triggered:

  • Generation type: 生成图片, 画图, 制图, 绘制, 作图, 生成图, create image, generate image, make image
  • Diagram type: 流程图, 架构图, 示意图, 思维导图, 图表, 拓扑图, chart, diagram, flowchart, mindmap, Mermaid
  • Visualization type: 可视化, visualization, illustration, infographic, DALL·E, Imagen, Midjourney

1. Automatic prompt enhancement (mandatory — pass --image flag, built into index.js since v14)

When an image generation request is detected,mustadd to the command --image flag:

node ~/.agents/skills/AgentChat-OneWeb/index.js --image "<用户原始prompt>"

index.js will, within the process, append the standard enhancement instruction ("Please use your image generation model/tool to actively generate…") to the end of the prompt, and record it in telemetry image_prompt_enhanced: true。Manually rewriting the prompt to replace --image is prohibited —— manual appending is a purely prose constraint, belonging to the kind of "narrative compliance" that the receipt mechanism is meant to eliminate; the flag path is machine-verifiable (checkable via telemetry).

If the user has explicitly specified --from=ChatGPT(DALL·E) or --from=Gemini(Imagen), prioritize using that provider's image generation capability:--image --from=Gemini。

2. Automatic image download (mandatory — built into index.js)

After receiving the web AI response, index.jsautomatically executesthe following steps:

  1. Scan the response text for image URLs:
    • Markdown syntax:![alt](url)
    • HTML tags:<img src="url">
    • Direct links: URLs ending with .png/.jpg/.jpeg/.gif/.webp/.svg URLs ending with
  2. Download each image to current working directory(process.cwd(), i.e., the directory where the user is executing the skill)
  3. Filename format:ai-image-{YYYYMMDD-HHmmss}-{pid}-{序号}.{ext}(v14 adds pid to avoid concurrent workers writing the same filename in the same second and overwriting each other)
  4. Download result summary (## 📥 Downloaded Images paragraph):when stdout is a TTY(run directly by a human) appended at the end of the response;when stdout is a pipe(consumed by execute.js / Python SDK / MCP server) The summary goes only to stderr, stdout keeps the "AI response raw text" machine contract uncontaminated, success/failure counts are recorded in the receipt (images_ok / images_failed)。

v14 hard limits(the download URL comes from the untrusted text of the web AI response and can be manipulated by prompt injection):

  • At most 20 imagesdownloaded per response, the excess is explicitly marked as skipped in the summary
  • Single image 30MB upper limit; total budget for the download phase 120s; tier-2 in-page fetch carries a 25s AbortSignal (previously there was no timeout — a hanging image endpoint would make the whole process never exit)
  • All tiers perform payload sniffing: an HTML error page returned with HTTP 200 is judged as a download failure and is no longer written to disk as a corrupted .png
  • Reject loopback / link-local / RFC1918 private network addresses(such as http://127.0.0.1:9222/... — an injected URL could previously write CDP debug endpoint data into the user directory); for intranet/test environments, AGENTCHAT_ALLOW_PRIVATE_IMAGE_HOSTS=1 can be used to allow
  • Relative to Location: redirects and 303 are now correctly followed; redirect targets also pass the blocked-host check

If there is no image URL in the response, this step is a zero-overhead no-op.

3. Download directory notes

The download target is always the user's current working directory(the shell's $PWD), not the skill installation directory. For example:

  • The user invokes ~/Project/ under /AgentChat-OneWeb 帮我画流程图 → images are downloaded to ~/Project/
  • The user invokes under ~/Data_Project/ → images are downloaded to ~/Data_Project/

Automatic download can be disabled via the --no-download-images flag.


🖼️ Image Upload Protocol

Trigger conditions

The image upload protocol is triggered when a user request involves the following patterns:

  • Explicit upload instruction: upload image, send image, send a picture, send the image to AI, upload image, send image to AI
  • Image path reference: the user mentions in the message .png/.jpg/.jpeg/.gif/.webp/.bmp and other image file paths
  • Visual analysis request: analyze this image, look at this picture, describe this image, what's in this picture

1. Automatically recognize image paths (mandatory)

When the user says "upload the image to AI" or a similar instruction,you mustextract the image file path from the user message, then use the --image-path flag:

node ~/.claude/skills/AgentChat-OneWeb/index.js --image-path="<图片绝对路径>" "<用户prompt>"

Path resolution rules:

  • The path provided by the user may be a relative path (relative to the current working directory $PWD) or an absolute path
  • index.js automatically resolves relative paths to absolute paths
  • Supports multiple --image-path to upload multiple images

2. Paste flow (built into index.js — no manual operation required)

When --image-path is specified, index.js automatically performs the following steps in the provider pipeline:

  1. Read the image file: read the image from disk, convert it to base64 encoding, detect the MIME type
  2. Write to clipboard: write the image to the system clipboard via the async Clipboard API (navigator.clipboard.write)
  3. Paste into the dialog box:Focus on the AI chat input box, press Ctrl+V paste image
  4. Wait for upload to complete:Wait 2.5s to let the web UI process the image attachment
  5. Enter prompt:After the image paste is complete, enter the user's text prompt
  6. Send:Click the send button

Fallback path(when the Clipboard API is unavailable):

  • Simulate paste event: create DataTransfer containing image File object, dispatch ClipboardEvent('paste')
  • Final fallback: inject <img> tag into the contenteditable editor

3. Supported image formats

Format MIME Type Extension
PNG image/png .png
JPEG image/jpeg .jpg, .jpeg
GIF image/gif .gif
WebP image/webp .webp
BMP image/bmp .bmp
SVG image/svg+xml .svg
TIFF image/tiff .tiff, .tif
AVIF image/avif .avif
ICO image/x-icon .ico

Single file limit 50MB。

4. Usage example

# 单张图片
node ~/.claude/skills/AgentChat-OneWeb/index.js --image-path=./screenshot.png "分析这张截图的内容"

# 多张图片
node ~/.claude/skills/AgentChat-OneWeb/index.js \
  --image-path=./before.png \
  --image-path=./after.png \
  "比较这两张图片的差异"

# 指定 provider 上传
node ~/.claude/skills/AgentChat-OneWeb/index.js \
  --image-path=./photo.jpg \
  --from=Gemini \
  "描述这张照片"

5. AI Agent invocation specification

When the user says "upload image to AI" or a similar instruction, the calling agent must:

  1. Identify the image path:Extract the image file path from the user message
  2. Verify the file exists:Confirm that the image file exists on the user's system
  3. Construct the command:Use the --image-path=<绝对路径> flag
  4. Execute the command:Run node ~/.claude/skills/AgentChat-OneWeb/index.js --image-path=... "prompt"
  5. Reference the receipt:According to mandatory rule §2, reference in the final answer the [receipt] AGENTCHAT_RUN line

Prohibited actions:

  • ❌ Use --image instead of --image-path(the former is image-generation intent, the latter is upload intent)
  • ❌ Describe the image content first and then send it to the AI as text—the original image file must be uploaded
  • ❌ Skip --image-path and only describe the image in text

Trigger

Use this skill when:

  • The user asks to send a prompt to "any available AI"
  • Gemini quota is known to be exhausted and a fallback is needed
  • The user wants automatic provider failover without manual switching
  • Running batch prompts where individual provider reliability matters
  • The user wants to upload an image to an AI chat (use --image-path flag)

Do NOT use for: interactive conversations that need multi-turn context (each provider has independent session state).

When to use THIS skill:

  • Multi-provider with automatic fallback. Use for reliability, batch processing, or when you don't care which AI answers.
  • For Gemini-specific Max reasoning depth, use --from=Gemini to force Gemini first in the chain.
  • For image upload: use --image-path=<path> to paste images into the chat before the prompt.

Configuration loading (.env parsing — v31 cross-directory support)

At skill startup, via skills/lib/cdp.js inline loadDotEnv() safely load .env(never shell-sourced; plain-text KEY=VALUE parser). Lookup order stops at the first hit:

# Path Description
1 $AGENTCHAT_ENV_FILE Forced override (CI/testing)
2 $AGENTCHAT_HOME/.env User-level directory override
3 $HOME/.agentchat/.env User-level default (recommended) — any cwd can hit it
4 <entry-point 向上爬,每级父目录 .env> From the entry script's directory up to / 12-level ancestor chain
5 <__dirname>/../../.env + <process.cwd()>/.env legacy fallback

Cross-directory use(invoke from any cwd ~/.agents/skills/.../index.js):

# 推荐:让 ~/.agentchat/.env 指向仓库 .env(一次性,所有终端/工具自动继承)
mkdir -p ~/.agentchat
ln -sf /path/to/AgentChat/.env ~/.agentchat/.env

# 或:单次显式覆盖
AGENTCHAT_ENV_FILE=/path/to/AgentChat/.env \
  node ~/.agents/skills/AgentChat-WebSubAgent/index.js --search "..."

When no .env is found:stderr immediately outputs [agentchat-env] NOT LOADED — 候选列表 + 3 修复选项(without burning provider budget and then failing). On success, only one line [agentchat-env] loaded <path>, with no key echo.

Quota-safe ChatGPT timeout recovery (opt-in)

Set AGENTCHAT_CHATGPT_RESUME_ON_TIMEOUT=1 in the recommended user-level file, ~/.agentchat/.env, to enable ChatGPT-only no-resend recovery. The process environment still has higher precedence than .env. The setting is disabled by default and does not change Gemini, Claude, Kimi, or any other provider.

After a ChatGPT prompt has been submitted, a visible stop-generation control is authoritative evidence that generation is still active. Once the control disappears, the assistant response must remain unchanged for the existing 10-second stability window before it is accepted as complete. The mere presence of an assistant DOM node at the deadline is never completion proof.

The enabled mode permits one normal per-provider observation budget plus exactly one additional budget on the same https://chatgpt.com/c/<conversation-id> conversation. Parent subprocess watchdogs allow both budgets plus the existing shutdown grace. If the second budget expires, AgentChat stops fallback and exits 10 with this stderr contract while leaving stdout empty:

[oneweb] AGENTCHAT_PENDING {"status":"submitted_pending","provider":"chatgpt","conversation_url":"https://chatgpt.com/c/...","safe_to_resend":false}

safe_to_resend: false is the quota-safety guarantee: the submission is committed, so callers must not retry it on ChatGPT or another provider. If a conversation URL cannot be captured, the field is omitted and the relevant browser tab is kept for manual recovery; the no-resend guarantee is unchanged.

Resume an existing conversation read-only with:

node ~/.agents/skills/AgentChat-OneWeb/index.js \
  --resume-chatgpt="https://chatgpt.com/c/<conversation-id>" \
  --timeout=300000

Resume mode opens that exact conversation in a dedicated page and never locates, fills, or submits the prompt editor. It prints the completed answer to stdout with exit 0, or emits the same pending line with exit 10 if generation is still active. Non-HTTPS, non-ChatGPT, homepage, non-conversation, credential-bearing, query-bearing, or prompt-combined resume invocations fail as usage errors before browser navigation.

Conversation URLs are transient recovery data. They may appear in the immediate pending result, but are never written to receipts, fallback telemetry, or a persistent pending registry.


Fallback Chain (Priority Order)

Gemini → ChatGPT → Claude → Qwen → Kimi → MiniMax → ChatGLM → Doubao → MiMo → DeepSeek
(newest full Flash + Extended Thinking default)                    (last resort)

First available provider wins. Each step falls through ONLY on confirmed unavailability (quota/auth/model-degraded), never on transient network errors.


Provider Availability Detection

Each provider undergoes 3 layers of checks before sending the prompt:

Check layer Detection content Failure behavior
L1: Reachability Whether the page can load and whether login is required Skip → next provider
L2: Availability Whether the input box is editable and whether it is rate-limited Skip → next provider
L3: Model quality Whether Pro/advanced models are available Gemini-specific, other providers skip

Gemini special handling

Gemini uses by default andmust verify that the newest full Flash in the current menu is selected (newest full Flash, not Lite/Pro/Ultra, nor the generic composer "Flash") and 延伸思考(free tier, fast);Flash-Lite、Pro、Ultra, standard thinking, and any existing state on a reused tab do not satisfy the default contract. No longer hard-pin the literal 3.6 Flash— the newest full Flash actually present in the menu is the default. If a Pro model is needed, set AGENTCHAT_GEMINI_MODEL=pro to enable Pro Extended Thinking(requires a Gemini Pro subscription, 3-5 minute generation). Model activation strategy (v36+; v34's 3.6 pinning has been superseded):

  1. newest full Flash + Extended Thinking(default,AGENTCHAT_GEMINI_MODEL=flash or unset) — send the prompt only after confirming in the Gemini verified menu that both "newest full Flash" and "extended thinking" are checked
  2. Pro Extended Thinking(AGENTCHAT_GEMINI_MODEL=pro) — deep reasoning + extended thinking; when Pro is unavailable, degrade only to the verified newest full Flash + Extended Thinking
  3. cannot select or verify these two default states → Gemini fails this round, and the normal fallback chain hands off to the next provider; never pass off Pro / Flash-Lite / Ultra / standard thinking / the page's existing model as the default Flash

Degradation trigger conditions are defined by each adapter's quotaPatterns (lib/providers/adapters/<name>.js), which is the authoritative source. SKILL.md no longer maintains a second copy (drift inconsistent with the code has occurred in the past).


Prerequisites

# 0. ⚠️ CRITICAL: 必须使用系统 Chrome + 含登录态的 profile
#    复制并编辑项目 .env 文件:
#      cp .env.example .env
#    关键配置:
#      CHROMIUM_PATH=/usr/bin/google-chrome-stable  (REQUIRED — 必须设为系统 Chrome,留空会报错退出;拒绝 ms-playwright 路径)
#      CHROME_PROFILE=~/.chrome-debug-profile
#    如果未配置,所有 AI 网站的登录态会丢失!

# 1. Chrome debug 在端口 9222 运行 — v16 起完全自动,零外部脚本依赖
#    index.js 端口不通时自动启动 Chrome(AGENTCHAT_NO_AUTOSTART=1 关闭):
#      Tier 1: 平台启动脚本(若部署了 scripts/ — 仓库完整 clone 场景)
#      Tier 2: 内嵌启动器 — 直接定位 Chrome 二进制并以加固 flag 集启动。
#              workbuddy 等只拷贝 skills 树的宿主(scripts/ 永远缺失)走此路径。
#    skill-only 部署(workbuddy / ~/.agents/skills/)只需保证:
#      a) .env 放在 skills/ 的上级目录(与 scripts/ 本应在的位置相同),
#         或设 AGENTCHAT_ENV_FILE 指向它 — Node 侧自 v16 起自行安全加载 .env
#      b) .env 里 CHROMIUM_PATH 指向系统 Chrome(Windows 例:
#         C:\Program Files\Google\Chrome\Application\chrome.exe;
#         未设时按标准安装路径自动探测,含 Edge 兜底)
#      c) Windows + agent 宿主(skill 装在 ~/.agents/skills/ 等): skill 进程
#         看不到仓库根的 .env 与 scripts/(lib 的候选路径会解析到
#         ~/.claude/.env)。用两个逃生门环境变量接回来(设为用户级,
#         工具调用子进程自动继承):
#           setx AGENTCHAT_ENV_FILE    "C:\path\to\AgentChat\.env"
#           setx AGENTCHAT_SCRIPTS_DIR "C:\path\to\AgentChat\scripts"
#         否则 skill 只会按默认值探测 127.0.0.1:9222 + ~/.chrome-debug-profile,
#         与 ps1 按仓库 .env 启动的 Chrome(自定义端口/profile)分裂 —— 端口
#         探测失败后再拉起的同 profile 实例会被 Windows 单例机制吸收秒退。
#         v18 起: 内嵌启动器经 WMI 创建 Chrome(脱离工具调用的 Job Object,
#         不再随 run 结束被连带杀掉);启动前侦测占用 profile 的存活实例
#         (仅回收 PID 文件记录的受管实例,他人实例快速报错);拒绝浏览器
#         默认 User Data 目录(Chrome ≥136 在其上静默禁用调试端口)。
#    手动预启动(可选,完整 clone 下更快):
#    Linux/macOS:
bash scripts/chrome-debug
#    Windows (PowerShell;首次使用加 --first-login 登录 Gemini):
#      scripts\run-helper.cmd chrome-debug --first-login
#    WSL2 注意: WSL 内 127.0.0.1 是 VM 而非 Windows 宿主。Chrome 跑在
#    Windows 侧时需设 CDP_HOST=<Windows 宿主 IP>(见 .env.example)。

# 2. CDP 可达
curl -s http://127.0.0.1:9222/json/version | python3 -c "import json,sys; print(json.load(sys.stdin).get('Browser','FAIL'))"

# 3. playwright-core (npm, ~3MB)
(cd ~/.agents/skills/AgentChat-OneWeb && npm install)
#    ⚠️ 本 skill 依赖同级 skills/lib/ 共享库(require('../lib/…'))——
#    安装到 ~/.agents/skills/ 时必须整棵拷贝:AgentChat-OneWeb/ 与 lib/ 并排。
#    只拷 AgentChat-OneWeb/ 会在启动时报出带修复指引的 FATAL(v14 起,不再是裸 MODULE_NOT_FOUND)。
#    IndependentTasks 同样需要 sibling `lib/providers/chain.js` that exports
#    PROVIDER_KEYS. A stale copy that only has PROVIDER_CHAIN fails loud
#    (`ERR_PROVIDER_KEYS`, refresh hint) instead of `includes` on undefined.
#    After tests, refresh ~/.agents/skills runtime files without replacing
#    data/, node_modules/, receipts, or user .env.

# 4. 至少一个 AI service 已登录 (Chrome profile 中)
#    各 service 登录 URL:
#    Gemini:  https://gemini.google.com/u/0/app
#    ChatGPT: https://chatgpt.com/
#    Claude:  https://claude.ai/
#    Qwen:    https://www.qianwen.com/?source=tongyigw
#    Kimi:    https://kimi.moonshot.cn/
#    MiniMax: https://agent.minimaxi.com/
#    Doubao:  https://www.doubao.com/chat/

Invocation

# 基本用法 — 自动遍历 fallback chain(默认保留浏览器标签)
node ~/.agents/skills/AgentChat-OneWeb/index.js "Your prompt"

# 执行完毕后自动清理浏览器标签
node ~/.agents/skills/AgentChat-OneWeb/index.js --close "Your prompt"

# 指定超时 (ms)
node ~/.agents/skills/AgentChat-OneWeb/index.js --timeout=600000 "Long prompt..."

# 从 stdin 读取
echo "Prompt from pipe" | node ~/.agents/skills/AgentChat-OneWeb/index.js

# 环境检查 (不发送 prompt)
node ~/.agents/skills/AgentChat-OneWeb/index.js --smoke

# CDP 连通性检查
node ~/.agents/skills/AgentChat-OneWeb/index.js --doctor

# 强制指定起始 provider (跳过前面的)
node ~/.agents/skills/AgentChat-OneWeb/index.js --from=ChatGPT "prompt"

# 上传图片并提问(可重复 --image-path 上传多张)
node ~/.agents/skills/AgentChat-OneWeb/index.js --image-path=./photo.png "描述这张图片"
node ~/.agents/skills/AgentChat-OneWeb/index.js --image-path=a.png --image-path=b.jpg "比较这两张图片"

# Read an existing ChatGPT conversation without sending a prompt
node ~/.agents/skills/AgentChat-OneWeb/index.js --resume-chatgpt="https://chatgpt.com/c/<conversation-id>" --timeout=300000

CLI Flags

Flag Description
--timeout=N Total timeout (ms), including all provider attempt time, default 600000
--timeout-per-provider=N Single provider timeout (ms), defaults to timeout / 2 or 180000
--from=NAME Start from the specified provider, skipping those earlier in the chain. NAME may be abbreviated and is case-insensitive
--single Only try the one provider specified by --from , and return on failure without cascading to subsequent providers in the chain. For callers that need to do their own cross-provider degradation + locking (e.g. AgentChat-IndependentTasks), to avoid internal cascading in the subprocess bypassing the caller's mutex
--only=NAME --from=NAME --single merged shorthand (for programmatic callers; an unknown NAME fails loudly rather than silently falling back)
--locale=xx_XX Force the Gemini UI language profile (zh_CN / zh_TW / en / ja), skipping auto-detection. The Python SDK's locale= parameter passes through this flag
--smoke Environment check: iterate over all providers to confirm at least one is reachable
--doctor CDP port connectivity check
--close / --close-browser Close all tabs and browser connections after execution completes (kept by default)
--image Image generation intent: within the index.js process, append the standard image-generation enhancement instruction and record image_prompt_enhanced telemetry (see image protocol §1)
--image-path=PATH Image upload: read a local image file, paste it into the AI chat dialog, then send the prompt (can be reused multiple times to upload multiple images). For trigger conditions see image upload protocol §4
--no-download-images Disable automatic image download (enabled by default, extracts image URLs from the response and downloads them to the current working directory)
--resume-chatgpt=URL Read-only ChatGPT recovery: open an existing validated /c/<id> conversation, never type or send, and return its completed answer or exit 10 pending

Unrecognized --flag will log WARN and then be ignored (since v14; previously silently discarded, which was the root cause of bugs such as --locale spinning idle for months and--keep-tabs having been spliced into the prompt).--from= / --only= An empty value will hard-fail with exit 64.--only/--single Underexact match key or display name (substring matching is retained only on the cascade path as a human convenience).


Output & Telemetry

  • stdout: Output the original AI response on success
  • stderr: Diagnostic log,[fallback] prefix
  • telemetry: Write to ~/.agents/skills/AgentChat-OneWeb/data/fallback-telemetry.jsonl
{
  "timestamp": "2026-07-01T...",
  "provider_used": "ChatGPT",
  "providers_tried": ["Gemini"],
  "fallback_reasons": {"Gemini": "ERR_RATE_LIMITED"},
  "prompt_length_chars": 1500,
  "response_length_chars": 3200,
  "total_ms": 45000,
  "exit_code": 0
}

Exit Codes

Exit Code Meaning
0 — Success — response on stdout
1 ERR_NO_CDP Chrome CDP port unreachable
2 ERR_NO_PROVIDER All providers unavailable (all not logged in / require authentication)
3 ERR_SAFETY_REJECTED Current provider security filter rejected (all attempted)
4 ERR_INTERNAL Internal error (Node exception, CDP disconnect, etc.)
5 ERR_RATE_LIMITED All providers are rate-limited
9 ERR_ALL_EXHAUSTED Traversed all providers, all unavailable
10 ERR_TIMEOUT Overall timeout, or the already-submitted opt-in ChatGPT request is still submitted_pending(must not resend)
64 EX_USAGE Usage error (empty prompt / --from=、--only= null value). Before v14, exit 1 was misused, conflicting with ERR_NO_CDP, causing the orchestrator to treat a caller bug as "the browser is down" and terminate the entire chain. Usage errors also produce a receipt

Architecture

index.js
├── main()                    — CLI 入口,解析参数
├── tryAllProviders()         — 按链遍历 provider,返回第一个成功
├── RUNNERS (factory-built)   — provider runners via createProviderRunner()
│   ├── gemini                — config: lib/providers/adapters/gemini.js
│   ├── chatgpt               — config: lib/providers/adapters/chatgpt.js
│   ├── claude                — config: lib/providers/adapters/claude.js
│   ├── qwen                  — config: lib/providers/adapters/qwen.js
│   ├── kimi                  — config: lib/providers/adapters/kimi.js
│   ├── minimax               — config: lib/providers/adapters/minimax.js
│   ├── doubao                — config: lib/providers/adapters/doubao.js
│   ├── mimo                  — config: lib/providers/adapters/mimo.js
│   ├── deepseek              — config: lib/providers/adapters/deepseek.js
│   └── muse                  — config: lib/providers/adapters/muse.js (draft/best-effort)
├── helpers/
│   ├── isProviderTabOpen()   — tab dedup (shared with smokeTest)
│   ├── log() / startTimer()  — 终端输出 (lib/terminal.js)
│   └── connectWithRetry()    — CDP 连接 + 重试 (lib/cdp.js)
└── constants/
    └── PROVIDER_CHAIN        — 优先级顺序 + URL

Core design decisions

  1. One page per invocation — Each invocation creates an independent tab; by default the browser is kept open and not closed (--close can enable automatic cleanup).
  2. New tab per provider — Each provider attempt uses an independent tab (via context.newPage()). After failure, close the current tab and create a new tab for the next provider.
  3. Quota detection via DOM — Does not rely on HTTP status codes; instead checks page DOM content to determine whether it is rate-limited.
  4. No cross-provider context — Does not pass context between different providers. Each time is an independent prompt.
  5. Verified newest full Flash + Extended Thinking default, Pro Extended opt-in — Gemini by default must confirm in the verified model menu that the current latest full Flash and 延伸思考 are both selected (not pinned to 3.6); if either cannot be verified, this provider fails and degrades, and never uses Flash-Lite, Pro, Ultra, or standard thinking to fake success. Pro Extended Thinking is explicitly enabled via AGENTCHAT_GEMINI_MODEL=pro (v36+).

Provider-Specific Implementation Notes

Each provider's special behavior is defined in lib/providers/adapters/<name>.js (configuration-driven, not hardcoded); SKILL.md only retains key differences for AI invocation reference:

Provider Key differences See details
Gemini By default strictly select and reopen the menu to verify the latest full Flash in the menu + 延伸思考(not pinned to 3.6); Pro Extended opt-in (AGENTCHAT_GEMINI_MODEL=pro), bursty output detection, 120s stop-btn extension, Action Toolbar completion anchor, search→answer gap grace re-read adapters/gemini.js
ChatGPT 3-layer input strategy (clipboard→simulated paste→chunked keyboard), React send button state verification adapters/chatgpt.js
Claude ProseMirror editor, "Thinking" placeholder filtering, embedded search block stripping adapters/claude.js
Qwen React SPA 3s delay, stop-btn detached mode, model name prefix stripping adapters/qwen.js
Kimi Create a new session per invocation, send-button-container disabled detection, adaptive stability window (5-30s) adapters/kimi.js
MiniMax TipTap/ProseMirror asynchronous mount 4s delay,<div aria-label="发送消息"> non-button send adapters/minimax.js
ChatGLM Zhipu Qingyan React SPA, Chinese UI, agentic tool/search phase stillWorkingCheck adapters/chatglm.js
Doubao ByteDance React SPA, CSS Modules hashed class names, agentic tool/search phase stillWorkingCheck adapters/doubao.js
MiMo React SPA 4s delay, DOM traversal to locate send button (no reliable CSS selector) adapters/mimo.js
DeepSeek Standard pipeline, ds-markdown response adapters/deepseek.js
Muse Draft/best-effort selector; end of chain; live CDP prove pending Karl reopening social/browser adapters/muse.js

Adding a New Provider

  1. Create lib/providers/adapters/<name>.js Export the config object (refer to the existing adapter; draft adapters like Muse prioritize durable generics)
  2. In PROVIDER_CHAIN add an entry to the array (PROVIDER_KEYS is derived from the chain and automatically registered to RUNNERS)
  3. Key fields of Config: url, authDomains, editorSelectors, sendSelectors/sendFallback, responseSelectors
  4. The function returns {success: true, response: string} or {success: false, reason: string}
    • reason must be: "quota" | "auth" | "error" | "timeout"
  5. Update the demo hub / webextended.html the hardcoded count text in the provider list and product-map tests

Code Location

  • index.js — CLI entry point + fallback orchestrator
  • lib/providerFactory.js — 10-step config-driven pipeline (shared by all 8 providers)
  • lib/providers/adapters/<name>.js — per-provider differential configuration
  • lib/providers/chain.js — priority order (single source of truth shared with IndependentTasks)
  • SKILL.md — AI-facing operational guide
  • package.json — npm metadata (playwright-core)