SDK Reference
Python and TypeScript SDKs for the LYDOS platform. Typed clients with retry, circuit breakers, and audit-trail integration.
Python (lydos-sdk v12.2.0b1) and TypeScript (@lydos/client v12.2.0-beta.1) clients for the LYDOS Sovereign AI Orchestration Platform REST API. Both ship in-repo only — the pip and npm packages are not yet published. Method signatures below come directly from the source tree, so they always match the running server.
Rate Limits
The shipped sliding-window limiter (core/infrastructure/rate_limiter_advanced.py) enforces per-tier limits keyed off the JWT / API-key subject. Defaults apply to the controlled beta; self-hosted deployments can override them via LYDOS_RATE_LIMIT_*environment variables. On HTTP 429 the server returns a Retry-Afterheader plus the X-RateLimit-Remaining and X-RateLimit-Reset hints.
| Tier | Requests / min | Burst | Who |
|---|---|---|---|
| anon | 30 RPM | 5 | Unauthenticated / public endpoints |
| auth | 120 RPM | 20 | Authenticated user (JWT or API key) |
| admin | 600 RPM | 60 | Admin RBAC role |
| service | 3000 RPM | 300 | Internal service tokens |
Python SDK
sdk-py/ folder of the repository. The distribution name is lydos-sdk (version 12.2.0), the import symbol is lydos. Requires Python 3.10+, httpx, tenacity, and pydantic v2. 3,800+ methods generated from the live OpenAPI spec.Installation
# From the repository root: cd sdk-py pip install -e . # Or install directly by path: pip install /path/to/AILYDIAN-AGENT-ORCHESTRATOR/sdk-py
Initialization
The package exports two clients with the same constructor signature: LydosClient (async, recommended) and LydosSyncClient (synchronous wrapper). Retries use exponential backoff via tenacity and are only triggered by ServerError, TimeoutError, and ConnectionError — never by auth failures.
import asyncio
from lydos import LydosClient
async def main() -> None:
# Anonymous (local development)
async with LydosClient(base_url="http://localhost:8888") as client:
health = await client.health()
print(health.overall_score, health.overall_status)
# With an API key
async with LydosClient(
base_url="http://localhost:8888",
api_key="lyd_sk_...",
timeout=30.0,
max_retries=3,
) as client:
agents = await client.list_agents()
print(f"{len(agents)} agents online")
asyncio.run(main())Synchronous Client
from lydos import LydosSyncClient
client = LydosSyncClient(base_url="http://localhost:8888")
try:
health = client.health()
print(f"Score: {health.overall_score}/100 ({health.overall_status})")
for module in health.modules[:5]:
print(f" {module.name}: {module.status} ({module.score})")
finally:
client.close()Authentication
login(username, password) → AuthResponse
Calls POST /api/q63/users/login. On success the JWT is applied to subsequent requests automatically — no need to call set_token.
auth = await client.login("operator", "s3cret")
print(auth.access_token[:24], "...")
print(auth.expires_in, "seconds")
print(auth.roles) # ['user', 'operator']
# Or set a pre-obtained JWT manually:
client.set_token("eyJhbGciOi...")Chat / LLM Gateway
chat(message, provider="auto", model=None, max_tokens=1024, temperature=0.7) → ChatResponse
Calls POST /api/groq/chat. Routes through the configured provider chain (Groq → Z.AI → NIM → Qwen3 by default). Streaming is not currently supported by either SDK.
reply = await client.chat(
"Summarise today's critical CVEs",
provider="auto",
max_tokens=512,
temperature=0.3,
)
print(reply.text) # str: unified accessor (content or response)
print(reply.provider) # str: groq | zai | nim | qwen3
print(reply.model) # str: model that served the request
print(reply.total_tokens) # int: prompt + completion tokens
print(f"{reply.latency_ms:.0f} ms")Agents
list_agents() → list[AgentInfo]
Calls GET /api/agents. Returns the full registry (13 Python-backed + 107 YAML-defined = 120+ registered agents in a default install).
agents = await client.list_agents()
for agent in agents:
print(f"{agent.agent_type}: {agent.name}")
print(f" status={agent.status} engine={agent.engine}")
print(f" capabilities={agent.capabilities}")run_agent(agent_type, input_data) → AgentResult
Calls POST /api/agents/{agent_type}/run. Executes synchronously and waits for the result. Use submit_task below for fire-and-forget work.
# SPEC-001 = HARIKA Doruk (maps to /api/agents/SPEC-001/run)
result = await client.run_agent(
"SPEC-001",
{
"task": "Analyse security posture of this codebase",
"path": "/workspace/app",
"depth": "comprehensive",
},
)
print(result.status) # 'success' | 'partial' | 'failed'
print(result.result) # primary textual output
print(result.output) # dict: structured output
print(f"{result.execution_time_ms:.0f} ms")Async Tasks (Q63)
submit_task(agent_type, payload) → TaskResponse
Calls POST /api/q63/users/tasks. Enqueues the task and returns immediately with a task_id for polling. Requires an authenticated session.
task = await client.submit_task(
"SPEC-001", # SPEC-001 = HARIKA Doruk
{"task": "scan_dependencies", "path": "/workspace/app"},
)
print(task.task_id, task.status) # 'queued'get_task(task_id) → TaskResponse
Calls GET /api/q63/users/tasks/{task_id}. Poll until status is completed, failed, or cancelled.
import asyncio
while True:
snapshot = await client.get_task(task.task_id)
if snapshot.status in {"completed", "failed", "cancelled"}:
break
await asyncio.sleep(2)
print(snapshot.status, snapshot.execution_time_ms, "ms")
if snapshot.status == "completed":
print(snapshot.result)
elif snapshot.status == "failed":
print("error:", snapshot.error)Semantic Memory
The memory API persists free-text entries with optional metadata and ranks them by relevance on search. Backed by POST /api/memory/store and GET /api/memory/search.
# Store an entry
mem = await client.store_memory(
"project_context: my-app runs on Next.js 16 + FastAPI",
metadata={"source": "sdk-py", "project": "my-app"},
)
print(mem.memory_id, mem.created_at)
# Search (ranked by relevance descending)
hits = await client.search_memory("Next.js stack", limit=5)
for hit in hits:
print(f"{hit.relevance:.2f} {hit.content[:60]}...")
print(f" tags={hit.tags} importance={hit.importance}")Health
health() → HealthResponse
Calls GET /api/health. Returns the composite score, a per-module breakdown, and aggregate counts.
health = await client.health()
print(health.overall_score) # int 0-100
print(health.overall_status) # 'excellent' | 'healthy' | 'degraded' | 'critical'
print(health.summary.total_modules, health.summary.ok)
for module in health.modules:
if module.status != "ok":
print(f"!! {module.name}: {module.status} — {module.details}")Error Handling
Every exception in lydos.exceptions inherits from LydosError. Catch specific subclasses for granular handling — server 4xx/5xx responses are mapped to structured exceptions automatically:
from lydos import LydosClient
from lydos.exceptions import (
LydosError,
AuthenticationError,
RateLimitError,
NotFoundError,
ValidationError,
ServerError,
ConnectionError,
TimeoutError,
)
async with LydosClient(base_url="http://localhost:8888") as client:
try:
reply = await client.chat("hello")
except AuthenticationError as err:
print(f"auth failed [{err.status_code}]: {err.detail}")
except RateLimitError as err:
wait = err.retry_after or 1.0
print(f"rate limited — retry after {wait:.1f}s")
except NotFoundError as err:
print(f"missing resource: {err.resource}")
except ValidationError as err:
print(f"bad request: {err.detail}")
except ConnectionError as err:
print(f"cannot reach {err.base_url}")
except TimeoutError as err:
print(f"{err.endpoint} timed out after {err.timeout}s")
except ServerError as err:
print(f"server error [{err.status_code}]: {err.detail}")
except LydosError as err:
print(f"sdk error: {err}")TypeScript SDK
GA · in-repo distribution
The TypeScript SDK ships inside sdk/generated/typescript/. Distribution name is @lydos/client (v12.2.0). 19,000+ lines generated from the live OpenAPI spec. The client is REST-only — there is no streaming or WebSocket surface. For memory, tasks, and async work, call the REST endpoints directly or use the Python SDK above.
Installation
# From the repository root: cd web/sdk/packages/client npm install npm run build # Link into another project: npm link # in web/sdk/packages/client npm link @lydos/client # in the consumer project
Initialization
The SDK ships a single LydosClient class. All retry options mirror fetchWithRetry in retry.ts. Retries are triggered only by the configured HTTP statuses (default: [408, 429, 500, 502, 503, 504]).
import { LydosClient } from "@lydos/client";
const client = new LydosClient({
baseURL: "http://localhost:8888",
apiKey: process.env.LYDOS_API_KEY,
timeout: 30_000,
retry: {
maxRetries: 3,
baseDelayMs: 500,
maxDelayMs: 5_000,
retryableStatuses: [408, 429, 500, 502, 503, 504],
jitter: true,
},
});Health
getHealth(): Promise<HealthStatus>
Calls GET /api/health. Returns a lightweight status envelope — for the full per-module breakdown use the Python SDK or call the REST endpoint directly.
const health = await client.getHealth(); console.log(health.healthy); // boolean console.log(health.status); // "ok" | "degraded" | "outage" | ... console.log(health.version); // server version string console.log(health.uptime); // e.g. "2d 14h 03m"
Capability Catalogue
The capability ledger tracks implementation, test, deploy, and health status for every platform feature. Use it to drive dashboards or gate releases.
// Roll-up stats
const stats = await client.getCapabilityStats();
console.log(stats.total, stats.implemented, stats.tested, stats.deployed);
console.log(stats.byCategory); // { engines: 245, agents: 120, ... }
// Filtered query
const deployedEngines = await client.queryCapabilities({
category: "engines",
status: "deployed",
});
for (const cap of deployedEngines) {
console.log(`${cap.id}: ${cap.name} [${cap.health_status}]`);
}
// Single record
const detail = await client.getCapability("q159");
console.log(detail.route_path, detail.risk_level);Agents
listAgents(filters?) | runAgent(agentId, options?)
listAgents accepts optional { category, status, type } filters. runAgent posts to /api/agents/run with { target?, async? } and returns the raw execution envelope.
// Filter agents by category
const security = await client.listAgents({ category: "security" });
for (const agent of security) {
console.log(`${agent.id} (${agent.type}) — ${agent.status}`);
}
// Synchronous run — SPEC-001 = HARIKA Doruk
const sync = await client.runAgent("SPEC-001", {
target: "/workspace/app",
async: false,
});
console.log(sync.status, sync.output ?? sync.error);
// Fire-and-forget
const queued = await client.runAgent("SPEC-001", {
target: "/workspace/app",
async: true,
});
console.log("queued as", queued.taskId, queued.status);Chat
chat(request: ChatRequest): Promise<ChatResponse>
Calls POST /api/llm/chat. Streaming is not supported.
const reply = await client.chat({
message: "Explain CVSS 4.0 in two sentences",
model: "llama-3.3-70b-versatile",
temperature: 0.3,
maxTokens: 512,
systemPrompt: "You are a concise security analyst.",
sessionId: "demo-session",
includeHistory: true,
});
console.log(reply.response); // string: generated text
console.log(reply.model); // string: model name
console.log(reply.sessionId); // string: server-side session id
console.log(reply.tokensUsed); // number: total tokens consumedMCP Tools & Config
Direct accessors for the MCP tool registry and the runtime configuration store.
// List MCP tools exposed by core/infrastructure/mcp_server.py
const { tools } = await client.getMcpTools();
console.log(`${tools.length} MCP tools`);
for (const tool of tools.slice(0, 5)) {
console.log(` ${tool.name} [${tool.category}] — ${tool.description}`);
}
// Runtime configuration
const entry = await client.getConfig("llm.primary_provider");
console.log(entry.key, "=", entry.value, `(${entry.type})`);
await client.setConfig("llm.primary_provider", "groq");
const all = await client.listConfig("llm.");
console.log(`${all.total} llm.* keys`);
const reloaded = await client.reloadConfig();
console.log("reloaded keys:", reloaded.reloadedKeys);Error Handling (TypeScript)
Every non-success response is wrapped in LydosClientError with the HTTP status code and raw response body. Retryable statuses are handled inside the client; non-retryable statuses and terminal retries surface the error to the caller.
import { LydosClient, LydosClientError } from "@lydos/client";
const client = new LydosClient({
baseURL: "http://localhost:8888",
apiKey: process.env.LYDOS_API_KEY,
});
try {
const reply = await client.chat({ message: "hello" });
console.log(reply.response);
} catch (err) {
if (err instanceof LydosClientError) {
console.error("HTTP", err.statusCode ?? "n/a", err.message);
if (err.response) {
console.error("body:", err.response);
}
} else {
throw err;
}
}Environment Variables
LYDOS_API_KEYAPI key for authenticated calls. Both SDKs also accept api_key / apiKey at construction.LYDOS_BASE_URLOverride the default http://localhost:8888.GROQ_API_KEYServer-side only — required by the LYDOS server to call the primary LLM provider.ZAI_API_KEYServer-side only — used by the Z.AI fallback provider.Need Help?
Start with the local docs bundled in the repository:
- Getting Started — local install + first request
- API Reference — REST endpoints and OpenAPI schema
- CLI Reference —
lydosCLI commands (incl.lydos truth) - SDK Landing Page — interactive playground