Skip to content

Gabriel AI Orchestrator ​

Gabriel is FOTOhub's intelligent platform orchestrator — a proprietary AI layer that classifies user intent, routes requests to optimal features, selects the best available model, builds prompts, and orchestrates multi-step workflows.

Gabriel AI is free to use for authenticated users and provides real-time suggestions, streaming responses, and proactive recommendations.

All authenticated Gabriel endpoints accept your standard API key (fh_live_*) via the Authorization: Bearer header — the same key you use for every other endpoint. A Supabase session JWT is also accepted (used by the web dashboard), but no separate credential is required for API integrations.

Endpoints ​

MethodPathAuthDescription
POST/v1/ai/gabrielAPI key or JWTClassify intent and route (single-shot)
POST/v1/ai/gabriel/streamAPI key or JWTStreaming orchestration (SSE)
POST/v1/ai/gabriel/suggestNoneLightweight autocomplete suggestions
POST/v1/ai/gabriel/recommendNoneProactive context-aware recommendations
POST/v1/ai/translateAPI key or JWTTranslate text

POST /v1/ai/gabriel ​

Classify user intent and return a routing decision with optimal model selection, credit estimation, and contextual tips.

Rate limit: 30 requests/minute per user

Authentication: API key (fh_live_*) or Supabase session JWT

Request Body ​

FieldTypeRequiredDescription
promptstringYesUser's natural language request (max 1000 chars)
languagestringNoLanguage code (default: "pl")
contextobjectNoAdditional context for better classification
enhance_promptbooleanNoWhen true, Gabriel enriches the prompt using model-specific architecture knowledge

Context Object ​

FieldTypeDescription
user_tierstringUser's subscription tier ("free", "pro", "business")
wallet_balance_usdfloatCurrent prepaid USD wallet balance
recent_toolsstring[]Last 5 features the user used
brand_idstringActive brand kit ID (for brand-aware suggestions)

Response ​

FieldTypeDescription
actionstring"route" | "answer" | "workflow" | "error"
targetstringFeature path to navigate to (e.g., /generate/image)
paramsobjectPre-configured parameters for the target feature
model_selectedstringOptimal available model for the request
suggested_actionsarrayAlternative actions the user might want
confidencefloatClassification confidence (0.0 - 1.0)
credits_estimatedintegerEstimated credit cost
tipsstring[]Contextual prompt engineering tips

Actions ​

ActionDescription
routeNavigate user to a FOTOhub feature with pre-filled parameters
answerDirect text response (FAQ, help, platform guidance)
workflowMulti-step task requiring sequential operations
errorClassification failed or timed out

Examples ​

python
from fotohub import FotoHub

client = FotoHub(api_key="your-api-key")

result = client.gabriel.classify(
    prompt="Generate a cinematic photo of a sunset over mountains",
    language="en",
    enhance_prompt=True
)

print(result)
# {
#   "action": "route",
#   "target": "/generate/image",
#   "params": {
#     "model": "seedream-5-0-260128",
#     "prompt": "a sunset over mountains, cinematic color grading, golden hour, dramatic volumetric clouds, 8K, ultra detailed, shallow depth of field"
#   },
#   "model_selected": "seedream-5-0-260128",
#   "confidence": 0.95,
#   "credits_estimated": 1,
#   "tips": ["Seedream excels at photorealism — add '8K, sharp detail' for best results"]
# }
typescript
import { FotoHub } from 'fotohub';

const client = new FotoHub({ apiKey: 'your-api-key' });

const result = await client.gabriel.classify({
  prompt: 'Make a 5-second video of a cat walking through a garden',
  language: 'en',
  context: { wallet_balance_usd: 50 }
});

// {
//   "action": "route",
//   "target": "/generate/video",
//   "params": { "model": "seedance-2-0-pro", "duration": 5, "prompt": "..." },
//   "model_selected": "seedance-2-0-pro",
//   "confidence": 0.92,
//   "credits_estimated": 10,
//   "tips": ["Seedance: describe camera movement for dynamic videos"]
// }
bash
curl -X POST https://apis.fotohub.app/v1/ai/gabriel \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer fh_live_YOUR_API_KEY" \
  -d '{
    "prompt": "Create a brand identity for my coffee shop",
    "language": "en",
    "enhance_prompt": true,
    "context": {
      "user_tier": "pro",
      "wallet_balance_usd": 100
    }
  }'

POST /v1/ai/gabriel/stream ​

Streaming orchestration via Server-Sent Events (SSE). Provides progressive feedback as Gabriel processes the request — reduces perceived latency and enables real-time UX.

Rate limit: 30 requests/minute per user

Authentication: API key (fh_live_*) or Supabase session JWT

Request Body ​

Same as /v1/ai/gabriel (prompt, language, context).

SSE Event Types ​

Events are sent as data: {json}\n\n lines. The stream ends with data: [DONE]\n\n.

Event TypeDescriptionFields
thinkingGabriel is processingcontent: status message
routingIntent classified, routing in progresstool: tool being called, content: description
resultFinal routing decisionSame fields as single-shot response
errorProcessing failedmessage: error description

Example ​

typescript
const response = await fetch('https://apis.fotohub.app/v1/ai/gabriel/stream', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify({
    prompt: 'Generate a portrait photo with dramatic lighting',
    language: 'en'
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const text = decoder.decode(value);
  for (const line of text.split('\n')) {
    if (line.startsWith('data: ')) {
      const data = line.slice(6);
      if (data === '[DONE]') break;

      const event = JSON.parse(data);
      switch (event.type) {
        case 'thinking':
          console.log('Processing:', event.content);
          break;
        case 'routing':
          console.log('Using tool:', event.tool);
          break;
        case 'result':
          console.log('Route:', event.target, event.model_selected);
          console.log('Tips:', event.tips);
          break;
      }
    }
  }
}

Stream Timeline ​

Client                    Gabriel
  |--- POST /stream ------->|
  |<-- thinking: "..." ------|  (immediate, <100ms)
  |<-- routing: {...} -------|  (after intent classification)
  |<-- result: {...} --------|  (final decision + tips)
  |<-- data: [DONE] ---------|

POST /v1/ai/gabriel/suggest ​

Lightweight autocomplete suggestions. No LLM call — pure in-memory fuzzy matching for sub-50ms response times. Use this for keystroke-speed suggestions as the user types.

Rate limit: 60 requests/minute per IP

Authentication: None required

Request Body ​

FieldTypeRequiredDescription
partialstringYesPartial user input (min 2 chars, max 200)
tabstringNoCurrent tab context: "all", "image", "video", "audio"
pagestringNoCurrent page path (e.g., /generate/new)

Response ​

FieldTypeDescription
suggestionsarrayUp to 5 ranked suggestions

Suggestion Object ​

FieldTypeDescription
textstringSuggestion text
categorystring"prompt" | "tip" | "model" | "feature"
targetstringOptional navigation target
iconstringOptional icon identifier

Example ​

typescript
// Debounce to 300ms for optimal UX
const suggestions = await fetch('https://apis.fotohub.app/v1/ai/gabriel/suggest', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    partial: 'portrait photo',
    tab: 'image',
    page: '/generate/new'
  })
}).then(r => r.json());

// {
//   "suggestions": [
//     { "text": "portrait photo, studio lighting, shallow depth of field, 8K", "category": "prompt", "icon": "camera" },
//     { "text": "Try Seedream for best portrait quality (1 credit)", "category": "tip", "icon": "sparkles" },
//     { "text": "Use face enhancement for portrait shots", "category": "feature", "target": "/tools/enhance", "icon": "wand" }
//   ]
// }
bash
curl -X POST https://apis.fotohub.app/v1/ai/gabriel/suggest \
  -H "Content-Type: application/json" \
  -d '{"partial": "sunset", "tab": "image"}'

Integration Pattern ​

typescript
// Recommended: debounced suggestions with local fallback
let debounceTimer: number;

function onInputChange(value: string) {
  // Show local suggestions immediately
  showLocalSuggestions(value);

  // Fetch API suggestions after 300ms pause
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(async () => {
    if (value.length >= 2) {
      const { suggestions } = await fetchSuggestions(value);
      if (suggestions.length > 0) {
        replaceSuggestions(suggestions); // API results take priority
      }
    }
  }, 300);
}

POST /v1/ai/gabriel/recommend ​

Proactive context-aware recommendations. Returns 1-3 relevant tips based on the user's current state. Template-based (no LLM call), responds in <100ms.

Rate limit: 30 requests/minute per IP

Authentication: None required

Request Body ​

FieldTypeRequiredDescription
pagestringNoCurrent page path
recent_actionsstring[]NoLast few actions taken
wallet_balance_usdfloatNoUser's prepaid USD wallet balance
has_brandbooleanNoWhether user has a brand kit

Response ​

FieldTypeDescription
recommendationsarrayUp to 3 contextual recommendations

Recommendation Object ​

FieldTypeDescription
textstringRecommendation text
targetstringNavigation target
iconstringIcon identifier

Example ​

bash
curl -X POST https://apis.fotohub.app/v1/ai/gabriel/recommend \
  -H "Content-Type: application/json" \
  -d '{
    "page": "/generate/new",
    "wallet_balance_usd": 5,
    "has_brand": false
  }'

# Response:
# {
#   "recommendations": [
#     { "text": "Low credits — Seedream gives best quality at 1 credit", "target": "/generate/new", "icon": "coins" },
#     { "text": "Create a Brand Kit for consistent style across generations", "target": "/brand", "icon": "palette" }
#   ]
# }

POST /v1/ai/translate ​

Translate text between languages using FOTOhub's built-in translation engine.

Rate limit: 30 requests/minute per user

Authentication: API key (fh_live_*) or Supabase session JWT

Request Body ​

FieldTypeRequiredDescription
textstringYesText to translate (max 10,000 chars)
target_languagestringYesTarget language code (e.g., "en", "pl", "de")
source_languagestringNoSource language (auto-detected if omitted)

Response ​

FieldTypeDescription
translated_textstringThe translation
source_languagestringDetected/specified source language
target_languagestringTarget language
character_countintegerCharacter count of translated text

Examples ​

python
from fotohub import FotoHub

client = FotoHub(api_key="your-api-key")

result = client.translate(
    text="The quick brown fox jumps over the lazy dog",
    target_language="pl"
)
# { "translated_text": "Szybki brązowy lis przeskakuje nad leniwym psem", ... }
typescript
const response = await fetch('https://apis.fotohub.app/v1/ai/translate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    text: 'Bonjour le monde',
    target_language: 'en',
    source_language: 'fr'
  })
});

const { translated_text } = await response.json();
// "Hello world"
bash
curl -X POST https://apis.fotohub.app/v1/ai/translate \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hallo Welt",
    "target_language": "en"
  }'

Orchestrator Capabilities ​

Gabriel provides 10 function-calling tools for intelligent platform routing:

ToolDescription
route_to_image_generationRoute to image generation with optimal model + params
route_to_video_generationRoute to video generation with model + duration
route_to_chatRoute to LLM chat with selected model
route_to_music_generationRoute to music/audio generation
route_to_image_editingRoute to image editing tools (upscale, bg remove, etc.)
route_to_3d_generationRoute to 3D model generation
answer_questionDirect text answer for FAQ/help
route_to_brandRoute to brand kit management
route_to_toolsRoute to platform tools (face swap, lip sync, etc.)
create_workflowMulti-step workflow for complex tasks

Dynamic Model Awareness ​

Gabriel only recommends models that are currently available. Model availability is checked against the platform's model status database (refreshed every 60 seconds). If a model is disabled or experiencing issues, Gabriel automatically selects the next best alternative.

Prompt Enhancement ​

When enhance_prompt: true is set, Gabriel applies model-specific prompt engineering:

Model FamilyEnhancement Strategy
SeedreamAdds photorealistic quality terms, resolution hints, optimized structure
SeedanceAdds camera movement, temporal progression, cinematic terms
FLUXAdds detailed composition, style-specific tokens
ImagenAdds quality terms, structured scene description
WanAdds motion description, scene progression
Grok ImagineAdds studio lighting terms, product photography markers, commercial quality

Multi-Step Workflows ​

When a request requires multiple operations, Gabriel returns action: "workflow" with a steps array:

json
{
  "action": "workflow",
  "params": {
    "steps": [
      { "action": "route_to_image_generation", "target": "/generate/new", "params": {"model": "seedream-5-0-260128", "prompt": "..."} },
      { "action": "route_to_image_editing", "target": "/tools/remove-bg", "params": {"tool": "background_removal"} },
      { "action": "route_to_brand", "target": "/brand", "params": {"action": "save_asset"} }
    ],
    "description": "Generate logo, remove background, save to brand kit"
  }
}

Credit Estimation ​

Gabriel estimates costs for 50+ models across image, video, and chat:

Image Models ​

ModelCredits/image
flux-2-klein-4b1.0
minimax-image-011.0
grok-imagine-image1.0
seedream-5-0-2601282.0
seedream-4-5-2511282.0
flux-1.1-pro2.0
flux-kontext-pro2.0
flux-2-pro2.0
imagen-4-standard3.0
grok-imagine-image-pro3.0
imagen-4-ultra5.0

Video Models ​

Most models bill per second (see the full catalog); MiniMax Hailuo bills a flat per-video amount.

ModelCredits/s
wan2.2-t2v-plus1.2
hailuo-o2— (6 flat)
kling-v35
seedance-2-0-pro9.4
sora-28
gemini-omni-flash6
veo-3.1-generate-00112
grok-imagine-video-1.59

Chat / LLM Models ​

ModelCredits/message
gemini-flash1.0
gemini-pro2.0
gpt-4o2.0
claude-sonnet2.0

Best Value

seedream-5-0-260128 offers the best quality-to-credit ratio for image generation, and wan2.2-t2v-plus / hailuo-o2 are the most cost-effective for video. For chat, gemini-flash (1 cr) is the cheapest option.


Error Handling ​

All endpoints gracefully degrade on failure:

ScenarioBehavior
Timeout (>5s for Gabriel, >10s for Translate)Returns error action / original text
Model errorAuto-failover to backup model (transparent to caller)
Rate limit exceededHTTP 429 with retry-after header
Invalid JWTHTTP 401 (for authenticated endpoints)
Missing promptHTTP 422 with validation details

Model Failover ​

Gabriel uses a multi-model failover chain. If the primary model is unavailable, it automatically falls back without returning an error:

Primary → Backup 1 → Backup 2

The response always succeeds unless all models in the chain are down.


Integration Patterns ​

Building a Conversational Assistant ​

python
from fotohub import FotoHub

client = FotoHub(api_key="your-api-key")

def handle_user_message(message: str, user_context: dict):
    result = client.gabriel.classify(
        prompt=message,
        language="en",
        context=user_context,
        enhance_prompt=True
    )
    
    if result["action"] == "route":
        return {
            "message": f"I'll use {result['model_selected']} (~{result['credits_estimated']} credits)",
            "action": result["target"],
            "params": result["params"],
            "tips": result.get("tips", [])
        }
    elif result["action"] == "workflow":
        steps = result["params"]["steps"]
        return {
            "message": f"This requires {len(steps)} steps: {result['params']['description']}",
            "workflow": steps
        }
    elif result["action"] == "answer":
        return {"message": result["answer"]}
    else:
        return {"message": "I couldn't understand that request."}

Real-time Suggestions with Streaming ​

typescript
import { FotoHub } from 'fotohub';

const client = new FotoHub({ apiKey: 'your-api-key' });

// 1. Autocomplete as user types (debounced 300ms)
const suggestions = await client.gabriel.suggest('portrait photo', {
  tab: 'image',
  page: '/generate/new'
});

// 2. Stream the final classification
const stream = await client.gabriel.stream({
  prompt: 'Generate a cinematic portrait with dramatic lighting',
  language: 'en'
});

for await (const event of stream) {
  if (event.type === 'thinking') updateUI('Processing...');
  if (event.type === 'routing') updateUI(`Using ${event.tool}...`);
  if (event.type === 'result') navigateTo(event.target, event.params);
}

Proactive Onboarding Tips ​

typescript
// Show contextual tips when user lands on a page
const { recommendations } = await fetch(
  'https://apis.fotohub.app/v1/ai/gabriel/recommend',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      page: '/generate/new',
      wallet_balance_usd: user.credits,
      has_brand: user.brands.length > 0,
      recent_actions: ['image_generation', 'image_generation']
    })
  }
).then(r => r.json());

// Display as floating chips:
// "Try video generation — Seedance creates 5s clips for 1 credit"
// "Create a Brand Kit for consistent style"

Multi-language App with Auto-translation ​

typescript
async function translateUI(texts: string[], targetLang: string) {
  const results = await Promise.all(
    texts.map(text =>
      fetch('https://apis.fotohub.app/v1/ai/translate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text, target_language: targetLang })
      }).then(r => r.json())
    )
  );
  return results.map(r => r.translated_text);
}