mirror of
https://github.com/fumiama/go-onebot-agent.git
synced 2026-06-05 02:00:23 +08:00
feat: GetAction return multiple reqs
This commit is contained in:
85
README.md
85
README.md
@@ -13,55 +13,50 @@
|
||||
|
||||
## OneBot 11 协议
|
||||
> 输入输出均为 JSON 格式的一系列 Object,代表一系列事件或响应,以换行符分隔。
|
||||
> 所有可能的字段由对应的 Golang 结构体给出。
|
||||
> 所有可能的字段如下,type 由对应的 Golang 类型给出。
|
||||
|
||||
### 输入
|
||||
事件 (Event) 是输入的基本单位,
|
||||
```go
|
||||
type Event struct {
|
||||
Time int64 `json:"time"` // 事件发生的时间戳
|
||||
PostType string `json:"post_type"` // 上报类型: message / notice / request
|
||||
MessageType string `json:"message_type"` // message 类型: group / private
|
||||
SubType string `json:"sub_type"` // message 子类型: normal (一般消息) / notice (灰色小字通知)
|
||||
MessageID int64 `json:"message_id"` // 消息 ID, 唯一标识该事件
|
||||
GroupID int64 `json:"group_id"` // QQ群号
|
||||
UserID int64 `json:"user_id"` // 事件发送者QQ号
|
||||
TargetID int64 `json:"target_id"`
|
||||
SelfID int64 `json:"self_id"` // 收到事件的QQ号 (你的ID)
|
||||
NoticeType string `json:"notice_type,omitempty"`
|
||||
OperatorID int64 `json:"operator_id"` // This field is used for Notice Event
|
||||
File *File `json:"file,omitempty"`
|
||||
RequestType string `json:"request_type,omitempty"`
|
||||
Flag string `json:"flag,omitempty"`
|
||||
Comment string `json:"comment,omitempty"` // This field is used for Request Event
|
||||
Sender *User `json:"sender,omitempty"` // 事件发送者个人信息
|
||||
Message json.RawMessage `json:"message,omitempty"` // JSON 格式的消息内容
|
||||
}
|
||||
```
|
||||
|key|type|说明|
|
||||
|---|---|---|
|
||||
|time|int64|事件发生的时间戳|
|
||||
|post_type|string|上报类型: message / notice / request|
|
||||
|message_type|string|message 类型: group / private|
|
||||
|sub_type|string|message 子类型: normal (一般消息) / notice (灰色小字通知)|
|
||||
|message_id|int64|消息 ID, 唯一标识该事件|
|
||||
|group_id|int64|QQ群号|
|
||||
|user_id|int64|事件发送者QQ号|
|
||||
|target_id|int64|后述|
|
||||
|self_id|int64|收到事件的QQ号 (你的ID)|
|
||||
|notice_type|string|后述|
|
||||
|operator_id|int64|For Notice Event|
|
||||
|file|*File|后述|
|
||||
|request_type|string|后述|
|
||||
|flag|string|后述|
|
||||
|comment|string|For Request Event|
|
||||
|sender|*User|事件发送者个人信息|
|
||||
|message|json.RawMessage|JSON 格式的消息内容|
|
||||
|
||||
其中,文件 (File) 标识一个聊天文件,
|
||||
```go
|
||||
type File struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
BusID int64 `json:"busid"`
|
||||
}
|
||||
```
|
||||
|key|type|
|
||||
|---|---|
|
||||
|id|string|
|
||||
|name|string|
|
||||
|size|int64|
|
||||
|
||||
用户 (User) 标识一个QQ用户,
|
||||
```go
|
||||
type User struct {
|
||||
ID int64 `json:"user_id"`
|
||||
NickName string `json:"nickname"`
|
||||
Sex string `json:"sex"` // "male"、"female"、"unknown"
|
||||
Age int `json:"age"`
|
||||
Area string `json:"area"` // 地区
|
||||
// 以下为群聊特有字段
|
||||
Card string `json:"card"` // 群名片/备注
|
||||
Title string `json:"title"` // 专属头衔
|
||||
Level string `json:"level"` // 群聊等级
|
||||
Role string `json:"role"` // "owner"、"admin"、"member"
|
||||
}
|
||||
```
|
||||
|key|type|说明|
|
||||
|---|---|---|
|
||||
|user_id|int64|用户QQ号|
|
||||
|nickname|string|昵称|
|
||||
|sex|string|"male"、"female"、"unknown"|
|
||||
|age|int|年龄|
|
||||
|area|string|地区|
|
||||
|card|string|群名片/备注(群聊特有)|
|
||||
|title|string|专属头衔(群聊特有)|
|
||||
|level|string|群聊等级(群聊特有)|
|
||||
|role|string|"owner"、"admin"、"member"(群聊特有)|
|
||||
|
||||
#### 详细事件种类
|
||||
|
||||
|类型|post_type|message_type|sub_type|message_id|group_id|user_id|target_id|self_id|notice_type|operator_id|file|request_type|flag|comment|sender|message|
|
||||
@@ -113,4 +108,4 @@ type User struct {
|
||||
```
|
||||
你可以调用的全部 API 如下表。注意:即使之前的记录显示你曾调用过某 API,但如果现在列表中不存在此 API,你就不能调用。
|
||||
|
||||
%v
|
||||
%v
|
||||
55
agent.go
55
agent.go
@@ -4,7 +4,7 @@ package goba
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/fumiama/deepinfra"
|
||||
"github.com/fumiama/deepinfra/chat"
|
||||
@@ -26,16 +26,23 @@ type Agent struct {
|
||||
nickname, sex string
|
||||
chars string
|
||||
perm *Perm
|
||||
manualaddreq bool
|
||||
}
|
||||
|
||||
// NewAgent characteristics 最好是 MD 格式, defaultprompt 是上下文为空时的默认项, 建议为 Event JSON
|
||||
// NewAgent 创建一个 Agent 实例。
|
||||
//
|
||||
// - characteristics 推荐使用 Markdown 格式,描述 Agent 个性。
|
||||
// - defaultprompt 为上下文为空时的默认提示,建议为事件的 JSON,一般不会用到,因此也可留空。
|
||||
// - manualaddreq 表示是否由用户手动添加请求。
|
||||
func NewAgent(
|
||||
id int64, batchcap, itemscap int,
|
||||
nickname, sex, characteristics, defaultprompt string,
|
||||
manualaddreq bool,
|
||||
) (ag Agent) {
|
||||
ag = Agent{
|
||||
id: id, nickname: nickname, sex: sex, chars: characteristics,
|
||||
log: chat.NewLog[fmt.Stringer](batchcap, itemscap, "\n", defaultprompt),
|
||||
log: chat.NewLog[fmt.Stringer](batchcap, itemscap, "\n", defaultprompt),
|
||||
manualaddreq: manualaddreq,
|
||||
}
|
||||
_ = ag.LoadPermTable()
|
||||
return
|
||||
@@ -55,16 +62,12 @@ func (ag *Agent) AddRequest(grp int64, req *zero.APIRequest) {
|
||||
//
|
||||
// Note:
|
||||
//
|
||||
// 1. The response may be empty, meaning that LLM do not want
|
||||
// to react with these events. In this case, this function will
|
||||
// return io.EOF and the context will be left no change.
|
||||
//
|
||||
// 2. If LLM returns an invalid action, ErrPermissionDenied will be returned
|
||||
// with complete req, caller may decide whether to use this req by themselves.
|
||||
// Whatever, this req will not be added into the context. You may call
|
||||
// AddRequest to add it but it is not recommended.
|
||||
// - If LLM returns an invalid action, ErrPermissionDenied will be returned
|
||||
// with complete reqs before invalid call, caller may decide whether to use
|
||||
// these reqs by themselves. Whatever, invalid req will not be added into
|
||||
// the context. You may call AddRequest to add it but it is not recommended.
|
||||
func (ag *Agent) GetAction(api deepinfra.API, p model.Protocol, grp int64, role PermRole, isusersystem bool) (
|
||||
req zero.APIRequest, err error,
|
||||
reqs []zero.APIRequest, err error,
|
||||
) {
|
||||
sysp, err := ag.system(role)
|
||||
if err != nil {
|
||||
@@ -77,15 +80,25 @@ func (ag *Agent) GetAction(api deepinfra.API, p model.Protocol, grp int64, role
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal([]byte(resp), &req)
|
||||
if err == nil && req.Action == "" {
|
||||
err = io.EOF
|
||||
}
|
||||
|
||||
if !ag.perm.allow(role, req.Action) {
|
||||
err = errors.Wrap(ErrPermissionDenied, req.Action)
|
||||
} else {
|
||||
ag.AddRequest(grp, &req)
|
||||
reqs = make([]zero.APIRequest, 0, 2)
|
||||
dec := json.NewDecoder(strings.NewReader(resp))
|
||||
for dec.More() {
|
||||
r := zero.APIRequest{}
|
||||
err = dec.Decode(&r)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if r.Action == "" {
|
||||
continue
|
||||
}
|
||||
switch {
|
||||
case !ag.perm.allow(role, r.Action):
|
||||
err = errors.Wrap(ErrPermissionDenied, r.Action)
|
||||
return
|
||||
case !ag.manualaddreq:
|
||||
ag.AddRequest(grp, &r)
|
||||
}
|
||||
reqs = append(reqs, r)
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
18
types.go
18
types.go
@@ -10,17 +10,17 @@ import (
|
||||
|
||||
// Event is the simplified OneBot event that dumped to the agent in JSON format
|
||||
type Event struct {
|
||||
Time int64 `json:"time"` // 事件发生的时间戳
|
||||
PostType string `json:"post_type"` // 上报类型: message / notice / request
|
||||
MessageType string `json:"message_type"` // message 类型: group / private
|
||||
SubType string `json:"sub_type"` // message 子类型: normal (一般消息) / notice (灰色小字通知)
|
||||
MessageID int64 `json:"message_id"` // 消息 ID, 唯一标识该事件
|
||||
GroupID int64 `json:"group_id"` // QQ群号
|
||||
UserID int64 `json:"user_id"` // 事件发送者QQ号
|
||||
TargetID int64 `json:"target_id"`
|
||||
Time int64 `json:"time"` // 事件发生的时间戳
|
||||
PostType string `json:"post_type"` // 上报类型: message / notice / request
|
||||
MessageType string `json:"message_type"` // message 类型: group / private
|
||||
SubType string `json:"sub_type,omitempty"` // message 子类型: normal (一般消息) / notice (灰色小字通知)
|
||||
MessageID int64 `json:"message_id"` // 消息 ID, 唯一标识该事件
|
||||
GroupID int64 `json:"group_id,omitempty"` // QQ群号
|
||||
UserID int64 `json:"user_id"` // 事件发送者QQ号
|
||||
TargetID int64 `json:"target_id,omitempty"`
|
||||
SelfID int64 `json:"self_id"` // 收到事件的QQ号 (你的ID)
|
||||
NoticeType string `json:"notice_type,omitempty"`
|
||||
OperatorID int64 `json:"operator_id"` // This field is used for Notice Event
|
||||
OperatorID int64 `json:"operator_id,omitempty"` // This field is used for Notice Event
|
||||
File *zero.File `json:"file,omitempty"`
|
||||
RequestType string `json:"request_type,omitempty"`
|
||||
Flag string `json:"flag,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user