wfz 2 gadi atpakaļ
vecāks
revīzija
f8d67334cb
9 mainītis faili ar 2711 papildinājumiem un 0 dzēšanām
  1. 1565 0
      api/ai/ai.pb.go
  2. 175 0
      api/ai/ai.proto
  3. 370 0
      api/ai/ai_grpc.pb.go
  4. 389 0
      api/ai/ai_http.pb.go
  5. 19 0
      client/ai.go
  6. 8 0
      define/ai.go
  7. 7 0
      errors/ai.go
  8. 49 0
      js/api/ai/ai_http_pb.ts
  9. 129 0
      js/api/ai/ai_pb.ts

+ 1565 - 0
api/ai/ai.pb.go

@@ -0,0 +1,1565 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.1-devel
+// 	protoc        v3.21.8
+// source: ai.proto
+
+package ai
+
+import (
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+	_ "google.golang.org/protobuf/types/known/structpb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type AIRobotIDReply struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id"`
+}
+
+func (x *AIRobotIDReply) Reset() {
+	*x = AIRobotIDReply{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AIRobotIDReply) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AIRobotIDReply) ProtoMessage() {}
+
+func (x *AIRobotIDReply) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AIRobotIDReply.ProtoReflect.Descriptor instead.
+func (*AIRobotIDReply) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *AIRobotIDReply) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+type AIRecordListReply struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	List   []*AIRecordInfo `protobuf:"bytes,1,rep,name=list,proto3" json:"list"`
+	NextId int64           `protobuf:"varint,2,opt,name=nextId,proto3" json:"nextId"`
+}
+
+func (x *AIRecordListReply) Reset() {
+	*x = AIRecordListReply{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AIRecordListReply) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AIRecordListReply) ProtoMessage() {}
+
+func (x *AIRecordListReply) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AIRecordListReply.ProtoReflect.Descriptor instead.
+func (*AIRecordListReply) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *AIRecordListReply) GetList() []*AIRecordInfo {
+	if x != nil {
+		return x.List
+	}
+	return make([]*AIRecordInfo, 0)
+}
+
+func (x *AIRecordListReply) GetNextId() int64 {
+	if x != nil {
+		return x.NextId
+	}
+	return 0
+}
+
+type AIRecordInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	MessageId int64    `protobuf:"varint,1,opt,name=messageId,proto3" json:"messageId"` // 消息的ID
+	MsgType   string   `protobuf:"bytes,2,opt,name=msgType,proto3" json:"msgType"`      // 消息类型
+	Message   *Message `protobuf:"bytes,3,opt,name=message,proto3" json:"message"`      // 消息的结构
+	RobotId   int64    `protobuf:"varint,4,opt,name=robotId,proto3" json:"robotId"`     // 机器人ID
+	IsSelf    bool     `protobuf:"varint,5,opt,name=isSelf,proto3" json:"isSelf"`       // 是否是自己
+	SendTime  int64    `protobuf:"varint,6,opt,name=sendTime,proto3" json:"sendTime"`   // 发送时间
+	Status    string   `protobuf:"bytes,7,opt,name=status,proto3" json:"status"`        // 消息状态
+	StatusMsg string   `protobuf:"bytes,8,opt,name=statusMsg,proto3" json:"statusMsg"`  // 状态说明
+}
+
+func (x *AIRecordInfo) Reset() {
+	*x = AIRecordInfo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AIRecordInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AIRecordInfo) ProtoMessage() {}
+
+func (x *AIRecordInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AIRecordInfo.ProtoReflect.Descriptor instead.
+func (*AIRecordInfo) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *AIRecordInfo) GetMessageId() int64 {
+	if x != nil {
+		return x.MessageId
+	}
+	return 0
+}
+
+func (x *AIRecordInfo) GetMsgType() string {
+	if x != nil {
+		return x.MsgType
+	}
+	return ""
+}
+
+func (x *AIRecordInfo) GetMessage() *Message {
+	if x != nil && x.Message != nil {
+		return x.Message
+	}
+	return &Message{}
+}
+
+func (x *AIRecordInfo) GetRobotId() int64 {
+	if x != nil {
+		return x.RobotId
+	}
+	return 0
+}
+
+func (x *AIRecordInfo) GetIsSelf() bool {
+	if x != nil {
+		return x.IsSelf
+	}
+	return false
+}
+
+func (x *AIRecordInfo) GetSendTime() int64 {
+	if x != nil {
+		return x.SendTime
+	}
+	return 0
+}
+
+func (x *AIRecordInfo) GetStatus() string {
+	if x != nil {
+		return x.Status
+	}
+	return ""
+}
+
+func (x *AIRecordInfo) GetStatusMsg() string {
+	if x != nil {
+		return x.StatusMsg
+	}
+	return ""
+}
+
+type Message struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content"` // 文本内容
+}
+
+func (x *Message) Reset() {
+	*x = Message{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Message) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Message) ProtoMessage() {}
+
+func (x *Message) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Message.ProtoReflect.Descriptor instead.
+func (*Message) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *Message) GetContent() string {
+	if x != nil {
+		return x.Content
+	}
+	return ""
+}
+
+type SendAIChatRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id      int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id"`
+	Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message"` // 消息
+}
+
+func (x *SendAIChatRequest) Reset() {
+	*x = SendAIChatRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendAIChatRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendAIChatRequest) ProtoMessage() {}
+
+func (x *SendAIChatRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SendAIChatRequest.ProtoReflect.Descriptor instead.
+func (*SendAIChatRequest) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *SendAIChatRequest) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *SendAIChatRequest) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type FindAIChatRecordListRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NextId int64 `protobuf:"varint,1,opt,name=nextId,proto3" json:"nextId"`
+	Offset int64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset"`
+	Id     int64 `protobuf:"varint,3,opt,name=id,proto3" json:"id"`
+}
+
+func (x *FindAIChatRecordListRequest) Reset() {
+	*x = FindAIChatRecordListRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindAIChatRecordListRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindAIChatRecordListRequest) ProtoMessage() {}
+
+func (x *FindAIChatRecordListRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindAIChatRecordListRequest.ProtoReflect.Descriptor instead.
+func (*FindAIChatRecordListRequest) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *FindAIChatRecordListRequest) GetNextId() int64 {
+	if x != nil {
+		return x.NextId
+	}
+	return 0
+}
+
+func (x *FindAIChatRecordListRequest) GetOffset() int64 {
+	if x != nil {
+		return x.Offset
+	}
+	return 0
+}
+
+func (x *FindAIChatRecordListRequest) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+type AIRobotList struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NextId int64          `protobuf:"varint,1,opt,name=nextId,proto3" json:"nextId"`
+	List   []*AIRobotInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list"`
+}
+
+func (x *AIRobotList) Reset() {
+	*x = AIRobotList{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AIRobotList) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AIRobotList) ProtoMessage() {}
+
+func (x *AIRobotList) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AIRobotList.ProtoReflect.Descriptor instead.
+func (*AIRobotList) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *AIRobotList) GetNextId() int64 {
+	if x != nil {
+		return x.NextId
+	}
+	return 0
+}
+
+func (x *AIRobotList) GetList() []*AIRobotInfo {
+	if x != nil {
+		return x.List
+	}
+	return make([]*AIRobotInfo, 0)
+}
+
+type AIRobotInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id            int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id"`
+	Name          string `protobuf:"bytes,2,opt,name=name,proto3" json:"name"`                   // ai名称
+	AvatarUrl     string `protobuf:"bytes,3,opt,name=avatarUrl,proto3" json:"avatarUrl"`         // ai头像
+	Sex           int64  `protobuf:"varint,4,opt,name=sex,proto3" json:"sex"`                    // ai性别
+	Age           int64  `protobuf:"varint,5,opt,name=age,proto3" json:"age"`                    // ai年龄
+	Constellation string `protobuf:"bytes,6,opt,name=constellation,proto3" json:"constellation"` // ai星座
+	LastTime      int64  `protobuf:"varint,7,opt,name=lastTime,proto3" json:"lastTime"`          // 上次发送时间
+	LastContent   string `protobuf:"bytes,8,opt,name=lastContent,proto3" json:"lastContent"`     // 上次发送的内容
+	UnreadNum     int64  `protobuf:"varint,9,opt,name=unreadNum,proto3" json:"unreadNum"`        // 未读
+	Status        string `protobuf:"bytes,10,opt,name=status,proto3" json:"status"`              // 状态
+	CreateTime    int64  `protobuf:"varint,11,opt,name=createTime,proto3" json:"createTime"`     // 创建时间
+}
+
+func (x *AIRobotInfo) Reset() {
+	*x = AIRobotInfo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AIRobotInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AIRobotInfo) ProtoMessage() {}
+
+func (x *AIRobotInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AIRobotInfo.ProtoReflect.Descriptor instead.
+func (*AIRobotInfo) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *AIRobotInfo) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *AIRobotInfo) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *AIRobotInfo) GetAvatarUrl() string {
+	if x != nil {
+		return x.AvatarUrl
+	}
+	return ""
+}
+
+func (x *AIRobotInfo) GetSex() int64 {
+	if x != nil {
+		return x.Sex
+	}
+	return 0
+}
+
+func (x *AIRobotInfo) GetAge() int64 {
+	if x != nil {
+		return x.Age
+	}
+	return 0
+}
+
+func (x *AIRobotInfo) GetConstellation() string {
+	if x != nil {
+		return x.Constellation
+	}
+	return ""
+}
+
+func (x *AIRobotInfo) GetLastTime() int64 {
+	if x != nil {
+		return x.LastTime
+	}
+	return 0
+}
+
+func (x *AIRobotInfo) GetLastContent() string {
+	if x != nil {
+		return x.LastContent
+	}
+	return ""
+}
+
+func (x *AIRobotInfo) GetUnreadNum() int64 {
+	if x != nil {
+		return x.UnreadNum
+	}
+	return 0
+}
+
+func (x *AIRobotInfo) GetStatus() string {
+	if x != nil {
+		return x.Status
+	}
+	return ""
+}
+
+func (x *AIRobotInfo) GetCreateTime() int64 {
+	if x != nil {
+		return x.CreateTime
+	}
+	return 0
+}
+
+type FindAIRobotListRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NextId int64 `protobuf:"varint,1,opt,name=nextId,proto3" json:"nextId"`
+	Offset int64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset"`
+}
+
+func (x *FindAIRobotListRequest) Reset() {
+	*x = FindAIRobotListRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindAIRobotListRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindAIRobotListRequest) ProtoMessage() {}
+
+func (x *FindAIRobotListRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindAIRobotListRequest.ProtoReflect.Descriptor instead.
+func (*FindAIRobotListRequest) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *FindAIRobotListRequest) GetNextId() int64 {
+	if x != nil {
+		return x.NextId
+	}
+	return 0
+}
+
+func (x *FindAIRobotListRequest) GetOffset() int64 {
+	if x != nil {
+		return x.Offset
+	}
+	return 0
+}
+
+type UpdateAIRobotRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id       int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id"`
+	AiName   string `protobuf:"bytes,2,opt,name=aiName,proto3" json:"aiName"`     // 自定义ai名称
+	UserName string `protobuf:"bytes,3,opt,name=userName,proto3" json:"userName"` // ai对我的称呼
+}
+
+func (x *UpdateAIRobotRequest) Reset() {
+	*x = UpdateAIRobotRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateAIRobotRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateAIRobotRequest) ProtoMessage() {}
+
+func (x *UpdateAIRobotRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateAIRobotRequest.ProtoReflect.Descriptor instead.
+func (*UpdateAIRobotRequest) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *UpdateAIRobotRequest) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *UpdateAIRobotRequest) GetAiName() string {
+	if x != nil {
+		return x.AiName
+	}
+	return ""
+}
+
+func (x *UpdateAIRobotRequest) GetUserName() string {
+	if x != nil {
+		return x.UserName
+	}
+	return ""
+}
+
+type AIRobotIDRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id"`
+}
+
+func (x *AIRobotIDRequest) Reset() {
+	*x = AIRobotIDRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AIRobotIDRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AIRobotIDRequest) ProtoMessage() {}
+
+func (x *AIRobotIDRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AIRobotIDRequest.ProtoReflect.Descriptor instead.
+func (*AIRobotIDRequest) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *AIRobotIDRequest) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+type FindAITemplateRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NextId int64 `protobuf:"varint,1,opt,name=nextId,proto3" json:"nextId"`
+	Offset int64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset"`
+	Sex    int64 `protobuf:"varint,3,opt,name=sex,proto3" json:"sex"` // 性别
+}
+
+func (x *FindAITemplateRequest) Reset() {
+	*x = FindAITemplateRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindAITemplateRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindAITemplateRequest) ProtoMessage() {}
+
+func (x *FindAITemplateRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindAITemplateRequest.ProtoReflect.Descriptor instead.
+func (*FindAITemplateRequest) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *FindAITemplateRequest) GetNextId() int64 {
+	if x != nil {
+		return x.NextId
+	}
+	return 0
+}
+
+func (x *FindAITemplateRequest) GetOffset() int64 {
+	if x != nil {
+		return x.Offset
+	}
+	return 0
+}
+
+func (x *FindAITemplateRequest) GetSex() int64 {
+	if x != nil {
+		return x.Sex
+	}
+	return 0
+}
+
+type FindAITemplateReply struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NextId int64             `protobuf:"varint,1,opt,name=nextId,proto3" json:"nextId"`
+	List   []*AITemplateInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list"`
+}
+
+func (x *FindAITemplateReply) Reset() {
+	*x = FindAITemplateReply{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindAITemplateReply) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindAITemplateReply) ProtoMessage() {}
+
+func (x *FindAITemplateReply) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindAITemplateReply.ProtoReflect.Descriptor instead.
+func (*FindAITemplateReply) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *FindAITemplateReply) GetNextId() int64 {
+	if x != nil {
+		return x.NextId
+	}
+	return 0
+}
+
+func (x *FindAITemplateReply) GetList() []*AITemplateInfo {
+	if x != nil {
+		return x.List
+	}
+	return make([]*AITemplateInfo, 0)
+}
+
+type AITemplateInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id            int64       `protobuf:"varint,1,opt,name=id,proto3" json:"id"`                      // ai模板ID
+	Name          string      `protobuf:"bytes,2,opt,name=name,proto3" json:"name"`                   // ai名称
+	AvatarUrl     string      `protobuf:"bytes,3,opt,name=avatarUrl,proto3" json:"avatarUrl"`         // ai头像
+	Sex           int64       `protobuf:"varint,4,opt,name=sex,proto3" json:"sex"`                    // ai性别
+	Age           int64       `protobuf:"varint,5,opt,name=age,proto3" json:"age"`                    // ai年龄
+	Label         []string    `protobuf:"bytes,6,rep,name=label,proto3" json:"label"`                 // ai标签
+	Description   string      `protobuf:"bytes,7,opt,name=description,proto3" json:"description"`     // ai描述
+	Constellation string      `protobuf:"bytes,8,opt,name=constellation,proto3" json:"constellation"` // ai星座
+	RelationList  []*Relation `protobuf:"bytes,9,rep,name=relationList,proto3" json:"relationList"`   // ai关系列表
+}
+
+func (x *AITemplateInfo) Reset() {
+	*x = AITemplateInfo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AITemplateInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AITemplateInfo) ProtoMessage() {}
+
+func (x *AITemplateInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AITemplateInfo.ProtoReflect.Descriptor instead.
+func (*AITemplateInfo) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *AITemplateInfo) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *AITemplateInfo) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *AITemplateInfo) GetAvatarUrl() string {
+	if x != nil {
+		return x.AvatarUrl
+	}
+	return ""
+}
+
+func (x *AITemplateInfo) GetSex() int64 {
+	if x != nil {
+		return x.Sex
+	}
+	return 0
+}
+
+func (x *AITemplateInfo) GetAge() int64 {
+	if x != nil {
+		return x.Age
+	}
+	return 0
+}
+
+func (x *AITemplateInfo) GetLabel() []string {
+	if x != nil {
+		return x.Label
+	}
+	return make([]string, 0)
+}
+
+func (x *AITemplateInfo) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *AITemplateInfo) GetConstellation() string {
+	if x != nil {
+		return x.Constellation
+	}
+	return ""
+}
+
+func (x *AITemplateInfo) GetRelationList() []*Relation {
+	if x != nil {
+		return x.RelationList
+	}
+	return make([]*Relation, 0)
+}
+
+type Relation struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id       int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id"`            // 关系ID
+	Picture  string `protobuf:"bytes,2,opt,name=picture,proto3" json:"picture"`   // 图片
+	Relation string `protobuf:"bytes,3,opt,name=relation,proto3" json:"relation"` // 关系
+}
+
+func (x *Relation) Reset() {
+	*x = Relation{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Relation) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Relation) ProtoMessage() {}
+
+func (x *Relation) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Relation.ProtoReflect.Descriptor instead.
+func (*Relation) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *Relation) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *Relation) GetPicture() string {
+	if x != nil {
+		return x.Picture
+	}
+	return ""
+}
+
+func (x *Relation) GetRelation() string {
+	if x != nil {
+		return x.Relation
+	}
+	return ""
+}
+
+type CreateAIRobotRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	TemplateId int64  `protobuf:"varint,1,opt,name=templateId,proto3" json:"templateId"` // ai模板ID
+	AiName     string `protobuf:"bytes,2,opt,name=aiName,proto3" json:"aiName"`          // 自定义ai名称
+	UserName   string `protobuf:"bytes,3,opt,name=userName,proto3" json:"userName"`      // ai对我的称呼
+	RelationId int64  `protobuf:"varint,4,opt,name=relationId,proto3" json:"relationId"` // 关系ID
+}
+
+func (x *CreateAIRobotRequest) Reset() {
+	*x = CreateAIRobotRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ai_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateAIRobotRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateAIRobotRequest) ProtoMessage() {}
+
+func (x *CreateAIRobotRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ai_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateAIRobotRequest.ProtoReflect.Descriptor instead.
+func (*CreateAIRobotRequest) Descriptor() ([]byte, []int) {
+	return file_ai_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *CreateAIRobotRequest) GetTemplateId() int64 {
+	if x != nil {
+		return x.TemplateId
+	}
+	return 0
+}
+
+func (x *CreateAIRobotRequest) GetAiName() string {
+	if x != nil {
+		return x.AiName
+	}
+	return ""
+}
+
+func (x *CreateAIRobotRequest) GetUserName() string {
+	if x != nil {
+		return x.UserName
+	}
+	return ""
+}
+
+func (x *CreateAIRobotRequest) GetRelationId() int64 {
+	if x != nil {
+		return x.RelationId
+	}
+	return 0
+}
+
+var File_ai_proto protoreflect.FileDescriptor
+
+var file_ai_proto_rawDesc = []byte{
+	0x0a, 0x08, 0x61, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x61, 0x70, 0x69, 0x2e,
+	0x61, 0x69, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61,
+	0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
+	0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, 0x0a, 0x0e, 0x41,
+	0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a,
+	0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x55, 0x0a,
+	0x11, 0x41, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70,
+	0x6c, 0x79, 0x12, 0x28, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x63, 0x6f,
+	0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06,
+	0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x65,
+	0x78, 0x74, 0x49, 0x64, 0x22, 0xf5, 0x01, 0x0a, 0x0c, 0x41, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x72,
+	0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a,
+	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
+	0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52,
+	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x62, 0x6f,
+	0x74, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x6f, 0x62, 0x6f, 0x74,
+	0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x53, 0x65, 0x6c, 0x66, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65,
+	0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65,
+	0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c,
+	0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x73, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x73, 0x67, 0x22, 0x23, 0x0a, 0x07,
+	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+	0x74, 0x22, 0x3d, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x49, 0x43, 0x68, 0x61, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x22, 0x5d, 0x0a, 0x1b, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65,
+	0x63, 0x6f, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x16, 0x0a, 0x06, 0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x06, 0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65,
+	0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12,
+	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22,
+	0x4e, 0x0a, 0x0b, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16,
+	0x0a, 0x06, 0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
+	0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41, 0x49,
+	0x52, 0x6f, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22,
+	0xad, 0x02, 0x0a, 0x0b, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12,
+	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72,
+	0x6c, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03,
+	0x73, 0x65, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c,
+	0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f,
+	0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6c,
+	0x61, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c,
+	0x61, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x43,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x61,
+	0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x6e, 0x72,
+	0x65, 0x61, 0x64, 0x4e, 0x75, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x6e,
+	0x72, 0x65, 0x61, 0x64, 0x4e, 0x75, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
+	0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20,
+	0x01, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22,
+	0x48, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x4c, 0x69,
+	0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x65, 0x78,
+	0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x65, 0x78, 0x74, 0x49,
+	0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x5a, 0x0a, 0x14, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69,
+	0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x69, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x06, 0x61, 0x69, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65,
+	0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65,
+	0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x22, 0x0a, 0x10, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74,
+	0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x59, 0x0a, 0x15, 0x46, 0x69, 0x6e,
+	0x64, 0x41, 0x49, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x06, 0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66,
+	0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73,
+	0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x03, 0x73, 0x65, 0x78, 0x22, 0x59, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x54, 0x65,
+	0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6e,
+	0x65, 0x78, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x65, 0x78,
+	0x74, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41, 0x49, 0x54, 0x65, 0x6d,
+	0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22,
+	0x8a, 0x02, 0x0a, 0x0e, 0x41, 0x49, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6e,
+	0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
+	0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72,
+	0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61,
+	0x72, 0x55, 0x72, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x03, 0x73, 0x65, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65,
+	0x6c, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x20,
+	0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c,
+	0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c,
+	0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x50, 0x0a, 0x08,
+	0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74,
+	0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75,
+	0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8a,
+	0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c,
+	0x61, 0x74, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x65, 0x6d,
+	0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x69, 0x4e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x69, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+	0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72,
+	0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x0a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x32, 0xa9, 0x06, 0x0a, 0x02,
+	0x41, 0x69, 0x12, 0x6e, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x54, 0x65, 0x6d, 0x70,
+	0x6c, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x46, 0x69,
+	0x6e, 0x64, 0x41, 0x49, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x46, 0x69, 0x6e,
+	0x64, 0x41, 0x49, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79,
+	0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61,
+	0x69, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x3a,
+	0x01, 0x2a, 0x12, 0x60, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x49, 0x52, 0x6f,
+	0x62, 0x6f, 0x74, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x43, 0x72, 0x65,
+	0x61, 0x74, 0x65, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41, 0x49, 0x52, 0x6f, 0x62,
+	0x6f, 0x74, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x13, 0x22, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x3a, 0x01, 0x2a, 0x12, 0x5c, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x49,
+	0x52, 0x6f, 0x62, 0x6f, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41,
+	0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22,
+	0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x3a,
+	0x01, 0x2a, 0x12, 0x60, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x49, 0x52, 0x6f,
+	0x62, 0x6f, 0x74, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41, 0x49, 0x52, 0x6f, 0x62,
+	0x6f, 0x74, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x13, 0x22, 0x0e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x3a, 0x01, 0x2a, 0x12, 0x64, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x52, 0x6f,
+	0x62, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69,
+	0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69,
+	0x2e, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x1c, 0x82, 0xd3,
+	0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x2f, 0x66, 0x69,
+	0x6e, 0x64, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x59, 0x0a, 0x0a, 0x47, 0x65,
+	0x74, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61,
+	0x69, 0x2e, 0x41, 0x49, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41, 0x49, 0x52, 0x6f,
+	0x62, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22,
+	0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x2f, 0x69, 0x6e,
+	0x66, 0x6f, 0x3a, 0x01, 0x2a, 0x12, 0x76, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x43,
+	0x68, 0x61, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x23, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x49, 0x43, 0x68, 0x61,
+	0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x69, 0x2e, 0x41, 0x49, 0x52, 0x65,
+	0x63, 0x6f, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1e, 0x82,
+	0xd3, 0xe4, 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x2f, 0x63,
+	0x68, 0x61, 0x74, 0x2f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x58, 0x0a,
+	0x0a, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x49, 0x43, 0x68, 0x61, 0x74, 0x12, 0x19, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x61, 0x69, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x49, 0x43, 0x68, 0x61, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x17,
+	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x22, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x2f,
+	0x73, 0x65, 0x6e, 0x64, 0x3a, 0x01, 0x2a, 0x42, 0x37, 0x0a, 0x06, 0x61, 0x70, 0x69, 0x2e, 0x61,
+	0x69, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x2e, 0x69, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x77, 0x2d, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x69, 0x3b, 0x61, 0x69,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_ai_proto_rawDescOnce sync.Once
+	file_ai_proto_rawDescData = file_ai_proto_rawDesc
+)
+
+func file_ai_proto_rawDescGZIP() []byte {
+	file_ai_proto_rawDescOnce.Do(func() {
+		file_ai_proto_rawDescData = protoimpl.X.CompressGZIP(file_ai_proto_rawDescData)
+	})
+	return file_ai_proto_rawDescData
+}
+
+var file_ai_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
+var file_ai_proto_goTypes = []interface{}{
+	(*AIRobotIDReply)(nil),              // 0: api.ai.AIRobotIDReply
+	(*AIRecordListReply)(nil),           // 1: api.ai.AIRecordListReply
+	(*AIRecordInfo)(nil),                // 2: api.ai.AIRecordInfo
+	(*Message)(nil),                     // 3: api.ai.Message
+	(*SendAIChatRequest)(nil),           // 4: api.ai.SendAIChatRequest
+	(*FindAIChatRecordListRequest)(nil), // 5: api.ai.FindAIChatRecordListRequest
+	(*AIRobotList)(nil),                 // 6: api.ai.AIRobotList
+	(*AIRobotInfo)(nil),                 // 7: api.ai.AIRobotInfo
+	(*FindAIRobotListRequest)(nil),      // 8: api.ai.FindAIRobotListRequest
+	(*UpdateAIRobotRequest)(nil),        // 9: api.ai.UpdateAIRobotRequest
+	(*AIRobotIDRequest)(nil),            // 10: api.ai.AIRobotIDRequest
+	(*FindAITemplateRequest)(nil),       // 11: api.ai.FindAITemplateRequest
+	(*FindAITemplateReply)(nil),         // 12: api.ai.FindAITemplateReply
+	(*AITemplateInfo)(nil),              // 13: api.ai.AITemplateInfo
+	(*Relation)(nil),                    // 14: api.ai.Relation
+	(*CreateAIRobotRequest)(nil),        // 15: api.ai.CreateAIRobotRequest
+	(*emptypb.Empty)(nil),               // 16: google.protobuf.Empty
+}
+var file_ai_proto_depIdxs = []int32{
+	2,  // 0: api.ai.AIRecordListReply.list:type_name -> api.ai.AIRecordInfo
+	3,  // 1: api.ai.AIRecordInfo.message:type_name -> api.ai.Message
+	7,  // 2: api.ai.AIRobotList.list:type_name -> api.ai.AIRobotInfo
+	13, // 3: api.ai.FindAITemplateReply.list:type_name -> api.ai.AITemplateInfo
+	14, // 4: api.ai.AITemplateInfo.relationList:type_name -> api.ai.Relation
+	11, // 5: api.ai.Ai.FindAITemplate:input_type -> api.ai.FindAITemplateRequest
+	15, // 6: api.ai.Ai.CreateAIRobot:input_type -> api.ai.CreateAIRobotRequest
+	10, // 7: api.ai.Ai.DeleteAIRobot:input_type -> api.ai.AIRobotIDRequest
+	9,  // 8: api.ai.Ai.UpdateAIRobot:input_type -> api.ai.UpdateAIRobotRequest
+	8,  // 9: api.ai.Ai.FindAIRobotList:input_type -> api.ai.FindAIRobotListRequest
+	10, // 10: api.ai.Ai.GetAIRobot:input_type -> api.ai.AIRobotIDRequest
+	5,  // 11: api.ai.Ai.FindAIChatRecordList:input_type -> api.ai.FindAIChatRecordListRequest
+	4,  // 12: api.ai.Ai.SendAIChat:input_type -> api.ai.SendAIChatRequest
+	12, // 13: api.ai.Ai.FindAITemplate:output_type -> api.ai.FindAITemplateReply
+	0,  // 14: api.ai.Ai.CreateAIRobot:output_type -> api.ai.AIRobotIDReply
+	16, // 15: api.ai.Ai.DeleteAIRobot:output_type -> google.protobuf.Empty
+	0,  // 16: api.ai.Ai.UpdateAIRobot:output_type -> api.ai.AIRobotIDReply
+	6,  // 17: api.ai.Ai.FindAIRobotList:output_type -> api.ai.AIRobotList
+	7,  // 18: api.ai.Ai.GetAIRobot:output_type -> api.ai.AIRobotInfo
+	1,  // 19: api.ai.Ai.FindAIChatRecordList:output_type -> api.ai.AIRecordListReply
+	16, // 20: api.ai.Ai.SendAIChat:output_type -> google.protobuf.Empty
+	13, // [13:21] is the sub-list for method output_type
+	5,  // [5:13] is the sub-list for method input_type
+	5,  // [5:5] is the sub-list for extension type_name
+	5,  // [5:5] is the sub-list for extension extendee
+	0,  // [0:5] is the sub-list for field type_name
+}
+
+func init() { file_ai_proto_init() }
+func file_ai_proto_init() {
+	if File_ai_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_ai_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AIRobotIDReply); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AIRecordListReply); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AIRecordInfo); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Message); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendAIChatRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindAIChatRecordListRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AIRobotList); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AIRobotInfo); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindAIRobotListRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateAIRobotRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AIRobotIDRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindAITemplateRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindAITemplateReply); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AITemplateInfo); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Relation); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ai_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateAIRobotRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_ai_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   16,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_ai_proto_goTypes,
+		DependencyIndexes: file_ai_proto_depIdxs,
+		MessageInfos:      file_ai_proto_msgTypes,
+	}.Build()
+	File_ai_proto = out.File
+	file_ai_proto_rawDesc = nil
+	file_ai_proto_goTypes = nil
+	file_ai_proto_depIdxs = nil
+}

+ 175 - 0
api/ai/ai.proto

@@ -0,0 +1,175 @@
+syntax = "proto3";
+
+package api.ai;
+
+import "google/api/annotations.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/empty.proto";
+
+option go_package = "git.ikuban.com/server/pw-protobuf/api/ai;ai";
+option java_multiple_files = true;
+option java_package = "api.ai";
+
+service Ai {
+  // 查询AI模板
+  rpc FindAITemplate (FindAITemplateRequest) returns (FindAITemplateReply){
+    option (google.api.http) = {
+      post: "/api/ai/template/list",
+      body:"*"
+    };
+  };
+  // 创建AI
+  rpc CreateAIRobot (CreateAIRobotRequest) returns (AIRobotIDReply){
+    option (google.api.http) = {
+      post: "/api/ai/create",
+      body:"*"
+    };
+  };
+  // 销毁AI
+  rpc DeleteAIRobot (AIRobotIDRequest) returns (google.protobuf.Empty){
+    option (google.api.http) = {
+      post: "/api/ai/delete",
+      body:"*"
+    };
+  };
+  // 更新AI
+  rpc UpdateAIRobot (UpdateAIRobotRequest) returns (AIRobotIDReply){
+    option (google.api.http) = {
+      post: "/api/ai/update",
+      body:"*"
+    };
+  };
+  // 查询AI机器人列表
+  rpc FindAIRobotList (FindAIRobotListRequest) returns (AIRobotList){
+    option (google.api.http) = {
+      post: "/api/ai/find/list",
+      body:"*"
+    };
+  };
+  // 查询AI机器人
+  rpc GetAIRobot (AIRobotIDRequest) returns (AIRobotInfo){
+    option (google.api.http) = {
+      post: "/api/ai/find/info",
+      body:"*"
+    };
+  };
+  // 查询AI聊天记录
+  rpc FindAIChatRecordList (FindAIChatRecordListRequest) returns (AIRecordListReply){
+    option (google.api.http) = {
+      post: "/api/ai/chat/record",
+      body:"*"
+    };
+  };
+  // 发送消息给ai
+  rpc SendAIChat (SendAIChatRequest) returns (google.protobuf.Empty){
+    option (google.api.http) = {
+      post: "/api/ai/send",
+      body:"*"
+    };
+  };
+}
+
+message AIRobotIDReply{
+  int64 id = 1;
+}
+
+message AIRecordListReply{
+  repeated AIRecordInfo list = 1;
+  int64 nextId = 2;
+}
+
+message AIRecordInfo{
+  int64 messageId = 1; // 消息的ID
+  string msgType = 2;  // 消息类型
+  Message message = 3; // 消息的结构
+  int64 robotId = 4;    // 机器人ID
+  bool isSelf = 5;     // 是否是自己
+  int64 sendTime = 6;  // 发送时间
+  string status = 7;   // 消息状态
+  string statusMsg = 8;// 状态说明
+}
+
+message Message{
+  string content = 1; // 文本内容
+}
+
+message SendAIChatRequest{
+  int64 id = 1;
+  string message = 2;// 消息
+}
+
+message FindAIChatRecordListRequest{
+  int64 nextId = 1;
+  int64 offset = 2;
+  int64 id = 3;
+}
+
+message AIRobotList{
+  int64 nextId = 1;
+  repeated AIRobotInfo list = 2;
+}
+
+message AIRobotInfo{
+  int64 id = 1;
+  string name = 2;// ai名称
+  string avatarUrl = 3;// ai头像
+  int64 sex = 4;// ai性别
+  int64 age = 5;// ai年龄
+  string constellation = 6;// ai星座
+  int64 lastTime = 7;// 上次发送时间
+  string lastContent = 8;// 上次发送的内容
+  int64 unreadNum = 9;// 未读
+  string status = 10;// 状态
+  int64 createTime = 11;// 创建时间
+}
+
+message FindAIRobotListRequest{
+  int64 nextId = 1;
+  int64 offset = 2;
+}
+
+message UpdateAIRobotRequest{
+  int64 id = 1;
+  string aiName = 2;// 自定义ai名称
+  string userName = 3;// ai对我的称呼
+}
+
+message AIRobotIDRequest{
+  int64 id = 1;
+}
+
+message FindAITemplateRequest{
+  int64 nextId = 1;
+  int64 offset = 2;
+  int64 sex = 3;// 性别
+}
+
+message FindAITemplateReply{
+  int64 nextId = 1;
+  repeated AITemplateInfo list= 2;
+}
+
+message AITemplateInfo{
+  int64 id = 1;// ai模板ID
+  string name = 2;// ai名称
+  string avatarUrl = 3;// ai头像
+  int64 sex = 4;// ai性别
+  int64 age = 5;// ai年龄
+  repeated string label = 6;// ai标签
+  string description = 7;// ai描述
+  string constellation = 8;// ai星座
+  repeated Relation relationList = 9;// ai关系列表
+}
+
+message Relation{
+  int64 id = 1;// 关系ID
+  string picture = 2;// 图片
+  string relation = 3;// 关系
+}
+
+message CreateAIRobotRequest{
+  int64 templateId = 1;// ai模板ID
+  string aiName = 2;// 自定义ai名称
+  string userName = 3;// ai对我的称呼
+  int64 relationId = 4;// 关系ID
+}

+ 370 - 0
api/ai/ai_grpc.pb.go

@@ -0,0 +1,370 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package ai
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// AiClient is the client API for Ai service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type AiClient interface {
+	// 查询AI模板
+	FindAITemplate(ctx context.Context, in *FindAITemplateRequest, opts ...grpc.CallOption) (*FindAITemplateReply, error)
+	// 创建AI
+	CreateAIRobot(ctx context.Context, in *CreateAIRobotRequest, opts ...grpc.CallOption) (*AIRobotIDReply, error)
+	// 销毁AI
+	DeleteAIRobot(ctx context.Context, in *AIRobotIDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	// 更新AI
+	UpdateAIRobot(ctx context.Context, in *UpdateAIRobotRequest, opts ...grpc.CallOption) (*AIRobotIDReply, error)
+	// 查询AI机器人列表
+	FindAIRobotList(ctx context.Context, in *FindAIRobotListRequest, opts ...grpc.CallOption) (*AIRobotList, error)
+	// 查询AI机器人
+	GetAIRobot(ctx context.Context, in *AIRobotIDRequest, opts ...grpc.CallOption) (*AIRobotInfo, error)
+	// 查询AI聊天记录
+	FindAIChatRecordList(ctx context.Context, in *FindAIChatRecordListRequest, opts ...grpc.CallOption) (*AIRecordListReply, error)
+	// 发送消息给ai
+	SendAIChat(ctx context.Context, in *SendAIChatRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+}
+
+type aiClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewAiClient(cc grpc.ClientConnInterface) AiClient {
+	return &aiClient{cc}
+}
+
+func (c *aiClient) FindAITemplate(ctx context.Context, in *FindAITemplateRequest, opts ...grpc.CallOption) (*FindAITemplateReply, error) {
+	out := new(FindAITemplateReply)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/FindAITemplate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *aiClient) CreateAIRobot(ctx context.Context, in *CreateAIRobotRequest, opts ...grpc.CallOption) (*AIRobotIDReply, error) {
+	out := new(AIRobotIDReply)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/CreateAIRobot", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *aiClient) DeleteAIRobot(ctx context.Context, in *AIRobotIDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/DeleteAIRobot", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *aiClient) UpdateAIRobot(ctx context.Context, in *UpdateAIRobotRequest, opts ...grpc.CallOption) (*AIRobotIDReply, error) {
+	out := new(AIRobotIDReply)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/UpdateAIRobot", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *aiClient) FindAIRobotList(ctx context.Context, in *FindAIRobotListRequest, opts ...grpc.CallOption) (*AIRobotList, error) {
+	out := new(AIRobotList)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/FindAIRobotList", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *aiClient) GetAIRobot(ctx context.Context, in *AIRobotIDRequest, opts ...grpc.CallOption) (*AIRobotInfo, error) {
+	out := new(AIRobotInfo)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/GetAIRobot", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *aiClient) FindAIChatRecordList(ctx context.Context, in *FindAIChatRecordListRequest, opts ...grpc.CallOption) (*AIRecordListReply, error) {
+	out := new(AIRecordListReply)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/FindAIChatRecordList", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *aiClient) SendAIChat(ctx context.Context, in *SendAIChatRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, "/api.ai.Ai/SendAIChat", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// AiServer is the server API for Ai service.
+// All implementations must embed UnimplementedAiServer
+// for forward compatibility
+type AiServer interface {
+	// 查询AI模板
+	FindAITemplate(context.Context, *FindAITemplateRequest) (*FindAITemplateReply, error)
+	// 创建AI
+	CreateAIRobot(context.Context, *CreateAIRobotRequest) (*AIRobotIDReply, error)
+	// 销毁AI
+	DeleteAIRobot(context.Context, *AIRobotIDRequest) (*emptypb.Empty, error)
+	// 更新AI
+	UpdateAIRobot(context.Context, *UpdateAIRobotRequest) (*AIRobotIDReply, error)
+	// 查询AI机器人列表
+	FindAIRobotList(context.Context, *FindAIRobotListRequest) (*AIRobotList, error)
+	// 查询AI机器人
+	GetAIRobot(context.Context, *AIRobotIDRequest) (*AIRobotInfo, error)
+	// 查询AI聊天记录
+	FindAIChatRecordList(context.Context, *FindAIChatRecordListRequest) (*AIRecordListReply, error)
+	// 发送消息给ai
+	SendAIChat(context.Context, *SendAIChatRequest) (*emptypb.Empty, error)
+	mustEmbedUnimplementedAiServer()
+}
+
+// UnimplementedAiServer must be embedded to have forward compatible implementations.
+type UnimplementedAiServer struct {
+}
+
+func (UnimplementedAiServer) FindAITemplate(context.Context, *FindAITemplateRequest) (*FindAITemplateReply, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FindAITemplate not implemented")
+}
+func (UnimplementedAiServer) CreateAIRobot(context.Context, *CreateAIRobotRequest) (*AIRobotIDReply, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CreateAIRobot not implemented")
+}
+func (UnimplementedAiServer) DeleteAIRobot(context.Context, *AIRobotIDRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteAIRobot not implemented")
+}
+func (UnimplementedAiServer) UpdateAIRobot(context.Context, *UpdateAIRobotRequest) (*AIRobotIDReply, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateAIRobot not implemented")
+}
+func (UnimplementedAiServer) FindAIRobotList(context.Context, *FindAIRobotListRequest) (*AIRobotList, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FindAIRobotList not implemented")
+}
+func (UnimplementedAiServer) GetAIRobot(context.Context, *AIRobotIDRequest) (*AIRobotInfo, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetAIRobot not implemented")
+}
+func (UnimplementedAiServer) FindAIChatRecordList(context.Context, *FindAIChatRecordListRequest) (*AIRecordListReply, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FindAIChatRecordList not implemented")
+}
+func (UnimplementedAiServer) SendAIChat(context.Context, *SendAIChatRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SendAIChat not implemented")
+}
+func (UnimplementedAiServer) mustEmbedUnimplementedAiServer() {}
+
+// UnsafeAiServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to AiServer will
+// result in compilation errors.
+type UnsafeAiServer interface {
+	mustEmbedUnimplementedAiServer()
+}
+
+func RegisterAiServer(s grpc.ServiceRegistrar, srv AiServer) {
+	s.RegisterService(&Ai_ServiceDesc, srv)
+}
+
+func _Ai_FindAITemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(FindAITemplateRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).FindAITemplate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/FindAITemplate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).FindAITemplate(ctx, req.(*FindAITemplateRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Ai_CreateAIRobot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(CreateAIRobotRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).CreateAIRobot(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/CreateAIRobot",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).CreateAIRobot(ctx, req.(*CreateAIRobotRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Ai_DeleteAIRobot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AIRobotIDRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).DeleteAIRobot(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/DeleteAIRobot",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).DeleteAIRobot(ctx, req.(*AIRobotIDRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Ai_UpdateAIRobot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UpdateAIRobotRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).UpdateAIRobot(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/UpdateAIRobot",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).UpdateAIRobot(ctx, req.(*UpdateAIRobotRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Ai_FindAIRobotList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(FindAIRobotListRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).FindAIRobotList(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/FindAIRobotList",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).FindAIRobotList(ctx, req.(*FindAIRobotListRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Ai_GetAIRobot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AIRobotIDRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).GetAIRobot(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/GetAIRobot",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).GetAIRobot(ctx, req.(*AIRobotIDRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Ai_FindAIChatRecordList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(FindAIChatRecordListRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).FindAIChatRecordList(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/FindAIChatRecordList",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).FindAIChatRecordList(ctx, req.(*FindAIChatRecordListRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Ai_SendAIChat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SendAIChatRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AiServer).SendAIChat(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.ai.Ai/SendAIChat",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AiServer).SendAIChat(ctx, req.(*SendAIChatRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// Ai_ServiceDesc is the grpc.ServiceDesc for Ai service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Ai_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "api.ai.Ai",
+	HandlerType: (*AiServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "FindAITemplate",
+			Handler:    _Ai_FindAITemplate_Handler,
+		},
+		{
+			MethodName: "CreateAIRobot",
+			Handler:    _Ai_CreateAIRobot_Handler,
+		},
+		{
+			MethodName: "DeleteAIRobot",
+			Handler:    _Ai_DeleteAIRobot_Handler,
+		},
+		{
+			MethodName: "UpdateAIRobot",
+			Handler:    _Ai_UpdateAIRobot_Handler,
+		},
+		{
+			MethodName: "FindAIRobotList",
+			Handler:    _Ai_FindAIRobotList_Handler,
+		},
+		{
+			MethodName: "GetAIRobot",
+			Handler:    _Ai_GetAIRobot_Handler,
+		},
+		{
+			MethodName: "FindAIChatRecordList",
+			Handler:    _Ai_FindAIChatRecordList_Handler,
+		},
+		{
+			MethodName: "SendAIChat",
+			Handler:    _Ai_SendAIChat_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "ai.proto",
+}

+ 389 - 0
api/ai/ai_http.pb.go

@@ -0,0 +1,389 @@
+// Code generated by protoc-gen-go-http. DO NOT EDIT.
+// versions:
+// protoc-gen-go-http v2.0.0
+
+package ai
+
+import (
+	context "context"
+	base "git.ikuban.com/server/base-protobuf/kuban/api/base"
+	reply "git.ikuban.com/server/kratos-utils/http/reply"
+	http "github.com/go-kratos/kratos/v2/transport/http"
+	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+	ioutil "io/ioutil"
+	time "time"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the kratos package it is being compiled against.
+var _ = new(context.Context)
+var _ = binding.EncodeURL
+var _ = ioutil.Discard
+var _ = new(time.Time)
+var _ = new(reply.SuccessReply)
+var _ = new(base.Html)
+
+const _ = http.SupportPackageIsVersion1
+
+type AiHTTPServer interface {
+	CreateAIRobot(context.Context, *CreateAIRobotRequest) (*AIRobotIDReply, error)
+	DeleteAIRobot(context.Context, *AIRobotIDRequest) (*emptypb.Empty, error)
+	FindAIChatRecordList(context.Context, *FindAIChatRecordListRequest) (*AIRecordListReply, error)
+	FindAIRobotList(context.Context, *FindAIRobotListRequest) (*AIRobotList, error)
+	FindAITemplate(context.Context, *FindAITemplateRequest) (*FindAITemplateReply, error)
+	GetAIRobot(context.Context, *AIRobotIDRequest) (*AIRobotInfo, error)
+	SendAIChat(context.Context, *SendAIChatRequest) (*emptypb.Empty, error)
+	UpdateAIRobot(context.Context, *UpdateAIRobotRequest) (*AIRobotIDReply, error)
+}
+
+func RegisterAiHTTPServer(s *http.Server, srv AiHTTPServer) {
+	r := s.Route("/")
+	r.POST("/api/ai/template/list", _Ai_FindAITemplate0_HTTP_Handler(srv))
+	r.POST("/api/ai/create", _Ai_CreateAIRobot0_HTTP_Handler(srv))
+	r.POST("/api/ai/delete", _Ai_DeleteAIRobot0_HTTP_Handler(srv))
+	r.POST("/api/ai/update", _Ai_UpdateAIRobot0_HTTP_Handler(srv))
+	r.POST("/api/ai/find/list", _Ai_FindAIRobotList0_HTTP_Handler(srv))
+	r.POST("/api/ai/find/info", _Ai_GetAIRobot0_HTTP_Handler(srv))
+	r.POST("/api/ai/chat/record", _Ai_FindAIChatRecordList0_HTTP_Handler(srv))
+	r.POST("/api/ai/send", _Ai_SendAIChat0_HTTP_Handler(srv))
+}
+
+func _Ai_FindAITemplate0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in FindAITemplateRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/FindAITemplate")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.FindAITemplate(ctx, req.(*FindAITemplateRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+func _Ai_CreateAIRobot0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in CreateAIRobotRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/CreateAIRobot")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.CreateAIRobot(ctx, req.(*CreateAIRobotRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+func _Ai_DeleteAIRobot0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in AIRobotIDRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/DeleteAIRobot")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.DeleteAIRobot(ctx, req.(*AIRobotIDRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+func _Ai_UpdateAIRobot0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in UpdateAIRobotRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/UpdateAIRobot")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.UpdateAIRobot(ctx, req.(*UpdateAIRobotRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+func _Ai_FindAIRobotList0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in FindAIRobotListRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/FindAIRobotList")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.FindAIRobotList(ctx, req.(*FindAIRobotListRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+func _Ai_GetAIRobot0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in AIRobotIDRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/GetAIRobot")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.GetAIRobot(ctx, req.(*AIRobotIDRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+func _Ai_FindAIChatRecordList0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in FindAIChatRecordListRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/FindAIChatRecordList")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.FindAIChatRecordList(ctx, req.(*FindAIChatRecordListRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+func _Ai_SendAIChat0_HTTP_Handler(srv AiHTTPServer) func(ctx http.Context) error {
+	return func(ctx http.Context) error {
+		var in SendAIChatRequest
+		if err := ctx.Bind(&in); err != nil {
+			return err
+		}
+		if err := ctx.BindQuery(&in); err != nil {
+			return err
+		}
+		http.SetOperation(ctx, "/api.ai.Ai/SendAIChat")
+		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.SendAIChat(ctx, req.(*SendAIChatRequest))
+		})
+		out, err := h(ctx, &in)
+		if err != nil {
+			return err
+		}
+		success := &reply.SuccessReply{
+			Code: 0,
+		}
+		if out != nil {
+			success.Data = out
+		}
+		return ctx.Result(200, success)
+	}
+}
+
+type AiHTTPClient interface {
+	CreateAIRobot(ctx context.Context, req *CreateAIRobotRequest, opts ...http.CallOption) (rsp *AIRobotIDReply, err error)
+	DeleteAIRobot(ctx context.Context, req *AIRobotIDRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error)
+	FindAIChatRecordList(ctx context.Context, req *FindAIChatRecordListRequest, opts ...http.CallOption) (rsp *AIRecordListReply, err error)
+	FindAIRobotList(ctx context.Context, req *FindAIRobotListRequest, opts ...http.CallOption) (rsp *AIRobotList, err error)
+	FindAITemplate(ctx context.Context, req *FindAITemplateRequest, opts ...http.CallOption) (rsp *FindAITemplateReply, err error)
+	GetAIRobot(ctx context.Context, req *AIRobotIDRequest, opts ...http.CallOption) (rsp *AIRobotInfo, err error)
+	SendAIChat(ctx context.Context, req *SendAIChatRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error)
+	UpdateAIRobot(ctx context.Context, req *UpdateAIRobotRequest, opts ...http.CallOption) (rsp *AIRobotIDReply, err error)
+}
+
+type AiHTTPClientImpl struct {
+	cc *http.Client
+}
+
+func NewAiHTTPClient(client *http.Client) AiHTTPClient {
+	return &AiHTTPClientImpl{client}
+}
+
+func (c *AiHTTPClientImpl) CreateAIRobot(ctx context.Context, in *CreateAIRobotRequest, opts ...http.CallOption) (*AIRobotIDReply, error) {
+	var out AIRobotIDReply
+	pattern := "/api/ai/create"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/CreateAIRobot"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}
+
+func (c *AiHTTPClientImpl) DeleteAIRobot(ctx context.Context, in *AIRobotIDRequest, opts ...http.CallOption) (*emptypb.Empty, error) {
+	var out emptypb.Empty
+	pattern := "/api/ai/delete"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/DeleteAIRobot"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}
+
+func (c *AiHTTPClientImpl) FindAIChatRecordList(ctx context.Context, in *FindAIChatRecordListRequest, opts ...http.CallOption) (*AIRecordListReply, error) {
+	var out AIRecordListReply
+	pattern := "/api/ai/chat/record"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/FindAIChatRecordList"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}
+
+func (c *AiHTTPClientImpl) FindAIRobotList(ctx context.Context, in *FindAIRobotListRequest, opts ...http.CallOption) (*AIRobotList, error) {
+	var out AIRobotList
+	pattern := "/api/ai/find/list"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/FindAIRobotList"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}
+
+func (c *AiHTTPClientImpl) FindAITemplate(ctx context.Context, in *FindAITemplateRequest, opts ...http.CallOption) (*FindAITemplateReply, error) {
+	var out FindAITemplateReply
+	pattern := "/api/ai/template/list"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/FindAITemplate"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}
+
+func (c *AiHTTPClientImpl) GetAIRobot(ctx context.Context, in *AIRobotIDRequest, opts ...http.CallOption) (*AIRobotInfo, error) {
+	var out AIRobotInfo
+	pattern := "/api/ai/find/info"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/GetAIRobot"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}
+
+func (c *AiHTTPClientImpl) SendAIChat(ctx context.Context, in *SendAIChatRequest, opts ...http.CallOption) (*emptypb.Empty, error) {
+	var out emptypb.Empty
+	pattern := "/api/ai/send"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/SendAIChat"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}
+
+func (c *AiHTTPClientImpl) UpdateAIRobot(ctx context.Context, in *UpdateAIRobotRequest, opts ...http.CallOption) (*AIRobotIDReply, error) {
+	var out AIRobotIDReply
+	pattern := "/api/ai/update"
+	path := binding.EncodeURL(pattern, in, false)
+	opts = append(opts, http.Operation("/api.ai.Ai/UpdateAIRobot"))
+	opts = append(opts, http.PathTemplate(pattern))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &out, err
+}

+ 19 - 0
client/ai.go

@@ -0,0 +1,19 @@
+package client
+
+import (
+	"git.ikuban.com/server/kratos-nacos/registry"
+	"git.ikuban.com/server/pw-protobuf/api/ai"
+	"github.com/go-kratos/kratos/v2/log"
+)
+
+func NewAIClient(r *registry.Registry, logger log.Logger) ai.AiClient {
+	conn, err := getDialInsecure(r, logger, "discovery://pw/pw-ai")
+	if err != nil {
+		panic(err)
+	}
+	if conn == nil {
+		return nil
+	}
+	client := ai.NewAiClient(conn)
+	return client
+}

+ 8 - 0
define/ai.go

@@ -0,0 +1,8 @@
+package define
+
+var (
+	AIRobotStatusExperience = "experience" // 体验
+	AIRobotStatusNormal     = "normal"     // 正常
+	AIRobotStatusDelete     = "delete"     // 删除
+	AIRobotStatusOver       = "over"       // 过期
+)

+ 7 - 0
errors/ai.go

@@ -0,0 +1,7 @@
+package errors
+
+import "git.ikuban.com/server/kratos-utils/codes"
+
+var (
+	ErrorRobotNotExist = codes.Error(60001, "ai机器人不存在")
+)

+ 49 - 0
js/api/ai/ai_http_pb.ts

@@ -0,0 +1,49 @@
+// @ts-ignore
+import request from '@/libs/request';
+import {FindAITemplateRequest,FindAITemplateReply,CreateAIRobotRequest,AIRobotIDReply,AIRobotIDRequest,UpdateAIRobotRequest,FindAIRobotListRequest,AIRobotList,AIRobotInfo,FindAIChatRecordListRequest,AIRecordListReply,SendAIChatRequest} from "./ai_pb";
+
+const AiService = {
+  /**  查询AI模板 */
+  FindAITemplate: async (req?: FindAITemplateRequest) => {
+	const res = await request.post<{ data: FindAITemplateReply, code: string, message: string }>('/api/ai/template/list', req);
+    return res.data.data;
+  },
+  /**  创建AI */
+  CreateAIRobot: async (req?: CreateAIRobotRequest) => {
+	const res = await request.post<{ data: AIRobotIDReply, code: string, message: string }>('/api/ai/create', req);
+    return res.data.data;
+  },
+  /**  销毁AI */
+  DeleteAIRobot: async (req?: AIRobotIDRequest) => {
+	const res = await request.post('/api/ai/delete', req);
+    return res.data.data;
+  },
+  /**  更新AI */
+  UpdateAIRobot: async (req?: UpdateAIRobotRequest) => {
+	const res = await request.post<{ data: AIRobotIDReply, code: string, message: string }>('/api/ai/update', req);
+    return res.data.data;
+  },
+  /**  查询AI机器人列表 */
+  FindAIRobotList: async (req?: FindAIRobotListRequest) => {
+	const res = await request.post<{ data: AIRobotList, code: string, message: string }>('/api/ai/find/list', req);
+    return res.data.data;
+  },
+  /**  查询AI机器人 */
+  GetAIRobot: async (req?: AIRobotIDRequest) => {
+	const res = await request.post<{ data: AIRobotInfo, code: string, message: string }>('/api/ai/find/info', req);
+    return res.data.data;
+  },
+  /**  查询AI聊天记录 */
+  FindAIChatRecordList: async (req?: FindAIChatRecordListRequest) => {
+	const res = await request.post<{ data: AIRecordListReply, code: string, message: string }>('/api/ai/chat/record', req);
+    return res.data.data;
+  },
+  /**  发送消息给ai */
+  SendAIChat: async (req?: SendAIChatRequest) => {
+	const res = await request.post('/api/ai/send', req);
+    return res.data.data;
+  },
+
+};
+
+export default AiService;

+ 129 - 0
js/api/ai/ai_pb.ts

@@ -0,0 +1,129 @@
+export interface AIRobotIDReply{
+    id?:number;
+}
+export interface AIRecordListReply{
+    list?:Array<AIRecordInfo>;
+    nextId?:number;
+}
+export interface AIRecordInfo{
+    /**  消息的ID */
+    messageId?:number;
+    /**  消息类型 */
+    msgType?:string;
+    /**  消息的结构 */
+    message?:Message;
+    /**  机器人ID */
+    robotId?:number;
+    /**  是否是自己 */
+    isSelf?:boolean;
+    /**  发送时间 */
+    sendTime?:number;
+    /**  消息状态 */
+    status?:string;
+    /**  状态说明 */
+    statusMsg?:string;
+}
+export interface Message{
+    /**  文本内容 */
+    content?:string;
+}
+export interface SendAIChatRequest{
+    id?:number;
+    /**  消息 */
+    message?:string;
+}
+export interface FindAIChatRecordListRequest{
+    nextId?:number;
+    offset?:number;
+    id?:number;
+}
+export interface AIRobotList{
+    nextId?:number;
+    list?:Array<AIRobotInfo>;
+}
+export interface AIRobotInfo{
+    id?:number;
+    /**  ai名称 */
+    name?:string;
+    /**  ai头像 */
+    avatarUrl?:string;
+    /**  ai性别 */
+    sex?:number;
+    /**  ai年龄 */
+    age?:number;
+    /**  ai星座 */
+    constellation?:string;
+    /**  上次发送时间 */
+    lastTime?:number;
+    /**  上次发送的内容 */
+    lastContent?:string;
+    /**  未读 */
+    unreadNum?:number;
+    /**  状态 */
+    status?:string;
+    /**  创建时间 */
+    createTime?:number;
+}
+export interface FindAIRobotListRequest{
+    nextId?:number;
+    offset?:number;
+}
+export interface UpdateAIRobotRequest{
+    id?:number;
+    /**  自定义ai名称 */
+    aiName?:string;
+    /**  ai对我的称呼 */
+    userName?:string;
+}
+export interface AIRobotIDRequest{
+    id?:number;
+}
+export interface FindAITemplateRequest{
+    nextId?:number;
+    offset?:number;
+    /**  性别 */
+    sex?:number;
+}
+export interface FindAITemplateReply{
+    nextId?:number;
+    list?:Array<AITemplateInfo>;
+}
+export interface AITemplateInfo{
+    /**  ai模板ID */
+    id?:number;
+    /**  ai名称 */
+    name?:string;
+    /**  ai头像 */
+    avatarUrl?:string;
+    /**  ai性别 */
+    sex?:number;
+    /**  ai年龄 */
+    age?:number;
+    /**  ai标签 */
+    label?:Array<string>;
+    /**  ai描述 */
+    description?:string;
+    /**  ai星座 */
+    constellation?:string;
+    /**  ai关系列表 */
+    relationList?:Array<Relation>;
+}
+export interface Relation{
+    /**  关系ID */
+    id?:number;
+    /**  图片 */
+    picture?:string;
+    /**  关系 */
+    relation?:string;
+}
+export interface CreateAIRobotRequest{
+    /**  ai模板ID */
+    templateId?:number;
+    /**  自定义ai名称 */
+    aiName?:string;
+    /**  ai对我的称呼 */
+    userName?:string;
+    /**  关系ID */
+    relationId?:number;
+}
+