205 lines
5.9 KiB
Markdown
205 lines
5.9 KiB
Markdown
# Personas
|
|
|
|
A **Persona** is the unit of access control and AI identity: system
|
|
prompt + model + provider config + KB bindings + grant scoping. Users
|
|
interact with Personas, not raw provider configs. Admins curate which
|
|
Personas are available; team admins create team-scoped Personas.
|
|
|
|
**Model inheritance:** A Persona inherits all properties of its
|
|
underlying model. This includes context window size, max output
|
|
tokens, supported capabilities (thinking, tools, vision, streaming),
|
|
input/output pricing, and provider status. When the frontend displays
|
|
a Persona, it resolves the underlying model's capabilities and shows
|
|
the same pills/badges (e.g. thinking, tools, 200k context) that the
|
|
raw model would show. The Persona adds identity (name, avatar, system
|
|
prompt, KB bindings) on top of the model's capabilities — it never
|
|
masks or reduces them.
|
|
|
|
Three scopes, three route namespaces, one domain:
|
|
|
|
| Scope | Routes | Who manages |
|
|
|-------|--------|-------------|
|
|
| Personal | `GET/POST/PUT/DELETE /personas` | The user |
|
|
| Team | `GET/POST/PUT/DELETE /teams/:teamId/personas` | Team admin |
|
|
| Global (admin) | `GET/POST/PUT/DELETE /admin/personas` | Platform admin |
|
|
|
|
All three return the same Persona object shape:
|
|
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"name": "Code Reviewer",
|
|
"description": "Reviews code for bugs and style",
|
|
"system_prompt": "You are a senior code reviewer...",
|
|
"model": "claude-sonnet-4-20250514",
|
|
"provider_config_id": "uuid|null",
|
|
"scope": "personal|team|global",
|
|
"owner_id": "uuid|null",
|
|
"is_default": false,
|
|
"is_active": true,
|
|
"avatar_url": "/api/v1/personas/uuid/avatar?v=123",
|
|
"inherited": {
|
|
"context_window": 200000,
|
|
"max_output_tokens": 8192,
|
|
"supports_vision": true,
|
|
"supports_tools": true,
|
|
"supports_thinking": true,
|
|
"supports_streaming": true,
|
|
"input_price_per_m": 3.00,
|
|
"output_price_per_m": 15.00,
|
|
"provider_status": "healthy|degraded|down|null"
|
|
},
|
|
"created_at": "...",
|
|
"updated_at": "..."
|
|
}
|
|
```
|
|
|
|
The `inherited` block is populated by the backend from the resolved
|
|
model capabilities at response time — it is not stored on the persona.
|
|
If the underlying model's capabilities change (e.g. provider upgrades
|
|
context window), the persona inherits the new values automatically.
|
|
The frontend uses `inherited` to render capability pills and context
|
|
size badges identical to the raw model.
|
|
|
|
### Personal Personas
|
|
|
|
Gated by `allow_user_personas` policy.
|
|
|
|
```
|
|
GET /personas → { "personas": [...] }
|
|
POST /personas ← { "name", "description", "system_prompt", "model", ... }
|
|
PUT /personas/:id ← partial update
|
|
DELETE /personas/:id
|
|
```
|
|
|
|
### Team Personas
|
|
|
|
```
|
|
GET /teams/:teamId/personas → { "personas": [...] }
|
|
POST /teams/:teamId/personas ← same shape
|
|
PUT /teams/:teamId/personas/:id
|
|
DELETE /teams/:teamId/personas/:id
|
|
```
|
|
|
|
### Admin (Global) Personas
|
|
|
|
```
|
|
GET /admin/personas → { "personas": [...] }
|
|
POST /admin/personas ← same shape
|
|
PUT /admin/personas/:id
|
|
DELETE /admin/personas/:id
|
|
```
|
|
|
|
### Persona KB Bindings
|
|
|
|
A Persona can have Knowledge Bases bound to it. When a channel uses
|
|
that Persona, the bound KBs are automatically scoped into `kb_search`
|
|
tool calls. Users never see or manage the underlying KBs directly —
|
|
they talk to the Persona.
|
|
|
|
**Get bindings:**
|
|
|
|
```
|
|
GET /personas/:id/knowledge-bases → { "data": [KB objects] }
|
|
GET /teams/:teamId/personas/:id/knowledge-bases → { "data": [...] }
|
|
GET /admin/personas/:id/knowledge-bases → { "data": [...] }
|
|
```
|
|
|
|
**Set bindings** (replace all):
|
|
|
|
```
|
|
PUT /personas/:id/knowledge-bases
|
|
PUT /teams/:teamId/personas/:id/knowledge-bases
|
|
PUT /admin/personas/:id/knowledge-bases
|
|
```
|
|
|
|
```json
|
|
{
|
|
"kb_ids": ["kb-uuid-1", "kb-uuid-2"],
|
|
"auto_search": {
|
|
"kb-uuid-1": true,
|
|
"kb-uuid-2": false
|
|
}
|
|
}
|
|
```
|
|
|
|
`auto_search`: when `true`, the KB is always searched (prepended to
|
|
context). When `false`, it's available via the `kb_search` tool but
|
|
not auto-injected.
|
|
|
|
### Persona Avatars
|
|
|
|
```
|
|
POST /personas/:id/avatar ← multipart/form-data (field: "avatar")
|
|
DELETE /personas/:id/avatar
|
|
POST /admin/personas/:id/avatar
|
|
DELETE /admin/personas/:id/avatar
|
|
```
|
|
|
|
### Persona Tool Grants
|
|
|
|
Control which tools a persona can use during completions. The completion
|
|
handler applies tool grants as a second-pass allowlist.
|
|
|
|
```
|
|
GET /personas/:id/tool-grants → { "grants": ["web_search", "kb_search", ...] }
|
|
PUT /personas/:id/tool-grants ← { "tool_ids": ["web_search", "calculator"] }
|
|
```
|
|
|
|
Admin equivalents:
|
|
|
|
```
|
|
GET /admin/personas/:id/tool-grants
|
|
PUT /admin/personas/:id/tool-grants
|
|
```
|
|
|
|
When a workflow version is published, persona tool grants at that moment
|
|
are frozen into the version snapshot.
|
|
|
|
### Persona Groups
|
|
|
|
Saved roster templates. A persona group is a named set of personas that
|
|
can be stamped onto new conversations.
|
|
|
|
```
|
|
GET /persona-groups → { "data": [...] }
|
|
POST /persona-groups ← { "name", "description", "scope", "team_id" }
|
|
GET /persona-groups/:id → group with members
|
|
PUT /persona-groups/:id ← partial update
|
|
DELETE /persona-groups/:id
|
|
```
|
|
|
|
**Members:**
|
|
|
|
```
|
|
POST /persona-groups/:id/members ← { "persona_id", "is_leader": false, "sort_order": 0 }
|
|
DELETE /persona-groups/:id/members/:memberId
|
|
```
|
|
|
|
`is_leader`: the leader persona responds when no @mention is present in
|
|
a group channel. Only one leader per group.
|
|
|
|
**Persona Group Object:**
|
|
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"name": "Support Team",
|
|
"description": "...",
|
|
"owner_id": "uuid",
|
|
"scope": "personal|team|global",
|
|
"team_id": "uuid|null",
|
|
"members": [
|
|
{ "id": "uuid", "persona_id": "uuid", "is_leader": true, "sort_order": 0 }
|
|
],
|
|
"created_at": "...",
|
|
"updated_at": "..."
|
|
}
|
|
```
|
|
|
|
### Resource Grants
|
|
|
|
See [teams.md](teams.md) §15.3 for the grant system. Personas use grants
|
|
to control who can see and use them beyond their base scope.
|
|
|