@matterfact/embed 0.7.0 → 0.9.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 +171 -1
- package/dist/chunk-6EM7T2JV.js +816 -0
- package/dist/chunk-6EM7T2JV.js.map +1 -0
- package/dist/{chunk-4Q2ROXLR.js → chunk-BKKXHSYU.js} +2 -2
- package/dist/chunk-FEXG4LQJ.js +3 -0
- package/dist/chunk-FEXG4LQJ.js.map +7 -0
- package/dist/chunk-NWNMS34P.js +2 -0
- package/dist/chunk-URGQBG4I.js +800 -0
- package/dist/chunk-URGQBG4I.js.map +1 -0
- package/dist/context-ACFBWIFH.js +3 -0
- package/dist/{context-YX2KXFLI.js.map → context-ACFBWIFH.js.map} +1 -1
- package/dist/{context-WU2F5CBC.js → context-U2HJJN2S.js} +4 -2
- package/dist/embed.js +1 -1
- package/dist/embed.js.map +4 -4
- package/dist/index.cjs +1006 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +192 -32
- package/dist/index.d.ts +192 -32
- package/dist/index.js +537 -130
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1042 -165
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +81 -1
- package/dist/react.d.ts +81 -1
- package/dist/react.js +566 -132
- package/dist/react.js.map +1 -1
- package/dist/{snapshot-JOGZWESK.js → snapshot-4GXT6PKZ.js} +2 -2
- package/dist/{snapshot-MUXE7KXX.js → snapshot-Y75SCGCM.js} +3 -3
- package/dist/{snapshot-MUXE7KXX.js.map → snapshot-Y75SCGCM.js.map} +1 -1
- package/examples/embed-demo/README.md +37 -0
- package/examples/embed-demo/src/App.tsx +55 -21
- package/examples/embed-demo/src/HoistDemo.tsx +390 -0
- package/examples/embed-demo/src/main.tsx +7 -0
- package/examples/embed-demo/src/mockXH.ts +492 -0
- package/examples/embed-demo/src/placement.tsx +43 -0
- package/examples/embed-demo/src/styles.css +147 -2
- package/examples/embed-demo/vite.config.ts +2 -2
- package/package.json +1 -1
- package/dist/chunk-7I37ZFAJ.js +0 -2
- package/dist/chunk-AXKXNYRT.js +0 -381
- package/dist/chunk-AXKXNYRT.js.map +0 -1
- package/dist/chunk-D7R6WVHG.js +0 -2
- package/dist/chunk-D7R6WVHG.js.map +0 -7
- package/dist/chunk-RS6RMZ77.js +0 -396
- package/dist/chunk-RS6RMZ77.js.map +0 -1
- package/dist/context-YX2KXFLI.js +0 -3
- /package/dist/{chunk-4Q2ROXLR.js.map → chunk-BKKXHSYU.js.map} +0 -0
- /package/dist/{chunk-7I37ZFAJ.js.map → chunk-NWNMS34P.js.map} +0 -0
- /package/dist/{context-WU2F5CBC.js.map → context-U2HJJN2S.js.map} +0 -0
- /package/dist/{snapshot-JOGZWESK.js.map → snapshot-4GXT6PKZ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -92,6 +92,78 @@ Script-tag / non-React hosts can use the iframe directly (the Share dialog shows
|
|
|
92
92
|
></iframe>
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
## Linking your app's matterfact content
|
|
96
|
+
|
|
97
|
+
A co-embedded `<MatterfactArtifact>` (above) is found automatically. But your app may
|
|
98
|
+
render matterfact content another way — a report/dossier you pulled from matterfact and
|
|
99
|
+
render yourself, or artifacts spread across many routes. Tell the agent where that content
|
|
100
|
+
lives with a **site map**: your routes, each tagged with what kind of matterfact content
|
|
101
|
+
it carries. The agent uses it to reason about — and navigate toward — content the user
|
|
102
|
+
isn't currently looking at.
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
<MatterfactAgent
|
|
106
|
+
sitemap={[
|
|
107
|
+
{
|
|
108
|
+
path: '/company/:ticker/dossier',
|
|
109
|
+
label: 'Company Dossier',
|
|
110
|
+
content: { kind: 'mf-document', doctype: 'company_dossier' },
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
path: '/talent/exec-departures',
|
|
114
|
+
label: 'Exec Departures',
|
|
115
|
+
content: { kind: 'mf-artifact', slug: 'exec-departure-tracker' },
|
|
116
|
+
},
|
|
117
|
+
{ path: '/screener', label: 'Screener', content: { kind: 'host-data' } },
|
|
118
|
+
]}
|
|
119
|
+
/>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
// script tag — same shape
|
|
124
|
+
window.matterfact = {
|
|
125
|
+
sitemap: [
|
|
126
|
+
/* … */
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Each entry is **classification only** — a route pattern, a label, and a `content` tag:
|
|
132
|
+
|
|
133
|
+
- `{ kind: 'mf-artifact', slug }` — a matterfact artifact rendered on that route.
|
|
134
|
+
- `{ kind: 'mf-document', doctype }` — a matterfact document/report (dossier, etc.).
|
|
135
|
+
- `{ kind: 'host-data' }` — your own data; not matterfact content.
|
|
136
|
+
|
|
137
|
+
**Never put a capability token in the site map.** It is app-wide and rides on every turn;
|
|
138
|
+
the concrete artifact/document on the _current_ page arrives separately (the live artifact
|
|
139
|
+
iframe, or per-page context — see below), where the token belongs.
|
|
140
|
+
|
|
141
|
+
### Documents on the current page
|
|
142
|
+
|
|
143
|
+
For a matterfact **document** the user is looking at, hand the agent its id via page
|
|
144
|
+
context (the same `context.entities` you already declare — see _What the agent can see_):
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
<MatterfactAgent
|
|
148
|
+
getPageContext={() => ({
|
|
149
|
+
route: '/company/:ticker/dossier',
|
|
150
|
+
entities: [
|
|
151
|
+
{
|
|
152
|
+
kind: 'document',
|
|
153
|
+
id: currentDoc.mfDocId, // the matterfact MF_DOC_ID
|
|
154
|
+
label: currentDoc.title,
|
|
155
|
+
data: { href: location.href }, // optional: enables the panel's "open on page" deeplink
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
})}
|
|
159
|
+
/>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The agent can then cite the document inline as a chip; clicking it opens a read-only viewer
|
|
163
|
+
in the widget (authorized by the signed-in user's own matterfact access — no token), with an
|
|
164
|
+
optional **Open on page** deeplink back to your route. matterfact resolves the document from
|
|
165
|
+
its own systems by `MF_DOC_ID`; it never reads your database.
|
|
166
|
+
|
|
95
167
|
## Signing users in
|
|
96
168
|
|
|
97
169
|
By default the widget runs its own sign-in in a popup (the only way an embedded frame can
|
|
@@ -214,6 +286,102 @@ gets nothing back. Default is on: seeing the page is the point of the widget.
|
|
|
214
286
|
<MatterfactAgent publishableKey="pk_live_…" pageContext={false} />
|
|
215
287
|
```
|
|
216
288
|
|
|
289
|
+
## Hoist apps
|
|
290
|
+
|
|
291
|
+
If the host page is an [XH Hoist](https://xh.io/) SPA — `window.XH` is present — the widget
|
|
292
|
+
automatically extracts rich page context and a snapshot from it. No `window.matterfact.context`,
|
|
293
|
+
no `getPageContext`, no host code at all: the grids, charts, and navigation already mounted in
|
|
294
|
+
the page are the source of truth. On any other page this is skipped entirely and the widget falls
|
|
295
|
+
back to the generic DOM snapshot described above.
|
|
296
|
+
|
|
297
|
+
This affects two different messages the widget sends, independently:
|
|
298
|
+
|
|
299
|
+
- The per-turn **context** (route + one-line description) still prefers an explicit
|
|
300
|
+
`getPageContext` / `window.matterfact.context` when the host declares one — Hoist is only the
|
|
301
|
+
fallback when neither is set.
|
|
302
|
+
- The on-demand **snapshot** (what the agent sees when it looks at the page) is Hoist-first,
|
|
303
|
+
unconditionally, ahead of the generic DOM walk — whether or not the host also declares context.
|
|
304
|
+
|
|
305
|
+
What gets extracted:
|
|
306
|
+
|
|
307
|
+
- **Route + description** — `XH.routerState`, turned into a one-line summary, e.g. `"Viewing
|
|
308
|
+
default.company.tsr, 1 selected, 1 grid(s)."`
|
|
309
|
+
- **Grids** — each mounted `GridModel` that has rows or a selection (an empty, not-yet-loaded
|
|
310
|
+
grid — e.g. an off-view tab — is skipped), as a table: columns (a grouped column is flattened
|
|
311
|
+
to its visible leaves and prefixed with its group, e.g. `"5Y Value"`), the current selection,
|
|
312
|
+
and up to `rows` data rows with a total count.
|
|
313
|
+
- **Charts** — each mounted `ChartModel` with at least one series, summarised per series (point
|
|
314
|
+
count, min, max, last) — never the raw series.
|
|
315
|
+
- **Site map** — each mounted `TabContainerModel`, joined to the router's routes: the app's
|
|
316
|
+
navigable destinations, grouped by nav level (top tabs, a per-record sidebar, …), with the
|
|
317
|
+
current one marked. This leads the snapshot, since it barely changes turn to turn.
|
|
318
|
+
|
|
319
|
+
It reads roughly like the ARIA snapshot above, with its own block types:
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
- navigation "Site":
|
|
323
|
+
- link "Companies" → /app/companies
|
|
324
|
+
- link "Company Analysis" [current] → /app/company
|
|
325
|
+
- table "Peer TSR":
|
|
326
|
+
- rowgroup "columns":
|
|
327
|
+
- columnheader "Ticker"
|
|
328
|
+
- columnheader "1Y TSR"
|
|
329
|
+
- rowgroup "rows":
|
|
330
|
+
- row:
|
|
331
|
+
- cell "SITE"
|
|
332
|
+
- cell "12.3%"
|
|
333
|
+
- text: "showing 1 of 412 rows"
|
|
334
|
+
- figure "TSR vs Index":
|
|
335
|
+
- text: "series SITE: 4 points, min 1, max 10, last 10"
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Configuring it
|
|
339
|
+
|
|
340
|
+
```js
|
|
341
|
+
window.matterfact = {
|
|
342
|
+
hoist: {
|
|
343
|
+
rows: 50, // rows sent per grid before truncating (default 50)
|
|
344
|
+
excludeModels: [], // class names ('ChartModel') or specific model ids to omit
|
|
345
|
+
actions: { navigate: 'off' }, // see "Letting the agent navigate" below
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
| Key | Type | Default | What |
|
|
351
|
+
| ------------------ | ------------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
352
|
+
| `rows` | `number` | `50` | Rows sent per grid before truncating. The full row count still rides along. |
|
|
353
|
+
| `excludeModels` | `string[]` | `[]` | Model class names (drops every instance) or specific model ids to omit — applies to grids, charts, and nav tab containers alike. |
|
|
354
|
+
| `actions.navigate` | `'off' \| 'confirm' \| 'auto'` | `'off'` | Whether the agent can drive navigation — see below. |
|
|
355
|
+
|
|
356
|
+
### Letting the agent navigate
|
|
357
|
+
|
|
358
|
+
Set `actions.navigate` and the widget advertises a `hoist.navigate` tool bounded to exactly the
|
|
359
|
+
destinations in the CURRENT site map — the agent can't ask for somewhere that isn't reachable
|
|
360
|
+
from where the user actually is, and every call is re-validated against the live site map (and
|
|
361
|
+
the live policy), never whatever the widget last cached, before it runs:
|
|
362
|
+
|
|
363
|
+
- `'off'` (default) — the tool isn't advertised at all.
|
|
364
|
+
- `'confirm'` — advertised, and the widget shows an approval card the user must accept before
|
|
365
|
+
each call.
|
|
366
|
+
- `'auto'` — advertised and runs without asking.
|
|
367
|
+
|
|
368
|
+
```tsx
|
|
369
|
+
<MatterfactAgent publishableKey="pk_live_…" actions={{ navigate: 'confirm' }} />
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
```js
|
|
373
|
+
// script tag — same idea, the global the React prop above is sugar for
|
|
374
|
+
window.matterfact = { hoist: { actions: { navigate: 'confirm' } } };
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Changing `actions` on `<MatterfactAgent>` remounts the widget (a fresh chat session) so the new
|
|
378
|
+
policy is advertised immediately — it's identity-defining config, not a live callback like
|
|
379
|
+
`getPageContext`.
|
|
380
|
+
|
|
381
|
+
Everything else about page observation still applies here: values are redacted before anything
|
|
382
|
+
leaves the page, row counts are capped, and `pageContext={false}` turns this off along with
|
|
383
|
+
everything else (see above).
|
|
384
|
+
|
|
217
385
|
## Microphone / dictation
|
|
218
386
|
|
|
219
387
|
The composer supports voice dictation; the loader grants the iframe `allow="microphone"`.
|
|
@@ -253,7 +421,9 @@ Runnable examples ship inside this package (under `examples/`) and are browsable
|
|
|
253
421
|
cloning anything:
|
|
254
422
|
|
|
255
423
|
- **`examples/embed-demo/`** — a tiny Vite + React app that mounts `<MatterfactAgent inline>`
|
|
256
|
-
in a side panel next to an embedded `<MatterfactArtifact>`, configured entirely via `.env`.
|
|
424
|
+
in a side panel next to an embedded `<MatterfactArtifact>`, configured entirely via `.env`. Also
|
|
425
|
+
ships an opt-in mock Hoist app (`?hoist=1`) to try the automatic Hoist-app path above with no
|
|
426
|
+
real Hoist deployment — see its own README.
|
|
257
427
|
Browse it on [unpkg](https://unpkg.com/browse/@matterfact/embed/examples/embed-demo/), or
|
|
258
428
|
after `npm install @matterfact/embed` find it at
|
|
259
429
|
`node_modules/@matterfact/embed/examples/embed-demo/` — copy it out, `npm install`, `npm run dev`.
|