-
Notifications
You must be signed in to change notification settings - Fork 1
/
program.go
86 lines (67 loc) · 2.04 KB
/
program.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package typechat
import (
"fmt"
"reflect"
"strings"
)
type Program struct {
Steps []FunctionCall
}
type FunctionCall struct {
Name string
Args []interface{}
}
const (
programSchemaInstructions = `You are a service that translates user requests into programs represented as JSON
using the following Go definitions:`
programPromptInstructions = `The following is the user request translated into a JSON object with 2 spaces of
indentation and no properties with the value undefined:`
)
type program[T any] struct {
input string
messages []Message
}
func newProgram[T any](i string) *program[T] {
return &program[T]{input: i}
}
func (b *program[T]) prompt() ([]Message, error) {
if b.messages != nil {
return b.messages, nil
}
schema := new(T)
schemaElem := reflect.TypeOf(schema).Elem()
def, err := interfaceDef(schemaElem)
if err != nil {
return nil, fmt.Errorf("failed to get definition of schema: %w", err)
}
schemaPrompt, err := b.schema(def)
if err != nil {
return nil, fmt.Errorf("failed to build schema: %w", err)
}
b.messages = append(b.messages, newSystemMessage(schemaPrompt))
b.messages = append(b.messages, newUserMessage(b.userMessage()))
b.messages = append(b.messages, newSystemMessage(b.instructions()))
return b.messages, nil
}
func (b *program[T]) userMessage() string {
var sb strings.Builder
sb.WriteString(newline("The following is a user request:"))
sb.WriteString(newline(b.input))
return sb.String()
}
func (b *program[T]) instructions() string {
return programPromptInstructions
}
func (b *program[T]) schema(def string) (string, error) {
var sb strings.Builder
sb.WriteString(newline("A program consists of a sequence of function calls that are evaluated in order."))
sb.WriteString(newline(programSchemaInstructions))
_, programDef, err := structDef(reflect.TypeOf(Program{}))
if err != nil {
return "", err
}
sb.WriteString(programDef)
sb.WriteString(newline("The programs can call functions from the API defined in the following Go definitions:"))
sb.WriteString(def)
return sb.String(), nil
}