some more oc fixes

This commit is contained in:
Luxferre
2026-09-18 14:25:13 +03:00
parent f23c9132ce
commit 0cc2987dcb
3 changed files with 25 additions and 4 deletions
+1 -1
View File
@@ -125,7 +125,7 @@ Using these rules, everyone can build their own copy of Bantam from scratch in l
### Agentic loop (`AL(cfg, messages)`) function
1. Call OpenAI-compatible Completions API (`POST {endpoint}/chat/completions`) forwarding relevant parameters from `cfg` (`model`, `temperature`, `stream`, `reasoning_effort`, etc., excluding internal agent configs like `endpoint`, `api_key`, `timeout`, `shell_timeout`, `max_al_iterations`, `color`, `context_window`) and optional `api_key` bearer header.
- Set custom request headers. If the endpoint host is `opencode.ai` (or a subdomain), send the OpenCode Zen header set: `User-Agent: opencode/1.18.31 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14`, `x-opencode-client: cli`, `x-opencode-project: <project-md5>`, `x-opencode-session: <ses_...>`, and a fresh `x-opencode-request: msg_<26 base32 chars>` per call. For every other endpoint, keep the legacy `User-Agent: opencode/1.18.31` plus `X-Session-Id` and `x-session-affinity`. The `Authorization: Bearer <api_key>` header is added whenever `api_key` is set and not `-`.
- Set custom request headers. If the endpoint host is `opencode.ai` (or a subdomain), send the OpenCode Zen header set: `User-Agent: opencode/1.18.31 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14`, `x-opencode-client: cli`, `x-opencode-project: global`, `x-opencode-session: <ses_...>`, and a fresh `x-opencode-request: msg_<26 base32 chars>` per call. For every other endpoint, keep the legacy `User-Agent: opencode/1.18.31` plus `X-Session-Id` and `x-session-affinity`. The `Authorization: Bearer <api_key>` header is added whenever `api_key` is set and not `-`.
- Retry network/HTTP errors with Fibonacci backoff delays (`1s, 1s, 2s, 3s, 5s, 8s, 13s, 21s, 34s`).
- If `stream=true`, parse SSE stream (`data: {...}`) for real-time reasoning and text output, bracketing reasoning with `--- reasoning start ---` / `--- reasoning end ---` markers.
2. Append the assistant's response message object to `messages`. If non-streaming and response has reasoning tokens (`reasoning_content` or `reasoning`), output them wrapped in `--- reasoning start ---` / `--- reasoning end ---` markers.
+2 -1
View File
@@ -90,6 +90,7 @@ var defCfg = Cfg{"https://api.kilo.ai/api/openrouter", "openrouter/free", "-", 0
const opencodeAgentVersion = "opencode/1.18.31"
const opencodeProviderUA = "ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14"
const opencodeIDAlphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
const opencodeProjectID = "global"
func atoiD(s string, d int) int {
if v, e := strconv.Atoi(strings.TrimSpace(s)); e == nil {
@@ -1721,7 +1722,7 @@ func applyLLMHeaders(req *http.Request, cfg *Cfg, msgID string) {
if isOpencodeEndpoint(cfg.Endpoint) {
req.Header.Set("User-Agent", opencodeAgentVersion+" "+opencodeProviderUA)
req.Header.Set("x-opencode-client", "cli")
req.Header.Set("x-opencode-project", projectID())
req.Header.Set("x-opencode-project", opencodeProjectID)
req.Header.Set("x-opencode-session", sid)
req.Header.Set("x-opencode-request", msgID)
} else {
+22 -2
View File
@@ -1254,8 +1254,8 @@ func TestApplyLLMHeadersOpencode(t *testing.T) {
if got := req.Header.Get("x-opencode-client"); got != "cli" {
t.Errorf("x-opencode-client = %q, want cli", got)
}
if got := req.Header.Get("x-opencode-project"); got != projectID() {
t.Errorf("x-opencode-project = %q, want %q", got, projectID())
if got := req.Header.Get("x-opencode-project"); got != "global" {
t.Errorf("x-opencode-project = %q, want global", got)
}
if got := req.Header.Get("x-opencode-session"); got != opencodeSessionID() {
t.Errorf("x-opencode-session = %q, want %q", got, opencodeSessionID())
@@ -1271,6 +1271,26 @@ func TestApplyLLMHeadersOpencode(t *testing.T) {
}
}
func TestApplyLLMHeadersRequestID(t *testing.T) {
cfg := defCfg
cfg.Endpoint = "https://opencode.ai/zen/v1"
cfg.APIKey = "-"
req, _ := http.NewRequest("POST", "https://opencode.ai/zen/v1/chat/completions", nil)
applyLLMHeaders(req, &cfg, ocRequestID())
got := req.Header.Get("x-opencode-request")
if !strings.HasPrefix(got, "msg_") {
t.Errorf("x-opencode-request = %q, want msg_ prefix", got)
}
if len(got) != 30 {
t.Errorf("x-opencode-request length = %d, want 30: %q", len(got), got)
}
for _, c := range got[4:] {
if !strings.ContainsRune(opencodeIDAlphabet, c) {
t.Errorf("invalid character %c in x-opencode-request %q", c, got)
}
}
}
func TestApplyLLMHeadersOpencodeAuth(t *testing.T) {
cfg := defCfg
cfg.Endpoint = "https://opencode.ai/zen/v1"