3v324v23 commited on
Commit
20ad26e
·
1 Parent(s): 50c3ed9

Полностью переработан деплой для обхода ограничений прав доступа на HuggingFace Space

Browse files
Files changed (3) hide show
  1. Dockerfile +12 -23
  2. fallback.py +156 -28
  3. start.sh +13 -68
Dockerfile CHANGED
@@ -28,12 +28,11 @@ RUN wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz && \
28
  tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz && \
29
  rm go1.21.0.linux-amd64.tar.gz
30
 
31
- # Установка Task
32
  ENV PATH=$PATH:/usr/local/go/bin
33
  ENV GOPATH=/go
34
  ENV PATH=$PATH:$GOPATH/bin
35
  RUN mkdir -p /go && chmod 777 /go
36
- RUN go install github.com/go-task/task/v3/cmd/task@latest
37
 
38
  # Установка Node.js и pnpm
39
  RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
@@ -44,34 +43,24 @@ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
44
  WORKDIR /app
45
  RUN git clone --depth 1 https://github.com/TEN-framework/TEN-Agent.git /app
46
 
47
- # Создание .env файла из окружения Hugging Face Space
48
- RUN echo "\
49
- AGORA_APP_ID=${AGORA_APP_ID}\n\
50
- AGORA_APP_CERTIFICATE=${AGORA_APP_CERTIFICATE}\n\
51
- AZURE_STT_KEY=${AZURE_STT_KEY}\n\
52
- AZURE_STT_REGION=${AZURE_STT_REGION}\n\
53
- AZURE_TTS_KEY=${AZURE_TTS_KEY}\n\
54
- AZURE_TTS_REGION=${AZURE_TTS_REGION}\n\
55
- OPENAI_API_KEY=${OPENAI_API_KEY}\n\
56
- " > /app/.env
57
 
58
- # Установка правильных прав доступа для директорий и файлов
59
- RUN mkdir -p /app/agents && \
60
- chmod -R 777 /app/agents && \
61
- chmod -R 777 /app && \
62
- mkdir -p /tmp/ten_agent && \
63
- chmod -R 777 /tmp/ten_agent
64
 
65
- # Создаем необходимые директории для установки сервера
66
- RUN mkdir -p /app/server/bin && chmod -R 777 /app/server/bin
 
67
 
68
  # Копируем стартовые скрипты
69
  COPY start.sh /app/start.sh
70
  COPY fallback.py /app/fallback.py
71
  RUN chmod +x /app/start.sh /app/fallback.py
72
 
73
- # Открываем порты (7860 для HF Space, 8080 для API, 49483 для дизайнера)
74
- EXPOSE 7860 8080 49483 3000 3001 3002
75
 
76
- # Запускаем TEN-Agent через официальный стартовый скрипт
77
  CMD ["/app/start.sh"]
 
28
  tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz && \
29
  rm go1.21.0.linux-amd64.tar.gz
30
 
31
+ # Настройка окружения Go
32
  ENV PATH=$PATH:/usr/local/go/bin
33
  ENV GOPATH=/go
34
  ENV PATH=$PATH:$GOPATH/bin
35
  RUN mkdir -p /go && chmod 777 /go
 
36
 
37
  # Установка Node.js и pnpm
38
  RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
 
43
  WORKDIR /app
44
  RUN git clone --depth 1 https://github.com/TEN-framework/TEN-Agent.git /app
45
 
46
+ # Создание пользовательской директории для временных файлов
47
+ RUN mkdir -p /tmp/ten_user && chmod 777 /tmp/ten_user
 
 
 
 
 
 
 
 
48
 
49
+ # Создание .env файла из окружения Hugging Face Space
50
+ # Используем простой формат без пробелов для предотвращения ошибок
51
+ RUN echo "AGORA_APP_ID=${AGORA_APP_ID}\nAGORA_APP_CERTIFICATE=${AGORA_APP_CERTIFICATE}\nAZURE_STT_KEY=${AZURE_STT_KEY}\nAZURE_STT_REGION=${AZURE_STT_REGION}\nAZURE_TTS_KEY=${AZURE_TTS_KEY}\nAZURE_TTS_REGION=${AZURE_TTS_REGION}\nOPENAI_API_KEY=${OPENAI_API_KEY}" > /app/.env
 
 
 
52
 
53
+ # Предварительная установка зависимостей для playground
54
+ # Делаем это отдельно, чтобы не пересобирать при каждом изменении
55
+ RUN cd /app/playground && pnpm install
56
 
57
  # Копируем стартовые скрипты
58
  COPY start.sh /app/start.sh
59
  COPY fallback.py /app/fallback.py
60
  RUN chmod +x /app/start.sh /app/fallback.py
61
 
62
+ # Открываем порты (7860 для HF Space, 8080 для API)
63
+ EXPOSE 7860 8080
64
 
65
+ # Запускаем TEN-Agent через fallback скрипт
66
  CMD ["/app/start.sh"]
fallback.py CHANGED
@@ -1,20 +1,33 @@
1
  #!/usr/bin/env python3
2
  import os
3
  import json
4
- import shutil
5
  import subprocess
6
  import sys
7
  import time
 
8
  from pathlib import Path
9
 
10
- def create_basic_files():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  """Создает базовые файлы конфигурации для TEN-Agent"""
12
  print("Creating basic configuration files...")
13
 
14
- # Создаем директории
15
- agents_dir = Path("/app/agents")
16
- agents_dir.mkdir(exist_ok=True)
17
-
18
  # Создаем manifest.json
19
  manifest = {
20
  "_ten": {"version": "0.0.1"},
@@ -108,7 +121,7 @@ def create_basic_files():
108
  json.dump(voice_agent, f, indent=2)
109
 
110
  # Создаем chat_agent.json (аналогичный voice_agent.json)
111
- chat_agent = voice_agent.copy()
112
  chat_agent["nodes"][1]["data"]["properties"]["system_prompt"] = "You are a helpful chat assistant."
113
 
114
  with open(agents_dir / "chat_agent.json", "w") as f:
@@ -116,46 +129,161 @@ def create_basic_files():
116
 
117
  print("Basic configuration files created successfully.")
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  def main():
120
  try:
121
- # Устанавливаем права доступа
122
- subprocess.run(["chmod", "-R", "777", "/app"], check=True)
123
- subprocess.run(["chmod", "-R", "777", "/app/agents"], check=True)
124
 
125
- # Создаем базовые файлы
126
- create_basic_files()
 
 
127
 
128
- # Проверяем, скомпилирован ли API сервер
129
- server_binary = Path("/app/server/bin/api")
130
- if not server_binary.exists():
131
- print("Compiling API server...")
132
- subprocess.run(["cd", "/app/server", "&&", "go", "build", "-o", "bin/api", "main.go"], check=True)
133
- subprocess.run(["chmod", "+x", "/app/server/bin/api"], check=True)
134
 
135
- # Запускаем API сервер
136
- api_process = subprocess.Popen(["/app/server/bin/api"])
137
 
138
- # Запускаем playground
139
- os.environ["PORT"] = "7860"
 
 
 
 
 
140
  os.environ["AGENT_SERVER_URL"] = "http://localhost:8080"
141
  os.environ["NEXT_PUBLIC_EDIT_GRAPH_MODE"] = "true"
142
  os.environ["NEXT_PUBLIC_DISABLE_CAMERA"] = "true"
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  playground_process = subprocess.Popen(
145
- ["cd", "/app/playground", "&&", "pnpm", "dev"],
146
  env=os.environ,
147
- shell=True
 
 
148
  )
149
 
150
- print("TEN-Agent started successfully.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
- # Ожидаем завершения процессов
153
- api_process.wait()
154
- playground_process.wait()
 
 
 
 
 
 
 
 
 
 
155
 
156
  except Exception as e:
157
  print(f"Error: {e}")
158
  sys.exit(1)
159
 
160
  if __name__ == "__main__":
 
161
  main()
 
1
  #!/usr/bin/env python3
2
  import os
3
  import json
 
4
  import subprocess
5
  import sys
6
  import time
7
+ import shutil
8
  from pathlib import Path
9
 
10
+ def create_user_directory():
11
+ """Создает отдельную директорию для пользовательских файлов"""
12
+ print("Creating user directory...")
13
+
14
+ # Создаем пользовательскую директорию
15
+ user_dir = Path("/tmp/ten_user")
16
+ user_dir.mkdir(exist_ok=True, parents=True)
17
+
18
+ # Создаем структуру директорий
19
+ agents_dir = user_dir / "agents"
20
+ agents_dir.mkdir(exist_ok=True, parents=True)
21
+ server_bin_dir = user_dir / "server" / "bin"
22
+ server_bin_dir.mkdir(exist_ok=True, parents=True)
23
+
24
+ print(f"Created directory structure at {user_dir}")
25
+ return user_dir, agents_dir, server_bin_dir
26
+
27
+ def create_basic_files(agents_dir):
28
  """Создает базовые файлы конфигурации для TEN-Agent"""
29
  print("Creating basic configuration files...")
30
 
 
 
 
 
31
  # Создаем manifest.json
32
  manifest = {
33
  "_ten": {"version": "0.0.1"},
 
121
  json.dump(voice_agent, f, indent=2)
122
 
123
  # Создаем chat_agent.json (аналогичный voice_agent.json)
124
+ chat_agent = dict(voice_agent)
125
  chat_agent["nodes"][1]["data"]["properties"]["system_prompt"] = "You are a helpful chat assistant."
126
 
127
  with open(agents_dir / "chat_agent.json", "w") as f:
 
129
 
130
  print("Basic configuration files created successfully.")
131
 
132
+ def check_api_server(server_bin_dir):
133
+ """Проверяет наличие API сервера и компилирует его при необходимости"""
134
+ api_bin = server_bin_dir / "api"
135
+
136
+ if not api_bin.exists():
137
+ print("Copying API server binary...")
138
+ # Проверяем наличие уже скомпилированного сервера в основном репозитории
139
+ original_bin = Path("/app/server/bin/api")
140
+ if original_bin.exists():
141
+ # Копируем бинарник из основного репозитория
142
+ shutil.copy(original_bin, api_bin)
143
+ api_bin.chmod(0o755) # Делаем исполняемым
144
+ print(f"API server binary copied to {api_bin}")
145
+ else:
146
+ print("Compiling API server from source...")
147
+ try:
148
+ # Компилируем сервер
149
+ result = subprocess.run(
150
+ "cd /app/server && go build -o /tmp/ten_user/server/bin/api main.go",
151
+ shell=True,
152
+ check=True,
153
+ stdout=subprocess.PIPE,
154
+ stderr=subprocess.PIPE
155
+ )
156
+ print(f"API server compiled successfully: {result.stdout.decode()}")
157
+ # Делаем исполняемым
158
+ api_bin.chmod(0o755)
159
+ except subprocess.CalledProcessError as e:
160
+ print(f"Failed to compile API server: {e.stderr.decode()}")
161
+ # Как последний вариант, используем предварительно скомпилированный бинарник
162
+ fallback_bin = Path("/app/fallback/api")
163
+ if fallback_bin.exists():
164
+ shutil.copy(fallback_bin, api_bin)
165
+ api_bin.chmod(0o755)
166
+ print(f"Using pre-compiled fallback API server binary")
167
+ else:
168
+ print("No API server binary available! Cannot continue.")
169
+ return False
170
+
171
+ return True
172
+
173
  def main():
174
  try:
175
+ print(f"Starting TEN-Agent in fallback mode...")
176
+ print(f"Current directory: {os.getcwd()}")
 
177
 
178
+ # Выводим информацию о среде
179
+ user = os.environ.get('USER', 'unknown')
180
+ print(f"Current user: {user}")
181
+ print(f"HOME: {os.environ.get('HOME', 'unset')}")
182
 
183
+ # Создаем пользовательские директории
184
+ user_dir, agents_dir, server_bin_dir = create_user_directory()
 
 
 
 
185
 
186
+ # Создаем базовые конфигурационные файлы
187
+ create_basic_files(agents_dir)
188
 
189
+ # Проверяем API сервер
190
+ if not check_api_server(server_bin_dir):
191
+ print("Critical error: Cannot prepare API server")
192
+ sys.exit(1)
193
+
194
+ # Установка переменных среды
195
+ os.environ["PORT"] = "7860" # HuggingFace использует порт 7860
196
  os.environ["AGENT_SERVER_URL"] = "http://localhost:8080"
197
  os.environ["NEXT_PUBLIC_EDIT_GRAPH_MODE"] = "true"
198
  os.environ["NEXT_PUBLIC_DISABLE_CAMERA"] = "true"
199
 
200
+ # Путь к бинарнику API сервера
201
+ api_bin = str(server_bin_dir / "api")
202
+
203
+ # Запускаем API сервер с указанием пути к agents директории
204
+ print(f"Starting API server with agents directory: {agents_dir}")
205
+ api_env = os.environ.copy()
206
+ api_env["TEN_AGENT_DIR"] = str(agents_dir)
207
+
208
+ api_process = subprocess.Popen(
209
+ [api_bin],
210
+ env=api_env,
211
+ stdout=subprocess.PIPE,
212
+ stderr=subprocess.PIPE
213
+ )
214
+
215
+ # Даем серверу время для запуска
216
+ time.sleep(5)
217
+
218
+ # Проверяем, запустился ли сервер
219
+ if api_process.poll() is not None:
220
+ print("API server failed to start!")
221
+ stdout, stderr = api_process.communicate()
222
+ print(f"STDOUT: {stdout.decode()}")
223
+ print(f"STDERR: {stderr.decode()}")
224
+ sys.exit(1)
225
+
226
+ print("API server started successfully")
227
+
228
+ # Запускаем playground
229
+ print("Starting Playground UI...")
230
  playground_process = subprocess.Popen(
231
+ "cd /app/playground && pnpm dev",
232
  env=os.environ,
233
+ shell=True,
234
+ stdout=subprocess.PIPE,
235
+ stderr=subprocess.PIPE
236
  )
237
 
238
+ # Даем UI время для запуска
239
+ time.sleep(5)
240
+
241
+ # Проверяем, запустился ли UI
242
+ if playground_process.poll() is not None:
243
+ print("Playground UI failed to start!")
244
+ stdout, stderr = playground_process.communicate()
245
+ print(f"STDOUT: {stdout.decode()}")
246
+ print(f"STDERR: {stderr.decode()}")
247
+
248
+ # Останавливаем API сервер
249
+ api_process.terminate()
250
+ sys.exit(1)
251
+
252
+ print("TEN-Agent started successfully in fallback mode.")
253
+ print("Playground UI is available at http://localhost:7860")
254
+
255
+ # Следим за выводом процессов в реальном времени
256
+ def stream_output(process, name):
257
+ for line in iter(process.stdout.readline, b''):
258
+ print(f"[{name}] {line.decode().strip()}")
259
+
260
+ api_thread = threading.Thread(target=stream_output, args=(api_process, "API"))
261
+ ui_thread = threading.Thread(target=stream_output, args=(playground_process, "UI"))
262
+
263
+ api_thread.daemon = True
264
+ ui_thread.daemon = True
265
+
266
+ api_thread.start()
267
+ ui_thread.start()
268
 
269
+ # Ожидаем завершения любого из процессов
270
+ while True:
271
+ if api_process.poll() is not None:
272
+ print("API server has stopped.")
273
+ playground_process.terminate()
274
+ break
275
+
276
+ if playground_process.poll() is not None:
277
+ print("Playground UI has stopped.")
278
+ api_process.terminate()
279
+ break
280
+
281
+ time.sleep(1)
282
 
283
  except Exception as e:
284
  print(f"Error: {e}")
285
  sys.exit(1)
286
 
287
  if __name__ == "__main__":
288
+ import threading
289
  main()
start.sh CHANGED
@@ -1,83 +1,28 @@
1
  #!/bin/bash
2
- set -e
3
 
4
  # Вывод информации о запуске
5
  echo "===== Starting TEN-Agent on HuggingFace Space ====="
6
  echo "$(date)"
7
  echo "Current directory: $(pwd)"
8
 
 
 
 
 
 
 
9
  # Проверяем наличие .env файла
10
  if [ -f .env ]; then
11
  echo "✅ .env file found"
12
  cat .env | grep -v "KEY\|CERTIFICATE" | sed 's/=.*/=***/'
13
  else
14
- echo " Error: .env file not found"
15
- exit 1
16
- fi
17
-
18
- # Проверяем установку task
19
- if command -v task &> /dev/null; then
20
- echo "✅ task command is available"
21
- task --version
22
- else
23
- echo "❌ Error: task command not found"
24
- exit 1
25
  fi
26
 
27
- # Проверяем права доступа и структуру директорий
28
- echo "===== Checking directory permissions ====="
29
- mkdir -p /app/agents
30
- mkdir -p /tmp/ten_agent
31
- chmod -R 777 /app/agents
32
- chmod -R 777 /app
33
- chmod -R 777 /tmp/ten_agent
34
-
35
- echo "Directory permissions:"
36
- ls -la /app/agents
37
- ls -la /app
38
- ls -la /tmp/ten_agent
39
 
40
- # Проверяем наличие директории examples
41
- if [ -d "/app/agents/examples" ]; then
42
- echo "✅ Examples directory found"
43
- ls -la /app/agents/examples
44
- else
45
- echo "❌ Error: Examples directory not found"
46
- # Создаем базовую структуру
47
- mkdir -p /app/agents/examples/default
48
- echo "Created directory structure"
49
- fi
50
-
51
- # Запускаем сборку агента с официальной командой
52
- echo "===== Building TEN-Agent ====="
53
- if task use; then
54
- echo "✅ task use успешно выполнена"
55
-
56
- # Обновляем порт для HuggingFace Space (HF использует порт 7860)
57
- echo "===== Setting up port for HuggingFace Space ====="
58
- export PORT=7860
59
-
60
- # Отключаем запрос на использование камеры для HuggingFace Space
61
- export NEXT_PUBLIC_DISABLE_CAMERA=true
62
-
63
- # Запускаем TEN-Agent с официальной командой
64
- echo "===== Starting TEN-Agent server ====="
65
- exec task run
66
- else
67
- echo "⚠️ Warning: task use failed, trying alternative method..."
68
-
69
- # Альтернативный метод настройки агента без использования символических ссылок
70
- mkdir -p /app/agents/examples/default
71
- cp -r /app/agents/examples/default/* /app/agents/ 2>/dev/null || true
72
-
73
- echo "Manual setup completed, trying to run task run..."
74
-
75
- if task run; then
76
- echo "✅ task run успешно выполнена"
77
- exit 0
78
- else
79
- echo "⚠️ Warning: все методы запуска через task не удались, запускаем fallback..."
80
- chmod +x /app/fallback.py
81
- exec python3 /app/fallback.py
82
- fi
83
- fi
 
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
  # Проверяем наличие .env файла
15
  if [ -f .env ]; then
16
  echo "✅ .env file found"
17
  cat .env | grep -v "KEY\|CERTIFICATE" | sed 's/=.*/=***/'
18
  else
19
+ echo "⚠️ Warning: .env file not found, will use environment variables"
 
 
 
 
 
 
 
 
 
 
20
  fi
21
 
22
+ # Запускаем приложение напрямую через fallback скрипт
23
+ echo "===== Starting TEN-Agent via fallback script ====="
24
+ echo "Due to permission issues in Hugging Face Space, we'll use the fallback script"
25
+ echo "This will create necessary files in /tmp where we have write access"
 
 
 
 
 
 
 
 
26
 
27
+ # Выполняем Python скрипт напрямую
28
+ exec python3 /app/fallback.py