@page-speed/agent-everywhere 0.1.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 +186 -0
- package/dist/index.cjs +8116 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2568 -0
- package/dist/index.d.ts +2568 -0
- package/dist/index.js +7978 -0
- package/dist/index.js.map +1 -0
- package/package.json +103 -0
package/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# @page-speed/agent-everywhere
|
|
2
|
+
|
|
3
|
+
A composable, vendor-neutral UI engine for AI agent conversations. It ships the
|
|
4
|
+
React building blocks an AI agent needs to render a conversation **anywhere** —
|
|
5
|
+
across multiple **placements** and with a rich library of **artifacts** — plus a
|
|
6
|
+
streaming WebSocket transport and an orchestration manifest/registry an agent can
|
|
7
|
+
use to pick and render components at runtime.
|
|
8
|
+
|
|
9
|
+
The package is intentionally self-contained and host-agnostic:
|
|
10
|
+
|
|
11
|
+
- **No framework lock-in** — pure React + `motion` + `lucide-react`; no `next/*`
|
|
12
|
+
imports. Works in Next.js (App or Pages Router), Vite, Remix, CRA, etc.
|
|
13
|
+
- **No embedded backend** — the transport layer contains **no API origin and no
|
|
14
|
+
route**. The host application always supplies its own socket URL (typically
|
|
15
|
+
from an environment variable), so nothing about any specific deployment is
|
|
16
|
+
baked into this public package.
|
|
17
|
+
- **SSR-safe** — browser-only access is guarded; the entry is marked
|
|
18
|
+
`"use client"` for React Server Component frameworks.
|
|
19
|
+
- **Tree-shakable** — ESM + CJS builds with full TypeScript types.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add @page-speed/agent-everywhere
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Peer dependencies
|
|
28
|
+
|
|
29
|
+
Provided by the consuming app (versions are intentionally wide so the package
|
|
30
|
+
slots into existing projects):
|
|
31
|
+
|
|
32
|
+
| Package | Range |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| `react` / `react-dom` | `^18.2 || ^19` |
|
|
35
|
+
| `motion` | `>=11` |
|
|
36
|
+
| `lucide-react` | `>=0.460 <2` |
|
|
37
|
+
| `recharts` | `>=2.13 <4` (optional — only needed for chart artifacts) |
|
|
38
|
+
| `@radix-ui/react-*` | `>=1.1` (avatar, collapsible, progress, scroll-area, slot, tooltip) |
|
|
39
|
+
|
|
40
|
+
Tailwind CSS (v3 or v4) is expected in the host app. Components use CSS-variable
|
|
41
|
+
design tokens (`bg-background`, `text-foreground`, `bg-primary`, …) so they adopt
|
|
42
|
+
the consumer's theme/skin automatically.
|
|
43
|
+
|
|
44
|
+
## Placements
|
|
45
|
+
|
|
46
|
+
A single `AgentSurface` renders the same conversation into any layout — pick a
|
|
47
|
+
`mode` and the messages, input, and data region flow into the matching
|
|
48
|
+
container. There are no per-surface forks of the conversation logic.
|
|
49
|
+
|
|
50
|
+
| Mode | Container | Use |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| `panel` | `ChatPanel` | Inline conversation embedded in a dashboard. |
|
|
53
|
+
| `widget` | `FloatingWidget` | Embeddable launcher + chat (CMS, client sites, third-party pages). |
|
|
54
|
+
| `overlay` | `OverlayModal` | Centered modal conversation. |
|
|
55
|
+
| `fullscreen` | `FullscreenDashboard` | Full-screen chat + report sidebar. |
|
|
56
|
+
| `split` | `SplitView` | Chat beside a live results/preview pane. |
|
|
57
|
+
| `mobile` | `MobileShell` | Full-height mobile-optimized layout. |
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { AgentSurface } from '@page-speed/agent-everywhere';
|
|
61
|
+
|
|
62
|
+
<AgentSurface
|
|
63
|
+
mode="split"
|
|
64
|
+
title="Page Designer"
|
|
65
|
+
messages={messages}
|
|
66
|
+
isLoading={isStreaming}
|
|
67
|
+
inputValue={draft}
|
|
68
|
+
onInputChange={setDraft}
|
|
69
|
+
onSubmit={() => send(draft)}
|
|
70
|
+
dataPanel={<LivePreview />}
|
|
71
|
+
/>;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Artifacts
|
|
75
|
+
|
|
76
|
+
Components an agent can render inside responses, grouped by category. All are
|
|
77
|
+
prop-driven and individually importable:
|
|
78
|
+
|
|
79
|
+
- **Data display** — `ChartContainer`, `MetricsGrid`, `DataTable`,
|
|
80
|
+
`ProgressTracker`, `SentimentDisplay`, `MediaGallery`, `AllocationBreakdown`,
|
|
81
|
+
`AnalyticsDashboard`, `ReportView`.
|
|
82
|
+
- **Interactive** — `EntityCard`, `OptionCards`, `ListingFeed`, `ControlGrid`,
|
|
83
|
+
`RecommendationCards`, `ScheduleTimeline`, `SettingsPanel`, `AgentHandoff`,
|
|
84
|
+
`PersonaSelector`.
|
|
85
|
+
- **Messages** — `MessageList`, `MessageWithReasoning`, `MessageWithSteps`,
|
|
86
|
+
`MessageWithFeedback`, `MessageWithAttachments`, `ConversationArtifact`.
|
|
87
|
+
- **Input** — `PromptInput`, `MultimodalInput`, `QuickReplies`,
|
|
88
|
+
`TemplateSelector`, `InlineSuggestionsInput`, `FileDropZone`, `PromptLibrary`.
|
|
89
|
+
- **Specialty** — `ImageGenerator`, `WritingAssistant`, `OnboardingWizard`,
|
|
90
|
+
`QuizCard`, `GuidedLessonFlow`, `MediaEditorCanvas`.
|
|
91
|
+
|
|
92
|
+
## Streaming transport
|
|
93
|
+
|
|
94
|
+
The transport layer speaks a small, camelCase WebSocket envelope protocol for
|
|
95
|
+
streaming chat: `assistant_message_start` → `*_delta` / `*_thinking_delta` →
|
|
96
|
+
`assistant_message_blocks` → `assistant_message_complete`, with an `error`
|
|
97
|
+
envelope and a `connection_ready` handshake.
|
|
98
|
+
|
|
99
|
+
> The package embeds **no origin and no route**. Supply your own socket URL (or
|
|
100
|
+
> a resolver). The path below is an illustrative placeholder — substitute the
|
|
101
|
+
> route your own backend exposes, ideally read from an environment variable.
|
|
102
|
+
|
|
103
|
+
### `useSemanticBuilder` (drop-in hook)
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import {
|
|
107
|
+
useSemanticBuilder,
|
|
108
|
+
buildSocketUrl,
|
|
109
|
+
} from '@page-speed/agent-everywhere';
|
|
110
|
+
|
|
111
|
+
function Designer({ websiteId, pageCategoryId, blocks, onBlocks }) {
|
|
112
|
+
const conversation = useSemanticBuilder({
|
|
113
|
+
// Host supplies the URL — never hardcode it in shared code.
|
|
114
|
+
resolveSocketUrl: ({ websiteId, pageCategoryId }) =>
|
|
115
|
+
buildSocketUrl(
|
|
116
|
+
process.env.NEXT_PUBLIC_API_BASE_URL!, // e.g. https://api.your-app.example
|
|
117
|
+
'/your/backend/route/{websiteId}/{pageCategoryId}/chat',
|
|
118
|
+
{ websiteId, pageCategoryId },
|
|
119
|
+
),
|
|
120
|
+
websiteId,
|
|
121
|
+
pageCategoryId,
|
|
122
|
+
pageName: 'Home',
|
|
123
|
+
blocks,
|
|
124
|
+
enabled: true,
|
|
125
|
+
onGeneratedBlocks: onBlocks,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const { messages, isStreaming, statusLabel, sendMessage } = conversation;
|
|
129
|
+
// …render with <AgentSurface mode="split" … />
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The hook returns `{ messages, connectionState, connectionError, statusLabel,
|
|
134
|
+
isConnected, isStreaming, sendMessage, retry }` and manages connection
|
|
135
|
+
lifecycle, reconnect with backoff, the streaming message state machine, hidden
|
|
136
|
+
(background) requests, and block-extraction fallbacks.
|
|
137
|
+
|
|
138
|
+
### Low-level client
|
|
139
|
+
|
|
140
|
+
For non-React hosts or custom integrations, use the client directly:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { SemanticBuilderSocketClient } from '@page-speed/agent-everywhere';
|
|
144
|
+
|
|
145
|
+
const client = new SemanticBuilderSocketClient({
|
|
146
|
+
websiteId: 42,
|
|
147
|
+
pageCategoryId: 'home',
|
|
148
|
+
socketUrl: makeYourWssUrl(), // host-provided
|
|
149
|
+
onEnvelope: (e) => { /* handle assistant_* / blocks / complete / error */ },
|
|
150
|
+
onStateChange: (s) => { /* idle | connecting | ready | streaming | error */ },
|
|
151
|
+
});
|
|
152
|
+
client.connect();
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Orchestration
|
|
156
|
+
|
|
157
|
+
A data-only manifest describes every component an orchestrator (or LLM) can
|
|
158
|
+
select, plus a runtime registry to resolve a manifest name to a real component.
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import {
|
|
162
|
+
registerAllComponents,
|
|
163
|
+
componentManifest,
|
|
164
|
+
findComponentsByCapability,
|
|
165
|
+
DynamicRenderer,
|
|
166
|
+
} from '@page-speed/agent-everywhere';
|
|
167
|
+
|
|
168
|
+
registerAllComponents(); // once at startup
|
|
169
|
+
|
|
170
|
+
const [entry] = findComponentsByCapability('chart');
|
|
171
|
+
<DynamicRenderer instruction={{ component: entry.name, props: { data } }} />;
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Local development
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
pnpm install
|
|
178
|
+
pnpm type-check
|
|
179
|
+
pnpm test
|
|
180
|
+
pnpm build
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
UNLICENSED — private package. Distributed for use within OpenSite/Toastability
|
|
186
|
+
applications.
|