From 6d912f79b9b00836f00c00f735c9f1df5773442c Mon Sep 17 00:00:00 2001 From: Kurtis Van Gent <31518063+kurtisvg@users.noreply.github.com> Date: Wed, 5 Feb 2025 03:06:53 +0000 Subject: [PATCH 1/3] chore: seperate sdk from server repo --- .../integration.cloudbuild.yaml | 8 +- .github/CODEOWNERS | 6 + .github/ISSUE_TEMPLATE/bug_report.md | 43 ++++ .github/ISSUE_TEMPLATE/feature_request.md | 18 ++ .github/ISSUE_TEMPLATE/support_request.md | 7 + .../PULL_REQUEST_TEMPLATE.md | 7 + .github/auto-label.yaml | 15 ++ .github/header-checker-lint.yml | 31 +++ .github/labels.yaml | 70 ++++++ .github/release-please.yml | 17 ++ .github/release-trigger.yml | 15 ++ .github/renovate.json5 | 45 ++++ .github/sync-repo-settings.yaml | 41 ++++ .../cloud_build_failure_reporter.yml | 179 ++++++++++++++++ .github/workflows/lint.yaml | 78 +++++++ .github/workflows/lint_fallback.yml | 28 +++ .github/workflows/schedule_reporter.yml | 25 +++ .github/workflows/sync-labels.yaml | 37 ++++ .gitignore | 5 + CONTRIBUTING.md | 33 +++ LICENSE | 202 ++++++++++++++++++ 21 files changed, 906 insertions(+), 4 deletions(-) rename integration.cloudbuild.yaml => .ci/integration.cloudbuild.yaml (88%) create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/support_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/auto-label.yaml create mode 100644 .github/header-checker-lint.yml create mode 100644 .github/labels.yaml create mode 100644 .github/release-please.yml create mode 100644 .github/release-trigger.yml create mode 100644 .github/renovate.json5 create mode 100644 .github/sync-repo-settings.yaml create mode 100644 .github/workflows/cloud_build_failure_reporter.yml create mode 100644 .github/workflows/lint.yaml create mode 100644 .github/workflows/lint_fallback.yml create mode 100644 .github/workflows/schedule_reporter.yml create mode 100644 .github/workflows/sync-labels.yaml create mode 100644 .gitignore create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE diff --git a/integration.cloudbuild.yaml b/.ci/integration.cloudbuild.yaml similarity index 88% rename from integration.cloudbuild.yaml rename to .ci/integration.cloudbuild.yaml index 70b30a57..be02d2a1 100644 --- a/integration.cloudbuild.yaml +++ b/.ci/integration.cloudbuild.yaml @@ -1,4 +1,4 @@ -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,14 +18,14 @@ steps: args: - install - '-r' - - 'sdks/langchain/requirements.txt' + - './requirements.txt' - '--user' entrypoint: pip - id: Install test requirements name: 'python:${_VERSION}' args: - install - - 'sdks/langchain[test]' + - '.[test]' - '--user' entrypoint: pip - id: Run integration tests @@ -37,7 +37,7 @@ steps: args: - '-c' - >- - python -m pytest sdks/langchain/tests/ + python -m pytest ./tests/ entrypoint: /bin/bash options: logging: CLOUD_LOGGING_ONLY diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..39c75e75 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,6 @@ +# This file controls who is tagged for review for any given pull request. +# +# For syntax help see: +# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax + +* @googleapis/senseai-eco \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..2170d838 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,43 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +Thanks for stopping by to let us know something could be better! + +**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. + +Please run down the following list and make sure you've tried the usual "quick fixes": + + - Search the issues already opened: https://github.com/googleapis/genai-toolbox-langchain-python/issues + - Search StackOverflow: https://stackoverflow.com/questions/tagged/google-cloud-platform+python + +If you are still having issues, please be sure to include as much information as possible: + +#### Environment details + + - OS type and version: + - Python version: `python --version` + - pip version: `pip --version` + - `toolbox-langchain-sdk` version: `pip show toolbox-langchain-sdk` + +#### Steps to reproduce + + 1. ? + 2. ? + +#### Code example + +```python +# example +``` + +#### Stack trace +``` +# example +``` + +Making sure to follow these steps will guarantee the quickest resolution possible. + +Thanks! \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..b8d7217c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature request +about: Suggest an idea for this library + +--- + +Thanks for stopping by to let us know something could be better! + +**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. + + **Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + **Describe the solution you'd like** +A clear and concise description of what you want to happen. + **Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + **Additional context** +Add any other context or screenshots about the feature request here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/support_request.md b/.github/ISSUE_TEMPLATE/support_request.md new file mode 100644 index 00000000..9e5b2532 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support_request.md @@ -0,0 +1,7 @@ +--- +name: Support request +about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. + +--- + +**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..38406c1d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: +- [ ] Make sure to open an issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea +- [ ] Ensure the tests and linter pass +- [ ] Communicate test infrastructure changes, i.e. API enablement, secrets +- [ ] Appropriate docs were updated (if necessary) + +🛠️ Fixes # \ No newline at end of file diff --git a/.github/auto-label.yaml b/.github/auto-label.yaml new file mode 100644 index 00000000..57437684 --- /dev/null +++ b/.github/auto-label.yaml @@ -0,0 +1,15 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +enabled: false diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml new file mode 100644 index 00000000..42529751 --- /dev/null +++ b/.github/header-checker-lint.yml @@ -0,0 +1,31 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Presubmit test that ensures that source files contain valid license headers +# https://github.com/googleapis/repo-automation-bots/tree/main/packages/header-checker-lint +# Install: https://github.com/apps/license-header-lint-gcf + +allowedCopyrightHolders: + - "Google LLC" +allowedLicenses: + - "Apache-2.0" +sourceFileExtensions: + - "yaml" + - "yml" + - "sh" + - "proto" + - "Dockerfile" + - "py" + - "text" \ No newline at end of file diff --git a/.github/labels.yaml b/.github/labels.yaml new file mode 100644 index 00000000..552ca4de --- /dev/null +++ b/.github/labels.yaml @@ -0,0 +1,70 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: duplicate + color: ededed + description: "" + +- name: 'type: bug' + color: db4437 + description: Error or flaw in code with unintended results or allowing sub-optimal + usage patterns. +- name: 'type: cleanup' + color: c5def5 + description: An internal cleanup or hygiene concern. +- name: 'type: docs' + color: 0000A0 + description: Improvement to the documentation for an API. +- name: 'type: feature request' + color: c5def5 + description: ‘Nice-to-have’ improvement, new feature or different behavior or design. +- name: 'type: process' + color: c5def5 + description: A process-related concern. May include testing, release, or the like. +- name: 'type: question' + color: c5def5 + description: Request for information or clarification. + +- name: 'priority: p0' + color: b60205 + description: Highest priority. Critical issue. P0 implies highest priority. +- name: 'priority: p1' + color: ffa03e + description: Important issue which blocks shipping the next release. Will be fixed + prior to next release. +- name: 'priority: p2' + color: fef2c0 + description: Moderately-important priority. Fix may not be included in next release. +- name: 'priority: p3' + color: ffffc7 + description: Desirable enhancement or fix. May not be included in next release. + +- name: do not merge + color: d93f0b + description: Indicates a pull request not ready for merge, due to either quality + or timing. + +- name: 'autorelease: pending' + color: ededed + description: Release please needs to do its work on this. +- name: 'autorelease: triggered' + color: ededed + description: Release please has triggered a release for this. +- name: 'autorelease: tagged' + color: ededed + description: Release please has completed a release for this. + +- name: 'tests: run' + color: 3DED97 + description: Label to trigger Github Action tests. diff --git a/.github/release-please.yml b/.github/release-please.yml new file mode 100644 index 00000000..b2d5cdf0 --- /dev/null +++ b/.github/release-please.yml @@ -0,0 +1,17 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +handleGHRelease: true +packageName: genai-toolbox-langchain-python +releaseType: python diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml new file mode 100644 index 00000000..15c5a82d --- /dev/null +++ b/.github/release-trigger.yml @@ -0,0 +1,15 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +enabled: true \ No newline at end of file diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 00000000..61a303ac --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,45 @@ +{ + "extends": [ + "config:base", // https://docs.renovatebot.com/presets-config/#configbase + ":semanticCommits", // https://docs.renovatebot.com/presets-default/#semanticcommits + ":ignoreUnstable", // https://docs.renovatebot.com/presets-default/#ignoreunstable + "group:allNonMajor", // https://docs.renovatebot.com/presets-group/#groupallnonmajor + ":separateMajorReleases", // https://docs.renovatebot.com/presets-default/#separatemajorreleases + ":prConcurrentLimitNone", // View complete backlog as PRs. https://docs.renovatebot.com/presets-default/#prconcurrentlimitnone + ":prHourlyLimitNone", // https://docs.renovatebot.com/presets-default/#prhourlylimitnone + ":preserveSemverRanges" + ], + + // Give ecosystem time to catch up. + // npm allows maintainers to unpublish a release up to 3 days later. + // https://docs.renovatebot.com/configuration-options/#minimumreleaseage + "minimumReleaseAge": "3", + + // Create PRs, but do not update them without manual action. + // Reduces spurious retesting in repositories that have many PRs at a time. + // https://docs.renovatebot.com/configuration-options/#rebasewhen + "rebaseWhen": "conflicted", + + // Organizational processes. + // https://docs.renovatebot.com/configuration-options/#dependencydashboardlabels + "dependencyDashboardLabels": [ + "type: process" + ], + "packageRules": [ + { + "groupName": "GitHub Actions", + "matchManagers": ["github-actions"], + "pinDigests": true + }, + // Python Specific + { + "matchPackageNames": ["pytest"], + "matchUpdateTypes": ["minor", "major"] + }, + { + "groupName": "python-nonmajor", + "matchLanguages": ["python"], + "matchUpdateTypes": ["minor", "patch"] + } + ] +} \ No newline at end of file diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml new file mode 100644 index 00000000..3e117dd3 --- /dev/null +++ b/.github/sync-repo-settings.yaml @@ -0,0 +1,41 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Synchronize repository settings from a centralized config +# https://github.com/googleapis/repo-automation-bots/tree/main/packages/sync-repo-settings +# Install: https://github.com/apps/sync-repo-settings + +# Disable merge commits +rebaseMergeAllowed: true +squashMergeAllowed: true +mergeCommitAllowed: false +# Enable branch protection +branchProtectionRules: + - pattern: main + isAdminEnforced: true + requiredStatusCheckContexts: + - "cla/google" + - "lint" + - "conventionalcommits.org" + - "header-check" + # - Add required status checks like presubmit tests + - "langchain-python-sdk-pr-py313 (toolbox-testing-438616)" + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: true + +# Set team access +permissionRules: + - team: senseai-eco + permission: admin \ No newline at end of file diff --git a/.github/workflows/cloud_build_failure_reporter.yml b/.github/workflows/cloud_build_failure_reporter.yml new file mode 100644 index 00000000..39116bbf --- /dev/null +++ b/.github/workflows/cloud_build_failure_reporter.yml @@ -0,0 +1,179 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Cloud Build Failure Reporter + +on: + workflow_call: + inputs: + trigger_names: + required: true + type: string + workflow_dispatch: + inputs: + trigger_names: + description: 'Cloud Build trigger names separated by comma.' + required: true + default: '' + +jobs: + report: + + permissions: + issues: 'write' + checks: 'read' + + runs-on: 'ubuntu-latest' + + steps: + - uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # v7 + with: + script: |- + // parse test names + const testNameSubstring = '${{ inputs.trigger_names }}'; + const testNameFound = new Map(); //keeps track of whether each test is found + testNameSubstring.split(',').forEach(testName => { + testNameFound.set(testName, false); + }); + + // label for all issues opened by reporter + const periodicLabel = 'periodic-failure'; + + // check if any reporter opened any issues previously + const prevIssues = await github.paginate(github.rest.issues.listForRepo, { + ...context.repo, + state: 'open', + creator: 'github-actions[bot]', + labels: [periodicLabel] + }); + + // createOrCommentIssue creates a new issue or comments on an existing issue. + const createOrCommentIssue = async function (title, txt) { + if (prevIssues.length < 1) { + console.log('no previous issues found, creating one'); + await github.rest.issues.create({ + ...context.repo, + title: title, + body: txt, + labels: [periodicLabel] + }); + return; + } + // only comment on issue related to the current test + for (const prevIssue of prevIssues) { + if (prevIssue.title.includes(title)){ + console.log( + `found previous issue ${prevIssue.html_url}, adding comment` + ); + + await github.rest.issues.createComment({ + ...context.repo, + issue_number: prevIssue.number, + body: txt + }); + return; + } + } + }; + + // updateIssues comments on any existing issues. No-op if no issue exists. + const updateIssues = async function (checkName, txt) { + if (prevIssues.length < 1) { + console.log('no previous issues found.'); + return; + } + // only comment on issue related to the current test + for (const prevIssue of prevIssues) { + if (prevIssue.title.includes(checkName)){ + console.log(`found previous issue ${prevIssue.html_url}, adding comment`); + await github.rest.issues.createComment({ + ...context.repo, + issue_number: prevIssue.number, + body: txt + }); + } + } + }; + + // Find status of check runs. + // We will find check runs for each commit and then filter for the periodic. + // Checks API only allows for ref and if we use main there could be edge cases where + // the check run happened on a SHA that is different from head. + const commits = await github.paginate(github.rest.repos.listCommits, { + ...context.repo + }); + + const relevantChecks = new Map(); + for (const commit of commits) { + console.log( + `checking runs at ${commit.html_url}: ${commit.commit.message}` + ); + const checks = await github.rest.checks.listForRef({ + ...context.repo, + ref: commit.sha + }); + + // Iterate through each check and find matching names + for (const check of checks.data.check_runs) { + console.log(`Handling test name ${check.name}`); + for (const testName of testNameFound.keys()) { + if (testNameFound.get(testName) === true){ + //skip if a check is already found for this name + continue; + } + if (check.name.includes(testName)) { + relevantChecks.set(check, commit); + testNameFound.set(testName, true); + } + } + } + // Break out of the loop early if all tests are found + const allTestsFound = Array.from(testNameFound.values()).every(value => value === true); + if (allTestsFound){ + break; + } + } + + // Handle each relevant check + relevantChecks.forEach((commit, check) => { + if ( + check.status === 'completed' && + check.conclusion === 'success' + ) { + updateIssues( + check.name, + `[Tests are passing](${check.html_url}) for commit [${commit.sha}](${commit.html_url}).` + ); + } else if (check.status === 'in_progress') { + console.log( + `Check is pending ${check.html_url} for ${commit.html_url}. Retry again later.` + ); + } else { + createOrCommentIssue( + `Cloud Build Failure Reporter: ${check.name} failed`, + `Cloud Build Failure Reporter found test failure for [**${check.name}** ](${check.html_url}) at [${commit.sha}](${commit.html_url}). Please fix the error and then close the issue after the **${check.name}** test passes.` + ); + } + }); + + // no periodic checks found across all commits, report it + const noTestFound = Array.from(testNameFound.values()).every(value => value === false); + if (noTestFound){ + createOrCommentIssue( + 'Missing periodic tests: ${{ inputs.trigger_names }}', + `No periodic test is found for triggers: ${{ inputs.trigger_names }}. Last checked from ${ + commits[0].html_url + } to ${commits[commits.length - 1].html_url}.` + ); + } diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 00000000..a77f8627 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,78 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: lint +on: + pull_request: + pull_request_target: + types: [labeled] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + lint: + if: "${{ github.event.action != 'labeled' || github.event.label.name == 'tests: run' }}" + name: lint + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: + contents: 'read' + issues: 'write' + pull-requests: 'write' + steps: + - name: Remove PR Label + if: "${{ github.event.action == 'labeled' && github.event.label.name == 'tests: run' }}" + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + await github.rest.issues.removeLabel({ + name: 'tests: run', + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number + }); + } catch (e) { + console.log('Failed to remove label. Another job may have already removed it!'); + } + - name: Checkout code + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ github.event.pull_request.head.sha }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + token: ${{ secrets.GITHUB_TOKEN }} + - name: Setup Python + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + with: + python-version: "3.13" + + - name: Install library requirements + run: pip install -r requirements.txt + + - name: Install test requirements + run: pip install .[test] + + - name: Run linters + run: | + black --check . + isort --check . + + - name: Run type-check + env: + MYPYPATH: './src' + run: mypy --install-types --non-interactive --cache-dir=.mypy_cache/ -p toolbox_langchain_sdk \ No newline at end of file diff --git a/.github/workflows/lint_fallback.yml b/.github/workflows/lint_fallback.yml new file mode 100644 index 00000000..f43b681a --- /dev/null +++ b/.github/workflows/lint_fallback.yml @@ -0,0 +1,28 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: lint +on: + pull_request: + paths: # These paths are the inverse of lint.yml + - "**/*.md" + +jobs: + lint: + runs-on: ubuntu-latest + permissions: + contents: none + + steps: + - run: echo "No tests required." \ No newline at end of file diff --git a/.github/workflows/schedule_reporter.yml b/.github/workflows/schedule_reporter.yml new file mode 100644 index 00000000..25f6bfab --- /dev/null +++ b/.github/workflows/schedule_reporter.yml @@ -0,0 +1,25 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Schedule Reporter + +on: + schedule: + - cron: '0 6 * * *' # Runs at 6 AM every morning + +jobs: + run_reporter: + uses: ./.github/workflows/cloud_build_failure_reporter.yml + with: + trigger_names: "langchain-python-sdk-test-nightly,langchain-python-sdk-test-on-merge" \ No newline at end of file diff --git a/.github/workflows/sync-labels.yaml b/.github/workflows/sync-labels.yaml new file mode 100644 index 00000000..22df93c9 --- /dev/null +++ b/.github/workflows/sync-labels.yaml @@ -0,0 +1,37 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Sync Labels +on: + push: + branches: + - main + +# Declare default permissions as read only. +permissions: read-all + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: 'read' + issues: 'write' + pull-requests: 'write' + steps: + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c # v1.3.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + manifest: .github/labels.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..04fd2c0b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# direnv +.envrc + +# vscode +.vscode/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..bc23aaed --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,33 @@ +# How to contribute + +We'd love to accept your patches and contributions to this project. + +## Before you begin + +### Sign our Contributor License Agreement + +Contributions to this project must be accompanied by a +[Contributor License Agreement](https://cla.developers.google.com/about) (CLA). +You (or your employer) retain the copyright to your contribution; this simply +gives us permission to use and redistribute your contributions as part of the +project. + +If you or your current employer have already signed the Google CLA (even if it +was for a different project), you probably don't need to do it again. + +Visit to see your current agreements or to +sign a new one. + +### Review our community guidelines + +This project follows +[Google's Open Source Community Guidelines](https://opensource.google/conduct/). + +## Contribution process + +### Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..7a4a3ea2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file From 51485b1ef9e536f7e10e8c53f1e5335be262b519 Mon Sep 17 00:00:00 2001 From: Kurtis Van Gent <31518063+kurtisvg@users.noreply.github.com> Date: Wed, 5 Feb 2025 03:29:34 +0000 Subject: [PATCH 2/3] chore: remove duplicated lint --- .github/workflows/lint_fallback.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/lint_fallback.yml diff --git a/.github/workflows/lint_fallback.yml b/.github/workflows/lint_fallback.yml deleted file mode 100644 index f43b681a..00000000 --- a/.github/workflows/lint_fallback.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: lint -on: - pull_request: - paths: # These paths are the inverse of lint.yml - - "**/*.md" - -jobs: - lint: - runs-on: ubuntu-latest - permissions: - contents: none - - steps: - - run: echo "No tests required." \ No newline at end of file From 959d6a97aaa1ae836e132d9ad69d0fcb71715ac2 Mon Sep 17 00:00:00 2001 From: Kurtis Van Gent <31518063+kurtisvg@users.noreply.github.com> Date: Wed, 5 Feb 2025 15:21:26 +0000 Subject: [PATCH 3/3] chore: add addl changes --- CODE_OF_CONDUCT.md | 94 ++++++++++++++++++++++++++++++++++++++++++++++ DEVELOPER.md | 11 +++--- README.md | 4 +- SECURITY.md | 7 ++++ 4 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 SECURITY.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..2add2547 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,94 @@ + +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + +Reports should be directed to *googleapis-stewards@google.com*, the +Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/DEVELOPER.md b/DEVELOPER.md index f6c120db..4634c7bd 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -5,11 +5,12 @@ Below are the details to set up a development environment and run tests. ## Install 1. Clone the repository: ```bash - git clone https://github.com/googleapis/genai-toolbox.git + + git clone https://github.com/googleapis/genai-toolbox-langchain-python ``` -1. Navigate to the SDK directory: +1. Navigate to the repo directory: ```bash - cd genai-toolbox/sdks/langchain + cd genai-toolbox-langchain-python ``` 1. Install the package in editable mode, so changes are reflected without reinstall: @@ -21,9 +22,9 @@ Below are the details to set up a development environment and run tests. > those changes reflected immediately without reinstalling the package. ## Test -1. Navigate to the SDK directory: +1. Navigate to the repo directory if needed: ```bash - cd genai-toolbox/sdks/langchain + cd genai-toolbox-langchain-python ``` 1. Install the SDK and test dependencies: ```bash diff --git a/README.md b/README.md index c44b7733..19094a7c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# GenAI Toolbox SDK +# GenAI Toolbox LangChain SDK This SDK allows you to seamlessly integrate the functionalities of -[Toolbox](https://github.com/googleapis/genai-toolbox) into your LLM +[Toolbox](https://github.com/googleapis/genai-toolbox) into your LangChain LLM applications, enabling advanced orchestration and interaction with GenAI models. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..8b58ae9c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). + +The Google Security Team will respond within 5 working days of your report on g.co/vulnz. + +We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue.