mirror of
https://github.com/Warky-Devs/vecna.git
synced 2026-05-05 01:26:58 +00:00
feat(onboard): add interactive extra maps configuration step
This commit is contained in:
@@ -34,7 +34,7 @@ func runOnboard(_ *cobra.Command, _ []string) error {
|
||||
|
||||
// ── Step 1: Discover ──────────────────────────────────────────────────────
|
||||
|
||||
step(1, 5, "Discover embedding servers")
|
||||
step(1, 6, "Discover embedding servers")
|
||||
|
||||
fmt.Println("Scanning (Ollama, LM Studio, vLLM, LocalAI, Jan, Kobold, Tabby)...")
|
||||
servers := discovery.Scan(context.Background())
|
||||
@@ -89,7 +89,7 @@ func runOnboard(_ *cobra.Command, _ []string) error {
|
||||
|
||||
// ── Step 2: Detect dimensions ─────────────────────────────────────────────
|
||||
|
||||
step(2, 5, "Detect model dimensions")
|
||||
step(2, 6, "Detect model dimensions")
|
||||
|
||||
for i := range targets {
|
||||
fmt.Printf("Probing %s / %s ... ", targets[i].endpoint, targets[i].model)
|
||||
@@ -106,7 +106,7 @@ func runOnboard(_ *cobra.Command, _ []string) error {
|
||||
|
||||
// ── Step 3: Configure adapter ─────────────────────────────────────────────
|
||||
|
||||
step(3, 5, "Configure dimension adapter")
|
||||
step(3, 6, "Configure dimension adapter")
|
||||
|
||||
// Use the first target's detected dim as the source dimension default
|
||||
firstDim := 0
|
||||
@@ -156,7 +156,7 @@ func runOnboard(_ *cobra.Command, _ []string) error {
|
||||
|
||||
// ── Step 4: Configure vecna server ────────────────────────────────────────
|
||||
|
||||
step(4, 5, "Configure vecna server")
|
||||
step(4, 6, "Configure vecna server")
|
||||
|
||||
portRaw, err := promptString(in, "Bind port [8080]: ", "8080")
|
||||
if err != nil {
|
||||
@@ -189,9 +189,44 @@ func runOnboard(_ *cobra.Command, _ []string) error {
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// ── Step 5: Test & write ──────────────────────────────────────────────────
|
||||
// ── Step 5: Extra maps ────────────────────────────────────────────────────
|
||||
|
||||
step(5, 5, "Test connections and write config")
|
||||
step(5, 6, "Configure extra maps (optional)")
|
||||
|
||||
extraMaps := map[string]config.ExtraMapConfig{}
|
||||
|
||||
addMaps, err := promptBool(in, "Add extra dimension maps (/map/{key}/v1/embeddings)?", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if addMaps {
|
||||
// Build the list of target names from the already-collected targets.
|
||||
targetNames := make([]string, 0, len(targets))
|
||||
for _, t := range targets {
|
||||
targetNames = append(targetNames, t.name)
|
||||
}
|
||||
|
||||
for {
|
||||
mc, mapErr := collectExtraMap(in, sourceDim, targetDim, adapterType, truncateMode, padMode, targetNames)
|
||||
if mapErr != nil {
|
||||
return mapErr
|
||||
}
|
||||
extraMaps[mc.key] = mc.cfg
|
||||
|
||||
another, promptErr := promptBool(in, "Add another extra map?", false)
|
||||
if promptErr != nil {
|
||||
return promptErr
|
||||
}
|
||||
if !another {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// ── Step 6: Test & write ──────────────────────────────────────────────────
|
||||
|
||||
step(6, 6, "Test connections and write config")
|
||||
|
||||
allPassed := true
|
||||
for _, t := range targets {
|
||||
@@ -260,6 +295,7 @@ func runOnboard(_ *cobra.Command, _ []string) error {
|
||||
TruncateMode: truncateMode,
|
||||
PadMode: padMode,
|
||||
},
|
||||
ExtraMaps: extraMaps,
|
||||
}
|
||||
|
||||
defaultCfgPath := config.ResolveFile(cfgFile)
|
||||
@@ -467,6 +503,103 @@ func mustParseInt(s string, fallback int) int {
|
||||
return n
|
||||
}
|
||||
|
||||
// pendingExtraMap pairs the map key with its collected config.
|
||||
type pendingExtraMap struct {
|
||||
key string
|
||||
cfg config.ExtraMapConfig
|
||||
}
|
||||
|
||||
// collectExtraMap interactively collects one extra_map entry.
|
||||
// Global adapter values are shown as defaults; the user may override any field.
|
||||
func collectExtraMap(
|
||||
in *bufio.Reader,
|
||||
globalSourceDim, globalTargetDim int,
|
||||
globalAdapterType, globalTruncateMode, globalPadMode string,
|
||||
targetNames []string,
|
||||
) (pendingExtraMap, error) {
|
||||
key, err := promptString(in, "Map key (used in URL path, e.g. \"512\"): ", "")
|
||||
if err != nil || key == "" {
|
||||
return pendingExtraMap{}, fmt.Errorf("map key is required")
|
||||
}
|
||||
|
||||
mc := config.ExtraMapConfig{}
|
||||
|
||||
// Target dimension (required — always shown)
|
||||
targetDimRaw, err := promptString(in,
|
||||
fmt.Sprintf("Target dimension [%d]: ", globalTargetDim), fmt.Sprintf("%d", globalTargetDim))
|
||||
if err != nil {
|
||||
return pendingExtraMap{}, err
|
||||
}
|
||||
mc.TargetDim = mustParseInt(targetDimRaw, globalTargetDim)
|
||||
|
||||
// Forward target override
|
||||
if len(targetNames) > 0 {
|
||||
fmt.Println("Available forward targets: " + strings.Join(targetNames, ", "))
|
||||
ftRaw, err := promptString(in, "Forward target override (leave empty to use global default): ", "")
|
||||
if err != nil {
|
||||
return pendingExtraMap{}, err
|
||||
}
|
||||
mc.ForwardTarget = strings.TrimSpace(ftRaw)
|
||||
}
|
||||
|
||||
// Adapter type override
|
||||
adapterTypeRaw, err := promptString(in,
|
||||
fmt.Sprintf("Adapter type override (truncate/random/projection) [%s]: ", globalAdapterType), globalAdapterType)
|
||||
if err != nil {
|
||||
return pendingExtraMap{}, err
|
||||
}
|
||||
if adapterTypeRaw != globalAdapterType {
|
||||
mc.Type = adapterTypeRaw
|
||||
}
|
||||
effectiveType := coalesce(mc.Type, globalAdapterType)
|
||||
|
||||
// Source dim override
|
||||
sourceDimRaw, err := promptString(in,
|
||||
fmt.Sprintf("Source dimension override (leave empty to use global %d): ", globalSourceDim), "")
|
||||
if err != nil {
|
||||
return pendingExtraMap{}, err
|
||||
}
|
||||
if sourceDimRaw != "" {
|
||||
mc.SourceDim = mustParseInt(sourceDimRaw, globalSourceDim)
|
||||
}
|
||||
|
||||
// Truncate/pad mode overrides — only for truncate type
|
||||
if effectiveType == "truncate" {
|
||||
tmRaw, err := promptString(in,
|
||||
fmt.Sprintf("Truncate mode override (from_end/from_start) [%s]: ", globalTruncateMode), globalTruncateMode)
|
||||
if err != nil {
|
||||
return pendingExtraMap{}, err
|
||||
}
|
||||
if tmRaw != globalTruncateMode {
|
||||
mc.TruncateMode = tmRaw
|
||||
}
|
||||
|
||||
pmRaw, err := promptString(in,
|
||||
fmt.Sprintf("Pad mode override (at_end/at_start) [%s]: ", globalPadMode), globalPadMode)
|
||||
if err != nil {
|
||||
return pendingExtraMap{}, err
|
||||
}
|
||||
if pmRaw != globalPadMode {
|
||||
mc.PadMode = pmRaw
|
||||
}
|
||||
}
|
||||
|
||||
// Seed — only for random type
|
||||
if effectiveType == "random" {
|
||||
seedRaw, err := promptString(in, "Seed (0 = time-based): ", "0")
|
||||
if err != nil {
|
||||
return pendingExtraMap{}, err
|
||||
}
|
||||
var seed int64
|
||||
if _, err := fmt.Sscanf(seedRaw, "%d", &seed); err != nil {
|
||||
seed = 0
|
||||
}
|
||||
mc.Seed = seed
|
||||
}
|
||||
|
||||
return pendingExtraMap{key: key, cfg: mc}, nil
|
||||
}
|
||||
|
||||
func writeFullConfig(path string, cfg config.Config) error {
|
||||
// If file already exists, preserve any targets not touched by onboard
|
||||
// by using SaveTarget for each new target; otherwise write the whole file.
|
||||
|
||||
Reference in New Issue
Block a user