@page-speed/agent-everywhere 0.3.1 → 0.5.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 CHANGED
@@ -55,6 +55,7 @@ container. There are no per-surface forks of the conversation logic.
55
55
  | `fullscreen` | `FullscreenDashboard` | Full-screen chat + report sidebar. |
56
56
  | `split` | `SplitView` | Chat beside a live results/preview pane. |
57
57
  | `mobile` | `MobileShell` | Full-height mobile-optimized layout. |
58
+ | `native` | `NativeSurface` | Host-placed, position-agnostic pieces — see [Native variant](#native-variant). |
58
59
 
59
60
  ```tsx
60
61
  import { AgentSurface } from '@page-speed/agent-everywhere';
@@ -71,6 +72,110 @@ import { AgentSurface } from '@page-speed/agent-everywhere';
71
72
  />;
72
73
  ```
73
74
 
75
+ ### Native variant
76
+
77
+ The `native` variant is unlike the other placements: it has **no opinion on
78
+ position**. The agent's composer and conversation renderer are native,
79
+ fully-customizable pieces the host places anywhere — a docked bottom bar, a pane,
80
+ a modal, a dashboard card — and styles itself. The two pieces work **disconnected
81
+ from each other**, and a provider lets them **share one live session even when
82
+ rendered in completely separate DOM regions**.
83
+
84
+ **Simple, controlled case** — one component you position yourself:
85
+
86
+ ```tsx
87
+ import { AgentSurface } from '@page-speed/agent-everywhere';
88
+
89
+ <AgentSurface
90
+ mode="native"
91
+ messages={messages}
92
+ isLoading={isStreaming}
93
+ inputValue={draft}
94
+ onInputChange={setDraft}
95
+ onSubmit={() => send(draft)}
96
+ />;
97
+ ```
98
+
99
+ **Decoupled case** — one shared session feeding pieces in separate regions of the
100
+ page. The composer sits idle at the bottom; once the user submits, the host swaps
101
+ its own content for the conversation surface:
102
+
103
+ ```tsx
104
+ import {
105
+ NativeAgentProvider,
106
+ AgentComposer,
107
+ AgentConversation,
108
+ useNativeAgent,
109
+ } from '@page-speed/agent-everywhere';
110
+
111
+ function PagesDashboard() {
112
+ return (
113
+ <NativeAgentProvider
114
+ // Host supplies the socket URL (or a resolver) — never hardcoded here.
115
+ resolveSocketUrl={resolveSocketUrl}
116
+ websiteId={websiteId}
117
+ pageCategoryId="pages"
118
+ connectionStrategy="lazy" // default: no socket until the first submit
119
+ >
120
+ <Content />
121
+ {/* Place the composer anywhere — here, a docked bottom bar. */}
122
+ <AgentComposer
123
+ className="fixed inset-x-0 bottom-0 m-4"
124
+ footer="Grounded in your connected sources."
125
+ />
126
+ </NativeAgentProvider>
127
+ );
128
+ }
129
+
130
+ function Content() {
131
+ const { isActive } = useNativeAgent();
132
+ // The host owns the swap — render your own page until the agent is engaged.
133
+ return isActive ? <AgentConversation /> : <PagesTable />;
134
+ }
135
+ ```
136
+
137
+ Both `AgentComposer` and `AgentConversation` are **dual-mode**: inside a
138
+ `NativeAgentProvider` they wire themselves to the shared session; given explicit
139
+ `value`/`onChange`/`onSubmit` (composer) or `messages` (conversation) props they
140
+ run fully controlled with no provider. For 100%-custom UI, read the session
141
+ directly with `useNativeAgent()`. The connection is lazy by default
142
+ (`connectionStrategy="eager"` to pre-connect on mount).
143
+
144
+ ### Inline confirmation / proposed-plan panels
145
+
146
+ Confirmation and proposed-plan panels flow **inline in the transcript** — attach
147
+ one to a message via `message.confirmation` and it renders after that message's
148
+ content, never pinned over the response. The plan body reuses the same markdown
149
+ rendering and spacing as assistant messages, so long multi-paragraph / bulleted
150
+ plans stay readable. Wire `onConfirmAction` (or use `ConfirmationPanel`
151
+ directly) to handle the action buttons.
152
+
153
+ ```tsx
154
+ const messages = [
155
+ {
156
+ id: 'm1',
157
+ role: 'assistant',
158
+ content: 'Here is the response and the plan.',
159
+ timestamp: new Date(),
160
+ confirmation: {
161
+ title: 'Proposed plan',
162
+ summary: '3 pages to change',
163
+ body: '## What changes\n\n- Rebuild the platform page\n- Refresh OG images',
164
+ actions: [
165
+ { id: 'apply', label: 'Apply changes' },
166
+ { id: 'cancel', label: 'Cancel', variant: 'outline' },
167
+ ],
168
+ },
169
+ },
170
+ ];
171
+
172
+ <AgentSurface
173
+ mode="widget"
174
+ messages={messages}
175
+ onConfirmAction={(messageId, actionId) => apply(messageId, actionId)}
176
+ />;
177
+ ```
178
+
74
179
  ## Artifacts
75
180
 
76
181
  Components an agent can render inside responses, grouped by category. All are
@@ -81,7 +186,7 @@ prop-driven and individually importable:
81
186
  `AnalyticsDashboard`, `ReportView`.
82
187
  - **Interactive** — `EntityCard`, `OptionCards`, `ListingFeed`, `ControlGrid`,
83
188
  `RecommendationCards`, `ScheduleTimeline`, `SettingsPanel`, `AgentHandoff`,
84
- `PersonaSelector`.
189
+ `ConfirmationPanel`, `PersonaSelector`.
85
190
  - **Messages** — `MessageList`, `MessageWithReasoning`, `MessageWithSteps`,
86
191
  `MessageWithFeedback`, `MessageWithAttachments`, `ConversationArtifact`.
87
192
  - **Input** — `PromptInput`, `MultimodalInput`, `QuickReplies`,
@@ -131,9 +236,11 @@ function Designer({ websiteId, pageCategoryId, blocks, onBlocks }) {
131
236
  ```
132
237
 
133
238
  The hook returns `{ messages, connectionState, connectionError, statusLabel,
134
- isConnected, isStreaming, sendMessage, retry }` and manages connection
239
+ isConnected, isStreaming, sendMessage, retry, reset }` and manages connection
135
240
  lifecycle, reconnect with backoff, the streaming message state machine, hidden
136
- (background) requests, and block-extraction fallbacks.
241
+ (background) requests, and block-extraction fallbacks. Pass
242
+ `seedWelcomeMessage: false` to start with an empty transcript (the `native`
243
+ variant does this for its idle composer).
137
244
 
138
245
  ### Low-level client
139
246