runic-py 0.4.0__tar.gz → 0.4.2__tar.gz

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.
Files changed (100) hide show
  1. {runic_py-0.4.0 → runic_py-0.4.2}/PKG-INFO +59 -7
  2. {runic_py-0.4.0 → runic_py-0.4.2}/README.md +57 -5
  3. {runic_py-0.4.0 → runic_py-0.4.2}/packages/runic-rag-docling/pyproject.toml +11 -1
  4. {runic_py-0.4.0 → runic_py-0.4.2}/pyproject.toml +3 -3
  5. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/config.py +4 -1
  6. {runic_py-0.4.0 → runic_py-0.4.2}/.gitignore +0 -0
  7. {runic_py-0.4.0 → runic_py-0.4.2}/LICENSE.md +0 -0
  8. {runic_py-0.4.0 → runic_py-0.4.2}/examples/rag/README.md +0 -0
  9. {runic_py-0.4.0 → runic_py-0.4.2}/packages/runic-rag-docling/README.md +0 -0
  10. {runic_py-0.4.0 → runic_py-0.4.2}/runic/__init__.py +0 -0
  11. {runic_py-0.4.0 → runic_py-0.4.2}/runic/cypher.py +0 -0
  12. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/__init__.py +0 -0
  13. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/__init__.py +0 -0
  14. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/_base.py +0 -0
  15. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/age.py +0 -0
  16. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/arcadedb.py +0 -0
  17. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/falkordb.py +0 -0
  18. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/memgraph.py +0 -0
  19. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/neo4j.py +0 -0
  20. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/autogen.py +0 -0
  21. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/checksum.py +0 -0
  22. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/cli.py +0 -0
  23. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/config.py +0 -0
  24. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/context.py +0 -0
  25. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/exceptions.py +0 -0
  26. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/introspect.py +0 -0
  27. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/manifest.py +0 -0
  28. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/operations.py +0 -0
  29. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/schema.py +0 -0
  30. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/script.py +0 -0
  31. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/service.py +0 -0
  32. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/templates/env.py.mako +0 -0
  33. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/templates/script.py.mako +0 -0
  34. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/testing.py +0 -0
  35. {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/version.py +0 -0
  36. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/__init__.py +0 -0
  37. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/__init__.py +0 -0
  38. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/descriptors.py +0 -0
  39. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/metadata.py +0 -0
  40. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/models.py +0 -0
  41. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/types.py +0 -0
  42. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/__init__.py +0 -0
  43. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/age.py +0 -0
  44. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/arcadedb.py +0 -0
  45. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/bolt.py +0 -0
  46. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/factory.py +0 -0
  47. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/falkordb.py +0 -0
  48. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/memgraph.py +0 -0
  49. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/neo4j.py +0 -0
  50. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/exceptions.py +0 -0
  51. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/__init__.py +0 -0
  52. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/mapper.py +0 -0
  53. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/relationship_loader.py +0 -0
  54. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/relationship_writer.py +0 -0
  55. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/operations.py +0 -0
  56. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/__init__.py +0 -0
  57. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/_compiler.py +0 -0
  58. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/_decoder.py +0 -0
  59. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/builder.py +0 -0
  60. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/expressions.py +0 -0
  61. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/specialised.py +0 -0
  62. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/traversal.py +0 -0
  63. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/__init__.py +0 -0
  64. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/_base.py +0 -0
  65. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/async_repository.py +0 -0
  66. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/cypher.py +0 -0
  67. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/protocol.py +0 -0
  68. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/repository.py +0 -0
  69. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/schema/__init__.py +0 -0
  70. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/schema/index_manager.py +0 -0
  71. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/__init__.py +0 -0
  72. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/_base.py +0 -0
  73. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/async_session.py +0 -0
  74. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/connection_pool.py +0 -0
  75. {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/session.py +0 -0
  76. {runic_py-0.4.0 → runic_py-0.4.2}/runic/py.typed +0 -0
  77. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/__init__.py +0 -0
  78. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/__main__.py +0 -0
  79. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/__init__.py +0 -0
  80. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/_llm.py +0 -0
  81. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/chunking.py +0 -0
  82. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/documents.py +0 -0
  83. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/embedding.py +0 -0
  84. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/extraction.py +0 -0
  85. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/reranking.py +0 -0
  86. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/resolution.py +0 -0
  87. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/retrieval.py +0 -0
  88. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/synthesis.py +0 -0
  89. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/cli.py +0 -0
  90. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/concurrency.py +0 -0
  91. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/domain.py +0 -0
  92. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/exceptions.py +0 -0
  93. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/facade.py +0 -0
  94. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/models.py +0 -0
  95. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/ontology.py +0 -0
  96. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/ports.py +0 -0
  97. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/services/__init__.py +0 -0
  98. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/services/ingestion.py +0 -0
  99. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/services/retrieval.py +0 -0
  100. {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runic-py
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Graph schema migrations and OGM for Cypher-based graph databases.
5
5
  Project-URL: Homepage, https://runic.rehpoehler.de
6
6
  Project-URL: Repository, https://github.com/jenreh/runic
@@ -16,7 +16,7 @@ Requires-Python: >=3.14
16
16
  Requires-Dist: mako<2.0.0,>=1.3.0
17
17
  Requires-Dist: rich<16.0.0,>=14.0.0
18
18
  Requires-Dist: shellingham<2.0.0,>=1.5.0
19
- Requires-Dist: typer<1.0.0,>=0.26.0
19
+ Requires-Dist: typer<0.27.0,>=0.24.0
20
20
  Provides-Extra: age
21
21
  Requires-Dist: psycopg<4.0.0,>=3.3.4; extra == 'age'
22
22
  Provides-Extra: age-binary
@@ -47,12 +47,12 @@ Description-Content-Type: text/markdown
47
47
  **A type-safe OGM for Cypher graph databases.<br>
48
48
  Define your models once, run them on any backend.**
49
49
 
50
- ![Version](https://img.shields.io/badge/version-0.4.0-blue)
50
+ ![Version](https://img.shields.io/badge/version-0.4.2-blue)
51
51
  [![PyPI](https://img.shields.io/pypi/v/runic-py.svg)](https://pypi.org/project/runic-py/)
52
52
  [![Python](https://img.shields.io/badge/python-3.14%2B-orange)](https://www.python.org)
53
53
  [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE.md)
54
54
 
55
- [Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
55
+ [Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Graph-RAG](#graph-rag) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
56
56
 
57
57
  </div>
58
58
 
@@ -61,7 +61,8 @@ Define your models once, run them on any backend.**
61
61
  Runic maps Python classes to graph nodes and edges. You declare typed `Node` and `Edge` models
62
62
  and get change tracking, lazy and eager relationships, a composable query API, and schema
63
63
  migrations — on top of a pluggable driver layer that runs the same model code on FalkorDB,
64
- Neo4j, Memgraph, ArcadeDB, and Apache AGE.
64
+ Neo4j, Memgraph, ArcadeDB, and Apache AGE. A built-in [Graph-RAG SDK](#graph-rag) layers
65
+ document ingestion and cited, knowledge-graph-grounded question answering on top of the OGM.
65
66
 
66
67
  ## Why Runic
67
68
 
@@ -303,6 +304,55 @@ print("current:", runic.migrate.current())
303
304
 
304
305
  ---
305
306
 
307
+ ## Graph-RAG
308
+
309
+ `runic.rag` turns unstructured text into a knowledge graph and answers questions over it with
310
+ citations — chunking, entity/relation extraction, embedding, storage, and hybrid (vector +
311
+ fulltext + graph-expansion) retrieval are handled for you. It builds on the same OGM and driver
312
+ layer, so it runs on any supported backend. OpenAI is the default for the LLM and embeddings;
313
+ point it at Ollama for a fully local run.
314
+
315
+ ```python
316
+ from runic.ogm import create_driver
317
+ from runic.rag import GraphRAG, Ontology, RagSettings
318
+
319
+ settings = RagSettings()
320
+ driver = create_driver(
321
+ "falkordb", host="localhost", port=6379, graph=settings.falkordb_graph
322
+ )
323
+
324
+ # with_defaults() wires the full adapter stack from your environment:
325
+ # paragraph chunker, extractor, embedder, resolver, retrievers, reranker, synthesizer.
326
+ rag = GraphRAG.with_defaults(driver, settings=settings, ontology=Ontology.default())
327
+ rag.bootstrap_schema() # create entity types + indexes (idempotent)
328
+
329
+ # Ingest: chunk -> extract entities/relations -> embed -> resolve -> write the graph.
330
+ rag.ingest_text(
331
+ "Ada Lovelace worked with Charles Babbage on the Analytical Engine in London.",
332
+ source="inline-demo",
333
+ )
334
+
335
+ # mode="auto" classifies the question and picks the retrieval strategy automatically.
336
+ answer = rag.query("Who worked on the Analytical Engine?")
337
+ print(answer.text)
338
+ for citation in answer.citations:
339
+ print(f" - [{citation.source}] {citation.text[:80]}...")
340
+ ```
341
+
342
+ Every stage is a port with a default adapter you can swap — custom ontologies, chunkers,
343
+ extractors, or retrievers — and the optional **`runic-rag-docling`** add-on plugs Docling in for
344
+ layout-aware parsing and chunking of PDFs and office documents.
345
+
346
+ ```bash
347
+ uv add "runic-py[graphrag,falkordb]" # Graph-RAG extras + a backend driver
348
+ ```
349
+
350
+ > [!NOTE]
351
+ > Set `OPENAI_API_KEY` (or place it in a local `.env`) before running, or set
352
+ > `RUNIC_RAG_LLM_PROVIDER=ollama` and `RUNIC_RAG_EMBEDDING_PROVIDER=ollama` to run fully local.
353
+
354
+ ---
355
+
306
356
  ## Installation
307
357
 
308
358
  Install the core package plus the extra for your backend. The core has **no graph-driver
@@ -316,6 +366,7 @@ dependency** — you only pull in what you use.
316
366
  | ArcadeDB | `arcadedb` | `neo4j` (Bolt) |
317
367
  | Apache AGE | `age` | `psycopg[binary]` |
318
368
  | All backends | `all` | all of the above |
369
+ | Graph-RAG | `graphrag` | `pydantic-ai`, `pymupdf` (combine with a backend) |
319
370
 
320
371
  ```bash
321
372
  uv add "runic-py[falkordb]" # FalkorDB
@@ -324,6 +375,7 @@ uv add "runic-py[memgraph]" # Memgraph (Bolt)
324
375
  uv add "runic-py[arcadedb]" # ArcadeDB (Bolt)
325
376
  uv add "runic-py[age]" # Apache AGE (PostgreSQL extension)
326
377
  uv add "runic-py[all]" # everything
378
+ uv add "runic-py[graphrag,falkordb]" # Graph-RAG SDK + a backend driver
327
379
  ```
328
380
 
329
381
  > [!NOTE]
@@ -333,8 +385,8 @@ uv add "runic-py[all]" # everything
333
385
 
334
386
  ## Documentation
335
387
 
336
- Full conceptual overview, async usage, advanced CLI flags, and the complete API reference live
337
- at the **[Runic Documentation](https://runic.rehpoehler.de)**.
388
+ Full conceptual overview, async usage, advanced CLI flags, the Graph-RAG guides, and the
389
+ complete API reference live at the **[Runic Documentation](https://runic.rehpoehler.de)**.
338
390
 
339
391
  ## License
340
392
 
@@ -6,12 +6,12 @@
6
6
  **A type-safe OGM for Cypher graph databases.<br>
7
7
  Define your models once, run them on any backend.**
8
8
 
9
- ![Version](https://img.shields.io/badge/version-0.4.0-blue)
9
+ ![Version](https://img.shields.io/badge/version-0.4.2-blue)
10
10
  [![PyPI](https://img.shields.io/pypi/v/runic-py.svg)](https://pypi.org/project/runic-py/)
11
11
  [![Python](https://img.shields.io/badge/python-3.14%2B-orange)](https://www.python.org)
12
12
  [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE.md)
13
13
 
14
- [Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
14
+ [Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Graph-RAG](#graph-rag) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
15
15
 
16
16
  </div>
17
17
 
@@ -20,7 +20,8 @@ Define your models once, run them on any backend.**
20
20
  Runic maps Python classes to graph nodes and edges. You declare typed `Node` and `Edge` models
21
21
  and get change tracking, lazy and eager relationships, a composable query API, and schema
22
22
  migrations — on top of a pluggable driver layer that runs the same model code on FalkorDB,
23
- Neo4j, Memgraph, ArcadeDB, and Apache AGE.
23
+ Neo4j, Memgraph, ArcadeDB, and Apache AGE. A built-in [Graph-RAG SDK](#graph-rag) layers
24
+ document ingestion and cited, knowledge-graph-grounded question answering on top of the OGM.
24
25
 
25
26
  ## Why Runic
26
27
 
@@ -262,6 +263,55 @@ print("current:", runic.migrate.current())
262
263
 
263
264
  ---
264
265
 
266
+ ## Graph-RAG
267
+
268
+ `runic.rag` turns unstructured text into a knowledge graph and answers questions over it with
269
+ citations — chunking, entity/relation extraction, embedding, storage, and hybrid (vector +
270
+ fulltext + graph-expansion) retrieval are handled for you. It builds on the same OGM and driver
271
+ layer, so it runs on any supported backend. OpenAI is the default for the LLM and embeddings;
272
+ point it at Ollama for a fully local run.
273
+
274
+ ```python
275
+ from runic.ogm import create_driver
276
+ from runic.rag import GraphRAG, Ontology, RagSettings
277
+
278
+ settings = RagSettings()
279
+ driver = create_driver(
280
+ "falkordb", host="localhost", port=6379, graph=settings.falkordb_graph
281
+ )
282
+
283
+ # with_defaults() wires the full adapter stack from your environment:
284
+ # paragraph chunker, extractor, embedder, resolver, retrievers, reranker, synthesizer.
285
+ rag = GraphRAG.with_defaults(driver, settings=settings, ontology=Ontology.default())
286
+ rag.bootstrap_schema() # create entity types + indexes (idempotent)
287
+
288
+ # Ingest: chunk -> extract entities/relations -> embed -> resolve -> write the graph.
289
+ rag.ingest_text(
290
+ "Ada Lovelace worked with Charles Babbage on the Analytical Engine in London.",
291
+ source="inline-demo",
292
+ )
293
+
294
+ # mode="auto" classifies the question and picks the retrieval strategy automatically.
295
+ answer = rag.query("Who worked on the Analytical Engine?")
296
+ print(answer.text)
297
+ for citation in answer.citations:
298
+ print(f" - [{citation.source}] {citation.text[:80]}...")
299
+ ```
300
+
301
+ Every stage is a port with a default adapter you can swap — custom ontologies, chunkers,
302
+ extractors, or retrievers — and the optional **`runic-rag-docling`** add-on plugs Docling in for
303
+ layout-aware parsing and chunking of PDFs and office documents.
304
+
305
+ ```bash
306
+ uv add "runic-py[graphrag,falkordb]" # Graph-RAG extras + a backend driver
307
+ ```
308
+
309
+ > [!NOTE]
310
+ > Set `OPENAI_API_KEY` (or place it in a local `.env`) before running, or set
311
+ > `RUNIC_RAG_LLM_PROVIDER=ollama` and `RUNIC_RAG_EMBEDDING_PROVIDER=ollama` to run fully local.
312
+
313
+ ---
314
+
265
315
  ## Installation
266
316
 
267
317
  Install the core package plus the extra for your backend. The core has **no graph-driver
@@ -275,6 +325,7 @@ dependency** — you only pull in what you use.
275
325
  | ArcadeDB | `arcadedb` | `neo4j` (Bolt) |
276
326
  | Apache AGE | `age` | `psycopg[binary]` |
277
327
  | All backends | `all` | all of the above |
328
+ | Graph-RAG | `graphrag` | `pydantic-ai`, `pymupdf` (combine with a backend) |
278
329
 
279
330
  ```bash
280
331
  uv add "runic-py[falkordb]" # FalkorDB
@@ -283,6 +334,7 @@ uv add "runic-py[memgraph]" # Memgraph (Bolt)
283
334
  uv add "runic-py[arcadedb]" # ArcadeDB (Bolt)
284
335
  uv add "runic-py[age]" # Apache AGE (PostgreSQL extension)
285
336
  uv add "runic-py[all]" # everything
337
+ uv add "runic-py[graphrag,falkordb]" # Graph-RAG SDK + a backend driver
286
338
  ```
287
339
 
288
340
  > [!NOTE]
@@ -292,8 +344,8 @@ uv add "runic-py[all]" # everything
292
344
 
293
345
  ## Documentation
294
346
 
295
- Full conceptual overview, async usage, advanced CLI flags, and the complete API reference live
296
- at the **[Runic Documentation](https://runic.rehpoehler.de)**.
347
+ Full conceptual overview, async usage, advanced CLI flags, the Graph-RAG guides, and the
348
+ complete API reference live at the **[Runic Documentation](https://runic.rehpoehler.de)**.
297
349
 
298
350
  ## License
299
351
 
@@ -41,7 +41,10 @@ dev = [
41
41
  commit = false
42
42
  current_version = "0.2.0"
43
43
  tag = false
44
- allow-dirty = false
44
+ # This package lives in the shared ``runic`` monorepo, whose working tree
45
+ # routinely carries unrelated sibling changes and whose ``v*`` tags belong to
46
+ # ``runic-py``; allow a dirty tree so the package-scoped bump isn't blocked.
47
+ allow_dirty = true
45
48
 
46
49
  [[tool.bumpversion.files]]
47
50
  filename = "pyproject.toml"
@@ -72,6 +75,13 @@ build-backend = "hatchling.build"
72
75
  [tool.hatch.build.targets.wheel]
73
76
  packages = ["runic_rag_docling"]
74
77
 
78
+ [tool.hatch.build.targets.sdist]
79
+ # Ship only the source package and metadata; never the local virtualenv
80
+ # (``.venv.mac``), caches, or build artefacts, which break ``uv build`` with
81
+ # "external symlinks are not allowed".
82
+ include = ["/runic_rag_docling", "/README.md", "/pyproject.toml"]
83
+ exclude = [".venv*"]
84
+
75
85
  [tool.pytest.ini_options]
76
86
  # ``tests`` is a package; put the package root on the path so ``tests.fakes``
77
87
  # imports resolve regardless of the invocation directory.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "runic-py"
3
- version = "0.4.0"
3
+ version = "0.4.2"
4
4
  description = "Graph schema migrations and OGM for Cypher-based graph databases."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -16,7 +16,7 @@ classifiers = [
16
16
  ]
17
17
 
18
18
  dependencies = [
19
- "typer>=0.26.0,<1.0.0",
19
+ "typer>=0.24.0,<0.27.0",
20
20
  "rich>=14.0.0,<16.0.0",
21
21
  "mako>=1.3.0,<2.0.0",
22
22
  "shellingham>=1.5.0,<2.0.0",
@@ -101,7 +101,7 @@ exclude = [
101
101
 
102
102
  [tool.bumpversion]
103
103
  commit = false
104
- current_version = "0.4.0"
104
+ current_version = "0.4.2"
105
105
  tag = false
106
106
  allow-dirty = false
107
107
 
@@ -3,7 +3,9 @@
3
3
  All ``RUNIC_RAG_*`` environment variables map onto :class:`RagSettings`
4
4
  field names (env_prefix ``RUNIC_RAG_``). ``OPENAI_API_KEY`` and
5
5
  ``OLLAMA_BASE_URL`` are read UNPREFIXED so they match the conventions of the
6
- underlying OpenAI / Ollama clients. Defaults mirror ``.env.example`` exactly.
6
+ underlying OpenAI / Ollama clients (the ``RUNIC_RAG_``-prefixed form and direct
7
+ keyword init are also accepted via ``populate_by_name``). Defaults mirror
8
+ ``.env.example`` exactly.
7
9
  """
8
10
 
9
11
  from __future__ import annotations
@@ -37,6 +39,7 @@ class RagSettings(BaseSettings):
37
39
  env_file_encoding="utf-8",
38
40
  extra="ignore",
39
41
  case_sensitive=False,
42
+ populate_by_name=True,
40
43
  )
41
44
 
42
45
  # ── LLM provider ────────────────────────────────────────────────────────
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes