From 053bab3e789edd290325a5d35c19ded37d19f53b Mon Sep 17 00:00:00 2001 From: Simbiot Harness Date: Thu, 1 Oct 2026 10:02:28 +0000 Subject: [PATCH] =?UTF-8?q?tests(task-batch):=20=D1=81=D0=B8=D0=BD=D1=85?= =?UTF-8?q?=D1=80=D0=BE=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=81?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=BA=D1=81=D1=82-=D1=81?= =?UTF-8?q?=D1=85=D0=B5=D0=BC=D0=BE=D0=B9=2011a8ccc=20(min=20256k=20/=20ho?= =?UTF-8?q?ur=20512k=20/=20day=201M)=20=E2=80=94=20t-261001090908-18a4f5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Бюджет и размеры задач в секциях 5/6 выведены из LEVELS[].ctx_tokens, константы уровня захардкожены отдельным check'ом. 30 checks ALL PASS. --- tests/test_task_batch.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/test_task_batch.py b/tests/test_task_batch.py index db23910..69eb585 100644 --- a/tests/test_task_batch.py +++ b/tests/test_task_batch.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""t-260930101325-010ba3: батч-обработка задач в часовом тике (hermetic, без LLM/БД). +"""t-261001090908-18a4f5: тест синхронизирован с контекст-схемой 11a8ccc (min 256k / hour 512k / day 1M), hermetic. Запуск: ./venv/bin/python tests/test_task_batch.py @@ -81,16 +81,24 @@ check("4: env SIMBIOT_BATCH_MAX_HOUR=2 переопределяет", os.environ.pop("SIMBIOT_BATCH_MAX_HOUR", None) # ── 5. Бюджет контекста: секция задач не съедает ctx тика ── -# hour: ctx 32K токенов · 3 симв/токен · 0.5 = 48_000 симв на батч. -# Задача ~9261 симв → в 48К влезает 5 (46305), 6-я (55566) — нет. -big_details = "х" * 9000 +# Бюджет выводится из контекст-схемы уровня (11a8ccc: min 256k → hour 512k → +# day 1M ctx_tokens): budget = ctx_tokens · CHARS_PER_TOKEN · TASK_BUDGET_SHARE, +# для hour = 512_000 · 3 · 0.5 = 768_000 симв на батч. Размеры деталей тоже +# выведены из бюджета — схема не должна рассыпаться при следующей смене уровней. +budget = int(LEVELS["hour"].ctx_tokens * scheduler.CHARS_PER_TOKEN * scheduler.TASK_BUDGET_SHARE) +check("5: контекст-схема 11a8ccc (min 256k / hour 512k / day 1M)", + LEVELS["min"].ctx_tokens == 256_000 and LEVELS["hour"].ctx_tokens == 512_000 + and LEVELS["day"].ctx_tokens == 1_000_000, + f"min={LEVELS['min'].ctx_tokens} hour={LEVELS['hour'].ctx_tokens} day={LEVELS['day'].ctx_tokens}") +# Задача с деталями budget//5 - 300 симв стоит ≈ budget/5 (263+details); +# 5 шт влезают (сумма < 1.0·budget), 6-я пробивает (кап 6 не достигнут). +big_details = "х" * (budget // 5 - 300) huge = {f"t-{i}": _task(f"t-{i}", details=big_details, created=f"2026-09-30T0{i}:00:00") for i in range(8)} batch = scheduler.select_task_batch(LEVELS["hour"], _model(huge)) cost = scheduler.task_batch_cost([huge[t] for t in batch]) -budget = int(32_000 * scheduler.CHARS_PER_TOKEN * scheduler.TASK_BUDGET_SHARE) check("5: бюджетная отсечка (5 из 8, кап 6 не достигнут)", len(batch) == 5, f"n={len(batch)}") -check("5: суммарная стоимость ≤ 48К симв", cost <= budget, str(cost)) +check("5: суммарная стоимость ≤ бюджету hour (768К симв)", cost <= budget, str(cost)) check("5: 6-я задача пробила бы бюджет (отсечка не случайна)", cost + scheduler._task_cost(huge["t-5"]) > budget, f"cost6={cost + scheduler._task_cost(huge['t-5'])}") @@ -101,7 +109,9 @@ check("5: узкие — все 6 влезли", len(scheduler.select_task_batch(LEVELS["hour"], _model(wide))) == 6) # ── 6. Первая (старейшая) берётся ВСЕГДА, даже если бюджет пробит ── -fattail = {"t-huge": _task("t-huge", details="y" * 200_000, created="2026-09-30T07:00:00"), +# Размер t-huge — от бюджета (details = 2·budget симв): влезть следом для +# t-s (~263 симв) места нет, но первую задача берётся безусловно. +fattail = {"t-huge": _task("t-huge", details="y" * (budget * 2), created="2026-09-30T07:00:00"), "t-s": _task("t-s", created="2026-09-30T08:00:00")} batch = scheduler.select_task_batch(LEVELS["hour"], _model(fattail)) check("6: сверхтяжёлая старейшая берётся одна (не блокирует очередь)",