Blog6 min read

Use SolCard Inference in Crush

Add SolCard Inference to Charm’s Crush with the new crushrc file: the provider add and model add lines, context and price flags, a check, and fixes.

Contents

To use SolCard Inference in Crush, add a completions provider in your crushrc with --base-url https://api.solcardinference.ai/v1 and your sk-si- key, then register solcard-inference-fast, -large and -base with model add. Crush moved to this Bash-style config file in v0.88.0, whose release notes open with “.crushrc is here!”, so older guides that show a crush.json block are out of date. Everything about Crush below comes from its README and config docs. We haven’t run Crush ourselves; the same API also works in OpenCode and Goose.

What you need

  • A SolCard Inference API key. Make one on the dashboard’s API keys page. Keys start with sk-si- and are shown once.
  • Some balance or a plan. One prepaid USD balance pays for every key and model; see how billing works.
  • Crush. The README lists brew install charmbracelet/tap/crush, npm install -g @charmland/crush, winget install charmbracelet.crush and packages for Arch, Nix and FreeBSD.

Where the crushrc goes

Put the provider in your global file, ~/.config/crush/crushrc (%USERPROFILE%\.config\crush\crushrc on Windows), so every project sees it. Crush’s config docs give this order of priority, highest first:

FileScope
./.crushrcThis project
./crushrcThis project
$XDG_CONFIG_HOME/crush/crushrcEvery project

Project settings override global ones, and a crushrc overrides a JSON config in the same directory. The docs say the JSON format still works but “won’t be receiving new features.”

The provider and model lines

Add this to the file:

provider add solcard-inference \
  --type completions \
  --name "SolCard Inference" \
  --base-url "https://api.solcardinference.ai/v1" \
  --api-key "${SOLCARD_INFERENCE_API_KEY:?set SOLCARD_INFERENCE_API_KEY}"

model add solcard-inference/solcard-inference-fast \
  --name "SolCard Inference Fast" \
  --context-window 1048576 \
  --default-max-tokens 32768 \
  --supports-images false \
  --price-input 1.25 --price-cache-hit 0.125 --price-output 2.50

model add solcard-inference/solcard-inference-large \
  --name "SolCard Inference Large" \
  --context-window 1000000 \
  --default-max-tokens 32768 \
  --thinking always \
  --supports-images false \
  --price-input 3.75 --price-cache-hit 0.375 --price-output 6.25

model add solcard-inference/solcard-inference-base \
  --name "SolCard Inference Base" \
  --context-window 262144 \
  --default-max-tokens 32768 \
  --supports-images false \
  --price-input 1.25 --price-cache-hit 0.125 --price-output 3.75

model large solcard-inference/solcard-inference-fast
model small solcard-inference/solcard-inference-fast

Then export the key in the shell you start Crush from:

export SOLCARD_INFERENCE_API_KEY=sk-si-...

What each part does, per Crush’s config docs:

Line or flagWhat it’s for
--type completionsOpenAI Chat Completions, the type the docs’ OpenAI-compatible example uses.
--base-urlThe API endpoint. Ours ends in /v1.
--api-key "${...:?...}"Reads the key from a variable and stops with that message if it’s unset.
model add <provider>/<id>Registers a model on the provider. The id after the slash must match ours exactly.
--context-windowContext size in tokens, from our models page.
--default-max-tokensDefault maximum output tokens. Every model of ours stops at 32,768.
--thinkingalways, never or toggleable. Large always reasons, so it’s always.
--price-*Prices per 1M tokens. These are our pay-as-you-go rates.
model large / model smallCrush’s two model slots. Both point at Fast here.

We left --thinking off Fast and Base and --price-cache-create off all three, because our price list has no cache-write rate. Crush’s docs don’t say what each slot is used for, so putting the cheapest model in both is the safe start.

Keys from a password manager

A crushrc is Bash, so the key can come from a command instead of a variable. The config docs show this pattern for reading a key from a password manager:

--api-key "$(op read my-secret-key)"

Swap in your own secret reference. The same docs warn that both crushrc and crush.json are “trusted code”: a project’s .crushrc runs when you start Crush in that folder, so read one before you launch Crush in a repo you just cloned.

Switching models

Start on Fast and move to solcard-inference-large when a change needs planning or a bug won’t budge. Large costs about three times as much on input and writes reasoning on every turn. The README says to “Press ctrl+l to open the model picker”, and lists the ability to “switch LLMs mid-session while preserving context.” To change the default instead, edit the model large line. Fast, Large or Base compares the three.

Check it works

Check the key and URL from a terminal first:

curl https://api.solcardinference.ai/v1/models \
  -H "Authorization: Bearer $SOLCARD_INFERENCE_API_KEY"

You should see solcard-inference-fast, -large and -base. Then start crush in a project, press ctrl+l, confirm SolCard Inference is listed with its three models, and ask for something small, such as “Explain what this file does.”

What a session costs

An agent resends the conversation every turn, mostly at the cached rate. A turn on Fast that resends 100,000 tokens, 95,000 of them cached, and writes 2,000 tokens is about $0.023. The same turn on Large is about $0.067, and Large always reasons, so expect more output tokens per turn. How billing works has the plans and what a request is charged for.

Troubleshooting

These are the API’s codes, from our errors page; Crush may word them differently.

  • 401 invalid_api_key: the key is missing, revoked or unknown. Check the variable is set in the shell that started crush.
  • 400 model_not_found: an id after solcard-inference/ doesn’t match. Use solcard-inference-fast, -large or -base.
  • 400 unsupported_content: an image or file reached the model. Our models take text only, which is why --supports-images is false.
  • 402 insufficient_balance: top up, then retry.
  • 429 rate_limited: too many requests a minute for your plan.

For Crush’s side, the README says logs live in ./.crush/logs/crush.log, and crush logs --follow streams them. Add option debug true to your crushrc for more detail. Crush’s schema says its request timeout, 60 seconds by default, aborts a stream only after that much silence between tokens, and gives the first token at least five minutes, so a slow start on Large shouldn’t trip it.

FAQ

Can I keep my other providers in Crush? Yes. provider add adds one provider and the rest stay. Pick between them with ctrl+l.

I already have a crush.json. Do I need to convert it? No. Crush’s docs say the JSON format is still supported, and a crushrc in the same directory wins where they overlap. New options only go into crushrc.

Can I use the Anthropic-compatible type instead? Crush has a messages type for Anthropic Messages APIs, and our API speaks that format too. The completions setup above is the one this guide covers.

Does Crush send my prompts anywhere else? Crush’s README says it records pseudonymous usage metrics but prompts and responses are “NEVER collected.” Set CRUSH_DISABLE_METRICS=1 or DO_NOT_TRACK=1 to opt out. On our side, prompts and responses are never logged or stored; keeps nothing follows one request through.

Bring the prompt that got refused.

Private. No refusals. In the app, or in the tools you already use.

Pay in crypto. No KYC.