fix: OCGO 激活用量端点从 zen/v1 改为 zen/go/v1
- CHAT_API: opencode.ai/zen/v1/chat/completions → opencode.ai/zen/go/v1/chat/completions - fetchModels provider key: "opencode" → "opencode-go" (opencode = Zen 模型列表, opencode-go = Go 模型列表)
This commit is contained in:
parent
6a73155ed0
commit
728b3ad89e
@ -21,7 +21,7 @@ CommandCode Go 走 JSON API 抓取用量数据,Codex / ChatGPT Plus 通过 aut
|
|||||||
|
|
||||||
**服务**:
|
**服务**:
|
||||||
- ✅ DeepSeek — REST API `GET /user/balance`,API Key 认证
|
- ✅ DeepSeek — REST API `GET /user/balance`,API Key 认证
|
||||||
- ✅ OpenCode Go — OkHttp 抓 dashboard HTML,解析 `rollingUsage`/`weeklyUsage`/`monthlyUsage`。**一键激活用量**:OCGO 详情页可向 `opencode.ai/zen/v1/chat/completions` 发送简短请求(`content:hello`)触发用量统计,API Key 从设置页手动填写(存 `SessionCredential.apiKey`),模型列表从 `models.dev/api.json`(provider=`opencode`)动态获取,用户选择持久化到 `SharedPreferences("ocgo_trigger_prefs")`,响应经 `parseChatResponse()` 提取回复文本+用量统计后弹窗展示。
|
- ✅ OpenCode Go — OkHttp 抓 dashboard HTML,解析 `rollingUsage`/`weeklyUsage`/`monthlyUsage`。**一键激活用量**:OCGO 详情页可向 `opencode.ai/zen/go/v1/chat/completions` 发送简短请求(`content:hello`)触发用量统计,API Key 从设置页手动填写(存 `SessionCredential.apiKey`),模型列表从 `models.dev/api.json`(provider=`opencode-go`)动态获取,用户选择持久化到 `SharedPreferences("ocgo_trigger_prefs")`,响应经 `parseChatResponse()` 提取回复文本+用量统计后弹窗展示。
|
||||||
- ✅ CommandCode Go — JSON API 抓取用量数据,`CommandCodeUsageRepository` 解析(workspaceId = `"commandcode"`)
|
- ✅ CommandCode Go — JSON API 抓取用量数据,`CommandCodeUsageRepository` 解析(workspaceId = `"commandcode"`)
|
||||||
- ✅ Codex / ChatGPT Plus — 支持 **OAuth PKCE 登录(无头模式)** 或粘贴完整 auth.json(含 refresh_token),调 `chatgpt.com/backend-api/wham/usage`;token 过期前 60 分钟自动刷新。OpenAI 采用 refresh_token 单次轮换机制,被外部工具使用后旧 token 立即失效,需重新 OAuth 登录或导入新 auth.json。**5h 窗口可能被 OpenAI 临时关闭**(`primary_window` 返回 `null`),UI 保留空 5h 槽位 + 主标签动态化(`extras["primary.label"]`),恢复后自动填回。**一键激活用量**:Codex 详情页可向 `chatgpt.com/backend-api/codex/responses` 发送简短请求(`input:hello`)触发用量统计,模型列表从 `models.dev/api.json` 动态获取(无需认证),用户选择持久化到 `SharedPreferences("codex_trigger_prefs")`,请求需 `stream:true`+`store:false`+`ChatGPT-Account-Id` 头(从 access_token JWT 解析),SSE 响应经 `parseSseResponse()` 提取回复文本+用量统计后弹窗展示。
|
- ✅ Codex / ChatGPT Plus — 支持 **OAuth PKCE 登录(无头模式)** 或粘贴完整 auth.json(含 refresh_token),调 `chatgpt.com/backend-api/wham/usage`;token 过期前 60 分钟自动刷新。OpenAI 采用 refresh_token 单次轮换机制,被外部工具使用后旧 token 立即失效,需重新 OAuth 登录或导入新 auth.json。**5h 窗口可能被 OpenAI 临时关闭**(`primary_window` 返回 `null`),UI 保留空 5h 槽位 + 主标签动态化(`extras["primary.label"]`),恢复后自动填回。**一键激活用量**:Codex 详情页可向 `chatgpt.com/backend-api/codex/responses` 发送简短请求(`input:hello`)触发用量统计,模型列表从 `models.dev/api.json` 动态获取(无需认证),用户选择持久化到 `SharedPreferences("codex_trigger_prefs")`,请求需 `stream:true`+`store:false`+`ChatGPT-Account-Id` 头(从 access_token JWT 解析),SSE 响应经 `parseSseResponse()` 提取回复文本+用量统计后弹窗展示。
|
||||||
- ✅ Ollama Pro — Cookie 认证,OkHttp 抓 `ollama.com/settings` HTML,正则解析 plan/session(5h)/weekly 百分比 + `data-time` 重置时间 + `data-model` 模型级请求次数;无官方 API(ollama/ollama#12532)。**一键激活用量**:Ollama 详情页可向 `ollama.com/v1/chat/completions` 发送简短请求(`content:hello`)触发用量统计,API Key 从设置页手动填写(存 `SessionCredential.apiKey`),模型列表从 `models.dev/api.json`(provider=`ollama-cloud`)动态获取,用户选择持久化到 `SharedPreferences("ollama_trigger_prefs")`,响应经 `parseOllamaChatResponse()` 提取回复文本+用量统计后弹窗展示。
|
- ✅ Ollama Pro — Cookie 认证,OkHttp 抓 `ollama.com/settings` HTML,正则解析 plan/session(5h)/weekly 百分比 + `data-time` 重置时间 + `data-model` 模型级请求次数;无官方 API(ollama/ollama#12532)。**一键激活用量**:Ollama 详情页可向 `ollama.com/v1/chat/completions` 发送简短请求(`content:hello`)触发用量统计,API Key 从设置页手动填写(存 `SessionCredential.apiKey`),模型列表从 `models.dev/api.json`(provider=`ollama-cloud`)动态获取,用户选择持久化到 `SharedPreferences("ollama_trigger_prefs")`,响应经 `parseOllamaChatResponse()` 提取回复文本+用量统计后弹窗展示。
|
||||||
|
|||||||
@ -136,7 +136,7 @@ class OpenCodeGoRepository(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 models.dev/api.json 获取 OpenCode 可用模型列表(provider key = "opencode")。
|
* 从 models.dev/api.json 获取 OpenCode Go 可用模型列表(provider key = "opencode-go")。
|
||||||
* 该 API 不需要认证。
|
* 该 API 不需要认证。
|
||||||
*/
|
*/
|
||||||
suspend fun fetchModels(): Result<List<String>> = withContext(Dispatchers.IO) {
|
suspend fun fetchModels(): Result<List<String>> = withContext(Dispatchers.IO) {
|
||||||
@ -152,10 +152,10 @@ class OpenCodeGoRepository(
|
|||||||
}
|
}
|
||||||
val root = json.parseToJsonElement(resp.body?.string() ?: throw RepositoryError.ParseError("响应体为空")) as? JsonObject
|
val root = json.parseToJsonElement(resp.body?.string() ?: throw RepositoryError.ParseError("响应体为空")) as? JsonObject
|
||||||
?: throw RepositoryError.ParseError("响应根节点不是 JSON 对象")
|
?: throw RepositoryError.ParseError("响应根节点不是 JSON 对象")
|
||||||
val provider = root["opencode"] as? JsonObject
|
val provider = root["opencode-go"] as? JsonObject
|
||||||
val modelsObj = provider?.get("models") as? JsonObject
|
val modelsObj = provider?.get("models") as? JsonObject
|
||||||
modelsObj?.keys?.toList()?.sorted()
|
modelsObj?.keys?.toList()?.sorted()
|
||||||
?: throw RepositoryError.ParseError("未找到 OpenCode 模型列表")
|
?: throw RepositoryError.ParseError("未找到 OpenCode Go 模型列表")
|
||||||
}
|
}
|
||||||
if (models.isEmpty()) {
|
if (models.isEmpty()) {
|
||||||
return@withContext Result.failure(RepositoryError.ParseError("模型列表为空"))
|
return@withContext Result.failure(RepositoryError.ParseError("模型列表为空"))
|
||||||
@ -225,7 +225,7 @@ class OpenCodeGoRepository(
|
|||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "OCGO"
|
private const val TAG = "OCGO"
|
||||||
private const val MODELS_API = "https://models.dev/api.json"
|
private const val MODELS_API = "https://models.dev/api.json"
|
||||||
private const val CHAT_API = "https://opencode.ai/zen/v1/chat/completions"
|
private const val CHAT_API = "https://opencode.ai/zen/go/v1/chat/completions"
|
||||||
private val SCRAPED_FIELDS = listOf("rollingUsage", "weeklyUsage", "monthlyUsage")
|
private val SCRAPED_FIELDS = listOf("rollingUsage", "weeklyUsage", "monthlyUsage")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user