isA Model Service
Unified AI model platform for inference, training, and generic ML prediction.
Installation
pip install isa-modelQuick Start
from isa_model import AsyncISAModel
async with AsyncISAModel(base_url="http://localhost:8082") as client:
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)Latest Updates (2026-05-17)
- Sleep intelligence APIs added under
/api/v1/sleep. - Sleep evaluation endpoint added:
POST /api/v1/sleep/evaluate. - Sleep recommendation endpoint added:
POST /api/v1/sleep/recommend. - Commercial sleep model products registered:
com_sleep_quality,com_sleep_stage, andcom_health_risk. - Commercial model evidence gate added to validate serving behavior before release.
Earlier Updates (2026-02-14)
- Generic ML prediction API added with dedicated training and inference routes.
- Prediction endpoint pagination added (
limit/offset) for model and prediction lists. - Tenant isolation enforced for prediction model storage and retrieval.
- Prediction reliability/security hardening:
- training data key validation (
ds,y) - frequency / period bounds
- sanitized error persistence
- deleted-model safety checks during background training
- HMAC integrity checks for saved model artifacts
- tenant-scoped LRU model caching and eviction limits
- training data key validation (
- Auth integration improved by validating API keys through the auth service.
- Optional dependency guards added for Lightning algorithm modules.
Core Capabilities
Inference
- OpenAI-compatible chat/completions interface
- Multi-provider routing (OpenAI, Anthropic, Ollama, Cerebras, YYDS, Replicate, OpenRouter, Anthropic Sub)
- Streaming, tool-calling, and structured outputs
- Multi-modal support (text, vision, audio, embedding, image, video)
- Role-based and capability-based model resolution with cost-aware ranking
Voice & Realtime
- WebSocket bidirectional proxy for real-time voice conversations
- Session management with 15-minute TTL and reconnect window
- Voice privacy filter with PII redaction (SSN, phone, email, credit card)
- Configurable retention policies (STRICT, STANDARD, DEBUG)
- Turn detection with server-side VAD
- Per-session metrics (latency, audio chunks, interruptions)
Caching
- L1 exact-match cache (Redis)
- L2 semantic cache (Qdrant)
- Cache stats and invalidation endpoints
Training
- Lightning training pipeline endpoints for trace-based optimization
- Algorithm support for
closed_loop,apo,grpo, andcustom
Generic ML Prediction
- Model lifecycle for prediction models (create/train/list/get/delete)
- Inference endpoint for forecasts
- Tenant-scoped prediction history with pagination
Sleep Intelligence
- Sleep-quality evaluation
- Sleep-stage recommendation
- Health-risk assessment products for commercial serving flows
API Endpoints
Base URL: http://localhost:8082
Inference & Cache
| Endpoint | Method | Description |
|---|---|---|
/api/v1/invoke | POST | Unified inference endpoint |
/api/v1/invoke/v2 | POST | Extended invoke with role/capability routing |
/api/v1/models | GET | List available LLM models |
/api/v1/cache/stats | GET | Cache statistics |
/api/v1/cache/invalidate/{provider}/{model} | POST | Invalidate cache by provider/model |
/api/v1/cache/clear | POST | Clear all cache entries |
Voice & Realtime
| Endpoint | Method | Description |
|---|---|---|
/realtime/sessions | POST | Create realtime voice session |
/realtime/ws/{session_id} | WS | WebSocket bidirectional voice proxy |
/realtime/sessions/{session_id}/interrupt | POST | Send barge-in / cancel response |
Training
| Endpoint | Method | Description |
|---|---|---|
/api/v1/models/training/train | POST | Start Lightning training |
/api/v1/models/training/stats | GET | Training statistics |
/api/v1/models/training/export | POST | Export training data |
/api/v1/models/training/config | GET | Read active training config |
Prediction (ML)
| Endpoint | Method | Description |
|---|---|---|
/api/v1/models/training/ml/prediction/models | POST | Create + start training prediction model |
/api/v1/models/training/ml/prediction/models | GET | List prediction models (limit, offset) |
/api/v1/models/training/ml/prediction/models/{model_id} | GET | Get prediction model details |
/api/v1/models/training/ml/prediction/models/{model_id} | DELETE | Delete prediction model |
/api/v1/models/inference/ml/prediction/models/{model_id}/predict | POST | Run prediction |
/api/v1/models/inference/ml/prediction/models/{model_id}/predictions | GET | List prediction runs (limit, offset) |
Sleep
| Endpoint | Method | Description |
|---|---|---|
/api/v1/sleep/evaluate | POST | Evaluate sleep quality and related signals |
/api/v1/sleep/recommend | POST | Generate sleep-stage or health recommendations |
Prediction Example
# 1) Create + train a model (prophet)
curl -X POST http://localhost:8082/api/v1/models/training/ml/prediction/models \
-H "Content-Type: application/json" \
-d '{
"name": "daily-sales-forecast",
"model_type": "prophet",
"data": [
{"ds": "2026-01-01", "y": 120},
{"ds": "2026-01-02", "y": 125}
]
}'
# 2) Run prediction
curl -X POST http://localhost:8082/api/v1/models/inference/ml/prediction/models/<MODEL_ID>/predict \
-H "Content-Type: application/json" \
-d '{
"periods": 14,
"frequency": "D",
"include_history": false
}'Intelligent Model Routing
The invoke endpoint supports role-based and capability-based model selection with optional cost constraints:
# Role-based resolution — automatically selects best model for the role
curl -X POST http://localhost:8082/api/v1/invoke/v2 \
-H "Content-Type: application/json" \
-d '{
"role": "reasoning",
"messages": [{"role": "user", "content": "Solve this logic puzzle"}],
"preferred_max_cost_per_token": 0.00005
}'Role defaults:
| Role | Default Model | Provider |
|---|---|---|
reasoning | deepseek-reasoner | yyds |
response | gemini-2.5-flash-lite | openrouter |
coding | minimax-m2.5 | openrouter |
default | gpt-4o-mini | openai |
Resolution priority: explicit model/provider → role lookup → capability filter → service type defaults.
Latency-Aware Ranking
When multiple candidate models match a request (e.g., several models share the same capability), the router ranks them using a weighted composite score that balances cost and recent latency performance.
Composite score formula:
score = (1 - latency_weight) * normalized_cost + latency_weight * normalized_latencynormalized_cost— per-token output cost scaled to[0, 1]across candidates.normalized_latency— provider P50 latency scaled to[0, 1]across candidates.- The candidate with the lowest composite score wins.
When no latency data is available (cold start or new provider), the ranker falls back to cost-only sorting automatically.
Example request with latency preference:
curl -X POST http://localhost:8082/api/v1/invoke/v2 \
-H "Content-Type: application/json" \
-d '{
"role": "coding",
"messages": [{"role": "user", "content": "Refactor this function"}],
"preferred_max_cost_per_token": 0.0001,
"preferred_max_latency_ms": 500
}'Per-Provider Latency Tracking
The Model service maintains a sliding-window latency tracker for every provider. Each completed inference request records its response latency, and the tracker computes percentile statistics on demand.
Tracked percentiles:
| Metric | Description |
|---|---|
p50_ms | Median latency — typical response time |
p95_ms | 95th percentile — tail latency for most requests |
p99_ms | 99th percentile — worst-case latency |
avg_ms | Arithmetic mean across the window |
sample_count | Number of measurements in the current window |
How data flows:
- Every inference call records
latency_msfor the provider that served it. - Measurements are stored in a per-provider sliding window (default: last 1,000 requests).
- The latency ranker reads P50 from the tracker when scoring candidates.
- A NATS telemetry event (
isa.model.selection) is published for each selection decision, including the observed latency and chosen strategy. NATS failures never block inference.
Querying latency stats:
Provider latency percentiles are exposed through the health/stats endpoint and can also be queried programmatically:
from isa_model.serving.api.provider_latency import get_latency_tracker
tracker = get_latency_tracker()
# Get percentiles for a single provider
openai_stats = tracker.get_percentiles("openai")
print(f"OpenAI P50={openai_stats.p50_ms}ms P95={openai_stats.p95_ms}ms P99={openai_stats.p99_ms}ms")
# Get percentiles for all tracked providers
all_stats = tracker.get_all_percentiles()
for provider, stats in all_stats.items():
print(f"{provider}: P50={stats.p50_ms}ms ({stats.sample_count} samples)")Selection Statistics
The Model service also collects aggregate selection statistics that reveal routing patterns over time:
| Statistic | Description |
|---|---|
total_selections | Total model selection events since startup |
strategy_distribution | Breakdown by strategy (explicit, role, intelligent, default) with counts and percentages |
top_models | Most frequently selected models |
avg_latency_ms | Average selection latency across all events |
selections_by_provider | Selection count per provider |
These statistics are available via the /api/v1/models/selection/stats endpoint.
Tuning Guide
Control latency-aware routing behavior with these environment variables:
| Variable | Default | Description |
|---|---|---|
LATENCY_RANKING_WEIGHT | 0.3 | Weight given to latency in the composite score. 0.0 = cost-only ranking, 1.0 = latency-only ranking. Values are clamped to [0.0, 1.0]. |
LATENCY_WINDOW_SIZE | 1000 | Number of recent measurements kept per provider. Larger windows produce more stable percentiles but react slower to changes. |
Tuning recommendations:
| Scenario | Recommended LATENCY_RANKING_WEIGHT | Rationale |
|---|---|---|
| Cost-sensitive batch workloads | 0.0 – 0.1 | Minimize spend; latency is not critical |
| Balanced interactive use (default) | 0.3 | Good trade-off for chat and coding assistants |
| Real-time / low-latency APIs | 0.6 – 0.8 | Prioritize fast responses over cost savings |
| Latency-critical pipelines | 0.9 – 1.0 | Always pick the fastest provider regardless of cost |
Window size guidance:
- 100 — Reacts quickly to provider degradation; noisier percentiles.
- 1,000 (default) — Stable percentiles with reasonable responsiveness.
- 5,000+ — Very smooth percentiles; slow to reflect sudden latency spikes.
For production deployments, monitor P95 and P99 through the Grafana SLO dashboard (deployment/monitoring/grafana-slo-dashboard.json) and adjust the weight if a provider consistently exceeds latency SLOs.
Voice Session Example
# 1) Create a realtime voice session
curl -X POST http://localhost:8082/realtime/sessions \
-H "Content-Type: application/json" \
-H "x-user-id: user-123" \
-d '{"model": "gpt-4o-realtime-preview", "voice": "alloy"}'
# Response: { "session_id": "...", "websocket_url": "ws://...", "expires_at": "..." }
# 2) Connect via WebSocket for bidirectional audio streaming
# 3) Interrupt (barge-in) during a response
curl -X POST http://localhost:8082/realtime/sessions/{session_id}/interruptPrivacy modes:
| Mode | Audio Retention | Transcript Retention | Metadata Retention |
|---|---|---|---|
STRICT | 0 days | 0 days | 7 days |
STANDARD | 0 days | 30 days | 90 days |
DEBUG | 365 days | 365 days | 365 days |
Documentation
Getting Started
- Quick Start - First steps
- Providers - Provider configuration
Features
- LLM Services - Text generation and routing
- Tool Calling - Function calling
- Caching - Cache architecture and tuning
Environment Variables
| Variable | Description |
|---|---|
OPENAI_API_KEY | OpenAI provider key |
ANTHROPIC_API_KEY | Anthropic provider key |
YYDS_API_KEY | YYDS provider key |
REDIS_URL | Redis URL for caching |
QDRANT_URL | Qdrant URL for semantic cache |
NATS_URL | NATS URL for events |