@ykurilov/agent-chat-react 0.70.0 → 0.71.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,15 @@
1
1
  # @ykurilov/agent-chat-react
2
2
 
3
+ ## 0.71.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8b8c651: Три вида поля Одуванчик: сжатое, обычное и расширенное. Настройки модели/провайдера/рассуждений из каталога, цена и метки, инструменты приложения, шторка телефона. Сфера и токены из опубликованных ds-react/ds-tokens. Необязательный договор скина v29, сохранение уровня ответа для подписи в истории.
8
+
9
+ ## 0.70.1
10
+
11
+ No changes in this release.
12
+
3
13
  ## 0.70.0
4
14
 
5
15
  No changes in this release.
@@ -367,6 +367,7 @@ var russianLabels = {
367
367
  notices: russianNotices,
368
368
  messengerStatus: russianMessengerStatus,
369
369
  workView: russianWorkView,
370
+ composerSettings: { levels: { off: "\u0412\u044B\u043A\u043B", on: "\u0412\u043A\u043B", minimal: "\u041C\u0438\u043D\u0438\u043C\u0443\u043C", low: "\u041D\u0438\u0437\u043A\u043E", medium: "\u0421\u0440\u0435\u0434\u043D\u0435", high: "\u0412\u044B\u0441\u043E\u043A\u043E", max: "\u041C\u0430\u043A\u0441\u0438\u043C\u0443\u043C" }, model: "\u041C\u043E\u0434\u0435\u043B\u044C", reasoning: "\u0420\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u044F", tools: "\u0418\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B", settings: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043E\u0442\u0432\u0435\u0442\u0430", done: "\u0413\u043E\u0442\u043E\u0432\u043E", via: "\u0427\u0435\u0440\u0435\u0437", search: "\u041D\u0430\u0439\u0442\u0438 \u043C\u043E\u0434\u0435\u043B\u044C", showReasoning: "\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0445\u043E\u0434 \u043C\u044B\u0441\u043B\u0438", project: "\u041F\u0440\u043E\u0435\u043A\u0442", file: "\u0424\u0430\u0439\u043B", image: "\u041A\u0430\u0440\u0442\u0438\u043D\u043A\u0430", textModels: "\u0422\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0435 \u0437\u0430\u0434\u0430\u0447\u0438", imageModels: "\u0422\u0435\u043A\u0441\u0442 \u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F", models: "\u041C\u043E\u0434\u0435\u043B\u0438", noResults: "\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E", price: "USD \u0437\u0430 \u043C\u0438\u043B\u043B\u0438\u043E\u043D \u0442\u043E\u043A\u0435\u043D\u043E\u0432", input: "\u0432\u0445\u043E\u0434", output: "\u0432\u044B\u0445\u043E\u0434" },
370
371
  composerPlaceholder: "\u041D\u0430\u043F\u0438\u0448\u0438\u0442\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
371
372
  composerLabel: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
372
373
  send: "\u041E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C",
@@ -683,6 +684,7 @@ var englishLabels = {
683
684
  locale: "en",
684
685
  ...englishWorkLabels,
685
686
  workView: englishWorkViewLabels,
687
+ 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" },
686
688
  composerPlaceholder: "Write a message",
687
689
  composerLabel: "Message",
688
690
  send: "Send",
@@ -961,6 +963,7 @@ function ChatLabelsProvider({ labels, children }) {
961
963
  const resolved = useMemo(
962
964
  () => ({
963
965
  ...labels,
966
+ composerSettings: { ...(labels.locale?.startsWith("en") ? englishLabels : russianLabels).composerSettings, ...labels.composerSettings },
964
967
  externalImageLink: labels.externalImageLink ?? russianLabels.externalImageLink,
965
968
  answerCutByLength: labels.answerCutByLength ?? russianLabels.answerCutByLength,
966
969
  answerEdited: labels.answerEdited ?? russianLabels.answerEdited,
@@ -3886,6 +3889,10 @@ function useModelChoice({ api, chatId, savedChoice, savedChoicePending = false,
3886
3889
  models: provider.models.map((model) => ({
3887
3890
  id: model.id,
3888
3891
  name: model.displayName,
3892
+ ...model.group !== void 0 && { group: model.group },
3893
+ ...model.description !== void 0 && { description: model.description },
3894
+ ...model.tags !== void 0 && { tags: model.tags },
3895
+ ...model.price !== void 0 && { price: model.price },
3889
3896
  ...typeof model.acceptsImages === "boolean" && { acceptsImages: model.acceptsImages }
3890
3897
  }))
3891
3898
  })),
@@ -5784,7 +5791,8 @@ function workLayoutOf(entries, { streaming, phrases, labels, thoughts = false })
5784
5791
  }
5785
5792
  if (streaming && lastStep > lastShown) {
5786
5793
  const live = liveStepOf(group, phrases, labels);
5787
- layout.push({ kind: "live", key, phrase: labels.live(live.phrase), icon: live.icon });
5794
+ const completed = doneLinesOf((thoughts ? group : group.filter((step) => step.kind === "tool")).filter((step) => step.kind === "tool" && step.call.state !== "running"), phrases, labels, false).items;
5795
+ layout.push({ kind: "live", key, phrase: labels.live(live.phrase), icon: live.icon, ...completed.length > 0 && { completed } });
5788
5796
  } else {
5789
5797
  const done = doneLinesOf(thoughts ? group : group.filter((step) => step.kind === "tool"), phrases, labels, !streaming);
5790
5798
  if (done.count > 0) layout.push({ kind: "done", key, ...done });
@@ -5846,7 +5854,7 @@ function WorkStepsPart({
5846
5854
  const labels = useChatLabels();
5847
5855
  const [open, setOpen] = usePartOpen(expanded, `${item.key}:work`);
5848
5856
  if (skin.WorkSteps) {
5849
- return item.kind === "live" ? /* @__PURE__ */ jsx8(skin.WorkSteps, { state: "live", phrase: item.phrase, icon: item.icon }) : /* @__PURE__ */ jsx8(
5857
+ return item.kind === "live" ? /* @__PURE__ */ jsx8(skin.WorkSteps, { state: "live", phrase: item.phrase, icon: item.icon, ...item.completed && { completed: item.completed } }) : /* @__PURE__ */ jsx8(
5850
5858
  skin.WorkSteps,
5851
5859
  {
5852
5860
  state: "done",
@@ -5881,7 +5889,7 @@ function SubjectAgentChat(props) {
5881
5889
  if (found.state === "failed") return /* @__PURE__ */ jsx9(props.skin.ErrorNotice, { kind: "other", onRetry: found.retry });
5882
5890
  return /* @__PURE__ */ jsx9(SubjectChatLoading, { skin: props.skin });
5883
5891
  }
5884
- 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 }) {
5892
+ 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 }) {
5885
5893
  const spendingNoticeId = useId2();
5886
5894
  const closedNoticeId = useId2();
5887
5895
  const chat = useAgentChat({
@@ -5913,8 +5921,17 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
5913
5921
  const attachments = attachmentsPlugin?.useController({ api, chatId, modelSeesImages: chatModelSeesImages });
5914
5922
  const describeFiles = attachments?.describe;
5915
5923
  const imageClients = useSameList(imageClientsOf(images));
5924
+ const [localReasoningVisible, setLocalReasoningVisible] = useState18(true);
5925
+ const showReasoning = composerOptions?.reasoningVisibility?.value ?? localReasoningVisible;
5926
+ const effectiveComposerOptions = useMemo16(() => ({ ...composerOptions, reasoningVisibility: composerOptions?.reasoningVisibility ?? { value: showReasoning, onChange: setLocalReasoningVisible } }), [composerOptions, showReasoning]);
5927
+ const showAnswerDetails = answerDetails ?? composerOptions?.variant === "extended";
5928
+ const answerNamesKey = showAnswerDetails ? JSON.stringify(modelChoice.providers.map(({ id, name, models }) => ({ id, name, models: models.map(({ id: id2, name: name2 }) => ({ id: id2, name: name2 })) }))) : "";
5929
+ const answerModelNames = useMemo16(() => answerNamesKey ? JSON.parse(answerNamesKey) : void 0, [answerNamesKey]);
5916
5930
  const extensions = useMemo16(
5917
5931
  () => ({
5932
+ reasoningVisible: showReasoning,
5933
+ answerDetails: showAnswerDetails,
5934
+ ...answerModelNames && { modelNames: answerModelNames },
5918
5935
  ...widgets && { widgets },
5919
5936
  ...diagrams && { diagrams },
5920
5937
  ...liveDemos && { liveDemos },
@@ -5925,7 +5942,7 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
5925
5942
  ...stepPhrases && { stepPhrases },
5926
5943
  ...noticeLines && { noticeLines }
5927
5944
  }),
5928
- [widgets, diagrams, liveDemos, imageClients, videos, appEvents, workView, stepPhrases, noticeLines]
5945
+ [widgets, diagrams, liveDemos, imageClients, videos, appEvents, workView, stepPhrases, noticeLines, showReasoning, showAnswerDetails, answerModelNames]
5929
5946
  );
5930
5947
  const scrollRef = useRef17(null);
5931
5948
  const feedRef = useRef17(null);
@@ -6301,6 +6318,7 @@ ${text}` : text),
6301
6318
  composer: /* @__PURE__ */ jsx9(
6302
6319
  skin.Composer,
6303
6320
  {
6321
+ options: effectiveComposerOptions,
6304
6322
  value: chat.value,
6305
6323
  onValueChange: chat.setValue,
6306
6324
  onSubmit: submitComposer,
@@ -6496,6 +6514,7 @@ var AgentAnswer = memo4(function AgentAnswer2({
6496
6514
  const imagesView = isToolUIPart3(part) ? describeImages?.(part) : void 0;
6497
6515
  const videoView = isToolUIPart3(part) && extensions.videos && getToolName5(part) === extensions.videos.toolName ? extensions.videos.describe(part) : void 0;
6498
6516
  if (part.type === "reasoning") {
6517
+ if (extensions.reasoningVisible === false) return;
6499
6518
  const ordinal = String(reasoningIndex++);
6500
6519
  const streaming = part.state === "streaming";
6501
6520
  const durationMs = streaming ? null : durations[ordinal] ?? null;
@@ -6631,9 +6650,12 @@ var AgentAnswer = memo4(function AgentAnswer2({
6631
6650
  }));
6632
6651
  const errorText = status === "error" ? customErrorText(labels, message.metadata?.error) : void 0;
6633
6652
  const notice = status === "error" ? /* @__PURE__ */ jsx9(skin.ErrorNotice, { kind: message.metadata?.error?.kind ?? "other", ...errorText !== void 0 && { text: errorText }, ...onRetry && { onRetry } }) : void 0;
6653
+ const answerProvider = extensions.modelNames?.find((provider) => provider.id === message.metadata?.providerId);
6654
+ const answerModel = answerProvider?.models.find((model) => model.id === message.metadata?.modelId);
6634
6655
  return /* @__PURE__ */ jsx9(ThinkingClockProvider, { id: message.id, waiting: status === "streaming", children: /* @__PURE__ */ jsxs(
6635
6656
  skin.AgentMessage,
6636
6657
  {
6658
+ ...extensions.answerDetails && message.metadata?.modelId && message.metadata?.providerId && { modelDetails: { modelId: message.metadata.modelId, providerId: message.metadata.providerId, ...answerProvider && { providerName: answerProvider.name }, ...answerModel && { modelName: answerModel.name }, ...message.metadata.reasoningLevel !== void 0 && { reasoning: message.metadata.reasoningLevel } } },
6637
6659
  status,
6638
6660
  empty: !steered && status !== "streaming" && status !== "awaiting_approval" && text.trim().length === 0,
6639
6661
  onCopy: () => void navigator.clipboard?.writeText(text),
@@ -7172,4 +7194,4 @@ export {
7172
7194
  activeChatTitle,
7173
7195
  useWorkspaceListSync
7174
7196
  };
7175
- //# sourceMappingURL=chunk-Z7X5D4OF.js.map
7197
+ //# sourceMappingURL=chunk-W5VBPNFF.js.map