|
|
|
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_cache_dir = Path("/tmp/go-cache") |
|
go_cache_dir.mkdir(exist_ok=True, parents=True) |
|
|
|
|
|
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 = { |
|
"_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_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 = { |
|
"_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 = 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')}") |
|
|
|
|
|
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) |
|
|
|
|
|
os.environ["PORT"] = "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) |
|
|
|
|
|
print(f"Starting API server with agents directory: {agents_dir}") |
|
api_env = os.environ.copy() |
|
api_env["TEN_AGENT_DIR"] = str(agents_dir) |
|
|
|
|
|
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) |
|
|
|
|
|
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) |
|
|
|
|
|
print("Testing API server availability...") |
|
api_success = test_api_connection() |
|
|
|
if not api_success: |
|
print("WARNING: API server may not be working correctly!") |
|
|
|
|
|
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 |
|
) |
|
|
|
|
|
time.sleep(5) |
|
|
|
|
|
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_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()}") |
|
|
|
|
|
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() |