trustgraph-base 2.10.0__tar.gz → 2.10.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 (169) hide show
  1. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/PKG-INFO +1 -1
  2. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/async_bulk_client.py +4 -8
  3. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/async_flow.py +40 -3
  4. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/bulk_client.py +16 -19
  5. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/flow.py +15 -2
  6. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/types.py +24 -8
  7. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/__init__.py +1 -0
  8. trustgraph_base-2.10.2/trustgraph/base/policy_event_publisher.py +169 -0
  9. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/triples_client.py +9 -3
  10. trustgraph_base-2.10.2/trustgraph/base_version.py +1 -0
  11. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/retrieval.py +10 -3
  12. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/sparql_query.py +8 -1
  13. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/triples.py +6 -1
  14. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/__init__.py +2 -0
  15. trustgraph_base-2.10.2/trustgraph/schema/policy_event.py +22 -0
  16. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/retrieval.py +2 -0
  17. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/triples.py +3 -0
  18. trustgraph_base-2.10.2/trustgraph/schema/user_context.py +44 -0
  19. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph_base.egg-info/PKG-INFO +1 -1
  20. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph_base.egg-info/SOURCES.txt +3 -0
  21. trustgraph_base-2.10.0/trustgraph/base_version.py +0 -1
  22. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/README.md +0 -0
  23. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/pyproject.toml +0 -0
  24. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/setup.cfg +0 -0
  25. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/__init__.py +0 -0
  26. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/api.py +0 -0
  27. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/async_metrics.py +0 -0
  28. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/async_socket_client.py +0 -0
  29. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/collection.py +0 -0
  30. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/config.py +0 -0
  31. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/exceptions.py +0 -0
  32. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/explainability.py +0 -0
  33. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/knowledge.py +0 -0
  34. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/library.py +0 -0
  35. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/metrics.py +0 -0
  36. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/api/socket_client.py +0 -0
  37. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/agent_client.py +0 -0
  38. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/agent_service.py +0 -0
  39. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_backend.py +0 -0
  40. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_config_client.py +0 -0
  41. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_kafka_backend.py +0 -0
  42. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_librarian_client.py +0 -0
  43. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_processor.py +0 -0
  44. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_pulsar_backend.py +0 -0
  45. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_rabbitmq_backend.py +0 -0
  46. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/async_rr_wrapper.py +0 -0
  47. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/audit_publisher.py +0 -0
  48. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/backend.py +0 -0
  49. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/cassandra_config.py +0 -0
  50. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/chunking_service.py +0 -0
  51. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/collection_config_handler.py +0 -0
  52. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/config_client.py +0 -0
  53. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/consumer_spec.py +0 -0
  54. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/document_embeddings_client.py +0 -0
  55. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/document_embeddings_query_service.py +0 -0
  56. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/document_embeddings_store_service.py +0 -0
  57. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/dynamic_tool_service.py +0 -0
  58. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/embeddings_client.py +0 -0
  59. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/embeddings_service.py +0 -0
  60. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/flow.py +0 -0
  61. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/flow_processor.py +0 -0
  62. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/graph_embeddings_client.py +0 -0
  63. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/graph_embeddings_query_service.py +0 -0
  64. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/graph_embeddings_store_service.py +0 -0
  65. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/graph_rag_client.py +0 -0
  66. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/iam_client.py +0 -0
  67. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/image_to_text_service.py +0 -0
  68. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/keyword_index_client.py +0 -0
  69. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/keyword_index_service.py +0 -0
  70. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/librarian_spec.py +0 -0
  71. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/llm_service.py +0 -0
  72. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/logging.py +0 -0
  73. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/metrics.py +0 -0
  74. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/parameter_spec.py +0 -0
  75. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/processor_group.py +0 -0
  76. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/producer_spec.py +0 -0
  77. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/prompt_client.py +0 -0
  78. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/pubsub.py +0 -0
  79. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/qdrant_config.py +0 -0
  80. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/receiver_pool.py +0 -0
  81. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/request_response_client.py +0 -0
  82. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/request_response_spec.py +0 -0
  83. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/reranker_client.py +0 -0
  84. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/reranker_service.py +0 -0
  85. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/row_embeddings_query_client.py +0 -0
  86. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/schema_compatibility.py +0 -0
  87. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/sender_pool.py +0 -0
  88. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/serialization.py +0 -0
  89. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/sparql_client.py +0 -0
  90. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/spec.py +0 -0
  91. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/structured_query_client.py +0 -0
  92. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/text_completion_client.py +0 -0
  93. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/tool_client.py +0 -0
  94. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/tool_service.py +0 -0
  95. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/tool_service_client.py +0 -0
  96. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/triples_query_service.py +0 -0
  97. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/triples_store_service.py +0 -0
  98. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/base/workspace_processor.py +0 -0
  99. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/exceptions.py +0 -0
  100. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/__init__.py +0 -0
  101. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/__init__.py +0 -0
  102. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/ar.json +0 -0
  103. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/en.json +0 -0
  104. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/es.json +0 -0
  105. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/he.json +0 -0
  106. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/hi.json +0 -0
  107. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/pt.json +0 -0
  108. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/ru.json +0 -0
  109. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/sw.json +0 -0
  110. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/tr.json +0 -0
  111. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/i18n/packs/zh-cn.json +0 -0
  112. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/knowledge/__init__.py +0 -0
  113. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/knowledge/defs.py +0 -0
  114. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/knowledge/document.py +0 -0
  115. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/knowledge/identifier.py +0 -0
  116. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/knowledge/organization.py +0 -0
  117. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/knowledge/publication.py +0 -0
  118. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/log_level.py +0 -0
  119. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/__init__.py +0 -0
  120. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/registry.py +0 -0
  121. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/__init__.py +0 -0
  122. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/agent.py +0 -0
  123. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/base.py +0 -0
  124. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/collection.py +0 -0
  125. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/config.py +0 -0
  126. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/diagnosis.py +0 -0
  127. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/document_loading.py +0 -0
  128. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/embeddings.py +0 -0
  129. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/embeddings_query.py +0 -0
  130. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/flow.py +0 -0
  131. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/iam.py +0 -0
  132. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/image_to_text.py +0 -0
  133. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/knowledge.py +0 -0
  134. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/library.py +0 -0
  135. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/metadata.py +0 -0
  136. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/nlp_query.py +0 -0
  137. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/primitives.py +0 -0
  138. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/prompt.py +0 -0
  139. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/reranker.py +0 -0
  140. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/rows_query.py +0 -0
  141. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/structured_query.py +0 -0
  142. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/text_completion.py +0 -0
  143. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/messaging/translators/tool.py +0 -0
  144. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/objects/__init__.py +0 -0
  145. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/objects/field.py +0 -0
  146. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/objects/object.py +0 -0
  147. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/provenance/__init__.py +0 -0
  148. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/provenance/agent.py +0 -0
  149. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/provenance/namespaces.py +0 -0
  150. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/provenance/triples.py +0 -0
  151. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/provenance/uris.py +0 -0
  152. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/provenance/vocabulary.py +0 -0
  153. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/rdf.py +0 -0
  154. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/agent.py +0 -0
  155. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/audit.py +0 -0
  156. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/config.py +0 -0
  157. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/core/__init__.py +0 -0
  158. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/core/metadata.py +0 -0
  159. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/core/primitives.py +0 -0
  160. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/core/topic.py +0 -0
  161. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/documents.py +0 -0
  162. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/embeddings.py +0 -0
  163. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/iam.py +0 -0
  164. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/llm.py +0 -0
  165. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph/schema/structured.py +0 -0
  166. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph_base.egg-info/dependency_links.txt +0 -0
  167. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph_base.egg-info/entry_points.txt +0 -0
  168. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph_base.egg-info/requires.txt +0 -0
  169. {trustgraph_base-2.10.0 → trustgraph_base-2.10.2}/trustgraph_base.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trustgraph-base
3
- Version: 2.10.0
3
+ Version: 2.10.2
4
4
  Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
5
5
  Author-email: "trustgraph.ai" <security@trustgraph.ai>
6
6
  Project-URL: Homepage, https://github.com/trustgraph-ai/trustgraph
@@ -4,7 +4,7 @@ import websockets
4
4
  from typing import Optional, AsyncIterator, Dict, Any, Iterator
5
5
 
6
6
  from . types import Triple
7
- from . bulk_client import _string_to_term
7
+ from . bulk_client import _value_to_term
8
8
 
9
9
 
10
10
  class AsyncBulkClient:
@@ -46,13 +46,9 @@ class AsyncBulkClient:
46
46
  async with websockets.connect(ws_url, ping_interval=20, ping_timeout=self.timeout) as websocket:
47
47
  async for triple in triples:
48
48
  t = {
49
- "s": _string_to_term(triple.s),
50
- "p": _string_to_term(triple.p),
51
- "o": _string_to_term(
52
- triple.o,
53
- datatype=triple.o_datatype,
54
- language=triple.o_language,
55
- ),
49
+ "s": _value_to_term(triple.s),
50
+ "p": _value_to_term(triple.p),
51
+ "o": _value_to_term(triple.o),
56
52
  }
57
53
  if triple.g:
58
54
  t["g"] = triple.g
@@ -16,8 +16,8 @@ import base64
16
16
  from typing import Optional, Dict, Any, List
17
17
 
18
18
  from . types import TextCompletionResult, ImageToTextResult
19
-
20
19
  from . exceptions import ProtocolException, ApplicationException
20
+ from .. base.serialization import dataclass_to_dict
21
21
 
22
22
 
23
23
  def check_error(response):
@@ -529,7 +529,8 @@ class AsyncFlowInstance:
529
529
 
530
530
  async def graph_rag(self, query: str, collection: str,
531
531
  max_subgraph_size: int = 1000, max_subgraph_count: int = 5,
532
- max_entity_distance: int = 3, **kwargs: Any) -> str:
532
+ max_entity_distance: int = 3,
533
+ user_context=None, **kwargs: Any) -> str:
533
534
  """
534
535
  Execute graph-based RAG query (non-streaming).
535
536
 
@@ -572,6 +573,8 @@ class AsyncFlowInstance:
572
573
  "max-entity-distance": max_entity_distance,
573
574
  "streaming": False
574
575
  }
576
+ if user_context is not None:
577
+ request_data["user-context"] = dataclass_to_dict(user_context)
575
578
  request_data.update(kwargs)
576
579
 
577
580
  result = await self.request("graph-rag", request_data)
@@ -721,7 +724,8 @@ class AsyncFlowInstance:
721
724
 
722
725
  return await self.request("reranker", request_data)
723
726
 
724
- async def triples_query(self, s=None, p=None, o=None, collection=None, limit=100, **kwargs: Any):
727
+ async def triples_query(self, s=None, p=None, o=None, collection=None, limit=100,
728
+ user_context=None, **kwargs: Any):
725
729
  """
726
730
  Query RDF triples using pattern matching.
727
731
 
@@ -763,10 +767,43 @@ class AsyncFlowInstance:
763
767
  request_data["o"] = str(o)
764
768
  if collection is not None:
765
769
  request_data["collection"] = collection
770
+ if user_context is not None:
771
+ request_data["user-context"] = dataclass_to_dict(user_context)
766
772
  request_data.update(kwargs)
767
773
 
768
774
  return await self.request("triples", request_data)
769
775
 
776
+ async def sparql_query(self, query: str, collection: str = "default",
777
+ limit: int = 10000, user_context=None,
778
+ **kwargs: Any):
779
+ """
780
+ Execute a SPARQL query against the knowledge graph.
781
+
782
+ Args:
783
+ query: SPARQL 1.1 query string
784
+ collection: Collection identifier (default: "default")
785
+ limit: Safety limit on results (default: 10000)
786
+ user_context: Optional UserContext for policy-based filtering
787
+ **kwargs: Additional service-specific parameters
788
+
789
+ Returns:
790
+ dict: Query results depending on query type (SELECT, ASK,
791
+ CONSTRUCT, DESCRIBE)
792
+
793
+ Raises:
794
+ ApplicationException: If an error occurs
795
+ """
796
+ request_data = {
797
+ "query": query,
798
+ "collection": collection,
799
+ "limit": limit,
800
+ }
801
+ if user_context is not None:
802
+ request_data["user-context"] = dataclass_to_dict(user_context)
803
+ request_data.update(kwargs)
804
+
805
+ return await self.request("sparql", request_data)
806
+
770
807
  async def rows_query(self, query: str, collection: str, variables: Optional[Dict] = None,
771
808
  operation_name: Optional[str] = None, **kwargs: Any):
772
809
  """
@@ -11,23 +11,24 @@ import asyncio
11
11
  import websockets
12
12
  from typing import Optional, Iterator, Dict, Any, Coroutine
13
13
 
14
- from . types import Triple
14
+ from . types import Triple, Uri, Literal
15
15
  from . exceptions import ProtocolException
16
16
 
17
17
 
18
- def _string_to_term(
19
- value: str, datatype: str = "", language: str = ""
20
- ) -> Dict[str, Any]:
21
- """Convert a string value to Term format for the gateway."""
18
+ def _value_to_term(value) -> Dict[str, Any]:
19
+ """Convert a Uri, Literal, or plain string to wire Term format."""
20
+ if isinstance(value, Uri):
21
+ return {"t": "i", "i": str(value)}
22
+ if isinstance(value, Literal):
23
+ result: Dict[str, Any] = {"t": "l", "v": str(value)}
24
+ if value.datatype:
25
+ result["dt"] = value.datatype
26
+ if value.language:
27
+ result["ln"] = value.language
28
+ return result
22
29
  if value.startswith("http://") or value.startswith("https://") or "://" in value:
23
30
  return {"t": "i", "i": value}
24
- else:
25
- result: Dict[str, Any] = {"t": "l", "v": value}
26
- if datatype:
27
- result["dt"] = datatype
28
- if language:
29
- result["ln"] = language
30
- return result
31
+ return {"t": "l", "v": value}
31
32
 
32
33
 
33
34
  class BulkClient:
@@ -145,13 +146,9 @@ class BulkClient:
145
146
  batch = []
146
147
  for triple in triples:
147
148
  t = {
148
- "s": _string_to_term(triple.s),
149
- "p": _string_to_term(triple.p),
150
- "o": _string_to_term(
151
- triple.o,
152
- datatype=triple.o_datatype,
153
- language=triple.o_language,
154
- ),
149
+ "s": _value_to_term(triple.s),
150
+ "p": _value_to_term(triple.p),
151
+ "o": _value_to_term(triple.o),
155
152
  }
156
153
  if triple.g:
157
154
  t["g"] = triple.g
@@ -11,6 +11,7 @@ import base64
11
11
 
12
12
  from .. knowledge import hash, Uri, Literal, QuotedTriple
13
13
  from .. schema import IRI, LITERAL, TRIPLE
14
+ from .. base.serialization import dataclass_to_dict
14
15
  from . types import Triple, TextCompletionResult, ImageToTextResult
15
16
  from . exceptions import ProtocolException
16
17
 
@@ -406,6 +407,7 @@ class FlowInstance:
406
407
  entity_limit=50, triple_limit=30, max_subgraph_size=150,
407
408
  max_path_length=2, edge_score_limit=30, edge_limit=25,
408
409
  max_reranker_input=350,
410
+ user_context=None,
409
411
  ):
410
412
  """
411
413
  Execute graph-based Retrieval-Augmented Generation (RAG) query.
@@ -452,6 +454,9 @@ class FlowInstance:
452
454
  "max-reranker-input": max_reranker_input,
453
455
  }
454
456
 
457
+ if user_context is not None:
458
+ input["user-context"] = dataclass_to_dict(user_context)
459
+
455
460
  result = self.request(
456
461
  "service/graph-rag",
457
462
  input
@@ -772,7 +777,8 @@ class FlowInstance:
772
777
 
773
778
  def triples_query(
774
779
  self, s=None, p=None, o=None, g=None,
775
- collection=None, limit=10000
780
+ collection=None, limit=10000,
781
+ user_context=None,
776
782
  ):
777
783
  """
778
784
  Query knowledge graph triples using pattern matching.
@@ -848,6 +854,9 @@ class FlowInstance:
848
854
  if g is not None:
849
855
  input["g"] = g
850
856
 
857
+ if user_context is not None:
858
+ input["user-context"] = dataclass_to_dict(user_context)
859
+
851
860
  object = self.request(
852
861
  "service/triples",
853
862
  input
@@ -1103,7 +1112,8 @@ class FlowInstance:
1103
1112
 
1104
1113
  def sparql_query(
1105
1114
  self, query,collection="default",
1106
- limit=10000
1115
+ limit=10000,
1116
+ user_context=None,
1107
1117
  ):
1108
1118
  """
1109
1119
  Execute a SPARQL query against the knowledge graph.
@@ -1129,6 +1139,9 @@ class FlowInstance:
1129
1139
  "limit": limit,
1130
1140
  }
1131
1141
 
1142
+ if user_context is not None:
1143
+ input["user-context"] = dataclass_to_dict(user_context)
1144
+
1132
1145
  response = self.request("service/sparql", input)
1133
1146
 
1134
1147
  if "error" in response and response["error"]:
@@ -8,7 +8,23 @@ graph elements, metadata structures, and streaming response chunks.
8
8
  import dataclasses
9
9
  import datetime
10
10
  from typing import List, Optional, Dict, Any
11
- from .. knowledge import hash, Uri, Literal
11
+
12
+ class Literal(str):
13
+ def __new__(cls, value, datatype=None, language=None):
14
+ return str.__new__(cls, value)
15
+ def __init__(self, value, datatype=None, language=None):
16
+ self.datatype = datatype
17
+ self.language = language
18
+ def is_uri(self): return False
19
+ def is_literal(self): return True
20
+ def is_triple(self): return False
21
+
22
+ class Uri(str):
23
+ def __init__(self, value):
24
+ str(value)
25
+ def is_uri(self): return True
26
+ def is_literal(self): return False
27
+ def is_triple(self): return False
12
28
 
13
29
  @dataclasses.dataclass
14
30
  class Triple:
@@ -19,17 +35,17 @@ class Triple:
19
35
  s: Subject (entity URI or value)
20
36
  p: Predicate (relationship URI)
21
37
  o: Object (entity URI, literal value, or typed value)
22
- o_datatype: XSD datatype URI for literal objects (e.g. "xsd:string")
23
- o_language: Language tag for literal objects (e.g. "en", "lt")
24
38
  g: Named graph URI (e.g. "urn:graph:catalog")
25
39
  """
26
- s : str
27
- p : str
28
- o : str
29
- o_datatype : str = ""
30
- o_language : str = ""
40
+ s : Uri | str
41
+ p : Uri | str
42
+ o : Uri | Literal | str
31
43
  g : str = ""
32
44
 
45
+ def is_uri(self): return False
46
+ def is_literal(self): return False
47
+ def is_triple(self): return True
48
+
33
49
  @dataclasses.dataclass
34
50
  class ConfigKey:
35
51
  """
@@ -46,6 +46,7 @@ from . keyword_index_client import KeywordIndexClientSpec, KeywordIndexClient
46
46
  from . row_embeddings_query_client import RowEmbeddingsQueryClientSpec
47
47
  from . collection_config_handler import CollectionConfigHandler
48
48
  from . audit_publisher import AuditPublisher
49
+ from . policy_event_publisher import PolicyEventPublisher
49
50
  from . schema_compatibility import is_strict_mode_compatible
50
51
  from . async_backend import (
51
52
  AsyncPubSubBackend, AsyncBackendConsumer, AsyncBackendProducer, Message,
@@ -0,0 +1,169 @@
1
+
2
+ import json
3
+ import logging
4
+ from datetime import datetime, timezone
5
+ from uuid import uuid4
6
+ from collections import defaultdict
7
+
8
+ from trustgraph.schema import PolicyEvent, policy_events_queue
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ NODE_IRI_CAP = 100
13
+
14
+
15
+ class PolicyEventPublisher:
16
+
17
+ def __init__(self, component_name, async_backend=None):
18
+ self.component_name = component_name
19
+ self._handle = None
20
+ self._async_producer = None
21
+ self._async_backend = async_backend
22
+
23
+ async def start(self, sender_pool=None):
24
+ if sender_pool is not None:
25
+ self._handle = await sender_pool.add_producer(
26
+ topic=policy_events_queue,
27
+ schema=PolicyEvent,
28
+ )
29
+ elif self._async_backend is not None:
30
+ self._async_producer = (
31
+ await self._async_backend.create_producer(
32
+ topic=policy_events_queue,
33
+ schema=PolicyEvent,
34
+ )
35
+ )
36
+
37
+ async def stop(self):
38
+ if self._async_producer:
39
+ try:
40
+ await self._async_producer.close()
41
+ except BaseException:
42
+ pass
43
+ self._async_producer = None
44
+ if self._handle:
45
+ await self._handle.unregister()
46
+
47
+ async def emit(self, event_type, payload):
48
+ event = PolicyEvent(
49
+ schema_version=1,
50
+ event_id=str(uuid4()),
51
+ event_type=event_type,
52
+ timestamp=datetime.now(timezone.utc).isoformat(),
53
+ producer=self.component_name,
54
+ payload_json=json.dumps(payload),
55
+ )
56
+
57
+ try:
58
+ if self._handle:
59
+ await self._handle.send(event)
60
+ elif self._async_producer:
61
+ await self._async_producer.send(event)
62
+ except Exception as e:
63
+ logger.warning(f"Failed to emit policy event: {e}")
64
+
65
+ async def emit_evaluations(
66
+ self,
67
+ evaluations,
68
+ user_context,
69
+ request_id="",
70
+ query_s=None,
71
+ query_p=None,
72
+ query_o=None,
73
+ collection="",
74
+ graph="",
75
+ workspace="",
76
+ ):
77
+ """Batch evaluations by policy and emit one event per policy.
78
+
79
+ Evaluations with the same (policy_uri, determination, blocks)
80
+ are grouped into a single event. The node_iris list is capped
81
+ at NODE_IRI_CAP per event; node_count reflects the true total.
82
+ """
83
+
84
+ by_policy = defaultdict(list)
85
+ for ev in evaluations:
86
+ by_policy[(ev.policy_uri, ev.policy_label,
87
+ ev.determination, ev.blocks)].append(ev)
88
+
89
+ for (policy_uri, policy_label, determination, blocks), group in (
90
+ by_policy.items()
91
+ ):
92
+ node_iris = [ev.node_iri for ev in group]
93
+ node_count = len(node_iris)
94
+
95
+ reason = group[0].reason if group else ""
96
+
97
+ payload = {
98
+ "request_id": request_id,
99
+ "policy_uri": policy_uri,
100
+ "policy_label": policy_label,
101
+ "determination": determination,
102
+ "blocks": blocks,
103
+ "reason": reason,
104
+ "user_context": self._serialise_user_context(
105
+ user_context
106
+ ),
107
+ "node_iris": node_iris[:NODE_IRI_CAP],
108
+ "node_count": node_count,
109
+ "query_s": query_s,
110
+ "query_p": query_p,
111
+ "query_o": query_o,
112
+ "collection": collection,
113
+ "graph": graph,
114
+ "workspace": workspace,
115
+ }
116
+
117
+ await self.emit("policy.evaluation", payload)
118
+
119
+ def _serialise_user_context(self, user_context):
120
+ if user_context is None:
121
+ return None
122
+
123
+ result = {
124
+ "user_id": user_context.user_id,
125
+ "roles": user_context.roles,
126
+ "organisational_units": user_context.organisational_units,
127
+ "purpose": user_context.purpose,
128
+ }
129
+
130
+ if user_context.assignments:
131
+ result["assignments"] = [
132
+ {
133
+ "resource": a.resource,
134
+ "scope": a.scope,
135
+ "status": a.status,
136
+ "valid_from": a.valid_from,
137
+ "valid_to": a.valid_to,
138
+ "qualifiers": a.qualifiers,
139
+ }
140
+ for a in user_context.assignments
141
+ ]
142
+
143
+ if user_context.entitlements:
144
+ result["entitlements"] = [
145
+ {
146
+ "resource_scope": e.resource_scope,
147
+ "access_level": e.access_level,
148
+ "valid_from": e.valid_from,
149
+ "valid_to": e.valid_to,
150
+ }
151
+ for e in user_context.entitlements
152
+ ]
153
+
154
+ if user_context.override_authorities:
155
+ result["override_authorities"] = [
156
+ {
157
+ "policy_area": oa.policy_area,
158
+ "condition": oa.condition,
159
+ }
160
+ for oa in user_context.override_authorities
161
+ ]
162
+
163
+ if user_context.delegation:
164
+ result["delegation"] = {
165
+ "delegator_id": user_context.delegation.delegator_id,
166
+ "scope": user_context.delegation.scope,
167
+ }
168
+
169
+ return result
@@ -48,7 +48,8 @@ class TriplesClient:
48
48
 
49
49
  async def query_gen(self, s=None, p=None, o=None, limit=20,
50
50
  collection="default",
51
- batch_size=20, timeout=30, g=None):
51
+ batch_size=20, timeout=30, g=None,
52
+ user_context=None):
52
53
  """Async generator yielding Triple objects as batches arrive."""
53
54
  queue = asyncio.Queue()
54
55
  done = False
@@ -79,6 +80,7 @@ class TriplesClient:
79
80
  streaming=True,
80
81
  batch_size=batch_size,
81
82
  g=g,
83
+ user_context=user_context,
82
84
  ),
83
85
  timeout=timeout,
84
86
  recipient=recipient,
@@ -101,7 +103,8 @@ class TriplesClient:
101
103
 
102
104
  async def query(self, s=None, p=None, o=None, limit=20,
103
105
  collection="default",
104
- timeout=30, g=None):
106
+ timeout=30, g=None,
107
+ user_context=None):
105
108
 
106
109
  resp = await self.request(
107
110
  TriplesQueryRequest(
@@ -111,6 +114,7 @@ class TriplesClient:
111
114
  limit = limit,
112
115
  collection = collection,
113
116
  g = g,
117
+ user_context = user_context,
114
118
  ),
115
119
  timeout=timeout
116
120
  )
@@ -128,7 +132,8 @@ class TriplesClient:
128
132
  async def query_stream(self, s=None, p=None, o=None, limit=20,
129
133
  collection="default",
130
134
  batch_size=20, timeout=30,
131
- batch_callback=None, g=None):
135
+ batch_callback=None, g=None,
136
+ user_context=None):
132
137
  """
133
138
  Streaming triple query - calls callback for each batch as it arrives.
134
139
 
@@ -173,6 +178,7 @@ class TriplesClient:
173
178
  streaming=True,
174
179
  batch_size=batch_size,
175
180
  g=g,
181
+ user_context=user_context,
176
182
  ),
177
183
  timeout=timeout,
178
184
  recipient=recipient,
@@ -0,0 +1 @@
1
+ __version__ = "2.10.2"
@@ -1,5 +1,7 @@
1
1
  from typing import Dict, Any, Tuple
2
2
  from ...schema import DocumentRagQuery, DocumentRagResponse, GraphRagQuery, GraphRagResponse
3
+ from ...schema import UserContext
4
+ from ...base.serialization import dict_to_dataclass, dataclass_to_dict
3
5
  from .base import MessageTranslator
4
6
  from .primitives import TripleTranslator
5
7
 
@@ -94,6 +96,7 @@ class GraphRagRequestTranslator(MessageTranslator):
94
96
  """Translator for GraphRagQuery schema objects"""
95
97
 
96
98
  def decode(self, data: Dict[str, Any]) -> GraphRagQuery:
99
+ uc = data.get("user-context")
97
100
  return GraphRagQuery(
98
101
  query=data["query"],
99
102
  collection=data.get("collection", "default"),
@@ -104,11 +107,12 @@ class GraphRagRequestTranslator(MessageTranslator):
104
107
  edge_score_limit=int(data.get("edge-score-limit", 30)),
105
108
  edge_limit=int(data.get("edge-limit", 25)),
106
109
  max_reranker_input=int(data.get("max-reranker-input", 350)),
107
- streaming=data.get("streaming", False)
110
+ streaming=data.get("streaming", False),
111
+ user_context=dict_to_dataclass(uc, UserContext) if uc else None,
108
112
  )
109
113
 
110
114
  def encode(self, obj: GraphRagQuery) -> Dict[str, Any]:
111
- return {
115
+ result = {
112
116
  "query": obj.query,
113
117
  "collection": obj.collection,
114
118
  "entity-limit": obj.entity_limit,
@@ -118,8 +122,11 @@ class GraphRagRequestTranslator(MessageTranslator):
118
122
  "edge-score-limit": obj.edge_score_limit,
119
123
  "edge-limit": obj.edge_limit,
120
124
  "max-reranker-input": obj.max_reranker_input,
121
- "streaming": getattr(obj, "streaming", False)
125
+ "streaming": getattr(obj, "streaming", False),
122
126
  }
127
+ if obj.user_context is not None:
128
+ result["user-context"] = dataclass_to_dict(obj.user_context)
129
+ return result
123
130
 
124
131
 
125
132
  class GraphRagResponseTranslator(MessageTranslator):
@@ -2,7 +2,9 @@ from typing import Dict, Any, Tuple
2
2
  from ...schema import (
3
3
  SparqlQueryRequest, SparqlQueryResponse, SparqlBinding,
4
4
  Error, Term, Triple, IRI, LITERAL, BLANK,
5
+ UserContext,
5
6
  )
7
+ from ...base.serialization import dict_to_dataclass, dataclass_to_dict
6
8
  from .base import MessageTranslator
7
9
  from .primitives import TermTranslator, TripleTranslator
8
10
 
@@ -11,22 +13,27 @@ class SparqlQueryRequestTranslator(MessageTranslator):
11
13
  """Translator for SparqlQueryRequest schema objects."""
12
14
 
13
15
  def decode(self, data: Dict[str, Any]) -> SparqlQueryRequest:
16
+ uc = data.get("user-context")
14
17
  return SparqlQueryRequest(
15
18
  collection=data.get("collection", "default"),
16
19
  query=data.get("query", ""),
17
20
  limit=int(data.get("limit", 10000)),
18
21
  streaming=data.get("streaming", False),
19
22
  batch_size=int(data.get("batch-size", 20)),
23
+ user_context=dict_to_dataclass(uc, UserContext) if uc else None,
20
24
  )
21
25
 
22
26
  def encode(self, obj: SparqlQueryRequest) -> Dict[str, Any]:
23
- return {
27
+ result = {
24
28
  "collection": obj.collection,
25
29
  "query": obj.query,
26
30
  "limit": obj.limit,
27
31
  "streaming": obj.streaming,
28
32
  "batch-size": obj.batch_size,
29
33
  }
34
+ if obj.user_context is not None:
35
+ result["user-context"] = dataclass_to_dict(obj.user_context)
36
+ return result
30
37
 
31
38
 
32
39
  class SparqlQueryResponseTranslator(MessageTranslator):
@@ -1,5 +1,6 @@
1
1
  from typing import Dict, Any, Tuple, Optional
2
- from ...schema import TriplesQueryRequest, TriplesQueryResponse
2
+ from ...schema import TriplesQueryRequest, TriplesQueryResponse, UserContext
3
+ from ...base.serialization import dict_to_dataclass, dataclass_to_dict
3
4
  from .base import MessageTranslator
4
5
  from .primitives import ValueTranslator, SubgraphTranslator
5
6
 
@@ -15,6 +16,7 @@ class TriplesQueryRequestTranslator(MessageTranslator):
15
16
  p = self.value_translator.decode(data["p"]) if "p" in data else None
16
17
  o = self.value_translator.decode(data["o"]) if "o" in data else None
17
18
  g = data.get("g") # None=default graph, "*"=all graphs
19
+ uc = data.get("user-context")
18
20
 
19
21
  return TriplesQueryRequest(
20
22
  s=s,
@@ -25,6 +27,7 @@ class TriplesQueryRequestTranslator(MessageTranslator):
25
27
  collection=data.get("collection", "default"),
26
28
  streaming=data.get("streaming", False),
27
29
  batch_size=int(data.get("batch-size", 20)),
30
+ user_context=dict_to_dataclass(uc, UserContext) if uc else None,
28
31
  )
29
32
 
30
33
  def encode(self, obj: TriplesQueryRequest) -> Dict[str, Any]:
@@ -43,6 +46,8 @@ class TriplesQueryRequestTranslator(MessageTranslator):
43
46
  result["o"] = self.value_translator.encode(obj.o)
44
47
  if obj.g is not None:
45
48
  result["g"] = obj.g
49
+ if obj.user_context is not None:
50
+ result["user-context"] = dataclass_to_dict(obj.user_context)
46
51
 
47
52
  return result
48
53
 
@@ -13,3 +13,5 @@ from .agent import *
13
13
  from .config import *
14
14
  from .iam import *
15
15
  from .audit import *
16
+ from .policy_event import *
17
+ from .user_context import *
@@ -0,0 +1,22 @@
1
+
2
+ from dataclasses import dataclass, field
3
+
4
+ from .core.topic import queue
5
+
6
+ ############################################################################
7
+
8
+ # Policy events — see docs/tech-specs/policy-audit-events.md for spec.
9
+
10
+ @dataclass
11
+ class PolicyEvent:
12
+ schema_version: int = 1
13
+ event_id: str = ""
14
+ event_type: str = ""
15
+ timestamp: str = ""
16
+ producer: str = ""
17
+ payload_json: str = ""
18
+
19
+
20
+ policy_events_queue = queue('policy-events', cls='notify')
21
+
22
+ ############################################################################