Skip to content

Commit eee4337

Browse files
authored
enhance: add ability to get revision ID when opening file in a workspace (#93)
enhance: add ability to get revision ID when opening file in a workspace Signed-off-by: Donnie Adams <[email protected]>
1 parent 834896a commit eee4337

File tree

4 files changed

+200
-78
lines changed

4 files changed

+200
-78
lines changed

go.mod

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ module github.com/gptscript-ai/go-gptscript
33
go 1.23.0
44

55
require (
6-
github.com/getkin/kin-openapi v0.124.0
7-
github.com/stretchr/testify v1.8.4
6+
github.com/getkin/kin-openapi v0.129.0
7+
github.com/stretchr/testify v1.10.0
88
)
99

1010
require (
1111
github.com/davecgh/go-spew v1.1.1 // indirect
12-
github.com/go-openapi/jsonpointer v0.20.2 // indirect
13-
github.com/go-openapi/swag v0.22.8 // indirect
14-
github.com/invopop/yaml v0.2.0 // indirect
12+
github.com/go-openapi/jsonpointer v0.21.0 // indirect
13+
github.com/go-openapi/swag v0.23.0 // indirect
1514
github.com/josharian/intern v1.0.0 // indirect
16-
github.com/mailru/easyjson v0.7.7 // indirect
15+
github.com/mailru/easyjson v0.9.0 // indirect
1716
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
17+
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 // indirect
18+
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 // indirect
1819
github.com/perimeterx/marshmallow v1.1.5 // indirect
1920
github.com/pmezard/go-difflib v1.0.0 // indirect
2021
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,39 @@
11
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
22
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3-
github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M=
4-
github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
5-
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
6-
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
7-
github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw=
8-
github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI=
3+
github.com/getkin/kin-openapi v0.129.0 h1:QGYTNcmyP5X0AtFQ2Dkou9DGBJsUETeLH9rFrJXZh30=
4+
github.com/getkin/kin-openapi v0.129.0/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI=
5+
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
6+
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
7+
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
8+
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
99
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
1010
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
11-
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
12-
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
1311
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
1412
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
1513
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
1614
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
1715
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
1816
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
19-
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
20-
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
17+
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
18+
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
2119
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
2220
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
21+
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 h1:nZspmSkneBbtxU9TopEAE0CY+SBJLxO8LPUlw2vG4pU=
22+
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80/go.mod h1:7tFDb+Y51LcDpn26GccuUgQXUk6t0CXZsivKjyimYX8=
23+
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+7OIuqDwXbhl32HiZGpLy26BAPc=
24+
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
2325
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
2426
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
2527
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2628
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2729
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
2830
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
29-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
30-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
31+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
32+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
3133
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
3234
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
3335
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
3436
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
3537
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
36-
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3738
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
3839
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

workspace.go

+62-24
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ func (g *GPTScript) RemoveAll(ctx context.Context, opts ...RemoveAllOptions) err
147147
}
148148

149149
type WriteFileInWorkspaceOptions struct {
150-
WorkspaceID string
151-
CreateRevision *bool
152-
LatestRevision string
150+
WorkspaceID string
151+
CreateRevision *bool
152+
LatestRevisionID string
153153
}
154154

155155
func (g *GPTScript) WriteFileInWorkspace(ctx context.Context, filePath string, contents []byte, opts ...WriteFileInWorkspaceOptions) error {
@@ -161,8 +161,8 @@ func (g *GPTScript) WriteFileInWorkspace(ctx context.Context, filePath string, c
161161
if o.CreateRevision != nil {
162162
opt.CreateRevision = o.CreateRevision
163163
}
164-
if o.LatestRevision != "" {
165-
opt.LatestRevision = o.LatestRevision
164+
if o.LatestRevisionID != "" {
165+
opt.LatestRevisionID = o.LatestRevisionID
166166
}
167167
}
168168

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

173173
_, err := g.runBasicCommand(ctx, "workspaces/write-file", map[string]any{
174-
"id": opt.WorkspaceID,
175-
"contents": base64.StdEncoding.EncodeToString(contents),
176-
"filePath": filePath,
177-
"createRevision": opt.CreateRevision,
178-
"latestRevision": opt.LatestRevision,
179-
"workspaceTool": g.globalOpts.WorkspaceTool,
180-
"env": g.globalOpts.Env,
174+
"id": opt.WorkspaceID,
175+
"contents": base64.StdEncoding.EncodeToString(contents),
176+
"filePath": filePath,
177+
"createRevision": opt.CreateRevision,
178+
"latestRevisionID": opt.LatestRevisionID,
179+
"workspaceTool": g.globalOpts.WorkspaceTool,
180+
"env": g.globalOpts.Env,
181181
})
182182

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

248+
type ReadFileWithRevisionInWorkspaceResponse struct {
249+
Content []byte `json:"content"`
250+
RevisionID string `json:"revisionID"`
251+
}
252+
253+
func (g *GPTScript) ReadFileWithRevisionInWorkspace(ctx context.Context, filePath string, opts ...ReadFileInWorkspaceOptions) (*ReadFileWithRevisionInWorkspaceResponse, error) {
254+
var opt ReadFileInWorkspaceOptions
255+
for _, o := range opts {
256+
if o.WorkspaceID != "" {
257+
opt.WorkspaceID = o.WorkspaceID
258+
}
259+
}
260+
261+
if opt.WorkspaceID == "" {
262+
opt.WorkspaceID = os.Getenv("GPTSCRIPT_WORKSPACE_ID")
263+
}
264+
265+
out, err := g.runBasicCommand(ctx, "workspaces/read-file-with-revision", map[string]any{
266+
"id": opt.WorkspaceID,
267+
"filePath": filePath,
268+
"workspaceTool": g.globalOpts.WorkspaceTool,
269+
"env": g.globalOpts.Env,
270+
})
271+
if err != nil {
272+
if strings.HasSuffix(err.Error(), fmt.Sprintf("not found: %s/%s", opt.WorkspaceID, filePath)) {
273+
return nil, newNotFoundInWorkspaceError(opt.WorkspaceID, filePath)
274+
}
275+
return nil, err
276+
}
277+
278+
var resp ReadFileWithRevisionInWorkspaceResponse
279+
err = json.Unmarshal([]byte(out), &resp)
280+
if err != nil {
281+
return nil, err
282+
}
283+
284+
return &resp, nil
285+
}
286+
248287
type FileInfo struct {
249288
WorkspaceID string
250289
Name string
251290
Size int64
252291
ModTime time.Time
253292
MimeType string
293+
RevisionID string
254294
}
255295

256296
type StatFileInWorkspaceOptions struct {
257-
WorkspaceID string
297+
WorkspaceID string
298+
WithLatestRevisionID bool
258299
}
259300

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

268310
if opt.WorkspaceID == "" {
269311
opt.WorkspaceID = os.Getenv("GPTSCRIPT_WORKSPACE_ID")
270312
}
271313

272314
out, err := g.runBasicCommand(ctx, "workspaces/stat-file", map[string]any{
273-
"id": opt.WorkspaceID,
274-
"filePath": filePath,
275-
"workspaceTool": g.globalOpts.WorkspaceTool,
276-
"env": g.globalOpts.Env,
315+
"id": opt.WorkspaceID,
316+
"filePath": filePath,
317+
"withLatestRevisionID": opt.WithLatestRevisionID,
318+
"workspaceTool": g.globalOpts.WorkspaceTool,
319+
"env": g.globalOpts.Env,
277320
})
278321
if err != nil {
279322
if strings.HasSuffix(err.Error(), fmt.Sprintf("not found: %s/%s", opt.WorkspaceID, filePath)) {
@@ -291,16 +334,11 @@ func (g *GPTScript) StatFileInWorkspace(ctx context.Context, filePath string, op
291334
return info, nil
292335
}
293336

294-
type RevisionInfo struct {
295-
FileInfo
296-
RevisionID string
297-
}
298-
299337
type ListRevisionsForFileInWorkspaceOptions struct {
300338
WorkspaceID string
301339
}
302340

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

328-
var info []RevisionInfo
366+
var info []FileInfo
329367
err = json.Unmarshal([]byte(out), &info)
330368
if err != nil {
331369
return nil, err

0 commit comments

Comments
 (0)