#!/usr/bin/env python3 import json import re import urllib.error import urllib.request ASK_API = "https://fission.kube5s.ru/console/api/ai/ask" CHECK_API = "https://fission.kube5s.ru/console/api/ai/check" HEADERS = {"X-Test-Sub": "livetest@test.local", "Content-Type": "application/json"} PROMPT = """Ты генерируешь код одной функции для Fission. Правила: - Если ввод кривой, сначала коротко нормализуй задачу. - Если не хватает важного условия, задай один короткий вопрос или опиши допущение. - Верни только нормализованную задачу, код и отдельный блок LLM что делает. - Код должен быть синтаксически корректным и соответствовать runtime выбранного языка. - Не добавляй лишний wrapper-код, лишние зависимости или выдуманные SDK. - Заголовок блока объяснения должен быть ровно LLM что делает. Языковые правила: - Node.js: CommonJS без ESM export-обвязки. - Python: обычный entrypoint без лишних импортов. - PHP: обычный PHP-код без выдуманных контрактов. - Ruby: корректный def/end без лишних зависимостей. """ CASES = [ { "lang": "nodejs", "question": "Юзер просит 'сделай функцию которая приветит и не упадёт если имя не пришло'. Нужна Fission Node.js функция: принять JSON, взять name если оно есть, иначе использовать default, вернуть 200 и JSON-ответ. Если условия неполные — нормализуй их сам. Потом код и блок LLM что делает.", }, { "lang": "nodejs", "question": "Нужно обработать кривой input: пользователь сказал только 'верни сумму чисел'. Сделай Fission Node.js функцию, которая принимает массив numbers, считает сумму и возвращает JSON с result. Если numbers нет или это не массив — используй пустой массив. Потом код и блок LLM что делает.", }, { "lang": "python", "question": "Юзер хочет Fission-функцию на Python, но сказал только 'преобразуй данные'. Сделай безопасный вариант: если в context есть name, верни greeting; если нет — верни default greeting. Потом код и блок LLM что делает.", }, { "lang": "python", "question": "Нужна функция, которая суммирует числа из payload, но юзер не указал формат. Сделай Fission Python handler: если в context есть numbers, сложи их; если нет — верни 0. Потом код и блок LLM что делает.", }, { "lang": "php", "question": "Юзер криво формулирует задачу: 'нужен JSON и приветствие'. Сделай обычный PHP-обработчик Fission: если в context есть name, вернуть JSON 200 с greeting, иначе default greeting. Потом код и блок LLM что делает.", }, { "lang": "php", "question": "Нужна функция на PHP для подсчёта суммы, но юзер не указал входные данные. Сделай безопасный обработчик: если в context есть numbers и это массив, посчитай сумму, иначе верни 0. Потом код и блок LLM что делает.", }, { "lang": "ruby", "question": "Юзер просит 'сделай что-то с именем, но если его нет — не падай'. Сделай Fission Ruby функцию: безопасно достать name из context, вернуть JSON с greeting, при отсутствии имени использовать default. Потом код и блок LLM что делает.", }, { "lang": "ruby", "question": "Нужна функция на Ruby для суммирования чисел, но вход кривой. Сделай обработчик Fission: взять numbers из context, если это массив — просуммировать, иначе вернуть 0. Потом код и блок LLM что делает.", }, ] def post(url: str, payload: dict) -> dict: body = json.dumps(payload).encode() req = urllib.request.Request(url, data=body, headers=HEADERS) try: with urllib.request.urlopen(req, timeout=90) as resp: return json.loads(resp.read()) except urllib.error.HTTPError as exc: return {"http_error": exc.code, "body": exc.read().decode(errors="replace")} def extract_code(answer: str) -> str: match = re.search(r"```(?:[a-zA-Z0-9_+-]+)?\n(.*?)\n```", answer, re.S) return match.group(1).strip() if match else "" def explanation_block(answer: str) -> str: match = re.search(r"(^|\n)LLM что делает\s*\n(.*)$", answer, re.S) return match.group(2).strip() if match else "" for case in CASES: ask_resp = post(ASK_API, {"question": PROMPT + "\n\nЗадача:\n" + case["question"]}) if ask_resp.get("http_error"): print(f"=== {case['lang']} HTTP {ask_resp['http_error']} ===") print(ask_resp.get("body", "")) print("\n" + "=" * 72 + "\n") continue answer = ask_resp.get("answer", ask_resp.get("error", "???")) code = extract_code(answer) explanation = explanation_block(answer) lint_resp = post(CHECK_API, {"language": case["lang"], "code": code}) if code else {"ok": False, "result": "no code extracted"} print(f"=== {case['lang']} ===") print("QUESTION:") print(case["question"]) print("\nHAS EXPLICIT HEADING:", "LLM что делает" in answer) print("HAS PARSED EXPLANATION:", bool(explanation)) print("\nANSWER:") print(answer) print("\nEXTRACTED CODE:") print(code) if explanation: print("\nEXPLANATION:") print(explanation[:800]) print("\nLINT:") print(json.dumps(lint_resp, ensure_ascii=False, indent=2)[:2000]) print("\n" + "=" * 72 + "\n")