trustgraph-base 2.2.12__tar.gz → 2.2.13__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 (159) hide show
  1. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/PKG-INFO +1 -1
  2. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/__init__.py +2 -0
  3. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/explainability.py +77 -48
  4. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/socket_client.py +4 -2
  5. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/types.py +4 -0
  6. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/graph_rag_client.py +2 -0
  7. trustgraph_base-2.2.13/trustgraph/base_version.py +1 -0
  8. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/provenance/__init__.py +4 -0
  9. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/provenance/agent.py +49 -31
  10. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/provenance/namespaces.py +1 -0
  11. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/provenance/triples.py +29 -9
  12. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/retrieval.py +1 -0
  13. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph_base.egg-info/PKG-INFO +1 -1
  14. trustgraph_base-2.2.12/trustgraph/base_version.py +0 -1
  15. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/README.md +0 -0
  16. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/pyproject.toml +0 -0
  17. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/setup.cfg +0 -0
  18. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/api.py +0 -0
  19. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/async_bulk_client.py +0 -0
  20. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/async_flow.py +0 -0
  21. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/async_metrics.py +0 -0
  22. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/async_socket_client.py +0 -0
  23. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/bulk_client.py +0 -0
  24. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/collection.py +0 -0
  25. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/config.py +0 -0
  26. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/exceptions.py +0 -0
  27. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/flow.py +0 -0
  28. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/knowledge.py +0 -0
  29. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/library.py +0 -0
  30. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/api/metrics.py +0 -0
  31. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/__init__.py +0 -0
  32. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/agent_client.py +0 -0
  33. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/agent_service.py +0 -0
  34. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/async_processor.py +0 -0
  35. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/backend.py +0 -0
  36. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/cassandra_config.py +0 -0
  37. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/chunking_service.py +0 -0
  38. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/collection_config_handler.py +0 -0
  39. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/consumer.py +0 -0
  40. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/consumer_spec.py +0 -0
  41. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/document_embeddings_client.py +0 -0
  42. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/document_embeddings_query_service.py +0 -0
  43. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/document_embeddings_store_service.py +0 -0
  44. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/dynamic_tool_service.py +0 -0
  45. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/embeddings_client.py +0 -0
  46. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/embeddings_service.py +0 -0
  47. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/flow.py +0 -0
  48. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/flow_processor.py +0 -0
  49. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/graph_embeddings_client.py +0 -0
  50. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/graph_embeddings_query_service.py +0 -0
  51. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/graph_embeddings_store_service.py +0 -0
  52. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/llm_service.py +0 -0
  53. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/logging.py +0 -0
  54. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/metrics.py +0 -0
  55. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/parameter_spec.py +0 -0
  56. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/producer.py +0 -0
  57. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/producer_spec.py +0 -0
  58. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/prompt_client.py +0 -0
  59. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/publisher.py +0 -0
  60. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/pubsub.py +0 -0
  61. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/pulsar_backend.py +0 -0
  62. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/request_response_spec.py +0 -0
  63. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/row_embeddings_query_client.py +0 -0
  64. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/spec.py +0 -0
  65. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/structured_query_client.py +0 -0
  66. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/subscriber.py +0 -0
  67. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/subscriber_spec.py +0 -0
  68. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/text_completion_client.py +0 -0
  69. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/tool_client.py +0 -0
  70. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/tool_service.py +0 -0
  71. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/tool_service_client.py +0 -0
  72. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/triples_client.py +0 -0
  73. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/triples_query_service.py +0 -0
  74. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/base/triples_store_service.py +0 -0
  75. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/__init__.py +0 -0
  76. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/agent_client.py +0 -0
  77. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/base.py +0 -0
  78. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/config_client.py +0 -0
  79. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/document_embeddings_client.py +0 -0
  80. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/document_rag_client.py +0 -0
  81. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/embeddings_client.py +0 -0
  82. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/graph_embeddings_client.py +0 -0
  83. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/graph_rag_client.py +0 -0
  84. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/llm_client.py +0 -0
  85. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/prompt_client.py +0 -0
  86. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/row_embeddings_client.py +0 -0
  87. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/clients/triples_query_client.py +0 -0
  88. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/exceptions.py +0 -0
  89. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/knowledge/__init__.py +0 -0
  90. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/knowledge/defs.py +0 -0
  91. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/knowledge/document.py +0 -0
  92. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/knowledge/identifier.py +0 -0
  93. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/knowledge/organization.py +0 -0
  94. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/knowledge/publication.py +0 -0
  95. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/log_level.py +0 -0
  96. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/__init__.py +0 -0
  97. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/registry.py +0 -0
  98. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/__init__.py +0 -0
  99. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/agent.py +0 -0
  100. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/base.py +0 -0
  101. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/collection.py +0 -0
  102. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/config.py +0 -0
  103. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/diagnosis.py +0 -0
  104. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/document_loading.py +0 -0
  105. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/embeddings.py +0 -0
  106. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/embeddings_query.py +0 -0
  107. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/flow.py +0 -0
  108. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/knowledge.py +0 -0
  109. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/library.py +0 -0
  110. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/metadata.py +0 -0
  111. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/nlp_query.py +0 -0
  112. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/primitives.py +0 -0
  113. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/prompt.py +0 -0
  114. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/retrieval.py +0 -0
  115. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/rows_query.py +0 -0
  116. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/structured_query.py +0 -0
  117. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/text_completion.py +0 -0
  118. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/tool.py +0 -0
  119. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/messaging/translators/triples.py +0 -0
  120. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/objects/__init__.py +0 -0
  121. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/objects/field.py +0 -0
  122. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/objects/object.py +0 -0
  123. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/provenance/uris.py +0 -0
  124. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/provenance/vocabulary.py +0 -0
  125. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/rdf.py +0 -0
  126. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/__init__.py +0 -0
  127. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/core/__init__.py +0 -0
  128. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/core/metadata.py +0 -0
  129. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/core/primitives.py +0 -0
  130. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/core/topic.py +0 -0
  131. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/__init__.py +0 -0
  132. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/document.py +0 -0
  133. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/embeddings.py +0 -0
  134. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/graph.py +0 -0
  135. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/knowledge.py +0 -0
  136. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/nlp.py +0 -0
  137. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/object.py +0 -0
  138. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/rows.py +0 -0
  139. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/knowledge/structured.py +0 -0
  140. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/__init__.py +0 -0
  141. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/agent.py +0 -0
  142. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/collection.py +0 -0
  143. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/config.py +0 -0
  144. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/diagnosis.py +0 -0
  145. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/flow.py +0 -0
  146. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/library.py +0 -0
  147. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/llm.py +0 -0
  148. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/lookup.py +0 -0
  149. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/nlp_query.py +0 -0
  150. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/prompt.py +0 -0
  151. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/query.py +0 -0
  152. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/rows_query.py +0 -0
  153. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/storage.py +0 -0
  154. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/structured_query.py +0 -0
  155. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph/schema/services/tool_service.py +0 -0
  156. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph_base.egg-info/SOURCES.txt +0 -0
  157. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph_base.egg-info/dependency_links.txt +0 -0
  158. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/trustgraph_base.egg-info/requires.txt +0 -0
  159. {trustgraph_base-2.2.12 → trustgraph_base-2.2.13}/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.2.12
3
+ Version: 2.2.13
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
@@ -81,6 +81,7 @@ from .explainability import (
81
81
  Synthesis,
82
82
  Reflection,
83
83
  Analysis,
84
+ Observation,
84
85
  Conclusion,
85
86
  Decomposition,
86
87
  Finding,
@@ -164,6 +165,7 @@ __all__ = [
164
165
  "Focus",
165
166
  "Synthesis",
166
167
  "Analysis",
168
+ "Observation",
167
169
  "Conclusion",
168
170
  "EdgeSelection",
169
171
  "wire_triples_to_tuples",
@@ -40,6 +40,7 @@ TG_ANSWER_TYPE = TG + "Answer"
40
40
  TG_REFLECTION_TYPE = TG + "Reflection"
41
41
  TG_THOUGHT_TYPE = TG + "Thought"
42
42
  TG_OBSERVATION_TYPE = TG + "Observation"
43
+ TG_TOOL_USE = TG + "ToolUse"
43
44
  TG_GRAPH_RAG_QUESTION = TG + "GraphRagQuestion"
44
45
  TG_DOC_RAG_QUESTION = TG + "DocRagQuestion"
45
46
  TG_AGENT_QUESTION = TG + "AgentQuestion"
@@ -58,7 +59,6 @@ TG_PLAN_STEP = TG + "planStep"
58
59
  PROV = "http://www.w3.org/ns/prov#"
59
60
  PROV_STARTED_AT_TIME = PROV + "startedAtTime"
60
61
  PROV_WAS_DERIVED_FROM = PROV + "wasDerivedFrom"
61
- PROV_WAS_GENERATED_BY = PROV + "wasGeneratedBy"
62
62
 
63
63
  RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
64
64
  RDFS_LABEL = "http://www.w3.org/2000/01/rdf-schema#label"
@@ -102,6 +102,8 @@ class ExplainEntity:
102
102
  return StepResult.from_triples(uri, triples)
103
103
  elif TG_SYNTHESIS in types:
104
104
  return Synthesis.from_triples(uri, triples)
105
+ elif TG_OBSERVATION_TYPE in types and TG_REFLECTION_TYPE not in types:
106
+ return Observation.from_triples(uri, triples)
105
107
  elif TG_REFLECTION_TYPE in types:
106
108
  return Reflection.from_triples(uri, triples)
107
109
  elif TG_ANALYSIS in types:
@@ -279,18 +281,16 @@ class Reflection(ExplainEntity):
279
281
 
280
282
  @dataclass
281
283
  class Analysis(ExplainEntity):
282
- """Analysis entity - one think/act/observe cycle (Agent only)."""
284
+ """Analysis+ToolUse entity - decision + tool call (Agent only)."""
283
285
  action: str = ""
284
286
  arguments: str = "" # JSON string
285
287
  thought: str = ""
286
- observation: str = ""
287
288
 
288
289
  @classmethod
289
290
  def from_triples(cls, uri: str, triples: List[Tuple[str, str, Any]]) -> "Analysis":
290
291
  action = ""
291
292
  arguments = ""
292
293
  thought = ""
293
- observation = ""
294
294
 
295
295
  for s, p, o in triples:
296
296
  if p == TG_ACTION:
@@ -299,8 +299,6 @@ class Analysis(ExplainEntity):
299
299
  arguments = o
300
300
  elif p == TG_THOUGHT:
301
301
  thought = o
302
- elif p == TG_OBSERVATION:
303
- observation = o
304
302
 
305
303
  return cls(
306
304
  uri=uri,
@@ -308,7 +306,26 @@ class Analysis(ExplainEntity):
308
306
  action=action,
309
307
  arguments=arguments,
310
308
  thought=thought,
311
- observation=observation
309
+ )
310
+
311
+
312
+ @dataclass
313
+ class Observation(ExplainEntity):
314
+ """Observation entity - standalone tool result (Agent only)."""
315
+ document: str = ""
316
+
317
+ @classmethod
318
+ def from_triples(cls, uri: str, triples: List[Tuple[str, str, Any]]) -> "Observation":
319
+ document = ""
320
+
321
+ for s, p, o in triples:
322
+ if p == TG_DOCUMENT:
323
+ document = o
324
+
325
+ return cls(
326
+ uri=uri,
327
+ entity_type="observation",
328
+ document=document,
312
329
  )
313
330
 
314
331
 
@@ -757,9 +774,9 @@ class ExplainabilityClient:
757
774
  return trace
758
775
  trace["question"] = question
759
776
 
760
- # Find grounding: ?grounding prov:wasGeneratedBy question_uri
777
+ # Find grounding: ?grounding prov:wasDerivedFrom question_uri
761
778
  grounding_triples = self.flow.triples_query(
762
- p=PROV_WAS_GENERATED_BY,
779
+ p=PROV_WAS_DERIVED_FROM,
763
780
  o=question_uri,
764
781
  g=graph,
765
782
  user=user,
@@ -894,9 +911,9 @@ class ExplainabilityClient:
894
911
  return trace
895
912
  trace["question"] = question
896
913
 
897
- # Find grounding: ?grounding prov:wasGeneratedBy question_uri
914
+ # Find grounding: ?grounding prov:wasDerivedFrom question_uri
898
915
  grounding_triples = self.flow.triples_query(
899
- p=PROV_WAS_GENERATED_BY,
916
+ p=PROV_WAS_DERIVED_FROM,
900
917
  o=question_uri,
901
918
  g=graph,
902
919
  user=user,
@@ -1010,41 +1027,26 @@ class ExplainabilityClient:
1010
1027
  # Follow the provenance chain from the question
1011
1028
  self._follow_provenance_chain(
1012
1029
  session_uri, trace, graph, user, collection,
1013
- is_first=True, max_depth=50,
1030
+ max_depth=50,
1014
1031
  )
1015
1032
 
1016
1033
  return trace
1017
1034
 
1018
1035
  def _follow_provenance_chain(
1019
1036
  self, current_uri, trace, graph, user, collection,
1020
- is_first=False, max_depth=50,
1037
+ max_depth=50,
1021
1038
  ):
1022
1039
  """Recursively follow the provenance chain, handling branches."""
1023
1040
  if max_depth <= 0:
1024
1041
  return
1025
1042
 
1026
1043
  # Find entities derived from current_uri
1027
- if is_first:
1028
- derived_triples = self.flow.triples_query(
1029
- p=PROV_WAS_GENERATED_BY,
1030
- o=current_uri,
1031
- g=graph, user=user, collection=collection,
1032
- limit=20
1033
- )
1034
- if not derived_triples:
1035
- derived_triples = self.flow.triples_query(
1036
- p=PROV_WAS_DERIVED_FROM,
1037
- o=current_uri,
1038
- g=graph, user=user, collection=collection,
1039
- limit=20
1040
- )
1041
- else:
1042
- derived_triples = self.flow.triples_query(
1043
- p=PROV_WAS_DERIVED_FROM,
1044
- o=current_uri,
1045
- g=graph, user=user, collection=collection,
1046
- limit=20
1047
- )
1044
+ derived_triples = self.flow.triples_query(
1045
+ p=PROV_WAS_DERIVED_FROM,
1046
+ o=current_uri,
1047
+ g=graph, user=user, collection=collection,
1048
+ limit=20
1049
+ )
1048
1050
 
1049
1051
  if not derived_triples:
1050
1052
  return
@@ -1062,8 +1064,8 @@ class ExplainabilityClient:
1062
1064
  if entity is None:
1063
1065
  continue
1064
1066
 
1065
- if isinstance(entity, (Analysis, Decomposition, Finding,
1066
- Plan, StepResult)):
1067
+ if isinstance(entity, (Analysis, Observation, Decomposition,
1068
+ Finding, Plan, StepResult)):
1067
1069
  trace["steps"].append(entity)
1068
1070
 
1069
1071
  # Continue following from this entity
@@ -1072,6 +1074,27 @@ class ExplainabilityClient:
1072
1074
  max_depth=max_depth - 1,
1073
1075
  )
1074
1076
 
1077
+ elif isinstance(entity, Question):
1078
+ # Sub-trace: a RAG session linked to this agent step.
1079
+ # Fetch the full sub-trace and embed it.
1080
+ if entity.question_type == "graph-rag":
1081
+ sub_trace = self.fetch_graphrag_trace(
1082
+ derived_uri, graph, user, collection,
1083
+ )
1084
+ elif entity.question_type == "document-rag":
1085
+ sub_trace = self.fetch_docrag_trace(
1086
+ derived_uri, graph, user, collection,
1087
+ )
1088
+ else:
1089
+ sub_trace = None
1090
+
1091
+ if sub_trace:
1092
+ trace["steps"].append({
1093
+ "type": "sub-trace",
1094
+ "question": entity,
1095
+ "trace": sub_trace,
1096
+ })
1097
+
1075
1098
  elif isinstance(entity, (Conclusion, Synthesis)):
1076
1099
  trace["steps"].append(entity)
1077
1100
 
@@ -1114,10 +1137,25 @@ class ExplainabilityClient:
1114
1137
  if isinstance(entity, Question):
1115
1138
  questions.append(entity)
1116
1139
 
1140
+ # Filter out sub-traces: sessions that have a wasDerivedFrom link
1141
+ # (they are child sessions linked to a parent agent iteration)
1142
+ top_level = []
1143
+ for q in questions:
1144
+ parent_triples = self.flow.triples_query(
1145
+ s=q.uri,
1146
+ p=PROV_WAS_DERIVED_FROM,
1147
+ g=graph,
1148
+ user=user,
1149
+ collection=collection,
1150
+ limit=1
1151
+ )
1152
+ if not parent_triples:
1153
+ top_level.append(q)
1154
+
1117
1155
  # Sort by timestamp (newest first)
1118
- questions.sort(key=lambda q: q.timestamp or "", reverse=True)
1156
+ top_level.sort(key=lambda q: q.timestamp or "", reverse=True)
1119
1157
 
1120
- return questions
1158
+ return top_level
1121
1159
 
1122
1160
  def detect_session_type(
1123
1161
  self,
@@ -1159,18 +1197,9 @@ class ExplainabilityClient:
1159
1197
  limit=5
1160
1198
  )
1161
1199
 
1162
- generated_triples = self.flow.triples_query(
1163
- p=PROV_WAS_GENERATED_BY,
1164
- o=session_uri,
1165
- g=graph,
1166
- user=user,
1167
- collection=collection,
1168
- limit=5
1169
- )
1170
-
1171
1200
  all_child_uris = [
1172
1201
  extract_term_value(t.get("s", {}))
1173
- for t in (derived_triples + generated_triples)
1202
+ for t in derived_triples
1174
1203
  ]
1175
1204
 
1176
1205
  for child_uri in all_child_uris:
@@ -384,12 +384,14 @@ class SocketClient:
384
384
  if chunk_type == "thought":
385
385
  return AgentThought(
386
386
  content=resp.get("content", ""),
387
- end_of_message=resp.get("end_of_message", False)
387
+ end_of_message=resp.get("end_of_message", False),
388
+ message_id=resp.get("message_id", ""),
388
389
  )
389
390
  elif chunk_type == "observation":
390
391
  return AgentObservation(
391
392
  content=resp.get("content", ""),
392
- end_of_message=resp.get("end_of_message", False)
393
+ end_of_message=resp.get("end_of_message", False),
394
+ message_id=resp.get("message_id", ""),
393
395
  )
394
396
  elif chunk_type == "answer" or chunk_type == "final-answer":
395
397
  return AgentAnswer(
@@ -150,8 +150,10 @@ class AgentThought(StreamingChunk):
150
150
  content: Agent's thought text
151
151
  end_of_message: True if this completes the current thought
152
152
  chunk_type: Always "thought"
153
+ message_id: Provenance URI of the entity being built
153
154
  """
154
155
  chunk_type: str = "thought"
156
+ message_id: str = ""
155
157
 
156
158
  @dataclasses.dataclass
157
159
  class AgentObservation(StreamingChunk):
@@ -165,8 +167,10 @@ class AgentObservation(StreamingChunk):
165
167
  content: Observation text describing tool results
166
168
  end_of_message: True if this completes the current observation
167
169
  chunk_type: Always "observation"
170
+ message_id: Provenance URI of the entity being built
168
171
  """
169
172
  chunk_type: str = "observation"
173
+ message_id: str = ""
170
174
 
171
175
  @dataclasses.dataclass
172
176
  class AgentAnswer(StreamingChunk):
@@ -5,6 +5,7 @@ from .. schema import GraphRagQuery, GraphRagResponse
5
5
  class GraphRagClient(RequestResponse):
6
6
  async def rag(self, query, user="trustgraph", collection="default",
7
7
  chunk_callback=None, explain_callback=None,
8
+ parent_uri="",
8
9
  timeout=600):
9
10
  """
10
11
  Execute a graph RAG query with optional streaming callbacks.
@@ -50,6 +51,7 @@ class GraphRagClient(RequestResponse):
50
51
  query = query,
51
52
  user = user,
52
53
  collection = collection,
54
+ parent_uri = parent_uri,
53
55
  ),
54
56
  timeout=timeout,
55
57
  recipient=recipient,
@@ -0,0 +1 @@
1
+ __version__ = "2.2.13"
@@ -96,6 +96,7 @@ from . namespaces import (
96
96
  TG_ANALYSIS, TG_CONCLUSION,
97
97
  # Unifying types
98
98
  TG_ANSWER_TYPE, TG_REFLECTION_TYPE, TG_THOUGHT_TYPE, TG_OBSERVATION_TYPE,
99
+ TG_TOOL_USE,
99
100
  # Question subtypes (to distinguish retrieval mechanism)
100
101
  TG_GRAPH_RAG_QUESTION, TG_DOC_RAG_QUESTION, TG_AGENT_QUESTION,
101
102
  # Agent provenance predicates
@@ -132,6 +133,7 @@ from . triples import (
132
133
  from . agent import (
133
134
  agent_session_triples,
134
135
  agent_iteration_triples,
136
+ agent_observation_triples,
135
137
  agent_final_triples,
136
138
  # Orchestrator provenance triple builders
137
139
  agent_decomposition_triples,
@@ -210,6 +212,7 @@ __all__ = [
210
212
  "TG_ANALYSIS", "TG_CONCLUSION",
211
213
  # Unifying types
212
214
  "TG_ANSWER_TYPE", "TG_REFLECTION_TYPE", "TG_THOUGHT_TYPE", "TG_OBSERVATION_TYPE",
215
+ "TG_TOOL_USE",
213
216
  # Question subtypes
214
217
  "TG_GRAPH_RAG_QUESTION", "TG_DOC_RAG_QUESTION", "TG_AGENT_QUESTION",
215
218
  # Agent provenance predicates
@@ -238,6 +241,7 @@ __all__ = [
238
241
  # Agent provenance triple builders
239
242
  "agent_session_triples",
240
243
  "agent_iteration_triples",
244
+ "agent_observation_triples",
241
245
  "agent_final_triples",
242
246
  # Orchestrator provenance triple builders
243
247
  "agent_decomposition_triples",
@@ -20,11 +20,12 @@ from .. schema import Triple, Term, IRI, LITERAL
20
20
 
21
21
  from . namespaces import (
22
22
  RDF_TYPE, RDFS_LABEL,
23
- PROV_ACTIVITY, PROV_ENTITY, PROV_WAS_DERIVED_FROM,
24
- PROV_WAS_GENERATED_BY, PROV_STARTED_AT_TIME,
25
- TG_QUERY, TG_THOUGHT, TG_ACTION, TG_ARGUMENTS, TG_OBSERVATION,
23
+ PROV_ENTITY, PROV_WAS_DERIVED_FROM,
24
+ PROV_STARTED_AT_TIME,
25
+ TG_QUERY, TG_THOUGHT, TG_ACTION, TG_ARGUMENTS,
26
26
  TG_QUESTION, TG_ANALYSIS, TG_CONCLUSION, TG_DOCUMENT,
27
27
  TG_ANSWER_TYPE, TG_REFLECTION_TYPE, TG_THOUGHT_TYPE, TG_OBSERVATION_TYPE,
28
+ TG_TOOL_USE,
28
29
  TG_AGENT_QUESTION,
29
30
  TG_DECOMPOSITION, TG_FINDING, TG_PLAN_TYPE, TG_STEP_RESULT,
30
31
  TG_SYNTHESIS, TG_SUBAGENT_GOAL, TG_PLAN_STEP,
@@ -70,7 +71,7 @@ def agent_session_triples(
70
71
  timestamp = datetime.utcnow().isoformat() + "Z"
71
72
 
72
73
  return [
73
- _triple(session_uri, RDF_TYPE, _iri(PROV_ACTIVITY)),
74
+ _triple(session_uri, RDF_TYPE, _iri(PROV_ENTITY)),
74
75
  _triple(session_uri, RDF_TYPE, _iri(TG_QUESTION)),
75
76
  _triple(session_uri, RDF_TYPE, _iri(TG_AGENT_QUESTION)),
76
77
  _triple(session_uri, RDFS_LABEL, _literal("Agent Question")),
@@ -87,19 +88,15 @@ def agent_iteration_triples(
87
88
  arguments: Dict[str, Any] = None,
88
89
  thought_uri: Optional[str] = None,
89
90
  thought_document_id: Optional[str] = None,
90
- observation_uri: Optional[str] = None,
91
- observation_document_id: Optional[str] = None,
92
91
  ) -> List[Triple]:
93
92
  """
94
- Build triples for one agent iteration (Analysis - think/act/observe cycle).
93
+ Build triples for one agent iteration (Analysis+ToolUse).
95
94
 
96
95
  Creates:
97
- - Entity declaration with tg:Analysis type
98
- - wasGeneratedBy link to question (if first iteration)
99
- - wasDerivedFrom link to previous iteration (if not first)
96
+ - Entity declaration with tg:Analysis and tg:ToolUse types
97
+ - wasDerivedFrom link to question (if first iteration) or previous
100
98
  - Action and arguments metadata
101
99
  - Thought sub-entity (tg:Reflection, tg:Thought) with librarian document
102
- - Observation sub-entity (tg:Reflection, tg:Observation) with librarian document
103
100
 
104
101
  Args:
105
102
  iteration_uri: URI of this iteration (from agent_iteration_uri)
@@ -109,8 +106,6 @@ def agent_iteration_triples(
109
106
  arguments: Arguments passed to the tool (will be JSON-encoded)
110
107
  thought_uri: URI for the thought sub-entity
111
108
  thought_document_id: Document URI for thought in librarian
112
- observation_uri: URI for the observation sub-entity
113
- observation_document_id: Document URI for observation in librarian
114
109
 
115
110
  Returns:
116
111
  List of Triple objects
@@ -121,6 +116,7 @@ def agent_iteration_triples(
121
116
  triples = [
122
117
  _triple(iteration_uri, RDF_TYPE, _iri(PROV_ENTITY)),
123
118
  _triple(iteration_uri, RDF_TYPE, _iri(TG_ANALYSIS)),
119
+ _triple(iteration_uri, RDF_TYPE, _iri(TG_TOOL_USE)),
124
120
  _triple(iteration_uri, RDFS_LABEL, _literal(f"Analysis: {action}")),
125
121
  _triple(iteration_uri, TG_ACTION, _literal(action)),
126
122
  _triple(iteration_uri, TG_ARGUMENTS, _literal(json.dumps(arguments))),
@@ -128,7 +124,7 @@ def agent_iteration_triples(
128
124
 
129
125
  if question_uri:
130
126
  triples.append(
131
- _triple(iteration_uri, PROV_WAS_GENERATED_BY, _iri(question_uri))
127
+ _triple(iteration_uri, PROV_WAS_DERIVED_FROM, _iri(question_uri))
132
128
  )
133
129
  elif previous_uri:
134
130
  triples.append(
@@ -142,26 +138,48 @@ def agent_iteration_triples(
142
138
  _triple(thought_uri, RDF_TYPE, _iri(TG_REFLECTION_TYPE)),
143
139
  _triple(thought_uri, RDF_TYPE, _iri(TG_THOUGHT_TYPE)),
144
140
  _triple(thought_uri, RDFS_LABEL, _literal("Thought")),
145
- _triple(thought_uri, PROV_WAS_GENERATED_BY, _iri(iteration_uri)),
141
+ _triple(thought_uri, PROV_WAS_DERIVED_FROM, _iri(iteration_uri)),
146
142
  ])
147
143
  if thought_document_id:
148
144
  triples.append(
149
145
  _triple(thought_uri, TG_DOCUMENT, _iri(thought_document_id))
150
146
  )
151
147
 
152
- # Observation sub-entity
153
- if observation_uri:
154
- triples.extend([
155
- _triple(iteration_uri, TG_OBSERVATION, _iri(observation_uri)),
156
- _triple(observation_uri, RDF_TYPE, _iri(TG_REFLECTION_TYPE)),
157
- _triple(observation_uri, RDF_TYPE, _iri(TG_OBSERVATION_TYPE)),
158
- _triple(observation_uri, RDFS_LABEL, _literal("Observation")),
159
- _triple(observation_uri, PROV_WAS_GENERATED_BY, _iri(iteration_uri)),
160
- ])
161
- if observation_document_id:
162
- triples.append(
163
- _triple(observation_uri, TG_DOCUMENT, _iri(observation_document_id))
164
- )
148
+ return triples
149
+
150
+
151
+ def agent_observation_triples(
152
+ observation_uri: str,
153
+ iteration_uri: str,
154
+ document_id: Optional[str] = None,
155
+ ) -> List[Triple]:
156
+ """
157
+ Build triples for an agent observation (standalone entity).
158
+
159
+ Creates:
160
+ - Entity declaration with prov:Entity and tg:Observation types
161
+ - wasDerivedFrom link to the iteration (Analysis+ToolUse)
162
+ - Document reference to librarian (if provided)
163
+
164
+ Args:
165
+ observation_uri: URI of the observation entity
166
+ iteration_uri: URI of the iteration this observation derives from
167
+ document_id: Librarian document ID for the observation content
168
+
169
+ Returns:
170
+ List of Triple objects
171
+ """
172
+ triples = [
173
+ _triple(observation_uri, RDF_TYPE, _iri(PROV_ENTITY)),
174
+ _triple(observation_uri, RDF_TYPE, _iri(TG_OBSERVATION_TYPE)),
175
+ _triple(observation_uri, RDFS_LABEL, _literal("Observation")),
176
+ _triple(observation_uri, PROV_WAS_DERIVED_FROM, _iri(iteration_uri)),
177
+ ]
178
+
179
+ if document_id:
180
+ triples.append(
181
+ _triple(observation_uri, TG_DOCUMENT, _iri(document_id))
182
+ )
165
183
 
166
184
  return triples
167
185
 
@@ -199,7 +217,7 @@ def agent_final_triples(
199
217
 
200
218
  if question_uri:
201
219
  triples.append(
202
- _triple(final_uri, PROV_WAS_GENERATED_BY, _iri(question_uri))
220
+ _triple(final_uri, PROV_WAS_DERIVED_FROM, _iri(question_uri))
203
221
  )
204
222
  elif previous_uri:
205
223
  triples.append(
@@ -223,7 +241,7 @@ def agent_decomposition_triples(
223
241
  _triple(uri, RDF_TYPE, _iri(TG_DECOMPOSITION)),
224
242
  _triple(uri, RDFS_LABEL,
225
243
  _literal(f"Decomposed into {len(goals)} research threads")),
226
- _triple(uri, PROV_WAS_GENERATED_BY, _iri(session_uri)),
244
+ _triple(uri, PROV_WAS_DERIVED_FROM, _iri(session_uri)),
227
245
  ]
228
246
  for goal in goals:
229
247
  triples.append(_triple(uri, TG_SUBAGENT_GOAL, _literal(goal)))
@@ -261,7 +279,7 @@ def agent_plan_triples(
261
279
  _triple(uri, RDF_TYPE, _iri(TG_PLAN_TYPE)),
262
280
  _triple(uri, RDFS_LABEL,
263
281
  _literal(f"Plan with {len(steps)} steps")),
264
- _triple(uri, PROV_WAS_GENERATED_BY, _iri(session_uri)),
282
+ _triple(uri, PROV_WAS_DERIVED_FROM, _iri(session_uri)),
265
283
  ]
266
284
  for step in steps:
267
285
  triples.append(_triple(uri, TG_PLAN_STEP, _literal(step)))
@@ -105,6 +105,7 @@ TG_ANSWER_TYPE = TG + "Answer" # Final answer (Synthesis, Conclusion, F
105
105
  TG_REFLECTION_TYPE = TG + "Reflection" # Intermediate commentary (Thought, Observation)
106
106
  TG_THOUGHT_TYPE = TG + "Thought" # Agent reasoning
107
107
  TG_OBSERVATION_TYPE = TG + "Observation" # Agent tool result
108
+ TG_TOOL_USE = TG + "ToolUse" # Analysis+ToolUse mixin
108
109
 
109
110
  # Question subtypes (to distinguish retrieval mechanism)
110
111
  TG_GRAPH_RAG_QUESTION = TG + "GraphRagQuestion"
@@ -353,18 +353,21 @@ def question_triples(
353
353
  question_uri: str,
354
354
  query: str,
355
355
  timestamp: Optional[str] = None,
356
+ parent_uri: Optional[str] = None,
356
357
  ) -> List[Triple]:
357
358
  """
358
- Build triples for a question activity.
359
+ Build triples for a question entity.
359
360
 
360
361
  Creates:
361
- - Activity declaration for the question
362
+ - Entity declaration for the question
362
363
  - Query text and timestamp
364
+ - Optional wasDerivedFrom link to parent (for sub-traces)
363
365
 
364
366
  Args:
365
367
  question_uri: URI of the question (from question_uri)
366
368
  query: The user's query text
367
369
  timestamp: ISO timestamp (defaults to now)
370
+ parent_uri: Optional parent URI to link as wasDerivedFrom (for sub-traces)
368
371
 
369
372
  Returns:
370
373
  List of Triple objects
@@ -372,8 +375,8 @@ def question_triples(
372
375
  if timestamp is None:
373
376
  timestamp = datetime.utcnow().isoformat() + "Z"
374
377
 
375
- return [
376
- _triple(question_uri, RDF_TYPE, _iri(PROV_ACTIVITY)),
378
+ triples = [
379
+ _triple(question_uri, RDF_TYPE, _iri(PROV_ENTITY)),
377
380
  _triple(question_uri, RDF_TYPE, _iri(TG_QUESTION)),
378
381
  _triple(question_uri, RDF_TYPE, _iri(TG_GRAPH_RAG_QUESTION)),
379
382
  _triple(question_uri, RDFS_LABEL, _literal("GraphRAG Question")),
@@ -381,6 +384,13 @@ def question_triples(
381
384
  _triple(question_uri, TG_QUERY, _literal(query)),
382
385
  ]
383
386
 
387
+ if parent_uri:
388
+ triples.append(
389
+ _triple(question_uri, PROV_WAS_DERIVED_FROM, _iri(parent_uri))
390
+ )
391
+
392
+ return triples
393
+
384
394
 
385
395
  def grounding_triples(
386
396
  grounding_uri: str,
@@ -407,7 +417,7 @@ def grounding_triples(
407
417
  _triple(grounding_uri, RDF_TYPE, _iri(PROV_ENTITY)),
408
418
  _triple(grounding_uri, RDF_TYPE, _iri(TG_GROUNDING)),
409
419
  _triple(grounding_uri, RDFS_LABEL, _literal("Grounding")),
410
- _triple(grounding_uri, PROV_WAS_GENERATED_BY, _iri(question_uri)),
420
+ _triple(grounding_uri, PROV_WAS_DERIVED_FROM, _iri(question_uri)),
411
421
  ]
412
422
 
413
423
  for concept in concepts:
@@ -575,18 +585,21 @@ def docrag_question_triples(
575
585
  question_uri: str,
576
586
  query: str,
577
587
  timestamp: Optional[str] = None,
588
+ parent_uri: Optional[str] = None,
578
589
  ) -> List[Triple]:
579
590
  """
580
- Build triples for a document RAG question activity.
591
+ Build triples for a document RAG question entity.
581
592
 
582
593
  Creates:
583
- - Activity declaration with tg:Question type
594
+ - Entity declaration with tg:Question type
584
595
  - Query text and timestamp
596
+ - Optional wasDerivedFrom link to parent (for sub-traces)
585
597
 
586
598
  Args:
587
599
  question_uri: URI of the question (from docrag_question_uri)
588
600
  query: The user's query text
589
601
  timestamp: ISO timestamp (defaults to now)
602
+ parent_uri: Optional parent URI to link as wasDerivedFrom (for sub-traces)
590
603
 
591
604
  Returns:
592
605
  List of Triple objects
@@ -594,8 +607,8 @@ def docrag_question_triples(
594
607
  if timestamp is None:
595
608
  timestamp = datetime.utcnow().isoformat() + "Z"
596
609
 
597
- return [
598
- _triple(question_uri, RDF_TYPE, _iri(PROV_ACTIVITY)),
610
+ triples = [
611
+ _triple(question_uri, RDF_TYPE, _iri(PROV_ENTITY)),
599
612
  _triple(question_uri, RDF_TYPE, _iri(TG_QUESTION)),
600
613
  _triple(question_uri, RDF_TYPE, _iri(TG_DOC_RAG_QUESTION)),
601
614
  _triple(question_uri, RDFS_LABEL, _literal("DocumentRAG Question")),
@@ -603,6 +616,13 @@ def docrag_question_triples(
603
616
  _triple(question_uri, TG_QUERY, _literal(query)),
604
617
  ]
605
618
 
619
+ if parent_uri:
620
+ triples.append(
621
+ _triple(question_uri, PROV_WAS_DERIVED_FROM, _iri(parent_uri))
622
+ )
623
+
624
+ return triples
625
+
606
626
 
607
627
  def docrag_exploration_triples(
608
628
  exploration_uri: str,
@@ -18,6 +18,7 @@ class GraphRagQuery:
18
18
  edge_score_limit: int = 0
19
19
  edge_limit: int = 0
20
20
  streaming: bool = False
21
+ parent_uri: str = ""
21
22
 
22
23
  @dataclass
23
24
  class GraphRagResponse:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trustgraph-base
3
- Version: 2.2.12
3
+ Version: 2.2.13
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
@@ -1 +0,0 @@
1
- __version__ = "2.2.12"