Skip to content

Commit

Permalink
create kind package
Browse files Browse the repository at this point in the history
  • Loading branch information
Peyton-Spencer committed Jan 25, 2025
1 parent dbfacc7 commit e0a7a54
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 134 deletions.
30 changes: 30 additions & 0 deletions examples/chat-agent/chatagent2/ChatAgent2.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,33 @@ When the max line length is surpassed, AgentFlow will wrap the line.
This only applies to function headers. Prompt bodies are not wrapped.`)
return b.String()
}

func ConditionalPrompting(userEmail string) string {
var b strings.Builder
b.Grow(98 + len(userEmail) + 15)
b.WriteString(`This prompt demonstrates conditional prompting using optionals.
<?user.email>
The user's email is `)
b.WriteString(userEmail)
b.WriteString(`.
</user.email>`)
return b.String()
}

func ConditionalWithElse(userSubscriptionTier string) string {
var b strings.Builder
b.Grow(216 + len(userSubscriptionTier) + 103)
b.WriteString(`.var user.premium bool`)
b.WriteString(`.var user.premium bool
.var user.subscription.tier int
Here's an example with else syntax:
<?user.premium>
Welcome premium user! You have access to all features.
Your subscription tier is level `)
b.WriteString(userSubscriptionTier)
b.WriteString(`.
<else>
Welcome! You're using the basic version. Upgrade to premium for more features.
</user.premium>`)
return b.String()
}
82 changes: 82 additions & 0 deletions examples/chat-agent/ditto/ditto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package ditto

import "strings"

func SystemPrompt() string {
return `You are a friendly AI named Ditto here to help the user who is your best friend.`
}

func MainChatTemplate(
tools string,
examples string,
memoryLong string,
memoryShort string,
scriptName string,
scriptType string,
userName string,
currentTime string,
userPrompt string,
) string {
var b strings.Builder
b.Grow(233 + len(tools) + 89 + len(examples) + 287 + len(memoryLong) + 276 + len(memoryShort) + 59 + len(scriptName) + 74 + len(scriptType) + 92 + len(scriptType) + 171 + len(userName) + 34 + len(currentTime) + 16 + len(userPrompt) + 8)
b.WriteString(`The following is a conversation between an AI named Ditto and a human that are best friends. Ditto is helpful and answers factual questions correctly but maintains a friendly relationship with the human.
<?tools>
## Available Tools
`)
b.WriteString(tools)
b.WriteString(`
</tools>
<?examples>
## Examples of User Prompts that need tools:
-- Begin Examples --
`)
b.WriteString(examples)
b.WriteString(`
-- End Examples --
</examples>
## Long Term Memory
- Relevant prompt/response pairs from the user's prompt history are indexed using cosine similarity and are shown below as Long Term Memory.
Long Term Memory Buffer (most relevant prompt/response pairs):
-- Begin Long Term Memory --
`)
b.WriteString(memoryLong)
b.WriteString(`
-- End Long Term Memory --
## Short Term Memory
- The most recent prompt/response pairs are shown below as Short Term Memory. This is usually 5-10 most recent prompt/response pairs.
Short Term Memory Buffer (most recent prompt/response pairs):
-- Begin Short Term Memory --
`)
b.WriteString(memoryShort)
b.WriteString(`
-- End Short Term Memory --
<?script>
## Current Script: `)
b.WriteString(scriptName)
b.WriteString(`
- If you are reading this, that means the user is currently working on a `)
b.WriteString(scriptType)
b.WriteString(` script. Please send any requests from the user to the respective agent/tool for the user's `)
b.WriteString(scriptType)
b.WriteString(` script.
- Don't send a user's prompt to the tool if they are obviously asking you something off topic to the current script or chatting with you.
</script>
User's Name: `)
b.WriteString(userName)
b.WriteString(`
Current Time in User's Timezone: `)
b.WriteString(currentTime)
b.WriteString(`
User's Prompt: `)
b.WriteString(userPrompt)
b.WriteString(`
Ditto:
`)
return b.String()
}
16 changes: 5 additions & 11 deletions pkg/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strings"

"github.com/omniaura/agentflow/pkg/token"
"github.com/omniaura/agentflow/pkg/token/kind"
"github.com/peyton-spencer/caseconv"
"github.com/peyton-spencer/caseconv/bytcase"
)
Expand Down Expand Up @@ -91,7 +92,7 @@ func (p Prompt) Stringify(content []byte) string {
func (p Prompt) Vars(content []byte, c caseconv.Case) (vars [][]byte, length int) {
vars = make([][]byte, 0, len(p.Nodes))
for _, node := range p.Nodes {
if node.Kind == token.KindVar {
if node.Kind == kind.Var {
name := node.Get(content)
if slices.ContainsFunc(vars, func(b []byte) bool { return bytes.Equal(b, name) }) {
continue
Expand All @@ -115,21 +116,14 @@ func (p1 Prompt) Equal(p2 Prompt) bool {
return p1.Title == p2.Title && p1.Nodes.Equal(p2.Nodes)
}

func MustFile(name string, content []byte) File {
f, err := NewFile(name, content)
if err != nil {
panic(err)
}
return f
}

func NewFile(name string, content []byte) (f File, err error) {
tokens, err := token.Tokenize(content)
if err != nil {
return
}
if !strings.HasSuffix(name, ".af") {
return File{}, fmt.Errorf("file does not have .af extension: %s", name)
err = fmt.Errorf("file does not have .af extension: %s", name)
return
}
f.Name = strings.TrimSuffix(name, ".af")
f.Content = content
Expand All @@ -139,7 +133,7 @@ func NewFile(name string, content []byte) (f File, err error) {

func newPrompts(tokens token.Slice) (prompts []Prompt, err error) {
for _, t := range tokens {
if t.Kind == token.KindTitle {
if t.Kind == kind.Title {
prompts = append(prompts, Prompt{Title: t})
} else if len(prompts) == 0 {
prompts = append(prompts, Prompt{Nodes: token.Slice{t}})
Expand Down
11 changes: 6 additions & 5 deletions pkg/ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/omniaura/agentflow/pkg/assert/require"
"github.com/omniaura/agentflow/pkg/ast"
"github.com/omniaura/agentflow/pkg/token"
"github.com/omniaura/agentflow/pkg/token/kind"
)

func TestMain(m *testing.M) {
Expand Down Expand Up @@ -80,7 +81,7 @@ func TestNewFile(t *testing.T) {
Prompts: []ast.Prompt{
{
Nodes: token.Slice{
{Kind: token.KindText, Start: 0, End: len(singlePrompt)},
{Kind: kind.Text, Start: 0, End: len(singlePrompt)},
},
},
},
Expand All @@ -100,15 +101,15 @@ func TestNewFile(t *testing.T) {
Content: content,
Prompts: []ast.Prompt{
{
Title: token.T{Kind: token.KindTitle, Start: 7, End: 15},
Title: token.T{Kind: kind.Title, Start: 7, End: 15},
Nodes: token.Slice{
{Kind: token.KindText, Start: 16, End: 25},
{Kind: kind.Text, Start: 16, End: 25},
},
},
{
Title: token.T{Kind: token.KindTitle, Start: 33, End: 41},
Title: token.T{Kind: kind.Title, Start: 33, End: 41},
Nodes: token.Slice{
{Kind: token.KindText, Start: 42, End: 51},
{Kind: kind.Text, Start: 42, End: 51},
},
},
},
Expand Down
11 changes: 6 additions & 5 deletions pkg/gen/gogen/gogen.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/omniaura/agentflow/pkg/ast"
"github.com/omniaura/agentflow/pkg/gen"
"github.com/omniaura/agentflow/pkg/token"
"github.com/omniaura/agentflow/pkg/token/kind"
"github.com/peyton-spencer/caseconv"
"github.com/peyton-spencer/caseconv/bytcase"
)
Expand Down Expand Up @@ -55,7 +56,7 @@ func GenFile(w io.Writer, f ast.File) error {
p := f.Prompts[0]
vars, length := p.Vars(f.Content, caseconv.CaseCamel)
var title []byte
if p.Title.Kind == token.KindTitle {
if p.Title.Kind == kind.Title {
title = bytcase.ToCamel(p.Title.Get(f.Content))
} else {
title = bytcase.ToCamel([]byte(f.Name))
Expand All @@ -66,7 +67,7 @@ func GenFile(w io.Writer, f ast.File) error {
return err
}
for i, p := range f.Prompts {
if p.Title.Kind == token.KindUnset {
if p.Title.Kind == kind.Unset {
return gen.ErrMissingTitle.F("index: %d", i)
}
vars, length := p.Vars(f.Content, caseconv.CaseCamel)
Expand Down Expand Up @@ -111,7 +112,7 @@ func stringTemplate(buf *bytes.Buffer, toks token.Slice, content []byte) {
// Check if there are any variables
hasVars := false
for _, t := range toks {
if t.Kind == token.KindVar {
if t.Kind == kind.Var {
hasVars = true
break
}
Expand All @@ -135,7 +136,7 @@ func stringTemplate(buf *bytes.Buffer, toks token.Slice, content []byte) {
textLen := 0
hasWrittenLen := false
for _, t := range toks {
if t.Kind == token.KindVar {
if t.Kind == kind.Var {
if hasWrittenLen && textLen > 0 {
buf.WriteString(" + ")
}
Expand Down Expand Up @@ -163,7 +164,7 @@ func stringTemplate(buf *bytes.Buffer, toks token.Slice, content []byte) {

// Write the string parts
for _, t := range toks {
if t.Kind == token.KindVar {
if t.Kind == kind.Var {
buf.WriteString("\tb.WriteString(")
varName := bytcase.ToLowerCamel(t.Get(content))
buf.Write(varName)
Expand Down
7 changes: 4 additions & 3 deletions pkg/gen/js/jsgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/omniaura/agentflow/pkg/ast"
"github.com/omniaura/agentflow/pkg/gen"
"github.com/omniaura/agentflow/pkg/token"
"github.com/omniaura/agentflow/pkg/token/kind"
"github.com/peyton-spencer/caseconv"
"github.com/peyton-spencer/caseconv/bytcase"
)
Expand All @@ -36,7 +37,7 @@ func GenFile(w io.Writer, f ast.File) error {
p := f.Prompts[0]
vars, length := p.Vars(f.Content, caseconv.CaseCamel)
var title []byte
if p.Title.Kind == token.KindTitle {
if p.Title.Kind == kind.Title {
title = bytcase.ToLowerCamel(p.Title.Get(f.Content))
} else {
title = bytcase.ToLowerCamel([]byte(f.Name))
Expand All @@ -48,7 +49,7 @@ func GenFile(w io.Writer, f ast.File) error {
return err
}
for i, p := range f.Prompts {
if p.Title.Kind == token.KindUnset {
if p.Title.Kind == kind.Unset {
return gen.ErrMissingTitle.F("index: %d", i)
}
vars, length := p.Vars(f.Content, caseconv.CaseCamel)
Expand Down Expand Up @@ -103,7 +104,7 @@ func functionHeader(buf *bytes.Buffer, title []byte, stringVars [][]byte, length
func stringTemplate(buf *bytes.Buffer, toks token.Slice, content []byte) {
buf.WriteString(" return `")
for _, t := range toks {
if t.Kind == token.KindVar {
if t.Kind == kind.Var {
buf.Write(t.GetJSFmtVar(content))
} else {
buf.Write(t.Get(content))
Expand Down
9 changes: 5 additions & 4 deletions pkg/gen/py/pygen.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/omniaura/agentflow/pkg/ast"
"github.com/omniaura/agentflow/pkg/gen"
"github.com/omniaura/agentflow/pkg/token"
"github.com/omniaura/agentflow/pkg/token/kind"
"github.com/peyton-spencer/caseconv"
"github.com/peyton-spencer/caseconv/bytcase"
)
Expand All @@ -36,7 +37,7 @@ func GenFile(w io.Writer, f ast.File) error {
p := f.Prompts[0]
vars, length := p.Vars(f.Content, caseconv.CaseSnake)
var title []byte
if p.Title.Kind == token.KindTitle {
if p.Title.Kind == kind.Title {
title = bytcase.ToSnake(p.Title.Get(f.Content))
} else {
title = bytcase.ToSnake([]byte(f.Name))
Expand All @@ -52,7 +53,7 @@ func GenFile(w io.Writer, f ast.File) error {
return err
}
for i, p := range f.Prompts {
if p.Title.Kind == token.KindUnset {
if p.Title.Kind == kind.Unset {
return gen.ErrMissingTitle.F("index: %d", i)
}
vars, length := p.Vars(f.Content, caseconv.CaseSnake)
Expand Down Expand Up @@ -101,7 +102,7 @@ func stringTemplate(buf *bytes.Buffer, toks token.Slice, content []byte) {
buf.WriteRune('\n')
buf.WriteString(` return f"""`)
for _, t := range toks {
if t.Kind == token.KindVar {
if t.Kind == kind.Var {
buf.Write(t.GetWrap(content, '{', '}'))
} else {
buf.Write(t.Get(content))
Expand All @@ -115,7 +116,7 @@ func stringLiteral(buf *bytes.Buffer, toks token.Slice, content []byte) {
buf.WriteRune('\n')
buf.WriteString(` return """`)
for _, t := range toks {
if t.Kind == token.KindVar {
if t.Kind == kind.Var {
buf.Write(t.GetWrap(content, '{', '}'))
} else {
buf.Write(t.Get(content))
Expand Down
7 changes: 4 additions & 3 deletions pkg/gen/ts/tsgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/omniaura/agentflow/pkg/ast"
"github.com/omniaura/agentflow/pkg/gen"
"github.com/omniaura/agentflow/pkg/token"
"github.com/omniaura/agentflow/pkg/token/kind"
"github.com/peyton-spencer/caseconv"
"github.com/peyton-spencer/caseconv/bytcase"
)
Expand All @@ -36,7 +37,7 @@ func GenFile(w io.Writer, f ast.File) error {
p := f.Prompts[0]
vars, length := p.Vars(f.Content, caseconv.CaseCamel)
var title []byte
if p.Title.Kind == token.KindTitle {
if p.Title.Kind == kind.Title {
title = bytcase.ToLowerCamel(p.Title.Get(f.Content))
} else {
title = bytcase.ToLowerCamel([]byte(f.Name))
Expand All @@ -47,7 +48,7 @@ func GenFile(w io.Writer, f ast.File) error {
return err
}
for i, p := range f.Prompts {
if p.Title.Kind == token.KindUnset {
if p.Title.Kind == kind.Unset {
return gen.ErrMissingTitle.F("index: %d", i)
}
vars, length := p.Vars(f.Content, caseconv.CaseCamel)
Expand Down Expand Up @@ -91,7 +92,7 @@ func functionHeader(buf *bytes.Buffer, title []byte, stringVars [][]byte, length
func stringTemplate(buf *bytes.Buffer, toks token.Slice, content []byte) {
buf.WriteString("\treturn `")
for _, t := range toks {
if t.Kind == token.KindVar {
if t.Kind == kind.Var {
buf.Write(t.GetJSFmtVar(content))
} else {
buf.Write(t.Get(content))
Expand Down
Loading

0 comments on commit e0a7a54

Please sign in to comment.