@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/README.md +79 -172
- package/dist/index.d.mts +75 -9
- package/dist/index.d.ts +75 -9
- package/dist/index.js +157 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +158 -20
- 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.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,59 @@ function AgentActionProvider({
|
|
|
537
605
|
signal: controller.signal,
|
|
538
606
|
resolveTarget,
|
|
539
607
|
resolveNamedTarget
|
|
540
|
-
}
|
|
608
|
+
};
|
|
609
|
+
if (action.navigateVia && action.navigateVia.length > 0) {
|
|
610
|
+
for (const viaName of action.navigateVia) {
|
|
611
|
+
if (controller.signal.aborted) break;
|
|
612
|
+
const viaRegistered = actionsRef.current.get(viaName);
|
|
613
|
+
const viaTimeout = viaRegistered?.mountTimeout ?? 1e4;
|
|
614
|
+
const viaAction = await waitForActionMount(viaName, controller.signal, viaTimeout);
|
|
615
|
+
if (!viaAction || viaAction.getExecutionTargets().length === 0) {
|
|
616
|
+
return {
|
|
617
|
+
success: false,
|
|
618
|
+
actionName,
|
|
619
|
+
error: `Navigation chain action "${viaName}" not found or has no targets`
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
const viaResult = await executeAction(viaAction, {}, executorConfig);
|
|
623
|
+
if (!viaResult.success) {
|
|
624
|
+
return {
|
|
625
|
+
success: false,
|
|
626
|
+
actionName,
|
|
627
|
+
error: `Navigation chain failed at "${viaName}": ${viaResult.error}`
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
const mounted = await waitForActionMount(actionName, controller.signal, action.mountTimeout ?? 1e4);
|
|
632
|
+
if (!mounted || mounted.getExecutionTargets().length === 0) {
|
|
633
|
+
return {
|
|
634
|
+
success: false,
|
|
635
|
+
actionName,
|
|
636
|
+
error: `Action "${actionName}" did not mount after navigation chain \u2014 the page may require authentication or failed to load`
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
action = mounted;
|
|
640
|
+
} else {
|
|
641
|
+
const targets = action.getExecutionTargets();
|
|
642
|
+
if (targets.length === 0 && action.route && navigateRef.current) {
|
|
643
|
+
const path = action.route(params ?? {});
|
|
644
|
+
await navigateRef.current(path);
|
|
645
|
+
const mounted = await waitForActionMount(actionName, controller.signal, action.mountTimeout);
|
|
646
|
+
if (mounted) {
|
|
647
|
+
action = mounted;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if (action.disabled) {
|
|
652
|
+
const result2 = {
|
|
653
|
+
success: false,
|
|
654
|
+
actionName,
|
|
655
|
+
error: action.disabledReason || "Action is disabled"
|
|
656
|
+
};
|
|
657
|
+
onExecutionComplete?.(result2);
|
|
658
|
+
return result2;
|
|
659
|
+
}
|
|
660
|
+
const result = await executeAction(action, params ?? {}, executorConfig);
|
|
541
661
|
onExecutionComplete?.(result);
|
|
542
662
|
return result;
|
|
543
663
|
} catch (err) {
|
|
@@ -555,7 +675,7 @@ function AgentActionProvider({
|
|
|
555
675
|
}
|
|
556
676
|
}
|
|
557
677
|
},
|
|
558
|
-
[mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, onExecutionStart, onExecutionComplete, resolveTarget, resolveNamedTarget]
|
|
678
|
+
[mode, stepDelay, overlayOpacity, spotlightPadding, tooltipEnabled, cursorEnabled, onExecutionStart, onExecutionComplete, resolveTarget, resolveNamedTarget, waitForActionMount]
|
|
559
679
|
);
|
|
560
680
|
const availableActions = react.useMemo(
|
|
561
681
|
() => Array.from(actionsRef.current.values()).map((a) => ({
|
|
@@ -600,19 +720,24 @@ function AgentActionProvider({
|
|
|
600
720
|
return /* @__PURE__ */ jsxRuntime.jsx(AgentActionContext.Provider, { value: contextValue, children });
|
|
601
721
|
}
|
|
602
722
|
var AgentStepContext = react.createContext(null);
|
|
603
|
-
function AgentAction({
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
723
|
+
function AgentAction(props) {
|
|
724
|
+
const {
|
|
725
|
+
action,
|
|
726
|
+
onExecute,
|
|
727
|
+
disabled = false,
|
|
728
|
+
disabledReason,
|
|
729
|
+
children
|
|
730
|
+
} = props;
|
|
731
|
+
const name = props.name ?? action?.name;
|
|
732
|
+
const description = props.description ?? action?.description ?? "";
|
|
733
|
+
const parameters = props.parameters ?? action?.parameters;
|
|
612
734
|
const context = react.useContext(AgentActionContext);
|
|
613
735
|
if (!context) {
|
|
614
736
|
throw new Error("AgentAction must be used within an AgentActionProvider");
|
|
615
737
|
}
|
|
738
|
+
if (!name) {
|
|
739
|
+
throw new Error('AgentAction requires either a "name" prop or an "action" prop');
|
|
740
|
+
}
|
|
616
741
|
const wrapperRef = react.useRef(null);
|
|
617
742
|
const stepsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
618
743
|
const onExecuteRef = react.useRef(onExecute);
|
|
@@ -1251,20 +1376,34 @@ function useAgentCommandRouter(fallback, getActionName) {
|
|
|
1251
1376
|
const actionName = getActionName(command);
|
|
1252
1377
|
const isRegistered = availableActions.some((a) => a.name === actionName && !a.disabled);
|
|
1253
1378
|
if (isRegistered) {
|
|
1254
|
-
await execute(actionName, command);
|
|
1255
|
-
return;
|
|
1379
|
+
return await execute(actionName, command);
|
|
1256
1380
|
}
|
|
1257
1381
|
await fallback?.(command);
|
|
1382
|
+
return void 0;
|
|
1258
1383
|
},
|
|
1259
1384
|
[execute, availableActions, fallback, getActionName]
|
|
1260
1385
|
);
|
|
1261
1386
|
}
|
|
1262
1387
|
|
|
1388
|
+
// src/core/defineAction.ts
|
|
1389
|
+
function defineAction(config) {
|
|
1390
|
+
return {
|
|
1391
|
+
name: config.name,
|
|
1392
|
+
description: config.description,
|
|
1393
|
+
parameters: config.parameters,
|
|
1394
|
+
route: config.route,
|
|
1395
|
+
onExecute: config.onExecute,
|
|
1396
|
+
navigateVia: config.navigateVia,
|
|
1397
|
+
mountTimeout: config.mountTimeout
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1263
1401
|
exports.AgentAction = AgentAction;
|
|
1264
1402
|
exports.AgentActionProvider = AgentActionProvider;
|
|
1265
1403
|
exports.AgentDevTools = AgentDevTools;
|
|
1266
1404
|
exports.AgentStep = AgentStep;
|
|
1267
1405
|
exports.AgentTarget = AgentTarget;
|
|
1406
|
+
exports.defineAction = defineAction;
|
|
1268
1407
|
exports.generateToolSchemas = generateToolSchemas;
|
|
1269
1408
|
exports.useAgentAction = useAgentAction;
|
|
1270
1409
|
exports.useAgentActions = useAgentActions;
|