iatoolkit 0.11.0__py3-none-any.whl → 0.66.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. iatoolkit/base_company.py +11 -3
  2. iatoolkit/common/routes.py +92 -52
  3. iatoolkit/common/session_manager.py +0 -1
  4. iatoolkit/common/util.py +17 -27
  5. iatoolkit/iatoolkit.py +91 -47
  6. iatoolkit/infra/llm_client.py +7 -8
  7. iatoolkit/infra/openai_adapter.py +1 -1
  8. iatoolkit/infra/redis_session_manager.py +48 -2
  9. iatoolkit/locales/en.yaml +144 -0
  10. iatoolkit/locales/es.yaml +140 -0
  11. iatoolkit/repositories/database_manager.py +17 -2
  12. iatoolkit/repositories/models.py +31 -4
  13. iatoolkit/repositories/profile_repo.py +7 -2
  14. iatoolkit/services/auth_service.py +193 -0
  15. iatoolkit/services/branding_service.py +59 -18
  16. iatoolkit/services/dispatcher_service.py +10 -40
  17. iatoolkit/services/excel_service.py +15 -15
  18. iatoolkit/services/help_content_service.py +30 -0
  19. iatoolkit/services/history_service.py +2 -11
  20. iatoolkit/services/i18n_service.py +104 -0
  21. iatoolkit/services/jwt_service.py +15 -24
  22. iatoolkit/services/language_service.py +77 -0
  23. iatoolkit/services/onboarding_service.py +43 -0
  24. iatoolkit/services/profile_service.py +148 -75
  25. iatoolkit/services/query_service.py +124 -81
  26. iatoolkit/services/tasks_service.py +1 -1
  27. iatoolkit/services/user_feedback_service.py +68 -32
  28. iatoolkit/services/user_session_context_service.py +112 -54
  29. iatoolkit/static/images/fernando.jpeg +0 -0
  30. iatoolkit/static/js/chat_feedback_button.js +80 -0
  31. iatoolkit/static/js/chat_help_content.js +124 -0
  32. iatoolkit/static/js/chat_history_button.js +112 -0
  33. iatoolkit/static/js/chat_logout_button.js +36 -0
  34. iatoolkit/static/js/chat_main.js +148 -220
  35. iatoolkit/static/js/chat_onboarding_button.js +97 -0
  36. iatoolkit/static/js/chat_prompt_manager.js +94 -0
  37. iatoolkit/static/js/chat_reload_button.js +35 -0
  38. iatoolkit/static/styles/chat_iatoolkit.css +367 -199
  39. iatoolkit/static/styles/chat_modal.css +98 -76
  40. iatoolkit/static/styles/chat_public.css +107 -0
  41. iatoolkit/static/styles/landing_page.css +182 -0
  42. iatoolkit/static/styles/onboarding.css +169 -0
  43. iatoolkit/system_prompts/query_main.prompt +3 -12
  44. iatoolkit/templates/_company_header.html +20 -0
  45. iatoolkit/templates/_login_widget.html +42 -0
  46. iatoolkit/templates/base.html +40 -20
  47. iatoolkit/templates/change_password.html +57 -36
  48. iatoolkit/templates/chat.html +169 -83
  49. iatoolkit/templates/chat_modals.html +134 -68
  50. iatoolkit/templates/error.html +44 -8
  51. iatoolkit/templates/forgot_password.html +40 -23
  52. iatoolkit/templates/index.html +145 -0
  53. iatoolkit/templates/login_simulation.html +34 -0
  54. iatoolkit/templates/onboarding_shell.html +104 -0
  55. iatoolkit/templates/signup.html +63 -65
  56. iatoolkit/views/base_login_view.py +92 -0
  57. iatoolkit/views/change_password_view.py +56 -30
  58. iatoolkit/views/external_login_view.py +61 -28
  59. iatoolkit/views/{file_store_view.py → file_store_api_view.py} +9 -2
  60. iatoolkit/views/forgot_password_view.py +27 -19
  61. iatoolkit/views/help_content_api_view.py +54 -0
  62. iatoolkit/views/history_api_view.py +56 -0
  63. iatoolkit/views/home_view.py +50 -23
  64. iatoolkit/views/index_view.py +14 -0
  65. iatoolkit/views/init_context_api_view.py +73 -0
  66. iatoolkit/views/llmquery_api_view.py +57 -0
  67. iatoolkit/views/login_simulation_view.py +81 -0
  68. iatoolkit/views/login_view.py +130 -37
  69. iatoolkit/views/logout_api_view.py +49 -0
  70. iatoolkit/views/profile_api_view.py +46 -0
  71. iatoolkit/views/{prompt_view.py → prompt_api_view.py} +10 -10
  72. iatoolkit/views/signup_view.py +42 -35
  73. iatoolkit/views/{tasks_view.py → tasks_api_view.py} +10 -36
  74. iatoolkit/views/tasks_review_api_view.py +55 -0
  75. iatoolkit/views/user_feedback_api_view.py +60 -0
  76. iatoolkit/views/verify_user_view.py +35 -28
  77. {iatoolkit-0.11.0.dist-info → iatoolkit-0.66.2.dist-info}/METADATA +2 -2
  78. iatoolkit-0.66.2.dist-info/RECORD +119 -0
  79. iatoolkit/common/auth.py +0 -200
  80. iatoolkit/static/images/arrow_up.png +0 -0
  81. iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
  82. iatoolkit/static/images/logo_clinica.png +0 -0
  83. iatoolkit/static/images/logo_iatoolkit.png +0 -0
  84. iatoolkit/static/images/logo_maxxa.png +0 -0
  85. iatoolkit/static/images/logo_notaria.png +0 -0
  86. iatoolkit/static/images/logo_tarjeta.png +0 -0
  87. iatoolkit/static/images/logo_umayor.png +0 -0
  88. iatoolkit/static/images/upload.png +0 -0
  89. iatoolkit/static/js/chat_feedback.js +0 -115
  90. iatoolkit/static/js/chat_history.js +0 -117
  91. iatoolkit/static/styles/chat_info.css +0 -53
  92. iatoolkit/templates/header.html +0 -31
  93. iatoolkit/templates/home.html +0 -199
  94. iatoolkit/templates/login.html +0 -43
  95. iatoolkit/templates/test.html +0 -9
  96. iatoolkit/views/chat_token_request_view.py +0 -98
  97. iatoolkit/views/chat_view.py +0 -58
  98. iatoolkit/views/download_file_view.py +0 -58
  99. iatoolkit/views/external_chat_login_view.py +0 -95
  100. iatoolkit/views/history_view.py +0 -57
  101. iatoolkit/views/llmquery_view.py +0 -65
  102. iatoolkit/views/tasks_review_view.py +0 -83
  103. iatoolkit/views/user_feedback_view.py +0 -74
  104. iatoolkit-0.11.0.dist-info/RECORD +0 -110
  105. {iatoolkit-0.11.0.dist-info → iatoolkit-0.66.2.dist-info}/WHEEL +0 -0
  106. {iatoolkit-0.11.0.dist-info → iatoolkit-0.66.2.dist-info}/top_level.txt +0 -0
@@ -4,52 +4,59 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from flask.views import MethodView
7
- from flask import render_template
7
+ from flask import render_template, url_for, redirect, session, flash
8
8
  from iatoolkit.services.profile_service import ProfileService
9
9
  from itsdangerous import URLSafeTimedSerializer, SignatureExpired
10
+ from iatoolkit.services.branding_service import BrandingService
11
+ from iatoolkit.services.i18n_service import I18nService
10
12
  from injector import inject
11
13
  import os
12
14
 
13
15
 
14
16
  class VerifyAccountView(MethodView):
15
17
  @inject
16
- def __init__(self, profile_service: ProfileService):
18
+ def __init__(self,
19
+ profile_service: ProfileService,
20
+ branding_service: BrandingService,
21
+ i18n_service: I18nService):
17
22
  self.profile_service = profile_service
23
+ self.branding_service = branding_service
24
+ self.i18n_service = i18n_service
18
25
  self.serializer = URLSafeTimedSerializer(os.getenv("USER_VERIF_KEY"))
19
26
 
20
27
  def get(self, company_short_name: str, token: str):
21
- # get company info
22
- company = self.profile_service.get_company_by_short_name(company_short_name)
23
- if not company:
24
- return render_template('error.html', message="Empresa no encontrada"), 404
25
-
26
28
  try:
27
- # decode the token from the URL
28
- email = self.serializer.loads(token, salt='email-confirm', max_age=3600*5)
29
- except SignatureExpired:
30
- return render_template('signup.html',
31
- company=company,
32
- company_short_name=company_short_name,
33
- token=token,
34
- alert_message="El enlace de verificación ha expirado. Por favor, solicita uno nuevo."), 400
29
+ # get company info
30
+ company = self.profile_service.get_company_by_short_name(company_short_name)
31
+ if not company:
32
+ return render_template('error.html',
33
+ message=self.i18n_service.t('errors.templates.company_not_found')), 404
34
+
35
+ branding_data = self.branding_service.get_company_branding(company)
36
+ try:
37
+ # decode the token from the URL
38
+ email = self.serializer.loads(token, salt='email-confirm', max_age=3600*5)
39
+ except SignatureExpired:
40
+ flash(self.i18n_service.t('errors.verification.token_expired'), 'error')
41
+ return render_template('signup.html',
42
+ company=company,
43
+ company_short_name=company_short_name,
44
+ branding=branding_data,
45
+ token=token), 400
35
46
 
36
- try:
37
47
  response = self.profile_service.verify_account(email)
38
48
  if "error" in response:
49
+ flash(response["error"], 'error')
39
50
  return render_template(
40
51
  'signup.html',
41
52
  company=company,
42
53
  company_short_name=company_short_name,
43
- token=token,
44
- alert_message=response["error"]), 400
45
-
46
- return render_template('login.html',
47
- company=company,
48
- company_short_name=company_short_name,
49
- alert_icon='success',
50
- alert_message=response['message'])
54
+ branding=branding_data,
55
+ token=token), 400
56
+
57
+ flash(response['message'], 'success')
58
+ return redirect(url_for('home', company_short_name=company_short_name))
59
+
51
60
  except Exception as e:
52
- return render_template("error.html",
53
- company=company,
54
- company_short_name=company_short_name,
55
- message="Ha ocurrido un error inesperado."), 500
61
+ flash(self.i18n_service.t('errors.general.unexpected_error'), 'error')
62
+ return redirect(url_for('home', company_short_name=company_short_name))
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.11.0
3
+ Version: 0.66.2
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
7
- Requires-Python: >=3.11
7
+ Requires-Python: >=3.12
8
8
  Description-Content-Type: text/markdown
9
9
  Requires-Dist: aiohappyeyeballs==2.4.4
10
10
  Requires-Dist: aiohttp==3.11.9
@@ -0,0 +1,119 @@
1
+ iatoolkit/__init__.py,sha256=4PWjMJjktixtrxF6BY405qyA50Sv967kEP2x-oil6qk,1120
2
+ iatoolkit/base_company.py,sha256=vU4ki-wB3PWIn3_Bvehfh0TfBH_XNC614tRBKNmEd84,4718
3
+ iatoolkit/cli_commands.py,sha256=G5L9xQXZ0lVFXQWBaE_KEZHyfuiT6PL1nTQRoSdnBzc,2302
4
+ iatoolkit/company_registry.py,sha256=tduqt3oV8iDX_IB1eA7KIgvIxE4edTcy-3qZIXh3Lzw,2549
5
+ iatoolkit/iatoolkit.py,sha256=lz8-49TDLG0RcDqg5kh7jlir7K6JQbKDRKTBMGGKu7c,19134
6
+ iatoolkit/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ iatoolkit/common/exceptions.py,sha256=EXx40n5htp7UiOM6P1xfJ9U6NMcADqm62dlFaKz7ICU,1154
8
+ iatoolkit/common/routes.py,sha256=sYkW9mLIh8IUh8v_CyLxwR9wELiPJdZqjt07DVyozeU,6261
9
+ iatoolkit/common/session_manager.py,sha256=UeKfD15bcEA3P5e0WSURfotLqpsiIMp3AXxAMhtgHs0,471
10
+ iatoolkit/common/util.py,sha256=lwMhQ2gT1DPzJ3mmL9xw3uobWJFIapAw50ks6mCvV60,15028
11
+ iatoolkit/infra/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
12
+ iatoolkit/infra/call_service.py,sha256=iRk9VxbXaAwlLIl8fUzGDWIAdzwfsbs1MtP84YeENxg,4929
13
+ iatoolkit/infra/gemini_adapter.py,sha256=kXV-t5i9GmWBafUPX2kAyiqvcT7GPoxHylcCUWG_c_U,15051
14
+ iatoolkit/infra/google_chat_app.py,sha256=_uKWxeacHH6C5a4FVx0YZjBn1tL-x_MIQV9gqgWGAjo,1937
15
+ iatoolkit/infra/llm_client.py,sha256=clTYqV_0a2VD2vVH3j6AWqd1gVUmeg-fU3_myizmjQc,18543
16
+ iatoolkit/infra/llm_proxy.py,sha256=cHyNxUpVE4UDoWUfvSGfGCrIUFPTrpWZOixELQTsGFY,5744
17
+ iatoolkit/infra/llm_response.py,sha256=YUUQPBHzmP3Ce6-t0kKMRIpowvh7de1odSoefEByIvI,904
18
+ iatoolkit/infra/mail_app.py,sha256=PLGZdEs7LQ_9bmMRRxz0iqQdNa4xToAFyf9tg75wK8U,6103
19
+ iatoolkit/infra/openai_adapter.py,sha256=tbzd8aPAH5cQOJT-sD4ypqq2fWB6WiEIGuGesUDnQNk,3550
20
+ iatoolkit/infra/redis_session_manager.py,sha256=EPr3E_g7LHxn6U4SV5lT_L8WQsAwg8VzA_WIEZ3TwOw,3667
21
+ iatoolkit/infra/connectors/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
22
+ iatoolkit/infra/connectors/file_connector.py,sha256=HOjRTFd-WfDOcFyvHncAhnGNZuFgChIwC-P6osPo9ZM,352
23
+ iatoolkit/infra/connectors/file_connector_factory.py,sha256=3qvyfH4ZHKuiMxJFkawOxhW2-TGKKtsBYHgoPpZMuKU,2118
24
+ iatoolkit/infra/connectors/google_cloud_storage_connector.py,sha256=IXpL3HTo7Ft4EQsYiQq5wXRRQK854jzOEB7ZdWjLa4U,2050
25
+ iatoolkit/infra/connectors/google_drive_connector.py,sha256=WR1AlO5-Bl3W89opdja0kKgHTJzVOjTsy3H4SlIvwVg,2537
26
+ iatoolkit/infra/connectors/local_file_connector.py,sha256=hrzIgpMJOTuwTqzlQeTIU_50ZbZ6yl8lcWPv6hMnoqI,1739
27
+ iatoolkit/infra/connectors/s3_connector.py,sha256=Nj4_YaLobjfcnbZewJf21_K2EXohgcc3mJll1Pzn4zg,1123
28
+ iatoolkit/locales/en.yaml,sha256=6FO_3U7QMvRDve8f6a_VpB5n--F7klTpYbYekB_Gqd8,6577
29
+ iatoolkit/locales/es.yaml,sha256=vQJQWKR7mnGtG32gTcnwJW52YmizVrgGSvKFQuiMw-s,7520
30
+ iatoolkit/repositories/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
31
+ iatoolkit/repositories/database_manager.py,sha256=QgV8hNnVv9RmeOvUdomdj_mfk0bf3Rl8Ti41a-5zIAY,3700
32
+ iatoolkit/repositories/document_repo.py,sha256=Y7bF1kZB1HWJsAGjWdF7P2aVYeTYNufq9ngQXp7mDkY,1124
33
+ iatoolkit/repositories/llm_query_repo.py,sha256=YT_t7cYGQk8rwzH_17-28aTzO-e2jUfa2rvXy8tugvA,3612
34
+ iatoolkit/repositories/models.py,sha256=b08sJ8ZXyIbMa7dK4wgG7juTG7-FzL--ADFv8Zx-sQU,14417
35
+ iatoolkit/repositories/profile_repo.py,sha256=21am3GP7XCG0nq6i3pArQ7mfGsrRn8rdcWT98fsdwlU,4397
36
+ iatoolkit/repositories/tasks_repo.py,sha256=icVO_r2oPagGnnBhwVFzznnvEEU2EAx-2dlWuWvoDC4,1745
37
+ iatoolkit/repositories/vs_repo.py,sha256=UkpmQQiocgM5IwRBmmWhw3HHzHP6zK1nN3J3TcQgjhc,5300
38
+ iatoolkit/services/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
39
+ iatoolkit/services/auth_service.py,sha256=c2yDHNQqbt8Tio7QSL4FaxcHVtsBxLQf8VC2pDetZ4Y,7753
40
+ iatoolkit/services/benchmark_service.py,sha256=CdbFYyS3FHFhNzWQEa9ZNjUlmON10DT1nKNbZQ1EUi8,5880
41
+ iatoolkit/services/branding_service.py,sha256=a9T32oEFZY2e0DXg8WrFGX9KXBJYfuN2sbcD2Hpgypk,7832
42
+ iatoolkit/services/dispatcher_service.py,sha256=Qdn2x4cozpgpKg2448sUxkhO6tuplzb8xPWUxdTTFBE,12772
43
+ iatoolkit/services/document_service.py,sha256=nMXrNtbHQuc9pSaten0LvKY0kT8_WngBDmZJUP3jNPw,5936
44
+ iatoolkit/services/excel_service.py,sha256=JdAcg7_vPz3J16cf2chC6j7WYVpiT55tDX9667tfMUc,3764
45
+ iatoolkit/services/file_processor_service.py,sha256=B1sUUhZNFf-rT4_1wrD38GKNoBFMp2g0dYrXYMCWe2E,4122
46
+ iatoolkit/services/help_content_service.py,sha256=LV-HYe-1YyUkiYfeuzZmvW100pQMlqpL4h49lnJSFD0,940
47
+ iatoolkit/services/history_service.py,sha256=3IxcdpKV1mHBGIiv2KIYV3LsVQJ0GPdFuCOiGYRszMU,1255
48
+ iatoolkit/services/i18n_service.py,sha256=MisTYp1WZe2YUnq4oWWnSqfsneetOV5igUIlyEJBDmI,3933
49
+ iatoolkit/services/jwt_service.py,sha256=W2kQVNQheQSLkNLS7RZ4jd3hmySBPLbHAS5hvBrUI10,3244
50
+ iatoolkit/services/language_service.py,sha256=7G6LVCgvzckszxju04pECCl2VJHJGH5IXOhVtlJGASI,3024
51
+ iatoolkit/services/load_documents_service.py,sha256=ZpB0BZ3qX1fGJGBtZtMLbFdWWx0hkPoeCS3OqJKwCTs,7291
52
+ iatoolkit/services/mail_service.py,sha256=2h-fcF3swZDya_o7IpgXkmuj3iEVHVCiHi7oVxU99sQ,2182
53
+ iatoolkit/services/onboarding_service.py,sha256=cMO2Ho1-G3wAeVNl-j25LwCMJjRwj3yKHpYKnZUFLDE,2001
54
+ iatoolkit/services/profile_service.py,sha256=_7H6dfOKl6UoXpr6mOKnjbSNe8ef6Wwh8Fc2hNJlBuo,21820
55
+ iatoolkit/services/prompt_manager_service.py,sha256=U-XmSpkeXvv1KRN4dytdMxSYBMRSB7y-UHcb18mk0nA,8342
56
+ iatoolkit/services/query_service.py,sha256=gtMEAQ7IRVrFAMq4h_Pc_lHlMlXFI6heLSuBYHenkfs,17502
57
+ iatoolkit/services/search_service.py,sha256=i1xGWu7ORKIIDH0aAQBkF86dVVbLQ0Yrooz5TiZ6aGo,1823
58
+ iatoolkit/services/sql_service.py,sha256=MIslAtpJWnTMgSD74nnqTvQj27p-lHiyRXc6OiA2C_c,2172
59
+ iatoolkit/services/tasks_service.py,sha256=itREO5rDnUIgsqtyCOBKDtH30QL5v1egs4qPTiBK8xU,6865
60
+ iatoolkit/services/user_feedback_service.py,sha256=__65iWHPmBafqaYtVuv8Lg9XBgVshDXvL1JXFw5TxfM,5003
61
+ iatoolkit/services/user_session_context_service.py,sha256=vYF_vWM37tPB_ZyPBJ6f6WTJVjT2j-4L8JfZbqbI93k,6775
62
+ iatoolkit/static/images/fernando.jpeg,sha256=W68TYMuo5hZVpbP-evwH6Nu4xWFv2bc8pJzSKDoLTeQ,100612
63
+ iatoolkit/static/js/chat_feedback_button.js,sha256=Wzb2l3jmpZNwY2KYQQDuBmFKS4oU9WteB9s4U-bEqb4,2429
64
+ iatoolkit/static/js/chat_filepond.js,sha256=mzXafm7a506EpM37KATTK3zvAswO1E0KSUY1vKbwuRc,3163
65
+ iatoolkit/static/js/chat_help_content.js,sha256=N9APsdNoPWWyC1aMLjfq-xFfFYZ5g8ZefUGTkYt75DY,5211
66
+ iatoolkit/static/js/chat_history_button.js,sha256=YxJPNDwgnNCZAk0u3bTOWWZ_iXWimNNQY05LGFgvg-U,3488
67
+ iatoolkit/static/js/chat_logout_button.js,sha256=Of9H6IbAboSBmeqRaurEVW6_dL752L0UeDcDLNBD5Z0,1335
68
+ iatoolkit/static/js/chat_main.js,sha256=qXf8za7CAY5deLUraNsGJo_ljB1ceNkhFZo8IsCEgn0,13255
69
+ iatoolkit/static/js/chat_onboarding_button.js,sha256=vjvEloJ9PA9D7jOGca0QjS3J_7bU97R71L7kSyY3wOI,3153
70
+ iatoolkit/static/js/chat_prompt_manager.js,sha256=QYki28CpyM2Chn82dnOP2eH6FObxH8eChGFyUxukv1M,3319
71
+ iatoolkit/static/js/chat_reload_button.js,sha256=FHMm5sLdn2HuWDq66wphNuRcltjLG-aADp0yTwEbnQw,1256
72
+ iatoolkit/static/styles/chat_iatoolkit.css,sha256=C1qVIpL6hUdhkYIE4D1PeQmr-hv1QptuFqoWLcKkAuY,17006
73
+ iatoolkit/static/styles/chat_modal.css,sha256=ac49DAyViRUJZFcvxB7z8Ufv_ixAEXSKOC8NdtTuiMU,4130
74
+ iatoolkit/static/styles/chat_public.css,sha256=4EHN_VvURQYlooCmNB-UHIhvMsn4GFm7tKtr4VKpCNE,3830
75
+ iatoolkit/static/styles/landing_page.css,sha256=E6VRI5dko_naloH_FmNAHpjzxz4NZbrbzKwYLw4fYJA,4297
76
+ iatoolkit/static/styles/llm_output.css,sha256=AlxgRSOleeCk2dLAqFWVaQ-jwZiJjcpC5rHuUv3T6VU,2312
77
+ iatoolkit/static/styles/onboarding.css,sha256=Bo0hd8ngVy404_a-gtNFi-hzljhIAnpE-1oQJGnj0F0,3655
78
+ iatoolkit/system_prompts/format_styles.prompt,sha256=MSMe1qvR3cF_0IbFshn8R0z6Wx6VCHQq1p37rpu5wwk,3576
79
+ iatoolkit/system_prompts/query_main.prompt,sha256=D2Wjf0uunQIQsQiJVrY-BTQz6PemM5En6ftmw_c5t4E,2808
80
+ iatoolkit/system_prompts/sql_rules.prompt,sha256=y4nURVnb9AyFwt-lrbMNBHHtZlhk6kC9grYoOhRnrJo,59174
81
+ iatoolkit/templates/_company_header.html,sha256=wrwDftsSVu1uMPchsweAPLupsPkmLIPQBQ0xpIIyxjA,747
82
+ iatoolkit/templates/_login_widget.html,sha256=mheHpa_mcGK7UYSYdzxyD_n97MnJXJE19IcFxxUQYTY,1952
83
+ iatoolkit/templates/about.html,sha256=ciC08grUVz5qLzdzDDqDX31xirg5PrJIRYabWpV9oA8,294
84
+ iatoolkit/templates/base.html,sha256=xOox6JJEd6dHBlw6DBrFDJTXtAKCaXZc3Ffrufa-GDk,3042
85
+ iatoolkit/templates/change_password.html,sha256=rvB4R7lO3y__umQRvkcK1FaOYYvvHn4oKCdrUzvIvf8,3483
86
+ iatoolkit/templates/chat.html,sha256=Os_jD8QKh5goHnhJCo79FBzupzX37DnpcsyWc141fCY,13000
87
+ iatoolkit/templates/chat_modals.html,sha256=ojJRZ1a1yt7ByFLIqEyDpUTRuMepJIR6We9HLsLZFdI,8278
88
+ iatoolkit/templates/error.html,sha256=IdswYbZYp5cHZjPdKBOR44OBwL1GRVR--UTpSKYSwTU,1779
89
+ iatoolkit/templates/forgot_password.html,sha256=RPV_fDCzEdSQpA0qM8RNSCsNlhUhgp9sRGUHpMMBQ10,2247
90
+ iatoolkit/templates/index.html,sha256=mOuHePAmQ5PaMwqkJf7HU5oIL_lh8iKBKFng6d-QVzA,8017
91
+ iatoolkit/templates/login_simulation.html,sha256=1svwCBPrJ3Gy6bD9WMuz25NBSdFgZt4j8_sC7HE6MFU,1270
92
+ iatoolkit/templates/onboarding_shell.html,sha256=3Kb7R9AytkztJpxoTCi4zNZRZxxQ3mZsAId44BR5PaU,4611
93
+ iatoolkit/templates/signup.html,sha256=u2wiahk_d_BfooknSCcgcgAaQqIfas2aj6fe0cG3jzE,4174
94
+ iatoolkit/views/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
95
+ iatoolkit/views/base_login_view.py,sha256=wwPcB2LE0FwyE-Any-KPkAJPYtzUw5_9E6q2sxO5Ryo,3700
96
+ iatoolkit/views/change_password_view.py,sha256=JfFcJgqIbsDaMgt9OB70GsWmzR8er6vmLi-fm-gPU1A,4966
97
+ iatoolkit/views/external_login_view.py,sha256=d4gUQbxFsThGbbAUdtFn7AMgPJjeb7_8KFFoH3vspVA,2853
98
+ iatoolkit/views/file_store_api_view.py,sha256=UvtZWOG-rLQMLfs8igOIYoQ-tkkEg5baMjqCJdKxaRQ,2300
99
+ iatoolkit/views/forgot_password_view.py,sha256=k200mbuzL6CZ-P8NfovpBYKAkzK0FNvZawD8kjGUWGA,3184
100
+ iatoolkit/views/help_content_api_view.py,sha256=f6zEQwTczA7X9Hbmstiglz6Oj1sMpXdF87bNY46BXEU,2026
101
+ iatoolkit/views/history_api_view.py,sha256=AFl_EQ3NaY4x_8BZ-jAYMV5DGAIEPgbyjNQnfI7iXt0,1974
102
+ iatoolkit/views/home_view.py,sha256=zKR-8bzOrS2OKy9Ka-j3Tsg3MHDzUurJQQ0LOfVF8P4,2574
103
+ iatoolkit/views/index_view.py,sha256=OsykSlXLB-TpFAPkDlsMna6bi3Ie5PXL303Hsg3WwUM,329
104
+ iatoolkit/views/init_context_api_view.py,sha256=i6fiotS7e7-xXFNH98FLnKqkXWj9pQ-gmgI2Y5bH93A,3000
105
+ iatoolkit/views/llmquery_api_view.py,sha256=MfUqHbX-EX8u3wBl2w7FMCPBZPm-EyH4aBvZdGljhms,2164
106
+ iatoolkit/views/login_simulation_view.py,sha256=0Qt-puRnltI2HZxlfdyJmOf26-hQp3xjknGV_jkwV7E,3484
107
+ iatoolkit/views/login_view.py,sha256=3C356H9UfI8VHcMwg8K8_5F3ZlFqeDD3s4pIaEfPUKw,6412
108
+ iatoolkit/views/logout_api_view.py,sha256=tvk4sCCXOFsk6qfGsrwY-pDKHL4ET30tL7ncTG-PT8A,1733
109
+ iatoolkit/views/profile_api_view.py,sha256=qhlmhyygIs5h-OyNDwq1uGUS8S-GxB2zOYY51Hs5prY,1645
110
+ iatoolkit/views/prompt_api_view.py,sha256=zumYnC_LWq_IeLraoL24YrY87U6a7iC6maY1PN-IP6U,1263
111
+ iatoolkit/views/signup_view.py,sha256=aAY5R4iH2Bi6qzfTNpyHvD-Vx6jC8oSKXlwQNOrQqw4,3980
112
+ iatoolkit/views/tasks_api_view.py,sha256=wGnuwuuL83ByQ1Yre6ytRVztA0OGQjGrwMjB1_G830U,2630
113
+ iatoolkit/views/tasks_review_api_view.py,sha256=wsCpzqyRyUdCXWAhyGlBe3eNZZ6A1DQG7TblN_GZNfM,1894
114
+ iatoolkit/views/user_feedback_api_view.py,sha256=QOTBtpNqYAmewXDgVAoaIprnVjvf1xM0ExWxSFp3ICI,2098
115
+ iatoolkit/views/verify_user_view.py,sha256=zo24b1Z-yAUR09zrAtl-o7-TwsSZQIHVHx2qK3VjEkc,2721
116
+ iatoolkit-0.66.2.dist-info/METADATA,sha256=tARrXrUegiJY4D_mftfIFDeEn2uclyfbp1e-lyeLnA8,9301
117
+ iatoolkit-0.66.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
118
+ iatoolkit-0.66.2.dist-info/top_level.txt,sha256=V_w4QvDx0b1RXiy8zTCrD1Bp7AZkFe3_O0-9fMiwogg,10
119
+ iatoolkit-0.66.2.dist-info/RECORD,,
iatoolkit/common/auth.py DELETED
@@ -1,200 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- from flask import redirect, url_for
7
- from iatoolkit.common.session_manager import SessionManager
8
- from datetime import datetime, timezone
9
- from injector import inject
10
- from iatoolkit.repositories.profile_repo import ProfileRepo
11
- from iatoolkit.services.jwt_service import JWTService
12
- import logging
13
- from flask import request
14
- from typing import Optional
15
-
16
- MAX_INACTIVITY_SECONDS = 60*30
17
-
18
- class IAuthentication:
19
- @inject
20
-
21
- def __init__(self,
22
- profile_repo: ProfileRepo,
23
- jwt_service: JWTService):
24
- self.profile_repo = profile_repo
25
- self.jwt_service = jwt_service
26
-
27
- def verify(self, company_short_name: str, body_external_user_id: str = None) -> dict:
28
- # authentication is in this orden: JWT, API Key, Sesión
29
- local_user_id = None
30
- company_id = None
31
- auth_method = None
32
- external_user_id = None # for JWT or API Key
33
-
34
- # 1. try auth via JWT
35
- jwt_company_id, jwt_external_user_id, jwt_error_info = self._authenticate_via_chat_jwt(company_short_name)
36
-
37
- if jwt_company_id is not None and jwt_external_user_id is not None:
38
- auth_method = "JWT"
39
- company_id = jwt_company_id
40
- external_user_id = jwt_external_user_id
41
- local_user_id = 0
42
- elif jwt_error_info is not None:
43
- # explicit error in JWT (inválido, expirado, etc.)
44
- logging.warning(f"Fallo de autenticación JWT: {jwt_error_info}")
45
- return {"error_message": "Fallo de autenticación JWT"}
46
- else:
47
- # 2. JWT not apply, try by API Key
48
- api_key_company_id, api_key_error_info = self._authenticate_via_api_key(company_short_name)
49
-
50
- if api_key_company_id is not None:
51
- auth_method = "API Key"
52
- company_id = api_key_company_id
53
- external_user_id = body_external_user_id # API Key usa external_user_id del body
54
- local_user_id = 0
55
- elif api_key_error_info is not None:
56
- # explicit error in API Key (inválida, incorrecta, error interno)
57
- logging.warning(f"Fallo de autenticación API Key: {api_key_error_info}")
58
- return {"error_message": "Fallo de autenticación API Key"}
59
- else:
60
- # 3. no JWT and API Key auth, try by Session
61
- self.check_if_user_is_logged_in(company_short_name) # raise exception or redirect if not logged in
62
-
63
- # In case not logged in check_if_user_is_logged_in redirects to login page
64
- auth_method = "Session"
65
- local_user_id = SessionManager.get('user_id')
66
- company_id = SessionManager.get('company_id')
67
- external_user_id = ""
68
-
69
- if not company_id or not local_user_id:
70
- logging.error(
71
- f"Sesión válida para {company_short_name} pero falta company_id o user_id en SessionManager.")
72
- return {"error_message": "Fallo interno en la autenticación o no autenticado"}
73
-
74
- # last verification of authentication
75
- if company_id is None or auth_method is None or local_user_id is None:
76
- # this condition should never happen,
77
- logging.error(
78
- f"Fallo inesperado en la lógica de autenticación para {company_short_name}. Ningún método tuvo éxito o devolvió error.")
79
- return {"error_message": "Fallo interno en la autenticación o no autenticado"}
80
-
81
- return {
82
- 'success': True,
83
- "auth_method": auth_method,
84
- "company_id": company_id,
85
- "auth_method": auth_method,
86
- "local_user_id": local_user_id,
87
- "external_user_id": external_user_id
88
- }
89
-
90
- def _authenticate_via_api_key(self, company_short_name_from_url: str):
91
- """
92
- try to authenticate using an API Key from the header 'Authorization'.
93
- Retorna (company_id, None) en éxito.
94
- Retorna (None, error_message) en fallo.
95
- """
96
- api_key_header = request.headers.get('Authorization')
97
- api_key_value = None
98
-
99
- # extract the key
100
- if api_key_header and api_key_header.startswith('Bearer '):
101
- api_key_value = api_key_header.split('Bearer ')[1]
102
- else:
103
- # there is no key in the headers expected
104
- return None, None
105
-
106
- # validate the api-key using ProfileRepo
107
- try:
108
- api_key_entry = self.profile_repo.get_active_api_key_entry(api_key_value)
109
- if not api_key_entry:
110
- logging.warning(f"Intento de acceso con API Key inválida o inactiva: {api_key_value[:5]}...")
111
- return None, "API Key inválida o inactiva"
112
-
113
- # check that the key belongs to the company
114
- # api_key_entry.company already loaded by joinedload
115
- if not api_key_entry.company or api_key_entry.company.short_name != company_short_name_from_url:
116
- return None, f"API Key no es válida para la compañía {company_short_name_from_url}"
117
-
118
- # successfull auth by API Key
119
- company_id = api_key_entry.company_id
120
-
121
- return company_id, None
122
-
123
- except Exception as e:
124
- logging.exception(f"Error interno durante validación de API Key: {e}")
125
- return None, "Error interno del servidor al validar API Key"
126
-
127
- def _authenticate_via_chat_jwt(self, company_short_name_from_url: str) -> tuple[
128
- Optional[int], Optional[str], Optional[str]]:
129
- """
130
- authenticate using an JWT chat session in the del header 'X-Chat-Token'.
131
- Return (company_id, external_user_id, None) on exit
132
- Returns (None, None, error_message) on fail.
133
- """
134
- chat_jwt = request.headers.get('X-Chat-Token')
135
- if not chat_jwt:
136
- return None, None, None
137
-
138
- # open the jwt token and retrieve the payload
139
- jwt_payload = self.jwt_service.validate_chat_jwt(chat_jwt, company_short_name_from_url)
140
- if not jwt_payload:
141
- # validation fails (token expired, incorrect signature, company , etc.)
142
- # validate_chat_jwt logs the specific failure
143
- return None, None, "Token de chat expirado, debes reingresar al chat"
144
-
145
- # JWT is validated: extract the company_id and external_user_id
146
- company_id = jwt_payload.get('company_id')
147
- external_user_id = jwt_payload.get('external_user_id')
148
-
149
- # Sanity check aditional, should never happen
150
- if not isinstance(company_id, int) or not external_user_id:
151
- logging.error(
152
- f"LLMQuery: JWT payload incompleto tras validación exitosa. CompanyID: {company_id}, UserID: {external_user_id}")
153
- return None, None, "Token de chat con formato interno incorrecto"
154
-
155
- return company_id, external_user_id, None
156
-
157
- def check_if_user_is_logged_in(self, company_short_name: str):
158
- if not SessionManager.get('user'):
159
- if company_short_name:
160
- return redirect(url_for('login', company_short_name=company_short_name))
161
- else:
162
- return redirect(url_for('home'))
163
-
164
- if company_short_name != SessionManager.get('company_short_name'):
165
- return redirect(url_for('login', company_short_name=company_short_name))
166
-
167
- # check session timeout
168
- if not self.check_session_timeout():
169
- SessionManager.clear()
170
- return redirect(url_for('login', company_short_name=company_short_name))
171
-
172
- # update last_activity
173
- SessionManager.set('last_activity', datetime.now(timezone.utc).timestamp())
174
-
175
- def check_session_timeout(self):
176
- # get last activity from session manager
177
- last_activity = SessionManager.get('last_activity')
178
- if not last_activity:
179
- return False
180
-
181
- # Tiempo actual en timestamp
182
- current_time = datetime.now(timezone.utc).timestamp()
183
-
184
- # get inactivity duration
185
- inactivity_duration = current_time - last_activity
186
-
187
- # verify if inactivity duration is greater than MAX_INACTIVITY_SECONDS
188
- if inactivity_duration > MAX_INACTIVITY_SECONDS:
189
- # close session
190
- return False
191
-
192
- # update last activity timestamp
193
- SessionManager.set('last_activity', current_time)
194
-
195
- return True # session is active
196
-
197
-
198
-
199
-
200
-
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,115 +0,0 @@
1
- $(document).ready(function () {
2
-
3
- // Evento para enviar el feedback
4
- $('#submit-feedback').on('click', async function() {
5
- const feedbackText = $('#feedback-text').val().trim();
6
- const submitButton = $(this);
7
-
8
- // --- LÓGICA DE COMPATIBILIDAD BS3 / BS5 ---
9
- // Detecta si Bootstrap 5 está presente.
10
- const isBootstrap5 = (typeof bootstrap !== 'undefined');
11
-
12
- // Define el HTML del botón de cierre según la versión.
13
- const closeButtonHtml = isBootstrap5 ?
14
- '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' : // Versión BS5
15
- '<button type="button" class="close" data-dismiss="alert"><span>&times;</span></button>'; // Versión BS3/BS4
16
- // --- FIN DE LA LÓGICA DE COMPATIBILIDAD ---
17
-
18
- if (!feedbackText) {
19
- const alertHtml = `
20
- <div class="alert alert-warning alert-dismissible fade show" role="alert">
21
- <strong>¡Atención!</strong> Por favor, escribe tu comentario antes de enviar.
22
- ${closeButtonHtml}
23
- </div>`;
24
- $('.modal-body .alert').remove();
25
- $('.modal-body').prepend(alertHtml);
26
- return;
27
- }
28
-
29
- const activeStars = $('.star.active').length;
30
- if (activeStars === 0) {
31
- const alertHtml = `
32
- <div class="alert alert-warning alert-dismissible fade show" role="alert">
33
- <strong>¡Atención!</strong> Por favor, califica al asistente con las estrellas.
34
- ${closeButtonHtml}
35
- </div>`;
36
- $('.modal-body .alert').remove();
37
- $('.modal-body').prepend(alertHtml);
38
- return;
39
- }
40
-
41
- submitButton.prop('disabled', true);
42
- submitButton.html('<i class="bi bi-send me-1 icon-spaced"></i>Enviando...');
43
-
44
- const response = await sendFeedback(feedbackText);
45
-
46
- $('#feedbackModal').modal('hide');
47
-
48
- if (response) {
49
- Swal.fire({ icon: 'success', title: 'Feedback enviado', text: 'Gracias por tu comentario.' });
50
- } else {
51
- Swal.fire({ icon: 'error', title: 'Error', text: 'No se pudo enviar el feedback, intente nuevamente.' });
52
- }
53
- });
54
-
55
- // Evento para abrir el modal de feedback
56
- $('#send-feedback-button').on('click', function() {
57
- $('#submit-feedback').prop('disabled', false);
58
- $('#submit-feedback').html('<i class="bi bi-send me-1 icon-spaced"></i>Enviar');
59
- $('.star').removeClass('active hover-active'); // Resetea estrellas
60
- $('#feedback-text').val(''); // Limpia texto
61
- $('.modal-body .alert').remove(); // Quita alertas previas
62
- $('#feedbackModal').modal('show');
63
- });
64
-
65
- // Evento que se dispara DESPUÉS de que el modal se ha ocultado
66
- $('#feedbackModal').on('hidden.bs.modal', function () {
67
- $('#feedback-text').val('');
68
- $('.modal-body .alert').remove();
69
- $('.star').removeClass('active');
70
- });
71
-
72
- // Función para el sistema de estrellas
73
- window.gfg = function(rating) {
74
- $('.star').removeClass('active');
75
- $('.star').each(function(index) {
76
- if (index < rating) {
77
- $(this).addClass('active');
78
- }
79
- });
80
- };
81
-
82
- $('.star').hover(
83
- function() {
84
- const rating = $(this).data('rating');
85
- $('.star').removeClass('hover-active');
86
- $('.star').each(function(index) {
87
- if ($(this).data('rating') <= rating) {
88
- $(this).addClass('hover-active');
89
- }
90
- });
91
- },
92
- function() {
93
- $('.star').removeClass('hover-active');
94
- }
95
- );
96
- });
97
-
98
- const sendFeedback = async function(message) {
99
- const activeStars = $('.star.active').length;
100
- const data = {
101
- "external_user_id": window.externalUserId,
102
- "message": message,
103
- "rating": activeStars,
104
- "space": "spaces/AAQAupQldd4", // Este valor podría necesitar ser dinámico
105
- "type": "MESSAGE_TRIGGER"
106
- };
107
- try {
108
- // Asumiendo que callLLMAPI está definido globalmente en otro archivo (ej. chat_main.js)
109
- const responseData = await callLLMAPI('/feedback', data, "POST");
110
- return responseData;
111
- } catch (error) {
112
- console.error("Error al enviar feedback:", error);
113
- return null;
114
- }
115
- }