@promptbook/cli 0.112.0-126 → 0.112.0-127

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 (190) hide show
  1. package/README.md +5 -5
  2. package/apps/agents-server/README.md +3 -0
  3. package/apps/agents-server/playwright.config.ts +1 -0
  4. package/apps/agents-server/public/promptbook-logo-blue.png +0 -0
  5. package/apps/agents-server/public/promptbook-logo-white.png +0 -0
  6. package/apps/agents-server/src/app/[agentName]/layout.tsx +1 -0
  7. package/apps/agents-server/src/app/actions.ts +2 -2
  8. package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +68 -36
  9. package/apps/agents-server/src/app/agents/[agentName]/ActiveAgentBreadcrumbBinder.tsx +30 -0
  10. package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +2 -0
  11. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatHistoryPayloadState.ts +38 -4
  12. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatHistorySyncOperations.ts +4 -1
  13. package/apps/agents-server/src/app/agents/[agentName]/chat/CanonicalAgentChatSurface.tsx +19 -15
  14. package/apps/agents-server/src/app/agents/[agentName]/chat/useCanonicalAgentChatPanelState.ts +58 -7
  15. package/apps/agents-server/src/app/agents/[agentName]/layout.tsx +47 -1
  16. package/apps/agents-server/src/app/api/chat/citation-label/route.ts +133 -0
  17. package/apps/agents-server/src/app/globals.css +78 -0
  18. package/apps/agents-server/src/components/Header/ActiveAgentBreadcrumbContext.tsx +82 -0
  19. package/apps/agents-server/src/components/Header/useHeaderActiveAgent.ts +26 -7
  20. package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +35 -32
  21. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/ManGoNewAgentWizard.tsx +151 -0
  22. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/ManGoOnboardingNavigation.tsx +50 -0
  23. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/BookLanguagePanel.tsx +125 -0
  24. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/DropZone.tsx +83 -0
  25. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/EmailTestRun.tsx +216 -0
  26. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/KnowledgeList.tsx +79 -0
  27. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/Logo.tsx +20 -0
  28. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownBookEditor.tsx +154 -0
  29. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownPreview.tsx +188 -0
  30. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/RailStepper.tsx +115 -0
  31. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/StepFrame.tsx +47 -0
  32. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/TestChat.tsx +159 -0
  33. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/WizardShell.tsx +114 -0
  34. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/brand/RailArtwork.tsx +60 -0
  35. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/BookStep.tsx +135 -0
  36. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/DoneStep.tsx +215 -0
  37. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/KnowledgeStep.tsx +152 -0
  38. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/TestStep.tsx +262 -0
  39. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/ZadaniStep.tsx +64 -0
  40. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Badge.tsx +41 -0
  41. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Banner.tsx +69 -0
  42. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Button.tsx +77 -0
  43. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Card.tsx +33 -0
  44. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Field.tsx +103 -0
  45. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/IconButton.tsx +40 -0
  46. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Spinner.tsx +14 -0
  47. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/tokens.ts +37 -0
  48. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/bookSections.ts +62 -0
  49. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/emailScenarios.ts +22 -0
  50. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/steps.ts +46 -0
  51. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/index.ts +11 -0
  52. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/cn.ts +4 -0
  53. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/format.ts +9 -0
  54. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/id.ts +11 -0
  55. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/agentEvalService.ts +30 -0
  56. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/agentTestService.ts +69 -0
  57. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/bookService.ts +21 -0
  58. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/createManGoAgentSource.ts +107 -0
  59. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/draftService.ts +45 -0
  60. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/uploadService.ts +27 -0
  61. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/state/OnboardingProvider.tsx +121 -0
  62. package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/types.ts +52 -0
  63. package/apps/agents-server/src/components/NewAgentDialog/createNewAgentWizardSource.ts +1 -1
  64. package/apps/agents-server/src/components/NewAgentDialog/trackNewAgentCreationEvent.ts +1 -1
  65. package/apps/agents-server/src/components/NewAgentDialog/useNewAgentDialog.tsx +76 -0
  66. package/apps/agents-server/src/constants/newAgentWizard.ts +17 -8
  67. package/apps/agents-server/src/database/getMetadata.ts +37 -1
  68. package/apps/agents-server/src/database/metadataDefaults.ts +18 -7
  69. package/apps/agents-server/src/database/migrations/2026-06-2200-new-agent-wizard-metadata-key.sql +27 -0
  70. package/apps/agents-server/src/database/migrations/2026-06-2201-new-agent-wizard-mango-default.sql +11 -0
  71. package/apps/agents-server/src/generated/reservedPaths.ts +2 -0
  72. package/apps/agents-server/src/languages/translations/english.yaml +1 -1
  73. package/apps/agents-server/src/tools/createChatAttachmentToolFunctions.ts +8 -4
  74. package/apps/agents-server/src/utils/chat/resolveAgentsServerCitationLabel.ts +130 -0
  75. package/apps/agents-server/src/utils/chat/resolveCitationSourceLabel.ts +436 -0
  76. package/apps/agents-server/src/utils/knowledge/resolveWebsiteKnowledgeSourcesForServer.ts +10 -1
  77. package/apps/agents-server/src/utils/session.ts +62 -5
  78. package/apps/agents-server/src/utils/transpilers/resolveTranspiledTeamExport.ts +10 -10
  79. package/apps/agents-server/src/utils/userChat/userChatProgressCard.ts +198 -63
  80. package/apps/agents-server/src/utils/vpsConfiguration.ts +1 -0
  81. package/apps/agents-server/src/utils/vpsSelfUpdate.ts +81 -8
  82. package/esm/index.es.js +1052 -455
  83. package/esm/index.es.js.map +1 -1
  84. package/esm/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -1
  85. package/esm/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -2
  86. package/esm/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +50 -0
  87. package/esm/scripts/run-codex-prompts/server/buildCoderServerRunState.d.ts +23 -0
  88. package/esm/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
  89. package/esm/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +13 -1
  90. package/esm/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
  91. package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -0
  92. package/esm/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +4 -0
  93. package/esm/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +1 -0
  94. package/esm/src/_packages/components.index.d.ts +2 -0
  95. package/esm/src/_packages/types.index.d.ts +2 -0
  96. package/esm/src/avatars/avatarAnimationScheduler.d.ts +4 -0
  97. package/esm/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
  98. package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
  99. package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
  100. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  101. package/esm/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
  102. package/esm/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
  103. package/esm/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
  104. package/esm/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
  105. package/esm/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
  106. package/esm/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
  107. package/esm/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
  108. package/esm/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
  109. package/esm/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
  110. package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
  111. package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
  112. package/esm/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
  113. package/esm/src/version.d.ts +1 -1
  114. package/package.json +1 -1
  115. package/src/_packages/components.index.ts +2 -0
  116. package/src/_packages/types.index.ts +2 -0
  117. package/src/avatars/avatarAnimationScheduler.ts +61 -20
  118. package/src/avatars/visuals/octopus3d2AvatarVisual.ts +106 -21
  119. package/src/avatars/visuals/octopus3d3AvatarVisual.ts +131 -28
  120. package/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.ts +18 -2
  121. package/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.ts +7 -1
  122. package/src/book-components/Chat/Chat/Chat.tsx +4 -0
  123. package/src/book-components/Chat/Chat/ChatCitationModal.tsx +17 -3
  124. package/src/book-components/Chat/Chat/ChatMessageItem.tsx +22 -2
  125. package/src/book-components/Chat/Chat/ChatMessageList.tsx +6 -0
  126. package/src/book-components/Chat/Chat/ChatProps.tsx +6 -0
  127. package/src/book-components/Chat/Chat/ChatToolCallModal.tsx +4 -0
  128. package/src/book-components/Chat/Chat/ChatToolCallModalContent.tsx +4 -0
  129. package/src/book-components/Chat/Chat/TeamToolCallModalContent.tsx +16 -3
  130. package/src/book-components/Chat/Chat/useChatPostprocessedMessages.ts +13 -2
  131. package/src/book-components/Chat/SourceChip/SourceChip.module.css +8 -0
  132. package/src/book-components/Chat/SourceChip/SourceChip.tsx +19 -5
  133. package/src/book-components/Chat/hooks/useResolvedCitationLabel.ts +65 -0
  134. package/src/book-components/Chat/save/html/htmlSaveFormatDefinition.ts +315 -88
  135. package/src/book-components/Chat/save/react/reactSaveFormatDefinition.ts +7 -1
  136. package/src/book-components/Chat/types/ChatMessage.ts +5 -0
  137. package/src/book-components/Chat/types/ChatParticipant.ts +1 -1
  138. package/src/book-components/Chat/types/CitationLabelResolver.ts +9 -0
  139. package/src/book-components/Chat/utils/citationHelpers.ts +90 -2
  140. package/src/book-components/Chat/utils/createCitationFootnoteRenderModel.ts +3 -0
  141. package/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.ts +178 -0
  142. package/src/book-components/Chat/utils/parseCitationsFromContent.ts +6 -0
  143. package/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.ts +13 -2
  144. package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
  145. package/src/cli/cli-commands/coder/run.ts +17 -20
  146. package/src/cli/cli-commands/coder/server.ts +13 -16
  147. package/src/cli/common/$deprecateCliCommand.ts +10 -1
  148. package/src/commitments/GOAL/GOAL.ts +7 -2
  149. package/src/commitments/LANGUAGE/LANGUAGE.ts +7 -2
  150. package/src/commitments/TEAM/TEAM.ts +12 -1
  151. package/src/commitments/USE_PROJECT/createUseProjectToolFunctions.ts +8 -1
  152. package/src/import-plugins/JsonFileImportPlugin.ts +15 -2
  153. package/src/import-plugins/TextFileImportPlugin.ts +8 -1
  154. package/src/llm-providers/_common/register/$registeredLlmToolsMessage.ts +6 -1
  155. package/src/other/templates/getTemplatesPipelineCollection.ts +681 -837
  156. package/src/utils/chat/chatAttachments/resolveChatAttachmentContent.ts +8 -1
  157. package/src/version.ts +2 -2
  158. package/src/versions.txt +1 -0
  159. package/umd/index.umd.js +1055 -458
  160. package/umd/index.umd.js.map +1 -1
  161. package/umd/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -1
  162. package/umd/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -2
  163. package/umd/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +50 -0
  164. package/umd/scripts/run-codex-prompts/server/buildCoderServerRunState.d.ts +23 -0
  165. package/umd/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
  166. package/umd/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +13 -1
  167. package/umd/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
  168. package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -0
  169. package/umd/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +4 -0
  170. package/umd/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +1 -0
  171. package/umd/src/_packages/components.index.d.ts +2 -0
  172. package/umd/src/_packages/types.index.d.ts +2 -0
  173. package/umd/src/avatars/avatarAnimationScheduler.d.ts +4 -0
  174. package/umd/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
  175. package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
  176. package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
  177. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  178. package/umd/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
  179. package/umd/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
  180. package/umd/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
  181. package/umd/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
  182. package/umd/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
  183. package/umd/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
  184. package/umd/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
  185. package/umd/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
  186. package/umd/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
  187. package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
  188. package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
  189. package/umd/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
  190. package/umd/src/version.d.ts +1 -1
@@ -18,6 +18,7 @@ import { SourceChip } from '../SourceChip/SourceChip';
18
18
  import type { ChatMessage } from '../types/ChatMessage';
19
19
  import type { ChatParticipant } from '../types/ChatParticipant';
20
20
  import { createCitationFootnoteRenderModel } from '../utils/createCitationFootnoteRenderModel';
21
+ import { resolveCitationPreviewUrl } from '../utils/citationHelpers';
21
22
  import { getChatMessageTimingDisplay } from '../utils/getChatMessageTimingDisplay';
22
23
  import type { ParsedCitation } from '../utils/parseCitationsFromContent';
23
24
  import type { MessageButton } from '../utils/parseMessageButtons';
@@ -78,6 +79,10 @@ type ChatMessageItemProps = Pick<
78
79
  * Optional localized labels used by timestamp metadata.
79
80
  */
80
81
  timingTranslations?: ChatProps['timingTranslations'];
82
+ /**
83
+ * Optional resolver for turning technical citation sources into page/document titles.
84
+ */
85
+ resolveCitationLabel?: ChatProps['resolveCitationLabel'];
81
86
  /**
82
87
  * Optional moment locale used to format message timestamps.
83
88
  */
@@ -248,6 +253,7 @@ export const ChatMessageItem = memo(
248
253
  feedbackMode = 'stars',
249
254
  feedbackTranslations,
250
255
  timingTranslations,
256
+ resolveCitationLabel,
251
257
  chatLocale,
252
258
  onCopy,
253
259
  onCreateAgent,
@@ -340,6 +346,14 @@ export const ChatMessageItem = memo(
340
346
  }),
341
347
  [message.citations, sanitizedContentWithoutButtons],
342
348
  );
349
+ const enrichCitationForRendering = useCallback(
350
+ (citation: ParsedCitation): ParsedCitation => {
351
+ const previewUrl = resolveCitationPreviewUrl(citation, participants ?? []);
352
+
353
+ return previewUrl && !citation.url ? { ...citation, url: previewUrl } : citation;
354
+ },
355
+ [participants],
356
+ );
343
357
  const contentSegments = useMemo(
344
358
  () => splitMessageContentIntoSegments(citationFootnoteRenderModel.content),
345
359
  [citationFootnoteRenderModel.content],
@@ -951,8 +965,9 @@ export const ChatMessageItem = memo(
951
965
  >
952
966
  <span className={styles.citationFootnoteNumber}>{footnote.number}</span>
953
967
  <SourceChip
954
- citation={footnote.citation}
968
+ citation={enrichCitationForRendering(footnote.citation)}
955
969
  onClick={onCitationClick}
970
+ resolveCitationLabel={resolveCitationLabel}
956
971
  isCitationIdVisible={false}
957
972
  />
958
973
  </div>
@@ -964,9 +979,10 @@ export const ChatMessageItem = memo(
964
979
  {transitiveCitations.map((citation, index) => (
965
980
  <SourceChip
966
981
  key={`team-source-${citation.source}-${index}`}
967
- citation={citation}
982
+ citation={enrichCitationForRendering(citation)}
968
983
  suffix={`by ${citation.origin.label}`}
969
984
  onClick={onCitationClick}
985
+ resolveCitationLabel={resolveCitationLabel}
970
986
  />
971
987
  ))}
972
988
  </div>
@@ -1178,6 +1194,10 @@ export const ChatMessageItem = memo(
1178
1194
  return false;
1179
1195
  }
1180
1196
 
1197
+ if (prev.resolveCitationLabel !== next.resolveCitationLabel) {
1198
+ return false;
1199
+ }
1200
+
1181
1201
  if (prev.handleRating !== next.handleRating) {
1182
1202
  return false;
1183
1203
  }
@@ -38,6 +38,10 @@ export type ChatMessageListProps = {
38
38
  * Optional localized labels used by timestamp metadata.
39
39
  */
40
40
  timingTranslations?: ChatProps['timingTranslations'];
41
+ /**
42
+ * Optional resolver for turning technical citation sources into page/document titles.
43
+ */
44
+ resolveCitationLabel?: ChatProps['resolveCitationLabel'];
41
45
  /**
42
46
  * Optional moment locale used to format message timestamps.
43
47
  */
@@ -87,6 +91,7 @@ export function ChatMessageList(props: ChatMessageListProps) {
87
91
  feedbackMode,
88
92
  feedbackTranslations,
89
93
  timingTranslations,
94
+ resolveCitationLabel,
90
95
  chatLocale,
91
96
  onCopy,
92
97
  onMessage,
@@ -156,6 +161,7 @@ export function ChatMessageList(props: ChatMessageListProps) {
156
161
  feedbackMode={feedbackMode}
157
162
  feedbackTranslations={feedbackTranslations}
158
163
  timingTranslations={timingTranslations}
164
+ resolveCitationLabel={resolveCitationLabel}
159
165
  chatLocale={chatLocale}
160
166
  onCopy={onCopy}
161
167
  onCreateAgent={onCreateAgent}
@@ -12,6 +12,7 @@ import type { AgentChipData } from '../AgentChip/AgentChip';
12
12
  import type { string_chat_format_name } from '../save/_common/string_chat_format_name';
13
13
  import type { ChatMessage } from '../types/ChatMessage';
14
14
  import type { ChatParticipant } from '../types/ChatParticipant';
15
+ import type { CitationLabelResolver } from '../types/CitationLabelResolver';
15
16
  import type { ChatSaveFormatHandlerMap } from '../save/_common/ChatSaveFormatHandler';
16
17
 
17
18
  /**
@@ -830,6 +831,11 @@ export type ChatProps = {
830
831
  */
831
832
  readonly timingTranslations?: ChatTimingTranslations;
832
833
 
834
+ /**
835
+ * Optional resolver for turning technical citation sources into page/document titles.
836
+ */
837
+ readonly resolveCitationLabel?: CitationLabelResolver;
838
+
833
839
  /**
834
840
  * Optional localized labels for general Chat UI elements such as button labels,
835
841
  * lifecycle state badges, tool call modal strings, and the default input placeholder.
@@ -8,6 +8,7 @@ import { CloseIcon } from '../../icons/CloseIcon';
8
8
  import type { AgentChipData } from '../AgentChip/AgentChip';
9
9
  import type { ChatMessage } from '../types/ChatMessage';
10
10
  import type { ChatParticipant } from '../types/ChatParticipant';
11
+ import type { CitationLabelResolver } from '../types/CitationLabelResolver';
11
12
  import styles from './Chat.module.css';
12
13
  import { ChatToolCallModalContent } from './ChatToolCallModalContent';
13
14
  import { useChatToolCallModalState } from './useChatToolCallModalState';
@@ -29,6 +30,7 @@ export type ChatToolCallModalProps = {
29
30
  toolCallIdentity?: string | null;
30
31
  onClose: () => void;
31
32
  toolTitles?: Record<string, string>;
33
+ resolveCitationLabel?: CitationLabelResolver;
32
34
  agentParticipant?: ChatParticipant;
33
35
  buttonColor: WithTake<Color>;
34
36
  /**
@@ -77,6 +79,7 @@ export function ChatToolCallModal(props: ChatToolCallModalProps) {
77
79
  toolCallIdentity,
78
80
  onClose,
79
81
  toolTitles,
82
+ resolveCitationLabel,
80
83
  agentParticipant,
81
84
  buttonColor,
82
85
  teamAgentProfiles,
@@ -157,6 +160,7 @@ export function ChatToolCallModal(props: ChatToolCallModalProps) {
157
160
  onClearSelectedTeamToolCall={clearSelectedTeamToolCall}
158
161
  teamProfiles={teamProfiles}
159
162
  toolTitles={toolTitles}
163
+ resolveCitationLabel={resolveCitationLabel}
160
164
  agentParticipant={agentParticipant}
161
165
  buttonColor={buttonColor}
162
166
  locale={locale}
@@ -3,6 +3,7 @@ import { Color } from '../../../utils/color/Color';
3
3
  import type { WithTake } from '../../../utils/take/interfaces/ITakeChain';
4
4
  import type { ChatMessage } from '../types/ChatMessage';
5
5
  import type { ChatParticipant } from '../types/ChatParticipant';
6
+ import type { CitationLabelResolver } from '../types/CitationLabelResolver';
6
7
  import type { TeamToolCallSummary, TransitiveToolCall } from '../utils/collectTeamToolCallSummary';
7
8
  import type { AgentProfileData } from '../utils/loadAgentProfile';
8
9
  import type { TeamToolResult } from '../utils/toolCallParsing/TeamToolResult';
@@ -32,6 +33,7 @@ type ChatToolCallModalContentProps = {
32
33
  readonly isAdvancedView: boolean;
33
34
  readonly locale?: string;
34
35
  readonly mode: 'LIGHT' | 'DARK';
36
+ readonly resolveCitationLabel?: CitationLabelResolver;
35
37
  readonly onClearSelectedTeamToolCall: () => void;
36
38
  readonly onRequestAdvancedView: () => void;
37
39
  readonly onSelectTeamToolCall: (toolCall: TransitiveToolCall) => void;
@@ -58,6 +60,7 @@ export function ChatToolCallModalContent({
58
60
  isAdvancedView,
59
61
  locale,
60
62
  mode,
63
+ resolveCitationLabel,
61
64
  onClearSelectedTeamToolCall,
62
65
  onRequestAdvancedView,
63
66
  onSelectTeamToolCall,
@@ -89,6 +92,7 @@ export function ChatToolCallModalContent({
89
92
  onClearSelectedTeamToolCall={onClearSelectedTeamToolCall}
90
93
  teamProfiles={teamProfiles}
91
94
  toolTitles={toolTitles}
95
+ resolveCitationLabel={resolveCitationLabel}
92
96
  agentParticipant={agentParticipant}
93
97
  buttonColor={buttonColor}
94
98
  />
@@ -8,6 +8,7 @@ import { FAST_FLOW } from '../MockedChat/constants';
8
8
  import { MockedChat } from '../MockedChat/MockedChat';
9
9
  import { SourceChip } from '../SourceChip/SourceChip';
10
10
  import type { ChatParticipant } from '../types/ChatParticipant';
11
+ import type { CitationLabelResolver } from '../types/CitationLabelResolver';
11
12
  import type { TeamToolCallSummary, TransitiveToolCall } from '../utils/collectTeamToolCallSummary';
12
13
  import { buildToolCallChipText, getToolCallChipletInfo } from '../utils/getToolCallChipletInfo';
13
14
  import type { AgentProfileData } from '../utils/loadAgentProfile';
@@ -59,6 +60,7 @@ type TeamToolCallModalContentOptions = {
59
60
  onClearSelectedTeamToolCall: () => void;
60
61
  teamProfiles: Record<string, AgentProfileData>;
61
62
  toolTitles?: Record<string, string>;
63
+ resolveCitationLabel?: CitationLabelResolver;
62
64
  agentParticipant?: ChatParticipant;
63
65
  buttonColor: WithTake<Color>;
64
66
  };
@@ -408,8 +410,11 @@ function TeamToolCallActionsGroup(props: {
408
410
  *
409
411
  * @private component of ChatToolCallModal
410
412
  */
411
- function TeamToolCallSourcesGroup(props: { readonly teamCitations: TeamToolCallSummary['citations'] }) {
412
- const { teamCitations } = props;
413
+ function TeamToolCallSourcesGroup(props: {
414
+ readonly teamCitations: TeamToolCallSummary['citations'];
415
+ readonly resolveCitationLabel?: CitationLabelResolver;
416
+ }) {
417
+ const { teamCitations, resolveCitationLabel } = props;
413
418
 
414
419
  if (teamCitations.length === 0) {
415
420
  return null;
@@ -424,6 +429,7 @@ function TeamToolCallSourcesGroup(props: { readonly teamCitations: TeamToolCallS
424
429
  key={`team-source-${citation.source}-${index}`}
425
430
  citation={citation}
426
431
  suffix={`by ${citation.origin.label}`}
432
+ resolveCitationLabel={resolveCitationLabel}
427
433
  />
428
434
  ))}
429
435
  </div>
@@ -483,6 +489,7 @@ function TeamToolCallSummarySection(props: {
483
489
  readonly selectedTeamToolCall: TransitiveToolCall | null;
484
490
  readonly teamToolCallSummary: TeamToolCallSummary;
485
491
  readonly toolTitles?: Record<string, string>;
492
+ readonly resolveCitationLabel?: CitationLabelResolver;
486
493
  }) {
487
494
  const {
488
495
  agentParticipant,
@@ -492,6 +499,7 @@ function TeamToolCallSummarySection(props: {
492
499
  selectedTeamToolCall,
493
500
  teamToolCallSummary,
494
501
  toolTitles,
502
+ resolveCitationLabel,
495
503
  } = props;
496
504
  const hasSummaryContent = teamToolCallSummary.toolCalls.length > 0 || teamToolCallSummary.citations.length > 0;
497
505
 
@@ -506,7 +514,10 @@ function TeamToolCallSummarySection(props: {
506
514
  onSelectTeamToolCall={onSelectTeamToolCall}
507
515
  toolTitles={toolTitles}
508
516
  />
509
- <TeamToolCallSourcesGroup teamCitations={teamToolCallSummary.citations} />
517
+ <TeamToolCallSourcesGroup
518
+ teamCitations={teamToolCallSummary.citations}
519
+ resolveCitationLabel={resolveCitationLabel}
520
+ />
510
521
  <TeamToolCallDetailsPanel
511
522
  selectedTeamToolCall={selectedTeamToolCall}
512
523
  onClearSelectedTeamToolCall={onClearSelectedTeamToolCall}
@@ -533,6 +544,7 @@ export function TeamToolCallModalContent(options: TeamToolCallModalContentOption
533
544
  onClearSelectedTeamToolCall,
534
545
  teamProfiles,
535
546
  toolTitles,
547
+ resolveCitationLabel,
536
548
  agentParticipant,
537
549
  buttonColor,
538
550
  } = options;
@@ -561,6 +573,7 @@ export function TeamToolCallModalContent(options: TeamToolCallModalContentOption
561
573
  onSelectTeamToolCall={onSelectTeamToolCall}
562
574
  onClearSelectedTeamToolCall={onClearSelectedTeamToolCall}
563
575
  toolTitles={toolTitles}
576
+ resolveCitationLabel={resolveCitationLabel}
564
577
  agentParticipant={agentParticipant}
565
578
  buttonColor={buttonColor}
566
579
  />
@@ -4,6 +4,7 @@ import { useMemo } from 'react';
4
4
  import { humanizeAiText } from '../../../utils/markdown/humanizeAiText';
5
5
  import { promptbookifyAiText } from '../../../utils/markdown/promptbookifyAiText';
6
6
  import type { ChatMessage } from '../types/ChatMessage';
7
+ import { decodeJsonUnicodeEscapesInMarkdownText } from '../utils/decodeJsonUnicodeEscapesInMarkdownText';
7
8
  import { extractCitationsFromMessage } from '../utils/parseCitationsFromContent';
8
9
 
9
10
  /**
@@ -29,17 +30,27 @@ function postprocessChatMessage(message: ChatMessage): ChatMessage {
29
30
  const normalizedReplyingTo = messageWithCitations.replyingTo
30
31
  ? {
31
32
  ...messageWithCitations.replyingTo,
32
- content: promptbookifyAiText(humanizeAiText(messageWithCitations.replyingTo.content)),
33
+ content: postprocessChatMessageContent(messageWithCitations.replyingTo.content),
33
34
  }
34
35
  : undefined;
35
36
 
36
37
  return {
37
38
  ...messageWithCitations,
38
- content: promptbookifyAiText(humanizeAiText(messageWithCitations.content)),
39
+ content: postprocessChatMessageContent(messageWithCitations.content),
39
40
  ...(normalizedReplyingTo ? { replyingTo: normalizedReplyingTo } : {}),
40
41
  };
41
42
  }
42
43
 
44
+ /**
45
+ * Applies markdown-safe text normalization to one chat message content value.
46
+ *
47
+ * @private utility of `useChatPostprocessedMessages`
48
+ */
49
+ function postprocessChatMessageContent(content: ChatMessage['content']): ChatMessage['content'] {
50
+ const decodedContent = decodeJsonUnicodeEscapesInMarkdownText(content);
51
+ return promptbookifyAiText(humanizeAiText(decodedContent));
52
+ }
53
+
43
54
  /**
44
55
  * Memoizes the render-only message normalization used by `<Chat/>`.
45
56
  *
@@ -2,6 +2,7 @@
2
2
  display: inline-flex;
3
3
  align-items: center;
4
4
  gap: 6px;
5
+ max-width: min(100%, 32rem);
5
6
  font-size: 0.8rem;
6
7
  font-weight: 600;
7
8
  padding: 5px 11px;
@@ -36,6 +37,13 @@
36
37
  display: flex;
37
38
  align-items: center;
38
39
  gap: 5px;
40
+ min-width: 0;
41
+ }
42
+
43
+ .labelText {
44
+ min-width: 0;
45
+ overflow: hidden;
46
+ text-overflow: ellipsis;
39
47
  }
40
48
 
41
49
  .citationId {
@@ -1,6 +1,8 @@
1
1
  'use client';
2
2
 
3
- import { getCitationLabel, isCitationUrl, isPlainTextCitation } from '../utils/citationHelpers';
3
+ import { useResolvedCitationLabel } from '../hooks/useResolvedCitationLabel';
4
+ import type { CitationLabelResolver } from '../types/CitationLabelResolver';
5
+ import { isCitationUrl, isPlainTextCitation } from '../utils/citationHelpers';
4
6
  import type { ParsedCitation } from '../utils/parseCitationsFromContent';
5
7
  import styles from './SourceChip.module.css';
6
8
 
@@ -26,6 +28,10 @@ export type SourceChipProps = {
26
28
  * Optional suffix text to display after the citation label.
27
29
  */
28
30
  suffix?: string;
31
+ /**
32
+ * Optional resolver for richer citation labels.
33
+ */
34
+ resolveCitationLabel?: CitationLabelResolver;
29
35
  /**
30
36
  * Controls whether the technical citation id is shown inside the chip label.
31
37
  */
@@ -49,7 +55,14 @@ export type SourceChipProps = {
49
55
  *
50
56
  * @private utility of `ChatMessageItem` component
51
57
  */
52
- export function SourceChip({ citation, onClick, className, suffix, isCitationIdVisible = true }: SourceChipProps) {
58
+ export function SourceChip({
59
+ citation,
60
+ onClick,
61
+ className,
62
+ suffix,
63
+ resolveCitationLabel,
64
+ isCitationIdVisible = true,
65
+ }: SourceChipProps) {
53
66
  const handleClick = (event: React.MouseEvent) => {
54
67
  event.stopPropagation();
55
68
  if (onClick) {
@@ -59,7 +72,8 @@ export function SourceChip({ citation, onClick, className, suffix, isCitationIdV
59
72
 
60
73
  // Keep source chips concise and human-readable for CDN-backed knowledge files.
61
74
  const normalizedSource = citation.source.trim();
62
- const displayName = getCitationLabel(citation);
75
+ const displayName = useResolvedCitationLabel(citation, resolveCitationLabel);
76
+ const title = displayName === citation.source ? citation.source : `${displayName}\n${citation.source}`;
63
77
 
64
78
  // Get file extension for icon
65
79
  const fileExtension = (normalizedSource || citation.source).split('.').pop()?.toLowerCase() || 'file';
@@ -70,10 +84,10 @@ export function SourceChip({ citation, onClick, className, suffix, isCitationIdV
70
84
  : getFileIcon(fileExtension);
71
85
 
72
86
  return (
73
- <button className={`${styles.sourceChip} ${className || ''}`} onClick={handleClick} title={citation.source}>
87
+ <button className={`${styles.sourceChip} ${className || ''}`} onClick={handleClick} title={title}>
74
88
  <span className={styles.icon}>{icon}</span>
75
89
  <span className={styles.label}>
76
- {displayName}
90
+ <span className={styles.labelText}>{displayName}</span>
77
91
  {isCitationIdVisible && <span className={styles.citationId}> [{citation.id}]</span>}
78
92
  </span>
79
93
  {suffix && <span className={styles.suffix}>{suffix}</span>}
@@ -0,0 +1,65 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useMemo, useState } from 'react';
4
+ import type { CitationLabelResolver } from '../types/CitationLabelResolver';
5
+ import { getCitationLabel } from '../utils/citationHelpers';
6
+ import type { ParsedCitation } from '../utils/parseCitationsFromContent';
7
+
8
+ /**
9
+ * Creates a stable key for one citation label lookup.
10
+ *
11
+ * @param citation - Citation metadata.
12
+ * @returns Stable citation key.
13
+ *
14
+ * @private hook helper of `<Chat/>`
15
+ */
16
+ function createCitationLabelLookupKey(citation: ParsedCitation): string {
17
+ return [citation.id, citation.source, citation.url || '', citation.title || '', citation.excerpt || ''].join('\n');
18
+ }
19
+
20
+ /**
21
+ * Resolves the best available label for one citation.
22
+ *
23
+ * @param citation - Citation metadata.
24
+ * @param resolveCitationLabel - Optional async host resolver.
25
+ * @returns Current label, starting with a synchronous fallback and updating when the resolver finishes.
26
+ *
27
+ * @private hook of `<Chat/>`
28
+ */
29
+ export function useResolvedCitationLabel(
30
+ citation: ParsedCitation,
31
+ resolveCitationLabel?: CitationLabelResolver,
32
+ ): string {
33
+ const fallbackLabel = useMemo(() => getCitationLabel(citation), [citation]);
34
+ const citationKey = useMemo(() => createCitationLabelLookupKey(citation), [citation]);
35
+ const [resolvedLabel, setResolvedLabel] = useState<string | null>(null);
36
+
37
+ useEffect(() => {
38
+ setResolvedLabel(null);
39
+
40
+ if (!resolveCitationLabel) {
41
+ return;
42
+ }
43
+
44
+ let isCurrent = true;
45
+
46
+ Promise.resolve(resolveCitationLabel(citation))
47
+ .then((label) => {
48
+ if (!isCurrent) {
49
+ return;
50
+ }
51
+
52
+ const normalizedLabel = label?.trim();
53
+ if (normalizedLabel) {
54
+ setResolvedLabel(normalizedLabel);
55
+ }
56
+ })
57
+ .catch(() => undefined);
58
+
59
+ return () => {
60
+ isCurrent = false;
61
+ };
62
+ }, [citation, citationKey, resolveCitationLabel]);
63
+
64
+ return resolvedLabel || fallbackLabel;
65
+ }