pi-free 1.0.0
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.
- package/.github/workflows/update-benchmarks.yml +67 -0
- package/.pi/skills/pi-extension-dev/SKILL.md +155 -0
- package/CHANGELOG.md +59 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/config.ts +224 -0
- package/constants.ts +110 -0
- package/docs/free-tier-limits.md +213 -0
- package/docs/model-hopping.md +214 -0
- package/docs/plans/file-reorganization.md +172 -0
- package/docs/plans/package-json-fix.md +143 -0
- package/docs/provider-failover-plan.md +279 -0
- package/lib/json-persistence.ts +102 -0
- package/lib/logger.ts +94 -0
- package/lib/model-enhancer.ts +20 -0
- package/lib/types.ts +108 -0
- package/lib/util.ts +256 -0
- package/package.json +52 -0
- package/provider-factory.ts +221 -0
- package/provider-failover/errors.ts +275 -0
- package/provider-failover/hardcoded-benchmarks.ts +9889 -0
- package/provider-failover/index.ts +194 -0
- package/provider-helper.ts +336 -0
- package/providers/cline-auth.ts +473 -0
- package/providers/cline-models.ts +77 -0
- package/providers/cline.ts +257 -0
- package/providers/factory.ts +125 -0
- package/providers/fireworks.ts +49 -0
- package/providers/kilo-auth.ts +172 -0
- package/providers/kilo-models.ts +26 -0
- package/providers/kilo.ts +144 -0
- package/providers/mistral.ts +144 -0
- package/providers/model-fetcher.ts +138 -0
- package/providers/nvidia.ts +97 -0
- package/providers/ollama.ts +113 -0
- package/providers/openrouter.ts +175 -0
- package/providers/zen.ts +416 -0
- package/scripts/update-benchmarks.ts +255 -0
- package/tests/cline.test.ts +149 -0
- package/tests/errors.test.ts +139 -0
- package/tests/failover.test.ts +94 -0
- package/tests/fireworks.test.ts +148 -0
- package/tests/free-tier-limits.test.ts +191 -0
- package/tests/json-persistence.test.ts +105 -0
- package/tests/kilo.test.ts +186 -0
- package/tests/mistral.test.ts +138 -0
- package/tests/nvidia.test.ts +55 -0
- package/tests/ollama.test.ts +261 -0
- package/tests/openrouter.test.ts +192 -0
- package/tests/usage-tracking.test.ts +150 -0
- package/tests/util.test.ts +413 -0
- package/tests/zen.test.ts +180 -0
- package/todo.md +153 -0
- package/tsconfig.json +26 -0
- package/usage/commands.ts +17 -0
- package/usage/cumulative.ts +193 -0
- package/usage/formatters.ts +131 -0
- package/usage/index.ts +46 -0
- package/usage/limits.ts +166 -0
- package/usage/metrics.ts +222 -0
- package/usage/sessions.ts +355 -0
- package/usage/store.ts +99 -0
- package/usage/tracking.ts +329 -0
- package/usage/widget.ts +90 -0
- package/vitest.config.ts +20 -0
- package/widget/data.ts +113 -0
- package/widget/format.ts +26 -0
- package/widget/render.ts +117 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Update Benchmark Data
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Run monthly (1st of every month at 00:00 UTC)
|
|
6
|
+
- cron: '0 0 1 * *'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
# Allow manual trigger
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: write
|
|
12
|
+
pull-requests: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
update-benchmarks:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Setup Node.js
|
|
23
|
+
uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: '20'
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: npm ci
|
|
29
|
+
|
|
30
|
+
- name: Update benchmark data
|
|
31
|
+
env:
|
|
32
|
+
ARTIFICIAL_ANALYSIS_API_KEY: ${{ secrets.ARTIFICIAL_ANALYSIS_API_KEY }}
|
|
33
|
+
run: npx tsx scripts/update-benchmarks.ts
|
|
34
|
+
|
|
35
|
+
- name: Check for changes
|
|
36
|
+
id: check-changes
|
|
37
|
+
run: |
|
|
38
|
+
if git diff --quiet; then
|
|
39
|
+
echo "changed=false" >> $GITHUB_OUTPUT
|
|
40
|
+
else
|
|
41
|
+
echo "changed=true" >> $GITHUB_OUTPUT
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
- name: Create Pull Request
|
|
45
|
+
if: steps.check-changes.outputs.changed == 'true'
|
|
46
|
+
uses: peter-evans/create-pull-request@v6
|
|
47
|
+
with:
|
|
48
|
+
token: ${{ secrets.PAT_TOKEN }}
|
|
49
|
+
commit-message: 'chore: update benchmark data from Artificial Analysis'
|
|
50
|
+
title: 'chore: update benchmark data from Artificial Analysis'
|
|
51
|
+
body: |
|
|
52
|
+
## Automated Benchmark Update
|
|
53
|
+
|
|
54
|
+
This PR updates the hardcoded benchmark data with fresh scores from [Artificial Analysis](https://artificialanalysis.ai).
|
|
55
|
+
|
|
56
|
+
### Changes
|
|
57
|
+
- Updated `provider-failover/hardcoded-benchmarks.ts`
|
|
58
|
+
- New data as of ${{ github.event.repository.updated_at }}
|
|
59
|
+
|
|
60
|
+
### Verification
|
|
61
|
+
- [ ] Review score changes for major models
|
|
62
|
+
- [ ] Run tests: `npm run test:run`
|
|
63
|
+
- [ ] Check no unexpected tier downgrades
|
|
64
|
+
|
|
65
|
+
Auto-generated by GitHub Actions.
|
|
66
|
+
branch: update-benchmarks-${{ github.run_number }}
|
|
67
|
+
delete-branch: true
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-extension-dev
|
|
3
|
+
description: Guide for developing Pi coding agent extensions. Use when creating or debugging extensions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pi Extension Development
|
|
7
|
+
|
|
8
|
+
## Documentation Locations
|
|
9
|
+
|
|
10
|
+
| Resource | Path |
|
|
11
|
+
|----------|------|
|
|
12
|
+
| Extension API | `~/.pi/agent/docs/extensions.md` |
|
|
13
|
+
| Examples | `~/.pi/agent/examples/extensions/*.ts` |
|
|
14
|
+
| Type Definitions | `~/.pi/agent/node_modules/@mariozechner/pi-coding-agent/dist/core/extensions/types.d.ts` |
|
|
15
|
+
| Logs | `~/.pi/agent/logs/` |
|
|
16
|
+
| Global Extensions | `~/.pi/agent/extensions/*.ts` |
|
|
17
|
+
| Project Extensions | `.pi/extensions/*.ts` |
|
|
18
|
+
|
|
19
|
+
## Extension Structure
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// Single file: ~/.pi/agent/extensions/my-ext.ts
|
|
23
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
24
|
+
|
|
25
|
+
export default function (pi: ExtensionAPI) {
|
|
26
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
27
|
+
ctx.ui.notify("Loaded!", "info");
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Key Events
|
|
33
|
+
|
|
34
|
+
| Event | When | Use For |
|
|
35
|
+
|-------|------|---------|
|
|
36
|
+
| `session_start` | Session loads | Register providers, init state |
|
|
37
|
+
| `turn_end` | Turn completes | **Error detection** (check `event.message.errorMessage`) |
|
|
38
|
+
| `model_select` | Model changes | Clear provider status |
|
|
39
|
+
| `before_agent_start` | Before LLM call | Inject messages |
|
|
40
|
+
| `tool_call` | Tool invoked | Block/modify tools |
|
|
41
|
+
|
|
42
|
+
## Context (ctx) Methods
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// UI
|
|
46
|
+
ctx.ui.notify("msg", "info"|"warning"|"error"|"success")
|
|
47
|
+
ctx.ui.setStatus("id", "text" | undefined)
|
|
48
|
+
ctx.ui.confirm(title, message) → Promise<boolean>
|
|
49
|
+
ctx.ui.input(title, placeholder?) → Promise<string>
|
|
50
|
+
|
|
51
|
+
// Registry
|
|
52
|
+
ctx.modelRegistry.registerProvider(id, config)
|
|
53
|
+
ctx.modelRegistry.getAvailable()
|
|
54
|
+
|
|
55
|
+
// Storage
|
|
56
|
+
ctx.sessionStorage.setItem(key, value)
|
|
57
|
+
ctx.sessionStorage.getItem(key)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Register Provider
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
pi.registerProvider("id", {
|
|
64
|
+
baseUrl: "https://api.example.com/v1",
|
|
65
|
+
apiKey: "ENV_VAR_NAME",
|
|
66
|
+
api: "openai-completions", // or "anthropic-messages"
|
|
67
|
+
headers: {},
|
|
68
|
+
models: [{
|
|
69
|
+
id: "model-id",
|
|
70
|
+
name: "Display Name",
|
|
71
|
+
reasoning: false,
|
|
72
|
+
input: ["text"], // or ["text", "image"]
|
|
73
|
+
cost: { input: 0.5, output: 1.5 },
|
|
74
|
+
contextWindow: 128000,
|
|
75
|
+
maxTokens: 4096,
|
|
76
|
+
}]
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Error Detection (Important!)
|
|
81
|
+
|
|
82
|
+
Pi has **no error event**. Detect errors in `turn_end`:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
pi.on("turn_end", async (event, ctx) => {
|
|
86
|
+
const msg = event.message as { role?: string; errorMessage?: string };
|
|
87
|
+
|
|
88
|
+
if (msg?.role === "assistant" && msg.errorMessage) {
|
|
89
|
+
const error = msg.errorMessage;
|
|
90
|
+
|
|
91
|
+
// Classify
|
|
92
|
+
if (error.includes("429") || /rate.?limit/i.test(error)) {
|
|
93
|
+
ctx.ui.notify("Rate limited! Try /model to switch.", "warning");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Error Patterns
|
|
100
|
+
|
|
101
|
+
| Type | Patterns |
|
|
102
|
+
|------|----------|
|
|
103
|
+
| Rate Limit | `429`, `rate limit`, `quota exceeded`, `throttled` |
|
|
104
|
+
| Capacity | `no capacity`, `overloaded`, `503`, `temporarily unavailable` |
|
|
105
|
+
| Auth | `401`, `403`, `unauthorized`, `invalid key` |
|
|
106
|
+
|
|
107
|
+
## Register Commands
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
pi.registerCommand("my-cmd", {
|
|
111
|
+
description: "What it does",
|
|
112
|
+
handler: async (args, ctx) => {
|
|
113
|
+
ctx.ui.notify(`Args: ${args}`, "info");
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Register Tools
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { Type } from "@sinclair/typebox";
|
|
122
|
+
|
|
123
|
+
pi.registerTool({
|
|
124
|
+
name: "my_tool",
|
|
125
|
+
label: "My Tool",
|
|
126
|
+
description: "What it does",
|
|
127
|
+
parameters: Type.Object({
|
|
128
|
+
param: Type.String({ description: "Param desc" })
|
|
129
|
+
}),
|
|
130
|
+
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
131
|
+
return {
|
|
132
|
+
content: [{ type: "text", text: "Result" }],
|
|
133
|
+
details: {}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Best Practices
|
|
140
|
+
|
|
141
|
+
- Import as type: `import type { ExtensionAPI }`
|
|
142
|
+
- Export default function
|
|
143
|
+
- Use `.ts` extensions for imports
|
|
144
|
+
- Errors in `turn_end` (no error event exists)
|
|
145
|
+
- Clear status in `model_select` when switching away
|
|
146
|
+
- API keys in env vars, never hardcoded
|
|
147
|
+
- Test with `pi -e ./ext.ts`, install to `~/.pi/agent/extensions/`
|
|
148
|
+
- Hot reload with `/reload` after changes
|
|
149
|
+
|
|
150
|
+
## Debugging
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
console.log("[ext] Debug:", data); // Check ~/.pi/agent/logs/
|
|
154
|
+
ctx.ui.notify("Extension loaded!", "info");
|
|
155
|
+
```
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Structured logging with namespaced logger (lib/logger.ts)
|
|
12
|
+
- LICENSE file (MIT)
|
|
13
|
+
- CHANGELOG.md
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- **Major refactoring**: Split free-tier-limits.ts into usage/* modules
|
|
17
|
+
- usage/tracking.ts - runtime session tracking
|
|
18
|
+
- usage/cumulative.ts - persistent storage
|
|
19
|
+
- usage/formatters.ts - display formatting
|
|
20
|
+
- 77% line reduction (741 → 166 lines)
|
|
21
|
+
- **Major refactoring**: Split usage-widget.ts into widget/* modules
|
|
22
|
+
- widget/data.ts - data collection
|
|
23
|
+
- widget/format.ts - formatting utilities
|
|
24
|
+
- widget/render.ts - HTML generation
|
|
25
|
+
- 74% line reduction (~350 → 90 lines)
|
|
26
|
+
- **Refactoring**: Extracted functions from cline-auth.ts
|
|
27
|
+
- fetchAuthorizeUrl() - auth URL fetching
|
|
28
|
+
- waitForAuthCode() - callback handling
|
|
29
|
+
- exchangeCodeForTokens() - token exchange
|
|
30
|
+
- parseManualInput() - manual input parsing
|
|
31
|
+
- **Refactoring**: Simplified model-hop.ts complexity
|
|
32
|
+
- Extracted handleDowngradeDecision()
|
|
33
|
+
- Extracted tryAlternativeModel()
|
|
34
|
+
- **Deduplication**: Created shared modules
|
|
35
|
+
- lib/json-persistence.ts - file I/O with caching
|
|
36
|
+
- lib/logger.ts - structured logging
|
|
37
|
+
- providers/model-fetcher.ts - OpenRouter-compatible fetching
|
|
38
|
+
- Replaced ~30 console.log statements with structured logging
|
|
39
|
+
- Fixed all 9 pre-existing test failures
|
|
40
|
+
- fetchWithRetry now throws after last retry
|
|
41
|
+
- Fixed auth pattern matching (added key.*not.*valid)
|
|
42
|
+
- Updated capability ranking tests
|
|
43
|
+
- Added resetUsageStats() for test isolation
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
- fetchWithRetry() now properly throws after exhausting retries
|
|
47
|
+
- Auth error pattern matching now handles more message variants
|
|
48
|
+
- Test isolation for free-tier-limits tests
|
|
49
|
+
|
|
50
|
+
## [1.0.0] - 2024-03-28
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- Initial release with 6 providers: Kilo, Zen, OpenRouter, NVIDIA, Cline, Fireworks
|
|
54
|
+
- Free tier usage tracking across all sessions
|
|
55
|
+
- Provider failover with model hopping
|
|
56
|
+
- Autocompact integration for rate limit recovery
|
|
57
|
+
- Usage widget with glimpseui
|
|
58
|
+
- Command toggles for free/all model filtering
|
|
59
|
+
- Hardcoded benchmark data from Artificial Analysis
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 pi-free-providers contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# pi-free-providers
|
|
2
|
+
|
|
3
|
+
Free AI model providers for [Pi](https://pi.dev). Access **free models** from multiple providers in one install.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What does pi-free do
|
|
8
|
+
|
|
9
|
+
**pi-free is a Pi extension that unlocks free AI models from 8 different providers.**
|
|
10
|
+
|
|
11
|
+
When you install pi-free, it:
|
|
12
|
+
|
|
13
|
+
1. **Registers 7 AI providers** with Pi's model picker — OpenCode Zen, Kilo, OpenRouter, NVIDIA NIM, Cline, Mistral, and Ollama Cloud
|
|
14
|
+
|
|
15
|
+
2. **Filters to show only free models by default** — You see only the models that cost $0 to use, no API key required for some providers
|
|
16
|
+
|
|
17
|
+
3. **Provides a toggle command** — Run `/{provider}-toggle` (e.g., `/zen-toggle`, `/kilo-toggle`) to switch between free-only mode and showing all models including paid ones
|
|
18
|
+
|
|
19
|
+
4. **Handles authentication for you** — OAuth flows (Kilo, Cline) open your browser automatically; API keys are read from `~/.pi/free.json` or environment variables
|
|
20
|
+
|
|
21
|
+
5. **Adds Coding Index scores** — Model names include a coding benchmark score (CI: 45.2) to help you pick capable coding models at a glance
|
|
22
|
+
|
|
23
|
+
6. **Persists your preferences** — Your toggle choices (free vs all models) are saved to `~/.pi/free.json` and remembered across Pi restarts
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## How to use
|
|
28
|
+
|
|
29
|
+
### 1. Install the extension
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pi install git:github.com/apmantza/pi-free
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Open the model picker
|
|
36
|
+
|
|
37
|
+
Start Pi and press `Ctrl+L` to open the model picker.
|
|
38
|
+
|
|
39
|
+
Free models are shown by default — look for the provider prefixes:
|
|
40
|
+
- `zen/` — OpenCode Zen models (no setup required)
|
|
41
|
+
- `kilo/` — Kilo models (free models available immediately, more after `/login kilo`)
|
|
42
|
+
- `openrouter/` — OpenRouter models (free account required)
|
|
43
|
+
- `nvidia/` — NVIDIA NIM models (free API key required)
|
|
44
|
+
- `cline/` — Cline models (run `/login cline` to use)
|
|
45
|
+
- `mistral/` — Mistral models (API key required)
|
|
46
|
+
- `ollama/` — Ollama Cloud models (API key required)
|
|
47
|
+
|
|
48
|
+
### 3. Toggle between free and paid models
|
|
49
|
+
|
|
50
|
+
Want to see paid models too? Run the toggle command for your provider:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
/zen-toggle # Toggle Zen free/paid models
|
|
54
|
+
/kilo-toggle # Toggle Kilo free/paid models
|
|
55
|
+
/openrouter-toggle # Toggle OpenRouter free/paid models
|
|
56
|
+
/nvidia-toggle # Toggle NVIDIA zero-cost/credit-costing models
|
|
57
|
+
/cline-toggle # Toggle Cline free/paid models
|
|
58
|
+
/mistral-toggle # Toggle Mistral free/paid models
|
|
59
|
+
/ollama-toggle # Toggle Ollama models (requires SHOW_PAID=true)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You'll see a notification like: `zen: showing free models` or `zen: showing all models (including paid)`
|
|
63
|
+
|
|
64
|
+
### 4. Add API keys for more providers (optional)
|
|
65
|
+
|
|
66
|
+
Some providers require a free account or API key.
|
|
67
|
+
|
|
68
|
+
**The first time you run Pi after installing this extension, a config file is automatically created:**
|
|
69
|
+
- **Linux/Mac:** `~/.pi/free.json`
|
|
70
|
+
- **Windows:** `%USERPROFILE%\.pi\free.json`
|
|
71
|
+
|
|
72
|
+
Add your API keys to this file:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"openrouter_api_key": "sk-or-v1-...",
|
|
77
|
+
"nvidia_api_key": "nvapi-...",
|
|
78
|
+
"ollama_api_key": "...",
|
|
79
|
+
"fireworks_api_key": "...",
|
|
80
|
+
"mistral_api_key": "..."
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or set environment variables instead (same names, uppercase: `OPENROUTER_API_KEY`, `NVIDIA_API_KEY`, etc.)
|
|
85
|
+
|
|
86
|
+
See the [Providers That Need Authentication](#providers-that-need-authentication) section below for detailed setup instructions per provider.
|
|
87
|
+
|
|
88
|
+
### 5. Quick commands reference
|
|
89
|
+
|
|
90
|
+
| Command | What it does |
|
|
91
|
+
|---------|-------------|
|
|
92
|
+
| `/{provider}-toggle` | Switch between free-only and all models for that provider |
|
|
93
|
+
| `/login kilo` | Start OAuth flow for Kilo |
|
|
94
|
+
| `/login cline` | Start OAuth flow for Cline |
|
|
95
|
+
| `/logout kilo` | Clear Kilo OAuth credentials |
|
|
96
|
+
| `/logout cline` | Clear Cline OAuth credentials |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Using Free Models (No Setup Required)
|
|
101
|
+
|
|
102
|
+
### OpenCode Zen — Easiest Start
|
|
103
|
+
|
|
104
|
+
Works immediately with zero setup:
|
|
105
|
+
|
|
106
|
+
1. Press `Ctrl+L`
|
|
107
|
+
2. Search for `zen/`
|
|
108
|
+
3. Pick any model (e.g., `zen/mimo-v2-omni-free`)
|
|
109
|
+
4. Start chatting
|
|
110
|
+
|
|
111
|
+
No account, no API key, no OAuth.
|
|
112
|
+
|
|
113
|
+
### Ollama Cloud
|
|
114
|
+
|
|
115
|
+
Get an API key from [ollama.com/settings/keys](https://ollama.com/settings/keys), then:
|
|
116
|
+
|
|
117
|
+
**Option A: Environment variable**
|
|
118
|
+
```bash
|
|
119
|
+
export OLLAMA_API_KEY="..."
|
|
120
|
+
export OLLAMA_SHOW_PAID=true
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Option B: Config file** (`~/.pi/free.json`)
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"ollama_api_key": "YOUR_KEY",
|
|
127
|
+
"ollama_show_paid": true
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Note:** Ollama requires `OLLAMA_SHOW_PAID=true` because they have usage limits on their cloud API.
|
|
132
|
+
|
|
133
|
+
Free tier resets every 5 hours + 7 days.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Providers That Need Authentication
|
|
138
|
+
|
|
139
|
+
Some providers require free accounts or OAuth to access their free tiers:
|
|
140
|
+
|
|
141
|
+
### Kilo (free models, more after login)
|
|
142
|
+
|
|
143
|
+
Kilo shows free models immediately. To unlock all models, authenticate with Kilo's free OAuth:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
/login kilo
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
This command will:
|
|
150
|
+
1. Open your browser to Kilo's authorization page
|
|
151
|
+
2. Show a device code in Pi's UI
|
|
152
|
+
3. Wait for you to authorize in the browser
|
|
153
|
+
4. Automatically complete login once approved
|
|
154
|
+
|
|
155
|
+
- No credit card required
|
|
156
|
+
- Free tier: 200 requests/hour
|
|
157
|
+
- After login, run `/kilo-toggle` to switch between free-only and all models
|
|
158
|
+
|
|
159
|
+
### OpenRouter (free models available)
|
|
160
|
+
|
|
161
|
+
Get a free API key at [openrouter.ai/keys](https://openrouter.ai/keys), then either:
|
|
162
|
+
|
|
163
|
+
**Option A: Environment variable**
|
|
164
|
+
```bash
|
|
165
|
+
export OPENROUTER_API_KEY="sk-or-v1-..."
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Option B: Config file** (`~/.pi/free.json`)
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"openrouter_api_key": "sk-or-v1-..."
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Then in Pi:
|
|
176
|
+
```
|
|
177
|
+
/openrouter-all # Show all models (free + paid)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### NVIDIA NIM (Free Credits System)
|
|
181
|
+
|
|
182
|
+
NVIDIA provides **free monthly credits** (1000 requests/month) at [build.nvidia.com](https://build.nvidia.com).
|
|
183
|
+
|
|
184
|
+
**Important:** Models have different "costs" per token:
|
|
185
|
+
- **Zero-cost models**: Don't consume your credit balance (shown by default)
|
|
186
|
+
- **Credit-costing models**: Consume credits faster (hidden by default)
|
|
187
|
+
|
|
188
|
+
Get your API key and optionally enable all models:
|
|
189
|
+
|
|
190
|
+
**Option A: Show only free models (default)**
|
|
191
|
+
```bash
|
|
192
|
+
export NVIDIA_API_KEY="nvapi-..."
|
|
193
|
+
```
|
|
194
|
+
Uses only zero-cost models → your 1000 credits last the full month
|
|
195
|
+
|
|
196
|
+
**Option B: Show all models (uses credits faster)**
|
|
197
|
+
```bash
|
|
198
|
+
export NVIDIA_API_KEY="nvapi-..."
|
|
199
|
+
export NVIDIA_SHOW_PAID=true
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Or in `~/.pi/free.json`:
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"nvidia_api_key": "nvapi-...",
|
|
206
|
+
"nvidia_show_paid": true
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Toggle anytime with `/nvidia-toggle`
|
|
211
|
+
|
|
212
|
+
### Cline
|
|
213
|
+
|
|
214
|
+
Cline models appear immediately in the model picker. To use them, authenticate with Cline's free account:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
/login cline
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
This command will:
|
|
221
|
+
1. Open your browser to Cline's sign-in page
|
|
222
|
+
2. Wait for you to complete sign-in
|
|
223
|
+
3. Automatically complete login once approved
|
|
224
|
+
|
|
225
|
+
- Free account required (no credit card)
|
|
226
|
+
- Uses local ports 48801-48811 for OAuth callback
|
|
227
|
+
|
|
228
|
+
### Mistral
|
|
229
|
+
|
|
230
|
+
Add API key to `~/.pi/free.json` or environment variables:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
export MISTRAL_API_KEY="..."
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Slash Commands
|
|
239
|
+
|
|
240
|
+
Each provider has toggle commands to switch between free and all models:
|
|
241
|
+
|
|
242
|
+
| Command | Action |
|
|
243
|
+
|---------|--------|
|
|
244
|
+
| `/zen-toggle` | Toggle between free/all Zen models |
|
|
245
|
+
| `/kilo-toggle` | Toggle between free/all Kilo models |
|
|
246
|
+
| `/openrouter-toggle` | Toggle between free/all OpenRouter models |
|
|
247
|
+
| `/nvidia-toggle` | Toggle between free/all NVIDIA models |
|
|
248
|
+
| `/cline-toggle` | Toggle between free/all Cline models |
|
|
249
|
+
| `/mistral-toggle` | Toggle between free/all Mistral models |
|
|
250
|
+
| `/ollama-toggle` | Toggle between free/all Ollama models |
|
|
251
|
+
|
|
252
|
+
**The toggle command:**
|
|
253
|
+
- Switches between showing only free models vs. all available models
|
|
254
|
+
- **Persists your preference** to `~/.pi/free.json` for next startup
|
|
255
|
+
- Shows a notification: "zen: showing free models" or "zen: showing all models (including paid)"
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Configuration
|
|
260
|
+
|
|
261
|
+
Create `~/.pi/free.json` in your home directory:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"openrouter_api_key": "YOUR_OPENROUTER_KEY",
|
|
266
|
+
"nvidia_api_key": "YOUR_NVIDIA_KEY",
|
|
267
|
+
"fireworks_api_key": "YOUR_FIREWORKS_KEY",
|
|
268
|
+
"mistral_api_key": "YOUR_MISTRAL_KEY",
|
|
269
|
+
"opencode_api_key": "YOUR_ZEN_KEY",
|
|
270
|
+
"ollama_api_key": "YOUR_OLLAMA_KEY",
|
|
271
|
+
"ollama_show_paid": true,
|
|
272
|
+
"hidden_models": ["model-id-to-hide"]
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Or use environment variables (same names, uppercase):
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
export OPENROUTER_API_KEY="..."
|
|
280
|
+
export NVIDIA_API_KEY="..."
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## License
|
|
286
|
+
|
|
287
|
+
MIT — See [LICENSE](LICENSE)
|
|
288
|
+
|
|
289
|
+
**Questions?** [Open an issue](https://github.com/apmantza/pi-free/issues)
|