NovaLab Agent Development Kit — Build, test, and deploy Nova AI agents with multi-agent orchestration
Project description
Nova ADK — Agent Development Kit
The official Agent Development Kit for the NovaLab AI orchestration platform. Build, test, and deploy autonomous AI agents with enterprise-grade trust, confidence scoring, and full auditability.
Any LLM in. Governed agents out.
Available in TypeScript (@novalabai/adk) and Python (novalab-adk).
v1.1.0 — New
nova.orchestratemodule:route(intent),parallel([agent₁, agent₂]),verify(output), and composablepipeline().
Table of Contents
- Features
- Prerequisites
- Installation
- API Keys Setup
- Quick Start
- Running the Playground Server
- Testing Your Setup
- Writing an Agent
- Deploying an Agent
- Running an Agent
- Smart Model Routing
- Confidence Layer
- Multi-Agent Orchestration
- Multi-Agent Architecture
- Workflows
- Signal Monitoring
- Automations
- Webhooks
- Connections Hub
- API Resources
- Project Structure
- Running Tests
- Deployment Models
- Compliance
- Troubleshooting
- License
Features
- Agent Management — Create, configure, deploy, and run AI agents programmatically
- Multi-Agent Orchestration —
route(intent),parallel([agent₁, agent₂]),verify(output)as first-class SDK primitives - Composable Pipelines — Chain route → parallel → verify into a single
pipeline()call - Smart Model Routing — Automatically routes tasks to Claude (analytical) or Gemini (creative) based on intent
- Workflow Studio — Build multi-step agent pipelines with confidence gates at every step
- Signal Monitor — Ingest and stream real-time telemetry from IoT, vehicles, machines, and infrastructure
- Automations — Rule-based workflows described in plain English with configurable confidence thresholds
- Connections Hub — Manage third-party integrations (CRM, Slack, GitHub, databases, MQTT, etc.)
- Data Explorer — Upload datasets and query them with natural language
- History & Replay — Full audit trail with decision explanations
- Webhook Support — 8+ event types with HMAC-SHA256 signed payloads
- Confidence Layer — Every decision carries a 0-100% score determining autonomy level
- Human-in-the-Loop — High-risk actions require explicit human approval
- EU-first — GDPR-native, EU AI Act-ready
Prerequisites
- Node.js >= 18 (for TypeScript SDK)
- Python >= 3.10 (for Python SDK and playground server)
- npm or yarn (for TypeScript)
- pip (for Python)
Installation
TypeScript SDK
npm install @novalabai/adk
Or install from source:
cd Nova/typescript
npm install
npm run build
Then in your project:
npm install /path/to/Nova/typescript
Python SDK
pip install novalab-adk
Or install from source:
cd Nova/python
pip install -e .
Playground Server Dependencies
The playground server requires these Python packages:
pip install httpx fastapi uvicorn python-dotenv
API Keys Setup
Nova uses Claude (Anthropic) for analytical tasks and Gemini (Google) for creative tasks. You need API keys for both.
Get Your Keys
- Anthropic API Key — Sign up at console.anthropic.com and create an API key (starts with
sk-ant-...) - Google Gemini API Key — Get one at aistudio.google.com (starts with
AIza...)
Configure Keys
Option A: .env file (recommended)
Create a .env file in the project root:
ANTHROPIC_API_KEY="sk-ant-your-key-here"
GEMINI_API_KEY="AIzaSy-your-key-here"
The server auto-loads this file using python-dotenv.
Option B: Environment variables
export ANTHROPIC_API_KEY="sk-ant-your-key-here"
export GEMINI_API_KEY="AIzaSy-your-key-here"
Security: The
.envfile is listed in.gitignoreand will not be committed to version control. Never hardcode API keys in source files.
Quick Start
1. Start the Server
cd Nova
python3 playground/real_server.py
You should see:
╔══════════════════════════════════════════════════════════════╗
║ Nova ADK — Real AI Server (Claude + Gemini) ║
╠══════════════════════════════════════════════════════════════╣
║ API: http://localhost:4300/v1 ║
║ Docs: http://localhost:4300/docs ║
║ ║
║ Claude: Connected ║
║ Gemini: Connected ║
╚══════════════════════════════════════════════════════════════╝
2. Test with curl
# Health check — verify API keys are loaded
curl http://localhost:4300/v1/health
# Create an agent
curl -X POST http://localhost:4300/v1/agents \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"name": "My Agent", "description": "A test agent"}'
# Deploy the agent
curl -X POST http://localhost:4300/v1/agents/AGENT_ID/deploy \
-H "Authorization: Bearer your-api-key"
# Run the agent
curl -X POST http://localhost:4300/v1/agents/AGENT_ID/run \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"input": "Analyze the security risks of using JWT tokens"}'
3. Run the Full Demo
# In a second terminal
PYTHONPATH=python python3 playground/real_demo.py
This sends 5 different task types and shows you the full routing pipeline in action.
Running the Playground Server
Nova includes three server options:
| Server | Port | Description |
|---|---|---|
playground/real_server.py |
4300 | Real AI — Calls Claude + Gemini APIs |
playground/mock_server.py |
4200 | Mock — Simulated responses (no API keys needed) |
playground/mock-server.ts |
4100 | Mock (TS) — TypeScript mock server |
Real AI Server (recommended)
python3 playground/real_server.py
Requires API keys in .env. Routes tasks to Claude or Gemini based on intent.
Mock Server (for development)
# Python mock
python3 playground/mock_server.py
# TypeScript mock
npx tsx playground/mock-server.ts
No API keys needed — returns simulated responses for testing SDK features.
Testing Your Setup
Health Check
curl http://localhost:4300/v1/health
Expected response:
{
"status": "ok",
"version": "1.0.0-real",
"models": {
"claude": "connected",
"gemini": "connected"
}
}
If you see "no API key" for either model, check your .env file.
Run Demo Scripts
# Real AI demo (requires real_server.py running on port 4300)
PYTHONPATH=python python3 playground/real_demo.py
# Mock demo — Python (requires mock_server.py running on port 4200)
PYTHONPATH=python python3 playground/demo.py
# Mock demo — TypeScript (requires mock-server.ts running on port 4100)
npx tsx playground/demo.ts
Run Unit Tests
# Python SDK tests
cd python && pytest tests/
# TypeScript SDK tests
cd typescript && npm test
Writing an Agent
TypeScript
import { NovaClient } from "@novalabai/adk";
const nova = new NovaClient({
apiKey: process.env.NOVA_API_KEY,
region: "eu-west-1",
});
// Create an agent with confidence thresholds and tools
const agent = await nova.agents.create({
name: "Risk Analyser",
description: "Analyses portfolio risk using financial data",
model: "claude",
tools: [
{ name: "portfolio_reader", permissions: ["data:read"], riskLevel: "low" },
{ name: "market_data", permissions: ["data:read"], riskLevel: "low" },
],
confidenceThresholds: {
autonomous: 90, // >= 90% — runs without intervention
notify: 70, // >= 70% — runs and notifies stakeholders
approvalRequired: 50, // >= 50% — waits for human approval
// < 50% — blocked entirely
},
humanApproval: {
required: true,
riskThreshold: "high",
},
});
console.log(`Agent created: ${agent.id}`);
Python
import asyncio
from novalab_adk import NovaClient
async def main():
async with NovaClient(api_key="...", region="eu-west-1") as nova:
agent = await nova.agents.create(
name="Risk Analyser",
description="Analyses portfolio risk using financial data",
model="claude",
tools=[
{"name": "portfolio_reader", "permissions": ["data:read"], "risk_level": "low"},
{"name": "market_data", "permissions": ["data:read"], "risk_level": "low"},
],
confidence_thresholds={
"autonomous": 90,
"notify": 70,
"approval_required": 50,
},
human_approval={"required": True, "risk_threshold": "high"},
)
print(f"Agent created: {agent.id}")
asyncio.run(main())
Using the REST API Directly
curl -X POST http://localhost:4300/v1/agents \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Risk Analyser",
"description": "Analyses portfolio risk",
"model": "claude",
"confidenceThresholds": {
"autonomous": 90,
"notify": 70,
"approvalRequired": 50
}
}'
Deploying an Agent
After creating an agent, deploy it to make it active:
TypeScript
await nova.agents.deploy(agent.id);
console.log("Agent deployed and active");
Python
await nova.agents.deploy(agent.id)
print("Agent deployed and active")
REST API
curl -X POST http://localhost:4300/v1/agents/AGENT_ID/deploy \
-H "Authorization: Bearer your-api-key"
Running an Agent
Once deployed, send tasks to your agent:
TypeScript
const result = await nova.agents.run(agent.id, {
input: "Analyse portfolio risk for Q1 2026",
context: { portfolio: "growth-fund-a" },
});
console.log(`Output: ${result.output}`);
console.log(`Confidence: ${result.confidence}%`);
console.log(`Model: ${result.model_used}`);
console.log(`Autonomy: ${result.autonomy_level}`);
console.log(`Audit ID: ${result.audit_id}`);
Python
result = await nova.agents.run(
agent.id,
input="Analyse portfolio risk for Q1 2026",
context={"portfolio": "growth-fund-a"},
)
print(f"Output: {result.output}")
print(f"Confidence: {result.confidence}%")
print(f"Model: {result.model_used}")
print(f"Autonomy: {result.autonomy_level}")
print(f"Audit ID: {result.audit_id}")
REST API
curl -X POST http://localhost:4300/v1/agents/AGENT_ID/run \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"input": "Analyse portfolio risk for Q1 2026", "context": {"portfolio": "growth-fund-a"}}'
Agent Run Response
{
"output": "Based on current market analysis...",
"confidence": 92,
"agents_involved": ["nova-intent", "nova-research", "nova-guard", "nova-verify", "nova-confidence"],
"audit_id": "audit-a1b2c3d4",
"duration": 1250,
"model_used": "claude-sonnet-4-20250514",
"routing": {
"category": "analytical",
"recommended_model": "claude",
"claude_score": 3,
"gemini_score": 0,
"reasoning": "Task contains analytical keywords. Routing to Claude for precise reasoning."
},
"risk": {
"risk_level": "low",
"requires_approval": false
},
"autonomy_level": "AUTONOMOUS",
"tokens_used": 450
}
Smart Model Routing
Nova automatically routes tasks to the best model based on intent classification:
| Model | Routed For | Keywords |
|---|---|---|
| Claude (Anthropic) | Reasoning, analysis, code, security, logic | analyse, reason, code, debug, security, evaluate, compare, technical, algorithm |
| Gemini (Google) | Creative writing, summarisation, content | create, write, draft, summarise, story, brainstorm, translate, blog, marketing |
When scores are equal, Nova defaults to Claude for safer, more precise output.
Examples
| Task | Routed To | Why |
|---|---|---|
| "Analyze security risks of JWT tokens" | Claude | Contains "analyze", "security", "risk" |
| "Write a blog post about AI trends" | Gemini | Contains "write", "blog", "content" |
| "Review this code for bugs" | Claude | Contains "review", "code" |
| "Create a marketing tagline" | Gemini | Contains "create", "marketing" |
| "What is the best approach?" | Claude | Ambiguous — defaults to Claude |
Confidence Layer
Every Nova decision carries a confidence score (0-100%) that determines the autonomy level:
| Score | Level | Behaviour |
|---|---|---|
| 90-100% | AUTONOMOUS |
Executes without intervention |
| 70-89% | NOTIFY |
Executes and notifies stakeholders |
| 50-69% | APPROVAL_REQUIRED |
Blocked until human approves |
| 0-49% | BLOCKED |
Escalated to human, cannot proceed |
Thresholds are configurable per agent, per workflow, and per organisation.
Confidence Scoring Factors
- Routing clarity — Higher when model selection is clear (large score gap between Claude and Gemini)
- Risk level — Reduced for high-risk tasks (delete, deploy, payment, etc.)
- Response quality — Boosted for longer, more detailed AI responses
Multi-Agent Orchestration
Nova v1.1 introduces a first-class orchestration engine with three composable primitives that match the Nova architecture:
→ route(intent) — classify & dispatch to the best agent
→ parallel([agent₁, agent₂]) — fan-out to N agents concurrently
→ verify(output) ✓ — trust-layer verification gate
Access via nova.orchestrate.* in both TypeScript and Python.
route(intent)
Classify the user's intent and route to the best-matching agent.
TypeScript
const routed = await nova.orchestrate.route({
input: "Analyse customer churn for Q4",
targets: [
{ agentId: "support-agent", intents: ["support", "help", "ticket"] },
{ agentId: "crm-agent", intents: ["customer", "crm", "lead"] },
{ agentId: "data-agent", intents: ["analyse", "data", "metrics", "report"] },
{ agentId: "risk-agent", intents: ["risk", "compliance", "audit"] },
],
});
console.log(routed.selectedAgentId); // "data-agent"
console.log(routed.intent); // "analytics"
console.log(routed.routeConfidence); // 75
console.log(routed.scores); // { "data-agent": 75, "crm-agent": 25, ... }
console.log(routed.result?.output); // Agent's response
Python
from novalab_adk import RouteParams, RouteTarget
routed = await nova.orchestrate.route(RouteParams(
input="Analyse customer churn for Q4",
targets=[
RouteTarget(agent_id="support-agent", intents=["support", "help", "ticket"]),
RouteTarget(agent_id="crm-agent", intents=["customer", "crm", "lead"]),
RouteTarget(agent_id="data-agent", intents=["analyse", "data", "metrics"]),
RouteTarget(agent_id="risk-agent", intents=["risk", "compliance", "audit"]),
],
))
print(routed.selected_agent_id) # "data-agent"
print(routed.result.output) # Agent's response
Options:
| Param | Type | Description |
|---|---|---|
input |
string | User input to classify |
targets |
RouteTarget[] | Candidate agents with intent keywords |
targets[].weight |
number (0-1) | Optional bias weight for tie-breaking |
context |
object | Context forwarded to the selected agent |
dryRun |
boolean | Returns classification without executing the agent |
parallel([agent₁, agent₂])
Execute multiple agents concurrently and merge their results.
TypeScript
const results = await nova.orchestrate.parallel({
tasks: [
{ agentId: "support-agent", input: "Summarise ticket #1234", label: "summary" },
{ agentId: "crm-agent", input: "Get customer profile for ticket #1234", label: "profile" },
{ agentId: "data-agent", input: "Pull usage metrics for this customer", label: "metrics" },
],
merge: "best", // "all" | "best" | "first" | "custom"
timeout: 30_000, // 30s max per task
confidenceFloor: 50, // skip results below 50% confidence
});
console.log(`Completed: ${results.successCount}/${results.tasks.length}`);
console.log(`Best result: ${results.merged?.result?.output}`);
console.log(`Wall time: ${results.duration}ms`);
// Access individual task results
for (const task of results.tasks) {
console.log(`${task.label}: ${task.status} (${task.duration}ms)`);
}
Python
from novalab_adk import ParallelParams, ParallelTask
results = await nova.orchestrate.parallel(ParallelParams(
tasks=[
ParallelTask(agent_id="support-agent", input="Summarise ticket #1234", label="summary"),
ParallelTask(agent_id="crm-agent", input="Get customer profile", label="profile"),
ParallelTask(agent_id="data-agent", input="Pull usage metrics", label="metrics"),
],
merge="best",
timeout=30,
confidence_floor=50,
))
print(f"Completed: {results.success_count}/{len(results.tasks)}")
print(f"Best result: {results.merged.result.output}")
Merge strategies:
| Strategy | Behaviour |
|---|---|
all |
Returns all results. merged = highest confidence. |
best |
Picks the single highest-confidence result. |
first |
Picks the first task to complete. |
custom |
Provide a mergeFn / merge_fn callback. |
Options:
| Param | Type | Description |
|---|---|---|
tasks |
ParallelTask[] | Tasks to run concurrently |
tasks[].agentId |
string | Agent to execute |
tasks[].input |
string | Task input |
tasks[].label |
string | Optional label for identification |
merge |
string | Merge strategy (default: "all") |
timeout |
number | Max time per task in ms (TS) or seconds (Python). 0 = no limit. |
confidenceFloor |
number | Skip results below this confidence (0-100) |
mergeFn |
function | Custom merge function (for merge: "custom") |
verify(output)
Pass an agent's output through the Nova trust layer for verification.
TypeScript
const verified = await nova.orchestrate.verify({
input: "Summarise Q4 revenue",
output: agentResult.output,
agentId: "data-agent",
threshold: 80, // must score >= 80 to pass
});
if (verified.passed) {
console.log(`Verified ✓ (${verified.trust.overallScore}/100)`);
console.log(verified.output); // safe to use
} else {
console.log(`Failed ✗ — ${verified.summary}`);
console.log("Concerns:", verified.trust.concerns);
}
Python
from novalab_adk import VerifyParams
verified = await nova.orchestrate.verify(VerifyParams(
input="Summarise Q4 revenue",
output=agent_result.output,
agent_id="data-agent",
threshold=80,
))
if verified.passed:
print(f"Verified ✓ ({verified.trust.overall_score}/100)")
else:
print(f"Failed ✗ — {verified.summary}")
Trust dimensions scored:
| Dimension | Weight | Description |
|---|---|---|
| Accuracy | 30% | Is the output factually correct? |
| Safety | 25% | Does it avoid harmful content? |
| Relevance | 25% | Does it address the original task? |
| Completeness | 20% | Is the response thorough? |
pipeline()
Compose route → parallel → verify into a single execution flow.
TypeScript
const result = await nova.orchestrate.pipeline({
input: "Analyse customer churn and prepare a retention plan",
steps: [
{
kind: "route",
params: {
input: "", // auto-filled from pipeline input
targets: [
{ agentId: "data-agent", intents: ["analyse", "data", "metrics"] },
{ agentId: "support-agent", intents: ["support", "help"] },
],
},
},
{
kind: "parallel",
params: {
tasks: [
{ agentId: "data-agent", input: "Analyse churn rate trends" },
{ agentId: "crm-agent", input: "Identify at-risk customers" },
],
merge: "best",
},
},
{
kind: "verify",
params: { input: "", output: "", threshold: 80 },
},
],
});
console.log(result.output); // Final verified output
console.log(result.confidence); // Trust score
console.log(result.verified); // true/false
console.log(result.agentsInvolved); // ["data-agent", "crm-agent"]
console.log(result.duration); // Total wall time (ms)
Python
from novalab_adk import (
PipelineStep, PipelineParams,
RouteParams, RouteTarget,
ParallelParams, ParallelTask,
VerifyParams,
)
result = await nova.orchestrate.pipeline(PipelineParams(
input="Analyse customer churn and prepare a retention plan",
steps=[
PipelineStep(kind="route", params=RouteParams(
input="",
targets=[
RouteTarget(agent_id="data-agent", intents=["analyse", "data"]),
RouteTarget(agent_id="support-agent", intents=["support", "help"]),
],
)),
PipelineStep(kind="parallel", params=ParallelParams(
tasks=[
ParallelTask(agent_id="data-agent", input="Analyse churn trends"),
ParallelTask(agent_id="crm-agent", input="Identify at-risk customers"),
],
merge="best",
)),
PipelineStep(kind="verify", params=VerifyParams(
input="", output="", threshold=80,
)),
],
))
print(result.output)
print(f"Confidence: {result.confidence}, Verified: {result.verified}")
Pipeline step types:
| Kind | What it does |
|---|---|
route |
Classify intent, pick best agent, execute |
parallel |
Fan-out N agents, merge results |
verify |
Trust-layer verification gate |
custom |
Run a custom async handler function |
Each step auto-inherits the previous step's output as input. The final verify step gates whether the pipeline passes or fails.
Multi-Agent Architecture
Nova decomposes requests into parallel sub-tasks across specialised internal agents:
Request --> Nova-Intent --> Agent Routing --> Parallel Execution --> Nova-Guard --> Nova-Confidence --> Human Gate --> Action --> Audit Log
| Agent | Role |
|---|---|
| Nova-Intent | Classifies user intent and routes to appropriate agents |
| Nova-Research | Gathers data from connected tools and external sources |
| Nova-Guard | Evaluates risk, confidence thresholds, and policy compliance |
| Nova-Verify | Cross-checks outputs for accuracy and consistency |
| Nova-Confidence | Computes final confidence scores and determines autonomy level |
Workflows
Build multi-step agent pipelines with confidence gates:
const workflow = await nova.workflows.create({
name: "Customer Onboarding",
steps: [
{ id: "classify", agentId: "nova-intent", action: "classify_request", confidenceGate: 80 },
{ id: "kyc", agentId: "kyc-verifier", action: "verify_identity", confidenceGate: 90 },
{ id: "risk", agentId: "risk-assessor", action: "assess_risk", confidenceGate: 70 },
{ id: "provision", agentId: "account-provisioner", action: "create_account", confidenceGate: 95 },
],
});
const result = await nova.workflows.run(workflow.id, { input: { ... } });
Each step's output feeds into the next. If any step falls below its confidence gate, the workflow pauses for human review.
Signal Monitoring
Ingest and stream real-time telemetry:
// Stream signals from factory equipment
const stream = nova.signals.stream({
systemIds: ["factory-line-a"],
signalNames: ["temperature", "vibration"],
interval: 1000,
});
for await (const signal of stream) {
console.log(`${signal.name}: ${signal.value} ${signal.unit}`);
}
Supported system types: IoT sensors, vehicles, robots, machines, infrastructure (HVAC, power, water).
Automations
Plain-English rule-based workflows:
await nova.automations.create({
name: "High Temperature Alert",
description: "When temperature > 85C, notify engineering and reduce speed",
trigger: {
type: "signal",
config: { signalName: "temperature", condition: "above", threshold: 85 },
},
actions: [
{ type: "notify", config: { connectionId: "slack-eng", message: "Temp alert: {{signal.value}}C" } },
{ type: "agent_run", config: { agentId: "machine-controller", input: "Reduce speed by 20%" } },
],
confidenceThreshold: 80,
});
Webhooks
Subscribe to platform events with HMAC-SHA256 verification:
import { verifyWebhookSignature } from "@novalabai/adk";
// Available events:
// approval.needed | anomaly.detected | agent.run.completed | agent.run.failed
// workflow.completed | signal.alert | automation.triggered | confidence.low
const isValid = verifyWebhookSignature(payload, signature, secret);
Connections Hub
Manage third-party integrations:
| Category | Providers |
|---|---|
| CRM | Salesforce, HubSpot, Pipedrive |
| Communication | Slack, Microsoft Teams, Email |
| Storage | Google Drive, Dropbox, S3 |
| Development | GitHub, GitLab, Jira |
| Data | PostgreSQL, BigQuery, Snowflake |
| IoT / Industrial | MQTT, OPC-UA, custom APIs |
API Resources
Both SDKs provide the same resource structure:
nova.agents — Create, deploy, run, and manage AI agents
nova.orchestrate — Multi-agent orchestration (route, parallel, verify, pipeline)
nova.workflows — Build and execute multi-step pipelines
nova.signals — Ingest and stream real-time telemetry
nova.automations — Manage rule-based automations
nova.connections — Third-party integrations
nova.data — Upload and query datasets
nova.history — Audit trail and decision replay
nova.trust — Trust evaluation on any AI output
nova.webhooks — Event subscriptions
Project Structure
Nova/
├── .env # API keys (not committed to git)
├── .gitignore # Excludes .env, node_modules, __pycache__
├── README.md # This file
├── package.json # Root dependencies
│
├── typescript/ # @novalabai/adk (TypeScript SDK)
│ ├── src/
│ │ ├── index.ts # Main exports
│ │ ├── client.ts # NovaClient entry point
│ │ ├── core/ # HTTP client, errors, confidence
│ │ ├── types/ # Full type definitions
│ │ ├── resources/ # API resource classes
│ │ ├── orchestration/ # route, parallel, verify, pipeline
│ │ └── utils/ # HMAC, streaming
│ ├── tests/ # Vitest unit tests
│ ├── examples/ # Usage examples
│ └── dist/ # Compiled output
│
├── python/ # novalab-adk (Python SDK)
│ ├── novalab_adk/
│ │ ├── client.py # NovaClient entry point
│ │ ├── core/ # HTTP client, errors, confidence
│ │ ├── types/ # Pydantic models
│ │ ├── resources/ # API resource classes
│ │ ├── orchestration/ # route, parallel, verify, pipeline
│ │ └── utils/ # HMAC, streaming
│ ├── tests/ # Pytest tests
│ └── examples/ # Usage examples
│
└── playground/ # Local demo servers & scripts
├── real_server.py # Real AI server (Claude + Gemini, port 4300)
├── real_demo.py # Full demo with model routing
├── mock_server.py # Mock server (port 4200)
├── mock-server.ts # Mock server TypeScript (port 4100)
├── demo.py # Python demo (mock)
└── demo.ts # TypeScript demo (mock)
Running Tests
Python SDK
cd Nova/python
pip install -e ".[dev]"
pytest tests/
Individual test files:
pytest tests/test_client.py # Client creation & config
pytest tests/test_confidence.py # Confidence scoring & gates
pytest tests/test_errors.py # Error types
pytest tests/test_hmac.py # Webhook signature verification
pytest tests/test_types.py # Type validation
TypeScript SDK
cd Nova/typescript
npm install
npm test
Deployment Models
| Model | Description |
|---|---|
| Cloud (SaaS) | Fully managed on EU infrastructure |
| Hybrid | Control plane in cloud, data processing on-premise |
| On-Premise | Full platform in customer infrastructure |
| SDK-only | Embed Nova agents into existing apps via ADK |
Compliance
- GDPR-native — data residency in EU, no cross-border transfers without consent
- EU AI Act-ready — risk classification, transparency obligations, human oversight
- Full audit trail — every decision logged with timestamp, confidence, and reasoning
- Role-based access control — granular permissions per user, team, and agent
- Signed webhooks — HMAC-SHA256 payload verification
- SOC 2 Type II alignment (in progress)
Troubleshooting
"Claude API key not set" / "Gemini API key not set"
Check that your .env file exists in the project root and contains valid keys:
cat .env
Make sure python-dotenv is installed:
pip install python-dotenv
Server won't start
Install required packages:
pip install httpx fastapi uvicorn python-dotenv
"No such file or directory" when running python3 playground/real_server.py
Make sure you're in the Nova/ directory:
cd /path/to/Nova
python3 playground/real_server.py
Port already in use
Kill the existing process:
lsof -ti:4300 | xargs kill -9
Claude/Gemini API errors
- Verify your API keys are valid and active
- Check you have credits/quota on your Anthropic and Google accounts
- Check the health endpoint:
curl http://localhost:4300/v1/health
License
MIT
NovaLab — Build AI Workflows You Can Trust
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file novalab_adk-1.2.0.tar.gz.
File metadata
- Download URL: novalab_adk-1.2.0.tar.gz
- Upload date:
- Size: 43.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f86bef0bdd7197d6b994009f797dc459908d8dd0a27e3e01e83ba0797f0c0446
|
|
| MD5 |
3669aef1f4e367bd12bae2ccb15baeac
|
|
| BLAKE2b-256 |
27ef06671f92d35b50b25b152e201b68ae5bd70782f8daf62a84fa0aa8fd9cc9
|
File details
Details for the file novalab_adk-1.2.0-py3-none-any.whl.
File metadata
- Download URL: novalab_adk-1.2.0-py3-none-any.whl
- Upload date:
- Size: 40.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
834f726e5ff0191a4795c2cc78a9daa0153e181cb4ad367b9a5bf4375177eb0f
|
|
| MD5 |
b467aff22c2bfacb5e10547cef37b57c
|
|
| BLAKE2b-256 |
fa910463eeef0e10ffcd9e6adb2191a13b79de41f9d44ce31c41b798146acbb6
|