no gemini
This commit is contained in:
@@ -7,8 +7,10 @@ import (
|
||||
"log/slog"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"g.fc.run/ai/byre/internal/antigravity"
|
||||
"g.fc.run/ai/byre/internal/api"
|
||||
)
|
||||
|
||||
type agySteps struct {
|
||||
@@ -151,6 +153,7 @@ func (m *Manager) agyTurnEnded(ctx context.Context, l *live, p antigravityProces
|
||||
m.mu.Lock()
|
||||
final := l.lastText
|
||||
m.mu.Unlock()
|
||||
go m.readAgyRateLimit()
|
||||
|
||||
success := res.Status == "SUCCESS"
|
||||
bounce := false
|
||||
@@ -194,6 +197,42 @@ func (m *Manager) agyTurnEnded(ctx context.Context, l *live, p antigravityProces
|
||||
return m.turnEnded(ctx, l, r)
|
||||
}
|
||||
|
||||
var agyWindowMins = map[string]int{"5h": 300, "weekly": 7 * 24 * 60}
|
||||
|
||||
func (m *Manager) readAgyRateLimit() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
groups, err := antigravity.ReadUsage(ctx)
|
||||
if err != nil {
|
||||
slog.Error("read antigravity rate limits", "err", err)
|
||||
return
|
||||
}
|
||||
m.mu.Lock()
|
||||
m.rateLimits[api.Antigravity] = agyRateLimit(groups)
|
||||
m.mu.Unlock()
|
||||
m.store.Broadcast(api.Event{Kind: "admin.health", Actor: "byre", Payload: map[string]any{}})
|
||||
}
|
||||
|
||||
func agyRateLimit(groups []antigravity.UsageGroup) map[string]any {
|
||||
info := map[string]any{"status": "allowed"}
|
||||
windows := map[string]any{}
|
||||
for _, g := range groups {
|
||||
for _, b := range g.Buckets {
|
||||
window := map[string]any{"utilization": 1 - b.RemainingFraction, "resetsAt": b.ResetTime.Unix()}
|
||||
if mins := agyWindowMins[b.Window]; mins != 0 {
|
||||
window["windowMins"] = mins
|
||||
}
|
||||
windows[b.ID] = window
|
||||
if b.RemainingFraction <= 0 {
|
||||
info["status"] = "rejected"
|
||||
info["rateLimitType"] = b.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
info["unifiedWindows"] = windows
|
||||
return info
|
||||
}
|
||||
|
||||
func (m *Manager) agyBeforeModel(l *live) antigravity.HookFunc {
|
||||
return func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
||||
in := struct {
|
||||
|
||||
@@ -161,6 +161,7 @@ func New(st *store.Store, worktreeRoot, leadRoot, handsRoot, codexHome, antigrav
|
||||
}
|
||||
go m.signalLoop()
|
||||
go m.readCodexRateLimit()
|
||||
go m.readAgyRateLimit()
|
||||
return m
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package antigravity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UsageBucket struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Window string `json:"window"`
|
||||
RemainingFraction float64 `json:"remaining_fraction"`
|
||||
ResetTime time.Time `json:"reset_time"`
|
||||
}
|
||||
|
||||
type UsageGroup struct {
|
||||
Name string `json:"name"`
|
||||
Buckets []UsageBucket `json:"buckets"`
|
||||
}
|
||||
|
||||
func ReadUsage(ctx context.Context) ([]UsageGroup, error) {
|
||||
out, err := exec.CommandContext(ctx, "agy", "--output-format", "json", "--print", "/usage").Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("agy /usage: %w", err)
|
||||
}
|
||||
resp := struct {
|
||||
Command struct {
|
||||
Data struct {
|
||||
Groups []UsageGroup `json:"groups"`
|
||||
} `json:"data"`
|
||||
} `json:"command"`
|
||||
}{}
|
||||
err = json.Unmarshal(out, &resp)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("agy /usage: %w", err)
|
||||
}
|
||||
return resp.Command.Data.Groups, nil
|
||||
}
|
||||
Reference in New Issue
Block a user