@dudousxd/nestjs-agent-react 0.9.0 → 0.11.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 +44 -2
- package/dist/index.cjs +633 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +290 -10
- package/dist/index.d.ts +290 -10
- package/dist/index.js +612 -70
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -112,7 +112,7 @@ function Chat() {
|
|
|
112
112
|
|---|---|
|
|
113
113
|
| `items` | The mounted window, oldest first. Each item carries `blocks`, `text`, `usage`, `timestamp`, `isStreaming`, `isLastAssistant`, and its action machines. |
|
|
114
114
|
| `items[i].blocks` | `{ kind: 'text' \| 'reasoning' \| 'tools' \| 'sources' \| 'elicitation' \| 'ui' }`. A `ui` block is a component the server pushed (`{ id, component, props, version }`) — look `component` up in your own registry. A `tools` block is a run of CONSECUTIVE tool parts — any other part between two calls (including a `step-start` marker) ends the run. A `reasoning` block carries `isOpen`/`toggle`, open while it streams. A `sources` block appears only under `sources: true`, an `elicitation` block only under `onAnswer` — see below. |
|
|
115
|
-
| `items[i].blocks[n]` (`tools`) | Also carries `calls`: the same parts, each with `{ toolCallId, name, toolKind, parentId, children, approval, isAwaitingApproval, approve, reject, error }`, and `roots`: the same calls as a tree (a call nested under another by the stream's `parentId` sits in its parent's `children`). `approval` is `{ approver, expiresAt, reason }` when the runner said who has to decide, else `null`. |
|
|
115
|
+
| `items[i].blocks[n]` (`tools`) | Also carries `calls`: the same parts, each with `{ toolCallId, name, toolKind, parentId, children, approval, isAwaitingApproval, approve, reject, error }`, and `roots`: the same calls as a tree (a call nested under another by the stream's `parentId` sits in its parent's `children`). `approval` is `{ approver, expiresAt, reason, status, remember, decidedBy, decidedVia, decisionReason }` when the runner said who has to decide, else `null` — `status` is `pending` / `approved` / `rejected` / `expired`. |
|
|
116
116
|
| `items[i].copy` | `{ available, copied, copy() }` — `copied` flashes for `copyResetMs` (default 1500). |
|
|
117
117
|
| `items[i].edit` | `{ available, isEditing, draft, canSave, start(), cancel(), setDraft(), save(), getTextareaProps() }`. The prop-getter focuses with the caret at the end, saves on Enter, cancels on Escape. |
|
|
118
118
|
| `items[i].fork` / `.regenerate` | `{ available, run() }`. Regenerate is offered on the last assistant message only. |
|
|
@@ -126,6 +126,34 @@ function Chat() {
|
|
|
126
126
|
itself. `MessageItemView({ item })` is the default markup for one modelled item — drive the model
|
|
127
127
|
yourself and still render the shipped bubble.
|
|
128
128
|
|
|
129
|
+
### Talking about tool calls
|
|
130
|
+
|
|
131
|
+
Tools declare how they are spoken about on the server (`@AiTool({ presentation })`, served by
|
|
132
|
+
`GET /agent/tools`). `useToolCatalog` fetches that once per client + agent and shares it; hand the
|
|
133
|
+
catalog to the transcript and every tool call carries a `description`, and every tool block an
|
|
134
|
+
`activity` grouping:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
const chat = useAgentChat({ baseUrl: '/agent' });
|
|
138
|
+
const { catalog } = useToolCatalog({ client: chat.client });
|
|
139
|
+
const transcript = useChatTranscript({ messages: chat.messages, status: chat.status, toolCatalog: catalog });
|
|
140
|
+
|
|
141
|
+
// in a `tools` block:
|
|
142
|
+
block.activity.map((group) => (
|
|
143
|
+
<li key={group.key} data-state={group.status}>
|
|
144
|
+
<MyGlyph name={group.icon} /> {group.phrase} {group.count > 1 ? `×${group.count}` : null}
|
|
145
|
+
</li>
|
|
146
|
+
));
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| Helper | What it gives you |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `call.description` / `describeToolCall(part, catalog)` | `{ status, phrase, label, icon, tone, detail, confirm, result, error }` — `status` is `running` / `awaiting-approval` / `done` / `failed` / `denied`; `confirm` is the approval prompt filled from the input; `result` the output read through the declared view (`metrics` readings, `table` rows as text, `log` lines, `note` text). |
|
|
152
|
+
| `groupToolActivity(block.roots, { catalog, keyOf?, expandNested?, hideCorrected? })` | Calls folded by key ("Database query ×3"), worst status first, latest phrase, `innerCount` of nested calls. `expandNested` replaces a parent (a code-mode `execute`) with the calls it made; `keyOf` groups by anything else (e.g. `github:search`). |
|
|
153
|
+
| `phraseFor` / `fillTemplate` / `readPath` | The template engine: `{dotted.path}` over the input; an empty slot collapses with its leading space; an undescribed tool reads `Working` / `Done`, never its name. |
|
|
154
|
+
| `resolveResultView` / `inferResultView` | A tool output through a view, as plain data — never a serialized payload. |
|
|
155
|
+
| `toolCallState` / `correctedCallIds` / `isActionCall` | Per-call status, and which failures the model later corrected. |
|
|
156
|
+
|
|
129
157
|
### Where the answer came from
|
|
130
158
|
|
|
131
159
|
RAG persists its retrieval as an auto-executed tool call whose output is `{ passages }` — inject
|
|
@@ -195,7 +223,20 @@ An `action` tool's input lands and its output never follows on its own — the l
|
|
|
195
223
|
between the two — so a call stuck at `input-available` IS the pending approval. A question set parks
|
|
196
224
|
the same way and is deliberately excluded: approving one settles nothing.
|
|
197
225
|
|
|
198
|
-
|
|
226
|
+
`call.approve.run({ remember: true })` approves this tool for the rest of the thread (the server
|
|
227
|
+
stops asking); `call.approval` says who has to decide and, once settled, who did and through what.
|
|
228
|
+
For a request with an expiry, `useApprovalCountdown(call.approval?.expiresAt)` ticks the time left
|
|
229
|
+
(`{ remainingMs, isExpired }`, headless — pair it with `formatElapsed`):
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
function ApprovalDeadline({ expiresAt }: { expiresAt: string | null }) {
|
|
233
|
+
const { remainingMs, isExpired } = useApprovalCountdown(expiresAt);
|
|
234
|
+
if (remainingMs === null) return null;
|
|
235
|
+
return <span>{isExpired ? 'Expired' : `${formatElapsed(remainingMs)} left`}</span>;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
A refused settlement (403 "not your thread" or "not your approval", 410 "expired", a network failure) lands on `block.error` /
|
|
199
240
|
`call.error` with the affordance still live, rather than escaping as an unhandled rejection. Render
|
|
200
241
|
it — a button that silently does nothing is indistinguishable from a broken one.
|
|
201
242
|
|
|
@@ -392,6 +433,7 @@ data parts, which `useChat`'s `onData` (and `useAgentChat({ onData })`) sees as
|
|
|
392
433
|
|---|---|
|
|
393
434
|
| `ui` | a `data-ui` part keyed by the component id (a repeat id updates it in place) |
|
|
394
435
|
| `approval-requested` | a `data-approval-requested` part keyed by the call id, plus the SDK's native approval request — the tool part moves to `state: 'approval-requested'` |
|
|
436
|
+
| `approval-settled` | a `data-approval-settled` part keyed by the call id — who decided, through what, remembered or not; folded into `call.approval` |
|
|
395
437
|
| `title` / `cancelled` | transient `data-title` / `data-cancelled` (never stored on the message); `useAgentChat({ onTitle })` |
|
|
396
438
|
| a kind this version does not know | a `data-<kind>` part — forwarded, never dropped |
|
|
397
439
|
|