workspaceMentions.ts 1.3 KB

1234567891011121314151617181920212223242526
  1. import type { WorkspaceAgent as Agent } from '../shared/workspace.js'
  2. export function mentionableText(text: string): string {
  3. return text
  4. .replace(/<quoted_message\b[^>]*>[\s\S]*?<\/quoted_message>/gi, '')
  5. .replace(/```[\s\S]*?(?:```|$)|~~~[\s\S]*?(?:~~~|$)/g, '')
  6. .replace(/`[^`]*`/g, '')
  7. .replace(/https?:\/\/\S+/g, '')
  8. .replace(/[\p{L}\p{N}._%+-]{1,64}@[\p{L}\p{N}.-]{1,255}\.[\p{L}]{2,63}/gu, '')
  9. .split('\n').filter(line => !line.trimStart().startsWith('>')).join('\n')
  10. }
  11. export function mentionedAgents(text: string, agents: Array<Pick<Agent, 'id' | 'name'>>): string[] {
  12. if (!text.includes('@')) return []
  13. const plain = mentionableText(text)
  14. const names = [...agents].sort((a, b) => b.name.length - a.name.length)
  15. const alternatives = [...names.map(a => a.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')), 'all', '所有人']
  16. const pattern = new RegExp(`(?<![A-Za-z0-9_.%+/@-])@(${alternatives.join('|')})(?![A-Za-z0-9_])`, 'giu')
  17. const result = new Set<string>()
  18. for (const match of plain.matchAll(pattern)) {
  19. const name = match[1]!
  20. if (/^(all|所有人)$/i.test(name)) { for (const a of agents) result.add(a.id) }
  21. else { const a = agents.find(a => a.name.toLocaleLowerCase() === name.toLocaleLowerCase()); if (a) result.add(a.id) }
  22. }
  23. return [...result]
  24. }