cortexdbai 0.4.3__tar.gz → 0.5.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 (95) hide show
  1. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/PKG-INFO +1 -1
  2. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/v1/client.py +311 -0
  3. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/pyproject.toml +186 -186
  4. cortexdbai-0.5.0/tests/test_conflicts.py +310 -0
  5. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/.gitignore +0 -0
  6. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/README.md +0 -0
  7. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/__init__.py +0 -0
  8. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/__init__.py +0 -0
  9. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/ag2/__init__.py +0 -0
  10. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/ag2/agent.py +0 -0
  11. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/ag2/tools.py +0 -0
  12. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/agno/__init__.py +0 -0
  13. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/agno/memory.py +0 -0
  14. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/agno/tools.py +0 -0
  15. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/autogen/__init__.py +0 -0
  16. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/autogen/agent.py +0 -0
  17. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/autogen/tools.py +0 -0
  18. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/beeai/__init__.py +0 -0
  19. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/beeai/memory.py +0 -0
  20. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/beeai/tools.py +0 -0
  21. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/camel/__init__.py +0 -0
  22. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/camel/memory.py +0 -0
  23. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/camel/tools.py +0 -0
  24. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/controlflow/__init__.py +0 -0
  25. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/controlflow/memory.py +0 -0
  26. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/crewai/__init__.py +0 -0
  27. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/crewai/memory.py +0 -0
  28. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/crewai/tools.py +0 -0
  29. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/deepinfra/__init__.py +0 -0
  30. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/deepinfra/config.py +0 -0
  31. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/deepinfra/embeddings.py +0 -0
  32. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/deepinfra/openai_compat.py +0 -0
  33. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/dify/__init__.py +0 -0
  34. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/dify/manifest.yaml +0 -0
  35. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/dify/tool.py +0 -0
  36. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/dspy/__init__.py +0 -0
  37. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/dspy/memory.py +0 -0
  38. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/dspy/retriever.py +0 -0
  39. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/fireworks/__init__.py +0 -0
  40. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/fireworks/config.py +0 -0
  41. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/fireworks/embeddings.py +0 -0
  42. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/fireworks/openai_compat.py +0 -0
  43. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/flowise/__init__.py +0 -0
  44. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/flowise/node.py +0 -0
  45. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/google_adk/__init__.py +0 -0
  46. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/google_adk/tools.py +0 -0
  47. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/groq/__init__.py +0 -0
  48. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/groq/config.py +0 -0
  49. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/groq/embeddings.py +0 -0
  50. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/groq/openai_compat.py +0 -0
  51. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/hermes/__init__.py +0 -0
  52. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/hermes/provider.py +0 -0
  53. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/instructor/__init__.py +0 -0
  54. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/instructor/memory.py +0 -0
  55. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/langchain/__init__.py +0 -0
  56. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/langchain/memory.py +0 -0
  57. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/langchain/retriever.py +0 -0
  58. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/langchain/tools.py +0 -0
  59. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/langgraph/__init__.py +0 -0
  60. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/langgraph/memory.py +0 -0
  61. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/letta/__init__.py +0 -0
  62. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/letta/storage.py +0 -0
  63. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/llamaindex/__init__.py +0 -0
  64. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/llamaindex/memory.py +0 -0
  65. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/nemo_guardrails/__init__.py +0 -0
  66. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/nemo_guardrails/actions.py +0 -0
  67. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/nemo_guardrails/knowledge_base.py +0 -0
  68. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/ollama/__init__.py +0 -0
  69. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/ollama/config.py +0 -0
  70. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/ollama/embeddings.py +0 -0
  71. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/openai_agents/__init__.py +0 -0
  72. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/openai_agents/tools.py +0 -0
  73. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/prefect/__init__.py +0 -0
  74. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/prefect/blocks.py +0 -0
  75. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/prefect/tasks.py +0 -0
  76. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/pydanticai/__init__.py +0 -0
  77. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/pydanticai/dependencies.py +0 -0
  78. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/pydanticai/tools.py +0 -0
  79. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/smolagents/__init__.py +0 -0
  80. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/smolagents/tools.py +0 -0
  81. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/temporal/__init__.py +0 -0
  82. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/temporal/activities.py +0 -0
  83. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/temporal/interceptor.py +0 -0
  84. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/together/__init__.py +0 -0
  85. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/together/config.py +0 -0
  86. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/together/embeddings.py +0 -0
  87. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/together/openai_compat.py +0 -0
  88. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/vllm/__init__.py +0 -0
  89. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/vllm/config.py +0 -0
  90. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/vllm/embeddings.py +0 -0
  91. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/integrations/vllm/openai_compat.py +0 -0
  92. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/py.typed +0 -0
  93. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/v1/__init__.py +0 -0
  94. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/cortexdb/v1/exceptions.py +0 -0
  95. {cortexdbai-0.4.3 → cortexdbai-0.5.0}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cortexdbai
3
- Version: 0.4.3
3
+ Version: 0.5.0
4
4
  Summary: The Long-Term Memory Layer for AI Systems
5
5
  Project-URL: Homepage, https://cortexdb.ai
6
6
  Project-URL: Documentation, https://docs.cortexdb.ai
@@ -148,6 +148,99 @@ def _envelope(
148
148
  return env
149
149
 
150
150
 
151
+ # Per-action argument contract for POST /v1/conflicts/{id}/resolve. The
152
+ # server rejects unknown shapes with a 422; validating client-side gives the
153
+ # caller a `ValueError` naming the exact problem before any bytes move.
154
+ _RESOLVE_ACTIONS: dict = {
155
+ "pick": {"required": ("winner",), "optional": ("reason",)},
156
+ "split": {"required": ("boundary", "earlier", "later"), "optional": ()},
157
+ "new_information": {"required": ("record",), "optional": ()},
158
+ "dismiss": {"required": (), "optional": ("reason",)},
159
+ }
160
+
161
+
162
+ def _resolve_conflict_body(action: str, kwargs: Mapping[str, Any]) -> dict:
163
+ """Validate + build the resolve-conflict request body.
164
+
165
+ ``kwargs`` maps every action-specific parameter name to its value (or
166
+ ``None`` when the caller didn't pass it). Raises :class:`ValueError` on
167
+ an unknown action, a missing required parameter, or a parameter that
168
+ doesn't belong to the chosen action.
169
+ """
170
+ spec = _RESOLVE_ACTIONS.get(action)
171
+ if spec is None:
172
+ raise ValueError(
173
+ f"unknown resolve action {action!r}; expected one of "
174
+ f"{sorted(_RESOLVE_ACTIONS)}"
175
+ )
176
+ allowed = set(spec["required"]) | set(spec["optional"])
177
+ provided = {k for k, v in kwargs.items() if v is not None}
178
+ missing = [k for k in spec["required"] if k not in provided]
179
+ if missing:
180
+ raise ValueError(f"action {action!r} requires {missing}")
181
+ extraneous = sorted(provided - allowed)
182
+ if extraneous:
183
+ raise ValueError(
184
+ f"action {action!r} does not accept {extraneous} "
185
+ f"(allowed: {sorted(allowed)})"
186
+ )
187
+ body: dict = {"action": action}
188
+ for k in allowed:
189
+ v = kwargs.get(k)
190
+ if v is not None:
191
+ body[k] = v
192
+ if action in ("pick", "dismiss") and "reason" not in body:
193
+ body["reason"] = ""
194
+ return body
195
+
196
+
197
+ def _range_expr(value: Any) -> str:
198
+ """Normalize a bi-temporal range to the server's ``start..end`` string.
199
+
200
+ Accepts a preformatted ``"start..end"`` string or a 2-item
201
+ ``(start, end)`` sequence of date expressions.
202
+ """
203
+ if isinstance(value, str):
204
+ return value
205
+ try:
206
+ start, end = value
207
+ except (TypeError, ValueError) as e:
208
+ raise ValueError(
209
+ "range must be a 'start..end' string or a (start, end) pair"
210
+ ) from e
211
+ return f"{start}..{end}"
212
+
213
+
214
+ def _claims_params(
215
+ scope: str,
216
+ *,
217
+ subject: Optional[str],
218
+ predicate: Optional[str],
219
+ valid_as_of: Optional[str],
220
+ known_as_of: Optional[str],
221
+ valid_during: Optional[Any],
222
+ recorded_during: Optional[Any],
223
+ limit: Optional[int],
224
+ ) -> dict:
225
+ """Build the query params for ``GET /v1/claims``."""
226
+ params: dict = {"scope": scope}
227
+ if subject:
228
+ params["subject"] = subject
229
+ if predicate:
230
+ params["predicate"] = predicate
231
+ if valid_as_of:
232
+ params["valid_as_of"] = valid_as_of
233
+ if known_as_of:
234
+ params["known_as_of"] = known_as_of
235
+ if valid_during is not None:
236
+ params["valid_during"] = _range_expr(valid_during)
237
+ if recorded_during is not None:
238
+ params["recorded_during"] = _range_expr(recorded_during)
239
+ if limit is not None:
240
+ params["limit"] = limit
241
+ return params
242
+
243
+
151
244
  # ── Synchronous client ──────────────────────────────────────────────────────
152
245
 
153
246
 
@@ -492,6 +585,130 @@ class V1Client:
492
585
  body: dict = {"scope": scope, "topics": list(topics) if topics else []}
493
586
  return self._post("/v1/understanding/synthesize", body)
494
587
 
588
+ # ── conflicts + bi-temporal claims ────────────────────────────────
589
+ #
590
+ # Rendering note: RecordView boundaries carry `valid_from_basis` /
591
+ # `valid_to_basis` ("stated" | "observed"). An "observed" boundary is
592
+ # only a knowledge bound — present it as "by <date>", never
593
+ # "on/since <date>".
594
+
595
+ def list_conflicts(
596
+ self,
597
+ scope: str,
598
+ *,
599
+ status: str = "open",
600
+ limit: int = 50,
601
+ cursor: Optional[int] = None,
602
+ ) -> dict:
603
+ """``GET /v1/conflicts`` — the conflict queue for a scope.
604
+
605
+ ``status`` is ``"open"`` (default) or ``"all"``. Returns
606
+ ``{conflicts: [ConflictView], total, next_cursor}``; pass
607
+ ``next_cursor`` back as ``cursor`` to page.
608
+ """
609
+ params: dict = {"scope": scope, "status": status, "limit": limit}
610
+ if cursor is not None:
611
+ params["cursor"] = cursor
612
+ return self._get("/v1/conflicts", params=params)
613
+
614
+ def get_conflict(self, conflict_id: str) -> dict:
615
+ """``GET /v1/conflicts/{id}`` — one conflict with full member
616
+ records."""
617
+ return self._get(f"/v1/conflicts/{conflict_id}")
618
+
619
+ def resolve_conflict(
620
+ self,
621
+ conflict_id: str,
622
+ action: str,
623
+ *,
624
+ winner: Optional[str] = None,
625
+ reason: Optional[str] = None,
626
+ boundary: Optional[str] = None,
627
+ earlier: Optional[str] = None,
628
+ later: Optional[str] = None,
629
+ record: Optional[str] = None,
630
+ ) -> dict:
631
+ """``POST /v1/conflicts/{id}/resolve`` — manually resolve a conflict.
632
+
633
+ Actions and their arguments:
634
+
635
+ * ``"pick"`` — ``winner`` (record UUID) required, ``reason`` optional.
636
+ * ``"split"`` — ``boundary`` (absolute date expression, e.g.
637
+ ``"2024-03"``), ``earlier`` and ``later`` (record UUIDs) required.
638
+ * ``"new_information"`` — ``record`` (record UUID) required.
639
+ * ``"dismiss"`` — ``reason`` optional.
640
+
641
+ Raises :class:`ValueError` on a bad action/argument combination.
642
+ Returns the post-resolution ``ConflictView``.
643
+ """
644
+ body = _resolve_conflict_body(
645
+ action,
646
+ {
647
+ "winner": winner,
648
+ "reason": reason,
649
+ "boundary": boundary,
650
+ "earlier": earlier,
651
+ "later": later,
652
+ "record": record,
653
+ },
654
+ )
655
+ return self._post(f"/v1/conflicts/{conflict_id}/resolve", body)
656
+
657
+ def query_claims(
658
+ self,
659
+ scope: str,
660
+ *,
661
+ subject: Optional[str] = None,
662
+ predicate: Optional[str] = None,
663
+ valid_as_of: Optional[str] = None,
664
+ known_as_of: Optional[str] = None,
665
+ valid_during: Optional[Any] = None,
666
+ recorded_during: Optional[Any] = None,
667
+ limit: Optional[int] = None,
668
+ ) -> dict:
669
+ """``GET /v1/claims`` — the two-axis bi-temporal record query
670
+ ("what was true at X, as known at Y").
671
+
672
+ * ``valid_as_of`` — world-time point (``"2023"``, ``"2023-06-01"``).
673
+ Defaults server-side to now.
674
+ * ``known_as_of`` — record-time point. Defaults server-side to now.
675
+ * ``valid_during`` / ``recorded_during`` — ranges; either a
676
+ ``"start..end"`` string or a ``(start, end)`` pair.
677
+
678
+ Returns ``{records: [RecordView]}``.
679
+ """
680
+ params = _claims_params(
681
+ scope,
682
+ subject=subject,
683
+ predicate=predicate,
684
+ valid_as_of=valid_as_of,
685
+ known_as_of=known_as_of,
686
+ valid_during=valid_during,
687
+ recorded_during=recorded_during,
688
+ limit=limit,
689
+ )
690
+ return self._get("/v1/claims", params=params)
691
+
692
+ def claim_history(self, scope: str, *, subject: str, predicate: str) -> dict:
693
+ """``GET /v1/claims/history`` — the full change-log of one claim:
694
+ every valid interval and record-time correction, plus any conflicts
695
+ involving the claim. Returns ``{claim, history, conflicts}``."""
696
+ return self._get(
697
+ "/v1/claims/history",
698
+ params={"scope": scope, "subject": subject, "predicate": predicate},
699
+ )
700
+
701
+ def belief_history(self, belief_id: str) -> dict:
702
+ """``GET /v1/beliefs/history`` — current belief + every superseded
703
+ semantic version, oldest first. Returns
704
+ ``{current, versions, revision_count}``."""
705
+ return self._get("/v1/beliefs/history", params={"belief_id": belief_id})
706
+
707
+ def concept_history(self, concept_id: str) -> dict:
708
+ """``GET /v1/concepts/{id}/history`` — current concept + superseded
709
+ semantic versions. Returns ``{current, versions}``."""
710
+ return self._get(f"/v1/concepts/{concept_id}/history")
711
+
495
712
  # ── forget + erasures ─────────────────────────────────────────────
496
713
 
497
714
  def forget(
@@ -798,6 +1015,100 @@ class AsyncV1Client:
798
1015
  body["question_date"] = question_date
799
1016
  return await self._post("/v1/answer", body)
800
1017
 
1018
+ # ── conflicts + bi-temporal claims ────────────────────────────────
1019
+ # Same surface + semantics as the sync client; see V1Client for the
1020
+ # full docstrings (including the "observed → by <date>" rendering rule).
1021
+
1022
+ async def list_conflicts(
1023
+ self,
1024
+ scope: str,
1025
+ *,
1026
+ status: str = "open",
1027
+ limit: int = 50,
1028
+ cursor: Optional[int] = None,
1029
+ ) -> dict:
1030
+ """``GET /v1/conflicts``. See :meth:`V1Client.list_conflicts`."""
1031
+ params: dict = {"scope": scope, "status": status, "limit": limit}
1032
+ if cursor is not None:
1033
+ params["cursor"] = cursor
1034
+ return await self._get("/v1/conflicts", params=params)
1035
+
1036
+ async def get_conflict(self, conflict_id: str) -> dict:
1037
+ """``GET /v1/conflicts/{id}``. See :meth:`V1Client.get_conflict`."""
1038
+ return await self._get(f"/v1/conflicts/{conflict_id}")
1039
+
1040
+ async def resolve_conflict(
1041
+ self,
1042
+ conflict_id: str,
1043
+ action: str,
1044
+ *,
1045
+ winner: Optional[str] = None,
1046
+ reason: Optional[str] = None,
1047
+ boundary: Optional[str] = None,
1048
+ earlier: Optional[str] = None,
1049
+ later: Optional[str] = None,
1050
+ record: Optional[str] = None,
1051
+ ) -> dict:
1052
+ """``POST /v1/conflicts/{id}/resolve``.
1053
+ See :meth:`V1Client.resolve_conflict` for the per-action contract."""
1054
+ body = _resolve_conflict_body(
1055
+ action,
1056
+ {
1057
+ "winner": winner,
1058
+ "reason": reason,
1059
+ "boundary": boundary,
1060
+ "earlier": earlier,
1061
+ "later": later,
1062
+ "record": record,
1063
+ },
1064
+ )
1065
+ return await self._post(f"/v1/conflicts/{conflict_id}/resolve", body)
1066
+
1067
+ async def query_claims(
1068
+ self,
1069
+ scope: str,
1070
+ *,
1071
+ subject: Optional[str] = None,
1072
+ predicate: Optional[str] = None,
1073
+ valid_as_of: Optional[str] = None,
1074
+ known_as_of: Optional[str] = None,
1075
+ valid_during: Optional[Any] = None,
1076
+ recorded_during: Optional[Any] = None,
1077
+ limit: Optional[int] = None,
1078
+ ) -> dict:
1079
+ """``GET /v1/claims``. See :meth:`V1Client.query_claims`."""
1080
+ params = _claims_params(
1081
+ scope,
1082
+ subject=subject,
1083
+ predicate=predicate,
1084
+ valid_as_of=valid_as_of,
1085
+ known_as_of=known_as_of,
1086
+ valid_during=valid_during,
1087
+ recorded_during=recorded_during,
1088
+ limit=limit,
1089
+ )
1090
+ return await self._get("/v1/claims", params=params)
1091
+
1092
+ async def claim_history(
1093
+ self, scope: str, *, subject: str, predicate: str
1094
+ ) -> dict:
1095
+ """``GET /v1/claims/history``. See :meth:`V1Client.claim_history`."""
1096
+ return await self._get(
1097
+ "/v1/claims/history",
1098
+ params={"scope": scope, "subject": subject, "predicate": predicate},
1099
+ )
1100
+
1101
+ async def belief_history(self, belief_id: str) -> dict:
1102
+ """``GET /v1/beliefs/history``. See :meth:`V1Client.belief_history`."""
1103
+ return await self._get(
1104
+ "/v1/beliefs/history", params={"belief_id": belief_id}
1105
+ )
1106
+
1107
+ async def concept_history(self, concept_id: str) -> dict:
1108
+ """``GET /v1/concepts/{id}/history``.
1109
+ See :meth:`V1Client.concept_history`."""
1110
+ return await self._get(f"/v1/concepts/{concept_id}/history")
1111
+
801
1112
  async def _get(
802
1113
  self,
803
1114
  path: str,