langchain-prolog 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Antonio Pisani.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.3
2
+ Name: langchain-prolog
3
+ Version: 0.1.0
4
+ Summary: An integration package connecting Prolog and LangChain
5
+ License: MIT
6
+ Keywords: langchain,prolog,swi-prolog,llm,agent
7
+ Author: Antonio Pisani
8
+ Requires-Python: >=3.10,<4.0
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Prolog
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Dist: janus-swi (>=1.5.0,<2.0.0)
21
+ Requires-Dist: langchain-core (>=0.3.0,<0.4.0)
22
+ Requires-Dist: pydantic (>=2.0.0,<3.0.0)
23
+ Project-URL: Repository, https://github.com/apisani1/langchain-prolog
24
+ Project-URL: Release Notes, https://github.com/langchain-ai/langchain/releases?q=tag%3A%22prolog%3D%3D0%22&expanded=true
25
+ Project-URL: Source Code, https://github.com/langchain-ai/langchain/tree/master/libs/partners/prolog
26
+ Description-Content-Type: text/markdown
27
+
28
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
29
+ [![PyPI version](https://badge.fury.io/py/langchain-prolog.svg)](https://badge.fury.io/py/langchain-prolog)
30
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/release/python-390/)
31
+ [![Documentation Status](https://readthedocs.org/projects/langchain-prolog/badge/?version=latest)](https://langchain-prolog.readthedocs.io/en/latest/?badge=latest)
32
+ ![Version](https://img.shields.io/badge/version-0.1.0-blue)
33
+
34
+ # LangChain-Prolog
35
+
36
+ A Python library that integrates SWI-Prolog with LangChain, allowing seamless
37
+ blending of Prolog's logic programming capabilities into LangChain applications.
38
+
39
+
40
+ ## Features
41
+
42
+ - Seamless integration between LangChain and SWI-Prolog
43
+ - Use Prolog queries as LangChain runnables and tools
44
+ - Invoke Prolog predicates from LangChain LLM models, chains and agents
45
+ - Support for both synchronous and asynchronous operations
46
+ - Comprehensive error handling and logging
47
+ - Cross-platform support (macOS, Linux, Windows)
48
+
49
+ ## Installation
50
+
51
+ #### Prerequisites
52
+
53
+ - Python 3.10 or later
54
+ - SWI-Prolog installed on your system
55
+ - The following python libraries installed:
56
+ - langchain 0.3.0 or later
57
+ - janus-swi 1.5.0 or later
58
+ - pydantic 0.2.0 or later
59
+
60
+ langchain-prolog can be installed using pip:
61
+ ```bash
62
+ pip install langchain-prolog
63
+ ```
64
+
65
+ ## Runnable Interface
66
+
67
+ The PrologRunnable class allows the generation of langchain runnables that use Prolog rules to generate answers.
68
+
69
+ Let's assume that we have the following set of Prolog rules in the file family.pl:
70
+
71
+ ```prolog
72
+ parent(john, bianca, mary).
73
+ parent(john, bianca, michael).
74
+ parent(peter, patricia, jennifer).
75
+ partner(X, Y) :- parent(X, Y, _).
76
+ ```
77
+
78
+ There are three diferent ways to use a PrologRunnable to query Prolog:
79
+
80
+ #### 1) Using a Prolog runnable with a full predicate string
81
+
82
+ ```python
83
+ from langchain_prolog import PrologConfig, PrologRunnable
84
+
85
+ config = PrologConfig(rules_file="family.pl")
86
+ prolog = PrologRunnable(prolog_config=config)
87
+ result = prolog.invoke("partner(X, Y)")
88
+ print(result)
89
+ ```
90
+ We can pass a string representing a single predicate query. The invoke method will return `True`, `False` or a list of dictionaries with all the solutions to the query:
91
+ ```python
92
+ [{'X': 'john', 'Y': 'bianca'},
93
+ {'X': 'john', 'Y': 'bianca'},
94
+ {'X': 'peter', 'Y': 'patricia'}]
95
+ ```
96
+
97
+ #### 2) Using a Prolog runnable with a default predicate
98
+
99
+ ```python
100
+ from langchain_prolog import PrologConfig, PrologRunnable
101
+
102
+ config = PrologConfig(rules_file="family.pl", default_predicate="partner")
103
+ prolog = PrologRunnable(prolog_config=config)
104
+ result = prolog.invoke("peter, X")
105
+ print(result)
106
+ ```
107
+ When using a default predicate, only the arguments for the predicate are passed to the Prolog runable, as a single string. Following Prolog conventions, uppercase identifiers are variables and lowercase identifiers are values (atoms or strings):
108
+
109
+ ```python
110
+ [{'X': 'patricia'}]
111
+ ```
112
+
113
+ ### 3) Using a Prolog runnable with a dictionary and schema validation
114
+
115
+ ```python
116
+ from langchain_prolog import PrologConfig, PrologRunnable
117
+
118
+ schema = PrologRunnable.create_schema("partner", ["man", "woman"])
119
+ config = PrologConfig(rules_file="family.pl", query_schema=schema)
120
+ prolog = PrologRunnable(prolog_config=config)
121
+ result = prolog.invoke({"man": None, "woman": "bianca"})
122
+ print(result)
123
+ ```
124
+ If a schema is defined, we can pass a dictionary using the names of the parameters in the schema as the keys in the dictionary. The values can represent Prolog variables (uppercase first letter) or strings (lower case first letter). A `None` value is interpreted as a variable and replaced with the key capitalized:
125
+ ```python
126
+ [{'Man': 'john'}, {'Man': 'john'}]
127
+ ```
128
+
129
+ You can also pass a Pydantic object generated with the schema to the invoke method:
130
+ ```python
131
+ args = schema(man='M', woman='W')
132
+ result = prolog.invoke(args)
133
+ print(result)
134
+ ```
135
+ Uppercase values are treated as variables:
136
+ ```python
137
+ [{'M': 'john', 'W': 'bianca'},
138
+ {'M': 'john', 'W': 'bianca'},
139
+ {'M': 'peter', 'W': 'patricia'}]
140
+ ```
141
+
142
+ ## Tool Interface
143
+
144
+ The PrologTool class allows the generation of langchain tools that use Prolog rules to generate answers.
145
+
146
+ See the Runnable Interface section for the conventions on hown to pass variables and values to the Prolog interpreter.
147
+
148
+ Let's assume that we have the following set of Prolog rules in the file family.pl:
149
+
150
+ ```prolog
151
+ parent(john, bianca, mary).
152
+ parent(john, bianca, michael).
153
+ parent(peter, patricia, jennifer).
154
+ partner(X, Y) :- parent(X, Y, _).
155
+ ```
156
+
157
+ There are two ways to use a Prolog tool:
158
+
159
+ ### 1) Using a Prolog tool with an LLM and function calling
160
+
161
+ First create the Prolog tool:
162
+ ```python
163
+ from langchain_prolog import PrologConfig, PrologTool
164
+
165
+ schema = PrologRunnable.create_schema('parent', ['men', 'women', 'child'])
166
+ config = PrologConfig(
167
+ rules_file="family.pl",
168
+ query_schema=schema,
169
+ )
170
+ prolog_tool = PrologTool(
171
+ prolog_config=config,
172
+ name="family_query",
173
+ description="""
174
+ Query family relationships using Prolog.
175
+ parent(X, Y, Z) implies only that Z is a child of X and Y.
176
+ Input can be a query string like 'parent(john, X, Y)'
177
+ or 'john, X, Y'"
178
+ You have to specify 3 parameters: men, woman, child.
179
+ Do not use quotes.
180
+ """
181
+ )
182
+ ```
183
+
184
+ Then bind it to the LLM model and query the model:
185
+ ```python
186
+ from langchain_openai import ChatOpenAI
187
+ from langchain_core.messages import HumanMessage
188
+
189
+ llm = ChatOpenAI(model="gpt-4o-mini")
190
+ llm_with_tools = llm.bind_tools([prolog_tool])
191
+ messages = [HumanMessage("Who are John's children?")]
192
+ response = llm_with_tools.invoke(messages)
193
+ messages.append(response)
194
+ print(response.tool_calls[0])
195
+ ```
196
+ The LLM will respond with a tool call request:
197
+ ```python
198
+ {'name': 'family_query',
199
+ 'args': {'men': 'john', 'women': None, 'child': None},
200
+ 'id': 'call_V6NUsJwhF41G9G7q6TBmghR0',
201
+ 'type': 'tool_call'}
202
+ ```
203
+ The tool takes this request and queries the Prolog database:
204
+ ```python
205
+ tool_msg = prolog_tool.invoke(response.tool_calls[0])
206
+ messages.append(tool_msg)
207
+ print(tool_msg)
208
+ ```
209
+ The tool returns a list with all the solutions for the query:
210
+ ```python
211
+ content='[{"Women": "bianca", "Child": "mary"}, {"Women": "bianca", "Child": "michael"}]'
212
+ name='family_query'
213
+ tool_call_id='call_V6NUsJwhF41G9G7q6TBmghR0'
214
+ ```
215
+ That we then pass to the LLM:
216
+ ```python
217
+ answer = llm_with_tools.invoke(messages)
218
+ print(answer.content)
219
+ ```
220
+ And the LLM answers the original query using the tool response:
221
+ ```python
222
+ John has two children: Mary and Michael. Their mother is Bianca.
223
+ ```
224
+
225
+ ### 2) Using a Prolog tool with an agent
226
+
227
+ First create the Prolog tool:
228
+ ```python
229
+ from langchain_prolog import PrologConfig, PrologTool
230
+
231
+ schema = PrologRunnable.create_schema('parent', ['men', 'women', 'child'])
232
+ config = PrologConfig(
233
+ rules_file="family.pl",
234
+ query_schema=schema,
235
+ )
236
+ prolog_tool = PrologTool(
237
+ prolog_config=config,
238
+ name="family_query",
239
+ description="""
240
+ Query family relationships using Prolog.
241
+ parent(X, Y, Z) implies only that Z is a child of X and Y.
242
+ Input can be a query string like 'parent(john, X, Y)'
243
+ or 'john, X, Y'"
244
+ You have to specify 3 parameters: men, woman, child.
245
+ Do not use quotes.
246
+ """
247
+ )
248
+ ```
249
+ Then pass it to the agent's constructor:
250
+ ```python
251
+ from langchain_core.prompts import ChatPromptTemplate
252
+ from langchain.agents import create_tool_calling_agent, AgentExecutor
253
+
254
+ llm = ChatOpenAI(model="gpt-4o-mini")
255
+ prompt = ChatPromptTemplate.from_messages(
256
+ [
257
+ ("system", "You are a helpful assistant"),
258
+ ("human", "{input}"),
259
+ ("placeholder", "{agent_scratchpad}"),
260
+ ]
261
+ )
262
+ tools = [prolog_tool]
263
+ agent = create_tool_calling_agent(llm, tools, prompt)
264
+ agent_executor = AgentExecutor(agent=agent, tools=tools)
265
+ ```
266
+ The agent takes the query and use the Prolog tool if needed:
267
+ ```python
268
+ answer = agent_executor.invoke({"input": "Who are John's children?"})
269
+ print(answer)
270
+ ```
271
+ Then the agent recieves the tool response as part of the {agent_scratchpad} placeholder and generates the answer:
272
+ ```python
273
+ {'input': "Who are John's children?", 'output': 'John has two children: Mary and Michael, with Bianca as their mother.'}
274
+
@@ -0,0 +1,246 @@
1
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
2
+ [![PyPI version](https://badge.fury.io/py/langchain-prolog.svg)](https://badge.fury.io/py/langchain-prolog)
3
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/release/python-390/)
4
+ [![Documentation Status](https://readthedocs.org/projects/langchain-prolog/badge/?version=latest)](https://langchain-prolog.readthedocs.io/en/latest/?badge=latest)
5
+ ![Version](https://img.shields.io/badge/version-0.1.0-blue)
6
+
7
+ # LangChain-Prolog
8
+
9
+ A Python library that integrates SWI-Prolog with LangChain, allowing seamless
10
+ blending of Prolog's logic programming capabilities into LangChain applications.
11
+
12
+
13
+ ## Features
14
+
15
+ - Seamless integration between LangChain and SWI-Prolog
16
+ - Use Prolog queries as LangChain runnables and tools
17
+ - Invoke Prolog predicates from LangChain LLM models, chains and agents
18
+ - Support for both synchronous and asynchronous operations
19
+ - Comprehensive error handling and logging
20
+ - Cross-platform support (macOS, Linux, Windows)
21
+
22
+ ## Installation
23
+
24
+ #### Prerequisites
25
+
26
+ - Python 3.10 or later
27
+ - SWI-Prolog installed on your system
28
+ - The following python libraries installed:
29
+ - langchain 0.3.0 or later
30
+ - janus-swi 1.5.0 or later
31
+ - pydantic 0.2.0 or later
32
+
33
+ langchain-prolog can be installed using pip:
34
+ ```bash
35
+ pip install langchain-prolog
36
+ ```
37
+
38
+ ## Runnable Interface
39
+
40
+ The PrologRunnable class allows the generation of langchain runnables that use Prolog rules to generate answers.
41
+
42
+ Let's assume that we have the following set of Prolog rules in the file family.pl:
43
+
44
+ ```prolog
45
+ parent(john, bianca, mary).
46
+ parent(john, bianca, michael).
47
+ parent(peter, patricia, jennifer).
48
+ partner(X, Y) :- parent(X, Y, _).
49
+ ```
50
+
51
+ There are three diferent ways to use a PrologRunnable to query Prolog:
52
+
53
+ #### 1) Using a Prolog runnable with a full predicate string
54
+
55
+ ```python
56
+ from langchain_prolog import PrologConfig, PrologRunnable
57
+
58
+ config = PrologConfig(rules_file="family.pl")
59
+ prolog = PrologRunnable(prolog_config=config)
60
+ result = prolog.invoke("partner(X, Y)")
61
+ print(result)
62
+ ```
63
+ We can pass a string representing a single predicate query. The invoke method will return `True`, `False` or a list of dictionaries with all the solutions to the query:
64
+ ```python
65
+ [{'X': 'john', 'Y': 'bianca'},
66
+ {'X': 'john', 'Y': 'bianca'},
67
+ {'X': 'peter', 'Y': 'patricia'}]
68
+ ```
69
+
70
+ #### 2) Using a Prolog runnable with a default predicate
71
+
72
+ ```python
73
+ from langchain_prolog import PrologConfig, PrologRunnable
74
+
75
+ config = PrologConfig(rules_file="family.pl", default_predicate="partner")
76
+ prolog = PrologRunnable(prolog_config=config)
77
+ result = prolog.invoke("peter, X")
78
+ print(result)
79
+ ```
80
+ When using a default predicate, only the arguments for the predicate are passed to the Prolog runable, as a single string. Following Prolog conventions, uppercase identifiers are variables and lowercase identifiers are values (atoms or strings):
81
+
82
+ ```python
83
+ [{'X': 'patricia'}]
84
+ ```
85
+
86
+ ### 3) Using a Prolog runnable with a dictionary and schema validation
87
+
88
+ ```python
89
+ from langchain_prolog import PrologConfig, PrologRunnable
90
+
91
+ schema = PrologRunnable.create_schema("partner", ["man", "woman"])
92
+ config = PrologConfig(rules_file="family.pl", query_schema=schema)
93
+ prolog = PrologRunnable(prolog_config=config)
94
+ result = prolog.invoke({"man": None, "woman": "bianca"})
95
+ print(result)
96
+ ```
97
+ If a schema is defined, we can pass a dictionary using the names of the parameters in the schema as the keys in the dictionary. The values can represent Prolog variables (uppercase first letter) or strings (lower case first letter). A `None` value is interpreted as a variable and replaced with the key capitalized:
98
+ ```python
99
+ [{'Man': 'john'}, {'Man': 'john'}]
100
+ ```
101
+
102
+ You can also pass a Pydantic object generated with the schema to the invoke method:
103
+ ```python
104
+ args = schema(man='M', woman='W')
105
+ result = prolog.invoke(args)
106
+ print(result)
107
+ ```
108
+ Uppercase values are treated as variables:
109
+ ```python
110
+ [{'M': 'john', 'W': 'bianca'},
111
+ {'M': 'john', 'W': 'bianca'},
112
+ {'M': 'peter', 'W': 'patricia'}]
113
+ ```
114
+
115
+ ## Tool Interface
116
+
117
+ The PrologTool class allows the generation of langchain tools that use Prolog rules to generate answers.
118
+
119
+ See the Runnable Interface section for the conventions on hown to pass variables and values to the Prolog interpreter.
120
+
121
+ Let's assume that we have the following set of Prolog rules in the file family.pl:
122
+
123
+ ```prolog
124
+ parent(john, bianca, mary).
125
+ parent(john, bianca, michael).
126
+ parent(peter, patricia, jennifer).
127
+ partner(X, Y) :- parent(X, Y, _).
128
+ ```
129
+
130
+ There are two ways to use a Prolog tool:
131
+
132
+ ### 1) Using a Prolog tool with an LLM and function calling
133
+
134
+ First create the Prolog tool:
135
+ ```python
136
+ from langchain_prolog import PrologConfig, PrologTool
137
+
138
+ schema = PrologRunnable.create_schema('parent', ['men', 'women', 'child'])
139
+ config = PrologConfig(
140
+ rules_file="family.pl",
141
+ query_schema=schema,
142
+ )
143
+ prolog_tool = PrologTool(
144
+ prolog_config=config,
145
+ name="family_query",
146
+ description="""
147
+ Query family relationships using Prolog.
148
+ parent(X, Y, Z) implies only that Z is a child of X and Y.
149
+ Input can be a query string like 'parent(john, X, Y)'
150
+ or 'john, X, Y'"
151
+ You have to specify 3 parameters: men, woman, child.
152
+ Do not use quotes.
153
+ """
154
+ )
155
+ ```
156
+
157
+ Then bind it to the LLM model and query the model:
158
+ ```python
159
+ from langchain_openai import ChatOpenAI
160
+ from langchain_core.messages import HumanMessage
161
+
162
+ llm = ChatOpenAI(model="gpt-4o-mini")
163
+ llm_with_tools = llm.bind_tools([prolog_tool])
164
+ messages = [HumanMessage("Who are John's children?")]
165
+ response = llm_with_tools.invoke(messages)
166
+ messages.append(response)
167
+ print(response.tool_calls[0])
168
+ ```
169
+ The LLM will respond with a tool call request:
170
+ ```python
171
+ {'name': 'family_query',
172
+ 'args': {'men': 'john', 'women': None, 'child': None},
173
+ 'id': 'call_V6NUsJwhF41G9G7q6TBmghR0',
174
+ 'type': 'tool_call'}
175
+ ```
176
+ The tool takes this request and queries the Prolog database:
177
+ ```python
178
+ tool_msg = prolog_tool.invoke(response.tool_calls[0])
179
+ messages.append(tool_msg)
180
+ print(tool_msg)
181
+ ```
182
+ The tool returns a list with all the solutions for the query:
183
+ ```python
184
+ content='[{"Women": "bianca", "Child": "mary"}, {"Women": "bianca", "Child": "michael"}]'
185
+ name='family_query'
186
+ tool_call_id='call_V6NUsJwhF41G9G7q6TBmghR0'
187
+ ```
188
+ That we then pass to the LLM:
189
+ ```python
190
+ answer = llm_with_tools.invoke(messages)
191
+ print(answer.content)
192
+ ```
193
+ And the LLM answers the original query using the tool response:
194
+ ```python
195
+ John has two children: Mary and Michael. Their mother is Bianca.
196
+ ```
197
+
198
+ ### 2) Using a Prolog tool with an agent
199
+
200
+ First create the Prolog tool:
201
+ ```python
202
+ from langchain_prolog import PrologConfig, PrologTool
203
+
204
+ schema = PrologRunnable.create_schema('parent', ['men', 'women', 'child'])
205
+ config = PrologConfig(
206
+ rules_file="family.pl",
207
+ query_schema=schema,
208
+ )
209
+ prolog_tool = PrologTool(
210
+ prolog_config=config,
211
+ name="family_query",
212
+ description="""
213
+ Query family relationships using Prolog.
214
+ parent(X, Y, Z) implies only that Z is a child of X and Y.
215
+ Input can be a query string like 'parent(john, X, Y)'
216
+ or 'john, X, Y'"
217
+ You have to specify 3 parameters: men, woman, child.
218
+ Do not use quotes.
219
+ """
220
+ )
221
+ ```
222
+ Then pass it to the agent's constructor:
223
+ ```python
224
+ from langchain_core.prompts import ChatPromptTemplate
225
+ from langchain.agents import create_tool_calling_agent, AgentExecutor
226
+
227
+ llm = ChatOpenAI(model="gpt-4o-mini")
228
+ prompt = ChatPromptTemplate.from_messages(
229
+ [
230
+ ("system", "You are a helpful assistant"),
231
+ ("human", "{input}"),
232
+ ("placeholder", "{agent_scratchpad}"),
233
+ ]
234
+ )
235
+ tools = [prolog_tool]
236
+ agent = create_tool_calling_agent(llm, tools, prompt)
237
+ agent_executor = AgentExecutor(agent=agent, tools=tools)
238
+ ```
239
+ The agent takes the query and use the Prolog tool if needed:
240
+ ```python
241
+ answer = agent_executor.invoke({"input": "Who are John's children?"})
242
+ print(answer)
243
+ ```
244
+ Then the agent recieves the tool response as part of the {agent_scratchpad} placeholder and generates the answer:
245
+ ```python
246
+ {'input': "Who are John's children?", 'output': 'John has two children: Mary and Michael, with Bianca as their mother.'}
@@ -0,0 +1,94 @@
1
+ [build-system]
2
+ requires = ["poetry-core>=1.0.0"]
3
+ build-backend = "poetry.core.masonry.api"
4
+
5
+ [tool.poetry]
6
+ name = "langchain-prolog"
7
+ version = "0.1.0"
8
+ description = "An integration package connecting Prolog and LangChain"
9
+ authors = ["Antonio Pisani"]
10
+ readme = "README.md"
11
+ repository = "https://github.com/apisani1/langchain-prolog"
12
+ license = "MIT"
13
+ packages = [{ include = "langchain_prolog", from = "src" }]
14
+ keywords = ["langchain", "prolog", "swi-prolog", "llm", "agent"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Prolog",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
24
+ ]
25
+ include = [
26
+ { path = "src/langchain_prolog/*.pl", format = "sdist" },
27
+ { path = "src/langchain_prolog/*.pl", format = "wheel" }
28
+ ]
29
+
30
+ [tool.poetry.urls]
31
+ "Source Code" = "https://github.com/langchain-ai/langchain/tree/master/libs/partners/prolog"
32
+ "Release Notes" = "https://github.com/langchain-ai/langchain/releases?q=tag%3A%22prolog%3D%3D0%22&expanded=true"
33
+
34
+ [tool.poetry.dependencies]
35
+ python = ">=3.10,<4.0"
36
+ langchain-core = "^0.3.0"
37
+ janus-swi = "^1.5.0"
38
+ pydantic = "^2.0.0"
39
+
40
+ [tool.coverage.run]
41
+ omit = ["tests/*"]
42
+
43
+ [tool.pytest.ini_options]
44
+ addopts = "--strict-markers --strict-config --durations=5"
45
+ markers = [
46
+ "compile: mark placeholder test used to compile integration tests without running them",
47
+ "integration: mark integration tests",
48
+ "requires_prolog: mark tests that require SWI-Prolog",]
49
+ asyncio_mode = "auto"
50
+
51
+ [tool.poetry.group.test]
52
+ optional = true
53
+
54
+ [tool.poetry.group.lint]
55
+ optional = true
56
+
57
+ [tool.poetry.group.dev]
58
+ optional = true
59
+
60
+ [tool.poetry.group.dev.dependencies]
61
+ black = "^25.1.0"
62
+ isort = "^6.0.0"
63
+ mypy = "^1.15.0"
64
+
65
+ [tool.poetry.group.test.dependencies]
66
+ pytest = "^7.0.0"
67
+ pytest-asyncio = "^0.21.0"
68
+
69
+ [tool.poetry.group.lint.dependencies]
70
+ flake8 = "^7.1.0"
71
+
72
+ [tool.poetry.group.typing.dependencies]
73
+ mypy = "^1.10"
74
+
75
+ [tool.poetry.group.docs.dependencies]
76
+ sphinx = "^8.1.3"
77
+ sphinx-rtd-theme = "^3.0.2"
78
+ myst-parser = "^4.0.0"
79
+ sphinx-copybutton = "^0.5.2"
80
+
81
+ [tool.black]
82
+ line-length = 100
83
+ target-version = ['py39']
84
+
85
+ [tool.isort]
86
+ profile = "black"
87
+ line_length = 100
88
+
89
+ [tool.mypy]
90
+ python_version = "3.9"
91
+ disallow_untyped_defs = true
92
+ warn_return_any = true
93
+ warn_unused_configs = true
94
+ check_untyped_defs = true
@@ -0,0 +1,59 @@
1
+ """
2
+ langchain_prolog - A LangChain integration for SWI-Prolog
3
+
4
+ This module provides a bridge between LangChain and SWI-Prolog, allowing seamless
5
+ integration of Prolog's logic programming capabilities into LangChain pipelines.
6
+
7
+ Key Components:
8
+ - PrologConfig: Configuration class for Prolog settings
9
+ - PrologRunnable: Main class for executing Prolog queries
10
+ - PrologTool: Utility class for integrating Prolog queries into LangChain tools
11
+ - PrologResult: Type representing possible Prolog query results
12
+ - PrologInput: Type representing valid input formats
13
+ - PrologRuntimeError: Exception class for Prolog execution errors
14
+
15
+ Requirements:
16
+ - Python 3.9 or higher
17
+ - LangChain 0.3.0 or higher
18
+ - Pydantic 2.0 or higher
19
+ - SWI-Prolog must be installed and accessible in the system path
20
+ - On macOS, requires Homebrew installation of SWI-Prolog
21
+ - The janus_swipl package must be installed
22
+ """
23
+
24
+ from pydantic import ValidationError
25
+
26
+ from ._prolog_init import initialize_prolog
27
+ from .exceptions import (
28
+ PrologFileNotFoundError,
29
+ PrologInitializationError,
30
+ PrologRuntimeError,
31
+ PrologToolException,
32
+ PrologValueError,
33
+ )
34
+ from .runnable import (
35
+ PrologConfig,
36
+ PrologInput,
37
+ PrologResult,
38
+ PrologRunnable,
39
+ )
40
+ from .tool import PrologTool
41
+ from .__version__ import __version__
42
+
43
+
44
+ __all__ = [
45
+ "PrologConfig",
46
+ "PrologInput",
47
+ "PrologRunnable",
48
+ "PrologRuntimeError",
49
+ "PrologFileNotFoundError",
50
+ "PrologInitializationError",
51
+ "PrologToolException",
52
+ "PrologValueError",
53
+ "PrologResult",
54
+ "PrologTool",
55
+ "ValidationError",
56
+ ]
57
+
58
+ # Initialize Prolog immediately when this module is imported
59
+ initialize_prolog()
@@ -0,0 +1,3 @@
1
+ VERSION = (0, 1, 0) # Major, Minor, Patch
2
+
3
+ __version__ = ".".join(map(str, VERSION))