exactdocs 0.1.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.
- exactdocs/__init__.py +5 -0
- exactdocs/__main__.py +3 -0
- exactdocs/_version.py +6 -0
- exactdocs/_web/assets/index-B350HwjP.js +10 -0
- exactdocs/_web/assets/index-CG8rwfz9.css +2 -0
- exactdocs/_web/assets/routes-CCGZxbYl.js +1 -0
- exactdocs/_web/index.html +13 -0
- exactdocs/bootstrap/__init__.py +5 -0
- exactdocs/bootstrap/bridges.py +27 -0
- exactdocs/bootstrap/cli.py +48 -0
- exactdocs/bootstrap/container.py +28 -0
- exactdocs/bootstrap/http.py +90 -0
- exactdocs/bootstrap/mcp.py +21 -0
- exactdocs/bootstrap/settings.py +15 -0
- exactdocs/catalog/__init__.py +9 -0
- exactdocs/catalog/adapters/__init__.py +0 -0
- exactdocs/catalog/adapters/driven/__init__.py +0 -0
- exactdocs/catalog/adapters/driven/memory.py +35 -0
- exactdocs/catalog/adapters/driving/__init__.py +0 -0
- exactdocs/catalog/adapters/driving/http.py +21 -0
- exactdocs/catalog/adapters/driving/mcp.py +18 -0
- exactdocs/catalog/dtos.py +42 -0
- exactdocs/catalog/errors.py +16 -0
- exactdocs/catalog/models.py +34 -0
- exactdocs/catalog/module.py +27 -0
- exactdocs/catalog/ports/__init__.py +4 -0
- exactdocs/catalog/ports/driven.py +18 -0
- exactdocs/catalog/ports/driving.py +21 -0
- exactdocs/catalog/use_cases.py +33 -0
- exactdocs/py.typed +0 -0
- exactdocs/retrieval/__init__.py +8 -0
- exactdocs/retrieval/adapters/__init__.py +0 -0
- exactdocs/retrieval/adapters/driven/__init__.py +0 -0
- exactdocs/retrieval/adapters/driven/memory.py +26 -0
- exactdocs/retrieval/adapters/driving/__init__.py +0 -0
- exactdocs/retrieval/adapters/driving/http.py +17 -0
- exactdocs/retrieval/adapters/driving/mcp.py +28 -0
- exactdocs/retrieval/dtos.py +53 -0
- exactdocs/retrieval/errors.py +17 -0
- exactdocs/retrieval/models.py +34 -0
- exactdocs/retrieval/module.py +18 -0
- exactdocs/retrieval/ports/__init__.py +4 -0
- exactdocs/retrieval/ports/driven.py +26 -0
- exactdocs/retrieval/ports/driving.py +13 -0
- exactdocs/retrieval/use_cases.py +22 -0
- exactdocs-0.1.0.dist-info/METADATA +35 -0
- exactdocs-0.1.0.dist-info/RECORD +49 -0
- exactdocs-0.1.0.dist-info/WHEEL +4 -0
- exactdocs-0.1.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter, Query
|
|
4
|
+
|
|
5
|
+
from exactdocs.retrieval.dtos import SearchDocsQuery, SearchDocsResult
|
|
6
|
+
from exactdocs.retrieval.ports.driving import SearchDocs
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def build_router(*, search_docs: SearchDocs) -> APIRouter:
|
|
10
|
+
"""Expose retrieval under ``/search``."""
|
|
11
|
+
router = APIRouter(prefix="/search", tags=["retrieval"])
|
|
12
|
+
|
|
13
|
+
@router.get("")
|
|
14
|
+
async def search(query: Annotated[SearchDocsQuery, Query()]) -> SearchDocsResult:
|
|
15
|
+
return await search_docs(query)
|
|
16
|
+
|
|
17
|
+
return router
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""MCP adapter for retrieval. All tools are read-only."""
|
|
2
|
+
|
|
3
|
+
from typing import Annotated
|
|
4
|
+
|
|
5
|
+
from fastmcp import FastMCP
|
|
6
|
+
from mcp.types import ToolAnnotations
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
|
|
9
|
+
from exactdocs.retrieval.dtos import SearchDocsQuery, SearchDocsResult
|
|
10
|
+
from exactdocs.retrieval.ports.driving import SearchDocs
|
|
11
|
+
|
|
12
|
+
READ_ONLY = ToolAnnotations(read_only_hint=True)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def register_tools(mcp: FastMCP, *, search_docs: SearchDocs) -> None:
|
|
16
|
+
"""Register retrieval's MCP tools on ``mcp``."""
|
|
17
|
+
|
|
18
|
+
@mcp.tool(name="search_docs", annotations=READ_ONLY)
|
|
19
|
+
async def search_docs_tool(
|
|
20
|
+
library: Annotated[str, Field(description="Library name, e.g. 'react'")],
|
|
21
|
+
version: Annotated[str, Field(description="Exact indexed version, e.g. '19.1'")],
|
|
22
|
+
query: Annotated[str, Field(description="Identifier, error message or question")],
|
|
23
|
+
limit: Annotated[int, Field(ge=1, le=50)] = 5,
|
|
24
|
+
) -> SearchDocsResult:
|
|
25
|
+
"""Search one library version. Returns verbatim excerpts with source URLs."""
|
|
26
|
+
return await search_docs(
|
|
27
|
+
SearchDocsQuery(library=library, version=version, query=query, limit=limit)
|
|
28
|
+
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Data crossing the retrieval boundary. Immutable, validated."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
from typing import Self
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
|
|
8
|
+
from exactdocs.retrieval.models import Excerpt
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class _Dto(BaseModel):
|
|
12
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SearchDocsQuery(_Dto):
|
|
16
|
+
"""Search within exactly one library version."""
|
|
17
|
+
|
|
18
|
+
library: str = Field(min_length=1)
|
|
19
|
+
version: str = Field(min_length=1)
|
|
20
|
+
query: str = Field(min_length=1)
|
|
21
|
+
limit: int = Field(default=5, ge=1, le=50)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ExcerptOut(_Dto):
|
|
25
|
+
"""One verbatim excerpt with its provenance."""
|
|
26
|
+
|
|
27
|
+
text: str
|
|
28
|
+
source_url: str
|
|
29
|
+
library: str
|
|
30
|
+
version: str
|
|
31
|
+
commit_sha: str | None
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def from_model(cls, excerpt: Excerpt) -> Self:
|
|
35
|
+
"""Map a domain value object to its boundary representation."""
|
|
36
|
+
return cls(
|
|
37
|
+
text=excerpt.text,
|
|
38
|
+
source_url=excerpt.source_url,
|
|
39
|
+
library=excerpt.target.library,
|
|
40
|
+
version=excerpt.target.version,
|
|
41
|
+
commit_sha=excerpt.commit_sha,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SearchDocsResult(_Dto):
|
|
46
|
+
"""Excerpts ordered from most to least relevant."""
|
|
47
|
+
|
|
48
|
+
excerpts: list[ExcerptOut]
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def from_models(cls, excerpts: Iterable[Excerpt]) -> Self:
|
|
52
|
+
"""Map domain value objects, keeping their order."""
|
|
53
|
+
return cls(excerpts=[ExcerptOut.from_model(e) for e in excerpts])
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from exactdocs_kernel import NotFoundError, ValidationError
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class EmptySearchTextError(ValidationError):
|
|
5
|
+
"""The search text is blank."""
|
|
6
|
+
|
|
7
|
+
def __init__(self) -> None:
|
|
8
|
+
super().__init__("search text must not be empty")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class VersionNotIndexedError(NotFoundError):
|
|
12
|
+
"""There is no index for this exact library version, so there is no answer."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, library: str, version: str) -> None:
|
|
15
|
+
super().__init__(f"no index for {library}@{version}")
|
|
16
|
+
self.library = library
|
|
17
|
+
self.version = version
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Retrieval value objects. Pure Python: no frameworks, no I/O."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from exactdocs.retrieval.errors import EmptySearchTextError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
9
|
+
class DocTarget:
|
|
10
|
+
"""The exact library version a search is pinned to. Version is a hard filter."""
|
|
11
|
+
|
|
12
|
+
library: str
|
|
13
|
+
version: str
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
17
|
+
class SearchText:
|
|
18
|
+
"""What the agent is looking for: an identifier, an error code or a question."""
|
|
19
|
+
|
|
20
|
+
value: str
|
|
21
|
+
|
|
22
|
+
def __post_init__(self) -> None:
|
|
23
|
+
if not self.value.strip():
|
|
24
|
+
raise EmptySearchTextError
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
28
|
+
class Excerpt:
|
|
29
|
+
"""Original documentation text, never a summary, with where it came from."""
|
|
30
|
+
|
|
31
|
+
text: str
|
|
32
|
+
source_url: str
|
|
33
|
+
target: DocTarget
|
|
34
|
+
commit_sha: str | None = None
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Self
|
|
3
|
+
|
|
4
|
+
from exactdocs.retrieval.ports.driven import ExcerptIndex, IndexedVersions
|
|
5
|
+
from exactdocs.retrieval.ports.driving import SearchDocs
|
|
6
|
+
from exactdocs.retrieval.use_cases import SearchDocsUseCase
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
10
|
+
class RetrievalModule:
|
|
11
|
+
"""Retrieval's driving ports, ready to be exposed by driving adapters."""
|
|
12
|
+
|
|
13
|
+
search_docs: SearchDocs
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def build(cls, *, versions: IndexedVersions, index: ExcerptIndex) -> Self:
|
|
17
|
+
"""Assemble the use cases around the given driven adapters."""
|
|
18
|
+
return cls(search_docs=SearchDocsUseCase(versions, index))
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Driven (secondary) ports of retrieval."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import Protocol
|
|
5
|
+
|
|
6
|
+
from exactdocs.retrieval.models import DocTarget, Excerpt, SearchText
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class IndexedVersions(Protocol):
|
|
10
|
+
"""Which library versions have an index.
|
|
11
|
+
|
|
12
|
+
The catalog domain owns this knowledge. Retrieval states what it needs in its own terms
|
|
13
|
+
and the composition root plugs in an adapter, so neither domain imports the other.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
async def is_indexed(self, target: DocTarget) -> bool:
|
|
17
|
+
"""Return ``True`` only for an exact library and version match."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ExcerptIndex(Protocol):
|
|
22
|
+
"""Search backend (BM25 + vectors + rerank) scoped to one library version."""
|
|
23
|
+
|
|
24
|
+
async def search(self, target: DocTarget, text: SearchText, limit: int) -> Sequence[Excerpt]:
|
|
25
|
+
"""Return at most ``limit`` excerpts from ``target`` only, best first."""
|
|
26
|
+
...
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Driving (primary) ports of retrieval."""
|
|
2
|
+
|
|
3
|
+
from typing import Protocol
|
|
4
|
+
|
|
5
|
+
from exactdocs.retrieval.dtos import SearchDocsQuery, SearchDocsResult
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SearchDocs(Protocol):
|
|
9
|
+
"""Hybrid search within one library version; raises ``VersionNotIndexedError``."""
|
|
10
|
+
|
|
11
|
+
async def __call__(self, query: SearchDocsQuery) -> SearchDocsResult:
|
|
12
|
+
"""Run the use case."""
|
|
13
|
+
...
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from exactdocs.retrieval.dtos import SearchDocsQuery, SearchDocsResult
|
|
4
|
+
from exactdocs.retrieval.errors import VersionNotIndexedError
|
|
5
|
+
from exactdocs.retrieval.models import DocTarget, SearchText
|
|
6
|
+
from exactdocs.retrieval.ports.driven import ExcerptIndex, IndexedVersions
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True, slots=True)
|
|
10
|
+
class SearchDocsUseCase:
|
|
11
|
+
"""Implements ``ports.driving.SearchDocs``."""
|
|
12
|
+
|
|
13
|
+
versions: IndexedVersions
|
|
14
|
+
index: ExcerptIndex
|
|
15
|
+
|
|
16
|
+
async def __call__(self, query: SearchDocsQuery) -> SearchDocsResult:
|
|
17
|
+
"""Search one exact version; never fall back to another version."""
|
|
18
|
+
target = DocTarget(library=query.library, version=query.version)
|
|
19
|
+
if not await self.versions.is_indexed(target):
|
|
20
|
+
raise VersionNotIndexedError(target.library, target.version)
|
|
21
|
+
excerpts = await self.index.search(target, SearchText(value=query.query), query.limit)
|
|
22
|
+
return SearchDocsResult.from_models(excerpts)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: exactdocs
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Self-hosted, version-accurate documentation for AI coding agents (MCP server).
|
|
5
|
+
Project-URL: Repository, https://github.com/SirCypkowskyy/ExactDocs
|
|
6
|
+
Project-URL: Issues, https://github.com/SirCypkowskyy/ExactDocs/issues
|
|
7
|
+
Author: Cyprian Gburek
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Keywords: ai-agents,documentation,fastmcp,mcp,rag
|
|
10
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
11
|
+
Classifier: Framework :: FastAPI
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Requires-Python: >=3.14
|
|
15
|
+
Requires-Dist: cyclopts>=4
|
|
16
|
+
Requires-Dist: exactdocs-kernel==0.1.0
|
|
17
|
+
Requires-Dist: fastapi>=0.120
|
|
18
|
+
Requires-Dist: fastmcp>=4
|
|
19
|
+
Requires-Dist: mcp>=2
|
|
20
|
+
Requires-Dist: pydantic-settings>=2.11
|
|
21
|
+
Requires-Dist: pydantic>=2.12
|
|
22
|
+
Requires-Dist: uvicorn[standard]>=0.38
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# exactdocs
|
|
26
|
+
|
|
27
|
+
Self-hosted, version-accurate documentation for AI coding agents: an MCP server that serves
|
|
28
|
+
the right docs for the right library version, verbatim and with sources.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uvx exactdocs serve # HTTP: web UI + MCP on http://localhost:3000
|
|
32
|
+
uvx exactdocs serve --stdio # MCP over stdio
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
See the [project README](https://github.com/SirCypkowskyy/ExactDocs) for the full documentation.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
exactdocs/__init__.py,sha256=ZyWSa5dAmFbfc0TjKWhLJBcrryu1r_VmBOkF37IpkUw,154
|
|
2
|
+
exactdocs/__main__.py,sha256=ssz-NB4QDdynBs1NQKemNmA7m6Qa5FBNfceppQteRJg,49
|
|
3
|
+
exactdocs/_version.py,sha256=auPWjG7MmNQBtyjHzThYGqLlFuaGHu8gyxB7V7-GqvM,218
|
|
4
|
+
exactdocs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
exactdocs/_web/index.html,sha256=qfdyFgXtPPRcBaW1lj4kwVvq7UT4l80uZWtHY6owjSI,394
|
|
6
|
+
exactdocs/_web/assets/index-B350HwjP.js,sha256=xWKuZGMqGuK7_lOFM3oaxffCYQoKzh0CHfU991MIS8Q,366751
|
|
7
|
+
exactdocs/_web/assets/index-CG8rwfz9.css,sha256=foha27uzVRpwi61OcHwCGko46dODPxeFh4UlTWGJlb0,18144
|
|
8
|
+
exactdocs/_web/assets/routes-CCGZxbYl.js,sha256=WYFRFl7Rr2wfuVmqL3NGVtZduzSxr6rgTlCuI15lmTw,71
|
|
9
|
+
exactdocs/bootstrap/__init__.py,sha256=XG_MBkV1HgArcX61rCLHrAFFv3ShMmi-KzpqJX4neJY,192
|
|
10
|
+
exactdocs/bootstrap/bridges.py,sha256=hUcvDHsCKTpMcQJBWaHIWE1tVyZ2i0ZMewR6xFugmr8,1018
|
|
11
|
+
exactdocs/bootstrap/cli.py,sha256=BghXcWdv5ias-ebZPmLH46sj_nM73kJToOHzWQB9wuw,1327
|
|
12
|
+
exactdocs/bootstrap/container.py,sha256=xs5UHI7IcgZiYSbrgEko9t2I9V0lpH5VAhwk7SWsnWI,1092
|
|
13
|
+
exactdocs/bootstrap/http.py,sha256=Fs6E3YWovNlhbqTnaKwNxDkg70rPFAp0x3BKRzvMuho,3349
|
|
14
|
+
exactdocs/bootstrap/mcp.py,sha256=EvoJiroS6fWHldTlKOM2z7qL2nIdI87cRkld7tHCX8A,858
|
|
15
|
+
exactdocs/bootstrap/settings.py,sha256=8-NLbcusqgdvmL2yHvUdjdv75n_EDef8onrtTofbwT8,533
|
|
16
|
+
exactdocs/catalog/__init__.py,sha256=0u3x-I9VxUub0bK5pBNyj1Zt0UmJkPZnPJ_7tD0mnvc,334
|
|
17
|
+
exactdocs/catalog/dtos.py,sha256=uhcxSg_TkFTJa-NrWtD7FETGHXXRDQE9NRdKePR6EHU,1203
|
|
18
|
+
exactdocs/catalog/errors.py,sha256=ClRbwoQJp5nKIWazIVcuAY_LECG0kyiuErewK_bL8R0,464
|
|
19
|
+
exactdocs/catalog/models.py,sha256=neRWNCVD8g6wuLfHRkvLEhgp962OhXBqn7cCbSdAXow,974
|
|
20
|
+
exactdocs/catalog/module.py,sha256=_TNrybsuFmGhIcaQkJhsROKTz4SBePAWL5rOQVGcKdg,958
|
|
21
|
+
exactdocs/catalog/use_cases.py,sha256=JPN-5eqejXXHNJVdggsAxdHqoJ1ebIGALPj2gWadfFM,1159
|
|
22
|
+
exactdocs/catalog/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
exactdocs/catalog/adapters/driven/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
exactdocs/catalog/adapters/driven/memory.py,sha256=Qn1DykuZGf4zPeaMob9QCpGFQbJ1weXroXzWp8p08Ec,1281
|
|
25
|
+
exactdocs/catalog/adapters/driving/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
exactdocs/catalog/adapters/driving/http.py,sha256=DJ5c8WUAEUvDKXIp37rwPAEB_y1XkyVE7153l6CYuYI,724
|
|
27
|
+
exactdocs/catalog/adapters/driving/mcp.py,sha256=-lj8sCNL6NRng4Tr83zJ7LtPVsfPLQJgE1FYNCn-OVY,624
|
|
28
|
+
exactdocs/catalog/ports/__init__.py,sha256=RYrj8wC8kMrVVB-gXWv_DSIG5xVW4Wb8db8UFn16Epw,195
|
|
29
|
+
exactdocs/catalog/ports/driven.py,sha256=i0SXcHEC7WM-EzAyOpP3SX5ZpYjlMkicZQ_gwOgOnJY,524
|
|
30
|
+
exactdocs/catalog/ports/driving.py,sha256=qVC4z64AJ7mPDsVRZNqmAOXZpTeD-fLNRIPhJb5Fc2k,597
|
|
31
|
+
exactdocs/retrieval/__init__.py,sha256=OQDJF0SkGRPe9ew8hYdq3o5qBQU03kgI3O81KnwzV-M,250
|
|
32
|
+
exactdocs/retrieval/dtos.py,sha256=TA4Hh9ycwJc8cn5xpEqpolqBF5kwVoAonIb_XAK6qXM,1444
|
|
33
|
+
exactdocs/retrieval/errors.py,sha256=93JiMAB-w46UtYB7GGaq4jArLIstTO3SkbyCKw01dlw,549
|
|
34
|
+
exactdocs/retrieval/models.py,sha256=Cr3X9WYDwH7TAtOVwpaNpep5jGzU6HoPh5nQwGveqqU,874
|
|
35
|
+
exactdocs/retrieval/module.py,sha256=o7V7XnrygWGMba5meh90qWkc73Ax9fyMpFIokh_vgfs,668
|
|
36
|
+
exactdocs/retrieval/use_cases.py,sha256=9rMQb9EqUYLdvPBNnScJ4v5-UhXDOHnl8M5Ve-JRjjw,974
|
|
37
|
+
exactdocs/retrieval/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
+
exactdocs/retrieval/adapters/driven/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
exactdocs/retrieval/adapters/driven/memory.py,sha256=ecbyITEWQWAAIIhsc0GPWUcteO_vSyCy5ltY4IlSsLM,1016
|
|
40
|
+
exactdocs/retrieval/adapters/driving/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
+
exactdocs/retrieval/adapters/driving/http.py,sha256=LX33oSBLBqSrTsBeEenD7T7BxLjXtSPMS3u7vAlPG6s,530
|
|
42
|
+
exactdocs/retrieval/adapters/driving/mcp.py,sha256=tD7k79JwWaDRNEOVK8HVUorknlS1nFcgWWMCShwQoco,1139
|
|
43
|
+
exactdocs/retrieval/ports/__init__.py,sha256=Usylx_LGTpaW65iHiPGbj1TIxqo-L2yY5e3qS-T6BBU,193
|
|
44
|
+
exactdocs/retrieval/ports/driven.py,sha256=_mjBPeKbGlWGB1Oo9-wHPeEXYEHQ1mAJhn5RWhwvuDQ,904
|
|
45
|
+
exactdocs/retrieval/ports/driving.py,sha256=3G1OgmLEi-4dGW-H56zYWW_hGz1ZRFlxdENaG3oMhDo,381
|
|
46
|
+
exactdocs-0.1.0.dist-info/METADATA,sha256=anL1Knc8rBlTiM2dWl85EJz8OzCCbMZbweu9WsiSrNQ,1275
|
|
47
|
+
exactdocs-0.1.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
48
|
+
exactdocs-0.1.0.dist-info/entry_points.txt,sha256=OZ7OENarmXQDD7Wl163Y12c8n2DSOTVugwim-Lr0pcs,59
|
|
49
|
+
exactdocs-0.1.0.dist-info/RECORD,,
|