Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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