О проекте
Команда: Amadeus
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Доведённый продукт
Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам
Суть
Городской симулятор: пользователь выбирает 5 мер из каталога в 14 мер по районам в пределах бюджета 100, получает Astana Quality of Life Score и AI-разбор сильных сторон, рисков и рекомендаций.
Как устроено
Данные и правила лежат в data/city.json. Детерминированный движок (engine/validator.py, simulator.py) проверяет набор мер и считает Score = 0.7×D_avg + 0.3×D_min − N_crit с учётом лага и синергии. optimizer.py перебирает все 694 395 допустимых наборов (numpy, около 1 с) и выдаёт percentile, gap_to_best и suggest_swaps. AI-агент на OpenAI Responses API с tool calling (score_scenario, suggest_swaps, get_optimum) только объясняет результат; сервер проверяет, что каждое число в ответе взято из результатов инструментов, а при сбое срабатывает шаблонное объяснение.
Ключевые решения
- deterministic scoring formula
- exhaustive enumeration optimizer
- function calling
- numeric grounding verification
- template fallback
- percentile vs all scenarios
Метрики
125 pytest + 8 npm тестов; Score примера 56.54 при бюджете 95; доказанный оптимум 57.237 (стоимость 98) среди 694 395 наборов
Особенности
LLM ничего не считает: числа в ответе агента сверяются с выводом инструментов, основной сценарий работает без ключа. Полный перебор всех допустимых наборов даёт перцентиль решения пользователя и доказуемый оптимум. В README есть таблица «требование ТЗ → где реализовано → как проверить» с ожидаемыми числами.
Стек
Python · FastAPI · React · Vite · numpy · SQLite · PostgreSQL · pytest
Модели
OpenAI Responses API
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-18c231dc-amadeus.
README
README.mdАким на 5 часов — AI-симулятор управления городом
Описание и назначение
Симулятор помогает городскому управленцу или аналитику оценить, как распределение ограниченного бюджета между городскими инициативами влияет на качество жизни в районах.
Пользователь получает общий бюджет 100 и данные пяти районов города. Он выбирает 5 мер из каталога (14 мер по пяти направлениям: транспорт, экология, соцсфера, безопасность, сервисы). Затем получает Astana Quality of Life Score и AI-разбор: сильные стороны, риски, последствия и рекомендации по улучшению.
Главный принцип: Score и все показатели считает детерминированный движок engine/. AI-агент
(OpenAI Responses API, tool calling) ничего не вычисляет. Он вызывает инструменты
движка, и сервер проверяет, что каждое число в его ответе взято из результатов
инструментов. Если проверка не прошла, ключа нет или сервис недоступен, возвращается
объяснение по шаблону (ai_generated: false). Весь основной сценарий работает без
ключа OpenAI.
Задание — docs/task.md, датасет, формула и правила — docs/dataset.md, данные — data/city.json.
Быстрый старт
- Установите зависимости по разделу «Установка»: Python-окружение
.venvиnpm ci. - Терминал 1, в активированном
.venv:uvicorn api.main:app --host 127.0.0.1 --port 8000. - Терминал 2:
npm run dev, затем откройте http://localhost:5173/. - В интерфейсе нажмите «Пример» → «Рассчитать» → «Объяснить».
Ключ OpenAI не нужен: без него объяснение строится по шаблону и помечено «Шаблон».
Что видит пользователь
- Выбирает 5 мер из каталога, а для районных мер ещё и район. Индикатор показывает, сколько осталось от бюджета.
- Нажимает «Рассчитать». Интерфейс не даёт добавить меру дороже остатка бюджета, а сервер проверяет все правила. Если набор их нарушает, интерфейс показывает причины от сервера и не показывает Score этого набора.
- Для допустимого набора видит Score из 100 и его изменение за сценарий, занятый бюджет и резерв, а по каждому району — оценку и показатели после мер с изменениями. Для примера из датасета: Score около 56,5 при бюджете 95 из 100 (точное значение 56.54307 — в ответе API).
- До запроса объяснения блок «AI-анализ сценария» показывает короткий локальный разбор по числам сервера с меткой «Local Analysis». Нажимает «Объяснить» и получает сильные стороны, риски, последствия и рекомендации. С ключом OpenAI разбор делает AI-агент, ответ идёт около 30 с. Агент сам вызывает расчётный движок и, например, предлагает заменить M5 в Сарыарке на M3 в Нуре (Score 57,21). Без ключа объяснение строится по шаблону.
Содержание
- Быстрый старт
- Что видит пользователь
- Проверка основного сценария без ключа
- Требования ТЗ → где реализовано → как проверить
- Архитектура
- AI-агент (/api/explain)
- Технологии
- Зависимости и системные требования
- Установка
- Запуск
- Параметры окружения
- HTTP API
- Движок
- Оригинальность и потенциал
- Известные ограничения
- Сторонние компоненты и лицензии
- Как использовались AI-инструменты
- Команда и вклад
- Подготовка до хакатона
Проверка основного сценария без ключа
Нужны только установка и запуск API (разделы ниже); .env не нужен. Команды python
выполняются в активированном .venv (или через .venv\Scripts\python, см. «Установка»). Проще всего
проверять через Swagger http://127.0.0.1:8000/docs: «Try it out», вставить
содержимое файла из examples/. Можно и через curl (на Windows используйте
curl.exe):
curl -X POST http://127.0.0.1:8000/api/simulate -H "Content-Type: application/json" --data-binary @examples/example.json
| Шаг | Запрос | Ожидаемый результат |
|---|---|---|
| 1. Исходные данные | GET /api/config | budget: 100, 5 районов, 14 мер, baseline_score: 52.55768 |
| 2. Пример из датасета | POST /api/simulate, examples/example.json | valid: true, cost: 95, Score: 56.54307, best_possible_score ≈ 57.2367, percentile ≈ 99.9 |
| 3. Другой набор меняет Score | POST /api/simulate, examples/swap.json (M5 в Сарыарке → M3 в Нуре) | valid: true, cost: 100, Score ≈ 57.20556 |
| 4. Контроль бюджета | POST /api/simulate, examples/over_budget.json | valid: false, errors: ["Стоимость 121 превышает бюджет 100."], Score не считается |
| 5. Объяснение без ключа | POST /api/explain, examples/example.json | ai_generated: false, tools_called: [], заполнены summary, strengths, risks, consequences, recommendations, contributions |
| 6. Доказуемый оптимум | python -c "from engine.optimizer import optimize; r = optimize(1); print(r['n_valid'], r['top'][0]['Score'], r['top'][0]['cost'])" | 694395 57.236734999999996 98 (M2, M3 в Нуре, M8 в Нуре, M9 в Нуре, M14), около 1 с |
| 7. Интерфейс | npm run dev, http://localhost:5173/ → «Пример» → «Рассчитать» → «Объяснить» | Те же Score и причины ошибок, что в шагах 2–5; после «Объяснить» без ключа метка «Шаблон», с ключом — «AI Generated» |
Автотесты: python -m pytest -q (125 тестов) и npm test (8 тестов). В тестах
клиент OpenAI подменён, в сеть они не ходят даже при заполненном .env.
Требования ТЗ → где реализовано → как проверить
| Требование ТЗ | Где реализовано | Как проверить |
|---|---|---|
| Единый виртуальный бюджет и исходные данные для всех | data/city.json, GET /api/config | Шаг 1; tests/test_api.py::test_config, test_repeated_requests_do_not_change_config |
| Решения по 5 направлениям | Каталог из 14 мер по 5 направлениям; ровно 5 мер, не больше 2 в одном направлении, без повторов (engine/validator.py) | UI: пять слотов решений; tests/test_engine.py::test_three_measures_in_one_direction |
| Автоматический контроль превышения бюджета | engine/validator.py; /api/simulate и /api/explain не считают невалидный набор | Шаг 4; tests/test_engine.py::test_over_budget, test_exact_budget_is_valid |
| Расчёт Astana Quality of Life Score | engine/simulator.py: Score = 0.7 × D_avg + 0.3 × D_min − N_crit | Шаг 2; tests/test_engine.py::test_reference_scenario, test_baseline |
| Решения влияют на показатели; другой набор — другой Score | engine/simulator.py, поле districts в ответе /api/simulate (до/после/изменение) | Шаги 2–3; tests/test_api.py::test_all_district_deltas_match_engine |
| AI-анализ принятых решений | api/agent.py: агент с инструментами движка, эндпоинт /api/explain | Раздел «AI-агент»; tests/test_agent.py, tests/test_explain.py |
| Объяснение сильных сторон, рисков, последствий и компромиссов | Поля summary, strengths, risks, consequences, recommendations в /api/explain (агент или шаблон api/explanation.py) | Шаг 5; с ключом — раздел «Проверка с настоящим API» |
| Опционально: AI-рекомендации по улучшению сценария | Инструменты suggest_swaps (лучшие одиночные замены) и get_optimum (полный перебор), engine/optimizer.py | Шаг 6; tests/test_optimizer.py |
| Опционально: визуализация изменений показателей районов | src/App.jsx: значения районов до и после по ответу /api/simulate | Шаг 7 |
| Опционально: сравнение результатов | Вместо сравнения команд — сравнение со всеми 694 395 допустимыми наборами: percentile, gap_to_best | Шаг 2; tests/test_scenario_api.py, tests/test_scenario_stats.py |
Не реализованы опциональные пункты: неожиданные городские события и генерация презентации.
Архитектура
Браузер (React, src/) ──HTTP──▶ FastAPI (api/main.py)
├─ /api/config → data/city.json
├─ /api/simulate → engine/validator.py → engine/simulator.py
│ + сравнение: data/scenario_stats.json
└─ /api/explain → проверка и расчёт как в /api/simulate
→ api/agent.py (OpenAI Responses API)
инструменты → engine/ и engine/optimizer.py
→ при сбое: шаблон api/explanation.py
| Модуль | Назначение |
|---|---|
engine/data.py | Загрузка data/city.json — единственного источника данных и правил |
engine/validator.py | Правила набора: 5 мер, бюджет, районы, лимит направления, несовместимости. Причины на русском |
engine/simulator.py | Эффекты с учётом лага, синергии, ограничение 0–100, D районов, D_avg, D_min, N_crit, Score. Без округлений |
engine/optimizer.py | Полный перебор всех допустимых наборов в памяти (numpy, ~1 с, кэшируется), suggest_swaps |
engine/scenario_stats.py, scripts/precompute_scenarios.py | Предрасчёт распределения Score всех наборов в data/scenario_stats.json для percentile и gap_to_best |
api/main.py | HTTP API, CORS для localhost:5173 и localhost:3000 |
api/explanation.py | Факты для объяснения (вклад каждой меры, критические значения) и шаблонное объяснение |
api/agent.py | AI-агент с tool calling и проверкой чисел |
src/ | React-интерфейс. Формулы Score и валидатора в браузере нет: Score, показатели и ошибки приходят из API. Браузер только суммирует цены выбранных мер для индикатора бюджета и до запроса объяснения показывает локальный разбор по числам сервера с меткой «Local Analysis» |
engine/database.py, data/city.sqlite, data/city_postgres.sql | Копии датасета для SQLite и PostgreSQL (docs/postgres.md). API их не использует |
AI-агент (/api/explain)
-
Сервер валидирует набор и считает его движком; клиент не передаёт никаких чисел.
-
Агент получает только список решений и работает в цикле tool calling (OpenAI Responses API,
json_schemaсоstrict: true):score_scenario— Score, D районов, стоимость и лаги набора пользователя; первый вызов всегда принудительно этот;suggest_swaps— лучшие одиночные замены, которые проходят правила и повышают Score;get_optimum— лучшие наборы полного перебора.
Не больше 4 вызовов инструментов.
-
Проверка ответа: каждое число в тексте должно встречаться среди чисел результатов инструментов (инструменты отдают значения, округлённые кодом до 0.01). Если есть хоть одно число, которого там нет, ответ модели отклоняется. Проверяется наличие значения, а не поле, к которому модель его отнесла; брать рекомендации только из
suggest_swapsиget_optimumтребует промпт. Ответ отклоняется и тогда, когда сценарий пользователя не был рассчитан. -
Откат: нет
OPENAI_API_KEYилиOPENAI_MODEL, ошибка OpenAI, тайм-аут (60 с на запрос, 90 с всего), отказ или непрошедшая проверка → шаблонное объяснение изapi/explanation.py,ai_generated: false,tools_called: []. Текст ошибок и ключ клиенту не передаются. -
В ответе:
ai_generated,tools_called(инструменты по порядку),contributions(вклад меры = Score набора − Score без этой меры),best_possible_score,gap_to_best,percentile,warnings.
Живой прогон 23.09 17:11 на примере датасета: ai_generated: true за 31 с,
вызваны score_scenario, suggest_swaps, get_optimum. В тексте ответа Score 56.54,
замена M5 в Сарыарке → M3 в Нуре с результатом 57.21 и оптимум 57.24 при стоимости 98.
Все эти числа совпадают с движком.
Технологии
Python, FastAPI, uvicorn, Pydantic, numpy, OpenAI Python SDK (Responses API, function calling, Structured Outputs), python-dotenv, pytest, httpx. Интерфейс: React 19, Vite 6, lucide-react.
Зависимости и системные требования
- Python 3.10 или новее (проверено на 3.14.3), зависимости —
requirements.txt. - Node.js и npm для интерфейса (проверено на Node.js 24.19, npm 11.17),
зависимости —
package.jsonиpackage-lock.json. - Интернет нужен для установки пакетов, для режима с настоящим OpenAI и для страницы
Swagger
/docs(FastAPI загружает swagger-ui с cdn.jsdelivr.net). curl и интерфейс работают без интернета.
Установка
Из корня репозитория:
python -m venv .venv
source .venv/bin/activate # Linux/macOS
python -m venv .venv
.venv\Scripts\Activate.ps1 # Windows PowerShell
Все следующие команды выполняются в активированном окружении:
python -m pip install -r requirements.txt
npm ci
Если PowerShell запрещает запуск скриптов, вызывайте Python окружения напрямую:
.venv\Scripts\python -m pip install -r requirements.txt,
.venv\Scripts\python -m pytest -q,
.venv\Scripts\python -m uvicorn api.main:app --host 127.0.0.1 --port 8000.
npm 11 может предупредить о postinstall пакета esbuild (allow-scripts).
Предупреждение не мешает: тесты и сборка проходят.
Запуск
Терминал 1 — API, в активированном .venv (иначе .venv\Scripts\python -m uvicorn ...).
Порт 8000 обязателен: интерфейс обращается к
http://127.0.0.1:8000, адрес задан в src/api.js):
uvicorn api.main:app --host 127.0.0.1 --port 8000
Swagger: http://127.0.0.1:8000/docs.
Терминал 2 — интерфейс:
npm run dev
Откройте именно http://localhost:5173/ (CORS разрешён для localhost, а не для
127.0.0.1). Подробности интерфейса — docs/frontend.md.
Тесты и сборка:
python -m pytest -q
npm test
npm run build
Параметры окружения
Скопируйте .env.example в .env. .env исключён из Git. Переменные окружения
процесса имеют приоритет над .env; после изменения перезапустите сервер.
| Переменная | Обязательна | Назначение |
|---|---|---|
OPENAI_API_KEY | Нет | Ключ OpenAI. Без него /api/explain отвечает шаблоном (ai_generated: false), остальное работает полностью |
OPENAI_MODEL | Нет | Идентификатор модели с поддержкой Responses API, function calling и Structured Outputs; живой прогон 23.09 выполнен на gpt-6-astra. Без него — шаблон |
Проверка с настоящим API
- Заполните в
.envобе переменные, напримерOPENAI_MODEL=gpt-6-astra(модель живого прогона), и перезапуститеuvicorn. С одним ключом без модели придёт шаблон. POST /api/explainсexamples/example.json(или «Объяснить» в интерфейсе). Ответ идёт около 30 с.- Ожидается
ai_generated: trueи непустойtools_called. Числа в тексте совпадают с/api/simulateи шагом 6. Если модель вернула число не из инструментов, придёт шаблон сai_generated: false: это защитный механизм, а не ошибка запуска.
HTTP API
| Метод и путь | Вход | Выход |
|---|---|---|
GET /api/config | — | Бюджет, горизонт, районы, показатели с весами, меры, синергии, несовместимости, правила, baseline_score |
POST /api/simulate | {"decisions": [{"measure_id": "M7", "district": "Нура"}, ...]} | valid, cost, remaining_budget, Score, baseline_score, score_delta, D_avg, D_min, N_crit, synergies, districts (до/после по районам и показателям), best_possible_score, gap_to_best, percentile, warnings |
POST /api/explain | То же | Поля объяснения, ai_generated, tools_called, contributions, поля сравнения |
Для городской меры district — null или отсутствует. Нарушение правил →
HTTP 200 с {"valid": false, "errors": [...]}, без расчёта и без обращения к OpenAI.
Некорректная структура или лишние поля (например, Score от клиента) → HTTP 422.
Движок
from engine.validator import validate
from engine.simulator import simulate
decisions = [
{"measure_id": "M7", "district": "Нура"},
{"measure_id": "M8", "district": "Нура"},
{"measure_id": "M10", "district": "Нура"},
{"measure_id": "M12"}, # городская мера: поле district опускается
{"measure_id": "M5", "district": "Сарыарка"},
]
assert validate(decisions) == []
print(simulate(decisions)["Score"]) # 56.54307, стоимость 95
| Сценарий | Стоимость | D_avg | D_min | N_crit | Score |
|---|---|---|---|---|---|
| Пустой набор | 0 | 56.8624 | 49.18 | 2 | 52.55768 |
| Пример из датасета | 95 | 58.0776 | 52.9625 | 0 | 56.54307 |
| Оптимум полного перебора | 98 | — | — | — | 57.236735 |
Эффекты масштабируются по лагу. Синергии начисляются в район указанной в JSON меры. Ограничение 0–100 применяется после суммирования, промежуточные числа не округляются, порядок решений не влияет на результат.
После изменения data/city.json пересчитайте статистику сравнения:
python scripts/precompute_scenarios.py --workers 4. Пока статистика не пересчитана,
best_possible_score, gap_to_best и percentile равны null. engine/optimizer.py
пересчитывает перебор сам при первом обращении в процессе (около 1 с) и кэширует его.
Оригинальность и потенциал
- Доказуемый оптимум как эталон. Полный перебор всех 694 395 допустимых наборов
даёт точный лучший результат. Каждый сценарий получает место в распределении
(
percentile) и расстояние до оптимума. Агент получает варианты улучшения из инструментов движка (suggest_swaps,get_optimum), а не придумывает их. - Защита от выдуманных чисел. LLM только объясняет. Числа берутся из инструментов движка и сверяются кодом; при расхождении пользователь получает шаблон, а не ошибочную цифру.
- Перенос. Районы, показатели, веса, меры, синергии и правила задаются данными
(
data/city.json, есть схемы SQLite и PostgreSQL). Реальные данные районов Астаны или другой город подключаются без изменения кода движка.
Известные ограничения
- AI-ответ приходит примерно за 30 с (reasoning-модель, несколько вызовов инструментов), предел — 90 с, затем шаблон.
- Строгая проверка чисел иногда отклоняет корректный по смыслу ответ модели (например, если модель сама округлила число). Тогда приходит шаблон.
- Проверка чисел не сверяет, к чему относится число: значение, которое есть в
результатах инструментов (например, бюджет 100), пройдёт проверку и в чужом
контексте. Соответствие рекомендаций результатам
suggest_swapsобеспечивает промпт, а не код. - Агент видит только результаты своих инструментов. Поля
warnings,percentileиgap_to_bestвозвращаются в ответе/api/explainи показываются отдельно, но AI-текст может их не упомянуть. - Шаблонное объяснение (без ключа) предлагает допустимые замены без расчёта их
Score; оценённые замены даёт
suggest_swapsв режиме агента и шаг 6. - Датасет синтетический, от организаторов; модель эффектов линейная, с лагом и синергиями из датасета.
- Нет сравнения нескольких команд, неожиданных событий и генерации презентации.
- Адрес API в интерфейсе зашит (
http://127.0.0.1:8000), интерфейс должен открываться наlocalhost:5173илиlocalhost:3000. Авторизации нет: это локальное демо. - Тексты объяснений только на русском.
- В интерфейсе метка объяснения — «AI Generated» или «Шаблон»; список вызванных
инструментов (
tools_called) есть в ответе/api/explain, но интерфейс его не показывает. До нажатия «Объяснить» под заголовком «AI-анализ сценария» виден локальный разбор («Local Analysis»), а не ответ модели.
Сторонние компоненты и лицензии
Лицензии взяты из метаданных установленных пакетов.
| Компонент | Версия (проверено) | Лицензия |
|---|---|---|
| fastapi | 0.141.1 | MIT |
| uvicorn | 0.53.0 | BSD-3-Clause |
| pydantic (зависимость fastapi) | 2.13.5 | MIT |
| openai (Python SDK) | 2.54.0 | Apache-2.0 |
| python-dotenv | 1.2.3 | BSD-3-Clause |
| numpy | 2.5.3, ограничение >=2.2,<3.0 в requirements.txt | BSD-3-Clause AND 0BSD AND MIT AND Zlib AND CC0-1.0 |
| pytest | 8.4.2 | MIT |
| httpx | 0.28.1 | BSD-3-Clause |
| react, react-dom | 19.3.0 | MIT |
| vite | 6.4.3 | MIT |
| @vitejs/plugin-react | 5.2.0 | MIT |
| lucide-react | 0.468.0 | ISC |
Датасет (районы, показатели, меры, синергии, несовместимости, формула Score)
предоставлен организаторами хакатона HackAlem AI в составе задания. Он синтетический
и не содержит персональных данных (docs/dataset.md). OpenAI API (модель
gpt-6-astra в живом прогоне 23.09) — внешний сервис, используется только при заданном
ключе.
Как использовались AI-инструменты
- В продукте: OpenAI Responses API — агент с tool calling в
api/agent.py, одиночный структурированный вызовexplain()вapi/explanation.pyсохранён и покрыт тестами. - В разработке: Claude Code и Codex — написание и ревью кода, тестов и документации. Codex (в режиме только чтения) также проверял репозиторий по критериям ТЗ. Каждое изменение проверялось тестами и запуском.
Команда и вклад
- lMakEl (Малика Ерболқызы): план и зоны, полный перебор
(
engine/optimizer.py), AI-агент (api/agent.py), подключение агента к API, README. - xehrf: датасет в JSON, движок и валидатор, HTTP API, шаблонное объяснение, статистика сценариев, React-интерфейс, SQLite/PostgreSQL.
- secorluve: макет интерфейса в Figma (сделан командой 23.09, сторонние
UI-шаблоны не использовались) и доработка UI по нему, состав команды
(
docs/team.md), подготовка к защите. Часть коммитов UI сделана с общего ноутбука под git-автором xehrf и запушена аккаунтом secorluve.
Подготовка до хакатона
Заранее подготовленные материалы в репозиторий не копировались; до начала на ноутбуках участников были настроены только инструменты разработки (зависимости, git-хуки, инструкции для AI-агентов). Весь код и документация созданы 23.09.2026 с 13:00 до 18:00.
Авторы коммитов
История коммитов
- 2026-09-23 18:00Update README.mdlMakEl
- 2026-09-23 17:58Fix explanation tests for agent response flowxehrf
- 2026-09-23 17:38checkpoint 17:38: [h5] tests/test_explain.py: вернуть импорт validate и хелперы tool_turn/call/final_turn (после fd74523 падали 5 тестов, теперь 125/125); README: быстрый старт, «Что видит пользователМалика Ерболқызы
- 2026-09-23 17:34Polish dashboard and wire agent explain endpointxehrf
- 2026-09-23 17:31checkpoint 17:31: [h5] README: вклад secorluve — свой Figma-макет 23.09 и доработка UI с общего ноутбука (п. 5.4.4, 5.4.7)Малика Ерболқызы
- 2026-09-23 17:30checkpoint 17:30: [h5] README по readme-verifier: запуск API и шаг 6 в активированном .venv или через .venv\Scripts\python; режим с ключом требует обе переменные (пример OPENAI_MODEL); Swagger /docs гМалика Ерболқызы
- 2026-09-23 17:25checkpoint 17:25: [h5] README по ревью Codex: активация venv по ОС и запуск без активации, точные формулировки проверки чисел агента и кэша оптимизатора, стоимость в браузере; модель живого прогона (пМалика Ерболқызы
- 2026-09-23 17:21checkpoint 17:21: [h5] README: раздел «Описание и назначение» (п. 5.4.15, verify-clean); PLAN: статус на 17:20 — агент в /api/explain, UI на API, 125+8 тестовМалика Ерболқызы
Все коммиты (34)
- 2026-09-23 17:19checkpoint 17:19: [h5] UI: бейдж объяснения показывает tools_called агента или «Резервный режим: по шаблону, без LLM», загрузка ~30 с; frontend.md и README шаг 7 под новые подписи; npm test 8/8, buildМалика Ерболқызы
- 2026-09-23 17:17checkpoint 17:16: [h5] README по Промт 5: проверка без ключа по шагам с ожидаемыми числами (examples/*.json), таблица ТЗ → где → как проверить, архитектура, раздел агента, окружение, лицензии из метадМалика Ерболқызы
- 2026-09-23 17:11checkpoint 17:11: [h5] /api/explain переключён на агента (tool calling, проверка чисел, tools_called в ответе); тесты изолируют agent.OpenAI; живой прогон 17:11 — ai_generated=true за 31 с, 3 инструмеМалика Ерболқызы
- 2026-09-23 17:05Connect dashboard to API and add exhaustive scenario analysisxehrf
- 2026-09-23 17:02Remove dark dashboard backgroundxehrf
- 2026-09-23 16:53checkpoint 16:53: [h4] PLAN: живой прогон агента — ответ модели принят за 27,7 с, три инструмента, числа совпали с движкомМалика Ерболқызы
- 2026-09-23 16:48Polish dashboard UI from Figma mockupxehrf
- 2026-09-23 16:47checkpoint 16:46: [h4] агент: первый ход принудительно score_scenario, без лимита max_output_tokens (reasoning), тайм-ауты 60/90 с, причина отката в журнал без данных ответа (по ревью Codex)Малика Ерболқызы
- 2026-09-23 16:37checkpoint 16:37: [h4] optimizer: Score топа берётся из simulate() — точное совпадение вместо расхождения float в последнем знаке (по ревью Codex)Малика Ерболқызы
- 2026-09-23 16:32checkpoint 16:32: [h4] PLAN: синтаксис агента сверен с документацией OpenAI; строка подключения агента для xehrf и 2 теста test_explain, которые нужно поправить вместе с нейМалика Ерболқызы
- 2026-09-23 16:26checkpoint 16:26: [h4] PLAN: число тестов и дерево файлов сверены с mainМалика Ерболқызы
- 2026-09-23 16:16checkpoint 16:16: [h4] агент: инструменты привязаны к сценарию пользователя, точная проверка чисел со знаком (по ревью Codex); PLAN: статус агентаМалика Ерболқызы
- 2026-09-23 16:06checkpoint 16:06: [h4] api/agent.py: агент с tool calling (score_scenario, suggest_swaps, get_optimum, до 4 вызовов), проверка чисел по результатам инструментов, шаблон при сбое; тесты на подменённом Малика Ерболқызы
- 2026-09-23 15:58checkpoint 15:58: [h4] engine/optimizer.py: полный перебор (694395 наборов, оптимум 57.24 при стоимости 98), suggest_swaps, тесты; numpy в requirementsМалика Ерболқызы
- 2026-09-23 15:46checkpoint 15:45: [h3] PLAN под фактический код: статус требований, зоны, задачи до freezeМалика Ерболқызы
- 2026-09-23 15:30Create team.mdsecorluve
- 2026-09-23 15:22Add FastAPI endpoints and structured AI explanationsxehrf
- 2026-09-23 15:18Remove duplicate task documentxehrf
- 2026-09-23 15:09Add React simulator dashboardxehrf
- 2026-09-23 14:59Add postgres inspection queryxehrf
- 2026-09-23 14:55Add database setup scriptsxehrf
- 2026-09-23 14:15Skibidi simulator pytestxehrf
- 2026-09-23 13:56Add task and datasetxehrf
- 2026-09-23 13:49checkpoint 13:49: kickoff: план, MVP, архитектура, разбивка по часамМалика Ерболқызы
- 2026-09-23 13:47checkpoint 13:47: ТЗ задачи «Аким на 5 часов»Малика Ерболқызы
- 2026-09-23 13:46checkpoint 13:46: гигиена репозитория: .gitignore, .gitattributes, каркас docsМалика Ерболқызы
Структура репозитория (50 файлов)
.env.example .gitattributes .gitignore README.md api/__init__.py api/agent.py api/explanation.py api/main.py data/city.json data/city.sqlite data/city_postgres.sql data/scenario_stats.json docs/PLAN.md docs/PROGRESS.md docs/dataset.md docs/frontend.md docs/postgres.md docs/task.md docs/team.md engine/__init__.py engine/data.py engine/database.py engine/optimizer.py engine/postgres_dump.py engine/scenario_stats.py engine/simulator.py engine/validator.py examples/example.json examples/over_budget.json examples/swap.json index.html package-lock.json package.json pytest.ini requirements.txt scripts/precompute_scenarios.py src/App.jsx src/api.js src/api.test.js src/main.jsx src/styles.css tests/test_agent.py tests/test_api.py tests/test_database.py tests/test_engine.py tests/test_explain.py tests/test_optimizer.py tests/test_scenario_api.py tests/test_scenario_stats.py vite.config.js
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.