Getting Started with Smarter’s CLI

smarter is the command-line interface of The Smarter Project. It is to the Smarter API what kubectl is to Kubernetes. You describe a resource in a YAML file, and smarter apply makes the platform match it. The same program lists and describes what’s already there, checks a manifest before you apply it, prompts an LLMClient from your terminal, deploys it to a public url, and deletes it when you’re done. It’s a single binary, written in Go, for macOS, Linux and Windows.

This article takes one chatbot, a small LLMClient that answers every question with a haiku, through its whole life. You’ll write its manifest, validate it, apply it, prompt it, deploy it and delete it. Every command and every output below was run against a Smarter platform.

Diagram of a chatbot's life with the smarter cli, in six steps. Write the manifest (smarter manifest llmclient), validate it (smarter validate -f haiku-bot.yaml), apply it (smarter apply -f haiku-bot.yaml), prompt it (smarter chat prompt -l haiku_bot), deploy it to a public url (smarter deploy llmclient haiku_bot), and delete it (smarter delete llmclient haiku_bot).

Before you start

You need a Smarter platform to connect to, and a Smarter api key. The platform can be your own laptop, because the Quick Start Guide runs one locally on http://localhost:9357. To create an api key, see API Keys. An api key acts as the user who owns it, so everything below happens in that user’s account.

Install it

On macOS or Linux, with Homebrew.

brew tap smarter-sh/tap https://github.com/smarter-sh/homebrew-tap
brew trust smarter-sh/tap
brew install smarter

On Ubuntu, from its Launchpad PPA.

sudo add-apt-repository ppa:lpm0073/smarter-cli
sudo apt-get update
sudo apt-get install smarter-cli

On Windows, with Chocolatey.

choco install smarter

There’s also a Docker image, mcdaniel0073/smarter-cli, and a binary for every platform on the releases page. Check the install with smarter version.

Configure it

smarter configure asks for these, plus your preferred output format, and writes them to ~/.smarter/config.yaml, a file that only you can read.

  • root_domain is your platform’s domain, such as platform.example.com.
  • account_number is your Smarter account number, such as 3141-5926-5359.
  • api_key is your 64-character api key. It’s masked as you type it.
  • username is the name you sign in to the web console with.

Pressing enter keeps the value shown in parentheses, so you can run configure again to change one thing.

The cli can keep a key for each of five environments, named local, alpha, beta, next and prod, the default. Choose one with --environment. local is always http://localhost:9357, which is where the Quick Start runs, and the others are derived from your root domain.

Every setting can also come from an environment variable, which takes precedence over the file. That’s the usual way to run the cli in CI/CD, or against a platform you don’t want in your configuration.

export SMARTER_API_KEY="your 64-character Smarter api key"
export SMARTER_BASE_URL="http://localhost:9357"

The Smarter SDKs for Python, Node.js and Go read the same file and the same variables, so once the cli works, they do too.

Now check who you are.

smarter whoami

It prints the api key’s owner, which is their user, their account and the platform’s environment. It’s the cheapest way to check that a key works.

Look around

smarter resources lists the kinds of resource that the platform has, such as LLMClients, Plugins, Connections, Secrets, Guardrails, Budgets and the rest. smarter get lists the resources of one kind. Its output is JSON by default, and -o yaml and -o tabular are also available. Tabular is the easiest to read.

smarter get llmclients -o tabular
name              url                                                           deployed
----              ---                                                           --------
calculator        http://calculator.3141-5926-5359.api.local.smarter.sh/        true
customer_support  http://customer-support.3141-5926-5359.api.local.smarter.sh/  true
example           http://localhost:9357/workbench/llm-clients/rMTAwMDAwNgx/     false
openai            http://localhost:9357/workbench/llm-clients/rMTAwMDAxMQx/     false

(The real table has a few more columns, such as when each LLMClient was created and last updated.)

A deployed LLMClient has a public url of its own. One that isn’t deployed is reached through the web console’s workbench.

smarter describe returns one resource as a manifest, ready to save, edit and apply again.

smarter describe llmclient openai -o yaml > openai.yaml

Write a manifest

Every Smarter resource is declared in a Smarter Application Manifest (SAM), which has apiVersion, kind, metadata and spec, like a Kubernetes manifest. You don’t have to start from a blank file. smarter manifest prints a complete example of any kind, with every field filled in.

smarter manifest llmclient > llmclient-example.yaml

Most fields are optional. Here’s the haiku bot, saved as haiku-bot.yaml.

apiVersion: smarter.sh/v1
kind: LLMClient
metadata:
  name: haiku_bot
  description: Answers every question with a haiku.
  version: 1.0.0
spec:
  config:
    prompt:
      provider: openai
      defaultModel: gpt-6-luna
      defaultSystemRole: You answer every question with a single haiku.
      appName: Haiku Bot
      appAssistant: Basho
      appWelcomeMessage: Ask me anything. I answer in seventeen syllables.
      appExamplePrompts:
        - What is Kubernetes?
        - Why is the sky blue?

provider and defaultModel choose the LLM, and defaultSystemRole is the system prompt that starts every conversation. The app fields are what the chat window shows, which is its title, the assistant’s name, a welcome message and a few example prompts.

Validate it

smarter validate asks the platform to check a manifest against its kind’s model, without saving anything. Here’s what it says about a manifest with a mistake in it, defaultTemperature: warm.

smarter validate -f haiku-bot.yaml
spec.config.prompt.defaultTemperature: Input should be a valid number, unable to parse string as a number

Error: manifest has 1 error(s)

Each error names the field and the problem, and the command exits with status 1, so a CI job that runs it fails. With the mistake fixed, it prints manifest is valid. smarter apply --dry-run does the same check.

Apply it

smarter apply -f haiku-bot.yaml
manifest applied.

That’s it. haiku_bot now appears in smarter get llmclients and in the web console. apply is declarative. The platform compares the manifest with the resource’s current state and makes only the changes that the difference requires, so applying the same file again is safe, and changing the resource means editing the file and applying it again. That’s what makes a folder of manifests in a git repository, reviewed in pull requests, a workable way to run a Smarter account.

Prompt it

smarter chat prompt --llmclient haiku_bot --prompt "What is Kubernetes?"

The response is the platform’s whole answer as JSON, including the messages that were sent, the LLM’s reply, any tool calls, and the tokens that the prompt was charged. That’s useful for debugging. To see only the reply, pipe it through jq.

smarter chat prompt -l haiku_bot -p "What is Kubernetes?" \
  | jq -r '.data.response.data.body.choices[0].message.content'
A harbor for containers
Kubernetes steers their fleets
Across cloud and machine

A prompt runs exactly as it would in a chat window. The platform adds the LLMClient’s system prompt, calls the LLM, runs any Plugins that the LLM asks for, applies the LLMClient’s Guardrails, and bills the tokens to the LLMClient’s owner, like any other prompt. smarter chat config --llmclient haiku_bot returns the configuration that a chat window loads, which is the name, the welcome message, the example prompts and the styles.

Deploy it

So far, haiku_bot can be reached only through the platform’s api and the web console. Deploying it gives it a url of its own, which a web page can embed.

smarter deploy llmclient haiku_bot

Its url has the form https://haiku-bot.<account-number>.api.<your-smarter-domain>/, or a custom domain of your own. smarter get llmclients shows it once the deployment is done, and smarter undeploy llmclient haiku_bot takes it down again. To put the deployed chatbot on a web page, see How to Embed a Smarter Chatbot in an HTML Web Page, or Getting Started with @smarter.sh/ui-chat for a React app.

deploy also works for API keys, custom domains, vectorstores, self-hosted LLMs and the compute they run on. Run smarter deploy --help for the list.

Clean up

smarter delete llmclient haiku_bot
deleted.

delete is permanent, so describe the resource to a file first if you might want it back.

Using the cli in scripts and CI/CD

A few properties make the cli easy to automate.

  • Exit codes. A failed command exits with a non-zero status, so a script can stop on the first error. validate exits 1 for an invalid manifest.
  • Machine-readable output. JSON is the default, and -o yaml gives you manifests you can save. Tabular output is only for get, and is meant for people.
  • Configuration from the environment. In CI, give the job its own api key in SMARTER_API_KEY, as a CI secret, and set SMARTER_BASE_URL to the platform it deploys to. No configuration file is needed.
  • Retries. Requests that fail for a transient reason, such as a rate limit or a gateway timeout, are retried twice by default (--max_retries), and each one waits up to two minutes (--timeout).

A typical pipeline runs smarter validate on every manifest in each pull request, and smarter apply when the pull request is merged. Apply the manifests in dependency order, so that a Secret exists before the Connection that names it, and a Plugin before the LLMClient that uses it. Getting Started With smarter-api shows how to work that order out with SAMKinds.apply_order().

The manifest haiku-bot.yaml lives in a git repository. On each pull request, smarter validate exits 1 on an invalid manifest so the check fails; on merge, smarter apply sends the manifests in dependency order, and the platform compares each with the resource's current state and changes only the difference. Applying the same file again changes nothing. In CI, SMARTER_API_KEY and SMARTER_BASE_URL replace the config file.

To write manifests with completion and validation as you type, smarter json-schema llmclient > llmclient.schema.json gives you the JSON Schema that the platform validates against, which any YAML-aware editor can use. In VS Code, the Smarter Manifest extension does this for every kind, and runs the cli’s validate, apply and deploy commands from the editor.

Where to go next

Every command has --help, and smarter <command> <kind> --help describes each kind. The haiku bot is the smallest useful LLMClient. Its manifest is also where you give it Plugins that query a database or call an api, Guardrails, a Budget and its chat window’s styles, and the cli applies all of them the same way.

Have fun with your first chatbot. 🤩