Skip to main content

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.orchestrate module: route(intent), parallel([agent₁, agent₂]), verify(output), and composable pipeline().


Table of Contents


Features

  • Agent Management — Create, configure, deploy, and run AI agents programmatically
  • Multi-Agent Orchestrationroute(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

  1. Anthropic API Key — Sign up at console.anthropic.com and create an API key (starts with sk-ant-...)
  2. 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 .env file is listed in .gitignore and 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

novalab_adk-1.1.0.tar.gz (43.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

novalab_adk-1.1.0-py3-none-any.whl (40.4 kB view details)

Uploaded Python 3

File details

Details for the file novalab_adk-1.1.0.tar.gz.

File metadata

  • Download URL: novalab_adk-1.1.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

Hashes for novalab_adk-1.1.0.tar.gz
Algorithm Hash digest
SHA256 b98a6593356720396c8b4220e1b425a5f8ec78865b059a4715076720bdfffbca
MD5 9430cd637a2f4d58ab95a457e405e8ae
BLAKE2b-256 cc95f79afe3be84f4b157a76a470caad738e367d29a7edf4996ac4c58bf55dea

See more details on using hashes here.

File details

Details for the file novalab_adk-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: novalab_adk-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 40.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for novalab_adk-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 30463ffb1690c1fce3e7826ea728bc69fd838f904e3477fe9d8976e9f8e8e60f
MD5 1668416fae3b65c44aededb1e54d01c9
BLAKE2b-256 a8d88e36edbf0707ca8f75edc5fdf37f08cc4bfb6c9758d7e226ebcd2eb3b974

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page