98 lines
4.3 KiB
Go
98 lines
4.3 KiB
Go
// Package grpc adapts sandboxfs.Toolbox onto the generated
|
|
// workspacev1.WorkspaceServiceServer interface. Every RPC here either
|
|
// replaces one agent tool (internal/llm/tools.go) or one human-facing
|
|
// files-panel endpoint (internal/handlers/files.go) from the monolith —
|
|
// see each method's doc comment.
|
|
package grpc
|
|
|
|
import (
|
|
"context"
|
|
|
|
workspacev1 "enkly/gen/workspace/v1"
|
|
"enkly/services/workspace/internal/infrastructure/sandboxfs"
|
|
)
|
|
|
|
type Server struct {
|
|
workspacev1.UnimplementedWorkspaceServiceServer
|
|
Toolbox *sandboxfs.Toolbox
|
|
}
|
|
|
|
func New(tb *sandboxfs.Toolbox) *Server { return &Server{Toolbox: tb} }
|
|
|
|
func (s *Server) ReadFile(ctx context.Context, req *workspacev1.ReadFileRequest) (*workspacev1.ReadFileResponse, error) {
|
|
res := s.Toolbox.ReadFile(req.GetPath(), int(req.GetOffset()), int(req.GetLimit()))
|
|
if res.IsError {
|
|
return &workspacev1.ReadFileResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.ReadFileResponse{Content: res.Content}, nil
|
|
}
|
|
|
|
func (s *Server) WriteFile(ctx context.Context, req *workspacev1.WriteFileRequest) (*workspacev1.WriteFileResponse, error) {
|
|
res := s.Toolbox.WriteFile(req.GetPath(), req.GetContent())
|
|
if res.IsError {
|
|
return &workspacev1.WriteFileResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.WriteFileResponse{BytesWritten: int64(len(req.GetContent()))}, nil
|
|
}
|
|
|
|
func (s *Server) EditFile(ctx context.Context, req *workspacev1.EditFileRequest) (*workspacev1.EditFileResponse, error) {
|
|
res := s.Toolbox.EditFile(req.GetPath(), req.GetOldString(), req.GetNewString(), req.GetReplaceAll())
|
|
if res.IsError {
|
|
return &workspacev1.EditFileResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.EditFileResponse{DiffPreview: res.Content}, nil
|
|
}
|
|
|
|
func (s *Server) MultiEditFile(ctx context.Context, req *workspacev1.MultiEditFileRequest) (*workspacev1.MultiEditFileResponse, error) {
|
|
edits := make([]sandboxfs.WorkspaceEdit, 0, len(req.GetEdits()))
|
|
for _, e := range req.GetEdits() {
|
|
edits = append(edits, sandboxfs.WorkspaceEdit{
|
|
OldString: e.GetOldString(), NewString: e.GetNewString(), ReplaceAll: e.GetReplaceAll(),
|
|
})
|
|
}
|
|
res := s.Toolbox.MultiEditFile(req.GetPath(), edits)
|
|
if res.IsError {
|
|
return &workspacev1.MultiEditFileResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.MultiEditFileResponse{DiffPreview: res.Content}, nil
|
|
}
|
|
|
|
func (s *Server) ListDirectory(ctx context.Context, req *workspacev1.ListDirectoryRequest) (*workspacev1.ListDirectoryResponse, error) {
|
|
res := s.Toolbox.ListDirectory(req.GetPath())
|
|
if res.IsError {
|
|
return &workspacev1.ListDirectoryResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.ListDirectoryResponse{Listing: res.Content}, nil
|
|
}
|
|
|
|
func (s *Server) GlobSearch(ctx context.Context, req *workspacev1.GlobSearchRequest) (*workspacev1.GlobSearchResponse, error) {
|
|
res := s.Toolbox.GlobSearch(req.GetPattern(), req.GetPath())
|
|
if res.IsError {
|
|
return &workspacev1.GlobSearchResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.GlobSearchResponse{Output: res.Content}, nil
|
|
}
|
|
|
|
func (s *Server) Grep(ctx context.Context, req *workspacev1.GrepRequest) (*workspacev1.GrepResponse, error) {
|
|
res := s.Toolbox.Grep(req.GetPattern(), req.GetPath(), req.GetGlob(), req.GetCaseInsensitive())
|
|
if res.IsError {
|
|
return &workspacev1.GrepResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.GrepResponse{Output: res.Content}, nil
|
|
}
|
|
|
|
// RunBashCommand replaces the run_bash_command tool. req.TimeoutSeconds
|
|
// is accepted but not applied per-call — the monolith's sandbox only
|
|
// ever used one process-wide timeout (ENKLY_BASH_TIMEOUT_SECONDS /
|
|
// Toolbox.CommandTimeout, set once at startup; see cmd/server/main.go),
|
|
// and a per-call override wasn't a feature of the original tool, so
|
|
// introducing one here would be a behavior change, not a neutral
|
|
// restructuring.
|
|
func (s *Server) RunBashCommand(ctx context.Context, req *workspacev1.RunBashCommandRequest) (*workspacev1.RunBashCommandResponse, error) {
|
|
res := s.Toolbox.RunBashCommand(ctx, req.GetCommand())
|
|
if res.IsError {
|
|
return &workspacev1.RunBashCommandResponse{IsError: true, ErrorMessage: res.Content}, nil
|
|
}
|
|
return &workspacev1.RunBashCommandResponse{Output: res.Content}, nil
|
|
}
|