@mydatavalue/polter 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/LICENSE +21 -0
- package/README.md +330 -0
- package/dist/index.d.mts +220 -0
- package/dist/index.d.ts +220 -0
- package/dist/index.js +1274 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1263 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 myDataValue
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="logo.svg?raw=true" alt="Polter" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">polter</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">Declarative React library for agent-driven UI control with visual guided execution.</p>
|
|
8
|
+
|
|
9
|
+
The agent drives the **real UI** — it opens the actual dropdown, clicks the actual button, with the user watching. "Let me show you how" instead of "I did it for you." After seeing it twice, users do it themselves.
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
Every SaaS adding an AI agent faces the same problem: the agent does things programmatically but the user never learns where buttons are or how the UI works. They become dependent on the agent.
|
|
14
|
+
|
|
15
|
+
The alternative — agents generating UI at runtime — is worse. Generated UI is unpredictable and breaks muscle memory.
|
|
16
|
+
|
|
17
|
+
**The right pattern**: the agent drives the real UI. It scrolls to the button, spotlights it, pauses so the user sees it, then clicks it. The user watches and learns. Nothing else does this.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install polter
|
|
23
|
+
# peer deps
|
|
24
|
+
npm install react react-dom zod
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { AgentActionProvider, AgentAction, useAgentActions } from 'polter';
|
|
31
|
+
import { z } from 'zod';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 1. Wrap your app
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<AgentActionProvider mode="guided" stepDelay={600}>
|
|
38
|
+
<App />
|
|
39
|
+
</AgentActionProvider>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Register actions
|
|
43
|
+
|
|
44
|
+
**Visual actions** — wrap an element, the agent spotlights and clicks it:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
<AgentAction name="export_csv" description="Export properties to CSV">
|
|
48
|
+
<ExportButton />
|
|
49
|
+
</AgentAction>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Parameterized actions** — spotlight the element, call your function:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
<AgentAction
|
|
56
|
+
name="sync_properties"
|
|
57
|
+
description="Sync specific properties"
|
|
58
|
+
parameters={z.object({
|
|
59
|
+
property_ids: z.array(z.number()).optional().describe("IDs to sync")
|
|
60
|
+
})}
|
|
61
|
+
onExecute={(params) => triggerSync(params.property_ids)}
|
|
62
|
+
>
|
|
63
|
+
<SyncButton />
|
|
64
|
+
</AgentAction>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Multi-step actions** — sequential clicks (e.g. open dropdown, then select):
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
<AgentAction name="sync_data" description="Sync from API">
|
|
71
|
+
<AgentStep label="Open sync menu">
|
|
72
|
+
<DropdownTrigger />
|
|
73
|
+
</AgentStep>
|
|
74
|
+
<AgentStep label="Click sync">
|
|
75
|
+
<SyncButton />
|
|
76
|
+
</AgentStep>
|
|
77
|
+
</AgentAction>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 3. Connect to your agent
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
const { schemas, execute, availableActions, isExecuting } = useAgentActions();
|
|
84
|
+
|
|
85
|
+
// Send schemas to your agent backend (auto-updates as components mount/unmount)
|
|
86
|
+
// Call execute("action_name", params) when the agent responds with a tool call
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 4. Integrate with existing handlers
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { useAgentCommandRouter } from 'polter';
|
|
93
|
+
|
|
94
|
+
// Wraps any existing command handler — registered actions get visual execution,
|
|
95
|
+
// unregistered ones fall through to your original handler.
|
|
96
|
+
const handleCommand = useAgentCommandRouter(existingHandler, (cmd) => cmd.action);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## How it works
|
|
100
|
+
|
|
101
|
+
1. `<AgentAction>` registers actions in a React context on mount, deregisters on unmount
|
|
102
|
+
2. The registry always reflects exactly what's on screen — schemas auto-generate from Zod parameter definitions
|
|
103
|
+
3. `execute(name, params)` looks up the action, finds the DOM element via refs, runs: **scroll into view → dim surroundings → spotlight with pulsing ring → tooltip → pause → click/execute → cleanup**
|
|
104
|
+
4. `<div style="display: contents">` wrapper provides DOM refs without affecting layout
|
|
105
|
+
5. Components that mount = actions that exist. Navigate away = actions disappear. No manual sync.
|
|
106
|
+
|
|
107
|
+
## API
|
|
108
|
+
|
|
109
|
+
### Execution modes
|
|
110
|
+
|
|
111
|
+
| Mode | Behavior | Use case |
|
|
112
|
+
|------|----------|----------|
|
|
113
|
+
| `"guided"` | Scroll → spotlight → pause → click | Teaching users, first-time flows |
|
|
114
|
+
| `"instant"` | Execute immediately, no visual | Power users, repeat actions |
|
|
115
|
+
|
|
116
|
+
### Provider props
|
|
117
|
+
|
|
118
|
+
| Prop | Type | Default |
|
|
119
|
+
|------|------|---------|
|
|
120
|
+
| `mode` | `"guided" \| "instant"` | `"guided"` |
|
|
121
|
+
| `stepDelay` | `number` | `600` |
|
|
122
|
+
| `overlayOpacity` | `number` | `0.5` |
|
|
123
|
+
| `spotlightPadding` | `number` | `8` |
|
|
124
|
+
| `tooltipEnabled` | `boolean` | `true` |
|
|
125
|
+
| `onExecutionStart` | `(name: string) => void` | — |
|
|
126
|
+
| `onExecutionComplete` | `(result: ExecutionResult) => void` | — |
|
|
127
|
+
|
|
128
|
+
### Disabled actions
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
<AgentAction
|
|
132
|
+
name="push_changes"
|
|
133
|
+
description="Push pending changes"
|
|
134
|
+
disabled={!hasPendingChanges}
|
|
135
|
+
disabledReason="No pending changes to push"
|
|
136
|
+
>
|
|
137
|
+
<PushButton />
|
|
138
|
+
</AgentAction>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Disabled actions appear in `availableActions` but are excluded from `schemas`. Calling `execute()` on a disabled action returns `{ success: false, error: "No pending changes to push" }`.
|
|
142
|
+
|
|
143
|
+
### CSS customization
|
|
144
|
+
|
|
145
|
+
All overlay elements have class names:
|
|
146
|
+
|
|
147
|
+
```css
|
|
148
|
+
.polter-spotlight { /* box-shadow overlay with cutout */ }
|
|
149
|
+
.polter-ring { /* pulsing border around target */ }
|
|
150
|
+
.polter-tooltip { /* label tooltip */ }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Best practices
|
|
154
|
+
|
|
155
|
+
### Use `<AgentAction>` when wrapping a visible element
|
|
156
|
+
|
|
157
|
+
The component pattern is for actions that have a single, visible UI element to spotlight:
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
// Good — wraps the actual button
|
|
161
|
+
<AgentAction name="push_changes" description="Push pending changes">
|
|
162
|
+
<PushButton />
|
|
163
|
+
</AgentAction>
|
|
164
|
+
|
|
165
|
+
// Bad — wraps nothing visible, renders a pointless display:contents div
|
|
166
|
+
<AgentAction name="sync_data" description="Sync data"
|
|
167
|
+
onExecute={handleSync} />
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Wrap conditionally rendered elements with `<AgentAction>` on the outside
|
|
171
|
+
|
|
172
|
+
`<AgentAction>` always registers the action regardless of whether its children are rendered. Keep the wrapper always-rendered and put the condition inside — `onExecute` works even when there's nothing visible to spotlight:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
// Bad — conditionally rendering the AgentAction itself, action disappears when button is hidden
|
|
176
|
+
{selectedIds.size > 0 && (
|
|
177
|
+
<AgentAction name="grant_access" description="Grant access" onExecute={() => handleGrant()}>
|
|
178
|
+
<Button onClick={handleGrant}>Grant Access ({selectedIds.size})</Button>
|
|
179
|
+
</AgentAction>
|
|
180
|
+
)}
|
|
181
|
+
|
|
182
|
+
// Good — AgentAction always registered, button conditionally rendered inside
|
|
183
|
+
<AgentAction name="grant_access" description="Grant access" onExecute={() => handleGrant()}>
|
|
184
|
+
{selectedIds.size > 0 && (
|
|
185
|
+
<Button onClick={handleGrant}>Grant Access ({selectedIds.size})</Button>
|
|
186
|
+
)}
|
|
187
|
+
</AgentAction>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Use `useAgentAction` hook for per-row and programmatic actions
|
|
191
|
+
|
|
192
|
+
When N rows each have their own button (sync, edit, navigate), you can't wrap each with `<AgentAction>` — same name would register N times, each overwriting the last. Use the hook + `<AgentTarget>` on each row's element:
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
// Hook registers the action once
|
|
196
|
+
useAgentAction({
|
|
197
|
+
name: 'sync_property',
|
|
198
|
+
description: 'Sync a property',
|
|
199
|
+
parameters: z.object({ property_id: z.number() }),
|
|
200
|
+
onExecute: (p) => handleSync(p.property_id),
|
|
201
|
+
steps: [{ label: 'Click Sync', fromParam: 'property_id' }],
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// AgentTarget on each row's button (in a column renderer)
|
|
205
|
+
<AgentTarget action="sync_property" param="property_id" value={String(propertyId)}>
|
|
206
|
+
<SyncButton />
|
|
207
|
+
</AgentTarget>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The hook also accepts an array to batch-register multiple actions in one call:
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
useAgentAction([
|
|
214
|
+
{ name: 'navigate_to_property', ... },
|
|
215
|
+
{ name: 'sync_property', ... },
|
|
216
|
+
{ name: 'edit_markup', ... },
|
|
217
|
+
]);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Never nest `AgentTarget` inside Radix `asChild` components
|
|
221
|
+
|
|
222
|
+
Radix primitives (`PopoverTrigger`, `DialogTrigger`, `TooltipTrigger`) with `asChild` need their direct child to forward refs. `AgentTarget` inserts a `<div style="display:contents">` wrapper that breaks this:
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
// Bad — breaks ref forwarding, trigger won't work
|
|
226
|
+
<PopoverTrigger asChild>
|
|
227
|
+
<AgentTarget name="my-btn">
|
|
228
|
+
<Button>Open</Button>
|
|
229
|
+
</AgentTarget>
|
|
230
|
+
</PopoverTrigger>
|
|
231
|
+
|
|
232
|
+
// Good — wrap outside the Popover entirely
|
|
233
|
+
<AgentTarget name="my-btn">
|
|
234
|
+
<Popover>
|
|
235
|
+
<PopoverTrigger asChild>
|
|
236
|
+
<Button>Open</Button>
|
|
237
|
+
</PopoverTrigger>
|
|
238
|
+
<PopoverContent>...</PopoverContent>
|
|
239
|
+
</Popover>
|
|
240
|
+
</AgentTarget>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Since `Popover.Root` renders no DOM element, `AgentTarget`'s `firstElementChild` resolves to the Button directly.
|
|
244
|
+
|
|
245
|
+
### Use shared targets for elements used by multiple actions
|
|
246
|
+
|
|
247
|
+
When two actions need the same trigger (e.g. both open the same overflow menu), omit the `action` prop to make a shared target:
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
// Shared target — any action can resolve it by name
|
|
251
|
+
<AgentTarget name="overflow-menu-btn">
|
|
252
|
+
<OverflowMenuPopover>
|
|
253
|
+
<AgentTarget name="export-btn">
|
|
254
|
+
<ExportButton />
|
|
255
|
+
</AgentTarget>
|
|
256
|
+
<AgentTarget name="freeze-btn">
|
|
257
|
+
<FreezeButton />
|
|
258
|
+
</AgentTarget>
|
|
259
|
+
</OverflowMenuPopover>
|
|
260
|
+
</AgentTarget>
|
|
261
|
+
|
|
262
|
+
// Both actions find the same trigger
|
|
263
|
+
useAgentAction([
|
|
264
|
+
{ name: 'export_csv', steps: [
|
|
265
|
+
{ label: 'Open menu', fromTarget: 'overflow-menu-btn' },
|
|
266
|
+
{ label: 'Click Export', fromTarget: 'export-btn' },
|
|
267
|
+
]},
|
|
268
|
+
{ name: 'toggle_freeze', steps: [
|
|
269
|
+
{ label: 'Open menu', fromTarget: 'overflow-menu-btn' },
|
|
270
|
+
{ label: 'Click Freeze', fromTarget: 'freeze-btn' },
|
|
271
|
+
]},
|
|
272
|
+
]);
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Multi-step is required for dropdowns
|
|
276
|
+
|
|
277
|
+
With `onExecute`, the executor skips clicking the last step (to avoid double-firing). If your action has only one step, the click never happens — the dropdown won't open:
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
// Bad — single step with onExecute, dropdown never opens
|
|
281
|
+
<AgentAction name="filter" onExecute={handleFilter}>
|
|
282
|
+
<Select>...</Select>
|
|
283
|
+
</AgentAction>
|
|
284
|
+
|
|
285
|
+
// Good — two steps: click to open, then select option
|
|
286
|
+
<AgentAction name="filter" onExecute={handleFilter}>
|
|
287
|
+
<AgentStep label="Open filter">
|
|
288
|
+
<Select>
|
|
289
|
+
<SelectTrigger>...</SelectTrigger>
|
|
290
|
+
<SelectContent>
|
|
291
|
+
<AgentTarget action="filter" param="status" value="active">
|
|
292
|
+
<SelectItem value="active">Active</SelectItem>
|
|
293
|
+
</AgentTarget>
|
|
294
|
+
</SelectContent>
|
|
295
|
+
</Select>
|
|
296
|
+
</AgentStep>
|
|
297
|
+
<AgentStep label="Select option" fromParam="status" />
|
|
298
|
+
</AgentAction>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Don't deeply nest `<AgentAction>` wrappers
|
|
302
|
+
|
|
303
|
+
Each `<AgentAction>` renders a `<div style="display:contents">`. Nesting them creates a chain of `display:contents` divs. `getBoundingClientRect()` on these returns all zeros, causing spotlights to appear at (0,0):
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
// Bad — nested wrappers, inner actions resolve to display:contents divs
|
|
307
|
+
<AgentAction name="action_a">
|
|
308
|
+
<AgentAction name="action_b">
|
|
309
|
+
<AgentAction name="action_c">
|
|
310
|
+
<ActualContent />
|
|
311
|
+
</AgentAction>
|
|
312
|
+
</AgentAction>
|
|
313
|
+
</AgentAction>
|
|
314
|
+
|
|
315
|
+
// Good — flat siblings, each wrapping its own element (or use the hook)
|
|
316
|
+
<AgentAction name="action_a">
|
|
317
|
+
<ButtonA />
|
|
318
|
+
</AgentAction>
|
|
319
|
+
<AgentAction name="action_b">
|
|
320
|
+
<ButtonB />
|
|
321
|
+
</AgentAction>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Zero dependencies
|
|
325
|
+
|
|
326
|
+
Peer deps only: React 18+ and Zod. No runtime dependencies.
|
|
327
|
+
|
|
328
|
+
## License
|
|
329
|
+
|
|
330
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React$1 from 'react';
|
|
3
|
+
|
|
4
|
+
type ExecutionMode = 'guided' | 'instant';
|
|
5
|
+
interface ExecutionTarget {
|
|
6
|
+
label: string;
|
|
7
|
+
element: HTMLElement | null;
|
|
8
|
+
/** Resolve element from AgentTarget registry by matching this param's value. */
|
|
9
|
+
fromParam?: string;
|
|
10
|
+
/** Resolve element from AgentTarget registry by matching a named target. */
|
|
11
|
+
fromTarget?: string;
|
|
12
|
+
/** Simulate typing the value of this param into the element. */
|
|
13
|
+
setParam?: string;
|
|
14
|
+
/** Set a value programmatically via onSetValue callback. */
|
|
15
|
+
setValue?: string;
|
|
16
|
+
onSetValue?: (value: unknown) => void;
|
|
17
|
+
/** Run a callback to prepare the DOM (e.g. scroll virtualized list) before resolving. */
|
|
18
|
+
prepareView?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
interface AgentTargetEntry {
|
|
21
|
+
/** Action name — when omitted, the target is shared and matches any action. */
|
|
22
|
+
action?: string;
|
|
23
|
+
element: HTMLElement;
|
|
24
|
+
/** Parameter key — used with `value` for param-based resolution. */
|
|
25
|
+
param?: string;
|
|
26
|
+
/** Parameter value — matched against the agent's param value. */
|
|
27
|
+
value?: string;
|
|
28
|
+
/** Named target key — used for static lazy resolution via `fromTarget`. */
|
|
29
|
+
name?: string;
|
|
30
|
+
}
|
|
31
|
+
interface RegisteredAction {
|
|
32
|
+
name: string;
|
|
33
|
+
description: string;
|
|
34
|
+
parameters?: unknown;
|
|
35
|
+
onExecute?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
36
|
+
disabled: boolean;
|
|
37
|
+
disabledReason?: string;
|
|
38
|
+
getExecutionTargets: () => ExecutionTarget[];
|
|
39
|
+
}
|
|
40
|
+
interface ToolSchema {
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
parameters: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
interface ExecutionResult {
|
|
46
|
+
success: boolean;
|
|
47
|
+
actionName: string;
|
|
48
|
+
error?: string;
|
|
49
|
+
}
|
|
50
|
+
interface AvailableAction {
|
|
51
|
+
name: string;
|
|
52
|
+
description: string;
|
|
53
|
+
disabled: boolean;
|
|
54
|
+
disabledReason?: string;
|
|
55
|
+
hasParameters: boolean;
|
|
56
|
+
}
|
|
57
|
+
interface ExecutorConfig {
|
|
58
|
+
mode: ExecutionMode;
|
|
59
|
+
stepDelay: number;
|
|
60
|
+
overlayOpacity: number;
|
|
61
|
+
spotlightPadding: number;
|
|
62
|
+
tooltipEnabled: boolean;
|
|
63
|
+
cursorEnabled: boolean;
|
|
64
|
+
signal?: AbortSignal;
|
|
65
|
+
/** Resolve an element from the AgentTarget registry. Used by fromParam steps. */
|
|
66
|
+
resolveTarget?: (actionName: string, param: string, value: string, signal?: AbortSignal) => Promise<HTMLElement | null>;
|
|
67
|
+
/** Resolve a named target from the AgentTarget registry. Used by fromTarget steps. */
|
|
68
|
+
resolveNamedTarget?: (actionName: string, name: string, signal?: AbortSignal) => Promise<HTMLElement | null>;
|
|
69
|
+
}
|
|
70
|
+
interface AgentActionProviderProps {
|
|
71
|
+
mode?: ExecutionMode;
|
|
72
|
+
stepDelay?: number;
|
|
73
|
+
overlayOpacity?: number;
|
|
74
|
+
spotlightPadding?: number;
|
|
75
|
+
tooltipEnabled?: boolean;
|
|
76
|
+
cursorEnabled?: boolean;
|
|
77
|
+
children: React.ReactNode;
|
|
78
|
+
onExecutionStart?: (actionName: string) => void;
|
|
79
|
+
onExecutionComplete?: (result: ExecutionResult) => void;
|
|
80
|
+
}
|
|
81
|
+
interface AgentActionContextValue {
|
|
82
|
+
registerAction: (action: RegisteredAction) => void;
|
|
83
|
+
unregisterAction: (name: string) => void;
|
|
84
|
+
registerTarget: (id: string, entry: AgentTargetEntry) => void;
|
|
85
|
+
unregisterTarget: (id: string) => void;
|
|
86
|
+
execute: (actionName: string, params?: Record<string, unknown>) => Promise<ExecutionResult>;
|
|
87
|
+
availableActions: AvailableAction[];
|
|
88
|
+
schemas: ToolSchema[];
|
|
89
|
+
isExecuting: boolean;
|
|
90
|
+
mode: ExecutionMode;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
declare function AgentActionProvider({ mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, children, onExecutionStart, onExecutionComplete, }: AgentActionProviderProps): react_jsx_runtime.JSX.Element;
|
|
94
|
+
|
|
95
|
+
interface AgentActionProps {
|
|
96
|
+
name: string;
|
|
97
|
+
description: string;
|
|
98
|
+
parameters?: unknown;
|
|
99
|
+
onExecute?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
100
|
+
disabled?: boolean;
|
|
101
|
+
disabledReason?: string;
|
|
102
|
+
children?: React$1.ReactNode;
|
|
103
|
+
}
|
|
104
|
+
declare function AgentAction({ name, description, parameters, onExecute, disabled, disabledReason, children, }: AgentActionProps): react_jsx_runtime.JSX.Element | null;
|
|
105
|
+
|
|
106
|
+
interface AgentStepProps {
|
|
107
|
+
label: string;
|
|
108
|
+
children?: React$1.ReactNode;
|
|
109
|
+
/** Resolve the target element from the AgentTarget registry by matching this param's value. */
|
|
110
|
+
fromParam?: string;
|
|
111
|
+
/** Resolve a named target from the AgentTarget registry (for static elements inside popovers/dropdowns). */
|
|
112
|
+
fromTarget?: string;
|
|
113
|
+
/** Simulate typing the value of this param into the element. */
|
|
114
|
+
setParam?: string;
|
|
115
|
+
/** Set a value programmatically via onSetValue callback. */
|
|
116
|
+
setValue?: string;
|
|
117
|
+
/** Callback for setValue — receives the param value and sets it on the component. */
|
|
118
|
+
onSetValue?: (value: unknown) => void;
|
|
119
|
+
/** Run a callback to prepare the DOM (e.g. scroll a virtualized list) before resolving the target. */
|
|
120
|
+
prepareView?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
121
|
+
}
|
|
122
|
+
declare function AgentStep({ label, children, fromParam, fromTarget, setParam, setValue, onSetValue, prepareView, }: AgentStepProps): react_jsx_runtime.JSX.Element | null;
|
|
123
|
+
|
|
124
|
+
interface AgentTargetProps {
|
|
125
|
+
/** The action name this target belongs to. Omit to make a shared target that any action can resolve. */
|
|
126
|
+
action?: string;
|
|
127
|
+
children: React$1.ReactNode;
|
|
128
|
+
/** The parameter key this target maps to (for fromParam resolution). */
|
|
129
|
+
param?: string;
|
|
130
|
+
/** The parameter value this target represents (for fromParam resolution). */
|
|
131
|
+
value?: string;
|
|
132
|
+
/** Named target key (for fromTarget resolution — static elements inside popovers/dropdowns). */
|
|
133
|
+
name?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Register a DOM element as a selectable target for an agent action step.
|
|
137
|
+
*
|
|
138
|
+
* Use this to wrap lazily-rendered elements (dropdown options, search results, etc.)
|
|
139
|
+
* so that `AgentStep fromParam` or `AgentStep fromTarget` can find and interact
|
|
140
|
+
* with them after they mount.
|
|
141
|
+
*
|
|
142
|
+
* Works through React portals — context flows regardless of DOM position.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```tsx
|
|
146
|
+
* // Dynamic: match by param value (inside a dropdown's renderOption):
|
|
147
|
+
* <AgentTarget action="filter_by_tag" param="tag_name" value={option.label}>
|
|
148
|
+
* <DropdownOption>{option.label}</DropdownOption>
|
|
149
|
+
* </AgentTarget>
|
|
150
|
+
*
|
|
151
|
+
* // Static: match by name (inside a popover that mounts lazily):
|
|
152
|
+
* <AgentTarget action="toggle_frozen_columns" name="freeze-btn">
|
|
153
|
+
* <button>Freeze columns</button>
|
|
154
|
+
* </AgentTarget>
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
declare function AgentTarget({ action, param, value, name, children }: AgentTargetProps): react_jsx_runtime.JSX.Element;
|
|
158
|
+
|
|
159
|
+
interface AgentDevToolsProps {
|
|
160
|
+
/** Default open state. */
|
|
161
|
+
defaultOpen?: boolean;
|
|
162
|
+
}
|
|
163
|
+
declare function AgentDevTools({ defaultOpen }: AgentDevToolsProps): react_jsx_runtime.JSX.Element;
|
|
164
|
+
|
|
165
|
+
interface StepConfig {
|
|
166
|
+
label: string;
|
|
167
|
+
fromParam?: string;
|
|
168
|
+
fromTarget?: string;
|
|
169
|
+
setParam?: string;
|
|
170
|
+
setValue?: string;
|
|
171
|
+
onSetValue?: (value: unknown) => void;
|
|
172
|
+
prepareView?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
173
|
+
}
|
|
174
|
+
interface AgentActionConfig {
|
|
175
|
+
name: string;
|
|
176
|
+
description: string;
|
|
177
|
+
parameters?: unknown;
|
|
178
|
+
onExecute?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
179
|
+
disabled?: boolean;
|
|
180
|
+
disabledReason?: string;
|
|
181
|
+
steps?: StepConfig[];
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Hook-based action registration for actions that don't wrap a single element.
|
|
185
|
+
* Use this for per-row actions where AgentTargets are on scattered elements
|
|
186
|
+
* and the action resolves to them via fromParam/fromTarget.
|
|
187
|
+
*
|
|
188
|
+
* Accepts a single config or an array to batch-register multiple actions.
|
|
189
|
+
*
|
|
190
|
+
* For actions that wrap a visible element, prefer the <AgentAction> component.
|
|
191
|
+
*/
|
|
192
|
+
declare function useAgentAction(config: AgentActionConfig | AgentActionConfig[]): void;
|
|
193
|
+
|
|
194
|
+
declare function useAgentActions(): AgentActionContextValue;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Wraps an existing command handler with agent action routing.
|
|
198
|
+
*
|
|
199
|
+
* When a command arrives, if a matching `<AgentAction>` is mounted and enabled,
|
|
200
|
+
* it routes through `execute()` for visual guided execution. Otherwise it falls
|
|
201
|
+
* through to the original handler.
|
|
202
|
+
*
|
|
203
|
+
* Works with any command shape — you provide `getActionName` to extract the
|
|
204
|
+
* action name from your command object.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```tsx
|
|
208
|
+
* const handleCommand = useAgentCommandRouter(
|
|
209
|
+
* existingHandler,
|
|
210
|
+
* (cmd) => cmd.action,
|
|
211
|
+
* );
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
declare function useAgentCommandRouter<T>(fallback: ((command: T) => void | Promise<void>) | null, getActionName: (command: T) => string): (command: T) => Promise<void>;
|
|
215
|
+
|
|
216
|
+
type JsonSchema = Record<string, unknown>;
|
|
217
|
+
declare function zodToJsonSchema(schema: unknown): JsonSchema;
|
|
218
|
+
declare function generateToolSchemas(actions: RegisteredAction[]): ToolSchema[];
|
|
219
|
+
|
|
220
|
+
export { AgentAction, type AgentActionContextValue, AgentActionProvider, type AgentActionProviderProps, AgentDevTools, AgentStep, AgentTarget, type AgentTargetEntry, type AvailableAction, type ExecutionMode, type ExecutionResult, type ExecutionTarget, type ExecutorConfig, type RegisteredAction, type ToolSchema, generateToolSchemas, useAgentAction, useAgentActions, useAgentCommandRouter, zodToJsonSchema };
|