Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save muhfaris/cb9529b7bece2ebda6a2f879f0a3adfd to your computer and use it in GitHub Desktop.

Select an option

Save muhfaris/cb9529b7bece2ebda6a2f879f0a3adfd to your computer and use it in GitHub Desktop.
Custom Adapter CodeCompanion NVIM
---
### Ringkasan Masalah
Adapter custom `sumopod_buddy` yang extend dari OpenAI adapter gagal berkomunikasi dengan backend LiteLLM karena **3 bug berbeda** yang ditemukan secara bertahap.
---
### Bug #1 — `model=None` (Error 400)
**Error:**
```
Invalid model name passed in model=None
```
**Penyebab:**
Config mendefinisikan `model` di **dua tempat sekaligus** yang saling konflik:
```lua
-- KONFLIK: model di-set di parameters...
parameters = {
model = "gpt-4o-mini", -- <-- ini
},
-- ...dan juga di schema dengan mapping ke parameters
schema = {
model = {
mapping = "parameters", -- <-- ini juga inject ke parameters
default = "gpt-4o-mini",
},
},
```
OpenAI adapter punya logic di `setup` handler yang me-resolve model dari `schema.model.default` dan meng-inject-nya ke parameters. Ketika `model` sudah ada di `parameters` secara hardcode, terjadi konflik dan hasilnya `None`.
**Fix:** Hapus `model` dari `parameters` table. Biarkan schema yang handle injection-nya.
---
### Bug #2 — `before_request` handler tidak ada (Silent Fail)
**Error:** Tidak ada error eksplisit — handler diabaikan sepenuhnya.
**Penyebab:**
Kode awal menggunakan lifecycle hook `before_request` yang **tidak exist** di CodeCompanion:
```lua
handlers = {
lifecycle = {
before_request = function(self, request) -- <-- tidak ada di docs
-- patch tool schema
end,
},
},
```
Lifecycle handlers yang valid hanya: `setup`, `on_exit`, `teardown`.
**Fix:** Pindah logic patch ke `request.build_tools` yang memang tempat yang tepat untuk mutate tool schema sebelum dikirim.
---
### Bug #3 — Tool Schema Invalid untuk Strict Mode (Error 400)
**Error:**
```
Invalid schema for function 'sequential-thinking_sequentialthinking':
- 'required' is required to be supplied and to be an array including every key in properties. Missing 'isRevision'
- 'additionalProperties' is required to be supplied and to be false
```
**Penyebab:**
Tool `sequential-thinking` dari MCP server menggunakan `strict: true`. OpenAI strict mode mengharuskan:
1. `additionalProperties` harus `false`
2. **Semua** keys di `properties` harus ada di array `required`
Tool schema yang dikirim hanya punya sebagian keys di `required`:
```lua
required = { "thought", "nextThoughtNeeded", "thoughtNumber", "totalThoughts" }
-- Missing: isRevision, revisesThought, branchFromThought, branchId, needsMoreThoughts
```
**Sub-bug saat patching:** Kondisi pengecekan `strict` salah level:
```lua
-- SALAH: strict dicek di schema level
if fn and schema.strict == true then
-- BENAR: strict ada di fn level
local is_strict = schema.strict == true or (fn and fn.strict == true)
```
Struktur aktual payload:
```lua
{
["function"] = {
strict = true, -- <-- strict ada di sini
name = "...",
parameters = { ... }
},
type = "function"
}
```
**Fix final di `build_tools`:**
```lua
build_tools = function(self, tools)
if not self.opts.tools or not tools or vim.tbl_count(tools) == 0 then
return nil
end
local transformed = {}
for _, tool in pairs(tools) do
for _, schema in pairs(tool) do
local fn = schema["function"]
local is_strict = schema.strict == true or (fn and fn.strict == true)
if fn and is_strict then
local params = fn.parameters
if params and params.type == "object" and params.properties then
params.additionalProperties = false
local all_keys = {}
for k, _ in pairs(params.properties) do
table.insert(all_keys, k)
end
params.required = all_keys
end
end
table.insert(transformed, schema)
end
end
return { tools = transformed }
end,
```
---
### Timeline Error
| # | Error | Root Cause |
|---|-------|-----------|
| 1 | `model=None` | `model` didefinisikan dobel di `parameters` dan `schema` |
| 2 | `Internal Server Error 500` | Tool schema invalid karena `before_request` tidak exist, patch tidak jalan |
| 3 | `missing 'isRevision'` | Strict mode butuh semua properties di `required` |
| 4 | `additionalProperties` required | Patch tidak kepanggil karena cek `schema.strict` salah level |
| ✅ | Berhasil | Semua fix diterapkan |
---
### Pelajaran
1. **Selalu cek docs** untuk lifecycle hooks yang tersedia — jangan assume ada `before_request`
2. **Jangan definisikan `model` di dua tempat** — pilih schema atau parameters, bukan keduanya
3. **OpenAI strict mode** butuh schema yang benar-benar ketat: semua properties wajib di `required` + `additionalProperties: false`
4. **Debug dengan `vim.notify(vim.inspect(...))`** adalah cara paling efektif untuk lihat payload aktual yang dikirim
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment