langchain-quantumscan 0.1.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_quantumscan/__init__.py +305 -0
- langchain_quantumscan-0.1.0.dist-info/METADATA +90 -0
- langchain_quantumscan-0.1.0.dist-info/RECORD +6 -0
- langchain_quantumscan-0.1.0.dist-info/WHEEL +5 -0
- langchain_quantumscan-0.1.0.dist-info/licenses/LICENSE +21 -0
- langchain_quantumscan-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"""
|
|
2
|
+
QuantumScan tools for LangChain, LangGraph, CrewAI, and AutoGen.
|
|
3
|
+
|
|
4
|
+
Pre-transaction safety checks (honeypot/drainer detection, contract risk
|
|
5
|
+
scoring) and post-quantum cryptography vulnerability scanning, exposed as
|
|
6
|
+
ready-to-use agent tools — no server to run, calls the hosted QuantumScan
|
|
7
|
+
MCP endpoint directly.
|
|
8
|
+
|
|
9
|
+
Works with:
|
|
10
|
+
- LangChain / LangGraph: use the BaseTool subclasses below
|
|
11
|
+
- CrewAI: see QuantumScanCrewTool
|
|
12
|
+
- AutoGen: see quantumscan_scan / quantumscan_result / quantumscan_check
|
|
13
|
+
and AUTOGEN_TOOLS
|
|
14
|
+
|
|
15
|
+
No API key required for the free tier (10 scans/day per IP).
|
|
16
|
+
Optional: QUANTUMSCAN_API_KEY env var for higher limits.
|
|
17
|
+
|
|
18
|
+
Example (LangChain / LangGraph):
|
|
19
|
+
from langchain_quantumscan import get_quantumscan_tools
|
|
20
|
+
from langgraph.prebuilt import create_react_agent
|
|
21
|
+
|
|
22
|
+
tools = get_quantumscan_tools()
|
|
23
|
+
agent = create_react_agent(llm, tools)
|
|
24
|
+
|
|
25
|
+
Example (CrewAI):
|
|
26
|
+
from langchain_quantumscan import QuantumScanCrewTool
|
|
27
|
+
agent = Agent(role="Security Auditor", tools=[QuantumScanCrewTool()], ...)
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
import json
|
|
33
|
+
import os
|
|
34
|
+
import urllib.error
|
|
35
|
+
import urllib.request
|
|
36
|
+
from typing import Optional, Type
|
|
37
|
+
|
|
38
|
+
__version__ = "0.1.0"
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
from langchain.tools import BaseTool
|
|
42
|
+
from pydantic import BaseModel, Field
|
|
43
|
+
|
|
44
|
+
HAS_LANGCHAIN = True
|
|
45
|
+
except ImportError:
|
|
46
|
+
HAS_LANGCHAIN = False
|
|
47
|
+
|
|
48
|
+
QUANTUMSCAN_URL = os.environ.get("QUANTUMSCAN_API_URL", "https://quantumscan.io")
|
|
49
|
+
QUANTUMSCAN_API_KEY = os.environ.get("QUANTUMSCAN_API_KEY", "")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# ── HTTP helper ─────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _mcp_call(tool_name: str, arguments: dict) -> str:
|
|
56
|
+
"""Call a QuantumScan MCP tool. Returns tool result text."""
|
|
57
|
+
headers = {"Content-Type": "application/json", "User-Agent": f"langchain-quantumscan/{__version__}"}
|
|
58
|
+
if QUANTUMSCAN_API_KEY:
|
|
59
|
+
headers["X-API-Key"] = QUANTUMSCAN_API_KEY
|
|
60
|
+
|
|
61
|
+
payload = json.dumps(
|
|
62
|
+
{
|
|
63
|
+
"jsonrpc": "2.0",
|
|
64
|
+
"id": 1,
|
|
65
|
+
"method": "tools/call",
|
|
66
|
+
"params": {"name": tool_name, "arguments": arguments},
|
|
67
|
+
}
|
|
68
|
+
).encode()
|
|
69
|
+
|
|
70
|
+
req = urllib.request.Request(
|
|
71
|
+
f"{QUANTUMSCAN_URL}/api/mcp",
|
|
72
|
+
data=payload,
|
|
73
|
+
headers=headers,
|
|
74
|
+
method="POST",
|
|
75
|
+
)
|
|
76
|
+
try:
|
|
77
|
+
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
78
|
+
data = json.loads(resp.read().decode())
|
|
79
|
+
content = data.get("result", {}).get("content", [])
|
|
80
|
+
return "\n".join(c.get("text", "") for c in content if c.get("type") == "text")
|
|
81
|
+
except urllib.error.HTTPError as e:
|
|
82
|
+
return f"Error {e.code}: {e.read().decode()}"
|
|
83
|
+
except Exception as e: # noqa: BLE001 — agent tools must return text, never raise
|
|
84
|
+
return f"Request failed: {e}"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# ── Pydantic schemas (for LangChain) ────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
if HAS_LANGCHAIN:
|
|
90
|
+
|
|
91
|
+
class ScanRepositoryInput(BaseModel):
|
|
92
|
+
repo_url: str = Field(description="GitHub, GitLab, or Bitbucket URL to scan")
|
|
93
|
+
|
|
94
|
+
class GetScanResultInput(BaseModel):
|
|
95
|
+
scan_id: str = Field(description="Scan UUID returned by scan_repository")
|
|
96
|
+
|
|
97
|
+
class CheckPqcRiskInput(BaseModel):
|
|
98
|
+
algorithms: list[str] = Field(
|
|
99
|
+
description='Algorithm names to check, e.g. ["ECDSA", "RSA-2048", "ML-KEM-768"]'
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
class ScanContractInput(BaseModel):
|
|
103
|
+
contract_address: str = Field(description="Ethereum contract address (0x...)")
|
|
104
|
+
network: Optional[int] = Field(
|
|
105
|
+
default=1, description="Chain ID (1=Ethereum, 137=Polygon, 42161=Arbitrum, 8453=Base)"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# ── LangChain / LangGraph Tools ──────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
if HAS_LANGCHAIN:
|
|
112
|
+
|
|
113
|
+
class QuantumScanTool(BaseTool):
|
|
114
|
+
name: str = "scan_repository"
|
|
115
|
+
description: str = (
|
|
116
|
+
"Submit a GitHub, GitLab, or Bitbucket repository for post-quantum cryptography "
|
|
117
|
+
"vulnerability scanning. Returns a scan_id. Poll with get_scan_result after ~60s."
|
|
118
|
+
)
|
|
119
|
+
args_schema: Type[BaseModel] = ScanRepositoryInput
|
|
120
|
+
|
|
121
|
+
def _run(self, repo_url: str) -> str:
|
|
122
|
+
return _mcp_call("scan_repository", {"repo_url": repo_url})
|
|
123
|
+
|
|
124
|
+
async def _arun(self, repo_url: str) -> str:
|
|
125
|
+
return self._run(repo_url)
|
|
126
|
+
|
|
127
|
+
class GetScanResultTool(BaseTool):
|
|
128
|
+
name: str = "get_scan_result"
|
|
129
|
+
description: str = (
|
|
130
|
+
"Get results of a PQC scan by scan_id. "
|
|
131
|
+
"Returns risk score (0-100), vulnerable algorithms, and CBOM. "
|
|
132
|
+
"If status is 'working', wait 15s and retry."
|
|
133
|
+
)
|
|
134
|
+
args_schema: Type[BaseModel] = GetScanResultInput
|
|
135
|
+
|
|
136
|
+
def _run(self, scan_id: str) -> str:
|
|
137
|
+
return _mcp_call("get_scan_result", {"scan_id": scan_id})
|
|
138
|
+
|
|
139
|
+
async def _arun(self, scan_id: str) -> str:
|
|
140
|
+
return self._run(scan_id)
|
|
141
|
+
|
|
142
|
+
class CheckPqcRiskTool(BaseTool):
|
|
143
|
+
name: str = "check_pqc_risk"
|
|
144
|
+
description: str = (
|
|
145
|
+
"Instantly check if cryptographic algorithms are quantum-vulnerable. "
|
|
146
|
+
"No scan needed. Supports ECDSA, RSA, Ed25519, AES-128, SHA-1, BLS12, ML-KEM, etc."
|
|
147
|
+
)
|
|
148
|
+
args_schema: Type[BaseModel] = CheckPqcRiskInput
|
|
149
|
+
|
|
150
|
+
def _run(self, algorithms: list[str]) -> str:
|
|
151
|
+
return _mcp_call("check_pqc_risk", {"algorithms": algorithms})
|
|
152
|
+
|
|
153
|
+
async def _arun(self, algorithms: list[str]) -> str:
|
|
154
|
+
return self._run(algorithms)
|
|
155
|
+
|
|
156
|
+
class ScanContractTool(BaseTool):
|
|
157
|
+
name: str = "scan_contract"
|
|
158
|
+
description: str = (
|
|
159
|
+
"Verify a smart contract is safe BEFORE an agent signs a transaction with it. "
|
|
160
|
+
"Detects honeypots, drainers, rug pulls, uncapped mints, and PQC-vulnerable crypto. "
|
|
161
|
+
"Returns risk score 0-100 and a signing recommendation."
|
|
162
|
+
)
|
|
163
|
+
args_schema: Type[BaseModel] = ScanContractInput
|
|
164
|
+
|
|
165
|
+
def _run(self, contract_address: str, network: int = 1) -> str:
|
|
166
|
+
return _mcp_call("scan_contract", {"contract_address": contract_address, "network": network})
|
|
167
|
+
|
|
168
|
+
async def _arun(self, contract_address: str, network: int = 1) -> str:
|
|
169
|
+
return self._run(contract_address, network)
|
|
170
|
+
|
|
171
|
+
def get_quantumscan_tools() -> list:
|
|
172
|
+
"""Return all 4 QuantumScan LangChain tools, ready to pass to any agent."""
|
|
173
|
+
return [QuantumScanTool(), GetScanResultTool(), CheckPqcRiskTool(), ScanContractTool()]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# ── CrewAI Tool ──────────────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
from crewai.tools import BaseTool as CrewBaseTool
|
|
180
|
+
|
|
181
|
+
class QuantumScanCrewTool(CrewBaseTool):
|
|
182
|
+
name: str = "QuantumScan Security Check"
|
|
183
|
+
description: str = (
|
|
184
|
+
"Verifies a smart contract before signing, or scans a repo/algorithm for post-quantum risk. "
|
|
185
|
+
"Input: a contract address (0x...) to verify before signing, a repo URL to scan, "
|
|
186
|
+
"a scan UUID to get results, or an algorithm name to check."
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def _run(self, input_text: str) -> str:
|
|
190
|
+
import re
|
|
191
|
+
|
|
192
|
+
eth_addr_m = re.search(r"\b0x[0-9a-fA-F]{40}\b", input_text)
|
|
193
|
+
url_m = re.search(r"https?://(?:github|gitlab|bitbucket)\.(?:com|org)/\S+", input_text)
|
|
194
|
+
uuid_m = re.search(
|
|
195
|
+
r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", input_text, re.I
|
|
196
|
+
)
|
|
197
|
+
algo_m = re.search(r"\b(ECDSA|RSA|ECDH|Ed25519|AES-?128|SHA-?1|MD5|ML-KEM|ML-DSA)\b", input_text, re.I)
|
|
198
|
+
|
|
199
|
+
if eth_addr_m:
|
|
200
|
+
return _mcp_call("scan_contract", {"contract_address": eth_addr_m.group(0)})
|
|
201
|
+
elif url_m:
|
|
202
|
+
return _mcp_call("scan_repository", {"repo_url": url_m.group(0).rstrip("/")})
|
|
203
|
+
elif uuid_m:
|
|
204
|
+
return _mcp_call("get_scan_result", {"scan_id": uuid_m.group(0)})
|
|
205
|
+
elif algo_m:
|
|
206
|
+
return _mcp_call("check_pqc_risk", {"algorithms": [algo_m.group(0)]})
|
|
207
|
+
else:
|
|
208
|
+
return (
|
|
209
|
+
"Send a contract address (0x...) to verify before signing, a GitHub URL to scan, "
|
|
210
|
+
"a scan UUID to get results, or an algorithm name to check risk."
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
except ImportError:
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# ── AutoGen Function Tools ───────────────────────────────────────────────────
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def quantumscan_scan(repo_url: str) -> str:
|
|
221
|
+
"""Submit a GitHub/GitLab/Bitbucket repo for PQC vulnerability scanning. Returns scan_id."""
|
|
222
|
+
return _mcp_call("scan_repository", {"repo_url": repo_url})
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def quantumscan_result(scan_id: str) -> str:
|
|
226
|
+
"""Get PQC scan result by scan_id. Returns risk score + vulnerable algorithms."""
|
|
227
|
+
return _mcp_call("get_scan_result", {"scan_id": scan_id})
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def quantumscan_check(algorithms: list) -> str:
|
|
231
|
+
"""Instantly check if algorithms are quantum-vulnerable. No scan needed."""
|
|
232
|
+
return _mcp_call("check_pqc_risk", {"algorithms": algorithms})
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def quantumscan_scan_contract(contract_address: str, network: int = 1) -> str:
|
|
236
|
+
"""Verify a smart contract is safe to sign a transaction with. Returns risk score + recommendation."""
|
|
237
|
+
return _mcp_call("scan_contract", {"contract_address": contract_address, "network": network})
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
AUTOGEN_TOOLS = [
|
|
241
|
+
{
|
|
242
|
+
"type": "function",
|
|
243
|
+
"function": {
|
|
244
|
+
"name": "quantumscan_scan",
|
|
245
|
+
"description": "Submit a GitHub/GitLab/Bitbucket repository for PQC vulnerability scanning.",
|
|
246
|
+
"parameters": {
|
|
247
|
+
"type": "object",
|
|
248
|
+
"properties": {"repo_url": {"type": "string", "description": "Full repository URL"}},
|
|
249
|
+
"required": ["repo_url"],
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"type": "function",
|
|
255
|
+
"function": {
|
|
256
|
+
"name": "quantumscan_result",
|
|
257
|
+
"description": "Get PQC scan results by scan_id.",
|
|
258
|
+
"parameters": {
|
|
259
|
+
"type": "object",
|
|
260
|
+
"properties": {"scan_id": {"type": "string", "description": "UUID from quantumscan_scan"}},
|
|
261
|
+
"required": ["scan_id"],
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"type": "function",
|
|
267
|
+
"function": {
|
|
268
|
+
"name": "quantumscan_check",
|
|
269
|
+
"description": "Instantly check if cryptographic algorithms are quantum-vulnerable.",
|
|
270
|
+
"parameters": {
|
|
271
|
+
"type": "object",
|
|
272
|
+
"properties": {"algorithms": {"type": "array", "items": {"type": "string"}}},
|
|
273
|
+
"required": ["algorithms"],
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"type": "function",
|
|
279
|
+
"function": {
|
|
280
|
+
"name": "quantumscan_scan_contract",
|
|
281
|
+
"description": "Verify a smart contract is safe to sign a transaction with before doing so.",
|
|
282
|
+
"parameters": {
|
|
283
|
+
"type": "object",
|
|
284
|
+
"properties": {
|
|
285
|
+
"contract_address": {"type": "string", "description": "0x... Ethereum contract address"},
|
|
286
|
+
"network": {"type": "integer", "description": "Chain ID, default 1 (Ethereum)"},
|
|
287
|
+
},
|
|
288
|
+
"required": ["contract_address"],
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
]
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
# ── Claude Desktop / MCP client config snippet ───────────────────────────────
|
|
296
|
+
|
|
297
|
+
CLAUDE_DESKTOP_CONFIG = {
|
|
298
|
+
"mcpServers": {
|
|
299
|
+
"quantumscan": {
|
|
300
|
+
"command": "npx",
|
|
301
|
+
"args": ["-y", "mcp-remote", "https://quantumscan.io/api/mcp"],
|
|
302
|
+
"env": {"QUANTUMSCAN_API_KEY": "optional — get a free key at quantumscan.io"},
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-quantumscan
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: QuantumScan tools for LangChain, LangGraph, CrewAI, and AutoGen — pre-transaction safety checks and post-quantum cryptography scanning for autonomous agents.
|
|
5
|
+
Author-email: QuantumScan <hello@quantumscan.io>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://quantumscan.io
|
|
8
|
+
Project-URL: Repository, https://github.com/quantumscan-io/langchain-quantumscan
|
|
9
|
+
Project-URL: Issues, https://github.com/quantumscan-io/langchain-quantumscan/issues
|
|
10
|
+
Keywords: langchain,langgraph,crewai,autogen,ai-agent,blockchain-security,post-quantum-cryptography,quantumscan,mcp
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Provides-Extra: langchain
|
|
19
|
+
Requires-Dist: langchain>=0.1; extra == "langchain"
|
|
20
|
+
Requires-Dist: pydantic>=2.0; extra == "langchain"
|
|
21
|
+
Provides-Extra: crewai
|
|
22
|
+
Requires-Dist: crewai>=0.1; python_version >= "3.10" and extra == "crewai"
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# langchain-quantumscan
|
|
28
|
+
|
|
29
|
+
QuantumScan tools for **LangChain**, **LangGraph**, **CrewAI**, and **AutoGen** — pre-transaction
|
|
30
|
+
safety checks (honeypot/drainer detection, contract risk scoring) and post-quantum cryptography
|
|
31
|
+
vulnerability scanning, ready to drop into an agent's toolset.
|
|
32
|
+
|
|
33
|
+
No server to run — every tool calls the hosted QuantumScan MCP endpoint
|
|
34
|
+
(`https://quantumscan.io/api/mcp`) directly. Free tier: 10 scans/day per IP, no signup.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install langchain-quantumscan
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## LangChain / LangGraph
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from langchain_quantumscan import get_quantumscan_tools
|
|
46
|
+
from langgraph.prebuilt import create_react_agent
|
|
47
|
+
|
|
48
|
+
tools = get_quantumscan_tools()
|
|
49
|
+
agent = create_react_agent(llm, tools)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Individual tools: `QuantumScanTool` (scan a repo), `GetScanResultTool` (poll for results),
|
|
53
|
+
`CheckPqcRiskTool` (instant algorithm check, no scan), `ScanContractTool` (verify a contract
|
|
54
|
+
is safe **before** signing a transaction with it).
|
|
55
|
+
|
|
56
|
+
## CrewAI
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from crewai import Agent
|
|
60
|
+
from langchain_quantumscan import QuantumScanCrewTool
|
|
61
|
+
|
|
62
|
+
auditor = Agent(
|
|
63
|
+
role="Security Auditor",
|
|
64
|
+
goal="Verify contracts and repos are safe before the crew interacts with them",
|
|
65
|
+
tools=[QuantumScanCrewTool()],
|
|
66
|
+
)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## AutoGen
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from langchain_quantumscan import quantumscan_scan_contract, AUTOGEN_TOOLS
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Why this exists
|
|
76
|
+
|
|
77
|
+
Autonomous agents that sign transactions or install dependencies are the highest-value target
|
|
78
|
+
for honeypots, drainers, and rug pulls — and by construction they can't "notice" a scam the way
|
|
79
|
+
a human would. `ScanContractTool` / `quantumscan_scan_contract` gives an agent a way to check
|
|
80
|
+
**before** signing, not just discover the loss after.
|
|
81
|
+
|
|
82
|
+
## Optional: higher rate limits
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
export QUANTUMSCAN_API_KEY=qs_... # get one free at quantumscan.io
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
langchain_quantumscan/__init__.py,sha256=u4fjEUYblP2XD577ArNxWXFU73-aG2WzS05mazSo3bw,12007
|
|
2
|
+
langchain_quantumscan-0.1.0.dist-info/licenses/LICENSE,sha256=T-do6N76xWBkLV14YMzge8AY12a-47upAG4VM9Dxl-Y,1068
|
|
3
|
+
langchain_quantumscan-0.1.0.dist-info/METADATA,sha256=R4pqXL0JzG2W2n-BXDrWz5MGI_34L16p4FVxa9BtQx4,3036
|
|
4
|
+
langchain_quantumscan-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
langchain_quantumscan-0.1.0.dist-info/top_level.txt,sha256=mKzhh4-vaXyNPFohtguuCycJDH0Yb1laZOgu5ceyRew,22
|
|
6
|
+
langchain_quantumscan-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 QuantumScan
|
|
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 @@
|
|
|
1
|
+
langchain_quantumscan
|