Skip to content

Commit 5e20ec1

Browse files
bug: String() is unsafe, so rename to Print() and make a safer version
The syntax of GPTScript is not well defined enough to safely parse at the moment. :/
1 parent 552dad3 commit 5e20ec1

File tree

11 files changed

+38
-97
lines changed

11 files changed

+38
-97
lines changed

pkg/assemble/assemble.go

-17
This file was deleted.

pkg/auth/auth.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func Authorize(ctx engine.Context, input string) (runner.AuthorizerResponse, err
2323

2424
var result bool
2525
err := survey.AskOne(&survey.Confirm{
26-
Help: fmt.Sprintf("The full source of the tools is as follows:\n\n%s", ctx.Tool.String()),
26+
Help: fmt.Sprintf("The full source of the tools is as follows:\n\n%s", ctx.Tool.Print()),
2727
Default: true,
2828
Message: ConfirmMessage(ctx, input),
2929
}, &result)

pkg/cli/fmt.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ func (e *Fmt) Run(_ *cobra.Command, args []string) error {
4343
}
4444

4545
if e.Write && loc != "" {
46-
return os.WriteFile(loc, []byte(doc.String()), 0644)
46+
return os.WriteFile(loc, []byte(doc.Print()), 0644)
4747
}
4848

49-
fmt.Print(doc.String())
49+
fmt.Print(doc.Print())
5050
return nil
5151
}

pkg/cli/gptscript.go

-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"github.com/fatih/color"
1515
"github.com/gptscript-ai/cmd"
1616
gptscript2 "github.com/gptscript-ai/go-gptscript"
17-
"github.com/gptscript-ai/gptscript/pkg/assemble"
1817
"github.com/gptscript-ai/gptscript/pkg/auth"
1918
"github.com/gptscript-ai/gptscript/pkg/builtin"
2019
"github.com/gptscript-ai/gptscript/pkg/cache"
@@ -58,7 +57,6 @@ type GPTScript struct {
5857
// Input should not be using GPTSCRIPT_INPUT env var because that is the same value that is set in tool executions
5958
Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f" env:"GPTSCRIPT_INPUT_FILE"`
6059
SubTool string `usage:"Use tool of this name, not the first tool in file" local:"true"`
61-
Assemble bool `usage:"Assemble tool to a single artifact, saved to --output" hidden:"true" local:"true"`
6260
ListModels bool `usage:"List the models available and exit" local:"true"`
6361
ListTools bool `usage:"List built-in tools and exit" local:"true"`
6462
ListenAddress string `usage:"Server listen address" default:"127.0.0.1:0" hidden:"true"`
@@ -439,20 +437,6 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) (retErr error) {
439437
return cmd.Help()
440438
}
441439

442-
if r.Assemble {
443-
var out io.Writer = os.Stdout
444-
if r.Output != "" && r.Output != "-" {
445-
f, err := os.Create(r.Output)
446-
if err != nil {
447-
return fmt.Errorf("opening %s: %w", r.Output, err)
448-
}
449-
defer f.Close()
450-
out = f
451-
}
452-
453-
return assemble.Assemble(prg, out)
454-
}
455-
456440
toolInput, err := input.FromCLI(r.Input, args)
457441
if err != nil {
458442
return err

pkg/loader/loader.go

+13-44
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717

1818
"github.com/getkin/kin-openapi/openapi3"
1919
"github.com/gptscript-ai/gptscript/internal"
20-
"github.com/gptscript-ai/gptscript/pkg/assemble"
2120
"github.com/gptscript-ai/gptscript/pkg/builtin"
2221
"github.com/gptscript-ai/gptscript/pkg/cache"
2322
"github.com/gptscript-ai/gptscript/pkg/hash"
@@ -132,36 +131,6 @@ func loadLocal(base *source, name string) (*source, bool, error) {
132131
}, true, nil
133132
}
134133

135-
func loadProgram(data []byte, into *types.Program, targetToolName, defaultModel string) (types.Tool, error) {
136-
var ext types.Program
137-
138-
if err := json.Unmarshal(data[len(assemble.Header):], &ext); err != nil {
139-
return types.Tool{}, err
140-
}
141-
142-
into.ToolSet = make(map[string]types.Tool, len(ext.ToolSet))
143-
for k, v := range ext.ToolSet {
144-
if builtinTool, ok := builtin.DefaultModel(k, defaultModel); ok {
145-
v = builtinTool
146-
}
147-
into.ToolSet[k] = v
148-
}
149-
150-
tool := into.ToolSet[ext.EntryToolID]
151-
if targetToolName == "" {
152-
return tool, nil
153-
}
154-
155-
tool, ok := into.ToolSet[tool.LocalTools[strings.ToLower(targetToolName)]]
156-
if !ok {
157-
return tool, &types.ErrToolNotFound{
158-
ToolName: targetToolName,
159-
}
160-
}
161-
162-
return tool, nil
163-
}
164-
165134
func loadOpenAPI(prg *types.Program, data []byte) *openapi3.T {
166135
var (
167136
openAPICacheKey = hash.Digest(data)
@@ -189,14 +158,6 @@ func loadOpenAPI(prg *types.Program, data []byte) *openapi3.T {
189158
func readTool(ctx context.Context, cache *cache.Client, prg *types.Program, base *source, targetToolName, defaultModel string) ([]types.Tool, error) {
190159
data := base.Content
191160

192-
if bytes.HasPrefix(data, assemble.Header) {
193-
tool, err := loadProgram(data, prg, targetToolName, defaultModel)
194-
if err != nil {
195-
return nil, err
196-
}
197-
return []types.Tool{tool}, nil
198-
}
199-
200161
var (
201162
tools []types.Tool
202163
isOpenAPI bool
@@ -231,11 +192,19 @@ func readTool(ctx context.Context, cache *cache.Client, prg *types.Program, base
231192
// If we didn't get any tools from trying to parse it as OpenAPI, try to parse it as a GPTScript
232193
if len(tools) == 0 {
233194
var err error
234-
tools, err = parser.ParseTools(bytes.NewReader(data), parser.Options{
235-
AssignGlobals: true,
236-
})
237-
if err != nil {
238-
return nil, err
195+
_, marshaled, ok := strings.Cut(string(data), "#!GPTSCRIPT")
196+
if ok {
197+
err = json.Unmarshal([]byte(marshaled), &tools)
198+
if err != nil {
199+
return nil, fmt.Errorf("error parsing marshalled script: %w", err)
200+
}
201+
} else {
202+
tools, err = parser.ParseTools(bytes.NewReader(data), parser.Options{
203+
AssignGlobals: true,
204+
})
205+
if err != nil {
206+
return nil, err
207+
}
239208
}
240209
}
241210

pkg/parser/parser.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ func writeSep(buf *strings.Builder, lastText bool) {
263263
}
264264
}
265265

266-
func (d Document) String() string {
266+
func (d Document) Print() string {
267267
buf := strings.Builder{}
268268
lastText := false
269269
for _, node := range d.Nodes {
@@ -274,7 +274,7 @@ func (d Document) String() string {
274274
}
275275
if node.ToolNode != nil {
276276
writeSep(&buf, lastText)
277-
buf.WriteString(node.ToolNode.Tool.String())
277+
buf.WriteString(node.ToolNode.Tool.Print())
278278
lastText = false
279279
}
280280
}

pkg/parser/parser_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ body
304304
!metadata:first:package.json
305305
foo=base
306306
f
307-
`).Equal(t, tools[0].String())
307+
`).Equal(t, tools[0].Print())
308308
}
309309

310310
func TestFormatWithBadInstruction(t *testing.T) {
@@ -316,9 +316,9 @@ func TestFormatWithBadInstruction(t *testing.T) {
316316
Instructions: "foo: bar",
317317
},
318318
}
319-
autogold.Expect("Name: foo\n===\nfoo: bar\n").Equal(t, input.String())
319+
autogold.Expect("Name: foo\n===\nfoo: bar\n").Equal(t, input.Print())
320320

321-
tools, err := ParseTools(strings.NewReader(input.String()))
321+
tools, err := ParseTools(strings.NewReader(input.Print()))
322322
require.NoError(t, err)
323323
if reflect.DeepEqual(input, tools[0]) {
324324
t.Errorf("expected %v, got %v", input, tools[0])

pkg/sdkserver/routes.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (s *server) listTools(w http.ResponseWriter, r *http.Request) {
114114
// Don't print instructions
115115
tool.Instructions = ""
116116

117-
lines = append(lines, tool.String())
117+
lines = append(lines, tool.Print())
118118
}
119119

120120
writeResponse(logger, w, map[string]any{"stdout": strings.Join(lines, "\n---\n")})
@@ -339,5 +339,5 @@ func (s *server) fmtDocument(w http.ResponseWriter, r *http.Request) {
339339
return
340340
}
341341

342-
writeResponse(logger, w, map[string]string{"stdout": doc.String()})
342+
writeResponse(logger, w, map[string]string{"stdout": doc.Print()})
343343
}

pkg/sdkserver/types.go

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package sdkserver
22

33
import (
4+
"encoding/json"
45
"maps"
5-
"strings"
66
"time"
77

88
"github.com/gptscript-ai/gptscript/pkg/cache"
@@ -30,15 +30,12 @@ const (
3030
type toolDefs []types.ToolDef
3131

3232
func (t toolDefs) String() string {
33-
s := new(strings.Builder)
34-
for i, tool := range t {
35-
s.WriteString(tool.String())
36-
if i != len(t)-1 {
37-
s.WriteString("\n\n---\n\n")
38-
}
33+
data, err := json.Marshal(t)
34+
if err != nil {
35+
panic(err)
3936
}
4037

41-
return s.String()
38+
return "#!GPTSCRIPT" + string(data)
4239
}
4340

4441
type (

pkg/types/tool.go

+8
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,14 @@ func (t Tool) GetToolRefsFromNames(names []string) (result []ToolReference, _ er
389389
}
390390

391391
func (t ToolDef) String() string {
392+
data, err := json.Marshal([]any{t})
393+
if err != nil {
394+
panic(err)
395+
}
396+
return "#!GPTSCRIPT" + string(data)
397+
}
398+
399+
func (t ToolDef) Print() string {
392400
buf := &strings.Builder{}
393401
if t.Parameters.GlobalModelName != "" {
394402
_, _ = fmt.Fprintf(buf, "Global Model Name: %s\n", t.Parameters.GlobalModelName)

pkg/types/tool_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"github.com/hexops/autogold/v2"
77
)
88

9-
func TestToolDef_String(t *testing.T) {
9+
func TestToolDef_Print(t *testing.T) {
1010
tool := ToolDef{
1111
Parameters: Parameters{
1212
Name: "Tool Sample",
@@ -82,7 +82,7 @@ This is a sample instruction
8282
// blah blah some ugly JSON
8383
}
8484
85-
`).Equal(t, tool.String())
85+
`).Equal(t, tool.Print())
8686
}
8787

8888
// float32Ptr is used to return a pointer to a given float32 value

0 commit comments

Comments
 (0)