GNL
Dokümanlar menüsü
Core · Ücretsiz@gnldev/server

Otomatik REST API + OpenAPI + SSE

createGnl yapılandırmasını tek satırda durable HTTP API'ye çevirir: /agents/:name/run|resume|stream (SSE), /workflows, /runs, /usage ve üretilmiş /openapi.json.

Ne işe yarar / ne zaman kullanılır#

Elinde zaten bir createGnl yapılandırması (agent'lar + workflow'lar + storage) varsa, bunu dışarıya bir HTTP API olarak açmak için endpoint'leri elle yazman gerekmez. createRestApi config'i okuyup çalıştırma, resume, SSE streaming, run geçmişi ve kullanım (usage) uçlarını otomatik üretir — hepsi runDurable üzerinden aktığı için exactly-once ve durability garantileri bedava gelir.

Tipik senaryo: bir Hono uygulamasına app.route('/api', createRestApi(config, opts)) ile bağlayıp, bir istemciyi (web, CLI, başka bir servis) doğrudan bu uçlara konuşturmak. Auth, çok organizasyonluluk ve bütçe/kota opsiyonel — vermezsen uçlar açık ve tek organizasyonlu çalışır (aşağıda örneklenmiştir).

Kurulum / import#

Paket @gnldev/server; journal/storage için @gnldev/durable ve alt-export'u @gnldev/durable/sqlite kullanılır.

npm install
npm install @gnldev/server @gnldev/durable hono
config oluştur
import { Hono } from 'hono';
import { createRestApi } from '@gnldev/server';
import { createGnl } from '@gnldev/durable';
import { SqliteStorage } from '@gnldev/durable/sqlite';

const storage = new SqliteStorage('runs.db');
const config = {
  storage,
  agents: {
    starwars: { model: buildModel(), system: SYSTEM, tools: makeSwapiTools(), maxSteps: 4 },
  },
};

Adım adım kullanım#

Config hazır olunca createRestApi(config, opts) bir Hono router döner; bunu istediğin bir yola bağlarsın (ör. /api).

app.ts
const app = new Hono();
app.route('/api', createRestApi(config, { title: 'SWAPI Free', auth }));

// POST /api/agents/starwars/run     {"runId":"demo-1","prompt":"..."}
// POST /api/agents/starwars/stream  -> SSE (text-delta/tool-call/tool-result/interrupt/done)
// GET  /api/usage                   -> token/maliyet raporu

Çalıştırma isteğinde runId zorunludur — bu, exactly-once garantisinin idempotency anahtarıdır; aynı runId ile tekrar POST atarsan tamamlanmış tool çağrıları yeniden çalışmaz.

curl — çalıştır
curl -s -X POST http://localhost:3001/api/agents/starwars/run \
  -H 'content-type: application/json' \
  -d '{"runId":"demo-1","prompt":"Who is Luke Skywalker?"}'

Akış istiyorsan aynı gövdeyle /agents/:name/stream uçuna POST at — yanıt bir SSE akışıdır (text-delta, tool-call, tool-result, interrupt, done event'leri). Bir tool insan onayı için askıya alındıysa (interrupt), aynı runId ile /agents/:name/resume uçuna { runId, approvals } gönderilerek devam ettirilir — girdi (prompt/messages) journal'dan okunur, tekrar vermene gerek yok.

Kullanım/maliyet raporu için GET /usage:

curl — kullanım
curl -s http://localhost:3001/api/usage
# {"org":null,"usage":{...},"limit":null,"exceeded":false}

Üretilen OpenAPI 3.1 şeması GET /openapi.json üzerinden servis edilir — kayıtlı her agent ve workflow için run/resume/stream yolları otomatik eklenir; bunu Swagger/Redoc gibi araçlara doğrudan verebilirsin.

API referansı#

fncreateRestApi

createGnl config'inden Hono router üretir: /agents/:name/run|resume|stream, /agents, /workflows/:name/run, /workflows, /runs, /runs/:id, /usage, /openapi.json.

typeRestApiOptions

createRestApi ikinci argümanı: title (OpenAPI başlığı), auth (opsiyonel AuthProvider/ReadWriteAuth), org (opt-in çok organizasyonluluk), budgets (bütçe/kota fallback limitleri).

fnbuildOpenApi

Agent ve workflow adı listesinden OpenAPI 3.1 şeması üretir; createRestApi bunu /openapi.json ucunda otomatik çağırır, doğrudan da import edilebilir.

fnpipeAgentStream

streamDurable sonucunu (AI SDK StreamTextResult) SSE'ye pompalar: text-delta/tool-call/tool-result/error/interrupt/done event'leri.

fninterruptsFromSteps

Tamamlanmış step listesinden askıya alınmış tool çağrılarını (Interrupt[]) çıkarır — runDurable'daki suspend mantığıyla aynı; pipeAgentStream bunu stream sonunda interrupt event'i için kullanır.

fnstreamDurable

@gnldev/durable'dan gelir (createRestApi.gnl.stream() içinde dolaylı kullanılır): durable+streaming çalıştırma — aynı exactly-once/suspend garantileri, sonuç fullStream olarak akar.

İpucu
Auth vermezsen tüm uçlar AÇIKTIR (mevcut davranış korunur). Prodüksiyonda en azından roleAuth (@gnldev/auth) ile bir auth geçmen önerilir — GET uçları read, POST uçları write yetkisi ister.
Idempotency
Her çalıştırma isteğinde runId zorunludur — bu exactly-once garantisinin anahtarıdır. Aynı runId ile tekrar istek atmak yeni bir iş DEĞİL, var olanın devamı/tekrarı sayılır (tamamlanmış tool'lar yeniden çalışmaz; askıdaki iş varsa bütçe kapısı da atlanır).