naas-abi-core 1.4.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.
Files changed (124) hide show
  1. assets/favicon.ico +0 -0
  2. assets/logo.png +0 -0
  3. naas_abi_core/__init__.py +1 -0
  4. naas_abi_core/apps/api/api.py +245 -0
  5. naas_abi_core/apps/api/api_test.py +281 -0
  6. naas_abi_core/apps/api/openapi_doc.py +144 -0
  7. naas_abi_core/apps/mcp/Dockerfile.mcp +35 -0
  8. naas_abi_core/apps/mcp/mcp_server.py +243 -0
  9. naas_abi_core/apps/mcp/mcp_server_test.py +163 -0
  10. naas_abi_core/apps/terminal_agent/main.py +555 -0
  11. naas_abi_core/apps/terminal_agent/terminal_style.py +175 -0
  12. naas_abi_core/engine/Engine.py +87 -0
  13. naas_abi_core/engine/EngineProxy.py +109 -0
  14. naas_abi_core/engine/Engine_test.py +6 -0
  15. naas_abi_core/engine/IEngine.py +91 -0
  16. naas_abi_core/engine/conftest.py +45 -0
  17. naas_abi_core/engine/engine_configuration/EngineConfiguration.py +216 -0
  18. naas_abi_core/engine/engine_configuration/EngineConfiguration_Deploy.py +7 -0
  19. naas_abi_core/engine/engine_configuration/EngineConfiguration_GenericLoader.py +49 -0
  20. naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService.py +159 -0
  21. naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService_test.py +26 -0
  22. naas_abi_core/engine/engine_configuration/EngineConfiguration_SecretService.py +138 -0
  23. naas_abi_core/engine/engine_configuration/EngineConfiguration_SecretService_test.py +74 -0
  24. naas_abi_core/engine/engine_configuration/EngineConfiguration_TripleStoreService.py +224 -0
  25. naas_abi_core/engine/engine_configuration/EngineConfiguration_TripleStoreService_test.py +109 -0
  26. naas_abi_core/engine/engine_configuration/EngineConfiguration_VectorStoreService.py +76 -0
  27. naas_abi_core/engine/engine_configuration/EngineConfiguration_VectorStoreService_test.py +33 -0
  28. naas_abi_core/engine/engine_configuration/EngineConfiguration_test.py +9 -0
  29. naas_abi_core/engine/engine_configuration/utils/PydanticModelValidator.py +15 -0
  30. naas_abi_core/engine/engine_loaders/EngineModuleLoader.py +302 -0
  31. naas_abi_core/engine/engine_loaders/EngineOntologyLoader.py +16 -0
  32. naas_abi_core/engine/engine_loaders/EngineServiceLoader.py +47 -0
  33. naas_abi_core/integration/__init__.py +7 -0
  34. naas_abi_core/integration/integration.py +28 -0
  35. naas_abi_core/models/Model.py +198 -0
  36. naas_abi_core/models/OpenRouter.py +18 -0
  37. naas_abi_core/models/OpenRouter_test.py +36 -0
  38. naas_abi_core/module/Module.py +252 -0
  39. naas_abi_core/module/ModuleAgentLoader.py +50 -0
  40. naas_abi_core/module/ModuleUtils.py +20 -0
  41. naas_abi_core/modules/templatablesparqlquery/README.md +196 -0
  42. naas_abi_core/modules/templatablesparqlquery/__init__.py +39 -0
  43. naas_abi_core/modules/templatablesparqlquery/ontologies/TemplatableSparqlQueryOntology.ttl +116 -0
  44. naas_abi_core/modules/templatablesparqlquery/workflows/GenericWorkflow.py +48 -0
  45. naas_abi_core/modules/templatablesparqlquery/workflows/TemplatableSparqlQueryLoader.py +192 -0
  46. naas_abi_core/pipeline/__init__.py +6 -0
  47. naas_abi_core/pipeline/pipeline.py +70 -0
  48. naas_abi_core/services/__init__.py +0 -0
  49. naas_abi_core/services/agent/Agent.py +1619 -0
  50. naas_abi_core/services/agent/AgentMemory_test.py +28 -0
  51. naas_abi_core/services/agent/Agent_test.py +214 -0
  52. naas_abi_core/services/agent/IntentAgent.py +1179 -0
  53. naas_abi_core/services/agent/IntentAgent_test.py +139 -0
  54. naas_abi_core/services/agent/beta/Embeddings.py +181 -0
  55. naas_abi_core/services/agent/beta/IntentMapper.py +120 -0
  56. naas_abi_core/services/agent/beta/LocalModel.py +88 -0
  57. naas_abi_core/services/agent/beta/VectorStore.py +89 -0
  58. naas_abi_core/services/agent/test_agent_memory.py +278 -0
  59. naas_abi_core/services/agent/test_postgres_integration.py +145 -0
  60. naas_abi_core/services/cache/CacheFactory.py +31 -0
  61. naas_abi_core/services/cache/CachePort.py +63 -0
  62. naas_abi_core/services/cache/CacheService.py +246 -0
  63. naas_abi_core/services/cache/CacheService_test.py +85 -0
  64. naas_abi_core/services/cache/adapters/secondary/CacheFSAdapter.py +39 -0
  65. naas_abi_core/services/object_storage/ObjectStorageFactory.py +57 -0
  66. naas_abi_core/services/object_storage/ObjectStoragePort.py +47 -0
  67. naas_abi_core/services/object_storage/ObjectStorageService.py +41 -0
  68. naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterFS.py +52 -0
  69. naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterNaas.py +131 -0
  70. naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterS3.py +171 -0
  71. naas_abi_core/services/ontology/OntologyPorts.py +36 -0
  72. naas_abi_core/services/ontology/OntologyService.py +17 -0
  73. naas_abi_core/services/ontology/adaptors/secondary/OntologyService_SecondaryAdaptor_NERPort.py +37 -0
  74. naas_abi_core/services/secret/Secret.py +138 -0
  75. naas_abi_core/services/secret/SecretPorts.py +45 -0
  76. naas_abi_core/services/secret/Secret_test.py +65 -0
  77. naas_abi_core/services/secret/adaptors/secondary/Base64Secret.py +57 -0
  78. naas_abi_core/services/secret/adaptors/secondary/Base64Secret_test.py +39 -0
  79. naas_abi_core/services/secret/adaptors/secondary/NaasSecret.py +88 -0
  80. naas_abi_core/services/secret/adaptors/secondary/NaasSecret_test.py +25 -0
  81. naas_abi_core/services/secret/adaptors/secondary/dotenv_secret_secondaryadaptor.py +29 -0
  82. naas_abi_core/services/triple_store/TripleStoreFactory.py +116 -0
  83. naas_abi_core/services/triple_store/TripleStorePorts.py +223 -0
  84. naas_abi_core/services/triple_store/TripleStoreService.py +419 -0
  85. naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune.py +1300 -0
  86. naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune_test.py +284 -0
  87. naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph.py +597 -0
  88. naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph_test.py +1474 -0
  89. naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__Filesystem.py +223 -0
  90. naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__ObjectStorage.py +234 -0
  91. naas_abi_core/services/triple_store/adaptors/secondary/base/TripleStoreService__SecondaryAdaptor__FileBase.py +18 -0
  92. naas_abi_core/services/vector_store/IVectorStorePort.py +101 -0
  93. naas_abi_core/services/vector_store/IVectorStorePort_test.py +189 -0
  94. naas_abi_core/services/vector_store/VectorStoreFactory.py +47 -0
  95. naas_abi_core/services/vector_store/VectorStoreService.py +171 -0
  96. naas_abi_core/services/vector_store/VectorStoreService_test.py +185 -0
  97. naas_abi_core/services/vector_store/__init__.py +13 -0
  98. naas_abi_core/services/vector_store/adapters/QdrantAdapter.py +251 -0
  99. naas_abi_core/services/vector_store/adapters/QdrantAdapter_test.py +57 -0
  100. naas_abi_core/tests/test_services_imports.py +69 -0
  101. naas_abi_core/utils/Expose.py +55 -0
  102. naas_abi_core/utils/Graph.py +182 -0
  103. naas_abi_core/utils/JSON.py +49 -0
  104. naas_abi_core/utils/LazyLoader.py +44 -0
  105. naas_abi_core/utils/Logger.py +12 -0
  106. naas_abi_core/utils/OntologyReasoner.py +141 -0
  107. naas_abi_core/utils/OntologyYaml.py +681 -0
  108. naas_abi_core/utils/SPARQL.py +256 -0
  109. naas_abi_core/utils/Storage.py +33 -0
  110. naas_abi_core/utils/StorageUtils.py +398 -0
  111. naas_abi_core/utils/String.py +52 -0
  112. naas_abi_core/utils/Workers.py +114 -0
  113. naas_abi_core/utils/__init__.py +0 -0
  114. naas_abi_core/utils/onto2py/README.md +0 -0
  115. naas_abi_core/utils/onto2py/__init__.py +10 -0
  116. naas_abi_core/utils/onto2py/__main__.py +29 -0
  117. naas_abi_core/utils/onto2py/onto2py.py +611 -0
  118. naas_abi_core/utils/onto2py/tests/ttl2py_test.py +271 -0
  119. naas_abi_core/workflow/__init__.py +5 -0
  120. naas_abi_core/workflow/workflow.py +48 -0
  121. naas_abi_core-1.4.1.dist-info/METADATA +630 -0
  122. naas_abi_core-1.4.1.dist-info/RECORD +124 -0
  123. naas_abi_core-1.4.1.dist-info/WHEEL +4 -0
  124. naas_abi_core-1.4.1.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,224 @@
1
+ from typing import TYPE_CHECKING, Literal, Union
2
+
3
+ from naas_abi_core.engine.engine_configuration.EngineConfiguration_GenericLoader import (
4
+ GenericLoader,
5
+ )
6
+ from naas_abi_core.engine.engine_configuration.EngineConfiguration_ObjectStorageService import (
7
+ ObjectStorageServiceConfiguration,
8
+ )
9
+ from naas_abi_core.engine.engine_configuration.utils.PydanticModelValidator import (
10
+ pydantic_model_validator,
11
+ )
12
+ from naas_abi_core.services.triple_store.TripleStorePorts import ITripleStorePort
13
+ from naas_abi_core.services.triple_store.TripleStoreService import TripleStoreService
14
+ from pydantic import BaseModel, model_validator
15
+ from typing_extensions import Self
16
+
17
+ # Only import for type checking, not at runtime
18
+ if TYPE_CHECKING:
19
+ pass
20
+
21
+
22
+ class OxigraphAdapterConfiguration(BaseModel):
23
+ """Oxigraph adapter configuration.
24
+
25
+ triple_store_adapter:
26
+ adapter: "oxigraph"
27
+ config:
28
+ oxigraph_url: "http://localhost:7878"
29
+ timeout: 60
30
+ """
31
+
32
+ oxigraph_url: str = "http://localhost:7878"
33
+ timeout: int = 60
34
+
35
+
36
+ class AWSNeptuneAdapterConfiguration(BaseModel):
37
+ """AWS Neptune adapter configuration.
38
+
39
+ triple_store_adapter:
40
+ adapter: "aws_neptune"
41
+ config:
42
+ aws_region_name: "{{ secret.AWS_REGION }}"
43
+ aws_access_key_id: "{{ secret.AWS_ACCESS_KEY_ID }}"
44
+ aws_secret_access_key: "{{ secret.AWS_SECRET_ACCESS_KEY }}"
45
+ db_instance_identifier: "{{ secret.AWS_NEPTUNE_DB_INSTANCE_IDENTIFIER }}"
46
+ """
47
+
48
+ aws_region_name: str
49
+ aws_access_key_id: str
50
+ aws_secret_access_key: str
51
+ db_instance_identifier: str
52
+
53
+
54
+ class AWSNeptuneSSHTunnelAdapterConfiguration(AWSNeptuneAdapterConfiguration):
55
+ """AWS Neptune SSH tunnel adapter configuration.
56
+
57
+ triple_store_adapter:
58
+ adapter: "aws_neptune_sshtunnel"
59
+ config:
60
+ aws_region_name: "{{ secret.AWS_REGION }}"
61
+ aws_access_key_id: "{{ secret.AWS_ACCESS_KEY_ID }}"
62
+ aws_secret_access_key: "{{ secret.AWS_SECRET_ACCESS_KEY }}"
63
+ db_instance_identifier: "{{ secret.AWS_NEPTUNE_DB_INSTANCE_IDENTIFIER }}"
64
+ bastion_host: "{{ secret.AWS_BASTION_HOST }}"
65
+ bastion_port: "{{ secret.AWS_BASTION_PORT }}"
66
+ bastion_user: "{{ secret.AWS_BASTION_USER }}"
67
+ bastion_private_key: "{{ secret.AWS_BASTION_PRIVATE_KEY }}"
68
+ """
69
+
70
+ bastion_host: str
71
+ bastion_port: int
72
+ bastion_user: str
73
+ bastion_private_key: str
74
+
75
+
76
+ class TripleStoreAdapterFilesystemConfiguration(BaseModel):
77
+ """Filesystem adapter configuration.
78
+
79
+ triple_store_adapter:
80
+ adapter: "fs"
81
+ config:
82
+ store_path: "storage/triplestore"
83
+ triples_path: "triples"
84
+ """
85
+
86
+ store_path: str
87
+ triples_path: str = "triples"
88
+
89
+
90
+ class TripleStoreAdapterObjectStorageConfiguration(BaseModel):
91
+ """Object storage adapter configuration.
92
+
93
+ triple_store_adapter:
94
+ adapter: "object_storage"
95
+ config:
96
+ object_storage_service: *object_storage_service
97
+ triples_prefix: "triples"
98
+ """
99
+
100
+ object_storage_service: ObjectStorageServiceConfiguration
101
+ triples_prefix: str = "triples"
102
+
103
+
104
+ class TripleStoreAdapterConfiguration(GenericLoader):
105
+ adapter: Literal[
106
+ "oxigraph",
107
+ "aws_neptune_sshtunnel",
108
+ "aws_neptune",
109
+ "fs",
110
+ "object_storage",
111
+ "custom",
112
+ ]
113
+ config: (
114
+ Union[
115
+ OxigraphAdapterConfiguration,
116
+ AWSNeptuneAdapterConfiguration,
117
+ AWSNeptuneSSHTunnelAdapterConfiguration,
118
+ TripleStoreAdapterFilesystemConfiguration,
119
+ TripleStoreAdapterObjectStorageConfiguration,
120
+ dict,
121
+ ]
122
+ | None
123
+ ) = None
124
+
125
+ @model_validator(mode="after")
126
+ def validate_adapter(self) -> Self:
127
+ if self.adapter != "custom":
128
+ assert self.config is not None, (
129
+ "config is required if adapter is not custom"
130
+ )
131
+
132
+ if self.adapter == "fs":
133
+ pydantic_model_validator(
134
+ TripleStoreAdapterFilesystemConfiguration,
135
+ self.config,
136
+ "Invalid configuration for services.triple_store.triple_store_adapter 'fs' adapter",
137
+ )
138
+ if self.adapter == "object_storage":
139
+ pydantic_model_validator(
140
+ TripleStoreAdapterObjectStorageConfiguration,
141
+ self.config,
142
+ "Invalid configuration for services.triple_store.triple_store_adapter 'object_storage' adapter",
143
+ )
144
+ if self.adapter == "oxigraph":
145
+ pydantic_model_validator(
146
+ OxigraphAdapterConfiguration,
147
+ self.config,
148
+ "Invalid configuration for services.triple_store.triple_store_adapter 'oxigraph' adapter",
149
+ )
150
+ if self.adapter == "aws_neptune":
151
+ pydantic_model_validator(
152
+ AWSNeptuneAdapterConfiguration,
153
+ self.config,
154
+ "Invalid configuration for services.triple_store.triple_store_adapter 'aws_neptune' adapter",
155
+ )
156
+ if self.adapter == "aws_neptune_sshtunnel":
157
+ pydantic_model_validator(
158
+ AWSNeptuneSSHTunnelAdapterConfiguration,
159
+ self.config,
160
+ "Invalid configuration for services.triple_store.triple_store_adapter 'aws_neptune_sshtunnel' adapter",
161
+ )
162
+
163
+ return self
164
+
165
+ def load(self) -> ITripleStorePort:
166
+ if self.adapter != "custom":
167
+ assert self.config is not None, "config is required"
168
+
169
+ arguments = (
170
+ self.config.model_dump()
171
+ if not isinstance(self.config, dict)
172
+ else self.config
173
+ )
174
+
175
+ # Lazy import: only import the adapter that's actually configured
176
+ if self.adapter == "oxigraph":
177
+ from naas_abi_core.services.triple_store.adaptors.secondary.Oxigraph import (
178
+ Oxigraph,
179
+ )
180
+
181
+ OxigraphAdapterConfiguration.model_validate(arguments)
182
+
183
+ return Oxigraph(**arguments)
184
+ elif self.adapter == "aws_neptune":
185
+ from naas_abi_core.services.triple_store.adaptors.secondary.AWSNeptune import (
186
+ AWSNeptune,
187
+ )
188
+
189
+ AWSNeptuneAdapterConfiguration.model_validate(arguments)
190
+
191
+ return AWSNeptune(**arguments)
192
+ elif self.adapter == "aws_neptune_sshtunnel":
193
+ from naas_abi_core.services.triple_store.adaptors.secondary.AWSNeptune import (
194
+ AWSNeptuneSSHTunnel,
195
+ )
196
+
197
+ AWSNeptuneSSHTunnelAdapterConfiguration.model_validate(arguments)
198
+
199
+ return AWSNeptuneSSHTunnel(**arguments)
200
+ elif self.adapter == "fs":
201
+ from naas_abi_core.services.triple_store.adaptors.secondary.TripleStoreService__SecondaryAdaptor__Filesystem import (
202
+ TripleStoreService__SecondaryAdaptor__Filesystem,
203
+ )
204
+
205
+ TripleStoreAdapterFilesystemConfiguration.model_validate(arguments)
206
+
207
+ return TripleStoreService__SecondaryAdaptor__Filesystem(**arguments)
208
+ elif self.adapter == "object_storage":
209
+ from naas_abi_core.services.triple_store.adaptors.secondary.TripleStoreService__SecondaryAdaptor__ObjectStorage import (
210
+ TripleStoreService__SecondaryAdaptor__ObjectStorage,
211
+ )
212
+
213
+ return TripleStoreService__SecondaryAdaptor__ObjectStorage(**arguments)
214
+ else:
215
+ raise ValueError(f"Adapter {self.adapter} not supported")
216
+ else:
217
+ return super().load()
218
+
219
+
220
+ class TripleStoreServiceConfiguration(BaseModel):
221
+ triple_store_adapter: TripleStoreAdapterConfiguration
222
+
223
+ def load(self) -> TripleStoreService:
224
+ return TripleStoreService(triple_store_adapter=self.triple_store_adapter.load())
@@ -0,0 +1,109 @@
1
+ from naas_abi_core.engine.engine_configuration.EngineConfiguration_TripleStoreService import (
2
+ AWSNeptuneSSHTunnelAdapterConfiguration,
3
+ OxigraphAdapterConfiguration,
4
+ TripleStoreAdapterConfiguration,
5
+ TripleStoreAdapterFilesystemConfiguration,
6
+ TripleStoreServiceConfiguration,
7
+ )
8
+ from naas_abi_core.services.triple_store.TripleStorePorts import ITripleStorePort
9
+ from naas_abi_core.services.triple_store.TripleStoreService import TripleStoreService
10
+
11
+
12
+ def test_triple_store_service_configuration():
13
+ from naas_abi_core.services.triple_store.adaptors.secondary.TripleStoreService__SecondaryAdaptor__Filesystem import (
14
+ TripleStoreService__SecondaryAdaptor__Filesystem,
15
+ )
16
+
17
+ configuration = TripleStoreServiceConfiguration(
18
+ triple_store_adapter=TripleStoreAdapterConfiguration(
19
+ adapter="fs",
20
+ config=TripleStoreAdapterFilesystemConfiguration(
21
+ store_path="storage/triplestore/test", triples_path="triples"
22
+ ),
23
+ )
24
+ )
25
+ assert configuration.triple_store_adapter is not None
26
+
27
+ triple_store_adapter = configuration.triple_store_adapter.load()
28
+
29
+ assert triple_store_adapter is not None
30
+ assert isinstance(triple_store_adapter, ITripleStorePort)
31
+ assert isinstance(
32
+ triple_store_adapter, TripleStoreService__SecondaryAdaptor__Filesystem
33
+ )
34
+
35
+ triple_store_service = configuration.load()
36
+
37
+ assert triple_store_service is not None
38
+ assert isinstance(triple_store_service, TripleStoreService)
39
+
40
+
41
+ def test_triple_store_service_configuration_naas():
42
+ from naas_abi_core.services.triple_store.adaptors.secondary.Oxigraph import (
43
+ Oxigraph,
44
+ )
45
+
46
+ configuration = TripleStoreServiceConfiguration(
47
+ triple_store_adapter=TripleStoreAdapterConfiguration(
48
+ adapter="oxigraph",
49
+ config=OxigraphAdapterConfiguration(
50
+ oxigraph_url="http://localhost:7878",
51
+ timeout=120,
52
+ ),
53
+ )
54
+ )
55
+ assert configuration.triple_store_adapter is not None
56
+
57
+ triple_store_adapter = configuration.triple_store_adapter.load()
58
+
59
+ assert triple_store_adapter is not None
60
+ assert isinstance(triple_store_adapter, ITripleStorePort)
61
+ assert isinstance(triple_store_adapter, Oxigraph)
62
+
63
+ triple_store_service = configuration.load()
64
+
65
+ assert triple_store_service is not None
66
+ assert isinstance(triple_store_service, TripleStoreService)
67
+
68
+
69
+ def test_triple_store_service_configuration_aws_neptune_sshtunnel():
70
+ import os
71
+
72
+ from dotenv import load_dotenv
73
+
74
+ load_dotenv()
75
+
76
+ from naas_abi_core.services.triple_store.adaptors.secondary.AWSNeptune import (
77
+ AWSNeptuneSSHTunnel,
78
+ )
79
+
80
+ configuration = TripleStoreServiceConfiguration(
81
+ triple_store_adapter=TripleStoreAdapterConfiguration(
82
+ adapter="aws_neptune_sshtunnel",
83
+ config=AWSNeptuneSSHTunnelAdapterConfiguration(
84
+ aws_region_name=os.environ.get("AWS_REGION"),
85
+ aws_access_key_id=os.environ.get("AWS_ACCESS_KEY_ID"),
86
+ aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY"),
87
+ db_instance_identifier=os.environ.get(
88
+ "AWS_NEPTUNE_DB_INSTANCE_IDENTIFIER"
89
+ ),
90
+ bastion_host=os.environ.get("AWS_BASTION_HOST"),
91
+ bastion_port=int(os.environ.get("AWS_BASTION_PORT")),
92
+ bastion_user=os.environ.get("AWS_BASTION_USER"),
93
+ bastion_private_key=os.environ.get("AWS_BASTION_PRIVATE_KEY"),
94
+ ),
95
+ ),
96
+ )
97
+
98
+ assert configuration.triple_store_adapter is not None
99
+
100
+ triple_store_adapter = configuration.triple_store_adapter.load()
101
+
102
+ assert triple_store_adapter is not None
103
+ assert isinstance(triple_store_adapter, ITripleStorePort)
104
+ assert isinstance(triple_store_adapter, AWSNeptuneSSHTunnel)
105
+
106
+ triple_store_service = configuration.load()
107
+
108
+ assert triple_store_service is not None
109
+ assert isinstance(triple_store_service, TripleStoreService)
@@ -0,0 +1,76 @@
1
+ from typing import Literal
2
+
3
+ from naas_abi_core.engine.engine_configuration.EngineConfiguration_GenericLoader import (
4
+ GenericLoader,
5
+ )
6
+ from naas_abi_core.engine.engine_configuration.utils.PydanticModelValidator import (
7
+ pydantic_model_validator,
8
+ )
9
+ from naas_abi_core.services.vector_store.IVectorStorePort import IVectorStorePort
10
+ from naas_abi_core.services.vector_store.VectorStoreService import VectorStoreService
11
+ from pydantic import BaseModel, model_validator
12
+
13
+
14
+ class VectorStoreAdapterQdrantConfiguration(BaseModel):
15
+ """Qdrant vector store adapter configuration.
16
+
17
+ vector_store_adapter:
18
+ adapter: "qdrant"
19
+ config:
20
+ host: "{{ secret.QDRANT_HOST }}"
21
+ port: "{{ secret.QDRANT_PORT }}"
22
+ api_key: "{{ secret.QDRANT_API_KEY }}"
23
+ https: "{{ secret.QDRANT_HTTPS }}"
24
+ timeout: "{{ secret.QDRANT_TIMEOUT }}"
25
+ """
26
+ host: str = "localhost"
27
+ port: int = 6333
28
+ api_key: str | None = None
29
+ https: bool = False
30
+ timeout: int = 30
31
+
32
+
33
+ class VectorStoreAdapterConfiguration(GenericLoader):
34
+ adapter: Literal["qdrant", "custom"]
35
+ config: dict | None = None
36
+
37
+ @model_validator(mode="after")
38
+ def validate_adapter(self) -> "VectorStoreAdapterConfiguration":
39
+ if self.adapter != "custom":
40
+ assert self.config is not None, (
41
+ "config is required if adapter is not custom"
42
+ )
43
+
44
+ if self.adapter == "qdrant":
45
+ pydantic_model_validator(
46
+ VectorStoreAdapterQdrantConfiguration,
47
+ self.config,
48
+ "Invalid configuration for services.vector_store.vector_store_adapter 'qdrant' adapter",
49
+ )
50
+
51
+ return self
52
+
53
+ def load(self) -> IVectorStorePort:
54
+ if self.adapter != "custom":
55
+ assert self.config is not None, (
56
+ "config is required if adapter is not custom"
57
+ )
58
+
59
+ # Lazy import: only import when actually loading
60
+ if self.adapter == "qdrant":
61
+ from naas_abi_core.services.vector_store.adapters.QdrantAdapter import (
62
+ QdrantAdapter,
63
+ )
64
+
65
+ return QdrantAdapter(**self.config)
66
+ else:
67
+ raise ValueError(f"Unknown adapter: {self.adapter}")
68
+ else:
69
+ return super().load()
70
+
71
+
72
+ class VectorStoreServiceConfiguration(BaseModel):
73
+ vector_store_adapter: VectorStoreAdapterConfiguration
74
+
75
+ def load(self) -> VectorStoreService:
76
+ return VectorStoreService(adapter=self.vector_store_adapter.load())
@@ -0,0 +1,33 @@
1
+ from naas_abi_core.engine.engine_configuration.EngineConfiguration_VectorStoreService import (
2
+ VectorStoreAdapterConfiguration,
3
+ VectorStoreAdapterQdrantConfiguration,
4
+ VectorStoreServiceConfiguration,
5
+ )
6
+ from naas_abi_core.services.vector_store.IVectorStorePort import IVectorStorePort
7
+ from naas_abi_core.services.vector_store.VectorStoreService import VectorStoreService
8
+
9
+
10
+ def test_vector_store_service_configuration():
11
+ from naas_abi_core.services.vector_store.adapters.QdrantAdapter import (
12
+ QdrantAdapter,
13
+ )
14
+
15
+ qdrant_config = VectorStoreAdapterQdrantConfiguration()
16
+ configuration = VectorStoreServiceConfiguration(
17
+ vector_store_adapter=VectorStoreAdapterConfiguration(
18
+ adapter="qdrant",
19
+ config=qdrant_config.model_dump(),
20
+ )
21
+ )
22
+ assert configuration.vector_store_adapter is not None
23
+
24
+ vector_store_adapter = configuration.vector_store_adapter.load()
25
+
26
+ assert vector_store_adapter is not None
27
+ assert isinstance(vector_store_adapter, IVectorStorePort)
28
+ assert isinstance(vector_store_adapter, QdrantAdapter)
29
+
30
+ vector_store_service = configuration.load()
31
+
32
+ assert vector_store_service is not None
33
+ assert isinstance(vector_store_service, VectorStoreService)
@@ -0,0 +1,9 @@
1
+ from naas_abi_core.engine.engine_configuration.EngineConfiguration import (
2
+ EngineConfiguration,
3
+ )
4
+
5
+
6
+ def test_configuration_load(test_configuration: str):
7
+ config = EngineConfiguration.load_configuration(test_configuration)
8
+ assert config is not None
9
+ assert False is True
@@ -0,0 +1,15 @@
1
+ from typing import Any
2
+
3
+ from naas_abi_core.utils.Logger import logger
4
+ from pydantic import BaseModel, ValidationError
5
+
6
+
7
+ def pydantic_model_validator(model: Any, payload: Any, message: str):
8
+ if not isinstance(model, type) or not issubclass(model, BaseModel):
9
+ raise TypeError(
10
+ "The model argument must be a class that inherits from pydantic.BaseModel"
11
+ )
12
+ try:
13
+ model.model_validate(payload)
14
+ except ValidationError as e:
15
+ logger.error(f"{message}: {e}")