@things-factory/ai-assistant 10.1.233 → 10.1.241

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.
Files changed (35) hide show
  1. package/client/components/assistant-chat.ts +11 -3
  2. package/dist-client/components/assistant-chat.js +11 -4
  3. package/dist-client/components/assistant-chat.js.map +1 -1
  4. package/dist-client/tsconfig.tsbuildinfo +1 -1
  5. package/dist-server/service/assistant-chat-resolver.js +1 -1
  6. package/dist-server/service/assistant-chat-resolver.js.map +1 -1
  7. package/dist-server/service/chat-message/chat-message.js +3 -3
  8. package/dist-server/service/chat-message/chat-message.js.map +1 -1
  9. package/dist-server/service/chat-session/chat-session.js +2 -2
  10. package/dist-server/service/chat-session/chat-session.js.map +1 -1
  11. package/dist-server/service/chat-session/session-name.d.ts +8 -0
  12. package/dist-server/service/chat-session/session-name.js +32 -0
  13. package/dist-server/service/chat-session/session-name.js.map +1 -0
  14. package/dist-server/service/chat-session-participant/chat-session-participant.js +1 -1
  15. package/dist-server/service/chat-session-participant/chat-session-participant.js.map +1 -1
  16. package/dist-server/service/chat-session-resolver.js +24 -18
  17. package/dist-server/service/chat-session-resolver.js.map +1 -1
  18. package/dist-server/service/unattended-run/assistant-run.js +1 -1
  19. package/dist-server/service/unattended-run/assistant-run.js.map +1 -1
  20. package/dist-server/service/unattended-run/run-unattended.js +1 -1
  21. package/dist-server/service/unattended-run/run-unattended.js.map +1 -1
  22. package/dist-server/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +8 -8
  24. package/server/service/assistant-chat-resolver.ts +1 -1
  25. package/server/service/chat-message/chat-message.ts +3 -3
  26. package/server/service/chat-session/chat-session.ts +2 -2
  27. package/server/service/chat-session/group-room.test.ts +1 -1
  28. package/server/service/chat-session/session-name.ts +32 -0
  29. package/server/service/chat-session-participant/chat-session-participant.ts +1 -1
  30. package/server/service/chat-session-resolver.ts +27 -16
  31. package/server/service/unattended-run/assistant-run.ts +1 -1
  32. package/server/service/unattended-run/run-unattended.ts +1 -1
  33. package/test/refusals-in-korean.test.ts +80 -0
  34. package/translations/en.json +22 -2
  35. package/translations/ko.json +22 -2
@@ -71,6 +71,7 @@ const chat_message_publish_js_1 = require("./chat-message/chat-message-publish.j
71
71
  const GraphQLUpload_js_1 = tslib_1.__importDefault(require("graphql-upload/GraphQLUpload.js"));
72
72
  const registry_js_1 = require("./assistant-mode/registry.js");
73
73
  const attachment_policy_js_1 = require("./chat-session/attachment-policy.js");
74
+ const session_name_js_1 = require("./chat-session/session-name.js");
74
75
  const session_attachments_js_1 = require("./chat-session/session-attachments.js");
75
76
  let ChatSessionInboxEntry = class ChatSessionInboxEntry {
76
77
  };
@@ -215,6 +216,9 @@ tslib_1.__decorate([
215
216
  exports.ChatAttachmentInfo = ChatAttachmentInfo = tslib_1.__decorate([
216
217
  (0, type_graphql_1.ObjectType)({ description: 'A file stored with a conversation - opened only through the conversation.' })
217
218
  ], ChatAttachmentInfo);
219
+ function sessionNotFound(context) {
220
+ return new Error((0, request_translator_js_1.requestTranslator)(context)('ai-assistant.text.session-not-found', { defaultValue: 'this conversation is not here any more. reload the list.' }));
221
+ }
218
222
  /** A refusal said in the reader's words - code first, the sentence from it (ADR-0054). */
219
223
  function attachmentRefusalMessage(refusal, context) {
220
224
  const t = (key, options) => (context.t ? context.t(key, options) : String(options?.defaultValue ?? key));
@@ -224,7 +228,7 @@ function attachmentRefusalMessage(refusal, context) {
224
228
  case 'attachment-kind-not-accepted':
225
229
  return t('ai-assistant.text.attachment-kind-not-accepted', {
226
230
  name: refusal.name,
227
- kinds: refusal.kinds.join(', '),
231
+ kinds: (0, session_name_js_1.attachmentKindWords)(refusal.kinds, t),
228
232
  defaultValue: '{name} cannot be attached here - this conversation takes {kinds}.'
229
233
  });
230
234
  case 'attachment-too-large':
@@ -353,7 +357,7 @@ let ChatSessionResolver = class ChatSessionResolver {
353
357
  if (!session || !session.deletedAt)
354
358
  return false;
355
359
  if (!user?.id || session.creatorId !== user.id) {
356
- throw new Error('Only the user who created this session may bring it back.');
360
+ throw new Error((0, request_translator_js_1.requestTranslator)(context)('ai-assistant.text.restore-creator-only', { defaultValue: 'only the person who started this conversation can bring it back.' }));
357
361
  }
358
362
  await repo.restore(sessionId);
359
363
  (0, session_activity_publish_js_1.publishSessionActivity)({
@@ -440,7 +444,9 @@ let ChatSessionResolver = class ChatSessionResolver {
440
444
  return false;
441
445
  if (!user?.id || session.creatorId !== user.id) {
442
446
  /* 조용한 무동작이 아니라 명시 실패 — 지워진 줄 알고 넘어가면 안 된다. */
443
- throw new Error('Only the user who created this session may delete it. Hide it from your own list instead.');
447
+ throw new Error((0, request_translator_js_1.requestTranslator)(context)('ai-assistant.text.delete-creator-only', {
448
+ defaultValue: 'only the person who started this conversation can delete it. hide it from your own list instead.'
449
+ }));
444
450
  }
445
451
  await repo.softDelete(sessionId);
446
452
  (0, session_activity_publish_js_1.publishSessionActivity)({
@@ -511,7 +517,7 @@ let ChatSessionResolver = class ChatSessionResolver {
511
517
  async setSessionVisibility(sessionId, visibility, context) {
512
518
  const { domain, user } = context.state;
513
519
  if (!session_visibility_js_1.SESSION_VISIBILITIES.includes(visibility)) {
514
- throw new Error(`unknown visibility '${visibility}' — use ${session_visibility_js_1.SESSION_VISIBILITIES.join(' or ')}`);
520
+ throw new Error((0, request_translator_js_1.requestTranslator)(context)('ai-assistant.text.visibility-unknown', { defaultValue: 'a conversation is open, group or private.' }));
515
521
  }
516
522
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession).findOneBy({ id: sessionId, domain: { id: domain.id } });
517
523
  if (!session)
@@ -550,7 +556,7 @@ let ChatSessionResolver = class ChatSessionResolver {
550
556
  const { domain, user } = context.state;
551
557
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession).findOneBy({ id: sessionId, domain: { id: domain.id } });
552
558
  if (!session)
553
- throw new Error('chat session not found');
559
+ throw sessionNotFound(context);
554
560
  /* Only people of this domain - an id from elsewhere is not a colleague here. */
555
561
  const wanted = [...new Set((userIds ?? []).filter(id => typeof id === 'string' && id))].slice(0, 50);
556
562
  if (wanted.length === 0)
@@ -654,9 +660,8 @@ let ChatSessionResolver = class ChatSessionResolver {
654
660
  }
655
661
  async renameAISession(sessionId, name, context) {
656
662
  const { domain, user } = context.state;
657
- const trimmed = (name ?? '').trim().slice(0, 200);
658
- if (!trimmed)
659
- return false; // 빈 이름으로 지우지 않는다 — 지우려면 별도 의도가 필요하다
663
+ /* 빈 이름으로 지우지 않는다 — 지우려면 별도 의도가 필요하다. 거절은 말로 한다. */
664
+ const trimmed = (0, session_name_js_1.sessionNameOf)(name, (0, request_translator_js_1.requestTranslator)(context), false);
660
665
  const participant = await (0, shell_1.getRepository)(chat_session_participant_js_1.ChatSessionParticipant).findOne({
661
666
  where: { domain: { id: domain.id }, session: { id: sessionId }, user: { id: user.id } }
662
667
  });
@@ -826,17 +831,17 @@ let ChatSessionResolver = class ChatSessionResolver {
826
831
  const repo = (0, shell_1.getRepository)(chat_session_js_1.ChatSession, tx);
827
832
  const session = await repo.findOneBy({ id: sessionId, domain: { id: domain.id } });
828
833
  if (!session)
829
- throw new Error(`ChatSession ${sessionId} not found`);
834
+ throw sessionNotFound(context);
830
835
  /* The board-era rename door had no gate at all - a private conversation's name was anyone's to change. */
831
836
  await writeGate(session, context, tx);
832
- await repo.update(sessionId, { name: name.trim() || null, updater: user });
837
+ await repo.update(sessionId, { name: (0, session_name_js_1.sessionNameOf)(name, (0, request_translator_js_1.requestTranslator)(context), true) || null, updater: user });
833
838
  return true;
834
839
  }
835
840
  async reportProposalOutcome(sessionId, proposalKey, outcome, context) {
836
841
  const { domain, user, tx } = context.state;
837
842
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession, tx).findOneBy({ id: sessionId, domain: { id: domain.id } });
838
843
  if (!session)
839
- throw new Error(`ChatSession ${sessionId} not found`);
844
+ throw sessionNotFound(context);
840
845
  await writeGate(session, context, tx);
841
846
  const key = (proposalKey ?? '').trim();
842
847
  if (!key)
@@ -869,7 +874,7 @@ let ChatSessionResolver = class ChatSessionResolver {
869
874
  const { domain, user, tx } = context.state;
870
875
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession, tx).findOneBy({ id: sessionId, domain: { id: domain.id } });
871
876
  if (!session)
872
- throw new Error(`ChatSession ${sessionId} not found`);
877
+ throw sessionNotFound(context);
873
878
  await writeGate(session, context, tx);
874
879
  const key = (proposalKey ?? '').trim();
875
880
  if (!key)
@@ -905,7 +910,7 @@ let ChatSessionResolver = class ChatSessionResolver {
905
910
  const { domain, tx } = context.state;
906
911
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession, tx).findOneBy({ id: sessionId, domain: { id: domain.id } });
907
912
  if (!session)
908
- throw new Error(`ChatSession ${sessionId} not found`);
913
+ throw sessionNotFound(context);
909
914
  await writeGate(session, context, tx);
910
915
  const policy = (0, registry_js_1.getAssistantMode)(session.kind || kind || '')?.attachments;
911
916
  const uploads = await Promise.all(files);
@@ -924,7 +929,7 @@ let ChatSessionResolver = class ChatSessionResolver {
924
929
  const { domain, user, tx } = context.state;
925
930
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession, tx).findOneBy({ id: sessionId, domain: { id: domain.id } });
926
931
  if (!session)
927
- throw new Error(`ChatSession ${sessionId} not found`);
932
+ throw sessionNotFound(context);
928
933
  await writeGate(session, context, tx);
929
934
  const body = (0, room_message_js_1.roomMessageBody)(content);
930
935
  if (!body)
@@ -933,8 +938,9 @@ let ChatSessionResolver = class ChatSessionResolver {
933
938
  const previousLast = replyToId
934
939
  ? await messages.findOneBy({ id: replyToId, session: { id: session.id } })
935
940
  : await messages.findOne({ where: { session: { id: session.id } }, order: { createdAt: 'DESC' } });
936
- if (replyToId && !previousLast)
937
- throw new Error('The message to reply to is not in this conversation');
941
+ if (replyToId && !previousLast) {
942
+ throw new Error((0, request_translator_js_1.requestTranslator)(context)('ai-assistant.text.reply-target-missing', { defaultValue: 'the message you are replying to is not in this conversation.' }));
943
+ }
938
944
  const saved = await (0, shell_1.getRepository)(chat_message_js_1.ChatMessage, tx).save({
939
945
  session: { id: session.id },
940
946
  role: 'user',
@@ -982,7 +988,7 @@ let ChatSessionResolver = class ChatSessionResolver {
982
988
  const { domain, user, tx } = context.state;
983
989
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession, tx).findOneBy({ id: sessionId, domain: { id: domain.id } });
984
990
  if (!session)
985
- throw new Error(`ChatSession ${sessionId} not found`);
991
+ throw sessionNotFound(context);
986
992
  await writeGate(session, context, tx);
987
993
  /* 프롬프트가 한 기록으로 폭증하지 않도록 자른다 — 맥락 전달이 목적이고 전문 보존이 아니다. */
988
994
  const body = (content ?? '').trim().slice(0, 4000);
@@ -1023,7 +1029,7 @@ let ChatSessionResolver = class ChatSessionResolver {
1023
1029
  const { domain, user, tx } = context.state;
1024
1030
  const session = await (0, shell_1.getRepository)(chat_session_js_1.ChatSession, tx).findOneBy({ id: sessionId, domain: { id: domain.id } });
1025
1031
  if (!session)
1026
- throw new Error(`ChatSession ${sessionId} not found`);
1032
+ throw sessionNotFound(context);
1027
1033
  await writeGate(session, context, tx);
1028
1034
  /* 옮겨온 대화는 **그 대화의 발언 그대로** 들어간다 — 한 덩어리 기록으로 뭉치면 사람이 읽을 수 없고
1029
1035
  * (화면 하나를 잡아먹는 이탤릭 덩어리), 마크다운도 죽는다. 대신 개수·길이는 제한한다: 맥락 전달이