@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/dist/index.js
CHANGED
|
@@ -437,6 +437,20 @@ async function executeAction(action, params, config) {
|
|
|
437
437
|
return executeGuided(action, params, config);
|
|
438
438
|
}
|
|
439
439
|
var AgentActionContext = react.createContext(null);
|
|
440
|
+
function definitionToRegisteredAction(def) {
|
|
441
|
+
return {
|
|
442
|
+
name: def.name,
|
|
443
|
+
description: def.description,
|
|
444
|
+
parameters: def.parameters,
|
|
445
|
+
onExecute: def.onExecute,
|
|
446
|
+
disabled: false,
|
|
447
|
+
disabledReason: void 0,
|
|
448
|
+
getExecutionTargets: () => [],
|
|
449
|
+
route: def.route,
|
|
450
|
+
navigateVia: def.navigateVia,
|
|
451
|
+
mountTimeout: def.mountTimeout
|
|
452
|
+
};
|
|
453
|
+
}
|
|
440
454
|
function AgentActionProvider({
|
|
441
455
|
mode = "guided",
|
|
442
456
|
stepDelay = 600,
|
|
@@ -446,24 +460,61 @@ function AgentActionProvider({
|
|
|
446
460
|
cursorEnabled = true,
|
|
447
461
|
children,
|
|
448
462
|
onExecutionStart,
|
|
449
|
-
onExecutionComplete
|
|
463
|
+
onExecutionComplete,
|
|
464
|
+
registry,
|
|
465
|
+
navigate
|
|
450
466
|
}) {
|
|
451
467
|
const actionsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
452
468
|
const targetsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
469
|
+
const registryRef = react.useRef(/* @__PURE__ */ new Map());
|
|
470
|
+
const navigateRef = react.useRef(navigate);
|
|
471
|
+
navigateRef.current = navigate;
|
|
453
472
|
const [version, setVersion] = react.useState(0);
|
|
454
473
|
const [isExecuting, setIsExecuting] = react.useState(false);
|
|
455
474
|
const currentExecutionRef = react.useRef(null);
|
|
475
|
+
react.useEffect(() => {
|
|
476
|
+
const newNames = /* @__PURE__ */ new Set();
|
|
477
|
+
for (const def of registry ?? []) {
|
|
478
|
+
newNames.add(def.name);
|
|
479
|
+
const registryAction = definitionToRegisteredAction(def);
|
|
480
|
+
registryRef.current.set(def.name, registryAction);
|
|
481
|
+
const existing = actionsRef.current.get(def.name);
|
|
482
|
+
if (!existing || existing.getExecutionTargets().length === 0) {
|
|
483
|
+
actionsRef.current.set(def.name, registryAction);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
for (const name of registryRef.current.keys()) {
|
|
487
|
+
if (!newNames.has(name)) {
|
|
488
|
+
registryRef.current.delete(name);
|
|
489
|
+
const current = actionsRef.current.get(name);
|
|
490
|
+
if (current && current.getExecutionTargets().length === 0) {
|
|
491
|
+
actionsRef.current.delete(name);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
setVersion((v) => v + 1);
|
|
496
|
+
}, [registry]);
|
|
456
497
|
const registerAction = react.useCallback((action) => {
|
|
457
498
|
const existing = actionsRef.current.get(action.name);
|
|
499
|
+
const registryAction = registryRef.current.get(action.name);
|
|
500
|
+
if (registryAction) {
|
|
501
|
+
if (!action.route) action.route = registryAction.route;
|
|
502
|
+
if (!action.navigateVia) action.navigateVia = registryAction.navigateVia;
|
|
503
|
+
if (action.mountTimeout == null) action.mountTimeout = registryAction.mountTimeout;
|
|
504
|
+
}
|
|
458
505
|
actionsRef.current.set(action.name, action);
|
|
459
506
|
if (!existing || existing.description !== action.description || existing.disabled !== action.disabled || existing.disabledReason !== action.disabledReason) {
|
|
460
507
|
setVersion((v) => v + 1);
|
|
461
508
|
}
|
|
462
509
|
}, []);
|
|
463
510
|
const unregisterAction = react.useCallback((name) => {
|
|
464
|
-
|
|
465
|
-
|
|
511
|
+
const registryAction = registryRef.current.get(name);
|
|
512
|
+
if (registryAction) {
|
|
513
|
+
actionsRef.current.set(name, registryAction);
|
|
514
|
+
} else {
|
|
515
|
+
actionsRef.current.delete(name);
|
|
466
516
|
}
|
|
517
|
+
setVersion((v) => v + 1);
|
|
467
518
|
}, []);
|
|
468
519
|
const registerTarget = react.useCallback((id, entry) => {
|
|
469
520
|
targetsRef.current.set(id, entry);
|
|
@@ -508,12 +559,29 @@ function AgentActionProvider({
|
|
|
508
559
|
},
|
|
509
560
|
[]
|
|
510
561
|
);
|
|
562
|
+
const waitForActionMount = react.useCallback(
|
|
563
|
+
async (name, signal, timeout = 5e3) => {
|
|
564
|
+
const maxWait = timeout;
|
|
565
|
+
const pollInterval = 50;
|
|
566
|
+
const start = Date.now();
|
|
567
|
+
while (Date.now() - start < maxWait) {
|
|
568
|
+
if (signal?.aborted) return null;
|
|
569
|
+
const current = actionsRef.current.get(name);
|
|
570
|
+
if (current && (current.componentBacked || current.getExecutionTargets().length > 0)) {
|
|
571
|
+
return current;
|
|
572
|
+
}
|
|
573
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
574
|
+
}
|
|
575
|
+
return actionsRef.current.get(name) ?? null;
|
|
576
|
+
},
|
|
577
|
+
[]
|
|
578
|
+
);
|
|
511
579
|
const execute = react.useCallback(
|
|
512
580
|
async (actionName, params) => {
|
|
513
581
|
currentExecutionRef.current?.abort();
|
|
514
582
|
const controller = new AbortController();
|
|
515
583
|
currentExecutionRef.current = controller;
|
|
516
|
-
|
|
584
|
+
let action = actionsRef.current.get(actionName);
|
|
517
585
|
if (!action) {
|
|
518
586
|
return { success: false, actionName, error: `Action "${actionName}" not found` };
|
|
519
587
|
}
|
|
@@ -527,7 +595,7 @@ function AgentActionProvider({
|
|
|
527
595
|
setIsExecuting(true);
|
|
528
596
|
onExecutionStart?.(actionName);
|
|
529
597
|
try {
|
|
530
|
-
const
|
|
598
|
+
const executorConfig = {
|
|
531
599
|
mode,
|
|
532
600
|
stepDelay,
|
|
533
601
|
overlayOpacity,
|
|
@@ -537,7 +605,68 @@ function AgentActionProvider({
|
|
|
537
605
|
signal: controller.signal,
|
|
538
606
|
resolveTarget,
|
|
539
607
|
resolveNamedTarget
|
|
540
|
-
}
|
|
608
|
+
};
|
|
609
|
+
const schema = action.parameters;
|
|
610
|
+
if (schema?.safeParse) {
|
|
611
|
+
const validation = schema.safeParse(params ?? {});
|
|
612
|
+
if (!validation.success) {
|
|
613
|
+
const missing = validation.error.issues.map((i) => i.path.join(".")).filter(Boolean);
|
|
614
|
+
const error = missing.length > 0 ? `Required parameters missing: ${missing.join(", ")}` : validation.error.issues.map((i) => i.message).join("; ");
|
|
615
|
+
return { success: false, actionName, error };
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (action.navigateVia && action.navigateVia.length > 0) {
|
|
619
|
+
for (const viaName of action.navigateVia) {
|
|
620
|
+
if (controller.signal.aborted) break;
|
|
621
|
+
const viaRegistered = actionsRef.current.get(viaName);
|
|
622
|
+
const viaTimeout = viaRegistered?.mountTimeout ?? 1e4;
|
|
623
|
+
const viaAction = await waitForActionMount(viaName, controller.signal, viaTimeout);
|
|
624
|
+
if (!viaAction || viaAction.getExecutionTargets().length === 0) {
|
|
625
|
+
return {
|
|
626
|
+
success: false,
|
|
627
|
+
actionName,
|
|
628
|
+
error: `Navigation chain action "${viaName}" not found or has no targets`
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
const viaResult = await executeAction(viaAction, {}, executorConfig);
|
|
632
|
+
if (!viaResult.success) {
|
|
633
|
+
return {
|
|
634
|
+
success: false,
|
|
635
|
+
actionName,
|
|
636
|
+
error: `Navigation chain failed at "${viaName}": ${viaResult.error}`
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
const mounted = await waitForActionMount(actionName, controller.signal, action.mountTimeout ?? 1e4);
|
|
641
|
+
if (!mounted || !mounted.componentBacked) {
|
|
642
|
+
return {
|
|
643
|
+
success: false,
|
|
644
|
+
actionName,
|
|
645
|
+
error: `Action "${actionName}" did not mount after navigation chain \u2014 the page may require authentication or failed to load`
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
action = mounted;
|
|
649
|
+
} else {
|
|
650
|
+
const targets = action.getExecutionTargets();
|
|
651
|
+
if (targets.length === 0 && action.route && navigateRef.current) {
|
|
652
|
+
const path = action.route(params ?? {});
|
|
653
|
+
await navigateRef.current(path);
|
|
654
|
+
const mounted = await waitForActionMount(actionName, controller.signal, action.mountTimeout);
|
|
655
|
+
if (mounted) {
|
|
656
|
+
action = mounted;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
if (action.disabled) {
|
|
661
|
+
const result2 = {
|
|
662
|
+
success: false,
|
|
663
|
+
actionName,
|
|
664
|
+
error: action.disabledReason || "Action is disabled"
|
|
665
|
+
};
|
|
666
|
+
onExecutionComplete?.(result2);
|
|
667
|
+
return result2;
|
|
668
|
+
}
|
|
669
|
+
const result = await executeAction(action, params ?? {}, executorConfig);
|
|
541
670
|
onExecutionComplete?.(result);
|
|
542
671
|
return result;
|
|
543
672
|
} catch (err) {
|
|
@@ -555,7 +684,7 @@ function AgentActionProvider({
|
|
|
555
684
|
}
|
|
556
685
|
}
|
|
557
686
|
},
|
|
558
|
-
[mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, onExecutionStart, onExecutionComplete, resolveTarget, resolveNamedTarget]
|
|
687
|
+
[mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, onExecutionStart, onExecutionComplete, resolveTarget, resolveNamedTarget, waitForActionMount]
|
|
559
688
|
);
|
|
560
689
|
const availableActions = react.useMemo(
|
|
561
690
|
() => Array.from(actionsRef.current.values()).map((a) => ({
|
|
@@ -600,19 +729,24 @@ function AgentActionProvider({
|
|
|
600
729
|
return /* @__PURE__ */ jsxRuntime.jsx(AgentActionContext.Provider, { value: contextValue, children });
|
|
601
730
|
}
|
|
602
731
|
var AgentStepContext = react.createContext(null);
|
|
603
|
-
function AgentAction({
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
732
|
+
function AgentAction(props) {
|
|
733
|
+
const {
|
|
734
|
+
action,
|
|
735
|
+
onExecute,
|
|
736
|
+
disabled = false,
|
|
737
|
+
disabledReason,
|
|
738
|
+
children
|
|
739
|
+
} = props;
|
|
740
|
+
const name = props.name ?? action?.name;
|
|
741
|
+
const description = props.description ?? action?.description ?? "";
|
|
742
|
+
const parameters = props.parameters ?? action?.parameters;
|
|
612
743
|
const context = react.useContext(AgentActionContext);
|
|
613
744
|
if (!context) {
|
|
614
745
|
throw new Error("AgentAction must be used within an AgentActionProvider");
|
|
615
746
|
}
|
|
747
|
+
if (!name) {
|
|
748
|
+
throw new Error('AgentAction requires either a "name" prop or an "action" prop');
|
|
749
|
+
}
|
|
616
750
|
const wrapperRef = react.useRef(null);
|
|
617
751
|
const stepsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
618
752
|
const onExecuteRef = react.useRef(onExecute);
|
|
@@ -656,7 +790,8 @@ function AgentAction({
|
|
|
656
790
|
onExecute: onExecuteRef.current ? stableOnExecute : void 0,
|
|
657
791
|
disabled,
|
|
658
792
|
disabledReason,
|
|
659
|
-
getExecutionTargets
|
|
793
|
+
getExecutionTargets,
|
|
794
|
+
componentBacked: true
|
|
660
795
|
});
|
|
661
796
|
return () => unregisterAction(name);
|
|
662
797
|
}, [name, description, disabled, disabledReason, stableOnExecute, getExecutionTargets, registerAction, unregisterAction]);
|
|
@@ -1251,20 +1386,34 @@ function useAgentCommandRouter(fallback, getActionName) {
|
|
|
1251
1386
|
const actionName = getActionName(command);
|
|
1252
1387
|
const isRegistered = availableActions.some((a) => a.name === actionName && !a.disabled);
|
|
1253
1388
|
if (isRegistered) {
|
|
1254
|
-
await execute(actionName, command);
|
|
1255
|
-
return;
|
|
1389
|
+
return await execute(actionName, command);
|
|
1256
1390
|
}
|
|
1257
1391
|
await fallback?.(command);
|
|
1392
|
+
return void 0;
|
|
1258
1393
|
},
|
|
1259
1394
|
[execute, availableActions, fallback, getActionName]
|
|
1260
1395
|
);
|
|
1261
1396
|
}
|
|
1262
1397
|
|
|
1398
|
+
// src/core/defineAction.ts
|
|
1399
|
+
function defineAction(config) {
|
|
1400
|
+
return {
|
|
1401
|
+
name: config.name,
|
|
1402
|
+
description: config.description,
|
|
1403
|
+
parameters: config.parameters,
|
|
1404
|
+
route: config.route,
|
|
1405
|
+
onExecute: config.onExecute,
|
|
1406
|
+
navigateVia: config.navigateVia,
|
|
1407
|
+
mountTimeout: config.mountTimeout
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1263
1411
|
exports.AgentAction = AgentAction;
|
|
1264
1412
|
exports.AgentActionProvider = AgentActionProvider;
|
|
1265
1413
|
exports.AgentDevTools = AgentDevTools;
|
|
1266
1414
|
exports.AgentStep = AgentStep;
|
|
1267
1415
|
exports.AgentTarget = AgentTarget;
|
|
1416
|
+
exports.defineAction = defineAction;
|
|
1268
1417
|
exports.generateToolSchemas = generateToolSchemas;
|
|
1269
1418
|
exports.useAgentAction = useAgentAction;
|
|
1270
1419
|
exports.useAgentActions = useAgentActions;
|