npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sarvamai-cli

v0.2.11

Published

An agentic CLI coding assistant powered by Sarvam AI — built on the official sarvamai SDK, with OpenAI-compatible fallback.

Readme

sarvamai-cli

An open-source agentic CLI coding assistant powered by Sarvam AI, built on the official sarvamai SDK, with an OpenAI-compatible fallback provider. It reads, writes, and edits files and runs shell commands in your project — with your approval before any side effect.

Think of it as a lightweight, hackable terminal agent that talks to Sarvam's Indic-first LLMs (sarvam-105b) via the official SDK, and degrades gracefully to any OpenAI-compatible endpoint as a fallback. MIT-licensed, designed to complement Sarvam's SDK + skills ecosystem and be adoptable upstream.

sarvamai-cli in a terminal: a ! shell escape, an agent turn that runs a script through the approval gate, the Ctrl+O reasoning toggle, and /model

Recorded from the real binary with scripts/record-demo.py — no external recorder needed.

Why

Sarvam ships an excellent SDK (sarvamai on npm/PyPI) and Agent Skills for hosted editors (Claude Code, Cursor, Windsurf). But there's no standalone terminal agent for developers who live in the CLI. sarvamai-cli fills that gap — it consumes the official SDK for auth, retries, streaming, and SDK quirks, then layers an agentic tool loop on top.

Relationship to Sarvam's stack:

| Layer | What | Example | |-------|------|---------| | API client / SDK | sarvamai (official) | npm install sarvamai | | Framework provider | Vercel AI SDK provider | sarvam-ai-sdk | | Skills for hosted editors | sarvamai/skills (official) | Claude Code, Cursor | | Standalone terminal agent | sarvamai-cli (this project) | — |

Changelog

v0.2.11

  • Renamed package from sarvam-cli to sarvamai-cli (the former was taken on npm) — the sarvam binary name is unchanged. First release published to the npm registry.

v0.2.10

  • Fixed: sarvam --init exited 0 without writing anything when stdin ended early (piped input, Ctrl+D) — the same unguarded readline pattern fixed in the REPL in v0.2.9. It now aborts with a clear message and a non-zero status rather than reporting success. A partial config is never written: an empty apiKey silently shadows the env vars.
  • Added: demo GIF and an architecture diagram in the README, both reproducible from scripts/

v0.2.9

  • Fixed: Ctrl+D / Ctrl+C at any prompt exited silently with status 0 mid-line — readline's close event never resolved the pending question. Now exits cleanly (130 on interrupt).
  • Fixed: tool output printed twice when the model restated it as its answer
  • Fixed: /model accepted any string, so a typo failed later as an opaque API error
  • Fixed: Ctrl+O redraw dropped already-typed text from the display while keeping it in the buffer
  • Added: ! <cmd> shell escape — runs directly, no model round trip
  • /model reports when only one model is available instead of prompting for a choice of one

v0.2.8

  • Ctrl+O toggles reasoning display on/off (replaces /reasoning command)
  • /model command switches models mid-session without restarting
  • Provider interface gains getModel() and setModel() methods
  • SARVAM_MODELS exported for model listing
  • Welcome message shows current model + available shortcuts

v0.2.7

  • Reasoning tokens collected silently in background buffer (never shown by default)
  • /reasoning command toggles inline reasoning display on/off
  • /show command dumps the full reasoning log from the session
  • Reasoning is passed per-turn to the UI callback (not streamed live)
  • Welcome message updated to show available commands

v0.2.6

  • Buffer reasoning_content tokens (same as text) — discard when tool calls present
  • Detect and skip duplicate tool calls (model was calling pwd twice)
  • Add "do not repeat tool calls" rule to system prompt

v0.2.5

  • Add tool aliases: bash/shell/exec/cmd → run_shell, cat/read → read_file, etc. (model was calling "bash" and getting "Unknown tool")
  • List exact tool names in system prompt: "Do NOT invent tool names like bash, cat, exec"
  • Compact REPL output: single-line approval, drop "Exit: 0" noise, no redundant confirmation lines
  • Strip exit-code lines from tool result display in REPL
  • Tell model not to repeat tool output in its response

v0.2.4

  • Buffer streamed text and discard chain-of-thought when tool calls are present (only show final answer)
  • Detect premature stops after partial work ("No response requested", "done", etc.) and nudge model to continue
  • Add task completion rules to system prompt: complete ALL steps, don't stop after one tool call

v0.2.3

  • Fix read_file crashing on directories (EISDIR) — now detects directories and returns a helpful listing
  • Constrain model to working directory via dynamic {CWD} injection in system prompt
  • Auto-recover from empty responses with nudge mechanism

v0.2.2

  • Suppress chain-of-thought leakage via system prompt rules
  • Accept exit, quit, clear without leading slash in REPL

v0.2.1

  • Fix deprecated sarvam-m model default → sarvam-105b (API returns 400 for sarvam-m)
  • Fix env var fallback bug: ??|| for API key resolution so empty strings from partial config files don't block env vars

v0.2.0

  • Now backed by the official sarvamai SDK — no more hand-rolled fetch
  • Reasoning token streaming — reasoning_content deltas surfaced live in the REPL
  • Cleaner provider separation: Sarvam provider is SDK-backed, OpenAI provider is raw-fetch

Install

npm install -g sarvamai-cli   # makes `sarvam` available on your PATH

Or build from source:

git clone https://github.com/indic-ai-contribs/sarvamai-cli.git
cd sarvamai-cli
npm install        # installs sarvamai + typescript
npm run build
npm link           # makes `sarvam` available on your PATH

Then get a Sarvam API key from https://dashboard.sarvam.ai and run:

sarvam --init

This writes ~/.sarvam/config.json:

{
  "provider": "sarvam",
  "sarvam": { "apiKey": "sk_...", "model": "sarvam-105b" },
  "openai": { "apiKey": "", "model": "gpt-4o" }
}

Alternatively, set environment variables:

export SARVAM_API_KEY="sk_..."
# or, for the OpenAI-compatible fallback
export OPENAI_API_KEY="sk-..."

Usage

Interactive REPL:

sarvam

Inside the REPL, ! runs a shell command directly — no model round trip, no approval prompt, since you typed the command yourself:

❯ ! git status
❯ ! npm test

Commands the model chooses to run still go through the usual approval gate.

Single prompt (non-interactive):

sarvam "add a .gitignore for a Python project"
sarvam "find and fix the off-by-one in src/parser.ts"

Force a provider / model:

sarvam --provider openai --model gpt-4o "refactor utils.ts"
sarvam -p sarvam -m sarvam-105b "write a test for the auth flow"

Auto-approve all tool calls (use with care):

sarvam --approve never "run the tests and report failures"

Sarvam-native reasoning effort (streams thinking tokens in the REPL):

sarvam --reasoning-effort high "design a rate-limiter for this API"

All flags:

  -p, --provider <name>           sarvam | openai
  -m, --model <name>              Model name (sarvam-105b, gpt-4o, ...)
      --base-url <url>            Override the API base URL (OpenAI provider only)
      --approve <mode>            always | never  (default: prompt each time)
  -t, --temperature <n>           Sampling temperature (0–2)
      --reasoning-effort <lvl>    low | medium | high  (Sarvam only)
      --init                      Create ~/.sarvam/config.json interactively
  -h, --help                      Show help

Tools

The agent has four tools, all with approval prompts before any mutation:

| Tool | Description | |------|-------------| | read_file | Read a file (with line numbers, offset/limit paging) | | write_file | Write/overwrite a file (creates parent dirs) | | patch | Targeted find-and-replace edit on a file | | run_shell | Run a shell command, return stdout+stderr |

Architecture

Every side effect is gated. The model can propose a write, a patch, or a shell command, but nothing touches your disk until you approve it — and a decline is fed back as a tool result so the agent can adapt rather than stall.

bin/sarvam.ts        CLI entrypoint — flag parsing, config loading, mode dispatch
src/
  config.ts          ~/.sarvam/config.json + env var resolution
  types.ts           Shared message/tool/provider types
  providers/
    sarvam.ts        Sarvam provider — backed by the official sarvamai SDK
    openai.ts        OpenAI-compatible provider — raw fetch + SSE, works with any /v1 endpoint
  tools/
    index.ts         Tool definitions + runtime with approval gating
  agent/
    loop.ts          Agent loop: stream → tool calls → results → repeat
  ui/
    repl.ts          Interactive REPL + single-prompt mode with streaming
  util/
    sse.ts           Minimal async SSE parser (used by the OpenAI provider)

Runtime dependencies: sarvamai (the official Sarvam SDK). The OpenAI provider uses Node 20's built-in fetch — no additional dependencies.

Why two providers?

The Sarvam provider uses SarvamAIClient from the official sarvamai package. This gives us:

  • Correct auth via apiSubscriptionKey (the SDK handles the header)
  • Built-in retries and error handling (SDK throws typed SarvamAIError subclasses)
  • Proper SSE stream parsing (SDK returns an AsyncIterable<ChatCompletionChunk>)
  • Access to Sarvam-native extras: reasoning_effort, reasoning_content, wiki_grounding

The OpenAI provider is a thin raw-fetch client that works with any OpenAI-compatible endpoint (OpenAI, Groq, Together, Ollama, LM Studio). It exists as a fallback for users who don't have a Sarvam key yet or want to use a different model.

Programmatic use

import { SarvamProvider, runAgent } from "sarvamai-cli";

const provider = new SarvamProvider({ apiKey: process.env.SARVAM_API_KEY! });
const history = await runAgent([], "list files in the current directory", {
  provider,
  cwd: ".",
  approve: async () => true,
  onText: (chunk) => process.stdout.write(chunk),
  onReasoning: (chunk) => process.stderr.write(`[thinking] ${chunk}`),
});

Config resolution order

  1. CLI flags (--provider, --model, etc.)
  2. Environment variables (SARVAM_API_KEY, OPENAI_API_KEY)
  3. ~/.sarvam/config.json

Notes on the Sarvam SDK

  • Package: npm install sarvamai (v1.1.7+)
  • Client: new SarvamAIClient({ apiSubscriptionKey: "sk_..." })
  • Chat: client.chat.completions({ model, messages, stream: true, tools })
  • Streaming returns AsyncIterable<ChatCompletionChunk> — each chunk has choices[0].delta
  • delta.content can be null when reasoning consumes the token budget — the provider guards for this
  • delta.reasoning_content carries thinking tokens (Sarvam-native) — surfaced in the REPL
  • Auth failures throw ForbiddenError (Sarvam returns 403, not 401)

Contributing

PRs welcome. This is an open-source community project — see AUTHORS for contributors. The goal is a clean, ecosystem-aligned codebase that Sarvam (or anyone) can adopt or fork.

To add a new tool: add a handler in src/tools/index.ts (a ToolDef + run function), then register it in the TOOLS array. The agent loop picks it up automatically.

To add a new provider: implement the Provider interface in src/types.ts, then wire it in bin/sarvam.ts's buildProvider.

License

MIT — see LICENSE.