kodit 0.4.3__py3-none-any.whl → 0.5.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.
Potentially problematic release.
This version of kodit might be problematic. Click here for more details.
- kodit/_version.py +2 -2
- kodit/app.py +51 -23
- kodit/application/factories/reporting_factory.py +6 -2
- kodit/application/factories/server_factory.py +353 -0
- kodit/application/services/code_search_application_service.py +144 -0
- kodit/application/services/commit_indexing_application_service.py +700 -0
- kodit/application/services/indexing_worker_service.py +13 -44
- kodit/application/services/queue_service.py +24 -3
- kodit/application/services/reporting.py +0 -2
- kodit/application/services/sync_scheduler.py +15 -31
- kodit/cli.py +2 -753
- kodit/cli_utils.py +2 -9
- kodit/config.py +4 -97
- kodit/database.py +38 -1
- kodit/domain/enrichments/__init__.py +1 -0
- kodit/domain/enrichments/architecture/__init__.py +1 -0
- kodit/domain/enrichments/architecture/architecture.py +20 -0
- kodit/domain/enrichments/architecture/physical/__init__.py +1 -0
- kodit/domain/enrichments/architecture/physical/discovery_notes.py +14 -0
- kodit/domain/enrichments/architecture/physical/formatter.py +11 -0
- kodit/domain/enrichments/architecture/physical/physical.py +17 -0
- kodit/domain/enrichments/development/__init__.py +1 -0
- kodit/domain/enrichments/development/development.py +18 -0
- kodit/domain/enrichments/development/snippet/__init__.py +1 -0
- kodit/domain/enrichments/development/snippet/snippet.py +21 -0
- kodit/domain/enrichments/enricher.py +17 -0
- kodit/domain/enrichments/enrichment.py +39 -0
- kodit/domain/enrichments/request.py +12 -0
- kodit/domain/enrichments/response.py +11 -0
- kodit/domain/enrichments/usage/__init__.py +1 -0
- kodit/domain/enrichments/usage/api_docs.py +19 -0
- kodit/domain/enrichments/usage/usage.py +18 -0
- kodit/domain/{entities.py → entities/__init__.py} +50 -195
- kodit/domain/entities/git.py +190 -0
- kodit/domain/factories/__init__.py +1 -0
- kodit/domain/factories/git_repo_factory.py +76 -0
- kodit/domain/protocols.py +264 -64
- kodit/domain/services/bm25_service.py +5 -1
- kodit/domain/services/embedding_service.py +3 -0
- kodit/domain/services/enrichment_service.py +9 -30
- kodit/domain/services/git_repository_service.py +429 -0
- kodit/domain/services/git_service.py +300 -0
- kodit/domain/services/physical_architecture_service.py +182 -0
- kodit/domain/services/task_status_query_service.py +2 -2
- kodit/domain/value_objects.py +87 -135
- kodit/infrastructure/api/client/__init__.py +0 -2
- kodit/infrastructure/api/v1/__init__.py +0 -4
- kodit/infrastructure/api/v1/dependencies.py +92 -46
- kodit/infrastructure/api/v1/routers/__init__.py +0 -6
- kodit/infrastructure/api/v1/routers/commits.py +352 -0
- kodit/infrastructure/api/v1/routers/queue.py +2 -2
- kodit/infrastructure/api/v1/routers/repositories.py +282 -0
- kodit/infrastructure/api/v1/routers/search.py +31 -14
- kodit/infrastructure/api/v1/schemas/__init__.py +0 -24
- kodit/infrastructure/api/v1/schemas/commit.py +96 -0
- kodit/infrastructure/api/v1/schemas/context.py +2 -0
- kodit/infrastructure/api/v1/schemas/enrichment.py +29 -0
- kodit/infrastructure/api/v1/schemas/repository.py +128 -0
- kodit/infrastructure/api/v1/schemas/search.py +12 -9
- kodit/infrastructure/api/v1/schemas/snippet.py +58 -0
- kodit/infrastructure/api/v1/schemas/tag.py +31 -0
- kodit/infrastructure/api/v1/schemas/task_status.py +2 -0
- kodit/infrastructure/bm25/local_bm25_repository.py +16 -4
- kodit/infrastructure/bm25/vectorchord_bm25_repository.py +68 -52
- kodit/infrastructure/cloning/git/git_python_adaptor.py +534 -0
- kodit/infrastructure/cloning/git/working_copy.py +1 -1
- kodit/infrastructure/embedding/embedding_factory.py +3 -2
- kodit/infrastructure/embedding/local_vector_search_repository.py +1 -1
- kodit/infrastructure/embedding/vectorchord_vector_search_repository.py +111 -84
- kodit/infrastructure/enricher/__init__.py +1 -0
- kodit/infrastructure/enricher/enricher_factory.py +53 -0
- kodit/infrastructure/{enrichment/litellm_enrichment_provider.py → enricher/litellm_enricher.py} +36 -56
- kodit/infrastructure/{enrichment/local_enrichment_provider.py → enricher/local_enricher.py} +19 -24
- kodit/infrastructure/enricher/null_enricher.py +36 -0
- kodit/infrastructure/indexing/fusion_service.py +1 -1
- kodit/infrastructure/mappers/enrichment_mapper.py +83 -0
- kodit/infrastructure/mappers/git_mapper.py +193 -0
- kodit/infrastructure/mappers/snippet_mapper.py +104 -0
- kodit/infrastructure/mappers/task_mapper.py +5 -44
- kodit/infrastructure/physical_architecture/__init__.py +1 -0
- kodit/infrastructure/physical_architecture/detectors/__init__.py +1 -0
- kodit/infrastructure/physical_architecture/detectors/docker_compose_detector.py +336 -0
- kodit/infrastructure/physical_architecture/formatters/__init__.py +1 -0
- kodit/infrastructure/physical_architecture/formatters/narrative_formatter.py +149 -0
- kodit/infrastructure/reporting/log_progress.py +8 -5
- kodit/infrastructure/reporting/telemetry_progress.py +21 -0
- kodit/infrastructure/slicing/api_doc_extractor.py +836 -0
- kodit/infrastructure/slicing/ast_analyzer.py +1128 -0
- kodit/infrastructure/slicing/slicer.py +87 -421
- kodit/infrastructure/sqlalchemy/embedding_repository.py +43 -23
- kodit/infrastructure/sqlalchemy/enrichment_v2_repository.py +118 -0
- kodit/infrastructure/sqlalchemy/entities.py +402 -158
- kodit/infrastructure/sqlalchemy/git_branch_repository.py +274 -0
- kodit/infrastructure/sqlalchemy/git_commit_repository.py +346 -0
- kodit/infrastructure/sqlalchemy/git_repository.py +262 -0
- kodit/infrastructure/sqlalchemy/git_tag_repository.py +268 -0
- kodit/infrastructure/sqlalchemy/snippet_v2_repository.py +479 -0
- kodit/infrastructure/sqlalchemy/task_repository.py +29 -23
- kodit/infrastructure/sqlalchemy/task_status_repository.py +24 -12
- kodit/infrastructure/sqlalchemy/unit_of_work.py +10 -14
- kodit/mcp.py +12 -30
- kodit/migrations/env.py +1 -0
- kodit/migrations/versions/04b80f802e0c_foreign_key_review.py +100 -0
- kodit/migrations/versions/19f8c7faf8b9_add_generic_enrichment_type.py +260 -0
- kodit/migrations/versions/7f15f878c3a1_add_new_git_entities.py +690 -0
- kodit/migrations/versions/f9e5ef5e688f_add_git_commits_number.py +43 -0
- kodit/py.typed +0 -0
- kodit/utils/dump_config.py +361 -0
- kodit/utils/dump_openapi.py +6 -4
- kodit/utils/path_utils.py +29 -0
- {kodit-0.4.3.dist-info → kodit-0.5.1.dist-info}/METADATA +3 -3
- kodit-0.5.1.dist-info/RECORD +168 -0
- kodit/application/factories/code_indexing_factory.py +0 -195
- kodit/application/services/auto_indexing_service.py +0 -99
- kodit/application/services/code_indexing_application_service.py +0 -410
- kodit/domain/services/index_query_service.py +0 -70
- kodit/domain/services/index_service.py +0 -269
- kodit/infrastructure/api/client/index_client.py +0 -57
- kodit/infrastructure/api/v1/routers/indexes.py +0 -164
- kodit/infrastructure/api/v1/schemas/index.py +0 -101
- kodit/infrastructure/bm25/bm25_factory.py +0 -28
- kodit/infrastructure/cloning/__init__.py +0 -1
- kodit/infrastructure/cloning/metadata.py +0 -98
- kodit/infrastructure/enrichment/__init__.py +0 -1
- kodit/infrastructure/enrichment/enrichment_factory.py +0 -52
- kodit/infrastructure/enrichment/null_enrichment_provider.py +0 -19
- kodit/infrastructure/mappers/index_mapper.py +0 -345
- kodit/infrastructure/reporting/tdqm_progress.py +0 -38
- kodit/infrastructure/slicing/language_detection_service.py +0 -18
- kodit/infrastructure/sqlalchemy/index_repository.py +0 -646
- kodit-0.4.3.dist-info/RECORD +0 -125
- /kodit/infrastructure/{enrichment → enricher}/utils.py +0 -0
- {kodit-0.4.3.dist-info → kodit-0.5.1.dist-info}/WHEEL +0 -0
- {kodit-0.4.3.dist-info → kodit-0.5.1.dist-info}/entry_points.txt +0 -0
- {kodit-0.4.3.dist-info → kodit-0.5.1.dist-info}/licenses/LICENSE +0 -0
kodit/cli_utils.py
CHANGED
|
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
8
|
|
|
9
|
-
from kodit.infrastructure.api.client import
|
|
9
|
+
from kodit.infrastructure.api.client import SearchClient
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from kodit.config import AppContext
|
|
@@ -37,7 +37,7 @@ def with_client(f: Callable) -> Callable:
|
|
|
37
37
|
inner_func = getattr(
|
|
38
38
|
getattr(session_wrapped, "__wrapped__", session_wrapped),
|
|
39
39
|
"__wrapped__",
|
|
40
|
-
session_wrapped
|
|
40
|
+
session_wrapped,
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
# Get database session manually
|
|
@@ -47,13 +47,6 @@ def with_client(f: Callable) -> Callable:
|
|
|
47
47
|
else:
|
|
48
48
|
# Remote mode - use API clients
|
|
49
49
|
clients = {
|
|
50
|
-
"index_client": IndexClient(
|
|
51
|
-
base_url=app_context.remote.server_url or "",
|
|
52
|
-
api_key=app_context.remote.api_key,
|
|
53
|
-
timeout=app_context.remote.timeout,
|
|
54
|
-
max_retries=app_context.remote.max_retries,
|
|
55
|
-
verify_ssl=app_context.remote.verify_ssl,
|
|
56
|
-
),
|
|
57
50
|
"search_client": SearchClient(
|
|
58
51
|
base_url=app_context.remote.server_url or "",
|
|
59
52
|
api_key=app_context.remote.api_key,
|
kodit/config.py
CHANGED
|
@@ -14,9 +14,7 @@ import structlog
|
|
|
14
14
|
from pydantic import BaseModel, Field, field_validator
|
|
15
15
|
from pydantic_settings import (
|
|
16
16
|
BaseSettings,
|
|
17
|
-
EnvSettingsSource,
|
|
18
17
|
NoDecode,
|
|
19
|
-
PydanticBaseSettingsSource,
|
|
20
18
|
SettingsConfigDict,
|
|
21
19
|
)
|
|
22
20
|
|
|
@@ -68,9 +66,9 @@ class Endpoint(BaseModel):
|
|
|
68
66
|
default=None,
|
|
69
67
|
description="Unix socket path for local communication (e.g., /tmp/openai.sock)",
|
|
70
68
|
)
|
|
71
|
-
timeout: float
|
|
72
|
-
default=
|
|
73
|
-
description="Request timeout in seconds
|
|
69
|
+
timeout: float = Field(
|
|
70
|
+
default=60,
|
|
71
|
+
description="Request timeout in seconds",
|
|
74
72
|
)
|
|
75
73
|
extra_params: dict[str, Any] | None = Field(
|
|
76
74
|
default=None,
|
|
@@ -91,46 +89,12 @@ class Search(BaseModel):
|
|
|
91
89
|
provider: Literal["sqlite", "vectorchord"] = Field(default="sqlite")
|
|
92
90
|
|
|
93
91
|
|
|
94
|
-
class AutoIndexingSource(BaseModel):
|
|
95
|
-
"""Configuration for a single auto-indexing source."""
|
|
96
|
-
|
|
97
|
-
uri: str = Field(description="URI of the source to index (git URL or local path)")
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
class AutoIndexingConfig(BaseModel):
|
|
101
|
-
"""Configuration for auto-indexing."""
|
|
102
|
-
|
|
103
|
-
sources: list[AutoIndexingSource] = Field(
|
|
104
|
-
default_factory=list, description="List of sources to auto-index"
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
@field_validator("sources", mode="before")
|
|
108
|
-
@classmethod
|
|
109
|
-
def parse_sources(cls, v: Any) -> Any:
|
|
110
|
-
"""Parse sources from environment variables or other formats."""
|
|
111
|
-
if v is None:
|
|
112
|
-
return []
|
|
113
|
-
if isinstance(v, list):
|
|
114
|
-
return v
|
|
115
|
-
if isinstance(v, dict):
|
|
116
|
-
# Handle case where env vars are numbered keys like {'0': {'uri': '...'}}
|
|
117
|
-
sources = []
|
|
118
|
-
i = 0
|
|
119
|
-
while str(i) in v:
|
|
120
|
-
source_data = v[str(i)]
|
|
121
|
-
if isinstance(source_data, dict) and "uri" in source_data:
|
|
122
|
-
sources.append(AutoIndexingSource(uri=source_data["uri"]))
|
|
123
|
-
i += 1
|
|
124
|
-
return sources
|
|
125
|
-
return v
|
|
126
|
-
|
|
127
|
-
|
|
128
92
|
class PeriodicSyncConfig(BaseModel):
|
|
129
93
|
"""Configuration for periodic/scheduled syncing."""
|
|
130
94
|
|
|
131
95
|
enabled: bool = Field(default=True, description="Enable periodic sync")
|
|
132
96
|
interval_seconds: float = Field(
|
|
133
|
-
default=1800, description="Interval between
|
|
97
|
+
default=1800, description="Interval between periodic syncs in seconds"
|
|
134
98
|
)
|
|
135
99
|
retry_attempts: int = Field(
|
|
136
100
|
default=3, description="Number of retry attempts for failed syncs"
|
|
@@ -147,36 +111,6 @@ class RemoteConfig(BaseModel):
|
|
|
147
111
|
verify_ssl: bool = Field(default=True, description="Verify SSL certificates")
|
|
148
112
|
|
|
149
113
|
|
|
150
|
-
class CustomAutoIndexingEnvSource(EnvSettingsSource):
|
|
151
|
-
"""Custom environment source for parsing AutoIndexingConfig."""
|
|
152
|
-
|
|
153
|
-
def __call__(self) -> dict[str, Any]:
|
|
154
|
-
"""Load settings from env vars with custom auto-indexing parsing."""
|
|
155
|
-
d: dict[str, Any] = {}
|
|
156
|
-
|
|
157
|
-
# First get the standard env vars
|
|
158
|
-
env_vars = super().__call__()
|
|
159
|
-
d.update(env_vars)
|
|
160
|
-
|
|
161
|
-
# Custom parsing for auto-indexing sources
|
|
162
|
-
auto_indexing_sources = []
|
|
163
|
-
i = 0
|
|
164
|
-
while True:
|
|
165
|
-
# Note: env_vars keys are lowercase due to Pydantic Settings normalization
|
|
166
|
-
uri_key = f"auto_indexing_sources_{i}_uri"
|
|
167
|
-
if uri_key in self.env_vars:
|
|
168
|
-
uri_value = self.env_vars[uri_key]
|
|
169
|
-
auto_indexing_sources.append({"uri": uri_value})
|
|
170
|
-
i += 1
|
|
171
|
-
else:
|
|
172
|
-
break
|
|
173
|
-
|
|
174
|
-
if auto_indexing_sources:
|
|
175
|
-
d["auto_indexing"] = {"sources": auto_indexing_sources}
|
|
176
|
-
|
|
177
|
-
return d
|
|
178
|
-
|
|
179
|
-
|
|
180
114
|
class AppContext(BaseSettings):
|
|
181
115
|
"""Global context for the kodit project. Provides a shared state for the app."""
|
|
182
116
|
|
|
@@ -189,30 +123,6 @@ class AppContext(BaseSettings):
|
|
|
189
123
|
extra="ignore",
|
|
190
124
|
)
|
|
191
125
|
|
|
192
|
-
@classmethod
|
|
193
|
-
def settings_customise_sources(
|
|
194
|
-
cls,
|
|
195
|
-
settings_cls: type[BaseSettings],
|
|
196
|
-
init_settings: PydanticBaseSettingsSource,
|
|
197
|
-
env_settings: PydanticBaseSettingsSource, # noqa: ARG003
|
|
198
|
-
dotenv_settings: PydanticBaseSettingsSource,
|
|
199
|
-
file_secret_settings: PydanticBaseSettingsSource,
|
|
200
|
-
) -> tuple[PydanticBaseSettingsSource, ...]:
|
|
201
|
-
"""Customize settings sources to use custom auto-indexing parsing."""
|
|
202
|
-
custom_env_settings = CustomAutoIndexingEnvSource(
|
|
203
|
-
settings_cls,
|
|
204
|
-
env_nested_delimiter=settings_cls.model_config.get("env_nested_delimiter"),
|
|
205
|
-
env_ignore_empty=settings_cls.model_config.get("env_ignore_empty", False),
|
|
206
|
-
env_parse_none_str=settings_cls.model_config.get("env_parse_none_str", ""),
|
|
207
|
-
env_parse_enums=settings_cls.model_config.get("env_parse_enums", None),
|
|
208
|
-
)
|
|
209
|
-
return (
|
|
210
|
-
init_settings,
|
|
211
|
-
custom_env_settings,
|
|
212
|
-
dotenv_settings,
|
|
213
|
-
file_secret_settings,
|
|
214
|
-
)
|
|
215
|
-
|
|
216
126
|
data_dir: Path = Field(default=DEFAULT_BASE_DIR)
|
|
217
127
|
db_url: str = Field(
|
|
218
128
|
default_factory=lambda data: f"sqlite+aiosqlite:///{data['data_dir']}/kodit.db"
|
|
@@ -231,9 +141,6 @@ class AppContext(BaseSettings):
|
|
|
231
141
|
default_search: Search = Field(
|
|
232
142
|
default=Search(),
|
|
233
143
|
)
|
|
234
|
-
auto_indexing: AutoIndexingConfig | None = Field(
|
|
235
|
-
default=AutoIndexingConfig(), description="Auto-indexing configuration"
|
|
236
|
-
)
|
|
237
144
|
periodic_sync: PeriodicSyncConfig = Field(
|
|
238
145
|
default=PeriodicSyncConfig(), description="Periodic sync configuration"
|
|
239
146
|
)
|
kodit/database.py
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
7
|
import structlog
|
|
7
8
|
from alembic import command
|
|
8
9
|
from alembic.config import Config as AlembicConfig
|
|
10
|
+
from sqlalchemy import event
|
|
9
11
|
from sqlalchemy.ext.asyncio import (
|
|
10
12
|
AsyncSession,
|
|
11
13
|
async_sessionmaker,
|
|
@@ -21,7 +23,42 @@ class Database:
|
|
|
21
23
|
def __init__(self, db_url: str) -> None:
|
|
22
24
|
"""Initialize the database."""
|
|
23
25
|
self.log = structlog.get_logger(__name__)
|
|
24
|
-
|
|
26
|
+
|
|
27
|
+
# Configure SQLite-specific connection arguments to prevent locking issues
|
|
28
|
+
connect_args = {}
|
|
29
|
+
if "sqlite" in db_url.lower():
|
|
30
|
+
connect_args = {
|
|
31
|
+
"timeout": 20, # 20 second timeout for database operations
|
|
32
|
+
"check_same_thread": False, # Allow use from different threads
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
self.db_engine = create_async_engine(
|
|
36
|
+
db_url,
|
|
37
|
+
echo=False,
|
|
38
|
+
connect_args=connect_args,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Configure SQLite pragmas for better concurrency and performance
|
|
42
|
+
if "sqlite" in db_url.lower():
|
|
43
|
+
|
|
44
|
+
@event.listens_for(self.db_engine.sync_engine, "connect")
|
|
45
|
+
def set_sqlite_pragma(
|
|
46
|
+
dbapi_connection: Any, connection_record: Any
|
|
47
|
+
) -> None:
|
|
48
|
+
del (
|
|
49
|
+
connection_record
|
|
50
|
+
) # Unused but required by SQLAlchemy event interface
|
|
51
|
+
cursor = dbapi_connection.cursor()
|
|
52
|
+
# Enable WAL mode for better concurrency
|
|
53
|
+
cursor.execute("PRAGMA journal_mode=WAL")
|
|
54
|
+
# Set busy timeout to prevent immediate locking failures
|
|
55
|
+
cursor.execute("PRAGMA busy_timeout=20000")
|
|
56
|
+
# Enable foreign key constraints
|
|
57
|
+
cursor.execute("PRAGMA foreign_keys=ON")
|
|
58
|
+
# Optimize for speed over safety (acceptable for indexing workloads)
|
|
59
|
+
cursor.execute("PRAGMA synchronous=NORMAL")
|
|
60
|
+
cursor.close()
|
|
61
|
+
|
|
25
62
|
self.db_session_factory = async_sessionmaker(
|
|
26
63
|
self.db_engine,
|
|
27
64
|
class_=AsyncSession,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Enrichment domain package."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Architecture enrichment package."""
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Architecture enrichment domain entity."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from kodit.domain.enrichments.enrichment import (
|
|
7
|
+
CommitEnrichment,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
ENRICHMENT_TYPE_ARCHITECTURE = "architecture"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class ArchitectureEnrichment(CommitEnrichment, ABC):
|
|
15
|
+
"""Enrichment containing physical architecture discovery for a commit."""
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def type(self) -> str:
|
|
19
|
+
"""Return the enrichment type."""
|
|
20
|
+
return ENRICHMENT_TYPE_ARCHITECTURE
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Physical architecture enrichment package."""
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Physical architecture domain value objects."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class ArchitectureDiscoveryNotes:
|
|
8
|
+
"""Rich, narrative observations about repository architecture for LLM consumption.""" # noqa: E501
|
|
9
|
+
|
|
10
|
+
repository_context: str # High-level overview and discovery scope
|
|
11
|
+
component_observations: list[str] # Detailed findings about each component
|
|
12
|
+
connection_observations: list[str] # How components interact and communicate
|
|
13
|
+
infrastructure_observations: list[str] # Deployment, config, operational patterns
|
|
14
|
+
discovery_metadata: str # Methodology, confidence, limitations, timestamp
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Physical architecture formatter protocol."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Protocol
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PhysicalArchitectureFormatter(Protocol):
|
|
7
|
+
"""Formatter for converting architecture discovery notes to LLM-optimized text."""
|
|
8
|
+
|
|
9
|
+
def format_for_llm(self, notes: Any) -> str:
|
|
10
|
+
"""Format architecture discovery notes for LLM consumption."""
|
|
11
|
+
...
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Physical architecture enrichment domain entity."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from kodit.domain.enrichments.architecture.architecture import ArchitectureEnrichment
|
|
6
|
+
|
|
7
|
+
ENRICHMENT_SUBTYPE_PHYSICAL = "physical"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class PhysicalArchitectureEnrichment(ArchitectureEnrichment):
|
|
12
|
+
"""Enrichment containing physical architecture discovery for a commit."""
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def subtype(self) -> str | None:
|
|
16
|
+
"""Return the enrichment subtype."""
|
|
17
|
+
return ENRICHMENT_SUBTYPE_PHYSICAL
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Development enrichment package."""
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Development enrichment domain entity."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from kodit.domain.enrichments.enrichment import CommitEnrichment
|
|
7
|
+
|
|
8
|
+
ENRICHMENT_TYPE_DEVELOPMENT = "development"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class DevelopmentEnrichment(CommitEnrichment, ABC):
|
|
13
|
+
"""Enrichment containing development discovery for a commit."""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def type(self) -> str:
|
|
17
|
+
"""Return the enrichment type."""
|
|
18
|
+
return ENRICHMENT_TYPE_DEVELOPMENT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Snippet enrichment package."""
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Snippet enrichment domain entity."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from kodit.domain.enrichments.development.development import DevelopmentEnrichment
|
|
6
|
+
|
|
7
|
+
ENRICHMENT_SUBTYPE_SNIPPET_SUMMARY = "snippet_summary"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class SnippetEnrichment(DevelopmentEnrichment):
|
|
12
|
+
"""Enrichment specific to code snippets."""
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def subtype(self) -> str | None:
|
|
16
|
+
"""Return the enrichment subtype."""
|
|
17
|
+
return ENRICHMENT_SUBTYPE_SNIPPET_SUMMARY
|
|
18
|
+
|
|
19
|
+
def entity_type_key(self) -> str:
|
|
20
|
+
"""Return the entity type key this enrichment is for."""
|
|
21
|
+
return "snippet_v2"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Enricher interface."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import AsyncGenerator
|
|
4
|
+
from typing import Protocol
|
|
5
|
+
|
|
6
|
+
from kodit.domain.enrichments.request import EnrichmentRequest
|
|
7
|
+
from kodit.domain.enrichments.response import EnrichmentResponse
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Enricher(Protocol):
|
|
11
|
+
"""Interface for text enrichment with custom prompts."""
|
|
12
|
+
|
|
13
|
+
def enrich(
|
|
14
|
+
self, requests: list[EnrichmentRequest]
|
|
15
|
+
) -> AsyncGenerator[EnrichmentResponse, None]:
|
|
16
|
+
"""Enrich a list of requests with custom system prompts."""
|
|
17
|
+
...
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Enrichment domain entities."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class EnrichmentV2(ABC):
|
|
10
|
+
"""Generic enrichment that can be attached to any entity."""
|
|
11
|
+
|
|
12
|
+
entity_id: str
|
|
13
|
+
content: str = ""
|
|
14
|
+
id: int | None = None
|
|
15
|
+
created_at: datetime | None = None
|
|
16
|
+
updated_at: datetime | None = None
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def type(self) -> str:
|
|
21
|
+
"""Return the enrichment type."""
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def subtype(self) -> str | None:
|
|
26
|
+
"""Return the enrichment subtype (optional for hierarchical types)."""
|
|
27
|
+
|
|
28
|
+
@abstractmethod
|
|
29
|
+
def entity_type_key(self) -> str:
|
|
30
|
+
"""Return the entity type key this enrichment is for."""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class CommitEnrichment(EnrichmentV2, ABC):
|
|
35
|
+
"""Enrichment specific to commits."""
|
|
36
|
+
|
|
37
|
+
def entity_type_key(self) -> str:
|
|
38
|
+
"""Return the entity type key this enrichment is for."""
|
|
39
|
+
return "git_commit"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Usage enrichment domain entities."""
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""API documentation enrichment entity."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from kodit.domain.enrichments.usage.usage import UsageEnrichment
|
|
6
|
+
|
|
7
|
+
ENRICHMENT_SUBTYPE_API_DOCS = "api_docs"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class APIDocEnrichment(UsageEnrichment):
|
|
12
|
+
"""API documentation enrichment for a module."""
|
|
13
|
+
|
|
14
|
+
language: str = ""
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def subtype(self) -> str | None:
|
|
18
|
+
"""Return the enrichment subtype."""
|
|
19
|
+
return ENRICHMENT_SUBTYPE_API_DOCS
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Usage enrichment domain entity."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from kodit.domain.enrichments.enrichment import CommitEnrichment
|
|
7
|
+
|
|
8
|
+
ENRICHMENT_TYPE_USAGE = "usage"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class UsageEnrichment(CommitEnrichment, ABC):
|
|
13
|
+
"""Enrichment containing development discovery for a commit."""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def type(self) -> str:
|
|
17
|
+
"""Return the enrichment type."""
|
|
18
|
+
return ENRICHMENT_TYPE_USAGE
|