Allow to initiate new conversations
This commit is contained in:
35
action/newconversation.go
Normal file
35
action/newconversation.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package action
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sashabaranov/go-openai/jsonschema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ConversationActionName = "new_conversation"
|
||||||
|
|
||||||
|
func NewConversation() *ConversationAction {
|
||||||
|
return &ConversationAction{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConversationAction struct{}
|
||||||
|
|
||||||
|
type ConversationActionResponse struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ConversationAction) Run(ActionParams) (string, error) {
|
||||||
|
return "no-op", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ConversationAction) Definition() ActionDefinition {
|
||||||
|
return ActionDefinition{
|
||||||
|
Name: ConversationActionName,
|
||||||
|
Description: "Use this tool to initiate a new conversation or to notify something.",
|
||||||
|
Properties: map[string]jsonschema.Definition{
|
||||||
|
"message": {
|
||||||
|
Type: jsonschema.String,
|
||||||
|
Description: "The message to start the conversation",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Required: []string{"message"},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -137,10 +137,17 @@ func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act
|
|||||||
|
|
||||||
func (a *Agent) systemInternalActions() Actions {
|
func (a *Agent) systemInternalActions() Actions {
|
||||||
if a.options.enableHUD {
|
if a.options.enableHUD {
|
||||||
return append(a.options.userActions, action.NewState(), action.NewReply())
|
return append(a.options.userActions,
|
||||||
|
action.NewState(), action.NewReply())
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(a.options.userActions, action.NewReply())
|
if a.options.initiateConversations && a.selfEvaluationInProgress { // && self-evaluation..
|
||||||
|
return append(a.options.userActions,
|
||||||
|
action.NewState(), action.NewReply(), action.NewConversation())
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(a.options.userActions,
|
||||||
|
action.NewReply())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) prepareHUD() PromptHUD {
|
func (a *Agent) prepareHUD() PromptHUD {
|
||||||
|
|||||||
@@ -27,10 +27,13 @@ type Agent struct {
|
|||||||
actionContext *action.ActionContext
|
actionContext *action.ActionContext
|
||||||
context *action.ActionContext
|
context *action.ActionContext
|
||||||
|
|
||||||
currentReasoning string
|
currentReasoning string
|
||||||
currentState *action.StateResult
|
currentState *action.StateResult
|
||||||
nextAction Action
|
nextAction Action
|
||||||
currentConversation []openai.ChatCompletionMessage
|
currentConversation []openai.ChatCompletionMessage
|
||||||
|
selfEvaluationInProgress bool
|
||||||
|
|
||||||
|
newConversations chan openai.ChatCompletionMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(opts ...Option) (*Agent, error) {
|
func New(opts ...Option) (*Agent, error) {
|
||||||
@@ -180,13 +183,21 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
// Set the action context
|
// Set the action context
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
a.actionContext = action.NewContext(ctx, cancel)
|
a.actionContext = action.NewContext(ctx, cancel)
|
||||||
|
a.selfEvaluationInProgress = selfEvaluation
|
||||||
a.Unlock()
|
a.Unlock()
|
||||||
|
|
||||||
if job.Image != "" {
|
if selfEvaluation {
|
||||||
// TODO: Use llava to explain the image content
|
defer func() {
|
||||||
|
a.Lock()
|
||||||
|
a.selfEvaluationInProgress = false
|
||||||
|
a.Unlock()
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if job.Image != "" {
|
||||||
|
// TODO: Use llava to explain the image content
|
||||||
|
//}
|
||||||
|
|
||||||
if job.Text != "" {
|
if job.Text != "" {
|
||||||
a.currentConversation = append(a.currentConversation, openai.ChatCompletionMessage{
|
a.currentConversation = append(a.currentConversation, openai.ChatCompletionMessage{
|
||||||
Role: role,
|
Role: role,
|
||||||
@@ -265,6 +276,32 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if selfEvaluation && a.options.initiateConversations &&
|
||||||
|
chosenAction.Definition().Name.Is(action.ConversationActionName) {
|
||||||
|
|
||||||
|
message := action.ConversationActionResponse{}
|
||||||
|
if err := params.actionParams.Unmarshal(&message); err != nil {
|
||||||
|
job.Result.Finish(fmt.Errorf("error unmarshalling conversation response: %w", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
a.currentConversation = []openai.ChatCompletionMessage{
|
||||||
|
{
|
||||||
|
Role: "assistant",
|
||||||
|
Content: message.Message,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
a.newConversations <- openai.ChatCompletionMessage{
|
||||||
|
Role: "assistant",
|
||||||
|
Content: message.Message,
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
job.Result.SetResponse("decided to initiate a new conversation")
|
||||||
|
job.Result.Finish(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// If we don't have to reply , run the action!
|
// If we don't have to reply , run the action!
|
||||||
if !chosenAction.Definition().Name.Is(action.ReplyActionName) {
|
if !chosenAction.Definition().Name.Is(action.ReplyActionName) {
|
||||||
result, err := a.runAction(chosenAction, params)
|
result, err := a.runAction(chosenAction, params)
|
||||||
@@ -411,6 +448,13 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) periodicallyRun() {
|
func (a *Agent) periodicallyRun() {
|
||||||
|
// This is running in the background.
|
||||||
|
|
||||||
|
// TODO: Would be nice if we have a special action to
|
||||||
|
// contact the user. This would actually make sure that
|
||||||
|
// if the agent wants to initiate a conversation, it can do so.
|
||||||
|
// This would be a special action that would be picked up by the agent
|
||||||
|
// and would be used to contact the user.
|
||||||
|
|
||||||
if a.options.debugMode {
|
if a.options.debugMode {
|
||||||
fmt.Println("START -- Periodically run is starting")
|
fmt.Println("START -- Periodically run is starting")
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ type options struct {
|
|||||||
userActions Actions
|
userActions Actions
|
||||||
enableHUD, standaloneJob, showCharacter bool
|
enableHUD, standaloneJob, showCharacter bool
|
||||||
debugMode bool
|
debugMode bool
|
||||||
|
initiateConversations bool
|
||||||
characterfile string
|
characterfile string
|
||||||
statefile string
|
statefile string
|
||||||
context context.Context
|
context context.Context
|
||||||
@@ -64,6 +65,11 @@ var EnableHUD = func(o *options) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var EnableInitiateConversations = func(o *options) error {
|
||||||
|
o.initiateConversations = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var DebugMode = func(o *options) error {
|
var DebugMode = func(o *options) error {
|
||||||
o.debugMode = true
|
o.debugMode = true
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user