feat: add telegram_user_id to AIRequest and response style RPCs to UserSettingsService

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kaien 2026-07-07 17:09:40 +03:00
parent be5ac2dc40
commit 1a9fd4a067
5 changed files with 579 additions and 22 deletions

View File

@ -26,10 +26,11 @@ type AIRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` // Текст запроса
BotUsername string `protobuf:"bytes,2,opt,name=bot_username,json=botUsername,proto3" json:"bot_username,omitempty"` // Username бота для упоминаний
ModelName string `protobuf:"bytes,3,opt,name=model_name,json=modelName,proto3" json:"model_name,omitempty"` // Название модели (по умолчанию "venice-uncensored")
ModelName string `protobuf:"bytes,3,opt,name=model_name,json=modelName,proto3" json:"model_name,omitempty"` // Название модели (по умолчанию "deepseek-v4-flash")
EnableReasoning bool `protobuf:"varint,4,opt,name=enable_reasoning,json=enableReasoning,proto3" json:"enable_reasoning,omitempty"` // Включить режим рассуждений (по умолчанию false)
GlobalUserId int64 `protobuf:"varint,5,opt,name=global_user_id,json=globalUserId,proto3" json:"global_user_id,omitempty"` // Global user ID для получения доп. данных (профиль, воспоминания)
Options *AnswerGenerationOptions `protobuf:"bytes,6,opt,name=options,proto3" json:"options,omitempty"` // Дополнительные опции генерации ответа
TelegramUserId int64 `protobuf:"varint,7,opt,name=telegram_user_id,json=telegramUserId,proto3" json:"telegram_user_id,omitempty"` // Telegram user ID для применения пользовательских настроек (стиль ответа)
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -106,6 +107,13 @@ func (x *AIRequest) GetOptions() *AnswerGenerationOptions {
return nil
}
func (x *AIRequest) GetTelegramUserId() int64 {
if x != nil {
return x.TelegramUserId
}
return 0
}
// AnswerGenerationOptions содержит дополнительные опции для генерации ответа
type AnswerGenerationOptions struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -225,7 +233,7 @@ type CreateSessionRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Идентификатор пользователя
BotUsername string `protobuf:"bytes,2,opt,name=bot_username,json=botUsername,proto3" json:"bot_username,omitempty"` // Username бота для упоминаний
ModelName string `protobuf:"bytes,3,opt,name=model_name,json=modelName,proto3" json:"model_name,omitempty"` // Название модели (по умолчанию "venice-uncensored")
ModelName string `protobuf:"bytes,3,opt,name=model_name,json=modelName,proto3" json:"model_name,omitempty"` // Название модели (по умолчанию "deepseek-v4-flash")
TtlSeconds int64 `protobuf:"varint,4,opt,name=ttl_seconds,json=ttlSeconds,proto3" json:"ttl_seconds,omitempty"` // Время жизни сессии в секундах (по умолчанию 3600 = 1 час)
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
@ -569,7 +577,7 @@ func (x *StatelessMessage) GetContent() string {
type StatelessRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Messages []*StatelessMessage `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` // Массив сообщений (system + history + user)
ModelName string `protobuf:"bytes,2,opt,name=model_name,json=modelName,proto3" json:"model_name,omitempty"` // Название модели (по умолчанию "venice-uncensored")
ModelName string `protobuf:"bytes,2,opt,name=model_name,json=modelName,proto3" json:"model_name,omitempty"` // Название модели (по умолчанию "deepseek-v4-flash")
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -712,7 +720,7 @@ var File_ai_proto protoreflect.FileDescriptor
const file_ai_proto_rawDesc = "" +
"\n" +
"\bai.proto\x12\x02ai\"\xe9\x01\n" +
"\bai.proto\x12\x02ai\"\x93\x02\n" +
"\tAIRequest\x12\x12\n" +
"\x04text\x18\x01 \x01(\tR\x04text\x12!\n" +
"\fbot_username\x18\x02 \x01(\tR\vbotUsername\x12\x1d\n" +
@ -720,7 +728,8 @@ const file_ai_proto_rawDesc = "" +
"model_name\x18\x03 \x01(\tR\tmodelName\x12)\n" +
"\x10enable_reasoning\x18\x04 \x01(\bR\x0fenableReasoning\x12$\n" +
"\x0eglobal_user_id\x18\x05 \x01(\x03R\fglobalUserId\x125\n" +
"\aoptions\x18\x06 \x01(\v2\x1b.ai.AnswerGenerationOptionsR\aoptions\"M\n" +
"\aoptions\x18\x06 \x01(\v2\x1b.ai.AnswerGenerationOptionsR\aoptions\x12(\n" +
"\x10telegram_user_id\x18\a \x01(\x03R\x0etelegramUserId\"M\n" +
"\x17AnswerGenerationOptions\x122\n" +
"\x15include_user_memories\x18\x01 \x01(\bR\x13includeUserMemories\"\x8a\x01\n" +
"\n" +

View File

@ -8,10 +8,11 @@ option go_package = "git.be.kaien.ru/l-ai/l-ai-core-proto/proto";
message AIRequest {
string text = 1; // Текст запроса
string bot_username = 2; // Username бота для упоминаний
string model_name = 3; // Название модели (по умолчанию "venice-uncensored")
string model_name = 3; // Название модели (по умолчанию "deepseek-v4-flash")
bool enable_reasoning = 4; // Включить режим рассуждений (по умолчанию false)
int64 global_user_id = 5; // Global user ID для получения доп. данных (профиль, воспоминания)
AnswerGenerationOptions options = 6; // Дополнительные опции генерации ответа
int64 telegram_user_id = 7; // Telegram user ID для применения пользовательских настроек (стиль ответа)
}
// AnswerGenerationOptions содержит дополнительные опции для генерации ответа
@ -31,7 +32,7 @@ message AIResponse {
message CreateSessionRequest {
string user_id = 1; // Идентификатор пользователя
string bot_username = 2; // Username бота для упоминаний
string model_name = 3; // Название модели (по умолчанию "venice-uncensored")
string model_name = 3; // Название модели (по умолчанию "deepseek-v4-flash")
int64 ttl_seconds = 4; // Время жизни сессии в секундах (по умолчанию 3600 = 1 час)
}
@ -70,7 +71,7 @@ message StatelessMessage {
// StatelessRequest для stateless генерации с полным контролем над messages
message StatelessRequest {
repeated StatelessMessage messages = 1; // Массив сообщений (system + history + user)
string model_name = 2; // Название модели (по умолчанию "venice-uncensored")
string model_name = 2; // Название модели (по умолчанию "deepseek-v4-flash")
}
// HealthCheckRequest для проверки здоровья сервиса

View File

@ -170,6 +170,359 @@ func (x *SetPreferredModelRequest) GetModel() string {
return ""
}
// StylePreset - пресет стиля ответа, хранится в БД
type StylePreset struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Отображаемое название (например "Токсик")
Prompt string `protobuf:"bytes,3,opt,name=prompt,proto3" json:"prompt,omitempty"` // Текст system prompt
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *StylePreset) Reset() {
*x = StylePreset{}
mi := &file_settings_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *StylePreset) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*StylePreset) ProtoMessage() {}
func (x *StylePreset) ProtoReflect() protoreflect.Message {
mi := &file_settings_proto_msgTypes[3]
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 StylePreset.ProtoReflect.Descriptor instead.
func (*StylePreset) Descriptor() ([]byte, []int) {
return file_settings_proto_rawDescGZIP(), []int{3}
}
func (x *StylePreset) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
func (x *StylePreset) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *StylePreset) GetPrompt() string {
if x != nil {
return x.Prompt
}
return ""
}
type ListStylePresetsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListStylePresetsRequest) Reset() {
*x = ListStylePresetsRequest{}
mi := &file_settings_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListStylePresetsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListStylePresetsRequest) ProtoMessage() {}
func (x *ListStylePresetsRequest) ProtoReflect() protoreflect.Message {
mi := &file_settings_proto_msgTypes[4]
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 ListStylePresetsRequest.ProtoReflect.Descriptor instead.
func (*ListStylePresetsRequest) Descriptor() ([]byte, []int) {
return file_settings_proto_rawDescGZIP(), []int{4}
}
type ListStylePresetsResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Presets []*StylePreset `protobuf:"bytes,1,rep,name=presets,proto3" json:"presets,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListStylePresetsResponse) Reset() {
*x = ListStylePresetsResponse{}
mi := &file_settings_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListStylePresetsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListStylePresetsResponse) ProtoMessage() {}
func (x *ListStylePresetsResponse) ProtoReflect() protoreflect.Message {
mi := &file_settings_proto_msgTypes[5]
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 ListStylePresetsResponse.ProtoReflect.Descriptor instead.
func (*ListStylePresetsResponse) Descriptor() ([]byte, []int) {
return file_settings_proto_rawDescGZIP(), []int{5}
}
func (x *ListStylePresetsResponse) GetPresets() []*StylePreset {
if x != nil {
return x.Presets
}
return nil
}
type GetUserStyleRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Telegram user ID
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetUserStyleRequest) Reset() {
*x = GetUserStyleRequest{}
mi := &file_settings_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetUserStyleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetUserStyleRequest) ProtoMessage() {}
func (x *GetUserStyleRequest) ProtoReflect() protoreflect.Message {
mi := &file_settings_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 GetUserStyleRequest.ProtoReflect.Descriptor instead.
func (*GetUserStyleRequest) Descriptor() ([]byte, []int) {
return file_settings_proto_rawDescGZIP(), []int{6}
}
func (x *GetUserStyleRequest) GetUserId() int64 {
if x != nil {
return x.UserId
}
return 0
}
type GetUserStyleResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
PresetId int64 `protobuf:"varint,1,opt,name=preset_id,json=presetId,proto3" json:"preset_id,omitempty"` // ID выбранного пресета (0 - не выбран)
CustomPrompt string `protobuf:"bytes,2,opt,name=custom_prompt,json=customPrompt,proto3" json:"custom_prompt,omitempty"` // Кастомный промпт (пустой - не задан)
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetUserStyleResponse) Reset() {
*x = GetUserStyleResponse{}
mi := &file_settings_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetUserStyleResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetUserStyleResponse) ProtoMessage() {}
func (x *GetUserStyleResponse) ProtoReflect() protoreflect.Message {
mi := &file_settings_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 GetUserStyleResponse.ProtoReflect.Descriptor instead.
func (*GetUserStyleResponse) Descriptor() ([]byte, []int) {
return file_settings_proto_rawDescGZIP(), []int{7}
}
func (x *GetUserStyleResponse) GetPresetId() int64 {
if x != nil {
return x.PresetId
}
return 0
}
func (x *GetUserStyleResponse) GetCustomPrompt() string {
if x != nil {
return x.CustomPrompt
}
return ""
}
type SetUserStyleRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Telegram user ID
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
// Выбор стиля: пресет, кастомный промпт или сброс на дефолт
//
// Types that are valid to be assigned to Style:
//
// *SetUserStyleRequest_PresetId
// *SetUserStyleRequest_CustomPrompt
// *SetUserStyleRequest_Reset_
Style isSetUserStyleRequest_Style `protobuf_oneof:"style"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SetUserStyleRequest) Reset() {
*x = SetUserStyleRequest{}
mi := &file_settings_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SetUserStyleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetUserStyleRequest) ProtoMessage() {}
func (x *SetUserStyleRequest) ProtoReflect() protoreflect.Message {
mi := &file_settings_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 SetUserStyleRequest.ProtoReflect.Descriptor instead.
func (*SetUserStyleRequest) Descriptor() ([]byte, []int) {
return file_settings_proto_rawDescGZIP(), []int{8}
}
func (x *SetUserStyleRequest) GetUserId() int64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *SetUserStyleRequest) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *SetUserStyleRequest) GetStyle() isSetUserStyleRequest_Style {
if x != nil {
return x.Style
}
return nil
}
func (x *SetUserStyleRequest) GetPresetId() int64 {
if x != nil {
if x, ok := x.Style.(*SetUserStyleRequest_PresetId); ok {
return x.PresetId
}
}
return 0
}
func (x *SetUserStyleRequest) GetCustomPrompt() string {
if x != nil {
if x, ok := x.Style.(*SetUserStyleRequest_CustomPrompt); ok {
return x.CustomPrompt
}
}
return ""
}
func (x *SetUserStyleRequest) GetReset_() bool {
if x != nil {
if x, ok := x.Style.(*SetUserStyleRequest_Reset_); ok {
return x.Reset_
}
}
return false
}
type isSetUserStyleRequest_Style interface {
isSetUserStyleRequest_Style()
}
type SetUserStyleRequest_PresetId struct {
PresetId int64 `protobuf:"varint,3,opt,name=preset_id,json=presetId,proto3,oneof"` // Выбрать пресет по ID
}
type SetUserStyleRequest_CustomPrompt struct {
CustomPrompt string `protobuf:"bytes,4,opt,name=custom_prompt,json=customPrompt,proto3,oneof"` // Задать свой промпт (макс 4000 символов)
}
type SetUserStyleRequest_Reset_ struct {
Reset_ bool `protobuf:"varint,5,opt,name=reset,proto3,oneof"` // Сбросить стиль на дефолтный
}
func (*SetUserStyleRequest_PresetId) isSetUserStyleRequest_Style() {}
func (*SetUserStyleRequest_CustomPrompt) isSetUserStyleRequest_Style() {}
func (*SetUserStyleRequest_Reset_) isSetUserStyleRequest_Style() {}
var File_settings_proto protoreflect.FileDescriptor
const file_settings_proto_rawDesc = "" +
@ -182,10 +535,32 @@ const file_settings_proto_rawDesc = "" +
"\x18SetPreferredModelRequest\x12\x17\n" +
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12\x14\n" +
"\x05model\x18\x03 \x01(\tR\x05model2\xbb\x01\n" +
"\x05model\x18\x03 \x01(\tR\x05model\"I\n" +
"\vStylePreset\x12\x0e\n" +
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" +
"\x04name\x18\x02 \x01(\tR\x04name\x12\x16\n" +
"\x06prompt\x18\x03 \x01(\tR\x06prompt\"\x19\n" +
"\x17ListStylePresetsRequest\"H\n" +
"\x18ListStylePresetsResponse\x12,\n" +
"\apresets\x18\x01 \x03(\v2\x12.users.StylePresetR\apresets\".\n" +
"\x13GetUserStyleRequest\x12\x17\n" +
"\auser_id\x18\x01 \x01(\x03R\x06userId\"X\n" +
"\x14GetUserStyleResponse\x12\x1b\n" +
"\tpreset_id\x18\x01 \x01(\x03R\bpresetId\x12#\n" +
"\rcustom_prompt\x18\x02 \x01(\tR\fcustomPrompt\"\xb1\x01\n" +
"\x13SetUserStyleRequest\x12\x17\n" +
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12\x1d\n" +
"\tpreset_id\x18\x03 \x01(\x03H\x00R\bpresetId\x12%\n" +
"\rcustom_prompt\x18\x04 \x01(\tH\x00R\fcustomPrompt\x12\x16\n" +
"\x05reset\x18\x05 \x01(\bH\x00R\x05resetB\a\n" +
"\x05style2\x9d\x03\n" +
"\x13UserSettingsService\x12V\n" +
"\x11GetPreferredModel\x12\x1f.users.GetPreferredModelRequest\x1a .users.GetPreferredModelResponse\x12L\n" +
"\x11SetPreferredModel\x12\x1f.users.SetPreferredModelRequest\x1a\x16.google.protobuf.EmptyB,Z*git.be.kaien.ru/l-ai/l-ai-core-proto/protob\x06proto3"
"\x11SetPreferredModel\x12\x1f.users.SetPreferredModelRequest\x1a\x16.google.protobuf.Empty\x12S\n" +
"\x10ListStylePresets\x12\x1e.users.ListStylePresetsRequest\x1a\x1f.users.ListStylePresetsResponse\x12G\n" +
"\fGetUserStyle\x12\x1a.users.GetUserStyleRequest\x1a\x1b.users.GetUserStyleResponse\x12B\n" +
"\fSetUserStyle\x12\x1a.users.SetUserStyleRequest\x1a\x16.google.protobuf.EmptyB,Z*git.be.kaien.ru/l-ai/l-ai-core-proto/protob\x06proto3"
var (
file_settings_proto_rawDescOnce sync.Once
@ -199,23 +574,36 @@ func file_settings_proto_rawDescGZIP() []byte {
return file_settings_proto_rawDescData
}
var file_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_settings_proto_goTypes = []any{
(*GetPreferredModelRequest)(nil), // 0: users.GetPreferredModelRequest
(*GetPreferredModelResponse)(nil), // 1: users.GetPreferredModelResponse
(*SetPreferredModelRequest)(nil), // 2: users.SetPreferredModelRequest
(*emptypb.Empty)(nil), // 3: google.protobuf.Empty
(*StylePreset)(nil), // 3: users.StylePreset
(*ListStylePresetsRequest)(nil), // 4: users.ListStylePresetsRequest
(*ListStylePresetsResponse)(nil), // 5: users.ListStylePresetsResponse
(*GetUserStyleRequest)(nil), // 6: users.GetUserStyleRequest
(*GetUserStyleResponse)(nil), // 7: users.GetUserStyleResponse
(*SetUserStyleRequest)(nil), // 8: users.SetUserStyleRequest
(*emptypb.Empty)(nil), // 9: google.protobuf.Empty
}
var file_settings_proto_depIdxs = []int32{
0, // 0: users.UserSettingsService.GetPreferredModel:input_type -> users.GetPreferredModelRequest
2, // 1: users.UserSettingsService.SetPreferredModel:input_type -> users.SetPreferredModelRequest
1, // 2: users.UserSettingsService.GetPreferredModel:output_type -> users.GetPreferredModelResponse
3, // 3: users.UserSettingsService.SetPreferredModel:output_type -> google.protobuf.Empty
2, // [2:4] is the sub-list for method output_type
0, // [0:2] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
3, // 0: users.ListStylePresetsResponse.presets:type_name -> users.StylePreset
0, // 1: users.UserSettingsService.GetPreferredModel:input_type -> users.GetPreferredModelRequest
2, // 2: users.UserSettingsService.SetPreferredModel:input_type -> users.SetPreferredModelRequest
4, // 3: users.UserSettingsService.ListStylePresets:input_type -> users.ListStylePresetsRequest
6, // 4: users.UserSettingsService.GetUserStyle:input_type -> users.GetUserStyleRequest
8, // 5: users.UserSettingsService.SetUserStyle:input_type -> users.SetUserStyleRequest
1, // 6: users.UserSettingsService.GetPreferredModel:output_type -> users.GetPreferredModelResponse
9, // 7: users.UserSettingsService.SetPreferredModel:output_type -> google.protobuf.Empty
5, // 8: users.UserSettingsService.ListStylePresets:output_type -> users.ListStylePresetsResponse
7, // 9: users.UserSettingsService.GetUserStyle:output_type -> users.GetUserStyleResponse
9, // 10: users.UserSettingsService.SetUserStyle:output_type -> google.protobuf.Empty
6, // [6:11] is the sub-list for method output_type
1, // [1:6] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_settings_proto_init() }
@ -223,13 +611,18 @@ func file_settings_proto_init() {
if File_settings_proto != nil {
return
}
file_settings_proto_msgTypes[8].OneofWrappers = []any{
(*SetUserStyleRequest_PresetId)(nil),
(*SetUserStyleRequest_CustomPrompt)(nil),
(*SetUserStyleRequest_Reset_)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_settings_proto_rawDesc), len(file_settings_proto_rawDesc)),
NumEnums: 0,
NumMessages: 3,
NumMessages: 9,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -10,6 +10,11 @@ import "google/protobuf/empty.proto";
service UserSettingsService {
rpc GetPreferredModel(GetPreferredModelRequest) returns (GetPreferredModelResponse);
rpc SetPreferredModel(SetPreferredModelRequest) returns (google.protobuf.Empty);
// Response style: пресеты из БД или кастомный промпт пользователя
rpc ListStylePresets(ListStylePresetsRequest) returns (ListStylePresetsResponse);
rpc GetUserStyle(GetUserStyleRequest) returns (GetUserStyleResponse);
rpc SetUserStyle(SetUserStyleRequest) returns (google.protobuf.Empty);
}
message GetPreferredModelRequest {
@ -25,3 +30,36 @@ message SetPreferredModelRequest {
string username = 2;
string model = 3;
}
// StylePreset - пресет стиля ответа, хранится в БД
message StylePreset {
int64 id = 1;
string name = 2; // Отображаемое название (например "Токсик")
string prompt = 3; // Текст system prompt
}
message ListStylePresetsRequest {}
message ListStylePresetsResponse {
repeated StylePreset presets = 1;
}
message GetUserStyleRequest {
int64 user_id = 1; // Telegram user ID
}
message GetUserStyleResponse {
int64 preset_id = 1; // ID выбранного пресета (0 - не выбран)
string custom_prompt = 2; // Кастомный промпт (пустой - не задан)
}
message SetUserStyleRequest {
int64 user_id = 1; // Telegram user ID
string username = 2;
// Выбор стиля: пресет, кастомный промпт или сброс на дефолт
oneof style {
int64 preset_id = 3; // Выбрать пресет по ID
string custom_prompt = 4; // Задать свой промпт (макс 4000 символов)
bool reset = 5; // Сбросить стиль на дефолтный
}
}

View File

@ -22,6 +22,9 @@ const _ = grpc.SupportPackageIsVersion9
const (
UserSettingsService_GetPreferredModel_FullMethodName = "/users.UserSettingsService/GetPreferredModel"
UserSettingsService_SetPreferredModel_FullMethodName = "/users.UserSettingsService/SetPreferredModel"
UserSettingsService_ListStylePresets_FullMethodName = "/users.UserSettingsService/ListStylePresets"
UserSettingsService_GetUserStyle_FullMethodName = "/users.UserSettingsService/GetUserStyle"
UserSettingsService_SetUserStyle_FullMethodName = "/users.UserSettingsService/SetUserStyle"
)
// UserSettingsServiceClient is the client API for UserSettingsService service.
@ -32,6 +35,10 @@ const (
type UserSettingsServiceClient interface {
GetPreferredModel(ctx context.Context, in *GetPreferredModelRequest, opts ...grpc.CallOption) (*GetPreferredModelResponse, error)
SetPreferredModel(ctx context.Context, in *SetPreferredModelRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Response style: пресеты из БД или кастомный промпт пользователя
ListStylePresets(ctx context.Context, in *ListStylePresetsRequest, opts ...grpc.CallOption) (*ListStylePresetsResponse, error)
GetUserStyle(ctx context.Context, in *GetUserStyleRequest, opts ...grpc.CallOption) (*GetUserStyleResponse, error)
SetUserStyle(ctx context.Context, in *SetUserStyleRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
}
type userSettingsServiceClient struct {
@ -62,6 +69,36 @@ func (c *userSettingsServiceClient) SetPreferredModel(ctx context.Context, in *S
return out, nil
}
func (c *userSettingsServiceClient) ListStylePresets(ctx context.Context, in *ListStylePresetsRequest, opts ...grpc.CallOption) (*ListStylePresetsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListStylePresetsResponse)
err := c.cc.Invoke(ctx, UserSettingsService_ListStylePresets_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userSettingsServiceClient) GetUserStyle(ctx context.Context, in *GetUserStyleRequest, opts ...grpc.CallOption) (*GetUserStyleResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetUserStyleResponse)
err := c.cc.Invoke(ctx, UserSettingsService_GetUserStyle_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userSettingsServiceClient) SetUserStyle(ctx context.Context, in *SetUserStyleRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, UserSettingsService_SetUserStyle_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// UserSettingsServiceServer is the server API for UserSettingsService service.
// All implementations must embed UnimplementedUserSettingsServiceServer
// for forward compatibility.
@ -70,6 +107,10 @@ func (c *userSettingsServiceClient) SetPreferredModel(ctx context.Context, in *S
type UserSettingsServiceServer interface {
GetPreferredModel(context.Context, *GetPreferredModelRequest) (*GetPreferredModelResponse, error)
SetPreferredModel(context.Context, *SetPreferredModelRequest) (*emptypb.Empty, error)
// Response style: пресеты из БД или кастомный промпт пользователя
ListStylePresets(context.Context, *ListStylePresetsRequest) (*ListStylePresetsResponse, error)
GetUserStyle(context.Context, *GetUserStyleRequest) (*GetUserStyleResponse, error)
SetUserStyle(context.Context, *SetUserStyleRequest) (*emptypb.Empty, error)
mustEmbedUnimplementedUserSettingsServiceServer()
}
@ -86,6 +127,15 @@ func (UnimplementedUserSettingsServiceServer) GetPreferredModel(context.Context,
func (UnimplementedUserSettingsServiceServer) SetPreferredModel(context.Context, *SetPreferredModelRequest) (*emptypb.Empty, error) {
return nil, status.Error(codes.Unimplemented, "method SetPreferredModel not implemented")
}
func (UnimplementedUserSettingsServiceServer) ListStylePresets(context.Context, *ListStylePresetsRequest) (*ListStylePresetsResponse, error) {
return nil, status.Error(codes.Unimplemented, "method ListStylePresets not implemented")
}
func (UnimplementedUserSettingsServiceServer) GetUserStyle(context.Context, *GetUserStyleRequest) (*GetUserStyleResponse, error) {
return nil, status.Error(codes.Unimplemented, "method GetUserStyle not implemented")
}
func (UnimplementedUserSettingsServiceServer) SetUserStyle(context.Context, *SetUserStyleRequest) (*emptypb.Empty, error) {
return nil, status.Error(codes.Unimplemented, "method SetUserStyle not implemented")
}
func (UnimplementedUserSettingsServiceServer) mustEmbedUnimplementedUserSettingsServiceServer() {}
func (UnimplementedUserSettingsServiceServer) testEmbeddedByValue() {}
@ -143,6 +193,60 @@ func _UserSettingsService_SetPreferredModel_Handler(srv interface{}, ctx context
return interceptor(ctx, in, info, handler)
}
func _UserSettingsService_ListStylePresets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListStylePresetsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserSettingsServiceServer).ListStylePresets(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserSettingsService_ListStylePresets_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserSettingsServiceServer).ListStylePresets(ctx, req.(*ListStylePresetsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _UserSettingsService_GetUserStyle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserStyleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserSettingsServiceServer).GetUserStyle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserSettingsService_GetUserStyle_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserSettingsServiceServer).GetUserStyle(ctx, req.(*GetUserStyleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _UserSettingsService_SetUserStyle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SetUserStyleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserSettingsServiceServer).SetUserStyle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserSettingsService_SetUserStyle_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserSettingsServiceServer).SetUserStyle(ctx, req.(*SetUserStyleRequest))
}
return interceptor(ctx, in, info, handler)
}
// UserSettingsService_ServiceDesc is the grpc.ServiceDesc for UserSettingsService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -158,6 +262,18 @@ var UserSettingsService_ServiceDesc = grpc.ServiceDesc{
MethodName: "SetPreferredModel",
Handler: _UserSettingsService_SetPreferredModel_Handler,
},
{
MethodName: "ListStylePresets",
Handler: _UserSettingsService_ListStylePresets_Handler,
},
{
MethodName: "GetUserStyle",
Handler: _UserSettingsService_GetUserStyle_Handler,
},
{
MethodName: "SetUserStyle",
Handler: _UserSettingsService_SetUserStyle_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "settings.proto",