lorebase-keeper 0.2.3__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.
Files changed (126) hide show
  1. lorebase_keeper/__init__.py +1 -0
  2. lorebase_keeper/__main__.py +456 -0
  3. lorebase_keeper/agents/__init__.py +1 -0
  4. lorebase_keeper/agents/budget.py +247 -0
  5. lorebase_keeper/agents/context.py +529 -0
  6. lorebase_keeper/agents/explain.py +582 -0
  7. lorebase_keeper/agents/feed.py +259 -0
  8. lorebase_keeper/agents/markdown.py +219 -0
  9. lorebase_keeper/agents/pack.py +403 -0
  10. lorebase_keeper/agents/settings.py +111 -0
  11. lorebase_keeper/app.py +373 -0
  12. lorebase_keeper/auth/__init__.py +4 -0
  13. lorebase_keeper/auth/api_keys.py +127 -0
  14. lorebase_keeper/auth/audit.py +356 -0
  15. lorebase_keeper/auth/cache.py +53 -0
  16. lorebase_keeper/auth/config.py +618 -0
  17. lorebase_keeper/auth/deps.py +183 -0
  18. lorebase_keeper/auth/keyring.py +14 -0
  19. lorebase_keeper/auth/oidc.py +242 -0
  20. lorebase_keeper/auth/permissions.py +142 -0
  21. lorebase_keeper/auth/ports.py +212 -0
  22. lorebase_keeper/auth/principals.py +377 -0
  23. lorebase_keeper/auth/provider.py +250 -0
  24. lorebase_keeper/auth/rbac.py +247 -0
  25. lorebase_keeper/auth/read_audit.py +357 -0
  26. lorebase_keeper/auth/runtime.py +113 -0
  27. lorebase_keeper/auth/sessions.py +452 -0
  28. lorebase_keeper/bootstrap.py +151 -0
  29. lorebase_keeper/client_address.py +129 -0
  30. lorebase_keeper/context.py +226 -0
  31. lorebase_keeper/db.py +93 -0
  32. lorebase_keeper/deps.py +47 -0
  33. lorebase_keeper/errors.py +257 -0
  34. lorebase_keeper/health.py +61 -0
  35. lorebase_keeper/kindhealth/__init__.py +6 -0
  36. lorebase_keeper/kindhealth/config.py +51 -0
  37. lorebase_keeper/kindhealth/markdown.py +163 -0
  38. lorebase_keeper/kindhealth/models.py +179 -0
  39. lorebase_keeper/kindhealth/report.py +154 -0
  40. lorebase_keeper/kindhealth/scan.py +512 -0
  41. lorebase_keeper/middleware.py +285 -0
  42. lorebase_keeper/pagination.py +87 -0
  43. lorebase_keeper/ratelimit/__init__.py +10 -0
  44. lorebase_keeper/ratelimit/bucket.py +118 -0
  45. lorebase_keeper/ratelimit/config.py +283 -0
  46. lorebase_keeper/ratelimit/enforce.py +393 -0
  47. lorebase_keeper/ratelimit/limiter.py +149 -0
  48. lorebase_keeper/ratelimit/quotas.py +204 -0
  49. lorebase_keeper/ratelimit/shared.py +242 -0
  50. lorebase_keeper/readiness.py +257 -0
  51. lorebase_keeper/reading/__init__.py +1 -0
  52. lorebase_keeper/reading/caching.py +251 -0
  53. lorebase_keeper/reading/compiler.py +678 -0
  54. lorebase_keeper/reading/cursors.py +56 -0
  55. lorebase_keeper/reading/diff.py +408 -0
  56. lorebase_keeper/reading/graph.py +268 -0
  57. lorebase_keeper/reading/history.py +152 -0
  58. lorebase_keeper/reading/points.py +410 -0
  59. lorebase_keeper/reading/problems.py +74 -0
  60. lorebase_keeper/reading/record_history.py +722 -0
  61. lorebase_keeper/reading/records.py +780 -0
  62. lorebase_keeper/reading/requests.py +107 -0
  63. lorebase_keeper/reading/runtime.py +145 -0
  64. lorebase_keeper/reading/search.py +708 -0
  65. lorebase_keeper/reading/sensitivity.py +882 -0
  66. lorebase_keeper/reading/settings.py +339 -0
  67. lorebase_keeper/reading/snapshots.py +148 -0
  68. lorebase_keeper/reading/tree.py +98 -0
  69. lorebase_keeper/reading/views.py +264 -0
  70. lorebase_keeper/reading/visibility.py +93 -0
  71. lorebase_keeper/routes/__init__.py +1 -0
  72. lorebase_keeper/routes/admin.py +597 -0
  73. lorebase_keeper/routes/agents.py +160 -0
  74. lorebase_keeper/routes/branches.py +438 -0
  75. lorebase_keeper/routes/derivations.py +215 -0
  76. lorebase_keeper/routes/documents.py +497 -0
  77. lorebase_keeper/routes/domain_api.py +59 -0
  78. lorebase_keeper/routes/domains.py +220 -0
  79. lorebase_keeper/routes/events.py +187 -0
  80. lorebase_keeper/routes/kind_health.py +166 -0
  81. lorebase_keeper/routes/operations.py +392 -0
  82. lorebase_keeper/routes/proposal_items.py +563 -0
  83. lorebase_keeper/routes/proposals.py +1107 -0
  84. lorebase_keeper/routes/read.py +493 -0
  85. lorebase_keeper/routes/revisions.py +523 -0
  86. lorebase_keeper/routes/schema.py +682 -0
  87. lorebase_keeper/routes/schema_inference.py +437 -0
  88. lorebase_keeper/routes/schema_suggestions.py +328 -0
  89. lorebase_keeper/routes/sessions.py +286 -0
  90. lorebase_keeper/routes/source_preview.py +232 -0
  91. lorebase_keeper/routes/sources.py +200 -0
  92. lorebase_keeper/routes/trace.py +506 -0
  93. lorebase_keeper/routes/vault.py +332 -0
  94. lorebase_keeper/routes/webhooks.py +298 -0
  95. lorebase_keeper/routes/whoami.py +88 -0
  96. lorebase_keeper/services/__init__.py +1 -0
  97. lorebase_keeper/services/agent_writes.py +1035 -0
  98. lorebase_keeper/services/branches.py +337 -0
  99. lorebase_keeper/services/config.py +431 -0
  100. lorebase_keeper/services/derivation_preview.py +279 -0
  101. lorebase_keeper/services/document_urls.py +114 -0
  102. lorebase_keeper/services/domains.py +118 -0
  103. lorebase_keeper/services/errors.py +196 -0
  104. lorebase_keeper/services/operation_catalog.py +806 -0
  105. lorebase_keeper/services/operation_events.py +199 -0
  106. lorebase_keeper/services/operations.py +1229 -0
  107. lorebase_keeper/services/pii_import.py +222 -0
  108. lorebase_keeper/services/proposal_reads.py +158 -0
  109. lorebase_keeper/services/proposals.py +850 -0
  110. lorebase_keeper/services/reads.py +286 -0
  111. lorebase_keeper/services/schema.py +601 -0
  112. lorebase_keeper/services/schema_inference.py +390 -0
  113. lorebase_keeper/services/schema_suggestions.py +418 -0
  114. lorebase_keeper/services/source_preview.py +127 -0
  115. lorebase_keeper/settings.py +313 -0
  116. lorebase_keeper/tracing/__init__.py +1 -0
  117. lorebase_keeper/tracing/capture.py +350 -0
  118. lorebase_keeper/tracing/config.py +157 -0
  119. lorebase_keeper/tracing/explain.py +97 -0
  120. lorebase_keeper/tracing/middleware.py +359 -0
  121. lorebase_keeper/tracing/notes.py +80 -0
  122. lorebase_keeper/tracing/recorder.py +180 -0
  123. lorebase_keeper-0.2.3.dist-info/METADATA +21 -0
  124. lorebase_keeper-0.2.3.dist-info/RECORD +126 -0
  125. lorebase_keeper-0.2.3.dist-info/WHEEL +4 -0
  126. lorebase_keeper-0.2.3.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,180 @@
1
+ """Writes trace steps off the request path, and deletes expired ones.
2
+
3
+ Like the read auditor (`auth.read_audit`), the recorder queues steps without waiting and a
4
+ background task writes them in batches; a full queue or a failed batch drops steps, counted
5
+ in `lorebase.trace.steps.dropped` by reason. A second task deletes steps older than the
6
+ retention period every `prune_interval_s`. Tracing is debugging, not compliance: nothing is
7
+ retried.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import asyncio
13
+ import contextlib
14
+ import logging
15
+ from collections.abc import Awaitable, Callable, Sequence
16
+ from datetime import UTC, datetime, timedelta
17
+
18
+ from opentelemetry import metrics
19
+ from opentelemetry.metrics import MeterProvider
20
+ from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
21
+
22
+ from lorebase_keeper.tracing.config import TraceSettings
23
+ from lorebase_store.tracing import NewTraceStep, TraceRepository
24
+
25
+ logger = logging.getLogger("lorebase.keeper.trace")
26
+
27
+
28
+ class TraceSink:
29
+ """Where steps go: written in batches, and pruned."""
30
+
31
+ def __init__(
32
+ self,
33
+ write: Callable[[Sequence[NewTraceStep]], Awaitable[int]],
34
+ prune: Callable[[datetime], Awaitable[int]],
35
+ ) -> None:
36
+ self.write = write
37
+ self.prune = prune
38
+
39
+
40
+ def database_sink(sessions: async_sessionmaker[AsyncSession], settings: TraceSettings) -> TraceSink:
41
+ """A sink writing to `agent_trace_steps`, one transaction per batch."""
42
+
43
+ async def write(steps: Sequence[NewTraceStep]) -> int:
44
+ async with sessions() as session, session.begin():
45
+ return await TraceRepository(session).append_many(
46
+ steps,
47
+ max_per_session=settings.max_steps_per_session,
48
+ inferred_idle_s=settings.inferred_session_idle_s,
49
+ )
50
+
51
+ async def prune(before: datetime) -> int:
52
+ async with sessions() as session, session.begin():
53
+ return await TraceRepository(session).prune(before, limit=settings.prune_batch)
54
+
55
+ return TraceSink(write, prune)
56
+
57
+
58
+ class TraceRecorder:
59
+ """Queues, writes and prunes trace steps (see the module doc)."""
60
+
61
+ def __init__(
62
+ self,
63
+ settings: TraceSettings,
64
+ sink: TraceSink,
65
+ *,
66
+ meter_provider: MeterProvider | None = None,
67
+ clock: Callable[[], datetime] = lambda: datetime.now(UTC),
68
+ ) -> None:
69
+ self.settings = settings
70
+ self._sink = sink
71
+ self._clock = clock
72
+ self._queue: asyncio.Queue[NewTraceStep] = asyncio.Queue(maxsize=settings.queue_size)
73
+ self._writer: asyncio.Task[None] | None = None
74
+ self._pruner: asyncio.Task[None] | None = None
75
+ meter = (meter_provider or metrics.get_meter_provider()).get_meter("lorebase.keeper")
76
+ self._recorded = meter.create_counter(
77
+ "lorebase.trace.steps.recorded",
78
+ unit="{step}",
79
+ description="Agent trace steps written.",
80
+ )
81
+ self._dropped = meter.create_counter(
82
+ "lorebase.trace.steps.dropped",
83
+ unit="{step}",
84
+ description="Agent trace steps dropped, by reason (queue_full, write_failed, "
85
+ "session_full, shutdown).",
86
+ )
87
+
88
+ def offer(self, step: NewTraceStep) -> bool:
89
+ """Queue a step without waiting; false when it was dropped."""
90
+ self._ensure_running()
91
+ try:
92
+ self._queue.put_nowait(step)
93
+ except asyncio.QueueFull:
94
+ self._dropped.add(1, {"reason": "queue_full"})
95
+ return False
96
+ return True
97
+
98
+ def _ensure_running(self) -> None:
99
+ loop = asyncio.get_running_loop()
100
+ if self._writer is None or self._writer.done():
101
+ self._writer = loop.create_task(self._run(), name="trace-writer")
102
+ if self._pruner is None or self._pruner.done():
103
+ self._pruner = loop.create_task(self._prune_loop(), name="trace-pruner")
104
+
105
+ async def _next_batch(self) -> list[NewTraceStep]:
106
+ batch = [await self._queue.get()]
107
+ loop = asyncio.get_running_loop()
108
+ deadline = loop.time() + self.settings.flush_interval_s
109
+ while len(batch) < self.settings.batch_size:
110
+ try:
111
+ batch.append(self._queue.get_nowait())
112
+ continue
113
+ except asyncio.QueueEmpty:
114
+ pass
115
+ remaining = deadline - loop.time()
116
+ if remaining <= 0:
117
+ break
118
+ try:
119
+ async with asyncio.timeout(remaining):
120
+ batch.append(await self._queue.get())
121
+ except TimeoutError:
122
+ break
123
+ return batch
124
+
125
+ async def _write(self, batch: Sequence[NewTraceStep]) -> None:
126
+ try:
127
+ async with asyncio.timeout(self.settings.write_timeout_s):
128
+ written = await self._sink.write(batch)
129
+ except Exception as exc:
130
+ self._dropped.add(len(batch), {"reason": "write_failed"})
131
+ logger.error(
132
+ "agent trace steps dropped",
133
+ exc_info=not isinstance(exc, TimeoutError),
134
+ extra={"steps": len(batch), "reason": type(exc).__name__},
135
+ )
136
+ return
137
+ self._recorded.add(written)
138
+ if written < len(batch):
139
+ self._dropped.add(len(batch) - written, {"reason": "session_full"})
140
+
141
+ async def _run(self) -> None:
142
+ while True:
143
+ batch = await self._next_batch()
144
+ await self._write(batch)
145
+ for _ in batch:
146
+ self._queue.task_done()
147
+
148
+ async def prune_once(self) -> int:
149
+ """Delete expired steps (one batch); the number deleted."""
150
+ before = self._clock() - timedelta(days=self.settings.retention_days)
151
+ return await self._sink.prune(before)
152
+
153
+ async def _prune_loop(self) -> None:
154
+ while True:
155
+ try:
156
+ async with asyncio.timeout(self.settings.write_timeout_s):
157
+ await self.prune_once()
158
+ except Exception:
159
+ logger.warning("deleting expired agent trace steps failed", exc_info=True)
160
+ await asyncio.sleep(self.settings.prune_interval_s)
161
+
162
+ async def flush(self) -> None:
163
+ """Wait until every queued step is written or dropped."""
164
+ if self._writer is not None and not self._writer.done():
165
+ await self._queue.join()
166
+
167
+ async def aclose(self) -> None:
168
+ """Write what is queued (within one write timeout), then stop."""
169
+ with contextlib.suppress(TimeoutError):
170
+ async with asyncio.timeout(self.settings.write_timeout_s):
171
+ await self.flush()
172
+ for task in (self._writer, self._pruner):
173
+ if task is not None:
174
+ task.cancel()
175
+ with contextlib.suppress(asyncio.CancelledError):
176
+ await task
177
+ self._writer = self._pruner = None
178
+ while not self._queue.empty():
179
+ self._queue.get_nowait()
180
+ self._dropped.add(1, {"reason": "shutdown"})
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.5
2
+ Name: lorebase-keeper
3
+ Version: 0.2.3
4
+ Summary: Lorebase Keeper: REST API service
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: asyncpg>=0.29
7
+ Requires-Dist: fastapi>=0.115
8
+ Requires-Dist: httpx>=0.27
9
+ Requires-Dist: lorebase-platform<0.3,>=0.2
10
+ Requires-Dist: lorebase-store<0.3,>=0.2
11
+ Requires-Dist: opentelemetry-api>=1.25
12
+ Requires-Dist: pydantic>=2.7
13
+ Requires-Dist: pyjwt[crypto]>=2.8
14
+ Requires-Dist: python-multipart>=0.0.9
15
+ Requires-Dist: uvicorn>=0.30
16
+ Provides-Extra: mssql
17
+ Requires-Dist: pymssql>=2.3; extra == 'mssql'
18
+ Provides-Extra: mysql
19
+ Requires-Dist: asyncmy>=0.2.10; extra == 'mysql'
20
+ Provides-Extra: parquet
21
+ Requires-Dist: pyarrow>=15; extra == 'parquet'
@@ -0,0 +1,126 @@
1
+ lorebase_keeper/__init__.py,sha256=PNiDER4qM19h9zdsdfgKt2_dT4WgYK7EguJ8RU2qA_g,22
2
+ lorebase_keeper/__main__.py,sha256=x1LJkv6CoRmGLVldb7TR9Xy64XKmk4TAPcktEmiy9ZE,18281
3
+ lorebase_keeper/app.py,sha256=PQDdbBwHHwl082kDhZAf2P7U08Sf1eOcUycbaBZUpKU,14066
4
+ lorebase_keeper/bootstrap.py,sha256=FT1y8SnKStlj3PTgrQsOHmWh6xrhSDdyS5YrhiJTdow,6082
5
+ lorebase_keeper/client_address.py,sha256=4Eh9IFkA-97dB8u6fKO-r7v5kq_SQI1ykJ0FYJnGXzw,5240
6
+ lorebase_keeper/context.py,sha256=qo87_EKMYcEypXBsLNkhXPf7CrvFhK7Xi8PGmUJrIU8,8522
7
+ lorebase_keeper/db.py,sha256=AbkgUWcJdTv56faSc9MT8MEG872weoadM9NsshJt7W4,3378
8
+ lorebase_keeper/deps.py,sha256=I7w-G7cdAF9aVVb9Ur9zJcBNnmK8XUJbitJwNR9gZgA,1657
9
+ lorebase_keeper/errors.py,sha256=saas1gA1MzNIZ1DAaiBJ__SMU18mswq_LIlkIp7yqGQ,8395
10
+ lorebase_keeper/health.py,sha256=5kwc63GETfyWumtYFjnmIfSXVhDDhCeGgeCyN_veZ-k,1921
11
+ lorebase_keeper/middleware.py,sha256=VHlfpcuG8wy7h5PviI8a6UeePaNOxGRWDjuRo5q41c4,10838
12
+ lorebase_keeper/pagination.py,sha256=MdzjSNm4roRw2JWXOWhKiONJnQxSvyaaLfnwsXanbLI,2865
13
+ lorebase_keeper/readiness.py,sha256=Wsa3uctVXCkrViTvtdXLPMjIBwD8PdCQRz78K1XFniY,9139
14
+ lorebase_keeper/settings.py,sha256=YfMnPzduFTA4fKByPhT0VtBnP9j63yKhTWdzLB1EFCY,13232
15
+ lorebase_keeper/agents/__init__.py,sha256=R5C2Vtdo8gT9WOzhcgyS4nwkvFaoflrWRc3S9rB-3no,94
16
+ lorebase_keeper/agents/budget.py,sha256=8ULj2Oa4CVGATdm9km7Hm9IYUawXd0gmny9lh_q7Y_4,8287
17
+ lorebase_keeper/agents/context.py,sha256=1guz-JAC-qmprdr_Ywie1g31JyABsTE1WjOEDt4qdHc,20258
18
+ lorebase_keeper/agents/explain.py,sha256=wiZQ6lyfUvMUaPiAyl9gLZBk9S47mIdu3dJ_NjGFtVE,21198
19
+ lorebase_keeper/agents/feed.py,sha256=OgxZVFU_NQE7vyfkHduJT8bA06MDDhWlGnSUdo9Ij6I,10055
20
+ lorebase_keeper/agents/markdown.py,sha256=HrqcEuWM5ObmEtbj8cNC2_nprj3pYt1dKl5xcGQ8pzg,7604
21
+ lorebase_keeper/agents/pack.py,sha256=EMGW39uIb4AdJ74hcVtdCz8azGwUuhzyc4RxQr9clb8,14085
22
+ lorebase_keeper/agents/settings.py,sha256=DbjUBwyUsWzCu92d85A3vFqaF3UwZlWp2aKPEN7oMWs,4736
23
+ lorebase_keeper/auth/__init__.py,sha256=h5un6W-oQ4g3mukAeCIykPTEC4IPh3hAuiSsdmMgXNM,159
24
+ lorebase_keeper/auth/api_keys.py,sha256=vaV0Uv9hYoezbHsG69BT2Bu3LQz4LyJwA0nu8s5VwJ4,4403
25
+ lorebase_keeper/auth/audit.py,sha256=PItD9qPPxzfxFQ7jDtKv-hbmEotovkAVk70dDdzDdW4,13648
26
+ lorebase_keeper/auth/cache.py,sha256=Q4mncF7GJ6CClCHctNwOytvVN6JgaSM5_PjY47bCWfc,1577
27
+ lorebase_keeper/auth/config.py,sha256=b4357HrOCL2UADqTwr7x3fieb-8jxVGvRGpg2IGNHRs,26196
28
+ lorebase_keeper/auth/deps.py,sha256=JpuaK2q83STiN5fXo-cCtXRDCZyGwUch1UBLTvEa3hg,7372
29
+ lorebase_keeper/auth/keyring.py,sha256=xrZ7UGimWkgEEcvGEH5G1slnnYG7lCNCHgV7SsRJVr4,405
30
+ lorebase_keeper/auth/oidc.py,sha256=tZQE-Clfe_CQevr-5BZRA7T-yokiA0_3lwgx39lNg9o,9382
31
+ lorebase_keeper/auth/permissions.py,sha256=dYVtjDV0JRO39auvFkNPjAwWhRuFdPELNTltr2PFMig,5944
32
+ lorebase_keeper/auth/ports.py,sha256=m2RdSWX4abXc_ZdpuLrPkCpzuo9uoQRjseeppM1PhGg,5745
33
+ lorebase_keeper/auth/principals.py,sha256=WvrkAeTS8crJAa5jr7wXS4m2yxO3d28AUSDz4fwocBA,15964
34
+ lorebase_keeper/auth/provider.py,sha256=1OWCLHVLSOVh9thrDu-nKXnR-n2A5i-X5guRmszX4Jw,10506
35
+ lorebase_keeper/auth/rbac.py,sha256=hnlWQHBiCNDkMv6pg6QY86aPfG-16iQeLgsfcHlbj1Y,10436
36
+ lorebase_keeper/auth/read_audit.py,sha256=xTHdlwziUPc3hq1Ksf_MOXxIroquo9ZEZpWUCqW0UrA,14457
37
+ lorebase_keeper/auth/runtime.py,sha256=PgRxamiIKIxo60LllrwoN3J9aw_bioh09iW_2ZoEXis,3862
38
+ lorebase_keeper/auth/sessions.py,sha256=uu3ejui9saA6AHRbc_caslOHSYnmmHqUEWyepHRgNns,19108
39
+ lorebase_keeper/kindhealth/__init__.py,sha256=6htr9hpIgXmBP9pBS_6SWt_ADjnY-C31nz1tFxQN_k4,269
40
+ lorebase_keeper/kindhealth/config.py,sha256=Yxe41f_0wZ4_20uTv5zf7y7jxqFYV86KZ1_w6SwLeZY,2025
41
+ lorebase_keeper/kindhealth/markdown.py,sha256=6HatKIWdum2bybOWs7d-CKOoxsza0vgfWRh4-AeQyVk,5744
42
+ lorebase_keeper/kindhealth/models.py,sha256=QqidtVhC0QiRfJuqUwhoh1e1MseLW2Jrj-i48plqfHs,6056
43
+ lorebase_keeper/kindhealth/report.py,sha256=J0y32FPIO8FvaUAytBoopeWF4ajcGraLdZnj8RX1ADI,6368
44
+ lorebase_keeper/kindhealth/scan.py,sha256=1QDujcBqajmTP1jrXkz5FlDT3N7ktXLngIuggcuhQFQ,18675
45
+ lorebase_keeper/ratelimit/__init__.py,sha256=cdTBn2v0px1zj5HvU87ztMRxMl1a4FQW9uiMiuUd6YY,470
46
+ lorebase_keeper/ratelimit/bucket.py,sha256=WiftA7otL6c62xej12ztKYxyQIoL-zQXlIf9fjzMXiA,3930
47
+ lorebase_keeper/ratelimit/config.py,sha256=yNVN_2XCOeBWcKg7U5di5P752WShxEjth5CNHeAPNpM,12230
48
+ lorebase_keeper/ratelimit/enforce.py,sha256=bWq7fCppqUweJnr5qUY1CTIC7T8tm1R2x0aD5ggKWv4,15498
49
+ lorebase_keeper/ratelimit/limiter.py,sha256=z73pJBnhIjiSehOKxmK0kjEbhwBahHtOpNJCqTXUomk,6301
50
+ lorebase_keeper/ratelimit/quotas.py,sha256=wjxyp7aDsDCv-V7-X917dVVyNCmK9AW0YMWrTwpD9oI,8012
51
+ lorebase_keeper/ratelimit/shared.py,sha256=tLA8wejpyrWRCh1N0XB8_J6dUJH5AeSNhoA20d3gw30,11006
52
+ lorebase_keeper/reading/__init__.py,sha256=vBXTyaPpgDvvxYb-wbI4n6jqDoH1Uy1LtMRTkROlKww,93
53
+ lorebase_keeper/reading/caching.py,sha256=8LAN8KntHC9Cnix11AGIJuZj2-6H4BvYdpbc0yhfFu0,9215
54
+ lorebase_keeper/reading/compiler.py,sha256=Gn7qGejxu1m84eJ33mA-VotaetWgN7yBJMdi39gyCS4,28255
55
+ lorebase_keeper/reading/cursors.py,sha256=DJkzHNdoNN4fgBs61D39uuHZbVwCNAL6EGeh1ddP8T8,1803
56
+ lorebase_keeper/reading/diff.py,sha256=IyvpkNm84UiYwMaeo1QoowSWVJX2ZdIMh92QhMOfJ0k,14570
57
+ lorebase_keeper/reading/graph.py,sha256=AS4GjNYSKgMcQxpi9-9AcD9lyVOnxLHhYwwgiznz1Vk,11090
58
+ lorebase_keeper/reading/history.py,sha256=anLlTjzRz1FVt878UDnBACrY-cue7S4sXvjRQ8AA6uc,4946
59
+ lorebase_keeper/reading/points.py,sha256=rhb6HRwjWWQyaKpz-eMjSg8exqnLDUQ0uTAzONlkTwQ,16429
60
+ lorebase_keeper/reading/problems.py,sha256=NjsAm6iggYpTX4sbUYqON7P29uUbCKDKta-Gfoaqg5I,2758
61
+ lorebase_keeper/reading/record_history.py,sha256=lUHYM6EVITI5jqToKMduwCzyXhDGvio_vNi9jgly08I,27512
62
+ lorebase_keeper/reading/records.py,sha256=N4EMKxyUXO1Eb6ganG8y92Ykj1DP-_Jfhs65ZcrR57s,30856
63
+ lorebase_keeper/reading/requests.py,sha256=RK_lTJVj3Qd1lCsRzz5QCp1XdhtNIfSafqkEF_gYjfY,4066
64
+ lorebase_keeper/reading/runtime.py,sha256=ckKK6DL4m2jRENJsdNK_IjUCG_F4rYo5AEWyO9p3VG8,5456
65
+ lorebase_keeper/reading/search.py,sha256=oWPNRAhrlHr7I3dTvOfx_WVz_LM1rWyueeHIdlMwJgs,27624
66
+ lorebase_keeper/reading/sensitivity.py,sha256=DGreazb6GA74ZJjXP9I8TDhqfVab4b-jKvapJsMTEfU,38730
67
+ lorebase_keeper/reading/settings.py,sha256=2nAQTDMbmwJE0cOBn7Yjz6sgWUPgLYHGYIBcP9f-J_U,14190
68
+ lorebase_keeper/reading/snapshots.py,sha256=zN7WbizLpxa8fdEUwWo6G8OcAS7v_eJ8Em-QbZ5rSGc,6684
69
+ lorebase_keeper/reading/tree.py,sha256=VzLSWkgsTsJ-fJBbBXO09Mm99qz-gfKziPfG4YVusv0,3766
70
+ lorebase_keeper/reading/views.py,sha256=1iqetYpM1Dr8Zsz443zfvNtRdmpSfJ8wwIjeOwb_YLE,8041
71
+ lorebase_keeper/reading/visibility.py,sha256=RO0nSo5RAKOMY5uAUoqUm6zSwaWzxI_hcBkXwrz3uF4,3576
72
+ lorebase_keeper/routes/__init__.py,sha256=Wp5IQRAcBuK-Rbqme6S6_CjhSF-69_lNANbqRVU8fJQ,19
73
+ lorebase_keeper/routes/admin.py,sha256=g9AxMENhMYQAtDqtFkFIQkjlbBm-asW5RwinstDbEwM,20928
74
+ lorebase_keeper/routes/agents.py,sha256=k44OnRkW3SMv1wvdZYAFnA4u2o1p14FcKuxb2B5I2d8,6273
75
+ lorebase_keeper/routes/branches.py,sha256=a7QFxl7foXuh0sE_UcL_WVUmStg59ySYxv7WSWCHiSs,15427
76
+ lorebase_keeper/routes/derivations.py,sha256=CBf37REWqRgpiKcBRvze-N_FQJtbmxAYYpGfakGRGAs,8636
77
+ lorebase_keeper/routes/documents.py,sha256=Pi9_tlWfyeuOVriGLvBPYcFfeH92FfnIH1-ypV_X0iU,19222
78
+ lorebase_keeper/routes/domain_api.py,sha256=BtlRpwtELvaESApYDW86VTdFp01Q30PLLcSX_PQGzTo,1742
79
+ lorebase_keeper/routes/domains.py,sha256=7CLywx12PjLkefyniY6vUcfNqr7E_cAt8mqURHqWFZU,8391
80
+ lorebase_keeper/routes/events.py,sha256=CU93hZo8dOkFsz2_uxulky2OYZ8JJX3JcgDB7eGfT1Y,6563
81
+ lorebase_keeper/routes/kind_health.py,sha256=5GHXTyhAn1NKBkJ0fRo-cSzE6np7nSBfc9Gd9NGFm-E,6077
82
+ lorebase_keeper/routes/operations.py,sha256=R08RPB5BYYG_o0_Kghg31-CkUwtR3Fqyra4UkYGO5fk,15040
83
+ lorebase_keeper/routes/proposal_items.py,sha256=yuqpxClDfrLjgV5fUYLbEFiEmsOWi_EmO2DsoqXwM50,21941
84
+ lorebase_keeper/routes/proposals.py,sha256=pShv9zsPZ3e6bJuuvj1VjlwciFIL_I1Xl_g3oq5SLfI,40256
85
+ lorebase_keeper/routes/read.py,sha256=aUsmEg8ofQpSicA8oxrgm9wsshrY-jU6zWvdF3NCu38,17193
86
+ lorebase_keeper/routes/revisions.py,sha256=y0mTKPTrp0GXtO41s3B9MHAzRAJqL-hofUXstzFZc7w,17937
87
+ lorebase_keeper/routes/schema.py,sha256=meHRJYfMx6Z5pkfquxvixqoPEUsAL6BvDiH8O4-TAmc,25240
88
+ lorebase_keeper/routes/schema_inference.py,sha256=xF-ZLTyM2TMzK0y_iBGVlg_TNdyCJnD3Ei5SJnLp-tA,17596
89
+ lorebase_keeper/routes/schema_suggestions.py,sha256=O6JSMSldn-oWN3b80VLZ--XqK4FjmwnL2P_4P7ieOt4,12844
90
+ lorebase_keeper/routes/sessions.py,sha256=E9tiO93oiJwD8keaKfKm-lKKJ4iGH4ok2pW0cof73_8,10528
91
+ lorebase_keeper/routes/source_preview.py,sha256=ZQhQsyatDCiG0X6LxkWWCHMydrH-aKif3gTbwTVuIg0,9724
92
+ lorebase_keeper/routes/sources.py,sha256=IXi18RNsYm31sqp7_eQ8ElzJdjs7b_1F2O3fp7JVG3c,8075
93
+ lorebase_keeper/routes/trace.py,sha256=EmmXtwuj4rj7LpwPCU4JzPwZsrZrXh8xSOVhiUwtqzg,19098
94
+ lorebase_keeper/routes/vault.py,sha256=tdNNaytbAciIFzbHUbCuLnjgn-3pUBOjRK2Oq2S_7z8,14406
95
+ lorebase_keeper/routes/webhooks.py,sha256=NJq8K2OOWuO84HpoJKdhY0iOYFl7JCrCJ4qdt9Vwawk,11737
96
+ lorebase_keeper/routes/whoami.py,sha256=F9_2DbdoS6yf_zol3u-raoGgtDiC2a6ufl6kqVQmTnY,2780
97
+ lorebase_keeper/services/__init__.py,sha256=mXfYcydUQabRtyQmufxkeO3GWs9SrcPJE9Fbf1i9pKc,72
98
+ lorebase_keeper/services/agent_writes.py,sha256=cOR7SlsxdRkyDkKYZJ-8Iy2VkGtuJp18_Q8kpfmE12I,36799
99
+ lorebase_keeper/services/branches.py,sha256=pOG2MAKeSss3mGiDKRiOJqBvxti64e_fIZy2DlF78yI,12823
100
+ lorebase_keeper/services/config.py,sha256=lMa_ELXZQrUiFJrbMeHQg5fcZpxLZXEQsbRru3RjWbc,18254
101
+ lorebase_keeper/services/derivation_preview.py,sha256=uyMbOf0B62XDBpc6jtCdcbH3jkg1q2MqY2hSdR6f2No,10506
102
+ lorebase_keeper/services/document_urls.py,sha256=me0GG23zkx_TcyHoJRAa7qWUusU7xlFaGQE4TrkHD-w,4885
103
+ lorebase_keeper/services/domains.py,sha256=mZ35vGe9NTsgXm1Khiacx3Xns1jApRdy-waWAzbiCSc,4910
104
+ lorebase_keeper/services/errors.py,sha256=V_F3IEczf0JgKVPETZV1ALFMUXNB96zAoO7GXVpxFXs,7388
105
+ lorebase_keeper/services/operation_catalog.py,sha256=8uDecT1-Lob8VSJHiG0puqqFnmKN4g2dhXVD02b-BHQ,31615
106
+ lorebase_keeper/services/operation_events.py,sha256=xrIGRUn__dW3bqn3jc6C3aBRaRGBAdZ9rCGPcRHgaW8,8588
107
+ lorebase_keeper/services/operations.py,sha256=YQ7mHvREAUwskLcXwp-dxidDzZveRP8l_cKFyeuJco8,47135
108
+ lorebase_keeper/services/pii_import.py,sha256=R-ya3-Wwq5X__5RLcUd0tztOhDo9MYcOiVGYTiMYeJ4,9585
109
+ lorebase_keeper/services/proposal_reads.py,sha256=eIKfhVneSyqCYOhcx9MmOHKMPSI8uI26aSyYxmBs7e0,6698
110
+ lorebase_keeper/services/proposals.py,sha256=Dp4bFvps4NLSXpWSNuBVVT840lzOUl7N4NH9NrlheZ4,31682
111
+ lorebase_keeper/services/reads.py,sha256=PEKmUc6IjKWRsI0ZsnUetZblM9XMvI7nGSXzV0wvOQw,11390
112
+ lorebase_keeper/services/schema.py,sha256=JfaTgZHC2rnWE-KRwwux7A2zdlygZ-uh5_du_lby8BA,22209
113
+ lorebase_keeper/services/schema_inference.py,sha256=9R65Y3w34m98fU84GiToMbLa2w30ZZkW_KvCXxyMNsU,15082
114
+ lorebase_keeper/services/schema_suggestions.py,sha256=0hRN9uMVmjx6p6o8Gat5oaxej6k8ONLAPUL1mJRNlVE,15362
115
+ lorebase_keeper/services/source_preview.py,sha256=4dmdjiyjt0eod-SK06C6Z-JBxaee3QSVI9ITN4NrwCk,4975
116
+ lorebase_keeper/tracing/__init__.py,sha256=EII0TYLnAVelpzHClIoEWrNPWQr2fPAtZEKGGqenf60,92
117
+ lorebase_keeper/tracing/capture.py,sha256=mp81BYNccABe6630mp6ZHAAT4pGKr4z4l_nsb1Mf0wU,13213
118
+ lorebase_keeper/tracing/config.py,sha256=4CIqnakxVgzf2NZKNsWB9fFvKB_4L1RskD0NMD2LMl8,6622
119
+ lorebase_keeper/tracing/explain.py,sha256=DgH2NCyVT9xR2lpRoGy56LA3Xz4bTI9lv4Ojlmxe7fY,3523
120
+ lorebase_keeper/tracing/middleware.py,sha256=VB5aL6XPpLxssS1AEB6dNoZ4_eGKMBflqBpGIt-aNLM,14650
121
+ lorebase_keeper/tracing/notes.py,sha256=G6lLKb2A0NGC78hXwa4UOxI8r3fR4D4qsjkFi_tljnQ,3211
122
+ lorebase_keeper/tracing/recorder.py,sha256=awXsq0IdhbaYBZY8PF-xDeWm3h4d82F577ZdXMoWljE,6975
123
+ lorebase_keeper-0.2.3.dist-info/METADATA,sha256=z8ckbTvPyqMbDDcY_0xAUbEqkRVCKbtO5rV48GapbTc,675
124
+ lorebase_keeper-0.2.3.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
125
+ lorebase_keeper-0.2.3.dist-info/entry_points.txt,sha256=mAPqxYVZQcFcHtVB0YYmYoGUXk_bZin5wsLuzOvIkXU,66
126
+ lorebase_keeper-0.2.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ lorebase-keeper = lorebase_keeper.__main__:main