@dudousxd/nestjs-agent-react 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -1
- package/dist/genui.d.cts +1 -1
- package/dist/genui.d.ts +1 -1
- package/dist/index.cjs +970 -432
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +316 -31
- package/dist/index.d.ts +316 -31
- package/dist/index.js +931 -399
- package/dist/index.js.map +1 -1
- package/dist/{model-CMNhyau6.d.cts → model-gHqjNjLJ.d.cts} +5 -1
- package/dist/{model-CMNhyau6.d.ts → model-gHqjNjLJ.d.ts} +5 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -468,12 +468,101 @@ disables itself while busy never noticed; a double-submitted one, and StrictMode
|
|
|
468
468
|
effect, did.
|
|
469
469
|
|
|
470
470
|
`chat` is the AI SDK v7 `useChat` return value (`messages`, `status`, `sendMessage`, `stop`, …) spread
|
|
471
|
-
together with the extras: `runId`/`activeRunId`, `
|
|
471
|
+
together with the extras: `runId`/`activeRunId`, `connection`, `getThreadId`, `backend` (the `AgentBackend`; also
|
|
472
|
+
under its old name `client`), thread list/CRUD
|
|
472
473
|
(`threads`, `loadThreads`, `loadThread`, `deleteThread`, `forkThread`, `renameThread`, `promoteThread`,
|
|
473
474
|
`truncateFromMessage`), `quota`/`loadQuota`, `cancel`, HITL `approve`/`reject` and `answer`/`skip`, and `regenerate`.
|
|
474
475
|
`MyToolCard`'s `part` prop above types as the exported `AnyToolUIPart` (`ToolUIPart | DynamicToolUIPart`
|
|
475
476
|
— `MessageItem` uses the same union for its own `renderToolPart` callback).
|
|
476
477
|
|
|
478
|
+
### Your own backend (`AgentBackend`)
|
|
479
|
+
|
|
480
|
+
Everything the hooks ask of a server goes through one interface, `AgentBackend`: start a turn
|
|
481
|
+
(`openChatStream`), attach to a streaming run (`resumeChatStream`), cancel, list/get/update/delete
|
|
482
|
+
threads — required — plus optional fork/promote/truncate, approve/reject/answer/skip, upload, tools,
|
|
483
|
+
skills, quota and message feedback. `AgentClient` (fetch over this library's routes) is the default.
|
|
484
|
+
An app with its own client, auth scheme or server implements the interface and passes it in:
|
|
485
|
+
|
|
486
|
+
```ts
|
|
487
|
+
import type { AgentBackend } from '@dudousxd/nestjs-agent-react';
|
|
488
|
+
|
|
489
|
+
const backend: AgentBackend = {
|
|
490
|
+
async openChatStream({ body, headers, signal }) {
|
|
491
|
+
const res = await fetch('/api/chat', {
|
|
492
|
+
method: 'POST',
|
|
493
|
+
credentials: 'include',
|
|
494
|
+
headers: { 'content-type': 'application/json', ...csrfHeader(), ...headers },
|
|
495
|
+
body: JSON.stringify(body),
|
|
496
|
+
signal,
|
|
497
|
+
});
|
|
498
|
+
if (!res.ok || !res.body) throw new Error(`chat failed: ${res.status}`);
|
|
499
|
+
return { body: res.body }; // SSE bytes in docs/stream-protocol.md framing
|
|
500
|
+
},
|
|
501
|
+
async resumeChatStream({ runId, after, signal }) {
|
|
502
|
+
const res = await fetch(`/api/chat/${runId}/stream${after ? `?after=${after}` : ''}`, {
|
|
503
|
+
credentials: 'include',
|
|
504
|
+
signal,
|
|
505
|
+
});
|
|
506
|
+
return res.status === 404 ? null : { body: res.body! };
|
|
507
|
+
},
|
|
508
|
+
cancelStream: (runId) => api.chat.cancel(runId),
|
|
509
|
+
listThreads: () => api.threads.list(),
|
|
510
|
+
getThread: (id) => api.threads.get(id),
|
|
511
|
+
updateThread: (id, patch) => api.threads.update(id, patch),
|
|
512
|
+
deleteThread: (id) => api.threads.remove(id),
|
|
513
|
+
setMessageFeedback: (id, input) => api.messages.feedback(id, input),
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const chat = useAgentChat({ backend }); // chat.backend === backend, typed as yours
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
Calling a hook method whose optional backend member is missing throws
|
|
520
|
+
`AgentBackendUnsupportedError`. The body a backend receives is `{ message, threadId?, agent?,
|
|
521
|
+
attachments?, pageContext?, regenerate? }`; the SSE it returns and the REST shapes are in
|
|
522
|
+
[docs/stream-protocol.md](../../docs/stream-protocol.md).
|
|
523
|
+
|
|
524
|
+
**Cookie session + CSRF with the default client.** `credentials` and `getHeaders` are all it takes —
|
|
525
|
+
`getHeaders` runs per request, so a rotated token is picked up:
|
|
526
|
+
|
|
527
|
+
```ts
|
|
528
|
+
const readCookie = (name: string) =>
|
|
529
|
+
decodeURIComponent(document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`))?.[1] ?? '');
|
|
530
|
+
|
|
531
|
+
useAgentChat({
|
|
532
|
+
baseUrl: '/api',
|
|
533
|
+
credentials: 'include', // 'same-origin' (the fetch default) is enough when the API is same-origin
|
|
534
|
+
getHeaders: () => ({ 'X-XSRF-TOKEN': readCookie('XSRF-TOKEN') }),
|
|
535
|
+
});
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Reconnecting a dropped stream
|
|
539
|
+
|
|
540
|
+
A server that numbers its frames (SSE `id:`, as this library's does) can be resumed: when the
|
|
541
|
+
connection drops mid-run, the transport re-attaches with `GET <base>/chat/:runId/stream?after=<last
|
|
542
|
+
id>`, backing off 0.5s, 1s, 2s… (`reconnect: { maxAttempts, baseDelayMs, maxDelayMs }`, or `false`).
|
|
543
|
+
Meanwhile `chat.status` is `'reconnecting'` (a busy status to `useChatTranscript`) and
|
|
544
|
+
`chat.connection` says which attempt it is on. If the run ended while the client was away (the
|
|
545
|
+
resume answers 404), the hook reloads the thread so the full answer replaces the partial one. After
|
|
546
|
+
the last failed attempt the turn ends with an error.
|
|
547
|
+
|
|
548
|
+
### Thread list and message feedback
|
|
549
|
+
|
|
550
|
+
```tsx
|
|
551
|
+
import { useMessageFeedback, useThreads } from '@dudousxd/nestjs-agent-react';
|
|
552
|
+
|
|
553
|
+
const { threads, isLoading, rename, remove, refresh } = useThreads({ backend: chat.backend });
|
|
554
|
+
const feedback = useMessageFeedback({ backend: chat.backend, threadId: chat.getThreadId });
|
|
555
|
+
|
|
556
|
+
<button aria-pressed={feedback.feedbackOf(message)?.value === 'up'}
|
|
557
|
+
onClick={() => feedback.toggle(message, 'up')}>Helpful</button>
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
`useThreads` refreshes itself when a chat on the same backend creates a thread or settles a run,
|
|
561
|
+
and patches a streamed title in place; `rename`/`remove` are optimistic and roll back on failure.
|
|
562
|
+
`useMessageFeedback` reads a replayed message's rating from `message.metadata.feedback`, rates
|
|
563
|
+
through `POST <base>/messages/:id/feedback`, and maps a message streamed in this session to the row
|
|
564
|
+
its run persisted (the live message carries `metadata.runId`).
|
|
565
|
+
|
|
477
566
|
### The transport, standalone
|
|
478
567
|
|
|
479
568
|
`AgentChatTransport` is a plain AI SDK v7 `ChatTransport` — wire it straight into `useChat` for the SSE
|
package/dist/genui.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { T as TranscriptUiBlock } from './model-
|
|
3
|
+
import { T as TranscriptUiBlock } from './model-gHqjNjLJ.cjs';
|
|
4
4
|
import { G as GenerativeUIOptions, a as GenerativeUIItem, b as GenerativeUIProblem, c as GenerativeUIElement, d as GenerativeUIState } from './types-DFD-soWU.cjs';
|
|
5
5
|
export { e as GENUI_TREE_COMPONENT, f as GenuiCatalogLike, g as GenuiIssueLike, h as GenuiRegistry, i as GenuiRenderer, R as ResolveComponent } from './types-DFD-soWU.cjs';
|
|
6
6
|
import '@dudousxd/nestjs-agent-core';
|
package/dist/genui.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { T as TranscriptUiBlock } from './model-
|
|
3
|
+
import { T as TranscriptUiBlock } from './model-gHqjNjLJ.js';
|
|
4
4
|
import { G as GenerativeUIOptions, a as GenerativeUIItem, b as GenerativeUIProblem, c as GenerativeUIElement, d as GenerativeUIState } from './types-DFD-soWU.js';
|
|
5
5
|
export { e as GENUI_TREE_COMPONENT, f as GenuiCatalogLike, g as GenuiIssueLike, h as GenuiRegistry, i as GenuiRenderer, R as ResolveComponent } from './types-DFD-soWU.js';
|
|
6
6
|
import '@dudousxd/nestjs-agent-core';
|