fix(opencode): убрать смешение слоёв API — перейти целиком на experimental (/session)
Корень проблемы «не получаем результаты»: клиент смешивал два слоя opencode
serve. CreateSession ходил на /api/session (v2, ждал {data.id}), Verdict — на
/api/session/{id}/message?order=desc и ждал {data:[{type,content}]}, где поле
content[].type/text физически отсутствует, поэтому вердикт никогда не находился
и поллинг уходил в вечный таймаут. Abort и вовсе звал несуществующий /interrupt.
Теперь весь код на experimental-слое, как сверено с sst/opencode (ветка dev):
- CreateSession: POST /session → голая Session, id в .id.
- Send: блокирующий POST /session/{id}/message, тело {parts:[{type:text,text}]},
вердикт из частей parts[].type=="text" ответа. Это и есть результат — метод
Verdict и отдельный GET удалены.
- textCount (прогресс): GET /session/{id}/message → голый массив [{info, parts}].
- Abort: POST /session/{id}/abort.
Runner: блокирующий Send запускается в горутине (канал вердикта/ошибки),
параллельно поллим textCount (рост text-частей сбрасывает idle-таймер). При
idle/hard-таймауте или отмене контекста — Abort + cancel() Send-горутины → rc=-1.
Send ходит через отдельный http.Client без жёсткого Timeout (управляется ctx),
чтобы длинная генерация не обрывалась на 30s. Тесты/fakeAPIServer переведены на
экспериментальный формат. Версия → 0.2.2.
This commit is contained in:
@@ -30,10 +30,7 @@ func httptestURL(t *testing.T, f *fakeAPIServer) string {
|
||||
func TestRun_Success(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
f := &fakeAPIServer{
|
||||
messages: []sessionMessage{{Type: "assistant", Content: []struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
}{textPart("done")}}},
|
||||
verdictParts: []part{{Type: "text", Text: "done"}},
|
||||
}
|
||||
p, _ := fakePool(t, f, dir)
|
||||
|
||||
@@ -55,8 +52,8 @@ func TestRun_Success(t *testing.T) {
|
||||
|
||||
func TestRun_IdleTimeout(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
// сервер никогда не отдаёт text → всегда неготов, прогресс не растёт
|
||||
f := &fakeAPIServer{}
|
||||
// prompt блокируется (агент «завис»), прогресс не растёт → idle abort
|
||||
f := &fakeAPIServer{blockPrompt: true}
|
||||
p, _ := fakePool(t, f, dir)
|
||||
|
||||
r := &Runner{Pool: p, IdleTimeout: 30 * time.Millisecond,
|
||||
@@ -72,7 +69,7 @@ func TestRun_IdleTimeout(t *testing.T) {
|
||||
|
||||
func TestRun_ContextCancel(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
f := &fakeAPIServer{}
|
||||
f := &fakeAPIServer{blockPrompt: true}
|
||||
p, _ := fakePool(t, f, dir)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -102,10 +99,7 @@ func TestRun_ContextCancel(t *testing.T) {
|
||||
func TestResumeDev_NoFallbackOnSuccess(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
f := &fakeAPIServer{
|
||||
messages: []sessionMessage{{Type: "assistant", Content: []struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
}{textPart("ok")}}},
|
||||
verdictParts: []part{{Type: "text", Text: "ok"}},
|
||||
}
|
||||
p, _ := fakePool(t, f, dir)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user