feat: add @goose off commands to disable AI

Added support for turning AI off after enabling it:

useChatEngine.ts:
- Added detection for @goose off/disable/stop/quiet/sleep commands
- When AI is enabled and user sends @goose off, AI gets disabled
- Message is added to chat without triggering AI response
- Console logging shows when AI is disabled

EnhancedMentionPopover.tsx:
- Added multiple @goose command options in autocomplete:
  - @goose (enable AI)
  - @goose off (disable AI)
  - @goose stop (stop AI)
  - @goose quiet (make AI quiet)
- Updated icons to show different emojis for off commands (🦆💤)
- All goose commands get green styling and 'Mention' action hint

Now users can:
1. Start DM (AI disabled by default)
2. Send @goose to enable AI
3. Send @goose off to disable AI again
4. Autocomplete shows all available @goose commands
This commit is contained in:
spencrmartin
2025-11-17 16:26:52 -05:00
parent 8e84a0c1f9
commit e6656b9288
2 changed files with 72 additions and 19 deletions
@@ -84,19 +84,44 @@ const EnhancedMentionPopover = forwardRef<
const mentionItems = useMemo((): MentionItem[] => {
const items: MentionItem[] = [];
// Add "goose" as a special mention for AI reinitialization
const gooseScore = fuzzyMatch(query, 'goose');
if (gooseScore > 0 || !query.trim()) {
items.push({
id: 'goose',
type: 'friend', // Use friend type for consistent styling
name: 'goose',
displayText: 'goose',
secondaryText: 'Reinitialize AI assistance',
userId: 'goose',
matchScore: gooseScore + 100, // Highest priority for goose
});
}
// Add "goose" commands as special mentions for AI control
const gooseCommands = [
{
command: 'goose',
description: 'Enable AI assistance',
emoji: '🦆'
},
{
command: 'goose off',
description: 'Disable AI assistance',
emoji: '🦆💤'
},
{
command: 'goose stop',
description: 'Stop AI assistance',
emoji: '🦆🛑'
},
{
command: 'goose quiet',
description: 'Make AI quiet',
emoji: '🦆🤫'
}
];
gooseCommands.forEach(({ command, description, emoji }) => {
const score = fuzzyMatch(query, command);
if (score > 0 || !query.trim()) {
items.push({
id: command,
type: 'friend', // Use friend type for consistent styling
name: command,
displayText: command,
secondaryText: description,
userId: command,
matchScore: score + 100, // Highest priority for goose commands
});
}
});
// Add friends (prioritize if connected)
if (isConnected && friends.length > 0) {
@@ -251,9 +276,12 @@ const EnhancedMentionPopover = forwardRef<
{/* Icon */}
<div className="flex-shrink-0">
{item.type === 'friend' ? (
item.userId === 'goose' ? (
item.userId?.startsWith('goose') ? (
<div className="w-6 h-6 bg-green-500 rounded-full flex items-center justify-center">
<span className="text-white text-xs font-bold">🦆</span>
<span className="text-white text-xs">
{item.userId === 'goose' ? '🦆' :
item.userId.includes('off') || item.userId.includes('stop') || item.userId.includes('quiet') ? '🦆💤' : '🦆'}
</span>
</div>
) : (
<div className="w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center">
@@ -286,11 +314,11 @@ const EnhancedMentionPopover = forwardRef<
<div className={`text-xs px-2 py-1 rounded ${
index === selectedIndex
? 'bg-text-on-accent/20 text-text-on-accent'
: item.userId === 'goose'
: item.userId?.startsWith('goose')
? 'bg-green-100 text-green-600'
: 'bg-blue-100 text-blue-600'
}`}>
{item.userId === 'goose' ? 'Mention' : 'Invite'}
{item.userId?.startsWith('goose') ? 'Mention' : 'Invite'}
</div>
)}
</div>
+27 -2
View File
@@ -185,8 +185,33 @@ export const useChatEngine = ({
: '';
const containsGooseMention = /@goose\b/i.test(messageText);
// If @goose is mentioned, enable AI for this session
if (containsGooseMention && !aiEnabled) {
// Check for @goose off/disable/stop commands
const gooseOffPattern = /@goose\s+(off|disable|stop|quiet|sleep)\b/i;
const isGooseOffCommand = gooseOffPattern.test(messageText);
// If @goose off is mentioned, disable AI for this session
if (isGooseOffCommand && aiEnabled) {
console.log('🦆💤 @goose off mentioned - disabling AI for session:', {
sessionId: chat.sessionId,
messageId: message.id,
contentPreview: messageText.substring(0, 50) + '...'
});
// Update the chat to disable AI
setChat((prevChat: ChatType) => ({ ...prevChat, aiEnabled: false }));
// Add the message to the chat without triggering AI response
setMessages(prevMessages => [...prevMessages, message]);
// Store in history if it's a user message
storeMessageInHistory(message);
// Return a promise that resolves immediately (to match originalAppend's interface)
return Promise.resolve();
}
// If @goose is mentioned (but not an off command), enable AI for this session
if (containsGooseMention && !isGooseOffCommand && !aiEnabled) {
console.log('🦆 @goose mentioned - enabling AI for session:', {
sessionId: chat.sessionId,
messageId: message.id,