Skip to content

Commit

Permalink
feat: simplify the workspace API and add support for s3 (#878)
Browse files Browse the repository at this point in the history
Signed-off-by: Donnie Adams <[email protected]>
  • Loading branch information
thedadams authored Oct 17, 2024
1 parent 419ccbb commit c3a3279
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 72 deletions.
3 changes: 1 addition & 2 deletions pkg/sdkserver/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ func (s *server) addRoutes(mux *http.ServeMux) {
mux.HandleFunc("POST /workspaces/create", s.createWorkspace)
mux.HandleFunc("POST /workspaces/delete", s.deleteWorkspace)
mux.HandleFunc("POST /workspaces/list", s.listWorkspaceContents)
mux.HandleFunc("POST /workspaces/mkdir", s.mkDirInWorkspace)
mux.HandleFunc("POST /workspaces/rmdir", s.rmDirInWorkspace)
mux.HandleFunc("POST /workspaces/remove-all-with-prefix", s.removeAllWithPrefixInWorkspace)
mux.HandleFunc("POST /workspaces/write-file", s.writeFileInWorkspace)
mux.HandleFunc("POST /workspaces/delete-file", s.removeFileInWorkspace)
mux.HandleFunc("POST /workspaces/read-file", s.readFileInWorkspace)
Expand Down
94 changes: 24 additions & 70 deletions pkg/sdkserver/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import (
)

type workspaceCommonRequest struct {
ID string `json:"id"`
WorkspaceTool string `json:"workspaceTool"`
ID string `json:"id"`
WorkspaceTool string `json:"workspaceTool"`
Env []string `json:"env"`
}

func (w workspaceCommonRequest) getToolRepo() string {
Expand Down Expand Up @@ -50,7 +51,7 @@ func (s *server) createWorkspace(w http.ResponseWriter, r *http.Request) {
out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
reqObject.Env,
fmt.Sprintf(
`{"provider": "%s", "data_home": "%s", "workspace_ids": "%s"}`,
reqObject.ProviderType, reqObject.DirectoryDataHome, strings.Join(reqObject.FromWorkspaceIDs, ","),
Expand Down Expand Up @@ -85,7 +86,7 @@ func (s *server) deleteWorkspace(w http.ResponseWriter, r *http.Request) {
out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
reqObject.Env,
fmt.Sprintf(
`{"workspace_id": "%s"}`,
reqObject.ID,
Expand All @@ -102,10 +103,7 @@ func (s *server) deleteWorkspace(w http.ResponseWriter, r *http.Request) {
type listWorkspaceContentsRequest struct {
workspaceCommonRequest `json:",inline"`
ID string `json:"id"`
SubDir string `json:"subDir"`
NonRecursive bool `json:"nonRecursive"`
ExcludeHidden bool `json:"excludeHidden"`
JSON bool `json:"json"`
Prefix string `json:"prefix"`
}

func (s *server) listWorkspaceContents(w http.ResponseWriter, r *http.Request) {
Expand All @@ -125,10 +123,10 @@ func (s *server) listWorkspaceContents(w http.ResponseWriter, r *http.Request) {
out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
reqObject.Env,
fmt.Sprintf(
`{"workspace_id": "%s", "ls_sub_dir": "%s", "ls_non_recursive": %t, "ls_exclude_hidden": %t, "ls_json": %t}`,
reqObject.ID, reqObject.SubDir, reqObject.NonRecursive, reqObject.ExcludeHidden, reqObject.JSON,
`{"workspace_id": "%s", "ls_prefix": "%s"}`,
reqObject.ID, reqObject.Prefix,
),
)
if err != nil {
Expand All @@ -139,22 +137,20 @@ func (s *server) listWorkspaceContents(w http.ResponseWriter, r *http.Request) {
writeResponse(logger, w, map[string]any{"stdout": out})
}

type mkDirRequest struct {
type removeAllWithPrefixInWorkspaceRequest struct {
workspaceCommonRequest `json:",inline"`
DirectoryName string `json:"directoryName"`
IgnoreExists bool `json:"ignoreExists"`
CreateDirs bool `json:"createDirs"`
Prefix string `json:"prefix"`
}

func (s *server) mkDirInWorkspace(w http.ResponseWriter, r *http.Request) {
func (s *server) removeAllWithPrefixInWorkspace(w http.ResponseWriter, r *http.Request) {
logger := gcontext.GetLogger(r.Context())
var reqObject mkDirRequest
var reqObject removeAllWithPrefixInWorkspaceRequest
if err := json.NewDecoder(r.Body).Decode(&reqObject); err != nil {
writeError(logger, w, http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err))
return
}

prg, err := loader.Program(r.Context(), reqObject.getToolRepo(), "Create Directory In Workspace", loader.Options{Cache: s.client.Cache})
prg, err := loader.Program(r.Context(), reqObject.getToolRepo(), "Remove All With Prefix In Workspace", loader.Options{Cache: s.client.Cache})
if err != nil {
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to load program: %w", err))
return
Expand All @@ -163,48 +159,10 @@ func (s *server) mkDirInWorkspace(w http.ResponseWriter, r *http.Request) {
out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
reqObject.Env,
fmt.Sprintf(
`{"workspace_id": "%s", "directory_name": "%s", "mk_dir_ignore_exists": %t, "mk_dir_create_dirs": %t}`,
reqObject.ID, reqObject.DirectoryName, reqObject.IgnoreExists, reqObject.CreateDirs,
),
)
if err != nil {
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to run program: %w", err))
return
}

writeResponse(logger, w, map[string]any{"stdout": out})
}

type rmDirRequest struct {
workspaceCommonRequest `json:",inline"`
DirectoryName string `json:"directoryName"`
IgnoreNotFound bool `json:"ignoreNotFound"`
MustBeEmpty bool `json:"mustBeEmpty"`
}

func (s *server) rmDirInWorkspace(w http.ResponseWriter, r *http.Request) {
logger := gcontext.GetLogger(r.Context())
var reqObject rmDirRequest
if err := json.NewDecoder(r.Body).Decode(&reqObject); err != nil {
writeError(logger, w, http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err))
return
}

prg, err := loader.Program(r.Context(), reqObject.getToolRepo(), "Remove Directory In Workspace", loader.Options{Cache: s.client.Cache})
if err != nil {
writeError(logger, w, http.StatusInternalServerError, fmt.Errorf("failed to load program: %w", err))
return
}

out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
fmt.Sprintf(
`{"workspace_id": "%s", "directory_name": "%s", "ignore_not_found": %t, "rm_dir_must_be_empty": %t}`,
reqObject.ID, reqObject.DirectoryName, reqObject.IgnoreNotFound, reqObject.MustBeEmpty,
`{"workspace_id": "%s", "prefix": "%s"}`,
reqObject.ID, reqObject.Prefix,
),
)
if err != nil {
Expand All @@ -220,9 +178,6 @@ type writeFileInWorkspaceRequest struct {
FilePath string `json:"filePath"`
Contents string `json:"contents"`
Base64EncodedInput bool `json:"base64EncodedInput"`
MustNotExist bool `json:"mustNotExist"`
CreateDirs bool `json:"createDirs"`
WithoutCreate bool `json:"withoutCreate"`
}

func (s *server) writeFileInWorkspace(w http.ResponseWriter, r *http.Request) {
Expand All @@ -242,10 +197,10 @@ func (s *server) writeFileInWorkspace(w http.ResponseWriter, r *http.Request) {
out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
reqObject.Env,
fmt.Sprintf(
`{"workspace_id": "%s", "file_path": "%s", "file_contents": "%s", "write_file_must_not_exist": %t, "write_file_create_dirs": %t, "write_file_without_create": %t, "write_file_base64_encoded_input": %t}`,
reqObject.ID, reqObject.FilePath, reqObject.Contents, reqObject.MustNotExist, reqObject.CreateDirs, reqObject.WithoutCreate, reqObject.Base64EncodedInput,
`{"workspace_id": "%s", "file_path": "%s", "file_contents": "%s", "write_file_base64_encoded_input": %t}`,
reqObject.ID, reqObject.FilePath, reqObject.Contents, reqObject.Base64EncodedInput,
),
)
if err != nil {
Expand All @@ -259,7 +214,6 @@ func (s *server) writeFileInWorkspace(w http.ResponseWriter, r *http.Request) {
type rmFileInWorkspaceRequest struct {
workspaceCommonRequest `json:",inline"`
FilePath string `json:"filePath"`
IgnoreNotFound bool `json:"ignoreNotFound"`
}

func (s *server) removeFileInWorkspace(w http.ResponseWriter, r *http.Request) {
Expand All @@ -279,10 +233,10 @@ func (s *server) removeFileInWorkspace(w http.ResponseWriter, r *http.Request) {
out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
reqObject.Env,
fmt.Sprintf(
`{"workspace_id": "%s", "file_path": "%s", "ignore_not_found": %t}`,
reqObject.ID, reqObject.FilePath, reqObject.IgnoreNotFound,
`{"workspace_id": "%s", "file_path": "%s"}`,
reqObject.ID, reqObject.FilePath,
),
)
if err != nil {
Expand Down Expand Up @@ -316,7 +270,7 @@ func (s *server) readFileInWorkspace(w http.ResponseWriter, r *http.Request) {
out, err := s.client.Run(
r.Context(),
prg,
s.gptscriptOpts.Env,
reqObject.Env,
fmt.Sprintf(
`{"workspace_id": "%s", "file_path": "%s", "read_file_base64_encode_output": %t}`,
reqObject.ID, reqObject.FilePath, reqObject.Base64EncodeOutput,
Expand Down

0 comments on commit c3a3279

Please sign in to comment.