3v324v23 commited on
Commit
cc37d72
·
1 Parent(s): 2e3dab3

Улучшение работы TEN-Agent на HuggingFace Space

Browse files
Files changed (5) hide show
  1. .space/config.json +7 -0
  2. Dockerfile +89 -40
  3. api_wrapper.py +162 -275
  4. fallback.py +91 -118
  5. start.sh +63 -44
.space/config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "docker": {
3
+ "enable": true,
4
+ "build": true,
5
+ "gpu": false
6
+ }
7
+ }
Dockerfile CHANGED
@@ -1,56 +1,105 @@
1
- FROM node:18
2
 
3
- WORKDIR /app
4
-
5
- # Устанавливаем Python
6
  RUN apt-get update && apt-get install -y \
 
 
 
 
 
 
 
 
 
 
 
7
  python3 \
8
- python3-pip \
9
  python3-venv \
10
- git \
11
- curl \
12
- && rm -rf /var/lib/apt/lists/*
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- # Копируем файлы API wrapper и конфигурации
15
- COPY api_wrapper.py /app/
16
- COPY app.py /app/
17
- COPY proxy.py /app/
18
- COPY .space/hf-space.sh /app/
19
 
20
- # Создаем директории
21
- RUN mkdir -p /tmp/ten_user/agents /tmp/ten_user/logs /app/backup /tmp/ten_playground
22
- RUN chmod -R 777 /tmp/ten_playground
23
 
24
- # Создаем и активируем виртуальную среду Python
25
- RUN python3 -m venv /app/venv
26
- ENV PATH="/app/venv/bin:$PATH"
 
27
 
28
- # Устанавливаем Python зависимости в виртуальную среду
29
- COPY requirements.txt /app/
30
- RUN pip install --no-cache-dir -U pip && \
31
- pip install --no-cache-dir -r requirements.txt
 
 
32
 
33
- # Клонируем репозиторий TEN-Agent
34
- RUN git clone --depth 1 https://github.com/TEN-framework/TEN-Agent.git /tmp/ten-agent
 
 
 
 
35
 
36
- # Копируем только необходимые файлы из репозитория
37
- RUN mkdir -p /app/playground
38
- RUN cp -r /tmp/ten-agent/playground/* /app/playground/
39
- RUN rm -rf /tmp/ten-agent
 
40
 
41
- # Устанавливаем pnpm и next глобально для использования с npx
42
- RUN npm install -g pnpm@8 next@latest
43
 
44
- # Возвращаемся в основную директорию
45
- WORKDIR /app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
- # Делаем скрипт запуска исполняемым
48
- RUN chmod +x /app/hf-space.sh
49
 
50
- # Экспортируем порт
51
- EXPOSE 7860 3000 8080
 
 
52
 
53
- # Запускаем приложение через скрипт
54
- COPY start.sh /app/
55
- RUN chmod +x /app/start.sh
56
  CMD ["/app/start.sh"]
 
1
+ FROM ubuntu:22.04
2
 
3
+ # Установка базовых пакетов
 
 
4
  RUN apt-get update && apt-get install -y \
5
+ curl \
6
+ git \
7
+ wget \
8
+ make \
9
+ gcc \
10
+ build-essential \
11
+ libasound2 \
12
+ libgstreamer1.0-dev \
13
+ libunwind-dev \
14
+ libc++1 \
15
+ libssl-dev \
16
  python3 \
 
17
  python3-venv \
18
+ python3-pip \
19
+ python3-dev \
20
+ unzip \
21
+ jq \
22
+ vim \
23
+ ca-certificates \
24
+ gnupg \
25
+ lsb-release \
26
+ net-tools \
27
+ procps \
28
+ && apt-get clean && rm -rf /var/lib/apt/lists/* && rm -rf /tmp/*
29
+
30
+ # Установка Go
31
+ RUN wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz && \
32
+ tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz && \
33
+ rm go1.21.0.linux-amd64.tar.gz
34
 
35
+ # Настройка окружения Go
36
+ ENV PATH=$PATH:/usr/local/go/bin
37
+ ENV GOPATH=/go
38
+ ENV PATH=$PATH:$GOPATH/bin
39
+ RUN mkdir -p /go && chmod 777 /go
40
 
41
+ # Создание директории для кэша Go
42
+ ENV GOCACHE=/tmp/go-cache
43
+ RUN mkdir -p /tmp/go-cache && chmod 777 /tmp/go-cache
44
 
45
+ # Установка Node.js и pnpm
46
+ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
47
+ apt-get install -y nodejs && \
48
+ npm install -g pnpm
49
 
50
+ # Клонирование репозитория TEN-Agent
51
+ WORKDIR /app
52
+ RUN git clone --depth 1 https://github.com/TEN-framework/TEN-Agent.git /app-temp && \
53
+ mv /app-temp/* /app/ && \
54
+ mv /app-temp/.* /app/ 2>/dev/null || true && \
55
+ rm -rf /app-temp
56
 
57
+ # Создание пользовательских директорий для временных файлов
58
+ RUN mkdir -p /tmp/ten_user && chmod 777 /tmp/ten_user
59
+ RUN mkdir -p /tmp/ten_user/agents && chmod 777 /tmp/ten_user/agents
60
+ RUN mkdir -p /tmp/ten_user/logs && chmod 777 /tmp/ten_user/logs
61
+ RUN mkdir -p /tmp/ten_user/rag_data && chmod 777 /tmp/ten_user/rag_data
62
+ RUN mkdir -p /app/backup && chmod 777 /app/backup
63
 
64
+ # Компиляция API сервера (для справки, мы будем использовать Python-реализацию)
65
+ RUN mkdir -p /app/server/bin && \
66
+ cd /app/server && \
67
+ GOCACHE=/tmp/go-cache go build -o bin/api main.go && \
68
+ chmod +x bin/api
69
 
70
+ # Проверяем, что API сервер скомпилирован
71
+ RUN ls -la /app/server/bin/api || echo "API server not compiled"
72
 
73
+ # Предварительная установка зависимостей для playground
74
+ # Делаем это отдельно, чтобы не пересобирать при каждом изменении
75
+ RUN cd /app/playground && pnpm install
76
+
77
+ # Запускаем playground один раз для предварительной сборки
78
+ RUN cd /app/playground && pnpm build || echo "Failed to build playground, but continuing"
79
+
80
+ # Копируем наши скрипты
81
+ COPY fallback.py /app/fallback.py
82
+ COPY api_wrapper.py /app/api_wrapper.py
83
+ COPY start.sh /app/start.sh
84
+ RUN chmod +x /app/start.sh /app/fallback.py /app/api_wrapper.py
85
+
86
+ # Устанавливаем переменные окружения для HuggingFace
87
+ ENV HF_SPACE=true
88
+ ENV AGENT_SERVER_URL=http://localhost:8080
89
+ ENV NEXT_PUBLIC_EDIT_GRAPH_MODE=true
90
+ ENV NEXT_PUBLIC_DISABLE_CAMERA=true
91
+ ENV PORT=7860
92
+ ENV API_PORT=8080
93
+ ENV TEN_AGENT_DIR=/tmp/ten_user/agents
94
+ ENV PYTHONUNBUFFERED=1
95
 
96
+ # Открываем порты (7860 для HF Space, 8080 для API)
97
+ EXPOSE 7860 8080
98
 
99
+ # Предварительно создаем важные файлы
100
+ RUN mkdir -p /app/agents
101
+ RUN echo '{"_ten":{"version":"0.0.1"},"name":"default","agents":[{"name":"voice_agent","description":"A simple voice agent","type":"voice"}]}' > /app/agents/manifest.json
102
+ RUN echo '{"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"}]}' > /app/agents/property.json
103
 
104
+ # Запускаем TEN-Agent через fallback скрипт
 
 
105
  CMD ["/app/start.sh"]
api_wrapper.py CHANGED
@@ -3,317 +3,204 @@ import http.server
3
  import json
4
  import os
5
  import sys
6
- import logging
 
7
  from pathlib import Path
8
- import time
9
- from urllib.parse import parse_qs, urlparse
10
-
11
- # Настройка логирования
12
- logging.basicConfig(
13
- level=logging.INFO,
14
- format='%(asctime)s [%(levelname)s] %(message)s',
15
- handlers=[logging.StreamHandler()]
16
- )
17
- logger = logging.getLogger("ten_api")
18
-
19
- # Проверяем, запущены ли мы в HuggingFace Space
20
- IS_HF_SPACE = os.environ.get("SPACE_ID") is not None
21
- USE_WRAPPER = os.environ.get("USE_WRAPPER", "false").lower() in ("true", "1", "yes")
22
 
23
  # Путь к директории с агентами
24
- if IS_HF_SPACE or USE_WRAPPER:
25
- # В HuggingFace используем корневую директорию /tmp
26
- TMP_DIR = os.environ.get("TMP_DIR", "/tmp")
27
- AGENT_DIR = os.environ.get("TEN_AGENT_DIR", TMP_DIR)
28
- else:
29
- AGENT_DIR = os.environ.get("TEN_AGENT_DIR", "/tmp/ten_user/agents")
30
-
31
- logger.info(f"Using agent directory: {AGENT_DIR}")
32
- logger.info(f"Running in HuggingFace Space: {IS_HF_SPACE}")
33
- logger.info(f"Using Wrapper: {USE_WRAPPER}")
34
-
35
- # Проверяем наличие файлов конфигурации
36
- agent_dir_path = Path(AGENT_DIR)
37
- if agent_dir_path.exists():
38
- logger.info(f"Checking files in agent directory {AGENT_DIR}:")
39
- for file in agent_dir_path.iterdir():
40
- if file.name.endswith('.json'):
41
- logger.info(f" - {file.name} ({os.path.getsize(file)}b)")
42
- else:
43
- logger.warning(f"Agent directory {AGENT_DIR} does not exist!")
44
 
45
  class TENAgentHandler(http.server.BaseHTTPRequestHandler):
46
- def log_message(self, format, *args):
47
- """Переопределение логирования для вывода в stdout"""
48
- logger.info("%s - %s", self.address_string(), format % args)
49
-
50
  def _set_headers(self, content_type="application/json"):
51
  self.send_response(200)
52
  self.send_header('Content-type', content_type)
53
  self.send_header('Access-Control-Allow-Origin', '*')
54
  self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
55
- self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
56
  self.end_headers()
57
 
58
  def do_OPTIONS(self):
59
  self._set_headers()
60
 
61
- def do_GET(self):
62
- logger.info(f"GET request: {self.path}")
63
-
64
- # Разбор URL для параметров
65
- parsed_url = urlparse(self.path)
66
- path = parsed_url.path
67
- query_params = parse_qs(parsed_url.query)
68
 
69
- # Обрабатываем API endpoints
70
- if path == "/graphs" or path == "/api/graphs":
71
- self._handle_graphs()
72
- elif path == "/health" or path == "/":
73
- self._handle_health()
74
- elif path == "/list":
75
- self._handle_list()
76
- elif path == "/dev-tmp/addons/default-properties":
77
- self._handle_default_properties()
78
- elif path == "/vector/document/preset/list":
79
- self._handle_vector_preset_list()
80
- elif path.startswith("/api/dev/v1/packages"):
81
- self._handle_packages()
82
- elif path.startswith("/api/designer/v1/packages"):
83
- self._handle_packages()
84
- else:
85
- # Для всех остальных запросов возвращаем 404
86
- self.send_error(404, f"Not found: {path}")
87
-
88
- def _handle_graphs(self):
89
- """Обработка запроса на получение списка графов"""
90
  try:
91
- property_file = Path(AGENT_DIR) / "property.json"
92
- logger.info(f"Looking for property file at {property_file}")
93
 
94
- if not property_file.exists():
95
- logger.error(f"Property file not found at {property_file}")
96
-
97
- # Проверяем, возможно файл находится в другой директории
98
- alt_property_file = Path("/tmp/property.json")
99
- if alt_property_file.exists():
100
- logger.info(f"Found property file at alternative location: {alt_property_file}")
101
- property_file = alt_property_file
102
- else:
103
- self.send_error(404, "Property file not found")
104
- return
105
-
106
- with open(property_file, "r") as f:
107
- property_data = json.load(f)
 
 
 
 
108
 
109
- graphs = property_data.get("graphs", [])
110
-
111
- # Для каждого графа проверяем наличие файла
112
- for graph in graphs:
113
- file_name = graph.get("file", "")
114
- file_path = Path(AGENT_DIR) / file_name
115
- alt_file_path = Path("/tmp") / file_name
 
 
 
 
 
 
116
 
117
- if file_path.exists():
118
- logger.info(f"Graph file exists: {file_path}")
119
- elif alt_file_path.exists():
120
- logger.info(f"Graph file exists at alternative location: {alt_file_path}")
121
- else:
122
- logger.warning(f"Graph file not found: {file_name}")
 
 
 
123
 
124
- self._set_headers()
125
- self.wfile.write(json.dumps(graphs).encode())
126
- logger.info(f"Returned {len(graphs)} graphs")
 
 
 
 
 
127
  except Exception as e:
128
- logger.error(f"Error reading property.json: {e}")
129
- self.send_error(500, f"Internal error: {e}")
130
-
131
- def _handle_health(self):
132
- """Обработка запроса на проверку статуса сервера"""
133
- self._set_headers()
134
- self.wfile.write(json.dumps({
135
- "status": "ok",
136
- "time": time.time(),
137
- "is_hf_space": IS_HF_SPACE,
138
- "using_wrapper": True,
139
- "agent_dir": AGENT_DIR
140
- }).encode())
141
 
142
- def _handle_list(self):
143
- """Обработка запроса на получение списка активных сессий"""
144
- self._set_headers()
145
- self.wfile.write(json.dumps([]).encode())
146
-
147
- def _handle_default_properties(self):
148
- """Обработка запроса на получение настроек по умолчанию"""
149
- self._set_headers()
150
- self.wfile.write(json.dumps({}).encode())
151
-
152
- def _handle_vector_preset_list(self):
153
- """Обработка запроса на получение списка пресетов векторов"""
154
- self._set_headers()
155
- self.wfile.write(json.dumps([]).encode())
156
-
157
- def _handle_packages(self):
158
- """Обработка запросов к пакетам"""
159
- # Этот метод эмулирует возврат списка графов и для других эндпоинтов
160
  try:
161
- property_file = Path(AGENT_DIR) / "property.json"
162
- if not property_file.exists():
163
- # Проверяем альтернативную директорию
164
- alt_property_file = Path("/tmp/property.json")
165
- if alt_property_file.exists():
166
- property_file = alt_property_file
167
- else:
168
- logger.error(f"Property file not found at {property_file}")
169
- self.send_error(404, "Property file not found")
170
- return
171
 
172
- with open(property_file, "r") as f:
173
- property_data = json.load(f)
 
174
 
175
- graphs = property_data.get("graphs", [])
176
- self._set_headers()
177
- response_data = {
178
- "data": graphs,
179
- "status": 200,
180
- "message": "Success"
181
- }
182
- self.wfile.write(json.dumps(response_data).encode())
183
- logger.info(f"Handled packages request and returned {len(graphs)} graphs")
184
- except Exception as e:
185
- logger.error(f"Error handling packages request: {e}")
186
- self.send_error(500, f"Internal error: {e}")
187
-
188
- def do_POST(self):
189
- logger.info(f"POST request: {self.path}")
190
-
191
- # Читаем тело запроса
192
- content_length = int(self.headers['Content-Length']) if 'Content-Length' in self.headers else 0
193
- post_data = self.rfile.read(content_length)
194
-
195
- try:
196
- request_data = json.loads(post_data) if content_length > 0 else {}
197
- except json.JSONDecodeError:
198
- request_data = {}
199
 
200
- logger.info(f"Request data: {json.dumps(request_data)[:200]}...")
201
-
202
- # Обрабатываем различные POST запросы
203
- if self.path == "/ping":
204
- self._handle_ping()
205
- elif self.path == "/token/generate":
206
- self._handle_token_generate(request_data)
207
- elif self.path == "/start":
208
- self._handle_start(request_data)
209
- elif self.path == "/stop":
210
- self._handle_stop(request_data)
211
- elif self.path == "/vector/document/update" or self.path == "/vector/document/upload":
212
- self._handle_vector_document(request_data)
213
- elif self.path.startswith("/api/dev/v1/packages") or self.path.startswith("/api/designer/v1/packages"):
214
- self._handle_packages_post(request_data)
215
- else:
216
- # Для всех остальных запросов возвращаем 404
217
- self.send_error(404, f"Not found: {self.path}")
218
-
219
- def _handle_ping(self):
220
- """Обработка ping запроса"""
221
- self._set_headers()
222
- self.wfile.write(json.dumps({
223
- "status": "ok",
224
- "timestamp": time.time(),
225
- "server": "ten-agent-api-wrapper",
226
- "in_hf_space": IS_HF_SPACE,
227
- "agent_dir": AGENT_DIR
228
- }).encode())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
 
230
- def _handle_token_generate(self, request_data):
231
- """Обработка запроса на генерацию токена"""
232
- self._set_headers()
233
- response = {
234
- "token": "dummy_token_for_agora",
235
- "request_id": request_data.get("RequestId", ""),
236
- "channel_name": request_data.get("ChannelName", ""),
237
- "uid": request_data.get("Uid", 0)
238
- }
239
- self.wfile.write(json.dumps(response).encode())
240
- logger.info(f"Generated token for channel: {request_data.get('ChannelName', '')}")
241
 
242
- def _handle_start(self, request_data):
243
- """Обработка запроса на запуск сессии"""
244
- graph_file = request_data.get("graph_file", "")
245
- logger.info(f"Starting session with graph file: {graph_file}")
246
-
247
- # Проверяем наличие файла графа
248
- graph_path = Path(AGENT_DIR) / graph_file
249
- alt_graph_path = Path("/tmp") / graph_file
250
 
251
- if graph_path.exists():
252
- logger.info(f"Found graph file at: {graph_path}")
253
- elif alt_graph_path.exists():
254
- logger.info(f"Found graph file at alternative location: {alt_graph_path}")
255
- else:
256
- logger.warning(f"Graph file not found: {graph_file}")
257
-
258
- self._set_headers()
259
- # Возвращаем успешный статус и ID сессии
260
- response = {
261
- "status": "ok",
262
- "session_id": f"dummy_session_{int(time.time())}",
263
- "message": "Session started successfully",
264
- "graph_file": graph_file
265
  }
266
- self.wfile.write(json.dumps(response).encode())
267
- logger.info(f"Started session with graph: {graph_file}")
268
-
269
- def _handle_stop(self, request_data):
270
- """Обработка запроса на остановку сессии"""
271
- self._set_headers()
272
- self.wfile.write(json.dumps({
273
- "status": "ok",
274
- "message": "Session stopped successfully"
275
- }).encode())
276
- logger.info(f"Stopped session: {request_data.get('session_id', '')}")
277
-
278
- def _handle_vector_document(self, request_data):
279
- """Обработка запроса на работу с векторными документами"""
280
- self._set_headers()
281
- self.wfile.write(json.dumps({
282
- "status": "ok",
283
- "document_id": f"dummy_doc_{int(time.time())}",
284
- "message": "Document processed successfully"
285
- }).encode())
286
- logger.info(f"Processed vector document: {request_data.get('name', 'unnamed')}")
287
 
288
- def _handle_packages_post(self, request_data):
289
- """Обработка POST запросов к пакетам"""
290
- self._set_headers()
291
- response_data = {
292
- "data": {},
293
- "status": 200,
294
- "message": "Success"
295
- }
296
- self.wfile.write(json.dumps(response_data).encode())
297
- logger.info(f"Handled packages POST request")
298
-
299
- def run(server_class=http.server.HTTPServer, handler_class=TENAgentHandler, port=8080):
300
- server_address = ('', port)
301
- httpd = server_class(server_address, handler_class)
302
- logger.info(f"Starting API server on port {port}...")
303
- logger.info(f"Using agent directory: {AGENT_DIR}")
304
  try:
305
  httpd.serve_forever()
306
  except KeyboardInterrupt:
307
- logger.info("Server stopped by user")
308
  except Exception as e:
309
- logger.error(f"Server error: {e}")
310
- raise
311
 
312
  if __name__ == "__main__":
313
  port = int(os.environ.get("API_PORT", 8080))
314
- try:
315
- run(port=port)
316
- except KeyboardInterrupt:
317
- logger.info("Server stopped by user")
318
- except Exception as e:
319
- logger.error(f"Server error: {e}")
 
3
  import json
4
  import os
5
  import sys
6
+ import datetime
7
+ import traceback
8
  from pathlib import Path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  # Путь к директории с агентами
11
+ AGENT_DIR = os.environ.get("TEN_AGENT_DIR", "/tmp/ten_user/agents")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  class TENAgentHandler(http.server.BaseHTTPRequestHandler):
 
 
 
 
14
  def _set_headers(self, content_type="application/json"):
15
  self.send_response(200)
16
  self.send_header('Content-type', content_type)
17
  self.send_header('Access-Control-Allow-Origin', '*')
18
  self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
19
+ self.send_header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With')
20
  self.end_headers()
21
 
22
  def do_OPTIONS(self):
23
  self._set_headers()
24
 
25
+ def log_request(self, code='-', size='-'):
26
+ # Переопределяем, чтобы не логировать каждый запрос в stderr
27
+ # особенно health checks, которые могут забивать логи
28
+ if self.path != '/health':
29
+ super().log_request(code, size)
 
 
30
 
31
+ def do_GET(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  try:
33
+ print(f"GET request: {self.path}")
 
34
 
35
+ # Базовые API эндпоинты
36
+ if self.path in ["/graphs", "/api/graphs"]:
37
+ # Чтение property.json для получения списка графов
38
+ try:
39
+ property_file = Path(AGENT_DIR) / "property.json"
40
+ if not property_file.exists():
41
+ self.send_error(404, "Property file not found")
42
+ return
43
+
44
+ with open(property_file, "r") as f:
45
+ property_data = json.load(f)
46
+
47
+ graphs = property_data.get("graphs", [])
48
+ self._set_headers()
49
+ self.wfile.write(json.dumps(graphs).encode())
50
+ except Exception as e:
51
+ print(f"Error reading property.json: {e}")
52
+ self.send_error(500, f"Internal error: {e}")
53
 
54
+ elif self.path in ["/health", "/"]:
55
+ # Просто возвращаем, что API сервер работает
56
+ self._set_headers()
57
+ self.wfile.write(json.dumps({
58
+ "status": "ok",
59
+ "time": str(datetime.datetime.now()),
60
+ "message": "TEN Agent API wrapper is running"
61
+ }).encode())
62
+
63
+ elif self.path == "/list":
64
+ # Возвращаем пустой список сессий
65
+ self._set_headers()
66
+ self.wfile.write(json.dumps([]).encode())
67
 
68
+ elif self.path.startswith("/dev-tmp/"):
69
+ # Обработка всех запросов к /dev-tmp/
70
+ self._set_headers()
71
+ self.wfile.write(json.dumps({}).encode())
72
+
73
+ elif self.path == "/vector/document/preset/list":
74
+ # Возвращаем пустой список предустановок векторов
75
+ self._set_headers()
76
+ self.wfile.write(json.dumps([]).encode())
77
 
78
+ # Обработка запросов к API TEN Graph Designer
79
+ elif self.path.startswith("/api/designer/") or self.path.startswith("/api/dev/"):
80
+ self._set_headers()
81
+ self.wfile.write(json.dumps({"data": [], "status": 200, "message": "Success"}).encode())
82
+
83
+ else:
84
+ # Для всех остальных запросов возвращаем 404
85
+ self.send_error(404, "Not found")
86
  except Exception as e:
87
+ print(f"Error handling GET request: {e}")
88
+ traceback.print_exc()
89
+ self.send_error(500, f"Internal server error: {e}")
 
 
 
 
 
 
 
 
 
 
90
 
91
+ def do_POST(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  try:
93
+ print(f"POST request: {self.path}")
 
 
 
 
 
 
 
 
 
94
 
95
+ # Читаем тело запроса
96
+ content_length = int(self.headers['Content-Length']) if 'Content-Length' in self.headers else 0
97
+ post_data = self.rfile.read(content_length)
98
 
99
+ try:
100
+ request_data = json.loads(post_data) if content_length > 0 else {}
101
+ except json.JSONDecodeError:
102
+ request_data = {}
103
+
104
+ print(f"Request data: {request_data}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
+ if self.path == "/ping":
107
+ # Для ping запросов просто возвращаем успешный статус
108
+ self._set_headers()
109
+ self.wfile.write(json.dumps({"status": "ok"}).encode())
110
+
111
+ elif self.path == "/token/generate":
112
+ # Для запросов на генерацию токена возвращаем простой токен
113
+ # Это нужно для Agora SDK
114
+ self._set_headers()
115
+ response = {
116
+ "token": "dummy_token_for_agora",
117
+ "request_id": request_data.get("RequestId", ""),
118
+ "channel_name": request_data.get("ChannelName", ""),
119
+ "uid": request_data.get("Uid", 0)
120
+ }
121
+ self.wfile.write(json.dumps(response).encode())
122
+
123
+ elif self.path == "/start":
124
+ # Для запросов на запуск сессии возвращаем успешный статус
125
+ self._set_headers()
126
+ # Возвращаем идентификатор сессии для совместимости
127
+ session_id = "fallback-session-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S")
128
+ self.wfile.write(json.dumps({
129
+ "status": "ok",
130
+ "session_id": session_id
131
+ }).encode())
132
+
133
+ elif self.path == "/stop":
134
+ # Для запросов на остановку сессии возвращаем успешный статус
135
+ self._set_headers()
136
+ self.wfile.write(json.dumps({"status": "ok"}).encode())
137
+
138
+ elif self.path.startswith("/vector/document/"):
139
+ # Для запросов на обновление или загрузку документов возвращаем успешный статус
140
+ self._set_headers()
141
+ self.wfile.write(json.dumps({"status": "ok", "message": "Operation completed"}).encode())
142
+
143
+ # API для TEN Graph Designer
144
+ elif self.path.startswith("/api/designer/") or self.path.startswith("/api/dev/"):
145
+ self._set_headers()
146
+ self.wfile.write(json.dumps({"data": {}, "status": 200, "message": "Success"}).encode())
147
+
148
+ else:
149
+ # Для всех остальных запросов возвращаем 404
150
+ self.send_error(404, "Not found")
151
+ except Exception as e:
152
+ print(f"Error handling POST request: {e}")
153
+ traceback.print_exc()
154
+ self.send_error(500, f"Internal server error: {e}")
155
+
156
+ def run(server_class=http.server.HTTPServer, handler_class=TENAgentHandler, port=8080):
157
+ server_address = ('', port)
158
+ httpd = server_class(server_address, handler_class)
159
+ print(f"Starting API server on port {port}...")
160
+ print(f"Using agent directory: {AGENT_DIR}")
161
 
162
+ # Проверяем, что директория с агентами существует
163
+ agent_dir_path = Path(AGENT_DIR)
164
+ if not agent_dir_path.exists():
165
+ print(f"WARNING: Agent directory {AGENT_DIR} does not exist, creating it...")
166
+ agent_dir_path.mkdir(exist_ok=True, parents=True)
 
 
 
 
 
 
167
 
168
+ # Проверка наличия необходимых файлов
169
+ property_file = agent_dir_path / "property.json"
170
+ if not property_file.exists():
171
+ print(f"WARNING: property.json not found in {AGENT_DIR}")
172
+ print("Creating minimal property.json...")
 
 
 
173
 
174
+ # Создаем базовый property.json
175
+ property_data = {
176
+ "name": "TEN Agent Example",
177
+ "version": "0.0.1",
178
+ "extensions": ["openai_chatgpt"],
179
+ "description": "A basic voice agent with OpenAI",
180
+ "graphs": [
181
+ {
182
+ "name": "Voice Agent",
183
+ "description": "Basic voice agent with OpenAI",
184
+ "file": "voice_agent.json"
185
+ }
186
+ ]
 
187
  }
188
+
189
+ try:
190
+ with open(property_file, "w") as f:
191
+ json.dump(property_data, f, indent=2)
192
+ print(f"Created {property_file}")
193
+ except Exception as e:
194
+ print(f"ERROR: Could not create property.json: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  try:
197
  httpd.serve_forever()
198
  except KeyboardInterrupt:
199
+ print("Shutting down API server...")
200
  except Exception as e:
201
+ print(f"Error in API server: {e}")
202
+ traceback.print_exc()
203
 
204
  if __name__ == "__main__":
205
  port = int(os.environ.get("API_PORT", 8080))
206
+ run(port=port)
 
 
 
 
 
fallback.py CHANGED
@@ -6,6 +6,9 @@ import sys
6
  import time
7
  import shutil
8
  from pathlib import Path
 
 
 
9
 
10
  def create_user_directory():
11
  """Создает отдельную директорию для пользовательских файлов"""
@@ -29,8 +32,12 @@ def create_user_directory():
29
  go_cache_dir = Path("/tmp/go-cache")
30
  go_cache_dir.mkdir(exist_ok=True, parents=True)
31
 
 
 
 
 
32
  print(f"Created directory structure at {user_dir}")
33
- return user_dir, agents_dir, server_bin_dir, logs_dir, go_cache_dir
34
 
35
  def create_basic_files(agents_dir):
36
  """Создает базовые файлы конфигурации для TEN-Agent"""
@@ -137,54 +144,53 @@ def create_basic_files(agents_dir):
137
 
138
  print("Basic configuration files created successfully.")
139
 
140
- def copy_api_server(server_bin_dir):
141
- """Копирует предварительно скомпилированный API сервер"""
142
- api_bin = server_bin_dir / "api"
143
-
144
- # Приоритезируем API сервер из директории fallback
145
- fallback_bin = Path("/app/fallback/api")
146
- if fallback_bin.exists():
147
- print(f"Found pre-compiled API server at {fallback_bin}")
148
- shutil.copy(fallback_bin, api_bin)
149
- api_bin.chmod(0o755) # Делаем исполняемым
150
- print(f"API server binary copied to {api_bin}")
151
- return True
152
-
153
- # Ищем API сервер в основной директории
154
- original_bin = Path("/app/server/bin/api")
155
- if original_bin.exists():
156
- print(f"Found API server at {original_bin}")
157
- shutil.copy(original_bin, api_bin)
158
- api_bin.chmod(0o755) # Делаем исполняемым
159
- print(f"API server binary copied to {api_bin}")
160
- return True
161
-
162
- # Если не нашли готовый бинарник, пытаемся компилировать
163
  try:
164
- print("No pre-compiled API server found, trying to compile from source...")
165
- env = os.environ.copy()
166
- env["GOCACHE"] = "/tmp/go-cache" # Указываем директорию для кэша Go
167
- env["GOPATH"] = "/tmp/go-path" # Указываем пользовательский GOPATH
168
 
169
- # Создаем директорию для GOPATH
170
- Path("/tmp/go-path").mkdir(exist_ok=True, parents=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
172
- # Компилируем с пользовательскими настройками
173
- result = subprocess.run(
174
- "cd /app/server && go build -o /tmp/ten_user/server/bin/api main.go",
175
- shell=True,
176
- check=True,
177
- stdout=subprocess.PIPE,
178
- stderr=subprocess.PIPE,
179
- env=env
180
- )
181
- print(f"Successfully compiled API server: {result.stdout.decode()}")
182
- api_bin.chmod(0o755)
183
- return True
184
- except subprocess.CalledProcessError as e:
185
- print(f"Failed to compile API server: {e.stderr.decode()}")
186
- print("Critical error: No API server available!")
187
- return False
188
 
189
  def main():
190
  try:
@@ -197,8 +203,11 @@ def main():
197
  print(f"HOME: {os.environ.get('HOME', 'unset')}")
198
  print(f"PATH: {os.environ.get('PATH', 'unset')}")
199
 
 
 
 
200
  # Создаем пользовательские директории
201
- user_dir, agents_dir, server_bin_dir, logs_dir, go_cache_dir = create_user_directory()
202
 
203
  # Создаем пустой файл в директории логов, чтобы точно создать директорию
204
  (logs_dir / "server.log").touch()
@@ -207,98 +216,61 @@ def main():
207
  # Создаем базовые конфигурационные файлы
208
  create_basic_files(agents_dir)
209
 
210
- # Копируем API сервер
211
- if not copy_api_server(server_bin_dir):
212
- print("Critical error: Cannot prepare API server")
213
- sys.exit(1)
214
-
215
- # Проверяем, что API сервер действительно скопирован и исполняемый
216
- api_bin = server_bin_dir / "api"
217
- if not api_bin.exists():
218
- print(f"Critical error: API server binary not found at {api_bin}")
219
- sys.exit(1)
220
-
221
- try:
222
- api_bin.chmod(0o755) # Дополнительно проверяем права
223
- except Exception as e:
224
- print(f"Warning: Could not set execute permissions on API server binary: {e}")
225
- # Продолжаем, возможно, права уже установлены
226
-
227
- print(f"API server binary prepared successfully: {api_bin}")
228
- print(f"File exists: {api_bin.exists()}, size: {api_bin.stat().st_size} bytes")
229
-
230
- # Установка переменных среды
231
  os.environ["PORT"] = "7860" # HuggingFace использует порт 7860
232
  os.environ["AGENT_SERVER_URL"] = "http://localhost:8080"
233
  os.environ["NEXT_PUBLIC_EDIT_GRAPH_MODE"] = "true"
234
  os.environ["NEXT_PUBLIC_DISABLE_CAMERA"] = "true"
 
235
 
236
- # Путь к бинарнику API сервера
237
- api_bin_str = str(api_bin)
238
-
239
- # Запускаем API сервер с указанием пути к agents директории
240
  print(f"Starting API server with agents directory: {agents_dir}")
241
  api_env = os.environ.copy()
242
  api_env["TEN_AGENT_DIR"] = str(agents_dir)
243
- api_env["GOCACHE"] = str(go_cache_dir) # Устанавливаем переменную GOCACHE
244
-
245
- # Отключаем логирование в файл
246
- api_env["GF_LOG_MODE"] = "console" # Логирование только в консоль
247
- api_env["LOG_LEVEL"] = "error" # Минимальный уровень логирования
248
- api_env["TEN_LOG_DISABLE_FILE"] = "true" # Отключаем логирование в файл (кастомная переменная)
249
- api_env["GF_LOG_FILE_STAT"] = "false" # Отключаем статистику файлов логов
250
-
251
- # Выводим важные переменные окружения
252
- print(f"Environment variables:")
253
- print(f"TEN_AGENT_DIR: {api_env.get('TEN_AGENT_DIR')}")
254
- print(f"GF_LOG_MODE: {api_env.get('GF_LOG_MODE')}")
255
- print(f"LOG_LEVEL: {api_env.get('LOG_LEVEL')}")
256
- print(f"TEN_LOG_DISABLE_FILE: {api_env.get('TEN_LOG_DISABLE_FILE')}")
257
- print(f"GOCACHE: {api_env.get('GOCACHE')}")
258
 
259
- # Дополнительно проверяем права на исполнение через ls -la
260
- subprocess.run(["ls", "-la", api_bin_str], check=True)
261
-
262
- # Проверяем директорию логов
263
- subprocess.run(["ls", "-la", str(logs_dir)], check=True)
264
-
265
- # Запускаем API сервер с передачей аргумента для отключения файлового логирования
266
- print(f"Executing API server: {api_bin_str}")
267
- try:
268
- api_process = subprocess.Popen(
269
- [api_bin_str, "--log_to_stdout", "--disable_file_logging"],
270
- env=api_env,
271
- stdout=subprocess.PIPE,
272
- stderr=subprocess.PIPE
273
- )
274
- except Exception as e:
275
- print(f"Failed to start API server: {e}")
276
  sys.exit(1)
 
 
 
277
 
278
- # Даем серверу время для запуска и выводим любые ошибки сразу
 
 
 
 
 
 
 
 
 
279
  time.sleep(2)
280
 
281
  # Проверяем, запустился ли сервер
282
  if api_process.poll() is not None:
283
  print("API server failed to start!")
284
  stdout, stderr = api_process.communicate()
285
- print(f"STDOUT: {stdout.decode()}")
286
- print(f"STDERR: {stderr.decode()}")
287
  sys.exit(1)
288
 
289
  # Проверяем доступность API
290
  print("Testing API server availability...")
291
- try:
292
- import urllib.request
293
- response = urllib.request.urlopen("http://localhost:8080/graphs")
294
- print(f"API server is responding! Response: {response.read().decode()}")
295
- except Exception as e:
296
- print(f"API server is not responding yet, but continuing... ({e})")
297
-
298
- print("API server started successfully")
299
 
 
 
 
300
  # Запускаем playground
301
  print("Starting Playground UI...")
 
 
 
 
 
302
  playground_process = subprocess.Popen(
303
  "cd /app/playground && pnpm dev",
304
  env=os.environ,
@@ -314,8 +286,8 @@ def main():
314
  if playground_process.poll() is not None:
315
  print("Playground UI failed to start!")
316
  stdout, stderr = playground_process.communicate()
317
- print(f"STDOUT: {stdout.decode()}")
318
- print(f"STDERR: {stderr.decode()}")
319
 
320
  # Останавливаем API сервер
321
  api_process.terminate()
@@ -358,8 +330,9 @@ def main():
358
 
359
  except Exception as e:
360
  print(f"Error: {e}")
 
 
361
  sys.exit(1)
362
 
363
  if __name__ == "__main__":
364
- import threading
365
  main()
 
6
  import time
7
  import shutil
8
  from pathlib import Path
9
+ import threading
10
+ import urllib.request
11
+ import urllib.error
12
 
13
  def create_user_directory():
14
  """Создает отдельную директорию для пользовательских файлов"""
 
32
  go_cache_dir = Path("/tmp/go-cache")
33
  go_cache_dir.mkdir(exist_ok=True, parents=True)
34
 
35
+ # Создаем директорию для RAG данных
36
+ rag_dir = user_dir / "rag_data"
37
+ rag_dir.mkdir(exist_ok=True, parents=True)
38
+
39
  print(f"Created directory structure at {user_dir}")
40
+ return user_dir, agents_dir, server_bin_dir, logs_dir, go_cache_dir, rag_dir
41
 
42
  def create_basic_files(agents_dir):
43
  """Создает базовые файлы конфигурации для TEN-Agent"""
 
144
 
145
  print("Basic configuration files created successfully.")
146
 
147
+ def check_file_permissions(filepath):
148
+ """Проверяет и выводит права доступа для файла"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  try:
150
+ print(f"Checking permissions for {filepath}")
151
+ if not Path(filepath).exists():
152
+ print(f" - File does not exist!")
153
+ return
154
 
155
+ # Получаем права доступа и информацию о файле
156
+ result = subprocess.run(["ls", "-la", filepath], capture_output=True, text=True)
157
+ if result.returncode == 0:
158
+ print(f" - {result.stdout.strip()}")
159
+ else:
160
+ print(f" - Error: {result.stderr.strip()}")
161
+
162
+ # Проверяем, можем ли писать в файл
163
+ try:
164
+ with open(filepath, "a") as f:
165
+ pass
166
+ print(" - Can write: Yes")
167
+ except PermissionError:
168
+ print(" - Can write: No (Permission denied)")
169
+ except Exception as e:
170
+ print(f" - Can write: No ({e})")
171
+ except Exception as e:
172
+ print(f"Error checking permissions: {e}")
173
+
174
+ def test_api_connection(max_attempts=5):
175
+ """Проверяет, доступен ли API сервер"""
176
+ print("\nTesting API server connection...")
177
+ for attempt in range(max_attempts):
178
+ try:
179
+ with urllib.request.urlopen("http://localhost:8080/health") as response:
180
+ if response.status == 200:
181
+ print(f"✅ API server is working! Response: {response.read().decode()}")
182
+ return True
183
+ else:
184
+ print(f"❌ API server responded with status {response.status}")
185
+ except Exception as e:
186
+ print(f"❌ Attempt {attempt+1}/{max_attempts}: API server connection failed: {e}")
187
 
188
+ if attempt < max_attempts - 1:
189
+ print(f"Waiting 2 seconds before next attempt...")
190
+ time.sleep(2)
191
+
192
+ print("Could not connect to API server after multiple attempts")
193
+ return False
 
 
 
 
 
 
 
 
 
 
194
 
195
  def main():
196
  try:
 
203
  print(f"HOME: {os.environ.get('HOME', 'unset')}")
204
  print(f"PATH: {os.environ.get('PATH', 'unset')}")
205
 
206
+ # Проверяем наличие /tmp и права на него
207
+ check_file_permissions("/tmp")
208
+
209
  # Создаем пользовательские директории
210
+ user_dir, agents_dir, server_bin_dir, logs_dir, go_cache_dir, rag_dir = create_user_directory()
211
 
212
  # Создаем пустой файл в директории логов, чтобы точно создать директорию
213
  (logs_dir / "server.log").touch()
 
216
  # Создаем базовые конфигурационные файлы
217
  create_basic_files(agents_dir)
218
 
219
+ # Установка переменных среды для Playground
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  os.environ["PORT"] = "7860" # HuggingFace использует порт 7860
221
  os.environ["AGENT_SERVER_URL"] = "http://localhost:8080"
222
  os.environ["NEXT_PUBLIC_EDIT_GRAPH_MODE"] = "true"
223
  os.environ["NEXT_PUBLIC_DISABLE_CAMERA"] = "true"
224
+ os.environ["TEN_AGENT_DIR"] = str(agents_dir)
225
 
226
+ # Запускаем API сервер с использованием нашей обертки
 
 
 
227
  print(f"Starting API server with agents directory: {agents_dir}")
228
  api_env = os.environ.copy()
229
  api_env["TEN_AGENT_DIR"] = str(agents_dir)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
 
231
+ # Проверяем наличие API wrapper
232
+ wrapper_path = Path("/app/api_wrapper.py")
233
+ if not wrapper_path.exists():
234
+ print(f"Error: API wrapper not found at {wrapper_path}")
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  sys.exit(1)
236
+
237
+ # Убедимся, что у скрипта есть права на исполнение
238
+ wrapper_path.chmod(0o755)
239
 
240
+ # Запускаем API обертку
241
+ print(f"Using Python API wrapper instead of original server")
242
+ api_process = subprocess.Popen(
243
+ ["python3", str(wrapper_path)],
244
+ env=api_env,
245
+ stdout=subprocess.PIPE,
246
+ stderr=subprocess.PIPE
247
+ )
248
+
249
+ # Даем серверу время для запуска
250
  time.sleep(2)
251
 
252
  # Проверяем, запустился ли сервер
253
  if api_process.poll() is not None:
254
  print("API server failed to start!")
255
  stdout, stderr = api_process.communicate()
256
+ print(f"STDOUT: {stdout.decode() if stdout else 'No output'}")
257
+ print(f"STDERR: {stderr.decode() if stderr else 'No error output'}")
258
  sys.exit(1)
259
 
260
  # Проверяем доступность API
261
  print("Testing API server availability...")
262
+ api_success = test_api_connection()
 
 
 
 
 
 
 
263
 
264
+ if not api_success:
265
+ print("WARNING: API server may not be working correctly!")
266
+
267
  # Запускаем playground
268
  print("Starting Playground UI...")
269
+ playground_path = Path("/app/playground")
270
+ if not playground_path.exists():
271
+ print(f"Error: Playground directory not found at {playground_path}")
272
+ sys.exit(1)
273
+
274
  playground_process = subprocess.Popen(
275
  "cd /app/playground && pnpm dev",
276
  env=os.environ,
 
286
  if playground_process.poll() is not None:
287
  print("Playground UI failed to start!")
288
  stdout, stderr = playground_process.communicate()
289
+ print(f"STDOUT: {stdout.decode() if stdout else 'No output'}")
290
+ print(f"STDERR: {stderr.decode() if stderr else 'No error output'}")
291
 
292
  # Останавливаем API сервер
293
  api_process.terminate()
 
330
 
331
  except Exception as e:
332
  print(f"Error: {e}")
333
+ import traceback
334
+ traceback.print_exc()
335
  sys.exit(1)
336
 
337
  if __name__ == "__main__":
 
338
  main()
start.sh CHANGED
@@ -1,67 +1,86 @@
1
  #!/bin/bash
2
 
3
- echo "===== Starting TEN-Agent in Python Mode ====="
 
4
  echo "$(date)"
5
  echo "Current directory: $(pwd)"
6
 
7
- # Активируем виртуальную среду Python, если она существует
8
- if [ -d "/app/venv" ]; then
9
- echo "Activating Python virtual environment..."
10
- source /app/venv/bin/activate
11
- PYTHON_CMD="python"
 
 
 
 
 
 
 
 
 
 
 
 
12
  else
13
- echo "No virtual environment found, using system Python..."
14
- PYTHON_CMD="python3"
15
  fi
16
 
17
- # Создаем необходимые директории без изменения прав
18
- echo "Creating temporary directories in /tmp..."
 
19
  mkdir -p /tmp/ten_user/agents
20
  mkdir -p /tmp/ten_user/logs
21
- mkdir -p /tmp/ten_playground
 
22
 
23
- # Проверяем, что директории созданы
24
- echo "Checking directories..."
25
- if [ -d "/tmp/ten_user" ]; then
26
- echo "✅ /tmp/ten_user exists"
 
 
 
 
 
 
27
  fi
28
 
29
- # Проверяем наличие файлов
30
- echo "Checking necessary files..."
31
- if [ -f "api_wrapper.py" ]; then
32
- echo "✅ api_wrapper.py found"
33
  else
34
- echo "❌ api_wrapper.py missing!"
35
- exit 1
36
  fi
37
 
38
- if [ -f "app.py" ]; then
39
- echo "✅ app.py found"
40
  else
41
- echo "❌ app.py missing!"
42
- exit 1
43
  fi
44
 
45
- # Убеждаемся, что fallback.py не будет использован
46
- if [ -f "fallback.py" ]; then
47
- echo "⚠️ Renaming fallback.py to fallback.py.bak to prevent conflicts"
48
- mv fallback.py fallback.py.bak
 
49
  fi
50
 
51
- # Выводим информацию об окружении
52
- echo "===== Environment Information ====="
53
- echo "User: $(whoami || echo 'Unknown')"
54
- echo "Home directory: $HOME"
55
- echo "Python version: $($PYTHON_CMD --version)"
56
- echo "Node version: $(node --version)"
57
- echo "Using Python command: $PYTHON_CMD"
58
 
59
- # Запускаем прокси-сервер в фоновом режиме
60
- echo "Starting proxy server..."
61
- $PYTHON_CMD proxy.py &
62
- PROXY_PID=$!
63
- echo "Proxy server started with PID: $PROXY_PID"
 
 
 
 
64
 
65
- # Запускаем приложение через Python-обертку
66
- echo "Starting TEN-Agent via Python wrapper (app.py)..."
67
- exec $PYTHON_CMD app.py
 
1
  #!/bin/bash
2
 
3
+ # Вывод информации о запуске
4
+ echo "===== Starting TEN-Agent on HuggingFace Space ====="
5
  echo "$(date)"
6
  echo "Current directory: $(pwd)"
7
 
8
+ # Вывод информации о пользователе и его правах
9
+ echo "===== Environment Information ====="
10
+ echo "User: $(whoami)"
11
+ echo "Groups: $(groups)"
12
+ echo "Home directory: $HOME"
13
+
14
+ # Checking directory permissions
15
+ echo "===== Checking Directory Permissions ====="
16
+ echo "Temp directory permissions:"
17
+ ls -la /tmp
18
+ echo "App directory permissions:"
19
+ ls -la /app
20
+
21
+ # Проверяем наличие .env файла
22
+ if [ -f .env ]; then
23
+ echo "✅ .env file found"
24
+ cat .env | grep -v "KEY\|CERTIFICATE\|PASSWORD\|SECRET" | sed 's/=.*/=***/'
25
  else
26
+ echo "⚠️ Warning: .env file not found, will use environment variables"
 
27
  fi
28
 
29
+ # Создаем директории, которые могут понадобиться
30
+ echo "===== Creating required directories ====="
31
+ mkdir -p /tmp/ten_user
32
  mkdir -p /tmp/ten_user/agents
33
  mkdir -p /tmp/ten_user/logs
34
+ mkdir -p /tmp/ten_user/rag_data
35
+ chmod -R 755 /tmp/ten_user
36
 
37
+ # Проверяем, создаются ли файлы в /tmp
38
+ echo "===== Testing file creation in /tmp ====="
39
+ TEST_FILE="/tmp/test_write_$(date +%s).txt"
40
+ if touch $TEST_FILE; then
41
+ echo "✅ Can create files in /tmp"
42
+ echo "Test content" > $TEST_FILE
43
+ cat $TEST_FILE
44
+ rm $TEST_FILE
45
+ else
46
+ echo "❌ Cannot create files in /tmp - this will cause problems!"
47
  fi
48
 
49
+ # Проверяем наличие необходимых компонентов
50
+ echo "===== Checking required components ====="
51
+ if [ -f /app/fallback.py ]; then
52
+ echo "✅ Fallback script found"
53
  else
54
+ echo "❌ Fallback script missing!"
 
55
  fi
56
 
57
+ if [ -f /app/api_wrapper.py ]; then
58
+ echo "✅ API wrapper found"
59
  else
60
+ echo "❌ API wrapper missing!"
 
61
  fi
62
 
63
+ if [ -d /app/playground ]; then
64
+ echo "✅ Playground directory found"
65
+ ls -la /app/playground
66
+ else
67
+ echo "❌ Playground directory missing!"
68
  fi
69
 
70
+ # Запускаем приложение через fallback скрипт
71
+ echo "===== Starting TEN-Agent via fallback script ====="
72
+ echo "Due to permission issues in Hugging Face Space, we'll use the fallback script"
73
+ echo "This will create necessary files in /tmp where we have write access"
 
 
 
74
 
75
+ # Установка переменных окружения для совместимости
76
+ export HF_SPACE=true
77
+ export INTERFACE_PORT=7860
78
+ export API_PORT=8080
79
+ export TEN_AGENT_DIR=/tmp/ten_user/agents
80
+ export AGENT_SERVER_URL=http://localhost:8080
81
+ export NEXT_PUBLIC_EDIT_GRAPH_MODE=true
82
+ export NEXT_PUBLIC_DISABLE_CAMERA=true
83
+ export PYTHONUNBUFFERED=1
84
 
85
+ # Выполняем Python скрипт напрямую
86
+ exec python3 /app/fallback.py