lorebase-scribe 0.2.3__tar.gz → 0.3.0__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 (98) hide show
  1. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/PKG-INFO +5 -5
  2. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/pyproject.toml +5 -5
  3. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/__init__.py +1 -1
  4. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/__main__.py +94 -0
  5. lorebase_scribe-0.3.0/src/lorebase_scribe/consolidation.py +543 -0
  6. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/assemble.py +42 -7
  7. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/candidates.py +14 -1
  8. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/llm_discovery.py +1 -1
  9. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/ontology.py +29 -12
  10. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/pipeline.py +291 -13
  11. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/settings.py +54 -0
  12. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/tier2.py +51 -6
  13. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/jobs.py +190 -2
  14. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/__init__.py +2 -0
  15. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/detector.py +443 -0
  16. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/duplicates.py +124 -0
  17. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/extraction.py +203 -0
  18. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/semantic.py +372 -0
  19. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/sources.py +159 -0
  20. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/sweep.py +654 -0
  21. lorebase_scribe-0.3.0/src/lorebase_scribe/reconcile/versions.py +456 -0
  22. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/scheduler.py +58 -0
  23. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/service.py +10 -0
  24. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/settings.py +100 -1
  25. lorebase_scribe-0.3.0/src/lorebase_scribe/sources/delta.py +550 -0
  26. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/mapping.py +87 -6
  27. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/sql.py +8 -11
  28. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/sync.py +418 -38
  29. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/telemetry.py +46 -0
  30. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_audit_checkpoints.py +7 -1
  31. lorebase_scribe-0.3.0/tests/integration/test_consolidation.py +420 -0
  32. lorebase_scribe-0.3.0/tests/integration/test_document_versions.py +379 -0
  33. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_embeddings.py +2 -0
  34. lorebase_scribe-0.3.0/tests/integration/test_extraction_local_edit_postgres.py +143 -0
  35. lorebase_scribe-0.3.0/tests/integration/test_ingestion_modes.py +345 -0
  36. lorebase_scribe-0.3.0/tests/integration/test_local_edits.py +483 -0
  37. lorebase_scribe-0.3.0/tests/integration/test_reconciliation.py +546 -0
  38. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_source_sync.py +85 -6
  39. lorebase_scribe-0.3.0/tests/integration/test_source_unseen.py +192 -0
  40. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_worker.py +35 -8
  41. lorebase_scribe-0.3.0/tests/test_delta.py +414 -0
  42. lorebase_scribe-0.3.0/tests/test_extraction_local_edit.py +88 -0
  43. lorebase_scribe-0.3.0/tests/test_ingestion_modes.py +83 -0
  44. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_llm_discovery.py +3 -1
  45. lorebase_scribe-0.3.0/tests/test_reconcile_merge_check.py +103 -0
  46. lorebase_scribe-0.3.0/tests/test_reconcile_semantic.py +455 -0
  47. lorebase_scribe-0.3.0/tests/test_reconcile_triggers.py +323 -0
  48. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_settings.py +16 -0
  49. lorebase_scribe-0.2.3/src/lorebase_scribe/sources/delta.py +0 -175
  50. lorebase_scribe-0.2.3/tests/test_delta.py +0 -182
  51. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/.gitignore +0 -0
  52. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/checkpoints.py +0 -0
  53. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/cron.py +0 -0
  54. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/embeddings.py +0 -0
  55. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/__init__.py +0 -0
  56. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/discovery.py +0 -0
  57. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/matching.py +0 -0
  58. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/parsing.py +0 -0
  59. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/relations.py +0 -0
  60. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/sandbox.py +0 -0
  61. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/text.py +0 -0
  62. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/extraction/values.py +0 -0
  63. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/__init__.py +0 -0
  64. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/access.py +0 -0
  65. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/connectors.py +0 -0
  66. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/http_json.py +0 -0
  67. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/profile.py +0 -0
  68. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/sources/records.py +0 -0
  69. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/webhooks.py +0 -0
  70. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/src/lorebase_scribe/worker.py +0 -0
  71. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/conftest.py +0 -0
  72. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/conftest.py +0 -0
  73. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/extraction_support.py +0 -0
  74. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/support.py +0 -0
  75. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_extraction.py +0 -0
  76. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_lineage_startup.py +0 -0
  77. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_schema_suggestions.py +0 -0
  78. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/integration/test_sql_sources.py +0 -0
  79. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/sandbox_targets.py +0 -0
  80. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_checkpoint_sinks.py +0 -0
  81. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_connectors.py +0 -0
  82. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_cron.py +0 -0
  83. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_extraction_discovery.py +0 -0
  84. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_extraction_link_values.py +0 -0
  85. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_extraction_rules.py +0 -0
  86. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_extraction_text.py +0 -0
  87. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_extraction_vault_items.py +0 -0
  88. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_http_json_connector.py +0 -0
  89. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_mapping.py +0 -0
  90. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_parser_sandbox.py +0 -0
  91. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_record_connectors.py +0 -0
  92. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_service.py +0 -0
  93. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_source_connections.py +0 -0
  94. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_source_profile.py +0 -0
  95. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_sql_connectors.py +0 -0
  96. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_telemetry.py +0 -0
  97. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_webhook_job.py +0 -0
  98. {lorebase_scribe-0.2.3 → lorebase_scribe-0.3.0}/tests/test_webhook_sender.py +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: lorebase-scribe
3
- Version: 0.2.3
3
+ Version: 0.3.0
4
4
  Summary: Lorebase Scribe: job worker, scheduler and Source synchronization
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: asyncpg>=0.29
7
7
  Requires-Dist: httpx>=0.27
8
- Requires-Dist: lorebase-core<0.3,>=0.2
9
- Requires-Dist: lorebase-inference<0.3,>=0.2
10
- Requires-Dist: lorebase-platform<0.3,>=0.2
11
- Requires-Dist: lorebase-store<0.3,>=0.2
8
+ Requires-Dist: lorebase-core<0.4,>=0.3
9
+ Requires-Dist: lorebase-inference<0.4,>=0.3
10
+ Requires-Dist: lorebase-platform<0.4,>=0.3
11
+ Requires-Dist: lorebase-store<0.4,>=0.3
12
12
  Requires-Dist: opentelemetry-api>=1.25
13
13
  Requires-Dist: pydantic>=2.7
14
14
  Requires-Dist: sqlalchemy[asyncio]>=2.0.30
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lorebase-scribe"
3
- version = "0.2.3"
3
+ version = "0.3.0"
4
4
  description = "Lorebase Scribe: job worker, scheduler and Source synchronization"
5
5
  requires-python = ">=3.12"
6
6
  # lorebase-store: job queue, commit pipeline, merges, webhooks, index jobs and GC.
@@ -8,10 +8,10 @@ requires-python = ">=3.12"
8
8
  # httpx: webhook deliveries, CSV Sources served over HTTP(S) and http_json Sources.
9
9
  # asyncpg and sqlalchemy: reading Postgres Sources (the drivers the store already uses).
10
10
  dependencies = [
11
- "lorebase-core>=0.2,<0.3",
12
- "lorebase-platform>=0.2,<0.3",
13
- "lorebase-store>=0.2,<0.3",
14
- "lorebase-inference>=0.2,<0.3",
11
+ "lorebase-core>=0.3,<0.4",
12
+ "lorebase-platform>=0.3,<0.4",
13
+ "lorebase-store>=0.3,<0.4",
14
+ "lorebase-inference>=0.3,<0.4",
15
15
  "sqlalchemy[asyncio]>=2.0.30",
16
16
  "asyncpg>=0.29",
17
17
  "httpx>=0.27",
@@ -1,3 +1,3 @@
1
1
  """Lorebase Scribe: job worker, scheduler and Source synchronization."""
2
2
 
3
- __version__ = "0.2.3"
3
+ __version__ = "0.3.0"
@@ -7,6 +7,16 @@ lorebase-scribe sync DOMAIN SOURCE [--dry-run]
7
7
  lorebase-scribe embeddings DOMAIN [--branch B]... [--reindex] [--prune]
8
8
  compute missing embeddings now (backfill) and print
9
9
  the report
10
+ lorebase-scribe value-index DOMAIN [--rebuild]
11
+ bring the value index selection in line with the default
12
+ branch now, or recount every value (rebuild)
13
+ lorebase-scribe coverage DOMAIN [--force]
14
+ count Records and missing values per Kind of the default
15
+ branch head now
16
+ lorebase-scribe consolidate DOMAIN prune expired resolution misses and propose vocabulary
17
+ suggestions from the frequent ones now
18
+ lorebase-scribe misses purge DOMAIN delete every recorded resolution miss of a Domain and
19
+ the vocabulary suggestions quoting them
10
20
  lorebase-scribe modes clear forget the structured output modes remembered per chat
11
21
  endpoint
12
22
  """
@@ -25,7 +35,11 @@ from lorebase_platform.settings import ConfigError, Settings, load_settings
25
35
  from lorebase_platform.telemetry import setup_telemetry
26
36
  from lorebase_scribe.service import open_scribe
27
37
  from lorebase_scribe.sources import SourceSync
38
+ from lorebase_store.coverage import run_coverage
28
39
  from lorebase_store.endpoint_modes import clear_modes
40
+ from lorebase_store.repositories import SchemaSuggestionRepository, scope_to_domain
41
+ from lorebase_store.resolve_misses import lock_domain, purge_misses
42
+ from lorebase_store.values import run_value_index
29
43
 
30
44
  SERVICE_NAME = "scribe"
31
45
 
@@ -61,6 +75,33 @@ def _parser() -> argparse.ArgumentParser:
61
75
  action="store_true",
62
76
  help="After a complete pass, delete the vectors of every other model.",
63
77
  )
78
+ value_index = commands.add_parser(
79
+ "value-index", help="Bring the value index of a Domain up to date now."
80
+ )
81
+ value_index.add_argument("domain")
82
+ value_index.add_argument(
83
+ "--rebuild",
84
+ action="store_true",
85
+ help="Recount every value from the Records (repair, or an install upgraded in place).",
86
+ )
87
+ coverage = commands.add_parser(
88
+ "coverage", help="Count Records and missing values per Kind of a Domain now."
89
+ )
90
+ coverage.add_argument("domain")
91
+ coverage.add_argument(
92
+ "--force", action="store_true", help="Recount although the head did not move."
93
+ )
94
+ consolidate = commands.add_parser(
95
+ "consolidate", help="Turn a Domain's frequent resolution misses into suggestions now."
96
+ )
97
+ consolidate.add_argument("domain")
98
+ misses = commands.add_parser("misses", help="Recorded resolution misses.")
99
+ misses.add_argument(
100
+ "action",
101
+ choices=["purge"],
102
+ help="Delete every miss of the Domain and the vocabulary suggestions quoting them.",
103
+ )
104
+ misses.add_argument("domain")
64
105
  modes = commands.add_parser("modes", help="Structured output modes of the chat endpoints.")
65
106
  modes.add_argument("action", choices=["clear"], help="Forget every remembered mode.")
66
107
  return parser
@@ -94,6 +135,7 @@ async def _sync(settings: Settings, domain: str, source: str, dry_run: bool) ->
94
135
  context.settings.sources,
95
136
  principal=context.settings.worker.principal,
96
137
  connectors=context.connectors,
138
+ approval_rules=context.approval_rules,
97
139
  )
98
140
  return (await sync.run(domain, source, dry_run=dry_run)).as_dict()
99
141
 
@@ -121,6 +163,46 @@ async def _embeddings(
121
163
  return {"passes": reports, "complete": report.complete}
122
164
 
123
165
 
166
+ async def _value_index(settings: Settings, domain: str, rebuild: bool) -> dict[str, object]:
167
+ async with open_scribe(settings) as scribe:
168
+ context = scribe.context
169
+ report = await run_value_index(
170
+ context.sessions, domain, settings=context.runtime.settings, rebuild_all=rebuild
171
+ )
172
+ return report.as_dict()
173
+
174
+
175
+ async def _coverage(settings: Settings, domain: str, force: bool) -> dict[str, object]:
176
+ async with open_scribe(settings) as scribe:
177
+ context = scribe.context
178
+ report = await run_coverage(
179
+ context.sessions,
180
+ domain,
181
+ settings=context.runtime.settings.coverage,
182
+ clock=context.clock,
183
+ force=force,
184
+ )
185
+ return report.as_dict()
186
+
187
+
188
+ async def _consolidate(settings: Settings, domain: str) -> dict[str, object]:
189
+ async with open_scribe(settings) as scribe:
190
+ return (await scribe.context.consolidation_pass().run(domain)).as_dict()
191
+
192
+
193
+ async def _misses_purge(settings: Settings, domain: str) -> dict[str, object]:
194
+ async with (
195
+ open_scribe(settings) as scribe,
196
+ scribe.context.sessions() as session,
197
+ session.begin(),
198
+ ):
199
+ await scope_to_domain(session, domain)
200
+ await lock_domain(session, domain)
201
+ purged = await purge_misses(session, domain)
202
+ suggestions = await SchemaSuggestionRepository(session, domain).purge_vocabulary()
203
+ return {"domain": domain, "purged": purged, "suggestions": suggestions}
204
+
205
+
124
206
  def main(argv: Sequence[str] | None = None) -> int:
125
207
  """Load settings, configure logging and telemetry, then run the command."""
126
208
  args = _parser().parse_args(argv)
@@ -142,6 +224,18 @@ def main(argv: Sequence[str] | None = None) -> int:
142
224
  return 0 if result["complete"] else 1
143
225
  elif args.command == "modes":
144
226
  sys.stdout.write(json.dumps(asyncio.run(_modes_clear(settings))) + "\n")
227
+ elif args.command == "coverage":
228
+ report = asyncio.run(_coverage(settings, args.domain, args.force))
229
+ sys.stdout.write(json.dumps(report, default=str) + "\n")
230
+ elif args.command == "consolidate":
231
+ report = asyncio.run(_consolidate(settings, args.domain))
232
+ sys.stdout.write(json.dumps(report, default=str) + "\n")
233
+ elif args.command == "misses":
234
+ report = asyncio.run(_misses_purge(settings, args.domain))
235
+ sys.stdout.write(json.dumps(report, default=str) + "\n")
236
+ elif args.command == "value-index":
237
+ report = asyncio.run(_value_index(settings, args.domain, args.rebuild))
238
+ sys.stdout.write(json.dumps(report, default=str) + "\n")
145
239
  elif args.command == "sync":
146
240
  report = asyncio.run(_sync(settings, args.domain, args.source, args.dry_run))
147
241
  sys.stdout.write(json.dumps(report, default=str) + "\n")