feat(p5): messaging, push gateway and AI assistant services
P5 阶段交付物: - services/msg: 消息通知服务(NestJS) - notifications: 发送通知 + ES 全文检索 + search - config/elasticsearch.ts: ES Client 单例 - package.json: 补充 @opentelemetry/sdk-node + exporter-trace-otlp-http - services/push-gateway: WebSocket 推送网关(Go Gin) - internal/hub/hub.go: WebSocket 连接池管理(Register/Unregister/SendToUser) - internal/ws/handler.go: JWT 鉴权 + WebSocket 升级 + 内部推送 API - services/ai: AI 辅助服务(Python FastAPI) - /chat + /chat/stream(SSE 流式) - /generate/question + /optimize/expression - config.py: OpenAI 兼容 API 配置 - packages/shared-proto/proto/msg.proto: NotificationService 契约(send/search) - packages/shared-proto/proto/ai.proto: AiService 契约(含 stream 方法)
This commit is contained in:
60
packages/shared-proto/proto/ai.proto
Normal file
60
packages/shared-proto/proto/ai.proto
Normal file
@@ -0,0 +1,60 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package next_edu_cloud.ai.v1;
|
||||
|
||||
service AiService {
|
||||
rpc Chat(ChatRequest) returns (ChatResponse);
|
||||
rpc StreamChat(ChatRequest) returns (stream ChatChunk);
|
||||
rpc GenerateQuestion(GenerateQuestionRequest) returns (GeneratedQuestion);
|
||||
rpc OptimizeExpression(OptimizeExpressionRequest) returns (OptimizedExpression);
|
||||
}
|
||||
|
||||
message ChatRequest {
|
||||
repeated ChatMessage messages = 1;
|
||||
string model = 2;
|
||||
double temperature = 3;
|
||||
}
|
||||
|
||||
message ChatMessage {
|
||||
string role = 1;
|
||||
string content = 2;
|
||||
}
|
||||
|
||||
message ChatResponse {
|
||||
string content = 1;
|
||||
string model = 2;
|
||||
Usage usage = 3;
|
||||
}
|
||||
|
||||
message Usage {
|
||||
int32 prompt_tokens = 1;
|
||||
int32 completion_tokens = 2;
|
||||
int32 total_tokens = 3;
|
||||
}
|
||||
|
||||
message ChatChunk {
|
||||
string content = 1;
|
||||
bool done = 2;
|
||||
}
|
||||
|
||||
message GenerateQuestionRequest {
|
||||
string prompt = 1;
|
||||
string subject = 2;
|
||||
string difficulty = 3;
|
||||
}
|
||||
|
||||
message GeneratedQuestion {
|
||||
string question = 1;
|
||||
string answer = 2;
|
||||
string explanation = 3;
|
||||
}
|
||||
|
||||
message OptimizeExpressionRequest {
|
||||
string text = 1;
|
||||
string context = 2;
|
||||
}
|
||||
|
||||
message OptimizedExpression {
|
||||
string optimized = 1;
|
||||
repeated string suggestions = 2;
|
||||
}
|
||||
48
packages/shared-proto/proto/msg.proto
Normal file
48
packages/shared-proto/proto/msg.proto
Normal file
@@ -0,0 +1,48 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package next_edu_cloud.msg.v1;
|
||||
|
||||
service NotificationService {
|
||||
rpc SendNotification(SendNotificationRequest) returns (Notification);
|
||||
rpc ListNotifications(ListNotificationsRequest) returns (ListNotificationsResponse);
|
||||
rpc MarkAsRead(MarkAsReadRequest) returns (Empty);
|
||||
rpc SearchNotifications(SearchNotificationsRequest) returns (SearchNotificationsResponse);
|
||||
}
|
||||
|
||||
message Notification {
|
||||
string id = 1;
|
||||
string user_id = 2;
|
||||
string type = 3;
|
||||
string title = 4;
|
||||
string content = 5;
|
||||
string channel = 6;
|
||||
bool is_read = 7;
|
||||
int64 created_at = 8;
|
||||
}
|
||||
|
||||
message SendNotificationRequest {
|
||||
string user_id = 1;
|
||||
string type = 2;
|
||||
string title = 3;
|
||||
string content = 4;
|
||||
string channel = 5;
|
||||
}
|
||||
|
||||
message ListNotificationsRequest {
|
||||
string user_id = 1;
|
||||
bool only_unread = 2;
|
||||
}
|
||||
|
||||
message ListNotificationsResponse {
|
||||
repeated Notification notifications = 1;
|
||||
}
|
||||
|
||||
message MarkAsReadRequest { string id = 1; }
|
||||
message SearchNotificationsRequest {
|
||||
string user_id = 1;
|
||||
string query = 2;
|
||||
}
|
||||
message SearchNotificationsResponse {
|
||||
repeated Notification notifications = 1;
|
||||
}
|
||||
message Empty {}
|
||||
Reference in New Issue
Block a user