package main
import (
"elefant/models"
"fmt"
"regexp"
"strings"
"time"
)
var (
toolCallRE = regexp.MustCompile(`__tool_call__\s*([\s\S]*?)__tool_call__`)
quotesRE = regexp.MustCompile(`(".*?")`)
starRE = regexp.MustCompile(`(\*.*?\*)`)
thinkRE = regexp.MustCompile(`(.*?)`)
codeBlockRE = regexp.MustCompile(`(?s)\x60{3}(?:.*?)\n(.*?)\n\s*\x60{3}\s*`)
basicSysMsg = `Large Language Model that helps user with any of his requests.`
toolSysMsg = `You can do functions call if needed.
Your current tools:
[
{
"name":"recall",
"args": "topic",
"when_to_use": "when asked about topic that user previously asked to memorise"
},
{
"name":"memorise",
"args": ["topic", "info"],
"when_to_use": "when asked to memorise something"
},
{
"name":"recall_topics",
"args": null,
"when_to_use": "to see what topics are saved in memory"
}
]
To make a function call return a json object within __tool_call__ tags;
__tool_call__
{
"name":"recall",
"args": "Adam's number"
}
__tool_call__
Tool call is addressed to the tool agent, avoid sending more info than tool call itself, while making a call.
When done right, tool call will be delivered to the tool agent. tool agent will respond with the results of the call.
tool:
under the topic: Adam's number is stored:
559-996
After that you are free to respond to the user.
`
basicCard = &models.CharCard{
SysPrompt: basicSysMsg,
FirstMsg: defaultFirstMsg,
Role: "",
FilePath: "",
}
toolCard = &models.CharCard{
SysPrompt: toolSysMsg,
FirstMsg: defaultFirstMsg,
Role: "",
FilePath: "",
}
// sysMap = map[string]string{"basic_sys": basicSysMsg, "tool_sys": toolSysMsg}
sysMap = map[string]*models.CharCard{"basic_sys": basicCard, "tool_sys": toolCard}
sysLabels = []string{"basic_sys", "tool_sys"}
)
/*
consider cases:
- append mode (treat it like a journal appendix)
- replace mode (new info/mind invalidates old ones)
also:
- some writing can be done without consideration of previous data;
- others do;
*/
func memorise(args ...string) []byte {
agent := cfg.AssistantRole
if len(args) < 2 {
msg := "not enough args to call memorise tool; need topic and data to remember"
logger.Error(msg)
return []byte(msg)
}
memory := &models.Memory{
Agent: agent,
Topic: args[0],
Mind: args[1],
UpdatedAt: time.Now(),
}
if _, err := store.Memorise(memory); err != nil {
logger.Error("failed to save memory", "err", err, "memoory", memory)
return []byte("failed to save info")
}
msg := "info saved under the topic:" + args[0]
return []byte(msg)
}
func recall(args ...string) []byte {
agent := cfg.AssistantRole
if len(args) < 1 {
logger.Warn("not enough args to call recall tool")
return nil
}
mind, err := store.Recall(agent, args[0])
if err != nil {
msg := fmt.Sprintf("failed to recall; error: %v; args: %v", err, args)
logger.Error(msg)
return []byte(msg)
}
answer := fmt.Sprintf("under the topic: %s is stored:\n%s", args[0], mind)
return []byte(answer)
}
func recallTopics(args ...string) []byte {
agent := cfg.AssistantRole
topics, err := store.RecallTopics(agent)
if err != nil {
logger.Error("failed to use tool", "error", err, "args", args)
return nil
}
joinedS := strings.Join(topics, ";")
return []byte(joinedS)
}
// func fullMemoryLoad() {}
type fnSig func(...string) []byte
var fnMap = map[string]fnSig{
"recall": recall,
"recall_topics": recallTopics,
"memorise": memorise,
}