# Smart Cloudflare Worker: AI-Powered Image Search with GoogLLM

## Prompt

````md path="prompt.md"
https://googllm.com/llms.txt

please make me a Cloudflare Worker that uses chat completions from openAI with googllm to output the most logical image based on GET /{query}. The worker first fetches the markdown from googllm, then inserts that into the system prompt. It is prompted to output exactly one URL that is most likely
````

## Context

````md path="context.md"

https://googllm.com/llms.txt (1516 tokens) 
```markdown
# GoogLLM API Documentation for Large Language Models

## Overview

GoogLLM is an agent-friendly Google search replacement that returns clean, structured markdown results instead of HTML. This API is specifically designed for AI agents and LLMs to easily consume Google search results.

## Why GoogLLM Exists

**Problem**: Traditional Google search returns massive HTML documents that are difficult for LLMs to parse efficiently. Other search APIs like Tavily, Exa, and Brave require complex setup and authentication processes.

**Solution**: GoogLLM provides the same Google search results in a clean, markdown format that LLMs can easily understand and process. Simply replace "google.com" with "googllm.com" in any search URL.

## Key Benefits

- 🤯 Returns markdown by default (works with curl, fetch, any HTTP client)
- 🤯 Easy and free to try, then pay-as-you-go pricing
- 🤯 No tracking, no ads, privacy-focused
- 🤯 Use as direct API or OpenAI tool/function call
- 🤯 Supports multiple search types: search, images, videos, news, places, shopping, scholar

## Authentication

All requests require an Authorization header with your API key:

```
Authorization: YOUR_API_KEY
```

You can obtain your API key by visiting the `/api/` endpoint while authenticated.

## API Endpoints

### Base URL: `https://googllm.com`

### Search Types

- `/search/{query}` - Web search results
- `/images/{query}` - Image search results
- `/videos/{query}` - Video search results
- `/news/{query}` - News search results
- `/places/{query}` - Local business/place results
- `/shopping/{query}` - Shopping/product results
- `/scholar/{query}` - Academic/scholarly results

### URL Parameters

- `gl` - Country code (e.g., "us", "uk", "ca")
- `hl` - Language code (e.g., "en", "es", "fr")
- `location` - Geographic location for search
- `num` - Number of results (10 or 100)
- `page` - Page number for pagination
- `autocorrect` - Enable/disable autocorrect (true/false)

## Usage Examples

### Basic Search

```bash
curl "https://googllm.com/search/artificial%20intelligence%20news" \
  -H "Authorization: YOUR_API_KEY"
```

### Image Search

```bash
curl "https://googllm.com/images/cats" \
  -H "Authorization: YOUR_API_KEY"
```

### News Search with Parameters

```bash
curl "https://googllm.com/news/climate%20change?gl=us&hl=en&num=10" \
  -H "Authorization: YOUR_API_KEY"
```

## OpenAI Tool Integration

You can use GoogLLM as a function/tool in OpenAI's Chat Completions API:

```json
{
  "model": "gpt-4",
  "messages": [
    {
      "role": "user",
      "content": "What are the latest developments in quantum computing?"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "googllm_search",
        "description": "Search Google for current information on any topic",
        "parameters": {
          "type": "object",
          "properties": {
            "query": {
              "type": "string",
              "description": "The search query"
            },
            "type": {
              "type": "string",
              "enum": [
                "search",
                "images",
                "videos",
                "news",
                "places",
                "shopping",
                "scholar"
              ],
              "description": "Type of search to perform",
              "default": "search"
            }
          },
          "required": ["query"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}
```

### Function Implementation

```javascript
// When the model calls the function:
const response = await fetch(`https://googllm.com/${type}/${encodeURIComponent(query)}`, {
  headers: {
    'Authorization': 'YOUR_API_KEY'
  }
});
const searchResults = await response.text(); // Returns markdown

// Send results back to the model:
{
  "role": "tool",
  "tool_call_id": "call_abc123",
  "content": searchResults
}
```

## Response Format

All responses are returned in clean markdown format optimized for LLM consumption:

### Web Search Results

```markdown
# Google Search: artificial intelligence news

1. [AI Breakthrough: New Language Model Surpasses GPT-4](https://example.com/ai-news)
   Researchers at Stanford University have developed a new language model that outperforms GPT-4 on various benchmarks...

2. [The Future of AI in Healthcare](https://example.com/ai-healthcare)
   Artificial intelligence is revolutionizing healthcare with new diagnostic tools and treatment recommendations...
```

### Image Search Results

```markdown
# Google Images: cats

1. [Cute Orange Cat](https://example.com/cat-image)
   ![Cute Orange Cat](https://example.com/cat.jpg)

2. [Sleeping Kitten](https://example.com/kitten)
   ![Sleeping Kitten](https://example.com/kitten.jpg)
```

### News Results

```markdown
# Google News: climate change

1. [Global Climate Summit Reaches Historic Agreement](https://news.example.com/climate)
   World leaders agree on ambitious new targets for carbon reduction... (Reuters, 2024-01-15)

2. [Arctic Ice Melting Faster Than Predicted](https://news.example.com/arctic)
   New satellite data shows accelerating ice loss in the Arctic region... (BBC, 2024-01-14)
```

## Pricing

- **Free Tier**: 10 requests per hour
- **Paid Usage**: $0.005 (0.5 cents) per request after free tier exhausted
- **Payment**: Pay-as-you-go, add funds to your balance as needed

If your balance is depleted, the API responds with HTTP 402 and a payment URL.

## Error Handling

- **400 Bad Request**: Invalid search type or malformed URL
- **401 Unauthorized**: Missing or invalid API key
- **402 Payment Required**: Insufficient balance, includes payment URL
- **429 Too Many Requests**: Rate limit exceeded (free tier)
- **500 Internal Server Error**: Server-side error

## Rate Limits

- **Free Users**: 10 requests per hour
- **Paid Users**: No rate limits (pay per request)

## Best Practices for LLMs

1. **Cache Results**: Search results are cached for 24 hours, identical queries return cached results
2. **Use Specific Queries**: More specific queries yield better, more relevant results
3. **Choose Appropriate Search Type**: Use `news` for current events, `scholar` for academic research, etc.
4. **Handle Errors Gracefully**: Always check response status and handle payment redirects
5. **Respect Rate Limits**: For free tier usage, space out requests appropriately

## Comparison to Alternatives

| Feature             | GoogLLM  | Tavily   | Exa      | Brave Search API | Google Custom Search |
| ------------------- | -------- | -------- | -------- | ---------------- | -------------------- |
| Setup Complexity    | Minimal  | Complex  | Complex  | Moderate         | Complex              |
| Output Format       | Markdown | JSON     | JSON     | JSON             | JSON                 |
| LLM Optimized       | ✅       | ✅       | ✅       | ❌               | ❌                   |
| Free Tier           | 10/hour  | Limited  | Limited  | None             | 100/day              |
| Search Types        | 7 types  | Web only | Web only | Web only         | Web only             |
| Real Google Results | ✅       | ❌       | ❌       | ❌               | ✅                   |

## Getting Started

1. Visit `https://googllm.com/api/` to get your API key
2. Make your first request to test the service
3. Integrate into your LLM application or OpenAI tool setup
4. Add funds when you exceed the free tier

For immediate testing, you can replace any Google search URL by changing "google.com" to "googllm.com" and the results will be returned in markdown format.


```


````

## Result

````md path="result.md"
I'll create a Cloudflare Worker that uses GoogLLM to search for images and then uses OpenAI to select the most logical image URL based on the query.

```javascript
export default {
  async fetch(request, env, ctx) {
    // Handle CORS preflight requests
    if (request.method === 'OPTIONS') {
      return new Response(null, {
        status: 200,
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'GET, OPTIONS',
          'Access-Control-Allow-Headers': 'Content-Type',
        },
      });
    }

    // Only handle GET requests
    if (request.method !== 'GET') {
      return new Response('Method not allowed', { status: 405 });
    }

    try {
      // Parse the URL to get the query
      const url = new URL(request.url);
      const pathParts = url.pathname.split('/').filter(part => part.length > 0);
      
      if (pathParts.length === 0) {
        return new Response('Usage: GET /{query} - Returns the most logical image URL for the query', {
          status: 200,
          headers: { 'Content-Type': 'text/plain' }
        });
      }

      const query = decodeURIComponent(pathParts.join(' '));

      if (!query || query.trim().length === 0) {
        return new Response('Query parameter is required', { status: 400 });
      }

      // Check for required environment variables
      if (!env.GOOGLLM_API_KEY) {
        return new Response('GOOGLLM_API_KEY environment variable is required', { status: 500 });
      }

      if (!env.OPENAI_API_KEY) {
        return new Response('OPENAI_API_KEY environment variable is required', { status: 500 });
      }

      // Step 1: Fetch image search results from GoogLLM
      console.log(`Searching GoogLLM for images: ${query}`);
      
      const googllmResponse = await fetch(`https://googllm.com/images/${encodeURIComponent(query)}`, {
        headers: {
          'Authorization': env.GOOGLLM_API_KEY,
          'User-Agent': 'Cloudflare-Worker-ImageSelector/1.0'
        }
      });

      if (!googllmResponse.ok) {
        console.error(`GoogLLM API error: ${googllmResponse.status} ${googllmResponse.statusText}`);
        
        if (googllmResponse.status === 401) {
          return new Response('Invalid GoogLLM API key', { status: 500 });
        } else if (googllmResponse.status === 402) {
          return new Response('GoogLLM API payment required', { status: 500 });
        } else if (googllmResponse.status === 429) {
          return new Response('GoogLLM API rate limit exceeded', { status: 429 });
        }
        
        return new Response(`GoogLLM API error: ${googllmResponse.status}`, { status: 500 });
      }

      const imageSearchResults = await googllmResponse.text();
      console.log(`GoogLLM results length: ${imageSearchResults.length} characters`);

      // Step 2: Use OpenAI to analyze the results and select the most logical image URL
      const systemPrompt = `You are an AI assistant that analyzes image search results and selects the most logical image URL based on a user's query.

Here are the image search results from Google:

${imageSearchResults}

Your task is to:
1. Analyze the search results for the query "${query}"
2. Select the single most logical, relevant, and high-quality image URL
3. Consider factors like relevance to the query, image quality indicators, and source reliability
4. Output EXACTLY ONE URL and nothing else - no explanations, no markdown, just the raw URL

If no suitable image URLs are found in the results, output: NO_IMAGES_FOUND`;

      const openaiResponse = await fetch('https://api.openai.com/v1/chat/completions', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          model: 'gpt-4o-mini', // Using the more cost-effective model
          messages: [
            {
              role: 'system',
              content: systemPrompt
            },
            {
              role: 'user',
              content: `Find the most logical image URL for: ${query}`
            }
          ],
          max_tokens: 200,
          temperature: 0.1, // Low temperature for consistent, logical selection
        }),
      });

      if (!openaiResponse.ok) {
        console.error(`OpenAI API error: ${openaiResponse.status} ${openaiResponse.statusText}`);
        const errorText = await openaiResponse.text();
        console.error(`OpenAI error details: ${errorText}`);
        
        if (openaiResponse.status === 401) {
          return new Response('Invalid OpenAI API key', { status: 500 });
        } else if (openaiResponse.status === 429) {
          return new Response('OpenAI API rate limit exceeded', { status: 429 });
        }
        
        return new Response(`OpenAI API error: ${openaiResponse.status}`, { status: 500 });
      }

      const openaiResult = await openaiResponse.json();
      const selectedImageUrl = openaiResult.choices[0].message.content.trim();

      console.log(`Selected image URL: ${selectedImageUrl}`);

      // Validate that we got a URL or the no images found message
      if (selectedImageUrl === 'NO_IMAGES_FOUND') {
        return new Response('No suitable images found for the query', { 
          status: 404,
          headers: {
            'Content-Type': 'text/plain',
            'Access-Control-Allow-Origin': '*'
          }
        });
      }

      // Basic URL validation
      try {
        new URL(selectedImageUrl);
      } catch (e) {
        console.error(`Invalid URL returned by OpenAI: ${selectedImageUrl}`);
        return new Response('Invalid image URL generated', { status: 500 });
      }

      // Return the selected image URL
      return new Response(selectedImageUrl, {
        status: 200,
        headers: {
          'Content-Type': 'text/plain',
          'Access-Control-Allow-Origin': '*',
          'Cache-Control': 'public, max-age=3600', // Cache for 1 hour
        },
      });

    } catch (error) {
      console.error('Unexpected error:', error);
      return new Response('Internal server error', { 
        status: 500,
        headers: {
          'Access-Control-Allow-Origin': '*'
        }
      });
    }
  },
};
```

## Setup Instructions

1. **Create a new Cloudflare Worker:**
   ```bash
   npm create cloudflare@latest my-image-selector
   cd my-image-selector
   ```

2. **Replace the contents of `src/index.js` with the code above**

3. **Set up environment variables in your `wrangler.toml`:**
   ```toml
   name = "image-selector"
   main = "src/index.js"
   compatibility_date = "2024-01-15"

   [vars]
   # Add your API keys as secrets (don't put them in this file)

   # Use wrangler to set secrets:
   # npx wrangler secret put GOOGLLM_API_KEY
   # npx wrangler secret put OPENAI_API_KEY
   ```

4. **Set your API keys as secrets:**
   ```bash
   npx wrangler secret put GOOGLLM_API_KEY
   # Enter your GoogLLM API key when prompted

   npx wrangler secret put OPENAI_API_KEY
   # Enter your OpenAI API key when prompted
   ```

5. **Deploy the worker:**
   ```bash
   npx wrangler deploy
   ```

## Usage Examples

Once deployed, you can use your worker like this:

```bash
# Search for cat images
curl https://your-worker.your-subdomain.workers.dev/cute%20cats

# Search for nature images
curl https://your-worker.your-subdomain.workers.dev/beautiful%20nature%20landscape

# Search for technology images
curl https://your-worker.your-subdomain.workers.dev/artificial%20intelligence%20robot
```

## Features

- **CORS support** for browser requests
- **Error handling** for both GoogLLM and OpenAI API failures
- **URL validation** to ensure valid image URLs are returned
- **Caching headers** to improve performance
- **Logging** for debugging purposes
- **Cost optimization** using `gpt-4o-mini` model
- **Rate limiting awareness** with appropriate error responses

## How it works

1. **Query parsing**: Extracts the search query from the URL path
2. **Image search**: Uses GoogLLM to get Google image search results in markdown format
3. **AI selection**: Feeds the markdown results to OpenAI with a system prompt that instructs it to select the single most logical image URL
4. **URL validation**: Ensures the returned result is a valid URL
5. **Response**: Returns the selected image URL as plain text

The worker will return a single image URL that OpenAI determines is the most logical match for your query based on the Google image search results.
````

