feat(server): add localized agent starter config endpoint
Add a public GET /api/ui/agent-starters endpoint returning localized empty-state content (title, description, preview images, and starter prompts) for the canvas Agent panel. Content is server-configurable via AgentStarter config with built-in zh-CN/en-US fallbacks, and the route is exempt from authentication so shared canvases render the same content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"img_infinite_canvas/internal/logic"
|
||||
"img_infinite_canvas/internal/svc"
|
||||
"img_infinite_canvas/internal/types"
|
||||
)
|
||||
|
||||
func getAgentStarterConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetAgentStarterConfigRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := logic.NewGetAgentStarterConfigLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetAgentStarterConfig(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,6 +329,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
Path: "/shares/:shareId",
|
||||
Handler: resolveShareHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/ui/agent-starters",
|
||||
Handler: getAgentStarterConfigHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api"),
|
||||
)
|
||||
|
||||
@@ -107,7 +107,8 @@ func requiresAuthenticatedUser(r *http.Request) bool {
|
||||
strings.HasPrefix(path, "/api/shares/") ||
|
||||
path == "/api/auth/options" ||
|
||||
path == "/api/health" ||
|
||||
path == "/api/dashboard" {
|
||||
path == "/api/dashboard" ||
|
||||
path == "/api/ui/agent-starters" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -86,6 +86,24 @@ func TestUserContextMiddlewareIgnoresSpoofedUserIDOnPublicRoute(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserContextMiddlewareAllowsPublicAgentStarterConfig(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/ui/agent-starters?locale=en-US", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
called := false
|
||||
UserContextMiddleware(fakeBearerAuthenticator{})(func(w http.ResponseWriter, _ *http.Request) {
|
||||
called = true
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
})(rec, req)
|
||||
|
||||
if !called {
|
||||
t.Fatal("expected public agent starter config route to continue")
|
||||
}
|
||||
if rec.Code != http.StatusNoContent {
|
||||
t.Fatalf("expected status %d, got %d", http.StatusNoContent, rec.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserContextMiddlewareAuthorizesAnonymousCanvasShare(t *testing.T) {
|
||||
ownerID := "d1d2fbbb-97bb-4406-8d0b-ec814cc65092"
|
||||
authorizer := fakeShareAuthorizer{access: sharingmodule.Access{
|
||||
|
||||
Reference in New Issue
Block a user