trustgraph-base 1.3.15__tar.gz → 1.5.1__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 (136) hide show
  1. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/PKG-INFO +2 -1
  2. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/pyproject.toml +1 -0
  3. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/api.py +4 -0
  4. trustgraph_base-1.5.1/trustgraph/api/collection.py +98 -0
  5. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/flow.py +163 -8
  6. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/types.py +10 -0
  7. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/__init__.py +2 -1
  8. trustgraph_base-1.5.1/trustgraph/base/chunking_service.py +62 -0
  9. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/flow.py +2 -2
  10. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/flow_processor.py +1 -1
  11. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/llm_service.py +34 -4
  12. trustgraph_base-1.3.15/trustgraph/base/setting_spec.py → trustgraph_base-1.5.1/trustgraph/base/parameter_spec.py +5 -3
  13. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/request_response_spec.py +0 -4
  14. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/structured_query_client.py +4 -2
  15. trustgraph_base-1.5.1/trustgraph/base_version.py +1 -0
  16. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/__init__.py +16 -2
  17. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/__init__.py +1 -0
  18. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/agent.py +7 -5
  19. trustgraph_base-1.5.1/trustgraph/messaging/translators/collection.py +114 -0
  20. trustgraph_base-1.5.1/trustgraph/messaging/translators/diagnosis.py +67 -0
  21. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/embeddings_query.py +2 -2
  22. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/flow.py +10 -5
  23. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/structured_query.py +6 -2
  24. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/__init__.py +4 -1
  25. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/agent.py +2 -0
  26. trustgraph_base-1.5.1/trustgraph/schema/services/collection.py +59 -0
  27. trustgraph_base-1.5.1/trustgraph/schema/services/diagnosis.py +33 -0
  28. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/flow.py +6 -0
  29. trustgraph_base-1.5.1/trustgraph/schema/services/storage.py +42 -0
  30. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/structured_query.py +2 -0
  31. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph_base.egg-info/PKG-INFO +2 -1
  32. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph_base.egg-info/SOURCES.txt +8 -1
  33. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph_base.egg-info/requires.txt +1 -0
  34. trustgraph_base-1.3.15/trustgraph/base_version.py +0 -1
  35. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/README.md +0 -0
  36. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/setup.cfg +0 -0
  37. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/__init__.py +0 -0
  38. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/config.py +0 -0
  39. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/exceptions.py +0 -0
  40. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/knowledge.py +0 -0
  41. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/api/library.py +0 -0
  42. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/agent_client.py +0 -0
  43. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/agent_service.py +0 -0
  44. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/async_processor.py +0 -0
  45. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/cassandra_config.py +0 -0
  46. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/consumer.py +0 -0
  47. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/consumer_spec.py +0 -0
  48. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/document_embeddings_client.py +0 -0
  49. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/document_embeddings_query_service.py +0 -0
  50. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/document_embeddings_store_service.py +0 -0
  51. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/embeddings_client.py +0 -0
  52. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/embeddings_service.py +0 -0
  53. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/graph_embeddings_client.py +0 -0
  54. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/graph_embeddings_query_service.py +0 -0
  55. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/graph_embeddings_store_service.py +0 -0
  56. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/graph_rag_client.py +0 -0
  57. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/metrics.py +0 -0
  58. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/producer.py +0 -0
  59. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/producer_spec.py +0 -0
  60. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/prompt_client.py +0 -0
  61. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/publisher.py +0 -0
  62. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/pubsub.py +0 -0
  63. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/spec.py +0 -0
  64. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/subscriber.py +0 -0
  65. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/subscriber_spec.py +0 -0
  66. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/text_completion_client.py +0 -0
  67. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/tool_client.py +0 -0
  68. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/tool_service.py +0 -0
  69. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/triples_client.py +0 -0
  70. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/triples_query_service.py +0 -0
  71. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/base/triples_store_service.py +0 -0
  72. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/__init__.py +0 -0
  73. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/agent_client.py +0 -0
  74. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/base.py +0 -0
  75. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/config_client.py +0 -0
  76. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/document_embeddings_client.py +0 -0
  77. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/document_rag_client.py +0 -0
  78. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/embeddings_client.py +0 -0
  79. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/graph_embeddings_client.py +0 -0
  80. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/graph_rag_client.py +0 -0
  81. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/llm_client.py +0 -0
  82. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/prompt_client.py +0 -0
  83. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/clients/triples_query_client.py +0 -0
  84. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/exceptions.py +0 -0
  85. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/knowledge/__init__.py +0 -0
  86. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/knowledge/defs.py +0 -0
  87. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/knowledge/document.py +0 -0
  88. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/knowledge/identifier.py +0 -0
  89. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/knowledge/organization.py +0 -0
  90. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/knowledge/publication.py +0 -0
  91. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/log_level.py +0 -0
  92. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/registry.py +0 -0
  93. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/base.py +0 -0
  94. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/config.py +0 -0
  95. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/document_loading.py +0 -0
  96. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/embeddings.py +0 -0
  97. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/knowledge.py +0 -0
  98. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/library.py +0 -0
  99. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/metadata.py +0 -0
  100. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/nlp_query.py +0 -0
  101. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/objects_query.py +0 -0
  102. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/primitives.py +0 -0
  103. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/prompt.py +0 -0
  104. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/retrieval.py +0 -0
  105. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/text_completion.py +0 -0
  106. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/tool.py +0 -0
  107. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/messaging/translators/triples.py +0 -0
  108. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/objects/__init__.py +0 -0
  109. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/objects/field.py +0 -0
  110. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/objects/object.py +0 -0
  111. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/rdf.py +0 -0
  112. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/__init__.py +0 -0
  113. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/core/__init__.py +0 -0
  114. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/core/metadata.py +0 -0
  115. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/core/primitives.py +0 -0
  116. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/core/topic.py +0 -0
  117. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/__init__.py +0 -0
  118. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/document.py +0 -0
  119. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/embeddings.py +0 -0
  120. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/graph.py +0 -0
  121. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/knowledge.py +0 -0
  122. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/nlp.py +0 -0
  123. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/object.py +0 -0
  124. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/rows.py +0 -0
  125. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/knowledge/structured.py +0 -0
  126. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/config.py +0 -0
  127. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/library.py +0 -0
  128. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/llm.py +0 -0
  129. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/lookup.py +0 -0
  130. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/nlp_query.py +0 -0
  131. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/objects_query.py +0 -0
  132. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/prompt.py +0 -0
  133. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/query.py +0 -0
  134. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph/schema/services/retrieval.py +0 -0
  135. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/trustgraph_base.egg-info/dependency_links.txt +0 -0
  136. {trustgraph_base-1.3.15 → trustgraph_base-1.5.1}/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.3.15
3
+ Version: 1.5.1
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
@@ -10,5 +10,6 @@ Requires-Python: >=3.8
10
10
  Description-Content-Type: text/markdown
11
11
  Requires-Dist: pulsar-client
12
12
  Requires-Dist: prometheus-client
13
+ Requires-Dist: requests
13
14
 
14
15
  See https://trustgraph.ai/
@@ -12,6 +12,7 @@ requires-python = ">=3.8"
12
12
  dependencies = [
13
13
  "pulsar-client",
14
14
  "prometheus-client",
15
+ "requests",
15
16
  ]
16
17
  classifiers = [
17
18
  "Programming Language :: Python :: 3",
@@ -8,6 +8,7 @@ from . library import Library
8
8
  from . flow import Flow
9
9
  from . config import Config
10
10
  from . knowledge import Knowledge
11
+ from . collection import Collection
11
12
  from . exceptions import *
12
13
  from . types import *
13
14
 
@@ -68,3 +69,6 @@ class Api:
68
69
 
69
70
  def library(self):
70
71
  return Library(self)
72
+
73
+ def collection(self):
74
+ return Collection(self)
@@ -0,0 +1,98 @@
1
+ import datetime
2
+ import logging
3
+
4
+ from . types import CollectionMetadata
5
+ from . exceptions import *
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ class Collection:
10
+
11
+ def __init__(self, api):
12
+ self.api = api
13
+
14
+ def request(self, request):
15
+ return self.api.request(f"collection-management", request)
16
+
17
+ def list_collections(self, user, tag_filter=None):
18
+
19
+ input = {
20
+ "operation": "list-collections",
21
+ "user": user,
22
+ }
23
+
24
+ if tag_filter:
25
+ input["tag_filter"] = tag_filter
26
+
27
+ object = self.request(input)
28
+
29
+ try:
30
+ # Handle case where collections might be None or missing
31
+ if object is None or "collections" not in object:
32
+ return []
33
+
34
+ collections = object.get("collections", [])
35
+ if collections is None:
36
+ return []
37
+
38
+ return [
39
+ CollectionMetadata(
40
+ user = v["user"],
41
+ collection = v["collection"],
42
+ name = v["name"],
43
+ description = v["description"],
44
+ tags = v["tags"],
45
+ created_at = v["created_at"],
46
+ updated_at = v["updated_at"]
47
+ )
48
+ for v in collections
49
+ ]
50
+ except Exception as e:
51
+ logger.error("Failed to parse collection list response", exc_info=True)
52
+ raise ProtocolException(f"Response not formatted correctly")
53
+
54
+ def update_collection(self, user, collection, name=None, description=None, tags=None):
55
+
56
+ input = {
57
+ "operation": "update-collection",
58
+ "user": user,
59
+ "collection": collection,
60
+ }
61
+
62
+ if name is not None:
63
+ input["name"] = name
64
+ if description is not None:
65
+ input["description"] = description
66
+ if tags is not None:
67
+ input["tags"] = tags
68
+
69
+ object = self.request(input)
70
+
71
+ try:
72
+ if "collections" in object and object["collections"]:
73
+ v = object["collections"][0]
74
+ return CollectionMetadata(
75
+ user = v["user"],
76
+ collection = v["collection"],
77
+ name = v["name"],
78
+ description = v["description"],
79
+ tags = v["tags"],
80
+ created_at = v["created_at"],
81
+ updated_at = v["updated_at"]
82
+ )
83
+ return None
84
+ except Exception as e:
85
+ logger.error("Failed to parse collection update response", exc_info=True)
86
+ raise ProtocolException(f"Response not formatted correctly")
87
+
88
+ def delete_collection(self, user, collection):
89
+
90
+ input = {
91
+ "operation": "delete-collection",
92
+ "user": user,
93
+ "collection": collection,
94
+ }
95
+
96
+ object = self.request(input)
97
+
98
+ return {}
@@ -87,7 +87,7 @@ class Flow:
87
87
 
88
88
  return json.loads(self.request(request = input)["flow"])
89
89
 
90
- def start(self, class_name, id, description):
90
+ def start(self, class_name, id, description, parameters=None):
91
91
 
92
92
  # The input consists of system and prompt strings
93
93
  input = {
@@ -97,6 +97,9 @@ class Flow:
97
97
  "description": description,
98
98
  }
99
99
 
100
+ if parameters:
101
+ input["parameters"] = parameters
102
+
100
103
  self.request(request = input)
101
104
 
102
105
  def stop(self, id):
@@ -132,12 +135,24 @@ class FlowInstance:
132
135
  input
133
136
  )["response"]
134
137
 
135
- def agent(self, question):
138
+ def agent(self, question, user="trustgraph", state=None, group=None, history=None):
136
139
 
137
- # The input consists of a question
140
+ # The input consists of a question and optional context
138
141
  input = {
139
- "question": question
142
+ "question": question,
143
+ "user": user,
140
144
  }
145
+
146
+ # Only include state if it has a value
147
+ if state is not None:
148
+ input["state"] = state
149
+
150
+ # Only include group if it has a value
151
+ if group is not None:
152
+ input["group"] = group
153
+
154
+ # Always include history (empty list if None)
155
+ input["history"] = history or []
141
156
 
142
157
  return self.request(
143
158
  "service/agent",
@@ -456,32 +471,172 @@ class FlowInstance:
456
471
 
457
472
  return response
458
473
 
459
- def structured_query(self, question):
474
+ def structured_query(self, question, user="trustgraph", collection="default"):
460
475
  """
461
476
  Execute a natural language question against structured data.
462
477
  Combines NLP query conversion and GraphQL execution.
463
478
 
464
479
  Args:
465
480
  question: Natural language question
481
+ user: Cassandra keyspace identifier (default: "trustgraph")
482
+ collection: Data collection identifier (default: "default")
466
483
 
467
484
  Returns:
468
485
  dict with data and optional errors
469
486
  """
470
487
 
471
488
  input = {
472
- "question": question
489
+ "question": question,
490
+ "user": user,
491
+ "collection": collection
473
492
  }
474
493
 
475
494
  response = self.request(
476
495
  "service/structured-query",
477
496
  input
478
497
  )
479
-
498
+
480
499
  # Check for system-level error
481
500
  if "error" in response and response["error"]:
482
501
  error_type = response["error"].get("type", "unknown")
483
502
  error_message = response["error"].get("message", "Unknown error")
484
503
  raise ProtocolException(f"{error_type}: {error_message}")
485
-
504
+
505
+ return response
506
+
507
+ def detect_type(self, sample):
508
+ """
509
+ Detect the data type of a structured data sample.
510
+
511
+ Args:
512
+ sample: Data sample to analyze (string content)
513
+
514
+ Returns:
515
+ dict with detected_type, confidence, and optional metadata
516
+ """
517
+
518
+ input = {
519
+ "operation": "detect-type",
520
+ "sample": sample
521
+ }
522
+
523
+ response = self.request(
524
+ "service/structured-diag",
525
+ input
526
+ )
527
+
528
+ # Check for system-level error
529
+ if "error" in response and response["error"]:
530
+ error_type = response["error"].get("type", "unknown")
531
+ error_message = response["error"].get("message", "Unknown error")
532
+ raise ProtocolException(f"{error_type}: {error_message}")
533
+
534
+ return response["detected-type"]
535
+
536
+ def generate_descriptor(self, sample, data_type, schema_name, options=None):
537
+ """
538
+ Generate a descriptor for structured data mapping to a specific schema.
539
+
540
+ Args:
541
+ sample: Data sample to analyze (string content)
542
+ data_type: Data type (csv, json, xml)
543
+ schema_name: Target schema name for descriptor generation
544
+ options: Optional parameters (e.g., delimiter for CSV)
545
+
546
+ Returns:
547
+ dict with descriptor and metadata
548
+ """
549
+
550
+ input = {
551
+ "operation": "generate-descriptor",
552
+ "sample": sample,
553
+ "type": data_type,
554
+ "schema-name": schema_name
555
+ }
556
+
557
+ if options:
558
+ input["options"] = options
559
+
560
+ response = self.request(
561
+ "service/structured-diag",
562
+ input
563
+ )
564
+
565
+ # Check for system-level error
566
+ if "error" in response and response["error"]:
567
+ error_type = response["error"].get("type", "unknown")
568
+ error_message = response["error"].get("message", "Unknown error")
569
+ raise ProtocolException(f"{error_type}: {error_message}")
570
+
571
+ return response["descriptor"]
572
+
573
+ def diagnose_data(self, sample, schema_name=None, options=None):
574
+ """
575
+ Perform combined data diagnosis: detect type and generate descriptor.
576
+
577
+ Args:
578
+ sample: Data sample to analyze (string content)
579
+ schema_name: Optional target schema name for descriptor generation
580
+ options: Optional parameters (e.g., delimiter for CSV)
581
+
582
+ Returns:
583
+ dict with detected_type, confidence, descriptor, and metadata
584
+ """
585
+
586
+ input = {
587
+ "operation": "diagnose",
588
+ "sample": sample
589
+ }
590
+
591
+ if schema_name:
592
+ input["schema-name"] = schema_name
593
+
594
+ if options:
595
+ input["options"] = options
596
+
597
+ response = self.request(
598
+ "service/structured-diag",
599
+ input
600
+ )
601
+
602
+ # Check for system-level error
603
+ if "error" in response and response["error"]:
604
+ error_type = response["error"].get("type", "unknown")
605
+ error_message = response["error"].get("message", "Unknown error")
606
+ raise ProtocolException(f"{error_type}: {error_message}")
607
+
486
608
  return response
487
609
 
610
+ def schema_selection(self, sample, options=None):
611
+ """
612
+ Select matching schemas for a data sample using prompt analysis.
613
+
614
+ Args:
615
+ sample: Data sample to analyze (string content)
616
+ options: Optional parameters
617
+
618
+ Returns:
619
+ dict with schema_matches array and metadata
620
+ """
621
+
622
+ input = {
623
+ "operation": "schema-selection",
624
+ "sample": sample
625
+ }
626
+
627
+ if options:
628
+ input["options"] = options
629
+
630
+ response = self.request(
631
+ "service/structured-diag",
632
+ input
633
+ )
634
+
635
+ # Check for system-level error
636
+ if "error" in response and response["error"]:
637
+ error_type = response["error"].get("type", "unknown")
638
+ error_message = response["error"].get("message", "Unknown error")
639
+ raise ProtocolException(f"{error_type}: {error_message}")
640
+
641
+ return response["schema-matches"]
642
+
@@ -41,3 +41,13 @@ class ProcessingMetadata:
41
41
  user : str
42
42
  collection : str
43
43
  tags : List[str]
44
+
45
+ @dataclasses.dataclass
46
+ class CollectionMetadata:
47
+ user : str
48
+ collection : str
49
+ name : str
50
+ description : str
51
+ tags : List[str]
52
+ created_at : str
53
+ updated_at : str
@@ -8,11 +8,12 @@ from . subscriber import Subscriber
8
8
  from . metrics import ProcessorMetrics, ConsumerMetrics, ProducerMetrics
9
9
  from . flow_processor import FlowProcessor
10
10
  from . consumer_spec import ConsumerSpec
11
- from . setting_spec import SettingSpec
11
+ from . parameter_spec import ParameterSpec
12
12
  from . producer_spec import ProducerSpec
13
13
  from . subscriber_spec import SubscriberSpec
14
14
  from . request_response_spec import RequestResponseSpec
15
15
  from . llm_service import LlmService, LlmResult
16
+ from . chunking_service import ChunkingService
16
17
  from . embeddings_service import EmbeddingsService
17
18
  from . embeddings_client import EmbeddingsClientSpec
18
19
  from . text_completion_client import TextCompletionClientSpec
@@ -0,0 +1,62 @@
1
+ """
2
+ Base chunking service that provides parameter specification functionality
3
+ for chunk-size and chunk-overlap parameters
4
+ """
5
+
6
+ import logging
7
+ from .flow_processor import FlowProcessor
8
+ from .parameter_spec import ParameterSpec
9
+
10
+ # Module logger
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class ChunkingService(FlowProcessor):
14
+ """Base service for chunking processors with parameter specification support"""
15
+
16
+ def __init__(self, **params):
17
+
18
+ # Call parent constructor
19
+ super(ChunkingService, self).__init__(**params)
20
+
21
+ # Register parameter specifications for chunk-size and chunk-overlap
22
+ self.register_specification(
23
+ ParameterSpec(name="chunk-size")
24
+ )
25
+
26
+ self.register_specification(
27
+ ParameterSpec(name="chunk-overlap")
28
+ )
29
+
30
+ logger.debug("ChunkingService initialized with parameter specifications")
31
+
32
+ async def chunk_document(self, msg, consumer, flow, default_chunk_size, default_chunk_overlap):
33
+ """
34
+ Extract chunk parameters from flow and return effective values
35
+
36
+ Args:
37
+ msg: The message containing the document to chunk
38
+ consumer: The consumer spec
39
+ flow: The flow context
40
+ default_chunk_size: Default chunk size from processor config
41
+ default_chunk_overlap: Default chunk overlap from processor config
42
+
43
+ Returns:
44
+ tuple: (chunk_size, chunk_overlap) - effective values to use
45
+ """
46
+ # Extract parameters from flow (flow-configurable parameters)
47
+ chunk_size = flow("chunk-size")
48
+ chunk_overlap = flow("chunk-overlap")
49
+
50
+ # Use provided values or fall back to defaults
51
+ effective_chunk_size = chunk_size if chunk_size is not None else default_chunk_size
52
+ effective_chunk_overlap = chunk_overlap if chunk_overlap is not None else default_chunk_overlap
53
+
54
+ logger.debug(f"Using chunk-size: {effective_chunk_size}")
55
+ logger.debug(f"Using chunk-overlap: {effective_chunk_overlap}")
56
+
57
+ return effective_chunk_size, effective_chunk_overlap
58
+
59
+ @staticmethod
60
+ def add_args(parser):
61
+ """Add chunking service arguments to parser"""
62
+ FlowProcessor.add_args(parser)
@@ -12,7 +12,7 @@ class Flow:
12
12
  # Consumers and publishers. Is this a bit untidy?
13
13
  self.consumer = {}
14
14
 
15
- self.setting = {}
15
+ self.parameter = {}
16
16
 
17
17
  for spec in processor.specifications:
18
18
  spec.add(self, processor, defn)
@@ -28,5 +28,5 @@ class Flow:
28
28
  def __call__(self, key):
29
29
  if key in self.producer: return self.producer[key]
30
30
  if key in self.consumer: return self.consumer[key]
31
- if key in self.setting: return self.setting[key].value
31
+ if key in self.parameter: return self.parameter[key].value
32
32
  return None
@@ -35,7 +35,7 @@ class FlowProcessor(AsyncProcessor):
35
35
 
36
36
  # These can be overriden by a derived class:
37
37
 
38
- # Array of specifications: ConsumerSpec, ProducerSpec, SettingSpec
38
+ # Array of specifications: ConsumerSpec, ProducerSpec, ParameterSpec
39
39
  self.specifications = []
40
40
 
41
41
  logger.info("Service initialised.")
@@ -5,11 +5,11 @@ LLM text completion base class
5
5
 
6
6
  import time
7
7
  import logging
8
- from prometheus_client import Histogram
8
+ from prometheus_client import Histogram, Info
9
9
 
10
10
  from .. schema import TextCompletionRequest, TextCompletionResponse, Error
11
11
  from .. exceptions import TooManyRequests
12
- from .. base import FlowProcessor, ConsumerSpec, ProducerSpec
12
+ from .. base import FlowProcessor, ConsumerSpec, ProducerSpec, ParameterSpec
13
13
 
14
14
  # Module logger
15
15
  logger = logging.getLogger(__name__)
@@ -32,7 +32,7 @@ class LlmService(FlowProcessor):
32
32
 
33
33
  def __init__(self, **params):
34
34
 
35
- id = params.get("id")
35
+ id = params.get("id", default_ident)
36
36
  concurrency = params.get("concurrency", 1)
37
37
 
38
38
  super(LlmService, self).__init__(**params | {
@@ -56,6 +56,18 @@ class LlmService(FlowProcessor):
56
56
  )
57
57
  )
58
58
 
59
+ self.register_specification(
60
+ ParameterSpec(
61
+ name = "model",
62
+ )
63
+ )
64
+
65
+ self.register_specification(
66
+ ParameterSpec(
67
+ name = "temperature",
68
+ )
69
+ )
70
+
59
71
  if not hasattr(__class__, "text_completion_metric"):
60
72
  __class__.text_completion_metric = Histogram(
61
73
  'text_completion_duration',
@@ -70,6 +82,13 @@ class LlmService(FlowProcessor):
70
82
  ]
71
83
  )
72
84
 
85
+ if not hasattr(__class__, "text_completion_model_metric"):
86
+ __class__.text_completion_model_metric = Info(
87
+ 'text_completion_model',
88
+ 'Text completion model',
89
+ ["processor", "flow"]
90
+ )
91
+
73
92
  async def on_request(self, msg, consumer, flow):
74
93
 
75
94
  try:
@@ -85,10 +104,21 @@ class LlmService(FlowProcessor):
85
104
  flow=f"{flow.name}-{consumer.name}",
86
105
  ).time():
87
106
 
107
+ model = flow("model")
108
+ temperature = flow("temperature")
109
+
88
110
  response = await self.generate_content(
89
- request.system, request.prompt
111
+ request.system, request.prompt, model, temperature
90
112
  )
91
113
 
114
+ __class__.text_completion_model_metric.labels(
115
+ processor = self.id,
116
+ flow = flow.name
117
+ ).info({
118
+ "model": str(model) if model is not None else "",
119
+ "temperature": str(temperature) if temperature is not None else "",
120
+ })
121
+
92
122
  await flow("response").send(
93
123
  TextCompletionResponse(
94
124
  error=None,
@@ -1,7 +1,7 @@
1
1
 
2
2
  from . spec import Spec
3
3
 
4
- class Setting:
4
+ class Parameter:
5
5
  def __init__(self, value):
6
6
  self.value = value
7
7
  async def start():
@@ -9,11 +9,13 @@ class Setting:
9
9
  async def stop():
10
10
  pass
11
11
 
12
- class SettingSpec(Spec):
12
+ class ParameterSpec(Spec):
13
13
  def __init__(self, name):
14
14
  self.name = name
15
15
 
16
16
  def add(self, flow, processor, definition):
17
17
 
18
- flow.config[self.name] = Setting(definition[self.name])
18
+ value = definition.get(self.name, None)
19
+
20
+ flow.parameter[self.name] = Parameter(value)
19
21
 
@@ -49,8 +49,6 @@ class RequestResponse(Subscriber):
49
49
 
50
50
  id = str(uuid.uuid4())
51
51
 
52
- logger.debug(f"Sending request {id}...")
53
-
54
52
  q = await self.subscribe(id)
55
53
 
56
54
  try:
@@ -75,8 +73,6 @@ class RequestResponse(Subscriber):
75
73
  timeout=timeout
76
74
  )
77
75
 
78
- logger.debug("Received response")
79
-
80
76
  if recipient is None:
81
77
 
82
78
  # If no recipient handler, just return the first
@@ -2,10 +2,12 @@ from . request_response_spec import RequestResponse, RequestResponseSpec
2
2
  from .. schema import StructuredQueryRequest, StructuredQueryResponse
3
3
 
4
4
  class StructuredQueryClient(RequestResponse):
5
- async def structured_query(self, question, timeout=600):
5
+ async def structured_query(self, question, user="trustgraph", collection="default", timeout=600):
6
6
  resp = await self.request(
7
7
  StructuredQueryRequest(
8
- question = question
8
+ question = question,
9
+ user = user,
10
+ collection = collection
9
11
  ),
10
12
  timeout=timeout
11
13
  )
@@ -0,0 +1 @@
1
+ __version__ = "1.5.1"
@@ -24,6 +24,8 @@ from .translators.embeddings_query import (
24
24
  from .translators.objects_query import ObjectsQueryRequestTranslator, ObjectsQueryResponseTranslator
25
25
  from .translators.nlp_query import QuestionToStructuredQueryRequestTranslator, QuestionToStructuredQueryResponseTranslator
26
26
  from .translators.structured_query import StructuredQueryRequestTranslator, StructuredQueryResponseTranslator
27
+ from .translators.diagnosis import StructuredDataDiagnosisRequestTranslator, StructuredDataDiagnosisResponseTranslator
28
+ from .translators.collection import CollectionManagementRequestTranslator, CollectionManagementResponseTranslator
27
29
 
28
30
  # Register all service translators
29
31
  TranslatorRegistry.register_service(
@@ -123,11 +125,23 @@ TranslatorRegistry.register_service(
123
125
  )
124
126
 
125
127
  TranslatorRegistry.register_service(
126
- "structured-query",
127
- StructuredQueryRequestTranslator(),
128
+ "structured-query",
129
+ StructuredQueryRequestTranslator(),
128
130
  StructuredQueryResponseTranslator()
129
131
  )
130
132
 
133
+ TranslatorRegistry.register_service(
134
+ "structured-diag",
135
+ StructuredDataDiagnosisRequestTranslator(),
136
+ StructuredDataDiagnosisResponseTranslator()
137
+ )
138
+
139
+ TranslatorRegistry.register_service(
140
+ "collection-management",
141
+ CollectionManagementRequestTranslator(),
142
+ CollectionManagementResponseTranslator()
143
+ )
144
+
131
145
  # Register single-direction translators for document loading
132
146
  TranslatorRegistry.register_request("document", DocumentTranslator())
133
147
  TranslatorRegistry.register_request("text-document", TextDocumentTranslator())
@@ -18,3 +18,4 @@ from .embeddings_query import (
18
18
  GraphEmbeddingsRequestTranslator, GraphEmbeddingsResponseTranslator
19
19
  )
20
20
  from .objects_query import ObjectsQueryRequestTranslator, ObjectsQueryResponseTranslator
21
+ from .diagnosis import StructuredDataDiagnosisRequestTranslator, StructuredDataDiagnosisResponseTranslator