@ykurilov/agent-chat-react 0.63.1 → 0.64.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.64.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 99cded9: Подробности сбоя провайдера для админа. Ответ, упавший на провайдере, хранит `error.details`: провайдер, модель, код, причина одной строкой (до 300 знаков; ключи окружения, `Bearer`, значения `key=`/`token`/`api-key`/`password`, маски ключей со `*`, параметры адресов, `org-…`/`proj_…` и e-mail вычищены; модерация может повторять текст человека) и `resetsAt` — когда провайдер снимет предел (OpenRouter «resets 2026-11-01»; только будущее до двух лет, без пояса — UTC). В браузер подробности уходят только по новому праву `chatCapabilities` → `errorDetails: true` (по умолчанию `false`, при `modelDetails: false` тоже `false`) — в истории, потоке и при переподключении; остальным — только `error.kind`. `afterTurn` получает их всегда. Экран: подпись-функция `labels.errorText(error, plain)`, без неё или если она бросила исключение — прежний текст `labels.errors[kind]`; типы `ChatError`, `ChatErrorDetails`, помощник `customErrorText`. Хранилища: тип колонки `error` — `ChatError`, миграций нет.
8
+
9
+ ## 0.63.2
10
+
11
+ No changes in this release.
12
+
3
13
  ## 0.63.1
4
14
 
5
15
  ### Patch Changes
package/README.md CHANGED
@@ -125,6 +125,18 @@ import { AgentChat, ChatLabelsProvider, russianLabels } from "@ykurilov/agent-ch
125
125
  (`process.env.NODE_ENV !== "production"`) в консоли подсказка, какой адрес вписать.
126
126
  Состояние — `refusal: "signed_out" | "too_many_turns" | "forbidden_origin" | null` у `useAgentChat`; скин получает их в `ErrorNotice` как `kind`
127
127
  (текст — `labels.errors[kind]`).
128
+ Сбой ответа подписывается `labels.errors[kind]`. Своя подпись — функция `labels.errorText(error, plain)`: `error` — вид и,
129
+ если сервер их отдал (право `errorDetails`), подробности `details` (`providerId`, `modelId`, `statusCode`, `reason`,
130
+ `resetsAt`); `plain` — `errors[kind]`. Текст уходит скину в `ErrorNotice` как `text` и диктору. Функция бросила
131
+ исключение — подпись `plain` и одна запись в консоль. Например, админу:
132
+
133
+ ```tsx
134
+ const labels = {
135
+ ...russianLabels,
136
+ errorText: (error, plain) =>
137
+ error.details?.resetsAt ? `${plain}. Предел снимут ${new Date(error.details.resetsAt).toLocaleDateString("ru")}` : plain,
138
+ };
139
+ ```
128
140
  Ответ брошен упавшей копией сервера — экран сам перечитывает историю раз в 3 с и через 30 с показывает «прерван» с «Повторить»; обновлять страницу не нужно.
129
141
  Подробности — [contracts/liveness.md](../../specs/002-fast-feed-and-liveness/contracts/liveness.md).
130
142
 
@@ -214,6 +214,20 @@ function resetDate(moment, timeZone = "UTC", withTime = false) {
214
214
  var resetPhrase = (info) => info.resetsAt ? `, \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u0441\u044F ${resetDate(info.resetsAt, info.timeZone, info.period === "rolling")}` : "";
215
215
  var mergeDate = new Intl.DateTimeFormat("ru-RU", { day: "numeric", month: "long", hour: "2-digit", minute: "2-digit" });
216
216
  var DEFAULT_VOICE_LIMIT_SECONDS = 300;
217
+ var reportedErrorTextFailure = false;
218
+ function customErrorText(labels, error) {
219
+ if (!error || !labels.errorText) return void 0;
220
+ const plain = labels.errors[error.kind];
221
+ try {
222
+ return labels.errorText(error, plain);
223
+ } catch (failure) {
224
+ if (!reportedErrorTextFailure) {
225
+ reportedErrorTextFailure = true;
226
+ console.error("labels.errorText \u0443\u043F\u0430\u043B \u2014 \u043F\u043E\u043A\u0430\u0437\u0430\u043D\u0430 \u043E\u0431\u044B\u0447\u043D\u0430\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u044C \u0441\u0431\u043E\u044F.", failure);
227
+ }
228
+ return plain;
229
+ }
230
+ }
217
231
  function voiceErrorText(errors, kind, details) {
218
232
  if (kind !== "time_limit") return errors[kind] ?? errors.other;
219
233
  const label = errors.time_limit;
@@ -4079,7 +4093,7 @@ function announcementFor(messages, labels) {
4079
4093
  const answer = messages.findLast((message) => message.role === "assistant");
4080
4094
  if (!answer) return "";
4081
4095
  const status = answer.metadata?.status ?? "complete";
4082
- if (status === "error") return labels.errors[answer.metadata?.error?.kind ?? "other"];
4096
+ if (status === "error") return customErrorText(labels, answer.metadata?.error) ?? labels.errors[answer.metadata?.error?.kind ?? "other"];
4083
4097
  if (status === "stopped") return labels.answerStopped;
4084
4098
  if (status === "interrupted") return labels.answerInterrupted;
4085
4099
  if (status === "awaiting_approval") return widgetQuestionOf(answer, labels) ?? labels.approvalAnnouncement;
@@ -6503,7 +6517,8 @@ var AgentAnswer = memo4(function AgentAnswer2({
6503
6517
  busy: runningActionIds?.includes(action.id) ?? false,
6504
6518
  onRun: () => onRunAction?.(action, message, text)
6505
6519
  }));
6506
- const notice = status === "error" ? /* @__PURE__ */ jsx9(skin.ErrorNotice, { kind: message.metadata?.error?.kind ?? "other", ...onRetry && { onRetry } }) : void 0;
6520
+ const errorText = status === "error" ? customErrorText(labels, message.metadata?.error) : void 0;
6521
+ const notice = status === "error" ? /* @__PURE__ */ jsx9(skin.ErrorNotice, { kind: message.metadata?.error?.kind ?? "other", ...errorText !== void 0 && { text: errorText }, ...onRetry && { onRetry } }) : void 0;
6507
6522
  return /* @__PURE__ */ jsx9(ThinkingClockProvider, { id: message.id, waiting: status === "streaming", children: /* @__PURE__ */ jsxs(
6508
6523
  skin.AgentMessage,
6509
6524
  {
@@ -7016,6 +7031,7 @@ export {
7016
7031
  splitVoiceTags,
7017
7032
  stripVoiceTags,
7018
7033
  voiceAnswerIds,
7034
+ customErrorText,
7019
7035
  voiceErrorText,
7020
7036
  englishWorkViewLabels,
7021
7037
  englishWorkLabels,
@@ -7042,4 +7058,4 @@ export {
7042
7058
  activeChatTitle,
7043
7059
  useWorkspaceListSync
7044
7060
  };
7045
- //# sourceMappingURL=chunk-Y5HL6THS.js.map
7061
+ //# sourceMappingURL=chunk-OAQ7TGUB.js.map