django-spire 0.18.3__py3-none-any.whl → 0.19.0__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 +40 -52
- 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 +8 -3
- django_spire/ai/chat/templates/django_spire/ai/chat/message/message.html +16 -7
- 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 -23
- 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/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 +218 -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.0.dist-info}/METADATA +3 -3
- {django_spire-0.18.3.dist-info → django_spire-0.19.0.dist-info}/RECORD +217 -178
- 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.0.dist-info}/WHEEL +0 -0
- {django_spire-0.18.3.dist-info → django_spire-0.19.0.dist-info}/licenses/LICENSE.md +0 -0
- {django_spire-0.18.3.dist-info → django_spire-0.19.0.dist-info}/top_level.txt +0 -0
|
@@ -42,15 +42,15 @@ class EntryTransformationService(BaseDjangoModelService['Entry']):
|
|
|
42
42
|
if current_version.published_datetime else ''
|
|
43
43
|
),
|
|
44
44
|
'status': current_version.status,
|
|
45
|
-
'delete_url': f
|
|
45
|
+
'delete_url': f"""
|
|
46
46
|
{site}{
|
|
47
47
|
reverse(
|
|
48
48
|
'django_spire:knowledge:entry:page:delete',
|
|
49
49
|
kwargs={'pk': self.obj.pk},
|
|
50
50
|
)
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
'edit_url': f
|
|
52
|
+
""",
|
|
53
|
+
'edit_url': f"""
|
|
54
54
|
{site}{
|
|
55
55
|
reverse(
|
|
56
56
|
'django_spire:knowledge:entry:form:update',
|
|
@@ -60,21 +60,21 @@ class EntryTransformationService(BaseDjangoModelService['Entry']):
|
|
|
60
60
|
},
|
|
61
61
|
)
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
'view_url': f
|
|
63
|
+
""",
|
|
64
|
+
'view_url': f"""
|
|
65
65
|
{site}{
|
|
66
66
|
reverse(
|
|
67
|
-
'django_spire:knowledge:entry:version:page:
|
|
67
|
+
'django_spire:knowledge:entry:version:page:editor',
|
|
68
68
|
kwargs={'pk': current_version.pk},
|
|
69
69
|
)
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
'edit_version_url': f
|
|
71
|
+
""",
|
|
72
|
+
'edit_version_url': f"""
|
|
73
73
|
{site}{
|
|
74
74
|
reverse(
|
|
75
|
-
'django_spire:knowledge:entry:version:page:
|
|
75
|
+
'django_spire:knowledge:entry:version:page:editor',
|
|
76
76
|
kwargs={'pk': current_version.pk},
|
|
77
77
|
)
|
|
78
78
|
}?view_mode=edit
|
|
79
|
-
|
|
79
|
+
"""
|
|
80
80
|
}
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class BaseEditorJsBlockData(BaseModel):
|
|
7
7
|
"""
|
|
8
8
|
This class serves as a foundational abstract model for EditorJS tool data objects.
|
|
9
9
|
|
|
@@ -29,5 +29,6 @@ class BaseEditorBlockData(BaseModel):
|
|
|
29
29
|
|
|
30
30
|
Raises:
|
|
31
31
|
NotImplementedError: If the method is not implemented in a subclass.
|
|
32
|
+
|
|
32
33
|
"""
|
|
33
34
|
raise NotImplementedError
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from django_spire.knowledge.entry.version.block.data.data import
|
|
3
|
+
from django_spire.knowledge.entry.version.block.data.data import BaseEditorJsBlockData
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class HeadingEditorBlockData(
|
|
6
|
+
class HeadingEditorBlockData(BaseEditorJsBlockData):
|
|
7
7
|
text: str
|
|
8
8
|
level: int
|
|
9
9
|
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
4
|
from pydantic import model_validator, BaseModel
|
|
6
5
|
|
|
7
6
|
from django_spire.knowledge.entry.version.block.constants import SPACES_PER_INDENT
|
|
8
|
-
from django_spire.knowledge.entry.version.block.data.data import
|
|
7
|
+
from django_spire.knowledge.entry.version.block.data.data import BaseEditorJsBlockData
|
|
9
8
|
from django_spire.knowledge.entry.version.block.data.list.meta import ChecklistItemMeta, \
|
|
10
9
|
OrderedListItemMeta
|
|
11
10
|
from django_spire.knowledge.entry.version.block.data.list.choices import \
|
|
12
11
|
ListEditorBlockDataStyle
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
class ListEditorBlockData(
|
|
14
|
+
class ListEditorBlockData(BaseEditorJsBlockData):
|
|
16
15
|
style: ListEditorBlockDataStyle | str
|
|
17
16
|
meta: ChecklistItemMeta | OrderedListItemMeta | None = None
|
|
18
17
|
items: list[ListItemEditorBlockData]
|
|
@@ -41,7 +40,7 @@ class ListEditorBlockData(BaseEditorBlockData):
|
|
|
41
40
|
class ListItemEditorBlockData(BaseModel):
|
|
42
41
|
content: str
|
|
43
42
|
meta: ChecklistItemMeta | OrderedListItemMeta | dict | None = None
|
|
44
|
-
items:
|
|
43
|
+
items: list[ListItemEditorBlockData] | None = []
|
|
45
44
|
|
|
46
45
|
def get_prefix(
|
|
47
46
|
self,
|
|
@@ -9,15 +9,13 @@ from django_spire.knowledge.entry.version.block.data.text_data import \
|
|
|
9
9
|
TextEditorBlockData
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
EDITOR_JS_BLOCK_DATA_MAP = {
|
|
13
13
|
BlockTypeChoices.TEXT: TextEditorBlockData,
|
|
14
14
|
BlockTypeChoices.HEADING: HeadingEditorBlockData,
|
|
15
15
|
BlockTypeChoices.LIST: ListEditorBlockData,
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
HeadingEditorBlockData: BlockTypeChoices.HEADING,
|
|
22
|
-
ListEditorBlockData: BlockTypeChoices.LIST
|
|
19
|
+
EDITOR_JS_BLOCK_DATA_REVERSE_MAP = {
|
|
20
|
+
value: key for key, value in EDITOR_JS_BLOCK_DATA_MAP.items()
|
|
23
21
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from django_spire.knowledge.entry.version.block.data.data import
|
|
3
|
+
from django_spire.knowledge.entry.version.block.data.data import BaseEditorJsBlockData
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class TextEditorBlockData(
|
|
6
|
+
class TextEditorBlockData(BaseEditorJsBlockData):
|
|
7
7
|
text: str
|
|
8
8
|
|
|
9
9
|
def render_to_text(self) -> str:
|
|
@@ -5,8 +5,8 @@ from django.db import models
|
|
|
5
5
|
from django_spire.contrib.ordering.mixins import OrderingModelMixin
|
|
6
6
|
from django_spire.history.mixins import HistoryModelMixin
|
|
7
7
|
from django_spire.knowledge.entry.version.block.choices import BlockTypeChoices
|
|
8
|
-
from django_spire.knowledge.entry.version.block.data.data import
|
|
9
|
-
from django_spire.knowledge.entry.version.block.data.maps import
|
|
8
|
+
from django_spire.knowledge.entry.version.block.data.data import BaseEditorJsBlockData
|
|
9
|
+
from django_spire.knowledge.entry.version.block.data.maps import EDITOR_JS_BLOCK_DATA_MAP
|
|
10
10
|
from django_spire.knowledge.entry.version.block.querysets import \
|
|
11
11
|
EntryVersionBlockQuerySet
|
|
12
12
|
from django_spire.knowledge.entry.version.block.services.service import \
|
|
@@ -40,18 +40,21 @@ class EntryVersionBlock(HistoryModelMixin, OrderingModelMixin):
|
|
|
40
40
|
services = EntryVersionBlockService()
|
|
41
41
|
|
|
42
42
|
@property
|
|
43
|
-
def
|
|
44
|
-
return
|
|
43
|
+
def editor_js_block_data(self) -> BaseEditorJsBlockData:
|
|
44
|
+
return EDITOR_JS_BLOCK_DATA_MAP[self.type](**self._block_data)
|
|
45
45
|
|
|
46
|
-
@
|
|
47
|
-
def
|
|
46
|
+
@editor_js_block_data.setter
|
|
47
|
+
def editor_js_block_data(self, value: BaseEditorJsBlockData):
|
|
48
48
|
# exclude_none=True ensures that block meta objects aren't autofilled with keys,
|
|
49
49
|
# which can mess up editor rendering
|
|
50
50
|
self._block_data = value.model_dump(exclude_none=True)
|
|
51
51
|
self._text_data = value.render_to_text()
|
|
52
52
|
|
|
53
|
+
def update_editor_js_block_data_from_dict(self, value: dict):
|
|
54
|
+
self.editor_js_block_data = EDITOR_JS_BLOCK_DATA_MAP[self.type](**value)
|
|
55
|
+
|
|
53
56
|
def render_to_text(self) -> str:
|
|
54
|
-
return self.
|
|
57
|
+
return self.editor_js_block_data.render_to_text()
|
|
55
58
|
|
|
56
59
|
class Meta:
|
|
57
60
|
verbose_name = 'Block'
|
|
@@ -4,7 +4,7 @@ from django_spire.contrib.service import BaseDjangoModelService
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from django_spire.knowledge.entry.version.block.data.maps import
|
|
7
|
+
from django_spire.knowledge.entry.version.block.data.maps import EDITOR_JS_BLOCK_DATA_MAP
|
|
8
8
|
from django_spire.knowledge.entry.version.maps import FILE_TYPE_CONVERTER_MAP
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
@@ -34,17 +34,18 @@ class EntryVersionBlockFactoryService(BaseDjangoModelService['EntryVersionBlock'
|
|
|
34
34
|
def create_validated_block(
|
|
35
35
|
self,
|
|
36
36
|
entry_version: EntryVersion,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
type: BlockTypeChoices,
|
|
38
|
+
data: dict,
|
|
39
|
+
order: int,
|
|
40
|
+
tunes: dict = {},
|
|
41
|
+
**kwargs,
|
|
41
42
|
):
|
|
42
43
|
self.obj.version = entry_version
|
|
43
|
-
self.obj.type =
|
|
44
|
-
self.obj.order =
|
|
45
|
-
self.obj.tunes =
|
|
46
|
-
self.obj.
|
|
44
|
+
self.obj.type = type
|
|
45
|
+
self.obj.order = order
|
|
46
|
+
self.obj.tunes = tunes
|
|
47
|
+
self.obj.editor_js_block_data = EDITOR_JS_BLOCK_DATA_MAP[type](**data)
|
|
47
48
|
|
|
48
49
|
self.obj.clean()
|
|
49
50
|
|
|
50
|
-
return self.obj
|
|
51
|
+
return self.obj
|
|
@@ -12,10 +12,11 @@ from django_spire.knowledge.entry.version.tests.factories import \
|
|
|
12
12
|
|
|
13
13
|
def create_test_block_form_data(**kwargs) -> dict:
|
|
14
14
|
data = {
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
15
|
+
'id': 'ABC123',
|
|
16
|
+
'order': 0,
|
|
17
|
+
'type': BlockTypeChoices.TEXT,
|
|
18
|
+
'data': {'text': 'test text'},
|
|
19
|
+
'tunes': {}
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
data.update(kwargs)
|
|
@@ -33,7 +34,7 @@ def create_test_version_block(**kwargs) -> EntryVersionBlock:
|
|
|
33
34
|
|
|
34
35
|
data.update(kwargs)
|
|
35
36
|
version_block = EntryVersionBlock.objects.create(**data)
|
|
36
|
-
version_block.
|
|
37
|
+
version_block.editor_js_block_data = TextEditorBlockData(
|
|
37
38
|
text='',
|
|
38
39
|
)
|
|
39
40
|
version_block.save()
|
|
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING
|
|
|
6
6
|
|
|
7
7
|
from markitdown import MarkItDown
|
|
8
8
|
|
|
9
|
-
from django_spire.knowledge.entry.version.
|
|
9
|
+
from django_spire.knowledge.entry.version.consts import MARKDOWN_AI_CHUNK_SIZE
|
|
10
10
|
from django_spire.knowledge.entry.version.converters.converter import \
|
|
11
11
|
BaseConverter
|
|
12
12
|
from django_spire.knowledge.entry.version.block import models
|
|
@@ -3,22 +3,24 @@ from __future__ import annotations
|
|
|
3
3
|
from dandy import BaseIntel, Bot, Prompt, recorder_to_html_file
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class
|
|
7
|
-
|
|
6
|
+
class MarkdownIntel(BaseIntel):
|
|
7
|
+
markdown_content: str
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class MarkdownFormatLlmBot(Bot):
|
|
11
|
-
|
|
11
|
+
llm_role = 'Markdown Formater'
|
|
12
|
+
llm_task = 'Improve the markdown formatting of the content provided to make more logical sense.'
|
|
13
|
+
llm_guidelines = (
|
|
14
|
+
Prompt()
|
|
15
|
+
.list([
|
|
16
|
+
'Make sure the relevant heading text is from a heading with mark down formatting.'
|
|
17
|
+
'Do not change any of the content only change the formatting as needed.'
|
|
18
|
+
])
|
|
19
|
+
)
|
|
20
|
+
llm_intel_class = MarkdownIntel
|
|
12
21
|
|
|
13
22
|
@recorder_to_html_file('knowledge_markdown_improvement')
|
|
14
23
|
def process(self, markdown_content: str) -> str:
|
|
15
|
-
|
|
16
|
-
markdown_prompt.text(
|
|
17
|
-
'Can you improve the markdown formatting? Do NOT add or change any of the '
|
|
18
|
-
'content.'
|
|
19
|
-
)
|
|
20
|
-
markdown_prompt.line_break()
|
|
21
|
-
markdown_prompt.text(markdown_content)
|
|
24
|
+
markdown_intel = self.llm.prompt_to_intel(prompt=markdown_content)
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
return result.text
|
|
26
|
+
return markdown_intel.markdown_content
|
|
@@ -12,7 +12,7 @@ from django_spire.knowledge.entry.version import models
|
|
|
12
12
|
|
|
13
13
|
from django_spire.contrib.seeding import DjangoModelSeeder
|
|
14
14
|
from django_spire.knowledge.entry.version.block.data.maps import \
|
|
15
|
-
|
|
15
|
+
EDITOR_JS_BLOCK_DATA_REVERSE_MAP
|
|
16
16
|
from django_spire.knowledge.entry.version.block.models import EntryVersionBlock
|
|
17
17
|
from django_spire.knowledge.entry.version.block.seeding.constants import SAFETY_BLOCKS
|
|
18
18
|
from django_spire.knowledge.entry.version.choices import EntryVersionStatusChoices
|
|
@@ -63,10 +63,10 @@ class EntryVersionSeeder(DjangoModelSeeder):
|
|
|
63
63
|
for idx, safety_block in enumerate(safety_blocks):
|
|
64
64
|
version_block = EntryVersionBlock(
|
|
65
65
|
version=entry_version,
|
|
66
|
-
type=
|
|
66
|
+
type=EDITOR_JS_BLOCK_DATA_REVERSE_MAP[type(safety_block)],
|
|
67
67
|
order=idx,
|
|
68
68
|
)
|
|
69
|
-
version_block.
|
|
69
|
+
version_block.editor_js_block_data = safety_block
|
|
70
70
|
version_blocks.append(version_block)
|
|
71
71
|
|
|
72
72
|
EntryVersionBlock.objects.bulk_create(version_blocks)
|
|
@@ -20,19 +20,45 @@ class EntryVersionProcessorService(BaseDjangoModelService['EntryVersion']):
|
|
|
20
20
|
self.obj.published_datetime = localtime()
|
|
21
21
|
self.obj.save()
|
|
22
22
|
|
|
23
|
-
def
|
|
23
|
+
def add_update_delete_blocks(self, block_data_list: list[dict]):
|
|
24
24
|
from django_spire.knowledge.entry.version.block.models import EntryVersionBlock
|
|
25
25
|
|
|
26
|
+
entry_blocks_to_add = []
|
|
27
|
+
entry_blocks_to_update = []
|
|
28
|
+
entry_blocks_to_delete = []
|
|
29
|
+
|
|
30
|
+
handled_block_ids = []
|
|
31
|
+
|
|
26
32
|
old_entry_blocks = self.obj.blocks.active()
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
old_entry_block_ids = [entry_block.id for entry_block in old_entry_blocks]
|
|
35
|
+
|
|
36
|
+
for block_data in block_data_list:
|
|
37
|
+
if block_data['id'] in old_entry_block_ids:
|
|
38
|
+
entry_block: EntryVersionBlock = old_entry_blocks.get(id=block_data['id'])
|
|
39
|
+
|
|
40
|
+
entry_block.type = block_data['type']
|
|
41
|
+
entry_block.order = block_data['order']
|
|
42
|
+
entry_block.update_editor_js_block_data_from_dict(block_data['data'])
|
|
43
|
+
|
|
44
|
+
entry_blocks_to_update.append(entry_block)
|
|
45
|
+
|
|
46
|
+
handled_block_ids.append(block_data['id'])
|
|
47
|
+
|
|
48
|
+
else:
|
|
49
|
+
entry_block = EntryVersionBlock.services.factory.create_validated_block(
|
|
50
|
+
entry_version=self.obj,
|
|
51
|
+
**block_data,
|
|
52
|
+
)
|
|
53
|
+
entry_blocks_to_add.append(entry_block)
|
|
54
|
+
|
|
55
|
+
handled_block_ids.append(block_data['id'])
|
|
56
|
+
|
|
57
|
+
for entry_block in old_entry_blocks:
|
|
58
|
+
if entry_block.id not in handled_block_ids:
|
|
59
|
+
entry_blocks_to_delete.append(entry_block.id)
|
|
35
60
|
|
|
36
61
|
with transaction.atomic():
|
|
37
|
-
|
|
38
|
-
EntryVersionBlock.objects.
|
|
62
|
+
EntryVersionBlock.objects.filter(id__in=entry_blocks_to_delete).delete()
|
|
63
|
+
EntryVersionBlock.objects.bulk_update(entry_blocks_to_update, ['order', 'type', '_block_data', '_text_data'])
|
|
64
|
+
EntryVersionBlock.objects.bulk_create(entry_blocks_to_add)
|
|
@@ -5,7 +5,7 @@ import time
|
|
|
5
5
|
from unittest.mock import MagicMock, patch
|
|
6
6
|
|
|
7
7
|
from django_spire.core.tests.test_cases import BaseTestCase
|
|
8
|
-
from django_spire.knowledge.entry.version.
|
|
8
|
+
from django_spire.knowledge.entry.version.consts import MARKDOWN_AI_CHUNK_SIZE
|
|
9
9
|
from django_spire.knowledge.entry.version.converters.docx_converter import DocxConverter
|
|
10
10
|
|
|
11
11
|
from django_spire.knowledge.entry.version.tests.factories import \
|
|
@@ -22,7 +22,7 @@ class EntryVersionPageUrlsTests(BaseTestCase):
|
|
|
22
22
|
def test_detail_view_url_path(self):
|
|
23
23
|
response = self.client.get(
|
|
24
24
|
reverse(
|
|
25
|
-
'django_spire:knowledge:entry:version:page:
|
|
25
|
+
'django_spire:knowledge:entry:version:page:editor',
|
|
26
26
|
kwargs={'pk': self.test_entry_version.pk}
|
|
27
27
|
)
|
|
28
28
|
)
|
|
@@ -15,7 +15,9 @@ from django_spire.knowledge.entry.version.models import EntryVersion
|
|
|
15
15
|
@AppAuthController('knowledge').permission_required('can_change')
|
|
16
16
|
def update_blocks_view(request: WSGIRequest, pk: int) -> JsonResponse:
|
|
17
17
|
entry_version = get_object_or_404(EntryVersion.objects.prefetch_blocks(), pk=pk)
|
|
18
|
-
new_block_data = json.loads(request.body.decode('utf-8'))
|
|
19
|
-
entry_version.services.processor.update_blocks(new_block_data)
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
block_data_list = json.loads(request.body.decode('utf-8'))
|
|
20
|
+
|
|
21
|
+
entry_version.services.processor.add_update_delete_blocks(block_data_list)
|
|
22
|
+
|
|
23
|
+
return JsonResponse({'type': 'success'})
|
|
@@ -3,22 +3,22 @@ from __future__ import annotations
|
|
|
3
3
|
import json
|
|
4
4
|
|
|
5
5
|
from django.core.handlers.wsgi import WSGIRequest
|
|
6
|
-
from django.db.models import F, Prefetch
|
|
7
6
|
from django.shortcuts import get_object_or_404
|
|
8
7
|
from django.template.response import TemplateResponse
|
|
9
8
|
from django.urls import reverse
|
|
10
9
|
|
|
11
10
|
from django_spire.auth.controller.controller import AppAuthController
|
|
12
11
|
from django_spire.contrib.generic_views import portal_views
|
|
13
|
-
from django_spire.knowledge.
|
|
12
|
+
from django_spire.knowledge.collection.models import Collection
|
|
14
13
|
from django_spire.knowledge.entry.version.models import EntryVersion
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
@AppAuthController('knowledge').permission_required('can_view')
|
|
18
|
-
def
|
|
17
|
+
def editor_view(request: WSGIRequest, pk: int) -> TemplateResponse:
|
|
19
18
|
entry_version = get_object_or_404(EntryVersion.objects.prefetch_blocks(),pk=pk)
|
|
20
19
|
|
|
21
20
|
entry = entry_version.entry
|
|
21
|
+
top_level_collection = entry.top_level_collection
|
|
22
22
|
version_blocks = entry_version.blocks.format_for_editor()
|
|
23
23
|
|
|
24
24
|
def breadcrumbs_func(breadcrumbs):
|
|
@@ -26,13 +26,7 @@ def detail_view(request: WSGIRequest, pk: int) -> TemplateResponse:
|
|
|
26
26
|
name='Knowledge',
|
|
27
27
|
href=reverse('django_spire:knowledge:page:home')
|
|
28
28
|
)
|
|
29
|
-
|
|
30
|
-
breadcrumbs.add_breadcrumb(
|
|
31
|
-
name=f'{collection.name}'
|
|
32
|
-
)
|
|
33
|
-
breadcrumbs.add_breadcrumb(
|
|
34
|
-
name=f'{entry.name}',
|
|
35
|
-
)
|
|
29
|
+
breadcrumbs.add_base_breadcrumb(entry)
|
|
36
30
|
|
|
37
31
|
return portal_views.detail_view(
|
|
38
32
|
request,
|
|
@@ -40,8 +34,13 @@ def detail_view(request: WSGIRequest, pk: int) -> TemplateResponse:
|
|
|
40
34
|
breadcrumbs_func=breadcrumbs_func,
|
|
41
35
|
context_data={
|
|
42
36
|
'entry': entry,
|
|
43
|
-
'
|
|
37
|
+
'current_version': entry_version,
|
|
38
|
+
'collection': top_level_collection,
|
|
44
39
|
'version_blocks': json.dumps(list(version_blocks)),
|
|
40
|
+
'collection_tree_json': Collection.services.transformation.to_hierarchy_json(
|
|
41
|
+
request=request,
|
|
42
|
+
parent_id=top_level_collection.id,
|
|
43
|
+
),
|
|
45
44
|
},
|
|
46
|
-
template='django_spire/knowledge/entry/version/page/
|
|
45
|
+
template='django_spire/knowledge/entry/version/page/editor_page.html',
|
|
47
46
|
)
|
|
@@ -16,7 +16,7 @@ def publish_view(request: WSGIRequest, pk: int) -> HttpResponseRedirect:
|
|
|
16
16
|
|
|
17
17
|
return HttpResponseRedirect(
|
|
18
18
|
reverse(
|
|
19
|
-
'django_spire:knowledge:entry:version:page:
|
|
19
|
+
'django_spire:knowledge:entry:version:page:editor',
|
|
20
20
|
kwargs={'pk': version.pk}
|
|
21
21
|
)
|
|
22
22
|
)
|
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dandy import Bot, Prompt
|
|
4
|
-
from dandy.intel.intel import DefaultIntel
|
|
5
4
|
|
|
6
5
|
from django_spire.knowledge.entry.models import Entry
|
|
6
|
+
from django_spire.knowledge.intelligence.intel.collection_intel import CollectionIntel
|
|
7
|
+
from django_spire.knowledge.intelligence.intel.entry_intel import EntryIntel
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
class
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
class EntrySearchBot(Bot):
|
|
11
|
+
llm_role = 'Knowledge Entry Search Assistant'
|
|
12
|
+
llm_task = 'Read through the knowledge entry the information request and return information and the block id that relevant'
|
|
13
|
+
llm_guidelines = (
|
|
14
|
+
Prompt()
|
|
15
|
+
.list([
|
|
16
|
+
'Make sure the relevant heading text is from a heading with mark down formatting.'
|
|
17
|
+
'When returning the relevant heading remove any of the markdown formating characters.'
|
|
18
|
+
])
|
|
19
|
+
)
|
|
20
|
+
llm_intel_class = EntryIntel
|
|
21
|
+
|
|
22
|
+
def process(self, user_input: str, entry: Entry) -> EntryIntel:
|
|
12
23
|
entry_prompt = Prompt()
|
|
13
|
-
entry_prompt.
|
|
14
|
-
entry_prompt.
|
|
15
|
-
entry_prompt.text(f'
|
|
24
|
+
entry_prompt.sub_heading('Information Request')
|
|
25
|
+
entry_prompt.line_break()
|
|
26
|
+
entry_prompt.text(f'{user_input}')
|
|
27
|
+
entry_prompt.line_break()
|
|
28
|
+
entry_prompt.sub_heading(f'Knowledge Entry: {entry.name}')
|
|
29
|
+
entry_prompt.line_break()
|
|
16
30
|
|
|
17
31
|
for version_block in entry.current_version.blocks.all():
|
|
18
|
-
entry_prompt.text(version_block.render_to_text())
|
|
32
|
+
entry_prompt.text(f'{version_block.id}: {version_block.render_to_text()}')
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
entry_intel = self.llm.prompt_to_intel(
|
|
21
35
|
prompt=entry_prompt,
|
|
22
|
-
|
|
23
|
-
)
|
|
36
|
+
exclude_fields={'entry_id', 'collection_intel'},
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
entry_intel.entry_id = entry.id
|
|
40
|
+
entry_intel.collection_intel = CollectionIntel(
|
|
41
|
+
name=entry.collection.name,
|
|
42
|
+
collection_id=entry.collection.id,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
return entry_intel
|
|
File without changes
|
django_spire/knowledge/intelligence/{maps/collection_map.py → decoders/collection_decoder.py}
RENAMED
|
@@ -5,15 +5,15 @@ from dandy import Decoder
|
|
|
5
5
|
from django_spire.knowledge.collection.models import Collection
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def
|
|
9
|
-
class
|
|
8
|
+
def get_collection_decoder() -> Decoder:
|
|
9
|
+
class CollectionDecoder(Decoder):
|
|
10
10
|
mapping_keys_description = 'Knowledge Collection Titles'
|
|
11
11
|
mapping = {
|
|
12
12
|
**{
|
|
13
|
-
collection.name: collection
|
|
13
|
+
f'{collection.name}: {collection.description}': collection
|
|
14
14
|
for collection in Collection.objects.all().annotate_entry_count()
|
|
15
15
|
},
|
|
16
|
-
'No Matching Knowledge Collection Titles': None
|
|
16
|
+
'No Matching Knowledge Collection Titles': None,
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
return
|
|
19
|
+
return CollectionDecoder()
|
|
@@ -5,8 +5,8 @@ from dandy import Decoder
|
|
|
5
5
|
from django_spire.knowledge.collection.models import Collection
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def
|
|
9
|
-
class
|
|
8
|
+
def get_entry_decoder(collection: Collection) -> Decoder:
|
|
9
|
+
class EntryDecoder(Decoder):
|
|
10
10
|
mapping_keys_description = 'Knowledge Entries'
|
|
11
11
|
mapping = {
|
|
12
12
|
**{
|
|
@@ -16,4 +16,4 @@ def get_entry_map_class(collection: Collection) -> type[Decoder]:
|
|
|
16
16
|
'No Matching Knowledge Entries': None
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
return
|
|
19
|
+
return EntryDecoder()
|
|
@@ -6,8 +6,11 @@ from django_spire.knowledge.intelligence.intel.collection_intel import Collectio
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class EntryIntel(BaseIntel):
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
relevant_heading_text: str
|
|
10
|
+
relevant_subject_text: str
|
|
11
|
+
relevant_block_id: int
|
|
12
|
+
entry_id: int = None
|
|
13
|
+
collection_intel: CollectionIntel = None
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
class EntriesIntel(BaseListIntel[EntryIntel]):
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from django_spire.ai.chat.message_intel import BaseMessageIntel
|
|
4
|
+
from django_spire.knowledge.intelligence.intel.entry_intel import EntriesIntel
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class KnowledgeMessageIntel(BaseMessageIntel):
|
|
7
8
|
_template: str = 'django_spire/knowledge/message/knowledge_message_intel.html'
|
|
8
9
|
body: str
|
|
10
|
+
entries_intel: EntriesIntel
|
|
9
11
|
|
|
10
12
|
def content_to_str(self) -> str:
|
|
11
13
|
return self.body
|