Skip to content

Commit

Permalink
Merge pull request #148 from Cloud-Code-AI/147-add-tts-support-in-chr…
Browse files Browse the repository at this point in the history
…ome-extension

147 add tts support in chrome extension
  • Loading branch information
sauravpanda authored Feb 27, 2025
2 parents 8736de7 + ebef29b commit ab87396
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 3 deletions.
53 changes: 52 additions & 1 deletion extensions/chrome/src/helpers/executors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ const nodeExecutors = {
truncatedPrompt,
{
temperature: node.nodeData?.temperature || 0.7,
max_tokens: node.nodeData?.maxTokens || 2048
max_tokens: node.nodeData?.maxTokens || 2048,
system_prompt: node.nodeData?.systemPrompt
}
);

Expand Down Expand Up @@ -215,6 +216,11 @@ const nodeExecutors = {
'transcriptionAgent': async (node: WorkflowStep, input: any, params?: ExecuteWorkflowParams) => {
try {
console.debug("transcription-agent", node, input);

// Throw a specific error for speech transcription in Chrome extension
throw new Error("Speech transcription models are not supported in the Chrome extension. Please use the web app version instead.");

// The code below will not execute due to the error above
const browserAI = new BrowserAI();

await browserAI.loadModel(node.nodeData?.model || 'whisper-tiny-en', {
Expand Down Expand Up @@ -246,6 +252,51 @@ const nodeExecutors = {
throw error;
}
},

'ttsAgent': async (node: WorkflowStep, input: any, params?: ExecuteWorkflowParams) => {
try {
console.debug("tts-agent", node, input);

// Throw a specific error for TTS in Chrome extension
throw new Error("Text-to-speech models are not supported in the Chrome extension. Please use the web app version instead.");

// The code below will not execute due to the error above
const browserAI = new BrowserAI();

await browserAI.loadModel(node.nodeData?.model || 'kokoro-tts', {
onProgress: (progress: any) => {
const progressPercent = progress.progress || 0;
const eta = progress.eta || 0;
params?.onModelLoadProgress?.(progressPercent * 100, eta);
}
});

// Extract text input
if (!input) {
throw new Error('No text input provided to TTS agent');
}

// Generate speech
const audioData = await browserAI.textToSpeech(input, {
voice: node.nodeData?.voice || 'af_bella'
});

// Create blob with proper MIME type
const blob = new Blob([audioData], { type: 'audio/wav' });

// Create and store blob URL
const audioUrl = URL.createObjectURL(blob);

return {
success: true,
output: audioUrl,
log: `Text-to-speech generated successfully using ${node.nodeData?.model || 'bark-small'}`
};
} catch (error) {
console.error('TTSAgent error:', error);
throw error;
}
},
};

export const executeWorkflow = async ({
Expand Down
38 changes: 37 additions & 1 deletion extensions/chrome/src/popup/workflow-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,27 @@ export function WorkflowView({ workflow, onBack }: WorkflowViewProps) {
const [modelLoadProgress, setModelLoadProgress] = useState<number | null>(null);
const [modelLoadEta, setModelLoadEta] = useState<number | null>(null);

// Add this function to check for unsupported nodes
const hasUnsupportedNodes = () => {
return nodes.some(node =>
node.nodeType?.toLowerCase() === 'ttsagent' ||
node.nodeType?.toLowerCase() === 'transcriptionagent'
);
};

// Get the unsupported node warning message
const getUnsupportedWarningMessage = () => {
const unsupportedTypes = nodes
.filter(node =>
node.nodeType?.toLowerCase() === 'ttsagent' ||
node.nodeType?.toLowerCase() === 'transcriptionagent'
)
.map(node => node.nodeType?.toLowerCase() === 'ttsagent' ? 'Text-to-Speech' : 'Speech Transcription');

const uniqueTypes = [...new Set(unsupportedTypes)];
return `${uniqueTypes.join(' and ')} ${uniqueTypes.length > 1 ? 'are' : 'is'} not supported in the Chrome extension. Please use the web app version instead.`;
};

useEffect(() => {
console.log('Workflow data received:', workflow);
console.log('Initial nodes:', nodes);
Expand All @@ -71,6 +92,15 @@ export function WorkflowView({ workflow, onBack }: WorkflowViewProps) {
fullNodeData: JSON.stringify(node.nodeData, null, 2)
});
});

// Show toast warning if workflow contains unsupported nodes
if (hasUnsupportedNodes()) {
toast({
variant: "destructive",
title: "Unsupported workflow",
description: getUnsupportedWarningMessage()
});
}
}, []);

// Update areAllInputsFilled function
Expand Down Expand Up @@ -273,7 +303,7 @@ export function WorkflowView({ workflow, onBack }: WorkflowViewProps) {
<div className="flex items-center gap-8">
<Button
onClick={handleExecute}
disabled={isExecuting || !areAllInputsFilled()}
disabled={isExecuting || !areAllInputsFilled() || hasUnsupportedNodes()}
className="flex items-center gap-2"
>
<Play className="h-4 w-4" />
Expand All @@ -283,6 +313,12 @@ export function WorkflowView({ workflow, onBack }: WorkflowViewProps) {
</div>

<div className="flex-1 overflow-y-auto">
{hasUnsupportedNodes() && (
<div className="p-3 bg-destructive/10 text-destructive text-sm mb-2 mx-4 mt-4 rounded-md">
<strong>Warning:</strong> {getUnsupportedWarningMessage()}
</div>
)}

{modelLoadProgress !== null && (
<div className="p-2 bg-primary/10 text-primary text-sm sticky top-0 z-10">
<div className="flex items-center gap-2">
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@browserai/browserai",
"version": "1.0.29",
"version": "1.0.30",
"private": false,
"description": "A library for running AI models directly in the browser",
"main": "dist/index.js",
Expand Down

0 comments on commit ab87396

Please sign in to comment.