Metadata-Version: 2.5
Name: stackai
Version: 0.8.1
Summary: Interactive AI agent CLI for StackAI.
Project-URL: Homepage, https://www.stack-ai.com
Project-URL: Repository, https://github.com/StackAI/stack-cli
Project-URL: Issues, https://github.com/StackAI/stack-cli/issues
Author-email: StackAI <arosinol@stack-ai.com>
License-Expression: MIT
License-File: LICENSE
Keywords: ai,cli,stackai,workflows
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Requires-Dist: anthropic>=0.69.0
Requires-Dist: openai>=1.40.0
Requires-Dist: textual>=0.80.0
Requires-Dist: typer>=0.12.0
Description-Content-Type: text/markdown

# stackai

[![CI](https://github.com/StackAI/stack-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/StackAI/stack-cli/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/stackai.svg)](https://pypi.org/project/stackai/)

An interactive AI agent in your terminal — like Claude Code, for [StackAI](https://www.stack-ai.com).

## Installation

```bash
pip install stackai
```

This installs the `stack` command.

## The interactive agent

Just run `stack` (or `stack chat`) to start an interactive session:

```bash
stack
```

On a real terminal this opens a **full-screen app** (scrolling transcript +
anchored input, à la Claude Code). Piped/non-interactive input falls back to a
line REPL automatically; force it with `stack chat --classic`.

You get a streaming chat loop with **tool use** — the agent can read files,
list directories, and run shell commands (with your approval) to help answer
your questions. Responses render as Markdown with syntax-highlighted code
blocks; extended thinking is streamed inline.

```
› what does pyproject.toml configure?

stack ⚙ read_file pyproject.toml
      … reads the file, then explains it
```

### Slash commands

| Command            | Description                              |
| ------------------ | ---------------------------------------- |
| `/help`            | show available commands                  |
| `/clear`           | reset the conversation                   |
| `/tools`           | list the tools the agent can call        |
| `/compact`         | summarize older turns to shrink context  |
| `/model [name]`    | switch model (Claude/OpenAI); no name opens a picker |
| `/backend <name>`  | switch backend (`anthropic` \| `openai` \| `stackai`)|
| `/exit`, `/quit`   | leave                                    |

### Models

Run `/model` for a picker across **Claude** (Opus 4.8, Fable 5, Sonnet 5,
Haiku 4.5) and **OpenAI** (GPT-5 Codex, GPT-5, o4-mini), or `/model <name>` to
switch directly — the backend is inferred from the id (`gpt-*`/`o*` → OpenAI,
`claude-*` → Anthropic; or force with `openai:<id>`). Switching starts a fresh
session. OpenAI needs `OPENAI_API_KEY` (or `stack config set openai_api_key …`).

### Backends

The agent is backend-pluggable: **Anthropic** (Claude, default), **OpenAI**
(GPT/Codex), or a deployed **StackAI** workflow.

**Anthropic** (default) — set a key and go:

```bash
export ANTHROPIC_API_KEY=sk-ant-...
stack                          # or: stack chat -b anthropic -m claude-opus-4-8
```

**StackAI** — call one of your deployed workflows:

```bash
stack config set backend stackai
stack config set stackai_url  https://api.stack-ai.com/inference/v0/run/<org>/<flow>
stack config set stackai_api_key <key>
stack
```

Config is stored at `~/.config/stackai/config.json`. Relevant keys:
`backend`, `model`, `anthropic_api_key`, `stackai_url`, `stackai_api_key`,
`stackai_input_field` (default `in-0`), `stackai_output_field` (default `outputs`).

## Context compaction

Long sessions are kept from overflowing the model's context window by
**auto-summarization**. When the transcript grows past a threshold, the oldest
turns are replaced by a single summary while the most recent turns are kept
verbatim; run `/compact` to trigger it manually.

Compaction rewrites history **rarely and in one batch**, so the compacted
prefix stays stable between compactions — friendly to prompt caching, unlike a
rolling window that would change the prefix every turn. It only applies to
backends that send the full history (currently Anthropic). Relevant config keys:

| Key                        | Default  | Meaning                                   |
| -------------------------- | -------- | ----------------------------------------- |
| `compact`                  | `true`   | enable auto-summarization                 |
| `compact_threshold_tokens` | `120000` | compact once the transcript exceeds this  |
| `compact_keep_tokens`      | `40000`  | recent tokens kept verbatim after compact |

```bash
stack config set compact_threshold_tokens 80000
stack config set compact false        # disable auto-compaction
```

## Other commands

```bash
stack --version
stack hello [name]
stack config set|get|list|path
```

## Development

This project uses [uv](https://docs.astral.sh/uv/).

```bash
uv sync                   # install deps into a local venv
uv run stack              # run the agent from source
uv run pytest             # run the test suite
```

## Building & publishing

```bash
uv build                  # produces wheel + sdist in dist/
uv publish                # upload to PyPI
```

## License

MIT
