WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/Tencent/WeKnora/internal/application/service"
|
||||
"github.com/Tencent/WeKnora/internal/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// usableSkillLister returns the installed skills a chat turn can actually
|
||||
// invoke on one sandbox config. The @ picker and the agent editor both read
|
||||
// this set so they cannot offer a skill the running image does not carry.
|
||||
type usableSkillLister interface {
|
||||
ListUsableSkills(ctx context.Context, tenantID uint64, configID string) []*types.TenantSkillEntity
|
||||
}
|
||||
|
||||
// SkillHandler handles skill-related HTTP requests
|
||||
type SkillHandler struct {
|
||||
usableSkills usableSkillLister
|
||||
catalog skillCatalogService
|
||||
instructions *service.InstructionSkillService
|
||||
}
|
||||
|
||||
func (h *SkillHandler) SetInstructionService(s *service.InstructionSkillService) { h.instructions = s }
|
||||
|
||||
type skillCatalogService interface {
|
||||
ListCatalog(ctx context.Context, tenantID uint64) ([]service.SkillCatalogView, error)
|
||||
RegisterCatalogFromArchive(ctx context.Context, tenantID uint64, archive []byte) (*types.TenantSkillCatalogEntity, error)
|
||||
RegisterCatalogFromSource(ctx context.Context, tenantID uint64, source string) (*types.TenantSkillCatalogEntity, error)
|
||||
InstallCatalogToConfigs(ctx context.Context, tenantID uint64, catalogID string, configIDs []string) (*service.CatalogInstallResult, error)
|
||||
DeleteCatalog(ctx context.Context, tenantID uint64, catalogID string) error
|
||||
ListCatalogFiles(ctx context.Context, tenantID uint64, catalogID string) ([]service.SkillFileEntry, error)
|
||||
ReadCatalogFile(ctx context.Context, tenantID uint64, catalogID, relativePath string) (*service.SkillFileContent, error)
|
||||
}
|
||||
|
||||
// NewSkillHandler creates a new skill handler. catalog may be nil in tests
|
||||
// that only exercise the chat picker.
|
||||
func NewSkillHandler(usableSkills usableSkillLister, catalog skillCatalogService) *SkillHandler {
|
||||
return &SkillHandler{
|
||||
usableSkills: usableSkills,
|
||||
catalog: catalog,
|
||||
}
|
||||
}
|
||||
|
||||
// SkillInfoResponse represents the skill info returned to frontend
|
||||
type SkillInfoResponse struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ListSkills godoc
|
||||
// @Summary 获取当前沙箱配置上可执行的 Skills
|
||||
// @Description 返回指定沙箱配置镜像内、智能体实际能调用的已安装技能(ready 且启用)。不传 sandbox_config_id 时列表为空。
|
||||
// @Tags Skills
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param sandbox_config_id query string false "Sandbox config ID"
|
||||
// @Success 200 {object} map[string]interface{} "Skills列表"
|
||||
// @Security Bearer
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /skills [get]
|
||||
func (h *SkillHandler) ListSkills(c *gin.Context) {
|
||||
configID := c.Query("sandbox_config_id")
|
||||
if configID == "" || h.usableSkills == nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"success": true,
|
||||
"data": []SkillInfoResponse{},
|
||||
"skills_available": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
rows := h.usableSkills.ListUsableSkills(
|
||||
c.Request.Context(), sandboxConfigTenantID(c), configID,
|
||||
)
|
||||
response := make([]SkillInfoResponse, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
if row == nil {
|
||||
continue
|
||||
}
|
||||
response = append(response, SkillInfoResponse{
|
||||
Name: row.Name,
|
||||
Description: row.Description,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"success": true,
|
||||
"data": response,
|
||||
"skills_available": true,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user