// buildLineBytes is the most bytes of one line in a build input or usage log.
const buildLineBytes = 1 << 20
+// buildWaitTimeout is the longest wait for pending memory builds.
+const buildWaitTimeout = time.Second
+
// buildQuotaLimit is the largest increase in used quota points of a run.
const buildQuotaLimit = 15.0
-// buildCallLimit is the most model calls of a run.
-const buildCallLimit = 660
-
// BuildRun appends messages, builds their tree, and stops the run by the rules
// of buildStop.
type BuildRun struct {
usagePath string
}
+// DatedMessage is one message with an optional RFC 3339 date.
+type DatedMessage struct {
+ Kind string `json:"kind"`
+ Text string `json:"text"`
+ Date string `json:"date,omitempty"`
+}
+
// Run appends the entries. It waits for the builds only before a user message,
// as a turn does, so up to buildMax builds run at once in between, and it waits
// for all builds at the end. It returns the number of messages appended and why
// waitBuilds waits up to one second without leaving a child context open.
func (r *BuildRun) waitBuilds(ctx context.Context) error {
- ctx, cancel := context.WithTimeout(ctx, time.Second)
+ ctx, cancel := context.WithTimeout(ctx, buildWaitTimeout)
defer cancel()
return r.memory.Wait(ctx)
}
-// DatedMessage is one message with an optional RFC 3339 date.
-type DatedMessage struct {
- Kind string `json:"kind"`
- Text string `json:"text"`
- Date string `json:"date,omitempty"`
-}
-
// buildReadUsage reads the records of usage.jsonl at path, in the order of the
// start of their calls. The file has them in the order of the end of their
// calls, which differs when calls run at once.
return records, nil
}
+// buildStop returns why a build run must stop: a failed call, or a quota window
+// whose used percent grew by more than buildQuotaLimit points since the first
+// call. It returns "" when the run can go on.
+func buildStop(records []ModelUsageRecord) string {
+ for _, record := range records {
+ if record.Error != "" {
+ return "call failed: " + record.Error
+ }
+ }
+
+ if len(records) == 0 {
+ return ""
+ }
+
+ first := buildUsedPercents(records[0])
+ for name, used := range buildUsedPercents(records[len(records)-1]) {
+ start, found := first[name]
+ if found && used-start > buildQuotaLimit {
+ return fmt.Sprintf("%s grew from %g to %g", name, start, used)
+ }
+ }
+
+ return ""
+}
+
+// buildCallStart returns the start of the call of record, or the zero time when
+// its date is not valid.
+func buildCallStart(record ModelUsageRecord) time.Time {
+ start, err := time.Parse(time.RFC3339Nano, record.Date)
+ if err != nil {
+ return time.Time{}
+ }
+
+ return start
+}
+
+// buildUsedPercents returns the used percent of each quota window of record, by
+// header name.
+func buildUsedPercents(record ModelUsageRecord) map[string]float64 {
+ used := make(map[string]float64)
+ for name, value := range record.Quota {
+ if !strings.HasSuffix(name, "-used-percent") {
+ continue
+ }
+
+ percent, err := strconv.ParseFloat(value, 64)
+ if err == nil {
+ used[name] = percent
+ }
+ }
+
+ return used
+}
+
// buildWriteReport writes the result of a build run.
func buildWriteReport(out io.Writer, appended int, stop string, records []ModelUsageRecord, sizes []int) error {
var input, cached, output, failed int
return nil
}
-// buildStop returns why a build run must stop: a failed call, or a quota window
-// whose used percent grew by more than buildQuotaLimit points since the first
-// call. It returns "" when the run can go on.
-func buildStop(records []ModelUsageRecord) string {
- for _, record := range records {
- if record.Error != "" {
- return "call failed: " + record.Error
- }
- }
-
- if len(records) == 0 {
- return ""
- }
-
- first := buildUsedPercents(records[0])
- for name, used := range buildUsedPercents(records[len(records)-1]) {
- start, found := first[name]
- if found && used-start > buildQuotaLimit {
- return fmt.Sprintf("%s grew from %g to %g", name, start, used)
- }
- }
-
- return ""
-}
-
-// buildCallStart returns the start of the call of record, or the zero time when
-// its date is not valid.
-func buildCallStart(record ModelUsageRecord) time.Time {
- start, err := time.Parse(time.RFC3339Nano, record.Date)
- if err != nil {
- return time.Time{}
- }
-
- return start
-}
-
// buildRatio returns a / b, or 0 when b is 0.
func buildRatio(a, b int) float64 {
if b == 0 {
return strings.Join(parts, " ")
}
-
-// buildUsedPercents returns the used percent of each quota window of record, by
-// header name.
-func buildUsedPercents(record ModelUsageRecord) map[string]float64 {
- used := make(map[string]float64)
- for name, value := range record.Quota {
- if !strings.HasSuffix(name, "-used-percent") {
- continue
- }
-
- percent, err := strconv.ParseFloat(value, 64)
- if err == nil {
- used[name] = percent
- }
- }
-
- return used
-}