@psnext/slingcli 3.0.20260810-3 → 3.0.20260811-2
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/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js +4 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/testing/conformance.js +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +12 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/deepseek.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -3
- package/node_modules/@earendil-works/pi-coding-agent/docs/compaction.md +9 -9
- package/node_modules/@earendil-works/pi-coding-agent/docs/containerization.md +8 -8
- package/node_modules/@earendil-works/pi-coding-agent/docs/custom-provider.md +20 -12
- package/node_modules/@earendil-works/pi-coding-agent/docs/development.md +71 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/docs.json +14 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/environment-variables.md +9 -9
- package/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md +53 -26
- package/node_modules/@earendil-works/pi-coding-agent/docs/index.md +10 -9
- package/node_modules/@earendil-works/pi-coding-agent/docs/json.md +21 -16
- package/node_modules/@earendil-works/pi-coding-agent/docs/keybindings.md +46 -14
- package/node_modules/@earendil-works/pi-coding-agent/docs/llama-cpp.md +3 -3
- package/node_modules/@earendil-works/pi-coding-agent/docs/mcp.md +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/models.md +25 -4
- package/node_modules/@earendil-works/pi-coding-agent/docs/packages.md +13 -13
- package/node_modules/@earendil-works/pi-coding-agent/docs/prompt-templates.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/providers.md +317 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/quickstart.md +11 -9
- package/node_modules/@earendil-works/pi-coding-agent/docs/rpc.md +15 -13
- package/node_modules/@earendil-works/pi-coding-agent/docs/sdk.md +33 -14
- package/node_modules/@earendil-works/pi-coding-agent/docs/security.md +5 -5
- package/node_modules/@earendil-works/pi-coding-agent/docs/session-format.md +3 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/sessions.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +6 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/shell-aliases.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/skills.md +5 -5
- package/node_modules/@earendil-works/pi-coding-agent/docs/terminal-setup.md +3 -3
- package/node_modules/@earendil-works/pi-coding-agent/docs/termux.md +5 -5
- package/node_modules/@earendil-works/pi-coding-agent/docs/themes.md +7 -5
- package/node_modules/@earendil-works/pi-coding-agent/docs/tmux.md +3 -3
- package/node_modules/@earendil-works/pi-coding-agent/docs/usage.md +17 -10
- package/node_modules/@earendil-works/pi-coding-agent/docs/windows.md +1 -1
- package/package.json +2 -2
- package/slingshot/index.js +9 -7
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
> sling can help you create sling packages. Ask it to bundle your extensions, skills, prompt templates, or themes.
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# sling Packages
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Pi packages bundle extensions, skills, prompt templates, and themes so you can share them through npm or git. A package can declare resources in `package.json` under the `pi` key, or use conventional directories.
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
9
|
- [Install and Manage](#install-and-manage)
|
|
10
10
|
- [Package Sources](#package-sources)
|
|
11
|
-
- [Creating a sling Package](#creating-a-
|
|
11
|
+
- [Creating a sling Package](#creating-a-pi-package)
|
|
12
12
|
- [Package Structure](#package-structure)
|
|
13
13
|
- [Dependencies](#dependencies)
|
|
14
14
|
- [Package Filtering](#package-filtering)
|
|
@@ -38,7 +38,7 @@ sling update npm:@foo/bar # update one package
|
|
|
38
38
|
sling update --extension npm:@foo/bar
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
These commands manage sling packages and `sling
|
|
41
|
+
These commands manage sling packages and `sling` can update the sling CLI installation. To uninstall sling itself, see [Quickstart](quickstart.md#uninstall).
|
|
42
42
|
|
|
43
43
|
By default, `install` and `remove` write to user settings (`~/.sling/agent/settings.json`). Use `-l` to write to project settings (`.sling/settings.json`) instead. Project settings can be shared with your team, and sling installs any missing packages automatically on startup after the project is trusted.
|
|
44
44
|
|
|
@@ -60,7 +60,7 @@ npm:@scope/pkg@1.2.3
|
|
|
60
60
|
npm:pkg
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
- Versioned specs are pinned and skipped by package updates (`sling update --extensions`, `sling
|
|
63
|
+
- Versioned specs are pinned and skipped by package updates (`sling update --extensions`, `sling`).
|
|
64
64
|
- User installs go under `~/.sling/agent/npm/`.
|
|
65
65
|
- Project installs go under `.sling/npm/`.
|
|
66
66
|
- Set `npmCommand` in `settings.json` to pin npm package lookup and install operations to a specific wrapper command such as `mise` or `asdf`.
|
|
@@ -87,7 +87,7 @@ ssh://git@github.com/user/repo@v1
|
|
|
87
87
|
- HTTPS and SSH URLs are both supported.
|
|
88
88
|
- SSH URLs use your configured SSH keys automatically (respects `~/.ssh/config`).
|
|
89
89
|
- For non-interactive runs (for example CI), you can set `GIT_TERMINAL_PROMPT=0` to disable credential prompts and set `GIT_SSH_COMMAND` (for example `ssh -o BatchMode=yes -o ConnectTimeout=5`) to fail fast.
|
|
90
|
-
- Refs are pinned tags or commits. `sling update --extensions` and `sling
|
|
90
|
+
- Refs are pinned tags or commits. `sling update --extensions` and `sling` do not move them to newer refs, but they do reconcile an existing clone to the configured ref.
|
|
91
91
|
- Use `sling install git:host/user/repo@new-ref` to update settings and move an existing package to a new pinned ref.
|
|
92
92
|
- Cloned to `~/.sling/agent/git/<host>/<path>` (global) or `.sling/git/<host>/<path>` (project).
|
|
93
93
|
- When reconciliation changes the checkout, sling resets and cleans the clone, then runs `npm install` if `package.json` exists.
|
|
@@ -95,13 +95,13 @@ ssh://git@github.com/user/repo@v1
|
|
|
95
95
|
**SSH examples:**
|
|
96
96
|
```bash
|
|
97
97
|
# git@host:path shorthand (requires git: prefix)
|
|
98
|
-
|
|
98
|
+
pi install git:git@github.com:user/repo
|
|
99
99
|
|
|
100
100
|
# ssh:// protocol format
|
|
101
|
-
|
|
101
|
+
pi install ssh://git@github.com/user/repo
|
|
102
102
|
|
|
103
103
|
# With version ref
|
|
104
|
-
|
|
104
|
+
pi install git:git@github.com:user/repo@v1.0.0
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
### Local Paths
|
|
@@ -111,11 +111,11 @@ sling install git:git@github.com:user/repo@v1.0.0
|
|
|
111
111
|
./relative/path/to/package
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
Local paths point to files or directories on disk and are added to settings without copying. Relative paths are resolved against the settings file they appear in. If the path is a file, it loads as a single extension. If it is a directory,
|
|
114
|
+
Local paths point to files or directories on disk and are added to settings without copying. Relative paths are resolved against the settings file they appear in. If the path is a file, it loads as a single extension. If it is a directory, pi loads resources using package rules.
|
|
115
115
|
|
|
116
|
-
## Creating a
|
|
116
|
+
## Creating a Pi Package
|
|
117
117
|
|
|
118
|
-
Add a `
|
|
118
|
+
Add a `pi` manifest to `package.json` or use conventional directories. Include the `pi-package` keyword for discoverability.
|
|
119
119
|
|
|
120
120
|
```json
|
|
121
121
|
{
|
|
@@ -157,7 +157,7 @@ If both are set, video takes precedence.
|
|
|
157
157
|
|
|
158
158
|
### Convention Directories
|
|
159
159
|
|
|
160
|
-
If no `pi` manifest is present,
|
|
160
|
+
If no `pi` manifest is present, sling auto-discovers resources from these directories:
|
|
161
161
|
|
|
162
162
|
- `extensions/` loads `.ts` and `.js` files
|
|
163
163
|
- `skills/` recursively finds `SKILL.md` folders and loads top-level `.md` files as skills
|
|
@@ -6,7 +6,7 @@ Prompt templates are Markdown snippets that expand into full prompts. Type `/nam
|
|
|
6
6
|
|
|
7
7
|
## Locations
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Pi loads prompt templates from:
|
|
10
10
|
|
|
11
11
|
- Global: `~/.sling/agent/prompts/*.md`
|
|
12
12
|
- Project: `.sling/prompts/*.md` (only after the project is trusted)
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Providers
|
|
2
|
+
|
|
3
|
+
sling supports subscription-based providers via OAuth and API key providers via environment variables or auth file. Built-in catalogs ship with sling; configured providers may refresh newer catalogs and cache them in `~/.sling/agent/models-store.json` for offline use.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Subscriptions](#subscriptions)
|
|
8
|
+
- [API Keys](#api-keys)
|
|
9
|
+
- [Auth File](#auth-file)
|
|
10
|
+
- [Cloud Providers](#cloud-providers)
|
|
11
|
+
- [llama.cpp](#llamacpp)
|
|
12
|
+
- [Custom Providers](#custom-providers)
|
|
13
|
+
- [Resolution Order](#resolution-order)
|
|
14
|
+
|
|
15
|
+
## Subscriptions
|
|
16
|
+
|
|
17
|
+
Use `/login` in interactive mode, then select a provider:
|
|
18
|
+
|
|
19
|
+
- ChatGPT Plus/Pro (Codex)
|
|
20
|
+
- Claude Pro/Max
|
|
21
|
+
- GitHub Copilot
|
|
22
|
+
- xAI (Grok/X subscription)
|
|
23
|
+
- OpenRouter (OAuth-minted API key billed from OpenRouter credits)
|
|
24
|
+
- Radius
|
|
25
|
+
|
|
26
|
+
Use `/logout` to clear credentials. Tokens are stored in `~/.sling/agent/auth.json` and auto-refresh when expired. OpenRouter instead mints a user-controlled API key that does not expire automatically.
|
|
27
|
+
|
|
28
|
+
### OpenAI Codex
|
|
29
|
+
|
|
30
|
+
- Requires ChatGPT Plus or Pro subscription
|
|
31
|
+
- Officially endorsed by OpenAI: [Codex for OSS](https://developers.openai.com/community/codex-for-oss)
|
|
32
|
+
|
|
33
|
+
### Claude Pro/Max
|
|
34
|
+
|
|
35
|
+
Anthropic subscription auth is active for Claude Pro/Max accounts. Third-party harness usage draws from [extra usage](https://claude.ai/settings/usage) and is billed per token, not against Claude plan limits.
|
|
36
|
+
|
|
37
|
+
### GitHub Copilot
|
|
38
|
+
|
|
39
|
+
- Press Enter for github.com, or enter your GitHub Enterprise Server domain
|
|
40
|
+
- If you get "model not supported", enable it in VS Code: Copilot Chat → model selector → select model → "Enable"
|
|
41
|
+
|
|
42
|
+
### xAI (Grok/X subscription)
|
|
43
|
+
|
|
44
|
+
- Run `/login xai`, then select **Use a subscription**
|
|
45
|
+
- `XAI_API_KEY` remains available through **Use an API key**
|
|
46
|
+
|
|
47
|
+
### OpenRouter
|
|
48
|
+
|
|
49
|
+
- Run `/login openrouter`, then select **Sign in with OpenRouter** to open the OpenRouter PKCE authorization flow
|
|
50
|
+
- The authorization creates a user-controlled OpenRouter API key billed from your OpenRouter credits
|
|
51
|
+
- On remote/headless machines (e.g. over SSH) the browser cannot reach the loopback callback; paste the final redirect URL (or the authorization code) into the login prompt instead
|
|
52
|
+
- `OPENROUTER_API_KEY` remains available through **Use an API key**
|
|
53
|
+
|
|
54
|
+
### Radius
|
|
55
|
+
|
|
56
|
+
Radius is a dynamic `pi-messages` gateway. `/login radius` stores OAuth tokens in `auth.json`; the gateway catalog is refreshed independently and cached in `models-store.json`. Custom Radius gateways can be declared in `models.json` with `"oauth": "radius"` and a gateway `baseUrl`.
|
|
57
|
+
|
|
58
|
+
## API Keys
|
|
59
|
+
|
|
60
|
+
### Environment Variables or Auth File
|
|
61
|
+
|
|
62
|
+
Use `/login` in interactive mode and select a provider to store an API key in `auth.json`, or set credentials via environment variable:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
66
|
+
pi
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Provider | Environment Variable | `auth.json` key |
|
|
70
|
+
|----------|----------------------|------------------|
|
|
71
|
+
| Anthropic | `ANTHROPIC_API_KEY` | `anthropic` |
|
|
72
|
+
| Ant Ling | `ANT_LING_API_KEY` | `ant-ling` |
|
|
73
|
+
| Azure OpenAI Responses | `AZURE_OPENAI_API_KEY` | `azure-openai-responses` |
|
|
74
|
+
| OpenAI | `OPENAI_API_KEY` | `openai` |
|
|
75
|
+
| DeepSeek | `DEEPSEEK_API_KEY` | `deepseek` |
|
|
76
|
+
| NVIDIA NIM | `NVIDIA_API_KEY` | `nvidia` |
|
|
77
|
+
| Google Gemini | `GEMINI_API_KEY` | `google` |
|
|
78
|
+
| Amazon Bedrock | `AWS_BEARER_TOKEN_BEDROCK` | `amazon-bedrock` |
|
|
79
|
+
| Mistral | `MISTRAL_API_KEY` | `mistral` |
|
|
80
|
+
| Groq | `GROQ_API_KEY` | `groq` |
|
|
81
|
+
| Cerebras | `CEREBRAS_API_KEY` | `cerebras` |
|
|
82
|
+
| Cloudflare AI Gateway | `CLOUDFLARE_API_KEY` (+ `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_GATEWAY_ID`) | `cloudflare-ai-gateway` |
|
|
83
|
+
| Cloudflare Workers AI | `CLOUDFLARE_API_KEY` (+ `CLOUDFLARE_ACCOUNT_ID`) | `cloudflare-workers-ai` |
|
|
84
|
+
| xAI | `XAI_API_KEY` | `xai` |
|
|
85
|
+
| OpenRouter | `OPENROUTER_API_KEY` | `openrouter` |
|
|
86
|
+
| Vercel AI Gateway | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway` |
|
|
87
|
+
| ZAI Coding Plan (Global) | `ZAI_API_KEY` | `zai` |
|
|
88
|
+
| ZAI Coding Plan (China) | `ZAI_CODING_CN_API_KEY` | `zai-coding-cn` |
|
|
89
|
+
| OpenCode Zen | `OPENCODE_API_KEY` | `opencode` |
|
|
90
|
+
| OpenCode Go | `OPENCODE_API_KEY` | `opencode-go` |
|
|
91
|
+
| Radius | `RADIUS_API_KEY` | `radius` |
|
|
92
|
+
| Hugging Face | `HF_TOKEN` | `huggingface` |
|
|
93
|
+
| Fireworks | `FIREWORKS_API_KEY` | `fireworks` |
|
|
94
|
+
| Together AI | `TOGETHER_API_KEY` | `together` |
|
|
95
|
+
| Baseten | `BASETEN_API_KEY` | `baseten` |
|
|
96
|
+
| Kimi For Coding | `KIMI_API_KEY` | `kimi-coding` |
|
|
97
|
+
| MiniMax | `MINIMAX_API_KEY` | `minimax` |
|
|
98
|
+
| MiniMax (China) | `MINIMAX_CN_API_KEY` | `minimax-cn` |
|
|
99
|
+
| Qwen Token Plan (existing catalog) | `QWEN_TOKEN_PLAN_API_KEY` | `qwen-token-plan` |
|
|
100
|
+
| Qwen Token Plan (Individual) | `QWEN_TOKEN_PLAN_API_KEY` | `qwen-token-plan-individual` |
|
|
101
|
+
| Qwen Token Plan (China) | `QWEN_TOKEN_PLAN_CN_API_KEY` | `qwen-token-plan-cn` |
|
|
102
|
+
| Xiaomi MiMo | `XIAOMI_API_KEY` | `xiaomi` |
|
|
103
|
+
| Xiaomi MiMo Token Plan (China) | `XIAOMI_TOKEN_PLAN_CN_API_KEY` | `xiaomi-token-plan-cn` |
|
|
104
|
+
| Xiaomi MiMo Token Plan (Amsterdam) | `XIAOMI_TOKEN_PLAN_AMS_API_KEY` | `xiaomi-token-plan-ams` |
|
|
105
|
+
| Xiaomi MiMo Token Plan (Singapore) | `XIAOMI_TOKEN_PLAN_SGP_API_KEY` | `xiaomi-token-plan-sgp` |
|
|
106
|
+
|
|
107
|
+
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/env-api-keys.ts).
|
|
108
|
+
|
|
109
|
+
#### Auth File
|
|
110
|
+
|
|
111
|
+
Store credentials in `~/.sling/agent/auth.json`:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"anthropic": { "type": "api_key", "key": "sk-ant-..." },
|
|
116
|
+
"ant-ling": { "type": "api_key", "key": "..." },
|
|
117
|
+
"openai": { "type": "api_key", "key": "sk-..." },
|
|
118
|
+
"deepseek": { "type": "api_key", "key": "sk-..." },
|
|
119
|
+
"nvidia": { "type": "api_key", "key": "nvapi-..." },
|
|
120
|
+
"google": { "type": "api_key", "key": "..." },
|
|
121
|
+
"opencode": { "type": "api_key", "key": "..." },
|
|
122
|
+
"opencode-go": { "type": "api_key", "key": "..." },
|
|
123
|
+
"together": { "type": "api_key", "key": "..." },
|
|
124
|
+
"qwen-token-plan": { "type": "api_key", "key": "sk-sp-..." },
|
|
125
|
+
"qwen-token-plan-individual": { "type": "api_key", "key": "sk-sp-..." },
|
|
126
|
+
"qwen-token-plan-cn": { "type": "api_key", "key": "sk-sp-..." },
|
|
127
|
+
"xiaomi": { "type": "api_key", "key": "..." },
|
|
128
|
+
"xiaomi-token-plan-cn": { "type": "api_key", "key": "..." },
|
|
129
|
+
"xiaomi-token-plan-ams": { "type": "api_key", "key": "..." },
|
|
130
|
+
"xiaomi-token-plan-sgp": { "type": "api_key", "key": "..." }
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`qwen-token-plan-individual` uses the same international endpoint and `QWEN_TOKEN_PLAN_API_KEY` as
|
|
135
|
+
`qwen-token-plan`, but limits the picker to the models documented for Individual subscriptions. The existing
|
|
136
|
+
provider keeps its broader catalog for backward compatibility. When using `auth.json`, store the
|
|
137
|
+
credential under the provider you select; an environment variable is shared by both international providers.
|
|
138
|
+
|
|
139
|
+
The file is created with `0600` permissions (user read/write only). Auth file credentials take priority over environment variables.
|
|
140
|
+
|
|
141
|
+
API key credentials can also include provider-scoped environment values. These values are used before process environment variables when resolving the credential key, provider/model headers, and provider configuration such as Cloudflare account IDs, Azure OpenAI settings, Vertex project/location, Bedrock settings, `PI_CACHE_RETENTION`, and `HTTP_PROXY`/`HTTPS_PROXY`.
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"cloudflare-ai-gateway": {
|
|
146
|
+
"type": "api_key",
|
|
147
|
+
"key": "$CLOUDFLARE_API_KEY",
|
|
148
|
+
"env": {
|
|
149
|
+
"CLOUDFLARE_API_KEY": "...",
|
|
150
|
+
"CLOUDFLARE_ACCOUNT_ID": "account-id",
|
|
151
|
+
"CLOUDFLARE_GATEWAY_ID": "gateway-id"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Use this when sling should use different provider settings than the project shell environment.
|
|
158
|
+
|
|
159
|
+
### Key Resolution
|
|
160
|
+
|
|
161
|
+
The `key` field supports command execution, environment interpolation, and literals:
|
|
162
|
+
|
|
163
|
+
- **Shell command:** `"!command"` at the start executes the whole value as a command and uses stdout (cached for process lifetime)
|
|
164
|
+
```json
|
|
165
|
+
{ "type": "api_key", "key": "!security find-generic-password -ws 'anthropic'" }
|
|
166
|
+
{ "type": "api_key", "key": "!op read 'op://vault/item/credential'" }
|
|
167
|
+
```
|
|
168
|
+
- **Environment interpolation:** `"$ENV_VAR"` or `"${ENV_VAR}"` uses the value of the named variable. Interpolation works inside larger literals.
|
|
169
|
+
```json
|
|
170
|
+
{ "type": "api_key", "key": "$MY_ANTHROPIC_KEY" }
|
|
171
|
+
{ "type": "api_key", "key": "${KEY_PREFIX}_${KEY_SUFFIX}" }
|
|
172
|
+
```
|
|
173
|
+
`$FOO_BAR` is the variable `FOO_BAR`; use `${FOO}_BAR` when `BAR` is literal text. Missing environment variables make the value unresolved.
|
|
174
|
+
- **Escapes:** `"$$"` emits a literal `"$"`; `"$!"` emits a literal `"!"` without triggering command execution.
|
|
175
|
+
```json
|
|
176
|
+
{ "type": "api_key", "key": "$$literal-dollar-prefix" }
|
|
177
|
+
{ "type": "api_key", "key": "$!literal-bang-prefix" }
|
|
178
|
+
```
|
|
179
|
+
- **Literal value:** Used directly. Plain uppercase strings such as `MY_API_KEY` are literals; use `$MY_API_KEY` for environment variables.
|
|
180
|
+
```json
|
|
181
|
+
{ "type": "api_key", "key": "sk-ant-..." }
|
|
182
|
+
{ "type": "api_key", "key": "public" }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
OAuth credentials are also stored here after `/login` and managed automatically.
|
|
186
|
+
|
|
187
|
+
## Cloud Providers
|
|
188
|
+
|
|
189
|
+
### Azure OpenAI
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
export AZURE_OPENAI_API_KEY=...
|
|
193
|
+
export AZURE_OPENAI_BASE_URL=https://your-resource.ai.azure.com
|
|
194
|
+
# also supported: https://your-resource.cognitiveservices.azure.com
|
|
195
|
+
# also supported: https://your-resource.openai.azure.com
|
|
196
|
+
# root endpoints are auto-normalized to /openai/v1
|
|
197
|
+
# or use resource name instead of base URL
|
|
198
|
+
export AZURE_OPENAI_RESOURCE_NAME=your-resource
|
|
199
|
+
|
|
200
|
+
# Optional
|
|
201
|
+
export AZURE_OPENAI_API_VERSION=2024-02-01
|
|
202
|
+
export AZURE_OPENAI_DEPLOYMENT_NAME_MAP=gpt-4=my-gpt4,gpt-4o=my-gpt4o
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Amazon Bedrock
|
|
206
|
+
|
|
207
|
+
Use `/login amazon-bedrock` to store a Bedrock API key, or configure one of the ambient AWS credential sources below:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Option 1: AWS Profile
|
|
211
|
+
export AWS_PROFILE=your-profile
|
|
212
|
+
|
|
213
|
+
# Option 2: IAM Keys
|
|
214
|
+
export AWS_ACCESS_KEY_ID=AKIA...
|
|
215
|
+
export AWS_SECRET_ACCESS_KEY=...
|
|
216
|
+
|
|
217
|
+
# Option 3: Bearer Token
|
|
218
|
+
export AWS_BEARER_TOKEN_BEDROCK=...
|
|
219
|
+
|
|
220
|
+
# Optional region (defaults to us-east-1)
|
|
221
|
+
export AWS_REGION=us-west-2
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Also supports ECS task roles (`AWS_CONTAINER_CREDENTIALS_*`) and IRSA (`AWS_WEB_IDENTITY_TOKEN_FILE`).
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
pi --provider amazon-bedrock --model us.anthropic.claude-sonnet-4-20250514-v1:0
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Prompt caching is enabled automatically for Claude models whose ID contains a recognizable model name (base models and system-defined inference profiles). For application inference profiles (whose ARNs don't contain the model name), set `AWS_BEDROCK_FORCE_CACHE=1` to enable cache points:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
export AWS_BEDROCK_FORCE_CACHE=1
|
|
234
|
+
pi --provider amazon-bedrock --model arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
If you are connecting to a Bedrock API proxy, the following environment variables can be used:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# Set the URL for the Bedrock proxy (standard AWS SDK env var)
|
|
241
|
+
export AWS_ENDPOINT_URL_BEDROCK_RUNTIME=https://my.corp.proxy/bedrock
|
|
242
|
+
|
|
243
|
+
# Set if your proxy does not require authentication
|
|
244
|
+
export AWS_BEDROCK_SKIP_AUTH=1
|
|
245
|
+
|
|
246
|
+
# Set if your proxy only supports HTTP/1.1
|
|
247
|
+
export AWS_BEDROCK_FORCE_HTTP1=1
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Cloudflare AI Gateway
|
|
251
|
+
|
|
252
|
+
`CLOUDFLARE_API_KEY` can be set via `/login`. The account ID and gateway slug can be set as environment variables or in the API key credential's `env` object in `auth.json`.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
export CLOUDFLARE_API_KEY=... # or use /login
|
|
256
|
+
export CLOUDFLARE_ACCOUNT_ID=...
|
|
257
|
+
export CLOUDFLARE_GATEWAY_ID=... # create at dash.cloudflare.com → AI → AI Gateway
|
|
258
|
+
pi --provider cloudflare-ai-gateway --model "claude-sonnet-4-5"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Routes to OpenAI, Anthropic, and Workers AI through Cloudflare AI Gateway. Workers AI uses the Unified API (`/compat`) and prefixed model IDs (`workers-ai/@cf/...`). OpenAI uses the OpenAI passthrough route (`/openai`) with native OpenAI model IDs such as `gpt-5.1`. Anthropic uses the Anthropic passthrough route (`/anthropic`) with native Anthropic model IDs such as `claude-sonnet-4-5`.
|
|
262
|
+
|
|
263
|
+
AI Gateway authentication uses `CLOUDFLARE_API_KEY` as `cf-aig-authorization`. Upstream authentication can be one of:
|
|
264
|
+
|
|
265
|
+
| Mode | Request auth | Upstream auth |
|
|
266
|
+
|------|--------------|---------------|
|
|
267
|
+
| Workers AI | Cloudflare token only | Cloudflare-native |
|
|
268
|
+
| Unified billing | Cloudflare token only | Cloudflare handles upstream auth and deducts credits |
|
|
269
|
+
| Stored BYOK | Cloudflare token only | Cloudflare injects provider keys stored in the AI Gateway dashboard |
|
|
270
|
+
| Inline BYOK | Cloudflare token plus upstream `Authorization` header | The request supplies the upstream provider key |
|
|
271
|
+
|
|
272
|
+
For normal sling usage, prefer unified billing or stored BYOK. Inline BYOK requires configuring an additional upstream `Authorization` header for the Cloudflare AI Gateway provider, for example via a `models.json` provider/model override.
|
|
273
|
+
|
|
274
|
+
### Cloudflare Workers AI
|
|
275
|
+
|
|
276
|
+
`CLOUDFLARE_API_KEY` can be set via `/login`. `CLOUDFLARE_ACCOUNT_ID` can be set as an environment variable or in the API key credential's `env` object in `auth.json`.
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
export CLOUDFLARE_API_KEY=... # or use /login
|
|
280
|
+
export CLOUDFLARE_ACCOUNT_ID=...
|
|
281
|
+
pi --provider cloudflare-workers-ai --model "@cf/moonshotai/kimi-k2.6"
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Pi automatically sets `x-session-affinity` for [prefix caching](https://developers.cloudflare.com/workers-ai/features/prompt-caching/) discounts.
|
|
285
|
+
|
|
286
|
+
### Google Vertex AI
|
|
287
|
+
|
|
288
|
+
Uses Application Default Credentials:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
gcloud auth application-default login
|
|
292
|
+
export GOOGLE_CLOUD_PROJECT=your-project
|
|
293
|
+
export GOOGLE_CLOUD_LOCATION=us-central1
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Or set `GOOGLE_APPLICATION_CREDENTIALS` to a service account key file.
|
|
297
|
+
|
|
298
|
+
## llama.cpp
|
|
299
|
+
|
|
300
|
+
Pi supports the llama.cpp router server. Configure it with `/login llama.cpp`, manage loaded models with `/llama`, and select a loaded model with `/model`.
|
|
301
|
+
|
|
302
|
+
See [llama.cpp](llama-cpp.md) for server setup, model directory layout, environment variables, and command usage.
|
|
303
|
+
|
|
304
|
+
## Custom Providers
|
|
305
|
+
|
|
306
|
+
**Via models.json:** Add Ollama, LM Studio, vLLM, or any provider that speaks a supported API (OpenAI Completions, OpenAI Responses, Anthropic Messages, Google Generative AI). See [models.md](models.md).
|
|
307
|
+
|
|
308
|
+
**Via extensions:** For providers that need custom API implementations or OAuth flows, create an extension. See [custom-provider.md](custom-provider.md) and [examples/extensions/custom-provider-gitlab-duo](../examples/extensions/custom-provider-gitlab-duo/).
|
|
309
|
+
|
|
310
|
+
## Resolution Order
|
|
311
|
+
|
|
312
|
+
When resolving credentials for a provider:
|
|
313
|
+
|
|
314
|
+
1. CLI `--api-key` flag
|
|
315
|
+
2. `auth.json` entry (API key or OAuth token)
|
|
316
|
+
3. Environment variable
|
|
317
|
+
4. Custom provider keys from `models.json`
|
|
@@ -4,7 +4,7 @@ This page gets you from install to a useful first sling session.
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Pi is distributed as an npm package:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install -g --ignore-scripts @psnext/slingcli
|
|
@@ -14,7 +14,7 @@ npm install -g --ignore-scripts @psnext/slingcli
|
|
|
14
14
|
|
|
15
15
|
### Uninstall
|
|
16
16
|
|
|
17
|
-
Use the package manager that installed
|
|
17
|
+
Use the package manager that installed pi. The curl installer uses npm globally, so curl and npm installs are removed with npm:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
# curl installer or npm install -g
|
|
@@ -36,12 +36,12 @@ Then start sling in the project directory you want it to work on:
|
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
cd /path/to/project
|
|
39
|
-
|
|
39
|
+
pi
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
## Authenticate
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Pi can use subscription providers through `/login`, or API-key providers through environment variables or the auth file.
|
|
45
45
|
|
|
46
46
|
### Option 1: subscription login
|
|
47
47
|
|
|
@@ -51,7 +51,7 @@ Start sling and run:
|
|
|
51
51
|
/login
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Then select a provider. Built-in subscription logins include
|
|
54
|
+
Then select a provider. Built-in subscription logins include Slingshot.
|
|
55
55
|
|
|
56
56
|
### Option 2: API key
|
|
57
57
|
|
|
@@ -59,7 +59,7 @@ Set an API key before launching sling:
|
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
export SLINGSHOT_API_KEY=sk-ant-...
|
|
62
|
-
|
|
62
|
+
pi
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
You can also run `/login` and select an API-key provider to store the key in `~/.sling/agent/auth.json`.
|
|
@@ -95,11 +95,13 @@ sling loads context files at startup. Add an `AGENTS.md` file to tell it how to
|
|
|
95
95
|
- Keep responses concise.
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
Pi loads:
|
|
99
99
|
|
|
100
100
|
- `~/.sling/agent/AGENTS.md` for global instructions
|
|
101
101
|
- `AGENTS.md` or `CLAUDE.md` from parent directories and the current directory
|
|
102
102
|
|
|
103
|
+
If a directory contains `AGENTS.override.md`, sling loads it instead of `AGENTS.md` or `CLAUDE.md` from that directory.
|
|
104
|
+
|
|
103
105
|
Restart sling, or run `/reload`, after changing context files.
|
|
104
106
|
|
|
105
107
|
## Common things to try
|
|
@@ -109,8 +111,8 @@ Restart sling, or run `/reload`, after changing context files.
|
|
|
109
111
|
Type `@` in the editor to fuzzy-search files, or pass files on the command line:
|
|
110
112
|
|
|
111
113
|
```bash
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
pi @README.md "Summarize this"
|
|
115
|
+
pi @src/app.ts @src/app.test.ts "Review these together"
|
|
114
116
|
```
|
|
115
117
|
|
|
116
118
|
Images or text can be pasted with Ctrl+V (Alt+V on Windows); images can also be dragged into supported terminals.
|
|
@@ -7,7 +7,7 @@ RPC mode enables headless operation of the coding agent via a JSON protocol over
|
|
|
7
7
|
## Starting RPC Mode
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
pi --mode rpc [options]
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Common options:
|
|
@@ -490,7 +490,7 @@ If output was truncated, includes `fullOutputPath`:
|
|
|
490
490
|
"exitCode": 0,
|
|
491
491
|
"cancelled": false,
|
|
492
492
|
"truncated": true,
|
|
493
|
-
"fullOutputPath": "/tmp/
|
|
493
|
+
"fullOutputPath": "/tmp/pi-bash-abc123.log"
|
|
494
494
|
}
|
|
495
495
|
}
|
|
496
496
|
```
|
|
@@ -914,17 +914,15 @@ Emitted when a message begins and completes. The `message` field contains an `Ag
|
|
|
914
914
|
|
|
915
915
|
### message_update (Streaming)
|
|
916
916
|
|
|
917
|
-
Emitted during streaming of assistant messages. Contains
|
|
917
|
+
Emitted during streaming of assistant messages. Contains a delta event without a cumulative message snapshot.
|
|
918
918
|
|
|
919
919
|
```json
|
|
920
920
|
{
|
|
921
921
|
"type": "message_update",
|
|
922
|
-
"message": {...},
|
|
923
922
|
"assistantMessageEvent": {
|
|
924
923
|
"type": "text_delta",
|
|
925
924
|
"contentIndex": 0,
|
|
926
|
-
"delta": "Hello "
|
|
927
|
-
"partial": {...}
|
|
925
|
+
"delta": "Hello "
|
|
928
926
|
}
|
|
929
927
|
}
|
|
930
928
|
```
|
|
@@ -933,7 +931,6 @@ The `assistantMessageEvent` field contains one of these delta types:
|
|
|
933
931
|
|
|
934
932
|
| Type | Description |
|
|
935
933
|
|------|-------------|
|
|
936
|
-
| `start` | Message generation started |
|
|
937
934
|
| `text_start` | Text content block started |
|
|
938
935
|
| `text_delta` | Text content chunk |
|
|
939
936
|
| `text_end` | Text content block ended |
|
|
@@ -943,17 +940,21 @@ The `assistantMessageEvent` field contains one of these delta types:
|
|
|
943
940
|
| `toolcall_start` | Tool call started |
|
|
944
941
|
| `toolcall_delta` | Tool call arguments chunk |
|
|
945
942
|
| `toolcall_end` | Tool call ended (includes full `toolCall` object) |
|
|
946
|
-
| `done` | Message complete (reason: `"stop"`, `"length"`, `"toolUse"`) |
|
|
947
|
-
| `error` | Error occurred (reason: `"aborted"`, `"error"`) |
|
|
948
943
|
|
|
949
944
|
Example streaming a text response:
|
|
950
945
|
```json
|
|
951
|
-
{"type":"message_update","
|
|
952
|
-
{"type":"message_update","
|
|
953
|
-
{"type":"message_update","
|
|
954
|
-
{"type":"message_update","
|
|
946
|
+
{"type":"message_update","assistantMessageEvent":{"type":"text_start","contentIndex":0}}
|
|
947
|
+
{"type":"message_update","assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello"}}
|
|
948
|
+
{"type":"message_update","assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":" world"}}
|
|
949
|
+
{"type":"message_update","assistantMessageEvent":{"type":"text_end","contentIndex":0,"content":"Hello world"}}
|
|
955
950
|
```
|
|
956
951
|
|
|
952
|
+
`message_update` intentionally omits the former cumulative `message` field and
|
|
953
|
+
`assistantMessageEvent.partial`. Clients that need a live partial message must assemble it
|
|
954
|
+
from `message_start` and subsequent events using `contentIndex`. Treat `message_end.message`
|
|
955
|
+
as authoritative. For tool calls, buffer `toolcall_delta.delta`; `toolcall_end.toolCall`
|
|
956
|
+
contains the completed call.
|
|
957
|
+
|
|
957
958
|
### bash_execution_update
|
|
958
959
|
|
|
959
960
|
Emitted once for each output chunk from a direct `bash` command. `id` matches the command's `id`, allowing clients to associate output with the correct command.
|
|
@@ -1362,6 +1363,7 @@ Source files:
|
|
|
1362
1363
|
- [`packages/ai/src/types.ts`](../../ai/src/types.ts) - `Model`, `UserMessage`, `AssistantMessage`, `ToolResultMessage`
|
|
1363
1364
|
- [`packages/agent/src/types.ts`](../../agent/src/types.ts) - `AgentMessage`, `AgentEvent`
|
|
1364
1365
|
- [`src/core/messages.ts`](../src/core/messages.ts) - `BashExecutionMessage`
|
|
1366
|
+
- [`src/modes/json-event.ts`](../src/modes/json-event.ts) - `JsonAgentSessionEvent`
|
|
1365
1367
|
- [`src/modes/rpc/rpc-types.ts`](../src/modes/rpc/rpc-types.ts) - RPC command/response types, extension UI request/response types
|
|
1366
1368
|
|
|
1367
1369
|
### Model
|