support OLLIE_PROMPTS_PATH: multi-dir prompt store via NewFlatDirUnion
This commit is contained in:
parent
11618a7960
commit
77c20cf43d
|
|
@ -251,7 +251,7 @@ func New(sink *olog.Sink, opts ...ServerOption) *Server {
|
||||||
sink: sink,
|
sink: sink,
|
||||||
agentsDir: agentsDir,
|
agentsDir: agentsDir,
|
||||||
agentStore: NewFlatDirStore(agentsDir, 0644),
|
agentStore: NewFlatDirStore(agentsDir, 0644),
|
||||||
promptStore: NewFlatDirStore(agent.DefaultPromptsDir(), 0444),
|
promptStore: store.NewFlatDirUnion(agent.PromptsDirs(), 0444),
|
||||||
memStore: NewFlatDirStore(memDir, 0644),
|
memStore: NewFlatDirStore(memDir, 0644),
|
||||||
toolStore: NewToolStore(),
|
toolStore: NewToolStore(),
|
||||||
utilStore: NewUtilStore(),
|
utilStore: NewUtilStore(),
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,66 @@ func NewFlatDir(dir string, perm os.FileMode) Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewFlatDirUnion returns a read-only Store that merges multiple directories.
|
||||||
|
// Files are deduplicated by name; the first directory containing a name wins.
|
||||||
|
func NewFlatDirUnion(dirs []string, perm os.FileMode) Store {
|
||||||
|
notBlocking := func(context.Context, string) ([]byte, error) {
|
||||||
|
return nil, fmt.Errorf("blocking read not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve := func(name string) (string, error) {
|
||||||
|
for _, dir := range dirs {
|
||||||
|
p := filepath.Join(dir, name)
|
||||||
|
if _, err := os.Stat(p); err == nil {
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("%s: not found", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &storeConfig{
|
||||||
|
StatFn: func(name string) (os.FileInfo, error) {
|
||||||
|
p, err := resolve(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return os.Stat(p)
|
||||||
|
},
|
||||||
|
ListFn: func() ([]os.DirEntry, error) {
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
var result []os.DirEntry
|
||||||
|
for _, dir := range dirs {
|
||||||
|
entries, err := os.ReadDir(dir)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, e := range entries {
|
||||||
|
if !seen[e.Name()] {
|
||||||
|
seen[e.Name()] = true
|
||||||
|
result = append(result, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
},
|
||||||
|
OpenFn: func(name string) (StoreEntry, error) {
|
||||||
|
p, err := resolve(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &EntryConfig{
|
||||||
|
StatFn: func() (os.FileInfo, error) { return os.Stat(p) },
|
||||||
|
ReadFn: func() ([]byte, error) { return os.ReadFile(p) },
|
||||||
|
WriteFn: func([]byte) error { return fmt.Errorf("%s: read-only", name) },
|
||||||
|
BlockingReadFn: notBlocking,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
CreateFn: func(string) error { return fmt.Errorf("read-only store") },
|
||||||
|
DeleteFn: func(string) error { return fmt.Errorf("read-only store") },
|
||||||
|
RenameFn: func(string, string) error { return fmt.Errorf("read-only store") },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SyntheticFileInfo implements os.FileInfo for entries with no backing file.
|
// SyntheticFileInfo implements os.FileInfo for entries with no backing file.
|
||||||
type SyntheticFileInfo struct {
|
type SyntheticFileInfo struct {
|
||||||
Name_ string
|
Name_ string
|
||||||
|
|
|
||||||
Reference in New Issue