Wrap Stage 7.1 participant RPCs and add a version-aware ParticipantCache with batch hydration helpers for agents and services. Co-authored-by: Cursor <cursoragent@cursor.com>
109 lines
3.6 KiB
Go
109 lines
3.6 KiB
Go
package chatclient
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
pb "gitea.fe.kaien.ru/kaien/l-ai-chat-proto"
|
|
)
|
|
|
|
// GetParticipant returns one participant by author_id.
|
|
func (c *Client) GetParticipant(ctx context.Context, authorID string) (*pb.Participant, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
if authorID == "" {
|
|
return nil, fmt.Errorf("%w: author id is required", ErrInvalidConfig)
|
|
}
|
|
return c.api.GetParticipant(ctx, &pb.GetParticipantRequest{AuthorId: authorID})
|
|
}
|
|
|
|
// BatchGetParticipants fetches participants for the given author IDs
|
|
// (server deduplicates and bounds the batch).
|
|
func (c *Client) BatchGetParticipants(ctx context.Context, authorIDs []string) ([]*pb.Participant, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := c.api.BatchGetParticipants(ctx, &pb.BatchGetParticipantsRequest{AuthorIds: authorIDs})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp.GetParticipants(), nil
|
|
}
|
|
|
|
// ListTopicParticipants returns the durable topic membership roster.
|
|
func (c *Client) ListTopicParticipants(ctx context.Context, topicID string) ([]*pb.Participant, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
if topicID == "" {
|
|
return nil, fmt.Errorf("%w: topic id is required", ErrInvalidConfig)
|
|
}
|
|
resp, err := c.api.ListTopicParticipants(ctx, &pb.ListTopicParticipantsRequest{TopicId: topicID})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp.GetParticipants(), nil
|
|
}
|
|
|
|
// GetMyParticipant returns the authenticated caller's participant profile.
|
|
func (c *Client) GetMyParticipant(ctx context.Context) (*pb.Participant, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
return c.api.GetMyParticipant(ctx, &pb.GetMyParticipantRequest{})
|
|
}
|
|
|
|
// RegisterSelfProfileRequest carries mutable public agent profile fields only.
|
|
// Identity (author_id / agent_id) is derived server-side from the service token.
|
|
type RegisterSelfProfileRequest struct {
|
|
DisplayName string
|
|
Aliases map[string]string
|
|
Role string
|
|
Bio string
|
|
StatusText string
|
|
}
|
|
|
|
// RegisterSelfProfile upserts the authenticated agent's public profile and
|
|
// returns the authoritative Participant (including canonical author_id).
|
|
func (c *Client) RegisterSelfProfile(ctx context.Context, req RegisterSelfProfileRequest) (*pb.Participant, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
return c.api.RegisterSelfProfile(ctx, &pb.RegisterSelfProfileRequest{
|
|
DisplayName: req.DisplayName,
|
|
Aliases: req.Aliases,
|
|
Role: req.Role,
|
|
Bio: req.Bio,
|
|
StatusText: req.StatusText,
|
|
})
|
|
}
|
|
|
|
// SyncMyTopicMemberships replaces the authenticated agent's durable topic
|
|
// memberships with the full desired set.
|
|
func (c *Client) SyncMyTopicMemberships(ctx context.Context, topicIDs []string) (*pb.SyncMyTopicMembershipsResponse, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
return c.api.SyncMyTopicMemberships(ctx, &pb.SyncMyTopicMembershipsRequest{TopicIds: topicIDs})
|
|
}
|
|
|
|
// UploadSelfAvatar replaces the authenticated agent's avatar bytes.
|
|
func (c *Client) UploadSelfAvatar(ctx context.Context, content []byte, contentType string) (*pb.Participant, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
return c.api.UploadSelfAvatar(ctx, &pb.UploadSelfAvatarRequest{
|
|
Content: content,
|
|
ContentType: contentType,
|
|
})
|
|
}
|
|
|
|
// DeleteSelfAvatar clears the authenticated agent's avatar.
|
|
func (c *Client) DeleteSelfAvatar(ctx context.Context) (*pb.Participant, error) {
|
|
if err := c.checkOpen(); err != nil {
|
|
return nil, err
|
|
}
|
|
return c.api.DeleteSelfAvatar(ctx, &pb.DeleteSelfAvatarRequest{})
|
|
}
|