Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -1175,16 +1175,18 @@ The connection owner spans preparation and the transferred Run without a reserva
deadline; every exit releases it.

The existing Worker scans pending inputs using the same bounded scheduling slots,
Session locks, durable deadlines and engine capability checks. Keep the five-second
Session locks, durable deadlines and engine capability checks. Keep the one-second
Environment-input scan cadence and at most 100 candidates per scan. At EOF after a
nonempty cursor, refill the first page once in the same scan; an empty queue must
not spin. Advance the cursor before readiness checks so an unavailable Runtime
cannot starve later candidates. Preserve the four active slots and alternation
between ordinary Turns and Environment inputs. A self-hosted Session
waits for its dedicated enrolled device; it cannot select an arbitrary same-tenant
device or migrate an existing binding. Preparation failure can retry while still
pending without extending the deadline. Unknown promotion results or errors after
admission retain the existing no-replay settlement rules.
pending without extending the deadline. Preparation retries share this scan cadence;
the four slots bound concurrency, not attempt frequency. Managed-provider lifecycle
polling retains its separate five-second interval. Unknown promotion results or
errors after admission retain the existing no-replay settlement rules.

`AGENTS_API_DAEMON_WS_URL` enables the private gateway and supplies the unchanged
public `remote_url`. `AGENTS_API_HARNESSES` explicitly adds deployment-supported
Expand Down
2 changes: 1 addition & 1 deletion services/agents-api/internal/execution/worker_schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (s *workerSchedule) selectWork(ctx context.Context, w *Worker, devices []st
if err != nil {
return nil, err
}
s.nextEnvironmentScan = time.Now().Add(5 * time.Second)
s.nextEnvironmentScan = time.Now().Add(time.Second)
if len(environments) == 0 && s.environmentCursor != "" {
s.environmentCursor = ""
// Retry the first page now instead of spending a scan interval on EOF.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestWorkerEnvironmentRetriesNewlyReadyAtNextScan(t *testing.T) {
waitTurn(t, h, barrier.ID, store.TurnCompleted)

prepare := nextWorkerFrame(t, frames, proto.TypeExecutionPrepare)
if elapsed := time.Since(scanned); elapsed < 4*time.Second || elapsed > 8*time.Second {
if elapsed := time.Since(scanned); elapsed < 750*time.Millisecond || elapsed > 3*time.Second {
t.Fatal("readiness retry must use the next scan, without an empty scan interval", elapsed)
}
if workerRuntimeForPreparation(t, h, prepare) != runtime {
Expand Down Expand Up @@ -79,7 +79,7 @@ func TestWorkerEnvironmentPaginationReachesReadyTail(t *testing.T) {
// The first 100 unbound inputs must not pin the cursor, and the ready
// tail must wait for its own bounded page rather than an unbounded drain.
prepare := nextWorkerFrame(t, frames, proto.TypeExecutionPrepare)
if elapsed := time.Since(scanned); elapsed < 4*time.Second || elapsed > 8*time.Second {
if elapsed := time.Since(scanned); elapsed < 750*time.Millisecond || elapsed > 3*time.Second {
t.Fatal("pagination lost the scan bound or starved the ready tail", elapsed)
}
if workerRuntimeForPreparation(t, h, prepare) != runtime {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func TestWorkerEnvironmentRetriesPendingWithoutExtendingDeadline(t *testing.T) {
h.write(request.ID, proto.TypeDone, proto.DonePayload{Content: "complete"})
waitTurn(t, h, request.ID, store.TurnCompleted)
second := nextWorkerFrame(t, frames, proto.TypeExecutionPrepare)
if elapsed := time.Since(started); elapsed < 4*time.Second || elapsed > 8*time.Second || first.ID == second.ID {
if elapsed := time.Since(started); elapsed < 750*time.Millisecond || elapsed > 3*time.Second || first.ID == second.ID {
t.Fatal("pending preparation missed its next scan or reused a released owner")
}
acknowledgePreparation(runtime, second.ID)
Expand Down
Loading