rgcsekaraa/aitunnel

GitHub: rgcsekaraa/aitunnel

本地 Gemini 代理服务器,通过逆向 Web 协议复用浏览器会话 cookie,无需 API key 即可在 localhost 提供完整的 Gemini HTTP API 及流式服务。

Stars: 0 | Forks: 0

# aitunnel [![tests](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/31ea4a6838215906.svg)](https://github.com/rgcsekaraa/aitunnel/actions/workflows/test.yml) [![PyPI](https://img.shields.io/pypi/v/aitunnel.svg)](https://pypi.org/project/aitunnel/) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) 一个小型的 Python 服务器,利用你 gemini.google.com 会话中的 cookies,在 `localhost` 上为你提供 Gemini 服务。专为无法访问官方 Gemini API 但仍希望将其卓越性能集成到其工具中的开发者而设计。 你只需运行 `aitunnel-server`,一次性粘贴两个 cookies,你的脚本/agent/IDE 扩展就可以像访问任何其他 LLM endpoint 一样访问 `http://localhost:8000/query`。 ``` curl -X POST localhost:8000/query \ -H 'Content-Type: application/json' \ -d '{"prompt": "explain monads in one paragraph"}' ``` ## 为什么会有这个项目 Google 官方的 Gemini API 有速率限制(并且并非在所有地区都可用)。 而 gemini.google.com 上的 Web 应用则没有。aitunnel 逆向工程了 Gemini Web UI 内部通信所使用的相同协议——相同的模型、相同的质量,且不需要 API key。 它不是 SaaS,也不是官方 API 的 wrapper。它在你自己的机器上本地运行,针对你自己的 Google 账号。 ## 你能得到什么 - 位于 `localhost:8000` 的 **HTTP API** - JSON 输入,JSON 输出。通过 SSE 进行流式传输。 - **Web 仪表盘**,用于手动发送查询、浏览已保存的聊天记录、管理自定义 Gems 以及实时查看活动状态。 - **文件附件** - 将图像或任何文件拖放到仪表盘中,或者将它们 POST 到 `/upload` 并在后续查询中引用该 URL。 - **多轮对话**,通过 API 中的 `cid` 延续实现;支持深度研究;Gem CRUD。 - **活动日志**,显示每个请求的状态、尝试次数、持续时间和请求/响应预览。 - **自动轮换 session** - 短期 auth token 会在后台刷新,因此你只需设置一次,然后几个月都不用再管它。 ## 安装 ``` pip install aitunnel aitunnel-server ``` 或从源码安装: ``` git clone https://github.com/rgcsekaraa/aitunnel cd aitunnel python -m venv .venv && source .venv/bin/activate pip install -e . aitunnel-server ``` 需要 Python 3.11 或更高版本。 ## 首次运行 第一次在没有 cookies 的情况下启动时,它会在 `http://localhost:8000` 弹出一个设置表单。从 Chrome 的 DevTools 中粘贴两个值: 1. 在浏览器中打开 `https://gemini.google.com`,并确保已登录。 2. F12 → Application → Cookies → `https://gemini.google.com` 3. 复制 `__Secure-1PSID` 和 `__Secure-1PSIDTS` 的值。 4. 将它们粘贴到表单中,点击 Save。 就这样。服务器会引导 session,捕获你的账号信息,启动一个后台 coroutine 每九分钟刷新一次短期 cookie,并将你带到仪表盘。 之后,你只需在 `__Secure-1PSID` 本身过期时才需要重新粘贴——那是几个月,而不是几小时。服务器将 cookies 存储在你运行它的目录旁的 `.env` 文件中。 ## 工作原理 简短介绍,以备你需要调试时参考: - **Transport(传输层)**:带有 Chrome uTLS 模拟的 `curl_cffi`。如果没有它,即使带有有效的 cookies,Google 也会基于 TLS 指纹拒绝请求。 - **Auth(认证层)**:使用你的 cookies 对 `gemini.google.com/app` 进行 GET 请求,通过正则表达式从引导 HTML 中提取 `SNlM0e` access token。后续的每个 generate 请求都需要该 token。 - **Generate(生成层)**:向 `BardFrontendService/StreamGenerate` 发起 POST 请求,请求体为 form-encoded,包含 access token 和一个模仿 Web 应用发送内容的 JSON-in-JSON payload。响应是一个带有长度前缀的 JSON envelope 流,其中包含回答文本。 - **Cookie 轮换**:一个后台 `asyncio.Task` 每九分钟向 `accounts.google.com/RotateCookies` 发送 POST 请求,以保持 `__Secure-1PSIDTS` 有效。 - **仪表盘**:一个使用原生 JS + Tailwind CDN 的单文件嵌入式 HTML。活动日志使用 Server-Sent Events 进行实时更新。 由于传输格式(wire format)是逆向工程得到的,因此当 Google 进行更改时,它可能会失效。当发生这种情况时,你会看到“SNlM0e token not found in bootstrap”或类似错误——请检查 `src/aitunnel/_protocol/` 中相关的偏移量。 ## 需要了解的限制 - 每个进程仅支持一个 Google 账号。如果需要更多,请使用不同的 `.env` 在不同的端口上运行第二个实例。 - 账号级别的速率限制仍然适用。“没有 API 配额”并不意味着“完全没有配额”——如果你频繁请求,Google 将开始对该账号进行限流。 - 这是一个不断变化的目标。请固定适合你的版本;传输格式每隔几个月就会改变。 - 每个聊天会话坚持使用一个模型。在对话中途切换可能会返回 `model_inconsistent` 错误。 ## 配置 `.env`(位于 `aitunnel-server` 调用命令的旁边): ``` SECURE_1PSID=g.a000... # your long-lived auth cookie SECURE_1PSIDTS=sidts-... # the short-lived one (auto-rotated) HOST=127.0.0.1 # bind address PORT=8000 LOG_LEVEL=info # debug | info | warning | error HTTPS_PROXY= # optional outbound proxy ``` ## API 完整 endpoint 参考请参阅 [API.md](API.md)。简要亮点: ``` # 基础查询 curl -X POST localhost:8000/query \ -H 'Content-Type: application/json' \ -d '{"prompt": "hello"}' # streaming curl -N -X POST localhost:8000/query/stream \ -H 'Content-Type: application/json' \ -d '{"prompt": "tell me a story"}' # 上传文件,然后就此提问 URL=$(curl -s -X POST localhost:8000/upload -F "file=@./photo.jpg" | jq -r .url) curl -X POST localhost:8000/query \ -H 'Content-Type: application/json' \ -d "{\"prompt\":\"describe this\",\"files\":[{\"url\":\"$URL\",\"filename\":\"photo.jpg\"}]}" ``` ## 库使用(Python) aitunnel 也是一个可导入的 Python 包,因此当你从 Python 代码中调用时,可以跳过 HTTP 层: ``` import asyncio from aitunnel import Client async def main(): async with Client(psid, psidts) as c: # one-shot, never persisted to your history out = await c.query("hello") print(out.text) # streaming stream = await c.query_stream("write a poem") async for delta in stream: print(delta.text_delta, end="", flush=True) if delta.done: break await stream.aclose() # multi-turn chat = c.start_chat() await chat.send("my name is Sam") out = await chat.send("what's my name?") print(out.text) asyncio.run(main()) ``` 错误均派生自 `AitunnelError` - 可以捕获特定的子类以进行重试/处理决策: ``` from aitunnel import AuthError, UsageLimitError, TransientError, IPBlockedError try: out = await c.query(prompt) except AuthError: # cookies expired - re-auth ... except UsageLimitError: # back off or switch model ... except TransientError: # already retried by policy ... except IPBlockedError: # rotate IP / use proxy ... ``` ## 布局 ``` . ├── src/aitunnel/ │ ├── client.py, chat.py, stream.py public surface │ ├── types.py, models.py, errors.py typed contracts │ ├── retry.py retry policy │ ├── chats.py, gems.py, ... per-feature public APIs │ ├── _protocol/ wire format (auth, request, frames, response) │ ├── _transport/ curl_cffi async client + cookie rotation │ └── server/ FastAPI app + dashboard HTML └── tests/ pytest suite ``` 四层结构,各司其职。以 `_` 为前缀的包是内部 API,不会从顶级模块中导出。 ## 贡献 请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。Bug——尤其是当传输格式失效时——是主要关注点。请在提交 issue 时附带 `LOG_LEVEL=debug` 的服务器输出。 ## 致谢 Python 项目 [HanaokaYuzu/Gemini-API](https://github.com/HanaokaYuzu/Gemini-API) 率先实现了这一点,并且仍然是传输格式的权威参考。 aitunnel 是一次结构上的重构,具有更紧凑的架构(分离了 protocol/transport/client 层,单一职责文件),内置了 FastAPI 服务器和仪表盘、活动日志、多轮 HTTP API,以及更丰富的类型化错误(typed-error)层级结构。 ## 许可证 MIT。
标签:AV绕过, Cookie认证, DLL 劫持, FastAPI, Gemini, HTTP API, LLM代理, MIT许可, Pure Python, Python 3.11, SSE流式传输, Waymore结果处理, Web仪表盘, Web协议, 云资产清单, 免API密钥, 反向工程, 多轮对话, 大语言模型, 开源, 异步流式处理, 文件附件, 本地代理, 本地服务器, 活动日志, 网络隧道, 计算机取证, 逆向工具, 逆向工程