惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V2EX - 技术
V2EX - 技术
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
S
Securelist
P
Privacy & Cybersecurity Law Blog
Scott Helme
Scott Helme
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
量子位
博客园 - Franky
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
T
Troy Hunt's Blog
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
N
Netflix TechBlog - Medium
小众软件
小众软件
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学
L
Lohrmann on Cybersecurity
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Last Watchdog
The Last Watchdog
S
Security @ Cisco Blogs
P
Privacy International News Feed
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
T
Tailwind CSS Blog
博客园_首页
云风的 BLOG
云风的 BLOG
V
Vulnerabilities – Threatpost
D
DataBreaches.Net
Recent Announcements
Recent Announcements
酷 壳 – CoolShell
酷 壳 – CoolShell
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
罗磊的独立博客
Engineering at Meta
Engineering at Meta
Forbes - Security
Forbes - Security
T
Tenable Blog

Hacker News: Show HN

PurrrrrFocus: Pomodoro Timer App - App Store Workflow Engine — Multi-Step Orchestration for Bun RapidPhoto: Pro Photo Editor App - App Store GitHub - DheerG/swarms: Achieve extraordinary results with claude code across a variety of tasks SPICE simulation → oscilloscope → verification with Claude Code — Lucas Gerads Show HN: VCoding – A 5 MB native Windows IDE with no dynamic dependencies Show HN: LLMs don't hallucinate because they're bad at math, it's the format GitHub - Agent-FM/agentfm-core: AgentFM is a peer-to-peer network that turns everyday computers into a decentralized AI supercomputer. AgentFM lets you run massive AI workloads directly across a global mesh of idle CPUs and GPUs. Show HN: Tracking Top US Science Olympiad Alumni over Last 25 Years GitHub - Potarix/agent-hub: One place to talk to all your agents Show HN: Runtime security for AI agents(injection,tool abuse, data exfiltration) GitHub - dubeyKartikay/lazyspotify: Terminal Spotify client for macOS and Linux GitHub - the-banana-tool/king-louie: Easy to use GUI Personal AI Assistant. Win/Linux/Mac. Show HN I made my vacation rental bookable by AI agents–no Airbnb, 0% commission GitHub - basteez/jsf-autoreload: maven plugin to enable hot reload on jsf projects uvm32/hosts/host-gdbstub at main · ringtailsoftware/uvm32 GitHub - labsai/EDDI: Config-driven engine that turns JSON into production-grade AI agents. Multi-agent orchestration, 12+ LLM providers, MCP/A2A protocols, RAG, persistent memory, and enterprise compliance (EU AI Act, GDPR, HIPAA). Built on Quarkus. GitHub - glitchnsec/fortyone-oss: AI Executive Assistant Platform Quickstart | Alien GitHub - muxshed/shed: One stream in, or many. Every destination, simultaneously. No cloud middleman, no per-channel fees, no limits. GitHub - ocrbase-hq/ocrbase: 📄 PDF/IMG ->.MD/JSON Document OCR API for PaddleOCR and GLMOCR. Self-hostable. GitHub - impactjo/home-memory: MCP server that lets your AI assistant remember everything about your home. GitHub - Sets88/dbcls: DbCls is a powerful terminal database client that supports various databases GitHub - neptun2000/heor-agent-mcp GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh RollQuation: Math Puzzles - Apps on Google Play GitHub - dropbox/witchcraft Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis GitHub - opentalon/opentalon: OpenTalon is an open-source platform built from the ground up in Go as a robust alternative to OpenClaw LinkedIn™ 职位抓取工具 - Chrome 应用商店 GitHub - EdoardoBambini/Agent-Armor-Iaga: AI agents are getting tool access — shell, file system, databases, APIs, secrets. But **nobody is governing what they actually do with it**. Frameworks like LangChain, CrewAI, AutoGen, and Claude Code give agents the power to execute. Agent Armor gives you the power to control, audit, and approve every single action before it happens. HN Vibes — Week 15, Apr 7–13 2026 GitHub - chojs23/ec: Easy terminal-native 3-way git mergetool vim-like workflow GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. GitHub - JakOb-dotcom/cloud-sandbox-security-analysis: Technical analysis and Proof of Concept (PoC) regarding environment variable exfiltration in containerized cloud sandboxes via side-channel data leaks. Springboards - Flint Alpha Show HN: A simpler coding agent harness GitHub - audiodude/sudomake-friends GitHub - 256thFission/mini-mythos: OSS clone of Anthropic’s Mythos harness to locate C/C++ memory vulnerabilities Show HN: OpenParallax: OS-level privilege separation for AI agent execution Hacker News Sorted - Chrome 应用商店 Show HN: How to Install Docker on Ubuntu 24.04 LTS: Complete 2026 Guide GitHub - himanshudongre/smriti GitHub - sverrirsig/claude-control: macOS desktop dashboard for monitoring and managing multiple Claude Code sessions GitHub - ory/dockertest: Write better integration tests! Dockertest helps you boot up ephermal docker images for your Go tests with minimal work. Chiral - Chrome 应用商店 Show HN: Two Claudes collaborating through shared memory on a $100 mini-PC GitHub - pmichaillat/latex-cv: Minimalist LaTeX template for academic CVs GitHub - oguzbilgic/posse: A web UI for Anthropic Managed Agents. GitHub - sshiraz/depsly: Dependency risk analysis tool for npm packages ABI Add safari/agent-harness — Safari browser automation via safari-mcp by achiya-automation · Pull Request #212 · HKUDS/CLI-Anything GitHub - Halfblood-Prince/trustcheck: Verify PyPI package attestations and improve Python supply-chain security GitHub - oguzbilgic/kern-ai: Agents that do the work and show it. GitHub - bruits/satteri: High-performance Markdown and MDX processing for the JavaScript ecosystem GitHub - tylergibbs1/feedstock: High-performance web crawler and scraper for TypeScript, powered by Bun and Playwright GitHub - Grimm67123/grimmbot: The self-improving sandboxed and open-source AI agent. With persistent memory and scheduling. GitHub - whitevanillaskies/whitebloom: Local whiteboard that blooms. GitHub - hwdsl2/docker-whisper: Docker image for a self-hosted Whisper speech-to-text server with speaker diarization and OpenAI-compatible transcription and translation APIs. Powered by faster-whisper. Supports all Whisper models, NVIDIA GPU (CUDA) acceleration, JSON/SRT/VTT output, SSE streaming, offline mode, and multi-arch (amd64, arm64). GitHub - yisding/reviewwiggum GitHub - MarwanAlsoltany/serrors: Structured errors for Go: sentinel hierarchies, typed data, custom formatting, and slog integration. GitHub - soatok/age-php GitHub - Luthiraa/markitme GitHub - stagas/rtdiff: realtime git diff gui and AI-assisted commits GitHub - tombedor/excalicharts GitHub - wh1le/excalidraw-edit: Open and edit .excalidraw files from the terminal. Offline, auto-saves to disk. MalExt Sentry - Malicious Extension Scanner - Chrome 应用商店 GitHub - syi0808/asciianimesvg: Generate animated ASCII art SVGs from text. CLI, Rust library, WASM, and web editor. GitHub - zaina-ml/ml_forge: A visual-based graph node editor for training computer vision models. GitHub - anakin87/llm-rl-environments-lil-course: 🌱 A little course on Reinforcement Learning Environments for evaluating and training Language Models GitHub - takaakit/superpowers-uml: Superpowers-UML modifies Superpowers to ensure a software development workflow in which AI agents design through UML modeling. AdriByte Studio - Sviluppo Web e Soluzioni Digitali GitHub - chouligi/angel-copilot: Your personalized Angel Investment Advisor Show HN: MoodSense AI (ML and FastAPI and Gradio, Deployed on Hugging Face) Moodsense Ai - a Hugging Face Space by aman179102 GitHub - agenteractai/lodmem: Level Of Detail Context Management for Agents GitHub - ostefani/subnetlens: A fast, concurrent network scanner with a TUI and plain-text CLI, built in Go. It discovers live hosts on your network, scans their open ports, resolves hostnames, and fingerprints operating systems—delivered. Cyber Pulse: Agentic Intel - Apps on Google Play Whisper API: Self-Hostable Speech to Text Transcription The Agent-Web Protocol Stack: A Research Thesis GitHub - msmarkgu/RelayFreeLLM: A restful API designed to route user prompts to various AI model providers. Show HN: Provepy – A Python decorator that proves your code using Lean and LLMs Show HN: Pardonned.com – A searchable database of US Pardons GitHub - patrickdappollonio/dux: Dux is a terminal UI that lets you run multiple AI coding agents side by side, each in its own git worktree, with full companion terminals, macros, commit generation, and a command palette that knows more tricks than you do. kMC Crystal Simulator Show HN: HyperFlow – A self-improving agent framework built on LangGraph GitHub - stef41/vibescore: 🎵 Grade your vibe-coded project. One command, instant letter grade across security, quality, dependencies, and testing. GitHub - stef41/lmscan: 🔍 Detect AI-generated text and fingerprint which LLM wrote it. Open-source GPTZero alternative. Zero dependencies, works offline. imgur.com GitHub - visionscaper/collabmem: Enabling long-term collaboration with Agentic AI - building up episodic and world model memory over time with in-context awareness 在 Steam 上购买 FriedrichAI: Offline AI 立省 10% GitHub - atripati/ark: AI Runtime Kernel — a context operating system for AI agents. Eliminates tool bloat, loads only what’s needed, and gives LLMs their reasoning space back. GitHub - nowork-studio/toprank: Open-source Claude Code skills for SEO, SEM, Google Ads GitHub - tacomanator/sash: Lightweight macOS menu bar app for reliably cycling through windows of the current application. Appents | Social Media Management for Product-First Teams GitHub - pnhoang/youtube-spam-blocker: Automatically detects and hides spam messages in YouTube Live chat. Set rate limits, keyword filters, and block repeat offenders. GitHub - decisionnode/DecisionNode: CLI + Local MCP - A shared structured memory store across Claude Code, Cursor, Windsurf, Antigravity, and every MCP client. Semantically queryable. GitHub - AvaCodeSolutions/django-email-learning: An open source Django app for creating email-based learning platforms with IMAP integration and React frontend components. The $100K Gap in Kubernetes Security Tooling Function Calling Harness: From 6.75% to 100%
smile/serve at master · haifengl/smile
haifeng · 2026-05-05 · via Hacker News: Show HN

SMILE Serve User Guide

SMILE Serve is a production-ready inference server built on Quarkus that brings together three complementary inference capabilities on the JVM:

Capability API prefix Description
Classic ML /api/v1/models Serialized SMILE models (.sml) — classifiers and regressors
ONNX Runtime /api/v1/onnx Any model in the ONNX open format (.onnx)
LLM Chat /api/v1/chat Llama 3 chat completions with conversation persistence

A React-based web UI is bundled and served from the same process.


Table of Contents

  1. Quick Start with Docker
  2. Building and Running
  3. Configuration Reference
  4. Classic ML Inference API
  5. ONNX Inference API
  6. LLM Chat API
  7. Web UI
  8. Database
  9. Testing

1. Quick Start with Docker

The fastest way to run SMILE Serve is via the pre-built Docker image. Mount a local directory containing your model files and map the port:

docker run -it \
  -v /path/to/model/folder:/model \
  -p 8888:8080 \
  ghcr.io/haifengl/smile-serve:latest

The service starts on port 8080 inside the container (mapped to 8888 on the host). Place your .sml and .onnx model files in /path/to/model/folder; they are discovered automatically at startup.


2. Building and Running

All commands use the Gradle wrapper from the project root.

2.1 Dev Mode

Live-reload development mode — changes to Java sources are reflected without restarting. The Quarkus Dev UI is available at http://localhost:8888/q/dev/.

./gradlew :serve:quarkusDev \
  --jvm-args="--add-opens java.base/java.lang=ALL-UNNAMED"

The --add-opens flags are required by ONNX Runtime's Foreign Function Interface. The dev-mode HTTP port defaults to 8888 (configured via %dev.quarkus.http.port).

2.2 Packaging as a JAR

./gradlew :serve:build

This produces a Quarkus layered application in build/quarkus-app/. The entry point is build/quarkus-app/quarkus-run.jar; the dependencies live in build/quarkus-app/lib/ and must be distributed together.

Run it with:

java \
  --add-opens java.base/java.lang=ALL-UNNAMED \
  --add-opens java.base/java.nio=ALL-UNNAMED \
  --enable-native-access ALL-UNNAMED \
  -jar build/quarkus-app/quarkus-run.jar

To run on a custom port:

java \
  --add-opens java.base/java.lang=ALL-UNNAMED \
  --add-opens java.base/java.nio=ALL-UNNAMED \
  --enable-native-access ALL-UNNAMED \
  -Dquarkus.http.port=3801 \
  -jar build/quarkus-app/quarkus-run.jar

2.3 Uber-JAR

A single self-contained JAR (slower to start, simpler to deploy):

./gradlew :serve:build -Dquarkus.package.jar.type=uber-jar
java \
  --add-opens java.base/java.lang=ALL-UNNAMED \
  --add-opens java.base/java.nio=ALL-UNNAMED \
  --enable-native-access ALL-UNNAMED \
  -jar build/smile-serve-runner.jar

2.4 Native Executable

Compile to a native binary with GraalVM (sub-millisecond startup, lower memory):

./gradlew :serve:build -Dquarkus.native.enabled=true
./build/smile-serve-*-runner

Without a local GraalVM installation, use a Docker-based build:

./gradlew :serve:build \
  -Dquarkus.native.enabled=true \
  -Dquarkus.native.container-build=true

See the Quarkus native build guide for details.


3. Configuration Reference

Configuration is managed in src/main/resources/application.properties. Quarkus profile prefixes (%dev., %test.) override the base values in the corresponding profiles.

Property Default Description
quarkus.http.port 8080 HTTP listen port (%dev default: 8888)
quarkus.rest.path /api/v1 Global REST path prefix
smile.serve.model ../model Path to a .sml file or directory of .sml files
smile.onnx.model ../model Path to a .onnx file or directory of .onnx files
smile.chat.model ../model/Llama3.1-8B-Instruct Directory containing the Llama model
smile.chat.tokenizer ../model/Llama3.1-8B-Instruct/tokenizer.model SentencePiece tokenizer path
smile.chat.max_seq_len 4096 Maximum sequence length in tokens
smile.chat.max_batch_size 1 Maximum generation batch size
smile.chat.device 0 GPU device index (%dev default: 7)
quarkus.datasource.db-kind postgresql Database backend for chat history
quarkus.datasource.jdbc.url jdbc:postgresql://localhost:5432/smile JDBC connection URL
quarkus.hibernate-orm.active false Enable ORM (set true when database is available)

Override at runtime with -D system properties, for example:

java ... -Dsmile.serve.model=/data/models/rf_classifier.sml -jar quarkus-run.jar

4. Classic ML Inference API

4.1 Model Format

Classic ML models are serialized Java objects saved in .sml files by the SMILE smile.model.Model framework. They carry:

  • The trained algorithm (random forest, SVM, gradient boost, etc.)
  • The input feature schema (field names and data types)
  • Training / validation metrics
  • Optional metadata tags (id, version, user-defined properties)

At startup, InferenceService scans the path specified by the property smile.serve.model. If the path is a regular .sml file only that model is loaded; if it is a directory every .sml file in the directory is loaded.

4.2 List Models

Returns the IDs of all loaded models in alphabetical order.

GET /api/v1/models

Example:

curl http://localhost:8080/api/v1/models
["iris_random_forest-1", "titanic_logistic-2"]

4.3 Get Model Metadata

Returns the algorithm name, input schema, and tags for a model.

GET /api/v1/models/{id}

Example:

curl http://localhost:8080/api/v1/models/iris_random_forest-1
{
  "id": "iris_random_forest-1",
  "algorithm": "random-forest",
  "schema": {
    "petallength": { "type": "float", "nullable": false },
    "petalwidth":  { "type": "float", "nullable": false },
    "sepallength": { "type": "float", "nullable": false },
    "sepalwidth":  { "type": "float", "nullable": false }
  },
  "tags": {
    "smile.random_forest.trees": "200"
  }
}

The schema object lists every input feature in alphabetical order — this is the column order used by the CSV streaming endpoint.

4.4 Single Inference (JSON)

Send one sample as a JSON object and receive the prediction synchronously.

POST /api/v1/models/{id}
Content-Type: application/json

The request body is a flat JSON object whose keys are the feature names defined in the model schema. All non-nullable fields are required.

Classification example (iris):

curl -X POST http://localhost:8080/api/v1/models/iris_random_forest-1 \
  -H "Content-Type: application/json" \
  -d '{
    "sepallength": 5.1,
    "sepalwidth":  3.5,
    "petallength": 1.4,
    "petalwidth":  0.2
  }'
{
  "prediction": 0,
  "probabilities": [0.960, 0.021, 0.019]
}
  • prediction — the predicted class label (integer) or regression value (float).
  • probabilities — posterior class probabilities for soft classifiers (e.g. random forest, logistic regression). Absent for hard classifiers and regressors.

Error responses:

HTTP Cause
400 Bad Request Missing required field, or malformed JSON
404 Not Found Unknown model ID

4.5 Streaming Inference (CSV / JSON-lines)

Process many samples in a single request. The server returns results as a Server-Sent Events stream — one data: line per input sample.

POST /api/v1/models/{id}/stream
Content-Type: text/plain          ← CSV mode
Content-Type: application/json   ← JSON-lines mode

CSV mode (text/plain)

Each non-blank line is a comma-separated row of feature values in the same column order as the model schema (alphabetical by field name, as shown by GET /api/v1/models/{id}).

cat iris.csv | curl -X POST \
  -H "Content-Type: text/plain" \
  --data-binary @- \
  http://localhost:8080/api/v1/models/iris_random_forest-1/stream

Where iris.csv might contain:

5.1,3.5,1.4,0.2
6.7,3.0,5.2,2.3
5.8,2.7,4.1,1.0

The response stream (SSE format):

data: 0 0.960 0.021 0.019

data: 2 0.012 0.051 0.937

data: 1 0.031 0.752 0.217

JSON-lines mode (application/json)

Each non-blank line must be a complete JSON object (one per line). This is more verbose but supports named fields in any order.

cat iris.jsonl | curl -X POST \
  -H "Content-Type: application/json" \
  --data-binary @- \
  http://localhost:8080/api/v1/models/iris_random_forest-1/stream

Where iris.jsonl contains:

{"sepallength":5.1,"sepalwidth":3.5,"petallength":1.4,"petalwidth":0.2}
{"sepallength":6.7,"sepalwidth":3.0,"petallength":5.2,"petalwidth":2.3}

4.6 Model IDs

A model's ID is constructed as <name>-<version> from the model's embedded metadata tags (smile.model.Model.ID and smile.model.Model.VERSION). If those tags are absent, the file name stem is used as the name and "1" as the version. For example, a file named iris_random_forest.sml with no ID tag gets the ID iris_random_forest-1.


5. ONNX Inference API

The ONNX endpoint exposes any model in the ONNX open format through SMILE's native ONNX Runtime binding (smile.onnx). This covers models exported from PyTorch, TensorFlow, scikit-learn (via sklearn-onnx), and many other frameworks.

5.1 Model Format

At startup, OnnxService scans the folder specified by the property smile.onnx.model. Every .onnx file found is loaded into an InferenceSession. The model ID is the file name without the .onnx extension (e.g., resnet50.onnx → ID resnet50).

5.2 List ONNX Models

GET /api/v1/onnx
curl http://localhost:8080/api/v1/onnx
["resnet50", "sentiment_bert"]

5.3 Get ONNX Model Info

Returns graph metadata and the typed, shaped input/output node descriptors.

GET /api/v1/onnx/{id}
curl http://localhost:8080/api/v1/onnx/resnet50
{
  "id": "resnet50",
  "graphName": "ResNet50",
  "description": "Image classification model",
  "version": 1,
  "inputs": [
    {
      "name": "input",
      "onnxType": "TENSOR",
      "elementType": "FLOAT",
      "shape": [1, 3, 224, 224]
    }
  ],
  "outputs": [
    {
      "name": "output",
      "onnxType": "TENSOR",
      "elementType": "FLOAT",
      "shape": [1, 1000]
    }
  ],
  "customMeta": {}
}

A shape value of -1 means that dimension is dynamic (determined at inference time from the input data).

5.4 Single Inference (JSON)

POST /api/v1/onnx/{id}
Content-Type: application/json

The request body is a JSON object mapping each input name to a flat JSON array of numbers. The server constructs the required ORT tensor from the declared element type and shape.

Example — image classification (resnet50, 1×3×224×224 = 150528 floats):

curl -X POST http://localhost:8080/api/v1/onnx/resnet50 \
  -H "Content-Type: application/json" \
  -d '{"input": [0.485, 0.456, 0.406, ...]}'

Response — a JSON object mapping each output name to a flat array:

{
  "output": [0.001, 0.002, 0.872, 0.003, ...]
}

Multi-input model example:

curl -X POST http://localhost:8080/api/v1/onnx/bert_classifier \
  -H "Content-Type: application/json" \
  -d '{
    "input_ids":      [101, 2054, 2003, 1996, 3007, 1997, 2605, 1029, 102],
    "attention_mask": [1,   1,    1,    1,    1,    1,    1,    1,    1  ],
    "token_type_ids": [0,   0,    0,    0,    0,    0,    0,    0,    0  ]
  }'

Supported input element types:

ONNX type JSON values ORT type
FLOAT numbers float[]
DOUBLE numbers double[]
INT32 integers int[]
INT64 integers long[]
INT8 / UINT8 / BOOL integers (0/1 for bool) byte[]

Error responses:

HTTP Cause
400 Bad Request Missing input, wrong element count, non-numeric values
404 Not Found Unknown model ID

5.5 Streaming Inference

Identical in structure to the classic ML streaming endpoint but returns JSON objects:

POST /api/v1/onnx/{id}/stream
Content-Type: text/plain          ← CSV floats for single-input models
Content-Type: application/json   ← JSON-lines for multi-input models

CSV (single-input models only):

cat features.csv | curl -X POST \
  -H "Content-Type: text/plain" \
  --data-binary @- \
  http://localhost:8080/api/v1/onnx/my_classifier/stream

Each response line is a compact JSON object:

data: {"output":[0.02,0.95,0.03]}

data: {"output":[0.88,0.07,0.05]}

JSON-lines (any number of inputs):

cat samples.jsonl | curl -X POST \
  -H "Content-Type: application/json" \
  --data-binary @- \
  http://localhost:8080/api/v1/onnx/bert_classifier/stream

5.6 Tensor Types and Shape Resolution

The server automatically resolves the ORT tensor shape from the model's declared input shape and the actual array length:

  • Fully static shape (no -1 dimensions) — the array length must exactly match the product of all dimensions. A mismatch returns HTTP 400.
  • Single dynamic dimension — the unknown dimension is inferred as arrayLength / product(staticDimensions). For example, a declared shape [-1, 3, 224, 224] with 150528 elements resolves to [1, 3, 224, 224].
  • Multiple dynamic dimensions — the shape is set to [1, arrayLength].
  • No shape info — the shape is set to [1, arrayLength].

6. LLM Chat API

SMILE Serve includes a Java implementation of Llama 3 for on-premise LLM inference. The chat API is designed to be compatible with the OpenAI Chat Completions interface.

The LLM is optional: if the path specified by the property smile.chat.model does not exist on the file system, ChatService starts in an unavailable state and every request to the chat endpoints returns HTTP 503 Service Unavailable.

6.1 Chat Completions

POST /api/v1/chat/completions
Content-Type: application/json

Tokens are streamed back as Server-Sent Events. The conversation (user message + assistant reply) is automatically persisted to the configured database after generation finishes.

Request body fields (snake_case):

Field Type Default Description
messages Message[] required Ordered dialog turns
conversation Long null Existing conversation ID to append to
max_tokens int 2048 Maximum new tokens to generate
temperature double 0.6 Sampling temperature (higher = more random)
top_p double 0.9 Nucleus-sampling threshold
logprobs boolean false Include log-probabilities
seed long 0 Random seed (0 = non-deterministic)
stream boolean true Reserved; always streams

Each Message has a role (system, user, or assistant) and content.

Example — single-turn:

curl -X POST http://localhost:8080/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "messages": [
      {"role": "system",  "content": "You are a helpful assistant."},
      {"role": "user",    "content": "What is the capital of France?"}
    ],
    "max_tokens": 256,
    "temperature": 0.7
  }'

The response is an SSE stream of plain-text token chunks ending when generation is complete.

Example — continue a previous conversation:

curl -X POST http://localhost:8080/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "conversation": 42,
    "messages": [
      {"role": "user", "content": "What about Germany?"}
    ]
  }'

6.2 Conversation History API

Chat history is stored in a relational database (PostgreSQL in production, SQLite in dev mode). The API base path is /api/v1/conversations.

List conversations

GET /api/v1/conversations?pageIndex=0&pageSize=25

Returns conversations in reverse-chronological order (newest first). Pagination parameters default to page 0 with 25 records per page.

curl "http://localhost:8080/api/v1/conversations?pageSize=10"

Get a single conversation

GET /api/v1/conversations/{id}

Returns the conversation record (metadata only, no messages). Returns 404 if the ID does not exist.

Get conversation messages

GET /api/v1/conversations/{id}/items?pageIndex=0&pageSize=25

Returns the individual message turns (role + content + createdAt) in chronological order.

curl http://localhost:8080/api/v1/conversations/42/items
[
  { "id": 1, "conversationId": 42, "role": "user",      "content": "What is the capital of France?", "createdAt": "2026-04-15T10:00:00Z" },
  { "id": 2, "conversationId": 42, "role": "assistant", "content": "The capital of France is Paris.", "createdAt": "2026-04-15T10:00:02Z" }
]

Create a conversation record manually

POST /api/v1/conversations
Content-Type: application/json

Useful for creating a labelled conversation before sending the first chat message. The server records the client IP and User-Agent automatically.

Delete a conversation

DELETE /api/v1/conversations/{id}

Returns 204 on success, 404 if not found.


7. Web UI

A React-based web interface is bundled via Quarkus Quinoa. It is served from the root URL and provides:

  • Inference UI (/infer) — select a loaded SMILE model from the sidebar, fill in the auto-generated form (derived from the model schema), and view the prediction result.
  • Chat UI (/chat) — a conversational interface for the Llama chat service with streaming token display and Markdown/math rendering.

In dev mode the React development server runs on port 5173 and requests are proxied to the Quarkus backend. The production build (dist/) is served statically by the Quarkus process.


8. Database

Chat conversation history requires a relational database.

Profile Backend URL
Production PostgreSQL jdbc:postgresql://localhost:5432/smile
Dev SQLite jdbc:sqlite:./smile_serve.db
Test H2 (in-memory) jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

To enable the database in production set:

quarkus.hibernate-orm.active=true
quarkus.datasource.username=<user>
quarkus.datasource.password=<password>

Hibernate ORM uses drop-and-create by default. Change the strategy in production to update or validate:

quarkus.hibernate-orm.schema-management.strategy=update

The database is not required for the ML or ONNX inference endpoints — only for chat conversation persistence.


9. Testing

./gradlew :serve:test

The test profile (%test.*) configures the service with:

  • An in-memory H2 database (no external database required).
  • A pre-trained iris random forest model from serve/src/test/resources/model/iris_random_forest.sml.
  • The ONNX model path also pointed at the test resources directory (no .onnx files present by default, so OnnxService starts empty).
  • The chat model path set to a non-existent path so ChatService starts gracefully unavailable without attempting to load a GPU model.

The test class InferenceResourceTest covers:

Test Endpoint Scenario
testListModels GET /models Returns the correct model IDs
testGetModelMetadata GET /models/{id} Returns algorithm, schema, and nullability
testGetUnknownModelReturns404 GET /models/{id} 404 for unknown ID
testPredictJsonReturnsPredictionAndProbabilities POST /models/{id} Correct label + probabilities
testPredictJsonWithZeroFeaturesReturnsValidPrediction POST /models/{id} Edge case: all-zero features
testPredictJsonMissingFieldReturns400 POST /models/{id} 400 for missing field
testPredictUnknownModelReturns404 POST /models/{id} 404 for unknown model
testStreamCsvReturnsPredictions POST /models/{id}/stream 3 CSV rows → 3 SSE data lines
testStreamJsonLinesReturnsPredictions POST /models/{id}/stream 2 JSON-lines → 2 SSE data lines
testStreamCsvTooFewColumnsEmitsNoPredictions POST /models/{id}/stream Bad CSV closes stream
testStreamUnknownModelReturns404 POST /models/{id}/stream 404 before stream starts

API Quick Reference

Classic ML — /api/v1/models

Method Path Description
GET /models List all loaded model IDs
GET /models/{id} Get model metadata and schema
POST /models/{id} Single JSON inference
POST /models/{id}/stream Streaming CSV or JSON-lines inference

ONNX — /api/v1/onnx

Method Path Description
GET /onnx List all loaded ONNX model IDs
GET /onnx/{id} Get graph info, input/output shapes
POST /onnx/{id} Single JSON inference
POST /onnx/{id}/stream Streaming CSV or JSON-lines inference

Chat — /api/v1/chat and /api/v1/conversations

Method Path Description
POST /chat/completions Streaming LLM chat completion (SSE)
GET /conversations List conversations (paginated)
GET /conversations/{id} Get conversation metadata
POST /conversations Create a conversation record
DELETE /conversations/{id} Delete a conversation
GET /conversations/{id}/items List message turns (paginated)

SMILE Serve is free software under the GNU General Public License v3. For commercial use enquiries contact smile.sales@outlook.com.