@invana/assistant 0.0.32
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 +103 -0
- package/dist/index.cjs +2007 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1468 -0
- package/dist/index.d.ts +1468 -0
- package/dist/index.js +1892 -0
- package/dist/index.js.map +1 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @invana/assistant
|
|
2
|
+
|
|
3
|
+
The analyst assistant, driven by JSON. `<ChatSession spec variant />` renders a whole conversation
|
|
4
|
+
— the analyst's questions, what the assistant asks back, its answers, and the run behind each —
|
|
5
|
+
from a `ConversationSpec`, the way `@invana/boards` renders a `BoardSpec`. Two variants draw
|
|
6
|
+
the same spec: `cli`, the console (caret prompts, status-dotted replies, step rows, a Tasks view),
|
|
7
|
+
and `web`, the chat (labelled turns, answer cards, `Answered in 1.4 s`). The composer is the same in
|
|
8
|
+
both, configured by the spec's `composer`.
|
|
9
|
+
|
|
10
|
+
The contract is the [Design Kit Spec](https://claude.ai/artifact/VcN3AYgmbdCpHbxXZjMir5): 29 ask
|
|
11
|
+
intents on 21 blocks that return a value, 14 answer intents on 41 blocks that show data, and 26 answer patterns. Its ids
|
|
12
|
+
are copied into `src/grammar/`, and a test fails when the block registry and the grammar disagree.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @invana/assistant
|
|
16
|
+
pnpm add @invana/ui @invana/charts @invana/tables @invana/forms @invana/styling react react-dom
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { ChatSession, fromNdjson, useChatSession } from '@invana/assistant';
|
|
23
|
+
|
|
24
|
+
const chat = useChatSession(initial);
|
|
25
|
+
|
|
26
|
+
<ChatSession
|
|
27
|
+
variant="web"
|
|
28
|
+
spec={chat.spec}
|
|
29
|
+
// One typed callback per event, then `onEvent` for all of them.
|
|
30
|
+
onPrompt={async (e) => chat.stream(fromNdjson(await fetch('/ask', { method: 'POST', body: JSON.stringify(e) })))}
|
|
31
|
+
onAction={(e) => e.action === 'load-canvas' && canvas.load(e.turn)}
|
|
32
|
+
onOpenRun={(e) => openRunView(e.turn)}
|
|
33
|
+
onStop={chat.stop}
|
|
34
|
+
onEvent={(e) => api.send(e)}
|
|
35
|
+
icons={{ send: <ArrowUp />, stop: <Square /> }}
|
|
36
|
+
/>;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The API sends patches — `add-turn`, `set-state`, `add-block`, `update-block`, `add-trace-step`,
|
|
40
|
+
`update-trace-step`, `update-turn`, `update-spec`, `set-records` (a model's live record count), and for the streaming effect `append-text` (words
|
|
41
|
+
into any block's text field) and `append-thinking` (a step's reasoning). Hand them over any way:
|
|
42
|
+
|
|
43
|
+
- `applyPatch(spec, patch)` and pass the spec — fully controlled;
|
|
44
|
+
- `useChatSession()` — `apply`, `stream(source)`, `play(script)`, `stop()`, `reset(spec)`;
|
|
45
|
+
- `<ChatSession stream={source}>` — the session applies them itself.
|
|
46
|
+
|
|
47
|
+
A source is any iterable or async iterable of patches: `fromNdjson(response)`, `fromEventSource(es)`,
|
|
48
|
+
a generator, or `playScript(script)` for a recorded run (`textDeltas` and `thinkingDeltas` build the
|
|
49
|
+
word-by-word steps). `stopPatches(spec)` is what stopping records: the running step stopped, the
|
|
50
|
+
rest left queued.
|
|
51
|
+
|
|
52
|
+
A trace step carries its record — `startedAt` and `duration`, `attempt` of `attempts`, streamed
|
|
53
|
+
`thinking`, and `io` (what went in, what came out) — and the answer its `startedAt`, `at`,
|
|
54
|
+
`duration`, `meta` line and `outcome` (what the run produced, with its actions).
|
|
55
|
+
|
|
56
|
+
Every action comes back as one `ConversationEvent` — `prompt` (with the composer's `settings` and
|
|
57
|
+
`files`), `reply`, `skip`, `change`, `action`, `scope`, `open`, `template`, `refine`, `rate`,
|
|
58
|
+
`stop`, `retry`, `open-run`, `setting`, `copy`, `toggle-steps`. The component changes nothing itself.
|
|
59
|
+
|
|
60
|
+
Beside each settled answer's time sit its actions, chosen by the `actions` prop — the built-ins by
|
|
61
|
+
name (`retry`, `copy`, `steps`, `rate`) and your own as `{ id, label, icon }`, sent as `action`:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<ChatSession
|
|
65
|
+
spec={spec}
|
|
66
|
+
actions={['retry', 'copy', { id: 'pin', label: 'Pin to report', icon: <Pin /> }, 'rate']}
|
|
67
|
+
onAction={(e) => e.action === 'pin' && reports.pin(e.turn)}
|
|
68
|
+
onCopy={(e) => toast('Copied')}
|
|
69
|
+
/>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`validate(spec)` checks a payload the compiler cannot see: unknown kinds and broken turns are
|
|
73
|
+
errors, and an answer that does not match its pattern is a warning.
|
|
74
|
+
|
|
75
|
+
A block with no renderer yet renders as a labelled placeholder with its JSON. Register your own
|
|
76
|
+
renderer, or replace a built-in one, with the traits that say how it sits:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
<ChatSession
|
|
80
|
+
spec={spec}
|
|
81
|
+
registry={{
|
|
82
|
+
blocks: { subgraph: MyGraphBlock },
|
|
83
|
+
blockTraits: { subgraph: { placement: 'own' } }, // a card of its own, under the answer
|
|
84
|
+
asks: { picker: MyPickerAsk },
|
|
85
|
+
askTraits: { picker: { frame: 'none' } }, // drawn bare, not in the question card
|
|
86
|
+
}}
|
|
87
|
+
/>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`ChatSessionFrame` is the layout alone (a scrolling stack with a footer), and `ChatSessionTurn`
|
|
91
|
+
draws one turn outside a thread — for a block's board.
|
|
92
|
+
|
|
93
|
+
## Moving from `@invana/ui`
|
|
94
|
+
|
|
95
|
+
`ChatSession*`, `ClarifyCard`, `EmissionCard` (with `EmissionHeader` and `CitationMarker`) and
|
|
96
|
+
`TemplatePicker` now import from here. They are still exported from `@invana/ui`, marked
|
|
97
|
+
`@deprecated`, for this release only; their names and props do not change.
|
|
98
|
+
|
|
99
|
+
## Tests
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pnpm --filter @invana/assistant test
|
|
103
|
+
```
|