@mydatavalue/polter 0.1.0 → 0.1.1

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, useRef, useState, useCallback, useMemo, useContext, useEffect, useId } from 'react';
1
+ import { createContext, useRef, useState, useEffect, useCallback, useMemo, useContext, useId } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
 
4
4
  // src/components/AgentActionProvider.tsx
@@ -435,6 +435,20 @@ async function executeAction(action, params, config) {
435
435
  return executeGuided(action, params, config);
436
436
  }
437
437
  var AgentActionContext = createContext(null);
438
+ function definitionToRegisteredAction(def) {
439
+ return {
440
+ name: def.name,
441
+ description: def.description,
442
+ parameters: def.parameters,
443
+ onExecute: def.onExecute,
444
+ disabled: false,
445
+ disabledReason: void 0,
446
+ getExecutionTargets: () => [],
447
+ route: def.route,
448
+ navigateVia: def.navigateVia,
449
+ mountTimeout: def.mountTimeout
450
+ };
451
+ }
438
452
  function AgentActionProvider({
439
453
  mode = "guided",
440
454
  stepDelay = 600,
@@ -444,24 +458,61 @@ function AgentActionProvider({
444
458
  cursorEnabled = true,
445
459
  children,
446
460
  onExecutionStart,
447
- onExecutionComplete
461
+ onExecutionComplete,
462
+ registry,
463
+ navigate
448
464
  }) {
449
465
  const actionsRef = useRef(/* @__PURE__ */ new Map());
450
466
  const targetsRef = useRef(/* @__PURE__ */ new Map());
467
+ const registryRef = useRef(/* @__PURE__ */ new Map());
468
+ const navigateRef = useRef(navigate);
469
+ navigateRef.current = navigate;
451
470
  const [version, setVersion] = useState(0);
452
471
  const [isExecuting, setIsExecuting] = useState(false);
453
472
  const currentExecutionRef = useRef(null);
473
+ useEffect(() => {
474
+ const newNames = /* @__PURE__ */ new Set();
475
+ for (const def of registry ?? []) {
476
+ newNames.add(def.name);
477
+ const registryAction = definitionToRegisteredAction(def);
478
+ registryRef.current.set(def.name, registryAction);
479
+ const existing = actionsRef.current.get(def.name);
480
+ if (!existing || existing.getExecutionTargets().length === 0) {
481
+ actionsRef.current.set(def.name, registryAction);
482
+ }
483
+ }
484
+ for (const name of registryRef.current.keys()) {
485
+ if (!newNames.has(name)) {
486
+ registryRef.current.delete(name);
487
+ const current = actionsRef.current.get(name);
488
+ if (current && current.getExecutionTargets().length === 0) {
489
+ actionsRef.current.delete(name);
490
+ }
491
+ }
492
+ }
493
+ setVersion((v) => v + 1);
494
+ }, [registry]);
454
495
  const registerAction = useCallback((action) => {
455
496
  const existing = actionsRef.current.get(action.name);
497
+ const registryAction = registryRef.current.get(action.name);
498
+ if (registryAction) {
499
+ if (!action.route) action.route = registryAction.route;
500
+ if (!action.navigateVia) action.navigateVia = registryAction.navigateVia;
501
+ if (action.mountTimeout == null) action.mountTimeout = registryAction.mountTimeout;
502
+ }
456
503
  actionsRef.current.set(action.name, action);
457
504
  if (!existing || existing.description !== action.description || existing.disabled !== action.disabled || existing.disabledReason !== action.disabledReason) {
458
505
  setVersion((v) => v + 1);
459
506
  }
460
507
  }, []);
461
508
  const unregisterAction = useCallback((name) => {
462
- if (actionsRef.current.delete(name)) {
463
- setVersion((v) => v + 1);
509
+ const registryAction = registryRef.current.get(name);
510
+ if (registryAction) {
511
+ actionsRef.current.set(name, registryAction);
512
+ } else {
513
+ actionsRef.current.delete(name);
464
514
  }
515
+ setVersion((v) => v + 1);
465
516
  }, []);
466
517
  const registerTarget = useCallback((id, entry) => {
467
518
  targetsRef.current.set(id, entry);
@@ -506,12 +557,29 @@ function AgentActionProvider({
506
557
  },
507
558
  []
508
559
  );
560
+ const waitForActionMount = useCallback(
561
+ async (name, signal, timeout = 5e3) => {
562
+ const maxWait = timeout;
563
+ const pollInterval = 50;
564
+ const start = Date.now();
565
+ while (Date.now() - start < maxWait) {
566
+ if (signal?.aborted) return null;
567
+ const current = actionsRef.current.get(name);
568
+ if (current && current.getExecutionTargets().length > 0) {
569
+ return current;
570
+ }
571
+ await new Promise((r) => setTimeout(r, pollInterval));
572
+ }
573
+ return actionsRef.current.get(name) ?? null;
574
+ },
575
+ []
576
+ );
509
577
  const execute = useCallback(
510
578
  async (actionName, params) => {
511
579
  currentExecutionRef.current?.abort();
512
580
  const controller = new AbortController();
513
581
  currentExecutionRef.current = controller;
514
- const action = actionsRef.current.get(actionName);
582
+ let action = actionsRef.current.get(actionName);
515
583
  if (!action) {
516
584
  return { success: false, actionName, error: `Action "${actionName}" not found` };
517
585
  }
@@ -525,7 +593,7 @@ function AgentActionProvider({
525
593
  setIsExecuting(true);
526
594
  onExecutionStart?.(actionName);
527
595
  try {
528
- const result = await executeAction(action, params ?? {}, {
596
+ const executorConfig = {
529
597
  mode,
530
598
  stepDelay,
531
599
  overlayOpacity,
@@ -535,7 +603,59 @@ function AgentActionProvider({
535
603
  signal: controller.signal,
536
604
  resolveTarget,
537
605
  resolveNamedTarget
538
- });
606
+ };
607
+ if (action.navigateVia && action.navigateVia.length > 0) {
608
+ for (const viaName of action.navigateVia) {
609
+ if (controller.signal.aborted) break;
610
+ const viaRegistered = actionsRef.current.get(viaName);
611
+ const viaTimeout = viaRegistered?.mountTimeout ?? 1e4;
612
+ const viaAction = await waitForActionMount(viaName, controller.signal, viaTimeout);
613
+ if (!viaAction || viaAction.getExecutionTargets().length === 0) {
614
+ return {
615
+ success: false,
616
+ actionName,
617
+ error: `Navigation chain action "${viaName}" not found or has no targets`
618
+ };
619
+ }
620
+ const viaResult = await executeAction(viaAction, {}, executorConfig);
621
+ if (!viaResult.success) {
622
+ return {
623
+ success: false,
624
+ actionName,
625
+ error: `Navigation chain failed at "${viaName}": ${viaResult.error}`
626
+ };
627
+ }
628
+ }
629
+ const mounted = await waitForActionMount(actionName, controller.signal, action.mountTimeout ?? 1e4);
630
+ if (!mounted || mounted.getExecutionTargets().length === 0) {
631
+ return {
632
+ success: false,
633
+ actionName,
634
+ error: `Action "${actionName}" did not mount after navigation chain \u2014 the page may require authentication or failed to load`
635
+ };
636
+ }
637
+ action = mounted;
638
+ } else {
639
+ const targets = action.getExecutionTargets();
640
+ if (targets.length === 0 && action.route && navigateRef.current) {
641
+ const path = action.route(params ?? {});
642
+ await navigateRef.current(path);
643
+ const mounted = await waitForActionMount(actionName, controller.signal, action.mountTimeout);
644
+ if (mounted) {
645
+ action = mounted;
646
+ }
647
+ }
648
+ }
649
+ if (action.disabled) {
650
+ const result2 = {
651
+ success: false,
652
+ actionName,
653
+ error: action.disabledReason || "Action is disabled"
654
+ };
655
+ onExecutionComplete?.(result2);
656
+ return result2;
657
+ }
658
+ const result = await executeAction(action, params ?? {}, executorConfig);
539
659
  onExecutionComplete?.(result);
540
660
  return result;
541
661
  } catch (err) {
@@ -553,7 +673,7 @@ function AgentActionProvider({
553
673
  }
554
674
  }
555
675
  },
556
- [mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, onExecutionStart, onExecutionComplete, resolveTarget, resolveNamedTarget]
676
+ [mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, onExecutionStart, onExecutionComplete, resolveTarget, resolveNamedTarget, waitForActionMount]
557
677
  );
558
678
  const availableActions = useMemo(
559
679
  () => Array.from(actionsRef.current.values()).map((a) => ({
@@ -598,19 +718,24 @@ function AgentActionProvider({
598
718
  return /* @__PURE__ */ jsx(AgentActionContext.Provider, { value: contextValue, children });
599
719
  }
600
720
  var AgentStepContext = createContext(null);
601
- function AgentAction({
602
- name,
603
- description,
604
- parameters,
605
- onExecute,
606
- disabled = false,
607
- disabledReason,
608
- children
609
- }) {
721
+ function AgentAction(props) {
722
+ const {
723
+ action,
724
+ onExecute,
725
+ disabled = false,
726
+ disabledReason,
727
+ children
728
+ } = props;
729
+ const name = props.name ?? action?.name;
730
+ const description = props.description ?? action?.description ?? "";
731
+ const parameters = props.parameters ?? action?.parameters;
610
732
  const context = useContext(AgentActionContext);
611
733
  if (!context) {
612
734
  throw new Error("AgentAction must be used within an AgentActionProvider");
613
735
  }
736
+ if (!name) {
737
+ throw new Error('AgentAction requires either a "name" prop or an "action" prop');
738
+ }
614
739
  const wrapperRef = useRef(null);
615
740
  const stepsRef = useRef(/* @__PURE__ */ new Map());
616
741
  const onExecuteRef = useRef(onExecute);
@@ -1249,15 +1374,28 @@ function useAgentCommandRouter(fallback, getActionName) {
1249
1374
  const actionName = getActionName(command);
1250
1375
  const isRegistered = availableActions.some((a) => a.name === actionName && !a.disabled);
1251
1376
  if (isRegistered) {
1252
- await execute(actionName, command);
1253
- return;
1377
+ return await execute(actionName, command);
1254
1378
  }
1255
1379
  await fallback?.(command);
1380
+ return void 0;
1256
1381
  },
1257
1382
  [execute, availableActions, fallback, getActionName]
1258
1383
  );
1259
1384
  }
1260
1385
 
1261
- export { AgentAction, AgentActionProvider, AgentDevTools, AgentStep, AgentTarget, generateToolSchemas, useAgentAction, useAgentActions, useAgentCommandRouter, zodToJsonSchema };
1386
+ // src/core/defineAction.ts
1387
+ function defineAction(config) {
1388
+ return {
1389
+ name: config.name,
1390
+ description: config.description,
1391
+ parameters: config.parameters,
1392
+ route: config.route,
1393
+ onExecute: config.onExecute,
1394
+ navigateVia: config.navigateVia,
1395
+ mountTimeout: config.mountTimeout
1396
+ };
1397
+ }
1398
+
1399
+ export { AgentAction, AgentActionProvider, AgentDevTools, AgentStep, AgentTarget, defineAction, generateToolSchemas, useAgentAction, useAgentActions, useAgentCommandRouter, zodToJsonSchema };
1262
1400
  //# sourceMappingURL=index.mjs.map
1263
1401
  //# sourceMappingURL=index.mjs.map