@@ -69,12 +69,22 @@ func resolveCacheDir(opts Options, skillDir string) string {
6969// newThrottle returns a function that blocks until the next request is allowed.
7070// If rps is 0 or negative, the returned function is a no-op.
7171// The caller must call the returned stop function when done.
72- func newThrottle (rps int ) (wait func (), stop func ()) {
72+ func newThrottle (ctx context. Context , rps int ) (wait func (), stop func ()) {
7373 if rps <= 0 {
7474 return func () {}, func () {}
7575 }
7676 ticker := time .NewTicker (time .Second / time .Duration (rps ))
77- return func () { <- ticker .C }, ticker .Stop
77+ first := true
78+ return func () {
79+ if first {
80+ first = false
81+ return
82+ }
83+ select {
84+ case <- ticker .C :
85+ case <- ctx .Done ():
86+ }
87+ }, ticker .Stop
7888}
7989
8090// EvaluateSkill scores a skill directory (SKILL.md and/or reference files).
@@ -89,7 +99,7 @@ func EvaluateSkill(ctx context.Context, dir string, client judge.LLMClient, opts
8999 return nil , fmt .Errorf ("loading skill: %w" , err )
90100 }
91101
92- wait , stop := newThrottle (opts .RateLimit )
102+ wait , stop := newThrottle (ctx , opts .RateLimit )
93103 defer stop ()
94104
95105 // Score SKILL.md
@@ -252,7 +262,7 @@ func EvaluateSingleFile(ctx context.Context, absPath string, client judge.LLMCli
252262 }
253263 }
254264
255- wait , stop := newThrottle (opts .RateLimit )
265+ wait , stop := newThrottle (ctx , opts .RateLimit )
256266 defer stop ()
257267
258268 wait ()
0 commit comments