arclith-cli 0.18.0__tar.gz → 0.20.0__tar.gz
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.
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/PKG-INFO +2 -2
- arclith_cli-0.20.0/arclith_cli/__init__.py +1 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/adapter_templates.py +2 -1
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/capabilities.py +12 -1
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/capability_models.py +41 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/catalogs/ai.py +89 -0
- arclith_cli-0.20.0/arclith_cli/catalogs/channels.py +197 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/catalogs/persistence.py +141 -0
- arclith_cli-0.20.0/arclith_cli/catalogs/repository_facets.py +94 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/init_project.py +1 -1
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/main.py +1 -1
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/project_paths.py +18 -3
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/pyproject.toml +2 -2
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/e2e_manual.sh +1 -1
- arclith_cli-0.20.0/tests/test_adapter_templates.py +20 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_add_adapter.py +166 -7
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_capabilities.py +174 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_core_scaffold.py +1 -1
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_embedding_capability.py +125 -3
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_project_paths.py +1 -0
- arclith_cli-0.20.0/tests/test_vector_store_capability.py +166 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/uv.lock +6 -3
- arclith_cli-0.18.0/arclith_cli/__init__.py +0 -1
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/.gitignore +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/LICENSE +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/Makefile +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/README.md +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/adapter_config.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/adapter_generator.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/adapter_parameters.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/adapter_rendering.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/adapter_selection.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/add_adapter.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/catalogs/__init__.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/catalogs/core.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/catalogs/observability.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/catalogs/security.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/catalogs/transports.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/core_scaffold.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/entity_scanner.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/export_config.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/new_project.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/recipe.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/recipe_cli.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/recipe_models.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/rename.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/runtime_templates.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/scaffold.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/arclith_cli/updater.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/__init__.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_e2e_scaffold.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_recipe.py +0 -0
- {arclith_cli-0.18.0 → arclith_cli-0.20.0}/tests/test_rename.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: arclith-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.0
|
|
4
4
|
Summary: CLI scaffolding tool for arclith — hexagonal architecture framework
|
|
5
5
|
Author-email: Killian KOPP <killiankopp@gmail.com>
|
|
6
6
|
License: Apache License
|
|
@@ -186,7 +186,7 @@ License: Apache License
|
|
|
186
186
|
License-File: LICENSE
|
|
187
187
|
Keywords: arclith,cli,ddd,hexagonal-architecture,scaffold
|
|
188
188
|
Requires-Python: >=3.13
|
|
189
|
-
Requires-Dist: arclith>=0.
|
|
189
|
+
Requires-Dist: arclith>=0.23.0
|
|
190
190
|
Requires-Dist: httpx>=0.27.0
|
|
191
191
|
Requires-Dist: rich>=13.0.0
|
|
192
192
|
Requires-Dist: typer>=0.15.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.20.0"
|
|
@@ -205,7 +205,8 @@ _repository_registry: RepositoryRegistry[{pascal}, {pascal}Repository] = (
|
|
|
205
205
|
|
|
206
206
|
|
|
207
207
|
def build_{snake}_service(arclith: Arclith) -> tuple[{pascal}Service, Logger]:
|
|
208
|
-
|
|
208
|
+
adapter = arclith.config.adapters.repository_adapter_for({pascal})
|
|
209
|
+
arclith.logger.info("🗄️ Repository adapter selected", adapter=adapter)
|
|
209
210
|
repo: {pascal}Repository = arclith.repository({pascal}, registry=_repository_registry)
|
|
210
211
|
return {pascal}Service(repo, arclith.logger, arclith.config.soft_delete.retention_days), arclith.logger
|
|
211
212
|
"""
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
from arclith_cli.capability_models import (
|
|
6
|
+
AdapterFacets,
|
|
6
7
|
AdapterProfileSpec,
|
|
7
8
|
AdapterSpec,
|
|
8
9
|
CapabilitySpec,
|
|
@@ -18,13 +19,18 @@ from arclith_cli.catalogs.ai import (
|
|
|
18
19
|
EMBEDDING_CAPABILITY,
|
|
19
20
|
LLM_CAPABILITY,
|
|
20
21
|
)
|
|
22
|
+
from arclith_cli.catalogs.channels import CHANNEL_CAPABILITY
|
|
21
23
|
from arclith_cli.catalogs.core import (
|
|
22
24
|
CACHE_CAPABILITY,
|
|
23
25
|
LOGGER_CAPABILITY,
|
|
24
26
|
SECRETS_CAPABILITY,
|
|
25
27
|
)
|
|
26
28
|
from arclith_cli.catalogs.observability import OBSERVABILITY_CAPABILITY
|
|
27
|
-
from arclith_cli.catalogs.persistence import
|
|
29
|
+
from arclith_cli.catalogs.persistence import (
|
|
30
|
+
REPOSITORY_CAPABILITY,
|
|
31
|
+
STORAGE_CAPABILITY,
|
|
32
|
+
VECTOR_STORE_CAPABILITY,
|
|
33
|
+
)
|
|
28
34
|
from arclith_cli.catalogs.security import (
|
|
29
35
|
AUTH_CAPABILITY,
|
|
30
36
|
LICENSE_CAPABILITY,
|
|
@@ -44,9 +50,11 @@ __all__ = [
|
|
|
44
50
|
"AGENT_PERSISTENCE_CAPABILITY",
|
|
45
51
|
"API_CAPABILITY",
|
|
46
52
|
"AUTH_CAPABILITY",
|
|
53
|
+
"AdapterFacets",
|
|
47
54
|
"AdapterProfileSpec",
|
|
48
55
|
"AdapterSpec",
|
|
49
56
|
"CACHE_CAPABILITY",
|
|
57
|
+
"CHANNEL_CAPABILITY",
|
|
50
58
|
"CAPABILITY_CATALOG",
|
|
51
59
|
"COMMAND_BUS_CAPABILITY",
|
|
52
60
|
"CapabilitySpec",
|
|
@@ -68,6 +76,7 @@ __all__ = [
|
|
|
68
76
|
"STORAGE_CAPABILITY",
|
|
69
77
|
"SecretMappingSpec",
|
|
70
78
|
"TENANT_CAPABILITY",
|
|
79
|
+
"VECTOR_STORE_CAPABILITY",
|
|
71
80
|
"capability_catalog_as_dict",
|
|
72
81
|
"capability_names",
|
|
73
82
|
"get_capability",
|
|
@@ -77,6 +86,7 @@ __all__ = [
|
|
|
77
86
|
CAPABILITY_CATALOG = (
|
|
78
87
|
REPOSITORY_CAPABILITY,
|
|
79
88
|
STORAGE_CAPABILITY,
|
|
89
|
+
VECTOR_STORE_CAPABILITY,
|
|
80
90
|
CACHE_CAPABILITY,
|
|
81
91
|
LOGGER_CAPABILITY,
|
|
82
92
|
SECRETS_CAPABILITY,
|
|
@@ -85,6 +95,7 @@ CAPABILITY_CATALOG = (
|
|
|
85
95
|
PROBE_CAPABILITY,
|
|
86
96
|
HTTP_CAPABILITY,
|
|
87
97
|
COMMAND_BUS_CAPABILITY,
|
|
98
|
+
CHANNEL_CAPABILITY,
|
|
88
99
|
RUNTIME_CAPABILITY,
|
|
89
100
|
AUTH_CAPABILITY,
|
|
90
101
|
TENANT_CAPABILITY,
|
|
@@ -5,6 +5,16 @@ from typing import Any, Literal
|
|
|
5
5
|
|
|
6
6
|
ParameterKind = Literal["string", "boolean"]
|
|
7
7
|
LayerKind = Literal["inbound", "outbound", "bidirectional", "runtime"]
|
|
8
|
+
StorageModel = Literal[
|
|
9
|
+
"memory",
|
|
10
|
+
"document",
|
|
11
|
+
"relational_json",
|
|
12
|
+
"embedded_analytics",
|
|
13
|
+
"relational_structured",
|
|
14
|
+
]
|
|
15
|
+
RuntimeKind = Literal["in_process", "file", "server"]
|
|
16
|
+
TransactionSupport = Literal["none", "limited", "strong"]
|
|
17
|
+
SchemaStrategy = Literal["flexible", "json_table", "structured_tables"]
|
|
8
18
|
|
|
9
19
|
|
|
10
20
|
@dataclass(frozen=True)
|
|
@@ -70,6 +80,30 @@ class AdapterProfileSpec:
|
|
|
70
80
|
return {"name": self.name, "parameters": dict(self.parameters)}
|
|
71
81
|
|
|
72
82
|
|
|
83
|
+
@dataclass(frozen=True)
|
|
84
|
+
class AdapterFacets:
|
|
85
|
+
storage_model: StorageModel
|
|
86
|
+
runtime: RuntimeKind
|
|
87
|
+
production_ready: bool
|
|
88
|
+
multi_process: bool
|
|
89
|
+
transactions: TransactionSupport
|
|
90
|
+
schema_strategy: SchemaStrategy
|
|
91
|
+
recommended_for: tuple[str, ...]
|
|
92
|
+
limits: tuple[str, ...]
|
|
93
|
+
|
|
94
|
+
def to_dict(self) -> dict[str, Any]:
|
|
95
|
+
return {
|
|
96
|
+
"storage_model": self.storage_model,
|
|
97
|
+
"runtime": self.runtime,
|
|
98
|
+
"production_ready": self.production_ready,
|
|
99
|
+
"multi_process": self.multi_process,
|
|
100
|
+
"transactions": self.transactions,
|
|
101
|
+
"schema_strategy": self.schema_strategy,
|
|
102
|
+
"recommended_for": list(self.recommended_for),
|
|
103
|
+
"limits": list(self.limits),
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
73
107
|
@dataclass(frozen=True)
|
|
74
108
|
class AdapterSpec:
|
|
75
109
|
name: str
|
|
@@ -90,6 +124,7 @@ class AdapterSpec:
|
|
|
90
124
|
profiles: tuple[AdapterProfileSpec, ...] = ()
|
|
91
125
|
dependency_extra: str | None = None
|
|
92
126
|
entity_scoped: bool = True
|
|
127
|
+
facets: AdapterFacets | None = None
|
|
93
128
|
|
|
94
129
|
def has_config(self) -> bool:
|
|
95
130
|
return self.config_path is not None and bool(self.config_template)
|
|
@@ -137,6 +172,7 @@ class AdapterSpec:
|
|
|
137
172
|
"profiles": [profile.to_dict() for profile in self.profiles],
|
|
138
173
|
"dependency_extra": self.dependency_extra,
|
|
139
174
|
"entity_scoped": self.entity_scoped,
|
|
175
|
+
"facets": self.facets.to_dict() if self.facets is not None else None,
|
|
140
176
|
}
|
|
141
177
|
|
|
142
178
|
|
|
@@ -169,6 +205,7 @@ class CapabilitySpec:
|
|
|
169
205
|
|
|
170
206
|
|
|
171
207
|
__all__ = [
|
|
208
|
+
"AdapterFacets",
|
|
172
209
|
"AdapterProfileSpec",
|
|
173
210
|
"AdapterSpec",
|
|
174
211
|
"CapabilitySpec",
|
|
@@ -176,5 +213,9 @@ __all__ = [
|
|
|
176
213
|
"LayerKind",
|
|
177
214
|
"ParameterKind",
|
|
178
215
|
"ParameterSpec",
|
|
216
|
+
"RuntimeKind",
|
|
217
|
+
"SchemaStrategy",
|
|
179
218
|
"SecretMappingSpec",
|
|
219
|
+
"StorageModel",
|
|
220
|
+
"TransactionSupport",
|
|
180
221
|
]
|
|
@@ -260,6 +260,95 @@ multitenant: {multitenant}
|
|
|
260
260
|
dependency_extra="embedding",
|
|
261
261
|
entity_scoped=False,
|
|
262
262
|
),
|
|
263
|
+
AdapterSpec(
|
|
264
|
+
name="openai",
|
|
265
|
+
capability="embedding",
|
|
266
|
+
layer="outbound",
|
|
267
|
+
description="Embeddings via l'API OpenAI officielle et un secret externe.",
|
|
268
|
+
config_path="config/adapters/outbound/embedding.yaml",
|
|
269
|
+
config_template="""\
|
|
270
|
+
adapter: openai
|
|
271
|
+
base_url: "{base_url}"
|
|
272
|
+
api_key: null
|
|
273
|
+
model_name: "{model_name}"
|
|
274
|
+
dimensions: {dimensions}
|
|
275
|
+
batch_size: {batch_size}
|
|
276
|
+
timeout: {timeout}
|
|
277
|
+
encoding_format: {encoding_format}
|
|
278
|
+
normalize: {normalize}
|
|
279
|
+
multitenant: {multitenant}
|
|
280
|
+
""",
|
|
281
|
+
env_path=".env",
|
|
282
|
+
env_template="""\
|
|
283
|
+
OPENAI_API_KEY={api_key}
|
|
284
|
+
""",
|
|
285
|
+
secret_mappings=(
|
|
286
|
+
SecretMappingSpec(
|
|
287
|
+
field_path="adapters.embedding.api_key",
|
|
288
|
+
secret_key="OPENAI_API_KEY",
|
|
289
|
+
),
|
|
290
|
+
),
|
|
291
|
+
parameters=(
|
|
292
|
+
ParameterSpec(
|
|
293
|
+
name="base_url",
|
|
294
|
+
kind="string",
|
|
295
|
+
prompt="Endpoint officiel OpenAI avec préfixe API",
|
|
296
|
+
default="https://api.openai.com/v1",
|
|
297
|
+
),
|
|
298
|
+
ParameterSpec(
|
|
299
|
+
name="api_key",
|
|
300
|
+
kind="string",
|
|
301
|
+
prompt="OPENAI_API_KEY (laisser vide pour un secret externe)",
|
|
302
|
+
default="",
|
|
303
|
+
secret=True,
|
|
304
|
+
),
|
|
305
|
+
ParameterSpec(
|
|
306
|
+
name="model_name",
|
|
307
|
+
kind="string",
|
|
308
|
+
prompt="ID du modèle d'embedding OpenAI accessible au projet",
|
|
309
|
+
default="remplacer-par-model-id-openai-embedding",
|
|
310
|
+
),
|
|
311
|
+
ParameterSpec(
|
|
312
|
+
name="dimensions",
|
|
313
|
+
kind="string",
|
|
314
|
+
prompt="Dimension optionnelle des vecteurs (null pour le défaut modèle)",
|
|
315
|
+
default="null",
|
|
316
|
+
),
|
|
317
|
+
ParameterSpec(
|
|
318
|
+
name="batch_size",
|
|
319
|
+
kind="string",
|
|
320
|
+
prompt="Taille maximale des sous-batches",
|
|
321
|
+
default="64",
|
|
322
|
+
),
|
|
323
|
+
ParameterSpec(
|
|
324
|
+
name="timeout",
|
|
325
|
+
kind="string",
|
|
326
|
+
prompt="Timeout HTTP en secondes",
|
|
327
|
+
default="30.0",
|
|
328
|
+
),
|
|
329
|
+
ParameterSpec(
|
|
330
|
+
name="encoding_format",
|
|
331
|
+
kind="string",
|
|
332
|
+
prompt="Format des vecteurs retournés",
|
|
333
|
+
default="float",
|
|
334
|
+
choices=("float",),
|
|
335
|
+
),
|
|
336
|
+
ParameterSpec(
|
|
337
|
+
name="normalize",
|
|
338
|
+
kind="boolean",
|
|
339
|
+
prompt="Normaliser les vecteurs en norme L2",
|
|
340
|
+
default=False,
|
|
341
|
+
),
|
|
342
|
+
ParameterSpec(
|
|
343
|
+
name="multitenant",
|
|
344
|
+
kind="boolean",
|
|
345
|
+
prompt="Réserver la résolution de contexte par tenant",
|
|
346
|
+
default=False,
|
|
347
|
+
),
|
|
348
|
+
),
|
|
349
|
+
dependency_extra="embedding",
|
|
350
|
+
entity_scoped=False,
|
|
351
|
+
),
|
|
263
352
|
),
|
|
264
353
|
)
|
|
265
354
|
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
from arclith_cli.capability_models import (
|
|
2
|
+
AdapterSpec,
|
|
3
|
+
CapabilitySpec,
|
|
4
|
+
ParameterSpec,
|
|
5
|
+
SecretMappingSpec,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
CHANNEL_CAPABILITY = CapabilitySpec(
|
|
9
|
+
name="channel",
|
|
10
|
+
layer="bidirectional",
|
|
11
|
+
description="Messages conversationnels entrants et sortants normalisés.",
|
|
12
|
+
activation_config_key=None,
|
|
13
|
+
adapters=(
|
|
14
|
+
AdapterSpec(
|
|
15
|
+
name="memory",
|
|
16
|
+
capability="channel",
|
|
17
|
+
layer="bidirectional",
|
|
18
|
+
description="Fake déterministe en mémoire pour tests et prototypes locaux.",
|
|
19
|
+
config_path="config/adapters/bidirectional/memory.yaml",
|
|
20
|
+
config_template="""\
|
|
21
|
+
enabled: true
|
|
22
|
+
""",
|
|
23
|
+
entity_scoped=False,
|
|
24
|
+
),
|
|
25
|
+
AdapterSpec(
|
|
26
|
+
name="webhook",
|
|
27
|
+
capability="channel",
|
|
28
|
+
layer="bidirectional",
|
|
29
|
+
description="Webhook HTTP générique signé, idempotent et provider-neutral.",
|
|
30
|
+
config_path="config/adapters/bidirectional/webhook.yaml",
|
|
31
|
+
config_template="""\
|
|
32
|
+
enabled: true
|
|
33
|
+
path: "{path}"
|
|
34
|
+
secret: null
|
|
35
|
+
signature_header: "{signature_header}"
|
|
36
|
+
timestamp_header: "{timestamp_header}"
|
|
37
|
+
signature_tolerance_seconds: {signature_tolerance_seconds}
|
|
38
|
+
idempotency_header: "{idempotency_header}"
|
|
39
|
+
event_ttl_seconds: {event_ttl_seconds}
|
|
40
|
+
max_payload_bytes: {max_payload_bytes}
|
|
41
|
+
metadata_allowlist: []
|
|
42
|
+
response_mode: "{response_mode}"
|
|
43
|
+
callback_url: {callback_url}
|
|
44
|
+
callback_allowed_host: {callback_allowed_host}
|
|
45
|
+
callback_timeout_seconds: {callback_timeout_seconds}
|
|
46
|
+
""",
|
|
47
|
+
secret_mappings=(
|
|
48
|
+
SecretMappingSpec(
|
|
49
|
+
field_path="adapters.channel.webhook.secret",
|
|
50
|
+
secret_key="ARCLITH_WEBHOOK_SECRET",
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
parameters=(
|
|
54
|
+
ParameterSpec(
|
|
55
|
+
name="path",
|
|
56
|
+
kind="string",
|
|
57
|
+
prompt="Route HTTP statique du webhook",
|
|
58
|
+
default="/channels/webhook",
|
|
59
|
+
),
|
|
60
|
+
ParameterSpec(
|
|
61
|
+
name="signature_header",
|
|
62
|
+
kind="string",
|
|
63
|
+
prompt="Header de signature HMAC",
|
|
64
|
+
default="X-Arclith-Signature",
|
|
65
|
+
),
|
|
66
|
+
ParameterSpec(
|
|
67
|
+
name="timestamp_header",
|
|
68
|
+
kind="string",
|
|
69
|
+
prompt="Header du timestamp signé",
|
|
70
|
+
default="X-Arclith-Timestamp",
|
|
71
|
+
),
|
|
72
|
+
ParameterSpec(
|
|
73
|
+
name="signature_tolerance_seconds",
|
|
74
|
+
kind="string",
|
|
75
|
+
prompt="Tolérance de fraîcheur HMAC en secondes",
|
|
76
|
+
default="300",
|
|
77
|
+
),
|
|
78
|
+
ParameterSpec(
|
|
79
|
+
name="idempotency_header",
|
|
80
|
+
kind="string",
|
|
81
|
+
prompt="Header de l'identifiant stable de l'événement",
|
|
82
|
+
default="X-Arclith-Event-Id",
|
|
83
|
+
),
|
|
84
|
+
ParameterSpec(
|
|
85
|
+
name="event_ttl_seconds",
|
|
86
|
+
kind="string",
|
|
87
|
+
prompt="Durée de déduplication en secondes",
|
|
88
|
+
default="86400",
|
|
89
|
+
),
|
|
90
|
+
ParameterSpec(
|
|
91
|
+
name="max_payload_bytes",
|
|
92
|
+
kind="string",
|
|
93
|
+
prompt="Taille maximale du payload en octets",
|
|
94
|
+
default="1048576",
|
|
95
|
+
),
|
|
96
|
+
ParameterSpec(
|
|
97
|
+
name="response_mode",
|
|
98
|
+
kind="string",
|
|
99
|
+
prompt="Mode de réponse HTTP",
|
|
100
|
+
default="sync",
|
|
101
|
+
choices=("sync", "accepted", "callback"),
|
|
102
|
+
),
|
|
103
|
+
ParameterSpec(
|
|
104
|
+
name="callback_url",
|
|
105
|
+
kind="string",
|
|
106
|
+
prompt="URL HTTPS du callback côté serveur (null hors mode callback)",
|
|
107
|
+
default="null",
|
|
108
|
+
),
|
|
109
|
+
ParameterSpec(
|
|
110
|
+
name="callback_allowed_host",
|
|
111
|
+
kind="string",
|
|
112
|
+
prompt="Hostname exact autorisé pour le callback (null hors mode callback)",
|
|
113
|
+
default="null",
|
|
114
|
+
),
|
|
115
|
+
ParameterSpec(
|
|
116
|
+
name="callback_timeout_seconds",
|
|
117
|
+
kind="string",
|
|
118
|
+
prompt="Timeout du callback sortant en secondes",
|
|
119
|
+
default="5.0",
|
|
120
|
+
),
|
|
121
|
+
),
|
|
122
|
+
dependency_extra="channel",
|
|
123
|
+
entity_scoped=False,
|
|
124
|
+
),
|
|
125
|
+
AdapterSpec(
|
|
126
|
+
name="slack",
|
|
127
|
+
capability="channel",
|
|
128
|
+
layer="bidirectional",
|
|
129
|
+
description="Slack Events API signé avec réponses chat.postMessage.",
|
|
130
|
+
config_path="config/adapters/bidirectional/slack.yaml",
|
|
131
|
+
config_template="""\
|
|
132
|
+
enabled: true
|
|
133
|
+
path: "{path}"
|
|
134
|
+
signing_secret: null
|
|
135
|
+
bot_token: null
|
|
136
|
+
workspace_id: {workspace_id}
|
|
137
|
+
allowed_channel_ids: []
|
|
138
|
+
signature_tolerance_seconds: {signature_tolerance_seconds}
|
|
139
|
+
event_ttl_seconds: {event_ttl_seconds}
|
|
140
|
+
max_payload_bytes: {max_payload_bytes}
|
|
141
|
+
request_timeout_seconds: {request_timeout_seconds}
|
|
142
|
+
""",
|
|
143
|
+
secret_mappings=(
|
|
144
|
+
SecretMappingSpec(
|
|
145
|
+
field_path="adapters.channel.slack.signing_secret",
|
|
146
|
+
secret_key="ARCLITH_SLACK_SIGNING_SECRET",
|
|
147
|
+
),
|
|
148
|
+
SecretMappingSpec(
|
|
149
|
+
field_path="adapters.channel.slack.bot_token",
|
|
150
|
+
secret_key="ARCLITH_SLACK_BOT_TOKEN",
|
|
151
|
+
),
|
|
152
|
+
),
|
|
153
|
+
parameters=(
|
|
154
|
+
ParameterSpec(
|
|
155
|
+
name="path",
|
|
156
|
+
kind="string",
|
|
157
|
+
prompt="Route HTTP statique des événements Slack",
|
|
158
|
+
default="/channels/slack/events",
|
|
159
|
+
),
|
|
160
|
+
ParameterSpec(
|
|
161
|
+
name="workspace_id",
|
|
162
|
+
kind="string",
|
|
163
|
+
prompt="Workspace Slack exact autorisé (null pour tout accepter)",
|
|
164
|
+
default="null",
|
|
165
|
+
),
|
|
166
|
+
ParameterSpec(
|
|
167
|
+
name="signature_tolerance_seconds",
|
|
168
|
+
kind="string",
|
|
169
|
+
prompt="Tolérance de fraîcheur de signature en secondes",
|
|
170
|
+
default="300",
|
|
171
|
+
),
|
|
172
|
+
ParameterSpec(
|
|
173
|
+
name="event_ttl_seconds",
|
|
174
|
+
kind="string",
|
|
175
|
+
prompt="Durée de déduplication des event_id en secondes",
|
|
176
|
+
default="86400",
|
|
177
|
+
),
|
|
178
|
+
ParameterSpec(
|
|
179
|
+
name="max_payload_bytes",
|
|
180
|
+
kind="string",
|
|
181
|
+
prompt="Taille maximale du payload en octets",
|
|
182
|
+
default="1048576",
|
|
183
|
+
),
|
|
184
|
+
ParameterSpec(
|
|
185
|
+
name="request_timeout_seconds",
|
|
186
|
+
kind="string",
|
|
187
|
+
prompt="Timeout de chat.postMessage en secondes",
|
|
188
|
+
default="5.0",
|
|
189
|
+
),
|
|
190
|
+
),
|
|
191
|
+
dependency_extra="channel",
|
|
192
|
+
entity_scoped=False,
|
|
193
|
+
),
|
|
194
|
+
),
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
__all__ = ["CHANNEL_CAPABILITY"]
|
|
@@ -6,6 +6,13 @@ from arclith_cli.capability_models import (
|
|
|
6
6
|
ParameterSpec,
|
|
7
7
|
SecretMappingSpec,
|
|
8
8
|
)
|
|
9
|
+
from arclith_cli.catalogs.repository_facets import (
|
|
10
|
+
DUCKDB_FACETS,
|
|
11
|
+
MARIADB_FACETS,
|
|
12
|
+
MEMORY_FACETS,
|
|
13
|
+
MONGODB_FACETS,
|
|
14
|
+
POSTGRESQL_FACETS,
|
|
15
|
+
)
|
|
9
16
|
|
|
10
17
|
REPOSITORY_CAPABILITY = CapabilitySpec(
|
|
11
18
|
name="repository",
|
|
@@ -18,6 +25,7 @@ REPOSITORY_CAPABILITY = CapabilitySpec(
|
|
|
18
25
|
capability="repository",
|
|
19
26
|
layer="outbound",
|
|
20
27
|
description="Stockage volatile en mémoire pour dev, tests et smoke locaux.",
|
|
28
|
+
facets=MEMORY_FACETS,
|
|
21
29
|
),
|
|
22
30
|
AdapterSpec(
|
|
23
31
|
name="mongodb",
|
|
@@ -57,6 +65,7 @@ multitenant: {multitenant} # true = uri/db_name résolus par requête via JWT
|
|
|
57
65
|
default=False,
|
|
58
66
|
),
|
|
59
67
|
),
|
|
68
|
+
facets=MONGODB_FACETS,
|
|
60
69
|
),
|
|
61
70
|
AdapterSpec(
|
|
62
71
|
name="duckdb",
|
|
@@ -76,6 +85,7 @@ path: {path}
|
|
|
76
85
|
default="data/",
|
|
77
86
|
),
|
|
78
87
|
),
|
|
88
|
+
facets=DUCKDB_FACETS,
|
|
79
89
|
),
|
|
80
90
|
AdapterSpec(
|
|
81
91
|
name="mariadb",
|
|
@@ -142,6 +152,7 @@ multitenant: false
|
|
|
142
152
|
default="",
|
|
143
153
|
),
|
|
144
154
|
),
|
|
155
|
+
facets=MARIADB_FACETS,
|
|
145
156
|
),
|
|
146
157
|
AdapterSpec(
|
|
147
158
|
name="postgresql",
|
|
@@ -221,6 +232,7 @@ multitenant: {multitenant}
|
|
|
221
232
|
default=False,
|
|
222
233
|
),
|
|
223
234
|
),
|
|
235
|
+
facets=POSTGRESQL_FACETS,
|
|
224
236
|
),
|
|
225
237
|
),
|
|
226
238
|
)
|
|
@@ -444,3 +456,132 @@ multitenant: {multitenant}
|
|
|
444
456
|
),
|
|
445
457
|
),
|
|
446
458
|
)
|
|
459
|
+
|
|
460
|
+
VECTOR_STORE_CAPABILITY = CapabilitySpec(
|
|
461
|
+
name="vector-store",
|
|
462
|
+
layer="outbound",
|
|
463
|
+
description="Indexation et recherche dense derrière un port provider-neutral.",
|
|
464
|
+
activation_config_key=None,
|
|
465
|
+
adapters=(
|
|
466
|
+
AdapterSpec(
|
|
467
|
+
name="memory",
|
|
468
|
+
capability="vector-store",
|
|
469
|
+
layer="outbound",
|
|
470
|
+
description="Recherche exacte déterministe sans dépendance pour tests et POC.",
|
|
471
|
+
config_path="config/adapters/outbound/vector_store.yaml",
|
|
472
|
+
config_template="""\
|
|
473
|
+
adapter: memory
|
|
474
|
+
collection_name: "{collection_name}"
|
|
475
|
+
vector_size: {vector_size}
|
|
476
|
+
distance: {distance}
|
|
477
|
+
multitenant: {multitenant}
|
|
478
|
+
""",
|
|
479
|
+
parameters=(
|
|
480
|
+
ParameterSpec(
|
|
481
|
+
name="collection_name",
|
|
482
|
+
kind="string",
|
|
483
|
+
prompt="Nom logique de la collection",
|
|
484
|
+
default="default",
|
|
485
|
+
),
|
|
486
|
+
ParameterSpec(
|
|
487
|
+
name="vector_size",
|
|
488
|
+
kind="string",
|
|
489
|
+
prompt="Dimension obligatoire des vecteurs",
|
|
490
|
+
default="1536",
|
|
491
|
+
),
|
|
492
|
+
ParameterSpec(
|
|
493
|
+
name="distance",
|
|
494
|
+
kind="string",
|
|
495
|
+
prompt="Métrique de similarité",
|
|
496
|
+
default="cosine",
|
|
497
|
+
choices=("cosine", "dot", "euclid"),
|
|
498
|
+
),
|
|
499
|
+
ParameterSpec(
|
|
500
|
+
name="multitenant",
|
|
501
|
+
kind="boolean",
|
|
502
|
+
prompt="Réserver la résolution de contexte par tenant",
|
|
503
|
+
default=False,
|
|
504
|
+
),
|
|
505
|
+
),
|
|
506
|
+
entity_scoped=False,
|
|
507
|
+
),
|
|
508
|
+
AdapterSpec(
|
|
509
|
+
name="qdrant",
|
|
510
|
+
capability="vector-store",
|
|
511
|
+
layer="outbound",
|
|
512
|
+
description="Index vectoriel dense Qdrant via le client Python async officiel.",
|
|
513
|
+
config_path="config/adapters/outbound/vector_store.yaml",
|
|
514
|
+
config_template="""\
|
|
515
|
+
adapter: qdrant
|
|
516
|
+
url: "{url}"
|
|
517
|
+
api_key: null
|
|
518
|
+
collection_name: "{collection_name}"
|
|
519
|
+
vector_size: {vector_size}
|
|
520
|
+
distance: {distance}
|
|
521
|
+
prefer_grpc: {prefer_grpc}
|
|
522
|
+
timeout: {timeout}
|
|
523
|
+
create_collection: {create_collection}
|
|
524
|
+
multitenant: {multitenant}
|
|
525
|
+
""",
|
|
526
|
+
secret_mappings=(
|
|
527
|
+
SecretMappingSpec(
|
|
528
|
+
field_path="adapters.vector_store.api_key",
|
|
529
|
+
secret_key="QDRANT_API_KEY",
|
|
530
|
+
),
|
|
531
|
+
),
|
|
532
|
+
parameters=(
|
|
533
|
+
ParameterSpec(
|
|
534
|
+
name="url",
|
|
535
|
+
kind="string",
|
|
536
|
+
prompt="Endpoint HTTP Qdrant sans credentials",
|
|
537
|
+
default="http://localhost:6333",
|
|
538
|
+
),
|
|
539
|
+
ParameterSpec(
|
|
540
|
+
name="collection_name",
|
|
541
|
+
kind="string",
|
|
542
|
+
prompt="Nom de la collection Qdrant",
|
|
543
|
+
default="default",
|
|
544
|
+
),
|
|
545
|
+
ParameterSpec(
|
|
546
|
+
name="vector_size",
|
|
547
|
+
kind="string",
|
|
548
|
+
prompt="Dimension obligatoire des vecteurs",
|
|
549
|
+
default="1536",
|
|
550
|
+
),
|
|
551
|
+
ParameterSpec(
|
|
552
|
+
name="distance",
|
|
553
|
+
kind="string",
|
|
554
|
+
prompt="Métrique de similarité",
|
|
555
|
+
default="cosine",
|
|
556
|
+
choices=("cosine", "dot", "euclid"),
|
|
557
|
+
),
|
|
558
|
+
ParameterSpec(
|
|
559
|
+
name="prefer_grpc",
|
|
560
|
+
kind="boolean",
|
|
561
|
+
prompt="Préférer le transport gRPC",
|
|
562
|
+
default=False,
|
|
563
|
+
),
|
|
564
|
+
ParameterSpec(
|
|
565
|
+
name="timeout",
|
|
566
|
+
kind="string",
|
|
567
|
+
prompt="Timeout client en secondes",
|
|
568
|
+
default="5.0",
|
|
569
|
+
),
|
|
570
|
+
ParameterSpec(
|
|
571
|
+
name="create_collection",
|
|
572
|
+
kind="boolean",
|
|
573
|
+
prompt="Créer la collection si elle manque",
|
|
574
|
+
default=True,
|
|
575
|
+
),
|
|
576
|
+
ParameterSpec(
|
|
577
|
+
name="multitenant",
|
|
578
|
+
kind="boolean",
|
|
579
|
+
prompt="Résoudre url, api_key et collection par tenant",
|
|
580
|
+
default=False,
|
|
581
|
+
),
|
|
582
|
+
),
|
|
583
|
+
dependency_extra="qdrant",
|
|
584
|
+
entity_scoped=False,
|
|
585
|
+
),
|
|
586
|
+
),
|
|
587
|
+
)
|