flatten: merge internal/p9 into package main
Removes internal/p9/ directory. store.go and server.go merged into root server.go alongside main.go. No logic changes.
This commit is contained in:
parent
73b634b6d3
commit
6936c1c959
|
|
@ -1,166 +0,0 @@
|
|||
package p9
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"ollie/pkg/paths"
|
||||
"ollie/pkg/store"
|
||||
"ollie/pkg/tools/execute"
|
||||
)
|
||||
|
||||
// Re-export core store types so existing 9p code compiles unchanged.
|
||||
type (
|
||||
ReadableStore = store.ReadableStore
|
||||
WritableStore = store.WritableStore
|
||||
ReadWriteStore = store.ReadWriteStore
|
||||
BlobStore = store.BlobStore
|
||||
Store = store.Store
|
||||
FlatDirStore = store.FlatDir
|
||||
SkillStore = store.SkillStore
|
||||
BatchStore = store.BatchStore
|
||||
BatchJobStore = store.BatchJobStore
|
||||
Session = store.Session
|
||||
SessionStore = store.SessionStore
|
||||
SessionFileStore = store.SessionFileStore
|
||||
|
||||
syntheticFileInfo = store.SyntheticFileInfo
|
||||
)
|
||||
|
||||
func NewFlatDirStore(dir string, perm os.FileMode) *FlatDirStore {
|
||||
return store.NewFlatDir(dir, perm)
|
||||
}
|
||||
|
||||
func NewSkillStore() *SkillStore {
|
||||
return store.NewSkillStore()
|
||||
}
|
||||
|
||||
func syntheticEntry(name string, mode os.FileMode) os.DirEntry {
|
||||
return store.FileEntry(name, mode)
|
||||
}
|
||||
|
||||
func syntheticDirEntry(name string, mode os.FileMode) os.DirEntry {
|
||||
return store.DirEntry(name, mode)
|
||||
}
|
||||
|
||||
// --- util ---
|
||||
|
||||
// UtilStore is a FlatDirStore backed by the scripts/u/ directory.
|
||||
type UtilStore struct {
|
||||
*FlatDirStore
|
||||
}
|
||||
|
||||
func NewUtilStore() *UtilStore {
|
||||
return &UtilStore{FlatDirStore: NewFlatDirStore(paths.CfgDir()+"/scripts/u", 0555)}
|
||||
}
|
||||
|
||||
func (s *UtilStore) Stat(name string) (os.FileInfo, error) {
|
||||
return s.FlatDirStore.Stat(name)
|
||||
}
|
||||
|
||||
func (s *UtilStore) List() ([]os.DirEntry, error) {
|
||||
return s.FlatDirStore.List()
|
||||
}
|
||||
|
||||
func (s *UtilStore) Get(name string) ([]byte, error) {
|
||||
return s.FlatDirStore.Get(name)
|
||||
}
|
||||
|
||||
// --- exec ---
|
||||
|
||||
// ExecStore is a read-only FlatDirStore backed by the scripts/x/ directory.
|
||||
type ExecStore struct {
|
||||
*FlatDirStore
|
||||
}
|
||||
|
||||
func NewExecStore() *ExecStore {
|
||||
return &ExecStore{FlatDirStore: NewFlatDirStore(execute.PluginsPath(), 0555)}
|
||||
}
|
||||
|
||||
func (s *ExecStore) Stat(name string) (os.FileInfo, error) {
|
||||
return s.FlatDirStore.Stat(name)
|
||||
}
|
||||
|
||||
func (s *ExecStore) List() ([]os.DirEntry, error) {
|
||||
return s.FlatDirStore.List()
|
||||
}
|
||||
|
||||
func (s *ExecStore) Get(name string) ([]byte, error) {
|
||||
return s.FlatDirStore.Get(name)
|
||||
}
|
||||
|
||||
// --- tools ---
|
||||
|
||||
// ToolStore is a BlobStore backed by the tools directory.
|
||||
// It extends FlatDirStore with a synthetic "idx" entry that lists all tools
|
||||
// with their descriptions and argument signatures.
|
||||
type ToolStore struct {
|
||||
*FlatDirStore
|
||||
}
|
||||
|
||||
func NewToolStore() *ToolStore {
|
||||
return &ToolStore{FlatDirStore: NewFlatDirStore(execute.ToolsPath(), 0755)}
|
||||
}
|
||||
|
||||
func (s *ToolStore) Stat(name string) (os.FileInfo, error) {
|
||||
if name == "idx" {
|
||||
return &syntheticFileInfo{Name_: "idx", Mode_: 0444}, nil
|
||||
}
|
||||
return s.FlatDirStore.Stat(name)
|
||||
}
|
||||
|
||||
func (s *ToolStore) List() ([]os.DirEntry, error) {
|
||||
entries, err := s.FlatDirStore.List()
|
||||
result := make([]os.DirEntry, 0, len(entries)+1)
|
||||
result = append(result, syntheticEntry("idx", 0444))
|
||||
result = append(result, entries...)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *ToolStore) Get(name string) ([]byte, error) {
|
||||
if name == "idx" {
|
||||
return s.index()
|
||||
}
|
||||
return s.FlatDirStore.Get(name)
|
||||
}
|
||||
|
||||
func (s *ToolStore) index() ([]byte, error) {
|
||||
entries, err := s.FlatDirStore.List()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var sb strings.Builder
|
||||
for _, e := range entries {
|
||||
if e.IsDir() {
|
||||
continue
|
||||
}
|
||||
data, err := s.FlatDirStore.Get(e.Name())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var desc, args string
|
||||
for line := range strings.SplitSeq(string(data), "\n") {
|
||||
if d, ok := strings.CutPrefix(line, "# description:"); ok {
|
||||
desc = strings.TrimSpace(d)
|
||||
} else if a, ok := strings.CutPrefix(line, "# Args:"); ok {
|
||||
args = strings.TrimSpace(a)
|
||||
} else if a, ok := strings.CutPrefix(line, "# args:"); ok {
|
||||
args = strings.TrimSpace(a)
|
||||
}
|
||||
if !strings.HasPrefix(line, "#") && line != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
if desc == "" {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(&sb, "## %s\n", e.Name())
|
||||
fmt.Fprintf(&sb, "description: %s\n", desc)
|
||||
if args != "" {
|
||||
fmt.Fprintf(&sb, "args: %s\n", args)
|
||||
}
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
return []byte(sb.String()), nil
|
||||
}
|
||||
3
main.go
3
main.go
|
|
@ -12,7 +12,6 @@ import (
|
|||
"syscall"
|
||||
|
||||
"9fans.net/go/plan9/client"
|
||||
p9 "olliesrv/internal/p9"
|
||||
"ollie/pkg/env"
|
||||
olog "ollie/pkg/log"
|
||||
)
|
||||
|
|
@ -153,7 +152,7 @@ func runServer(sockPath, pidPath string) {
|
|||
os.WriteFile(pidPath, []byte(fmt.Sprintf("%d", os.Getpid())), 0644) //nolint:errcheck
|
||||
|
||||
sink := olog.NewSink(os.Stdout, os.Stderr, olog.ParseLevel(os.Getenv("OLLIE_LOG"), olog.LevelWarn))
|
||||
srv := p9.New(sink)
|
||||
srv := New(sink)
|
||||
|
||||
listener, err := net.Listen("unix", sockPath)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,37 +1,6 @@
|
|||
// Package p9 implements the 9P filesystem for ollie sessions.
|
||||
//
|
||||
// Filesystem layout:
|
||||
//
|
||||
// ollie/
|
||||
// a/ (dir) agent configs (r/w, backed by ~/.config/ollie/agents/)
|
||||
// backends (read) list of ollie-provided backends
|
||||
// help (read) help file (backed by ~/.config/ollie/help.md)
|
||||
// m/ (dir) memories (r/w, backed by OLLIE_MEMORY_PATH)
|
||||
// p/ (dir) prompt templates
|
||||
// s/ (dir) session directory
|
||||
// new (r/w) read: KV template; write: create session
|
||||
// idx (read) live index: name state cwd backend model (tab-separated)
|
||||
// {session-id}/ rm -r to kill session; mv to rename
|
||||
// ctl (write) session control: stop, kill, rn, compact, clear
|
||||
// prompt (write) submit a prompt to the agent
|
||||
// fifo.in (write) queue a prompt for later execution
|
||||
// fifo.out (read) pop the next queued prompt
|
||||
// chat (r/w) cumulative chat history; write to save a transcript to tr/
|
||||
// state (read) current agent state
|
||||
// backend (r/w) active backend name
|
||||
// agent (r/w) active agent name
|
||||
// model (r/w) active model name
|
||||
// models (read) available models from the backend
|
||||
// models (read) available models
|
||||
// cwd (r/w) working directory
|
||||
// usage (read) token counts
|
||||
// ctxsz (read) context size vs window
|
||||
// sk/ (dir) skills
|
||||
// t/ (dir) tool scripts
|
||||
// tmp/ (dir) tool dumping ground (r/w, backed by OLLIE_TMP_PATH)
|
||||
// tr/ (dir) transcripts (ro; write to s/{id}/chat to save)
|
||||
// x/ (dir) plugins (ro, backed by ~/.config/ollie/scripts/x/)
|
||||
package p9
|
||||
// 9P filesystem server for ollie sessions.
|
||||
// See doc comment below for filesystem layout.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -49,10 +18,166 @@ import (
|
|||
olog "ollie/pkg/log"
|
||||
"ollie/pkg/paths"
|
||||
"ollie/pkg/store"
|
||||
"ollie/pkg/tools/execute"
|
||||
|
||||
"9fans.net/go/plan9"
|
||||
)
|
||||
|
||||
// Re-export core store types so existing 9p code compiles unchanged.
|
||||
type (
|
||||
ReadableStore = store.ReadableStore
|
||||
WritableStore = store.WritableStore
|
||||
ReadWriteStore = store.ReadWriteStore
|
||||
BlobStore = store.BlobStore
|
||||
Store = store.Store
|
||||
FlatDirStore = store.FlatDir
|
||||
SkillStore = store.SkillStore
|
||||
BatchStore = store.BatchStore
|
||||
BatchJobStore = store.BatchJobStore
|
||||
Session = store.Session
|
||||
SessionStore = store.SessionStore
|
||||
SessionFileStore = store.SessionFileStore
|
||||
|
||||
syntheticFileInfo = store.SyntheticFileInfo
|
||||
)
|
||||
|
||||
func NewFlatDirStore(dir string, perm os.FileMode) *FlatDirStore {
|
||||
return store.NewFlatDir(dir, perm)
|
||||
}
|
||||
|
||||
func NewSkillStore() *SkillStore {
|
||||
return store.NewSkillStore()
|
||||
}
|
||||
|
||||
func syntheticEntry(name string, mode os.FileMode) os.DirEntry {
|
||||
return store.FileEntry(name, mode)
|
||||
}
|
||||
|
||||
func syntheticDirEntry(name string, mode os.FileMode) os.DirEntry {
|
||||
return store.DirEntry(name, mode)
|
||||
}
|
||||
|
||||
// --- util ---
|
||||
|
||||
// UtilStore is a FlatDirStore backed by the scripts/u/ directory.
|
||||
type UtilStore struct {
|
||||
*FlatDirStore
|
||||
}
|
||||
|
||||
func NewUtilStore() *UtilStore {
|
||||
return &UtilStore{FlatDirStore: NewFlatDirStore(paths.CfgDir()+"/scripts/u", 0555)}
|
||||
}
|
||||
|
||||
func (s *UtilStore) Stat(name string) (os.FileInfo, error) {
|
||||
return s.FlatDirStore.Stat(name)
|
||||
}
|
||||
|
||||
func (s *UtilStore) List() ([]os.DirEntry, error) {
|
||||
return s.FlatDirStore.List()
|
||||
}
|
||||
|
||||
func (s *UtilStore) Get(name string) ([]byte, error) {
|
||||
return s.FlatDirStore.Get(name)
|
||||
}
|
||||
|
||||
// --- exec ---
|
||||
|
||||
// ExecStore is a read-only FlatDirStore backed by the scripts/x/ directory.
|
||||
type ExecStore struct {
|
||||
*FlatDirStore
|
||||
}
|
||||
|
||||
func NewExecStore() *ExecStore {
|
||||
return &ExecStore{FlatDirStore: NewFlatDirStore(execute.PluginsPath(), 0555)}
|
||||
}
|
||||
|
||||
func (s *ExecStore) Stat(name string) (os.FileInfo, error) {
|
||||
return s.FlatDirStore.Stat(name)
|
||||
}
|
||||
|
||||
func (s *ExecStore) List() ([]os.DirEntry, error) {
|
||||
return s.FlatDirStore.List()
|
||||
}
|
||||
|
||||
func (s *ExecStore) Get(name string) ([]byte, error) {
|
||||
return s.FlatDirStore.Get(name)
|
||||
}
|
||||
|
||||
// --- tools ---
|
||||
|
||||
// ToolStore is a BlobStore backed by the tools directory.
|
||||
// It extends FlatDirStore with a synthetic "idx" entry that lists all tools
|
||||
// with their descriptions and argument signatures.
|
||||
type ToolStore struct {
|
||||
*FlatDirStore
|
||||
}
|
||||
|
||||
func NewToolStore() *ToolStore {
|
||||
return &ToolStore{FlatDirStore: NewFlatDirStore(execute.ToolsPath(), 0755)}
|
||||
}
|
||||
|
||||
func (s *ToolStore) Stat(name string) (os.FileInfo, error) {
|
||||
if name == "idx" {
|
||||
return &syntheticFileInfo{Name_: "idx", Mode_: 0444}, nil
|
||||
}
|
||||
return s.FlatDirStore.Stat(name)
|
||||
}
|
||||
|
||||
func (s *ToolStore) List() ([]os.DirEntry, error) {
|
||||
entries, err := s.FlatDirStore.List()
|
||||
result := make([]os.DirEntry, 0, len(entries)+1)
|
||||
result = append(result, syntheticEntry("idx", 0444))
|
||||
result = append(result, entries...)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *ToolStore) Get(name string) ([]byte, error) {
|
||||
if name == "idx" {
|
||||
return s.index()
|
||||
}
|
||||
return s.FlatDirStore.Get(name)
|
||||
}
|
||||
|
||||
func (s *ToolStore) index() ([]byte, error) {
|
||||
entries, err := s.FlatDirStore.List()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var sb strings.Builder
|
||||
for _, e := range entries {
|
||||
if e.IsDir() {
|
||||
continue
|
||||
}
|
||||
data, err := s.FlatDirStore.Get(e.Name())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var desc, args string
|
||||
for line := range strings.SplitSeq(string(data), "\n") {
|
||||
if d, ok := strings.CutPrefix(line, "# description:"); ok {
|
||||
desc = strings.TrimSpace(d)
|
||||
} else if a, ok := strings.CutPrefix(line, "# Args:"); ok {
|
||||
args = strings.TrimSpace(a)
|
||||
} else if a, ok := strings.CutPrefix(line, "# args:"); ok {
|
||||
args = strings.TrimSpace(a)
|
||||
}
|
||||
if !strings.HasPrefix(line, "#") && line != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
if desc == "" {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(&sb, "## %s\n", e.Name())
|
||||
fmt.Fprintf(&sb, "description: %s\n", desc)
|
||||
if args != "" {
|
||||
fmt.Fprintf(&sb, "args: %s\n", args)
|
||||
}
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
return []byte(sb.String()), nil
|
||||
}
|
||||
|
||||
const (
|
||||
QTDir = plan9.QTDIR
|
||||
QTFile = plan9.QTFILE
|
||||
Reference in New Issue