ten / fallback.py
3v324v23's picture
Улучшение работы TEN-Agent на HuggingFace Space
cc37d72
raw
history blame
12.7 kB
#!/usr/bin/env python3
import os
import json
import subprocess
import sys
import time
import shutil
from pathlib import Path
import threading
import urllib.request
import urllib.error
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)
# Создаем директорию для RAG данных
rag_dir = user_dir / "rag_data"
rag_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, rag_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 check_file_permissions(filepath):
"""Проверяет и выводит права доступа для файла"""
try:
print(f"Checking permissions for {filepath}")
if not Path(filepath).exists():
print(f" - File does not exist!")
return
# Получаем права доступа и информацию о файле
result = subprocess.run(["ls", "-la", filepath], capture_output=True, text=True)
if result.returncode == 0:
print(f" - {result.stdout.strip()}")
else:
print(f" - Error: {result.stderr.strip()}")
# Проверяем, можем ли писать в файл
try:
with open(filepath, "a") as f:
pass
print(" - Can write: Yes")
except PermissionError:
print(" - Can write: No (Permission denied)")
except Exception as e:
print(f" - Can write: No ({e})")
except Exception as e:
print(f"Error checking permissions: {e}")
def test_api_connection(max_attempts=5):
"""Проверяет, доступен ли API сервер"""
print("\nTesting API server connection...")
for attempt in range(max_attempts):
try:
with urllib.request.urlopen("http://localhost:8080/health") as response:
if response.status == 200:
print(f"✅ API server is working! Response: {response.read().decode()}")
return True
else:
print(f"❌ API server responded with status {response.status}")
except Exception as e:
print(f"❌ Attempt {attempt+1}/{max_attempts}: API server connection failed: {e}")
if attempt < max_attempts - 1:
print(f"Waiting 2 seconds before next attempt...")
time.sleep(2)
print("Could not connect to API server after multiple attempts")
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')}")
# Проверяем наличие /tmp и права на него
check_file_permissions("/tmp")
# Создаем пользовательские директории
user_dir, agents_dir, server_bin_dir, logs_dir, go_cache_dir, rag_dir = create_user_directory()
# Создаем пустой файл в директории логов, чтобы точно создать директорию
(logs_dir / "server.log").touch()
print(f"Created log directory at {logs_dir}")
# Создаем базовые конфигурационные файлы
create_basic_files(agents_dir)
# Установка переменных среды для Playground
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"
os.environ["TEN_AGENT_DIR"] = str(agents_dir)
# Запускаем API сервер с использованием нашей обертки
print(f"Starting API server with agents directory: {agents_dir}")
api_env = os.environ.copy()
api_env["TEN_AGENT_DIR"] = str(agents_dir)
# Проверяем наличие API wrapper
wrapper_path = Path("/app/api_wrapper.py")
if not wrapper_path.exists():
print(f"Error: API wrapper not found at {wrapper_path}")
sys.exit(1)
# Убедимся, что у скрипта есть права на исполнение
wrapper_path.chmod(0o755)
# Запускаем API обертку
print(f"Using Python API wrapper instead of original server")
api_process = subprocess.Popen(
["python3", str(wrapper_path)],
env=api_env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# Даем серверу время для запуска
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() if stdout else 'No output'}")
print(f"STDERR: {stderr.decode() if stderr else 'No error output'}")
sys.exit(1)
# Проверяем доступность API
print("Testing API server availability...")
api_success = test_api_connection()
if not api_success:
print("WARNING: API server may not be working correctly!")
# Запускаем playground
print("Starting Playground UI...")
playground_path = Path("/app/playground")
if not playground_path.exists():
print(f"Error: Playground directory not found at {playground_path}")
sys.exit(1)
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() if stdout else 'No output'}")
print(f"STDERR: {stderr.decode() if stderr else 'No error output'}")
# Останавливаем 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}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()