feat: initial implementation taller-wox.fitlabs.dev

Portal FastAPI + 5 endpoints REST para Bootcamp Agentic AI con
watsonx Orchestrate (FactorIT). Single container, Coolify-ready.

- Landing brandeado FIT con formulario de registro (honeypot anti-bot)
- Tokens itsdangerous para descargas (24h expiry)
- 5 endpoints API: historical/available procedures, member-insights,
  schedule, generate-report (Jinja2 + Plotly)
- SQLite con upsert-on-email para leads + log de descargas
- Admin endpoints (HTTP Basic): leads.json, leads.csv, stats
- 23 tests pytest pasando
- Dockerfile listo para Coolify con volúmenes persistentes
  (/app/leads.db, /app/app/data/reports_output, /app/material)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 03:01:44 +00:00
commit 041e2325e7
56 changed files with 7992 additions and 0 deletions

View File

@@ -0,0 +1,876 @@
{
"name": "Main Desk Concierge-action",
"type": "action",
"counts": {
"actions": 5,
"intents": 2,
"entities": 3,
"data_types": 0,
"collections": 0,
"global_variables": 0
},
"status": "Available",
"language": "en",
"skill_id": "1744ee3b-f227-45b2-9848-98415cc3c872",
"workspace": {
"actions": [
{
"type": "standard",
"steps": [
{
"step": "digression_failure",
"output": {
"generic": [
{
"values": [
{
"text": "Sorry I couldn't confirm if you wanted to return to previous topic, let me connect to an agent."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "connect_to_agent",
"response": {
"transfer_info": {
"target": {}
},
"agent_available": {
"message": "Let's send you to an available agent."
},
"agent_unavailable": {
"message": "There are no agents available at this time. When one becomes available, we'll connect you."
},
"message_to_human_agent": ""
}
},
"variable": "digression_failure",
"condition": {
"eq": [
{
"system_variable": "fallback_reason"
},
{
"scalar": "Failed to confirm topic return"
}
]
},
"next_step": "step_001"
},
{
"step": "step_001",
"output": {
"generic": [
{
"values": [
{
"text": "I'm afraid I don't understand. I can connect you to an agent."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "connect_to_agent",
"response": {
"transfer_info": {
"target": {}
},
"agent_available": {
"message": "Let's send you to an available agent."
},
"agent_unavailable": {
"message": "There are no agents available at this time. When one becomes available, we'll connect you."
},
"message_to_human_agent": ""
}
},
"variable": "step_001",
"condition": {
"eq": [
{
"system_variable": "fallback_reason"
},
{
"scalar": "Step validation failed"
}
]
},
"next_step": "step_002"
},
{
"step": "step_002",
"output": {
"generic": [
{
"values": [
{
"text": "Sorry I couldn't assist you. I will connect you to an agent right away."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "connect_to_agent",
"response": {
"transfer_info": {
"target": {}
},
"agent_available": {
"message": "Let's send you to an available agent."
},
"agent_unavailable": {
"message": "There are no agents available at this time. When one becomes available, we'll connect you."
},
"message_to_human_agent": ""
}
},
"variable": "step_002",
"condition": {
"eq": [
{
"system_variable": "fallback_reason"
},
{
"scalar": "Agent requested"
}
]
},
"next_step": "step_003"
},
{
"step": "step_003",
"output": {
"generic": [
{
"values": [
{
"text": "I am afraid I do not understand what you are asking, let me connect you to an agent."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "connect_to_agent",
"response": {
"transfer_info": {
"target": {}
},
"agent_available": {
"message": "Let's send you to an available agent."
},
"agent_unavailable": {
"message": "There are no agents available at this time. When one becomes available, we'll connect you."
},
"message_to_human_agent": ""
}
},
"variable": "step_003",
"condition": {
"eq": [
{
"system_variable": "fallback_reason"
},
{
"scalar": "No action matches"
}
]
},
"next_step": "step_004"
},
{
"step": "step_004",
"output": {
"generic": [
{
"values": [
{
"text": "It seems this conversation would be best managed by a human agent. Let me connect you to one of our agents."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "connect_to_agent",
"response": {
"transfer_info": {
"target": {}
},
"agent_available": {
"message": "Let's send you to an available agent."
},
"agent_unavailable": {
"message": "There are no agents available at this time. When one becomes available, we'll connect you."
},
"message_to_human_agent": ""
}
},
"variable": "step_004",
"condition": {
"eq": [
{
"system_variable": "fallback_reason"
},
{
"scalar": "Danger word detected"
}
]
},
"next_step": "step_005"
},
{
"step": "step_005",
"output": {
"generic": [
{
"values": [
{
"text": "It seems this conversation would be best managed by a human agent. Let me connect you to one of our agents."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "connect_to_agent",
"response": {
"transfer_info": {
"target": {}
},
"agent_available": {
"message": "Let's send you to an available agent."
},
"agent_unavailable": {
"message": "There are no agents available at this time. When one becomes available, we'll connect you."
},
"message_to_human_agent": ""
}
},
"variable": "step_005",
"condition": {
"eq": [
{
"system_variable": "fallback_reason"
},
{
"scalar": "Profanity detected"
}
]
}
}
],
"title": "Fallback",
"action": "fallback",
"boosts": [],
"handlers": [],
"condition": {
"intent": "fallback_connect_to_agent"
},
"variables": [
{
"title": "Topic return failed",
"variable": "digression_failure",
"data_type": "any"
},
{
"title": "I'm afraid I don't understand. I can connect you to an agent.",
"variable": "step_001",
"data_type": "any"
},
{
"title": "Sorry I couldn't assist you. I will connect you to an agent righ",
"variable": "step_002",
"data_type": "any"
},
{
"title": "I am afraid I do not understand what you are asking, let me conn",
"variable": "step_003",
"data_type": "any"
},
{
"title": "It seems this conversation would be best managed",
"variable": "step_004",
"data_type": "any"
},
{
"title": "Profanity - It seems this conversation",
"variable": "step_005",
"data_type": "any"
}
],
"next_action": "run_always",
"disambiguation_opt_out": true
},
{
"type": "standard",
"steps": [
{
"step": "danger_word_detected",
"title": "Connect to agent",
"handlers": [],
"resolver": {
"type": "fallback"
},
"variable": "danger_word_detected_variable",
"condition": {
"entity": "danger_words"
},
"next_step": "profanity_detected"
},
{
"step": "profanity_detected",
"title": "Show warning",
"output": {
"generic": [
{
"values": [
{
"text_expression": {
"concat": [
{
"scalar": "Please use appropriate language when interacting with the assistant."
}
]
}
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [
{
"type": "max_hits",
"handler": "max_hits_handler",
"resolver": {
"type": "fallback"
}
}
],
"max_hits": 2,
"resolver": {
"type": "end_action"
},
"variable": "profanity_detected_variable",
"condition": {
"entity": "profane_words"
}
}
],
"title": "Trigger word detected",
"action": "run_always",
"boosts": [],
"handlers": [],
"variables": [
{
"title": "Profanity detected",
"variable": "danger_word_detected_variable",
"data_type": "any"
},
{
"title": "Profane word detected",
"variable": "profanity_detected_variable",
"data_type": "any"
}
],
"next_action": "anything_else"
},
{
"type": "standard",
"steps": [
{
"step": "step_001",
"output": {
"generic": [
{
"values": [
{
"text": "I'm afraid I don't understand. Please rephrase your question."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "end_action"
},
"variable": "step_001",
"condition": {
"lte": [
{
"system_variable": "no_action_matches_count"
},
{
"scalar": 3
}
]
},
"next_step": "step_002"
},
{
"step": "step_002",
"output": {
"generic": [
{
"values": [
{
"text": ""
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "invoke_another_action_and_end",
"invoke_action": {
"action": "fallback",
"policy": "default",
"parameters": null,
"result_variable": "step_002_result_1"
}
},
"variable": "step_002",
"condition": {
"gt": [
{
"system_variable": "no_action_matches_count"
},
{
"scalar": 3
}
]
}
}
],
"title": "No matches",
"action": "anything_else",
"boosts": [],
"handlers": [],
"condition": {
"expression": "anything_else"
},
"variables": [
{
"title": "I am afraid I do not understand what you are asking, please re-p",
"variable": "step_001",
"data_type": "any"
},
{
"variable": "step_002",
"data_type": "any"
},
{
"variable": "step_002_result_1",
"data_type": "any"
}
],
"disambiguation_opt_out": true
},
{
"type": "standard",
"steps": [
{
"step": "step_001",
"output": {
"generic": [
{
"values": [
{
"text": "Welcome, how can I assist you?"
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "end_action"
},
"variable": "step_001"
}
],
"title": "Greet customer",
"action": "welcome",
"boosts": [],
"handlers": [],
"condition": {
"expression": "welcome"
},
"variables": [
{
"variable": "step_001",
"data_type": "any"
}
],
"next_action": "action_44900",
"disambiguation_opt_out": true
},
{
"type": "standard",
"steps": [
{
"step": "step_356",
"title": "Get Patients Name",
"output": {
"generic": [
{
"values": [
{
"text_expression": {
"concat": [
{
"scalar": "Sure I can help you with that! What's your first and last name?"
}
]
}
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"question": {
"free_text": true
},
"resolver": {
"type": "continue"
},
"variable": "step_356",
"next_step": "step_572"
},
{
"step": "step_572",
"title": "Get Patients DOB",
"output": {
"generic": [
{
"values": [
{
"text_expression": {
"concat": [
{
"scalar": "Thank you! Could you please confirm your date of birth for me?"
}
]
}
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"question": {
"free_text": true
},
"resolver": {
"type": "continue"
},
"variable": "step_572",
"next_step": "step_309"
},
{
"step": "step_309",
"title": "Conclusion",
"output": {
"generic": [
{
"values": [
{
"text_expression": {
"concat": [
{
"scalar": "Great I have all the information I need, and I am now ready to answer your questions!"
}
]
}
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"handlers": [],
"resolver": {
"type": "end_action"
},
"variable": "step_309"
}
],
"title": "Main Desk",
"action": "action_44900",
"boosts": [],
"handlers": [],
"condition": {
"intent": "action_44900_intent_12533"
},
"variables": [
{
"title": "Conclusion",
"privacy": {
"enabled": false
},
"variable": "step_309",
"data_type": "any"
},
{
"title": "Get Patients Name",
"privacy": {
"enabled": false
},
"variable": "step_356",
"data_type": "any"
},
{
"title": "Get Patients DOB",
"privacy": {
"enabled": false
},
"variable": "step_572",
"data_type": "any"
}
],
"launch_mode": "learning",
"next_action": "fallback",
"topic_switch": {
"allowed_from": true,
"allowed_into": true,
"never_return": false
},
"disambiguation_opt_out": false
}
],
"intents": [
{
"intent": "fallback_connect_to_agent",
"examples": [
{
"text": "Call agent"
},
{
"text": "Agent help"
},
{
"text": "I would like to speak to a human"
},
{
"text": "Can I connect to an agent?"
},
{
"text": "I would like to speak to someone"
}
],
"description": "Please transfer me to an agent"
},
{
"intent": "action_44900_intent_12533",
"examples": [
{
"text": "I want to access my medical records"
}
]
}
],
"entities": [
{
"entity": "sys-yes-no",
"values": []
},
{
"entity": "danger_words",
"values": [],
"fuzzy_match": false
},
{
"entity": "profane_words",
"values": [],
"fuzzy_match": false
}
],
"metadata": {
"api_version": {
"major_version": "v2",
"minor_version": "2018-11-08"
},
"skill": {
"counts": {
"actions": 5,
"intents": 2,
"entities": 3,
"data_types": 0,
"collections": 0,
"global_variables": 0
}
}
},
"variables": [],
"data_types": [],
"collections": [],
"counterexamples": [],
"system_settings": {
"variable": {
"format": {
"time": {
"pattern": "short"
},
"currency": {
"fraction_digits": 2
}
}
},
"off_topic": {
"enabled": true
},
"auto_learn": {
"apply": true
},
"topic_switch": {
"enabled": true,
"messages": {
"enable_confirmation": true,
"confirmation_failure": {
"generic": [
{
"values": [
{
"text_expression": {
"concat": [
{
"scalar": "I'm sorry, I did not catch that, please confirm."
}
]
}
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"confirmation_request": {
"generic": [
{
"values": [
{
"text_expression": {
"concat": [
{
"scalar": "Do you want to continue with the previous topic: "
},
{
"system_variable": "digressed_from"
},
{
"scalar": "?"
}
]
}
}
],
"response_type": "text",
"selection_policy": "sequential"
},
{
"options": [
{
"label": "Yes",
"value": {
"input": {
"text": "Yes"
}
}
},
{
"label": "No",
"value": {
"input": {
"text": "No"
}
}
}
],
"response_type": "option",
"repeat_on_reprompt": true
}
]
}
},
"max_tries": 3
},
"generative_ai": {
"model_id": "ibm/granite-3-8b-instruct",
"hap_filter": {
"output": {
"enabled": true
}
}
},
"disambiguation": {
"prompt": "Did you mean:",
"enabled": true,
"randomize": true,
"max_suggestions": 5,
"suggestion_text_policy": "title",
"none_of_the_above_prompt": "None of the above",
"use_connect_to_support_prompt": "Connect to support",
"single_answer_clarification_prompt": "Something else"
},
"search_routing": {
"target": "conversational_search"
},
"spelling_auto_correct": true
},
"learning_opt_out": true,
"language": "en"
},
"description": "created for assistant dfcdc7a1-4a37-4714-9189-daa085b3e4a9",
"dialog_settings": {
"source_assistant": "14184e97-fe24-4fc4-ae2a-addfb22e41c1"
},
"created": "2025-05-16T15:38:23.103Z",
"updated": "2025-05-16T15:38:23.103Z",
"snapshot": "1",
"assistant_id": "dfcdc7a1-4a37-4714-9189-daa085b3e4a9",
"assistant_references": [
{
"name": "Main Desk Concierge",
"assistant_id": "14184e97-fe24-4fc4-ae2a-addfb22e41c1",
"skill_reference": "actions skill"
}
]
}