Metadata-Version: 2.4
Name: scvp
Version: 0.1.0a3
Summary: SCVP — a provider-agnostic Python runtime for AI agents
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=6.0
Requires-Dist: click>=8.1
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Provides-Extra: local-models
Requires-Dist: torch>=2.0; extra == "local-models"
Requires-Dist: transformers>=4.35; extra == "local-models"
Provides-Extra: gguf
Requires-Dist: llama-cpp-python>=0.2.0; extra == "gguf"
Dynamic: license-file

# SCVP — Provider-Agnostic Agent Runtime

SCVP is a small, provider-agnostic Python runtime for building AI agents.
It provides one stable model interface, deterministic local providers,
configurable agent execution, and injectable tools without locking an
application to a vendor SDK.

> **Status:** The core, model interface, and sequential agent runtime are
> implemented and covered by tests. Later roadmap items are intentionally
> not part of this release.

## Model providers

The built-in `mock` provider is deterministic and requires no API key. It
implements the complete model surface (`generate`, `chat`, `stream`,
`embed`, `classify`, and `reason`) so applications and tests can run locally.
Additional providers can register against the same `SCVPModel` interface.

### Local Custom Model

`CustomModelProvider` runs a model from disk without an API key or external
service. Install the optional backend you need:

```bash
pip install -e ".[local-models]"       # Hugging Face Transformers + torch
pip install -e ".[gguf]"               # GGUF through llama-cpp-python
```

Download a compatible model into a local directory (for example from a model
repository using its normal download tools), then point the configuration at
that directory. Transformers directories are loaded with
`AutoTokenizer`/`AutoModelForCausalLM`; a `.gguf` path uses llama.cpp.

Complete `scvp.config.yaml` example:

```yaml
models:
  default: custom
  providers:
    custom:
      type: custom
      model_path: "./models/my-model"
      device: "auto"
      temperature: 0.7
      max_tokens: 512
      timeout: 120
```

Create a model from that configuration and use it with an Agent:

```python
from scvp import Agent, SCVPModel, load_config

config = load_config("scvp.config.yaml")
model = SCVPModel.from_config(config)
agent = Agent(name="local-support", model=model)
result = agent.run("Summarize this project.")
print(result.content)
```

Loading is lazy: `transformers`, `torch`, or `llama-cpp-python` are imported
only when the custom provider receives its first request. Tests can inject any
lightweight object with a `generate()` method, so they never need a large model.

## Architecture

```mermaid
flowchart TB
    App[Your Application] --> SDK[SCVP SDK]
    SDK --> Core[SCVP Core]
    Core --> Runtime["Agent Runtime (phase 3)"]
    Runtime --> MTS["Model / Tools / Search / Memory (phases 2, 4, 5, 6)"]
    MTS --> Providers[(Providers / Adapters)]
    Core -.->|Registry pattern| Providers
```

Every layer only depends on the interfaces below it, never on a concrete
provider. `scvp.core.registry.Registry` is the one mechanism every
swappable layer (models today; tools, search, memory in later phases)
uses to register and resolve a named provider — Core never imports
`OpenAIProvider` or `RedisMemory` directly.

## Repository layout

```
scvp/
├── core/                    # config, logging, exceptions, registry, shared types
├── models/                  # ModelProvider interface, SCVPModel, MockModelProvider
│   └── providers/mock.py
├── agents/                  # Agent, planner, executor, and sequential runtime
├── tools/                   # Injectable SCVPTool contract and ToolResult
└── cli/                     # `scvp` command (init, model, agent/tool/plugin stubs)
    └── templates/minimal/   # `scvp init` starter template
tests/                       # pytest suite for everything above
examples/quickstart.py       # runnable end-to-end example
```

Layers not built yet (`search/`, `memory/`, `knowledge/`, `plugins/`, `api/`,
`sdk/`, ...) will each land in their own
phase, as an independent, replaceable module under `scvp/` — exactly as
laid out in the architecture above.

## Install

```bash
cd scvp
pip install -e ".[dev]"
```

## Quickstart

```python
from scvp import Message, Role, SCVPModel

model = SCVPModel(provider="mock")
response = model.chat([Message(role=Role.USER, content="Hello, SCVP!")])
print(response.content)
```

Or scaffold a starter project with the CLI:

```bash
scvp init my-agent
cd my-agent
python main.py
```

Run a provider-agnostic agent with the built-in mock model:

```python
from scvp import Agent

agent = Agent(name="support")
result = agent.run("Explain what SCVP is.")
print(result.content)
```

The current Agent Runtime is intentionally sequential. It supports injected
tools, custom planners, explicit step limits, and typed execution state.
Multi-agent orchestration and parallel execution are later phases.

Run the full walkthrough (chat, stream, embed, classify):

```bash
python examples/quickstart.py
```

## Configuration

Put a `scvp.config.yaml` (or `.json`) in your project root. It's
overridable by `SCVP_`-prefixed environment variables (`__` = nesting):

```yaml
model:
  provider: mock
```

```bash
export SCVP_MODEL__PROVIDER=mock   # overrides model.provider
```

Secrets (API keys, etc.) are **never** read from the config file — only
from environment variables (see `.env.example`) — so `scvp.config.yaml`
is always safe to commit.

## Run the tests

```bash
pytest
```

## Roadmap

- [x] Phase 0 — Architecture
- [x] Phase 1 — Core (config, logging, exceptions, registry, types)
- [x] Phase 2 — Model Interface (`ModelProvider`, `SCVPModel`, Mock provider) — *started*
- [x] Phase 3 — Agent Runtime (sequential MVP)
- [ ] Phase 4 — Tool System
- [ ] Phase 5 — Memory
- [ ] Phase 6 — Search
- [ ] Phase 7 — RAG / Knowledge
- [ ] Phase 8 — API
- [ ] Phase 9 — Plugins
- [ ] Phase 10 — SDK (Bot SDK, Web SDK)
- [ ] Phase 11 — CLI (full command surface)
- [ ] Phase 12 — Testing (integration/security suites)
- [ ] Phase 13 — Documentation

## Design principles

- **No provider lock-in.** Core never imports a concrete vendor SDK.
- **Real over fake.** No empty stub files — every file in this repo runs
  and is covered by a test.
- **Secrets stay in the environment**, never in source or config files.
- **Fail loud.** Missing config, unregistered providers, and unsupported
  capabilities raise a specific, typed exception instead of a silent
  no-op.

## License

MIT — see `LICENSE`.
