Skip to content

Commit d2a3bb3

Browse files
author
WebAPI
committed
feat: v1.0.0 release - DeepSeek/Qwen/Doubao AI relay proxy
- DeepSeek channel with PoW support (port 55555) - Qwen channel (port 56666) - Doubao channel (port 55556) - OpenAI-compatible API (/v1/chat/completions) - SSE streaming support - WebView2-based browser integration - Real-time logging - Multi-tab UI with dark theme
0 parents  commit d2a3bb3

47 files changed

Lines changed: 7393 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# .NET build outputs
2+
bin/
3+
obj/
4+
out/
5+
6+
# Logs
7+
log/
8+
*.log
9+
10+
# Local config overrides (contains user-specific settings)
11+
config/settings.local.json
12+
13+
# WebView2 user data
14+
*_Data/
15+
WebView2Data/
16+
17+
# IDE
18+
.vs/
19+
.vscode/
20+
*.user
21+
*.suo
22+
*.userosscache
23+
*.sln.docstates
24+
*.rsuser
25+
26+
# OS
27+
Thumbs.db
28+
.DS_Store
29+
Desktop.ini
30+
31+
# NuGet
32+
packages/
33+
34+
# Publish
35+
publish/
36+
*.exe
37+
*.dll
38+
39+
# Temp
40+
*.tmp
41+
*.cache

DeepSeek网页转API_20260527_154447.qka

Lines changed: 872 additions & 0 deletions
Large diffs are not rendered by default.

IconInjector/IconInjector.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net9.0</TargetFramework>
5+
</PropertyGroup>
6+
</Project>

IconInjector/Program.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.IO;
3+
using System.Runtime.InteropServices;
4+
5+
public class IconInjector
6+
{
7+
[DllImport("kernel32.dll", SetLastError = true)]
8+
static extern IntPtr BeginUpdateResource(string pFileName, [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);
9+
10+
[DllImport("kernel32.dll", SetLastError = true)]
11+
static extern bool UpdateResource(IntPtr hUpdate, uint lpType, ushort lpName, ushort wLanguage, byte[] lpData, uint cbData);
12+
13+
[DllImport("kernel32.dll", SetLastError = true)]
14+
static extern bool EndUpdateResource(IntPtr hUpdate, [MarshalAs(UnmanagedType.Bool)]bool fDiscard);
15+
16+
[DllImport("kernel32.dll")]
17+
static extern uint GetLastError();
18+
19+
const uint RT_ICON = 3;
20+
const uint RT_GROUP_ICON = 14;
21+
22+
public static void Main(string[] args)
23+
{
24+
if (args.Length < 2)
25+
{
26+
Console.WriteLine("Usage: IconInjector <exePath> <iconPath>");
27+
return;
28+
}
29+
30+
string exePath = args[0];
31+
string iconPath = args[1];
32+
33+
try
34+
{
35+
UpdateIcon(exePath, iconPath);
36+
Console.WriteLine("Icon updated successfully!");
37+
}
38+
catch (Exception ex)
39+
{
40+
Console.WriteLine("Error: " + ex.Message);
41+
}
42+
}
43+
44+
public static void UpdateIcon(string exePath, string iconPath)
45+
{
46+
byte[] iconData = File.ReadAllBytes(iconPath);
47+
48+
IntPtr hUpdate = BeginUpdateResource(exePath, false);
49+
if (hUpdate == IntPtr.Zero)
50+
{
51+
uint error = GetLastError();
52+
throw new Exception("Cannot open exe file, error code: " + error);
53+
}
54+
55+
try
56+
{
57+
bool result = UpdateResource(hUpdate, RT_GROUP_ICON, 1, 0, iconData, (uint)iconData.Length);
58+
if (!result)
59+
{
60+
uint error = GetLastError();
61+
throw new Exception("Update icon group failed, error code: " + error);
62+
}
63+
64+
result = UpdateResource(hUpdate, RT_ICON, 1, 0, iconData, (uint)iconData.Length);
65+
if (!result)
66+
{
67+
uint error = GetLastError();
68+
throw new Exception("Update icon failed, error code: " + error);
69+
}
70+
}
71+
finally
72+
{
73+
if (!EndUpdateResource(hUpdate, false))
74+
{
75+
uint error = GetLastError();
76+
Console.WriteLine("Warning: Error ending update, code: " + error);
77+
}
78+
}
79+
}
80+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 WebAPI Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Qwen千问无限API_20260527_160135.qka

Lines changed: 222 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# WebAPI - AI 网页工具转本地 API 代理服务
2+
3+
将 DeepSeek、通义千问、豆包等网页版 AI 工具转换为本地 OpenAI 兼容 API 接口。
4+
5+
## 特性
6+
7+
- **多渠支持**: DeepSeek、通义千问、豆包
8+
- **OpenAI 兼容**: 完全兼容 OpenAI API 格式,可直接用于各种客户端
9+
- **流式响应**: 支持 SSE 流式输出
10+
- **WebView2 内核**: 基于微软 WebView2 的真实浏览器环境
11+
- **独立端口**: 每个渠道独立端口,互不干扰
12+
- **实时日志**: 内置日志窗口,实时查看请求状态
13+
14+
## 快速开始
15+
16+
### 系统要求
17+
18+
- Windows 10/11
19+
- .NET 9.0 Runtime (或使用 self-contained 版本)
20+
- Microsoft Edge WebView2 Runtime (通常已预装)
21+
22+
### 安装
23+
24+
1. 下载最新 Release 版本
25+
2. 解压到任意目录
26+
3. 运行 `WebAPI.exe`
27+
28+
### 配置
29+
30+
各渠道默认配置:
31+
32+
| 渠道 | Base URL | 默认端口 |
33+
|------|----------|----------|
34+
| DeepSeek | `http://127.0.0.1:55555` | 55555 |
35+
| 通义千问 | `http://127.0.0.1:56666` | 56666 |
36+
| 豆包 | `http://127.0.0.1:55556` | 55556 |
37+
38+
## 使用示例
39+
40+
### cURL
41+
42+
```bash
43+
# 非流式请求
44+
curl -X POST http://127.0.0.1:55555/v1/chat/completions \
45+
-H "Content-Type: application/json" \
46+
-H "Authorization: Bearer sk-any" \
47+
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"你好"}],"stream":false}'
48+
49+
# 流式请求
50+
curl -X POST http://127.0.0.1:55555/v1/chat/completions \
51+
-H "Content-Type: application/json" \
52+
-H "Authorization: Bearer sk-any" \
53+
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"你好"}],"stream":true}'
54+
```
55+
56+
### Python (OpenAI SDK)
57+
58+
```python
59+
from openai import OpenAI
60+
61+
# DeepSeek
62+
client = OpenAI(base_url="http://127.0.0.1:55555/v1", api_key="sk-any")
63+
response = client.chat.completions.create(
64+
model="deepseek-chat",
65+
messages=[{"role": "user", "content": "你好"}],
66+
stream=True
67+
)
68+
for chunk in response:
69+
if chunk.choices[0].delta.content:
70+
print(chunk.choices[0].delta.content, end="")
71+
```
72+
73+
### 配置文件
74+
75+
编辑 `config/settings.json` 可以自定义端口和模型列表。
76+
77+
## 可用模型
78+
79+
### DeepSeek
80+
- `deepseek-chat` - 标准对话(极速)
81+
- `deepseek-chat-search` - 联网对话(搜索)
82+
- `deepseek-reasoner` - 深度思考(R1)
83+
- `deepseek-reasoner-search` - R1联网(弱)
84+
85+
### 通义千问
86+
- `qwen-turbo` - 千问加速
87+
- `qwen-plus` - 千问增强
88+
- `qwen-max` - 千问旗舰
89+
- `qwen-max-long` - 千问长文本
90+
91+
### 豆包
92+
- `doubao-pro` - 豆包Pro
93+
- `doubao-lite` - 豆包Lite
94+
- `doubao-role` - 角色扮演
95+
96+
## 功能
97+
98+
- **健康检查**: `GET /health` 返回服务状态
99+
- **模型列表**: `GET /v1/models` 返回可用模型列表
100+
- **对话接口**: `POST /v1/chat/completions` OpenAI 兼容对话接口
101+
- **关闭服务**: `GET /shutdown` 优雅关闭服务
102+
103+
## 常见问题
104+
105+
### Q: 为什么需要登录?
106+
A: 本工具通过 WebView2 嵌入真实浏览器环境,需要你在对应 AI 平台保持登录状态。
107+
108+
### Q: 响应速度慢?
109+
A: 首次请求可能需要等待页面加载,后续请求会快很多。可以使用"重启浏览器内核"按钮重置状态。
110+
111+
### Q: 出现"找不到输入框"错误?
112+
A: 目标网页的 DOM 结构可能已更新。请尝试点击"重启浏览器内核"按钮。
113+
114+
### Q: 支持 macOS/Linux 吗?
115+
A: 当前仅支持 Windows。macOS/Linux 支持正在规划中。
116+
117+
## 技术栈
118+
119+
- .NET 9.0 WPF
120+
- WebView2
121+
- HttpListener
122+
- OpenAI 兼容 API 格式
123+
124+
## 许可证
125+
126+
MIT License
127+
128+
## 开发计划
129+
130+
| 阶段 | 内容 | 状态 |
131+
|------|------|------|
132+
| Phase 0 | 项目初始化与基础框架 | ✅ 完成 |
133+
| Phase 1 | DeepSeek 渠道 | ✅ 完成 |
134+
| Phase 2 | 通义千问渠道 | ✅ 完成 |
135+
| Phase 3 | 豆包渠道 | ✅ 完成 |
136+
| Phase 4 | UI打磨与功能完善 | ⏳ 进行中 |
137+
| Phase 5 | 测试、文档与发布 | ⏳ 进行中 |
138+
139+
## 贡献
140+
141+
欢迎提交 Issue 和 Pull Request!

WebAPI.sln

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31903.59
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAPI", "src\WebAPI\WebAPI.csproj", "{76448264-5BE1-4E85-9762-6117F2043C49}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Debug|x64 = Debug|x64
14+
Debug|x86 = Debug|x86
15+
Release|Any CPU = Release|Any CPU
16+
Release|x64 = Release|x64
17+
Release|x86 = Release|x86
18+
EndGlobalSection
19+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20+
{76448264-5BE1-4E85-9762-6117F2043C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{76448264-5BE1-4E85-9762-6117F2043C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{76448264-5BE1-4E85-9762-6117F2043C49}.Debug|x64.ActiveCfg = Debug|Any CPU
23+
{76448264-5BE1-4E85-9762-6117F2043C49}.Debug|x64.Build.0 = Debug|Any CPU
24+
{76448264-5BE1-4E85-9762-6117F2043C49}.Debug|x86.ActiveCfg = Debug|Any CPU
25+
{76448264-5BE1-4E85-9762-6117F2043C49}.Debug|x86.Build.0 = Debug|Any CPU
26+
{76448264-5BE1-4E85-9762-6117F2043C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
27+
{76448264-5BE1-4E85-9762-6117F2043C49}.Release|Any CPU.Build.0 = Release|Any CPU
28+
{76448264-5BE1-4E85-9762-6117F2043C49}.Release|x64.ActiveCfg = Release|Any CPU
29+
{76448264-5BE1-4E85-9762-6117F2043C49}.Release|x64.Build.0 = Release|Any CPU
30+
{76448264-5BE1-4E85-9762-6117F2043C49}.Release|x86.ActiveCfg = Release|Any CPU
31+
{76448264-5BE1-4E85-9762-6117F2043C49}.Release|x86.Build.0 = Release|Any CPU
32+
EndGlobalSection
33+
GlobalSection(SolutionProperties) = preSolution
34+
HideSolutionNode = FALSE
35+
EndGlobalSection
36+
GlobalSection(NestedProjects) = preSolution
37+
{76448264-5BE1-4E85-9762-6117F2043C49} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
38+
EndGlobalSection
39+
EndGlobal

config/settings.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"channels": [
3+
{
4+
"id": "deepseek",
5+
"name": "DeepSeek",
6+
"enabled": true,
7+
"port": 55555,
8+
"targetUrl": "https://chat.deepseek.com/",
9+
"icon": "💬",
10+
"models": [
11+
{ "id": "deepseek-chat", "name": "标准对话(极速)" },
12+
{ "id": "deepseek-chat-search", "name": "联网对话(搜索)" },
13+
{ "id": "deepseek-reasoner", "name": "深度思考(R1)" },
14+
{ "id": "deepseek-reasoner-search", "name": "R1联网(弱)" }
15+
]
16+
},
17+
{
18+
"id": "qwen",
19+
"name": "通义千问",
20+
"enabled": true,
21+
"port": 56666,
22+
"targetUrl": "https://qianwen.aliyun.com/",
23+
"icon": "🔮",
24+
"models": [
25+
{ "id": "qwen-turbo", "name": "千问加速" },
26+
{ "id": "qwen-plus", "name": "千问增强" },
27+
{ "id": "qwen-max", "name": "千问旗舰" }
28+
]
29+
},
30+
{
31+
"id": "doubao",
32+
"name": "豆包",
33+
"enabled": true,
34+
"port": 55556,
35+
"targetUrl": "https://www.doubao.com/",
36+
"icon": "🫘",
37+
"models": [
38+
{ "id": "doubao-pro", "name": "豆包Pro" },
39+
{ "id": "doubao-lite", "name": "豆包Lite" }
40+
]
41+
}
42+
],
43+
"logging": {
44+
"level": "info",
45+
"keepDays": 30
46+
}
47+
}

0 commit comments

Comments
 (0)