Add a search feature in the virtual_garden.html code that searches for the 3d plant model using the sketchfab api and the plant info has to be generated by the gemini model...the plant model has to be deployed in the environment ...
"
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>Interactive Ayurvedic Garden</title>
<script src="https://aframe.io/releases/1.4.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-environment-component/dist/aframe-environment-component.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@google/generative-ai@0.1.0/dist/index.min.js"></script>
<script>
AFRAME.registerComponent('ayush-plant', {
schema: {
name: { type: 'string' },
info: { type: 'string' }
},
init: function () {
this.el.addEventListener('click', () => {
if (!this.isFound) {
this.incrementScore();
this.isFound = true;
}
this.toggleInfo();
});
this.isFound = false;
this.infoVisible = false;
this.totalPlants = document.querySelectorAll('[ayush-plant]').length;
},
toggleInfo: function () {
if (this.infoVisible) {
this.hideInfo();
} else {
this.showInfo();
}
},
showInfo: function () {
// Remove existing info displays if any
this.hideInfo();

const infoContainer = document.createElement('a-entity');
infoContainer.setAttribute('class', 'info-display');
infoContainer.setAttribute('look-at', '#player');

// Position the info screen to avoid overlap and display in hover
infoContainer.setAttribute('position', '0 1.8 -2'); // Adjust this position as needed

const panelWidth = 6; // Wider panel for landscape orientation
const wrapCount = 40; // Reduced wrap count for better readability
const padding = 0.2; // Padding around the text

// Set a fixed height for the info panel
const panelHeight = 5; // You can adjust this value

// Create the panel
const infoPanel = document.createElement('a-plane');
infoPanel.setAttribute('width', panelWidth);
infoPanel.setAttribute('height', panelHeight);
infoPanel.setAttribute('material', 'color: #0080ff; opacity: 0.8');
infoPanel.setAttribute('position', '0 0 0'); // Center the panel
infoContainer.appendChild(infoPanel);

// Create the text entities
const titleTextEntity = document.createElement('a-text');
titleTextEntity.setAttribute('value', this.data.name);
titleTextEntity.setAttribute('color', '#fff');
titleTextEntity.setAttribute('align', 'center');
titleTextEntity.setAttribute('wrap-count', wrapCount);
titleTextEntity.setAttribute('width', panelWidth - padding * 2);
titleTextEntity.setAttribute('position', '0 2 0.01'); // Adjust Y for vertical positioning
titleTextEntity.setAttribute('baseline', 'top');
infoContainer.appendChild(titleTextEntity);

const infoTextEntity = document.createElement('a-text');
infoTextEntity.setAttribute('value', this.data.info);
infoTextEntity.setAttribute('color', '#fff');
infoTextEntity.setAttribute('align', 'left');
infoTextEntity.setAttribute('wrap-count', wrapCount);
infoTextEntity.setAttribute('width', panelWidth - padding * 2);
infoTextEntity.setAttribute('position', -${(panelWidth - padding * 2) / 2} 1.5 0.01); // Adjust Y for vertical positioning
infoTextEntity.setAttribute('baseline', 'top');
infoContainer.appendChild(infoTextEntity);

this.el.appendChild(infoContainer);
this.infoVisible = true;
},

hideInfo: function () {
const existingInfo = this.el.querySelector('.info-display');
if (existingInfo) {
this.el.removeChild(existingInfo);
this.infoVisible = false;
}
},
incrementScore: function () {
const scoreElement = document.getElementById('score');
const currentScore = parseInt(scoreElement.getAttribute('value')) || 0;
// Using this.totalPlants now

if (currentScore < this.totalPlants) {
const newScore = currentScore + 1;
scoreElement.setAttribute('value', newScore);
document.getElementById('scoreboard').innerHTML = 'Score: ' + newScore;

updateCoolScoreDisplay(newScore);

if (newScore === this.totalPlants) {
this.endGame();
}
}
},
endGame: function () {
const endTime = new Date();
const startTime = new Date(parseInt(document.getElementById('start-time').getAttribute('value')));
const timeTakenInSeconds = Math.floor((endTime - startTime) / 1000);

const gameOverScreen = document.createElement('a-entity');
gameOverScreen.setAttribute('id', 'game-over-screen');
gameOverScreen.setAttribute('position', '0 1.6 -2');
gameOverScreen.setAttribute('look-at', '#player');

const background = document.createElement('a-plane');
background.setAttribute('width', 3);
background.setAttribute('height', 2);
background.setAttribute('material', 'color: #0080ff; opacity: 0.8');
gameOverScreen.appendChild(background);

const congratsText = document.createElement('a-text');
congratsText.setAttribute('value', 'Congratulations!');
congratsText.setAttribute('color', '#ffffff');
congratsText.setAttribute('align', 'center');
congratsText.setAttribute('width', 2.8);
congratsText.setAttribute('wrap-count', 30);
congratsText.setAttribute('position', '0 0.5 0.01');
gameOverScreen.appendChild(congratsText);

const timeText = document.createElement('a-text');
timeText.setAttribute('value', You found all the plants in ${timeTakenInSeconds} seconds!);
timeText.setAttribute('color', '#ffffff');
timeText.setAttribute('align', 'center');
timeText.setAttribute('width', 2.8);
timeText.setAttribute('wrap-count', 30);
timeText.setAttribute('position', '0 0 0.01');
gameOverScreen.appendChild(timeText);

const restartText = document.createElement('a-text');
restartText.setAttribute('value', 'Press "R" to restart');
restartText.setAttribute('color', '#ffffff');
restartText.setAttribute('align', 'center');
restartText.setAttribute('width', 2.8);
restartText.setAttribute('wrap-count', 30);
restartText.setAttribute('position', '0 -0.5 0.01');
gameOverScreen.appendChild(restartText);

document.querySelector('a-scene').appendChild(gameOverScreen);

window.addEventListener('keydown', function (event) {
if (event.key === 'r' || event.key === 'R') {
location.reload();
}
});
}
});

function startGame() {
document.getElementById('start-time').setAttribute('value', new Date().getTime());
document.getElementById('score').setAttribute('value', 0);
document.getElementById('scoreboard').innerHTML = 'Score: 0';
updateCoolScoreDisplay(0);
}

function updateCoolScoreDisplay(score) {
const coolScoreDisplay = document.getElementById('cool-score-display');
coolScoreDisplay.innerHTML = '';
for (let i = 0; i < 8; i++) {
const leaf = document.createElement('span');
leaf.textContent = '🍃';
leaf.style.opacity = i < score ? '1' : '0.3';
coolScoreDisplay.appendChild(leaf);
}
}

</script>
<style>
#scoreboard {
position: fixed;
top: 10px;
left: 50%;
transform: translateX(-50%);
font-family: sans-serif;
color: white;
z-index: 1;
font-size: 16px;
background-color: rgba(0, 0, 0, 0.5);
padding: 5px 10px;
border-radius: 5px;
}

#instructions {
position: fixed;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
font-family: sans-serif;
color: white;
z-index: 1;
background-color: rgba(0, 0, 0, 0.5);
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
}

#cool-score-display {
position: fixed;
top: 10px;
right: 10px;
font-size: 20px;
z-index: 1;
}

@media (max-width: 767px) {
#scoreboard,
#instructions,
#cool-score-display {
font-size: 12px;
}
}
</style>
</head>

<body onload="startGame()">
<div id="scoreboard">Score: 0</div>
<div id="instructions">Use W, A, S, D to move, Click on Plants for Info and score a point</div>
<div id="cool-score-display"></div>

<a-scene environment="preset: forest; groundTexture: none; ground: flat; groundColor: #553c25" cursor="rayOrigin: mouse">

<a-entity id="start-time" visible="false"></a-entity>
<a-entity id="score" value="0" visible="false"></a-entity>

<a-assets>
<!-- Replace the src with the correct paths to your model files -->
<a-asset-item id="banana-model" src="banana_plant.glb"></a-asset-item>
<a-asset-item id="aloe-vera-model" src="aloe_vera_plant.glb"></a-asset-item>
<a-asset-item id="basil-model" src="stylized_basil_pot_plant.glb"></a-asset-item>
<a-asset-item id="tulsi-model" src="tulsi.glb"></a-asset-item>
<a-asset-item id="aswagandha-model" src="aswagandha.glb"></a-asset-item>
<a-asset-item id="giloy-model" src="giloy.glb"></a-asset-item>
<a-asset-item id="neem-model" src="neem_plant.glb"></a-asset-item>
<a-asset-item id="turmeric-model" src="Turmeric.glb"></a-asset-item>
</a-assets>

<a-entity id="player" camera look-controls wasd-controls position="0 1.6 0"></a-entity>

<a-entity id="garden">

<a-box color="#3c2f2f" width="30" depth="30" height="0.1" position="0 0 -5"></a-box>

<a-entity position="-5 0 -15">
<a-entity gltf-model="#banana-model" scale="1.2 1.2 1.2"
ayush-plant="name: Banana Plant (Musa);
info: Ayurvedic Uses:
• Promotes Digestive Health
• Supports Respiratory Function
• Nourishes Skin and Hair
• Enhances Blood Health
• Provides Cooling Properties

Interesting Facts:
• The banana plant is technically a herb
• It grows from a bulb-like structure called a corm
• The entire plant is used in traditional medicine">
</a-entity>
</a-entity>

<a-entity position="10 0 -8">
<a-entity gltf-model="#aloe-vera-model" scale="1.5 1.5 1.5"
ayush-plant="name: Aloe Vera (Aloe barbadensis);
info: Ayurvedic Uses:
• Soothes Burns and Wounds
• Promotes Digestive Health
• Supports Skin Health
• Boosts Immunity
• Has Anti-inflammatory Properties

Interesting Facts:
• Used for medicinal purposes for centuries
• Contains vitamins, minerals, and amino acids
• Gel can be applied topically or consumed">
</a-entity>
</a-entity>

<a-entity position="0 0 5">
<a-entity gltf-model="#basil-model" scale="3 3 3"
ayush-plant="name: Basil (Ocimum basilicum);
info: Ayurvedic Uses:
• Relieves Headaches and Cold
• Supports Digestive Health
• Improves Cognitive Function
• Reduces Stress
• Has Antioxidant Properties

Interesting Facts:
• Revered in Hindu culture and considered sacred
• Used in traditional ceremonies
• Its aroma is uplifting and refreshing">
</a-entity>
</a-entity>

<a-entity position="-12 0 0">
<a-entity gltf-model="#tulsi-model" scale="3 2 1"
ayush-plant="name: Tulsi (Ocimum tenuiflorum);
info: Ayurvedic Uses:
• Treats Respiratory Infections
• Improves Immunity
• Has Antibacterial Properties
• Supports Cardiovascular Health
• Reduces Stress and Anxiety

Interesting Facts:
• Sacred plant in Hindu religion
• Vital ingredient in Ayurveda
• Can grow in many climates">
</a-entity>
</a-entity>

<a-entity position="5 2 10">
<a-entity gltf-model="#aswagandha-model" scale="2 2 2"
ayush-plant="name: Ashwagandha (Withania somnifera);
info: Ayurvedic Uses:
• Reduces Stress and Anxiety
• Improves Sleep Quality
• Boosts Energy Levels
• Supports Brain Function
• Enhances Immune System

Interesting Facts:
• Known as Indian Ginseng
• Adaptogen that helps body adapt to stress
• Roots and leaves are used in Ayurveda">
</a-entity>
</a-entity>

<a-entity position="-15 2 10">
<a-entity gltf-model="#giloy-model" scale="2 2 2"
ayush-plant="name: Giloy (Tinospora cordifolia);
info: Ayurvedic Uses:
• Boosts Immunity
• Supports Liver Health
• Manages Diabetes
• Reduces Inflammation
• Has Antioxidant Properties

Interesting Facts:
• Known as Amrita (nectar of immortality)
• A powerful immune-boosting herb
• Used in various Ayurvedic formulations">
</a-entity>
</a-entity>

<a-entity position="10 1 15">
<a-entity gltf-model="#neem-model" scale="1 1 1"
ayush-plant="name: Neem (Azadirachta indica);
info: Ayurvedic Uses:
• Treats Skin Conditions
• Manages Diabetes
• Supports Oral Health
• Has Antibacterial and Antifungal Properties
• Improves Digestive Health

Interesting Facts:
• A versatile tree with medicinal properties
• Used in traditional medicine for centuries
• Various parts of the tree are used for different purposes">
</a-entity>
</a-entity>

<a-entity position="0 1 -15">
<a-entity gltf-model="#turmeric-model" scale="1 1 1"
ayush-plant="name: Turmeric (Curcuma longa);
info: Ayurvedic Uses:
• Reduces Inflammation
• Supports Brain Health
• Has Antioxidant Properties
• Aids Digestion
• Promotes Skin Health

Interesting Facts:
• Used as a spice and a medicine
• Contains curcumin, a powerful antioxidant
• Essential part of traditional Indian cuisine and medicine">
</a-entity>
</a-entity>


</a-entity>

<a-light type="ambient" color="#BBB"></a-light>
<a-light type="directional" color="#FFF" intensity="0.6" position="-0.5 1 1"></a-light>

</a-scene>
</body>

</html>
"
"
Viewer API
The Viewer API lets you build web apps on top of Sketchfab’s 3D viewer. With the API, you can control the viewer in JavaScript. It provides functions for starting, stopping the viewer, moving the camera, taking screenshots and more.

Getting started
To use the viewer API in a web page, follow these 3 steps:

Insert this script in your page: sketchfab-viewer-1.12.1.js
Add an empty iframe
Initialize the viewer
Here is a ready to use example:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Sketchfab Viewer API example</title>

    <!-- Insert this script -->
    <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script>
</head>

<body>
    <!-- Insert an empty iframe with attributes -->
    <iframe src="" id="api-frame" allow="autoplay; fullscreen; xr-spatial-tracking" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

    <!-- Initialize the viewer -->
    <script type="text/javascript">
    var iframe = document.getElementById( 'api-frame' );
    var uid = '7w7pAfrCfjovwykkEeRFLGw5SXS';

    // By default, the latest version of the viewer API will be used.
    var client = new Sketchfab( iframe );

    // Alternatively, you can request a specific version.
    // var client = new Sketchfab( '1.12.1', iframe );

    client.init( uid, {
        success: function onSuccess( api ){
            api.start();
            api.addEventListener( 'viewerready', function() {

                // API is ready to use
                // Insert your code here
                console.log( 'Viewer is ready' );

            } );
        },
        error: function onError() {
            console.log( 'Viewer error' );
        }
    } );
    </script>
</body>
</html>
NOTE: Firefox does not support certain tasks for iframes with style="display:none", like adding event listeners. A possible workaround is to add a class that changes the visibility. Here is an example:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Sketchfab Viewer API example</title>

    <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script>
    <style>
    // Hidden class
    .hidden {
        visibility: hidden;
        height: 0;
        width: 0;
    }
    </style>
</head>

<body>
  <!-- Insert an empty iframe with attrubutes, hidden by default using a class-->
  <iframe class="hidden" src="" id="api-frame" allow="autoplay; fullscreen; xr-spatial-tracking" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true" ></iframe>

  <!-- Initialize the viewer -->
  <script type="text/javascript">

    var iframe = document.getElementById( 'api-frame' );

        var uid = '731235038f6945d19f10d9331b78ea09';
        var client = null;

        function loadmodel() {
            document.addEventListener('load', () => console.log( 'viewerready' ));

            // By default, the latest version of the viewer API will be used.
            var client = new Sketchfab( iframe );

            // Alternatively, you can request a specific version.
            // var client = new Sketchfab( '1.12.0', iframe );

            client.init( uid, {
                success: function onSuccess( api ) {
                    console.log( 'Success' );
                    api.load();
                    api.start();

                    api.addEventListener( 'viewerready', function() {
                        console.log( 'Viewer is ready' );
                        // once the viewer is ready, show the iframe
                        let $apiFrame = document.getElementById( 'api-frame' );
                        $apiFrame.classList.remove( 'hidden' ); // Remove hidden class
                    } );
                },
                error: function onError( callback ) {
                    console.log( this.error );
                }
            } );
        }
  </script>

  <button onclick="loadmodel()">Click me to load model and show iframe.</button>
</body>

</html>
NOTE: In order to load correctly, the Sketchfab viewer must run various scripts, access browser cookies, and make requests to other resources on Sketchfab’s servers. If your website sandboxes iframes for security purposes, you must lift certain restrictions. This is very common in various WordPress configurations, for example. To ensure all viewer features function correctly, and to abide by our terms of use, you should include the following values in the sandbox attribute:

allow-scripts
allow-same-origin
allow-popups
allow-forms
<iframe src="" id="api-frame" sandbox="allow-scripts allow-same-origin allow-popups allow-forms" allow="autoplay; fullscreen; xr-spatial-tracking" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>


Downloading models with JavaScript
For web apps, downloading models can be challenging:

browsers have cross-origin restrictions.
web apps do not have access to the file system.
3D frameworks usually work with URLs or files, not ZIP archives.
This guide will help you overcome these issues while implementing the Download API into a web app.

Requesting a download
Models are not directly accessible for downloading. You need to make a preliminary request to obtain the URL of the archive.

To request a download, use the /v3/models/{UID}/download endpoint. Make sure to add the Authorization header to authenticate the user.

In this example, we’ll use fetch to make the request:

var url = 'https://api.sketchfab.com/v3/models/49d97ca2fbf34f85b6c88ae8ebc7514f/download';
var options = {
    method: 'GET',
    headers: {
        Authorization: 'Bearer {INSERT_OAUTH_ACCESS_TOKEN_HERE}',
    },
    mode: 'cors'
};

fetch(url, options).then(function(response){
    return response.json();
}).then(function(data){
    console.log(data);
});
This request will return something like:

{
    "gltf": {
        "url": "https://sketchfab-prod-media.s3.amazonaws.com/archives/799f8c4511f84fab8c3f12887f7e6b36/gltf/...",
        "size": 45388265,
        "expires": 300
    },
    "usdz": {
        "url": "https://sketchfab-prod-media.s3.amazonaws.com/archives/799f8c4511f84fab8c3f12887f7e6b36/usdz/...",
        "size": 6394777,
        "expires": 300
    }
}
The response contains all the information needed to download the archive. All you need to do is request the URL contained in gltf.url to download the archive.

IMPORTANT: The archive URL is only valid for a short period of time. Your application shouldn’t cache it.

Downloading a model archive
To download the zip archive, you can make a HTTP GET request to the url provided by the /v3/models/{uid}/download endpoint. Instead of making the request yourself, we recommend using zip.js which will download the file and decompress it into memory.

<!-- Download zip.js from https://gildas-lormeau.github.io/zip.js/ -->
<script type="text/javascript" src="/lib/zip.js"></script>
<script type="text/javascript" src="/lib/zip-ext.js"></script>
zip.workerScriptsPath = '/lib/';
var reader = new zip.HttpReader(url);
zip.createReader(
    reader,
    function(zipReader) {
        zipReader.getEntries(function(entries){
            console.log(entries);
        });
    },
    function(error) {
        console.error(error);
    }
);
This will return an array of entries that represent files in the zip. It looks something like this:

[
    ...,
    {
        "_worker": {
            "crcTime": 0,
            "codecTime": 0
        },
        "version": 788,
        "bitFlag": 0,
        "compressionMethod": 8,
        "lastModDateRaw": 1267768440,
        "lastModDate": "2017-12-16T18:35:48.000Z",
        "crc32": 2072282119,
        "compressedSize": 9978,
        "uncompressedSize": 73359,
        "filenameLength": 10,
        "extraFieldLength": 0,
        "commentLength": 0,
        "directory": false,
        "offset": 341906,
        "filename": "scene.gltf",
        "comment": ""
    },
    ...
]
Loading a USDZ model
iOS devices can open USDZ file URLs directly in Safari. For more details, visit the USDZ documentation from Apple and Pixar.

Loading a glTF model
Once the archive has been downloaded and unzipped, all unzipped files are stored in memory as Entry objects.

If your app is using a 3D framework, it probably has a glTF plugin for reading glTF files:

three.js GLTF Loader
babylon.js glTF File loader plugin
OSG.JS
The final step is to convert the Entry objects into something that these frameworks can load.

Generating URLs for every Entry
First, write the Entry content to Blob objects and generate URLs for each Blob:

entry.getData(new zip.BlobWriter('text/plain'), function onEnd(data) {
    var url = window.URL.createObjectURL(data);
    console.log(url);
});
This will generate URLs that look like this:

blob:http://example.com/59b3c659-d042-4a7f-bfb9-5c4c798fc0ed
Rewriting paths to URLs in scene.gltf
A glTF file is actually a JSON file. It contains all the information about the model, and links to other resources like geometry buffers and images. You will then need to rewrite the path of these resources to point to the URLs generated in the previous step.

// sceneFileContent is the content of scene.gltf
// and fileUrls is a key/value object,
// keys being filenames and values being corresponding URLs

var json = JSON.parse(sceneFileContent);

// Replace original buffers and images by blob URLs
if (json.hasOwnProperty('buffers')) {
    for (var i = 0; i < json.buffers.length; i++) {
        json.buffers[i].uri = fileUrls[json.buffers[i].uri];
    }
}

if (json.hasOwnProperty('images')) {
    for (var i = 0; i < json.images.length; i++) {
        json.images[i].uri = fileUrls[json.images[i].uri];
    }
}

var updatedSceneFileContent = JSON.stringify(json, null, 2);
var updatedBlob = new Blob([updatedSceneFileContent], { type: 'text/plain' });
var updatedUrl = window.URL.createObjectURL(updatedBlob);
// -> blob:http://example.com/a9b5c659-b032-4b7e-df19-5c42798fc049
Once all paths have been replaced, you can pass the URL of the updated scene.gltf file to your 3D framework to load the model.

// three.js

// URL corresponding to scene.gltf
var url = 'blob:http://example.com/a9b5c659-b032-4b7e-df19-5c42798fc049';

var loader = new THREE.GLTFLoader();
loader.load(url, function(gltf){
    scene.add( gltf.scene );
}, undefined, function(error){
    console.error( error );
});
// babylon.js

// URL corresponding to scene.gltf
var url = 'blob:http://example.com/a9b5c659-b032-4b7e-df19-5c42798fc049';

BABYLON.SceneLoader.ImportMesh('', '', url, scene, function onSuccess() {
    console.log('Loaded');
}, function onProgress() {
    console.log('Progress');
}, function onError(e) {
    console.error(e);
}, '.gltf');
JavaScript 




google gemini api documentation 

Generate text using the Gemini API 

bookmark_border
Python Node.js Go REST

The Gemini API can generate text output from various types of input, including text, images, video, and audio. You can use text generation for various applications, including:

Creative writing
Describing or interpreting media assets
Text completion
Summarizing free-form text
Translating between languages
Chatbots
Your own novel use cases
This guide shows you how to generate text using the generateContent and streamGenerateContent APIs. The focus is on text output from text-only and text-and-image input. To learn more about multimodal prompting with video and audio files, see File prompting strategies.

Before you begin: Set up your project and API key
Before calling the Gemini API, you need to set up your project and configure your API key.

 Expand to view how to set up your project and API key

Generate text from text-only input
The simplest way to generate text using the Gemini API is to provide the model with a single text-only input, as shown in this example:


curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[{"text": "Write a story about a magic backpack."}]
        }]
       }' 2> /dev/null

In this case, the prompt ("Write a story about a magic backpack") doesn't include any output examples, system instructions, or formatting information. It's a zero-shot approach. For some use cases, a one-shot or few-shot prompt might produce output that's more aligned with user expectations. In some cases, you might also want to provide system instructions to help the model understand the task or follow specific guidelines.

Generate text from text-and-image input
The Gemini API supports multimodal inputs that combine text with media files. The following example shows how to generate text from text-and-image input:


curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
            {"text": "Tell me about this instrument"},
            {
              "inline_data": {
                "mime_type":"image/jpeg",
                "data": "'$(base64 $B64FLAGS $IMG_PATH)'"
              }
            }
        ]
        }]
       }' 2> /dev/null

As with text-only prompting, multimodal prompting can involve various approaches and refinements. Depending on the output from this example, you might want to add steps to the prompt or be more specific in your instructions. To learn more, see File prompting strategies.

Generate a text stream
By default, the model returns a response after completing the entire text generation process. You can achieve faster interactions by not waiting for the entire result, and instead use streaming to handle partial results.

The following example shows how to implement streaming using the streamGenerateContent method to generate text from a text-only input prompt.


curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=${GOOGLE_API_KEY}" \
        -H 'Content-Type: application/json' \
        --no-buffer \
        -d '{ "contents":[{"parts":[{"text": "Write a story about a magic backpack."}]}]}'

Build an interactive chat
You can use the Gemini API to build interactive chat experiences for your users. Using the chat feature of the API lets you collect multiple rounds of questions and responses, allowing users to step incrementally toward answers or get help with multipart problems. This feature is ideal for applications that require ongoing communication, such as chatbots, interactive tutors, or customer support assistants.

The following code example shows a basic chat implementation:


curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [
        {"role":"user",
         "parts":[{
           "text": "Hello"}]},
        {"role": "model",
         "parts":[{
           "text": "Great to meet you. What would you like to know?"}]},
        {"role":"user",
         "parts":[{
           "text": "I have two dogs in my house. How many paws are in my house?"}]},
      ]
    }' 2> /dev/null | grep "text"

Configure text generation
Every prompt you send to the model includes parameters that control how the model generates responses. You can use GenerationConfig to configure these parameters. If you don't configure the parameters, the model uses default options, which can vary by model.

The following example shows how to configure several of the available options.


curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
        "contents": [{
            "parts":[
                {"text": "Write a story about a magic backpack."}
            ]
        }],
        "safetySettings": [
            {
                "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
                "threshold": "BLOCK_ONLY_HIGH"
            }
        ],
        "generationConfig": {
            "stopSequences": [
                "Title"
            ],
            "temperature": 1.0,
            "maxOutputTokens": 800,
            "topP": 0.8,
            "topK": 10
        }
    }'  2> /dev/null | grep "text"

stopSequences specifies the set of character sequences (up to 5) that will stop output generation. If specified, the API will stop at the first appearance of a stop_sequence. The stop sequence won't be included as part of the response.

temperature controls the randomness of the output. Use higher values for more creative responses, and lower values for more deterministic responses. Values can range from [0.0, 2.0].

maxOutputTokens sets the maximum number of tokens to include in a candidate.

topP changes how the model selects tokens for output. Tokens are selected from the most to least probable until the sum of their probabilities equals the topP value. The default topP value is 0.95.

topK changes how the model selects tokens for output. A topK of 1 means the selected token is the most probable among all the tokens in the model's vocabulary, while a topK of 3 means that the next token is selected from among the 3 most probable using the temperature. Tokens are further filtered based on topP with the final token selected using temperature sampling.

What's next
This guide shows how to use generateContent and streamGenerateContent to generate text outputs from text-only and text-and-image inputs. To learn more about generating text using the Gemini API, see the following resources:

File prompting strategies: The Gemini API supports prompting with text, image, audio, and video data, also known as multimodal prompting.
System instructions: System instructions let you steer the behavior of the model based on your specific needs and use cases.
Safety guidance: Sometimes generative AI models produce unexpected outputs, such as outputs that are inaccurate, biased, or offensive. Post-processing and human evaluation are essential to limit the risk of harm from such outputs.
"

here is the documentation of the sketchfab and google gemini api with the code