django-spire 0.18.3__py3-none-any.whl → 0.19.1__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.
- django_spire/ai/admin.py +1 -0
- django_spire/ai/chat/apps.py +1 -8
- django_spire/ai/chat/intelligence/decoders/tools.py +29 -0
- django_spire/ai/chat/intelligence/prompts.py +13 -7
- django_spire/ai/chat/intelligence/workflows/chat_workflow.py +55 -57
- django_spire/ai/chat/models.py +2 -1
- django_spire/ai/chat/querysets.py +1 -3
- django_spire/ai/chat/responses.py +5 -0
- django_spire/ai/chat/templates/django_spire/ai/chat/card/chat_card.html +2 -2
- django_spire/ai/chat/templates/django_spire/ai/chat/dropdown/ellipsis_dropdown.html +1 -1
- django_spire/ai/chat/templates/django_spire/ai/chat/element/recent_chat_select_element.html +82 -44
- django_spire/ai/chat/templates/django_spire/ai/chat/message/loading_response_message.html +9 -4
- django_spire/ai/chat/templates/django_spire/ai/chat/message/message.html +33 -33
- django_spire/ai/chat/templates/django_spire/ai/chat/message/request_message.html +5 -8
- django_spire/ai/chat/templates/django_spire/ai/chat/message/response_message.html +14 -10
- django_spire/ai/chat/templates/django_spire/ai/chat/page/chat_page.html +35 -0
- django_spire/ai/chat/templates/django_spire/ai/chat/widget/dialog_widget.html +72 -24
- django_spire/ai/chat/templates/django_spire/ai/chat/widget/selection_widget.html +42 -0
- django_spire/ai/chat/tests/test_urls/test_json_urls.py +4 -2
- django_spire/ai/chat/urls/__init__.py +1 -1
- django_spire/ai/chat/urls/json_urls.py +1 -1
- django_spire/ai/chat/urls/page_urls.py +1 -1
- django_spire/ai/chat/urls/{template_urls.py → template/template_urls.py} +1 -1
- django_spire/ai/chat/views/json_views.py +4 -3
- django_spire/ai/chat/views/message_request_views.py +32 -14
- django_spire/ai/chat/views/message_response_views.py +14 -11
- django_spire/ai/chat/views/message_views.py +7 -1
- django_spire/ai/chat/views/page_views.py +2 -2
- django_spire/ai/chat/views/{template_views.py → template/template_views.py} +1 -7
- django_spire/ai/context/__init__.py +0 -0
- django_spire/ai/context/admin.py +15 -0
- django_spire/ai/context/apps.py +16 -0
- django_spire/ai/context/choices.py +11 -0
- django_spire/ai/context/intelligence/__init__.py +0 -0
- django_spire/ai/context/intelligence/prompts/__init__.py +0 -0
- django_spire/ai/context/intelligence/prompts/organization_prompts.py +19 -0
- django_spire/ai/context/migrations/0001_initial.py +67 -0
- django_spire/ai/context/migrations/__init__.py +0 -0
- django_spire/ai/context/models.py +67 -0
- django_spire/ai/context/querysets.py +15 -0
- django_spire/ai/context/seeding/__init__.py +0 -0
- django_spire/ai/context/seeding/seed.py +24 -0
- django_spire/ai/prompt/system/bots.py +3 -5
- django_spire/ai/prompt/tuning/bots.py +5 -10
- django_spire/ai/sms/admin.py +2 -0
- django_spire/ai/sms/apps.py +2 -7
- django_spire/ai/sms/decorators.py +2 -2
- django_spire/ai/sms/intelligence/workflows/sms_conversation_workflow.py +18 -18
- django_spire/ai/sms/tests/test_webhook.py +5 -4
- django_spire/ai/sms/urls.py +3 -0
- django_spire/ai/sms/views.py +3 -5
- django_spire/ai/urls.py +2 -0
- django_spire/auth/templates/django_spire/auth/form/login_form.html +25 -0
- django_spire/auth/templates/django_spire/auth/page/auth_page.html +2 -3
- django_spire/auth/templates/django_spire/auth/page/login_page.html +1 -25
- django_spire/conf.py +1 -3
- django_spire/consts.py +1 -7
- django_spire/contrib/seeding/intelligence/bots/seeder_generator_bot.py +3 -2
- django_spire/contrib/utils.py +2 -0
- django_spire/core/management/commands/spire_startapp_pkg/__init__.py +4 -20
- django_spire/core/management/commands/spire_startapp_pkg/builder.py +2 -2
- django_spire/core/management/commands/spire_startapp_pkg/config.py +2 -2
- django_spire/core/management/commands/spire_startapp_pkg/filesystem.py +1 -19
- django_spire/core/management/commands/spire_startapp_pkg/generator.py +8 -8
- django_spire/core/management/commands/spire_startapp_pkg/processor.py +3 -3
- django_spire/core/management/commands/spire_startapp_pkg/registry.py +0 -16
- django_spire/core/management/commands/spire_startapp_pkg/reporter.py +1 -21
- django_spire/core/management/commands/spire_startapp_pkg/resolver.py +0 -15
- django_spire/core/management/commands/spire_startapp_pkg/template/app/views/form_views.py.template +2 -2
- django_spire/core/management/commands/spire_startapp_pkg/template/app/views/page_views.py.template +2 -2
- django_spire/core/management/commands/spire_startapp_pkg/validator.py +9 -9
- django_spire/core/static/django_spire/css/app-button.css +11 -1
- django_spire/core/static/django_spire/css/app-import.css +2 -0
- django_spire/core/static/django_spire/css/app-layout.css +15 -0
- django_spire/core/static/django_spire/css/app-navigation.css +24 -2
- django_spire/core/static/django_spire/css/app-page.css +8 -0
- django_spire/core/static/django_spire/css/app-side-panel.css +102 -0
- django_spire/core/static/django_spire/css/app-text.css +19 -1
- django_spire/core/static/django_spire/css/bootstrap-extension.css +128 -7
- django_spire/core/static/django_spire/css/bootstrap-override.css +161 -111
- django_spire/core/static/django_spire/css/themes/ayu/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/ayu/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/catppuccin/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/catppuccin/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/default/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/default/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/dracula/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/dracula/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/gruvbox/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/gruvbox/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/material/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/material/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/nord/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/nord/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/oceanic-next/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/oceanic-next/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/one-dark/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/one-dark/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/palenight/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/palenight/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/rose-pine/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/rose-pine/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/synthwave/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/synthwave/app-light.css +0 -4
- django_spire/core/static/django_spire/css/themes/tokyo-night/app-dark.css +0 -4
- django_spire/core/static/django_spire/css/themes/tokyo-night/app-light.css +0 -4
- django_spire/core/static/django_spire/font/Poppins-Black.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-BlackItalic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-Bold.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-BoldItalic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-ExtraBold.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-ExtraBoldItalic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-ExtraLight.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-ExtraLightItalic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-Italic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-Light.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-LightItalic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-Medium.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-MediumItalic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-SemiBold.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-SemiBoldItalic.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-Thin.ttf +0 -0
- django_spire/core/static/django_spire/font/Poppins-ThinItalic.ttf +0 -0
- django_spire/core/static/django_spire/js/ui.js +12 -0
- django_spire/core/templates/django_spire/button/base_button.html +1 -1
- django_spire/core/templates/django_spire/button/primary_dark_outlined_button.html +3 -0
- django_spire/core/templates/django_spire/dropdown/element/dropdown_link_element.html +12 -8
- django_spire/core/templates/django_spire/dropdown/element/ellipsis_dropdown_modal_link_element.html +2 -1
- django_spire/core/templates/django_spire/dropdown/ellipsis_dropdown.html +2 -1
- django_spire/core/templates/django_spire/navigation/accordion/nav_accordion.html +1 -1
- django_spire/core/templates/django_spire/navigation/elements/nav_link.html +1 -1
- django_spire/core/templates/django_spire/navigation/elements/nav_title_divider.html +1 -1
- django_spire/core/templates/django_spire/navigation/side_navigation.html +52 -8
- django_spire/core/templates/django_spire/navigation/top_navigation.html +8 -2
- django_spire/core/templates/django_spire/page/full_page.html +223 -11
- django_spire/core/utils.py +26 -2
- django_spire/knowledge/collection/models.py +24 -0
- django_spire/knowledge/collection/services/transformation_service.py +2 -1
- django_spire/knowledge/collection/tests/test_services/test_transformation_service.py +44 -42
- django_spire/knowledge/collection/urls/form_urls.py +1 -0
- django_spire/knowledge/collection/urls/page_urls.py +1 -0
- django_spire/knowledge/collection/views/form_views.py +13 -2
- django_spire/knowledge/collection/views/page_views.py +36 -4
- django_spire/knowledge/entry/models.py +32 -0
- django_spire/knowledge/entry/services/transformation_services.py +10 -10
- django_spire/knowledge/entry/version/block/data/data.py +2 -1
- django_spire/knowledge/entry/version/block/data/heading_data.py +2 -2
- django_spire/knowledge/entry/version/block/data/list/data.py +3 -4
- django_spire/knowledge/entry/version/block/data/maps.py +3 -5
- django_spire/knowledge/entry/version/block/data/text_data.py +2 -2
- django_spire/knowledge/entry/version/block/models.py +10 -7
- django_spire/knowledge/entry/version/block/services/factory_service.py +11 -10
- django_spire/knowledge/entry/version/block/tests/factories.py +6 -5
- django_spire/knowledge/entry/version/converters/docx_converter.py +1 -1
- django_spire/knowledge/entry/version/intelligence/bots/markdown_format_llm_bot.py +14 -12
- django_spire/knowledge/entry/version/seeding/seeder.py +3 -3
- django_spire/knowledge/entry/version/services/processor_service.py +36 -10
- django_spire/knowledge/entry/version/tests/test_converters/test_docx_converter.py +1 -1
- django_spire/knowledge/entry/version/tests/test_urls/test_page_urls.py +1 -1
- django_spire/knowledge/entry/version/urls/page_urls.py +1 -1
- django_spire/knowledge/entry/version/views/json_views.py +5 -3
- django_spire/knowledge/entry/version/views/page_views.py +11 -12
- django_spire/knowledge/entry/version/views/redirect_views.py +1 -1
- django_spire/knowledge/entry/views/form_views.py +1 -1
- django_spire/knowledge/intelligence/bots/entry_search_llm_bot.py +33 -11
- django_spire/knowledge/intelligence/decoders/__init__.py +0 -0
- django_spire/knowledge/intelligence/{maps/collection_map.py → decoders/collection_decoder.py} +5 -5
- django_spire/knowledge/intelligence/{maps/entry_map.py → decoders/entry_decoder.py} +3 -3
- django_spire/knowledge/intelligence/intel/collection_intel.py +1 -0
- django_spire/knowledge/intelligence/intel/entry_intel.py +5 -2
- django_spire/knowledge/intelligence/intel/message_intel.py +2 -0
- django_spire/knowledge/intelligence/workflows/knowledge_workflow.py +43 -51
- django_spire/knowledge/migrations/0007_alter_collection_options.py +17 -0
- django_spire/knowledge/static/django_spire/knowledge/entry/version/js/editor.js +24 -5
- django_spire/knowledge/templates/django_spire/knowledge/collection/card/top_level_list_card.html +21 -0
- django_spire/knowledge/templates/django_spire/knowledge/collection/component/x_collection_navigation.html +15 -6
- django_spire/knowledge/templates/django_spire/knowledge/collection/element/ellipsis_dropdown.html +22 -0
- django_spire/knowledge/templates/django_spire/knowledge/collection/form/form.html +21 -9
- django_spire/knowledge/templates/django_spire/knowledge/collection/item/collection_item.html +19 -0
- django_spire/knowledge/templates/django_spire/knowledge/collection/page/display_page.html +49 -0
- django_spire/knowledge/templates/django_spire/knowledge/collection/page/form_page.html +1 -1
- django_spire/knowledge/templates/django_spire/knowledge/container/container.html +33 -0
- django_spire/knowledge/templates/django_spire/knowledge/entry/file/page/list_page.html +1 -1
- django_spire/knowledge/templates/django_spire/knowledge/entry/item/list_item.html +2 -2
- django_spire/knowledge/templates/django_spire/knowledge/entry/page/form_page.html +1 -1
- django_spire/knowledge/templates/django_spire/knowledge/entry/page/import_form_page.html +1 -1
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/container/detail_container.html +51 -45
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/editor_page.html +54 -0
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/form_page.html +1 -1
- django_spire/knowledge/templates/django_spire/knowledge/message/knowledge_message_intel.html +18 -1
- django_spire/knowledge/templates/django_spire/knowledge/page/full_page.html +37 -0
- django_spire/knowledge/templates/django_spire/knowledge/page/home_page.html +2 -2
- django_spire/knowledge/templates/django_spire/knowledge/sub_navigation/item/collection_sub_navigation_item.html +29 -0
- django_spire/knowledge/templates/django_spire/knowledge/sub_navigation/item/entry_sub_navigation_item.html +20 -0
- django_spire/knowledge/templates/django_spire/knowledge/{navigation/content/navigation_content.html → sub_navigation/widget/collection_entry_sub_navigation_widget.html} +42 -19
- django_spire/knowledge/views/page_views.py +4 -4
- django_spire/settings.py +3 -3
- django_spire/theme/templates/django_spire/theme/card/badges_preview_card.html +0 -1
- django_spire/theme/templates/django_spire/theme/card/base_preview_card.html +1 -0
- django_spire/theme/templates/django_spire/theme/card/typography_preview_card.html +1 -1
- django_spire/theme/templates/django_spire/theme/example/form/example_form.html +2 -0
- django_spire/theme/templates/django_spire/theme/example/form/example_form_card.html +5 -0
- django_spire/theme/templates/django_spire/theme/page/badges_page.html +7 -9
- django_spire/theme/templates/django_spire/theme/page/borders_page.html +6 -9
- django_spire/theme/templates/django_spire/theme/page/buttons_page.html +6 -9
- django_spire/theme/templates/django_spire/theme/page/colors_page.html +6 -6
- django_spire/theme/templates/django_spire/theme/page/dashboard_page.html +57 -0
- django_spire/theme/templates/django_spire/theme/page/django_glue_page.html +7 -9
- django_spire/theme/templates/django_spire/theme/page/theme_page.html +24 -0
- django_spire/theme/templates/django_spire/theme/page/typography_page.html +6 -9
- django_spire/theme/templates/django_spire/theme/section/badge_section_card.html +5 -0
- django_spire/theme/templates/django_spire/theme/section/border_section_card.html +5 -0
- django_spire/theme/templates/django_spire/theme/section/button_section.html +1 -0
- django_spire/theme/templates/django_spire/theme/section/button_section_card.html +5 -0
- django_spire/theme/templates/django_spire/theme/section/color_section.html +10 -10
- django_spire/theme/templates/django_spire/theme/section/color_section_card.html +5 -0
- django_spire/theme/templates/django_spire/theme/section/typography_section.html +41 -1
- django_spire/theme/templates/django_spire/theme/section/typography_section_card.html +5 -0
- {django_spire-0.18.3.dist-info → django_spire-0.19.1.dist-info}/METADATA +3 -3
- {django_spire-0.18.3.dist-info → django_spire-0.19.1.dist-info}/RECORD +229 -190
- django_spire/ai/chat/intelligence/bots/chat_bot.py +0 -8
- django_spire/ai/chat/intelligence/maps/intent_llm_map.py +0 -10
- django_spire/ai/chat/templates/django_spire/ai/chat/page/home_page.html +0 -9
- django_spire/ai/chat/templates/django_spire/ai/chat/widget/chat_widget.html +0 -64
- django_spire/ai/chat/templates/django_spire/ai/chat/widget/search_chat_results_widget.html +0 -25
- django_spire/ai/chat/templates/django_spire/ai/chat/widget/search_chat_widget.html +0 -39
- django_spire/ai/chat/templates/django_spire/ai/chat/widget/select_chat_widget.html +0 -24
- django_spire/ai/chat/tools.py +0 -57
- django_spire/ai/sms/tools.py +0 -57
- django_spire/core/static/django_spire/font/Karla-Bold.ttf +0 -0
- django_spire/core/static/django_spire/font/Merriweather.ttf +0 -0
- django_spire/knowledge/context_processors.py +0 -18
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/detail_page.html +0 -25
- django_spire/knowledge/templates/django_spire/knowledge/navigation/card/navigation_card.html +0 -9
- django_spire/knowledge/templates/django_spire/knowledge/navigation/item/collection/collection_item.html +0 -29
- django_spire/knowledge/templates/django_spire/knowledge/navigation/item/entry/entry_item.html +0 -18
- django_spire/knowledge/templates/django_spire/knowledge/navigation/page/full_page.html +0 -90
- /django_spire/ai/chat/intelligence/{bots → decoders}/__init__.py +0 -0
- /django_spire/ai/chat/{intelligence/maps → urls/template}/__init__.py +0 -0
- /django_spire/{knowledge/intelligence/maps → ai/chat/views/template}/__init__.py +0 -0
- /django_spire/knowledge/entry/version/{constants.py → consts.py} +0 -0
- /django_spire/knowledge/templates/django_spire/knowledge/{navigation/item/collection/dropdown/navigation_ellipsis_dropdown.html → sub_navigation/element/collection_sub_navigation_ellipsis_dropdown.html} +0 -0
- /django_spire/knowledge/templates/django_spire/knowledge/{navigation/item/entry/dropdown/navigation_ellipsis_dropdown.html → sub_navigation/element/entry_sub_navigation_ellipsis_dropdown.html} +0 -0
- {django_spire-0.18.3.dist-info → django_spire-0.19.1.dist-info}/WHEEL +0 -0
- {django_spire-0.18.3.dist-info → django_spire-0.19.1.dist-info}/licenses/LICENSE.md +0 -0
- {django_spire-0.18.3.dist-info → django_spire-0.19.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django.core.exceptions import ValidationError
|
|
4
|
+
from django.db import models
|
|
5
|
+
|
|
6
|
+
from django_spire.ai.context import querysets
|
|
7
|
+
from django_spire.ai.context.choices import PersonRoleChoices
|
|
8
|
+
from django_spire.auth.user.models import AuthUser
|
|
9
|
+
from django_spire.history.mixins import HistoryModelMixin
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Organization(HistoryModelMixin):
|
|
13
|
+
name = models.CharField(max_length=255, blank=True, null=True)
|
|
14
|
+
legal_name = models.CharField(max_length=255, blank=True, null=True)
|
|
15
|
+
description = models.TextField(blank=True, null=True)
|
|
16
|
+
sector = models.CharField(max_length=255, blank=True, null=True)
|
|
17
|
+
sub_sector = models.CharField(max_length=255, blank=True, null=True)
|
|
18
|
+
website = models.URLField(max_length=255, blank=True, null=True)
|
|
19
|
+
street_address = models.CharField(max_length=255, blank=True, null=True)
|
|
20
|
+
unit_number = models.CharField(max_length=32, blank=True, null=True)
|
|
21
|
+
city = models.CharField(max_length=255, blank=True, null=True)
|
|
22
|
+
province = models.CharField(max_length=255, blank=True, null=True)
|
|
23
|
+
postal_code = models.CharField(max_length=16, blank=True, null=True)
|
|
24
|
+
country = models.CharField(max_length=255, blank=True, null=True)
|
|
25
|
+
phone = models.CharField(max_length=255, blank=True, null=True)
|
|
26
|
+
email = models.EmailField(max_length=255, blank=True, null=True)
|
|
27
|
+
|
|
28
|
+
objects = querysets.OrganizationQuerySet.as_manager()
|
|
29
|
+
|
|
30
|
+
def save(self, *args, **kwargs) -> None:
|
|
31
|
+
if self.pk is None:
|
|
32
|
+
if self.__class__.objects.exists():
|
|
33
|
+
message = 'Only one AI Organization Context is allowed'
|
|
34
|
+
raise ValidationError(message)
|
|
35
|
+
|
|
36
|
+
return super().save(*args, **kwargs)
|
|
37
|
+
|
|
38
|
+
class Meta:
|
|
39
|
+
db_table = 'django_spire_ai_context_organization'
|
|
40
|
+
verbose_name = 'Organization Context'
|
|
41
|
+
verbose_name_plural = 'Organization Context'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Person(HistoryModelMixin):
|
|
45
|
+
is_internal_to_organization = models.BooleanField(default=True)
|
|
46
|
+
user = models.ForeignKey(
|
|
47
|
+
AuthUser,
|
|
48
|
+
blank=True,
|
|
49
|
+
null=True,
|
|
50
|
+
on_delete=models.SET_NULL,
|
|
51
|
+
related_name='ai_context_people',
|
|
52
|
+
related_query_name='ai_context_person'
|
|
53
|
+
)
|
|
54
|
+
role = models.CharField(max_length=16, choices=PersonRoleChoices, default=PersonRoleChoices.ADMIN)
|
|
55
|
+
role_details = models.TextField(blank=True, null=True)
|
|
56
|
+
first_name = models.CharField(max_length=255, blank=True, null=True)
|
|
57
|
+
last_name = models.CharField(max_length=255, blank=True, null=True)
|
|
58
|
+
phone = models.CharField(max_length=255, blank=True, null=True)
|
|
59
|
+
email = models.EmailField(max_length=255, blank=True, null=True)
|
|
60
|
+
|
|
61
|
+
objects = querysets.PeopleQuerySet.as_manager()
|
|
62
|
+
|
|
63
|
+
class Meta:
|
|
64
|
+
db_table = 'django_spire_ai_context_person'
|
|
65
|
+
verbose_name = 'Person Context'
|
|
66
|
+
verbose_name_plural = 'People Context'
|
|
67
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django_spire.history.querysets import HistoryQuerySet
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OrganizationQuerySet(HistoryQuerySet):
|
|
7
|
+
def get_only_or_none(self):
|
|
8
|
+
try:
|
|
9
|
+
return self.earliest('id')
|
|
10
|
+
except self.model.DoesNotExist:
|
|
11
|
+
return None
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class PeopleQuerySet(HistoryQuerySet):
|
|
15
|
+
pass
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django_spire.ai.context import models
|
|
4
|
+
from django_spire.ai.context import choices
|
|
5
|
+
|
|
6
|
+
from faker import Faker
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
models.Organization.objects.create(
|
|
10
|
+
name='Spire Candy',
|
|
11
|
+
legal_name='Spire Candy Processors Limited',
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
for people_role_choice in choices.PersonRoleChoices:
|
|
15
|
+
first_name = Faker().first_name()
|
|
16
|
+
last_name = Faker().last_name()
|
|
17
|
+
|
|
18
|
+
people = models.Person.objects.create(
|
|
19
|
+
role=people_role_choice.value,
|
|
20
|
+
first_name=first_name,
|
|
21
|
+
last_name=last_name,
|
|
22
|
+
email=f'{first_name.lower()}.{last_name.lower()}@spirecandy.ca',
|
|
23
|
+
phone=Faker().phone_number(),
|
|
24
|
+
)
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dandy import Bot, LlmConfigOptions
|
|
3
|
+
from dandy import Bot, LlmConfigOptions
|
|
4
4
|
|
|
5
|
-
from django_spire.ai.prompt.system import prompts
|
|
6
|
-
from django_spire.ai.prompt.system import intel
|
|
7
|
-
from django_spire.ai.prompt.system.intel import SystemPromptIntel
|
|
5
|
+
from django_spire.ai.prompt.system import intel, prompts
|
|
8
6
|
|
|
9
7
|
|
|
10
8
|
class RoleSystemPromptBot(Bot):
|
|
@@ -70,7 +68,7 @@ class SystemPromptBot(Bot):
|
|
|
70
68
|
guidelines = guidelines_bot.process(user_story)
|
|
71
69
|
output_format = output_format_bot.process(user_story)
|
|
72
70
|
|
|
73
|
-
return SystemPromptIntel(
|
|
71
|
+
return intel.SystemPromptIntel(
|
|
74
72
|
role=role.result,
|
|
75
73
|
task=task.result,
|
|
76
74
|
guidelines=guidelines.result,
|
|
@@ -65,8 +65,7 @@ class FormattingBot(Bot):
|
|
|
65
65
|
def process(self, system_prompt: str) -> intel.PromptTuningIntel:
|
|
66
66
|
return self.llm.prompt_to_intel(
|
|
67
67
|
prompt=prompts.specialized_bot_input_prompt(system_prompt),
|
|
68
|
-
intel_class=intel.PromptTuningIntel
|
|
69
|
-
postfix_system_prompt=None
|
|
68
|
+
intel_class=intel.PromptTuningIntel
|
|
70
69
|
)
|
|
71
70
|
|
|
72
71
|
|
|
@@ -76,8 +75,7 @@ class InstructionClarityBot(Bot):
|
|
|
76
75
|
def process(self, system_prompt: str) -> intel.PromptTuningIntel:
|
|
77
76
|
return self.llm.prompt_to_intel(
|
|
78
77
|
prompt=prompts.specialized_bot_input_prompt(system_prompt),
|
|
79
|
-
intel_class=intel.PromptTuningIntel
|
|
80
|
-
postfix_system_prompt=None
|
|
78
|
+
intel_class=intel.PromptTuningIntel
|
|
81
79
|
)
|
|
82
80
|
|
|
83
81
|
|
|
@@ -87,8 +85,7 @@ class PersonaBot(Bot):
|
|
|
87
85
|
def process(self, system_prompt: str) -> intel.PromptTuningIntel:
|
|
88
86
|
return self.llm.prompt_to_intel(
|
|
89
87
|
prompt=prompts.specialized_bot_input_prompt(system_prompt),
|
|
90
|
-
intel_class=intel.PromptTuningIntel
|
|
91
|
-
postfix_system_prompt=None
|
|
88
|
+
intel_class=intel.PromptTuningIntel
|
|
92
89
|
)
|
|
93
90
|
|
|
94
91
|
|
|
@@ -98,8 +95,7 @@ class DuplicationRemovalBot(Bot):
|
|
|
98
95
|
def process(self, system_prompt: str) -> intel.PromptTuningIntel:
|
|
99
96
|
return self.llm.prompt_to_intel(
|
|
100
97
|
prompt=prompts.specialized_bot_input_prompt(system_prompt),
|
|
101
|
-
intel_class=intel.PromptTuningIntel
|
|
102
|
-
postfix_system_prompt=None
|
|
98
|
+
intel_class=intel.PromptTuningIntel
|
|
103
99
|
)
|
|
104
100
|
|
|
105
101
|
|
|
@@ -109,6 +105,5 @@ class ExampleOptimizationBot(Bot):
|
|
|
109
105
|
def process(self, system_prompt: str) -> intel.PromptTuningIntel:
|
|
110
106
|
return self.llm.prompt_to_intel(
|
|
111
107
|
prompt=prompts.specialized_bot_input_prompt(system_prompt),
|
|
112
|
-
intel_class=intel.PromptTuningIntel
|
|
113
|
-
postfix_system_prompt=None
|
|
108
|
+
intel_class=intel.PromptTuningIntel
|
|
114
109
|
)
|
django_spire/ai/sms/admin.py
CHANGED
|
@@ -25,11 +25,13 @@ class SmsConversationAdmin(admin.ModelAdmin):
|
|
|
25
25
|
|
|
26
26
|
def view_sms_messages_link(self, obj):
|
|
27
27
|
count = obj.messages.count()
|
|
28
|
+
|
|
28
29
|
url = (
|
|
29
30
|
reverse("admin:django_spire_ai_sms_smsmessage_changelist")
|
|
30
31
|
+ "?"
|
|
31
32
|
+ urlencode({"sms_conversation__id": f"{obj.id}"})
|
|
32
33
|
)
|
|
34
|
+
|
|
33
35
|
return format_html('<a href="%s">%s Messages</a>' % (url, count))
|
|
34
36
|
|
|
35
37
|
view_sms_messages_link.short_description = "Messages"
|
django_spire/ai/sms/apps.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from django.apps import AppConfig
|
|
4
|
-
from django.conf import settings
|
|
5
4
|
|
|
6
|
-
from django_spire.consts import AI_SMS_CONVERSATION_WORKFLOW_CLASS_SETTINGS_NAME
|
|
7
5
|
from django_spire.utils import check_required_apps
|
|
8
6
|
|
|
9
7
|
|
|
@@ -12,10 +10,7 @@ class SmsConfig(AppConfig):
|
|
|
12
10
|
name = 'django_spire.ai.sms'
|
|
13
11
|
label = 'django_spire_ai_sms'
|
|
14
12
|
|
|
15
|
-
REQUIRED_APPS = ('django_spire_ai',)
|
|
16
|
-
|
|
17
|
-
def ready(self):
|
|
18
|
-
if not isinstance(getattr(settings, AI_SMS_CONVERSATION_WORKFLOW_CLASS_SETTINGS_NAME), str):
|
|
19
|
-
raise ValueError(f'"{AI_SMS_CONVERSATION_WORKFLOW_CLASS_SETTINGS_NAME}" must be set in the django settings when using "{self.label}".')
|
|
13
|
+
REQUIRED_APPS = ('django_spire_ai', 'django_spire_ai_context')
|
|
20
14
|
|
|
15
|
+
def ready(self) -> None:
|
|
21
16
|
check_required_apps(self.label)
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
3
5
|
from dandy.recorder import recorder_to_html_file
|
|
4
|
-
from dandy.llm.request.message import MessageHistory
|
|
5
|
-
from django.core.handlers.wsgi import WSGIRequest
|
|
6
6
|
|
|
7
|
-
from django_spire.ai.chat.intelligence.workflows.chat_workflow import
|
|
7
|
+
from django_spire.ai.chat.intelligence.workflows.chat_workflow import chat_workflow
|
|
8
8
|
from django_spire.ai.sms.intel import SmsIntel
|
|
9
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from django.core.handlers.wsgi import WSGIRequest
|
|
12
|
+
from dandy.llm.request.message import MessageHistory
|
|
13
|
+
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
SpireChatWorkflow.process(
|
|
22
|
-
request,
|
|
23
|
-
user_input=user_input,
|
|
24
|
-
message_history=message_history,
|
|
25
|
-
)
|
|
15
|
+
@recorder_to_html_file('spire_ai_sms_conversation_workflow')
|
|
16
|
+
def sms_conversation_workflow(
|
|
17
|
+
request: WSGIRequest, user_input: str, message_history: MessageHistory | None = None, actor: str | None = None
|
|
18
|
+
) -> SmsIntel:
|
|
19
|
+
return SmsIntel(
|
|
20
|
+
body=str(
|
|
21
|
+
chat_workflow(
|
|
22
|
+
request,
|
|
23
|
+
user_input=user_input,
|
|
24
|
+
message_history=message_history,
|
|
26
25
|
)
|
|
27
26
|
)
|
|
27
|
+
)
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
from unittest.mock import patch
|
|
2
2
|
|
|
3
|
-
from django.test import TestCase, Client
|
|
4
3
|
from django.urls import reverse
|
|
5
4
|
|
|
6
5
|
from django_spire.ai.sms.models import SmsConversation
|
|
6
|
+
from django_spire.core.tests.test_cases import BaseTestCase
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class SmsWebhookTests(
|
|
9
|
+
class SmsWebhookTests(BaseTestCase):
|
|
10
10
|
def setUp(self):
|
|
11
|
-
|
|
11
|
+
super().setUp()
|
|
12
|
+
|
|
12
13
|
self.webhook_url = reverse('django_spire:ai:sms:webhook')
|
|
13
14
|
|
|
14
15
|
@patch('twilio.request_validator.RequestValidator.validate')
|
|
@@ -34,4 +35,4 @@ class SmsWebhookTests(TestCase):
|
|
|
34
35
|
self.assertEqual(inbound_message.twilio_sid, 'SM123456789')
|
|
35
36
|
|
|
36
37
|
outbound_message = conversation.messages.filter(is_inbound=False).first()
|
|
37
|
-
self.assertTrue(len(outbound_message.body) > 0)
|
|
38
|
+
self.assertTrue(len(outbound_message.body) > 0)
|
django_spire/ai/sms/urls.py
CHANGED
django_spire/ai/sms/views.py
CHANGED
|
@@ -6,8 +6,8 @@ from django.views.decorators.http import require_POST
|
|
|
6
6
|
from twilio.twiml.messaging_response import MessagingResponse
|
|
7
7
|
|
|
8
8
|
from django_spire.ai.sms.decorators import twilio_auth_required
|
|
9
|
+
from django_spire.ai.sms.intelligence.workflows.sms_conversation_workflow import sms_conversation_workflow
|
|
9
10
|
from django_spire.ai.sms.models import SmsConversation
|
|
10
|
-
from django_spire.ai.sms.tools import sms_workflow_process
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@csrf_exempt
|
|
@@ -22,7 +22,7 @@ def webhook_view(request):
|
|
|
22
22
|
body = request.POST.get('Body', '')
|
|
23
23
|
message_sid = request.POST.get('MessageSid', '')
|
|
24
24
|
|
|
25
|
-
conversation,
|
|
25
|
+
conversation, _ = SmsConversation.objects.get_or_create(
|
|
26
26
|
phone_number=from_number
|
|
27
27
|
)
|
|
28
28
|
|
|
@@ -33,8 +33,7 @@ def webhook_view(request):
|
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
try:
|
|
36
|
-
|
|
37
|
-
sms_intel = sms_workflow_process(
|
|
36
|
+
sms_intel = sms_conversation_workflow(
|
|
38
37
|
request=request,
|
|
39
38
|
user_input=body,
|
|
40
39
|
message_history=conversation.generate_message_history(),
|
|
@@ -55,7 +54,6 @@ def webhook_view(request):
|
|
|
55
54
|
message.save()
|
|
56
55
|
|
|
57
56
|
return HttpResponse(twiml_response)
|
|
58
|
-
|
|
59
57
|
except:
|
|
60
58
|
raise
|
|
61
59
|
|
django_spire/ai/urls.py
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<form
|
|
2
|
+
class="text-app-secondary"
|
|
3
|
+
method="post"
|
|
4
|
+
x-data="{
|
|
5
|
+
username: new GlueCharField('username', {required: true, label: {% block username_label %}'Email Address'{% endblock %}}),
|
|
6
|
+
password: new GlueCharField('password', {required: true})
|
|
7
|
+
}"
|
|
8
|
+
>
|
|
9
|
+
{% csrf_token %}
|
|
10
|
+
<div class="row">
|
|
11
|
+
<div class="col">
|
|
12
|
+
{% include 'django_glue/form/field/char_field.html' with glue_field='username' %}
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="row mt-2">
|
|
16
|
+
<div class="col">
|
|
17
|
+
{% include 'django_glue/form/field/password_field.html' with glue_field='password' %}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="row mt-2">
|
|
21
|
+
<div class="col">
|
|
22
|
+
<button type="submit" class="d-block mx-auto btn btn-app-primary-outlined my-4 w-100">Login</button>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</form>
|
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
{% load static %}
|
|
4
4
|
|
|
5
5
|
{% block page_content %}
|
|
6
|
-
<div class="row justify-content-center
|
|
6
|
+
<div class="row justify-content-center mx-auto mt-5">
|
|
7
7
|
<div class="col-11 col-md-6 col-lg-4 bg-app-layer-one">
|
|
8
8
|
<div class="px-4 py-5">
|
|
9
9
|
{% block authentication_page_top_content %}
|
|
10
10
|
<div class="text-center pb-5">
|
|
11
11
|
<a href="/">
|
|
12
12
|
{% block authentication_page_img %}
|
|
13
|
-
<img class="ms-1
|
|
14
|
-
alt="">
|
|
13
|
+
<img height="120px" class="ms-1" src="{% static 'img/django_spire.png' %}" alt="">
|
|
15
14
|
{% endblock %}
|
|
16
15
|
</a>
|
|
17
16
|
</div>
|
|
@@ -1,31 +1,7 @@
|
|
|
1
1
|
{% extends 'django_spire/auth/page/auth_page.html' %}
|
|
2
2
|
|
|
3
3
|
{% block authentication_page_content %}
|
|
4
|
-
|
|
5
|
-
class="text-app-secondary"
|
|
6
|
-
method="post"
|
|
7
|
-
x-data="{
|
|
8
|
-
username: new GlueCharField('username', {required: true, label: {% block username_label %}'Email Address'{% endblock %}}),
|
|
9
|
-
password: new GlueCharField('password', {required: true})
|
|
10
|
-
}"
|
|
11
|
-
>
|
|
12
|
-
{% csrf_token %}
|
|
13
|
-
<div class="row">
|
|
14
|
-
<div class="col">
|
|
15
|
-
{% include 'django_glue/form/field/char_field.html' with glue_field='username' %}
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
<div class="row mt-2">
|
|
19
|
-
<div class="col">
|
|
20
|
-
{% include 'django_glue/form/field/password_field.html' with glue_field='password' %}
|
|
21
|
-
</div>
|
|
22
|
-
</div>
|
|
23
|
-
<div class="row mt-2">
|
|
24
|
-
<div class="col">
|
|
25
|
-
<button type="submit" class="d-block mx-auto btn btn-app-primary-outlined my-4 w-100">Login</button>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
</form>
|
|
4
|
+
{% include 'django_spire/auth/form/login_form.html' %}
|
|
29
5
|
|
|
30
6
|
<div class="text-center">
|
|
31
7
|
<a href="{% url 'django_spire:auth:admin:password_reset' %}"
|
django_spire/conf.py
CHANGED
django_spire/consts.py
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
__VERSION__ = '0.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
AI_CHAT_WORKFLOW_SENDER_SETTINGS_NAME = 'AI_CHAT_WORKFLOW_NAME'
|
|
5
|
-
AI_CHAT_WORKFLOW_CLASS_SETTINGS_NAME = 'AI_CHAT_WORKFLOW_CLASS'
|
|
6
|
-
AI_SMS_CONVERSATION_WORKFLOW_CLASS_SETTINGS_NAME = 'AI_SMS_CONVERSATION_WORKFLOW_CLASS'
|
|
7
|
-
|
|
1
|
+
__VERSION__ = '0.19.1'
|
|
8
2
|
|
|
9
3
|
MAINTENANCE_MODE_SETTINGS_NAME = 'MAINTENANCE_MODE'
|
|
10
4
|
|
|
@@ -15,6 +15,8 @@ class SeederGeneratorBot(Bot):
|
|
|
15
15
|
randomize_seed=True
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
+
llm_guidelines = generate_django_model_seeder_system_prompt()
|
|
19
|
+
|
|
18
20
|
llm_role = 'You are an expert Python developer specializing in Django model seeders.'
|
|
19
21
|
|
|
20
22
|
def process(
|
|
@@ -27,6 +29,5 @@ class SeederGeneratorBot(Bot):
|
|
|
27
29
|
model_import,
|
|
28
30
|
model_description,
|
|
29
31
|
),
|
|
30
|
-
intel_class=SourceIntel
|
|
31
|
-
postfix_system_prompt=generate_django_model_seeder_system_prompt()
|
|
32
|
+
intel_class=SourceIntel
|
|
32
33
|
)
|
|
@@ -6,10 +6,7 @@ from django_spire.core.management.commands.spire_startapp_pkg.config import (
|
|
|
6
6
|
AppConfigFactory,
|
|
7
7
|
PathConfig,
|
|
8
8
|
)
|
|
9
|
-
from django_spire.core.management.commands.spire_startapp_pkg.filesystem import
|
|
10
|
-
FileSystem,
|
|
11
|
-
FileSystemInterface,
|
|
12
|
-
)
|
|
9
|
+
from django_spire.core.management.commands.spire_startapp_pkg.filesystem import FileSystem
|
|
13
10
|
from django_spire.core.management.commands.spire_startapp_pkg.generator import (
|
|
14
11
|
AppGenerator,
|
|
15
12
|
TemplateGenerator,
|
|
@@ -20,18 +17,9 @@ from django_spire.core.management.commands.spire_startapp_pkg.processor import (
|
|
|
20
17
|
TemplateEngine,
|
|
21
18
|
TemplateProcessor,
|
|
22
19
|
)
|
|
23
|
-
from django_spire.core.management.commands.spire_startapp_pkg.registry import
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
)
|
|
27
|
-
from django_spire.core.management.commands.spire_startapp_pkg.reporter import (
|
|
28
|
-
Reporter,
|
|
29
|
-
ReporterInterface,
|
|
30
|
-
)
|
|
31
|
-
from django_spire.core.management.commands.spire_startapp_pkg.resolver import (
|
|
32
|
-
PathResolver,
|
|
33
|
-
PathResolverInterface,
|
|
34
|
-
)
|
|
20
|
+
from django_spire.core.management.commands.spire_startapp_pkg.registry import AppRegistry
|
|
21
|
+
from django_spire.core.management.commands.spire_startapp_pkg.reporter import Reporter
|
|
22
|
+
from django_spire.core.management.commands.spire_startapp_pkg.resolver import PathResolver
|
|
35
23
|
from django_spire.core.management.commands.spire_startapp_pkg.user_input import UserInputCollector
|
|
36
24
|
from django_spire.core.management.commands.spire_startapp_pkg.validator import AppValidator
|
|
37
25
|
|
|
@@ -41,16 +29,12 @@ __all__ = [
|
|
|
41
29
|
'AppConfigFactory',
|
|
42
30
|
'AppGenerator',
|
|
43
31
|
'AppRegistry',
|
|
44
|
-
'AppRegistryInterface',
|
|
45
32
|
'AppValidator',
|
|
46
33
|
'FileSystem',
|
|
47
|
-
'FileSystemInterface',
|
|
48
34
|
'PathConfig',
|
|
49
35
|
'PathResolver',
|
|
50
|
-
'PathResolverInterface',
|
|
51
36
|
'PermissionInheritanceHandler',
|
|
52
37
|
'Reporter',
|
|
53
|
-
'ReporterInterface',
|
|
54
38
|
'TemplateBuilder',
|
|
55
39
|
'TemplateEngine',
|
|
56
40
|
'TemplateGenerator',
|
|
@@ -7,7 +7,7 @@ from django_spire.core.management.commands.spire_startapp_pkg.maps import genera
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
|
-
from django_spire.core.management.commands.spire_startapp_pkg.reporter import
|
|
10
|
+
from django_spire.core.management.commands.spire_startapp_pkg.reporter import Reporter
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class TemplateBuilder:
|
|
@@ -18,7 +18,7 @@ class TemplateBuilder:
|
|
|
18
18
|
that will be created for new apps and their associated templates.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
def __init__(self, reporter:
|
|
21
|
+
def __init__(self, reporter: Reporter):
|
|
22
22
|
"""
|
|
23
23
|
Initializes the TemplateBuilder with a reporter for output.
|
|
24
24
|
|
|
@@ -7,7 +7,7 @@ from pathlib import Path
|
|
|
7
7
|
from typing import TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
|
-
from django_spire.core.management.commands.spire_startapp_pkg.resolver import
|
|
10
|
+
from django_spire.core.management.commands.spire_startapp_pkg.resolver import PathResolver
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@dataclass(frozen=True)
|
|
@@ -84,7 +84,7 @@ class AppConfigFactory:
|
|
|
84
84
|
paths and processing user inputs.
|
|
85
85
|
"""
|
|
86
86
|
|
|
87
|
-
def __init__(self, path_resolver:
|
|
87
|
+
def __init__(self, path_resolver: PathResolver):
|
|
88
88
|
"""
|
|
89
89
|
Initializes the factory with a path resolver.
|
|
90
90
|
|
|
@@ -2,31 +2,13 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import shutil
|
|
4
4
|
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from typing import Iterator
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class FileSystemInterface(Protocol):
|
|
13
|
-
"""
|
|
14
|
-
Protocol defining the interface for file system operations.
|
|
15
|
-
|
|
16
|
-
This protocol specifies the methods required for interacting with
|
|
17
|
-
the file system during app creation.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
def copy_tree(self, src: Path, dst: Path) -> None: ...
|
|
21
|
-
def create_directory(self, path: Path) -> None: ...
|
|
22
|
-
def exists(self, path: Path) -> bool: ...
|
|
23
|
-
def has_content(self, path: Path) -> bool: ...
|
|
24
|
-
def iterate_files(self, path: Path, pattern: str) -> Iterator[Path]: ...
|
|
25
|
-
def read_file(self, path: Path) -> str: ...
|
|
26
|
-
def rename(self, old: Path, new: Path) -> None: ...
|
|
27
|
-
def write_file(self, path: Path, content: str) -> None: ...
|
|
28
|
-
|
|
29
|
-
|
|
30
12
|
class FileSystem:
|
|
31
13
|
"""
|
|
32
14
|
Implementation of file system operations for app generation.
|
|
@@ -8,9 +8,9 @@ if TYPE_CHECKING:
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
from django_spire.core.management.commands.spire_startapp_pkg.config import AppConfig, PathConfig
|
|
11
|
-
from django_spire.core.management.commands.spire_startapp_pkg.filesystem import
|
|
11
|
+
from django_spire.core.management.commands.spire_startapp_pkg.filesystem import FileSystem
|
|
12
12
|
from django_spire.core.management.commands.spire_startapp_pkg.processor import TemplateProcessor
|
|
13
|
-
from django_spire.core.management.commands.spire_startapp_pkg.reporter import
|
|
13
|
+
from django_spire.core.management.commands.spire_startapp_pkg.reporter import Reporter
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class AppGenerator:
|
|
@@ -23,15 +23,15 @@ class AppGenerator:
|
|
|
23
23
|
|
|
24
24
|
def __init__(
|
|
25
25
|
self,
|
|
26
|
-
filesystem:
|
|
26
|
+
filesystem: FileSystem,
|
|
27
27
|
processor: TemplateProcessor,
|
|
28
|
-
reporter:
|
|
28
|
+
reporter: Reporter,
|
|
29
29
|
path_config: PathConfig
|
|
30
30
|
):
|
|
31
31
|
"""
|
|
32
32
|
Initializes the AppGenerator with required dependencies.
|
|
33
33
|
|
|
34
|
-
:param filesystem: File system
|
|
34
|
+
:param filesystem: File system for file operations.
|
|
35
35
|
:param processor: Template processor for replacing placeholders.
|
|
36
36
|
:param reporter: Reporter for user feedback and output.
|
|
37
37
|
:param path_config: Configuration containing template paths.
|
|
@@ -100,15 +100,15 @@ class TemplateGenerator:
|
|
|
100
100
|
|
|
101
101
|
def __init__(
|
|
102
102
|
self,
|
|
103
|
-
filesystem:
|
|
103
|
+
filesystem: FileSystem,
|
|
104
104
|
processor: TemplateProcessor,
|
|
105
|
-
reporter:
|
|
105
|
+
reporter: Reporter,
|
|
106
106
|
path_config: PathConfig
|
|
107
107
|
):
|
|
108
108
|
"""
|
|
109
109
|
Initializes the TemplateGenerator with required dependencies.
|
|
110
110
|
|
|
111
|
-
:param filesystem: File system
|
|
111
|
+
:param filesystem: File system for file operations.
|
|
112
112
|
:param processor: Template processor for replacing placeholders.
|
|
113
113
|
:param reporter: Reporter for user feedback and output.
|
|
114
114
|
:param path_config: Configuration containing template paths.
|