Skip to content

AI System

Agent-based AI system for generating travel product content, parsing trip descriptions, and providing an interactive travel consultant. Built on laravel/ai with Gemini as default provider.

  • TCAI Chat Modal — Create or edit a SupplierTour with an interactive AI conversation that confirms destinations before generating (primary workflow)
  • Parse raw trip text (e.g., “Asia India 9N - 2 Delhi - 3 Jaipur”) into itinerary-only data
  • Refine individual product template fields with AI assistance (sparkles icons in admin)
  • Interactive travel planning via the standalone Travel Consultant chat page
Terminal window
# Default provider is openrouter (configured in config/ai.php)
OPENROUTER_API_KEY=your_key
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
OPENROUTER_MODEL="openai/gpt-4o-mini"
# Alternative provider for image tasks
GEMINI_API_KEY=your_key

Config File: config/ai.php

The UsesConfiguredModel concern reads config('ai.model') which resolves to OPENROUTER_MODEL env var.

Source: backend/app/Ai/Concerns/UsesConfiguredModel.php

All agents implement Laravel\Ai\Contracts\Agent and use the Promptable trait with the UsesConfiguredModel concern.

AgentTypeTokensTempTimeoutPurpose
TravelConsultantAgentConversational + Tools40000.7120sInteractive travel planning with multi-turn chat and tool use
TripParserAgentStructured160000.360sParse raw trip text into product template data
TravelContentAgentStructured40000.760sGenerate marketing content from a title
FieldContentAgentStructured20000.730sRefine/generate a single form field
HotelGeneratorAgentStructured40000.7120sGenerate hotel data
TranslationAgentStructured28000.3120sTranslate travel product content

Source: backend/app/Ai/Agents/

ToolPurpose
SearchDestinationsToolSearch POIs by keyword
SearchHotelsToolSearch hotels by city
GetExistingTemplatesToolFind existing templates to avoid duplicates
GenerateFormContentToolGenerate structured form data (title, descriptions, itinerary) for the TCAI chat modal — returns data without persisting to DB
CreateProductTemplateToolCreate a ProductTemplate from trip description (standalone chat page)

Source: backend/app/Ai/Tools/

Orchestrates content generation for product templates. All methods accept an optional TcaiProfile for style customization.

MethodAgent UsedDescription
generateContent(title, profile?)TravelContentAgentGenerate marketing fields from a product title
generateFromRawInput(rawText, profile?, locale?)TripParserAgent + TripContentAgentParse raw trip text into full template data with resolved itinerary. Used by GenerateFormContentTool in the TCAI chat flow.
generateItineraryFromRawInput(rawText, profile?, locale?)TripParserAgentGenerate itinerary-only data (no marketing content). Used by the standalone “Generate Itinerary” action.
refineField(fieldName, currentValue, instructions, context, profile?)FieldContentAgentAI-assisted refinement for a single form field

generateFromRawInput post-processes itineraries through ItineraryResolver to normalize the schema, ensure route continuity between days, and resolve city names to POI IDs via database lookup and Google Places. It includes a fallback parser for shorthand formats like 5N, 7D, and dash-separated N City patterns (e.g., 3 Bogota - 2 Medellin).

Source: backend/app/Services/ProductTemplateAIService.php

Wraps TravelConsultantAgent with three modes:

MethodPurpose
prompt(message, profile?)One-shot text response (standalone chat page)
startConversation(message, user, profile?, locale?)Start a new streaming conversation. Prepends locale context. Returns StreamableAgentResponse.
continueConversation(message, conversationId, user, profile?, locale?)Continue an existing conversation by ID. Returns StreamableAgentResponse.

The streaming methods use RemembersConversations on the agent to maintain multi-turn chat history. Conversation state is tied to the authenticated user via forUser() / continue().

Source: backend/app/Services/TravelConsultantService.php

Support class that bridges AI output and the itinerary data model:

  • normalizeRawItinerary() — converts AI raw output to proper schema
  • ensureRouteContinuity() — fills gaps between days with connecting routes
  • resolveItineraryLocations() — resolves city names to POI IDs via database/Google Places

Source: backend/app/Support/ItineraryResolver.php

TCAI (Travel Consultant AI) Profiles store reusable personality and style configurations that customize agent behavior.

Table: tcai_profiles — columns: name, description, custom_instructions (text), is_default (boolean)

  • TcaiProfile::getDefault() returns the default profile
  • markAsDefault() sets this profile as default (unsets others in a transaction)
  • Has many ProductTemplate records via tcai_profile_id FK
  • Managed in admin at /admin/tcai-profiles

Source: backend/app/Models/TcaiProfile.php

The primary TCAI workflow is an interactive chat modal embedded in the SupplierTour create/edit forms. When an admin pastes raw tour info and clicks “Generate with TCAI”:

  1. A Filament action modal opens containing the TcaiChat Livewire component
  2. The chat starts automatically — the agent analyzes the input, searches destinations/hotels, and proposes a city/nights plan
  3. The admin confirms or adjusts the plan through conversation
  4. Only after explicit confirmation does the agent call GenerateFormContentTool, which generates structured form data (title, descriptions, itinerary) without persisting to DB
  5. A green “Apply to Form” button appears — clicking it dispatches a tcai-content-generated event
  6. The HandlesTcaiContent trait (shared by CreateSupplierTour and EditSupplierTour) receives the event and populates all form fields including repeaters (itinerary, hotel assignments, activity assignments)

Key components:

  • TcaiChat Livewire component — manages chat state, streams AI responses via wire:stream, detects GenerateFormContentTool output markers
  • HandlesTcaiContent trait — event listener that maps AI output to Filament form fields, handles UUID-keyed repeater state
  • GenerateFormContentTool — AI tool that wraps ProductTemplateAIService::generateFromRawInput(), returns data with __tcai_form_data__ markers

Source: backend/app/Livewire/TcaiChat.php, backend/app/Filament/Resources/Suppliers/SupplierTours/Concerns/HandlesTcaiContent.php

Chat-style Livewire page at /admin/ai/travel-consultant (nav group: “AI Tools”). Users select a TCAI Profile from a dropdown and interact with the TravelConsultantAgent. This page uses CreateProductTemplateTool which persists directly to the database (unlike the chatbox modal flow).

Permission required: use_travel_consultant

Sparkles icon buttons on ProductTemplate form fields open a modal with an instructions textarea and TCAI profile selector. Calls ProductTemplateAIService::refineField() and updates the form field in place.

PermissionScope
view_tcai_profileView TCAI profiles
create_tcai_profileCreate TCAI profiles
update_tcai_profileUpdate TCAI profiles
delete_tcai_profileDelete TCAI profiles
use_travel_consultantAccess Travel Consultant chat page
  • Product Templates — AI content generation for templates
  • Roles and Permissions — TCAI permissions
  • Source: backend/app/Ai/ — all agents, tools, and concerns
  • Source: backend/app/Services/ProductTemplateAIService.php
  • Source: backend/app/Services/TravelConsultantService.php
  • Source: backend/app/Livewire/TcaiChat.php
  • Source: backend/app/Filament/Resources/Suppliers/SupplierTours/Concerns/HandlesTcaiContent.php
  • Source: backend/app/Support/ItineraryResolver.php