fix(platform): 内嵌 IANA tzdata,Windows 也能解析 TZ;新增本机 embedding 服务脚本
- cmd/cyrene/main.go: import _ "time/tzdata" —— Windows 无系统 tzdata,导致 config.TZ(默认 Asia/Shanghai) 解析失败、loop 时间注入被静默禁用;内嵌后单二进制自洽(约 +450KB) - 实测:迁移到 Windows 后启动日志不再出现 "timezone load failed; time injection disabled" - scripts/embed.bat(新):本机 llama.cpp embedding 服务启停(start/stop/status),OpenAI 兼容 /v1/embeddings,跑 Qwen3-Embedding-0.6B-Q8_0(dim 1024) - 实测:start→Ready→status running→POST /v1/embeddings 200 dim=1024;配合 docker compose 的 cyrene-pg(pgvector) 后端日志变为 pgvector index ready dim=1024(不再回落内存语义)
This commit is contained in:
1 parent
17c9fb7545
commit
2092094d0a
2 files changed
+140
No files matched your search
@@ -17,6 +17,12 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
// Embed the IANA timezone database so the configured TZ (config.TZ, default
|
||||
// "Asia/Shanghai") resolves everywhere: Windows ships no system tzdata and Go
|
||||
// deliberately does not bundle one, so without this the loop's time injection
|
||||
// silently disables itself there (internal/runtime/loop/time.go logs
|
||||
// "timezone load failed"). Costs ~450 KB and keeps the binary self-contained.
|
||||
_ "time/tzdata"
|
||||
|
||||
capreg "git.yeij.top/AskaEth/Cyrene_v2/internal/capability/registry"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/config"
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
@echo off
|
||||
setlocal EnableExtensions EnableDelayedExpansion
|
||||
rem ============================================================
|
||||
rem Cyrene v2 local embedding server (llama.cpp) - Windows
|
||||
rem
|
||||
rem Usage:
|
||||
rem scripts\embed.bat start (default)
|
||||
rem scripts\embed.bat start start llama-server on :11434
|
||||
rem scripts\embed.bat stop stop llama-server
|
||||
rem scripts\embed.bat status show status
|
||||
rem
|
||||
rem Serves an OpenAI-compatible embeddings endpoint:
|
||||
rem POST http://127.0.0.1:<port>/v1/embeddings
|
||||
rem backed by Qwen3-Embedding-0.6B Q8_0 (dim 1024, CPU) - the model
|
||||
rem .env EMBEDDING_API_URL / EMBEDDING_MODEL are expected to point at.
|
||||
rem Cyrene only takes the real semantic path when this is up; otherwise it
|
||||
rem logs "vector index unavailable, falling back to in-memory semantic".
|
||||
rem
|
||||
rem The vector index itself lives in PostgreSQL + pgvector (DB_PG_URL):
|
||||
rem docker compose -f docker-compose.dev.yml up -d pg
|
||||
rem
|
||||
rem Overridable via environment:
|
||||
rem LLAMA_DIR (default %USERPROFILE%\apps\llama.cpp)
|
||||
rem EMBED_MODEL (default %USERPROFILE%\.models\Qwen3-Embedding-0.6B-Q8_0.gguf)
|
||||
rem EMBED_PORT (default 11434)
|
||||
rem Logs: %USERPROFILE%\llama.log (+ llama.stdout.log)
|
||||
rem
|
||||
rem ASCII-only + CRLF on purpose (cmd parsing is codepage/line-ending
|
||||
rem sensitive); Windows tools are called by absolute System32 path so an
|
||||
rem MSYS/MinGW PATH (Git Bash) cannot shadow them.
|
||||
rem ============================================================
|
||||
|
||||
set "SYS=%SystemRoot%\System32"
|
||||
if not defined LLAMA_DIR set "LLAMA_DIR=%USERPROFILE%\apps\llama.cpp"
|
||||
if not defined EMBED_MODEL set "EMBED_MODEL=%USERPROFILE%\.models\Qwen3-Embedding-0.6B-Q8_0.gguf"
|
||||
if not defined EMBED_PORT set "EMBED_PORT=11434"
|
||||
set "SERVER=%LLAMA_DIR%\llama-server.exe"
|
||||
set "LOG_FILE=%USERPROFILE%\llama.log"
|
||||
set "STDOUT_FILE=%USERPROFILE%\llama.stdout.log"
|
||||
set "HEALTH_URL=http://127.0.0.1:%EMBED_PORT%/health"
|
||||
|
||||
set "ACTION=%~1"
|
||||
if "%ACTION%"=="" set "ACTION=start"
|
||||
if /i "%ACTION%"=="start" goto :do_start
|
||||
if /i "%ACTION%"=="stop" goto :do_stop
|
||||
if /i "%ACTION%"=="status" goto :do_status
|
||||
echo Usage: scripts\embed.bat [start^|stop^|status] (no arg = start)
|
||||
exit /b 1
|
||||
|
||||
:do_start
|
||||
if not exist "%SYS%\curl.exe" (
|
||||
echo [ERROR] %SYS%\curl.exe not found - the readiness check needs it.
|
||||
exit /b 1
|
||||
)
|
||||
call :is_running
|
||||
if defined RUNNING_PID (
|
||||
echo embedding server is already running ^(PID !RUNNING_PID!^) on port %EMBED_PORT%.
|
||||
exit /b 0
|
||||
)
|
||||
if not exist "%SERVER%" (
|
||||
echo [ERROR] llama-server.exe not found: %SERVER%
|
||||
echo download the llama.cpp bin-win-cpu-x64 zip and extract it there.
|
||||
exit /b 1
|
||||
)
|
||||
if not exist "%EMBED_MODEL%" (
|
||||
echo [ERROR] embedding model not found: %EMBED_MODEL%
|
||||
echo fetch Qwen3-Embedding-0.6B-Q8_0.gguf from ModelScope.
|
||||
exit /b 1
|
||||
)
|
||||
echo Starting llama-server -^> %EMBED_MODEL% ^(port %EMBED_PORT%^)
|
||||
powershell -NoProfile -Command "Start-Process -FilePath '%SERVER%' -ArgumentList '-m','%EMBED_MODEL%','--embeddings','--host','127.0.0.1','--port','%EMBED_PORT%','-c','4096','-b','2048','-ub','2048','-t','8' -WorkingDirectory '%LLAMA_DIR%' -RedirectStandardOutput '%STDOUT_FILE%' -RedirectStandardError '%LOG_FILE%' -WindowStyle Hidden"
|
||||
set /a TRIES=0
|
||||
:start_wait
|
||||
set /a TRIES+=1
|
||||
call :healthy
|
||||
if not errorlevel 1 (
|
||||
echo Ready: http://127.0.0.1:%EMBED_PORT%/v1/embeddings ^(log: %LOG_FILE%^)
|
||||
exit /b 0
|
||||
)
|
||||
if !TRIES! GEQ 30 (
|
||||
echo [ERROR] not ready after ~60s - check %LOG_FILE%
|
||||
exit /b 1
|
||||
)
|
||||
"%SYS%\ping.exe" -n 2 127.0.0.1 >nul
|
||||
goto :start_wait
|
||||
|
||||
:do_stop
|
||||
call :is_running
|
||||
if not defined RUNNING_PID (
|
||||
echo embedding server is not running.
|
||||
exit /b 0
|
||||
)
|
||||
echo Stopping PID !RUNNING_PID! ...
|
||||
"%SYS%\taskkill.exe" /PID !RUNNING_PID! /T /F >nul 2>&1
|
||||
"%SYS%\ping.exe" -n 2 127.0.0.1 >nul
|
||||
call :is_running
|
||||
if not defined RUNNING_PID (
|
||||
echo Stopped.
|
||||
exit /b 0
|
||||
)
|
||||
echo [WARN] still listening on %EMBED_PORT%.
|
||||
exit /b 1
|
||||
|
||||
:do_status
|
||||
call :is_running
|
||||
call :healthy
|
||||
if not errorlevel 1 (
|
||||
echo embedding: running ^(PID !RUNNING_PID!^) . port %EMBED_PORT% . health ok
|
||||
exit /b 0
|
||||
)
|
||||
if defined RUNNING_PID (
|
||||
echo embedding: process alive ^(PID !RUNNING_PID!^) but health not ready ^(%HEALTH_URL%^)
|
||||
exit /b 1
|
||||
)
|
||||
echo embedding: not running
|
||||
exit /b 1
|
||||
|
||||
rem healthy: errorlevel 0 = HTTP 2xx
|
||||
:healthy
|
||||
"%SYS%\curl.exe" -s -f --max-time 3 -o NUL "%HEALTH_URL%" >nul 2>&1
|
||||
exit /b %errorlevel%
|
||||
|
||||
rem is_running -> RUNNING_PID (detected from the listening port)
|
||||
:is_running
|
||||
set "RUNNING_PID="
|
||||
set "NS_FILE=%TEMP%\embed-netstat-%RANDOM%.txt"
|
||||
"%SYS%\netstat.exe" -ano -p tcp > "%NS_FILE%" 2>nul
|
||||
for /f "tokens=2,5" %%A in ('%SYS%\findstr.exe /C:"LISTENING" "%NS_FILE%"') do (
|
||||
if not defined RUNNING_PID (
|
||||
echo %%A| "%SYS%\findstr.exe" /E /C:":%EMBED_PORT%" >nul && set "RUNNING_PID=%%B"
|
||||
)
|
||||
)
|
||||
del "%NS_FILE%" >nul 2>&1
|
||||
exit /b 0
|
||||
Reference in new issue
Block a user