messageDisplay.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132
  1. const ATTACHED_CONTEXT_MARKER_RE = /(?:^|\n)--- Attached Context ---\s*\n/
  2. const CONTEXT_WARNINGS_MARKER_RE = /(?:^|\n)--- Context Warnings ---[\s\S]*$/
  3. const CONTEXT_REF_RE = /@(file|folder|url|image|tool|terminal):(?:"[^"\n]+"|'[^'\n]+'|`[^`\n]+`|\S+)/g
  4. /**
  5. * Project persisted message content into the text shown to a person.
  6. *
  7. * Hermes deliberately keeps expanded reference payloads in the stored user
  8. * message so the model can consume them. Those payloads are transport data,
  9. * not part of the user's visible transcript. Keep the raw content in state and
  10. * apply this projection only at display/copy boundaries.
  11. */
  12. export function displayContentForMessage(role: string, content: string): string {
  13. if (role !== 'user') return content
  14. const marker = content.match(ATTACHED_CONTEXT_MARKER_RE)
  15. if (!marker || marker.index === undefined) {
  16. return content.replace(CONTEXT_WARNINGS_MARKER_RE, '').trim()
  17. }
  18. const visibleText = content
  19. .slice(0, marker.index)
  20. .replace(CONTEXT_WARNINGS_MARKER_RE, '')
  21. .trim()
  22. const attachedContext = content.slice(marker.index + marker[0].length)
  23. const references = [...new Set(
  24. Array.from(attachedContext.matchAll(CONTEXT_REF_RE), match => match[0]),
  25. )]
  26. const missingReferences = references.filter(reference => !visibleText.includes(reference))
  27. return [missingReferences.join('\n'), visibleText].filter(Boolean).join('\n\n') || visibleText
  28. }