feat: 更新服务地址为 192.168.1.9,修改相关配置以支持局域网访问
This commit is contained in:
+1
-1
@@ -55,6 +55,6 @@ VOLUME ["/app/backend/media", "/app/backend/knowledge", "/app/backend/data.json"
|
|||||||
EXPOSE 10085 8765
|
EXPOSE 10085 8765
|
||||||
|
|
||||||
HEALTHCHECK --interval=15s --timeout=5s --start-period=30s --retries=5 \
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=30s --retries=5 \
|
||||||
CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:10085/api/health', timeout=4).status==200 else 1)" || exit 1
|
CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://192.168.1.9:10085/api/health', timeout=4).status==200 else 1)" || exit 1
|
||||||
|
|
||||||
CMD ["python", "docker_entry.py"]
|
CMD ["python", "docker_entry.py"]
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ export DPM_S2S_ENABLED=1 # 实时语音对话开关
|
|||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
|
|
||||||
# 3) 验证
|
# 3) 验证
|
||||||
curl http://127.0.0.1:10085/api/health # {"ok":true,...}
|
curl http://192.168.1.9:10085/api/health # {"ok":true,...}
|
||||||
docker compose logs -f backend
|
docker compose logs -f backend
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class Settings:
|
|||||||
|
|
||||||
# ---- MQTT(优先使用 .env 中的局域网 Broker 配置) ----
|
# ---- MQTT(优先使用 .env 中的局域网 Broker 配置) ----
|
||||||
MQTT_ENABLED = _env("DPM_MQTT_ENABLED", "1") == "1"
|
MQTT_ENABLED = _env("DPM_MQTT_ENABLED", "1") == "1"
|
||||||
MQTT_HOST = _env("DPM_MQTT_HOST", _env("MQTT_BROKER_HOST", "127.0.0.1"))
|
MQTT_HOST = _env("DPM_MQTT_HOST", _env("MQTT_BROKER_HOST", "192.168.1.9"))
|
||||||
MQTT_PORT = int(_env("DPM_MQTT_PORT", _env("MQTT_BROKER_PORT", "1883")))
|
MQTT_PORT = int(_env("DPM_MQTT_PORT", _env("MQTT_BROKER_PORT", "1883")))
|
||||||
MQTT_USERNAME = _env("DPM_MQTT_USERNAME", _env("MQTT_USERNAME", "")) or None
|
MQTT_USERNAME = _env("DPM_MQTT_USERNAME", _env("MQTT_USERNAME", "")) or None
|
||||||
MQTT_PASSWORD = _env("DPM_MQTT_PASSWORD", _env("MQTT_PASSWORD", "")) or None
|
MQTT_PASSWORD = _env("DPM_MQTT_PASSWORD", _env("MQTT_PASSWORD", "")) or None
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ async def runtime_config():
|
|||||||
"""
|
"""
|
||||||
ws = settings.MQTT_WS_URL
|
ws = settings.MQTT_WS_URL
|
||||||
# 从 ws://host:port/mqtt 中提取 broker 主机
|
# 从 ws://host:port/mqtt 中提取 broker 主机
|
||||||
host = "127.0.0.1"
|
host = "192.168.1.9"
|
||||||
try:
|
try:
|
||||||
host = ws.split("://", 1)[1].split(":", 1)[0]
|
host = ws.split("://", 1)[1].split(":", 1)[0]
|
||||||
except Exception: # noqa: BLE001
|
except Exception: # noqa: BLE001
|
||||||
|
|||||||
Vendored
+4
-4
@@ -35,7 +35,7 @@ This starts an OpenAI Realtime-compatible server at `ws://localhost:8765/v1/real
|
|||||||
From a source checkout, talk to it from a second terminal:
|
From a source checkout, talk to it from a second terminal:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/listen_and_play_realtime.py --host 127.0.0.1 --port 8765
|
python scripts/listen_and_play_realtime.py --host 192.168.1.9 --port 8765
|
||||||
```
|
```
|
||||||
|
|
||||||
Prefer to keep the LLM on your own machine? Serve Gemma 4 with llama.cpp:
|
Prefer to keep the LLM on your own machine? Serve Gemma 4 with llama.cpp:
|
||||||
@@ -49,7 +49,7 @@ Then point the OpenAI-compatible LLM backend at it:
|
|||||||
```bash
|
```bash
|
||||||
speech-to-speech \
|
speech-to-speech \
|
||||||
--model_name "ggml-org/gemma-4-E4B-it-GGUF" \
|
--model_name "ggml-org/gemma-4-E4B-it-GGUF" \
|
||||||
--responses_api_base_url "http://127.0.0.1:8080/v1" \
|
--responses_api_base_url "http://192.168.1.9:8080/v1" \
|
||||||
--responses_api_api_key ""
|
--responses_api_api_key ""
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -342,7 +342,7 @@ Works with any provider or server that implements the OpenAI Responses API. Poin
|
|||||||
| HF Inference Providers | `https://router.huggingface.co/v1` | `$HF_TOKEN` |
|
| HF Inference Providers | `https://router.huggingface.co/v1` | `$HF_TOKEN` |
|
||||||
| OpenRouter | `https://openrouter.ai/api/v1` | `$OPENROUTER_API_KEY` |
|
| OpenRouter | `https://openrouter.ai/api/v1` | `$OPENROUTER_API_KEY` |
|
||||||
| vLLM | `http://localhost:8000/v1` | omit or any string |
|
| vLLM | `http://localhost:8000/v1` | omit or any string |
|
||||||
| llama.cpp | `http://127.0.0.1:8080/v1` | empty string |
|
| llama.cpp | `http://192.168.1.9:8080/v1` | empty string |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# OpenAI
|
# OpenAI
|
||||||
@@ -439,7 +439,7 @@ speech-to-speech \
|
|||||||
--llm_backend responses-api \
|
--llm_backend responses-api \
|
||||||
--tts qwen3 \
|
--tts qwen3 \
|
||||||
--model_name "ggml-org/gemma-4-E4B-it-GGUF" \
|
--model_name "ggml-org/gemma-4-E4B-it-GGUF" \
|
||||||
--responses_api_base_url "http://127.0.0.1:8080/v1" \
|
--responses_api_base_url "http://192.168.1.9:8080/v1" \
|
||||||
--responses_api_api_key "" \
|
--responses_api_api_key "" \
|
||||||
--responses_api_stream \
|
--responses_api_stream \
|
||||||
--enable_live_transcription
|
--enable_live_transcription
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ Realtime **GA** protocol and plays back the assistant's audio as it arrives.
|
|||||||
3. Open <http://localhost:7860/>, click the orb, allow the mic, talk.
|
3. Open <http://localhost:7860/>, click the orb, allow the mic, talk.
|
||||||
|
|
||||||
> Browsers require **HTTPS or `localhost`** for `getUserMedia()` (mic + camera).
|
> Browsers require **HTTPS or `localhost`** for `getUserMedia()` (mic + camera).
|
||||||
> `127.0.0.1` and `localhost` both work; plain `http://192.168.x.y` does NOT.
|
> `192.168.1.9` and `localhost` both work; plain `http://192.168.x.y` does NOT.
|
||||||
|
|
||||||
Smoke-test the backend from the shell:
|
Smoke-test the backend from the shell:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@
|
|||||||
<body class="booting">
|
<body class="booting">
|
||||||
<!-- Digital-human video, fixed as a full-viewport background layer -->
|
<!-- Digital-human video, fixed as a full-viewport background layer -->
|
||||||
<div id="avatar-stage" class="avatar-stage" aria-hidden="true">
|
<div id="avatar-stage" class="avatar-stage" aria-hidden="true">
|
||||||
<iframe id="avatar-frame" src="http://127.0.0.1:8010/embed.html" allow="autoplay; microphone" frameborder="0"></iframe>
|
<iframe id="avatar-frame" src="http://192.168.1.9:8010/embed.html" allow="autoplay; microphone" frameborder="0"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ async function getWsUrl() {
|
|||||||
const cfg = await r.json();
|
const cfg = await r.json();
|
||||||
if (cfg.s2sUrl) return cfg.s2sUrl;
|
if (cfg.s2sUrl) return cfg.s2sUrl;
|
||||||
} catch (e) { /* fall through */ }
|
} catch (e) { /* fall through */ }
|
||||||
return "ws://127.0.0.1:8765/v1/realtime";
|
return "ws://192.168.1.9:8765/v1/realtime";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must be called from a user gesture (button click) so the browser allows audio.
|
// Must be called from a user gesture (button click) so the browser allows audio.
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ from openai import AsyncOpenAI
|
|||||||
@dataclass
|
@dataclass
|
||||||
class ListenAndPlayRealtimeArguments:
|
class ListenAndPlayRealtimeArguments:
|
||||||
host: str = field(
|
host: str = field(
|
||||||
default="127.0.0.1",
|
default="192.168.1.9",
|
||||||
metadata={"help": "Realtime server host. Default is 127.0.0.1."},
|
metadata={"help": "Realtime server host. Default is 192.168.1.9."},
|
||||||
)
|
)
|
||||||
port: int = field(
|
port: int = field(
|
||||||
default=8765,
|
default=8765,
|
||||||
@@ -30,11 +30,11 @@ class ListenAndPlayRealtimeArguments:
|
|||||||
)
|
)
|
||||||
base_url: Optional[str] = field(
|
base_url: Optional[str] = field(
|
||||||
default=None,
|
default=None,
|
||||||
metadata={"help": "Optional HTTP base URL, e.g. http://127.0.0.1:8765/v1"},
|
metadata={"help": "Optional HTTP base URL, e.g. http://192.168.1.9:8765/v1"},
|
||||||
)
|
)
|
||||||
websocket_base_url: Optional[str] = field(
|
websocket_base_url: Optional[str] = field(
|
||||||
default=None,
|
default=None,
|
||||||
metadata={"help": "Optional WS base URL, e.g. ws://127.0.0.1:8765/v1"},
|
metadata={"help": "Optional WS base URL, e.g. ws://192.168.1.9:8765/v1"},
|
||||||
)
|
)
|
||||||
send_rate: int = field(
|
send_rate: int = field(
|
||||||
default=16000,
|
default=16000,
|
||||||
|
|||||||
@@ -536,7 +536,7 @@ def main() -> None:
|
|||||||
"Overrides --host/--port."
|
"Overrides --host/--port."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument("--host", default="127.0.0.1", help="Used only when --url and --lb-url are unset.")
|
parser.add_argument("--host", default="192.168.1.9", help="Used only when --url and --lb-url are unset.")
|
||||||
parser.add_argument("--port", type=int, default=8765, help="Used only when --url and --lb-url are unset.")
|
parser.add_argument("--port", type=int, default=8765, help="Used only when --url and --lb-url are unset.")
|
||||||
parser.add_argument("--clients", type=int, default=1, help="Number of parallel clients (default 1).")
|
parser.add_argument("--clients", type=int, default=1, help="Number of parallel clients (default 1).")
|
||||||
parser.add_argument("--turns", type=int, default=60, help="Turns per client (default 60).")
|
parser.add_argument("--turns", type=int, default=60, help="Turns per client (default 60).")
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ python s2s_pipeline.py \
|
|||||||
--ws_port 8765
|
--ws_port 8765
|
||||||
|
|
||||||
# 2. Connect with the realtime client
|
# 2. Connect with the realtime client
|
||||||
python listen_and_play_realtime.py --host 127.0.0.1 --port 8765
|
python listen_and_play_realtime.py --host 192.168.1.9 --port 8765
|
||||||
```
|
```
|
||||||
|
|
||||||
Or with `--local_mac_optimal_settings` on Apple Silicon:
|
Or with `--local_mac_optimal_settings` on Apple Silicon:
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ from speech_to_speech.pipeline.messages import AUDIO_RESPONSE_DONE, PIPELINE_END
|
|||||||
|
|
||||||
def _free_port() -> int:
|
def _free_port() -> int:
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
s.bind(("127.0.0.1", 0))
|
s.bind(("192.168.1.9", 0))
|
||||||
return s.getsockname()[1]
|
return s.getsockname()[1]
|
||||||
|
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ class _ServerEnv:
|
|||||||
def start(self):
|
def start(self):
|
||||||
config = uvicorn.Config(
|
config = uvicorn.Config(
|
||||||
self.app,
|
self.app,
|
||||||
host="127.0.0.1",
|
host="192.168.1.9",
|
||||||
port=self.port,
|
port=self.port,
|
||||||
log_level="warning",
|
log_level="warning",
|
||||||
)
|
)
|
||||||
@@ -101,7 +101,7 @@ class _ServerEnv:
|
|||||||
self._server_thread.start()
|
self._server_thread.start()
|
||||||
for _ in range(50):
|
for _ in range(50):
|
||||||
try:
|
try:
|
||||||
with socket.create_connection(("127.0.0.1", self.port), timeout=0.1):
|
with socket.create_connection(("192.168.1.9", self.port), timeout=0.1):
|
||||||
return
|
return
|
||||||
except OSError:
|
except OSError:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
@@ -116,8 +116,8 @@ class _ServerEnv:
|
|||||||
def make_client(self) -> AsyncOpenAI:
|
def make_client(self) -> AsyncOpenAI:
|
||||||
return AsyncOpenAI(
|
return AsyncOpenAI(
|
||||||
api_key="test-key",
|
api_key="test-key",
|
||||||
base_url=f"http://127.0.0.1:{self.port}/v1",
|
base_url=f"http://192.168.1.9:{self.port}/v1",
|
||||||
websocket_base_url=f"ws://127.0.0.1:{self.port}/v1",
|
websocket_base_url=f"ws://192.168.1.9:{self.port}/v1",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -71,8 +71,8 @@ services:
|
|||||||
MQTT_USERNAME: "${EMQX_USER:-dpmserver}"
|
MQTT_USERNAME: "${EMQX_USER:-dpmserver}"
|
||||||
MQTT_PASSWORD: "${EMQX_PASS:-123456}"
|
MQTT_PASSWORD: "${EMQX_PASS:-123456}"
|
||||||
# 展播端(Tauri 大屏)经后端 /api/config 获取的 WebSocket 地址:
|
# 展播端(Tauri 大屏)经后端 /api/config 获取的 WebSocket 地址:
|
||||||
# 必须填"展播机能访问到的服务器地址",默认 127.0.0.1(同机部署)
|
# 必须填"展播机能访问到的服务器地址",默认 192.168.1.9(同机部署)
|
||||||
DPM_MQTT_WS: "ws://${MQTT_PUBLIC_HOST:-127.0.0.1}:8083/mqtt"
|
DPM_MQTT_WS: "ws://${MQTT_PUBLIC_HOST:-192.168.1.9}:8083/mqtt"
|
||||||
DPM_S2S_ENABLED: "${DPM_S2S_ENABLED:-1}"
|
DPM_S2S_ENABLED: "${DPM_S2S_ENABLED:-1}"
|
||||||
DASHSCOPE_API_KEY: "${DASHSCOPE_API_KEY:-}"
|
DASHSCOPE_API_KEY: "${DASHSCOPE_API_KEY:-}"
|
||||||
volumes:
|
volumes:
|
||||||
@@ -80,7 +80,7 @@ services:
|
|||||||
- dpm_knowledge:/app/backend/knowledge # 知识库 park.md(可热更新,删除 kb_index.json 触发重建)
|
- dpm_knowledge:/app/backend/knowledge # 知识库 park.md(可热更新,删除 kb_index.json 触发重建)
|
||||||
- dpm_data:/app/backend/data.json # 播放列表 / 设置
|
- dpm_data:/app/backend/data.json # 播放列表 / 设置
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:10085/api/health', timeout=4).status==200 else 1)"]
|
test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://192.168.1.9:10085/api/health', timeout=4).status==200 else 1)"]
|
||||||
interval: 15s
|
interval: 15s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|||||||
+2
-2
@@ -19,7 +19,7 @@
|
|||||||
- `mqtt_url`:EMQX Broker 的 **WebSocket** 地址(端口 8083)
|
- `mqtt_url`:EMQX Broker 的 **WebSocket** 地址(端口 8083)
|
||||||
- `mqtt_username/password`:Broker 鉴权账号(默认 dpm / 123456,与后端 .env 一致)
|
- `mqtt_username/password`:Broker 鉴权账号(默认 dpm / 123456,与后端 .env 一致)
|
||||||
|
|
||||||
地址解析优先级:**config.json > 后端 /api/config > 构建默认(127.0.0.1)**。
|
地址解析优先级:**config.json > 后端 /api/config > 构建默认(192.168.1.9)**。
|
||||||
|
|
||||||
## 二、后端 /api/config 方式(同机部署自动生效)
|
## 二、后端 /api/config 方式(同机部署自动生效)
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ MQTT_PASSWORD=你的密码
|
|||||||
```
|
```
|
||||||
|
|
||||||
> 若后端与 Broker 同机:后端默认 `MQTT_WS_URL=ws://localhost:8083/mqtt` 即可,
|
> 若后端与 Broker 同机:后端默认 `MQTT_WS_URL=ws://localhost:8083/mqtt` 即可,
|
||||||
> 展播端连 `127.0.0.1` 也通;跨机必须显式配置上面的 IP。
|
> 展播端连 `192.168.1.9` 也通;跨机必须显式配置上面的 IP。
|
||||||
|
|
||||||
## 三、构建期固定地址(不推荐,需重新打包)
|
## 三、构建期固定地址(不推荐,需重新打包)
|
||||||
|
|
||||||
|
|||||||
+19
-8
@@ -3,7 +3,7 @@
|
|||||||
优先级:window.__DPM_*__ 全局变量(运行时可被 /api/config 引导覆盖)
|
优先级:window.__DPM_*__ 全局变量(运行时可被 /api/config 引导覆盖)
|
||||||
> Vite 环境变量(.env.local,构建时)> 内置默认
|
> Vite 环境变量(.env.local,构建时)> 内置默认
|
||||||
内置默认(打包部署):Tauri 内 WebView 的 hostname 为 tauri.localhost,
|
内置默认(打包部署):Tauri 内 WebView 的 hostname 为 tauri.localhost,
|
||||||
后端与 MQTT Broker 若与展播程序同机部署,回退到 127.0.0.1;
|
后端与 MQTT Broker 若与展播程序同机部署,回退到 192.168.1.9;
|
||||||
浏览器开发/局域网访问时回退到当前主机 hostname。
|
浏览器开发/局域网访问时回退到当前主机 hostname。
|
||||||
========================================================= */
|
========================================================= */
|
||||||
|
|
||||||
@@ -11,10 +11,10 @@ const env = import.meta.env || {};
|
|||||||
|
|
||||||
/* 运行期解析(惰性读取 window.__DPM_*__,供 main.jsx bootstrap 覆盖后再生效) */
|
/* 运行期解析(惰性读取 window.__DPM_*__,供 main.jsx bootstrap 覆盖后再生效) */
|
||||||
function resolveHost() {
|
function resolveHost() {
|
||||||
const h = window.location.hostname || '127.0.0.1';
|
const h = window.location.hostname || '192.168.1.9';
|
||||||
// Tauri 打包 WebView(tauri.localhost / localhost)→ 服务同机部署用 127.0.0.1
|
// Tauri 打包 WebView(tauri.localhost / localhost)→ 服务同机部署用 192.168.1.9
|
||||||
if (h === 'tauri.localhost' || h === 'localhost' || h === '127.0.0.1' || h.includes('tauri')) {
|
if (h === 'tauri.localhost' || h === 'localhost' || h === '192.168.1.9' || h.includes('tauri')) {
|
||||||
return '127.0.0.1';
|
return '192.168.1.9';
|
||||||
}
|
}
|
||||||
return h; // 浏览器开发/局域网:当前主机 IP
|
return h; // 浏览器开发/局域网:当前主机 IP
|
||||||
}
|
}
|
||||||
@@ -41,10 +41,21 @@ export function getMqttCredentials() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 惰性读取 s2s 实时语音 WebSocket 地址(打包部署:tauri.localhost → 127.0.0.1) */
|
/** 惰性读取 s2s 实时语音 WebSocket 地址。
|
||||||
|
* 优先 config.json / VITE_VOICE_WS 显式配置;
|
||||||
|
* 否则默认跟随 `api_base` 的主机名(s2s 由 s2s_bridge 在后端同机 :8765 启动),
|
||||||
|
* 而不是页面 hostname(打包后是 tauri.localhost/192.168.1.9,会导致连本机回环而失败)。 */
|
||||||
export function getVoiceWsUrl() {
|
export function getVoiceWsUrl() {
|
||||||
const baked = env.VITE_VOICE_WS || `ws://${resolveHost()}:8765/v1/realtime`;
|
if (window.__DPM_VOICE_WS__) return window.__DPM_VOICE_WS__;
|
||||||
return window.__DPM_VOICE_WS__ || baked;
|
const baked = env.VITE_VOICE_WS;
|
||||||
|
if (baked) return baked;
|
||||||
|
let host;
|
||||||
|
try {
|
||||||
|
host = new URL(getApiBase()).hostname;
|
||||||
|
} catch {
|
||||||
|
host = resolveHost();
|
||||||
|
}
|
||||||
|
return `ws://${host}:8765/v1/realtime`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MQTT_TOPIC_COMMAND = 'opc/display/command';
|
export const MQTT_TOPIC_COMMAND = 'opc/display/command';
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import "./styles/global.css";
|
|||||||
启动引导(打包部署关键)—— 地址解析优先级:
|
启动引导(打包部署关键)—— 地址解析优先级:
|
||||||
1. exe 旁 config.json(Tauri 命令读取,部署免重打包改 IP)★
|
1. exe 旁 config.json(Tauri 命令读取,部署免重打包改 IP)★
|
||||||
2. 后端 GET /api/config(MQTT 地址/账号,后端 .env 为准)
|
2. 后端 GET /api/config(MQTT 地址/账号,后端 .env 为准)
|
||||||
3. 内置默认(Tauri 打包回退 127.0.0.1 / 浏览器用当前主机)
|
3. 内置默认(Tauri 打包回退 192.168.1.9 / 浏览器用当前主机)
|
||||||
结果写入 window.__DPM_*__,api.js / mqtt.js 惰性读取生效。
|
结果写入 window.__DPM_*__,api.js / mqtt.js 惰性读取生效。
|
||||||
========================================================= */
|
========================================================= */
|
||||||
async function bootstrapRuntimeConfig() {
|
async function bootstrapRuntimeConfig() {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import '../styles/datascreen.css';
|
|||||||
import './voice-original.css';
|
import './voice-original.css';
|
||||||
import './voice-overrides.css';
|
import './voice-overrides.css';
|
||||||
|
|
||||||
// 惰性读取 s2s 地址:打包部署 tauri.localhost → 127.0.0.1,且可在 config.json 覆盖
|
// 惰性读取 s2s 地址:打包部署 tauri.localhost → 192.168.1.9,且可在 config.json 覆盖
|
||||||
const VOICE_URL = getVoiceWsUrl();
|
const VOICE_URL = getVoiceWsUrl();
|
||||||
// 基础提示词由后端统一管理(GET /api/s2s/instructions:配置提示词 + 园区知识库),
|
// 基础提示词由后端统一管理(GET /api/s2s/instructions:配置提示词 + 园区知识库),
|
||||||
// 前端不硬编码;此处仅为后端不可用时的兜底
|
// 前端不硬编码;此处仅为后端不可用时的兜底
|
||||||
|
|||||||
Reference in New Issue
Block a user