Metadata-Version: 2.4
Name: cmdop-utils
Version: 0.1.1
Summary: CMDOP umbrella package — reusable utilities (llm, codegen, logging, telegram, agent) extracted from the relay.
Project-URL: Homepage, https://cmdop.com
Project-URL: Documentation, https://docs.cmdop.com
Project-URL: Repository, https://github.com/commandoperator/cmdop-utils
Project-URL: Bug Tracker, https://github.com/commandoperator/cmdop-utils/issues
License: Apache-2.0
Keywords: client-generator,cmdop,codegen,grpc,openapi,proto
Requires-Python: >=3.12
Requires-Dist: aiohttp>=3.9
Requires-Dist: aiometer>=0.5
Requires-Dist: cachetools>=5.3
Requires-Dist: grpcio-tools>=1.80
Requires-Dist: httpx>=0.27
Requires-Dist: json-repair>=0.30
Requires-Dist: openai>=1.0
Requires-Dist: pillow>=10.0
Requires-Dist: pydantic-ai-slim>=1.107
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.8
Requires-Dist: pytelegrambotapi>=4.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.31
Requires-Dist: rich>=13
Requires-Dist: structlog>=25.5
Requires-Dist: tiktoken>=0.7
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# cmdop-utils

The **umbrella package** for reusable CMDOP utilities — heavy, self-contained
pieces lifted out of the relay repo so the repo stays light. This is **not** the
whole relay (run that from the repo); it's an installable home for features other
projects (e.g. the LLM router) can reuse.

```bash
pip install cmdop-utils
```

📚 **[docs.cmdop.com](https://docs.cmdop.com)** ·
[Server](https://cmdop.com/server) · [Connect](https://cmdop.com/connect) ·
[Bots](https://cmdop.com/bots) · [SDK](https://cmdop.com/sdk)

## Features

### `cmdop_utils.codegen` — multi-language client generator

A monorepo-agnostic code-generation engine: declarative targets (proto / OpenAPI /
WebSocket) → typed clients in **Go, TypeScript, Python, Swift**. You supply a
`Config` describing your sources + outputs; the engine drives the toolchains
(`grpc_tools`, `ogen`, `@hey-api`, `openapi-python-client`, `swift-openapi`, a
built-in WS emitter).

```python
from cmdop_utils.codegen.schema import Config, ProtoSpec, ProtoTarget, Lang, Tool
from cmdop_utils.codegen.core.runner import run

cfg = Config(proto=ProtoSpec(targets=[ProtoTarget(
    name="proto-python", lang=Lang.PY, tool=Tool.GRPC_PYTHON,
    path=my_out_dir, proto_dirs=[my_proto_dir],
)]))
run(cfg, kinds=("proto",))
```

Or the CLI, pointing at a module that exposes `config: Config`:

```bash
python -m cmdop_utils.codegen --config myproject.codegen_config gen all
```

External toolchains (ogen, buf, swift-openapi, @hey-api) are subprocess
prerequisites — install the ones your targets use.

### `cmdop_utils.llm` — universal LLM transport

One module for every model call — chat, structured extraction (Pydantic
`response_format` with parse-and-repair), vision, image generation/edit,
embeddings, translation. It owns HTTP, auth, **cost-per-response**, retries, a
live **OpenRouter model registry** (pricing + capabilities), and a cascade
`LLMRouter` with role presets. Provider-agnostic (OpenAI / OpenRouter).

```python
from cmdop_utils.llm import LLMClient

client = LLMClient(api_key="sk-...")        # or omit → reads OPENROUTER_API_KEY / OPENAI_API_KEY
resp = client.chat("Summarize this.", model="alias:balanced")
print(resp.content, resp.cost_usd)
```

**Config is hybrid** (the openai/stripe-SDK pattern): pass keys explicitly, or let
them fall back to env (`OPENROUTER_API_KEY`, `OPENAI_API_KEY`, or the
`CMDOP_DEV_LLM_KEYS__*` form). No global Django config — explicit always wins.

### `cmdop_utils.telegram` — Telegram notification service

A small, framework-neutral Telegram sender (queue + formatters + parse-mode
handling) used for alerts/notifications. Reads `CMDOP_TELEGRAM_BOT_TOKEN` /
`CMDOP_TELEGRAM_CHAT_ID` from env, or take them per-call.

### `cmdop_utils.agent` — reusable tool-use loop

The framework-neutral agent harness built on `pydantic-ai` (Agent + toolsets +
`iter()`). Slim — no provider SDKs bundled; the consumer injects the Model.

### `cmdop_utils.logging` — universal structured logger

`structlog` + `rich`: async-safe queue sink, token-efficient logfmt for AI
consumption, dual console/machine renderers, context scoping, noise control.

> All features are framework-neutral — **no Django**. `cmdop_utils.llm` and
> `cmdop_utils.telegram` were ported from `django_cfg`; the single host seam is
> `cmdop_utils._compat` (env-driven config + a tiny TTL cache).

Apache-2.0.
