{"id":26055513,"url":"https://github.com/bniladridas/friday_gemini_ai","last_synced_at":"2026-03-11T11:39:35.701Z","repository":{"id":343398703,"uuid":"940787284","full_name":"bniladridas/friday_gemini_ai","owner":"bniladridas","description":"ruby gem for gemini ai.","archived":false,"fork":false,"pushed_at":"2026-03-10T07:57:13.000Z","size":740,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-10T14:20:52.357Z","etag":null,"topics":["gemini","library","ruby"],"latest_commit_sha":null,"homepage":"https://bniladridas.github.io/friday_gemini_ai/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bniladridas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"docs/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2025-02-28T19:43:43.000Z","updated_at":"2026-03-10T07:57:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bniladridas/friday_gemini_ai","commit_stats":null,"previous_names":["bniladridas/friday_gemini_ai"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/bniladridas/friday_gemini_ai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bniladridas%2Ffriday_gemini_ai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bniladridas%2Ffriday_gemini_ai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bniladridas%2Ffriday_gemini_ai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bniladridas%2Ffriday_gemini_ai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bniladridas","download_url":"https://codeload.github.com/bniladridas/friday_gemini_ai/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bniladridas%2Ffriday_gemini_ai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30380098,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-11T06:09:32.197Z","status":"ssl_error","status_checked_at":"2026-03-11T06:09:17.086Z","response_time":84,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gemini","library","ruby"],"created_at":"2025-03-08T10:19:36.805Z","updated_at":"2026-03-11T11:39:35.696Z","avatar_url":"https://github.com/bniladridas.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Friday Gemini AI\n\n[![CI](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/ci.yml/badge.svg)](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/ci.yml)\n[![Security](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/security.yml/badge.svg)](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/security.yml)\n[![Dependencies](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/dependencies.yml/badge.svg)](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/dependencies.yml)\n[![HarperBot](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/harperbot.yml/badge.svg)](https://github.com/bniladridas/friday_gemini_ai/actions/workflows/harperbot.yml)\n\nRuby gem for integrating with Google's Gemini AI models.\n\nThe full API of this library can be found in [docs/reference/api.md](docs/reference/api.md).\n\n## Installation\n\n```bash\ngem install friday_gemini_ai\n```\n\nSet your API key in `.env`:\n\n```\nGEMINI_API_KEY=your_api_key\n```\n\n\u003e [!NOTE]\n\u003e Ensure your API key is kept secure and not committed to version control.\n\n## HarperBot Integration\n\nHarperBot provides automated PR code reviews using Google's Gemini AI. It supports two deployment modes:\n\n### Webhook Mode (Recommended)\n- **Self-hosted on Vercel** for centralized, scalable analysis\n- Install the [HarperBot GitHub App](https://github.com/apps/harperbot) once for all repositories\n- No per-repository setup required\n- **Note:** For self-hosting outside Vercel, use a production WSGI server like Gunicorn instead of Flask's development server for security and performance.\n\n### Workflow Mode (Legacy)\n- Repository-specific GitHub Actions workflow\n- Requires secrets setup per repository\n- Automated setup: `curl -fsSL https://raw.githubusercontent.com/bniladridas/friday_gemini_ai/main/bin/setup-harperbot | bash` (use `--update` to update, `--dry-run` to preview)\n- **Note:** This is legacy mode for existing users. New installations should use Webhook Mode for better scalability and centralized management\n\nFor detailed setup instructions, see [harperbot/HarperBot.md](harperbot/HarperBot.md).\n\n## Usage\n\nThe full API of this library can be found in [docs/reference/api.md](docs/reference/api.md).\n\n### Basic Setup\n\n**Security Note for Automated Setup:** The recommended `curl | bash` method downloads and executes code from the internet. For security, review the script at https://github.com/bniladridas/friday_gemini_ai/blob/main/bin/setup-harperbot before running. Alternatively, download first: `curl -O https://raw.githubusercontent.com/bniladridas/friday_gemini_ai/main/bin/setup-harperbot`, inspect, then `bash setup-harperbot`.\n\n```ruby\nrequire 'friday_gemini_ai'\nGeminiAI.load_env\n\nclient = GeminiAI::Client.new               # Default: gemini-2.5-pro\nfast_client = GeminiAI::Client.new(model: :flash)\n```\n\n### Model Reference\n\n| Key           | ID                      | Use case                        |\n| ------------- | ----------------------- | ------------------------------- |\n| `:pro`        | `gemini-2.5-pro`        | Most capable, complex reasoning |\n| `:flash`      | `gemini-2.5-flash`      | Fast, general-purpose           |\n| `:flash_2_0`  | `gemini-2.0-flash`      | Legacy support                  |\n| `:flash_lite` | `gemini-2.0-flash-lite` | Lightweight legacy              |\n\n## Capabilities\n\n* **Text:** content generation, summaries, documentation\n* **Chat:** multi-turn Q\u0026A and assistants\n* **Image:** image-to-text analysis\n* **CLI:** for quick prototyping and automation\n\n## Features\n\n* **Multiple Model Support:** Gemini 2.5 + 2.0 families with automatic fallback\n* **Text Generation:** configurable parameters, safety settings\n* **Image Analysis:** base64 image input, detailed descriptions\n* **Chat:** context retention, system instructions\n* **Security:** API key masking, retries, and rate limits (1s default, 3s CI)\n\n## Handling errors\n\nWhen the library is unable to connect to the API,\nor if the API returns a non-success status code (i.e., 4xx or 5xx response),\na subclass of `GeminiAI::APIError` will be thrown:\n\n```ruby\nresponse = client.generate_text('Hello').catch do |err|\n  if err.is_a?(GeminiAI::APIError)\n    puts err.status  # 400\n    puts err.name    # BadRequestError\n    puts err.headers # {server: 'nginx', ...}\n  else\n    raise err\n  end\nend\n```\n\nError codes are as follows:\n\n| Status Code | Error Type                 |\n| ----------- | -------------------------- |\n| 400         | `BadRequestError`          |\n| 401         | `AuthenticationError`     |\n| 403         | `PermissionDeniedError`   |\n| 404         | `NotFoundError`           |\n| 422         | `UnprocessableEntityError` |\n| 429         | `RateLimitError`          |\n| \u003e=500       | `InternalServerError`     |\n| N/A         | `APIConnectionError`      |\n\n### Retries\n\nCertain errors will be automatically retried 2 times by default, with a short exponential backoff.\nConnection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,\n429 Rate Limit, and \u003e=500 Internal errors will all be retried by default.\n\nYou can use the `max_retries` option to configure or disable this:\n\n```ruby\n# Configure the default for all requests:\nclient = GeminiAI::Client.new(max_retries: 0)  # default is 2\n\n# Or, configure per-request:\nclient.generate_text('Hello', max_retries: 5)\n```\n\n### Timeouts\n\nRequests time out after 60 seconds by default. You can configure this with a `timeout` option:\n\n```ruby\n# Configure the default for all requests:\nclient = GeminiAI::Client.new(timeout: 20)  # 20 seconds (default is 60)\n\n# Override per-request:\nclient.generate_text('Hello', timeout: 5)\n```\n\nOn timeout, an `APIConnectionTimeoutError` is thrown.\n\nNote that requests which time out will be [retried twice by default](#retries).\n\n## Advanced Usage\n\n### Logging\n\n\u003e [!IMPORTANT]\n\u003e All log messages are intended for debugging only. The format and content of log messages\n\u003e may change between releases.\n\n#### Log levels\n\nThe log level can be configured via the `GEMINI_LOG_LEVEL` environment variable or client option.\n\nAvailable log levels, from most to least verbose:\n\n- `'debug'` - Show debug messages, info, warnings, and errors\n- `'info'` - Show info messages, warnings, and errors\n- `'warn'` - Show warnings and errors (default)\n- `'error'` - Show only errors\n- `'off'` - Disable all logging\n\n```ruby\nrequire 'friday_gemini_ai'\n\nclient = GeminiAI::Client.new(log_level: 'debug')  # Show all log messages\n```\n\n## Frequently Asked Questions\n\n## Semantic versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes that only affect static types, without breaking runtime behavior.\n2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n3. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://github.com/bniladridas/friday_gemini_ai/issues) with questions, bugs, or suggestions.\n\n## Requirements\n\nRuby 3.0 or later is supported.\n\nThe following runtimes are supported:\n\n- Ruby 3.0+\n- JRuby (compatible versions)\n- TruffleRuby (compatible versions)\n\nNote that Windows support is limited; Linux and macOS are recommended.\n\n## Migration Guide\n\nGemini 1.5 models have been deprecated.\nUse:\n\n* `:pro` → `gemini-2.5-pro`\n* `:flash` → `gemini-2.5-flash`\n\nLegacy options (`:flash_2_0`, `:flash_lite`) remain supported for backward compatibility.\n\n## Environment Variables\n\n```bash\n# Required\nGEMINI_API_KEY=your_api_key_here\n\n# Optional\nGEMINI_LOG_LEVEL=debug  # debug | info | warn | error\n```\n\n### CLI Shortcuts\n\n```bash\n./bin/gemini test\n./bin/gemini generate \"Your prompt\"\n./bin/gemini chat\n```\n\n## GitHub Actions Integration\n\nFriday Gemini AI includes a built-in GitHub Actions workflow for automated PR reviews via **HarperBot**, powered by Gemini AI.\n\n💡 **Install the [HarperBot GitHub App](https://github.com/apps/harperbot)** for automated PR reviews across repositories.\n\n### HarperBot – Automated PR Analysis\n\nHarperBot provides AI-driven code review and analysis directly in pull requests.\n\n**Key Capabilities:**\n\n* Configurable focus: `all`, `security`, `performance`, `quality`\n* Code quality, documentation, and test coverage analysis\n* Security \u0026 performance issue detection\n* Inline review comments with actionable suggestions\n* Clean, minimal, and structured feedback output\n\n### Setup\n\n**Workflow Mode (default)**\n\n1. Add repository secrets:\n\n   * `GEMINI_API_KEY`\n   * `GITHUB_TOKEN` (auto-provided by GitHub)\n2. Configure `.github/workflows/harperbot.yml`\n3. Optional: tune behavior via `harperbot/config.yaml`\n\n**Webhook Mode (Recommended)**\n\n* Deploy `webhook-vercel` branch to Vercel\n* Create a GitHub App and set environment variables:\n  - `GEMINI_API_KEY`: Your Google Gemini API key\n  - `HARPER_BOT_APP_ID`: App ID from your GitHub App settings (found under \"About\" section)\n  - `HARPER_BOT_PRIVATE_KEY`: Private key content (paste the entire .pem file)\n  - `WEBHOOK_SECRET`: Random secret string for webhook verification\n* Install the GitHub App on your repositories\n* Webhooks will handle PR events automatically\n* Preferred for scalability and centralized management\n\n### Workflow Highlights\n\n* **Pull Requests:** triggered on open, update, or reopen\n* **Push to main:** runs Gemini CLI verification\n* **Concurrency control:** cancels redundant runs for efficiency\n\nRequired permissions:\n\n```yaml\npermissions:\n  contents: read\n  pull-requests: write\n  issues: write\n  statuses: write\n```\n\n## Local Development \u0026 Testing\n\n```bash\nbundle exec rake test          # Run tests\nbundle exec rake rubocop       # Optional lint check\ngem build *.gemspec            # Verify build\n```\n\n### Test Workflows Locally\n\nUsing [act](https://github.com/nektos/act):\n\n```bash\nbrew install act\nact -j test --container-architecture linux/amd64\n```\n\n## Examples\n\n### Text Generation\n\n```ruby\nclient = GeminiAI::Client.new\nputs client.generate_text('Write a haiku about Ruby')\n```\n\n### Image Analysis\n\n```ruby\nimage_data = Base64.strict_encode64(File.binread('path/to/image.jpg'))\nputs client.generate_image_text(image_data, 'Describe this image')\n```\n\n### Chat\n\n```ruby\nmessages = [\n  { role: 'user', content: 'Hello!' },\n  { role: 'model', content: 'Hi there!' },\n  { role: 'user', content: 'Tell me about Ruby.' }\n]\nputs client.chat(messages, system_instruction: 'Be helpful and concise.')\n```\n\n## Conventional Commits\n\nConsistent commit messages are enforced via a local Git hook.\n\n```bash\ncp scripts/commit-msg .git/hooks/\nchmod +x .git/hooks/commit-msg\n```\n\n**Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`\nExample:\n\n```bash\ngit commit -m \"feat: add user authentication\"\n```\n\n## Documentation\n\n* [Documentation](docs/index.md)\n* [Quickstart](docs/start/quickstart.md)\n* [API Reference](docs/reference/api.md)\n* [Cookbook](docs/reference/cookbook.md)\n* [Best Practices](docs/guides/practices.md)\n* [CI/CD Workflows](docs/guides/workflows.md)\n* [Changelog](docs/CHANGELOG.md)\n* [Contributing](docs/CONTRIBUTING.md)\n* [Resources](docs/guides/resources.md)\n\n## Contributing\n\nFork → Branch → Commit → Pull Request.\n\n## License\n\nMIT – see [LICENSE](LICENSE).\n\n\u003cdiv align=\"center\"\u003e\n\n[\u003csup\u003e© 2026 Friday Gemini AI • Hand-crafted for Rubyists\u003c/sup\u003e](https://bniladridas.github.io/friday_gemini_ai/)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbniladridas%2Ffriday_gemini_ai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbniladridas%2Ffriday_gemini_ai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbniladridas%2Ffriday_gemini_ai/lists"}