litecoo 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. litecoo-1.0.0/.claude/skills/docx/SKILL.md +23 -0
  2. litecoo-1.0.0/.claude/skills/pdf/SKILL.md +24 -0
  3. litecoo-1.0.0/.claude/skills/pptx/SKILL.md +24 -0
  4. litecoo-1.0.0/.claude/skills/xlsx/SKILL.md +23 -0
  5. litecoo-1.0.0/.env.example +17 -0
  6. litecoo-1.0.0/.gitignore +70 -0
  7. litecoo-1.0.0/MEMORY.md +20 -0
  8. litecoo-1.0.0/PKG-INFO +138 -0
  9. litecoo-1.0.0/README.md +103 -0
  10. litecoo-1.0.0/config.yaml +32 -0
  11. litecoo-1.0.0/models.json +0 -0
  12. litecoo-1.0.0/pyproject.toml +53 -0
  13. litecoo-1.0.0/requirements.txt +11 -0
  14. litecoo-1.0.0/schedules.json +1 -0
  15. litecoo-1.0.0/src/litecoo/__init__.py +0 -0
  16. litecoo-1.0.0/src/litecoo/agent_loop.py +107 -0
  17. litecoo-1.0.0/src/litecoo/cli.py +18 -0
  18. litecoo-1.0.0/src/litecoo/context.py +57 -0
  19. litecoo-1.0.0/src/litecoo/custom_router.py +260 -0
  20. litecoo-1.0.0/src/litecoo/main.py +978 -0
  21. litecoo-1.0.0/src/litecoo/mcp_client.py +272 -0
  22. litecoo-1.0.0/src/litecoo/memory.py +93 -0
  23. litecoo-1.0.0/src/litecoo/scheduler.py +135 -0
  24. litecoo-1.0.0/src/litecoo/skills.py +91 -0
  25. litecoo-1.0.0/src/litecoo/store.py +232 -0
  26. litecoo-1.0.0/src/litecoo/tools/__init__.py +67 -0
  27. litecoo-1.0.0/src/litecoo/tools/bash.py +85 -0
  28. litecoo-1.0.0/src/litecoo/tools/docx.py +80 -0
  29. litecoo-1.0.0/src/litecoo/tools/file_ops.py +99 -0
  30. litecoo-1.0.0/src/litecoo/tools/memory.py +51 -0
  31. litecoo-1.0.0/src/litecoo/tools/pdf.py +85 -0
  32. litecoo-1.0.0/src/litecoo/tools/pptx.py +81 -0
  33. litecoo-1.0.0/src/litecoo/tools/web_fetch.py +66 -0
  34. litecoo-1.0.0/src/litecoo/tools/web_search.py +79 -0
  35. litecoo-1.0.0/src/litecoo/tools/xlsx.py +90 -0
  36. litecoo-1.0.0/tests/check_anthropic_sse.py +67 -0
  37. litecoo-1.0.0/tests/check_sse.py +57 -0
  38. litecoo-1.0.0/tests/run_integration_tests.py +289 -0
  39. litecoo-1.0.0/tests/test_api.py +20 -0
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: docx
3
+ description: Create and edit Microsoft Word (.docx) documents with formatted text, headings, tables, and styles.
4
+ ---
5
+
6
+ # DOCX Skill
7
+
8
+ You can create Word documents using the `create_docx` tool.
9
+
10
+ ## Capabilities
11
+ - Create documents with multiple sections and headings (levels 0-4)
12
+ - Add formatted body paragraphs
13
+ - Set document metadata (author, title)
14
+ - Output to any writable path
15
+
16
+ ## Usage
17
+ When the user asks you to create a Word document (.docx file), use the `create_docx` tool with:
18
+ - `path`: where to save the file
19
+ - `title`: optional document title
20
+ - `sections`: array of `{heading, content, level}` objects
21
+ - `author`: optional author name
22
+
23
+ Always save documents to the user's Desktop or a path they specify. Confirm the file was created successfully.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: pdf
3
+ description: Create PDF documents with formatted text, headings, and tables using ReportLab.
4
+ ---
5
+
6
+ # PDF Skill
7
+
8
+ You can create PDF documents using the `create_pdf` tool.
9
+
10
+ ## Capabilities
11
+ - Create PDFs with title and multiple sections
12
+ - Support for A4 and Letter page sizes
13
+ - Formatted headings and body paragraphs
14
+ - Professional layout with margins
15
+
16
+ ## Usage
17
+ When the user asks you to create a PDF document (.pdf file), use the `create_pdf` tool with:
18
+ - `path`: where to save the file
19
+ - `title`: optional document title
20
+ - `sections`: array of `{heading, content}` objects
21
+ - `content`: body text (paragraphs separated by double newlines)
22
+ - `page_size`: "A4" or "Letter" (default A4)
23
+
24
+ Always save to the user's Desktop or specified path. Confirm the file was created.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: pptx
3
+ description: Create PowerPoint (.pptx) presentations with slides, titles, bullet points, and speaker notes.
4
+ ---
5
+
6
+ # PPTX Skill
7
+
8
+ You can create PowerPoint presentations using the `create_pptx` tool.
9
+
10
+ ## Capabilities
11
+ - Create multi-slide presentations
12
+ - Add slide titles and body content (bullet points)
13
+ - Include speaker notes per slide
14
+ - Set presentation title
15
+
16
+ ## Usage
17
+ When the user asks you to create a PowerPoint presentation (.pptx file), use the `create_pptx` tool with:
18
+ - `path`: where to save the file
19
+ - `title`: presentation title
20
+ - `slides`: array of `{title, content, notes}` objects
21
+ - `content`: bullet points separated by newlines
22
+ - `notes`: optional speaker notes
23
+
24
+ Always save to the user's Desktop or specified path. Confirm the file was created.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: xlsx
3
+ description: Create Excel (.xlsx) spreadsheets with multiple sheets, headers, styled columns, and data rows.
4
+ ---
5
+
6
+ # XLSX Skill
7
+
8
+ You can create Excel spreadsheets using the `create_xlsx` tool.
9
+
10
+ ## Capabilities
11
+ - Create workbooks with multiple sheets
12
+ - Add styled header rows with blue background
13
+ - Fill data rows
14
+ - Auto-sizing columns
15
+
16
+ ## Usage
17
+ When the user asks you to create an Excel spreadsheet (.xlsx file), use the `create_xlsx` tool with:
18
+ - `path`: where to save the file
19
+ - `sheets`: array of `{name, headers, rows}` objects
20
+ - `headers`: array of column names (optional)
21
+ - `rows`: array of arrays (each row is cell values)
22
+
23
+ Always save to the user's Desktop or specified path. Confirm the file was created.
@@ -0,0 +1,17 @@
1
+ # OpenRouter API Key (https://openrouter.ai/keys)
2
+ OPENROUTER_API_KEY=your_openrouter_key_here
3
+
4
+ # NVIDIA NIM API Key (https://build.nvidia.com/)
5
+ NVIDIA_API_KEY=your_nvidia_key_here
6
+
7
+ # OpenCodeZen API Key
8
+ OPENCODEZEN_API_KEY=your_opencodezen_key_here
9
+
10
+ # Config path (defaults to config.yaml in current directory)
11
+ COWORKFORVAS_CONFIG_PATH=config.yaml
12
+
13
+ # Optional tuning
14
+ # COWORKFORVAS_COOLDOWN_SECONDS=120
15
+ # COWORKFORVAS_MAX_CONTEXT_TOKENS=50000
16
+ # COWORKFORVAS_SESSION_TTL_DAYS=7
17
+ # COWORKFORVAS_DB_PATH=coworkforvas.db
@@ -0,0 +1,70 @@
1
+ # Environments
2
+ .env
3
+ .venv
4
+ env/
5
+ venv/
6
+ ENV/
7
+ env.bak/
8
+ venv.bak/
9
+
10
+ # Byte-compiled / optimized / DLL files
11
+ __pycache__/
12
+ *.py[cod]
13
+ *$py.class
14
+
15
+ # Distribution / packaging
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+ MANIFEST
33
+
34
+ # PyInstaller
35
+ # Usually these files are written by a python script from a template
36
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Installer logs
41
+ pip-log.txt
42
+ pip-delete-this-directory.txt
43
+
44
+ # Unit test / coverage reports
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+ .coverage
49
+ .coverage.*
50
+ .cache
51
+ nosetests.xml
52
+ coverage.xml
53
+ *.cover
54
+ *.py,cover
55
+ .hypothesis/
56
+ .pytest_cache/
57
+ cover/
58
+
59
+ # Jupyter Notebook
60
+ .ipynb_checkpoints
61
+
62
+ # IDEs
63
+ .vscode/
64
+ .idea/
65
+ *.swp
66
+ *.swo
67
+
68
+ # Project specific
69
+ cowork_proxy.db
70
+ sessions/
@@ -0,0 +1,20 @@
1
+ # AI Context Memory
2
+
3
+ This document serves as a persistent context memory for the project.
4
+
5
+ ## Project Architecture
6
+ - **Package name**: `coworkforvas` (litecoo v3).
7
+ - **Directory layout**: Standard `src/coworkforvas` and `tests/` structure.
8
+ - **Entry point**: `src/coworkforvas/cli.py:main` configures and runs `uvicorn`.
9
+ - **Frameworks**: `FastAPI` + `httpx` (proxy), SQLite (session persistence).
10
+
11
+ ## Key Files
12
+ - `src/coworkforvas/main.py`: Defines the FastAPI app and Anthropic/OpenAI conversion logic.
13
+ - `src/coworkforvas/custom_router.py`: Handles upstream `httpx` logic.
14
+ - `src/coworkforvas/agent_loop.py`: Executes multi-step tools internally when `X-Agent-Loop: server` is provided.
15
+ - `src/coworkforvas/tools/`: Built-in tools directory (`web_fetch`, `web_search`, `bash`, file and office document generation). All dependencies added in `pyproject.toml`.
16
+
17
+ ## Important Rules
18
+ - Local imports within `src/coworkforvas` must be relative (e.g. `from .store import get_session`).
19
+ - To run tests locally, install the package in editable mode with dev dependencies first (`pip install -e .[dev]`).
20
+ - Do not add arbitrary root scripts; use `pytest` for testing and `cli.py` for commands.
litecoo-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: litecoo
3
+ Version: 1.0.0
4
+ Summary: Free LLM proxy for Cowork and OpenAI-compatible clients — no litellm, pure httpx routing
5
+ Project-URL: Homepage, https://github.com/Saisharathchandranandnetha/KrishiMitra_Beast
6
+ Project-URL: Repository, https://github.com/Saisharathchandranandnetha/KrishiMitra_Beast
7
+ License: MIT
8
+ Keywords: anthropic,cowork,free,litecoo,llm,openai,proxy
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: aiosqlite>=0.20.0
19
+ Requires-Dist: chromadb>=0.5.0
20
+ Requires-Dist: fastapi<0.129.0,>=0.128.0
21
+ Requires-Dist: httpx>=0.27.0
22
+ Requires-Dist: openpyxl>=3.1.2
23
+ Requires-Dist: pydantic>=2.12.3
24
+ Requires-Dist: python-docx>=1.1.0
25
+ Requires-Dist: python-dotenv>=1.0.0
26
+ Requires-Dist: python-pptx>=0.6.23
27
+ Requires-Dist: pyyaml>=6.0.1
28
+ Requires-Dist: reportlab>=4.1.0
29
+ Requires-Dist: uvicorn<0.41.0,>=0.40.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: httpx; extra == 'dev'
32
+ Requires-Dist: pytest; extra == 'dev'
33
+ Requires-Dist: pytest-asyncio; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # litecoo (litecoo v3)
37
+
38
+ **litecoo** (formerly litecoo) is a local FastAPI proxy that makes free LLM models (DeepSeek V4, Gemma, Nemotron) behave like Claude for Cowork Desktop and Claude Code. It handles the Anthropic protocol, agentic tool loops, session memory, and built-in tools — all without spending a cent on API calls.
39
+
40
+ ---
41
+
42
+ ## 🚀 System Architecture
43
+
44
+ ```mermaid
45
+ graph TD
46
+ Client[Client (Cowork / curl)] --> API[FastAPI Proxy]
47
+ API --> Router[Model Router]
48
+
49
+ subgraph Core Features
50
+ Router --> Memory[SQLite Session Memory]
51
+ Router --> AgentLoop[Server-Side Agent Loop]
52
+ Router --> RateLimit[Cooldown / Rate Limiting]
53
+ end
54
+
55
+ subgraph Built-in Tools
56
+ AgentLoop --> Fetch[Web Fetch]
57
+ AgentLoop --> Search[Web Search]
58
+ AgentLoop --> Bash[Bash Command]
59
+ AgentLoop --> FileOps[File Read/Write]
60
+ AgentLoop --> Office[Create PDF/DOCX/PPTX]
61
+ end
62
+
63
+ Router --> Provider[OpenRouter / DeepSeek / External APIs]
64
+ ```
65
+
66
+ ## 🛠️ Endpoints
67
+
68
+ | Endpoint | Format | Description |
69
+ |---|---|---|
70
+ | `POST /v1/messages` | Anthropic | For Claude Desktop and Cowork. Handles tool loops and SSE streaming. |
71
+ | `POST /v1/chat/completions` | OpenAI | For standard OpenAI clients, Claude Code, curl. |
72
+ | `GET /v1/models` | Standard | Returns the list of available aliases. |
73
+ | `GET /v1/sessions/{id}` | Internal | Inspect a session's history. |
74
+ | `DELETE /v1/sessions/{id}` | Internal | Clear a session from SQLite. |
75
+ | `GET /v1/cooldowns` | Internal | Check rate limit status for each model. |
76
+ | `GET /v1/usage` | Internal | Review token usage stats. |
77
+
78
+ ## 📦 Built-in Tools
79
+
80
+ If the client doesn't send its own tool definitions, litecoo automatically injects these tools:
81
+ - `web_fetch`, `web_search`: DuckDuckGo and basic page scraping.
82
+ - `bash`: Local command execution.
83
+ - `read_file`, `write_file`: Read and write to disk.
84
+ - `create_pdf`, `create_docx`, `create_pptx`, `create_xlsx`: Generate rich documents.
85
+
86
+ Add the header `X-Agent-Loop: server` to let litecoo automatically execute multi-step tools server-side before returning the final text to the client.
87
+
88
+ ---
89
+
90
+ ## 💻 Installation
91
+
92
+ To run it locally or use it as a library, install directly from source:
93
+
94
+ ```bash
95
+ python -m venv venv
96
+ # On Windows: venv\Scripts\activate
97
+ # On Mac/Linux: source venv/bin/activate
98
+
99
+ pip install litecoo
100
+ ```
101
+
102
+ Then run the proxy:
103
+ ```bash
104
+ litecoo --host 0.0.0.0 --port 8000 --env-file .env
105
+ ```
106
+
107
+ ## 🔌 Connecting Clients
108
+
109
+ **Claude Desktop:**
110
+ Settings → Developer → API base URL → `http://localhost:8000`
111
+
112
+ **Claude Code:**
113
+ ```bash
114
+ export ANTHROPIC_BASE_URL=http://localhost:8000
115
+ export ANTHROPIC_API_KEY=any-string
116
+ claude
117
+ ```
118
+
119
+ ## ⬆️ How to Publish to PyPI
120
+
121
+ If you are a developer and want to push the latest changes to PyPI, follow these steps:
122
+
123
+ 1. **Install build tools:**
124
+ ```bash
125
+ pip install build twine
126
+ ```
127
+
128
+ 2. **Build the wheel and source distribution:**
129
+ ```bash
130
+ python -m build
131
+ ```
132
+ *This creates a `dist/` directory with a `.tar.gz` and `.whl` file.*
133
+
134
+ 3. **Upload to PyPI:**
135
+ ```bash
136
+ python -m twine upload dist/*
137
+ ```
138
+ *You will be prompted for your PyPI API token (username `__token__`).*
@@ -0,0 +1,103 @@
1
+ # litecoo (litecoo v3)
2
+
3
+ **litecoo** (formerly litecoo) is a local FastAPI proxy that makes free LLM models (DeepSeek V4, Gemma, Nemotron) behave like Claude for Cowork Desktop and Claude Code. It handles the Anthropic protocol, agentic tool loops, session memory, and built-in tools — all without spending a cent on API calls.
4
+
5
+ ---
6
+
7
+ ## 🚀 System Architecture
8
+
9
+ ```mermaid
10
+ graph TD
11
+ Client[Client (Cowork / curl)] --> API[FastAPI Proxy]
12
+ API --> Router[Model Router]
13
+
14
+ subgraph Core Features
15
+ Router --> Memory[SQLite Session Memory]
16
+ Router --> AgentLoop[Server-Side Agent Loop]
17
+ Router --> RateLimit[Cooldown / Rate Limiting]
18
+ end
19
+
20
+ subgraph Built-in Tools
21
+ AgentLoop --> Fetch[Web Fetch]
22
+ AgentLoop --> Search[Web Search]
23
+ AgentLoop --> Bash[Bash Command]
24
+ AgentLoop --> FileOps[File Read/Write]
25
+ AgentLoop --> Office[Create PDF/DOCX/PPTX]
26
+ end
27
+
28
+ Router --> Provider[OpenRouter / DeepSeek / External APIs]
29
+ ```
30
+
31
+ ## 🛠️ Endpoints
32
+
33
+ | Endpoint | Format | Description |
34
+ |---|---|---|
35
+ | `POST /v1/messages` | Anthropic | For Claude Desktop and Cowork. Handles tool loops and SSE streaming. |
36
+ | `POST /v1/chat/completions` | OpenAI | For standard OpenAI clients, Claude Code, curl. |
37
+ | `GET /v1/models` | Standard | Returns the list of available aliases. |
38
+ | `GET /v1/sessions/{id}` | Internal | Inspect a session's history. |
39
+ | `DELETE /v1/sessions/{id}` | Internal | Clear a session from SQLite. |
40
+ | `GET /v1/cooldowns` | Internal | Check rate limit status for each model. |
41
+ | `GET /v1/usage` | Internal | Review token usage stats. |
42
+
43
+ ## 📦 Built-in Tools
44
+
45
+ If the client doesn't send its own tool definitions, litecoo automatically injects these tools:
46
+ - `web_fetch`, `web_search`: DuckDuckGo and basic page scraping.
47
+ - `bash`: Local command execution.
48
+ - `read_file`, `write_file`: Read and write to disk.
49
+ - `create_pdf`, `create_docx`, `create_pptx`, `create_xlsx`: Generate rich documents.
50
+
51
+ Add the header `X-Agent-Loop: server` to let litecoo automatically execute multi-step tools server-side before returning the final text to the client.
52
+
53
+ ---
54
+
55
+ ## 💻 Installation
56
+
57
+ To run it locally or use it as a library, install directly from source:
58
+
59
+ ```bash
60
+ python -m venv venv
61
+ # On Windows: venv\Scripts\activate
62
+ # On Mac/Linux: source venv/bin/activate
63
+
64
+ pip install litecoo
65
+ ```
66
+
67
+ Then run the proxy:
68
+ ```bash
69
+ litecoo --host 0.0.0.0 --port 8000 --env-file .env
70
+ ```
71
+
72
+ ## 🔌 Connecting Clients
73
+
74
+ **Claude Desktop:**
75
+ Settings → Developer → API base URL → `http://localhost:8000`
76
+
77
+ **Claude Code:**
78
+ ```bash
79
+ export ANTHROPIC_BASE_URL=http://localhost:8000
80
+ export ANTHROPIC_API_KEY=any-string
81
+ claude
82
+ ```
83
+
84
+ ## ⬆️ How to Publish to PyPI
85
+
86
+ If you are a developer and want to push the latest changes to PyPI, follow these steps:
87
+
88
+ 1. **Install build tools:**
89
+ ```bash
90
+ pip install build twine
91
+ ```
92
+
93
+ 2. **Build the wheel and source distribution:**
94
+ ```bash
95
+ python -m build
96
+ ```
97
+ *This creates a `dist/` directory with a `.tar.gz` and `.whl` file.*
98
+
99
+ 3. **Upload to PyPI:**
100
+ ```bash
101
+ python -m twine upload dist/*
102
+ ```
103
+ *You will be prompted for your PyPI API token (username `__token__`).*
@@ -0,0 +1,32 @@
1
+ # coworkforvas — model routing config
2
+ # Primary : DeepSeek V4 Flash Free via OpenCodeZen (verified working)
3
+ # Fallback 1: NVIDIA Nemotron 550B via OpenRouter (verified working)
4
+ # Fallback 2: Google Gemma 4 26B via OpenRouter (verified working)
5
+ # Standby : Gemini 2.5 Flash — DISABLED (credits depleted, re-enable when topped up)
6
+
7
+ model_list:
8
+ - model_name: free-default
9
+ provider_params:
10
+ model: openai/deepseek-v4-flash-free
11
+ api_base: https://opencode.ai/zen/v1
12
+ api_key: os.environ/OPENCODEZEN_API_KEY
13
+ extra_headers:
14
+ x-api-key: os.environ/OPENCODEZEN_API_KEY
15
+ User-Agent: "Mozilla/5.0"
16
+
17
+ - model_name: free-openrouter-nemotron
18
+ provider_params:
19
+ model: openrouter/nvidia/nemotron-3-ultra-550b-a55b:free
20
+ api_key: os.environ/OPENROUTER_API_KEY
21
+
22
+ - model_name: free-openrouter-gemma26b
23
+ provider_params:
24
+ model: openrouter/google/gemma-4-26b-a4b-it:free
25
+ api_key: os.environ/OPENROUTER_API_KEY
26
+
27
+ # Uncomment when Gemini credits are topped up at https://ai.studio/projects
28
+ # - model_name: free-gemini-flash
29
+ # provider_params:
30
+ # model: openai/gemini-2.5-flash
31
+ # api_base: https://generativelanguage.googleapis.com/v1beta/openai/
32
+ # api_key: os.environ/GEMINI_API_KEY
File without changes
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "litecoo"
7
+ version = "1.0.0"
8
+ description = "Free LLM proxy for Cowork and OpenAI-compatible clients — no litellm, pure httpx routing"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ keywords = ["llm", "proxy", "cowork", "openai", "anthropic", "free", "litecoo"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Topic :: Internet :: WWW/HTTP :: HTTP Servers",
22
+ ]
23
+ dependencies = [
24
+ "fastapi>=0.128.0,<0.129.0",
25
+ "uvicorn>=0.40.0,<0.41.0",
26
+ "pyyaml>=6.0.1",
27
+ "pydantic>=2.12.3",
28
+ "httpx>=0.27.0",
29
+ "aiosqlite>=0.20.0",
30
+ "python-dotenv>=1.0.0",
31
+ "python-docx>=1.1.0",
32
+ "python-pptx>=0.6.23",
33
+ "openpyxl>=3.1.2",
34
+ "reportlab>=4.1.0",
35
+ "chromadb>=0.5.0",
36
+ ]
37
+
38
+ [project.optional-dependencies]
39
+ dev = ["pytest", "pytest-asyncio", "httpx"]
40
+
41
+ [project.scripts]
42
+ litecoo = "litecoo.cli:main"
43
+
44
+ [project.urls]
45
+ Homepage = "https://github.com/Saisharathchandranandnetha/KrishiMitra_Beast"
46
+ Repository = "https://github.com/Saisharathchandranandnetha/KrishiMitra_Beast"
47
+
48
+ [tool.hatch.build.targets.wheel]
49
+ packages = ["src/litecoo"]
50
+
51
+ [tool.pytest.ini_options]
52
+ pythonpath = ["src"]
53
+
@@ -0,0 +1,11 @@
1
+ fastapi>=0.128.0,<0.129.0
2
+ uvicorn>=0.40.0,<0.41.0
3
+ pyyaml>=6.0.1
4
+ pydantic>=2.12.3
5
+ httpx>=0.27.0
6
+ aiosqlite>=0.20.0
7
+ python-dotenv>=1.0.0
8
+ python-docx>=1.1.0
9
+ python-pptx>=0.6.23
10
+ openpyxl>=3.1.2
11
+ reportlab>=4.1.0
@@ -0,0 +1 @@
1
+ []
File without changes
@@ -0,0 +1,107 @@
1
+ """
2
+ Server-side agentic loop for litecoo.
3
+ When X-Agent-Loop: server header is set on /v1/messages requests,
4
+ litecoo executes tool calls internally instead of returning them to the client.
5
+ The loop continues until stop_reason=end_turn or max_turns is reached.
6
+ """
7
+
8
+ import logging
9
+ from typing import Any, Optional
10
+
11
+ logger = logging.getLogger("litecoo.agent_loop")
12
+
13
+
14
+ async def run_agent_loop(
15
+ initial_messages: list[dict],
16
+ system: str,
17
+ tools: list[dict],
18
+ kwargs: dict,
19
+ alias: str,
20
+ router: Any,
21
+ session_id: str = None,
22
+ max_turns: int = 10,
23
+ execute_tool_fn: Optional[Any] = None,
24
+ ) -> dict:
25
+ """
26
+ Execute the agentic tool loop server-side.
27
+ Returns a final Anthropic-format response dict.
28
+ """
29
+ from .main import openai_response_to_anthropic # late import to avoid circular
30
+
31
+ messages = list(initial_messages)
32
+
33
+ # Ensure system message is prepended if not already present
34
+ if system and (not messages or messages[0].get("role") != "system"):
35
+ messages = [{"role": "system", "content": system}] + messages
36
+
37
+ last_anthropic_resp: dict = {}
38
+
39
+ for turn in range(max_turns):
40
+ call_kwargs = dict(kwargs)
41
+ call_kwargs["messages"] = messages
42
+ call_kwargs["stream"] = False
43
+ if tools:
44
+ call_kwargs["tools"] = tools
45
+
46
+ oai_resp = await router.acompletion(model=alias, **call_kwargs)
47
+ raw = oai_resp.model_dump() if hasattr(oai_resp, "model_dump") else dict(oai_resp)
48
+
49
+ # Determine request_model from alias for response
50
+ anthropic_resp = openai_response_to_anthropic(raw, alias)
51
+ last_anthropic_resp = anthropic_resp
52
+ stop_reason = anthropic_resp.get("stop_reason", "end_turn")
53
+
54
+ if stop_reason == "end_turn":
55
+ logger.info(f"[agent_loop] done after {turn + 1} turn(s)")
56
+ return anthropic_resp
57
+
58
+ if stop_reason == "max_tokens":
59
+ logger.info(f"[agent_loop] max_tokens hit at turn {turn + 1}")
60
+ return anthropic_resp
61
+
62
+ if stop_reason == "tool_use":
63
+ # Build the assistant message from the OAI response
64
+ choice = (raw.get("choices") or [{}])[0]
65
+ asst_msg = choice.get("message", {})
66
+ if hasattr(asst_msg, "model_dump"):
67
+ asst_msg = asst_msg.model_dump()
68
+ messages.append({"role": "assistant", **asst_msg})
69
+
70
+ # Execute each tool and append results to messages in OpenAI format
71
+ for block in anthropic_resp.get("content", []):
72
+ if block.get("type") != "tool_use":
73
+ continue
74
+ tool_name = block.get("name", "")
75
+ tool_input = block.get("input", {})
76
+ tool_id = block.get("id", "")
77
+
78
+ logger.info(f"[agent_loop] executing tool '{tool_name}' (turn {turn + 1})")
79
+
80
+ if "_error_invalid_json" in tool_input:
81
+ error_msg = tool_input["_error_invalid_json"]
82
+ raw_args = tool_input.get("raw_arguments", "")
83
+ result = f"Error: Invalid JSON arguments for tool '{tool_name}'. {error_msg}. Raw input was: {raw_args}. Please correct the JSON syntax and try again."
84
+ else:
85
+ fn = execute_tool_fn if execute_tool_fn else (lambda n, i, sid: __import__("tools").execute_tool(n, i, sid))
86
+ import inspect
87
+ sig = inspect.signature(fn)
88
+ if "session_id" in sig.parameters:
89
+ result = await fn(tool_name, tool_input, session_id=session_id)
90
+ else:
91
+ result = await fn(tool_name, tool_input)
92
+
93
+ messages.append({
94
+ "role": "tool",
95
+ "tool_call_id": tool_id,
96
+ "content": str(result),
97
+ })
98
+ continue
99
+
100
+ # Unknown stop reason — return what we have
101
+ break
102
+
103
+ # max_turns exceeded — annotate and return
104
+ logger.warning(f"[agent_loop] max_turns ({max_turns}) exceeded")
105
+ if last_anthropic_resp:
106
+ last_anthropic_resp["stop_reason"] = "end_turn"
107
+ return last_anthropic_resp
@@ -0,0 +1,18 @@
1
+ import argparse
2
+ import sys
3
+ import uvicorn
4
+
5
+ def main():
6
+ parser = argparse.ArgumentParser(description="litecoo - Free LLM proxy for Cowork")
7
+ parser.add_argument("--host", default="0.0.0.0", help="Host to bind (default: 0.0.0.0)")
8
+ parser.add_argument("--port", type=int, default=8000, help="Port to bind (default: 8000)")
9
+ parser.add_argument("--env-file", default=".env", help="Environment file to load")
10
+
11
+ args = parser.parse_args()
12
+
13
+ # We pass the import string instead of the object to enable hot-reloading if needed,
14
+ # and to ensure uvicorn runs correctly across platforms.
15
+ uvicorn.run("litecoo.main:app", host=args.host, port=args.port, env_file=args.env_file)
16
+
17
+ if __name__ == "__main__":
18
+ main()