Files
Codex Local bf1233d5df
ci / verify (push) Canceled after 0s
feat: expand companion platform, device controls, and memoir workflows
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
2026-10-08 10:06:44 +08:00

127 lines
4.7 KiB
PowerShell

[CmdletBinding()]
param(
[string]$RtcAppId = "6a8f92ca43726c017d34cce1",
[switch]$EnableArkSummary,
[string]$ArkContentModel = "",
[switch]$Force
)
$ErrorActionPreference = "Stop"
$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
$runtimeDirectory = Join-Path $scriptDirectory "runtime"
$utf8NoBom = [System.Text.UTF8Encoding]::new($false)
function Read-RequiredText {
param([string]$Prompt, [string]$Default = "")
$suffix = if ($Default) { " [$Default]" } else { "" }
$value = Read-Host "$Prompt$suffix"
if ([string]::IsNullOrWhiteSpace($value)) { $value = $Default }
if ([string]::IsNullOrWhiteSpace($value)) { throw "$Prompt 不能为空" }
return $value.Trim()
}
function Read-RequiredSecret {
param([string]$Prompt, [int]$MinimumLength = 1)
$secureValue = Read-Host $Prompt -AsSecureString
$pointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureValue)
try {
$value = [Runtime.InteropServices.Marshal]::PtrToStringBSTR($pointer)
}
finally {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($pointer)
}
if ($value.Length -lt $MinimumLength) { throw "$Prompt 长度不足" }
return $value
}
function Write-SecretFile {
param([string]$Name, [string]$Value)
$target = Join-Path $runtimeDirectory $Name
[IO.File]::WriteAllText($target, $Value, $utf8NoBom)
}
if ($RtcAppId.Length -ne 24) {
throw "RTC AppId 必须正好为 24 个字符"
}
if ((Test-Path -LiteralPath $runtimeDirectory) -and -not $Force) {
throw "本地凭据目录已经存在。确认需要重新配置后使用 -Force。"
}
New-Item -ItemType Directory -Path $runtimeDirectory -Force | Out-Null
Write-Host "`n配置只保存在本机 deploy/local-rtc/runtime,已被 Git 忽略。" -ForegroundColor Cyan
Write-Host "输入密钥时屏幕不会显示字符。`n" -ForegroundColor DarkGray
$rtcAppKey = Read-RequiredSecret "RTC AppKey" 16
$volcAccessKeyId = Read-RequiredText "火山引擎 AccessKey ID"
$volcSecretAccessKey = Read-RequiredSecret "火山引擎 Secret AccessKey"
$doubaoAppId = Read-RequiredText "豆包端到端语音 APP ID"
$doubaoAccessToken = Read-RequiredSecret "豆包端到端语音 Access Token"
$speaker = Read-RequiredText "豆包音色 ID" "zh_female_vv_jupiter_bigtts"
$arkApiKey = ""
if ($EnableArkSummary) {
$arkApiKey = Read-RequiredSecret "方舟 API Key"
$ArkContentModel = Read-RequiredText "方舟内容模型 Endpoint ID" $ArkContentModel
}
$template = [ordered]@{
schema_version = "voice-chat-template-bundle-v1"
templates = [ordered]@{
s2s_hybrid = [ordered]@{
AgentConfig = [ordered]@{
TargetUserId = @()
UserId = ""
WelcomeMessage = ""
EnableConversationStateCallback = $false
}
Config = [ordered]@{
InterruptMode = 0
S2SConfig = [ordered]@{
Provider = "volcano"
OutputMode = 0
ProviderParams = [ordered]@{
app = [ordered]@{
appid = $doubaoAppId
token = $doubaoAccessToken
}
dialog = [ordered]@{
extra = [ordered]@{
model = "O"
strict_audit = $true
audit_response = "抱歉,这个话题我暂时无法回答。我们换个轻松的话题吧。"
}
}
asr = [ordered]@{
extra = [ordered]@{
end_smooth_window_ms = 800
}
}
tts = [ordered]@{
speaker = $speaker
}
}
}
}
}
}
}
Write-SecretFile "rtc-app-key" $rtcAppKey
Write-SecretFile "volc-access-key-id" $volcAccessKeyId
Write-SecretFile "volc-secret-access-key" $volcSecretAccessKey
Write-SecretFile "ark-api-key" $arkApiKey
[IO.File]::WriteAllText(
(Join-Path $runtimeDirectory "voice-chat-template.json"),
($template | ConvertTo-Json -Depth 20),
$utf8NoBom
)
[IO.File]::WriteAllText(
(Join-Path $runtimeDirectory "local-rtc.env"),
"RTC_APP_ID=$RtcAppId`nCONTENT_GENERATOR=$(if ($EnableArkSummary) { 'ark' } else { 'local' })`nARK_CONTENT_MODEL=$ArkContentModel`n",
$utf8NoBom
)
Write-Host "`n本地真实 RTC 配置已生成。" -ForegroundColor Green
Write-Host "下一步运行: .\deploy\local-rtc\start.ps1" -ForegroundColor Green