Skip to main content

cmind/conversations/v1/conversation_service.proto

Package: cmind.conversations.v1

Messages

CreateConversationRequest

FieldTypeNumberDescription
tenantIdstring1
metadatamap<string, string>2
itemsrepeated ConversationItem3optional seed items, max 20

CreateConversationResponse

FieldTypeNumberDescription
conversationConversation1

GetConversationRequest

FieldTypeNumberDescription
conversationIdstring1
tenantIdstring2

GetConversationResponse

FieldTypeNumberDescription
conversationConversation1

UpdateConversationRequest

FieldTypeNumberDescription
conversationIdstring1
tenantIdstring2
metadatamap<string, string>3

UpdateConversationResponse

FieldTypeNumberDescription
conversationConversation1

DeleteConversationRequest

FieldTypeNumberDescription
conversationIdstring1
tenantIdstring2

DeleteConversationResponse

FieldTypeNumberDescription
deletedConversationDeletedConversation1

ListConversationsRequest

FieldTypeNumberDescription
tenantIdstring1
afterstring2cursor: conversation ID to start after
limitint3231-100, default 20
orderSortOrder4by last activity (updated_at); DESC = most recently active first
sourceoptional string5Only return conversations whose source equals this value. Unset returns all (default), so other OpenAI-compatible integrations don't need to send it. Used so the chat UI can hide conversations created elsewhere (e.g. openwebui).

ListConversationsResponse

FieldTypeNumberDescription
conversationsrepeated Conversation1
firstIdstring2
lastIdstring3
hasMorebool4

ForkConversationRequest

FieldTypeNumberDescription
conversationIdstring1source conversation to fork from
tenantIdstring2
upToItemIdstring3copy items up to and including this item
metadatamap<string, string>4metadata for new conversation (title)

ForkConversationResponse

FieldTypeNumberDescription
conversationConversation1

Services

ConversationService

CreateConversation

POST /cmind.conversations.v1.ConversationService/CreateConversation

CreateConversation and ListConversations gate on selected_tenant, not can_read: both are owner-scoped (create writes owner tuples, list filters by owner), so the only question is "is the caller acting in this tenant". The passport tenant is trustworthy for every principal type — extauthz membership-checks user JWTs at ingress, and an api_key's tenant is baked into the key — while can_read would reject api_key subjects, which can only reach tenant roles through group grants (CON-2468). Do NOT fix that by giving api_keys a can_read leg on tenant: model/RAG can_invoke derives from tenant can_read, so that would leak invoke on all shared models.

Request: CreateConversationRequest

Response: CreateConversationResponse

GetConversation

GET /cmind.conversations.v1.ConversationService/GetConversation

Request: GetConversationRequest

Response: GetConversationResponse

UpdateConversation

POST /cmind.conversations.v1.ConversationService/UpdateConversation

Request: UpdateConversationRequest

Response: UpdateConversationResponse

DeleteConversation

POST /cmind.conversations.v1.ConversationService/DeleteConversation

Request: DeleteConversationRequest

Response: DeleteConversationResponse

ListConversations

GET /cmind.conversations.v1.ConversationService/ListConversations

Request: ListConversationsRequest

Response: ListConversationsResponse

ForkConversation

POST /cmind.conversations.v1.ConversationService/ForkConversation

Request: ForkConversationRequest

Response: ForkConversationResponse