langchain-timbr 2.1.14__py3-none-any.whl → 3.0.0__py3-none-any.whl
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.
- langchain_timbr/_version.py +2 -2
- langchain_timbr/langchain/execute_timbr_query_chain.py +62 -19
- langchain_timbr/langchain/generate_answer_chain.py +18 -4
- langchain_timbr/langchain/generate_timbr_sql_chain.py +54 -17
- langchain_timbr/langchain/identify_concept_chain.py +31 -9
- langchain_timbr/langchain/timbr_sql_agent.py +20 -1
- langchain_timbr/langchain/validate_timbr_sql_chain.py +57 -17
- langchain_timbr/langgraph/execute_timbr_query_node.py +3 -0
- langchain_timbr/langgraph/generate_response_node.py +5 -2
- langchain_timbr/langgraph/generate_timbr_sql_node.py +3 -0
- langchain_timbr/langgraph/identify_concept_node.py +3 -0
- langchain_timbr/langgraph/validate_timbr_query_node.py +3 -0
- langchain_timbr/utils/timbr_llm_utils.py +333 -166
- langchain_timbr/utils/timbr_utils.py +27 -0
- {langchain_timbr-2.1.14.dist-info → langchain_timbr-3.0.0.dist-info}/METADATA +1 -1
- langchain_timbr-3.0.0.dist-info/RECORD +28 -0
- langchain_timbr-2.1.14.dist-info/RECORD +0 -28
- {langchain_timbr-2.1.14.dist-info → langchain_timbr-3.0.0.dist-info}/WHEEL +0 -0
- {langchain_timbr-2.1.14.dist-info → langchain_timbr-3.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,6 +2,8 @@ from typing import Optional, Union, Dict, Any
|
|
|
2
2
|
from langchain.chains.base import Chain
|
|
3
3
|
from langchain.llms.base import LLM
|
|
4
4
|
|
|
5
|
+
from langchain_timbr.utils.timbr_utils import get_timbr_agent_options
|
|
6
|
+
|
|
5
7
|
from ..utils.general import parse_list, to_integer, to_boolean, validate_timbr_connection_params
|
|
6
8
|
from ..utils.timbr_llm_utils import generate_sql
|
|
7
9
|
from ..utils.timbr_utils import validate_sql
|
|
@@ -17,6 +19,8 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
17
19
|
compatible with the target Timbr ontology/knowledge graph structure. It uses an LLM
|
|
18
20
|
for validation and connects to Timbr via URL and token.
|
|
19
21
|
"""
|
|
22
|
+
|
|
23
|
+
_ontology: Optional[str] = None
|
|
20
24
|
|
|
21
25
|
def __init__(
|
|
22
26
|
self,
|
|
@@ -36,6 +40,7 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
36
40
|
note: Optional[str] = '',
|
|
37
41
|
db_is_case_sensitive: Optional[bool] = False,
|
|
38
42
|
graph_depth: Optional[int] = 1,
|
|
43
|
+
agent: Optional[str] = None,
|
|
39
44
|
verify_ssl: Optional[bool] = True,
|
|
40
45
|
is_jwt: Optional[bool] = False,
|
|
41
46
|
jwt_tenant_id: Optional[str] = None,
|
|
@@ -62,6 +67,7 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
62
67
|
:param note: Optional additional note to extend our llm prompt
|
|
63
68
|
:param db_is_case_sensitive: Whether the database is case sensitive (default is False).
|
|
64
69
|
:param graph_depth: Maximum number of relationship hops to traverse from the source concept during schema exploration (default is 1).
|
|
70
|
+
:param agent: Optional Timbr agent name for options setup.
|
|
65
71
|
:param verify_ssl: Whether to verify SSL certificates (default is True).
|
|
66
72
|
:param is_jwt: Whether to use JWT authentication (default is False).
|
|
67
73
|
:param jwt_tenant_id: JWT tenant ID for multi-tenant environments (required when is_jwt=True).
|
|
@@ -111,30 +117,58 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
111
117
|
|
|
112
118
|
self._url = url if url is not None else config.url
|
|
113
119
|
self._token = token if token is not None else config.token
|
|
114
|
-
self._ontology = ontology if ontology is not None else config.ontology
|
|
115
120
|
|
|
116
121
|
# Validate required parameters
|
|
117
122
|
validate_timbr_connection_params(self._url, self._token)
|
|
118
123
|
|
|
119
|
-
self._schema = schema
|
|
120
|
-
self._concept = concept
|
|
121
|
-
self._retries = retries
|
|
122
|
-
self._concepts_list = parse_list(concepts_list)
|
|
123
|
-
self._views_list = parse_list(views_list)
|
|
124
|
-
self._include_logic_concepts = to_boolean(include_logic_concepts)
|
|
125
|
-
self._include_tags = parse_list(include_tags)
|
|
126
|
-
self._exclude_properties = parse_list(exclude_properties)
|
|
127
|
-
self._max_limit = to_integer(max_limit)
|
|
128
|
-
self._note = note
|
|
129
|
-
self._db_is_case_sensitive = to_boolean(db_is_case_sensitive)
|
|
130
|
-
self._graph_depth = to_integer(graph_depth)
|
|
131
124
|
self._verify_ssl = to_boolean(verify_ssl)
|
|
132
125
|
self._is_jwt = to_boolean(is_jwt)
|
|
133
126
|
self._jwt_tenant_id = jwt_tenant_id
|
|
134
|
-
self._conn_params = conn_params or {}
|
|
135
|
-
self._enable_reasoning = to_boolean(enable_reasoning)
|
|
136
|
-
self._reasoning_steps = to_integer(reasoning_steps)
|
|
137
127
|
self._debug = to_boolean(debug)
|
|
128
|
+
self._conn_params = conn_params or {}
|
|
129
|
+
self._max_limit = config.llm_default_limit # use default value so the self._get_conn_params() won't fail before agent options are processed
|
|
130
|
+
|
|
131
|
+
self._agent = agent
|
|
132
|
+
if self._agent:
|
|
133
|
+
agent_options = get_timbr_agent_options(self._agent, conn_params=self._get_conn_params())
|
|
134
|
+
|
|
135
|
+
self._ontology = agent_options.get("ontology") if "ontology" in agent_options else None
|
|
136
|
+
self._schema = agent_options.get("schema") if "schema" in agent_options else schema
|
|
137
|
+
self._concept = agent_options.get("concept") if "concept" in agent_options else None
|
|
138
|
+
self._retries = to_integer(agent_options.get("retries") if "retries" in agent_options else retries)
|
|
139
|
+
self._concepts_list = parse_list(agent_options.get("concepts_list")) if "concepts_list" in agent_options else None
|
|
140
|
+
self._views_list = parse_list(agent_options.get("views_list")) if "views_list" in agent_options else None
|
|
141
|
+
self._include_logic_concepts = to_boolean(agent_options.get("include_logic_concepts")) if "include_logic_concepts" in agent_options else False
|
|
142
|
+
self._include_tags = parse_list(agent_options.get("include_tags")) if "include_tags" in agent_options else None
|
|
143
|
+
self._exclude_properties = parse_list(agent_options.get("exclude_properties")) if "exclude_properties" in agent_options else ['entity_id', 'entity_type', 'entity_label']
|
|
144
|
+
self._max_limit = to_integer(agent_options.get("max_limit")) if "max_limit" in agent_options else config.llm_default_limit
|
|
145
|
+
self._db_is_case_sensitive = to_boolean(agent_options.get("db_is_case_sensitive")) if "db_is_case_sensitive" in agent_options else False
|
|
146
|
+
self._graph_depth = to_integer(agent_options.get("graph_depth")) if "graph_depth" in agent_options else 1
|
|
147
|
+
self._note = agent_options.get("note") if "note" in agent_options else ''
|
|
148
|
+
if note:
|
|
149
|
+
self._note = ((self._note + '\n') if self._note else '') + note
|
|
150
|
+
self._enable_reasoning = to_boolean(agent_options.get("enable_reasoning")) if "enable_reasoning" in agent_options else config.enable_reasoning
|
|
151
|
+
if enable_reasoning is not None and enable_reasoning != self._enable_reasoning:
|
|
152
|
+
self._enable_reasoning = to_boolean(enable_reasoning)
|
|
153
|
+
self._reasoning_steps = to_integer(agent_options.get("reasoning_steps")) if "reasoning_steps" in agent_options else config.reasoning_steps
|
|
154
|
+
if reasoning_steps is not None and reasoning_steps != self._reasoning_steps:
|
|
155
|
+
self._reasoning_steps = to_integer(reasoning_steps)
|
|
156
|
+
else:
|
|
157
|
+
self._ontology = ontology if ontology is not None else config.ontology
|
|
158
|
+
self._schema = schema
|
|
159
|
+
self._concept = concept
|
|
160
|
+
self._retries = to_integer(retries)
|
|
161
|
+
self._concepts_list = parse_list(concepts_list)
|
|
162
|
+
self._views_list = parse_list(views_list)
|
|
163
|
+
self._include_logic_concepts = to_boolean(include_logic_concepts)
|
|
164
|
+
self._include_tags = parse_list(include_tags)
|
|
165
|
+
self._exclude_properties = parse_list(exclude_properties)
|
|
166
|
+
self._max_limit = to_integer(max_limit)
|
|
167
|
+
self._db_is_case_sensitive = to_boolean(db_is_case_sensitive)
|
|
168
|
+
self._graph_depth = to_integer(graph_depth)
|
|
169
|
+
self._note = note
|
|
170
|
+
self._enable_reasoning = to_boolean(enable_reasoning)
|
|
171
|
+
self._reasoning_steps = to_integer(reasoning_steps)
|
|
138
172
|
|
|
139
173
|
|
|
140
174
|
@property
|
|
@@ -163,7 +197,7 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
163
197
|
return {
|
|
164
198
|
"url": self._url,
|
|
165
199
|
"token": self._token,
|
|
166
|
-
"ontology": self._ontology,
|
|
200
|
+
"ontology": self._ontology if self._ontology is not None else config.ontology,
|
|
167
201
|
"verify_ssl": self._verify_ssl,
|
|
168
202
|
"is_jwt": self._is_jwt,
|
|
169
203
|
"jwt_tenant_id": self._jwt_tenant_id,
|
|
@@ -179,6 +213,8 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
179
213
|
schema = self._schema
|
|
180
214
|
concept = self._concept
|
|
181
215
|
reasoning_status = None
|
|
216
|
+
identify_concept_reason = None
|
|
217
|
+
generate_sql_reason = None
|
|
182
218
|
|
|
183
219
|
is_sql_valid, error, sql = validate_sql(sql, self._get_conn_params())
|
|
184
220
|
if not is_sql_valid:
|
|
@@ -211,6 +247,8 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
211
247
|
is_sql_valid = generate_res.get("is_sql_valid")
|
|
212
248
|
reasoning_status = generate_res.get("reasoning_status")
|
|
213
249
|
error = generate_res.get("error")
|
|
250
|
+
identify_concept_reason = generate_res.get("identify_concept_reason")
|
|
251
|
+
generate_sql_reason = generate_res.get("generate_sql_reason")
|
|
214
252
|
|
|
215
253
|
return {
|
|
216
254
|
"sql": sql,
|
|
@@ -219,5 +257,7 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
219
257
|
"is_sql_valid": is_sql_valid,
|
|
220
258
|
"error": error,
|
|
221
259
|
"reasoning_status": reasoning_status,
|
|
260
|
+
"identify_concept_reason": identify_concept_reason,
|
|
261
|
+
"generate_sql_reason": generate_sql_reason,
|
|
222
262
|
self.usage_metadata_key: usage_metadata,
|
|
223
263
|
}
|
|
@@ -32,6 +32,7 @@ class ExecuteSemanticQueryNode:
|
|
|
32
32
|
note: Optional[str] = '',
|
|
33
33
|
db_is_case_sensitive: Optional[bool] = False,
|
|
34
34
|
graph_depth: Optional[int] = 1,
|
|
35
|
+
agent: Optional[str] = None,
|
|
35
36
|
verify_ssl: Optional[bool] = True,
|
|
36
37
|
is_jwt: Optional[bool] = False,
|
|
37
38
|
jwt_tenant_id: Optional[str] = None,
|
|
@@ -61,6 +62,7 @@ class ExecuteSemanticQueryNode:
|
|
|
61
62
|
:param note: Optional additional note to extend our llm prompt
|
|
62
63
|
:param db_is_case_sensitive: Whether the database is case sensitive (default is False).
|
|
63
64
|
:param graph_depth: Maximum number of relationship hops to traverse from the source concept during schema exploration (default is 1).
|
|
65
|
+
:param agent: Optional Timbr agent name for options setup.
|
|
64
66
|
:param verify_ssl: Whether to verify SSL certificates (default is True).
|
|
65
67
|
:param is_jwt: Whether to use JWT authentication (default is False).
|
|
66
68
|
:param jwt_tenant_id: JWT tenant ID for multi-tenant environments (required when is_jwt=True).
|
|
@@ -89,6 +91,7 @@ class ExecuteSemanticQueryNode:
|
|
|
89
91
|
note=note,
|
|
90
92
|
db_is_case_sensitive=db_is_case_sensitive,
|
|
91
93
|
graph_depth=graph_depth,
|
|
94
|
+
agent=agent,
|
|
92
95
|
verify_ssl=verify_ssl,
|
|
93
96
|
is_jwt=is_jwt,
|
|
94
97
|
jwt_tenant_id=jwt_tenant_id,
|
|
@@ -16,11 +16,12 @@ class GenerateResponseNode:
|
|
|
16
16
|
llm: Optional[LLM] = None,
|
|
17
17
|
url: Optional[str] = None,
|
|
18
18
|
token: Optional[str] = None,
|
|
19
|
+
note: Optional[str] = '',
|
|
20
|
+
agent: Optional[str] = None,
|
|
19
21
|
verify_ssl: Optional[bool] = True,
|
|
20
22
|
is_jwt: Optional[bool] = False,
|
|
21
23
|
jwt_tenant_id: Optional[str] = None,
|
|
22
24
|
conn_params: Optional[dict] = None,
|
|
23
|
-
note: Optional[str] = '',
|
|
24
25
|
debug: Optional[bool] = False,
|
|
25
26
|
**kwargs,
|
|
26
27
|
):
|
|
@@ -28,11 +29,12 @@ class GenerateResponseNode:
|
|
|
28
29
|
:param llm: An LLM instance or a function that takes a prompt string and returns the LLM's response (optional, will use LlmWrapper with env variables if not provided)
|
|
29
30
|
:param url: Timbr server url (optional, defaults to TIMBR_URL environment variable)
|
|
30
31
|
:param token: Timbr password or token value (optional, defaults to TIMBR_TOKEN environment variable)
|
|
32
|
+
:param note: Optional additional note to extend our llm prompt
|
|
33
|
+
:param agent: Optional Timbr agent name for options setup.
|
|
31
34
|
:param verify_ssl: Whether to verify SSL certificates (default is True).
|
|
32
35
|
:param is_jwt: Whether to use JWT authentication (default is False).
|
|
33
36
|
:param jwt_tenant_id: JWT tenant ID for multi-tenant environments (required when is_jwt=True).
|
|
34
37
|
:param conn_params: Extra Timbr connection parameters sent with every request (e.g., 'x-api-impersonate-user').
|
|
35
|
-
:param note: Optional additional note to extend our llm prompt
|
|
36
38
|
"""
|
|
37
39
|
self.chain = GenerateAnswerChain(
|
|
38
40
|
llm=llm,
|
|
@@ -43,6 +45,7 @@ class GenerateResponseNode:
|
|
|
43
45
|
jwt_tenant_id=jwt_tenant_id,
|
|
44
46
|
conn_params=conn_params,
|
|
45
47
|
note=note,
|
|
48
|
+
agent=agent,
|
|
46
49
|
debug=debug,
|
|
47
50
|
**kwargs,
|
|
48
51
|
)
|
|
@@ -29,6 +29,7 @@ class GenerateTimbrSqlNode:
|
|
|
29
29
|
note: Optional[str] = '',
|
|
30
30
|
db_is_case_sensitive: Optional[bool] = False,
|
|
31
31
|
graph_depth: Optional[int] = 1,
|
|
32
|
+
agent: Optional[str] = None,
|
|
32
33
|
verify_ssl: Optional[bool] = True,
|
|
33
34
|
is_jwt: Optional[bool] = False,
|
|
34
35
|
jwt_tenant_id: Optional[str] = None,
|
|
@@ -56,6 +57,7 @@ class GenerateTimbrSqlNode:
|
|
|
56
57
|
:param note: Optional additional note to extend our llm prompt
|
|
57
58
|
:param db_is_case_sensitive: Whether the database is case sensitive (default is False).
|
|
58
59
|
:param graph_depth: Maximum number of relationship hops to traverse from the source concept during schema exploration (default is 1).
|
|
60
|
+
:param agent: Optional Timbr agent name for options setup.
|
|
59
61
|
:param verify_ssl: Whether to verify SSL certificates (default is True).
|
|
60
62
|
:param is_jwt: Whether to use JWT authentication (default: False)
|
|
61
63
|
:param jwt_tenant_id: Tenant ID for JWT authentication when using multi-tenant setup
|
|
@@ -81,6 +83,7 @@ class GenerateTimbrSqlNode:
|
|
|
81
83
|
note=note,
|
|
82
84
|
db_is_case_sensitive=db_is_case_sensitive,
|
|
83
85
|
graph_depth=graph_depth,
|
|
86
|
+
agent=agent,
|
|
84
87
|
verify_ssl=verify_ssl,
|
|
85
88
|
is_jwt=is_jwt,
|
|
86
89
|
jwt_tenant_id=jwt_tenant_id,
|
|
@@ -19,6 +19,7 @@ class IdentifyConceptNode:
|
|
|
19
19
|
should_validate: Optional[bool] = False,
|
|
20
20
|
retries: Optional[int] = 3,
|
|
21
21
|
note: Optional[str] = None,
|
|
22
|
+
agent: Optional[str] = None,
|
|
22
23
|
verify_ssl: Optional[bool] = True,
|
|
23
24
|
is_jwt: Optional[bool] = False,
|
|
24
25
|
jwt_tenant_id: Optional[str] = None,
|
|
@@ -38,6 +39,7 @@ class IdentifyConceptNode:
|
|
|
38
39
|
:param should_validate: Whether to validate the identified concept before returning it
|
|
39
40
|
:param retries: Number of retry attempts if the identified concept is invalid
|
|
40
41
|
:param note: Optional additional note to extend our llm prompt
|
|
42
|
+
:param agent: Optional Timbr agent name for options setup.
|
|
41
43
|
:param verify_ssl: Whether to verify SSL certificates
|
|
42
44
|
:param is_jwt: Whether to use JWT authentication (default: False)
|
|
43
45
|
:param jwt_tenant_id: Tenant ID for JWT authentication when using multi-tenant setup
|
|
@@ -55,6 +57,7 @@ class IdentifyConceptNode:
|
|
|
55
57
|
should_validate=should_validate,
|
|
56
58
|
retries=retries,
|
|
57
59
|
note=note,
|
|
60
|
+
agent=agent,
|
|
58
61
|
verify_ssl=verify_ssl,
|
|
59
62
|
is_jwt=is_jwt,
|
|
60
63
|
jwt_tenant_id=jwt_tenant_id,
|
|
@@ -29,6 +29,7 @@ class ValidateSemanticSqlNode:
|
|
|
29
29
|
note: Optional[str] = None,
|
|
30
30
|
db_is_case_sensitive: Optional[bool] = False,
|
|
31
31
|
graph_depth: Optional[int] = 1,
|
|
32
|
+
agent: Optional[str] = None,
|
|
32
33
|
verify_ssl: Optional[bool] = True,
|
|
33
34
|
is_jwt: Optional[bool] = False,
|
|
34
35
|
jwt_tenant_id: Optional[str] = None,
|
|
@@ -55,6 +56,7 @@ class ValidateSemanticSqlNode:
|
|
|
55
56
|
:param note: Optional additional note to extend our llm prompt
|
|
56
57
|
:param db_is_case_sensitive: Whether the database is case sensitive (default is False).
|
|
57
58
|
:param graph_depth: Maximum number of relationship hops to traverse from the source concept during schema exploration (default is 1).
|
|
59
|
+
:param agent: Optional Timbr agent name for options setup.
|
|
58
60
|
:param verify_ssl: Whether to verify SSL certificates (default is True).
|
|
59
61
|
:param is_jwt: Whether to use JWT authentication (default: False)
|
|
60
62
|
:param jwt_tenant_id: Tenant ID for JWT authentication when using multi-tenant setup
|
|
@@ -79,6 +81,7 @@ class ValidateSemanticSqlNode:
|
|
|
79
81
|
note=note,
|
|
80
82
|
db_is_case_sensitive=db_is_case_sensitive,
|
|
81
83
|
graph_depth=graph_depth,
|
|
84
|
+
agent=agent,
|
|
82
85
|
verify_ssl=verify_ssl,
|
|
83
86
|
is_jwt=is_jwt,
|
|
84
87
|
jwt_tenant_id=jwt_tenant_id,
|