commit - c8e3c5f06180d15bf331fbefe09eba169f617038
commit + 12ba2f2c78139c78d96c01a668b70e22dfdf9aa2
blob - 65e2267280ea6945baa53e5dcb28b27e683bb5ce
blob + 870280a852c9319b649d4f7366ea6ade73a72f2a
--- README.md
+++ README.md
status.
`alpaca` saves each successful request as a JSON transcript in
-`$XDG_DATA_HOME/alpaca` or `~/.local/share/alpaca`. `alpaca` writes files with mode
-`0600` in a directory with mode `0700`. Each turn sends the whole conversation
-as context.
+`$XDG_DATA_HOME/alpaca` or `~/.local/share/alpaca`. `alpaca` writes files with
+mode `0600` in a directory with mode `0700`. Each turn sends the whole
+conversation as context.
When the editor is `vim` or `neovim`, `alpaca` keeps one editor open for the
whole conversation instead of reopening it each turn. Writing the buffer sends
window as a bar showing the used share, with a countdown to the next reset.
Some providers also report a table of per-model counts.
-Pick a provider with `-p`. Without it, alpaca reports all providers in one output
-and skips the ones it cannot reach:
+Pick a provider with `-p`. Without it, `alpaca` reports all providers in one
+output and skips the ones it cannot reach:
```sh
$ alpaca quota # all providers
`platform.openai.com/settings/organization/admin-keys`. A regular project
key, such as `sk-proj-...`, gets a 403.
-DeepInfra bills per token or per second, with no fixed quota. alpaca prints
+DeepInfra bills per token or per second, with no fixed quota. `alpaca` prints
no window for it. It prints the remaining credit as a note. A negative balance
is funds ready to spend, and a positive one is money owed.
The Ollama provider reports Ollama Cloud usage. It takes the key from
`$OLLAMA_API_KEY` and defaults to `https://ollama.com`. You can override this
with `$OLLAMA_API_ENDPOINT`. It shows the monthly usage pool as the share of
-the plan's credits used, with per-model request counts and any extra spend
-beyond the plan. The endpoint reports no reset time, so no reset is shown.
-Accounts on the old billing get the 5 hour and weekly windows instead, with
-locally computed reset boundaries.
+the plan's credits used, and any extra spend beyond the plan. The endpoint
+reports no reset time, so no reset is shown. Accounts on the old billing get
+the 5 hour and weekly windows instead, with locally computed reset boundaries.
The Codex provider reports your ChatGPT plan usage, not organization spend.
-alpaca reads the OAuth token the Codex CLI stores in `$CODEX_HOME/auth.json`,
+`alpaca` reads the OAuth token the Codex CLI stores in `$CODEX_HOME/auth.json`,
defaulting to `~/.codex/auth.json`. Sign in once with `codex` and the report
works. `--apikey` replaces that token. The endpoint serves the Codex CLI and
the ChatGPT client, so it is not a documented public API and may change
-without notice. alpaca prints the 5 hour and weekly windows with their reset
+without notice. `alpaca` prints the 5 hour and weekly windows with their reset
times, the plan name, and the credits balance when the plan has one.
The top-level `base_url` configures the chat endpoint only, so `alpaca quota`
nothing more specific names one, because all three double as chat endpoints.
Anthropic and OpenAI never serve chat, so they ignore the top-level `apikey`
and always need a key from a table or profile. Without a chosen provider,
-alpaca resolves each provider key on its own, exactly as an explicit `-p`
+`alpaca` resolves each provider key on its own, exactly as an explicit `-p`
would. It never sends the top-level `apikey` to all providers.
Options:
blob - be87851ab36a15e4c8b18a41e58b8a7981938ae5
blob + 7067c3e1bf36af142b3e44c2c51e72410f9d0cba
--- man/alpaca-compose.1.scd
+++ man/alpaca-compose.1.scd
inherits the process's streams. Saving an empty buffer sends nothing and ends
the session with status 0.
-Each successful request is saved as a JSON transcript in _$XDG_DATA_HOME/alpaca_,
-or _~/.local/share/alpaca_ when that variable is unset. *alpaca* writes the
-transcripts with mode 0600 in a directory with mode 0700. Each turn sends the
-whole conversation as context.
+Each successful request is saved as a JSON transcript in
+_$XDG_DATA_HOME/alpaca_, or _~/.local/share/alpaca_ when that variable is
+unset. *alpaca* writes the transcripts with mode 0600 in a directory with mode
+0700. Each turn sends the whole conversation as context.
When the editor is *vim* or *neovim*, *alpaca* keeps one editor open for the
whole conversation instead of reopening it each turn. Writing the buffer
# Options
*-m*, *--model* _model_
- The model to use. It defaults to *ALPACA_MODEL*, or *gpt-4o-mini* if that is not set.
+ The model to use. It defaults to *ALPACA_MODEL*, or *gpt-4o-mini* if that
+ is not set.
*-s*, *--system* _msg_
The system prompt, sent before the conversation.
The sampling temperature.
*-T*, *--timeout* _secs_
- The request timeout in seconds. It defaults to *ALPACA_TIMEOUT*, or 60 if that is not set.
+ The request timeout in seconds. It defaults to *ALPACA_TIMEOUT*, or 60 if
+ that is not set.
*--reasoning-effort* _effort_
One of *low*, *medium*, *high* or *none*.
# Configuration
-This command reads its settings from the Alpaca configuration file.
+This command reads its settings from the alpaca configuration file.
Command-line options and environment variables take priority. See
*alpaca-config*(5).
# Exit status
-An editor that exits non-zero sets the exit status of *alpaca compose*, so
+An editor that exits nonzero sets the exit status of *alpaca compose*, so
aborting an edit aborts the request. Usage errors exit 2.
# Examples
blob - 682c73da29d5c26d031ce1a3ba47e72f53941cd6
blob + c681e966e24eb9df81f0c4848ad4f472d17b388c
--- man/alpaca-config.5.scd
+++ man/alpaca-config.5.scd
# Description
-Alpaca reads shared defaults from _$XDG_CONFIG_HOME/alpaca/config.toml_. If you
-do not set *XDG_CONFIG_HOME*, Alpaca reads _~/.config/alpaca/config.toml_.
+alpaca reads shared defaults from _$XDG_CONFIG_HOME/alpaca/config.toml_. If you
+do not set *XDG_CONFIG_HOME*, alpaca reads _~/.config/alpaca/config.toml_.
-The file is optional. Alpaca exits with an error if the file exists but cannot
+The file is optional. alpaca exits with an error if the file exists but cannot
be read or parsed.
Settings take priority in this order:
blob - 3054cefdd7e70d720bfe12a8f5da5d42dfc7672f
blob + 73d2f1b89863c2428a43fc1e9ec679b4168449f6
--- man/alpaca-quota.1.scd
+++ man/alpaca-quota.1.scd
*ollama*
Ollama Cloud. It takes the key from *OLLAMA_API_KEY*. The base URL is
*https://ollama.com*, or *$OLLAMA_API_ENDPOINT* when set. It prints the
- monthly usage pool as the share of the plan's credits used, a table of
- per-model request counts, and any extra spend beyond the plan. It shows
- no reset, because the endpoint reports no reset time. Accounts on the
- old billing get the 5 hour and weekly windows instead, with locally
- computed reset boundaries.
+ monthly usage pool as the share of the plan's credits used, and any extra
+ spend beyond the plan. It shows no reset, because the endpoint reports no
+ reset time. Accounts on the old billing get the 5 hour and weekly windows
+ instead, with locally computed reset boundaries.
The *anthropic* endpoint is not a documented public API, so it may change
without notice. It expects the short-lived OAuth token the Claude Code CLI
cannot reach.
*-T*, *--timeout* _secs_
- The request timeout in seconds. It defaults to *ALPACA_TIMEOUT*, or 60 if that is not set.
+ The request timeout in seconds. It defaults to *ALPACA_TIMEOUT*, or 60 if
+ that is not set.
*--apikey* _key_
The API key or OAuth token, replacing the provider default.
# Configuration
-This command uses *output_format* and *timeout* from the Alpaca configuration
+This command uses *output_format* and *timeout* from the alpaca configuration
file. Top-level *base_url* configures the chat endpoint, so this command
never uses it for any provider: each provider already has the correct
endpoint built in. A table named after a provider, such as *[anthropic]* or
blob - 1c77f2c18a36211a336d9b1aecef268ee748227a
blob + 85f0dcefd1e752e0a7d65127804491b6c96c1502
--- man/alpaca.1.scd
+++ man/alpaca.1.scd
# Options
*-m*, *--model* _model_
- The model to use. It defaults to *ALPACA_MODEL*, or *gpt-4o-mini* if that is not set.
+ The model to use. It defaults to *ALPACA_MODEL*, or *gpt-4o-mini* if that
+ is not set.
*-t*, *--temperature* _temp_
The sampling temperature.
*-T*, *--timeout* _secs_
- The request timeout in seconds. It defaults to *ALPACA_TIMEOUT*, or 60 if that is not set.
+ The request timeout in seconds. It defaults to *ALPACA_TIMEOUT*, or 60 if
+ that is not set.
*-s*, *--system* _msg_
The system prompt. It is always sent first.
blob - e133bb147b6c894ab6b24ff1746faee228cd1130
blob + 411e416a1df5089621a257b95bdb8789d2ec85a3
--- src/usage/ollama.rs
+++ src/usage/ollama.rs
rows: sorted(&limits.weekly.models),
});
}
+ // The monthly pool is a credit pool, not a request window: its per-model
+ // request counts are not shown.
if let Some(used) = limits.monthly.usage {
windows.push(Window::new("monthly", used, None));
- tables.push(Table {
- heading: "monthly models".to_string(),
- unit: "reqs",
- rows: sorted(&limits.monthly.models),
- });
}
if !usage.activity.models.is_empty() {
tables.push(Table {
view.windows[0].resets_in_secs, None,
"the monthly pool renews on the plan start day, which is not reported"
);
- assert_eq!(view.tables.len(), 1);
- assert_eq!(view.tables[0].heading, "monthly models");
- assert_eq!(
- view.tables[0].rows,
- vec![
- ModelCount {
- name: "kimi-k3".to_string(),
- requests: 329
- },
- ModelCount {
- name: "web search".to_string(),
- requests: 4
- }
- ],
- "models are sorted busiest first"
+ assert!(
+ view.tables.is_empty(),
+ "the monthly pool has no per-model table"
);
Ok(())
}
}"#,
)?;
- assert_eq!(view.tables[0].heading, "monthly models");
- assert_eq!(view.tables[1].heading, "activity models");
- assert_eq!(view.tables[1].rows[0].name, "kimi-k3");
+ assert_eq!(view.tables.len(), 1);
+ assert_eq!(view.tables[0].heading, "activity models");
+ assert_eq!(view.tables[0].rows[0].name, "kimi-k3");
Ok(())
}
blob - 409a19f4c2734c1d40d110e90edd994f97125775
blob + 43367bb1052185e2fdb34f469619c5a820e8ffe0
--- tests/quota.rs
+++ tests/quota.rs
predicate::str::contains("ollama cloud usage")
.and(predicate::str::contains("monthly"))
.and(predicate::str::contains("87.6%"))
- .and(predicate::str::contains("monthly models"))
- .and(predicate::str::contains("kimi-k3"))
+ .and(predicate::str::contains("monthly models").not())
+ .and(predicate::str::contains("kimi-k3").not())
.and(predicate::str::contains("extra 0.00000 USD"))
.and(predicate::str::contains("resets in").not()),
);