@c4t4/heyamigo 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -182,6 +182,7 @@ export async function processIncomingMessage(incoming, opts = {}) {
182
182
  const trigger = checkTrigger({
183
183
  mode: decision.triggerMode,
184
184
  text: stored.text,
185
+ audioTranscript: audioTranscript ?? undefined,
185
186
  mentionedBot: incoming.triggerHints?.mentionedBot,
186
187
  replyToBot: incoming.triggerHints?.replyToBot,
187
188
  });
@@ -1,4 +1,68 @@
1
1
  import { config } from '../config.js';
2
+ const AUDIO_ALIAS_VARIANTS = {
3
+ heyamigo: [
4
+ 'hey amigo',
5
+ 'hey amigos',
6
+ 'hey amego',
7
+ 'hey amico',
8
+ 'hey a migo',
9
+ 'hay amigo',
10
+ 'hi amigo',
11
+ ],
12
+ amigo: [
13
+ 'a migo',
14
+ 'amego',
15
+ 'amico',
16
+ 'amigos',
17
+ 'amiga',
18
+ 'migo',
19
+ ],
20
+ claude: [
21
+ 'cloud',
22
+ 'clawd',
23
+ 'clawed',
24
+ 'clod',
25
+ 'clode',
26
+ 'cload',
27
+ 'clout',
28
+ 'claut',
29
+ 'clause',
30
+ 'claus',
31
+ ],
32
+ clawd: [
33
+ 'claude',
34
+ 'cloud',
35
+ 'clawed',
36
+ 'clod',
37
+ 'clode',
38
+ 'cload',
39
+ 'clout',
40
+ 'claut',
41
+ ],
42
+ grok: [
43
+ 'grock',
44
+ 'grog',
45
+ 'gronk',
46
+ 'grawk',
47
+ 'groc',
48
+ ],
49
+ codex: [
50
+ 'code x',
51
+ 'codec',
52
+ 'codecs',
53
+ 'codecks',
54
+ 'codicks',
55
+ 'kodeks',
56
+ 'codacs',
57
+ ],
58
+ xai: [
59
+ 'x ai',
60
+ 'x a i',
61
+ 'ex ai',
62
+ 'ex a i',
63
+ 'x.ai',
64
+ ],
65
+ };
2
66
  function escapeRegex(s) {
3
67
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
4
68
  }
@@ -10,6 +74,50 @@ function aliasMatches(text, aliases) {
10
74
  }
11
75
  return null;
12
76
  }
77
+ function normalizeAudioText(text) {
78
+ return text
79
+ .toLowerCase()
80
+ .normalize('NFKD')
81
+ .replace(/[\u0300-\u036f]/g, '')
82
+ .replace(/[^a-z0-9]+/g, ' ')
83
+ .trim()
84
+ .replace(/\s+/g, ' ');
85
+ }
86
+ function phraseMatches(normalizedText, phrase) {
87
+ const normalizedPhrase = normalizeAudioText(phrase);
88
+ if (!normalizedPhrase)
89
+ return false;
90
+ const re = new RegExp(`(^| )${escapeRegex(normalizedPhrase)}($| )`, 'i');
91
+ return re.test(normalizedText);
92
+ }
93
+ function wakePhraseMatches(normalizedText, phrase) {
94
+ const normalizedPhrase = normalizeAudioText(phrase);
95
+ if (!normalizedPhrase)
96
+ return false;
97
+ const wake = '(hey|hi|hello|yo|ok|okay|oye|hola)';
98
+ const re = new RegExp(`(^| )${wake} ${escapeRegex(normalizedPhrase)}($| )`, 'i');
99
+ return re.test(normalizedText);
100
+ }
101
+ function audioAliasMatches(transcript, aliases) {
102
+ const normalizedTranscript = normalizeAudioText(transcript);
103
+ if (!normalizedTranscript)
104
+ return null;
105
+ for (const alias of aliases) {
106
+ const normalizedAlias = normalizeAudioText(alias);
107
+ if (phraseMatches(normalizedTranscript, normalizedAlias)) {
108
+ return { alias, variant: normalizedAlias };
109
+ }
110
+ const variants = new Set([
111
+ ...(AUDIO_ALIAS_VARIANTS[normalizedAlias] ?? []),
112
+ ]);
113
+ for (const variant of variants) {
114
+ if (wakePhraseMatches(normalizedTranscript, variant)) {
115
+ return { alias, variant: normalizeAudioText(variant) };
116
+ }
117
+ }
118
+ }
119
+ return null;
120
+ }
13
121
  export function checkTrigger(params) {
14
122
  const { mode, text } = params;
15
123
  if (mode === 'off')
@@ -27,6 +135,15 @@ export function checkTrigger(params) {
27
135
  const alias = aliasMatches(text, config.triggers.aliases);
28
136
  if (alias)
29
137
  return { triggered: true, reason: `alias:${alias}` };
138
+ const audioAlias = params.audioTranscript
139
+ ? audioAliasMatches(params.audioTranscript, config.triggers.aliases)
140
+ : null;
141
+ if (audioAlias) {
142
+ return {
143
+ triggered: true,
144
+ reason: `audio-alias:${audioAlias.alias}~${audioAlias.variant}`,
145
+ };
146
+ }
30
147
  // 2. Channel-provided mention signal, e.g. WhatsApp @mention or
31
148
  // Telegram bot username mention.
32
149
  if (params.mentionedBot)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c4t4/heyamigo",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "WhatsApp and Telegram AI bot powered by Claude, Codex, or Grok with long-term memory, browser control, and role-based access",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",