feat(server): add support for extra maps in adapter configuration

* Introduced ExtraMapConfig to allow multiple adapter configurations.
* Updated server and handler to utilize extra maps for routing.
* Added dashboard handler for metrics visualization.
This commit is contained in:
2026-04-11 21:43:14 +02:00
parent c12e16c9f7
commit c7a3fed6e1
10 changed files with 461 additions and 37 deletions

View File

@@ -9,6 +9,7 @@ import (
"github.com/uptrace/bunrouter"
"github.com/Warky-Devs/vecna.git/pkg/adapter"
"github.com/Warky-Devs/vecna.git/pkg/embedclient"
)
@@ -16,6 +17,18 @@ import (
// correct Google handler. The colon is a literal method separator in the
// Google embedding API, not a bunrouter parameter prefix.
func (h *handler) googleDispatch(w http.ResponseWriter, req bunrouter.Request) error {
return h.googleDispatchWithAdapter(w, req, h.adapter, "")
}
func (h *handler) googleDispatchMapped(w http.ResponseWriter, req bunrouter.Request) error {
em, err := h.resolveExtraMap(req.Param("mapping"))
if err != nil {
return writeJSON(w, http.StatusNotFound, map[string]string{"error": err.Error()})
}
return h.googleDispatchWithAdapter(w, req, em.Adapter, em.ForwardTarget)
}
func (h *handler) googleDispatchWithAdapter(w http.ResponseWriter, req bunrouter.Request, adp adapter.Adapter, targetOverride string) error {
modelaction := req.Param("modelaction") // e.g. "text-embedding-foo:embedContent"
idx := strings.LastIndex(modelaction, ":")
if idx < 0 {
@@ -29,9 +42,9 @@ func (h *handler) googleDispatch(w http.ResponseWriter, req bunrouter.Request) e
switch action {
case "embedContent":
return h.googleEmbedContent(w, req)
return h.googleEmbedContentWithAdapter(w, req, adp, targetOverride)
case "batchEmbedContents":
return h.googleBatchEmbedContents(w, req)
return h.googleBatchEmbedContentsWithAdapter(w, req, adp, targetOverride)
default:
return writeJSON(w, http.StatusNotFound, map[string]string{"error": "unknown Google API method: " + action})
}
@@ -60,7 +73,7 @@ type googleEmbeddingValues struct {
Values []float32 `json:"values"`
}
func (h *handler) googleEmbedContent(w http.ResponseWriter, req bunrouter.Request) error {
func (h *handler) googleEmbedContentWithAdapter(w http.ResponseWriter, req bunrouter.Request, adp adapter.Adapter, targetOverride string) error {
model, _ := req.Context().Value(modelKey).(string)
var body googleEmbedContentRequest
@@ -73,7 +86,7 @@ func (h *handler) googleEmbedContent(w http.ResponseWriter, req bunrouter.Reques
texts[i] = p.Text
}
client, targetName, targetURL := h.resolveClient(model)
client, targetName, targetURL := h.resolveClientOverride(targetOverride, model)
trace := TraceFromContext(req.Context())
trace.ForwardTarget = targetName
trace.ForwardURL = targetURL
@@ -91,7 +104,7 @@ func (h *handler) googleEmbedContent(w http.ResponseWriter, req bunrouter.Reques
t1 := time.Now()
var adapted []float32
if len(embedResp.Embeddings) > 0 {
adapted, err = h.adapter.Adapt(embedResp.Embeddings[0])
adapted, err = adp.Adapt(embedResp.Embeddings[0])
if err != nil {
return writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
}
@@ -115,7 +128,7 @@ type googleBatchResponse struct {
Embeddings []googleEmbeddingValues `json:"embeddings"`
}
func (h *handler) googleBatchEmbedContents(w http.ResponseWriter, req bunrouter.Request) error {
func (h *handler) googleBatchEmbedContentsWithAdapter(w http.ResponseWriter, req bunrouter.Request, adp adapter.Adapter, targetOverride string) error {
model, _ := req.Context().Value(modelKey).(string)
var body googleBatchRequest
@@ -130,7 +143,7 @@ func (h *handler) googleBatchEmbedContents(w http.ResponseWriter, req bunrouter.
}
}
client, targetName, targetURL := h.resolveClient(model)
client, targetName, targetURL := h.resolveClientOverride(targetOverride, model)
trace := TraceFromContext(req.Context())
trace.ForwardTarget = targetName
trace.ForwardURL = targetURL
@@ -148,7 +161,7 @@ func (h *handler) googleBatchEmbedContents(w http.ResponseWriter, req bunrouter.
t1 := time.Now()
result := make([]googleEmbeddingValues, len(embedResp.Embeddings))
for i, vec := range embedResp.Embeddings {
adapted, adaptErr := h.adapter.Adapt(vec)
adapted, adaptErr := adp.Adapt(vec)
if adaptErr != nil {
return writeJSON(w, http.StatusInternalServerError, map[string]string{"error": adaptErr.Error()})
}