@arbidocs/react 0.5.126 → 0.5.127

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.ts CHANGED
@@ -15849,6 +15849,10 @@ interface RemoteControlRequest {
15849
15849
  sequenceId?: string;
15850
15850
  /** An ad-hoc guided run to execute (used when no registered sequence fits). */
15851
15851
  steps?: GuidedStep[];
15852
+ actionRequestId?: string;
15853
+ screenRequestId?: string;
15854
+ screenQuestion?: string;
15855
+ workspaceExtId?: string;
15852
15856
  }
15853
15857
  /** The agent whose run is actively executing — drives the "controlling" banner. */
15854
15858
  interface ControllingAgent {
@@ -15859,6 +15863,8 @@ interface ControllingAgent {
15859
15863
  interface RemoteControlState {
15860
15864
  /** Whether WS-driven runs may execute without re-prompting this session. */
15861
15865
  enabled: boolean;
15866
+ /** A browser-authorized screen stream is active. Never persisted. */
15867
+ sharing?: boolean;
15862
15868
  /** The in-flight consent request awaiting the user's decision, or null. */
15863
15869
  pending: RemoteControlRequest | null;
15864
15870
  /** Set while a WS-driven run is actively executing (labels the banner). */
@@ -15886,6 +15892,7 @@ declare function remoteControlActions(session: RemoteControlSession): {
15886
15892
  /** Directly set the session enabled flag. Turning it OFF revokes immediately: clears any
15887
15893
  * pending prompt and the controlling banner (GUARANTEE #5). */
15888
15894
  setEnabled: (enabled: boolean) => void;
15895
+ setSharing: (sharing: boolean) => void;
15889
15896
  /** Set (or clear) the agent whose run is currently executing. */
15890
15897
  setControllingAgent: (agent: ControllingAgent | null) => void;
15891
15898
  /** Back to the session start: off, nothing pending, nobody driving (a sign-in or sign-out). */
@@ -22,6 +22,7 @@ function remoteControlActions(session) {
22
22
  /** Directly set the session enabled flag. Turning it OFF revokes immediately: clears any
23
23
  * pending prompt and the controlling banner (GUARANTEE #5). */
24
24
  setEnabled: (enabled) => update(() => enabled ? { enabled } : { enabled, pending: null, controllingAgent: null }),
25
+ setSharing: (sharing) => update(() => ({ sharing })),
25
26
  /** Set (or clear) the agent whose run is currently executing. */
26
27
  setControllingAgent: (agent) => update(() => ({ controllingAgent: agent })),
27
28
  /** Back to the session start: off, nothing pending, nobody driving (a sign-in or sign-out). */
@@ -44,7 +45,7 @@ function toGuidedSteps(steps) {
44
45
  function toRemoteControlRequest(msg, isSequenceId) {
45
46
  const steps = hasRunnableSteps(msg.steps) ? toGuidedSteps(msg.steps) : void 0;
46
47
  const sequenceId = typeof msg.sequence_id === "string" && isSequenceId(msg.sequence_id) ? msg.sequence_id : void 0;
47
- if (!steps && !sequenceId) {
48
+ if (!steps && !sequenceId && !(msg.screen_request_id && msg.workspace_ext_id)) {
48
49
  logger.warn("[RemoteControl] Ignoring message with no runnable action", msg.sequence_id);
49
50
  return null;
50
51
  }
@@ -54,7 +55,16 @@ function toRemoteControlRequest(msg, isSequenceId) {
54
55
  agentName: msg.agent_name.trim() || "An assistant",
55
56
  agentExtId: msg.agent_ext_id ?? void 0,
56
57
  sequenceId,
57
- steps
58
+ steps,
59
+ ...msg.action_request_id ? {
60
+ actionRequestId: msg.action_request_id,
61
+ workspaceExtId: msg.workspace_ext_id ?? void 0
62
+ } : {},
63
+ ...msg.screen_request_id ? {
64
+ screenRequestId: msg.screen_request_id,
65
+ screenQuestion: msg.screen_question ?? void 0,
66
+ workspaceExtId: msg.workspace_ext_id ?? void 0
67
+ } : {}
58
68
  };
59
69
  }
60
70
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/remote-control.ts"],
4
- "sourcesContent": ["/**\n * Remote control's session state and its websocket message: an `agt-\u2026` assistant asks to drive\n * the UI over the live connection (`remote_control`), and the user's consent decides whether it\n * may. The guided run itself (the cursor, the clicks) is `@arbidocs/blocks`' (`createRemoteControl`).\n *\n * GUARANTEE #1: `enabled` is `false` at the start of EVERY session and is NEVER saved. The state is\n * a transient view of the session's layout (`views.transient`), which the layout never saves. Every\n * sign-in and sign-out drops it: `@arbidocs/blocks`' remote control resets it (`reset`) on the\n * host's sign-in, sign-out, expiry and change of user, on every host, and a host's own\n * `resetLayout` drops it too.\n *\n * The actions here are pure state. Running the requested run (and labelling the driver for its\n * duration) is the orchestration layer's.\n *\n * \u2500\u2500 BACKEND WS CONTRACT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Message `type`: `'remote_control'`. Payload (snake_case, matching the other WS messages):\n * {\n * type: 'remote_control',\n * agent_name: string, // display name of the requesting agent\n * agent_ext_id?: string, // the agent's `agt-\u2026` external id\n * sequence_id?: string, // a REGISTERED guided-run id\n * steps?: GuidedStep[], // OR an inline guided run (target-based)\n * }\n * Exactly one of `sequence_id` / `steps` is expected. An unknown `sequence_id`, a `steps` list with\n * no valid target, and an empty/absent run are all ignored.\n */\nimport type { components } from '@arbidocs/client'\nimport { logger } from '@arbidocs/client'\nimport type { ArbiSessionState, ArbiSessionStore } from './session'\nimport { useArbiSessionState } from './session'\n\n/** The websocket message: an `agt-\u2026` agent asks to drive the UI (exactly one of `sequence_id` /\n * `steps`). The generated schema type is the single source of truth. */\nexport type RemoteControlMessage = components['schemas']['RemoteControlMessage']\n/** One guided-cursor step, as on the wire (nullable JSON fields). */\ntype RemoteControlStep = components['schemas']['RemoteControlStep']\n\n/** One UI operation: glide the cursor to `target`, then perform `do` on it. */\nexport interface GuidedStep {\n /** `[data-testid=...]` (or any CSS selector) the cursor glides to and acts on. */\n target: string\n /** Interaction once the cursor arrives. Defaults to 'click'. */\n do?: 'click' | 'type'\n /** Text to type for `do: 'type'`. */\n value?: string\n /** Narration toast shown when the step runs. */\n note?: string\n /** Pause (ms) AFTER this step, before the next. */\n pauseMs?: number\n /** Max ms to wait for the target to appear (it may follow a prior step). */\n waitMs?: number\n}\n\n/** A remote-control run requested by a backend agent (name always present so the consent prompt\n * can name who is asking \u2014 GUARANTEE #3). Carries either a registered `sequenceId` or an inline\n * `steps` list to execute. */\nexport interface RemoteControlRequest {\n /** Display name of the requesting assistant, e.g. \"Research Assistant\". */\n agentName: string\n /** The assistant's `agt-\u2026` external id, shown so the user knows which agent. */\n agentExtId?: string\n /** A registered guided-run id to execute. */\n sequenceId?: string\n /** An ad-hoc guided run to execute (used when no registered sequence fits). */\n steps?: GuidedStep[]\n}\n\n/** The agent whose run is actively executing \u2014 drives the \"controlling\" banner. */\nexport interface ControllingAgent {\n name: string\n extId?: string\n}\n\n/** Session-only remote-control state (never saved \u2014 see the file header). */\nexport interface RemoteControlState {\n /** Whether WS-driven runs may execute without re-prompting this session. */\n enabled: boolean\n /** The in-flight consent request awaiting the user's decision, or null. */\n pending: RemoteControlRequest | null\n /** Set while a WS-driven run is actively executing (labels the banner). */\n controllingAgent: ControllingAgent | null\n}\n\n/** The session the state lives in. */\nexport type RemoteControlSession = Pick<ArbiSessionStore, 'getState' | 'setTransientView'>\n\n/** The transient view that holds the state. */\nexport const REMOTE_CONTROL_VIEW = 'actions.remoteControl'\nconst OFF: RemoteControlState = { enabled: false, pending: null, controllingAgent: null }\n\n/** The remote-control state of a session state. */\nexport const remoteControlStateOf = (state: Pick<ArbiSessionState, 'views'>): RemoteControlState =>\n (state.views.transient[REMOTE_CONTROL_VIEW] as RemoteControlState | undefined) ?? OFF\n\n/** A slice of the remote-control state of the host's session; re-renders when it changes. */\nexport function useRemoteControl<T>(selector: (state: RemoteControlState) => T): T {\n return useArbiSessionState((state) => selector(remoteControlStateOf(state)))\n}\n\n/** The state's actions on a session. */\nexport function remoteControlActions(session: RemoteControlSession) {\n const update = (change: (state: RemoteControlState) => Partial<RemoteControlState>): void => {\n const state = remoteControlStateOf(session.getState())\n session.setTransientView(REMOTE_CONTROL_VIEW, { ...state, ...change(state) })\n }\n return {\n /** Stash a requested run and open the consent prompt (`pending` set). */\n request: (req: RemoteControlRequest): void => update(() => ({ pending: req })),\n /** Resolve the pending request: `forSession` enables it for the whole session; either way\n * the pending request is cleared. Running it is the caller's job. */\n grant: ({ forSession }: { forSession: boolean }): void =>\n update((state) => ({ enabled: forSession || state.enabled, pending: null })),\n /** Reject the pending request \u2014 clears it, changes nothing else. */\n deny: (): void => update(() => ({ pending: null })),\n /** Directly set the session enabled flag. Turning it OFF revokes immediately: clears any\n * pending prompt and the controlling banner (GUARANTEE #5). */\n setEnabled: (enabled: boolean): void =>\n update(() => (enabled ? { enabled } : { enabled, pending: null, controllingAgent: null })),\n /** Set (or clear) the agent whose run is currently executing. */\n setControllingAgent: (agent: ControllingAgent | null): void =>\n update(() => ({ controllingAgent: agent })),\n /** Back to the session start: off, nothing pending, nobody driving (a sign-in or sign-out). */\n reset: (): void => session.setTransientView(REMOTE_CONTROL_VIEW, undefined),\n }\n}\n\n/** A runnable steps list: a non-empty array whose every step has a real target selector \u2014 the\n * one field the runner cannot act without. Operates on the wire step (nullable JSON fields). */\nfunction hasRunnableSteps(\n steps: RemoteControlStep[] | null | undefined\n): steps is RemoteControlStep[] {\n return (\n Array.isArray(steps) &&\n steps.length > 0 &&\n steps.every((s) => typeof s?.target === 'string' && s.target.length > 0)\n )\n}\n\n/** Normalise wire steps (nullable JSON fields) into plain optionals \u2014 a `null` off the socket\n * becomes an absent field. */\nfunction toGuidedSteps(steps: RemoteControlStep[]): GuidedStep[] {\n return steps.map((s) => ({\n target: s.target,\n do: s.do ?? undefined,\n value: s.value ?? undefined,\n note: s.note ?? undefined,\n pauseMs: s.pauseMs ?? undefined,\n waitMs: s.waitMs ?? undefined,\n }))\n}\n\n/**\n * Narrow an incoming message into a request, or null if nothing is runnable: inline steps that\n * all have a target, or a `sequence_id` the site registered (`isSequenceId`).\n */\nexport function toRemoteControlRequest(\n msg: RemoteControlMessage,\n isSequenceId: (id: string) => boolean\n): RemoteControlRequest | null {\n const steps = hasRunnableSteps(msg.steps) ? toGuidedSteps(msg.steps) : undefined\n const sequenceId =\n typeof msg.sequence_id === 'string' && isSequenceId(msg.sequence_id)\n ? msg.sequence_id\n : undefined\n if (!steps && !sequenceId) {\n logger.warn('[RemoteControl] Ignoring message with no runnable action', msg.sequence_id)\n return null\n }\n return {\n // The agent is always named in the prompt; fall back to a neutral label rather than leaving\n // the consent dialog anonymous.\n agentName: msg.agent_name.trim() || 'An assistant',\n agentExtId: msg.agent_ext_id ?? undefined,\n sequenceId,\n steps,\n }\n}\n"],
5
- "mappings": "AA2BA,SAAS,cAAc;AAEvB,SAAS,2BAA2B;AA0D7B,MAAM,sBAAsB;AACnC,MAAM,MAA0B,EAAE,SAAS,OAAO,SAAS,MAAM,kBAAkB,KAAK;AAGjF,MAAM,uBAAuB,CAAC,UAClC,MAAM,MAAM,UAAU,mBAAmB,KAAwC;AAG7E,SAAS,iBAAoB,UAA+C;AACjF,SAAO,oBAAoB,CAAC,UAAU,SAAS,qBAAqB,KAAK,CAAC,CAAC;AAC7E;AAGO,SAAS,qBAAqB,SAA+B;AAClE,QAAM,SAAS,CAAC,WAA6E;AAC3F,UAAM,QAAQ,qBAAqB,QAAQ,SAAS,CAAC;AACrD,YAAQ,iBAAiB,qBAAqB,EAAE,GAAG,OAAO,GAAG,OAAO,KAAK,EAAE,CAAC;AAAA,EAC9E;AACA,SAAO;AAAA;AAAA,IAEL,SAAS,CAAC,QAAoC,OAAO,OAAO,EAAE,SAAS,IAAI,EAAE;AAAA;AAAA;AAAA,IAG7E,OAAO,CAAC,EAAE,WAAW,MACnB,OAAO,CAAC,WAAW,EAAE,SAAS,cAAc,MAAM,SAAS,SAAS,KAAK,EAAE;AAAA;AAAA,IAE7E,MAAM,MAAY,OAAO,OAAO,EAAE,SAAS,KAAK,EAAE;AAAA;AAAA;AAAA,IAGlD,YAAY,CAAC,YACX,OAAO,MAAO,UAAU,EAAE,QAAQ,IAAI,EAAE,SAAS,SAAS,MAAM,kBAAkB,KAAK,CAAE;AAAA;AAAA,IAE3F,qBAAqB,CAAC,UACpB,OAAO,OAAO,EAAE,kBAAkB,MAAM,EAAE;AAAA;AAAA,IAE5C,OAAO,MAAY,QAAQ,iBAAiB,qBAAqB,MAAS;AAAA,EAC5E;AACF;AAIA,SAAS,iBACP,OAC8B;AAC9B,SACE,MAAM,QAAQ,KAAK,KACnB,MAAM,SAAS,KACf,MAAM,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,YAAY,EAAE,OAAO,SAAS,CAAC;AAE3E;AAIA,SAAS,cAAc,OAA0C;AAC/D,SAAO,MAAM,IAAI,CAAC,OAAO;AAAA,IACvB,QAAQ,EAAE;AAAA,IACV,IAAI,EAAE,MAAM;AAAA,IACZ,OAAO,EAAE,SAAS;AAAA,IAClB,MAAM,EAAE,QAAQ;AAAA,IAChB,SAAS,EAAE,WAAW;AAAA,IACtB,QAAQ,EAAE,UAAU;AAAA,EACtB,EAAE;AACJ;AAMO,SAAS,uBACd,KACA,cAC6B;AAC7B,QAAM,QAAQ,iBAAiB,IAAI,KAAK,IAAI,cAAc,IAAI,KAAK,IAAI;AACvE,QAAM,aACJ,OAAO,IAAI,gBAAgB,YAAY,aAAa,IAAI,WAAW,IAC/D,IAAI,cACJ;AACN,MAAI,CAAC,SAAS,CAAC,YAAY;AACzB,WAAO,KAAK,4DAA4D,IAAI,WAAW;AACvF,WAAO;AAAA,EACT;AACA,SAAO;AAAA;AAAA;AAAA,IAGL,WAAW,IAAI,WAAW,KAAK,KAAK;AAAA,IACpC,YAAY,IAAI,gBAAgB;AAAA,IAChC;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["/**\n * Remote control's session state and its websocket message: an `agt-\u2026` assistant asks to drive\n * the UI over the live connection (`remote_control`), and the user's consent decides whether it\n * may. The guided run itself (the cursor, the clicks) is `@arbidocs/blocks`' (`createRemoteControl`).\n *\n * GUARANTEE #1: `enabled` is `false` at the start of EVERY session and is NEVER saved. The state is\n * a transient view of the session's layout (`views.transient`), which the layout never saves. Every\n * sign-in and sign-out drops it: `@arbidocs/blocks`' remote control resets it (`reset`) on the\n * host's sign-in, sign-out, expiry and change of user, on every host, and a host's own\n * `resetLayout` drops it too.\n *\n * The actions here are pure state. Running the requested run (and labelling the driver for its\n * duration) is the orchestration layer's.\n *\n * \u2500\u2500 BACKEND WS CONTRACT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Message `type`: `'remote_control'`. Payload (snake_case, matching the other WS messages):\n * {\n * type: 'remote_control',\n * agent_name: string, // display name of the requesting agent\n * agent_ext_id?: string, // the agent's `agt-\u2026` external id\n * sequence_id?: string, // a REGISTERED guided-run id\n * steps?: GuidedStep[], // OR an inline guided run (target-based)\n * }\n * Exactly one of `sequence_id` / `steps` is expected. An unknown `sequence_id`, a `steps` list with\n * no valid target, and an empty/absent run are all ignored.\n */\nimport type { components } from '@arbidocs/client'\nimport { logger } from '@arbidocs/client'\nimport type { ArbiSessionState, ArbiSessionStore } from './session'\nimport { useArbiSessionState } from './session'\n\n/** The websocket message: an `agt-\u2026` agent asks to drive the UI (exactly one of `sequence_id` /\n * `steps`). The generated schema type is the single source of truth. */\nexport type RemoteControlMessage = components['schemas']['RemoteControlMessage']\n/** One guided-cursor step, as on the wire (nullable JSON fields). */\ntype RemoteControlStep = components['schemas']['RemoteControlStep']\n\n/** One UI operation: glide the cursor to `target`, then perform `do` on it. */\nexport interface GuidedStep {\n /** `[data-testid=...]` (or any CSS selector) the cursor glides to and acts on. */\n target: string\n /** Interaction once the cursor arrives. Defaults to 'click'. */\n do?: 'click' | 'type'\n /** Text to type for `do: 'type'`. */\n value?: string\n /** Narration toast shown when the step runs. */\n note?: string\n /** Pause (ms) AFTER this step, before the next. */\n pauseMs?: number\n /** Max ms to wait for the target to appear (it may follow a prior step). */\n waitMs?: number\n}\n\n/** A remote-control run requested by a backend agent (name always present so the consent prompt\n * can name who is asking \u2014 GUARANTEE #3). Carries either a registered `sequenceId` or an inline\n * `steps` list to execute. */\nexport interface RemoteControlRequest {\n /** Display name of the requesting assistant, e.g. \"Research Assistant\". */\n agentName: string\n /** The assistant's `agt-\u2026` external id, shown so the user knows which agent. */\n agentExtId?: string\n /** A registered guided-run id to execute. */\n sequenceId?: string\n /** An ad-hoc guided run to execute (used when no registered sequence fits). */\n steps?: GuidedStep[]\n actionRequestId?: string\n screenRequestId?: string\n screenQuestion?: string\n workspaceExtId?: string\n}\n\n/** The agent whose run is actively executing \u2014 drives the \"controlling\" banner. */\nexport interface ControllingAgent {\n name: string\n extId?: string\n}\n\n/** Session-only remote-control state (never saved \u2014 see the file header). */\nexport interface RemoteControlState {\n /** Whether WS-driven runs may execute without re-prompting this session. */\n enabled: boolean\n /** A browser-authorized screen stream is active. Never persisted. */\n sharing?: boolean\n /** The in-flight consent request awaiting the user's decision, or null. */\n pending: RemoteControlRequest | null\n /** Set while a WS-driven run is actively executing (labels the banner). */\n controllingAgent: ControllingAgent | null\n}\n\n/** The session the state lives in. */\nexport type RemoteControlSession = Pick<ArbiSessionStore, 'getState' | 'setTransientView'>\n\n/** The transient view that holds the state. */\nexport const REMOTE_CONTROL_VIEW = 'actions.remoteControl'\nconst OFF: RemoteControlState = { enabled: false, pending: null, controllingAgent: null }\n\n/** The remote-control state of a session state. */\nexport const remoteControlStateOf = (state: Pick<ArbiSessionState, 'views'>): RemoteControlState =>\n (state.views.transient[REMOTE_CONTROL_VIEW] as RemoteControlState | undefined) ?? OFF\n\n/** A slice of the remote-control state of the host's session; re-renders when it changes. */\nexport function useRemoteControl<T>(selector: (state: RemoteControlState) => T): T {\n return useArbiSessionState((state) => selector(remoteControlStateOf(state)))\n}\n\n/** The state's actions on a session. */\nexport function remoteControlActions(session: RemoteControlSession) {\n const update = (change: (state: RemoteControlState) => Partial<RemoteControlState>): void => {\n const state = remoteControlStateOf(session.getState())\n session.setTransientView(REMOTE_CONTROL_VIEW, { ...state, ...change(state) })\n }\n return {\n /** Stash a requested run and open the consent prompt (`pending` set). */\n request: (req: RemoteControlRequest): void => update(() => ({ pending: req })),\n /** Resolve the pending request: `forSession` enables it for the whole session; either way\n * the pending request is cleared. Running it is the caller's job. */\n grant: ({ forSession }: { forSession: boolean }): void =>\n update((state) => ({ enabled: forSession || state.enabled, pending: null })),\n /** Reject the pending request \u2014 clears it, changes nothing else. */\n deny: (): void => update(() => ({ pending: null })),\n /** Directly set the session enabled flag. Turning it OFF revokes immediately: clears any\n * pending prompt and the controlling banner (GUARANTEE #5). */\n setEnabled: (enabled: boolean): void =>\n update(() => (enabled ? { enabled } : { enabled, pending: null, controllingAgent: null })),\n setSharing: (sharing: boolean): void => update(() => ({ sharing })),\n /** Set (or clear) the agent whose run is currently executing. */\n setControllingAgent: (agent: ControllingAgent | null): void =>\n update(() => ({ controllingAgent: agent })),\n /** Back to the session start: off, nothing pending, nobody driving (a sign-in or sign-out). */\n reset: (): void => session.setTransientView(REMOTE_CONTROL_VIEW, undefined),\n }\n}\n\n/** A runnable steps list: a non-empty array whose every step has a real target selector \u2014 the\n * one field the runner cannot act without. Operates on the wire step (nullable JSON fields). */\nfunction hasRunnableSteps(\n steps: RemoteControlStep[] | null | undefined\n): steps is RemoteControlStep[] {\n return (\n Array.isArray(steps) &&\n steps.length > 0 &&\n steps.every((s) => typeof s?.target === 'string' && s.target.length > 0)\n )\n}\n\n/** Normalise wire steps (nullable JSON fields) into plain optionals \u2014 a `null` off the socket\n * becomes an absent field. */\nfunction toGuidedSteps(steps: RemoteControlStep[]): GuidedStep[] {\n return steps.map((s) => ({\n target: s.target,\n do: s.do ?? undefined,\n value: s.value ?? undefined,\n note: s.note ?? undefined,\n pauseMs: s.pauseMs ?? undefined,\n waitMs: s.waitMs ?? undefined,\n }))\n}\n\n/**\n * Narrow an incoming message into a request, or null if nothing is runnable: inline steps that\n * all have a target, or a `sequence_id` the site registered (`isSequenceId`).\n */\nexport function toRemoteControlRequest(\n msg: RemoteControlMessage,\n isSequenceId: (id: string) => boolean\n): RemoteControlRequest | null {\n const steps = hasRunnableSteps(msg.steps) ? toGuidedSteps(msg.steps) : undefined\n const sequenceId =\n typeof msg.sequence_id === 'string' && isSequenceId(msg.sequence_id)\n ? msg.sequence_id\n : undefined\n if (!steps && !sequenceId && !(msg.screen_request_id && msg.workspace_ext_id)) {\n logger.warn('[RemoteControl] Ignoring message with no runnable action', msg.sequence_id)\n return null\n }\n return {\n // The agent is always named in the prompt; fall back to a neutral label rather than leaving\n // the consent dialog anonymous.\n agentName: msg.agent_name.trim() || 'An assistant',\n agentExtId: msg.agent_ext_id ?? undefined,\n sequenceId,\n steps,\n ...(msg.action_request_id\n ? {\n actionRequestId: msg.action_request_id,\n workspaceExtId: msg.workspace_ext_id ?? undefined,\n }\n : {}),\n ...(msg.screen_request_id\n ? {\n screenRequestId: msg.screen_request_id,\n screenQuestion: msg.screen_question ?? undefined,\n workspaceExtId: msg.workspace_ext_id ?? undefined,\n }\n : {}),\n }\n}\n"],
5
+ "mappings": "AA2BA,SAAS,cAAc;AAEvB,SAAS,2BAA2B;AAgE7B,MAAM,sBAAsB;AACnC,MAAM,MAA0B,EAAE,SAAS,OAAO,SAAS,MAAM,kBAAkB,KAAK;AAGjF,MAAM,uBAAuB,CAAC,UAClC,MAAM,MAAM,UAAU,mBAAmB,KAAwC;AAG7E,SAAS,iBAAoB,UAA+C;AACjF,SAAO,oBAAoB,CAAC,UAAU,SAAS,qBAAqB,KAAK,CAAC,CAAC;AAC7E;AAGO,SAAS,qBAAqB,SAA+B;AAClE,QAAM,SAAS,CAAC,WAA6E;AAC3F,UAAM,QAAQ,qBAAqB,QAAQ,SAAS,CAAC;AACrD,YAAQ,iBAAiB,qBAAqB,EAAE,GAAG,OAAO,GAAG,OAAO,KAAK,EAAE,CAAC;AAAA,EAC9E;AACA,SAAO;AAAA;AAAA,IAEL,SAAS,CAAC,QAAoC,OAAO,OAAO,EAAE,SAAS,IAAI,EAAE;AAAA;AAAA;AAAA,IAG7E,OAAO,CAAC,EAAE,WAAW,MACnB,OAAO,CAAC,WAAW,EAAE,SAAS,cAAc,MAAM,SAAS,SAAS,KAAK,EAAE;AAAA;AAAA,IAE7E,MAAM,MAAY,OAAO,OAAO,EAAE,SAAS,KAAK,EAAE;AAAA;AAAA;AAAA,IAGlD,YAAY,CAAC,YACX,OAAO,MAAO,UAAU,EAAE,QAAQ,IAAI,EAAE,SAAS,SAAS,MAAM,kBAAkB,KAAK,CAAE;AAAA,IAC3F,YAAY,CAAC,YAA2B,OAAO,OAAO,EAAE,QAAQ,EAAE;AAAA;AAAA,IAElE,qBAAqB,CAAC,UACpB,OAAO,OAAO,EAAE,kBAAkB,MAAM,EAAE;AAAA;AAAA,IAE5C,OAAO,MAAY,QAAQ,iBAAiB,qBAAqB,MAAS;AAAA,EAC5E;AACF;AAIA,SAAS,iBACP,OAC8B;AAC9B,SACE,MAAM,QAAQ,KAAK,KACnB,MAAM,SAAS,KACf,MAAM,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,YAAY,EAAE,OAAO,SAAS,CAAC;AAE3E;AAIA,SAAS,cAAc,OAA0C;AAC/D,SAAO,MAAM,IAAI,CAAC,OAAO;AAAA,IACvB,QAAQ,EAAE;AAAA,IACV,IAAI,EAAE,MAAM;AAAA,IACZ,OAAO,EAAE,SAAS;AAAA,IAClB,MAAM,EAAE,QAAQ;AAAA,IAChB,SAAS,EAAE,WAAW;AAAA,IACtB,QAAQ,EAAE,UAAU;AAAA,EACtB,EAAE;AACJ;AAMO,SAAS,uBACd,KACA,cAC6B;AAC7B,QAAM,QAAQ,iBAAiB,IAAI,KAAK,IAAI,cAAc,IAAI,KAAK,IAAI;AACvE,QAAM,aACJ,OAAO,IAAI,gBAAgB,YAAY,aAAa,IAAI,WAAW,IAC/D,IAAI,cACJ;AACN,MAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,qBAAqB,IAAI,mBAAmB;AAC7E,WAAO,KAAK,4DAA4D,IAAI,WAAW;AACvF,WAAO;AAAA,EACT;AACA,SAAO;AAAA;AAAA;AAAA,IAGL,WAAW,IAAI,WAAW,KAAK,KAAK;AAAA,IACpC,YAAY,IAAI,gBAAgB;AAAA,IAChC;AAAA,IACA;AAAA,IACA,GAAI,IAAI,oBACJ;AAAA,MACE,iBAAiB,IAAI;AAAA,MACrB,gBAAgB,IAAI,oBAAoB;AAAA,IAC1C,IACA,CAAC;AAAA,IACL,GAAI,IAAI,oBACJ;AAAA,MACE,iBAAiB,IAAI;AAAA,MACrB,gBAAgB,IAAI,mBAAmB;AAAA,MACvC,gBAAgB,IAAI,oBAAoB;AAAA,IAC1C,IACA,CAAC;AAAA,EACP;AACF;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbidocs/react",
3
- "version": "0.5.126",
3
+ "version": "0.5.127",
4
4
  "description": "React hooks and provider for the ARBI SDK",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -117,8 +117,8 @@
117
117
  "build-storybook": "storybook build"
118
118
  },
119
119
  "dependencies": {
120
- "@arbidocs/client": "0.5.126",
121
- "@arbidocs/sdk": "0.5.126",
120
+ "@arbidocs/client": "0.5.127",
121
+ "@arbidocs/sdk": "0.5.127",
122
122
  "@didit-protocol/sdk-web": "0.4.0",
123
123
  "@livekit/components-react": "2.9.24",
124
124
  "@radix-ui/react-avatar": "^1.2.0",