Merge branch 'develop' into test/coverage-batch1
This commit is contained in:
@@ -10,6 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- **Public share AI: default per-workspace hourly assistant cap lowered
|
||||
300 → 100.** The limiter falls back to this default whenever
|
||||
`SHARE_AI_WORKSPACE_MAX_PER_HOUR` is unset, so a `0.93.0` deployment that
|
||||
never set the env var has its anonymous public-share assistant hourly cap
|
||||
cut from 300 to 100 on upgrade. Set `SHARE_AI_WORKSPACE_MAX_PER_HOUR` to
|
||||
keep the previous limit. (#62)
|
||||
|
||||
## [0.93.0] - 2026-06-21
|
||||
|
||||
This release builds on the 0.91.0 AI foundation: admin-defined AI agent roles,
|
||||
|
||||
@@ -1147,6 +1147,7 @@
|
||||
"Take a look at the current document": "Take a look at the current document",
|
||||
"AI agent is typing…": "AI agent is typing…",
|
||||
"{{name}} is typing…": "{{name}} is typing…",
|
||||
"AI is typing…": "AI is typing…",
|
||||
"Send": "Send",
|
||||
"Stop": "Stop",
|
||||
"Chat menu": "Chat menu",
|
||||
|
||||
@@ -672,6 +672,7 @@
|
||||
"Take a look at the current document": "Посмотри текущий документ",
|
||||
"AI agent is typing…": "AI-агент печатает…",
|
||||
"{{name}} is typing…": "{{name}} печатает…",
|
||||
"AI is typing…": "AI печатает…",
|
||||
"Agent role": "Роль агента",
|
||||
"AI chat": "AI-чат",
|
||||
"AI chat is disabled for this workspace.": "AI-чат отключён для этого рабочего пространства.",
|
||||
|
||||
@@ -43,7 +43,7 @@ interface MessageListProps {
|
||||
const BOTTOM_THRESHOLD = 40;
|
||||
|
||||
/**
|
||||
* Whether to show the standalone "AI agent is typing…" indicator. It bridges the
|
||||
* Whether to show the standalone "AI is typing…" indicator. It bridges the
|
||||
* gap between sending and the first streamed content, so it shows only while a
|
||||
* turn is in flight AND the latest assistant message has nothing visible yet:
|
||||
* - the last message is still the user's (assistant hasn't started a row), or
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
/* flex-start keeps the first row reachable when the wrapped cards overflow and
|
||||
the container scrolls. With align-content: center, an overflowing top row is
|
||||
pushed out of the scrollable area and becomes unreachable. The parent Mantine
|
||||
Center still vertically centers the whole block when it fits. */
|
||||
align-content: flex-start;
|
||||
gap: 10px;
|
||||
/* Cap the height so a large number of roles scrolls instead of blowing out
|
||||
the empty chat area. */
|
||||
@@ -21,7 +25,7 @@
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
min-width: 140px;
|
||||
max-width: 180px;
|
||||
max-width: 200px;
|
||||
min-height: 90px;
|
||||
padding: 12px 10px;
|
||||
border-radius: var(--mantine-radius-md);
|
||||
@@ -50,4 +54,8 @@
|
||||
.description {
|
||||
opacity: 0.8;
|
||||
line-height: 1.3;
|
||||
/* Break long unbreakable tokens (URLs, long foreign words) in the
|
||||
admin-configured description so they wrap instead of overflowing the card
|
||||
width now that the line clamp no longer caps the text. */
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ function RoleCard({
|
||||
{name}
|
||||
</Text>
|
||||
{description && (
|
||||
<Text size="xs" lineClamp={3} className={classes.description}>
|
||||
<Text size="xs" className={classes.description}>
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { showTypingIndicator } from "@/features/ai-chat/components/message-list.
|
||||
/**
|
||||
* Pure-helper tests for the typing-indicator bridging logic that the internal
|
||||
* chat and the public share widget now share. This is the behavior that decides
|
||||
* whether the animated "AI agent is typing…" placeholder shows in the gap
|
||||
* whether the animated "AI is typing…" placeholder shows in the gap
|
||||
* between sending and the first streamed token.
|
||||
*/
|
||||
const msg = (
|
||||
|
||||
@@ -19,8 +19,10 @@ interface TypingIndicatorProps {
|
||||
* the real assistant message once content starts arriving.
|
||||
*
|
||||
* Mirrors the assistant row layout in MessageItem (the dimmed label), so it reads
|
||||
* as the assistant's bubble taking shape. The label and typing line use the
|
||||
* configured identity name when provided, otherwise the generic "AI agent".
|
||||
* as the assistant's bubble taking shape. The dimmed label uses the configured
|
||||
* identity name when provided (otherwise the generic "AI agent"), while the
|
||||
* typing line is always the generic "AI is typing…" (it never includes the
|
||||
* role/identity name).
|
||||
*/
|
||||
export default function TypingIndicator({ assistantName }: TypingIndicatorProps) {
|
||||
const { t } = useTranslation();
|
||||
@@ -38,7 +40,7 @@ export default function TypingIndicator({ assistantName }: TypingIndicatorProps)
|
||||
<span />
|
||||
</span>
|
||||
<Text size="sm" c="dimmed">
|
||||
{name ? t("{{name}} is typing…", { name }) : t("AI agent is typing…")}
|
||||
{t("AI is typing…")}
|
||||
</Text>
|
||||
</Group>
|
||||
</Box>
|
||||
|
||||
33
docs/backlog/ai-chat-stream-integration-coverage.md
Normal file
33
docs/backlog/ai-chat-stream-integration-coverage.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Отложенные интеграционные тесты `AiChatService.stream`
|
||||
|
||||
Статус: **открыто.** Это остаток от прежнего документа
|
||||
`feature-test-coverage-deferred.md` (хвост тест-плана PR #49). Два из трёх
|
||||
его разделов уже закрыты новой интеграционной обвязкой против реального
|
||||
Postgres/Redis (`apps/server/test/integration/`, PR #115):
|
||||
|
||||
- ✅ **Раздел 1 — repo-тесты против БД.** Закрыт `ai-agent-roles-repo`,
|
||||
`ai-chat-repo-find-by-creator`, `page-template-references-cascade`,
|
||||
`workspace-repo-update-setting` (`*.int-spec.ts`).
|
||||
- ✅ **Раздел 2 — достоверность Lua-окна cost-cap против реального Redis.**
|
||||
Закрыт `public-share-workspace-limiter.int-spec.ts`.
|
||||
- ⬜ **Раздел 3 (ниже) — полная интеграция `AiChatService.stream`.** Всё ещё
|
||||
не реализован; держим запись открытой, чтобы тест-долг не потерялся при
|
||||
удалении исходного документа.
|
||||
|
||||
## Полная интеграция `AiChatService.stream` (рефактор R1-stream)
|
||||
|
||||
`apps/server/src/core/ai-chat/ai-chat.service.ts`. В PR #49 извлечён и
|
||||
покрыт только чистый `buildErrorAssistantRecord`. Полные интеграционные
|
||||
сценарии всё ещё отложены:
|
||||
|
||||
- **Запись чата, упавшего на первом ходу** (`onError`) — ассистентская
|
||||
запись об ошибке должна сохраняться, даже когда первый ход стрима падает.
|
||||
- **Жизненный цикл external-MCP клиентов** — клиенты закрываются и при
|
||||
`throw`, и при `onFinish` (нет утечки соединений).
|
||||
- **Анти-tamper: история восстанавливается из БД, а не из `body.messages`** —
|
||||
клиент не может подменить историю через тело запроса.
|
||||
|
||||
Эти сценарии требуют сидирования SDK `streamText` (инъекция/seam колбэков
|
||||
`onError` / `onFinish` / `onAbort` + `res.hijack`). Отложено, чтобы не
|
||||
дестабилизировать 287-строчный `stream()`; делать вместе с выносом testable
|
||||
turn-pipeline.
|
||||
Reference in New Issue
Block a user