diff --git a/.github/time/test_time.py b/.github/time/test_time.py index db79502..04a8b94 100644 --- a/.github/time/test_time.py +++ b/.github/time/test_time.py @@ -835,39 +835,40 @@ if _sh.which("node"): print("ALL OK 41") # 78 Time retries its own parked cards (error / stuck), within TIME_AUTO_RETRY; a human only hears once it has given up +K78 = {**K, "TIME_WORKER": "cursor"} meta78 = lambda w: [json.loads(re.search(r"", t).group(1)) for _, t in w.posted] # error with no PR -> redispatched on the next beat, and the beat says it was automatic -w = run(World([card(1, D)], {1: [beat("dispatched", 3, launched=True), beat("error", 1)]}), K) +w = run(World([card(1, D)], {1: [beat("dispatched", 3, launched=True), beat("error", 1)]}), K78) assert len(w.launched) == 1 and meta78(w)[-1].get("auto_retry") is True and meta78(w)[-1].get("launched") is True, w.posted assert "Retrying on my own" in w.posted[-1][1], w.posted # stuck with no PR is retried too -w = run(World([card(1, D)], {1: [beat("dispatched", 8, launched=True), beat("stuck", 1)]}), K) +w = run(World([card(1, D)], {1: [beat("dispatched", 8, launched=True), beat("stuck", 1)]}), K78) assert len(w.launched) == 1 and meta78(w)[-1].get("auto_retry") is True, w.posted # after one automatic retry (the default) a second error waits for a human; TIME_AUTO_RETRY=2 tries again spent78 = {1: [beat("dispatched", 5, launched=True), beat("error", 4), beat("dispatched", 3, launched=True, auto_retry=True), beat("error", 1, auto_retry=True)]} -w = run(World([card(1, D)], spent78), K); assert w.launched == [] and w.posted == [], w.posted -w = run(World([card(1, D)], spent78), {**K, "TIME_AUTO_RETRY": "2"}); assert len(w.launched) == 1, "a second automatic retry" +w = run(World([card(1, D)], spent78), K78); assert w.launched == [] and w.posted == [], w.posted +w = run(World([card(1, D)], spent78), {**K78, "TIME_AUTO_RETRY": "2"}); assert len(w.launched) == 1, "a second automatic retry" # a seat's two dispatch beats (and its error) are one automatic retry, not three seat78 = {1: [beat("dispatched", 5, launched=True), beat("error", 4), beat("dispatched", 3, launched=True, auto_retry=True), beat("dispatched", 2, auto_retry=True, pr=9), beat("stuck", 1)]} -w = run(World([card(1, D)], seat78), {**K, "TIME_AUTO_RETRY": "2"}); assert len(w.launched) == 1 -w = run(World([card(1, D)], seat78), K); assert w.launched == [] and w.posted == [] +w = run(World([card(1, D)], seat78), {**K78, "TIME_AUTO_RETRY": "2"}); assert len(w.launched) == 1 +w = run(World([card(1, D)], seat78), K78); assert w.launched == [] and w.posted == [] # a human's /time retry still works after the automatic ones are spent -w = run(World([card(1, D)], {1: spent78[1] + [human]}), K); assert len(w.launched) == 1 +w = run(World([card(1, D)], {1: spent78[1] + [human]}), K78); assert len(w.launched) == 1 # stuck with an open linked PR is reviewed, not redispatched -w = run(World([card(1, D)], {1: [beat("dispatched", 8, launched=True), beat("stuck", 1)]}, [pr]), K) +w = run(World([card(1, D)], {1: [beat("dispatched", 8, launched=True), beat("stuck", 1)]}, [pr]), K78) assert w.launched == [] and meta78(w)[-1]["beat"] == "pr" and "PR #7" in w.posted[-1][1], w.posted # a closed PR does not hold the retry back -w = run(World([card(1, D)], {1: [beat("dispatched", 8, launched=True), beat("stuck", 1)]}, [{**pr, "state": "closed"}]), K) +w = run(World([card(1, D)], {1: [beat("dispatched", 8, launched=True), beat("stuck", 1)]}, [{**pr, "state": "closed"}]), K78) assert len(w.launched) == 1 # dry-run retries nothing w = run(World([card(1, D)], {1: [beat("error", 1)]}), {"TIME_MODE": "dry-run", "CURSOR_API_KEY": "ck"}); assert w.launched == [] and w.posted == [] # the messages say what Time will do -w = run(World([card(1, D)], {1: [beat("dispatched", 7, launched=True)]}), K) +w = run(World([card(1, D)], {1: [beat("dispatched", 7, launched=True)]}), K78) assert w.posted[0][1].split("\n\n")[0].endswith("I'll dispatch again on my own next beat; comment `/time retry` to force one."), w.posted -w = run(World([card(1, D)], {1: [beat("dispatched", 7, launched=True)]}), {**K, "TIME_AUTO_RETRY": "0"}) +w = run(World([card(1, D)], {1: [beat("dispatched", 7, launched=True)]}), {**K78, "TIME_AUTO_RETRY": "0"}) assert "I'll dispatch again" not in w.posted[0][1] and "`/time retry`" in w.posted[0][1], w.posted -w = run(World([card(1, D)], {1: [beat("would-dispatch")]}), K) +w = run(World([card(1, D)], {1: [beat("would-dispatch")]}), K78) _hb = w.http def failing78(method, path, body=None, *a, **k): if "api.cursor.com" in path: raise RuntimeError("boom") @@ -878,7 +879,7 @@ assert meta78(w)[-1]["beat"] == "error" and "I'll retry on my own next beat (TIM # a venice: worker on an automatic retry gets half as many turns again; a first dispatch gets the plain default seen78, real_vw78 = [], tm.venice_work tm.venice_work = lambda card, done, spec, hands_cls=None, review=None, **kw: (seen78.append(kw), {"pr": 42, "steps": 3, "seat": "kimi", "model": "m"})[1] -KS = {**K, "TIME_WORKER": "venice:kimi code", "VENICE_API_KEY": "vk", "TIME_WORKER_STEPS": "40"} +KS = {**K78, "TIME_WORKER": "venice:kimi code", "VENICE_API_KEY": "vk", "TIME_WORKER_STEPS": "40"} w = run(World([card(1, D)], {1: [beat("dispatched", 3, launched=True), beat("error", 1)]}), KS) assert seen78 == [{"steps": 60}], seen78 assert "Retrying on my own, resuming the branch." in w.posted[0][1] and all(m.get("auto_retry") is True for m in meta78(w)), w.posted