{"version":3,"file":"sinequa-components-machine-learning.mjs","sources":["../../../projects/components/machine-learning/answer-card.component.ts","../../../projects/components/machine-learning/answer-card.component.html","../../../projects/components/machine-learning/passage-list.component.ts","../../../projects/components/machine-learning/top-passages/top-passages.component.ts","../../../projects/components/machine-learning/top-passages/top-passages.component.html","../../../projects/components/machine-learning/chat/chunk.ts","../../../projects/components/machine-learning/chat/chat.service.ts","../../../projects/components/machine-learning/chat/chat-message.component.ts","../../../projects/components/machine-learning/chat/chat-message.component.html","../../../projects/components/machine-learning/chat/chat.component.ts","../../../projects/components/machine-learning/chat/chat.component.html","../../../projects/components/machine-learning/chat/chat-settings.component.ts","../../../projects/components/machine-learning/chat/chat-settings.component.html","../../../projects/components/machine-learning/chat/saved-chats.component.ts","../../../projects/components/machine-learning/machine-learning.module.ts","../../../projects/components/machine-learning/similar-documents/similar-documents.component.ts","../../../projects/components/machine-learning/messages/en.ts","../../../projects/components/machine-learning/messages/fr.ts","../../../projects/components/machine-learning/messages/de.ts","../../../projects/components/machine-learning/messages/index.ts","../../../projects/components/machine-learning/sinequa-components-machine-learning.ts"],"sourcesContent":["import { Observable, map, of } from \"rxjs\";\n\nimport { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from \"@angular/core\";\n\nimport { AbstractFacet } from '@sinequa/components/facet';\nimport { SearchService } from \"@sinequa/components/search\";\nimport { AppService } from \"@sinequa/core/app-utils\";\nimport { NotificationsService } from \"@sinequa/core/notification\";\nimport { Answer, AuditEvent, AuditEventType, AuditWebService, Results } from \"@sinequa/core/web-services\";\nimport { AuditEventTypeValues } from \"@sinequa/core/web-services/types/audit/AuditEventType\";\n\n@Component({\n    selector: 'sq-answer-card',\n    templateUrl: 'answer-card.component.html',\n    styles: [`\n.card-body {\n  cursor: pointer;\n}\n\n.card-body:hover {\n  background-color: rgb(0,0,0,0.03);\n}\n\n.passage-text {\n  font-size: 0.875em;\n}\n  `],\n    standalone: false\n})\nexport class AnswerCardComponent extends AbstractFacet implements OnChanges {\n  @Input() results: Results;\n  @Input() collapsed: boolean;\n  @Input() showLikeButtons: boolean;\n  @Input() hideDate: boolean = false;\n  @Input() dateFormat: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' };\n  @Output() previewOpened = new EventEmitter<Answer>();\n  @Output() titleClicked = new EventEmitter<{ item: Answer, isLink: boolean }>();\n  selectedAnswer: number;\n\n  answer$: Observable<Answer>;\n\n  get answers(): Answer[] {\n    return this.results?.answers?.answers || [];\n  }\n\n  constructor(\n    public searchService: SearchService,\n    public appService: AppService,\n    public auditService: AuditWebService,\n    public notificationsService: NotificationsService\n  ) {\n    super();\n  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    this.selectedAnswer = 0;\n    this.setAnswer();\n    const answers = changes.results?.currentValue?.answers?.answers;\n    if (answers?.length) {\n      this.notifyAnswerResult(answers);\n    }\n  }\n\n  openPreview(answer: Answer) {\n    this.notifyAnswer(AuditEventType.Answer_Click, answer);\n    this.previewOpened.next(answer);\n  }\n\n  onTitleClicked(isLink: boolean, answer: Answer) {\n    this.notifyAnswer(AuditEventType.Answer_Click, answer);\n    this.titleClicked.next({ item: answer, isLink });\n  }\n\n  previous() {\n    this.selectedAnswer = (this.selectedAnswer + this.answers.length - 1) % this.answers.length;\n    this.setAnswer();\n  }\n\n  next() {\n    this.selectedAnswer = (this.selectedAnswer + 1) % this.answers.length;\n    this.setAnswer();\n  }\n\n  setAnswer() {\n    const answer = this.answers[this.selectedAnswer];\n    if (!!answer) {\n      this.notifyAnswer(AuditEventType.Answer_Display, answer);\n      if (!!answer.$record) {\n        this.answer$ = of(answer);\n      } else {\n        // Get the missing record\n        this.answer$ = this.searchService.getRecords([answer.recordId]).pipe(map(records => {\n          answer.$record = records[0];\n          return answer;\n        }));\n      }\n    }\n  }\n\n  likeAnswer(answer: Answer) {\n    this.setLiked(answer, true);\n  }\n\n  dislikeAnswer(answer: Answer) {\n    this.setLiked(answer, false);\n  }\n\n  private setLiked(answer: Answer, liked: boolean) {\n    const type = liked ? AuditEventType.Answer_Liked : AuditEventType.Answer_Disliked;\n    if (answer.$liked === liked) {\n      answer.$liked = undefined;\n      this.auditService.notify(this.makeAuditEvent(`${type}_Cancelled`, answer));\n    }\n    else {\n      answer.$liked = liked;\n      this.auditService.notify(this.makeAuditEvent(type, answer))\n        .subscribe(() => this.notificationsService.success(\"Thank you for your feedback!\"));\n    }\n  }\n\n  private notifyAnswer(type: AuditEventType, answer: Answer) {\n    const auditEvent: AuditEvent = this.makeAuditEvent(type, answer);\n    this.auditService.notify(auditEvent);\n  }\n\n  private notifyAnswerResult(answers: Answer[]) {\n    const auditEvents: AuditEvent[] = answers\n      .map((answer: Answer) => this.makeAuditEvent(AuditEventType.Answer_Result, answer));\n    this.auditService.notify(auditEvents);\n  }\n\n  private makeAuditEvent(type: AuditEventType | AuditEventTypeValues, answer: Answer): AuditEvent {\n    const rank = this.answers.indexOf(answer);\n    return {\n      type,\n      detail: {\n        querytext: this.searchService.query.text,\n        answertext: answer.text,\n        recordid: answer.recordId,\n        passageid: answer.passage.id,\n        afscore: answer[\"af.score\"],\n        rmscore: answer[\"rm.score\"],\n        rank\n      }\n    };\n  }\n}\n","<ng-template #headerTpl>\n    <div class=\"d-flex flex-grow-1 align-items-center text-truncate\">\n        <div class=\"card-icon primary-icon fas fa-brain me-2\" aria-hidden=\"true\"></div>\n        <div class=\"card-title text-truncate mb-0 py-1 me-auto\">\n            <span *ngIf=\"collapsed\">\n                {{'msg#machine-learning.answersCollapsed' | sqMessage:{values: {answersNb: answers.length} } }}\n            </span>\n            <span *ngIf=\"!collapsed\">\n                {{'msg#machine-learning.answers' | sqMessage }}\n            </span>\n        </div>\n        <div class=\"card-action d-flex justify-content-center align-items-center mx-2\" *ngIf=\"!collapsed\">\n            <button class=\"btn btn-sm btn-link\" (click)=\"previous()\" *ngIf=\"answers.length > 1\">\n                <i class=\"fas fa-chevron-left\"></i>\n            </button>\n            {{'msg#machine-learning.answer' | sqMessage }} {{selectedAnswer+1}}/{{answers.length}}\n            <button class=\"btn btn-sm btn-link\" (click)=\"next()\" *ngIf=\"answers.length > 1\">\n                <i class=\"fas fa-chevron-right\"></i>\n            </button>\n        </div>\n    </div>\n</ng-template>\n\n<div class=\"card-body\" (click)=\"openPreview(answer)\" *ngIf=\"answer$ | async as answer\">\n    <div class=\"fw-bold\">\n        {{answer.text}}\n        <div *ngIf=\"showLikeButtons\" class=\"float-end\">\n            <button class=\"btn btn-link\" (click)=\"$event.stopPropagation; likeAnswer(answer)\"\n                sqTooltip=\"This answer is helpful\">\n                <i class=\"far fa-thumbs-up\" [ngClass]=\"{fas: answer.$liked}\"></i>\n            </button>\n            <button class=\"btn btn-link\" (click)=\"$event.stopPropagation; dislikeAnswer(answer)\"\n                sqTooltip=\"This answer is wrong\">\n                <i class=\"far fa-thumbs-down\" [ngClass]=\"{fas: answer.$liked === false}\"></i>\n            </button>\n        </div>\n    </div>\n    <div class=\"my-3 passage-text\">\n        <span *ngIf=\"answer.$record?.modified && !hideDate\" class=\"extracts-date\">{{answer.$record.modified | sqDate:dateFormat }} - </span>\n        <span [innerHTML]=\"answer.passage?.highlightedText\"></span>\n    </div>\n    <ng-container *ngIf=\"answer.$record as record\">\n        <sq-result-title [record]=\"record\" titleLinkBehavior=\"action\" (titleClicked)=\"onTitleClicked($event, answer)\"\n            class=\"d-block text-truncate\"></sq-result-title>\n        <sq-result-source [record]=\"record\" [displayTreepath]=\"true\" (click)=\"$event.stopPropagation();\">\n        </sq-result-source>\n    </ng-container>\n</div>","import { Component, Input, OnChanges, SimpleChanges } from \"@angular/core\";\nimport { MatchingPassage, Record } from \"@sinequa/core/web-services\";\n\n@Component({\n    selector: 'sq-passage-list',\n    template: `\n<ol class=\"list-group list-group-flush\" *ngIf=\"record.matchingpassages?.passages?.length\">\n  <li class=\"list-group-item list-group-item-action sq-passage\" #list [id]=\"'li-'+index\" [ngClass]=\"{expanded: passage.$expanded}\"\n      *ngFor=\"let passage of record.matchingpassages?.passages|slice:0:maxPassages; let index = index\"\n      (click)=\"expand(passage)\">\n      <div class=\"sq-passage-icon\"></div>\n      <div class=\"sq-passage-text\">\n        <span [innerHTML]=\"passage.highlightedText || passage.text\"></span>\n      </div>\n  </li>\n</ol>\n  `,\n    styleUrls: ['passage-list.component.scss'],\n    standalone: false\n})\nexport class PassageListComponent implements OnChanges {\n\n  @Input() record: Record;\n  @Input() maxPassages?: number;\n  @Input() passageId?: string;\n\n  ngOnChanges(changes: SimpleChanges): void {\n    const passages = this.record.matchingpassages?.passages;\n    // invalidate all $expanded property except for the first passage\n    passages?.forEach((p, index) => p.$expanded = this.passageId\n      ? p.id === Number(this.passageId) : index === 0);\n  }\n\n  expand(passage: MatchingPassage) {\n    // Do not expand if there is a selection\n    const selection = window.getSelection();\n    if(selection && selection.toString().length > 0) {\n      return;\n    }\n\n    const state = !passage.$expanded;\n    this.record.matchingpassages?.passages.forEach(p => p.$expanded = false);\n    passage.$expanded = state;\n  }\n}","import { delay } from \"rxjs\";\r\n\r\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output } from \"@angular/core\";\r\n\r\nimport { AbstractFacet } from '@sinequa/components/facet';\r\nimport { SearchService } from \"@sinequa/components/search\";\r\nimport { AuditEvent, AuditEventType, AuditWebService, Record, Results, TopPassage } from \"@sinequa/core/web-services\";\r\n\r\n@Component({\n    selector: 'sq-top-passages',\n    templateUrl: 'top-passages.component.html',\n    styleUrls: ['./top-passages.component.scss'],\n    changeDetection: ChangeDetectionStrategy.OnPush,\n    standalone: false\n})\r\nexport class TopPassagesComponent extends AbstractFacet implements OnChanges {\r\n  @Input() results: Results;\r\n  @Input() hideDate: boolean = false;\r\n  @Input() dateFormat: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' };\r\n\r\n  @Output() passageClicked = new EventEmitter<TopPassage>();\r\n  @Output() documentOpened = new EventEmitter<Record>();\r\n\r\n  passages?: TopPassage[];\r\n  documentsNb: number;\r\n\r\n  constructor(\r\n    private auditService: AuditWebService,\r\n    private searchService: SearchService,\r\n    public cdRef: ChangeDetectorRef\r\n  ) {\r\n    super();\r\n  }\r\n\r\n  ngOnChanges(): void {\r\n    this.documentsNb = 0;\r\n    this.passages = undefined;\r\n    if(this.results.topPassages?.passages?.length) {\r\n      this.fetchPassagesRecords(this.results.topPassages.passages);\r\n    }\r\n  }\r\n\r\n  fetchPassagesRecords(passages: TopPassage[]): void {\r\n    const ids = passages.filter(p => !p.$record).map(p => p.recordId);\r\n    this.searchService.getRecords(ids)\r\n      .pipe(delay(0)) // Force async refresh of the view to scroll to the top\r\n      .subscribe((records) => {\r\n        // Post process passages\r\n        this.passages = passages\r\n          // Fill missing records\r\n          .map(p => ({...p, $record: p.$record || records.find(record => record?.id === p.recordId)}))\r\n          // Remove records that cannot be retrieved\r\n          .filter(p => p.$record)\r\n          // Put answers first\r\n          .sort((a, b) => (b.answerScore ? (b.answerScore + 100) : b.score)\r\n                        - (a.answerScore ? (a.answerScore + 100) : a.score));\r\n\r\n        this.notifyTopPassagesDisplay(this.passages);\r\n\r\n        // Set the numbers of unique documents\r\n        const uniqueRecords = [...new Set(this.passages.map(p => p.recordId))];\r\n        this.documentsNb = uniqueRecords.length;\r\n\r\n        this.cdRef.detectChanges();\r\n      });\r\n  }\r\n\r\n  // Open the mini preview on text click\r\n  openPreview(passage: TopPassage) {\r\n    this.notifyTopPassagesClick(passage);\r\n    this.passageClicked.emit(passage);\r\n  }\r\n\r\n  // Open the big preview on title click\r\n  onTitleClicked(isLink: boolean, passage: TopPassage) {\r\n    this.notifyTopPassagesClick(passage);\r\n    // If isLink === true, then we are navigating outside the app\r\n    if(!isLink && passage.$record) {\r\n      this.documentOpened.emit(passage.$record);\r\n    }\r\n  }\r\n\r\n  private notifyTopPassagesClick(passage: TopPassage) {\r\n    const auditEvent: AuditEvent = this.makeAuditEvent(AuditEventType.TopPassages_Click, passage);\r\n    this.auditService.notify(auditEvent);\r\n  }\r\n\r\n  private notifyTopPassagesDisplay(passages: TopPassage[]) {\r\n    const auditEvents: AuditEvent[] = passages\r\n      .map((passage: TopPassage) => this.makeAuditEvent(AuditEventType.TopPassages_Display, passage));\r\n    this.auditService.notify(auditEvents);\r\n  }\r\n\r\n  private makeAuditEvent(type: string, passage: TopPassage): AuditEvent {\r\n    const rank = this.passages?.indexOf(passage);\r\n    const answer = !!passage.answer;\r\n    return {\r\n      type,\r\n      detail: {\r\n        querytext: this.searchService.query.text,\r\n        recordid: passage.recordId,\r\n        passageid: passage.id,\r\n        score: passage.score,\r\n        rank,\r\n        answer\r\n      }\r\n    };\r\n  }\r\n\r\n  public override isHidden(): boolean {\r\n    return !this.passages?.length;\r\n  }\r\n}\r\n","\r\n<div *ngIf=\"passages && documentsNb\" class=\"text-end text-muted px-3 py-2\">{{'msg#machine-learning.passagesFound' |\r\n  sqMessage:{passagesNb: passages.length, documentsNb: documentsNb} }}\r\n</div>\r\n\r\n<ul class=\"list-group list-group-flush\" *ngIf=\"passages\">\r\n\r\n  <li role=\"button\" *ngFor=\"let passage of passages\" (click)=\"openPreview(passage)\" class=\"list-group-item list-group-item-action sq-passage\">\r\n\r\n    <div class=\"sq-passage-title d-flex align-content-center mb-1\">\r\n      <sq-result-title\r\n        [record]=\"passage.$record\"\r\n        (titleClicked)=\"onTitleClicked($event, passage)\"\r\n        (click)=\"$event.stopPropagation()\"\r\n        class=\"d-block text-truncate\">\r\n      </sq-result-title>\r\n    </div>\r\n\r\n    <div class=\"sq-passage-text\">\r\n      <span *ngIf=\"passage.$record?.modified && !hideDate\" class=\"extracts-date\">\r\n        {{passage.$record.modified | sqDate:dateFormat }} -\r\n      </span>\r\n      <span [innerHTML]=\"passage.highlightedText\"></span>\r\n    </div>\r\n\r\n  </li>\r\n\r\n</ul>\r\n","\nexport interface Chunk {offset: number, length: number};\n\n/**\n * This function takes a list of ordered \"chunks\" (segment positioned at certain \"offset\" and with\n * a certain \"length\") and inserts a new chunk in this list.\n * It takes care of inserting the chunk at the right location, and to merge it (if needed) with other\n * existing chunks (such that all chunks are always ordered and without overlap between them,\n * as long as all the chunks have been inserted using this method).\n * A \"margin\" parameter prevents small gaps between chunks, such that, if margin is 10, and a new chunk\n * is inserted within less that 10 positions of an existing chunk, then the 2 will be merged directly.\n */\nexport function insertChunk(chunks: Chunk[], offset: number, length: number, margin = 0) {\n  let end = offset + length;\n\n  let spliceStart = chunks.length;\n  let spliceLength = 0;\n\n  for(let i=0; i<chunks.length; i++) {\n    const chunk = chunks[i];\n    const chunkOffset = chunk.offset;\n    const chunkEnd = chunkOffset + chunk.length;\n\n    // Detect the starting point\n    if(i < spliceStart) {\n      // Chunk includes the begining of segment\n      if(chunkOffset - margin <= offset && chunkEnd + margin >= offset) {\n        spliceStart = i; // Insert new chunk here\n        offset = Math.min(chunkOffset, offset); // Update the offset/length to \"merge\" with the chunk\n        length = end - offset;\n      }\n      // Chunk is after the begining of the segment\n      else if (chunkOffset > offset) {\n        spliceStart = i;\n      }\n    }\n\n    // Detect the ending point\n    if(i >= spliceStart) {\n      // Chunk is included in the segment\n      if(chunkEnd < end) {\n        spliceLength++;\n      }\n      // Chunk includes the end of segment\n      else if(chunkOffset - margin <= end && chunkEnd + margin >= end) {\n        spliceLength++; // Delete at least this first chunk\n        end = Math.max(chunkEnd, end);\n        length = end - offset;\n        break;\n      }\n      // Chunk is after the end of the segment\n      else if (chunkOffset > end) {\n        break; // All the chunks after this one won't be changed\n      }\n    }\n\n  }\n\n  chunks.splice(spliceStart, spliceLength, {offset, length});\n}\n\nexport function equalChunks(a: Chunk[], b: Chunk[]) {\n  if(a.length !== b.length) {\n    return false;\n  }\n  for(let i=0; i<a.length; i++) {\n    if(a[i].offset !== b[i].offset || a[i].length !== b[i].length) {\n      return false;\n    }\n  }\n  return true;\n}\n","import { HttpDownloadProgressEvent, HttpEvent, HttpEventType } from \"@angular/common/http\";\nimport { Injectable } from \"@angular/core\";\nimport { Validators } from \"@angular/forms\";\nimport { SearchService } from \"@sinequa/components/search\";\nimport { UserPreferences } from \"@sinequa/components/user-settings\";\nimport { LoginService } from \"@sinequa/core/login\";\nimport { ModalResult, ModalService, PromptOptions } from \"@sinequa/core/modal\";\nimport { NotificationsService } from \"@sinequa/core/notification\";\nimport { AuditEvent, AuditWebService, JsonMethodPluginService, Record, RelevantExtract, Results, TextChunksWebService, TopPassage, UserSettingsWebService } from \"@sinequa/core/web-services\";\nimport { BehaviorSubject, Observable, Subject, defaultIfEmpty, filter, finalize, forkJoin, map, of, scan, switchMap, tap } from \"rxjs\";\nimport { Chunk, equalChunks, insertChunk } from \"./chunk\";\nimport { ChatAttachment, ChatAttachmentWithTokens, ChatMessage, ChatResponse, DocumentChunk, GllmModel, GllmModelDescription, GllmTokenQuota, GllmTokens, RawMessage, RawResponse, SavedChat } from \"./types\";\n\nexport interface SearchAttachmentsOptions {\n  /** Max number of top passages to include */\n  maxTopPassages: number;\n  /** Minimum score a top passage should have to be included */\n  minScoreTopPassage: number;\n  /** Max number of documents to include */\n  maxDocuments: number;\n  /** Minimum global relevance that a document should have to be included */\n  minDocumentRelevance: number;\n  /** Max number of relevant extracts to include for one document */\n  maxExtractsPerDocument: number;\n  /** Max number of matching passages to include for one document */\n  maxPassagesPerDocument: number;\n  /** Length of the document to include from offset 0 (not tied to a specific snippet, just the beginning of the document) */\n  startLengthPerDocument: number;\n  /** Number of sentences to extend before each snippet */\n  extendBefore: number;\n  /** Number of sentences to extend after each snippet */\n  extendAfter: number;\n}\n\nexport const defaultSearchAttachmentsOptions: SearchAttachmentsOptions = {\n  maxTopPassages: 5,\n  minScoreTopPassage: 0.5,\n  maxDocuments: 2,\n  minDocumentRelevance: 0,\n  maxExtractsPerDocument: 2,\n  maxPassagesPerDocument: 2,\n  startLengthPerDocument: 500,\n  extendBefore: 1,\n  extendAfter: 2\n}\n\n@Injectable({providedIn: 'root'})\nexport class ChatService {\n\n  /** When 2 passages in a document are within this number of characters, we merge them */\n  chunkMargin = 100;\n\n  /**\n   * Global list of attachments fed by various methods from the ChatService,\n   * such as: searchAttachments, addAttachments, removeAttachment...\n   */\n  attachments$ = new BehaviorSubject<ChatAttachmentWithTokens[]>([]);\n\n  /** LLM used for computing the number of tokens in text */\n  attachmentModel: GllmModel = 'GPT35Turbo';\n\n  /** Name of the GLLM plugin */\n  GLLM_PLUGIN = \"GLLM\";\n\n  /** Metadata possibly included in the attachments */\n  availableAttachmentMetadata: { field: string, name?: string, formatter?: (value: any) => string}[] = [\n    {field: \"title\"},\n    {field: \"modified\", name: \"date\", formatter: (value: string) => value.substring(0,10)},\n    {field: \"treepath\", name: \"source\", formatter: (value: string[]) => value[0].split('/').find(v => v) ?? ''},\n    {field: \"authors\", formatter: (value: string[]) => value.join(',')},\n    {field: \"language\", formatter: (value: string[]) => value.join(',')},\n    {field: \"docformat\", name: \"format\"},\n    {field: \"filename\"}\n  ];\n  defaultAttachmentMetadata = ['title', 'modified'];\n\n  initialized$ = new BehaviorSubject<boolean>(false);\n  models?: GllmModelDescription[];\n  quota?: GllmTokenQuota;\n  quotaPercentage = 0;\n\n  constructor(\n    public textChunksService: TextChunksWebService,\n    public jsonMethodWebService: JsonMethodPluginService,\n    public searchService: SearchService,\n    public userSettingsService: UserSettingsWebService,\n    public modalService: ModalService,\n    public notificationsService: NotificationsService,\n    public auditService: AuditWebService,\n    public prefs: UserPreferences,\n    public loginService: LoginService\n  ) {\n    // Upon login, get the list of models and current quota\n    this.loginService.events.pipe(\n      filter(e => e.type === 'login-complete'),\n      switchMap(() => forkJoin([\n        this.listModels(),\n        this.getQuota()\n      ]))\n    ).subscribe(() => this.initialized$.next(true));\n  }\n\n\n  // ChatGPT API\n\n  /**\n   * Calls the ChatGPT API to retrieve a new message given all previous messages\n   */\n  fetch(messages: ChatMessage[], name: GllmModel, temperature: number, generateTokens: number, topP: number, context?: string, stream = false): Observable<ChatResponse> {\n\n    // Prepare inputs\n    const model = {\n      name,\n      temperature,\n      generateTokens,\n      topP,\n      context\n    };\n    const messagesHistory = this.cleanMessages(messages, true);\n    const data = {action: \"chat\", model, messagesHistory, promptProtection: false};\n\n    // Stream mode\n    if(stream && this.models?.find(m => m.name === name)?.eventStream) {\n      let _res: ChatResponse;\n      return this.fetchStream(data).pipe(\n        map(res => this.processResponse(messages, res)),\n        tap(res => _res = res), // Store the last version of the message so we can audit it in finalize()\"\"\n        finalize(() => {\n          if(_res) {\n            this.notifyAudit(_res.messagesHistory, model.name, _res.tokens);\n          }\n        })\n      );\n    }\n\n    // Regular mode\n    return this.fetchAll(data).pipe(\n      map(res => this.processResponse(messages, res)),\n      tap(({tokens, messagesHistory}) => this.notifyAudit(messagesHistory, model.name, tokens))\n    );\n  }\n\n  fetchAll(data: any): Observable<RawResponse> {\n    return this.jsonMethodWebService.post(this.GLLM_PLUGIN, data);\n  }\n\n  fetchStream(data: any): Observable<RawResponse> {\n    data.stream = true;\n    let msgCount = 0;\n    return this.jsonMethodWebService.post(this.GLLM_PLUGIN, data, {observe: 'events', responseType: 'text', reportProgress: true}).pipe(\n      // Only keep download progress events\n      filter((data: HttpEvent<string>): data is HttpDownloadProgressEvent => data.type === HttpEventType.DownloadProgress),\n\n      // Retrieve and parse the last event of the stream\n      map(data => {\n        const messages = data.partialText!\n          .trim()\n          .split('\\n\\n')\n          .slice(msgCount)\n          .map(text => text.substring('data: '.length))\n          .map(text => JSON.parse(text) as {content: string, tokens: number, stop?: boolean});\n        msgCount += messages.length;\n        return messages.reduceRight((acc, json) => ({...acc, content: json.content+acc.content})) ;\n      }),\n\n      // Transform the result into a RawResponse\n      map(json => ({\n        tokens: json.tokens,\n        streaming: !json.stop,\n        messagesHistory: [{role: \"assistant\", display: true, content: json.content}]\n      })),\n\n      // Accumulate stream into one message / response\n      scan((acc, res) => ({\n        ...res,\n        messagesHistory: [{ // Merge the last message with the previous one\n          ...res.messagesHistory[0],\n          content: acc.messagesHistory[0].content + res.messagesHistory[0].content\n        }]\n      })),\n    );\n  }\n\n  /**\n   * Returns the number of tokens taken by the given text\n   */\n  count(text: string[], model: GllmModel): Observable<number[]> {\n    const data = { action: \"TokenCount\", model, text };\n    return this.jsonMethodWebService.post(this.GLLM_PLUGIN, data).pipe(map(res => res.tokens));\n  }\n\n  /**\n   * Return the list of OpenAI models available on the server\n   */\n  listModels(): Observable<GllmModelDescription[]> {\n    const data = { action: \"listmodels\" };\n    return this.jsonMethodWebService.get(this.GLLM_PLUGIN, data).pipe(\n      map(res => res.models),\n      tap(models => this.models = models)\n    );\n  }\n\n  /**\n   * Return the number of tokens left for the current user\n   */\n  getQuota(): Observable<GllmTokenQuota> {\n    const data = { action: \"quota\" };\n    return this.jsonMethodWebService.get(this.GLLM_PLUGIN, data).pipe(\n      map(res => res.quota),\n      tap(quota => this.quota = quota),\n      tap(quota => this.quotaPercentage = Math.min(100, Math.ceil(100 * quota.tokenCount / quota.periodTokens)))\n    );\n  }\n\n  /**\n   * Fetch document text chunks from the standard Sinequa API\n   */\n  fetchChunks(id: string, chunks: {offset: number, length: number}[], sentencesBefore = 0, sentencesAfter = 0) {\n    return this.textChunksService.getTextChunks(id, chunks, [], this.searchService.makeQuery(), sentencesBefore, sentencesAfter);\n  }\n\n  /**\n   * Takes a list of ChatMessage and strips it from its\n   * optional data ($content, $record, etc.) so that it can be sent\n   * to the chat, or saved in the user settings\n   */\n  cleanMessages(messagesHistory: ChatMessage[], minimize = false): RawMessage[] {\n    return messagesHistory.map(message => ({\n      role: message.role,\n      content: message.content,\n      display: message.display,\n      $attachment: minimize? undefined : message.$attachment ? {\n        recordId: message.$attachment.recordId,\n        chunks: message.$attachment.chunks\n      } : undefined,\n      $refId: minimize? undefined : message.$refId,\n      $actions: minimize? undefined : message.$actions\n    }));\n  }\n\n  /**\n   * Given a list of raw messages (typically from a saved chat),\n   * this function reconstructs all the necessary data (records, attachments...)\n   * and returns a list of ChatMessage objects ready to be displayed\n   */\n  restoreMessages(messages: RawMessage[]): Observable<ChatMessage[]> {\n    const ids = messages.map(m => m.$attachment?.recordId!).filter(id => id);\n    return this.searchService.getRecords(ids).pipe(\n      map(records => messages.reduce((chatMessages, message) => {\n        const chatMessage: ChatMessage = {...message, $attachment: undefined};\n        if(message.$attachment) {\n          const $record = records.find(r => r?.id === message.$attachment?.recordId);\n          if($record) {\n            chatMessage.$attachment = {...message.$attachment, $record};\n          }\n        }\n        chatMessages.push(chatMessage);\n        return chatMessages;\n      }, [] as ChatMessage[]))\n    );\n  }\n\n  processResponse(messages: ChatMessage[], response: RawResponse) {\n    const rawMessage = response.messagesHistory.at(-1) as ChatMessage;\n    return {\n      tokens: response.tokens,\n      messagesHistory: [\n        ...messages,\n        { ...rawMessage }\n      ]\n    }\n  }\n\n  /**\n   * Given a list of attachments this function generates\n   * a list of chat messages with the formatted attachment as content.\n   */\n  prepareAttachmentMessages(attachments: ChatAttachment[], conversation: ChatMessage[], display: boolean): ChatMessage[] {\n    const idOffset = Math.max(0, ...conversation.map(m => m.$refId ?? 0)); // Determine the latest id used in the conversation\n    return attachments.map(($attachment, i) => {\n      const $refId = idOffset + i + 1;\n      return {\n        role: 'user',\n        content: this.formatContent($refId, $attachment.$record, $attachment.chunks.map(c => c.text)),\n        display,\n        $attachment,\n        $refId\n      }\n    });\n  }\n\n  protected formatContent(id: number, record: Record, text: string[]) {\n    let metas = \"\";\n    for(let field of this.attachmentMetadata) {\n      const meta = this.availableAttachmentMetadata.find(m => m.field === field);\n      if(meta) {\n        const value = record[meta.field];\n        if(value) {\n          metas += ` ${meta.name ?? field}=\"${meta.formatter?.(value) ?? value}\"`\n        }\n      }\n    }\n    const parts = text.map((t, i) => `<part id=\"${id}.${i+1}\">${t}</part>`);\n    return `<document id=\"${id}\" ${metas}>${parts.join('\\n\\n')}</document>`;\n  }\n\n  /**\n   * Get the model description for the given model name\n   */\n  getModel(name: GllmModel): GllmModelDescription | undefined {\n    return this.models?.find(m => m.name === name);\n  }\n\n\n  // Attachment API\n\n  /**\n   * Use Sinequa to retrieve relevant passages for the given text query\n   * When relevant content is retrieved, the attachments$ subject is\n   * upated.\n   */\n  searchAttachments(results: Results, options: Partial<SearchAttachmentsOptions>) {\n\n    const _options = Object.assign({}, defaultSearchAttachmentsOptions, options);\n\n    // Select top passages\n    const passages = results.topPassages?.passages\n      ?.filter(p => p.score > _options.minScoreTopPassage)\n      .slice(0, _options.maxTopPassages) || [];\n\n    const topDocuments = results.records\n      .filter(d => (d.globalrelevance ?? 1) > _options.minDocumentRelevance)\n      .slice(0, _options.maxDocuments)\n\n    return of(passages).pipe(\n      // Retrieve the records of these top passages (potentially asynchronous)\n      switchMap(passages => this.passagesWithRecords(passages, results.records)),\n      // Group by record\n      map(passage => this.groupPassages(passage)),\n      // Complement with regular records, when not already in the list\n      map(docs => {\n        for(let $record of topDocuments) {\n          if(!docs.find(d => d.$record.id === $record.id)) {\n            docs.push({$record, chunks: []});\n          }\n        }\n        return docs;\n      }),\n      // For each record retrieve chunks and return \"attachments\"\n      switchMap(docs => forkJoin(\n        docs.map(({$record, chunks}) => this.addDocument($record, chunks, _options.startLengthPerDocument, _options.maxExtractsPerDocument, _options.maxPassagesPerDocument, _options.extendBefore, _options.extendAfter))\n      )),\n      // forkJoin([]) does not emit anything, so the following line makes the observable emit something\n      defaultIfEmpty([] as ChatAttachment[])\n    );\n  }\n\n  /**\n   * Automatically search attachments in the results yielded by the given query\n   */\n  searchAttachmentsSync(query = this.searchService.query, options: Partial<SearchAttachmentsOptions>) {\n    const event: AuditEvent = {\n      type: \"Chat_Autosearch\",\n      detail: {\n        querytext: query.text\n      }\n    };\n    return this.searchService.getResults(query, event).pipe(\n      tap(results => this.searchService.setResults(results)),\n      switchMap(results => this.searchAttachments(results, options)),\n      switchMap(attachments => this.countChunks(attachments)),\n    ).subscribe(attachments => this.addAttachments(attachments));\n  }\n\n  protected passagesWithRecords(passages: TopPassage[], records: (Record | undefined)[], retrieveRecords = true): Observable<{$record: Record, location: number[]}[]> {\n    const passagesWithRecords = passages\n      .map(p => ({...p, $record: p.$record || records.find(r => r?.id === p.recordId)!}))\n      .filter(p => p.$record);\n    if(passagesWithRecords.length === passages.length || !retrieveRecords)\n      return of(passagesWithRecords);\n    const ids = passages.filter(p => !p.$record)\n      .map(p => p.recordId);\n    return this.searchService.getRecords(ids).pipe(\n      switchMap(records => this.passagesWithRecords(passages, records, false))\n    );\n  }\n\n  /**\n   * Get the list of chunks currently present in the attachments for\n   * a given record id (and return an empty list if there is none)\n   */\n  protected getChunks(recordId: string): DocumentChunk[] {\n    const attachment = this.attachments$.getValue().find(a => a.recordId === recordId);\n    return attachment?.chunks ?? [];\n  }\n\n  /**\n   * Adds a list of text chunks from a record to the list of attachments.\n   * If the record was already in the attachments, it will merge\n   * the new chunks into the existing ones.\n   */\n  addChunks($record: Record, _chunks: {offset: number, length: number}[], sentencesBefore=0, sentencesAfter=0): Observable<ChatAttachment> {\n    let obs: Observable<{offset: number, length: number, text?: string}[]> = of(_chunks);\n    if(sentencesBefore > 0 || sentencesAfter > 0) {\n      obs = this.fetchChunks($record.id, _chunks, sentencesBefore, sentencesAfter); // if needed, perform a first request that expands the given chunks\n    }\n    return obs.pipe(\n      switchMap(chunks => {\n        const existingChunks = this.getChunks($record.id);\n        for(let chunk of chunks) {\n          insertChunk(existingChunks, chunk.offset, chunk.length, this.chunkMargin);\n        }\n        if(chunks.every(c => c.text) && equalChunks(existingChunks, chunks)) {\n          return of(chunks as DocumentChunk[]); // No need to perform another request\n        }\n        return this.fetchChunks($record.id, existingChunks);\n      }),\n      map(chunks => ({$record, recordId: $record.id, chunks}))\n    );\n  }\n\n  /**\n   * Increase the size of all the chunks in an attachment\n   */\n  increaseChunks(attachment: ChatAttachmentWithTokens, sentencesBefore = 2, sentencesAfter = 4) {\n    return this.fetchChunks(attachment.recordId, attachment.chunks, sentencesBefore, sentencesAfter).pipe(\n      switchMap(newChunks => this.addChunks(attachment.$record, newChunks)),\n      switchMap(a => this.countChunks([a])),\n      map(a => ({...a[0], $expanded: attachment.$expanded}))\n    );\n  }\n\n  increaseChunksSync(attachment: ChatAttachmentWithTokens, sentencesBefore = 2, sentencesAfter = 4) {\n    this.increaseChunks(attachment, sentencesBefore, sentencesAfter)\n      .subscribe(a => this.addAttachments([a]));\n  }\n\n  /**\n   * Take in a list of chat attachment and enriches it with the number of tokens of each one\n   */\n  countChunks(attachments: ChatAttachment[]): Observable<ChatAttachmentWithTokens[]> {\n    if(attachments.length === 0) {\n      return of([]);\n    }\n    const texts = attachments.map(a => this.formatContent(10, a.$record, a.chunks.map(c => c.text)));\n    return this.count(texts, this.attachmentModel).pipe(\n      map(counts => attachments.map((a,i) => ({...a, $tokenCount: counts[i]})))\n    )\n  }\n\n  /**\n   * Removes a document chunk from an attachment and update the list\n   * of attachments.\n   * If this was the last chunk, the attachment is removed altogether.\n   */\n  removeChunk(attachment: ChatAttachmentWithTokens, chunk: DocumentChunk) {\n    const j = attachment.chunks.indexOf(chunk);\n    if(j !== -1) {\n      attachment.chunks.splice(j, 1);\n      if(attachment.chunks.length === 0) {\n        this.removeAttachment(attachment);\n      }\n      else {\n        this.addAttachments([attachment]); // Will take care of replacing the existing attachment if it exists (as it should)\n      };\n    }\n  }\n\n  /**\n   * Add a list of records as attachments\n   */\n  addDocuments(records: Record[], includeStart = 2048, includeExtracts = 3, includePassages = 2, sentencesBefore = 1, sentencesAfter = 3) {\n    return forkJoin(records.map(record => this.addDocument(record, [], includeStart, includeExtracts, includePassages, sentencesBefore, sentencesAfter)));\n  }\n\n  addDocumentsSync(records: Record[], includeStart = 2048, includeExtracts = 3, includePassages = 2, sentencesBefore = 1, sentencesAfter = 3) {\n    this.addDocuments(records, includeStart, includeExtracts, includePassages, sentencesBefore, sentencesAfter)\n      .pipe(switchMap(doc => this.countChunks(doc)))\n      .subscribe(a => this.addAttachments(a));\n  }\n\n  /**\n   * Returns a (truncated) document attachment\n   */\n  addDocument(record: Record, chunks: Chunk[] = [], includeStart = 2048, includeExtracts = 3, includePassages = 2, sentencesBefore = 1, sentencesAfter = 3): Observable<ChatAttachment> {\n    if(includeStart) {\n      chunks.push({offset: 0, length: includeStart});\n    }\n    if(includeExtracts && record.extracts) {\n      const extracts = this.getExtractChunks(record.extracts)\n        .slice(0, includeExtracts);\n      chunks.push(...extracts);\n    }\n    if(includePassages && record.matchingpassages?.passages) {\n      const passages = record.matchingpassages.passages\n        .map(p => p.location)\n        .map(([offset, length]) => ({offset, length}))\n        .slice(0, includePassages);\n      chunks.push(...passages);\n    }\n    return this.addChunks(record, chunks, sentencesBefore, sentencesAfter);\n  }\n\n  addDocumentSync(record: Record, chunks: Chunk[] = [], includeStart = 2048, includeExtracts = 3, includePassages = 2, sentencesBefore = 1, sentencesAfter = 3) {\n    this.addDocument(record, chunks, includeStart, includeExtracts, includePassages, sentencesBefore, sentencesAfter)\n      .pipe(switchMap(doc => this.countChunks([doc])))\n      .subscribe(a => this.addAttachments(a));\n  }\n\n  /**\n   * Preprocess top passage to ensure they have a record object and add them\n   * via the addPassages method\n   */\n  addTopPassages(passages: TopPassage[], records: Record[] = [], sentencesBefore=0, sentencesAfter=0): Observable<ChatAttachment[]> {\n    return this.passagesWithRecords(passages, records).pipe(\n      switchMap(passages => forkJoin(this.addPassages(passages, sentencesBefore, sentencesAfter))),\n    )\n  }\n\n  addTopPassagesSync(passages: TopPassage[], records: Record[] = [], sentencesBefore=0, sentencesAfter=0) {\n    this.addTopPassages(passages, records, sentencesBefore, sentencesAfter)\n      .pipe(switchMap(doc => this.countChunks(doc)))\n      .subscribe(a => this.addAttachments(a));\n  }\n\n  protected groupPassages(passages: {$record: Record, location: number[]}[]) {\n    const passagesById: {[id: string]: {$record: Record, chunks: Chunk[]}} = {};\n    for(let passage of passages) {\n      const group = passagesById[passage.$record.id] || {$record: passage.$record, chunks: []};\n      const [offset, length] = passage.location;\n      group.chunks.push({offset, length});\n      passagesById[passage.$record.id] = group;\n    }\n    return Object.values(passagesById);\n  }\n\n  /**\n   * Take a list of passages (typically \"top passages\"), group them by record id\n   * and for each record generate an attachment (merged with potential existing attachments)\n   */\n  addPassages(passages: {$record: Record, location: number[]}[], sentencesBefore=0, sentencesAfter=0): Observable<ChatAttachment>[] {\n    return this.groupPassages(passages).map(group => {\n      return this.addChunks(group.$record, group.chunks, sentencesBefore, sentencesAfter);\n    });\n  }\n\n  addPassagesSync(passages: {$record: Record, location: number[]}[], sentencesBefore=0, sentencesAfter=0) {\n    forkJoin(this.addPassages(passages, sentencesBefore, sentencesAfter))\n      .pipe(switchMap(p => this.countChunks(p)))\n      .subscribe(a => this.addAttachments(a));\n  }\n\n  /**\n   * Add relevant extracts to the attachments.\n   * There must be at least one extract.\n   */\n  addExtracts(record: Record, extracts: RelevantExtract[], sentencesBefore=0, sentencesAfter=0): Observable<ChatAttachment> {\n    const chunks = this.getExtractChunks(extracts);\n    return this.addChunks(record, chunks, sentencesBefore, sentencesAfter);\n  }\n\n  addExtractsSync(record: Record, extracts: RelevantExtract[], sentencesBefore=0, sentencesAfter=0) {\n    this.addExtracts(record, extracts, sentencesBefore, sentencesAfter)\n      .pipe(switchMap(e => this.countChunks([e])))\n      .subscribe(a => this.addAttachments(a));\n  }\n\n  protected getExtractChunks(extracts: RelevantExtract[]) {\n    return extracts.map(e => e.locations.split(',')).map(([offset, length]) => ({offset: +offset, length: +length}));\n  }\n\n  /**\n   * Updates the list of attachments with a new attachment,\n   * replacing the existing attachment for that record if it exists\n   */\n  addAttachments(attachments: ChatAttachmentWithTokens[]) {\n    const existingAttachments = this.attachments$.getValue();\n    for(let attachment of attachments) {\n      const i = existingAttachments.findIndex(a => a.recordId === attachment.recordId);\n      if(i === -1) {\n        existingAttachments.push(attachment);\n      }\n      else {\n        existingAttachments.splice(i, 1, attachment);\n      }\n    }\n    this.attachments$.next(existingAttachments);\n  }\n\n  /**\n   * Replace an old attachment with a new one\n   */\n  protected spliceAttachment(old: ChatAttachmentWithTokens, replace?: ChatAttachmentWithTokens) {\n    const attachments = this.attachments$.value;\n    const i = attachments.indexOf(old);\n    if(i !== -1 ) {\n      if(replace) {\n        replace.$expanded = old.$expanded;\n      }\n      attachments.splice(i, 1, ...replace ? [replace] : []);\n      this.attachments$.next(attachments);\n    }\n  }\n\n  /**\n   * Remove an attachment\n   */\n  removeAttachment(attachment: ChatAttachmentWithTokens) {\n    this.spliceAttachment(attachment);\n  }\n\n\n  // Saved chats management\n\n  savedChats$ = new Subject<SavedChat[]>();\n\n  /**\n   * Chats saved by the user to reopen them later\n   */\n  get savedChats(): SavedChat[] {\n    if (!this.userSettingsService.userSettings)\n      this.userSettingsService.userSettings = {};\n    if (!this.userSettingsService.userSettings[\"savedChats\"])\n      this.userSettingsService.userSettings[\"savedChats\"] = [];\n    return this.userSettingsService.userSettings[\"savedChats\"];\n  }\n\n  /**\n   * Returns the saved chat with the given name\n   */\n  getSavedChat(name: string): SavedChat | undefined {\n    return this.savedChats.find(chat => chat.name === name);\n  }\n\n  /**\n   * Save a agiven chat in the user settings\n   */\n  saveChat(savedChat: SavedChat): void {\n    const chat = this.getSavedChat(savedChat.name);\n    if (chat) {\n      this.deleteSavedChat(chat.name, true);\n    }\n    this.savedChats.push(savedChat);\n    this.syncSavedChats()\n      .subscribe(() => this.notificationsService.success(`${savedChat.name} was saved successfully`));\n    this.auditService.notify({\n      type: \"Chat_Save\",\n      detail: {\n        chat: savedChat.name\n      }\n    });\n  }\n\n  /**\n   * Delete a given chat\n   */\n  deleteSavedChat(name: string, skipSync?: boolean): void {\n    const chat = this.getSavedChat(name);\n    if (chat) {\n      this.savedChats.splice(this.savedChats.indexOf(chat), 1);\n      if (!skipSync) {\n        this.syncSavedChats();\n        this.auditService.notify({\n          type: \"Chat_Delete\",\n          detail: {\n            chat: name\n          }\n        });\n      }\n    }\n  }\n\n  syncSavedChats() {\n    const savedChats = this.savedChats;\n    this.savedChats$.next(savedChats);\n    return this.userSettingsService.patch({ savedChats });\n  }\n\n  /**\n   * Open a prompt to let the user pick a name for a saved chat.\n   * If the user obliges the chat is saved.\n   */\n  saveChatModal(conversation: ChatMessage[], tokens: GllmTokens) {\n    const messages = this.cleanMessages(conversation);\n    const model: PromptOptions = {\n      title: 'Save Chat',\n      message: 'Enter a name for the chat',\n      buttons: [],\n      output: '',\n      validators: [Validators.required]\n    };\n    this.modalService.prompt(model).then(res => {\n      if (res === ModalResult.OK) {\n        const savedChat: SavedChat = { name: model.output, messages, tokens };\n        this.saveChat(savedChat);\n      }\n    });\n  }\n\n  notifyAudit(messagesHistory: ChatMessage[], model: string, tokens: number) {\n    let numberOfUserMessages = 0;\n    let numberOfAttachments = 0;\n    let numberOfAssistantMessages = 0;\n    for(let m of messagesHistory) {\n      if(m.$attachment) numberOfAttachments++;\n      else if(m.role === 'user') numberOfUserMessages++;\n      else if (m.role === 'assistant') numberOfAssistantMessages++;\n    }\n    this.auditService.notify({\n      type: 'Chat_Messages',\n      detail: {\n        message: messagesHistory.map(m => m.role.toUpperCase() + ': '+ (m.$attachment? `attachment ${m.$attachment?.$record.title}` : m.content)).join('\\n\\n'),\n        numberOfUserMessages,\n        numberOfAttachments,\n        numberOfAssistantMessages,\n        model,\n        tokens\n      }\n    });\n  }\n\n  get attachmentMetadata(): string[] {\n    return this.prefs.get(\"chat-attachment-metadata\") ?? this.defaultAttachmentMetadata;\n  }\n\n  set attachmentMetadata(metadata: string[]) {\n    this.prefs.set(\"chat-attachment-metadata\", metadata);\n  }\n\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ChangeDetectorRef, AfterViewInit, ElementRef } from \"@angular/core\";\nimport { Record } from \"@sinequa/core/web-services\";\nimport { SearchService } from \"@sinequa/components/search\";\nimport { ChatAttachmentOpen, ChatMessage } from \"./types\";\n\nimport { unified, Processor } from \"unified\";\nimport remarkParse from \"remark-parse\";\nimport { visit, CONTINUE, EXIT } from \"unist-util-visit\";\nimport { Text, Parent, Content } from \"mdast\";\nimport { Node } from \"unist\";\nimport { UIService } from \"@sinequa/components/utils\";\n\ndeclare module Prism {\n  function highlightAllUnder(el: HTMLElement): void;\n}\n\n@Component({\n    selector: \"sq-chat-message\",\n    templateUrl: \"./chat-message.component.html\",\n    styleUrls: [\"./chat-message.component.scss\"],\n    changeDetection: ChangeDetectionStrategy.OnPush,\n    standalone: false\n})\nexport class ChatMessageComponent implements OnChanges, AfterViewInit {\n  @Input() message: ChatMessage;\n  @Input() conversation: ChatMessage[];\n  @Input() assistantIcon: string;\n  @Input() streaming: boolean;\n  @Input() canEdit: boolean = false;\n  @Input() canRegenerate: boolean = false;\n  @Output() referenceClicked = new EventEmitter<Record>();\n  @Output() edit = new EventEmitter<ChatMessage>();\n  @Output() regenerate = new EventEmitter<ChatMessage>();\n  @Output() openPreview = new EventEmitter<ChatAttachmentOpen>();\n\n  processor: Processor;\n\n  references: string[] = [];\n  referenceMap = new Map<string, ChatAttachmentOpen>();\n\n  constructor(\n    public searchService: SearchService,\n    public ui: UIService,\n    public cdr: ChangeDetectorRef,\n    public el: ElementRef\n  ) {}\n\n  ngOnChanges(changes: SimpleChanges): void {\n    if(changes.message && this.message.role === \"assistant\") {\n      this.references = [];\n      this.referenceMap.clear();\n      for(let m of this.conversation) {\n        if(m.$attachment) {\n          for(let i = 0; i < m.$attachment.chunks.length; i++) {\n            const refId = `${m.$refId}.${i+1}`;\n            this.referenceMap.set(refId, {...m.$attachment, $chunkIndex: i});\n          }\n          this.referenceMap.set(''+m.$refId!, {...m.$attachment, $chunkIndex: 0});\n        }\n      }\n\n      this.processor = unified()\n        .use(remarkParse)\n        .use(() => this.referencePlugin);\n\n      if(this.streaming) {\n        this.processor = this.processor.use(() => this.placeholderPlugin);\n      }\n    }\n  }\n\n  ngAfterViewInit(): void {\n    Prism?.highlightAllUnder?.(this.el.nativeElement);\n  }\n\n  onReferenceClicked(record: Record, event: MouseEvent) {\n    const url = record.url1 || record.originalUrl;\n    if(!url) {\n      event.preventDefault();\n    }\n    this.referenceClicked.emit(record);\n  }\n\n  /**\n   * This Unified plugin looks a text nodes and replaces any reference in the\n   * form [1], [2.3], etc. with custom nodes of type \"chat-reference\".\n   */\n  referencePlugin = (tree: Node) => {\n\n    const references = new Set<number>();\n\n    // Visit all text nodes\n    visit(tree, \"text\", (node: Text, index: number, parent: Parent) => {\n      let text = node.value;\n\n      text = this.reformatReferences(text);\n      const matches = this.getReferenceMatches(text);\n\n      // Quit if no references were found\n      if(matches.length === 0) {\n        return CONTINUE;\n      }\n\n      const nodes: (Content & {end: number})[] = [];\n\n      for(let match of matches) {\n        const refId = match[1].trim();\n        const [ref] = refId.split(\".\");\n        // We find a valid reference in the text\n        if(!isNaN(+ref)) {\n          references.add(+ref); // Add it to the set of used references\n\n          // If needed, insert a text node before the reference\n          const current = nodes.at(-1) ?? {end: 0};\n          if (match.index! > current.end) {\n            nodes.push({ type: \"text\", value: text.substring(current.end, match.index!), end: match.index! });\n          }\n\n          // Add a custom reference node\n          nodes.push({ type: \"chat-reference\", refId, end: match.index! + match[0].length } as any);\n        }\n      }\n\n      // Quit if no references were found\n      if(nodes.length === 0) {\n        return CONTINUE;\n      }\n\n      if(nodes.at(-1)!.end < text.length) {\n        nodes.push({ type: \"text\", value: text.substring(nodes.at(-1)!.end, text.length), end: text.length });\n      }\n\n      // Delete the current text node from the parent and replace it with the new nodes\n      parent.children.splice(index, 1, ...nodes);\n\n      return index + nodes.length; // Visit the next node after the inserted ones\n    });\n\n    if(references.size > 0) {\n      this.references = Array.from(references.values())\n        .sort((a,b) => a-b)\n        .map(r => ''+r);\n      this.cdr.detectChanges();\n    }\n\n    return tree;\n  }\n\n  placeholderPlugin = (tree: Node) => {\n\n    visit(tree, \"text\", (node: Text, index: number, parent: Parent) => {\n      parent.children.push({type: \"streaming-placeholder\"} as any);\n      return EXIT;\n    }, true);\n\n    return tree;\n  }\n\n  /**\n   * Reformat [ids: 12.2, 42.5] to [12.2][42.5]\n   */\n  reformatReferences(content: string) {\n    return content.replace(/\\[(?:ids?:?\\s*)?(?:documents?:?\\s*)?(\\s*(?:,?\\s*\\d+(?:\\.\\d+)?\\s*)+)\\]/g,\n      (str, match: string) => `[${match.split(',').join(\"] [\")}]`\n    );\n  }\n\n  /**\n   * Match all references in a given message\n   */\n  getReferenceMatches(content: string) {\n    return Array.from(content.matchAll(/\\[(\\s*\\d+(?:\\.\\d+)?\\s*)\\]/g));\n  }\n\n  copyToClipboard(text: string) {\n    this.ui.copyToClipboard(text);\n  }\n}\n","<!-- Message icon -->\n<span class=\"me-3\" [title]=\"message.role\" [ngSwitch]=\"message.role\">\n  <i class=\"fas fa-2x fa-user-circle text-muted\" *ngSwitchCase=\"'user'\"></i>\n  <i [ngClass]=\"assistantIcon\" [style.--sq-size.px]=\"28\" *ngSwitchCase=\"'assistant'\"></i>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1\" style=\"min-width: 0;\">\n\n  <remark *ngIf=\"message.role === 'assistant'; else plainTextTpl\" class=\"message-content\" [markdown]=\"message.content\" [processor]=\"processor\">\n\n    <ng-template remarkTemplate=\"chat-reference\" let-ref>\n\n      <a *ngIf=\"referenceMap.get(ref.refId) as attachment; else staticRefTpl\"\n        [href]=\"attachment.$record.url1 || attachment.$record.originalUrl || '#'\"\n        target=\"_blank\"\n        (click)=\"onReferenceClicked(attachment.$record, $event)\"\n        class=\"reference\"\n        [sqTooltip]=\"attachment\"\n        [sqTooltipTemplate]=\"tooltipTpl\"\n        [hoverableTooltip]=\"true\"\n        >{{ref.refId}}</a>\n\n      <ng-template #staticRefTpl>\n        <span class=\"reference\">{{ref.refId}}</span>\n      </ng-template>\n\n    </ng-template>\n\n    <ng-template remarkTemplate=\"streaming-placeholder\">\n      <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n        <span class=\"placeholder ms-1\"></span>\n      </span>\n    </ng-template>\n\n    <ng-template remarkTemplate=\"code\" let-node>\n      <div class=\"card mb-2\">\n        <div class=\"card-header d-flex justify-content-between align-items-center\">\n          <span>{{node.lang}}</span>\n          <button class=\"btn btn-light btn-sm\" (click)=\"copyToClipboard(node.value)\"><i class=\"fas fa-fw fa-clipboard\"></i> Copy code</button>\n        </div>\n        <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n      </div>\n    </ng-template>\n\n  </remark>\n\n  <ng-template #plainTextTpl>\n    <div class=\"message-content\">{{message.content}}</div>\n  </ng-template>\n\n  <!-- Edit / Regenerate floating actions -->\n  <div class=\"sq-chat-message-action\">\n    <button class=\"btn btn-sm btn-light shadow mt-1 me-1\" *ngIf=\"canEdit\" sqTooltip=\"Edit message\"\n            (click)=\"edit.emit(message)\">\n      <i class=\"fas fa-edit\"></i>\n    </button>\n    <button class=\"btn btn-sm btn-light shadow mt-1 me-1\" *ngIf=\"canRegenerate\" sqTooltip=\"Regenerate message\"\n            (click)=\"regenerate.emit(message)\">\n      <i class=\"fas fa-sync-alt\"></i>\n    </button>\n  </div>\n  <ng-template #tooltipTpl let-ref>\n    <div class=\"sq-tooltip\">\n      <div class=\"text-center mb-2\">\n        <a role=\"button\" (click)=\"openPreview.emit(ref)\">\n          <i class=\"fas fa-fw fa-eye\"></i> Document preview\n        </a>\n      </div>\n      <span class=\"sq-passage-text\">{{ref.chunks[ref.$chunkIndex].text}}</span>\n    </div>\n  </ng-template>\n\n  <!-- List of reference, if any -->\n  <div *ngIf=\"references?.length\" class=\"references small\">\n    <b>References:</b>\n    <ul class=\"list-group\">\n      <ng-container *ngFor=\"let reference of references\">\n        <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\" [title]=\"attachment.$record.title\">\n          <span class=\"reference me-1\">{{reference}}</span>\n          <a [href]=\"attachment.$record.url1 || attachment.$record.originalUrl || '#'\"\n            target=\"_blank\"\n            (click)=\"onReferenceClicked(attachment.$record, $event)\">\n            {{attachment.$record.title}}\n          </a>\n        </li>\n      </ng-container>\n    </ul>\n  </div>\n</div>\n\n<!-- Message actions (optional) -->\n<div [sq-action-buttons]=\"{items: message.$actions, style: 'link', size: 'sm', rightAligned: true}\" *ngIf=\"message.$actions\"></div>\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, TemplateRef, ViewChild } from \"@angular/core\";\nimport { Action } from \"@sinequa/components/action\";\nimport { AbstractFacet } from \"@sinequa/components/facet\";\nimport { SearchService } from \"@sinequa/components/search\";\nimport { Query } from \"@sinequa/core/app-utils\";\nimport { Utils } from \"@sinequa/core/base\";\nimport { Record } from \"@sinequa/core/web-services\";\nimport { BehaviorSubject, Observable, Subscription, delay, map, of, switchMap } from \"rxjs\";\nimport { ChatService, SearchAttachmentsOptions } from \"./chat.service\";\nimport { ChatAttachment, ChatAttachmentOpen, ChatMessage, GllmModel, GllmModelDescription, GllmTokens, RawMessage } from \"./types\";\n\nexport interface ChatConfig extends SearchAttachmentsOptions {\n  // Model\n  model: GllmModel;\n  temperature: number;\n  topP: number;\n  maxTokens: number;\n  googleContextPrompt: string;\n  stream: boolean;\n\n  // UI\n  textBeforeAttachments: boolean;\n  displayAttachments: boolean;\n\n  // Prompts\n  initialSystemPrompt: string;\n  initialUserPrompt: string;\n  addAttachmentPrompt: string;\n  addAttachmentsPrompt: string;\n  attachmentsHiddenPrompt: string;\n}\n\nexport const defaultChatConfig: ChatConfig = {\n  // Model\n  model: 'GPT35Turbo',\n  temperature: 1.0,\n  topP: 1.0,\n  maxTokens: 800,\n  googleContextPrompt: \"Answer only using the text of the documents. If you don't know or don't have enough information from the documents just say so.\",\n  stream: true,\n\n  // UI\n  textBeforeAttachments: false,\n  displayAttachments: true,\n\n  // Prompts\n  initialSystemPrompt: \"You are a helpful assistant\",\n  initialUserPrompt: \"Hello, I am a user of the Sinequa search engine\",\n  addAttachmentPrompt: \"Summarize this document\",\n  addAttachmentsPrompt: \"Summarize these documents\",\n  attachmentsHiddenPrompt: \"You can refer to the above documents in the form: [id] (eg [2], [7])\",\n\n  // Auto-search\n  minScoreTopPassage: 0.5,\n  maxTopPassages: 4,\n  maxDocuments: 2,\n  minDocumentRelevance: 0,\n  maxExtractsPerDocument: 3,\n  maxPassagesPerDocument: 2,\n  startLengthPerDocument: 1024,\n  extendBefore: 1,\n  extendAfter: 1\n}\n\nexport interface InitChat {\n  messages: RawMessage[];\n  tokens?: GllmTokens;\n  attachments?: Observable<ChatAttachment[]|ChatAttachment>;\n}\n\n@Component({\n    selector: 'sq-chat',\n    templateUrl: './chat.component.html',\n    styleUrls: ['./chat.component.scss'],\n    changeDetection: ChangeDetectionStrategy.OnPush,\n    standalone: false\n})\nexport class ChatComponent extends AbstractFacet implements OnChanges, OnDestroy {\n  @Input() chat?: InitChat;\n  @Input() enableChat = true;\n  @Input() searchMode = false;\n\n  // Model\n  @Input() model =                    defaultChatConfig.model;\n  @Input() temperature =              defaultChatConfig.temperature;\n  @Input() topP =                     defaultChatConfig.topP;\n  @Input() maxTokens =                defaultChatConfig.maxTokens;\n  @Input() googleContextPrompt =      defaultChatConfig.googleContextPrompt;\n  @Input() stream =                   defaultChatConfig.stream;\n\n  // UI\n  @Input() textBeforeAttachments =    defaultChatConfig.textBeforeAttachments;\n  @Input() displayAttachments =       defaultChatConfig.displayAttachments;\n  @Input() showCredits = true;\n  @Input() customAssistantIcon?: string;\n\n  // Prompts\n  @Input() initialSystemPrompt =      defaultChatConfig.initialSystemPrompt;\n  @Input() initialUserPrompt =        defaultChatConfig.initialUserPrompt;\n  @Input() addAttachmentPrompt =      defaultChatConfig.addAttachmentPrompt;\n  @Input() addAttachmentsPrompt =     defaultChatConfig.addAttachmentsPrompt;\n  @Input() attachmentsHiddenPrompt =  defaultChatConfig.attachmentsHiddenPrompt;\n\n  // Auto-search\n  @Input() minScoreTopPassage =       defaultChatConfig.minScoreTopPassage;\n  @Input() maxTopPassages =           defaultChatConfig.maxTopPassages;\n  @Input() maxDocuments =             defaultChatConfig.maxDocuments;\n  @Input() minDocumentRelevance =     defaultChatConfig.minDocumentRelevance;\n  @Input() maxExtractsPerDocument =   defaultChatConfig.maxExtractsPerDocument;\n  @Input() maxPassagesPerDocument =   defaultChatConfig.maxPassagesPerDocument;\n  @Input() startLengthPerDocument =   defaultChatConfig.startLengthPerDocument;\n  @Input() extendBefore =             defaultChatConfig.extendBefore;\n  @Input() extendAfter =              defaultChatConfig.extendAfter;\n\n  @Input() query?: Query;\n  @Output() data = new EventEmitter<ChatMessage[]>();\n  @Output() referenceClicked = new EventEmitter<Record>();\n  @Output() openPreview = new EventEmitter<ChatAttachmentOpen>();\n  @Output() loading = new EventEmitter<boolean>(false);\n  @Output() error = new EventEmitter<any>();\n\n  @ViewChild('messageList') messageList?: ElementRef<HTMLUListElement>;\n  @ViewChild('questionInput') questionInput?: ElementRef<HTMLInputElement>;\n\n  @ContentChild('loadingTpl') loadingTpl?: TemplateRef<any>;\n\n  streaming = false;\n  loadingAttachments = false;\n  messages$ = new BehaviorSubject<ChatMessage[] | undefined>(undefined);\n\n  question = '';\n\n  tokensPercentage = 0; // Percentage of tokens used in the conversation over the tokens available in the model\n  tokensAbsolute = 0; // Tokens used in the conversation and in the question and attachments\n  tokens = 0; // Tokens used in previous messages of the conversation\n  get tokensModel() { return this.modelDescription?.size ?? 0; }\n\n  openChatAction: Action;\n  _actions: Action[] = [];\n  override get actions() { return this._actions; }\n\n  sub = new Subscription();\n  dataSubscription: Subscription | undefined;\n\n  /** Variables that depend on the type of model in use */\n  modelDescription?: GllmModelDescription;\n  assistantIcon: string;\n  privacyUrl: string;\n\n  messageToEdit?: number;\n\n  constructor(\n    public chatService: ChatService,\n    public searchService: SearchService,\n    public cdr: ChangeDetectorRef\n  ) {\n    super();\n    this.sub.add(\n      this.chatService.attachments$.subscribe(attachments => {\n        this.loadingAttachments = false;\n        this.updateTokensPercentage();\n        this.question = this.suggestQuestion(attachments);\n        if (attachments.length) {\n          setTimeout(() => this.questionInput?.nativeElement.focus());\n        }\n      })\n    );\n\n    this.sub.add(\n      this.chatService.savedChats$.subscribe(() => this.updateActions())\n    )\n\n    this.openChatAction = new Action({\n      icon: 'fas fa-folder-open',\n      title: 'Open Saved chat',\n      children: []\n    });\n\n    this._actions.push(new Action({\n      icon: 'fas fa-sync',\n      title: 'Reset chat',\n      action: () => this.loadDefaultChat()\n    }));\n\n    this._actions.push(new Action({\n      icon: 'fas fa-save',\n      title: 'Save chat',\n      action: () => this.saveChat()\n    }));\n\n    this._actions.push(this.openChatAction);\n\n    this.sub.add(\n      this.chatService.initialized$\n        .subscribe(() => this.updateModelDescription())\n    );\n  }\n\n  ngOnChanges(changes: SimpleChanges) {\n    this.chatService.attachmentModel = this.model;\n\n    if (!this.messages$.value || changes.chat) {\n      if (this.chat) {\n        this.openChat(this.chat.messages, this.chat.tokens, this.chat.attachments);\n      }\n      else {\n        this.loadDefaultChat();\n      }\n    }\n\n    this.updateActions();\n    this.updateModelDescription();\n  }\n\n  ngOnDestroy(): void {\n    this.sub.unsubscribe();\n    this.dataSubscription?.unsubscribe();\n  }\n\n  submitQuestion() {\n    if(this.question.trim() && this.messages$.value) {\n      const attachments = this.chatService.attachments$.value;\n      if (this.messageToEdit !== undefined) {\n        this.messages$.next(this.messages$.value.slice(0, this.messageToEdit));\n        this.messageToEdit = undefined;\n      }\n      this.fetchAnswer(this.question.trim(), this.messages$.value!, attachments);\n    }\n  }\n\n  searchAttachments(event?: Event) {\n    if(this.searchMode && this.question.trim()) {\n      event?.preventDefault();\n      this.loadingAttachments = true;\n      const query = (this.query || this.searchService.query).copy();\n      query.text = this.question;\n      this.chatService.searchAttachmentsSync(query, {\n        minScoreTopPassage:     this.minScoreTopPassage,\n        maxTopPassages:         this.maxTopPassages,\n        maxDocuments:           this.maxDocuments,\n        minDocumentRelevance:   this.minDocumentRelevance,\n        maxExtractsPerDocument: this.maxExtractsPerDocument,\n        maxPassagesPerDocument: this.maxPassagesPerDocument,\n        startLengthPerDocument: this.startLengthPerDocument,\n        extendBefore:           this.extendBefore,\n        extendAfter:            this.extendAfter\n      });\n    }\n  }\n\n  updateTokensPercentage() {\n    if (this.tokens) {\n      const questionTokens = Math.floor(this.question.trim().length / 3.5);\n      const attachments = this.chatService.attachments$.value;\n      const attachmentTokens = attachments.reduce((prev, cur) => prev + cur.$tokenCount, 0);\n      this.tokensAbsolute = this.tokens + questionTokens + attachmentTokens;\n      this.tokensPercentage = Math.min(100, 100 * this.tokensAbsolute / (this.tokensModel - this.maxTokens));\n    }\n  }\n\n  updateModelDescription() {\n    this.modelDescription = this.chatService.getModel(this.model);\n    switch(this.modelDescription?.provider) {\n      case 'Google':\n        this.assistantIcon = 'sq-google';\n        this.privacyUrl = '';\n        break;\n      case 'OpenAI':\n        this.assistantIcon = 'sq-chatgpt';\n        this.privacyUrl = 'https://learn.microsoft.com/en-us/legal/cognitive-services/openai/data-privacy';\n        break;\n      case 'Cohere':\n        this.assistantIcon = 'sq-cohere';\n        this.privacyUrl = 'https://cohere.com/security';\n        break;\n    }\n  }\n\n  private fetchAnswer(question: string, conversation: ChatMessage[], attachments: ChatAttachment[]) {\n    const attachmentMessages = this.getAttachmentMessages(conversation, attachments);\n    const userMsg = {role: 'user', content: question, display: true};\n    const messages = this.textBeforeAttachments?\n        [...conversation, userMsg, ...attachmentMessages]\n      : [...conversation, ...attachmentMessages, userMsg];\n    this.fetch(messages);\n  }\n\n  /**\n   * Given a list of messages, fetch the server for a continuation and updates\n   * the list of messages accordingly.\n   * @param messages\n   */\n  public fetch(messages: ChatMessage[]) {\n    this.loading.next(true);\n    this.cdr.detectChanges();\n    this.dataSubscription?.unsubscribe();\n    this.dataSubscription = this.chatService.fetch(messages, this.model, this.temperature, this.maxTokens, this.topP, this.googleContextPrompt, this.stream)\n      .subscribe({\n        next: res => this.updateData(res.messagesHistory, res.tokens),\n        error: err => {\n          this.terminateFetch();\n          console.error(err);\n          this.error.emit(err);\n        },\n        complete: () => {\n          this.terminateFetch();\n          setTimeout(() => {\n            this.questionInput?.nativeElement.focus();\n          })\n        }\n      });\n    this.scrollDown();\n  }\n\n  private getAttachmentMessages(conversation: ChatMessage[], attachments: ChatAttachment[], display = this.displayAttachments) {\n    const attachmentMessages = this.chatService.prepareAttachmentMessages(attachments, conversation, display);\n    if(this.attachmentsHiddenPrompt && attachmentMessages.length > 0) {\n      attachmentMessages.push(\n        {role: 'user', content: this.attachmentsHiddenPrompt, display: false}\n      );\n    }\n    return attachmentMessages;\n  }\n\n  updateData(messages: ChatMessage[], tokens: number) {\n    this.messages$.next(messages);\n    this.data.emit(messages);\n    this.loading.next(false);\n    this.streaming = this.stream; // streaming = false set in terminateFetch\n    this.tokens = tokens;\n    this.chatService.attachments$.next([]); // This updates the tokensPercentage\n    this.question = '';\n    this.scrollDown();\n  }\n\n  suggestQuestion(attachments: ChatAttachment[]) {\n    if(attachments.length === 1 && this.question === '') {\n      return this.addAttachmentPrompt || this.question;\n    }\n    else if(attachments.length > 1 && (this.question === '' || this.question === this.addAttachmentPrompt)) {\n      return this.addAttachmentsPrompt || this.question;\n    }\n    return this.question;\n  }\n\n  scrollDown() {\n    setTimeout(() => {\n      if(this.messageList?.nativeElement) {\n        this.messageList.nativeElement.scrollTop = this.messageList.nativeElement.scrollHeight;\n      }\n    });\n  }\n\n  resetChat() {\n    if(this.messages$.value) {\n      this.messages$.next(undefined); // Reset chat\n    }\n    this.question = '';\n    this.tokensPercentage = 0;\n    this.tokensAbsolute = 0;\n    this.tokens = 0;\n    this.terminateFetch();\n  }\n\n  loadDefaultChat() {\n    this.openChat([\n      {role: 'system', content: this.initialSystemPrompt, display: false},\n      {role: 'user', content: this.initialUserPrompt, display: true},\n    ]);\n  }\n\n  saveChat() {\n    if(this.messages$.value && this.tokens) {\n      this.chatService.saveChatModal(this.messages$.value, {model: this.tokensModel, used: this.tokens});\n    }\n  }\n\n  openChat(messages: RawMessage[], tokens?: GllmTokens, attachments$?: Observable<ChatAttachment[]|ChatAttachment>) {\n    this.resetChat();\n    this.loading.next(true);\n    this.dataSubscription = this.chatService.restoreMessages(messages)\n      .pipe(\n        delay(0), // In case the observer completes synchronously, the delay forces async update and prevents \"change after checked\" error\n        switchMap(messages => attachments$?.pipe( // Process the optional attachments\n            map(attachments => Utils.asArray(attachments)),\n            map(attachments => [\n              ...messages,\n              ...this.chatService.prepareAttachmentMessages(attachments, messages, false)\n            ])\n          ) ?? of(messages)\n        )\n      )\n      .subscribe(messages => {\n        const lastMessage = messages.at(-1);\n        if(lastMessage && lastMessage.role !== 'assistant') {\n          this.fetch(messages); // If the last message if from a user, an answer from ChatGPT is expected\n        }\n        else if(tokens) {\n          this.updateData(messages, tokens.used); // If the last message if from the assistant, we can load the conversation right away\n        }\n      });\n  }\n\n  updateActions() {\n    this.openChatAction.children = this.chatService.savedChats.map(chat => new Action({\n      text: chat.name,\n      action: () => this.openChat(chat.messages, chat.tokens)\n    }));\n    this.openChatAction.hidden = this.openChatAction.children.length === 0;\n  }\n\n  terminateFetch() {\n    this.dataSubscription?.unsubscribe();\n    this.dataSubscription = undefined;\n    this.streaming = false;\n    this.loading.next(false);\n    this.cdr.markForCheck();\n  }\n\n  editMessage(index: number) {\n    this.messageToEdit = index;\n    this.question = this.messages$.value![index].content;\n    this.questionInput?.nativeElement.focus();\n  }\n\n  regenerateMessage(index: number) {\n    const slicedMessages = this.messages$.value!.slice(0, index);\n    this.messages$.next(slicedMessages);\n    this.fetch(slicedMessages);\n  }\n}\n","\n<div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n  <ul class=\"list-group list-group-flush overflow-auto pb-5\" #messageList>\n    <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n      <!-- Regular messages -->\n      <li class=\"list-group-item\" *ngIf=\"message.display && !message.$attachment\"\n          [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n        <sq-chat-message\n          [message]=\"message\"\n          [conversation]=\"messages\"\n          [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n          [streaming]=\"last && streaming\"\n          [canEdit]=\"(loading | async) === false && !streaming && messageToEdit === undefined && message.role !== 'assistant'\"\n          [canRegenerate]=\"(loading | async) === false && !streaming && messageToEdit === undefined && message.role === 'assistant'\"\n          (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n          (referenceClicked)=\"referenceClicked.emit($event)\"\n          (openPreview)=\"openPreview.emit($event)\">\n        </sq-chat-message>\n      </li>\n      <!-- Attachment messages -->\n      <li *ngIf=\"message.display && message.$attachment\"\n        class=\"attachment list-group-item d-flex\"\n        [ngClass]=\"{expanded: message.$attachment.$expanded}\">\n        <ng-container *ngTemplateOutlet=\"attachmentTpl; context:{$implicit:message.$attachment}\"></ng-container>\n      </li>\n    </ng-container>\n\n    <li class=\"list-group-item\" *ngIf=\"loading | async\">\n      <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n    </li>\n  </ul>\n\n  <div class=\"user-input mt-auto\" *ngIf=\"enableChat\">\n    <div class=\"progress\" [ngClass]=\"{disabled: tokensPercentage >= 100 || chatService.quotaPercentage >= 100}\">\n      <div role=\"progressbar\" class=\"progress-bar\"\n        [ngStyle]=\"{'width.%': (chatService.quotaPercentage >= 100? 100 : tokensPercentage)}\"\n        title=\"Tokens used {{tokensAbsolute}}/{{tokensModel - maxTokens}} (quota: {{chatService.quotaPercentage}}%)\">\n        {{\n          tokensPercentage >= 100? 'Maximum number of tokens reached, reset the chat or remove attachments' :\n          chatService.quotaPercentage >= 100? 'You reached your maximum usage quota. Try again '+(chatService.quota!.nextResetUTC | sqRelativeTime) : ''\n        }}\n      </div>\n    </div>\n    <div class=\"py-2\">\n      <ng-container *ngIf=\"textBeforeAttachments\">\n        <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n        <ng-container *ngTemplateOutlet=\"attachmentListTpl\"></ng-container>\n      </ng-container>\n\n      <ng-container *ngIf=\"!textBeforeAttachments\">\n        <ng-container *ngTemplateOutlet=\"attachmentListTpl\"></ng-container>\n        <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n      </ng-container>\n\n      <div class=\"text-end small text-muted px-3\" *ngIf=\"showCredits\">\n        powered by {{modelDescription?.displayName}} <ng-container *ngIf=\"privacyUrl\"> - <a [href]=\"privacyUrl\" target=\"_blank\">privacy notice</a></ng-container>\n      </div>\n    </div>\n  </div>\n</div>\n\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n  <div class=\"spinner-grow text-success d-block mx-auto my-5\" role=\"status\">\n    <span class=\"visually-hidden\">Loading...</span>\n  </div>\n</ng-template>\n\n<ng-template #inputTpl>\n  <div class=\"d-flex position-relative align-items-center px-3 py-1\">\n    <span class=\"me-3\">\n      <i class=\"fas fa-2x fa-user-circle text-muted\"></i>\n    </span>\n    <input #questionInput\n      type=\"search\" class=\"form-control rounded-5 px-3\"\n      placeholder=\"Your response\" autofocus\n      [(ngModel)]=\"question\"\n      (ngModelChange)=\"updateTokensPercentage()\"\n      (keyup.enter)=\"submitQuestion()\"\n      (keyup.shift.enter)=\"submitQuestion()\"\n      (keydown.tab)=\"searchAttachments($event)\"\n      [disabled]=\"(loading | async) || streaming || loadingAttachments || tokensPercentage >= 100 || chatService.quotaPercentage >= 100\">\n    <a *ngIf=\"searchMode\" role=\"button\" [ngClass]=\"{disabled: !question}\" class=\"ms-3 mb-0 text-nowrap\" (click)=\"searchAttachments()\" sqTooltip=\"Search Before Chat\" placement=\"top\">\n      <img src=\"assets/sinequa-logo-light-lg.png\" alt=\"sinequa logo\" width=\"120px\">\n    </a>\n    <button class=\"btn btn-secondary ms-2\" *ngIf=\"messageToEdit !== undefined\" sqTooltip=\"Cancel edition\"\n            (click)=\"messageToEdit = undefined; question = ''\">\n      Cancel\n    </button>\n    <div class=\"sq-stop-generating\" *ngIf=\"streaming\">\n      <button class=\"btn btn-sm btn-outline-secondary shadow\" (click)=\"terminateFetch()\">\n        <i class=\"fas fa-stop me-1\"></i> Stop generating\n      </button>\n    </div>\n  </div>\n</ng-template>\n\n<ng-template #attachmentTpl let-attachment>\n  <span class=\"px-2 me-3\" title=\"Attachments\">\n    <i class=\"fas fa-paperclip text-muted\"></i>\n  </span>\n\n  <p class=\"flex-grow-1 mb-0\" role=\"button\" (click)=\"attachment.$expanded = !attachment.$expanded\">\n    <span>\n      <i class=\"fas fa-fw fa-caret-{{attachment.$expanded? 'down' : 'right'}} pe-1\"></i>\n      <b>{{attachment.$record?.title}}: </b>\n      <ng-container *ngIf=\"!attachment.$expanded\">\n        <span *ngFor=\"let c of attachment.chunks\">{{c.text}}</span>\n      </ng-container>\n      <ul class=\"list-group list-group-flush no-max-height\" *ngIf=\"attachment.$expanded\">\n        <li class=\"list-group-item attachment\" *ngFor=\"let c of attachment.chunks\">\n          <p class=\"m-0\" [title]=\"c.text\">{{c.text}}</p>\n        </li>\n      </ul>\n    </span>\n  </p>\n</ng-template>\n\n<ng-template #attachmentListTpl>\n  <ng-container *ngIf=\"loadingAttachments\" [ngTemplateOutlet]=\"loadingTpl || loadingTplDefault\"></ng-container>\n\n  <ul class=\"list-group list-group-flush overflow-auto\" *ngIf=\"chatService.attachments$ | async as attachments\">\n\n    <li *ngFor=\"let attachment of attachments\"\n      class=\"attachment list-group-item d-flex\"\n      [ngClass]=\"{expanded: attachment.$expanded}\">\n\n      <ng-container *ngTemplateOutlet=\"attachmentTpl; context:{$implicit:attachment}\"></ng-container>\n\n      <div class=\"ms-3 col-1 small text-muted d-flex flex-column align-items-center\" *ngIf=\"!loading\">\n        <span title=\"Number of tokens\">{{attachment.$tokenCount}}</span>\n        <button class=\"btn btn-sm btn-link px-1 py-0\" sqTooltip=\"More tokens\" (click)=\"chatService.increaseChunksSync(attachment)\">\n          <i class=\"fas fa-plus\"></i>\n        </button>\n        <button class=\"btn btn-sm btn-link py-0\" sqTooltip=\"Remove\" (click)=\"chatService.removeAttachment(attachment)\">\n          <i class=\"fas fa-trash\"></i>\n        </button>\n      </div>\n\n    </li>\n  </ul>\n</ng-template>\n","import { Component, EventEmitter, Input, Output } from \"@angular/core\";\nimport { ChatConfig, defaultChatConfig } from \"./chat.component\";\nimport { ChatService } from \"./chat.service\";\n\n@Component({\n    selector: 'sq-chat-settings',\n    templateUrl: './chat-settings.component.html',\n    standalone: false\n})\nexport class ChatSettingsComponent {\n  @Input() config: ChatConfig;\n  @Output(\"reset\") _reset = new EventEmitter();\n\n  constructor(\n    public chatService: ChatService\n  ) {}\n\n  reset() {\n    Object.assign(this.config, defaultChatConfig);\n    this._reset.emit();\n  }\n}\n","\n<div class=\"card-body small\">\n\n  <h5>Model</h5>\n  <div class=\"mb-2\">\n    <label for=\"gllmModel\" class=\"form-label\">Model</label>\n    <select class=\"form-select\" id=\"gllmModel\" [(ngModel)]=\"config.model\">\n      <option *ngFor=\"let model of chatService.models\" [ngValue]=\"model.name\">{{model.displayName}}</option>\n    </select>\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"temperature\" class=\"form-label\">Temperature: {{config.temperature}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"2\" step=\"0.1\" id=\"temperature\" [(ngModel)]=\"config.temperature\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"top-p\" class=\"form-label\">Top P: {{config.topP}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"1\" step=\"0.05\" id=\"top-p\" [(ngModel)]=\"config.topP\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"max-tokens\" class=\"form-label\">Max generated tokens per answer: {{config.maxTokens}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"1\" max=\"2048\" step=\"1\" id=\"max-tokens\" [(ngModel)]=\"config.maxTokens\">\n  </div>\n  <div class=\"mb-2\" *ngIf=\"config.model === 'Chat-Bison-001'\">\n    <label for=\"googleContextPrompt\" class=\"form-label\">Google context prompt</label>\n    <textarea class=\"form-control\" id=\"googleContextPrompt\" [(ngModel)]=\"config.googleContextPrompt\"></textarea>\n  </div>\n  <div class=\"form-check form-switch mb-2\">\n    <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"stream\" [(ngModel)]=\"config.stream\">\n    <label class=\"form-check-label\" for=\"stream\">Stream messages</label>\n  </div>\n\n  <h5>UI</h5>\n  <div class=\"form-check form-switch mb-2\">\n    <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"textBeforeAttachments\" [(ngModel)]=\"config.textBeforeAttachments\">\n    <label class=\"form-check-label\" for=\"textBeforeAttachments\">Send text before attachments</label>\n  </div>\n  <div class=\"form-check form-switch mb-2\">\n    <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"displayAttachments\" [(ngModel)]=\"config.displayAttachments\">\n    <label class=\"form-check-label\" for=\"displayAttachments\">Display attachments in the chat conversation</label>\n  </div>\n\n  <h5>Prompts</h5>\n  <div class=\"mb-2\">\n    <label for=\"initialSystemPrompt\" class=\"form-label\">Initial system prompt (hidden)</label>\n    <textarea class=\"form-control\" id=\"initialSystemPrompt\" [(ngModel)]=\"config.initialSystemPrompt\"></textarea>\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"initialUserPrompt\" class=\"form-label\">Initial user prompt</label>\n    <textarea class=\"form-control\" id=\"initialUserPrompt\" [(ngModel)]=\"config.initialUserPrompt\"></textarea>\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"addAttachmentPrompt\" class=\"form-label\">Default prompt when adding an attachment</label>\n    <textarea class=\"form-control\" id=\"addAttachmentPrompt\" [(ngModel)]=\"config.addAttachmentPrompt\"></textarea>\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"addAttachmentsPrompt\" class=\"form-label\">Default prompt when adding multiple attachments</label>\n    <textarea class=\"form-control\" id=\"addAttachmentsPrompt\" [(ngModel)]=\"config.addAttachmentsPrompt\"></textarea>\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"attachmentsHiddenPrompt\" class=\"form-label\">Hidden prompt inserted after a list of attachments to given special instructions/guidance</label>\n    <textarea class=\"form-control\" id=\"attachmentsHiddenPrompt\" [(ngModel)]=\"config.attachmentsHiddenPrompt\"></textarea>\n  </div>\n\n  <h5>Auto-search</h5>\n\n  <h6>Top passages <i class=\"fas fa-info-circle\" sqTooltip=\"Top passages (aka 'Neural search suggested answer') are selected by Neural Search for their semantic correlation with the user query.\"></i></h6>\n  <div class=\"mb-2\">\n    <label for=\"maxTopPassages\" class=\"form-label\">Maximum number of top passages: {{config.maxTopPassages}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"10\" step=\"1\" id=\"maxTopPassages\" [(ngModel)]=\"config.maxTopPassages\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"minScoreTopPassage\" class=\"form-label\">Minimum top passage score: {{config.minScoreTopPassage}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"1\" step=\"0.05\" id=\"minScoreTopPassage\" [(ngModel)]=\"config.minScoreTopPassage\">\n  </div>\n\n  <h6>Top documents  <i class=\"fas fa-info-circle\" sqTooltip=\"Top documents contain the most relevant passages retrieved by Neural Search.\"></i></h6>\n  <div class=\"mb-2\">\n    <label for=\"maxDocuments\" class=\"form-label\">Maximum number of top documents: {{config.maxDocuments}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"10\" step=\"1\" id=\"maxDocuments\" [(ngModel)]=\"config.maxDocuments\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"minDocumentRelevance\" class=\"form-label\">Minimum relevance of top documents: {{config.minDocumentRelevance}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"1\" step=\"0.05\" id=\"minDocumentRelevance\" [(ngModel)]=\"config.minDocumentRelevance\">\n  </div>\n\n  <h6>Attachment composition</h6>\n  <div class=\"mb-2\">\n    <label for=\"startLengthPerDocument\" class=\"form-label\">First n characters of the document: n = {{config.startLengthPerDocument}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"4000\" step=\"100\" id=\"startLengthPerDocument\" [(ngModel)]=\"config.startLengthPerDocument\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"maxExtractsPerDocument\" class=\"form-label\">Top relevant extracts <i class=\"fas fa-info-circle\" sqTooltip=\"An extract is a sentence containing keywords from the user query\"></i>: {{config.maxExtractsPerDocument}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"10\" step=\"1\" id=\"maxExtractsPerDocument\" [(ngModel)]=\"config.maxExtractsPerDocument\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"maxPassagesPerDocument\" class=\"form-label\">Top relevant passages <i class=\"fas fa-info-circle\" sqTooltip=\"A passage is a piece of text (a few sentences long) indexed by Neural Search\"></i>: {{config.maxPassagesPerDocument}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"10\" step=\"1\" id=\"maxPassagesPerDocument\" [(ngModel)]=\"config.maxPassagesPerDocument\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"extendBefore\" class=\"form-label\">Expand <b>before</b> each snippet with n sentences: {{config.extendBefore}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"10\" step=\"1\" id=\"extendBefore\" [(ngModel)]=\"config.extendBefore\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"extendAfter\" class=\"form-label\">Expand <b>after</b> each snippet with n sentences: {{config.extendAfter}}</label>\n    <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"10\" step=\"1\" id=\"extendAfter\" [(ngModel)]=\"config.extendAfter\">\n  </div>\n  <div class=\"mb-2\">\n    <label for=\"attachment-metadata\" class=\"form-label\">Metadata</label>\n    <select class=\"form-select\" id=\"attachment-metadata\" [(ngModel)]=\"chatService.attachmentMetadata\" multiple>\n      <option *ngFor=\"let option of chatService.availableAttachmentMetadata\" [ngValue]=\"option.field\">\n        {{option.name ?? option.field}}\n      </option>\n    </select>\n  </div>\n\n  <button class=\"btn btn-primary\" (click)=\"reset()\">Reset configuration</button>\n</div>\n","import { Component, EventEmitter, Output } from \"@angular/core\";\nimport { AuditWebService } from \"@sinequa/core/web-services\";\nimport { ChatService } from \"./chat.service\";\nimport { SavedChat } from \"./types\";\n\n@Component({\n    selector: 'sq-saved-chats',\n    template: `\n  <ul class=\"list-group list-group-flush rounded-4\">\n    <li *ngFor=\"let chat of chatService.savedChats\"\n      class=\"d-flex align-items-center list-group-item list-group-item-action\">\n      <a class=\"flex-grow-1\" role=\"button\" (click)=\"onLoad(chat)\">\n        {{chat.name}}\n      </a>\n      <button class=\"btn btn-link\" (click)=\"delete(chat);\">\n        <i class=\"fas fa-times\"></i>\n      </button>\n    </li>\n  </ul>\n  `,\n    standalone: false\n})\nexport class SavedChatsComponent {\n  @Output() load = new EventEmitter<SavedChat>();\n\n  constructor(\n    public chatService: ChatService,\n    public auditService: AuditWebService\n  ){}\n\n  onLoad(chat: SavedChat) {\n    this.load.emit(chat);\n    this.auditService.notify({\n      type: \"Chat_Open\",\n      detail: {\n        chat: chat.name\n      }\n    });\n  }\n\n  delete(chat: SavedChat) {\n    this.chatService.deleteSavedChat(chat.name);\n  }\n\n}\n","import { CommonModule } from \"@angular/common\";\nimport { NgModule } from \"@angular/core\";\nimport { FormsModule } from \"@angular/forms\";\nimport { RemarkModule } from \"ngx-remark\";\n\nimport { ResultModule } from \"@sinequa/components/result\";\nimport { UtilsModule } from \"@sinequa/components/utils\";\nimport { IntlModule } from \"@sinequa/core/intl\";\nimport { BsActionModule } from \"@sinequa/components/action\";\n\nimport { AnswerCardComponent } from \"./answer-card.component\";\nimport { PassageListComponent } from \"./passage-list.component\";\nimport { TopPassagesComponent } from \"./top-passages/top-passages.component\";\n\nimport { ChatComponent } from \"./chat/chat.component\";\nimport { ChatSettingsComponent } from \"./chat/chat-settings.component\";\nimport { SavedChatsComponent } from \"./chat/saved-chats.component\";\nimport { ChatMessageComponent } from \"./chat/chat-message.component\";\n\n\n@NgModule({\n    imports: [\n        CommonModule,\n        ResultModule,\n        IntlModule,\n        UtilsModule,\n        FormsModule,\n        BsActionModule,\n        RemarkModule\n    ],\n    declarations: [\n        AnswerCardComponent,\n        PassageListComponent,\n        TopPassagesComponent,\n        ChatComponent,\n        ChatMessageComponent,\n        ChatSettingsComponent,\n        SavedChatsComponent\n    ],\n    exports: [\n        AnswerCardComponent,\n        PassageListComponent,\n        TopPassagesComponent,\n        ChatComponent,\n        ChatSettingsComponent,\n        SavedChatsComponent\n    ]\n})\nexport class MLModule {\n}\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, inject } from '@angular/core';\nimport { UtilsModule } from '@sinequa/components/utils';\nimport { IntlModule } from '@sinequa/core/intl';\nimport { DocumentSimilarityService, SimilarDocument, SimilarityParams } from '@sinequa/core/web-services';\nimport { BehaviorSubject, catchError, combineLatest, filter } from 'rxjs';\n\nexport type OptionsProps = {\n  params?: SimilarityParams,\n  expand?: string[]\n};\n\n@Component({\n    selector: 'sq-similar-documents',\n    imports: [CommonModule, UtilsModule, IntlModule],\n    template: `\n    <ng-container *ngIf=\"similarDocuments && similarDocuments.length > 0; else noSimilarDocuments\">\n      <li *ngFor=\"let document of similarDocuments\" (click)=\"handleClick(document)\" class=\"similar-document d-flex mb-2\">\n        <span role=\"button\" class=\"similarDocument link-primary\">{{ document.doc.title }}</span>\n      </li>\n    </ng-container>\n    <ng-template #noSimilarDocuments>\n      <p class=\"fst-italic text-muted\">{{ 'msg#machine-learning.similarDocumentsNotFound' | sqMessage }}</p>\n    </ng-template>\n  `,\n    styles: [`\n    :host {\n      display: block;\n    }\n  `],\n    changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SimilarDocumentsComponent implements OnInit {\n  cdr = inject(ChangeDetectorRef);\n  similarityService = inject(DocumentSimilarityService);\n\n  /**\n   * Array of similar documents.\n   */\n  similarDocuments: SimilarDocument[];\n\n\n  _documentId$ = new BehaviorSubject(\"\");\n  _queryName$ = new BehaviorSubject(\"\");\n  _options$ = new BehaviorSubject<OptionsProps>({});\n\n  /**\n   * Event emitted when a document is clicked.\n   *\n   * @event documentClick\n   * @type {EventEmitter<SimilarDocument>}\n   */\n  @Output() documentClick = new EventEmitter<SimilarDocument>();\n\n  /**\n   * Sets the query name.\n   * @param value The new value for the query name.\n   */\n  @Input() set queryName(value: string) {\n    this._queryName$.next(value);\n  }\n\n  /**\n   * Sets the document ID.\n   *\n   * @param value - The document ID value.\n   */\n  @Input() set documentId(id: string) {\n    this._documentId$.next(id);\n  }\n\n  /**\n   * Setter for the options property.\n   * @param value - The options object.\n   */\n  @Input() set options(value: OptionsProps) {\n    this._options$.next(value);\n  }\n\n  /**\n   * Initializes the component and subscribes to changes in documentId, queryName, and options.\n   * Fetches similar documents based on the provided inputs.\n   */\n  ngOnInit(): void {\n    // subscribe to changes in documentId, queryName and options, just after the component is initialized\n    // not in the constructor, because the inputs are not available yet\n    combineLatest([this._documentId$, this._queryName$, this._options$])\n      .pipe(filter(([documentId, queryName]) => !!documentId && !!queryName))\n      .subscribe(([documentId, queryName, options]) => {\n        this.fetchSimilarDocuments(documentId, queryName, options);\n      });\n  }\n\n  /**\n   * Fetches similar documents based on the provided document ID and query name.\n   *\n   * @param documentId - The ID of the document.\n   * @param queryName - The name of the query.\n   * @param options - Optional parameters for the similarity service.\n   */\n  fetchSimilarDocuments(documentId: string, queryName: string, options?: OptionsProps) {\n    this.similarityService.get(documentId, queryName, options)\n    .pipe(catchError((error) => {\n      this.similarDocuments = [];\n      this.cdr.detectChanges();\n      return [];\n    }))\n    .subscribe((response) => {\n      this.similarDocuments = response;\n      this.cdr.detectChanges();\n    });\n  }\n\n  /**\n   * Handles the click event for a document.\n   * @param document - The document that was clicked.\n   */\n  handleClick(document: SimilarDocument) {\n    this.documentClick.emit(document);\n  }\n}\n","export default {\r\n  \"machine-learning\": {\r\n    \"passage\": \"{items, plural, =1 {Answer} other {Answers}} {current}/{length, number}\",\r\n    \"passagesFound\": \"{passagesNb} {passagesNb, plural, =1 {answer} other {answers}} found in {documentsNb} {documentsNb, plural, =1 {document} other {documents}}\",\r\n    \"passages\": \"Neural Search Suggested Answers\",\r\n    \"answers\": \"Suggested answers\",\r\n    \"answersCollapsed\": \"I found {answersNb, number} suggested answers\",\r\n    \"answer\": \"Suggested answer\",\r\n    \"similarDocuments\": \"Similar Documents\",\r\n    \"similarDocumentsNotFound\": \"No similar documents found\"\r\n  }\r\n}","export default {\r\n  \"machine-learning\": {\r\n    \"passage\": \"{items, plural, =1 {Réponse} other {Réponses}} {current}/{length, number}\",\r\n    \"passagesFound\": \"{passagesNb} {passagesNb, plural, =1 {réponse trouvée} other {réponses trouvées}} dans {documentsNb} {documentsNb, plural, =1 {document} other {documents}}\",\r\n    \"passages\": \"Réponses suggérées par Neural Search\",\r\n    \"answers\": \"Réponses suggérées\",\r\n    \"answersCollapsed\": \"J'ai trouvé {answersNb, number} réponses suggérées\",\r\n    \"answer\": \"Réponse suggérée\",\r\n    \"similarDocuments\": \"Documents similaires\",\r\n    \"similarDocumentsNotFound\": \"Aucun document similaire trouvé\"\r\n  }\r\n}","export default {\r\n  \"machine-learning\": {\r\n    \"passage\": \"{items, plural, =1 {Antwort} other {Antworten}} {current}/{length, number}\",\r\n    \"passagesFound\": \"{passagesNb} {passagesNb, plural, =1 {Antwort} other {Antworten}} in {documentsNb} {documentsNb, plural, =1 {Dokument} other {Dokumenten}} gefunden\",\r\n    \"passages\": \"Neural Search Vorgeschlagene Antworten\",\r\n    \"answers\": \"Vorgeschlagene Antworten\",\r\n    \"answersCollapsed\": \"Ich habe {answersNb, number} vorgeschlagene Antworten gefunden\",\r\n    \"answer\": \"Vorgeschlagene Antwort\",\r\n    \"similarDocuments\": \"Ähnliche Dokumente\",\r\n    \"similarDocumentsNotFound\": \"Keine ähnlichen Dokumente gefunden\"\r\n  }\r\n}","import { Utils } from '@sinequa/core/base';\r\nimport _enML from './en';\r\nimport _frML from './fr';\r\nimport _deML from './de';\r\n\r\nconst enML = Utils.merge({}, _enML);\r\nconst frML = Utils.merge({}, _frML);\r\nconst deML = Utils.merge({}, _deML);\r\n\r\nexport { enML, frML, deML };","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2","i3","i5","i7","i4","i6","i1.ChatService","i6.ChatMessageComponent"],"mappings":"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"}