diff --git a/ai.pb.go b/ai.pb.go index 55dfa44..a6bb371 100644 --- a/ai.pb.go +++ b/ai.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 -// protoc v7.34.0 +// protoc-gen-go v1.36.12 +// protoc v7.36.0 // source: ai.proto package proto @@ -204,8 +204,11 @@ type AIRequest struct { TelegramUserId int64 `protobuf:"varint,7,opt,name=telegram_user_id,json=telegramUserId,proto3" json:"telegram_user_id,omitempty"` // Telegram user ID для применения пользовательских настроек (стиль ответа) SteamUserId int64 `protobuf:"varint,8,opt,name=steam_user_id,json=steamUserId,proto3" json:"steam_user_id,omitempty"` // SteamID64 отправителя для живых Steam-диалогов (l-ai-steam) - тот же "сигнал живого чата", что telegram_user_id, для второй платформы SupportsDeferred bool `protobuf:"varint,9,opt,name=supports_deferred,json=supportsDeferred,proto3" json:"supports_deferred,omitempty"` // Клиент умеет обрабатывать status=PENDING + GetAnswerJob (async тяжёлые тулзы). Старые клиенты не ставят — тяжёлые тулзы исполняются синхронно, как раньше. - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Структурированные воспоминания, которые клиент уже вложил в text (для debug-trace). + // Core сохраняет их as-is на ai_response_traces — не перезапрашивает memories-сервис. + UsedMemories []*UsedMemory `protobuf:"bytes,10,rep,name=used_memories,json=usedMemories,proto3" json:"used_memories,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AIRequest) Reset() { @@ -301,6 +304,114 @@ func (x *AIRequest) GetSupportsDeferred() bool { return false } +func (x *AIRequest) GetUsedMemories() []*UsedMemory { + if x != nil { + return x.UsedMemories + } + return nil +} + +// UsedMemory — снимок одного воспоминания, участвовавшего в генерации ответа. +type UsedMemory struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // ID в l-ai-memories (для будущего delete с debug-страницы) + UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + Key string `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` + Value string `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` + Category string `protobuf:"bytes,6,opt,name=category,proto3" json:"category,omitempty"` + Priority string `protobuf:"bytes,7,opt,name=priority,proto3" json:"priority,omitempty"` + SourceLabel string `protobuf:"bytes,8,opt,name=source_label,json=sourceLabel,proto3" json:"source_label,omitempty"` // контекст от клиента, напр. "автор сообщения (@nick)" + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UsedMemory) Reset() { + *x = UsedMemory{} + mi := &file_ai_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UsedMemory) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UsedMemory) ProtoMessage() {} + +func (x *UsedMemory) 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 UsedMemory.ProtoReflect.Descriptor instead. +func (*UsedMemory) Descriptor() ([]byte, []int) { + return file_ai_proto_rawDescGZIP(), []int{1} +} + +func (x *UsedMemory) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UsedMemory) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *UsedMemory) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *UsedMemory) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *UsedMemory) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *UsedMemory) GetCategory() string { + if x != nil { + return x.Category + } + return "" +} + +func (x *UsedMemory) GetPriority() string { + if x != nil { + return x.Priority + } + return "" +} + +func (x *UsedMemory) GetSourceLabel() string { + if x != nil { + return x.SourceLabel + } + return "" +} + // AnswerGenerationOptions содержит дополнительные опции для генерации ответа type AnswerGenerationOptions struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -311,7 +422,7 @@ type AnswerGenerationOptions struct { func (x *AnswerGenerationOptions) Reset() { *x = AnswerGenerationOptions{} - mi := &file_ai_proto_msgTypes[1] + mi := &file_ai_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -323,7 +434,7 @@ func (x *AnswerGenerationOptions) String() string { func (*AnswerGenerationOptions) ProtoMessage() {} func (x *AnswerGenerationOptions) 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 { @@ -336,7 +447,7 @@ func (x *AnswerGenerationOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use AnswerGenerationOptions.ProtoReflect.Descriptor instead. func (*AnswerGenerationOptions) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{1} + return file_ai_proto_rawDescGZIP(), []int{2} } func (x *AnswerGenerationOptions) GetIncludeUserMemories() bool { @@ -355,14 +466,15 @@ type AIResponse struct { ReasoningContent string `protobuf:"bytes,4,opt,name=reasoning_content,json=reasoningContent,proto3" json:"reasoning_content,omitempty"` // Текст рассуждений (если включён режим reasoning) Status AnswerStatus `protobuf:"varint,5,opt,name=status,proto3,enum=ai.AnswerStatus" json:"status,omitempty"` // COMPLETE (или UNSPECIFIED для старых клиентов) — content финальный; // PENDING — запущена долгая job, content это interim, финал тянуть через GetAnswerJob(job_id) - JobId string `protobuf:"bytes,6,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` // Идентификатор отложенной job (только при status=PENDING) + JobId string `protobuf:"bytes,6,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` // Идентификатор отложенной job (только при status=PENDING) + ResponseId string `protobuf:"bytes,7,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"` // UUID (hex) debug-trace; доступен уже при PENDING unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *AIResponse) Reset() { *x = AIResponse{} - mi := &file_ai_proto_msgTypes[2] + mi := &file_ai_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -374,7 +486,7 @@ func (x *AIResponse) String() string { func (*AIResponse) ProtoMessage() {} func (x *AIResponse) 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 { @@ -387,7 +499,7 @@ func (x *AIResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AIResponse.ProtoReflect.Descriptor instead. func (*AIResponse) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{2} + return file_ai_proto_rawDescGZIP(), []int{3} } func (x *AIResponse) GetContent() string { @@ -432,6 +544,13 @@ func (x *AIResponse) GetJobId() string { return "" } +func (x *AIResponse) GetResponseId() string { + if x != nil { + return x.ResponseId + } + return "" +} + // GetAnswerJobRequest запрашивает статус отложенной генерации ответа. type GetAnswerJobRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -442,7 +561,7 @@ type GetAnswerJobRequest struct { func (x *GetAnswerJobRequest) Reset() { *x = GetAnswerJobRequest{} - mi := &file_ai_proto_msgTypes[3] + mi := &file_ai_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -454,7 +573,7 @@ func (x *GetAnswerJobRequest) String() string { func (*GetAnswerJobRequest) ProtoMessage() {} func (x *GetAnswerJobRequest) 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 { @@ -467,7 +586,7 @@ func (x *GetAnswerJobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAnswerJobRequest.ProtoReflect.Descriptor instead. func (*GetAnswerJobRequest) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{3} + return file_ai_proto_rawDescGZIP(), []int{4} } func (x *GetAnswerJobRequest) GetJobId() string { @@ -488,13 +607,14 @@ type AnswerJobResponse struct { // возвращает synchronous RunAgent (реальные iterations/tool calls core, не // self-reported из ответа модели). Для legacy GenerateAnswer jobs не заполняется. AgentUsage *AgentUsage `protobuf:"bytes,5,opt,name=agent_usage,json=agentUsage,proto3" json:"agent_usage,omitempty"` + ResponseId string `protobuf:"bytes,6,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"` // тот же debug-trace id, что в AIResponse при PENDING unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *AnswerJobResponse) Reset() { *x = AnswerJobResponse{} - mi := &file_ai_proto_msgTypes[4] + mi := &file_ai_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -506,7 +626,7 @@ func (x *AnswerJobResponse) String() string { func (*AnswerJobResponse) ProtoMessage() {} func (x *AnswerJobResponse) 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 { @@ -519,7 +639,7 @@ func (x *AnswerJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AnswerJobResponse.ProtoReflect.Descriptor instead. func (*AnswerJobResponse) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{4} + return file_ai_proto_rawDescGZIP(), []int{5} } func (x *AnswerJobResponse) GetState() AnswerJobState { @@ -557,6 +677,300 @@ func (x *AnswerJobResponse) GetAgentUsage() *AgentUsage { return nil } +func (x *AnswerJobResponse) GetResponseId() string { + if x != nil { + return x.ResponseId + } + return "" +} + +// ToolCallTrace — один вызов тула во время GenerateAnswer (args + результат для модели). +type ToolCallTrace struct { + state protoimpl.MessageState `protogen:"open.v1"` + CallId string `protobuf:"bytes,1,opt,name=call_id,json=callId,proto3" json:"call_id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + ArgumentsJson string `protobuf:"bytes,3,opt,name=arguments_json,json=argumentsJson,proto3" json:"arguments_json,omitempty"` + Result string `protobuf:"bytes,4,opt,name=result,proto3" json:"result,omitempty"` + Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"` + Deferred bool `protobuf:"varint,6,opt,name=deferred,proto3" json:"deferred,omitempty"` // тяжёлый тул через l-evolver + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolCallTrace) Reset() { + *x = ToolCallTrace{} + mi := &file_ai_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolCallTrace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolCallTrace) ProtoMessage() {} + +func (x *ToolCallTrace) ProtoReflect() protoreflect.Message { + mi := &file_ai_proto_msgTypes[6] + 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 ToolCallTrace.ProtoReflect.Descriptor instead. +func (*ToolCallTrace) Descriptor() ([]byte, []int) { + return file_ai_proto_rawDescGZIP(), []int{6} +} + +func (x *ToolCallTrace) GetCallId() string { + if x != nil { + return x.CallId + } + return "" +} + +func (x *ToolCallTrace) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ToolCallTrace) GetArgumentsJson() string { + if x != nil { + return x.ArgumentsJson + } + return "" +} + +func (x *ToolCallTrace) GetResult() string { + if x != nil { + return x.Result + } + return "" +} + +func (x *ToolCallTrace) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *ToolCallTrace) GetDeferred() bool { + if x != nil { + return x.Deferred + } + return false +} + +// GetAIResponseTraceRequest — запрос debug-снимка генерации по UUID. +type GetAIResponseTraceRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // response_id (hex UUID без дефисов) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAIResponseTraceRequest) Reset() { + *x = GetAIResponseTraceRequest{} + mi := &file_ai_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAIResponseTraceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAIResponseTraceRequest) ProtoMessage() {} + +func (x *GetAIResponseTraceRequest) ProtoReflect() protoreflect.Message { + mi := &file_ai_proto_msgTypes[7] + 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 GetAIResponseTraceRequest.ProtoReflect.Descriptor instead. +func (*GetAIResponseTraceRequest) Descriptor() ([]byte, []int) { + return file_ai_proto_rawDescGZIP(), []int{7} +} + +func (x *GetAIResponseTraceRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// GetAIResponseTraceResponse — снимок того, что ушло в модель / вернулось. +type GetAIResponseTraceResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + BotUsername string `protobuf:"bytes,2,opt,name=bot_username,json=botUsername,proto3" json:"bot_username,omitempty"` + ModelName string `protobuf:"bytes,3,opt,name=model_name,json=modelName,proto3" json:"model_name,omitempty"` + TelegramUserId int64 `protobuf:"varint,4,opt,name=telegram_user_id,json=telegramUserId,proto3" json:"telegram_user_id,omitempty"` + GlobalUserId int64 `protobuf:"varint,5,opt,name=global_user_id,json=globalUserId,proto3" json:"global_user_id,omitempty"` + SystemPrompt string `protobuf:"bytes,6,opt,name=system_prompt,json=systemPrompt,proto3" json:"system_prompt,omitempty"` + UserPrompt string `protobuf:"bytes,7,opt,name=user_prompt,json=userPrompt,proto3" json:"user_prompt,omitempty"` + Memories []*UsedMemory `protobuf:"bytes,8,rep,name=memories,proto3" json:"memories,omitempty"` + ToolCalls []*ToolCallTrace `protobuf:"bytes,9,rep,name=tool_calls,json=toolCalls,proto3" json:"tool_calls,omitempty"` + Response string `protobuf:"bytes,10,opt,name=response,proto3" json:"response,omitempty"` + ReasoningContent string `protobuf:"bytes,11,opt,name=reasoning_content,json=reasoningContent,proto3" json:"reasoning_content,omitempty"` + Error string `protobuf:"bytes,12,opt,name=error,proto3" json:"error,omitempty"` + DurationMs float64 `protobuf:"fixed64,13,opt,name=duration_ms,json=durationMs,proto3" json:"duration_ms,omitempty"` + CreatedAtUnix int64 `protobuf:"varint,14,opt,name=created_at_unix,json=createdAtUnix,proto3" json:"created_at_unix,omitempty"` + Found bool `protobuf:"varint,15,opt,name=found,proto3" json:"found,omitempty"` // false — нет такого id / истёк TTL + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAIResponseTraceResponse) Reset() { + *x = GetAIResponseTraceResponse{} + mi := &file_ai_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAIResponseTraceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAIResponseTraceResponse) ProtoMessage() {} + +func (x *GetAIResponseTraceResponse) ProtoReflect() protoreflect.Message { + mi := &file_ai_proto_msgTypes[8] + 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 GetAIResponseTraceResponse.ProtoReflect.Descriptor instead. +func (*GetAIResponseTraceResponse) Descriptor() ([]byte, []int) { + return file_ai_proto_rawDescGZIP(), []int{8} +} + +func (x *GetAIResponseTraceResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetBotUsername() string { + if x != nil { + return x.BotUsername + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetModelName() string { + if x != nil { + return x.ModelName + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetTelegramUserId() int64 { + if x != nil { + return x.TelegramUserId + } + return 0 +} + +func (x *GetAIResponseTraceResponse) GetGlobalUserId() int64 { + if x != nil { + return x.GlobalUserId + } + return 0 +} + +func (x *GetAIResponseTraceResponse) GetSystemPrompt() string { + if x != nil { + return x.SystemPrompt + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetUserPrompt() string { + if x != nil { + return x.UserPrompt + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetMemories() []*UsedMemory { + if x != nil { + return x.Memories + } + return nil +} + +func (x *GetAIResponseTraceResponse) GetToolCalls() []*ToolCallTrace { + if x != nil { + return x.ToolCalls + } + return nil +} + +func (x *GetAIResponseTraceResponse) GetResponse() string { + if x != nil { + return x.Response + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetReasoningContent() string { + if x != nil { + return x.ReasoningContent + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *GetAIResponseTraceResponse) GetDurationMs() float64 { + if x != nil { + return x.DurationMs + } + return 0 +} + +func (x *GetAIResponseTraceResponse) GetCreatedAtUnix() int64 { + if x != nil { + return x.CreatedAtUnix + } + return 0 +} + +func (x *GetAIResponseTraceResponse) GetFound() bool { + if x != nil { + return x.Found + } + return false +} + // CreateSessionRequest для создания новой AI сессии type CreateSessionRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -570,7 +984,7 @@ type CreateSessionRequest struct { func (x *CreateSessionRequest) Reset() { *x = CreateSessionRequest{} - mi := &file_ai_proto_msgTypes[5] + mi := &file_ai_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -582,7 +996,7 @@ func (x *CreateSessionRequest) String() string { func (*CreateSessionRequest) ProtoMessage() {} func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[5] + mi := &file_ai_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -595,7 +1009,7 @@ func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSessionRequest.ProtoReflect.Descriptor instead. func (*CreateSessionRequest) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{5} + return file_ai_proto_rawDescGZIP(), []int{9} } func (x *CreateSessionRequest) GetUserId() string { @@ -638,7 +1052,7 @@ type CreateSessionResponse struct { func (x *CreateSessionResponse) Reset() { *x = CreateSessionResponse{} - mi := &file_ai_proto_msgTypes[6] + mi := &file_ai_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -650,7 +1064,7 @@ func (x *CreateSessionResponse) String() string { func (*CreateSessionResponse) ProtoMessage() {} func (x *CreateSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[6] + mi := &file_ai_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -663,7 +1077,7 @@ func (x *CreateSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSessionResponse.ProtoReflect.Descriptor instead. func (*CreateSessionResponse) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{6} + return file_ai_proto_rawDescGZIP(), []int{10} } func (x *CreateSessionResponse) GetSessionId() string { @@ -701,7 +1115,7 @@ type AskInSessionRequest struct { func (x *AskInSessionRequest) Reset() { *x = AskInSessionRequest{} - mi := &file_ai_proto_msgTypes[7] + mi := &file_ai_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -713,7 +1127,7 @@ func (x *AskInSessionRequest) String() string { func (*AskInSessionRequest) ProtoMessage() {} func (x *AskInSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[7] + mi := &file_ai_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -726,7 +1140,7 @@ func (x *AskInSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AskInSessionRequest.ProtoReflect.Descriptor instead. func (*AskInSessionRequest) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{7} + return file_ai_proto_rawDescGZIP(), []int{11} } func (x *AskInSessionRequest) GetSessionId() string { @@ -779,7 +1193,7 @@ type SessionStatusResponse struct { func (x *SessionStatusResponse) Reset() { *x = SessionStatusResponse{} - mi := &file_ai_proto_msgTypes[8] + mi := &file_ai_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -791,7 +1205,7 @@ func (x *SessionStatusResponse) String() string { func (*SessionStatusResponse) ProtoMessage() {} func (x *SessionStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[8] + mi := &file_ai_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -804,7 +1218,7 @@ func (x *SessionStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionStatusResponse.ProtoReflect.Descriptor instead. func (*SessionStatusResponse) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{8} + return file_ai_proto_rawDescGZIP(), []int{12} } func (x *SessionStatusResponse) GetSessionId() string { @@ -860,7 +1274,7 @@ type StatelessMessage struct { func (x *StatelessMessage) Reset() { *x = StatelessMessage{} - mi := &file_ai_proto_msgTypes[9] + mi := &file_ai_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -872,7 +1286,7 @@ func (x *StatelessMessage) String() string { func (*StatelessMessage) ProtoMessage() {} func (x *StatelessMessage) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[9] + mi := &file_ai_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -885,7 +1299,7 @@ func (x *StatelessMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use StatelessMessage.ProtoReflect.Descriptor instead. func (*StatelessMessage) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{9} + return file_ai_proto_rawDescGZIP(), []int{13} } func (x *StatelessMessage) GetRole() string { @@ -913,7 +1327,7 @@ type StatelessRequest struct { func (x *StatelessRequest) Reset() { *x = StatelessRequest{} - mi := &file_ai_proto_msgTypes[10] + mi := &file_ai_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -925,7 +1339,7 @@ func (x *StatelessRequest) String() string { func (*StatelessRequest) ProtoMessage() {} func (x *StatelessRequest) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[10] + mi := &file_ai_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -938,7 +1352,7 @@ func (x *StatelessRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StatelessRequest.ProtoReflect.Descriptor instead. func (*StatelessRequest) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{10} + return file_ai_proto_rawDescGZIP(), []int{14} } func (x *StatelessRequest) GetMessages() []*StatelessMessage { @@ -964,7 +1378,7 @@ type HealthCheckRequest struct { func (x *HealthCheckRequest) Reset() { *x = HealthCheckRequest{} - mi := &file_ai_proto_msgTypes[11] + mi := &file_ai_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -976,7 +1390,7 @@ func (x *HealthCheckRequest) String() string { func (*HealthCheckRequest) ProtoMessage() {} func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[11] + mi := &file_ai_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -989,7 +1403,7 @@ func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthCheckRequest.ProtoReflect.Descriptor instead. func (*HealthCheckRequest) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{11} + return file_ai_proto_rawDescGZIP(), []int{15} } // HealthCheckResponse для ответа на проверку здоровья @@ -1003,7 +1417,7 @@ type HealthCheckResponse struct { func (x *HealthCheckResponse) Reset() { *x = HealthCheckResponse{} - mi := &file_ai_proto_msgTypes[12] + mi := &file_ai_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1015,7 +1429,7 @@ func (x *HealthCheckResponse) String() string { func (*HealthCheckResponse) ProtoMessage() {} func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[12] + mi := &file_ai_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1028,7 +1442,7 @@ func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthCheckResponse.ProtoReflect.Descriptor instead. func (*HealthCheckResponse) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{12} + return file_ai_proto_rawDescGZIP(), []int{16} } func (x *HealthCheckResponse) GetServing() bool { @@ -1060,7 +1474,7 @@ type AgentToolLoopOptions struct { func (x *AgentToolLoopOptions) Reset() { *x = AgentToolLoopOptions{} - mi := &file_ai_proto_msgTypes[13] + mi := &file_ai_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1072,7 +1486,7 @@ func (x *AgentToolLoopOptions) String() string { func (*AgentToolLoopOptions) ProtoMessage() {} func (x *AgentToolLoopOptions) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[13] + mi := &file_ai_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1085,7 +1499,7 @@ func (x *AgentToolLoopOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentToolLoopOptions.ProtoReflect.Descriptor instead. func (*AgentToolLoopOptions) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{13} + return file_ai_proto_rawDescGZIP(), []int{17} } func (x *AgentToolLoopOptions) GetToolsEnabled() bool { @@ -1135,7 +1549,7 @@ type AgentResponseContract struct { func (x *AgentResponseContract) Reset() { *x = AgentResponseContract{} - mi := &file_ai_proto_msgTypes[14] + mi := &file_ai_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1147,7 +1561,7 @@ func (x *AgentResponseContract) String() string { func (*AgentResponseContract) ProtoMessage() {} func (x *AgentResponseContract) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[14] + mi := &file_ai_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1160,7 +1574,7 @@ func (x *AgentResponseContract) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentResponseContract.ProtoReflect.Descriptor instead. func (*AgentResponseContract) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{14} + return file_ai_proto_rawDescGZIP(), []int{18} } func (x *AgentResponseContract) GetFormat() AgentOutputFormat { @@ -1205,7 +1619,7 @@ type AgentRequest struct { func (x *AgentRequest) Reset() { *x = AgentRequest{} - mi := &file_ai_proto_msgTypes[15] + mi := &file_ai_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1217,7 +1631,7 @@ func (x *AgentRequest) String() string { func (*AgentRequest) ProtoMessage() {} func (x *AgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[15] + mi := &file_ai_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1230,7 +1644,7 @@ func (x *AgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentRequest.ProtoReflect.Descriptor instead. func (*AgentRequest) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{15} + return file_ai_proto_rawDescGZIP(), []int{19} } func (x *AgentRequest) GetMessages() []*StatelessMessage { @@ -1331,7 +1745,7 @@ type AgentUsage struct { func (x *AgentUsage) Reset() { *x = AgentUsage{} - mi := &file_ai_proto_msgTypes[16] + mi := &file_ai_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1343,7 +1757,7 @@ func (x *AgentUsage) String() string { func (*AgentUsage) ProtoMessage() {} func (x *AgentUsage) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[16] + mi := &file_ai_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1356,7 +1770,7 @@ func (x *AgentUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentUsage.ProtoReflect.Descriptor instead. func (*AgentUsage) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{16} + return file_ai_proto_rawDescGZIP(), []int{20} } func (x *AgentUsage) GetToolIterations() uint32 { @@ -1409,7 +1823,7 @@ type AgentResponse struct { func (x *AgentResponse) Reset() { *x = AgentResponse{} - mi := &file_ai_proto_msgTypes[17] + mi := &file_ai_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1421,7 +1835,7 @@ func (x *AgentResponse) String() string { func (*AgentResponse) ProtoMessage() {} func (x *AgentResponse) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[17] + mi := &file_ai_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1434,7 +1848,7 @@ func (x *AgentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentResponse.ProtoReflect.Descriptor instead. func (*AgentResponse) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{17} + return file_ai_proto_rawDescGZIP(), []int{21} } func (x *AgentResponse) GetStatus() AnswerStatus { @@ -1490,7 +1904,7 @@ type CancelAnswerJobRequest struct { func (x *CancelAnswerJobRequest) Reset() { *x = CancelAnswerJobRequest{} - mi := &file_ai_proto_msgTypes[18] + mi := &file_ai_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1502,7 +1916,7 @@ func (x *CancelAnswerJobRequest) String() string { func (*CancelAnswerJobRequest) ProtoMessage() {} func (x *CancelAnswerJobRequest) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[18] + mi := &file_ai_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1515,7 +1929,7 @@ func (x *CancelAnswerJobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelAnswerJobRequest.ProtoReflect.Descriptor instead. func (*CancelAnswerJobRequest) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{18} + return file_ai_proto_rawDescGZIP(), []int{22} } func (x *CancelAnswerJobRequest) GetJobId() string { @@ -1544,7 +1958,7 @@ type CancelAnswerJobResponse struct { func (x *CancelAnswerJobResponse) Reset() { *x = CancelAnswerJobResponse{} - mi := &file_ai_proto_msgTypes[19] + mi := &file_ai_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1556,7 +1970,7 @@ func (x *CancelAnswerJobResponse) String() string { func (*CancelAnswerJobResponse) ProtoMessage() {} func (x *CancelAnswerJobResponse) ProtoReflect() protoreflect.Message { - mi := &file_ai_proto_msgTypes[19] + mi := &file_ai_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1569,7 +1983,7 @@ func (x *CancelAnswerJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelAnswerJobResponse.ProtoReflect.Descriptor instead. func (*CancelAnswerJobResponse) Descriptor() ([]byte, []int) { - return file_ai_proto_rawDescGZIP(), []int{19} + return file_ai_proto_rawDescGZIP(), []int{23} } func (x *CancelAnswerJobResponse) GetState() AnswerJobState { @@ -1597,7 +2011,7 @@ var File_ai_proto protoreflect.FileDescriptor const file_ai_proto_rawDesc = "" + "\n" + - "\bai.proto\x12\x02ai\"\xe4\x02\n" + + "\bai.proto\x12\x02ai\"\x99\x03\n" + "\tAIRequest\x12\x12\n" + "\x04text\x18\x01 \x01(\tR\x04text\x12!\n" + "\fbot_username\x18\x02 \x01(\tR\vbotUsername\x12\x1d\n" + @@ -1608,9 +2022,21 @@ const file_ai_proto_rawDesc = "" + "\aoptions\x18\x06 \x01(\v2\x1b.ai.AnswerGenerationOptionsR\aoptions\x12(\n" + "\x10telegram_user_id\x18\a \x01(\x03R\x0etelegramUserId\x12\"\n" + "\rsteam_user_id\x18\b \x01(\x03R\vsteamUserId\x12+\n" + - "\x11supports_deferred\x18\t \x01(\bR\x10supportsDeferred\"M\n" + + "\x11supports_deferred\x18\t \x01(\bR\x10supportsDeferred\x123\n" + + "\rused_memories\x18\n" + + " \x03(\v2\x0e.ai.UsedMemoryR\fusedMemories\"\xd4\x01\n" + + "\n" + + "UsedMemory\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x17\n" + + "\auser_id\x18\x02 \x01(\x03R\x06userId\x12\x1a\n" + + "\busername\x18\x03 \x01(\tR\busername\x12\x10\n" + + "\x03key\x18\x04 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x05 \x01(\tR\x05value\x12\x1a\n" + + "\bcategory\x18\x06 \x01(\tR\bcategory\x12\x1a\n" + + "\bpriority\x18\a \x01(\tR\bpriority\x12!\n" + + "\fsource_label\x18\b \x01(\tR\vsourceLabel\"M\n" + "\x17AnswerGenerationOptions\x122\n" + - "\x15include_user_memories\x18\x01 \x01(\bR\x13includeUserMemories\"\xcb\x01\n" + + "\x15include_user_memories\x18\x01 \x01(\bR\x13includeUserMemories\"\xec\x01\n" + "\n" + "AIResponse\x12\x18\n" + "\acontent\x18\x01 \x01(\tR\acontent\x12\x14\n" + @@ -1619,9 +2045,11 @@ const file_ai_proto_rawDesc = "" + "durationMs\x12+\n" + "\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n" + "\x06status\x18\x05 \x01(\x0e2\x10.ai.AnswerStatusR\x06status\x12\x15\n" + - "\x06job_id\x18\x06 \x01(\tR\x05jobId\",\n" + + "\x06job_id\x18\x06 \x01(\tR\x05jobId\x12\x1f\n" + + "\vresponse_id\x18\a \x01(\tR\n" + + "responseId\",\n" + "\x13GetAnswerJobRequest\x12\x15\n" + - "\x06job_id\x18\x01 \x01(\tR\x05jobId\"\xbf\x01\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\"\xe0\x01\n" + "\x11AnswerJobResponse\x12(\n" + "\x05state\x18\x01 \x01(\x0e2\x12.ai.AnswerJobStateR\x05state\x12\x18\n" + "\acontent\x18\x02 \x01(\tR\acontent\x12\x14\n" + @@ -1629,7 +2057,39 @@ const file_ai_proto_rawDesc = "" + "\vduration_ms\x18\x04 \x01(\x01R\n" + "durationMs\x12/\n" + "\vagent_usage\x18\x05 \x01(\v2\x0e.ai.AgentUsageR\n" + - "agentUsage\"\x92\x01\n" + + "agentUsage\x12\x1f\n" + + "\vresponse_id\x18\x06 \x01(\tR\n" + + "responseId\"\xad\x01\n" + + "\rToolCallTrace\x12\x17\n" + + "\acall_id\x18\x01 \x01(\tR\x06callId\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12%\n" + + "\x0earguments_json\x18\x03 \x01(\tR\rargumentsJson\x12\x16\n" + + "\x06result\x18\x04 \x01(\tR\x06result\x12\x14\n" + + "\x05error\x18\x05 \x01(\tR\x05error\x12\x1a\n" + + "\bdeferred\x18\x06 \x01(\bR\bdeferred\"+\n" + + "\x19GetAIResponseTraceRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\xa0\x04\n" + + "\x1aGetAIResponseTraceResponse\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12!\n" + + "\fbot_username\x18\x02 \x01(\tR\vbotUsername\x12\x1d\n" + + "\n" + + "model_name\x18\x03 \x01(\tR\tmodelName\x12(\n" + + "\x10telegram_user_id\x18\x04 \x01(\x03R\x0etelegramUserId\x12$\n" + + "\x0eglobal_user_id\x18\x05 \x01(\x03R\fglobalUserId\x12#\n" + + "\rsystem_prompt\x18\x06 \x01(\tR\fsystemPrompt\x12\x1f\n" + + "\vuser_prompt\x18\a \x01(\tR\n" + + "userPrompt\x12*\n" + + "\bmemories\x18\b \x03(\v2\x0e.ai.UsedMemoryR\bmemories\x120\n" + + "\n" + + "tool_calls\x18\t \x03(\v2\x11.ai.ToolCallTraceR\ttoolCalls\x12\x1a\n" + + "\bresponse\x18\n" + + " \x01(\tR\bresponse\x12+\n" + + "\x11reasoning_content\x18\v \x01(\tR\x10reasoningContent\x12\x14\n" + + "\x05error\x18\f \x01(\tR\x05error\x12\x1f\n" + + "\vduration_ms\x18\r \x01(\x01R\n" + + "durationMs\x12&\n" + + "\x0fcreated_at_unix\x18\x0e \x01(\x03R\rcreatedAtUnix\x12\x14\n" + + "\x05found\x18\x0f \x01(\bR\x05found\"\x92\x01\n" + "\x14CreateSessionRequest\x12\x17\n" + "\auser_id\x18\x01 \x01(\tR\x06userId\x12!\n" + "\fbot_username\x18\x02 \x01(\tR\vbotUsername\x12\x1d\n" + @@ -1739,7 +2199,7 @@ const file_ai_proto_rawDesc = "" + "\x1fAGENT_OUTPUT_FORMAT_UNSPECIFIED\x10\x00\x12\x1c\n" + "\x18AGENT_OUTPUT_FORMAT_TEXT\x10\x01\x12\x1c\n" + "\x18AGENT_OUTPUT_FORMAT_JSON\x10\x02\x12#\n" + - "\x1fAGENT_OUTPUT_FORMAT_JSON_SCHEMA\x10\x032\xfe\x03\n" + + "\x1fAGENT_OUTPUT_FORMAT_JSON_SCHEMA\x10\x032\xd3\x04\n" + "\tAIService\x12/\n" + "\bRunAgent\x12\x10.ai.AgentRequest\x1a\x11.ai.AgentResponse\x12J\n" + "\x0fCancelAnswerJob\x12\x1a.ai.CancelAnswerJobRequest\x1a\x1b.ai.CancelAnswerJobResponse\x12/\n" + @@ -1748,7 +2208,8 @@ const file_ai_proto_rawDesc = "" + "\vHealthCheck\x12\x16.ai.HealthCheckRequest\x1a\x17.ai.HealthCheckResponse\x12D\n" + "\rCreateSession\x12\x18.ai.CreateSessionRequest\x1a\x19.ai.CreateSessionResponse\x12B\n" + "\fAskInSession\x12\x17.ai.AskInSessionRequest\x1a\x19.ai.SessionStatusResponse\x12>\n" + - "\fGetAnswerJob\x12\x17.ai.GetAnswerJobRequest\x1a\x15.ai.AnswerJobResponseB,Z*git.be.kaien.ru/l-ai/l-ai-core-proto/protob\x06proto3" + "\fGetAnswerJob\x12\x17.ai.GetAnswerJobRequest\x1a\x15.ai.AnswerJobResponse\x12S\n" + + "\x12GetAIResponseTrace\x12\x1d.ai.GetAIResponseTraceRequest\x1a\x1e.ai.GetAIResponseTraceResponseB,Z*git.be.kaien.ru/l-ai/l-ai-core-proto/protob\x06proto3" var ( file_ai_proto_rawDescOnce sync.Once @@ -1763,69 +2224,78 @@ func file_ai_proto_rawDescGZIP() []byte { } var file_ai_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_ai_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_ai_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_ai_proto_goTypes = []any{ - (AnswerStatus)(0), // 0: ai.AnswerStatus - (AnswerJobState)(0), // 1: ai.AnswerJobState - (AgentOutputFormat)(0), // 2: ai.AgentOutputFormat - (*AIRequest)(nil), // 3: ai.AIRequest - (*AnswerGenerationOptions)(nil), // 4: ai.AnswerGenerationOptions - (*AIResponse)(nil), // 5: ai.AIResponse - (*GetAnswerJobRequest)(nil), // 6: ai.GetAnswerJobRequest - (*AnswerJobResponse)(nil), // 7: ai.AnswerJobResponse - (*CreateSessionRequest)(nil), // 8: ai.CreateSessionRequest - (*CreateSessionResponse)(nil), // 9: ai.CreateSessionResponse - (*AskInSessionRequest)(nil), // 10: ai.AskInSessionRequest - (*SessionStatusResponse)(nil), // 11: ai.SessionStatusResponse - (*StatelessMessage)(nil), // 12: ai.StatelessMessage - (*StatelessRequest)(nil), // 13: ai.StatelessRequest - (*HealthCheckRequest)(nil), // 14: ai.HealthCheckRequest - (*HealthCheckResponse)(nil), // 15: ai.HealthCheckResponse - (*AgentToolLoopOptions)(nil), // 16: ai.AgentToolLoopOptions - (*AgentResponseContract)(nil), // 17: ai.AgentResponseContract - (*AgentRequest)(nil), // 18: ai.AgentRequest - (*AgentUsage)(nil), // 19: ai.AgentUsage - (*AgentResponse)(nil), // 20: ai.AgentResponse - (*CancelAnswerJobRequest)(nil), // 21: ai.CancelAnswerJobRequest - (*CancelAnswerJobResponse)(nil), // 22: ai.CancelAnswerJobResponse - nil, // 23: ai.AgentRequest.MetadataEntry + (AnswerStatus)(0), // 0: ai.AnswerStatus + (AnswerJobState)(0), // 1: ai.AnswerJobState + (AgentOutputFormat)(0), // 2: ai.AgentOutputFormat + (*AIRequest)(nil), // 3: ai.AIRequest + (*UsedMemory)(nil), // 4: ai.UsedMemory + (*AnswerGenerationOptions)(nil), // 5: ai.AnswerGenerationOptions + (*AIResponse)(nil), // 6: ai.AIResponse + (*GetAnswerJobRequest)(nil), // 7: ai.GetAnswerJobRequest + (*AnswerJobResponse)(nil), // 8: ai.AnswerJobResponse + (*ToolCallTrace)(nil), // 9: ai.ToolCallTrace + (*GetAIResponseTraceRequest)(nil), // 10: ai.GetAIResponseTraceRequest + (*GetAIResponseTraceResponse)(nil), // 11: ai.GetAIResponseTraceResponse + (*CreateSessionRequest)(nil), // 12: ai.CreateSessionRequest + (*CreateSessionResponse)(nil), // 13: ai.CreateSessionResponse + (*AskInSessionRequest)(nil), // 14: ai.AskInSessionRequest + (*SessionStatusResponse)(nil), // 15: ai.SessionStatusResponse + (*StatelessMessage)(nil), // 16: ai.StatelessMessage + (*StatelessRequest)(nil), // 17: ai.StatelessRequest + (*HealthCheckRequest)(nil), // 18: ai.HealthCheckRequest + (*HealthCheckResponse)(nil), // 19: ai.HealthCheckResponse + (*AgentToolLoopOptions)(nil), // 20: ai.AgentToolLoopOptions + (*AgentResponseContract)(nil), // 21: ai.AgentResponseContract + (*AgentRequest)(nil), // 22: ai.AgentRequest + (*AgentUsage)(nil), // 23: ai.AgentUsage + (*AgentResponse)(nil), // 24: ai.AgentResponse + (*CancelAnswerJobRequest)(nil), // 25: ai.CancelAnswerJobRequest + (*CancelAnswerJobResponse)(nil), // 26: ai.CancelAnswerJobResponse + nil, // 27: ai.AgentRequest.MetadataEntry } var file_ai_proto_depIdxs = []int32{ - 4, // 0: ai.AIRequest.options:type_name -> ai.AnswerGenerationOptions - 0, // 1: ai.AIResponse.status:type_name -> ai.AnswerStatus - 1, // 2: ai.AnswerJobResponse.state:type_name -> ai.AnswerJobState - 19, // 3: ai.AnswerJobResponse.agent_usage:type_name -> ai.AgentUsage - 4, // 4: ai.AskInSessionRequest.options:type_name -> ai.AnswerGenerationOptions - 12, // 5: ai.StatelessRequest.messages:type_name -> ai.StatelessMessage - 2, // 6: ai.AgentResponseContract.format:type_name -> ai.AgentOutputFormat - 12, // 7: ai.AgentRequest.messages:type_name -> ai.StatelessMessage - 16, // 8: ai.AgentRequest.tool_loop:type_name -> ai.AgentToolLoopOptions - 17, // 9: ai.AgentRequest.response_contract:type_name -> ai.AgentResponseContract - 23, // 10: ai.AgentRequest.metadata:type_name -> ai.AgentRequest.MetadataEntry - 0, // 11: ai.AgentResponse.status:type_name -> ai.AnswerStatus - 19, // 12: ai.AgentResponse.usage:type_name -> ai.AgentUsage - 1, // 13: ai.CancelAnswerJobResponse.state:type_name -> ai.AnswerJobState - 18, // 14: ai.AIService.RunAgent:input_type -> ai.AgentRequest - 21, // 15: ai.AIService.CancelAnswerJob:input_type -> ai.CancelAnswerJobRequest - 3, // 16: ai.AIService.GenerateAnswer:input_type -> ai.AIRequest - 13, // 17: ai.AIService.GenerateStateless:input_type -> ai.StatelessRequest - 14, // 18: ai.AIService.HealthCheck:input_type -> ai.HealthCheckRequest - 8, // 19: ai.AIService.CreateSession:input_type -> ai.CreateSessionRequest - 10, // 20: ai.AIService.AskInSession:input_type -> ai.AskInSessionRequest - 6, // 21: ai.AIService.GetAnswerJob:input_type -> ai.GetAnswerJobRequest - 20, // 22: ai.AIService.RunAgent:output_type -> ai.AgentResponse - 22, // 23: ai.AIService.CancelAnswerJob:output_type -> ai.CancelAnswerJobResponse - 5, // 24: ai.AIService.GenerateAnswer:output_type -> ai.AIResponse - 5, // 25: ai.AIService.GenerateStateless:output_type -> ai.AIResponse - 15, // 26: ai.AIService.HealthCheck:output_type -> ai.HealthCheckResponse - 9, // 27: ai.AIService.CreateSession:output_type -> ai.CreateSessionResponse - 11, // 28: ai.AIService.AskInSession:output_type -> ai.SessionStatusResponse - 7, // 29: ai.AIService.GetAnswerJob:output_type -> ai.AnswerJobResponse - 22, // [22:30] is the sub-list for method output_type - 14, // [14:22] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 5, // 0: ai.AIRequest.options:type_name -> ai.AnswerGenerationOptions + 4, // 1: ai.AIRequest.used_memories:type_name -> ai.UsedMemory + 0, // 2: ai.AIResponse.status:type_name -> ai.AnswerStatus + 1, // 3: ai.AnswerJobResponse.state:type_name -> ai.AnswerJobState + 23, // 4: ai.AnswerJobResponse.agent_usage:type_name -> ai.AgentUsage + 4, // 5: ai.GetAIResponseTraceResponse.memories:type_name -> ai.UsedMemory + 9, // 6: ai.GetAIResponseTraceResponse.tool_calls:type_name -> ai.ToolCallTrace + 5, // 7: ai.AskInSessionRequest.options:type_name -> ai.AnswerGenerationOptions + 16, // 8: ai.StatelessRequest.messages:type_name -> ai.StatelessMessage + 2, // 9: ai.AgentResponseContract.format:type_name -> ai.AgentOutputFormat + 16, // 10: ai.AgentRequest.messages:type_name -> ai.StatelessMessage + 20, // 11: ai.AgentRequest.tool_loop:type_name -> ai.AgentToolLoopOptions + 21, // 12: ai.AgentRequest.response_contract:type_name -> ai.AgentResponseContract + 27, // 13: ai.AgentRequest.metadata:type_name -> ai.AgentRequest.MetadataEntry + 0, // 14: ai.AgentResponse.status:type_name -> ai.AnswerStatus + 23, // 15: ai.AgentResponse.usage:type_name -> ai.AgentUsage + 1, // 16: ai.CancelAnswerJobResponse.state:type_name -> ai.AnswerJobState + 22, // 17: ai.AIService.RunAgent:input_type -> ai.AgentRequest + 25, // 18: ai.AIService.CancelAnswerJob:input_type -> ai.CancelAnswerJobRequest + 3, // 19: ai.AIService.GenerateAnswer:input_type -> ai.AIRequest + 17, // 20: ai.AIService.GenerateStateless:input_type -> ai.StatelessRequest + 18, // 21: ai.AIService.HealthCheck:input_type -> ai.HealthCheckRequest + 12, // 22: ai.AIService.CreateSession:input_type -> ai.CreateSessionRequest + 14, // 23: ai.AIService.AskInSession:input_type -> ai.AskInSessionRequest + 7, // 24: ai.AIService.GetAnswerJob:input_type -> ai.GetAnswerJobRequest + 10, // 25: ai.AIService.GetAIResponseTrace:input_type -> ai.GetAIResponseTraceRequest + 24, // 26: ai.AIService.RunAgent:output_type -> ai.AgentResponse + 26, // 27: ai.AIService.CancelAnswerJob:output_type -> ai.CancelAnswerJobResponse + 6, // 28: ai.AIService.GenerateAnswer:output_type -> ai.AIResponse + 6, // 29: ai.AIService.GenerateStateless:output_type -> ai.AIResponse + 19, // 30: ai.AIService.HealthCheck:output_type -> ai.HealthCheckResponse + 13, // 31: ai.AIService.CreateSession:output_type -> ai.CreateSessionResponse + 15, // 32: ai.AIService.AskInSession:output_type -> ai.SessionStatusResponse + 8, // 33: ai.AIService.GetAnswerJob:output_type -> ai.AnswerJobResponse + 11, // 34: ai.AIService.GetAIResponseTrace:output_type -> ai.GetAIResponseTraceResponse + 26, // [26:35] is the sub-list for method output_type + 17, // [17:26] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name } func init() { file_ai_proto_init() } @@ -1839,7 +2309,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: 3, - NumMessages: 21, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/ai.proto b/ai.proto index 2ca7bbe..68ab78d 100644 --- a/ai.proto +++ b/ai.proto @@ -15,6 +15,21 @@ message AIRequest { int64 telegram_user_id = 7; // Telegram user ID для применения пользовательских настроек (стиль ответа) int64 steam_user_id = 8; // SteamID64 отправителя для живых Steam-диалогов (l-ai-steam) - тот же "сигнал живого чата", что telegram_user_id, для второй платформы bool supports_deferred = 9; // Клиент умеет обрабатывать status=PENDING + GetAnswerJob (async тяжёлые тулзы). Старые клиенты не ставят — тяжёлые тулзы исполняются синхронно, как раньше. + // Структурированные воспоминания, которые клиент уже вложил в text (для debug-trace). + // Core сохраняет их as-is на ai_response_traces — не перезапрашивает memories-сервис. + repeated UsedMemory used_memories = 10; +} + +// UsedMemory — снимок одного воспоминания, участвовавшего в генерации ответа. +message UsedMemory { + int64 id = 1; // ID в l-ai-memories (для будущего delete с debug-страницы) + int64 user_id = 2; + string username = 3; + string key = 4; + string value = 5; + string category = 6; + string priority = 7; + string source_label = 8; // контекст от клиента, напр. "автор сообщения (@nick)" } // AnswerGenerationOptions содержит дополнительные опции для генерации ответа @@ -31,6 +46,7 @@ message AIResponse { AnswerStatus status = 5; // COMPLETE (или UNSPECIFIED для старых клиентов) — content финальный; // PENDING — запущена долгая job, content это interim, финал тянуть через GetAnswerJob(job_id) string job_id = 6; // Идентификатор отложенной job (только при status=PENDING) + string response_id = 7; // UUID (hex) debug-trace; доступен уже при PENDING } // AnswerStatus описывает, готов ли ответ синхронно или отложен в job. @@ -70,6 +86,41 @@ message AnswerJobResponse { // возвращает synchronous RunAgent (реальные iterations/tool calls core, не // self-reported из ответа модели). Для legacy GenerateAnswer jobs не заполняется. AgentUsage agent_usage = 5; + string response_id = 6; // тот же debug-trace id, что в AIResponse при PENDING +} + +// ToolCallTrace — один вызов тула во время GenerateAnswer (args + результат для модели). +message ToolCallTrace { + string call_id = 1; + string name = 2; + string arguments_json = 3; + string result = 4; + string error = 5; + bool deferred = 6; // тяжёлый тул через l-evolver +} + +// GetAIResponseTraceRequest — запрос debug-снимка генерации по UUID. +message GetAIResponseTraceRequest { + string id = 1; // response_id (hex UUID без дефисов) +} + +// GetAIResponseTraceResponse — снимок того, что ушло в модель / вернулось. +message GetAIResponseTraceResponse { + string id = 1; + string bot_username = 2; + string model_name = 3; + int64 telegram_user_id = 4; + int64 global_user_id = 5; + string system_prompt = 6; + string user_prompt = 7; + repeated UsedMemory memories = 8; + repeated ToolCallTrace tool_calls = 9; + string response = 10; + string reasoning_content = 11; + string error = 12; + double duration_ms = 13; + int64 created_at_unix = 14; + bool found = 15; // false — нет такого id / истёк TTL } // CreateSessionRequest для создания новой AI сессии @@ -240,4 +291,7 @@ service AIService { // GetAnswerJob возвращает статус отложенной генерации ответа (когда GenerateAnswer // вернул status=PENDING). Клиент поллит его до DONE/FAILED и постит финал. rpc GetAnswerJob(GetAnswerJobRequest) returns (AnswerJobResponse); + + // GetAIResponseTrace возвращает debug-снимок генерации (промпты, memories, tool calls). + rpc GetAIResponseTrace(GetAIResponseTraceRequest) returns (GetAIResponseTraceResponse); } diff --git a/ai_grpc.pb.go b/ai_grpc.pb.go index f139501..de32e15 100644 --- a/ai_grpc.pb.go +++ b/ai_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.6.1 -// - protoc v7.34.0 +// - protoc-gen-go-grpc v1.6.2 +// - protoc v7.36.0 // source: ai.proto package proto @@ -19,14 +19,15 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - AIService_RunAgent_FullMethodName = "/ai.AIService/RunAgent" - AIService_CancelAnswerJob_FullMethodName = "/ai.AIService/CancelAnswerJob" - AIService_GenerateAnswer_FullMethodName = "/ai.AIService/GenerateAnswer" - AIService_GenerateStateless_FullMethodName = "/ai.AIService/GenerateStateless" - AIService_HealthCheck_FullMethodName = "/ai.AIService/HealthCheck" - AIService_CreateSession_FullMethodName = "/ai.AIService/CreateSession" - AIService_AskInSession_FullMethodName = "/ai.AIService/AskInSession" - AIService_GetAnswerJob_FullMethodName = "/ai.AIService/GetAnswerJob" + AIService_RunAgent_FullMethodName = "/ai.AIService/RunAgent" + AIService_CancelAnswerJob_FullMethodName = "/ai.AIService/CancelAnswerJob" + AIService_GenerateAnswer_FullMethodName = "/ai.AIService/GenerateAnswer" + AIService_GenerateStateless_FullMethodName = "/ai.AIService/GenerateStateless" + AIService_HealthCheck_FullMethodName = "/ai.AIService/HealthCheck" + AIService_CreateSession_FullMethodName = "/ai.AIService/CreateSession" + AIService_AskInSession_FullMethodName = "/ai.AIService/AskInSession" + AIService_GetAnswerJob_FullMethodName = "/ai.AIService/GetAnswerJob" + AIService_GetAIResponseTrace_FullMethodName = "/ai.AIService/GetAIResponseTrace" ) // AIServiceClient is the client API for AIService service. @@ -53,6 +54,8 @@ type AIServiceClient interface { // GetAnswerJob возвращает статус отложенной генерации ответа (когда GenerateAnswer // вернул status=PENDING). Клиент поллит его до DONE/FAILED и постит финал. GetAnswerJob(ctx context.Context, in *GetAnswerJobRequest, opts ...grpc.CallOption) (*AnswerJobResponse, error) + // GetAIResponseTrace возвращает debug-снимок генерации (промпты, memories, tool calls). + GetAIResponseTrace(ctx context.Context, in *GetAIResponseTraceRequest, opts ...grpc.CallOption) (*GetAIResponseTraceResponse, error) } type aIServiceClient struct { @@ -143,6 +146,16 @@ func (c *aIServiceClient) GetAnswerJob(ctx context.Context, in *GetAnswerJobRequ return out, nil } +func (c *aIServiceClient) GetAIResponseTrace(ctx context.Context, in *GetAIResponseTraceRequest, opts ...grpc.CallOption) (*GetAIResponseTraceResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetAIResponseTraceResponse) + err := c.cc.Invoke(ctx, AIService_GetAIResponseTrace_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // AIServiceServer is the server API for AIService service. // All implementations must embed UnimplementedAIServiceServer // for forward compatibility. @@ -167,6 +180,8 @@ type AIServiceServer interface { // GetAnswerJob возвращает статус отложенной генерации ответа (когда GenerateAnswer // вернул status=PENDING). Клиент поллит его до DONE/FAILED и постит финал. GetAnswerJob(context.Context, *GetAnswerJobRequest) (*AnswerJobResponse, error) + // GetAIResponseTrace возвращает debug-снимок генерации (промпты, memories, tool calls). + GetAIResponseTrace(context.Context, *GetAIResponseTraceRequest) (*GetAIResponseTraceResponse, error) mustEmbedUnimplementedAIServiceServer() } @@ -201,6 +216,9 @@ func (UnimplementedAIServiceServer) AskInSession(context.Context, *AskInSessionR func (UnimplementedAIServiceServer) GetAnswerJob(context.Context, *GetAnswerJobRequest) (*AnswerJobResponse, error) { return nil, status.Error(codes.Unimplemented, "method GetAnswerJob not implemented") } +func (UnimplementedAIServiceServer) GetAIResponseTrace(context.Context, *GetAIResponseTraceRequest) (*GetAIResponseTraceResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetAIResponseTrace not implemented") +} func (UnimplementedAIServiceServer) mustEmbedUnimplementedAIServiceServer() {} func (UnimplementedAIServiceServer) testEmbeddedByValue() {} @@ -366,6 +384,24 @@ func _AIService_GetAnswerJob_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _AIService_GetAIResponseTrace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAIResponseTraceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AIServiceServer).GetAIResponseTrace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AIService_GetAIResponseTrace_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AIServiceServer).GetAIResponseTrace(ctx, req.(*GetAIResponseTraceRequest)) + } + return interceptor(ctx, in, info, handler) +} + // AIService_ServiceDesc is the grpc.ServiceDesc for AIService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -405,6 +441,10 @@ var AIService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetAnswerJob", Handler: _AIService_GetAnswerJob_Handler, }, + { + MethodName: "GetAIResponseTrace", + Handler: _AIService_GetAIResponseTrace_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "ai.proto",