Files
gitmost/apps/client
glm5.2 agent 180 24bf0ab18f feat(ai-chat): add reusable agent roles (persona + optional model)
Roles are workspace-admin presets that customize the AI agent's system-
prompt persona and, optionally, the model, attached to a chat at creation
time. Examples: a 'Proofreader' that only touches grammar, a 'Fact-
checker' that cites web sources. A role changes ONLY instructions and
( optional ) the model; the toolset stays full, so the security boundary
(CASL via the per-user loopback token) is unchanged.

Backend:
- Migration 20260620T150000-ai-agent-roles: ai_agent_roles table
  (workspace-scoped, soft-delete, model_config jsonb) + ai_chats.role_id
  (ON DELETE SET NULL).
- AiAgentRoleRepo / AiAgentRolesService / AiAgentRolesController at
  /workspace/ai-agent-roles. LIST (picker view) is open to all workspace
  members; create/update/delete are admin-only. The picker view omits
  instructions and model_config so they never leak to non-admins.
- buildSystemPrompt: optional roleInstructions REPLACES the admin persona
  (priority order: role > admin > default). The non-removable
  SAFETY_FRAMEWORK is always appended - a role cannot strip it.
- AiChatService.stream: persists roleId on first turn; subsequent turns
  read role_id from the chat row, never from the request body. The role's
  instructions are applied even if it was later disabled or soft-deleted
  (existing chats keep their persona).
- AiService.getChatModel accepts an optional override. Same-driver
  overrides reuse the workspace key; cross-driver (openai/gemini) loads
  alternate creds from ai_provider_credentials and throws a clean 503 if
  they are missing (no silent fallback). Cross-driver ollama is rejected
  with a clear message (no per-driver ollama base URL exists yet).
- Controller resolves the role model BEFORE res.hijack so misconfigured
  overrides return JSON 503, not a broken stream.

Client:
- New chat picker (Mantine Select) lists enabled roles, default
  'Universal assistant' (roleId null). The roleId is sent only when
  starting a new chat; existing chats show the role as a fixed badge.
- Role badge in the chat window header and conversation list.
- Settings -> AI: new 'Agent roles' management section mirrors the
  external MCP servers UI (add/edit/delete + enable toggle + optional
  model override). Form fields: name, emoji, description, instructions,
  model override (driver + chatModel), with a reminder that the safety
  framework is always appended.

Hardening after review:
- Empty-string roleId coerced to null on both client and server (picker
  'Universal assistant' option used to crash the uuid INSERT).
- New-chat insert validates picker-eligibility (enabled + not soft-deleted
  + workspace-scoped); ineligible ids silently fall back to null.
- findByCreator's role JOIN is workspace-scoped and every column ref is
  table-qualified (avoids Postgres ambiguous-column errors).
- getChatModelForRole applies the same picker-eligibility gate as stream
  on the new-chat path, so model and persona resolve from one source.
2026-06-20 15:54:23 +03:00
..
2024-06-07 17:29:34 +01:00
2024-01-09 18:58:26 +01:00
2024-12-09 14:51:31 +00:00
2026-06-18 18:07:54 +03:00
2024-01-09 18:58:26 +01:00
2024-01-09 18:58:26 +01:00
2024-01-09 18:58:26 +01:00
2024-01-09 18:58:26 +01:00

React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

  • Configure the top-level parserOptions property like this:
   parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: ['./tsconfig.json', './tsconfig.node.json'],
    tsconfigRootDir: __dirname,
   },
  • Replace plugin:@typescript-eslint/recommended to plugin:@typescript-eslint/recommended-type-checked or plugin:@typescript-eslint/strict-type-checked
  • Optionally add plugin:@typescript-eslint/stylistic-type-checked
  • Install eslint-plugin-react and add plugin:react/recommended & plugin:react/jsx-runtime to the extends list