@mydatavalue/polter 0.1.1 → 0.1.3

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/dist/index.d.mts CHANGED
@@ -73,6 +73,8 @@ interface AgentTargetEntry {
73
73
  value?: string;
74
74
  /** Named target key — used for static lazy resolution via `fromTarget`. */
75
75
  name?: string;
76
+ /** Run a callback to prepare component state before the agent interacts with this target. */
77
+ prepareView?: (params: Record<string, unknown>) => void | Promise<void>;
76
78
  }
77
79
  interface RegisteredAction {
78
80
  name: string;
@@ -88,6 +90,8 @@ interface RegisteredAction {
88
90
  navigateVia?: string[];
89
91
  /** How long (ms) to wait for this action's component to mount after navigation. */
90
92
  mountTimeout?: number;
93
+ /** True when registered by an `<AgentAction>` component (vs schema-only from registry). */
94
+ componentBacked?: boolean;
91
95
  }
92
96
  interface ToolSchema {
93
97
  name: string;
@@ -117,7 +121,7 @@ interface ExecutorConfig {
117
121
  /** Resolve an element from the AgentTarget registry. Used by fromParam steps. */
118
122
  resolveTarget?: (actionName: string, param: string, value: string, signal?: AbortSignal) => Promise<HTMLElement | null>;
119
123
  /** Resolve a named target from the AgentTarget registry. Used by fromTarget steps. */
120
- resolveNamedTarget?: (actionName: string, name: string, signal?: AbortSignal) => Promise<HTMLElement | null>;
124
+ resolveNamedTarget?: (actionName: string, name: string, signal?: AbortSignal, params?: Record<string, unknown>) => Promise<HTMLElement | null>;
121
125
  }
122
126
  interface AgentActionProviderProps {
123
127
  mode?: ExecutionMode;
@@ -194,6 +198,8 @@ interface AgentTargetProps {
194
198
  value?: string;
195
199
  /** Named target key (for fromTarget resolution — static elements inside popovers/dropdowns). */
196
200
  name?: string;
201
+ /** Run a callback to prepare component state before the agent interacts with this target. Runs in the child's scope so it can access internal state. */
202
+ prepareView?: (params: Record<string, unknown>) => void | Promise<void>;
197
203
  }
198
204
  /**
199
205
  * Register a DOM element as a selectable target for an agent action step.
@@ -217,7 +223,7 @@ interface AgentTargetProps {
217
223
  * </AgentTarget>
218
224
  * ```
219
225
  */
220
- declare function AgentTarget({ action, param, value, name, children }: AgentTargetProps): react_jsx_runtime.JSX.Element;
226
+ declare function AgentTarget({ action, param, value, name, prepareView, children }: AgentTargetProps): react_jsx_runtime.JSX.Element;
221
227
 
222
228
  interface AgentDevToolsProps {
223
229
  /** Default open state. */
package/dist/index.d.ts CHANGED
@@ -73,6 +73,8 @@ interface AgentTargetEntry {
73
73
  value?: string;
74
74
  /** Named target key — used for static lazy resolution via `fromTarget`. */
75
75
  name?: string;
76
+ /** Run a callback to prepare component state before the agent interacts with this target. */
77
+ prepareView?: (params: Record<string, unknown>) => void | Promise<void>;
76
78
  }
77
79
  interface RegisteredAction {
78
80
  name: string;
@@ -88,6 +90,8 @@ interface RegisteredAction {
88
90
  navigateVia?: string[];
89
91
  /** How long (ms) to wait for this action's component to mount after navigation. */
90
92
  mountTimeout?: number;
93
+ /** True when registered by an `<AgentAction>` component (vs schema-only from registry). */
94
+ componentBacked?: boolean;
91
95
  }
92
96
  interface ToolSchema {
93
97
  name: string;
@@ -117,7 +121,7 @@ interface ExecutorConfig {
117
121
  /** Resolve an element from the AgentTarget registry. Used by fromParam steps. */
118
122
  resolveTarget?: (actionName: string, param: string, value: string, signal?: AbortSignal) => Promise<HTMLElement | null>;
119
123
  /** Resolve a named target from the AgentTarget registry. Used by fromTarget steps. */
120
- resolveNamedTarget?: (actionName: string, name: string, signal?: AbortSignal) => Promise<HTMLElement | null>;
124
+ resolveNamedTarget?: (actionName: string, name: string, signal?: AbortSignal, params?: Record<string, unknown>) => Promise<HTMLElement | null>;
121
125
  }
122
126
  interface AgentActionProviderProps {
123
127
  mode?: ExecutionMode;
@@ -194,6 +198,8 @@ interface AgentTargetProps {
194
198
  value?: string;
195
199
  /** Named target key (for fromTarget resolution — static elements inside popovers/dropdowns). */
196
200
  name?: string;
201
+ /** Run a callback to prepare component state before the agent interacts with this target. Runs in the child's scope so it can access internal state. */
202
+ prepareView?: (params: Record<string, unknown>) => void | Promise<void>;
197
203
  }
198
204
  /**
199
205
  * Register a DOM element as a selectable target for an agent action step.
@@ -217,7 +223,7 @@ interface AgentTargetProps {
217
223
  * </AgentTarget>
218
224
  * ```
219
225
  */
220
- declare function AgentTarget({ action, param, value, name, children }: AgentTargetProps): react_jsx_runtime.JSX.Element;
226
+ declare function AgentTarget({ action, param, value, name, prepareView, children }: AgentTargetProps): react_jsx_runtime.JSX.Element;
221
227
 
222
228
  interface AgentDevToolsProps {
223
229
  /** Default open state. */
package/dist/index.js CHANGED
@@ -330,7 +330,7 @@ async function resolveStepElement(target, actionName, params, config) {
330
330
  return config.resolveTarget(actionName, target.fromParam, paramValue, config.signal);
331
331
  }
332
332
  if (target.fromTarget && config.resolveNamedTarget) {
333
- return config.resolveNamedTarget(actionName, target.fromTarget, config.signal);
333
+ return config.resolveNamedTarget(actionName, target.fromTarget, config.signal, params);
334
334
  }
335
335
  return target.element;
336
336
  }
@@ -542,7 +542,7 @@ function AgentActionProvider({
542
542
  []
543
543
  );
544
544
  const resolveNamedTarget = react.useCallback(
545
- async (actionName, name, signal) => {
545
+ async (actionName, name, signal, params) => {
546
546
  const maxWait = 3e3;
547
547
  const pollInterval = 50;
548
548
  const start = Date.now();
@@ -550,6 +550,9 @@ function AgentActionProvider({
550
550
  if (signal?.aborted) return null;
551
551
  for (const entry of targetsRef.current.values()) {
552
552
  if ((!entry.action || entry.action === actionName) && entry.name === name && entry.element.isConnected) {
553
+ if (entry.prepareView && params) {
554
+ await entry.prepareView(params);
555
+ }
553
556
  return entry.element;
554
557
  }
555
558
  }
@@ -567,7 +570,7 @@ function AgentActionProvider({
567
570
  while (Date.now() - start < maxWait) {
568
571
  if (signal?.aborted) return null;
569
572
  const current = actionsRef.current.get(name);
570
- if (current && current.getExecutionTargets().length > 0) {
573
+ if (current && (current.componentBacked || current.getExecutionTargets().length > 0)) {
571
574
  return current;
572
575
  }
573
576
  await new Promise((r) => setTimeout(r, pollInterval));
@@ -606,6 +609,15 @@ function AgentActionProvider({
606
609
  resolveTarget,
607
610
  resolveNamedTarget
608
611
  };
612
+ const schema = action.parameters;
613
+ if (schema?.safeParse) {
614
+ const validation = schema.safeParse(params ?? {});
615
+ if (!validation.success) {
616
+ const missing = validation.error.issues.map((i) => i.path.join(".")).filter(Boolean);
617
+ const error = missing.length > 0 ? `Required parameters missing: ${missing.join(", ")}` : validation.error.issues.map((i) => i.message).join("; ");
618
+ return { success: false, actionName, error };
619
+ }
620
+ }
609
621
  if (action.navigateVia && action.navigateVia.length > 0) {
610
622
  for (const viaName of action.navigateVia) {
611
623
  if (controller.signal.aborted) break;
@@ -629,7 +641,7 @@ function AgentActionProvider({
629
641
  }
630
642
  }
631
643
  const mounted = await waitForActionMount(actionName, controller.signal, action.mountTimeout ?? 1e4);
632
- if (!mounted || mounted.getExecutionTargets().length === 0) {
644
+ if (!mounted || !mounted.componentBacked) {
633
645
  return {
634
646
  success: false,
635
647
  actionName,
@@ -781,7 +793,8 @@ function AgentAction(props) {
781
793
  onExecute: onExecuteRef.current ? stableOnExecute : void 0,
782
794
  disabled,
783
795
  disabledReason,
784
- getExecutionTargets
796
+ getExecutionTargets,
797
+ componentBacked: true
785
798
  });
786
799
  return () => unregisterAction(name);
787
800
  }, [name, description, disabled, disabledReason, stableOnExecute, getExecutionTargets, registerAction, unregisterAction]);
@@ -838,10 +851,12 @@ function AgentStep({
838
851
  if (!children) return null;
839
852
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: wrapperRef, style: { display: "contents" }, children });
840
853
  }
841
- function AgentTarget({ action, param, value, name, children }) {
854
+ function AgentTarget({ action, param, value, name, prepareView, children }) {
842
855
  const id = react.useId();
843
856
  const wrapperRef = react.useRef(null);
844
857
  const context = react.useContext(AgentActionContext);
858
+ const prepareViewRef = react.useRef(prepareView);
859
+ prepareViewRef.current = prepareView;
845
860
  if (!context) {
846
861
  throw new Error("AgentTarget must be used within an AgentActionProvider");
847
862
  }
@@ -849,7 +864,7 @@ function AgentTarget({ action, param, value, name, children }) {
849
864
  react.useEffect(() => {
850
865
  const element = wrapperRef.current?.firstElementChild;
851
866
  if (element) {
852
- registerTarget(id, { action, param, value, name, element });
867
+ registerTarget(id, { action, param, value, name, element, prepareView: prepareViewRef.current });
853
868
  }
854
869
  return () => unregisterTarget(id);
855
870
  }, [id, action, param, value, name, registerTarget, unregisterTarget]);