Загрузка данных


import json
import os
import subprocess
import requests

API_KEY = os.getenv("ANTHROPIC_API_KEY")
BASE_URL = os.getenv("ANTHROPIC_BASE_URL", "http://localhost:8080")

SYSTEM_PROMPT = """
Ты терминальный AI-агент.

Если нужен инструмент, отвечай ТОЛЬКО JSON.

Пример:

{
  "tool": "write_file",
  "args": {
    "path": "hello.py",
    "content": "print('hello')"
  }
}

Доступные инструменты:

read_file(path)
write_file(path, content)
list_files(path)
run_command(command)

Если инструмент не нужен — отвечай обычным текстом.
"""


def read_file(path):
    with open(path, "r", encoding="utf-8") as f:
        return f.read()


def write_file(path, content):
    with open(path, "w", encoding="utf-8") as f:
        f.write(content)
    return f"saved: {path}"


def list_files(path="."):
    return "\n".join(os.listdir(path))


def run_command(command):
    result = subprocess.run(
        command,
        shell=True,
        capture_output=True,
        text=True
    )
    return result.stdout + result.stderr


TOOLS = {
    "read_file": read_file,
    "write_file": write_file,
    "list_files": list_files,
    "run_command": run_command,
}


messages = []


def ask_llm():
    payload = {
        "model": "claude-sonnet-4",
        "messages": messages,
        "system": SYSTEM_PROMPT,
        "max_tokens": 4000
    }

    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    }

    r = requests.post(
        f"{BASE_URL}/v1/messages",
        json=payload,
        headers=headers,
        timeout=300
    )

    r.raise_for_status()

    data = r.json()

    try:
        return data["content"][0]["text"]
    except Exception:
        return str(data)


while True:
    user = input("\n> ")

    if user.lower() in ["exit", "quit"]:
        break

    messages.append({
        "role": "user",
        "content": user
    })

    for _ in range(10):
        response = ask_llm()

        print("\nAI:")
        print(response)

        try:
            call = json.loads(response)

            tool_name = call["tool"]
            args = call["args"]

            if tool_name not in TOOLS:
                break

            result = TOOLS[tool_name](**args)

            print("\nTOOL RESULT:")
            print(result)

            messages.append({
                "role": "assistant",
                "content": response
            })

            messages.append({
                "role": "user",
                "content": f"Tool result:\n{result}"
            })

        except Exception:
            messages.append({
                "role": "assistant",
                "content": response
            })
            break