Skip to main content

model sdk built by the 9th ditrict at tooig

Project description

nineth

nineth is the Python SDK for the 1984 model API, built by the 9th District at Tooig.


Install

pip install nineth
export NINETH_API_KEY="your-api-key"

How it works

Every request goes through client.model.request(...).

  • Pass a task. Get a response.
  • Set stream=True to receive text as it arrives, word by word.
  • Everything else — caching, service routing, continuity — is handled server-side.

Models

Name Description
1984-m3-0317 Most capable. Best for research and complex tasks.
1984-m2-preview Fast and powerful. Good for most tasks.
1984-m2-light Lightweight, quick general tasks.
1984-m1-unified High-throughput unified model.
1984-m0-brute Compact efficient model.
1984-m0-sm Smallest model, fastest responses.

Set a default at client creation or pass model= per call.


Cookbook

1 — Get a response

The simplest case. Ask something, get the answer.

from nineth import NinethClient

with NinethClient(default_model="1984-m3-0317") as client:
    response = client.model.request("Give me a tight BTC market brief.")
    print(response["final_response"])

response is a plain dict. The text is always in response["final_response"].


2 — Stream the response live

Set stream=True to print text as it arrives.

from nineth import NinethClient

with NinethClient(default_model="1984-m3-0317") as client:
    for event in client.model.request("Summarise crude oil today.", stream=True):
        if event["type"] == "model_delta":
            print(event["data"]["text"], end="", flush=True)

The last event in the stream is type: result and contains the full final_response alongside iterations.


3 — Choose a different model per request

from nineth import NinethClient

with NinethClient() as client:
    response = client.model.request(
        "What happened with Nvidia earnings?",
        model="1984-m2-light",
    )
    print(response["final_response"])

4 — Control reasoning depth

Use reasoning to hint at how deeply the model should think before answering. Valid values: "low", "medium", "high". Leave it out to use the model default.

from nineth import NinethClient

with NinethClient(default_model="1984-m3-0317") as client:
    response = client.model.request(
        "Analyse the macro impact of a Fed rate pause.",
        reasoning="high",
    )
    print(response["final_response"])

5 — Show the model's reasoning

Set show_reasoning=True to include the model's internal chain-of-thought. This is off by default.

from nineth import NinethClient

with NinethClient(default_model="1984-m3-0317") as client:
    response = client.model.request(
        "Walk me through whether gold is trending or ranging.",
        reasoning="medium",
        show_reasoning=True,
    )
    for block in response.get("thinking", []):
        print("[thinking]", block)
    print(response["final_response"])

6 — Limit how many turns the model takes

max_iterations controls how many model turns the server runs. The default is 10. Most tasks finish in 1–3 turns.

from nineth import NinethClient

with NinethClient(default_model="1984-m3-0317") as client:
    response = client.model.request(
        "Give me a one-paragraph ETH brief.",
        max_iterations=2,
    )
    print(response["final_response"])

7 — Async usage

import asyncio
from nineth import AsyncNinethClient

async def main():
    async with AsyncNinethClient(default_model="1984-m3-0317") as client:
        response = await client.model.request(
            "Summarise macro risk factors this week.",
        )
        print(response["final_response"])

asyncio.run(main())

Async streaming works the same way:

import asyncio
from nineth import AsyncNinethClient

async def main():
    async with AsyncNinethClient(default_model="1984-m3-0317") as client:
        async for event in await client.model.request(
            "Research BTC ETF flows.", stream=True
        ):
            if event["type"] == "model_delta":
                print(event["data"]["text"], end="", flush=True)

asyncio.run(main())

8 — Health check

No API key needed. Use this to verify the endpoint is reachable.

from nineth import NinethClient

with NinethClient() as client:
    print(client.health())
# {'status': 'ok', 'timestamp': '2026-04-04T00:00:00+00:00'}

9 — Point the SDK at a different endpoint

from nineth import NinethClient

with NinethClient(
    base_url="https://your-deployment.modal.run",
    api_key="your-key",
    default_model="1984-m3-0317",
) as client:
    response = client.model.request("Hello.")
    print(response["final_response"])

Or use environment variables:

export NINETH_BASE_URL="https://your-deployment.modal.run"
export NINETH_MODEL="1984-m3-0317"

Response shape

Buffered (stream=False)

{
    "final_response": "Bitcoin is trading near...",
    "iterations": 2,
    "usage": {"prompt_tokens": 412, "completion_tokens": 88, "total_tokens": 500},
    "thinking": [],          # only populated when show_reasoning=True
    "service_calls": [...],
    "service_responses": [...],
    "events": [...],
}

Only final_response and iterations are guaranteed to be present on every response.

Streaming (stream=True)

Each loop iteration yields a dict:

# Text arriving live
{"type": "model_delta", "data": {"text": "Bitcoin is trading..."}}

# Tool calls the model made
{"type": "service_call",     "data": {"service_name": "search_web", "params": {...}}}
{"type": "service_response", "data": {"service_name": "search_web", "success": True, "summary": {...}}}

# Final summary — always the last event
{"type": "result", "data": {"final_response": "...", "iterations": 2}}

Error handling

from nineth import NinethClient, NinethAPIError

with NinethClient(default_model="1984-m3-0317") as client:
    try:
        response = client.model.request("Analyse ETH.")
    except NinethAPIError as exc:
        print("API error:", exc)
    except ValueError as exc:
        print("Configuration error:", exc)

Authentication

Set NINETH_API_KEY in your environment or pass api_key= to the client constructor. The health check endpoint does not require a key.

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

nineth-0.4.15.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

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

nineth-0.4.15-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file nineth-0.4.15.tar.gz.

File metadata

  • Download URL: nineth-0.4.15.tar.gz
  • Upload date:
  • Size: 9.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nineth-0.4.15.tar.gz
Algorithm Hash digest
SHA256 47d8c461039614b8ed4800962f01d5a12b61bd7db8e5810ad61dd925c5b9803f
MD5 90b0c458ac81045f13f084558065c249
BLAKE2b-256 1268f32213e2f40dc58032e0621e2a35cd658ca73fa7c7bff718ca38933db3e6

See more details on using hashes here.

File details

Details for the file nineth-0.4.15-py3-none-any.whl.

File metadata

  • Download URL: nineth-0.4.15-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nineth-0.4.15-py3-none-any.whl
Algorithm Hash digest
SHA256 d6f43e1022174fa826c1339ced2f1f145b8e22a826d3e0427c98c98e1be16b6e
MD5 0a6f7523d2637de5ba1dd6dc41461373
BLAKE2b-256 1b26dc37e1429967d72758d7316b87c65d3de0a0a261fc1f9058e20f39f2a0ae

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