Skip to content

Commit

Permalink
enhance: add ability to get revision ID when opening file in a worksp…
Browse files Browse the repository at this point in the history
…ace (#93)

enhance: add ability to get revision ID when opening file in a workspace

Signed-off-by: Donnie Adams <[email protected]>
  • Loading branch information
thedadams authored Feb 22, 2025
1 parent 834896a commit eee4337
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 78 deletions.
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ module github.com/gptscript-ai/go-gptscript
go 1.23.0

require (
github.com/getkin/kin-openapi v0.124.0
github.com/stretchr/testify v1.8.4
github.com/getkin/kin-openapi v0.129.0
github.com/stretchr/testify v1.10.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/swag v0.22.8 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 // indirect
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
27 changes: 14 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M=
github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw=
github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI=
github.com/getkin/kin-openapi v0.129.0 h1:QGYTNcmyP5X0AtFQ2Dkou9DGBJsUETeLH9rFrJXZh30=
github.com/getkin/kin-openapi v0.129.0/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 h1:nZspmSkneBbtxU9TopEAE0CY+SBJLxO8LPUlw2vG4pU=
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80/go.mod h1:7tFDb+Y51LcDpn26GccuUgQXUk6t0CXZsivKjyimYX8=
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+7OIuqDwXbhl32HiZGpLy26BAPc=
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
86 changes: 62 additions & 24 deletions workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ func (g *GPTScript) RemoveAll(ctx context.Context, opts ...RemoveAllOptions) err
}

type WriteFileInWorkspaceOptions struct {
WorkspaceID string
CreateRevision *bool
LatestRevision string
WorkspaceID string
CreateRevision *bool
LatestRevisionID string
}

func (g *GPTScript) WriteFileInWorkspace(ctx context.Context, filePath string, contents []byte, opts ...WriteFileInWorkspaceOptions) error {
Expand All @@ -161,8 +161,8 @@ func (g *GPTScript) WriteFileInWorkspace(ctx context.Context, filePath string, c
if o.CreateRevision != nil {
opt.CreateRevision = o.CreateRevision
}
if o.LatestRevision != "" {
opt.LatestRevision = o.LatestRevision
if o.LatestRevisionID != "" {
opt.LatestRevisionID = o.LatestRevisionID
}
}

Expand All @@ -171,13 +171,13 @@ func (g *GPTScript) WriteFileInWorkspace(ctx context.Context, filePath string, c
}

_, err := g.runBasicCommand(ctx, "workspaces/write-file", map[string]any{
"id": opt.WorkspaceID,
"contents": base64.StdEncoding.EncodeToString(contents),
"filePath": filePath,
"createRevision": opt.CreateRevision,
"latestRevision": opt.LatestRevision,
"workspaceTool": g.globalOpts.WorkspaceTool,
"env": g.globalOpts.Env,
"id": opt.WorkspaceID,
"contents": base64.StdEncoding.EncodeToString(contents),
"filePath": filePath,
"createRevision": opt.CreateRevision,
"latestRevisionID": opt.LatestRevisionID,
"workspaceTool": g.globalOpts.WorkspaceTool,
"env": g.globalOpts.Env,
})

return parsePossibleConflictInWorkspaceError(err)
Expand Down Expand Up @@ -245,16 +245,57 @@ func (g *GPTScript) ReadFileInWorkspace(ctx context.Context, filePath string, op
return base64.StdEncoding.DecodeString(out)
}

type ReadFileWithRevisionInWorkspaceResponse struct {
Content []byte `json:"content"`
RevisionID string `json:"revisionID"`
}

func (g *GPTScript) ReadFileWithRevisionInWorkspace(ctx context.Context, filePath string, opts ...ReadFileInWorkspaceOptions) (*ReadFileWithRevisionInWorkspaceResponse, error) {
var opt ReadFileInWorkspaceOptions
for _, o := range opts {
if o.WorkspaceID != "" {
opt.WorkspaceID = o.WorkspaceID
}
}

if opt.WorkspaceID == "" {
opt.WorkspaceID = os.Getenv("GPTSCRIPT_WORKSPACE_ID")
}

out, err := g.runBasicCommand(ctx, "workspaces/read-file-with-revision", map[string]any{
"id": opt.WorkspaceID,
"filePath": filePath,
"workspaceTool": g.globalOpts.WorkspaceTool,
"env": g.globalOpts.Env,
})
if err != nil {
if strings.HasSuffix(err.Error(), fmt.Sprintf("not found: %s/%s", opt.WorkspaceID, filePath)) {
return nil, newNotFoundInWorkspaceError(opt.WorkspaceID, filePath)
}
return nil, err
}

var resp ReadFileWithRevisionInWorkspaceResponse
err = json.Unmarshal([]byte(out), &resp)
if err != nil {
return nil, err
}

return &resp, nil
}

type FileInfo struct {
WorkspaceID string
Name string
Size int64
ModTime time.Time
MimeType string
RevisionID string
}

type StatFileInWorkspaceOptions struct {
WorkspaceID string
WorkspaceID string
WithLatestRevisionID bool
}

func (g *GPTScript) StatFileInWorkspace(ctx context.Context, filePath string, opts ...StatFileInWorkspaceOptions) (FileInfo, error) {
Expand All @@ -263,17 +304,19 @@ func (g *GPTScript) StatFileInWorkspace(ctx context.Context, filePath string, op
if o.WorkspaceID != "" {
opt.WorkspaceID = o.WorkspaceID
}
opt.WithLatestRevisionID = opt.WithLatestRevisionID || o.WithLatestRevisionID
}

if opt.WorkspaceID == "" {
opt.WorkspaceID = os.Getenv("GPTSCRIPT_WORKSPACE_ID")
}

out, err := g.runBasicCommand(ctx, "workspaces/stat-file", map[string]any{
"id": opt.WorkspaceID,
"filePath": filePath,
"workspaceTool": g.globalOpts.WorkspaceTool,
"env": g.globalOpts.Env,
"id": opt.WorkspaceID,
"filePath": filePath,
"withLatestRevisionID": opt.WithLatestRevisionID,
"workspaceTool": g.globalOpts.WorkspaceTool,
"env": g.globalOpts.Env,
})
if err != nil {
if strings.HasSuffix(err.Error(), fmt.Sprintf("not found: %s/%s", opt.WorkspaceID, filePath)) {
Expand All @@ -291,16 +334,11 @@ func (g *GPTScript) StatFileInWorkspace(ctx context.Context, filePath string, op
return info, nil
}

type RevisionInfo struct {
FileInfo
RevisionID string
}

type ListRevisionsForFileInWorkspaceOptions struct {
WorkspaceID string
}

func (g *GPTScript) ListRevisionsForFileInWorkspace(ctx context.Context, filePath string, opts ...ListRevisionsForFileInWorkspaceOptions) ([]RevisionInfo, error) {
func (g *GPTScript) ListRevisionsForFileInWorkspace(ctx context.Context, filePath string, opts ...ListRevisionsForFileInWorkspaceOptions) ([]FileInfo, error) {
var opt ListRevisionsForFileInWorkspaceOptions
for _, o := range opts {
if o.WorkspaceID != "" {
Expand All @@ -325,7 +363,7 @@ func (g *GPTScript) ListRevisionsForFileInWorkspace(ctx context.Context, filePat
return nil, err
}

var info []RevisionInfo
var info []FileInfo
err = json.Unmarshal([]byte(out), &info)
if err != nil {
return nil, err
Expand Down
Loading

0 comments on commit eee4337

Please sign in to comment.