kodit 0.3.16__py3-none-any.whl → 0.4.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.
Potentially problematic release.
This version of kodit might be problematic. Click here for more details.
- kodit/_version.py +3 -16
- kodit/app.py +11 -2
- kodit/application/services/auto_indexing_service.py +16 -7
- kodit/application/services/indexing_worker_service.py +154 -0
- kodit/application/services/queue_service.py +52 -0
- kodit/application/services/sync_scheduler.py +10 -48
- kodit/cli.py +407 -148
- kodit/cli_utils.py +74 -0
- kodit/config.py +33 -3
- kodit/domain/entities.py +48 -1
- kodit/domain/protocols.py +29 -2
- kodit/domain/value_objects.py +13 -0
- kodit/infrastructure/api/client/__init__.py +14 -0
- kodit/infrastructure/api/client/base.py +100 -0
- kodit/infrastructure/api/client/exceptions.py +21 -0
- kodit/infrastructure/api/client/generated_endpoints.py +27 -0
- kodit/infrastructure/api/client/index_client.py +57 -0
- kodit/infrastructure/api/client/search_client.py +86 -0
- kodit/infrastructure/api/v1/dependencies.py +13 -0
- kodit/infrastructure/api/v1/routers/indexes.py +9 -4
- kodit/infrastructure/enrichment/local_enrichment_provider.py +4 -1
- kodit/infrastructure/enrichment/openai_enrichment_provider.py +5 -1
- kodit/infrastructure/enrichment/utils.py +30 -0
- kodit/infrastructure/mappers/task_mapper.py +81 -0
- kodit/infrastructure/sqlalchemy/entities.py +35 -0
- kodit/infrastructure/sqlalchemy/task_repository.py +81 -0
- kodit/migrations/versions/9cf0e87de578_add_queue.py +47 -0
- kodit/utils/generate_api_paths.py +135 -0
- {kodit-0.3.16.dist-info → kodit-0.4.0.dist-info}/METADATA +1 -1
- {kodit-0.3.16.dist-info → kodit-0.4.0.dist-info}/RECORD +33 -19
- {kodit-0.3.16.dist-info → kodit-0.4.0.dist-info}/WHEEL +0 -0
- {kodit-0.3.16.dist-info → kodit-0.4.0.dist-info}/entry_points.txt +0 -0
- {kodit-0.3.16.dist-info → kodit-0.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Utility functions for enrichment processing."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def clean_thinking_tags(content: str) -> str:
|
|
7
|
+
"""Remove <think>...</think> tags from content.
|
|
8
|
+
|
|
9
|
+
This utility handles thinking tags that may be produced by various AI models,
|
|
10
|
+
including both local and remote models. It safely removes thinking content
|
|
11
|
+
while preserving the actual response.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
content: The content that may contain thinking tags.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
The content with thinking tags removed and cleaned up.
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
if not content:
|
|
21
|
+
return content
|
|
22
|
+
|
|
23
|
+
# Remove thinking tags using regex with DOTALL flag to match across newlines
|
|
24
|
+
cleaned = re.sub(
|
|
25
|
+
r"<think>.*?</think>", "", content, flags=re.DOTALL | re.IGNORECASE
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Clean up extra whitespace that may be left behind
|
|
29
|
+
cleaned = re.sub(r"\n\s*\n\s*\n", "\n\n", cleaned)
|
|
30
|
+
return cleaned.strip() # Remove leading/trailing whitespace
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Task mapper for the task queue."""
|
|
2
|
+
|
|
3
|
+
from typing import ClassVar
|
|
4
|
+
|
|
5
|
+
from kodit.domain.entities import Task
|
|
6
|
+
from kodit.domain.value_objects import TaskType
|
|
7
|
+
from kodit.infrastructure.sqlalchemy import entities as db_entities
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TaskTypeMapper:
|
|
11
|
+
"""Maps between domain QueuedTaskType and SQLAlchemy TaskType."""
|
|
12
|
+
|
|
13
|
+
# Map TaskType enum to QueuedTaskType
|
|
14
|
+
TASK_TYPE_MAPPING: ClassVar[dict[db_entities.TaskType, TaskType]] = {
|
|
15
|
+
db_entities.TaskType.INDEX_UPDATE: TaskType.INDEX_UPDATE,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def to_domain_type(task_type: db_entities.TaskType) -> TaskType:
|
|
20
|
+
"""Convert SQLAlchemy TaskType to domain QueuedTaskType."""
|
|
21
|
+
if task_type not in TaskTypeMapper.TASK_TYPE_MAPPING:
|
|
22
|
+
raise ValueError(f"Unknown task type: {task_type}")
|
|
23
|
+
return TaskTypeMapper.TASK_TYPE_MAPPING[task_type]
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def from_domain_type(task_type: TaskType) -> db_entities.TaskType:
|
|
27
|
+
"""Convert domain QueuedTaskType to SQLAlchemy TaskType."""
|
|
28
|
+
if task_type not in TaskTypeMapper.TASK_TYPE_MAPPING.values():
|
|
29
|
+
raise ValueError(f"Unknown task type: {task_type}")
|
|
30
|
+
|
|
31
|
+
# Find value in TASK_TYPE_MAPPING
|
|
32
|
+
return next(
|
|
33
|
+
(
|
|
34
|
+
db_task_type
|
|
35
|
+
for db_task_type, domain_task_type in TaskTypeMapper.TASK_TYPE_MAPPING.items() # noqa: E501
|
|
36
|
+
if domain_task_type == task_type
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TaskMapper:
|
|
42
|
+
"""Maps between domain QueuedTask and SQLAlchemy Task entities.
|
|
43
|
+
|
|
44
|
+
This mapper handles the conversion between the existing domain and
|
|
45
|
+
persistence layers without creating any new entities.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def to_domain_task(record: db_entities.Task) -> Task:
|
|
50
|
+
"""Convert SQLAlchemy Task record to domain QueuedTask.
|
|
51
|
+
|
|
52
|
+
Since QueuedTask doesn't have status fields, we store processing
|
|
53
|
+
state in the payload.
|
|
54
|
+
"""
|
|
55
|
+
# Get the task type
|
|
56
|
+
task_type = TaskTypeMapper.to_domain_type(record.type)
|
|
57
|
+
|
|
58
|
+
# The dedup_key becomes the id in the domain entity
|
|
59
|
+
return Task(
|
|
60
|
+
id=record.dedup_key, # Use dedup_key as the unique identifier
|
|
61
|
+
type=task_type,
|
|
62
|
+
priority=record.priority,
|
|
63
|
+
payload=record.payload or {},
|
|
64
|
+
created_at=record.created_at,
|
|
65
|
+
updated_at=record.updated_at,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def from_domain_task(task: Task) -> db_entities.Task:
|
|
70
|
+
"""Convert domain QueuedTask to SQLAlchemy Task record."""
|
|
71
|
+
if task.type not in TaskTypeMapper.TASK_TYPE_MAPPING.values():
|
|
72
|
+
raise ValueError(f"Unknown task type: {task.type}")
|
|
73
|
+
|
|
74
|
+
# Find value in TASK_TYPE_MAPPING
|
|
75
|
+
task_type = TaskTypeMapper.from_domain_type(task.type)
|
|
76
|
+
return db_entities.Task(
|
|
77
|
+
dedup_key=task.id,
|
|
78
|
+
type=task_type,
|
|
79
|
+
payload=task.payload,
|
|
80
|
+
priority=task.priority,
|
|
81
|
+
)
|
|
@@ -201,3 +201,38 @@ class Snippet(Base, CommonMixin):
|
|
|
201
201
|
self.index_id = index_id
|
|
202
202
|
self.content = content
|
|
203
203
|
self.summary = summary
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class TaskType(Enum):
|
|
207
|
+
"""Task type."""
|
|
208
|
+
|
|
209
|
+
INDEX_UPDATE = 1
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class Task(Base, CommonMixin):
|
|
213
|
+
"""Queued tasks."""
|
|
214
|
+
|
|
215
|
+
__tablename__ = "tasks"
|
|
216
|
+
|
|
217
|
+
# dedup_key is used to deduplicate items in the queue
|
|
218
|
+
dedup_key: Mapped[str] = mapped_column(String(255), index=True)
|
|
219
|
+
# type represents what the task is meant to achieve
|
|
220
|
+
type: Mapped[TaskType] = mapped_column(SQLAlchemyEnum(TaskType), index=True)
|
|
221
|
+
# payload contains the task-specific payload data
|
|
222
|
+
payload: Mapped[dict] = mapped_column(JSON)
|
|
223
|
+
# priority is used to determine the order of the items in the queue
|
|
224
|
+
priority: Mapped[int] = mapped_column(Integer)
|
|
225
|
+
|
|
226
|
+
def __init__(
|
|
227
|
+
self,
|
|
228
|
+
dedup_key: str,
|
|
229
|
+
type: TaskType, # noqa: A002
|
|
230
|
+
payload: dict,
|
|
231
|
+
priority: int,
|
|
232
|
+
) -> None:
|
|
233
|
+
"""Initialize the queue item."""
|
|
234
|
+
super().__init__()
|
|
235
|
+
self.dedup_key = dedup_key
|
|
236
|
+
self.type = type
|
|
237
|
+
self.payload = payload
|
|
238
|
+
self.priority = priority
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Task repository for the task queue."""
|
|
2
|
+
|
|
3
|
+
import structlog
|
|
4
|
+
from sqlalchemy import select
|
|
5
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
6
|
+
|
|
7
|
+
from kodit.domain.entities import Task
|
|
8
|
+
from kodit.domain.protocols import TaskRepository
|
|
9
|
+
from kodit.domain.value_objects import TaskType
|
|
10
|
+
from kodit.infrastructure.mappers.task_mapper import TaskMapper, TaskTypeMapper
|
|
11
|
+
from kodit.infrastructure.sqlalchemy import entities as db_entities
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SqlAlchemyTaskRepository(TaskRepository):
|
|
15
|
+
"""Repository for task persistence using the existing Task entity."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, session: AsyncSession) -> None:
|
|
18
|
+
"""Initialize the repository."""
|
|
19
|
+
self.session = session
|
|
20
|
+
self.log = structlog.get_logger(__name__)
|
|
21
|
+
|
|
22
|
+
async def add(
|
|
23
|
+
self,
|
|
24
|
+
task: Task,
|
|
25
|
+
) -> None:
|
|
26
|
+
"""Create a new task in the database."""
|
|
27
|
+
self.session.add(TaskMapper.from_domain_task(task))
|
|
28
|
+
|
|
29
|
+
async def get(self, task_id: str) -> Task | None:
|
|
30
|
+
"""Get a task by ID."""
|
|
31
|
+
stmt = select(db_entities.Task).where(db_entities.Task.dedup_key == task_id)
|
|
32
|
+
result = await self.session.execute(stmt)
|
|
33
|
+
db_task = result.scalar_one_or_none()
|
|
34
|
+
if not db_task:
|
|
35
|
+
return None
|
|
36
|
+
return TaskMapper.to_domain_task(db_task)
|
|
37
|
+
|
|
38
|
+
async def take(self) -> Task | None:
|
|
39
|
+
"""Take a task for processing and remove it from the database."""
|
|
40
|
+
stmt = (
|
|
41
|
+
select(db_entities.Task)
|
|
42
|
+
.order_by(db_entities.Task.priority.desc(), db_entities.Task.created_at)
|
|
43
|
+
.limit(1)
|
|
44
|
+
)
|
|
45
|
+
result = await self.session.execute(stmt)
|
|
46
|
+
db_task = result.scalar_one_or_none()
|
|
47
|
+
if not db_task:
|
|
48
|
+
return None
|
|
49
|
+
await self.session.delete(db_task)
|
|
50
|
+
return TaskMapper.to_domain_task(db_task)
|
|
51
|
+
|
|
52
|
+
async def update(self, task: Task) -> None:
|
|
53
|
+
"""Update a task in the database."""
|
|
54
|
+
stmt = select(db_entities.Task).where(db_entities.Task.dedup_key == task.id)
|
|
55
|
+
result = await self.session.execute(stmt)
|
|
56
|
+
db_task = result.scalar_one_or_none()
|
|
57
|
+
|
|
58
|
+
if not db_task:
|
|
59
|
+
raise ValueError(f"Task not found: {task.id}")
|
|
60
|
+
|
|
61
|
+
db_task.priority = task.priority
|
|
62
|
+
db_task.payload = task.payload
|
|
63
|
+
|
|
64
|
+
async def list(self, task_type: TaskType | None = None) -> list[Task]:
|
|
65
|
+
"""List tasks with optional status filter."""
|
|
66
|
+
stmt = select(db_entities.Task)
|
|
67
|
+
|
|
68
|
+
if task_type:
|
|
69
|
+
stmt = stmt.where(
|
|
70
|
+
db_entities.Task.type == TaskTypeMapper.from_domain_type(task_type)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
stmt = stmt.order_by(
|
|
74
|
+
db_entities.Task.priority.desc(), db_entities.Task.created_at
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
result = await self.session.execute(stmt)
|
|
78
|
+
records = result.scalars().all()
|
|
79
|
+
|
|
80
|
+
# Convert to domain entities
|
|
81
|
+
return [TaskMapper.to_domain_task(record) for record in records]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# ruff: noqa
|
|
2
|
+
"""add queue
|
|
3
|
+
|
|
4
|
+
Revision ID: 9cf0e87de578
|
|
5
|
+
Revises: 4073b33f9436
|
|
6
|
+
Create Date: 2025-08-06 17:38:21.055235
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Sequence, Union
|
|
11
|
+
|
|
12
|
+
from alembic import op
|
|
13
|
+
import sqlalchemy as sa
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# revision identifiers, used by Alembic.
|
|
17
|
+
revision: str = '9cf0e87de578'
|
|
18
|
+
down_revision: Union[str, None] = '4073b33f9436'
|
|
19
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
|
20
|
+
depends_on: Union[str, Sequence[str], None] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def upgrade() -> None:
|
|
24
|
+
"""Upgrade schema."""
|
|
25
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
26
|
+
op.create_table('tasks',
|
|
27
|
+
sa.Column('dedup_key', sa.String(length=255), nullable=False),
|
|
28
|
+
sa.Column('type', sa.Enum('INDEX_UPDATE', name='tasktype'), nullable=False),
|
|
29
|
+
sa.Column('payload', sa.JSON(), nullable=False),
|
|
30
|
+
sa.Column('priority', sa.Integer(), nullable=False),
|
|
31
|
+
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
|
32
|
+
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
|
33
|
+
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
|
|
34
|
+
sa.PrimaryKeyConstraint('id')
|
|
35
|
+
)
|
|
36
|
+
op.create_index(op.f('ix_tasks_dedup_key'), 'tasks', ['dedup_key'], unique=False)
|
|
37
|
+
op.create_index(op.f('ix_tasks_type'), 'tasks', ['type'], unique=False)
|
|
38
|
+
# ### end Alembic commands ###
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def downgrade() -> None:
|
|
42
|
+
"""Downgrade schema."""
|
|
43
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
44
|
+
op.drop_index(op.f('ix_tasks_type'), table_name='tasks')
|
|
45
|
+
op.drop_index(op.f('ix_tasks_dedup_key'), table_name='tasks')
|
|
46
|
+
op.drop_table('tasks')
|
|
47
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate API path constants from OpenAPI specification."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def to_python_constant(path: str) -> str:
|
|
10
|
+
"""Convert API path to Python constant name.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
path: API path like '/api/v1/indexes' or '/api/v1/indexes/{index_id}'
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
Python constant name like 'API_V1_INDEXES' or 'API_V1_INDEXES_INDEX_ID'
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
import re
|
|
20
|
+
|
|
21
|
+
# Replace any non-alphanumeric characters with underscores and convert to uppercase
|
|
22
|
+
clean_path = re.sub(r"[^a-zA-Z0-9]", "_", path)
|
|
23
|
+
clean_path = clean_path.strip("_").upper()
|
|
24
|
+
|
|
25
|
+
# Remove consecutive underscores
|
|
26
|
+
clean_path = re.sub(r"_+", "_", clean_path)
|
|
27
|
+
|
|
28
|
+
return clean_path or "ROOT"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def generate_api_paths_file(openapi_spec_path: Path, output_path: Path) -> None:
|
|
32
|
+
"""Generate Python file with API path constants from OpenAPI spec.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
openapi_spec_path: Path to the OpenAPI JSON specification
|
|
36
|
+
output_path: Path where to write the generated Python file
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
with openapi_spec_path.open() as f:
|
|
40
|
+
spec = json.load(f)
|
|
41
|
+
|
|
42
|
+
paths = spec.get("paths", {})
|
|
43
|
+
|
|
44
|
+
# Sort paths for consistent output
|
|
45
|
+
sorted_paths = sorted(paths.keys())
|
|
46
|
+
|
|
47
|
+
# Generate Python constants
|
|
48
|
+
constants = []
|
|
49
|
+
for path in sorted_paths:
|
|
50
|
+
constant_name = to_python_constant(path)
|
|
51
|
+
constants.append((constant_name, path))
|
|
52
|
+
|
|
53
|
+
# Generate the Python file content
|
|
54
|
+
content = generate_python_file_content(constants, openapi_spec_path)
|
|
55
|
+
|
|
56
|
+
# Write the file
|
|
57
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
with output_path.open("w") as f:
|
|
59
|
+
f.write(content)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def generate_python_file_content(
|
|
64
|
+
constants: list[tuple[str, str]], spec_path: Path
|
|
65
|
+
) -> str:
|
|
66
|
+
"""Generate the content of the Python API paths file.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
constants: List of (constant_name, path_value) tuples
|
|
70
|
+
spec_path: Path to the OpenAPI spec (for documentation)
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Generated Python file content
|
|
74
|
+
|
|
75
|
+
"""
|
|
76
|
+
# Header
|
|
77
|
+
content = '''"""API endpoint constants generated from OpenAPI specification.
|
|
78
|
+
|
|
79
|
+
This file is auto-generated. Do not edit manually.
|
|
80
|
+
Run `make generate-api-paths` to regenerate.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
from typing import Final
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class APIEndpoints:
|
|
87
|
+
"""API endpoint constants extracted from OpenAPI specification."""
|
|
88
|
+
|
|
89
|
+
'''
|
|
90
|
+
|
|
91
|
+
# Add constants with comments
|
|
92
|
+
for constant_name, path_value in constants:
|
|
93
|
+
# Add a comment describing the endpoint
|
|
94
|
+
comment = f" # {path_value}"
|
|
95
|
+
constant = f' {constant_name}: Final[str] = "{path_value}"'
|
|
96
|
+
|
|
97
|
+
content += f"{comment}\n{constant}\n\n"
|
|
98
|
+
|
|
99
|
+
# Add footer comment
|
|
100
|
+
content += f"""
|
|
101
|
+
# Generated from: {spec_path.name}
|
|
102
|
+
# Total endpoints: {len(constants)}
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
return content
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def main() -> None:
|
|
109
|
+
"""Generate API path constants from OpenAPI specification."""
|
|
110
|
+
parser = argparse.ArgumentParser(
|
|
111
|
+
description="Generate API path constants from OpenAPI specification"
|
|
112
|
+
)
|
|
113
|
+
parser.add_argument(
|
|
114
|
+
"--openapi-spec",
|
|
115
|
+
type=Path,
|
|
116
|
+
default=Path("docs/reference/api/openapi.json"),
|
|
117
|
+
help="Path to OpenAPI JSON specification file"
|
|
118
|
+
)
|
|
119
|
+
parser.add_argument(
|
|
120
|
+
"--output",
|
|
121
|
+
type=Path,
|
|
122
|
+
default=Path("src/kodit/infrastructure/api/client/generated_endpoints.py"),
|
|
123
|
+
help="Output path for generated Python file"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
args = parser.parse_args()
|
|
127
|
+
|
|
128
|
+
if not args.openapi_spec.exists():
|
|
129
|
+
return
|
|
130
|
+
|
|
131
|
+
generate_api_paths_file(args.openapi_spec, args.output)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
if __name__ == "__main__":
|
|
135
|
+
main()
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
kodit/.gitignore,sha256=ztkjgRwL9Uud1OEi36hGQeDGk3OLK1NfDEO8YqGYy8o,11
|
|
2
2
|
kodit/__init__.py,sha256=aEKHYninUq1yh6jaNfvJBYg-6fenpN132nJt1UU6Jxs,59
|
|
3
|
-
kodit/_version.py,sha256=
|
|
4
|
-
kodit/app.py,sha256=
|
|
5
|
-
kodit/cli.py,sha256=
|
|
6
|
-
kodit/
|
|
3
|
+
kodit/_version.py,sha256=l5eo51MdCumDFCp44TFT1JH8yCDo1krag-GJubLxnVo,511
|
|
4
|
+
kodit/app.py,sha256=r0w0JJsOacrQ5aAQ1yf-BK1CrYZPrvtUoH1LACd9FaA,4262
|
|
5
|
+
kodit/cli.py,sha256=VUZD4cPRgAnrKEWUl2PbS-nOA0FkDVqmJ2SR0g1yJsk,28202
|
|
6
|
+
kodit/cli_utils.py,sha256=bW4rIm-elrsyM_pSGHh30zV0_oX7V-64pL3YSaBcOt0,2810
|
|
7
|
+
kodit/config.py,sha256=YYo36lBi3auCssyCVrpw3Z3ZXSzXKTDo45nIsUjkzfs,10305
|
|
7
8
|
kodit/database.py,sha256=kI9yBm4uunsgV4-QeVoCBL0wLzU4kYmYv5qZilGnbPE,1740
|
|
8
9
|
kodit/log.py,sha256=XyuseZk90gUBj1B7np2UO2EW9eE_ApayIpPRvI19KCE,8651
|
|
9
10
|
kodit/mcp.py,sha256=aEcPc8dQiZaR0AswCZZNxcm_rhhUZNsEBimYti0ibSI,7221
|
|
@@ -13,15 +14,17 @@ kodit/application/__init__.py,sha256=mH50wTpgP9dhbKztFsL8Dda9Hi18TSnMVxXtpp4aGOA
|
|
|
13
14
|
kodit/application/factories/__init__.py,sha256=bU5CvEnaBePZ7JbkCOp1MGTNP752bnU2uEqmfy5FdRk,37
|
|
14
15
|
kodit/application/factories/code_indexing_factory.py,sha256=R9f0wsj4-3NJFS5SEt_-OIGR_s_01gJXaL3PkZd8MlU,5911
|
|
15
16
|
kodit/application/services/__init__.py,sha256=p5UQNw-H5sxQvs5Etfte93B3cJ1kKW6DNxK34uFvU1E,38
|
|
16
|
-
kodit/application/services/auto_indexing_service.py,sha256=
|
|
17
|
+
kodit/application/services/auto_indexing_service.py,sha256=O5BNR5HypgghzUFG4ykIWMl9mxHCUExnBmJuITIhECk,3457
|
|
17
18
|
kodit/application/services/code_indexing_application_service.py,sha256=nrnd_Md-D0AfNKku7Aqt3YHDbXsBV9f44Z6XsjhiF3E,15877
|
|
18
|
-
kodit/application/services/
|
|
19
|
+
kodit/application/services/indexing_worker_service.py,sha256=Un4PytnWJU4uwROcxOMUFkt4cD7nmPezaBLsEHrMN6U,5185
|
|
20
|
+
kodit/application/services/queue_service.py,sha256=GaixRoCUaDhLYfwZLVED8C3w_NPiy_QbuVp_jhwP4GI,1727
|
|
21
|
+
kodit/application/services/sync_scheduler.py,sha256=aLpEczZdTM8ubfAEY0Ajdh3MLfDcB9s-0ILZJrtIuZs,3504
|
|
19
22
|
kodit/domain/__init__.py,sha256=TCpg4Xx-oF4mKV91lo4iXqMEfBT1OoRSYnbG-zVWolA,66
|
|
20
|
-
kodit/domain/entities.py,sha256=
|
|
23
|
+
kodit/domain/entities.py,sha256=QsCzKXT7gF9jTPAjJo5lqjFGRsIklAFC2qRy_Gt3RbA,10377
|
|
21
24
|
kodit/domain/errors.py,sha256=yIsgCjM_yOFIg8l7l-t7jM8pgeAX4cfPq0owf7iz3DA,106
|
|
22
25
|
kodit/domain/interfaces.py,sha256=Jkd0Ob4qSvhZHI9jRPFQ1n5Cv0SvU-y3Z-HCw2ikc4I,742
|
|
23
|
-
kodit/domain/protocols.py,sha256=
|
|
24
|
-
kodit/domain/value_objects.py,sha256=
|
|
26
|
+
kodit/domain/protocols.py,sha256=GA0CCvmhvQ3F4MseeQUVw3NeIgUoaV7V_7TdAaU70Is,2587
|
|
27
|
+
kodit/domain/value_objects.py,sha256=dkfbg99PSCrfj6nJ7tZ2UzDG3QUgNa_Cpj2gLakDM5k,17512
|
|
25
28
|
kodit/domain/services/__init__.py,sha256=Q1GhCK_PqKHYwYE4tkwDz5BIyXkJngLBBOHhzvX8nzo,42
|
|
26
29
|
kodit/domain/services/bm25_service.py,sha256=nsfTan3XtDwXuuAu1LUv-6Jukm6qFKVqqCVymjyepZQ,3625
|
|
27
30
|
kodit/domain/services/embedding_service.py,sha256=7drYRC2kjg0WJmo06a2E9N0vDnwInUlBB96twjz2BT8,4526
|
|
@@ -30,12 +33,18 @@ kodit/domain/services/index_query_service.py,sha256=cDQkgpJ3JbyeZ3z3GTIqH1JzhhKE
|
|
|
30
33
|
kodit/domain/services/index_service.py,sha256=uVwDUEQWfZ5yJRvcjaWW7P9gCZttmnlkI51IHz52eew,11554
|
|
31
34
|
kodit/infrastructure/__init__.py,sha256=HzEYIjoXnkz_i_MHO2e0sIVYweUcRnl2RpyBiTbMObU,28
|
|
32
35
|
kodit/infrastructure/api/__init__.py,sha256=U0TSMPpHrlj1zbAtleuZjU3nXGwudyMe-veNBgvODwM,34
|
|
36
|
+
kodit/infrastructure/api/client/__init__.py,sha256=6RSYqeuxjDe_zTUq48D0F-VfBBUvDmTkO3K3vD61q3I,349
|
|
37
|
+
kodit/infrastructure/api/client/base.py,sha256=CIx0Cth8u845T1_6Q71Nj8BkXnh9m_v6d7OlJsZQsyQ,3105
|
|
38
|
+
kodit/infrastructure/api/client/exceptions.py,sha256=wK1OGiImIbNW-fz1juOExd5pKmkKK-xDhI_YFj4Q5Ic,401
|
|
39
|
+
kodit/infrastructure/api/client/generated_endpoints.py,sha256=8qhAg_gDuHsH_nKqGLialZCmEEuDDjLtSnEr-za82XU,641
|
|
40
|
+
kodit/infrastructure/api/client/index_client.py,sha256=OxsakDQBEulwmqZVzwOSSI0Lk6T6SLhfw6WquGoTFqY,1864
|
|
41
|
+
kodit/infrastructure/api/client/search_client.py,sha256=f4mM5ZJpAuR7w-i9yASbh4SYMxOq7_f4hXgaQesGquI,2614
|
|
33
42
|
kodit/infrastructure/api/middleware/__init__.py,sha256=6m7eE5k5buboJbuzyX5E9-Tf99yNwFaeJF0f_6HwLyM,30
|
|
34
43
|
kodit/infrastructure/api/middleware/auth.py,sha256=QSnMcMLWvfumqN1iG4ePj2vEZb2Dlsgr-WHptkEkkhE,1064
|
|
35
44
|
kodit/infrastructure/api/v1/__init__.py,sha256=XYv4_9Z6fo69oMvC2mEbtD6DaMqHth29KHUOelmQFwM,121
|
|
36
|
-
kodit/infrastructure/api/v1/dependencies.py,sha256=
|
|
45
|
+
kodit/infrastructure/api/v1/dependencies.py,sha256=jaM000IfSnvU8uzwnC1cBZsfsMC-19jWFjObHfqBYuM,2475
|
|
37
46
|
kodit/infrastructure/api/v1/routers/__init__.py,sha256=L8hT_SkDzmCXIiWrFQWCkZXQ3UDy_ZMxPr8AIhjSWK0,160
|
|
38
|
-
kodit/infrastructure/api/v1/routers/indexes.py,sha256=
|
|
47
|
+
kodit/infrastructure/api/v1/routers/indexes.py,sha256=_lUir1M0SW6kPHeGqjiPjtSa50rY4PN2es5TZEpSHYE,3442
|
|
39
48
|
kodit/infrastructure/api/v1/routers/search.py,sha256=da9YTR6VTzU85_6X3aaZemdTHGCEvcPNeKuMFBgmT_A,2452
|
|
40
49
|
kodit/infrastructure/api/v1/schemas/__init__.py,sha256=_5BVqv4EUi_vvWlAQOE_VfRulUDAF21ZQ7z27y7YOdw,498
|
|
41
50
|
kodit/infrastructure/api/v1/schemas/context.py,sha256=NlsIn9j1R3se7JkGZivS_CUN4gGP5NYaAtkRe3QH6dk,214
|
|
@@ -60,9 +69,10 @@ kodit/infrastructure/embedding/embedding_providers/local_embedding_provider.py,s
|
|
|
60
69
|
kodit/infrastructure/embedding/embedding_providers/openai_embedding_provider.py,sha256=CE86s8IicieUjIDWn2xzswteHXCzmw1Qz6Kp4GBIcus,6316
|
|
61
70
|
kodit/infrastructure/enrichment/__init__.py,sha256=8acZKNzql8Fs0lceFu9U3KoUrOptRBtVIxr_Iw6lz3Y,40
|
|
62
71
|
kodit/infrastructure/enrichment/enrichment_factory.py,sha256=jZWGgAvFjEuRUc1oW3iGhgipvX-EnVJZpw6ybzp9NGM,2016
|
|
63
|
-
kodit/infrastructure/enrichment/local_enrichment_provider.py,sha256=
|
|
72
|
+
kodit/infrastructure/enrichment/local_enrichment_provider.py,sha256=aVU3_kbLJ0BihwGIwvJ00DBe0voHkiKdFSjPxxkVfVA,4150
|
|
64
73
|
kodit/infrastructure/enrichment/null_enrichment_provider.py,sha256=DhZkJBnkvXg_XSAs-oKiFnKqYFPnmTl3ikdxrqeEfbc,713
|
|
65
|
-
kodit/infrastructure/enrichment/openai_enrichment_provider.py,sha256=
|
|
74
|
+
kodit/infrastructure/enrichment/openai_enrichment_provider.py,sha256=C0y0NEPu1GpFr22TGi1voxYGsYTV0ZITYuDzvRJ5vW4,5573
|
|
75
|
+
kodit/infrastructure/enrichment/utils.py,sha256=FE9UCuxxzSdoHrmAC8Si2b5D6Nf6kVqgM1yjUVyCvW0,930
|
|
66
76
|
kodit/infrastructure/git/__init__.py,sha256=0iMosFzudj4_xNIMe2SRbV6l5bWqkjnUsZoFsoZFuM8,33
|
|
67
77
|
kodit/infrastructure/git/git_utils.py,sha256=KERwmhWDR4ooMQKS-nSPxjvdCzoWF9NS6nhdeXyzdtY,571
|
|
68
78
|
kodit/infrastructure/ignore/__init__.py,sha256=VzFv8XOzHmsu0MEGnWVSF6KsgqLBmvHlRqAkT1Xb1MY,36
|
|
@@ -71,13 +81,15 @@ kodit/infrastructure/indexing/__init__.py,sha256=7UPRa2jwCAsa0Orsp6PqXSF8iIXJVzX
|
|
|
71
81
|
kodit/infrastructure/indexing/fusion_service.py,sha256=2B0guBsuKz19uWcs18sIJpUJPzXoRvULgl7UNWQGysA,1809
|
|
72
82
|
kodit/infrastructure/mappers/__init__.py,sha256=QPHOjNreXmBPPovZ6elnYFS0vD-IsmrGl4TT01FCKro,77
|
|
73
83
|
kodit/infrastructure/mappers/index_mapper.py,sha256=ZSfu8kjTaa8_UY0nTqr4b02NS3VrjqZYkduCN71AL2g,12743
|
|
84
|
+
kodit/infrastructure/mappers/task_mapper.py,sha256=QW7uL8rji6QJ7RRdHwbvkWqmwDcUDGTYPLwbwiKlViY,2919
|
|
74
85
|
kodit/infrastructure/slicing/__init__.py,sha256=x7cjvHA9Ay2weUYE_dpdAaPaStp20M-4U2b5MLgT5KM,37
|
|
75
86
|
kodit/infrastructure/slicing/language_detection_service.py,sha256=JGJXrq9bLyfnisWJXeP7y1jbZMmKAISdPBlRBCosUcE,684
|
|
76
87
|
kodit/infrastructure/slicing/slicer.py,sha256=GOqJykd00waOTO1WJHyE5KUgJ2RLx2rOQ7M7T_u5LLg,35600
|
|
77
88
|
kodit/infrastructure/sqlalchemy/__init__.py,sha256=UXPMSF_hgWaqr86cawRVqM8XdVNumQyyK5B8B97GnlA,33
|
|
78
89
|
kodit/infrastructure/sqlalchemy/embedding_repository.py,sha256=dC2Wzj_zQiWExwfScE1LAGiiyxPyg0YepwyLOgDwcs4,7905
|
|
79
|
-
kodit/infrastructure/sqlalchemy/entities.py,sha256=
|
|
90
|
+
kodit/infrastructure/sqlalchemy/entities.py,sha256=2iG_2NoKS26rJXimLFL8whRqFsUvKNGFAXCkQYK5GtE,6951
|
|
80
91
|
kodit/infrastructure/sqlalchemy/index_repository.py,sha256=QQNsyLBI09YLUPLguB9qvqPZMxtg1p2twpm7sO_gNlo,23598
|
|
92
|
+
kodit/infrastructure/sqlalchemy/task_repository.py,sha256=yazMO6Kw0Pb2b3L8wlGKOFA0QuMFcWBUXYFGZdtZo0w,2874
|
|
81
93
|
kodit/infrastructure/ui/__init__.py,sha256=CzbLOBwIZ6B6iAHEd1L8cIBydCj-n_kobxJAhz2I9_Y,32
|
|
82
94
|
kodit/infrastructure/ui/progress.py,sha256=SHEUoQA_x36z4nqHrQduVrrWIvFfX6QxAawC7zQ50pw,6433
|
|
83
95
|
kodit/infrastructure/ui/spinner.py,sha256=GcP115qtR0VEnGfMEtsGoAUpRzVGUSfiUXfoJJERngA,2357
|
|
@@ -89,14 +101,16 @@ kodit/migrations/versions/4073b33f9436_add_file_processing_flag.py,sha256=c8dMcK
|
|
|
89
101
|
kodit/migrations/versions/4552eb3f23ce_add_summary.py,sha256=WjyBQzFK8IXuvta15YBE23yaTMM1rZCXvPxW98MStng,870
|
|
90
102
|
kodit/migrations/versions/7c3bbc2ab32b_add_embeddings_table.py,sha256=JL6lxaYtGbXolrkNEujg5SWj3_aQBWReYP3I4vcibdo,1755
|
|
91
103
|
kodit/migrations/versions/85155663351e_initial.py,sha256=h8DWmSxVwTtWlmWNH8-S4AxfEIbCm_iWtR6Kg5psPnk,3605
|
|
104
|
+
kodit/migrations/versions/9cf0e87de578_add_queue.py,sha256=FYrco38f3_-1ZRfGOU617bgR1Ta0YTwwz3QDQMw_NKY,1600
|
|
92
105
|
kodit/migrations/versions/9e53ea8bb3b0_add_authors.py,sha256=a32Zm8KUQyiiLkjKNPYdaJDgjW6VsV-GhaLnPnK_fpI,3884
|
|
93
106
|
kodit/migrations/versions/__init__.py,sha256=9-lHzptItTzq_fomdIRBegQNm4Znx6pVjwD4MiqRIdo,36
|
|
94
107
|
kodit/migrations/versions/c3f5137d30f5_index_all_the_things.py,sha256=r7ukmJ_axXLAWewYx-F1fEmZ4JbtFd37i7cSb0tq3y0,1722
|
|
95
108
|
kodit/utils/__init__.py,sha256=DPEB1i8evnLF4Ns3huuAYg-0pKBFKUFuiDzOKG9r-sw,33
|
|
96
109
|
kodit/utils/dump_openapi.py,sha256=29VdjHpNSaGAg7RjQw0meq1OLhljCx1ElgBlTC8xoF4,1247
|
|
110
|
+
kodit/utils/generate_api_paths.py,sha256=TMtx9v55podDfUmiWaHgJHLtEWLV2sLL-5ejGFMPzAo,3569
|
|
97
111
|
kodit/utils/path_utils.py,sha256=thK6YGGNvQThdBaCYCCeCvS1L8x-lwl3AoGht2jnjGw,1645
|
|
98
|
-
kodit-0.
|
|
99
|
-
kodit-0.
|
|
100
|
-
kodit-0.
|
|
101
|
-
kodit-0.
|
|
102
|
-
kodit-0.
|
|
112
|
+
kodit-0.4.0.dist-info/METADATA,sha256=bwViEYL092ciMPsday_wvQgIEheDQ1frFv26RxsTxcI,7671
|
|
113
|
+
kodit-0.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
114
|
+
kodit-0.4.0.dist-info/entry_points.txt,sha256=hoTn-1aKyTItjnY91fnO-rV5uaWQLQ-Vi7V5et2IbHY,40
|
|
115
|
+
kodit-0.4.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
116
|
+
kodit-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|