mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
feat(skills): add effective skill resolution and actions (#377)
* feat(skills): add effective skill resolution and actions * refactor(workspace): normalize skill-related env and prompt * chore(api): regenerate skills OpenAPI and SDK artifacts * feat(web): surface effective skill state in console * test(skills): cover API and runtime effective state * fix(web): show adopt action for discovered skills * fix(web): align skill header and show stateful visibility icon * refactor(web): compact skill metadata on narrow layouts * fix(web): constrain long skill text in cards * refactor(skills): narrow default discovery roots * fix(skills): harden managed skill path validation * feat: add path in the results of `use_skill` --------- Co-authored-by: Acbox <acbox0328@gmail.com>
This commit is contained in:
@@ -61,6 +61,7 @@ func (*SkillProvider) Tools(_ context.Context, session SessionContext) ([]sdk.To
|
||||
"skillName": skillName,
|
||||
"description": skill.Description,
|
||||
"content": skill.Content,
|
||||
"path": skill.Path,
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUseSkillReturnsPath(t *testing.T) {
|
||||
provider := NewSkillProvider(nil)
|
||||
|
||||
toolset, err := provider.Tools(context.Background(), SessionContext{
|
||||
Skills: map[string]SkillDetail{
|
||||
"pdf": {
|
||||
Description: "Read PDF instructions",
|
||||
Content: "Use a PDF-aware workflow.",
|
||||
Path: "/data/.agents/skills/pdf",
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Tools returned error: %v", err)
|
||||
}
|
||||
if len(toolset) != 1 {
|
||||
t.Fatalf("expected 1 tool, got %d", len(toolset))
|
||||
}
|
||||
|
||||
result, err := toolset[0].Execute(nil, map[string]any{
|
||||
"skillName": "pdf",
|
||||
"reason": "Need to process a PDF attachment",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Execute returned error: %v", err)
|
||||
}
|
||||
|
||||
payload, ok := result.(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("result type = %T, want map[string]any", result)
|
||||
}
|
||||
if got := payload["path"]; got != "/data/.agents/skills/pdf" {
|
||||
t.Fatalf("path = %#v, want %q", got, "/data/.agents/skills/pdf")
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
type SkillDetail struct {
|
||||
Description string
|
||||
Content string
|
||||
Path string
|
||||
}
|
||||
|
||||
// StreamEventType identifies the kind of stream event emitted by tools.
|
||||
|
||||
Reference in New Issue
Block a user