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

Sohbet arayüzü: client, useChat ve AG-UI

Dayanıklı bir ajanı kullanıcının önüne koymanın üç yolu: tipli bir REST/SSE istemcisi, Vercel AI SDK useChat uyumu ve bir AG-UI adaptörü — hiçbiri kendi UI kütüphanenizi yazmanızı istemez.

Ne işe yarar#

Sunucu her ajanı zaten REST ve SSE üzerinden yayınlıyor. Geriye istemci yarısı kalıyor ve burada tek bir doğru cevap yok: kimi uygulama tipli bir istemci ister, kimi zaten useChat koşar, kimi de mevcut bir AG-UI yüzeyine takılır. Üçü de aynı akışı okur.

Hepsinin paylaştığı ve baştan söylenmesi gereken bir mesele var. Dayanıklı bir tool, sonuç yerine iç sentinel dönebilir — çalıştırma onay için askıya alınmıştır ya da bir guard çağrıyı engellemiştir. Bunlar iç alanlar taşır ve bir tel sözleşmesi değildir; yani tarayıcıya asla olduğu gibi ulaşmamalıdır. Onları değiştiren maskeleme, canlı akış ile geçmiş yeniden kurulumunun paylaştığı tek bir yardımcıda durur, böylece ikisi birbirinden ayrışamaz.

Tipli istemci (@gnldev/client)#

GnlClient sunucunun uçlarını sarar: listAgents, run, resume (aynı runId artı approvals — askıdaki tool serbest bırakılır), async generator olarak stream, geri çağırmalarla streamTo, ayrıca journal zaman çizelgesi için listRuns ve getRun. Çerçeveden bağımsızdır; @gnldev/client/react kancaları ekler.

run, stream, resume
import { GnlClient } from '@gnldev/client';

const client = new GnlClient({
  baseUrl: 'http://localhost:3000/api',
  headers: { authorization: `Bearer ${token}` },
});

const { runId } = await client.run('support', { prompt: 'Where is my order?' });

for await (const ev of client.stream('support', { runId, prompt: 'and the refund?' })) {
  if (ev.event === 'text-delta') process.stdout.write(ev.data.text);
}

// an approval came back from the operator same runId, the suspended tool is released
await client.resume('support', runId, { 'call-7': true });

React girişi useGnlAgent ile istemcinin kendi biriktiricisi üzerine kurulu bir useChat kancası sunar; mesaj durumu sizin için toplanır.

React kancaları
import { useChat, useGnlAgent } from '@gnldev/client/react';

const { messages, send, streaming } = useChat(client, 'support');

Vercel AI SDK useChat (@gnldev/chat-adapter)#

Arayüzünüz zaten AI SDK'nın useChat'ini (v5) koşuyorsa bu paket onun protokolünü konuşur. toUIMessageStreamResponse dayanıklı bir çalıştırmayı UI mesaj akışına çevirir, createChatRoute ise ucu tek satırda verir.

toUIMessages diğer yarıdır: mesaj geçmişini journal'dan yeniden kurar, yani sayfa yenilenince konuşma kaybolmaz — döküm istemci durumundan değil, gerçekte ne olduğundan yeniden üretilir. Bir kesinti data-gnl-interrupt parçası olarak yüzeye çıkar; arayüz sonuç yerine bir onay istemi göstermesi gerektiğini böyle bilir.

bir sohbet ucu artı geçmiş
import { createChatRoute, toUIMessages } from '@gnldev/chat-adapter';

app.route('/chat', createChatRoute(config, { agent: 'support' }));

// restore the conversation after a reload rebuilt from the journal
const history = await toUIMessages(journal, runId);

AG-UI / CopilotKit (@gnldev/agui)#

AG-UI, CopilotKit'in ve birkaç başka ön yüzün konuştuğu protokoldür. createAguiRoute bir AG-UI HttpAgent'ının POST edebileceği tek bir uç yayınlar; pipeAguiStream ise alt seviyedeki parçadır ve çalıştırmanın akışını AG-UI olaylarına çevirir. Paket olay tiplerini kendisi tanımlar, hiçbir @ag-ui/* bağımlılığı almaz.

bir AG-UI ucu
import { createAguiRoute } from '@gnldev/agui';

app.route('/agui', createAguiRoute(config));
// POST /agui/agents/support/run an AG-UI HttpAgent can consume this directly

API#

classGnlClient

listAgents, run, resume, stream (async generator), streamTo (geri çağırmalar), listRuns, getRun. Seçenekler: baseUrl, headers, fetch (Node <18 ya da test mock'ları için).

fnuseGnlAgent

Tek bir ajan için GnlClient üzerine React kancası.

fnuseChat

İstemcinin biriktiricisi üzerine kurulu React sohbet kancası — mesaj durumu sizin için toplanır.

fntoUIMessageStreamResponse

Dayanıklı bir çalıştırmayı AI SDK useChat (v5) UI mesaj akışı yanıtına çevirir.

fntoUIMessages

Sohbet geçmişini journal'dan yeniden kurar; yenileme konuşmayı geri getirir.

fncreateChatRoute

useChat için hazır bir Hono sohbet ucu.

fnmaskSentinelOutput

İç askı/engel sentinel'lerini istemciye güvenli bir şekille değiştirir; canlı akış ve geçmiş bunu paylaşır, böylece ayrışamazlar.

fncreateAguiRoute

Bir AG-UI HttpAgent'ının tüketebileceği tek POST ucu.

fnpipeAguiStream

Bir çalıştırmayı AG-UI olayları olarak akıtır (pipeAgentStream'in AG-UI karşılığı).

İç sentinel'ler tarayıcıya ulaşmaz
Askıya alınmış bir tool __gnl_suspend sentinel'i, engellenmiş olan da kendi işaretini döner. İkisi de iç ayrıntı ve ham guard gerekçeleri taşır. maskSentinelOutput bunları { pending: 'approval' } / { blocked: true } ile değiştirir ve ham kesintiyi çağırana ayrıca verir; böylece arayüz onay istemini, içeriler sızmadan gösterebilir.
Tek olay eşlemesinin iki kopyası, bilerek
AG-UI adaptörü akış parçalarını, pipeAgentStream'in içinden kopyalanmış bir switch ile çevirir; import etmez. O dosya devam ettirilebilir akışın id sözleşmesini taşır ve süreç-öldürme ile exactly-once testleriyle sabitlenmiştir; oraya bir sink parametresi eklemek daha riskli olurdu. Kopya, iki şeklin adım adım aynı kalması için paralel testlerle korunuyor — ve burada yazıyor, çünkü okuyan kişi bunun bir kopya olduğunu bilmeyi hak eder.