@ykurilov/agent-chat-react 0.64.0 → 0.65.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +5 -0
- package/dist/{chunk-OAQ7TGUB.js → chunk-JLGBVDAR.js} +32 -6
- package/dist/chunk-JLGBVDAR.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/panel.js +1 -1
- package/dist/types/agent-chat-extensions.d.ts +12 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/notices/agent-notices.d.ts +11 -1
- package/dist/types/skin-contract.d.ts +12 -1
- package/package.json +1 -1
- package/dist/chunk-OAQ7TGUB.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @ykurilov/agent-chat-react
|
|
2
2
|
|
|
3
|
+
## 0.65.1
|
|
4
|
+
|
|
5
|
+
No changes in this release.
|
|
6
|
+
|
|
7
|
+
## 0.65.0
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- 814ee7f: Пометка «Агент написал первым — человек молчал 1 ч 7 мин» перед ответом, который агент написал сам. Ядро: право чата `appNotices` (по умолчанию выключено) — служебные пометки приложения (`kind: "app"`) уходят в историю без текста для модели и только через белый список `appNoticeViews` (имя → безопасные данные для экрана; без функции пометка не уходит); `modelDetails: false` выключает и `appNotices`. React: `noticeLines` у `AgentChat` (имя пометки → строка), договор скина 27 — необязательный `ServiceLine`. Сценарии: в данных пометки `silentMs` (от последнего сообщения человека) и `exit`, проекция для экрана регистрируется в `withChat`, готовые строки `flowNoticeLines()` с подписями `russianFlowNoticeLabels`/`englishFlowNoticeLabels` (`FlowLabels.notices`); `FlowTestChat` передаёт их в `renderChat(chatId, { noticeLines })`. Тандем рисует `ServiceLine`. Как подключить — CHANGES.md, раздел 0.65.0.
|
|
12
|
+
|
|
3
13
|
## 0.64.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -39,6 +39,11 @@ import { AgentChat, ChatLabelsProvider, russianLabels } from "@ykurilov/agent-ch
|
|
|
39
39
|
необязательными `wide` (по ширине ответа со своей пропорцией) и `caption` (подпись под картинкой). Договор скина
|
|
40
40
|
версии 26; скин версии 25 работает без правок: плитка ближайшей обычной пропорции без подписи —
|
|
41
41
|
[docs/skin-v26.md](https://github.com/ykurilov/agent-chat-sdk/blob/main/docs/skin-v26.md).
|
|
42
|
+
- Служебные пометки приложения (`kind: "app"`) — серой строкой перед ответом агента: «Агент написал первым — человек
|
|
43
|
+
молчал 1 ч 7 мин». Нужны право чата `appNotices` на сервере (по умолчанию выключено), `noticeLines` у `AgentChat`
|
|
44
|
+
(имя пометки → строка; для сценариев — `flowNoticeLines()`) и `ServiceLine` у скина. Договор скина версии 27; скин
|
|
45
|
+
версии 26 работает без правок: пометок не видно —
|
|
46
|
+
[docs/skin-v27.md](https://github.com/ykurilov/agent-chat-sdk/blob/main/docs/skin-v27.md).
|
|
42
47
|
- `ChatWorkspace` — список чатов и открытый чат вместе: создать, переименовать, удалить (нужен `chatList: true` на сервере). Хук — `useChatList`. Скину дополнительно нужны `ChatWorkspace` и `ChatList` (`ChatListSkin`, договор версии 7).
|
|
43
48
|
- `AgentMemory` — экран долгой памяти агента: записи по разделам, добавить, изменить, удалить, «Стереть всю память» (нужна опция `memory` на сервере, пакет `@ykurilov/agent-chat-memory`). `api` — `createMemoryApi({ api: "/api/chat" })`, создавать один раз; `skin` — `MemorySkin` (`tandemMemorySkin`). Хук — `useMemoryNotes`. Без памяти на сервере экран пишет, что память не включена. Договор скина версии 11 — отдельный `MemorySkin`, `ChatSkin` не менялся ([contracts/memory.md](../../specs/017-long-term-memory/contracts/memory.md)).
|
|
44
49
|
- Панель агента: вход `@ykurilov/agent-chat-react/panel`; основной вход его не подтягивает. `AgentPanelProvider` ставится в корневой макет выше страниц (`api`, `userKey`, `browserTools`, `mode` — `overlay` или `push`, `width`, `onDataChanged`, `fetch` — свой `fetch` только для списка чатов), `AgentPanel` рисует кнопку, рамку и чат через скин. Хуки: `useAgentPanel` (`open`, `openChat`, `openNewChat({ draft })`, `pageInset` — отступ страницы в режиме `push`, на экране ≤ 640 px он 0, `busy`), `useAgentPlace({ description, data? })` (где человек; модель видит только описание, `data` — только инструменты), `useAgentDataChanges(tag, handler)` (страница узнаёт, что инструмент изменил данные). Браузерные инструменты — функции в `browserTools` с теми же именами, что описания на сервере (`BrowserToolImplementations`); нет функции — модель получает «Инструмент недоступен на этой странице» (надпись `agentPanelToolUnavailable`). Подробно — [docs/getting-started.md](../../docs/getting-started.md#панель-агента-в-приложении-по-желанию). Общие части: `AgentAppBridge` (связь чата с приложением; `appBridge` в `AgentChat`, `useAgentChat`, `ChatWorkspace`), `initialDraft` (текст в поле ввода при открытии чата), `rememberKey` в `useChatList` (свой ключ запомненного чата). Договор скина версии 12 — отдельный `AgentPanelSkin` (`AgentPanelLauncher`, `AgentPanel`), надписи `agentPanel…` в словаре; `ChatSkin`, `ChatListSkin` и `MemorySkin` не менялись ([contracts/skin.md](../../specs/021-agent-panel/contracts/skin.md)).
|
|
@@ -2187,8 +2187,17 @@ function useBackgroundTasks({ chatUrl: chatUrl2, enabled, version, fetch: custom
|
|
|
2187
2187
|
|
|
2188
2188
|
// src/notices/agent-notices.ts
|
|
2189
2189
|
var AGENT_NOTICE_PART_TYPE = "data-agent-notice";
|
|
2190
|
+
var isAgentNoticePart = (part) => part.type === AGENT_NOTICE_PART_TYPE;
|
|
2190
2191
|
function agentNoticesOf(message) {
|
|
2191
|
-
return rawNoticesOf(message).filter((notice) => notice.kind !== STAFF_NOTICE_KIND);
|
|
2192
|
+
return rawNoticesOf(message).filter((notice) => notice.kind !== STAFF_NOTICE_KIND && notice.kind !== APP_NOTICE_KIND);
|
|
2193
|
+
}
|
|
2194
|
+
var APP_NOTICE_KIND = "app";
|
|
2195
|
+
function appNoticesOf(message) {
|
|
2196
|
+
return rawNoticesOf(message).flatMap((notice) => {
|
|
2197
|
+
if (notice.kind !== APP_NOTICE_KIND) return [];
|
|
2198
|
+
const { name, data } = notice;
|
|
2199
|
+
return typeof name === "string" ? [{ name, data }] : [];
|
|
2200
|
+
});
|
|
2192
2201
|
}
|
|
2193
2202
|
var STAFF_NOTICE_KIND = "staff";
|
|
2194
2203
|
function staffRepliesOf(message) {
|
|
@@ -5790,7 +5799,7 @@ function SubjectAgentChat(props) {
|
|
|
5790
5799
|
if (found.state === "failed") return /* @__PURE__ */ jsx9(props.skin.ErrorNotice, { kind: "other", onRetry: found.retry });
|
|
5791
5800
|
return /* @__PURE__ */ jsx9(SubjectChatLoading, { skin: props.skin });
|
|
5792
5801
|
}
|
|
5793
|
-
function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attachments: attachmentsPlugin, spendingLimits, onBusyChange, appBridge, initialDraft, answerEditing, onFeedChange, messageActions, onTurnFinished, onTurnRefused, composerActions, onAppEvent, onChatAccessChange, onStateChange, onModelChosen, onChatUnavailable, reloadKey, steering, widgets, diagrams, liveDemos, images, videos, appEvents, workView, stepPhrases }) {
|
|
5802
|
+
function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attachments: attachmentsPlugin, spendingLimits, onBusyChange, appBridge, initialDraft, answerEditing, onFeedChange, messageActions, onTurnFinished, onTurnRefused, composerActions, onAppEvent, onChatAccessChange, onStateChange, onModelChosen, onChatUnavailable, reloadKey, steering, widgets, diagrams, liveDemos, images, videos, appEvents, workView, stepPhrases, noticeLines }) {
|
|
5794
5803
|
const spendingNoticeId = useId2();
|
|
5795
5804
|
const closedNoticeId = useId2();
|
|
5796
5805
|
const chat = useAgentChat({
|
|
@@ -5831,9 +5840,10 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
5831
5840
|
...videos && { videos },
|
|
5832
5841
|
...appEvents && { appEvents },
|
|
5833
5842
|
...workView && { workView },
|
|
5834
|
-
...stepPhrases && { stepPhrases }
|
|
5843
|
+
...stepPhrases && { stepPhrases },
|
|
5844
|
+
...noticeLines && { noticeLines }
|
|
5835
5845
|
}),
|
|
5836
|
-
[widgets, diagrams, liveDemos, imageClients, videos, appEvents, workView, stepPhrases]
|
|
5846
|
+
[widgets, diagrams, liveDemos, imageClients, videos, appEvents, workView, stepPhrases, noticeLines]
|
|
5837
5847
|
);
|
|
5838
5848
|
const scrollRef = useRef17(null);
|
|
5839
5849
|
const feedRef = useRef17(null);
|
|
@@ -5999,7 +6009,10 @@ ${text}` : text),
|
|
|
5999
6009
|
const NoticeView = skin.AgentNoticeView;
|
|
6000
6010
|
const notices2 = agentNoticesOf(message);
|
|
6001
6011
|
const staffReplies = staffRepliesOf(message);
|
|
6002
|
-
const
|
|
6012
|
+
const appNotices = appNoticesOf(message);
|
|
6013
|
+
const serviceLines = appNotices.length > 0 && /* @__PURE__ */ jsx9(ServiceLines, { skin, notices: appNotices, lines: extensions.noticeLines });
|
|
6014
|
+
const onlyAppNotices = appNotices.length > 0 && notices2.length === 0 && staffReplies.length === 0 && message.parts.every(isAgentNoticePart);
|
|
6015
|
+
const content = onlyAppNotices ? /* @__PURE__ */ jsx9(Fragment2, {}) : staffReplies.length > 0 ? /* @__PURE__ */ jsx9(StaffReplies, { skin, replies: staffReplies, label: labels.notices.staffSaid }) : notices2.length > 0 ? NoticeView ? /* @__PURE__ */ jsx9(Fragment2, { children: notices2.map((notice2, noticeIndex) => /* @__PURE__ */ jsx9(NoticeView, { ...noticeViewOf(notice2, noticeControls) }, noticeIndex)) }) : (
|
|
6003
6016
|
// Скин без плашек (v16): короткая строка из словаря, не пустой пузырь; править служебное сообщение нельзя.
|
|
6004
6017
|
/* @__PURE__ */ jsx9(skin.UserMessage, { text: noticesAsText(notices2, labels.notices), ...branchSwitcher && { branchSwitcher } })
|
|
6005
6018
|
) : message.role === "user" ? editingId === message.id ? /* @__PURE__ */ jsx9(
|
|
@@ -6072,6 +6085,10 @@ ${text}` : text),
|
|
|
6072
6085
|
}
|
|
6073
6086
|
}
|
|
6074
6087
|
);
|
|
6088
|
+
const shown = serviceLines ? /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
6089
|
+
serviceLines,
|
|
6090
|
+
content
|
|
6091
|
+
] }) : content;
|
|
6075
6092
|
const markers = dividers.get(message.id);
|
|
6076
6093
|
return markers ? /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
6077
6094
|
shown,
|
|
@@ -6269,6 +6286,15 @@ var EDIT_REFUSAL_ERRORS = {
|
|
|
6269
6286
|
// Текст сервера идёт в редактор как есть; надпись — на случай, если текста почему-то нет.
|
|
6270
6287
|
server_refused: "rejected"
|
|
6271
6288
|
};
|
|
6289
|
+
function ServiceLines({ skin, notices, lines }) {
|
|
6290
|
+
const View = skin.ServiceLine;
|
|
6291
|
+
if (!View || !lines) return null;
|
|
6292
|
+
const texts = notices.flatMap((notice) => {
|
|
6293
|
+
const text = Object.hasOwn(lines, notice.name) ? lines[notice.name](notice) : void 0;
|
|
6294
|
+
return text ? [{ name: notice.name, text }] : [];
|
|
6295
|
+
});
|
|
6296
|
+
return /* @__PURE__ */ jsx9(Fragment2, { children: texts.map(({ name, text }, index) => /* @__PURE__ */ jsx9(View, { text }, `${name}-${index}`)) });
|
|
6297
|
+
}
|
|
6272
6298
|
function StaffReplies({ skin, replies, label }) {
|
|
6273
6299
|
const View = skin.StaffMessage;
|
|
6274
6300
|
return /* @__PURE__ */ jsx9(Fragment2, { children: replies.map(
|
|
@@ -7058,4 +7084,4 @@ export {
|
|
|
7058
7084
|
activeChatTitle,
|
|
7059
7085
|
useWorkspaceListSync
|
|
7060
7086
|
};
|
|
7061
|
-
//# sourceMappingURL=chunk-
|
|
7087
|
+
//# sourceMappingURL=chunk-JLGBVDAR.js.map
|