Merge pull request #1302 from dinhkarate/feat(vertex)/add-prefix-field

Feat(vertex): add prefix field
This commit is contained in:
Luis Pater
2026-04-04 04:17:12 +08:00
committed by GitHub
4 changed files with 31 additions and 3 deletions

6
.gitignore vendored
View File

@@ -49,3 +49,9 @@ _bmad-output/*
# macOS
.DS_Store
._*
# Opencode
.beads/
.opencode/
.cli-proxy-api/
.venv/

View File

@@ -70,6 +70,7 @@ func main() {
var kimiLogin bool
var projectID string
var vertexImport string
var vertexImportPrefix string
var configPath string
var password string
var tuiMode bool
@@ -91,6 +92,7 @@ func main() {
flag.StringVar(&projectID, "project_id", "", "Project ID (Gemini only, not required)")
flag.StringVar(&configPath, "config", DefaultConfigPath, "Configure File Path")
flag.StringVar(&vertexImport, "vertex-import", "", "Import Vertex service account key JSON file")
flag.StringVar(&vertexImportPrefix, "vertex-import-prefix", "", "Prefix for Vertex model namespacing (use with -vertex-import)")
flag.StringVar(&password, "password", "", "")
flag.BoolVar(&tuiMode, "tui", false, "Start with terminal management UI")
flag.BoolVar(&standalone, "standalone", false, "In TUI mode, start an embedded local server")
@@ -462,7 +464,7 @@ func main() {
if vertexImport != "" {
// Handle Vertex service account import
cmd.DoVertexImport(cfg, vertexImport)
cmd.DoVertexImport(cfg, vertexImport, vertexImportPrefix)
} else if login {
// Handle Google/Gemini login
cmd.DoLogin(cfg, projectID, options)

View File

@@ -30,6 +30,10 @@ type VertexCredentialStorage struct {
// Type is the provider identifier stored alongside credentials. Always "vertex".
Type string `json:"type"`
// Prefix optionally namespaces models for this credential (e.g., "teamA").
// This results in model names like "teamA/gemini-2.0-flash".
Prefix string `json:"prefix,omitempty"`
}
// SaveTokenToFile writes the credential payload to the given file path in JSON format.

View File

@@ -20,7 +20,7 @@ import (
// DoVertexImport imports a Google Cloud service account key JSON and persists
// it as a "vertex" provider credential. The file content is embedded in the auth
// file to allow portable deployment across stores.
func DoVertexImport(cfg *config.Config, keyPath string) {
func DoVertexImport(cfg *config.Config, keyPath string, prefix string) {
if cfg == nil {
cfg = &config.Config{}
}
@@ -62,13 +62,28 @@ func DoVertexImport(cfg *config.Config, keyPath string) {
// Default location if not provided by user. Can be edited in the saved file later.
location := "us-central1"
fileName := fmt.Sprintf("vertex-%s.json", sanitizeFilePart(projectID))
// Normalize and validate prefix: must be a single segment (no "/" allowed).
prefix = strings.TrimSpace(prefix)
prefix = strings.Trim(prefix, "/")
if prefix != "" && strings.Contains(prefix, "/") {
log.Errorf("vertex-import: prefix must be a single segment (no '/' allowed): %q", prefix)
return
}
// Include prefix in filename so importing the same project with different
// prefixes creates separate credential files instead of overwriting.
baseName := sanitizeFilePart(projectID)
if prefix != "" {
baseName = sanitizeFilePart(prefix) + "-" + baseName
}
fileName := fmt.Sprintf("vertex-%s.json", baseName)
// Build auth record
storage := &vertex.VertexCredentialStorage{
ServiceAccount: sa,
ProjectID: projectID,
Email: email,
Location: location,
Prefix: prefix,
}
metadata := map[string]any{
"service_account": sa,
@@ -76,6 +91,7 @@ func DoVertexImport(cfg *config.Config, keyPath string) {
"email": email,
"location": location,
"type": "vertex",
"prefix": prefix,
"label": labelForVertex(projectID, email),
}
record := &coreauth.Auth{