model sdk built by the 9th ditrict at tooig
Project description
nineth
nineth is the public Python SDK for the 1984 model API.
This guide is caller-facing and SDK-specific.
If you maintain server internals, use README.md.
Table of Contents
- Install
- Quick Start
- Public Surface
- Client Construction
- Provider Notes
- Model Catalog
- Request Arguments (Complete)
- Payload Mapping Reference
- Callback Lifecycle Matrix
- Full End-to-End Request (All Parameters)
- Cookbook
- Response Shapes
- Error Handling
- Practical Patterns
- Troubleshooting
- Versioning and Compatibility
Install
pip install nineth
export NINETH_API_KEY="your-api-key"
Quick Start
1) Basic synchronous request
from nineth import NinethClient
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request("Give me a concise BTC market brief.")
print(response["final_response"])
Typical response shape:
{
"final_response": "BTC is range-bound with ...",
"iterations": 2,
"usage": {
"prompt_tokens": 1200,
"completion_tokens": 310,
"total_tokens": 1510
},
"service_calls": [],
"service_responses": [],
"events": []
}
2) Basic asynchronous request
import asyncio
from nineth import AsyncNinethClient
async def main() -> None:
async with AsyncNinethClient(default_model="1984-m3-0424") as client:
response = await client.model.request("Summarize crude oil in 5 bullets.")
print(response["final_response"])
asyncio.run(main())
3) Streaming request
from nineth import NinethClient
with NinethClient(default_model="1984-m3-0424") as client:
for event in client.model.request("Analyze ETH setup.", stream=True):
if event["type"] == "model_delta":
print(event["data"]["text"], end="", flush=True)
elif event["type"] == "result":
print("\n---")
print(event["data"]["final_response"])
Stream event types you should handle:
acceptedmodel_deltaservice_callservice_responseawaiting_client_services(manual callback mode)resulterror
Public Surface
Most applications only need:
NinethClientAsyncNinethClientclient.health()client.model.request(...)
AVAILABLE_MODELS is exported for convenience.
Client Construction
import httpx
from nineth import NinethClient
client = NinethClient(
base_url="https://weirdpablo--rooster-api.modal.run",
api_key="...",
default_model="1984-m3-0424",
timeout=httpx.Timeout(300.0, connect=10.0),
stream_timeout=httpx.Timeout(connect=10.0, read=None, write=60.0, pool=60.0),
headers={"X-Caller": "research-worker-1"},
)
Environment fallbacks:
NINETH_API_KEYNINETH_BASE_URLNINETH_DEFAULT_MODEL(orNINETH_MODEL)
Provider Notes
The SDK talks to the Rooster API endpoint. Provider routing happens server-side.
Common server provider modes:
- Together-backed models (slash-form provider model names)
- Ollama/cloud models (
:cloud/-cloudconventions) - OpenRouter models (
openrouter/<slug>or latest aliases like~openai/gpt-latest)
If your server is configured for OpenRouter, ensure OPENROUTER_API exists in the server runtime.
Example SDK request that targets an OpenRouter model slug:
from nineth import NinethClient
with NinethClient(default_model="openrouter/openai/gpt-4o") as client:
response = client.model.request("Summarize this incident report in 5 bullets.")
print(response["final_response"])
Model Catalog
Current SDK AVAILABLE_MODELS:
1984-m0-brute1984-m0-sm1984-m1-unified1984-m2-light1984-m2-preview1984-m3-03171984-m3-04041984-m3-04211984-m3-04241984-c0-0427
Request Arguments (Complete)
client.model.request(...) supports:
Task identity
task_input(required)model(optional if client default exists)
Generation controls
reasoning:disabled|low|medium|highshow_reasoning: include model reasoning outputtemperature,top_p,min_p,top_krepetition_penalty,presence_penalty,frequency_penaltyseed
Loop controls
max_iterationscontinuous
Inputs
images: list of base64 stringsaudio: list of base64 strings or objects{data, mime_type?, filename?}
Runtime controls
policy: caller runtime policy textguardrail: ADAM extension textbase_system: legacy provider-path compatibility control
Memory continuity
session: keep using the active SDK session for the same memory scopevcache: caller-owned persistent memory scope (name+cache_id) rooted at/knowledge/sdk/{name}/{cache_id}
Service controls
default_service:False,True, or allowlist listinclude_service: caller-managed list, or callback object viacallback: true/callback: false/callback: "https://..."client_service_results: manual callback resume payloadscallback_url: global callback URL
Output controls
streamresponse_format:text|jsoncomputeverbose(legacy alias:debug)
Messaging transport
messaging.emailmessaging.telegram
Payload Mapping Reference
_build_payload(...) in the SDK maps request arguments into the API payload with the following rules.
Core fields always emitted:
task_inputmodelmax_iterationsshow_reasoningcontinuous(continuousarg or derived asmax_iterations > 10)sessionbase_system(legacy compatibility)default_service(boolean or expanded/merged service list)verbose
Conditionally emitted fields:
reasoning->reasoning_efforttemperature->temperaturetop_p->top_pmin_p->min_ptop_k->top_krepetition_penalty->repetition_penaltypresence_penalty->presence_penaltyfrequency_penalty->frequency_penaltyseed->seedinclude_service->include_service(deduplicated list/object form;callback: falseis preserved)client_service_results->client_service_resultsimages->imagesaudio->audiopolicy->policyguardrail->guardrailmessaging-> normalizedmessagingcallback_url-> normalizedcallback_urlresponse_format="json"->response_format: "json"compute=True->compute: truevcache->vcache- remembered SDK session id ->
process_id(internal resume wire field whensession=True)
Validation rule:
client_service_resultsrequiressession=Trueand an already established session for that client + vcache scope.
Service auto-enable rule:
- Email messaging can auto-enable
send_email/send_replywhen outbound behavior is needed. - Telegram messaging auto-enables Telegram send/edit services.
Callback propagation rule:
- Top-level
callback_urlis normalized and propagated into email templates (inbound or outbound) missingurl. - If
include_serviceis list-form andcallback_urlexists, payload is promoted to object-form with callback + schema. - If
include_service.callbackisfalse, the SDK preserves that flag in the emitted object even when a globalcallback_urlis present. - If
include_service.callbackistrue, the SDK treats it as a mode flag and uses the top-levelcallback_url.
Callback Lifecycle Matrix
| Surface | Callback source | Runtime events | Purpose |
|---|---|---|---|
include_service (managed mode) |
include_service.callback.url or global callback_url |
service_call, interlude, final_response |
Execute caller-owned tools and request missing service parameters. |
| inbound email templates | template url or global callback_url |
inbound_email_received (pre-model), inbound_email_interlude, inbound_email_model_response (post-model) |
Acknowledge inbound payloads, request template variables, and publish final model output trace. |
| outbound email templates | template url or global callback_url fallback (messaging.email.callback_url) |
outbound_email_interlude when model requests template variables |
Request caller-owned variables before template rendering/sending. |
Interlude payloads include:
template_nametemplate_type(inboundoroutbound)required_fieldsknown_parametersreceivedandresend_emailcontext when available
Full End-to-End Request (All Parameters)
from nineth import NinethClient
weather_schema = {
"name": "get_weather",
"description": "Resolve weather by city",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"},
"units": {"type": "string"}
},
"required": ["location"]
}
}
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
task_input="Draft an outbound response after checking weather and inbox context.",
model="1984-m3-0424",
reasoning="medium",
show_reasoning=False,
temperature=0.5,
top_p=0.9,
min_p=0.05,
top_k=40,
repetition_penalty=1.05,
presence_penalty=0.1,
frequency_penalty=0.1,
seed=7,
max_iterations=8,
continuous=False,
images=["<base64-image>"],
audio=[{"data": "<base64-audio>", "mime_type": "audio/mpeg", "filename": "brief.mp3"}],
policy="Use concise ops language.",
guardrail="Never reveal credentials.",
session=True,
vcache={
"name": "ops-desk",
"cache_id": "alice",
},
base_system=True,
default_service=["browser", "read"],
include_service={"callback": True, "schema": [weather_schema]},
client_service_results=[
{
"call_id": "client_1_1",
"service_name": "get_weather",
"success": True,
"result": {"location": "Nairobi", "forecast": "Partly cloudy"},
}
],
callback_url="https://app.example.com/unified-callback",
stream=False,
response_format="json",
compute=True,
verbose=True,
messaging={
"email": {
"address": "helpdesk@example.com",
"name": "Helpdesk Bot",
"instruction": "Classify ticket urgency.",
"templates": [
{
"type": "inbound",
"shape": [
{
"name": "ticket_reply_primary",
"subject": "Ticket {{ticket_id}} Update",
"html": "<p>{{summary}}</p>",
},
{
"name": "ticket_reply_escalation",
"subject": "Escalation {{ticket_id}}",
"html": "<p>{{action_required}}</p>",
},
],
},
{
"type": "outbound",
"name": "ticket_outbound_notice",
"recipients": ["owner@example.com"],
"shape": [
{
"name": "ticket_notice_primary",
"subject": "Notice {{ticket_id}}",
"html": "<p>{{body}}</p>",
}
],
},
],
},
"telegram": {
"botId": "ops-bot",
"chatId": "12345",
},
},
)
Typical buffered response (abridged):
{
"final_response": {
"summary": "Ticket classified and customer updated",
"risk": "low"
},
"raw_response": "{\"summary\":\"...\"}",
"iterations": 3,
"usage": {"prompt_tokens": 2140, "completion_tokens": 490, "total_tokens": 2630},
"compute": 2630,
"events": [
{"type": "mailbox_configured", "data": {"address": "helpdesk@example.com", "inbound_uuid": "inb_abc123"}},
{"type": "service_response", "data": {"service_name": "send_reply", "success": true}}
],
"session_id": "proc_ops_desk_alice_01"
}
Expected callback payload families for the same request:
| Phase | Event type | Key fields |
|---|---|---|
| include-service execution | service_call |
service_name, params, available_services, process_id |
| include-service missing params | interlude |
service_name, required_fields, known_parameters, reason |
| include-service final | final_response |
final_response, process_id |
| inbound pre-model | inbound_email_received |
phase=pre_model, received, resend_email, available_templates |
| template variable fetch | inbound_email_interlude / outbound_email_interlude |
template_name, template_type, required_fields, known_parameters |
| inbound post-model | inbound_email_model_response |
phase=post_model, model_response, service_calls, service_responses |
Cookbook
Recipe 1: Health check
from nineth import NinethClient
with NinethClient() as client:
print(client.health())
Notes:
client.health()is API-key protected like other runtime endpoints.- If authentication is missing/invalid, the server returns auth errors rather than a public health payload.
- Server schema/docs endpoints are typically hidden in production unless the server is started with
ROOSTER_EXPOSE_OPENAPI=true.
Typical response:
{"status": "ok", "timestamp": "2026-05-24T00:00:00+00:00"}
Recipe 2: Per-request model override
with NinethClient(default_model="1984-m2-preview") as client:
a = client.model.request("fast summary")
b = client.model.request("deeper review", model="1984-m3-0424")
Recipe 3: Reasoning and sampling
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Build a scenario tree for BTC next week.",
reasoning="high",
temperature=0.4,
top_p=0.9,
seed=7,
)
Recipe 4: Request JSON output
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Return a JSON object with keys trend, risk, levels.",
response_format="json",
)
print(type(response["final_response"])) # dict if JSON parse succeeded
print(response.get("raw_response")) # original string is preserved
Typical JSON-mode response:
{
"final_response": {
"trend": "neutral",
"risk": "medium",
"levels": ["68000", "70000"]
},
"raw_response": "{\"trend\":\"neutral\",...}",
"iterations": 1
}
Recipe 5: Compute totals
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request("Explain carry trade risk.", compute=True)
print(response.get("compute"))
Recipe 6: Session continuity (session)
from nineth import NinethClient
with NinethClient(default_model="1984-m3-0424") as client:
first = client.model.request("Remember: my risk budget is medium.", session=True)
second = client.model.request(
"What risk budget did I set?",
session=True,
)
print(second["final_response"])
Important rule:
- keep using the same
NinethClientinstance when you wantsession=Trueto auto-reuse the latest session id.
Recipe 6b: Persistent memory partitions with vcache
from nineth import NinethClient
with NinethClient(default_model="1984-m3-0424") as client:
scoped = {"name": "research-team", "cache_id": "analyst-007"}
r1 = client.model.request(
"Remember that this workspace tracks only energy equities.",
session=True,
vcache=scoped,
)
r2 = client.model.request(
"What domain did I say this workspace tracks?",
session=True,
vcache=scoped,
)
print(r1["session_id"])
print(r2["final_response"])
vcache behavior:
- creates/uses
/knowledge/sdk/{name}/{cache_id}/...on the server - the filesystem scope persists independently of individual sessions
session=Truereuses only the hot conversational session for that vcache scope- starting a new session in the same vcache scope clears hot conversational state while keeping durable memory artifacts in that vcache path
Recipe 7: Built-in services with default_service
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Search web and summarize today's semiconductor headlines.",
default_service=["browser", "read"],
)
Notes:
default_service=Trueenables all built-ins.default_service=Falsedisables built-ins.- List mode accepts group aliases such as
browser,knowledge,computer,workspace,voice,trading,shop. - Alias expansion is automatic, and duplicate service names are deduplicated.
Recipe 8: Streaming with service progress
with NinethClient(default_model="1984-m3-0424") as client:
for event in client.model.request(
"Research AI gateway patterns and summarize.",
stream=True,
default_service=["browser", "read", "deepsearch"],
):
if event["type"] == "model_delta":
print(event["data"]["text"], end="")
elif event["type"] == "service_call":
print("\n[service]", event["data"]["service_name"])
elif event["type"] == "service_response":
print("\n[service done]", event["data"].get("service_name"))
Recipe 9: Caller-managed include services (manual resume)
weather_schema = {
"name": "get_weather",
"description": "Return weather for a city.",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"],
"additionalProperties": False,
},
}
with NinethClient(default_model="1984-m3-0424") as client:
first = client.model.request(
"Get weather for Lagos and summarize.",
include_service=[weather_schema],
)
if first.get("status") == "awaiting_client_services":
pending = first["pending_client_calls"]
# Execute pending client tools yourself.
manual_results = [
{
"call_id": pending[0]["call_id"],
"service_name": "get_weather",
"success": True,
"result": {"location": "Lagos", "forecast": "sunny"},
}
]
final = client.model.request(
"continue",
include_service=[weather_schema],
client_service_results=manual_results,
session=True,
)
Recipe 10: SDK-managed callback runtime (include_service object)
weather_schema = {
"name": "get_weather",
"description": "Return weather for a city.",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"],
},
}
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Get weather for Nairobi and summarize risk impact.",
include_service={
"callback": {"url": "https://app.example.com/api/callback"},
"schema": [weather_schema],
},
)
Recipe 10c: Caller-managed include-service payload (callback: false)
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Use the tool schema, but let the caller handle the calls.",
include_service={
"callback": False,
"schema": [weather_schema],
},
callback_url="https://app.example.com/global-callback",
)
In this mode the SDK preserves callback: false in the emitted object and does
not add the managed callback interlude schema.
Callback runtime events sent to your callback URL include:
service_callinterlude(missing caller-side parameters)final_response
Recipe 10b: Callback endpoint contract (request/response)
When include_service callback mode is active, your callback endpoint receives
JSON requests with idempotency metadata:
{
"event_type": "service_call",
"listener": "nineth_include_service_callback",
"idempotency_key": "<sha1>",
"process_id": "proc_abc123",
"call_id": "call_1",
"service_name": "get_weather",
"params": {"location": "Nairobi"},
"service": {
"name": "get_weather",
"description": "Return weather for a city.",
"parameters": {"type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"]}
},
"available_services": [{"name": "get_weather", "description": "..."}]
}
Your callback should return HTTP 200 with a JSON object.
Successful service response example:
{
"success": true,
"result": {
"location": "Nairobi",
"forecast": "Partly cloudy",
"temperature_c": 22
}
}
Interlude response example (ask caller for missing fields):
{
"success": true,
"parameters": {
"location": "Nairobi",
"units": "metric"
}
}
Failure response example:
{
"success": false,
"error": "Rate limit from upstream weather provider"
}
Notes:
- The SDK includes
X-Idempotency-Keyon callback HTTP requests. - Callback responses must be JSON objects; non-object JSON is treated as a callback error.
- The reserved interlude service name is
request_include_service_interlude.
Recipe 11: Local schema.py include-service references
include_service supports legacy local references:
- absolute or relative
schema.pypath - directory containing
schema.py - shorthand token discoverable from local
services/**/schema.py - manager class/object references from loaded schema modules
Example:
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Run local weather service.",
include_service=["./services/weather/schema.py"],
)
Recipe 12: Messaging (email + telegram)
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Draft and send the update.",
messaging={
"email": {
"address": "ops@example.com",
"name": "Ops Bot",
"instruction": "Reply with concise operational summaries.",
},
"telegram": {
"botId": "bot-1",
"chatId": "12345",
},
},
)
Auto-enable behavior:
- Telegram messaging config auto-enables Telegram delivery service names.
- Email messaging auto-enables email send services except inbound-only setup flows.
Recipe 12b: Messaging payload and result events
Example request emphasizing template payloads:
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Handle inbound request and reply.",
callback_url="https://app.example.com/mailbox-hook",
messaging={
"email": {
"address": "support@example.com",
"name": "Support Bot",
"instruction": "Classify and route inbound email.",
"templates": [
{
"type": "inbound",
"shape": {
"subject": "string",
"html": "<p>{{body}}</p>",
"text": "string",
"from": "string"
}
},
{
"type": "outbound",
"recipients": ["customer@example.com"],
"message": {
"subject": "Ticket update",
"body": "Issue resolved.",
"html": "<p>Issue resolved.</p>"
}
}
]
},
"telegram": {
"botId": "ops-bot",
"chatId": "12345"
}
},
)
Typical transport-side effect event fragments inside events:
[
{
"type": "mailbox_configured",
"data": {
"address": "support@example.com",
"inbound_uuid": "inb_abc123"
}
},
{
"type": "service_response",
"data": {
"service_name": "send_reply",
"success": true
}
}
]
Inbound UUID behavior:
- The SDK caches
mailbox_configuredinbound IDs by sender address per client instance. - Subsequent requests can automatically reuse the remembered
inbound_uuidfor the same address.
Recipe 13: Inbound/outbound email templates with global callback URL
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Configure mailbox templates.",
callback_url="https://app.example.com/mailbox-hook",
messaging={
"email": {
"address": "helpdesk@example.com",
"name": "Helpdesk Bot",
"templates": [
{
"type": "inbound",
"shape": {
"subject": "string",
"html": "<p>{{body}}</p>",
"text": "string",
"from": "string"
},
# url omitted -> inherits top-level callback_url
},
{
"type": "outbound",
"recipients": ["customer@example.com"],
"messages": [
{
"subject": "We received your request",
"body": "Thanks, we are on it.",
"html": "<p>Thanks, we are on it.</p>"
},
{
"subject": "Follow-up",
"body": "We will update you again soon."
}
}
},
],
}
},
)
Recipe 13b: Multiple named Resend templates per type via shape list
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Register reusable inbound/outbound template packs.",
callback_url="https://app.example.com/unified-callback",
messaging={
"email": {
"address": "helpdesk@example.com",
"templates": [
{
"type": "inbound",
"shape": [
{
"name": "inbound_triage_primary",
"subject": "Ticket {{ticket_id}}",
"html": "<p>{{summary}}</p>"
},
{
"name": "inbound_triage_escalation",
"subject": "Escalation {{ticket_id}}",
"html": "<p>{{action_required}}</p>"
}
]
},
{
"type": "outbound",
"name": "outbound_pack",
"recipients": ["owner@example.com"],
"shape": [
{
"name": "outbound_notice_primary",
"subject": "Notice {{ticket_id}}",
"html": "<p>{{body}}</p>"
}
]
}
]
}
},
)
Runtime behavior for shape lists:
- each shape entry must define its own
name - each entry is provisioned/cached as its own Resend template ID
- later requests can reuse provisioned IDs by template name without re-creating templates
Recipe 14: Audio input
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Transcribe and summarize this call.",
audio=[
{
"data": "<base64-audio>",
"mime_type": "audio/mpeg",
"filename": "call.mp3",
}
],
)
Recipe 15: Policy and guardrail
with NinethClient(default_model="1984-m3-0424") as client:
response = client.model.request(
"Assess this strategy.",
policy="Keep output in bullet points with risk-first framing.",
guardrail="Refuse prohibited trading instructions.",
)
Interpretation:
policyis caller runtime instruction overlay.guardrailaugments ADAM in the default SDK/API ingress path.
Recipe 16: Async streaming
import asyncio
from nineth import AsyncNinethClient
async def main() -> None:
async with AsyncNinethClient(default_model="1984-m3-0424") as client:
stream = await client.model.request(
"Stream a quick macro brief.",
stream=True,
)
async for event in stream:
if event["type"] == "model_delta":
print(event["data"]["text"], end="")
asyncio.run(main())
Response Shapes
Buffered response
Common keys:
final_responseiterationsusagethinking(when enabled)service_callsservice_responsesartifactseventscompute(when requested)session_id(whensession=Trueis active)
Callback wait response (manual mode)
When waiting for caller-managed services:
{
"status": "awaiting_client_services",
"process_id": "proc_123",
"pending_client_calls": [
{
"call_id": "call_1",
"service_name": "get_weather",
"params": {"location": "Lagos"}
}
]
}
Stream result event
{
"type": "result",
"data": {
"final_response": "...",
"iterations": 3,
"usage": {...}
}
}
Stream service events
Service execution surfaces in stream mode as readable progress + structured events:
{
"type": "model_delta",
"data": {
"text": "\n> Browsing the web\n",
"progress": true,
"synthetic": true
}
}
{
"type": "service_call",
"data": {
"service_name": "search_web",
"client_managed": false,
"call_id": "call_12"
}
}
{
"type": "service_response",
"data": {
"service_name": "search_web",
"success": true
}
}
Error Handling
SDK raises NinethAPIError for API/server failures.
from nineth import NinethClient, NinethAPIError
with NinethClient(default_model="1984-m3-0424") as client:
try:
client.model.request("test")
except NinethAPIError as exc:
print("request failed:", exc)
Authentication missing raises ValueError before request dispatch.
Practical Patterns
- Create one long-lived client per worker process to maximize HTTP connection reuse.
- Use
stream_timeoutwithread=Nonefor long-running SSE sessions. - Use
response_format="json"only when your prompt explicitly asks for strict JSON. - Prefer
default_service=[...]over broadTruein production to keep service scope tight. - For include-service workflows, choose one mode per integration:
- SDK-managed callback URL mode for autonomous orchestration.
- caller-managed mode when you need full deterministic control.
Troubleshooting
ValueError: Authentication required: setNINETH_API_KEYor passapi_key=.401/403 on health endpoint:/healthis protected; verifyNINETH_API_KEY(or explicitapi_key=) matches server-side key registry.ValueError: A model is required: set clientdefault_modelor passmodel=per request.client_service_results requires session=True: setsession=Trueand reuse the same client (and vcache scope, if provided) before sending callback results.- callback responses not progressing: verify callback endpoint returns HTTP 200 JSON object.
- stalled stream with include services: confirm pending calls are resumed via
client_service_results(manual mode) or callback endpoint handling (managed mode). 404 on /openapi.json or /docs: expected in hardened deployments. Ask operators to enableROOSTER_EXPOSE_OPENAPI=trueonly for controlled internal debugging.
Versioning and Compatibility
- Public SDK API is centered on
NinethClient,AsyncNinethClient,AVAILABLE_MODELS, andNinethAPIError. - Legacy aliases (
system_prompt,debug,services,service_names) remain compatibility surfaces but should be considered migration paths, not preferred new usage.
Maintainer Link
For server architecture and internal operations, see README.md.
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 nineth-0.7.1.tar.gz.
File metadata
- Download URL: nineth-0.7.1.tar.gz
- Upload date:
- Size: 42.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
144e8145bdbeed5ee10ac67a84fc5f9fd024fe2d2b248a863bff5b82424b6031
|
|
| MD5 |
cb10193e78130087825891f2d0cb067a
|
|
| BLAKE2b-256 |
159b5e0a9676ae58001a37119f035d94502257bbad44f14099487c53085dac34
|
File details
Details for the file nineth-0.7.1-py3-none-any.whl.
File metadata
- Download URL: nineth-0.7.1-py3-none-any.whl
- Upload date:
- Size: 35.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3eb8879fbc33e24ed3d3c13d8b9bbb285c2e7133c4e47a85d26d880fda856844
|
|
| MD5 |
d99f6e88337f84f856b6234956437777
|
|
| BLAKE2b-256 |
fe44e112c5f8af8af1f904b638e640d47b4f3c9b9605deb13c87a69573359228
|