Skip to content

Commit 1e2c77f

Browse files
pranavjanaTest User
andauthored
Add LangChain TinyFish integration (#14)
* Add SDK-backed LangChain TinyFish tools Bumps the TinyFish Python SDK dependency to 0.2.5 and exposes SDK-backed LangChain tools for web search, content fetch, and browser session creation. Updates package metadata, README examples, unit coverage, and adds LangChain CI plus PyPI trusted-publishing workflows. * Address LangChain CodeRabbit review findings Stop SSE consumption after terminal events, validate fetch URL counts, skip integration tests without credentials, and add CI build coverage. * Install build in LangChain CI Add the build package to LangChain dev requirements so the CI packaging smoke test can run python -m build. * Publish LangChain only when PyPI needs the version Align the LangChain integration with the ADK package release path: push-to-main builds the package, skips already-published versions, and uploads with the provisioned PyPI token. Also align Python metadata with the tinyfish SDK floor before the first publish.\n\nConstraint: tinyfish 0.2.5 requires Python >=3.11 and PYPI_API_TOKEN is the repo secret provisioned through github-control.\nRejected: tag-only trusted publishing | this repo is using first-release publish-on-main for these integration packages.\nConfidence: high\nScope-risk: narrow\nTested: YAML parsed; PyPI guard returned missing for langchain-tinyfish 0.1.0; uv build --python 3.13; twine check; make lint; make test.\nNot-tested: live GitHub Actions publish, because it only runs after merge to main. * Document how integration package versions publish Keep release-process guidance outside package READMEs so it does not become PyPI project description content.\n\nConstraint: Python publish workflows read versions from pyproject.toml and use the repo PYPI_API_TOKEN secret.\nRejected: package README docs | package READMEs are published as public PyPI descriptions.\nConfidence: high\nScope-risk: narrow\nTested: git diff --check .github/README.md.\nNot-tested: GitHub Actions, documentation-only change. * Guide maintainer-only workflow docs Make the workflow subtree preserve release-process guidance outside package READMEs, which are reused as PyPI descriptions.\n\nConstraint: .github guidance applies only to repo automation and maintainer docs.\nRejected: package-level guidance | package READMEs are public package metadata.\nConfidence: high\nScope-risk: narrow\nTested: git diff --check .github/AGENTS.md.\nNot-tested: GitHub Actions, documentation-only change. --------- Co-authored-by: Test User <test@example.com>
1 parent 4fecb95 commit 1e2c77f

26 files changed

Lines changed: 2421 additions & 0 deletions

.github/AGENTS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# GitHub workflow guidance
2+
3+
This directory contains maintainer-facing repository automation and notes.
4+
5+
- Keep release-process documentation in `.github/README.md` or another maintainer-only repo doc, not in package `README.md` files that become PyPI project descriptions.
6+
- Python package publish workflows should read package name/version from the package `pyproject.toml`, check PyPI for that exact version, and skip publishing if it already exists.
7+
- Do not add automatic version bumping to publish workflows unless the release process is explicitly redesigned; package version bumps should be reviewed in PRs.
8+
- Use the repository `PYPI_API_TOKEN` Actions secret for token-based PyPI publishing. Never commit token values or package credentials.
9+
- Keep publish workflows scoped by `paths` to the package directory and the workflow file so unrelated merges do not trigger package release jobs.

.github/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Maintainer notes
2+
3+
This file is for repository maintainers. Do not copy release-process notes into an integration package `README.md`: package READMEs are used as PyPI project descriptions.
4+
5+
## Python integration releases
6+
7+
Python integration publish workflows do not bump package versions automatically. Each workflow reads the package name and version from that integration's `pyproject.toml`, checks PyPI for that exact version, and publishes only when the version does not already exist.
8+
9+
To publish a new version:
10+
11+
1. Update the package version in the relevant `pyproject.toml`.
12+
2. Commit the version bump with the code change.
13+
3. Merge to `main`.
14+
4. Let the push-to-`main` publish workflow run.
15+
16+
Current Python package version files:
17+
18+
| Integration | Package | Version file |
19+
| --- | --- | --- |
20+
| Google ADK | `tinyfish-adk` | `google-adk/pyproject.toml` |
21+
| CrewAI | `tinyfish-web-agent` | `crew-ai/pyproject.toml` |
22+
| LangChain | `langchain-tinyfish` | `langchain/pyproject.toml` |
23+
24+
PyPI versions are immutable. If a version has already been published, bump to a new version such as a patch release before merging.
25+
26+
The publish workflows use the repository `PYPI_API_TOKEN` Actions secret provisioned through `github-control`; never commit token values or package credentials.

.github/workflows/langchain-ci.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: LangChain CI
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
paths:
7+
- ".github/workflows/langchain-ci.yml"
8+
- "langchain/**"
9+
push:
10+
branches: [main]
11+
paths:
12+
- ".github/workflows/langchain-ci.yml"
13+
- "langchain/**"
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
test:
20+
runs-on: ubuntu-latest
21+
22+
defaults:
23+
run:
24+
working-directory: langchain
25+
26+
steps:
27+
- uses: actions/checkout@v6
28+
29+
- uses: actions/setup-python@v6
30+
with:
31+
python-version: "3.12"
32+
33+
- run: python -m pip install --upgrade pip
34+
35+
- run: python -m pip install -e . -r requirements-dev.txt
36+
37+
- run: make lint
38+
39+
- run: make test
40+
41+
- run: python -m build
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: LangChain CD - Publish to PyPI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- ".github/workflows/langchain-publish.yml"
8+
- "langchain/**"
9+
10+
jobs:
11+
build:
12+
name: Build distribution
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
outputs:
17+
version-exists: ${{ steps.version.outputs.exists }}
18+
package-version: ${{ steps.version.outputs.version }}
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v6
22+
23+
- name: Set up Python
24+
uses: actions/setup-python@v6
25+
with:
26+
python-version: "3.12"
27+
28+
- name: Install uv
29+
uses: astral-sh/setup-uv@v8.1.0
30+
31+
- name: Check PyPI version availability
32+
id: version
33+
working-directory: ./langchain
34+
run: |
35+
PACKAGE=$(python -c "import tomllib; f=open('pyproject.toml','rb'); d=tomllib.load(f); print(d['project']['name'])")
36+
VERSION=$(python -c "import tomllib; f=open('pyproject.toml','rb'); d=tomllib.load(f); print(d['project']['version'])")
37+
echo "package=${PACKAGE}" >> "$GITHUB_OUTPUT"
38+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
39+
RESULT=$(python - "$PACKAGE" "$VERSION" <<'PY'
40+
import sys
41+
import urllib.error
42+
import urllib.parse
43+
import urllib.request
44+
45+
package = sys.argv[1]
46+
version = sys.argv[2]
47+
url = f"https://pypi.org/pypi/{urllib.parse.quote(package)}/{version}/json"
48+
try:
49+
with urllib.request.urlopen(url, timeout=10):
50+
pass
51+
except urllib.error.HTTPError as exc:
52+
if exc.code == 404:
53+
print("missing")
54+
sys.exit(0)
55+
print(f"PyPI returned HTTP {exc.code} while checking {url}", file=sys.stderr)
56+
sys.exit(2)
57+
except Exception as exc:
58+
print(f"Failed to check PyPI for {url}: {exc}", file=sys.stderr)
59+
sys.exit(2)
60+
print("exists")
61+
PY
62+
)
63+
case "$RESULT" in
64+
exists)
65+
echo "exists=true" >> "$GITHUB_OUTPUT"
66+
echo "${PACKAGE} ${VERSION} already exists on PyPI; skipping publish."
67+
;;
68+
missing)
69+
echo "exists=false" >> "$GITHUB_OUTPUT"
70+
echo "${PACKAGE} ${VERSION} is available on PyPI; building distribution."
71+
;;
72+
*)
73+
echo "Unexpected PyPI availability result: $RESULT"
74+
exit 1
75+
;;
76+
esac
77+
78+
- name: Build package
79+
if: steps.version.outputs.exists == 'false'
80+
working-directory: ./langchain
81+
run: uv build
82+
83+
- name: Upload distribution artifact
84+
if: steps.version.outputs.exists == 'false'
85+
uses: actions/upload-artifact@v7
86+
with:
87+
name: python-package-distributions
88+
path: langchain/dist/
89+
90+
publish-pypi:
91+
name: Publish to PyPI
92+
needs: build
93+
if: needs.build.outputs.version-exists == 'false'
94+
runs-on: ubuntu-latest
95+
steps:
96+
- name: Download distributions
97+
uses: actions/download-artifact@v8
98+
with:
99+
name: python-package-distributions
100+
path: dist/
101+
102+
- name: Publish to PyPI
103+
uses: pypa/gh-action-pypi-publish@release/v1
104+
with:
105+
packages-dir: dist/
106+
password: ${{ secrets.PYPI_API_TOKEN }}

langchain/.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
*.egg-info/
2+
*.egg
3+
dist/
4+
build/
5+
__pycache__/
6+
*.pyc
7+
*.pyo
8+
.env
9+
.claude/
10+
.mypy_cache/
11+
.ruff_cache/
12+
.pytest_cache/

langchain/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 TinyFish
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.

langchain/Makefile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.PHONY: all format lint test integration_test check_imports clean
2+
3+
all: format lint test
4+
5+
TEST_FILE ?= tests/unit_tests/
6+
integration_test: TEST_FILE = tests/integration_tests/
7+
8+
format:
9+
ruff format langchain_tinyfish tests
10+
ruff check --fix langchain_tinyfish tests
11+
12+
lint:
13+
ruff check langchain_tinyfish tests
14+
mypy langchain_tinyfish
15+
16+
test integration_test:
17+
pytest $(TEST_FILE) -v
18+
19+
check_imports: $(shell find langchain_tinyfish -name '*.py')
20+
python scripts/check_imports.py $^
21+
22+
clean:
23+
rm -rf build dist *.egg-info .pytest_cache .mypy_cache .ruff_cache
24+
find . -type d -name __pycache__ -exec rm -rf {} +

0 commit comments

Comments
 (0)