{"id":35858043,"url":"https://github.com/acodercat/cave-agent","last_synced_at":"2026-04-07T12:00:37.259Z","repository":{"id":273850038,"uuid":"921101366","full_name":"acodercat/cave-agent","owner":"acodercat","description":"Stateful runtime management for LLM agents—inject, manipulate, and retrieve Python objects across turns. ","archived":false,"fork":false,"pushed_at":"2026-03-27T03:12:49.000Z","size":15889,"stargazers_count":151,"open_issues_count":0,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-04-01T16:40:12.425Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://caveagent.dev","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/acodercat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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":"2025-01-23T10:40:48.000Z","updated_at":"2026-04-01T08:08:49.000Z","dependencies_parsed_at":"2026-01-19T16:02:06.757Z","dependency_job_id":null,"html_url":"https://github.com/acodercat/cave-agent","commit_stats":null,"previous_names":["acodercat/pyagent","acodercat/py-calling-agent","acodercat/cave-agent"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/acodercat/cave-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Fcave-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Fcave-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Fcave-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Fcave-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/acodercat","download_url":"https://codeload.github.com/acodercat/cave-agent/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Fcave-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31511784,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":[],"created_at":"2026-01-08T10:11:11.308Z","updated_at":"2026-04-07T12:00:37.252Z","avatar_url":"https://github.com/acodercat.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/acodercat/cave-agent/raw/master/assets/logo-dark.svg\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/acodercat/cave-agent/raw/master/assets/logo-light.svg\"\u003e\n    \u003cimg src=\"https://github.com/acodercat/cave-agent/raw/master/assets/logo-light.svg\" alt=\"CaveAgent\" width=\"50%\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003ch3 align=\"center\"\u003e\n  \u003cb\u003eCaveAgent: Transforming LLMs into Stateful Runtime Operators \u003c/b\u003e\n\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://caveagent.dev\"\u003e\u003cimg src=\"https://img.shields.io/badge/-Website-brightgreen?style=flat-square\u0026logo=googlechrome\u0026logoColor=white\" alt=\"Website\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://arxiv.org/abs/2601.01569\"\u003e\u003cimg src=\"https://img.shields.io/badge/arXiv-Paper-red?style=flat-square\u0026logo=arxiv\" alt=\"arXiv Paper\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow?style=flat-square\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.python.org/downloads/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Python-3.12+-blue?style=flat-square\" alt=\"Python 3.12+\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/cave-agent\"\u003e\u003cimg src=\"https://img.shields.io/badge/PyPI-0.7.2-blue?style=flat-square\" alt=\"PyPI version\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003e\"From text-in-text-out to (text\u0026amp;object)-in-(text\u0026amp;object)-out\"\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\nMost LLM agents operate under a text-in-text-out paradigm, with tool interactions constrained to JSON primitives. CaveAgent breaks this with **Stateful Runtime Management**—a persistent Python runtime with direct **variable injection and retrieval**:\n\n- **Inject** any Python object into the runtime—DataFrames, models, database connections, custom class instances—as first-class variables the LLM can manipulate\n- **Persist** state across turns without serialization; objects live in the runtime, not in the context window\n- **Retrieve** manipulated objects back as native Python types for downstream\n\n\nhttps://github.com/user-attachments/assets/0e4a23b0-1afb-4408-8d87-ae1e13388aae\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Hello World](#hello-world)\n- [Runtimes](#runtimes)\n- [Examples](#examples)\n  - [Data Visualization](#data-visualization)\n  - [Function Calling](#function-calling)\n  - [Stateful Object Interactions](#stateful-object-interactions)\n  - [Multi-Agent Coordination](#multi-agent-coordination)\n  - [Real-time Streaming](#real-time-streaming)\n  - [Security Rules](#security-rules)\n- [Agent Skills](#agent-skills)\n  - [Creating a Skill](#creating-a-skill)\n  - [How Skills Load](#how-skills-load-progressive-disclosure)\n  - [Using Skills](#using-skills)\n  - [Injection Module](#injection-module-caveagent-extension)\n- [Features](#features)\n- [Configuration](#configuration)\n- [LLM Provider Support](#llm-provider-support)\n\n## Installation\n\n```bash\npip install 'cave-agent[all]'\n```\n\nChoose your installation:\n\n```bash\n# OpenAI support\npip install 'cave-agent[openai]'\n\n# 100+ LLM providers via LiteLLM\npip install 'cave-agent[litellm]'\n\n# Process-isolated kernel runtime (IPyKernelRuntime)\npip install 'cave-agent[ipykernel]'\n```\n\n## Hello World\n\n```python\nimport asyncio\nfrom cave_agent import CaveAgent\nfrom cave_agent.runtime import IPythonRuntime, Variable, Function\nfrom cave_agent.models import LiteLLMModel\n\nmodel = LiteLLMModel(model_id=\"model-id\", api_key=\"your-api-key\", custom_llm_provider=\"openai\")\n\nasync def main():\n    def reverse(s: str) -\u003e str:\n        \"\"\"Reverse a string\"\"\"\n        return s[::-1]\n\n    runtime = IPythonRuntime(\n        variables=[\n            Variable(\"secret\", \"!dlrow ,olleH\", \"A reversed message\"),\n            Variable(\"greeting\", \"\", \"Store the reversed message\"),\n        ],\n        functions=[Function(reverse)],\n    )\n    agent = CaveAgent(model, runtime=runtime)\n    response = await agent.run(\"Reverse the secret\")\n    print(await runtime.retrieve(\"secret\"))  # Hello, world!\n    print(response.content)              # Agent's text response\n\nasyncio.run(main())\n```\n\n## Runtimes\n\nCaveAgent provides two runtime backends. Both share the same API for injecting functions, variables, and types — choose based on your trust and isolation requirements.\n\n### IPythonRuntime (default)\n\nCode runs **in the same process** via an embedded IPython shell. Injected objects (DataFrames, DB connections, custom classes) are accessed directly — no serialization overhead.\n\n```python\nfrom cave_agent.runtime import IPythonRuntime, Function, Variable\n\nruntime = IPythonRuntime(\n    functions=[Function(my_func)],\n    variables=[Variable(\"data\", my_dataframe, \"Input data\")],\n)\nagent = CaveAgent(model, runtime=runtime)\n```\n\nBest for: trusted environments, internal tools, when you need zero-overhead access to complex Python objects.\n\n### IPyKernelRuntime (process-isolated)\n\nCode runs in a **separate IPython kernel process**. If the code crashes (segfault, OOM, infinite loop), the host process stays alive — just reset the kernel and continue.\n\n```bash\npip install 'cave-agent[ipykernel]'\n```\n\n```python\nfrom cave_agent.runtime import IPyKernelRuntime, Function, Variable\n\nasync with IPyKernelRuntime(\n    functions=[Function(my_func)],\n    variables=[Variable(\"data\", [1, 2, 3], \"Input data\")],\n) as runtime:\n    agent = CaveAgent(model, runtime=runtime)\n    response = await agent.run(\"Analyze the data\")\n```\n\nInjected objects are serialized via [dill](https://github.com/uqfoundation/dill), which supports local functions, closures, lambdas, and most Python objects.\n\nBest for: untrusted code execution, multi-tenant environments, sandboxed agent workflows.\n\n### Comparison\n\n| | IPythonRuntime | IPyKernelRuntime |\n|---|---|---|\n| Isolation | Same process | Separate process |\n| Crash impact | Host process dies | Kernel restarts, host survives |\n| Object injection | Direct reference, zero-copy | Serialized via dill |\n| Startup | Instant | ~1s (kernel launch) |\n| Local functions / closures | Always works | Works (via dill) |\n| Requires | *(included)* | `pip install 'cave-agent[ipykernel]'` |\n\n## Examples\n\n### Data Visualization\n\n```python\nfrom cave_agent import CaveAgent\nfrom cave_agent.runtime import IPythonRuntime, Variable\nfrom cave_agent.models import LiteLLMModel\n\nmodel = LiteLLMModel(model_id=\"model-id\", api_key=\"your-api-key\", custom_llm_provider=\"openai\")\n\n# 1. Inject — real DB connection \u0026 chart config manager\nruntime = IPythonRuntime(\n    variables=[\n        Variable(\"engine\", database_engine),             # SQLAlchemy Engine\n        Variable(\"echarts_config_manager\", EChartsConfigManager()),  # Chart collector\n    ]\n)\nagent = CaveAgent(model, runtime=runtime)\n\n# 2. Query — LLM sees object types, not data\nawait agent.run(\"Show me the air quality trend for the past week\")\n\n# LLM generates \u0026 executes:\n#   df = pd.read_sql(\"SELECT * FROM air_quality WHERE ...\", engine)\n#   echarts_config_manager.add_config({\n#       \"title\": {\"text\": \"Air Quality - Past Week\"},\n#       \"xAxis\": {\"data\": dates},\n#       \"series\": [{\"name\": \"PM2.5\", \"type\": \"line\", \"data\": ...}]\n#   })\n\n# 3. Retrieve — get real chart configs for rendering\nmgr = await runtime.retrieve(\"echarts_config_manager\")  # Real Python object\nconfigs = mgr.get_configs()\n\nfor config in configs:\n    render_echarts(config)  # Render directly in web UI\n```\n\n### Function Calling\n\n```python\n# Inject functions and variables into runtime\nruntime = IPythonRuntime(\n    variables=[Variable(\"tasks\", [], \"User's task list\")],\n    functions=[Function(add_task), Function(complete_task)],\n)\nagent = CaveAgent(model, runtime=runtime)\n\nawait agent.run(\"Add 'buy groceries' to my tasks\")\nprint(await runtime.retrieve(\"tasks\"))  # [{'name': 'buy groceries', 'done': False}]\n```\n\nSee [examples/basic_usage.py](examples/basic_usage.py) for a complete example.\n\n### Stateful Object Interactions\n\n```python\n# Inject objects with methods - LLM can call them directly\nruntime = IPythonRuntime(\n    types=[Type(Light), Type(Thermostat)],\n    variables=[\n        Variable(\"light\", Light(\"Living Room\"), \"Smart light\"),\n        Variable(\"thermostat\", Thermostat(), \"Home thermostat\"),\n    ],\n)\nagent = CaveAgent(model, runtime=runtime)\n\nawait agent.run(\"Dim the light to 20% and set thermostat to 22°C\")\nlight = await runtime.retrieve(\"light\")  # Object with updated state\n```\n\nSee [examples/object_methods.py](examples/object_methods.py) for a complete example.\n\n### Multi-Agent Coordination\n\n```python\n# Sub-agents with their own runtimes\ncleaner_agent = CaveAgent(model, runtime=IPythonRuntime(variables=[\n    Variable(\"data\", [], \"Input\"), Variable(\"cleaned_data\", [], \"Output\"),\n]))\n\nanalyzer_agent = CaveAgent(model, runtime=IPythonRuntime(variables=[\n    Variable(\"data\", [], \"Input\"), Variable(\"insights\", {}, \"Output\"),\n]))\n\n# Orchestrator controls sub-agents as first-class objects\norchestrator = CaveAgent(model, runtime=IPythonRuntime(variables=[\n    Variable(\"raw_data\", raw_data, \"Raw dataset\"),\n    Variable(\"cleaner\", cleaner_agent, \"Cleaner agent\"),\n    Variable(\"analyzer\", analyzer_agent, \"Analyzer agent\"),\n]))\n\n# Inject → trigger → retrieve\nawait orchestrator.run(\"Clean raw_data using cleaner, then analyze using analyzer\")\ninsights = await analyzer.runtime.retrieve(\"insights\")\n```\n\nSee [examples/multi_agent.py](examples/multi_agent.py) for a complete example.\n\n### Real-time Streaming\n\n```python\nasync for event in agent.stream_events(\"Analyze this data\"):\n    if event.type.value == 'code':\n        print(f\"Executing: {event.content}\")\n    elif event.type.value == 'execution_output':\n        print(f\"Result: {event.content}\")\n```\n\nSee [examples/stream.py](examples/stream.py) for a complete example.\n\n### Security Rules\n\n```python\n# Block dangerous operations with AST-based validation\nrules = [\n    ImportRule({\"os\", \"subprocess\", \"sys\"}),\n    FunctionRule({\"eval\", \"exec\", \"open\"}),\n    AttributeRule({\"__globals__\", \"__builtins__\"}),\n    RegexRule([r\"rm\\s+-rf\", r\"sudo\\s+\"]),\n]\nruntime = IPythonRuntime(security_checker=SecurityChecker(rules))\n```\n\n### More Examples\n\n- [Basic Usage](examples/basic_usage.py): Function calling and object processing\n- [Runtime State](examples/runtime_state.py): State management across interactions\n- [Object Methods](examples/object_methods.py): Class methods and complex objects\n- [Multi-Turn](examples/multi_turn.py): Conversations with state persistence\n- [Multi-Agent](examples/multi_agent.py): Data pipeline with multiple agents\n- [Stream](examples/stream.py): Streaming responses and events\n\n## Agent Skills\n\nCaveAgent implements the [Agent Skills](https://agentskills.io) open standard—a portable format for packaging instructions that agents can discover and use. Originally developed by Anthropic and now supported across the AI ecosystem (Claude, Gemini CLI, Cursor, VS Code, and more), Skills enable agents to acquire domain expertise on-demand.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/acodercat/cave-agent/raw/master/assets/skills.png\" alt=\"Agent Skills Architecture\" width=\"85%\"\u003e\n\u003c/p\u003e\n\n### Creating a Skill\n\nA Skill is a directory containing a `SKILL.md` file with YAML frontmatter:\n\n```\nmy-skill/\n├── SKILL.md           # Required: Skill definition and instructions\n└── injection.py       # Optional: Functions/variables/types to inject (CaveAgent extension)\n```\n\n**SKILL.md** structure:\n\n```markdown\n---\nname: data-processor\ndescription: Process and analyze datasets with statistical methods. Use when working with data analysis tasks.\n---\n\n# Data Processing Instructions\n\n## Quick Start\nUse the injected functions to analyze datasets...\n\n## Workflows\n1. Activate the skill to load injected functions\n2. Apply statistical analysis using the provided functions\n3. Return structured results\n```\n\n**Required fields**: `name` (max 64 chars, lowercase with hyphens) and `description` (max 1024 chars)\n\n**Optional fields**: `license`, `compatibility`, `metadata`\n\n### How Skills Load (Progressive Disclosure)\n\nSkills use progressive disclosure to minimize context usage:\n\n| Level | When Loaded | Content |\n|-------|-------------|---------|\n| **Metadata** | At startup | `name` and `description` from YAML frontmatter (~100 tokens) |\n| **Instructions** | When activated | SKILL.md body with guidance (loaded on-demand) |\n\n### Using Skills\n\n```python\nfrom pathlib import Path\nfrom cave_agent import CaveAgent, Skill\nfrom cave_agent.skills import SkillDiscovery\nfrom cave_agent.runtime import Function, Variable\n\n# Create skills directly\nskill = Skill(\n    name=\"my-skill\",\n    description=\"A custom skill\",\n    body_content=\"# Instructions\\nFollow these steps...\",\n    functions=[Function(my_func)],\n    variables=[Variable(\"config\", value={})],\n)\nagent = CaveAgent(model=model, skills=[skill])\n\n# Or load from files\nskill = SkillDiscovery.from_file(Path(\"./my-skill/SKILL.md\"))\nagent = CaveAgent(model=model, skills=[skill])\n\n# Or load from directory\nskills = SkillDiscovery.from_directory(Path(\"./skills\"))\nagent = CaveAgent(model=model, skills=skills)\n```\n\nWhen skills are loaded, the agent gains access to the `activate_skill(skill_name)` runtime function to activate a skill and load its instructions.\n\n### Injection Module (CaveAgent Extension)\n\nCaveAgent extends the Agent Skills standard with `injection.py`—allowing skills to inject functions, variables, and types directly into the runtime when activated:\n\n```python\nfrom cave_agent.runtime import Function, Variable, Type\nfrom dataclasses import dataclass\n\ndef analyze_data(data: list) -\u003e dict:\n    \"\"\"Analyze data and return statistics.\"\"\"\n    return {\"mean\": sum(data) / len(data), \"count\": len(data)}\n\n@dataclass\nclass AnalysisResult:\n    mean: float\n    count: int\n    status: str\n\nCONFIG = {\"threshold\": 0.5, \"max_items\": 1000}\n\n__exports__ = [\n    Function(analyze_data, description=\"Analyze data statistically\"),\n    Variable(\"CONFIG\", value=CONFIG, description=\"Analysis configuration\"),\n    Type(AnalysisResult, description=\"Result structure\"),\n]\n```\n\nWhen `activate_skill()` is called, these exports are automatically injected into the runtime namespace.\n\nSee [examples/skill_data_processor.py](examples/skill_data_processor.py) for a complete example.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/acodercat/cave-agent/raw/master/assets/overall.png\" alt=\"CaveAgent Architecture\"\u003e\n\u003c/p\u003e\n\n## Features\n\n- **Code-Based Function Calling**: Leverages LLM's natural coding abilities instead of rigid JSON schemas\n- **Secure Runtime Environment**:\n  - Inject Python objects, variables, and functions as tools\n  - Rule-based security validation prevents dangerous code execution\n  - Flexible security rules: ImportRule, FunctionRule, AttributeRule, RegexRule\n  - Customizable security policies for different use cases\n  - Access execution results and maintain state across interactions\n- **[Agent Skills](https://agentskills.io)**: Implements the open Agent Skills standard for modular, portable instruction packages. CaveAgent extends the standard with runtime injection (`injection.py`).\n- **Multi-Agent Coordination**: Control sub-agents programmatically through runtime injection and retrieval. Shared runtimes enable instant state synchronization.\n- **Streaming \u0026 Async**: Real-time event streaming and full async/await support for optimal performance\n- **Execution Control**: Configurable step limits and error handling to prevent infinite loops\n- **Flexible LLM Support**: Works with any LLM provider via OpenAI-compatible APIs or LiteLLM\n- **Type Injection**: Expose class schemas for type-aware LLM code generation\n\n\n## Awesome Blogs\n\nWe thank these community to post our work.\n\n- [CaveAgent让LLM学会了“跑代码”，你能把Agent变成Jupyter里的“老司机”](https://mp.weixin.qq.com/s/cJQ8ki0gXSmcbTPaBBfT5g)\n- [Token消耗减半性能满分！状态化运行时管理能力让智能体性能飞升](https://mp.weixin.qq.com/s/qfVl3ATO4ueDdPb4npmTXQ)\n- [Stateful environment to LLMs](https://x.com/rosinality/status/2008434433972728264)\n- [TEKTA-AI](https://www.tekta.ai/ai-research-papers/caveagent-stateful-llm-runtime-2025)\n\n## Configuration\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| model | Model | required | LLM model instance (OpenAIServerModel or LiteLLMModel) |\n| runtime | Runtime | None | `IPythonRuntime` (default) or `IPyKernelRuntime` (process-isolated) |\n| skills | List[Skill] | None | List of skill objects to load |\n| max_steps | int | 10 | Maximum execution steps per run |\n| max_history | int | 20 | Maximum conversation history length |\n| max_exec_output | int | 5000 | Max characters in execution output |\n| max_exec_timeout | float \\| None | None | Max seconds per code execution. LLM is guided to use timeouts in network/DB calls |\n| display | bool | True | Render events to terminal via Rich (Claude Code-style UI) |\n| instructions | str | default | User instructions defining agent role and behavior |\n| system_instructions | str | default | System-level execution rules and examples |\n| system_prompt_template | str | default | Custom system prompt template |\n| python_block_identifier | str | python | Code block language identifier |\n| messages | List[Message] | None | Initial message history |\n\n## LLM Provider Support\n\nCaveAgent supports multiple LLM providers:\n\n### OpenAI-Compatible Models\n```python\nfrom cave_agent.models import OpenAIServerModel\n\nmodel = OpenAIServerModel(\n    model_id=\"gpt-4\",\n    api_key=\"your-api-key\",\n    base_url=\"https://api.openai.com/v1\"  # or your custom endpoint\n)\n```\n\n### LiteLLM Models (Recommended)\nLiteLLM provides unified access to hundreds of LLM providers:\n\n```python\nfrom cave_agent.models import LiteLLMModel\n\n# OpenAI\nmodel = LiteLLMModel(\n    model_id=\"gpt-4\",\n    api_key=\"your-api-key\",\n    custom_llm_provider='openai'\n)\n\n# Anthropic Claude\nmodel = LiteLLMModel(\n    model_id=\"claude-3-sonnet-20240229\",\n    api_key=\"your-api-key\",\n    custom_llm_provider='anthropic' \n)\n\n# Google Gemini\nmodel = LiteLLMModel(\n    model_id=\"gemini/gemini-pro\",\n    api_key=\"your-api-key\"\n)\n```\n\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a PR.\nFor more details, see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## Citation\n\nIf you use CaveAgent in your research, please cite:\n```bibtex\n@article{ran2026caveagent,\n  title={CaveAgent: Transforming LLMs into Stateful Runtime Operators},\n  author={Ran, Maohao and Wan, Zhenglin and Lin, Cooper and Zhang, Yanting and others},\n  journal={arXiv preprint arXiv:2601.01569},\n  year={2026}\n}\n```\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facodercat%2Fcave-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Facodercat%2Fcave-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facodercat%2Fcave-agent/lists"}