yao/agent/sandbox/v2/shared/inject.go
Max 194faac9b7 feat(agent): enhance sandbox V2 initialization and role management
- Refactored the initSandboxV2 function to return a structured result, consolidating the runner, computer, configuration, cleanup function, loading message ID, and roles into a single return type.
- Updated the Stream method to utilize the new sandboxV2InitResult structure, improving clarity and reducing complexity in handling sandbox initialization.
- Introduced role management enhancements, allowing for pre-resolved role connectors to be passed through the request, streamlining connector resolution during execution.
- Adjusted various components to support the new roles structure, ensuring consistent handling across the agent's sandbox operations.
- Added logging for connector resolution and role management, improving diagnostics and traceability during sandbox execution.
- Updated .gitignore to include tools/TOOL-REGISTRATION.md for better project organization.
2026-05-03 19:11:29 +08:00

71 lines
2 KiB
Go

package shared
import (
"bytes"
"errors"
"io/fs"
"os"
"path"
"strings"
)
const systemToolsMarker = "<!-- Yao System Tools (auto-injected) -->"
// writerFS is the minimal filesystem interface needed by the injection helpers.
// workspace.FS satisfies this interface.
type writerFS interface {
ReadFile(name string) ([]byte, error)
WriteFile(name string, data []byte, perm os.FileMode) error
MkdirAll(name string, perm os.FileMode) error
}
// InjectSystemSkills copies SKILL files from an embed.FS into the workspace.
// The skills parameter should be an embed.FS produced by `//go:embed skills`,
// where each file has a path like "skills/yao-web/SKILL.md". This function
// strips the "skills/" prefix and writes files into targetDir (e.g. ".claude/skills").
func InjectSystemSkills(ws writerFS, skills fs.FS, targetDir string) error {
return fs.WalkDir(skills, "skills", func(p string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
rel := strings.TrimPrefix(p, "skills/")
dst := path.Join(targetDir, rel)
data, err := fs.ReadFile(skills, p)
if err != nil {
return err
}
dir := path.Dir(dst)
if err := ws.MkdirAll(dir, 0755); err != nil {
return err
}
return ws.WriteFile(dst, data, 0644)
})
}
// AppendSystemPrompt appends content to a file in the workspace with an
// idempotent marker. If the marker already exists the call is a no-op.
// If the file does not exist it is created with just the marker + content.
func AppendSystemPrompt(ws writerFS, filename string, content []byte) error {
existing, err := ws.ReadFile(filename)
if err != nil {
if !errors.Is(err, fs.ErrNotExist) {
return err
}
header := []byte(systemToolsMarker + "\n\n")
return ws.WriteFile(filename, append(header, content...), 0644)
}
if bytes.Contains(existing, []byte(systemToolsMarker)) {
return nil
}
separator := []byte("\n\n---\n\n" + systemToolsMarker + "\n\n")
merged := append(existing, append(separator, content...)...)
return ws.WriteFile(filename, merged, 0644)
}