[add] Neo enter command mode by typing the /name

This commit is contained in:
Max 2023-05-12 13:20:09 +08:00
parent 46ad1e761c
commit 4bb5fca430
7 changed files with 87 additions and 15 deletions

View file

@ -2,6 +2,8 @@ package command
import (
"fmt"
"regexp"
"strings"
"github.com/yaoapp/gou/connector"
"github.com/yaoapp/yao/aigc"
@ -12,6 +14,8 @@ import (
// DefaultStore the default store driver
var DefaultStore Store
var recmd, _ = regexp.Compile(`^\/([a-zA-Z]+) +`)
var reCmdOnly, _ = regexp.Compile(`^\/([a-zA-Z]+)$`)
// SetStore the driver interface
func SetStore(store Store) {
@ -31,6 +35,21 @@ func Match(sid string, query query.Param, input string) (string, error) {
return cid, nil
}
// Match the command use the command ID
match := reCmdOnly.FindSubmatch([]byte(strings.TrimSpace(input)))
if match == nil {
match = recmd.FindSubmatch([]byte(strings.TrimSpace(input)))
}
if match != nil {
key := fmt.Sprintf("[Index]%s", match[1])
fmt.Println("Match Index:", key)
if cmd, ok := DefaultStore.Get(key); ok {
fmt.Println("Match Command:", cmd.ID)
return cmd.ID, nil
}
}
return DefaultStore.Match(query, input)
}
@ -60,13 +79,24 @@ func (cmd *Command) save() error {
})
}
return DefaultStore.Set(cmd.ID, driver.Command{
data := driver.Command{
ID: cmd.ID,
Use: cmd.Use,
Description: cmd.Description,
Args: args,
Stack: cmd.Stack,
Path: cmd.Path,
})
}
if cmd.Use != "" {
key := fmt.Sprintf("[Index]%s", cmd.Use)
err := DefaultStore.Set(key, data)
if err != nil {
return err
}
}
return DefaultStore.Set(cmd.ID, data)
}
// NewAI create a new AI

View file

@ -60,6 +60,7 @@ func (driver *Memory) Match(query query.Param, content string) (string, error) {
has = true
bytes, err := jsoniter.Marshal(map[string]interface{}{
"id": cmd.ID,
"use": cmd.Use,
"name": cmd.Name,
"description": cmd.Description,
"args": cmd.Args,
@ -118,19 +119,19 @@ func (driver *Memory) Match(query query.Param, content string) (string, error) {
}
// Set Set the command data
func (driver *Memory) Set(id string, cmd Command) error {
commands.Store(id, cmd)
func (driver *Memory) Set(key string, cmd Command) error {
commands.Store(key, cmd)
return nil
}
// Del delete the command data
func (driver *Memory) Del(id string) {
commands.Delete(id)
func (driver *Memory) Del(key string) {
commands.Delete(key)
}
// Get the command data
func (driver *Memory) Get(id string) (Command, bool) {
v, ok := commands.Load(id)
func (driver *Memory) Get(key string) (Command, bool) {
v, ok := commands.Load(key)
if !ok {
return Command{}, false
}

View file

@ -10,6 +10,7 @@ type Request struct {
// Command the command struct
type Command struct {
ID string `json:"-" yaml:"-"`
Use string `json:"use,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Args []map[string]interface{} `json:"args,omitempty"`

View file

@ -10,6 +10,8 @@ import (
v8 "github.com/yaoapp/gou/runtime/v8"
"github.com/yaoapp/kun/log"
"github.com/yaoapp/kun/maps"
"github.com/yaoapp/kun/utils"
"github.com/yaoapp/yao/config"
"github.com/yaoapp/yao/neo/conversation"
"github.com/yaoapp/yao/neo/message"
"rogchap.com/v8go"
@ -18,18 +20,46 @@ import (
// Run the command
func (req *Request) Run(messages []map[string]interface{}, cb func(msg *message.JSON) int) error {
// Enter the command mode
if input, ok := messages[len(messages)-1]["content"].(string); ok {
match := reCmdOnly.FindSubmatch([]byte(strings.TrimSpace(input)))
if match != nil {
fmt.Printf("Match Command: %s | %s\n", match[1], input)
cb(req.msg().Text("Enter the command Mode"))
cb(req.msg().Done())
return nil
}
}
if config.Conf.Mode == "development" {
utils.Dump("----Request Run ----")
fmt.Printf("Command Request: %s %s\n", req.Command.ID, req.sid)
fmt.Printf("Command Process: %s\n", req.Command.Process)
fmt.Printf("Command Prepare Before: %s\n", req.Command.Prepare.Before)
fmt.Printf("Command Prepare Before: %s\n", req.Command.Prepare.After)
}
input, err := req.prepare(messages, cb)
if err != nil {
req.error(err, cb)
return err
}
if config.Conf.Mode == "development" {
utils.Dump("----Input After Prepare ----", input)
}
args, err := req.parseArgs(input, cb)
if err != nil {
cb(req.msg().Text("\n\n" + err.Error()))
cb(req.msg().Done())
return nil
}
if config.Conf.Mode == "development" {
utils.Dump("---- Command Args ----", args)
}
// Send the command to the service
if req.Command.Optional.Confirm != "" {
req.confirm(args, cb)
@ -167,6 +197,10 @@ func (req *Request) parseArgs(input interface{}, cb func(msg *message.JSON) int)
// RunPrepare the command
func (req *Request) prepare(messages []map[string]interface{}, cb func(msg *message.JSON) int) (interface{}, error) {
if config.Conf.Mode == "development" {
utils.Dump("----Messages Before Prepare ----", messages)
}
// Before hook
data, err := req.prepareBefore(messages, cb)
if err != nil {
@ -198,6 +232,10 @@ func (req *Request) prepare(messages []map[string]interface{}, cb func(msg *mess
return nil, err
}
if config.Conf.Mode == "development" {
utils.Dump("----Command Prompts ----", chatMessages)
}
// chat with AI
content := []byte{}
_, ex := req.AI.ChatCompletionsWith(req.ctx, chatMessages, req.Prepare.Option, func(data []byte) int {
@ -281,7 +319,7 @@ func (req *Request) saveHistory(content []byte, messages []map[string]interface{
func (req *Request) error(err error, cb func(msg *message.JSON) int) {
cb(req.msg().Text(err.Error()))
cb(message.New().Done())
req.Done()
// req.Done()
}
func (req *Request) question(messages []map[string]interface{}) (string, error) {

View file

@ -23,6 +23,7 @@ type Request struct {
type Command struct {
ID string `json:"-" yaml:"-"`
Name string `json:"name,omitempty"`
Use string `json:"use,omitempty"`
Connector string `json:"connector"`
Process string `json:"process"`
Prepare Prepare `json:"prepare"`
@ -77,9 +78,9 @@ type Context struct {
// Store the command driver
type Store interface {
Match(query query.Param, content string) (string, error)
Set(id string, cmd driver.Command) error
Get(id string) (driver.Command, bool)
Del(id string)
Set(key string, cmd driver.Command) error
Get(key string) (driver.Command, bool)
Del(key string)
SetRequest(sid, id, cid string) error
GetRequest(sid string) (string, string, bool)
DelRequest(sid string)

View file

@ -251,9 +251,9 @@ func (neo *DSL) matchCommand(ctx command.Context, messages []map[string]interfac
return nil, false
}
name, err := command.Match(ctx.Sid, query.Param{Stack: ctx.Stack, Path: ctx.Path}, input)
if err == nil && name != "" {
cmd, isCommand := command.Commands[name]
id, err := command.Match(ctx.Sid, query.Param{Stack: ctx.Stack, Path: ctx.Path}, input)
if err == nil && id != "" {
cmd, isCommand := command.Commands[id]
return cmd, isCommand
}

View file

@ -11,6 +11,7 @@ import (
type DSL struct {
ID string `json:"-" yaml:"-"`
Name string `json:"name,omitempty"`
Use string `json:"use,omitempty"`
Guard string `json:"guard,omitempty"`
Connector string `json:"connector"`
ConversationSetting conversation.Setting `json:"conversation" yaml:"conversation"`