Merge remote-tracking branch 'origin/pr-577' into codex/pr-557-589-security-integration
This commit is contained in:
@@ -215,16 +215,28 @@ func TestCloudAgentAnnotationRenderFeedsControlledTransientReference(t *testing.
|
||||
}
|
||||
|
||||
func TestCloudAgentPolicyPublishesSkillManifestWithoutInliningSkillBody(t *testing.T) {
|
||||
skill := cloudAgentSkill{ID: "skill-1", Name: "任务技能", Version: "v1", Hash: agentProfileHash("skill"), Instruction: "PRIVATE_SKILL_BODY", Files: map[string]string{"references/a.md": "A"}}
|
||||
skill := cloudAgentSkill{ID: "skill-1", Name: "任务技能", Description: "当用户要写短剧剧本时调用", Version: "v1", Hash: agentProfileHash("skill"), Instruction: "PRIVATE_SKILL_BODY", Files: map[string]string{"references/a.md": "A"}}
|
||||
text, _, err := compileCloudAgentPolicies(agentTestRequest(), []cloudAgentSkill{skill}, "", cloudAgentProfileSnapshot{Revision: agentProfileRevision(nil), Hash: agentProfileHash("")})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(text, skill.Instruction) || !strings.Contains(text, `"entryPath":"SKILL.md"`) || !strings.Contains(text, `"files":["SKILL.md","references/a.md"]`) {
|
||||
if strings.Contains(text, skill.Instruction) || !strings.Contains(text, `"entryPath":"SKILL.md"`) || !strings.Contains(text, `"files":["SKILL.md","references/a.md"]`) || !strings.Contains(text, `"description":"当用户要写短剧剧本时调用"`) {
|
||||
t.Fatalf("compiled policy did not publish a safe on-demand skill manifest: %s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudAgentPolicyTruncatesOversizedSkillDescription(t *testing.T) {
|
||||
long := strings.Repeat("描", 600)
|
||||
skill := cloudAgentSkill{ID: "skill-2", Name: "长描述技能", Description: long, Version: "v1", Hash: agentProfileHash("skill2")}
|
||||
text, _, err := compileCloudAgentPolicies(agentTestRequest(), []cloudAgentSkill{skill}, "", cloudAgentProfileSnapshot{Revision: agentProfileRevision(nil), Hash: agentProfileHash("")})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(text, long) || !strings.Contains(text, strings.Repeat("描", 500)+"…") {
|
||||
t.Fatalf("oversized skill description was not capped at 500 runes: %s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudAgentPolicyPublishesCapabilityRoutingGuide(t *testing.T) {
|
||||
text, _, err := compileCloudAgentPolicies(agentTestRequest(), nil, "", cloudAgentProfileSnapshot{Revision: agentProfileRevision(nil), Hash: agentProfileHash("")})
|
||||
if err != nil {
|
||||
|
||||
@@ -84,6 +84,19 @@ func cloudAgentCapabilityGuide() string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// cloudAgentSkillManifestDescription bounds the system prompt: the description
|
||||
// is author-supplied public metadata, so it is trimmed and capped before it
|
||||
// enters the compiled policy.
|
||||
func cloudAgentSkillManifestDescription(description string) string {
|
||||
const maxRunes = 500
|
||||
trimmed := strings.TrimSpace(description)
|
||||
if utf8.RuneCountInString(trimmed) <= maxRunes {
|
||||
return trimmed
|
||||
}
|
||||
runes := []rune(trimmed)
|
||||
return strings.TrimSpace(string(runes[:maxRunes])) + "…"
|
||||
}
|
||||
|
||||
func compileCloudAgentPolicies(req CloudAgentRequest, skills []cloudAgentSkill, canvasSummary string, profile cloudAgentProfileSnapshot, anchors ...cloudAgentCreativeAnchor) (string, cloudAgentPolicySnapshot, error) {
|
||||
system, media, err := prompts.LoadAgentPolicies()
|
||||
if err != nil {
|
||||
@@ -121,7 +134,7 @@ func compileCloudAgentPolicies(req CloudAgentRequest, skills []cloudAgentSkill,
|
||||
}
|
||||
manifests := make([]map[string]any, 0, len(skills))
|
||||
for _, skill := range skills {
|
||||
manifests = append(manifests, map[string]any{"skillId": skill.ID, "name": skill.Name, "version": skill.Version, "hash": skill.Hash, "entryPath": cloudAgentSkillEntryPath, "files": cloudAgentSkillPaths(skill)})
|
||||
manifests = append(manifests, map[string]any{"skillId": skill.ID, "name": skill.Name, "description": cloudAgentSkillManifestDescription(skill.Description), "version": skill.Version, "hash": skill.Hash, "entryPath": cloudAgentSkillEntryPath, "files": cloudAgentSkillPaths(skill)})
|
||||
}
|
||||
context["skills"] = manifests
|
||||
layers := make([]map[string]any, 0, len(profile.Layers))
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
type cloudAgentSkill struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Version string `json:"version"`
|
||||
Hash string `json:"hash"`
|
||||
Instruction string `json:"instruction,omitempty"`
|
||||
@@ -60,7 +61,9 @@ func (s *Service) cloudAgentSkills(userID string, ids []string) ([]cloudAgentSki
|
||||
}
|
||||
// Skill content is loaded only after the model explicitly calls
|
||||
// skill_read_file; keep the run context to stable metadata and paths.
|
||||
snapshot := cloudAgentSkill{ID: id, Name: skill.SkillName, Version: skill.VersionID, Hash: skill.ContentHash, Files: map[string]string{cloudAgentSkillEntryPath: ""}}
|
||||
// The description is public metadata (market listing) and lets the
|
||||
// model route between activated skills without reading any body.
|
||||
snapshot := cloudAgentSkill{ID: id, Name: skill.SkillName, Description: skill.Description, Version: skill.VersionID, Hash: skill.ContentHash, Files: map[string]string{cloudAgentSkillEntryPath: ""}}
|
||||
files, err := s.SkillPackageFiles(userID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user