[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at twitter\n@asimdotshrestha.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing to AgentGPT\n\nFirst of all, thank you for your interest in contributing to AgentGPT! We appreciate the time and effort you're willing to invest in making our project better. This document provides guidelines and information to make the contribution process as smooth as possible.\n\n## Table of Contents\n\n- [Code of Conduct](#code-of-conduct)\n- [Getting Started](#getting-started)\n- [How to Contribute](#how-to-contribute)\n  - [Reporting Bugs](#reporting-bugs)\n  - [Suggesting Enhancements](#suggesting-enhancements)\n  - [Submitting Pull Requests](#submitting-pull-requests)\n- [Style Guidelines](#style-guidelines)\n  - [Code Style](#code-style)\n  - [Commit Messages](#commit-messages)\n- [Additional Resources](#additional-resources)\n\n## Code of Conduct\n\nAll contributors are expected to adhere to our [Code of Conduct](CODE_OF_CONDUCT.md). Please read it before participating in the AgentGPT community.\n\n## Getting Started\n\n1. Fork the repository and clone it to your local machine.\n2. Set up the development environment by following the instructions in the [README.md](https://github.com/reworkd/AgentGPT/tree/main/README.md) file.\n3. Explore the codebase, run tests, and verify that everything works as expected.\n\n## How to Contribute\n\n### Reporting Bugs\n\nIf you encounter a bug or issue while using AgentGPT, please open a new issue on the [GitHub Issues](https://github.com/reworkd/AgentGPT/issues) page. Provide a clear and concise description of the problem, steps to reproduce it, and any relevant error messages or logs.\n\n### Suggesting Enhancements\n\nWe welcome ideas for improvements and new features. To suggest an enhancement, open a new issue on the [GitHub Issues](https://github.com/reworkd/AgentGPT/issues) page. Describe the enhancement in detail, explain the use case, and outline the benefits it would bring to the project.\n\n### Submitting Pull Requests\n\n1. Create a new branch for your feature or bugfix. Use a descriptive name like `feature/your-feature-name` or `fix/your-bugfix-name`.\n2. Make your changes, following the [Style Guidelines](#style-guidelines) below.\n3. Test your changes and ensure that they don't introduce new issues or break existing functionality.\n4. Commit your changes, following the [commit message guidelines](#commit-messages).\n5. Push your branch to your fork on GitHub.\n6. Open a new pull request against the `main` branch of the Wolverine repository. Include a clear and concise description of your changes, referencing any related issues.\n\n## Style Guidelines\n\n### Code Style\n\nAgentGPT uses [ESLint](https://eslint.org/) as its code style guide. Please ensure that your code follows these guidelines. \n\n### Commit Messages\n\nWrite clear and concise commit messages that briefly describe the changes made in each commit. Use the imperative mood and start with a capitalized verb, e.g., \"Add new feature\" or \"Fix bug in function\".\n\n## Additional Resources\n\n- [GitHub Help](https://help.github.com/)\n- [GitHub Pull Request Documentation](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests)\n- [ESLint Style Guide](https://eslint.org/)\n\nThank you once again for your interest in contributing to AgentGPT. We look forward to collaborating with you and creating an even better project together!\n\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: reworkd-admin\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yaml",
    "content": "name: Bug Report\ndescription: File a bug report\nlabels: [\"bug\", \"needs triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        ## Before you start\n        Please **make sure you are on the latest version.**\n        If you encountered the issue after you installed, updated, or reloaded, **please try restarting before reporting the bug**.\n\n  - type: checkboxes\n    id: no-duplicate-issues\n    attributes:\n      label: \"Please check that this issue hasn't been reported before.\"\n      description: \"The **Label filters** may help make your search more focussed.\"\n      options:\n        - label: \"I searched previous [Bug Reports](https://github.com/reworkd/AgentGPT/labels/bug) didn't find any similar reports.\"\n          required: true\n\n  - type: textarea\n    id: expected\n    attributes:\n      label: Expected Behavior\n      description: Tell us what **should** happen.\n    validations:\n      required: true\n\n  - type: textarea\n    id: what-happened\n    attributes:\n      label: Current behaviour\n      description: |\n        Tell us what happens instead of the expected behavior.\n        Adding of screenshots really helps.\n    validations:\n      required: true\n\n  - type: textarea\n    id: reproduce\n    attributes:\n      label: Steps to reproduce\n      description: |\n        Which exact steps can a developer take to reproduce the issue?\n        The more detail you provide, the easier it will be to narrow down and fix the bug.\n        Please paste in tasks and/or queries **as text, not screenshots**.\n      placeholder: |\n        Example of the level of detail needed to reproduce any bugs efficiently and reliably.\n        1. Go to the '...' page.\n        2. Click on the '...' button.\n        3. Scroll down to '...'.\n        4. Observe the error.\n    validations:\n      required: true\n      \n  - type: textarea\n    id: possible-solution\n    attributes:\n      label: Possible solution\n      placeholder: I think that change foo to type bar would fix it...\n      description: |\n        Not obligatory, but please suggest a fix or reason for the bug, if you have an idea.  \n      \n\n  - type: checkboxes\n    id: operating-systems\n    attributes:\n      label: Which Operating Systems are you using?\n      description: You may select more than one.\n      options:\n        - label: Android\n        - label: iPhone/iPad\n        - label: Linux\n        - label: macOS\n        - label: Windows\n\n  - type: checkboxes\n    id: acknowledgements\n    attributes:\n      label: 'Acknowledgements'\n      description: 'Please confirm the following:'\n      options:\n        - label: 'My issue title is concise, descriptive, and in title casing.'\n          required: true\n        - label: 'I have searched the existing issues to make sure this bug has not been reported yet.'\n          required: true\n        - label: 'I am using the latest version of AgentGPT.'\n          required: true\n        - label: 'I have provided enough information for the maintainers to reproduce and diagnose the issue.'\n          required: true\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: Ask a question\n    url: https://github.com/reworkd/AgentGPT/discussions/categories/q-a\n    about: Ask questions and discuss with other community members\n  - name: Discuss the Project in Discord\n    url: https://discord.gg/jjYCfaqu\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/docs.yml",
    "content": "name: Documentation Improvement / Clarity\ndescription: Make a suggestion to improve the project documentation.\nlabels: ['needs triage']\nbody:\n  - type: markdown\n    attributes:\n      value: '## :book: Documentation :book:'\n  - type: markdown\n    attributes:\n      value: |\n        * Ask questions in [Discord](https://discord.gg/jjYCfaqu).\n        * Before you file an issue read the [Contributing guide](https://github.com/reworkd/AgentGPT/tree/main/.github/CONTRIBUTING.md).\n        * Check to make sure someone hasn't already opened a [similar issue](https://github.com/reworkd/AgentGPT/issues).\n  - type: textarea\n    attributes:\n      label: What piece of documentation is affected?\n      description: Please link to the article you'd like to see updated.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: What part(s) of the article would you like to see updated?\n      description: |\n        - Give as much detail as you can to help us understand the change you want to see. \n        - Why should the docs be changed? What use cases does it support? \n        - What is the expected outcome?\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Additional Information\n      description: Add any other context or screenshots about the feature request here.\n    validations:\n      required: false\n  - type: checkboxes\n    id: acknowledgements\n    attributes:\n      label: 'Acknowledgements'\n      description: 'Please confirm the following:'\n      options:\n        - label: 'My issue title is concise, descriptive, and in title casing.'\n          required: true\n        - label: 'I have searched the existing issues to make sure this feature has not been requested yet.'\n          required: true\n        - label: 'I have provided enough information for the maintainers to understand and evaluate this request.'\n          required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yaml",
    "content": "name: Feature Request / Enhancement\ndescription: Suggest a new feature or feature enhancement for the project\nlabels: [\"enhancement\", \"needs triage\"]\nbody:\n  - type: checkboxes\n    id: no-duplicate-issues\n    attributes:\n      label: \"⚠️ Please check that this feature request hasn't been suggested before.\"\n      description: \"There are two locations for previous feature requests. Please search in both. Thank you. The **Label filters** may help make your search more focussed.\"\n      options:\n        - label: \"I searched previous [Ideas in Discussions](https://github.com/reworkd/AgentGPT/discussions/categories/ideas) didn't find any similar feature requests.\"\n          required: true\n        - label: \"I searched previous [Issues](https://github.com/reworkd/AgentGPT/labels/enhancement) didn't find any similar feature requests.\"\n          required: true\n\n  - type: textarea\n    id: feature-description\n    validations:\n      required: true\n    attributes:\n      label: \"🔖 Feature description\"\n      description: \"A clear and concise description of what the feature request is.\"\n      placeholder: \"You should add ...\"\n\n  - type: textarea\n    id: solution\n    validations:\n      required: true\n    attributes:\n      label: \"✔️ Solution\"\n      description: \"A clear and concise description of what you want to happen, and why.\"\n      placeholder: \"In my use-case, ...\"\n\n  - type: textarea\n    id: alternatives\n    validations:\n      required: false\n    attributes:\n      label: \"❓ Alternatives\"\n      description: \"A clear and concise description of any alternative solutions or features you've considered.\"\n      placeholder: \"I have considered ...\"\n\n  - type: textarea\n    id: additional-context\n    validations:\n      required: false\n    attributes:\n      label: \"📝 Additional Context\"\n      description: \"Add any other context or screenshots about the feature request here.\"\n      placeholder: \"...\"\n      \n  - type: checkboxes\n    id: acknowledgements\n    attributes:\n      label: 'Acknowledgements'\n      description: 'Please confirm the following:'\n      options:\n        - label: 'My issue title is concise, descriptive, and in title casing.'\n          required: true\n        - label: 'I have searched the existing issues to make sure this feature has not been requested yet.'\n          required: true\n        - label: 'I have provided enough information for the maintainers to understand and evaluate this request.'\n          required: true\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/pull_request_template.md",
    "content": "<!--- Provide a general summary of your changes in the Title above -->\n\n# Description\n\n<!--- Describe your changes in detail -->\n\n## Motivation and Context\n\n<!--- Why is this change required? What problem does it solve? -->\n<!--- If it fixes an open issue, please link to the issue here. -->\n\n## How has this been tested?\n\n<!--- Please describe in detail how you tested your changes. -->\n<!--- Include details of your testing environment, tests ran to see how -->\n<!--- your change affects other areas of the code, etc. -->\n\n## Screenshots (if appropriate)\n\n## Types of changes\n\n<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->\n\nChanges visible to users:\n\n- [ ] **Bug fix** (prefix: `fix` - non-breaking change which fixes an issue)\n- [ ] **New feature** (prefix: `feat` - non-breaking change which adds functionality)\n- [ ] **Breaking change** (prefix: `feat!!` or `fix!!` - fix or feature that would cause existing functionality to not work as expected)\n- [ ] **Documentation** (prefix: `docs` - improvements to any documentation content **for users**)\n- [ ] **Homepage** (prefix: `page` - improvements to the [Homepage](https://agentgpt.reworkd.ai/) #{HOMEPAGE} should lead to the place where one could actually change the homepage\n- [ ] **Contributing Guidelines** (prefix: `contrib` - any improvements to documentation content **for contributors** - see [Contributing](https://github.com/reworkd/AgentGPT/tree/main/.github/CONTRIBUTING.md)\n\nInternal changes:\n\n- [ ] **Refactor** (prefix: `refactor` - non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)\n- [ ] **Tests** (prefix: `test` - additions and improvements to unit tests and the smoke tests)\n- [ ] **Infrastructure** (prefix: `chore` - examples include GitHub Actions, issue templates)\n\n## Checklist\n\n<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->\n<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->\n\n- [ ] My code follows the code style of this project and passes `npm run lint`.\n- [ ] My change requires a change to the documentation.\n- [ ] I have [updated the documentation](https://reworkd.ai/docs) accordingly.  #   {DOCUMENTATION}     <------- this should lead to the doc that could be changed/ didnt find it\n- [ ] My change has adequate [Unit Test coverage]({PLACEHOLDER}).\n\n## Terms\n\n<!--\nBy submitting this pull request, you must agree to follow our\n[contributing guide](https://github.com/reworkd/AgentGPT/tree/main/.github/CONTRIBUTING.md) and\n[Code of Conduct](https://github.com/reworkd/AgentGPT/tree/main/.github/CODE_OF_CONDUCT.md).\nPut an x in the boxes to confirm you agree.\n-->\n\n- [ ] My contribution follow this project's [contributing guide](https://github.com/reworkd/AgentGPT/tree/main/.github/CONTRIBUTING.md)\n- [ ] I agree to follow this project's [Code of Conduct](https://github.com/reworkd/AgentGPT/tree/main/.github/CODE_OF_CONDUCT.md)\n"
  },
  {
    "path": ".github/SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nDue to the nature of the fast development that is happening in this project, only the latest released version can be supported.\n\n## Reporting a Vulnerability\n\nIf you find a vulnerability, please either report a vulnerability [here](https://github.com/reworkd/AgentGPT/security) or contact us on twitter @asimdotshrestha. Please don't create a GitHub before contacting a maintainer to allow us  to fix the vulnerability before others can take advantage of it.\n"
  },
  {
    "path": ".github/SUPPORT.md",
    "content": "# Support\n\nIf you need help with this project or have questions, please:\n\n1. Check the documentation.\n2. Search the existing issues and pull requests.\n3. Create a new issue if your question is not answered or your problem is not solved.\n\nPlease note that this project is maintained by volunteers who have limited availability. We'll do our best to address your questions and concerns in a timely manner.\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# Please see the documentation for all configuration options:\n# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: npm\n    directory: /cli\n    schedule:\n      interval: weekly\n\n  - package-ecosystem: npm\n    directory: /next\n    schedule:\n      interval: weekly\n\n  - package-ecosystem: pip\n    directory: /platform\n    schedule:\n      interval: weekly\n"
  },
  {
    "path": ".github/workflows/node.js.yml",
    "content": "name: Node.js CI\n\non:\n  push:\n    branches: [ \"main\" ]\n    paths:\n      - 'next/**'\n  pull_request:\n    branches: [ \"main\" ]\n    paths:\n      - 'next/**'\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: next\n    steps:\n      - uses: actions/checkout@v3\n      - name: Use Node.js 18\n        uses: actions/setup-node@v3\n        with:\n          node-version: 18.x\n          cache: \"npm\"\n          cache-dependency-path: next/package-lock.json\n      - run: npm ci\n      - run: npm test\n        env:\n          OPENAI_API_KEY: sk-0000000000\n      - run: ./prisma/useSqlite.sh && npm run postinstall\n\n"
  },
  {
    "path": ".github/workflows/python.yml",
    "content": "name: Testing Platform\non:\n  pull_request:\n    branches: [ \"main\" ]\n    paths:\n      - 'platform/**'\n\nenv:\n  PYTHON_VERSION: \"3.11\"\n\njobs:\n  black:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: platform\n    steps:\n      - uses: actions/checkout@v3\n      - name: Install poetry\n        run: pipx install poetry\n      - uses: actions/setup-python@v4\n        with:\n          python-version: ${{ env.PYTHON_VERSION }}\n          cache: 'poetry'\n      - run: poetry install\n      - name: Run black check\n        run: poetry run black --check .\n\n  mypy:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: platform\n    steps:\n      - uses: actions/checkout@v3\n      - name: Install poetry\n        run: pipx install poetry\n      - uses: actions/setup-python@v4\n        with:\n          python-version: ${{ env.PYTHON_VERSION }}\n          cache: 'poetry'\n      - run: poetry install\n      - name: Run mypy check\n        run: poetry run mypy .\n\n  pytest:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: platform\n    services:\n      reworkd_platform-db:\n        image: bitnami/mysql:8.0.30\n        env:\n          MYSQL_ROOT_PASSWORD: \"reworkd_platform\"\n          MYSQL_ROOT_USER: \"reworkd_platform\"\n          MYSQL_DATABASE: \"reworkd_platform\"\n          MYSQL_AUTHENTICATION_PLUGIN: \"mysql_native_password\"\n        options: >-\n          --health-cmd=\"mysqladmin ping -u root\"\n          --health-interval=15s\n          --health-timeout=5s\n          --health-retries=6\n        ports:\n          - 3306:3306\n    steps:\n      - uses: actions/checkout@v3\n      - name: Install poetry\n        run: pipx install poetry\n      - uses: actions/setup-python@v4\n        with:\n          python-version: ${{ env.PYTHON_VERSION }}\n          cache: 'poetry'\n      - run: poetry install\n      - name: Run pytest check\n        run: poetry run pytest -vv --cov=\"reworkd_platform\" .\n        env:\n          REWORKD_PLATFORM_HOST: \"0.0.0.0\"\n          REWORKD_PLATFORM_DB_HOST: localhost\n          REWORKD_PLATFORM_KAFKA_BOOTSTRAP_SERVERS: '[\"localhost:9092\"]'\n"
  },
  {
    "path": ".github/workflows/sponsors.yml",
    "content": "name: Generate Sponsors README\non:\n  workflow_dispatch:\n  schedule:\n    - cron: 0 0 * * *\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout 🛎️\n        uses: actions/checkout@v2\n\n      - name: Generate Sponsors 💖\n        uses: JamesIves/github-sponsors-readme-action@v1.2.2\n        with:\n          token: ${{ secrets.SPONSOR_WORKFLOW_PAT }}\n          file: 'README.md'\n          minimum: 1399\n\n      - name: Create Pull Request\n        uses: peter-evans/create-pull-request@v5.0.1\n        with:\n          token: ${{ secrets.SPONSOR_WORKFLOW_PAT }}\n          branch: \"workflow/sponsors\"\n          title: \"🤖 Update Sponsors\"\n          commit-message: \"🤖 Update Sponsors\"\n          body: \"🤖 Automated pull request created by [sponsors action](https://github.com/reworkd/AgentGPT/actions/workflows/sponsors.yml)\"\n          labels: \"documentation\"\n\n"
  },
  {
    "path": ".github/workflows/webhooks.yml",
    "content": "name: Invoke Deployment Webhooks\non:\n  workflow_dispatch:\n  push:\n    branches: [ \"main\" ]\n\njobs:\n  invoke:\n    name: Invoke Webhooks\n    runs-on: ubuntu-latest\n    environment: production\n    if: github.repository == 'reworkd/AgentGPT'\n    steps:\n    - name: Trigger Webhooks\n      run: |\n        curl -L \\\n          -X POST \\\n          -H \"Accept: application/vnd.github+json\" \\\n          -H ${{ secrets.WEBHOOK_AUTHORIZATION }} \\\n          -H \"X-GitHub-Api-Version: 2022-11-28\" \\\n          -d '{\"ref\":\"main\"}' \\\n          ${{ secrets.DEPLOYMENT_WEBHOOK_URL }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# database\n/prisma/db.sqlite\n/prisma/db.sqlite-journal\n/db/db.sqlite\n\n# next.js\n/.next/\n/out/\nnext-env.d.ts\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n# local env files\n# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables\n.env*\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\n.idea\n.swc\n\n# extracted language files\n/public/locales/$LOCALES\n\n.eslintcache\n\n# Sentry Auth Token\n.sentryclirc\n/volumes/\nschema.prismae\n*.sql\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/reworkd/AgentGPT/main/next/public/banner.png\" height=\"300\" alt=\"AgentGPT Logo\"/>\n</p>\n<p align=\"center\">\n  <em>🤖 Assemble, configure, and deploy autonomous AI Agent(s) in your browser. 🤖   </em>\n</p>\n<p align=\"center\">\n    <img alt=\"Node version\" src=\"https://img.shields.io/static/v1?label=node&message=%20%3E=18&logo=node.js&color=2334D058\" />\n      <a href=\"https://github.com/reworkd/AgentGPT/blob/master/README.md\"><img src=\"https://img.shields.io/badge/lang-English-blue.svg\" alt=\"English\"></a>\n  <a href=\"https://github.com/reworkd/AgentGPT/blob/master/docs/README.zh-HANS.md\"><img src=\"https://img.shields.io/badge/lang-简体中文-red.svg\" alt=\"简体中文\"></a>\n  <a href=\"https://github.com/reworkd/AgentGPT/blob/master/docs/README.hu-Cs4K1Sr4C.md\"><img src=\"https://img.shields.io/badge/lang-Hungarian-red.svg\" alt=\"Hungarian\"></a>\n</p>\n\n<p align=\"center\">\n<a href=\"https://agentgpt.reworkd.ai\">🔗 Short link</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://reworkd.ai/docs\">📚 Docs</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://twitter.com/reworkdai\">🐦 Twitter</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://discord.gg/gcmNyAAFfV\">📢 Discord</a>\n</p>\n\nAgentGPT allows you to configure and deploy Autonomous AI agents.\nName your own custom AI and have it embark on any goal imaginable.\nIt will attempt to reach the goal by thinking of tasks to do, executing them, and learning from the results 🚀.\n\n---\n\n## ✨ Demo\nFor the best demo experience, try [our site](https://agentgpt.reworkd.ai) directly :)\n\n[Demo Video](https://github.com/reworkd/AgentGPT/assets/50181239/5348e44a-29a5-4280-a06b-fe1429a8d99e)\n\n\n## 👨‍🚀 Getting Started\n\nThe easiest way to get started with AgentGPT is automatic setup CLI bundled with the project.\nThe cli sets up the following for AgentGPT:\n- 🔐 [Environment variables](https://github.com/reworkd/AgentGPT/blob/main/.env.example) (and API Keys)\n- 🗂️ [Database](https://github.com/reworkd/AgentGPT/tree/main/db) (Mysql)\n- 🤖 [Backend](https://github.com/reworkd/AgentGPT/tree/main/platform) (FastAPI)\n- 🎨 [Frontend](https://github.com/reworkd/AgentGPT/tree/main/next) (Nextjs)\n\n## Prerequisites :point_up:\n\nBefore you get started, please make sure you have the following installed:\n\n- An editor of your choice. For example, [Visual Studio Code (VS Code)](https://code.visualstudio.com/download)\n- [Node.js](https://nodejs.org/en/download)\n- [Git](https://git-scm.com/downloads)\n- [Docker](https://www.docker.com/products/docker-desktop). After installation, please create an account, open up the Docker application, and sign in.\n- An [OpenAI API key](https://platform.openai.com/signup)\n- A [Serper API Key](https://serper.dev/signup) (optional)\n- A [Replicate API Token](https://replicate.com/signin) (optional)\n\n## Getting Started :rocket:\n1. **Open your editor**\n\n2. **Open the Terminal** - Typically, you can do this from a 'Terminal' tab or by using a shortcut\n   (e.g., `Ctrl + ~` for Windows or `Control + ~` for Mac in VS Code).\n\n3. **Clone the Repository and Navigate into the Directory** - Once your terminal is open, you can clone the repository and move into the directory by running the commands below.\n\n   **For Mac/Linux users** :apple: :penguin:\n   ```bash\n   git clone https://github.com/reworkd/AgentGPT.git\n   cd AgentGPT\n   ./setup.sh\n   ```\n   **For Windows users** :windows:\n   ```bash\n   git clone https://github.com/reworkd/AgentGPT.git\n   cd AgentGPT\n   ./setup.bat\n   ```\n4. **Follow the setup instructions from the script** - add the appropriate API keys, and once all of the services are running, travel to [http://localhost:3000](http://localhost:3000) on your web-browser.\n\nHappy hacking! :tada:\n\n\n## 🚀 Tech Stack\n\n- ✅ **Bootstrapping**: [create-t3-app](https://create.t3.gg) + [FastAPI-template](https://github.com/s3rius/FastAPI-template).\n- ✅ **Framework**: [Nextjs 13 + Typescript](https://nextjs.org/) + [FastAPI](https://fastapi.tiangolo.com/)\n- ✅ **Auth**: [Next-Auth.js](https://next-auth.js.org)\n- ✅ **ORM**: [Prisma](https://prisma.io) & [SQLModel](https://sqlmodel.tiangolo.com/).\n- ✅ **Database**: [Planetscale](https://planetscale.com/).\n- ✅ **Styling**: [TailwindCSS + HeadlessUI](https://tailwindcss.com).\n- ✅ **Schema Validation**: [Zod](https://github.com/colinhacks/zod) + [Pydantic](https://docs.pydantic.dev/).\n- ✅ **LLM Tooling**: [Langchain](https://github.com/hwchase17/langchain).\n\n\n<h2 align=\"center\">\n💝 Our GitHub sponsors 💝\n</h2>\n\n<p align=\"center\">\nJoin us in fueling the development of AgentGPT, an open-source project pushing the boundaries of AI agents! Your sponsorship would drive progress by helping us scale up resources, enhance features and functionality, and continue to iterate on this exciting project! 🚀\n</p>\n\n<p align=\"center\">\n<!-- sponsors --><a href=\"https://github.com/arthurbnhm\"><img src=\"https://github.com/arthurbnhm.png\" width=\"60px\" alt=\"Arthur\" /></a><a href=\"https://github.com/mrayonnaise\"><img src=\"https://github.com/mrayonnaise.png\" width=\"60px\" alt=\"Matt Ray\" /></a><a href=\"https://github.com/jd3655\"><img src=\"https://github.com/jd3655.png\" width=\"60px\" alt=\"Vector Ventures\" /></a><a href=\"https://github.com/durairajasivam\"><img src=\"https://github.com/durairajasivam.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/floriank\"><img src=\"https://github.com/floriank.png\" width=\"60px\" alt=\"Florian Kraft\" /></a><a href=\"https://github.com/localecho\"><img src=\"https://github.com/localecho.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/fireheat135\"><img src=\"https://github.com/fireheat135.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/zoelidity\"><img src=\"https://github.com/zoelidity.png\" width=\"60px\" alt=\"Zoe\" /></a><a href=\"https://github.com/busseyl\"><img src=\"https://github.com/busseyl.png\" width=\"60px\" alt=\"Lucas Bussey\" /></a><a href=\"https://github.com/DuanChaori\"><img src=\"https://github.com/DuanChaori.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jukwaphil1\"><img src=\"https://github.com/jukwaphil1.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/lisa-ee\"><img src=\"https://github.com/lisa-ee.png\" width=\"60px\" alt=\"Lisa\" /></a><a href=\"https://github.com/VulcanT\"><img src=\"https://github.com/VulcanT.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/kman62\"><img src=\"https://github.com/kman62.png\" width=\"60px\" alt=\"kmotte\" /></a><a href=\"https://github.com/Haithamhaj\"><img src=\"https://github.com/Haithamhaj.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/SwftCoins\"><img src=\"https://github.com/SwftCoins.png\" width=\"60px\" alt=\"SWFT Blockchain\" /></a><a href=\"https://github.com/ChevalierzA\"><img src=\"https://github.com/ChevalierzA.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/research-developer\"><img src=\"https://github.com/research-developer.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Mitchell-Coder-New\"><img src=\"https://github.com/Mitchell-Coder-New.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Trecares\"><img src=\"https://github.com/Trecares.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/nnkostov\"><img src=\"https://github.com/nnkostov.png\" width=\"60px\" alt=\"Nikolay Kostov\" /></a><a href=\"https://github.com/oryanmoshe\"><img src=\"https://github.com/oryanmoshe.png\" width=\"60px\" alt=\"Oryan Moshe\" /></a><a href=\"https://github.com/ClayNelson\"><img src=\"https://github.com/ClayNelson.png\" width=\"60px\" alt=\"Clay Nelson\" /></a><a href=\"https://github.com/0xmatchmaker\"><img src=\"https://github.com/0xmatchmaker.png\" width=\"60px\" alt=\"0xmatchmaker\" /></a><a href=\"https://github.com/carlosbartolomeu\"><img src=\"https://github.com/carlosbartolomeu.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Agronobeetles\"><img src=\"https://github.com/Agronobeetles.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/CloudyGuyThompson\"><img src=\"https://github.com/CloudyGuyThompson.png\" width=\"60px\" alt=\"Guy Thompson\" /></a><a href=\"https://github.com/Jhonvolt17\"><img src=\"https://github.com/Jhonvolt17.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/sirswali\"><img src=\"https://github.com/sirswali.png\" width=\"60px\" alt=\"Vusi Dube\" /></a><a href=\"https://github.com/Tweezamiza\"><img src=\"https://github.com/Tweezamiza.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/DixonFyre\"><img src=\"https://github.com/DixonFyre.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jenius-eagle\"><img src=\"https://github.com/jenius-eagle.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/CubanCongaMan\"><img src=\"https://github.com/CubanCongaMan.png\" width=\"60px\" alt=\"Roberto Luis Sanchez, P.E., P.G.; D,GE; F.ASCE\" /></a><a href=\"https://github.com/cskrobec\"><img src=\"https://github.com/cskrobec.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Jahmazon\"><img src=\"https://github.com/Jahmazon.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/ISDAworld\"><img src=\"https://github.com/ISDAworld.png\" width=\"60px\" alt=\"David Gammond\" /></a><a href=\"https://github.com/lazzacapital\"><img src=\"https://github.com/lazzacapital.png\" width=\"60px\" alt=\"Lazza Capital\" /></a><a href=\"https://github.com/OptionalJoystick\"><img src=\"https://github.com/OptionalJoystick.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/rodolfoguzzi\"><img src=\"https://github.com/rodolfoguzzi.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/bluecat2210\"><img src=\"https://github.com/bluecat2210.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/dactylogram9\"><img src=\"https://github.com/dactylogram9.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/RUFreeJAC63\"><img src=\"https://github.com/RUFreeJAC63.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/cecilmiles\"><img src=\"https://github.com/cecilmiles.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Djarielm007\"><img src=\"https://github.com/Djarielm007.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/mikenj07\"><img src=\"https://github.com/mikenj07.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/SvetaMolusk\"><img src=\"https://github.com/SvetaMolusk.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/wuminkung\"><img src=\"https://github.com/wuminkung.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/zhoumo1221\"><img src=\"https://github.com/zhoumo1221.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Stefan6666XXX\"><img src=\"https://github.com/Stefan6666XXX.png\" width=\"60px\" alt=\"Stephane DeGuire\" /></a><a href=\"https://github.com/lyska\"><img src=\"https://github.com/lyska.png\" width=\"60px\" alt=\"Lyska\" /></a><a href=\"https://github.com/KurganKolde\"><img src=\"https://github.com/KurganKolde.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/sclappccsu\"><img src=\"https://github.com/sclappccsu.png\" width=\"60px\" alt=\"Sharon Clapp at CCSU\" /></a><a href=\"https://github.com/Rooba-Finance\"><img src=\"https://github.com/Rooba-Finance.png\" width=\"60px\" alt=\"Rooba.Finance\" /></a><a href=\"https://github.com/ferienhausmiete\"><img src=\"https://github.com/ferienhausmiete.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/benjaminbales\"><img src=\"https://github.com/benjaminbales.png\" width=\"60px\" alt=\"Benjamin Bales\" /></a><a href=\"https://github.com/pimentel233\"><img src=\"https://github.com/pimentel233.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/PinkyWobbles\"><img src=\"https://github.com/PinkyWobbles.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jconroy11\"><img src=\"https://github.com/jconroy11.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/DavidJamesRotenberg\"><img src=\"https://github.com/DavidJamesRotenberg.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/antecochat\"><img src=\"https://github.com/antecochat.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/RealBonOfaSitch\"><img src=\"https://github.com/RealBonOfaSitch.png\" width=\"60px\" alt=\"\" /></a><!-- sponsors -->\n</p>\n\n<h2 align=\"center\">\n💪 Contributors 💪\n</h2>\n\n<p align=\"center\">\nOur contributors have made this project possible. Thank you! 🙏\n</p>\n\n<a href=\"https://github.com/reworkd/agentgpt/graphs/contributors\">\n  <img src=\"https://contrib.rocks/image?repo=reworkd/agentgpt\" />\n</a>\n\n<div align=\"center\">\n<sub>Made with <a href=\"https://contrib.rocks\">contrib.rocks</a>.</sub>\n</div>\n"
  },
  {
    "path": "cli/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n.eslintcache\n"
  },
  {
    "path": "cli/README.md",
    "content": "## AgentGPT CLI\n\nAgentGPT CLI is a utility designed to streamline the setup process of your AgentGPT environment.\nIt uses Inquirer to interactively build up ENV values while also validating they are correct.\n\nThis was first created by @JPDucky on GitHub.\n\n### Running the tool\n\n```\n// Running from the root of the project\n./setup.sh\n```\n\n```\n// Running from the cli directory\ncd cli/\nnpm run start\n```\n\n### Updating ENV values\n\nTo update ENV values:\n\n- Add a question to the list of questions in `index.js` for the ENV value\n- Add a value in the `envDefinition` for the ENV value\n- Add the ENV value to the `.env.example` in the root of the project\n"
  },
  {
    "path": "cli/package.json",
    "content": "{\n  \"name\": \"agentgpt-cli\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A CLI to create your AgentGPT environment\",\n  \"private\": true,\n  \"engines\": {\n    \"node\": \">=18.0.0 <19.0.0\"\n  },\n  \"type\": \"module\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node src/index.js\",\n    \"dev\": \"node src/index.js\"\n  },\n  \"author\": \"reworkd\",\n  \"dependencies\": {\n    \"@octokit/auth-basic\": \"^1.4.8\",\n    \"@octokit/rest\": \"^20.0.2\",\n    \"chalk\": \"^5.3.0\",\n    \"clear\": \"^0.1.0\",\n    \"clui\": \"^0.3.6\",\n    \"configstore\": \"^6.0.0\",\n    \"dotenv\": \"^16.3.1\",\n    \"figlet\": \"^1.7.0\",\n    \"inquirer\": \"^9.2.12\",\n    \"lodash\": \"^4.17.21\",\n    \"minimist\": \"^1.2.8\",\n    \"node-fetch\": \"^3.3.2\",\n    \"simple-git\": \"^3.20.0\",\n    \"touch\": \"^3.1.0\"\n  }\n}\n"
  },
  {
    "path": "cli/src/envGenerator.js",
    "content": "import crypto from \"crypto\";\nimport fs from \"fs\";\nimport chalk from \"chalk\";\n\nexport const generateEnv = (envValues) => {\n  let isDockerCompose = envValues.runOption === \"docker-compose\";\n  let dbPort = isDockerCompose ? 3307 : 3306;\n  let platformUrl = isDockerCompose\n    ? \"http://host.docker.internal:8000\"\n    : \"http://localhost:8000\";\n\n  const envDefinition = getEnvDefinition(\n    envValues,\n    isDockerCompose,\n    dbPort,\n    platformUrl\n  );\n\n  const envFileContent = generateEnvFileContent(envDefinition);\n  saveEnvFile(envFileContent);\n};\n\nconst getEnvDefinition = (envValues, isDockerCompose, dbPort, platformUrl) => {\n  return {\n    \"Deployment Environment\": {\n      NODE_ENV: \"development\",\n      NEXT_PUBLIC_VERCEL_ENV: \"${NODE_ENV}\",\n    },\n    NextJS: {\n      NEXT_PUBLIC_BACKEND_URL: \"http://localhost:8000\",\n      NEXT_PUBLIC_MAX_LOOPS: 100,\n    },\n    \"Next Auth config\": {\n      NEXTAUTH_SECRET: generateAuthSecret(),\n      NEXTAUTH_URL: \"http://localhost:3000\",\n    },\n    \"Auth providers (Use if you want to get out of development mode sign-in)\": {\n      GOOGLE_CLIENT_ID: \"***\",\n      GOOGLE_CLIENT_SECRET: \"***\",\n      GITHUB_CLIENT_ID: \"***\",\n      GITHUB_CLIENT_SECRET: \"***\",\n      DISCORD_CLIENT_SECRET: \"***\",\n      DISCORD_CLIENT_ID: \"***\",\n    },\n    Backend: {\n      REWORKD_PLATFORM_ENVIRONMENT: \"${NODE_ENV}\",\n      REWORKD_PLATFORM_FF_MOCK_MODE_ENABLED: false,\n      REWORKD_PLATFORM_MAX_LOOPS: \"${NEXT_PUBLIC_MAX_LOOPS}\",\n      REWORKD_PLATFORM_OPENAI_API_KEY:\n        envValues.OpenAIApiKey || '\"<change me>\"',\n      REWORKD_PLATFORM_FRONTEND_URL: \"http://localhost:3000\",\n      REWORKD_PLATFORM_RELOAD: true,\n      REWORKD_PLATFORM_OPENAI_API_BASE: \"https://api.openai.com/v1\",\n      REWORKD_PLATFORM_SERP_API_KEY: envValues.serpApiKey || '\"\"',\n      REWORKD_PLATFORM_REPLICATE_API_KEY: envValues.replicateApiKey || '\"\"',\n    },\n    \"Database (Backend)\": {\n      REWORKD_PLATFORM_DATABASE_USER: \"reworkd_platform\",\n      REWORKD_PLATFORM_DATABASE_PASSWORD: \"reworkd_platform\",\n      REWORKD_PLATFORM_DATABASE_HOST: \"agentgpt_db\",\n      REWORKD_PLATFORM_DATABASE_PORT: dbPort,\n      REWORKD_PLATFORM_DATABASE_NAME: \"reworkd_platform\",\n      REWORKD_PLATFORM_DATABASE_URL:\n        \"mysql://${REWORKD_PLATFORM_DATABASE_USER}:${REWORKD_PLATFORM_DATABASE_PASSWORD}@${REWORKD_PLATFORM_DATABASE_HOST}:${REWORKD_PLATFORM_DATABASE_PORT}/${REWORKD_PLATFORM_DATABASE_NAME}\",\n    },\n    \"Database (Frontend)\": {\n      DATABASE_USER: \"reworkd_platform\",\n      DATABASE_PASSWORD: \"reworkd_platform\",\n      DATABASE_HOST: \"agentgpt_db\",\n      DATABASE_PORT: dbPort,\n      DATABASE_NAME: \"reworkd_platform\",\n      DATABASE_URL:\n        \"mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}\",\n    },\n  };\n};\n\nconst generateEnvFileContent = (config) => {\n  let configFile = \"\";\n\n  Object.entries(config).forEach(([section, variables]) => {\n    configFile += `# ${section}:\\n`;\n    Object.entries(variables).forEach(([key, value]) => {\n      configFile += `${key}=${value}\\n`;\n    });\n    configFile += \"\\n\";\n  });\n\n  return configFile.trim();\n};\n\nconst generateAuthSecret = () => {\n  const length = 32;\n  const buffer = crypto.randomBytes(length);\n  return buffer.toString(\"base64\");\n};\n\nconst ENV_PATH = \"../next/.env\";\nconst BACKEND_ENV_PATH = \"../platform/.env\";\n\nexport const doesEnvFileExist = () => {\n  return fs.existsSync(ENV_PATH);\n};\n\n// Read the existing env file, test if it is missing any keys or contains any extra keys\nexport const testEnvFile = () => {\n  const data = fs.readFileSync(ENV_PATH, \"utf8\");\n\n  // Make a fake definition to compare the keys of\n  const envDefinition = getEnvDefinition({}, \"\", \"\", \"\", \"\");\n\n  const lines = data\n    .split(\"\\n\")\n    .filter((line) => !line.startsWith(\"#\") && line.trim() !== \"\");\n  const envKeysFromFile = lines.map((line) => line.split(\"=\")[0]);\n\n  const envKeysFromDef = Object.entries(envDefinition).flatMap(\n    ([section, entries]) => Object.keys(entries)\n  );\n\n  const missingFromFile = envKeysFromDef.filter(\n    (key) => !envKeysFromFile.includes(key)\n  );\n\n  if (missingFromFile.length > 0) {\n    let errorMessage = \"\\nYour ./next/.env is missing the following keys:\\n\";\n    missingFromFile.forEach((key) => {\n      errorMessage += chalk.whiteBright(`- ❌  ${key}\\n`);\n    });\n    errorMessage += \"\\n\";\n\n    errorMessage += chalk.red(\n      \"We recommend deleting your .env file(s) and restarting this script.\"\n    );\n    throw new Error(errorMessage);\n  }\n};\n\nexport const saveEnvFile = (envFileContent) => {\n  fs.writeFileSync(ENV_PATH, envFileContent);\n  fs.writeFileSync(BACKEND_ENV_PATH, envFileContent);\n};\n"
  },
  {
    "path": "cli/src/helpers.js",
    "content": "import chalk from \"chalk\";\nimport figlet from \"figlet\";\n\nexport const printTitle = () => {\n  console.log(\n    chalk.red(\n      figlet.textSync(\"AgentGPT\", {\n        horizontalLayout: \"full\",\n        font: \"ANSI Shadow\",\n      })\n    )\n  );\n  console.log(\n    \"Welcome to the AgentGPT CLI! This CLI will generate the required .env files.\"\n  );\n  console.log(\n    \"Copies of the generated envs will be created in `./next/.env` and `./platform/.env`.\\n\"\n  );\n};\n\n// Function to check if entered api key is in the correct format or empty\nexport const isValidKey = (apikey, pattern) => {\n  return (apikey === \"\" || pattern.test(apikey))\n};\n\nexport const validKeyErrorMessage = \"\\nInvalid api key. Please try again.\"\n"
  },
  {
    "path": "cli/src/index.js",
    "content": "import inquirer from \"inquirer\";\nimport dotenv from \"dotenv\";\nimport { printTitle } from \"./helpers.js\";\nimport { doesEnvFileExist, generateEnv, testEnvFile } from \"./envGenerator.js\";\nimport { newEnvQuestions } from \"./questions/newEnvQuestions.js\";\nimport { existingEnvQuestions } from \"./questions/existingEnvQuestions.js\";\nimport { spawn } from \"child_process\";\nimport chalk from \"chalk\";\n\nconst handleExistingEnv = () => {\n  console.log(chalk.yellow(\"Existing ./next/env file found. Validating...\"));\n\n  try {\n    testEnvFile();\n  } catch (e) {\n    console.log(e.message);\n    return;\n  }\n\n  inquirer.prompt(existingEnvQuestions).then((answers) => {\n    handleRunOption(answers.runOption);\n  });\n};\n\nconst handleNewEnv = () => {\n  inquirer.prompt(newEnvQuestions).then((answers) => {\n    dotenv.config({ path: \"./.env\" });\n    generateEnv(answers);\n    console.log(\"\\nEnv files successfully created!\");\n    handleRunOption(answers.runOption);\n  });\n};\n\nconst handleRunOption = (runOption) => {\n  if (runOption === \"docker-compose\") {\n    const dockerComposeUp = spawn(\"docker-compose\", [\"up\", \"--build\"], {\n      stdio: \"inherit\",\n    });\n  }\n\n  if (runOption === \"manual\") {\n    console.log(\n      \"Please go into the ./next folder and run `npm install && npm run dev`.\"\n    );\n    console.log(\n      \"Please also go into the ./platform folder and run `poetry install && poetry run python -m reworkd_platform`.\"\n    );\n    console.log(\n      \"Please use or update the MySQL database configuration in the env file(s).\"\n    );\n  }\n};\n\nprintTitle();\n\nif (doesEnvFileExist()) {\n  handleExistingEnv();\n} else {\n  handleNewEnv();\n}\n"
  },
  {
    "path": "cli/src/questions/existingEnvQuestions.js",
    "content": "import { RUN_OPTION_QUESTION } from \"./sharedQuestions.js\";\n\nexport const existingEnvQuestions = [\n  RUN_OPTION_QUESTION\n];\n"
  },
  {
    "path": "cli/src/questions/newEnvQuestions.js",
    "content": "import { isValidKey, validKeyErrorMessage } from \"../helpers.js\";\nimport { RUN_OPTION_QUESTION } from \"./sharedQuestions.js\";\nimport fetch from \"node-fetch\";\n\nexport const newEnvQuestions = [\n    RUN_OPTION_QUESTION,\n    {\n        type: \"input\",\n        name: \"OpenAIApiKey\",\n        message:\n            \"Enter your openai key (eg: sk...) or press enter to continue with no key:\",\n        validate: async(apikey) => {\n            if(apikey === \"\") return true;\n\n            if(!isValidKey(apikey, /^sk-[a-zA-Z0-9]{48}$/)) {\n                return validKeyErrorMessage\n            }\n\n            const endpoint = \"https://api.openai.com/v1/models\"\n            const response = await fetch(endpoint, {\n                headers: {\n                    \"Authorization\": `Bearer ${apikey}`,\n                },\n            });\n            if(!response.ok) {\n                return validKeyErrorMessage\n            }\n\n            return true\n        },\n    },\n    {\n        type: \"input\",\n        name: \"serpApiKey\",\n        message:\n            \"What is your SERP API key (https://serper.dev/)? Leave empty to disable web search.\",\n        validate: async(apikey) => {\n            if(apikey === \"\") return true;\n\n            if(!isValidKey(apikey, /^[a-zA-Z0-9]{40}$/)) {\n                return validKeyErrorMessage\n            }\n\n            const endpoint = \"https://google.serper.dev/search\"\n            const response = await fetch(endpoint, {\n                method: 'POST',\n                headers: {\n                    \"X-API-KEY\": apikey,\n                    \"Content-Type\": \"application/json\",\n                },\n                body: JSON.stringify({\n                    \"q\": \"apple inc\"\n                }),\n            });\n            if(!response.ok) {\n                return validKeyErrorMessage\n            }\n\n            return true\n        },\n    },\n    {\n        type: \"input\",\n        name: \"replicateApiKey\",\n        message:\n            \"What is your Replicate API key (https://replicate.com/)? Leave empty to just use DALL-E for image generation.\",\n        validate: async(apikey) => {\n            if(apikey === \"\") return true;\n            \n            if(!isValidKey(apikey, /^r8_[a-zA-Z0-9]{37}$/)) {\n                return validKeyErrorMessage\n            }\n\n            const endpoint = \"https://api.replicate.com/v1/models/replicate/hello-world\"\n            const response = await fetch(endpoint, {\n                headers: {\n                    \"Authorization\": `Token ${apikey}`,\n                },\n            });\n            if(!response.ok) {\n                return validKeyErrorMessage\n            }\n\n            return true\n        },\n    },\n];\n"
  },
  {
    "path": "cli/src/questions/sharedQuestions.js",
    "content": "export const RUN_OPTION_QUESTION = {\n  type: 'list',\n  name: 'runOption',\n  choices: [\n    { value: \"docker-compose\", name: \"🐋 Docker-compose (Recommended)\" },\n    { value: \"manual\", name: \"💪 Manual (Not recommended)\" },\n  ],\n  message: 'How will you be running AgentGPT?',\n  default: \"docker-compose\",\n}\n"
  },
  {
    "path": "cli/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig to read more about this file */\n\n    /* Projects */\n    // \"incremental\": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */\n    // \"composite\": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */\n    // \"tsBuildInfoFile\": \"./.tsbuildinfo\",              /* Specify the path to .tsbuildinfo incremental compilation file. */\n    // \"disableSourceOfProjectReferenceRedirect\": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */\n    // \"disableSolutionSearching\": true,                 /* Opt a project out of multi-project reference checking when editing. */\n    // \"disableReferencedProjectLoad\": true,             /* Reduce the number of projects loaded automatically by TypeScript. */\n\n    /* Language and Environment */\n    \"target\": \"es2016\",\n    /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */\n    // \"src\": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */\n    // \"jsx\": \"preserve\",                                /* Specify what JSX code is generated. */\n    // \"experimentalDecorators\": true,                   /* Enable experimental support for legacy experimental decorators. */\n    // \"emitDecoratorMetadata\": true,                    /* Emit design-type metadata for decorated declarations in source files. */\n    // \"jsxFactory\": \"\",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */\n    // \"jsxFragmentFactory\": \"\",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */\n    // \"jsxImportSource\": \"\",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */\n    // \"reactNamespace\": \"\",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */\n    // \"noLib\": true,                                    /* Disable including any library files, including the default src.d.ts. */\n    // \"useDefineForClassFields\": true,                  /* Emit ECMAScript-standard-compliant class fields. */\n    // \"moduleDetection\": \"auto\",                        /* Control what method is used to detect module-format JS files. */\n\n    /* Modules */\n    \"module\": \"commonjs\",\n    /* Specify what module code is generated. */\n    // \"rootDir\": \"./\",                                  /* Specify the root folder within your source files. */\n    // \"moduleResolution\": \"node10\",                     /* Specify how TypeScript looks up a file from a given module specifier. */\n    // \"baseUrl\": \"./\",                                  /* Specify the base directory to resolve non-relative module names. */\n    // \"paths\": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */\n    // \"rootDirs\": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */\n    // \"typeRoots\": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */\n    // \"types\": [],                                      /* Specify type package names to be included without being referenced in a source file. */\n    // \"allowUmdGlobalAccess\": true,                     /* Allow accessing UMD globals from modules. */\n    // \"moduleSuffixes\": [],                             /* List of file name suffixes to search when resolving a module. */\n    // \"allowImportingTsExtensions\": true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */\n    // \"resolvePackageJsonExports\": true,                /* Use the package.json 'exports' field when resolving package imports. */\n    // \"resolvePackageJsonImports\": true,                /* Use the package.json 'imports' field when resolving imports. */\n    // \"customConditions\": [],                           /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */\n    // \"resolveJsonModule\": true,                        /* Enable importing .json files. */\n    // \"allowArbitraryExtensions\": true,                 /* Enable importing files with any extension, provided a declaration file is present. */\n    // \"noResolve\": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */\n\n    /* JavaScript Support */\n    // \"allowJs\": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */\n    // \"checkJs\": true,                                  /* Enable error reporting in type-checked JavaScript files. */\n    // \"maxNodeModuleJsDepth\": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */\n\n    /* Emit */\n    // \"declaration\": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */\n    // \"declarationMap\": true,                           /* Create sourcemaps for d.ts files. */\n    // \"emitDeclarationOnly\": true,                      /* Only output d.ts files and not JavaScript files. */\n    // \"sourceMap\": true,                                /* Create source map files for emitted JavaScript files. */\n    // \"inlineSourceMap\": true,                          /* Include sourcemap files inside the emitted JavaScript. */\n    // \"outFile\": \"./\",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */\n    // \"outDir\": \"./\",                                   /* Specify an output folder for all emitted files. */\n    // \"removeComments\": true,                           /* Disable emitting comments. */\n    // \"noEmit\": true,                                   /* Disable emitting files from a compilation. */\n    // \"importHelpers\": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */\n    // \"importsNotUsedAsValues\": \"remove\",               /* Specify emit/checking behavior for imports that are only used for types. */\n    // \"downlevelIteration\": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */\n    // \"sourceRoot\": \"\",                                 /* Specify the root path for debuggers to find the reference source code. */\n    // \"mapRoot\": \"\",                                    /* Specify the location where debugger should locate map files instead of generated locations. */\n    // \"inlineSources\": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */\n    // \"emitBOM\": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */\n    // \"newLine\": \"crlf\",                                /* Set the newline character for emitting files. */\n    // \"stripInternal\": true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */\n    // \"noEmitHelpers\": true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */\n    // \"noEmitOnError\": true,                            /* Disable emitting files if any type checking errors are reported. */\n    // \"preserveConstEnums\": true,                       /* Disable erasing 'const enum' declarations in generated code. */\n    // \"declarationDir\": \"./\",                           /* Specify the output directory for generated declaration files. */\n    // \"preserveValueImports\": true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */\n\n    /* Interop Constraints */\n    // \"isolatedModules\": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */\n    // \"verbatimModuleSyntax\": true,                     /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */\n    // \"allowSyntheticDefaultImports\": true,             /* Allow 'import x from y' when a module doesn't have a default export. */\n    \"esModuleInterop\": true,\n    /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */\n    // \"preserveSymlinks\": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */\n    \"forceConsistentCasingInFileNames\": true,\n    /* Ensure that casing is correct in imports. */\n\n    /* Type Checking */\n    \"strict\": true,\n    /* Enable all strict type-checking options. */\n    // \"noImplicitAny\": true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */\n    // \"strictNullChecks\": true,                         /* When type checking, take into account 'null' and 'undefined'. */\n    // \"strictFunctionTypes\": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */\n    // \"strictBindCallApply\": true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */\n    // \"strictPropertyInitialization\": true,             /* Check for class properties that are declared but not set in the constructor. */\n    // \"noImplicitThis\": true,                           /* Enable error reporting when 'this' is given the type 'any'. */\n    // \"useUnknownInCatchVariables\": true,               /* Default catch clause variables as 'unknown' instead of 'any'. */\n    // \"alwaysStrict\": true,                             /* Ensure 'use strict' is always emitted. */\n    // \"noUnusedLocals\": true,                           /* Enable error reporting when local variables aren't read. */\n    // \"noUnusedParameters\": true,                       /* Raise an error when a function parameter isn't read. */\n    // \"exactOptionalPropertyTypes\": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */\n    // \"noImplicitReturns\": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */\n    // \"noFallthroughCasesInSwitch\": true,               /* Enable error reporting for fallthrough cases in switch statements. */\n    // \"noUncheckedIndexedAccess\": true,                 /* Add 'undefined' to a type when accessed using an index. */\n    // \"noImplicitOverride\": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */\n    // \"noPropertyAccessFromIndexSignature\": true,       /* Enforces using indexed accessors for keys declared using an indexed type. */\n    // \"allowUnusedLabels\": true,                        /* Disable error reporting for unused labels. */\n    // \"allowUnreachableCode\": true,                     /* Disable error reporting for unreachable code. */\n\n    /* Completeness */\n    // \"skipDefaultLibCheck\": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */\n    \"skipLibCheck\": true\n    /* Skip type checking all .d.ts files. */\n  }\n}\n"
  },
  {
    "path": "db/Dockerfile",
    "content": "FROM mysql:8.0\n\nADD setup.sql /docker-entrypoint-initdb.d\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3.9'\n\nservices:\n  frontend:\n    container_name: frontend\n    build:\n      context: ./next\n      dockerfile: Dockerfile\n    ports:\n      - \"3000:3000\"\n    volumes:\n      - ./next/.env:/next/.env\n      - ./next/:/next/\n      - /next/node_modules\n      - /next/.next\n\n  platform:\n    container_name: platform\n    build:\n      context: ./platform\n      target: prod\n    ports:\n      - \"8000:8000\"\n    restart: always\n    volumes:\n      - ./platform:/app/src/\n    env_file:\n      - next/.env\n    environment:\n      REWORKD_PLATFORM_HOST: 0.0.0.0\n      REWORKD_PLATFORM_DB_HOST: agentgpt_db\n      REWORKD_PLATFORM_DB_PORT: \"3307\"\n      REWORKD_PLATFORM_DB_USER: \"reworkd_platform\"\n      REWORKD_PLATFORM_DB_PASS: \"reworkd_platform\"\n      REWORKD_PLATFORM_DB_BASE: \"reworkd_platform\"\n    depends_on:\n      - agentgpt_db\n\n  agentgpt_db:\n    image: mysql:8.0\n    container_name: agentgpt_db\n    restart: always\n    build:\n      context: ./db\n    ports:\n      - \"3308:3307\"\n    environment:\n      MYSQL_DATABASE: \"reworkd_platform\"\n      MYSQL_USER: \"reworkd_platform\"\n      MYSQL_PASSWORD: \"reworkd_platform\"\n      MYSQL_ROOT_PASSWORD: \"reworkd_platform\"\n      MYSQL_TCP_PORT: 3307\n    volumes:\n      - agentgpt_db:/var/lib/mysql\n    command: [ 'mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci' ]\n\nvolumes:\n  agentgpt_db:\n"
  },
  {
    "path": "docs/README.hu-Cs4K1Sr4C.md",
    "content": "<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/reworkd/AgentGPT/main/public/banner.png?token=GHSAT0AAAAAAB7JND3U3VGGF3UYYHGYO4RAZBSDJAQ\" height=\"300\"/>\n</p>\n<p align=\"center\">\n  <em>🤖 Szerelje össze, konfigurálja és telepítse az autonóm AI-ügynököket a böngészőjében. 🤖 </em>\n</p>\n<p align=\"center\">\n    <img alt=\"Node version\" src=\"https://img.shields.io/static/v1?label=node&message=%20%3E=16.0.0&logo=node.js&color=2334D058\" />\n      <a href=\"https://github.com/reworkd/AgentGPT/blob/master/README.md\"><img src=\"https://img.shields.io/badge/lang-English-blue.svg\" alt=\"English\"></a>\n  <a href=\"https://github.com/reworkd/AgentGPT/blob/master/docs/README.zh-HANS.md\"><img src=\"https://img.shields.io/badge/lang-简体中文-red.svg\" alt=\"简体中文\"></a>\n  <a href=\"https://github.com/reworkd/AgentGPT/blob/master/docs/README.hu-Cs4K1Sr4C.md\"><img src=\"https://img.shields.io/badge/lang-Hungarian-red.svg\" alt=\"Hungarian\"></a>\n</p>\n\n<p align=\"center\">\n<a href=\"https://agentgpt.reworkd.ai\">🔗 Weboldal</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"#-getting-started\">🤝 Hozzájárulás</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://twitter.com/asimdotshrestha/status/1644883727707959296\">🐦 Twitter</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://discord.gg/gcmNyAAFfV\">📢 Discord</a>\n</p>\n\n---\n\n<h2 align=\"center\">\n💝 Támogassa az AgentGPT fejlesztését!! 💝\n</h2>\n\n<p align=\"center\">\nCsatlakozzon hozzánk, az AgentGPT fejlesztéséhez, egy nyílt forráskódú projekthez, amely az AI automatizálás határait feszegeti! Kihívásokkal nézünk szembe a működési költségek fedezése 💸, beleértve a házon belüli API-t és egyéb infrastrukturális költségeket, amelyek az előrejelzések szerint körülbelül napi 150 USD-ra nőnek. 💳🤕 Az Ön szponzorálása elősegítené a fejlődést azáltal, hogy segít nekünk az erőforrások bővítésében, a funkciók és a funkcionalitás bővítésében, valamint az izgalmas projekt folytatásában! 🚀\n</p>\n\n<p align=\"center\">\nEnnek az ingyenes, nyílt forráskódú projektnek a szponzorálásával nem csak az avatarod/logódat láthatod alább, hanem exkluzív lehetőséget kapsz az alapítókkal való beszélgetésre is!🗣️\n</p>\n\n<p align=\"center\">\n<a href=\"https://github.com/sponsors/reworkd-admin\">👉 Kattint ide</a> ha szeretnéd támogatni a projektet\n</p>\n\n<h3 align=\"center\">\n🙌🏻 Szponzoraink 🙌🏻\n</h3>\n\n<div align=\"center\" dir=\"auto\">\n  <!-- sponsors --><a href=\"https://github.com/arthurbnhm\"><img src=\"https://github.com/arthurbnhm.png\" width=\"60px\" alt=\"Arthur\" /></a><a href=\"https://github.com/mrayonnaise\"><img src=\"https://github.com/mrayonnaise.png\" width=\"60px\" alt=\"Matt Ray\" /></a><a href=\"https://github.com/iv-ann\"><img src=\"https://github.com/iv-ann.png\" width=\"60px\" alt=\"Ivan\" /></a><a href=\"https://github.com/alex-shortt\"><img src=\"https://github.com/alex-shortt.png\" width=\"60px\" alt=\"Alex Shortt\" /></a><a href=\"https://github.com/echallenge\"><img src=\"https://github.com/echallenge.png\" width=\"60px\" alt=\"eDad\" /></a><a href=\"https://github.com/jd3655\"><img src=\"https://github.com/jd3655.png\" width=\"60px\" alt=\"Vector Ventures\" /></a><a href=\"https://github.com/PersonMan65\"><img src=\"https://github.com/PersonMan65.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/peth-yursick\"><img src=\"https://github.com/peth-yursick.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/durairajasivam\"><img src=\"https://github.com/durairajasivam.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/floriank\"><img src=\"https://github.com/floriank.png\" width=\"60px\" alt=\"Florian Kraft\" /></a><a href=\"https://github.com/SicilianaTrevino\"><img src=\"https://github.com/SicilianaTrevino.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/andrewpeluso\"><img src=\"https://github.com/andrewpeluso.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/localecho\"><img src=\"https://github.com/localecho.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/fireheat135\"><img src=\"https://github.com/fireheat135.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/ashventure\"><img src=\"https://github.com/ashventure.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/biolippi\"><img src=\"https://github.com/biolippi.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/orkunisitmak\"><img src=\"https://github.com/orkunisitmak.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/zoelidity\"><img src=\"https://github.com/zoelidity.png\" width=\"60px\" alt=\"Zoe\" /></a><a href=\"https://github.com/busseyl\"><img src=\"https://github.com/busseyl.png\" width=\"60px\" alt=\"Lucas Bussey\" /></a><a href=\"https://github.com/DuanChaori\"><img src=\"https://github.com/DuanChaori.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Faitltd\"><img src=\"https://github.com/Faitltd.png\" width=\"60px\" alt=\"fAIt\" /></a><a href=\"https://github.com/jukwaphil1\"><img src=\"https://github.com/jukwaphil1.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/lisa-ee\"><img src=\"https://github.com/lisa-ee.png\" width=\"60px\" alt=\"Lisa\" /></a><a href=\"https://github.com/VulcanT\"><img src=\"https://github.com/VulcanT.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/kman62\"><img src=\"https://github.com/kman62.png\" width=\"60px\" alt=\"kmotte\" /></a><a href=\"https://github.com/Haithamhaj\"><img src=\"https://github.com/Haithamhaj.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/SwftCoins\"><img src=\"https://github.com/SwftCoins.png\" width=\"60px\" alt=\"SWFT Blockchain\" /></a><a href=\"https://github.com/ChevalierzA\"><img src=\"https://github.com/ChevalierzA.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/research-developer\"><img src=\"https://github.com/research-developer.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Wetradetogether\"><img src=\"https://github.com/Wetradetogether.png\" width=\"60px\" alt=\"Wetradetogether Corporation\" /></a><a href=\"https://github.com/keanuhsieh\"><img src=\"https://github.com/keanuhsieh.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/sorrynothing\"><img src=\"https://github.com/sorrynothing.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/FelixAI2023\"><img src=\"https://github.com/FelixAI2023.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Mitchell-Coder-New\"><img src=\"https://github.com/Mitchell-Coder-New.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Xiaofeixiao0309\"><img src=\"https://github.com/Xiaofeixiao0309.png\" width=\"60px\" alt=\"XIAO FEI\" /></a><a href=\"https://github.com/jondwillis\"><img src=\"https://github.com/jondwillis.png\" width=\"60px\" alt=\"jon\" /></a><a href=\"https://github.com/mojosolo\"><img src=\"https://github.com/mojosolo.png\" width=\"60px\" alt=\"MojoSolo\" /></a><a href=\"https://github.com/Trecares\"><img src=\"https://github.com/Trecares.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/nnkostov\"><img src=\"https://github.com/nnkostov.png\" width=\"60px\" alt=\"Nikolay Kostov\" /></a><a href=\"https://github.com/mfcolbrie\"><img src=\"https://github.com/mfcolbrie.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/oryanmoshe\"><img src=\"https://github.com/oryanmoshe.png\" width=\"60px\" alt=\"Oryan Moshe\" /></a><a href=\"https://github.com/newjxmaster\"><img src=\"https://github.com/newjxmaster.png\" width=\"60px\" alt=\"Napole\" /></a><a href=\"https://github.com/jofe03\"><img src=\"https://github.com/jofe03.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/DanielRobertKelly\"><img src=\"https://github.com/DanielRobertKelly.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/genetrader\"><img src=\"https://github.com/genetrader.png\" width=\"60px\" alt=\"Gene Waxman\" /></a><a href=\"https://github.com/NerdDeWallStreet\"><img src=\"https://github.com/NerdDeWallStreet.png\" width=\"60px\" alt=\"Nerd de Wall Street\" /></a><a href=\"https://github.com/qwe777897\"><img src=\"https://github.com/qwe777897.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/tudorw\"><img src=\"https://github.com/tudorw.png\" width=\"60px\" alt=\"Tudor Watson\" /></a><a href=\"https://github.com/ClayNelson\"><img src=\"https://github.com/ClayNelson.png\" width=\"60px\" alt=\"Clay Nelson\" /></a><a href=\"https://github.com/johnopaluwa\"><img src=\"https://github.com/johnopaluwa.png\" width=\"60px\" alt=\"Opaluwa John\" /></a><a href=\"https://github.com/Mamadouff\"><img src=\"https://github.com/Mamadouff.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/xuxizhen\"><img src=\"https://github.com/xuxizhen.png\" width=\"60px\" alt=\"xizhen\" /></a><a href=\"https://github.com/ShamrockYuma\"><img src=\"https://github.com/ShamrockYuma.png\" width=\"60px\" alt=\"Elizabeth\" /></a><a href=\"https://github.com/thecatfix\"><img src=\"https://github.com/thecatfix.png\" width=\"60px\" alt=\"John Shelburne\" /></a><a href=\"https://github.com/18900775855\"><img src=\"https://github.com/18900775855.png\" width=\"60px\" alt=\"bin\" /></a><a href=\"https://github.com/destro225\"><img src=\"https://github.com/destro225.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/0xmatchmaker\"><img src=\"https://github.com/0xmatchmaker.png\" width=\"60px\" alt=\"0xmatchmaker\" /></a><a href=\"https://github.com/dray3310\"><img src=\"https://github.com/dray3310.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/mgesteban\"><img src=\"https://github.com/mgesteban.png\" width=\"60px\" alt=\"Grace Esteban\" /></a><a href=\"https://github.com/fegodi\"><img src=\"https://github.com/fegodi.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/kylburns89\"><img src=\"https://github.com/kylburns89.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Ademrobert\"><img src=\"https://github.com/Ademrobert.png\" width=\"60px\" alt=\"Adem Ottoman\" /></a><a href=\"https://github.com/mouhaxp\"><img src=\"https://github.com/mouhaxp.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/carlosbartolomeu\"><img src=\"https://github.com/carlosbartolomeu.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Zoffra1984\"><img src=\"https://github.com/Zoffra1984.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Agronobeetles\"><img src=\"https://github.com/Agronobeetles.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/CloudyGuyThompson\"><img src=\"https://github.com/CloudyGuyThompson.png\" width=\"60px\" alt=\"Guy Thompson\" /></a><a href=\"https://github.com/rocogirl-jp\"><img src=\"https://github.com/rocogirl-jp.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Jhonvolt17\"><img src=\"https://github.com/Jhonvolt17.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/koltziver\"><img src=\"https://github.com/koltziver.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/meeuwsstefaan\"><img src=\"https://github.com/meeuwsstefaan.png\" width=\"60px\" alt=\"Stefaan Meeuws\" /></a><a href=\"https://github.com/sirswali\"><img src=\"https://github.com/sirswali.png\" width=\"60px\" alt=\"Vusi Dube\" /></a><a href=\"https://github.com/Tweezamiza\"><img src=\"https://github.com/Tweezamiza.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Kenono2000\"><img src=\"https://github.com/Kenono2000.png\" width=\"60px\" alt=\"Ken Wong\" /></a><a href=\"https://github.com/QuickBenx\"><img src=\"https://github.com/QuickBenx.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/ouguajian\"><img src=\"https://github.com/ouguajian.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/DixonFyre\"><img src=\"https://github.com/DixonFyre.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/ospl99\"><img src=\"https://github.com/ospl99.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/bbookser\"><img src=\"https://github.com/bbookser.png\" width=\"60px\" alt=\"Bradford Bookser\" /></a><a href=\"https://github.com/abhirichster\"><img src=\"https://github.com/abhirichster.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/SwingPoint\"><img src=\"https://github.com/SwingPoint.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jenius-eagle\"><img src=\"https://github.com/jenius-eagle.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/CubanCongaMan\"><img src=\"https://github.com/CubanCongaMan.png\" width=\"60px\" alt=\"Roberto Luis Sanchez, P.E., P.G.; D,GE; F.ASCE\" /></a><a href=\"https://github.com/cskrobec\"><img src=\"https://github.com/cskrobec.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Jahmazon\"><img src=\"https://github.com/Jahmazon.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jackPan010203\"><img src=\"https://github.com/jackPan010203.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/pmespresso\"><img src=\"https://github.com/pmespresso.png\" width=\"60px\" alt=\"πisk0mate\" /></a><a href=\"https://github.com/itbc2004\"><img src=\"https://github.com/itbc2004.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/ISDAworld\"><img src=\"https://github.com/ISDAworld.png\" width=\"60px\" alt=\"David Gammond\" /></a><a href=\"https://github.com/mattlwaters\"><img src=\"https://github.com/mattlwaters.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Stargard\"><img src=\"https://github.com/Stargard.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/lazzacapital\"><img src=\"https://github.com/lazzacapital.png\" width=\"60px\" alt=\"Lazza Capital\" /></a><a href=\"https://github.com/MichaelRDionne\"><img src=\"https://github.com/MichaelRDionne.png\" width=\"60px\" alt=\"Michael R Dionne\" /></a><a href=\"https://github.com/nilotpalc\"><img src=\"https://github.com/nilotpalc.png\" width=\"60px\" alt=\"Nilotpal Choudhury\" /></a><a href=\"https://github.com/FrankyPete\"><img src=\"https://github.com/FrankyPete.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/TylerrDurden1979\"><img src=\"https://github.com/TylerrDurden1979.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/OptionalJoystick\"><img src=\"https://github.com/OptionalJoystick.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/PaulV27\"><img src=\"https://github.com/PaulV27.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/rodolfoguzzi\"><img src=\"https://github.com/rodolfoguzzi.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/bluecat2210\"><img src=\"https://github.com/bluecat2210.png\" width=\"60px\" alt=\"\" /></a><!-- sponsors -->\n\n</div>\n\n---\n\nAz AgentGPT lehetővé teszi az automatizált AI-ügynökök konfigurálását és üzembe helyezését.\nNevezze el saját egyéni mesterséges intelligenciáját, és tegye lehetővé, hogy bármilyen célt elérjen.\nMegkísérli elérni a célt az elvégzendő feladatok átgondolásával, végrehajtásával és az eredményekből való tanulással 🚀.\n\n## 🎉 Útiterv\n\nEz a platform jelenleg béta állapotban van és a következőkön dolgozunk:\n\n- Hosszú távú memória vektoros DB-n keresztül 🧠\n- Webböngészési lehetőségek a LangChain-en keresztül 🌐\n- Interakció webhelyekkel és emberekkel 👨‍👩‍👦\n- Írási lehetőségek egy dokumentum API-n keresztül 📄\n- Az AI-ügynökök mentése 💾\n- Felhasználók és hitelesítés 🔐\n- Stripe integráció egy alsó limites fizetős verzióhoz (hogy ne aggódjunk az infra költségek miatt) 💵\n\nHamarosan még több jön...\n\n## 🚀 Tech Stack\n\n- ✅ **Bootstrapping**: [create-t3-app](https://create.t3.gg).\n- ✅ **Framework**: [Nextjs 13 + Typescript](https://nextjs.org/).\n- ✅ **Auth**: [Next-Auth.js](https://next-auth.js.org)\n- ✅ **ORM**: [Prisma](https://prisma.io).\n- ✅ **Database**: [Supabase](https://supabase.com/).\n- ✅ **Styling**: [TailwindCSS + HeadlessUI](https://tailwindcss.com).\n- ✅ **Typescript Schema Validation**: [Zod](https://github.com/colinhacks/zod).\n- ✅ **End-to-end typesafe API**: [tRPC](https://trpc.io/).\n\n## 👨‍🚀 Első lépések\n\n### 🐳 Docker beállítása\n\nAz AgentGPT helyi futtatásának legegyszerűbb módja a Docker használata.\nEgy kényelmes beállítási szkriptet biztosítunk az induláshoz.\n\n```bash\n./setup.sh --docker\n```\n\n### 👷 Helyi fejlesztési beállítások\n\nHa helyben szeretné fejleszteni az Agent GPT-t, a legegyszerűbb módja a mellékelt telepítőszkript használata.\n\n```bash\n./setup.sh --local\n```\n\n### 🛠️ Manuális beállítás\n\n> 🚧 Szüksége lesz a [Nodejs +18 (LTS recommended)](https://nodejs.org/en/) telepítésre.\n\n1. Elágaztatni a tárat\n\n- [Elágaztatás](https://github.com/reworkd/AgentGPT/fork).\n\n2. Klónozni a tárolót:\n\n```bash\ngit clone git@github.com:YOU_USER/AgentGPT.git\n```\n\n3. Függőségek telepítése:\n\n```bash\ncd AgentGPT\nnpm install\n```\n\n4. Hozzon létre egy **.env** fájlt a következő tartalommal:\n\n> 🚧 A környezeti változóknak meg kell egyeznie a következő [sémával](https://github.com/reworkd/AgentGPT/blob/main/src/env/schema.mjs).\n\n```bash\n# Telepítési környezet:\nNODE_ENV=development\n\n# Következő hitelesítési konfiguráció:\n# Hozzon létre egy titkos kulcsot az `openssl rand -base64 32` paranccsal\nNEXTAUTH_SECRET=VÁLTOZTASS_MEG\nNEXTAUTH_URL=http://localhost:3000\nDATABASE_URL=file:./db.sqlite\n\n# OpenAI API kulcs\nOPENAI_API_KEY=VÁLTOZTASS_MEG\n```\n\n5. Módosítsa a prisma sémát az sqlite használatához:\n\n```bash\n./prisma/useSqlite.sh\n```\n\n**Megjegyzés:** Ezt csak akkor kell megtenni, ha sqlite-ot szeretne használni.\n\n6. Kész 🥳, következő a futtatás:\n\n```bash\n# Adatbázis-migrálások létrehozása\nnpx prisma db push\nnpm run dev\n```\n\n### 🚀 GitHub Codespaces\n\nÁllítsa be azonnal az AgentGPT-t a felhőben a [GitHub Codespaces](https://github.com/features/codespaces) használatával.\n\n1. A GitHub-tárhelyen kattintson a zöld \"Kód\" gombra, és válassza a \"Kódterek\" lehetőséget.\n2. Hozzon létre egy új kódteret, vagy válasszon egy előzőt, amelyet már létrehozott.\n3. A kódtér külön lapon nyílik meg a böngészőben.\n4. A terminálban futtassa a `bash ./setup.sh --local` parancsot\n5. Amikor a terminál kéri, adja hozzá OpenAI API-kulcsát.\n6. Kattintson a \"Megnyitás böngészőben\" gombra, amikor az összeállítási folyamat befejeződött.\n\n- Az AgentGPT leállításához írja be a Ctrl+C billentyűkombinációt a terminálba.\n- Az AgentGPT újraindításához futtassa az \"npm run dev\" parancsot a terminálban.\n\nFuttassa a projektet 🥳\n\n```\nnpm run dev\n```\n\n---\n\n<h3 align=\"center\">\n🙌🏻 További szponzoraink 🙌🏻\n</h3>\n\n<div align=\"center\" dir=\"auto\">\n  <a href=\"https://github.com/Trecares\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/Trecares.png\" width=\"50px\" alt=\"Trecares\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/oryanmoshe\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/oryanmoshe.png\" width=\"50px\" alt=\"oryanmoshe\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/rekimcn\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/rekimcn.png\" width=\"50px\" alt=\"rekimcn\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/qwe777897\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/qwe777897.png\" width=\"50px\" alt=\"qwe777897\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/ClayNelson\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/ClayNelson.png\" width=\"50px\" alt=\"ClayNelson\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/xuxizhen\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/xuxizhen.png\" width=\"50px\" alt=\"xuxizhen\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/destro225\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/destro225.png\" width=\"50px\" alt=\"destro225\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/mouhaxp\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/mouhaxp.png\" width=\"50px\" alt=\"mouhaxp\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/carlosbartolomeu\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/carlosbartolomeu.png\" width=\"50px\" alt=\"carlosbartolomeu\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/Agronobeetles\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/Agronobeetles.png\" width=\"50px\" alt=\"Agronobeetles \" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/CloudyGuyThompson\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/CloudyGuyThompson.png\" width=\"50px\" alt=\"CloudyGuyThompson\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/xinghz\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/xinghz.png\" width=\"50px\" alt=\"xinghz\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/Jaimbart\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/Jaimbart.png\" width=\"50px\" alt=\"Jaimbart\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/Jhonvolt17\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/Jhonvolt17.png\" width=\"50px\" alt=\"Jhonvolt17\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/koltziver\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/koltziver.png\" width=\"50px\" alt=\"koltziver\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/sirswali\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/sirswali.png\" width=\"50px\" alt=\"sirswali\" style=\"max-width:100%;\">\n  </a>\n  <a href=\"https://github.com/DixonFyre\" style=\"display: inline-block; margin-right: 20px;\">\n    <img src=\"https://github.com/DixonFyre.png\" width=\"50px\" alt=\"DixonFyre\" style=\"max-width:100%;\">\n  </a>\n\n</div>\n"
  },
  {
    "path": "docs/README.md",
    "content": ""
  },
  {
    "path": "docs/README.zh-HANS.md",
    "content": "<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/reworkd/AgentGPT/main/next/public/banner.png\" height=\"300\" alt=\"AgentGPT Logo\"/>\n</p>\n<p align=\"center\">\n  <em>🤖 组装，配置和部署自主的 AI 代理（只需浏览器） 🤖 </em>\n</p>\n<p align=\"center\">\n    <img alt=\"Node version\" src=\"https://img.shields.io/static/v1?label=node&message=%20%3E=18&logo=node.js&color=2334D058\" />\n      <a href=\"https://github.com/reworkd/AgentGPT/blob/master/README.md\"><img src=\"https://img.shields.io/badge/lang-English-blue.svg\" alt=\"English\"></a>\n  <a href=\"https://github.com/reworkd/AgentGPT/blob/master/docs/README.zh-HANS.md\"><img src=\"https://img.shields.io/badge/lang-简体中文-red.svg\" alt=\"简体中文\"></a>\n  <a href=\"https://github.com/reworkd/AgentGPT/blob/master/docs/README.hu-Cs4K1Sr4C.md\"><img src=\"https://img.shields.io/badge/lang-Hungarian-red.svg\" alt=\"Hungarian\"></a>\n</p>\n\n<p align=\"center\">\n<a href=\"https://agentgpt.reworkd.ai\">🔗 短链接</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://reworkd.ai/docs\">📚 文档</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://twitter.com/reworkdai\">🐦 推特</a>\n<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>\n<a href=\"https://discord.gg/gcmNyAAFfV\">📢 Discord</a>\n</p>\n\nAgentGPT允许您配置和部署自主AI代理。\n为您自己的定制AI命名，并使其追求任何可以想象到的目标。\n它将通过思考要执行的任务、执行这些任务并从结果中学习来尝试实现目标🚀。\n\n---\n\n## ✨ 演示\n为了获得最佳的演示体验，请直接访问 [our site](https://agentgpt.reworkd.ai) :)\n\n[Demo Video](https://github.com/reworkd/AgentGPT/assets/50181239/5348e44a-29a5-4280-a06b-fe1429a8d99e)\n\n\n## 👨‍🚀 开始使用\n\n使用AgentGPT的最简单方法是自动设置CLI，该CLI与项目捆绑在一起。\ncli为AgentGPT设置了以下内容：\n- 🔐 [Environment variables](https://github.com/reworkd/AgentGPT/blob/main/.env.example) (和 API 密钥)\n- 🗂️ [Database](https://github.com/reworkd/AgentGPT/tree/main/db) (Mysql)\n- 🤖 [Backend](https://github.com/reworkd/AgentGPT/tree/main/platform) (FastAPI)\n- 🎨 [Frontend](https://github.com/reworkd/AgentGPT/tree/main/next) (Nextjs)\n\n## 先决条件👆\n\n开始之前，请确保您已安装了以下内容：\n\n- 选择你的编辑器，例如[Visual Studio Code (VS Code)](https://code.visualstudio.com/download)\n- [Node.js](https://nodejs.org/en/download)\n- [Git](https://git-scm.com/downloads)\n- [Docker](https://www.docker.com/products/docker-desktop). 安装完成后，请创建一个账号，打开 Docker 应用程序，并登录。\n- 一个 [OpenAI API key](https://platform.openai.com/signup)\n- 一个 [Serper API Key](https://serper.dev/signup) (可选)\n- 一个 [Replicate API Token](https://replicate.com/signin) (可选)\n\n## 入门指南🚀\n1. **打开你的编辑器**\n\n2. **打开终端** - 通常，你可以在'Terminal'标签页中执行此操作，或者使用快捷键\n（例如，在 VS Code 中，对于 Windows 可以使用 `Ctrl + ~`，对于 Mac 可以使用 `Control + ~`）。\n\n3. **克隆存储库并进入目录** - 一旦您的终端打开，您可以通过运行下面的命令克隆存储库并进入目录。\n\n   **For Mac/Linux users** 🍎 🐧\n   ```bash\n   git clone https://github.com/reworkd/AgentGPT.git\n   cd AgentGPT\n   ./setup.sh\n   ```\n   **For Windows users** :windows:\n   ```bash\n   git clone https://github.com/reworkd/AgentGPT.git\n   cd AgentGPT\n   ./setup.bat\n   ```\n4. **按照脚本中的设置说明进行操作。** - 在添加适当的 API 密钥之后，确保所有服务都已经运行起来，然后在您的网页浏览器中访问 [http://localhost:3000](http://localhost:3000)。\n\n黑客快乐! 🎉\n\n\n## 🚀 技术栈\n\n- ✅ **Bootstrapping**: [create-t3-app](https://create.t3.gg) + [FastAPI-template](https://github.com/s3rius/FastAPI-template).\n- ✅ **Framework**: [Nextjs 13 + Typescript](https://nextjs.org/) + [FastAPI](https://fastapi.tiangolo.com/)\n- ✅ **Auth**: [Next-Auth.js](https://next-auth.js.org)\n- ✅ **ORM**: [Prisma](https://prisma.io) & [SQLModel](https://sqlmodel.tiangolo.com/).\n- ✅ **Database**: [Planetscale](https://planetscale.com/).\n- ✅ **Styling**: [TailwindCSS + HeadlessUI](https://tailwindcss.com).\n- ✅ **Schema Validation**: [Zod](https://github.com/colinhacks/zod) + [Pydantic](https://docs.pydantic.dev/).\n- ✅ **LLM Tooling**: [Langchain](https://github.com/hwchase17/langchain).\n\n\n<h2 align=\"center\">\n💝 支持 AgentGPT 的发展!! 💝\n</h2>\n\n<p align=\"center\">\n加入我们，共同推动AgentGPT的发展，这是一个突破人工智能代理边界的开源项目！您的赞助将通过帮助我们扩大资源、增强功能和继续迭代这个令人兴奋的项目来推动进步！🚀\n</p>\n\n<p align=\"center\">\n<!-- sponsors --><a href=\"https://github.com/arthurbnhm\"><img src=\"https://github.com/arthurbnhm.png\" width=\"60px\" alt=\"Arthur\" /></a><a href=\"https://github.com/mrayonnaise\"><img src=\"https://github.com/mrayonnaise.png\" width=\"60px\" alt=\"Matt Ray\" /></a><a href=\"https://github.com/jd3655\"><img src=\"https://github.com/jd3655.png\" width=\"60px\" alt=\"Vector Ventures\" /></a><a href=\"https://github.com/durairajasivam\"><img src=\"https://github.com/durairajasivam.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/floriank\"><img src=\"https://github.com/floriank.png\" width=\"60px\" alt=\"Florian Kraft\" /></a><a href=\"https://github.com/localecho\"><img src=\"https://github.com/localecho.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/fireheat135\"><img src=\"https://github.com/fireheat135.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/zoelidity\"><img src=\"https://github.com/zoelidity.png\" width=\"60px\" alt=\"Zoe\" /></a><a href=\"https://github.com/busseyl\"><img src=\"https://github.com/busseyl.png\" width=\"60px\" alt=\"Lucas Bussey\" /></a><a href=\"https://github.com/DuanChaori\"><img src=\"https://github.com/DuanChaori.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jukwaphil1\"><img src=\"https://github.com/jukwaphil1.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/lisa-ee\"><img src=\"https://github.com/lisa-ee.png\" width=\"60px\" alt=\"Lisa\" /></a><a href=\"https://github.com/VulcanT\"><img src=\"https://github.com/VulcanT.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/kman62\"><img src=\"https://github.com/kman62.png\" width=\"60px\" alt=\"kmotte\" /></a><a href=\"https://github.com/Haithamhaj\"><img src=\"https://github.com/Haithamhaj.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/SwftCoins\"><img src=\"https://github.com/SwftCoins.png\" width=\"60px\" alt=\"SWFT Blockchain\" /></a><a href=\"https://github.com/ChevalierzA\"><img src=\"https://github.com/ChevalierzA.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/research-developer\"><img src=\"https://github.com/research-developer.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Mitchell-Coder-New\"><img src=\"https://github.com/Mitchell-Coder-New.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Trecares\"><img src=\"https://github.com/Trecares.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/nnkostov\"><img src=\"https://github.com/nnkostov.png\" width=\"60px\" alt=\"Nikolay Kostov\" /></a><a href=\"https://github.com/oryanmoshe\"><img src=\"https://github.com/oryanmoshe.png\" width=\"60px\" alt=\"Oryan Moshe\" /></a><a href=\"https://github.com/ClayNelson\"><img src=\"https://github.com/ClayNelson.png\" width=\"60px\" alt=\"Clay Nelson\" /></a><a href=\"https://github.com/0xmatchmaker\"><img src=\"https://github.com/0xmatchmaker.png\" width=\"60px\" alt=\"0xmatchmaker\" /></a><a href=\"https://github.com/carlosbartolomeu\"><img src=\"https://github.com/carlosbartolomeu.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Agronobeetles\"><img src=\"https://github.com/Agronobeetles.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/CloudyGuyThompson\"><img src=\"https://github.com/CloudyGuyThompson.png\" width=\"60px\" alt=\"Guy Thompson\" /></a><a href=\"https://github.com/Jhonvolt17\"><img src=\"https://github.com/Jhonvolt17.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/sirswali\"><img src=\"https://github.com/sirswali.png\" width=\"60px\" alt=\"Vusi Dube\" /></a><a href=\"https://github.com/Tweezamiza\"><img src=\"https://github.com/Tweezamiza.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/DixonFyre\"><img src=\"https://github.com/DixonFyre.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jenius-eagle\"><img src=\"https://github.com/jenius-eagle.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/CubanCongaMan\"><img src=\"https://github.com/CubanCongaMan.png\" width=\"60px\" alt=\"Roberto Luis Sanchez, P.E., P.G.; D,GE; F.ASCE\" /></a><a href=\"https://github.com/cskrobec\"><img src=\"https://github.com/cskrobec.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Jahmazon\"><img src=\"https://github.com/Jahmazon.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/ISDAworld\"><img src=\"https://github.com/ISDAworld.png\" width=\"60px\" alt=\"David Gammond\" /></a><a href=\"https://github.com/lazzacapital\"><img src=\"https://github.com/lazzacapital.png\" width=\"60px\" alt=\"Lazza Capital\" /></a><a href=\"https://github.com/OptionalJoystick\"><img src=\"https://github.com/OptionalJoystick.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/rodolfoguzzi\"><img src=\"https://github.com/rodolfoguzzi.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/bluecat2210\"><img src=\"https://github.com/bluecat2210.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/dactylogram9\"><img src=\"https://github.com/dactylogram9.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/RUFreeJAC63\"><img src=\"https://github.com/RUFreeJAC63.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/cecilmiles\"><img src=\"https://github.com/cecilmiles.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Djarielm007\"><img src=\"https://github.com/Djarielm007.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/mikenj07\"><img src=\"https://github.com/mikenj07.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/SvetaMolusk\"><img src=\"https://github.com/SvetaMolusk.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/wuminkung\"><img src=\"https://github.com/wuminkung.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/zhoumo1221\"><img src=\"https://github.com/zhoumo1221.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/Stefan6666XXX\"><img src=\"https://github.com/Stefan6666XXX.png\" width=\"60px\" alt=\"Stephane DeGuire\" /></a><a href=\"https://github.com/lyska\"><img src=\"https://github.com/lyska.png\" width=\"60px\" alt=\"Lyska\" /></a><a href=\"https://github.com/KurganKolde\"><img src=\"https://github.com/KurganKolde.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/sclappccsu\"><img src=\"https://github.com/sclappccsu.png\" width=\"60px\" alt=\"Sharon Clapp at CCSU\" /></a><a href=\"https://github.com/Rooba-Finance\"><img src=\"https://github.com/Rooba-Finance.png\" width=\"60px\" alt=\"Rooba.Finance\" /></a><a href=\"https://github.com/ferienhausmiete\"><img src=\"https://github.com/ferienhausmiete.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/benjaminbales\"><img src=\"https://github.com/benjaminbales.png\" width=\"60px\" alt=\"Benjamin Bales\" /></a><a href=\"https://github.com/pimentel233\"><img src=\"https://github.com/pimentel233.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/PinkyWobbles\"><img src=\"https://github.com/PinkyWobbles.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/jconroy11\"><img src=\"https://github.com/jconroy11.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/DavidJamesRotenberg\"><img src=\"https://github.com/DavidJamesRotenberg.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/antecochat\"><img src=\"https://github.com/antecochat.png\" width=\"60px\" alt=\"\" /></a><a href=\"https://github.com/RealBonOfaSitch\"><img src=\"https://github.com/RealBonOfaSitch.png\" width=\"60px\" alt=\"\" /></a><!-- sponsors -->\n</p>\n\n<h2 align=\"center\">\n💪 贡献者 💪\n</h2>\n\n<p align=\"center\">\n我们的贡献者使这个项目成为可能。谢谢！🙏\n</p>\n\n<a href=\"https://github.com/reworkd/agentgpt/graphs/contributors\">\n  <img src=\"https://contrib.rocks/image?repo=reworkd/agentgpt\" />\n</a>\n\n<div align=\"center\">\n<sub>使用 <a href=\"https://contrib.rocks\">contrib.rocks</a>制作。</sub>\n</div>\n"
  },
  {
    "path": "docs/developers/api-keys.mdx",
    "content": "---\ntitle: API Keys\n---\n\nBefore you can use the Reworkd API, you will need to create an API key for your organization. To do this:\n1. Travel to the organization API key page. You may either visit [https://auth.reworkd.ai/org/api_keys/](https://auth.reworkd.ai/org/api_keys/) directly or click the settings button on the organization menu dropdown\n<Frame>\n  <img src=\"/images/organization-menu.png\" />\n</Frame>\n2. Ensure you are on the `Organization API Keys` page\n3. Click the `New API key` button and create a new API key with a reasonable expiration date\n\nYou should now be able to use your new API key to authenticate your requests. To do this, you will need to add the following header to your requests:\n```\nAuthorization: Bearer <YOUR-API-KEY>\n```\n"
  },
  {
    "path": "docs/developers/file-downloads.mdx",
    "content": "---\ntitle: Handling File Downloads\n---\nDifferent types of file downloads require different code strategies. This page outlines various strategies you may take.\n\n## Regular Download Links\nRegular downloads occur when the file link is directly available within the HTML (typically in the `href` of an `<a>` tag). Clicking these links directly initiates a file download.\n\nTo handle these downloads:\n\n1. Save the URL directly from the page.\n2. Reworkd will then asynchronously visit and download the file. We use `curl-cffi` mimicking browser behavior when downloading the file.\n\n```python\n# Select the link element\nlink = await sdk.page.query_selector('a.download')\n\n# Get the URL directly\nhref = await link.get_attribute(\"href\")\n\n# Save the URL, Lambda will handle the download\nawait sdk.save_data({\"download_url\": href })\n```\n\n## Indirect Download Links\n\nIndirect downloads happen when the direct link isn't immediately visible but becomes available after clicking a button or link.\n\nTo handle indirect downloads:\n\n1. Click the button/link to open the URL.\n2. Capture and save the newly loaded URL.\n3. Automatically navigate back.\n\n```python\n# Select element to open page\nelement = await sdk.page.query_selector('button.download')\n\n# Capture the URL after clicking\ndownload_url = await sdk.capture_url(element)\n\n# Save URL for download via Lambda\nawait sdk.save_data({\"download_url\": download_url })\n```\n\n## JavaScript/Dynamic Downloads\n\nDynamic downloads occur when a file download is triggered by JavaScript events directly in the browser, without a direct URL.\n\nTo handle dynamic downloads:\n\n1. Use `capture_download` method to trigger and capture the download directly in the browser.\n2. Retrieve the file metadata (URL and title).\n\n```python\n# Select element triggering download\nelement = await sdk.page.query_selector('button.download')\n\n# Capture download event directly\ndownload_metadata = await sdk.capture_download(element)\n\n# Save file metadata directly\nawait sdk.save_data({\n    \"attachment\": {\n        \"download_url\": download_metadata[\"url\"],\n        \"title\": download_metadata[\"title\"],\n    },\n})\n```\n\n## Downloads Requiring Cookies/Session\n\nSome sites require the download to occur within the same browser session that accessed the page, making AWS Lambda unsuitable.\n\nIn these cases:\n\n- Follow the same approach as dynamic downloads, handling the download directly in the browser context using `capture_download`.\n"
  },
  {
    "path": "docs/developers/sdk.mdx",
    "content": "---\ntitle: Scraping SDK\n---\n\nAs part of code generation, Reworkd generates code in its own custom SDK called [Harambe](https://github.com/reworkd/harambe).\nHarambe is web scraping SDK with a number of useful methods and features for:\n- Saving data and validating that the data follows a specific schema\n- Enqueuing (and automatically formatting) urls\n- De-duplicating saved data, urls, etc\n- Effectively handling classic web scraping problems like pagination, pdfs, downloads, etc\n\nThese methods, what they do, how they work, and some examples of how to use them will be highlighted below.\n\n\n---\n\n## `save_data`\nSave scraped data and validate its type matches the current schema\n\n**Signature:**\n```python\ndef save_data(self, data: dict[str, Any], source_url: str | None = None) -> None\n```\n**Params:**\n- `data`: Rows of data (as dictionaries) to save\n- `source_url`: Optional URL to associate with the data, defaults to current page URL. Only use this if the source of the data is different than the current page when the data is saved\n\n\n\n\n**Raises:**\n- `SchemaValidationError`: If any of the saved data does not match the provided schema\n\n\n**Example:**\n```python\nawait sdk.save_data({ \"title\": \"example\", \"description\": \"another_example\" })\nawait sdk.save_data({ \"title\": \"example\", \"description\": \"another_example\" }, source_url=\"https://www.example.com/product/example_id\")\n```\n---\n\n## `enqueue`\nEnqueue url(s) to be scraped later.\n\n**Signature:**\n```python\ndef enqueue(self, urls: str | Awaitable[str], context: dict[str, Any] | None = None, options: dict[str, Any] | None = None) -> None\n```\n**Params:**\n- `urls`: urls to enqueue\n- `context`: additional context to pass to the next run of the next stage/url. Typically just data that is only available on the current page but required in the schema. Only use this when some data is available on this page, but not on the page that is enqueued.\n- `options`: job level options to pass to the next stage/url\n\n\n\n\n\n\n**Example:**\n```python\nawait sdk.enqueue(\"https://www.test.com\")\nawait sdk.enqueue(\"/some-path\") # This will automatically be converted into an absolute url\n```\n---\n\n## `paginate`\nSDK method to automatically facilitate paginating a list of elements.\nSimply define a function that should return any of:\n- A direct link to the next page\n- An element with hrefs to the next page\n- An element to click on to get to the next page\nAnd call `sdk.paginate` at the end of your scrape function. The element will automatically be used to paginate the site and run the scraping code against all pages\nPagination will conclude once all pages are reached no next page element is found.\nThis method should ALWAYS be used for pagination instead of manual for loops and if statements.\n\n**Signature:**\n```python\ndef paginate(self, get_next_page_element: Callable[Ellipsis, Awaitable[str | playwright.async_api._generated.ElementHandle | None]], timeout: int = 2000) -> None\n```\n**Params:**\n- `get_next_page_element`: the url or ElementHandle of the next page\n- `timeout`: milliseconds to sleep for before continuing. Only use if there is no other wait option\n\n\n\n\n\n\n**Example:**\n```python\nasync def pager():\n    return await page.query_selector(\"div.pagination > .pager.next\")\n\nawait sdk.paginate(pager)\n```\n---\n\n## `capture_url`\nCapture the url of a click event. This will click the element and return the url\nvia network request interception. This is useful for capturing urls that are\ngenerated dynamically (eg: redirects to document downloads).\n\n**Signature:**\n```python\ndef capture_url(self, clickable: ElementHandle, resource_type: Literal[document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other, *] = 'document', timeout: int | None = 10000) -> str | None\n```\n**Params:**\n- `clickable`: the element to click\n- `resource_type`: the type of resource to capture\n- `timeout`: the time to wait for the new page to open (in ms)\n\n\n**Return Value:**\nurl: the url of the captured resource or None if no match was found\n\n**Raises:**\n- `ValueError`: if more than one page is created by the click event\n\n\n\n---\n\n## `capture_download`\nCapture a download event that gets triggered by clicking an element. This method will:\n- Handle clicking the element\n- Download the resulting file\n- Apply download handling logic and build a download URL\n- Return a download metadata object\nUse this method to manually download dynamic files or files that can only be downloaded in the current browser session.\n\n**Signature:**\n```python\ndef capture_download(self, clickable: ElementHandle, override_filename: str | None = None, override_url: str | None = None, timeout: float | None = None) -> DownloadMeta\n```\n\n\n**Return Value:**\nDownloadMeta: A typed dict containing the download metadata such as the `url` and `filename`\n\n\n\n\n---\n\n## `capture_html`\nCapture and download the html content of the document or a specific element.\nThe returned HTML will be cleaned of any excluded elements and will be wrapped in a proper HTML document structure.\n\n**Signature:**\n```python\ndef capture_html(self, selector: str = 'html', exclude_selectors: list[str] | None = None, soup_transform: Callable[BeautifulSoup, None] | None = None, html_converter_type: Literal[markdown, text] = 'markdown') -> HTMLMetadata\n```\n**Params:**\n- `selector`: CSS selector of element to capture. Defaults to \"html\" for the document element.\n- `exclude_selectors`: List of CSS selectors for elements to exclude from capture.\n- `soup_transform`: A function to transform the BeautifulSoup html prior to saving. Use this to remove aspects of the returned content\n- `html_converter_type`: Type of HTML converter to use for the inner text. Defaults to \"markdown\".\n\n\n**Return Value:**\nHTMLMetadata containing the `html` of the element, the formatted `text` of the element, along with the `url` and `filename` of the document\n\n**Raises:**\n- `ValueError`: If the specified selector doesn't match any element.\n\n\n**Example:**\n```python\nmeta = await sdk.capture_html(selector=\"div.content\")\nawait sdk.save_data({\"name\": meta[\"filename\"], \"text\": meta[\"text\"], \"download_url\": meta[\"url\"]})\n```\n---\n\n## `capture_pdf`\nCapture the current page as a pdf and then apply some download handling logic\nfrom the observer to transform to a usable URL\n\n**Signature:**\n```python\ndef capture_pdf(self) -> DownloadMeta\n```\n\n\n**Return Value:**\nDownloadMeta: A typed dict containing the download metadata such as the `url` and `filename`\n\n\n\n**Example:**\n```python\nmeta = await sdk.capture_pdf()\nawait sdk.save_data({\"file_name\": meta[\"filename\"], \"download_url\": meta[\"url\"]})\n```\n---\n\n## `log`\nLog a message via both `print` and `console.log` if a browser is running\nConcatenates all arguments with spaces.\nArgs:\n*args: Values to log (will be concatenated)\n\n**Signature:**\n```python\ndef log(self, args) -> None\n```\n\n"
  },
  {
    "path": "docs/docs.json",
    "content": "{\n  \"$schema\": \"https://mintlify.com/docs.json\",\n  \"theme\": \"mint\",\n  \"name\": \"Reworkd\",\n    \"background\": {\n    \"color\": {\n      \"light\": \"#FBFCFD\",\n      \"dark\": \"#11181C\"\n    }\n  },\n  \"colors\": {\n    \"primary\": \"#7E868C\",\n    \"light\": \"#7E868C\",\n    \"dark\": \"#7E868C\"\n  },\n\n  \"favicon\": \"/favicon.png\",\n  \"navigation\": {\n    \"tabs\": [\n      {\n        \"tab\": \"Documentation\",\n        \"icon\": \"book-open\",\n        \"groups\": [\n          {\n            \"group\": \"Get Started\",\n            \"pages\": [\n              \"introduction\",\n              \"key-concepts\",\n              \"schemas\"\n            ]\n          },\n          {\n            \"group\": \"Features\",\n            \"pages\": [\n              \"features/deduplication\",\n              {\n                \"group\": \"Exports\",\n                \"pages\": [\n                  \"features/exports/overview\",\n                  \"features/exports/api-exports\",\n                  \"features/exports/bulk-exports\"\n                ]\n              },\n              \"features/scheduling\",\n              \"features/templates\",\n              \"features/file-downloads\"\n            ]\n          },\n          {\n            \"group\": \"Developers\",\n            \"pages\": [\n              \"developers/api-keys\",\n              \"developers/sdk\",\n              \"developers/file-downloads\"\n            ]\n          }\n        ]\n      },\n      {\n        \"tab\": \"API Reference\",\n        \"icon\": \"book-open\",\n        \"openapi\": \"https://api.reworkd.dev/api/openapi.json\"\n      }\n    ],\n    \"global\": {\n      \"anchors\": [\n        {\n          \"anchor\": \"Website\",\n          \"href\": \"https://www.reworkd.ai/\",\n          \"icon\": \"globe\"\n        },\n        {\n          \"anchor\": \"GitHub\",\n          \"href\": \"https://github.com/reworkd\",\n          \"icon\": \"github\"\n        }\n      ]\n    }\n  },\n  \"logo\": {\n    \"light\": \"/images/logo.png\",\n    \"dark\": \"/images/logo-light.png\"\n  },\n\n  \"navbar\": {\n    \"primary\": {\n      \"type\": \"github\",\n      \"href\": \"https://github.com/reworkd\"\n    }\n  },\n  \"footer\": {\n    \"socials\": {\n      \"github\": \"https://github.com/reworkd\",\n      \"twitter\": \"https://twitter.com/ReworkdAI\",\n      \"linkedin\": \"https://www.linkedin.com/company/reworkd/\"\n    }\n  }\n}\n"
  },
  {
    "path": "docs/features/deduplication.mdx",
    "content": "---\ntitle: Deduplication\ndescription: Automatically generate scrapers\n---\n\nReworkd automatically handles deduplicating data whenever your scrapers re-run.\n\n## How It Works\n\nWhen saving data, Reworkd uses a **unique key** (or composite key) based on the record's fields to determine if the data is new or if it is a duplicate of data that has already been saved.\n\n\n| Scenario | Action Taken by Reworkd |\n| --- | --- |\n| **New row of data saved** | Inserts data and marks as a `CREATE` change. |\n| **Duplicate row of data saved** | Skips insertion; no duplicate is created. |\n| **Updating data that has been seen before (existing key)** | Updates existing record without duplication and marks as an `UPDATE` change |\n\n## Defining your Deduplication Key\n\nWhen you are creating your schema, you must also select which of the fields you want to use as part of your **primary/deduplication key**.\nThis deduplication key is critical to ensure you avoid duplicated data. It must:\n\n- ✅ **Be unique** for every output row.\n- ✅ **Remain stable** over time (avoid frequently changing fields).\n- ✅ **Be consistent**. Regardless of what website you are on, this key must be the same for the same item.\n\nIf there is no one obvious key field, use multiple attributes to create a reliable **composite key**.\n\n\n## Good vs. Poor Key Examples\n#### Good key choices\n- Unique ID like a **SKU** or **UPC**\n- Combination of unique attributes like **Brand + Model + Color**\n\n#### Poor key choices\n- Price (frequently changes)\n- Availability status (frequently fluctuating)\n- Timestamp of last update\n"
  },
  {
    "path": "docs/features/exports/api-exports.mdx",
    "content": "---\ntitle: API Exports\ndescription: Export data via our APIs\n---\n\nThe most common way for our customers to ingest our data is via our API endpoints.\nIf you haven't already, create an API key by following our [API key documentation](/developers/api-keys) and get started with our API below.\n\n<CardGroup cols={1}>\n  <Card title=\"Outputs API\" icon=\"chart-mixed\" href=\"/api-reference/public/get-outputs-for-a-scraping-group\">\n    Full API documentation for how to export data from your groups\n  </Card>\n</CardGroup>\n\n\n## Getting only new data\nUse the `created_after` query parameter to filter for data created after your last ingestion.\n\nTypically our customers will call our API once a day, keeping track of the exact datetime in which they made the API call.\nAny subsequent API calls they make will set `created_after` to the previously recorded datetime.\n"
  },
  {
    "path": "docs/features/exports/bulk-exports.mdx",
    "content": "---\ntitle: Bulk Exports\ndescription: Export data via our UI\n---\n\nBulk exports are JSON or CSV files of all of the scraped data within a group or job.\nYou create bulk exports in our UI by selecting the group you want to export, and optionally selecting a job and/or a date you want to filter the data by.\n\nBulk exports are useful for getting a full snapshot of your data at a given point in time but our API exports should be the preferred export method for most use cases.\n\n<Warning>Note: Running an export for a large group may take a very long time to complete.</Warning>\n\n<CardGroup cols={1}>\n  <Card title=\"Reworkd Exports Page\" icon=\"files\" href=\"https://app.reworkd.ai/exports\">\n    Bulk export data from your scraping groups\n  </Card>\n</CardGroup>\n"
  },
  {
    "path": "docs/features/exports/overview.mdx",
    "content": "---\ntitle: Exports Overview\nsidebarTitle: Overview\ndescription: Exporting your data out of Reworkd\n---\n\n<CardGroup cols={2}>\n  <Card title=\"API Exports\" icon=\"chart-mixed\" href=\"/features/exports/api-exports\">\n    Dynamically export data from your groups via our APIs\n  </Card>\n    <Card title=\"Bulk Exports\" icon=\"files\" href=\"/features/exports/bulk-exports\">\n    Create single file exports of entire groups via our UI\n  </Card>\n</CardGroup>\n"
  },
  {
    "path": "docs/features/file-downloads.mdx",
    "content": "---\ntitle: File Downloads\n---\n\nReworkd can automatically handle downloading files on your behalf. Files are stored in our infrastructure, and download links to these files are provided in all export formats.\n\n## Setting up downloads\n\nTo configure automatic downloads:\n\n1. Create a field in your schema with the **URL** type.\n2. In the field settings, ensure **Download file from URL** is set to `True`.\n3. Create a job that will save the download URL to a file in this field.\n\nOnce the job is run, the file linked in that URL will be automatically downloaded.\n<Warning>\n    Note: File downloads happen asynchronously. It may take time for files to appear in your exports.\n</Warning>\n\n## Retrieving files\n\nFile download links will be included in the `files` array of your exports.\n\nExample API response for file data:\n```json\n{\n    ...\n    \"files\": [\n        {\n            \"id\": \"70057eca-d05c-4a33-ae84-4af8dce83ce3\",\n            \"field\": \"attachments[0].url\",\n            \"url_etag_hash\": \"92359181252f9b52a4da21599fbf8f8d.pdf\",\n            \"s3_key\": \"test_key.pdf\",\n            \"s3_url\": \"https://files.reworkd.dev/test_url\",\n            \"source_url\": \"https://source-website.com/download/49a42973\",\n            \"create_date\": \"2024-08-26T18:49:31.575000\",\n            \"file_url\": \"s3://deworkd-prod-files/11ee111ee.pdf\",\n            \"file_type\": \"pdf\",\n            \"file_checksum\": \"7eec76e4bd1fed22f5d7d5fa7efbeaf717a77da771bb5c61e09b0d7ae46bbd\",\n            \"file_metadata\": {\n                \"url\": \"https://source-website.com/download/49a42973\",\n                \"filename\": \"Test document.pdf\",\n                \"dynamic_download\": \"true\"\n            }\n        }\n    ],\n    ...\n}\n```\n\n### Key fields\n\n- `s3_url`: Pre-signed URL to retrieve the file from our S3 bucket.\n- `source_url`: Original URL of the file; points to our S3 bucket if no canonical source URL exists. If so, file_metadata.dynamic_download will be set to true.\n- `field`: Indicates which field in the output data the file relates to.\n\n\n## How are files downloaded?\n#### Regular downloads\nRegular downloads occur when files are directly accessible via a URL (e.g., direct PDF links).\n- The canonical URL of the file is used and saved\n- Files are downloaded asynchronously via AWS Lambda using a dedicated download queue. Delays may occur.\n\n#### Dynamic downloads\nDynamic downloads occur when there is no canonical URL available, typically triggered via JavaScript or requiring active session information.\n- Files are downloaded directly in the browser worker to guarantee accuracy.\n- Because no canonical link is available, the link to the current page is used as the source URL.\n- For more technical details, see Handling file downloading.\n\n## File storage\n**We can only guarantee that your downloaded files remain stored within our S3 buckets for 90 days.**\nIf your use case requires longer retention periods, please let us know!\n"
  },
  {
    "path": "docs/features/scheduling.mdx",
    "content": "---\ntitle: Scheduling\ndescription: Re-use scrapers across identical sites\n---\n\nYou can schedule groups to be re-run at a specific cadence. To set a schedule, go to the settings tab within a group and select the schedule you want to use.\n\n## Overriding schedules\nOften there may be specific sources within a group that you want to run more or less frequently than the rest of the group.\nTo do this, you can override the schedule for the specific source by going into the settings tab of the job.\n\n## How are pages re-visited?\n#### Category/Listing pages\nAll higher level stages such as category and listing pages will always be re-run in subsequent runs.\nThey will enqueue and run all of their lower level stages (except for detail pages).\n\n#### Detail pages\nDetail page visits are de-duplicated. By we do not revisit detail pages after initially scraping its data by default.\nThis is because there is no consistent way to detect detail page changes without actually opening the page and re-running the extraction code. If you require detail page re-visits, please reach out to us!\n"
  },
  {
    "path": "docs/features/templates.mdx",
    "content": "---\ntitle: Templates\ndescription: Re-use scrapers across identical sites\n---\n\n<Note>Note: Templates are not available for hobby plan customers</Note>\n\nWhen scraping, you'll often encounter multiple websites using identical underlying structures or sharing the same web provider.\nInstead of repeatedly writing new scrapers for each of these websites—which consumes both your time and LLM tokens—use Templates.\n\nTemplates allow you to save and re-use pre-built scraper code.\nOnce created, templates can be applied to multiple websites with matching structures, without any extra effort required.\nThis means whenever the structure of these websites changes, you only need to update the template once to instantly fix the issue for all associated sites, rather than manually updating each individual scraper.\n"
  },
  {
    "path": "docs/introduction.mdx",
    "content": "---\ntitle: Introduction\ndescription: Reworkd - Extract web data at scale\n---\n\n<Frame>\n    <img src=\"/images/banner.png\" />\n</Frame>\n\nReworkd uses LLMs to parse, understand, and interact with web pages to help users scrape web data at ***scale***.\nReworkd customers are extracting millions of rows of data to help build data constrained products, fine tune domain specific language models, and enrich existing data pipelines.\n\n<Info>\n    We also built AgentGPT! If you're looking for info on AgentGPT, please visit our\n    [Github](https://github.com/reworkd/AgentGPT)\n</Info>\n\n<CardGroup cols={2}>\n    <Card title=\"Build your first scraper\" icon=\"lightbulb\" href=\"https://app.arcade.software/share/6GkFKiXytq3lXQU3JWAx\">\n        Learn how to scrape a website and its sub pages with Reworkd\n    </Card>\n    <Card title=\"Key terms\" icon=\"brain\" href=\"/key-concepts\">\n        Understand all of the key terms required to get started\n    </Card>\n    <Card title=\"Exporting data\" icon=\"globe\" href=\"/features/exports/overview\">\n        Learn how to export the data you scrape\n    </Card>\n    <Card title=\"Blog\" icon=\"rss\" href=\"https://www.reworkd.ai/blog\">\n        Read the latest updates on the Reworkd blog\n    </Card>\n</CardGroup>\n"
  },
  {
    "path": "docs/key-concepts.mdx",
    "content": "---\ntitle: Key Concepts\ndescription: Everything you need to get started with Reworkd\n---\n\n# Groups\nA group is the first thing you create when you use Reworkd.\nGroups are a collection of source urls/jobs that share a common schema and scraping frequency.\n\nFor example, if you were looking to scrape multiple online bookstores for book data, you might create a **Bookstore** group\nand add all of the bookstore source URLs within it.\n\n### Schemas\nA schema is a structured definition of the data you want to scrape from a website. Read more about schemas in our [Schemas](/features/schemas) page.\nAll jobs within a group will share the same schema.\n\n# Jobs\nA job represents a distinct source URL within a scraping group.\nWe break jobs down to various stages as a scraper flows through a website and enqueues additional pages.\nWe consider the first job the source job, and any jobs that get enqueued by the source job are considered child jobs.\n\n\nJobs can be configured with various settings such as proxy types, timeouts, and other parameters to optimize the scraping process for different page requirements.\n\n### Stages\nEvery job is associated with a specific type of stage. Suppose you are wanting to scrape an e-commerce website.\n1. The first stage might be the **category** page. This page would list all of the different categories of products available on the site such as shirts, pants, shoes, etc.\nThis job would go through and enqueue all of these categories as listing pages.\n2. Each **listing** page would just be all of the products under a specific category. For example, it may be a list of pants.\nListing jobs would just go through each page of the list and enqueue the associated product detail page.\n3. Finally, the **detail** page would be the final page. This page contains all of the information about a specific product. This job would just save the data of the product and be done.\n\n# Run\nA `Run` is a single execution of a scraping job.\nJob runs are essential for tracking the status and results of each scraping attempt, ensuring data is consistently collected and processed correctly;\nthey can also be retried upon failures to enhance data accuracy.\nAdditionally, job runs often generate a list of outputs, capturing the extracted data or links to be further processed.\n"
  },
  {
    "path": "docs/schemas.mdx",
    "content": "---\ntitle: Schemas\n---\nSchemas are the definition for the exact data format you expect websites within a particular group to use.\nEvery row of data Reworkd processes will go through a strict schema validation process to guaranteed your data is consistent with your schema.\n\n## Schema field types\nSchemas support both basic data types like strings and numbers along with a collection of advanced fields that apply transformations to the data:\n\n- **URL**: A string field that transform relative URLs into absolute URLs and fail if an invalid URL is provided. URL fields will also allow you to download files from whatever URL is provided. See the Downloading files page for more information.\n- **Phone Number**: A string field that will case cast values to known phone number types\n- **Currency**\n\n## What makes for a good schema?\nHow well you can scrape a page is is heavily impacted by your schema choices. Here are some loose guides on making a good schema:\n1. Simple. The less fields there are, the less room for error there.\n2. Only use fields you need today. Do not build schemas for fields you probably won't need\n3. Ensure schema fields actually appear on the page.\n   - Do not include nice-to-have fields that never actually appear on any website\n   - Do not include fields that are only present in one of your 10s/100s/1000s of websites\n4. **Capture fields as they appear on the page.** If they appear as arbitrary strings but your system requires them to be in domain specific enums, capture them as strings and create your own post processing layer to transform them as necessary\n5. Avoid derived field: fields that are generated from other fields in the schema. Derived fields should be handled in your own application code\n6. Ensure fields are unambiguous\n   - Carefully name fields as they appear on websites\n   - Provide field descriptions and example values where possible to clarify ambiguity. Clarify industry specific naming jargon and describe all of the different aliases that a given field may go by on the site\n7. Use advanced fields if possible. They abstract away some of the complexities of data transformations from LLMs leading to lower failures and higher data consistency\n\n## What if the page is missing fields?\nOften not every website will conform to the unified schema you’ve created.\nSometimes individual pages may be missing fields while other times the entire website itself may not present a field.\n\nIf the field is missing, it will be left as null in the output. If it is an array, it will be left as an empty array.\n"
  },
  {
    "path": "next/.dockerignore",
    "content": "**/.git\n**/node_modules\n**/idea\n**/.next\n**/aws\n**/.husky\n**/venv"
  },
  {
    "path": "next/.eslintrc.json",
    "content": "{\n  \"overrides\": [\n    {\n      \"extends\": [\n        \"plugin:@typescript-eslint/recommended-requiring-type-checking\"\n      ],\n      \"files\": [\n        \"*.ts\",\n        \"*.tsx\"\n      ],\n      \"parserOptions\": {\n        \"project\": \"tsconfig.json\"\n      }\n    }\n  ],\n  \"parser\": \"@typescript-eslint/parser\",\n  \"parserOptions\": {\n    \"project\": \"./tsconfig.json\"\n  },\n  \"plugins\": [\n    \"@typescript-eslint\", \"import\"\n  ],\n  \"extends\": [\n    \"next/core-web-vitals\",\n    \"plugin:@typescript-eslint/recommended\"\n  ],\n  \"rules\": {\n    \"@typescript-eslint/consistent-type-imports\": \"warn\",\n    \"@typescript-eslint/no-unused-vars\": \"off\",\n    \"@typescript-eslint/no-unsafe-return\": \"off\",\n    \"@typescript-eslint/no-unsafe-member-access\": \"off\",\n    \"@typescript-eslint/no-unsafe-call\": \"off\",\n    \"@typescript-eslint/no-unsafe-assignment\": \"off\",\n    \"@typescript-eslint/no-unsafe-argument\": \"off\",\n    \"@typescript-eslint/ban-ts-comment\": \"off\",\n    \"@typescript-eslint/no-restricted-imports\": [\n      \"error\",\n      {\n        \"paths\": [\n          {\n            \"name\": \"react-i18next\",\n            \"importNames\": [\n              \"useTranslation\"\n            ],\n            \"message\": \"Import useTranslation from next-i18next instead.\"\n          }\n        ]\n      }\n    ],\n    \"import/no-unresolved\": \"error\",\n       // \"import/no-named-as-default-member\": \"off\",\n       \"import/order\": [\n         \"error\",\n         {\n           \"groups\": [\n             \"builtin\", // Built-in imports (come from NodeJS native) go first\n             \"external\", // <- External imports\n             \"internal\", // <- Absolute imports\n             [\"sibling\", \"parent\"], // <- Relative imports, the sibling and parent types they can be mingled together\n             \"index\", // <- index imports\n             \"unknown\" // <- unknown\n           ],\n           \"newlines-between\": \"always\",\n           \"alphabetize\": {\n             /* sort in ascending order. Options: [\"ignore\", \"asc\", \"desc\"] */\n             \"order\": \"asc\",\n             /* ignore case. Options: [true, false] */\n             \"caseInsensitive\": true\n           }\n         }\n       ]\n  }\n}\n"
  },
  {
    "path": "next/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# database\n/prisma/db.sqlite\n/prisma/db.sqlite-journal\n/db/db.sqlite\n\n# next.js\n/.next/\n/out/\nnext-env.d.ts\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n# local env files\n# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables\n.env*\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\n.idea\n.swc\n\n# extracted language files\n/public/locales/$LOCALES\n\n.eslintcache\n\n# Sentry Auth Token\n.sentryclirc\n/volumes/\n"
  },
  {
    "path": "next/.husky/.gitignore",
    "content": "_\n"
  },
  {
    "path": "next/.husky/pre-commit",
    "content": "#!/usr/bin/env sh\n\n#npx lint-staged --allow-empty\n"
  },
  {
    "path": "next/Dockerfile",
    "content": "# Use the official Node.js image as the base image\nFROM node:19-alpine\n\nARG NODE_ENV\n\nENV NODE_ENV=$NODE_ENV\n\n# Needed for the wait-for-db script\nRUN apk add --no-cache netcat-openbsd\n\n# Set the working directory\nWORKDIR /next\n\n# Copy package.json and package-lock.json to the working directory\nCOPY package*.json ./\n\n# Install dependencies\nRUN npm ci\n\n# Copy the wait-for-db.sh script\nCOPY wait-for-db.sh /usr/local/bin/wait-for-db.sh\nRUN chmod +x /usr/local/bin/wait-for-db.sh\n\n# Copy the rest of the application code\nCOPY . .\nCOPY entrypoint.sh /\n\n# Ensure correct line endings after these files are edited by windows\nRUN apk add --no-cache dos2unix netcat-openbsd \\\n    && dos2unix /entrypoint.sh\n\n\n# Expose the port the app will run on\nEXPOSE 3000\n\nENTRYPOINT [\"sh\", \"/entrypoint.sh\"]\n\n# Start the application\nCMD [\"npm\", \"run\", \"dev\"]\n"
  },
  {
    "path": "next/__mocks__/matchMedia.mock.ts",
    "content": "// When using the matchMedia API in your tests, you will need to mock it.\nObject.defineProperty(window, \"matchMedia\", {\n  writable: true,\n  value: jest.fn().mockImplementation((query: string) => ({\n    matches: false,\n    media: query,\n    onchange: null,\n    addListener: jest.fn(), // Deprecated\n    removeListener: jest.fn(), // Deprecated\n    addEventListener: jest.fn(),\n    removeEventListener: jest.fn(),\n    dispatchEvent: jest.fn(),\n  })),\n});\n"
  },
  {
    "path": "next/__tests__/message-service.test.ts",
    "content": "import \"../__mocks__/matchMedia.mock\"\nimport type { Message } from \"../src/types/message\";\nimport { MessageService } from \"../src/services/agent/message-service\";\n\ndescribe(\"sendErrorMessage\", () => {\n  let instance: MessageService;\n  let renderMessage: jest.Mock;\n\n  beforeEach(() => {\n    renderMessage = jest.fn((message: Message) => ({}));\n    instance = new MessageService(renderMessage);\n  });\n\n  it(\"should handle Axios errors\", () => {\n    const axiosError = {\n      isAxiosError: true,\n      response: { status: 429, data: { detail: \"ERROR_API_KEY_QUOTA\" } },\n    };\n\n    instance.sendErrorMessage(axiosError);\n    expect(renderMessage).toHaveBeenCalledWith({\n      type: \"error\",\n      value: \"ERROR_API_KEY_QUOTA\",\n    });\n  });\n\n  it(\"should handle platform errors\", () => {\n    const axiosError = {\n      isAxiosError: true,\n      response: {\n        status: 409,\n        data: {\n          error: \"OpenAIError\",\n          detail: \"You have exceeded the maximum number of requests allowed for your API key.\",\n          code: 429,\n        },\n      },\n    };\n\n    instance.sendErrorMessage(axiosError);\n    expect(renderMessage).toHaveBeenCalledWith({\n      type: \"error\",\n      value: axiosError.response.data.detail,\n    });\n  });\n\n  it(\"should handle unknown platform errors\", () => {\n    const axiosError = {\n      isAxiosError: true,\n      response: { status: 409 },\n    };\n\n    instance.sendErrorMessage(axiosError);\n    expect(renderMessage).toHaveBeenCalledWith({\n      type: \"error\",\n      value: \"An Unknown Error Occurred, Please Try Again!\",\n    });\n  });\n\n  it(\"should handle non-Axios string errors\", () => {\n    const error = \"An error occurred\";\n\n    instance.sendErrorMessage(error);\n    expect(renderMessage).toHaveBeenCalledWith({\n      type: \"error\",\n      value: error,\n    });\n  });\n\n  it(\"should handle unknown errors\", () => {\n    instance.sendErrorMessage({});\n    expect(renderMessage).toHaveBeenCalledWith({\n      type: \"error\",\n      value: \"An unknown error occurred. Please try again later.\",\n    });\n  });\n});\n"
  },
  {
    "path": "next/__tests__/stripe.sh",
    "content": "stripe listen --forward-to localhost:3000/api/webhooks/stripe"
  },
  {
    "path": "next/__tests__/whitespace.test.ts",
    "content": "import { isEmptyOrBlank } from \"../src/utils/whitespace\";\n\ndescribe(\"WhiteSpace and empty string should return true\", () => {\n  test(\"Empty string should return true\", () => {\n    const emptyString = \"\";\n    expect(isEmptyOrBlank(emptyString)).toEqual(true);\n  })\n  test(\"WhiteSpace string should return true\", () => {\n    const whiteSpaceString = \"    \";\n    expect(isEmptyOrBlank(whiteSpaceString)).toEqual(true);\n  })\n  test(\"NewLine should return true\", () => {\n    const newLineString = \"\\n\\n\";\n    expect(isEmptyOrBlank(newLineString)).toEqual(true);\n  })\n})\n"
  },
  {
    "path": "next/__tests__/with-retries.test.ts",
    "content": "import { withRetries } from \"../src/services/api-utils\";\n\ndescribe(\"withRetries\", () => {\n  it(\"should retry 3 times by default\", async () => {\n    let numTries = 0;\n\n    await withRetries(\n      (): Promise<void> => {\n        ++numTries;\n        throw new Error();\n      },\n      (): Promise<boolean> => {\n        return Promise.resolve(true);\n      }\n    );\n\n    expect(numTries).toEqual(4);\n  });\n\n  it(\"should retry numRetries times on error\", async () => {\n    const numRetries = 5;\n    let numTries = 0;\n\n    await withRetries(\n      (): Promise<void> => {\n        ++numTries;\n        throw new Error();\n      },\n      (): Promise<boolean> => {\n        return Promise.resolve(true);\n      },\n      numRetries\n    );\n\n    expect(numTries).toEqual(numRetries + 1);\n  });\n\n  it(\"should retry if onError returns true\", async () => {\n    let numTries = 0;\n\n    await withRetries(\n      (): Promise<void> => {\n        ++numTries;\n        throw new Error();\n      },\n      (): Promise<boolean> => {\n        return Promise.resolve(true);\n      }\n    );\n\n    expect(numTries).toBeGreaterThan(1);\n  });\n\n  it(\"should stop if onError returns false\", async () => {\n    let numTries = 0;\n\n    await withRetries(\n      (): Promise<void> => {\n        ++numTries;\n        throw new Error();\n      },\n      (): Promise<boolean> => {\n        return Promise.resolve(false);\n      }\n    );\n\n    expect(numTries).toEqual(1);\n  });\n});\n"
  },
  {
    "path": "next/entrypoint.sh",
    "content": "#!/usr/bin/env sh\n\ncd /next\ndos2unix wait-for-db.sh\n\n# copy .env file if not exists\n[ ! -f .env ] && [ -f .env.example ] && cp .env.example .env\ncp .env .env.temp\ndos2unix .env.temp\ncat .env.temp > .env\nrm .env.temp\n\nsource .env\n\n# Ensure DB is available before running Prisma commands\n./wait-for-db.sh agentgpt_db 3307\n\n# Run Prisma commands\nif [[ ! -f \"/app/prisma/${DATABASE_URL:5}\" ]]; then\n  npx prisma migrate deploy --name init\n  npx prisma db push\nfi\n\n# Generate Prisma client\nnpx prisma generate\n\n# run cmd\nexec \"$@\"\n"
  },
  {
    "path": "next/jest.config.cjs",
    "content": "const nextJest = require(\"next/jest\");\n\nconst createJestConfig = nextJest({\n  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment\n  dir: \"./\",\n});\n\n// Add any custom config to be passed to Jest\n/** @type {import('jest').Config} */\nconst customJestConfig = {\n  // Add more setup options before each test is run\n  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],\n  // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work\n  moduleDirectories: [\"node_modules\", \"<rootDir>/\"],\n  testEnvironment: \"jest-environment-jsdom\",\n};\n\n// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async\nmodule.exports = createJestConfig(customJestConfig);\n"
  },
  {
    "path": "next/next-i18next.config.js",
    "content": "module.exports = {\n  i18n: {\n    defaultLocale: \"en\",\n    locales: [\n      \"en\",\n      \"hu\",\n      \"fr\",\n      \"de\",\n      \"it\",\n      \"ja\",\n      \"lt\",\n      \"zh\",\n      \"zhtw\",\n      \"ko\",\n      \"pl\",\n      \"pt\",\n      \"ro\",\n      \"ru\",\n      \"uk\",\n      \"es\",\n      \"nl\",\n      \"sk\",\n      \"hr\",\n      \"tr\",\n    ],\n  },\n  localePath: typeof window === \"undefined\" ? \"./public/locales\" : \"/locales\",\n  debug: false,\n  reloadOnPrerender: process.env.NODE_ENV === \"development\",\n  defaultNS: \"common\",\n  ns: [\"common\", \"help\", \"settings\", \"chat\", \"agent\", \"errors\", \"languages\", \"drawer\", \"indexPage\"],\n  react: {\n    useSuspense: false,\n  },\n  saveMissing: true,\n};\n"
  },
  {
    "path": "next/next.config.mjs",
    "content": "import nextI18NextConfig from \"./next-i18next.config.js\";\n\n// @ts-check\n/**\n * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.\n * This is especially useful for Docker builds.\n */\n!process.env.SKIP_ENV_VALIDATION && (await import(\"./src/env/server.mjs\"));\n\n/** @type {import(\"next\").NextConfig} */\nconst config = {\n  reactStrictMode: true,\n  /* If trying out the experimental appDir, comment the i18n config out\n   * @see https://github.com/vercel/next.js/issues/41980 */\n  i18n: nextI18NextConfig.i18n,\n  webpack: function(config, options) {\n    config.experiments = { asyncWebAssembly: true, layers: true };\n    config.watchOptions = {\n      poll: 1000,\n      aggregateTimeout: 300\n    };\n    config.module.rules.push({\n      test: /\\.svg$/i,\n      issuer: /\\.[jt]sx?$/,\n      use: ['@svgr/webpack'],\n    })\n    return config;\n  },\n  rewrites() {\n      return {\n          beforeFiles: [\n              {\n                  source: '/:path*',\n                  has: [\n                      {\n                          type: 'host',\n                          value: 'reworkd.ai',\n                      },\n                  ],\n                  destination: '/landing-page',\n              },\n          ]\n      }\n  }\n};\n\nexport default config;\n"
  },
  {
    "path": "next/package.json",
    "content": "{\n  \"name\": \"agent-gpt\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"engines\": {\n    \"node\": \">=18.0.0 <19.0.0\"\n  },\n  \"scripts\": {\n    \"build\": \"next build --no-lint\",\n    \"dev\": \"next dev\",\n    \"postinstall\": \"prisma generate\",\n    \"lint\": \"cross-env SKIP_ENV_VALIDATION=1 next lint --fix\",\n    \"start\": \"next start\",\n    \"prepare\": \"cd .. && husky install next/.husky\",\n    \"test\": \"cross-env SKIP_ENV_VALIDATION=1 jest\"\n  },\n  \"dependencies\": {\n    \"@headlessui/react\": \"^1.7.14\",\n    \"@next-auth/prisma-adapter\": \"^1.0.5\",\n    \"@prisma/client\": \"^4.9.0\",\n    \"@radix-ui/react-switch\": \"^1.0.2\",\n    \"@radix-ui/react-toast\": \"^1.1.4\",\n    \"@radix-ui/react-tooltip\": \"^1.0.5\",\n    \"@react-pdf/renderer\": \"^3.1.9\",\n    \"@sid-hq/sid\": \"^3.1.0\",\n    \"@splinetool/react-spline\": \"^2.2.6\",\n    \"@tailwindcss/forms\": \"^0.5.3\",\n    \"@tanstack/react-query\": \"^4.29.14\",\n    \"@trpc/client\": \"^10.21.1\",\n    \"@trpc/next\": \"^10.21.1\",\n    \"@trpc/react-query\": \"^10.21.1\",\n    \"@trpc/server\": \"^10.9.0\",\n    \"@types/lodash\": \"^4.14.194\",\n    \"@uiball/loaders\": \"^1.3.0\",\n    \"@vercel/analytics\": \"^1.0.1\",\n    \"@vercel/edge\": \"^0.3.4\",\n    \"axios\": \"^0.26.0\",\n    \"cheerio\": \"^1.0.0-rc.12\",\n    \"clsx\": \"^1.2.1\",\n    \"cobe\": \"^0.6.3\",\n    \"cookies-next\": \"^2.1.2\",\n    \"framer-motion\": \"^10.12.8\",\n    \"gray-matter\": \"^4.0.3\",\n    \"html-to-image\": \"^1.11.11\",\n    \"i18next\": \"^22.4.15\",\n    \"lodash\": \"^4.17.21\",\n    \"next\": \"^13.5.6\",\n    \"next-auth\": \"4.20.1\",\n    \"next-i18next\": \"^13.2.2\",\n    \"nextjs-google-analytics\": \"^2.3.3\",\n    \"openai\": \"^4.14.2\",\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"react-i18next\": \"^12.3.1\",\n    \"react-icons\": \"^4.11.0\",\n    \"react-markdown\": \"^8.0.7\",\n    \"react-type-animation\": \"^3.1.0\",\n    \"rehype-highlight\": \"^6.0.0\",\n    \"remark-gfm\": \"^3.0.1\",\n    \"superjson\": \"1.9.1\",\n    \"tailwindcss-radix\": \"^2.8.0\",\n    \"uuid\": \"^9.0.1\",\n    \"zod\": \"^3.22.2\",\n    \"zustand\": \"^4.3.7\"\n  },\n  \"devDependencies\": {\n    \"@svgr/webpack\": \"^8.0.1\",\n    \"@tailwindcss/typography\": \"^0.5.9\",\n    \"@testing-library/jest-dom\": \"^5.16.5\",\n    \"@testing-library/react\": \"^14.0.0\",\n    \"@types/node\": \"^18.11.18\",\n    \"@types/prettier\": \"^2.7.3\",\n    \"@types/react\": \"^18.0.26\",\n    \"@types/react-dom\": \"^18.2.7\",\n    \"@types/uuid\": \"^9.0.5\",\n    \"@typescript-eslint/eslint-plugin\": \"^5.59.8\",\n    \"@typescript-eslint/parser\": \"^5.59.1\",\n    \"autoprefixer\": \"^10.4.7\",\n    \"cross-env\": \"^7.0.3\",\n    \"eslint\": \"^8.43.0\",\n    \"eslint-config-next\": \"13.4.1\",\n    \"eslint-plugin-import\": \"^2.27.5\",\n    \"husky\": \"^8.0.3\",\n    \"jest\": \"^29.3.1\",\n    \"jest-environment-jsdom\": \"^29.7.0\",\n    \"lint-staged\": \"^13.2.1\",\n    \"postcss\": \"^8.4.24\",\n    \"prettier\": \"^2.8.8\",\n    \"prettier-plugin-tailwindcss\": \"^0.2.8\",\n    \"prisma\": \"^4.9.0\",\n    \"tailwindcss\": \"^3.3.2\",\n    \"typescript\": \"^5.1.3\"\n  },\n  \"ct3aMetadata\": {\n    \"initVersion\": \"7.4.0\"\n  },\n  \"lint-staged\": {\n    \"*.js\": \"eslint --cache --fix\",\n    \"*.{js,css,md}\": \"prettier --write\"\n  }\n}\n"
  },
  {
    "path": "next/postcss.config.cjs",
    "content": "module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n};\n"
  },
  {
    "path": "next/posts/Understanding-AgentGPT.mdx",
    "content": "---\ntitle: \"Understanding AgentGPT: How we build AI agents that reason, remember, and perform.\"\ndescription: \"How we build AI agents that reason, remember, and perform.\"\nimageUrl: \"https://petal-diplodocus-04a.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fef520689-ca1b-4489-98aa-41136f565840%2FCybrCo_Art_human-like_robot_typing_on_a_computer_in_a_dark_room_a0174b88-a5b9-4b82-98c6-734dbbde8d09.webp?id=f768fec9-bd6a-43ae-811d-1adb065c6c8e&table=block&spaceId=46c3481b-d8de-4c34-8647-2292d63a5f29&width=2000&userId=&cache=v2\"\ndate: \"July 17th, 2023\"\ndatetime: \"2023-07-17\"\ncategory:\n  title: \"Tech\"\n  href: \"#\"\nauthor:\n  name: \"Arthur Riechert\"\n  role: \"Writer\"\n  href: \"#\"\n  imageUrl: \"https://pbs.twimg.com/profile_images/1676828916546248704/5YMDlr1U_400x400.jpg\"\n---\n\n![CybrCo_Art_human-like_robot_typing_on_a_computer_in_a_dark_room_a0174b88-a5b9-4b82-98c6-734dbbde8d09.webp](https://petal-diplodocus-04a.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fef520689-ca1b-4489-98aa-41136f565840%2FCybrCo_Art_human-like_robot_typing_on_a_computer_in_a_dark_room_a0174b88-a5b9-4b82-98c6-734dbbde8d09.webp?id=f768fec9-bd6a-43ae-811d-1adb065c6c8e&table=block&spaceId=46c3481b-d8de-4c34-8647-2292d63a5f29&width=2000&userId=&cache=v2)\n\n> Alt: A robotic agent types at a laptop in a dark room.\n\n---\n\nThe invention of the **Generative Pre-trained Transformer (GPT)** is one of the recent decade's most important\nadvancements in AI technology. The GPTs powering today's **Large Language Models (LLMs)** demonstrate a _remarkable\nability for reasoning, understanding, and planning_. However, their true potential has yet to be fully realized.\n\nAt **Reworkd**, we believe that the _true power of LLMs lies in agentic behavior_. By engineering a system that draws on\nLLMs' emergent abilities and providing an ecosystem that supports environmental interactions, we can draw out the full\npotential of models like GPT-4. Here's how AgentGPT works.\n\n## LLMs have a lot of limitations.\n\nThe main products shipping LLMs are chatbots powered by\n\n[Foundation Model - Techopedia](https://www.techopedia.com/definition/34826/foundation-model).\n\nIf you have any familiarity working with OpenAI's API, a common formula you might use for chatting with the model may\ninclude:\n\n- Taking the user's message.\n- Adding a list of chat histories.\n- Sending the chat history across the API to retrieve a completion.\n\nThis method works fine when the scope of conversations is small; however, _as you continue adding new messages to the\nchat history, the size and complexity of completions balloons_, and you will quickly run into a wall: the dreaded\ncontext limit.\n\nA **context limit** is the maximum number of **tokens** (a token usually represents a single word) that can be input\ninto\nthe model for a single response. They are necessary because the _computational cost as we add additional tokens tends to\nincrease quadratically_. However, they are often the bane of prompt engineers.\n\nOne solution is to measure the number of tokens in the chat history before sending it to the model and removing old\nmessages to ensure it fits the token limit. While this approach works, it ultimately reduces the amount of knowledge\navailable to the assistant.\n\nAnother issue that standalone LLMs face is the need for human guidance. Fundamentally, LLMs are next-word predictors,\nand often, their internal structure is not inherently suited to higher-order thought processes, such as **reasoning**\nthrough complex tasks. This weakness doesn't mean they can't or don't reason. In fact, there are several [studies](https://arxiv.org/abs/2205.11916#:~:text=While%20these%20successes%20are%20often%20attributed%20to%20LLMs%27,%22Let%27s%20think%20step%20by%20step%22%20before%20each%20answer.) that shows they can. However, it does mean they face certain impediments. For example, the LLM itself can create a logical list of steps; however, it has _no built-in mechanisms for observation and reflection on that list._\n\nA pre-trained model is essentially a \"black box\" for the end user in which the final product that is shipped has\n_limited to no capability of actively updating its knowledge base and tends to act in unpredictable ways_. As a result,\nit's [hallucination](https://arxiv.org/abs/2202.03629)-prone.\n\nThus, it requires a lot of effort on the user's part to guide the model's output, and prompting the LLM itself becomes a\njob on its own. This extra work is a far cry from our vision of an AI-powered future.\n\nBy providing a platform to give LLMs agentic abilities, _AgentGPT aims to overcome the limitations of standalone LLMs by\nleveraging prompt engineering techniques, vector databases, and API tooling._ Here’s some interesting work that is being\ndone with the agent concept:\n\n[![Tweet by Dr. Jim Fan](https://platform.twitter.com/embed/Tweet.html?dnt=false&embedId=twitter-widget-0&frame=false&hideCard=false&hideThread=false&id=1673006745067847683&lang=en&origin=https%3A%2F%2Fpublish.twitter.com%2F%3Fquery%3Dhttps3A2F2Ftwitter.com2FDrJimFan2Fstatus2F1673006745067847683%26widget%3DTweet&theme=light&widgetsVersion=82e1070%3A1619632193066&width=550px)](https://twitter.com/DrJimFan/status/1673006745067847683)\n\n> Alt: A Twitter post by Dr. Jim Fan\n\n## What are agents?\n\nIn a general sense, [agents](https://zapier.com/blog/ai-agent/) are rational actors. They use thinking and reasoning to\ninfluence their environment. _This could be in the form of solving problems or pursuing specific goals. They might\ninteract with humans or utilize tools._ Ultimately, we can apply this concept to LLMs to instill more intelligent and\nlogical behavior.\n\nIn AgentGPT, large language models essentially function as the **brain** of each agent. As a result, we can produce\npowerful agents by cleverly _manipulating the English language_ and engineering a _framework that supports\ninteroperability between LLM completions and a diverse set of APIs_.\n\n### Engineering this system consists of 3 parts.\n\n**Reasoning and Planning.** If you were to simply take a general goal, such as \"build a scaling e-commerce platform,\"\nand\ngive it to ChatGPT, you would likely get a response along the lines of \"As an AI language model….\" However, through\n**prompt engineering**, we can get a model to _break down goals into digestible steps and reflect on them_ with a method\ncalled chain of thought prompting.\n\n**Memory.** When dealing with memory, we divide the problem into **short-term** and **long-term**. In managing\nshort-term\nmemory, we can use prompting techniques such as _few-shot prompting to steer LLM responses_. However, _cost and context\nlimits make it tricky to generate completions without limiting the breadth of information_ a model can use to make\ndecisions.\n\nSimilarly, this issue also arises in **long-term memory** because it would be impossible to provide an appropriate\ncorpus\nof writing to bridge the gap between GPT -4's cutoff date, 2021, till today. By using vector databases, we attempt to\novercome this using specialized models for _information retrieval in high-dimensional vector spaces_.\n\n**Tools**. Another challenge in using LLMs as general actors is their confinement to text outputs. Again, we can use\nprompt engineering techniques to solve this issue. We can generate predictable function calls from the LLM through\nfew-shot and chain-of-thought methods, utilizing API tools like **Google Search**, **Hugging Face**, **Dall-E**, etc. In\naddition, we can use fine-tuned LLMs that only return responses in specialized formatting, like JSON. This is the\napproach OpenAI took when they recently released the function calling feature for their API.\n\nThese three concepts have formed the backbone of multiple successful agent-based LLM platforms such\nas [Microsoft Jarvis](https://github.com/microsoft/JARVIS), [AutoGPT](https://github.com/Significant-Gravitas/Auto-GPT), [BabyAGI](https://github.com/yoheinakajima/babyagi),\nand of course, AgentGPT. With this brief overview in mind, let's dive deeper into each component.\n\n## How do we get agents to act intelligently?\n\n**Prompt engineering** has become highly popularized, and it's only natural given its ability to _increase the\nreliability of LLM responses_, opening a wide avenue of potential applications for generative AI. AgentGPT's ability to\nthink and reason is a result of novel prompting methods.\n\n### A Brief Intro to Prompt Engineering\n\nPrompt engineering is a largely empirical field that aims to find methods to steer LLM responses by finding clever ways\nto use the English language. _You can think of it like lawyering, where every nuance in the wording of a prompt counts._\n\nThese are the main concepts and building blocks for more advanced prompting techniques:\n\n1. **Zero-Shot** involves sending the raw command directly to the LLM with little to no formatting.\n2. **Few-Shot** gives context for completions in the form of example responses.\n3. **Chain-of-Thought** guides the model in reasoning through generating and reasoning over a complex task.\n\n### How AgentGPT Uses Prompt Engineering\n\nAgentGPT uses an advanced form of chain-of-thought prompting called **Plan-and-Solve** to generate the steps you see\nwhen\noperating the agents.\n\nTraditionally, chain-of-thought prompting utilized few-shot techniques to provide examples of a thinking and reasoning\nprocess. However, as is becomes a theme, it becomes more costly as the complexity of a task increases because we will\nneed to provide more context.\n\n**Plan-and-solve (PS):** By virtue of being a zero-shot method, it provides a _prompting framework for LLM-guided\nreasoning using \"trigger\" words_. These keywords trigger a reasoning response from the model.\n\nWe can expand on this concept by _modifying the prompt to extract important variables and steps to generate a final\nresponse with a cohesive format_. This method allows us to parse the final response and display it for the end user as\nwell as feed sub-steps into future plan-and-solve prompts.\n\n![Screen Shot 2023-07-01 at 12.25.37 PM.png](https://petal-diplodocus-04a.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F29d8c98c-21e6-4991-992d-62d95fd40dba%2FScreen_Shot_2023-07-01_at_12.25.37_PM.png?id=021895a6-149a-4282-aa8e-6719e7d7c47a&table=block&spaceId=46c3481b-d8de-4c34-8647-2292d63a5f29&width=2000&userId=&cache=v2)\n\n> Alt: Picture of Plan & Solve\n\nWhile PS prompting helps evoke a reasoning response, it still misses a fundamental concept in reasoning, and that is\nproper handling for reflection and action. **Reflection**is _fundamental for any agent because it must rationalize an\naction, perform that action, and use feedback to adjust future actions._ Without it, the agent would be stateless and\nunchanging.\n\nAgentGPT uses a prompting framework called Reasoning and Acting ([ReAct](https://arxiv.org/pdf/2210.03629.pdf)) to\nexpand on the capabilities of the Plan-and-Solve concept. **ReAct** aims to _enable a framework for the model to access\nfresh knowledge through external knowledge bases and make observations of actions it has taken_. Using those\nobservations, the LLM can make educated decisions on the next set of steps to complete while performing actions to query\nknowledge bases such as **Google Search** or **Wikipedia API**.\n\nPrompt engineering is largely effective in resolving challenges in short-term memory as well as instilling the reasoning\nbehavior that you can see when AgentGPT is at work. However, prompt engineering does not resolve the issue of long-term\nmemory. This issue is where vector databases come in, and we will look at those next.\n\n![Screen Shot 2023-07-03 at 3.12.56 AM.png](https://petal-diplodocus-04a.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F481f0812-00e5-4cb1-9ed6-4f2f9215eef5%2FScreen_Shot_2023-07-03_at_3.12.56_AM.png?id=8002f409-2913-4e68-b8b6-6100c4128cf5&table=block&spaceId=46c3481b-d8de-4c34-8647-2292d63a5f29&width=2000&userId=&cache=v2)\n\n> Alt : ReAct (Reason + Act) Logic Picture\n\n> The ReAct framework allows us to generate a reasoning response, an action, and a reflection to\n> steer the model’s response. This example is courtesy of the following\n> paper: [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629)\\*\n\n## How do we give agents a working memory?\n\nWhile we have seen that _prompt engineering is largely effective in resolving issues with short-term memory and\nreasoning_, we cannot solve long-term memory solely through clever English. Since we are not allowed to update the model\nto learn our data, we must build an external system for storing and retrieving knowledge.\n\nA clever solution might use an LLM to _generate summaries of previous conversations as context for the prompt_. However,\nthere are three significant issues with this. First, we are diluting the relevant information for the conversation;\nsecond, it introduces another cost area by paying for API usage for those summaries; and third, it's unscalable.\n\nThus, prompts appear to be ineffective for long-term memory. Seeing as _long-term memory is a problem of storage and\nefficient retrieval of information_, there is no absence of research in the study of search, so we must look towards\nvector databases.\n\n### Vector Databases Demystified\n\n**[Vector databases](https://aws.amazon.com/what-is/vector-databases/)** have been hyped up for a while now, and the\nhype\nis very deserved. They are an efficient way of storing and retrieving vectors by allowing us to use some fun new\n_algorithms to query billions - even trillions - of data records in milliseconds._\n\nLet's start with a little bit of vocabulary:\n\n- A **vector** in the context of an LLM is a representation of a piece of text that a model like GPT-4 encodes.\n- A **vector space** contains many of these vectors.\n- An **embedding** is the vectorized version of a text.\n\n### Vector libraries like\n\n[Facebook AI Similarity Search](https://www.bing.com/ck/a?!&&p=a0f4167bc6cd7db9JmltdHM9MTY4ODM0MjQwMCZpZ3VpZD0zOTYwYjczZS1hNzg2LTY5Y2MtMjM2YS1hNDdmYTYwMjY4MjImaW5zaWQ9NTIwMQ&ptn=3&hsh=3&fclid=3960b73e-a786-69cc-236a-a47fa6026822&psq=faiss+github&u=a1aHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rcmVzZWFyY2gvZmFpc3M&ntb=1) (\nFAISS) give us access to valuable _tools to control these vectors and locate them efficiently in the vector space._\n\nSince the text is in a numerical embedding dictated by the model type (i.e., text-embedding-ada-002), there is some\nlocation in space that the text exists in, and it's based on the numbers that compose its vector. That means _similar\ntexts will be represented as vectors with similar numbers, and thus, they will likely be grouped closely. On the other\nhand, less similar texts will be further away_. For example, texts about cooking will be closer to food than texts about\nphysics.\n\nThere are several different algorithms for querying the vector space, but the most relevant to this discussion is the\ncosine similarity search. **[Cosine similarity](https://www.geeksforgeeks.org/cosine-similarity/)** measures the cosine\nof the angle between two non-zero vectors. _It is a measure of orientation, meaning that it's used to determine how\nsimilar two documents (or whatever the vectors represent) are_. Cosine similarity can range from -1 to 1, with -1\nmeaning the vectors are diametrically opposed (completely opposite), 0 meaning the vectors are orthogonal (or\nunrelated), and 1 meaning the vectors are identical.\n\nFAISS is helpful in managing these vector spaces, but it is not a database. _Vector libraries\nlack [CRUD](https://www.freecodecamp.org/news/crud-operations-explained/) operations, which makes them alone unviable\nfor long-term memory_, and that's where cloud services such as Pinecone and Weaviate step in.\n\n**Pinecone** and **Weaviate** essentially do all the hard work of managing our vectors. They provide an API that allows\nyou\nto upload embeddings, perform various types of searches, and store those vectors for later. _They provide the typical\nCRUD functions we need to instill memory into LLMs in easily-accessible Python modules._\n\nBy using them, we can encode large amounts of information for future storage and retrieval. For instance, when the LLM\nneeds extra knowledge to complete a task, we can prompt it to query the vector space to find relevant information. Thus,\nwe can create long-term memory.\n\n![CybrCo_Art_A_human-like_robot_touching_a_flower_for_the_first_t_92e97d56-54fa-4bb0-8581-5a1e15fd94aa.webp](https://petal-diplodocus-04a.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fad2521b3-1c6b-4f16-b719-d2b766570c61%2FCybrCo_Art_A_human-like_robot_touching_a_flower_for_the_first_t_92e97d56-54fa-4bb0-8581-5a1e15fd94aa.webp?id=8d261d10-f4e4-4798-bc33-8f40da67bb42&table=block&spaceId=46c3481b-d8de-4c34-8647-2292d63a5f29&width=2000&userId=&cache=v2)\n\n> Alt : Robot With A Rose In Hand\n\n## Tools to interact with the environment\n\nWhile **prompt engineering** and **vector databases** resolve many of the limitations and challenges of LLMs, there is\nstill the problem of agent interaction. _How can we extend the capabilities of an LLM to interact with the environment\noutside of text?_\n\nAPIs are the answer. By utilizing APIs, we can give our agents the ability to perform a wide range of actions and\naccess external resources.\n\nHere are a few examples:\n\n- **Google Search API**: Allows agents to search the web and retrieve relevant information.\n- **Hugging Face**: Provides access to various NLP models and transformers for tasks such as summarization, translation,\n  sentiment analysis, and more.\n- **Dall-E**: Enables agents to generate images from textual descriptions.\n- **OpenAI's GPT API**: Allows agents to utilize the GPT-4 model for text completion and generation.\n\nUsing API tools in combination with prompt engineering techniques, we can create prompts that generate predictable\nfunction calls and utilize the output of API requests to enhance the agent's capabilities. This enables agents to\ninteract with the environment in a meaningful way beyond text-based interactions.\n\n### Engineering Robust Function Calls\n\nAgain, we can achieve tooling through prompt engineering by _representing the tool we want to provide for the model_ as a **function**. _We can then tell the model that this function exists in a prompt, so our program can call it programmatically based on the model's response_. First, however, we should examine the main challenges in implementing tool interactions: consistency, context, and format.\n\nFor example, responses tend to vary among chat completions that use the same prompt. Thus, getting the LLM to issue a function call consistently is challenging. A minor solution may include adjusting the **temperature** of the model (a parameter to control the randomness), but the best solution should leverage an LLM's reasoning abilities. Thus, _we can use the ReAct framework to help the llm understand when to issue function calls._\n\nIn doing this, we will still run into another major issue. How will the LLMs understand what tools are at their disposal? We could include the available tools in a prompt, but this could significantly increase the number of tokens we would need to send to the model. While this may be fine for an application that runs on a couple of tools, it will increase costs as we add more tools to the system. Thus, _we would use vector databases to help the LLM look up relevant tools it needs._\n\nFinally, we need to generate function calls in a predictable format. This format should include provisions for the name of the function and the parameters it takes, and it must include delimiters that allow us to parse and execute the response for those parameters programmatically. _For instance, you can prompt the model to only return responses in JSON and then use built-in Python libraries to parse the stringified JSON._\n\nRecently, it became even easier to use this type of method as well. In late June, OpenAI released **gpt-4-0613** and **gpt-3.5-turbo-16k-0613** (whew, these names are getting long). They natively support function calls by using a model fine-tuned for JSON to return easy-to-use function calls. You can read more about it [here](https://platform.openai.com/docs/guides/gpt/function-calling).\n\n## The future of LLM-powered agents is bright!\n\nLarge language models have been one of the most significant advances of the past decade. Capable of reasoning and talking like a human, they appear to be able to do anything. Despite this, several engineering challenges arise in building around an LLM, such as context limits, reasoning, and long-term retention.\n\nUsing the methods described above, **AgentGPT** unlocks the full potential of powerful models such as GPT-4. _We can give any model superpowers using novel prompting methods, efficient vector databases, and abundant API tools_. It's only the start, and we hope you'll join us on this journey.\n\n## Conclusion\n\nAgentGPT represents a powerful approach to building AI agents that reason, remember, and perform. By leveraging prompt\nengineering, vector databases, and API tools, we can overcome the limitations of standalone LLMs and create agents that\ndemonstrate agentic behavior.\n\nWith the ability to reason, plan, and reflect, AgentGPT agents can tackle complex tasks and interact with the\nenvironment in a meaningful way. By incorporating long-term memory through vector databases and utilizing APIs, we\nprovide agents with access to a vast pool of knowledge and resources.\n\nAgentGPT is a step towards unlocking the full potential of LLMs and creating intelligent agents that can assist and\ncollaborate with humans in various domains. The combination of language models, prompt engineering, external memory,\nand API interactions opens up exciting possibilities for AI agents in the future.\n\n## Extra Resources\n\nAre you interested in learning more about prompt engineering? We encourage you to check out other informational posts on our site, or you can check out the fantastic places below, or if you are interested in contributing, check out our [GitHub repo](https://github.com/reworkd/AgentGPT).\n"
  },
  {
    "path": "next/prettier.config.cjs",
    "content": "/** @type {import(\"prettier\").Config} */\nmodule.exports = {\n  plugins: [require.resolve(\"prettier-plugin-tailwindcss\")],\n  printWidth: 100\n};\n"
  },
  {
    "path": "next/prisma/.gitignore",
    "content": "schema.prisma*\n"
  },
  {
    "path": "next/prisma/useMysql.sh",
    "content": "#!/bin/bash\ncd \"$(dirname \"$0\")\" || exit 1\n\nrm schema.prisma\nmv schema.prisma.mysql schema.prisma\n\n"
  },
  {
    "path": "next/prisma/useSqlite.sh",
    "content": "#!/usr/bin/env bash\ncd \"$(dirname \"$0\")\" || exit 1\n\ncp schema.prisma schema.prisma.mysql\nsed -ie 's/mysql/sqlite/g' schema.prisma\nsed -ie 's/@db.Text//' schema.prisma\nsed -ie 's/@db.VarChar([0-9]\\{1,\\})//' schema.prisma\nsed -ie 's/Json/String/g' schema.prisma\n"
  },
  {
    "path": "next/public/locales/de/chat.json",
    "content": "{\n  \"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Wir haben außergewöhnlichen Verkehr, erwarten Sie Verzögerungen und Ausfälle, wenn Sie keinen eigenen API-Schlüssel verwenden 🚨\",\n  \"CREATE_AN_AGENT_DESCRIPTION\": \"Erstellen Sie einen Agenten, indem Sie einen Namen/Ziel hinzufügen und auf Bereitstellen klicken!\",\n  \"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Sie können Ihren eigenen OpenAI API-Schlüssel im Einstellungen-Tab für höhere Limits bereitstellen!\",\n  \"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Unterstützen Sie die Weiterentwicklung von AgentGPT. 💝️\",\n  \"CONSIDER_SPONSORING_ON_GITHUB\": \"Bitte erwägen Sie, das Projekt auf GitHub zu unterstützen.\",\n  \"SUPPORT_NOW\": \"Jetzt unterstützen 🚀\",\n  \"EMBARKING_ON_NEW_GOAL\": \"Beginne ein neues Ziel:\",\n  \"THINKING\": \"Denke nach...\",\n  \"TASK_ADDED\": \"Aufgabe hinzugefügt:\",\n  \"COMPLETING\": \"Fertigstellen:\",\n  \"NO_MORE_TASKS\": \"Keine weiteren Unteraufgaben für:\",\n  \"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Text wurde in die Zwischenablage kopiert\",\n  \"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Text konnte nicht in die Zwischenablage kopiert werden\",\n  \"RESTART_IF_IT_TAKES_X_SEC\": \"(Starten Sie neu, wenn dies länger als 30 Sekunden dauert)\",\n  \"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Erstelle einen Agenten, indem du einen Namen/ein Ziel hinzufügst und auf Deploy drückst!\"\n}\n"
  },
  {
    "path": "next/public/locales/de/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Erstelle einen Agenten, indem du einen Namen/ein Ziel hinzufügst und auf Deploy drückst! \\nProbieren Sie unsere Beispiele unten aus!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/de/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Aufgabe Hinzufügen\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentation von AgentGPT\",\n\t\"CLOSE\": \"Schließen\",\n\t\"CONTINUE\": \"Weitermachen\",\n\t\"COPIED_TO_CLIPBOARD\": \"In die Zwischenablage kopiert! 🚀\",\n\t\"COPY\": \"Kopieren\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Erstellen Sie einen Agenten, indem Sie einen Namen / ein Ziel hinzufügen und auf „Bereitstellen“ klicken!\",\n\t\"CURRENT_TASKS\": \"Aktuelle Aufgaben\",\n\t\"EXECUTING\": \"Ausführen\",\n\t\"EXPORT\": \"Exportieren\",\n\t\"IMAGE\": \"Bild\",\n\t\"LOOP\": \"Schleife\",\n\t\"PAUSED\": \"Angehalten\",\n\t\"RESET\": \"Zurücksetzen\",\n\t\"RUNNING\": \"Im Gange\",\n\t\"SAVE\": \"Speichern\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Um weitere Informationen über AgentGPT, seine Roadmap usw. zu erhalten, besuchen Sie den folgenden Link\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Erstellen Sie einen umfassenden Bericht über das Unternehmen Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Wenn Sie auf Probleme stoßen, wenden Sie sich bitte an unsere\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Planen Sie eine detaillierte Reise nach Hawaii.\",\n\t\"platformergpt\": \"PlattformerGPT 🎮\",\n\t\"researchgpt\": \"ForschungGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"Web-Suche\"\n}\n"
  },
  {
    "path": "next/public/locales/de/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Konto\",\n\t\"HELP_BUTTON\": \"Hilfe\",\n\t\"MY_AGENTS\": \"Meine Agenten\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Sie müssen zuerst Ihren ersten Agenten erstellen und speichern, bevor hier etwas angezeigt wird!\",\n\t\"SETTINGS_BUTTON\": \"Einstellungen\",\n\t\"SIGN_IN\": \"Anmelden\",\n\t\"SIGN_IN_NOTICE\": \"Melden Sie sich an, um Ihre Agenten zu speichern und Ihr Konto zu verwalten!\",\n\t\"SIGN_OUT\": \"Abmelden\",\n\t\"SUPPORT_BUTTON\": \"Unterstützung\",\n\t\"USER_IMAGE\": \"Benutzerbild\"\n}\n"
  },
  {
    "path": "next/public/locales/de/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"Fehler beim Zugriff auf den OpenAI API-Schlüssel. Bitte überprüfen Sie den API-Schlüssel oder versuchen Sie es später erneut.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"Fehler beim Hinzufügen zusätzlicher Aufgaben. Möglicherweise kann unser Modell die Antwort nicht handhaben und hat dies verursacht. Fortfahren...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Maximale Anzahl an Anfragen erreicht! Bitte langsamer machen...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Dieser Agent hat die maximale Anzahl ausführbarer Durchläufe erreicht. Um Geld zu sparen, wird dieser Agent jetzt gestoppt... Die maximale Anzahl von Agentenläufen kann in den Einstellungen konfiguriert werden.\",\n  \"DEMO_LOOPS_REACHED\": \"Entschuldigung, da dies eine Demoversion ist, können wir unsere Agenten nicht zu lange laufen lassen. Hinweis: Wenn Sie längere Laufzeiten wünschen, geben Sie bitte einen eigenen API-Schlüssel in den Einstellungen an. Stoppen...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agent manuell gestoppt.\",\n  \"ALL_TASKS_COMPLETETD\": \"Alle Aufgaben wurden abgeschlossen. Stoppen...\",\n  \"ERROR_API_KEY_QUOTA\": \"Fehler bei der Verwendung des OpenAI API-Schlüssels. Sie haben Ihre derzeitige Quote überschritten. Bitte überprüfen Sie Ihre Abrechnungsinformationen.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"FEHLER: Ihr OpenAI API-Schlüssel hat keinen Zugriff auf GPT-4. Sie müssen sich zuerst auf der OpenAI-Warteliste anmelden. (Dies unterscheidet sich vom ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"Fehler beim Abrufen der Ausgangsaufgaben. Versuchen Sie es erneut, formulieren Sie das Ziel des Agenten klarer oder passen Sie es so an, dass es unserem Modell entspricht. Stoppen...\",\n  \"INVALID_OPENAI_API_KEY\": \"FEHLER ungültiger OpenAI-API-Schlüssel\"\n}\n"
  },
  {
    "path": "next/public/locales/de/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentation von AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Folgen Sie uns auf folgenden Wegen:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interaktion mit Websites und Menschen 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"ermöglicht es Ihnen, eigenständige KI-Agenten über Ihren Browser zu konfigurieren und auszuführen. Benennen Sie Ihren individuellen KI-Agenten und definieren Sie sein Ziel. Der KI-Agent versucht, das definierte Ziel zu erreichen, indem er Aufgaben erstellt, sie ausführt und ihre Ergebnisse auswertet 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Langzeitgedächtnis 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Diese Plattform ist derzeit in der Beta-Version und wir arbeiten derzeit an folgenden Funktionen:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Um mehr über AgentGPT, seine Roadmap, FAQ usw. zu erfahren, besuchen Sie die\",\n\t\"WEB_BROWSING\": \"Web-Browsing 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Willkommen bei AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/de/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Stellen Sie autonome KI-Agenten in Ihrem Browser zusammen, konfigurieren Sie sie und installieren Sie sie.\",\n  \"AGENT_NAME\": \"Name\",\n  \"LABEL_AGENT_GOAL\": \"Ziel\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Machen Sie die Welt zu einem besseren Ort\",\n  \"BUTTON_DEPLOY_AGENT\": \"Agent ausführen\",\n  \"BUTTON_STOP_AGENT\": \"Agent stoppen\"\n}\n"
  },
  {
    "path": "next/public/locales/de/languages.json",
    "content": "{\n    \"ENGLISH\": \"Englisch\",\n    \"FRENCH\": \"Französisch\",\n    \"SPANISH\": \"Spanisch\",\n    \"GERMAN\": \"Deutsch\",\n    \"JAPANESE\": \"Japanisch\",\n    \"KOREAN\": \"Koreanisch\",\n    \"CHINESE\": \"Chinesisch\",\n    \"PORTUGEES\": \"Portugiesisch\",\n    \"ITALIAN\": \"Italienisch\",\n    \"DUTCH\": \"Niederländisch\",\n    \"POLSKI\": \"Polnisch\",\n    \"HUNGARIAN\": \"Ungarisch\",\n    \"ROMANIAN\": \"Rumänisch\",\n    \"SLOVAK\": \"Slowakisch\"\n}\n"
  },
  {
    "path": "next/public/locales/de/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Erweiterte Einstellungen\",\n\t\"API_KEY\": \"API-Schlüssel\",\n\t\"AUTOMATIC_MODE\": \"Automatikmodus\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Standard): Der Agent führt alle Aufgaben automatisch aus.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Steuerung der maximalen Anzahl von Tokens, die bei jedem API-Aufruf verwendet werden (höhere Werte führen zu detaillierteren Antworten, sind aber teurer).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Steuerung der maximalen Anzahl von Schleifen, die vom Agenten ausgeführt werden (höhere Werte führen zu mehr API-Aufrufen).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Holen Sie sich Ihren eigenen OpenAI-API-Schlüssel\",\n\t\"HERE\": \"hier\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Hier können Sie Ihren OpenAI API-Schlüssel hinzufügen. Dies bedeutet, dass Sie für die Verwendung Ihres eigenen OpenAI-Tokens bezahlen müssen, aber einen größeren Zugang zu ChatGPT erhalten! Außerdem können Sie jedes von OpenAI angebotene Modell auswählen.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Höhere Werte machen die Ausgabe zufälliger, während niedrigere Werte sie fokussierter und bestimmter machen.\",\n\t\"INFO_TO_USE_GPT4\": \"Um das GPT-4-Modell zu verwenden, muss auch der API-Schlüssel angegeben werden. Sie können es\",\n\t\"INVALID_OPENAI_API_KEY\": \"Ungültiger API-Schlüssel!\",\n\t\"LABEL_MODE\": \"Modus\",\n\t\"LABEL_MODEL\": \"Modell\",\n\t\"LANG\": \"Sprache\",\n\t\"LINK\": \"API-Schlüssel beantragen\",\n\t\"LOOP\": \"Schleife\",\n \t\"MUST_CONNECT_CREDIT_CARD\": \"Hinweis: Sie müssen eine Kreditkarte mit Ihrem Konto verbinden\",\n\t\"NOTE_API_KEY_USAGE\": \"Dieser Schlüssel wird nur in der aktuellen Browsersitzung verwendet.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"HINWEIS: Um den API-Schlüssel zu erhalten, müssen Sie ein OpenAI-Konto registrieren, das Sie unter dem folgenden Link tun können:\",\n\t\"PAUSE\": \"Pause\",\n\t\"PAUSE_MODE\": \"Pause-Modus\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Der Agent pausiert nach jeder Gruppe von Aufgaben.\",\n\t\"PENAI_API_KEY\": \"Ungültiger OpenAI-API-Schlüssel\",\n\t\"PLAY\": \"Abspielen\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Einstellungen ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(Das ChatGPT Plus-Abonnement funktioniert nicht)\",\n\t\"TEMPERATURE\": \"Temperatur\",\n\t\"TOKENS\": \"Token\"\n}\n"
  },
  {
    "path": "next/public/locales/en/chat.json",
    "content": "{\n  \"COMPLETING\": \"Completing:\",\n  \"CONSIDER_SPONSORING_ON_GITHUB\": \"Please consider sponsoring the project on GitHub.\",\n  \"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Text copied to clipboard\",\n  \"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Unable to copy text to clipboard\",\n  \"CREATE_AN_AGENT_DESCRIPTION\": \"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\",\n  \"EMBARKING_ON_NEW_GOAL\": \"Embarking on a new goal:\",\n  \"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 We are experiencing exceptional traffic, expect delays and failures if you do not use your own API key🚨\",\n  \"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Help support the advancement of AgentGPT. 💝️\",\n  \"NO_MORE_TASKS\": \"No more subtasks for:\",\n  \"RESTART_IF_IT_TAKES_X_SEC\": \"(Restart if this takes more than 30 seconds)\",\n  \"SUPPORT_NOW\": \"Support now 🚀\",\n  \"TASK_ADDED\": \"Added task:\",\n  \"THINKING\": \"Thinking...\",\n  \"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 You can provide your own OpenAI API key in the settings tab for increased limits!\",\n  \"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Create an agent by adding a name/target and pressing deploy!\"\n}\n"
  },
  {
    "path": "next/public/locales/en/chat.missing.json",
    "content": "{\n  \"👉 創建一個AI機器人，輸入名稱和目標，然後點擊\\\"啟動AI！\\\"按鈕\": \"👉 創建一個AI機器人，輸入名稱和目標，然後點擊\\\"啟動AI！\\\"按鈕\",\n  \"👉 Utwórz agenta, dodając nazwę i cel, a następnie kliknij przycisk \\\"Uruchom agenta!\\\"\": \"👉 Utwórz agenta, dodając nazwę i cel, a następnie kliknij przycisk \\\"Uruchom agenta!\\\"\",\n  \"👉 Creați un agent prin adăugarea numelui și obiectivului, apoi faceți clic pe butonul \\\"Pornire agent!\\\"\": \"👉 Creați un agent prin adăugarea numelui și obiectivului, apoi faceți clic pe butonul \\\"Pornire agent!\\\"\",\n  \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n  \"👉 Maak een agent aan door de naam en het doel toe te voegen en klik op de knop \\\"Agent starten!\\\"\": \"👉 Maak een agent aan door de naam en het doel toe te voegen en klik op de knop \\\"Agent starten!\\\"\",\n  \"👉 Kreirajte agenta dodavanjem imena/cilja i klikom na deploy!\": \"👉 Kreirajte agenta dodavanjem imena/cilja i klikom na deploy!\",\n  \"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\",\n  \"👉 Créez un agent en ajoutant un nom / objectif et en appuyant sur le déploiement !\": \"👉 Créez un agent en ajoutant un nom / objectif et en appuyant sur le déploiement !\",\n  \"👉 Erstellen Sie einen Agenten, indem Sie einen Namen/Ziel hinzufügen und auf Bereitstellen klicken!\": \"👉 Erstellen Sie einen Agenten, indem Sie einen Namen/Ziel hinzufügen und auf Bereitstellen klicken!\",\n  \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\",\n  \"👉 이름과 목표를 추가하여 에이전트를 생성한 다음, \\\"에이전트 시작!\\\" 버튼을 클릭하세요\": {\n    \"\": \"👉 이름과 목표를 추가하여 에이전트를 생성한 다음, \\\"에이전트 시작!\\\" 버튼을 클릭하세요.\"\n  },\n  \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n  \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n  \"👉 Bir ad / hedef ekleyerek ve konuşlandır'a basarak bir aracı oluşturun! Aşağıdaki örneklerimizi deneyin!\": \"👉 Bir ad / hedef ekleyerek ve konuşlandır'a basarak bir aracı oluşturun! Aşağıdaki örneklerimizi deneyin!\",\n  \"👉 Sukurkite agentą pridėdami pavadinimą ir tikslą, tada paspauskite mygtuką \\\"Paleisti agentą!\\\"\": \"👉 Sukurkite agentą pridėdami pavadinimą ir tikslą, tada paspauskite mygtuką \\\"Paleisti agentą!\\\"\",\n  \"👉 Hozzon létre egy ügynököt a név és a cél hozzáadásával, majd kattintson az \\\"Ügynök indítása!\\\" gombra\": \"👉 Hozzon létre egy ügynököt a név és a cél hozzáadásával, majd kattintson az \\\"Ügynök indítása!\\\" gombra\",\n  \"👉 Crea un agente aggiungendo nome e obiettivo, quindi premi il pulsante \\\"Avvia agente!\\\"\": \"👉 Crea un agente aggiungendo nome e obiettivo, quindi premi il pulsante \\\"Avvia agente!\\\"\",\n  \"👉 Crie um agente adicionando nome e objetivo, e clique no botão \\\"Iniciar agente!\\\"\": \"👉 Crie um agente adicionando nome e objetivo, e clique no botão \\\"Iniciar agente!\\\"\",\n  \"👉 ¡Cree un agente agregando un nombre/objetivo y presionando desplegar!\": \"👉 ¡Cree un agente agregando un nombre/objetivo y presionando desplegar!\"\n}"
  },
  {
    "path": "next/public/locales/en/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Adding Task\",\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT's Documentation\",\n\t\"CLOSE\": \"Close\",\n\t\"CONTINUE\": \"Continue\",\n\t\"COPIED_TO_CLIPBOARD\": \"Copied to clipboard! 🚀\",\n\t\"COPY\": \"Copy\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Create an agent by adding a name / goal, and hitting deploy!\",\n\t\"CURRENT_TASKS\": \"Current Tasks\",\n\t\"EXECUTING\": \"Executing\",\n\t\"EXPORT\": \"Export\",\n\t\"IMAGE\": \"Image\",\n\t\"LOOP\": \"Loop\",\n\t\"PAUSED\": \"Paused\",\n\t\"RESET\": \"Reset\",\n\t\"RUNNING\": \"Running\",\n\t\"SAVE\": \"Save\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"To get more information about AgentGPT, its Roadmap, etc, visit the following link\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Create a comprehensive report of the Nike company\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"If you are facing issues, please head over to our\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Plan a detailed trip to Hawaii.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"ResearchGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"Web search\"\n}\n"
  },
  {
    "path": "next/public/locales/en/common.missing.json",
    "content": "{\n  \"Current tasks\": \"Current tasks\"\n}"
  },
  {
    "path": "next/public/locales/en/drawer.json",
    "content": "{\n  \"HELP_BUTTON\": \"Help\",\n  \"SETTINGS_BUTTON\": \"Settings\",\n  \"SUPPORT_BUTTON\": \"Support\",\n  \"MY_AGENTS\": \"My Agents\",\n  \"SIGN_IN_NOTICE\": \" to be able to save agents and manage your account!\",\n  \"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Create and save your first agent to get started!\",\n  \"SIGN_IN\": \"Sign In\",\n  \"SIGN_OUT\": \"Sign Out\",\n  \"ACCOUNT\": \"Account\",\n  \"USER_IMAGE\": \"User Image\"\n}\n"
  },
  {
    "path": "next/public/locales/en/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"ERROR accessing the backend. Please email support@reworkd.ai or try again later\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"ERROR adding additional task(s). It might have been against our model's policies to run them. Continuing.\",\n  \"RATE_LIMIT_EXCEEDED\": \"Rate limit exceeded! Please slow down...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"This agent has maxed out on loops. To save your wallet, this agent is shutting down. You can configure the number of loops in the advanced settings.\",\n  \"DEMO_LOOPS_REACHED\": \"The agent has run out of loops. Update the number of loops in the settings menu if more loops are required. Shutting down.\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"The agent has been manually shutdown.\",\n  \"ALL_TASKS_COMPLETETD\": \"All tasks completed. Shutting down.\",\n  \"ERROR_API_KEY_QUOTA\": \"ERROR using your OpenAI API key. You've exceeded your current quota, please check your plan and billing details.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"ERROR your API key does not have GPT-4 access. You must first join OpenAI's wait-list. (This is different from ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"ERROR retrieving initial tasks array. Retry, make your goal more clear, or revise your goal such that it is within our model's policies to run. Shutting Down.\",\n  \"INVALID_OPENAI_API_KEY\": \"ERROR invalid OpenAI API-key\"\n}\n"
  },
  {
    "path": "next/public/locales/en/help.json",
    "content": "{\n  \"WELCOME_TO_AGENT_GPT\": \"Welcome to AgentGPT\",\n  \"INTRODUCING_AGENTGPT\": \"allows you to configure and deploy Autonomous AI agents. Name your custom AI and have it embark on any goal imaginable. It will attempt to reach the goal by thinking of tasks to do, executing them, and learning from the results 🚀\",\n  \"PLATFORM_BETA_DESCRIPTION\": \"This platform is currently in beta, we are currently working on:\",\n  \"LONG_TERM_MEMORY\": \"Long term memory 🧠\",\n  \"WEB_BROWSING\": \"Web browsing 🌐\",\n  \"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interaction with websites and people 👨‍👩‍👦\",\n  \"FOLLOW_THE_JOURNEY\": \"Follow the journey below:\",\n  \"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"To learn more about AgentGPT, its roadmap, FAQ, etc, visit the \",\n  \"AGENTGPT_DOCUMENTATION\": \"AgentGPT's Documentation\"\n}"
  },
  {
    "path": "next/public/locales/en/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Assemble, configure, and deploy autonomous AI Agents in your browser.\",\n  \"AGENT_NAME\": \"Name\",\n  \"LABEL_AGENT_GOAL\": \"Goal\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"What is the latest AI news?\",\n  \"BUTTON_DEPLOY_AGENT\": \"Deploy Agent\",\n  \"BUTTON_STOP_AGENT\": \"Stop Agent\"\n}\n"
  },
  {
    "path": "next/public/locales/en/languages.json",
    "content": "{\n    \"ENGLISH\": \"English\",\n    \"FRENCH\": \"French\",\n    \"SPANISH\": \"Spanish\",\n    \"GERMAN\": \"Deutsch\",\n    \"JAPANESE\": \"Japanese\",\n    \"KOREAN\": \"Korean\",\n    \"CHINESE\": \"Chinese\",\n    \"PORTUGEES\": \"Portugees\",\n    \"ITALIAN\": \"Italian\",\n    \"DUTCH\": \"Dutch\",\n    \"POLSKI\": \"Polski\",\n    \"HUNGARIAN\": \"Hungarian\",\n    \"ROMANIAN\": \"Romanian\",\n    \"SLOVAK\": \"Slovak\"\n}"
  },
  {
    "path": "next/public/locales/en/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Advanced settings\",\n\t\"API_KEY\": \"Key\",\n\t\"AUTOMATIC_MODE\": \"Automatic mode\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Default): Agent automatically executes every task.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Controls the maximum number of tokens used in each API call (higher value will make responses more detailed but cost more).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Controls the maximum number of loops that the agent will run (higher value will make more API calls).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Get your own OpenAI API key\",\n\t\"HERE\": \"here\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Here you can add your OpenAI API key. This will require you to pay for your own OpenAI usage but give you greater access to AgentGPT! You can additionally select any model OpenAI offers.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Higher values will make the output more random, while lower values make the output more focused and deterministic.\",\n\t\"INFO_TO_USE_GPT4\": \"To use the GPT-4 model, you need to also provide the API key for GPT-4. You can request for it\",\n\t\"INVALID_OPENAI_API_KEY\": \"Invalid API key!\",\n\t\"LABEL_MODE\": \"Mode\",\n\t\"LABEL_MODEL\": \"Model\",\n\t\"LANG\": \"Language\",\n\t\"LINK\": \"link\",\n\t\"LOOP\": \"Loop\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Note: You must connect a credit card to your account\",\n\t\"NOTE_API_KEY_USAGE\": \"This key is only used in the current browser session\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"NOTE: To get a key, sign up for an OpenAI account and visit the following\",\n\t\"PAUSE\": \"Pause\",\n\t\"PAUSE_MODE\": \"Pause mode\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Agent pauses after every set of task(s)\",\n\t\"PENAI_API_KEY\": \"Invalid OpenAI API-key\",\n\t\"PLAY\": \"Play\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Settings ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(ChatGPT Plus subscription will not work)\",\n\t\"TEMPERATURE\": \"Temp.\",\n\t\"TOKENS\": \"Tokens\"\n}\n"
  },
  {
    "path": "next/public/locales/es/chat.json",
    "content": "{\n  \"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 AgentGPT experimenta un tráfico excepcional. Si no estas usando tu propia clave del API, podrias notar retrasos y errores 🚨\",\n  \"CREATE_AN_AGENT_DESCRIPTION\": \"¡Crea un Agente agregando un nombre, objetivo y presionando 'Ejecutar Agente'! Puedes experimentar con estos ejemplos:\",\n  \"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 ¡Puedes proporcionar tu propia clave de API de OpenAI en la pestaña de configuración para evitar limitaciones!\",\n  \"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Apoya el progreso de AgentGPT. 💝️\",\n  \"CONSIDER_SPONSORING_ON_GITHUB\": \"Considera patrocinar el proyecto en GitHub.\",\n  \"SUPPORT_NOW\": \"Apoyar ahora 🚀\",\n  \"EMBARKING_ON_NEW_GOAL\": \"Embarcándose en un nuevo objetivo:\",\n  \"THINKING\": \"Pensando...\",\n  \"TASK_ADDED\": \"Tarea agregada:\",\n  \"COMPLETING\": \"Completando:\",\n  \"NO_MORE_TASKS\": \"No hay más sub-tareas para:\",\n  \"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Texto copiado al portapapeles\",\n  \"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"No se pudo copiar el texto al portapapeles\",\n  \"RESTART_IF_IT_TAKES_X_SEC\": \"(Reiniciar si esto tarda más de 30 segundos)\",\n  \"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 ¡Crea un agente agregando un nombre, objetivo y presionando 'Ejecutar Agente'!\"\n}\n"
  },
  {
    "path": "next/public/locales/es/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 ¡Crea un Agente agregando un nombre, objetivo y presionando 'Ejecutar Agente'! Puedes experimentar con estos ejemplos:\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/es/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Añadiendo tarea\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentación de AgentGPT\",\n\t\"CLOSE\": \"Cerrar\",\n\t\"CONTINUE\": \"Continuar\",\n\t\"COPIED_TO_CLIPBOARD\": \"¡Copiado al portapapeles! 🚀\",\n\t\"COPY\": \"Copiar\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"¡Crea un agente agregando un nombre, objetivo y presionando 'Ejecutar Agente'!\",\n\t\"CURRENT_TASKS\": \"Tareas Actuales\",\n\t\"EXECUTING\": \"Ejecutando\",\n\t\"EXPORT\": \"Exportar\",\n\t\"IMAGE\": \"Imagen\",\n\t\"LOOP\": \"Bucle\",\n\t\"PAUSED\": \"En pausa\",\n\t\"RESET\": \"Reiniciar\",\n\t\"RUNNING\": \"En curso\",\n\t\"SAVE\": \"Guardar\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Para conocer más sobre AgentGPT visita el siguiente enlace\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Crear un informe completo de la empresa Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Si tienes inconvenientes, dirígete a nuestro\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Planifica un viaje detallado a Hawái.\",\n\t\"platformergpt\": \"VideojuegoGPT 🎮\",\n\t\"researchgpt\": \"InvestigaGPT 📜\",\n\t\"travelgpt\": \"ViajaGPT 🌴\",\n\t\"web-search\": \"búsqueda Web\"\n}\n"
  },
  {
    "path": "next/public/locales/es/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Cuenta\",\n\t\"HELP_BUTTON\": \"Ayuda\",\n\t\"MY_AGENTS\": \"Mis agentes\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"¡Debes crear y guardar tu primer agente para comenzar!\",\n\t\"SETTINGS_BUTTON\": \"Configuraciones\",\n\t\"SIGN_IN\": \"Iniciar sesión\",\n\t\"SIGN_IN_NOTICE\": \"¡Inicia sesión para guardar sus agentes y administrar tu cuenta!\",\n\t\"SIGN_OUT\": \"Cerrar sesión\",\n\t\"SUPPORT_BUTTON\": \"Apoyar\",\n\t\"USER_IMAGE\": \"Imagen de usuario\"\n}\n"
  },
  {
    "path": "next/public/locales/es/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"Error al acceder al API de OpenAI. Por favor, verifica tu clave de API o intenta más tarde.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"Error al agregar tarea(s) adicional(es). Es posible que las politicas de AgentGPT hayan evitar que se ejecuten. Continuando...\",\n  \"RATE_LIMIT_EXCEEDED\": \"¡Has alcanzado el número máximo de consultas! Por favor, disminuye la velocidad...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Este agente ha alcanzado el número máximo de rondas ejecutables. Para cuidar tu billetera, este agente se detendrá ahora... El número máximo de rondas de ejecución del agente se puede configurar en la configuración.\",\n  \"DEMO_LOOPS_REACHED\": \"Esta es una aplicación de demostración y no podemos ejecutar nuestros agentes durante mucho tiempo. Si desea ejecuciones más extendidas, proporciona tu clave de API de OpenAI en Configuración. Deteniendo...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agente apagado manualmente.\",\n  \"ALL_TASKS_COMPLETETD\": \"Todas las tareas han sido completadas. Deteniendo...\",\n  \"ERROR_API_KEY_QUOTA\": \"Error al usar la clave de API de OpenAI. Has superado su cuota actual, por favor, revisa tu información de facturación.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"ERROR: Tu clave de API de OpenAI no tiene acceso a GPT-4. Debes registrarse en la lista de espera de OpenAI para tener acceso. (AgentGPT utiliza el API de OpenAI, que no es lo mismo que ChatGPT ni ChatGPT Plus de chat.openai.com)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"Error al recuperar las tareas iniciales. Inténtalo de nuevo formulando el objetivo del agente de manera más clara o modificandolo de manera que se adapte a las políticas de nuestro modelo. Deteniendo...\",\n  \"INVALID_OPENAI_API_KEY\": \"ERROR Clave de API de OpenAI inválida\"\n}\n"
  },
  {
    "path": "next/public/locales/es/help.json",
    "content": "{\n\t\"WELCOME_TO_AGENT_GPT\": \"Bienvenido a AgentGPT\",\n\t\"INTRODUCING_AGENTGPT\": \"te permite configurar y ejecutar agentes de inteligencia artificial autónomos a través de tu navegador. Nombra tu agente de IA personalizado y define su objetivo. El agente de IA intentará alcanzar el objetivo definido mediante la creación de tareas, su ejecución y la evaluación de sus resultados 🚀\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Esta plataforma está actualmente en versión beta y estamos trabajando en las siguientes características:\",\n\t\"LONG_TERM_MEMORY\": \"Memoria a largo plazo 🧠\",\n\t\"WEB_BROWSING\": \"Navegación web 🌐\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interacción con sitios web y personas 👨‍👩‍👦\",\n\t\"FOLLOW_THE_JOURNEY\": \"Sígue nuestra aventura en nuestras redes:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Para obtener más información sobre AgentGPT, su hoja de ruta, preguntas frecuentes, etc., visite la\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentación de AgentGPT\"\n}"
  },
  {
    "path": "next/public/locales/es/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Ensambla, configura y ejecuta agentes de IA autónomos en tu navegador.\",\n  \"AGENT_NAME\": \"Nombre\",\n  \"LABEL_AGENT_GOAL\": \"Objetivo\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Hacer del mundo un lugar mejor\",\n  \"BUTTON_DEPLOY_AGENT\": \"Ejecutar Agente\",\n  \"BUTTON_STOP_AGENT\": \"Detener Agente\"\n}\n"
  },
  {
    "path": "next/public/locales/es/languages.json",
    "content": "{\n    \"ENGLISH\": \"Inglés\",\n    \"FRENCH\": \"Francés\",\n    \"SPANISH\": \"Español\",\n    \"GERMAN\": \"Alemán\",\n    \"JAPANESE\": \"Japonés\",\n    \"KOREAN\": \"Coreano\",\n    \"CHINESE\": \"Chino\",\n    \"PORTUGEES\": \"Portugués\",\n    \"ITALIAN\": \"Italiano\",\n    \"DUTCH\": \"Holandés\",\n    \"POLSKI\": \"Polaco\",\n    \"HUNGARIAN\": \"Húngaro\",\n    \"ROMANIAN\": \"Rumano\",\n    \"SLOVAK\": \"Eslovaco\"\n}\n"
  },
  {
    "path": "next/public/locales/es/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Configuración avanzada\",\n\t\"API_KEY\": \"Clave del API de OpenAI\",\n\t\"AUTOMATIC_MODE\": \"Modo automático\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Por defecto): El agente ejecuta automáticamente cada tarea.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Controla el número máximo de tokens utilizados en cada llamada a la API (un valor más alto resultará en respuestas más detalladas, pero también será más costoso).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Controla el número máximo de bucles que el agente puede ejecutar (un valor más alto resultará en más llamadas a la API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Obtenga su propia clave de API de OpenAI\",\n\t\"HERE\": \"aquí\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Aquí puedes agregar tu clave de API de OpenAI. Esto significa que tendrás que pagar por tu uso del API, ¡pero obtendrás un mayor acceso a AgentGPT! También podras elegir cualquier modelo de lenguaje ofrecido por OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Valores más altos hacen que la salida sea más creativa y aleatoria, mientras que valores más bajos la hacen más enfocada y determinista.\",\n\t\"INFO_TO_USE_GPT4\": \"Para utilizar el modelo GPT-4, también es necesario proporcionar la clave de API de OpenAI. Puedes obtenerla\",\n\t\"INVALID_OPENAI_API_KEY\": \"¡Clave de API inválida!\",\n\t\"LABEL_MODE\": \"Modo\",\n\t\"LABEL_MODEL\": \"Modelo\",\n\t\"LANG\": \"Idioma\",\n\t\"LINK\": \"Solicita una clave de API\",\n\t\"LOOP\": \"Bucle\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Nota: Debes agregar una tarjeta de crédito en tu cuenta\",\n\t\"NOTE_API_KEY_USAGE\": \"Esta clave solo se utiliza en la sesión actual del navegador.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"NOTA: Para obtener una clave de API, necesitas registrarte en una cuenta de OpenAI, lo cual puedes hacer en el siguiente enlace:\",\n\t\"PAUSE\": \"Pausa\",\n\t\"PAUSE_MODE\": \"Modo pausa\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"El agente se pausa después de cada conjunto de tareas.\",\n\t\"PENAI_API_KEY\": \"Clave API de OpenAI no válida\",\n\t\"PLAY\": \"Reproducir\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Configuración ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(La suscripción a ChatGPT Plus no funcionará)\",\n\t\"TEMPERATURE\": \"Temperatura\",\n\t\"TOKENS\": \"Tokens\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/chat.json",
    "content": "{\n  \"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Nous rencontrons un trafic exceptionnel, prévoyez des retards et des échecs si vous n'utilisez pas votre propre clé API 🚨\",\n  \"CREATE_AN_AGENT_DESCRIPTION\": \"Créez un agent en ajoutant un nom / objectif et en appuyant sur le déploiement !\",\n  \"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Vous pouvez fournir votre propre clé OpenAI API dans l'onglet des paramètres pour des limites accrues !\",\n  \"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Aidez à soutenir l'avancement d'AgentGPT. 💝️\",\n  \"CONSIDER_SPONSORING_ON_GITHUB\": \"Veuillez envisager de parrainer le projet sur GitHub.\",\n  \"SUPPORT_NOW\": \"Soutenir maintenant 🚀\",\n  \"EMBARKING_ON_NEW_GOAL\": \"Se lancer dans un nouvel objectif :\",\n  \"THINKING\": \"Réfléchir...\",\n  \"TASK_ADDED\": \"Tâche ajoutée :\",\n  \"COMPLETING\": \"En cours d'achèvement :\",\n  \"NO_MORE_TASKS\": \"Plus de sous-tâches pour :\",\n  \"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Texte copié dans le presse-papiers\",\n  \"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Impossible de copier le texte dans le presse-papiers\",\n  \"RESTART_IF_IT_TAKES_X_SEC\": \"(Redémarrez si cela prend plus de 30 secondes)\",\n  \"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Créez un agent en ajoutant un nom/objectif et en appuyant sur déployer !\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Créez un agent en ajoutant un nom/objectif et en appuyant sur déployer ! \\nEssayez nos exemples ci-dessous !\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"\\\" non !\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Ajout de tâche\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentation d'AgentGPT\",\n\t\"CLOSE\": \"Fermer\",\n\t\"CONTINUE\": \"Continuer\",\n\t\"COPIED_TO_CLIPBOARD\": \"Copié dans le presse-papier! 🚀\",\n\t\"COPY\": \"Copier\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Créez un agent en ajoutant un nom/objectif et en appuyant sur déployer !\",\n\t\"CURRENT_TASKS\": \"Tâches actuelles\",\n\t\"EXECUTING\": \"Exécution\",\n\t\"EXPORT\": \"Exporter\",\n\t\"IMAGE\": \"Image\",\n\t\"LOOP\": \"Boucle\",\n\t\"PAUSED\": \"En pause\",\n\t\"RESET\": \"Réinitialiser\",\n\t\"RUNNING\": \"En cours\",\n\t\"SAVE\": \"Enregistrer\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Pour obtenir plus d'informations sur AgentGPT, sa feuille de route, etc., visitez le lien suivant\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Créer un rapport complet sur la société Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Si vous rencontrez des problèmes, rendez-vous sur notre\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Planifiez un voyage détaillé à Hawaï.\",\n\t\"platformergpt\": \"PlateformeGPT 🎮\",\n\t\"researchgpt\": \"RechercheGPT 📜\",\n\t\"travelgpt\": \"VoyageGPT 🌴\",\n\t\"web-search\": \"recherche Internet\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Compte\",\n\t\"HELP_BUTTON\": \"Aide\",\n\t\"MY_AGENTS\": \"Mes agents\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Vous devez d'abord créer et enregistrer votre premier agent avant que quelque chose ne s'affiche ici!\",\n\t\"SETTINGS_BUTTON\": \"Paramètres\",\n\t\"SIGN_IN\": \"Se connecter\",\n\t\"SIGN_IN_NOTICE\": \"Connectez-vous pour enregistrer vos agents et gérer votre compte!\",\n\t\"SIGN_OUT\": \"Se déconnecter\",\n\t\"SUPPORT_BUTTON\": \"Soutien\",\n\t\"USER_IMAGE\": \"Image d'utilisateur\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"ERREUR lors de l'accès à la clé d'API OpenAI. Veuillez vérifier la clé d'API ou réessayer ultérieurement.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"ERREUR lors de l'ajout de tâches supplémentaires. Il est possible que notre modèle ne puisse pas gérer la réponse et ait généré cette erreur. Continuer...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Vous avez atteint le nombre maximal de requêtes ! Veuillez ralentir...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Cet agent a atteint le nombre maximal de boucles exécutables. Pour sauver votre porte-monnaie, cet agent s'arrête maintenant... Le nombre maximal de boucles d'exécution de l'agent peut être configuré dans les paramètres.\",\n  \"DEMO_LOOPS_REACHED\": \"Désolé, puisqu'il s'agit d'une application de démonstration, nous ne pouvons pas faire fonctionner les agents pendant une période prolongée. Note : si vous souhaitez des exécutions plus longues, veuillez fournir une clé API personnalisée dans les Paramètres. Arrêt...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"L'agent a été arrêté manuellement.\",\n  \"ALL_TASKS_COMPLETETD\": \"Toutes les tâches ont été terminées. Arrêt...\",\n  \"ERROR_API_KEY_QUOTA\": \"ERREUR lors de l'utilisation de la clé API OpenAI. Vous avez dépassé votre quota actuel, veuillez vérifier vos informations de facturation.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"ERREUR : Votre clé API OpenAI ne dispose pas d'un accès à GPT-4. Vous devez d'abord vous inscrire sur la liste d'attente OpenAI. (Ceci est différent de ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"ERREUR lors de la récupération des tâches initiales. Réessayez, reformulez l'objectif de l'agent de manière plus claire ou modifiez-le de manière à ce qu'il convienne à notre modèle. Arrêt...\",\n  \"INVALID_OPENAI_API_KEY\": \"ERREUR clé API OpenAI invalide\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentation d'AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Suivez notre parcours ci-dessous :\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interaction avec les sites Web et les personnes 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"permet de configurer et d'exécuter des agents d'IA autonomes dans votre navigateur. Nommez votre agent d'IA personnalisé et définissez son objectif. L'agent d'IA tentera d'atteindre l'objectif défini en créant des tâches, en les exécutant, puis en évaluant les résultats 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Mémoire à long terme 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Cette plateforme est actuellement en version bêta, nous travaillons actuellement sur les fonctionnalités suivantes:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Pour en savoir plus sur AgentGPT, sa feuille de route, sa FAQ, etc., visitez le\",\n\t\"WEB_BROWSING\": \"Navigation Web 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Bienvenue sur AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/indexPage.json",
    "content": "{\n  \"BETA\": \"Béta\",\n  \"HEADING_DESCRIPTION\": \"Assembler, configurer et déployer des agents d'IA autonomes dans votre navigateur.\",\n  \"AGENT_NAME\": \"Nom\",\n  \"LABEL_AGENT_GOAL\": \"Objectif\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Rendre le monde meilleur\",\n  \"BUTTON_DEPLOY_AGENT\": \"Exécuter l'agent\",\n  \"BUTTON_STOP_AGENT\": \"Arrêter l'agent\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/languages.json",
    "content": "{\n    \"ENGLISH\": \"Anglais\",\n    \"FRENCH\": \"Français\",\n    \"SPANISH\": \"Espagnol\",\n    \"GERMAN\": \"Allemand\",\n    \"JAPANESE\": \"Japonais\",\n    \"KOREAN\": \"Coréen\",\n    \"CHINESE\": \"Chinois\",\n    \"PORTUGEES\": \"Portugais\",\n    \"ITALIAN\": \"Italien\",\n    \"DUTCH\": \"Néerlandais\",\n    \"POLSKI\": \"Polonais\",\n    \"HUNGARIAN\": \"Hongrois\",\n    \"ROMANIAN\": \"Roumain\",\n    \"SLOVAK\": \"Slovaque\"\n}\n"
  },
  {
    "path": "next/public/locales/fr/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Paramètres avancés\",\n\t\"API_KEY\": \"Clé API\",\n\t\"AUTOMATIC_MODE\": \"Mode automatique\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Par défaut) : L'agent exécute automatiquement chaque tâche.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Contrôle le nombre maximal de jetons utilisés dans chaque appel API (une valeur plus élevée produit des réponses plus détaillées mais plus coûteuses).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Contrôle le nombre maximal de boucles exécutées par l'agent (une valeur plus élevée entraîne plus d'appels API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Obtenez votre propre clé API OpenAI\",\n\t\"HERE\": \"ici\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Ici, vous pouvez ajouter votre clé API OpenAI. Cela signifie que vous devrez payer pour utiliser votre propre jeton OpenAI, mais vous aurez un accès accru à ChatGPT ! Vous pouvez également sélectionner n'importe quel modèle proposé par OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Des valeurs plus élevées rendent la sortie plus aléatoire, tandis que des valeurs plus basses la rendent plus ciblée et précise.\",\n\t\"INFO_TO_USE_GPT4\": \"Pour utiliser le modèle GPT-4, vous devez également fournir une clé API. Vous pouvez l'obtenir\",\n\t\"INVALID_OPENAI_API_KEY\": \"Clé API invalide !\",\n\t\"LABEL_MODE\": \"Mode\",\n\t\"LABEL_MODEL\": \"Modèle\",\n\t\"LANG\": \"Langue\",\n\t\"LINK\": \"Demande de clé API\",\n\t\"LOOP\": \"Boucle\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Remarque : Vous devez connecter une carte de crédit à votre compte\",\n\t\"NOTE_API_KEY_USAGE\": \"Cette clé est utilisée uniquement dans la session de travail actuelle du navigateur.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"REMARQUE : Pour obtenir une clé API, vous devez vous inscrire à un compte OpenAI en suivant le lien ci-dessous :\",\n\t\"PAUSE\": \"Pause\",\n\t\"PAUSE_MODE\": \"Mode pause\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"L'agent fait une pause après chaque groupe de tâches.\",\n\t\"PENAI_API_KEY\": \"Clé API OpenAI invalide\",\n\t\"PLAY\": \"Lire\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Paramètres ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(L'abonnement ChatGPT Plus ne fonctionnera pas)\",\n\t\"TEMPERATURE\": \"Température\",\n\t\"TOKENS\": \"Jetons\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/chat.json",
    "content": "{\n  \"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Doživljavamo iznimno velik promet, očekujte kašnjenja i probleme ako ne koristite svoj vlastiti API ključ 🚨\",\n  \"CREATE_AN_AGENT_DESCRIPTION\": \"Kreirajte agenta dodavanjem imena/cilja i klikom na deploy!\",\n  \"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Možete koristiti svoj vlastiti OpenAI API ključ u kartici postavki za povećanje limita!\",\n  \"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Pomozite u napretku AgentGPT-a. 💝️\",\n  \"CONSIDER_SPONSORING_ON_GITHUB\": \"Molimo razmotrite sponzoriranje projekta na GitHubu.\",\n  \"SUPPORT_NOW\": \"Podržite odmah 🚀\",\n  \"EMBARKING_ON_NEW_GOAL\": \"Kreće se u ostvarivanje novog cilja:\",\n  \"THINKING\": \"Razmišljam...\",\n  \"TASK_ADDED\": \"Dodana zadaća:\",\n  \"COMPLETING\": \"Dovršavanje:\",\n  \"NO_MORE_TASKS\": \"Nema više pod-zadataka za:\",\n  \"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Tekst kopiran u međuspremnik\",\n  \"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Nije moguće kopirati tekst u međuspremnik\",\n  \"RESTART_IF_IT_TAKES_X_SEC\": \"(Ponovo pokrenite ako ovo traje više od 30 sekundi)\",\n  \"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Izradite agenta dodavanjem imena/cilja i pritiskom na Deploy!\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Izradite agenta dodavanjem imena/cilja i pritiskom na Deploy! \\nIsprobajte naše primjere u nastavku!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Kreirajte agenta pridaním mena a cieľa i kliknite na tipku \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Izradite agenta, dodajte ime i ćeliju, a zatim pritisnite gumb \\\"Zapusti agenta!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Stvorite agenta, dodajte ime i poruku, a zatim kliknite gumb \\\"Zakaži agenta!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Dodavanje zadatka\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentacija AgentGPT-a\",\n\t\"CLOSE\": \"Zatvoriti\",\n\t\"CONTINUE\": \"Nastaviti\",\n\t\"COPIED_TO_CLIPBOARD\": \"Kopirano u međuspremnik! 🚀\",\n\t\"COPY\": \"Kopirati\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Napravite agenta tako da dodate ime/cilj i pritisnete Deploy!\",\n\t\"CURRENT_TASKS\": \"Trenutni zadaci\",\n\t\"EXECUTING\": \"Izvršavanje\",\n\t\"EXPORT\": \"Izvoz\",\n\t\"IMAGE\": \"Slika\",\n\t\"LOOP\": \"Petlja\",\n\t\"PAUSED\": \"Pauzirano\",\n\t\"RESET\": \"Resetiraj\",\n\t\"RUNNING\": \"Trčanje\",\n\t\"SAVE\": \"Uštedjeti\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Da biste dobili više informacija o AgentGPT-u, njegovom Planu, itd., posjetite sljedeću poveznicu\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Napravite iscrpno izvješće tvrtke Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Ako imate problema, obratite se našem\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Isplanirajte detaljno putovanje na Havaje.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"ResearchGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"Internet pretraga\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Račun\",\n\t\"HELP_BUTTON\": \"Pomoć\",\n\t\"MY_AGENTS\": \"Moji agenti\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Prvo morate stvoriti i spremiti svoj prvi agent prije nego što se ovdje pojavi išta!\",\n\t\"SETTINGS_BUTTON\": \"Postavke\",\n\t\"SIGN_IN\": \"Prijava\",\n\t\"SIGN_IN_NOTICE\": \"Prijavite se da biste mogli spremiti svoje agente i upravljati svojim računom!\",\n\t\"SIGN_OUT\": \"Odjava\",\n\t\"SUPPORT_BUTTON\": \"podrška\",\n\t\"USER_IMAGE\": \"Slika korisnika\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"Pogreška prilikom pristupa OpenAI API ključu. Provjerite ključ ili pokušajte kasnije.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"Pogreška prilikom dodavanja dodatnih zadataka. Moguće je da naš model ne može obraditi odgovor i to je uzrokovalo ovu pogrešku. Nastavljam...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Dosegli ste maksimalni broj upita! Molimo usporite...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Ovaj agent je dosegnuo maksimalni broj mogućih izvršavanja. Kako biste sačuvali novac, ovaj će agent sada prestati raditi... Maksimalni broj izvršavanja agenta moguće je konfigurirati u postavkama.\",\n  \"DEMO_LOOPS_REACHED\": \"Žao nam je, ali budući da je ovo demo aplikacija, ne možemo izvoditi rad agenata predugo. Napomena: Ako želite dulje izvršavanje, molimo unesite vlastiti API ključ u Postavkama. Prestajem raditi...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agent je ručno zaustavljen.\",\n  \"ALL_TASKS_COMPLETETD\": \"Svi zadaci su završeni. Zaustavljam...\",\n  \"ERROR_API_KEY_QUOTA\": \"Pogreška pri korištenju OpenAI API ključa. Premašili ste trenutnu kvotu, molimo provjerite svoje fakturiranje.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"POGREŠKA: Vaš OpenAI API ključ nema pristup GPT-4. Prvo se morate prijaviti na OpenAI čekalici. (Ovo se razlikuje od ChatGPT Plus-a)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"Pogreška prilikom preuzimanja početnih zadataka. Pokušajte ponovno, jasnije definirajte cilj agenta ili ga prilagodite kako bi odgovarao našem modelu. Zaustavljam...\",\n  \"INVALID_OPENAI_API_KEY\": \"POGREŠKA nevažeći OpenAI API ključ\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentacija AgentGPT-a\",\n\t\"FOLLOW_THE_JOURNEY\": \"Pratite naše putovanje u nastavku:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interakcija s web stranicama i ljudima 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"omogućuje vam konfiguriranje i pokretanje samostalnih AI agenata u vašem pregledniku. Nazovite svoj prilagođeni AI agent i odredite njegov cilj. AI agent će pokušati postići određeni cilj stvaranjem zadataka, izvršavanjem zadataka, a zatim procjenom rezultata 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Dugoročna memorija 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Ova platforma trenutno je u beta verziji, trenutno radimo na sljedećem:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Da biste saznali više o AgentGPT-u, njegovom planu, često postavljanim pitanjima itd., posjetite\",\n\t\"WEB_BROWSING\": \"Web pregledavanje 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Dobrodošli u AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Sastavite, konfigurirajte i instalirajte autonomne AI agente u svom pregledniku.\",\n  \"AGENT_NAME\": \"Ime\",\n  \"LABEL_AGENT_GOAL\": \"Cilj\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Učinite svijet boljim mjestom\",\n  \"BUTTON_DEPLOY_AGENT\": \"Pokreni agenta\",\n  \"BUTTON_STOP_AGENT\": \"Zaustavi agenta\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/languages.json",
    "content": "{\n    \"ENGLISH\": \"Engleski\",\n    \"FRENCH\": \"Francuski\",\n    \"SPANISH\": \"Španjolski\",\n    \"GERMAN\": \"Njemački\",\n    \"JAPANESE\": \"Japanski\",\n    \"KOREAN\": \"Korejski\",\n    \"CHINESE\": \"Kineski\",\n    \"PORTUGEES\": \"Portugalski\",\n    \"ITALIAN\": \"Talijanski\",\n    \"DUTCH\": \"Nizozemski\",\n    \"POLSKI\": \"Poljski\",\n    \"HUNGARIAN\": \"Mađarski\",\n    \"ROMANIAN\": \"Rumunjski\",\n    \"SLOVAK\": \"Slovački\"\n}\n"
  },
  {
    "path": "next/public/locales/hr/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Napredne postavke\",\n\t\"API_KEY\": \"API ključ\",\n\t\"AUTOMATIC_MODE\": \"Automatski način rada\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Zadano): Agent automatski izvršava svaki zadatak.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Kontrolira maksimalni broj tokena korištenih u svakom pojedinom API pozivu (viša vrijednost rezultira detaljnijim odgovorima, ali je skuplje).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Kontrolira maksimalni broj petlji koje će agent pokrenuti (viša vrijednost rezultira više API poziva).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Obtenez votre propre clé API OpenAI\",\n\t\"HERE\": \"ovdje\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Ovdje možete dodati svoj OpenAI API ključ. To znači da ćete morati platiti za korištenje vlastitog OpenAI tokena, ali ćete dobiti veći pristup ChatGPT-u! Također možete odabrati bilo koji model koji nudi OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Više vrijednosti čine izlaz više slučajnim, dok niže vrijednosti čine izlaz usredotočenijim i preciznijim.\",\n\t\"INFO_TO_USE_GPT4\": \"Za korištenje GPT-4 modela potreban je i API ključ. Možete ga nabaviti\",\n\t\"INVALID_OPENAI_API_KEY\": \"Clé API invalide !\",\n\t\"LABEL_MODE\": \"Mode\",\n\t\"LABEL_MODEL\": \"Model\",\n\t\"LANG\": \"Jezik\",\n\t\"LINK\": \"Zahtjev za API ključ\",\n\t\"LOOP\": \"Petlja\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Napomena: Morate povezati kreditnu karticu s vašim računom\",\n\t\"NOTE_API_KEY_USAGE\": \"Ovaj ključ se koristi samo u trenutnoj sesiji preglednika.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"NAPOMENA: Da biste dobili API ključ, morate se registrirati za OpenAI račun na sljedećoj poveznici:\",\n\t\"PAUSE\": \"Pauza\",\n\t\"PAUSE_MODE\": \"Način pauziranja\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Agent se pauzira nakon svakog seta zadataka.\",\n\t\"PENAI_API_KEY\": \"Nevažeći OpenAI API ključ\",\n\t\"PLAY\": \"Reproduciraj\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Postavke ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(ChatGPT Plus pretplata neće raditi)\",\n\t\"TEMPERATURE\": \"Temperatura\",\n\t\"TOKENS\": \"Tokeni\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/chat.json",
    "content": "{\n  \"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Kivételesen nagy forgalmat tapasztalunk, várható késések és hibák, ha nem a saját API-kulcsát használja 🚨\",\n  \"CREATE_AN_AGENT_DESCRIPTION\": \"Hozzon létre egy ügynököt a név és a cél hozzáadásával, majd kattintson az \\\"Ügynök indítása!\\\" gombra\",\n  \"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Saját OpenAI API-kulcsot adhat meg a beállítások fülön az emelt korlátok érdekében!\",\n  \"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Segítse az AgentGPT fejlesztését. 💝️\",\n  \"CONSIDER_SPONSORING_ON_GITHUB\": \"Támogasson a projektet a GitHub-on keresztül.\",\n  \"SUPPORT_NOW\": \"Támogatás most 🚀\",\n  \"EMBARKING_ON_NEW_GOAL\": \"Új cél elérése:\",\n  \"THINKING\": \"Gondolkodás...\",\n  \"TASK_ADDED\": \"Feladat hozzáadva:\",\n  \"COMPLETING\": \"Befejezés:\",\n  \"NO_MORE_TASKS\": \"Nincsenek további alfeladatok ehhez:\",\n  \"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Szöveg másolva a vágólapra\",\n  \"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Nem sikerült a szöveg vágólapra másolása\",\n  \"RESTART_IF_IT_TAKES_X_SEC\": \"(Frissítse az oldalt vagy indítsa újra az ügynököt manuálisan, ha ez több mint 30 másodpercig tart)\",\n  \"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Hozzon létre egy ügynököt név/cél hozzáadásával, és a telepítés gombra kattintva!\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Hozzon létre egy ügynököt név/cél hozzáadásával, és a telepítés gombra kattintva! \\nPróbáld ki az alábbi példáinkat!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Feladat hozzáadása\",\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT Dokumentáció\",\n\t\"CLOSE\": \"Bezárás\",\n\t\"CONTINUE\": \"Folytatás\",\n\t\"COPIED_TO_CLIPBOARD\": \"Vágólapra másolva 🚀\",\n\t\"COPY\": \"Másolás\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Hozzon létre egy ügynököt egy név / cél hozzáadásával, és nyomja meg a telepítést!\",\n\t\"CURRENT_TASKS\": \"Jelenlegi feladatok\",\n\t\"EXECUTING\": \"Feladat végrehajtása\",\n\t\"EXPORT\": \"Exportálás\",\n\t\"IMAGE\": \"Kép\",\n\t\"LOOP\": \"Kör\",\n\t\"PAUSED\": \"Szüneteltetve\",\n\t\"RESET\": \"Visszaállítás\",\n\t\"RUNNING\": \"Folyamatban\",\n\t\"SAVE\": \"Mentés\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Hogy többet megtudjon az AgentGPT-ről látogasson el a\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Készítsen átfogó jelentést a Nike cégről\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Ha problémái vannak, kérjük, látogasson el hozzánk\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Tervezz meg egy részletes utazást Hawaiira.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"ResearchGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"Webes keresés\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/drawer.json",
    "content": "{\n  \"HELP_BUTTON\": \"Segítség\",\n  \"SETTINGS_BUTTON\": \"Beállítások\",\n  \"SUPPORT_BUTTON\": \"Támogatás\",\n  \"MY_AGENTS\": \"Az én ügynökeim\",\n  \"SIGN_IN_NOTICE\": \"Jelentkezzen be, hogy menthesse az ügynökeit, és kezelhesse a fiókját!\",\n  \"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Először létre kell hoznia és mentenie az első ügynökét, mielőtt itt valami megjelenne!\",\n  \"SIGN_IN\": \"Bejelentkezés\",\n  \"SIGN_OUT\": \"Kijelentkezés\",\n  \"ACCOUNT\" : \"Fiók\",\n  \"USER_IMAGE\": \"Felhasználói kép\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"HIBA a OpenAI API-hoz való csatlakozás közben. Kérjük, ellenőrizze az API-kulcsot, vagy próbálja meg később.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"HIBA a további feladat(ok) hozzáadása közben. Lehet, hogy a modellünk nem tudja kezelni a választ és az eredményezte ezt. Folytatás...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Elérte a maximális lekérdezések számát! Kérjük, lassítson le...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Ez az ügynök elérte a maximális futtatható köreinek a számát. Hogy megmentse a pénztárcáját, ez az ügynök most leáll... Az ügynök futási köreinek a maximális számát az beállításokban lehet konfigurálni.\",\n  \"DEMO_LOOPS_REACHED\": \"Sajnáljuk, de mivel ez egy bemutató alkalmazás így nem tudjuk túl hosszú ideig futtatni az ügynökeit. Megjegyzés: ha hosszabb futtatásokat szeretne, kérjük, adjon meg egy saját API-kulcsot a Beállításokban. Leállítás...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Az ügynök manuálisan leállítva.\",\n  \"ALL_TASKS_COMPLETETD\": \"Minden feladat befejeződött. Leállítás...\",\n  \"ERROR_API_KEY_QUOTA\": \"HIBA az OpenAI API-kulcs használatakor. Túllépte jelenlegi kvótáját, kérjük, ellenőrizze számlázási adatait.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"HIBA: Az Ön OpenAI API kulcsa nem rendelkezik GPT-4 hozzáféréssel. Először jelentkeznie kell az OpenAI várólistáján. (Ez eltér a ChatGPT Plus-tól)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"HIBA az alapfeladatok lekérdezése közben. Próbálja újra, fogalmazza meg az ügynök célját világosabban, vagy módosítsa a oly módon, hogy az megfeleljen a modellünk számára. Leállítás...\",\n  \"INVALID_OPENAI_API_KEY\": \"HIBA érvénytelen OpenAI API-kulcs\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT dokumentációja\",\n\t\"FOLLOW_THE_JOURNEY\": \"Kövessen minket az alábbi utakon:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interakció a weboldalakkal és az emberekkel 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"lehetővé teszi az Ön számára, hogy konfigurálja és futtassa az önálló MI ügynököket a böngészőjén keresztül. Nevezze el az egyéni MI ügynökét, és határozza meg a célját. Az MI ügynök Megkísérli elérni a meghatározott célt azzal, hogy feladatokra hoz létre, végrehajtja őket, majd kiértékeli azok eredményeit 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Hosszú távú memória 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Ez a platform jelenleg béta verzióban van, jelenleg a következőkön dolgozunk:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Ha többet szeretne megtudni az AgentGPT-ről, annak ütemtervéről, GYIK-ról stb., látogasson el a következő oldalra\",\n\t\"WEB_BROWSING\": \"Webes böngészés 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Üdvözöljük az AgentGPT-nél\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/indexPage.json",
    "content": "{\n  \"BETA\": \"Béta\",\n  \"HEADING_DESCRIPTION\": \"Összeállít, konfigurál és telepít autonóm MI ügynököket a böngészőjében.\",\n  \"AGENT_NAME\": \"Név\",\n  \"LABEL_AGENT_GOAL\": \"Cél\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Tedd egy jobb hellyé a világot\",\n  \"BUTTON_DEPLOY_AGENT\": \"Ügynök futtatása\",\n  \"BUTTON_STOP_AGENT\": \"Ügynök leállítása\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/languages.json",
    "content": "{\n    \"ENGLISH\": \"Angol\",\n    \"FRENCH\": \"Francia\",\n    \"SPANISH\": \"Spanyol\",\n    \"GERMAN\": \"Német\",\n    \"JAPANESE\": \"Japán\",\n    \"KOREAN\": \"Koreai\",\n    \"CHINESE\": \"Kínai\",\n    \"PORTUGEES\": \"Portugál\",\n    \"ITALIAN\": \"Olasz\",\n    \"DUTCH\": \"Holland\",\n    \"POLSKI\": \"Lengyel\",\n    \"HUNGARIAN\": \"Magyar\",\n    \"ROMANIAN\": \"Román\",\n    \"SLOVAK\": \"Szlovák\"\n}\n"
  },
  {
    "path": "next/public/locales/hu/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Haladó beállítások\",\n\t\"API_KEY\": \"Kulcs\",\n\t\"AUTOMATIC_MODE\": \"Automatikus mód\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Alapértelmezett): Az ügynök automatikusan végrehajt minden feladatot.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Szabályozza a minden egyes API-hívásban használt tokenek maximális számát (magasabb érték részletesebb válaszokat eredményez, de többe kerül).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Szabályozza az ügynök által futtatott ciklusok maximális számát (magasabb érték több API-hívást eredményez).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Szerezze be saját OpenAI API kulcsát\",\n\t\"HERE\": \"itt\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Itt adhatja hozzá az OpenAI API-kulcsát. Ez azt jelenti, hogy saját OpenAI token felhasználásáért fizetnie kell, de nagyobb hozzáférést kap a ChatGPT-hez! Továbbá bármely OpenAI által kínált modellt is kiválaszthat.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Magasabb értékek több véletlenszerűséget adnak a kimenetnek, míg alacsonyabb értékek fókuszáltabbá és meghatározottabbá teszik azt.\",\n\t\"INFO_TO_USE_GPT4\": \"A GPT-4 modell használatához szükséges az API-kulcs megadása is. Beszerezheti\",\n\t\"INVALID_OPENAI_API_KEY\": \"Érvénytelen API kulcs!\",\n\t\"LABEL_MODE\": \"Mód\",\n\t\"LABEL_MODEL\": \"Modell\",\n\t\"LANG\": \"Nyelv\",\n\t\"LINK\": \"API kulcs igénylése\",\n\t\"LOOP\": \"Ciklus\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Megjegyzés: Kreditkártyát kell csatlakoztatnia a fiókjához\",\n\t\"NOTE_API_KEY_USAGE\": \"Ez a kulcs csak az aktuális böngészői munkamenetben használatos.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"MEGJEGYZÉS: Az API-kulcs megszerzéséhez regisztrálnia kell egy OpenAI-fiókot, amit a következő hivatkozáson tehet meg:\",\n\t\"PAUSE\": \"Szünet\",\n\t\"PAUSE_MODE\": \"Szünet mód\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Az ügynök szünetel minden feladatkészlet után.\",\n\t\"PENAI_API_KEY\": \"Érvénytelen OpenAI API-kulcs\",\n\t\"PLAY\": \"Lejátszás\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Beállítások ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(A ChatGPT Plus előfizetés nem működik)\",\n\t\"TEMPERATURE\": \"Temperametum\",\n\t\"TOKENS\": \"Tokenek\"\n}\n"
  },
  {
    "path": "next/public/locales/it/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Completando:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Considera di sponsorizzare il progetto su GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Testo copiato negli appunti\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Impossibile copiare il testo negli appunti\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Crea un agente aggiungendo nome e obiettivo, quindi premi il pulsante \\\"Avvia agente!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Affrontando un nuovo obiettivo:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Stiamo riscontrando un traffico eccezionalmente elevato, si prevedono ritardi e errori se non si utilizza la propria chiave API 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Aiuta a sostenere lo sviluppo di AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Non ci sono più sottocompiti per questo:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Ricaricare la pagina o avviare manualmente l'agente se ciò richiede più di 30 secondi)\",\n\t\"SUPPORT_NOW\": \"Supporto ora 🚀\",\n\t\"TASK_ADDED\": \"Compito aggiunto:\",\n\t\"THINKING\": \"Pensando...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 È possibile fornire la propria chiave API OpenAI nella scheda Impostazioni per ottenere limiti superiori!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Crea un agente aggiungendo un nome/target e premendo deploy!\"\n}\n"
  },
  {
    "path": "next/public/locales/it/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Crea un agente aggiungendo un nome/obiettivo e premendo Distribuisci! \\nProva i nostri esempi qui sotto!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та METу, а потім клацніть KNOPку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/it/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Aggiunta attività\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentazione di AgentGPT\",\n\t\"CLOSE\": \"Chiudi\",\n\t\"CONTINUE\": \"Continua\",\n\t\"COPIED_TO_CLIPBOARD\": \"Copiato negli appunti! 🚀\",\n\t\"COPY\": \"Copia\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Crea un agente aggiungendo un nome/obiettivo e premendo Distribuisci!\",\n\t\"CURRENT_TASKS\": \"Compiti attuali\",\n\t\"EXECUTING\": \"Esecuzione\",\n\t\"EXPORT\": \"Esporta\",\n\t\"IMAGE\": \"Immagine\",\n\t\"LOOP\": \"Ciclo continuo\",\n\t\"PAUSED\": \"In pausa\",\n\t\"RESET\": \"Ripristina\",\n\t\"RUNNING\": \"In esecuzione\",\n\t\"SAVE\": \"Salva\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Per ottenere maggiori informazioni su AgentGPT, la sua Roadmap, ecc., visita il seguente link\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Creare un rapporto completo della società Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"In caso di problemi, vai al nostro\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Pianifica un viaggio dettagliato alle Hawaii.\",\n\t\"platformergpt\": \"Piattaforma GPT 🎮\",\n\t\"researchgpt\": \"RicercaGPT 📜\",\n\t\"travelgpt\": \"ViaggiGPT 🌴\",\n\t\"web-search\": \"Ricerca sul web\"\n}\n"
  },
  {
    "path": "next/public/locales/it/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Account\",\n\t\"HELP_BUTTON\": \"Aiuto\",\n\t\"MY_AGENTS\": \"I miei agenti\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Prima di visualizzare qualcosa qui, devi creare e salvare il tuo primo agente!\",\n\t\"SETTINGS_BUTTON\": \"Impostazioni\",\n\t\"SIGN_IN\": \"Accedi\",\n\t\"SIGN_IN_NOTICE\": \"Effettua l'accesso per salvare i tuoi agenti e gestire il tuo account!\",\n\t\"SIGN_OUT\": \"Esci\",\n\t\"SUPPORT_BUTTON\": \"Supporto\",\n\t\"USER_IMAGE\": \"Immagine utente\"\n}\n"
  },
  {
    "path": "next/public/locales/it/errors.json",
    "content": "{\n    \"ERROR_ACCESSING_OPENAI_API_KEY\": \"ERRORE durante l'accesso alla chiave API di OpenAI. Controllare la chiave API o riprovare più tardi.\",\n    \"ERROR_ADDING_ADDITIONAL_TASKS\": \"ERRORE durante l'aggiunta di ulteriori compiti. Potrebbe essere che il nostro modello non riesca a gestire la risposta e ciò abbia generato l'errore. Continua...\",\n    \"RATE_LIMIT_EXCEEDED\": \"Limite massimo di query raggiunto! Si prega di rallentare...😅\",\n    \"AGENT_MAXED_OUT_LOOPS\": \"Questo agente ha raggiunto il numero massimo di cicli eseguibili. Per salvare il portafoglio, questo agente si fermerà ora... Il numero massimo di cicli di esecuzione dell'agente può essere configurato nelle impostazioni.\",\n    \"DEMO_LOOPS_REACHED\": \"Spiacente, poiché questa è un'applicazione demo, non possiamo far funzionare gli agenti per troppo tempo. Nota: se desideri eseguire cicli più lunghi, fornisci una chiave API personalizzata nelle Impostazioni. Si ferma...\",\n    \"AGENT_MANUALLY_SHUT_DOWN\": \"Agente arrestato manualmente.\",\n    \"ALL_TASKS_COMPLETETD\": \"Tutti i compiti sono stati completati. Arresto...\",\n    \"ERROR_API_KEY_QUOTA\": \"ERRORE nell'uso della chiave API di OpenAI. Hai superato la tua quota corrente, controlla le tue informazioni di fatturazione.\",\n    \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"ERRORE: la tua chiave API di OpenAI non ha accesso a GPT-4. Prima devi registrarti nella lista d'attesa di OpenAI. (Ciò differisce da ChatGPT Plus)\",\n    \"ERROR_RETRIEVE_INITIAL_TASKS\": \"ERRORE durante il recupero dei compiti iniziali. Riprova, formulando più chiaramente l'obiettivo dell'agente o modificandolo in modo che sia conforme al nostro modello. Arresto...\",\n    \"INVALID_OPENAI_API_KEY\": \"ERRORE chiave API OpenAI non valida\"\n}"
  },
  {
    "path": "next/public/locales/it/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentazione di AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Seguici sui seguenti canali:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interazione con siti web e persone 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"consente di configurare e eseguire agenti di intelligenza artificiale autonomi nel proprio browser. Assegna un nome al tuo agente di intelligenza artificiale personalizzato e definisci il suo obiettivo. L'agente di intelligenza artificiale cercherà di raggiungere l'obiettivo specificato creando compiti, eseguendoli e valutando i risultati 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Memoria a lungo termine 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Questa piattaforma è attualmente in versione beta, al momento stiamo lavorando su:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Per saperne di più su AgentGPT, la sua tabella di marcia, le domande frequenti, ecc., visita il\",\n\t\"WEB_BROWSING\": \"Navigazione Web 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Benvenuti in AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/it/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Compila, configura e installa agenti AI autonomi nel tuo browser.\",\n  \"AGENT_NAME\": \"Nome\",\n  \"LABEL_AGENT_GOAL\": \"Obiettivo\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Rendi il mondo un posto migliore\",\n  \"BUTTON_DEPLOY_AGENT\": \"Esegui agente\",\n  \"BUTTON_STOP_AGENT\": \"Arresta agente\"\n}\n"
  },
  {
    "path": "next/public/locales/it/languages.json",
    "content": "{\n    \"ENGLISH\": \"Inglese\",\n    \"FRENCH\": \"Francese\",\n    \"SPANISH\": \"Spagnolo\",\n    \"GERMAN\": \"Tedesco\",\n    \"JAPANESE\": \"Giapponese\",\n    \"KOREAN\": \"Coreano\",\n    \"CHINESE\": \"Cinese\",\n    \"PORTUGEES\": \"Portoghese\",\n    \"ITALIAN\": \"Italiano\",\n    \"DUTCH\": \"Olandese\",\n    \"POLSKI\": \"Polacco\",\n    \"HUNGARIAN\": \"Ungherese\",\n    \"ROMANIAN\": \"Rumeno\",\n    \"SLOVAK\": \"Slovacco\"\n}\n"
  },
  {
    "path": "next/public/locales/it/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Impostazioni avanzate\",\n\t\"API_KEY\": \"Chiave API\",\n\t\"AUTOMATIC_MODE\": \"Modalità automatica\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Predefinito): L'agente esegue automaticamente ogni compito.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Controlla il numero massimo di token utilizzati in ogni chiamata API (un valore più alto fornisce risposte più dettagliate ma ha un costo maggiore).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Controlla il numero massimo di loop eseguiti dall'agente (un valore più alto comporta più chiamate API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Ottieni la tua chiave API OpenAI\",\n\t\"HERE\": \"qui\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Qui puoi aggiungere la tua chiave API OpenAI. Ciò significa che dovrai pagare l'utilizzo dei tuoi token OpenAI, ma avrai un maggiore accesso a ChatGPT! Inoltre, puoi selezionare qualsiasi modello offerto da OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Valori più alti rendono l'output più casuale, mentre valori più bassi lo rendono più focalizzato e determinato.\",\n\t\"INFO_TO_USE_GPT4\": \"Per utilizzare il modello GPT-4 è necessario fornire la chiave API. Puoi ottenerla\",\n\t\"INVALID_OPENAI_API_KEY\": \"Chiave API non valida!\",\n\t\"LABEL_MODE\": \"Modalità\",\n\t\"LABEL_MODEL\": \"Modello\",\n\t\"LANG\": \"Lingua\",\n\t\"LINK\": \"Richiesta chiave API\",\n\t\"LOOP\": \"Loop\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Nota: Devi collegare una carta di credito al tuo account\",\n\t\"NOTE_API_KEY_USAGE\": \"Questa chiave verrà utilizzata solo durante la sessione del browser corrente.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"NOTA: Per ottenere la chiave API è necessario registrarsi per un account OpenAI, che può essere fatto al seguente link:\",\n\t\"PAUSE\": \"Metti in pausa\",\n\t\"PAUSE_MODE\": \"Modalità pausa\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"L'agente si mette in pausa dopo ogni insieme di compiti.\",\n\t\"PENAI_API_KEY\": \"Chiave API OpenAI non valida\",\n\t\"PLAY\": \"Riproduci\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Impostazioni ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(La sottoscrizione ChatGPT Plus non funzionerà)\",\n\t\"TEMPERATURE\": \"Temperatura\",\n\t\"TOKENS\": \"Token\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Completing:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Please consider sponsoring the project on GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Text copied to clipboard\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Unable to copy text to clipboard\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Create an agent by adding a name / goal, and hitting deploy!\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"新たな目標への着手：\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 We are experiencing exceptional traffic, expect delays and failures if you do not use your own API key🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Help support the advancement of AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"No more subtasks for:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Restart if this takes more than 30 seconds)\",\n\t\"SUPPORT_NOW\": \"Support now 🚀\",\n\t\"TASK_ADDED\": \"追加されたタスク:\",\n\t\"THINKING\": \"考え...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 You can provide your own OpenAI API key in the settings tab for increased limits!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 名前/ターゲットを追加し、デプロイを押してエージェントを作成してください!\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 名前/目標を追加してエージェントを作成し、デプロイを押してください!\\n以下の例を試してみてください。\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, апотім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 1 つの代理を作成し、名前と目印を追加し、その後、「启动代理!」\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"タスクの追加\",\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT のドキュメント\",\n\t\"CLOSE\": \"閉じる\",\n\t\"CONTINUE\": \"続く\",\n\t\"COPIED_TO_CLIPBOARD\": \"クリップボードにコピーしました！ 🚀\",\n\t\"COPY\": \"コピー\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"名前/目標を追加してエージェントを作成し、デプロイを押してください!\",\n\t\"CURRENT_TASKS\": \"現在のタスク\",\n\t\"EXECUTING\": \"実行中\",\n\t\"EXPORT\": \"エクスポート\",\n\t\"IMAGE\": \"画像\",\n\t\"LOOP\": \"ループ\",\n\t\"PAUSED\": \"一時停止\",\n\t\"RESET\": \"リセット\",\n\t\"RUNNING\": \"進行中\",\n\t\"SAVE\": \"保存\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"AgentGPT やそのロードマップなどの詳細については、次のリンクにアクセスしてください。\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"ナイキ社の包括的なレポートを作成する\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"問題に直面している場合は、\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"ハワイへの詳細な旅行を計画します。\",\n\t\"platformergpt\": \"プラットフォーマーGPT 🎮\",\n\t\"researchgpt\": \"リサーチGPT📜\",\n\t\"travelgpt\": \"トラベルGPT🌴\",\n\t\"web-search\": \"ウェブ検索\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"アカウント\",\n\t\"HELP_BUTTON\": \"ヘルプ\",\n\t\"MY_AGENTS\": \"私のエージェント\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"ここに何か表示される前に、最初にエージェントを作成して保存する必要があります！\",\n\t\"SETTINGS_BUTTON\": \"設定\",\n\t\"SIGN_IN\": \"ログイン\",\n\t\"SIGN_IN_NOTICE\": \"アカウントを保存し、エージェントを管理するにはログインしてください！\",\n\t\"SIGN_OUT\": \"ログアウト\",\n\t\"SUPPORT_BUTTON\": \"サポート\",\n\t\"USER_IMAGE\": \"ユーザー画像\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"OpenAI APIキーにアクセスできませんでした。APIキーを確認するか、後でもう一度お試しください。\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"追加タスクの追加中にエラーが発生しました。モデルが回答を扱えない可能性があるため、処理を続行します...\",\n  \"RATE_LIMIT_EXCEEDED\": \"最大クエリ数に達しました！ 一時的にお待ちください...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"このエージェントは、最大実行可能なループ数に達しました。財布を救うために、このエージェントは今停止します... エージェントの最大実行可能なループ数は設定で構成できます。\",\n  \"DEMO_LOOPS_REACHED\": \"申し訳ありませんが、これはデモアプリケーションなので、エージェントを長時間実行することはできません。注：より長い実行を希望する場合は、設定でAPIキーを入力してください。停止...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"エージェントが手動でシャットダウンされました。\",\n  \"ALL_TASKS_COMPLETETD\": \"すべてのタスクが完了しました。停止...\",\n  \"ERROR_API_KEY_QUOTA\": \"OpenAI APIキーを使用する際のエラー。現在のクォータを超えています。請求情報を確認してください。\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"エラー：お持ちのOpenAI APIキーにはGPT-4アクセス権がありません。まずOpenAIの待ち行列に登録する必要があります。（ChatGPT Plusとは異なります）\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"初期タスクの取得中にエラーが発生しました。再試行するか、エージェントの目的を明確にしたり、モデルに適合するように変更してください。停止...\",\n  \"INVALID_OPENAI_API_KEY\": \"エラー 無効なOpenAI APIキー\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT のドキュメント\",\n\t\"FOLLOW_THE_JOURNEY\": \"以下のチャンネルで私たちに参加してください:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"ウェブサイトや人々との相互作用 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"は、ブラウザーで独自のAIエージェントを構成して実行することができます。独自のAIエージェントに名前を付け、目標を定義します。AIエージェントは、タスクを作成し、実行し、結果を評価することで、指定された目標を達成しようとします 🚀\",\n\t\"LONG_TERM_MEMORY\": \"長期的な記憶 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"このプラットフォームは現在ベータ版です。現在、以下に取り組んでいます：\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"AgentGPT、そのロードマップ、FAQ などの詳細については、\",\n\t\"WEB_BROWSING\": \"Webブラウジング 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"AgentGPTへようこそ\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/indexPage.json",
    "content": "{\n  \"BETA\": \"ベータ版\",\n  \"HEADING_DESCRIPTION\": \"ブラウザーで自律型AIエージェントを構成、設定、およびインストールします。\",\n  \"AGENT_NAME\": \"名前\",\n  \"LABEL_AGENT_GOAL\": \"目標\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"世界をより良い場所にする\",\n  \"BUTTON_DEPLOY_AGENT\": \"エージェントを実行\",\n  \"BUTTON_STOP_AGENT\": \"エージェントを停止\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/languages.json",
    "content": "{\n    \"ENGLISH\": \"英語\",\n    \"FRENCH\": \"フランス語\",\n    \"SPANISH\": \"スペイン語\",\n    \"GERMAN\": \"ドイツ語\",\n    \"JAPANESE\": \"日本語\",\n    \"KOREAN\": \"韓国語\",\n    \"CHINESE\": \"中国語\",\n    \"PORTUGEES\": \"ポルトガル語\",\n    \"ITALIAN\": \"イタリア語\",\n    \"DUTCH\": \"オランダ語\",\n    \"POLSKI\": \"ポーランド語\",\n    \"HUNGARIAN\": \"ハンガリー語\",\n    \"ROMANIAN\": \"ルーマニア語\",\n    \"SLOVAK\": \"スロバキア語\"\n}\n"
  },
  {
    "path": "next/public/locales/ja/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"高度な設定\",\n\t\"API_KEY\": \"APIキー\",\n\t\"AUTOMATIC_MODE\": \"自動モード\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"（デフォルト）：エージェントはすべてのタスクを自動的に実行します。\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"各API呼び出しで使用されるトークンの最大数を制御します（より高い値は詳細な応答を生成しますが、コストがかかります）。\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"エージェントが実行するループの最大数を制御します（高い値はより多くのAPI呼び出しを生成します）。\",\n\t\"GET_YOUR_OWN_APIKEY\": \"自分自身のOpenAI APIキーを取得してください\",\n\t\"HERE\": \"こちら\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"ここでOpenAI APIキーを追加できます。これにより、独自のOpenAIトークンを使用するために支払いをする必要がありますが、ChatGPTにより大きなアクセス権が与えられます！また、OpenAIが提供する任意のモデルを選択できます。\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"より高い値は出力をよりランダムにしますが、より低い値はより焦点を絞り、定義されたものにします。\",\n\t\"INFO_TO_USE_GPT4\": \"GPT-4モデルを使用するには、APIキーの指定が必要です。取得できます\",\n\t\"INVALID_OPENAI_API_KEY\": \"APIキーが無効です！\",\n\t\"LABEL_MODE\": \"モード\",\n\t\"LABEL_MODEL\": \"モデル\",\n\t\"LANG\": \"言語\",\n\t\"LINK\": \"APIキーの申請\",\n\t\"LOOP\": \"ループ\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"注意: クレジットカードをアカウントに接続する必要があります\",\n\t\"NOTE_API_KEY_USAGE\": \"このキーは現在のブラウザセッションでのみ使用されます。\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"注意：APIキーを取得するには、次のリンクでOpenAIアカウントに登録する必要があります。\",\n\t\"PAUSE\": \"一時停止\",\n\t\"PAUSE_MODE\": \"一時停止モード\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"エージェントは、各タスクセットの後に一時停止します。\",\n\t\"PENAI_API_KEY\": \"OpenAI API キーが無効です\",\n\t\"PLAY\": \"再生\",\n\t\"SETTINGS_DIALOG_HEADER\": \"設定 ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"（ChatGPT Plusのサブスクリプションは機能しません）\",\n\t\"TEMPERATURE\": \"温度\",\n\t\"TOKENS\": \"トークン\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/chat.json",
    "content": "{\n\t\"COMPLETING\": \"완료중:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"GitHub에서 이 프로젝트를 후원해주세요.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"텍스트가 클립보드에 복사됨\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"텍스트를 클립보드에 복사할 수 없습니다\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"이름과 목표를 추가하여 에이전트를 생성한 다음, \\\"에이전트 시작!\\\" 버튼을 클릭하세요.\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"새로운 목표 시작:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 우리는 예외적인 교통량을 경험하고 있습니다. API 키를 사용하지 않으면 지연과 오류가 예상됩니다 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ AgentGPT의 발전을 지원하세요. 💝️\",\n\t\"NO_MORE_TASKS\": \"더 이상 이 작업에 대한 하위 작업이 없습니다:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(30초 이상 걸리면 페이지를 새로 고치거나 에이전트를 수동으로 재시작하세요)\",\n\t\"SUPPORT_NOW\": \"지금 지원하기 🚀\",\n\t\"TASK_ADDED\": \"작업 추가됨:\",\n\t\"THINKING\": \"생각중...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 고객님만의 OpenAI API 키를 설정 탭에서 제공하면 제한을 늘릴 수 있습니다!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 이름/대상을 추가하고 배포를 눌러 에이전트를 생성하세요!\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 이름/목표를 추가하고 배포를 눌러 에이전트를 생성하세요! \\n아래 예시를 시도해 보세요!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"작업 추가\",\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT 문서\",\n\t\"CLOSE\": \"닫기\",\n\t\"CONTINUE\": \"계속하다\",\n\t\"COPIED_TO_CLIPBOARD\": \"클립보드에 복사되었습니다! 🚀\",\n\t\"COPY\": \"복사\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"이름/목표를 추가하고 배치를 눌러 에이전트를 생성하십시오!\",\n\t\"CURRENT_TASKS\": \"현재 작업\",\n\t\"EXECUTING\": \"실행 중\",\n\t\"EXPORT\": \"내보내기\",\n\t\"IMAGE\": \"이미지\",\n\t\"LOOP\": \"반복\",\n\t\"PAUSED\": \"일시중지됨\",\n\t\"RESET\": \"재설정\",\n\t\"RUNNING\": \"진행 중\",\n\t\"SAVE\": \"저장\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"AgentGPT, 로드맵 등에 대한 자세한 정보를 얻으려면 다음 링크를 방문하십시오.\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Nike 회사에 대한 포괄적인 보고서 작성\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"문제가 있는 경우 당사로 이동하십시오.\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"하와이로의 상세한 여행을 계획하십시오.\",\n\t\"platformergpt\": \"플랫포머GPT 🎮\",\n\t\"researchgpt\": \"ResearchGPT 📜\",\n\t\"travelgpt\": \"여행GPT 🌴\",\n\t\"web-search\": \"웹 서핑\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"계정\",\n\t\"HELP_BUTTON\": \"도움말\",\n\t\"MY_AGENTS\": \"나의 대리인\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"여기에 무언가 표시되기 전에 먼저 대리인을 생성하고 저장해야합니다!\",\n\t\"SETTINGS_BUTTON\": \"설정\",\n\t\"SIGN_IN\": \"로그인\",\n\t\"SIGN_IN_NOTICE\": \"계정을 관리하고 대리인을 저장하려면 로그인하세요!\",\n\t\"SIGN_OUT\": \"로그아웃\",\n\t\"SUPPORT_BUTTON\": \"지원하다\",\n\t\"USER_IMAGE\": \"사용자 이미지\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"오류: OpenAI API에 접속하는 중에 문제가 발생했습니다. API 키를 확인하거나 나중에 다시 시도해주세요.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"오류: 추가 작업을 추가하는 중에 문제가 발생했습니다. 모델이 답변을 처리할 수 없어서 발생한 것일 수 있습니다. 계속 진행합니다...\",\n  \"RATE_LIMIT_EXCEEDED\": \"최대 쿼리 수를 초과했습니다! 속도를 늦춰주세요...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"이 에이전트는 최대 실행 가능한 루프 수에 도달했습니다. 지갑을 보호하기 위해 이제 이 에이전트를 중단합니다... 에이전트 실행 횟수의 최대값은 설정에서 구성할 수 있습니다.\",\n  \"DEMO_LOOPS_REACHED\": \"죄송합니다. 이것은 데모 애플리케이션이기 때문에 에이전트를 너무 오래 실행할 수 없습니다. 참고: 더 오래 실행하려면 설정에서 자체 API 키를 제공해주세요. 중단합니다...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"에이전트가 수동으로 중단되었습니다.\",\n  \"ALL_TASKS_COMPLETETD\": \"모든 작업이 완료되었습니다. 중단합니다...\",\n  \"ERROR_API_KEY_QUOTA\": \"OpenAI API 키를 사용하는 중에 오류가 발생했습니다. 현재 할당량을 초과하였습니다. 결제 정보를 확인해주세요.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"오류: OpenAI API 키에 GPT-4 액세스 권한이 없습니다. 먼저 OpenAI 대기열에 등록해야합니다. (이는 ChatGPT Plus와 다릅니다)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"오류: 초기 작업을 검색하는 중에 문제가 발생했습니다. 에이전트 목적을 명확하게 제시하거나 모델에 맞도록 수정하십시오. 중단합니다...\",\n  \"INVALID_OPENAI_API_KEY\": \"에러 유효하지 않은 OpenAI API 키\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT 문서\",\n\t\"FOLLOW_THE_JOURNEY\": \"아래의 방법으로 우리를 따라가십시오:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"웹 사이트 및 사람들과의 상호 작용 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"AgentGPT는 브라우저를 통해 독립적인 AI 에이전트를 구성하고 실행할 수 있도록합니다. 사용자 정의 AI 에이전트의 이름을 지정하고 목표를 정의하십시오. AI 에이전트는 작업을 생성하고 실행하여 지정된 목표를 달성하려고합니다. 그런 다음 결과를 평가합니다 🚀\",\n\t\"LONG_TERM_MEMORY\": \"장기 기억 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"이 플랫폼은 현재 베타 버전입니다. 현재 다음에 집중하고 있습니다:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"AgentGPT, 로드맵, FAQ 등에 대해 자세히 알아보려면\",\n\t\"WEB_BROWSING\": \"웹 탐색 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"AgentGPT에 오신 것을 환영합니다\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/indexPage.json",
    "content": "{\n  \"BETA\": \"베타\",\n  \"HEADING_DESCRIPTION\": \"브라우저에서 자율적 인 AI 에이전트를 구성, 구성 및 설치합니다.\",\n  \"AGENT_NAME\": \"이름\",\n  \"LABEL_AGENT_GOAL\": \"목표\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"세상을 더 나은 곳으로 만들기\",\n  \"BUTTON_DEPLOY_AGENT\": \"에이전트 실행\",\n  \"BUTTON_STOP_AGENT\": \"에이전트 중지\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/languages.json",
    "content": "{\n    \"ENGLISH\": \"영어\",\n    \"FRENCH\": \"프랑스어\",\n    \"SPANISH\": \"스페인어\",\n    \"GERMAN\": \"독일어\",\n    \"JAPANESE\": \"일본어\",\n    \"KOREAN\": \"한국어\",\n    \"CHINESE\": \"중국어\",\n    \"PORTUGEES\": \"포르투갈어\",\n    \"ITALIAN\": \"이탈리아어\",\n    \"DUTCH\": \"네덜란드어\",\n    \"POLSKI\": \"폴란드어\",\n    \"HUNGARIAN\": \"헝가리어\",\n    \"ROMANIAN\": \"루마니아어\",\n    \"SLOVAK\": \"슬로바키아어\"\n}\n"
  },
  {
    "path": "next/public/locales/ko/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"고급 설정\",\n\t\"API_KEY\": \"API 키\",\n\t\"AUTOMATIC_MODE\": \"자동 모드\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(기본값) 에이전트는 모든 작업을 자동으로 실행합니다.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"각 API 호출에서 사용되는 토큰의 최대 수를 제어합니다 (높은 값은 자세한 응답을 제공하지만 더 비용이 듭니다).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"에이전트가 실행하는 루프의 최대 수를 제어합니다 (높은 값은 더 많은 API 호출을 의미합니다).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"당신만의 OpenAI API 키를 가져오세요\",\n\t\"HERE\": \"여기\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"여기에서 OpenAI API 키를 추가할 수 있습니다. 이것은 사용자의 OpenAI 토큰을 사용하고 이를 위해 비용을 지불해야 하지만 ChatGPT에 대한 더 큰 액세스 권한을 얻을 수 있습니다. 또한 OpenAI에서 제공하는 어떤 모델도 선택할 수 있습니다.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"높은 값은 출력을 더 무작위하게 만듭니다. 반면, 낮은 값은 출력을 집중하고 명확하게 만듭니다.\",\n\t\"INFO_TO_USE_GPT4\": \"GPT-4 모델을 사용하려면 API 키를 입력해야 합니다. 여기서\",\n\t\"INVALID_OPENAI_API_KEY\": \"잘못된 API 키입니다!\",\n\t\"LABEL_MODE\": \"모드\",\n\t\"LABEL_MODEL\": \"모델\",\n\t\"LANG\": \"언어\",\n\t\"LINK\": \"API 키 요청\",\n\t\"LOOP\": \"루프\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"참고: 계정에 신용카드를 연결해야 합니다\",\n\t\"NOTE_API_KEY_USAGE\": \"이 키는 현재 브라우저 세션에서만 사용됩니다.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"참고: API 키를 얻으려면 OpenAI 계정을 등록해야 합니다. 다음 링크에서 등록할 수 있습니다:\",\n\t\"PAUSE\": \"일시 정지\",\n\t\"PAUSE_MODE\": \"일시 정지 모드\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"에이전트는 각 작업 집합 후에 일시 정지됩니다.\",\n\t\"PENAI_API_KEY\": \"잘못된 OpenAI API 키\",\n\t\"PLAY\": \"재생\",\n\t\"SETTINGS_DIALOG_HEADER\": \"설정 ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(ChatGPT Plus 구독은 작동하지 않습니다)\",\n\t\"TEMPERATURE\": \"온도\",\n\t\"TOKENS\": \"토큰\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Baigiama:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Remkite projektą per GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Tekstas nukopijuotas į iškarpinę\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Nepavyko nukopijuoti teksto į iškarpinę\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Sukurkite agentą pridėdami pavadinimą ir tikslą, tada paspauskite mygtuką \\\"Paleisti agentą!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Įgyvendinama nauja tikslas:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Mesame neįprastai didelį eismą, tikimasi delsų ir klaidų, jei nenaudojate savo API rakto 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Padėkite plėtoti AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Nėra daugiau sub-ūduočių:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Atnaujinkite puslapį arba paleiskite agentą iš naujo rankiniu būdu, jei tai užtrunka daugiau nei 30 sekundžių)\",\n\t\"SUPPORT_NOW\": \"Palaikyti dabar 🚀\",\n\t\"TASK_ADDED\": \"Užduotis pridėta:\",\n\t\"THINKING\": \"Mąstymas...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Galite pateikti savo OpenAI API raktą skirtai padidinti limitus nustatymuose!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Sukurkite agentą pridėdami pavadinimą / tikslą ir paspausdami dislokuoti!\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Sukurkite agentą pridėdami vardą / tikslą ir paspausdami dislokuoti! \\nIšbandykite žemiau pateiktus pavyzdžius!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Pridedama užduotis\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Agento GPT dokumentacija\",\n\t\"CLOSE\": \"Uždaryti\",\n\t\"CONTINUE\": \"Tęsti\",\n\t\"COPIED_TO_CLIPBOARD\": \"Nukopijuota į mainų sritį! 🚀\",\n\t\"COPY\": \"Kopijuoti\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Sukurkite agentą pridėdami pavadinimą / tikslą ir paspausdami dislokuoti!\",\n\t\"CURRENT_TASKS\": \"Dabartinės užduotys\",\n\t\"EXECUTING\": \"Vykdymas\",\n\t\"EXPORT\": \"Eksportuoti\",\n\t\"IMAGE\": \"Vaizdas\",\n\t\"LOOP\": \"Kilpa\",\n\t\"PAUSED\": \"Pristabdyta\",\n\t\"RESET\": \"Nustatyti iš naujo\",\n\t\"RUNNING\": \"Bėgimas\",\n\t\"SAVE\": \"Sutaupyti\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Norėdami gauti daugiau informacijos apie AgentGPT, jos planą ir kt., apsilankykite šioje nuorodoje\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Sukurkite išsamią Nike įmonės ataskaitą\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Jei susiduriate su problemomis, apsilankykite mūsų svetainėje\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Suplanuokite išsamią kelionę į Havajus.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"TyrimasGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"Interneto paieška\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Paskyra\",\n\t\"HELP_BUTTON\": \"Pagalba\",\n\t\"MY_AGENTS\": \"Mano agentai\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Pirma turite sukurti ir įrašyti savo pirmąjį agentą, prieš atsiras ką nors čia!\",\n\t\"SETTINGS_BUTTON\": \"Nustatymai\",\n\t\"SIGN_IN\": \"Prisijungti\",\n\t\"SIGN_IN_NOTICE\": \"Prisijunkite, kad galėtumėte įrašyti savo agentus ir tvarkyti savo paskyrą!\",\n\t\"SIGN_OUT\": \"Atsijungti\",\n\t\"SUPPORT_BUTTON\": \"Palaikymas\",\n\t\"USER_IMAGE\": \"Naudotojo paveikslėlis\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"KLAIDA jungiantis prie OpenAI API. Patikrinkite API raktą arba bandykite vėliau.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"KLAIDA pridedant papildomus uždavinius. Mūsų modelis galbūt negali apdoroti atsakymo ir dėl to kilo problema. Tęsiame...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Pasiektas maksimalus užklausų skaičius! Prašome sulėtinti...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Šis agentas pasiekė maksimalų leistinų ciklų skaičių. Kad išvengtumėte pinigų išlaidų, šis agentas dabar bus sustabdytas... Maksimalų leistinų agento ciklų skaičių galima konfigūruoti nustatymuose.\",\n  \"DEMO_LOOPS_REACHED\": \"Atsiprašome, tačiau, kadangi tai demonstracinė programa, negalime leisti agentams būti vykdomi ilgiau nei tam tikrą laiką. Pastaba: jei norite vykdyti ilgesnes programas, įveskite savo API raktą Nustatymuose. Sustabdymas...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agentas sustabdytas rankiniu būdu.\",\n  \"ALL_TASKS_COMPLETETD\": \"Visi uždaviniai baigti. Sustabdymas...\",\n  \"ERROR_API_KEY_QUOTA\": \"KLAIDA naudojant OpenAI API raktą. Viršijote savo dabartinę kvotą. Patikrinkite savo sąskaitos informaciją.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"KLAIDA: Jūsų OpenAI API raktas neturi prieigos prie GPT-4. Pirmiausia turite užsiregistruoti OpenAI eilėje. (Tai skiriasi nuo ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"KLAIDA gaunant pradinius uždavinius. Bandykite dar kartą, aiškiau suformuluokite agento tikslą arba pakeiskite jį taip, kad jis atitiktų mūsų modelio reikalavimus. Sustabdymas...\",\n  \"INVALID_OPENAI_API_KEY\": \"KLAIDA neteisingas OpenAI API raktas\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Agento GPT dokumentacija\",\n\t\"FOLLOW_THE_JOURNEY\": \"Sekite mus šiais keliais:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Sąveika su svetainėmis ir žmonėmis 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"AgentGPT leidžia jums konfigūruoti ir paleisti savarankiškus MI agentus per naršyklę. Pavadinkite savo asmeninį MI agentą ir nustatykite tikslą. MI agentas stengsis pasiekti nustatytą tikslą, kurdamas ir vykdamas užduotis, o tada vertindamas jų rezultatus 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Ilguoju laikotarpiu atmintis 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Ši platforma dabar yra beta versijoje, mes dabar dirbame su:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Norėdami sužinoti daugiau apie AgentGPT, jo planą, DUK ir kt., apsilankykite\",\n\t\"WEB_BROWSING\": \"Interneto naršymas 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Sveiki atvykę į AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Compila, configura e installa agenti AI autonomi nel tuo browser.\",\n  \"AGENT_NAME\": \"Nome\",\n  \"LABEL_AGENT_GOAL\": \"Obiettivo\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Rendere il mondo un posto migliore\",\n  \"BUTTON_DEPLOY_AGENT\": \"Esegui agente\",\n  \"BUTTON_STOP_AGENT\": \"Ferma agente\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/languages.json",
    "content": "{\n    \"ENGLISH\": \"Anglų\",\n    \"FRENCH\": \"Prancūzų\",\n    \"SPANISH\": \"Ispanų\",\n    \"GERMAN\": \"Vokiečių\",\n    \"JAPANESE\": \"Japonų\",\n    \"KOREAN\": \"Korėjiečių\",\n    \"CHINESE\": \"Kinų\",\n    \"PORTUGEES\": \"Portugalų\",\n    \"ITALIAN\": \"Italų\",\n    \"DUTCH\": \"Olandų\",\n    \"POLSKI\": \"Lenkų\",\n    \"HUNGARIAN\": \"Vengrų\",\n    \"ROMANIAN\": \"Rumunų\",\n    \"SLOVAK\": \"Slovakų\"\n}\n"
  },
  {
    "path": "next/public/locales/lt/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Išplėstiniai nustatymai\",\n\t\"API_KEY\": \"API raktas\",\n\t\"AUTOMATIC_MODE\": \"Automatinis režimas\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Numatytasis): Agentas automatiškai vykdo kiekvieną užduotį.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Valdo maksimalų žetonų skaičių, naudojamų kiekviename API užklausime (didelis skaičius reiškia išsamesnius atsakymus, bet didesnes išlaidas).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Valdo maksimalų leidžiamų ciklų skaičių (didelis skaičius reiškia daugiau API užklausų).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Gaukite savo OpenAI API raktą\",\n\t\"HERE\": \"čia\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Čia galite pridėti savo OpenAI API raktą. Tai reiškia, kad turėsite sumokėti už savo OpenAI žetonus, tačiau gausite didesnę prieigą prie ChatGPT! Be to, galite pasirinkti bet kurią OpenAI modelį.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Didesnės reikšmės padidina atsakymų atsitiktinumą, o mažesnės reikšmės padeda sukoncentruoti atsakymą ir jį nukreipti.\",\n\t\"INFO_TO_USE_GPT4\": \"Norint naudoti GPT-4 modelį, taip pat reikalingas API raktas. Jį galite gauti\",\n\t\"INVALID_OPENAI_API_KEY\": \"Nevalidi API raktas!\",\n\t\"LABEL_MODE\": \"Režimas\",\n\t\"LABEL_MODEL\": \"Modelis\",\n\t\"LANG\": \"Kalba\",\n\t\"LINK\": \"API rakto užsakymas\",\n\t\"LOOP\": \"Ciklas\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Pastaba: privalote prijungti kreditinę kortelę prie savo paskyros\",\n\t\"NOTE_API_KEY_USAGE\": \"Šis raktas naudojamas tik dabartinėje naršymo sesijoje.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"PRIMINIMAS: Norint gauti API raktą, turite užsiregistruoti OpenAI paskyroje, kurią galite sukurti šiuo nuorodos adresu:\",\n\t\"PAUSE\": \"Pauzė\",\n\t\"PAUSE_MODE\": \"Pauzės režimas\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Agentas sustabdo veiksmus po kiekvienos užduočių grupės.\",\n\t\"PENAI_API_KEY\": \"Neteisingas OpenAI API raktas\",\n\t\"PLAY\": \"Groti\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Nustatymai ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(ChatGPT Plus prenumerata neveiks)\",\n\t\"TEMPERATURE\": \"Temperatūra\",\n\t\"TOKENS\": \"Žetoniai\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Voltooien:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Overweeg om het project te sponsoren via GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Tekst gekopieerd naar klembord\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Tekst kon niet worden gekopieerd naar het klembord\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Maak een agent aan door de naam en het doel toe te voegen en klik op de knop \\\"Agent starten!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Starten van een nieuw doel:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 We ervaren uitzonderlijk verkeer, verwachte vertragingen en fouten als u niet uw eigen API-sleutel gebruikt 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Ondersteun de ontwikkeling van AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Er zijn geen verdere subtaken voor dit item:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Vernieuw de pagina of start de agent handmatig opnieuw op als dit langer dan 30 seconden duurt)\",\n\t\"SUPPORT_NOW\": \"Ondersteun nu 🚀\",\n\t\"TASK_ADDED\": \"Taak toegevoegd:\",\n\t\"THINKING\": \"Denken...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 U kunt uw eigen OpenAI API-sleutel opgeven op het tabblad Instellingen voor verhoogde limieten!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Maak een agent aan door een naam/doel toe te voegen en op Implementeren te drukken!\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Maak een agent aan door een naam/doel toe te voegen en op Implementeren te drukken! \\nProbeer onze voorbeelden hieronder!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 U kunt uw agent een keer klikken en klikken op \\\"Spustiť agent!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Schakel het apparaat uit en klik op \\\"Verwijder het!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Als u een bericht plaatst, drukt u op de knop \\\"Verzenden!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Taak toevoegen\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentatie van AgentGPT\",\n\t\"CLOSE\": \"Sluiten\",\n\t\"CONTINUE\": \"Doorgaan\",\n\t\"COPIED_TO_CLIPBOARD\": \"Gekopieerd naar het klembord! 🚀\",\n\t\"COPY\": \"Kopiëren\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Maak een agent aan door een naam/doel toe te voegen en op Implementeren te drukken!\",\n\t\"CURRENT_TASKS\": \"Huidige taken\",\n\t\"EXECUTING\": \"Uitvoeren\",\n\t\"EXPORT\": \"Exporteren\",\n\t\"IMAGE\": \"Afbeelding\",\n\t\"LOOP\": \"Lus\",\n\t\"PAUSED\": \"Gepauzeerd\",\n\t\"RESET\": \"Resetten\",\n\t\"RUNNING\": \"Bezig\",\n\t\"SAVE\": \"Opslaan\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Bezoek de volgende link voor meer informatie over AgentGPT, de Roadmap, enz\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Maak een uitgebreid rapport van het bedrijf Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Als u problemen ondervindt, ga dan naar onze\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Plan een gedetailleerde reis naar Hawaï.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"OnderzoekGPT 📜\",\n\t\"travelgpt\": \"ReisGPT 🌴\",\n\t\"web-search\": \"Zoeken op internet\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Account\",\n\t\"HELP_BUTTON\": \"Help\",\n\t\"MY_AGENTS\": \"Mijn agenten\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"U moet eerst uw eerste agent maken en opslaan voordat er hier iets verschijnt!\",\n\t\"SETTINGS_BUTTON\": \"Instellingen\",\n\t\"SIGN_IN\": \"Inloggen\",\n\t\"SIGN_IN_NOTICE\": \"Meld u aan om uw agenten op te slaan en uw account te beheren!\",\n\t\"SIGN_OUT\": \"Uitloggen\",\n\t\"SUPPORT_BUTTON\": \"Steun\",\n\t\"USER_IMAGE\": \"Gebruikersafbeelding\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"FOUT bij het openen van de OpenAI API-sleutel. Controleer de API-sleutel of probeer het later opnieuw.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"FOUT bij het toevoegen van extra taken. Het kan zijn dat ons model het antwoord niet aankan en dit heeft veroorzaakt. Ga verder...\",\n  \"RATE_LIMIT_EXCEEDED\": \"U heeft het maximale aantal verzoeken bereikt! Vertraag alsjeblieft...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Deze agent heeft het maximum aantal uitvoerbare rondes bereikt. Om uw portemonnee te sparen, stopt deze agent nu... Het maximum aantal uitvoerbare rondes van de agent kan worden geconfigureerd in de instellingen.\",\n  \"DEMO_LOOPS_REACHED\": \"Sorry, maar omdat dit een demo-applicatie is, kunnen we onze agenten niet te lang laten draaien. Opmerking: als u langere runs wilt, geef dan uw eigen API-sleutel op in de instellingen. Stoppen...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"De agent is handmatig gestopt.\",\n  \"ALL_TASKS_COMPLETETD\": \"Alle taken zijn voltooid. Stoppen...\",\n  \"ERROR_API_KEY_QUOTA\": \"FOUT bij het gebruik van de OpenAI API-sleutel. U heeft uw huidige quota overschreden, controleer uw factureringsgegevens.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"FOUT: uw OpenAI API-sleutel heeft geen toegang tot GPT-4. U moet zich eerst aanmelden voor de OpenAI-wachtlijst. (Dit is anders dan ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"FOUT bij het ophalen van de initiële taken. Probeer het opnieuw, formuleer de doelstellingen van de agent duidelijker of pas deze aan zodat deze geschikt is voor ons model. Stoppen...\",\n  \"INVALID_OPENAI_API_KEY\": \"FOUT ongeldige OpenAI API-sleutel\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentatie van AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Volg ons op onze reis:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interactie met websites en mensen 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"Stelt u in staat om uw eigen zelfstandige AI-agenten te configureren en uit te voeren via uw browser. Noem uw aangepaste AI-agent en bepaal het doel. De AI-agent probeert het gespecificeerde doel te bereiken door taken te creëren, uit te voeren en de resultaten ervan te evalueren 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Lange termijngeheugen 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Dit platform is momenteel in bètafase, we werken momenteel aan de volgende functies:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Ga voor meer informatie over AgentGPT, de roadmap, veelgestelde vragen, enz\",\n\t\"WEB_BROWSING\": \"Webbrowsen 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Welkom bij AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/indexPage.json",
    "content": "{\n  \"BETA\": \"Bèta\",\n  \"HEADING_DESCRIPTION\": \"Compileer, configureer en installeer autonome AI-agenten in uw browser.\",\n  \"AGENT_NAME\": \"Naam\",\n  \"LABEL_AGENT_GOAL\": \"Doel\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Maak de wereld een betere plek\",\n  \"BUTTON_DEPLOY_AGENT\": \"Agent implementeren\",\n  \"BUTTON_STOP_AGENT\": \"Agent stoppen\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/languages.json",
    "content": "{\n    \"ENGLISH\": \"Engels\",\n    \"FRENCH\": \"Frans\",\n    \"SPANISH\": \"Spaans\",\n    \"GERMAN\": \"Duits\",\n    \"JAPANESE\": \"Japans\",\n    \"KOREAN\": \"Koreaans\",\n    \"CHINESE\": \"Chinees\",\n    \"PORTUGEES\": \"Portugees\",\n    \"ITALIAN\": \"Italiaans\",\n    \"DUTCH\": \"Nederlands\",\n    \"POLSKI\": \"Pools\",\n    \"HUNGARIAN\": \"Hongaars\",\n    \"ROMANIAN\": \"Roemeens\",\n    \"SLOVAK\": \"Slowaaks\"\n}\n"
  },
  {
    "path": "next/public/locales/nl/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Geavanceerde instellingen\",\n\t\"API_KEY\": \"API-sleutel\",\n\t\"AUTOMATIC_MODE\": \"Automatische modus\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Standaard): Agent voert automatisch elke taak uit.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Regelt het maximale aantal tokens dat in elke API-oproep wordt gebruikt (een hogere waarde resulteert in gedetailleerdere antwoorden, maar is duurder).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Regelt het maximale aantal lussen dat de agent kan uitvoeren (een hogere waarde resulteert in meer API-oproepen).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Vraag je eigen OpenAI API-sleutel aan\",\n\t\"HERE\": \"hier\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Hier kunt u uw OpenAI API-sleutel toevoegen. Dit betekent dat u moet betalen voor uw eigen OpenAI-tokengebruik, maar u krijgt meer toegang tot ChatGPT! Bovendien kunt u elk model kiezen dat door OpenAI wordt aangeboden.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Hogere waarden maken de output meer willekeurig, terwijl lagere waarden het gerichter en bepaalder maken.\",\n\t\"INFO_TO_USE_GPT4\": \"Om het GPT-4-model te gebruiken, moet u ook de API-sleutel opgeven. Je kunt het\",\n\t\"INVALID_OPENAI_API_KEY\": \"Ongeldige API-sleutel!\",\n\t\"LABEL_MODE\": \"Modus\",\n\t\"LABEL_MODEL\": \"Model\",\n\t\"LANG\": \"Taal\",\n\t\"LINK\": \"API-sleutel aanvragen\",\n\t\"LOOP\": \"Lus\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Opmerking: U moet een creditcard koppelen aan uw account\",\n\t\"NOTE_API_KEY_USAGE\": \"Deze sleutel wordt alleen gebruikt tijdens de huidige browsersessie.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"OPMERKING: Om een ​​API-sleutel te krijgen, moet u een OpenAI-account registreren op de volgende link:\",\n\t\"PAUSE\": \"Pauzeren\",\n\t\"PAUSE_MODE\": \"Pauze modus\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Agent pauzeert na elke set van taak(taken)\",\n\t\"PENAI_API_KEY\": \"Ongeldige OpenAI API-sleutel\",\n\t\"PLAY\": \"Afspelen\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Instellingen ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(Het ChatGPT Plus-abonnement werkt niet)\",\n\t\"TEMPERATURE\": \"Temperatuur\",\n\t\"TOKENS\": \"Tokens\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Wykonywanie:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Rozważ wsparcie projektu na GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Tekst skopiowany do schowka\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Nie można skopiować tekstu do schowka\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Utwórz agenta, dodając nazwę i cel, a następnie kliknij przycisk \\\"Uruchom agenta!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Nowe cel:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Doświadczamy wyjątkowo dużego ruchu, oczekiwane są opóźnienia i błędy, jeśli nie używasz własnego klucza API 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Wsparcie dla rozwoju AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Brak kolejnych zadań dla tego:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Odśwież stronę lub uruchom agenta ponownie ręcznie, jeśli zajmie to ponad 30 sekund)\",\n\t\"SUPPORT_NOW\": \"Wsparcie teraz 🚀\",\n\t\"TASK_ADDED\": \"Zadanie dodane:\",\n\t\"THINKING\": \"Myślenie...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Możesz podać swój własny klucz API OpenAI w zakładce Ustawienia, aby uzyskać podwyższone limity!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Utwórz agenta, dodając nazwę/cel i naciskając przycisk wdrażania!\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Utwórz agenta, dodając nazwę / cel i naciskając przycisk wdrażania! \\nWypróbuj nasze przykłady poniżej!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理, 添加名称和目标, 然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Dodawanie zadania\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentacja AgentGPT\",\n\t\"CLOSE\": \"Zamknąć\",\n\t\"CONTINUE\": \"Kontynuować\",\n\t\"COPIED_TO_CLIPBOARD\": \"Skopiowane do schowka! 🚀\",\n\t\"COPY\": \"Kopiuj\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Utwórz agenta, dodając nazwę/cel i naciskając przycisk wdrażania!\",\n\t\"CURRENT_TASKS\": \"Bieżące zadania\",\n\t\"EXECUTING\": \"Wykonanie\",\n\t\"EXPORT\": \"Eksport\",\n\t\"IMAGE\": \"Obraz\",\n\t\"LOOP\": \"Pętla\",\n\t\"PAUSED\": \"Wstrzymane\",\n\t\"RESET\": \"Resetowanie\",\n\t\"RUNNING\": \"Działanie\",\n\t\"SAVE\": \"Ratować\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Aby uzyskać więcej informacji na temat AgentGPT, jego harmonogramu itp., odwiedź poniższe łącze\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Stwórz kompleksowy raport firmy Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Jeśli napotkasz problemy, przejdź do naszego\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Zaplanuj szczegółową wycieczkę na Hawaje.\",\n\t\"platformergpt\": \"PlatformówkaGPT 🎮\",\n\t\"researchgpt\": \"BadaniaGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"wyszukiwarka internetowa\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Konto\",\n\t\"HELP_BUTTON\": \"Pomoc\",\n\t\"MY_AGENTS\": \"Moje agenci\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Musisz najpierw stworzyć i zapisać swojego pierwszego agenta, zanim pojawi się tutaj coś!\",\n\t\"SETTINGS_BUTTON\": \"Ustawienia\",\n\t\"SIGN_IN\": \"Zaloguj się\",\n\t\"SIGN_IN_NOTICE\": \"Zaloguj się, aby zapisać swoich agentów i zarządzać swoim kontem!\",\n\t\"SIGN_OUT\": \"Wyloguj się\",\n\t\"SUPPORT_BUTTON\": \"Wsparcie\",\n\t\"USER_IMAGE\": \"Zdjęcie użytkownika\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"BŁĄD podczas łączenia się z kluczem API OpenAI. Proszę sprawdzić klucz API lub spróbować później.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"BŁĄD podczas dodawania dodatkowych zadań. Nasz model może nie obsługiwać odpowiedzi i spowodować to błąd. Kontynuacja...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Przekroczyłeś maksymalną liczbę zapytań! Proszę zwolnić... 😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Ten agent osiągnął maksymalną liczbę możliwych iteracji. Aby zachować swoją kieszeń, ten agent jest teraz wyłączony... Maksymalną liczbę iteracji agenta można skonfigurować w ustawieniach.\",\n  \"DEMO_LOOPS_REACHED\": \"Przepraszamy, ale ponieważ jest to aplikacja demonstracyjna, nie możemy uruchamiać agentów przez zbyt długi czas. Uwaga: jeśli chcesz uruchamiać dłuższe sesje, proszę podać własny klucz API w ustawieniach. Wyłączenie...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agent został ręcznie wyłączony.\",\n  \"ALL_TASKS_COMPLETETD\": \"Wszystkie zadania zostały zakończone. Wyłączanie...\",\n  \"ERROR_API_KEY_QUOTA\": \"BŁĄD podczas korzystania z klucza OpenAI API. Przekroczono bieżący limit, proszę sprawdzić informacje o rozliczeniach.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"BŁĄD: Twój klucz OpenAI API nie ma dostępu do GPT-4. Musisz najpierw zapisać się na listę oczekujących OpenAI. (To różni się od ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"BŁĄD podczas pobierania podstawowych zadań. Spróbuj ponownie, sformułuj cel agenta bardziej jasno lub zmodyfikuj go w taki sposób, aby pasował do naszego modelu. Wyłączanie...\",\n  \"INVALID_OPENAI_API_KEY\": \"BŁĄD nieprawidłowy klucz API OpenAI\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentacja AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Podążaj za nami na naszej drodze:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interakcja z witrynami i ludźmi 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"Umożliwia konfigurację i uruchamianie samodzielnych agentów AI za pomocą przeglądarki. Nazwij swojego spersonalizowanego agenta AI i określ jego cel. Agent AI będzie próbował osiągnąć określony cel, tworząc zadania, wykonując je, a następnie oceniając ich wyniki 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Długotrwała pamięć 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Ta platforma jest obecnie w wersji beta, obecnie pracujemy nad następującymi funkcjami:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Aby dowiedzieć się więcej o programie AgentGPT, jego harmonogramie, często zadawanych pytaniach itp., odwiedź stronę\",\n\t\"WEB_BROWSING\": \"Przeglądanie internetu 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Witaj w AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Twórz, konfiguruj i instaluj autonomiczne agenty AI w Twojej przeglądarce.\",\n  \"AGENT_NAME\": \"Nazwa\",\n  \"LABEL_AGENT_GOAL\": \"Cel\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Uczynić świat lepszym miejscem\",\n  \"BUTTON_DEPLOY_AGENT\": \"Uruchom agenta\",\n  \"BUTTON_STOP_AGENT\": \"Zatrzymaj agenta\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/languages.json",
    "content": "{\n    \"ENGLISH\": \"Angielski\",\n    \"FRENCH\": \"Francuski\",\n    \"SPANISH\": \"Hiszpański\",\n    \"GERMAN\": \"Niemiecki\",\n    \"JAPANESE\": \"Japoński\",\n    \"KOREAN\": \"Koreański\",\n    \"CHINESE\": \"Chiński\",\n    \"PORTUGEES\": \"Portugalski\",\n    \"ITALIAN\": \"Włoski\",\n    \"DUTCH\": \"Holenderski\",\n    \"POLSKI\": \"Polski\",\n    \"HUNGARIAN\": \"Węgierski\",\n    \"ROMANIAN\": \"Rumuński\",\n    \"SLOVAK\": \"Słowacki\"\n}\n"
  },
  {
    "path": "next/public/locales/pl/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Zaawansowane ustawienia\",\n\t\"API_KEY\": \"Klucz API\",\n\t\"AUTOMATIC_MODE\": \"Tryb automatyczny\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Domyślnie): Agenty wykonują zadania automatycznie.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Kontroluje maksymalną liczbę tokenów używanych w każdym wywołaniu API (wyższa wartość daje bardziej szczegółowe odpowiedzi, ale jest droższa).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Kontroluje maksymalną liczbę pętli uruchamianych przez agenta (wyższa wartość oznacza więcej wywołań API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Otrzymaj swój własny klucz API OpenAI\",\n\t\"HERE\": \"tutaj\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Tutaj możesz dodać swój klucz OpenAI API. Oznacza to, że musisz płacić za używanie własnego tokenu OpenAI, ale otrzymujesz większy dostęp do ChatGPT! Ponadto możesz wybrać dowolny model oferowany przez OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Wyższe wartości powodują, że wynik jest bardziej losowy, podczas gdy niższe wartości skupiają go i definiują bardziej.\",\n\t\"INFO_TO_USE_GPT4\": \"Aby użyć modelu GPT-4, musisz podać klucz API. Możesz go uzyskać\",\n\t\"INVALID_OPENAI_API_KEY\": \"Nieprawidłowy klucz API!\",\n\t\"LABEL_MODE\": \"Tryb\",\n\t\"LABEL_MODEL\": \"Model\",\n\t\"LANG\": \"Język\",\n\t\"LINK\": \"Zażądaj klucza API\",\n\t\"LOOP\": \"Pętla\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Uwaga: Musisz podłączyć kartę kredytową do swojego konta\",\n\t\"NOTE_API_KEY_USAGE\": \"Ten klucz jest używany tylko w bieżącej sesji przeglądarki.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"UWAGA: Aby uzyskać klucz API, musisz zarejestrować konto OpenAI, co możesz zrobić pod tym linkiem:\",\n\t\"PAUSE\": \"Pauza\",\n\t\"PAUSE_MODE\": \"Tryb pauzy\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Agent przerywa po każdym zbiorze zadania\",\n\t\"PENAI_API_KEY\": \"Nieprawidłowy klucz API OpenAI\",\n\t\"PLAY\": \"Odtwórz\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Ustawienia ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(Subskrypcja ChatGPT Plus nie będzie działać)\",\n\t\"TEMPERATURE\": \"Temperatura\",\n\t\"TOKENS\": \"Tokeny\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Completando:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Considere apoiar o projeto no GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Texto copiado para a área de transferência\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Não foi possível copiar o texto para a área de transferência\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Crie um agente adicionando nome e objetivo, e clique no botão \\\"Iniciar agente!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Embarcando em um novo objetivo:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Estamos experimentando tráfego excepcionalmente alto, podem ocorrer atrasos e erros se você não estiver usando sua própria chave de API 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Ajude no avanço do AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Não há mais tarefas secundárias para isso:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Atualize a página ou reinicie o agente manualmente se isso levar mais de 30 segundos)\",\n\t\"SUPPORT_NOW\": \"Apoiar agora 🚀\",\n\t\"TASK_ADDED\": \"Tarefa adicionada:\",\n\t\"THINKING\": \"Pensando...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Você pode fornecer sua própria chave de API OpenAI nas configurações para limites mais altos!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Crie um agente adicionando um nome/alvo e pressionando implantar!\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Crie um agente adicionando um nome/objetivo e clique em implantar! \\nExperimente nossos exemplos abaixo!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Adding Task\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentação do AgentGPT\",\n\t\"CLOSE\": \"Fechar\",\n\t\"CONTINUE\": \"Continuar\",\n\t\"COPIED_TO_CLIPBOARD\": \"Copiado para a área de transferência! 🚀\",\n\t\"COPY\": \"Cópia de\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Crie um agente adicionando um nome/objetivo e clique em implantar!\",\n\t\"CURRENT_TASKS\": \"Tarefas Atuais\",\n\t\"EXECUTING\": \"Executando\",\n\t\"EXPORT\": \"Export\",\n\t\"IMAGE\": \"Imagem\",\n\t\"LOOP\": \"Laço\",\n\t\"PAUSED\": \"Pausado\",\n\t\"RESET\": \"Reiniciar\",\n\t\"RUNNING\": \"Em andamento\",\n\t\"SAVE\": \"Salvar\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Para obter mais informações sobre o AgentGPT, seu Roadmap, etc, visite o seguinte link\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Crie um relatório abrangente da empresa Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Se você está enfrentando problemas, por favor, dirija-se ao nosso\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Planeje uma viagem detalhada para o Havaí.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"PesquisaGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"pesquisa na internet\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Conta\",\n\t\"HELP_BUTTON\": \"Ajuda\",\n\t\"MY_AGENTS\": \"Meus agentes\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Você precisa criar e salvar seu primeiro agente antes de qualquer coisa aparecer aqui!\",\n\t\"SETTINGS_BUTTON\": \"Configurações\",\n\t\"SIGN_IN\": \"Entrar\",\n\t\"SIGN_IN_NOTICE\": \"Faça login para salvar seus agentes e gerenciar sua conta!\",\n\t\"SIGN_OUT\": \"Sair\",\n\t\"SUPPORT_BUTTON\": \"Apoiar\",\n\t\"USER_IMAGE\": \"Imagem do usuário\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"Erro ao acessar a chave da API OpenAI durante a conexão. Por favor, verifique a chave da API ou tente novamente mais tarde.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"Erro ao adicionar tarefa(s) adicional(is). Talvez nosso modelo não seja capaz de lidar com a resposta e isso resultou nisso. Continuando...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Você atingiu o limite máximo de consultas! Por favor, diminua a velocidade...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Este agente atingiu o número máximo de ciclos executáveis. Para salvar sua carteira, este agente agora está sendo desligado... O número máximo de ciclos de execução do agente pode ser configurado nas configurações.\",\n  \"DEMO_LOOPS_REACHED\": \"Desculpe, mas como esta é uma aplicação de demonstração, não podemos executar os agentes por muito tempo. Observação: se você quiser execuções mais longas, forneça sua própria chave API nas Configurações. Parando...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agente desligado manualmente.\",\n  \"ALL_TASKS_COMPLETETD\": \"Todas as tarefas foram concluídas. Desligando...\",\n  \"ERROR_API_KEY_QUOTA\": \"Erro ao usar a chave da API OpenAI. Você excedeu sua cota atual, por favor verifique suas informações de faturamento.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"ERRO: Sua chave OpenAI API não tem acesso ao GPT-4. Você precisa se inscrever na lista de espera da OpenAI primeiro. (Isso é diferente do ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"Erro ao recuperar tarefas iniciais. Tente novamente, formule o objetivo do agente de forma mais clara ou modifique-o para que atenda ao nosso modelo. Desligando...\",\n  \"INVALID_OPENAI_API_KEY\": \"ERRO chave de API OpenAI inválida\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentação do AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Siga-nos nas seguintes jornadas:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interagir com sites e pessoas 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"permite que configure e execute agentes de IA autônomos em seu navegador. Dê um nome ao seu agente de IA personalizado e defina seu objetivo. O agente de IA tentará atingir o objetivo especificado, criando tarefas, executando-as e avaliando seus resultados 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Memória de longo prazo 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Esta plataforma está atualmente em versão beta e estamos trabalhando em:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Para saber mais sobre AgentGPT, seu roteiro, FAQ, etc, visite o\",\n\t\"WEB_BROWSING\": \"Navegação na web 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Bem-vindo à AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Crie, configure e instale agentes autônomos de IA em seu navegador.\",\n  \"AGENT_NAME\": \"Nome\",\n  \"LABEL_AGENT_GOAL\": \"Objetivo\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Tornar o mundo um lugar melhor\",\n  \"BUTTON_DEPLOY_AGENT\": \"Executar agente\",\n  \"BUTTON_STOP_AGENT\": \"Parar agente\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/languages.json",
    "content": "{\n    \"ENGLISH\": \"Inglês\",\n    \"FRENCH\": \"Francês\",\n    \"SPANISH\": \"Espanhol\",\n    \"GERMAN\": \"Alemão\",\n    \"JAPANESE\": \"Japonês\",\n    \"KOREAN\": \"Coreano\",\n    \"CHINESE\": \"Chinês\",\n    \"PORTUGEES\": \"Português\",\n    \"ITALIAN\": \"Italiano\",\n    \"DUTCH\": \"Holandês\",\n    \"POLSKI\": \"Polonês\",\n    \"HUNGARIAN\": \"Húngaro\",\n    \"ROMANIAN\": \"Romeno\",\n    \"SLOVAK\": \"Eslovaco\"\n}\n"
  },
  {
    "path": "next/public/locales/pt/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Configurações avançadas\",\n\t\"API_KEY\": \"Chave de API\",\n\t\"AUTOMATIC_MODE\": \"Modo automático\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Padrão): O agente executa automaticamente todas as tarefas.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Controla o número máximo de tokens usados em cada chamada de API (valores mais altos resultam em respostas mais detalhadas, mas também mais caras).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Controla o número máximo de loops executados pelo agente (valores mais altos resultam em mais chamadas de API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Obtenha sua própria chave de API da OpenAI\",\n\t\"HERE\": \"aqui\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Aqui você pode adicionar sua chave de API da OpenAI. Isso significa que você terá que pagar pelo uso de seu próprio token da OpenAI, mas terá acesso mais amplo ao ChatGPT! Além disso, você pode escolher qualquer modelo oferecido pela OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Valores mais altos tornam a saída mais aleatória, enquanto valores mais baixos a tornam mais focada e definida.\",\n\t\"INFO_TO_USE_GPT4\": \"Para usar o modelo GPT-4, é necessário fornecer a chave de API. Você pode obtê-la\",\n\t\"INVALID_OPENAI_API_KEY\": \"Chave de API inválida!\",\n\t\"LABEL_MODE\": \"Modo\",\n\t\"LABEL_MODEL\": \"Modelo\",\n\t\"LANG\": \"Idioma\",\n\t\"LINK\": \"Solicitar chave de API\",\n\t\"LOOP\": \"Laço\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Nota: Você deve conectar um cartão de crédito à sua conta\",\n\t\"NOTE_API_KEY_USAGE\": \"Esta chave só será usada nesta sessão do navegador.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"OBSERVAÇÃO: Para obter uma chave de API, você precisa se registrar em uma conta da OpenAI, o que pode ser feito no seguinte link:\",\n\t\"PAUSE\": \"Pausar\",\n\t\"PAUSE_MODE\": \"Modo de pausa\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"O agente pausa após cada conjunto de tarefa(s)\",\n\t\"PENAI_API_KEY\": \"Chave de API OpenAI inválida\",\n\t\"PLAY\": \"Reproduzir\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Configurações ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(A assinatura do ChatGPT Plus não funcionará)\",\n\t\"TEMPERATURE\": \"Temperatura\",\n\t\"TOKENS\": \"Tokens\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Finalizare:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Luați în considerare sponsorizarea proiectului pe GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Text copiat în clipboard\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Nu se poate copia textul în clipboard\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Creați un agent prin adăugarea numelui și obiectivului, apoi faceți clic pe butonul \\\"Pornire agent!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Începerea unui nou obiectiv:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Experimentăm un trafic excepțional de mare, se așteaptă întârzieri și erori dacă nu utilizați propriul cheie API 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Ajutați la dezvoltarea AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Nu mai sunt alte sub-sarcini pentru aceasta:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Reîncărcați pagina sau porniți manual agentul dacă durează mai mult de 30 de secunde)\",\n\t\"SUPPORT_NOW\": \"Susținere acum 🚀\",\n\t\"TASK_ADDED\": \"Sarcină adăugată:\",\n\t\"THINKING\": \"Gândire...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Puteți furniza propriul cheie API OpenAI în fila Setări pentru limite mai mari!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Creați un agent adăugând un nume/țintă și apăsând deploy!\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Creați un agent adăugând un nume/obiectiv și apăsând deploy! \\nÎncercați exemplele noastre de mai jos!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa a clicknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Adăugarea sarcinii\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentația AgentGPT\",\n\t\"CLOSE\": \"Închidere\",\n\t\"CONTINUE\": \"Continua\",\n\t\"COPIED_TO_CLIPBOARD\": \"Copiat în clipboard! 🚀\",\n\t\"COPY\": \"Copiere\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Creați un agent adăugând un nume/obiectiv și apăsând deploy!\",\n\t\"CURRENT_TASKS\": \"Sarcinile curente\",\n\t\"EXECUTING\": \"Executarea\",\n\t\"EXPORT\": \"Export\",\n\t\"IMAGE\": \"Imagine\",\n\t\"LOOP\": \"Bucle\",\n\t\"PAUSED\": \"Întrerupt\",\n\t\"RESET\": \"Resetare\",\n\t\"RUNNING\": \"În curs\",\n\t\"SAVE\": \"Salvare\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Pentru a obține mai multe informații despre AgentGPT, foaia sa de parcurs etc., accesați următorul link\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Creați un raport cuprinzător al companiei Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Dacă vă confruntați cu probleme, vă rugăm să mergeți la nostru\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Planificați o călătorie detaliată în Hawaii.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"ResearchGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"cautare pe internet\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Cont\",\n\t\"HELP_BUTTON\": \"Ajutor\",\n\t\"MY_AGENTS\": \"Agenta mea\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Trebuie să creați și să salvați primul agent înainte ca ceva să apară aici!\",\n\t\"SETTINGS_BUTTON\": \"Setări\",\n\t\"SIGN_IN\": \"Conectare\",\n\t\"SIGN_IN_NOTICE\": \"Conectați-vă pentru a salva agenții dvs. și a gestiona contul!\",\n\t\"SIGN_OUT\": \"Deconectare\",\n\t\"SUPPORT_BUTTON\": \"A sustine\",\n\t\"USER_IMAGE\": \"Imagine utilizator\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"EROARE la conectarea cu cheia API OpenAI. Vă rugăm să verificați cheia API sau încercați mai târziu.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"EROARE la adăugarea task-urilor suplimentare. Este posibil ca modelul nostru să nu poată gestiona răspunsul și să genereze această eroare. Continuare...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Ați atins limita maximă de interogări! Vă rugăm să încetiniți... 😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Acest agent a atins numărul maxim de iterații posibile. Pentru a vă economisi banii, acest agent va fi oprit acum... Numărul maxim de iterații ale agentului poate fi configurat în setări.\",\n  \"DEMO_LOOPS_REACHED\": \"Ne pare rău, dar deoarece aceasta este o aplicație demonstrativă, nu putem rula agenții prea mult timp. Notă: dacă doriți să rulați mai mult timp, vă rugăm să furnizați o cheie API proprie în Setări. Oprim...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agentul a fost oprit manual.\",\n  \"ALL_TASKS_COMPLETETD\": \"Toate task-urile au fost finalizate. Oprim...\",\n  \"ERROR_API_KEY_QUOTA\": \"EROARE la utilizarea cheii API OpenAI. Ați depășit cota curentă, vă rugăm să verificați informațiile de facturare.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"EROARE: Cheia API OpenAI nu are acces la GPT-4. Trebuie să vă înscrieți mai întâi în lista de așteptare OpenAI. (Acest lucru diferă de ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"EROARE la recuperarea task-urilor inițiale. Încercați din nou, formulați obiectivul agentului mai clar sau modificați-l astfel încât să se potrivească modelului nostru. Oprim...\",\n  \"INVALID_OPENAI_API_KEY\": \"EROARE cheie API OpenAI nevalidă\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Documentația AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Urmăriți călătoria noastră:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interacțiune cu site-uri și persoane 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"vă permite să configurați și să rulați agenți de IA autonomi în browser-ul dvs. Dați un nume agenților de IA personalizați și definiți obiectivul lor. Agenții de IA vor încerca să atingă obiectivul specificat, creând sarcini, executându-le și evaluând rezultatele lor 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Memorie pe termen lung 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Această platformă este în prezent în versiune beta și lucrăm la:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Pentru a afla mai multe despre AgentGPT, foaia de parcurs, Întrebări frecvente etc., vizitați\",\n\t\"WEB_BROWSING\": \"Navigare web 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Bine ați venit la AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta\",\n  \"HEADING_DESCRIPTION\": \"Compilează, configurează și instalează agenți autonomi de IA în browser-ul tău.\",\n  \"AGENT_NAME\": \"Nume\",\n  \"LABEL_AGENT_GOAL\": \"Scop\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Să facă lumea un loc mai bun\",\n  \"BUTTON_DEPLOY_AGENT\": \"Execută agentul\",\n  \"BUTTON_STOP_AGENT\": \"Oprește agentul\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/languages.json",
    "content": "{\n    \"ENGLISH\": \"Engleză\",\n    \"FRENCH\": \"Franceză\",\n    \"SPANISH\": \"Spaniolă\",\n    \"GERMAN\": \"Germană\",\n    \"JAPANESE\": \"Japoneză\",\n    \"KOREAN\": \"Coreeană\",\n    \"CHINESE\": \"Chineză\",\n    \"PORTUGEES\": \"Portugheză\",\n    \"ITALIAN\": \"Italiană\",\n    \"DUTCH\": \"Olandeză\",\n    \"POLSKI\": \"Poloneză\",\n    \"HUNGARIAN\": \"Maghiară\",\n    \"ROMANIAN\": \"Română\",\n    \"SLOVAK\": \"Slovacă\"\n}\n"
  },
  {
    "path": "next/public/locales/ro/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Setări avansate\",\n\t\"API_KEY\": \"Cheie API\",\n\t\"AUTOMATIC_MODE\": \"Mod automat\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Implicit): Agentul execută automat fiecare sarcină.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Controlează numărul maxim de token-uri folosite în fiecare apel API (o valoare mai mare va duce la răspunsuri mai detaliate, dar mai costisitoare).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Controlează numărul maxim de bucle executate de agent (o valoare mai mare va duce la mai multe apeluri API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Obțineți propria cheie API OpenAI\",\n\t\"HERE\": \"aici\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Aici puteți adăuga cheia dvs. API OpenAI. Aceasta înseamnă că va trebui să plătiți pentru utilizarea propriului dvs. token OpenAI, dar veți avea un acces mai mare la ChatGPT! De asemenea, puteți selecta orice model oferit de OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Valori mai mari fac ieșirea mai aleatorie, în timp ce valori mai mici o fac mai focalizată și mai precisă.\",\n\t\"INFO_TO_USE_GPT4\": \"Pentru a utiliza modelul GPT-4, trebuie să furnizați cheia API. O puteți obține\",\n\t\"INVALID_OPENAI_API_KEY\": \"Cheie API nevalidă!\",\n\t\"LABEL_MODE\": \"Mod\",\n\t\"LABEL_MODEL\": \"Model\",\n\t\"LANG\": \"Limbă\",\n\t\"LINK\": \"Solicitare cheie API\",\n\t\"LOOP\": \"Bucle\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Notă: Trebuie să conectați un card de credit la contul dvs\",\n\t\"NOTE_API_KEY_USAGE\": \"Această cheie este valabilă doar pentru sesiunea curentă a browser-ului.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"NOTĂ: Pentru a obține o cheie API, trebuie să vă înregistrați pentru un cont OpenAI la următorul link:\",\n\t\"PAUSE\": \"Pauză\",\n\t\"PAUSE_MODE\": \"Mod pauză\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Agentul se oprește după fiecare set de sarcină(i)\",\n\t\"PENAI_API_KEY\": \"Cheie API OpenAI nevalidă\",\n\t\"PLAY\": \"Redare\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Setări ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(Abonamentul ChatGPT Plus nu va funcționa)\",\n\t\"TEMPERATURE\": \"Temperatură\",\n\t\"TOKENS\": \"Token-uri\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Завершение:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Поддержите проект на GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Текст скопирован в буфер обмена\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Не удалось скопировать текст в буфер обмена\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Новая цель:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Мы наблюдаем исключительно высокий трафик, ожидайте задержек и ошибок, если не используете свой собственный API-ключ 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Поддержите развитие AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Нет больше подзадач для этого:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Обновите страницу или запустите агента заново вручную, если это займет более 30 секунд)\",\n\t\"SUPPORT_NOW\": \"Поддержать сейчас 🚀\",\n\t\"TASK_ADDED\": \"Задача добавлена:\",\n\t\"THINKING\": \"Думаю...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Вы можете предоставить свой ключ OpenAI API в разделе настроек для повышения лимитов!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Создайте агента, добавив имя/цель и нажав «Развернуть»!\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Создайте агента, добавив имя/цель и нажав «Развернуть»! \\nПопробуйте наши примеры ниже!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Вытворите агента, придав ему имя и кликните на тлачидло \\\"Спусти агента!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 настроить агента, выбрать имя и цель, затем нажать кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Создайте агента, отправив его туда, а затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Добавление задачи\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Документация AgentGPT\",\n\t\"CLOSE\": \"Закрыть\",\n\t\"CONTINUE\": \"Продолжать\",\n\t\"COPIED_TO_CLIPBOARD\": \"Скопировано в буфер обмена! 🚀\",\n\t\"COPY\": \"Копировать\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Создайте агента, добавив имя/цель и нажав «Развернуть»!\",\n\t\"CURRENT_TASKS\": \"Текущие задачи\",\n\t\"EXECUTING\": \"выполнение\",\n\t\"EXPORT\": \"Экспортировать\",\n\t\"IMAGE\": \"Изображение\",\n\t\"LOOP\": \"Петля\",\n\t\"PAUSED\": \"Приостановлено\",\n\t\"RESET\": \"Сбросить\",\n\t\"RUNNING\": \"В ходе выполнения\",\n\t\"SAVE\": \"Сохранить\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Чтобы получить дополнительную информацию об AgentGPT, его дорожной карте и т. д., перейдите по следующей ссылке.\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Создать комплексный отчет о компании Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Если вы столкнулись с проблемами, обратитесь к нам\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Спланируйте детальное путешествие на Гавайи.\",\n\t\"platformergpt\": \"ПлатформерGPT 🎮\",\n\t\"researchgpt\": \"ИсследованияGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"веб-поиск\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Учетная запись\",\n\t\"HELP_BUTTON\": \"Помощь\",\n\t\"MY_AGENTS\": \"Мои агенты\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Сначала вам нужно создать и сохранить своего первого агента, прежде чем что-либо появится здесь!\",\n\t\"SETTINGS_BUTTON\": \"Настройки\",\n\t\"SIGN_IN\": \"Войти\",\n\t\"SIGN_IN_NOTICE\": \"Войдите, чтобы сохранить своих агентов и управлять своей учетной записью!\",\n\t\"SIGN_OUT\": \"Выйти\",\n\t\"SUPPORT_BUTTON\": \"Поддерживать\",\n\t\"USER_IMAGE\": \"Изображение пользователя\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"Ошибка при доступе к ключу OpenAI API. Проверьте ключ API или попробуйте позже.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"Ошибка при добавлении дополнительных задач. Возможно, наша модель не может обработать ответ, что привело к этому. Продолжаем...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Превышен лимит запросов! Пожалуйста, замедлите...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Этот агент достиг максимального количества запускаемых циклов. Чтобы сохранить ваш кошелек, этот агент сейчас остановится... Максимальное количество запускаемых циклов агента можно настроить в настройках.\",\n  \"DEMO_LOOPS_REACHED\": \"К сожалению, поскольку это демонстрационное приложение, мы не можем запускать наших агентов слишком долго. Примечание: если вам нужно длительное выполнение, пожалуйста, укажите свой собственный ключ API в настройках. Остановка...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Агент был остановлен вручную.\",\n  \"ALL_TASKS_COMPLETETD\": \"Все задачи выполнены. Остановка...\",\n  \"ERROR_API_KEY_QUOTA\": \"Ошибка при использовании ключа OpenAI API. Вы превысили свою текущую квоту, пожалуйста, проверьте свои платежные данные.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"Ошибка: ваш ключ OpenAI API не имеет доступа к GPT-4. Сначала вам нужно зарегистрироваться в списке ожидания OpenAI. (Это отличается от ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"Ошибка при запросе исходных задач. Попробуйте еще раз, яснее сформулируйте цель агента или измените ее таким образом, чтобы она соответствовала нашей модели. Остановка...\",\n  \"INVALID_OPENAI_API_KEY\": \"ОШИБКА неверный ключ API OpenAI\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Документация AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Следите за нашими достижениями:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Взаимодействие с веб-сайтами и людьми 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"позволяет вам настроить и запустить независимых агентов ИИ в вашем браузере. Назовите вашего собственного агента ИИ и определите его цель. Агент ИИ попытается достичь заданной цели, создавая задачи, выполняя их, а затем оценивая результаты 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Долгосрочная память 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Эта платформа находится в бета-версии, мы в настоящее время работаем над следующим:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Чтобы узнать больше об AgentGPT, его дорожной карте, часто задаваемых вопросах и т. д., посетите\",\n\t\"WEB_BROWSING\": \"Веб-браузинг 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Добро пожаловать в AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/indexPage.json",
    "content": "{\n  \"BETA\": \"Бета\",\n  \"HEADING_DESCRIPTION\": \"Соберите, настройте и установите автономных агентов искусственного интеллекта в своем браузере.\",\n  \"AGENT_NAME\": \"Имя\",\n  \"LABEL_AGENT_GOAL\": \"Цель\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Сделать мир лучше\",\n  \"BUTTON_DEPLOY_AGENT\": \"Запустить агента\",\n  \"BUTTON_STOP_AGENT\": \"Остановить агента\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/languages.json",
    "content": "{\n    \"ENGLISH\": \"Английский\",\n    \"FRENCH\": \"Французский\",\n    \"SPANISH\": \"Испанский\",\n    \"GERMAN\": \"Немецкий\",\n    \"JAPANESE\": \"Японский\",\n    \"KOREAN\": \"Корейский\",\n    \"CHINESE\": \"Китайский\",\n    \"PORTUGEES\": \"Португальский\",\n    \"ITALIAN\": \"Итальянский\",\n    \"DUTCH\": \"Голландский\",\n    \"POLSKI\": \"Польский\",\n    \"HUNGARIAN\": \"Венгерский\",\n    \"ROMANIAN\": \"Румынский\",\n    \"SLOVAK\": \"Словацкий\"\n}\n"
  },
  {
    "path": "next/public/locales/ru/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Расширенные настройки\",\n\t\"API_KEY\": \"API-ключ\",\n\t\"AUTOMATIC_MODE\": \"Автоматический режим\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(По умолчанию): Агент автоматически выполняет каждую задачу.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Ограничивает максимальное количество токенов, используемых в каждом вызове API (более высокое значение дает более подробные ответы, но стоит дороже).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Управляет максимальным числом циклов, запущенных агентом (большее значение приводит к большему числу вызовов API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Получите свой собственный ключ API OpenAI\",\n\t\"HERE\": \"здесь\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Здесь вы можете добавить свой ключ OpenAI API. Это означает, что вам нужно заплатить за использование своего токена OpenAI, но вы получите больший доступ к ChatGPT! Кроме того, вы можете выбрать любую модель, предлагаемую OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Большие значения делают вывод более случайным, в то время как более низкие значения делают его более фокусированным и определенным.\",\n\t\"INFO_TO_USE_GPT4\": \"Для использования модели GPT-4 необходимо также указать API-ключ. Вы можете получить его\",\n\t\"INVALID_OPENAI_API_KEY\": \"Неверный API-ключ!\",\n\t\"LABEL_MODE\": \"Режим\",\n\t\"LABEL_MODEL\": \"Модель\",\n\t\"LANG\": \"Язык\",\n\t\"LINK\": \"запросить API-ключ\",\n\t\"LOOP\": \"Цикл\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Примечание: Вы должны подключить кредитную карту к вашему аккаунту\",\n\t\"NOTE_API_KEY_USAGE\": \"Этот ключ используется только в текущей сессии браузера.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"ПРИМЕЧАНИЕ: Для получения API-ключа вам необходимо зарегистрироваться в учетной записи OpenAI по следующей ссылке:\",\n\t\"PAUSE\": \"Пауза\",\n\t\"PAUSE_MODE\": \"Режим паузы\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Агент приостанавливает выполнение после каждого набора задач(и)\",\n\t\"PENAI_API_KEY\": \"Недействительный API-ключ OpenAI\",\n\t\"PLAY\": \"Воспроизвести\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Настройки ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(Подписка ChatGPT Plus не будет работать)\",\n\t\"TEMPERATURE\": \"Температура\",\n\t\"TOKENS\": \"Токены\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Dokončovanie:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Zvážte podporu projektu na Github-e.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Text skopírovaný do schránky\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Nepodarilo sa skopírovať text do schránky\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Začíname nový cieľ:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Momentálne sa stretávame s mimoriadne vysokou premávkou. Očakávajte meškania a chyby, ak aký nepoužívate svoj API kľúč 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Podporte rozvoj AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Žiadne ďalšie úlohy nie sú k dispozícii pre:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Ak to trvá viac ako 30 sekúnd, obnovte stránku alebo spustite agenta znova manuálne)\",\n\t\"SUPPORT_NOW\": \"Podporiť teraz 🚀\",\n\t\"TASK_ADDED\": \"Úloha pridaná:\",\n\t\"THINKING\": \"Premýšľanie...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Môžete uviesť svoj OpenAI API kľúč v sekcii Nastavenia, aby ste zvýšili obmedzenia!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Vytvorte agenta pridaním mena/cieľa a stlačením nasadiť!\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Vytvorte agenta pridaním mena / cieľa a stlačením nasadiť! \\nVyskúšajte naše príklady nižšie!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta smerom mena a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопкута \\\"Зтипустити!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Pridanie úlohy\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentácia AgentGPT\",\n\t\"CLOSE\": \"Zavrieť\",\n\t\"CONTINUE\": \"Dalej\",\n\t\"COPIED_TO_CLIPBOARD\": \"Skopírované do schránky! 🚀\",\n\t\"COPY\": \"Kopírovať\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Vytvorte agenta pridaním mena / cieľa a stlačením nasadiť!\",\n\t\"CURRENT_TASKS\": \"Aktuálne úlohy\",\n\t\"EXECUTING\": \"Vykonávanie\",\n\t\"EXPORT\": \"Exportovať\",\n\t\"IMAGE\": \"Obrázok\",\n\t\"LOOP\": \"Smyčka\",\n\t\"PAUSED\": \"Pozastavené\",\n\t\"RESET\": \"Obnoviť\",\n\t\"RUNNING\": \"Prebieha\",\n\t\"SAVE\": \"Uložiť\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Ak chcete získať viac informácií o AgentGPT, jeho pláne atď., navštívte nasledujúci odkaz\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Vytvorte komplexnú správu spoločnosti Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Ak máte problémy, obráťte sa na nás\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Naplánujte si podrobný výlet na Havaj.\",\n\t\"platformergpt\": \"PlatformaGPT 🎮\",\n\t\"researchgpt\": \"Preskúmajte GPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"vyhľadávanie na webe\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Účet\",\n\t\"HELP_BUTTON\": \"Pomoc\",\n\t\"MY_AGENTS\": \"Moji agenti\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Najprv musíte vytvoriť a uložiť svojho prvého agenta, než sa tu niečo zobrazí!\",\n\t\"SETTINGS_BUTTON\": \"Nastavenia\",\n\t\"SIGN_IN\": \"Prihlásiť sa\",\n\t\"SIGN_IN_NOTICE\": \"Prihláste sa, aby ste mohli uložiť svojich agentov a spravovať svoj účet!\",\n\t\"SIGN_OUT\": \"Odhlásiť sa\",\n\t\"SUPPORT_BUTTON\": \"podpora\",\n\t\"USER_IMAGE\": \"Obrázok používateľa\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"Chyba pri prístupe k OpenAI API kľúču. Skontrolujte prosím svoj API kľúč alebo to skúste neskôr.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"Chyba pri pridávaní ďalších úloh. Možno naša model nevie spracovať váš výber a toto je výsledkom. Pokračovanie...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Dosiahli ste maximálny počet dotazov! Prosím, spomaľte...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Tento agent dosiahol maximálny počet opakovaní. Pretože chceme ušetriť vašu peňaženku, tento agent sa teraz zastaví... Maximálny počet behov agenta je možné konfigurovať v nastaveniach.\",\n  \"DEMO_LOOPS_REACHED\": \"Prepáčte, ale táto je ukážková aplikácia, takže nemôžeme nechať našich agentov behať príliš dlho. Poznámka: Ak chcete behy predĺžiť, zadajte vlastný API kľúč v nastaveniach. Zastavenie...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Agent bol ručne vypnutý.\",\n  \"ALL_TASKS_COMPLETETD\": \"Všetky úlohy sú dokončené. Zastavenie...\",\n  \"ERROR_API_KEY_QUOTA\": \"Chyba pri používaní OpenAI API kľúča. Prekročili ste svoju súčasnú kvótu, skontrolujte svoje fakturačné údaje.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"Chyba: Váš OpenAI API kľúč nemá prístup k GPT-4. Najskôr sa musíte zaregistrovať v OpenAI čakacej zoznamu. (To sa líši od ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"Chyba pri získavaní základných úloh. Skúste to znova, zmeňte cieľ agenta tak, aby bol jasný alebo ho upravte tak, aby zodpovedal nášmu modelu. Zastavenie...\",\n  \"INVALID_OPENAI_API_KEY\": \"Chyba neplatný OpenAI API-kľúč\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Dokumentácia AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Sledujte nás na našej ceste:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Interakcia s webovými stránkami a ľuďmi 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"vám umožňuje konfigurovať a spúšťať nezávislých agentov umelej inteligencie vo vašom prehliadači. Nazvite svojho vlastného agenta AI a stanovte jeho cieľ. Agent AI sa bude snažiť dosiahnuť stanovený cieľ tým, že vytvára úlohy, vykonáva ich a potom hodnotí ich výsledky 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Dlhodobá pamäť 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Táto platforma je momentálne v beta verzii, momentálne pracujeme na týchto veciach:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Ak sa chcete dozvedieť viac o AgentGPT, jeho pláne, často kladených otázkach atď., navštívte stránku\",\n\t\"WEB_BROWSING\": \"Prehliadanie webových stránok 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Vitajte v AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/indexPage.json",
    "content": "{\n  \"BETA\": \"Béta\",\n  \"HEADING_DESCRIPTION\": \"Skladajte, konfigurujte a inštalujte autonómne agentov AI vo svojom prehliadači.\",\n  \"AGENT_NAME\": \"Meno\",\n  \"LABEL_AGENT_GOAL\": \"Cieľ\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Urobiť svet lepším miestom\",\n  \"BUTTON_DEPLOY_AGENT\": \"Spustiť agenta\",\n  \"BUTTON_STOP_AGENT\": \"Zastaviť agenta\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/languages.json",
    "content": "{\n    \"ENGLISH\": \"Angličtina\",\n    \"FRENCH\": \"Francúzština\",\n    \"SPANISH\": \"Španielčina\",\n    \"GERMAN\": \"Nemčina\",\n    \"JAPANESE\": \"Japončina\",\n    \"KOREAN\": \"Kórejčina\",\n    \"CHINESE\": \"Čínština\",\n    \"PORTUGEES\": \"Portugalčina\",\n    \"ITALIAN\": \"Taliančina\",\n    \"DUTCH\": \"Holandčina\",\n    \"POLSKI\": \"Poľština\",\n    \"HUNGARIAN\": \"Maďarčina\",\n    \"ROMANIAN\": \"Rumunčina\",\n    \"SLOVAK\": \"Slovenčina\"\n}\n"
  },
  {
    "path": "next/public/locales/sk/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Pokročilé nastavenia\",\n\t\"API_KEY\": \"API kľúč\",\n\t\"AUTOMATIC_MODE\": \"Automatický režim\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Predvolené): Agent automaticky vykonáva každú úlohu.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Ovládajte maximálny počet tokenov použitých v každom volaní API (vyššia hodnota poskytuje podrobnejšie odpovede, ale je drahšia).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Ovládajte maximálny počet slučiek, ktoré spustí agent (vyššia hodnota znamená viac volaní API).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Získajte svoj vlastný OpenAI API kľúč\",\n\t\"HERE\": \"tu\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Tu môžete pridať svoj OpenAI API kľúč. To znamená, že musíte platiť za použitie vlastného OpenAI tokenu, ale získate väčší prístup k ChatGPT! Okrem toho môžete vybrať akýkoľvek model ponúkaný OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Vyššie hodnoty robia výstup viac náhodným, zatiaľ čo nižšie hodnoty ho zameriavajú a určujú.\",\n\t\"INFO_TO_USE_GPT4\": \"Na použitie modelu GPT-4 je potrebné zadať aj API kľúč. Môžete ho získať\",\n\t\"INVALID_OPENAI_API_KEY\": \"Neplatný API kľúč!\",\n\t\"LABEL_MODE\": \"Režim\",\n\t\"LABEL_MODEL\": \"Model\",\n\t\"LANG\": \"Jazyk\",\n\t\"LINK\": \"Získanie API kľúča\",\n\t\"LOOP\": \"Smyčka\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Poznámka: Musíte pripojiť kreditnú kartu k vášmu účtu\",\n\t\"NOTE_API_KEY_USAGE\": \"Tento kľúč sa použije iba počas aktuálnej relácie prehliadača.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"POZNÁMKA: Na získanie API kľúča musíte zaregistrovať OpenAI účet, ktorý môžete urobiť na nasledujúcej adrese:\",\n\t\"PAUSE\": \"Pozastaviť\",\n\t\"PAUSE_MODE\": \"Režim pozastavenia\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Agent sa pozastaví po každej sade úloh(y)\",\n\t\"PENAI_API_KEY\": \"Neplatný kľúč API OpenAI\",\n\t\"PLAY\": \"Prehrať\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Nastavenia ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(Predplatné ChatGPT Plus nebude fungovať)\",\n\t\"TEMPERATURE\": \"Teplota\",\n\t\"TOKENS\": \"Tokeny\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Tamamlanıyor:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Lütfen GitHub'da projeye sponsor olmayı düşünün.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Metin panoya kopyalandı\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Metin panoya kopyalanamıyor\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Bir ad / hedef ekleyerek ve konuşlandır'a basarak bir aracı oluşturun! Aşağıdaki örneklerimizi deneyin!\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Yeni bir hedefe başlamak:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Olağanüstü trafik yaşıyoruz, kendi API anahtarınızı kullanmazsanız gecikmeler ve başarısızlıklar bekliyoruz🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ AgentGPT'nin ilerlemesini desteklemeye yardımcı olun. \\n💝️\",\n\t\"NO_MORE_TASKS\": \"Şunun için başka alt görev yok:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(30 saniyeden fazla sürerse yeniden başlatın)\",\n\t\"SUPPORT_NOW\": \"Şimdi destek 🚀\",\n\t\"TASK_ADDED\": \"Görev eklendi:\",\n\t\"THINKING\": \"Düşünüyorum...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Arttırılmış limitler için ayarlar sekmesinden kendi OpenAI API anahtarınızı sağlayabilirsiniz!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Bir ad/hedef ekleyip konuşlandır'a basarak bir aracı oluşturun!\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Bir isim / hedef ekleyerek ve konuşlandır'a basarak bir temsilci oluşturun! \\nAşağıdaki örneklerimizi deneyin!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 \\\"Temsilci!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Görev Ekleme\",\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT Belgeleri\",\n\t\"CLOSE\": \"Kapalı\",\n\t\"CONTINUE\": \"Devam etmek\",\n\t\"COPIED_TO_CLIPBOARD\": \"Panoya kopyalandı! 🚀\",\n\t\"COPY\": \"kopyala\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Bir ad / hedef ekleyerek ve konuşlandır'a basarak bir aracı oluşturun!\",\n\t\"CURRENT_TASKS\": \"Mevcut Görevler\",\n\t\"EXECUTING\": \"Yürütme\",\n\t\"EXPORT\": \"İhracat\",\n\t\"IMAGE\": \"resim\",\n\t\"LOOP\": \"Döngü\",\n\t\"PAUSED\": \"Duraklatıldı\",\n\t\"RESET\": \"Sıfırla\",\n\t\"RUNNING\": \"Koşma\",\n\t\"SAVE\": \"Kaydetmek\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"AgentGPT, Yol Haritası vb. hakkında daha fazla bilgi almak için aşağıdaki bağlantıyı ziyaret edin\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Nike şirketi hakkında kapsamlı bir rapor oluşturun\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Sorunlarla karşılaşıyorsanız, lütfen şuraya gidin:\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Hawaii'ye ayrıntılı bir gezi planlayın.\",\n\t\"platformergpt\": \"PlatformerGPT 🎮\",\n\t\"researchgpt\": \"AraştırmaGPT 📜\",\n\t\"travelgpt\": \"🌴\",\n\t\"web-search\": \"internette arama\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Hesap\",\n\t\"HELP_BUTTON\": \"Yardım\",\n\t\"MY_AGENTS\": \"ajanlarım\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Burada herhangi bir şey ortaya çıkmadan önce ilk temsilcinizi oluşturmanız ve kaydetmeniz gerekir!\",\n\t\"SETTINGS_BUTTON\": \"Ayarlar\",\n\t\"SIGN_IN\": \"Kayıt olmak\",\n\t\"SIGN_IN_NOTICE\": \"ajanları kaydedebilmek ve hesabınızı yönetebilmek için!\",\n\t\"SIGN_OUT\": \"Oturumu Kapat\",\n\t\"SUPPORT_BUTTON\": \"Destek\",\n\t\"USER_IMAGE\": \"Kullanıcı Resmi\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/errors.json",
    "content": "{\n\t\"AGENT_MANUALLY_SHUT_DOWN\": \"Temsilci manuel olarak kapatıldı.\",\n\t\"AGENT_MAXED_OUT_LOOPS\": \"Bu ajan döngülerde maksimuma ulaştı. \\nCüzdanınızı kurtarmak için bu aracı kapatılıyor. \\nGelişmiş ayarlarda döngü sayısını yapılandırabilirsiniz.\",\n\t\"ALL_TASKS_COMPLETETD\": \"Tüm görevler tamamlandı. \\nKapatmak.\",\n\t\"DEMO_LOOPS_REACHED\": \"Üzgünüz, çünkü bu bir demo, ajanlarımızı çok uzun süre çalıştıramayız. \\nDaha uzun çalıştırmalar istiyorsanız, lütfen Ayarlar'da kendi API anahtarınızı sağlayın. \\nKapatmak.\",\n\t\"ERROR_ACCESSING_OPENAI_API_KEY\": \"OpenAI'nin API'sine erişirken HATA. \\nLütfen API anahtarınızı kontrol edin veya daha sonra tekrar deneyin\",\n\t\"ERROR_ADDING_ADDITIONAL_TASKS\": \"Ek görev(ler) eklenirken HATA. \\nBunları çalıştırmak modelimizin ilkelerine aykırı olabilir. \\nDevam ediyor.\",\n\t\"ERROR_API_KEY_QUOTA\": \"OpenAI API anahtarınızı kullanırken HATA. \\nMevcut kotanızı aştınız, lütfen planınızı ve fatura ayrıntılarınızı kontrol edin.\",\n\t\"ERROR_OPENAI_API_KEY_NO_GPT4\": \"HATA, API anahtarınızın GPT-4 erişimi yok. \\nÖnce OpenAI'nin bekleme listesine katılmalısınız. \\n(Bu, ChatGPT Plus'tan farklıdır)\",\n\t\"ERROR_RETRIEVE_INITIAL_TASKS\": \"İlk görevler dizisi alınırken HATA. \\nYeniden deneyin, hedefinizi daha net hale getirin veya hedefinizi, çalıştırılacak modelimizin politikaları dahilinde olacak şekilde revize edin. \\nKapatmak.\",\n\t\"INVALID_OPENAI_API_KEY\": \"HATA geçersiz OpenAI API anahtarı\",\n\t\"RATE_LIMIT_EXCEEDED\": \"Hız limiti aşıldı! \\nLütfen yavaşlayın...😅\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT Belgeleri\",\n\t\"FOLLOW_THE_JOURNEY\": \"Aşağıdaki yolculuğu takip edin:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Web siteleri ve insanlarla etkileşim 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"Autonomous AI aracılarını yapılandırmanıza ve dağıtmanıza olanak tanır. \\nÖzel yapay zekanıza bir ad verin ve hayal edebileceğiniz herhangi bir hedefe ulaşmasını sağlayın. \\nYapılacak işleri düşünerek, yürüterek ve sonuçlardan ders çıkararak hedefe ulaşmaya çalışacaktır 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Uzun süreli hafıza 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Bu platform şu anda beta aşamasındadır ve şu anda üzerinde çalışıyoruz:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"AgentGPT, yol haritası, SSS vb. hakkında daha fazla bilgi edinmek için şu adresi ziyaret edin:\",\n\t\"WEB_BROWSING\": \"Web'de gezinme 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"AgentGPT'ye hoş geldiniz\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/indexPage.json",
    "content": "{\n\t\"AGENT_NAME\": \"İsim\",\n\t\"BETA\": \"Beta\",\n\t\"BUTTON_DEPLOY_AGENT\": \"Aracıyı Dağıt\",\n\t\"BUTTON_STOP_AGENT\": \"Ajanı Durdur\",\n\t\"HEADING_DESCRIPTION\": \"Tarayıcınızda otonom AI Aracılarını birleştirin, yapılandırın ve dağıtın.\",\n\t\"LABEL_AGENT_GOAL\": \"Amaç\",\n\t\"PLACEHOLDER_AGENT_GOAL\": \"Dünyayı daha güzel bir yer yap\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/languages.json",
    "content": "{\n\t\"CHINESE\": \"Çince\",\n\t\"DUTCH\": \"Flemenkçe\",\n\t\"ENGLISH\": \"İngilizce\",\n\t\"FRENCH\": \"Fransızca\",\n\t\"GERMAN\": \"Almanca\",\n\t\"HUNGARIAN\": \"Macarca\",\n\t\"ITALIAN\": \"İtalyan\",\n\t\"JAPANESE\": \"Japonca\",\n\t\"KOREAN\": \"Koreli\",\n\t\"POLSKI\": \"Polski\",\n\t\"PORTUGEES\": \"Portekizce\",\n\t\"ROMANIAN\": \"Romence\",\n\t\"SLOVAK\": \"Slovak\",\n\t\"SPANISH\": \"İspanyol\"\n}\n"
  },
  {
    "path": "next/public/locales/tr/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Gelişmiş Ayarlar\",\n\t\"API_KEY\": \"Anahtar\",\n\t\"AUTOMATIC_MODE\": \"Otomatik mod\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(Varsayılan): Aracı, her görevi otomatik olarak yürütür.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Her bir API çağrısında kullanılan maksimum belirteç sayısını kontrol eder (daha yüksek değer, yanıtları daha ayrıntılı hale getirir ancak daha pahalıya mal olur).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Aracının çalıştıracağı maksimum döngü sayısını kontrol eder (daha yüksek değer, daha fazla API çağrısı yapar).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Kendi OpenAI API anahtarınızı alın\",\n\t\"HERE\": \"Burada\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Burada OpenAI API anahtarınızı ekleyebilirsiniz. \\nBu, kendi OpenAI kullanımınız için ödeme yapmanızı gerektirir, ancak size AgentGPT'ye daha fazla erişim sağlar! \\nEk olarak OpenAI'nin sunduğu herhangi bir modeli de seçebilirsiniz.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Daha yüksek değerler çıktıyı daha rasgele hale getirirken, daha düşük değerler çıktıyı daha odaklı ve deterministik yapar.\",\n\t\"INFO_TO_USE_GPT4\": \"GPT-4 modelini kullanmak için GPT-4 için API anahtarını da sağlamanız gerekir. \\nbunun için istekte bulunabilirsiniz\",\n\t\"INVALID_OPENAI_API_KEY\": \"Geçersiz API anahtarı!\",\n\t\"LABEL_MODE\": \"mod\",\n\t\"LABEL_MODEL\": \"modeli\",\n\t\"LANG\": \"Dil\",\n\t\"LINK\": \"bağlantı\",\n\t\"LOOP\": \"Döngü\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Not: Hesabınıza bir kredi kartı bağlamanız gerekmektedir\",\n\t\"NOTE_API_KEY_USAGE\": \"Bu anahtar yalnızca geçerli tarayıcı oturumunda kullanılır\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"NOT: Bir anahtar almak için bir OpenAI hesabına kaydolun ve aşağıdakileri ziyaret edin.\",\n\t\"PAUSE\": \"Duraklat\",\n\t\"PAUSE_MODE\": \"Duraklatma modu\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Aracı, her görev grubundan sonra duraklar\",\n\t\"PENAI_API_KEY\": \"Geçersiz OpenAI API anahtarı\",\n\t\"PLAY\": \"Oynamak\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Ayarlar ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(ChatGPT Plus aboneliği çalışmaz)\",\n\t\"TEMPERATURE\": \"Sıcaklık\",\n\t\"TOKENS\": \"Jetonlar\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/chat.json",
    "content": "{\n\t\"COMPLETING\": \"Виконання:\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"Розгляньте можливість підтримки проекту на GitHub.\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"Текст скопійовано в буфер обміну\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"Не вдалося скопіювати текст в буфер обміну\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"Розпочато нову мету:\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 Ми спостерігаємо надзвичайний трафік, очікуються затримки та помилки, якщо ви не використовуєте свій власний API-ключ 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ Підтримайте розвиток AgentGPT. 💝️\",\n\t\"NO_MORE_TASKS\": \"Більше немає підзадач для цього:\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"(Оновіть сторінку або запустіть агента вручну, якщо це займає більше 30 секунд)\",\n\t\"SUPPORT_NOW\": \"Підтримати зараз 🚀\",\n\t\"TASK_ADDED\": \"Завдання додано:\",\n\t\"THINKING\": \"Думаємо...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 Ви можете вказати свій власний ключ OpenAI API на вкладці Налаштування, щоб підвищити ліміти!\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 Створіть агента, додавши ім’я/ціль і натиснувши розгорнути!\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 Створіть агента, додавши ім’я/ціль і натиснувши розгорнути! \\nСпробуйте наші приклади нижче!\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Створіть агента, надавши його на ціль, і натисніть на кнопку \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Створіть агента, додавши ім’я та ціль, потім натисніть кнопку «Запустити агента!»\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім натисніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"Додавання завдання\",\n\t\"AGENTGPT_DOCUMENTATION\": \"Документація AgentGPT\",\n\t\"CLOSE\": \"Закрити\",\n\t\"CONTINUE\": \"Продовжити\",\n\t\"COPIED_TO_CLIPBOARD\": \"Скопійовано в буфер обміну! 🚀\",\n\t\"COPY\": \"Копія\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"Створіть агента, додавши ім’я/ціль і натиснувши розгорнути!\",\n\t\"CURRENT_TASKS\": \"Поточні завдання\",\n\t\"EXECUTING\": \"Виконується\",\n\t\"EXPORT\": \"Експорт\",\n\t\"IMAGE\": \"Зображення\",\n\t\"LOOP\": \"Петля\",\n\t\"PAUSED\": \"Призупинено\",\n\t\"RESET\": \"Скинути\",\n\t\"RUNNING\": \"В процесі\",\n\t\"SAVE\": \"зберегти\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Щоб отримати більше інформації про AgentGPT, його дорожню карту тощо, перейдіть за цим посиланням\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"Створити комплексний звіт компанії Nike\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"Якщо у вас виникли проблеми, зверніться до нас\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"Детальний план подорожі на Гаваї.\",\n\t\"platformergpt\": \"ПлатформерGPT 🎮\",\n\t\"researchgpt\": \"ДослідженняGPT 📜\",\n\t\"travelgpt\": \"TravelGPT 🌴\",\n\t\"web-search\": \"Пошук в Інтернеті\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"Обліковий запис\",\n\t\"HELP_BUTTON\": \"Допомога\",\n\t\"MY_AGENTS\": \"Мої агенти\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"Спочатку вам потрібно створити та зберегти свого першого агента, перш ніж тут що-небудь з'явиться!\",\n\t\"SETTINGS_BUTTON\": \"Налаштування\",\n\t\"SIGN_IN\": \"Увійти\",\n\t\"SIGN_IN_NOTICE\": \"Увійдіть, щоб зберегти своїх агентів та керувати своїм обліковим записом!\",\n\t\"SIGN_OUT\": \"Вийти\",\n\t\"SUPPORT_BUTTON\": \"Підтримка\",\n\t\"USER_IMAGE\": \"Зображення користувача\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"ПОМИЛКА при доступі до ключа OpenAI API. Будь ласка, перевірте ключ API або спробуйте пізніше.\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"ПОМИЛКА при додаванні додаткових завдань. Можливо, наша модель не може обробити відповідь, тому так сталося. Продовження...\",\n  \"RATE_LIMIT_EXCEEDED\": \"Досягнуто максимальну кількість запитів! Будь ласка, сповільніть...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"Цей агент досяг максимальної кількості запусків. Щоб зберегти кошти, цей агент тепер припиняє свою роботу... Максимальну кількість запусків агента можна налаштувати в налаштуваннях.\",\n  \"DEMO_LOOPS_REACHED\": \"Вибачте, але це демонстраційний додаток, тому ми не можемо запускати агентів занадто довго. Примітка: якщо ви хочете запускати довші роботи, будь ласка, вкажіть власний ключ API в налаштуваннях. Припинення...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"Агент був вручну вимкнутий.\",\n  \"ALL_TASKS_COMPLETETD\": \"Всі завдання виконано. Припинення...\",\n  \"ERROR_API_KEY_QUOTA\": \"ПОМИЛКА при використанні ключа OpenAI API. Ви перевищили свою поточну квоту, будь ласка, перевірте свої рахункові дані.\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"ПОМИЛКА: Ваш ключ OpenAI API не має доступу до GPT-4. Спочатку вам потрібно зареєструватися в черзі OpenAI. (Це відрізняється від ChatGPT Plus)\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"ПОМИЛКА при отриманні початкових завдань. Спробуйте ще раз, сформулюйте мету агента ясніше або змініть її таким чином, щоб вона відповідала нашій моделі. Припинення...\",\n  \"INVALID_OPENAI_API_KEY\": \"ПОМИЛКА недійсний OpenAI API-ключ\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"Документація AgentGPT\",\n\t\"FOLLOW_THE_JOURNEY\": \"Слідкуйте за нашими досягненнями на:\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"Взаємодія з веб-сайтами та людьми 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"дозволяє вам налаштовувати та запускати власних незалежних агентів штучного інтелекту через свій веб-браузер. Назвіть вашого персоналізованого агента штучного інтелекту та визначте його ціль. Агент ШІ намагається досягти заданої мети, створюючи завдання, виконуючи їх та оцінюючи їх результати 🚀\",\n\t\"LONG_TERM_MEMORY\": \"Довготривала пам'ять 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"Ця платформа наразі перебуває у бета-версії, на даний момент ми працюємо над наступними функціями:\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"Щоб дізнатися більше про AgentGPT, його дорожню карту, поширені запитання тощо, відвідайте\",\n\t\"WEB_BROWSING\": \"Веб-перегляд 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"Ласкаво просимо до AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/indexPage.json",
    "content": "{\n  \"BETA\": \"Бета\",\n  \"HEADING_DESCRIPTION\": \"Збирайте, налаштовуйте та встановлюйте автономних агентів ШІ у своєму браузері.\",\n  \"AGENT_NAME\": \"Ім'я\",\n  \"LABEL_AGENT_GOAL\": \"Мета\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"Зробити світ кращим місцем\",\n  \"BUTTON_DEPLOY_AGENT\": \"Запустити агента\",\n  \"BUTTON_STOP_AGENT\": \"Зупинити агента\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/languages.json",
    "content": "{\n    \"ENGLISH\": \"Англійська\",\n    \"FRENCH\": \"Французька\",\n    \"SPANISH\": \"Іспанська\",\n    \"GERMAN\": \"Німецька\",\n    \"JAPANESE\": \"Японська\",\n    \"KOREAN\": \"Корейська\",\n    \"CHINESE\": \"Китайська\",\n    \"PORTUGEES\": \"Португальська\",\n    \"ITALIAN\": \"Італійська\",\n    \"DUTCH\": \"Голландська\",\n    \"POLSKI\": \"Польська\",\n    \"HUNGARIAN\": \"Угорська\",\n    \"ROMANIAN\": \"Румунська\",\n    \"SLOVAK\": \"Словаць\"\n}\n"
  },
  {
    "path": "next/public/locales/uk/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"Розширені налаштування\",\n\t\"API_KEY\": \"API ключ\",\n\t\"AUTOMATIC_MODE\": \"Автоматичний режим\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"(За замовчуванням): Агент автоматично виконує кожне завдання.\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"Керує максимальною кількістю токенів, які використовуються в кожному API-виклику (більше значення дає більш детальні відповіді, але коштує більше).\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"Керує максимальною кількістю циклів, які виконує агент (більш високе значення призводить до більшої кількості API-викликів).\",\n\t\"GET_YOUR_OWN_APIKEY\": \"Отримайте свій власний ключ API OpenAI\",\n\t\"HERE\": \"тут\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"Тут ви можете додати свій API-ключ OpenAI. Це означає, що вам потрібно буде платити за використання свого власного токену OpenAI, але ви отримаєте більший доступ до ChatGPT! Крім того, ви можете вибрати будь-яку модель, яку пропонує OpenAI.\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"Вищі значення роблять вихід більш випадковим, тоді як нижчі значення зосередженішими та більш визначеними.\",\n\t\"INFO_TO_USE_GPT4\": \"Для використання моделі GPT-4 потрібно також вказати ключ API. Ви можете отримати його\",\n\t\"INVALID_OPENAI_API_KEY\": \"Неприпустимий API-ключ!\",\n\t\"LABEL_MODE\": \"Режим\",\n\t\"LABEL_MODEL\": \"Модель\",\n\t\"LANG\": \"Мова\",\n\t\"LINK\": \"Запит ключа API\",\n\t\"LOOP\": \"Цикл\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"Примітка: Ви повинні підключити кредитну картку до свого облікового запису\",\n\t\"NOTE_API_KEY_USAGE\": \"Цей ключ використовується лише протягом поточної сесії браузера.\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"ПРИМІТКА: Для отримання ключа API вам потрібно зареєструватися в обліковому записі OpenAI, що можна зробити за наступним посиланням:\",\n\t\"PAUSE\": \"Призупинити\",\n\t\"PAUSE_MODE\": \"Режим паузи\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"Агент паузує після кожного набору завдань\",\n\t\"PENAI_API_KEY\": \"Недійсний API-ключ OpenAI\",\n\t\"PLAY\": \"Відтворити\",\n\t\"SETTINGS_DIALOG_HEADER\": \"Налаштування ⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"(Підписка ChatGPT Plus не буде працювати)\",\n\t\"TEMPERATURE\": \"Температура\",\n\t\"TOKENS\": \"Токени\"\n}\n"
  },
  {
    "path": "next/public/locales/zh/chat.json",
    "content": "{\n\t\"COMPLETING\": \"完成：\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"通过GitHub赞助该项目。\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"文本已复制到剪贴板\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"无法将文本复制到剪贴板\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"迎接新目标：\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 我们正在经历异常的流量，请预计会有延迟和错误，如果您没有使用自己的API密钥 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ 支持AgentGPT的发展。 💝️\",\n\t\"NO_MORE_TASKS\": \"没有更多的子任务可以使用：\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"（如果需要30秒以上，请刷新页面或手动重新启动代理）\",\n\t\"SUPPORT_NOW\": \"现在支持 🚀\",\n\t\"TASK_ADDED\": \"任务已添加：\",\n\t\"THINKING\": \"思考中...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 您可以在设置选项卡中提供自己的OpenAI API密钥以获得提高的限制！\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 通过添加名称/目标并按部署来创建代理！\"\n}\n"
  },
  {
    "path": "next/public/locales/zh/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 通过添加名称/目标并点击部署来创建代理！\\n尝试下面的示例！\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉创建一个代理，添加名称和目标，然后单击“启动代理！”按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/zh/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"添加任务\",\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT 的文档\",\n\t\"CLOSE\": \"关闭\",\n\t\"CONTINUE\": \"继续\",\n\t\"COPIED_TO_CLIPBOARD\": \"已复制到剪贴板！ 🚀\",\n\t\"COPY\": \"复制\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"通过添加名称/目标并点击部署来创建代理！\",\n\t\"CURRENT_TASKS\": \"当前任务\",\n\t\"EXECUTING\": \"执行中\",\n\t\"EXPORT\": \"导出\",\n\t\"IMAGE\": \"图片\",\n\t\"LOOP\": \"循环\",\n\t\"PAUSED\": \"暂停\",\n\t\"RESET\": \"重置\",\n\t\"RUNNING\": \"进行中\",\n\t\"SAVE\": \"保存\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"要获取有关 AgentGPT 及其路线图等的更多信息，请访问以下链接\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"创建耐克公司的综合报告\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"如果您遇到问题，请前往我们的\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"计划详细的夏威夷之旅。\",\n\t\"platformergpt\": \"平台 GPT 🎮\",\n\t\"researchgpt\": \"研究 GPT 📜\",\n\t\"travelgpt\": \"旅游 GPT 🌴\",\n\t\"web-search\": \"网络搜索\"\n}\n"
  },
  {
    "path": "next/public/locales/zh/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"帐户\",\n\t\"HELP_BUTTON\": \"帮助\",\n\t\"MY_AGENTS\": \"我的代理人\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"在此显示任何内容之前，您需要先创建和保存第一个代理人！\",\n\t\"SETTINGS_BUTTON\": \"设置\",\n\t\"SIGN_IN\": \"登录\",\n\t\"SIGN_IN_NOTICE\": \"请登录以保存您的代理人并管理您的帐户！\",\n\t\"SIGN_OUT\": \"退出\",\n\t\"SUPPORT_BUTTON\": \"支持\",\n\t\"USER_IMAGE\": \"用户图片\"\n}\n"
  },
  {
    "path": "next/public/locales/zh/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"在连接 OpenAI API 时出错。请检查 API 密钥，或稍后再试。\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"添加其他任务时出错。可能是因为我们的模型无法处理您的响应和结果。继续...\",\n  \"RATE_LIMIT_EXCEEDED\": \"已达到最大查询次数！请放慢速度...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"此代理已达到可运行循环的最大次数。为了节省您的钱包，此代理现在将停止... 可以在设置中配置代理运行循环的最大次数。\",\n  \"DEMO_LOOPS_REACHED\": \"抱歉，因为这是一个演示应用程序，所以我们无法让代理运行太长时间。备注：如果您想运行更长时间，请在设置中提供自己的 API 密钥。停止...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"代理已手动关闭。\",\n  \"ALL_TASKS_COMPLETETD\": \"所有任务已完成。停止...\",\n  \"ERROR_API_KEY_QUOTA\": \"使用 OpenAI API 密钥时出错。您已超出当前配额，请检查您的帐单信息。\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"错误：您的 OpenAI API 密钥没有 GPT-4 访问权限。您首先需要在 OpenAI 等待列表中注册。 （这与 ChatGPT Plus 不同）\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"检索初始任务时出错。请重试，更清楚地表达代理目标，或者修改代理以使其符合我们的模型。停止...\",\n  \"INVALID_OPENAI_API_KEY\": \"錯誤，OpenAI API 金鑰無效\"\n}\n"
  },
  {
    "path": "next/public/locales/zh/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT 的文档\",\n\t\"FOLLOW_THE_JOURNEY\": \"在以下方面关注我们的旅程：\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"与网站和人们的互动 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"让您能够通过浏览器配置和运行自主的AI代理。命名您的定制AI代理并定义其目标。AI代理通过创建任务，执行任务，然后评估其结果来尝试实现指定的目标 🚀\",\n\t\"LONG_TERM_MEMORY\": \"长期记忆 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"该平台目前处于beta版，我们目前正在处理以下内容：\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"要了解有关 AgentGPT、其路线图、常见问题解答等的更多信息，请访问\",\n\t\"WEB_BROWSING\": \"网络浏览 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"欢迎使用AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/zh/indexPage.json",
    "content": "{\n  \"BETA\": \"贝塔\",\n  \"HEADING_DESCRIPTION\": \"在浏览器中编译，配置和安装自主 AI 代理。\",\n  \"AGENT_NAME\": \"名称\",\n  \"LABEL_AGENT_GOAL\": \"目标\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"让世界变得更美好\",\n  \"BUTTON_DEPLOY_AGENT\": \"运行代理\",\n  \"BUTTON_STOP_AGENT\": \"停止代理\"\n  }"
  },
  {
    "path": "next/public/locales/zh/languages.json",
    "content": "{\n    \"ENGLISH\": \"英语\",\n    \"FRENCH\": \"法语\",\n    \"SPANISH\": \"西班牙语\",\n    \"GERMAN\": \"德语\",\n    \"JAPANESE\": \"日语\",\n    \"KOREAN\": \"韩语\",\n    \"CHINESE\": \"中文\",\n    \"PORTUGEES\": \"葡萄牙语\",\n    \"ITALIAN\": \"意大利语\",\n    \"DUTCH\": \"荷兰语\",\n    \"POLSKI\": \"波兰语\",\n    \"HUNGARIAN\": \"匈牙利语\",\n    \"ROMANIAN\": \"罗马尼亚语\",\n    \"SLOVAK\": \"斯洛伐克语\"\n}"
  },
  {
    "path": "next/public/locales/zh/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"高级设置\",\n\t\"API_KEY\": \"API密钥\",\n\t\"AUTOMATIC_MODE\": \"自动模式\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"（默认）：代理自动执行每个任务。\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"控制每个API调用中使用的令牌的最大数量（较高的值会产生更详细的响应，但成本更高）。\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"控制代理程序运行的最大循环次数（较高的值会导致更多的API调用）。\",\n\t\"GET_YOUR_OWN_APIKEY\": \"获取您自己的 OpenAI API 密钥\",\n\t\"HERE\": \"这里\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"您可以在这里添加OpenAI API密钥。这意味着您需要支付使用自己的OpenAI令牌的费用，但您将获得更大的ChatGPT访问权限！此外，您还可以选择任何OpenAI提供的模型。\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"较高的值会使输出更加随机，而较低的值会使其更加聚焦和明确。\",\n\t\"INFO_TO_USE_GPT4\": \"使用GPT-4模型需要提供API密钥。您可以在此处获取。\",\n\t\"INVALID_OPENAI_API_KEY\": \"无效的 API 密钥！\",\n\t\"LABEL_MODE\": \"模式\",\n\t\"LABEL_MODEL\": \"模型\",\n\t\"LANG\": \"语言\",\n\t\"LINK\": \"获取API密钥\",\n\t\"LOOP\": \"循环\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"注：您必须将信用卡连接到您的账户\",\n\t\"NOTE_API_KEY_USAGE\": \"此密钥仅在当前浏览器会话中使用。\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"注意：要获取API密钥，您需要注册一个OpenAI帐户，可以在以下链接上完成：\",\n\t\"PAUSE\": \"暂停\",\n\t\"PAUSE_MODE\": \"暂停模式\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"代理在每组任务后暂停\",\n\t\"PENAI_API_KEY\": \"无效的 OpenAI API 密钥\",\n\t\"PLAY\": \"播放\",\n\t\"SETTINGS_DIALOG_HEADER\": \"设置⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"（ChatGPT Plus订阅不起作用）\",\n\t\"TEMPERATURE\": \"温度\",\n\t\"TOKENS\": \"令牌\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/chat.json",
    "content": "{\n\t\"COMPLETING\": \"完成：\",\n\t\"CONSIDER_SPONSORING_ON_GITHUB\": \"透過GitHub贊助本專案。\",\n\t\"CONSOLE_TEXT_COPIED_TO_CLIPBOARD\": \"文字已複製到剪貼簿\",\n\t\"CONSOLE_UNABLE_TO_COPY_TO_CLIPBOARD\": \"無法將文字複製至剪貼簿\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"創建一個AI機器人，輸入名稱和目標，然後點擊\\\"啟動AI！\\\"按鈕\",\n\t\"EMBARKING_ON_NEW_GOAL\": \"執行新目標：\",\n\t\"EXPERIENCING_EXCEPTIONAL_TRAFFIC\": \"🚨 我們正在經歷高流量，如果您沒有使用自己的API金鑰，預計會有延遲或錯誤 🚨\",\n\t\"HELP_SUPPORT_THE_ADVANCEMENT_OF_AGENTGPT\": \"💝️ 支持AgentGPT的發展。 💝️\",\n\t\"NO_MORE_TASKS\": \"沒有更多的次要任務可以執行：\",\n\t\"RESTART_IF_IT_TAKES_X_SEC\": \"（如果需要30秒以上，請重新整理網頁或手動重新啟動AI機器人）\",\n\t\"SUPPORT_NOW\": \"現在支持 🚀\",\n\t\"TASK_ADDED\": \"已添加任務：\",\n\t\"THINKING\": \"思考中...\",\n\t\"YOU_CAN_PROVIDE_YOUR_API_KEY\": \"📢 您可以在設定中提供自己的 OpenAI API 金鑰以解除AI回數上限！\",\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy!\": \"👉 輸入名稱/目標並點擊部署以創建一個AI機器人！\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/chat.missing.json",
    "content": "{\n\t\"👉 Create an agent by adding a name / goal, and hitting deploy! Try our examples below!\": \"👉 通过添加名称/目标并点击部署来创建代理！\\n尝试下面的示例！\",\n\t\"👉 Vytvorte agenta pridaním mena a cieľa a kliknite na tlačidlo \\\"Spustiť agenta!\\\"\": \"👉 Vytvorte agenta pridaním mena a cieľa kliknite na tlačidlo \\\"Spustiť agenta!\\\"\",\n\t\"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\": \"👉 Создайте агента, добавив имя и цель, затем нажмите кнопку \\\"Запустить агента!\\\"\",\n\t\"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\": \"👉 Створіть агента, додавши ім'я та мету, а потім клацніть кнопку \\\"Запустити агента!\\\"\",\n\t\"👉 创建一个代理，添加名称和目标，然后单击\\\"启动代理！\\\"按钮\": \"👉创建一个代理，添加名称和目标，然后单击“启动代理！”按钮\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/common.json",
    "content": "{\n\t\"ADDING_TASK\": \"增加任務\",\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT 的文件\",\n\t\"CLOSE\": \"關閉\",\n\t\"CONTINUE\": \"繼續\",\n\t\"COPIED_TO_CLIPBOARD\": \"以複製到剪貼簿！ \\n🚀\",\n\t\"COPY\": \"複製\",\n\t\"CREATE_AN_AGENT_DESCRIPTION\": \"輸入名稱/目標並點擊部署以創建一個AI機器人！\",\n\t\"CURRENT_TASKS\": \"目前任務\",\n\t\"EXECUTING\": \"執行中\",\n\t\"EXPORT\": \"匯出\",\n\t\"IMAGE\": \"圖片\",\n\t\"LOOP\": \"圈數\",\n\t\"PAUSED\": \"暫停\",\n\t\"RESET\": \"重置\",\n\t\"RUNNING\": \"進行中\",\n\t\"SAVE\": \"儲存\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"如果要取得有關 AgentGPT 及產品路線圖的資訊，請點閱以下連結\",\n\t\"create-a-comprehensive-report-of-the-nike-company\": \"建立Nike公司的綜合報告\",\n\t\"if-you-are-facing-issues-please-head-over-to-our\": \"如果您遇到問題，請前往我們的\",\n\t\"plan-a-detailed-trip-to-hawaii\": \"計畫詳細的夏威夷之旅。\",\n\t\"platformergpt\": \"平台 GPT 🎮\",\n\t\"researchgpt\": \"研究 GPT 📜\",\n\t\"travelgpt\": \"旅遊 GPT 🌴\",\n\t\"web-search\": \"網路搜尋\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/drawer.json",
    "content": "{\n\t\"ACCOUNT\": \"帳戶\",\n\t\"HELP_BUTTON\": \"協助\",\n\t\"MY_AGENTS\": \"我的AI機器人\",\n\t\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\": \"在顯示任何內容之前，您需要建立和儲存第一個AI機器人！\",\n\t\"SETTINGS_BUTTON\": \"設定\",\n\t\"SIGN_IN\": \"登入\",\n\t\"SIGN_IN_NOTICE\": \"請登入已儲存您的AI機器人並管理您的帳戶！\",\n\t\"SIGN_OUT\": \"登出\",\n\t\"SUPPORT_BUTTON\": \"支持\",\n\t\"USER_IMAGE\": \"使用者圖片\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/errors.json",
    "content": "{\n  \"ERROR_ACCESSING_OPENAI_API_KEY\": \"錯誤：在連結 OpenAI API 時執行錯誤。請檢查您的 API 金鑰或稍後再試。\",\n  \"ERROR_ADDING_ADDITIONAL_TASKS\": \"錯誤：增加其他任務時出錯。可能因為我們的模型無法處理您的結果，繼續中...\",\n  \"RATE_LIMIT_EXCEEDED\": \"超過最高服務次數。請減少服務次數...😅\",\n  \"AGENT_MAXED_OUT_LOOPS\": \"此AI機器人以達循環次數上限。為了節省您的荷包，此AI正在停止執行...您可以在更多設定中調整循環次數上限。\",\n  \"DEMO_LOOPS_REACHED\": \"很抱歉，因為這是一個Demo程式，所以我們無法讓機器人運作太長。備註：如果您想運作更長的時間，請在設定中提供自己的 API 金鑰。停止中...\",\n  \"AGENT_MANUALLY_SHUT_DOWN\": \"機器人已手動關閉。\",\n  \"ALL_TASKS_COMPLETETD\": \"所以任務已完成。停止中...\",\n  \"ERROR_API_KEY_QUOTA\": \"錯誤： OpenAI API 金鑰錯誤。您已超出使用額度，請檢查您的方案及付費資訊。\",\n  \"ERROR_OPENAI_API_KEY_NO_GPT4\": \"錯誤：您的 API 金鑰沒有 GPT-4 使用權限。您必須先加入 OpenAI 的等候清單。（這和 ChatGPT Plus 不同）\",\n  \"ERROR_RETRIEVE_INITIAL_TASKS\": \"錯誤：尋找初始任務數列錯誤。請重試、將目標寫得更加清楚，或修改目標以符合我們的模型政策。停止中...\",\n  \"INVALID_OPENAI_API_KEY\": \"錯誤：OpenAI API 金鑰無效\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/help.json",
    "content": "{\n\t\"AGENTGPT_DOCUMENTATION\": \"AgentGPT 的文件\",\n\t\"FOLLOW_THE_JOURNEY\": \"請跟隨以下流程：\",\n\t\"INTERACTION_WITH_WEBSITES_AND_PEOPLE\": \"與網站和人互動 👨‍👩‍👦\",\n\t\"INTRODUCING_AGENTGPT\": \"允許設定集部署自主AI機器人以及將其命名以讓他追求任何能想像的目標。他將會通過思考、執行任務並從結果中學習來實現目標 🚀\",\n\t\"LONG_TERM_MEMORY\": \"長期記憶 🧠\",\n\t\"PLATFORM_BETA_DESCRIPTION\": \"此平台目前處於beta試用版，我們正在處理以下內容：\",\n\t\"TO_LEARN_MORE_ABOUT_AGENTGPT\": \"要了解有關 AgentGPT、其產品路線圖、常見問題等的更多資訊，請點擊\",\n\t\"WEB_BROWSING\": \"網頁瀏覽 🌐\",\n\t\"WELCOME_TO_AGENT_GPT\": \"歡迎使用AgentGPT\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/indexPage.json",
    "content": "{\n  \"BETA\": \"Beta試用版\",\n  \"HEADING_DESCRIPTION\": \"在瀏覽器中編譯、配置並安裝自主AI機器人。\",\n  \"AGENT_NAME\": \"名稱\",\n  \"LABEL_AGENT_GOAL\": \"目標\",\n  \"PLACEHOLDER_AGENT_GOAL\": \"讓世界變個更美好\",\n  \"BUTTON_DEPLOY_AGENT\": \"執行AI機器人\",\n  \"BUTTON_STOP_AGENT\": \"停止AI機器人\"\n}\n"
  },
  {
    "path": "next/public/locales/zhtw/languages.json",
    "content": "{\n    \"ENGLISH\": \"英語\",\n    \"FRENCH\": \"法語\",\n    \"SPANISH\": \"西班牙語\",\n    \"GERMAN\": \"德語\",\n    \"JAPANESE\": \"日語\",\n    \"KOREAN\": \"韓語\",\n    \"CHINESE\": \"中文\",\n    \"PORTUGEES\": \"葡萄牙語\",\n    \"ITALIAN\": \"義大利語\",\n    \"DUTCH\": \"荷蘭語\",\n    \"POLSKI\": \"波蘭語\",\n    \"HUNGARIAN\": \"匈牙利語\",\n    \"ROMANIAN\": \"羅馬尼亞語\",\n    \"SLOVAK\": \"斯洛伐克語\"\n}"
  },
  {
    "path": "next/public/locales/zhtw/settings.json",
    "content": "{\n\t\"ADVANCED_SETTINGS\": \"進階設定\",\n\t\"API_KEY\": \"API金鑰\",\n\t\"AUTOMATIC_MODE\": \"自動模式\",\n\t\"AUTOMATIC_MODE_DESCRIPTION\": \"（初始設定）：AI機器人自動執行每個任務。\",\n\t\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\": \"控制每個API服務中使用的token最大數量（較高的值會產生更詳細的回饋，但成本會更高）。\",\n\t\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\": \"控制AI執行的大循環次數（較高的值會使用更多API服務）。\",\n\t\"GET_YOUR_OWN_APIKEY\": \"獲得您自己的 OpenAI API 金鑰\",\n\t\"HERE\": \"這裡\",\n\t\"HERE_YOU_CAN_ADD_YOUR_OPENAI_API_KEY\": \"您可以在這裡輸入OpenAI API金鑰。儘管這會使用您自己的OpenAI付費功能，但將會為您增加使用AgentGPT的權限！並且，您還可以選擇OpenAI提供的任一模型。\",\n\t\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\": \"較高的值會增加輸出的隨機性，較低的值會增加的輸出的單一及集中性。\",\n\t\"INFO_TO_USE_GPT4\": \"如果需要使用GPT-4模型，您還須提供GPT-4的API金鑰。您可以在此處申請\",\n\t\"INVALID_OPENAI_API_KEY\": \"無效的 OpenAI API 金鑰！\",\n\t\"LABEL_MODE\": \"模式\",\n\t\"LABEL_MODEL\": \"模型\",\n\t\"LANG\": \"語言\",\n\t\"LINK\": \"獲得API金鑰\",\n\t\"LOOP\": \"循環\",\n\t\"MUST_CONNECT_CREDIT_CARD\": \"注意：您必須將信用卡連接到您的帳戶\",\n\t\"NOTE_API_KEY_USAGE\": \"此金鑰僅在當前瀏覽器對話中使用。\",\n\t\"NOTE_TO_GET_OPENAI_KEY\": \"注意：如果要獲取金鑰，請註冊OpenAI帳號並瀏覽一下網址：\",\n\t\"PAUSE\": \"暫停\",\n\t\"PAUSE_MODE\": \"暫停模式\",\n\t\"PAUSE_MODE_DESCRIPTION\": \"AI機器下會在執行每項任務後暫停\",\n\t\"PENAI_API_KEY\": \"無效的 API 金鑰\",\n\t\"PLAY\": \"播放\",\n\t\"SETTINGS_DIALOG_HEADER\": \"設定⚙\",\n\t\"SUBSCRIPTION_WILL_NOT_WORK\": \"（ChatGPT Plus訂閱帳號無法使用）\",\n\t\"TEMPERATURE\": \"溫度\",\n\t\"TOKENS\": \"token\"\n}\n"
  },
  {
    "path": "next/public/robots.txt",
    "content": "User-agent: *\nAllow: /"
  },
  {
    "path": "next/public/site.webmanifest",
    "content": "{\n  \"name\": \"Agent-GPT\",\n  \"short_name\": \"Agent-GPT\",\n  \"icons\": [\n    {\n      \"src\": \"/android-chrome-192x192.png\",\n      \"sizes\": \"192x192\",\n      \"type\": \"image/png\"\n    },\n    {\n      \"src\": \"/android-chrome-512x512.png\",\n      \"sizes\": \"512x512\",\n      \"type\": \"image/png\"\n    }\n  ],\n  \"theme_color\": \"#ffffff\",\n  \"background_color\": \"#ffffff\",\n  \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "next/src/components/Accordion.tsx",
    "content": "import { Disclosure as AccordionPrimitive } from \"@headlessui/react\";\nimport { FaChevronDown } from \"react-icons/fa\";\n\ninterface AccordionProps {\n  child: React.ReactNode;\n  name: string;\n}\n\nconst Accordion = ({ child, name }: AccordionProps) => {\n  return (\n    <AccordionPrimitive>\n      {({ open }) => (\n        <>\n          <AccordionPrimitive.Button className=\"border:black delay-50 flex w-full items-center justify-between rounded-xl bg-[#4a4a4a] px-3 py-2 text-sm tracking-wider outline-0 transition-all placeholder:text-white/20 hover:border-[#1E88E5]/40 hover:bg-[#6b6b6b] focus:border-[#1E88E5] focus-visible:ring  md:text-lg\">\n            {name}\n            <FaChevronDown\n              className={`${open ? \"rotate-180 transform\" : \"\"} h-5 w-5`}\n            />\n          </AccordionPrimitive.Button>\n          <AccordionPrimitive.Panel className=\"rounded-xl bg-[#4a4a4a] p-2\">\n            {child}\n          </AccordionPrimitive.Panel>\n        </>\n      )}\n    </AccordionPrimitive>\n  );\n};\n\nexport default Accordion;\n"
  },
  {
    "path": "next/src/components/AppHead.tsx",
    "content": "import Head from \"next/head\";\n\nconst AppHead = ({ title, ogTitle }: { title?: string; ogTitle?: string }) => {\n  // Do not translate. Head attributes won't have access to i18n.\n  const description = \"Assemble, configure, and deploy autonomous AI Agents in your browser.\";\n  return (\n    <Head>\n      <title>{title ?? \"AgentGPT\"}</title>\n      <meta name=\"description\" content={description} />\n      <meta name=\"twitter:site\" content=\"@ReworkdAI\" />\n      <meta name=\"twitter:card\" content=\"summary_large_image\" />\n      <meta name=\"twitter:title\" content={title ?? \"AgentGPT 🤖\"} />\n      <meta name=\"twitter:description\" content={description} />\n      <meta name=\"twitter:image\" content=\"https://agentgpt.reworkd.ai/banner.png\" />\n      <meta name=\"twitter:image:width\" content=\"1280\" />\n      <meta name=\"twitter:image:height\" content=\"640\" />\n      <meta property=\"og:title\" content={ogTitle ?? \"AgentGPT: Autonomous AI in your browser 🤖\"} />\n      <meta property=\"og:description\" content={description} />\n      <meta property=\"og:url\" content=\"https://agentgpt.reworkd.ai/\" />\n      <meta property=\"og:image\" content=\"https://agentgpt.reworkd.ai/banner.png\" />\n      <meta property=\"og:image:width\" content=\"1280\" />\n      <meta property=\"og:image:height\" content=\"640\" />\n      <meta property=\"og:type\" content=\"website\" />\n      <meta name=\"google-site-verification\" content=\"sG4QDkC8g2oxKSopgJdIe2hQ_SaJDaEaBjwCXZNkNWA\" />\n\n      <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\" />\n      <link rel=\"mask-icon\" href=\"/favicon.svg\" />\n    </Head>\n  );\n};\n\nexport default AppHead;\n"
  },
  {
    "path": "next/src/components/AppTitle.tsx",
    "content": "import React from \"react\";\n\nimport BannerBadge from \"./BannerBadge\";\n\nconst AppTitle = () => {\n  return (\n    <div id=\"title\" className=\"relative flex flex-col items-center\">\n      <div className=\"flex flex-row items-start\">\n        <span\n          className=\"text-4xl font-bold text-slate-12 xs:text-5xl sm:text-7xl\"\n          style={{\n            textShadow: \"0px 5px 5px rgba(0, 0, 0, 0.1)\",\n          }}\n        >\n          AgentGPT\n        </span>\n      </div>\n      <div className=\"mt-3 text-center font-mono text-[0.7em] font-bold text-white\">\n        <div>\n          <BannerBadge\n            className=\"md:hidden\"\n            onClick={() => {\n              window.open(\"https://6h6bquxo5g1.typeform.com/to/qscfsOf1\", \"_blank\");\n            }}\n          >\n            Automate your business with Agents\n          </BannerBadge>\n        </div>\n        <div\n          className=\"hidden md:flex\"\n          onClick={() => {\n            window.open(\"https://6h6bquxo5g1.typeform.com/to/qscfsOf1\", \"_blank\");\n          }}\n        >\n          <BannerBadge>Interested in automating businesses with AI Agents? Apply here</BannerBadge>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport default AppTitle;\n"
  },
  {
    "path": "next/src/components/Badge.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\ninterface BadgeProps {\n  className?: string;\n  colorClass?: string;\n  children: React.ReactNode;\n}\n\nconst Badge = ({ className, colorClass, children }: BadgeProps) => {\n  return (\n    <div\n      className={clsx(\n        colorClass || \"bg-blue-600\",\n        className,\n        \"rounded-full px-2 py-1 text-xs font-semibold text-gray-100 transition-all hover:scale-110 sm:px-3 sm:py-1 sm:text-sm\"\n      )}\n    >\n      {children}\n    </div>\n  );\n};\n\nexport default Badge;\n"
  },
  {
    "path": "next/src/components/BannerBadge.tsx",
    "content": "import clsx from \"clsx\";\nimport type { PropsWithChildren } from \"react\";\nimport React from \"react\";\nimport { FaChevronRight } from \"react-icons/fa\";\n\ntype BadgeProps = PropsWithChildren<React.AnchorHTMLAttributes<HTMLAnchorElement>>;\n\nconst BannerBadge = ({ children, className, ...props }: BadgeProps) => (\n  <div\n    className={clsx(\n      \"rounded-full bg-gradient-to-tl from-[#A02BFE] via-[#02FCF1] to-[#A02BFE] p-[1px] subpixel-antialiased\",\n      className\n    )}\n  >\n    <a\n      className=\"animate-border-pulse py group relative flex w-max cursor-pointer items-center gap-2 rounded-full bg-black px-4 py-2 text-xs text-white\"\n      {...props}\n    >\n      <span>{children}</span>\n      <FaChevronRight\n        size={10}\n        className=\"font-thin text-gray-400 transition-transform duration-300 group-hover:translate-x-1\"\n      />\n    </a>\n  </div>\n);\n\nexport default BannerBadge;\n"
  },
  {
    "path": "next/src/components/Button.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ForwardedRef } from \"react\";\nimport React, { forwardRef, useState } from \"react\";\n\nimport Loader from \"./loader\";\n\nexport interface ButtonProps {\n  type?: \"button\" | \"submit\" | \"reset\";\n  className?: string;\n  icon?: React.ReactNode;\n  children?: React.ReactNode;\n  loader?: boolean;\n  disabled?: boolean;\n  ping?: boolean;\n  enabledClassName?: string;\n  onClick?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n}\n\nconst Button = forwardRef((props: ButtonProps, ref: ForwardedRef<HTMLButtonElement>) => {\n  const [loading, setLoading] = useState(false);\n  const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n    if (props.loader == true) setLoading(true);\n\n    try {\n      void Promise.resolve(props.onClick?.(e)).then();\n    } catch (e) {\n      setLoading(false);\n    }\n  };\n\n  return (\n    <button\n      ref={ref}\n      type={props.type}\n      disabled={loading || props.disabled}\n      className={clsx(\n        \"relative rounded-lg border-2 border-black/20 px-4 py-1 font-bold text-white transition-all duration-300 sm:px-10 sm:py-3\",\n        props.disabled && \"cursor-not-allowed border-white/10 bg-slate-9 text-white\",\n        props.disabled ||\n          \"cursor-pointer bg-[#1E88E5]/80 text-white hover:bg-[#0084f7] hover:shadow-lg\",\n        props.disabled || props.enabledClassName,\n        props.className\n      )}\n      onClick={onClick}\n    >\n      <div className=\"relative\">\n        {loading && (\n          <Loader className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform\" />\n        )}\n        <div\n          className={clsx(\"flex h-full w-full items-center justify-center\", loading && \"opacity-0\")}\n        >\n          {props.icon ? <div className=\"mr-2\">{props.icon}</div> : null}\n          {props.children}\n        </div>\n      </div>\n    </button>\n  );\n});\n\nButton.displayName = \"Button\";\nexport default Button;\n"
  },
  {
    "path": "next/src/components/Globe.tsx",
    "content": "import type { COBEOptions } from \"cobe\";\nimport createGlobe from \"cobe\";\nimport type { MutableRefObject } from \"react\";\nimport React, { useEffect, useRef } from \"react\";\n\nexport default function Globe(): JSX.Element {\n  const canvasRef: MutableRefObject<HTMLCanvasElement | null> = useRef(null);\n\n  const size = 700;\n  useEffect(() => {\n    if (!canvasRef.current) return;\n    let phi = 0;\n\n    const globeSettings: COBEOptions = {\n      devicePixelRatio: 2,\n      width: size * 2,\n      height: size * 2,\n      phi: 0,\n      theta: 0,\n      dark: 0,\n      diffuse: 1.2,\n      mapSamples: 16000,\n      mapBrightness: 6,\n      baseColor: [1, 1, 1],\n      markerColor: [1, 1, 0],\n      glowColor: [0.757, 0.784, 0.804],\n      markers: [],\n      onRender: (state) => {\n        // Called on every animation frame.\n        // `state` will be an empty object, return updated params.\n        state.phi = phi;\n        phi += 0.001;\n      },\n    };\n\n    const globe = createGlobe(canvasRef.current, globeSettings);\n\n    return () => {\n      if (canvasRef.current && globe) {\n        globe.destroy();\n      }\n    };\n  }, []);\n\n  return <canvas ref={canvasRef} style={{ width: size, height: size, aspectRatio: \"1\" }} />;\n}\n"
  },
  {
    "path": "next/src/components/GlowWrapper.tsx",
    "content": "import type { ReactNode } from \"react\";\nimport clsx from \"clsx\";\n\ntype GlowWrapperProps = {\n  children: ReactNode;\n  className?: string;\n};\n\nconst GlowWrapper = ({ children, className }: GlowWrapperProps) => {\n  return (\n    <div className=\"relative inline-flex items-center justify-center\">\n      <div\n        className={clsx(\n          className || \"opacity-50\",\n          \"absolute -inset-1 rounded-full bg-gradient-to-tr from-[#A02BFE] to-[#1152FA] blur-lg transition-all duration-1000\"\n        )}\n      />\n      <div className=\"relative z-10\">{children}</div>\n    </div>\n  );\n};\n\nexport default GlowWrapper;\n"
  },
  {
    "path": "next/src/components/HeroCard.tsx",
    "content": "import type { ReactNode } from \"react\";\nimport React from \"react\";\n\nimport GlowWrapper from \"./GlowWrapper\";\nimport SparkleIcon from \"../../public/icons/sparkle-default-regular.svg\";\n\ntype HeroCardProps = {\n  title: string;\n  subtitle: string;\n  leftIcon: ReactNode;\n};\n\nconst HeroCard: React.FC<HeroCardProps> = ({ title, subtitle, leftIcon }) => {\n  return (\n    <div className=\"border-gradient -z-10 flex max-h-16 w-72 flex-row items-center justify-center rounded-full p-3\">\n      <div className=\"mr-auto flex items-center gap-3\">\n        <div>{leftIcon}</div>\n        <div className=\"flex flex-col font-inter leading-6 tracking-normal text-transparent\">\n          <h2 className=\"ml-2s bg-gradient-to-r from-white to-white/70 bg-clip-text text-[12px] font-semibold  md:text-[15px]\">\n            {title}\n          </h2>\n          <p className=\"bg-gradient-to-r from-white/80 via-white/60 via-[53.18%] to-white/50 bg-clip-text text-[11px] font-medium md:text-[14px]\">\n            {subtitle}\n          </p>\n        </div>\n      </div>\n      <GlowWrapper className=\"opacity-60\">\n        <div\n          className=\"group relative flex h-8 w-8 items-center justify-center rounded-full bg-white\"\n          onClick={() => {\n            window.open(\"https://6h6bquxo5g1.typeform.com/to/qscfsOf1\", \"_blank\");\n          }}\n        >\n          <SparkleIcon className=\"transition-transform group-hover:scale-110\" />\n        </div>\n      </GlowWrapper>\n    </div>\n  );\n};\n\nexport default HeroCard;\n"
  },
  {
    "path": "next/src/components/Input.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ChangeEvent, KeyboardEvent, ReactNode, RefObject } from \"react\";\n\nimport Label from \"./Label\";\nimport type { toolTipProperties } from \"../types\";\n\ntype InputElement = HTMLInputElement | HTMLTextAreaElement;\n\ninterface InputProps {\n  small?: boolean; // Will lower padding and font size. Currently only works for the default input\n  left?: ReactNode;\n  value: string | number | undefined;\n  onChange: (e: ChangeEvent<InputElement>) => void;\n  placeholder?: string;\n  disabled?: boolean;\n  type?: string;\n  subType?: string;\n  attributes?: { [key: string]: string | number | string[] }; // attributes specific to input type\n  toolTipProperties?: toolTipProperties;\n  inputRef?: RefObject<InputElement>;\n  onKeyDown?: (e: KeyboardEvent<InputElement>) => void;\n}\n\nconst Input = (props: InputProps) => {\n  const isTypeTextArea = () => {\n    return props.type === \"textarea\";\n  };\n\n  return (\n    <div className=\"items-left z-5 flex h-fit w-full flex-col rounded-xl text-lg text-slate-12 md:flex-row md:items-center\">\n      {props.left && (\n        <Label left={props.left} type={props.type} toolTipProperties={props.toolTipProperties} />\n      )}\n      {isTypeTextArea() ? (\n        <textarea\n          className={clsx(\n            \"delay-50 h-15 w-full resize-none rounded-xl border-2 border-slate-7 bg-slate-1 p-2 text-sm tracking-wider text-slate-12 outline-none transition-all selection:bg-sky-300 placeholder:text-slate-8 hover:border-sky-200 focus:border-sky-400 sm:h-20 md:text-lg\",\n            props.disabled && \"cursor-not-allowed\",\n            props.left && \"md:rounded-l-none\",\n            props.small && \"text-sm sm:py-[0]\"\n          )}\n          ref={props.inputRef as RefObject<HTMLTextAreaElement>}\n          placeholder={props.placeholder}\n          value={props.value}\n          onChange={props.onChange}\n          disabled={props.disabled}\n          onKeyDown={props.onKeyDown}\n          {...props.attributes}\n        />\n      ) : (\n        <input\n          className={clsx(\n            \"w-full rounded-xl border-2 border-slate-7 bg-slate-1 p-2 py-1 text-sm tracking-wider text-slate-12 outline-none transition-all duration-200 selection:bg-sky-300 placeholder:text-slate-8 hover:border-sky-200 focus:border-sky-400 sm:py-3 md:text-lg\",\n            props.disabled && \"cursor-not-allowed\",\n            props.left && \"md:rounded-l-none\",\n            props.small && \"text-sm sm:py-[0]\"\n          )}\n          ref={props.inputRef as RefObject<HTMLInputElement>}\n          placeholder={props.placeholder}\n          type={props.type}\n          value={props.value}\n          onChange={props.onChange}\n          disabled={props.disabled}\n          onKeyDown={props.onKeyDown}\n          {...props.attributes}\n        />\n      )}\n    </div>\n  );\n};\n\nexport default Input;\n"
  },
  {
    "path": "next/src/components/Label.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\nimport Tooltip from \"./Tooltip\";\nimport type { toolTipProperties } from \"../types\";\n\ninterface LabelProps {\n  left?: React.ReactNode;\n  type?: string;\n  toolTipProperties?: toolTipProperties;\n}\n\nconst Label = ({ type, left, toolTipProperties }: LabelProps) => {\n  const isTypeTextArea = () => {\n    return type === \"textarea\";\n  };\n\n  return (\n    <Tooltip\n      child={\n        <div\n          className={clsx(\n            \"center flex min-w-[8em] items-center rounded-xl md:border-2\",\n            type !== \"range\" && \"md:rounded-r-none md:border-r-0 md:border-slate-7\",\n            \"py-2 text-sm font-semibold tracking-wider text-slate-10 transition-all md:bg-slate-4 md:py-3 md:pl-3 md:text-lg\",\n            isTypeTextArea() && \"md:h-20\"\n          )}\n        >\n          {left}\n        </div>\n      }\n      sideOffset={0}\n      toolTipProperties={toolTipProperties}\n    ></Tooltip>\n  );\n};\n\nexport default Label;\n"
  },
  {
    "path": "next/src/components/Menu.tsx",
    "content": "import { Menu as MenuPrimitive, Transition } from \"@headlessui/react\";\nimport clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport { Fragment } from \"react\";\nimport { FaChevronDown } from \"react-icons/fa\";\n\ninterface MenuProps {\n  icon?: ReactNode;\n  chevron?: boolean;\n  name?: string;\n  buttonPosition?: \"top\" | \"bottom\";\n  items: JSX.Element[];\n}\n\nfunction Menu({ icon, name, items, chevron, buttonPosition = \"top\" }: MenuProps) {\n  return (\n    <MenuPrimitive>\n      <div className=\"relative\">\n        <MenuPrimitive.Button className=\"flex h-8 items-center gap-1 rounded-lg bg-slate-1 p-2 font-bold shadow-depth-1 hover:bg-slate-3\">\n          <div>{icon}</div>\n          {name && <p className=\"text-gray/50 font-mono text-sm\">{name}</p>}\n          {chevron && <FaChevronDown size={15} className=\"ml-2\" />}\n        </MenuPrimitive.Button>\n        <MenuItems buttonPosition={buttonPosition} items={items} />\n      </div>\n    </MenuPrimitive>\n  );\n}\n\ntype MenuItemsProps = {\n  buttonPosition: \"top\" | \"bottom\";\n  items: JSX.Element[];\n  show?: boolean;\n};\n\nexport const MenuItems = ({ buttonPosition, items, show }: MenuItemsProps) => {\n  return (\n    <Transition\n      show={show ? true : undefined}\n      enter=\"transition duration-100 ease-out\"\n      enterFrom=\"transform scale-95 opacity-0\"\n      enterTo=\"transform scale-100 opacity-100\"\n      leave=\"transition duration-75 ease-out\"\n      leaveFrom=\"transform scale-100 opacity-100\"\n      leaveTo=\"transform scale-95 opacity-0\"\n    >\n      <MenuPrimitive.Items\n        className={clsx(\n          \"background-color-3 absolute right-0 z-20 max-h-48  w-fit min-w-full overflow-hidden rounded-xl shadow-xl\",\n          buttonPosition === \"top\" ? \"top-full mt-1\" : \"bottom-full mb-9\"\n        )}\n      >\n        {items.map((item, i) => {\n          return (\n            <MenuPrimitive.Item key={i} as={Fragment}>\n              <div className=\"w-full\">{item}</div>\n            </MenuPrimitive.Item>\n          );\n        })}\n      </MenuPrimitive.Items>\n    </Transition>\n  );\n};\n\nexport default Menu;\n"
  },
  {
    "path": "next/src/components/NavBar.tsx",
    "content": "import { Disclosure } from \"@headlessui/react\";\nimport clsx from \"clsx\";\nimport Image from \"next/image\";\nimport { useRouter } from \"next/router\";\nimport { useState } from \"react\";\nimport { FaBars, FaChevronRight, FaTimes } from \"react-icons/fa\";\n\nimport GlowWrapper from \"./GlowWrapper\";\nimport CycleIcons from \"./motions/CycleIcons\";\nimport FadeIn from \"./motions/FadeIn\";\nimport PrimaryButton from \"./PrimaryButton\";\nimport BlogsIcon from \"../../public/icons/icon-blogs.svg\";\nimport DocsIcon from \"../../public/icons/icon-docs.svg\";\nimport GithubIcon from \"../../public/icons/icon-github.svg\";\nimport HomeIcon from \"../../public/icons/icon-home.svg\";\nimport PricingIcon from \"../../public/icons/icon-pricing.svg\";\n\nconst navigation = [\n  { name: \"Home\", href: \"/home\", icon: <HomeIcon /> },\n  { name: \"Blog\", href: \"/blog\", icon: <BlogsIcon /> },\n  { name: \"Pricing\", href: \"https://agentgpt.reworkd.ai/plan\", icon: <PricingIcon /> },\n  {\n    name: \"Github\",\n    href: \"https://github.com/reworkd/AgentGPT\",\n    icon: <GithubIcon />,\n  },\n  { name: \"Docs\", href: \"https://reworkd.ai/docs\", icon: <DocsIcon /> },\n];\n\nexport default function NavBar() {\n  const router = useRouter();\n  const currentIndex = navigation.findIndex(\n    (nav) => router.pathname.includes(nav.href) || router.pathname === nav.href\n  );\n  const [hoveredButtonIndex, setHoveredButtonIndex] = useState(0);\n\n  return (\n    <FadeIn duration={3}>\n      <Disclosure as=\"nav\" className=\"z-50 w-full bg-transparent text-white\">\n        {({ open }) => (\n          <>\n            <div className=\"align-center flex h-16 flex-row justify-between\">\n              <div className=\"flex flex-shrink-0 cursor-pointer items-center lg:flex-1\">\n                <Image\n                  src=\"/logos/dark-default-solid.svg\"\n                  width=\"25\"\n                  height=\"25\"\n                  alt=\"Reworkd AI\"\n                  className=\"mb-1 mr-2 invert-0\"\n                />\n                <span className=\"text-xl font-light tracking-wider\">Reworkd</span>\n              </div>\n              <div className=\"hidden flex-1 items-center justify-center xmd:flex\">\n                <div className=\"border-gradient flex h-[42px] items-center self-center overflow-hidden rounded-full bg-opacity-5 px-2 py-1 backdrop-blur-lg\">\n                  <CycleIcons\n                    currentIndex={currentIndex}\n                    hoveredItemIndex={hoveredButtonIndex}\n                    icons={navigation.map((nav) => nav.icon)}\n                  />\n                  {navigation.map((item, i) => (\n                    <a\n                      key={item.name}\n                      href={item.href}\n                      className={clsx(\n                        \"after-gradient relative flex flex-col items-center justify-center p-2 px-4 text-center font-inter text-sm tracking-normal text-white transition-colors duration-700 before:absolute before:-bottom-[20px] before:-z-20 before:h-6 before:w-12 before:bg-white/60 before:blur-lg before:transition-opacity before:duration-700 after:absolute after:-bottom-[2.25px] after:h-[1px] after:w-16 after:px-2 after:transition-opacity after:duration-700 hover:text-white\",\n                        currentIndex !== i && \"text-white/50 before:opacity-0 after:opacity-0\"\n                      )}\n                      onMouseEnter={() => setHoveredButtonIndex(i)}\n                      onMouseLeave={() => setHoveredButtonIndex(0)}\n                    >\n                      {item.name}\n                    </a>\n                  ))}\n                </div>\n              </div>\n              <div className=\"hidden justify-end gap-2 xmd:flex sm:items-center lg:flex-1\">\n                <GlowWrapper className=\"opacity-40\">\n                  <PrimaryButton\n                    onClick={() => {\n                      window.open(\"https://6h6bquxo5g1.typeform.com/to/qscfsOf1\", \"_blank\");\n                    }}\n                  >\n                    <>\n                      <span>Join the Waitlist</span>\n                      <FaChevronRight\n                        size=\"12\"\n                        className=\"text-gray-700 transition-transform group-hover:translate-x-1\"\n                      />\n                    </>\n                  </PrimaryButton>\n                </GlowWrapper>\n              </div>\n              <div className=\"-mr-2 flex items-center xmd:hidden\">\n                {/* Mobile menu button */}\n                <Disclosure.Button className=\"inline-flex items-center justify-center rounded-md p-2 text-white hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\">\n                  <span className=\"sr-only\">Open main menu</span>\n                  {open ? (\n                    <FaTimes className=\"block h-6 w-6\" aria-hidden=\"true\" />\n                  ) : (\n                    <FaBars className=\"block h-6 w-6\" aria-hidden=\"true\" />\n                  )}\n                </Disclosure.Button>\n              </div>\n            </div>\n\n            <Disclosure.Panel className=\"xmd:hidden\">\n              <div className=\"space-y-1 pb-3 pt-2\">\n                {navigation.map((item) => (\n                  <Disclosure.Button\n                    key={item.name}\n                    as=\"a\"\n                    href={item.href}\n                    className=\"block border-l-4 border-transparent py-2 pl-3 pr-4 text-base text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800\"\n                  >\n                    {item.name}\n                  </Disclosure.Button>\n                ))}\n              </div>\n            </Disclosure.Panel>\n          </>\n        )}\n      </Disclosure>\n    </FadeIn>\n  );\n}\n"
  },
  {
    "path": "next/src/components/Ping.tsx",
    "content": "import React from \"react\";\n\nconst Ping = ({ color }: { color: \"blue\" | \"white\" }) => {\n  const colorClasses = {\n    primary: color == \"blue\" ? \"bg-sky-400\" : \"bg-white\",\n    secondary: color == \"blue\" ? \"bg-sky-400\" : \"bg-white\",\n  };\n\n  return (\n    <span className=\"absolute right-[-3px] top-[-3px] flex h-3 w-3\">\n      <span\n        className={`absolute inline-flex h-full w-full animate-ping rounded-full ${colorClasses.secondary} opacity-75`}\n      ></span>\n      <span\n        className={`relative inline-flex h-3 w-3 rounded-full opacity-90 ${colorClasses.primary}`}\n      ></span>\n    </span>\n  );\n};\n\nexport default Ping;\n"
  },
  {
    "path": "next/src/components/PrimaryButton.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport React from \"react\";\n\nimport Button from \"../ui/button\";\n\ntype PrimaryButtonProps = {\n  className?: string;\n  children: ReactNode | string;\n  icon?: React.ReactNode;\n  onClick?: () => void | Promise<void>;\n};\n\nexport default function PrimaryButton({ children, onClick, icon, className }: PrimaryButtonProps) {\n  return (\n    <Button\n      onClick={onClick}\n      className={clsx(\n        \"group rounded-full border border-black bg-white text-black transition duration-300 ease-in-out hover:hover:bg-neutral-200 focus-visible:bg-white/90 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-white/30\",\n        className\n      )}\n    >\n      {icon}\n      {children}\n    </Button>\n  );\n}\n"
  },
  {
    "path": "next/src/components/QuestionInput.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\nimport { FaArrowRight } from \"react-icons/fa\";\n\ninterface Props extends React.InputHTMLAttributes<HTMLInputElement> {\n  name: string;\n  attributes?: { [key: string]: string | number | string[] };\n  icon?: React.ReactNode;\n  disabled?: boolean;\n  handleFocusChange?: (focused: boolean) => void;\n  onSubmit: () => void;\n}\n\n// Test stylized input component\nconst QuestionInput = (props: Props) => {\n  return (\n    <div className=\"relative flex flex-col\">\n      <div className=\"flex flex-grow flex-row items-center gap-1\">\n        <input\n          type={props.type}\n          name={props.name}\n          id={props.name}\n          className=\"placeholder:text-color-tertiary w-full rounded-full border-2 border-slate-6 bg-slate-1 p-4 text-slate-12 caret-purple-400 ring-0 transition-colors duration-300 selection:bg-purple-300 hover:border-purple-200 focus:border-purple-400 focus:outline-0 focus:ring-0  sm:leading-6\"\n          placeholder={props.placeholder}\n          value={props.value}\n          onChange={props.onChange}\n          disabled={props.disabled}\n          onFocus={() => props.handleFocusChange && props.handleFocusChange(true)}\n          onBlur={() => props.handleFocusChange && props.handleFocusChange(false)}\n          {...{ \"aria-describedby\": `${props.name}-description` }}\n          {...props.attributes}\n        />\n        <div\n          className={clsx(\n            \"absolute right-2 rounded-full p-3 text-white transition-colors duration-300\",\n            props.value === \"\"\n              ? \"cursor-not-allowed bg-slate-8\"\n              : \"cursor-pointer bg-purple-300 hover:bg-purple-400\"\n          )}\n          onClick={props.onSubmit}\n        >\n          <FaArrowRight size={20} />\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport default QuestionInput;\n"
  },
  {
    "path": "next/src/components/Switch.tsx",
    "content": "import * as SwitchPrimitive from \"@radix-ui/react-switch\";\nimport { clsx } from \"clsx\";\nimport React, { useEffect, useState } from \"react\";\n\ninterface SwitchProps {\n  value: boolean;\n  disabled?: boolean;\n  onChange: (checked: boolean) => void;\n}\n\nconst Switch = ({ value, disabled = false, onChange }: SwitchProps) => {\n  const [checked, setChecked] = useState(false);\n\n  // Due to SSR, we should only change the internal state after the initial render\n  useEffect(() => {\n    setChecked(value);\n  }, [value]);\n\n  const handleChange = (checked: boolean) => {\n    onChange(checked);\n  };\n\n  return (\n    <SwitchPrimitive.Root\n      className={clsx(\n        \"group\",\n        \"radix-state-checked:bg-sky-600 radix-state-unchecked:bg-zinc-500\",\n        \"relative inline-flex h-4 w-7 flex-shrink-0 rounded-full border border-transparent transition-colors duration-200 ease-in-out\",\n        \"focus:outline-none focus-visible:ring focus-visible:ring-sky-500 focus-visible:ring-opacity-75\",\n        disabled ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer \"\n      )}\n      disabled={disabled}\n      onCheckedChange={handleChange}\n      checked={checked}\n    >\n      <SwitchPrimitive.Thumb\n        className={clsx(\n          \"group-radix-state-checked:translate-x-3\",\n          \"group-radix-state-unchecked:translate-x-0\",\n          \"pointer-events-none inline-block h-3 w-3 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out\"\n        )}\n      />\n    </SwitchPrimitive.Root>\n  );\n};\n\nexport { Switch };\n"
  },
  {
    "path": "next/src/components/TextButton.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport React from \"react\";\n\nimport Button from \"../ui/button\";\n\ntype TextButtonProps = {\n  children: ReactNode | string;\n  icon?: ReactNode;\n  onClick?: () => void;\n  className?: string;\n};\nexport default function TextButton({ children, onClick, icon, className }: TextButtonProps) {\n  return (\n    <Button\n      onClick={onClick}\n      className={clsx(\n        \"group rounded-full bg-transparent text-neutral-400 transition duration-200 ease-in-out hover:bg-white/10 hover:text-white focus-visible:bg-neutral-900 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-neutral-500\",\n        className\n      )}\n    >\n      {icon}\n      {children}\n    </Button>\n  );\n}\n"
  },
  {
    "path": "next/src/components/Tooltip.tsx",
    "content": "import * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport React from \"react\";\n\nimport type { toolTipProperties } from \"../types\";\n\ninterface TooltipProps {\n  child: React.ReactNode;\n  toolTipProperties?: toolTipProperties;\n  style?: { [key: string]: string };\n  sideOffset: number;\n}\n\nconst Tooltip = ({\n  child,\n  toolTipProperties = { message: \"\", disabled: true },\n  style = { container: \"\" },\n  sideOffset,\n}: TooltipProps) => {\n  const { message, disabled } = toolTipProperties;\n  return (\n    <div className={style?.container}>\n      <TooltipPrimitive.Provider>\n        <TooltipPrimitive.Root delayDuration={0}>\n          <TooltipPrimitive.Trigger asChild>{child}</TooltipPrimitive.Trigger>\n          {disabled ? null : (\n            <TooltipPrimitive.Portal>\n              <TooltipPrimitive.Content\n                className=\"will-change animation-transform user-select-none z-40 w-3/5 rounded-sm bg-black px-3.5 py-2.5 text-white shadow-lg \"\n                sideOffset={sideOffset}\n              >\n                <span className=\"whitespace-pre-line\">{message}</span>\n                <TooltipPrimitive.Arrow className=\"fill-black\" />\n              </TooltipPrimitive.Content>\n            </TooltipPrimitive.Portal>\n          )}\n        </TooltipPrimitive.Root>\n      </TooltipPrimitive.Provider>\n    </div>\n  );\n};\n\nexport default Tooltip;\n"
  },
  {
    "path": "next/src/components/WindowButton.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\nimport Ping from \"./Ping\";\n\ntype WindowButtonProps = {\n  ping?: boolean; // Toggles the ping animation\n  onClick?: () => void;\n  icon: React.ReactNode;\n  text: string;\n  border?: boolean;\n};\n\nconst WindowButton = ({ ping, onClick, icon, text, border }: WindowButtonProps) => {\n  return (\n    <div\n      className={clsx(\n        \"relative flex h-8 cursor-pointer items-center gap-2 rounded-lg bg-slate-1 p-2 font-mono text-sm font-bold text-slate-12 transition-all hover:bg-slate-3\",\n        !border && \"rounded-none border-none\"\n      )}\n      onClick={onClick}\n    >\n      {ping ? <Ping color=\"blue\" /> : <></>}\n      {icon}\n      <p className=\"text-gray/50 font-mono\">{text}</p>\n    </div>\n  );\n};\n\nexport default WindowButton;\n"
  },
  {
    "path": "next/src/components/console/AgentControls.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\nimport { FaPause, FaPlay, FaStop, FaUndo } from \"react-icons/fa\";\nimport { ImSpinner2 } from \"react-icons/im\";\n\nimport type { AgentLifecycle } from \"../../services/agent/agent-run-model\";\nimport Button from \"../Button\";\n\ntype AgentControlsProps = {\n  disablePlay: boolean;\n  lifecycle: AgentLifecycle;\n  handlePlay: () => void;\n  handlePause: () => void;\n  handleStop: () => void;\n};\nconst AgentControls = ({\n  lifecycle,\n  disablePlay,\n  handlePlay,\n  handlePause,\n  handleStop,\n}: AgentControlsProps) => {\n  return (\n    <div className=\"flex gap-2\">\n      <Button ping={!disablePlay} disabled={disablePlay} onClick={handlePlay}>\n        {lifecycle === \"running\" && <ImSpinner2 className=\"animate-spin\" />}\n        {lifecycle === \"stopped\" && <FaUndo />}\n        {![\"running\", \"stopped\"].includes(lifecycle || \"\") && <FaPlay />}\n      </Button>\n      <Button\n        disabled={lifecycle !== \"running\"}\n        onClick={handlePause}\n        enabledClassName={clsx(\"bg-yellow-600 hover:bg-yellow-400\")}\n      >\n        {lifecycle === \"pausing\" ? <ImSpinner2 className=\"animate-spin\" /> : <FaPause />}\n      </Button>\n      <Button\n        disabled={lifecycle === \"offline\" || lifecycle == \"stopped\"}\n        onClick={handleStop}\n        enabledClassName={clsx(\"bg-red-600 hover:bg-red-400\")}\n      >\n        <FaStop />\n      </Button>\n    </div>\n  );\n};\n\nexport default AgentControls;\n"
  },
  {
    "path": "next/src/components/console/ChatMessage.tsx",
    "content": "import clsx from \"clsx\";\nimport { useTranslation } from \"next-i18next\";\nimport React, { useState } from \"react\";\nimport { FaCheck } from \"react-icons/fa\";\nimport { FiClipboard } from \"react-icons/fi\";\n\nimport MarkdownRenderer from \"./MarkdownRenderer\";\nimport SourceCard from \"./SourceCard\";\nimport type { Message } from \"../../types/message\";\nimport { MESSAGE_TYPE_GOAL, MESSAGE_TYPE_SYSTEM } from \"../../types/message\";\nimport {\n  getTaskStatus,\n  isAction,\n  TASK_STATUS_COMPLETED,\n  TASK_STATUS_FINAL,\n  TASK_STATUS_STARTED,\n} from \"../../types/task\";\nimport Button from \"../../ui/button\";\nimport { getMessageContainerStyle, getTaskStatusIcon } from \"../utils/helpers\";\n\nconst ChatMessage = ({ message }: { message: Message }) => {\n  const [t] = useTranslation();\n  const [isCopied, setIsCopied] = useState(false);\n\n  const handleCopy = () => {\n    try {\n      const textToCopy = isAction(message) ? message.info || \"\" : message.value;\n      void navigator.clipboard.writeText(textToCopy);\n      setIsCopied(true);\n    } catch (error) {\n      console.error(error);\n    }\n  };\n\n  if (message.type === MESSAGE_TYPE_GOAL && !isAction(message)) {\n    return <div className=\"pb-2 text-2xl sm:text-4xl\">{message.value}</div>;\n  }\n  return (\n    <div\n      className={clsx(\n        getMessageContainerStyle(message),\n        \"my-1 mr-2 rounded-lg bg-slate-1 p-2 text-xs shadow-depth-1 hover:border-[#1E88E5]/40 sm:mr-4 sm:p-3\",\n        \"sm:my-1.5 sm:text-sm\",\n        !isAction(message) && \"w-fit max-w-full\"\n      )}\n    >\n      {message.type !== MESSAGE_TYPE_SYSTEM && !isAction(message) && (\n        <>\n          <div className=\"mr-2 inline-block h-[0.9em]\">{getTaskStatusIcon(message, {})}</div>\n          <span className=\"mr-2 font-bold\">{getMessagePrefix(message)}</span>\n        </>\n      )}\n\n      {isAction(message) ? (\n        <>\n          <div className=\"flex flex-row\">\n            <div className=\"mr-2 inline-block h-[0.9em]\">{getTaskStatusIcon(message, {})}</div>\n            <span className=\"mr-2 flex-1 font-bold\">{getMessagePrefix(message)}</span>\n            <Button\n              className=\"justify-end rounded-md text-slate-10 hover:bg-slate-6 hover:text-slate-12\"\n              onClick={handleCopy}\n              aria-label=\"Copy\"\n            >\n              <div className=\"w-full\">{isCopied ? <FaCheck /> : <FiClipboard size={15} />}</div>\n            </Button>\n          </div>\n          <hr className=\"my-2 border border-white/20\" />\n          <div>\n            <MarkdownRenderer>{message.info || \"\"}</MarkdownRenderer>\n            <SourceCard content={message.info || \"\"} />\n          </div>\n        </>\n      ) : (\n        <>\n          <span>{message.value}</span>\n          {message.type === MESSAGE_TYPE_SYSTEM &&\n            (message.value.toLowerCase().includes(\"shut\") ||\n              message.value.toLowerCase().includes(\"error\")) && <FAQ />}\n        </>\n      )}\n    </div>\n  );\n};\n\nconst FAQ = () => {\n  return (\n    <p>\n      <br />\n      If you are facing issues, please head over to our{\" \"}\n      <a href=\"https://reworkd.ai/docs\" className=\"text-sky-500\">\n        docs\n      </a>\n    </p>\n  );\n};\n\n// Returns the translation key of the prefix\nconst getMessagePrefix = (message: Message) => {\n  if (getTaskStatus(message) === TASK_STATUS_STARTED) {\n    return \"Task Added:\";\n  } else if (getTaskStatus(message) === TASK_STATUS_COMPLETED) {\n    return message.value;\n  } else if (getTaskStatus(message) === TASK_STATUS_FINAL) {\n    return `Finished:`;\n  }\n  return \"\";\n};\nexport { ChatMessage };\n"
  },
  {
    "path": "next/src/components/console/ChatWindow.tsx",
    "content": "import clsx from \"clsx\";\nimport { useTranslation } from \"next-i18next\";\nimport type { ReactNode } from \"react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { FaArrowCircleDown, FaCommentDots } from \"react-icons/fa\";\nimport { ImSpinner2 } from \"react-icons/im\";\n\nimport type { HeaderProps } from \"./MacWindowHeader\";\nimport { MacWindowHeader, messageListId } from \"./MacWindowHeader\";\nimport { useAgentStore } from \"../../stores\";\nimport Button from \"../Button\";\nimport Input from \"../Input\";\nimport HideShow from \"../motions/HideShow\";\n\ninterface ChatControls {\n  value: string;\n  onChange: (string) => void;\n  handleChat: () => Promise<void>;\n  loading?: boolean;\n}\n\ninterface ChatWindowProps extends HeaderProps {\n  children?: ReactNode;\n  setAgentRun?: (name: string, goal: string) => void;\n  visibleOnMobile?: boolean;\n  chatControls?: ChatControls;\n}\n\nconst ChatWindow = ({ messages, children, title, chatControls }: ChatWindowProps) => {\n  const [t] = useTranslation();\n  const [hasUserScrolled, setHasUserScrolled] = useState(false);\n  const isThinking = useAgentStore.use.isAgentThinking();\n  const isStopped = useAgentStore.use.lifecycle() === \"stopped\";\n  const scrollRef = useRef<HTMLDivElement>(null);\n\n  const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {\n    const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;\n\n    // Use has scrolled if we have scrolled up at all from the bottom\n    const hasUserScrolled = scrollTop < scrollHeight - clientHeight - 10;\n    setHasUserScrolled(hasUserScrolled);\n  };\n\n  const handleScrollToBottom = (behaviour: \"instant\" | \"smooth\") => {\n    if (!scrollRef || !scrollRef.current) return;\n\n    scrollRef.current.scrollTo({\n      top: scrollRef.current.scrollHeight,\n      behavior: behaviour,\n    });\n  };\n\n  useEffect(() => {\n    if (!hasUserScrolled) {\n      handleScrollToBottom(\"instant\");\n    }\n  });\n\n  return (\n    <div\n      className={clsx(\n        \"flex h-full w-full max-w-[inherit] flex-1 flex-col overflow-auto text-slate-12 transition-all duration-500\"\n      )}\n    >\n      <HideShow\n        showComponent={hasUserScrolled}\n        className=\"absolute bottom-11 right-6 z-40 cursor-pointer sm:bottom-14\"\n      >\n        <FaArrowCircleDown\n          onClick={() => handleScrollToBottom(\"smooth\")}\n          className=\"h-6 w-6 animate-bounce md:h-7 md:w-7\"\n        />\n      </HideShow>\n      <MacWindowHeader title={title} messages={messages} />\n      <div\n        className=\"mb-2 mr-2 flex-1 overflow-auto transition-all duration-500\"\n        ref={scrollRef}\n        onScroll={handleScroll}\n        id={messageListId}\n      >\n        {children}\n        <div\n          className={clsx(\n            isThinking && !isStopped ? \"opacity-100\" : \"opacity-0\",\n            \"mr-2 flex flex-row items-center gap-2 p-2 transition duration-300 sm:mr-4\",\n            \"text-xs sm:text-base\"\n          )}\n        >\n          <p>🧠 Thinking</p>\n          <ImSpinner2 className=\"animate-spin\" />\n        </div>\n      </div>\n      {chatControls && (\n        <div className=\"mt-auto flex flex-row gap-2 p-2 pt-0 sm:p-4\">\n          <Input\n            small\n            placeholder=\"Chat with your agent...\"\n            value={chatControls.value}\n            onChange={(e) => chatControls?.onChange(e.target.value)}\n          />\n          <Button\n            className=\"px-1 py-1 sm:px-3 md:py-1\"\n            onClick={chatControls?.handleChat}\n            disabled={chatControls.loading}\n          >\n            <FaCommentDots />\n          </Button>\n        </div>\n      )}\n    </div>\n  );\n};\n\nexport default ChatWindow;\n"
  },
  {
    "path": "next/src/components/console/ChatWindowTitle.tsx",
    "content": "import React from \"react\";\n\nimport type { GPTModelNames } from \"../../types\";\nimport { GPT_35_TURBO_16K, GPT_4 } from \"../../types\";\n\nexport const ChatWindowTitle = ({ model }: { model: GPTModelNames }) => {\n  if (model === GPT_4) {\n    return (\n      <>\n        Agent<span className=\"text-amber-500\">GPT-4</span>\n      </>\n    );\n  }\n\n  if (model === GPT_35_TURBO_16K) {\n    return (\n      <>\n        Agent\n        <span className=\"text-neutral-400\">\n          GPT-3.5<span className=\"text-amber-500\">-16K</span>\n        </span>\n      </>\n    );\n  }\n\n  return (\n    <>\n      Agent<span className=\"text-neutral-400\">GPT-3.5</span>\n    </>\n  );\n};\n"
  },
  {
    "path": "next/src/components/console/ExampleAgentButton.tsx",
    "content": "import React from \"react\";\n\nexport const ExampleAgentButton = ({\n  name,\n  children,\n  setAgentRun,\n}: {\n  name: string;\n  children: string;\n  setAgentRun?: (name: string, goal: string) => void;\n}) => {\n  const handleClick = () => {\n    if (setAgentRun) {\n      setAgentRun(name, children);\n    }\n  };\n\n  return (\n    <div\n      className=\"w-full cursor-pointer rounded-lg border-2 border-slate-7 bg-slate-1 p-4 text-sm text-slate-12 opacity-90 shadow-depth-2 transition-all duration-300 hover:bg-slate-3 sm:text-base\"\n      onClick={handleClick}\n    >\n      <p className=\"text-lg font-bold\">{name}</p>\n      <p className=\"mt-2 text-sm\">{children}</p>\n    </div>\n  );\n};\n"
  },
  {
    "path": "next/src/components/console/ExampleAgents.tsx",
    "content": "import { useSession } from \"next-auth/react\";\nimport React from \"react\";\n\nimport { ExampleAgentButton } from \"./ExampleAgentButton\";\nimport { useSID } from \"../../hooks/useSID\";\nimport FadeIn from \"../motions/FadeIn\";\n\ntype ExampleAgentsProps = {\n  setAgentRun?: (name: string, goal: string) => void;\n  setShowSignIn: (show: boolean) => void;\n};\n\nconst ExampleAgents = ({ setAgentRun, setShowSignIn }: ExampleAgentsProps) => {\n  const { data: session } = useSession();\n  const sid = useSID(session);\n\n  return (\n    <>\n      <FadeIn delay={0.9} duration={0.5}>\n        <div className=\"my-2 grid grid-cols-1 items-stretch gap-2 sm:my-4 sm:grid-cols-3\">\n          <ExampleAgentButton name=\"TravelGPT 🌴\" setAgentRun={setAgentRun}>\n            Plan a detailed trip to Hawaii\n          </ExampleAgentButton>\n\n          <ExampleAgentButton name=\"CalculusGPT 📚\" setAgentRun={setAgentRun}>\n            Create a study plan for an intro to Calculus exam\n          </ExampleAgentButton>\n\n          <ExampleAgentButton name=\"HustleGPT 🚀\" setAgentRun={setAgentRun}>\n            Create a comprehensive report for how to scale a startup to 1000 customers\n          </ExampleAgentButton>\n        </div>\n      </FadeIn>\n    </>\n  );\n};\n\nexport default ExampleAgents;\n"
  },
  {
    "path": "next/src/components/console/MacWindowHeader.tsx",
    "content": "import clsx from \"clsx\";\nimport * as htmlToImage from \"html-to-image\";\nimport { useTranslation } from \"next-i18next\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\nimport React from \"react\";\nimport { CgExport } from \"react-icons/cg\";\nimport { FaImage } from \"react-icons/fa\";\nimport { FiClipboard } from \"react-icons/fi\";\n\nimport type { Message } from \"../../types/message\";\nimport Menu from \"../Menu\";\nimport Expand from \"../motions/expand\";\nimport PopIn from \"../motions/popin\";\nimport PDFButton from \"../pdf/PDFButton\";\nimport WindowButton from \"../WindowButton\";\n\nexport const messageListId = \"chat-window-message-list\";\n\nexport interface HeaderProps {\n  title?: string | ReactNode;\n  messages: Message[];\n}\n\nexport const MacWindowHeader = (props: HeaderProps) => {\n  const [t] = useTranslation();\n\n  const saveElementAsImage = (elementId: string) => {\n    const element = document.getElementById(elementId);\n    if (!element) {\n      return;\n    }\n\n    htmlToImage\n      .toJpeg(element, {\n        height: element.scrollHeight,\n        style: {\n          overflowY: \"visible\",\n          maxHeight: \"none\",\n          border: \"none\",\n        },\n      })\n      .then((dataUrl) => {\n        const link = document.createElement(\"a\");\n        link.href = dataUrl;\n        link.download = \"agent-gpt-output.png\";\n        link.click();\n      })\n      .catch(() =>\n        alert(\"Error saving image! Note this doesn't work if the AI generated an image\")\n      );\n  };\n\n  const copyElementText = (elementId: string) => {\n    const element = document.getElementById(elementId);\n    if (!element) {\n      return;\n    }\n\n    const text = element.innerText;\n\n    if (navigator.clipboard) {\n      void navigator.clipboard.writeText(text);\n    } else {\n      // Fallback to a different method for unsupported browsers\n      const textArea = document.createElement(\"textarea\");\n      textArea.value = text;\n      document.body.appendChild(textArea);\n      textArea.focus();\n      textArea.select();\n\n      try {\n        document.execCommand(\"copy\");\n        console.log(\"Text copied to clipboard\");\n      } catch (err) {\n        console.error(\"Unable to copy text to clipboard\", err);\n      }\n\n      document.body.removeChild(textArea);\n    }\n  };\n\n  const exportOptions = [\n    <WindowButton\n      key=\"Image\"\n      onClick={(): void => saveElementAsImage(messageListId)}\n      icon={<FaImage size={12} />}\n      text={t(\"IMAGE\", { ns: \"common\" })}\n    />,\n    <WindowButton\n      key=\"Copy\"\n      onClick={(): void => copyElementText(messageListId)}\n      icon={<FiClipboard size={12} />}\n      text={t(\"COPY\", { ns: \"common\" })}\n    />,\n    <PDFButton key=\"PDF\" name=\"PDF\" messages={props.messages} />,\n  ];\n\n  return (\n    <div className=\"flex items-center gap-1 overflow-visible rounded-t-3xl p-1.5 px-1\">\n      <PopIn delay={0.4}>\n        <div className=\"h-3 w-3 rounded-full bg-red-500\" />\n      </PopIn>\n      <PopIn delay={0.5}>\n        <div className=\"h-3 w-3 rounded-full bg-yellow-500\" />\n      </PopIn>\n      <PopIn delay={0.6}>\n        <div className=\"h-3 w-3 rounded-full bg-green-500\" />\n      </PopIn>\n      <Expand\n        delay={0.75}\n        className=\"flex flex-grow font-mono text-xs font-bold text-gray-500 sm:ml-2 sm:text-sm\"\n      >\n        {props.title}\n      </Expand>\n      <Menu icon={<CgExport size={15} />} items={exportOptions} />\n    </div>\n  );\n};\n\ninterface MacWindowInternalProps extends PropsWithChildren {\n  className?: string;\n}\n\nexport const MacWindowInternal = (props: MacWindowInternalProps) => {\n  return (\n    <div\n      className={clsx(\n        \"ml-2 flex items-baseline gap-1 overflow-visible rounded-t-3xl p-1.5\",\n        props.className\n      )}\n    >\n      <PopIn delay={0.4}>\n        <div className=\"h-2 w-2 rounded-full bg-red-500\" />\n      </PopIn>\n      <PopIn delay={0.5}>\n        <div className=\"h-2 w-2 rounded-full bg-yellow-500\" />\n      </PopIn>\n      <PopIn delay={0.6}>\n        <div className=\"h-2 w-2 rounded-full bg-green-500\" />\n      </PopIn>\n      <Expand\n        delay={0.75}\n        className=\"ml-1 flex flex-grow font-mono text-[8pt] font-bold text-gray-400\"\n      >\n        {props.children}\n      </Expand>\n    </div>\n  );\n};\n"
  },
  {
    "path": "next/src/components/console/MarkdownRenderer.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport React, { useCallback, useState } from \"react\";\nimport { FiClipboard } from \"react-icons/fi\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport remarkGfm from \"remark-gfm\";\nimport \"highlight.js/styles/default.css\";\n\ninterface MarkdownRendererProps {\n  children: string;\n  className?: string;\n}\n\nconst MarkdownRenderer = ({ children, className }: MarkdownRendererProps) => {\n  return (\n    <ReactMarkdown\n      remarkPlugins={[remarkGfm]}\n      rehypePlugins={[() => rehypeHighlight({ ignoreMissing: true })]}\n      components={{\n        pre: CustomPre,\n        code: CustomCodeBlock,\n        h1: (props) => <h1 className=\"text-md mb-2 font-black sm:text-xl\">{props.children}</h1>,\n        h2: (props) => <h1 className=\"sm:text-md mb-2 text-sm font-bold\">{props.children}</h1>,\n        a: (props) => CustomLink({ children: props.children, href: props.href }),\n        p: (props) => <p className=\"mb-4\">{props.children}</p>,\n        ul: (props) => (\n          <ul className={clsx(\"mb-4 list-disc marker:text-neutral-400\", className)}>\n            {props.children}\n          </ul>\n        ),\n        ol: (props) => (\n          <ol className=\"mb-4 ml-8 list-decimal marker:text-neutral-400\">{props.children}</ol>\n        ),\n        li: (props) => <li className=\"mb-1 ml-8\">{props.children}</li>,\n      }}\n    >\n      {children}\n    </ReactMarkdown>\n  );\n};\n\nconst CustomPre = ({ children }: { children: ReactNode }) => {\n  const [isCopied, setIsCopied] = useState(false);\n\n  const code = React.Children.toArray(children).find(isValidCustomCodeBlock);\n\n  const language: string =\n    code && code.props.className\n      ? extractLanguageName(code.props.className.replace(\"hljs \", \"\"))\n      : \"\";\n\n  const handleCopyClick = useCallback(() => {\n    if (code && React.isValidElement(code)) {\n      const codeString = extractTextFromNode(code.props.children);\n      void navigator.clipboard.writeText(codeString);\n      setIsCopied(true);\n      setTimeout(() => {\n        setIsCopied(false);\n      }, 2000);\n    }\n  }, [code]);\n\n  return (\n    <div className=\"mb-4 flex flex-col \">\n      <div className=\"flex w-full items-center justify-between rounded-t-lg bg-slate-10 p-1 px-4 text-white\">\n        <div>{language.charAt(0).toUpperCase() + language.slice(1)}</div>\n        <button\n          onClick={handleCopyClick}\n          className=\"flex items-center gap-2 rounded px-2 py-1 hover:bg-slate-9 focus:outline-none\"\n        >\n          <FiClipboard />\n          {isCopied ? \"Copied!\" : \"Copy Code\"}\n        </button>\n      </div>\n      <pre className=\"rounded-t-[0]\">{children}</pre>\n    </div>\n  );\n};\n\ninterface CustomCodeBlockProps {\n  inline?: boolean;\n  className?: string;\n  children: ReactNode;\n}\n\nconst CustomCodeBlock = ({ inline, className, children }: CustomCodeBlockProps) => {\n  // Inline code blocks will be placed directly within a paragraph\n  if (inline) {\n    return <code className=\"rounded bg-slate-2 px-1 py-[1px] text-black\">{children}</code>;\n  }\n\n  const language = className ? className.replace(\"language-\", \"\") : \"plaintext\";\n\n  return <code className={`hljs ${language}`}>{children}</code>;\n};\n\nconst CustomLink = ({ children, href }) => {\n  return (\n    <a\n      className={clsx(\n        \"mx-0.5 rounded-full bg-sky-600 px-1.5 py-0.5 align-top text-[0.6rem] text-white\",\n        \"transition-colors duration-300 hover:bg-sky-500 hover:text-white\"\n      )}\n      href={href as string}\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      {children}\n    </a>\n  );\n};\n\nconst isValidCustomCodeBlock = (\n  element: ReactNode\n): element is React.ReactElement<CustomCodeBlockProps> =>\n  React.isValidElement(element) && element.type === CustomCodeBlock;\n\nconst extractLanguageName = (languageString: string): string => {\n  // The provided language will be \"language-{PROGRAMMING_LANGUAGE}\"\n  const parts = languageString.split(\"-\");\n  if (parts.length > 1) {\n    return parts[1] || \"\";\n  }\n  return \"\";\n};\n\nconst extractTextFromNode = (node: React.ReactNode): string => {\n  if (typeof node === \"string\") {\n    return node;\n  }\n\n  if (Array.isArray(node)) {\n    return node.map(extractTextFromNode).join(\"\");\n  }\n\n  if (React.isValidElement(node)) {\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-member-access\n    return extractTextFromNode(node.props.children);\n  }\n\n  return \"\";\n};\n\nexport default MarkdownRenderer;\n"
  },
  {
    "path": "next/src/components/console/SourceCard.tsx",
    "content": "import SourceLink from \"./SourceLink\";\n\nconst SourceCard = ({ content }: { content: string }) => {\n  const regex = /(?=\\[(!\\[.+?\\]\\(.+?\\)|.+?)]\\((https?:\\/\\/[^\\)]+)\\))/gi;\n  const linksSet = new Set<string>();\n  const linksMatches = [...content.matchAll(regex)];\n  linksMatches.forEach((m) => linksSet.add(m[2] as string));\n  const linksArray = Array.from(linksSet);\n\n  if (linksArray.length === 0) return null;\n\n  return (\n    <>\n      <div className=\"my-2 grid grid-cols-2 gap-3 md:grid-cols-3 lg:grid-cols-4\">\n        {linksArray.map((link, index) => {\n          return <SourceLink key={link} link={link} index={index} />;\n        })}\n      </div>\n    </>\n  );\n};\n\nexport default SourceCard;\n"
  },
  {
    "path": "next/src/components/console/SourceLink.tsx",
    "content": "import { useQuery } from \"@tanstack/react-query\";\nimport axios from \"axios\";\nimport type { SyntheticEvent } from \"react\";\nimport { z } from \"zod\";\n\nimport { env } from \"../../env/client.mjs\";\nimport FadeIn from \"../motions/FadeIn\";\n\ninterface LinkInfo {\n  link: string;\n  index: number;\n}\n\nconst MetaDataSchema = z.object({\n  title: z.string().nullish(),\n  favicon: z.string().nullish(),\n  hostname: z.string().nullish(),\n});\n\nconst SourceLink = ({ link, index }: LinkInfo) => {\n  const linkMeta = useQuery([\"linkMeta\", link], async () =>\n    MetaDataSchema.parse(\n      (\n        await axios.get(env.NEXT_PUBLIC_BACKEND_URL + \"/api/metadata\", {\n          params: {\n            url: link,\n          },\n        })\n      ).data\n    )\n  );\n\n  const addImageFallback = (event: SyntheticEvent<HTMLImageElement, Event>) => {\n    event.currentTarget.src = \"/errorFavicon.ico\";\n  };\n\n  return (\n    <FadeIn>\n      <a href={link} target=\"_blank\">\n        <div className=\"group h-full space-y-2 rounded-lg border border-slate-8 bg-slate-3 p-2 transition-colors duration-300 hover:bg-slate-4\">\n          {linkMeta.isLoading ? (\n            <div className=\"animate-pulse space-y-2\">\n              <div className=\"h-2 rounded bg-slate-8\"></div>\n              <div className=\"h-2 rounded bg-slate-8\"></div>\n              <div className=\"flex items-center gap-2\">\n                <div className=\"h-4 w-4 rounded bg-slate-8\"></div>\n                <div className=\"h-2 w-2/3  rounded bg-slate-8\"></div>\n              </div>\n            </div>\n          ) : linkMeta.isSuccess ? (\n            <>\n              <p className=\"line-clamp-2 text-xs\">{linkMeta.data.title}</p>\n              <div className=\"flex items-center gap-2 overflow-ellipsis\">\n                <img\n                  className=\"inline h-4 w-4\"\n                  src={linkMeta.data.favicon || \"\"}\n                  alt=\"Logo\"\n                  onError={addImageFallback}\n                />\n                <p className=\"line-clamp-1 overflow-ellipsis\">{linkMeta.data.hostname}</p>\n                <p className=\"rounded-full bg-slate-5 px-2 text-slate-12 transition-colors duration-300 group-hover:bg-sky-600 group-hover:text-white\">\n                  {index + 1}\n                </p>\n              </div>\n            </>\n          ) : linkMeta.isError ? (\n            <div className=\"flex gap-2\">\n              <p className=\"line-clamp-1\">{link}</p>\n              <p className=\"rounded-full bg-slate-5 px-3 text-slate-12\">{index + 1}</p>\n            </div>\n          ) : null}\n        </div>\n      </a>\n    </FadeIn>\n  );\n};\n\nexport default SourceLink;\n"
  },
  {
    "path": "next/src/components/console/SummarizeButton.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\nimport { useAgentStore } from \"../../stores\";\nimport { useTaskStore } from \"../../stores/taskStore\";\nimport Button from \"../Button\";\n\nconst Summarize = () => {\n  const agent = useAgentStore.use.agent();\n  const lifecycle = useAgentStore.use.lifecycle();\n  const tasksWithResults = useTaskStore.use\n    .tasks()\n    .filter((task) => task.status == \"completed\" && task.result !== \"\");\n  const summarized = useAgentStore.use.summarized();\n  const setSummarized = useAgentStore.use.setSummarized();\n\n  if (!agent || lifecycle !== \"stopped\" || tasksWithResults.length < 1 || summarized) return null;\n\n  return (\n    <div\n      className={clsx(\n        \"mr-2 flex flex-row items-center gap-2 rounded-lg bg-slate-1 p-2 shadow-depth-1 transition duration-300 sm:mr-4\",\n        \"text-xs sm:text-base\"\n      )}\n    >\n      <span className=\"text-sm\">Click here to summarize the conversation</span>\n      <Button\n        className=\"ml-auto py-1 font-medium sm:py-1 md:py-1\"\n        onClick={async () => {\n          setSummarized(true);\n          await agent?.summarize();\n        }}\n      >\n        Summarize\n      </Button>\n    </div>\n  );\n};\n\nexport default Summarize;\n"
  },
  {
    "path": "next/src/components/dialog/HelpDialog.tsx",
    "content": "import { useTranslation } from \"next-i18next\";\nimport React, { useEffect, useState } from \"react\";\nimport { FaDiscord, FaGithub } from \"react-icons/fa\";\nimport {FaXTwitter} from 'react-icons/fa6';\n\nimport Dialog from \"../../ui/dialog\";\n\nexport default function HelpDialog() {\n  const [show, setShow] = useState(false);\n\n  useEffect(() => {\n    const key = \"agentgpt-modal-opened-v0.2\";\n    const savedModalData = localStorage.getItem(key);\n\n    setTimeout(() => {\n      if (savedModalData == null) {\n        setShow(true);\n      }\n    }, 1500);\n\n    localStorage.setItem(key, JSON.stringify(true));\n  }, []);\n\n  const [t] = useTranslation();\n  return (\n    <Dialog\n      inline\n      open={show}\n      setOpen={setShow}\n      title=\"Welcome!\"\n      actions={\n        <>\n          <button\n            type=\"button\"\n            className=\"inline-flex w-full justify-center rounded-md bg-sky-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-sky-400\"\n            onClick={() => {\n              setShow(false);\n            }}\n          >\n            Get Started\n          </button>\n        </>\n      }\n    >\n      <div>\n        <p>\n          AgentGPT is the next generation of Google search. Ask any question and watch as an AI\n          Agent gives you the perfect answer after aggregating relevant sources from across the\n          internet.\n        </p>\n        <br />\n        <p className=\"mt-2 text-center font-bold\">{t(\"FOLLOW_THE_JOURNEY\", { ns: \"help\" })}</p>\n        <div className=\"mt-4 flex w-full items-center justify-center gap-5\">\n          <div\n            className=\"cursor-pointer rounded-full bg-slate-6 p-3 hover:bg-slate-8\"\n            onClick={() => window.open(\"https://discord.gg/jdSBAnmdnY\", \"_blank\")}\n          >\n            <FaDiscord size={30} />\n          </div>\n          <div\n            className=\"cursor-pointer rounded-full bg-slate-6 p-3 hover:bg-slate-8\"\n            onClick={() =>\n              window.open(\n                \"https://twitter.com/asimdotshrestha/status/1644883727707959296\",\n                \"_blank\"\n              )\n            }\n          >\n            <FaXTwitter size={30} />\n          </div>\n          <div\n            className=\"cursor-pointer rounded-full bg-slate-6 p-3 hover:bg-slate-8\"\n            onClick={() => window.open(\"https://github.com/reworkd/AgentGPT\", \"_blank\")}\n          >\n            <FaGithub size={30} />\n          </div>\n        </div>\n      </div>\n    </Dialog>\n  );\n}\n"
  },
  {
    "path": "next/src/components/dialog/SignInDialog.tsx",
    "content": "import React from \"react\";\n\nimport { useAuth } from \"../../hooks/useAuth\";\nimport Dialog from \"../../ui/dialog\";\n\nexport interface SignInDialogProps {\n  show: boolean;\n  setOpen: (boolean) => void;\n}\n\nexport const SignInDialog = ({ show, setOpen }: SignInDialogProps) => {\n  const { signIn } = useAuth();\n\n  return (\n    <Dialog\n      inline\n      open={show}\n      setOpen={setOpen}\n      title=\"Sign in 🔐\"\n      actions={\n        <>\n          <button\n            type=\"button\"\n            className=\"inline-flex w-full justify-center rounded-md bg-sky-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-sky-400\"\n            onClick={() => {\n              signIn().catch(console.error);\n            }}\n          >\n            Sign in\n          </button>\n          <button\n            type=\"button\"\n            className=\"inline-flex w-full justify-center rounded-md bg-slate-1 px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-slate-3\"\n            onClick={() => setOpen(false)}\n          >\n            Close\n          </button>\n        </>\n      }\n    >\n      <p>\n        Please{\" \"}\n        <a className=\"link\" onClick={() => void signIn()}>\n          sign in\n        </a>{\" \"}\n        to deploy an Agent! 🤖\n      </p>\n    </Dialog>\n  );\n};\n"
  },
  {
    "path": "next/src/components/dialog/ToolsDialog.tsx",
    "content": "import { useSession } from \"next-auth/react\";\nimport React from \"react\";\n\nimport { useSID } from \"../../hooks/useSID\";\nimport type { ActiveTool } from \"../../hooks/useTools\";\nimport { useTools } from \"../../hooks/useTools\";\nimport Dialog from \"../../ui/dialog\";\nimport Button from \"../Button\";\nimport { Switch } from \"../Switch\";\n\nexport const ToolsDialog: React.FC<{\n  show: boolean;\n  setOpen: (boolean) => void;\n}> = ({ show, setOpen }) => {\n  const { activeTools, setToolActive, isSuccess } = useTools();\n\n  return (\n    <Dialog\n      inline\n      open={show}\n      setOpen={setOpen}\n      title=\"Tools\"\n      actions={\n        <>\n          <button\n            type=\"button\"\n            className=\"inline-flex w-full justify-center rounded-md bg-sky-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-sky-400\"\n            onClick={() => {\n              setOpen(false);\n            }}\n          >\n            Close\n          </button>\n        </>\n      }\n    >\n      <p>Select what external tools your agents have access to.</p>\n      <div className=\"mt-5 flex flex-col gap-3 \">\n        {activeTools.map((tool, i) => {\n          if (tool.name === \"sid\") {\n            return <SidTool key={i} tool={tool} onChange={setToolActive} />;\n          }\n\n          return <GenericTool key={i} tool={tool} onChange={setToolActive} />;\n        })}\n        {!isSuccess && <p className=\"text-center text-red-300\">Error loading tools.</p>}\n      </div>\n    </Dialog>\n  );\n};\n\ninterface ToolProps {\n  tool: ActiveTool;\n  onChange: (name: string, active: boolean) => void;\n}\n\nconst GenericTool = ({ tool, onChange }: ToolProps) => {\n  return (\n    <div className=\"flex items-center gap-3 rounded-md border border-white/30 bg-zinc-800 p-2 px-4 text-white\">\n      <ToolAvatar tool={tool} />\n      <div className=\"flex flex-grow flex-col gap-1\">\n        <p className=\"font-bold capitalize\">{tool.name}</p>\n        <p className=\"text-xs sm:text-sm\">{tool.description}</p>\n      </div>\n      <Switch value={tool.active} onChange={() => onChange(tool.name, !tool.active)} />\n    </div>\n  );\n};\n\nconst SidTool = ({ tool, onChange }: ToolProps) => {\n  const { data: session } = useSession();\n  const sid = useSID(session);\n\n  return (\n    <div className=\"relative flex items-center gap-3 overflow-hidden rounded-md border border-white/30 bg-zinc-800 p-2 px-4 text-white\">\n      {!sid.connected && (\n        <div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n          <div className=\"absolute inset-0 backdrop-blur-sm\" />\n          <Button\n            className=\"border-white/20 bg-gradient-to-t from-sky-500 to-sky-600 transition-all hover:bg-gradient-to-t hover:from-sky-400 hover:to-sky-600\"\n            onClick={sid.install}\n          >\n            Connect your Data\n          </Button>\n        </div>\n      )}\n      <ToolAvatar tool={tool} />\n      <div className=\"flex flex-grow flex-col gap-1\">\n        <p className=\"font-bold capitalize\">{tool.name}</p>\n        <p className=\"text-xs sm:text-sm\">{tool.description}</p>\n      {sid.connected && (\n        <>\n          <Button onClick={sid.manage}>Manage</Button>\n          <Button\n            className=\"rounded-full bg-gray-700 font-semibold text-white hover:bg-gray-600\"\n            onClick={sid.uninstall}\n          >\n            Disconnect\n          </Button>\n         </>\n      )}\n      </div>\n      <Switch\n        value={!sid?.connected ?? false ? false : tool.active}\n        onChange={() => onChange(tool.name, !tool.active)}\n      />\n    </div>\n  );\n};\n\nconst ToolAvatar = ({ tool }: { tool: ActiveTool }) => {\n  if (tool.image_url) {\n    // eslint-disable-next-line @next/next/no-img-element\n    return <img alt={tool.name} width=\"40px\" height=\"40px\" src={tool.image_url} />;\n  }\n\n  return <div className=\"h-10 w-10 rounded-full border border-white/30 bg-amber-600\" />;\n};\n"
  },
  {
    "path": "next/src/components/drawer/DrawerItemButton.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\ninterface DrawerItemProps {\n  text: string;\n  className?: string;\n  onClick?: () => Promise<void> | void;\n}\n\nexport const DrawerItemButton = (props: DrawerItemProps) => {\n  const { text, onClick } = props;\n\n  return (\n    <button\n      type=\"button\"\n      className={clsx(\n        \"cursor-pointer items-center rounded-md text-slate-12 hover:bg-slate-5\",\n        props.className\n      )}\n      onClick={onClick}\n    >\n      <span className=\"line-clamp-1 text-left text-sm font-medium\">{text}</span>\n    </button>\n  );\n};\n\nexport const DrawerItemButtonLoader = () => {\n  return <div className=\"w-50 mx-1.5 h-7 animate-pulse rounded-md bg-slate-6\"></div>;\n};\n"
  },
  {
    "path": "next/src/components/drawer/LeftSidebar.tsx",
    "content": "import Image from \"next/image\";\nimport { useRouter } from \"next/router\";\nimport { useTranslation } from \"next-i18next\";\nimport { FaBars } from \"react-icons/fa\";\n\nimport { DrawerItemButton, DrawerItemButtonLoader } from \"./DrawerItemButton\";\nimport type { DisplayProps } from \"./Sidebar\";\nimport Sidebar from \"./Sidebar\";\nimport { useAuth } from \"../../hooks/useAuth\";\nimport { api } from \"../../utils/api\";\nimport AuthItem from \"../sidebar/AuthItem\";\nimport LinkIconItem from \"../sidebar/LinkIconItem\";\nimport LinkItem from \"../sidebar/LinkItem\";\nimport { PAGE_LINKS, SOCIAL_LINKS } from \"../sidebar/links\";\n\nconst LeftSidebar = ({ show, setShow, onReload }: DisplayProps & { onReload?: () => void }) => {\n  const router = useRouter();\n  const { session, signIn, signOut, status } = useAuth();\n  const [t] = useTranslation(\"drawer\");\n\n  const { isLoading, data } = api.agent.getAll.useQuery(undefined, {\n    enabled: status === \"authenticated\",\n  });\n  const userAgents = data ?? [];\n\n  const navigateToPage = (href: string) => {\n    if (router.pathname === href) {\n      onReload?.();\n      return;\n    }\n\n    void router.push(href);\n  };\n\n  return (\n    <Sidebar show={show} setShow={setShow} side=\"left\" className=\"border-slate-6s border-r\">\n      <div className=\"flex flex-row items-center pb-6\">\n        <div className=\"rounded-xl bg-slate-1 p-1 shadow-depth-1\">\n          <a\n            href=\"https://reworkd.ai\"\n            className=\"flex cursor-pointer gap-2 rounded-lg border-t bg-white bg-gradient-to-b from-slate-4 to-transparent px-2.5 py-1.5 duration-1000 hover:from-slate-6\"\n          >\n            <Image src=\"/logos/light-default-solid.svg\" width=\"20\" height=\"20\" alt=\"Reworkd AI\" />\n            <h1 className=\"text-sm font-medium\">Reworkd</h1>\n          </a>\n        </div>\n        <button\n          className=\"ml-auto rounded-md border-none transition-all hover:bg-slate-5\"\n          onClick={() => setShow(!show)}\n        >\n          <FaBars size=\"12\" className=\"z-20 m-2 text-slate-11\" />\n        </button>\n      </div>\n      <button\n        className=\"mb-4 rounded-md bg-slate-1 p-1 shadow-depth-1 hover:bg-slate-2\"\n        onClick={() => navigateToPage(\"/\")}\n      >\n        New Agent\n      </button>\n      <div className=\"mb-2 mr-2 flex-1 overflow-y-auto overflow-x-hidden overflow-ellipsis\">\n        {status === \"unauthenticated\" && (\n          <div className=\"p-1 text-sm text-slate-12\">\n            <a className=\"link\" onClick={() => void signIn()}>\n              {t(\"SIGN_IN\")}\n            </a>{\" \"}\n            {t(\"SIGN_IN_NOTICE\")}\n          </div>\n        )}\n        {status === \"authenticated\" && !isLoading && userAgents.length === 0 && (\n          <div className=\"p-1 text-sm text-slate-12\">\n            {t(\"NEED_TO_SIGN_IN_AND_CREATE_AGENT_FIRST\")}\n          </div>\n        )}\n        {(status === \"loading\" || (status === \"authenticated\" && isLoading)) && (\n          <div className=\"flex flex-col gap-2 overflow-hidden\">\n            {Array(13)\n              .fill(0)\n              .map((_, index) => (\n                <DrawerItemButtonLoader key={index} />\n              ))}\n          </div>\n        )}\n\n        {userAgents.map((agent, index) => (\n          <DrawerItemButton\n            key={`${index}-${agent.name}`}\n            className=\"flex w-full rounded-md p-2 text-sm font-semibold\"\n            text={agent.name}\n            onClick={() => void router.push(`/agent?id=${agent.id}`)}\n          />\n        ))}\n      </div>\n      <ul role=\"list\" className=\"flex flex-col\">\n        <ul className=\"mb-2\">\n          <div className=\"mb-2 ml-2 text-xs font-semibold text-slate-10\">Pages</div>\n          {PAGE_LINKS.map((link, i) => (\n            <LinkItem\n              key={i}\n              title={link.name}\n              href={link.href}\n              onClick={() => navigateToPage(link.href)}\n            >\n              <link.icon className={link.className} />\n            </LinkItem>\n          ))}\n        </ul>\n        <li className=\"mb-2\">\n          <div className=\"mx-2 flex items-center justify-center gap-3\">\n            {SOCIAL_LINKS.map((link) => (\n              <LinkIconItem\n                key={link.name}\n                href={link.href}\n                onClick={() => {\n                  void router.push(link.href);\n                }}\n              >\n                <link.icon\n                  size={20}\n                  className=\"transition-all group-hover:rotate-3 group-hover:scale-125\"\n                />\n              </LinkIconItem>\n            ))}\n          </div>\n        </li>\n        <li>\n          <div className=\"mb-2 ml-2 text-xs font-semibold text-slate-10\"></div>\n        </li>\n        <li>\n          <AuthItem session={session} signOut={signOut} signIn={signIn} />\n        </li>\n      </ul>\n    </Sidebar>\n  );\n};\n\nexport default LeftSidebar;\n"
  },
  {
    "path": "next/src/components/drawer/Sidebar.tsx",
    "content": "import { Transition } from \"@headlessui/react\";\nimport clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport { Fragment } from \"react\";\nimport { FaBars } from \"react-icons/fa\";\n\nexport type DisplayProps = {\n  show: boolean;\n  setShow: (boolean: boolean) => void;\n};\n\nexport type SidebarProps = DisplayProps & {\n  children: ReactNode;\n  side: \"left\" | \"right\";\n  className?: string;\n};\n\nconst Sidebar = ({ show, children, side, className }: SidebarProps) => {\n  return (\n    <SidebarTransition show={show} side={side}>\n      <nav\n        className={clsx(\n          \"flex flex-1 flex-col overflow-x-hidden bg-slate-3 p-4 ring-1 ring-white/10\",\n          className\n        )}\n      >\n        {children}\n      </nav>\n    </SidebarTransition>\n  );\n};\n\ntype SidebarTransitionProps = {\n  side: \"left\" | \"right\";\n  children: ReactNode;\n  show: boolean;\n  className?: string;\n};\n\nexport const SidebarTransition = ({ children, show, side, className }: SidebarTransitionProps) => {\n  return (\n    <Transition.Root show={show} as={Fragment}>\n      <div className=\"relative z-30\">\n        <Transition.Child\n          as={Fragment}\n          enter=\"transition-opacity ease-linear duration-300\"\n          enterFrom=\"opacity-0\"\n          enterTo=\"opacity-100\"\n          leave=\"transition-opacity ease-linear duration-300\"\n          leaveFrom=\"opacity-100\"\n          leaveTo=\"opacity-0\"\n        >\n          <div className=\"fixed inset-0 bg-neutral-900/80 lg:hidden\" />\n        </Transition.Child>\n        <div className={`fixed ${side}-0 flex`}>\n          <Transition.Child\n            as={Fragment}\n            enter=\"transition ease-in-out duration-300 transform\"\n            enterFrom={side === \"left\" ? \"-translate-x-full\" : \"translate-x-full\"}\n            enterTo=\"translate-x-0\"\n            leave=\"transition ease-in-out duration-300 transform\"\n            leaveFrom=\"translate-x-0\"\n            leaveTo={side === \"left\" ? \"-translate-x-full\" : \"translate-x-full\"}\n          >\n            <div\n              className={clsx(\"flex max-w-xs flex-1\", className || \"h-screen max-h-screen w-64\")}\n            >\n              {children}\n            </div>\n          </Transition.Child>\n        </div>\n      </div>\n    </Transition.Root>\n  );\n};\n\nexport const SidebarControlButton = ({\n  show,\n  setShow,\n  side,\n}: DisplayProps & { side: \"left\" | \"right\" }) => {\n  return (\n    <button\n      className={clsx(\n        \"fixed z-20 m-1 rounded-md bg-slate-1 shadow-depth-1 transition-all sm:m-2\",\n        side === \"right\" && \"right-0\"\n      )}\n      onClick={() => setShow(!show)}\n    >\n      <FaBars size=\"12\" className=\"z-20 m-2 text-slate-11\" />\n    </button>\n  );\n};\nexport default Sidebar;\n"
  },
  {
    "path": "next/src/components/drawer/TaskSidebar.tsx",
    "content": "import clsx from \"clsx\";\nimport { AnimatePresence } from \"framer-motion\";\nimport { useTranslation } from \"next-i18next\";\nimport React from \"react\";\nimport { FaBars, FaTimesCircle } from \"react-icons/fa\";\nimport { v1 } from \"uuid\";\n\nimport Sidebar from \"./Sidebar\";\nimport { useAgentStore } from \"../../stores\";\nimport { useConfigStore } from \"../../stores/configStore\";\nimport { useTaskStore } from \"../../stores/taskStore\";\nimport type { Task as TaskType } from \"../../types/task\";\nimport { MESSAGE_TYPE_TASK, TASK_STATUS_STARTED } from \"../../types/task\";\nimport Button from \"../Button\";\nimport Input from \"../Input\";\nimport FadeIn from \"../motions/FadeIn\";\nimport { getMessageContainerStyle, getTaskStatusIcon } from \"../utils/helpers\";\n\nconst TaskSidebar = () => {\n  const [customTask, setCustomTask] = React.useState(\"\");\n  const agent = useAgentStore.use.agent();\n  const tasks = useTaskStore.use.tasks();\n  const addTask = useTaskStore.use.addTask();\n  const [t] = useTranslation();\n\n  const { layout, setLayout } = useConfigStore();\n\n  const setShow = (show: boolean) => {\n    setLayout({ showRightSidebar: show });\n  };\n\n  const handleAddTask = () => {\n    addTask({\n      id: v1().toString(),\n      taskId: v1().toString(),\n      value: customTask,\n      status: TASK_STATUS_STARTED,\n      type: MESSAGE_TYPE_TASK,\n    });\n    setCustomTask(\"\");\n  };\n\n  return (\n    <Sidebar\n      show={layout.showRightSidebar}\n      setShow={setShow}\n      side=\"right\"\n      className=\"border-slate-6s border-l\"\n    >\n      <div className=\"flex h-screen flex-col gap-2 text-slate-12\">\n        <div className=\"flex flex-row items-center gap-1\">\n          <button\n            className=\"neutral-button-primary rounded-md border-none transition-all\"\n            onClick={() => setShow(!layout.showRightSidebar)}\n          >\n            <FaBars size=\"15\" className=\"z-20 m-2\" />\n          </button>\n          <div className=\"ml-5 font-bold\">{t(\"Current tasks\")}</div>\n        </div>\n        <div className=\"flex flex-1 flex-col gap-2 overflow-auto pr-1\">\n          {tasks.length == 0 && (\n            <p className=\"w-full p-2 text-slate-11\">\n              This window will display agent tasks as they are created.\n            </p>\n          )}\n          <AnimatePresence>\n            {tasks.map((task) => (\n              <Task key={`${task.id || \"\"} ${task.taskId || \"\"}`} task={task} />\n            ))}\n          </AnimatePresence>\n        </div>\n        <div className=\"flex flex-row gap-1\">\n          <Input\n            value={customTask}\n            onChange={(e) => setCustomTask(e.target.value)}\n            placeholder={\"Custom task\"}\n            small\n          />\n          <Button\n            className=\"font-sm px-2 py-[0] text-sm sm:px-2 sm:py-[0]\"\n            onClick={handleAddTask}\n            disabled={!customTask || agent == null}\n          >\n            Add\n          </Button>\n        </div>\n      </div>\n    </Sidebar>\n  );\n};\n\nconst Task = ({ task }: { task: TaskType }) => {\n  const isAgentStopped = useAgentStore.use.lifecycle() === \"stopped\";\n  const deleteTask = useTaskStore.use.deleteTask();\n  const isTaskDeletable = task.taskId && !isAgentStopped && task.status === \"started\";\n\n  const handleDeleteTask = () => {\n    if (isTaskDeletable) {\n      deleteTask(task.taskId as string);\n    }\n  };\n\n  return (\n    <FadeIn>\n      <div\n        className={clsx(\n          \"w-full rounded-md bg-slate-1 p-2 text-sm text-slate-12 shadow-depth-1\",\n          isAgentStopped && \"opacity-50\",\n          getMessageContainerStyle(task)\n        )}\n      >\n        {getTaskStatusIcon(task, { isAgentStopped })}\n        <span>{task.value}</span>\n        <div className=\"flex justify-end\">\n          <FaTimesCircle\n            onClick={handleDeleteTask}\n            className={clsx(\n              isTaskDeletable && \"cursor-pointer hover:text-red-500\",\n              !isTaskDeletable && \"cursor-not-allowed opacity-30\"\n            )}\n          />\n        </div>\n      </div>\n    </FadeIn>\n  );\n};\n\nexport default TaskSidebar;\n"
  },
  {
    "path": "next/src/components/index/chat.tsx",
    "content": "import { useTranslation } from \"next-i18next\";\nimport React from \"react\";\n\nimport { useSettings } from \"../../hooks/useSettings\";\nimport { useAgentStore } from \"../../stores\";\nimport { useTaskStore } from \"../../stores/taskStore\";\nimport type { Message } from \"../../types/message\";\nimport AgentControls from \"../console/AgentControls\";\nimport { ChatMessage } from \"../console/ChatMessage\";\nimport ChatWindow from \"../console/ChatWindow\";\nimport { ChatWindowTitle } from \"../console/ChatWindowTitle\";\nimport Summarize from \"../console/SummarizeButton\";\nimport FadeIn from \"../motions/FadeIn\";\n\ntype ChatProps = {\n  messages: Message[];\n  disableStartAgent: boolean;\n  handlePlay: (name: string, goal: string) => void;\n  nameInput: string;\n  goalInput: string;\n  setShowSignInDialog: (boolean) => void;\n  setAgentRun: (newName: string, newGoal: string) => void;\n};\nconst Chat = (props: ChatProps) => {\n  const { settings } = useSettings();\n  const { t } = useTranslation(\"indexPage\");\n  const [chatInput, setChatInput] = React.useState(\"\");\n  const agent = useAgentStore.use.agent();\n  const agentLifecycle = useAgentStore.use.lifecycle();\n\n  const tasks = useTaskStore.use.tasks();\n\n  return (\n    <>\n      <div className=\"flex w-full flex-grow flex-col items-center overflow-hidden\">\n        <ChatWindow\n          messages={props.messages}\n          title={<ChatWindowTitle model={settings.customModelName} />}\n          chatControls={\n            agent\n              ? {\n                  value: chatInput,\n                  onChange: (value: string) => {\n                    setChatInput(value);\n                  },\n                  handleChat: async () => {\n                    const currentInput = chatInput;\n                    setChatInput(\"\");\n                    await agent?.chat(currentInput);\n                  },\n                  loading: tasks.length == 0 || chatInput === \"\",\n                }\n              : undefined\n          }\n        >\n          {props.messages.map((message, index) => {\n            return (\n              <FadeIn key={`${index}-${message.type}`}>\n                <ChatMessage message={message} />\n              </FadeIn>\n            );\n          })}\n          <Summarize />\n        </ChatWindow>\n      </div>\n      <AgentControls\n        disablePlay={props.disableStartAgent}\n        lifecycle={agentLifecycle}\n        handlePlay={() => props.handlePlay(props.nameInput, props.goalInput)}\n        handlePause={() => agent?.pauseAgent()}\n        handleStop={() => agent?.stopAgent()}\n      />\n    </>\n  );\n};\n\nexport default Chat;\n"
  },
  {
    "path": "next/src/components/index/landing.tsx",
    "content": "import { motion } from \"framer-motion\";\nimport { useTranslation } from \"next-i18next\";\nimport type { KeyboardEvent, RefObject } from \"react\";\nimport { useState } from \"react\";\nimport { FaCog, FaPlay, FaStar } from \"react-icons/fa\";\n\nimport { useAgentStore } from \"../../stores\";\nimport type { Message } from \"../../types/message\";\nimport AppTitle from \"../AppTitle\";\nimport Button from \"../Button\";\nimport ExampleAgents from \"../console/ExampleAgents\";\nimport { ToolsDialog } from \"../dialog/ToolsDialog\";\nimport Globe from \"../Globe\";\nimport Input from \"../Input\";\n\ntype LandingProps = {\n  messages: Message[];\n  disableStartAgent: boolean;\n  handlePlay: () => void;\n  handleKeyPress: (e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n  goalInputRef: RefObject<HTMLInputElement>;\n  goalInput: string;\n  setGoalInput: (string) => void;\n  setShowSignInDialog: (boolean) => void;\n  setAgentRun: (newName: string, newGoal: string) => void;\n};\nconst Landing = (props: LandingProps) => {\n  const [showToolsDialog, setShowToolsDialog] = useState(false);\n\n  const { t } = useTranslation(\"indexPage\");\n  const agent = useAgentStore.use.agent();\n\n  return (\n    <>\n      <ToolsDialog show={showToolsDialog} setOpen={setShowToolsDialog} />\n      <motion.div\n        initial={{ opacity: 0, y: -50 }}\n        animate={{ opacity: 1, y: 0 }}\n        transition={{ duration: 0.75, type: \"easeInOut\" }}\n        className=\"z-10\"\n      >\n        <AppTitle />\n      </motion.div>\n      <div className=\"absolute left-0 right-0 m-auto grid place-items-center overflow-hidden opacity-40\">\n        <Globe />\n      </div>\n      <motion.div\n        initial={{ opacity: 0, y: -50 }}\n        animate={{ opacity: 1, y: 0 }}\n        transition={{ duration: 0.75, delay: 1, type: \"easeInOut\" }}\n        className=\"z-10\"\n      >\n        <ExampleAgents setAgentRun={props.setAgentRun} setShowSignIn={props.setShowSignInDialog} />\n      </motion.div>\n      <motion.div\n        initial={{ opacity: 0, y: 50 }}\n        animate={{ opacity: 1, y: 0 }}\n        transition={{ duration: 0.75, delay: 0.5, type: \"easeInOut\" }}\n        className=\"z-10 flex w-full flex-col gap-6\"\n      >\n        <Input\n          inputRef={props.goalInputRef}\n          left={\n            <>\n              <FaStar />\n              <span className=\"ml-2\">{`${t(\"LABEL_AGENT_GOAL\")}`}</span>\n            </>\n          }\n          disabled={agent != null}\n          value={props.goalInput}\n          onChange={(e) => props.setGoalInput(e.target.value)}\n          onKeyDown={props.handleKeyPress}\n          placeholder={`${t(\"PLACEHOLDER_AGENT_GOAL\")}`}\n          type=\"textarea\"\n        />\n\n        <div className=\"flex w-full flex-row items-center justify-center gap-3\">\n          <Button\n            ping\n            onClick={() => setShowToolsDialog(true)}\n            className=\"h-full bg-gradient-to-t from-slate-9 to-slate-12 hover:shadow-depth-3\"\n          >\n            <FaCog />\n          </Button>\n          <Button\n            onClick={props.handlePlay}\n            className=\"border-0 bg-gradient-to-t from-[#02FCF1] to-[#A02BFE] subpixel-antialiased saturate-[75%] hover:saturate-100\"\n          >\n            <FaPlay />\n          </Button>\n        </div>\n      </motion.div>\n    </>\n  );\n};\n\nexport default Landing;\n"
  },
  {
    "path": "next/src/components/landing/Backing.tsx",
    "content": "import clsx from \"clsx\";\n\nimport PanacheLogo from \"../../../public/logos/panache-default-solid.svg\";\nimport YCLogo from \"../../../public/logos/yc-default-solid.svg\";\n\nconst Backing = (props: { className?: string }) => (\n  <div\n    className={clsx(\n      \"flex flex-col font-inter text-xs font-normal text-white/50 md:text-sm\",\n      props.className\n    )}\n  >\n    <div className=\"flex flex-row items-center gap-x-1\">\n      <div className=\"ml-2 mr-1 flex flex-row items-center\">\n        <a\n          className=\" z-10 -mr-2 cursor-pointer\"\n          href=\"https://www.ycombinator.com/companies/reworkd\"\n          target=\"_blank\"\n        >\n          <YCLogo />\n        </a>\n        <a href=\"https://www.panache.vc/\" target=\"_blank\" className=\"cursor-pointer\">\n          <PanacheLogo />\n        </a>\n      </div>\n      <div className=\"hidden tracking-wide sm:flex\">Backed By</div>\n      <a\n        className=\"flex cursor-pointer flex-row items-center gap-1 font-light text-white/95\"\n        href=\"https://www.ycombinator.com/companies/reworkd\"\n        target=\"_blank\"\n      >\n        Y Combinator\n      </a>\n      <span>and</span>\n      <a\n        className=\"cursor-pointer font-light text-white/95\"\n        href=\"https://www.panache.vc/\"\n        target=\"_blank\"\n      >\n        Panache Ventures\n      </a>\n    </div>\n  </div>\n);\n\nexport default Backing;\n"
  },
  {
    "path": "next/src/components/landing/ConnectorSection.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\nconst ConnectorSection = () => {\n  return (\n    <div\n      className={clsx(\n        \"h-screen w-screen items-center justify-center overflow-hidden\",\n        \"bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))]\",\n        \"from-purple-500/10 from-20% to-transparent to-60%\"\n      )}\n    >\n      <div className=\"flex flex-col items-center justify-center\">\n        <div className=\"mt-20 text-center\">\n          <h1 className=\"mb-4 text-6xl font-medium\">Integrate with your</h1>\n          <h1 className=\"text-6xl font-semibold\">Entire Stack</h1>\n        </div>\n        <div className=\"mt-5\">\n          <h2 className=\"text-thin\">Custom Connectors for every part of your business</h2>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport default ConnectorSection;\n"
  },
  {
    "path": "next/src/components/landing/FooterLinks.tsx",
    "content": "import type { FC, ReactNode } from \"react\";\n\ninterface FooterLinkProps {\n  href: string;\n  children: ReactNode;\n}\n\nconst FooterLink: FC<FooterLinkProps> = ({ href, children }) => (\n  <a\n    href={href}\n    target=\"_blank\"\n    rel=\"noopener noreferrer\"\n    className=\"group w-full rounded-full bg-transparent px-2 text-sm text-white/50 transition-colors duration-300 ease-in-out hover:text-white/90\"\n  >\n    {children}\n  </a>\n);\n\nconst FooterLinks = () => {\n  return (\n    <div className=\"hidden cursor-pointer flex-row justify-center space-x-4 lg:flex\">\n      <FooterLink href=\"https://www.ycombinator.com/companies/reworkd/jobs\">Careers</FooterLink>\n      <FooterLink href=\"https://status.reworkd.ai\">\n        <div className=\"flex items-center gap-3\">\n          <p>Status</p>\n          <div className=\"h-[6px] w-[6px] animate-pulse items-center justify-center rounded-full bg-green-500 ring-[3px] ring-green-500 ring-opacity-60\"></div>\n        </div>\n      </FooterLink>\n      <FooterLink href=\"https://agentgpt.reworkd.ai/privacypolicy\">Privacy</FooterLink>\n      <FooterLink href=\"https://agentgpt.reworkd.ai/terms\">Terms</FooterLink>\n    </div>\n  );\n};\n\nexport default FooterLinks;\n"
  },
  {
    "path": "next/src/components/landing/Hero.tsx",
    "content": "import Spline from \"@splinetool/react-spline\";\nimport clsx from \"clsx\";\nimport { motion } from \"framer-motion\";\nimport Image from \"next/image\";\nimport { useRouter } from \"next/router\";\nimport type { FC } from \"react\";\nimport { Suspense, useEffect, useState } from \"react\";\nimport { FaChevronLeft, FaChevronRight } from \"react-icons/fa\";\n\nimport BlueHeroIcon from \"../../../public/icons/icon-hero-blue.svg\";\nimport GreenHeroIcon from \"../../../public/icons/icon-hero-green.svg\";\nimport OrangeHeroIcon from \"../../../public/icons/icon-hero-orange.svg\";\nimport PurpleHeroIcon from \"../../../public/icons/icon-hero-purple.svg\";\nimport BannerBadge from \"../BannerBadge\";\nimport GlowWrapper from \"../GlowWrapper\";\nimport HeroCard from \"../HeroCard\";\nimport FadeIn from \"../motions/FadeIn\";\nimport PrimaryButton from \"../PrimaryButton\";\n\nconst Hero: FC<{ className?: string }> = ({ className }) => {\n  const router = useRouter();\n  const [sliderIndex, setSliderIndex] = useState(0);\n  const totalCards = roles.length;\n  const [showVideo, setShowVideo] = useState(false);\n\n  const handleWindowResize = () => {\n    setShowVideo(window.innerWidth <= 768);\n  };\n\n  const handleSliderButtonLeft = (decrement: number) => {\n    if (sliderIndex != 0) {\n      const newIndex = (sliderIndex - decrement + totalCards) % totalCards;\n      setSliderIndex(newIndex);\n    }\n  };\n\n  const handleSliderButtonRight = (increment: number) => {\n    if (sliderIndex != roles.length - 2) {\n      const newIndex = (sliderIndex + increment + totalCards) % totalCards;\n      setSliderIndex(newIndex);\n    }\n  };\n\n  useEffect(() => {\n    window.addEventListener(\"resize\", handleWindowResize);\n\n    return () => {\n      window.removeEventListener(\"resize\", handleWindowResize);\n    };\n  }, []);\n\n  return (\n    <FadeIn\n      delay={0.75}\n      duration={3}\n      className={clsx(\"grid grid-cols-1 place-items-center gap-2 md:grid-cols-2\", className)}\n    >\n      <div className=\"relative z-30 flex h-full w-full justify-center md:flex md:h-[30vw] md:w-[30vw]\">\n        <div className=\"absolute -z-10 h-full w-full bg-gradient-radial from-[#1152FA] via-[#882BFE] to-70% opacity-25\" />\n        {showVideo ? (\n          <Image\n            src=\"/prod_square.png\"\n            alt=\"A 3D blob that seems to represent most AI companies\"\n            width=\"500\"\n            height=\"500\"\n            className=\"w-52\"\n          />\n        ) : (\n          <Suspense>\n            <Spline\n              scene=\"https://draft.spline.design/n2h-XebGYJ95sdSw/scene.splinecode\"\n              className=\"hidden md:flex\"\n            />\n          </Suspense>\n        )}\n      </div>\n      <div className=\"relative z-10 col-span-1 max-w-full md:order-first\">\n        <div className=\"relative flex flex-col items-center gap-4 md:items-start md:gap-12\">\n          <BannerBadge\n            href=\"https://www.ycombinator.com/launches/J1r-reworkd-ai-the-open-source-zapier-of-ai-agents\"\n            target=\"_blank\"\n            className=\"hidden md:flex\"\n          >\n            <span className=\"tracking-wider text-gray-300\">Reworkd raises a $1.25M pre-seed</span>\n          </BannerBadge>\n          <div className=\"flex flex-col items-center md:items-start\">\n            <h1 className=\"resend-font-effect-hero bg-gradient-to-br from-white to-white/30 bg-clip-text pb-2 text-center text-5xl font-normal tracking-[.09rem] text-transparent md:text-left md:text-5xl lg:text-6xl xl:text-7xl\">\n              <div>\n                <span className=\"bg-gradient-to-r from-[#1E26FF] to-[#FF04FF] bg-clip-text text-transparent\">\n                  Web Extraction\n                </span>{\" \"}\n                <span className=\"bg-gradient-to-r from-white to-transparent bg-clip-text text-transparent\">\n                  At Your Fingertips.\n                  <br />\n                </span>\n              </div>\n            </h1>\n            <p className=\"my-3 inline-block bg-gradient-to-r from-white via-white via-50% to-neutral-500 bg-clip-text text-center align-top font-inter font-[400] leading-[24px] tracking-[.08rem] text-transparent sm:w-4/5 md:text-left\">\n              Optimize web scraping with AI that generates and repairs scraping code, adapting to\n              website changes. Scale your data extraction effortlessly.\n            </p>\n          </div>\n\n          <div className=\"relative hidden w-full items-center sm:max-w-[40em] md:flex\">\n            <button\n              onClick={() => handleSliderButtonLeft(1)}\n              className=\"group absolute left-0 z-30 flex h-6 w-8 -translate-x-5 items-center justify-center rounded-full border border-white/20 bg-black bg-gradient-to-r from-white/10 to-black opacity-75 hover:border-white/30\"\n            >\n              <FaChevronLeft\n                size={10}\n                className=\"text-gray-400 transition-transform group-hover:translate-x-0.5\"\n              />\n            </button>\n            <div className=\"relative hidden w-full items-center overflow-hidden sm:max-w-[40em] md:flex\">\n              <motion.div\n                className=\"z-20 flex gap-5\"\n                animate={{ x: `${sliderIndex * -308}px` }}\n                transition={{ duration: 0.5, type: \"spring\", stiffness: 60 }}\n              >\n                {roles.map((role, index) => (\n                  <HeroCard\n                    key={role.title}\n                    title={role.title}\n                    subtitle={role.subtitle}\n                    leftIcon={role.icon}\n                  />\n                ))}\n              </motion.div>\n            </div>\n            <div className=\"absolute left-0 z-20 h-full w-6 -translate-x-0.5 bg-gradient-to-l from-transparent to-black\" />\n            <div className=\"absolute right-0 z-20 h-full w-40 translate-x-0.5 bg-gradient-to-r from-transparent to-black to-75%\" />\n            <button\n              onClick={() => handleSliderButtonRight(1)}\n              className=\"group absolute right-10 z-30 flex h-6 w-8 items-center justify-center rounded-full border border-white/20 bg-black bg-gradient-to-r from-white/10 to-black opacity-75 hover:border-white/30\"\n            >\n              <FaChevronRight\n                size={10}\n                className=\"text-gray-400 transition-transform group-hover:translate-x-0.5\"\n              />\n            </button>\n          </div>\n\n          <div className=\"flex flex-col items-center justify-center gap-4 md:flex-row md:justify-start\">\n            <GlowWrapper>\n              <PrimaryButton\n                icon={<Image src=\"email-24x24.svg\" width=\"24\" height=\"24\" alt=\"Email\" />}\n                onClick={() => {\n                  window.open(\"https://6h6bquxo5g1.typeform.com/to/qscfsOf1\", \"_blank\");\n                }}\n              >\n                <>\n                  <span className=\"py-2 font-medium\">Join the Waitlist</span>\n                  <FaChevronRight\n                    size=\"10\"\n                    className=\"text-gray-400 transition-transform group-hover:translate-x-1\"\n                  />\n                </>\n              </PrimaryButton>\n            </GlowWrapper>\n          </div>\n        </div>\n      </div>\n    </FadeIn>\n  );\n};\n\nconst roles = [\n  {\n    title: \"Manufacturing\",\n    subtitle: \"Collect product data\",\n    icon: <PurpleHeroIcon />,\n  },\n  {\n    title: \"E-commerce\",\n    subtitle: \"Get competitor prices\",\n    icon: <OrangeHeroIcon />,\n  },\n  {\n    title: \"Recruiting\",\n    subtitle: \"Scrape job postings\",\n    icon: <GreenHeroIcon />,\n  },\n  {\n    title: \"Lead Generation\",\n    subtitle: \"Assemble prospect list\",\n    icon: <PurpleHeroIcon />,\n  },\n  {\n    title: \"Real Estate\",\n    subtitle: \"Get property listings\",\n    icon: <BlueHeroIcon />,\n  },\n  {\n    title: \"Media\",\n    subtitle: \"Get News & Article data\",\n    icon: <OrangeHeroIcon />,\n  },\n];\n\nexport default Hero;\n"
  },
  {
    "path": "next/src/components/landing/OpenSource.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\nimport { FaGithub } from \"react-icons/fa\";\n\nimport { MacWindowInternal } from \"../console/MacWindowHeader\";\nimport PrimaryButton from \"../PrimaryButton\";\n\ninterface TerminalProps {\n  className?: string;\n  title?: string;\n  children?: React.ReactNode;\n}\n\nconst OpenSource = () => {\n  return (\n    <div className=\"min-h-[50vh] w-full\">\n      <div className=\"flex flex-row\">\n        <div className=\"relative hidden w-full md:flex\">\n          <Terminal className=\"absolute\" title=\"index.ts\">\n            <pre className=\"overflow-x-hidden\">\n              {\"\" +\n                \"<!DOCTYPE html>\\n\" +\n                \"<html>\\n\" +\n                \"<head>\\n\" +\n                \" <title>My AgentGPT Website</title>\\n\" +\n                \"</head>\\n\" +\n                \"<body>\\n\" +\n                \"  <h1>Welcome to AgentGPT!</h1>\\n\" +\n                \"  <p>Explore the power of autonomous AI agents.</p>\\n\" +\n                '  <script src=\"https://agentgpt.reworkd.ai/agentgpt.js\"></script>\\n' +\n                \"  <script>\\n\" +\n                \"    // Connect to AgentGPT API\\n\" +\n                \"    const agent = new AgentGPT();\\n\" +\n                \"    agent.connect('YOUR_API_KEY');\\n\" +\n                \"    \\n\" +\n                \"    // Example code to interact with AgentGPT\\n\" +\n                \"    agent.createAgent('MyAIAssistant');\\n\" +\n                \"    agent.setGoal('Sort my emails');\\n\" +\n                \"    agent.start();\\n\" +\n                \"  </script>\\n\" +\n                \"</body>\\n\" +\n                \"</html>\\n\"}\n            </pre>\n          </Terminal>\n          <Terminal className=\"absolute left-16 top-20 z-10\" title=\"agent_service.py\">\n            <pre className=\"overflow-x-hidden\">\n              {\"import requests\\n\" +\n                \"\\n\" +\n                \"# Define the API endpoint\\n\" +\n                'url = \"https://api.agentgpt.example.com\"\\n' +\n                \"\\n\" +\n                \"# Make a GET request to retrieve data from the API\\n\" +\n                \"response = requests.get(url)\\n\" +\n                \"\\n\" +\n                \"# Process the response data\\n\" +\n                \"if response.status_code == 200:\\n\" +\n                \"    data = response.json()\\n\" +\n                \"    # Perform further actions with the data\\n\" +\n                \"    print(data)\\n\" +\n                \"else:\\n\" +\n                '    print(\"Error: Unable to fetch data from the API\")\\n'}\n            </pre>\n          </Terminal>\n        </div>\n        <div className=\"mt-28 w-full\">\n          <div className=\"flex w-fit flex-row items-center gap-2 rounded-full bg-neutral-900 bg-gradient-to-bl from-neutral-800  to-transparent p-2 pr-4\">\n            <FaGithub size={32} />\n            <div>\n              24.4 k<span className=\"text-gray-400\"> stars</span>\n            </div>\n          </div>\n          <h3 className=\"my-4 text-6xl font-medium tracking-tight\">Proudly Open Source</h3>\n          <p className=\"mb-8 font-extralight leading-7 text-gray-400\">\n            We think the power of AI should be available to everyone and should be driven by\n            community. This is why we are proudly open source. We&apos;d love to hear your feedback\n            at every step of the journey.\n          </p>\n          <div className=\"mt-6 flex flex-row gap-4\">\n            <a href=\"https://github.com/reworkd\" target=\"_blank\">\n              <PrimaryButton>View on Github</PrimaryButton>\n            </a>\n            <a href=\"https://github.com/orgs/reworkd/projects/3\" target=\"_blank\">\n              <PrimaryButton>Public Roadmap</PrimaryButton>\n            </a>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nconst Terminal = (props: TerminalProps) => {\n  return (\n    <div\n      className={clsx(\"w-3/4 max-w-md rounded-xl bg-neutral-800 drop-shadow-2xl\", props.className)}\n    >\n      <MacWindowInternal>{props.title}</MacWindowInternal>\n      <div className=\"h-72 overflow-hidden rounded-b-xl bg-neutral-900 p-4 text-[8pt] text-gray-400\">\n        {props.children}\n      </div>\n    </div>\n  );\n};\n\nexport default OpenSource;\n"
  },
  {
    "path": "next/src/components/landing/Section.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\nimport Highlight from \"../../ui/highlight\";\n\nconst Sections = () => {\n  return (\n    <>\n      <Section\n        className=\"col-span-1\"\n        title=\"Intelligent Logging\"\n        subtitle=\"Experience Complete Transparency with Detailed Step-By-Step Logs from Your LLM\"\n      ></Section>\n      <Section\n        className=\"col-span-2\"\n        title=\"Human in the Loop\"\n        subtitle=\"Maintain Control and Decision-Making Power with our AI-Assisted Automation\"\n      ></Section>\n      <Section\n        className=\"col-span-1\"\n        title=\"Web Search\"\n        subtitle=\"Empower Your Agents with Access to Real-Time Web Information\"\n      ></Section>\n      <Section\n        className=\"col-span-2\"\n        title=\"Long Term Memory for Agents\"\n        subtitle=\"Enhance Your Workflow with Agents Capable of Detailed Recall and Context Preservation\"\n      ></Section>\n      <Section\n        className=\"col-span-2\"\n        title=\"AI-Driven Workflows\"\n        subtitle=\"Design and Implement Custom Workflows that Drive Efficiency and Productivity\"\n      ></Section>\n      <Section\n        className=\"col-span-1\"\n        title=\"Business Automation\"\n        subtitle=\"Achieve Unprecedented Levels of Automation Across Your Entire Business\"\n      ></Section>\n      <Section\n        className=\"col-span-2\"\n        title=\"Customization at Its Best\"\n        subtitle=\"Craft Your AI Workflows to Fit Your Unique Business Requirements\"\n      ></Section>\n      <Section\n        className=\"col-span-1\"\n        title=\"Continuous Improvement\"\n        subtitle=\"Benefit from Constant Upgrades and Enhancements, Driven by Our Open-Source Commitment\"\n      ></Section>\n    </>\n  );\n};\n\ninterface ResourceProps {\n  title: string;\n  subtitle: string;\n  className: string;\n}\n\nconst Section = ({ title, subtitle, className }: ResourceProps) => {\n  return (\n    <div\n      className={clsx(\n        className,\n        \"group relative flex h-full rounded-xl border border-white/20 bg-black p-10 transition duration-300 hover:border-sky-500/60\"\n      )}\n    >\n      <Highlight color=\"blue\" />\n      <div className=\"relative rounded-xl\">\n        <h3 className=\"text-xl font-bold leading-7 \">{title}</h3>\n        <p className=\"text-sm text-zinc-400\">{subtitle}</p>\n      </div>\n    </div>\n  );\n};\n\nexport default Sections;\n"
  },
  {
    "path": "next/src/components/loader.tsx",
    "content": "import { Ring } from \"@uiball/loaders\";\nimport type { FC } from \"react\";\n\ninterface LoaderProps {\n  className?: string;\n  size?: number;\n  speed?: number;\n  lineWeight?: number;\n  color?: string;\n}\n\nconst Loader: FC<LoaderProps> = ({\n  className,\n  size = 16,\n  speed = 2,\n  lineWeight = 7,\n  color = \"white\",\n}) => {\n  return (\n    <div className={className}>\n      <Ring size={size} speed={speed} color={color} lineWeight={lineWeight} />\n    </div>\n  );\n};\n\nexport default Loader;\n"
  },
  {
    "path": "next/src/components/motions/CycleIcons.tsx",
    "content": "import { motion } from \"framer-motion\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\n\nimport GlowWrapper from \"../GlowWrapper\";\n\ninterface CycleItemsProps extends PropsWithChildren {\n  className?: string;\n  currentIndex: number;\n  hoveredItemIndex: number;\n  icons: ReactNode[];\n}\n\nconst CycleIcons = (props: CycleItemsProps) => {\n  return (\n    <GlowWrapper className=\"opacity-75\">\n      <div className=\"flex h-[28px] w-[28px] flex-row justify-start gap-x-4 overflow-hidden rounded-full bg-white p-1.5\">\n        <motion.div\n          className=\"flex gap-2\"\n          animate={{\n            x: props.hoveredItemIndex ? -24 * props.hoveredItemIndex : -24 * props.currentIndex,\n          }}\n          transition={{ type: \"spring\", duration: 0.5, stiffness: 60, damping: 10 }}\n        >\n          {props.icons.map((item, i) => (\n            <motion.div\n              key={`cycle-icon-${i}`}\n              className={props.className}\n              transition={{ type: \"spring\", stiffness: 350, damping: 25 }}\n            >\n              {item}\n            </motion.div>\n          ))}\n        </motion.div>\n      </div>\n    </GlowWrapper>\n  );\n};\n\nexport default CycleIcons;\n"
  },
  {
    "path": "next/src/components/motions/FadeIn.tsx",
    "content": "import { motion } from \"framer-motion\";\nimport type { PropsWithChildren } from \"react\";\n\ninterface MotionProps extends PropsWithChildren {\n  className?: string;\n  delay?: number;\n  duration?: number;\n  initialY?: number;\n  initialX?: number;\n}\n\nconst FadeIn = (props: MotionProps) => {\n  // Because we are directly applying props, we cannot place initialX and initialY in the motion.div\n  const { initialY = -30, initialX = 0, duration = 0.5, delay = 0, className } = props;\n\n  return (\n    <motion.div\n      initial={{ opacity: 0, x: initialX, y: initialY }}\n      animate={{ opacity: 1, x: 0, y: 0 }}\n      transition={{ duration, type: \"spring\", delay }}\n      className={className}\n    >\n      {props.children}\n    </motion.div>\n  );\n};\n\nFadeIn.displayName = \"FadeIn\";\nexport default FadeIn;\n"
  },
  {
    "path": "next/src/components/motions/FadeOut.tsx",
    "content": "import { motion } from \"framer-motion\";\nimport type { PropsWithChildren } from \"react\";\n\ninterface MotionProps extends PropsWithChildren {\n  className?: string;\n  delay?: number;\n}\n\nconst FadeOut = (props: MotionProps) => (\n  <motion.div\n    exit={{ opacity: 0, x: -100 }}\n    animate={{ scale: 1 }}\n    transition={{ duration: 0.5, type: \"spring\", delay: props.delay ?? 0 }}\n    {...props}\n  >\n    {props.children}\n  </motion.div>\n);\n\nFadeOut.displayName = \"FadeOut\";\nexport default FadeOut;\n"
  },
  {
    "path": "next/src/components/motions/HideShow.tsx",
    "content": "import { motion } from \"framer-motion\";\nimport type { PropsWithChildren } from \"react\";\n\ninterface MotionProps extends PropsWithChildren {\n  showComponent: boolean;\n  className?: string;\n}\n\nconst HideShow = (props: MotionProps) => {\n  const { showComponent, ...rest } = props;\n  return (\n    <motion.span\n      animate={showComponent ? \"show\" : \"hide\"}\n      variants={{\n        show: { opacity: 1, visibility: \"visible\" },\n        hide: { opacity: 0, visibility: \"hidden\" },\n      }}\n      {...rest}\n    >\n      {props.children}\n    </motion.span>\n  );\n};\n\nHideShow.displayName = \"HideShow\";\nexport default HideShow;\n"
  },
  {
    "path": "next/src/components/motions/expand.tsx",
    "content": "import { motion } from \"framer-motion\";\nimport type { PropsWithChildren } from \"react\";\n\ninterface MotionProps extends PropsWithChildren {\n  className?: string;\n  delay?: number;\n  type?: \"spring\" | \"tween\";\n}\n\nconst Expand = (props: MotionProps) => (\n  <motion.div\n    initial={{ scaleX: 0.8, scaleY: 0 }}\n    animate={{ scaleX: 1, scaleY: 1 }}\n    transition={{\n      duration: 0.75,\n      type: props.type ?? \"spring\",\n      delay: props.delay ?? 0,\n    }}\n    {...props}\n  >\n    {props.children}\n  </motion.div>\n);\n\nExpand.displayName = \"Expand\";\nexport default Expand;\n"
  },
  {
    "path": "next/src/components/motions/popin.tsx",
    "content": "import { motion } from \"framer-motion\";\nimport type { MouseEventHandler, PropsWithChildren } from \"react\";\n\ninterface MotionProps extends PropsWithChildren {\n  className?: string;\n  delay?: number;\n  duration?: number;\n  onClick?: MouseEventHandler<HTMLDivElement>;\n}\n\nconst PopIn = (props: MotionProps) => (\n  <motion.div\n    exit={{ scale: 0 }}\n    initial={{ scale: 0 }}\n    animate={{ scale: 1 }}\n    transition={{ duration: props.duration ?? 0.3, type: \"spring\", delay: props.delay ?? 0 }}\n    {...props}\n    onClick={props.onClick}\n  >\n    {props.children}\n  </motion.div>\n);\n\nPopIn.displayName = \"PopIn\";\nexport default PopIn;\n"
  },
  {
    "path": "next/src/components/pdf/MyDocument.tsx",
    "content": "import ReactPDF, { Document, Font, Page, StyleSheet, Text } from \"@react-pdf/renderer\";\nimport { i18n } from \"next-i18next\";\nimport React from \"react\";\n\nimport View = ReactPDF.View;\n\nconst getFontUrlForLanguageCode = (languageCode: string) => {\n  switch (languageCode) {\n    case \"en\":\n      return \"\"; // Do not use a custom font for english\n    case \"zh\":\n      return \"/fonts/SimSun.ttf\";\n    case \"ja\":\n      return \"/fonts/Nasu-Regular.ttf\";\n    case \"ko\":\n      return \"/fonts/NanumMyeongjo-Regular.ttf\";\n    default:\n      return \"/fonts/Roboto-Regular.ttf\";\n  }\n};\n\nconst getFontUrl = () => getFontUrlForLanguageCode(i18n?.language || \"en\");\n\nFont.register({\n  family: \"customFont\",\n  src: getFontUrl(),\n});\n\nconst styles = StyleSheet.create({\n  page: {\n    flexDirection: \"column\",\n    backgroundColor: \"#FFFFFF\",\n    padding: 40,\n    wordBreak: \"break-all\",\n  },\n  horizontalRule: {\n    borderBottomWidth: 0.3,\n    borderBottomColor: \"#000\",\n    borderBottomStyle: \"solid\",\n  },\n  section: {\n    fontSize: 10,\n    ...(getFontUrl() == \"\" ? {} : { fontFamily: \"customFont\" }),\n    marginVertical: 10,\n    lineHeight: 1.5,\n    wordBreak: \"break-all\",\n    paddingRight: 10,\n  },\n});\n\n// NOTE: This should only ever be imported dynamically to reduce load times\nconst MyDocument: React.FC<{\n  textSections: string[];\n}> = ({ textSections }) => (\n  <Document>\n    <Page size=\"A4\" style={styles.page}>\n      {textSections.map((text, index) => (\n        <>\n          <Text key={index} style={styles.section}>\n            {renderTextLines(text)}\n          </Text>\n          <HorizontalRule />\n        </>\n      ))}\n    </Page>\n  </Document>\n);\n\nconst HorizontalRule: React.FC = () => <View style={styles.horizontalRule} />;\n\nconst renderTextLines = (text: string): React.ReactNode[] => {\n  const MAX_LINE_LENGTH = 10;\n  const lines: string[] = [];\n  let start = 0;\n  while (start < text.length) {\n    const end = start + MAX_LINE_LENGTH;\n    const line: string = text.slice(start, end);\n    lines.push(line);\n    start = end;\n  }\n  return lines.map((line: string, index) => (\n    <React.Fragment key={index}>\n      {line}\n      <br />\n    </React.Fragment>\n  ));\n};\n\nexport default MyDocument;\n"
  },
  {
    "path": "next/src/components/pdf/PDFButton.tsx",
    "content": "import { pdf } from \"@react-pdf/renderer\";\nimport { i18n } from \"next-i18next\";\nimport React, { memo } from \"react\";\nimport { FaFilePdf } from \"react-icons/fa\";\n\nimport type { Message } from \"../../types/message\";\nimport { MESSAGE_TYPE_GOAL } from \"../../types/message\";\nimport { MESSAGE_TYPE_TASK } from \"../../types/task\";\nimport WindowButton from \"../WindowButton\";\n\nconst PDFButton = ({ messages, name }: { messages: Message[]; name: string }) => {\n  const textSections = getTextSections(messages);\n\n  const downloadPDF = async () => {\n    const MyDocument = (await import(\"./MyDocument\")).default as React.FC<{\n      textSections: string[];\n    }>;\n\n    const blob = await pdf(<MyDocument textSections={textSections} />).toBlob();\n    const url = URL.createObjectURL(blob);\n    const link = document.createElement(\"a\");\n    link.href = url;\n    link.download = \"my-document.pdf\";\n    link.click();\n    URL.revokeObjectURL(url);\n  };\n\n  return (\n    <>\n      <WindowButton\n        onClick={() => {\n          downloadPDF().catch(console.error);\n        }}\n        icon={<FaFilePdf size={12} />}\n        text={name}\n      />\n    </>\n  );\n};\n\nconst getTextSections = (messages: Message[]): string[] => {\n  // Note \"Thinking\" messages have no `value` so they show up as new lines\n  return messages\n    .map((message) => {\n      if (message.type == MESSAGE_TYPE_GOAL) {\n        return `${i18n?.t(\"LABEL_AGENT_GOAL\", { ns: \"indexPage\" })}: ${message.value}`;\n      }\n      if (message.type == MESSAGE_TYPE_TASK) {\n        if (message.info) {\n          return `${i18n?.t(\"EXECUTING\", { ns: \"common\" })}: \"${message.value}\": ${message.info}`;\n        } else {\n          return `${i18n?.t(\"ADDING_TASK\", { ns: \"common\" })}: ${message.value}`;\n        }\n      }\n      return message.value;\n    })\n    .filter((message) => message !== \"\");\n};\n\nexport default memo(PDFButton);\n"
  },
  {
    "path": "next/src/components/sidebar/AuthItem.tsx",
    "content": "import clsx from \"clsx\";\nimport { useRouter } from \"next/router\";\nimport type { Session } from \"next-auth\";\nimport { useTranslation } from \"next-i18next\";\nimport type { FC } from \"react\";\nimport React, { useState } from \"react\";\nimport { BsThreeDots } from \"react-icons/bs\";\nimport { FaSignInAlt } from \"react-icons/fa\";\n\nimport Dialog from \"../../ui/dialog\";\nimport { get_avatar } from \"../../utils/user\";\n\nconst AuthItem: FC<{\n  session: Session | null;\n  classname?: string;\n  signIn: () => Promise<void>;\n  signOut: () => Promise<void>;\n}> = ({ session, classname, signOut, signIn }) => {\n  const [t] = useTranslation(\"drawer\");\n  const [showDialog, setShowDialog] = useState(false);\n  const router = useRouter();\n  const user = session?.user;\n\n  const organization = user?.organizations?.at(0)?.name;\n\n  return (\n    <div className=\"flex items-center justify-between\">\n      <div\n        className={clsx(\n          \"flex flex-1 cursor-pointer items-center justify-start gap-3 rounded-md px-1.5 py-2 text-sm font-semibold text-slate-12 hover:bg-slate-5\",\n          classname\n        )}\n        onClick={(e) => {\n          user ? setShowDialog(true) : void signIn();\n        }}\n      >\n        {user && (\n          <div className=\"relative\">\n            <img\n              className=\"h-6 w-6 rounded-full bg-neutral-800\"\n              src={get_avatar(user)}\n              alt=\"user avatar\"\n            />\n          </div>\n        )}\n\n        {!user && (\n          <h1 className=\"ml-2 flex h-6 w-6 flex-grow items-center gap-2 text-center text-slate-12\">\n            <FaSignInAlt />\n            <p>Sign in</p>\n          </h1>\n        )}\n\n        <span className=\"sr-only\">Your profile</span>\n        <div>\n          <p aria-hidden=\"true\" className=\"max-w-[6.5rem] overflow-hidden text-ellipsis text-black\">\n            {user?.name}\n          </p>\n        </div>\n        {user && <BsThreeDots className=\"ml-auto text-black\" />}\n\n        <Dialog\n          inline\n          open={showDialog}\n          setOpen={setShowDialog}\n          title=\"My Account\"\n          icon={<img className=\"h-20 w-20 rounded-md\" src={get_avatar(user)} alt=\"\" />}\n          actions={\n            <>\n              <button\n                type=\"button\"\n                className=\"inline-flex w-full justify-center rounded-md bg-sky-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-sky-400\"\n                onClick={() => {\n                  signOut()\n                    .then(() => setShowDialog(false))\n                    .catch(console.error)\n                    .finally(console.log);\n                }}\n              >\n                Sign out\n              </button>\n              <button\n                type=\"button\"\n                className=\"inline-flex w-full justify-center rounded-md bg-slate-1 px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-slate-3\"\n                onClick={() => setShowDialog(false)}\n              >\n                Close\n              </button>\n            </>\n          }\n        >\n          <div className=\"mt-2 w-full text-center\">\n            <p className=\"max-w-full text-sm text-gray-600\">{user?.name}</p>\n            <p className=\"text-sm text-gray-400\">{user?.email}</p>\n          </div>\n        </Dialog>\n      </div>\n    </div>\n  );\n};\n\nexport default AuthItem;\n"
  },
  {
    "path": "next/src/components/sidebar/LinkIconItem.tsx",
    "content": "import type { ReactNode } from \"react\";\n\nconst LinkIconItem = (props: { children: ReactNode; href?: string; onClick: () => void }) => (\n  <a\n    href={props.href}\n    className=\"group grid h-10 w-10 cursor-pointer place-items-center rounded-xl text-2xl hover:bg-slate-5 group-hover:scale-110\"\n    onClick={(e) => {\n      e.preventDefault();\n      props.onClick();\n    }}\n  >\n    {props.children}\n  </a>\n);\n\nexport default LinkIconItem;\n"
  },
  {
    "path": "next/src/components/sidebar/LinkItem.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\n\nconst LinkItem = (props: {\n  title: string;\n  children: ReactNode;\n  forceRefresh?: boolean;\n  href?: string;\n  onClick: () => void;\n}) => (\n  <li>\n    <a\n      href={props.href || \"\"}\n      className={clsx(\n        \"group flex gap-x-3 rounded-md px-2 py-1 text-sm font-medium leading-7 text-slate-12 hover:bg-slate-5\",\n        !props.href && \"cursor-not-allowed\"\n      )}\n      onClick={(e) => {\n        e.preventDefault();\n        props.onClick();\n      }}\n    >\n      <span className=\"flex items-center justify-center\">{props.children}</span>\n      <span>{props.title}</span>\n    </a>\n  </li>\n);\n\nexport default LinkItem;\n"
  },
  {
    "path": "next/src/components/sidebar/links.tsx",
    "content": "import type { IconType } from \"react-icons\";\nimport {\n  FaDiscord,\n  FaFileCode,\n  FaGear,\n  FaGithub,\n  FaHouse,\n  FaLinkedin,\n  FaQuestion,\n  FaXTwitter,\n} from \"react-icons/fa6\";\n\ntype LinkMetadata = {\n  name: string;\n  href: string;\n  icon: IconType;\n  className?: string;\n};\n\nexport const PAGE_LINKS: LinkMetadata[] = [\n  {\n    name: \"Home\",\n    href: \"/\",\n    icon: FaHouse,\n  },\n  {\n    name: \"Help\",\n    href: \"https://reworkd.ai/docs\",\n    icon: FaQuestion,\n    className: \"group-hover:text-red-500\",\n  },\n  {\n    name: \"Templates\",\n    href: \"/templates\",\n    icon: FaFileCode,\n    className: \"transition-transform group-hover:scale-110\",\n  },\n  {\n    name: \"Settings\",\n    href: \"/settings\",\n    icon: FaGear,\n    className: \"transition-transform group-hover:rotate-90\",\n  },\n];\n\nexport const SOCIAL_LINKS: LinkMetadata[] = [\n  {\n    name: \"Github\",\n    href: \"https://github.com/reworkd/AgentGPT\",\n    icon: FaGithub,\n  },\n  {\n    name: \"Twitter\",\n    href: \"https://twitter.com/ReworkdAI\",\n    icon: FaXTwitter,\n  },\n  {\n    name: \"Discord\",\n    href: \"https://discord.gg/gcmNyAAFfV\",\n    icon: FaDiscord,\n  },\n  {\n    name: \"LinkedIn\",\n    href: \"https://www.linkedin.com/company/reworkd/\",\n    icon: FaLinkedin,\n  },\n];\n"
  },
  {
    "path": "next/src/components/templates/TemplateCard.tsx",
    "content": "import clsx from \"clsx\";\nimport { useRouter } from \"next/router\";\n\nimport type { TemplateModel } from \"./TemplateData\";\nimport { useAgentInputStore } from \"../../stores/agentInputStore\";\n\ntype TemplateCardProps = {\n  model: TemplateModel;\n};\n\nconst TemplateCard = ({ model }: TemplateCardProps) => {\n  const router = useRouter();\n  const setNameInput = useAgentInputStore.use.setNameInput();\n  const setGoalInput = useAgentInputStore.use.setGoalInput();\n\n  const handleClick = () => {\n    setNameInput(model.name);\n    setGoalInput(model.promptTemplate);\n    router.push(\"/\").catch(console.log);\n  };\n  return (\n    <div\n      onClick={handleClick}\n      className={clsx(\n        \"h-34 w-full max-w-lg cursor-pointer space-y-2 whitespace-normal rounded-lg border border-white/20 p-4 text-left transition-all duration-100\",\n        \"bg-zinc-900 transition-colors hover:bg-zinc-800\"\n      )}\n    >\n      <div className=\"flex items-center\">\n        <div className=\"mr-2 text-xl text-white\">{model.icon}</div>\n        <div className={`text-md mb-0 font-bold text-white`}>{model.name}</div>\n      </div>\n      <div className={clsx(`mb-2 inline-block rounded-full  text-xs text-gray-400`)}>\n        {model.category}\n      </div>\n      <div className={`text-sm text-gray-200`}>{model.description}</div>\n    </div>\n  );\n};\n\nexport default TemplateCard;\n"
  },
  {
    "path": "next/src/components/templates/TemplateData.tsx",
    "content": "import {\n  FaAppleAlt,\n  FaBlog,\n  FaBook,\n  FaBookOpen,\n  FaBookReader,\n  FaCalendarAlt,\n  FaChartLine,\n  FaDumbbell,\n  FaFileAlt,\n  FaGamepad,\n  FaGraduationCap,\n  FaHashtag,\n  FaLaptopCode,\n  FaMoneyBillWave,\n  FaPalette,\n  FaPlaneDeparture,\n  FaRegEnvelope,\n  FaRegNewspaper,\n  FaShoppingCart,\n  FaStarAndCrescent,\n} from \"react-icons/fa\";\n\nexport const TEMPLATE_DATA: TemplateModel[] = [\n  {\n    name: \"ResearchGPT\",\n    icon: <FaBookReader />,\n    category: \"Academics and Professional\",\n    description: \"Generate a thorough report on a specific subject\",\n    promptTemplate:\n      \"Compile a comprehensive report on Global Warming, touching on its causes, effects, and mitigation strategies. Include recent research findings and statistics.\",\n    placeholder: \"Global Warming\",\n  },\n  {\n    name: \"BrandGPT\",\n    icon: <FaShoppingCart />,\n    category: \"Academics and Professional\",\n    description: \"Evaluate a brand's performance, market position, and future prospects\",\n    promptTemplate:\n      \"Provide an in-depth analysis of the Coca-Cola brand, assessing its current market status, consumer perception, competitive positioning, and future outlook. Include potential strategies for growth.\",\n    placeholder: \"Coca-Cola\",\n  },\n  {\n    name: \"TravelGPT\",\n    icon: <FaPlaneDeparture />,\n    category: \"Other\",\n    description: \"Plan a detailed journey to a selected destination\",\n    promptTemplate:\n      \"Outline a detailed itinerary for a 7-day trip to Paris, including sightseeing recommendations, accommodation options, and local dining experiences.\",\n    placeholder: \"Paris\",\n  },\n  {\n    name: \"PlatformerGPT\",\n    icon: <FaGamepad />,\n    category: \"Creative and Social\",\n    description: \"Code a platformer game featuring a popular character or theme\",\n    promptTemplate:\n      \"Develop a platformer game featuring the adventures of Mario in a mysterious realm.\",\n    placeholder: \"Mario\",\n  },\n  {\n    name: \"IndustryGPT\",\n    icon: <FaBook />,\n    category: \"Academics and Professional\",\n    description:\n      \"Present a comprehensive review of an industry, covering key trends, players, and future predictions\",\n    promptTemplate:\n      \"Conduct an in-depth examination of the ClimateTech industry, detailing its current market status, emerging trends, significant challenges, and opportunities. Make sure to include data and statistics, a list of major players, a forecast for the industry, and how current events or developments could influence it.\",\n    placeholder: \"ClimateTech\",\n  },\n  {\n    name: \"ScraperGPT\",\n    icon: <FaLaptopCode />,\n    category: \"Other\",\n    description: \"Extract and summarize data from a selected website\",\n    promptTemplate:\n      \"Write a program to scrape the IMDb website and summarize the top 10 trending movies, including their ratings, director names, and a brief synopsis.\",\n    placeholder: \"IMDb\",\n  },\n  {\n    name: \"PostGPT\",\n    icon: <FaHashtag />,\n    category: \"Creative and Social\",\n    description: \"Create engaging captions and hashtags for your social media posts\",\n    promptTemplate:\n      \"Create an engaging caption and appropriate hashtags for a social media post celebrating a fun-filled Summer Vacation at the beach.\",\n    placeholder: \"Summer Vacation\",\n  },\n  {\n    name: \"EmailGPT\",\n    icon: <FaRegEnvelope />,\n    category: \"Academics and Professional\",\n    description: \"Compose a concise and detailed email\",\n    promptTemplate:\n      \"Compose a clear and succinct email to update the team about the progress of Project Alpha, discussing completed milestones, forthcoming tasks, and any challenges encountered.\",\n    placeholder: \"Project Alpha\",\n  },\n  {\n    name: \"ResumeGPT\",\n    icon: <FaFileAlt />,\n    category: \"Academics and Professional\",\n    description: \"Design a professional resume based on your career history and skills\",\n    promptTemplate:\n      \"Develop a resume highlighting your skills and experiences in the Marketing field, paying particular attention to relevant projects, achievements, and any unique capabilities.\",\n    placeholder: \"Marketing\",\n  },\n  {\n    name: \"NovelGPT\",\n    icon: <FaBookOpen />,\n    category: \"Creative and Social\",\n    description: \"Begin writing a novel in a selected genre\",\n    promptTemplate:\n      \"Begin writing a Fantasy novel set in a magical realm teeming with enchanting creatures, ancient prophecies, and epic quests.\",\n    placeholder: \"Fantasy\",\n  },\n  {\n    name: \"DietGPT\",\n    icon: <FaAppleAlt />,\n    category: \"Health and Fitness\",\n    description: \"Create a customized diet plan based on dietary preferences and goals\",\n    promptTemplate:\n      \"Create a Vegetarian diet plan for a week aimed at promoting weight loss and overall health. Include a shopping list, meal suggestions, and simple recipes.\",\n    placeholder: \"Vegetarian\",\n  },\n  {\n    name: \"FitnessGPT\",\n    icon: <FaDumbbell />,\n    category: \"Health and Fitness\",\n    description: \"Design a workout regimen tailored to your fitness goals\",\n    promptTemplate:\n      \"Develop a 4-week workout regimen for Weight Loss that includes a balanced mix of cardio, strength training, and flexibility exercises. Include rest days and provide safety precautions.\",\n    placeholder: \"Weight Loss\",\n  },\n  {\n    name: \"MarketingGPT\",\n    icon: <FaChartLine />,\n    category: \"Academics and Professional\",\n    description: \"Design a comprehensive marketing strategy for your business\",\n    promptTemplate:\n      \"Develop a 6-month marketing plan for a Tech Startup. Include marketing objectives, target audience analysis, promotional strategies, budget allocation, timelines, and performance indicators.\",\n    placeholder: \"Tech Startup\",\n  },\n  {\n    name: \"BudgetGPT\",\n    icon: <FaMoneyBillWave />,\n    category: \"Academics and Professional\",\n    description: \"Prepare a personal or family budget\",\n    promptTemplate:\n      \"Create a detailed budget for a Family Vacation to Europe, including expenses for flights, accommodation, meals, sightseeing, shopping, and any contingencies.\",\n    placeholder: \"Family Vacation\",\n  },\n  {\n    name: \"StudyGPT\",\n    icon: <FaGraduationCap />,\n    category: \"Academics and Professional\",\n    description: \"Design a study schedule to achieve your academic objectives\",\n    promptTemplate:\n      \"Draft a study schedule for Final Exams, including study times, subjects to be covered each day, revision days, and breaks for rest and relaxation.\",\n    placeholder: \"Final Exams\",\n  },\n  {\n    name: \"NewsGPT\",\n    icon: <FaRegNewspaper />,\n    category: \"Other\",\n    description: \"Author a detailed news article on a selected topic\",\n    promptTemplate:\n      \"Write a detailed news article discussing recent Technology Advancements, including their implications for society and the economy.\",\n    placeholder: \"Technology Advancements\",\n  },\n  {\n    name: \"EventPlannerGPT\",\n    icon: <FaCalendarAlt />,\n    category: \"Other\",\n    description: \"Organize a detailed schedule for your forthcoming event\",\n    promptTemplate:\n      \"Plan a detailed schedule for a Music Festival, including artist line-ups, set times, venue arrangements, and contingency plans.\",\n    placeholder: \"Music Festival\",\n  },\n  {\n    name: \"BlogGPT\",\n    icon: <FaBlog />,\n    category: \"Creative and Social\",\n    description: \"Write a blog post on a selected topic\",\n    promptTemplate:\n      \"Write an engaging blog post about Healthy Living, discussing nutrition, exercise, mental health, and practical tips for maintaining a healthy lifestyle.\",\n    placeholder: \"Healthy Living\",\n  },\n  {\n    name: \"AstroGPT\",\n    icon: <FaStarAndCrescent />,\n    category: \"Science and Technology\",\n    description: \"Discuss astronomical phenomena, discoveries, and related technology\",\n    promptTemplate:\n      \"Delve into the latest discoveries about Black Holes. Cover their characteristics, theoretical underpinnings, related astronomical observations, and potential technological advancements driven by the research.\",\n    placeholder: \"Black Holes\",\n  },\n  {\n    name: \"ArtReviewGPT\",\n    icon: <FaPalette />,\n    category: \"Creative and Social\",\n    description: \"Critique a piece of art, discussing its style, context, and influence\",\n    promptTemplate:\n      \"Provide a thoughtful critique of Vincent van Gogh's 'Starry Night'. Discuss its artistic style, historical context, symbolism, and influence on later art movements.\",\n    placeholder: \"Starry Night\",\n  },\n];\n\nexport interface TemplateModel {\n  name: string;\n  icon: JSX.Element;\n  category: string;\n  description: string;\n  promptTemplate: string;\n  placeholder: string;\n}\n"
  },
  {
    "path": "next/src/components/templates/TemplateSearch.tsx",
    "content": "import type { ChangeEvent, FC } from \"react\";\nimport React from \"react\";\n\ninterface SearchBarProps {\n  setSearchQuery: (query: string) => void;\n  setCategory: (category: string) => void;\n}\n\nconst SearchBar: FC<SearchBarProps> = ({ setSearchQuery, setCategory }) => {\n  const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => {\n    setSearchQuery(e.target.value);\n  };\n\n  const handleCategoryChange = (e: ChangeEvent<HTMLSelectElement>) => {\n    setCategory(e.target.value);\n  };\n\n  return (\n    <div className=\"flex flex-row items-center gap-2 py-2\">\n      <div className=\"flex w-full flex-grow space-x-2\">\n        <input\n          type=\"search\"\n          className=\"flex-grow rounded-md border border-white/20 bg-zinc-900 py-1 text-white placeholder-white shadow-sm focus:border-white focus:outline-none focus:ring-white\"\n          placeholder=\"Search\"\n          aria-label=\"Search\"\n          aria-describedby=\"button-addon2\"\n          onChange={handleSearchChange}\n        />\n        \n      </div>\n      <div className=\"w-full sm:w-auto\">\n        <select\n          id=\"category\"\n          name=\"category\"\n          className=\"block w-full rounded-md border border-white/20 bg-zinc-900 px-2 py-1 text-white shadow-sm focus:border-white focus:outline-none focus:ring-white sm:text-sm\"\n          onChange={handleCategoryChange}\n        >\n          <option value=\"\">All</option>\n          <option>Health and Fitness</option>\n          <option>Creative and social</option>\n          <option>Academics and Professional</option>\n          <option>Other</option>\n        </select>\n      </div>\n    </div>\n  );\n};\n\nexport default SearchBar;\n"
  },
  {
    "path": "next/src/components/toast.tsx",
    "content": "import * as ToastPrimitive from \"@radix-ui/react-toast\";\nimport clsx from \"clsx\";\nimport { useTranslation } from \"next-i18next\";\nimport type { Dispatch, SetStateAction } from \"react\";\nimport React from \"react\";\n\ntype Props = {\n  model: [boolean, Dispatch<SetStateAction<boolean>>];\n  onAction?: () => void;\n  title: string;\n  description?: string;\n  className?: string;\n};\n\nconst Toast = (props: Props) => {\n  const [t] = useTranslation();\n  const [open, setOpen] = props.model;\n\n  return (\n    <ToastPrimitive.Provider swipeDirection={\"right\"}>\n      <ToastPrimitive.Root\n        open={open}\n        onOpenChange={setOpen}\n        className={clsx(\n          \"fixed inset-x-4 bottom-4 z-50 w-auto rounded-2xl shadow-lg md:left-auto md:right-4 md:w-full md:max-w-sm\",\n          \"radix-state-open:animate-toast-slide-in-bottom md:radix-state-open:animate-toast-slide-in-right\",\n          \"radix-state-closed:animate-toast-hide\",\n          \"radix-swipe-direction-right:radix-swipe-end:animate-toast-swipe-out-x\",\n          \"radix-swipe-direction-right:translate-x-radix-toast-swipe-move-x\",\n          \"radix-swipe-direction-down:radix-swipe-end:animate-toast-swipe-out-y\",\n          \"radix-swipe-direction-down:translate-y-radix-toast-swipe-move-y\",\n          \"radix-swipe-cancel:translate-x-0 radix-swipe-cancel:duration-200 radix-swipe-cancel:ease-[ease]\",\n          \"focus:outline-none focus-visible:ring focus-visible:ring-purple-500 focus-visible:ring-opacity-75\",\n          props.className\n        )}\n      >\n        <div className=\"flex\">\n          <div className=\"flex w-0 flex-1 items-center py-4 pl-5\">\n            <div className=\"radix w-full\">\n              <ToastPrimitive.Title className=\"font-mono text-lg font-medium text-white\">\n                {props.title}\n              </ToastPrimitive.Title>\n              {props.description && (\n                <ToastPrimitive.Description className=\"text-gray-10 text-md mt-1 rounded-md bg-slate-800/50 p-1\">\n                  <pre className=\"overflow-hidden text-ellipsis\">{props.description}</pre>\n                </ToastPrimitive.Description>\n              )}\n            </div>\n          </div>\n          <div className=\"mx-4 flex items-center justify-center py-4\">\n            <div className=\"flex flex-col \">\n              {props.onAction && (\n                <ToastPrimitive.Action\n                  altText=\"copy\"\n                  className=\"text-md flex w-full items-center justify-center rounded-2xl border border-transparent px-3 py-2 font-medium text-yellow-500 hover:bg-white/20 \"\n                  onClick={(e) => {\n                    e.preventDefault();\n                    if (props.onAction) props.onAction();\n                    setOpen(false);\n                  }}\n                >\n                  {t(\"COPY\", { ns: \"common\" })}\n                </ToastPrimitive.Action>\n              )}\n              <ToastPrimitive.Close className=\"text-md flex w-full items-center justify-center rounded-2xl border border-transparent px-3 py-2 font-medium text-white hover:bg-white/20 \">\n                {t(\"CLOSE\", { ns: \"common\" })}\n              </ToastPrimitive.Close>\n            </div>\n          </div>\n        </div>\n      </ToastPrimitive.Root>\n\n      <ToastPrimitive.Viewport />\n    </ToastPrimitive.Provider>\n  );\n};\n\nexport default Toast;\n"
  },
  {
    "path": "next/src/components/utils/helpers.tsx",
    "content": "import {\n  FaCheckCircle,\n  FaCircleNotch,\n  FaExclamationTriangle,\n  FaStar,\n  FaStopCircle,\n  FaThumbtack,\n} from \"react-icons/fa\";\n\nimport type { Message } from \"../../types/message\";\nimport { MESSAGE_TYPE_ERROR, MESSAGE_TYPE_GOAL } from \"../../types/message\";\nimport {\n  getTaskStatus,\n  isTask,\n  TASK_STATUS_COMPLETED,\n  TASK_STATUS_EXECUTING,\n  TASK_STATUS_FINAL,\n  TASK_STATUS_STARTED,\n} from \"../../types/task\";\n\nexport const getMessageContainerStyle = (message: Message) => {\n  if (!isTask(message)) {\n    switch (message.type) {\n      case \"error\":\n        return \"border-yellow-400 hover:border-yellow-300 transition-colors\";\n      default:\n        return \"border-white/10 hover:border-white/40\";\n    }\n  }\n\n  switch (message.status) {\n    case TASK_STATUS_STARTED:\n      return \"border-white/20 hover:border-white/40\";\n    case TASK_STATUS_EXECUTING:\n      return \"border-white/20 hover:border-white/40\";\n    case TASK_STATUS_COMPLETED:\n    case TASK_STATUS_FINAL:\n      return \"border-green-500 hover:border-green-400\";\n    default:\n      return \"\";\n  }\n};\n\nexport const getTaskStatusIcon = (\n  message: Message,\n  config: { [key: string]: string | boolean | undefined }\n) => {\n  const taskStatusIconClass = \"mr-1 mb-1 inline-block\";\n  const { isAgentStopped } = config;\n\n  switch (message.type) {\n    case MESSAGE_TYPE_GOAL:\n      return <FaStar className=\"text-yellow-300\" />;\n    case MESSAGE_TYPE_ERROR:\n      return <FaExclamationTriangle className=\"text-yellow-400\" />;\n  }\n\n  if (getTaskStatus(message) === TASK_STATUS_STARTED) {\n    return <FaThumbtack className={`${taskStatusIconClass} -rotate-45`} />;\n  } else if (getTaskStatus(message) === TASK_STATUS_EXECUTING) {\n    return isAgentStopped ? (\n      <FaStopCircle className={`${taskStatusIconClass}`} />\n    ) : (\n      <FaCircleNotch className={`${taskStatusIconClass} animate-spin`} />\n    );\n  } else if (\n    getTaskStatus(message) === TASK_STATUS_COMPLETED ||\n    getTaskStatus(message) === TASK_STATUS_FINAL\n  ) {\n    return (\n      <FaCheckCircle className={`${taskStatusIconClass} text-green-500 hover:text-green-400`} />\n    );\n  }\n};\n"
  },
  {
    "path": "next/src/env/client.mjs",
    "content": "// @ts-check\nimport { clientEnv, clientSchema } from \"./schema.mjs\";\n\nconst _clientEnv = clientSchema.safeParse(clientEnv);\n\nexport const formatErrors = (\n  /** @type {import('zod').ZodFormattedError<Map<string,string>,string>} */\n  errors,\n) =>\n  Object.entries(errors)\n    .map(([name, value]) => {\n      if (value && \"_errors\" in value)\n        return `${name}: ${value._errors.join(\", \")}\\n`;\n    })\n    .filter(Boolean);\n\nif (!_clientEnv.success) {\n  console.error(\n    \"❌ Invalid environment variables:\\n\",\n    ...formatErrors(_clientEnv.error.format()),\n  );\n  throw new Error(\"Invalid environment variables\");\n}\n\nfor (let key of Object.keys(_clientEnv.data)) {\n  if (!key.startsWith(\"NEXT_PUBLIC_\")) {\n    console.warn(\n      `❌ Invalid public environment variable name: ${key}. It must begin with 'NEXT_PUBLIC_'`,\n    );\n\n    throw new Error(\"Invalid public environment variable name\");\n  }\n}\n\nexport const env = _clientEnv.data;\n"
  },
  {
    "path": "next/src/env/schema.mjs",
    "content": "// @ts-check\nimport {z} from \"zod\";\n\nconst requiredForProduction = () =>\n    process.env.NODE_ENV === \"production\"\n        ? z.string().min(1).trim()\n        : z.string().min(1).trim().optional();\n\nfunction stringToBoolean() {\n    return z.preprocess((str) => str === \"true\", z.boolean());\n}\n\n/**\n * Specify your server-side environment variables schema here.\n * This way you can ensure the app isn't built with invalid env vars.\n */\nexport const serverSchema = z.object({\n    DATABASE_URL: z.string().url(),\n    NODE_ENV: z.enum([\"development\", \"test\", \"production\"]),\n    NEXTAUTH_SECRET: requiredForProduction(),\n    NEXTAUTH_URL: z.preprocess(\n        // This makes Vercel deployments not fail if you don't set NEXTAUTH_URL\n        // Since NextAuth.js automatically uses the VERCEL_URL if present.\n        (str) => process.env.VERCEL_URL ?? str,\n        // VERCEL_URL doesn't include `https` so it cant be validated as a URL\n        process.env.VERCEL ? z.string() : z.string().url()\n    ),\n    OPENAI_API_KEY: z.string().min(1).trim().optional(),\n\n    GOOGLE_CLIENT_ID: z.string().min(1).trim().optional(),\n    GOOGLE_CLIENT_SECRET: z.string().min(1).trim().optional(),\n    GITHUB_CLIENT_ID: z.string().min(1).trim().optional(),\n    GITHUB_CLIENT_SECRET: z.string().min(1).trim().optional(),\n    DISCORD_CLIENT_ID: z.string().min(1).trim().optional(),\n    DISCORD_CLIENT_SECRET: z.string().min(1).trim().optional(),\n});\n\n/**\n * You can't destruct `process.env` as a regular object in the Next.js\n * middleware, so you have to do it manually here.\n * @type {{ [k in keyof z.input<typeof serverSchema>]: string | undefined }}\n */\nexport const serverEnv = {\n    DATABASE_URL: process.env.DATABASE_URL,\n    NODE_ENV: process.env.NODE_ENV,\n    NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,\n    NEXTAUTH_URL: process.env.NEXTAUTH_URL,\n    OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n\n    GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,\n    GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,\n    GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID,\n    GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,\n    DISCORD_CLIENT_ID: process.env.DISCORD_CLIENT_ID,\n    DISCORD_CLIENT_SECRET: process.env.DISCORD_CLIENT_SECRET,\n};\n\n/**\n * Specify your client-side environment variables schema here.\n * This way you can ensure the app isn't built with invalid env vars.\n * To expose them to the client, prefix them with `NEXT_PUBLIC_`.\n */\nexport const clientSchema = z.object({\n    NEXT_PUBLIC_EXPERIMENTAL_FF_ENABLED: stringToBoolean().default(false),\n    NEXT_PUBLIC_CDN: z.string().default(\"\"),\n    NEXT_PUBLIC_VERCEL_ENV: z.enum([\"production\", \"preview\", \"development\", \"test\"]).default(\"development\"),\n    NEXT_PUBLIC_FF_MOCK_MODE_ENABLED: stringToBoolean().default(false),\n    NEXT_PUBLIC_FF_SID_ENABLED: stringToBoolean().default(false),\n    NEXT_PUBLIC_VERCEL_URL: z.string().default(\"http://localhost:3000\"),\n    NEXT_PUBLIC_BACKEND_URL: z.string().url().default(\"http://localhost:8000\"),\n    NEXT_PUBLIC_MAX_LOOPS: z.coerce.number().default(25),\n    NEXT_PUBLIC_PUSHER_APP_KEY: z.string().optional(),\n});\n\n/**\n * You can't destruct `process.env` as a regular object, so you have to do\n * it manually here. This is because Next.js evaluates this at build time,\n * and only used environment variables are included in the build.\n * @type {{ [k in keyof z.input<typeof clientSchema>]: string | undefined }}\n */\nexport const clientEnv = {\n    NEXT_PUBLIC_CDN: process.env.NEXT_PUBLIC_CDN,\n    NEXT_PUBLIC_EXPERIMENTAL_FF_ENABLED: process.env.NEXT_PUBLIC_EXPERIMENTAL_FF_ENABLED,\n    NEXT_PUBLIC_VERCEL_ENV: process.env.NEXT_PUBLIC_VERCEL_ENV,\n    NEXT_PUBLIC_VERCEL_URL: process.env.NEXT_PUBLIC_VERCEL_URL,\n    NEXT_PUBLIC_BACKEND_URL: process.env.NEXT_PUBLIC_BACKEND_URL,\n    NEXT_PUBLIC_FF_MOCK_MODE_ENABLED: process.env.NEXT_PUBLIC_FF_MOCK_MODE_ENABLED,\n    NEXT_PUBLIC_FF_SID_ENABLED: process.env.NEXT_PUBLIC_FF_SID_ENABLED,\n    NEXT_PUBLIC_MAX_LOOPS: process.env.NEXT_PUBLIC_MAX_LOOPS,\n    NEXT_PUBLIC_PUSHER_APP_KEY: process.env.NEXT_PUBLIC_PUSHER_APP_KEY,\n};\n"
  },
  {
    "path": "next/src/env/server.mjs",
    "content": "// @ts-check\n/**\n * This file is included in `/next.config.mjs` which ensures the app isn't built with invalid env vars.\n * It has to be a `.mjs`-file to be imported there.\n */\nimport { env as clientEnv, formatErrors } from \"./client.mjs\";\nimport { serverSchema, serverEnv } from \"./schema.mjs\";\n\nconst _serverEnv = serverSchema.safeParse(serverEnv);\n\nif (!_serverEnv.success) {\n  console.error(\n    \"❌ Invalid environment variables:\\n\",\n    ...formatErrors(_serverEnv.error.format()),\n  );\n  throw new Error(\"Invalid environment variables\");\n}\n\nfor (let key of Object.keys(_serverEnv.data)) {\n  if (key.startsWith(\"NEXT_PUBLIC_\")) {\n    console.warn(\"❌ You are exposing a server-side env-variable:\", key);\n\n    throw new Error(\"You are exposing a server-side env-variable\");\n  }\n}\n\nexport const env = { ..._serverEnv.data, ...clientEnv };\n"
  },
  {
    "path": "next/src/hooks/useAgent.ts",
    "content": "import type { Agent as PrismaAgent } from \"@prisma/client\";\n\nimport { useAuth } from \"./useAuth\";\nimport type { CreateAgentProps, SaveAgentProps } from \"../server/api/routers/agentRouter\";\nimport { api } from \"../utils/api\";\n\n\nexport type AgentUtils = {\n  createAgent: (data: CreateAgentProps) => Promise<PrismaAgent | undefined>;\n  saveAgent: (data: SaveAgentProps) => void;\n};\n\nexport function useAgent(): AgentUtils {\n  const { status } = useAuth();\n  const utils = api.useContext();\n\n  const createMutation = api.agent.create.useMutation({\n    onSuccess: (data: PrismaAgent) => {\n      utils.agent.getAll.setData(void 0, (oldData) => [data, ...(oldData ?? [])]);\n      return data;\n    },\n  });\n  const createAgent = async (data: CreateAgentProps): Promise<PrismaAgent | undefined> => {\n    if (status === \"authenticated\") {\n      return await createMutation.mutateAsync(data);\n    } else {\n      return undefined;\n    }\n  };\n\n  const saveMutation = api.agent.save.useMutation();\n  const saveAgent = (data: SaveAgentProps) => {\n    if (status === \"authenticated\") saveMutation.mutate(data);\n  };\n\n  return {\n    createAgent,\n    saveAgent,\n  };\n}\n"
  },
  {
    "path": "next/src/hooks/useAuth.ts",
    "content": "import { useRouter } from \"next/router\";\nimport type { Session } from \"next-auth\";\nimport { signIn, signOut, useSession } from \"next-auth/react\";\nimport { useEffect } from \"react\";\n\ntype Provider = \"google\" | \"github\" | \"discord\";\n\ninterface Auth {\n  signIn: (provider?: Provider) => Promise<void>;\n  signOut: () => Promise<void>;\n  status: \"authenticated\" | \"unauthenticated\" | \"loading\";\n  session: Session | null;\n}\n\ninterface UseAuthOptions {\n  protectedRoute?: boolean;\n  isAllowed?: (user: Session) => boolean;\n}\n\nexport function useAuth(\n  { protectedRoute, isAllowed }: UseAuthOptions = { protectedRoute: false, isAllowed: () => true }\n): Auth {\n  const { data: session, status } = useSession();\n  const { push } = useRouter();\n\n  useEffect(() => {\n    if (protectedRoute && status === \"unauthenticated\") {\n      handleSignIn().catch(console.error);\n    }\n\n    if (protectedRoute && status === \"authenticated\" && isAllowed && !isAllowed(session)) {\n      void push(\"/404\").catch(console.error);\n    }\n  }, [protectedRoute, isAllowed, status, session, push]);\n\n  const handleSignIn = async () => {\n    await signIn();\n  };\n\n  const handleSignOut = async () => {\n    await signOut({\n      callbackUrl: \"/\",\n    }).catch();\n  };\n\n  return {\n    signIn: handleSignIn,\n    signOut: handleSignOut,\n    status,\n    session,\n  };\n}\n"
  },
  {
    "path": "next/src/hooks/useModels.ts",
    "content": "import { useQuery } from \"@tanstack/react-query\";\nimport { useSession } from \"next-auth/react\";\nimport { z } from \"zod\";\n\nimport { get } from \"../services/fetch-utils\";\n\nconst Model = z.object({\n  name: z.string(),\n  max_tokens: z.number(),\n  has_access: z.boolean(),\n});\n\nconst ModelList = z.array(Model);\n\nexport type LLMModel = z.infer<typeof Model>;\n\nexport function useModels() {\n  const { data: session } = useSession();\n  const query = useQuery(\n    [\"llm\"],\n    async () => await get(\"/api/models\", ModelList, session?.accessToken),\n    {\n      enabled: !!session?.accessToken,\n    }\n  );\n\n  return {\n    models: query.data ?? [],\n    getModel: (name: string) => query.data?.find((m) => m.name === name),\n  };\n}\n"
  },
  {
    "path": "next/src/hooks/useMouseMovement.ts",
    "content": "import { useMotionValue } from \"framer-motion\";\nimport type { MouseEvent } from \"react\";\n\nexport function useMouseMovement() {\n  const mouseX = useMotionValue(0);\n  const mouseY = useMotionValue(0);\n\n  function onMouseMove(event: MouseEvent) {\n    const { clientX, clientY } = event;\n    const { left, top } = event.currentTarget.getBoundingClientRect();\n    mouseX.set(clientX - left);\n    mouseY.set(clientY - top);\n  }\n\n  return {\n    mouseX,\n    mouseY,\n    onMouseMove,\n  };\n}\n"
  },
  {
    "path": "next/src/hooks/useSID.ts",
    "content": "import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { Session } from \"next-auth\";\n\nimport OauthApi from \"../services/workflow/oauthApi\";\n\nconst QUERY_KEY = [\"sid\"];\n\nexport function useSID(session: Session | null) {\n  const api = OauthApi.fromSession(session);\n  const queryClient = useQueryClient();\n\n  const { data, refetch } = useQuery(QUERY_KEY, async () => await api.get_info_sid(), {\n    enabled: !!session,\n    retry: false,\n  });\n\n  const { mutateAsync: install } = useMutation(async () => {\n    if (!session) return;\n\n    window.location.href = await api.install(\"sid\");\n  });\n\n  const { mutateAsync: uninstall } = useMutation(async () => {\n    if (!session) return;\n\n    await api.uninstall(\"sid\");\n    queryClient.setQueriesData(QUERY_KEY, { connected: false });\n  });\n\n  return {\n    connected: data?.connected ?? false,\n    refetch,\n    install: async () => install(),\n    uninstall: async () => uninstall(),\n    manage: () => void window.open(\"https://me.sid.ai/\", \"_blank\"),\n  };\n}\n"
  },
  {
    "path": "next/src/hooks/useSettings.ts",
    "content": "import { useRouter } from \"next/router\";\nimport { useTranslation } from \"next-i18next\";\nimport { useEffect, useState } from \"react\";\n\nimport { useModelSettingsStore } from \"../stores\";\nimport type { ModelSettings } from \"../types\";\nimport { getDefaultModelSettings } from \"../utils/constants\";\nimport type { Language } from \"../utils/languages\";\nimport { findLanguage } from \"../utils/languages\";\n\n\nexport type SettingsModel = {\n  settings: ModelSettings;\n  updateSettings: <Key extends keyof ModelSettings>(key: Key, value: ModelSettings[Key]) => void;\n  updateLangauge: (language: Language) => Promise<void>;\n};\n\nexport function useSettings(): SettingsModel {\n  const [_modelSettings, set_ModelSettings] = useState<ModelSettings>(getDefaultModelSettings());\n  const modelSettings = useModelSettingsStore.use.modelSettings();\n  const updateSettings = useModelSettingsStore.use.updateSettings();\n  const router = useRouter();\n  const { i18n } = useTranslation();\n\n  // The server doesn't have access to local storage so rendering Zustand directly  will lead to a hydration error\n  useEffect(() => {\n    set_ModelSettings(modelSettings);\n  }, [modelSettings]);\n\n  // We must handle language setting changes uniquely as the router must be the source of truth for the language\n  useEffect(() => {\n    if (router.locale !== modelSettings.language.code) {\n      updateSettings(\"language\", findLanguage(router.locale || \"en\"));\n    }\n  }, [router, modelSettings.language, updateSettings]);\n\n  const updateLangauge = async (language: Language): Promise<void> => {\n    await i18n.changeLanguage(language.code);\n    const { pathname, asPath, query } = router;\n    await router.push({ pathname, query }, asPath, {\n      locale: language.code,\n    });\n  };\n\n  return {\n    settings: _modelSettings,\n    updateSettings: updateSettings,\n    updateLangauge: updateLangauge,\n  };\n}\n"
  },
  {
    "path": "next/src/hooks/useTools.ts",
    "content": "import { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { z } from \"zod\";\n\nimport { get } from \"../services/fetch-utils\";\nimport { useAgentStore } from \"../stores\";\n\nconst Tool = z.object({\n  name: z.string(),\n  description: z.string(),\n  color: z.string(),\n  image_url: z.string().optional(),\n});\n\nconst ToolsResponseSchema = z.object({\n  tools: z.array(Tool),\n});\n\nconst ActiveToolSchema = Tool.extend({\n  active: z.boolean(),\n});\n\nexport type ActiveTool = z.infer<typeof ActiveToolSchema>;\n\nconst loadTools = async (key: string) => {\n  const allTools = await get(\"/api/agent/tools\", ToolsResponseSchema);\n\n  const data = localStorage.getItem(key);\n  let activeTools: ActiveTool[] = [];\n\n  try {\n    const obj = z.array(ActiveToolSchema).parse(JSON.parse(data ?? \"\"));\n    activeTools = allTools.tools.map((db_tool) => {\n      const tool = obj.find((t) => t.name === db_tool.name);\n      return tool ?? { ...db_tool, active: false };\n    });\n  } catch (error) {\n    activeTools = allTools.tools.map((toolModel) => ({ ...toolModel, active: false }));\n  }\n\n  return activeTools;\n};\n\nconst save = (key: string, data: object) => {\n  localStorage.setItem(key, JSON.stringify(data));\n};\n\nexport function useTools() {\n  const setTools = useAgentStore.use.setTools();\n\n  const queryClient = useQueryClient();\n  const query = useQuery([\"tools\"], () => loadTools(\"tools\"), {\n    onSuccess: (data) => {\n      updateActiveTools(data);\n    },\n  });\n\n  function updateActiveTools(data: ActiveTool[]) {\n    save(\"tools\", data);\n    setTools(data.filter((tool) => tool.active));\n  }\n\n  const setToolActive = (toolName: string, active: boolean) => {\n    queryClient.setQueriesData([\"tools\"], (old) => {\n      const data = (old as ActiveTool[]).map((tool) =>\n        tool.name === toolName ? { ...tool, active } : tool\n      );\n\n      updateActiveTools(data);\n      return data;\n    });\n  };\n\n  return {\n    activeTools: query.data ?? [],\n    setToolActive,\n    isSuccess: query.isSuccess,\n  };\n}\n"
  },
  {
    "path": "next/src/layout/dashboard.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport { useState } from \"react\";\n\nimport AppHead from \"../components/AppHead\";\nimport LeftSidebar from \"../components/drawer/LeftSidebar\";\nimport { SidebarControlButton } from \"../components/drawer/Sidebar\";\nimport { useConfigStore } from \"../stores/configStore\";\n\ntype SidebarSettings = {\n  mobile: boolean;\n  desktop: boolean;\n};\n\ntype DashboardLayoutProps = {\n  children: ReactNode;\n  rightSidebar?: ReactNode;\n  onReload?: () => void;\n};\n\nconst defaultState: SidebarSettings = {\n  mobile: false,\n  desktop: true,\n};\n\nconst setMobile =\n  (settings: SidebarSettings, setSettings: (SidebarSettings) => void) => (open: boolean) =>\n    setSettings({\n      mobile: open,\n      desktop: settings.desktop,\n    });\n\nconst setDesktop =\n  (settings: SidebarSettings, setSettings: (SidebarSettings) => void) => (open: boolean) =>\n    setSettings({\n      mobile: settings.mobile,\n      desktop: open,\n    });\n\nconst DashboardLayout = (props: DashboardLayoutProps) => {\n  const [leftSettings, setLeftSettings] = useState(defaultState);\n  const { layout, setLayout } = useConfigStore();\n\n  return (\n    <>\n      <AppHead />\n      {/* Left sidebar */}\n      {/* Mobile */}\n      <LeftSidebar\n        show={leftSettings.mobile}\n        setShow={setMobile(leftSettings, setLeftSettings)}\n        onReload={props.onReload}\n      />\n      <div className={leftSettings.mobile ? \"hidden\" : \"lg:hidden\"}>\n        <SidebarControlButton\n          side=\"left\"\n          show={leftSettings.mobile}\n          setShow={setMobile(leftSettings, setLeftSettings)}\n        />\n      </div>\n      {/* Desktop */}\n      <div className=\"hidden lg:visible lg:inset-y-0  lg:flex lg:w-64 lg:flex-col\">\n        <LeftSidebar\n          show={leftSettings.desktop}\n          setShow={setDesktop(leftSettings, setLeftSettings)}\n          onReload={props.onReload}\n        />\n      </div>\n      <div className={leftSettings.desktop ? \"hidden\" : \"hidden lg:block\"}>\n        <SidebarControlButton\n          side=\"left\"\n          show={leftSettings.desktop}\n          setShow={setDesktop(leftSettings, setLeftSettings)}\n        />\n      </div>\n      {/* Right sidebar */}\n      {/* Mobile */}\n      {props.rightSidebar && (\n        <>\n          <div className=\"lg:inset-y-0 lg:flex lg:w-64 lg:flex-col\">{props.rightSidebar}</div>\n          <SidebarControlButton\n            side=\"right\"\n            show={layout.showRightSidebar}\n            setShow={(show) => setLayout({ showRightSidebar: show })}\n          />\n        </>\n      )}\n      <main\n        className={clsx(\n          \"bg-gradient-to-b from-slate-7 to-slate-3\",\n          leftSettings.desktop && \"lg:pl-64\",\n          props.rightSidebar && layout.showRightSidebar && \"lg:pr-64\"\n        )}\n      >\n        <div className=\"min-w-screen min-h-screen\">{props.children}</div>\n      </main>\n    </>\n  );\n};\n\nexport default DashboardLayout;\n"
  },
  {
    "path": "next/src/layout/default.tsx",
    "content": "import clsx from \"clsx\";\nimport Head from \"next/head\";\nimport { type ReactNode } from \"react\";\n\ninterface LayoutProps {\n  children: ReactNode;\n  className?: string;\n  centered?: boolean;\n}\n\nconst DefaultLayout = (props: LayoutProps) => {\n  const description = \"Assemble, configure, and deploy autonomous AI Agents in your browser.\";\n\n  return (\n    <div\n      className={clsx(\n        \"flex flex-col bg-gradient-to-b from-[#2B2B2B] to-[#1F1F1F]\",\n        props.centered && \"items-center justify-center\"\n      )}\n    >\n      <Head>\n        <title>AgentGPT</title>\n        <meta name=\"description\" content={description} />\n        <meta name=\"twitter:site\" content=\"@AgentGPT\" />\n        <meta name=\"twitter:card\" content=\"summary_large_image\" />\n        <meta name=\"twitter:title\" content=\"AgentGPT 🤖\" />\n        <meta name=\"twitter:description\" content={description} />\n        <meta name=\"twitter:image\" content=\"https://agentgpt.reworkd.ai/banner.png\" />\n        <meta name=\"twitter:image:width\" content=\"1280\" />\n        <meta name=\"twitter:image:height\" content=\"640\" />\n        <meta property=\"og:title\" content=\"AgentGPT: Autonomous AI in your browser 🤖\" />\n        <meta property=\"og:description\" content={description} />\n        <meta property=\"og:url\" content=\"https://agentgpt.reworkd.ai/\" />\n        <meta property=\"og:image\" content=\"https://agentgpt.reworkd.ai/banner.png\" />\n        <meta property=\"og:image:width\" content=\"1280\" />\n        <meta property=\"og:image:height\" content=\"640\" />\n        <meta property=\"og:type\" content=\"website\" />\n        <meta\n          name=\"google-site-verification\"\n          content=\"sG4QDkC8g2oxKSopgJdIe2hQ_SaJDaEaBjwCXZNkNWA\"\n        />\n        <link rel=\"icon\" href=\"/favicon.ico\" />\n      </Head>\n      <div className={clsx(\"min-w-screen min-h-screen\", props.className)}>{props.children}</div>\n    </div>\n  );\n};\n\nexport default DefaultLayout;\n"
  },
  {
    "path": "next/src/layout/grid.tsx",
    "content": "import type { PropsWithChildren } from \"react\";\n\nimport AppHead from \"../components/AppHead\";\n\ninterface Props extends PropsWithChildren {\n  title: string;\n}\n\nexport default function GridLayout(props: Props) {\n  return (\n    <div\n      className=\"bg-slate-1\"\n      style={{\n        backgroundSize: \"80px 80px\",\n        backgroundImage:\n          \"linear-gradient(to right, #F1F3F5 2px, transparent 2px), linear-gradient(to bottom, #F1F3F5 1px, transparent 1px)\",\n      }}\n    >\n      <AppHead title={props.title} />\n      {props.children}\n    </div>\n  );\n}\n"
  },
  {
    "path": "next/src/lib/posts.ts",
    "content": "import fs from \"fs\";\nimport path from \"path\";\n\nimport matter from \"gray-matter\";\n\n// Define the types for the data\nexport interface SlugData {\n  id: string;\n  date: string;\n\n  [key: string]: string;\n}\n\nconst postsDirectory = path.join(process.cwd(), \"posts\");\n\nexport function getSortedPostsData(): SlugData[] {\n  const fileNames = fs.readdirSync(postsDirectory);\n  const allPostsData: SlugData[] = fileNames.map((fileName) => {\n    const id = fileName.replace(/\\.mdx$/, \"\");\n    const fullPath = path.join(postsDirectory, fileName);\n    const fileContents = fs.readFileSync(fullPath, \"utf8\");\n    const matterResult = matter(fileContents);\n\n    return {\n      id,\n      date: matterResult.data.date as string,\n      ...matterResult.data,\n    };\n  });\n\n  return allPostsData.sort((a, b) => {\n    if (a.date < b.date) {\n      return 1;\n    } else {\n      return -1;\n    }\n  });\n}\n\nexport interface PostData {\n  slug: string;\n  content: string;\n\n  [key: string]: string;\n}\n\nexport function getPostData(slug: string): PostData {\n  const fullPath = path.join(postsDirectory, `${slug}.mdx`);\n  const fileContents = fs.readFileSync(fullPath, \"utf8\");\n  const matterResult = matter(fileContents);\n\n  return {\n    slug,\n    ...matterResult.data,\n    content: matterResult.content,\n  };\n}\n"
  },
  {
    "path": "next/src/pages/_app.tsx",
    "content": "/* eslint-disable import/order */\nimport { type AppType } from \"next/app\";\nimport { type Session } from \"next-auth\";\nimport { SessionProvider } from \"next-auth/react\";\n\nimport { api } from \"../utils/api\";\n\nimport \"../styles/globals.css\";\nimport { Analytics } from \"@vercel/analytics/react\";\nimport { appWithTranslation, useTranslation } from \"next-i18next\";\nimport { useEffect } from \"react\";\n\nimport nextI18NextConfig from \"../../next-i18next.config.js\";\n\nimport { GoogleAnalytics } from \"nextjs-google-analytics\";\n\nconst MyApp: AppType<{ session: Session | null }> = ({\n  Component,\n  pageProps: { session, ...pageProps },\n}) => {\n  const { i18n } = useTranslation();\n\n  useEffect(() => {\n    i18n.on(\"languageChanged\", () => {\n      document.documentElement.lang = i18n.language;\n    });\n    document.documentElement.lang = i18n.language;\n  }, [i18n]);\n\n  return (\n    <div>\n      <SessionProvider session={session}>\n        <GoogleAnalytics trackPageViews />\n        <Analytics />\n        <Component {...pageProps} />\n      </SessionProvider>\n    </div>\n  );\n};\n\nexport default api.withTRPC(appWithTranslation(MyApp, nextI18NextConfig));\n"
  },
  {
    "path": "next/src/pages/agent/index.tsx",
    "content": "import type { GetStaticProps } from \"next\";\nimport { type NextPage } from \"next\";\nimport { useRouter } from \"next/router\";\nimport { useTranslation } from \"next-i18next\";\nimport { serverSideTranslations } from \"next-i18next/serverSideTranslations\";\nimport React, { useState } from \"react\";\nimport { FaBackspace, FaShare, FaTrash } from \"react-icons/fa\";\n\nimport nextI18NextConfig from \"../../../next-i18next.config\";\nimport Button from \"../../components/Button\";\nimport { ChatMessage } from \"../../components/console/ChatMessage\";\nimport ChatWindow from \"../../components/console/ChatWindow\";\nimport FadeIn from \"../../components/motions/FadeIn\";\nimport Toast from \"../../components/toast\";\nimport { env } from \"../../env/client.mjs\";\nimport DashboardLayout from \"../../layout/dashboard\";\nimport type { Message } from \"../../types/message\";\nimport { api } from \"../../utils/api\";\nimport { languages } from \"../../utils/languages\";\n\nconst AgentPage: NextPage = () => {\n  const [t] = useTranslation();\n  const [showCopied, setShowCopied] = useState(false);\n  const router = useRouter();\n\n  const agentId = typeof router.query.id === \"string\" ? router.query.id : \"\";\n\n  const getAgent = api.agent.findById.useQuery(agentId, {\n    enabled: router.isReady,\n  });\n\n  const deleteAgent = api.agent.deleteById.useMutation({\n    onSuccess: () => {\n      void router.push(\"/\");\n    },\n  });\n\n  const messages = getAgent.data ? (getAgent.data.tasks as Message[]) : [];\n\n  const shareLink = () => {\n    return encodeURI(`${env.NEXT_PUBLIC_VERCEL_URL}${router.asPath}`);\n  };\n\n  return (\n    <DashboardLayout>\n      <div\n        id=\"content\"\n        className=\"flex h-screen max-w-full flex-col items-center justify-center gap-3 px-3 pt-7 md:px-10\"\n      >\n        <div className=\"flex w-full max-w-screen-md flex-grow flex-col items-center overflow-hidden\">\n          <ChatWindow messages={messages} title={getAgent?.data?.name} visibleOnMobile>\n            {messages.map((message, index) => {\n              return (\n                <FadeIn key={`${index}-${message.type}`}>\n                  <ChatMessage message={message} />\n                </FadeIn>\n              );\n            })}\n          </ChatWindow>\n        </div>\n        <div className=\"flex flex-row gap-2\">\n          <Button icon={<FaBackspace />} onClick={() => void router.push(\"/\")}>\n            Back\n          </Button>\n          <Button\n            icon={<FaTrash />}\n            loader\n            onClick={() => {\n              deleteAgent.mutate(agentId);\n            }}\n            enabledClassName={\"bg-red-600 hover:bg-red-400\"}\n          >\n            Delete\n          </Button>\n\n          <Button\n            icon={<FaShare />}\n            onClick={() => {\n              void window.navigator.clipboard\n                .writeText(shareLink())\n                .then(() => setShowCopied(true));\n            }}\n            enabledClassName={\"bg-green-600 hover:bg-green-400\"}\n          >\n            Share\n          </Button>\n        </div>\n        <Toast\n          model={[showCopied, setShowCopied]}\n          title={t(\"COPIED_TO_CLIPBOARD\", { ns: \"common\" })}\n          className=\"bg-gray-950 text-sm\"\n        />\n      </div>\n    </DashboardLayout>\n  );\n};\n\nexport default AgentPage;\n\nexport const getStaticProps: GetStaticProps = async ({ locale = \"en\" }) => {\n  const supportedLocales = languages.map((language) => language.code);\n  const chosenLocale = supportedLocales.includes(locale) ? locale : \"en\";\n\n  return {\n    props: {\n      ...(await serverSideTranslations(chosenLocale, nextI18NextConfig.ns)),\n    },\n  };\n};\n"
  },
  {
    "path": "next/src/pages/api/auth/[...nextauth].ts",
    "content": "import type { NextApiRequest, NextApiResponse } from \"next\";\nimport NextAuth from \"next-auth\";\n\nimport { authOptions } from \"../../../server/auth\";\n\nconst auth = (req: NextApiRequest, res: NextApiResponse) => {\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return NextAuth(req, res, authOptions(req, res));\n};\n\nexport default auth;\n"
  },
  {
    "path": "next/src/pages/api/trpc/[trpc].ts",
    "content": "import { createNextApiHandler } from \"@trpc/server/adapters/next\";\n\nimport { env } from \"../../../env/server.mjs\";\nimport { appRouter } from \"../../../server/api/root\";\nimport { createTRPCContext } from \"../../../server/api/trpc\";\n\n// export API handler\nexport default createNextApiHandler({\n  router: appRouter,\n  createContext: createTRPCContext,\n  onError:\n    env.NODE_ENV === \"development\"\n      ? ({ path, error }) => {\n          console.error(`❌ tRPC failed on ${path ?? \"<no-path>\"}: ${error.message}`);\n        }\n      : undefined,\n});\n"
  },
  {
    "path": "next/src/pages/blog/[slug].tsx",
    "content": "import { useRouter } from \"next/router\";\nimport React from \"react\";\nimport ReactMarkdown from \"react-markdown\";\n\nimport AppHead from \"../../components/AppHead\";\nimport FooterLinks from \"../../components/landing/FooterLinks\";\nimport FadeIn from \"../../components/motions/FadeIn\";\nimport NavBar from \"../../components/NavBar\";\nimport { getPostData, getSortedPostsData } from \"../../lib/posts\";\n\n\n\n\nexport default function BlogPost({\n  postData,\n}: {\n  postData: { title: string; date: string; content: string };\n}) {\n  const router = useRouter();\n\n  if (router.isFallback) {\n    return <div>Loading...</div>;\n  }\n\n  return (\n    <div className=\"min-w-screen mx-6 grid min-h-screen place-items-center py-2 selection:bg-purple-700/25 lg:overflow-x-hidden lg:overflow-y-hidden\">\n      <AppHead title=\"Reworkd Blog\" />\n\n      <div className=\"flex h-full w-full max-w-[1440px] flex-col justify-between overflow-hidden\">\n        <NavBar />\n        <FadeIn duration={3}>\n          <div className=\"flex min-h-screen justify-center\">\n            <div className=\"bg-stars animate-stars\"></div>\n            <div className=\"flex h-full max-w-[1440px] flex-col justify-between\">\n              <main className=\"mx-auto px-6 lg:px-8\">\n                <div className=\"bg-transparent py-8 sm:py-16\">\n                  <div className=\"mx-auto max-w-2xl text-center\">\n                    <h2 className=\"text-3xl font-bold tracking-tight text-white sm:text-4xl\">\n                      Reblogd\n                    </h2>\n                  </div>\n                </div>\n              </main>\n              <div className=\"mx-auto mb-8 max-w-2xl sm:mb-16\">\n                <div className=\"text-white\">\n                  <p>{postData.date}</p>\n                  <ReactMarkdown className=\"prose text-white\">{postData.content}</ReactMarkdown>\n                </div>\n              </div>\n            </div>\n          </div>\n          <footer className=\"flex flex-col items-center justify-center gap-2 pb-2 sm:gap-4 sm:pb-4 lg:flex-row\">\n            <FooterLinks />\n            <div className=\"font-inter text-xs font-normal text-gray-300 sm:text-sm lg:order-first\">\n              &copy; 2023 Reworkd AI, Inc.\n            </div>\n          </footer>\n        </FadeIn>\n      </div>\n    </div>\n  );\n}\n\nexport async function getStaticPaths() {\n  // Fetch the list of blog post slugs or IDs dynamically\n  const allPostsData = getSortedPostsData();\n\n  // Generate the paths based on the slugs\n  const paths = allPostsData.map(({ id }) => ({\n    params: { slug: id },\n  }));\n\n  return {\n    paths,\n    fallback: true,\n  };\n}\n\nexport async function getStaticProps({ params }: { params: { slug: string } }) {\n  const postData = getPostData(params.slug);\n\n  return {\n    props: {\n      postData,\n    },\n  };\n}\n"
  },
  {
    "path": "next/src/pages/blog.tsx",
    "content": "import React from \"react\";\nimport { useRouter } from \"next/router\";\n\nimport AppHead from \"../components/AppHead\";\nimport FooterLinks from \"../components/landing/FooterLinks\";\nimport FadeIn from \"../components/motions/FadeIn\";\nimport NavBar from \"../components/NavBar\";\nimport { getSortedPostsData } from \"../lib/posts\";\n\n\nexport default function BlogPage({ allPostsData }) { \n  const router = useRouter();\n\n  return (\n    <div className=\"min-w-screen mx-6 grid min-h-screen place-items-center py-2 selection:bg-purple-700/25 lg:overflow-x-hidden lg:overflow-y-hidden\">\n      <AppHead title=\"Reworkd Blog\" />\n\n      <div className=\"flex h-full w-full max-w-[1440px] flex-col justify-between overflow-hidden\">\n        <NavBar />\n        <FadeIn initialY={30} duration={3}>\n          <div className=\"flex min-h-screen justify-center\">\n            <div className=\"bg-stars animate-stars\"></div>\n\n            <div className=\"flex h-full max-w-[1440px] flex-col justify-between\">\n              <main className=\"mx-auto px-6 lg:px-8\">\n                <div className=\"bg-transparent py-8 sm:py-16\">\n                  <div className=\"mx-auto max-w-2xl text-center\">\n                    <h2 className=\"text-3xl font-bold tracking-tight text-white sm:text-4xl\">\n                      Reblogd\n                    </h2>\n                  </div>\n                </div>\n              </main>\n              <div className=\"flex-grow overflow-y-auto\">\n                <div className=\"mx-auto mb-8 max-w-2xl cursor-pointer sm:mb-16\">\n                  {allPostsData.map(({ id, title, date, imageUrl, category, author }) => (\n                    <article\n                      key={id}\n                      className=\"flex flex-col items-start justify-between rounded-lg p-3 transition-all duration-300 hover:bg-white/5\"\n                      onClick={() => {\n                        router.push(`/blog/${id}`).catch(console.error);\n                      }}\n                    >\n                      <div className=\"relative w-full\">\n                        <div className=\"absolute inset-0 rounded-2xl ring-1 ring-inset ring-gray-900/10\" />\n                        <img\n                          src={imageUrl}\n                          alt=\"\"\n                          className=\"aspect-[16/9] w-full rounded-2xl bg-gray-100 object-cover sm:aspect-[2/1] lg:aspect-[3/2]\"\n                        />\n                      </div>\n                      <div className=\"max-w-xl\">\n                        <div className=\"mt-4 flex items-center gap-x-2 text-xs sm:mt-6 sm:text-sm\">\n                          <time dateTime={date} className=\"text-gray-300\">\n                            {date}\n                          </time>\n                          <p className=\"relative z-10 rounded-full bg-gray-300 px-2 py-0.5 font-medium text-gray-600\">\n                            {category.title}\n                          </p>\n                        </div>\n                        <div className=\"group relative\">\n                          <h3 className=\"mt-2 text-lg font-semibold leading-6 text-white sm:mt-4\">\n                            <span className=\"absolute inset-0\" />\n                            {title}\n                          </h3>\n                        </div>\n                        <div className=\"relative mb-10 mt-4 flex items-center gap-x-2 sm:mt-6\">\n                          <img\n                            src={author.imageUrl}\n                            alt=\"\"\n                            className=\"h-8 w-8 rounded-full bg-gray-100 sm:h-10 sm:w-10\"\n                          />\n                          <div className=\"text-sm leading-6\">\n                            <div className=\"font-semibold text-white\">\n                              <p>\n                                <span className=\"absolute inset-0\" />\n                                {author.name}\n                              </p>\n                            </div>\n                            <p className=\"text-gray-300\">{author.role}</p>\n                          </div>\n                        </div>\n                      </div>\n                    </article>\n                  ))}\n                </div>\n              </div>\n              <footer className=\"flex flex-col items-center justify-center gap-2 pb-2 sm:gap-4 sm:pb-4 lg:flex-row\">\n                <FooterLinks />\n                <div className=\"font-inter text-xs font-normal text-gray-300 sm:text-sm lg:order-first\">\n                  &copy; 2023 Reworkd AI, Inc.\n                </div>\n              </footer>\n            </div>\n          </div>\n        </FadeIn>\n      </div>\n    </div>\n  );\n}\n\nexport async function getStaticProps() {\n  const allPostsData = getSortedPostsData();\n  return {\n    props: {\n      allPostsData,\n    },\n  };\n}\n"
  },
  {
    "path": "next/src/pages/home.tsx",
    "content": "import Image from \"next/image\";\nimport React from \"react\";\n\nimport AppHead from \"../components/AppHead\";\nimport Backing from \"../components/landing/Backing\";\nimport FooterLinks from \"../components/landing/FooterLinks\";\nimport Hero from \"../components/landing/Hero\";\nimport FadeIn from \"../components/motions/FadeIn\";\nimport NavBar from \"../components/NavBar\";\n\nconst HomePage = () => {\n  return (\n    <div className=\"min-w-screen mx-6 grid min-h-screen place-items-center bg-black py-2 selection:bg-purple-700/25 lg:overflow-x-hidden lg:overflow-y-hidden\">\n      <AppHead\n        title=\"Reworkd\"\n        ogTitle=\"Automate core business workflows with the help of AI Agents\"\n      />\n      <div className=\"absolute -z-50  h-full w-full bg-black\" />\n      <Image src=\"/stars.svg\" alt=\"stars\" fill className=\"pointer-events-none absolute invert-0\" />\n\n      <div className=\"flex h-full max-w-[1440px] flex-col justify-between\">\n        <NavBar />\n        <main className=\"mx-auto sm:px-16\">\n          <Hero />\n        </main>\n        <FadeIn initialY={30} duration={3}>\n          <footer className=\"flex flex-col items-center gap-2 pb-4 lg:flex-row\">\n            <Backing className=\"flex-grow\" />\n            <FooterLinks />\n            <div className=\"font-inter text-xs font-normal text-white/30 lg:order-first lg:text-sm\">\n              &copy; 2023 Reworkd AI, Inc.\n            </div>\n          </footer>\n        </FadeIn>\n      </div>\n    </div>\n  );\n};\n\nexport default HomePage;\n"
  },
  {
    "path": "next/src/pages/index.tsx",
    "content": "import { type GetStaticProps, type NextPage } from \"next\";\nimport { useTranslation } from \"next-i18next\";\nimport { serverSideTranslations } from \"next-i18next/serverSideTranslations\";\nimport React, { useEffect, useRef } from \"react\";\n\nimport nextI18NextConfig from \"../../next-i18next.config.js\";\nimport HelpDialog from \"../components/dialog/HelpDialog\";\nimport { SignInDialog } from \"../components/dialog/SignInDialog\";\nimport Chat from \"../components/index/chat\";\nimport Landing from \"../components/index/landing\";\nimport { useAgent } from \"../hooks/useAgent\";\nimport { useAuth } from \"../hooks/useAuth\";\nimport { useSettings } from \"../hooks/useSettings\";\nimport DashboardLayout from \"../layout/dashboard\";\nimport { AgentApi } from \"../services/agent/agent-api\";\nimport { DefaultAgentRunModel } from \"../services/agent/agent-run-model\";\nimport AutonomousAgent from \"../services/agent/autonomous-agent\";\nimport { MessageService } from \"../services/agent/message-service\";\nimport {\n  resetAllAgentSlices,\n  resetAllMessageSlices,\n  useAgentStore,\n  useMessageStore,\n} from \"../stores\";\nimport { useAgentInputStore } from \"../stores/agentInputStore\";\nimport { resetAllTaskSlices, useTaskStore } from \"../stores/taskStore\";\nimport { toApiModelSettings } from \"../utils/interfaces\";\nimport { languages } from \"../utils/languages\";\nimport { isEmptyOrBlank } from \"../utils/whitespace\";\n\nconst Home: NextPage = () => {\n  const { t } = useTranslation(\"indexPage\");\n  const addMessage = useMessageStore.use.addMessage();\n  const messages = useMessageStore.use.messages();\n  const tasks = useTaskStore.use.tasks();\n\n  const setAgent = useAgentStore.use.setAgent();\n  const agentLifecycle = useAgentStore.use.lifecycle();\n\n  const agent = useAgentStore.use.agent();\n\n  const { session } = useAuth();\n  const nameInput = useAgentInputStore.use.nameInput();\n  const setNameInput = useAgentInputStore.use.setNameInput();\n  const goalInput = useAgentInputStore.use.goalInput();\n  const setGoalInput = useAgentInputStore.use.setGoalInput();\n  const { settings } = useSettings();\n\n  const [showSignInDialog, setShowSignInDialog] = React.useState(false);\n  const agentUtils = useAgent();\n\n  const goalInputRef = useRef<HTMLInputElement>(null);\n  useEffect(() => {\n    goalInputRef?.current?.focus();\n  }, []);\n\n  const setAgentRun = (newName: string, newGoal: string) => {\n    setNameInput(newName);\n    setGoalInput(newGoal);\n    handlePlay(newGoal);\n  };\n\n  const disableStartAgent =\n    (agent !== null && ![\"paused\", \"stopped\"].includes(agentLifecycle)) ||\n    isEmptyOrBlank(goalInput);\n\n  const handlePlay = (goal: string) => {\n    if (agentLifecycle === \"stopped\") handleRestart();\n    else handleNewAgent(goal.trim());\n  };\n\n  const handleNewAgent = (goal: string) => {\n    if (session === null) {\n      storeAgentDataInLocalStorage(\"\", goal);\n      setShowSignInDialog(true);\n      return;\n    }\n\n    if (agent && agentLifecycle == \"paused\") {\n      agent?.run().catch(console.error);\n      return;\n    }\n\n    const model = new DefaultAgentRunModel(goal.trim());\n    const messageService = new MessageService(addMessage);\n    const agentApi = new AgentApi({\n      model_settings: toApiModelSettings(settings, session),\n      goal: goal,\n      session: session,\n      agentUtils: agentUtils,\n    });\n    const newAgent = new AutonomousAgent(\n      model,\n      messageService,\n      settings,\n      agentApi,\n      session ?? undefined\n    );\n    setAgent(newAgent);\n    newAgent?.run().then(console.log).catch(console.error);\n  };\n\n  const storeAgentDataInLocalStorage = (name: string, goal: string) => {\n    const agentData = { name, goal };\n    localStorage.setItem(\"agentData\", JSON.stringify(agentData));\n  };\n\n  const getAgentDataFromLocalStorage = () => {\n    const agentData = localStorage.getItem(\"agentData\");\n    return agentData ? (JSON.parse(agentData) as { name: string; goal: string }) : null;\n  };\n\n  useEffect(() => {\n    if (session !== null) {\n      const agentData = getAgentDataFromLocalStorage();\n\n      if (agentData) {\n        setNameInput(agentData.name);\n        setGoalInput(agentData.goal);\n        localStorage.removeItem(\"agentData\");\n      }\n    }\n  }, [session, setGoalInput, setNameInput]);\n\n  const handleRestart = () => {\n    resetAllMessageSlices();\n    resetAllTaskSlices();\n    resetAllAgentSlices();\n  };\n\n  const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n    // Only Enter is pressed, execute the function\n    if (e.key === \"Enter\" && !disableStartAgent && !e.shiftKey) {\n      handlePlay(goalInput);\n    }\n  };\n\n  return (\n    <DashboardLayout\n      onReload={() => {\n        agent?.stopAgent();\n        handleRestart();\n      }}\n    >\n      <HelpDialog />\n\n      <SignInDialog show={showSignInDialog} setOpen={setShowSignInDialog} />\n      <div id=\"content\" className=\"flex min-h-screen w-full items-center justify-center\">\n        <div\n          id=\"layout\"\n          className=\"relative flex h-screen w-full max-w-screen-md flex-col items-center justify-center gap-5 overflow-hidden p-2 py-10 sm:gap-3 sm:p-4\"\n        >\n          {agent !== null ? (\n            <Chat\n              messages={messages}\n              disableStartAgent={disableStartAgent}\n              handlePlay={handlePlay}\n              nameInput={nameInput}\n              goalInput={goalInput}\n              setShowSignInDialog={setShowSignInDialog}\n              setAgentRun={setAgentRun}\n            />\n          ) : (\n            <Landing\n              messages={messages}\n              disableStartAgent={disableStartAgent}\n              handlePlay={() => handlePlay(goalInput)}\n              handleKeyPress={handleKeyPress}\n              goalInputRef={goalInputRef}\n              goalInput={goalInput}\n              setGoalInput={setGoalInput}\n              setShowSignInDialog={setShowSignInDialog}\n              setAgentRun={setAgentRun}\n            />\n          )}\n        </div>\n      </div>\n    </DashboardLayout>\n  );\n};\n\nexport default Home;\n\nexport const getStaticProps: GetStaticProps = async ({ locale = \"en\" }) => {\n  const supportedLocales = languages.map((language) => language.code);\n  const chosenLocale = supportedLocales.includes(locale) ? locale : \"en\";\n\n  return {\n    props: {\n      ...(await serverSideTranslations(chosenLocale, nextI18NextConfig.ns)),\n    },\n  };\n};\n"
  },
  {
    "path": "next/src/pages/settings.tsx",
    "content": "import axios from \"axios\";\nimport clsx from \"clsx\";\nimport type { GetStaticProps } from \"next\";\nimport { useTranslation } from \"next-i18next\";\nimport { serverSideTranslations } from \"next-i18next/serverSideTranslations\";\nimport React, { useState } from \"react\";\nimport {\n  FaCheckCircle,\n  FaCoins,\n  FaExclamationCircle,\n  FaGlobe,\n  FaKey,\n  FaRobot,\n  FaSyncAlt,\n  FaThermometerFull,\n} from \"react-icons/fa\";\n\nimport nextI18NextConfig from \"../../next-i18next.config.js\";\nimport FadeIn from \"../components/motions/FadeIn\";\nimport { useAuth } from \"../hooks/useAuth\";\nimport type { LLMModel } from \"../hooks/useModels\";\nimport { useModels } from \"../hooks/useModels\";\nimport { useSettings } from \"../hooks/useSettings\";\nimport DashboardLayout from \"../layout/dashboard\";\nimport type { GPTModelNames } from \"../types\";\nimport Button from \"../ui/button\";\nimport Combo from \"../ui/combox\";\nimport Input from \"../ui/input\";\nimport type { Language } from \"../utils/languages\";\nimport { languages } from \"../utils/languages\";\n\nconst SettingsPage = () => {\n  const [t] = useTranslation(\"settings\");\n  const { settings, updateSettings, updateLangauge } = useSettings();\n  const { session } = useAuth({ protectedRoute: true });\n  const { models, getModel } = useModels();\n\n  const [isApiKeyValid, setIsApiKeyValid] = useState<boolean | undefined>(undefined);\n\n  const validateApiKey = async () => {\n    try {\n      await axios.get(\"https://api.openai.com/v1/engines\", {\n        headers: {\n          Authorization: `Bearer ${settings.customApiKey}`,\n        },\n      });\n\n      setIsApiKeyValid(true);\n    } catch (error) {\n      setIsApiKeyValid(false);\n    }\n  };\n\n  const disableAdvancedSettings = !session?.user;\n  const model = getModel(settings.customModelName) || {\n    name: settings.customModelName,\n    max_tokens: 2000,\n    has_access: true,\n  };\n\n  const updateModel = (model: LLMModel) => {\n    if (settings.maxTokens > model.max_tokens) {\n      updateSettings(\"maxTokens\", model.max_tokens);\n    }\n\n    updateSettings(\"customModelName\", model.name as GPTModelNames);\n  };\n\n  const onDisconnect = () => {\n    return Promise.resolve();\n  };\n\n  return (\n    <DashboardLayout>\n      <div className=\"min-h-screen flex-grow\">\n        <div className=\"\">\n          <FadeIn\n            initialX={-45}\n            initialY={0}\n            delay={0.1}\n            className=\"border-b border-slate-6 px-10 py-10\"\n          >\n            <div>\n              {\" \"}\n              <h1 className=\"text-4xl font-bold text-slate-12\">Settings</h1>\n              <h2 className=\"text-xl font-light text-slate-12\">Customize your agent experience</h2>\n            </div>\n          </FadeIn>\n          <FadeIn initialY={45} delay={0.1} className=\"mt-4 px-10\">\n            <div className=\"flex flex-col gap-3\">\n              <Combo<Language>\n                label=\"Language\"\n                value={settings.language}\n                valueMapper={(e) => e.name}\n                onChange={(e) => {\n                  updateLangauge(e).catch(console.error);\n                }}\n                items={languages}\n                icon={<FaGlobe />}\n              />\n              <Input\n                label=\"API Key\"\n                name=\"api-key\"\n                placeholder=\"sk...\"\n                helpText={\n                  <span>\n                    You can optionally use your own API key here. You can find your API key in your{\" \"}\n                    <a className=\"link\" href=\"https://platform.openai.com/account/api-keys\">\n                      OpenAI dashboard.\n                    </a>\n                  </span>\n                }\n                type=\"text\"\n                value={settings.customApiKey}\n                onChange={(e) => {\n                  setIsApiKeyValid(undefined);\n                  updateSettings(\"customApiKey\", e.target.value);\n                }}\n                icon={<FaKey />}\n                className=\"flex-grow-1 mr-2\"\n                right={\n                  <Button\n                    onClick={validateApiKey}\n                    className={clsx(\n                      \"transition-400 h-11 w-16 rounded text-sm text-white duration-200\",\n                      isApiKeyValid === undefined && \"bg-gray-500 hover:bg-gray-700\",\n                      isApiKeyValid === true && \"bg-green-500 hover:bg-green-700\",\n                      isApiKeyValid === false && \"bg-red-500 hover:bg-red-700\"\n                    )}\n                  >\n                    {isApiKeyValid === undefined && \"Test\"}\n                    {isApiKeyValid === true && <FaCheckCircle />}\n                    {isApiKeyValid === false && <FaExclamationCircle />}\n                  </Button>\n                }\n              />\n            </div>\n\n            {!disableAdvancedSettings && (\n              <div className=\"mt-4 flex flex-col \">\n                <h1 className=\"pb-4 text-xl font-bold text-slate-12\">Advanced Settings</h1>\n                <div className=\"flex flex-col gap-4\">\n                  <Combo<LLMModel>\n                    label=\"Model\"\n                    value={model}\n                    valueMapper={(e) => e.name}\n                    onChange={updateModel}\n                    items={models}\n                    icon={<FaRobot />}\n                  />\n                  <Input\n                    label={`${t(\"TEMPERATURE\")}`}\n                    value={settings.customTemperature}\n                    name=\"temperature\"\n                    type=\"range\"\n                    onChange={(e) =>\n                      updateSettings(\"customTemperature\", parseFloat(e.target.value))\n                    }\n                    attributes={{\n                      min: 0,\n                      max: 1,\n                      step: 0.01,\n                    }}\n                    helpText={t(\"HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM\")}\n                    icon={<FaThermometerFull />}\n                    disabled={disableAdvancedSettings}\n                  />\n                  <Input\n                    label={`${t(\"LOOP\")}`}\n                    value={settings.customMaxLoops}\n                    name=\"loop\"\n                    type=\"range\"\n                    onChange={(e) => updateSettings(\"customMaxLoops\", parseFloat(e.target.value))}\n                    attributes={{\n                      min: 1,\n                      max: 25,\n                      step: 1,\n                    }}\n                    helpText={t(\"CONTROL_THE_MAXIMUM_NUM_OF_LOOPS\")}\n                    icon={<FaSyncAlt />}\n                    disabled={disableAdvancedSettings}\n                  />\n                  <Input\n                    label={`${t(\"TOKENS\")}`}\n                    value={settings.maxTokens}\n                    name=\"tokens\"\n                    type=\"range\"\n                    onChange={(e) => updateSettings(\"maxTokens\", parseFloat(e.target.value))}\n                    attributes={{\n                      min: 200,\n                      max: model.max_tokens,\n                      step: 100,\n                    }}\n                    helpText={t(\"CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION\")}\n                    icon={<FaCoins />}\n                    disabled={disableAdvancedSettings}\n                  />\n                </div>\n              </div>\n            )}\n          </FadeIn>\n        </div>\n      </div>\n    </DashboardLayout>\n  );\n};\n\nexport default SettingsPage;\n\nexport const getStaticProps: GetStaticProps = async ({ locale = \"en\" }) => {\n  const supportedLocales = languages.map((language) => language.code);\n  const chosenLocale = supportedLocales.includes(locale) ? locale : \"en\";\n\n  return {\n    props: {\n      ...(await serverSideTranslations(chosenLocale, nextI18NextConfig.ns)),\n    },\n  };\n};\n"
  },
  {
    "path": "next/src/pages/signin.tsx",
    "content": "import clsx from \"clsx\";\nimport type { GetServerSidePropsContext } from \"next\";\nimport Image from \"next/image\";\nimport { useRouter } from \"next/router\";\nimport { getServerSession } from \"next-auth/next\";\nimport type { BuiltInProviderType } from \"next-auth/providers\";\nimport type { ClientSafeProvider } from \"next-auth/react\";\nimport { getProviders, signIn, useSession } from \"next-auth/react\";\nimport type { LiteralUnion } from \"next-auth/react/types\";\nimport React, { useState } from \"react\";\nimport { FaDiscord, FaGithub, FaGoogle } from \"react-icons/fa\";\n\nimport FadeIn from \"../components/motions/FadeIn\";\nimport GridLayout from \"../layout/grid\";\nimport { authOptions } from \"../server/auth/auth\";\nimport Input from \"../ui/input\";\n\nconst SignIn = ({ providers }: { providers: Provider }) => {\n  const { data: session } = useSession();\n  const { push } = useRouter();\n\n  if (session) push(\"/\").catch(console.error);\n\n  const details = Object.values(providers)\n    .map((provider) => providerButtonDetails[provider.id])\n    .filter((detail): detail is ButtonDetail => detail !== undefined);\n\n  return (\n    <GridLayout title=\"Sign in - Reworkd\">\n      <div className=\"grid h-screen w-screen place-items-center bg-gradient-radial from-slate-1 via-20% to-transparent\">\n        <div className=\"flex h-full w-full max-w-screen-lg flex-col items-center justify-center gap-10\">\n          <FadeIn\n            duration={1.5}\n            initialY={-50}\n            className=\"flex flex-col items-center justify-center gap-6 text-white invert\"\n          >\n            <div className=\"flex flex-col items-center justify-center gap-16\">\n              <Image\n                src=\"/logos/dark-default-gradient.svg\"\n                width=\"150\"\n                height=\"150\"\n                alt=\"Reworkd AI\"\n              />\n              <h1 className=\"bg-gradient-to-t from-white via-neutral-300 to-neutral-500 bg-clip-text text-center text-3xl font-bold leading-[1.1em] tracking-[-0.64px] text-transparent md:text-5xl\">\n                Reworkd\n              </h1>\n            </div>\n          </FadeIn>\n          <FadeIn duration={1.5} delay={0.4} initialY={50}>\n            {providers.credentials && <InsecureSignin />}\n            {details.map((detail) => (\n              <ProviderSignInButton key={detail.id} detail={detail} />\n            ))}\n          </FadeIn>\n        </div>\n      </div>\n    </GridLayout>\n  );\n};\n\nconst InsecureSignin = () => {\n  const [usernameValue, setUsernameValue] = useState(\"\");\n\n  return (\n    <div className=\"flex flex-col\">\n      <Input\n        value={usernameValue}\n        onChange={(e) => setUsernameValue(e.target.value)}\n        placeholder=\"Enter Username\"\n        type=\"text\"\n        name=\"Username Field\"\n      />\n      <button\n        onClick={() => {\n          if (!usernameValue) return;\n\n          signIn(\"credentials\", {\n            callbackUrl: \"/\",\n            name: usernameValue,\n          }).catch(console.error);\n        }}\n        className={clsx(\n          \"mb-4 mt-4 flex items-center rounded-md bg-slate-12 px-10 py-3 text-sm font-semibold text-white transition-colors duration-300 hover:bg-slate-10 sm:text-base\",\n          !usernameValue && \"cursor-not-allowed\"\n        )}\n      >\n        Sign in with username (Insecure)\n      </button>\n    </div>\n  );\n};\n\ntype Provider = Record<LiteralUnion<BuiltInProviderType>, ClientSafeProvider>;\n\ninterface ButtonDetail {\n  id: string;\n  icon: JSX.Element;\n  color: string;\n}\n\nconst providerButtonDetails: { [key: string]: ButtonDetail } = {\n  google: {\n    id: \"google\",\n    icon: <FaGoogle className=\"mr-2\" />,\n    color: \"bg-white hover:bg-gray-200 text-black\",\n  },\n  discord: {\n    id: \"discord\",\n    icon: <FaDiscord className=\"mr-2\" />,\n    color: \"bg-blue-600 hover:bg-blue-700 text-white\",\n  },\n  github: {\n    id: \"github\",\n    icon: <FaGithub className=\"mr-2\" />,\n    color: \"bg-gray-800 hover:bg-gray-900 text-white\",\n  },\n};\n\nconst ProviderSignInButton = ({ detail }: { detail: ButtonDetail }) => {\n  return (\n    <button\n      onClick={() => {\n        signIn(detail.id, { callbackUrl: \"/\" }).catch(console.error);\n      }}\n      className={clsx(\n        detail.color,\n        \"mb-4 flex w-full items-center rounded-md px-10 py-3 text-base font-semibold shadow-md transition-colors duration-300 sm:px-16 sm:py-5 sm:text-xl\"\n      )}\n    >\n      {detail.icon}\n      Sign in with {detail.id}\n    </button>\n  );\n};\n\nexport default SignIn;\n\nexport async function getServerSideProps(context: GetServerSidePropsContext) {\n  const session = await getServerSession(context.req, context.res, authOptions);\n\n  if (session) {\n    return {\n      redirect: {\n        destination: \"/\",\n      },\n    };\n  }\n\n  return {\n    props: { providers: (await getProviders()) ?? {} },\n  };\n}\n"
  },
  {
    "path": "next/src/pages/templates.tsx",
    "content": "import type { GetStaticProps } from \"next\";\nimport { serverSideTranslations } from \"next-i18next/serverSideTranslations\";\nimport React, { useState } from \"react\";\n\nimport nextI18NextConfig from \"../../next-i18next.config.js\";\nimport FadeIn from \"../components/motions/FadeIn\";\nimport TemplateCard from \"../components/templates/TemplateCard\";\nimport { TEMPLATE_DATA } from \"../components/templates/TemplateData\";\nimport SearchBar from \"../components/templates/TemplateSearch\";\nimport DashboardLayout from \"../layout/dashboard\";\nimport { languages } from \"../utils/languages\";\n\nconst Templates = () => {\n  const [searchQuery, setSearchQuery] = useState(\"\");\n  const [category, setCategory] = useState(\"\");\n\n  const filteredData = TEMPLATE_DATA.filter((model) => {\n    const matchQuery = model.name.toLowerCase().includes(searchQuery.toLowerCase());\n    const matchCategory =\n      category === \"\" || model.category.toLowerCase() === category.toLowerCase();\n    return matchQuery && matchCategory;\n  });\n\n  return (\n    <DashboardLayout>\n      <div className=\"flex h-full w-full flex-col p-10\">\n        <FadeIn initialX={-45} initialY={0} delay={0.1}>\n          <div>\n            <h1 className=\"text-4xl font-bold text-slate-12\">Templates</h1>\n            <h2 className=\"text-xl font-thin text-slate-12\">\n              Customizable and ready to deploy agents\n            </h2>\n          </div>\n        </FadeIn>\n        <FadeIn initialY={45} delay={0.1} className=\"mt-4\">\n          <SearchBar setSearchQuery={setSearchQuery} setCategory={setCategory} />\n          <div className=\"mt-3 grid grid-cols-1 justify-center gap-5 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n            {filteredData.map((model) => (\n              <TemplateCard key={model.name + model.description} model={model} />\n            ))}\n          </div>\n        </FadeIn>\n      </div>\n    </DashboardLayout>\n  );\n};\n\nexport default Templates;\n\nexport const getStaticProps: GetStaticProps = async ({ locale = \"en\" }) => {\n  const supportedLocales = languages.map((language) => language.code);\n  const chosenLocale = supportedLocales.includes(locale) ? locale : \"en\";\n\n  return {\n    props: {\n      ...(await serverSideTranslations(chosenLocale, nextI18NextConfig.ns)),\n    },\n  };\n};\n"
  },
  {
    "path": "next/src/pages/welcome.tsx",
    "content": "import { motion, useAnimation } from \"framer-motion\";\nimport Image from \"next/image\";\nimport { useRouter } from \"next/router\";\nimport React, { useEffect, useState } from \"react\";\n\nimport FadeIn from \"../components/motions/FadeIn\";\nimport PrimaryButton from \"../components/PrimaryButton\";\n\nconst welcome = () => {\n  const router = useRouter();\n  const controls = useAnimation();\n  const [buttonClicked, setButtonClicked] = useState(false);\n\n  useEffect(() => {\n    controls.start({\n      scale: 1,\n      y: 0,\n      transition: { type: \"spring\", stiffness: 80, damping: 15, mass: 1 },\n    });\n  }, [controls]);\n\n  useEffect(() => {\n    if (buttonClicked) {\n      controls.start({\n        opacity: 0,\n        transition: { duration: 0.75 },\n      });\n    }\n  }, [buttonClicked, controls]);\n\n  const handleButtonClick = () => {\n    setButtonClicked(true);\n    setInterval(() => {\n      // Wait 1 second and redirect\n      router.push(\"/\").catch(console.error);\n    }, 1000);\n  };\n\n  return (\n    <div className=\"flex h-full min-h-screen w-full items-center justify-center overflow-hidden bg-black\">\n      <motion.div\n        className=\"max-h-4xl flex h-full w-full max-w-4xl flex-col items-center justify-center text-center font-sans\"\n        initial={{ scale: 5, y: 1100, opacity: 1 }}\n        animate={controls}\n      >\n        <motion.div>\n          <Image\n            src=\"/logos/dark-default-solid.svg\"\n            width=\"150\"\n            height=\"150\"\n            alt=\"Reworkd AI\"\n            className=\"m-4\"\n          />\n        </motion.div>\n        <FadeIn duration={3} delay={0.45} initialY={-40}>\n          <h1 className=\"mb-6 text-5xl font-semibold tracking-widest text-white\">\n            Welcome to Reworkd\n          </h1>\n        </FadeIn>\n        <FadeIn duration={2.85} delay={0.6} initialY={-40}>\n          <p className=\"mb-8 max-w-lg text-center font-light text-neutral-500\">\n            Optimize web scraping with AI Agents that auto-generates, repairs scripts, and ensures uninterrupted data retrieval. Scale your data extraction effortlessly.\n          </p>\n        </FadeIn>\n        <FadeIn duration={2.7} delay={0.75} initialY={-40}>\n          <PrimaryButton className=\"px-16 font-bold\" onClick={handleButtonClick}>\n            Get Started\n          </PrimaryButton>\n        </FadeIn>\n      </motion.div>\n    </div>\n  );\n};\n\nexport default welcome;"
  },
  {
    "path": "next/src/server/api/root.ts",
    "content": "import { agentRouter } from \"./routers/agentRouter\";\nimport { createTRPCRouter } from \"./trpc\";\n\nexport const appRouter = createTRPCRouter({\n  agent: agentRouter,\n});\n\n// export type definition of API\nexport type AppRouter = typeof appRouter;\n"
  },
  {
    "path": "next/src/server/api/routers/agentRouter.ts",
    "content": "import OpenAI from \"openai\";\nimport { z } from \"zod\";\n\nimport { env } from \"../../../env/server.mjs\";\nimport { messageSchema } from \"../../../types/message\";\nimport { MESSAGE_TYPE_TASK } from \"../../../types/task\";\nimport { prisma } from \"../../db\";\nimport { createTRPCRouter, protectedProcedure, publicProcedure } from \"../trpc\";\n\nconst createAgentParser = z.object({\n  goal: z.string(),\n});\n\nexport type CreateAgentProps = z.infer<typeof createAgentParser>;\n\nconst saveAgentParser = z.object({\n  id: z.string(),\n  tasks: z.array(messageSchema),\n});\nexport type SaveAgentProps = z.infer<typeof saveAgentParser>;\n\nasync function generateAgentName(goal: string) {\n  if (!env.OPENAI_API_KEY) return undefined;\n\n  try {\n    const openAI = new OpenAI({\n      apiKey: env.OPENAI_API_KEY as string,\n    });\n\n    const chatCompletion = await openAI.chat.completions.create({\n      messages: [\n        {\n          role: \"user\",\n          content: goal,\n        },\n        {\n          role: \"system\",\n          content: `Summarize this into one or two words followed by \"GPT\" and a single emoji.\n           Examples:\n           - 'I want to buy a house' becomes HouseGPT 🏠\n           - 'Analyze top stock prices and generate a report' becomes AnalyzeStockGPT 📈\n           `,\n        },\n      ],\n      model: \"gpt-3.5-turbo\",\n    });\n\n    // @ts-ignore\n    return chatCompletion.choices[0].message.content as string;\n  } catch (e) {\n    console.error(e);\n    return undefined;\n  }\n}\n\nexport const agentRouter = createTRPCRouter({\n  create: protectedProcedure.input(createAgentParser).mutation(async ({ input, ctx }) => {\n    const name = (await generateAgentName(input.goal)) || input.goal;\n\n    return ctx.prisma.agent.create({\n      data: {\n        name: name.trim(),\n        goal: input.goal,\n        userId: ctx.session?.user?.id,\n      },\n    });\n  }),\n  save: protectedProcedure.input(saveAgentParser).mutation(async ({ input, ctx }) => {\n    const agent = await prisma.agent.findFirst({\n      where: {\n        id: input.id,\n        userId: ctx.session?.user?.id,\n      },\n    });\n\n    if (!agent) throw new Error(\"Agent not found\");\n\n    const all = input.tasks.map((e, i) => {\n      return prisma.agentTask.create({\n        data: {\n          agentId: agent.id,\n          type: e.type,\n          ...(e.type === MESSAGE_TYPE_TASK && { status: e.status }),\n          info: e.info,\n          value: e.value,\n          sort: 0, // TODO: Remove sort\n        },\n      });\n    });\n\n    await Promise.all(all);\n    return agent;\n  }),\n  getAll: protectedProcedure.query(async ({ ctx }) => {\n    return prisma.agent.findMany({\n      where: {\n        userId: ctx.session?.user?.id,\n        deleteDate: null,\n      },\n      orderBy: { createDate: \"desc\" },\n      take: 20,\n    });\n  }),\n  findById: publicProcedure.input(z.string()).query(async ({ input, ctx }) => {\n    return prisma.agent.findFirstOrThrow({\n      where: { id: input, deleteDate: null },\n      include: {\n        tasks: {\n          orderBy: {\n            createDate: \"asc\",\n          },\n        },\n      },\n    });\n  }),\n  deleteById: protectedProcedure.input(z.string()).mutation(async ({ input, ctx }) => {\n    await prisma.agent.updateMany({\n      where: { id: input, userId: ctx.session?.user?.id },\n      data: {\n        deleteDate: new Date(),\n      },\n    });\n  }),\n});\n"
  },
  {
    "path": "next/src/server/api/trpc.ts",
    "content": "/**\n * YOU PROBABLY DON'T NEED TO EDIT THIS FILE, UNLESS:\n * 1. You want to modify request context (see Part 1)\n * 2. You want to create a new middleware or type of procedure (see Part 3)\n *\n * tl;dr - this is where all the tRPC server stuff is created and plugged in.\n * The pieces you will need to use are documented accordingly near the end\n */\n\n/**\n * 1. CONTEXT\n *\n * This section defines the \"contexts\" that are available in the backend API\n *\n * These allow you to access things like the database, the session, etc, when\n * processing a request\n *\n */\nimport { initTRPC, TRPCError } from \"@trpc/server\";\nimport { type CreateNextContextOptions } from \"@trpc/server/adapters/next\";\nimport { type Session } from \"next-auth\";\nimport superjson from \"superjson\";\n\nimport { getServerAuthSession } from \"../auth\";\nimport { prisma } from \"../db\";\n\n/**\n * 2. INITIALIZATION\n *\n * This is where the trpc api is initialized, connecting the context and\n * transformer\n */\n\ntype CreateContextOptions = {\n  session: Session | null;\n};\n\n/**\n * This helper generates the \"internals\" for a tRPC context. If you need to use\n * it, you can export it from here\n *\n * Examples of things you may need it for:\n * - testing, so we dont have to mock Next.js' req/res\n * - trpc's `createSSGHelpers` where we don't have req/res\n * @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts\n */\nconst createInnerTRPCContext = (opts: CreateContextOptions) => {\n  return {\n    session: opts.session,\n    prisma,\n  };\n};\n\n/**\n * This is the actual context you'll use in your router. It will be used to\n * process every request that goes through your tRPC endpoint\n * @link https://trpc.io/docs/context\n */\nexport const createTRPCContext = async (opts: CreateNextContextOptions) => {\n  const { req, res } = opts;\n\n  // Get the session from the server using the unstable_getServerSession wrapper function\n  const session = await getServerAuthSession({ req, res });\n\n  return createInnerTRPCContext({\n    session,\n  });\n};\n\nconst t = initTRPC.context<typeof createTRPCContext>().create({\n  transformer: superjson,\n  errorFormatter({ shape }) {\n    return shape;\n  },\n});\n\n/**\n * 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)\n *\n * These are the pieces you use to build your tRPC API. You should import these\n * a lot in the /src/server/api/routers folder\n */\n\n/**\n * This is how you create new routers and subrouters in your tRPC API\n * @see https://trpc.io/docs/router\n */\nexport const createTRPCRouter = t.router;\n\n/**\n * Public (unauthed) procedure\n *\n * This is the base piece you use to build new queries and mutations on your\n * tRPC API. It does not guarantee that a user querying is authorized, but you\n * can still access user session data if they are logged in\n */\nexport const publicProcedure = t.procedure;\n\n/**\n * Reusable middleware that enforces users are logged in before running the\n * procedure\n */\nconst enforceUserIsAuthed = t.middleware(({ ctx, next }) => {\n  if (!ctx.session || !ctx.session.user) {\n    throw new TRPCError({ code: \"UNAUTHORIZED\" });\n  }\n  return next({\n    ctx: {\n      // infers the `session` as non-nullable\n      session: { ...ctx.session, user: ctx.session.user },\n    },\n  });\n});\n\n/**\n * Protected (authed) procedure\n *\n * If you want a query or mutation to ONLY be accessible to logged in users, use\n * this. It verifies the session is valid and guarantees ctx.session.user is not\n * null\n *\n * @see https://trpc.io/docs/procedures\n */\nexport const protectedProcedure = t.procedure.use(enforceUserIsAuthed);\n"
  },
  {
    "path": "next/src/server/auth/auth.ts",
    "content": "import type { NextAuthOptions } from \"next-auth\";\nimport DiscordProvider from \"next-auth/providers/discord\";\nimport GithubProvider from \"next-auth/providers/github\";\nimport GoogleProvider from \"next-auth/providers/google\";\n\nimport { serverEnv } from \"../../env/schema.mjs\";\n\n\nexport const authOptions: NextAuthOptions = {\n  providers: [\n    GoogleProvider({\n      clientId: serverEnv.GOOGLE_CLIENT_ID ?? \"\",\n      clientSecret: serverEnv.GOOGLE_CLIENT_SECRET ?? \"\",\n      allowDangerousEmailAccountLinking: true,\n    }),\n    GithubProvider({\n      clientId: serverEnv.GITHUB_CLIENT_ID ?? \"\",\n      clientSecret: serverEnv.GITHUB_CLIENT_SECRET ?? \"\",\n      allowDangerousEmailAccountLinking: true,\n    }),\n    DiscordProvider({\n      clientId: serverEnv.DISCORD_CLIENT_ID ?? \"\",\n      clientSecret: serverEnv.DISCORD_CLIENT_SECRET ?? \"\",\n      allowDangerousEmailAccountLinking: true,\n    }),\n  ],\n  pages: {\n    signIn: \"/signin\",\n  }\n};\n"
  },
  {
    "path": "next/src/server/auth/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"http\";\n\nimport { PrismaAdapter } from \"@next-auth/prisma-adapter\";\nimport merge from \"lodash/merge\";\nimport type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from \"next\";\nimport type { AuthOptions, Awaitable } from \"next-auth\";\nimport { getServerSession } from \"next-auth\";\nimport type { Adapter, AdapterUser } from \"next-auth/adapters\";\n\nimport { authOptions as prodOptions } from \"./auth\";\nimport { options as devOptions } from \"./local-auth\";\nimport { env } from \"../../env/server.mjs\";\nimport { prisma } from \"../db\";\n\nfunction overridePrisma<T>(fn: (user: T) => Awaitable<AdapterUser>) {\n  return async (user: T) => {\n    const newUser = await fn(user);\n\n    try {\n      // Add custom functionality here\n    } catch (e) {\n      console.error(e);\n    }\n\n    return newUser;\n  };\n}\n\nconst prismaAdapter = PrismaAdapter(prisma);\nprismaAdapter.createUser = overridePrisma<Omit<AdapterUser, \"id\">>(prismaAdapter.createUser);\n\nconst commonOptions: Partial<AuthOptions> & { adapter: Adapter } = {\n  adapter: prismaAdapter,\n  callbacks: {\n    async session({ session, user }) {\n      const [token, orgs] = await Promise.all([\n        prisma.session.findFirstOrThrow({\n          where: { userId: user.id },\n          orderBy: { expires: \"desc\" },\n        }),\n        prisma.organizationUser.findMany({\n          where: { user_id: user.id },\n          include: { organization: true },\n        }),\n      ]);\n\n      session.accessToken = token.sessionToken;\n      session.user.id = user.id;\n      session.user.superAdmin = user.superAdmin;\n      session.user.organizations = orgs.map((row) => ({\n        id: row.organization.id,\n        name: row.organization.name,\n        role: row.role,\n      }));\n\n      return session;\n    },\n  },\n};\nexport const authOptions = (\n  req: NextApiRequest | IncomingMessage,\n  res: NextApiResponse | ServerResponse\n) => {\n  const options =\n    env.NEXT_PUBLIC_VERCEL_ENV === \"development\"\n      ? devOptions(commonOptions.adapter, req, res)\n      : prodOptions;\n\n  return merge(commonOptions, options) as AuthOptions;\n};\n\n/**\n * Wrapper for getServerSession so that you don't need\n * to import the authOptions in every file.\n * @see https://next-auth.js.org/configuration/nextjs\n **/\nexport const getServerAuthSession = (ctx: {\n  req: GetServerSidePropsContext[\"req\"];\n  res: GetServerSidePropsContext[\"res\"];\n}) => {\n  return getServerSession(ctx.req, ctx.res, authOptions(ctx.req, ctx.res));\n};\n"
  },
  {
    "path": "next/src/server/auth/local-auth.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"http\";\n\nimport { getCookie, setCookie } from \"cookies-next\";\nimport type { NextApiRequest, NextApiResponse } from \"next\";\nimport type { AuthOptions } from \"next-auth\";\nimport type { Adapter, AdapterUser } from \"next-auth/adapters\";\nimport Credentials from \"next-auth/providers/credentials\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\n\nconst monthFromNow = () => {\n  const now = new Date(Date.now());\n  return new Date(now.setMonth(now.getMonth() + 1));\n};\n\nfunction cookieToString(cookie: string | undefined | null | boolean) {\n  switch (typeof cookie) {\n    case \"boolean\":\n      return cookie.toString();\n    case \"string\":\n      return cookie;\n    default:\n      return \"\";\n  }\n}\n\nexport const options = (\n  adapter: Adapter,\n  req: NextApiRequest | IncomingMessage,\n  res: NextApiResponse | ServerResponse\n): AuthOptions => {\n  return {\n    adapter,\n    providers: [\n      Credentials({\n        name: \"Username, Development Only (Insecure)\",\n        credentials: {\n          name: { label: \"Username\", type: \"text\" },\n          superAdmin: { label: \"SuperAdmin\", type: \"text\" },\n        },\n        async authorize(credentials, req) {\n          if (!credentials) return null;\n\n          const creds = z\n            .object({\n              name: z.string().min(1),\n              superAdmin: z.preprocess((str) => str === \"true\", z.boolean()).default(false),\n            })\n            .parse(credentials);\n\n          const user = await adapter.getUserByEmail(creds.name);\n          return user\n            ? adapter.updateUser({\n                id: user.id,\n                name: creds.name,\n                superAdmin: creds.superAdmin,\n              })\n            : adapter.createUser({\n                name: creds.name,\n                email: creds.name,\n                image: undefined,\n                emailVerified: null,\n                superAdmin: false,\n              } as AdapterUser);\n        },\n      }),\n    ],\n    pages: {\n      signIn: \"/signin\",\n    },\n    callbacks: {\n      // Fallback to base url if provided url is not a subdirectory\n      redirect: (params: { url: string; baseUrl: string }) =>\n        params.url.startsWith(params.baseUrl) ? params.url : params.baseUrl,\n\n      async signIn({ user }) {\n        if (user) {\n          const session = await adapter.createSession({\n            sessionToken: v4(),\n            userId: user.id,\n            expires: monthFromNow(),\n          });\n\n          // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n          setCookie(\"next-auth.session-token\", session.sessionToken, {\n            expires: session.expires,\n            req: req,\n            res: res,\n          });\n        }\n\n        return true;\n      },\n    },\n    jwt: {\n      encode: () => {\n        const cookie = getCookie(\"next-auth.session-token\", {\n          req: req,\n          res: res,\n        });\n\n        return cookieToString(cookie);\n      },\n      decode: () => {\n        return null;\n      },\n    },\n  };\n};\n"
  },
  {
    "path": "next/src/server/db.ts",
    "content": "import { PrismaClient } from \"@prisma/client\";\n\nimport { env } from \"../env/server.mjs\";\n\nconst globalForPrisma = globalThis as unknown as { prisma: PrismaClient };\n\nexport const prisma =\n  globalForPrisma.prisma ||\n  new PrismaClient({\n    log:\n      env.NODE_ENV === \"development\" ? [\"query\", \"error\", \"warn\"] : [\"error\"],\n  });\n\nif (process.env.NODE_ENV !== \"production\") globalForPrisma.prisma = prisma;\n"
  },
  {
    "path": "next/src/services/agent/agent-api.ts",
    "content": "import type { Session } from \"next-auth\";\n\nimport type { Analysis } from \"./analysis\";\nimport type { AgentUtils } from \"../../hooks/useAgent\";\nimport { useAgentStore } from \"../../stores\";\nimport type { Message } from \"../../types/message\";\nimport type { RequestBody } from \"../../utils/interfaces\";\nimport * as apiUtils from \"../api-utils\";\n\ntype ApiProps = Pick<RequestBody, \"model_settings\" | \"goal\"> & {\n  session?: Session;\n  agentUtils: AgentUtils;\n};\n\nexport class AgentApi {\n  readonly props: ApiProps;\n  agentId: string | undefined;\n  runId: string | undefined;\n\n  constructor(apiProps: ApiProps) {\n    this.props = apiProps;\n  }\n\n  async createAgent(): Promise<void> {\n    if (this.agentId) return;\n    const agent = await this.props.agentUtils.createAgent({\n      goal: this.props.goal,\n    });\n    this.agentId = agent?.id;\n  }\n\n  saveMessages(messages: Message[]): void {\n    if (!this.agentId) return;\n\n    this.props.agentUtils.saveAgent({\n      id: this.agentId,\n      tasks: messages,\n    });\n  }\n\n  async getInitialTasks(): Promise<string[]> {\n    return (await this.post<{ newTasks: string[] }>(\"/api/agent/start\", {})).newTasks;\n  }\n\n  async getAdditionalTasks(\n    tasks: {\n      current: string;\n      completed: string[];\n      remaining: string[];\n    },\n    result: string\n  ): Promise<string[]> {\n    return (\n      await this.post<{ newTasks: string[] }>(\"/api/agent/create\", {\n        result: result,\n        last_task: tasks.current,\n        tasks: tasks.remaining,\n        completed_tasks: tasks.completed,\n      })\n    ).newTasks;\n  }\n\n  async analyzeTask(task: string): Promise<Analysis> {\n    return await this.post<Analysis>(\"/api/agent/analyze\", {\n      task: task,\n      tool_names: useAgentStore.getState().tools.map((tool) => tool.name),\n    });\n  }\n\n  private async post<T>(\n    url: string,\n    data: Omit<RequestBody, \"goal\" | \"model_settings\" | \"run_id\">\n  ) {\n    const requestBody: RequestBody = {\n      model_settings: this.props.model_settings,\n      goal: this.props.goal,\n      run_id: this.runId,\n      ...data,\n    };\n\n    try {\n      useAgentStore.getState().setIsAgentThinking(true);\n      const { run_id, ...data } = await apiUtils.post<T & { run_id: string }>(\n        url,\n        requestBody,\n        this.props.session\n      );\n\n      if (this.runId === undefined) this.runId = run_id;\n      return data;\n    } finally {\n      useAgentStore.getState().setIsAgentThinking(false);\n    }\n  }\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-run-model.tsx",
    "content": "import { v4 } from \"uuid\";\n\nimport { useAgentStore } from \"../../stores\";\nimport { useTaskStore } from \"../../stores/taskStore\";\nimport type { Task, TaskStatus } from \"../../types/task\";\n\n/*\n * Abstraction over model used by Autonomous Agent to encapsulate the data required for a given run\n */\nexport interface AgentRunModel {\n  getId(): string;\n\n  getGoal(): string;\n\n  getLifecycle(): AgentLifecycle;\n\n  setLifecycle(AgentLifecycle): void;\n\n  getRemainingTasks(): Task[];\n\n  getCurrentTask(): Task | undefined;\n\n  updateTaskStatus(task: Task, status: TaskStatus): Task;\n\n  updateTaskResult(task: Task, result: string): Task;\n\n  getCompletedTasks(): Task[];\n\n  addTask(taskValue: string): void;\n}\n\nexport type AgentLifecycle = \"offline\" | \"running\" | \"pausing\" | \"paused\" | \"stopped\";\n\nexport class DefaultAgentRunModel implements AgentRunModel {\n  private readonly id: string;\n  private readonly goal: string;\n\n  constructor(goal: string) {\n    this.id = v4().toString();\n    this.goal = goal;\n  }\n\n  getId = () => this.id;\n\n  getGoal = () => this.goal;\n  getLifecycle = (): AgentLifecycle => useAgentStore.getState().lifecycle;\n  setLifecycle = (lifecycle: AgentLifecycle) => useAgentStore.getState().setLifecycle(lifecycle);\n\n  getRemainingTasks = (): Task[] => {\n    return useTaskStore.getState().tasks.filter((t: Task) => t.status === \"started\");\n  };\n\n  getCurrentTask = (): Task | undefined => this.getRemainingTasks()[0];\n\n  getCompletedTasks = (): Task[] =>\n    useTaskStore.getState().tasks.filter((t: Task) => t.status === \"completed\");\n\n  addTask = (taskValue: string): void =>\n    useTaskStore.getState().addTask({\n      id: v4().toString(),\n      type: \"task\",\n      value: taskValue,\n      status: \"started\",\n      result: \"\",\n    });\n\n  updateTaskStatus(task: Task, status: TaskStatus): Task {\n    return this.updateTask({ ...task, status });\n  }\n\n  updateTaskResult(task: Task, result: string): Task {\n    return this.updateTask({ ...task, result });\n  }\n\n  updateTask(updatedTask: Task): Task {\n    useTaskStore.getState().updateTask(updatedTask);\n    return updatedTask;\n  }\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-work/agent-work.ts",
    "content": "export default interface AgentWork {\n  run: () => Promise<void>;\n  conclude: () => Promise<void>;\n  next: () => AgentWork | undefined;\n  onError: (e: unknown) => boolean; // Handles errors and returns whether to continue retrying\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-work/analyze-task-work.ts",
    "content": "import type AgentWork from \"./agent-work\";\nimport ExecuteTaskWork from \"./execute-task-work\";\nimport type { Message } from \"../../../types/message\";\nimport type { Task } from \"../../../types/task\";\nimport type { Analysis } from \"../analysis\";\nimport type AutonomousAgent from \"../autonomous-agent\";\n\nexport default class AnalyzeTaskWork implements AgentWork {\n  analysis: Analysis | undefined = undefined;\n\n  constructor(private parent: AutonomousAgent, private task: Task) {}\n\n  run = async () => {\n    this.task = this.parent.model.updateTaskStatus(this.task, \"executing\");\n    this.analysis = await this.parent.api.analyzeTask(this.task.value);\n  };\n\n  // eslint-disable-next-line @typescript-eslint/require-await\n  conclude = async () => {\n    let message: Message | undefined = undefined;\n    if (this.analysis) {\n      message = this.parent.messageService.sendAnalysisMessage(this.analysis);\n    } else {\n      message = this.parent.messageService.skipTaskMessage(this.task);\n    }\n    this.parent.api.saveMessages([message]);\n  };\n\n  next = () => {\n    if (!this.analysis) return undefined;\n    return new ExecuteTaskWork(this.parent, this.task, this.analysis);\n  };\n\n  onError = (e: unknown): boolean => {\n    this.parent.messageService.sendErrorMessage(e);\n    return true;\n  };\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-work/chat-work.ts",
    "content": "import { v1 } from \"uuid\";\n\nimport type AgentWork from \"./agent-work\";\nimport type { Message } from \"../../../types/message\";\nimport { toApiModelSettings } from \"../../../utils/interfaces\";\nimport { streamText } from \"../../stream-utils\";\nimport type AutonomousAgent from \"../autonomous-agent\";\n\nexport default class ChatWork implements AgentWork {\n  constructor(private parent: AutonomousAgent, private message: string) {}\n\n  run = async () => {\n    const executionMessage: Message = {\n      type: \"task\",\n      status: \"completed\",\n      value: `Response for '${this.message}'`,\n      id: v1(),\n      info: \"Loading...\",\n    };\n    this.parent.messageService.sendMessage({ ...executionMessage });\n\n    // TODO: this should be moved to the api layer\n    await streamText(\n      \"/api/agent/chat\",\n      {\n        run_id: this.parent.api.runId,\n        goal: this.parent.model.getGoal(),\n        model_settings: toApiModelSettings(this.parent.modelSettings, this.parent.session),\n        message: this.message,\n        results: this.parent.model\n          .getCompletedTasks()\n          .filter((task) => task.result && task.result !== \"\")\n          .map((task) => task.result || \"\"),\n      },\n      this.parent.api.props.session?.accessToken || \"\",\n      () => {\n        executionMessage.info = \"\";\n      },\n      (text) => {\n        executionMessage.info += text;\n        this.parent.messageService.updateMessage(executionMessage);\n      },\n      () => this.parent.model.getLifecycle() === \"stopped\"\n    );\n    this.parent.api.saveMessages([executionMessage]);\n  };\n\n  // eslint-disable-next-line @typescript-eslint/require-await\n  conclude = async () => void 0;\n\n  next = () => undefined;\n\n  onError = (e: unknown): boolean => {\n    this.parent.messageService.sendErrorMessage(e);\n    return true;\n  };\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-work/create-task-work.ts",
    "content": "import type AgentWork from \"./agent-work\";\nimport type { Task } from \"../../../types/task\";\nimport type AutonomousAgent from \"../autonomous-agent\";\n\nexport default class CreateTaskWork implements AgentWork {\n  taskValues: string[] = [];\n\n  constructor(private parent: AutonomousAgent, private task: Task) {}\n\n  run = async () => {\n    this.taskValues = await this.parent.api.getAdditionalTasks(\n      {\n        current: this.task.value,\n        remaining: this.parent.model.getRemainingTasks().map((task) => task.value),\n        completed: this.parent.model.getCompletedTasks().map((task) => task.value),\n      },\n      this.task.result || \"\"\n    );\n  };\n\n  conclude = async () => {\n    const TIMEOUT_LONG = 1000;\n    this.parent.api.saveMessages(await this.parent.createTaskMessages(this.taskValues));\n    await new Promise((r) => setTimeout(r, TIMEOUT_LONG));\n  };\n\n  next = () => undefined;\n\n  // Ignore errors and simply avoid creating more tasks\n  onError = (): boolean => false;\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-work/execute-task-work.ts",
    "content": "import { v1 } from \"uuid\";\n\nimport type AgentWork from \"./agent-work\";\nimport type { Message } from \"../../../types/message\";\nimport type { Task } from \"../../../types/task\";\nimport { toApiModelSettings } from \"../../../utils/interfaces\";\nimport { streamText } from \"../../stream-utils\";\nimport type { Analysis } from \"../analysis\";\nimport type AutonomousAgent from \"../autonomous-agent\";\n\nexport default class ExecuteTaskWork implements AgentWork {\n  result = \"\";\n\n  constructor(private parent: AutonomousAgent, private task: Task, private analysis: Analysis) {}\n\n  run = async () => {\n    const executionMessage: Message = {\n      ...this.task,\n      id: v1(),\n      status: \"completed\",\n      info: \"Loading...\",\n    };\n    this.parent.messageService.sendMessage({ ...executionMessage, status: \"completed\" });\n\n    // TODO: this should be moved to the api layer\n    await streamText(\n      \"/api/agent/execute\",\n      {\n        run_id: this.parent.api.runId,\n        goal: this.parent.model.getGoal(),\n        task: this.task.value,\n        analysis: this.analysis,\n        model_settings: toApiModelSettings(this.parent.modelSettings, this.parent.session),\n      },\n      this.parent.api.props.session?.accessToken || \"\",\n      () => {\n        executionMessage.info = \"\";\n      },\n      (text) => {\n        executionMessage.info += text;\n        this.task = this.parent.model.updateTaskResult(this.task, executionMessage.info || \"\");\n        this.parent.messageService.updateMessage(executionMessage);\n      },\n      () => this.parent.model.getLifecycle() === \"stopped\"\n    );\n    this.result = executionMessage.info || \"\";\n    this.parent.api.saveMessages([executionMessage]);\n    this.task = this.parent.model.updateTaskStatus(this.task, \"completed\");\n  };\n\n  // eslint-disable-next-line @typescript-eslint/require-await\n  conclude = async () => void 0;\n\n  next = () => undefined;\n\n  onError = (e: unknown): boolean => {\n    this.parent.messageService.sendErrorMessage(e);\n    return true;\n  };\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-work/start-task-work.ts",
    "content": "import type AgentWork from \"./agent-work\";\nimport type AutonomousAgent from \"../autonomous-agent\";\n\nexport default class StartGoalWork implements AgentWork {\n  tasksValues: string[] = [];\n\n  constructor(private parent: AutonomousAgent) {}\n\n  run = async () => {\n    const goalMessage = this.parent.messageService.sendGoalMessage(this.parent.model.getGoal());\n    this.tasksValues = await this.parent.api.getInitialTasks();\n    await this.parent.api.createAgent();\n    this.parent.api.saveMessages([goalMessage]);\n  };\n\n  conclude = async () => {\n    const messages = await this.parent.createTaskMessages(this.tasksValues);\n    this.parent.api.saveMessages(messages);\n  };\n\n  onError = (e: unknown): boolean => {\n    this.parent.messageService.sendErrorMessage(e);\n    return true;\n  };\n\n  next = () => undefined;\n}\n"
  },
  {
    "path": "next/src/services/agent/agent-work/summarize-work.ts",
    "content": "import { v1 } from \"uuid\";\n\nimport type AgentWork from \"./agent-work\";\nimport type { Message } from \"../../../types/message\";\nimport { toApiModelSettings } from \"../../../utils/interfaces\";\nimport { streamText } from \"../../stream-utils\";\nimport type AutonomousAgent from \"../autonomous-agent\";\n\nexport default class SummarizeWork implements AgentWork {\n  constructor(private parent: AutonomousAgent) {}\n\n  run = async () => {\n    const executionMessage: Message = {\n      type: \"task\",\n      status: \"completed\",\n      value: `Summarizing ${this.parent.model.getGoal()}`,\n      id: v1(),\n      info: \"Loading...\",\n    };\n    this.parent.messageService.sendMessage({ ...executionMessage });\n\n    // TODO: this should be moved to the api layer\n    await streamText(\n      \"/api/agent/summarize\",\n      {\n        run_id: this.parent.api.runId,\n        goal: this.parent.model.getGoal(),\n        model_settings: toApiModelSettings(this.parent.modelSettings, this.parent.session),\n        results: this.parent.model\n          .getCompletedTasks()\n          .filter((task) => task.result && task.result !== \"\")\n          .map((task) => task.result || \"\"),\n      },\n      this.parent.api.props.session?.accessToken || \"\",\n      () => {\n        executionMessage.info = \"\";\n      },\n      (text) => {\n        executionMessage.info += text;\n        this.parent.messageService.updateMessage(executionMessage);\n      },\n      () => this.parent.model.getLifecycle() === \"stopped\"\n    );\n    this.parent.api.saveMessages([executionMessage]);\n  };\n\n  // eslint-disable-next-line @typescript-eslint/require-await\n  conclude = async () => void 0;\n\n  next = () => undefined;\n\n  onError = (e: unknown): boolean => {\n    this.parent.messageService.sendErrorMessage(e);\n    return true;\n  };\n}\n"
  },
  {
    "path": "next/src/services/agent/analysis.ts",
    "content": "export type Analysis = {\n  reasoning: string;\n  action: \"reason\" | \"search\" | \"wikipedia\" | \"image\" | \"code\";\n  arg: string;\n};\n"
  },
  {
    "path": "next/src/services/agent/autonomous-agent.ts",
    "content": "import type { Session } from \"next-auth\";\n\nimport type { AgentApi } from \"./agent-api\";\nimport type { AgentRunModel } from \"./agent-run-model\";\nimport type AgentWork from \"./agent-work/agent-work\";\nimport AnalyzeTaskWork from \"./agent-work/analyze-task-work\";\nimport ChatWork from \"./agent-work/chat-work\";\nimport StartGoalWork from \"./agent-work/start-task-work\";\nimport SummarizeWork from \"./agent-work/summarize-work\";\nimport type { MessageService } from \"./message-service\";\nimport { useAgentStore } from \"../../stores\";\nimport type { ModelSettings } from \"../../types\";\nimport { isRetryableError } from \"../../types/errors\";\nimport type { Message } from \"../../types/message\";\nimport { withRetries } from \"../api-utils\";\n\nclass AutonomousAgent {\n  model: AgentRunModel;\n  modelSettings: ModelSettings;\n  session?: Session;\n  messageService: MessageService;\n  api: AgentApi;\n\n  private readonly workLog: AgentWork[];\n  private lastConclusion?: () => Promise<void>;\n\n  constructor(\n    model: AgentRunModel,\n    messageService: MessageService,\n    modelSettings: ModelSettings,\n    api: AgentApi,\n    session?: Session\n  ) {\n    this.model = model;\n    this.messageService = messageService;\n    this.modelSettings = modelSettings;\n    this.session = session;\n    this.api = api;\n    this.workLog = [new StartGoalWork(this)];\n  }\n\n  async run() {\n    this.model.setLifecycle(\"running\");\n\n    // If an agent is paused during execution, we need to play work conclusions\n    if (this.lastConclusion) {\n      await this.lastConclusion();\n      this.lastConclusion = undefined;\n    }\n\n    this.addTasksIfWorklogEmpty();\n    while (this.workLog[0]) {\n      // No longer running, dip\n      if (this.model.getLifecycle() === \"pausing\") this.model.setLifecycle(\"paused\");\n      if (this.model.getLifecycle() !== \"running\") return;\n\n      // Get and run the next work item\n      const work = this.workLog[0];\n      await this.runWork(work, () => this.model.getLifecycle() === \"stopped\");\n\n      this.workLog.shift();\n      if (this.model.getLifecycle() !== \"running\") {\n        this.lastConclusion = () => work.conclude();\n      } else {\n        await work.conclude();\n      }\n\n      // Add next thing if available\n      const next = work.next();\n      if (next) {\n        this.workLog.push(next);\n      }\n\n      this.addTasksIfWorklogEmpty();\n    }\n\n    if (this.model.getLifecycle() === \"pausing\") this.model.setLifecycle(\"paused\");\n    if (this.model.getLifecycle() !== \"running\") return;\n\n    // Done with everything in the log and all queued tasks\n    this.stopAgent();\n  }\n\n  /*\n   * Runs a provided work object with error handling and retries\n   */\n  private async runWork(work: AgentWork, shouldStop: () => boolean = () => false) {\n    const RETRY_TIMEOUT = 2000;\n\n    await withRetries(\n      async () => {\n        if (shouldStop()) return;\n        await work.run();\n      },\n      async (e) => {\n        const shouldRetry = work.onError?.(e) || true;\n\n        if (!isRetryableError(e)) {\n          this.stopAgent();\n          return false;\n        }\n\n        if (shouldRetry) {\n          // Wait a bit before retrying\n          useAgentStore.getState().setIsAgentThinking(true);\n          await new Promise((r) => setTimeout(r, RETRY_TIMEOUT));\n        }\n\n        return shouldRetry;\n      }\n    );\n    useAgentStore.getState().setIsAgentThinking(false);\n  }\n\n  addTasksIfWorklogEmpty = () => {\n    if (this.workLog.length > 0) return;\n\n    // No work items, check if we still have tasks\n    const currentTask = this.model.getCurrentTask();\n    if (currentTask) {\n      this.workLog.push(new AnalyzeTaskWork(this, currentTask));\n    }\n  };\n\n  pauseAgent() {\n    this.model.setLifecycle(\"pausing\");\n  }\n\n  stopAgent() {\n    this.model.setLifecycle(\"stopped\");\n    return;\n  }\n\n  async summarize() {\n    this.model.setLifecycle(\"running\");\n    const summarizeWork = new SummarizeWork(this);\n    await this.runWork(summarizeWork);\n    await summarizeWork.conclude();\n    this.model.setLifecycle(\"stopped\");\n  }\n\n  async chat(message: string) {\n    if (this.model.getLifecycle() == \"running\") this.pauseAgent();\n    let paused = false;\n    if (this.model.getLifecycle() == \"stopped\") {\n      paused = true;\n      this.model.setLifecycle(\"pausing\");\n    }\n    const chatWork = new ChatWork(this, message);\n    await this.runWork(chatWork);\n    await chatWork.conclude();\n    if (paused) {\n      this.model.setLifecycle(\"stopped\");\n    }\n  }\n\n  async createTaskMessages(tasks: string[]) {\n    const TIMOUT_SHORT = 150;\n    const messages: Message[] = [];\n\n    for (const value of tasks) {\n      messages.push(this.messageService.startTask(value));\n      this.model.addTask(value);\n      await new Promise((r) => setTimeout(r, TIMOUT_SHORT));\n    }\n\n    return messages;\n  }\n}\n\nexport default AutonomousAgent;\n"
  },
  {
    "path": "next/src/services/agent/message-service.ts",
    "content": "import axios from \"axios\";\nimport { v1 } from \"uuid\";\n\nimport type { Analysis } from \"./analysis\";\nimport { useMessageStore } from \"../../stores\";\nimport { isPlatformError, isValueError } from \"../../types/errors\";\nimport type { Message } from \"../../types/message\";\nimport { MESSAGE_TYPE_GOAL, MESSAGE_TYPE_SYSTEM } from \"../../types/message\";\nimport type { Task } from \"../../types/task\";\nimport { translate } from \"../../utils/translations\";\n\nexport class MessageService {\n  private readonly renderMessage: (message: Message) => void;\n\n  constructor(renderMessage: (message: Message) => void) {\n    this.renderMessage = renderMessage;\n  }\n\n  sendMessage = (message: Message): Message => {\n    this.renderMessage({ ...message });\n    return message;\n  };\n\n  updateMessage = (message: Message): Message => {\n    useMessageStore.getState().updateMessage(message);\n    return message;\n  };\n\n  skipTaskMessage = (task: Task) =>\n    this.sendMessage({\n      type: \"system\",\n      value: `🥺 Skipping task: ${task.value}`,\n    });\n\n  startTask = (task: string) =>\n    this.sendMessage({\n      taskId: v1().toString(),\n      value: task,\n      status: \"started\",\n      type: \"task\",\n    });\n\n  sendGoalMessage = (goal: string) => this.sendMessage({ type: MESSAGE_TYPE_GOAL, value: goal });\n\n  sendAnalysisMessage = (analysis: Analysis) => {\n    let message = \"⏰ Generating response...\";\n    if (analysis.action == \"search\") {\n      message = `🔍 Searching the web for \"${analysis.arg}\"...`;\n    }\n    if (analysis.action == \"wikipedia\") {\n      message = `🌐 Searching Wikipedia for \"${analysis.arg}\"...`;\n    }\n    if (analysis.action == \"image\") {\n      message = `🎨 Generating an image with prompt: \"${analysis.arg}\"...`;\n    }\n    if (analysis.action == \"code\") {\n      message = `💻 Writing code...`;\n    }\n\n    return this.sendMessage({\n      type: MESSAGE_TYPE_SYSTEM,\n      value: message,\n    });\n  };\n\n  sendErrorMessage = (e: unknown) => {\n    let message = \"An unknown error occurred. Please try again later.\";\n    if (typeof e == \"string\") message = e;\n    else if (axios.isAxiosError(e) && e.message == \"Network Error\") {\n      message = \"Error attempting to connect to the server.\";\n    } else if (axios.isAxiosError(e)) {\n      const data = (e.response?.data as object) || {};\n      switch (e.response?.status) {\n        case 409:\n          message = isPlatformError(data)\n            ? data.detail\n            : \"An Unknown Error Occurred, Please Try Again!\";\n          break;\n        case 422:\n          if (isValueError(data)) {\n            const detailMessages = data.detail.map((detail) => detail.msg);\n            message = detailMessages.join(\"\\n\");\n          }\n          break;\n        case 429:\n          if (e.response?.data && \"detail\" in e.response.data) {\n            const { detail } = e.response.data as { detail?: string };\n            message = detail || \"Too many requests. Please try again later.\";\n          } else {\n            message = \"Too many requests. Please try again later.\";\n          }\n          break;\n        case 403:\n          message = \"Authentication Error. Please make sure you are logged in.\";\n          break;\n        case 404:\n          message = \"ERROR_OPENAI_API_KEY_NO_GPT4\";\n          break;\n        default:\n          message = \"ERROR_ACCESSING_OPENAI_API_KEY\";\n          break;\n      }\n    } else if (e instanceof Error) message = e.message;\n\n    return this.sendMessage({ type: \"error\", value: translate(message, \"errors\") });\n  };\n}\n"
  },
  {
    "path": "next/src/services/api/org.ts",
    "content": "import { z } from \"zod\";\n\nimport { get } from \"../fetch-utils\";\n\nconst OrganizationUsersSchema = z.object({\n  id: z.string(),\n  name: z.string(),\n  users: z.array(\n    z.object({\n      id: z.string(),\n      role: z.string(),\n      user: z.object({\n        id: z.string(),\n        name: z.string(),\n        email: z.string(),\n      }),\n    })\n  ),\n});\n\nexport class OrganizationApi {\n  readonly accessToken?: string;\n\n  constructor(accessToken?: string) {\n    this.accessToken = accessToken;\n  }\n\n  async get(name: string) {\n    return await get(`/api/auth/organization/${name}`, OrganizationUsersSchema, this.accessToken);\n  }\n}\n"
  },
  {
    "path": "next/src/services/api-utils.ts",
    "content": "import axios from \"axios\";\nimport type { Session } from \"next-auth\";\n\nimport { env } from \"../env/client.mjs\";\n\nexport const post = async <T>(url: string, body: unknown, session?: Session) => {\n  const headers = getHeaders(session);\n  url = getUrl(url);\n\n  return (\n    await axios.post(url, body, {\n      headers,\n    })\n  ).data as T;\n};\n\nexport const get = async <T>(url: string, session?: Session) => {\n  const headers = getHeaders(session);\n  url = getUrl(url);\n\n  return (\n    await axios.get(url, {\n      headers,\n    })\n  ).data as T;\n};\n\nexport const delete_ = async <T>(url: string, accessToken?: string) => {\n  const headers: Record<string, string> = {};\n  if (accessToken) headers.Authorization = `Bearer ${accessToken}`;\n\n  url = getUrl(url);\n\n  return (\n    await axios.delete(url, {\n      headers,\n    })\n  ).data as T;\n};\n\nexport function getHeaders(session?: Session) {\n  const headers: Record<string, string> = {};\n  if (session?.accessToken) {\n    headers.Authorization = `Bearer ${session.accessToken}`;\n  }\n\n  return headers;\n}\n\nfunction getUrl(url: string) {\n  return env.NEXT_PUBLIC_BACKEND_URL + url;\n}\nexport async function withRetries(\n  fn: () => Promise<void>,\n  onError: (error: unknown) => Promise<boolean>, // Function to handle the error and return whether to continue retrying\n  retries = 3\n): Promise<void> {\n  for (let i = 0; i < retries + 1; i++) {\n    try {\n      return await fn();\n    } catch (error) {\n      if (!(await onError(error))) return;\n    }\n  }\n}\n"
  },
  {
    "path": "next/src/services/fetch-utils.ts",
    "content": "import type { z } from \"zod\";\n\nimport { env } from \"../env/client.mjs\";\n\nfunction getHeaders(accessToken: string | undefined, organizationId: string | undefined) {\n  return {\n    \"Content-Type\": \"application/json\",\n    Authorization: `Bearer ${accessToken || \"\"}`,\n    ...(organizationId ? { \"X-Organization-Id\": organizationId } : {}),\n  };\n}\n\nexport const get = async <T extends z.ZodTypeAny>(\n  path: string,\n  schema: T,\n  accessToken?: string,\n  organizationId?: string\n): Promise<z.infer<T>> => {\n  const response = await fetch(`${env.NEXT_PUBLIC_BACKEND_URL}${path}`, {\n    method: \"GET\",\n    headers: getHeaders(accessToken, organizationId),\n  });\n\n  if (!response.ok) {\n    throw new Error(\"Request failed\");\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return schema.parse(await response.json());\n};\n\nexport const post = async <T extends z.ZodTypeAny>(\n  path: string,\n  schema: T,\n  body: unknown,\n  accessToken?: string,\n  organizationId?: string\n): Promise<z.infer<T>> => {\n  const response = await fetch(`${env.NEXT_PUBLIC_BACKEND_URL}${path}`, {\n    body: JSON.stringify(body),\n    method: \"POST\",\n    headers: getHeaders(accessToken, organizationId),\n  });\n\n  if (!response.ok) {\n    throw new Error(\"Request failed\");\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return schema.parse(await response.json());\n};\n\nexport const put = async <T extends z.ZodTypeAny>(\n  path: string,\n  schema: T,\n  body: unknown,\n  accessToken?: string,\n  organizationId?: string\n): Promise<z.infer<T>> => {\n  const response = await fetch(`${env.NEXT_PUBLIC_BACKEND_URL}${path}`, {\n    body: JSON.stringify(body),\n    method: \"PUT\",\n    headers: getHeaders(accessToken, organizationId),\n  });\n\n  if (!response.ok) {\n    throw new Error(response.statusText);\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return schema.parse(await response.json());\n};\n\nexport const delete_ = async <T extends z.ZodTypeAny>(\n  path: string,\n  schema: T,\n  body: unknown,\n  accessToken?: string,\n  organizationId?: string\n): Promise<z.infer<T>> => {\n  const response = await fetch(`${env.NEXT_PUBLIC_BACKEND_URL}${path}`, {\n    body: JSON.stringify(body),\n    method: \"DELETE\",\n    headers: getHeaders(accessToken, organizationId),\n  });\n\n  if (!response.ok) {\n    throw new Error(response.statusText);\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return schema.parse(await response.json());\n};\n"
  },
  {
    "path": "next/src/services/stream-utils.ts",
    "content": "import { env } from \"../env/client.mjs\";\n\ntype TextStream = ReadableStreamDefaultReader<Uint8Array>;\n\nconst fetchData = async <T>(\n  url: string,\n  body: T,\n  accessToken: string\n): Promise<TextStream | undefined> => {\n  url = env.NEXT_PUBLIC_BACKEND_URL + url;\n\n  const response = await fetch(url, {\n    method: \"POST\",\n    cache: \"no-cache\",\n    keepalive: true,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      Accept: \"text/event-stream\",\n      Authorization: `Bearer ${accessToken}`,\n    },\n    body: JSON.stringify(body),\n  });\n\n  if (response.status === 409) {\n    const error = (await response.json()) as { error: string; detail: string };\n    throw new Error(error.detail);\n  }\n\n  return response.body?.getReader();\n};\n\nasync function readStream(reader: TextStream): Promise<string | null> {\n  const result = await reader.read();\n  return result.done ? null : new TextDecoder().decode(result.value);\n}\n\nasync function processStream(\n  reader: TextStream,\n  onStart: () => void,\n  onText: (text: string) => void,\n  shouldClose: () => boolean\n): Promise<void> {\n  onStart();\n  while (true) {\n    if (shouldClose()) {\n      await reader.cancel();\n      return;\n    }\n\n    const text = await readStream(reader);\n    if (text === null) break;\n    onText(text);\n  }\n}\n\nexport const streamText = async <T>(\n  url: string,\n  body: T,\n  accessToken: string,\n  onStart: () => void,\n  onText: (text: string) => void,\n  shouldClose: () => boolean // Event handler to close connection early\n) => {\n  const reader = await fetchData(url, body, accessToken);\n  if (!reader) {\n    console.error(\"Reader is undefined!\");\n    return;\n  }\n\n  await processStream(reader, onStart, onText, shouldClose);\n};\n"
  },
  {
    "path": "next/src/services/workflow/oauthApi.ts",
    "content": "import type { Session } from \"next-auth\";\nimport { z } from \"zod\";\n\nimport { env } from \"../../env/client.mjs\";\nimport { get } from \"../fetch-utils\";\n\nexport default class OauthApi {\n  readonly accessToken?: string;\n  readonly organizationId?: string;\n\n  constructor(accessToken?: string, organizationId?: string) {\n    this.accessToken = accessToken;\n    this.organizationId = organizationId;\n  }\n\n  static fromSession(session: Session | null) {\n    return new OauthApi(session?.accessToken, session?.user?.organizations[0]?.id);\n  }\n\n  async install(provider: string, redirectUri?: string) {\n    const url = `${env.NEXT_PUBLIC_VERCEL_URL}${redirectUri || \"\"}`;\n\n    return await get(\n      `/api/auth/${provider}?redirect=${encodeURIComponent(url)}`,\n      z.string().url(),\n      this.accessToken,\n      this.organizationId\n    );\n  }\n\n  async uninstall(provider: string) {\n    return await get(\n      `/api/auth/${provider}/uninstall`,\n      z.object({\n        success: z.boolean(),\n      }),\n      this.accessToken,\n      this.organizationId\n    );\n  }\n  // TODO: decouple this\n  async get_info(provider: string) {\n    return await get(\n      `/api/auth/${provider}/info`,\n      z\n        .object({\n          name: z.string(),\n          id: z.string(),\n        })\n        .array(),\n      this.accessToken,\n      this.organizationId\n    );\n  }\n\n  async get_info_sid() {\n    return await get(\n      `/api/auth/sid/info`,\n      z.object({\n        connected: z.boolean(),\n      }),\n      this.accessToken,\n      this.organizationId\n    );\n  }\n}\n"
  },
  {
    "path": "next/src/stores/agentInputStore.ts",
    "content": "import type { StateCreator } from \"zustand\";\nimport { create } from \"zustand\";\n\nimport { createSelectors } from \"./helpers\";\n\nconst resetters: (() => void)[] = [];\n\ninterface AgentInputSlice {\n  nameInput: string;\n  goalInput: string;\n  setNameInput: (nameInput: string) => void;\n  setGoalInput: (goalInput: string) => void;\n  resetInputs: () => void;\n}\n\nconst initialInputState = {\n  nameInput: \"\",\n  goalInput: \"\",\n};\n\nconst createAgentInputSlice: StateCreator<AgentInputSlice> = (set) => {\n  resetters.push(() => set(initialInputState));\n  return {\n    ...initialInputState,\n    setNameInput: (nameInput: string) => {\n      set(() => ({ nameInput }));\n    },\n    setGoalInput: (goalInput: string) => {\n      set(() => ({ goalInput }));\n    },\n    resetInputs: () => {\n      set(initialInputState);\n    },\n  };\n};\nexport const useAgentInputStore = createSelectors(\n  create<AgentInputSlice>()((...a) => ({\n    ...createAgentInputSlice(...a),\n  }))\n);\n"
  },
  {
    "path": "next/src/stores/agentStore.ts",
    "content": "import type { StateCreator } from \"zustand\";\nimport { create } from \"zustand\";\nimport { createJSONStorage, persist } from \"zustand/middleware\";\n\nimport { createSelectors } from \"./helpers\";\nimport type { ActiveTool } from \"../hooks/useTools\";\nimport type { AgentLifecycle } from \"../services/agent/agent-run-model\";\nimport type AutonomousAgent from \"../services/agent/autonomous-agent\";\n\ninterface AgentSlice {\n  agent: AutonomousAgent | null;\n  lifecycle: AgentLifecycle;\n  setLifecycle: (AgentLifecycle) => void;\n  summarized: boolean;\n  setSummarized: (boolean) => void;\n  isAgentThinking: boolean;\n  setIsAgentThinking: (isThinking: boolean) => void;\n  setAgent: (newAgent: AutonomousAgent | null) => void;\n}\n\nconst initialAgentState = {\n  agent: null,\n  lifecycle: \"offline\" as const,\n  summarized: false,\n  isAgentThinking: false,\n  isAgentPaused: undefined,\n};\n\ninterface ToolsSlice {\n  tools: Omit<ActiveTool, \"active\">[];\n  setTools: (tools: ActiveTool[]) => void;\n}\n\nconst resetters: (() => void)[] = [];\n\nconst createAgentSlice: StateCreator<AgentSlice> = (set, get) => {\n  resetters.push(() => set(initialAgentState));\n  return {\n    ...initialAgentState,\n    setLifecycle: (lifecycle: AgentLifecycle) => {\n      set(() => ({\n        lifecycle: lifecycle,\n      }));\n    },\n    setSummarized: (summarized: boolean) => {\n      set(() => ({\n        summarized: summarized,\n      }));\n    },\n    setIsAgentThinking: (isThinking: boolean) => {\n      set(() => ({\n        isAgentThinking: isThinking,\n      }));\n    },\n    setAgent: (newAgent) => {\n      set(() => ({\n        agent: newAgent,\n      }));\n\n      if (get().agent === null) {\n        resetters.forEach((resetter) => resetter());\n      }\n    },\n  };\n};\n\nconst createToolsSlice: StateCreator<ToolsSlice> = (set) => {\n  return {\n    tools: [],\n    setTools: (tools) => {\n      set(() => ({\n        tools: tools,\n      }));\n    },\n  };\n};\n\nexport const useAgentStore = createSelectors(\n  create<AgentSlice & ToolsSlice>()(\n    persist(\n      (...a) => ({\n        ...createAgentSlice(...a),\n        ...createToolsSlice(...a),\n      }),\n      {\n        name: \"agent-storage-v2\",\n        storage: createJSONStorage(() => localStorage),\n        partialize: (state) => ({\n          tools: state.tools,\n        }),\n      }\n    )\n  )\n);\n\nexport const resetAllAgentSlices = () => resetters.forEach((resetter) => resetter());\n"
  },
  {
    "path": "next/src/stores/configStore.ts",
    "content": "import type { StateCreator } from \"zustand\";\nimport { create } from \"zustand\";\nimport { createJSONStorage, persist } from \"zustand/middleware\";\n\nimport { createSelectors } from \"./helpers\";\n\ninterface Layout {\n  showRightSidebar: boolean;\n  showLogSidebar: boolean;\n}\n\ninterface LayoutSlice {\n  layout: Layout;\n  setLayout: (layout: Partial<Layout>) => void;\n}\n\ninterface OrganizationRole {\n  id: string;\n  name: string;\n  role: string;\n}\n\ninterface AuthSlice {\n  organization: OrganizationRole | undefined;\n  setOrganization: (orgRole: OrganizationRole | undefined) => void;\n}\n\nconst createLayoutSlice: StateCreator<LayoutSlice> = (set, get) => {\n  return {\n    ...{\n      layout: {\n        showRightSidebar: false,\n        showLogSidebar: false,\n      },\n    },\n    setLayout: (layout: Partial<Layout>) => {\n      if (layout.showLogSidebar) layout.showRightSidebar = false;\n      if (layout.showRightSidebar) layout.showLogSidebar = false;\n\n      set((prev) => ({\n        layout: {\n          ...prev.layout,\n          ...layout,\n        },\n      }));\n    },\n  };\n};\n\nconst createAuthSlice: StateCreator<AuthSlice> = (set, get) => {\n  return {\n    ...{ organization: undefined },\n    setOrganization: (orgRole: OrganizationRole | undefined) => {\n      set(() => ({\n        organization: orgRole,\n      }));\n    },\n  };\n};\n\nexport const useConfigStore = createSelectors(\n  create<LayoutSlice & AuthSlice>()(\n    persist(\n      (...a) => ({\n        ...createLayoutSlice(...a),\n        ...createAuthSlice(...a),\n      }),\n      {\n        name: \"reworkd-config-2\",\n        version: 1,\n        storage: createJSONStorage(() => localStorage),\n      }\n    )\n  )\n);\n"
  },
  {
    "path": "next/src/stores/helpers.ts",
    "content": "import type { StoreApi, UseBoundStore } from \"zustand\";\n\n/*\n  Automatically creates selectors for each states in store.\n  Zustand recommends using selectors for calling state/actions for optimal performance\n  Reference: https://docs.pmnd.rs/zustand/guides/auto-generating-selectors\n*/\ntype WithSelectors<S> = S extends { getState: () => infer T }\n  ? S & { use: { [K in keyof T]: () => T[K] } }\n  : never;\n\nexport const createSelectors = <S extends UseBoundStore<StoreApi<object>>>(\n  _store: S\n) => {\n  const store = _store as WithSelectors<typeof _store>;\n  store.use = {};\n  for (const k of Object.keys(store.getState())) {\n    (store.use)[k] = () => store((s) => s[k as keyof typeof s]);\n  }\n\n  return store;\n};\n"
  },
  {
    "path": "next/src/stores/index.ts",
    "content": "export * from \"./messageStore\";\nexport * from \"./agentStore\";\nexport * from \"./modelSettingsStore\";\n"
  },
  {
    "path": "next/src/stores/messageStore.ts",
    "content": "import type { StateCreator } from \"zustand\";\nimport { create } from \"zustand\";\n\nimport { createSelectors } from \"./helpers\";\nimport type { Message } from \"../types/message\";\n\nconst resetters: (() => void)[] = [];\n\nconst initialMessageState = {\n  messages: [],\n};\n\ninterface MessageSlice {\n  messages: Message[];\n  addMessage: (newMessage: Message) => void;\n  updateMessage: (newMessage: Message) => void;\n}\n\nconst createMessageSlice: StateCreator<MessageSlice, [], [], MessageSlice> = (set) => {\n  resetters.push(() => set(initialMessageState));\n  return {\n    ...initialMessageState,\n    addMessage: (newMessage) => {\n      set((state) => ({\n        ...state,\n        messages: [...state.messages, { ...newMessage }],\n      }));\n    },\n\n    updateMessage: (newMessage) => {\n      set((state) => {\n        const oldMessage = state.messages.find((message) => message.id === newMessage.id);\n        if (oldMessage) {\n          const updatedMessages = state.messages.map((message) =>\n            message.id === oldMessage.id ? newMessage : message\n          );\n          return {\n            ...state,\n            messages: updatedMessages,\n          };\n        }\n        return state;\n      });\n    },\n  };\n};\n\nexport const useMessageStore = createSelectors(\n  create<MessageSlice>()((...a) => ({\n    ...createMessageSlice(...a),\n  }))\n);\n\nexport const resetAllMessageSlices = () => resetters.forEach((resetter) => resetter());\n"
  },
  {
    "path": "next/src/stores/modelSettingsStore.ts",
    "content": "import type { StateCreator } from \"zustand\";\nimport { create } from \"zustand\";\nimport { createJSONStorage, persist } from \"zustand/middleware\";\n\nimport { createSelectors } from \"./helpers\";\nimport type { ModelSettings } from \"../types\";\nimport { getDefaultModelSettings } from \"../utils/constants\";\n\nconst resetters: (() => void)[] = [];\n\ninterface ModelSettingsSlice {\n  modelSettings: ModelSettings;\n  updateSettings: <Key extends keyof ModelSettings>(key: Key, value: ModelSettings[Key]) => void;\n}\n\nconst initialModelSettingsState = {\n  modelSettings: getDefaultModelSettings(),\n};\n\nconst createModelSettingsSlice: StateCreator<ModelSettingsSlice> = (set) => {\n  resetters.push(() => set(initialModelSettingsState));\n\n  return {\n    ...initialModelSettingsState,\n    updateSettings: <Key extends keyof ModelSettings>(key: Key, value: ModelSettings[Key]) => {\n      set((state) => ({\n        modelSettings: { ...state.modelSettings, [key]: value },\n      }));\n    },\n  };\n};\n\nexport const useModelSettingsStore = createSelectors(\n  create<ModelSettingsSlice>()(\n    persist(\n      (...a) => ({\n        ...createModelSettingsSlice(...a),\n      }),\n      {\n        name: \"agentgpt-settings-storage-v2\",\n        storage: createJSONStorage(() => localStorage),\n        partialize: (state) => ({\n          modelSettings: {\n            ...state.modelSettings,\n            customModelName: \"gpt-3.5-turbo\",\n            maxTokens: Math.min(state.modelSettings.maxTokens, 4000),\n          },\n        }),\n      }\n    )\n  )\n);\n\nexport const resetSettings = () => resetters.forEach((resetter) => resetter());\n"
  },
  {
    "path": "next/src/stores/taskStore.ts",
    "content": "import type { StateCreator } from \"zustand\";\nimport { create } from \"zustand\";\n\nimport { createSelectors } from \"./helpers\";\nimport type { Message } from \"../types/message\";\nimport type { Task } from \"../types/task\";\nimport { isTask, TASK_STATUS_COMPLETED, TASK_STATUS_EXECUTING } from \"../types/task\";\n\nexport const isExistingTask = (message: Message): boolean =>\n  isTask(message) &&\n  (message.status === TASK_STATUS_EXECUTING || message.status === TASK_STATUS_COMPLETED);\n\nconst resetters: (() => void)[] = [];\n\nconst initialTaskState = {\n  tasks: [],\n};\n\nexport interface TaskSlice {\n  tasks: Task[];\n  addTask: (newTask: Task) => void;\n  updateTask: (updatedTask: Task) => void;\n  deleteTask: (taskId: string) => void;\n}\n\nexport const createTaskSlice: StateCreator<TaskSlice, [], [], TaskSlice> = (set) => {\n  resetters.push(() => set(initialTaskState));\n\n  return {\n    ...initialTaskState,\n    addTask: (newTask) => {\n      set((state) => ({\n        ...state,\n        tasks: [...state.tasks, { ...newTask }],\n      }));\n    },\n    updateTask: (updatedTask) => {\n      set((state) => {\n        const updatedTasks = state.tasks.map((task) => {\n          if (task.id === updatedTask.id && task.taskId == updatedTask.taskId) {\n            return {\n              ...updatedTask,\n            };\n          }\n          return task;\n        });\n\n        return {\n          ...state,\n          tasks: updatedTasks,\n        };\n      });\n    },\n    deleteTask: (taskId) => {\n      set((state) => ({\n        ...state,\n        tasks: state.tasks.filter((task) => task.taskId !== taskId),\n      }));\n    },\n  };\n};\n\nexport const useTaskStore = createSelectors(\n  create<TaskSlice>()((...a) => ({\n    ...createTaskSlice(...a),\n  }))\n);\n\nexport const resetAllTaskSlices = () => resetters.forEach((resetter) => resetter());\n"
  },
  {
    "path": "next/src/styles/globals.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\nbody {\n    background: black;\n}\n\n.resend-font-effect-hero {\n    /* #Resend */\n    -webkit-text-fill-color: transparent;\n    text-shadow: -1px -1px 0 hsla(0, 0%, 100%, .15), 1px 1px 0 rgba(0, 0, 0, .1);\n}\n\n.border-gradient {\n    /* Mark as important to override react flow styling */\n    background: linear-gradient(black, black) padding-box,\n    linear-gradient(to bottom, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0.15)) border-box !important;\n    border: 1px solid transparent !important;\n}\n\n.radial-background-1 {\n    background-image: radial-gradient(at 170% 0%, rgb(49, 46, 129) 0, transparent 69%), radial-gradient(at 0% -30%, rgb(21, 94, 117) 0, transparent 50%);\n}\n\n.after-gradient::after {\n    background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .8) 47.92%, rgba(255, 255, 255, 0));\n}\n\n.lower-gradient {\n    background-image: linear-gradient(\n            to top,\n            rgba(255, 255, 255, 0.03),\n            rgba(255, 255, 255, 0)\n    );\n    height: 20vh;\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n}\n\n.fading-hr {\n    position: relative;\n    height: 1px;\n    background: linear-gradient(\n            to right,\n            transparent,\n            hsla(0, 0%, 0%, 0.1),\n            hsla(0, 0%, 0%, 0.2),\n            hsla(0, 0%, 0%, 0.2),\n            hsla(20, 0%, 0%, 0.1),\n            transparent\n    );\n}\n\n.fading-hr-dark {\n    position: relative;\n    height: 1px;\n    background: linear-gradient(\n            to right,\n            transparent,\n            rgba(255, 255, 255, 0.1),\n            rgba(255, 255, 255, 0.2),\n            rgba(255, 255, 255, 0.2),\n            rgba(255, 255, 255, 0.1),\n            transparent\n    );\n}\n\n/* Used for code / table formatting within messages */\npre {\n    @apply overflow-auto rounded-lg;\n}\n\n.window-heights {\n    @apply h-[14em] overflow-y-auto overflow-x-hidden sm-h:h-[17em] md-h:h-[22em] lg-h:h-[30em];\n}\n\n.link {\n    @apply cursor-pointer text-sky-500 underline hover:text-sky-300;\n}\n\ntable {\n    @apply w-full rounded-lg text-white;\n    background-color: #0d1117;\n}\n\nth,\ntd {\n    @apply rounded-lg border border-gray-700 px-4 py-2;\n}\n\nth {\n    background-color: #161b22;\n}\n\ntr:nth-child(even) {\n    background-color: #1c2028;\n}\n\n\n/* range input track style */\ninput[type=range] {\n    -webkit-appearance: none;\n    appearance: none;\n    width: 100%;\n    background: transparent;\n}\n\ninput[type=range]:focus {\n    outline: none;\n}\n\ninput[type=range]::-ms-track {\n    width: 100%;\n    cursor: pointer;\n\n    /* Hides the slider so custom styles can be added */\n    background: transparent;\n    border-color: transparent;\n    color: transparent;\n}\n\ninput[type=range] {\n    @apply bg-slate-11 rounded-md;\n    height: 0.5rem;\n}\n\n/* Customize website's scrollbar like Mac OS\nNot supports in Firefox and IE */\n/* total width */\n*::-webkit-scrollbar {\n    border-radius: 12px;\n    background-color: #889096;\n    width: 12px;\n}\n\n/* scrollbar itself */\n*::-webkit-scrollbar-thumb {\n    background-color: #D7DBDF;\n    @apply rounded-lg;\n    border: 2px solid #889096; /* This creates the illusion of padding inside the track */\n}\n\n/* set button(top and bottom of the scrollbar) */\n*::-webkit-scrollbar-button {\n    display: none;\n}\n\n/*  disappearing animation */\n.animation-hide {\n    animation: hide 1s cubic-bezier(0.4, 0, 0.2, 1) 0s 1 forwards;\n}\n\n@keyframes hide {\n    to {\n        opacity: 0;\n    }\n}\n\n@keyframes border-pulse-animation {\n    0% {\n        border-color: rgba(216, 180, 254, 0.3);\n    }\n    50% {\n        border-color: rgba(216, 180, 254, 0.4);\n    }\n    100% {\n        border-color: rgba(216, 180, 254, 0.3);\n    }\n}\n\n.animate-border-pulse {\n    animation: border-pulse-animation 2s infinite;\n}\n\n@keyframes moveBackground {\n    from {\n        background-position: 0 0;\n    }\n    to {\n        background-position: 100% 0;\n    }\n}\n\n.bg-stars {\n    animation: moveBackground 30s linear infinite;\n    background: url(\"/stars.svg\");\n    background-size: cover;\n    position: fixed;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    z-index: -1;\n}\n"
  },
  {
    "path": "next/src/types/errors.ts",
    "content": "import axios from \"axios\";\nimport { z } from \"zod\";\n\nexport const MAX_LOOPS_ERROR = \"MaxLoopsError\";\nconst platformErrorSchema = z.object({\n  error: z.string(),\n  detail: z.string(),\n  code: z.number().optional(),\n});\n\nexport type PlatformError = z.infer<typeof platformErrorSchema>;\n\nexport const isPlatformError = (e: unknown): e is PlatformError => {\n  return platformErrorSchema.safeParse(e).success;\n};\n\nexport const isRetryableError = (e: unknown): boolean => {\n  if (axios.isAxiosError(e)) {\n    if (isPlatformError(e.response?.data)) {\n      const error = e.response?.data.error;\n      return error !== MAX_LOOPS_ERROR;\n    }\n\n    return e.response?.status !== 429;\n  }\n  return true;\n};\n\n// Backend returns a value error when the user's input is invalid.\nconst valueErrorDetailSchema = z.object({\n  loc: z.array(z.string()),\n  msg: z.string(),\n  type: z.string(),\n});\n\nconst valueErrorSchema = z.object({\n  detail: z.array(valueErrorDetailSchema),\n});\n\nexport type ValueError = z.infer<typeof valueErrorSchema>;\n\nexport const isValueError = (e: object): e is ValueError => {\n  return valueErrorSchema.safeParse(e).success;\n};\n"
  },
  {
    "path": "next/src/types/index.ts",
    "content": "export * from \"./propTypes\";\nexport * from \"./modelSettings\";\n"
  },
  {
    "path": "next/src/types/message.ts",
    "content": "import { z } from \"zod\";\n\nimport { taskSchema } from \"./task\";\n\n/* Message & Task Type */\nexport const [MESSAGE_TYPE_GOAL, MESSAGE_TYPE_ACTION, MESSAGE_TYPE_SYSTEM, MESSAGE_TYPE_ERROR] = [\n  \"goal\" as const,\n  \"action\" as const,\n  \"system\" as const,\n  \"error\" as const,\n];\n\nconst messageSchemaBase = z.object({\n  id: z.string().optional(),\n  value: z.string(),\n  info: z.string().optional().nullable(),\n});\n\nexport const nonTaskScehma = z\n  .object({\n    type: z.union([\n      z.literal(MESSAGE_TYPE_GOAL),\n      z.literal(MESSAGE_TYPE_ACTION),\n      z.literal(MESSAGE_TYPE_SYSTEM),\n      z.literal(MESSAGE_TYPE_ERROR),\n    ]),\n  })\n  .merge(messageSchemaBase);\n\nexport const messageSchema = z.union([taskSchema, nonTaskScehma]);\n\nexport type Message = z.infer<typeof messageSchema>;\n\n/*\n * Ideal message type\n * {\n *  icon: IconType,\n *  title: string,\n *  subtitle: string, // Optional\n *  value: string, // Markdown formatted value\n *  color: string, // Classname used for the border\n * }\n */\n"
  },
  {
    "path": "next/src/types/modelSettings.ts",
    "content": "import { type Language } from \"../utils/languages\";\n\nexport const [GPT_35_TURBO, GPT_35_TURBO_16K, GPT_4] = [\n  \"gpt-3.5-turbo\" as const,\n  \"gpt-3.5-turbo-16k\" as const,\n  \"gpt-4\" as const,\n];\nexport const GPT_MODEL_NAMES = [GPT_35_TURBO, GPT_35_TURBO_16K, GPT_4];\nexport type GPTModelNames = \"gpt-3.5-turbo\" | \"gpt-3.5-turbo-16k\" | \"gpt-4\";\n\nexport const MAX_TOKENS: Record<GPTModelNames, number> = {\n  \"gpt-3.5-turbo\": 4000,\n  \"gpt-3.5-turbo-16k\": 16000,\n  \"gpt-4\": 4000,\n};\n\nexport interface ModelSettings {\n  language: Language;\n  customApiKey: string;\n  customModelName: GPTModelNames;\n  customTemperature: number;\n  customMaxLoops: number;\n  maxTokens: number;\n}\n"
  },
  {
    "path": "next/src/types/next-auth.d.ts",
    "content": "import type { DefaultSession } from \"next-auth\";\n\ndeclare module \"next-auth\" {\n  /**\n   * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context\n   */\n  interface Session {\n    accessToken?: string;\n    user: {\n      id: string;\n    } & DefaultSession[\"user\"] &\n      User;\n  }\n\n  interface User {\n    image?: string;\n    superAdmin: boolean;\n    organizations: {\n      id: string;\n      name: string;\n      role: string;\n    }[];\n  }\n}\n"
  },
  {
    "path": "next/src/types/propTypes.ts",
    "content": "export type toolTipProperties = {\n  message?: string;\n  disabled?: boolean;\n};\n"
  },
  {
    "path": "next/src/types/task.ts",
    "content": "import { z } from \"zod\";\n\nexport const MESSAGE_TYPE_TASK = \"task\";\nconst messageSchemaBase = z.object({\n  id: z.string().optional(),\n  value: z.string(),\n  info: z.string().optional().nullable(),\n});\n\nexport const [\n  TASK_STATUS_STARTED,\n  TASK_STATUS_EXECUTING,\n  TASK_STATUS_COMPLETED,\n  TASK_STATUS_FINAL,\n] = [\"started\" as const, \"executing\" as const, \"completed\" as const, \"final\" as const];\n\nexport const TaskStatusSchema = z.union([\n  z.literal(TASK_STATUS_STARTED),\n  z.literal(TASK_STATUS_EXECUTING),\n  z.literal(TASK_STATUS_COMPLETED),\n  z.literal(TASK_STATUS_FINAL),\n  z.literal(\"\"),\n]);\n\nexport type TaskStatus = z.infer<typeof TaskStatusSchema>;\n\nexport const taskSchema = z\n  .object({\n    taskId: z.string().optional(),\n    type: z.literal(MESSAGE_TYPE_TASK),\n    status: TaskStatusSchema,\n    result: z.string().optional(),\n  })\n  .merge(messageSchemaBase);\n\nexport type Task = z.infer<typeof taskSchema>;\n\n/* Type Predicates */\nexport const isTask = (value: unknown): value is Task => {\n  try {\n    taskSchema.parse(value);\n    return true;\n  } catch (err) {\n    return false;\n  }\n};\n\n/* Helper Functions */\nexport const getTaskStatus = (value: unknown): TaskStatus | undefined => {\n  if (!isTask(value)) {\n    return;\n  }\n\n  return value.status;\n};\n\nexport const isAction = (value: unknown): boolean => {\n  return isTask(value) && value.status === TASK_STATUS_COMPLETED;\n};\n"
  },
  {
    "path": "next/src/ui/button.tsx",
    "content": "import type { ForwardedRef } from \"react\";\nimport React, { forwardRef } from \"react\";\n\nimport Loader from \"../components/loader\";\nimport Ping from \"../components/Ping\";\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  className?: string;\n  icon?: React.ReactNode;\n  children?: React.ReactNode;\n  loader?: boolean;\n  disabled?: boolean;\n  ping?: boolean;\n  onClick?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n}\n\nconst Button = forwardRef((props: ButtonProps, ref: ForwardedRef<HTMLButtonElement>) => {\n  const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n    void Promise.resolve(props.onClick?.(e)).then();\n    e.preventDefault();\n  };\n\n  return (\n    <button\n      ref={ref}\n      type={props.type}\n      disabled={props.loader || props.disabled}\n      className={props.className}\n      onClick={onClick}\n    >\n      {props.ping && <Ping color=\"white\" />}\n      <div className=\"flex items-center justify-center gap-x-2.5 px-4 py-1 font-inter text-sm leading-6\">\n        {props.loader ? <Loader /> : props.children}\n      </div>\n    </button>\n  );\n});\n\nButton.displayName = \"Button\";\nexport default Button;\n"
  },
  {
    "path": "next/src/ui/checkbox.tsx",
    "content": "import clsx from \"clsx\";\nimport type { ButtonHTMLAttributes, Dispatch, SetStateAction } from \"react\";\n\nexport interface Props extends ButtonHTMLAttributes<HTMLInputElement> {\n  label?: string;\n  description?: string;\n  model: [boolean, Dispatch<SetStateAction<boolean>>];\n  className?: string;\n}\n\nfunction Checkbox(props: Props) {\n  return (\n    <div className={clsx(\"relative flex items-start\", props.className)}>\n      <div className=\"flex h-6 items-center\">\n        <input\n          type=\"checkbox\"\n          className=\"h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600\"\n          checked={props.model[0]}\n          onChange={(e) => props.model[1](e.target.checked)}\n        />\n      </div>\n      <div className=\"ml-3 text-sm leading-6 text-gray-400\">\n        {props.label && <label className=\"font-medium\">{props.label}</label>}\n      </div>\n    </div>\n  );\n}\n\nexport default Checkbox;\n"
  },
  {
    "path": "next/src/ui/combox.tsx",
    "content": "import { Combobox } from \"@headlessui/react\";\nimport clsx from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport { useState } from \"react\";\nimport { HiCheck, HiChevronDown } from \"react-icons/hi2\";\n\ninterface Props<T> {\n  label: string;\n  items: T[];\n  value: T | undefined;\n  valueMapper: (e: T) => string;\n  onChange: (value: T) => void;\n  icon?: ReactNode;\n}\n\nconst Combo = <T,>({ items, ...props }: Props<T>) => {\n  const [query, setQuery] = useState(\"\");\n\n  const filtered =\n    query === \"\"\n      ? items\n      : items.filter((e) => props.valueMapper(e).toLowerCase().includes(query.toLowerCase()));\n\n  return (\n    <Combobox as=\"div\" value={props.value} onChange={props.onChange}>\n      <Combobox.Label className=\"flex items-center gap-2 text-sm font-bold leading-6 text-slate-12\">\n        {props.icon}\n        {props.label}\n      </Combobox.Label>\n      <div className=\"relative mt-1\">\n        <Combobox.Input\n          className=\"w-full rounded-md border-0 bg-slate-1 py-1.5 pl-3 pr-10 text-slate-12 shadow-depth-1 transition-colors sm:text-sm sm:leading-6\"\n          onChange={(event) => setQuery(event.target.value)}\n          displayValue={(e) => props.valueMapper(e as T)}\n        />\n        <Combobox.Button className=\"absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none\">\n          <HiChevronDown className=\"h-5 w-5 text-gray-400\" aria-hidden=\"true\" />\n        </Combobox.Button>\n\n        {filtered.length > 0 && (\n          <Combobox.Options className=\"absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-slate-1 py-1 text-slate-12 shadow-lg ring-opacity-5 focus:outline-none sm:text-sm\">\n            {filtered.map((e, i) => (\n              <Combobox.Option\n                key={i}\n                value={e}\n                className={({ active }) =>\n                  clsx(\n                    \"relative cursor-default select-none py-2 pl-3 pr-9 \",\n                    active ? \"hover:bg-slate-3\" : \"text-slate-12\"\n                  )\n                }\n              >\n                {({ selected }) => (\n                  <>\n                    <span className={clsx(\"block truncate\", selected && \"font-semibold\")}>\n                      {props.valueMapper(e)}\n                    </span>\n\n                    {selected && (\n                      <span\n                        className={clsx(\n                          \"absolute inset-y-0 right-0 flex items-center pr-4 text-slate-12\"\n                        )}\n                      >\n                        <HiCheck className=\"h-5 w-5\" aria-hidden=\"true\" />\n                      </span>\n                    )}\n                  </>\n                )}\n              </Combobox.Option>\n            ))}\n          </Combobox.Options>\n        )}\n      </div>\n    </Combobox>\n  );\n};\n\nexport default Combo;\n"
  },
  {
    "path": "next/src/ui/dialog.tsx",
    "content": "import { Dialog as HeadlessDialog, Transition } from \"@headlessui/react\";\nimport clsx from \"clsx\";\nimport type { Dispatch, FC, PropsWithChildren, ReactNode, SetStateAction } from \"react\";\nimport { Fragment, useRef } from \"react\";\n\ninterface DialogProps extends PropsWithChildren {\n  open: boolean;\n  setOpen: Dispatch<SetStateAction<boolean>>;\n  icon?: ReactNode;\n  title: ReactNode;\n  actions?: ReactNode;\n  inline?: boolean;\n}\n\nconst Dialog: FC<DialogProps> = ({ open, setOpen, ...props }) => {\n  const cancelButtonRef = useRef(null);\n\n  return (\n    <Transition.Root show={open} as={Fragment}>\n      <HeadlessDialog\n        as=\"div\"\n        className=\"relative z-50\"\n        initialFocus={cancelButtonRef}\n        onClose={setOpen}\n      >\n        <Transition.Child\n          as={Fragment}\n          enter=\"ease-out duration-300\"\n          enterFrom=\"opacity-0\"\n          enterTo=\"opacity-100\"\n          leave=\"ease-in duration-200\"\n          leaveFrom=\"opacity-100\"\n          leaveTo=\"opacity-0\"\n        >\n          <div className=\"fixed inset-0 bg-neutral-900/80 transition-opacity\" />\n        </Transition.Child>\n\n        <div className=\"fixed inset-0 z-10 overflow-y-auto\">\n          <div\n            className={clsx(\n              \"flex min-h-full items-center justify-center p-4 text-center\",\n              props.inline || \"sm:p-0\"\n            )}\n          >\n            <Transition.Child\n              as={Fragment}\n              enter=\"ease-out duration-300\"\n              enterFrom=\"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95\"\n              enterTo=\"opacity-100 translate-y-0 sm:scale-100\"\n              leave=\"ease-in duration-200\"\n              leaveFrom=\"opacity-100 translate-y-0 sm:scale-100\"\n              leaveTo=\"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95\"\n            >\n              <HeadlessDialog.Panel\n                className={clsx(\n                  \"relative w-full max-w-sm transform overflow-hidden rounded-lg border-b border-slate-6 bg-slate-3 text-left shadow-xl transition-all\",\n                  props.inline || \"sm:my-8 sm:w-full sm:max-w-lg\"\n                )}\n              >\n                <HeadlessDialog.Title\n                  as=\"h3\"\n                  className=\"flex flex-row items-start px-4 py-3 font-semibold leading-6 text-slate-12\"\n                >\n                  {props.title}\n                </HeadlessDialog.Title>\n                <div\n                  className={clsx(\"bg-slate-1 px-4 pb-4 pt-5\", props.inline || \"sm:p-6 sm:pb-4\")}\n                >\n                  <div className={clsx(props.inline || \"sm:flex sm:items-start\")}>\n                    <div\n                      className={clsx(\n                        \"mx-auto flex flex-shrink-0 items-center justify-center\",\n                        props.inline || \"sm:mx-0 sm:h-10 sm:w-10\"\n                      )}\n                    >\n                      {props.icon}\n                    </div>\n                    <div>{props.children}</div>\n                  </div>\n                </div>\n                <div className=\"flex flex-col gap-2 border-t border-slate-6 bg-slate-3 px-8 py-4\">\n                  {props.actions}\n                </div>\n              </HeadlessDialog.Panel>\n            </Transition.Child>\n          </div>\n        </div>\n      </HeadlessDialog>\n    </Transition.Root>\n  );\n};\n\nexport default Dialog;\n"
  },
  {
    "path": "next/src/ui/highlight.tsx",
    "content": "import clsx from \"clsx\";\nimport { motion, useMotionTemplate } from \"framer-motion\";\nimport React from \"react\";\n\nimport { useMouseMovement } from \"../hooks/useMouseMovement\";\n\nconst colors = {\n  blue: \"bg-gradient-to-r from-sky-500/30 to-sky-500/20\",\n  purple: \"bg-gradient-to-r from-purple-500/30 to-purple-500/20\",\n} as const;\n\ninterface Props {\n  color: keyof typeof colors;\n}\n\nconst Highlight = (props: Props) => {\n  const { mouseX, mouseY, onMouseMove } = useMouseMovement();\n\n  const maskImage = useMotionTemplate`radial-gradient(200px at ${mouseX}px ${mouseY}px, white, transparent)`;\n  const style = { maskImage, WebkitMaskImage: maskImage };\n\n  return (\n    <div className=\"absolute inset-0 z-10 h-full w-full\" onMouseMove={onMouseMove}>\n      <motion.div\n        className={clsx(\n          \"pointer-events-none h-full w-full rounded-xl opacity-0 transition duration-300 group-hover:opacity-100\",\n          colors[props.color]\n        )}\n        style={style}\n      />\n    </div>\n  );\n};\n\nexport default Highlight;\n"
  },
  {
    "path": "next/src/ui/input.tsx",
    "content": "import clsx from \"clsx\";\nimport React from \"react\";\n\ninterface Props extends React.InputHTMLAttributes<HTMLInputElement> {\n  name: string;\n  label?: string;\n  attributes?: { [key: string]: string | number | string[] };\n  helpText?: string | React.ReactNode;\n  icon?: React.ReactNode;\n  disabled?: boolean;\n  right?: React.ReactNode;\n  handleFocusChange?: (focused: boolean) => void;\n}\n\nconst Input = (props: Props) => {\n  return (\n    <div>\n      {props.label && (\n        <label\n          htmlFor={props.name}\n          className=\"flex items-center gap-2 text-sm font-bold leading-6 text-slate-12\"\n        >\n          {props.icon}\n          <span>{props.label}</span>\n\n          {props.type == \"range\" && (\n            <span className=\"text-xs font-medium text-slate-12 lg:text-sm\">({props.value})</span>\n          )}\n        </label>\n      )}\n      <div className=\"relative flex flex-col gap-1 rounded-md shadow-sm\">\n        {props.helpText && (\n          <p\n            className=\"text-xs font-light text-slate-11 lg:text-sm\"\n            id={`${props.name}-description`}\n          >\n            {props.helpText}\n          </p>\n        )}\n        <div className=\"flex flex-grow flex-row items-center gap-1\">\n          <input\n            type={props.type}\n            name={props.name}\n            id={props.name}\n            className={clsx(\n              \"placeholder:text-color-tertiary focus:outline-inset block w-full rounded-md border-0 bg-slate-1 p-1.5 text-slate-12 shadow-depth-1 transition-colors sm:text-sm sm:leading-6\"\n            )}\n            placeholder={props.placeholder}\n            value={props.value}\n            onChange={props.onChange}\n            disabled={props.disabled}\n            onFocus={() => props.handleFocusChange && props.handleFocusChange(true)}\n            onBlur={() => props.handleFocusChange && props.handleFocusChange(false)}\n            {...(props.helpText ? { \"aria-describedby\": `${props.name}-description` } : {})}\n            {...props.attributes}\n          />\n          {props.right}\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport default Input;\n"
  },
  {
    "path": "next/src/ui/select.tsx",
    "content": "import { Listbox, Transition } from \"@headlessui/react\";\nimport clsx from \"clsx\";\nimport { Fragment } from \"react\";\nimport type { IconType } from \"react-icons\";\nimport { FaCheck } from \"react-icons/fa\";\nimport { HiOutlineChevronUpDown } from \"react-icons/hi2\";\n\ninterface Props<T> {\n  value?: T;\n  onChange?: (value: T | undefined) => void | Promise<void>;\n  items?: T[];\n  valueMapper?: (item?: T) => string | undefined;\n  icon: IconType;\n  disabled?: boolean;\n  defaultValue: T;\n}\n\nexport default function Select<T>(props: Props<T>) {\n  return (\n    <Listbox\n      value={props.value || props.defaultValue}\n      onChange={props.onChange}\n      disabled={props.disabled}\n    >\n      {({ open }) => (\n        <>\n          <div className=\"relative\">\n            <Listbox.Button\n              className={clsx(\n                \"border-1 relative h-6 w-full cursor-default rounded-md border border-black bg-white px-1 text-left text-xs text-black focus:outline-none focus:ring-1 focus:ring-indigo-500\",\n                props.disabled && \"cursor-not-allowed bg-neutral-300 text-neutral-700\"\n              )}\n            >\n              <span className=\"flex flex-row items-center\">\n                {props.icon({\n                  className: \"text-white bg-black rounded-sm ring-2 ring-black\",\n                  size: \"1em\",\n                })}\n                <span className=\"ml-2 block min-w-[60px] flex-grow truncate capitalize\">\n                  {props.valueMapper?.(props.value || props.defaultValue)}\n                </span>\n                <HiOutlineChevronUpDown className=\"h-5 w-5 pl-1 text-black\" aria-hidden=\"true\" />\n              </span>\n            </Listbox.Button>\n\n            <Transition\n              show={open}\n              as={Fragment}\n              leave=\"transition ease-in duration-100\"\n              leaveFrom=\"opacity-100\"\n              leaveTo=\"opacity-0\"\n            >\n              <Listbox.Options className=\"absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm\">\n                {(!props.items || props.items?.length == 0) && (\n                  <div className=\"px-1 text-xs\">No options available</div>\n                )}\n                {props.items?.map((item, i) => (\n                  <Listbox.Option\n                    key={i}\n                    className={({ active }) =>\n                      clsx(\n                        active ? \"bg-indigo-600 text-white\" : \"text-gray-900\",\n                        \"relative cursor-default select-none py-2 pl-3 pr-9\"\n                      )\n                    }\n                    value={item}\n                  >\n                    {({ selected, active }) => (\n                      <>\n                        <div className=\"flex\">\n                          <span\n                            className={clsx(selected && \"font-semibold\", \"truncate capitalize\")}\n                          >\n                            {props.valueMapper?.(item)}\n                          </span>\n                        </div>\n\n                        {selected ? (\n                          <span\n                            className={clsx(\n                              active ? \"text-white\" : \"text-indigo-600\",\n                              \"absolute inset-y-0 right-0 flex items-center pr-4\"\n                            )}\n                          >\n                            <FaCheck className=\"h-4 w-4\" aria-hidden=\"true\" />\n                          </span>\n                        ) : null}\n                      </>\n                    )}\n                  </Listbox.Option>\n                ))}\n              </Listbox.Options>\n            </Transition>\n          </div>\n        </>\n      )}\n    </Listbox>\n  );\n}\n"
  },
  {
    "path": "next/src/utils/api.ts",
    "content": "/**\n * This is the client-side entrypoint for your tRPC API.\n * It's used to create the `api` object which contains the Next.js App-wrapper\n * as well as your typesafe react-query hooks.\n *\n * We also create a few inference helpers for input and output types\n */\nimport { httpBatchLink, loggerLink } from \"@trpc/client\";\nimport { createTRPCNext } from \"@trpc/next\";\nimport { type inferRouterInputs, type inferRouterOutputs } from \"@trpc/server\";\nimport superjson from \"superjson\";\n\nimport { type AppRouter } from \"../server/api/root\";\n\nconst getBaseUrl = () => {\n  if (typeof window !== \"undefined\") return \"\"; // browser should use relative url\n  if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url\n  return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost\n};\n\n/**\n * A set of typesafe react-query hooks for your tRPC API\n */\nexport const api = createTRPCNext<AppRouter>({\n  config() {\n    return {\n      /**\n       * Transformer used for data de-serialization from the server\n       * @see https://trpc.io/docs/data-transformers\n       **/\n      transformer: superjson,\n\n      /**\n       * Links used to determine request flow from client to server\n       * @see https://trpc.io/docs/links\n       * */\n      links: [\n        loggerLink({\n          enabled: (opts) =>\n            process.env.NODE_ENV === \"development\" ||\n            (opts.direction === \"down\" && opts.result instanceof Error),\n        }),\n        httpBatchLink({\n          url: `${getBaseUrl()}/api/trpc`,\n        }),\n      ],\n    };\n  },\n  /**\n   * Whether tRPC should await queries when server rendering pages\n   * @see https://trpc.io/docs/nextjs#ssr-boolean-default-false\n   */\n  ssr: false,\n});\n\n/**\n * Inference helper for inputs\n * @example type HelloInput = RouterInputs['example']['hello']\n **/\nexport type RouterInputs = inferRouterInputs<AppRouter>;\n/**\n * Inference helper for outputs\n * @example type HelloOutput = RouterOutputs['example']['hello']\n **/\nexport type RouterOutputs = inferRouterOutputs<AppRouter>;\n"
  },
  {
    "path": "next/src/utils/constants.ts",
    "content": "import { ENGLISH } from \"./languages\";\nimport type { ModelSettings } from \"../types\";\n\nexport const GPT_35_TURBO = \"gpt-3.5-turbo\" as const;\nexport const GPT_4 = \"gpt-4\" as const;\nexport const GPT_MODEL_NAMES = [GPT_35_TURBO, GPT_4];\n\nexport const DEFAULT_MAX_LOOPS_FREE = 25 as const;\nexport const DEFAULT_MAX_LOOPS_CUSTOM_API_KEY = 10 as const;\n\nexport const getDefaultModelSettings = (): ModelSettings => {\n  return {\n    customApiKey: \"\",\n    language: ENGLISH,\n    customModelName: GPT_35_TURBO,\n    customTemperature: 0.8,\n    customMaxLoops: DEFAULT_MAX_LOOPS_FREE,\n    maxTokens: 1250,\n  };\n};\n"
  },
  {
    "path": "next/src/utils/helpers.ts",
    "content": "type Constructor<T> = new (...args: unknown[]) => T;\n\n/* Check whether array is of the specified type */\nexport const isArrayOfType = <T>(\n  arr: unknown[] | unknown,\n  type: Constructor<T> | string\n): arr is T[] => {\n  return (\n    Array.isArray(arr) &&\n    arr.every((item): item is T => {\n      if (typeof type === \"string\") {\n        return typeof item === type;\n      } else {\n        return item instanceof type;\n      }\n    })\n  );\n};\n"
  },
  {
    "path": "next/src/utils/i18next.n.ts",
    "content": "import i18next from \"i18next\";\nimport { initReactI18next } from \"react-i18next\";\n\nawait i18next.use(initReactI18next).init({\n  fallbackLng: [\"en\"],\n  debug: true,\n  interpolation: {\n    escapeValue: false, // react already safes from xss\n  },\n  keySeparator: false,\n  react: {\n    useSuspense: false,\n  },\n  defaultNS: \"translation\",\n  backend: {\n    loadPath: \"./public/locales/{{lng}}/{{ns}}.json\",\n    crossDomain: false,\n  },\n});\n\nexport default i18next;\n"
  },
  {
    "path": "next/src/utils/interfaces.ts",
    "content": "import type { Session } from \"next-auth\";\n\nimport type { Analysis } from \"../services/agent/analysis\";\nimport type { GPTModelNames, ModelSettings } from \"../types\";\n\nexport interface ApiModelSettings {\n  language: string;\n  model: GPTModelNames;\n  temperature: number;\n  max_tokens: number;\n}\n\nexport const toApiModelSettings = (modelSettings: ModelSettings, session?: Session) => {\n  const allowCustomization = session?.user;\n\n  return {\n    language: modelSettings.language.name,\n    model: allowCustomization ? modelSettings.customModelName : \"gpt-3.5-turbo\",\n    temperature: modelSettings.customTemperature,\n    max_tokens: allowCustomization ? modelSettings.maxTokens : 500,\n    custom_api_key: modelSettings.customApiKey,\n  };\n};\n\nexport interface RequestBody {\n  run_id?: string;\n  model_settings: ApiModelSettings;\n  goal: string;\n  task?: string;\n  tasks?: string[];\n  last_task?: string;\n  result?: string;\n  results?: string[];\n  completed_tasks?: string[];\n  analysis?: Analysis;\n  tool_names?: string[];\n  message?: string; // Used for the chat endpoint\n}\n"
  },
  {
    "path": "next/src/utils/languages.ts",
    "content": "export type Language = {\n  code: string;\n  name: string;\n  flag: string;\n};\n\nexport const ENGLISH = { code: \"en\", name: \"English\", flag: \"🇺🇸\" };\n\nexport const availableLanguages: Language[] = [\n  ENGLISH,\n  { code: \"fr\", name: \"Français\", flag: \"🇫🇷\" },\n  { code: \"es\", name: \"Español\", flag: \"🇪🇸\" },\n  { code: \"de\", name: \"Deutsch\", flag: \"🇩🇪\" },\n  { code: \"ja\", name: \"日本語\", flag: \"🇯🇵\" },\n  { code: \"ko\", name: \"한국어\", flag: \"🇰🇷\" },\n  { code: \"zh\", name: \"简体中文\", flag: \"🇨🇳\" },\n  { code: \"zhtw\", name: \"繁體中文\", flag: \"🇹🇼\" },\n  { code: \"hr\", name: \"Hrvatski\", flag: \"🇭🇷\" },\n  { code: \"lt\", name: \"Lietuvių\", flag: \"🇱🇹\" },\n  { code: \"uk\", name: \"Українська\", flag: \"🇺🇦\" },\n  { code: \"pt\", name: \"Português\", flag: \"🇵🇹\" },\n  { code: \"it\", name: \"Italiano\", flag: \"🇮🇹\" },\n  { code: \"hu\", name: \"Magyar\", flag: \"🇭🇺\" },\n  { code: \"nl\", name: \"Nederlands\", flag: \"🇳🇱\" },\n  { code: \"pl\", name: \"Polski\", flag: \"🇵🇱\" },\n  { code: \"ru\", name: \"Русский\", flag: \"🇷🇺\" },\n  { code: \"ro\", name: \"Română\", flag: \"🇷🇴\" },\n  { code: \"sk\", name: \"Slovenčina\", flag: \"🇸🇰\" },\n  { code: \"tr\", name: \"Türkçe\", flag: \"🇹🇷\" },\n];\n\nexport const languages: Language[] = availableLanguages.sort((a, b) =>\n  a.name.localeCompare(b.name)\n);\n\nexport const findLanguage = (nameOrLocale: string): Language => {\n  const selectedLanguage = languages.find(\n    (lang) => lang.code === nameOrLocale || lang.name === nameOrLocale.substring(4).trim()\n  );\n  return selectedLanguage || ENGLISH;\n};\n"
  },
  {
    "path": "next/src/utils/translations.ts",
    "content": "import {i18n} from \"next-i18next\";\n\ntype Namespace =\n  'errors' | 'drawer'\n\n\nexport const translate = (key: string, ns: Namespace | undefined) => {\n  const opts = !!ns ? { ns } : undefined\n  return i18n?.t(key, key, opts) ?? key;\n}\n"
  },
  {
    "path": "next/src/utils/user.ts",
    "content": "export const get_avatar = (user?: {\n  name?: string | null;\n  email?: string | null;\n  image?: string | null;\n}) =>\n  user?.image ||\n  \"https://avatar.vercel.sh/\" +\n    (user?.email || \"\") +\n    \".svg?text=\" +\n    (user?.name?.substr(0, 2).toUpperCase() || \"\");\n"
  },
  {
    "path": "next/src/utils/whitespace.ts",
    "content": "function regex() {\n  return /^[\\s\\f\\n\\r\\t\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0]+$/;\n}\n\nexport function isEmptyOrBlank(value: string) {\n  return regex().test(value) || value === '';\n}\n"
  },
  {
    "path": "next/tailwind.config.cjs",
    "content": "/** @type {import(\"tailwindcss\").Config} */\nconst defaultTheme = require(\"tailwindcss/defaultTheme\");\n\nmodule.exports = {\n    content: [\n        \"./src/**/*.{js,ts,jsx,tsx}\",\n        \"./node_modules/@tremor/**/*.{js,ts,jsx,tsx}\",\n    ],\n    darkMode: \"class\",\n    theme: {\n        transparent: \"transparent\",\n        current: \"currentColor\",\n        screens: {\n            \"xs\": \"300px\",\n            \"xmd\": \"850px\",\n            \"sm-h\": { \"raw\": \"(min-height: 700px)\" },\n            \"md-h\": { \"raw\": \"(min-height: 800px)\" },\n            \"lg-h\": { \"raw\": \"(min-height: 1000px)\" },\n\n            ...defaultTheme.screens\n        },\n        extend: {\n            typography: (theme) => ({\n                DEFAULT: {\n                    css: {\n                        color: theme('colors.gray.900'),  // Change color as per your need\n                        a: {\n                            color: theme('colors.blue.500'),  // Change color as per your need\n                            '&:hover': {\n                                color: theme('colors.blue.600'),  // Change color as per your need\n                            },\n                        },\n                        'h1,h2,h3,h4': {\n                            color: theme('colors.white'),  // This is where you change your heading color\n                        },\n                        'b,strong': {\n                            color: theme('colors.gray.500'),  // This is where you change your bold text color\n                        },\n                    },\n                },\n            }),\n            backgroundImage: {\n                'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', // Add bg-gradient-radial for radial gradients\n            },\n            boxShadow: {\n                \"xs\": \"0px 0px 0px 0.75px rgba(0, 0, 0, 0.05), 0px 2px 4px rgba(0, 0, 0, 0.05)\",\n                // light\n                \"tremor-input\": \"0 1px 2px 0 rgb(0 0 0 / 0.05)\",\n                \"tremor-card\": \"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)\",\n                \"tremor-dropdown\": \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\",\n                // dark\n                \"dark-tremor-input\": \"0 1px 2px 0 rgb(0 0 0 / 0.05)\",\n                \"dark-tremor-card\": \"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)\",\n                \"dark-tremor-dropdown\": \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\",\n\n                \"depth-1\": \"0 2px 4px 0 rgba(0, 0, 0, 0.05), 0 0 0 0.75px rgba(0, 0, 0, 0.05), 0 0 12px -2px rgba(0, 0, 0, 0.05)\",\n                \"depth-2\": \"0 0 0 0.75px rgba(0, 0, 0, 0.05), 0 8px 32px 0 rgba(39, 40, 51, 0.05), 0 4px 16px 0 rgba(39, 40, 51, 0.05)\",\n                \"depth-3\": \"0 0 0 0.75px rgba(0, 0, 0, 0.05), 0 8px 32px 0 rgba(39, 40, 51, 0.05), 0 4px 16px 0 rgba(39, 40, 51, 0.05), 0 8px 24px -4px rgba(0, 0, 0, 0.20)\"\n            },\n            borderRadius: {\n                \"tremor-small\": \"0.375rem\",\n                \"tremor-default\": \"0.5rem\",\n                \"tremor-full\": \"9999px\",\n            },\n            fontSize: {\n                \"tremor-label\": [\"0.75rem\"],\n                \"tremor-default\": [\"0.875rem\", { lineHeight: \"1.25rem\" }],\n                \"tremor-title\": [\"1.125rem\", { lineHeight: \"1.75rem\" }],\n                \"tremor-metric\": [\"1.875rem\", { lineHeight: \"2.25rem\" }],\n            },\n            fontFamily: {\n                inter: [\"Inter\", ...defaultTheme.fontFamily.sans]\n            },\n\n            colors: {\n                slate: {\n                    1: \"#FBFCFD\",\n                    2: \"#F8F9FA\",\n                    3: \"#F1F3F5\",\n                    4: \"#ECEEF0\",\n                    5: \"#E6E8EB\",\n                    6: \"#DFE3E6\",\n                    7: \"#D7DBDF\",\n                    8: \"#C1C8CD\",\n                    9: \"#889096\",\n                    10: \"#7E868C\",\n                    11: \"#687076\",\n                    12: \"#11181C\",\n                },\n                // light mode\n                tremor: {\n                    brand: {\n                        faint: \"#eff6ff\", // blue-50\n                        muted: \"#bfdbfe\", // blue-200\n                        subtle: \"#60a5fa\", // blue-400\n                        DEFAULT: \"#3b82f6\", // blue-500\n                        emphasis: \"#1d4ed8\", // blue-700\n                        inverted: \"#ffffff\", // white\n                    },\n                    background: {\n                        muted: \"#f9fafb\", // gray-50\n                        subtle: \"#f3f4f6\", // gray-100\n                        DEFAULT: \"#ffffff\", // white\n                        emphasis: \"#374151\", // gray-700\n                    },\n                    border: {\n                        DEFAULT: \"#e5e7eb\", // gray-200\n                    },\n                    ring: {\n                        DEFAULT: \"#e5e7eb\", // gray-200\n                    },\n                    content: {\n                        subtle: \"#9ca3af\", // gray-400\n                        DEFAULT: \"#6b7280\", // gray-500\n                        emphasis: \"#374151\", // gray-700\n                        strong: \"#111827\", // gray-900\n                        inverted: \"#ffffff\", // white\n                    },\n                },\n                // dark mode\n                \"dark-tremor\": {\n                    brand: {\n                        faint: \"#0B1229\", // custom\n                        muted: \"#172554\", // blue-950\n                        subtle: \"#1e40af\", // blue-800\n                        DEFAULT: \"#3b82f6\", // blue-500\n                        emphasis: \"#60a5fa\", // blue-400\n                        inverted: \"#030712\", // gray-950\n                    },\n                    background: {\n                        muted: \"#131A2B\", // custom\n                        subtle: \"#1f2937\", // gray-800\n                        DEFAULT: \"#111827\", // gray-900\n                        emphasis: \"#d1d5db\", // gray-300\n                    },\n                    border: {\n                        DEFAULT: \"#1f2937\", // gray-800\n                    },\n                    ring: {\n                        DEFAULT: \"#1f2937\", // gray-800\n                    },\n                    content: {\n                        subtle: \"#4b5563\", // gray-600\n                        DEFAULT: \"#6b7280\", // gray-600\n                        emphasis: \"#e5e7eb\", // gray-200\n                        strong: \"#f9fafb\", // gray-50\n                        inverted: \"#000000\", // black\n                    },\n                },\n                blue: {\n                    base: {\n                        dark: \"hsl(199, 89%, 48%)\",\n                        light: \"hsl(199, 89%, 48%)\",\n                    },\n                    hover: {\n                        dark: \"hsl(199, 80%, 30%)\",\n                        light: \"hsl(199, 90%, 40%)\",\n                    },\n                    focusVisible: {\n                        dark: \"hsl(208, 79%, 51%)\",\n                        light: \"hsl(208, 79%, 55%)\",\n                    },\n                },\n                amber: {\n                    base: {\n                        dark: \"hsl(39, 100%, 50%)\",\n                        light: \"hsl(45, 100%, 50%)\",\n                    },\n                    hover: {\n                        dark: \"hsl(39, 100%, 40%)\",\n                        light: \"hsl(45, 100%, 45%)\",\n                    },\n                    focusVisible: {\n                        dark: \"hsl(39, 85%, 30%)\",\n                        light: \"hsl(45, 85%, 35%)\",\n                    }\n                },\n                red: {\n                    base: {\n                        dark: \"hsl(3, 100%, 61%)\",\n                        light: \"hsl(3, 100%, 59%)\",\n                    },\n                    hover: {\n                        dark: \"hsl(3, 100% 45%)\",\n                        light: \"hsl(3, 100%, 40%)\",\n                    },\n                    focusVisible: {\n                        dark: \"hsl(3, 85%, 40%)\",\n                        light: \"hsl(3, 85%, 35%)\",\n                    }\n                },\n                green: {\n                    base: {\n                        dark: \"hsl(143, 71%, 45%)\",\n                        light: \"hsl(143, 71%, 40%)\",\n                    },\n                    hover: {\n                        dark: \"hsl(143, 65%, 40%)\",\n                        light: \"hsl(143, 71%, 33%)\",\n                    },\n                    focusVisible: {\n                        dark: \"hsl(143, 65%, 35%)\",\n                        light: \"hsl(143, 71%, 30%)\",\n                    }\n                },\n                shade: {\n                    100: {\n                        dark: \"hsl(0, 0%, 100%)\",\n                        light: \"hsl(0, 0%, 0%)\",\n                    },\n                    200: {\n                        dark: \"hsl(240, 3%, 69%)\",\n                        light: \"hsl(240, 2%, 30%)\",\n                    },\n                    300: {\n                        dark: \"hsl(240, 2%, 49%)\",\n                        light: \"hsl(240, 2%, 57%)\",\n                    },\n                    400: {\n                        dark: \"hsl(240, 1%, 33%)\",\n                        light: \"hsl(240, 3%, 69%)\",\n                    },\n                    500: {\n                        dark: \"hsl(240, 1%, 27%)\",\n                        light: \"hsl(240, 5%, 79%)\",\n                    },\n                    600: {\n                        dark: \"hsl(240, 2%, 22%)\",\n                        light: \"hsl(240, 6%, 83%)\",\n                    },\n                    700: {\n                        dark: \"hsl(240, 3%, 15%)\",\n                        light: \"hsl(240, 11%, 91%)\",\n                    },\n                    800: {\n                        dark: \"hsl(240, 6%, 10%)\",\n                        light: \"hsl(240, 24%, 96%)\",\n                    }\n                }\n            },\n        },\n    },\n    safelist: [\n        {\n            pattern:\n                /^(bg-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,\n            variants: [\"hover\", \"ui-selected\"],\n        },\n        {\n            pattern:\n                /^(text-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,\n            variants: [\"hover\", \"ui-selected\"],\n        },\n        {\n            pattern:\n                /^(border-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,\n            variants: [\"hover\", \"ui-selected\"],\n        },\n        {\n            pattern:\n                /^(ring-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,\n        },\n        {\n            pattern:\n                /^(stroke-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,\n        },\n        {\n            pattern:\n                /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,\n        },\n    ],\n    plugins: [\n        require('@tailwindcss/typography'),\n        require('@tailwindcss/forms'),\n        require(\"tailwindcss-radix\"),\n    ]\n};\n"
  },
  {
    "path": "next/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"noImplicitAny\": false,\n    \"target\": \"es2017\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noEmit\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\",\n    \"incremental\": true,\n    \"noUncheckedIndexedAccess\": true\n  },\n  \"include\": [\n    \"next-env.d.ts\",\n    \"**/*.ts\",\n    \"**/*.tsx\",\n    \"**/*.cjs\",\n    \"**/*.mjs\",\n    \"**/*.js\"\n  ],\n  \"exclude\": [\"node_modules\", \"venv\"]\n}\n"
  },
  {
    "path": "next/wait-for-db.sh",
    "content": "#!/usr/bin/env sh\n\nhost=\"$1\"\nport=\"$2\"\n\nuntil echo \"SELECT 1;\" | nc \"$host\" \"$port\" > /dev/null 2>&1; do\n  >&2 echo \"Database is unavailable - Sleeping...\"\n  sleep 2\ndone\n\n>&2 echo \"Database is available! Continuing...\"\n"
  },
  {
    "path": "platform/.dockerignore",
    "content": "### Python template\n\ndeploy/\n.idea/\n.vscode/\n.git/\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n#   For a library or package, you might want to ignore these files since the code is\n#   intended to run in multiple environments; otherwise, check them in:\n# .python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\npoetry.lock\n"
  },
  {
    "path": "platform/.editorconfig",
    "content": "root = true\n\n[*]\ntab_width = 4\nend_of_line = lf\nmax_line_length = 88\nij_visual_guides = 88\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{js,py,html}]\ncharset = utf-8\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[*.{yml,yaml}]\nindent_style = space\nindent_size = 2\n\n[Makefile]\nindent_style = tab\n\n[.flake8]\nindent_style = space\nindent_size = 2\n\n[*.py]\nindent_style = space\nindent_size = 4\nij_python_from_import_parentheses_force_if_multiline = true\n"
  },
  {
    "path": "platform/.flake8",
    "content": "[flake8]\nmax-complexity = 6\ninline-quotes = double\nmax-line-length = 88\nextend-ignore = E203\ndocstring_style=sphinx\n\nignore =\n  ; Found `f` string\n  WPS305,\n  ; Missing docstring in public module\n  D100,\n  ; Missing docstring in magic method\n  D105,\n  ; Missing docstring in __init__\n  D107,\n  ; Found `__init__.py` module with logic\n  WPS412,\n  ; Found class without a base class\n  WPS306,\n  ; Missing docstring in public nested class\n  D106,\n  ; First line should be in imperative mood\n  D401,\n  ; Found wrong variable name\n  WPS110,\n  ; Found `__init__.py` module with logic\n  WPS326,\n  ; Found string constant over-use\n  WPS226,\n  ; Found upper-case constant in a class\n  WPS115,\n  ; Found nested function\n  WPS602,\n  ; Found method without arguments\n  WPS605,\n  ; Found overused expression\n  WPS204,\n  ; Found too many module members\n  WPS202,\n  ; Found too high module cognitive complexity\n  WPS232,\n  ; line break before binary operator\n  W503,\n  ; Found module with too many imports\n  WPS201,\n  ; Inline strong start-string without end-string.\n  RST210,\n  ; Found nested class\n  WPS431,\n  ; Found wrong module name\n  WPS100,\n  ; Found too many methods\n  WPS214,\n  ; Found too long ``try`` body\n  WPS229,\n  ; Found unpythonic getter or setter\n  WPS615,\n  ; Found a line that starts with a dot\n  WPS348,\n  ; Found complex default value (for dependency injection)\n  WPS404,\n  ;  not perform function calls in argument defaults (for dependency injection)\n  B008,\n  ; Model should define verbose_name in its Meta inner class\n  DJ10,\n  ; Model should define verbose_name_plural in its Meta inner class\n  DJ11,\n  ; Found mutable module constant.\n  WPS407,\n  ; Found too many empty lines in `def`\n  WPS473,\n  ; Found missing trailing comma\n  C812,\n\nper-file-ignores =\n  ; all tests\n  test_*.py,tests.py,tests_*.py,*/tests/*,conftest.py:\n  ; Use of assert detected\n  S101,\n  ; Found outer scope names shadowing\n  WPS442,\n  ; Found too many local variables\n  WPS210,\n  ; Found magic number\n  WPS432,\n  ; Missing parameter(s) in Docstring\n  DAR101,\n  ; Found too many arguments\n  WPS211,\n\n  ; all init files\n  __init__.py:\n  ; ignore not used imports\n  F401,\n  ; ignore import with wildcard\n  F403,\n  ; Found wrong metadata variable\n  WPS410,\n\nexclude =\n  ./.cache,\n  ./.git,\n  ./.idea,\n  ./.mypy_cache,\n  ./.pytest_cache,\n  ./.venv,\n  ./venv,\n  ./env,\n  ./cached_venv,\n  ./docs,\n  ./deploy,\n  ./var,\n  ./.vscode,\n  *migrations*,\n"
  },
  {
    "path": "platform/.gitignore",
    "content": "### Python template\n\n.idea/\n.vscode/\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n*.pem\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\nssl/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\n*.sqlite3\n*.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n#   For a library or package, you might want to ignore these files since the code is\n#   intended to run in multiple environments; otherwise, check them in:\n# .python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n"
  },
  {
    "path": "platform/.pre-commit-config.yaml",
    "content": "---\n# See https://pre-commit.com for more information\n# See https://pre-commit.com/hooks.html for more hooks\nrepos:\n    - repo: https://github.com/pre-commit/pre-commit-hooks\n      rev: v2.4.0\n      hooks:\n          - id: check-ast\n          - id: trailing-whitespace\n          - id: check-toml\n          - id: end-of-file-fixer\n\n    - repo: https://github.com/asottile/add-trailing-comma\n      rev: v2.1.0\n      hooks:\n          - id: add-trailing-comma\n\n    - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks\n      rev: v2.1.0\n      hooks:\n          - id: pretty-format-yaml\n            args:\n              - --autofix\n              - --preserve-quotes\n              - --indent=2\n\n    - repo: local\n      hooks:\n          - id: black\n            name: Format with Black\n            entry: poetry run black\n            language: system\n            types: [python]\n\n          - id: autoflake\n            name: autoflake\n            entry: poetry run autoflake\n            language: system\n            types: [python]\n            args: [--in-place, --remove-all-unused-imports, --remove-duplicate-keys]\n\n          - id: isort\n            name: isort\n            entry: poetry run isort\n            language: system\n            types: [python]\n\n          - id: flake8\n            name: Check with Flake8\n            entry: poetry run flake8\n            language: system\n            pass_filenames: false\n            types: [python]\n            args: [--count, .]\n\n          - id: mypy\n            name: Validate types with MyPy\n            entry: poetry run mypy\n            language: system\n            types: [python]\n            pass_filenames: false\n            args:\n              - \"reworkd_platform\"\n"
  },
  {
    "path": "platform/Dockerfile",
    "content": "FROM python:3.11-slim-buster as prod\n\nRUN apt-get update && apt-get install -y \\\n  default-libmysqlclient-dev \\\n  gcc \\\n  pkg-config \\\n  openjdk-11-jdk \\\n  build-essential \\\n  && rm -rf /var/lib/apt/lists/*\n\nRUN pip install poetry==1.4.2\n\n# Configuring poetry\nRUN poetry config virtualenvs.create false\n\n# Copying requirements of a project\nCOPY pyproject.toml /app/src/\nWORKDIR /app/src\n\n# Installing requirements\nRUN poetry install --only main\n# Removing gcc\nRUN apt-get purge -y \\\n  g++ \\\n  gcc \\\n  pkg-config \\\n  && rm -rf /var/lib/apt/lists/*\n\n# Copying actual application\nCOPY . /app/src/\nRUN poetry install --only main\n\nCMD [\"/usr/local/bin/python\", \"-m\", \"reworkd_platform\"]\n\nFROM prod as dev\n\nRUN poetry install\n"
  },
  {
    "path": "platform/README.md",
    "content": "# reworkd_platform\n\nThis project was generated using fastapi_template.\n\n## Poetry\n\nThis project uses poetry. It's a modern dependency management\ntool.\n\nTo run the project use this set of commands:\n\n```bash\npoetry install\npoetry run python -m reworkd_platform\n```\n\nThis will start the server on the configured host.\n\nYou can find swagger documentation at `/api/docs`.\n\nYou can read more about poetry here: https://python-poetry.org/\n\n## Docker\n\nYou can start the project with docker using this command:\n\n```bash\ndocker-compose -f deploy/docker-compose.yml --project-directory . up --build\n```\n\nIf you want to develop in docker with autoreload add `-f deploy/docker-compose.dev.yml` to your docker command.\nLike this:\n\n```bash\ndocker-compose -f deploy/docker-compose.yml -f deploy/docker-compose.dev.yml --project-directory . up --build\n```\n\nThis command exposes the web application on port 8000, mounts current directory and enables autoreload.\n\nBut you have to rebuild image every time you modify `poetry.lock` or `pyproject.toml` with this command:\n\n```bash\ndocker-compose -f deploy/docker-compose.yml --project-directory . build\n```\n\n## Project structure\n\n```bash\n$ tree \"reworkd_platform\"\nreworkd_platform\n├── conftest.py  # Fixtures for all tests.\n├── db  # module contains db configurations\n│   ├── dao  # Data Access Objects. Contains different classes to interact with database.\n│   └── models  # Package contains different models for ORMs.\n├── __main__.py  # Startup script. Starts uvicorn.\n├── services  # Package for different external services such as rabbit or redis etc.\n├── settings.py  # Main configuration settings for project.\n├── static  # Static content.\n├── tests  # Tests for project.\n└── web  # Package contains web server. Handlers, startup config.\n    ├── api  # Package with all handlers.\n    │   └── router.py  # Main router.\n    ├── application.py  # FastAPI application configuration.\n    └── lifetime.py  # Contains actions to perform on startup and shutdown.\n```\n\n## Configuration\n\nThis application can be configured with environment variables.\n\nYou can create `.env` file in the root directory and place all\nenvironment variables here.\n\nAll environment variables should start with \"REWORKD_PLATFORM_\" prefix.\n\nFor example if you see in your \"reworkd_platform/settings.py\" a variable named like\n`random_parameter`, you should provide the \"REWORKD_PLATFORM_RANDOM_PARAMETER\"\nvariable to configure the value. This behaviour can be changed by overriding `env_prefix` property\nin `reworkd_platform.settings.Settings.Config`.\n\nAn example of .env file:\n\n```bash\nREWORKD_PLATFORM_RELOAD=\"True\"\nREWORKD_PLATFORM_PORT=\"8000\"\nREWORKD_PLATFORM_ENVIRONMENT=\"development\"\n```\n\nYou can read more about BaseSettings class here: https://pydantic-docs.helpmanual.io/usage/settings/\n\n## Pre-commit\n\nTo install pre-commit simply run inside the shell:\n\n```bash\npre-commit install\n```\n\npre-commit is very useful to check your code before publishing it.\nIt's configured using .pre-commit-config.yaml file.\n\nBy default it runs:\n\n* black (formats your code);\n* mypy (validates types);\n* isort (sorts imports in all files);\n* flake8 (spots possibe bugs);\n\nYou can read more about pre-commit here: https://pre-commit.com/\n\n## Running tests\n\nIf you want to run it in docker, simply run:\n\n```bash\ndocker-compose -f deploy/docker-compose.yml -f deploy/docker-compose.dev.yml --project-directory . run --build --rm api pytest -vv .\ndocker-compose -f deploy/docker-compose.yml -f deploy/docker-compose.dev.yml --project-directory . down\n```\n\nFor running tests on your local machine.\n\n1. you need to start a database.\n\nI prefer doing it with docker:\n\n```\ndocker run -p \"3306:3306\" -e \"MYSQL_PASSWORD=reworkd_platform\" -e \"MYSQL_USER=reworkd_platform\" -e \"MYSQL_DATABASE=reworkd_platform\" -e ALLOW_EMPTY_PASSWORD=yes bitnami/mysql:8.0.30\n```\n\n2. Run the pytest.\n\n```bash\npytest -vv .\n```\n\n## Running linters\n\n```bash\n# Flake\npoetry run black .\npoetry run autoflake --in-place --remove-duplicate-keys --remove-all-unused-imports -r .\npoetry run flake8\npoetry run mypy .\n\n# Pytest\npoetry run pytest -vv --cov=\"reworkd_platform\" .\n\n# Bump packages\npoetry self add poetry-plugin-up\npoetry up --latest\n```\n"
  },
  {
    "path": "platform/entrypoint.sh",
    "content": "#!/usr/bin/env sh\n\nhost=agentgpt_db\nport=3306\n\nuntil echo \"SELECT 1;\" | nc \"$host\" \"$port\" > /dev/null 2>&1; do\n  >&2 echo \"Database is unavailable - Sleeping...\"\n  sleep 2\ndone\n\n>&2 echo \"Database is available! Continuing...\"\n\n# Run cmd\nexec \"$@\"\n"
  },
  {
    "path": "platform/pyproject.toml",
    "content": "[tool.poetry]\nname = \"reworkd_platform\"\nversion = \"0.1.0\"\ndescription = \"\"\nauthors = [\n    \"awtkns\",\n    \"asim-shrestha\"\n]\n\nmaintainers = [\n    \"reworkd\"\n]\n\nreadme = \"README.md\"\n\n[tool.poetry.dependencies]\npython = \"^3.11\"\nfastapi = \"^0.98.0\"\nboto3 = \"^1.28.51\"\nuvicorn = { version = \"^0.22.0\", extras = [\"standard\"] }\npydantic = { version = \"<2.0\", extras = [\"dotenv\"] }\nujson = \"^5.8.0\"\nsqlalchemy = { version = \"^2.0.21\", extras = [\"mypy\", \"asyncio\"] }\naiomysql = \"^0.1.1\"\nmysqlclient = \"^2.2.0\"\nsentry-sdk = \"^1.31.0\"\nloguru = \"^0.7.2\"\naiokafka = \"^0.8.1\"\nrequests = \"^2.31.0\"\nlangchain = \"^0.0.295\"\nopenai = \"^0.28.0\"\nwikipedia = \"^1.4.0\"\nreplicate = \"^0.8.4\"\nlanarky = \"^0.7.15\"\ntiktoken = \"^0.5.1\"\ngrpcio = \"^1.58.0\"\npinecone-client = \"^2.2.4\"\npython-multipart = \"^0.0.6\"\naws-secretsmanager-caching = \"^1.1.1.5\"\nbotocore = \"^1.31.51\"\nstripe = \"^5.5.0\"\ncryptography = \"^41.0.4\"\nhttpx = \"^0.25.0\"\n\n\n[tool.poetry.dev-dependencies]\nautopep8 = \"^2.0.4\"\npytest = \"^7.4.2\"\nflake8 = \"~6.0.0\"\nmypy = \"^1.5.1\"\nisort = \"^5.12.0\"\npre-commit = \"^3.4.0\"\nwemake-python-styleguide = \"^0.18.0\"\nblack = \"^23.9.1\"\nautoflake = \"^2.2.1\"\npytest-cov = \"^4.1.0\"\nanyio = \"^3.7.1\"\npytest-env = \"^0.8.2\"\n\n[tool.poetry.group.dev.dependencies]\ndotmap = \"^1.3.30\"\npytest-mock = \"^3.10.0\"\npytest-asyncio = \"^0.21.0\"\nmypy = \"^1.4.1\"\ntypes-requests = \"^2.31.0.1\"\ntypes-pytz = \"^2023.3.0.0\"\n\n[tool.isort]\nprofile = \"black\"\nmulti_line_output = 3\nsrc_paths = [\"reworkd_platform\"]\n\n[tool.mypy]\nstrict = true\nignore_missing_imports = true\nallow_subclassing_any = true\nallow_untyped_calls = true\npretty = true\nshow_error_codes = true\nimplicit_reexport = true\nallow_untyped_decorators = true\nwarn_unused_ignores = false\nwarn_return_any = false\nnamespace_packages = true\nexclude = \"tests\"\n\n[tool.pytest.ini_options]\nfilterwarnings = [\n    \"error\",\n    \"ignore::DeprecationWarning\",\n    \"ignore:.*unclosed.*:ResourceWarning\",\n    \"ignore::ImportWarning\",\n]\nenv = [\n    \"REWORKD_PLATFORM_DB_BASE=reworkd_platform_test\",\n]\n\n[build-system]\nrequires = [\"poetry-core>=1.0.0\"]\nbuild-backend = \"poetry.core.masonry.api\"\n"
  },
  {
    "path": "platform/reworkd_platform/__init__.py",
    "content": "\"\"\"reworkd_platform package.\"\"\"\n"
  },
  {
    "path": "platform/reworkd_platform/__main__.py",
    "content": "import uvicorn\n\nfrom reworkd_platform.settings import settings\n\n\ndef main() -> None:\n    \"\"\"Entrypoint of the application.\"\"\"\n    uvicorn.run(\n        \"reworkd_platform.web.application:get_app\",\n        workers=settings.workers_count,\n        host=settings.host,\n        port=settings.port,\n        reload=settings.reload,\n        log_level=settings.log_level.lower(),\n        factory=True,\n    )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "platform/reworkd_platform/conftest.py",
    "content": "from typing import Any, AsyncGenerator\n\nimport pytest\nfrom fastapi import FastAPI\nfrom httpx import AsyncClient\nfrom sqlalchemy.ext.asyncio import (\n    AsyncEngine,\n    AsyncSession,\n    async_sessionmaker,\n    create_async_engine,\n)\n\nfrom reworkd_platform.db.dependencies import get_db_session\nfrom reworkd_platform.db.utils import create_database, drop_database\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.application import get_app\n\n\n@pytest.fixture(scope=\"session\")\ndef anyio_backend() -> str:\n    \"\"\"\n    Backend for anyio pytest plugin.\n\n    :return: backend name.\n    \"\"\"\n    return \"asyncio\"\n\n\n@pytest.fixture(scope=\"session\")\nasync def _engine() -> AsyncGenerator[AsyncEngine, None]:\n    \"\"\"\n    Create engine and databases.\n\n    :yield: new engine.\n    \"\"\"\n    from reworkd_platform.db.meta import meta  # noqa: WPS433\n    from reworkd_platform.db.models import load_all_models  # noqa: WPS433\n\n    load_all_models()\n\n    await create_database()\n\n    engine = create_async_engine(str(settings.db_url))\n    async with engine.begin() as conn:\n        await conn.run_sync(meta.create_all)\n\n    try:\n        yield engine\n    finally:\n        await engine.dispose()\n        await drop_database()\n\n\n@pytest.fixture\nasync def dbsession(\n    _engine: AsyncEngine,\n) -> AsyncGenerator[AsyncSession, None]:\n    \"\"\"\n    Get session to database.\n\n    Fixture that returns a SQLAlchemy session with a SAVEPOINT, and the rollback to it\n    after the test completes.\n\n    :param _engine: current engine.\n    :yields: async session.\n    \"\"\"\n    connection = await _engine.connect()\n    trans = await connection.begin()\n\n    session_maker = async_sessionmaker(\n        connection,\n        expire_on_commit=False,\n    )\n    session = session_maker()\n\n    try:\n        yield session\n    finally:\n        await session.close()\n        await trans.rollback()\n        await connection.close()\n\n\n@pytest.fixture\ndef fastapi_app(dbsession: AsyncSession) -> FastAPI:\n    \"\"\"\n    Fixture for creating FastAPI app.\n\n    :return: fastapi app with mocked dependencies.\n    \"\"\"\n    application = get_app()\n    application.dependency_overrides[get_db_session] = lambda: dbsession\n    return application  # noqa: WPS331\n\n\n@pytest.fixture\nasync def client(\n    fastapi_app: FastAPI, anyio_backend: Any\n) -> AsyncGenerator[AsyncClient, None]:\n    \"\"\"\n    Fixture that creates client for requesting server.\n\n    :param fastapi_app: the application.\n    :yield: client for the app.\n    \"\"\"\n    async with AsyncClient(app=fastapi_app, base_url=\"http://test\") as ac:\n        yield ac\n"
  },
  {
    "path": "platform/reworkd_platform/constants.py",
    "content": "ENV_PREFIX = \"REWORKD_PLATFORM_\"\n"
  },
  {
    "path": "platform/reworkd_platform/db/__init__.py",
    "content": ""
  },
  {
    "path": "platform/reworkd_platform/db/base.py",
    "content": "import uuid\nfrom datetime import datetime\nfrom typing import Optional, Type, TypeVar\n\nfrom sqlalchemy import DateTime, String, func\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column\n\nfrom reworkd_platform.db.meta import meta\nfrom reworkd_platform.web.api.http_responses import not_found\n\nT = TypeVar(\"T\", bound=\"Base\")\n\n\nclass Base(DeclarativeBase):\n    \"\"\"Base for all models.\"\"\"\n\n    metadata = meta\n    id: Mapped[str] = mapped_column(\n        String,\n        primary_key=True,\n        default=lambda _: str(uuid.uuid4()),\n        unique=True,\n        nullable=False,\n    )\n\n    @classmethod\n    async def get(cls: Type[T], session: AsyncSession, id_: str) -> Optional[T]:\n        return await session.get(cls, id_)\n\n    @classmethod\n    async def get_or_404(cls: Type[T], session: AsyncSession, id_: str) -> T:\n        if model := await cls.get(session, id_):\n            return model\n\n        raise not_found(detail=f\"{cls.__name__}[{id_}] not found\")\n\n    async def save(self: T, session: AsyncSession) -> T:\n        session.add(self)\n        await session.flush()\n        return self\n\n    async def delete(self: T, session: AsyncSession) -> None:\n        await session.delete(self)\n\n\nclass TrackedModel(Base):\n    \"\"\"Base for all tracked models.\"\"\"\n\n    __abstract__ = True\n\n    create_date = mapped_column(\n        DateTime, name=\"create_date\", server_default=func.now(), nullable=False\n    )\n    update_date = mapped_column(\n        DateTime, name=\"update_date\", onupdate=func.now(), nullable=True\n    )\n    delete_date = mapped_column(DateTime, name=\"delete_date\", nullable=True)\n\n    async def delete(self, session: AsyncSession) -> None:\n        \"\"\"Marks the model as deleted.\"\"\"\n        self.delete_date = datetime.now()\n        await self.save(session)\n\n\nclass UserMixin:\n    user_id = mapped_column(String, name=\"user_id\", nullable=False)\n    organization_id = mapped_column(String, name=\"organization_id\", nullable=True)\n"
  },
  {
    "path": "platform/reworkd_platform/db/crud/__init__.py",
    "content": ""
  },
  {
    "path": "platform/reworkd_platform/db/crud/agent.py",
    "content": "from fastapi import HTTPException\nfrom sqlalchemy import and_, func, select\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom reworkd_platform.db.crud.base import BaseCrud\nfrom reworkd_platform.db.models.agent import AgentRun, AgentTask\nfrom reworkd_platform.schemas.agent import Loop_Step\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.errors import MaxLoopsError, MultipleSummaryError\n\n\nclass AgentCRUD(BaseCrud):\n    def __init__(self, session: AsyncSession, user: UserBase):\n        super().__init__(session)\n        self.user = user\n\n    async def create_run(self, goal: str) -> AgentRun:\n        return await AgentRun(\n            user_id=self.user.id,\n            goal=goal,\n        ).save(self.session)\n\n    async def create_task(self, run_id: str, type_: Loop_Step) -> AgentTask:\n        await self.validate_task_count(run_id, type_)\n        return await AgentTask(\n            run_id=run_id,\n            type_=type_,\n        ).save(self.session)\n\n    async def validate_task_count(self, run_id: str, type_: str) -> None:\n        if not await AgentRun.get(self.session, run_id):\n            raise HTTPException(404, f\"Run {run_id} not found\")\n\n        query = select(func.count(AgentTask.id)).where(\n            and_(\n                AgentTask.run_id == run_id,\n                AgentTask.type_ == type_,\n            )\n        )\n\n        task_count = (await self.session.execute(query)).scalar_one()\n        max_ = settings.max_loops\n\n        if task_count >= max_:\n            raise MaxLoopsError(\n                StopIteration(),\n                f\"Max loops of {max_} exceeded, shutting down.\",\n                429,\n                should_log=False,\n            )\n\n        if type_ == \"summarize\" and task_count > 1:\n            raise MultipleSummaryError(\n                StopIteration(),\n                \"Multiple summary tasks are not allowed\",\n                429,\n            )\n"
  },
  {
    "path": "platform/reworkd_platform/db/crud/base.py",
    "content": "from typing import TypeVar\n\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nT = TypeVar(\"T\", bound=\"BaseCrud\")\n\n\nclass BaseCrud:\n    def __init__(self, session: AsyncSession):\n        self.session = session\n"
  },
  {
    "path": "platform/reworkd_platform/db/crud/oauth.py",
    "content": "import secrets\nfrom typing import Dict, Optional\n\nfrom fastapi import Depends\nfrom sqlalchemy import func, select\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom reworkd_platform.db.crud.base import BaseCrud\nfrom reworkd_platform.db.dependencies import get_db_session\nfrom reworkd_platform.db.models.auth import OauthCredentials\nfrom reworkd_platform.schemas import UserBase\n\n\nclass OAuthCrud(BaseCrud):\n    @classmethod\n    async def inject(\n        cls,\n        session: AsyncSession = Depends(get_db_session),\n    ) -> \"OAuthCrud\":\n        return cls(session)\n\n    async def create_installation(\n        self, user: UserBase, provider: str, redirect_uri: Optional[str]\n    ) -> OauthCredentials:\n        return await OauthCredentials(\n            user_id=user.id,\n            organization_id=user.organization_id,\n            provider=provider,\n            state=secrets.token_hex(16),\n            redirect_uri=redirect_uri,\n        ).save(self.session)\n\n    async def get_installation_by_state(self, state: str) -> Optional[OauthCredentials]:\n        query = select(OauthCredentials).filter(OauthCredentials.state == state)\n\n        return (await self.session.execute(query)).scalar_one_or_none()\n\n    async def get_installation_by_user_id(\n        self, user_id: str, provider: str\n    ) -> Optional[OauthCredentials]:\n        query = select(OauthCredentials).filter(\n            OauthCredentials.user_id == user_id,\n            OauthCredentials.provider == provider,\n            OauthCredentials.access_token_enc.isnot(None),\n        )\n\n        return (await self.session.execute(query)).scalars().first()\n\n    async def get_installation_by_organization_id(\n        self, organization_id: str, provider: str\n    ) -> Optional[OauthCredentials]:\n        query = select(OauthCredentials).filter(\n            OauthCredentials.organization_id == organization_id,\n            OauthCredentials.provider == provider,\n            OauthCredentials.access_token_enc.isnot(None),\n            OauthCredentials.organization_id.isnot(None),\n        )\n\n        return (await self.session.execute(query)).scalars().first()\n\n    async def get_all(self, user: UserBase) -> Dict[str, str]:\n        query = (\n            select(\n                OauthCredentials.provider,\n                func.any_value(OauthCredentials.access_token_enc),\n            )\n            .filter(\n                OauthCredentials.access_token_enc.isnot(None),\n                OauthCredentials.organization_id == user.organization_id,\n            )\n            .group_by(OauthCredentials.provider)\n        )\n\n        return {\n            provider: token\n            for provider, token in (await self.session.execute(query)).all()\n        }\n"
  },
  {
    "path": "platform/reworkd_platform/db/crud/organization.py",
    "content": "# from\nfrom typing import List, Optional\n\nfrom fastapi import Depends\nfrom pydantic import BaseModel\nfrom sqlalchemy import and_, select\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom sqlalchemy.orm import aliased\n\nfrom reworkd_platform.db.crud.base import BaseCrud\nfrom reworkd_platform.db.dependencies import get_db_session\nfrom reworkd_platform.db.models.auth import Organization, OrganizationUser\nfrom reworkd_platform.db.models.user import User\nfrom reworkd_platform.schemas import UserBase\nfrom reworkd_platform.web.api.dependencies import get_current_user\n\n\nclass OrgUser(BaseModel):\n    id: str\n    role: str\n    user: UserBase\n\n\nclass OrganizationUsers(BaseModel):\n    id: str\n    name: str\n    users: List[OrgUser]\n\n\nclass OrganizationCrud(BaseCrud):\n    def __init__(self, session: AsyncSession, user: UserBase):\n        super().__init__(session)\n        self.user = user\n\n    @classmethod\n    def inject(\n        cls,\n        session: AsyncSession = Depends(get_db_session),\n        user: UserBase = Depends(get_current_user),\n    ) -> \"OrganizationCrud\":\n        return cls(session, user)\n\n    async def create_organization(self, name: str) -> Organization:\n        return await Organization(\n            created_by=self.user.id,\n            name=name,\n        ).save(self.session)\n\n    async def get_by_name(self, name: str) -> Optional[OrganizationUsers]:\n        owner = aliased(OrganizationUser, name=\"owner\")\n\n        query = (\n            select(\n                Organization,\n                User,\n                OrganizationUser,\n            )\n            .join(\n                OrganizationUser,\n                and_(\n                    Organization.id == OrganizationUser.organization_id,\n                ),\n            )\n            .join(\n                User,\n                User.id == OrganizationUser.user_id,\n            )\n            .join(  # Owner\n                owner,\n                and_(\n                    OrganizationUser.organization_id == Organization.id,\n                    OrganizationUser.user_id == self.user.id,\n                ),\n            )\n            .filter(Organization.name == name)\n        )\n\n        rows = (await self.session.execute(query)).all()\n        if not rows:\n            return None\n\n        org: Organization = rows[0][0]\n        return OrganizationUsers(\n            id=org.id,\n            name=org.name,\n            users=[\n                OrgUser(\n                    id=org_user.user_id,\n                    role=org_user.role,\n                    user=UserBase(\n                        id=user.id,\n                        email=user.email,\n                        name=user.name,\n                    ),\n                )\n                for [_, user, org_user] in rows\n            ],\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/db/crud/user.py",
    "content": "from typing import Optional\n\nfrom sqlalchemy import and_, select\nfrom sqlalchemy.orm import selectinload\n\nfrom reworkd_platform.db.crud.base import BaseCrud\nfrom reworkd_platform.db.models.auth import OrganizationUser\nfrom reworkd_platform.db.models.user import UserSession\n\n\nclass UserCrud(BaseCrud):\n    async def get_user_session(self, token: str) -> UserSession:\n        query = (\n            select(UserSession)\n            .filter(UserSession.session_token == token)\n            .options(selectinload(UserSession.user))\n        )\n        return (await self.session.execute(query)).scalar_one()\n\n    async def get_user_organization(\n        self, user_id: str, organization_id: str\n    ) -> Optional[OrganizationUser]:\n        query = select(OrganizationUser).filter(\n            and_(\n                OrganizationUser.user_id == user_id,\n                OrganizationUser.organization_id == organization_id,\n            )\n        )\n\n        # TODO: Only returns the first organization\n        return (await self.session.execute(query)).scalar()\n"
  },
  {
    "path": "platform/reworkd_platform/db/dependencies.py",
    "content": "from typing import AsyncGenerator\n\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom starlette.requests import Request\n\n\nasync def get_db_session(request: Request) -> AsyncGenerator[AsyncSession, None]:\n    \"\"\"\n    Create and get database session.\n\n    :param request: current request.\n    :yield: database session.\n    \"\"\"\n    session: AsyncSession = request.app.state.db_session_factory()\n\n    try:  # noqa: WPS501\n        yield session\n        await session.commit()\n    finally:\n        await session.close()\n"
  },
  {
    "path": "platform/reworkd_platform/db/meta.py",
    "content": "import sqlalchemy as sa\n\nmeta = sa.MetaData()\n"
  },
  {
    "path": "platform/reworkd_platform/db/models/__init__.py",
    "content": "\"\"\"reworkd_platform models.\"\"\"\nimport pkgutil\nfrom pathlib import Path\n\n\ndef load_all_models() -> None:\n    \"\"\"Load all models from this folder.\"\"\"\n    package_dir = Path(__file__).resolve().parent\n    modules = pkgutil.walk_packages(\n        path=[str(package_dir)],\n        prefix=\"reworkd_platform.db.models.\",\n    )\n    for module in modules:\n        __import__(module.name)  # noqa: WPS421\n"
  },
  {
    "path": "platform/reworkd_platform/db/models/agent.py",
    "content": "from sqlalchemy import DateTime, String, Text, func\nfrom sqlalchemy.orm import mapped_column\n\nfrom reworkd_platform.db.base import Base\n\n\nclass AgentRun(Base):\n    __tablename__ = \"agent_run\"\n\n    user_id = mapped_column(String, nullable=False)\n    goal = mapped_column(Text, nullable=False)\n    create_date = mapped_column(\n        DateTime, name=\"create_date\", server_default=func.now(), nullable=False\n    )\n\n\nclass AgentTask(Base):\n    __tablename__ = \"agent_task\"\n\n    run_id = mapped_column(String, nullable=False)\n    type_ = mapped_column(String, nullable=False, name=\"type\")\n    create_date = mapped_column(\n        DateTime, name=\"create_date\", server_default=func.now(), nullable=False\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/db/models/auth.py",
    "content": "from sqlalchemy import DateTime, String\nfrom sqlalchemy.orm import mapped_column\n\nfrom reworkd_platform.db.base import TrackedModel\n\n\nclass Organization(TrackedModel):\n    __tablename__ = \"organization\"\n\n    name = mapped_column(String, nullable=False)\n    created_by = mapped_column(String, nullable=False)\n\n\nclass OrganizationUser(TrackedModel):\n    __tablename__ = \"organization_user\"\n\n    user_id = mapped_column(String, nullable=False)\n    organization_id = mapped_column(String, nullable=False)\n    role = mapped_column(String, nullable=False, default=\"member\")\n\n\nclass OauthCredentials(TrackedModel):\n    __tablename__ = \"oauth_credentials\"\n\n    user_id = mapped_column(String, nullable=False)\n    organization_id = mapped_column(String, nullable=True)\n    provider = mapped_column(String, nullable=False)\n    state = mapped_column(String, nullable=False)\n    redirect_uri = mapped_column(String, nullable=False)\n\n    # Post-installation\n    token_type = mapped_column(String, nullable=True)\n    access_token_enc = mapped_column(String, nullable=True)\n    access_token_expiration = mapped_column(DateTime, nullable=True)\n    refresh_token_enc = mapped_column(String, nullable=True)\n    scope = mapped_column(String, nullable=True)\n"
  },
  {
    "path": "platform/reworkd_platform/db/models/user.py",
    "content": "from typing import List\n\nfrom sqlalchemy import DateTime, ForeignKey, Index, String, text\nfrom sqlalchemy.orm import Mapped, mapped_column, relationship\n\nfrom reworkd_platform.db.base import Base\n\n\nclass UserSession(Base):\n    __tablename__ = \"Session\"\n\n    session_token = mapped_column(String, unique=True, name=\"sessionToken\")\n    user_id = mapped_column(\n        String, ForeignKey(\"User.id\", ondelete=\"CASCADE\"), name=\"userId\"\n    )\n    expires = mapped_column(DateTime)\n\n    user = relationship(\"User\")\n\n    __table_args__ = (Index(\"user_id\"),)\n\n\nclass User(Base):\n    __tablename__ = \"User\"\n\n    name = mapped_column(String, nullable=True)\n    email = mapped_column(String, nullable=True, unique=True)\n    email_verified = mapped_column(DateTime, nullable=True, name=\"emailVerified\")\n    image = mapped_column(String, nullable=True)\n    create_date = mapped_column(\n        DateTime, server_default=text(\"(now())\"), name=\"createDate\"\n    )\n\n    sessions: Mapped[List[\"UserSession\"]] = relationship(\n        \"UserSession\", back_populates=\"user\"\n    )\n\n    __table_args__ = (Index(\"email\"),)\n"
  },
  {
    "path": "platform/reworkd_platform/db/utils.py",
    "content": "from ssl import CERT_REQUIRED\n\nfrom sqlalchemy import text\nfrom sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine\n\nfrom reworkd_platform.services.ssl import get_ssl_context\nfrom reworkd_platform.settings import settings\n\n\ndef create_engine() -> AsyncEngine:\n    \"\"\"\n    Creates SQLAlchemy engine instance.\n\n    :return: SQLAlchemy engine instance.\n    \"\"\"\n    if settings.environment == \"development\":\n        return create_async_engine(\n            str(settings.db_url),\n            echo=settings.db_echo,\n        )\n\n    ssl_context = get_ssl_context(settings)\n    ssl_context.verify_mode = CERT_REQUIRED\n    connect_args = {\"ssl\": ssl_context}\n\n    return create_async_engine(\n        str(settings.db_url),\n        echo=settings.db_echo,\n        connect_args=connect_args,\n    )\n\n\nasync def create_database() -> None:\n    \"\"\"Create a database.\"\"\"\n    engine = create_async_engine(str(settings.db_url.with_path(\"/mysql\")))\n\n    async with engine.connect() as conn:\n        database_existance = await conn.execute(\n            text(\n                \"SELECT 1 FROM INFORMATION_SCHEMA.SCHEMATA\"  # noqa: S608\n                f\" WHERE SCHEMA_NAME='{settings.db_base}';\",\n            )\n        )\n        database_exists = database_existance.scalar() == 1\n\n    if database_exists:\n        await drop_database()\n\n    async with engine.connect() as conn:  # noqa: WPS440\n        await conn.execute(text(f\"CREATE DATABASE {settings.db_base};\"))\n\n\nasync def drop_database() -> None:\n    \"\"\"Drop current database.\"\"\"\n    engine = create_async_engine(str(settings.db_url.with_path(\"/mysql\")))\n    async with engine.connect() as conn:\n        await conn.execute(text(f\"DROP DATABASE {settings.db_base};\"))\n"
  },
  {
    "path": "platform/reworkd_platform/logging.py",
    "content": "import logging\nimport sys\nfrom typing import Union\n\nfrom loguru import logger\n\nfrom reworkd_platform.settings import settings\n\n\nclass InterceptHandler(logging.Handler):\n    \"\"\"\n    Default handler from examples in loguru documentation.\n\n    This handler intercepts all log requests and\n    passes them to loguru.\n\n    For more info see:\n    https://loguru.readthedocs.io/en/stable/overview.html#entirely-compatible-with-standard-logging\n    \"\"\"\n\n    def emit(self, record: logging.LogRecord) -> None:  # pragma: no cover\n        \"\"\"\n        Propagates logs to loguru.\n\n        :param record: record to log.\n        \"\"\"\n        try:\n            level: Union[str, int] = logger.level(record.levelname).name\n        except ValueError:\n            level = record.levelno\n\n        # Find caller from where originated the logged message\n        frame, depth = logging.currentframe(), 2\n        while frame.f_code.co_filename == logging.__file__:\n            frame = frame.f_back  # type: ignore\n            depth += 1\n\n        logger.opt(depth=depth, exception=record.exc_info).log(\n            level,\n            record.getMessage(),\n        )\n\n\ndef configure_logging() -> None:  # pragma: no cover\n    \"\"\"Configures logging.\"\"\"\n    intercept_handler = InterceptHandler()\n\n    logging.basicConfig(handlers=[intercept_handler], level=logging.NOTSET)\n\n    for logger_name in logging.root.manager.loggerDict:\n        if logger_name.startswith(\"uvicorn.\"):\n            logging.getLogger(logger_name).handlers = []\n\n    # change handler for default uvicorn logger\n    logging.getLogger(\"uvicorn\").handlers = [intercept_handler]\n    logging.getLogger(\"uvicorn.access\").handlers = [intercept_handler]\n\n    # set logs output, level and format\n    logger.remove()\n    logger.add(\n        sys.stdout,\n        level=settings.log_level,\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/schemas/__init__.py",
    "content": "from .agent import ModelSettings\nfrom .user import UserBase\n"
  },
  {
    "path": "platform/reworkd_platform/schemas/agent.py",
    "content": "from datetime import datetime\nfrom typing import Any, Dict, List, Literal, Optional\n\nfrom pydantic import BaseModel, Field, validator\n\nfrom reworkd_platform.web.api.agent.analysis import Analysis\n\nLLM_Model = Literal[\n    \"gpt-3.5-turbo\",\n    \"gpt-3.5-turbo-16k\",\n    \"gpt-4\",\n]\nLoop_Step = Literal[\n    \"start\",\n    \"analyze\",\n    \"execute\",\n    \"create\",\n    \"summarize\",\n    \"chat\",\n]\nLLM_MODEL_MAX_TOKENS: Dict[LLM_Model, int] = {\n    \"gpt-3.5-turbo\": 4000,\n    \"gpt-3.5-turbo-16k\": 16000,\n    \"gpt-4\": 8000,\n}\n\n\nclass ModelSettings(BaseModel):\n    model: LLM_Model = Field(default=\"gpt-3.5-turbo\")\n    custom_api_key: Optional[str] = Field(default=None)\n    temperature: float = Field(default=0.9, ge=0.0, le=1.0)\n    max_tokens: int = Field(default=500, ge=0)\n    language: str = Field(default=\"English\")\n\n    @validator(\"max_tokens\")\n    def validate_max_tokens(cls, v: float, values: Dict[str, Any]) -> float:\n        model = values[\"model\"]\n        if v > (max_tokens := LLM_MODEL_MAX_TOKENS[model]):\n            raise ValueError(f\"Model {model} only supports {max_tokens} tokens\")\n        return v\n\n\nclass AgentRunCreate(BaseModel):\n    goal: str\n    model_settings: ModelSettings = Field(default=ModelSettings())\n\n\nclass AgentRun(AgentRunCreate):\n    run_id: str\n\n\nclass AgentTaskAnalyze(AgentRun):\n    task: str\n    tool_names: List[str] = Field(default=[])\n    model_settings: ModelSettings = Field(default=ModelSettings())\n\n\nclass AgentTaskExecute(AgentRun):\n    task: str\n    analysis: Analysis\n\n\nclass AgentTaskCreate(AgentRun):\n    tasks: List[str] = Field(default=[])\n    last_task: Optional[str] = Field(default=None)\n    result: Optional[str] = Field(default=None)\n    completed_tasks: List[str] = Field(default=[])\n\n\nclass AgentSummarize(AgentRun):\n    results: List[str] = Field(default=[])\n\n\nclass AgentChat(AgentRun):\n    message: str\n    results: List[str] = Field(default=[])\n\n\nclass NewTasksResponse(BaseModel):\n    run_id: str\n    new_tasks: List[str] = Field(alias=\"newTasks\")\n\n\nclass RunCount(BaseModel):\n    count: int\n    first_run: Optional[datetime]\n    last_run: Optional[datetime]\n"
  },
  {
    "path": "platform/reworkd_platform/schemas/user.py",
    "content": "from typing import Optional\n\nfrom pydantic import BaseModel, Field\n\n\nclass OrganizationRole(BaseModel):\n    id: str\n    role: str\n    organization_id: str\n\n\nclass UserBase(BaseModel):\n    id: str\n    name: Optional[str]\n    email: Optional[str]\n    image: Optional[str] = Field(default=None)\n    organization: Optional[OrganizationRole] = Field(default=None)\n\n    @property\n    def organization_id(self) -> Optional[str]:\n        return self.organization.organization_id if self.organization else None\n"
  },
  {
    "path": "platform/reworkd_platform/services/__init__.py",
    "content": "\"\"\"Services for reworkd_platform.\"\"\"\n"
  },
  {
    "path": "platform/reworkd_platform/services/anthropic.py",
    "content": "from typing import Any, Optional\n\nfrom anthropic import AsyncAnthropic\nfrom pydantic import BaseModel\n\n\nclass AbstractPrompt(BaseModel):\n    def to_string(self) -> str:\n        raise NotImplementedError\n\n\nclass HumanAssistantPrompt(AbstractPrompt):\n    assistant_prompt: str\n    human_prompt: str\n\n    def to_string(self) -> str:\n        return (\n            f\"\"\"\\n\\nHuman: {self.human_prompt}\\n\\nAssistant: {self.assistant_prompt}\"\"\"\n        )\n\n\nclass ClaudeService:\n    def __init__(self, api_key: Optional[str], model: str = \"claude-2\"):\n        self.claude = AsyncAnthropic(api_key=api_key)\n        self.model = model\n\n    async def completion(\n        self,\n        prompt: AbstractPrompt,\n        max_tokens_to_sample: int,\n        temperature: int = 0,\n        **kwargs: Any,\n    ) -> str:\n        return (\n            await self.claude.completions.create(\n                model=self.model,\n                prompt=prompt.to_string(),\n                max_tokens_to_sample=max_tokens_to_sample,\n                temperature=temperature,\n                **kwargs,\n            )\n        ).completion.strip()\n"
  },
  {
    "path": "platform/reworkd_platform/services/aws/__init__.py",
    "content": "import boto3\nfrom botocore.exceptions import ProfileNotFound\n\ntry:\n    boto3.setup_default_session(profile_name=\"dev\")\nexcept ProfileNotFound:\n    pass\n"
  },
  {
    "path": "platform/reworkd_platform/services/aws/s3.py",
    "content": "import io\nimport os\nfrom typing import Dict, List, Optional\n\nfrom aiohttp import ClientError\nfrom boto3 import client as boto3_client\nfrom loguru import logger\nfrom pydantic import BaseModel\n\nREGION = \"us-east-1\"\n\n\n# noinspection SpellCheckingInspection\nclass PresignedPost(BaseModel):\n    url: str\n    fields: Dict[str, str]\n\n\nclass SimpleStorageService:\n    # TODO: would be great if with could make this async\n\n    def __init__(self, bucket: Optional[str]) -> None:\n        if not bucket:\n            raise ValueError(\"Bucket name must be provided\")\n\n        self._client = boto3_client(\"s3\", region_name=REGION)\n        self._bucket = bucket\n\n    def create_presigned_upload_url(\n        self,\n        object_name: str,\n    ) -> PresignedPost:\n        return PresignedPost(\n            **self._client.generate_presigned_post(\n                Bucket=self._bucket,\n                Key=object_name,\n            )\n        )\n\n    def create_presigned_download_url(self, object_name: str) -> str:\n        return self._client.generate_presigned_url(\n            \"get_object\",\n            Params={\"Bucket\": self._bucket, \"Key\": object_name},\n        )\n\n    def upload_to_bucket(\n        self,\n        object_name: str,\n        file: io.BytesIO,\n    ) -> None:\n        try:\n            self._client.put_object(\n                Bucket=self._bucket, Key=object_name, Body=file.getvalue()\n            )\n        except ClientError as e:\n            logger.error(e)\n            raise e\n\n    def download_file(self, object_name: str, local_filename: str) -> None:\n        self._client.download_file(\n            Bucket=self._bucket, Key=object_name, Filename=local_filename\n        )\n\n    def list_keys(self, prefix: str) -> List[str]:\n        files = self._client.list_objects_v2(Bucket=self._bucket, Prefix=prefix)\n        if \"Contents\" not in files:\n            return []\n\n        return [file[\"Key\"] for file in files[\"Contents\"]]\n\n    def download_folder(self, prefix: str, path: str) -> List[str]:\n        local_files = []\n        for key in self.list_keys(prefix):\n            local_filename = os.path.join(path, key.split(\"/\")[-1])\n            self.download_file(key, local_filename)\n            local_files.append(local_filename)\n\n        return local_files\n\n    def delete_folder(self, prefix: str) -> None:\n        keys = self.list_keys(prefix)\n        self._client.delete_objects(\n            Bucket=self._bucket,\n            Delete={\"Objects\": [{\"Key\": key} for key in keys]},\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/services/oauth_installers.py",
    "content": "import json\nfrom abc import ABC, abstractmethod\nfrom datetime import datetime, timedelta\nfrom urllib.parse import urlencode\n\nimport aiohttp\nfrom fastapi import Depends, Path\n\nfrom reworkd_platform.db.crud.oauth import OAuthCrud\nfrom reworkd_platform.db.models.auth import OauthCredentials\nfrom reworkd_platform.schemas import UserBase\nfrom reworkd_platform.services.security import encryption_service\nfrom reworkd_platform.settings import Settings\nfrom reworkd_platform.settings import settings as platform_settings\nfrom reworkd_platform.web.api.http_responses import forbidden\n\n\nclass OAuthInstaller(ABC):\n    def __init__(self, crud: OAuthCrud, settings: Settings):\n        self.crud = crud\n        self.settings = settings\n\n    @abstractmethod\n    async def install(self, user: UserBase, redirect_uri: str) -> str:\n        raise NotImplementedError()\n\n    @abstractmethod\n    async def install_callback(self, code: str, state: str) -> OauthCredentials:\n        raise NotImplementedError()\n\n    @abstractmethod\n    async def uninstall(self, user: UserBase) -> bool:\n        raise NotImplementedError()\n\n    @staticmethod\n    def store_access_token(creds: OauthCredentials, access_token: str) -> None:\n        creds.access_token_enc = encryption_service.encrypt(access_token)\n\n    @staticmethod\n    def store_refresh_token(creds: OauthCredentials, refresh_token: str) -> None:\n        creds.refresh_token_enc = encryption_service.encrypt(refresh_token)\n\n\nclass SIDInstaller(OAuthInstaller):\n    PROVIDER = \"sid\"\n\n    async def install(self, user: UserBase, redirect_uri: str) -> str:\n        # gracefully handle the case where the installation already exists\n        # this can happen if the user starts the process from multiple tabs\n        installation = await self.crud.get_installation_by_user_id(\n            user.id, self.PROVIDER\n        )\n        if not installation:\n            installation = await self.crud.create_installation(\n                user,\n                self.PROVIDER,\n                redirect_uri,\n            )\n        scopes = [\"data:query\", \"offline_access\"]\n        params = {\n            \"client_id\": self.settings.sid_client_id,\n            \"redirect_uri\": self.settings.sid_redirect_uri,\n            \"response_type\": \"code\",\n            \"scope\": \" \".join(scopes),\n            \"state\": installation.state,\n            \"audience\": \"https://api.sid.ai/api/v1/\",\n        }\n        auth_url = \"https://me.sid.ai/api/oauth/authorize\"\n        auth_url += \"?\" + urlencode(params)\n        return auth_url\n\n    async def install_callback(self, code: str, state: str) -> OauthCredentials:\n        creds = await self.crud.get_installation_by_state(state)\n        if not creds:\n            raise forbidden()\n        req = {\n            \"grant_type\": \"authorization_code\",\n            \"client_id\": self.settings.sid_client_id,\n            \"client_secret\": self.settings.sid_client_secret,\n            \"redirect_uri\": self.settings.sid_redirect_uri,\n            \"code\": code,\n        }\n        async with aiohttp.ClientSession() as session:\n            async with session.post(\n                \"https://auth.sid.ai/oauth/token\",\n                headers={\n                    \"Content-Type\": \"application/json\",\n                    \"Accept\": \"application/json\",\n                },\n                data=json.dumps(req),\n            ) as response:\n                res_data = await response.json()\n\n        OAuthInstaller.store_access_token(creds, res_data[\"access_token\"])\n        OAuthInstaller.store_refresh_token(creds, res_data[\"refresh_token\"])\n        creds.access_token_expiration = datetime.now() + timedelta(\n            seconds=res_data[\"expires_in\"]\n        )\n        return await creds.save(self.crud.session)\n\n    async def uninstall(self, user: UserBase) -> bool:\n        creds = await self.crud.get_installation_by_user_id(user.id, self.PROVIDER)\n        # check if credentials exist and contain a refresh token\n        if not creds:\n            return False\n\n        # use refresh token to revoke access\n        delete_token = encryption_service.decrypt(creds.refresh_token_enc)\n        # delete credentials from database\n        await self.crud.session.delete(creds)\n\n        # revoke refresh token\n        async with aiohttp.ClientSession() as session:\n            await session.post(\n                \"https://auth.sid.ai/oauth/revoke\",\n                headers={\n                    \"Content-Type\": \"application/json\",\n                },\n                data=json.dumps(\n                    {\n                        \"client_id\": self.settings.sid_client_id,\n                        \"client_secret\": self.settings.sid_client_secret,\n                        \"token\": delete_token,\n                    }\n                ),\n            )\n        return True\n\n\nintegrations = {\n    SIDInstaller.PROVIDER: SIDInstaller,\n}\n\n\ndef installer_factory(\n    provider: str = Path(description=\"OAuth Provider\"),\n    crud: OAuthCrud = Depends(OAuthCrud.inject),\n) -> OAuthInstaller:\n    \"\"\"Factory for OAuth installers\n    Args:\n        provider (str): OAuth Provider (can be slack, github, etc.) (injected)\n        crud (OAuthCrud): OAuth Crud (injected)\n    \"\"\"\n\n    if provider in integrations:\n        return integrations[provider](crud, platform_settings)\n    raise NotImplementedError()\n"
  },
  {
    "path": "platform/reworkd_platform/services/pinecone/__init__.py",
    "content": ""
  },
  {
    "path": "platform/reworkd_platform/services/pinecone/lifetime.py",
    "content": "import pinecone\n\nfrom reworkd_platform.settings import settings\n\n\ndef init_pinecone() -> None:\n    if settings.pinecone_api_key and settings.pinecone_environment:\n        pinecone.init(\n            api_key=settings.pinecone_api_key,\n            environment=settings.pinecone_environment,\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/services/pinecone/pinecone.py",
    "content": "from __future__ import annotations\n\nimport uuid\nfrom typing import Any, Dict, List\n\nfrom langchain.embeddings import OpenAIEmbeddings\nfrom langchain.embeddings.base import Embeddings\nfrom pinecone import Index  # import doesnt work on plane wifi\nfrom pydantic import BaseModel\n\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.timer import timed_function\nfrom reworkd_platform.web.api.memory.memory import AgentMemory\n\nOPENAI_EMBEDDING_DIM = 1536\n\n\nclass Row(BaseModel):\n    id: str\n    values: List[float]\n    metadata: Dict[str, Any] = {}\n\n\nclass QueryResult(BaseModel):\n    id: str\n    score: float\n    metadata: Dict[str, Any] = {}\n\n\nclass PineconeMemory(AgentMemory):\n    \"\"\"\n    Wrapper around pinecone\n    \"\"\"\n\n    def __init__(self, index_name: str, namespace: str = \"\"):\n        self.index = Index(settings.pinecone_index_name)\n        self.namespace = namespace or index_name\n\n    @timed_function(level=\"DEBUG\")\n    def __enter__(self) -> AgentMemory:\n        self.embeddings: Embeddings = OpenAIEmbeddings(\n            client=None,  # Meta private value but mypy will complain its missing\n            openai_api_key=settings.openai_api_key,\n        )\n\n        return self\n\n    def __exit__(self, *args: Any, **kwargs: Any) -> None:\n        pass\n\n    @timed_function(level=\"DEBUG\")\n    def reset_class(self) -> None:\n        self.index.delete(delete_all=True, namespace=self.namespace)\n\n    @timed_function(level=\"DEBUG\")\n    def add_tasks(self, tasks: List[str]) -> List[str]:\n        if len(tasks) == 0:\n            return []\n\n        embeds = self.embeddings.embed_documents(tasks)\n\n        if len(tasks) != len(embeds):\n            raise ValueError(\"Embeddings and tasks are not the same length\")\n\n        rows = [\n            Row(values=vector, metadata={\"text\": tasks[i]}, id=str(uuid.uuid4()))\n            for i, vector in enumerate(embeds)\n        ]\n\n        self.index.upsert(\n            vectors=[row.dict() for row in rows], namespace=self.namespace\n        )\n\n        return [row.id for row in rows]\n\n    @timed_function(level=\"DEBUG\")\n    def get_similar_tasks(\n        self, text: str, score_threshold: float = 0.95\n    ) -> List[QueryResult]:\n        # Get similar tasks\n        vector = self.embeddings.embed_query(text)\n        results = self.index.query(\n            vector=vector,\n            top_k=5,\n            include_metadata=True,\n            include_values=True,\n            namespace=self.namespace,\n        )\n\n        return [\n            QueryResult(id=row.id, score=row.score, metadata=row.metadata)\n            for row in getattr(results, \"matches\", [])\n            if row.score > score_threshold\n        ]\n\n    @staticmethod\n    def should_use() -> bool:\n        return False\n"
  },
  {
    "path": "platform/reworkd_platform/services/security.py",
    "content": "from typing import Union\n\nfrom cryptography.fernet import Fernet, InvalidToken\n\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.http_responses import forbidden\n\n\nclass EncryptionService:\n    def __init__(self, secret: bytes):\n        self.fernet = Fernet(secret)\n\n    def encrypt(self, text: str) -> bytes:\n        return self.fernet.encrypt(text.encode(\"utf-8\"))\n\n    def decrypt(self, encoded_bytes: Union[bytes, str]) -> str:\n        try:\n            return self.fernet.decrypt(encoded_bytes).decode(\"utf-8\")\n        except InvalidToken:\n            raise forbidden()\n\n\nencryption_service = EncryptionService(settings.secret_signing_key.encode())\n"
  },
  {
    "path": "platform/reworkd_platform/services/ssl.py",
    "content": "from ssl import SSLContext, create_default_context\nfrom typing import List, Optional\n\nfrom reworkd_platform.settings import Settings\n\nMACOS_CERT_PATH = \"/etc/ssl/cert.pem\"\nDOCKER_CERT_PATH = \"/etc/ssl/certs/ca-certificates.crt\"\n\n\ndef get_ssl_context(\n    settings: Settings, paths: Optional[List[str]] = None\n) -> SSLContext:\n    if settings.db_ca_path:\n        return create_default_context(cafile=settings.db_ca_path)\n\n    for path in paths or [MACOS_CERT_PATH, DOCKER_CERT_PATH]:\n        try:\n            return create_default_context(cafile=path)\n        except FileNotFoundError:\n            continue\n\n    raise ValueError(\n        \"No CA certificates found for your OS. To fix this, please run change \"\n        \"db_ca_path in your settings.py to point to a valid CA certificate file.\"\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/services/tokenizer/__init__.py",
    "content": "\"\"\"Token Service\"\"\"\n"
  },
  {
    "path": "platform/reworkd_platform/services/tokenizer/dependencies.py",
    "content": "from fastapi import Request\n\nfrom reworkd_platform.services.tokenizer.token_service import TokenService\n\n\ndef get_token_service(request: Request) -> TokenService:\n    return TokenService(request.app.state.token_encoding)\n"
  },
  {
    "path": "platform/reworkd_platform/services/tokenizer/lifetime.py",
    "content": "import tiktoken\nfrom fastapi import FastAPI\n\nENCODING_NAME = \"cl100k_base\"  # gpt-4, gpt-3.5-turbo, text-embedding-ada-002\n\n\ndef init_tokenizer(app: FastAPI) -> None:  # pragma: no cover\n    \"\"\"\n    Initialize tokenizer.\n\n    TikToken downloads the encoding on start. It is then\n    stored in the state of the application.\n\n    :param app: current application.\n    \"\"\"\n    app.state.token_encoding = tiktoken.get_encoding(ENCODING_NAME)\n"
  },
  {
    "path": "platform/reworkd_platform/services/tokenizer/token_service.py",
    "content": "from tiktoken import Encoding, get_encoding\n\nfrom reworkd_platform.schemas.agent import LLM_MODEL_MAX_TOKENS, LLM_Model\nfrom reworkd_platform.web.api.agent.model_factory import WrappedChatOpenAI\n\n\nclass TokenService:\n    def __init__(self, encoding: Encoding):\n        self.encoding = encoding\n\n    @classmethod\n    def create(cls, encoding: str = \"cl100k_base\") -> \"TokenService\":\n        return cls(get_encoding(encoding))\n\n    def tokenize(self, text: str) -> list[int]:\n        return self.encoding.encode(text)\n\n    def detokenize(self, tokens: list[int]) -> str:\n        return self.encoding.decode(tokens)\n\n    def count(self, text: str) -> int:\n        return len(self.tokenize(text))\n\n    def get_completion_space(self, model: LLM_Model, *prompts: str) -> int:\n        max_allowed_tokens = LLM_MODEL_MAX_TOKENS.get(model, 4000)\n        prompt_tokens = sum([self.count(p) for p in prompts])\n        return max_allowed_tokens - prompt_tokens\n\n    def calculate_max_tokens(self, model: WrappedChatOpenAI, *prompts: str) -> None:\n        requested_tokens = self.get_completion_space(model.model_name, *prompts)\n\n        model.max_tokens = min(model.max_tokens, requested_tokens)\n        model.max_tokens = max(model.max_tokens, 1)\n"
  },
  {
    "path": "platform/reworkd_platform/settings.py",
    "content": "import platform\nfrom pathlib import Path\nfrom tempfile import gettempdir\nfrom typing import List, Literal, Optional, Union\n\nfrom pydantic import BaseSettings\nfrom yarl import URL\n\nfrom reworkd_platform.constants import ENV_PREFIX\n\nTEMP_DIR = Path(gettempdir())\n\nLOG_LEVEL = Literal[\n    \"NOTSET\",\n    \"DEBUG\",\n    \"INFO\",\n    \"WARNING\",\n    \"ERROR\",\n    \"FATAL\",\n]\n\n\nSASL_MECHANISM = Literal[\n    \"PLAIN\",\n    \"SCRAM-SHA-256\",\n]\n\nENVIRONMENT = Literal[\n    \"development\",\n    \"production\",\n]\n\n\nclass Settings(BaseSettings):\n    \"\"\"\n    Application settings.\n\n    These parameters can be configured\n    with environment variables.\n    \"\"\"\n\n    # Application settings\n    host: str = \"127.0.0.1\"\n    port: int = 8000\n    workers_count: int = 1\n    reload: bool = True\n    environment: ENVIRONMENT = \"development\"\n    log_level: LOG_LEVEL = \"INFO\"\n\n    # Make sure you update this with your own secret key\n    # Must be 32 url-safe base64-encoded bytes\n    secret_signing_key: str = \"JF52S66x6WMoifP5gZreiguYs9LYMn0lkXqgPYoNMD0=\"\n\n    # OpenAI\n    openai_api_base: str = \"https://api.openai.com/v1\"\n    openai_api_key: str = \"<Should be updated via env>\"\n    openai_api_version: str = \"2023-08-01-preview\"\n    azure_openai_deployment_name: str = \"<Should be updated via env if using azure>\"\n\n    # Helicone\n    helicone_api_base: str = \"https://oai.hconeai.com/v1\"\n    helicone_api_key: Optional[str] = None\n\n    replicate_api_key: Optional[str] = None\n    serp_api_key: Optional[str] = None\n\n    # Frontend URL for CORS\n    frontend_url: str = \"http://localhost:3000\"\n    allowed_origins_regex: Optional[str] = None\n\n    # Variables for the database\n    db_host: str = \"localhost\"\n    db_port: int = 3308\n    db_user: str = \"reworkd_platform\"\n    db_pass: str = \"reworkd_platform\"\n    db_base: str = \"reworkd_platform\"\n    db_echo: bool = False\n    db_ca_path: Optional[str] = None\n\n    # Variables for Pinecone DB\n    pinecone_api_key: Optional[str] = None\n    pinecone_index_name: Optional[str] = None\n    pinecone_environment: Optional[str] = None\n\n    # Sentry's configuration.\n    sentry_dsn: Optional[str] = None\n    sentry_sample_rate: float = 1.0\n\n    kafka_bootstrap_servers: Union[str, List[str]] = []\n    kafka_username: Optional[str] = None\n    kafka_password: Optional[str] = None\n    kafka_ssal_mechanism: SASL_MECHANISM = \"PLAIN\"\n\n    # Websocket settings\n    pusher_app_id: Optional[str] = None\n    pusher_key: Optional[str] = None\n    pusher_secret: Optional[str] = None\n    pusher_cluster: Optional[str] = None\n\n    # Application Settings\n    ff_mock_mode_enabled: bool = False  # Controls whether calls are mocked\n    max_loops: int = 25  # Maximum number of loops to run\n\n    # Settings for sid\n    sid_client_id: Optional[str] = None\n    sid_client_secret: Optional[str] = None\n    sid_redirect_uri: Optional[str] = None\n\n    @property\n    def kafka_consumer_group(self) -> str:\n        \"\"\"\n        Kafka consumer group will be the name of the host in development\n        mode, making it easier to share a dev cluster.\n        \"\"\"\n\n        if self.environment == \"development\":\n            return platform.node()\n\n        return \"platform\"\n\n    @property\n    def db_url(self) -> URL:\n        return URL.build(\n            scheme=\"mysql+aiomysql\",\n            host=self.db_host,\n            port=self.db_port,\n            user=self.db_user,\n            password=self.db_pass,\n            path=f\"/{self.db_base}\",\n        )\n\n    @property\n    def pusher_enabled(self) -> bool:\n        return all(\n            [\n                self.pusher_app_id,\n                self.pusher_key,\n                self.pusher_secret,\n                self.pusher_cluster,\n            ]\n        )\n\n    @property\n    def kafka_enabled(self) -> bool:\n        return all(\n            [\n                self.kafka_bootstrap_servers,\n                self.kafka_username,\n                self.kafka_password,\n            ]\n        )\n\n    @property\n    def helicone_enabled(self) -> bool:\n        return all(\n            [\n                self.helicone_api_base,\n                self.helicone_api_key,\n            ]\n        )\n\n    @property\n    def sid_enabled(self) -> bool:\n        return all(\n            [\n                self.sid_client_id,\n                self.sid_client_secret,\n                self.sid_redirect_uri,\n            ]\n        )\n\n    class Config:\n        env_file = \".env\"\n        env_prefix = ENV_PREFIX\n        env_file_encoding = \"utf-8\"\n\n\nsettings = Settings()\n"
  },
  {
    "path": "platform/reworkd_platform/tests/__init__.py",
    "content": "\"\"\"Tests for reworkd_platform.\"\"\"\n"
  },
  {
    "path": "platform/reworkd_platform/tests/agent/test_analysis.py",
    "content": "import pytest\nfrom pydantic import ValidationError\n\nfrom reworkd_platform.web.api.agent.analysis import Analysis\nfrom reworkd_platform.web.api.agent.tools.tools import get_default_tool, get_tool_name\n\n\ndef test_analysis_model() -> None:\n    valid_tool_name = get_tool_name(get_default_tool())\n    analysis = Analysis(action=valid_tool_name, arg=\"arg\", reasoning=\"reasoning\")\n\n    assert analysis.action == valid_tool_name\n    assert analysis.arg == \"arg\"\n    assert analysis.reasoning == \"reasoning\"\n\n\ndef test_analysis_model_search_empty_arg() -> None:\n    with pytest.raises(ValidationError):\n        Analysis(action=\"search\", arg=\"\", reasoning=\"reasoning\")\n\n\ndef test_analysis_model_search_non_empty_arg() -> None:\n    analysis = Analysis(action=\"search\", arg=\"non-empty arg\", reasoning=\"reasoning\")\n    assert analysis.action == \"search\"\n    assert analysis.arg == \"non-empty arg\"\n    assert analysis.reasoning == \"reasoning\"\n\n\ndef test_analysis_model_invalid_tool() -> None:\n    with pytest.raises(ValidationError):\n        Analysis(action=\"invalid tool name\", arg=\"test argument\", reasoning=\"reasoning\")\n"
  },
  {
    "path": "platform/reworkd_platform/tests/agent/test_crud.py",
    "content": "from unittest.mock import AsyncMock\n\nimport pytest\nfrom fastapi import HTTPException\nfrom pytest_mock import MockerFixture\n\nfrom reworkd_platform.db.crud.agent import AgentCRUD\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.errors import MaxLoopsError, MultipleSummaryError\n\n\n@pytest.mark.asyncio\nasync def test_validate_task_count_no_error(mocker) -> None:\n    mock_agent_run_exists(mocker, True)\n    session = mock_session_with_run_count(mocker, 0)\n    agent_crud: AgentCRUD = AgentCRUD(session, mocker.MagicMock())\n\n    # Doesn't throw an exception\n    await agent_crud.validate_task_count(\"test\", \"summarize\")\n\n\n@pytest.mark.asyncio\nasync def test_validate_task_count_when_run_not_found(mocker: MockerFixture) -> None:\n    mock_agent_run_exists(mocker, False)\n    agent_crud: AgentCRUD = AgentCRUD(mocker.AsyncMock(), mocker.MagicMock())\n\n    with pytest.raises(HTTPException):\n        await agent_crud.validate_task_count(\"test\", \"test\")\n\n\n@pytest.mark.asyncio\nasync def test_validate_task_count_max_loops_error(mocker: MockerFixture) -> None:\n    mock_agent_run_exists(mocker, True)\n    session = mock_session_with_run_count(mocker, settings.max_loops)\n    agent_crud: AgentCRUD = AgentCRUD(session, mocker.AsyncMock())\n\n    with pytest.raises(MaxLoopsError):\n        await agent_crud.validate_task_count(\"test\", \"test\")\n\n\n@pytest.mark.asyncio\nasync def test_validate_task_count_multiple_summary_error(\n    mocker: MockerFixture,\n) -> None:\n    mock_agent_run_exists(mocker, True)\n    session = mock_session_with_run_count(mocker, 2)\n    agent_crud: AgentCRUD = AgentCRUD(session, mocker.MagicMock())\n\n    with pytest.raises(MultipleSummaryError):\n        await agent_crud.validate_task_count(\"test\", \"summarize\")\n\n\ndef mock_agent_run_exists(mocker: MockerFixture, exists: bool) -> None:\n    mocker.patch(\"reworkd_platform.db.models.agent.AgentRun.get\", return_value=exists)\n\n\ndef mock_session_with_run_count(mocker: MockerFixture, run_count: int) -> AsyncMock:\n    session = mocker.AsyncMock()\n    scalar_mock = mocker.MagicMock()\n\n    session.execute.return_value = scalar_mock\n    scalar_mock.scalar_one.return_value = run_count\n    return session\n"
  },
  {
    "path": "platform/reworkd_platform/tests/agent/test_model_factory.py",
    "content": "import itertools\n\nimport pytest\nfrom langchain.chat_models import AzureChatOpenAI, ChatOpenAI\n\nfrom reworkd_platform.schemas import ModelSettings, UserBase\nfrom reworkd_platform.settings import Settings\nfrom reworkd_platform.web.api.agent.model_factory import (\n    WrappedAzureChatOpenAI,\n    WrappedChatOpenAI,\n    create_model,\n    get_base_and_headers,\n)\n\n\ndef test_helicone_enabled_without_custom_api_key():\n    model_settings = ModelSettings()\n    user = UserBase(id=\"user_id\")\n    settings = Settings(\n        helicone_api_key=\"some_key\",\n        helicone_api_base=\"helicone_base\",\n        openai_api_base=\"openai_base\",\n    )\n\n    base, headers, use_helicone = get_base_and_headers(settings, model_settings, user)\n\n    assert use_helicone is True\n    assert base == \"helicone_base\"\n    assert headers == {\n        \"Helicone-Auth\": \"Bearer some_key\",\n        \"Helicone-Cache-Enabled\": \"true\",\n        \"Helicone-User-Id\": \"user_id\",\n        \"Helicone-OpenAI-Api-Base\": \"openai_base\",\n    }\n\n\ndef test_helicone_disabled():\n    model_settings = ModelSettings()\n    user = UserBase(id=\"user_id\")\n    settings = Settings()\n\n    base, headers, use_helicone = get_base_and_headers(settings, model_settings, user)\n    assert base == \"https://api.openai.com/v1\"\n    assert headers is None\n    assert use_helicone is False\n\n\ndef test_helicone_enabled_with_custom_api_key():\n    model_settings = ModelSettings(\n        custom_api_key=\"custom_key\",\n    )\n    user = UserBase(id=\"user_id\")\n    settings = Settings(\n        openai_api_base=\"openai_base\",\n        helicone_api_key=\"some_key\",\n        helicone_api_base=\"helicone_base\",\n    )\n\n    base, headers, use_helicone = get_base_and_headers(settings, model_settings, user)\n\n    assert base == \"https://api.openai.com/v1\"\n    assert headers is None\n    assert use_helicone is False\n\n\n@pytest.mark.parametrize(\n    \"streaming, use_azure\",\n    list(\n        itertools.product(\n            [True, False],\n            [True, False],\n        )\n    ),\n)\ndef test_create_model(streaming, use_azure):\n    user = UserBase(id=\"user_id\")\n    settings = Settings()\n    model_settings = ModelSettings(\n        temperature=0.7,\n        model=\"gpt-3.5-turbo\",\n        max_tokens=100,\n    )\n\n    settings.openai_api_base = (\n        \"https://api.openai.com\" if not use_azure else \"https://oai.azure.com\"\n    )\n    settings.openai_api_key = \"key\"\n    settings.openai_api_version = \"version\"\n\n    result = create_model(settings, model_settings, user, streaming)\n    assert issubclass(result.__class__, WrappedChatOpenAI)\n    assert issubclass(result.__class__, ChatOpenAI)\n\n    # Check if the required keys are set properly\n    assert result.openai_api_base == settings.openai_api_base\n    assert result.openai_api_key == settings.openai_api_key\n    assert result.temperature == model_settings.temperature\n    assert result.max_tokens == model_settings.max_tokens\n    assert result.streaming == streaming\n    assert result.max_retries == 5\n\n    # For Azure specific checks\n    if use_azure:\n        assert isinstance(result, WrappedAzureChatOpenAI)\n        assert issubclass(result.__class__, AzureChatOpenAI)\n        assert result.openai_api_version == settings.openai_api_version\n        assert result.deployment_name == \"gpt-35-turbo\"\n        assert result.openai_api_type == \"azure\"\n\n\n@pytest.mark.parametrize(\n    \"model_settings, streaming\",\n    list(\n        itertools.product(\n            [\n                ModelSettings(\n                    customTemperature=0.222,\n                    customModelName=\"gpt-4\",\n                    maxTokens=1234,\n                ),\n                ModelSettings(),\n            ],\n            [True, False],\n        )\n    ),\n)\ndef test_custom_model_settings(model_settings: ModelSettings, streaming: bool):\n    model = create_model(\n        Settings(),\n        model_settings,\n        UserBase(id=\"\", email=\"test@example.com\"),\n        streaming=streaming,\n    )\n\n    assert model.temperature == model_settings.temperature\n    assert model.model_name.startswith(model_settings.model)\n    assert model.max_tokens == model_settings.max_tokens\n    assert model.streaming == streaming\n"
  },
  {
    "path": "platform/reworkd_platform/tests/agent/test_task_output_parser.py",
    "content": "from typing import List, Type\n\nimport pytest\nfrom langchain.schema import OutputParserException\n\nfrom reworkd_platform.web.api.agent.task_output_parser import (\n    TaskOutputParser,\n    extract_array,\n    real_tasks_filter,\n    remove_prefix,\n)\n\n\n@pytest.mark.parametrize(\n    \"input_text,expected_output\",\n    [\n        (\n            '[\"Task 1: Do something\", \"Task 2: Do something else\", \"Task 3: Do '\n            'another thing\"]',\n            [\"Do something\", \"Do something else\", \"Do another thing\"],\n        ),\n        (\n            'Some random stuff [\"1: Hello\"]',\n            [\"Hello\"],\n        ),\n        (\n            \"[]\",\n            [],\n        ),\n    ],\n)\ndef test_parse_success(input_text: str, expected_output: List[str]) -> None:\n    parser = TaskOutputParser(completed_tasks=[])\n    result = parser.parse(input_text)\n    assert result == expected_output\n\n\ndef test_parse_with_completed_tasks() -> None:\n    input_text = '[\"One\", \"Two\", \"Three\"]'\n    completed = [\"One\"]\n    expected = [\"Two\", \"Three\"]\n\n    parser = TaskOutputParser(completed_tasks=completed)\n\n    result = parser.parse(input_text)\n    assert result == expected\n\n\n@pytest.mark.parametrize(\n    \"input_text, exception\",\n    [\n        # Test cases for non-array and non-multiline string inputs\n        (\"This is not an array\", OutputParserException),\n        (\"123456\", OutputParserException),\n        (\"Some random text\", OutputParserException),\n        (\"[abc]\", OutputParserException),\n        # Test cases for malformed arrays\n        (\"[1, 2, 3\", OutputParserException),\n        (\"'item1', 'item2']\", OutputParserException),\n        (\"['item1', 'item2\", OutputParserException),\n        # Test case for invalid multiline strings\n        (\"This is not\\na valid\\nmultiline string.\", OutputParserException),\n        # Test case for multiline strings that don't start with digit + period\n        (\"Some text\\nMore text\\nAnd more text.\", OutputParserException),\n    ],\n)\ndef test_parse_failure(input_text: str, exception: Type[Exception]) -> None:\n    parser = TaskOutputParser(completed_tasks=[])\n    with pytest.raises(exception):\n        parser.parse(input_text)\n\n\n@pytest.mark.parametrize(\n    \"input_str, expected\",\n    [\n        # Test cases for empty array\n        (\"[]\", []),\n        # Test cases for arrays with one element\n        ('[\"One\"]', [\"One\"]),\n        (\"['Single quote']\", [\"Single quote\"]),\n        # Test cases for arrays with multiple elements\n        ('[\"Research\", \"Develop\", \"Integrate\"]', [\"Research\", \"Develop\", \"Integrate\"]),\n        ('[\"Search\", \"Identify\"]', [\"Search\", \"Identify\"]),\n        ('[\"Item 1\",\"Item 2\",\"Item 3\"]', [\"Item 1\", \"Item 2\", \"Item 3\"]),\n        # Test cases for arrays with special characters in elements\n        (\"['Single with \\\"quote\\\"']\", ['Single with \"quote\"']),\n        ('[\"Escape \\\\\" within\"]', ['Escape \" within']),\n        # Test case for array embedded in other text\n        (\"Random stuff ['Search', 'Identify']\", [\"Search\", \"Identify\"]),\n        # Test case for array within JSON\n        ('{\"array\": [\"123\", \"456\"]}', [\"123\", \"456\"]),\n        # Multiline string cases\n        (\n            \"1. Identify the target\\n2. Conduct research\\n3. Implement the methods\",\n            [\n                \"1. Identify the target\",\n                \"2. Conduct research\",\n                \"3. Implement the methods\",\n            ],\n        ),\n        (\"1. Step one.\\n2. Step two.\", [\"1. Step one.\", \"2. Step two.\"]),\n        (\n            \"\"\"1. Review and understand the code to be debugged\n2. Identify and address any errors or issues found during the review process\n3. Print out debug information and setup initial variables\n4. Start necessary threads and execute program logic.\"\"\",\n            [\n                \"1. Review and understand the code to be debugged\",\n                \"2. Identify and address any errors or issues found during the review \"\n                \"process\",\n                \"3. Print out debug information and setup initial variables\",\n                \"4. Start necessary threads and execute program logic.\",\n            ],\n        ),\n        # Test cases with sentences before the digit + period pattern\n        (\n            \"Any text before 1. Identify the task to be repeated\\nUnrelated info 2. \"\n            \"Determine the frequency of the repetition\\nAnother sentence 3. Create a \"\n            \"schedule or system to ensure completion of the task at the designated \"\n            \"frequency\\nMore text 4. Execute the task according to the established \"\n            \"schedule or system\",\n            [\n                \"1. Identify the task to be repeated\",\n                \"2. Determine the frequency of the repetition\",\n                \"3. Create a schedule or system to ensure completion of the task at \"\n                \"the designated frequency\",\n                \"4. Execute the task according to the established schedule or system\",\n            ],\n        ),\n    ],\n)\ndef test_extract_array_success(input_str: str, expected: List[str]) -> None:\n    print(extract_array(input_str), expected)\n    assert extract_array(input_str) == expected\n\n\n@pytest.mark.parametrize(\n    \"input_str, exception\",\n    [\n        (None, TypeError),\n        (\"123\", RuntimeError),\n        (\"Some random text\", RuntimeError),\n        ('\"single_string\"', RuntimeError),\n        ('{\"test\": 123}', RuntimeError),\n        ('[\"Unclosed array\", \"other\"', RuntimeError),\n    ],\n)\ndef test_extract_array_exception(input_str: str, exception: Type[Exception]) -> None:\n    with pytest.raises(exception):\n        extract_array(input_str)\n\n\n@pytest.mark.parametrize(\n    \"task_input, expected_output\",\n    [\n        (\"Task: This is a sample task\", \"This is a sample task\"),\n        (\n            \"Task 1: Perform a comprehensive analysis of system performance.\",\n            \"Perform a comprehensive analysis of system performance.\",\n        ),\n        (\"Task 2. Create a python script\", \"Create a python script\"),\n        (\"5 - This is a sample task\", \"This is a sample task\"),\n        (\"2: This is a sample task\", \"This is a sample task\"),\n        (\n            \"This is a sample task without a prefix\",\n            \"This is a sample task without a prefix\",\n        ),\n        (\"Step: This is a sample task\", \"This is a sample task\"),\n        (\n            \"Step 1: Perform a comprehensive analysis of system performance.\",\n            \"Perform a comprehensive analysis of system performance.\",\n        ),\n        (\"Step 2:Create a python script\", \"Create a python script\"),\n        (\"Step:This is a sample task\", \"This is a sample task\"),\n        (\n            \". Conduct research on the history of Nike\",\n            \"Conduct research on the history of Nike\",\n        ),\n        (\".This is a sample task\", \"This is a sample task\"),\n        (\n            \"1. Research the history and background of Nike company.\",\n            \"Research the history and background of Nike company.\",\n        ),\n    ],\n)\ndef test_remove_task_prefix(task_input: str, expected_output: str) -> None:\n    output = remove_prefix(task_input)\n    assert output == expected_output\n\n\n@pytest.mark.parametrize(\n    \"input_text, expected_result\",\n    [\n        (\"Write the report\", True),\n        (\"No new task needed\", False),\n        (\"Task completed\", False),\n        (\"Do nothing\", False),\n        (\"\", False),  # empty_string\n        (\"no new task needed\", False),  # case_insensitive\n    ],\n)\ndef test_real_tasks_filter_no_task(input_text: str, expected_result: bool) -> None:\n    assert real_tasks_filter(input_text) == expected_result\n"
  },
  {
    "path": "platform/reworkd_platform/tests/agent/test_tools.py",
    "content": "from typing import List, Type\n\nfrom reworkd_platform.web.api.agent.tools.conclude import Conclude\nfrom reworkd_platform.web.api.agent.tools.image import Image\nfrom reworkd_platform.web.api.agent.tools.reason import Reason\nfrom reworkd_platform.web.api.agent.tools.search import Search\nfrom reworkd_platform.web.api.agent.tools.sidsearch import SID\nfrom reworkd_platform.web.api.agent.tools.tools import (\n    Tool,\n    format_tool_name,\n    get_default_tool,\n    get_tool_from_name,\n    get_tool_name,\n    get_tools_overview,\n)\n\n\ndef test_get_tool_name() -> None:\n    assert get_tool_name(Image) == \"image\"\n    assert get_tool_name(Search) == \"search\"\n    assert get_tool_name(Reason) == \"reason\"\n\n\ndef test_format_tool_name() -> None:\n    assert format_tool_name(\"Search\") == \"search\"\n    assert format_tool_name(\"reason\") == \"reason\"\n    assert format_tool_name(\"Conclude\") == \"conclude\"\n    assert format_tool_name(\"CoNcLuDe\") == \"conclude\"\n\n\ndef test_get_tools_overview_no_duplicates() -> None:\n    \"\"\"Test to assert that the tools overview doesn't include duplicates.\"\"\"\n    tools: List[Type[Tool]] = [Image, Search, Reason, Conclude, Image, Search]\n    overview = get_tools_overview(tools)\n\n    # Check if each unique tool description is included in the overview\n    for tool in set(tools):\n        expected_description = f\"'{get_tool_name(tool)}': {tool.description}\"\n        assert expected_description in overview\n\n    # Check for duplicates in the overview\n    overview_list = overview.split(\"\\n\")\n    assert len(overview_list) == len(\n        set(overview_list)\n    ), \"Overview includes duplicate entries\"\n\n\ndef test_get_default_tool() -> None:\n    assert get_default_tool() == Search\n\n\ndef test_get_tool_from_name() -> None:\n    assert get_tool_from_name(\"Search\") == Search\n    assert get_tool_from_name(\"CoNcLuDe\") == Conclude\n    assert get_tool_from_name(\"NonExistingTool\") == Search\n    assert get_tool_from_name(\"SID\") == SID\n"
  },
  {
    "path": "platform/reworkd_platform/tests/memory/memory_with_fallback_test.py",
    "content": "import pytest\n\nfrom reworkd_platform.web.api.memory.memory_with_fallback import MemoryWithFallback\n\n\n@pytest.mark.parametrize(\n    \"method_name, args\",\n    [\n        (\"add_tasks\", ([\"task1\", \"task2\"],)),\n        (\"get_similar_tasks\", (\"task1\",)),\n        (\"reset_class\", ()),\n    ],\n)\ndef test_memory_primary(mocker, method_name: str, args) -> None:\n    primary = mocker.Mock()\n    secondary = mocker.Mock()\n    memory_with_fallback = MemoryWithFallback(primary, secondary)\n\n    # Use getattr() to call the method on the object with args\n    getattr(memory_with_fallback, method_name)(*args)\n    getattr(primary, method_name).assert_called_once_with(*args)\n    getattr(secondary, method_name).assert_not_called()\n\n\n@pytest.mark.parametrize(\n    \"method_name, args\",\n    [\n        (\"add_tasks\", ([\"task1\", \"task2\"],)),\n        (\"get_similar_tasks\", (\"task1\",)),\n        (\"reset_class\", ()),\n    ],\n)\ndef test_memory_fallback(mocker, method_name: str, args) -> None:\n    primary = mocker.Mock()\n    secondary = mocker.Mock()\n    memory_with_fallback = MemoryWithFallback(primary, secondary)\n\n    getattr(primary, method_name).side_effect = Exception(\"Primary Failed\")\n\n    # Call the method again, this time it should fall back to secondary\n    getattr(memory_with_fallback, method_name)(*args)\n    getattr(primary, method_name).assert_called_once_with(*args)\n    getattr(secondary, method_name).assert_called_once_with(*args)\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_dependancies.py",
    "content": "import pytest\n\nfrom reworkd_platform.web.api.agent import dependancies\n\n\n@pytest.mark.anyio\n@pytest.mark.parametrize(\n    \"validator, step\",\n    [\n        (dependancies.agent_summarize_validator, \"summarize\"),\n        (dependancies.agent_chat_validator, \"chat\"),\n        (dependancies.agent_analyze_validator, \"analyze\"),\n        (dependancies.agent_create_validator, \"create\"),\n        (dependancies.agent_execute_validator, \"execute\"),\n    ],\n)\nasync def test_agent_validate(mocker, validator, step):\n    run_id = \"asim\"\n    crud = mocker.Mock()\n    body = mocker.Mock()\n    body.run_id = run_id\n\n    crud.create_task = mocker.AsyncMock()\n\n    await validator(body, crud)\n    crud.create_task.assert_called_once_with(run_id, step)\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_helpers.py",
    "content": "import pytest\nfrom openai.error import InvalidRequestError, ServiceUnavailableError\n\nfrom reworkd_platform.schemas.agent import ModelSettings\nfrom reworkd_platform.web.api.agent.helpers import openai_error_handler\nfrom reworkd_platform.web.api.errors import OpenAIError\n\n\nasync def act(*args, settings: ModelSettings = ModelSettings(), **kwargs):\n    return await openai_error_handler(*args, settings=settings, **kwargs)\n\n\n@pytest.mark.asyncio\nasync def test_service_unavailable_error():\n    async def mock_service_unavailable_error():\n        raise ServiceUnavailableError(\"Service Unavailable\")\n\n    with pytest.raises(OpenAIError):\n        await act(mock_service_unavailable_error)\n\n\n@pytest.mark.asyncio\n@pytest.mark.parametrize(\n    \"settings,should_log\",\n    [\n        (ModelSettings(custom_api_key=\"xyz\"), False),\n        (ModelSettings(custom_api_key=None), True),\n    ],\n)\nasync def test_should_log(settings, should_log):\n    async def mock_invalid_request_error_model_access():\n        raise InvalidRequestError(\n            \"The model: xyz does not exist or you do not have access to it.\",\n            param=\"model\",\n        )\n\n    with pytest.raises(Exception) as exc_info:\n        await openai_error_handler(\n            mock_invalid_request_error_model_access, settings=settings\n        )\n\n    assert isinstance(exc_info.value, OpenAIError)\n    error: OpenAIError = exc_info.value\n\n    assert error.should_log == should_log\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_oauth_installers.py",
    "content": "import pytest\n\nfrom reworkd_platform.services.oauth_installers import installer_factory\n\n\ndef test_installer_factory(mocker):\n    crud = mocker.Mock()\n    installer_factory(\"sid\", crud)\n\n\ndef test_integration_dne(mocker):\n    crud = mocker.Mock()\n\n    with pytest.raises(NotImplementedError):\n        installer_factory(\"asim\", crud)\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_reworkd_platform.py",
    "content": "import pytest\nfrom fastapi import FastAPI\nfrom httpx import AsyncClient\nfrom starlette import status\n\n\n@pytest.mark.skip(reason=\"Mysql needs to be mocked\")\n@pytest.mark.anyio\nasync def test_health(client: AsyncClient, fastapi_app: FastAPI) -> None:\n    \"\"\"\n    Checks the health endpoint.\n\n    :param client: client for the app.\n    :param fastapi_app: current FastAPI application.\n    \"\"\"\n    url = fastapi_app.url_path_for(\"health_check\")\n    response = await client.get(url)\n    assert response.status_code == status.HTTP_200_OK\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_s3.py",
    "content": "from reworkd_platform.services.aws.s3 import SimpleStorageService\n\n\ndef test_create_signed_post(mocker):\n    post_url = {\n        \"url\": \"https://my_bucket.s3.amazonaws.com/my_object\",\n        \"fields\": {\"key\": \"value\"},\n    }\n\n    boto3_mock = mocker.Mock()\n    boto3_mock.generate_presigned_post.return_value = post_url\n    mocker.patch(\n        \"reworkd_platform.services.aws.s3.boto3_client\", return_value=boto3_mock\n    )\n\n    assert (\n        SimpleStorageService(bucket=\"my_bucket\").create_presigned_upload_url(\n            object_name=\"json\"\n        )\n        == post_url\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_schemas.py",
    "content": "import pytest\n\nfrom reworkd_platform.schemas.agent import ModelSettings\n\n\n@pytest.mark.parametrize(\n    \"settings\",\n    [\n        {\n            \"model\": \"gpt-4\",\n            \"max_tokens\": 7000,\n            \"temperature\": 0.5,\n            \"language\": \"french\",\n        },\n        {\n            \"model\": \"gpt-3.5-turbo\",\n            \"max_tokens\": 3000,\n        },\n        {\n            \"model\": \"gpt-3.5-turbo-16k\",\n            \"max_tokens\": 16000,\n        },\n    ],\n)\ndef test_model_settings_valid(settings):\n    result = ModelSettings(**settings)\n    assert result.model == settings.get(\"model\", \"gpt-3.5-turbo\")\n    assert result.max_tokens == settings.get(\"max_tokens\", 500)\n    assert result.temperature == settings.get(\"temperature\", 0.9)\n    assert result.language == settings.get(\"language\", \"English\")\n\n\n@pytest.mark.parametrize(\n    \"settings\",\n    [\n        {\n            \"model\": \"gpt-4-32k\",\n        },\n        {\n            \"temperature\": -1,\n        },\n        {\n            \"max_tokens\": 8000,\n        },\n        {\n            \"model\": \"gpt-4\",\n            \"max_tokens\": 32000,\n        },\n    ],\n)\ndef test_model_settings_invalid(settings):\n    with pytest.raises(Exception):\n        ModelSettings(**settings)\n\n\ndef test_model_settings_default():\n    settings = ModelSettings(**{})\n    assert settings.model == \"gpt-3.5-turbo\"\n    assert settings.temperature == 0.9\n    assert settings.max_tokens == 500\n    assert settings.language == \"English\"\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_security.py",
    "content": "import pytest\nfrom cryptography.fernet import Fernet\nfrom fastapi import HTTPException\n\nfrom reworkd_platform.services.security import EncryptionService\n\n\ndef test_encrypt_decrypt():\n    key = Fernet.generate_key()\n    service = EncryptionService(key)\n\n    original_text = \"Hello, world!\"\n    encrypted = service.encrypt(original_text)\n    decrypted = service.decrypt(encrypted)\n\n    assert original_text == decrypted\n\n\ndef test_invalid_key():\n    key = Fernet.generate_key()\n\n    different_key = Fernet.generate_key()\n    different_service = EncryptionService(different_key)\n\n    original_text = \"Hello, world!\"\n    encrypted = Fernet(key).encrypt(original_text.encode())\n\n    with pytest.raises(HTTPException):\n        different_service.decrypt(encrypted)\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_settings.py",
    "content": "from reworkd_platform.settings import Settings\n\n\ndef test_settings_create():\n    assert Settings() is not None\n"
  },
  {
    "path": "platform/reworkd_platform/tests/test_token_service.py",
    "content": "from unittest.mock import Mock\n\nimport tiktoken\n\nfrom reworkd_platform.schemas.agent import LLM_MODEL_MAX_TOKENS\nfrom reworkd_platform.services.tokenizer.token_service import TokenService\n\nencoding = tiktoken.get_encoding(\"cl100k_base\")\n\n\ndef test_happy_path() -> None:\n    service = TokenService(encoding)\n    text = \"Hello world!\"\n    validate_tokenize_and_detokenize(service, text, 3)\n\n\ndef test_nothing() -> None:\n    service = TokenService(encoding)\n    text = \"\"\n    validate_tokenize_and_detokenize(service, text, 0)\n\n\ndef validate_tokenize_and_detokenize(\n    service: TokenService, text: str, expected_token_count: int\n) -> None:\n    tokens = service.tokenize(text)\n    assert text == service.detokenize(tokens)\n    assert len(tokens) == service.count(text)\n    assert len(tokens) == expected_token_count\n\n\ndef test_calculate_max_tokens_with_small_max_tokens() -> None:\n    initial_max_tokens = 3000\n    service = TokenService(encoding)\n    model = Mock(spec=[\"model_name\", \"max_tokens\"])\n    model.model_name = \"gpt-3.5-turbo\"\n    model.max_tokens = initial_max_tokens\n\n    service.calculate_max_tokens(model, \"Hello\")\n\n    assert model.max_tokens == initial_max_tokens\n\n\ndef test_calculate_max_tokens_with_high_completion_tokens() -> None:\n    service = TokenService(encoding)\n    prompt_tokens = service.count(LONG_TEXT)\n    model = Mock(spec=[\"model_name\", \"max_tokens\"])\n    model.model_name = \"gpt-3.5-turbo\"\n    model.max_tokens = 8000\n\n    service.calculate_max_tokens(model, LONG_TEXT)\n\n    assert model.max_tokens == (\n        LLM_MODEL_MAX_TOKENS.get(\"gpt-3.5-turbo\") - prompt_tokens\n    )\n\n\ndef test_calculate_max_tokens_with_negative_result() -> None:\n    service = TokenService(encoding)\n    model = Mock(spec=[\"model_name\", \"max_tokens\"])\n    model.model_name = \"gpt-3.5-turbo\"\n    model.max_tokens = 8000\n\n    service.calculate_max_tokens(model, *([LONG_TEXT] * 100))\n\n    # We use the minimum length of 1\n    assert model.max_tokens == 1\n\n\nLONG_TEXT = \"\"\"\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\nThis is some long text. This is some long text. This is some long text.\n\"\"\"\n"
  },
  {
    "path": "platform/reworkd_platform/timer.py",
    "content": "from functools import wraps\nfrom time import time\nfrom typing import Any, Callable, Literal\n\nfrom loguru import logger\n\nLog_Level = Literal[\n    \"TRACE\",\n    \"DEBUG\",\n    \"INFO\",\n    \"SUCCESS\",\n    \"WARNING\",\n    \"ERROR\",\n    \"CRITICAL\",\n]\n\n\ndef timed_function(level: Log_Level = \"INFO\") -> Callable[..., Any]:\n    def decorator(func: Any) -> Callable[..., Any]:\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            start_time = time()\n            result = func(*args, **kwargs)\n            execution_time = time() - start_time\n            logger.log(\n                level,\n                f\"Function '{func.__qualname__}' executed in {execution_time:.4f} seconds\",\n            )\n\n            return result\n\n        return wrapper\n\n    return decorator\n"
  },
  {
    "path": "platform/reworkd_platform/web/__init__.py",
    "content": "\"\"\"WEB API for reworkd_platform.\"\"\"\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/__init__.py",
    "content": "\"\"\"reworkd_platform API package.\"\"\"\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/__init__.py",
    "content": "\"\"\"API for checking running agents\"\"\"\nfrom reworkd_platform.web.api.agent.views import router\n\n__all__ = [\"router\"]\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/agent_service/__init__.py",
    "content": ""
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/agent_service/agent_service.py",
    "content": "from typing import List, Optional, Protocol\n\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\n\nfrom reworkd_platform.web.api.agent.analysis import Analysis\n\n\nclass AgentService(Protocol):\n    async def start_goal_agent(self, *, goal: str) -> List[str]:\n        pass\n\n    async def analyze_task_agent(\n        self, *, goal: str, task: str, tool_names: List[str]\n    ) -> Analysis:\n        pass\n\n    async def execute_task_agent(\n        self,\n        *,\n        goal: str,\n        task: str,\n        analysis: Analysis,\n    ) -> FastAPIStreamingResponse:\n        pass\n\n    async def create_tasks_agent(\n        self,\n        *,\n        goal: str,\n        tasks: List[str],\n        last_task: str,\n        result: str,\n        completed_tasks: Optional[List[str]] = None,\n    ) -> List[str]:\n        pass\n\n    async def summarize_task_agent(\n        self,\n        *,\n        goal: str,\n        results: List[str],\n    ) -> FastAPIStreamingResponse:\n        pass\n\n    async def chat(\n        self,\n        *,\n        message: str,\n        results: List[str],\n    ) -> FastAPIStreamingResponse:\n        pass\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/agent_service/agent_service_provider.py",
    "content": "from typing import Any, Callable, Coroutine, Optional\n\nfrom fastapi import Depends\n\nfrom reworkd_platform.db.crud.oauth import OAuthCrud\nfrom reworkd_platform.schemas.agent import AgentRun, LLM_Model\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.services.tokenizer.dependencies import get_token_service\nfrom reworkd_platform.services.tokenizer.token_service import TokenService\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.agent.agent_service.agent_service import AgentService\nfrom reworkd_platform.web.api.agent.agent_service.mock_agent_service import (\n    MockAgentService,\n)\nfrom reworkd_platform.web.api.agent.agent_service.open_ai_agent_service import (\n    OpenAIAgentService,\n)\nfrom reworkd_platform.web.api.agent.model_factory import create_model\nfrom reworkd_platform.web.api.dependencies import get_current_user\n\n\ndef get_agent_service(\n    validator: Callable[..., Coroutine[Any, Any, AgentRun]],\n    streaming: bool = False,\n    llm_model: Optional[LLM_Model] = None,\n) -> Callable[..., AgentService]:\n    def func(\n        run: AgentRun = Depends(validator),\n        user: UserBase = Depends(get_current_user),\n        token_service: TokenService = Depends(get_token_service),\n        oauth_crud: OAuthCrud = Depends(OAuthCrud.inject),\n    ) -> AgentService:\n        if settings.ff_mock_mode_enabled:\n            return MockAgentService()\n\n        model = create_model(\n            settings,\n            run.model_settings,\n            user,\n            streaming=streaming,\n            force_model=llm_model,\n        )\n\n        return OpenAIAgentService(\n            model,\n            run.model_settings,\n            token_service,\n            callbacks=None,\n            user=user,\n            oauth_crud=oauth_crud,\n        )\n\n    return func\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/agent_service/mock_agent_service.py",
    "content": "import time\nfrom typing import Any, List\n\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\n\nfrom reworkd_platform.web.api.agent.agent_service.agent_service import (\n    AgentService,\n    Analysis,\n)\nfrom reworkd_platform.web.api.agent.stream_mock import stream_string\n\n\nclass MockAgentService(AgentService):\n    async def start_goal_agent(self, **kwargs: Any) -> List[str]:\n        time.sleep(1)\n        return [\"Task X\", \"Task Y\", \"Task Z\"]\n\n    async def create_tasks_agent(self, **kwargs: Any) -> List[str]:\n        time.sleep(1)\n        return [\"Some random task that doesn't exist\"]\n\n    async def analyze_task_agent(self, **kwargs: Any) -> Analysis:\n        time.sleep(1.5)\n        return Analysis(\n            action=\"reason\",\n            arg=\"Mock analysis\",\n            reasoning=\"Mock to avoid wasting money calling the OpenAI API.\",\n        )\n\n    async def execute_task_agent(self, **kwargs: Any) -> FastAPIStreamingResponse:\n        time.sleep(0.5)\n        return stream_string(\n            \"\"\" This is going to be a longer task result such that\n        We make the stream of this string take time and feel long. The reality is... this is a mock! \n        \n        Lorem Ipsum is simply dummy text of the printing and typesetting industry. \n        Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, \n        when an unknown printer took a galley of type and scrambled it to make a type specimen book. \n        It has survived not only five centuries, but also the leap into electronic typesetting, remaining unchanged.\n        \"\"\"\n            + kwargs.get(\"task\", \"task\"),\n            True,\n        )\n\n    async def summarize_task_agent(\n        self,\n        *,\n        goal: str,\n        results: List[str],\n    ) -> FastAPIStreamingResponse:\n        time.sleep(0.5)\n        return stream_string(\n            \"\"\" This is going to be a longer task result such that\n        We make the stream of this string take time and feel long. The reality is... this is a mock! \n        \n        Lorem Ipsum is simply dummy text of the printing and typesetting industry. \n        Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, \n        when an unknown printer took a galley of type and scrambled it to make a type specimen book. \n        It has survived not only five centuries, but also the leap into electronic typesetting, remaining unchanged.\n        \"\"\",\n            True,\n        )\n\n    async def chat(\n        self,\n        *,\n        message: str,\n        results: List[str],\n    ) -> FastAPIStreamingResponse:\n        time.sleep(0.5)\n        return stream_string(\n            \"What do you want dude?\",\n            True,\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/agent_service/open_ai_agent_service.py",
    "content": "from typing import List, Optional\n\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom lanarky.responses import StreamingResponse\nfrom langchain import LLMChain\nfrom langchain.callbacks.base import AsyncCallbackHandler\nfrom langchain.output_parsers import PydanticOutputParser\nfrom langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate\nfrom langchain.schema import HumanMessage\nfrom loguru import logger\nfrom pydantic import ValidationError\n\nfrom reworkd_platform.db.crud.oauth import OAuthCrud\nfrom reworkd_platform.schemas.agent import ModelSettings\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.services.tokenizer.token_service import TokenService\nfrom reworkd_platform.web.api.agent.agent_service.agent_service import AgentService\nfrom reworkd_platform.web.api.agent.analysis import Analysis, AnalysisArguments\nfrom reworkd_platform.web.api.agent.helpers import (\n    call_model_with_handling,\n    openai_error_handler,\n    parse_with_handling,\n)\nfrom reworkd_platform.web.api.agent.model_factory import WrappedChatOpenAI\nfrom reworkd_platform.web.api.agent.prompts import (\n    analyze_task_prompt,\n    chat_prompt,\n    create_tasks_prompt,\n    start_goal_prompt,\n)\nfrom reworkd_platform.web.api.agent.task_output_parser import TaskOutputParser\nfrom reworkd_platform.web.api.agent.tools.open_ai_function import get_tool_function\nfrom reworkd_platform.web.api.agent.tools.tools import (\n    get_default_tool,\n    get_tool_from_name,\n    get_tool_name,\n    get_user_tools,\n)\nfrom reworkd_platform.web.api.agent.tools.utils import summarize\nfrom reworkd_platform.web.api.errors import OpenAIError\n\n\nclass OpenAIAgentService(AgentService):\n    def __init__(\n        self,\n        model: WrappedChatOpenAI,\n        settings: ModelSettings,\n        token_service: TokenService,\n        callbacks: Optional[List[AsyncCallbackHandler]],\n        user: UserBase,\n        oauth_crud: OAuthCrud,\n    ):\n        self.model = model\n        self.settings = settings\n        self.token_service = token_service\n        self.callbacks = callbacks\n        self.user = user\n        self.oauth_crud = oauth_crud\n\n    async def start_goal_agent(self, *, goal: str) -> List[str]:\n        prompt = ChatPromptTemplate.from_messages(\n            [SystemMessagePromptTemplate(prompt=start_goal_prompt)]\n        )\n\n        self.token_service.calculate_max_tokens(\n            self.model,\n            prompt.format_prompt(\n                goal=goal,\n                language=self.settings.language,\n            ).to_string(),\n        )\n\n        completion = await call_model_with_handling(\n            self.model,\n            ChatPromptTemplate.from_messages(\n                [SystemMessagePromptTemplate(prompt=start_goal_prompt)]\n            ),\n            {\"goal\": goal, \"language\": self.settings.language},\n            settings=self.settings,\n            callbacks=self.callbacks,\n        )\n\n        task_output_parser = TaskOutputParser(completed_tasks=[])\n        tasks = parse_with_handling(task_output_parser, completion)\n\n        return tasks\n\n    async def analyze_task_agent(\n        self, *, goal: str, task: str, tool_names: List[str]\n    ) -> Analysis:\n        user_tools = await get_user_tools(tool_names, self.user, self.oauth_crud)\n        functions = list(map(get_tool_function, user_tools))\n        prompt = analyze_task_prompt.format_prompt(\n            goal=goal,\n            task=task,\n            language=self.settings.language,\n        )\n\n        self.token_service.calculate_max_tokens(\n            self.model,\n            prompt.to_string(),\n            str(functions),\n        )\n\n        message = await openai_error_handler(\n            func=self.model.apredict_messages,\n            messages=prompt.to_messages(),\n            functions=functions,\n            settings=self.settings,\n            callbacks=self.callbacks,\n        )\n\n        function_call = message.additional_kwargs.get(\"function_call\", {})\n        completion = function_call.get(\"arguments\", \"\")\n\n        try:\n            pydantic_parser = PydanticOutputParser(pydantic_object=AnalysisArguments)\n            analysis_arguments = parse_with_handling(pydantic_parser, completion)\n            return Analysis(\n                action=function_call.get(\"name\", get_tool_name(get_default_tool())),\n                **analysis_arguments.dict(),\n            )\n        except (OpenAIError, ValidationError):\n            return Analysis.get_default_analysis(task)\n\n    async def execute_task_agent(\n        self,\n        *,\n        goal: str,\n        task: str,\n        analysis: Analysis,\n    ) -> StreamingResponse:\n        # TODO: More mature way of calculating max_tokens\n        if self.model.max_tokens > 3000:\n            self.model.max_tokens = max(self.model.max_tokens - 1000, 3000)\n\n        tool_class = get_tool_from_name(analysis.action)\n        return await tool_class(self.model, self.settings.language).call(\n            goal,\n            task,\n            analysis.arg,\n            self.user,\n            self.oauth_crud,\n        )\n\n    async def create_tasks_agent(\n        self,\n        *,\n        goal: str,\n        tasks: List[str],\n        last_task: str,\n        result: str,\n        completed_tasks: Optional[List[str]] = None,\n    ) -> List[str]:\n        prompt = ChatPromptTemplate.from_messages(\n            [SystemMessagePromptTemplate(prompt=create_tasks_prompt)]\n        )\n\n        args = {\n            \"goal\": goal,\n            \"language\": self.settings.language,\n            \"tasks\": \"\\n\".join(tasks),\n            \"lastTask\": last_task,\n            \"result\": result,\n        }\n\n        self.token_service.calculate_max_tokens(\n            self.model, prompt.format_prompt(**args).to_string()\n        )\n\n        completion = await call_model_with_handling(\n            self.model, prompt, args, settings=self.settings, callbacks=self.callbacks\n        )\n\n        previous_tasks = (completed_tasks or []) + tasks\n        return [completion] if completion not in previous_tasks else []\n\n    async def summarize_task_agent(\n        self,\n        *,\n        goal: str,\n        results: List[str],\n    ) -> FastAPIStreamingResponse:\n        self.model.model_name = \"gpt-3.5-turbo-16k\"\n        self.model.max_tokens = 8000  # Total tokens = prompt tokens + completion tokens\n\n        snippet_max_tokens = 7000  # Leave room for the rest of the prompt\n        text_tokens = self.token_service.tokenize(\"\".join(results))\n        text = self.token_service.detokenize(text_tokens[0:snippet_max_tokens])\n        logger.info(f\"Summarizing text: {text}\")\n\n        return summarize(\n            model=self.model,\n            language=self.settings.language,\n            goal=goal,\n            text=text,\n        )\n\n    async def chat(\n        self,\n        *,\n        message: str,\n        results: List[str],\n    ) -> FastAPIStreamingResponse:\n        self.model.model_name = \"gpt-3.5-turbo-16k\"\n        prompt = ChatPromptTemplate.from_messages(\n            [\n                SystemMessagePromptTemplate(prompt=chat_prompt),\n                *[HumanMessage(content=result) for result in results],\n                HumanMessage(content=message),\n            ]\n        )\n\n        self.token_service.calculate_max_tokens(\n            self.model,\n            prompt.format_prompt(\n                language=self.settings.language,\n            ).to_string(),\n        )\n\n        chain = LLMChain(llm=self.model, prompt=prompt)\n\n        return StreamingResponse.from_chain(\n            chain,\n            {\"language\": self.settings.language},\n            media_type=\"text/event-stream\",\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/analysis.py",
    "content": "from typing import Dict\n\nfrom pydantic import BaseModel, validator\n\n\nclass AnalysisArguments(BaseModel):\n    \"\"\"\n    Arguments for the analysis function of a tool. OpenAI functions will resolve these values but leave out the action.\n    \"\"\"\n\n    reasoning: str\n    arg: str\n\n\nclass Analysis(AnalysisArguments):\n    action: str\n\n    @validator(\"action\")\n    def action_must_be_valid_tool(cls, v: str) -> str:\n        # TODO: Remove circular import\n        from reworkd_platform.web.api.agent.tools.tools import get_available_tools_names\n\n        if v not in get_available_tools_names():\n            raise ValueError(f\"Analysis action '{v}' is not a valid tool\")\n        return v\n\n    @validator(\"action\")\n    def search_action_must_have_arg(cls, v: str, values: Dict[str, str]) -> str:\n        from reworkd_platform.web.api.agent.tools.search import Search\n        from reworkd_platform.web.api.agent.tools.tools import get_tool_name\n\n        if v == get_tool_name(Search) and not values[\"arg\"]:\n            raise ValueError(\"Analysis arg cannot be empty if action is 'search'\")\n        return v\n\n    @classmethod\n    def get_default_analysis(cls, task: str) -> \"Analysis\":\n        # TODO: Remove circular import\n        from reworkd_platform.web.api.agent.tools.tools import get_default_tool_name\n\n        return cls(\n            reasoning=\"Hmm... I'll try searching it up\",\n            action=get_default_tool_name(),\n            arg=task,\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/dependancies.py",
    "content": "from typing import TypeVar\n\nfrom fastapi import Body, Depends\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom reworkd_platform.db.crud.agent import AgentCRUD\nfrom reworkd_platform.db.dependencies import get_db_session\nfrom reworkd_platform.schemas.agent import (\n    AgentChat,\n    AgentRun,\n    AgentRunCreate,\n    AgentSummarize,\n    AgentTaskAnalyze,\n    AgentTaskCreate,\n    AgentTaskExecute,\n    Loop_Step,\n)\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.web.api.dependencies import get_current_user\n\nT = TypeVar(\n    \"T\", AgentTaskAnalyze, AgentTaskExecute, AgentTaskCreate, AgentSummarize, AgentChat\n)\n\n\ndef agent_crud(\n    user: UserBase = Depends(get_current_user),\n    session: AsyncSession = Depends(get_db_session),\n) -> AgentCRUD:\n    return AgentCRUD(session, user)\n\n\nasync def agent_start_validator(\n    body: AgentRunCreate = Body(\n        example={\n            \"goal\": \"Create business plan for a bagel company\",\n            \"modelSettings\": {\n                \"customModelName\": \"gpt-3.5-turbo\",\n            },\n        },\n    ),\n    crud: AgentCRUD = Depends(agent_crud),\n) -> AgentRun:\n    id_ = (await crud.create_run(body.goal)).id\n    return AgentRun(**body.dict(), run_id=str(id_))\n\n\nasync def validate(body: T, crud: AgentCRUD, type_: Loop_Step) -> T:\n    body.run_id = (await crud.create_task(body.run_id, type_)).id\n    return body\n\n\nasync def agent_analyze_validator(\n    body: AgentTaskAnalyze = Body(),\n    crud: AgentCRUD = Depends(agent_crud),\n) -> AgentTaskAnalyze:\n    return await validate(body, crud, \"analyze\")\n\n\nasync def agent_execute_validator(\n    body: AgentTaskExecute = Body(\n        example={\n            \"goal\": \"Perform tasks accurately\",\n            \"task\": \"Write code to make a platformer\",\n            \"analysis\": {\n                \"reasoning\": \"I like to write code.\",\n                \"action\": \"code\",\n                \"arg\": \"\",\n            },\n        },\n    ),\n    crud: AgentCRUD = Depends(agent_crud),\n) -> AgentTaskExecute:\n    return await validate(body, crud, \"execute\")\n\n\nasync def agent_create_validator(\n    body: AgentTaskCreate = Body(),\n    crud: AgentCRUD = Depends(agent_crud),\n) -> AgentTaskCreate:\n    return await validate(body, crud, \"create\")\n\n\nasync def agent_summarize_validator(\n    body: AgentSummarize = Body(),\n    crud: AgentCRUD = Depends(agent_crud),\n) -> AgentSummarize:\n    return await validate(body, crud, \"summarize\")\n\n\nasync def agent_chat_validator(\n    body: AgentChat = Body(),\n    crud: AgentCRUD = Depends(agent_crud),\n) -> AgentChat:\n    return await validate(body, crud, \"chat\")\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/helpers.py",
    "content": "from typing import Any, Callable, Dict, TypeVar\n\nfrom langchain import BasePromptTemplate, LLMChain\nfrom langchain.chat_models.base import BaseChatModel\nfrom langchain.schema import BaseOutputParser, OutputParserException\nfrom openai.error import (\n    AuthenticationError,\n    InvalidRequestError,\n    RateLimitError,\n    ServiceUnavailableError,\n)\n\nfrom reworkd_platform.schemas.agent import ModelSettings\nfrom reworkd_platform.web.api.errors import OpenAIError\n\nT = TypeVar(\"T\")\n\n\ndef parse_with_handling(parser: BaseOutputParser[T], completion: str) -> T:\n    try:\n        return parser.parse(completion)\n    except OutputParserException as e:\n        raise OpenAIError(\n            e, \"There was an issue parsing the response from the AI model.\"\n        )\n\n\nasync def openai_error_handler(\n    func: Callable[..., Any], *args: Any, settings: ModelSettings, **kwargs: Any\n) -> Any:\n    try:\n        return await func(*args, **kwargs)\n    except ServiceUnavailableError as e:\n        raise OpenAIError(\n            e,\n            \"OpenAI is experiencing issues. Visit \"\n            \"https://status.openai.com/ for more info.\",\n            should_log=not settings.custom_api_key,\n        )\n    except InvalidRequestError as e:\n        if e.user_message.startswith(\"The model:\"):\n            raise OpenAIError(\n                e,\n                f\"Your API key does not have access to your current model. Please use a different model.\",\n                should_log=not settings.custom_api_key,\n            )\n        raise OpenAIError(e, e.user_message)\n    except AuthenticationError as e:\n        raise OpenAIError(\n            e,\n            \"Authentication error: Ensure a valid API key is being used.\",\n            should_log=not settings.custom_api_key,\n        )\n    except RateLimitError as e:\n        if e.user_message.startswith(\"You exceeded your current quota\"):\n            raise OpenAIError(\n                e,\n                f\"Your API key exceeded your current quota, please check your plan and billing details.\",\n                should_log=not settings.custom_api_key,\n            )\n        raise OpenAIError(e, e.user_message)\n    except Exception as e:\n        raise OpenAIError(\n            e, \"There was an unexpected issue getting a response from the AI model.\"\n        )\n\n\nasync def call_model_with_handling(\n    model: BaseChatModel,\n    prompt: BasePromptTemplate,\n    args: Dict[str, str],\n    settings: ModelSettings,\n    **kwargs: Any,\n) -> str:\n    chain = LLMChain(llm=model, prompt=prompt)\n    return await openai_error_handler(chain.arun, args, settings=settings, **kwargs)\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/model_factory.py",
    "content": "from typing import Any, Dict, Optional, Tuple, Type, Union\n\nfrom langchain.chat_models import AzureChatOpenAI, ChatOpenAI\nfrom pydantic import Field\n\nfrom reworkd_platform.schemas.agent import LLM_Model, ModelSettings\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.settings import Settings\n\n\nclass WrappedChatOpenAI(ChatOpenAI):\n    client: Any = Field(\n        default=None,\n        description=\"Meta private value but mypy will complain its missing\",\n    )\n    max_tokens: int\n    model_name: LLM_Model = Field(alias=\"model\")\n\n\nclass WrappedAzureChatOpenAI(AzureChatOpenAI, WrappedChatOpenAI):\n    openai_api_base: str\n    openai_api_version: str\n    deployment_name: str\n\n\nWrappedChat = Union[WrappedAzureChatOpenAI, WrappedChatOpenAI]\n\n\ndef create_model(\n    settings: Settings,\n    model_settings: ModelSettings,\n    user: UserBase,\n    streaming: bool = False,\n    force_model: Optional[LLM_Model] = None,\n) -> WrappedChat:\n    use_azure = (\n        not model_settings.custom_api_key and \"azure\" in settings.openai_api_base\n    )\n\n    llm_model = force_model or model_settings.model\n    model: Type[WrappedChat] = WrappedChatOpenAI\n    base, headers, use_helicone = get_base_and_headers(settings, model_settings, user)\n    kwargs = {\n        \"openai_api_base\": base,\n        \"openai_api_key\": model_settings.custom_api_key or settings.openai_api_key,\n        \"temperature\": model_settings.temperature,\n        \"model\": llm_model,\n        \"max_tokens\": model_settings.max_tokens,\n        \"streaming\": streaming,\n        \"max_retries\": 5,\n        \"model_kwargs\": {\"user\": user.email, \"headers\": headers},\n    }\n\n    if use_azure:\n        model = WrappedAzureChatOpenAI\n        deployment_name = llm_model.replace(\".\", \"\")\n        kwargs.update(\n            {\n                \"openai_api_version\": settings.openai_api_version,\n                \"deployment_name\": deployment_name,\n                \"openai_api_type\": \"azure\",\n                \"openai_api_base\": base.rstrip(\"v1\"),\n            }\n        )\n\n        if use_helicone:\n            kwargs[\"model\"] = deployment_name\n\n    return model(**kwargs)  # type: ignore\n\n\ndef get_base_and_headers(\n    settings_: Settings, model_settings: ModelSettings, user: UserBase\n) -> Tuple[str, Optional[Dict[str, str]], bool]:\n    use_helicone = settings_.helicone_enabled and not model_settings.custom_api_key\n    base = (\n        settings_.helicone_api_base\n        if use_helicone\n        else (\n            \"https://api.openai.com/v1\"\n            if model_settings.custom_api_key\n            else settings_.openai_api_base\n        )\n    )\n\n    headers = (\n        {\n            \"Helicone-Auth\": f\"Bearer {settings_.helicone_api_key}\",\n            \"Helicone-Cache-Enabled\": \"true\",\n            \"Helicone-User-Id\": user.id,\n            \"Helicone-OpenAI-Api-Base\": settings_.openai_api_base,\n        }\n        if use_helicone\n        else None\n    )\n\n    return base, headers, use_helicone\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/prompts.py",
    "content": "from langchain import PromptTemplate\n\n# Create initial tasks using plan and solve prompting\n# https://github.com/AGI-Edgerunners/Plan-and-Solve-Prompting\nstart_goal_prompt = PromptTemplate(\n    template=\"\"\"You are a task creation AI called AgentGPT. \nYou answer in the \"{language}\" language. You have the following objective \"{goal}\". \nReturn a list of search queries that would be required to answer the entirety of the objective. \nLimit the list to a maximum of 5 queries. Ensure the queries are as succinct as possible. \nFor simple questions use a single query.\n\nReturn the response as a JSON array of strings. Examples:\n\nquery: \"Who is considered the best NBA player in the current season?\", answer: [\"current NBA MVP candidates\"]\nquery: \"How does the Olympicpayroll brand currently stand in the market, and what are its prospects and strategies for expansion in NJ, NY, and PA?\", answer: [\"Olympicpayroll brand comprehensive analysis 2023\", \"customer reviews of Olympicpayroll.com\", \"Olympicpayroll market position analysis\", \"payroll industry trends forecast 2023-2025\", \"payroll services expansion strategies in NJ, NY, PA\"]\nquery: \"How can I create a function to add weight to edges in a digraph using {language}?\", answer: [\"algorithm to add weight to digraph edge in {language}\"]\nquery: \"What is the current weather in New York?\", answer: [\"current weather in New York\"]\nquery: \"5 + 5?\", answer: [\"Sum of 5 and 5\"]\nquery: \"What is a good homemade recipe for KFC-style chicken?\", answer: [\"KFC style chicken recipe at home\"]\nquery: \"What are the nutritional values of almond milk and soy milk?\", answer: [\"nutritional information of almond milk\", \"nutritional information of soy milk\"]\"\"\",\n    input_variables=[\"goal\", \"language\"],\n)\n\nanalyze_task_prompt = PromptTemplate(\n    template=\"\"\"\n    High level objective: \"{goal}\"\n    Current task: \"{task}\"\n\n    Based on this information, use the best function to make progress or accomplish the task entirely.\n    Select the correct function by being smart and efficient. Ensure \"reasoning\" and only \"reasoning\" is in the\n    {language} language.\n\n    Note you MUST select a function.\n    \"\"\",\n    input_variables=[\"goal\", \"task\", \"language\"],\n)\n\ncode_prompt = PromptTemplate(\n    template=\"\"\"\n    You are a world-class software engineer and an expert in all programing languages,\n    software systems, and architecture.\n\n    For reference, your high level goal is {goal}\n\n    Write code in English but explanations/comments in the \"{language}\" language.\n\n    Provide no information about who you are and focus on writing code.\n    Ensure code is bug and error free and explain complex concepts through comments\n    Respond in well-formatted markdown. Ensure code blocks are used for code sections.\n    Approach problems step by step and file by file, for each section, use a heading to describe the section.\n\n    Write code to accomplish the following:\n    {task}\n    \"\"\",\n    input_variables=[\"goal\", \"language\", \"task\"],\n)\n\nexecute_task_prompt = PromptTemplate(\n    template=\"\"\"Answer in the \"{language}\" language. Given\n    the following overall objective `{goal}` and the following sub-task, `{task}`.\n\n    Perform the task by understanding the problem, extracting variables, and being smart\n    and efficient. Write a detailed response that address the task.\n    When confronted with choices, make a decision yourself with reasoning.\n    \"\"\",\n    input_variables=[\"goal\", \"language\", \"task\"],\n)\n\ncreate_tasks_prompt = PromptTemplate(\n    template=\"\"\"You are an AI task creation agent. You must answer in the \"{language}\"\n    language. You have the following objective `{goal}`.\n\n    You have the following incomplete tasks:\n    `{tasks}`\n\n    You just completed the following task:\n    `{lastTask}`\n\n    And received the following result:\n    `{result}`.\n\n    Based on this, create a single new task to be completed by your AI system such that your goal is closer reached.\n    If there are no more tasks to be done, return nothing. Do not add quotes to the task.\n\n    Examples:\n    Search the web for NBA news\n    Create a function to add a new vertex with a specified weight to the digraph.\n    Search for any additional information on Bertie W.\n    \"\"\n    \"\"\",\n    input_variables=[\"goal\", \"language\", \"tasks\", \"lastTask\", \"result\"],\n)\n\nsummarize_prompt = PromptTemplate(\n    template=\"\"\"You must answer in the \"{language}\" language.\n\n    Combine the following text into a cohesive document:\n\n    \"{text}\"\n\n    Write using clear markdown formatting in a style expected of the goal \"{goal}\".\n    Be as clear, informative, and descriptive as necessary.\n    You will not make up information or add any information outside of the above text.\n    Only use the given information and nothing more.\n\n    If there is no information provided, say \"There is nothing to summarize\".\n    \"\"\",\n    input_variables=[\"goal\", \"language\", \"text\"],\n)\n\ncompany_context_prompt = PromptTemplate(\n    template=\"\"\"You must answer in the \"{language}\" language.\n\n    Create a short description on \"{company_name}\".\n    Find out what sector it is in and what are their primary products.\n\n    Be as clear, informative, and descriptive as necessary.\n    You will not make up information or add any information outside of the above text.\n    Only use the given information and nothing more.\n\n    If there is no information provided, say \"There is nothing to summarize\".\n    \"\"\",\n    input_variables=[\"company_name\", \"language\"],\n)\n\nsummarize_pdf_prompt = PromptTemplate(\n    template=\"\"\"You must answer in the \"{language}\" language.\n\n    For the given text: \"{text}\", you have the following objective \"{query}\".\n\n    Be as clear, informative, and descriptive as necessary.\n    You will not make up information or add any information outside of the above text.\n    Only use the given information and nothing more.\n    \"\"\",\n    input_variables=[\"query\", \"language\", \"text\"],\n)\n\nsummarize_with_sources_prompt = PromptTemplate(\n    template=\"\"\"You must answer in the \"{language}\" language.\n\n    Answer the following query: \"{query}\" using the following information: \"{snippets}\".\n    Write using clear markdown formatting and use markdown lists where possible.\n\n    Cite sources for sentences via markdown links using the source link as the link and the index as the text.\n    Use in-line sources. Do not separately list sources at the end of the writing.\n    \n    If the query cannot be answered with the provided information, mention this and provide a reason why along with what it does mention. \n    Also cite the sources of what is actually mentioned.\n    \n    Example sentences of the paragraph: \n    \"So this is a cited sentence at the end of a paragraph[1](https://test.com). This is another sentence.\"\n    \"Stephen curry is an american basketball player that plays for the warriors[1](https://www.britannica.com/biography/Stephen-Curry).\"\n    \"The economic growth forecast for the region has been adjusted from 2.5% to 3.1% due to improved trade relations[1](https://economictimes.com), while inflation rates are expected to remain steady at around 1.7% according to financial analysts[2](https://financeworld.com).\"\n    \"\"\",\n    input_variables=[\"language\", \"query\", \"snippets\"],\n)\n\nsummarize_sid_prompt = PromptTemplate(\n    template=\"\"\"You must answer in the \"{language}\" language.\n\n    Parse and summarize the following text snippets \"{snippets}\".\n    Write using clear markdown formatting in a style expected of the goal \"{goal}\".\n    Be as clear, informative, and descriptive as necessary and attempt to\n    answer the query: \"{query}\" as best as possible.\n    If any of the snippets are not relevant to the query,\n    ignore them, and do not include them in the summary.\n    Do not mention that you are ignoring them.\n\n    If there is no information provided, say \"There is nothing to summarize\".\n    \"\"\",\n    input_variables=[\"goal\", \"language\", \"query\", \"snippets\"],\n)\n\nchat_prompt = PromptTemplate(\n    template=\"\"\"You must answer in the \"{language}\" language.\n\n    You are a helpful AI Assistant that will provide responses based on the current conversation history.\n\n    The human will provide previous messages as context. Use ONLY this information for your responses.\n    Do not make anything up and do not add any additional information.\n    If you have no information for a given question in the conversation history,\n    say \"I do not have any information on this\".\n    \"\"\",\n    input_variables=[\"language\"],\n)\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/stream_mock.py",
    "content": "import asyncio\nfrom typing import AsyncGenerator\n\nimport tiktoken\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\n\napp = FastAPI()\n\n\ndef stream_string(data: str, delayed: bool = False) -> FastAPIStreamingResponse:\n    return FastAPIStreamingResponse(\n        stream_generator(data, delayed),\n    )\n\n\nasync def stream_generator(data: str, delayed: bool) -> AsyncGenerator[bytes, None]:\n    if delayed:\n        encoding = tiktoken.get_encoding(\"cl100k_base\")\n        token_data = encoding.encode(data)\n\n        for token in token_data:\n            yield encoding.decode([token]).encode(\"utf-8\")\n            await asyncio.sleep(0.025)  # simulate slow processing\n    else:\n        yield data.encode()\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/task_output_parser.py",
    "content": "import ast\nimport re\nfrom typing import List\n\nfrom langchain.schema import BaseOutputParser, OutputParserException\n\n\nclass TaskOutputParser(BaseOutputParser[List[str]]):\n    \"\"\"\n    Extension of LangChain's BaseOutputParser\n    Responsible for parsing task creation output into a list of task strings\n    \"\"\"\n\n    completed_tasks: List[str] = []\n\n    def __init__(self, *, completed_tasks: List[str]):\n        super().__init__()\n        self.completed_tasks = completed_tasks\n\n    def parse(self, text: str) -> List[str]:\n        try:\n            array_str = extract_array(text)\n            all_tasks = [\n                remove_prefix(task) for task in array_str if real_tasks_filter(task)\n            ]\n            return [task for task in all_tasks if task not in self.completed_tasks]\n        except Exception as e:\n            msg = f\"Failed to parse tasks from completion '{text}'. Exception: {e}\"\n            raise OutputParserException(msg)\n\n    def get_format_instructions(self) -> str:\n        return \"\"\"\n        The response should be a JSON array of strings. Example:\n\n        [\"Search the web for NBA news\", \"Write some code to build a web scraper\"]\n\n        This should be parsable by json.loads()\n        \"\"\"\n\n\ndef extract_array(input_str: str) -> List[str]:\n    regex = (\n        r\"\\[\\s*\\]|\"  # Empty array check\n        r\"(\\[(?:\\s*(?:\\\"(?:[^\\\"\\\\]|\\\\.)*\\\"|\\'(?:[^\\'\\\\]|\\\\.)*\\')\\s*,?)*\\s*\\])\"\n    )\n    match = re.search(regex, input_str)\n    if match is not None:\n        return ast.literal_eval(match[0])\n    else:\n        return handle_multiline_string(input_str)\n\n\ndef handle_multiline_string(input_str: str) -> List[str]:\n    # Handle multiline string as a list\n    processed_lines = [\n        re.sub(r\".*?(\\d+\\..+)\", r\"\\1\", line).strip()\n        for line in input_str.split(\"\\n\")\n        if line.strip() != \"\"\n    ]\n\n    # Check if there is at least one line that starts with a digit and a period\n    if any(re.match(r\"\\d+\\..+\", line) for line in processed_lines):\n        return processed_lines\n    else:\n        raise RuntimeError(f\"Failed to extract array from {input_str}\")\n\n\ndef remove_prefix(input_str: str) -> str:\n    prefix_pattern = (\n        r\"^(Task\\s*\\d*\\.\\s*|Task\\s*\\d*[-:]?\\s*|Step\\s*\\d*[\"\n        r\"-:]?\\s*|Step\\s*[-:]?\\s*|\\d+\\.\\s*|\\d+\\s*[-:]?\\s*|^\\.\\s*|^\\.*)\"\n    )\n    return re.sub(prefix_pattern, \"\", input_str, flags=re.IGNORECASE)\n\n\ndef real_tasks_filter(input_str: str) -> bool:\n    no_task_regex = (\n        r\"^No( (new|further|additional|extra|other))? tasks? (is )?(\"\n        r\"required|needed|added|created|inputted).*\"\n    )\n    task_complete_regex = r\"^Task (complete|completed|finished|done|over|success).*\"\n    do_nothing_regex = r\"^(\\s*|Do nothing(\\s.*)?)$\"\n\n    return (\n        not re.search(no_task_regex, input_str, re.IGNORECASE)\n        and not re.search(task_complete_regex, input_str, re.IGNORECASE)\n        and not re.search(do_nothing_regex, input_str, re.IGNORECASE)\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/__init__.py",
    "content": ""
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/code.py",
    "content": "from typing import Any\n\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom lanarky.responses import StreamingResponse\nfrom langchain import LLMChain\n\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\n\n\nclass Code(Tool):\n    description = \"Should only be used to write code, refactor code, fix code bugs, and explain programming concepts.\"\n    public_description = \"Write and review code.\"\n\n    async def call(\n        self, goal: str, task: str, input_str: str, *args: Any, **kwargs: Any\n    ) -> FastAPIStreamingResponse:\n        from reworkd_platform.web.api.agent.prompts import code_prompt\n\n        chain = LLMChain(llm=self.model, prompt=code_prompt)\n\n        return StreamingResponse.from_chain(\n            chain,\n            {\"goal\": goal, \"language\": self.language, \"task\": task},\n            media_type=\"text/event-stream\",\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/conclude.py",
    "content": "from typing import Any\n\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\n\nfrom reworkd_platform.web.api.agent.stream_mock import stream_string\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\n\n\nclass Conclude(Tool):\n    description = \"Use when there is nothing else to do. The task has been concluded.\"\n\n    async def call(\n        self, goal: str, task: str, input_str: str, *args: Any, **kwargs: Any\n    ) -> FastAPIStreamingResponse:\n        return stream_string(\"Task execution concluded.\", delayed=True)\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/image.py",
    "content": "from typing import Any\n\nimport openai\nimport replicate\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom replicate.exceptions import ModelError\nfrom replicate.exceptions import ReplicateError as ReplicateAPIError\n\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.agent.stream_mock import stream_string\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\nfrom reworkd_platform.web.api.errors import ReplicateError\n\n\nasync def get_replicate_image(input_str: str) -> str:\n    if settings.replicate_api_key is None or settings.replicate_api_key == \"\":\n        raise RuntimeError(\"Replicate API key not set\")\n\n    client = replicate.Client(settings.replicate_api_key)\n    try:\n        output = client.run(\n            \"stability-ai/stable-diffusion\"\n            \":db21e45d3f7023abc2a46ee38a23973f6dce16bb082a930b0c49861f96d1e5bf\",\n            input={\"prompt\": input_str},\n            image_dimensions=\"512x512\",\n        )\n    except ModelError as e:\n        raise ReplicateError(e, \"Image generation failed due to NSFW image.\")\n    except ReplicateAPIError as e:\n        raise ReplicateError(e, \"Failed to generate an image.\")\n\n    return output[0]\n\n\n# Use AI to generate an Image based on a prompt\nasync def get_open_ai_image(input_str: str) -> str:\n    response = openai.Image.create(\n        api_key=settings.openai_api_key,\n        prompt=input_str,\n        n=1,\n        size=\"256x256\",\n    )\n\n    return response[\"data\"][0][\"url\"]\n\n\nclass Image(Tool):\n    description = \"Used to sketch, draw, or generate an image.\"\n    public_description = \"Generate AI images.\"\n    arg_description = (\n        \"The input prompt to the image generator. \"\n        \"This should be a detailed description of the image touching on image \"\n        \"style, image focus, color, etc.\"\n    )\n    image_url = \"/tools/replicate.png\"\n\n    async def call(\n        self, goal: str, task: str, input_str: str, *args: Any, **kwargs: Any\n    ) -> FastAPIStreamingResponse:\n        # Use the replicate API if its available, otherwise use DALL-E\n        try:\n            url = await get_replicate_image(input_str)\n        except RuntimeError:\n            url = await get_open_ai_image(input_str)\n\n        return stream_string(f\"![{input_str}]({url})\")\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/open_ai_function.py",
    "content": "from typing import Type, TypedDict\n\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\nfrom reworkd_platform.web.api.agent.tools.tools import get_tool_name\n\n\nclass FunctionDescription(TypedDict):\n    \"\"\"Representation of a callable function to the OpenAI API.\"\"\"\n\n    name: str\n    \"\"\"The name of the function.\"\"\"\n    description: str\n    \"\"\"A description of the function.\"\"\"\n    parameters: dict[str, object]\n    \"\"\"The parameters of the function.\"\"\"\n\n\ndef get_tool_function(tool: Type[Tool]) -> FunctionDescription:\n    \"\"\"A function that will return the tool's function specification\"\"\"\n    name = get_tool_name(tool)\n\n    return {\n        \"name\": name,\n        \"description\": tool.description,\n        \"parameters\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"reasoning\": {\n                    \"type\": \"string\",\n                    \"description\": (\n                        f\"Reasoning is how the task will be accomplished with the current function. \"\n                        \"Detail your overall plan along with any concerns you have.\"\n                        \"Ensure this reasoning value is in the user defined langauge \"\n                    ),\n                },\n                \"arg\": {\n                    \"type\": \"string\",\n                    \"description\": tool.arg_description,\n                },\n            },\n            \"required\": [\"reasoning\", \"arg\"],\n        },\n    }\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/reason.py",
    "content": "from typing import Any\n\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom lanarky.responses import StreamingResponse\nfrom langchain import LLMChain\n\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\n\n\nclass Reason(Tool):\n    description = (\n        \"Reason about task via existing information or understanding. \"\n        \"Make decisions / selections from options.\"\n    )\n\n    async def call(\n        self, goal: str, task: str, input_str: str, *args: Any, **kwargs: Any\n    ) -> FastAPIStreamingResponse:\n        from reworkd_platform.web.api.agent.prompts import execute_task_prompt\n\n        chain = LLMChain(llm=self.model, prompt=execute_task_prompt)\n\n        return StreamingResponse.from_chain(\n            chain,\n            {\"goal\": goal, \"language\": self.language, \"task\": task},\n            media_type=\"text/event-stream\",\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/search.py",
    "content": "from typing import Any, List\nfrom urllib.parse import quote\n\nimport aiohttp\nfrom aiohttp import ClientResponseError\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom loguru import logger\n\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.agent.stream_mock import stream_string\nfrom reworkd_platform.web.api.agent.tools.reason import Reason\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\nfrom reworkd_platform.web.api.agent.tools.utils import (\n    CitedSnippet,\n    summarize_with_sources,\n)\n\n# Search google via serper.dev. Adapted from LangChain\n# https://github.com/hwchase17/langchain/blob/master/langchain/utilities\n\n\nasync def _google_serper_search_results(\n    search_term: str, search_type: str = \"search\"\n) -> dict[str, Any]:\n    headers = {\n        \"X-API-KEY\": settings.serp_api_key or \"\",\n        \"Content-Type\": \"application/json\",\n    }\n    params = {\n        \"q\": search_term,\n    }\n\n    async with aiohttp.ClientSession() as session:\n        async with session.post(\n            f\"https://google.serper.dev/{search_type}\", headers=headers, params=params\n        ) as response:\n            response.raise_for_status()\n            search_results = await response.json()\n            return search_results\n\n\nclass Search(Tool):\n    description = (\n        \"Search Google for short up to date searches for simple questions about public information \"\n        \"news and people.\\n\"\n    )\n    public_description = \"Search google for information about current events.\"\n    arg_description = \"The query argument to search for. This value is always populated and cannot be an empty string.\"\n    image_url = \"/tools/google.png\"\n\n    @staticmethod\n    def available() -> bool:\n        return settings.serp_api_key is not None and settings.serp_api_key != \"\"\n\n    async def call(\n        self, goal: str, task: str, input_str: str, *args: Any, **kwargs: Any\n    ) -> FastAPIStreamingResponse:\n        try:\n            return await self._call(goal, task, input_str, *args, **kwargs)\n        except ClientResponseError:\n            logger.exception(\"Error calling Serper API, falling back to reasoning\")\n            return await Reason(self.model, self.language).call(\n                goal, task, input_str, *args, **kwargs\n            )\n\n    async def _call(\n        self, goal: str, task: str, input_str: str, *args: Any, **kwargs: Any\n    ) -> FastAPIStreamingResponse:\n        results = await _google_serper_search_results(\n            input_str,\n        )\n\n        k = 5  # Number of results to return\n        snippets: List[CitedSnippet] = []\n\n        if results.get(\"answerBox\"):\n            answer_values = []\n            answer_box = results.get(\"answerBox\", {})\n            if answer_box.get(\"answer\"):\n                answer_values.append(answer_box.get(\"answer\"))\n            elif answer_box.get(\"snippet\"):\n                answer_values.append(answer_box.get(\"snippet\").replace(\"\\n\", \" \"))\n            elif answer_box.get(\"snippetHighlighted\"):\n                answer_values.append(\", \".join(answer_box.get(\"snippetHighlighted\")))\n\n            if len(answer_values) > 0:\n                snippets.append(\n                    CitedSnippet(\n                        len(snippets) + 1,\n                        \"\\n\".join(answer_values),\n                        f\"https://www.google.com/search?q={quote(input_str)}\",\n                    )\n                )\n\n        for i, result in enumerate(results[\"organic\"][:k]):\n            texts = []\n            link = \"\"\n            if \"snippet\" in result:\n                texts.append(result[\"snippet\"])\n            if \"link\" in result:\n                link = result[\"link\"]\n            for attribute, value in result.get(\"attributes\", {}).items():\n                texts.append(f\"{attribute}: {value}.\")\n            snippets.append(CitedSnippet(len(snippets) + 1, \"\\n\".join(texts), link))\n\n        if len(snippets) == 0:\n            return stream_string(\"No good Google Search Result was found\", True)\n\n        return summarize_with_sources(self.model, self.language, goal, task, snippets)\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/sidsearch.py",
    "content": "import json\nfrom datetime import datetime, timedelta\nfrom typing import Any, List, Optional\n\nimport aiohttp\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom loguru import logger\n\nfrom reworkd_platform.db.crud.oauth import OAuthCrud\nfrom reworkd_platform.db.models.auth import OauthCredentials\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.services.security import encryption_service\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.agent.stream_mock import stream_string\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\nfrom reworkd_platform.web.api.agent.tools.utils import Snippet, summarize_sid\n\nfrom reworkd_platform.web.api.agent.tools.search import Search\n\n\nasync def _sid_search_results(\n    search_term: str, limit: int, token: str\n) -> dict[str, Any]:\n    headers = {\"Authorization\": f\"Bearer {token}\", \"Content-Type\": \"application/json\"}\n    data = {\"query\": search_term, \"limit\": limit}\n\n    async with aiohttp.ClientSession() as session:\n        async with session.post(\n            \"https://api.sid.ai/v1/users/me/query\",\n            headers=headers,\n            data=json.dumps(data),\n        ) as response:\n            response.raise_for_status()\n            search_results = await response.json()\n            return search_results\n\n\nasync def token_exchange(refresh_token: str) -> tuple[str, datetime]:\n    data = {\n        \"grant_type\": \"refresh_token\",\n        \"client_id\": settings.sid_client_id,\n        \"client_secret\": settings.sid_client_secret,\n        \"redirect_uri\": settings.sid_redirect_uri,\n        \"refresh_token\": refresh_token,\n    }\n    async with aiohttp.ClientSession() as session:\n        async with session.post(\n            \"https://auth.sid.ai/oauth/token\", data=data\n        ) as response:\n            response.raise_for_status()\n            response_data = await response.json()\n            access_token = response_data[\"access_token\"]\n            expires_in = response_data[\"expires_in\"]\n    return access_token, datetime.now() + timedelta(seconds=expires_in)\n\n\nasync def get_access_token(\n    oauth_crud: OAuthCrud, installation: OauthCredentials\n) -> Optional[str]:\n    if not installation.refresh_token_enc:\n        return None\n    if datetime.now() + timedelta(minutes=5) > installation.access_token_expiration:\n        refresh_token = encryption_service.decrypt(installation.refresh_token_enc)\n        access_token, expiration = await token_exchange(refresh_token)\n        installation.access_token_enc = encryption_service.encrypt(access_token)\n        installation.access_token_expiration = expiration\n        await installation.save(oauth_crud.session)\n\n    return encryption_service.decrypt(installation.access_token_enc)\n\n\nclass SID(Tool):\n    public_description = \"Grant access to your Notion, Google Drive, etc.\"\n    description = \"\"\"\n        Find private information by searching through notion, email and google drive.\n        Should be used when questions refer to personal information.\n    \"\"\"\n    arg_description = (\n        \"The query to search for. It should be a question in natural language.\"\n    )\n    image_url = \"/tools/sid.png\"\n\n    @staticmethod\n    def available() -> bool:\n        return settings.sid_enabled\n\n    @staticmethod\n    async def dynamic_available(user: UserBase, oauth_crud: OAuthCrud) -> bool:\n        installation = await oauth_crud.get_installation_by_user_id(\n            user_id=user.id, provider=\"sid\"\n        )\n\n        return bool(installation and installation.access_token_enc)\n\n    async def _run_sid(\n        self,\n        goal: str,\n        task: str,\n        input_str: str,\n        user: UserBase,\n        oauth_crud: OAuthCrud,\n    ) -> Optional[FastAPIStreamingResponse]:\n        installation = await oauth_crud.get_installation_by_user_id(\n            user_id=user.id, provider=\"sid\"\n        )\n        if not installation:\n            logger.warning(\"No sid installation found for user {user.id}\")\n            return None\n\n        token = await get_access_token(oauth_crud, installation)\n        if not token:\n            logger.warning(\"Unable to fetch sid access token for {user.id}\")\n            return None\n\n        try:\n            res = await _sid_search_results(input_str, limit=10, token=token)\n            snippets: List[Snippet] = [\n                Snippet(text=result[\"text\"]) for result in (res.get(\"results\", []))\n            ]\n        except Exception as e:\n            logger.exception(e)\n            return None\n\n        if not snippets:\n            return None\n\n        return summarize_sid(self.model, self.language, goal, task, snippets)\n\n\n    async def call(\n        self,\n        goal: str,\n        task: str,\n        input_str: str,\n        user: UserBase,\n        oauth_crud: OAuthCrud,\n        *args: Any,\n        **kwargs: Any,\n    ) -> FastAPIStreamingResponse:\n         # fall back to search if no results are found\n        return await self._run_sid(goal, task, input_str, user, oauth_crud) or await Search(self.model, self.language).call(\n        goal, task, input_str, user, oauth_crud\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/tool.py",
    "content": "from abc import ABC, abstractmethod\nfrom typing import Optional\n\nfrom lanarky.responses import StreamingResponse\nfrom langchain.chat_models.base import BaseChatModel\n\nfrom reworkd_platform.db.crud.oauth import OAuthCrud\nfrom reworkd_platform.schemas.user import UserBase\n\n\nclass Tool(ABC):\n    description: str = \"\"\n    public_description: str = \"\"\n    arg_description: str = \"The argument to the function.\"\n    image_url: str = \"/tools/openai-white.png\"\n\n    model: BaseChatModel\n    language: str\n\n    def __init__(self, model: BaseChatModel, language: str):\n        self.model = model\n        self.language = language\n\n    @staticmethod\n    def available() -> bool:\n        return True\n\n    @staticmethod\n    async def dynamic_available(user: UserBase, oauth_crud: OAuthCrud) -> bool:\n        return True\n\n    @abstractmethod\n    async def call(\n        self,\n        goal: str,\n        task: str,\n        input_str: str,\n        user: UserBase,\n        oauth_crud: OAuthCrud,\n    ) -> StreamingResponse:\n        pass\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/tools.py",
    "content": "from typing import List, Type\n\nfrom reworkd_platform.db.crud.oauth import OAuthCrud\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.web.api.agent.tools.code import Code\nfrom reworkd_platform.web.api.agent.tools.image import Image\nfrom reworkd_platform.web.api.agent.tools.search import Search\nfrom reworkd_platform.web.api.agent.tools.sidsearch import SID\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\n\n\nasync def get_user_tools(\n    tool_names: List[str], user: UserBase, crud: OAuthCrud\n) -> List[Type[Tool]]:\n    tools = list(map(get_tool_from_name, tool_names)) + get_default_tools()\n    return [tool for tool in tools if await tool.dynamic_available(user, crud)]\n\n\ndef get_available_tools() -> List[Type[Tool]]:\n    return get_external_tools() + get_default_tools()\n\n\ndef get_available_tools_names() -> List[str]:\n    return [get_tool_name(tool) for tool in get_available_tools()]\n\n\ndef get_external_tools() -> List[Type[Tool]]:\n    return [\n        # Wikipedia,  # TODO: Remove if async doesn't work\n        Image,\n        Code,\n        SID,\n    ]\n\n\ndef get_default_tools() -> List[Type[Tool]]:\n    return [\n        Search,\n    ]\n\n\ndef get_tool_name(tool: Type[Tool]) -> str:\n    return format_tool_name(tool.__name__)\n\n\ndef format_tool_name(tool_name: str) -> str:\n    return tool_name.lower()\n\n\ndef get_tools_overview(tools: List[Type[Tool]]) -> str:\n    \"\"\"Return a formatted string of name: description pairs for all available tools\"\"\"\n\n    # Create a list of formatted strings\n    formatted_strings = [\n        f\"'{get_tool_name(tool)}': {tool.description}\" for tool in tools\n    ]\n\n    # Remove duplicates by converting the list to a set and back to a list\n    unique_strings = list(set(formatted_strings))\n\n    # Join the unique strings with newlines\n    return \"\\n\".join(unique_strings)\n\n\ndef get_tool_from_name(tool_name: str) -> Type[Tool]:\n    for tool in get_available_tools():\n        if get_tool_name(tool) == format_tool_name(tool_name):\n            return tool\n\n    return get_default_tool()\n\n\ndef get_default_tool() -> Type[Tool]:\n    return Search\n\n\ndef get_default_tool_name() -> str:\n    return get_tool_name(get_default_tool())\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/utils.py",
    "content": "from dataclasses import dataclass\nfrom typing import List\n\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom lanarky.responses import StreamingResponse\nfrom langchain import LLMChain\nfrom langchain.chat_models.base import BaseChatModel\n\n\n@dataclass\nclass CitedSnippet:\n    index: int\n    text: str\n    url: str = \"\"\n\n    def __repr__(self) -> str:\n        \"\"\"\n        The string representation the AI model will see\n        \"\"\"\n        return f\"{{i: {self.index}, text: {self.text}, url: {self.url}}}\"\n\n\n@dataclass\nclass Snippet:\n    text: str\n\n    def __repr__(self) -> str:\n        \"\"\"\n        The string representation the AI model will see\n        \"\"\"\n        return f\"{{text: {self.text}}}\"\n\n\ndef summarize(\n    model: BaseChatModel,\n    language: str,\n    goal: str,\n    text: str,\n) -> FastAPIStreamingResponse:\n    from reworkd_platform.web.api.agent.prompts import summarize_prompt\n\n    chain = LLMChain(llm=model, prompt=summarize_prompt)\n\n    return StreamingResponse.from_chain(\n        chain,\n        {\n            \"goal\": goal,\n            \"language\": language,\n            \"text\": text,\n        },\n        media_type=\"text/event-stream\",\n    )\n\n\ndef summarize_with_sources(\n    model: BaseChatModel,\n    language: str,\n    goal: str,\n    query: str,\n    snippets: List[CitedSnippet],\n) -> FastAPIStreamingResponse:\n    from reworkd_platform.web.api.agent.prompts import summarize_with_sources_prompt\n\n    chain = LLMChain(llm=model, prompt=summarize_with_sources_prompt)\n\n    return StreamingResponse.from_chain(\n        chain,\n        {\n            \"goal\": goal,\n            \"query\": query,\n            \"language\": language,\n            \"snippets\": snippets,\n        },\n        media_type=\"text/event-stream\",\n    )\n\n\ndef summarize_sid(\n    model: BaseChatModel,\n    language: str,\n    goal: str,\n    query: str,\n    snippets: List[Snippet],\n) -> FastAPIStreamingResponse:\n    from reworkd_platform.web.api.agent.prompts import summarize_sid_prompt\n\n    chain = LLMChain(llm=model, prompt=summarize_sid_prompt)\n\n    return StreamingResponse.from_chain(\n        chain,\n        {\n            \"goal\": goal,\n            \"query\": query,\n            \"language\": language,\n            \"snippets\": snippets,\n        },\n        media_type=\"text/event-stream\",\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/tools/wikipedia_search.py",
    "content": "from typing import Any\n\nfrom lanarky.responses import StreamingResponse\nfrom langchain import WikipediaAPIWrapper\n\nfrom reworkd_platform.web.api.agent.stream_mock import stream_string\nfrom reworkd_platform.web.api.agent.tools.tool import Tool\n\n\nclass Wikipedia(Tool):\n    description = (\n        \"Search Wikipedia for information about historical people, companies, events, \"\n        \"places or research. This should be used over search for broad overviews of \"\n        \"specific nouns.\"\n    )\n    public_description = \"Search Wikipedia for historical information.\"\n    arg_description = \"A simple query string of just the noun in question.\"\n    image_url = \"/tools/wikipedia.png\"\n\n    async def call(\n        self, goal: str, task: str, input_str: str, *args: Any, **kwargs: Any\n    ) -> StreamingResponse:\n        wikipedia_client = WikipediaAPIWrapper(\n            wiki_client=None,  # Meta private value but mypy will complain its missing\n        )\n\n        # TODO: Make the below async\n        wikipedia_search = wikipedia_client.run(input_str)\n        # return summarize_with_sources(self.model, self.language, goal, task, [wikipedia_search])\n        return stream_string(\"Wikipedia is currently not working\")\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/agent/views.py",
    "content": "from typing import List, Optional\n\nfrom fastapi import APIRouter, Depends\nfrom fastapi.responses import StreamingResponse as FastAPIStreamingResponse\nfrom pydantic import BaseModel\n\nfrom reworkd_platform.schemas.agent import (\n    AgentChat,\n    AgentRun,\n    AgentSummarize,\n    AgentTaskAnalyze,\n    AgentTaskCreate,\n    AgentTaskExecute,\n    NewTasksResponse,\n)\nfrom reworkd_platform.web.api.agent.agent_service.agent_service import AgentService\nfrom reworkd_platform.web.api.agent.agent_service.agent_service_provider import (\n    get_agent_service,\n)\nfrom reworkd_platform.web.api.agent.analysis import Analysis\nfrom reworkd_platform.web.api.agent.dependancies import (\n    agent_analyze_validator,\n    agent_chat_validator,\n    agent_create_validator,\n    agent_execute_validator,\n    agent_start_validator,\n    agent_summarize_validator,\n)\nfrom reworkd_platform.web.api.agent.tools.tools import get_external_tools, get_tool_name\n\nrouter = APIRouter()\n\n\n@router.post(\n    \"/start\",\n)\nasync def start_tasks(\n    req_body: AgentRun = Depends(agent_start_validator),\n    agent_service: AgentService = Depends(get_agent_service(agent_start_validator)),\n) -> NewTasksResponse:\n    new_tasks = await agent_service.start_goal_agent(goal=req_body.goal)\n    return NewTasksResponse(newTasks=new_tasks, run_id=req_body.run_id)\n\n\n@router.post(\"/analyze\")\nasync def analyze_tasks(\n    req_body: AgentTaskAnalyze = Depends(agent_analyze_validator),\n    agent_service: AgentService = Depends(get_agent_service(agent_analyze_validator)),\n) -> Analysis:\n    return await agent_service.analyze_task_agent(\n        goal=req_body.goal,\n        task=req_body.task or \"\",\n        tool_names=req_body.tool_names or [],\n    )\n\n\n@router.post(\"/execute\")\nasync def execute_tasks(\n    req_body: AgentTaskExecute = Depends(agent_execute_validator),\n    agent_service: AgentService = Depends(\n        get_agent_service(validator=agent_execute_validator, streaming=True),\n    ),\n) -> FastAPIStreamingResponse:\n    return await agent_service.execute_task_agent(\n        goal=req_body.goal or \"\",\n        task=req_body.task or \"\",\n        analysis=req_body.analysis,\n    )\n\n\n@router.post(\"/create\")\nasync def create_tasks(\n    req_body: AgentTaskCreate = Depends(agent_create_validator),\n    agent_service: AgentService = Depends(get_agent_service(agent_create_validator)),\n) -> NewTasksResponse:\n    new_tasks = await agent_service.create_tasks_agent(\n        goal=req_body.goal,\n        tasks=req_body.tasks or [],\n        last_task=req_body.last_task or \"\",\n        result=req_body.result or \"\",\n        completed_tasks=req_body.completed_tasks or [],\n    )\n    return NewTasksResponse(newTasks=new_tasks, run_id=req_body.run_id)\n\n\n@router.post(\"/summarize\")\nasync def summarize(\n    req_body: AgentSummarize = Depends(agent_summarize_validator),\n    agent_service: AgentService = Depends(\n        get_agent_service(\n            validator=agent_summarize_validator,\n            streaming=True,\n            llm_model=\"gpt-3.5-turbo-16k\",\n        ),\n    ),\n) -> FastAPIStreamingResponse:\n    return await agent_service.summarize_task_agent(\n        goal=req_body.goal or \"\",\n        results=req_body.results,\n    )\n\n\n@router.post(\"/chat\")\nasync def chat(\n    req_body: AgentChat = Depends(agent_chat_validator),\n    agent_service: AgentService = Depends(\n        get_agent_service(\n            validator=agent_chat_validator,\n            streaming=True,\n            llm_model=\"gpt-3.5-turbo-16k\",\n        ),\n    ),\n) -> FastAPIStreamingResponse:\n    return await agent_service.chat(\n        message=req_body.message,\n        results=req_body.results,\n    )\n\n\nclass ToolModel(BaseModel):\n    name: str\n    description: str\n    color: str\n    image_url: Optional[str]\n\n\nclass ToolsResponse(BaseModel):\n    tools: List[ToolModel]\n\n\n@router.get(\"/tools\")\nasync def get_user_tools() -> ToolsResponse:\n    tools = get_external_tools()\n    formatted_tools = [\n        ToolModel(\n            name=get_tool_name(tool),\n            description=tool.public_description,\n            color=\"TODO: Change to image of tool\",\n            image_url=tool.image_url,\n        )\n        for tool in tools\n        if tool.available()\n    ]\n\n    return ToolsResponse(tools=formatted_tools)\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/auth/__init__.py",
    "content": "from .views import router\n\n__all__ = [\"router\"]\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/auth/views.py",
    "content": "from typing import Any, Dict, Optional\n\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom fastapi.responses import RedirectResponse\n\nfrom reworkd_platform.db.crud.oauth import OAuthCrud\nfrom reworkd_platform.db.crud.organization import OrganizationCrud, OrganizationUsers\nfrom reworkd_platform.schemas import UserBase\nfrom reworkd_platform.services.oauth_installers import OAuthInstaller, installer_factory\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.dependencies import get_current_user\n\nrouter = APIRouter()\n\n\n@router.get(\"/organization/{name}\")\nasync def organizations(\n    name: str, crud: OrganizationCrud = Depends(OrganizationCrud.inject)\n) -> OrganizationUsers:\n    if org := await crud.get_by_name(name):\n        return org\n    raise HTTPException(status_code=404)\n\n\n@router.get(\"/{provider}\")\nasync def oauth_install(\n    redirect: str = settings.frontend_url,\n    user: UserBase = Depends(get_current_user),\n    installer: OAuthInstaller = Depends(installer_factory),\n) -> str:\n    \"\"\"Install an OAuth App\"\"\"\n    return await installer.install(user, redirect)\n\n\n@router.get(\"/{provider}/uninstall\")\nasync def oauth_uninstall(\n    user: UserBase = Depends(get_current_user),\n    installer: OAuthInstaller = Depends(installer_factory),\n) -> Dict[str, Any]:\n    res = await installer.uninstall(user)\n    return {\n        \"success\": res,\n    }\n\n\n@router.get(\"/{provider}/callback\")\nasync def oauth_callback(\n    code: Optional[str] = None,\n    state: Optional[str] = None,\n    installer: OAuthInstaller = Depends(installer_factory),\n) -> RedirectResponse:\n    \"\"\"Callback for OAuth App\"\"\"\n\n    # if code or state are missing (user cancelled), redirect to frontend\n    if not code or not state:\n        return RedirectResponse(url=settings.frontend_url)\n\n    creds = await installer.install_callback(code, state)\n    return RedirectResponse(url=creds.redirect_uri)\n\n\n@router.get(\"/sid/info\")\nasync def sid_info(\n    user: UserBase = Depends(get_current_user),\n    crud: OAuthCrud = Depends(OAuthCrud.inject),\n) -> Dict[str, Any]:\n    creds = await crud.get_installation_by_user_id(user.id, \"sid\")\n    return {\n        \"connected\": bool(creds and creds.access_token_enc),\n    }\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/dependencies.py",
    "content": "from datetime import datetime\nfrom typing import Annotated\n\nfrom fastapi import Depends, Header\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPBearer\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom sqlalchemy.orm.exc import NoResultFound\n\nfrom reworkd_platform.db.crud.user import UserCrud\nfrom reworkd_platform.db.dependencies import get_db_session\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.web.api.http_responses import forbidden\n\n\ndef user_crud(\n    session: AsyncSession = Depends(get_db_session),\n) -> UserCrud:\n    return UserCrud(session)\n\n\nasync def get_current_user(\n    x_organization_id: Annotated[str | None, Header()] = None,\n    bearer: HTTPAuthorizationCredentials = Depends(HTTPBearer()),\n    crud: UserCrud = Depends(user_crud),\n) -> UserBase:\n    session_token = bearer.credentials\n\n    try:\n        session = await crud.get_user_session(session_token)\n    except NoResultFound:\n        raise forbidden(\"Invalid session token\")\n\n    if session.expires <= datetime.utcnow():\n        raise forbidden(\"Session token expired\")\n\n    return UserBase(\n        id=session.user.id,\n        name=session.user.name,\n        email=session.user.email,\n        image=session.user.image,\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/error_handling.py",
    "content": "from fastapi import Request\nfrom fastapi.responses import JSONResponse\nfrom loguru import logger\n\nfrom reworkd_platform.web.api.errors import PlatformaticError\n\n\nasync def platformatic_exception_handler(\n    _: Request,\n    platform_exception: PlatformaticError,\n) -> JSONResponse:\n    if platform_exception.should_log:\n        logger.exception(platform_exception)\n\n    return JSONResponse(\n        status_code=409,\n        content={\n            \"error\": platform_exception.__class__.__name__,\n            \"detail\": platform_exception.detail,\n            \"code\": platform_exception.code,\n        },\n    )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/errors.py",
    "content": "class PlatformaticError(Exception):\n    \"\"\"\n    Parent exception class for all expected backend exceptions\n    Will be caught and handled by the platform_exception_handler\n    Shoutout to https://platformatic.dev/\n    \"\"\"\n\n    detail: str\n    code: int\n    should_log: bool = True\n\n    def __init__(\n        self,\n        base_exception: Exception,\n        detail: str = \"\",\n        code: int = 409,\n        should_log: bool = True,\n    ):\n        super().__init__(base_exception)\n        self.detail = detail\n        self.code = code\n        self.should_log = should_log\n\n\nclass OpenAIError(PlatformaticError):\n    pass\n\n\nclass ReplicateError(PlatformaticError):\n    pass\n\n\nclass MaxLoopsError(PlatformaticError):\n    pass\n\n\nclass MultipleSummaryError(PlatformaticError):\n    pass\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/http_responses.py",
    "content": "from fastapi import HTTPException, status\n\n\ndef forbidden(detail: str = \"Forbidden\") -> HTTPException:\n    return HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=detail)\n\n\ndef not_found(detail: str = \"Not Found\") -> HTTPException:\n    return HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=detail)\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/memory/__init__.py",
    "content": "\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/memory/memory.py",
    "content": "from abc import ABC, abstractmethod\nfrom typing import Any, List, Tuple\n\nSimilarTasks = List[Tuple[str, float]]\n\n\nclass AgentMemory(ABC):\n    \"\"\"\n    Base class for AgentMemory\n    Expose __enter__ and __exit__ to ensure connections get closed within requests\n    \"\"\"\n\n    @abstractmethod\n    def __enter__(self) -> \"AgentMemory\":\n        raise NotImplementedError()\n\n    @abstractmethod\n    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:\n        raise NotImplementedError()\n\n    @abstractmethod\n    def add_tasks(self, tasks: List[str]) -> List[str]:\n        raise NotImplementedError()\n\n    @abstractmethod\n    def get_similar_tasks(self, query: str, score_threshold: float = 0.95) -> List[str]:\n        raise NotImplementedError()\n\n    @abstractmethod\n    def reset_class(self) -> None:\n        raise NotImplementedError()\n\n    @staticmethod\n    def should_use() -> bool:\n        return True\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/memory/memory_with_fallback.py",
    "content": "from __future__ import annotations\n\nfrom typing import Any, List\n\nfrom loguru import logger\n\nfrom reworkd_platform.web.api.memory.memory import AgentMemory\n\n\nclass MemoryWithFallback(AgentMemory):\n    \"\"\"\n    Wrap a primary AgentMemory provider and use a fallback in the case that it fails\n    We do this because we've had issues with Weaviate crashing and causing memory to randomly fail\n    \"\"\"\n\n    def __init__(self, primary: AgentMemory, secondary: AgentMemory):\n        self.primary = primary\n        self.secondary = secondary\n\n    def __enter__(self) -> AgentMemory:\n        try:\n            return self.primary.__enter__()\n        except Exception as e:\n            logger.exception(e)\n            return self.secondary.__enter__()\n\n    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:\n        try:\n            self.primary.__exit__(exc_type, exc_value, traceback)\n        except Exception as e:\n            logger.exception(e)\n            self.secondary.__exit__(exc_type, exc_value, traceback)\n\n    def add_tasks(self, tasks: List[str]) -> List[str]:\n        try:\n            return self.primary.add_tasks(tasks)\n        except Exception as e:\n            logger.exception(e)\n            return self.secondary.add_tasks(tasks)\n\n    def get_similar_tasks(self, query: str, score_threshold: float = 0) -> List[str]:\n        try:\n            return self.primary.get_similar_tasks(query)\n        except Exception as e:\n            logger.exception(e)\n            return self.secondary.get_similar_tasks(query)\n\n    def reset_class(self) -> None:\n        try:\n            self.primary.reset_class()\n        except Exception as e:\n            logger.exception(e)\n            self.secondary.reset_class()\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/memory/null.py",
    "content": "from typing import Any, List\n\nfrom reworkd_platform.web.api.memory.memory import AgentMemory\n\n\nclass NullAgentMemory(AgentMemory):\n    \"\"\"\n    NullObjectPattern for AgentMemory\n    Used when database connections cannot be established\n    \"\"\"\n\n    def __enter__(self) -> AgentMemory:\n        return self\n\n    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:\n        pass\n\n    def add_tasks(self, tasks: List[str]) -> List[str]:\n        return []\n\n    def get_similar_tasks(self, query: str, score_threshold: float = 0) -> List[str]:\n        return []\n\n    def reset_class(self) -> None:\n        pass\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/metadata.py",
    "content": "from typing import Optional\nfrom urllib.parse import urljoin, urlparse\n\nfrom bs4 import BeautifulSoup\nfrom fastapi import APIRouter\nfrom httpx import AsyncClient, HTTPStatusError, RequestError\nfrom pydantic import BaseModel, Field\n\nfrom reworkd_platform.web.api.errors import PlatformaticError\n\nrouter = APIRouter()\n\n\nclass Metadata(BaseModel):\n    title: Optional[str] = Field(default=None, description=\"Title of the page\")\n    hostname: Optional[str] = Field(default=None, description=\"Hostname of the page\")\n    favicon: Optional[str] = Field(default=None, description=\"Favicon of the page\")\n\n\n@router.get(\n    \"\",\n)\nasync def extract_metadata(url: str) -> Metadata:\n    try:\n        headers = {\n            \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36\"\n        }\n\n        async with AsyncClient() as client:\n            res = await client.get(url, headers=headers)\n\n        res.raise_for_status()\n\n        soup = BeautifulSoup(res.text, \"html.parser\")\n        parsed_url = urlparse(url)\n\n        metadata = Metadata(\n            hostname=parsed_url.hostname,\n            title=soup.title.string.strip() if soup.title else None,\n        )\n\n        favicon = None\n        for link in soup.find_all(\"link\", rel=lambda x: x in [\"icon\", \"shortcut icon\"]):\n            favicon = link.get(\"href\")\n            if not favicon.startswith(\"http\"):\n                favicon = urljoin(url, favicon)\n            break\n\n        metadata.favicon = (\n            favicon\n            if favicon\n            else f\"{parsed_url.scheme}://{parsed_url.hostname}/favicon.ico\"\n        )\n\n        return metadata\n\n    except (RequestError, HTTPStatusError):\n        parsed_url = urlparse(url)\n        return Metadata(\n            hostname=parsed_url.hostname,\n            favicon=f\"{parsed_url.scheme}://{parsed_url.hostname}/favicon.ico\",\n        )\n    except Exception as e:\n        raise PlatformaticError(\n            base_exception=e,\n            detail=f\"Could not extract metadata from {url}\",\n            should_log=False,\n        )\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/models/__init__.py",
    "content": "\"\"\"API for llm models\"\"\"\nfrom reworkd_platform.web.api.models.views import router\n\n__all__ = [\"router\"]\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/models/views.py",
    "content": "from typing import List\n\nfrom fastapi import APIRouter, Depends\nfrom pydantic import BaseModel, Field\n\nfrom reworkd_platform.schemas.agent import LLM_MODEL_MAX_TOKENS\nfrom reworkd_platform.schemas.user import UserBase\nfrom reworkd_platform.web.api.dependencies import get_current_user\n\nrouter = APIRouter()\n\n\nclass ModelWithAccess(BaseModel):\n    name: str\n    max_tokens: int\n    has_access: bool = Field(\n        default=False, description=\"Whether the user has access to this model\"\n    )\n\n    @staticmethod\n    def from_model(name: str, max_tokens: int, user: UserBase) -> \"ModelWithAccess\":\n        has_access = user is not None\n        return ModelWithAccess(name=name, max_tokens=max_tokens, has_access=has_access)\n\n\n@router.get(\"\")\nasync def get_models(\n    user: UserBase = Depends(get_current_user),\n) -> List[ModelWithAccess]:\n    return [\n        ModelWithAccess.from_model(name=model, max_tokens=tokens, user=user)\n        for model, tokens in LLM_MODEL_MAX_TOKENS.items()\n    ]\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/monitoring/__init__.py",
    "content": "\"\"\"API for checking project status.\"\"\"\nfrom reworkd_platform.web.api.monitoring.views import router\n\n__all__ = [\"router\"]\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/monitoring/views.py",
    "content": "from fastapi import APIRouter\n\nrouter = APIRouter()\n\n\n@router.get(\"/health\")\ndef health_check() -> None:\n    \"\"\"\n    Checks the health of a project.\n\n    It returns 200 if the project is healthy.\n    \"\"\"\n\n\n@router.get(\"/error\")\ndef error_check() -> None:\n    \"\"\"\n    Checks that errors are being correctly logged.\n    \"\"\"\n    raise Exception(\"This is an expected error from the error check endpoint!\")\n"
  },
  {
    "path": "platform/reworkd_platform/web/api/router.py",
    "content": "from fastapi.routing import APIRouter\n\nfrom reworkd_platform.web.api import agent, auth, metadata, models, monitoring\n\napi_router = APIRouter()\napi_router.include_router(monitoring.router, prefix=\"/monitoring\", tags=[\"monitoring\"])\napi_router.include_router(agent.router, prefix=\"/agent\", tags=[\"agent\"])\napi_router.include_router(models.router, prefix=\"/models\", tags=[\"models\"])\napi_router.include_router(auth.router, prefix=\"/auth\", tags=[\"auth\"])\napi_router.include_router(metadata.router, prefix=\"/metadata\", tags=[\"metadata\"])\n"
  },
  {
    "path": "platform/reworkd_platform/web/application.py",
    "content": "from importlib import metadata\n\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.responses import UJSONResponse\n\nfrom reworkd_platform.logging import configure_logging\nfrom reworkd_platform.settings import settings\nfrom reworkd_platform.web.api.error_handling import platformatic_exception_handler\nfrom reworkd_platform.web.api.errors import PlatformaticError\nfrom reworkd_platform.web.api.router import api_router\nfrom reworkd_platform.web.lifetime import (\n    register_shutdown_event,\n    register_startup_event,\n)\n\n\ndef get_app() -> FastAPI:\n    \"\"\"\n    Get FastAPI application.\n\n    This is the main constructor of an application.\n\n    :return: application.\n    \"\"\"\n    configure_logging()\n\n    app = FastAPI(\n        title=\"Reworkd Platform API\",\n        version=metadata.version(\"reworkd_platform\"),\n        docs_url=\"/api/docs\",\n        redoc_url=\"/api/redoc\",\n        openapi_url=\"/api/openapi.json\",\n        default_response_class=UJSONResponse,\n    )\n\n    app.add_middleware(\n        CORSMiddleware,\n        allow_origins=[settings.frontend_url],\n        allow_origin_regex=settings.allowed_origins_regex,\n        allow_credentials=True,\n        allow_methods=[\"*\"],\n        allow_headers=[\"*\"],\n    )\n\n    # Adds startup and shutdown events.\n    register_startup_event(app)\n    register_shutdown_event(app)\n\n    # Main router for the API.\n    app.include_router(router=api_router, prefix=\"/api\")\n\n    app.exception_handler(PlatformaticError)(platformatic_exception_handler)\n\n    return app\n"
  },
  {
    "path": "platform/reworkd_platform/web/lifetime.py",
    "content": "from typing import Awaitable, Callable\n\nfrom fastapi import FastAPI\nfrom sqlalchemy.ext.asyncio import async_sessionmaker\n\nfrom reworkd_platform.db.meta import meta\nfrom reworkd_platform.db.models import load_all_models\nfrom reworkd_platform.db.utils import create_engine\nfrom reworkd_platform.services.tokenizer.lifetime import init_tokenizer\n\n\ndef _setup_db(app: FastAPI) -> None:  # pragma: no cover\n    \"\"\"\n    Creates connection to the database.\n\n    This function creates SQLAlchemy engine instance,\n    session_factory for creating sessions\n    and stores them in the application's state property.\n\n    :param app: fastAPI application.\n    \"\"\"\n    engine = create_engine()\n    session_factory = async_sessionmaker(\n        engine,\n        expire_on_commit=False,\n    )\n    app.state.db_engine = engine\n    app.state.db_session_factory = session_factory\n\n\nasync def _create_tables() -> None:  # pragma: no cover\n    \"\"\"Populates tables in the database.\"\"\"\n    load_all_models()\n\n    engine = create_engine()\n    async with engine.begin() as connection:\n        await connection.run_sync(meta.create_all)\n    await engine.dispose()\n\n\ndef register_startup_event(\n    app: FastAPI,\n) -> Callable[[], Awaitable[None]]:  # pragma: no cover\n    \"\"\"\n    Actions to run on application startup.\n\n    This function uses fastAPI app to store data\n    in the state, such as db_engine.\n\n    :param app: the fastAPI application.\n    :return: function that actually performs actions.\n    \"\"\"\n\n    @app.on_event(\"startup\")\n    async def _startup() -> None:  # noqa: WPS430\n        _setup_db(app)\n        init_tokenizer(app)\n        # await _create_tables()\n\n    return _startup\n\n\ndef register_shutdown_event(\n    app: FastAPI,\n) -> Callable[[], Awaitable[None]]:  # pragma: no cover\n    \"\"\"\n    Actions to run on application's shutdown.\n\n    :param app: fastAPI application.\n    :return: function that actually performs actions.\n    \"\"\"\n\n    @app.on_event(\"shutdown\")\n    async def _shutdown() -> None:  # noqa: WPS430\n        await app.state.db_engine.dispose()\n\n    return _shutdown\n"
  },
  {
    "path": "scripts/post-sync.sh",
    "content": "cd \"$(dirname \"$0\")\" || exit 1\ncd .. || exit 1\ncd platform || exit 1\n\nrm poetry.lock\npoetry install\npoetry lock\n"
  },
  {
    "path": "scripts/prepare-sync.sh",
    "content": "cd \"$(dirname \"$0\")\" || exit 1\ngit reset --hard\n\ngit fetch origin\n\ngit checkout main\ngit pull\n\ngit branch -d actions/sync --force\ngit checkout -b actions/sync origin/actions/sync\n"
  },
  {
    "path": "setup.bat",
    "content": "@echo off\nsetlocal\n\nrem  The CLI will take care of setting up the ENV variables\ncd cli || exit /b 1\ncall npm install\nnpm run start\n"
  },
  {
    "path": "setup.sh",
    "content": "#!/usr/bin/env bash\n\ncd \"$(dirname \"$0\")\" || exit 1\n\n# The CLI will take care of setting up the ENV variables\ncd ./cli || exit 1\nnpm install\nnpm run start\n"
  }
]