cmind/conversations/v1/conversation_service.proto
Package: cmind.conversations.v1
Messages
CreateConversationRequest
| Field | Type | Number | Description |
|---|---|---|---|
tenantId | string | 1 | |
metadata | map<string, string> | 2 | |
items | repeated ConversationItem | 3 | optional seed items, max 20 |
CreateConversationResponse
| Field | Type | Number | Description |
|---|---|---|---|
conversation | Conversation | 1 |
GetConversationRequest
| Field | Type | Number | Description |
|---|---|---|---|
conversationId | string | 1 | |
tenantId | string | 2 |
GetConversationResponse
| Field | Type | Number | Description |
|---|---|---|---|
conversation | Conversation | 1 |
UpdateConversationRequest
| Field | Type | Number | Description |
|---|---|---|---|
conversationId | string | 1 | |
tenantId | string | 2 | |
metadata | map<string, string> | 3 |
UpdateConversationResponse
| Field | Type | Number | Description |
|---|---|---|---|
conversation | Conversation | 1 |
DeleteConversationRequest
| Field | Type | Number | Description |
|---|---|---|---|
conversationId | string | 1 | |
tenantId | string | 2 |
DeleteConversationResponse
| Field | Type | Number | Description |
|---|---|---|---|
deletedConversation | DeletedConversation | 1 |
ListConversationsRequest
| Field | Type | Number | Description |
|---|---|---|---|
tenantId | string | 1 | |
after | string | 2 | cursor: conversation ID to start after |
limit | int32 | 3 | 1-100, default 20 |
order | SortOrder | 4 | by last activity (updated_at); DESC = most recently active first |
source | optional string | 5 | Only 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
| Field | Type | Number | Description |
|---|---|---|---|
conversations | repeated Conversation | 1 | |
firstId | string | 2 | |
lastId | string | 3 | |
hasMore | bool | 4 |
ForkConversationRequest
| Field | Type | Number | Description |
|---|---|---|---|
conversationId | string | 1 | source conversation to fork from |
tenantId | string | 2 | |
upToItemId | string | 3 | copy items up to and including this item |
metadata | map<string, string> | 4 | metadata for new conversation (title) |
ForkConversationResponse
| Field | Type | Number | Description |
|---|---|---|---|
conversation | Conversation | 1 |
Services
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
Request: GetConversationRequest
Response: GetConversationResponse
UpdateConversation
Request: UpdateConversationRequest
Response: UpdateConversationResponse
DeleteConversation
Request: DeleteConversationRequest
Response: DeleteConversationResponse
ListConversations
Request: ListConversationsRequest
Response: ListConversationsResponse
ForkConversation
Request: ForkConversationRequest
Response: ForkConversationResponse