UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

63 lines • 2.86 kB
import { createAgentClient } from './client.js'; import { agUiChatStream as baseAgUiChatStream, } from './core/ag-ui-backend.js'; import { csrfHeaders } from './csrf.js'; /** * the local React adapter's `agUiChatStream`, with `@adonisjs/shield`'s CSRF header read * from the page on every call (yours, in `options.headers`, win over it). * * The re-exported original sends only the headers it is handed, captured once — and shield refuses * a `POST` without a current token, so behind an Adonis session it would be refused on the first * send, or on the first send after the token rotated. */ export function agUiChatStream(request, options) { return baseAgUiChatStream(request, { ...options, headers: { ...csrfHeaders(), ...options.headers }, }); } function agentPath(path) { const trimmed = (path ?? '/agent').replace(/\/+$/, ''); return trimmed.startsWith('/') || trimmed === '' ? trimmed : `/${trimmed}`; } /** * A backend whose chat turns run over AG-UI 1.0 (`agUiAdapter()` on the server) while everything * else — threads, the queue, approvals, uploads — stays on this package's REST routes: * * ```tsx * import { AgentProvider, agUiBackend } from '@adonis-agora/agent/react' * * <AgentProvider backend={agUiBackend()}><Chat /></AgentProvider> * ``` * * Every AG-UI request carries the session cookie, the CSRF header (read per request) and the * connection's own `headers` / `getHeaders`. Point `url` at any other AG-UI 1.0 producer to drive * that one instead. */ export function agUiBackend(options = {}) { const { url, client, agUi, ...connection } = options; const rest = client ?? createAgentClient(connection); const endpoint = url ?? `${(connection.baseUrl ?? '').replace(/\/+$/, '')}${agentPath(connection.path)}/ag-ui`; const baseFetch = connection.fetch ?? globalThis.fetch.bind(globalThis); const fetchWithConnection = async (input, init) => baseFetch(input, { ...init, credentials: connection.credentials ?? 'same-origin', headers: { ...csrfHeaders(), ...connection.headers, ...((await connection.getHeaders?.()) ?? {}), ...init?.headers, }, }); const openChatStream = (request) => baseAgUiChatStream(request, { ...agUi, url: endpoint, fetch: fetchWithConnection }); // A Proxy rather than a spread: the default backend is a class instance, whose methods live on // its prototype, where `{ ...client }` would not find them. return new Proxy(rest, { get(target, property) { if (property === 'openChatStream') return openChatStream; const value = Reflect.get(target, property, target); return typeof value === 'function' ? value.bind(target) : value; }, }); } //# sourceMappingURL=ag-ui.js.map