kodit 0.5.0__py3-none-any.whl → 0.5.2__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 +10 -12
- kodit/application/factories/server_factory.py +78 -11
- kodit/application/services/commit_indexing_application_service.py +188 -31
- kodit/application/services/enrichment_query_service.py +95 -0
- kodit/config.py +3 -3
- 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/protocols.py +7 -6
- kodit/domain/services/enrichment_service.py +9 -30
- kodit/domain/services/physical_architecture_service.py +182 -0
- kodit/domain/tracking/__init__.py +1 -0
- kodit/domain/tracking/resolution_service.py +81 -0
- kodit/domain/tracking/trackable.py +21 -0
- kodit/domain/value_objects.py +6 -23
- kodit/infrastructure/api/v1/dependencies.py +15 -0
- kodit/infrastructure/api/v1/routers/commits.py +81 -0
- kodit/infrastructure/api/v1/routers/repositories.py +99 -0
- kodit/infrastructure/api/v1/schemas/enrichment.py +29 -0
- kodit/infrastructure/cloning/git/git_python_adaptor.py +71 -4
- 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} +20 -33
- kodit/infrastructure/{enrichment/local_enrichment_provider.py → enricher/local_enricher.py} +19 -24
- kodit/infrastructure/enricher/null_enricher.py +36 -0
- kodit/infrastructure/mappers/enrichment_mapper.py +83 -0
- kodit/infrastructure/mappers/snippet_mapper.py +20 -22
- 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/slicing/api_doc_extractor.py +836 -0
- kodit/infrastructure/slicing/ast_analyzer.py +1128 -0
- kodit/infrastructure/slicing/slicer.py +56 -391
- kodit/infrastructure/sqlalchemy/enrichment_v2_repository.py +118 -0
- kodit/infrastructure/sqlalchemy/entities.py +46 -38
- kodit/infrastructure/sqlalchemy/git_branch_repository.py +22 -11
- kodit/infrastructure/sqlalchemy/git_commit_repository.py +23 -14
- kodit/infrastructure/sqlalchemy/git_repository.py +27 -17
- kodit/infrastructure/sqlalchemy/git_tag_repository.py +22 -11
- kodit/infrastructure/sqlalchemy/snippet_v2_repository.py +101 -106
- kodit/migrations/versions/19f8c7faf8b9_add_generic_enrichment_type.py +260 -0
- kodit/utils/dump_config.py +361 -0
- kodit/utils/dump_openapi.py +5 -6
- {kodit-0.5.0.dist-info → kodit-0.5.2.dist-info}/METADATA +1 -1
- {kodit-0.5.0.dist-info → kodit-0.5.2.dist-info}/RECORD +67 -32
- 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/{enrichment → enricher}/utils.py +0 -0
- {kodit-0.5.0.dist-info → kodit-0.5.2.dist-info}/WHEEL +0 -0
- {kodit-0.5.0.dist-info → kodit-0.5.2.dist-info}/entry_points.txt +0 -0
- {kodit-0.5.0.dist-info → kodit-0.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""Narrative formatter for converting observations to LLM-optimized text."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
from kodit.domain.enrichments.architecture.physical.discovery_notes import (
|
|
6
|
+
ArchitectureDiscoveryNotes,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NarrativeFormatter:
|
|
11
|
+
"""Formats architecture observations into narrative text optimized for LLM consumption.""" # noqa: E501
|
|
12
|
+
|
|
13
|
+
def format_for_llm(self, notes: ArchitectureDiscoveryNotes) -> str:
|
|
14
|
+
"""Convert discovery notes into a comprehensive narrative format."""
|
|
15
|
+
sections = []
|
|
16
|
+
|
|
17
|
+
# Title and overview
|
|
18
|
+
sections.append("# Physical Architecture Discovery Report")
|
|
19
|
+
sections.append("")
|
|
20
|
+
sections.append(notes.repository_context)
|
|
21
|
+
sections.append("")
|
|
22
|
+
|
|
23
|
+
# Component Analysis
|
|
24
|
+
self._add_component_section(sections, notes.component_observations)
|
|
25
|
+
|
|
26
|
+
# Connection Analysis
|
|
27
|
+
self._add_connection_section(sections, notes.connection_observations)
|
|
28
|
+
|
|
29
|
+
# Infrastructure Analysis
|
|
30
|
+
self._add_infrastructure_section(sections, notes.infrastructure_observations)
|
|
31
|
+
|
|
32
|
+
# Methodology
|
|
33
|
+
sections.append("## Discovery Methodology")
|
|
34
|
+
sections.append(notes.discovery_metadata)
|
|
35
|
+
sections.append("")
|
|
36
|
+
|
|
37
|
+
# Conclusion
|
|
38
|
+
self._add_conclusion_section(sections, notes)
|
|
39
|
+
|
|
40
|
+
return "\n".join(sections)
|
|
41
|
+
|
|
42
|
+
def _add_component_section(
|
|
43
|
+
self, sections: list[str], component_observations: list[str]
|
|
44
|
+
) -> None:
|
|
45
|
+
"""Add component observations section with proper formatting."""
|
|
46
|
+
sections.append("## Components")
|
|
47
|
+
sections.append("")
|
|
48
|
+
|
|
49
|
+
if component_observations:
|
|
50
|
+
for i, observation in enumerate(component_observations, 1):
|
|
51
|
+
sections.append(f"**{i}.** {observation}")
|
|
52
|
+
sections.append("")
|
|
53
|
+
|
|
54
|
+
# Extract and highlight port information
|
|
55
|
+
port_info = self._extract_port_information(component_observations)
|
|
56
|
+
if port_info:
|
|
57
|
+
sections.append("### Port Mappings")
|
|
58
|
+
sections.append("")
|
|
59
|
+
for component, ports_desc in port_info.items():
|
|
60
|
+
sections.append(f"- **{component}**: {ports_desc}")
|
|
61
|
+
sections.append("")
|
|
62
|
+
else:
|
|
63
|
+
sections.append("None. Likely monolithic or library architecture.")
|
|
64
|
+
sections.append("")
|
|
65
|
+
|
|
66
|
+
def _add_connection_section(
|
|
67
|
+
self, sections: list[str], connection_observations: list[str]
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Add connection observations section with proper formatting."""
|
|
70
|
+
sections.append("## Connections")
|
|
71
|
+
sections.append("")
|
|
72
|
+
|
|
73
|
+
if connection_observations:
|
|
74
|
+
for i, observation in enumerate(connection_observations, 1):
|
|
75
|
+
sections.append(f"**{i}.** {observation}")
|
|
76
|
+
sections.append("")
|
|
77
|
+
else:
|
|
78
|
+
sections.append("None. Possible monolithic or independent services.")
|
|
79
|
+
sections.append("")
|
|
80
|
+
|
|
81
|
+
def _add_infrastructure_section(
|
|
82
|
+
self, sections: list[str], infrastructure_observations: list[str]
|
|
83
|
+
) -> None:
|
|
84
|
+
"""Add infrastructure observations section with proper formatting."""
|
|
85
|
+
sections.append("## Infrastructure")
|
|
86
|
+
sections.append("")
|
|
87
|
+
|
|
88
|
+
if infrastructure_observations:
|
|
89
|
+
for i, observation in enumerate(infrastructure_observations, 1):
|
|
90
|
+
sections.append(f"**{i}.** {observation}")
|
|
91
|
+
sections.append("")
|
|
92
|
+
else:
|
|
93
|
+
sections.append("None. May use external or cloud-native deployment.")
|
|
94
|
+
sections.append("")
|
|
95
|
+
|
|
96
|
+
def _add_conclusion_section(
|
|
97
|
+
self, sections: list[str], notes: ArchitectureDiscoveryNotes
|
|
98
|
+
) -> None:
|
|
99
|
+
"""Add a conclusion section summarizing the findings."""
|
|
100
|
+
sections.append("## Summary")
|
|
101
|
+
sections.append("")
|
|
102
|
+
|
|
103
|
+
# Determine architecture characteristics
|
|
104
|
+
has_components = bool(notes.component_observations)
|
|
105
|
+
has_connections = bool(notes.connection_observations)
|
|
106
|
+
has_infrastructure = bool(notes.infrastructure_observations)
|
|
107
|
+
|
|
108
|
+
if has_components and has_connections and has_infrastructure:
|
|
109
|
+
arch_type = "distributed microservices"
|
|
110
|
+
complexity = "high"
|
|
111
|
+
elif has_components and (has_connections or has_infrastructure):
|
|
112
|
+
arch_type = "multi-component"
|
|
113
|
+
complexity = "medium"
|
|
114
|
+
elif has_components or has_infrastructure:
|
|
115
|
+
arch_type = "structured application"
|
|
116
|
+
complexity = "medium"
|
|
117
|
+
else:
|
|
118
|
+
arch_type = "monolithic"
|
|
119
|
+
complexity = "low"
|
|
120
|
+
|
|
121
|
+
sections.append(f"**Architecture:** {arch_type} | **Complexity:** {complexity}")
|
|
122
|
+
sections.append("")
|
|
123
|
+
sections.append("**Note:** Static analysis only. Runtime behavior may differ.")
|
|
124
|
+
|
|
125
|
+
def _extract_port_information(
|
|
126
|
+
self, component_observations: list[str]
|
|
127
|
+
) -> dict[str, str]:
|
|
128
|
+
"""Extract port information from component observations."""
|
|
129
|
+
port_info = {}
|
|
130
|
+
|
|
131
|
+
# Pattern to extract service name and port information
|
|
132
|
+
service_pattern = r"Found '([^']+)' service"
|
|
133
|
+
port_pattern = r"Exposes ports ([\d, ]+)(?: suggesting ([^.]+))?"
|
|
134
|
+
|
|
135
|
+
for observation in component_observations:
|
|
136
|
+
service_match = re.search(service_pattern, observation)
|
|
137
|
+
port_match = re.search(port_pattern, observation)
|
|
138
|
+
|
|
139
|
+
if service_match and port_match:
|
|
140
|
+
service_name = service_match.group(1)
|
|
141
|
+
ports = port_match.group(1).strip()
|
|
142
|
+
protocol = port_match.group(2)
|
|
143
|
+
|
|
144
|
+
if protocol:
|
|
145
|
+
port_info[service_name] = f"{ports} ({protocol})"
|
|
146
|
+
else:
|
|
147
|
+
port_info[service_name] = ports
|
|
148
|
+
|
|
149
|
+
return port_info
|