@mydatavalue/polter 0.1.0 → 0.1.2
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 +79 -172
- package/dist/index.d.mts +77 -9
- package/dist/index.d.ts +77 -9
- package/dist/index.js +168 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +169 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">Declarative React library for agent-driven UI control with visual guided execution.</p>
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Your UI *is* the agent's interface. It opens the actual dropdown, clicks the actual button, with the user watching. No separate tools to build — single source of truth. After seeing it twice, users do it themselves.
|
|
10
10
|
|
|
11
11
|
## Why
|
|
12
12
|
|
|
13
|
-
Every SaaS adding an AI agent faces
|
|
13
|
+
Every SaaS adding an AI agent faces two problems:
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
1. **Double the work.** You build your UI, then build a whole separate set of agent tools — API endpoints, handlers, schemas — all duplicating what the UI already does.
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
2. **Users never learn.** The agent does things behind the scenes or generates throwaway UI. Either way, users never see where buttons are or how the interface works. Permanent dependency.
|
|
18
|
+
|
|
19
|
+
**Polter solves both.** Your UI *is* the agent's interface — single source of truth. The agent scrolls to the real button, spotlights it, clicks it. Users watch and learn. After twice, they do it themselves. And you wrote zero agent-specific tools.
|
|
18
20
|
|
|
19
21
|
## Install
|
|
20
22
|
|
|
@@ -104,6 +106,76 @@ const handleCommand = useAgentCommandRouter(existingHandler, (cmd) => cmd.action
|
|
|
104
106
|
4. `<div style="display: contents">` wrapper provides DOM refs without affecting layout
|
|
105
107
|
5. Components that mount = actions that exist. Navigate away = actions disappear. No manual sync.
|
|
106
108
|
|
|
109
|
+
## Advanced: `defineAction()` + Registry
|
|
110
|
+
|
|
111
|
+
For multi-page apps, `<AgentAction>` schemas are only available when the component is mounted. If the user says "update the price on property 123" but that page isn't open, the agent can't see the action.
|
|
112
|
+
|
|
113
|
+
`defineAction()` solves this — schemas are available at import time, before any component mounts. Combined with the `registry` prop, the agent gets full knowledge of every action upfront (single LLM roundtrip).
|
|
114
|
+
|
|
115
|
+
### 1. Define actions (co-located with your feature)
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
// features/pricing/actions.ts
|
|
119
|
+
import { defineAction } from 'polter';
|
|
120
|
+
import { z } from 'zod';
|
|
121
|
+
|
|
122
|
+
export const updatePrice = defineAction({
|
|
123
|
+
name: 'update_price',
|
|
124
|
+
description: 'Update price markup on a property',
|
|
125
|
+
parameters: z.object({
|
|
126
|
+
property_id: z.string(),
|
|
127
|
+
markup: z.number(),
|
|
128
|
+
}),
|
|
129
|
+
route: (p) => `/properties/${p.property_id}/pricing`,
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 2. Create a registry (barrel file)
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
// registry.ts
|
|
137
|
+
import { updatePrice } from './features/pricing/actions';
|
|
138
|
+
import { exportCsv } from './features/reports/actions';
|
|
139
|
+
|
|
140
|
+
export const agentRegistry = [updatePrice, exportCsv];
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 3. Pass to provider with your router
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { agentRegistry } from './registry';
|
|
147
|
+
|
|
148
|
+
<AgentActionProvider
|
|
149
|
+
registry={agentRegistry}
|
|
150
|
+
navigate={(path) => router.push(path)}
|
|
151
|
+
>
|
|
152
|
+
<App />
|
|
153
|
+
</AgentActionProvider>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 4. Components reference the definition
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
// features/pricing/PricingPage.tsx
|
|
160
|
+
import { updatePrice } from './actions';
|
|
161
|
+
|
|
162
|
+
<AgentAction action={updatePrice} onExecute={(p) => setMarkup(p.markup)}>
|
|
163
|
+
<SaveButton />
|
|
164
|
+
</AgentAction>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### How it works
|
|
168
|
+
|
|
169
|
+
1. On mount, the provider registers all registry actions as schema-only entries — the agent sees them immediately
|
|
170
|
+
2. When the agent calls `execute('update_price', { property_id: '123', markup: 15 })`:
|
|
171
|
+
- Provider calculates the route: `/properties/123/pricing`
|
|
172
|
+
- Calls your `navigate()` function
|
|
173
|
+
- Waits for the `<AgentAction>` component to mount on the new page
|
|
174
|
+
- Runs the visual execution (spotlight, click, etc.)
|
|
175
|
+
3. When the component unmounts (user navigates away), the action reverts to schema-only — never disappears from the agent's view
|
|
176
|
+
|
|
177
|
+
If an action has no corresponding UI element anywhere in the app, you can provide `onExecute` directly on the definition as an escape hatch — it will execute without navigation or spotlight.
|
|
178
|
+
|
|
107
179
|
## API
|
|
108
180
|
|
|
109
181
|
### Execution modes
|
|
@@ -124,6 +196,8 @@ const handleCommand = useAgentCommandRouter(existingHandler, (cmd) => cmd.action
|
|
|
124
196
|
| `tooltipEnabled` | `boolean` | `true` |
|
|
125
197
|
| `onExecutionStart` | `(name: string) => void` | — |
|
|
126
198
|
| `onExecutionComplete` | `(result: ExecutionResult) => void` | — |
|
|
199
|
+
| `registry` | `ActionDefinition[]` | — |
|
|
200
|
+
| `navigate` | `(path: string) => void \| Promise<void>` | — |
|
|
127
201
|
|
|
128
202
|
### Disabled actions
|
|
129
203
|
|
|
@@ -152,174 +226,7 @@ All overlay elements have class names:
|
|
|
152
226
|
|
|
153
227
|
## Best practices
|
|
154
228
|
|
|
155
|
-
|
|
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
|
-
```
|
|
229
|
+
See [docs/best-practices.md](docs/best-practices.md) for patterns around conditional rendering, per-row actions, Radix integration, dropdowns, and common pitfalls.
|
|
323
230
|
|
|
324
231
|
## Zero dependencies
|
|
325
232
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React$1 from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Define an action at import time so its schema is available before the component mounts.
|
|
6
|
+
* Pass defined actions to `<AgentActionProvider registry={[...]}>` for single-roundtrip execution.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* export const updatePrice = defineAction({
|
|
11
|
+
* name: 'update_price',
|
|
12
|
+
* description: 'Update price markup on a property',
|
|
13
|
+
* parameters: z.object({ property_id: z.string(), markup: z.number() }),
|
|
14
|
+
* route: (p) => `/properties/${p.property_id}/pricing`,
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
interface ActionDefinition<TParams = Record<string, unknown>> {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly description: string;
|
|
21
|
+
/** Zod schema for action parameters. */
|
|
22
|
+
readonly parameters?: unknown;
|
|
23
|
+
/** Client-side route to navigate to before executing. */
|
|
24
|
+
readonly route?: (params: TParams) => string;
|
|
25
|
+
/** Handler for background execution (no UI component needed). */
|
|
26
|
+
readonly onExecute?: (params: TParams) => void | Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Chain of action names to execute sequentially before this action.
|
|
29
|
+
* Each action in the chain is visually executed (spotlight → click), and the next
|
|
30
|
+
* action is waited on to mount before proceeding. This lets the user see the full
|
|
31
|
+
* navigation path instead of being teleported directly to a route.
|
|
32
|
+
*/
|
|
33
|
+
readonly navigateVia?: string[];
|
|
34
|
+
/**
|
|
35
|
+
* How long (ms) to wait for this action's component to mount after navigation.
|
|
36
|
+
* Defaults to 5000ms. Set higher for pages that load slowly
|
|
37
|
+
*/
|
|
38
|
+
readonly mountTimeout?: number;
|
|
39
|
+
}
|
|
40
|
+
declare function defineAction<TParams = Record<string, unknown>>(config: {
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
parameters?: unknown;
|
|
44
|
+
route?: (params: TParams) => string;
|
|
45
|
+
onExecute?: (params: TParams) => void | Promise<void>;
|
|
46
|
+
navigateVia?: string[];
|
|
47
|
+
mountTimeout?: number;
|
|
48
|
+
}): ActionDefinition<TParams>;
|
|
49
|
+
|
|
4
50
|
type ExecutionMode = 'guided' | 'instant';
|
|
5
51
|
interface ExecutionTarget {
|
|
6
52
|
label: string;
|
|
@@ -36,6 +82,14 @@ interface RegisteredAction {
|
|
|
36
82
|
disabled: boolean;
|
|
37
83
|
disabledReason?: string;
|
|
38
84
|
getExecutionTargets: () => ExecutionTarget[];
|
|
85
|
+
/** Client-side route for navigation before execution (from defineAction). */
|
|
86
|
+
route?: (params: Record<string, unknown>) => string;
|
|
87
|
+
/** Chain of action names to execute sequentially before this action (from defineAction). */
|
|
88
|
+
navigateVia?: string[];
|
|
89
|
+
/** How long (ms) to wait for this action's component to mount after navigation. */
|
|
90
|
+
mountTimeout?: number;
|
|
91
|
+
/** True when registered by an `<AgentAction>` component (vs schema-only from registry). */
|
|
92
|
+
componentBacked?: boolean;
|
|
39
93
|
}
|
|
40
94
|
interface ToolSchema {
|
|
41
95
|
name: string;
|
|
@@ -77,6 +131,10 @@ interface AgentActionProviderProps {
|
|
|
77
131
|
children: React.ReactNode;
|
|
78
132
|
onExecutionStart?: (actionName: string) => void;
|
|
79
133
|
onExecutionComplete?: (result: ExecutionResult) => void;
|
|
134
|
+
/** Pre-defined actions whose schemas are available before their components mount. */
|
|
135
|
+
registry?: ActionDefinition<any>[];
|
|
136
|
+
/** Router integration — called when executing a registry action that needs navigation. */
|
|
137
|
+
navigate?: (path: string) => void | Promise<void>;
|
|
80
138
|
}
|
|
81
139
|
interface AgentActionContextValue {
|
|
82
140
|
registerAction: (action: RegisteredAction) => void;
|
|
@@ -90,18 +148,25 @@ interface AgentActionContextValue {
|
|
|
90
148
|
mode: ExecutionMode;
|
|
91
149
|
}
|
|
92
150
|
|
|
93
|
-
declare function AgentActionProvider({ mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, children, onExecutionStart, onExecutionComplete, }: AgentActionProviderProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
declare function AgentActionProvider({ mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, children, onExecutionStart, onExecutionComplete, registry, navigate, }: AgentActionProviderProps): react_jsx_runtime.JSX.Element;
|
|
94
152
|
|
|
95
|
-
|
|
96
|
-
name: string;
|
|
97
|
-
description: string;
|
|
98
|
-
parameters?: unknown;
|
|
153
|
+
type AgentActionProps = {
|
|
99
154
|
onExecute?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
100
155
|
disabled?: boolean;
|
|
101
156
|
disabledReason?: string;
|
|
102
157
|
children?: React$1.ReactNode;
|
|
103
|
-
}
|
|
104
|
-
|
|
158
|
+
} & ({
|
|
159
|
+
action: ActionDefinition<any>;
|
|
160
|
+
name?: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
parameters?: unknown;
|
|
163
|
+
} | {
|
|
164
|
+
action?: never;
|
|
165
|
+
name: string;
|
|
166
|
+
description: string;
|
|
167
|
+
parameters?: unknown;
|
|
168
|
+
});
|
|
169
|
+
declare function AgentAction(props: AgentActionProps): react_jsx_runtime.JSX.Element | null;
|
|
105
170
|
|
|
106
171
|
interface AgentStepProps {
|
|
107
172
|
label: string;
|
|
@@ -200,6 +265,9 @@ declare function useAgentActions(): AgentActionContextValue;
|
|
|
200
265
|
* it routes through `execute()` for visual guided execution. Otherwise it falls
|
|
201
266
|
* through to the original handler.
|
|
202
267
|
*
|
|
268
|
+
* Returns the `ExecutionResult` for registered actions, or `undefined` for
|
|
269
|
+
* fallback commands.
|
|
270
|
+
*
|
|
203
271
|
* Works with any command shape — you provide `getActionName` to extract the
|
|
204
272
|
* action name from your command object.
|
|
205
273
|
*
|
|
@@ -211,10 +279,10 @@ declare function useAgentActions(): AgentActionContextValue;
|
|
|
211
279
|
* );
|
|
212
280
|
* ```
|
|
213
281
|
*/
|
|
214
|
-
declare function useAgentCommandRouter<T>(fallback: ((command: T) => void | Promise<void>) | null, getActionName: (command: T) => string): (command: T) => Promise<
|
|
282
|
+
declare function useAgentCommandRouter<T>(fallback: ((command: T) => void | Promise<void>) | null, getActionName: (command: T) => string): (command: T) => Promise<ExecutionResult | undefined>;
|
|
215
283
|
|
|
216
284
|
type JsonSchema = Record<string, unknown>;
|
|
217
285
|
declare function zodToJsonSchema(schema: unknown): JsonSchema;
|
|
218
286
|
declare function generateToolSchemas(actions: RegisteredAction[]): ToolSchema[];
|
|
219
287
|
|
|
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 };
|
|
288
|
+
export { type ActionDefinition, 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, defineAction, generateToolSchemas, useAgentAction, useAgentActions, useAgentCommandRouter, zodToJsonSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React$1 from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Define an action at import time so its schema is available before the component mounts.
|
|
6
|
+
* Pass defined actions to `<AgentActionProvider registry={[...]}>` for single-roundtrip execution.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* export const updatePrice = defineAction({
|
|
11
|
+
* name: 'update_price',
|
|
12
|
+
* description: 'Update price markup on a property',
|
|
13
|
+
* parameters: z.object({ property_id: z.string(), markup: z.number() }),
|
|
14
|
+
* route: (p) => `/properties/${p.property_id}/pricing`,
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
interface ActionDefinition<TParams = Record<string, unknown>> {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly description: string;
|
|
21
|
+
/** Zod schema for action parameters. */
|
|
22
|
+
readonly parameters?: unknown;
|
|
23
|
+
/** Client-side route to navigate to before executing. */
|
|
24
|
+
readonly route?: (params: TParams) => string;
|
|
25
|
+
/** Handler for background execution (no UI component needed). */
|
|
26
|
+
readonly onExecute?: (params: TParams) => void | Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Chain of action names to execute sequentially before this action.
|
|
29
|
+
* Each action in the chain is visually executed (spotlight → click), and the next
|
|
30
|
+
* action is waited on to mount before proceeding. This lets the user see the full
|
|
31
|
+
* navigation path instead of being teleported directly to a route.
|
|
32
|
+
*/
|
|
33
|
+
readonly navigateVia?: string[];
|
|
34
|
+
/**
|
|
35
|
+
* How long (ms) to wait for this action's component to mount after navigation.
|
|
36
|
+
* Defaults to 5000ms. Set higher for pages that load slowly
|
|
37
|
+
*/
|
|
38
|
+
readonly mountTimeout?: number;
|
|
39
|
+
}
|
|
40
|
+
declare function defineAction<TParams = Record<string, unknown>>(config: {
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
parameters?: unknown;
|
|
44
|
+
route?: (params: TParams) => string;
|
|
45
|
+
onExecute?: (params: TParams) => void | Promise<void>;
|
|
46
|
+
navigateVia?: string[];
|
|
47
|
+
mountTimeout?: number;
|
|
48
|
+
}): ActionDefinition<TParams>;
|
|
49
|
+
|
|
4
50
|
type ExecutionMode = 'guided' | 'instant';
|
|
5
51
|
interface ExecutionTarget {
|
|
6
52
|
label: string;
|
|
@@ -36,6 +82,14 @@ interface RegisteredAction {
|
|
|
36
82
|
disabled: boolean;
|
|
37
83
|
disabledReason?: string;
|
|
38
84
|
getExecutionTargets: () => ExecutionTarget[];
|
|
85
|
+
/** Client-side route for navigation before execution (from defineAction). */
|
|
86
|
+
route?: (params: Record<string, unknown>) => string;
|
|
87
|
+
/** Chain of action names to execute sequentially before this action (from defineAction). */
|
|
88
|
+
navigateVia?: string[];
|
|
89
|
+
/** How long (ms) to wait for this action's component to mount after navigation. */
|
|
90
|
+
mountTimeout?: number;
|
|
91
|
+
/** True when registered by an `<AgentAction>` component (vs schema-only from registry). */
|
|
92
|
+
componentBacked?: boolean;
|
|
39
93
|
}
|
|
40
94
|
interface ToolSchema {
|
|
41
95
|
name: string;
|
|
@@ -77,6 +131,10 @@ interface AgentActionProviderProps {
|
|
|
77
131
|
children: React.ReactNode;
|
|
78
132
|
onExecutionStart?: (actionName: string) => void;
|
|
79
133
|
onExecutionComplete?: (result: ExecutionResult) => void;
|
|
134
|
+
/** Pre-defined actions whose schemas are available before their components mount. */
|
|
135
|
+
registry?: ActionDefinition<any>[];
|
|
136
|
+
/** Router integration — called when executing a registry action that needs navigation. */
|
|
137
|
+
navigate?: (path: string) => void | Promise<void>;
|
|
80
138
|
}
|
|
81
139
|
interface AgentActionContextValue {
|
|
82
140
|
registerAction: (action: RegisteredAction) => void;
|
|
@@ -90,18 +148,25 @@ interface AgentActionContextValue {
|
|
|
90
148
|
mode: ExecutionMode;
|
|
91
149
|
}
|
|
92
150
|
|
|
93
|
-
declare function AgentActionProvider({ mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, children, onExecutionStart, onExecutionComplete, }: AgentActionProviderProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
declare function AgentActionProvider({ mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, children, onExecutionStart, onExecutionComplete, registry, navigate, }: AgentActionProviderProps): react_jsx_runtime.JSX.Element;
|
|
94
152
|
|
|
95
|
-
|
|
96
|
-
name: string;
|
|
97
|
-
description: string;
|
|
98
|
-
parameters?: unknown;
|
|
153
|
+
type AgentActionProps = {
|
|
99
154
|
onExecute?: (params: Record<string, unknown>) => void | Promise<void>;
|
|
100
155
|
disabled?: boolean;
|
|
101
156
|
disabledReason?: string;
|
|
102
157
|
children?: React$1.ReactNode;
|
|
103
|
-
}
|
|
104
|
-
|
|
158
|
+
} & ({
|
|
159
|
+
action: ActionDefinition<any>;
|
|
160
|
+
name?: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
parameters?: unknown;
|
|
163
|
+
} | {
|
|
164
|
+
action?: never;
|
|
165
|
+
name: string;
|
|
166
|
+
description: string;
|
|
167
|
+
parameters?: unknown;
|
|
168
|
+
});
|
|
169
|
+
declare function AgentAction(props: AgentActionProps): react_jsx_runtime.JSX.Element | null;
|
|
105
170
|
|
|
106
171
|
interface AgentStepProps {
|
|
107
172
|
label: string;
|
|
@@ -200,6 +265,9 @@ declare function useAgentActions(): AgentActionContextValue;
|
|
|
200
265
|
* it routes through `execute()` for visual guided execution. Otherwise it falls
|
|
201
266
|
* through to the original handler.
|
|
202
267
|
*
|
|
268
|
+
* Returns the `ExecutionResult` for registered actions, or `undefined` for
|
|
269
|
+
* fallback commands.
|
|
270
|
+
*
|
|
203
271
|
* Works with any command shape — you provide `getActionName` to extract the
|
|
204
272
|
* action name from your command object.
|
|
205
273
|
*
|
|
@@ -211,10 +279,10 @@ declare function useAgentActions(): AgentActionContextValue;
|
|
|
211
279
|
* );
|
|
212
280
|
* ```
|
|
213
281
|
*/
|
|
214
|
-
declare function useAgentCommandRouter<T>(fallback: ((command: T) => void | Promise<void>) | null, getActionName: (command: T) => string): (command: T) => Promise<
|
|
282
|
+
declare function useAgentCommandRouter<T>(fallback: ((command: T) => void | Promise<void>) | null, getActionName: (command: T) => string): (command: T) => Promise<ExecutionResult | undefined>;
|
|
215
283
|
|
|
216
284
|
type JsonSchema = Record<string, unknown>;
|
|
217
285
|
declare function zodToJsonSchema(schema: unknown): JsonSchema;
|
|
218
286
|
declare function generateToolSchemas(actions: RegisteredAction[]): ToolSchema[];
|
|
219
287
|
|
|
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 };
|
|
288
|
+
export { type ActionDefinition, 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, defineAction, generateToolSchemas, useAgentAction, useAgentActions, useAgentCommandRouter, zodToJsonSchema };
|