Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .air/build-errors.log
Original file line number Diff line number Diff line change
@@ -1 +1 @@
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1signal: terminatedexit status 1exit status 1signal: terminatedexit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1signal: terminatedsignal: terminatedexit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1signal: terminatedexit status 1exit status 1signal: terminatedexit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1signal: terminatedsignal: terminatedexit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
71 changes: 71 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: VitePress Pages

on:
pull_request:
branches: [main]
paths:
- "docs/**"
- "package.json"
push:
branches: [main]
paths:
- "docs/**"
- "package.json"
workflow_dispatch:

concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
pages: write
id-token: write

jobs:
build:
name: Build Docs
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: docs/package.json

- name: Install dependencies
working-directory: docs
run: npm install --frozen-lockfile

- name: Build docs
working-directory: docs
run: npm run docs:build

- name: Verify built docs
run: test -f docs/.vitepress/dist/index.html

- name: Upload pages artifact
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: docs/.vitepress/dist/

deploy:
name: Deploy Pages
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Configure Pages
uses: actions/configure-pages@v5

- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
2 changes: 1 addition & 1 deletion .github/workflows/vitepress-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ permissions:
id-token: write

concurrency:
group: cliproxy-vitepress-pages
group: cliproxy++-vitepress-pages
cancel-in-progress: false

jobs:
Expand Down
41 changes: 36 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,42 @@ providers:

## Documentation

- `docs/start-here.md` - Getting started guide
- `docs/provider-usage.md` - Provider configuration
- `docs/provider-quickstarts.md` - Per-provider guides
- `docs/api/` - API reference
- `docs/sdk-usage.md` - SDK guides
### Quick Links
- **[Getting Started](docs/getting-started.md)** - First run and configuration
- **[Installation](docs/install.md)** - Docker, binary, and source options
- **[Provider Usage](docs/provider-usage.md)** - Provider strategy and setup
- **[Provider Quickstarts](docs/provider-quickstarts.md)** - 5-minute success paths per provider
- **[API Reference](docs/api/)** - OpenAI-compatible and management APIs
- **[Operations](docs/operations/)** - Health, metrics, and incident workflows

### Documentation Structure

```
docs/
├── start-here.md # Start here guide
├── getting-started.md # First run tutorial
├── install.md # Installation options
├── provider-usage.md # Provider configuration
├── provider-quickstarts.md # Per-provider guides
├── provider-catalog.md # Provider reference
├── provider-operations.md # Operational runbooks
├── api/ # API documentation
│ ├── openai-compatible.md
│ ├── management.md
│ └── operations.md
├── guides/ # How-to guides
├── features/ # Feature deep-dives
├── tutorials/ # Step-by-step tutorials
├── reference/ # Command and config reference
└── operations/ # Runbooks and procedures
```

### GitHub Pages

Documentation is automatically built and deployed via GitHub Actions:
- **Workflow**: `.github/workflows/docs.yml`
- **URL**: `https://kooshapari.github.io/cliproxy-plus-plus/` (after first deploy)
- **Local Dev**: `cd docs && npm run docs:dev`

## Environment

Expand Down
8 changes: 4 additions & 4 deletions internal/registry/model_definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func GetGitHubCopilotModels() []*ModelInfo {
Type: "github-copilot",
DisplayName: "GPT-5",
Description: "OpenAI GPT-5 via GitHub Copilot",
ContextLength: 200000,
ContextLength: 128000,
MaxCompletionTokens: 32768,
SupportedEndpoints: []string{"/chat/completions", "/responses"},
Thinking: &ThinkingSupport{Levels: []string{"low", "medium", "high"}},
Expand All @@ -204,7 +204,7 @@ func GetGitHubCopilotModels() []*ModelInfo {
Type: "github-copilot",
DisplayName: "GPT-5 Codex",
Description: "OpenAI GPT-5 Codex via GitHub Copilot",
ContextLength: 200000,
ContextLength: 128000,
MaxCompletionTokens: 32768,
SupportedEndpoints: []string{"/responses"},
Thinking: &ThinkingSupport{Levels: []string{"low", "medium", "high"}},
Expand All @@ -217,7 +217,7 @@ func GetGitHubCopilotModels() []*ModelInfo {
Type: "github-copilot",
DisplayName: "GPT-5.1",
Description: "OpenAI GPT-5.1 via GitHub Copilot",
ContextLength: 200000,
ContextLength: 128000,
MaxCompletionTokens: 32768,
SupportedEndpoints: []string{"/chat/completions", "/responses"},
Thinking: &ThinkingSupport{Levels: []string{"none", "low", "medium", "high"}},
Expand All @@ -230,7 +230,7 @@ func GetGitHubCopilotModels() []*ModelInfo {
Type: "github-copilot",
DisplayName: "GPT-5.1 Codex",
Description: "OpenAI GPT-5.1 Codex via GitHub Copilot",
ContextLength: 200000,
ContextLength: 128000,
MaxCompletionTokens: 32768,
SupportedEndpoints: []string{"/responses"},
Thinking: &ThinkingSupport{Levels: []string{"none", "low", "medium", "high"}},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,16 +357,9 @@ func ConvertOpenAIResponsesRequestToGemini(modelName string, inputRawJSON []byte
// Convert parameter types from OpenAI format to Gemini format
cleaned := params.Raw
// Convert type values to uppercase for Gemini
paramsResult := gjson.Parse(cleaned)
if properties := paramsResult.Get("properties"); properties.Exists() {
properties.ForEach(func(key, value gjson.Result) bool {
if propType := value.Get("type"); propType.Exists() {
upperType := strings.ToUpper(propType.String())
cleaned, _ = sjson.Set(cleaned, "properties."+key.String()+".type", upperType)
}
return true
})
}
// Skip type uppercasing - let CleanJSONSchemaForGemini handle type arrays
// This fixes the bug where nullable type arrays like ["string","null"] were
// incorrectly converted to strings causing 400 errors on Gemini API
// Set the overall type to OBJECT
cleaned, _ = sjson.Set(cleaned, "type", "OBJECT")
funcDecl, _ = sjson.SetRaw(funcDecl, "parametersJsonSchema", cleaned)
Expand Down
2 changes: 1 addition & 1 deletion internal/translator/kiro/claude/truncation_detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ var RequiredFieldsByTool = map[string][]string{
"edit_file": {"path"},
"apply_diff": {"path", "diff"},
"str_replace_editor": {"path", "old_str", "new_str"},
"Bash": {"command"},
"Bash": {"command", "cmd"}, // Ampcode uses "cmd", others use "command"
"execute": {"command"},
"run_command": {"command"},
}
Expand Down
15 changes: 14 additions & 1 deletion pkg/llmproxy/executor/codex_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,20 @@ func (e *CodexExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Au
}
appendAPIResponseChunk(ctx, e.cfg, data)
logWithRequestID(ctx).Debugf("request error, error status: %d, error message: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), data))
err = statusErr{code: httpResp.StatusCode, msg: string(data)}
// Check for unsupported model errors and provide a clearer message
errMsg := string(data)
if httpResp.StatusCode == 400 && strings.Contains(errMsg, "not supported") {
// Provide a user-friendly error for unsupported models with ChatGPT cookies
if strings.Contains(errMsg, "gpt-5.3-codex-spark") || strings.Contains(errMsg, "codex-spark") {
err = statusErr{
code: httpResp.StatusCode,
msg: "Model gpt-5.3-codex-spark requires a Plus/Team/Enterprise ChatGPT account. Please upgrade your plan or use a different provider. Original error: " + errMsg,
}
return nil, err
}
}

err = statusErr{code: httpResp.StatusCode, msg: errMsg}
return nil, err
}
out := make(chan cliproxyexecutor.StreamChunk)
Expand Down
Loading