straylight-software/triton-tensorrt-llm

TensorRT-LLM inference on NVIDIA Triton for NixOS

0

stars

8

commits

Haskell

primary language

Mar 7, 2026

updated

Browse cluster: Haskell development tools and environments

README

triton-tensorrt-llm

TensorRT-LLM inference on NVIDIA Triton, with Servant-based tool server.

Components

PackageDescription
tool-serverServant API with OpenAPI3 — code sandbox, attestation, tools
openai-proxyHaskell AI Gateway — OpenAI-compatible chat completions
trtllm-validateEngine validation CLI
trtllm-engineTRT-LLM engine building infrastructure

Quick Start

# Run the demo (OpenAI Proxy + Tool Server + Open WebUI)
nix run github:straylight-software/triton-tensorrt-llm

# Point to your Triton server
nix run github:straylight-software/triton-tensorrt-llm -- --triton-url http://gpu-server:8000

# Then open http://localhost:3000 for chat UI

Individual Components

# OpenAI Proxy only
nix run .#openai-proxy

# Tool Server only (code sandbox + attestation)
nix run .#tool-server

# Open WebUI only
nix run .#open-webui

# Build a TRT-LLM engine (requires GPU)
nix build .#qwen3-32b-engine --option sandbox false

# Validate an engine
nix run .#trtllm-validate -- detect-quant /path/to/model

Demo

The default nix run starts a full stack:

ServicePortDescription
Open WebUI3000Chat interface
OpenAI Proxy9000OpenAI-compatible API
Tool Server9001Code sandbox + attestation
# Default: connects to localhost:8000 for Triton
nix run .

# Connect to remote Triton
nix run . -- --triton-url http://192.168.1.100:8000

# Custom model name
nix run . -- --model llama3

# Proxy only (no WebUI)
nix run . -- --proxy-only

Environment Variables

VariableDefaultDescription
TRITON_URLhttp://localhost:8000Triton server URL
MODEL_NAMEqwen3Model name
OPENAI_PROXY_PORT9000OpenAI proxy port
TOOL_SERVER_PORT9001Tool server port
OPEN_WEBUI_PORT3000Open WebUI port

Tool Server

The tool-server provides a Servant-based API with automatic OpenAPI 3.0 spec generation.

Features

  • Code Sandbox: Isolated workspaces for code editing and compilation
  • AST Operations: Pattern search/replace via ast-grep
  • Compilation: Type-check Rust, Haskell, Lean, Dhall, PureScript
  • Attestation: Ed25519 identity with signed git commits
  • Tools: Web search (SearXNG), URL reading (Jina)

Endpoints

MethodEndpointDescription
GET/healthHealth check
GET/openapi.jsonOpenAPI 3.0 specification
Code Sandbox
POST/code/workspaceCreate isolated workspace
GET/code/workspace/:idGet workspace info
GET/code/workspacesList all workspaces
POST/code/writeWrite file to workspace
POST/code/readRead file from workspace
GET/code/files/:workspace_idList files in workspace
POST/code/ast_searchAST pattern search
POST/code/ast_replaceAST pattern replace
POST/code/compileCompile/type-check file
Identity & Attestation
GET/identity/infoGet agent identity (fingerprint, DID)
POST/attestCreate signed attestation
GET/attest/logGet attestation chain
GET/attest/:commit/verifyVerify attestation signature
Tools
GET/tools/searchWeb search via SearXNG
GET/tools/code_searchCode-focused web search
GET/tools/read_urlRead URL content via Jina
Coeffects
GET/coeffects/manifestResource requirements per endpoint

Example Usage

# Start server
TOOL_SERVER_PORT=9001 nix run .#tool-server

# Get OpenAPI spec
curl http://localhost:9001/openapi.json | jq .

# Create workspace
curl -X POST http://localhost:9001/code/workspace \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": "my-project"}'

# Write a file
curl -X POST http://localhost:9001/code/write \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_id": "my-project",
    "path": "src/Main.hs",
    "content": "module Main where\n\nmain :: IO ()\nmain = putStrLn \"Hello\""
  }'

# Compile (type-check)
curl -X POST http://localhost:9001/code/compile \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": "my-project", "path": "src/Main.hs"}'

# AST search
curl -X POST http://localhost:9001/code/ast_search \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_id": "my-project",
    "pattern": "putStrLn $_",
    "language": "haskell"
  }'

# Create attestation (requires identity configured)
curl -X POST http://localhost:9001/attest \
  -H "Content-Type: application/json" \
  -d '{
    "attest_type": "task",
    "context": "Implemented feature X",
    "thought": "Considered approaches A and B, chose A for simplicity",
    "action": "Created 3 files, modified 2",
    "coeffects": {"filesystem": "readWrite", "network": "read"}
  }'

Supported Languages

The "Language Coset" for compilation:

LanguageExtensionCompilerCheck Mode
Rust.rsrustc--emit=metadata
Haskell.hs, .lhsghc-fno-code
Lean.leanlean--run
Dhall.dhalldhalltype
PureScript.purspurscompile

Architecture

lib/
├── CodeSandbox.hs    # Pure domain logic (reusable)
└── Attestation.hs    # Identity & signing (reusable)

tool-server/
├── API.hs            # Servant API type definition
├── API/Types.hs      # Request/Response with OpenAPI3 schemas
└── Server.hs         # Thin handlers over lib/

OpenAI Proxy

The openai-proxy provides an OpenAI-compatible interface to TensorRT-LLM.

Endpoints

EndpointDescription
POST /v1/chat/completionsChat completions (streaming & non-streaming)
GET /v1/modelsList available models
GET /healthHealth check
GET /tools/searchWeb search
GET /tools/read_urlURL reader

Configuration

Environment VariableDefaultDescription
OPENAI_PROXY_PORT9000Server port
TRITON_URLhttp://localhost:8000Triton backend URL
MODEL_NAMEqwen3Model name for API
SEARXNG_URLSearXNG instance URL
STRIP_THINKINGtrueStrip <think> blocks
METRICS_ENABLEDfalseEnable ClickHouse metrics

NixOS Module

The module is self-contained — it pulls in all dependencies including:

  • Triton server with TRT-LLM backend
  • OpenAI proxy (Haskell/Warp)
  • Tool server (Servant + OpenAPI3)
  • SearXNG (native, no Docker required)

Usage

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    triton-tensorrt-llm.url = "github:straylight-software/triton-tensorrt-llm";
  };

  outputs = { self, nixpkgs, triton-tensorrt-llm, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        # Apply the overlay to get packages
        { nixpkgs.overlays = [ triton-tensorrt-llm.overlays.default ]; }
        
        # Import the NixOS module
        triton-tensorrt-llm.nixosModules.default
        
        # Configure the service
        {
          services.triton-trtllm = {
            enable = true;
            model = "qwen3";
            enginePath = /var/lib/trtllm/engines/qwen3;
            
            triton = {
              enable = true;
              httpPort = 8000;
            };
            
            openaiProxy = {
              enable = true;
              port = 9000;
            };
            
            toolServer = {
              enable = true;
              port = 9001;
            };
            
            searxng.enable = true;  # Native SearXNG, no Docker
          };
        }
      ];
    };
  };
}

Module Options

OptionDefaultDescription
enablefalseEnable the service
model"qwen3"Model name for service identification
enginePathPath to TRT-LLM engine directory
triton.enabletrueEnable Triton server
triton.httpPort8000Triton HTTP port
openaiProxy.enabletrueEnable OpenAI proxy
openaiProxy.port9000OpenAI proxy port
toolServer.enablefalseEnable tool server
toolServer.port9001Tool server port
searxng.enablefalseEnable SearXNG (native)
searxng.port8888SearXNG port

Package Overrides

You can override packages if needed:

services.triton-trtllm = {
  enable = true;
  package.openaiProxy = myCustomProxy;
  package.toolServer = myCustomToolServer;
  # ...
};

Development

# Enter dev shell
nix develop

# Run tool-server tests
cd tool-server && cabal test

# Run openai-proxy property tests
nix build .#openai-proxy.tests.proxy-proptest

# Check flake
nix flake check

Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│   AI Agent /    │────▶│   tool-server    │────▶│   Compilers     │
│   Open WebUI    │     │   (port 9001)    │     │   ast-grep      │
└─────────────────┘     └──────────────────┘     └─────────────────┘
        │                        │
        │               ┌────────┴────────┐
        │               ▼                 ▼
        │         ┌──────────┐     ┌────────────┐
        │         │ Identity │     │ Attestation│
        │         │ Ed25519  │     │ Git Repo   │
        │         └──────────┘     └────────────┘
        │
        ▼
┌──────────────────┐     ┌─────────────────┐
│   openai-proxy   │────▶│  Triton Server  │
│   (port 9000)    │     │   (port 8000)   │
└────────┬─────────┘     └─────────────────┘
         │
┌────────┼────────┐
▼        ▼        ▼
┌─────────┐ ┌──────────┐ ┌─────────┐
│ SearXNG │ │   Jina   │ │ Metrics │
│ (8888)  │ │ (remote) │ │ (CH)    │
└─────────┘ └──────────┘ └─────────┘

Coeffects

The tool-server tracks resource requirements (coeffects) per endpoint:

{
  "tools": {
    "code/compile": {"filesystem": "readWrite"},
    "code/ast_search": {"filesystem": "read"},
    "code/ast_replace": {"filesystem": "readWrite"},
    "attest": {"filesystem": "readWrite", "crypto": "sign"},
    "tools/search": {"network": "read"},
    "tools/read_url": {"network": "read"}
  },
  "algebra": "Coeffect semiring: (R, join, 0, meet, 1)"
}

This supports the Aleph coeffect system for provenance tracking.


License

MIT

Contributors

b7r6

8 commits

straylight-software/triton-tensorrt-llm

TensorRT-LLM inference on NVIDIA Triton for NixOS

0

stars

8

commits

Haskell

primary language

Mar 7, 2026

updated

Browse cluster: Haskell development tools and environments

README

triton-tensorrt-llm

TensorRT-LLM inference on NVIDIA Triton, with Servant-based tool server.

Components

PackageDescription
tool-serverServant API with OpenAPI3 — code sandbox, attestation, tools
openai-proxyHaskell AI Gateway — OpenAI-compatible chat completions
trtllm-validateEngine validation CLI
trtllm-engineTRT-LLM engine building infrastructure

Quick Start

# Run the demo (OpenAI Proxy + Tool Server + Open WebUI)
nix run github:straylight-software/triton-tensorrt-llm

# Point to your Triton server
nix run github:straylight-software/triton-tensorrt-llm -- --triton-url http://gpu-server:8000

# Then open http://localhost:3000 for chat UI

Individual Components

# OpenAI Proxy only
nix run .#openai-proxy

# Tool Server only (code sandbox + attestation)
nix run .#tool-server

# Open WebUI only
nix run .#open-webui

# Build a TRT-LLM engine (requires GPU)
nix build .#qwen3-32b-engine --option sandbox false

# Validate an engine
nix run .#trtllm-validate -- detect-quant /path/to/model

Demo

The default nix run starts a full stack:

ServicePortDescription
Open WebUI3000Chat interface
OpenAI Proxy9000OpenAI-compatible API
Tool Server9001Code sandbox + attestation
# Default: connects to localhost:8000 for Triton
nix run .

# Connect to remote Triton
nix run . -- --triton-url http://192.168.1.100:8000

# Custom model name
nix run . -- --model llama3

# Proxy only (no WebUI)
nix run . -- --proxy-only

Environment Variables

VariableDefaultDescription
TRITON_URLhttp://localhost:8000Triton server URL
MODEL_NAMEqwen3Model name
OPENAI_PROXY_PORT9000OpenAI proxy port
TOOL_SERVER_PORT9001Tool server port
OPEN_WEBUI_PORT3000Open WebUI port

Tool Server

The tool-server provides a Servant-based API with automatic OpenAPI 3.0 spec generation.

Features

  • Code Sandbox: Isolated workspaces for code editing and compilation
  • AST Operations: Pattern search/replace via ast-grep
  • Compilation: Type-check Rust, Haskell, Lean, Dhall, PureScript
  • Attestation: Ed25519 identity with signed git commits
  • Tools: Web search (SearXNG), URL reading (Jina)

Endpoints

MethodEndpointDescription
GET/healthHealth check
GET/openapi.jsonOpenAPI 3.0 specification
Code Sandbox
POST/code/workspaceCreate isolated workspace
GET/code/workspace/:idGet workspace info
GET/code/workspacesList all workspaces
POST/code/writeWrite file to workspace
POST/code/readRead file from workspace
GET/code/files/:workspace_idList files in workspace
POST/code/ast_searchAST pattern search
POST/code/ast_replaceAST pattern replace
POST/code/compileCompile/type-check file
Identity & Attestation
GET/identity/infoGet agent identity (fingerprint, DID)
POST/attestCreate signed attestation
GET/attest/logGet attestation chain
GET/attest/:commit/verifyVerify attestation signature
Tools
GET/tools/searchWeb search via SearXNG
GET/tools/code_searchCode-focused web search
GET/tools/read_urlRead URL content via Jina
Coeffects
GET/coeffects/manifestResource requirements per endpoint

Example Usage

# Start server
TOOL_SERVER_PORT=9001 nix run .#tool-server

# Get OpenAPI spec
curl http://localhost:9001/openapi.json | jq .

# Create workspace
curl -X POST http://localhost:9001/code/workspace \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": "my-project"}'

# Write a file
curl -X POST http://localhost:9001/code/write \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_id": "my-project",
    "path": "src/Main.hs",
    "content": "module Main where\n\nmain :: IO ()\nmain = putStrLn \"Hello\""
  }'

# Compile (type-check)
curl -X POST http://localhost:9001/code/compile \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": "my-project", "path": "src/Main.hs"}'

# AST search
curl -X POST http://localhost:9001/code/ast_search \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_id": "my-project",
    "pattern": "putStrLn $_",
    "language": "haskell"
  }'

# Create attestation (requires identity configured)
curl -X POST http://localhost:9001/attest \
  -H "Content-Type: application/json" \
  -d '{
    "attest_type": "task",
    "context": "Implemented feature X",
    "thought": "Considered approaches A and B, chose A for simplicity",
    "action": "Created 3 files, modified 2",
    "coeffects": {"filesystem": "readWrite", "network": "read"}
  }'

Supported Languages

The "Language Coset" for compilation:

LanguageExtensionCompilerCheck Mode
Rust.rsrustc--emit=metadata
Haskell.hs, .lhsghc-fno-code
Lean.leanlean--run
Dhall.dhalldhalltype
PureScript.purspurscompile

Architecture

lib/
├── CodeSandbox.hs    # Pure domain logic (reusable)
└── Attestation.hs    # Identity & signing (reusable)

tool-server/
├── API.hs            # Servant API type definition
├── API/Types.hs      # Request/Response with OpenAPI3 schemas
└── Server.hs         # Thin handlers over lib/

OpenAI Proxy

The openai-proxy provides an OpenAI-compatible interface to TensorRT-LLM.

Endpoints

EndpointDescription
POST /v1/chat/completionsChat completions (streaming & non-streaming)
GET /v1/modelsList available models
GET /healthHealth check
GET /tools/searchWeb search
GET /tools/read_urlURL reader

Configuration

Environment VariableDefaultDescription
OPENAI_PROXY_PORT9000Server port
TRITON_URLhttp://localhost:8000Triton backend URL
MODEL_NAMEqwen3Model name for API
SEARXNG_URLSearXNG instance URL
STRIP_THINKINGtrueStrip <think> blocks
METRICS_ENABLEDfalseEnable ClickHouse metrics

NixOS Module

The module is self-contained — it pulls in all dependencies including:

  • Triton server with TRT-LLM backend
  • OpenAI proxy (Haskell/Warp)
  • Tool server (Servant + OpenAPI3)
  • SearXNG (native, no Docker required)

Usage

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    triton-tensorrt-llm.url = "github:straylight-software/triton-tensorrt-llm";
  };

  outputs = { self, nixpkgs, triton-tensorrt-llm, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        # Apply the overlay to get packages
        { nixpkgs.overlays = [ triton-tensorrt-llm.overlays.default ]; }
        
        # Import the NixOS module
        triton-tensorrt-llm.nixosModules.default
        
        # Configure the service
        {
          services.triton-trtllm = {
            enable = true;
            model = "qwen3";
            enginePath = /var/lib/trtllm/engines/qwen3;
            
            triton = {
              enable = true;
              httpPort = 8000;
            };
            
            openaiProxy = {
              enable = true;
              port = 9000;
            };
            
            toolServer = {
              enable = true;
              port = 9001;
            };
            
            searxng.enable = true;  # Native SearXNG, no Docker
          };
        }
      ];
    };
  };
}

Module Options

OptionDefaultDescription
enablefalseEnable the service
model"qwen3"Model name for service identification
enginePathPath to TRT-LLM engine directory
triton.enabletrueEnable Triton server
triton.httpPort8000Triton HTTP port
openaiProxy.enabletrueEnable OpenAI proxy
openaiProxy.port9000OpenAI proxy port
toolServer.enablefalseEnable tool server
toolServer.port9001Tool server port
searxng.enablefalseEnable SearXNG (native)
searxng.port8888SearXNG port

Package Overrides

You can override packages if needed:

services.triton-trtllm = {
  enable = true;
  package.openaiProxy = myCustomProxy;
  package.toolServer = myCustomToolServer;
  # ...
};

Development

# Enter dev shell
nix develop

# Run tool-server tests
cd tool-server && cabal test

# Run openai-proxy property tests
nix build .#openai-proxy.tests.proxy-proptest

# Check flake
nix flake check

Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│   AI Agent /    │────▶│   tool-server    │────▶│   Compilers     │
│   Open WebUI    │     │   (port 9001)    │     │   ast-grep      │
└─────────────────┘     └──────────────────┘     └─────────────────┘
        │                        │
        │               ┌────────┴────────┐
        │               ▼                 ▼
        │         ┌──────────┐     ┌────────────┐
        │         │ Identity │     │ Attestation│
        │         │ Ed25519  │     │ Git Repo   │
        │         └──────────┘     └────────────┘
        │
        ▼
┌──────────────────┐     ┌─────────────────┐
│   openai-proxy   │────▶│  Triton Server  │
│   (port 9000)    │     │   (port 8000)   │
└────────┬─────────┘     └─────────────────┘
         │
┌────────┼────────┐
▼        ▼        ▼
┌─────────┐ ┌──────────┐ ┌─────────┐
│ SearXNG │ │   Jina   │ │ Metrics │
│ (8888)  │ │ (remote) │ │ (CH)    │
└─────────┘ └──────────┘ └─────────┘

Coeffects

The tool-server tracks resource requirements (coeffects) per endpoint:

{
  "tools": {
    "code/compile": {"filesystem": "readWrite"},
    "code/ast_search": {"filesystem": "read"},
    "code/ast_replace": {"filesystem": "readWrite"},
    "attest": {"filesystem": "readWrite", "crypto": "sign"},
    "tools/search": {"network": "read"},
    "tools/read_url": {"network": "read"}
  },
  "algebra": "Coeffect semiring: (R, join, 0, meet, 1)"
}

This supports the Aleph coeffect system for provenance tracking.


License

MIT

Contributors

b7r6

8 commits

Languages

Haskell

55.9%

Nix

33.8%

Python

8.8%

Shell

1.5%