@ykurilov/agent-chat-react 0.73.0 → 0.75.0

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @ykurilov/agent-chat-react
2
2
 
3
+ ## 0.75.0
4
+
5
+ ### Minor Changes
6
+
7
+ - dfb9869: Необязательные `AgentChat.header` и `AgentChat.completion`: приложение задаёт шапку и свой итог. Итог появляется после успешно загруженной истории, когда ход свободен, скрывает поле без сброса черновика и не меняет серверное состояние. Во время ответа или активного голосового ввода управление остановкой доступно. Новые слоты Layout описаны в договоре скина 31.
8
+
9
+ В «Одуванчике» общая колонка DS 730px для шапки, переписки и поля; действия видны при наведении/фокусе и всегда на touch; поле 26–160px и круглые кнопки 40px. Используются готовые ChatHeader/ChatProgress/CompletionCard из DS, без копирования компонентов. Явный Тандем поддерживает необязательные слоты в своём оформлении.
10
+
11
+ ### Как обновить приложение
12
+
13
+ Обновите используемые пакеты SDK одной версией. Скин «Одуванчик» использует ds-react ^0.3.0 и ds-tokens ^0.2.0, отдельного CSS-импорта сверх CSS скина не требуется. Для прямых импортов ChatProgress/CompletionCard добавьте в зависимости приложения `@ykurilov/ds-react ^0.3.0`, `@ykurilov/ds-tokens ^0.2.0` и `@phosphor-icons/react ^2.1.10`. Новые свойства необязательны. Приложение передаёт `header={{ title, aside }}` и `completion={<CompletionCard .../>}`; снятие `completion` возвращает поле с прежним черновиком. Слова, статусы и действия принадлежат приложению; английские имена статусов задайте через `statusNames`. Без новых свойств дополнительных действий нет. Для собственного скина — поддержка Layout.header/completion по docs/skin-v31.md.
14
+
15
+ ## 0.74.0
16
+
17
+ ### Minor Changes
18
+
19
+ - 3140c17: Одуванчик получил композицию «Студия» и отдельный вход /sandbox с оформлением песочницы по умолчанию. Чат и журнал прокручиваются независимо; приветствие появляется только в загруженном пустом чате. В договорах скинов добавлены необязательные empty и busy, прежние скины совместимы. История песочницы сохраняет признаки транспорта, поэтому чат без фона не опрашивает несуществующий /tasks.
20
+
21
+ ### Как обновить приложение
22
+
23
+ Обновить все пакеты SDK одной версией. Для песочницы импортировать AgentSandbox из @ykurilov/agent-chat-skin-oduvanchik/sandbox, убрать прежние явные скины Тандема и подключить один CSS Одуванчика. У контейнера задать высоту и min-height: 0 у flex/grid-предков. Для сохранения Тандема оставить его импорты, явные скины и CSS. Сервер, доступ и данные не меняются. Подробности: https://github.com/ykurilov/agent-chat-sdk/blob/main/skins/oduvanchik/README.md
24
+
3
25
  ## 0.73.0
4
26
 
5
27
  No changes in this release.
@@ -362,6 +362,7 @@ var englishWorkLabels = {
362
362
  };
363
363
  var russianLabels = {
364
364
  locale: "ru",
365
+ welcome: { title: "\u0421 \u0447\u0435\u0433\u043E \u043D\u0430\u0447\u043D\u0451\u043C?", description: "\u0417\u0430\u0434\u0430\u0439\u0442\u0435 \u0432\u043E\u043F\u0440\u043E\u0441 \u0438\u043B\u0438 \u043E\u043F\u0438\u0448\u0438\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0443." },
365
366
  helpers: russianHelpers,
366
367
  tasks: russianTasks,
367
368
  notices: russianNotices,
@@ -682,6 +683,7 @@ var englishCount = (count, one, many) => `${count} ${count === 1 ? one : many}`;
682
683
  var englishMergeDate = new Intl.DateTimeFormat("en-US", { day: "numeric", month: "long", hour: "2-digit", minute: "2-digit" });
683
684
  var englishLabels = {
684
685
  locale: "en",
686
+ welcome: { title: "Where shall we start?", description: "Ask a question or describe a task." },
685
687
  ...englishWorkLabels,
686
688
  workView: englishWorkViewLabels,
687
689
  composerSettings: { levels: { off: "Off", on: "On", minimal: "Minimal", low: "Low", medium: "Medium", high: "High", max: "Max" }, model: "Model", reasoning: "Reasoning", tools: "Tools", settings: "Response settings", done: "Done", via: "Via", search: "Find model", showReasoning: "Show reasoning", project: "Project", file: "File", image: "Image", textModels: "Text tasks", imageModels: "Text and images", models: "Models", noResults: "No results", price: "USD per million tokens", input: "input", output: "output" },
@@ -963,6 +965,7 @@ function ChatLabelsProvider({ labels, children }) {
963
965
  const resolved = useMemo(
964
966
  () => ({
965
967
  ...labels,
968
+ welcome: { ...(labels.locale?.startsWith("en") ? englishLabels : russianLabels).welcome, ...labels.welcome },
966
969
  composerSettings: { ...(labels.locale?.startsWith("en") ? englishLabels : russianLabels).composerSettings, ...labels.composerSettings },
967
970
  externalImageLink: labels.externalImageLink ?? russianLabels.externalImageLink,
968
971
  answerCutByLength: labels.answerCutByLength ?? russianLabels.answerCutByLength,
@@ -2348,7 +2351,8 @@ function useAgentChat({
2348
2351
  const [accessRefusal, setAccessRefusal] = useState3(null);
2349
2352
  const [capabilities, setCapabilities] = useState3(ALL_CAPABILITIES);
2350
2353
  const [closed, setClosed] = useState3(null);
2351
- const [backgroundTasksAvailable, setBackgroundTasksAvailable] = useState3(true);
2354
+ const [backgroundCapability, setBackgroundCapability] = useState3(null);
2355
+ const backgroundTasksAvailable = backgroundCapability?.chatUrl === chatUrl2 ? backgroundCapability.available : true;
2352
2356
  const [modelAcceptsImages, setModelAcceptsImages] = useState3(void 0);
2353
2357
  const [externalContent, setExternalContent] = useState3(false);
2354
2358
  const showClosure = useCallback4((next) => {
@@ -2359,11 +2363,14 @@ function useAgentChat({
2359
2363
  const next = capabilitiesOf(history2.capabilities);
2360
2364
  setCapabilities((current) => sameCapabilities(current, next) ? current : next);
2361
2365
  showClosure(closureOf(history2.chat?.closed));
2362
- setBackgroundTasksAvailable(history2.backgroundTasks !== false);
2366
+ if (typeof history2.backgroundTasks === "boolean") {
2367
+ const available = history2.backgroundTasks;
2368
+ setBackgroundCapability((current) => current?.chatUrl === chatUrl2 && current.available === available ? current : { chatUrl: chatUrl2, available });
2369
+ }
2363
2370
  setModelAcceptsImages(typeof history2.modelAcceptsImages === "boolean" ? history2.modelAcceptsImages : void 0);
2364
2371
  if (history2.externalContent === true) setExternalContent(true);
2365
2372
  },
2366
- [showClosure]
2373
+ [chatUrl2, showClosure]
2367
2374
  );
2368
2375
  const onTurnRefusedRef = useRef5(onTurnRefused);
2369
2376
  onTurnRefusedRef.current = onTurnRefused;
@@ -5919,7 +5926,7 @@ function SubjectAgentChat(props) {
5919
5926
  if (found.state === "failed") return /* @__PURE__ */ jsx9(props.skin.ErrorNotice, { kind: "other", onRetry: found.retry });
5920
5927
  return /* @__PURE__ */ jsx9(SubjectChatLoading, { skin: props.skin });
5921
5928
  }
5922
- function AgentChatBody({ composerOptions, 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, answerDetails }) {
5929
+ function AgentChatBody({ header, completion, composerOptions, 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, answerDetails }) {
5923
5930
  const spendingNoticeId = useId2();
5924
5931
  const closedNoticeId = useId2();
5925
5932
  const chat = useAgentChat({
@@ -6339,9 +6346,14 @@ ${text}` : text),
6339
6346
  )) }) : void 0;
6340
6347
  const notices = [taskCards, connection, closedNotice, spendingNotice].filter(Boolean);
6341
6348
  const notice = notices.length > 1 ? /* @__PURE__ */ jsx9(Fragment2, { children: notices.map((part, index) => /* @__PURE__ */ jsx9(Fragment, { children: part }, index)) }) : notices[0];
6349
+ const voiceActive = Boolean(dictation.view && (dictation.view.state !== "idle" || dictation.view.polishing)) || Boolean(dialog && dialog.state !== "off" && dialog.state !== "error");
6350
+ const visibleCompletion = chat.loaded && !busy && !voiceActive && !chat.loadFailed && completion !== false ? completion : void 0;
6342
6351
  const layout = /* @__PURE__ */ jsx9(
6343
6352
  skin.Layout,
6344
6353
  {
6354
+ header,
6355
+ completion: visibleCompletion,
6356
+ empty: visibleCompletion == null && chat.loaded && !chat.loadFailed && !chat.sendFailed && !chat.serverRefusal && !chat.refusal && chat.connection === "online" && !chatClosed && !busy && feedMessages.length === 0,
6345
6357
  feed,
6346
6358
  scrollRef,
6347
6359
  announcement: announced,
@@ -7224,4 +7236,4 @@ export {
7224
7236
  activeChatTitle,
7225
7237
  useWorkspaceListSync
7226
7238
  };
7227
- //# sourceMappingURL=chunk-WJJY2WLQ.js.map
7239
+ //# sourceMappingURL=chunk-LF723Y52.js.map