{"id":50663954,"url":"https://github.com/palmshed/vesper","last_synced_at":"2026-06-08T04:33:42.436Z","repository":{"id":343398703,"uuid":"940787284","full_name":"palmshed/vesper","owner":"palmshed","description":"gemini client.","archived":false,"fork":false,"pushed_at":"2026-06-06T08:48:41.000Z","size":1798,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-06T10:20:01.970Z","etag":null,"topics":["gemini","ruby"],"latest_commit_sha":null,"homepage":"https://palmshed.github.io/vesper/","language":"Python","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/palmshed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"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-06-06T08:48:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/palmshed/vesper","commit_stats":null,"previous_names":["bniladridas/friday_gemini_ai","bniladridas/vesper","palmshed/vesper"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/palmshed/vesper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmshed%2Fvesper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmshed%2Fvesper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmshed%2Fvesper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmshed%2Fvesper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/palmshed","download_url":"https://codeload.github.com/palmshed/vesper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmshed%2Fvesper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34048681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","ruby"],"created_at":"2026-06-08T04:33:42.286Z","updated_at":"2026-06-08T04:33:42.423Z","avatar_url":"https://github.com/palmshed.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vesper\n\u003cimg src=\"website/assets/readme-header.png\" alt=\"Vesper\" width=\"100%\"\u003e\n\n\u003cbr\u003e\n\n[![Gem](https://img.shields.io/gem/v/friday_gemini_ai?style=flat-square\u0026label=gem)](https://rubygems.org/gems/friday_gemini_ai)\n![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.3-cc342d?style=flat-square)\n[![License](https://img.shields.io/badge/license-MIT-2f4858?style=flat-square)](LICENSE)\n![Tests](https://img.shields.io/badge/tests-passing-2e7d32?style=flat-square)\n\n\u003cbr\u003e\n\nRuby client for Gemini `generateContent`. Includes a CLI and a PR review app.\n\n\u003cbr\u003e\n\n# Installation\n\n\u003cbr\u003e\n\n```bash\ngem install friday_gemini_ai\n```\n\n\u003cbr\u003e\n\nWith Bundler:\n\n\u003cbr\u003e\n\n```ruby\ngem 'friday_gemini_ai', require: 'vesper'\n```\n\n\u003cbr\u003e\n\nThe package is published as `friday_gemini_ai`. The runtime entrypoint is `vesper`.\n\n\u003cbr\u003e\n\nSet your API key in `.env`:\n\n\u003cbr\u003e\n\n```\nGEMINI_API_KEY=your_api_key\n```\n\n\u003cbr\u003e\n\n\u003e [!NOTE]\n\u003e Ensure your API key is kept secure and not committed to version control.\n\n\u003cbr\u003e\n\n# Usage\n\n\u003cbr\u003e\n\n# Basic Setup\n\n\u003cbr\u003e\n\n```ruby\nrequire 'vesper'\nGeminiAI.load_env\n\nclient = GeminiAI::Client.new\nputs client.generate_text('Write a haiku about Ruby')\n```\n\n\u003cbr\u003e\n\nUse a different model when needed:\n\n\u003cbr\u003e\n\n```ruby\nfast_client = GeminiAI::Client.new(model: :flash)\nputs fast_client.generate_text('Explain Ruby in one sentence')\n```\n\n\u003cbr\u003e\n\n# generateContent Text Models\n\n\u003cbr\u003e\n\n| Key | ID |\n| --- | --- |\n| `:flash_latest` | `gemini-flash-latest` |\n| `:pro_latest` | `gemini-pro-latest` |\n| `:flash_3_5` | `gemini-3.5-flash` |\n| `:pro_3_preview` | `gemini-3-pro-preview` |\n| `:flash_3_preview` | `gemini-3-flash-preview` |\n| `:pro_3_1_preview` | `gemini-3.1-pro-preview` |\n| `:flash_3_1_lite` | `gemini-3.1-flash-lite` |\n| `:pro_2_5` | `gemini-2.5-pro` |\n| `:flash_2_5` | `gemini-2.5-flash` |\n| `:flash_2_0` | `gemini-2.0-flash` |\n\n\u003cbr\u003e\n\nShort aliases: `:pro` uses `gemini-pro-latest`, `:flash` uses `gemini-3.5-flash`, and `:flash_lite` uses `gemini-3.1-flash-lite`. Legacy `:pro_2_0` maps to `gemini-2.0-flash`.\n\n\u003cbr\u003e\n\nThe gem does not wrap embeddings, Imagen, or Veo APIs.\n\n\u003cbr\u003e\n\n# Capabilities\n\n\u003cbr\u003e\n\nVesper supports text generation, chat, image input for `generateContent`, model aliases, safety settings, API key masking, retries, and a local CLI.\n\n\u003cbr\u003e\n\n# Handling Errors\n\n\u003cbr\u003e\n\nClient validation and API failures raise `GeminiAI::Error` with a readable message.\nHTTP 429 responses are retried automatically up to three times with exponential backoff.\n\n\u003cbr\u003e\n\n```ruby\nbegin\n  response = client.generate_text('Hello')\n  puts response\nrescue GeminiAI::Error =\u003e err\n  warn \"Generation failed: #{err.message}\"\nend\n```\n\n\u003cbr\u003e\n\nCommon failures include:\n\n\u003cbr\u003e\n\n- Missing or invalid `GEMINI_API_KEY`\n- Empty prompts\n- Prompts over the configured maximum length\n- Gemini API errors returned by the service\n- Network errors raised by HTTParty\n\n\u003cbr\u003e\n\n# Retries\n\n\u003cbr\u003e\n\nRate-limit responses (`429`) are retried up to three times with waits of 5, 10, and 20 seconds.\n\n\u003cbr\u003e\n\n# Timeouts\n\n\u003cbr\u003e\n\nRequests use a 30 second HTTParty timeout.\n\n\u003cbr\u003e\n\n# Logging\n\n\u003cbr\u003e\n\n```ruby\nrequire 'vesper'\n\nGeminiAI::Client.logger.level = Logger::INFO\nclient = GeminiAI::Client.new\n```\n\n\u003cbr\u003e\n\n# Requirements\n\n\u003cbr\u003e\n\nRuby 3.3 or later. Linux and macOS are tested.\n\n\u003cbr\u003e\n\n# Environment Variables\n\n\u003cbr\u003e\n\n```bash\nGEMINI_API_KEY=your_api_key_here\n```\n\n\u003cbr\u003e\n\n# Repo CLI\n\n\u003cbr\u003e\n\n```bash\n./bin/gemini test\n./bin/gemini generate \"Your prompt\"\n./bin/gemini chat\n```\n\n\u003cbr\u003e\n\n# Local Development \u0026 Testing\n\n\u003cbr\u003e\n\n```bash\nbundle exec rake test          # Run tests\nbundle exec rake docs          # Build API docs\ngem build friday_gemini_ai.gemspec\n```\n\n\u003cbr\u003e\n\n# Review App\n\n\u003cbr\u003e\n\nVesper Review is the PR review app in this repo. It defaults to `gemini-3.5-flash`; retrieval context is off unless enabled in `vesper/config.yaml`.\n\n\u003cbr\u003e\n\nFor setup details, see [`vesper/Vesper.md`](vesper/Vesper.md).\n\n\u003cbr\u003e\n\n# Examples\n\n\u003cbr\u003e\n\n# Text Generation\n\n\u003cbr\u003e\n\n```ruby\nclient = GeminiAI::Client.new\nputs client.generate_text('Write a haiku about Ruby')\n```\n\n\u003cbr\u003e\n\n# Image Analysis\n\n\u003cbr\u003e\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\u003cbr\u003e\n\n# Chat\n\n\u003cbr\u003e\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 concise.')\n```\n\n\u003cbr\u003e\n\n# Documentation\n\n\u003cbr\u003e\n\n| Need | Link |\n| --- | --- |\n| Start | [`Quickstart`](docs/start/quickstart.md) |\n| API | [`Reference`](docs/reference/api.md) |\n| Recipes | [`Cookbook`](docs/reference/cookbook.md) |\n| Practice | [`Best practices`](docs/guides/practices.md) |\n| Automation | [`Workflows`](docs/guides/workflows.md) |\n| Project | [`Contributing`](docs/CONTRIBUTING.md) |\n\n\u003cbr\u003e\n\n# Contributing\n\n\u003cbr\u003e\n\nFork the repo and open a pull request.\n\n\u003cbr\u003e\n\n# License\n\n\u003cbr\u003e\n\nMIT → see [`LICENSE`](LICENSE).\n\n\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/apps/vesper-review\"\u003e\n    \u003cimg src=\"website/favicon.svg\" alt=\"Vesper Review app\" width=\"96\"\u003e\n  \u003c/a\u003e\n\n\u003cbr\u003e\n\n  \u003ca href=\"https://github.com/apps/vesper-review\"\u003e\u003ccode\u003eVesper Review\u003c/code\u003e\u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpalmshed%2Fvesper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpalmshed%2Fvesper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpalmshed%2Fvesper/lists"}