{"id":50751619,"url":"https://github.com/rajeshsub/raw-api-agent","last_synced_at":"2026-06-11T01:31:49.730Z","repository":{"id":363455533,"uuid":"1261886911","full_name":"rajeshsub/raw-api-agent","owner":"rajeshsub","description":"An AI agent built with raw api instead of langchain or framework abstractions","archived":false,"fork":false,"pushed_at":"2026-06-09T01:34:25.000Z","size":10269,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T02:25:22.074Z","etag":null,"topics":["agentic-coding","agentic-engineering","ai-agent","gemini-api","rawg-api"],"latest_commit_sha":null,"homepage":"https://huggingface.co/spaces/rajeshsub/raw-api-agent","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rajeshsub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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}},"created_at":"2026-06-07T09:35:39.000Z","updated_at":"2026-06-09T01:34:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rajeshsub/raw-api-agent","commit_stats":null,"previous_names":["rajeshsub/raw-api-agent"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rajeshsub/raw-api-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rajeshsub%2Fraw-api-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rajeshsub%2Fraw-api-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rajeshsub%2Fraw-api-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rajeshsub%2Fraw-api-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rajeshsub","download_url":"https://codeload.github.com/rajeshsub/raw-api-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rajeshsub%2Fraw-api-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34178819,"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-10T02:00:07.152Z","response_time":89,"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":["agentic-coding","agentic-engineering","ai-agent","gemini-api","rawg-api"],"created_at":"2026-06-11T01:31:49.650Z","updated_at":"2026-06-11T01:31:49.721Z","avatar_url":"https://github.com/rajeshsub.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# raw-api-agent\n\nGoal-driven AI agent built on raw Gemini function calling — no LangChain, no framework abstractions. Python 3.13 + FastAPI.\n\n**Live demo:** [huggingface.co/spaces/rajeshsub/raw-api-agent](https://huggingface.co/spaces/rajeshsub/raw-api-agent) — every push to `main` is automatically deployed.\n\n![raw-api-agent demo](assets/raw-api-agent-demo.gif)\n\n## What it does\n\nSend a natural language goal. The agent decides which tools to call, in what order, loops until done. Streams reasoning steps and final answer via Server-Sent Events.\n\n## Why no LangChain\n\nLangChain abstracts the function calling protocol behind convenience wrappers. This project calls the Gemini API directly to demonstrate how the tool use protocol actually works: what goes into the message history, how function call parts differ from text parts, how tool results feed back into the next model turn.\n\nSee [ADR-0001](docs/adr/0001-raw-gemini-no-langchain.md).\n\n## Architecture\n\n```\nPOST /agent/run         → runs agent loop → returns AgentResult (JSON)\nPOST /agent/stream      → runs agent loop → streams SSE events\nGET  /health            → service status\n\nAgent Loop:\n  1. Send goal + message history to Gemini with tool declarations\n  2. If STOP with text → return final answer\n  3. If STOP with function_call parts → dispatch tools, append results to history\n  4. Repeat up to max_iterations (default: 10)\n  5. If cap reached → return partial: true + steps so far\n```\n\n## Tools\n\n| Tool | Description |\n|---|---|\n| `web_search` | Search the web via Tavily API — explicit tool call, fully visible in SSE stream |\n| `file_read` | Read a file from workspace (sandboxed, no path traversal) |\n| `file_write` | Write a file to workspace (creates parent dirs) |\n| `calculate` | Evaluate math expressions safely via simpleeval (supports sqrt, trig, log) |\n\n## SSE Event Format\n\n```\nevent: thinking\ndata: {\"type\":\"thinking\",\"message\":\"Iteration 1: reasoning about next step...\"}\n\nevent: tool_call\ndata: {\"type\":\"tool_call\",\"tool\":\"calculate\",\"args\":{\"expression\":\"sqrt(2) * 100\"}}\n\nevent: tool_result\ndata: {\"type\":\"tool_result\",\"tool\":\"calculate\",\"result\":\"141.4213562373095\"}\n\nevent: answer\ndata: {\"type\":\"answer\",\"content\":\"Python 3.13 was released on...\"}\n```\n\nStream endpoint requires `fetch` with streaming (not `EventSource` — see [ADR-0002](docs/adr/0002-post-for-sse-streaming.md)).\n\nExample fetch client:\n```javascript\nconst res = await fetch('/agent/stream', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json', 'X-API-Key': 'your-key' },\n  body: JSON.stringify({ goal: 'Research Python 3.13 changes' })\n});\nfor await (const chunk of res.body) {\n  const text = new TextDecoder().decode(chunk);\n  console.log(text);\n}\n```\n\n## Quickstart\n\n**Windows:**\n```powershell\ngit clone https://github.com/rajeshsub/raw-api-agent\ncd raw-api-agent\n.\\bootstrap.ps1\n# Edit .env — add GEMINI_API_KEY and API_KEY\n.venv\\Scripts\\uvicorn app.main:app --reload\n```\n\n**Linux/macOS:**\n```bash\ngit clone https://github.com/rajeshsub/raw-api-agent\ncd raw-api-agent\nmake bootstrap\n# Edit .env — add GEMINI_API_KEY and API_KEY\nmake dev\n```\n\n## API Keys\n\n| Key | Source |\n|---|---|\n| `GEMINI_API_KEY` | [Google AI Studio](https://aistudio.google.com) |\n| `API_KEY` | Choose any secret string — used for `X-API-Key` header auth |\n| `TAVILY_API_KEY` | [Tavily](https://tavily.com) — free tier available |\n\n## Example goals\n\n```bash\n# JSON answer\ncurl -X POST http://localhost:8000/agent/run \\\n  -H \"X-API-Key: your-key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"goal\": \"What is 15% of 2847?\"}'\n\n# Write to workspace\ncurl -X POST http://localhost:8000/agent/run \\\n  -H \"X-API-Key: your-key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"goal\": \"Calculate the compound interest on $10000 at 5% for 10 years and write the result to report.md\"}'\n\n# Stream events\ncurl -X POST http://localhost:8000/agent/stream \\\n  -H \"X-API-Key: your-key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"goal\": \"Calculate sqrt(2) * 100 rounded to 2 decimal places\"}' \\\n  --no-buffer\n```\n\n## Running tests\n\n```bash\n# Linux/macOS\nmake test\n\n# Windows\n.venv\\Scripts\\pytest tests\\ --cov=app --cov-fail-under=80\n```\n\nTests are fully mocked — no real API calls, no keys needed.\n\n## Linting\n\n```bash\n# Linux/macOS\nmake lint\n\n# Windows\n.venv\\Scripts\\ruff check app\\ tests\\\n.venv\\Scripts\\black --check app\\ tests\\\n.venv\\Scripts\\mypy app\\ --strict\n.venv\\Scripts\\bandit -r app\\ -c pyproject.toml\n```\n\n## File security\n\n`file_read` and `file_write` resolve all paths relative to `AGENT_WORKSPACE` and reject any path that escapes the workspace boundary (e.g. `../etc/passwd`). Uses `pathlib.Path.resolve()` + `is_relative_to()` — works cross-platform.\n\n## Model\n\n`gemini-2.5-flash` on paid tier — optimized for cost and tool use. Configurable via `GEMINI_MODEL` env var.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frajeshsub%2Fraw-api-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frajeshsub%2Fraw-api-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frajeshsub%2Fraw-api-agent/lists"}