langchain-timbr 1.5.3__tar.gz → 1.5.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.
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/PKG-INFO +1 -1
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/_version.py +2 -2
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/config.py +2 -1
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/execute_timbr_query_chain.py +39 -15
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/generate_answer_chain.py +36 -10
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/generate_timbr_sql_chain.py +37 -13
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/identify_concept_chain.py +38 -14
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/timbr_sql_agent.py +35 -17
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/validate_timbr_sql_chain.py +37 -13
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langgraph/execute_timbr_query_node.py +6 -6
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langgraph/generate_response_node.py +7 -8
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langgraph/generate_timbr_sql_node.py +6 -6
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langgraph/identify_concept_node.py +6 -6
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langgraph/validate_timbr_query_node.py +9 -9
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/llm_wrapper/llm_wrapper.py +48 -17
- langchain_timbr-1.5.5/src/langchain_timbr/utils/general.py +140 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/utils/prompt_service.py +42 -61
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/utils/timbr_llm_utils.py +4 -4
- langchain_timbr-1.5.5/tests/standard/test_connection_validation.py +146 -0
- langchain_timbr-1.5.5/tests/standard/test_llm_wrapper_optional_params.py +105 -0
- langchain_timbr-1.5.5/tests/standard/test_optional_llm_integration.py +169 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/standard/test_standard_chain_requirements.py +1 -1
- langchain_timbr-1.5.3/src/langchain_timbr/utils/general.py +0 -71
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/.github/dependabot.yml +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/.github/pull_request_template.md +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/.github/workflows/_codespell.yml +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/.github/workflows/_fossa.yml +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/.github/workflows/install-dependencies-and-run-tests.yml +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/.github/workflows/publish.yml +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/.gitignore +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/LICENSE +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/README.md +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/pyproject.toml +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/pytest.ini +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/requirements.txt +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/__init__.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/__init__.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langgraph/__init__.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/llm_wrapper/timbr_llm_wrapper.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/timbr_llm_connector.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/utils/temperature_supported_models.json +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/utils/timbr_utils.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/README.md +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/conftest.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_agent_integration.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_azure_databricks_provider.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_azure_openai_model.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_chain_pipeline.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_jwt_token.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_langchain_chains.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_langgraph_nodes.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/integration/test_timeout_functionality.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/standard/conftest.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/standard/test_chain_documentation.py +0 -0
- {langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/tests/standard/test_unit_tests.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langchain-timbr
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.5
|
|
4
4
|
Summary: LangChain & LangGraph extensions that parse LLM prompts into Timbr semantic SQL and execute them.
|
|
5
5
|
Project-URL: Homepage, https://github.com/WPSemantix/langchain-timbr
|
|
6
6
|
Project-URL: Documentation, https://docs.timbr.ai/doc/docs/integration/langchain-sdk/
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.5.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 5,
|
|
31
|
+
__version__ = version = '1.5.5'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 5, 5)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -4,7 +4,7 @@ from .utils.general import to_boolean, to_integer, parse_list
|
|
|
4
4
|
# MUST HAVE VARIABLES
|
|
5
5
|
url = os.environ.get('TIMBR_URL')
|
|
6
6
|
token = os.environ.get('TIMBR_TOKEN')
|
|
7
|
-
ontology = os.environ.get('ONTOLOGY', 'system_db')
|
|
7
|
+
ontology = os.environ.get('TIMBR_ONTOLOGY', os.environ.get('ONTOLOGY', 'system_db'))
|
|
8
8
|
|
|
9
9
|
# OPTIONAL VARIABLES
|
|
10
10
|
is_jwt = to_boolean(os.environ.get('IS_JWT', 'false'))
|
|
@@ -18,4 +18,5 @@ llm_type = os.environ.get('LLM_TYPE')
|
|
|
18
18
|
llm_model = os.environ.get('LLM_MODEL')
|
|
19
19
|
llm_api_key = os.environ.get('LLM_API_KEY')
|
|
20
20
|
llm_temperature = os.environ.get('LLM_TEMPERATURE', 0.0)
|
|
21
|
+
llm_additional_params = os.environ.get('LLM_ADDITIONAL_PARAMS', '')
|
|
21
22
|
llm_timeout = to_integer(os.environ.get('LLM_TIMEOUT', 60)) # Default 60 seconds timeout
|
|
@@ -2,9 +2,11 @@ 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 ..utils.general import parse_list, to_boolean, to_integer
|
|
5
|
+
from ..utils.general import parse_list, to_boolean, to_integer, validate_timbr_connection_params
|
|
6
6
|
from ..utils.timbr_utils import run_query, validate_sql
|
|
7
7
|
from ..utils.timbr_llm_utils import generate_sql
|
|
8
|
+
from ..llm_wrapper.llm_wrapper import LlmWrapper
|
|
9
|
+
from .. import config
|
|
8
10
|
|
|
9
11
|
class ExecuteTimbrQueryChain(Chain):
|
|
10
12
|
"""
|
|
@@ -17,10 +19,10 @@ class ExecuteTimbrQueryChain(Chain):
|
|
|
17
19
|
|
|
18
20
|
def __init__(
|
|
19
21
|
self,
|
|
20
|
-
llm: LLM,
|
|
21
|
-
url: str,
|
|
22
|
-
token: str,
|
|
23
|
-
ontology: str,
|
|
22
|
+
llm: Optional[LLM] = None,
|
|
23
|
+
url: Optional[str] = None,
|
|
24
|
+
token: Optional[str] = None,
|
|
25
|
+
ontology: Optional[str] = None,
|
|
24
26
|
schema: Optional[str] = 'dtimbr',
|
|
25
27
|
concept: Optional[str] = None,
|
|
26
28
|
concepts_list: Optional[Union[list[str], str]] = None,
|
|
@@ -44,10 +46,10 @@ class ExecuteTimbrQueryChain(Chain):
|
|
|
44
46
|
**kwargs,
|
|
45
47
|
):
|
|
46
48
|
"""
|
|
47
|
-
:param llm: An LLM instance or a function that takes a prompt string and returns the LLM's response
|
|
48
|
-
:param url: Timbr server url
|
|
49
|
-
:param token: Timbr password or token value
|
|
50
|
-
:param ontology: The name of the ontology/knowledge graph
|
|
49
|
+
: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)
|
|
50
|
+
:param url: Timbr server url (optional, defaults to TIMBR_URL environment variable)
|
|
51
|
+
:param token: Timbr password or token value (optional, defaults to TIMBR_TOKEN environment variable)
|
|
52
|
+
:param ontology: The name of the ontology/knowledge graph (optional, defaults to ONTOLOGY/TIMBR_ONTOLOGY environment variable)
|
|
51
53
|
:param schema: The name of the schema to query
|
|
52
54
|
:param concept: The name of the concept to query
|
|
53
55
|
:param concepts_list: Optional specific concept options to query
|
|
@@ -72,6 +74,7 @@ class ExecuteTimbrQueryChain(Chain):
|
|
|
72
74
|
|
|
73
75
|
## Example
|
|
74
76
|
```
|
|
77
|
+
# Using explicit parameters
|
|
75
78
|
execute_timbr_query_chain = ExecuteTimbrQueryChain(
|
|
76
79
|
url=<url>,
|
|
77
80
|
token=<token>,
|
|
@@ -85,14 +88,35 @@ class ExecuteTimbrQueryChain(Chain):
|
|
|
85
88
|
note=<note>,
|
|
86
89
|
)
|
|
87
90
|
|
|
91
|
+
# Using environment variables for timbr environment (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY)
|
|
92
|
+
execute_timbr_query_chain = ExecuteTimbrQueryChain(
|
|
93
|
+
llm=<llm or timbr_llm_wrapper instance>,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Using environment variables for both timbr environment & llm (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY, LLM_TYPE, LLM_API_KEY, etc.)
|
|
97
|
+
execute_timbr_query_chain = ExecuteTimbrQueryChain()
|
|
98
|
+
|
|
88
99
|
return execute_timbr_query_chain.invoke({ "prompt": question }).get("rows", [])
|
|
89
100
|
```
|
|
90
101
|
"""
|
|
91
102
|
super().__init__(**kwargs)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
|
|
104
|
+
# Initialize LLM - use provided one or create with LlmWrapper from env variables
|
|
105
|
+
if llm is not None:
|
|
106
|
+
self._llm = llm
|
|
107
|
+
else:
|
|
108
|
+
try:
|
|
109
|
+
self._llm = LlmWrapper()
|
|
110
|
+
except Exception as e:
|
|
111
|
+
raise ValueError(f"Failed to initialize LLM from environment variables. Either provide an llm parameter or ensure LLM_TYPE and LLM_API_KEY environment variables are set. Error: {e}")
|
|
112
|
+
|
|
113
|
+
self._url = url if url is not None else config.url
|
|
114
|
+
self._token = token if token is not None else config.token
|
|
115
|
+
self._ontology = ontology if ontology is not None else config.ontology
|
|
116
|
+
|
|
117
|
+
# Validate required parameters
|
|
118
|
+
validate_timbr_connection_params(self._url, self._token)
|
|
119
|
+
|
|
96
120
|
self._schema = schema
|
|
97
121
|
self._concept = concept
|
|
98
122
|
self._concepts_list = parse_list(concepts_list)
|
|
@@ -181,7 +205,7 @@ class ExecuteTimbrQueryChain(Chain):
|
|
|
181
205
|
should_validate_sql=self._should_validate_sql,
|
|
182
206
|
retries=self._retries,
|
|
183
207
|
max_limit=self._max_limit,
|
|
184
|
-
note=self._note + err_txt,
|
|
208
|
+
note=(self._note or '') + err_txt,
|
|
185
209
|
db_is_case_sensitive=self._db_is_case_sensitive,
|
|
186
210
|
graph_depth=self._graph_depth,
|
|
187
211
|
debug=self._debug,
|
|
@@ -251,7 +275,7 @@ class ExecuteTimbrQueryChain(Chain):
|
|
|
251
275
|
generated.append(sql)
|
|
252
276
|
# If the SQL is valid but no rows are returned, create an error message to be sent to the LLM
|
|
253
277
|
if is_sql_valid:
|
|
254
|
-
error =
|
|
278
|
+
error = "No rows returned. Please revise the SQL considering if the question was ambiguous (e.g., which ID or name to use), try use alternative columns in the WHERE clause part in a way that could match the user's intent, without adding new columns with new filters."
|
|
255
279
|
error += "\nConsider that this queries already generated and returned 0 rows:\n" + "\n".join(generated)
|
|
256
280
|
is_sql_valid = False
|
|
257
281
|
else:
|
|
@@ -2,8 +2,10 @@ from typing import Optional, Dict, Any
|
|
|
2
2
|
from langchain.chains.base import Chain
|
|
3
3
|
from langchain.llms.base import LLM
|
|
4
4
|
|
|
5
|
-
from ..utils.general import to_boolean
|
|
5
|
+
from ..utils.general import to_boolean, validate_timbr_connection_params
|
|
6
6
|
from ..utils.timbr_llm_utils import answer_question
|
|
7
|
+
from ..llm_wrapper.llm_wrapper import LlmWrapper
|
|
8
|
+
from .. import config
|
|
7
9
|
|
|
8
10
|
class GenerateAnswerChain(Chain):
|
|
9
11
|
"""
|
|
@@ -14,9 +16,9 @@ class GenerateAnswerChain(Chain):
|
|
|
14
16
|
"""
|
|
15
17
|
def __init__(
|
|
16
18
|
self,
|
|
17
|
-
llm: LLM,
|
|
18
|
-
url: str,
|
|
19
|
-
token: str,
|
|
19
|
+
llm: Optional[LLM] = None,
|
|
20
|
+
url: Optional[str] = None,
|
|
21
|
+
token: Optional[str] = None,
|
|
20
22
|
verify_ssl: Optional[bool] = True,
|
|
21
23
|
is_jwt: Optional[bool] = False,
|
|
22
24
|
jwt_tenant_id: Optional[str] = None,
|
|
@@ -25,9 +27,9 @@ class GenerateAnswerChain(Chain):
|
|
|
25
27
|
**kwargs,
|
|
26
28
|
):
|
|
27
29
|
"""
|
|
28
|
-
:param llm: An LLM instance or a function that takes a prompt string and returns the LLM’s response
|
|
29
|
-
:param url: Timbr server url
|
|
30
|
-
:param token: Timbr password or token value
|
|
30
|
+
: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)
|
|
31
|
+
:param url: Timbr server url (optional, defaults to TIMBR_URL environment variable)
|
|
32
|
+
:param token: Timbr password or token value (optional, defaults to TIMBR_TOKEN environment variable)
|
|
31
33
|
:param verify_ssl: Whether to verify SSL certificates (default is True).
|
|
32
34
|
:param is_jwt: Whether to use JWT authentication (default is False).
|
|
33
35
|
:param jwt_tenant_id: JWT tenant ID for multi-tenant environments (required when is_jwt=True).
|
|
@@ -35,17 +37,41 @@ class GenerateAnswerChain(Chain):
|
|
|
35
37
|
|
|
36
38
|
## Example
|
|
37
39
|
```
|
|
40
|
+
# Using explicit parameters
|
|
41
|
+
generate_answer_chain = GenerateAnswerChain(
|
|
42
|
+
llm=<llm or timbr_llm_wrapper instance>,
|
|
43
|
+
url=<url>,
|
|
44
|
+
token=<token>
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Using environment variables for timbr environment (TIMBR_URL, TIMBR_TOKEN)
|
|
38
48
|
generate_answer_chain = GenerateAnswerChain(
|
|
39
49
|
llm=<llm or timbr_llm_wrapper instance>
|
|
40
50
|
)
|
|
51
|
+
|
|
52
|
+
# Using environment variables for both timbr environment & llm (TIMBR_URL, TIMBR_TOKEN, LLM_TYPE, LLM_API_KEY, etc.)
|
|
53
|
+
generate_answer_chain = GenerateAnswerChain()
|
|
41
54
|
|
|
42
55
|
return generate_answer_chain.invoke({ "prompt": prompt, "rows": rows }).get("answer", [])
|
|
43
56
|
```
|
|
44
57
|
"""
|
|
45
58
|
super().__init__(**kwargs)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
|
|
60
|
+
# Initialize LLM - use provided one or create with LlmWrapper from env variables
|
|
61
|
+
if llm is not None:
|
|
62
|
+
self._llm = llm
|
|
63
|
+
else:
|
|
64
|
+
try:
|
|
65
|
+
self._llm = LlmWrapper()
|
|
66
|
+
except Exception as e:
|
|
67
|
+
raise ValueError(f"Failed to initialize LLM from environment variables. Either provide an llm parameter or ensure LLM_TYPE and LLM_API_KEY environment variables are set. Error: {e}")
|
|
68
|
+
|
|
69
|
+
self._url = url if url is not None else config.url
|
|
70
|
+
self._token = token if token is not None else config.token
|
|
71
|
+
|
|
72
|
+
# Validate required parameters
|
|
73
|
+
validate_timbr_connection_params(self._url, self._token)
|
|
74
|
+
|
|
49
75
|
self._verify_ssl = to_boolean(verify_ssl)
|
|
50
76
|
self._is_jwt = to_boolean(is_jwt)
|
|
51
77
|
self._jwt_tenant_id = jwt_tenant_id
|
|
@@ -2,8 +2,10 @@ 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 ..utils.general import parse_list, to_boolean, to_integer
|
|
5
|
+
from ..utils.general import parse_list, to_boolean, to_integer, validate_timbr_connection_params
|
|
6
6
|
from ..utils.timbr_llm_utils import generate_sql
|
|
7
|
+
from ..llm_wrapper.llm_wrapper import LlmWrapper
|
|
8
|
+
from .. import config
|
|
7
9
|
|
|
8
10
|
class GenerateTimbrSqlChain(Chain):
|
|
9
11
|
"""
|
|
@@ -16,10 +18,10 @@ class GenerateTimbrSqlChain(Chain):
|
|
|
16
18
|
|
|
17
19
|
def __init__(
|
|
18
20
|
self,
|
|
19
|
-
llm: LLM,
|
|
20
|
-
url: str,
|
|
21
|
-
token: str,
|
|
22
|
-
ontology: str,
|
|
21
|
+
llm: Optional[LLM] = None,
|
|
22
|
+
url: Optional[str] = None,
|
|
23
|
+
token: Optional[str] = None,
|
|
24
|
+
ontology: Optional[str] = None,
|
|
23
25
|
schema: Optional[str] = 'dtimbr',
|
|
24
26
|
concept: Optional[str] = None,
|
|
25
27
|
concepts_list: Optional[Union[list[str], str]] = None,
|
|
@@ -41,10 +43,10 @@ class GenerateTimbrSqlChain(Chain):
|
|
|
41
43
|
**kwargs,
|
|
42
44
|
):
|
|
43
45
|
"""
|
|
44
|
-
:param llm: An LLM instance or a function that takes a prompt string and returns the LLM
|
|
45
|
-
:param url: Timbr server url
|
|
46
|
-
:param token: Timbr password or token value
|
|
47
|
-
:param ontology: The name of the ontology/knowledge graph
|
|
46
|
+
: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)
|
|
47
|
+
:param url: Timbr server url (optional, defaults to TIMBR_URL environment variable)
|
|
48
|
+
:param token: Timbr password or token value (optional, defaults to TIMBR_TOKEN environment variable)
|
|
49
|
+
:param ontology: The name of the ontology/knowledge graph (optional, defaults to ONTOLOGY/TIMBR_ONTOLOGY environment variable)
|
|
48
50
|
:param schema: The name of the schema to query
|
|
49
51
|
:param concept: The name of the concept to query
|
|
50
52
|
:param concepts_list: Optional specific concept options to query
|
|
@@ -66,6 +68,7 @@ class GenerateTimbrSqlChain(Chain):
|
|
|
66
68
|
|
|
67
69
|
## Example
|
|
68
70
|
```
|
|
71
|
+
# Using explicit parameters
|
|
69
72
|
generate_timbr_sql_chain = GenerateTimbrSqlChain(
|
|
70
73
|
url=<url>,
|
|
71
74
|
token=<token>,
|
|
@@ -79,14 +82,35 @@ class GenerateTimbrSqlChain(Chain):
|
|
|
79
82
|
note=<note>,
|
|
80
83
|
)
|
|
81
84
|
|
|
85
|
+
# Using environment variables for timbr environment (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY)
|
|
86
|
+
generate_timbr_sql_chain = GenerateTimbrSqlChain(
|
|
87
|
+
llm=<llm or timbr_llm_wrapper instance>,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Using environment variables for both timbr environment & llm (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY, LLM_TYPE, LLM_API_KEY, etc.)
|
|
91
|
+
generate_timbr_sql_chain = GenerateTimbrSqlChain()
|
|
92
|
+
|
|
82
93
|
return generate_timbr_sql_chain.invoke({ "prompt": question }).get("sql", [])
|
|
83
94
|
```
|
|
84
95
|
"""
|
|
85
96
|
super().__init__(**kwargs)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
|
|
98
|
+
# Initialize LLM - use provided one or create with LlmWrapper from env variables
|
|
99
|
+
if llm is not None:
|
|
100
|
+
self._llm = llm
|
|
101
|
+
else:
|
|
102
|
+
try:
|
|
103
|
+
self._llm = LlmWrapper()
|
|
104
|
+
except Exception as e:
|
|
105
|
+
raise ValueError(f"Failed to initialize LLM from environment variables. Either provide an llm parameter or ensure LLM_TYPE and LLM_API_KEY environment variables are set. Error: {e}")
|
|
106
|
+
|
|
107
|
+
self._url = url if url is not None else config.url
|
|
108
|
+
self._token = token if token is not None else config.token
|
|
109
|
+
self._ontology = ontology if ontology is not None else config.ontology
|
|
110
|
+
|
|
111
|
+
# Validate required parameters
|
|
112
|
+
validate_timbr_connection_params(self._url, self._token)
|
|
113
|
+
|
|
90
114
|
self._schema = schema
|
|
91
115
|
self._concept = concept
|
|
92
116
|
self._concepts_list = parse_list(concepts_list)
|
|
@@ -2,8 +2,10 @@ 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 ..utils.general import parse_list, to_boolean, to_integer
|
|
5
|
+
from ..utils.general import parse_list, to_boolean, to_integer, validate_timbr_connection_params
|
|
6
6
|
from ..utils.timbr_llm_utils import determine_concept
|
|
7
|
+
from ..llm_wrapper.llm_wrapper import LlmWrapper
|
|
8
|
+
from .. import config
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class IdentifyTimbrConceptChain(Chain):
|
|
@@ -17,10 +19,10 @@ class IdentifyTimbrConceptChain(Chain):
|
|
|
17
19
|
|
|
18
20
|
def __init__(
|
|
19
21
|
self,
|
|
20
|
-
llm: LLM,
|
|
21
|
-
url: str,
|
|
22
|
-
token: str,
|
|
23
|
-
ontology: str,
|
|
22
|
+
llm: Optional[LLM] = None,
|
|
23
|
+
url: Optional[str] = None,
|
|
24
|
+
token: Optional[str] = None,
|
|
25
|
+
ontology: Optional[str] = None,
|
|
24
26
|
concepts_list: Optional[Union[list[str], str]] = None,
|
|
25
27
|
views_list: Optional[Union[list[str], str]] = None,
|
|
26
28
|
include_logic_concepts: Optional[bool] = False,
|
|
@@ -36,10 +38,10 @@ class IdentifyTimbrConceptChain(Chain):
|
|
|
36
38
|
**kwargs,
|
|
37
39
|
):
|
|
38
40
|
"""
|
|
39
|
-
:param llm: An LLM instance or a function that takes a prompt string and returns the LLM
|
|
40
|
-
:param url: Timbr server url
|
|
41
|
-
:param token: Timbr password or token value
|
|
42
|
-
:param ontology: The name of the ontology/knowledge graph
|
|
41
|
+
: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)
|
|
42
|
+
:param url: Timbr server url (optional, defaults to TIMBR_URL environment variable)
|
|
43
|
+
:param token: Timbr password or token value (optional, defaults to TIMBR_TOKEN environment variable)
|
|
44
|
+
:param ontology: The name of the ontology/knowledge graph (optional, defaults to ONTOLOGY/TIMBR_ONTOLOGY environment variable)
|
|
43
45
|
:param concepts_list: Optional specific concept options to query
|
|
44
46
|
:param views_list: Optional specific view options to query
|
|
45
47
|
:param include_logic_concepts: Optional boolean to include logic concepts (concepts without unique properties which only inherits from an upper level concept with filter logic) in the query.
|
|
@@ -55,10 +57,11 @@ class IdentifyTimbrConceptChain(Chain):
|
|
|
55
57
|
|
|
56
58
|
## Example
|
|
57
59
|
```
|
|
60
|
+
# Using explicit parameters
|
|
58
61
|
identify_timbr_concept_chain = IdentifyTimbrConceptChain(
|
|
62
|
+
llm=<llm or timbr_llm_wrapper instance>,
|
|
59
63
|
url=<url>,
|
|
60
64
|
token=<token>,
|
|
61
|
-
llm=<llm or timbr_llm_wrapper instance>,
|
|
62
65
|
ontology=<ontology_name>,
|
|
63
66
|
concepts_list=<concepts>,
|
|
64
67
|
views_list=<views>,
|
|
@@ -66,14 +69,35 @@ class IdentifyTimbrConceptChain(Chain):
|
|
|
66
69
|
note=<note>,
|
|
67
70
|
)
|
|
68
71
|
|
|
72
|
+
# Using environment variables for timbr environment (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY)
|
|
73
|
+
identify_timbr_concept_chain = IdentifyTimbrConceptChain(
|
|
74
|
+
llm=<llm or timbr_llm_wrapper instance>,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Using environment variables for both timbr environment & llm (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY, LLM_TYPE, LLM_API_KEY, etc.)
|
|
78
|
+
identify_timbr_concept_chain = IdentifyTimbrConceptChain()
|
|
79
|
+
|
|
69
80
|
return identify_timbr_concept_chain.invoke({ "prompt": question }).get("concept", None)
|
|
70
81
|
```
|
|
71
82
|
"""
|
|
72
83
|
super().__init__(**kwargs)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
|
|
85
|
+
# Initialize LLM - use provided one or create with LlmWrapper from env variables
|
|
86
|
+
if llm is not None:
|
|
87
|
+
self._llm = llm
|
|
88
|
+
else:
|
|
89
|
+
try:
|
|
90
|
+
self._llm = LlmWrapper()
|
|
91
|
+
except Exception as e:
|
|
92
|
+
raise ValueError(f"Failed to initialize LLM from environment variables. Either provide an llm parameter or ensure LLM_TYPE and LLM_API_KEY environment variables are set. Error: {e}")
|
|
93
|
+
|
|
94
|
+
self._url = url if url is not None else config.url
|
|
95
|
+
self._token = token if token is not None else config.token
|
|
96
|
+
self._ontology = ontology if ontology is not None else config.ontology
|
|
97
|
+
|
|
98
|
+
# Validate required parameters
|
|
99
|
+
validate_timbr_connection_params(self._url, self._token)
|
|
100
|
+
|
|
77
101
|
self._concepts_list = parse_list(concepts_list)
|
|
78
102
|
self._views_list = parse_list(views_list)
|
|
79
103
|
self._include_logic_concepts = to_boolean(include_logic_concepts)
|
{langchain_timbr-1.5.3 → langchain_timbr-1.5.5}/src/langchain_timbr/langchain/timbr_sql_agent.py
RENAMED
|
@@ -10,10 +10,10 @@ from .generate_answer_chain import GenerateAnswerChain
|
|
|
10
10
|
class TimbrSqlAgent(BaseSingleActionAgent):
|
|
11
11
|
def __init__(
|
|
12
12
|
self,
|
|
13
|
-
llm: LLM,
|
|
14
|
-
url: str,
|
|
15
|
-
token: str,
|
|
16
|
-
ontology: str,
|
|
13
|
+
llm: Optional[LLM] = None,
|
|
14
|
+
url: Optional[str] = None,
|
|
15
|
+
token: Optional[str] = None,
|
|
16
|
+
ontology: Optional[str] = None,
|
|
17
17
|
schema: Optional[str] = 'dtimbr',
|
|
18
18
|
concept: Optional[str] = None,
|
|
19
19
|
concepts_list: Optional[Union[list[str], str]] = None,
|
|
@@ -37,10 +37,10 @@ class TimbrSqlAgent(BaseSingleActionAgent):
|
|
|
37
37
|
debug: Optional[bool] = False
|
|
38
38
|
):
|
|
39
39
|
"""
|
|
40
|
-
:param llm:
|
|
41
|
-
:param url: Timbr server URL
|
|
42
|
-
:param token: Timbr authentication token
|
|
43
|
-
:param ontology: Name of the ontology/knowledge graph
|
|
40
|
+
: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)
|
|
41
|
+
:param url: Timbr server URL (optional, defaults to TIMBR_URL environment variable)
|
|
42
|
+
:param token: Timbr authentication token (optional, defaults to TIMBR_TOKEN environment variable)
|
|
43
|
+
:param ontology: Name of the ontology/knowledge graph (optional, defaults to ONTOLOGY/TIMBR_ONTOLOGY environment variable)
|
|
44
44
|
:param schema: Optional specific schema name to query
|
|
45
45
|
:param concept: Optional specific concept name to query
|
|
46
46
|
:param concepts_list: Optional specific concept options to query
|
|
@@ -64,6 +64,7 @@ class TimbrSqlAgent(BaseSingleActionAgent):
|
|
|
64
64
|
|
|
65
65
|
## Example
|
|
66
66
|
```
|
|
67
|
+
# Using explicit parameters
|
|
67
68
|
agent = TimbrSqlAgent(
|
|
68
69
|
llm=<llm>,
|
|
69
70
|
url=<url>,
|
|
@@ -77,6 +78,14 @@ class TimbrSqlAgent(BaseSingleActionAgent):
|
|
|
77
78
|
retries=<retries>,
|
|
78
79
|
note=<note>,
|
|
79
80
|
)
|
|
81
|
+
|
|
82
|
+
# Using environment variables for timbr environment (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY)
|
|
83
|
+
agent = TimbrSqlAgent(
|
|
84
|
+
llm=<llm>,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Using environment variables for both timbr environment & llm (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY, LLM_TYPE, LLM_API_KEY, etc.)
|
|
88
|
+
agent = TimbrSqlAgent()
|
|
80
89
|
```
|
|
81
90
|
"""
|
|
82
91
|
super().__init__()
|
|
@@ -298,10 +307,10 @@ class TimbrSqlAgent(BaseSingleActionAgent):
|
|
|
298
307
|
|
|
299
308
|
|
|
300
309
|
def create_timbr_sql_agent(
|
|
301
|
-
llm: LLM,
|
|
302
|
-
url: str,
|
|
303
|
-
token: str,
|
|
304
|
-
ontology: str,
|
|
310
|
+
llm: Optional[LLM] = None,
|
|
311
|
+
url: Optional[str] = None,
|
|
312
|
+
token: Optional[str] = None,
|
|
313
|
+
ontology: Optional[str] = None,
|
|
305
314
|
schema: Optional[str] = 'dtimbr',
|
|
306
315
|
concept: Optional[str] = None,
|
|
307
316
|
concepts_list: Optional[Union[list[str], str]] = None,
|
|
@@ -327,10 +336,10 @@ def create_timbr_sql_agent(
|
|
|
327
336
|
"""
|
|
328
337
|
Create and configure a Timbr agent with its executor.
|
|
329
338
|
|
|
330
|
-
:param llm:
|
|
331
|
-
:param url: Timbr server URL
|
|
332
|
-
:param token: Timbr authentication token
|
|
333
|
-
:param ontology: Name of the ontology/knowledge graph
|
|
339
|
+
: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)
|
|
340
|
+
:param url: Timbr server URL (optional, defaults to TIMBR_URL environment variable)
|
|
341
|
+
:param token: Timbr authentication token (optional, defaults to TIMBR_TOKEN environment variable)
|
|
342
|
+
:param ontology: Name of the ontology/knowledge graph (optional, defaults to ONTOLOGY/TIMBR_ONTOLOGY environment variable)
|
|
334
343
|
:param schema: Optional specific schema name to query
|
|
335
344
|
:param concept: Optional specific concept name to query
|
|
336
345
|
:param concepts_list: Optional specific concept options to query
|
|
@@ -357,6 +366,7 @@ def create_timbr_sql_agent(
|
|
|
357
366
|
|
|
358
367
|
## Example
|
|
359
368
|
```
|
|
369
|
+
# Using explicit parameters
|
|
360
370
|
agent = create_timbr_sql_agent(
|
|
361
371
|
llm=<llm>,
|
|
362
372
|
url=<url>,
|
|
@@ -372,7 +382,15 @@ def create_timbr_sql_agent(
|
|
|
372
382
|
retries=<retries>,
|
|
373
383
|
note=<note>,
|
|
374
384
|
)
|
|
375
|
-
|
|
385
|
+
|
|
386
|
+
# Using environment variables for timbr environment (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY)
|
|
387
|
+
agent = create_timbr_sql_agent(
|
|
388
|
+
llm=<llm>,
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
# Using environment variables for both timbr environment & llm (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY, LLM_TYPE, LLM_API_KEY, etc.)
|
|
392
|
+
agent = create_timbr_sql_agent()
|
|
393
|
+
|
|
376
394
|
result = agent.invoke("What are the total sales for last month?")
|
|
377
395
|
|
|
378
396
|
# Access the components of the result:
|
|
@@ -2,9 +2,11 @@ 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 ..utils.general import parse_list, to_integer, to_boolean
|
|
5
|
+
from ..utils.general import parse_list, to_integer, to_boolean, validate_timbr_connection_params
|
|
6
6
|
from ..utils.timbr_llm_utils import generate_sql
|
|
7
7
|
from ..utils.timbr_utils import validate_sql
|
|
8
|
+
from ..llm_wrapper.llm_wrapper import LlmWrapper
|
|
9
|
+
from .. import config
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class ValidateTimbrSqlChain(Chain):
|
|
@@ -18,10 +20,10 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
18
20
|
|
|
19
21
|
def __init__(
|
|
20
22
|
self,
|
|
21
|
-
llm: LLM,
|
|
22
|
-
url: str,
|
|
23
|
-
token: str,
|
|
24
|
-
ontology: str,
|
|
23
|
+
llm: Optional[LLM] = None,
|
|
24
|
+
url: Optional[str] = None,
|
|
25
|
+
token: Optional[str] = None,
|
|
26
|
+
ontology: Optional[str] = None,
|
|
25
27
|
schema: Optional[str] = 'dtimbr',
|
|
26
28
|
concept: Optional[str] = None,
|
|
27
29
|
retries: Optional[int] = 3,
|
|
@@ -42,10 +44,10 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
42
44
|
**kwargs,
|
|
43
45
|
):
|
|
44
46
|
"""
|
|
45
|
-
:param llm: An LLM instance or a function that takes a prompt string and returns the LLM
|
|
46
|
-
:param url: Timbr server url
|
|
47
|
-
:param token: Timbr password or token value
|
|
48
|
-
:param ontology: The name of the ontology/knowledge graph
|
|
47
|
+
: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)
|
|
48
|
+
:param url: Timbr server url (optional, defaults to TIMBR_URL environment variable)
|
|
49
|
+
:param token: Timbr password or token value (optional, defaults to TIMBR_TOKEN environment variable)
|
|
50
|
+
:param ontology: The name of the ontology/knowledge graph (optional, defaults to ONTOLOGY/TIMBR_ONTOLOGY environment variable)
|
|
49
51
|
:param schema: The name of the schema to query
|
|
50
52
|
:param concept: The name of the concept to query
|
|
51
53
|
:param retries: The maximum number of retries to attempt
|
|
@@ -66,6 +68,7 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
66
68
|
|
|
67
69
|
## Example
|
|
68
70
|
```
|
|
71
|
+
# Using explicit parameters
|
|
69
72
|
validate_timbr_sql_chain = ValidateTimbrSqlChain(
|
|
70
73
|
url=<url>,
|
|
71
74
|
token=<token>,
|
|
@@ -80,14 +83,35 @@ class ValidateTimbrSqlChain(Chain):
|
|
|
80
83
|
note=<note>,
|
|
81
84
|
)
|
|
82
85
|
|
|
86
|
+
# Using environment variables for timbr environment (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY)
|
|
87
|
+
validate_timbr_sql_chain = ValidateTimbrSqlChain(
|
|
88
|
+
llm=<llm or timbr_llm_wrapper instance>,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Using environment variables for both timbr environment & llm (TIMBR_URL, TIMBR_TOKEN, TIMBR_ONTOLOGY, LLM_TYPE, LLM_API_KEY, etc.)
|
|
92
|
+
validate_timbr_sql_chain = ValidateTimbrSqlChain()
|
|
93
|
+
|
|
83
94
|
return validate_timbr_sql_chain.invoke({ "prompt": question, "sql": <latest_query_to_validate> }).get("sql", [])
|
|
84
95
|
```
|
|
85
96
|
"""
|
|
86
97
|
super().__init__(**kwargs)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
|
|
99
|
+
# Initialize LLM - use provided one or create with LlmWrapper from env variables
|
|
100
|
+
if llm is not None:
|
|
101
|
+
self._llm = llm
|
|
102
|
+
else:
|
|
103
|
+
try:
|
|
104
|
+
self._llm = LlmWrapper()
|
|
105
|
+
except Exception as e:
|
|
106
|
+
raise ValueError(f"Failed to initialize LLM from environment variables. Either provide an llm parameter or ensure LLM_TYPE and LLM_API_KEY environment variables are set. Error: {e}")
|
|
107
|
+
|
|
108
|
+
self._url = url if url is not None else config.url
|
|
109
|
+
self._token = token if token is not None else config.token
|
|
110
|
+
self._ontology = ontology if ontology is not None else config.ontology
|
|
111
|
+
|
|
112
|
+
# Validate required parameters
|
|
113
|
+
validate_timbr_connection_params(self._url, self._token)
|
|
114
|
+
|
|
91
115
|
self._schema = schema
|
|
92
116
|
self._concept = concept
|
|
93
117
|
self._retries = retries
|
|
@@ -13,7 +13,7 @@ class ExecuteSemanticQueryNode:
|
|
|
13
13
|
"""
|
|
14
14
|
def __init__(
|
|
15
15
|
self,
|
|
16
|
-
llm: LLM,
|
|
16
|
+
llm: Optional[LLM] = None,
|
|
17
17
|
url: Optional[str] = None,
|
|
18
18
|
token: Optional[str] = None,
|
|
19
19
|
ontology: Optional[str] = None,
|
|
@@ -40,10 +40,10 @@ class ExecuteSemanticQueryNode:
|
|
|
40
40
|
**kwargs,
|
|
41
41
|
):
|
|
42
42
|
"""
|
|
43
|
-
:param llm: An LLM instance or a function that takes a prompt string and returns the LLM
|
|
44
|
-
:param url: Timbr server url
|
|
45
|
-
:param token: Timbr password or token value
|
|
46
|
-
:param ontology: The name of the ontology/knowledge graph
|
|
43
|
+
: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)
|
|
44
|
+
:param url: Timbr server url (optional, defaults to TIMBR_URL environment variable)
|
|
45
|
+
:param token: Timbr password or token value (optional, defaults to TIMBR_TOKEN environment variable)
|
|
46
|
+
:param ontology: The name of the ontology/knowledge graph (optional, defaults to ONTOLOGY/TIMBR_ONTOLOGY environment variable)
|
|
47
47
|
:param schema: The name of the schema to query
|
|
48
48
|
:param concept: The name of the concept to query
|
|
49
49
|
:param concepts_list: Optional specific concept options to query
|
|
@@ -97,7 +97,7 @@ class ExecuteSemanticQueryNode:
|
|
|
97
97
|
def run(self, state: StateGraph) -> dict:
|
|
98
98
|
try:
|
|
99
99
|
prompt = state.messages[-1].content if state.messages[-1] else None
|
|
100
|
-
except:
|
|
100
|
+
except Exception:
|
|
101
101
|
prompt = state.get('prompt', None)
|
|
102
102
|
|
|
103
103
|
return self.chain.invoke({ "prompt": prompt })
|