feat(proto): AIRequest.images for vision multimodal input.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kaien 2026-09-09 18:18:30 +03:00
parent ea73b19a88
commit 72125c137a
2 changed files with 230 additions and 139 deletions

358
ai.pb.go
View File

@ -260,7 +260,11 @@ type AIRequest struct {
// Raw user message for intent classification (no history/memories/tools).
// Live chat clients (Telegram/Steam) send this; when empty, image intent
// detection is skipped and the request is treated as normal chat.
UserMessage string `protobuf:"bytes,11,opt,name=user_message,json=userMessage,proto3" json:"user_message,omitempty"`
UserMessage string `protobuf:"bytes,11,opt,name=user_message,json=userMessage,proto3" json:"user_message,omitempty"`
// Optional image attachments for vision models (photo/sticker/GIF frame).
// When non-empty, GenerateAnswer routes to LLM_VISION_MODEL and builds a
// multimodal user message; image-generation intent is skipped.
Images []*InputImage `protobuf:"bytes,12,rep,name=images,proto3" json:"images,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -372,6 +376,74 @@ func (x *AIRequest) GetUserMessage() string {
return ""
}
func (x *AIRequest) GetImages() []*InputImage {
if x != nil {
return x.Images
}
return nil
}
// InputImage — one vision attachment (raw bytes, not base64).
type InputImage struct {
state protoimpl.MessageState `protogen:"open.v1"`
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` // raw image bytes (jpeg/png/webp/gif)
MimeType string `protobuf:"bytes,2,opt,name=mime_type,json=mimeType,proto3" json:"mime_type,omitempty"` // e.g. image/jpeg
Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` // optional client hint: photo, sticker, animation, reply_photo, …
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *InputImage) Reset() {
*x = InputImage{}
mi := &file_ai_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *InputImage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InputImage) ProtoMessage() {}
func (x *InputImage) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use InputImage.ProtoReflect.Descriptor instead.
func (*InputImage) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{1}
}
func (x *InputImage) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
func (x *InputImage) GetMimeType() string {
if x != nil {
return x.MimeType
}
return ""
}
func (x *InputImage) GetSource() string {
if x != nil {
return x.Source
}
return ""
}
// UsedMemory — снимок одного воспоминания, участвовавшего в генерации ответа.
type UsedMemory struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -389,7 +461,7 @@ type UsedMemory struct {
func (x *UsedMemory) Reset() {
*x = UsedMemory{}
mi := &file_ai_proto_msgTypes[1]
mi := &file_ai_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -401,7 +473,7 @@ func (x *UsedMemory) String() string {
func (*UsedMemory) ProtoMessage() {}
func (x *UsedMemory) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[1]
mi := &file_ai_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -414,7 +486,7 @@ func (x *UsedMemory) ProtoReflect() protoreflect.Message {
// Deprecated: Use UsedMemory.ProtoReflect.Descriptor instead.
func (*UsedMemory) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{1}
return file_ai_proto_rawDescGZIP(), []int{2}
}
func (x *UsedMemory) GetId() int64 {
@ -483,7 +555,7 @@ type AnswerGenerationOptions struct {
func (x *AnswerGenerationOptions) Reset() {
*x = AnswerGenerationOptions{}
mi := &file_ai_proto_msgTypes[2]
mi := &file_ai_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -495,7 +567,7 @@ func (x *AnswerGenerationOptions) String() string {
func (*AnswerGenerationOptions) ProtoMessage() {}
func (x *AnswerGenerationOptions) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[2]
mi := &file_ai_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -508,7 +580,7 @@ func (x *AnswerGenerationOptions) ProtoReflect() protoreflect.Message {
// Deprecated: Use AnswerGenerationOptions.ProtoReflect.Descriptor instead.
func (*AnswerGenerationOptions) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{2}
return file_ai_proto_rawDescGZIP(), []int{3}
}
func (x *AnswerGenerationOptions) GetIncludeUserMemories() bool {
@ -539,7 +611,7 @@ type AIResponse struct {
func (x *AIResponse) Reset() {
*x = AIResponse{}
mi := &file_ai_proto_msgTypes[3]
mi := &file_ai_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -551,7 +623,7 @@ func (x *AIResponse) String() string {
func (*AIResponse) ProtoMessage() {}
func (x *AIResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[3]
mi := &file_ai_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -564,7 +636,7 @@ func (x *AIResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use AIResponse.ProtoReflect.Descriptor instead.
func (*AIResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{3}
return file_ai_proto_rawDescGZIP(), []int{4}
}
func (x *AIResponse) GetContent() string {
@ -654,7 +726,7 @@ type GetAnswerJobRequest struct {
func (x *GetAnswerJobRequest) Reset() {
*x = GetAnswerJobRequest{}
mi := &file_ai_proto_msgTypes[4]
mi := &file_ai_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -666,7 +738,7 @@ func (x *GetAnswerJobRequest) String() string {
func (*GetAnswerJobRequest) ProtoMessage() {}
func (x *GetAnswerJobRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[4]
mi := &file_ai_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -679,7 +751,7 @@ func (x *GetAnswerJobRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetAnswerJobRequest.ProtoReflect.Descriptor instead.
func (*GetAnswerJobRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{4}
return file_ai_proto_rawDescGZIP(), []int{5}
}
func (x *GetAnswerJobRequest) GetJobId() string {
@ -707,7 +779,7 @@ type AnswerJobResponse struct {
func (x *AnswerJobResponse) Reset() {
*x = AnswerJobResponse{}
mi := &file_ai_proto_msgTypes[5]
mi := &file_ai_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -719,7 +791,7 @@ func (x *AnswerJobResponse) String() string {
func (*AnswerJobResponse) ProtoMessage() {}
func (x *AnswerJobResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[5]
mi := &file_ai_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -732,7 +804,7 @@ func (x *AnswerJobResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use AnswerJobResponse.ProtoReflect.Descriptor instead.
func (*AnswerJobResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{5}
return file_ai_proto_rawDescGZIP(), []int{6}
}
func (x *AnswerJobResponse) GetState() AnswerJobState {
@ -792,7 +864,7 @@ type ToolCallTrace struct {
func (x *ToolCallTrace) Reset() {
*x = ToolCallTrace{}
mi := &file_ai_proto_msgTypes[6]
mi := &file_ai_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -804,7 +876,7 @@ func (x *ToolCallTrace) String() string {
func (*ToolCallTrace) ProtoMessage() {}
func (x *ToolCallTrace) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[6]
mi := &file_ai_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -817,7 +889,7 @@ func (x *ToolCallTrace) ProtoReflect() protoreflect.Message {
// Deprecated: Use ToolCallTrace.ProtoReflect.Descriptor instead.
func (*ToolCallTrace) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{6}
return file_ai_proto_rawDescGZIP(), []int{7}
}
func (x *ToolCallTrace) GetCallId() string {
@ -872,7 +944,7 @@ type GetAIResponseTraceRequest struct {
func (x *GetAIResponseTraceRequest) Reset() {
*x = GetAIResponseTraceRequest{}
mi := &file_ai_proto_msgTypes[7]
mi := &file_ai_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -884,7 +956,7 @@ func (x *GetAIResponseTraceRequest) String() string {
func (*GetAIResponseTraceRequest) ProtoMessage() {}
func (x *GetAIResponseTraceRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[7]
mi := &file_ai_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -897,7 +969,7 @@ func (x *GetAIResponseTraceRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetAIResponseTraceRequest.ProtoReflect.Descriptor instead.
func (*GetAIResponseTraceRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{7}
return file_ai_proto_rawDescGZIP(), []int{8}
}
func (x *GetAIResponseTraceRequest) GetId() string {
@ -931,7 +1003,7 @@ type GetAIResponseTraceResponse struct {
func (x *GetAIResponseTraceResponse) Reset() {
*x = GetAIResponseTraceResponse{}
mi := &file_ai_proto_msgTypes[8]
mi := &file_ai_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -943,7 +1015,7 @@ func (x *GetAIResponseTraceResponse) String() string {
func (*GetAIResponseTraceResponse) ProtoMessage() {}
func (x *GetAIResponseTraceResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[8]
mi := &file_ai_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -956,7 +1028,7 @@ func (x *GetAIResponseTraceResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetAIResponseTraceResponse.ProtoReflect.Descriptor instead.
func (*GetAIResponseTraceResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{8}
return file_ai_proto_rawDescGZIP(), []int{9}
}
func (x *GetAIResponseTraceResponse) GetId() string {
@ -1077,7 +1149,7 @@ type CreateSessionRequest struct {
func (x *CreateSessionRequest) Reset() {
*x = CreateSessionRequest{}
mi := &file_ai_proto_msgTypes[9]
mi := &file_ai_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1089,7 +1161,7 @@ func (x *CreateSessionRequest) String() string {
func (*CreateSessionRequest) ProtoMessage() {}
func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[9]
mi := &file_ai_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1102,7 +1174,7 @@ func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateSessionRequest.ProtoReflect.Descriptor instead.
func (*CreateSessionRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{9}
return file_ai_proto_rawDescGZIP(), []int{10}
}
func (x *CreateSessionRequest) GetUserId() string {
@ -1145,7 +1217,7 @@ type CreateSessionResponse struct {
func (x *CreateSessionResponse) Reset() {
*x = CreateSessionResponse{}
mi := &file_ai_proto_msgTypes[10]
mi := &file_ai_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1157,7 +1229,7 @@ func (x *CreateSessionResponse) String() string {
func (*CreateSessionResponse) ProtoMessage() {}
func (x *CreateSessionResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[10]
mi := &file_ai_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1170,7 +1242,7 @@ func (x *CreateSessionResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateSessionResponse.ProtoReflect.Descriptor instead.
func (*CreateSessionResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{10}
return file_ai_proto_rawDescGZIP(), []int{11}
}
func (x *CreateSessionResponse) GetSessionId() string {
@ -1208,7 +1280,7 @@ type AskInSessionRequest struct {
func (x *AskInSessionRequest) Reset() {
*x = AskInSessionRequest{}
mi := &file_ai_proto_msgTypes[11]
mi := &file_ai_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1220,7 +1292,7 @@ func (x *AskInSessionRequest) String() string {
func (*AskInSessionRequest) ProtoMessage() {}
func (x *AskInSessionRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[11]
mi := &file_ai_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1233,7 +1305,7 @@ func (x *AskInSessionRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use AskInSessionRequest.ProtoReflect.Descriptor instead.
func (*AskInSessionRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{11}
return file_ai_proto_rawDescGZIP(), []int{12}
}
func (x *AskInSessionRequest) GetSessionId() string {
@ -1286,7 +1358,7 @@ type SessionStatusResponse struct {
func (x *SessionStatusResponse) Reset() {
*x = SessionStatusResponse{}
mi := &file_ai_proto_msgTypes[12]
mi := &file_ai_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1298,7 +1370,7 @@ func (x *SessionStatusResponse) String() string {
func (*SessionStatusResponse) ProtoMessage() {}
func (x *SessionStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[12]
mi := &file_ai_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1311,7 +1383,7 @@ func (x *SessionStatusResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SessionStatusResponse.ProtoReflect.Descriptor instead.
func (*SessionStatusResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{12}
return file_ai_proto_rawDescGZIP(), []int{13}
}
func (x *SessionStatusResponse) GetSessionId() string {
@ -1367,7 +1439,7 @@ type StatelessMessage struct {
func (x *StatelessMessage) Reset() {
*x = StatelessMessage{}
mi := &file_ai_proto_msgTypes[13]
mi := &file_ai_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1379,7 +1451,7 @@ func (x *StatelessMessage) String() string {
func (*StatelessMessage) ProtoMessage() {}
func (x *StatelessMessage) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[13]
mi := &file_ai_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1392,7 +1464,7 @@ func (x *StatelessMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use StatelessMessage.ProtoReflect.Descriptor instead.
func (*StatelessMessage) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{13}
return file_ai_proto_rawDescGZIP(), []int{14}
}
func (x *StatelessMessage) GetRole() string {
@ -1420,7 +1492,7 @@ type StatelessRequest struct {
func (x *StatelessRequest) Reset() {
*x = StatelessRequest{}
mi := &file_ai_proto_msgTypes[14]
mi := &file_ai_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1432,7 +1504,7 @@ func (x *StatelessRequest) String() string {
func (*StatelessRequest) ProtoMessage() {}
func (x *StatelessRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[14]
mi := &file_ai_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1445,7 +1517,7 @@ func (x *StatelessRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StatelessRequest.ProtoReflect.Descriptor instead.
func (*StatelessRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{14}
return file_ai_proto_rawDescGZIP(), []int{15}
}
func (x *StatelessRequest) GetMessages() []*StatelessMessage {
@ -1471,7 +1543,7 @@ type HealthCheckRequest struct {
func (x *HealthCheckRequest) Reset() {
*x = HealthCheckRequest{}
mi := &file_ai_proto_msgTypes[15]
mi := &file_ai_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1483,7 +1555,7 @@ func (x *HealthCheckRequest) String() string {
func (*HealthCheckRequest) ProtoMessage() {}
func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[15]
mi := &file_ai_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1496,7 +1568,7 @@ func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use HealthCheckRequest.ProtoReflect.Descriptor instead.
func (*HealthCheckRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{15}
return file_ai_proto_rawDescGZIP(), []int{16}
}
// HealthCheckResponse для ответа на проверку здоровья
@ -1510,7 +1582,7 @@ type HealthCheckResponse struct {
func (x *HealthCheckResponse) Reset() {
*x = HealthCheckResponse{}
mi := &file_ai_proto_msgTypes[16]
mi := &file_ai_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1522,7 +1594,7 @@ func (x *HealthCheckResponse) String() string {
func (*HealthCheckResponse) ProtoMessage() {}
func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[16]
mi := &file_ai_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1535,7 +1607,7 @@ func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use HealthCheckResponse.ProtoReflect.Descriptor instead.
func (*HealthCheckResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{16}
return file_ai_proto_rawDescGZIP(), []int{17}
}
func (x *HealthCheckResponse) GetServing() bool {
@ -1567,7 +1639,7 @@ type AgentToolLoopOptions struct {
func (x *AgentToolLoopOptions) Reset() {
*x = AgentToolLoopOptions{}
mi := &file_ai_proto_msgTypes[17]
mi := &file_ai_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1579,7 +1651,7 @@ func (x *AgentToolLoopOptions) String() string {
func (*AgentToolLoopOptions) ProtoMessage() {}
func (x *AgentToolLoopOptions) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[17]
mi := &file_ai_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1592,7 +1664,7 @@ func (x *AgentToolLoopOptions) ProtoReflect() protoreflect.Message {
// Deprecated: Use AgentToolLoopOptions.ProtoReflect.Descriptor instead.
func (*AgentToolLoopOptions) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{17}
return file_ai_proto_rawDescGZIP(), []int{18}
}
func (x *AgentToolLoopOptions) GetToolsEnabled() bool {
@ -1642,7 +1714,7 @@ type AgentResponseContract struct {
func (x *AgentResponseContract) Reset() {
*x = AgentResponseContract{}
mi := &file_ai_proto_msgTypes[18]
mi := &file_ai_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1654,7 +1726,7 @@ func (x *AgentResponseContract) String() string {
func (*AgentResponseContract) ProtoMessage() {}
func (x *AgentResponseContract) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[18]
mi := &file_ai_proto_msgTypes[19]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1667,7 +1739,7 @@ func (x *AgentResponseContract) ProtoReflect() protoreflect.Message {
// Deprecated: Use AgentResponseContract.ProtoReflect.Descriptor instead.
func (*AgentResponseContract) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{18}
return file_ai_proto_rawDescGZIP(), []int{19}
}
func (x *AgentResponseContract) GetFormat() AgentOutputFormat {
@ -1712,7 +1784,7 @@ type AgentRequest struct {
func (x *AgentRequest) Reset() {
*x = AgentRequest{}
mi := &file_ai_proto_msgTypes[19]
mi := &file_ai_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1724,7 +1796,7 @@ func (x *AgentRequest) String() string {
func (*AgentRequest) ProtoMessage() {}
func (x *AgentRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[19]
mi := &file_ai_proto_msgTypes[20]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1737,7 +1809,7 @@ func (x *AgentRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use AgentRequest.ProtoReflect.Descriptor instead.
func (*AgentRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{19}
return file_ai_proto_rawDescGZIP(), []int{20}
}
func (x *AgentRequest) GetMessages() []*StatelessMessage {
@ -1838,7 +1910,7 @@ type AgentUsage struct {
func (x *AgentUsage) Reset() {
*x = AgentUsage{}
mi := &file_ai_proto_msgTypes[20]
mi := &file_ai_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1850,7 +1922,7 @@ func (x *AgentUsage) String() string {
func (*AgentUsage) ProtoMessage() {}
func (x *AgentUsage) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[20]
mi := &file_ai_proto_msgTypes[21]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1863,7 +1935,7 @@ func (x *AgentUsage) ProtoReflect() protoreflect.Message {
// Deprecated: Use AgentUsage.ProtoReflect.Descriptor instead.
func (*AgentUsage) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{20}
return file_ai_proto_rawDescGZIP(), []int{21}
}
func (x *AgentUsage) GetToolIterations() uint32 {
@ -1916,7 +1988,7 @@ type AgentResponse struct {
func (x *AgentResponse) Reset() {
*x = AgentResponse{}
mi := &file_ai_proto_msgTypes[21]
mi := &file_ai_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1928,7 +2000,7 @@ func (x *AgentResponse) String() string {
func (*AgentResponse) ProtoMessage() {}
func (x *AgentResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[21]
mi := &file_ai_proto_msgTypes[22]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1941,7 +2013,7 @@ func (x *AgentResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use AgentResponse.ProtoReflect.Descriptor instead.
func (*AgentResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{21}
return file_ai_proto_rawDescGZIP(), []int{22}
}
func (x *AgentResponse) GetStatus() AnswerStatus {
@ -1997,7 +2069,7 @@ type CancelAnswerJobRequest struct {
func (x *CancelAnswerJobRequest) Reset() {
*x = CancelAnswerJobRequest{}
mi := &file_ai_proto_msgTypes[22]
mi := &file_ai_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2009,7 +2081,7 @@ func (x *CancelAnswerJobRequest) String() string {
func (*CancelAnswerJobRequest) ProtoMessage() {}
func (x *CancelAnswerJobRequest) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[22]
mi := &file_ai_proto_msgTypes[23]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2022,7 +2094,7 @@ func (x *CancelAnswerJobRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CancelAnswerJobRequest.ProtoReflect.Descriptor instead.
func (*CancelAnswerJobRequest) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{22}
return file_ai_proto_rawDescGZIP(), []int{23}
}
func (x *CancelAnswerJobRequest) GetJobId() string {
@ -2051,7 +2123,7 @@ type CancelAnswerJobResponse struct {
func (x *CancelAnswerJobResponse) Reset() {
*x = CancelAnswerJobResponse{}
mi := &file_ai_proto_msgTypes[23]
mi := &file_ai_proto_msgTypes[24]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2063,7 +2135,7 @@ func (x *CancelAnswerJobResponse) String() string {
func (*CancelAnswerJobResponse) ProtoMessage() {}
func (x *CancelAnswerJobResponse) ProtoReflect() protoreflect.Message {
mi := &file_ai_proto_msgTypes[23]
mi := &file_ai_proto_msgTypes[24]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2076,7 +2148,7 @@ func (x *CancelAnswerJobResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CancelAnswerJobResponse.ProtoReflect.Descriptor instead.
func (*CancelAnswerJobResponse) Descriptor() ([]byte, []int) {
return file_ai_proto_rawDescGZIP(), []int{23}
return file_ai_proto_rawDescGZIP(), []int{24}
}
func (x *CancelAnswerJobResponse) GetState() AnswerJobState {
@ -2104,7 +2176,7 @@ var File_ai_proto protoreflect.FileDescriptor
const file_ai_proto_rawDesc = "" +
"\n" +
"\bai.proto\x12\x02ai\"\xbc\x03\n" +
"\bai.proto\x12\x02ai\"\xe4\x03\n" +
"\tAIRequest\x12\x12\n" +
"\x04text\x18\x01 \x01(\tR\x04text\x12!\n" +
"\fbot_username\x18\x02 \x01(\tR\vbotUsername\x12\x1d\n" +
@ -2118,7 +2190,13 @@ const file_ai_proto_rawDesc = "" +
"\x11supports_deferred\x18\t \x01(\bR\x10supportsDeferred\x123\n" +
"\rused_memories\x18\n" +
" \x03(\v2\x0e.ai.UsedMemoryR\fusedMemories\x12!\n" +
"\fuser_message\x18\v \x01(\tR\vuserMessage\"\xd4\x01\n" +
"\fuser_message\x18\v \x01(\tR\vuserMessage\x12&\n" +
"\x06images\x18\f \x03(\v2\x0e.ai.InputImageR\x06images\"U\n" +
"\n" +
"InputImage\x12\x12\n" +
"\x04data\x18\x01 \x01(\fR\x04data\x12\x1b\n" +
"\tmime_type\x18\x02 \x01(\tR\bmimeType\x12\x16\n" +
"\x06source\x18\x03 \x01(\tR\x06source\"\xd4\x01\n" +
"\n" +
"UsedMemory\x12\x0e\n" +
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x17\n" +
@ -2327,80 +2405,82 @@ func file_ai_proto_rawDescGZIP() []byte {
}
var file_ai_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
var file_ai_proto_msgTypes = make([]protoimpl.MessageInfo, 25)
var file_ai_proto_msgTypes = make([]protoimpl.MessageInfo, 26)
var file_ai_proto_goTypes = []any{
(ResponseKind)(0), // 0: ai.ResponseKind
(AnswerStatus)(0), // 1: ai.AnswerStatus
(AnswerJobState)(0), // 2: ai.AnswerJobState
(AgentOutputFormat)(0), // 3: ai.AgentOutputFormat
(*AIRequest)(nil), // 4: ai.AIRequest
(*UsedMemory)(nil), // 5: ai.UsedMemory
(*AnswerGenerationOptions)(nil), // 6: ai.AnswerGenerationOptions
(*AIResponse)(nil), // 7: ai.AIResponse
(*GetAnswerJobRequest)(nil), // 8: ai.GetAnswerJobRequest
(*AnswerJobResponse)(nil), // 9: ai.AnswerJobResponse
(*ToolCallTrace)(nil), // 10: ai.ToolCallTrace
(*GetAIResponseTraceRequest)(nil), // 11: ai.GetAIResponseTraceRequest
(*GetAIResponseTraceResponse)(nil), // 12: ai.GetAIResponseTraceResponse
(*CreateSessionRequest)(nil), // 13: ai.CreateSessionRequest
(*CreateSessionResponse)(nil), // 14: ai.CreateSessionResponse
(*AskInSessionRequest)(nil), // 15: ai.AskInSessionRequest
(*SessionStatusResponse)(nil), // 16: ai.SessionStatusResponse
(*StatelessMessage)(nil), // 17: ai.StatelessMessage
(*StatelessRequest)(nil), // 18: ai.StatelessRequest
(*HealthCheckRequest)(nil), // 19: ai.HealthCheckRequest
(*HealthCheckResponse)(nil), // 20: ai.HealthCheckResponse
(*AgentToolLoopOptions)(nil), // 21: ai.AgentToolLoopOptions
(*AgentResponseContract)(nil), // 22: ai.AgentResponseContract
(*AgentRequest)(nil), // 23: ai.AgentRequest
(*AgentUsage)(nil), // 24: ai.AgentUsage
(*AgentResponse)(nil), // 25: ai.AgentResponse
(*CancelAnswerJobRequest)(nil), // 26: ai.CancelAnswerJobRequest
(*CancelAnswerJobResponse)(nil), // 27: ai.CancelAnswerJobResponse
nil, // 28: ai.AgentRequest.MetadataEntry
(*InputImage)(nil), // 5: ai.InputImage
(*UsedMemory)(nil), // 6: ai.UsedMemory
(*AnswerGenerationOptions)(nil), // 7: ai.AnswerGenerationOptions
(*AIResponse)(nil), // 8: ai.AIResponse
(*GetAnswerJobRequest)(nil), // 9: ai.GetAnswerJobRequest
(*AnswerJobResponse)(nil), // 10: ai.AnswerJobResponse
(*ToolCallTrace)(nil), // 11: ai.ToolCallTrace
(*GetAIResponseTraceRequest)(nil), // 12: ai.GetAIResponseTraceRequest
(*GetAIResponseTraceResponse)(nil), // 13: ai.GetAIResponseTraceResponse
(*CreateSessionRequest)(nil), // 14: ai.CreateSessionRequest
(*CreateSessionResponse)(nil), // 15: ai.CreateSessionResponse
(*AskInSessionRequest)(nil), // 16: ai.AskInSessionRequest
(*SessionStatusResponse)(nil), // 17: ai.SessionStatusResponse
(*StatelessMessage)(nil), // 18: ai.StatelessMessage
(*StatelessRequest)(nil), // 19: ai.StatelessRequest
(*HealthCheckRequest)(nil), // 20: ai.HealthCheckRequest
(*HealthCheckResponse)(nil), // 21: ai.HealthCheckResponse
(*AgentToolLoopOptions)(nil), // 22: ai.AgentToolLoopOptions
(*AgentResponseContract)(nil), // 23: ai.AgentResponseContract
(*AgentRequest)(nil), // 24: ai.AgentRequest
(*AgentUsage)(nil), // 25: ai.AgentUsage
(*AgentResponse)(nil), // 26: ai.AgentResponse
(*CancelAnswerJobRequest)(nil), // 27: ai.CancelAnswerJobRequest
(*CancelAnswerJobResponse)(nil), // 28: ai.CancelAnswerJobResponse
nil, // 29: ai.AgentRequest.MetadataEntry
}
var file_ai_proto_depIdxs = []int32{
6, // 0: ai.AIRequest.options:type_name -> ai.AnswerGenerationOptions
5, // 1: ai.AIRequest.used_memories:type_name -> ai.UsedMemory
1, // 2: ai.AIResponse.status:type_name -> ai.AnswerStatus
0, // 3: ai.AIResponse.kind:type_name -> ai.ResponseKind
2, // 4: ai.AnswerJobResponse.state:type_name -> ai.AnswerJobState
24, // 5: ai.AnswerJobResponse.agent_usage:type_name -> ai.AgentUsage
5, // 6: ai.GetAIResponseTraceResponse.memories:type_name -> ai.UsedMemory
10, // 7: ai.GetAIResponseTraceResponse.tool_calls:type_name -> ai.ToolCallTrace
6, // 8: ai.AskInSessionRequest.options:type_name -> ai.AnswerGenerationOptions
17, // 9: ai.StatelessRequest.messages:type_name -> ai.StatelessMessage
3, // 10: ai.AgentResponseContract.format:type_name -> ai.AgentOutputFormat
17, // 11: ai.AgentRequest.messages:type_name -> ai.StatelessMessage
21, // 12: ai.AgentRequest.tool_loop:type_name -> ai.AgentToolLoopOptions
22, // 13: ai.AgentRequest.response_contract:type_name -> ai.AgentResponseContract
28, // 14: ai.AgentRequest.metadata:type_name -> ai.AgentRequest.MetadataEntry
1, // 15: ai.AgentResponse.status:type_name -> ai.AnswerStatus
24, // 16: ai.AgentResponse.usage:type_name -> ai.AgentUsage
2, // 17: ai.CancelAnswerJobResponse.state:type_name -> ai.AnswerJobState
23, // 18: ai.AIService.RunAgent:input_type -> ai.AgentRequest
26, // 19: ai.AIService.CancelAnswerJob:input_type -> ai.CancelAnswerJobRequest
4, // 20: ai.AIService.GenerateAnswer:input_type -> ai.AIRequest
18, // 21: ai.AIService.GenerateStateless:input_type -> ai.StatelessRequest
19, // 22: ai.AIService.HealthCheck:input_type -> ai.HealthCheckRequest
13, // 23: ai.AIService.CreateSession:input_type -> ai.CreateSessionRequest
15, // 24: ai.AIService.AskInSession:input_type -> ai.AskInSessionRequest
8, // 25: ai.AIService.GetAnswerJob:input_type -> ai.GetAnswerJobRequest
11, // 26: ai.AIService.GetAIResponseTrace:input_type -> ai.GetAIResponseTraceRequest
25, // 27: ai.AIService.RunAgent:output_type -> ai.AgentResponse
27, // 28: ai.AIService.CancelAnswerJob:output_type -> ai.CancelAnswerJobResponse
7, // 29: ai.AIService.GenerateAnswer:output_type -> ai.AIResponse
7, // 30: ai.AIService.GenerateStateless:output_type -> ai.AIResponse
20, // 31: ai.AIService.HealthCheck:output_type -> ai.HealthCheckResponse
14, // 32: ai.AIService.CreateSession:output_type -> ai.CreateSessionResponse
16, // 33: ai.AIService.AskInSession:output_type -> ai.SessionStatusResponse
9, // 34: ai.AIService.GetAnswerJob:output_type -> ai.AnswerJobResponse
12, // 35: ai.AIService.GetAIResponseTrace:output_type -> ai.GetAIResponseTraceResponse
27, // [27:36] is the sub-list for method output_type
18, // [18:27] is the sub-list for method input_type
18, // [18:18] is the sub-list for extension type_name
18, // [18:18] is the sub-list for extension extendee
0, // [0:18] is the sub-list for field type_name
7, // 0: ai.AIRequest.options:type_name -> ai.AnswerGenerationOptions
6, // 1: ai.AIRequest.used_memories:type_name -> ai.UsedMemory
5, // 2: ai.AIRequest.images:type_name -> ai.InputImage
1, // 3: ai.AIResponse.status:type_name -> ai.AnswerStatus
0, // 4: ai.AIResponse.kind:type_name -> ai.ResponseKind
2, // 5: ai.AnswerJobResponse.state:type_name -> ai.AnswerJobState
25, // 6: ai.AnswerJobResponse.agent_usage:type_name -> ai.AgentUsage
6, // 7: ai.GetAIResponseTraceResponse.memories:type_name -> ai.UsedMemory
11, // 8: ai.GetAIResponseTraceResponse.tool_calls:type_name -> ai.ToolCallTrace
7, // 9: ai.AskInSessionRequest.options:type_name -> ai.AnswerGenerationOptions
18, // 10: ai.StatelessRequest.messages:type_name -> ai.StatelessMessage
3, // 11: ai.AgentResponseContract.format:type_name -> ai.AgentOutputFormat
18, // 12: ai.AgentRequest.messages:type_name -> ai.StatelessMessage
22, // 13: ai.AgentRequest.tool_loop:type_name -> ai.AgentToolLoopOptions
23, // 14: ai.AgentRequest.response_contract:type_name -> ai.AgentResponseContract
29, // 15: ai.AgentRequest.metadata:type_name -> ai.AgentRequest.MetadataEntry
1, // 16: ai.AgentResponse.status:type_name -> ai.AnswerStatus
25, // 17: ai.AgentResponse.usage:type_name -> ai.AgentUsage
2, // 18: ai.CancelAnswerJobResponse.state:type_name -> ai.AnswerJobState
24, // 19: ai.AIService.RunAgent:input_type -> ai.AgentRequest
27, // 20: ai.AIService.CancelAnswerJob:input_type -> ai.CancelAnswerJobRequest
4, // 21: ai.AIService.GenerateAnswer:input_type -> ai.AIRequest
19, // 22: ai.AIService.GenerateStateless:input_type -> ai.StatelessRequest
20, // 23: ai.AIService.HealthCheck:input_type -> ai.HealthCheckRequest
14, // 24: ai.AIService.CreateSession:input_type -> ai.CreateSessionRequest
16, // 25: ai.AIService.AskInSession:input_type -> ai.AskInSessionRequest
9, // 26: ai.AIService.GetAnswerJob:input_type -> ai.GetAnswerJobRequest
12, // 27: ai.AIService.GetAIResponseTrace:input_type -> ai.GetAIResponseTraceRequest
26, // 28: ai.AIService.RunAgent:output_type -> ai.AgentResponse
28, // 29: ai.AIService.CancelAnswerJob:output_type -> ai.CancelAnswerJobResponse
8, // 30: ai.AIService.GenerateAnswer:output_type -> ai.AIResponse
8, // 31: ai.AIService.GenerateStateless:output_type -> ai.AIResponse
21, // 32: ai.AIService.HealthCheck:output_type -> ai.HealthCheckResponse
15, // 33: ai.AIService.CreateSession:output_type -> ai.CreateSessionResponse
17, // 34: ai.AIService.AskInSession:output_type -> ai.SessionStatusResponse
10, // 35: ai.AIService.GetAnswerJob:output_type -> ai.AnswerJobResponse
13, // 36: ai.AIService.GetAIResponseTrace:output_type -> ai.GetAIResponseTraceResponse
28, // [28:37] is the sub-list for method output_type
19, // [19:28] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
}
func init() { file_ai_proto_init() }
@ -2414,7 +2494,7 @@ func file_ai_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ai_proto_rawDesc), len(file_ai_proto_rawDesc)),
NumEnums: 4,
NumMessages: 25,
NumMessages: 26,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -22,6 +22,17 @@ message AIRequest {
// Live chat clients (Telegram/Steam) send this; when empty, image intent
// detection is skipped and the request is treated as normal chat.
string user_message = 11;
// Optional image attachments for vision models (photo/sticker/GIF frame).
// When non-empty, GenerateAnswer routes to LLM_VISION_MODEL and builds a
// multimodal user message; image-generation intent is skipped.
repeated InputImage images = 12;
}
// InputImage — one vision attachment (raw bytes, not base64).
message InputImage {
bytes data = 1; // raw image bytes (jpeg/png/webp/gif)
string mime_type = 2; // e.g. image/jpeg
string source = 3; // optional client hint: photo, sticker, animation, reply_photo, …
}
// UsedMemory — снимок одного воспоминания, участвовавшего в генерации ответа.