Skip to content

starhunt/star-vertex-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Star-Vertex-CLI (Polaris)

Vertex AI persistent CLI adapter for Star-CLIProxy.

한 프로세스로 Gemini 채팅 + Imagen + Nano-banana / Pro 이미지 생성을 NDJSON over stdin/stdout으로 처리. Star-CLIProxy 본체 코드 수정 없이 플러그인으로 등록되어, OpenAI 호환 /v1/chat/completions/v1/images/generations 엔드포인트로 자연스럽게 노출됩니다.

전체 설계: docs/Star-Vertex-CLI_PRD.md 설치/등록 단계별 가이드: examples/INSTALL.md

상태

  • ✅ MVP M0–M5 + Star-CLIProxy 통합 (라이브 chat/imagen/nano-banana/Pro 검증)
  • ✅ 통합 google-genai SDK 기반 (deprecated vertexai.* 모듈 의존성 제로)
  • ✅ 단위 테스트 56/56, ruff/mypy strict 클린
  • ✅ Nano-banana Pro image_size 1K/2K/4K 노출 — 한글 인포그래픽 100% 정확

비고: 클래식 vertexai.generative_models는 2026-06-24 제거. Polaris는 그 전에 google-genai로 이행 완료된 상태.

빠른 시작 (개발/로컬)

# 1. 의존성 설치 (uv 권장)
uv venv .venv
source .venv/bin/activate
uv pip install -e .

# 2. 인증
gcloud auth application-default login

# 3. 환경변수
export GOOGLE_CLOUD_PROJECT=<your-gcp-project>
export GOOGLE_CLOUD_LOCATION=us-central1   # Pro 모델은 요청별로 "global" override 가능

# 4. 헬스 체크
star-vertex-cli --health   # → "ok"

# 5. 스모크
echo '{"id":"hc","task":"ping"}' | star-vertex-cli
# → {"type":"pong","id":"hc","uptime_sec":0.001,"cached_models":0,"version":"0.1.0"}

영구 설치 (~/.svtx-cli/)

Star-CLIProxy 등 다른 도구가 안정적인 경로로 호출하려면 전용 venv + 런처를 만드는 것을 권장합니다 (pipx와 동일한 패턴).

mkdir -p ~/.svtx-cli
uv venv ~/.svtx-cli/.venv --python 3.11
~/.svtx-cli/.venv/bin/pip install -e <이_레포_경로>

cat > ~/.svtx-cli/svtx-cli <<'EOF'
#!/usr/bin/env bash
set -e
SVTX_HOME="${SVTX_HOME:-$HOME/.svtx-cli}"
exec "$SVTX_HOME/.venv/bin/python" -m star_vertex_cli "$@"
EOF
chmod +x ~/.svtx-cli/svtx-cli

GOOGLE_CLOUD_PROJECT=<your-project> ~/.svtx-cli/svtx-cli --health

editable install이라 소스 변경은 자동 반영됩니다. 의존성/메타데이터 변경 시에만 pip install -e 재실행.

Star-CLIProxy 플러그인 등록

전체 단계는 examples/INSTALL.md 참조. 요약:

  1. examples/cliproxy-plugin-svtx.js.package.json을 Star-CLIProxy의 plugins/cliproxy-plugin-svtx/ 디렉토리에 복사
  2. config.yamlplugins: 섹션에 등록 (cli_path, env)
  3. admin API로 model_mappings 등록 (svtx-flash, svtx-imagen-fast, svtx-nb-pro 등 — 6개 alias 권장)
  4. start.sh restart → 플러그인 로드
  5. /v1/chat/completions / /v1/images/generations로 호출

플러그인 동작 모델:

  • 한 번 spawn한 Polaris 자식 프로세스를 persistent하게 유지
  • 모든 요청은 id로 멀티플렉싱 (NDJSON 라인 단위)
  • chat 이벤트(text_delta/usage/done)와 image 이벤트(b64_json)를 OpenAI 응답 형식으로 변환 후 클라이언트로 전달

응답 모드: 기본 url, b64 옵트인

플러그인은 이미지 응답을 기본적으로 file:// URL로 반환합니다 — 응답 페이로드 120 바이트. LLM 에이전트가 호출자일 때 base64 한 장이 컨텍스트에 30만100만 토큰을 추가하는 비용 폭증을 막기 위함입니다.

모드 트리거 응답 크기 (1024² PNG 기준) 용도
url (기본) 미지정 또는 response_format: "url" ~120 B LLM 에이전트, 로컬 스크립트, 동일 호스트 소비자
b64_json response_format: "b64_json" ~700 KB+ 웹 프론트엔드, 원격 호출자, 인라인 임베드

캐시 디렉토리: ~/.svtx-cli/cache/ — 24h TTL 자동 청소(1시간 주기). 설정 가능: 플러그인 config.cache_dir / config.cache_ttl_ms.

중요: b64 옵트인이 작동하려면 Star-CLIProxy 본체의 response_format 패스스루 패치가 필요합니다. 자세한 내용은 examples/INSTALL.md 참고.

모델 alias 권장

alias actual model 용도
svtx-flash gemini-2.5-flash 일반 채팅, 저비용
svtx-pro gemini-2.5-pro 고품질 추론 채팅
svtx-imagen-fast imagen-4.0-fast-generate-001 빠른 일반 이미지
svtx-imagen imagen-4.0-generate-001 표준 일반 이미지
svtx-nb-pro gemini-3-pro-image-preview 인포그래픽/한글/도표 (global 자동, 기본 2K)
svtx-nb gemini-2.5-flash-image 빠른 이미지 (영문 위주)

요청 예시

Chat (Gemini)

{"id":"r1","task":"chat","model":"gemini-2.5-pro",
 "messages":[{"role":"user","content":[{"type":"text","text":"한 줄 자기소개"}]}],
 "params":{"temperature":0.7,"max_tokens":2048},"stream":true}

Image (Imagen)

{"id":"i1","task":"image","model":"imagen-4.0-generate-001",
 "prompt":"a cyberpunk workspace, neon, photorealistic",
 "params":{"n":1,"aspect_ratio":"16:9"},"response_format":"b64_json"}

Image (Nano-banana / Gemini Image)

{"id":"i2","task":"image","model":"gemini-2.5-flash-image",
 "prompt":"a stylised polar bear logo",
 "response_format":"file_path","output_dir":"./out"}

Image (Nano-banana Pro — 한글 인포그래픽 1순위)

{"id":"i3","task":"image","model":"gemini-3-pro-image-preview",
 "prompt":"한글 인포그래픽: ...",
 "params":{"image_size":"2K","aspect_ratio":"16:9"},
 "response_format":"file_path","output_dir":"./out",
 "location":"global"}

Pro는 global-endpoint 전용. 요청별 "location":"global" 필수. Star-CLIProxy 플러그인은 이를 자동 적용.

모델 비교

항목 Imagen 4 Nano-banana Pro
출신 디퓨전 전용 모델 Gemini 3 Pro 이미지 모드
추론 없음 있음 (thinking → image)
텍스트 (특히 한글/일본어) 약함 압도적
인포그래픽/도표/제품 목업 약함 1순위
일반 사진/일러스트 강함 양호
속도 5–15초 15–40초
비용 고 (~5–10배)
해상도 옵션 모델 기본 1K / 2K / 4K
Endpoint regional OK global 전용

image_size 가이드 (Pro 모델 한정)

  • "1K" — 빠르고 저렴, 텍스트 거의 깨짐 (한글 70% 정확도)
  • "2K"Polaris/플러그인 기본값, 한글 100% 정확, 권장
  • "4K" — 인쇄/포스터 등 디테일 필요 시. 픽셀은 SDK 이슈로 종종 2K와 같지만 콘텐츠 디테일은 더 풍부

Aspect ratio — 프롬프트 ≠ 출력 비율

중요: 프롬프트에 "16:9", "landscape" 같은 표현을 적어도 모델은 size/aspect_ratio 파라미터를 우선합니다. 정사각형 size를 보내면서 가로 인포그래픽을 기대하면 1:1로 강제됨.

플러그인이 OpenAI size → 내부 aspect_ratio + image_size tier로 자동 매핑하는 표:

OpenAI size aspect_ratio image_size
1024x1024 1:1 1K
2048x2048 1:1 2K
4096x4096 1:1 4K
1280x720 / 2560x1440 / 3840x2160 16:9 1K / 2K / 4K
720x1280 / 1440x2560 / 2160x3840 9:16 1K / 2K / 4K
1024x768 / 2048x1536 4:3 1K / 2K
768x1024 / 1536x2048 3:4 1K / 2K

가로형 인포그래픽이 필요하면 호출 시 size: "2560x1440" 같은 16:9 해상도를 보내야 합니다. 호출자(예: 배치 워커)에서 orientation별로 size를 다르게 매핑해 보내는 패턴 권장.

url 모드 응답 소비 (호출자 측 예시)

기본 응답은 file:// URL이라 같은 호스트 호출자는 fs로 직접 읽으면 b64를 받은 것과 동일한 결과 (네트워크 ~2MB 절약):

# OpenAI 호환 응답 처리: b64_json/url 양쪽 모두 수용
import base64
from urllib.parse import unquote
import httpx

resp = httpx.post(
    "http://localhost:8300/v1/images/generations",
    headers={"Authorization": f"Bearer {key}"},
    json={"model": "svtx-nb-pro", "prompt": prompt, "size": "2560x1440"},
    timeout=180,
).json()

item = resp["data"][0]
if item.get("b64_json"):
    image_bytes = base64.b64decode(item["b64_json"])
elif item.get("url", "").startswith("file://"):
    with open(unquote(item["url"][7:]), "rb") as f:
        image_bytes = f.read()  # 같은 호스트면 가장 빠름
else:
    image_bytes = httpx.get(item["url"]).content

프로토콜 (요약)

방향 형식
입력 (stdin) 1 line = 1 JSON request, id + task 필수
출력 (stdout) NDJSON 이벤트 (type + id)
로그 (stderr) JSON Lines

이벤트 타입: text_delta, image, usage, done, error, fatal, pong, capabilities, shutdown_ack, safety.

스키마 전체: src/star_vertex_cli/protocol.py

환경변수

변수 필수 설명
GOOGLE_CLOUD_PROJECT GCP 프로젝트 ID
GOOGLE_CLOUD_LOCATION 기본 us-central1. Pro는 요청별 global
GOOGLE_APPLICATION_CREDENTIALS ADC 파일 경로 override
POLARIS_LOG_LEVEL info / debug / warning
POLARIS_INCLUDE_TRACE true 시 error 이벤트에 traceback 포함
POLARIS_CACHE_MAXSIZE Client 캐시 크기 (기본 16)
POLARIS_CACHE_IDLE_SEC idle 시 캐시 비우는 임계 (기본 3600)
POLARIS_MAX_CONCURRENCY dispatch ThreadPool 워커 수 (기본 4, 1이면 직렬)
SVTX_HOME 런처 위치 override (기본 ~/.svtx-cli)

병렬 처리

Polaris는 stdin을 한 라인씩 읽지만, 요청 처리는 ThreadPoolExecutor로 병렬화됩니다 (Vertex SDK 호출이 IO-bound라 GIL 영향 적음). POLARIS_MAX_CONCURRENCY=N으로 워커 수 조절.

동시 요청 직렬 (N=1) 병렬 (N=4)
1 5.2s 5.2s
2 10.3s 4.2s (1.87x)
3 15.5s 9.4s (2.35x, Vertex throttle 시작)

shutdown 처리는 동기 — 진행 중 요청 완료 후 종료(graceful). 이벤트는 모두 id 태그가 있어 stdout 멀티플렉싱 시 호출자가 디멀티플렉싱 가능. Emitter는 잠금 보호로 partial line 발생 안 함.

개발

# 의존성 (dev 도구 포함)
uv pip install pytest pytest-asyncio pytest-mock ruff mypy

# 단위 + 프로토콜 통합 테스트 (네트워크 없음)
pytest

# 라이브 호출 (ADC + project 필요, CI 기본 skip)
pytest -m live

# 린트 / 타입체크
ruff check src/star_vertex_cli
mypy src/star_vertex_cli

레이아웃

src/star_vertex_cli/
  cli.py           # 엔트리, argparse, preflight (ADC + project 검증)
  dispatcher.py    # stdin 루프, task 라우팅, 예외 격리 (FR-4.3)
  protocol.py      # Pydantic 스키마 (요청 + 이벤트)
  emitter.py       # NDJSON stdout writer (line-buffered, 잠금)
  cache.py         # (project, location) → genai.Client LRU 캐시
  errors.py        # Vertex 예외 → ErrorEvent 분류
  config.py        # env + ADC 로더
  models.py        # genai.Client factory + 모델 ID 분류
  logging.py       # stderr JSON Lines 로거
  handlers/
    chat.py        # Gemini 채팅 (스트리밍 + 멀티모달)
    image.py       # Imagen + Nano-banana / Pro (image_size, mime sniff)
    control.py     # ping / capabilities / shutdown

tests/
  unit/            # 핸들러/디스패처/캐시/에러분류 단위 테스트 (mock SDK)
  integration/    # subprocess 라운드트립 테스트

examples/
  INSTALL.md                       # ~/.svtx-cli/ + 플러그인 등록 가이드
  cliproxy-plugin-svtx.js          # Star-CLIProxy 플러그인 코드 (참조본)
  cliproxy-plugin-svtx.package.json
  cliproxy-provider.json           # generic_provider 형식 참고
  README.md                        # 통합 메모

docs/
  Star-Vertex-CLI_PRD.md           # 원본 PRD

운영 메모

  • 업데이트 흐름: 소스 변경은 editable install 덕분에 자동 반영. 플러그인 코드만 변경 시 cp ... && start.sh restart. 의존성 변경 시 pip install -e 재실행.
  • Pro 모델 비용 보호: GCP 콘솔 Billing → 예산 알림($50/$100/$200 등) 설정 권장. Polaris는 호출만 중계, 사용량 집계는 Star-CLIProxy의 SQLite가 담당.
  • ADC 만료 (14일 미사용): 만료 시 gcloud auth application-default login 재실행. Polaris의 헬스체크가 auth_failed 코드로 빠르게 신호.
  • 비밀: ~/.config/gcloud/application_default_credentials.json는 OAuth refresh token 포함. 절대 커밋/공유 금지. Polaris stdout에는 ADC 토큰이 절대 흘러가지 않도록 설계 (NFR-7).

라이선스

MIT

About

Polaris — Vertex AI persistent CLI adapter for Star-CLIProxy (Gemini chat + Imagen + Nano-banana Pro)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages