fix: Fixed issue with openclaw skill page return empty (#12347)

This commit is contained in:
CityFun
2026-03-26 17:57:07 +08:00
committed by GitHub
parent 1d40bdc11b
commit 6e052b8ef2
2 changed files with 53 additions and 32 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ func countOpenclawConfiguredChannels(conf map[string]interface{}) int {
func loadOpenclawOverviewSkillStats(containerName string) (int, error) {
output, err := cmd.RunDefaultWithStdoutBashCfAndTimeOut(
"docker exec %s openclaw gateway call skills.status --json 2>&1",
"docker exec %s openclaw skills list --json 2>&1",
30*time.Second,
containerName,
)
+52 -31
View File
@@ -23,7 +23,10 @@ type openclawSkillListItem struct {
Source string `json:"source"`
Bundled bool `json:"bundled"`
Disabled bool `json:"disabled"`
SkillKey string `json:"skillKey"`
}
type openclawSkillInfo struct {
SkillKey string `json:"skillKey"`
}
type skillhubSearchPayload struct {
@@ -32,6 +35,7 @@ type skillhubSearchPayload struct {
}
var clawhubSearchLinePattern = regexp.MustCompile(`^(\S+)\s+(.+?)\s+\(([\d.]+)\)$`)
var ansiEscapePattern = regexp.MustCompile(`\x1b\[[0-9;?]*[ -/]*[@-~]`)
func (a AgentService) ListSkills(req dto.AgentIDReq) ([]dto.AgentSkillItem, error) {
_, install, err := a.loadOpenclawAgentAndInstall(req.AgentID)
@@ -41,7 +45,11 @@ func (a AgentService) ListSkills(req dto.AgentIDReq) ([]dto.AgentSkillItem, erro
if err := ensureContainerRunning(install.ContainerName); err != nil {
return nil, err
}
output, err := loadOpenclawSkillsStatus(install.ContainerName)
output, err := cmd.RunDefaultWithStdoutBashCfAndTimeOut(
"docker exec %s openclaw skills list --json 2>&1",
30*time.Second,
install.ContainerName,
)
if err != nil {
return nil, err
}
@@ -86,7 +94,7 @@ func (a AgentService) UpdateSkill(req dto.AgentSkillUpdateReq) error {
if err != nil {
return err
}
skillKey, err := getOpenclawSkillKeyFromStatus(install.ContainerName, req.Name)
skillKey, err := getOpenclawSkillKey(install.ContainerName, req.Name)
if err != nil {
return err
}
@@ -119,12 +127,15 @@ func (a AgentService) InstallSkill(req dto.AgentSkillInstallReq) error {
}
func parseOpenclawSkillsList(output string) ([]dto.AgentSkillItem, error) {
trimmed := strings.TrimSpace(output)
if trimmed == "" {
payloadBytes, err := extractEmbeddedJSON(output)
if err != nil {
return nil, err
}
if len(payloadBytes) == 0 {
return nil, nil
}
var payload openclawSkillsList
if err := json.Unmarshal([]byte(trimmed), &payload); err != nil {
if err := json.Unmarshal(payloadBytes, &payload); err != nil {
return nil, err
}
items := make([]dto.AgentSkillItem, 0, len(payload.Skills))
@@ -140,14 +151,6 @@ func parseOpenclawSkillsList(output string) ([]dto.AgentSkillItem, error) {
return items, nil
}
func loadOpenclawSkillsStatus(containerName string) (string, error) {
return cmd.RunDefaultWithStdoutBashCfAndTimeOut(
"docker exec %s openclaw gateway call skills.status --json 2>&1",
30*time.Second,
containerName,
)
}
func loadOpenclawSkillSearchOutput(containerName, source, keyword string) (string, error) {
switch source {
case "skillhub":
@@ -229,32 +232,50 @@ func buildOpenclawSkillInstallCommand(source, slug string) string {
}
}
func getOpenclawSkillKeyFromStatus(containerName, name string) (string, error) {
output, err := loadOpenclawSkillsStatus(containerName)
func getOpenclawSkillKey(containerName, name string) (string, error) {
output, err := cmd.RunDefaultWithStdoutBashCfAndTimeOut(
"docker exec %s openclaw skills info %q --json 2>&1",
30*time.Second,
containerName,
name,
)
if err != nil {
return "", err
}
return parseOpenclawSkillKeyFromStatus(name, output)
return parseOpenclawSkillKey(name, output)
}
func parseOpenclawSkillKeyFromStatus(name, output string) (string, error) {
trimmed := strings.TrimSpace(output)
if trimmed == "" {
return "", fmt.Errorf("skill %s does not have a skillKey", name)
}
var payload openclawSkillsList
if err := json.Unmarshal([]byte(trimmed), &payload); err != nil {
func parseOpenclawSkillKey(name, output string) (string, error) {
payloadBytes, err := extractEmbeddedJSON(output)
if err != nil {
return "", err
}
for _, item := range payload.Skills {
if item.Name == name {
if item.SkillKey == "" {
return "", fmt.Errorf("skill %s does not have a skillKey", name)
}
return item.SkillKey, nil
var payload openclawSkillInfo
if err := json.Unmarshal(payloadBytes, &payload); err != nil {
return "", err
}
if payload.SkillKey == "" {
return "", fmt.Errorf("skill %s does not have a skillKey", name)
}
return payload.SkillKey, nil
}
func extractEmbeddedJSON(output string) ([]byte, error) {
trimmed := strings.TrimSpace(ansiEscapePattern.ReplaceAllString(output, ""))
if trimmed == "" {
return nil, nil
}
for i := 0; i < len(trimmed); i++ {
if trimmed[i] != '{' && trimmed[i] != '[' {
continue
}
decoder := json.NewDecoder(strings.NewReader(trimmed[i:]))
var raw json.RawMessage
if err := decoder.Decode(&raw); err == nil {
return raw, nil
}
}
return "", fmt.Errorf("skill %s not found", name)
return nil, fmt.Errorf("json payload not found")
}
func setOpenclawSkillEnabled(conf map[string]interface{}, skillKey string, enabled bool) {