@particle-academy/agent-integrations 0.27.0 → 0.28.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/{chunk-HKQBG2HZ.js → chunk-5KLUYF4D.js} +3 -3
- package/dist/{chunk-HKQBG2HZ.js.map → chunk-5KLUYF4D.js.map} +1 -1
- package/dist/{chunk-FUI7KXE7.js → chunk-KMSRG5KH.js} +35 -2
- package/dist/chunk-KMSRG5KH.js.map +1 -0
- package/dist/components-shared-whiteboard.cjs +32 -0
- package/dist/components-shared-whiteboard.cjs.map +1 -1
- package/dist/components-shared-whiteboard.js +2 -2
- package/dist/index.cjs +96 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +68 -11
- package/dist/index.js.map +1 -1
- package/dist/sharing/index.d.cts +1 -0
- package/dist/sharing/index.d.ts +1 -0
- package/dist/sharing.cjs +32 -0
- package/dist/sharing.cjs.map +1 -1
- package/dist/sharing.js +2 -1
- package/package.json +1 -1
- package/dist/chunk-FUI7KXE7.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ShareControls, AgentCursor, AgentActivityHighlight, AgentPanel } from './chunk-
|
|
2
|
-
import { createSessionDescriptor, attachSseRelay } from './chunk-
|
|
1
|
+
import { ShareControls, AgentCursor, AgentActivityHighlight, AgentPanel } from './chunk-5KLUYF4D.js';
|
|
2
|
+
import { createSessionDescriptor, attachSseRelay } from './chunk-KMSRG5KH.js';
|
|
3
3
|
import { attachInProcess } from './chunk-AFUULW5E.js';
|
|
4
4
|
import { registerWhiteboardBridge } from './chunk-AAMQOXZC.js';
|
|
5
5
|
import './chunk-ULJL53DL.js';
|
package/dist/index.cjs
CHANGED
|
@@ -2772,6 +2772,17 @@ function registerNavigationBridge(host, options) {
|
|
|
2772
2772
|
const agent = { ...DEFAULT_AGENT11, ...options.agent ?? {} };
|
|
2773
2773
|
const pendingMode = options.pendingMode ?? true;
|
|
2774
2774
|
const disposers = [];
|
|
2775
|
+
let groundedRevision = null;
|
|
2776
|
+
const staleIntent = () => {
|
|
2777
|
+
const current = adapter.getRevision?.();
|
|
2778
|
+
if (current === void 0) return null;
|
|
2779
|
+
if (groundedRevision === null || groundedRevision !== current) {
|
|
2780
|
+
return errorResult(
|
|
2781
|
+
`Human took control at page revision ${current}. This agent action was cancelled; call page_describe before acting again.`
|
|
2782
|
+
);
|
|
2783
|
+
}
|
|
2784
|
+
return null;
|
|
2785
|
+
};
|
|
2775
2786
|
ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
|
|
2776
2787
|
const target = (label, elementId) => ({
|
|
2777
2788
|
kind: "navigation",
|
|
@@ -2812,6 +2823,11 @@ function registerNavigationBridge(host, options) {
|
|
|
2812
2823
|
[],
|
|
2813
2824
|
() => {
|
|
2814
2825
|
const snap = adapter.describe();
|
|
2826
|
+
const revision = adapter.getRevision?.();
|
|
2827
|
+
if (revision !== void 0) {
|
|
2828
|
+
snap.revision = revision;
|
|
2829
|
+
groundedRevision = revision;
|
|
2830
|
+
}
|
|
2815
2831
|
const text = [
|
|
2816
2832
|
`URL: ${snap.url}`,
|
|
2817
2833
|
`Title: ${snap.title}`,
|
|
@@ -2820,7 +2836,7 @@ function registerNavigationBridge(host, options) {
|
|
|
2820
2836
|
].join("\n");
|
|
2821
2837
|
return textResult(text, snap);
|
|
2822
2838
|
},
|
|
2823
|
-
|
|
2839
|
+
() => target("Inspect page")
|
|
2824
2840
|
);
|
|
2825
2841
|
reg(
|
|
2826
2842
|
"page_read",
|
|
@@ -2828,7 +2844,25 @@ function registerNavigationBridge(host, options) {
|
|
|
2828
2844
|
{},
|
|
2829
2845
|
[],
|
|
2830
2846
|
() => textResult(adapter.read ? adapter.read() : "(host did not provide page text)"),
|
|
2831
|
-
|
|
2847
|
+
() => target("Read page")
|
|
2848
|
+
);
|
|
2849
|
+
reg(
|
|
2850
|
+
"page_focus",
|
|
2851
|
+
"Move the agent's visible focus to an interactive element by stable handle without activating it.",
|
|
2852
|
+
{ handle: { type: "string" } },
|
|
2853
|
+
["handle"],
|
|
2854
|
+
(args) => {
|
|
2855
|
+
const stale = staleIntent();
|
|
2856
|
+
if (stale) return stale;
|
|
2857
|
+
const handle = String(args.handle ?? "");
|
|
2858
|
+
const action = adapter.describe().actions.find((candidate) => candidate.handle === handle);
|
|
2859
|
+
if (!action) return errorResult(`No element for handle "${handle}"`);
|
|
2860
|
+
return textResult(`Focused ${handle}`, {
|
|
2861
|
+
handle,
|
|
2862
|
+
rect: adapter.rectFor?.(handle) ?? void 0
|
|
2863
|
+
});
|
|
2864
|
+
},
|
|
2865
|
+
(args) => target(`Focus ${String(args.handle ?? "")}`, String(args.handle ?? ""))
|
|
2832
2866
|
);
|
|
2833
2867
|
reg(
|
|
2834
2868
|
"nav_visit",
|
|
@@ -2836,6 +2870,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2836
2870
|
{ url: { type: "string", description: "Path like /packages or an absolute URL." } },
|
|
2837
2871
|
["url"],
|
|
2838
2872
|
async (args) => {
|
|
2873
|
+
const stale = staleIntent();
|
|
2874
|
+
if (stale) return stale;
|
|
2839
2875
|
const url = String(args.url ?? "");
|
|
2840
2876
|
if (!url) return errorResult("url is required");
|
|
2841
2877
|
const from = adapter.getLocation().url;
|
|
@@ -2862,6 +2898,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2862
2898
|
{},
|
|
2863
2899
|
[],
|
|
2864
2900
|
async () => {
|
|
2901
|
+
const stale = staleIntent();
|
|
2902
|
+
if (stale) return stale;
|
|
2865
2903
|
if (!adapter.back) return errorResult("Host did not provide back navigation.");
|
|
2866
2904
|
await adapter.back();
|
|
2867
2905
|
return textResult("Went back");
|
|
@@ -2874,6 +2912,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2874
2912
|
{},
|
|
2875
2913
|
[],
|
|
2876
2914
|
async () => {
|
|
2915
|
+
const stale = staleIntent();
|
|
2916
|
+
if (stale) return stale;
|
|
2877
2917
|
if (!adapter.forward) return errorResult("Host did not provide forward navigation.");
|
|
2878
2918
|
await adapter.forward();
|
|
2879
2919
|
return textResult("Went forward");
|
|
@@ -2890,6 +2930,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2890
2930
|
},
|
|
2891
2931
|
[],
|
|
2892
2932
|
(args) => {
|
|
2933
|
+
const stale = staleIntent();
|
|
2934
|
+
if (stale) return stale;
|
|
2893
2935
|
const handle = typeof args.handle === "string" ? args.handle : void 0;
|
|
2894
2936
|
adapter.scrollTo({
|
|
2895
2937
|
handle,
|
|
@@ -2906,6 +2948,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2906
2948
|
{ dy: { type: "number" } },
|
|
2907
2949
|
["dy"],
|
|
2908
2950
|
(args) => {
|
|
2951
|
+
const stale = staleIntent();
|
|
2952
|
+
if (stale) return stale;
|
|
2909
2953
|
adapter.scrollBy(Number(args.dy ?? 0));
|
|
2910
2954
|
return textResult(`Scrolled by ${Number(args.dy ?? 0)}px`);
|
|
2911
2955
|
},
|
|
@@ -2920,6 +2964,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2920
2964
|
},
|
|
2921
2965
|
["handle", "value"],
|
|
2922
2966
|
(args) => {
|
|
2967
|
+
const stale = staleIntent();
|
|
2968
|
+
if (stale) return stale;
|
|
2923
2969
|
const handle = String(args.handle ?? "");
|
|
2924
2970
|
const res = adapter.setField(handle, args.value);
|
|
2925
2971
|
if (!res.ok) return errorResult(res.error ?? `Could not set ${handle}`);
|
|
@@ -2933,6 +2979,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2933
2979
|
{ handle: { type: "string" } },
|
|
2934
2980
|
["handle"],
|
|
2935
2981
|
async (args) => {
|
|
2982
|
+
const stale = staleIntent();
|
|
2983
|
+
if (stale) return stale;
|
|
2936
2984
|
const handle = String(args.handle ?? "");
|
|
2937
2985
|
const action = adapter.describe().actions.find((a) => a.handle === handle);
|
|
2938
2986
|
const rect = adapter.rectFor?.(handle) ?? void 0;
|
|
@@ -2952,6 +3000,8 @@ function registerNavigationBridge(host, options) {
|
|
|
2952
3000
|
{ handle: { type: "string" } },
|
|
2953
3001
|
["handle"],
|
|
2954
3002
|
async (args) => {
|
|
3003
|
+
const stale = staleIntent();
|
|
3004
|
+
if (stale) return stale;
|
|
2955
3005
|
const handle = String(args.handle ?? "");
|
|
2956
3006
|
const rect = adapter.rectFor?.(handle) ?? void 0;
|
|
2957
3007
|
if (pendingMode && adapter.confirm) {
|
|
@@ -3853,6 +3903,7 @@ function constantTimeEqual(a, b) {
|
|
|
3853
3903
|
}
|
|
3854
3904
|
|
|
3855
3905
|
// src/sharing/sse-relay.ts
|
|
3906
|
+
init_registry();
|
|
3856
3907
|
var SseRelayTransport = class {
|
|
3857
3908
|
constructor(options) {
|
|
3858
3909
|
this.disposed = false;
|
|
@@ -3860,6 +3911,7 @@ var SseRelayTransport = class {
|
|
|
3860
3911
|
this.connected = false;
|
|
3861
3912
|
this.listeners = /* @__PURE__ */ new Set();
|
|
3862
3913
|
this.state = "idle";
|
|
3914
|
+
this.peers = /* @__PURE__ */ new Set();
|
|
3863
3915
|
this.opts = options;
|
|
3864
3916
|
this.expectedToken = options.token;
|
|
3865
3917
|
}
|
|
@@ -3958,6 +4010,36 @@ var SseRelayTransport = class {
|
|
|
3958
4010
|
} catch {
|
|
3959
4011
|
return;
|
|
3960
4012
|
}
|
|
4013
|
+
if ("method" in message && message.method === "notifications/peer_joined") {
|
|
4014
|
+
const subscriberId = String(message.params?.subscriberId ?? "peer");
|
|
4015
|
+
this.peers.add(subscriberId);
|
|
4016
|
+
fancyAutoCommon.emitActivity({
|
|
4017
|
+
agentId: "agent",
|
|
4018
|
+
agentName: "Agent",
|
|
4019
|
+
agentColor: "#a855f7",
|
|
4020
|
+
action: "agent_connected",
|
|
4021
|
+
timestamp: Date.now(),
|
|
4022
|
+
target: { kind: "navigation", label: "Agent connected" },
|
|
4023
|
+
meta: { subscriberId }
|
|
4024
|
+
});
|
|
4025
|
+
return;
|
|
4026
|
+
}
|
|
4027
|
+
if ("method" in message && message.method === "notifications/peer_left") {
|
|
4028
|
+
const subscriberId = String(message.params?.subscriberId ?? "peer");
|
|
4029
|
+
this.peers.delete(subscriberId);
|
|
4030
|
+
if (this.peers.size === 0) {
|
|
4031
|
+
fancyAutoCommon.emitActivity({
|
|
4032
|
+
agentId: "agent",
|
|
4033
|
+
agentName: "Agent",
|
|
4034
|
+
agentColor: "#a855f7",
|
|
4035
|
+
action: "agent_disconnected",
|
|
4036
|
+
timestamp: Date.now(),
|
|
4037
|
+
target: { kind: "navigation", label: "Agent disconnected" },
|
|
4038
|
+
meta: { subscriberId }
|
|
4039
|
+
});
|
|
4040
|
+
}
|
|
4041
|
+
return;
|
|
4042
|
+
}
|
|
3961
4043
|
await this.server.receive(this, message);
|
|
3962
4044
|
}
|
|
3963
4045
|
setState(state) {
|
|
@@ -4026,11 +4108,14 @@ function useCoBrowseSession(options) {
|
|
|
4026
4108
|
if (!server || relayRef.current) return;
|
|
4027
4109
|
const descriptor = createSessionDescriptor();
|
|
4028
4110
|
const csrf = options.csrfToken?.() ?? "";
|
|
4029
|
-
await fetch(`${relayBaseUrl}/register`, {
|
|
4111
|
+
const response = await fetch(`${relayBaseUrl}/register`, {
|
|
4030
4112
|
method: "POST",
|
|
4031
4113
|
headers: { "content-type": "application/json", "x-csrf-token": csrf },
|
|
4032
4114
|
body: JSON.stringify({ session: descriptor.id, token: descriptor.token })
|
|
4033
4115
|
});
|
|
4116
|
+
if (!response.ok) {
|
|
4117
|
+
throw new Error(`Relay registration failed (${response.status})`);
|
|
4118
|
+
}
|
|
4034
4119
|
const relay = attachSseRelay(server, { baseUrl: relayBaseUrl, sessionId: descriptor.id, token: descriptor.token });
|
|
4035
4120
|
relay.onStateChange(setRelayState);
|
|
4036
4121
|
relayRef.current = relay;
|
|
@@ -4044,16 +4129,15 @@ function useCoBrowseSession(options) {
|
|
|
4044
4129
|
setSession(null);
|
|
4045
4130
|
if (current) {
|
|
4046
4131
|
const csrf = options.csrfToken?.() ?? "";
|
|
4047
|
-
void fetch(`${relayBaseUrl}/${current.id}/unregister`, {
|
|
4132
|
+
void fetch(`${relayBaseUrl}/${current.id}/unregister?token=${encodeURIComponent(current.token)}`, {
|
|
4048
4133
|
method: "POST",
|
|
4049
|
-
headers: { "content-type": "application/json", "x-csrf-token": csrf }
|
|
4050
|
-
body: JSON.stringify({ token: current.token })
|
|
4134
|
+
headers: { "content-type": "application/json", "x-csrf-token": csrf }
|
|
4051
4135
|
}).catch(() => {
|
|
4052
4136
|
});
|
|
4053
4137
|
}
|
|
4054
4138
|
}, [relayBaseUrl, options, session]);
|
|
4055
4139
|
const observeUser = react.useCallback((event) => {
|
|
4056
|
-
const label = event.kind === "navigation" ? `You navigated to ${event.url}` : event.kind === "scroll" ? "You scrolled" : `You edited ${event.handle}${event.masked ? " (hidden)" : ""}`;
|
|
4140
|
+
const label = event.kind === "navigation" ? `You navigated to ${event.url}` : event.kind === "scroll" ? "You scrolled" : event.kind === "click" ? `You clicked ${event.label ?? event.handle}` : `You edited ${event.handle}${event.masked ? " (hidden)" : ""}`;
|
|
4057
4141
|
fancyAutoCommon.emitActivity({
|
|
4058
4142
|
agentId: USER.id,
|
|
4059
4143
|
agentName: USER.name,
|
|
@@ -4829,6 +4913,11 @@ function CoBrowseCursorLayer({ active = true, zIndex = 2147483e3 }) {
|
|
|
4829
4913
|
const [pulse, setPulse] = react.useState(null);
|
|
4830
4914
|
react.useEffect(() => {
|
|
4831
4915
|
if (!latest || (latest.source ?? "agent") === "user") return;
|
|
4916
|
+
if (latest.action === "agent_disconnected") {
|
|
4917
|
+
setCursor(null);
|
|
4918
|
+
setPulse(null);
|
|
4919
|
+
return;
|
|
4920
|
+
}
|
|
4832
4921
|
const color = latest.agentColor ?? "#a855f7";
|
|
4833
4922
|
const name = latest.agentName ?? "Agent";
|
|
4834
4923
|
const status = latest.target?.label ?? latest.action;
|