ten / fallback.py
3v324v23's picture
Отключение файлового логирования для API сервера и перенаправление в stdout
6b8158b
raw
history blame
14.8 kB
#!/usr/bin/env python3
import os
import json
import subprocess
import sys
import time
import shutil
from pathlib import Path
def create_user_directory():
"""Создает отдельную директорию для пользовательских файлов"""
print("Creating user directory...")
# Создаем пользовательскую директорию
user_dir = Path("/tmp/ten_user")
user_dir.mkdir(exist_ok=True, parents=True)
# Создаем структуру директорий
agents_dir = user_dir / "agents"
agents_dir.mkdir(exist_ok=True, parents=True)
server_bin_dir = user_dir / "server" / "bin"
server_bin_dir.mkdir(exist_ok=True, parents=True)
# Создаем директорию для логов
logs_dir = user_dir / "logs"
logs_dir.mkdir(exist_ok=True, parents=True)
# Создаем директорию для кэша Go
go_cache_dir = Path("/tmp/go-cache")
go_cache_dir.mkdir(exist_ok=True, parents=True)
print(f"Created directory structure at {user_dir}")
return user_dir, agents_dir, server_bin_dir, logs_dir, go_cache_dir
def create_basic_files(agents_dir):
"""Создает базовые файлы конфигурации для TEN-Agent"""
print("Creating basic configuration files...")
# Создаем manifest.json
manifest = {
"_ten": {"version": "0.0.1"},
"name": "default",
"agents": [
{
"name": "voice_agent",
"description": "A simple voice agent",
"type": "voice"
},
{
"name": "chat_agent",
"description": "A text chat agent",
"type": "chat"
}
]
}
with open(agents_dir / "manifest.json", "w") as f:
json.dump(manifest, f, indent=2)
# Создаем property.json
property_data = {
"name": "TEN Agent Example",
"version": "0.0.1",
"extensions": ["openai_chatgpt"],
"description": "A basic voice agent with OpenAI",
"graphs": [
{
"name": "Voice Agent",
"description": "Basic voice agent with OpenAI",
"file": "voice_agent.json"
},
{
"name": "Chat Agent",
"description": "Simple chat agent",
"file": "chat_agent.json"
}
]
}
with open(agents_dir / "property.json", "w") as f:
json.dump(property_data, f, indent=2)
# Создаем voice_agent.json
voice_agent = {
"_ten": {"version": "0.0.1"},
"nodes": [
{
"id": "start",
"type": "start",
"data": {"x": 100, "y": 100}
},
{
"id": "openai_chatgpt",
"type": "openai_chatgpt",
"data": {
"x": 300,
"y": 200,
"properties": {
"model": "gpt-3.5-turbo",
"temperature": 0.7,
"system_prompt": "You are a helpful assistant."
}
}
},
{
"id": "end",
"type": "end",
"data": {"x": 500, "y": 100}
}
],
"edges": [
{
"id": "start_to_chatgpt",
"source": "start",
"target": "openai_chatgpt"
},
{
"id": "chatgpt_to_end",
"source": "openai_chatgpt",
"target": "end"
}
],
"groups": [],
"templates": [],
"root": "start"
}
with open(agents_dir / "voice_agent.json", "w") as f:
json.dump(voice_agent, f, indent=2)
# Создаем chat_agent.json (аналогичный voice_agent.json)
chat_agent = dict(voice_agent)
chat_agent["nodes"][1]["data"]["properties"]["system_prompt"] = "You are a helpful chat assistant."
with open(agents_dir / "chat_agent.json", "w") as f:
json.dump(chat_agent, f, indent=2)
print("Basic configuration files created successfully.")
def copy_api_server(server_bin_dir):
"""Копирует предварительно скомпилированный API сервер"""
api_bin = server_bin_dir / "api"
# Приоритезируем API сервер из директории fallback
fallback_bin = Path("/app/fallback/api")
if fallback_bin.exists():
print(f"Found pre-compiled API server at {fallback_bin}")
shutil.copy(fallback_bin, api_bin)
api_bin.chmod(0o755) # Делаем исполняемым
print(f"API server binary copied to {api_bin}")
return True
# Ищем API сервер в основной директории
original_bin = Path("/app/server/bin/api")
if original_bin.exists():
print(f"Found API server at {original_bin}")
shutil.copy(original_bin, api_bin)
api_bin.chmod(0o755) # Делаем исполняемым
print(f"API server binary copied to {api_bin}")
return True
# Если не нашли готовый бинарник, пытаемся компилировать
try:
print("No pre-compiled API server found, trying to compile from source...")
env = os.environ.copy()
env["GOCACHE"] = "/tmp/go-cache" # Указываем директорию для кэша Go
env["GOPATH"] = "/tmp/go-path" # Указываем пользовательский GOPATH
# Создаем директорию для GOPATH
Path("/tmp/go-path").mkdir(exist_ok=True, parents=True)
# Компилируем с пользовательскими настройками
result = subprocess.run(
"cd /app/server && go build -o /tmp/ten_user/server/bin/api main.go",
shell=True,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env
)
print(f"Successfully compiled API server: {result.stdout.decode()}")
api_bin.chmod(0o755)
return True
except subprocess.CalledProcessError as e:
print(f"Failed to compile API server: {e.stderr.decode()}")
print("Critical error: No API server available!")
return False
def main():
try:
print(f"Starting TEN-Agent in fallback mode...")
print(f"Current directory: {os.getcwd()}")
# Выводим информацию о среде
user = os.environ.get('USER', 'unknown')
print(f"Current user: {user}")
print(f"HOME: {os.environ.get('HOME', 'unset')}")
print(f"PATH: {os.environ.get('PATH', 'unset')}")
# Создаем пользовательские директории
user_dir, agents_dir, server_bin_dir, logs_dir, go_cache_dir = create_user_directory()
# Создаем пустой файл в директории логов, чтобы точно создать директорию
(logs_dir / "server.log").touch()
print(f"Created log directory at {logs_dir}")
# Создаем базовые конфигурационные файлы
create_basic_files(agents_dir)
# Копируем API сервер
if not copy_api_server(server_bin_dir):
print("Critical error: Cannot prepare API server")
sys.exit(1)
# Проверяем, что API сервер действительно скопирован и исполняемый
api_bin = server_bin_dir / "api"
if not api_bin.exists():
print(f"Critical error: API server binary not found at {api_bin}")
sys.exit(1)
try:
api_bin.chmod(0o755) # Дополнительно проверяем права
except Exception as e:
print(f"Warning: Could not set execute permissions on API server binary: {e}")
# Продолжаем, возможно, права уже установлены
print(f"API server binary prepared successfully: {api_bin}")
print(f"File exists: {api_bin.exists()}, size: {api_bin.stat().st_size} bytes")
# Установка переменных среды
os.environ["PORT"] = "7860" # HuggingFace использует порт 7860
os.environ["AGENT_SERVER_URL"] = "http://localhost:8080"
os.environ["NEXT_PUBLIC_EDIT_GRAPH_MODE"] = "true"
os.environ["NEXT_PUBLIC_DISABLE_CAMERA"] = "true"
# Путь к бинарнику API сервера
api_bin_str = str(api_bin)
# Запускаем API сервер с указанием пути к agents директории
print(f"Starting API server with agents directory: {agents_dir}")
api_env = os.environ.copy()
api_env["TEN_AGENT_DIR"] = str(agents_dir)
api_env["GOCACHE"] = str(go_cache_dir) # Устанавливаем переменную GOCACHE
# Отключаем логирование в файл
api_env["GF_LOG_MODE"] = "console" # Логирование только в консоль
api_env["LOG_LEVEL"] = "error" # Минимальный уровень логирования
api_env["TEN_LOG_DISABLE_FILE"] = "true" # Отключаем логирование в файл (кастомная переменная)
api_env["GF_LOG_FILE_STAT"] = "false" # Отключаем статистику файлов логов
# Выводим важные переменные окружения
print(f"Environment variables:")
print(f"TEN_AGENT_DIR: {api_env.get('TEN_AGENT_DIR')}")
print(f"GF_LOG_MODE: {api_env.get('GF_LOG_MODE')}")
print(f"LOG_LEVEL: {api_env.get('LOG_LEVEL')}")
print(f"TEN_LOG_DISABLE_FILE: {api_env.get('TEN_LOG_DISABLE_FILE')}")
print(f"GOCACHE: {api_env.get('GOCACHE')}")
# Дополнительно проверяем права на исполнение через ls -la
subprocess.run(["ls", "-la", api_bin_str], check=True)
# Проверяем директорию логов
subprocess.run(["ls", "-la", str(logs_dir)], check=True)
# Запускаем API сервер с передачей аргумента для отключения файлового логирования
print(f"Executing API server: {api_bin_str}")
try:
api_process = subprocess.Popen(
[api_bin_str, "--log_to_stdout", "--disable_file_logging"],
env=api_env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
except Exception as e:
print(f"Failed to start API server: {e}")
sys.exit(1)
# Даем серверу время для запуска и выводим любые ошибки сразу
time.sleep(2)
# Проверяем, запустился ли сервер
if api_process.poll() is not None:
print("API server failed to start!")
stdout, stderr = api_process.communicate()
print(f"STDOUT: {stdout.decode()}")
print(f"STDERR: {stderr.decode()}")
sys.exit(1)
# Проверяем доступность API
print("Testing API server availability...")
try:
import urllib.request
response = urllib.request.urlopen("http://localhost:8080/graphs")
print(f"API server is responding! Response: {response.read().decode()}")
except Exception as e:
print(f"API server is not responding yet, but continuing... ({e})")
print("API server started successfully")
# Запускаем playground
print("Starting Playground UI...")
playground_process = subprocess.Popen(
"cd /app/playground && pnpm dev",
env=os.environ,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# Даем UI время для запуска
time.sleep(5)
# Проверяем, запустился ли UI
if playground_process.poll() is not None:
print("Playground UI failed to start!")
stdout, stderr = playground_process.communicate()
print(f"STDOUT: {stdout.decode()}")
print(f"STDERR: {stderr.decode()}")
# Останавливаем API сервер
api_process.terminate()
sys.exit(1)
print("TEN-Agent started successfully in fallback mode.")
print("Playground UI is available at http://localhost:7860")
# Следим за выводом процессов в реальном времени
def stream_output(process, name):
for line in iter(process.stdout.readline, b''):
print(f"[{name}] {line.decode().strip()}")
# После завершения стандартного вывода, читаем stderr
for line in iter(process.stderr.readline, b''):
print(f"[{name} ERROR] {line.decode().strip()}")
api_thread = threading.Thread(target=stream_output, args=(api_process, "API"))
ui_thread = threading.Thread(target=stream_output, args=(playground_process, "UI"))
api_thread.daemon = True
ui_thread.daemon = True
api_thread.start()
ui_thread.start()
# Ожидаем завершения любого из процессов
while True:
if api_process.poll() is not None:
print("API server has stopped.")
playground_process.terminate()
break
if playground_process.poll() is not None:
print("Playground UI has stopped.")
api_process.terminate()
break
time.sleep(1)
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
import threading
main()