[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M718S1MZ1K4ZNG8P02QMFSX7":3,"skill-same:01M718S1MZ1K4ZNG8P02QMFSX7":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":55,"commitSha":56,"skillDirectory":57,"forksCount":14,"repositoryHtmlUrl":58,"repositoryHomepageUrl":6,"ownerHtmlUrl":59,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":60,"install":61,"resources":74},"01M718S1MZ1K4ZNG8P02QMFSX7","gemini-api-integration",null,"Use when integrating Google Gemini API into projects. Covers model selection, multimodal inputs, streaming, function calling, and production best practices.","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fgemini-api-integration\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"gemini","gemini api","integration","api","gemini api integration","api integration","2026","safe","when","google gemini api","calling","selection","community","use","function calling","model","projects","streaming","best practices","model selection","2026-11-10 10:12:30",false,"---\nname: gemini-api-integration\ndescription: \"Use when integrating Google Gemini API into projects. Covers model selection, multimodal inputs, streaming, function calling, and production best practices.\"\nrisk: safe\nsource: community\ndate_added: \"2026-03-04\"\n---\n\n# Gemini API Integration\n\n## Overview\n\nThis skill guides AI agents through integrating Google Gemini API into applications — from basic text generation to advanced multimodal, function calling, and streaming use cases. It covers the full Gemini SDK lifecycle with production-grade patterns.\n\n## When to Use This Skill\n\n- Use when setting up Gemini API for the first time in a Node.js, Python, or browser project\n- Use when implementing multimodal inputs (text + image\u002Faudio\u002Fvideo)\n- Use when adding streaming responses to improve perceived latency\n- Use when implementing function calling \u002F tool use with Gemini\n- Use when optimizing model selection (Flash vs Pro vs Ultra) for cost and performance\n- Use when debugging Gemini API errors, rate limits, or quota issues\n\n## Step-by-Step Guide\n\n### 1. Installation & Setup\n\n**Node.js \u002F TypeScript:**\n```bash\nnpm install @google\u002Fgenerative-ai\n```\n\n**Python:**\n```bash\npip install google-generativeai\n```\n\nSet your API key securely:\n```bash\nexport GEMINI_API_KEY=\"your-api-key-here\"\n```\n\n### 2. Basic Text Generation\n\n**Node.js:**\n```javascript\nimport { GoogleGenerativeAI } from \"@google\u002Fgenerative-ai\";\n\nconst genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);\nconst model = genAI.getGenerativeModel({ model: \"gemini-1.5-flash\" });\n\nconst result = await model.generateContent(\"Explain async\u002Fawait in JavaScript\");\nconsole.log(result.response.text());\n```\n\n**Python:**\n```python\nimport google.generativeai as genai\nimport os\n\ngenai.configure(api_key=os.environ[\"GEMINI_API_KEY\"])\nmodel = genai.GenerativeModel(\"gemini-1.5-flash\")\n\nresponse = model.generate_content(\"Explain async\u002Fawait in JavaScript\")\nprint(response.text)\n```\n\n### 3. Streaming Responses\n\n```javascript\nconst result = await model.generateContentStream(\"Write a detailed blog post about AI\");\n\nfor await (const chunk of result.stream) {\n  process.stdout.write(chunk.text());\n}\n```\n\n### 4. Multimodal Input (Text + Image)\n\n```javascript\nimport fs from \"fs\";\n\nconst imageData = fs.readFileSync(\"screenshot.png\");\nconst imagePart = {\n  inlineData: {\n    data: imageData.toString(\"base64\"),\n    mimeType: \"image\u002Fpng\",\n  },\n};\n\nconst result = await model.generateContent([\"Describe this image:\", imagePart]);\nconsole.log(result.response.text());\n```\n\n### 5. Function Calling \u002F Tool Use\n\n```javascript\nconst tools = [{\n  functionDeclarations: [{\n    name: \"get_weather\",\n    description: \"Get current weather for a city\",\n    parameters: {\n      type: \"OBJECT\",\n      properties: {\n        city: { type: \"STRING\", description: \"City name\" },\n      },\n      required: [\"city\"],\n    },\n  }],\n}];\n\nconst model = genAI.getGenerativeModel({ model: \"gemini-1.5-pro\", tools });\nconst result = await model.generateContent(\"What's the weather in Mumbai?\");\n\nconst call = result.response.functionCalls()?.[0];\nif (call) {\n  \u002F\u002F Execute the actual function\n  const weatherData = await getWeather(call.args.city);\n  \u002F\u002F Send result back to model\n}\n```\n\n### 6. Multi-turn Chat\n\n```javascript\nconst chat = model.startChat({\n  history: [\n    { role: \"user\", parts: [{ text: \"You are a helpful coding assistant.\" }] },\n    { role: \"model\", parts: [{ text: \"Sure! I'm ready to help with code.\" }] },\n  ],\n});\n\nconst response = await chat.sendMessage(\"How do I reverse a string in Python?\");\nconsole.log(response.response.text());\n```\n\n### 7. Model Selection Guide\n\n| Model | Best For | Speed | Cost |\n|-------|----------|-------|------|\n| `gemini-1.5-flash` | High-throughput, cost-sensitive tasks | Fast | Low |\n| `gemini-1.5-pro` | Complex reasoning, long context | Medium | Medium |\n| `gemini-2.0-flash` | Latest fast model, multimodal | Very Fast | Low |\n| `gemini-2.0-pro` | Most capable, advanced tasks | Slow | High |\n\n## Best Practices\n\n- ✅ **Do:** Use `gemini-1.5-flash` for most tasks — it's fast and cost-effective\n- ✅ **Do:** Always stream responses for user-facing chat UIs to reduce perceived latency\n- ✅ **Do:** Store API keys in environment variables, never hard-code them\n- ✅ **Do:** Implement exponential backoff for rate limit (429) errors\n- ✅ **Do:** Use `systemInstruction` to set persistent model behavior\n- ❌ **Don't:** Use `gemini-pro` for simple tasks — Flash is cheaper and faster\n- ❌ **Don't:** Send large base64 images inline for files > 20MB — use File API instead\n- ❌ **Don't:** Ignore safety ratings in responses for production apps\n\n## Error Handling\n\n```javascript\ntry {\n  const result = await model.generateContent(prompt);\n  return result.response.text();\n} catch (error) {\n  if (error.status === 429) {\n    \u002F\u002F Rate limited — wait and retry with exponential backoff\n    await new Promise(r => setTimeout(r, 2 ** retryCount * 1000));\n  } else if (error.status === 400) {\n    \u002F\u002F Invalid request — check prompt or parameters\n    console.error(\"Invalid request:\", error.message);\n  } else {\n    throw error;\n  }\n}\n```\n\n## Troubleshooting\n\n**Problem:** `API_KEY_INVALID` error\n**Solution:** Ensure `GEMINI_API_KEY` environment variable is set and the key is active in Google AI Studio.\n\n**Problem:** Response blocked by safety filters\n**Solution:** Check `result.response.promptFeedback.blockReason` and adjust your prompt or safety settings.\n\n**Problem:** Slow response times\n**Solution:** Switch to `gemini-1.5-flash` and enable streaming. Consider caching repeated prompts.\n\n**Problem:** `RESOURCE_EXHAUSTED` (quota exceeded)\n**Solution:** Check your quota in Google Cloud Console. Implement request queuing and exponential backoff.\n","# Gemini API Integration\n\n## Overview\n\nThis skill guides AI agents through integrating Google Gemini API into applications — from basic text generation to advanced multimodal, function calling, and streaming use cases. It covers the full Gemini SDK lifecycle with production-grade patterns.\n\n## When to Use This Skill\n\n- Use when setting up Gemini API for the first time in a Node.js, Python, or browser project\n- Use when implementing multimodal inputs (text + image\u002Faudio\u002Fvideo)\n- Use when adding streaming responses to improve perceived latency\n- Use when implementing function calling \u002F tool use with Gemini\n- Use when optimizing model selection (Flash vs Pro vs Ultra) for cost and performance\n- Use when debugging Gemini API errors, rate limits, or quota issues\n\n## Step-by-Step Guide\n\n### 1. Installation & Setup\n\n**Node.js \u002F TypeScript:**\n```bash\nnpm install @google\u002Fgenerative-ai\n```\n\n**Python:**\n```bash\npip install google-generativeai\n```\n\nSet your API key securely:\n```bash\nexport GEMINI_API_KEY=\"your-api-key-here\"\n```\n\n### 2. Basic Text Generation\n\n**Node.js:**\n```javascript\nimport { GoogleGenerativeAI } from \"@google\u002Fgenerative-ai\";\n\nconst genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);\nconst model = genAI.getGenerativeModel({ model: \"gemini-1.5-flash\" });\n\nconst result = await model.generateContent(\"Explain async\u002Fawait in JavaScript\");\nconsole.log(result.response.text());\n```\n\n**Python:**\n```python\nimport google.generativeai as genai\nimport os\n\ngenai.configure(api_key=os.environ[\"GEMINI_API_KEY\"])\nmodel = genai.GenerativeModel(\"gemini-1.5-flash\")\n\nresponse = model.generate_content(\"Explain async\u002Fawait in JavaScript\")\nprint(response.text)\n```\n\n### 3. Streaming Responses\n\n```javascript\nconst result = await model.generateContentStream(\"Write a detailed blog post about AI\");\n\nfor await (const chunk of result.stream) {\n  process.stdout.write(chunk.text());\n}\n```\n\n### 4. Multimodal Input (Text + Image)\n\n```javascript\nimport fs from \"fs\";\n\nconst imageData = fs.readFileSync(\"screenshot.png\");\nconst imagePart = {\n  inlineData: {\n    data: imageData.toString(\"base64\"),\n    mimeType: \"image\u002Fpng\",\n  },\n};\n\nconst result = await model.generateContent([\"Describe this image:\", imagePart]);\nconsole.log(result.response.text());\n```\n\n### 5. Function Calling \u002F Tool Use\n\n```javascript\nconst tools = [{\n  functionDeclarations: [{\n    name: \"get_weather\",\n    description: \"Get current weather for a city\",\n    parameters: {\n      type: \"OBJECT\",\n      properties: {\n        city: { type: \"STRING\", description: \"City name\" },\n      },\n      required: [\"city\"],\n    },\n  }],\n}];\n\nconst model = genAI.getGenerativeModel({ model: \"gemini-1.5-pro\", tools });\nconst result = await model.generateContent(\"What's the weather in Mumbai?\");\n\nconst call = result.response.functionCalls()?.[0];\nif (call) {\n  \u002F\u002F Execute the actual function\n  const weatherData = await getWeather(call.args.city);\n  \u002F\u002F Send result back to model\n}\n```\n\n### 6. Multi-turn Chat\n\n```javascript\nconst chat = model.startChat({\n  history: [\n    { role: \"user\", parts: [{ text: \"You are a helpful coding assistant.\" }] },\n    { role: \"model\", parts: [{ text: \"Sure! I'm ready to help with code.\" }] },\n  ],\n});\n\nconst response = await chat.sendMessage(\"How do I reverse a string in Python?\");\nconsole.log(response.response.text());\n```\n\n### 7. Model Selection Guide\n\n| Model | Best For | Speed | Cost |\n|-------|----------|-------|------|\n| `gemini-1.5-flash` | High-throughput, cost-sensitive tasks | Fast | Low |\n| `gemini-1.5-pro` | Complex reasoning, long context | Medium | Medium |\n| `gemini-2.0-flash` | Latest fast model, multimodal | Very Fast | Low |\n| `gemini-2.0-pro` | Most capable, advanced tasks | Slow | High |\n\n## Best Practices\n\n- ✅ **Do:** Use `gemini-1.5-flash` for most tasks — it's fast and cost-effective\n- ✅ **Do:** Always stream responses for user-facing chat UIs to reduce perceived latency\n- ✅ **Do:** Store API keys in environment variables, never hard-code them\n- ✅ **Do:** Implement exponential backoff for rate limit (429) errors\n- ✅ **Do:** Use `systemInstruction` to set persistent model behavior\n- ❌ **Don't:** Use `gemini-pro` for simple tasks — Flash is cheaper and faster\n- ❌ **Don't:** Send large base64 images inline for files > 20MB — use File API instead\n- ❌ **Don't:** Ignore safety ratings in responses for production apps\n\n## Error Handling\n\n```javascript\ntry {\n  const result = await model.generateContent(prompt);\n  return result.response.text();\n} catch (error) {\n  if (error.status === 429) {\n    \u002F\u002F Rate limited — wait and retry with exponential backoff\n    await new Promise(r => setTimeout(r, 2 ** retryCount * 1000));\n  } else if (error.status === 400) {\n    \u002F\u002F Invalid request — check prompt or parameters\n    console.error(\"Invalid request:\", error.message);\n  } else {\n    throw error;\n  }\n}\n```\n\n## Troubleshooting\n\n**Problem:** `API_KEY_INVALID` error\n**Solution:** Ensure `GEMINI_API_KEY` environment variable is set and the key is active in Google AI Studio.\n\n**Problem:** Response blocked by safety filters\n**Solution:** Check `result.response.promptFeedback.blockReason` and adjust your prompt or safety settings.\n\n**Problem:** Slow response times\n**Solution:** Switch to `gemini-1.5-flash` and enable streaming. Consider caching repeated prompts.\n\n**Problem:** `RESOURCE_EXHAUSTED` (quota exceeded)\n**Solution:** Check your quota in Google Cloud Console. Implement request queuing and exponential backoff.\n",{"name":5,"risk":36,"source":41,"date_added":54,"description":7},"2026-03-04","main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fglobal\u002Fgemini-api-integration","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill gemini-api-integration",{"tool":67,"command":68},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill gemini-api-integration",{"tool":70,"command":71},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill gemini-api-integration","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fgemini-api-integration\u002FSKILL.md",true,[],[76,98,122,132,145,162],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":85,"publishedAt":49},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[82],{"categoryNo":83,"categoryName":84,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000037","律师与法务",[86,87,88,89,90,91,92,93,94,95,96,97],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch","with",{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":104,"publishedAt":49},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[105,106,107,108,109,110,88,111,112,113,114,37,115,116,117,118,119,120,121,32],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","brew","live","data","google","install","read","across",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":128,"publishedAt":49},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[129,130,105,115,116,117,118,109,88,120,131,121,32,37,113,112,111,119,110,108],"trend radar","radar","pulse",{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":138,"publishedAt":49},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[139,140,141,142,143,144],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":154,"publishedAt":49},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[151],{"categoryNo":152,"categoryName":153,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",[147,94,155,156,157,97,115,158,159,160,107,161,119],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":168,"publishedAt":49},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[164,169,170,171,119,172,159,173,174,175,176,177],"status","play","go","latest","github","discover","control","cmd","volume"]