Repository navigation
Expand file tree
/
Copy pathcarried_child_test.go
More file actions
152 lines (144 loc) · 5.78 KB
/
Copy pathcarried_child_test.go
File metadata and controls
152 lines (144 loc) · 5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
// The program this package's tests carry, and the door a shell run's REAL
// child comes in by: carried_host_test.go starts this very test binary as the
// program's process, exactly as a shell run starts codeaf's own executable —
// the program's line after it, the model API's address and token in its
// environment and no key — marked by [carriedChildEnv], and TestMain then runs
// the whole dispatch (`execute`) with the fake program on the build's list.
import (
"bytes"
"context"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"strings"
"github.com/Agent-Field/codeaf/internal/delegate"
"github.com/Agent-Field/codeaf/internal/delegate/builtin"
"github.com/Agent-Field/codeaf/internal/provider/modelapi"
)
// carriedChildEnv marks a process started as a shell run's child.
const carriedChildEnv = "CODEAF_TEST_CARRIED_CHILD"
// fakeCarried is the fake program's name. It is a word no verb of codeaf's
// own is spelled with, which carried_test.go's collision law holds it to.
const fakeCarried = "fake-carried"
// fakeCarriedProgram is a program with a command flag of its own: `--calls`
// questions to the model API, a step for each answer, and a passing ending —
// or, with `--wait`, it waits to be stopped and says it was.
func fakeCarriedProgram() delegate.Delegate {
return delegate.Delegate{
Name: fakeCarried, Summary: "a program the tests carry, which asks its model a question or two", Default: "run", Page: "delegates",
Guide: "For the tests' questions to a model, with a brief that is the question.",
Commands: []delegate.Command{{
Name: "run", Usage: "[flags] -- <brief>", Summary: "does the whole task",
Bind: func(fs *flag.FlagSet) delegate.Body {
calls := fs.Int("calls", 1, "how many questions to ask the model")
wait := fs.Bool("wait", false, "wait to be stopped after the questions")
linger := fs.Duration("linger", 0, "leave a helper holding stdout this long after the program exits")
return func(ctx context.Context, host delegate.Host, args []string) error {
host.Hello([]string{"implement", "verify"})
host.Stage(delegate.StageRecord{Stage: "implement", Status: "running", Data: json.RawMessage(`{"models":["vendor/model-a"],"effort":"high"}`)})
for call := 1; call <= *calls && ctx.Err() == nil; call++ {
reply, err := askCarried(ctx, host.Models(), fmt.Sprintf("question %d: %s", call, strings.Join(args, " ")))
if err != nil {
host.Step(delegate.StepRecord{Command: "model: ask", Observation: "refused: " + err.Error()})
continue
}
host.Step(delegate.StepRecord{Command: "model: ask", Observation: reply})
}
if *wait || ctx.Err() != nil {
<-ctx.Done()
host.Terminal(delegate.Ending{Status: delegate.StatusFail, Message: "stopped before it finished"})
return nil
}
host.Stage(delegate.StageRecord{Stage: "verify", Status: "pass"})
host.Terminal(delegate.Ending{Status: delegate.StatusPass, Message: "submitted and verified", Claim: "the test is fixed", Observed: "pass"})
if *linger > 0 {
// A detached helper that inherited stdout and outlives the
// program, which keeps the launch draining after the exit.
helper := exec.Command("sleep", fmt.Sprintf("%g", linger.Seconds()))
helper.Stdout = os.Stdout
_ = helper.Start()
}
return nil
}
},
}, {
Name: "check", Usage: "", Summary: "says whether it could run",
Bind: func(*flag.FlagSet) delegate.Body {
return func(ctx context.Context, host delegate.Host, args []string) error {
host.Terminal(delegate.Ending{Status: delegate.StatusPass, Message: "it could run"})
return nil
}
},
}},
}
}
// askCarried is one question through the model API, as any OpenAI client asks
// one.
func askCarried(ctx context.Context, api delegate.ModelAPI, question string) (string, error) {
body, _ := json.Marshal(map[string]any{
"model": "openrouter/deepseek/deepseek-v4-flash-0731",
"messages": []map[string]string{{"role": "user", "content": question}},
})
request, err := http.NewRequestWithContext(ctx, http.MethodPost, modelapi.ChatURL(api.BaseURL), bytes.NewReader(body))
if err != nil {
return "", err
}
request.Header.Set("Content-Type", "application/json")
api.Authorize(request)
response, err := http.DefaultClient.Do(request)
if err != nil {
return "", err
}
defer response.Body.Close()
payload, _ := io.ReadAll(response.Body)
var answer struct {
Choices []struct {
Message struct {
Content string `json:"content"`
} `json:"message"`
} `json:"choices"`
Error *struct {
Message string `json:"message"`
} `json:"error"`
}
if err := json.Unmarshal(bytes.TrimSpace(payload), &answer); err != nil {
return "", fmt.Errorf("%d: %s", response.StatusCode, payload)
}
if answer.Error != nil {
return "", errors.New(answer.Error.Message)
}
if len(answer.Choices) == 0 {
return "", errors.New("no answer")
}
return answer.Choices[0].Message.Content, nil
}
// runAsCarriedChild runs the dispatch when this binary was started as a shell
// run's child, and says whether it was: with the fake program carried when
// the mark is "1", the fake that works in its folder when it is "folder"
// (carried_folder_test.go), and with the build's own list — senior-dev itself
// — when it is "real".
func runAsCarriedChild() (int, bool) {
switch os.Getenv(carriedChildEnv) {
case "1":
restore := builtin.Override([]delegate.Delegate{fakeCarriedProgram()})
defer restore()
return execute(), true
case "folder":
restore := builtin.Override([]delegate.Delegate{fakeFolderProgram()})
defer restore()
return execute(), true
case "model-flags":
restore := builtin.Override([]delegate.Delegate{fakeModelFlagsProgram()})
defer restore()
return execute(), true
case "real":
return execute(), true
}
return 0, false
}