Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a73d8c4a3 | ||
|
|
a318dff8b0 | ||
|
|
4a159d5bf5 | ||
|
|
734b040a48 |
10
README.md
10
README.md
@@ -8,6 +8,16 @@ It now also supports OpenAI Codex (GPT models) and Claude Code via OAuth.
|
||||
|
||||
So you can use local or multi-account CLI access with OpenAI(include Responses)/Gemini/Claude-compatible clients and SDKs.
|
||||
|
||||
## Sponsor
|
||||
|
||||
[](https://z.ai/subscribe?ic=8JVLJQFSKB)
|
||||
|
||||
This project is sponsored by Z.ai, supporting us with their GLM CODING PLAN.
|
||||
|
||||
GLM CODING PLAN is a subscription service designed for AI coding, starting at just $3/month. It provides access to their flagship GLM-4.6 model across 10+ popular AI coding tools (Claude Code, Cline, Roo Code, etc.), offering developers top-tier, fast, and stable coding experiences.
|
||||
|
||||
Get 10% OFF GLM CODING PLAN:https://z.ai/subscribe?ic=8JVLJQFSKB
|
||||
|
||||
## Overview
|
||||
|
||||
- OpenAI/Gemini/Claude compatible API endpoints for CLI models
|
||||
|
||||
10
README_CN.md
10
README_CN.md
@@ -8,7 +8,15 @@
|
||||
|
||||
您可以使用本地或多账户的CLI方式,通过任何与 OpenAI(包括Responses)/Gemini/Claude 兼容的客户端和SDK进行访问。
|
||||
|
||||
现已新增国内提供商:[Qwen Code](https://github.com/QwenLM/qwen-code)、[iFlow](https://iflow.cn/)。
|
||||
## 赞助商
|
||||
|
||||
[](https://www.bigmodel.cn/claude-code?ic=RRVJPB5SII)
|
||||
|
||||
本项目由 Z智谱 提供赞助, 他们通过 GLM CODING PLAN 对本项目提供技术支持。
|
||||
|
||||
GLM CODING PLAN 是专为AI编码打造的订阅套餐,每月最低仅需20元,即可在十余款主流AI编码工具如 Claude Code、Cline、Roo Code 中畅享智谱旗舰模型GLM-4.6,为开发者提供顶尖的编码体验。
|
||||
|
||||
智谱AI为本软件提供了特别优惠,使用以下链接购买可以享受九折优惠:https://www.bigmodel.cn/claude-code?ic=RRVJPB5SII
|
||||
|
||||
## 功能特性
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ func ConvertClaudeRequestToCLI(modelName string, inputRawJSON []byte, _ bool) []
|
||||
if len(toolCallIDs) > 1 {
|
||||
funcName = strings.Join(toolCallIDs[0:len(toolCallIDs)-1], "-")
|
||||
}
|
||||
responseData := contentResult.Get("content").String()
|
||||
responseData := contentResult.Get("content").Raw
|
||||
functionResponse := client.FunctionResponse{Name: funcName, Response: map[string]interface{}{"result": responseData}}
|
||||
clientContent.Parts = append(clientContent.Parts, client.Part{FunctionResponse: &functionResponse})
|
||||
}
|
||||
@@ -127,6 +127,7 @@ func ConvertClaudeRequestToCLI(modelName string, inputRawJSON []byte, _ bool) []
|
||||
inputSchema := inputSchemaResult.Raw
|
||||
tool, _ := sjson.Delete(toolResult.Raw, "input_schema")
|
||||
tool, _ = sjson.SetRaw(tool, "parametersJsonSchema", inputSchema)
|
||||
tool, _ = sjson.Delete(tool, "strict")
|
||||
var toolDeclaration any
|
||||
if err := json.Unmarshal([]byte(tool), &toolDeclaration); err == nil {
|
||||
tools[0].FunctionDeclarations = append(tools[0].FunctionDeclarations, toolDeclaration)
|
||||
|
||||
@@ -149,11 +149,7 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
|
||||
toolCallID := m.Get("tool_call_id").String()
|
||||
if toolCallID != "" {
|
||||
c := m.Get("content")
|
||||
if c.Type == gjson.String {
|
||||
toolResponses[toolCallID] = c.String()
|
||||
} else if c.IsObject() && c.Get("type").String() == "text" {
|
||||
toolResponses[toolCallID] = c.Get("text").String()
|
||||
}
|
||||
toolResponses[toolCallID] = c.Raw
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,7 +250,7 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
|
||||
if resp == "" {
|
||||
resp = "{}"
|
||||
}
|
||||
toolNode, _ = sjson.SetRawBytes(toolNode, "parts."+itoa(pp)+".functionResponse.response", []byte(`{"result":`+quoteIfNeeded(resp)+`}`))
|
||||
toolNode, _ = sjson.SetBytes(toolNode, "parts."+itoa(pp)+".functionResponse.response.result", []byte(resp))
|
||||
pp++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ func ConvertClaudeRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
|
||||
if len(toolCallIDs) > 1 {
|
||||
funcName = strings.Join(toolCallIDs[0:len(toolCallIDs)-1], "-")
|
||||
}
|
||||
responseData := contentResult.Get("content").String()
|
||||
responseData := contentResult.Get("content").Raw
|
||||
functionResponse := client.FunctionResponse{Name: funcName, Response: map[string]interface{}{"result": responseData}}
|
||||
clientContent.Parts = append(clientContent.Parts, client.Part{FunctionResponse: &functionResponse})
|
||||
}
|
||||
|
||||
@@ -150,14 +150,11 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
|
||||
toolCallID := m.Get("tool_call_id").String()
|
||||
if toolCallID != "" {
|
||||
c := m.Get("content")
|
||||
if c.Type == gjson.String {
|
||||
toolResponses[toolCallID] = c.String()
|
||||
} else if c.IsObject() && c.Get("type").String() == "text" {
|
||||
toolResponses[toolCallID] = c.Get("text").String()
|
||||
}
|
||||
toolResponses[toolCallID] = c.Raw
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Printf("11111")
|
||||
|
||||
for i := 0; i < len(arr); i++ {
|
||||
m := arr[i]
|
||||
@@ -280,7 +277,7 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
|
||||
if resp == "" {
|
||||
resp = "{}"
|
||||
}
|
||||
toolNode, _ = sjson.SetRawBytes(toolNode, "parts."+itoa(pp)+".functionResponse.response", []byte(`{"result":`+quoteIfNeeded(resp)+`}`))
|
||||
toolNode, _ = sjson.SetBytes(toolNode, "parts."+itoa(pp)+".functionResponse.response.result", []byte(resp))
|
||||
pp++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,17 +143,11 @@ func ConvertOpenAIResponsesRequestToGemini(modelName string, inputRawJSON []byte
|
||||
}
|
||||
|
||||
functionResponse, _ = sjson.Set(functionResponse, "functionResponse.name", functionName)
|
||||
// Also set response.name to align with docs/convert-2.md
|
||||
functionResponse, _ = sjson.Set(functionResponse, "functionResponse.response.name", functionName)
|
||||
|
||||
// Parse output JSON string and set as response content
|
||||
if output != "" {
|
||||
outputResult := gjson.Parse(output)
|
||||
if outputResult.IsObject() {
|
||||
functionResponse, _ = sjson.SetRaw(functionResponse, "functionResponse.response.content", outputResult.String())
|
||||
} else {
|
||||
functionResponse, _ = sjson.Set(functionResponse, "functionResponse.response.content", output)
|
||||
}
|
||||
functionResponse, _ = sjson.Set(functionResponse, "functionResponse.response.result", outputResult.Raw)
|
||||
}
|
||||
|
||||
functionContent, _ = sjson.SetRaw(functionContent, "parts.-1", functionResponse)
|
||||
|
||||
Reference in New Issue
Block a user