Skip to content

Commit

Permalink
Updated apps to use the up-to-date Gemini Nano API
Browse files Browse the repository at this point in the history
  • Loading branch information
ToonTalk committed Sep 4, 2024
1 parent 7033cd9 commit dfa2d66
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 74 deletions.
55 changes: 28 additions & 27 deletions apps/Connections-v2/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,14 @@ document.getElementById('initializeGame').addEventListener('click', async functi
break;
case 'gemini':
result = await geminiNano(fullPrompt);
if (result === undefined) { // Assume geminiNano() handles its own errors
throw new Error("Session creation or prompt failed in Gemini Nano.");
}
break;
default:
throw new Error("Unsupported AI provider selected.");
}
handleApiResponse(result);
} catch (error) {
// Specific error handling for Gemini Nano or other API errors
console.error('Error during API interaction:', error);
// Only update the status message if it's not already set by the API-specific function
if (document.getElementById('statusMessage').textContent === "") {
updateStatusMessage(error.message, "invalid-message");
}
updateStatusMessage(error.message, "invalid-message");
} finally {
hideLoadingIcon();
}
Expand Down Expand Up @@ -358,36 +351,44 @@ function updateGameWithCategories(categories) {

let aiSession = null; // Global variable to hold the session

async function geminiNano(prompt) {
if (!aiSession) { // Check if session exists
try {
let canCreateSession = await window.ai.canCreateTextSession();
if (canCreateSession === "no") {
// Inform the user and provide a link to the documentation
const statusMessage = document.getElementById('statusMessage');
statusMessage.innerHTML = 'Unable to create an AI session. Please refer to the <a href="https://docs.google.com/document/d/1VG8HIyz361zGduWgNG7R_R8Xkv0OOJ8b5C9QKeCjU0c/edit?pli=1#heading=h.5s2qlonhpm36" target="_blank">documentation</a> for more information.';
statusMessage.className = 'invalid-message';
throw new Error("Session creation denied."); // Abort the function by throwing an error
}
aiSession = await window.ai.createTextSession(); // Create a session if possible
} catch (error) {
// console.error('Error checking session capability:', error);
const statusMessage = document.getElementById('statusMessage');
statusMessage.innerHTML = 'Error checking AI session capability. Please refer to the <a href="https://docs.google.com/document/d/1VG8HIyz361zGduWgNG7R_R8Xkv0OOJ8b5C9QKeCjU0c/edit?pli=1#heading=h.5s2qlonhpm36" target="_blank">documentation</a> for troubleshooting.';
statusMessage.className = 'invalid-message';
throw error; // Re-throw to ensure the caller knows the function has failed
async function initializeAI() {
try {
const capabilities = await window.ai.assistant.capabilities();
if (capabilities.available === "readily" || capabilities.available === "after-download") {
aiSession = await window.ai.assistant.create();
console.log("AI session created successfully");
} else {
throw new Error("AI capabilities are not available on this device.");
}
} catch (error) {
console.error('Error initializing AI:', error);
const statusMessage = document.getElementById('statusMessage');
statusMessage.innerHTML = 'Error initializing AI. Please refer to the <a href="https://docs.google.com/document/d/1VG8HIyz361zGduWgNG7R_R8Xkv0OOJ8b5C9QKeCjU0c/edit?pli=1#heading=h.5s2qlonhpm36" target="_blank">documentation</a> for troubleshooting.';
statusMessage.className = 'invalid-message';
throw error;
}
}

async function geminiNano(prompt) {
if (!aiSession) {
await initializeAI();
}

try {
const result = await aiSession.prompt(prompt);
return result; // Return the AI's response
} catch (error) {
console.error('Error in aiPrompt:', error); // Log errors in aiPrompt
console.error('Error in Gemini Nano prompt:', error);
throw new Error("Error during AI interaction");
}
}

// Call this function when the page loads or when the user selects Gemini Nano
initializeAI().catch(error => {
console.error("Failed to initialize AI:", error);
// Handle the error appropriately in your UI
});

// Get the modal
var modal = document.getElementById("instructionsModal");

Expand Down
52 changes: 31 additions & 21 deletions apps/Gemini Nano v1/chat.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,53 @@
// chat.js
let conversationHistory = []; // Continue using the renamed array to avoid conflicts
let conversationHistory = [];

document.getElementById('send-button').addEventListener('click', sendMessage);
document.getElementById('user-input').addEventListener('keypress', function(event) {
if (event.key === "Enter") {
event.preventDefault(); // Prevent the default action to avoid form submission
event.preventDefault();
sendMessage();
}
});

let aiSession = null;

async function initializeAI() {
const capabilities = await window.ai.assistant.capabilities();
if (capabilities.available === "readily" || capabilities.available === "after-download") {
aiSession = await window.ai.assistant.create();
} else {
console.error("AI capabilities are not available on this device.");
}
}

async function sendMessage() {
const userInput = document.getElementById('user-input').value;
const chatOutput = document.getElementById('chat-output');
const sendButton = document.getElementById('send-button');

if (!userInput.trim()) return;

sendButton.disabled = true; // Disable the button to prevent re-entry during processing
sendButton.disabled = true;
chatOutput.innerHTML += `<div>You: ${userInput}</div>`;
conversationHistory.push(`You: ${userInput}<ctrl23>`); // Update conversation history
console.log('Sending prompt:', `You: ${userInput}<ctrl23>`); // Log the prompt

const canCreate = await window.ai.canCreateTextSession();
if (canCreate === "no") {
chatOutput.innerHTML += `<div>Sorry, your device does not support this feature.</div>`;
sendButton.disabled = false;
return;
conversationHistory.push(`You: ${userInput}<ctrl23>`);
console.log('Sending prompt:', `You: ${userInput}<ctrl23>`);

if (!aiSession) {
await initializeAI();
if (!aiSession) {
chatOutput.innerHTML += `<div>Sorry, AI capabilities are not available on your device.</div>`;
sendButton.disabled = false;
return;
}
}

const session = await window.ai.createTextSession();
let prompt = conversationHistory.join(' ');
if (prompt.length > 950) {
conversationHistory = conversationHistory.slice(-5);
prompt = conversationHistory.join(' ');
}

console.log('Full prompt to AI:', prompt); // Log the full prompt being sent to AI
try {
const result = await session.prompt(prompt);
const prompt = conversationHistory.join(' ');
console.log('Full prompt to AI:', prompt);
const result = await aiSession.prompt(prompt);
chatOutput.innerHTML += `<div>Gemini Nano:</div><div>${marked.parse(result)}</div>`;
conversationHistory.push(`Gemini Nano: ${result}<ctrl23>`);
console.log('Received response:', result); // Log the response from AI
console.log('Received response:', result);
} catch (error) {
console.error('Error prompting Gemini Nano:', error);
chatOutput.innerHTML += `<div>Error communicating with AI.</div>`;
Expand All @@ -49,3 +56,6 @@ async function sendMessage() {
document.getElementById('user-input').value = '';
sendButton.disabled = false;
}

// Initialize AI when the script loads
initializeAI();
78 changes: 52 additions & 26 deletions apps/Gemini Nano/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,6 @@ async function createPersona() {
updateUI(); // Update the UI with the new persona
}

async function generatePersonaName(personality, role) {
const prompt = `Suggest a single, suitable name for a persona characterized as '${personality}' and whose profession is '${role}'. The name should be creative and reflect these attributes. Please provide only the name without any explanations or additional text.`;

try {
const response = await aiPrompt(prompt);
// Check if the response is defined and has a valid format before splitting
if (response && typeof response === 'string') {
const suggestedName = response.split('\n')[0].trim(); // Takes only the first line to ensure it's just the name
console.log(`AI suggested name: ${suggestedName}`);
return suggestedName;
} else {
// Handle cases where response is undefined or not a string
console.error('Invalid response format:', response);
return null;
}
} catch (error) {
console.error('Error generating persona name:', error);
return null; // Return null if there's an error
}
}

function getRandomAttributes() {
const attributes = [
'curious', 'domineering', 'shy', 'creative', 'witty', 'literal minded',
Expand Down Expand Up @@ -92,16 +71,48 @@ function updateUI() {
const container = document.getElementById('personas-content');
// Iterate through personas and update UI with new entries only
personas.forEach(persona => {
const existingEntry = document.querySelector(`div[data-persona-id="${persona.name}"]`);
const safePersonaId = CSS.escape(persona.name); // Safely escape the persona name for use in a selector
const existingEntry = document.querySelector(`div[data-persona-id="${safePersonaId}"]`);
if (!existingEntry) {
const personaDiv = document.createElement('div');
personaDiv.setAttribute('data-persona-id', persona.name); // Helps identify the div later
personaDiv.innerHTML = `<strong>${persona.name}</strong> (${persona.attributes.personality}, ${persona.attributes.role})`;
personaDiv.innerHTML = `<strong>${escapeHtml(persona.name)}</strong> (${escapeHtml(persona.attributes.personality)}, ${escapeHtml(persona.attributes.role)})`;
container.appendChild(personaDiv);
}
});
}

// Helper function to escape HTML special characters
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}

async function generatePersonaName(personality, role) {
const prompt = `Suggest a single, suitable name for a persona characterized as '${personality}' and whose profession is '${role}'. The name should be creative and reflect these attributes. Please provide only the name without any explanations or additional text.`;

try {
const response = await aiPrompt(prompt);
// Check if the response is defined and has a valid format before processing
if (response && typeof response === 'string') {
const suggestedName = response.split('\n')[0].trim(); // Takes only the first line to ensure it's just the name
console.log(`AI suggested name: ${suggestedName}`);
return suggestedName.replace(/['"]/g, ''); // Remove any quotes from the name
} else {
// Handle cases where response is undefined or not a string
console.error('Invalid response format:', response);
return null;
}
} catch (error) {
console.error('Error generating persona name:', error);
return null; // Return null if there's an error
}
}

function handleBroadcast() {
const message = document.getElementById('broadcastMessage').value;
if (message.trim() === '') {
Expand Down Expand Up @@ -303,6 +314,15 @@ document.getElementById('pauseResumeButton').addEventListener('click', togglePau
// AI Interaction function
let aiSession = null; // Will hold the session object for Gemini

async function initializeAI() {
const capabilities = await window.ai.assistant.capabilities();
if (capabilities.available === "readily" || capabilities.available === "after-download") {
aiSession = await window.ai.assistant.create();
} else {
console.error("AI capabilities are not available on this device.");
}
}

async function aiPrompt(prompt, retries = 3) {
const model = document.getElementById('apiChoice').value || 'gemini'; // Default to Gemini Nano
const apiKey = document.getElementById('apiKey').value;
Expand All @@ -311,11 +331,11 @@ async function aiPrompt(prompt, retries = 3) {
try {
switch (model) {
case 'gemini':
if (!aiSession) { // Check if session exists for Gemini
if (await window.ai.canCreateTextSession() === "no") {
if (!aiSession) {
await initializeAI();
if (!aiSession) {
throw new Error("Unable to create an AI session.");
}
aiSession = await window.ai.createTextSession(); // Create session if none exists
}
console.log('Sending prompt to GeminiNano:', prompt);
const resultGemini = await aiSession.prompt(prompt);
Expand All @@ -324,6 +344,7 @@ async function aiPrompt(prompt, retries = 3) {
return resultGemini;

case 'cohere':
// The Cohere API call remains unchanged
if (!apiKey) {
throw new Error("API key for Cohere is not provided.");
}
Expand All @@ -344,6 +365,11 @@ async function aiPrompt(prompt, retries = 3) {
}
}

// Initialize AI when the script loads
initializeAI();

// The rest of your code remains unchanged

async function callCohere(apiKey, fullPrompt, retries = 3) {
const url = 'https://api.cohere.com/v1/generate'; // Correct API endpoint for generation
let delay = 2000; // Start with a 2-second delay
Expand Down
Binary file removed apps/chatbot chess extension.zip
Binary file not shown.

0 comments on commit dfa2d66

Please sign in to comment.