diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b05db38 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "nuget" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + groups: + all: + patterns: + - "*" diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 0000000..0d502c5 --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,39 @@ +name: Auto-approve and auto-merge bot pull requests +on: + pull_request: + branches: + - main + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + runs-on: ubuntu-latest + if: ${{ (github.actor == 'dependabot[bot]' || github.actor == 'HavenDV') && github.repository_owner == 'tryAGI' }} + steps: + - name: Dependabot metadata + if: ${{ github.actor == 'dependabot[bot]' }} + id: metadata + uses: dependabot/fetch-metadata@0fb21704c18a42ce5aa8d720ea4b912f5e6babef + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Show sender + run: echo ${{ github.event.pull_request.sender }} + + - name: Show triggering_actor + run: echo ${{ github.triggering_actor }} + + - name: Approve a PR + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Enable auto-merge + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/auto-update.yml b/.github/workflows/auto-update.yml new file mode 100644 index 0000000..de29132 --- /dev/null +++ b/.github/workflows/auto-update.yml @@ -0,0 +1,63 @@ +name: Opens a new PR if there are OpenAPI updates +on: + schedule: + - cron: '0 */3 * * *' + +permissions: + contents: write + pull-requests: write + actions: write + +jobs: + check-openapi-updates: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Git user + run: | + git config --local user.email "dependabot@bot.com" + git config --local user.name "github-actions[bot]" + + - name: Generate branch name + id: branch + run: echo "branch_name=bot/update-openapi_$(date +'%Y%m%d%H%M')" >> $GITHUB_OUTPUT + + - name: Create branch + run: | + git checkout -b ${{ steps.branch.outputs.branch_name }} origin/main + git rebase main + + - name: Generate code + run: | + cd src/libs/Tavily + chmod +x ./generate.sh + ./generate.sh + + - name: Check for changes + id: changes + run: | + CHANGED=$(git diff --name-only) + if [ -z "$CHANGED" ]; then + echo "has_changes=false" >> $GITHUB_OUTPUT + else + echo "has_changes=true" >> $GITHUB_OUTPUT + fi + + - name: Push changes + if: steps.changes.outputs.has_changes == 'true' + run: | + git add . + git commit -m "feat: Updated OpenAPI spec" + git push --force-with-lease -u origin ${{ steps.branch.outputs.branch_name }} + + - name: Wait for 15 seconds + if: steps.changes.outputs.has_changes == 'true' + run: sleep 15 + + - name: Create pull request + if: steps.changes.outputs.has_changes == 'true' + run: gh pr create -B main -H ${{ steps.branch.outputs.branch_name }} --title 'feat:@coderabbitai' --body '@coderabbitai summary' + env: + GITHUB_TOKEN: ${{ secrets.PERSONAL_TOKEN }} diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 0000000..83e1276 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,38 @@ +name: Publish +on: + push: + branches: + - main + tags: + - v** + +permissions: + contents: write + +jobs: + publish: + name: Publish + uses: HavenDV/workflows/.github/workflows/dotnet_build-test-publish.yml@main + with: + generate-build-number: false + conventional-commits-publish-conditions: false + enable-caching: false + additional-test-arguments: '--logger GitHubActions' + secrets: + nuget-key: ${{ secrets.NUGET_KEY }} + + release: + name: Release + runs-on: ubuntu-latest + needs: [publish] + if: startsWith(github.ref, 'refs/tags/v') + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create release + run: gh release create ${{ github.ref_name }} + --title "${{ github.ref_name }}" + --generate-notes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml new file mode 100644 index 0000000..f846e82 --- /dev/null +++ b/.github/workflows/mkdocs.yml @@ -0,0 +1,57 @@ +name: MKDocs Deploy +on: + push: + branches: + - main + paths: + - 'docs/**' + - 'mkdocs.yml' + - 'src/helpers/GenerateDocs/**' + - '.github/workflows/mkdocs.yml' + - 'src/tests/IntegrationTests/**' + - 'README.md' + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Install dependencies + run: pip install mkdocs-material + + - name: Generate docs + run: dotnet run --project src/helpers/GenerateDocs/GenerateDocs.csproj . + + - name: Build with MkDocs + run: mkdocs build -d ./_site + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..3c50ca1 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,15 @@ +name: Test +on: + pull_request: + branches: + - main + +jobs: + test: + name: Test + uses: HavenDV/workflows/.github/workflows/dotnet_build-test-publish.yml@main + with: + generate-build-number: false + conventional-commits-publish-conditions: false + enable-caching: false + additional-test-arguments: '--logger GitHubActions' \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..370da60 --- /dev/null +++ b/.gitignore @@ -0,0 +1,399 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +/.idea/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..193bba6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 tryAGI + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2b411b1 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# Tavily + +[![Nuget package](https://img.shields.io/nuget/vpre/Tavily)](https://www.nuget.org/packages/Tavily/) +[![dotnet](https://github.com/tryAGI/Tavily/actions/workflows/dotnet.yml/badge.svg?branch=main)](https://github.com/tryAGI/Tavily/actions/workflows/dotnet.yml) +[![License: MIT](https://img.shields.io/github/license/tryAGI/Tavily)](https://github.com/tryAGI/Tavily/blob/main/LICENSE.txt) +[![Discord](https://img.shields.io/discord/1115206893015662663?label=Discord&logo=discord&logoColor=white&color=d82679)](https://discord.gg/Ca2xhfBf3v) + +## Features 🔥 +- Fully generated C# SDK based on [official Tavily OpenAPI specification](https://raw.githubusercontent.com/Tavily/assemblyai-api-spec/main/openapi.yml) using [AutoSDK](https://github.com/HavenDV/AutoSDK) +- Same day update to support new features +- Updated and supported automatically if there are no breaking changes +- All modern .NET features - nullability, trimming, NativeAOT, etc. +- Support .Net Framework/.Net Standard 2.0 + +### Usage +```csharp +using Tavily; + +using var client = new TavilyClient(apiKey); +``` + +## Support + +Priority place for bugs: https://github.com/tryAGI/Tavily/issues +Priority place for ideas and general questions: https://github.com/tryAGI/Tavily/discussions +Discord: https://discord.gg/Ca2xhfBf3v + +## Acknowledgments + +![JetBrains logo](https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png) + +This project is supported by JetBrains through the [Open Source Support Program](https://jb.gg/OpenSourceSupport). + +![CodeRabbit logo](https://opengraph.githubassets.com/1c51002d7d0bbe0c4fd72ff8f2e58192702f73a7037102f77e4dbb98ac00ea8f/marketplace/coderabbitai) + +This project is supported by CodeRabbit through the [Open Source Support Program](https://github.com/marketplace/coderabbitai). \ No newline at end of file diff --git a/Tavily.sln b/Tavily.sln new file mode 100644 index 0000000..e38f964 --- /dev/null +++ b/Tavily.sln @@ -0,0 +1,84 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30204.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E793AF18-4371-4EBD-96FC-195EB1798855}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + src\Directory.Build.props = src\Directory.Build.props + LICENSE = LICENSE + README.md = README.md + .github\dependabot.yml = .github\dependabot.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libs", "libs", "{61E7E11E-4558-434C-ACE8-06316A3097B3}" + ProjectSection(SolutionItems) = preProject + src\libs\Directory.Build.props = src\libs\Directory.Build.props + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{AAA11B78-2764-4520-A97E-46AA7089A588}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tavily", "src\libs\Tavily\Tavily.csproj", "{0028BC85-0064-4CE8-A21A-C1F5E922BD59}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tavily.IntegrationTests", "src\tests\IntegrationTests\Tavily.IntegrationTests.csproj", "{592ADBC9-C951-4AF7-A163-B6C63B970B19}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "helpers", "helpers", "{B761B212-7CAB-46A7-BB98-B76EDE56530D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FixOpenApiSpec", "src\helpers\FixOpenApiSpec\FixOpenApiSpec.csproj", "{67BDEAD9-10A3-4D84-8D71-ED3FCF8C30B8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenerateDocs", "src\helpers\GenerateDocs\GenerateDocs.csproj", "{2E33DFAF-4E36-4549-832E-202AAB6D1B52}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrimmingHelper", "src\helpers\TrimmingHelper\TrimmingHelper.csproj", "{4BB0367D-803F-430B-AE3B-853811C48A94}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{02762835-D98C-4E26-B6AC-992CC318DCEC}" + ProjectSection(SolutionItems) = preProject + .github\workflows\auto-merge.yml = .github\workflows\auto-merge.yml + .github\workflows\auto-update.yml = .github\workflows\auto-update.yml + .github\workflows\mkdocs.yml = .github\workflows\mkdocs.yml + .github\workflows\dotnet.yml = .github\workflows\dotnet.yml + .github\workflows\pull-request.yml = .github\workflows\pull-request.yml + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0028BC85-0064-4CE8-A21A-C1F5E922BD59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0028BC85-0064-4CE8-A21A-C1F5E922BD59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0028BC85-0064-4CE8-A21A-C1F5E922BD59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0028BC85-0064-4CE8-A21A-C1F5E922BD59}.Release|Any CPU.Build.0 = Release|Any CPU + {592ADBC9-C951-4AF7-A163-B6C63B970B19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {592ADBC9-C951-4AF7-A163-B6C63B970B19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {592ADBC9-C951-4AF7-A163-B6C63B970B19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {592ADBC9-C951-4AF7-A163-B6C63B970B19}.Release|Any CPU.Build.0 = Release|Any CPU + {67BDEAD9-10A3-4D84-8D71-ED3FCF8C30B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67BDEAD9-10A3-4D84-8D71-ED3FCF8C30B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67BDEAD9-10A3-4D84-8D71-ED3FCF8C30B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67BDEAD9-10A3-4D84-8D71-ED3FCF8C30B8}.Release|Any CPU.Build.0 = Release|Any CPU + {2E33DFAF-4E36-4549-832E-202AAB6D1B52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E33DFAF-4E36-4549-832E-202AAB6D1B52}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E33DFAF-4E36-4549-832E-202AAB6D1B52}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E33DFAF-4E36-4549-832E-202AAB6D1B52}.Release|Any CPU.Build.0 = Release|Any CPU + {4BB0367D-803F-430B-AE3B-853811C48A94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BB0367D-803F-430B-AE3B-853811C48A94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BB0367D-803F-430B-AE3B-853811C48A94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BB0367D-803F-430B-AE3B-853811C48A94}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {0028BC85-0064-4CE8-A21A-C1F5E922BD59} = {61E7E11E-4558-434C-ACE8-06316A3097B3} + {592ADBC9-C951-4AF7-A163-B6C63B970B19} = {AAA11B78-2764-4520-A97E-46AA7089A588} + {67BDEAD9-10A3-4D84-8D71-ED3FCF8C30B8} = {B761B212-7CAB-46A7-BB98-B76EDE56530D} + {2E33DFAF-4E36-4549-832E-202AAB6D1B52} = {B761B212-7CAB-46A7-BB98-B76EDE56530D} + {4BB0367D-803F-430B-AE3B-853811C48A94} = {B761B212-7CAB-46A7-BB98-B76EDE56530D} + {02762835-D98C-4E26-B6AC-992CC318DCEC} = {E793AF18-4371-4EBD-96FC-195EB1798855} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CED9A020-DBA5-4BE6-8096-75E528648EC1} + EndGlobalSection +EndGlobal diff --git a/assets/nuget-icon.png b/assets/nuget-icon.png new file mode 100644 index 0000000..25574ba Binary files /dev/null and b/assets/nuget-icon.png differ diff --git a/docs/css/extra.css b/docs/css/extra.css new file mode 100644 index 0000000..f217483 --- /dev/null +++ b/docs/css/extra.css @@ -0,0 +1,102 @@ +/* Logo title */ +.md-header__topic:first-child { + font-weight: initial !important; +} + +/* Code font size in
*/ +details .linenos, details code { + font-size: inherit !important; +} + +/* Code block / tab in details */ +details > summary + .highlight:last-child, details > summary + .tabbed-set:last-child { margin: 0 -0.6rem !important; } +details > summary + .highlight:last-child > .highlighttable { margin: 0 !important; } + +/* Table full width */ +.md-typeset__table { display: block !important; } +.md-typeset table:not(.highlighttable) { display: table !important; } + +.md-typeset table:not([class]) th { + min-width: 0rem; +} + +.headerlink { transform: translateY(-2.5px); } + +.md-nav__link[for=__toc] .md-icon { margin-left: auto !important; } + +blockquote.page-time { + margin: 20px 0 !important; + border-left-color: #64b5f6 !important; /* Just change the color value and that's it*/ +} +blockquote.page-copyright { + margin: 20px 0 !important; + border-left-color: #ff1700 !important; /* Just change the color value and that's it*/ +} +blockquote.page-copyright i.md-icon { + display: inline-block; + margin-right: 5px; + transform: translateY(3.5px); + width: 18px; +} + +#myBtn { + display: none; + position: fixed; + bottom: 100px; + right: 16px; + z-index: 99; + border: none; + outline: none; + color: #8590a6; + cursor: pointer; + padding: .7rem; + border-radius: .4rem; +} + +#myBtn:hover { + background-color: #d3d3d3; +} + +#color-button > button { + cursor: pointer; + transition: opacity .25s; + display: inline-block; + width: 6.5rem; + margin-bottom: 0.2rem; + padding: 1.2rem 0.4rem 0.2rem; + font-size: 0.64rem; + text-align: left; +} + +#color-button > button[data-md-color-primary] { + background-color: var(--md-primary-fg-color); + color: var(--md-primary-bg-color); +} +#color-button > button[data-md-color-primary=white] { + box-shadow: inset 0 0 0.05rem rgb(0 0 0 / 54%); +} + +#color-button > button[data-md-color-accent] { + background-color: var(--md-accent-fg-color); + color: var(--md-code-bg-color); +} + +mjx-container > img { + width: 0; + height: 0; +} + +[data-md-color-scheme="slate"] { + --md-primary-fg-color: #2e303e; + --md-accent-fg-color: #00bda4; + --md-typeset-a-color: #526cfe; +} + +[data-md-color-scheme="slate"] .md-typeset img { + background: white; + filter: brightness(0.9); +} + +[data-md-color-scheme="slate"] .md-typeset img[src$=".svg"] { + border: 4px solid white; +} \ No newline at end of file diff --git a/docs/media/icon128.png b/docs/media/icon128.png new file mode 100644 index 0000000..05d2b17 Binary files /dev/null and b/docs/media/icon128.png differ diff --git a/global.json b/global.json new file mode 100644 index 0000000..eafb435 --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "rollForward": "latestMajor", + "allowPrerelease": false + } +} \ No newline at end of file diff --git a/initialize.sh b/initialize.sh index d9068b0..d677c0a 100755 --- a/initialize.sh +++ b/initialize.sh @@ -1,8 +1,8 @@ dotnet tool install --global autosdk.cli --prerelease autosdk init \ - SolutionName \ - SomeClient \ - https://raw.githubusercontent.com/api/openapi.json \ - CompanyName \ + Tavily \ + TavilyClient \ + https://raw.githubusercontent.com/davidmigloz/langchain_dart/refs/heads/main/packages/tavily_dart/oas/tavily_openapi.yaml \ + tryAGI \ --output . diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..315bb1b --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,82 @@ +site_name: Tavily .NET Documentation +nav: +- Overview: index.md +# EXAMPLES # + +theme: + name: material + static_templates: + - 404.html + language: 'en' + palette: + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: white + accent: red + toggle: + icon: material/weather-sunny + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: blue + accent: blue + toggle: + icon: material/weather-night + name: Switch to light mode + include_search_page: false + search_index_only: true + favicon: 'media/icon128.png' + icon: + logo: 'material/file-document' + features: + - content.action.edit + - navigation.instant + font: + text: 'Fira Sans' + code: 'Fira Mono' + +extra: + version: + provider: mike + +extra_css: + - 'css/extra.css?v=14' + +markdown_extensions: + - admonition + - def_list + - footnotes + - meta + - toc: + permalink: "" + slugify: !!python/name:pymdownx.slugs.uslugify + - pymdownx.arithmatex: + generic: true + - pymdownx.caret + - pymdownx.critic + - pymdownx.details + - pymdownx.emoji: + emoji_generator: !!python/name:pymdownx.emoji.to_svg + - pymdownx.highlight: + linenums: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink + - pymdownx.mark + - pymdownx.snippets: + check_paths: true + - pymdownx.progressbar + - pymdownx.smartsymbols + - pymdownx.superfences: + custom_fences: + - name: math + class: arithmatex + format: !!python/name:pymdownx.arithmatex.fence_mathjax_format + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + - pymdownx.tabbed: + alternate_style: true \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000..86f2c1f --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,9 @@ + + + + preview + enable + enable + + + diff --git a/src/helpers/FixOpenApiSpec/FixOpenApiSpec.csproj b/src/helpers/FixOpenApiSpec/FixOpenApiSpec.csproj new file mode 100644 index 0000000..deaad92 --- /dev/null +++ b/src/helpers/FixOpenApiSpec/FixOpenApiSpec.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + Exe + preview + enable + enable + + + + + + + diff --git a/src/helpers/FixOpenApiSpec/Program.cs b/src/helpers/FixOpenApiSpec/Program.cs new file mode 100644 index 0000000..3cb0684 --- /dev/null +++ b/src/helpers/FixOpenApiSpec/Program.cs @@ -0,0 +1,33 @@ +using Microsoft.OpenApi; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Extensions; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Readers; + +var path = args[0]; +var text = await File.ReadAllTextAsync(path); + +text = text + .Replace("openapi: 3.1.0", "openapi: 3.0.1") + .Replace("\"openapi\":\"3.1.0\"", "\"openapi\":\"3.0.1\"") + ; + +var openApiDocument = new OpenApiStringReader().Read(text, out var diagnostics); + +//openApiDocument.Components.Schemas["GenerateCompletionRequest"]!.Properties["stream"]!.Default = new OpenApiBoolean(true); + +text = openApiDocument.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_0); +_ = new OpenApiStringReader().Read(text, out diagnostics); + +if (diagnostics.Errors.Count > 0) +{ + foreach (var error in diagnostics.Errors) + { + Console.WriteLine(error.Message); + } + // Return Exit code 1 + Environment.Exit(1); +} + +await File.WriteAllTextAsync(path, text); +return; \ No newline at end of file diff --git a/src/helpers/FixOpenApiSpec/Properties/launchSettings.json b/src/helpers/FixOpenApiSpec/Properties/launchSettings.json new file mode 100644 index 0000000..575aa6e --- /dev/null +++ b/src/helpers/FixOpenApiSpec/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "FixOpenApiSpec": { + "commandName": "Project", + "commandLineArgs": "../../../../../../src/libs/Tavily/openapi.yaml" + } + } +} \ No newline at end of file diff --git a/src/helpers/GenerateDocs/GenerateDocs.csproj b/src/helpers/GenerateDocs/GenerateDocs.csproj new file mode 100644 index 0000000..f67f521 --- /dev/null +++ b/src/helpers/GenerateDocs/GenerateDocs.csproj @@ -0,0 +1,9 @@ + + + + Exe + net8.0 + enable + + + diff --git a/src/helpers/GenerateDocs/Program.cs b/src/helpers/GenerateDocs/Program.cs new file mode 100644 index 0000000..3c58368 --- /dev/null +++ b/src/helpers/GenerateDocs/Program.cs @@ -0,0 +1,46 @@ +var solutionDirectory = args.ElementAtOrDefault(0) ?? Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "../../../../../..")); +var sampleDirectory = Path.Combine(solutionDirectory, "src", "tests", "IntegrationTests"); +var mkDocsPath = Path.Combine(solutionDirectory, "mkdocs.yml"); + +var newDir = Path.Combine(solutionDirectory, "docs", "samples"); +Directory.CreateDirectory(newDir); + +File.Copy( + Path.Combine(solutionDirectory, "README.md"), + Path.Combine(solutionDirectory, "docs", "index.md"), + overwrite: true); + +Console.WriteLine($"Generating samples from {sampleDirectory}..."); +foreach (var path in Directory.EnumerateFiles(sampleDirectory, "Tests.*.cs", SearchOption.AllDirectories)) +{ + var code = await File.ReadAllTextAsync(path); + + var start = code.IndexOf("\n {", StringComparison.Ordinal); + var end = code.IndexOf("\n }", StringComparison.Ordinal); + code = code.Substring(start + 4, end - start + 4); + + var lines = code.Split('\n')[1..^2]; + code = string.Join('\n', lines + .Where(x => !x.Contains(".Should()")) + .Select(x => x.Length > 8 ? x[8..] : string.Empty)); + + code = code + .Replace( + "using var client = GetAuthenticatedClient();", + "using var client = new TavilyClient(apiKey);") + ; + + var newPath = Path.Combine(newDir, $"{Path.GetExtension(Path.GetFileNameWithoutExtension(path)).TrimStart('.')}.md"); + await File.WriteAllTextAsync(newPath, $@"```csharp +{code} +```"); +} + +var mkDocs = await File.ReadAllTextAsync(mkDocsPath); +var newMkDocs = mkDocs.Replace( + "# EXAMPLES #", + $"- Examples:{string.Concat(Directory.EnumerateFiles(Path.Combine(solutionDirectory, "docs", "samples"), "*.md") + .Select(x => $@" + - {Path.GetFileNameWithoutExtension(x)}: samples/{Path.GetFileNameWithoutExtension(x)}.md"))}"); +await File.WriteAllTextAsync(mkDocsPath, newMkDocs); + diff --git a/src/helpers/TrimmingHelper/Program.cs b/src/helpers/TrimmingHelper/Program.cs new file mode 100644 index 0000000..3b94c99 --- /dev/null +++ b/src/helpers/TrimmingHelper/Program.cs @@ -0,0 +1 @@ +Console.WriteLine("Build, rebuild or publish this app to see trimming warnings."); \ No newline at end of file diff --git a/src/helpers/TrimmingHelper/TrimmingHelper.csproj b/src/helpers/TrimmingHelper/TrimmingHelper.csproj new file mode 100644 index 0000000..8f8f904 --- /dev/null +++ b/src/helpers/TrimmingHelper/TrimmingHelper.csproj @@ -0,0 +1,30 @@ + + + + Exe + net8.0 + enable + + true + + + + + + + + + + + + win-x64 + osx-arm64 + + true + + + + + + + diff --git a/src/key.snk b/src/key.snk new file mode 100644 index 0000000..4205bc6 Binary files /dev/null and b/src/key.snk differ diff --git a/src/libs/Directory.Build.props b/src/libs/Directory.Build.props new file mode 100644 index 0000000..f35f050 --- /dev/null +++ b/src/libs/Directory.Build.props @@ -0,0 +1,63 @@ + + + + + + true + $(MSBuildThisFileDirectory)../key.snk + + + + + <_Parameter1>true + + + + + true + true + tryAGI and contributors + MIT + nuget-icon.png + README.md + + + + + + + + + v + dev + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + true + latest + All + + + + true + true + true + false + false + + + diff --git a/src/libs/Tavily/Generated/JsonConverters.SearchRequestSearchDepth.g.cs b/src/libs/Tavily/Generated/JsonConverters.SearchRequestSearchDepth.g.cs new file mode 100644 index 0000000..2d9086e --- /dev/null +++ b/src/libs/Tavily/Generated/JsonConverters.SearchRequestSearchDepth.g.cs @@ -0,0 +1,49 @@ +#nullable enable + +namespace Tavily.JsonConverters +{ + /// + public sealed class SearchRequestSearchDepthJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + /// + public override global::Tavily.SearchRequestSearchDepth Read( + ref global::System.Text.Json.Utf8JsonReader reader, + global::System.Type typeToConvert, + global::System.Text.Json.JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case global::System.Text.Json.JsonTokenType.String: + { + var stringValue = reader.GetString(); + if (stringValue != null) + { + return global::Tavily.SearchRequestSearchDepthExtensions.ToEnum(stringValue) ?? default; + } + + break; + } + case global::System.Text.Json.JsonTokenType.Number: + { + var numValue = reader.GetInt32(); + return (global::Tavily.SearchRequestSearchDepth)numValue; + } + default: + throw new global::System.ArgumentOutOfRangeException(nameof(reader)); + } + + return default; + } + + /// + public override void Write( + global::System.Text.Json.Utf8JsonWriter writer, + global::Tavily.SearchRequestSearchDepth value, + global::System.Text.Json.JsonSerializerOptions options) + { + writer = writer ?? throw new global::System.ArgumentNullException(nameof(writer)); + + writer.WriteStringValue(global::Tavily.SearchRequestSearchDepthExtensions.ToValueString(value)); + } + } +} diff --git a/src/libs/Tavily/Generated/JsonConverters.SearchRequestSearchDepthNullable.g.cs b/src/libs/Tavily/Generated/JsonConverters.SearchRequestSearchDepthNullable.g.cs new file mode 100644 index 0000000..5ce63a3 --- /dev/null +++ b/src/libs/Tavily/Generated/JsonConverters.SearchRequestSearchDepthNullable.g.cs @@ -0,0 +1,56 @@ +#nullable enable + +namespace Tavily.JsonConverters +{ + /// + public sealed class SearchRequestSearchDepthNullableJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + /// + public override global::Tavily.SearchRequestSearchDepth? Read( + ref global::System.Text.Json.Utf8JsonReader reader, + global::System.Type typeToConvert, + global::System.Text.Json.JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case global::System.Text.Json.JsonTokenType.String: + { + var stringValue = reader.GetString(); + if (stringValue != null) + { + return global::Tavily.SearchRequestSearchDepthExtensions.ToEnum(stringValue); + } + + break; + } + case global::System.Text.Json.JsonTokenType.Number: + { + var numValue = reader.GetInt32(); + return (global::Tavily.SearchRequestSearchDepth)numValue; + } + default: + throw new global::System.ArgumentOutOfRangeException(nameof(reader)); + } + + return default; + } + + /// + public override void Write( + global::System.Text.Json.Utf8JsonWriter writer, + global::Tavily.SearchRequestSearchDepth? value, + global::System.Text.Json.JsonSerializerOptions options) + { + writer = writer ?? throw new global::System.ArgumentNullException(nameof(writer)); + + if (value == null) + { + writer.WriteNullValue(); + } + else + { + writer.WriteStringValue(global::Tavily.SearchRequestSearchDepthExtensions.ToValueString(value.Value)); + } + } + } +} diff --git a/src/libs/Tavily/Generated/JsonConverters.UnixTimestamp.g.cs b/src/libs/Tavily/Generated/JsonConverters.UnixTimestamp.g.cs new file mode 100644 index 0000000..e8dbba2 --- /dev/null +++ b/src/libs/Tavily/Generated/JsonConverters.UnixTimestamp.g.cs @@ -0,0 +1,39 @@ +#nullable enable + +namespace Tavily.JsonConverters +{ + /// + public class UnixTimestampJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + /// + public override global::System.DateTimeOffset Read( + ref global::System.Text.Json.Utf8JsonReader reader, + global::System.Type typeToConvert, + global::System.Text.Json.JsonSerializerOptions options) + { + if (reader.TokenType == global::System.Text.Json.JsonTokenType.Number) + { + if (reader.TryGetInt64(out long unixTimestamp)) + { + return global::System.DateTimeOffset.FromUnixTimeSeconds(unixTimestamp); + } + if (reader.TryGetInt32(out int unixTimestampInt)) + { + return global::System.DateTimeOffset.FromUnixTimeSeconds(unixTimestampInt); + } + } + + return default; + } + + /// + public override void Write( + global::System.Text.Json.Utf8JsonWriter writer, + global::System.DateTimeOffset value, + global::System.Text.Json.JsonSerializerOptions options) + { + long unixTimestamp = value.ToUnixTimeSeconds(); + writer.WriteNumberValue(unixTimestamp); + } + } +} diff --git a/src/libs/Tavily/Generated/JsonSerializerContext.g.cs b/src/libs/Tavily/Generated/JsonSerializerContext.g.cs new file mode 100644 index 0000000..353ca19 --- /dev/null +++ b/src/libs/Tavily/Generated/JsonSerializerContext.g.cs @@ -0,0 +1,24 @@ + +#nullable enable + +#pragma warning disable CS0618 // Type or member is obsolete +#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant + +namespace Tavily +{ + /// + /// + /// + [global::System.Text.Json.Serialization.JsonSourceGenerationOptions( + DefaultIgnoreCondition = global::System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, + Converters = new global::System.Type[] + { + typeof(global::Tavily.JsonConverters.SearchRequestSearchDepthJsonConverter), + typeof(global::Tavily.JsonConverters.SearchRequestSearchDepthNullableJsonConverter), + })] + + [global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Tavily.JsonSerializerContextTypes))] + public sealed partial class SourceGenerationContext : global::System.Text.Json.Serialization.JsonSerializerContext + { + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/JsonSerializerContextTypes.g.cs b/src/libs/Tavily/Generated/JsonSerializerContextTypes.g.cs new file mode 100644 index 0000000..673c29c --- /dev/null +++ b/src/libs/Tavily/Generated/JsonSerializerContextTypes.g.cs @@ -0,0 +1,59 @@ + +#nullable enable + +#pragma warning disable CS0618 // Type or member is obsolete + +namespace Tavily +{ + /// + /// + /// + public sealed partial class JsonSerializerContextTypes + { + /// + /// + /// + public global::System.Collections.Generic.Dictionary? StringStringDictionary { get; set; } + + /// + /// + /// + public global::Tavily.SearchRequest? Type0 { get; set; } + /// + /// + /// + public string? Type1 { get; set; } + /// + /// + /// + public global::Tavily.SearchRequestSearchDepth? Type2 { get; set; } + /// + /// + /// + public bool? Type3 { get; set; } + /// + /// + /// + public int? Type4 { get; set; } + /// + /// + /// + public global::System.Collections.Generic.IList? Type5 { get; set; } + /// + /// + /// + public global::Tavily.SearchResponse? Type6 { get; set; } + /// + /// + /// + public double? Type7 { get; set; } + /// + /// + /// + public global::System.Collections.Generic.IList? Type8 { get; set; } + /// + /// + /// + public global::Tavily.SearchResult? Type9 { get; set; } + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.ITavilyClient.Search.g.cs b/src/libs/Tavily/Generated/Tavily.ITavilyClient.Search.g.cs new file mode 100644 index 0000000..ba57258 --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.ITavilyClient.Search.g.cs @@ -0,0 +1,68 @@ +#nullable enable + +namespace Tavily +{ + public partial interface ITavilyClient + { + /// + /// Search for data based on a query. + /// + /// + /// The token to cancel the operation with + /// + global::System.Threading.Tasks.Task SearchAsync( + global::Tavily.SearchRequest request, + global::System.Threading.CancellationToken cancellationToken = default); + + /// + /// Search for data based on a query. + /// + /// + /// Your unique API key.
+ /// Example: your api key + /// + /// + /// The search query string.
+ /// Example: your search query + /// + /// + /// The depth of the search. It can be 'basic' or advanced. Default is 'basic'.
+ /// Default Value: basic + /// + /// + /// Include a list of query related images in the response. Default is False.
+ /// Default Value: false + /// + /// + /// Include answers in the search results. Default is False.
+ /// Default Value: false + /// + /// + /// Include raw content in the search results. Default is False.
+ /// Default Value: false + /// + /// + /// The number of maximum search results to return. Default is 5.
+ /// Default Value: 5 + /// + /// + /// A list of domains to specifically include in the search results. Default is None. + /// + /// + /// A list of domains to specifically exclude from the search results. Default is None. + /// + /// The token to cancel the operation with + /// + global::System.Threading.Tasks.Task SearchAsync( + string apiKey, + string query, + global::Tavily.SearchRequestSearchDepth? searchDepth = global::Tavily.SearchRequestSearchDepth.Basic, + bool? includeImages = false, + bool? includeAnswer = false, + bool? includeRawContent = false, + int? maxResults = 5, + global::System.Collections.Generic.IList? includeDomains = default, + global::System.Collections.Generic.IList? excludeDomains = default, + global::System.Threading.CancellationToken cancellationToken = default); + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.ITavilyClient.g.cs b/src/libs/Tavily/Generated/Tavily.ITavilyClient.g.cs new file mode 100644 index 0000000..82af6fa --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.ITavilyClient.g.cs @@ -0,0 +1,20 @@ + +#nullable enable + +namespace Tavily +{ + /// + /// Tavily Search is a robust search API tailored specifically for LLM Agents. It seamlessly integrates with diverse data sources to ensure a superior, relevant search experience.
+ /// If no httpClient is provided, a new one will be created.
+ /// If no baseUri is provided, the default baseUri from OpenAPI spec will be used. + ///
+ public partial interface ITavilyClient : global::System.IDisposable + { + /// + /// + /// + global::System.Text.Json.Serialization.JsonSerializerContext JsonSerializerContext { get; set; } + + + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.Models.SearchRequest.g.cs b/src/libs/Tavily/Generated/Tavily.Models.SearchRequest.g.cs new file mode 100644 index 0000000..0ea6479 --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.Models.SearchRequest.g.cs @@ -0,0 +1,81 @@ + +#nullable enable + +namespace Tavily +{ + /// + /// The search request object. + /// + public sealed partial class SearchRequest + { + /// + /// Your unique API key.
+ /// Example: your api key + ///
+ [global::System.Text.Json.Serialization.JsonPropertyName("api_key")] + [global::System.Text.Json.Serialization.JsonRequired] + public required string ApiKey { get; set; } + + /// + /// The search query string.
+ /// Example: your search query + ///
+ [global::System.Text.Json.Serialization.JsonPropertyName("query")] + [global::System.Text.Json.Serialization.JsonRequired] + public required string Query { get; set; } + + /// + /// The depth of the search. It can be 'basic' or advanced. Default is 'basic'.
+ /// Default Value: basic + ///
+ [global::System.Text.Json.Serialization.JsonPropertyName("search_depth")] + [global::System.Text.Json.Serialization.JsonConverter(typeof(global::Tavily.JsonConverters.SearchRequestSearchDepthJsonConverter))] + public global::Tavily.SearchRequestSearchDepth? SearchDepth { get; set; } = global::Tavily.SearchRequestSearchDepth.Basic; + + /// + /// Include a list of query related images in the response. Default is False.
+ /// Default Value: false + ///
+ [global::System.Text.Json.Serialization.JsonPropertyName("include_images")] + public bool? IncludeImages { get; set; } = false; + + /// + /// Include answers in the search results. Default is False.
+ /// Default Value: false + ///
+ [global::System.Text.Json.Serialization.JsonPropertyName("include_answer")] + public bool? IncludeAnswer { get; set; } = false; + + /// + /// Include raw content in the search results. Default is False.
+ /// Default Value: false + ///
+ [global::System.Text.Json.Serialization.JsonPropertyName("include_raw_content")] + public bool? IncludeRawContent { get; set; } = false; + + /// + /// The number of maximum search results to return. Default is 5.
+ /// Default Value: 5 + ///
+ [global::System.Text.Json.Serialization.JsonPropertyName("max_results")] + public int? MaxResults { get; set; } = 5; + + /// + /// A list of domains to specifically include in the search results. Default is None. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("include_domains")] + public global::System.Collections.Generic.IList? IncludeDomains { get; set; } + + /// + /// A list of domains to specifically exclude from the search results. Default is None. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("exclude_domains")] + public global::System.Collections.Generic.IList? ExcludeDomains { get; set; } + + /// + /// Additional properties that are not explicitly defined in the schema + /// + [global::System.Text.Json.Serialization.JsonExtensionData] + public global::System.Collections.Generic.IDictionary AdditionalProperties { get; set; } = new global::System.Collections.Generic.Dictionary(); + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.Models.SearchRequestSearchDepth.g.cs b/src/libs/Tavily/Generated/Tavily.Models.SearchRequestSearchDepth.g.cs new file mode 100644 index 0000000..9da959a --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.Models.SearchRequestSearchDepth.g.cs @@ -0,0 +1,52 @@ + +#nullable enable + +namespace Tavily +{ + /// + /// The depth of the search. It can be 'basic' or advanced. Default is 'basic'.
+ /// Default Value: basic + ///
+ public enum SearchRequestSearchDepth + { + /// + /// + /// + Basic, + /// + /// + /// + Advanced, + } + + /// + /// Enum extensions to do fast conversions without the reflection. + /// + public static class SearchRequestSearchDepthExtensions + { + /// + /// Converts an enum to a string. + /// + public static string ToValueString(this SearchRequestSearchDepth value) + { + return value switch + { + SearchRequestSearchDepth.Basic => "basic", + SearchRequestSearchDepth.Advanced => "advanced", + _ => throw new global::System.ArgumentOutOfRangeException(nameof(value), value, null), + }; + } + /// + /// Converts an string to a enum. + /// + public static SearchRequestSearchDepth? ToEnum(string value) + { + return value switch + { + "basic" => SearchRequestSearchDepth.Basic, + "advanced" => SearchRequestSearchDepth.Advanced, + _ => null, + }; + } + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.Models.SearchResponse.g.cs b/src/libs/Tavily/Generated/Tavily.Models.SearchResponse.g.cs new file mode 100644 index 0000000..c2120b1 --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.Models.SearchResponse.g.cs @@ -0,0 +1,56 @@ + +#nullable enable + +namespace Tavily +{ + /// + /// The response data from the search query. + /// + public sealed partial class SearchResponse + { + /// + /// The answer to your search query. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("answer")] + public string? Answer { get; set; } + + /// + /// Your search query. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("query")] + [global::System.Text.Json.Serialization.JsonRequired] + public required string Query { get; set; } + + /// + /// Your search result response time. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("response_time")] + [global::System.Text.Json.Serialization.JsonRequired] + public required double ResponseTime { get; set; } + + /// + /// A list of query related image urls. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("images")] + public global::System.Collections.Generic.IList? Images { get; set; } + + /// + /// A list of suggested research follow up questions related to original query. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("follow_up_questions")] + public global::System.Collections.Generic.IList? FollowUpQuestions { get; set; } + + /// + /// A list of search results. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("results")] + [global::System.Text.Json.Serialization.JsonRequired] + public required global::System.Collections.Generic.IList Results { get; set; } + + /// + /// Additional properties that are not explicitly defined in the schema + /// + [global::System.Text.Json.Serialization.JsonExtensionData] + public global::System.Collections.Generic.IDictionary AdditionalProperties { get; set; } = new global::System.Collections.Generic.Dictionary(); + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.Models.SearchResult.g.cs b/src/libs/Tavily/Generated/Tavily.Models.SearchResult.g.cs new file mode 100644 index 0000000..b29010f --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.Models.SearchResult.g.cs @@ -0,0 +1,51 @@ + +#nullable enable + +namespace Tavily +{ + /// + /// The search result object. + /// + public sealed partial class SearchResult + { + /// + /// The title of the search result url. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("title")] + [global::System.Text.Json.Serialization.JsonRequired] + public required string Title { get; set; } + + /// + /// The url of the search result. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("url")] + [global::System.Text.Json.Serialization.JsonRequired] + public required string Url { get; set; } + + /// + /// The most query related content from the scraped url. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("content")] + [global::System.Text.Json.Serialization.JsonRequired] + public required string Content { get; set; } + + /// + /// The parsed and cleaned HTML of the site. For now includes parsed text only. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("raw_content")] + public string? RawContent { get; set; } + + /// + /// The relevance score of the search result. + /// + [global::System.Text.Json.Serialization.JsonPropertyName("score")] + [global::System.Text.Json.Serialization.JsonRequired] + public required double Score { get; set; } + + /// + /// Additional properties that are not explicitly defined in the schema + /// + [global::System.Text.Json.Serialization.JsonExtensionData] + public global::System.Collections.Generic.IDictionary AdditionalProperties { get; set; } = new global::System.Collections.Generic.Dictionary(); + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.PathBuilder.g.cs b/src/libs/Tavily/Generated/Tavily.PathBuilder.g.cs new file mode 100644 index 0000000..68b23a6 --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.PathBuilder.g.cs @@ -0,0 +1,253 @@ +using System.Linq; + +#nullable enable + +namespace Tavily +{ + /// + /// A helper class to build URL paths with optional and required parameters. + /// + public class PathBuilder + { + private readonly global::System.Text.StringBuilder _stringBuilder = + new global::System.Text.StringBuilder(capacity: 256); + private bool _firstParameter = true; + + /// + /// Initializes a new instance of the class. + /// + /// The base path for the URL. + /// The base URI to prepend to the path, if any. + public PathBuilder( + string path, + global::System.Uri? baseUri = null) + { + if (baseUri is not null) + { + _stringBuilder.Append(baseUri.AbsoluteUri.TrimEnd('/')); + } + + _stringBuilder.Append(path); + } + + /// + /// Adds a required parameter to the URL. + /// + /// The name of the parameter. + /// The value of the parameter. + /// The current instance. + public PathBuilder AddRequiredParameter( + string name, + string value) + { + if (_firstParameter) + { + _stringBuilder.Append('?'); + _firstParameter = false; + } + else + { + _stringBuilder.Append('&'); + } + + _stringBuilder.Append(global::System.Uri.EscapeDataString(name)); + _stringBuilder.Append('='); + _stringBuilder.Append(global::System.Uri.EscapeDataString(value)); + + return this; + } + + /// + /// Adds a required parameter with multiple values to the URL. + /// + /// The name of the parameter. + /// The values of the parameter. + /// The delimiter to use between values. + /// Whether to explode the values into separate parameters. + /// The current instance. + public PathBuilder AddRequiredParameter( + string name, + global::System.Collections.Generic.IEnumerable value, + string delimiter = ",", + bool explode = false) + { + if (explode) + { + foreach (var item in value) + { + AddRequiredParameter($"{name}", item); + } + + return this; + } + + AddRequiredParameter(name, string.Join(delimiter, value)); + + return this; + } + + /// + /// Adds a required parameter with multiple values to the URL, using a selector function. + /// + /// The type of the values. + /// The name of the parameter. + /// The values of the parameter. + /// The function to select the string representation of each value. + /// The delimiter to use between values. + /// Whether to explode the values into separate parameters. + /// The current instance. + public PathBuilder AddRequiredParameter( + string name, + global::System.Collections.Generic.IEnumerable value, + global::System.Func selector, + string delimiter = ",", + bool explode = false) + { + AddRequiredParameter(name, value.Select(selector).ToArray(), delimiter, explode); + + return this; + } + + /// + /// Adds an optional parameter to the URL. + /// + /// The name of the parameter. + /// The value of the parameter, or null if not present. + /// The current instance. + public PathBuilder AddOptionalParameter( + string name, + string? value) + { + if (value is not null) + { + AddRequiredParameter(name, value); + } + + return this; + } + + /// + /// Adds an optional parameter with multiple values to the URL. + /// + /// The name of the parameter. + /// The values of the parameter, or null if not present. + /// The delimiter to use between values. + /// Whether to explode the values into separate parameters. + /// The current instance. + public PathBuilder AddOptionalParameter( + string name, + global::System.Collections.Generic.IEnumerable? value, + string delimiter = ",", + bool explode = false) + { + if (value is not null) + { + AddRequiredParameter(name, value, delimiter, explode); + } + + return this; + } + + /// + /// Adds an optional parameter with multiple values to the URL, using a selector function. + /// + /// The type of the values. + /// The name of the parameter. + /// The values of the parameter, or null if not present. + /// The function to select the string representation of each value. + /// The delimiter to use between values. + /// Whether to explode the values into separate parameters. + /// The current instance. + public PathBuilder AddOptionalParameter( + string name, + global::System.Collections.Generic.IEnumerable? value, + global::System.Func selector, + string delimiter = ",", + bool explode = false) + { + if (value is not null) + { + AddRequiredParameter(name, value.Select(selector).ToArray(), delimiter, explode); + } + + return this; + } + + /// + /// Adds a required parameter to the URL, using a formattable value. + /// + /// The type of the value. + /// The name of the parameter. + /// The value of the parameter. + /// The format string. + /// The format provider. + /// The current instance. + public PathBuilder AddRequiredParameter( + string name, + T value, + string? format = null, + global::System.IFormatProvider? formatProvider = null) + where T : global::System.IFormattable + { + AddRequiredParameter(name, value.ToString(format, formatProvider)); + + return this; + } + + /// + /// Adds an optional parameter to the URL, using a formattable value. + /// + /// The type of the value. + /// The name of the parameter. + /// The value of the parameter, or null if not present. + /// The format string. + /// The format provider. + /// The current instance. + public PathBuilder AddOptionalParameter( + string name, + T? value, + string? format = null, + global::System.IFormatProvider? formatProvider = null) + where T : global::System.IFormattable + { + if (value is not null) + { + AddOptionalParameter(name, value.ToString(format, formatProvider)); + } + + return this; + } + + /// + /// Returns the constructed URL as a string. + /// + /// The constructed URL. + public override string ToString() => _stringBuilder.ToString(); + } + + /// + /// + /// + public class EndPointAuthorization + { + /// + /// + /// + public string Type { get; set; } = string.Empty; + + /// + /// + /// + public string Location { get; set; } = string.Empty; + + /// + /// + /// + public string Name { get; set; } = string.Empty; + + /// + /// + /// + public string Value { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.Polyfills.g.cs b/src/libs/Tavily/Generated/Tavily.Polyfills.g.cs new file mode 100644 index 0000000..359ddc2 --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.Polyfills.g.cs @@ -0,0 +1,53 @@ + +#if !NET6_0_OR_GREATER +#nullable enable + +namespace Tavily +{ + /// + /// + /// + public static partial class AutoSDKPolyfills + { + /// + /// + /// + /// + /// + /// + public static global::System.Threading.Tasks.Task ReadAsStringAsync( + this global::System.Net.Http.HttpContent content, + global::System.Threading.CancellationToken cancellationToken) + { + content = content ?? throw new global::System.ArgumentNullException(nameof(content)); + return content.ReadAsStringAsync(); + } + /// + /// + /// + /// + /// + /// + public static global::System.Threading.Tasks.Task ReadAsStreamAsync( + this global::System.Net.Http.HttpContent content, + global::System.Threading.CancellationToken cancellationToken) + { + content = content ?? throw new global::System.ArgumentNullException(nameof(content)); + return content.ReadAsStreamAsync(); + } + /// + /// + /// + /// + /// + /// + public static global::System.Threading.Tasks.Task ReadAsByteArrayAsync( + this global::System.Net.Http.HttpContent content, + global::System.Threading.CancellationToken cancellationToken) + { + content = content ?? throw new global::System.ArgumentNullException(nameof(content)); + return content.ReadAsByteArrayAsync(); + } + } +} +#endif \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.TavilyClient.Search.g.cs b/src/libs/Tavily/Generated/Tavily.TavilyClient.Search.g.cs new file mode 100644 index 0000000..03453c8 --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.TavilyClient.Search.g.cs @@ -0,0 +1,170 @@ + +#nullable enable + +namespace Tavily +{ + public partial class TavilyClient + { + partial void PrepareSearchArguments( + global::System.Net.Http.HttpClient httpClient, + global::Tavily.SearchRequest request); + partial void PrepareSearchRequest( + global::System.Net.Http.HttpClient httpClient, + global::System.Net.Http.HttpRequestMessage httpRequestMessage, + global::Tavily.SearchRequest request); + partial void ProcessSearchResponse( + global::System.Net.Http.HttpClient httpClient, + global::System.Net.Http.HttpResponseMessage httpResponseMessage); + + partial void ProcessSearchResponseContent( + global::System.Net.Http.HttpClient httpClient, + global::System.Net.Http.HttpResponseMessage httpResponseMessage, + ref string content); + + /// + /// Search for data based on a query. + /// + /// + /// The token to cancel the operation with + /// + public async global::System.Threading.Tasks.Task SearchAsync( + global::Tavily.SearchRequest request, + global::System.Threading.CancellationToken cancellationToken = default) + { + request = request ?? throw new global::System.ArgumentNullException(nameof(request)); + + PrepareArguments( + client: _httpClient); + PrepareSearchArguments( + httpClient: _httpClient, + request: request); + + var __pathBuilder = new PathBuilder( + path: "/search", + baseUri: _httpClient.BaseAddress); + var __path = __pathBuilder.ToString(); + using var httpRequest = new global::System.Net.Http.HttpRequestMessage( + method: global::System.Net.Http.HttpMethod.Post, + requestUri: new global::System.Uri(__path, global::System.UriKind.RelativeOrAbsolute)); + var __httpRequestContentBody = global::System.Text.Json.JsonSerializer.Serialize(request, request.GetType(), JsonSerializerContext); + var __httpRequestContent = new global::System.Net.Http.StringContent( + content: __httpRequestContentBody, + encoding: global::System.Text.Encoding.UTF8, + mediaType: "application/json"); + httpRequest.Content = __httpRequestContent; + + PrepareRequest( + client: _httpClient, + request: httpRequest); + PrepareSearchRequest( + httpClient: _httpClient, + httpRequestMessage: httpRequest, + request: request); + + using var response = await _httpClient.SendAsync( + request: httpRequest, + completionOption: global::System.Net.Http.HttpCompletionOption.ResponseContentRead, + cancellationToken: cancellationToken).ConfigureAwait(false); + + ProcessResponse( + client: _httpClient, + response: response); + ProcessSearchResponse( + httpClient: _httpClient, + httpResponseMessage: response); + + var __content = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + + ProcessResponseContent( + client: _httpClient, + response: response, + content: ref __content); + ProcessSearchResponseContent( + httpClient: _httpClient, + httpResponseMessage: response, + content: ref __content); + + try + { + response.EnsureSuccessStatusCode(); + } + catch (global::System.Net.Http.HttpRequestException ex) + { + throw new global::System.InvalidOperationException(__content, ex); + } + + return + global::System.Text.Json.JsonSerializer.Deserialize(__content, typeof(global::Tavily.SearchResponse), JsonSerializerContext) as global::Tavily.SearchResponse ?? + throw new global::System.InvalidOperationException($"Response deserialization failed for \"{__content}\" "); + } + + /// + /// Search for data based on a query. + /// + /// + /// Your unique API key.
+ /// Example: your api key + /// + /// + /// The search query string.
+ /// Example: your search query + /// + /// + /// The depth of the search. It can be 'basic' or advanced. Default is 'basic'.
+ /// Default Value: basic + /// + /// + /// Include a list of query related images in the response. Default is False.
+ /// Default Value: false + /// + /// + /// Include answers in the search results. Default is False.
+ /// Default Value: false + /// + /// + /// Include raw content in the search results. Default is False.
+ /// Default Value: false + /// + /// + /// The number of maximum search results to return. Default is 5.
+ /// Default Value: 5 + /// + /// + /// A list of domains to specifically include in the search results. Default is None. + /// + /// + /// A list of domains to specifically exclude from the search results. Default is None. + /// + /// The token to cancel the operation with + /// + public async global::System.Threading.Tasks.Task SearchAsync( + string apiKey, + string query, + global::Tavily.SearchRequestSearchDepth? searchDepth = global::Tavily.SearchRequestSearchDepth.Basic, + bool? includeImages = false, + bool? includeAnswer = false, + bool? includeRawContent = false, + int? maxResults = 5, + global::System.Collections.Generic.IList? includeDomains = default, + global::System.Collections.Generic.IList? excludeDomains = default, + global::System.Threading.CancellationToken cancellationToken = default) + { + var request = new global::Tavily.SearchRequest + { + ApiKey = apiKey, + Query = query, + SearchDepth = searchDepth, + IncludeImages = includeImages, + IncludeAnswer = includeAnswer, + IncludeRawContent = includeRawContent, + MaxResults = maxResults, + IncludeDomains = includeDomains, + ExcludeDomains = excludeDomains, + }; + + return await SearchAsync( + request: request, + cancellationToken: cancellationToken).ConfigureAwait(false); + } + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Generated/Tavily.TavilyClient.g.cs b/src/libs/Tavily/Generated/Tavily.TavilyClient.g.cs new file mode 100644 index 0000000..c2db25c --- /dev/null +++ b/src/libs/Tavily/Generated/Tavily.TavilyClient.g.cs @@ -0,0 +1,68 @@ + +#nullable enable + +namespace Tavily +{ + /// + /// Tavily Search is a robust search API tailored specifically for LLM Agents. It seamlessly integrates with diverse data sources to ensure a superior, relevant search experience.
+ /// If no httpClient is provided, a new one will be created.
+ /// If no baseUri is provided, the default baseUri from OpenAPI spec will be used. + ///
+ public sealed partial class TavilyClient : global::Tavily.ITavilyClient, global::System.IDisposable + { + /// + /// + /// + public const string BaseUrl = "https://api.tavily.com"; + + private readonly global::System.Net.Http.HttpClient _httpClient; + private global::System.Collections.Generic.List _authorizations; + + /// + /// + /// + public global::System.Text.Json.Serialization.JsonSerializerContext JsonSerializerContext { get; set; } = global::Tavily.SourceGenerationContext.Default; + + + /// + /// Creates a new instance of the TavilyClient. + /// If no httpClient is provided, a new one will be created. + /// If no baseUri is provided, the default baseUri from OpenAPI spec will be used. + /// + /// + /// + /// + public TavilyClient( + global::System.Net.Http.HttpClient? httpClient = null, + global::System.Uri? baseUri = null, + global::System.Collections.Generic.List? authorizations = null) + { + _httpClient = httpClient ?? new global::System.Net.Http.HttpClient(); + _httpClient.BaseAddress ??= baseUri ?? new global::System.Uri(BaseUrl); + _authorizations = authorizations ?? new global::System.Collections.Generic.List(); + + Initialized(_httpClient); + } + + /// + public void Dispose() + { + _httpClient.Dispose(); + } + + partial void Initialized( + global::System.Net.Http.HttpClient client); + partial void PrepareArguments( + global::System.Net.Http.HttpClient client); + partial void PrepareRequest( + global::System.Net.Http.HttpClient client, + global::System.Net.Http.HttpRequestMessage request); + partial void ProcessResponse( + global::System.Net.Http.HttpClient client, + global::System.Net.Http.HttpResponseMessage response); + partial void ProcessResponseContent( + global::System.Net.Http.HttpClient client, + global::System.Net.Http.HttpResponseMessage response, + ref string content); + } +} \ No newline at end of file diff --git a/src/libs/Tavily/Tavily.csproj b/src/libs/Tavily/Tavily.csproj new file mode 100644 index 0000000..2ed0f71 --- /dev/null +++ b/src/libs/Tavily/Tavily.csproj @@ -0,0 +1,24 @@ + + + + netstandard2.0;net4.6.2;net6.0;net8.0 + + + + C# SDK based on Tavily OpenAPI specification. + api;client;sdk;dotnet;swagger;openapi;specification;generated;nswag + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/src/libs/Tavily/generate.sh b/src/libs/Tavily/generate.sh new file mode 100644 index 0000000..6b4ad50 --- /dev/null +++ b/src/libs/Tavily/generate.sh @@ -0,0 +1,14 @@ +dotnet tool install --global autosdk.cli --prerelease +rm -rf Generated +curl -o openapi.yaml https://raw.githubusercontent.com/davidmigloz/langchain_dart/refs/heads/main/packages/tavily_dart/oas/tavily_openapi.yaml +dotnet run --project ../../helpers/FixOpenApiSpec openapi.yaml +if [ $? -ne 0 ]; then + echo "Failed, exiting..." + exit 1 +fi +autosdk generate openapi.yaml \ + --namespace Tavily \ + --clientClassName TavilyClient \ + --targetFramework net8.0 \ + --output Generated \ + --exclude-deprecated-operations \ No newline at end of file diff --git a/src/libs/Tavily/openapi.yaml b/src/libs/Tavily/openapi.yaml new file mode 100644 index 0000000..db2cac9 --- /dev/null +++ b/src/libs/Tavily/openapi.yaml @@ -0,0 +1,152 @@ +openapi: 3.0.1 +info: + title: Tavily API + description: 'Tavily Search is a robust search API tailored specifically for LLM Agents. It seamlessly integrates with diverse data sources to ensure a superior, relevant search experience.' + contact: + name: Tavily Support + url: https://tavily.com + version: 1.0.0 +servers: + - url: https://api.tavily.com +paths: + /search: + post: + summary: Search for data based on a query. + operationId: search + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SearchRequest' + required: true + responses: + '200': + description: Successful search response. + content: + application/json: + schema: + $ref: '#/components/schemas/SearchResponse' + '400': + description: Bad Request — Your request is invalid. + '401': + description: Unauthorized — Your API key is wrong. + '403': + description: Forbidden — The endpoint requested is hidden for administrators only. + '404': + description: Not Found — The specified endpoint could not be found. + '405': + description: Method Not Allowed — You tried to access an endpoint with an invalid method. + '429': + description: Too Many Requests — You're requesting too many results! Slow down! + '500': + description: Internal Server Error — We had a problem with our server. Try again later. + '503': + description: Service Unavailable — We're temporarily offline for maintenance. Please try again later. + '504': + description: Gateway Timeout — We're temporarily offline for maintenance. Please try again later. +components: + schemas: + SearchRequest: + required: + - api_key + - query + type: object + properties: + api_key: + type: string + description: Your unique API key. + example: your api key + query: + type: string + description: The search query string. + example: your search query + search_depth: + enum: + - basic + - advanced + type: string + description: The depth of the search. It can be 'basic' or advanced. Default is 'basic'. + default: basic + include_images: + type: boolean + description: Include a list of query related images in the response. Default is False. + default: false + include_answer: + type: boolean + description: Include answers in the search results. Default is False. + default: false + include_raw_content: + type: boolean + description: Include raw content in the search results. Default is False. + default: false + max_results: + type: integer + description: The number of maximum search results to return. Default is 5. + default: 5 + include_domains: + type: array + items: + type: string + description: A list of domains to specifically include in the search results. Default is None. + exclude_domains: + type: array + items: + type: string + description: A list of domains to specifically exclude from the search results. Default is None. + description: The search request object. + SearchResponse: + required: + - query + - response_time + - results + type: object + properties: + answer: + type: string + description: The answer to your search query. + query: + type: string + description: Your search query. + response_time: + type: number + description: Your search result response time. + images: + type: array + items: + type: string + description: A list of query related image urls. + follow_up_questions: + type: array + items: + type: string + description: A list of suggested research follow up questions related to original query. + results: + type: array + items: + $ref: '#/components/schemas/SearchResult' + description: A list of search results. + description: The response data from the search query. + SearchResult: + required: + - title + - url + - content + - score + type: object + properties: + title: + type: string + description: The title of the search result url. + url: + type: string + description: The url of the search result. + content: + type: string + description: The most query related content from the scraped url. + raw_content: + type: string + description: The parsed and cleaned HTML of the site. For now includes parsed text only. + score: + type: number + description: The relevance score of the search result. + description: The search result object. \ No newline at end of file diff --git a/src/tests/IntegrationTests/Tavily.IntegrationTests.csproj b/src/tests/IntegrationTests/Tavily.IntegrationTests.csproj new file mode 100644 index 0000000..f0812b4 --- /dev/null +++ b/src/tests/IntegrationTests/Tavily.IntegrationTests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/tests/IntegrationTests/Tests.Search.cs b/src/tests/IntegrationTests/Tests.Search.cs new file mode 100644 index 0000000..ec43d78 --- /dev/null +++ b/src/tests/IntegrationTests/Tests.Search.cs @@ -0,0 +1,29 @@ +namespace Tavily.IntegrationTests; + +public partial class Tests +{ + [TestMethod] + public async Task Search() + { + var apiKey = + Environment.GetEnvironmentVariable("TAVILY_API_KEY") ?? + throw new AssertInconclusiveException("TAVILY_API_KEY environment variable is not found."); + + using var client = new TavilyClient(); + + SearchResponse searchResponse = await client.SearchAsync( + apiKey: apiKey, + query: "Who is Leo Messi?"); + + foreach (var result in searchResponse.Results) + { + Console.WriteLine($"Title: {result.Title}"); + Console.WriteLine($"Content: {result.Content}"); + Console.WriteLine($"Score: {result.Score}"); + Console.WriteLine($"Url: {result.Url}"); + Console.WriteLine(); + } + + searchResponse.Results.Should().NotBeEmpty(); + } +} diff --git a/src/tests/IntegrationTests/Tests.cs b/src/tests/IntegrationTests/Tests.cs new file mode 100644 index 0000000..83bc675 --- /dev/null +++ b/src/tests/IntegrationTests/Tests.cs @@ -0,0 +1,6 @@ +namespace Tavily.IntegrationTests; + +[TestClass] +public partial class Tests +{ +}