moca-reader-llamaindex 0.6.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.
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""A LlamaIndex retriever over MOCA packages (Reader interface §7).
|
|
2
|
+
|
|
3
|
+
``MocaRetriever`` wraps a host-built ``moca_reader.Search``: its backend, audiences and hooks. Every call goes
|
|
4
|
+
through the Reader's gate, so the retrieval policy and the host's audience filter always apply, and nothing a
|
|
5
|
+
caller passes can widen them. Each citation record becomes a ``NodeWithScore``: a ``TextNode`` with the text, the
|
|
6
|
+
whole record under ``metadata["moca_citation"]`` and the consuming guide's flat ``moca_*`` fields beside it, and
|
|
7
|
+
the record's score. The MOCA keys are excluded from the text LlamaIndex sends to a model or an embedder.
|
|
8
|
+
|
|
9
|
+
Package text is untrusted input to a model: pass it to a model as quoted reference material to cite, never as
|
|
10
|
+
instructions (Reader contract §12).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from llama_index.core.callbacks import CallbackManager
|
|
18
|
+
from llama_index.core.retrievers import BaseRetriever
|
|
19
|
+
from llama_index.core.schema import NodeWithScore, QueryBundle, TextNode
|
|
20
|
+
|
|
21
|
+
from moca_reader import CitationRecord, Search, flat_metadata
|
|
22
|
+
|
|
23
|
+
__all__ = ["MocaRetriever", "node_id", "to_node"]
|
|
24
|
+
__version__ = "0.6.0"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def node_id(record: CitationRecord) -> str:
|
|
28
|
+
"""A unique id: the node's versioned reference, then the byte span, since one node can return several chunks."""
|
|
29
|
+
span = record.get("span")
|
|
30
|
+
ref = str(record["node"]["ref"])
|
|
31
|
+
return f"{ref}:{span['start']}-{span['end']}" if isinstance(span, dict) else ref
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def to_node(record: CitationRecord) -> NodeWithScore:
|
|
35
|
+
"""A citation record as a LlamaIndex ``NodeWithScore``."""
|
|
36
|
+
metadata: dict[str, Any] = {"moca_citation": record, **flat_metadata(record)}
|
|
37
|
+
keys = list(metadata)
|
|
38
|
+
node = TextNode(
|
|
39
|
+
id_=node_id(record),
|
|
40
|
+
text=record.get("text") or "",
|
|
41
|
+
metadata=metadata,
|
|
42
|
+
excluded_llm_metadata_keys=keys,
|
|
43
|
+
excluded_embed_metadata_keys=keys,
|
|
44
|
+
)
|
|
45
|
+
score = record.get("score")
|
|
46
|
+
return NodeWithScore(node=node, score=float(score) if isinstance(score, (int, float)) else None)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class MocaRetriever(BaseRetriever):
|
|
50
|
+
"""Retrieves citation records from MOCA packages as LlamaIndex ``NodeWithScore``s.
|
|
51
|
+
|
|
52
|
+
``search`` is the host's ``moca_reader.Search``; the other arguments are the search options for every call.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
search: Search,
|
|
58
|
+
*,
|
|
59
|
+
limit: int = 5,
|
|
60
|
+
locale: str | None = None,
|
|
61
|
+
concepts: list[str] | None = None,
|
|
62
|
+
scope: str | None = None,
|
|
63
|
+
include_all: bool = False,
|
|
64
|
+
callback_manager: CallbackManager | None = None,
|
|
65
|
+
) -> None:
|
|
66
|
+
super().__init__(callback_manager=callback_manager)
|
|
67
|
+
self._search = search
|
|
68
|
+
self._options: dict[str, Any] = {
|
|
69
|
+
"limit": limit,
|
|
70
|
+
"include_all": include_all,
|
|
71
|
+
"locale": locale,
|
|
72
|
+
"concepts": concepts,
|
|
73
|
+
"scope": scope,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
def _retrieve(self, query_bundle: QueryBundle) -> list[NodeWithScore]:
|
|
77
|
+
return [to_node(r) for r in self._search.search(query_bundle.query_str, **self._options)]
|
|
File without changes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: moca-reader-llamaindex
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: A LlamaIndex retriever over MOCA packages: citation records as scored nodes, through the MOCA Reader's gate.
|
|
5
|
+
Project-URL: Homepage, https://openmoca.org
|
|
6
|
+
Project-URL: Source, https://github.com/openmoca/moca-reader-python
|
|
7
|
+
Author: MOCA Standard Contributors
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Keywords: citations,llama-index,llamaindex,moca,rag,retriever
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Requires-Dist: llama-index-core>=0.14
|
|
15
|
+
Requires-Dist: moca-reader==0.6.0
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# moca-reader-llamaindex
|
|
19
|
+
|
|
20
|
+
A [LlamaIndex](https://www.llamaindex.ai) retriever over MOCA packages, built
|
|
21
|
+
on the [MOCA Reader for Python](https://github.com/openmoca/moca-reader-python).
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pip install moca-reader-llamaindex
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from moca_reader import LexicalBackend, Library, Search, read_package
|
|
29
|
+
from moca_reader_llamaindex import MocaRetriever
|
|
30
|
+
|
|
31
|
+
pkg = read_package("support-kb.moca", trust_root="trust-root.json")
|
|
32
|
+
library = Library().add(pkg)
|
|
33
|
+
search = Search(library, LexicalBackend(library), audiences=["public"])
|
|
34
|
+
|
|
35
|
+
retriever = MocaRetriever(search, limit=3)
|
|
36
|
+
for result in retriever.retrieve("How long is the refund window?"):
|
|
37
|
+
print(result.node.metadata["moca_node_ref"], result.score)
|
|
38
|
+
print(result.node.get_content()[:80])
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`MocaRetriever` wraps the `Search` you build: its backend (lexical, dense,
|
|
42
|
+
hybrid or your own store), its audiences and its hooks. Every call goes through
|
|
43
|
+
the Reader's gate, so content that is out of force, superseded, deprecated or
|
|
44
|
+
outside your audiences never comes back, and nothing a caller passes can widen
|
|
45
|
+
that. Use it anywhere LlamaIndex takes a retriever, such as a
|
|
46
|
+
`RetrieverQueryEngine`.
|
|
47
|
+
|
|
48
|
+
Each result is a `NodeWithScore` holding a `TextNode`:
|
|
49
|
+
|
|
50
|
+
| Field | Holds |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `text` | The text of the node, or of a sidecar chunk |
|
|
53
|
+
| `node_id` | The node's versioned reference and byte span |
|
|
54
|
+
| `metadata["moca_citation"]` | The whole citation record: package, version and digest, trust signals, evidence |
|
|
55
|
+
| `metadata["moca_*"]` | The flat fields of the consuming guide (`moca_node_ref`, `moca_package_digest`, `moca_status`, `moca_signed`, ...) |
|
|
56
|
+
| `score` | The search score |
|
|
57
|
+
|
|
58
|
+
The MOCA metadata keys are excluded from the text LlamaIndex sends to a model
|
|
59
|
+
or an embedder, so they travel with the node without filling the prompt.
|
|
60
|
+
|
|
61
|
+
**Package text is untrusted input.** Present it to a model as quoted reference
|
|
62
|
+
material to cite, never as instructions
|
|
63
|
+
([Reader contract §12](https://github.com/openmoca/moca-spec/blob/main/spec/moca-reader-contract.md#12-handing-content-to-a-model)).
|
|
64
|
+
Show users the source (`moca_node_ref`, the package version) with each answer.
|
|
65
|
+
|
|
66
|
+
## Licence
|
|
67
|
+
|
|
68
|
+
Apache-2.0.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
moca_reader_llamaindex/__init__.py,sha256=eDjRlNdRQEBlFIMh5AP_No5wuQl6XDkUU9PNm5mtF58,3068
|
|
2
|
+
moca_reader_llamaindex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
moca_reader_llamaindex-0.6.0.dist-info/METADATA,sha256=J2jJkfB7Gt8i7lSJWCHu1gss0ZtudCvuV96hLfKRy7I,2835
|
|
4
|
+
moca_reader_llamaindex-0.6.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
5
|
+
moca_reader_llamaindex-0.6.0.dist-info/RECORD,,
|