trustgraph-base 1.7.1__tar.gz → 1.7.5__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.

Potentially problematic release.


This version of trustgraph-base might be problematic. Click here for more details.

Files changed (145) hide show
  1. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/PKG-INFO +1 -1
  2. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/__init__.py +36 -2
  3. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/async_socket_client.py +11 -3
  4. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/collection.py +2 -6
  5. trustgraph_base-1.7.5/trustgraph/api/exceptions.py +134 -0
  6. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/socket_client.py +18 -6
  7. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/types.py +1 -2
  8. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/__init__.py +1 -0
  9. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/async_processor.py +2 -2
  10. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/cassandra_config.py +50 -23
  11. trustgraph_base-1.7.5/trustgraph/base/collection_config_handler.py +127 -0
  12. trustgraph_base-1.7.5/trustgraph/base_version.py +1 -0
  13. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/collection.py +2 -12
  14. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/collection.py +0 -4
  15. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph_base.egg-info/PKG-INFO +1 -1
  16. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph_base.egg-info/SOURCES.txt +1 -0
  17. trustgraph_base-1.7.1/trustgraph/api/exceptions.py +0 -6
  18. trustgraph_base-1.7.1/trustgraph/base_version.py +0 -1
  19. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/README.md +0 -0
  20. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/pyproject.toml +0 -0
  21. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/setup.cfg +0 -0
  22. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/api.py +0 -0
  23. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/async_bulk_client.py +0 -0
  24. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/async_flow.py +0 -0
  25. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/async_metrics.py +0 -0
  26. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/bulk_client.py +0 -0
  27. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/config.py +0 -0
  28. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/flow.py +0 -0
  29. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/knowledge.py +0 -0
  30. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/library.py +0 -0
  31. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/api/metrics.py +0 -0
  32. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/agent_client.py +0 -0
  33. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/agent_service.py +0 -0
  34. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/chunking_service.py +0 -0
  35. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/consumer.py +0 -0
  36. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/consumer_spec.py +0 -0
  37. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/document_embeddings_client.py +0 -0
  38. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/document_embeddings_query_service.py +0 -0
  39. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/document_embeddings_store_service.py +0 -0
  40. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/embeddings_client.py +0 -0
  41. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/embeddings_service.py +0 -0
  42. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/flow.py +0 -0
  43. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/flow_processor.py +0 -0
  44. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/graph_embeddings_client.py +0 -0
  45. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/graph_embeddings_query_service.py +0 -0
  46. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/graph_embeddings_store_service.py +0 -0
  47. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/graph_rag_client.py +0 -0
  48. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/llm_service.py +0 -0
  49. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/metrics.py +0 -0
  50. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/parameter_spec.py +0 -0
  51. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/producer.py +0 -0
  52. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/producer_spec.py +0 -0
  53. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/prompt_client.py +0 -0
  54. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/publisher.py +0 -0
  55. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/pubsub.py +0 -0
  56. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/request_response_spec.py +0 -0
  57. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/spec.py +0 -0
  58. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/structured_query_client.py +0 -0
  59. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/subscriber.py +0 -0
  60. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/subscriber_spec.py +0 -0
  61. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/text_completion_client.py +0 -0
  62. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/tool_client.py +0 -0
  63. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/tool_service.py +0 -0
  64. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/triples_client.py +0 -0
  65. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/triples_query_service.py +0 -0
  66. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/base/triples_store_service.py +0 -0
  67. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/__init__.py +0 -0
  68. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/agent_client.py +0 -0
  69. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/base.py +0 -0
  70. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/config_client.py +0 -0
  71. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/document_embeddings_client.py +0 -0
  72. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/document_rag_client.py +0 -0
  73. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/embeddings_client.py +0 -0
  74. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/graph_embeddings_client.py +0 -0
  75. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/graph_rag_client.py +0 -0
  76. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/llm_client.py +0 -0
  77. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/prompt_client.py +0 -0
  78. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/clients/triples_query_client.py +0 -0
  79. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/exceptions.py +0 -0
  80. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/knowledge/__init__.py +0 -0
  81. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/knowledge/defs.py +0 -0
  82. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/knowledge/document.py +0 -0
  83. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/knowledge/identifier.py +0 -0
  84. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/knowledge/organization.py +0 -0
  85. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/knowledge/publication.py +0 -0
  86. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/log_level.py +0 -0
  87. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/__init__.py +0 -0
  88. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/registry.py +0 -0
  89. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/__init__.py +0 -0
  90. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/agent.py +0 -0
  91. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/base.py +0 -0
  92. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/config.py +0 -0
  93. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/diagnosis.py +0 -0
  94. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/document_loading.py +0 -0
  95. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/embeddings.py +0 -0
  96. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/embeddings_query.py +0 -0
  97. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/flow.py +0 -0
  98. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/knowledge.py +0 -0
  99. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/library.py +0 -0
  100. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/metadata.py +0 -0
  101. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/nlp_query.py +0 -0
  102. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/objects_query.py +0 -0
  103. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/primitives.py +0 -0
  104. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/prompt.py +0 -0
  105. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/retrieval.py +0 -0
  106. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/structured_query.py +0 -0
  107. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/text_completion.py +0 -0
  108. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/tool.py +0 -0
  109. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/messaging/translators/triples.py +0 -0
  110. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/objects/__init__.py +0 -0
  111. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/objects/field.py +0 -0
  112. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/objects/object.py +0 -0
  113. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/rdf.py +0 -0
  114. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/__init__.py +0 -0
  115. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/core/__init__.py +0 -0
  116. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/core/metadata.py +0 -0
  117. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/core/primitives.py +0 -0
  118. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/core/topic.py +0 -0
  119. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/__init__.py +0 -0
  120. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/document.py +0 -0
  121. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/embeddings.py +0 -0
  122. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/graph.py +0 -0
  123. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/knowledge.py +0 -0
  124. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/nlp.py +0 -0
  125. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/object.py +0 -0
  126. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/rows.py +0 -0
  127. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/knowledge/structured.py +0 -0
  128. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/__init__.py +0 -0
  129. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/agent.py +0 -0
  130. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/config.py +0 -0
  131. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/diagnosis.py +0 -0
  132. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/flow.py +0 -0
  133. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/library.py +0 -0
  134. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/llm.py +0 -0
  135. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/lookup.py +0 -0
  136. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/nlp_query.py +0 -0
  137. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/objects_query.py +0 -0
  138. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/prompt.py +0 -0
  139. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/query.py +0 -0
  140. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/retrieval.py +0 -0
  141. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/storage.py +0 -0
  142. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph/schema/services/structured_query.py +0 -0
  143. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph_base.egg-info/dependency_links.txt +0 -0
  144. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/trustgraph_base.egg-info/requires.txt +0 -0
  145. {trustgraph_base-1.7.1 → trustgraph_base-1.7.5}/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: 1.7.1
3
+ Version: 1.7.5
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
@@ -34,7 +34,26 @@ from .types import (
34
34
  )
35
35
 
36
36
  # Exceptions
37
- from .exceptions import ProtocolException, ApplicationException
37
+ from .exceptions import (
38
+ ProtocolException,
39
+ TrustGraphException,
40
+ AgentError,
41
+ ConfigError,
42
+ DocumentRagError,
43
+ FlowError,
44
+ GatewayError,
45
+ GraphRagError,
46
+ LLMError,
47
+ LoadError,
48
+ LookupError,
49
+ NLPQueryError,
50
+ ObjectsQueryError,
51
+ RequestError,
52
+ StructuredQueryError,
53
+ UnexpectedError,
54
+ # Legacy alias
55
+ ApplicationException,
56
+ )
38
57
 
39
58
  __all__ = [
40
59
  # Core API
@@ -75,6 +94,21 @@ __all__ = [
75
94
 
76
95
  # Exceptions
77
96
  "ProtocolException",
78
- "ApplicationException",
97
+ "TrustGraphException",
98
+ "AgentError",
99
+ "ConfigError",
100
+ "DocumentRagError",
101
+ "FlowError",
102
+ "GatewayError",
103
+ "GraphRagError",
104
+ "LLMError",
105
+ "LoadError",
106
+ "LookupError",
107
+ "NLPQueryError",
108
+ "ObjectsQueryError",
109
+ "RequestError",
110
+ "StructuredQueryError",
111
+ "UnexpectedError",
112
+ "ApplicationException", # Legacy alias
79
113
  ]
80
114
 
@@ -130,18 +130,26 @@ class AsyncSocketClient:
130
130
  content=resp.get("content", ""),
131
131
  end_of_message=resp.get("end_of_message", False)
132
132
  )
133
- elif chunk_type == "final-answer":
133
+ elif chunk_type == "answer" or chunk_type == "final-answer":
134
134
  return AgentAnswer(
135
135
  content=resp.get("content", ""),
136
136
  end_of_message=resp.get("end_of_message", False),
137
137
  end_of_dialog=resp.get("end_of_dialog", False)
138
138
  )
139
+ elif chunk_type == "action":
140
+ # Agent action chunks - treat as thoughts for display purposes
141
+ return AgentThought(
142
+ content=resp.get("content", ""),
143
+ end_of_message=resp.get("end_of_message", False)
144
+ )
139
145
  else:
140
146
  # RAG-style chunk (or generic chunk)
147
+ # Text-completion uses "response" field, RAG uses "chunk" field, Prompt uses "text" field
148
+ content = resp.get("response", resp.get("chunk", resp.get("text", "")))
141
149
  return RAGChunk(
142
- content=resp.get("chunk", ""),
150
+ content=content,
143
151
  end_of_stream=resp.get("end_of_stream", False),
144
- error=resp.get("error")
152
+ error=None # Errors are always thrown, never stored
145
153
  )
146
154
 
147
155
  async def aclose(self):
@@ -41,9 +41,7 @@ class Collection:
41
41
  collection = v["collection"],
42
42
  name = v["name"],
43
43
  description = v["description"],
44
- tags = v["tags"],
45
- created_at = v["created_at"],
46
- updated_at = v["updated_at"]
44
+ tags = v["tags"]
47
45
  )
48
46
  for v in collections
49
47
  ]
@@ -76,9 +74,7 @@ class Collection:
76
74
  collection = v["collection"],
77
75
  name = v["name"],
78
76
  description = v["description"],
79
- tags = v["tags"],
80
- created_at = v["created_at"],
81
- updated_at = v["updated_at"]
77
+ tags = v["tags"]
82
78
  )
83
79
  return None
84
80
  except Exception as e:
@@ -0,0 +1,134 @@
1
+ """
2
+ TrustGraph API Exceptions
3
+
4
+ Exception hierarchy for errors returned by TrustGraph services.
5
+ Each service error type maps to a specific exception class.
6
+ """
7
+
8
+ # Protocol-level exceptions (communication errors)
9
+ class ProtocolException(Exception):
10
+ """Raised when WebSocket protocol errors occur"""
11
+ pass
12
+
13
+
14
+ # Base class for all TrustGraph application errors
15
+ class TrustGraphException(Exception):
16
+ """Base class for all TrustGraph service errors"""
17
+ def __init__(self, message: str, error_type: str = None):
18
+ super().__init__(message)
19
+ self.message = message
20
+ self.error_type = error_type
21
+
22
+
23
+ # Service-specific exceptions
24
+ class AgentError(TrustGraphException):
25
+ """Agent service error"""
26
+ pass
27
+
28
+
29
+ class ConfigError(TrustGraphException):
30
+ """Configuration service error"""
31
+ pass
32
+
33
+
34
+ class DocumentRagError(TrustGraphException):
35
+ """Document RAG retrieval error"""
36
+ pass
37
+
38
+
39
+ class FlowError(TrustGraphException):
40
+ """Flow management error"""
41
+ pass
42
+
43
+
44
+ class GatewayError(TrustGraphException):
45
+ """API Gateway error"""
46
+ pass
47
+
48
+
49
+ class GraphRagError(TrustGraphException):
50
+ """Graph RAG retrieval error"""
51
+ pass
52
+
53
+
54
+ class LLMError(TrustGraphException):
55
+ """LLM service error"""
56
+ pass
57
+
58
+
59
+ class LoadError(TrustGraphException):
60
+ """Data loading error"""
61
+ pass
62
+
63
+
64
+ class LookupError(TrustGraphException):
65
+ """Lookup/search error"""
66
+ pass
67
+
68
+
69
+ class NLPQueryError(TrustGraphException):
70
+ """NLP query service error"""
71
+ pass
72
+
73
+
74
+ class ObjectsQueryError(TrustGraphException):
75
+ """Objects query service error"""
76
+ pass
77
+
78
+
79
+ class RequestError(TrustGraphException):
80
+ """Request processing error"""
81
+ pass
82
+
83
+
84
+ class StructuredQueryError(TrustGraphException):
85
+ """Structured query service error"""
86
+ pass
87
+
88
+
89
+ class UnexpectedError(TrustGraphException):
90
+ """Unexpected/unknown error"""
91
+ pass
92
+
93
+
94
+ # Mapping from error type string to exception class
95
+ ERROR_TYPE_MAPPING = {
96
+ "agent-error": AgentError,
97
+ "config-error": ConfigError,
98
+ "document-rag-error": DocumentRagError,
99
+ "flow-error": FlowError,
100
+ "gateway-error": GatewayError,
101
+ "graph-rag-error": GraphRagError,
102
+ "llm-error": LLMError,
103
+ "load-error": LoadError,
104
+ "lookup-error": LookupError,
105
+ "nlp-query-error": NLPQueryError,
106
+ "objects-query-error": ObjectsQueryError,
107
+ "request-error": RequestError,
108
+ "structured-query-error": StructuredQueryError,
109
+ "unexpected-error": UnexpectedError,
110
+ }
111
+
112
+
113
+ def raise_from_error_dict(error_dict: dict) -> None:
114
+ """
115
+ Raise appropriate exception from TrustGraph error dictionary.
116
+
117
+ Args:
118
+ error_dict: Dictionary with 'type' and 'message' keys
119
+
120
+ Raises:
121
+ Appropriate TrustGraphException subclass based on error type
122
+ """
123
+ error_type = error_dict.get("type", "unexpected-error")
124
+ message = error_dict.get("message", "Unknown error")
125
+
126
+ # Look up exception class, default to UnexpectedError
127
+ exception_class = ERROR_TYPE_MAPPING.get(error_type, UnexpectedError)
128
+
129
+ # Raise the appropriate exception
130
+ raise exception_class(message, error_type)
131
+
132
+
133
+ # Legacy exception for backwards compatibility
134
+ ApplicationException = TrustGraphException
@@ -6,7 +6,7 @@ from typing import Optional, Dict, Any, Iterator, Union, List
6
6
  from threading import Lock
7
7
 
8
8
  from . types import AgentThought, AgentObservation, AgentAnswer, RAGChunk, StreamingChunk
9
- from . exceptions import ProtocolException, ApplicationException
9
+ from . exceptions import ProtocolException, raise_from_error_dict
10
10
 
11
11
 
12
12
  class SocketClient:
@@ -126,7 +126,7 @@ class SocketClient:
126
126
  raise ProtocolException(f"Response ID mismatch")
127
127
 
128
128
  if "error" in response:
129
- raise ApplicationException(response["error"])
129
+ raise_from_error_dict(response["error"])
130
130
 
131
131
  if "response" not in response:
132
132
  raise ProtocolException(f"Missing response in message")
@@ -171,11 +171,15 @@ class SocketClient:
171
171
  continue # Ignore messages for other requests
172
172
 
173
173
  if "error" in response:
174
- raise ApplicationException(response["error"])
174
+ raise_from_error_dict(response["error"])
175
175
 
176
176
  if "response" in response:
177
177
  resp = response["response"]
178
178
 
179
+ # Check for errors in response chunks
180
+ if "error" in resp:
181
+ raise_from_error_dict(resp["error"])
182
+
179
183
  # Parse different chunk types
180
184
  chunk = self._parse_chunk(resp)
181
185
  yield chunk
@@ -198,18 +202,26 @@ class SocketClient:
198
202
  content=resp.get("content", ""),
199
203
  end_of_message=resp.get("end_of_message", False)
200
204
  )
201
- elif chunk_type == "final-answer":
205
+ elif chunk_type == "answer" or chunk_type == "final-answer":
202
206
  return AgentAnswer(
203
207
  content=resp.get("content", ""),
204
208
  end_of_message=resp.get("end_of_message", False),
205
209
  end_of_dialog=resp.get("end_of_dialog", False)
206
210
  )
211
+ elif chunk_type == "action":
212
+ # Agent action chunks - treat as thoughts for display purposes
213
+ return AgentThought(
214
+ content=resp.get("content", ""),
215
+ end_of_message=resp.get("end_of_message", False)
216
+ )
207
217
  else:
208
218
  # RAG-style chunk (or generic chunk)
219
+ # Text-completion uses "response" field, RAG uses "chunk" field, Prompt uses "text" field
220
+ content = resp.get("response", resp.get("chunk", resp.get("text", "")))
209
221
  return RAGChunk(
210
- content=resp.get("chunk", ""),
222
+ content=content,
211
223
  end_of_stream=resp.get("end_of_stream", False),
212
- error=resp.get("error")
224
+ error=None # Errors are always thrown, never stored
213
225
  )
214
226
 
215
227
  def close(self) -> None:
@@ -49,8 +49,6 @@ class CollectionMetadata:
49
49
  name : str
50
50
  description : str
51
51
  tags : List[str]
52
- created_at : str
53
- updated_at : str
54
52
 
55
53
  # Streaming chunk types
56
54
 
@@ -79,5 +77,6 @@ class AgentAnswer(StreamingChunk):
79
77
  @dataclasses.dataclass
80
78
  class RAGChunk(StreamingChunk):
81
79
  """RAG streaming chunk"""
80
+ chunk_type: str = "rag"
82
81
  end_of_stream: bool = False
83
82
  error: Optional[Dict[str, str]] = None
@@ -33,4 +33,5 @@ from . tool_service import ToolService
33
33
  from . tool_client import ToolClientSpec
34
34
  from . agent_client import AgentClientSpec
35
35
  from . structured_query_client import StructuredQueryClientSpec
36
+ from . collection_config_handler import CollectionConfigHandler
36
37
 
@@ -258,9 +258,9 @@ class AsyncProcessor:
258
258
  PulsarClient.add_args(parser)
259
259
 
260
260
  parser.add_argument(
261
- '--config-queue',
261
+ '--config-push-queue',
262
262
  default=default_config_queue,
263
- help=f'Config push queue {default_config_queue}',
263
+ help=f'Config push queue (default: {default_config_queue})',
264
264
  )
265
265
 
266
266
  parser.add_argument(
@@ -13,14 +13,15 @@ from typing import Optional, Tuple, List, Any
13
13
  def get_cassandra_defaults() -> dict:
14
14
  """
15
15
  Get default Cassandra configuration values from environment variables or fallback defaults.
16
-
16
+
17
17
  Returns:
18
- dict: Dictionary with 'host', 'username', and 'password' keys
18
+ dict: Dictionary with 'host', 'username', 'password', and 'keyspace' keys
19
19
  """
20
20
  return {
21
21
  'host': os.getenv('CASSANDRA_HOST', 'cassandra'),
22
22
  'username': os.getenv('CASSANDRA_USERNAME'),
23
- 'password': os.getenv('CASSANDRA_PASSWORD')
23
+ 'password': os.getenv('CASSANDRA_PASSWORD'),
24
+ 'keyspace': os.getenv('CASSANDRA_KEYSPACE')
24
25
  }
25
26
 
26
27
 
@@ -53,82 +54,108 @@ def add_cassandra_args(parser: argparse.ArgumentParser) -> None:
53
54
  password_help += " (default: <set>)"
54
55
  if 'CASSANDRA_PASSWORD' in os.environ:
55
56
  password_help += " [from CASSANDRA_PASSWORD]"
56
-
57
+
58
+ keyspace_help = "Cassandra keyspace (default: service-specific)"
59
+ if defaults['keyspace']:
60
+ keyspace_help = f"Cassandra keyspace (default: {defaults['keyspace']})"
61
+ if 'CASSANDRA_KEYSPACE' in os.environ:
62
+ keyspace_help += " [from CASSANDRA_KEYSPACE]"
63
+
57
64
  parser.add_argument(
58
65
  '--cassandra-host',
59
66
  default=defaults['host'],
60
67
  help=host_help
61
68
  )
62
-
69
+
63
70
  parser.add_argument(
64
71
  '--cassandra-username',
65
72
  default=defaults['username'],
66
73
  help=username_help
67
74
  )
68
-
75
+
69
76
  parser.add_argument(
70
77
  '--cassandra-password',
71
78
  default=defaults['password'],
72
79
  help=password_help
73
80
  )
74
81
 
82
+ parser.add_argument(
83
+ '--cassandra-keyspace',
84
+ default=defaults['keyspace'],
85
+ help=keyspace_help
86
+ )
87
+
75
88
 
76
89
  def resolve_cassandra_config(
77
90
  args: Optional[Any] = None,
78
91
  host: Optional[str] = None,
79
92
  username: Optional[str] = None,
80
- password: Optional[str] = None
81
- ) -> Tuple[List[str], Optional[str], Optional[str]]:
93
+ password: Optional[str] = None,
94
+ default_keyspace: Optional[str] = None
95
+ ) -> Tuple[List[str], Optional[str], Optional[str], Optional[str]]:
82
96
  """
83
97
  Resolve Cassandra configuration from various sources.
84
-
98
+
85
99
  Can accept either argparse args object or explicit parameters.
86
100
  Converts host string to list format for Cassandra driver.
87
-
101
+
88
102
  Args:
89
- args: Optional argparse namespace with cassandra_host, cassandra_username, cassandra_password
103
+ args: Optional argparse namespace with cassandra_host, cassandra_username, cassandra_password, cassandra_keyspace
90
104
  host: Optional explicit host parameter (overrides args)
91
105
  username: Optional explicit username parameter (overrides args)
92
106
  password: Optional explicit password parameter (overrides args)
93
-
107
+ default_keyspace: Optional default keyspace if not specified elsewhere
108
+
94
109
  Returns:
95
- tuple: (hosts_list, username, password)
110
+ tuple: (hosts_list, username, password, keyspace)
96
111
  """
97
112
  # If args provided, extract values
113
+ keyspace = None
98
114
  if args is not None:
99
115
  host = host or getattr(args, 'cassandra_host', None)
100
116
  username = username or getattr(args, 'cassandra_username', None)
101
117
  password = password or getattr(args, 'cassandra_password', None)
102
-
118
+ keyspace = getattr(args, 'cassandra_keyspace', None)
119
+
103
120
  # Apply defaults if still None
104
121
  defaults = get_cassandra_defaults()
105
122
  host = host or defaults['host']
106
123
  username = username or defaults['username']
107
124
  password = password or defaults['password']
108
-
125
+ keyspace = keyspace or defaults['keyspace'] or default_keyspace
126
+
109
127
  # Convert host string to list
110
128
  if isinstance(host, str):
111
129
  hosts = [h.strip() for h in host.split(',') if h.strip()]
112
130
  else:
113
131
  hosts = host
114
-
115
- return hosts, username, password
116
132
 
133
+ return hosts, username, password, keyspace
117
134
 
118
- def get_cassandra_config_from_params(params: dict) -> Tuple[List[str], Optional[str], Optional[str]]:
135
+
136
+ def get_cassandra_config_from_params(
137
+ params: dict,
138
+ default_keyspace: Optional[str] = None
139
+ ) -> Tuple[List[str], Optional[str], Optional[str], Optional[str]]:
119
140
  """
120
141
  Extract and resolve Cassandra configuration from a parameters dictionary.
121
-
142
+
122
143
  Args:
123
144
  params: Dictionary of parameters that may contain Cassandra configuration
124
-
145
+ default_keyspace: Optional default keyspace if not specified in params
146
+
125
147
  Returns:
126
- tuple: (hosts_list, username, password)
148
+ tuple: (hosts_list, username, password, keyspace)
127
149
  """
128
150
  # Get Cassandra parameters
129
151
  host = params.get('cassandra_host')
130
152
  username = params.get('cassandra_username')
131
153
  password = params.get('cassandra_password')
132
-
154
+
133
155
  # Use resolve function to handle defaults and list conversion
134
- return resolve_cassandra_config(host=host, username=username, password=password)
156
+ return resolve_cassandra_config(
157
+ host=host,
158
+ username=username,
159
+ password=password,
160
+ default_keyspace=default_keyspace
161
+ )
@@ -0,0 +1,127 @@
1
+ """
2
+ Handler for storage services to process collection configuration from config push
3
+ """
4
+
5
+ import json
6
+ import logging
7
+ from typing import Dict, Set
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ class CollectionConfigHandler:
12
+ """
13
+ Handles collection configuration from config push messages for storage services.
14
+
15
+ Storage services should:
16
+ 1. Inherit from this class along with their service base class
17
+ 2. Call register_config_handler(self.on_collection_config) in __init__
18
+ 3. Implement create_collection(user, collection, metadata) method
19
+ 4. Implement delete_collection(user, collection) method
20
+ """
21
+
22
+ def __init__(self, **kwargs):
23
+ # Track known collections: {(user, collection): metadata_dict}
24
+ self.known_collections: Dict[tuple, dict] = {}
25
+ # Pass remaining kwargs up the inheritance chain
26
+ super().__init__(**kwargs)
27
+
28
+ async def on_collection_config(self, config: dict, version: int):
29
+ """
30
+ Handle config push messages and extract collection information
31
+
32
+ Args:
33
+ config: Configuration dictionary from ConfigPush message
34
+ version: Configuration version number
35
+ """
36
+ logger.info(f"Processing collection configuration (version {version})")
37
+
38
+ # Extract collections from config
39
+ if "collection" not in config:
40
+ logger.debug("No collection configuration in config push")
41
+ return
42
+
43
+ collection_config = config["collection"]
44
+
45
+ # Track which collections we've seen in this config
46
+ current_collections: Set[tuple] = set()
47
+
48
+ # Process each collection in the config
49
+ for key, value_json in collection_config.items():
50
+ try:
51
+ # Parse user:collection key
52
+ if ":" not in key:
53
+ logger.warning(f"Invalid collection key format (expected user:collection): {key}")
54
+ continue
55
+
56
+ user, collection = key.split(":", 1)
57
+ current_collections.add((user, collection))
58
+
59
+ # Parse metadata
60
+ metadata = json.loads(value_json)
61
+
62
+ # Check if this is a new collection or updated
63
+ collection_key = (user, collection)
64
+ if collection_key not in self.known_collections:
65
+ logger.info(f"New collection detected: {user}/{collection}")
66
+ await self.create_collection(user, collection, metadata)
67
+ self.known_collections[collection_key] = metadata
68
+ else:
69
+ # Collection already exists, update metadata if changed
70
+ if self.known_collections[collection_key] != metadata:
71
+ logger.info(f"Collection metadata updated: {user}/{collection}")
72
+ # Most storage services don't need to do anything for metadata updates
73
+ # They just need to know the collection exists
74
+ self.known_collections[collection_key] = metadata
75
+
76
+ except Exception as e:
77
+ logger.error(f"Error processing collection config for key {key}: {e}", exc_info=True)
78
+
79
+ # Find collections that were deleted (in known but not in current)
80
+ deleted_collections = set(self.known_collections.keys()) - current_collections
81
+ for user, collection in deleted_collections:
82
+ logger.info(f"Collection deleted: {user}/{collection}")
83
+ try:
84
+ await self.delete_collection(user, collection)
85
+ del self.known_collections[(user, collection)]
86
+ except Exception as e:
87
+ logger.error(f"Error deleting collection {user}/{collection}: {e}", exc_info=True)
88
+
89
+ logger.debug(f"Collection config processing complete. Known collections: {len(self.known_collections)}")
90
+
91
+ async def create_collection(self, user: str, collection: str, metadata: dict):
92
+ """
93
+ Create a collection in the storage backend.
94
+
95
+ Subclasses must implement this method.
96
+
97
+ Args:
98
+ user: User ID
99
+ collection: Collection ID
100
+ metadata: Collection metadata dictionary
101
+ """
102
+ raise NotImplementedError("Storage service must implement create_collection method")
103
+
104
+ async def delete_collection(self, user: str, collection: str):
105
+ """
106
+ Delete a collection from the storage backend.
107
+
108
+ Subclasses must implement this method.
109
+
110
+ Args:
111
+ user: User ID
112
+ collection: Collection ID
113
+ """
114
+ raise NotImplementedError("Storage service must implement delete_collection method")
115
+
116
+ def collection_exists(self, user: str, collection: str) -> bool:
117
+ """
118
+ Check if a collection is known to exist
119
+
120
+ Args:
121
+ user: User ID
122
+ collection: Collection ID
123
+
124
+ Returns:
125
+ True if collection exists, False otherwise
126
+ """
127
+ return (user, collection) in self.known_collections
@@ -0,0 +1 @@
1
+ __version__ = "1.7.5"
@@ -15,8 +15,6 @@ class CollectionManagementRequestTranslator(MessageTranslator):
15
15
  name=data.get("name"),
16
16
  description=data.get("description"),
17
17
  tags=data.get("tags"),
18
- created_at=data.get("created_at"),
19
- updated_at=data.get("updated_at"),
20
18
  tag_filter=data.get("tag_filter"),
21
19
  limit=data.get("limit")
22
20
  )
@@ -38,10 +36,6 @@ class CollectionManagementRequestTranslator(MessageTranslator):
38
36
  result["description"] = obj.description
39
37
  if obj.tags is not None:
40
38
  result["tags"] = list(obj.tags)
41
- if obj.created_at is not None:
42
- result["created_at"] = obj.created_at
43
- if obj.updated_at is not None:
44
- result["updated_at"] = obj.updated_at
45
39
  if obj.tag_filter is not None:
46
40
  result["tag_filter"] = list(obj.tag_filter)
47
41
  if obj.limit is not None:
@@ -73,9 +67,7 @@ class CollectionManagementResponseTranslator(MessageTranslator):
73
67
  collection=coll_data.get("collection"),
74
68
  name=coll_data.get("name"),
75
69
  description=coll_data.get("description"),
76
- tags=coll_data.get("tags"),
77
- created_at=coll_data.get("created_at"),
78
- updated_at=coll_data.get("updated_at")
70
+ tags=coll_data.get("tags", [])
79
71
  ))
80
72
 
81
73
  return CollectionManagementResponse(
@@ -104,9 +96,7 @@ class CollectionManagementResponseTranslator(MessageTranslator):
104
96
  "collection": coll.collection,
105
97
  "name": coll.name,
106
98
  "description": coll.description,
107
- "tags": list(coll.tags) if coll.tags else [],
108
- "created_at": coll.created_at,
109
- "updated_at": coll.updated_at
99
+ "tags": list(coll.tags) if coll.tags else []
110
100
  })
111
101
 
112
102
  print("RESULT IS", result, flush=True)