Files
iknowyou/back/internal/api/handler/tools.go
2026-04-06 15:12:34 +02:00

92 lines
2.5 KiB
Go

package handler
import (
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/anotherhadi/iknowyou/internal/respond"
"github.com/anotherhadi/iknowyou/internal/tools"
)
type ToolsHandler struct {
factories []func() tools.ToolRunner
}
func NewToolsHandler(factories []func() tools.ToolRunner) *ToolsHandler {
return &ToolsHandler{factories: factories}
}
type toolInfo struct {
Name string `json:"name"`
Description string `json:"description"`
Link string `json:"link,omitempty"`
Icon string `json:"icon,omitempty"`
InputTypes []tools.InputType `json:"input_types"`
Configurable bool `json:"configurable"`
ConfigFields []tools.ConfigField `json:"config_fields,omitempty"`
Available *bool `json:"available,omitempty"`
UnavailableReason string `json:"unavailable_reason,omitempty"`
Dependencies []string `json:"dependencies,omitempty"`
}
func toToolInfo(t tools.ToolRunner) toolInfo {
_, configurable := t.(tools.Configurable)
var fields []tools.ConfigField
if d, ok := t.(tools.ConfigDescriber); ok {
fields = d.ConfigFields()
}
var available *bool
var unavailableReason string
if checker, ok := t.(tools.AvailabilityChecker); ok {
avail, reason := checker.Available()
available = &avail
if !avail {
unavailableReason = reason
}
}
var dependencies []string
if lister, ok := t.(tools.DependencyLister); ok {
dependencies = lister.Dependencies()
}
return toolInfo{
Name: t.Name(),
Description: t.Description(),
Link: t.Link(),
Icon: t.Icon(),
InputTypes: t.InputTypes(),
Configurable: configurable,
ConfigFields: fields,
Available: available,
UnavailableReason: unavailableReason,
Dependencies: dependencies,
}
}
// GET /api/tools
func (h *ToolsHandler) List(w http.ResponseWriter, r *http.Request) {
infos := make([]toolInfo, 0, len(h.factories))
for _, factory := range h.factories {
infos = append(infos, toToolInfo(factory()))
}
respond.JSON(w, http.StatusOK, infos)
}
// GET /api/tools/{name}
func (h *ToolsHandler) Get(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
for _, factory := range h.factories {
t := factory()
if t.Name() == name {
respond.JSON(w, http.StatusOK, toToolInfo(t))
return
}
}
respond.Error(w, http.StatusNotFound, fmt.Sprintf("tool %q not found", name))
}