API リファレンス
ollaya serve は http://localhost:11435 で 2 つの API を公開します。
/api/*配下のネイティブ API —— Ollama を手本にしたもので、決定とモデル管理に使います。/v1/*配下の TypeSafe 互換 API —— TypeSafe とワイヤ単位で同一なので、既存の TypeSafe SDK がそのまま動きます。詳しくは TypeSafe 互換を参照してください。
| メソッド | パス | 用途 |
|---|---|---|
GET, HEAD |
/ |
生存確認:Ollaya is running |
GET |
/api/version |
サーバーのバージョン |
POST |
/api/decide |
state に関する型付きの質問に答えます。モデルのロードとアンロードも行います |
GET |
/api/tags |
このマシン上のモデル |
POST |
/api/show |
1 つのモデルの詳細 |
GET |
/api/ps |
メモリにロード済みのモデル |
POST |
/api/pull |
モデルをダウンロードします(進捗をストリーミング) |
DELETE |
/api/delete |
モデルを削除します |
POST |
/api/copy |
モデルを新しい名前へコピーします |
POST |
/api/create |
別のモデルからモデルを作成します(進捗をストリーミング) |
POST |
/v1/systemone |
TypeSafe System One |
POST |
/v1/decisions |
/v1/systemone のエイリアス |
GET |
/v1/models |
TypeSafe のモデル一覧 |
/api/push と /api/blobs/:digest は予約済みで、501 NOT_IMPLEMENTED を返します。Ollama のテキスト系エンドポイント(/api/generate、/api/chat、/api/embed)は 404 を返します。決定モデルは決してテキストを生成しません。
規約
- JSON。 リクエストとレスポンスのボディは JSON オブジェクトです。
Content-Typeが何であれボディは JSON としてパースされるので、curl -dがそのまま使えます。リクエストは最大 8 MiB です。 - フィールド名は
snake_caseです。未知のリクエストフィールドは無視され、nullは不在を意味します。 - モデル名は
[host/][namespace/]model[:tag]で、大文字小文字を区別しません。タグを省略するとlatestを意味します。レスポンスは常に正規形(laya:latestなど)を使います。 - 数値。 確率、信頼度、
score、noulは小数点以下 4 桁に丸められます。継続時間はナノ秒単位の整数で、タイムスタンプは UTC の RFC 3339 です。 - ストリーミング。
/api/pullと/api/createは改行区切りの JSON をストリーミングし、1 行に 1 オブジェクト、末尾にちょうど 1 つの{"status":"success"}か 1 行のエラーを付けます。単一のレスポンスが必要なら"stream": falseを送ります。 - リクエスト ID。 すべてのレスポンスは
X-Request-Idを運び、/v1/*のレスポンスはx-typesafe-request-idも運びます。クライアントが送った有効なX-Request-Idはそのまま返されます。 - 並行性。 ロード済みのモデルは一度に 1 つのリクエストを実行し、各リクエストは自分のすべての質問に 1 パスで答えます。同じモデルへのリクエストはキューに入るので、一度に多く送っても早く終わりません。その場合、各リクエストの往復には待ち時間が含まれます。ある state についての質問は 1 つのリクエストにまとめてください。ロード済みの別々のモデルは並列に実行されます。
- 暗黙のプルはありません。 副作用としてモデルをダウンロードするエンドポイントはありません。
ollaya runは先にプルし、アプリケーションは/api/pullを呼びます。
エラー
すべてのエンドポイントのすべてのエラーは、このボディを持ちます。
{
"error": "model \"laya:xl\" not found, try pulling it first",
"code": "MODEL_NOT_FOUND"
}
| フィールド | 意味 |
|---|---|
error |
人が読めるメッセージ。パースしないでください。Ollama と同様、凍結された唯一のメッセージは model "<name>" not found, try pulling it first です。 |
code |
機械可読なコード。これで分岐してください。 |
detail |
INVALID_REQUEST、TOO_MANY_OPTIONS、INPUT_TOO_LONG、STATE_TRUNCATED のときだけ。すべての検証問題を TypeSafe(FastAPI)の ValidationError の形で表します:loc、msg、type、ときに ctx。 |
| コード | HTTP | いつ | 再試行 |
|---|---|---|---|
INVALID_JSON |
400 | ボディがない、JSON でない、オブジェクトでない | 不可 |
INVALID_REQUEST |
422 | ボディが検証に失敗する。detail がすべての問題を列挙 |
不可 |
TOO_MANY_OPTIONS |
422 | 質問の選択肢がモデルの選択肢予算に収まらない | 不可 |
INPUT_TOO_LONG |
422 | state が 65,536 トークンより長い |
不可 |
STATE_TRUNCATED |
422 | /v1/systemone または /v1/decisions が、モデルのコンテキストに収めるため state の一部を落とす |
不可 |
UNAUTHORIZED |
401 | OLLAYA_API_KEY が設定されていて、リクエストにキーがない |
不可 |
FORBIDDEN |
403 | ブラウザの Origin または Host ヘッダーが許可されていない |
不可 |
MODEL_NOT_FOUND |
404 | モデル(またはルーターのターゲット)がこのマシンにない。プルの場合はレジストリにない | 不可 |
NOT_FOUND |
404 | そのようなエンドポイントがない | 不可 |
METHOD_NOT_ALLOWED |
405 | エンドポイントは存在するがメソッドが違う | 不可 |
OPERATION_IN_PROGRESS |
409 | プルまたは作成が同じモデル名を書き込み中 | 完了後 |
REQUEST_TOO_LARGE |
413 | ボディが 8 MiB を超えている | 不可 |
QUEUE_FULL |
503 | OLLAYA_MAX_QUEUE 個のリクエストがすでに待機中。Retry-After: 1 を付けて返す |
可 |
MODEL_LOAD_FAILED |
500 | モデルをロードできなかった(ファイル破損、メモリ、OLLAYA_LOAD_TIMEOUT) |
まれに |
INFERENCE_FAILED |
500 | 決定中にランナーが失敗した | 可 |
STORAGE_ERROR |
500 | ディスク容量不足、権限、I/O | 不可 |
INTERNAL |
500 | バグ。サーバーログにリクエスト ID の下で詳細がある | 可 |
UNSUPPORTED_MODEL |
501 | このビルドではモデルの形式を実行できない | 不可 |
NOT_IMPLEMENTED |
501 | 予約済みエンドポイント | 不可 |
REGISTRY_ERROR |
502 | レジストリに到達できない、または無効 | 可 |
DIGEST_MISMATCH |
502 | ダウンロードが sha256 と一致せず破棄された | 可 |
コードの集合は開いています。未知のコードはその HTTP ステータスで処理してください。検証エラーはすべての問題を一度に列挙します。
{
"error": "state: Field required; questions.urgency.score.criteria: List should have at least 2 items after validation, not 1",
"code": "INVALID_REQUEST",
"detail": [
{"loc": ["body", "state"], "msg": "Field required", "type": "missing"},
{
"loc": ["body", "questions", "urgency", "score", "criteria"],
"msg": "List should have at least 2 items after validation, not 1",
"type": "too_short",
"ctx": {"field_type": "List", "min_length": 2, "actual_length": 1}
}
]
}
ストリームが始まったあと、失敗は同じ形の最終行として届きます(例:{"error": "…", "code": "DIGEST_MISMATCH"})。各行を進捗として読む前に、error を確認してください。
質問
/api/decide、/v1/systemone、/api/create は 1 つの質問スキーマ(TypeSafe のもの)を共有します。1 つのリクエストには1〜256 個の質問があり、任意の id をキーにします。答えは同じ順序で返ります。
type |
instructions |
criteria |
答え |
|---|---|---|---|
choice |
任意 | 必須:オブジェクト(ラベル → 説明)、またはラベルの配列。2〜255 個の選択肢 | choice、confidence、probabilities |
score |
任意 | 必須:レベルの説明の配列。レベル 0 が先頭。2〜10 個のレベル | score、confidence、legend、probabilities |
noul |
任意 | 任意:{"true": "…", "false": "…"} |
noul |
instructionsは文字列、オブジェクト、配列、またはnullです。省略またはnullのとき、モデルは代わりに質問 id を読みます。したがってis_spamのような説明的な id はそれだけで機能します。stateは文字列、オブジェクト、または配列で、最大 65,536 トークンです。モデルが使えるコンテキストを超えると、/api/decideはそれを切り詰め、state_truncated: trueを報告します。/v1/systemoneと/v1/decisionsは422 STATE_TRUNCATEDを返し、答えたモデルをdetail[0].ctx.modelに含めます。- モデルの制限。 すべての選択肢はモデルのコンテキストに余地を必要とします。
laya:en(512 トークン)で約 125 個、laya:multilingual(1,024)で 250 個です。それより多いと422 TOO_MANY_OPTIONSになります。ルーターの場合は、ターゲットの制限が適用されます。
答えは TypeSafe の形で、このフィールド順です。
type |
フィールド |
|---|---|
choice |
choice:最も確率の高いラベル。confidence。probabilities:ラベル → 確率。criteria の順。 |
score |
score:期待レベル Σ i·pᵢ で、レベルの間に来ることがあります。confidence。legend:"0"… → そのレベルの説明。probabilities:"0"… → 確率。 |
noul |
noul:文が成り立つ確率。TypeSafe と同様、confidence はありません。 |
confidence は TypeSafe の正規化された最大確率で、K 個の選択肢に対して (K · pmax − 1) / (K − 1) です。すべての選択肢が等確率のとき 0、1 つの選択肢がすべての確率を持つとき 1 になります。この式はどのモデルでも同じですが、与えられた confidence の意味は同じではありません。モデルごとに較正が異なるので、自分のデータでモデルごとにしきい値を調整してください。確率は各モデルの temperature で較正されます。CUDA GPU では fp16 のグラフが動き、その答えは接戦で fp32 と異なることがあります。
keep_alive
リクエストが終わったあと、モデルがどれだけロードされたままになるか。Ollama の意味論に従います。
| 値 | 意味 |
|---|---|
"5m", "1h30m", "300ms", 300, "300" |
リクエスト後この時間だけロードしたままにする |
0, "0", "0s" |
リクエストが終わり次第アンロードする |
-1, "-5m", 任意の負の値 |
サーバーが停止するか明示的なアンロードがあるまでロードしたままにする |
省略または null |
OLLAYA_KEEP_ALIVE、既定は 5m |
タイマーはリクエストが終わったときに始まり、最新のリクエストの値が優先されます。ルーターの場合は、答えたターゲットに適用されます。/v1/* は keep_alive を無視します。
決定
POST /api/decide
1 回のフォワードパスで、ある state に関する型付きの質問に答えます。ボディは /v1/systemone のボディにネイティブのオプションを加えたもので、レスポンスは TypeSafe のレスポンスにネイティブのフィールドを加えたものです。したがって TypeSafe クライアントでもパースできます。
| フィールド | 型 | 必須 | 備考 |
|---|---|---|---|
model |
string | はい | モデル名 |
state |
string, object or array | 決定するには必須 | これがない場合、リクエストはモデルをロードまたはアンロードします(下記) |
questions |
object | はい(モデルが組み込みの質問を持たない場合) | モデル自身の質問を完全に置き換えます |
preset |
string | いいえ | questions の代わりに使う プリセットの名前。組み込みまたはカスタム |
images |
array of strings | いいえ | ビジョンモデル用:PNG 画像を base64、または base64 の data: URL で。Decider は 1 枚、winnow:e4b-vision は最大 16 枚。画像を参照 |
keep_alive |
string or number | いいえ | keep_aliveを参照 |
extras |
array of strings | いいえ | ["laya"] はすべての答えに laya 自身の confidence と act 確率を加えます |
stream |
boolean | いいえ | 予約済み。true は拒否されます |
curl http://localhost:11435/api/decide -d '{
"model": "laya",
"state": "I was charged twice for my subscription this month. Please refund the second charge.",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this ticket?",
"criteria": {
"billing": "Payments, invoices and refunds",
"technical": "Bugs, errors and outages",
"account": "Login, profile and settings"
}
},
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": ["Can wait", "Needs attention this week", "Needs attention today"]
},
"refund": {
"type": "noul",
"instructions": "The customer asks for money back.",
"criteria": {"true": "Asks for a refund", "false": "Does not ask for a refund"}
}
},
"keep_alive": "10m"
}'
{
"model": "laya:en",
"answers": {
"department": {
"type": "choice",
"choice": "billing",
"confidence": 0.7781,
"probabilities": {"billing": 0.8521, "technical": 0.0611, "account": 0.0868}
},
"urgency": {
"type": "score",
"score": 1.1982,
"confidence": 0.3418,
"legend": {"0": "Can wait", "1": "Needs attention this week", "2": "Needs attention today"},
"probabilities": {"0": 0.1203, "1": 0.5612, "2": 0.3185}
},
"refund": {"type": "noul", "noul": 0.9127}
},
"usage": {"input_tokens": 118, "output_tokens": 0},
"routing": {
"router": "laya:latest",
"model": "laya:en",
"route": "english",
"reason": "English Latin text"
},
"state_truncated": false,
"done_reason": "decide",
"created_at": "2026-09-24T09:30:12.418Z",
"total_duration": 18734512,
"load_duration": 0,
"eval_duration": 16302117
}
| フィールド | 意味 |
|---|---|
model |
答えたモデル。ルーターならそのターゲット(laya リクエストに対する laya:en) |
answers |
質問 id → 答え。質問の順 |
usage |
読まれた input_tokens。output_tokens は常に 0 |
routing |
ルーターの場合:router、選ばれた model、安定した route キー、情報を示す reason。それ以外は null。 |
state_truncated |
モデルのコンテキストに収めるため state の一部が落とされたとき true |
done_reason |
"decide"、"load"、"unload" のいずれか |
created_at |
レスポンスが生成された時刻 |
total_duration |
リクエスト受信からレスポンスまでのナノ秒。キュー待ちを含む |
load_duration |
モデルのロードを待つのに費やしたナノ秒。ウォームだったときは 0 |
eval_duration |
ランナー内のナノ秒:トークン化、フォワードパス、較正 |
"extras": ["laya"] を付けると、すべての答えに laya オブジェクトも付きます:confidence(laya のエントロピーに基づく信頼度)と act_probability(モデルの act ヘッドからの値。なければ null)。
画像
ビジョンモデル(decider:2b-vision または winnow:e4b-vision)は、state と同様に画像に関する質問にも答えます。画像は images に入れて base64 エンコードで送ります。Ollama の images と同じ動作です。
curl http://localhost:11435/api/decide -d '{
"model": "decider:2b-vision",
"state": "A photo from the warehouse camera.",
"images": ["'"$(base64 -w0 shelf.png)"'"],
"questions": {
"blocked": {"type": "noul", "instructions": "Is the aisle blocked?"},
"fill": {"type": "score", "instructions": "How full is the shelf?", "criteria": ["empty", "half full", "full"]}
}
}'
- Decider: 1 リクエストにつき画像 1 枚、PNG のみです。モデルの前処理は値単位で再現されるので、ピクセルはモデルの作者がデコードするものと一致しなければなりません。Rust の JPEG デコーダは一部のピクセルで libjpeg-turbo と最大 4 レベル異なるため、JPEG はまだ受け付けません。先に PNG に変換してください。
- Decider: 画像はモデルが期待するとおり 32 ピクセルの倍数にリサイズされ、その後は 16x16 ピクセルのパッチを最大 4,096 個、およそ 100 万ピクセル(1024x1024)まで持てます。それより大きい画像はその旨を示す 422 になります。先に縮小してください。
- Decider: 質問は最大 10 個の選択肢を取ります。同じモデルはテキストのみのリクエストにも答えます。
- Winnow E4B vision: 順序づけられた PNG を最大 16 枚、質問あたり 2–64 個の選択肢、画像・状態・質問を合わせたコンテキストの範囲内で。対応するプロジェクターは同じ著者のリビジョンから別途ダウンロードします。既存の Winnow テキストタグはそれを読み込みません。
- 画像を読まないモデルは、
images付きのリクエストに 422 で答えます。
/v1/systemone と /v1/decisions は、画像フィールドを持たない TypeSafe の API と同一のままです。
ロードとアンロード。 state と questions のないリクエストは決して決定しません。keep_alive がない場合、または正か負の値の場合は、モデル(ルーターならすべてのターゲット)をロードし、done_reason: "load" を返します。keep_alive: 0 の場合はアンロードします("unload")。ollaya run はこの方法でプリロードし、ollaya stop はアンロードします。
curl http://localhost:11435/api/decide -d '{"model": "laya:en", "keep_alive": -1}'
curl http://localhost:11435/api/decide -d '{"model": "laya:en", "keep_alive": 0}'
決定は保存されたデータに副作用がないので、再試行しても安全です。
プリセット
プリセットは名前付きの質問セットです。6 つが組み込みで(triage、email、guard、moderation、router、agent)、独自のものも保存できます。questions の代わりに "preset": "NAME" を /api/decide に送ります。
curl http://localhost:11435/api/presets/create -d '{
"name": "billing-check",
"description": "Billing, and how upset the customer is",
"questions": {
"billing": {"type": "noul", "instructions": "The message is about a charge, an invoice or a refund."},
"tone": {"type": "choice", "instructions": "How does the customer sound?", "criteria": {"calm": null, "annoyed": null, "angry": null}}
}
}'
curl http://localhost:11435/api/decide -d '{"model": "winnow:e4b", "state": "I was charged twice this month.", "preset": "billing-check"}'
| エンドポイント | ボディ | 効果 |
|---|---|---|
GET /api/presets |
– | 組み込みプリセット、次にカスタム:name、builtin、description、質問 id、modified_at |
POST /api/presets/create |
name、questions、description(任意) |
カスタムプリセットを保存し、同名のものを置き換えます |
POST /api/presets/show |
name |
質問付きの 1 つのプリセット |
DELETE /api/presets/delete |
name |
カスタムプリセットを削除します |
名前は小文字、数字、-、_ の 1〜64 文字です。組み込みの名前は再利用できず(422)、削除もできません(403)。未知の名前は 404 です。カスタムプリセットはモデルの隣に保存されるので、サーバーのどのクライアントも同じものを見ます。
ルーター
laya(laya:latest)のようなルーターは重みを持ちません。リクエストごとにターゲットの 1 つを選び、選ばれたものが答えます。laya は state だけを読みます。
| 状態 | route |
答えるモデル |
|---|---|---|
| 英語 | english |
laya:en |
| 主に非ラテン文字(アラビア文字、キリル文字、CJK など) | multilingual |
laya:multilingual |
| ラテン文字だが英語でない(トルコ語、ドイツ語など) | multilingual |
laya:multilingual |
| 文字がまったくない | english(既定) |
laya:en |
カード明細の加盟店名(MIGROS KADIKOY ISTANBUL TR)のように、アクセント記号のない大文字の短いテキスト、SKU、ユーザー名は通常識別できず、laya:en に行きます。言語がわかっている場合は、laya:multilingual または laya:en を直接リクエストしてください。レスポンスの model が、どのチェックポイントが答えたかを示します。
ルーティングのコストはマイクロ秒です。route で分岐し、reason では決して分岐しないでください。その文言は変わりえます。laya:typed-decisions はルーターに決して選ばれません。直接リクエストしてください。
ローカルモデルの一覧
GET /api/tags
このマシン上のモデルを新しい順に並べます。各エントリは name、model(同じ値)、modified_at、バイト単位の size、digest(マニフェストの sha256、素の 16 進)と details を持ちます:parent_model、format(onnx、gguf、router のいずれか)、family、families、parameter_size、quantization_level(F16/F32 のように保持する精度、または Q8_0 のような GGUF モデルの量子化)。
{
"models": [
{
"name": "laya:en",
"model": "laya:en",
"modified_at": "2026-09-24T08:11:02.117Z",
"size": 853634822,
"digest": "bf30e4654e9483ff1e6a4fe6fb21b8a71baff6c8a01013046e7d13339020efd7",
"details": {
"parent_model": "",
"format": "onnx",
"family": "laya",
"families": ["laya"],
"parameter_size": "421M",
"quantization_level": "F16/F32"
}
}
]
}
モデル詳細の表示
POST /api/show
curl http://localhost:11435/api/show -d '{"model": "laya:en"}'
| フィールド | 意味 |
|---|---|
license |
ライセンス本文 |
modelfile |
モデルを再現する Modelfile |
parameters |
モデルに設定されたパラメータ。1 行に name value を 1 つ(precision fp32 など) |
questions |
組み込みの質問、または null |
router |
ルーターの場合:strategy、default、routes(route → model)。それ以外は null。 |
details |
/api/tags と同じ |
model_info |
general.architecture、general.languages、general.source(固定された Hugging Face リポジトリ)、および laya.context_length のようなファミリー固有のキー。general.languages は、モデルが訓練と評価を行った言語を列挙します(多くは multilingual)。多言語ベースで作られたモデルでも他の言語を読めることがあるので、自分のデータで測ってください。 |
capabilities |
答える質問の型(choice、score、noul)、act ヘッドがあれば act も |
modified_at |
/api/tags と同じ |
ルーターはターゲットに解決されず、それ自体として表示されます。
実行中モデルの一覧
GET /api/ps
ロード済みのモデルを名前順に並べます。ルーターは決して現れません。ロード済みのターゲットが現れます。各エントリは name、model、size(メモリ、RAM と VRAM)、digest、details(実際にロードされた精度:F16 か F32、または GGUF モデルの量子化)、expires_at(アンロードされる時刻。ロードしたままなら null)、size_vram、context_length、device(cpu、cuda:0、metal など)を持ちます。
モデルのプル
POST /api/pull
{"model": "laya:en"}
モデルをローカルストアにダウンロードし、すべての blob を sha256 と照合します。ルーターをプルすると、それがルーティングするすべてのモデルもプルします。このマシンに必要なレイヤーだけがダウンロードされ、モデル間で共有される blob は一度だけダウンロードされ、中断したダウンロードは再開されます。
レスポンスは進捗をストリーミングし、Ollama のステータス文字列を使います。
{"status":"pulling manifest"}
{"status":"pulling 891102d37268","digest":"sha256:891102d372688fc2a094dac56a384bc537b87c63f21f9f3dac0be2b7cbc8d86c","total":842609210,"completed":420557117}
{"status":"pulling 891102d37268","digest":"sha256:891102d372688fc2a094dac56a384bc537b87c63f21f9f3dac0be2b7cbc8d86c","total":842609210,"completed":842609210}
{"status":"verifying sha256 digest"}
{"status":"writing manifest"}
{"status":"success"}
モデルは writing manifest のあとに初めて /api/tags に現れます。ルーターの場合は最後に 1 つの success があります。パースできない名前、レジストリにないモデル、到達できないレジストリは、ストリームが始まる前の通常の HTTP エラー(422、404、502)なので、curl --fail が機能します。"stream": false の場合、完了時のレスポンスは {"status": "success"} です。同じ名前の 2 回目のプルは、進行中のものに合流します。再試行しても安全です。
モデルの削除
DELETE /api/delete
{"model": "triage"}
名前と、他のどのモデルも使わない blob を削除します。ロード済みのモデルはリクエストが終わるとアンロードされます。ルーターを削除してもターゲットは残ります。レスポンスはボディが空の 200 で、名前が存在しないときは 404 MODEL_NOT_FOUND です。タイムアウトの後は、それを成功として扱ってください。
モデルのコピー
POST /api/copy
{"source": "laya:en", "destination": "my-guardrail"}
モデルを新しい名前へコピーし、既存のコピー先を上書きします。レスポンスはボディが空の 200 です。
モデルの作成
POST /api/create
ollaya create -f Modelfile の背後にある API です。CLI は Modelfile とそれが名指すファイルを読み、その内容を JSON として送ります。
| フィールド | 型 | 必須 | 備考 |
|---|---|---|---|
model |
string | はい | 作成する名前 |
from |
string | はい | ローカルモデル。ルーターも可。決してプルされません。 |
questions |
object | いいえ | 組み込みの質問。決定リクエストと同様に検証されます |
calibration |
object | いいえ | temperature:最大 3 つの数値(choice、score、noul)。temperature_by_options:"<type>:<2|3-5|6-10|11+>" → 数値。 |
parameters |
object | いいえ | precision:"fp16" か "fp32"。1 つのグラフを固定します |
license |
string or array | いいえ | ライセンス本文(複数可) |
description |
string | いいえ | 1 行。/v1/models と ollaya show に表示されます |
stream |
boolean | いいえ | 既定は true |
curl http://localhost:11435/api/create -d '{
"model": "triage",
"from": "laya:en",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this ticket?",
"criteria": ["billing", "technical", "account"]
}
},
"parameters": {"precision": "fp32"},
"description": "Support ticket triage"
}'
ストリームは、継承したレイヤーごとに using existing layer sha256:…、新しいレイヤーごとに creating new layer sha256:… を報告し、その後 writing manifest と success を報告します。レイヤーは内容でアドレス指定されるので、作成を繰り返すと同じモデルになります。
バージョン
GET /api/version
{"version": "0.1.0"}
TypeSafe 互換エンドポイント
| エンドポイント | 説明 |
|---|---|
POST /v1/systemone |
リクエスト:model、state(必須)、questions。レスポンス:ちょうど model、answers、usage。 |
POST /v1/decisions |
/v1/systemone のエイリアス |
GET /v1/models |
ローカルモデルを {"models": [{"name", "description", "release_date"}]} として |
/v1/* は keep_alive や extras のようなネイティブのフィールドを無視し、レスポンスにネイティブのフィールドを決して加えません。エラーは /api/* と同じボディを使い、TypeSafe SDK はそれを正しく読みます。詳しくは TypeSafe 互換を参照してください。
セキュリティ
サーバーは 127.0.0.1:11435 にバインドし、Ollama と同様にローカルの呼び出し元を信頼します。別のアドレス(OLLAYA_HOST=0.0.0.0)にバインドすると、そのポートに到達できる誰もが決定を実行し、モデルをプル・削除・作成できるので、次の点に注意してください。
OLLAYA_API_KEYを設定すると、GET /、HEAD /、CORS プリフライトを除くすべてのリクエストがAuthorization: Bearer <key>を要求します。そうでなければ答えは401 UNAUTHORIZEDです。TypeSafe SDK はこの方法でキーを送り、ollayaCLI は$OLLAYA_API_KEYを送ります。サーバーはループバックを超えて待ち受けるとき、キーがなければ警告をログに記録します。- TLS はサーバーでは終端されません。リモートアクセスには前にリバースプロキシを置いてください。
- ブラウザ。
Originヘッダー付きのリクエストは、localhost、127.0.0.1、0.0.0.0、[::1](任意のポート)、アプリとエディタのウェブビュー、およびOLLAYA_ORIGINS(カンマ区切り、*ワイルドカード)のオリジンからのみ許可されます。ループバックサーバーは予期しないHostヘッダーも拒否し、これが DNS リバインディングを防ぎます。 - データ。 state と質問は決してログに記録されず、エラーの中にそのまま返されることもありません。
| 変数 | 既定 | 効果 |
|---|---|---|
OLLAYA_HOST |
127.0.0.1:11435 |
バインドアドレス。クライアントのターゲット。ループバックアドレスは [::1] でも待ち受けるので、Windows のプログラムは WSL のサーバーに localhost で遅延なく到達できます |
OLLAYA_API_KEY |
未設定 | Authorization: Bearer <key> を要求します |
OLLAYA_ORIGINS |
未設定 | 追加で許可するブラウザオリジン |
OLLAYA_KEEP_ALIVE |
5m |
既定の keep_alive |
OLLAYA_MAX_LOADED_MODELS |
3 |
ロード済みモデルの上限 |
OLLAYA_MAX_QUEUE |
512 |
503 QUEUE_FULL になる前に処理中のリクエスト数 |
OLLAYA_LOAD_TIMEOUT |
5m |
500 MODEL_LOAD_FAILED になるまでのロード期限 |
OLLAYA_DEVICE |
auto |
auto、cpu、cuda、cuda:<n> |
OLLAYA_MODELS |
~/.ollaya/models |
モデルストア |
OLLAYA_REGISTRY |
ollaya.dev |
名前に含まれる既定のレジストリホスト |