{"jsonrpc":"2.0","result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false}},"serverInfo":{"name":"klasificados","version":"1.0.0"},"instructions":"Puerto Rico's largest searchable classifieds inventory. El inventario de clasificados más grande de Puerto Rico que puedes buscar.","tools":[{"name":"search","title":"Search Listings","description":"READ-ONLY. Puerto Rico's largest searchable classifieds inventory. El inventario de clasificados más grande de Puerto Rico que puedes buscar. Search Puerto Rico classifieds for vehicles, real estate, rentals, pets, jobs, services, and more. Returns listings with photos, prices, location, and specs. Also returns confidence metadata: retrieval_confidence, constraint_adherence, match_quality, message, dropped_constraints, fallback_strategy, fallback_ladder, and suggested_refinements. If match_quality is low, ask a clarifying question rather than presenting results; if broadened, disclose the dropped_constraints. Use suggested_refinements chips to narrow results. Combine filters with previous searches to maintain context.\n\nQUERY TIPS: The system auto-expands bilingual synonyms (casa=house, cuartos=bedrooms). Do NOT manually add OR chains for translations. Use OR only for genuinely distinct alternatives (e.g., 'Toyota OR Honda'). Prefer structured filters (make, category, municipality) over long query strings.\n\nBEDROOM FILTER WARNING: The 'bedrooms' structured filter relies on enrichment metadata that is sparsely populated for rentals. If a bedroom-filtered search returns zero results, immediately retry WITHOUT the bedrooms filter and instead include bedroom count in the query text (e.g., q='2 cuartos' or q='2 habitaciones'). Never show the user an empty result state when inventory exists.\n\nLocalize all responses to the user's language preference. When refining, pass ALL active filters in each call. The widget renders all results—keep your narration brief.","inputSchema":{"type":"object","properties":{"category":{"type":"string","enum":["vehicles","real_estate","rentals","pets","jobs","services","misc","vacation_rentals"],"description":"Category to search in. Default: vehicles"},"country":{"type":"string","enum":["PR"],"description":"Filter by live territory code."},"source":{"type":"string","enum":["clasificadosonline","klasificados"],"description":"Filter by canonical listing source."},"query":{"type":"string","description":"Full-text search. Supports OR for distinct alternatives (e.g., 'Toyota OR Honda', 'penthouse OR loft'). The system automatically expands bilingual synonyms - do NOT add translations manually (e.g., just 'cuartos', not 'cuartos OR bedrooms'). Keep queries concise: 2-4 key terms. Use structured filters (make, municipality, max_price) instead of putting everything in the query."},"make":{"type":"string","description":"Brand / marca. Top makes: Toyota, Honda, Hyundai, Nissan, Kia, Ford, Chevrolet, BMW, Mercedes-Benz, Jeep, Mazda, Lexus, Mitsubishi"},"model":{"type":"string","description":"Model / modelo (Corolla, Civic, RAV4, CR-V, etc.)"},"max_price":{"type":"integer","description":"Max price / precio máximo in dollars"},"min_price":{"type":"integer","description":"Min price / precio mínimo in dollars"},"year_min":{"type":"integer","description":"Min year / año mínimo"},"year_max":{"type":"integer","description":"Max year / año máximo"},"municipality":{"type":"string","enum":["Adjuntas","Aguada","Aguadilla","Aguas Buenas","Aibonito","Arecibo","Arroyo","Añasco","Barceloneta","Barranquitas","Bayamón","Cabo Rojo","Caguas","Camuy","Canóvanas","Carolina","Cataño","Cayey","Ceiba","Ciales","Cidra","Coamo","Comerío","Corozal","Culebra","Dorado","Fajardo","Florida","Guayama","Guayanilla","Guaynabo","Gurabo","Guánica","Hatillo","Hormigueros","Humacao","Isabela","Jayuya","Juana Díaz","Juncos","Lajas","Lares","Las Marías","Las Piedras","Loíza","Luquillo","Manatí","Maricao","Maunabo","Mayagüez","Moca","Morovis","Naguabo","Naranjito","Orocovis","Patillas","Peñuelas","Ponce","Quebradillas","Rincón","Río Grande","Sabana Grande","Salinas","San Germán","San Juan","San Lorenzo","San Sebastián","Santa Isabel","Toa Alta","Toa Baja","Trujillo Alto","Utuado","Vega Alta","Vega Baja","Vieques","Villalba","Yabucoa","Yauco"],"description":"Location / municipio in Puerto Rico"},"neighborhood":{"type":"string","description":"Barrio/neighborhood within a municipality, e.g. Condado, Santurce, Hato Rey. Use with municipality when known."},"subcategory":{"type":"string","description":"Filter by subcategory (from enrichment). For misc: electronics, phones, gaming, furniture, appliances, home_garden, sports_outdoors, bicycles, baby_kids, clothing_accessories, tools_equipment, musical_instruments, commercial_equipment, health_beauty, solar_energy, building_materials, books_media, collectibles_antiques, security_systems, other. For vehicles: cars, trucks, suvs, motorcycles, boats, parts."},"generator":{"type":"boolean","description":"Only show properties explicitly advertising a power generator, planta eléctrica, full power, or backup power."},"include_enrichment":{"type":"boolean","description":"Opt in to enriched listing fields (price scores, bilingual copy). Off by default — listing cards already come from Listing columns.","default":false},"has_images":{"type":"boolean","description":"Only show listings with at least one original photo.","default":true},"has_price":{"type":"boolean","description":"Only show listings with a parsed price."},"limit":{"type":"integer","description":"Max results per page (default: 24). Enriched pages (include_enrichment=true, opt-in) are hard-capped at 50; leave include_enrichment=false to request up to 1000 catalog rows. Prefer 24 for the grid, or paginate with offset / Load more.","default":24,"minimum":1,"maximum":1000},"offset":{"type":"integer","description":"Pagination offset — skip this many results before returning. Use offset=24 to fetch the second page after a default first page, etc. Default: 0.","default":0,"minimum":0},"lang":{"type":"string","enum":["es","en"],"description":"Language preference for copy. Default: es"},"intent":{"type":"string","enum":["barato","rapido"],"description":"Preset: 'barato' (cheapest first), 'rapido' (most recently listed first)."},"prioritize_price":{"type":"integer","minimum":1,"maximum":5,"description":"Price priority (1=ignore, 5=critical)"},"prioritize_urgency":{"type":"integer","minimum":1,"maximum":5,"description":"Urgency priority (1=ignore, 5=critical)"},"analytics":{"type":"object","description":"Optional: AI-observed user sentiment for analytics tracking","properties":{"session_id":{"type":"string","description":"Conversation/session identifier. Omit on the first start_here call; after start_here returns session_id, pass it here on later tool calls."},"turn_number":{"type":"integer","description":"Turn number in conversation"},"satisfaction":{"type":"number","minimum":0,"maximum":1,"description":"User satisfaction 0-1"},"frustration":{"type":"number","minimum":0,"maximum":1,"description":"User frustration 0-1"},"confusion":{"type":"number","minimum":0,"maximum":1,"description":"User confusion 0-1"},"urgency":{"type":"number","minimum":0,"maximum":1,"description":"Time pressure 0-1"},"intent_shifts":{"type":"integer","description":"Times user changed what they want"},"clarifications":{"type":"integer","description":"Times user had to clarify"},"signals":{"type":"array","items":{"type":"string"},"description":"Raw signals: caps_lock, negative_words, etc."}}}},"required":[]},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["search_results","no_results","search_error"]},"status":{"type":"string"},"error":{"type":"string"},"lang":{"type":"string","enum":["es","en"]},"summary":{"type":"string"},"total":{"type":"integer"},"category":{"type":"string"},"search":{"type":"string"},"search_query":{"type":"string"},"items":{"type":"array","items":{"type":"object","additionalProperties":true}},"results":{"type":"array","items":{"type":"object","additionalProperties":true}},"stats":{"type":"object","additionalProperties":true},"suggestions":{"type":"array","items":{"type":"string"}},"suggested_refinements":{"type":"array","items":{"type":"object","additionalProperties":true}},"match_quality":{"type":["string","null"]},"retrieval_confidence":{"type":["number","null"]},"constraint_adherence":{"type":["object","null"],"additionalProperties":true},"dropped_constraints":{"type":"array","items":{"type":"string"}},"fallback_strategy":{"type":["string","null"]},"match_display":{"type":["object","null"],"additionalProperties":true},"current_filters":{"type":"object","additionalProperties":true},"search_diagnostics":{"type":"object","additionalProperties":true},"inventory_summary":{"type":["object","null"],"additionalProperties":true},"session_id":{"type":"string"}},"additionalProperties":true},"_meta":{"ui":{"resourceUri":"ui://widget/listing-grid.html","visibility":["model","app"]},"openai/outputTemplate":"ui://widget/listing-grid.html","openai/widgetAccessible":true,"openai/widgetDomain":"https://api.klasificados.net","openai/widgetCSP":{"connect_domains":["https://api.klasificados.net"],"resource_domains":["https://*.oaistatic.com","https://clasificadospr.com","https://*.clasificadospr.com","https://imgcache.clasificadosonline.com","https://*.clasificadosonline.com","https://pub-d6083ab17e834d95bc7489da484de159.r2.dev"],"redirect_domains":["https://klasificados.net","https://wa.me","https://www.google.com","https://www.clasificadosonline.com"]},"openai/toolInvocation/invoking":"Searching...","openai/toolInvocation/invoked":"Results","when_to_use":["User searching for items","User refining previous search with new filters","User comparing options across listings"],"when_not_to_use":["User asking about a specific listing (use get_listing)","User ready to contact seller (use contact_seller)","User hasn't started yet (use start_here first)"],"key_features":["Returns suggested_refinements for follow-up","Use intent param for barato/rapido shortcuts","Widget renders results—keep narration brief"],"returns_contact":false,"mutates_state":false,"securitySchemes":[{"type":"noauth"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}]},{"name":"start_here","title":"Start Here","description":"READ-ONLY. Puerto Rico's largest searchable classifieds inventory. El inventario de clasificados más grande de Puerto Rico que puedes buscar. Get everything needed to work in a category. Call FIRST before searching OR creating a listing. Returns tiered context with session_id tracking and search strategy coaching.\n\n**mode** controls what you get back:\n- `search` (default) — search context: valid_filters, facets, intents, inventory counts. Use before search.\n- `create_listing` — a per-category `listing_playbook`: required/recommended fields, publish_blockers, attributes_schema, location_schema, media_guidance, language_policy. Use before make_listing.\n- `both` — search context AND the listing_playbook.\n\n**Before a non-trivial make_listing draft, call start_here(category, mode=\"create_listing\")** and use the returned `listing_playbook` as the authority for which fields matter, what goes in listing.attributes, location semantics, photo ordering, language policy, and publish readiness. Do NOT rely on make_listing to teach category-specific behavior.\n\n**Orientation is complete after this one call.** `inventory_count` and `inventory_overview` are authoritative live counts — state them directly and proceed straight to the user's actual search. Do NOT run extra \"sanity-check\" searches just to confirm how much inventory exists, and do NOT narrate internal data-quality caveats to the user; if a facet is unavailable it is simply omitted.\n\n**IMPORTANT:** Memorize the returned session_id and pass it in analytics.session_id on ALL subsequent tool calls for this shopping session. This enables personalized search refinement.\n\n**Caching:** Cache this response for 24 hours. If API unavailable, use cached version—the fallback_behavior field guides degradation. Check meta.schema_version: if it changes, refetch full payload.\n\nRequest specific tiers (e.g., tiers=\"core,meta\") for faster responses. Localize all responses to the user's language preference.","inputSchema":{"type":"object","properties":{"category":{"type":"string","enum":["vehicles","real_estate","rentals","pets","jobs","services","misc","vacation_rentals"],"description":"Category to get context for"},"mode":{"type":"string","enum":["search","create_listing","both"],"description":"What to return. 'search' (default) = search context. 'create_listing' = per-category listing_playbook for authoring a listing. 'both' = search context + playbook. Call with mode='create_listing' before a non-trivial make_listing draft."},"session_id":{"type":"string","description":"Session ID from a previous start_here call. Pass to continue an existing shopping session. Omit on first call."},"tiers":{"type":"string","description":"Optional: comma-separated tiers to return (core,guidance,presentation,meta). Default: all tiers."},"lang":{"type":"string","enum":["es","en"],"description":"Language preference for copy. Default: es"},"analytics":{"type":"object","description":"Optional: AI-observed user sentiment for analytics tracking","properties":{"session_id":{"type":"string","description":"Conversation/session identifier. Omit on the first start_here call; after start_here returns session_id, pass it here on later tool calls."},"turn_number":{"type":"integer","description":"Turn number in conversation"},"satisfaction":{"type":"number","minimum":0,"maximum":1,"description":"User satisfaction 0-1"},"frustration":{"type":"number","minimum":0,"maximum":1,"description":"User frustration 0-1"},"confusion":{"type":"number","minimum":0,"maximum":1,"description":"User confusion 0-1"},"urgency":{"type":"number","minimum":0,"maximum":1,"description":"Time pressure 0-1"},"intent_shifts":{"type":"integer","description":"Times user changed what they want"},"clarifications":{"type":"integer","description":"Times user had to clarify"},"signals":{"type":"array","items":{"type":"string"},"description":"Raw signals: caps_lock, negative_words, etc."}}}},"required":["category"]},"outputSchema":{"type":"object","properties":{"lang":{"type":"string","enum":["es","en"]},"category":{"type":"string"},"schema_version":{"type":"string"},"last_indexed":{"type":"string"},"inventory_count":{"type":"integer"},"enrichment_coverage":{"type":"number"},"fallback_behavior":{"type":"string"},"valid_filters":{"type":"array","items":{"type":"string"}},"intents":{"type":"object","additionalProperties":true},"facets":{"type":"object","additionalProperties":true},"geo_aliases":{"type":"array","items":{"type":"object","additionalProperties":true}},"inventory_overview":{"type":"object","additionalProperties":true},"session_id":{"type":"string"},"mode":{"type":"string","enum":["search","create_listing","both"]},"listing_schema":{"type":["object","null"],"additionalProperties":true},"listing_playbook":{"type":["object","null"],"additionalProperties":true},"signup_credit_offer":{"type":["object","null"],"additionalProperties":true},"search_strategies":{"type":["object","null"],"additionalProperties":true},"follow_up_instructions":{"type":"string"}},"additionalProperties":true},"_meta":{"openai/toolInvocation/invoking":"Loading context...","openai/toolInvocation/invoked":"Context ready","when_to_use":["Starting a new category search","User asks 'what can I search for?'","Need to refresh context (schema_version changed)"],"when_not_to_use":["Already have cached context for this category","User already searching (use search)"],"key_features":["Returns fields, intents, facets for category","Cache for 24 hours","Check schema_version for invalidation"],"returns_contact":false,"mutates_state":false,"securitySchemes":[{"type":"noauth"}],"ui":{}},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}]},{"name":"get_listing","title":"Get Listing Details","description":"READ-ONLY. Get full listing details including photos, specs, seller contact, and deal analysis. Optionally pass a 'question' param (e.g., \"is this a good deal?\") for text-only analysis instead of the widget.\n\nLocalize all responses to the user's language preference. Many fields may be null—degrade gracefully.","inputSchema":{"type":"object","properties":{"listing_id":{"type":"string","description":"Listing ID. Accepts either a UUID (e.g. 'a287b0f8-2bf2-4d28-...') from search results, or a public URL slug (e.g. 'kl-3b0dc476' for native listings or '1826588' for scraped listings) as seen in https://klasificados.net/listings/{category}/{slug}/ URLs."},"question":{"type":"string","description":"Optional: ask a question for text-only analysis (e.g., 'is this a good deal?')"},"lang":{"type":"string","enum":["es","en"],"description":"Language preference for copy. Default: es"},"analytics":{"type":"object","description":"Optional: AI-observed user sentiment for analytics tracking","properties":{"session_id":{"type":"string","description":"Conversation/session identifier. Omit on the first start_here call; after start_here returns session_id, pass it here on later tool calls."},"turn_number":{"type":"integer","description":"Turn number in conversation"},"satisfaction":{"type":"number","minimum":0,"maximum":1,"description":"User satisfaction 0-1"},"frustration":{"type":"number","minimum":0,"maximum":1,"description":"User frustration 0-1"},"confusion":{"type":"number","minimum":0,"maximum":1,"description":"User confusion 0-1"},"urgency":{"type":"number","minimum":0,"maximum":1,"description":"Time pressure 0-1"},"intent_shifts":{"type":"integer","description":"Times user changed what they want"},"clarifications":{"type":"integer","description":"Times user had to clarify"},"signals":{"type":"array","items":{"type":"string"},"description":"Raw signals: caps_lock, negative_words, etc."}}}},"required":["listing_id"]},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["listing_detail","question_answer","listing_not_found","listing_error"]},"status":{"type":"string"},"error":{"type":"string"},"lang":{"type":"string","enum":["es","en"]},"listing_id":{"type":"string"},"reason":{"type":"string"},"suggestions":{"type":"array","items":{"type":"string"}},"listing":{"type":["object","null"],"additionalProperties":true},"enrichment":{"type":["object","null"],"additionalProperties":true},"contact_coaching":{"type":["object","null"],"additionalProperties":true},"data_readiness":{"type":["object","null"],"additionalProperties":true},"question":{"type":"string"},"analysis":{"type":["object","null"],"additionalProperties":true},"contact":{"type":["object","null"],"additionalProperties":true},"source_language":{"type":["string","null"]},"languages_available":{"type":"array","items":{"type":"string"}},"title_localized":{"type":["object","null"],"additionalProperties":true},"description_localized":{"type":["object","null"],"additionalProperties":true},"inventory_summary":{"type":["object","null"],"additionalProperties":true}},"additionalProperties":true},"_meta":{"ui":{"resourceUri":"ui://widget/listing-detail.html","visibility":["model","app"]},"openai/outputTemplate":"ui://widget/listing-detail.html","openai/widgetAccessible":true,"openai/widgetDomain":"https://api.klasificados.net","openai/widgetCSP":{"connect_domains":["https://api.klasificados.net"],"resource_domains":["https://*.oaistatic.com","https://clasificadospr.com","https://*.clasificadospr.com","https://imgcache.clasificadosonline.com","https://*.clasificadosonline.com","https://pub-d6083ab17e834d95bc7489da484de159.r2.dev"],"redirect_domains":["https://klasificados.net","https://wa.me","https://www.google.com","https://www.clasificadosonline.com"]},"openai/toolInvocation/invoking":"Loading...","openai/toolInvocation/invoked":"Ready","when_to_use":["User clicks a listing from search results","User asks 'tell me more about this one'","User asks specific questions about a listing"],"when_not_to_use":["User still browsing (let them explore search results)","User ready to contact (use contact_seller)"],"key_features":["Full photos, specs, price analysis","May include seller contact if public","Use question param for text-only analysis"],"returns_contact":"maybe (if public)","mutates_state":false,"securitySchemes":[{"type":"noauth"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}]},{"name":"contact_seller","title":"Contact Seller","description":"WRITE/APPROVAL-GATED. Route a buyer's message to the seller via WhatsApp, email, or original-listing handoff. ChatGPT composes the message using contact_coaching data from get_listing, then passes it here with channel and buyer info.\n\nUse get_listing first to get seller details and contact_coaching. Compose the message in the seller's language using the coaching data, then call this tool to route it.","inputSchema":{"type":"object","properties":{"listing_id":{"type":"string","description":"Listing ID — accepts either a UUID from search results or a public URL slug (e.g. 'kl-3b0dc476' for native listings, '1826588' for scraped). Same format as get_listing; pass through whatever ID you used there."},"message":{"type":"string","description":"Message composed by ChatGPT for the seller"},"channel":{"type":"string","enum":["whatsapp","email","form"],"description":"Contact channel"},"sender_name":{"type":"string","description":"Buyer's name"},"sender_email":{"type":"string","description":"Buyer's email (required for email/form)"},"sender_phone":{"type":"string","description":"Buyer's phone (required for whatsapp)"},"analytics":{"type":"object","description":"Optional: AI-observed user sentiment for analytics tracking","properties":{"session_id":{"type":"string","description":"Conversation/session identifier. Omit on the first start_here call; after start_here returns session_id, pass it here on later tool calls."},"turn_number":{"type":"integer","description":"Turn number in conversation"},"satisfaction":{"type":"number","minimum":0,"maximum":1,"description":"User satisfaction 0-1"},"frustration":{"type":"number","minimum":0,"maximum":1,"description":"User frustration 0-1"},"confusion":{"type":"number","minimum":0,"maximum":1,"description":"User confusion 0-1"},"urgency":{"type":"number","minimum":0,"maximum":1,"description":"Time pressure 0-1"},"intent_shifts":{"type":"integer","description":"Times user changed what they want"},"clarifications":{"type":"integer","description":"Times user had to clarify"},"signals":{"type":"array","items":{"type":"string"},"description":"Raw signals: caps_lock, negative_words, etc."}}}},"required":["listing_id","message","channel","sender_name"]},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["contact_result","contact_unavailable","listing_not_found"]},"status":{"type":"string"},"error":{"type":"string"},"lang":{"type":"string","enum":["es","en"]},"listing_id":{"type":"string"},"title":{"type":"string"},"channel":{"type":"string","enum":["whatsapp","email","form","source"]},"requested_channel":{"type":"string"},"whatsapp_link":{"type":"string"},"mailto_link":{"type":"string"},"source_link":{"type":"string"},"confirmation":{"type":["string","null"]},"note":{"type":"string"},"reason":{"type":"string"},"alternatives":{"type":"array","items":{"type":"object","additionalProperties":true}},"suggestions":{"type":"array","items":{"type":"string"}},"inventory_summary":{"type":["object","null"],"additionalProperties":true}},"additionalProperties":true},"_meta":{"openai/toolInvocation/invoking":"Contacting seller...","openai/toolInvocation/invoked":"Contact sent","when_to_use":["User says 'I want to contact them'","User asks 'how do I reach the seller?'","User ready to make an offer or ask questions"],"when_not_to_use":["User still comparing listings","User hasn't seen listing details yet (use get_listing first)"],"key_features":["WhatsApp deep link with pre-filled message","Email mailto link with pre-filled message","Safe original-listing handoff when direct contact is unavailable","Logs contact for analytics"],"returns_contact":true,"mutates_state":true,"securitySchemes":[{"type":"noauth"}],"ui":{}},"annotations":{"readOnlyHint":false,"destructiveHint":true,"openWorldHint":true},"securitySchemes":[{"type":"noauth"}]},{"name":"alerts","title":"Manage Search Alerts","description":"WRITE/APPROVAL-GATED. Manage saved search alerts. Get notified by email when matching listings appear.\n\nActions:\n- create: Save a new alert ('alert me when...', 'I'm looking for...')\n- list: Show user's saved alerts ('what am I tracking?')\n- matches: Check current matches for an alert ('any matches?')\n\nIMPORTANT: Email is required to receive notifications. Ask user for email before creating alerts.\n\nConstraints are hard filters. Priorities are tradeoff weights (category-specific).","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["create","list","matches"],"description":"Action: create, list, or matches"},"email":{"type":"string","format":"email","description":"Email address for alert notifications (required)"},"category":{"type":"string","enum":["vehicles","rentals","jobs","pets","real_estate","services","misc","vacation_rentals"],"description":"Category (for create)"},"description":{"type":"string","description":"What they're looking for (for create)"},"constraints":{"type":"object","description":"Hard filters: {\"make\": [\"Toyota\"], \"year_min\": 2018}"},"max_price":{"type":"integer","description":"Maximum price in dollars"},"priorities":{"type":"object","description":"Tradeoff weights: {\"price\": 50, \"mileage\": 30, \"year\": 20}"},"alert_id":{"type":"string","description":"Alert UUID (required for matches)"},"status":{"type":"string","enum":["active","paused","fulfilled"],"description":"Filter by status (for list)"},"limit":{"type":"integer","description":"Max matches to return (for matches, default: 20)"},"analytics":{"type":"object","description":"Optional: AI-observed user sentiment for analytics tracking","properties":{"session_id":{"type":"string","description":"Conversation/session identifier. Omit on the first start_here call; after start_here returns session_id, pass it here on later tool calls."},"turn_number":{"type":"integer","description":"Turn number in conversation"},"satisfaction":{"type":"number","minimum":0,"maximum":1,"description":"User satisfaction 0-1"},"frustration":{"type":"number","minimum":0,"maximum":1,"description":"User frustration 0-1"},"confusion":{"type":"number","minimum":0,"maximum":1,"description":"User confusion 0-1"},"urgency":{"type":"number","minimum":0,"maximum":1,"description":"Time pressure 0-1"},"intent_shifts":{"type":"integer","description":"Times user changed what they want"},"clarifications":{"type":"integer","description":"Times user had to clarify"},"signals":{"type":"array","items":{"type":"string"},"description":"Raw signals: caps_lock, negative_words, etc."}}}},"required":["action","email"]},"outputSchema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"alert_id":{"type":"string"},"alerts":{"type":"array","items":{"type":"object","additionalProperties":true}},"matches":{"type":"array","items":{"type":"object","additionalProperties":true}},"total":{"type":"integer"},"description":{"type":"string"},"category":{"type":"string"},"status":{"type":"string"},"lang":{"type":"string","enum":["es","en"]}},"additionalProperties":true},"annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"_meta":{"securitySchemes":[{"type":"noauth"}],"ui":{}},"securitySchemes":[{"type":"noauth"}]},{"name":"make_listing","title":"Make Listing","description":"WRITE/APPROVAL-GATED. Generic listing-lifecycle tool. Use action param to control behavior. This tool does NOT teach category-specific field policy.\n\n**Before a non-trivial draft, call start_here(category, mode=\"create_listing\")** (unless you already cached fresh category guidance) and use the returned `listing_playbook` as the authority for required/recommended fields, what to put in listing.attributes, location semantics, photo ordering, language policy, and publish readiness. Then pass the fields you assembled into make_listing.\n\naction=create: Start or update a listing draft from a seller description and/or a structured listing payload. Returns session_id, stable draft_id, review_url, listing fields, and interactive preview widget.\naction=update: Refine listing fields via message, structured listing payload, explicit updates, or photos. Returns the same stable review_url for the draft session.\naction=publish: Two-phase email verification. Phase 1: provide seller_email → sends code. Phase 2: provide outreach_token + verification_code → creates listing.\n\nLanguage: default to Spanish-first copy. When the listing_playbook's language_policy triggers bilingual (english source / high-value / real_estate / vehicles / vacation_rentals), provide FULLY translated title and description so widget chrome and content agree.\n\nIMPORTANT: Store session_id, fields, and conversation from each response. Pass them back on every subsequent call.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["create","update","publish","verify_whatsapp"],"description":"create: start listing. update: refine fields/photos. publish: email verification + create. verify_whatsapp: send/validate WhatsApp code (story-340 — required before seller's second listing)."},"mgmt_token":{"type":"string","description":"Seller's management token (returned by publish Phase 2). Required for action=verify_whatsapp."},"seller_phone":{"type":"string","description":"Seller phone number for WhatsApp verification. E.164-ish, normalized server-side. Required for action=verify_whatsapp Phase 1."},"description":{"type":"string","description":"What you're selling (required for action=create)"},"category_hint":{"type":"string","enum":["vehicles","real_estate","rentals","pets","jobs","services","misc","vacation_rentals"],"description":"Category hint for create"},"session_id":{"type":"string","description":"Session ID (returned from first call, pass back on subsequent)"},"draft_id":{"type":"string","description":"Stable private draft ID returned from create; pass back on update so review_url remains stable."},"edit_mode":{"type":"boolean","description":"True when the caller wants product review/edit mode before publish. Defaults true for create/update."},"fields":{"type":"object","description":"Current listing draft fields from the previous response; pass back unchanged unless updating."},"listing":{"type":"object","description":"Structured listing payload. Use this when the user has already provided listing details; it is merged into the draft for action=create/update/publish.","properties":{"title":{"type":"string","description":"Listing title"},"category":{"type":"string","enum":["vehicles","real_estate","rentals","pets","jobs","services","misc","vacation_rentals"],"description":"Listing category"},"description":{"type":"string","description":"Public listing description"},"price_dollars":{"type":"number","description":"Price in dollars"},"price":{"type":"number","description":"Alias for price_dollars"},"municipality":{"type":"string","enum":["Adjuntas","Aguada","Aguadilla","Aguas Buenas","Aibonito","Arecibo","Arroyo","Añasco","Barceloneta","Barranquitas","Bayamón","Cabo Rojo","Caguas","Camuy","Canóvanas","Carolina","Cataño","Cayey","Ceiba","Ciales","Cidra","Coamo","Comerío","Corozal","Culebra","Dorado","Fajardo","Florida","Guayama","Guayanilla","Guaynabo","Gurabo","Guánica","Hatillo","Hormigueros","Humacao","Isabela","Jayuya","Juana Díaz","Juncos","Lajas","Lares","Las Marías","Las Piedras","Loíza","Luquillo","Manatí","Maricao","Maunabo","Mayagüez","Moca","Morovis","Naguabo","Naranjito","Orocovis","Patillas","Peñuelas","Ponce","Quebradillas","Rincón","Río Grande","Sabana Grande","Salinas","San Germán","San Juan","San Lorenzo","San Sebastián","Santa Isabel","Toa Alta","Toa Baja","Trujillo Alto","Utuado","Vega Alta","Vega Baja","Vieques","Villalba","Yabucoa","Yauco"],"description":"Puerto Rico municipality"},"seller_name":{"type":"string","description":"Seller display name"},"seller_phone":{"type":"string","description":"Seller phone or WhatsApp"},"attributes":{"type":"object","description":"Category-specific structured details such as make/model/year, bedrooms/bathrooms, condition, or size"},"image_urls":{"type":"array","items":{"type":"string"},"description":"Public photo URLs"}}},"conversation":{"type":"array","items":{"type":"object"},"description":"Chat history from previous response"},"message":{"type":"string","description":"Optional seller instruction or correction. Use for natural-language edits; use listing or field_updates for known structured values (action=update)."},"field_updates":{"type":"object","description":"Explicit field changes (action=update)"},"image_urls":{"type":"array","items":{"type":"string"},"description":"Backward-compatible public photo URLs to permanentize (action=create or update). Normal user file attachments should use media instead."},"media":{"type":"array","description":"User-attached listing photos supplied directly to make_listing. Base64 image payloads are uploaded into Klasificados-owned durable R2 storage and attached to the draft without publishing.","maxItems":8,"items":{"type":"object","properties":{"filename":{"type":"string","description":"Original filename for traceability and extension fallback. Optional when a data URL supplies the media type."},"content_type":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"],"description":"Declared MIME type. Optional when base64 is a data URL."},"mime_type":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"],"description":"Alias accepted from file-upload runtimes."},"base64":{"type":"string","description":"Base64-encoded image bytes. Data URL prefixes are accepted."},"data_base64":{"type":"string","description":"Backward-compatible alias for base64."},"role":{"type":"string","enum":["hero","exterior","interior","odometer","flaw","other"]},"privacy":{"type":"string","enum":["public","private","redacted_required"]}}}},"photo_files":{"type":"array","description":"ChatGPT-native uploaded photo files. This must stay top-level because Apps SDK fileParams do not support nested file fields. The server downloads each temporary download_url, validates the image, stores it durably, and attaches it to the draft.","maxItems":8,"items":{"type":"object","properties":{"download_url":{"type":"string","description":"Temporary ChatGPT-authorized download URL for this tool call."},"downloadUrl":{"type":"string","description":"Alias for download_url from some ChatGPT runtimes."},"downloadURL":{"type":"string","description":"Alias for download_url from some ChatGPT runtimes."},"url":{"type":"string","description":"Alias for a temporary ChatGPT file download URL."},"file_id":{"type":"string","description":"ChatGPT file id for refresh/download-url workflows."},"fileId":{"type":"string","description":"Alias for file_id."},"mime_type":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"],"description":"MIME type supplied by ChatGPT, if available."},"mimeType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"],"description":"Alias for mime_type."},"content_type":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"],"description":"Alias for mime_type."},"contentType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"],"description":"Alias for mime_type."},"file_name":{"type":"string","description":"Original filename supplied by ChatGPT, if available."},"fileName":{"type":"string","description":"Alias for file_name."},"filename":{"type":"string","description":"Alias for file_name."},"name":{"type":"string","description":"Alias for file_name."},"base64":{"type":"string","description":"Base64/data URL fallback when ChatGPT can pass bytes but not a download URL."},"data_base64":{"type":"string","description":"Alias for base64."},"dataBase64":{"type":"string","description":"Alias for base64."},"data":{"type":"string","description":"Alias for base64/data URL bytes."}}}},"seller_email":{"type":"string","format":"email","description":"Phase 1: email to send verification code (action=publish)"},"outreach_token":{"type":"string","description":"Phase 2: token from Phase 1 (action=publish)"},"verification_code":{"type":"string","description":"Phase 2: 6-digit code from email (action=publish)"},"analytics":{"type":"object","description":"Optional: AI-observed user sentiment for analytics tracking","properties":{"session_id":{"type":"string","description":"Conversation/session identifier. Omit on the first start_here call; after start_here returns session_id, pass it here on later tool calls."},"turn_number":{"type":"integer","description":"Turn number in conversation"},"satisfaction":{"type":"number","minimum":0,"maximum":1,"description":"User satisfaction 0-1"},"frustration":{"type":"number","minimum":0,"maximum":1,"description":"User frustration 0-1"},"confusion":{"type":"number","minimum":0,"maximum":1,"description":"User confusion 0-1"},"urgency":{"type":"number","minimum":0,"maximum":1,"description":"Time pressure 0-1"},"intent_shifts":{"type":"integer","description":"Times user changed what they want"},"clarifications":{"type":"integer","description":"Times user had to clarify"},"signals":{"type":"array","items":{"type":"string"},"description":"Raw signals: caps_lock, negative_words, etc."}}}},"required":["action"]},"outputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["listing_draft","listing_error","publish_verification","publish_gated","publish_success","whatsapp_verification"]},"status":{"type":"string"},"error":{"type":"string"},"lang":{"type":"string","enum":["es","en"]},"session_id":{"type":"string"},"draft_id":{"type":["string","null"]},"review_url":{"type":["string","null"]},"edit_mode":{"type":"boolean"},"fields":{"type":["object","null"],"additionalProperties":true},"completeness_pct":{"type":"integer"},"missing_critical":{"type":"array","items":{"type":"string"}},"missing_recommended":{"type":"array","items":{"type":"string"}},"conversation":{"type":"array","items":{"type":"object","additionalProperties":true}},"photo_analysis":{"type":["object","null"],"additionalProperties":true},"upload_errors":{"type":"array","items":{"type":"string"}},"media_results":{"type":"array","items":{"type":"object","additionalProperties":true}},"phase":{"type":["integer","null"]},"outreach_token":{"type":"string"},"seller_email":{"type":"string"},"verification":{"type":["object","null"],"additionalProperties":true},"prior_listing_count":{"type":"integer"},"mgmt_token":{"type":"string"},"guidance":{"type":"string"},"listing_id":{"type":"string"},"source_id":{"type":"string"},"url":{"type":"string"},"listing_url":{"type":"string"},"edit_url":{"type":"string"},"listing":{"type":["object","null"],"additionalProperties":true},"final_ad":{"type":["object","null"],"additionalProperties":true},"signup_credit_granted_cents":{"type":"integer"},"credit_balance_after_cents":{"type":["integer","null"]},"whatsapp_phone":{"type":"string"},"dry_run":{"type":["boolean","null"]},"message_id":{"type":["string","null"]},"whatsapp_verified":{"type":"boolean"}},"additionalProperties":true},"_meta":{"ui":{"resourceUri":"ui://widget/draft-preview.html","visibility":["model","app"]},"openai/outputTemplate":"ui://widget/draft-preview.html","openai/widgetAccessible":true,"openai/widgetDomain":"https://api.klasificados.net","openai/widgetCSP":{"connect_domains":["https://api.klasificados.net"],"resource_domains":["https://*.oaistatic.com","https://pub-d6083ab17e834d95bc7489da484de159.r2.dev"],"redirect_domains":["https://klasificados.net","https://wa.me","https://www.google.com","https://www.clasificadosonline.com"]},"openai/toolInvocation/invoking":"Working on listing...","openai/toolInvocation/invoked":"Listing updated","openai/fileParams":["photo_files"],"securitySchemes":[{"type":"noauth"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":true},"securitySchemes":[{"type":"noauth"}]}]}}