langchain-finic 0.1.0a4__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_finic-0.1.0a4/.gitignore +59 -0
- langchain_finic-0.1.0a4/CHANGELOG.md +15 -0
- langchain_finic-0.1.0a4/CODE_OF_CONDUCT.md +14 -0
- langchain_finic-0.1.0a4/CONTRIBUTING.md +54 -0
- langchain_finic-0.1.0a4/LANGCHAIN_LISTING.md +22 -0
- langchain_finic-0.1.0a4/LICENSE +21 -0
- langchain_finic-0.1.0a4/Makefile +21 -0
- langchain_finic-0.1.0a4/PKG-INFO +142 -0
- langchain_finic-0.1.0a4/README.md +109 -0
- langchain_finic-0.1.0a4/RELEASING.md +96 -0
- langchain_finic-0.1.0a4/SECURITY.md +14 -0
- langchain_finic-0.1.0a4/docs/api.md +43 -0
- langchain_finic-0.1.0a4/docs/index.md +65 -0
- langchain_finic-0.1.0a4/docs/usage.md +257 -0
- langchain_finic-0.1.0a4/examples/composition.py +46 -0
- langchain_finic-0.1.0a4/examples/middleware_agent.py +51 -0
- langchain_finic-0.1.0a4/mkdocs.yml +20 -0
- langchain_finic-0.1.0a4/pyproject.toml +71 -0
- langchain_finic-0.1.0a4/scripts/check_dist.py +73 -0
- langchain_finic-0.1.0a4/scripts/check_release.py +10 -0
- langchain_finic-0.1.0a4/scripts/smoke_install.py +55 -0
- langchain_finic-0.1.0a4/scripts/verify_registry.py +48 -0
- langchain_finic-0.1.0a4/src/langchain_finic/__init__.py +32 -0
- langchain_finic-0.1.0a4/src/langchain_finic/_config.py +7 -0
- langchain_finic-0.1.0a4/src/langchain_finic/_state.py +22 -0
- langchain_finic-0.1.0a4/src/langchain_finic/classifier.py +257 -0
- langchain_finic-0.1.0a4/src/langchain_finic/client.py +210 -0
- langchain_finic-0.1.0a4/src/langchain_finic/middleware.py +254 -0
- langchain_finic-0.1.0a4/src/langchain_finic/models.py +220 -0
- langchain_finic-0.1.0a4/src/langchain_finic/py.typed +0 -0
- langchain_finic-0.1.0a4/tests/integration_tests/test_live.py +40 -0
- langchain_finic-0.1.0a4/tests/unit_tests/conftest.py +69 -0
- langchain_finic-0.1.0a4/tests/unit_tests/test_classifier.py +188 -0
- langchain_finic-0.1.0a4/tests/unit_tests/test_documentation.py +110 -0
- langchain_finic-0.1.0a4/tests/unit_tests/test_integration.py +396 -0
- langchain_finic-0.1.0a4/tests/unit_tests/test_middleware.py +402 -0
- langchain_finic-0.1.0a4/tests/unit_tests/test_model_config.py +105 -0
- langchain_finic-0.1.0a4/tests/unit_tests/test_standard.py +50 -0
- langchain_finic-0.1.0a4/uv.lock +2927 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Python bytecode and compiled extensions
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.so
|
|
5
|
+
|
|
6
|
+
# Virtual environments
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
env/
|
|
10
|
+
|
|
11
|
+
# Packaging and build output
|
|
12
|
+
build/
|
|
13
|
+
dist/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
.eggs/
|
|
16
|
+
|
|
17
|
+
# Test, coverage, and tooling caches
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.mypy_cache/
|
|
20
|
+
.ruff_cache/
|
|
21
|
+
.pyright/
|
|
22
|
+
.tox/
|
|
23
|
+
.nox/
|
|
24
|
+
.coverage
|
|
25
|
+
.coverage.*
|
|
26
|
+
coverage.xml
|
|
27
|
+
htmlcov/
|
|
28
|
+
.cache/
|
|
29
|
+
.ipynb_checkpoints/
|
|
30
|
+
|
|
31
|
+
# Local secrets; keep templates trackable
|
|
32
|
+
.env
|
|
33
|
+
.env.*
|
|
34
|
+
!.env.example
|
|
35
|
+
!.env.*.example
|
|
36
|
+
!.env.sample
|
|
37
|
+
!.env.template
|
|
38
|
+
|
|
39
|
+
# Logs and editor files
|
|
40
|
+
*.log
|
|
41
|
+
.idea/
|
|
42
|
+
.vscode/
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
*~
|
|
46
|
+
|
|
47
|
+
# Operating system metadata
|
|
48
|
+
.DS_Store
|
|
49
|
+
Thumbs.db
|
|
50
|
+
Desktop.ini
|
|
51
|
+
|
|
52
|
+
# Local case reports and cached model responses
|
|
53
|
+
artifacts/
|
|
54
|
+
|
|
55
|
+
# Downloaded third-party India benchmark sources; provenance and checksums are tracked.
|
|
56
|
+
data/india/raw/
|
|
57
|
+
|
|
58
|
+
# Generated documentation
|
|
59
|
+
site/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0a4
|
|
4
|
+
|
|
5
|
+
Initial public alpha. See [GitHub Releases](https://github.com/supreplabs/langchain-finic/releases)
|
|
6
|
+
for publication dates and distribution checksums.
|
|
7
|
+
|
|
8
|
+
- Typed `Noul`, `Choice`, `MultiChoice`, and `Score` decisions with response validation.
|
|
9
|
+
- LangChain Runnable composition, tools, sync/async calls, batching, and tracing metadata.
|
|
10
|
+
- Optional model-routing and tool-screening middleware for LangChain agents.
|
|
11
|
+
- Configurable model name, transport injection, bounded retries, and client lifecycle management.
|
|
12
|
+
- MIT license, typed distributions, usage documentation, and API reference.
|
|
13
|
+
|
|
14
|
+
Configuration uses `FINIC_*` environment variables. Earlier unpublished prototypes
|
|
15
|
+
used `GRAYSON_*` aliases; those aliases are not supported by this release.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Community conduct
|
|
2
|
+
|
|
3
|
+
Be respectful, constructive, and welcoming to people of all backgrounds and levels
|
|
4
|
+
of experience. Focus feedback on the work. Harassment, discrimination, threats,
|
|
5
|
+
personal attacks, and disclosure of private information are not acceptable.
|
|
6
|
+
|
|
7
|
+
Maintainers may edit or remove inappropriate contributions and restrict participation
|
|
8
|
+
when needed. Enforcement should be proportionate and explained to the affected person
|
|
9
|
+
when possible. Apply these expectations consistently in issues, reviews, discussions,
|
|
10
|
+
and other project spaces.
|
|
11
|
+
|
|
12
|
+
Report conduct concerns privately to the Suprep Labs organization maintainers through
|
|
13
|
+
an available private contact on their GitHub profiles. Do not post private details in
|
|
14
|
+
public issues. Security vulnerabilities use the separate reporting path in SECURITY.md.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use Python 3.11 or later and [uv](https://docs.astral.sh/uv/).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/supreplabs/langchain-finic.git
|
|
7
|
+
cd langchain-finic
|
|
8
|
+
make install
|
|
9
|
+
make check
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Keep changes focused, describe the behavior and validation in your pull request,
|
|
13
|
+
and add regression tests for bugs. Public imports and serialized class identifiers
|
|
14
|
+
are compatibility commitments, including during the alpha period. Discuss breaking
|
|
15
|
+
changes in an issue before implementing them. Use conventional commit titles.
|
|
16
|
+
|
|
17
|
+
`tests/unit_tests` includes mocked framework composition tests and LangChain's
|
|
18
|
+
standard tool tests. Network access is disabled. Tests must not load `.env` or
|
|
19
|
+
require credentials. `langchain-tests` is pinned because its test contracts can
|
|
20
|
+
change independently of this package. Update it deliberately with the lockfile.
|
|
21
|
+
|
|
22
|
+
`make integration_test` makes two paid API requests (sync and async), with one
|
|
23
|
+
attempt each, using synthetic evidence. It requires an exported `FINIC_API_KEY`;
|
|
24
|
+
never put keys, production inputs, or raw responses in issues or fixtures.
|
|
25
|
+
These tests check response contracts, not deterministic probability values.
|
|
26
|
+
|
|
27
|
+
Use `make format` for formatting and `uv lock` after dependency changes.
|
|
28
|
+
Documentation lives in `docs/`; public API pages are generated from docstrings.
|
|
29
|
+
See [release instructions](RELEASING.md) for distribution and publishing.
|
|
30
|
+
|
|
31
|
+
By contributing, you agree to license your contributions under this repository's
|
|
32
|
+
MIT license. See [community conduct](CODE_OF_CONDUCT.md) and
|
|
33
|
+
[security reporting](SECURITY.md).
|
|
34
|
+
|
|
35
|
+
The minimum-dependency CI job uses `langchain-tests==1.0.0`, which supports
|
|
36
|
+
`langchain-core==1.0.0`; current-dependency jobs use `langchain-tests==1.1.9`.
|
|
37
|
+
The latter requires core >=1.4 and cannot validate the historical minimum.
|
|
38
|
+
|
|
39
|
+
## Documentation standards
|
|
40
|
+
|
|
41
|
+
Keep the user site focused on installation, supported interfaces, configuration,
|
|
42
|
+
examples, and API behavior. Release procedures and directory-listing instructions
|
|
43
|
+
belong in the repository's maintainer guides, outside `docs/`.
|
|
44
|
+
|
|
45
|
+
Ground capability claims in the public API and tests. Do not publish internal
|
|
46
|
+
research results, account-specific usage, or unverified accuracy/calibration claims.
|
|
47
|
+
Use fictional examples. Define inputs explicitly or label examples as reusable
|
|
48
|
+
functions with caller-supplied parameters. Python snippets in the README and user
|
|
49
|
+
guides are executed offline by `test_documentation.py`; keep them runnable in the
|
|
50
|
+
order shown. Prefer links over duplicated explanations and check relative links.
|
|
51
|
+
|
|
52
|
+
Follow [LangChain's documentation quality guidance](https://docs.langchain.com/oss/python/contributing/documentation#quality-standards).
|
|
53
|
+
Its Mintlify-specific syntax applies to LangChain-hosted pages; this repository's
|
|
54
|
+
site uses MkDocs and generated Python API references.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# LangChain directory listing
|
|
2
|
+
|
|
3
|
+
Submit only after PyPI publication. This document prepares the listing; it does not
|
|
4
|
+
claim acceptance, partnership, or endorsement.
|
|
5
|
+
|
|
6
|
+
Use the [LangChain integration listing process](https://docs.langchain.com/oss/python/contributing/publish-langchain).
|
|
7
|
+
New packages normally receive an external-docs listing rather than a hosted guide.
|
|
8
|
+
Do not open a manual documentation PR unless a maintainer asks.
|
|
9
|
+
|
|
10
|
+
| Field | Value |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| Display name | Finic |
|
|
13
|
+
| Language | Python |
|
|
14
|
+
| Package | langchain-finic |
|
|
15
|
+
| Component | Tools; middleware (select the form's corresponding category) |
|
|
16
|
+
| Documentation | https://supreplabs.github.io/langchain-finic/ |
|
|
17
|
+
| Repository | https://github.com/supreplabs/langchain-finic |
|
|
18
|
+
| Description | Typed Finic Grayson decisions as LangChain tools and Runnables, with optional model routing and tool-screening middleware. |
|
|
19
|
+
|
|
20
|
+
`FinicClassifier.as_tool()` produces a standard LangChain tool. Middleware classes
|
|
21
|
+
extend `AgentMiddleware`. The integration is not a chat model; do not advertise
|
|
22
|
+
chat generation, token streaming, or provider-native tool calling.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Suprep Labs
|
|
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,21 @@
|
|
|
1
|
+
.PHONY: install test integration_test lint format type_check docs build check
|
|
2
|
+
install:
|
|
3
|
+
uv sync --locked --group dev --extra middleware
|
|
4
|
+
test:
|
|
5
|
+
uv run --locked --group test pytest tests/unit_tests -q
|
|
6
|
+
integration_test:
|
|
7
|
+
FINIC_LIVE_TESTS=1 uv run --locked --group test pytest -o addopts= tests/integration_tests -m live -q
|
|
8
|
+
lint:
|
|
9
|
+
uv run --locked --group lint ruff check src tests examples scripts
|
|
10
|
+
uv run --locked --group lint ruff format --check src tests examples scripts
|
|
11
|
+
format:
|
|
12
|
+
uv run --locked --group lint ruff format src tests examples scripts
|
|
13
|
+
type_check:
|
|
14
|
+
uv run --locked --group lint --extra middleware mypy
|
|
15
|
+
docs:
|
|
16
|
+
uv run --locked --group docs --extra middleware mkdocs build --strict
|
|
17
|
+
build:
|
|
18
|
+
uv build
|
|
19
|
+
uv run --locked --group build twine check dist/*
|
|
20
|
+
uv run --locked python scripts/check_dist.py
|
|
21
|
+
check: lint type_check test docs build
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: langchain-finic
|
|
3
|
+
Version: 0.1.0a4
|
|
4
|
+
Summary: Community LangChain tools, Runnables, and middleware for Finic Grayson decisions
|
|
5
|
+
Project-URL: Homepage, https://github.com/supreplabs/langchain-finic
|
|
6
|
+
Project-URL: Documentation, https://supreplabs.github.io/langchain-finic/
|
|
7
|
+
Project-URL: Repository, https://github.com/supreplabs/langchain-finic
|
|
8
|
+
Project-URL: Issues, https://github.com/supreplabs/langchain-finic/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/supreplabs/langchain-finic/blob/main/CHANGELOG.md
|
|
10
|
+
Author: Suprep Labs
|
|
11
|
+
Maintainer: Suprep Labs
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: agents,finic,grayson,langchain,langgraph
|
|
15
|
+
Classifier: Development Status :: 3 - Alpha
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: httpx<1,>=0.28.1
|
|
26
|
+
Requires-Dist: langchain-core<2,>=1
|
|
27
|
+
Requires-Dist: langsmith<1,>=0.3
|
|
28
|
+
Requires-Dist: pydantic<3,>=2.12
|
|
29
|
+
Provides-Extra: middleware
|
|
30
|
+
Requires-Dist: langchain<2,>=1; extra == 'middleware'
|
|
31
|
+
Requires-Dist: langgraph<2,>=1; extra == 'middleware'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# langchain-finic
|
|
35
|
+
|
|
36
|
+
Community-maintained LangChain integration for **Finic Grayson**, by Suprep Labs.
|
|
37
|
+
Typed decisions, LCEL composition, LangGraph nodes, structured tools, and optional
|
|
38
|
+
agent middleware. This alpha is not endorsed by Finic or LangChain.
|
|
39
|
+
|
|
40
|
+
[Documentation](https://supreplabs.github.io/langchain-finic/) ·
|
|
41
|
+
[Source](https://github.com/supreplabs/langchain-finic) ·
|
|
42
|
+
[PyPI](https://pypi.org/project/langchain-finic/) ·
|
|
43
|
+
[MIT license](https://github.com/supreplabs/langchain-finic/blob/main/LICENSE)
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
Python 3.11 or newer. Install the alpha release:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install langchain-finic==0.1.0a4
|
|
51
|
+
export FINIC_API_KEY=your_key
|
|
52
|
+
# Optional; defaults to grayson-1:
|
|
53
|
+
export FINIC_MODEL=grayson-1
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Make a typed decision
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from langchain_finic import Choice, DecisionRequest, FinicClassifier, Noul
|
|
60
|
+
|
|
61
|
+
request = DecisionRequest(
|
|
62
|
+
state={"events": ["New device", "Transfer to an unfamiliar recipient"]},
|
|
63
|
+
questions={
|
|
64
|
+
"takeover": Noul(instructions="Does this evidence suggest account takeover?"),
|
|
65
|
+
"route": Choice(
|
|
66
|
+
instructions="Choose a review queue.",
|
|
67
|
+
criteria={"standard": "Routine review", "urgent": "Urgent investigation"},
|
|
68
|
+
),
|
|
69
|
+
},
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
with FinicClassifier() as classifier:
|
|
73
|
+
decision = classifier.invoke(request)
|
|
74
|
+
print(decision.nouls["takeover"].noul)
|
|
75
|
+
print(decision.choices["route"].choice)
|
|
76
|
+
print(decision.request_id)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`Noul`, `Choice`, `MultiChoice`, and `Score` have typed answers. Responses retain
|
|
80
|
+
probabilities, usage, and request metadata. Finic evaluates decisions; it does not
|
|
81
|
+
generate chat messages or text tokens.
|
|
82
|
+
|
|
83
|
+
## Compose with LangChain and LangGraph
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
# request is defined above.
|
|
87
|
+
with FinicClassifier() as classifier:
|
|
88
|
+
route_chain = classifier | (lambda result: result.choices["route"].choice)
|
|
89
|
+
route = route_chain.invoke(request, config={"tags": ["risk-review"]})
|
|
90
|
+
tool = classifier.as_tool()
|
|
91
|
+
print(tool.name) # finic_decide; pass it to create_agent or ToolNode
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
import asyncio
|
|
96
|
+
|
|
97
|
+
async def review():
|
|
98
|
+
async with FinicClassifier() as classifier:
|
|
99
|
+
return await classifier.abatch([request], config={"max_concurrency": 1})
|
|
100
|
+
|
|
101
|
+
results = asyncio.run(review())
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Batching makes individual API requests; concurrency is controlled by Runnable config.
|
|
105
|
+
Streaming yields one complete decision. A chat-provider model can call the Finic tool
|
|
106
|
+
through `create_agent`; the Finic integration itself is a decision Runnable.
|
|
107
|
+
|
|
108
|
+
## Optional middleware
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pip install 'langchain-finic[middleware]==0.1.0a4'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`ModelRouterMiddleware` selects among host chat models. `AutoModeMiddleware` screens
|
|
115
|
+
specified tools before execution. See the complete
|
|
116
|
+
[middleware example](https://github.com/supreplabs/langchain-finic/blob/main/examples/middleware_agent.py)
|
|
117
|
+
and [configuration guide](https://supreplabs.github.io/langchain-finic/usage/).
|
|
118
|
+
Tool screening is probabilistic; application authorization remains necessary.
|
|
119
|
+
|
|
120
|
+
## Configuration and data
|
|
121
|
+
|
|
122
|
+
Use `FINIC_API_KEY`, `FINIC_MODEL`, `FINIC_TIMEOUT_SECONDS`, and `FINIC_MAX_ATTEMPTS`,
|
|
123
|
+
or constructor options. The library does not load `.env`. The host controls optional
|
|
124
|
+
LangSmith tracing, which can record request data and responses. Default timeout is
|
|
125
|
+
60 seconds, with up to three attempts; retries can incur additional charges.
|
|
126
|
+
Use context managers to reuse and close owned HTTP clients. Injected clients remain
|
|
127
|
+
caller-owned. Read the [usage guide](https://supreplabs.github.io/langchain-finic/usage/)
|
|
128
|
+
for precedence, serialization, resource lifetimes, and error handling.
|
|
129
|
+
|
|
130
|
+
## Development
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
uv sync --locked --group dev --extra middleware
|
|
134
|
+
make check
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Default tests use mocked HTTP with network disabled. Opt-in live tests spend Finic
|
|
138
|
+
credits. See [contributing](https://github.com/supreplabs/langchain-finic/blob/main/CONTRIBUTING.md)
|
|
139
|
+
and [security reporting](https://github.com/supreplabs/langchain-finic/blob/main/SECURITY.md).
|
|
140
|
+
|
|
141
|
+
References: [Finic API](https://docs.finic.ai/reference/decide),
|
|
142
|
+
[LangChain integration guidelines](https://docs.langchain.com/oss/python/contributing/integrations-langchain).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# langchain-finic
|
|
2
|
+
|
|
3
|
+
Community-maintained LangChain integration for **Finic Grayson**, by Suprep Labs.
|
|
4
|
+
Typed decisions, LCEL composition, LangGraph nodes, structured tools, and optional
|
|
5
|
+
agent middleware. This alpha is not endorsed by Finic or LangChain.
|
|
6
|
+
|
|
7
|
+
[Documentation](https://supreplabs.github.io/langchain-finic/) ·
|
|
8
|
+
[Source](https://github.com/supreplabs/langchain-finic) ·
|
|
9
|
+
[PyPI](https://pypi.org/project/langchain-finic/) ·
|
|
10
|
+
[MIT license](https://github.com/supreplabs/langchain-finic/blob/main/LICENSE)
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
Python 3.11 or newer. Install the alpha release:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install langchain-finic==0.1.0a4
|
|
18
|
+
export FINIC_API_KEY=your_key
|
|
19
|
+
# Optional; defaults to grayson-1:
|
|
20
|
+
export FINIC_MODEL=grayson-1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Make a typed decision
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from langchain_finic import Choice, DecisionRequest, FinicClassifier, Noul
|
|
27
|
+
|
|
28
|
+
request = DecisionRequest(
|
|
29
|
+
state={"events": ["New device", "Transfer to an unfamiliar recipient"]},
|
|
30
|
+
questions={
|
|
31
|
+
"takeover": Noul(instructions="Does this evidence suggest account takeover?"),
|
|
32
|
+
"route": Choice(
|
|
33
|
+
instructions="Choose a review queue.",
|
|
34
|
+
criteria={"standard": "Routine review", "urgent": "Urgent investigation"},
|
|
35
|
+
),
|
|
36
|
+
},
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
with FinicClassifier() as classifier:
|
|
40
|
+
decision = classifier.invoke(request)
|
|
41
|
+
print(decision.nouls["takeover"].noul)
|
|
42
|
+
print(decision.choices["route"].choice)
|
|
43
|
+
print(decision.request_id)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`Noul`, `Choice`, `MultiChoice`, and `Score` have typed answers. Responses retain
|
|
47
|
+
probabilities, usage, and request metadata. Finic evaluates decisions; it does not
|
|
48
|
+
generate chat messages or text tokens.
|
|
49
|
+
|
|
50
|
+
## Compose with LangChain and LangGraph
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
# request is defined above.
|
|
54
|
+
with FinicClassifier() as classifier:
|
|
55
|
+
route_chain = classifier | (lambda result: result.choices["route"].choice)
|
|
56
|
+
route = route_chain.invoke(request, config={"tags": ["risk-review"]})
|
|
57
|
+
tool = classifier.as_tool()
|
|
58
|
+
print(tool.name) # finic_decide; pass it to create_agent or ToolNode
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
import asyncio
|
|
63
|
+
|
|
64
|
+
async def review():
|
|
65
|
+
async with FinicClassifier() as classifier:
|
|
66
|
+
return await classifier.abatch([request], config={"max_concurrency": 1})
|
|
67
|
+
|
|
68
|
+
results = asyncio.run(review())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Batching makes individual API requests; concurrency is controlled by Runnable config.
|
|
72
|
+
Streaming yields one complete decision. A chat-provider model can call the Finic tool
|
|
73
|
+
through `create_agent`; the Finic integration itself is a decision Runnable.
|
|
74
|
+
|
|
75
|
+
## Optional middleware
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install 'langchain-finic[middleware]==0.1.0a4'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`ModelRouterMiddleware` selects among host chat models. `AutoModeMiddleware` screens
|
|
82
|
+
specified tools before execution. See the complete
|
|
83
|
+
[middleware example](https://github.com/supreplabs/langchain-finic/blob/main/examples/middleware_agent.py)
|
|
84
|
+
and [configuration guide](https://supreplabs.github.io/langchain-finic/usage/).
|
|
85
|
+
Tool screening is probabilistic; application authorization remains necessary.
|
|
86
|
+
|
|
87
|
+
## Configuration and data
|
|
88
|
+
|
|
89
|
+
Use `FINIC_API_KEY`, `FINIC_MODEL`, `FINIC_TIMEOUT_SECONDS`, and `FINIC_MAX_ATTEMPTS`,
|
|
90
|
+
or constructor options. The library does not load `.env`. The host controls optional
|
|
91
|
+
LangSmith tracing, which can record request data and responses. Default timeout is
|
|
92
|
+
60 seconds, with up to three attempts; retries can incur additional charges.
|
|
93
|
+
Use context managers to reuse and close owned HTTP clients. Injected clients remain
|
|
94
|
+
caller-owned. Read the [usage guide](https://supreplabs.github.io/langchain-finic/usage/)
|
|
95
|
+
for precedence, serialization, resource lifetimes, and error handling.
|
|
96
|
+
|
|
97
|
+
## Development
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
uv sync --locked --group dev --extra middleware
|
|
101
|
+
make check
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Default tests use mocked HTTP with network disabled. Opt-in live tests spend Finic
|
|
105
|
+
credits. See [contributing](https://github.com/supreplabs/langchain-finic/blob/main/CONTRIBUTING.md)
|
|
106
|
+
and [security reporting](https://github.com/supreplabs/langchain-finic/blob/main/SECURITY.md).
|
|
107
|
+
|
|
108
|
+
References: [Finic API](https://docs.finic.ai/reference/decide),
|
|
109
|
+
[LangChain integration guidelines](https://docs.langchain.com/oss/python/contributing/integrations-langchain).
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Releasing
|
|
2
|
+
|
|
3
|
+
Release target: **0.1.0a4**, repository **supreplabs/langchain-finic**.
|
|
4
|
+
The package remains alpha. A release is complete only when PyPI installation is verified.
|
|
5
|
+
|
|
6
|
+
## One-time account setup
|
|
7
|
+
|
|
8
|
+
Create separate accounts on [PyPI](https://pypi.org/account/register/) and
|
|
9
|
+
[TestPyPI](https://test.pypi.org/account/register/). Verify each email address and
|
|
10
|
+
configure two-factor authentication (security key/passkey or authenticator), saving
|
|
11
|
+
recovery codes privately. Do not share passwords, recovery codes, or API keys here.
|
|
12
|
+
|
|
13
|
+
Register a **pending publisher** on each site's account publishing page:
|
|
14
|
+
[PyPI](https://pypi.org/manage/account/publishing/) and
|
|
15
|
+
[TestPyPI](https://test.pypi.org/manage/account/publishing/).
|
|
16
|
+
Choose GitHub Actions and enter these exact values:
|
|
17
|
+
|
|
18
|
+
| Field | TestPyPI | PyPI |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| PyPI project name | `langchain-finic` | `langchain-finic` |
|
|
21
|
+
| GitHub owner | `supreplabs` | `supreplabs` |
|
|
22
|
+
| Repository name | `langchain-finic` | `langchain-finic` |
|
|
23
|
+
| Workflow filename | `release.yml` | `release.yml` |
|
|
24
|
+
| Environment name | `testpypi` | `pypi` |
|
|
25
|
+
|
|
26
|
+
Pending publishers create the project on first successful upload; they do not reserve
|
|
27
|
+
its name. If a project already exists, verify ownership and configure its publisher
|
|
28
|
+
through the project settings. Never rename or upload to another project automatically.
|
|
29
|
+
No PyPI API token or `PYPI_TOKEN` GitHub secret is needed.
|
|
30
|
+
|
|
31
|
+
Reference: [PyPI pending publishers](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/).
|
|
32
|
+
|
|
33
|
+
## Repository configuration
|
|
34
|
+
|
|
35
|
+
GitHub environments `testpypi` and `pypi` permit deployments only from tags matching
|
|
36
|
+
`v*`. Enable GitHub Pages with GitHub Actions as the source, private vulnerability
|
|
37
|
+
reporting, and required CI checks on the default branch. CI and documentation builds
|
|
38
|
+
need no API credentials. Publishing jobs alone receive OIDC permission.
|
|
39
|
+
|
|
40
|
+
## Validate and release
|
|
41
|
+
|
|
42
|
+
1. Update `pyproject.toml` version and changelog, run `uv lock`, and commit the release.
|
|
43
|
+
2. Run `make install` and `make check`. Confirm all compatibility CI jobs pass.
|
|
44
|
+
3. Inspect wheel/sdist contents, generated documentation, and `scripts/check_dist.py`
|
|
45
|
+
hash output. No benchmark datasets, research code, credentials, or case artifacts
|
|
46
|
+
belong in this repository or its distributions.
|
|
47
|
+
4. Confirm both pending publishers are configured and the package name is still
|
|
48
|
+
available to this maintainer. Create and push the matching version tag:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git tag -a v0.1.0a4 -m 'Release 0.1.0a4'
|
|
52
|
+
git push origin v0.1.0a4
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The release workflow reruns CI, checks the tag against metadata, builds the release
|
|
56
|
+
wheel and sdist once, and uploads immutable workflow artifacts with SHA-256 hashes.
|
|
57
|
+
It publishes to TestPyPI, retrieves the exact files and checks their hashes, then
|
|
58
|
+
installs the wheel in a fresh environment. Dependencies are resolved from PyPI only;
|
|
59
|
+
TestPyPI is not used as an extra dependency index.
|
|
60
|
+
|
|
61
|
+
The same artifacts are then published to PyPI with attestations, downloaded and
|
|
62
|
+
hash-verified, and installed by exact public version. A GitHub prerelease is created
|
|
63
|
+
only after installation succeeds. All action references are pinned to commit SHAs.
|
|
64
|
+
|
|
65
|
+
If publishing succeeds but a later job fails, rerun failed jobs in the **same run**
|
|
66
|
+
to preserve the exact build artifacts. Existing files are skipped during upload,
|
|
67
|
+
but registry hash verification still requires an exact match. Do not rebuild and
|
|
68
|
+
replace an already published version; use a new version for changed artifacts.
|
|
69
|
+
`workflow_dispatch` must be dispatched on the version tag, not `main`.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install langchain-finic==0.1.0a4
|
|
73
|
+
pip install 'langchain-finic[middleware]==0.1.0a4'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Live smoke checks
|
|
77
|
+
|
|
78
|
+
Default tests and installation checks use mock HTTP and spend no credits. To make
|
|
79
|
+
two explicit live requests with fictional data:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
export FINIC_API_KEY=your_key
|
|
83
|
+
make integration_test
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Do not commit the key or record production inputs. Tests verify the response contract,
|
|
87
|
+
not an exact probability. No live calls run in pull requests or release CI.
|
|
88
|
+
|
|
89
|
+
## After publication
|
|
90
|
+
|
|
91
|
+
Use [listing metadata](LANGCHAIN_LISTING.md) for a LangChain integration listing request; do not
|
|
92
|
+
claim LangChain or Finic endorsement. Obtain maintainer authorization before submitting
|
|
93
|
+
an issue on their behalf.
|
|
94
|
+
|
|
95
|
+
If a release is broken, publish a corrected version and consider yanking the bad
|
|
96
|
+
version with a clear reason. Do not delete published files or move release tags.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
Security fixes target the latest published alpha. Older pre-releases are not maintained.
|
|
4
|
+
|
|
5
|
+
Use [GitHub private vulnerability reporting](https://github.com/supreplabs/langchain-finic/security/advisories/new).
|
|
6
|
+
Include affected versions, reproduction steps, impact, and a minimal example with fake
|
|
7
|
+
credentials and synthetic data. Do not disclose vulnerabilities through public issues.
|
|
8
|
+
|
|
9
|
+
The library sends request state and questions to Finic. Host-enabled LangSmith tracing
|
|
10
|
+
can also record inputs and responses. The application controls consent, access checks,
|
|
11
|
+
redaction, tracing, retention, and environment loading. The configured API key is excluded from
|
|
12
|
+
configuration representations and serialized values. Request state and caller metadata
|
|
13
|
+
are not automatically redacted. Load serialized objects only from
|
|
14
|
+
trusted sources. Tool screening is probabilistic and does not grant authorization.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# API reference
|
|
2
|
+
|
|
3
|
+
## Classifier
|
|
4
|
+
|
|
5
|
+
::: langchain_finic.classifier.FinicClassifier
|
|
6
|
+
options:
|
|
7
|
+
members: [model, api_key, timeout, max_attempts, client, http_client, http_async_client, transport, async_transport, invoke, ainvoke, as_tool, close, aclose, to_json]
|
|
8
|
+
|
|
9
|
+
Inherited Runnable methods such as `batch`, `abatch`, `bind`, and `with_config`
|
|
10
|
+
follow the [LangChain Runnable interface](https://reference.langchain.com/python/langchain-core/runnables).
|
|
11
|
+
See the [usage guide](usage.md) for resource lifetime and invocation behavior.
|
|
12
|
+
|
|
13
|
+
## HTTP client and errors
|
|
14
|
+
|
|
15
|
+
::: langchain_finic.client.FinicClient
|
|
16
|
+
options:
|
|
17
|
+
members: [__init__, decide, adecide, close, aclose]
|
|
18
|
+
|
|
19
|
+
::: langchain_finic.client.FinicError
|
|
20
|
+
|
|
21
|
+
## Request and response types
|
|
22
|
+
|
|
23
|
+
::: langchain_finic.models
|
|
24
|
+
options:
|
|
25
|
+
members: [DecisionRequest, DecisionResponse, Noul, Choice, MultiChoice, Score, NoulAnswer, ChoiceAnswer, MultiChoiceAnswer, ScoreAnswer]
|
|
26
|
+
|
|
27
|
+
`Noul` and `Score` are public aliases. Their fields are defined by the following schemas:
|
|
28
|
+
|
|
29
|
+
::: langchain_finic.models.NoulQuestion
|
|
30
|
+
|
|
31
|
+
::: langchain_finic.models.ScoreQuestion
|
|
32
|
+
|
|
33
|
+
`Choice` and `MultiChoice` share the fields defined by `ChoiceQuestion`:
|
|
34
|
+
|
|
35
|
+
::: langchain_finic.models.ChoiceQuestion
|
|
36
|
+
|
|
37
|
+
## Optional middleware
|
|
38
|
+
|
|
39
|
+
Requires `langchain-finic[middleware]`.
|
|
40
|
+
|
|
41
|
+
::: langchain_finic.middleware
|
|
42
|
+
options:
|
|
43
|
+
members: [ModelChoice, ModelRouterMiddleware, AutoModeMiddleware, ModelRouterState]
|