@blocksdiy/react-common 1.54.0 → 1.55.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.
@@ -0,0 +1,64 @@
1
+ export type FloatingAgentChatEnginePhase = "loading" | "ready" | "error";
2
+ export interface FloatingAgentChatEngineState {
3
+ /** Which engine this is: the agent's chat and the load attempt ({@link floatingAgentChatEngineKey}). */
4
+ key: string;
5
+ isReady: boolean;
6
+ loadError: Error | null;
7
+ }
8
+ export declare const floatingAgentChatEngineKey: (agentChatId: string, attempt: number) => string;
9
+ /** A fresh engine: nothing reported yet. */
10
+ export declare const floatingAgentChatEngineFor: (key: string) => FloatingAgentChatEngineState;
11
+ /** The engine with this key is up. A report from an engine since replaced changes nothing. */
12
+ export declare const floatingAgentChatEngineReady: (prev: FloatingAgentChatEngineState, key: string) => FloatingAgentChatEngineState;
13
+ /** The engine with this key could not load. A report from an engine since replaced changes nothing. */
14
+ export declare const floatingAgentChatEngineFailed: (prev: FloatingAgentChatEngineState, key: string, loadError: Error) => FloatingAgentChatEngineState;
15
+ /** Ready once up; failed only while not up; loading before either. */
16
+ export declare const floatingAgentChatEnginePhase: (state: FloatingAgentChatEngineState) => FloatingAgentChatEnginePhase;
17
+ export interface UseFloatingAgentChatEngineResult {
18
+ /** The runtime's key: another agent, or a retry, is another runtime. */
19
+ key: string;
20
+ phase: FloatingAgentChatEnginePhase;
21
+ /** The runtime's parts are up (it resolved the agent). */
22
+ onReady: () => void;
23
+ /** The runtime could not load the agent. */
24
+ onLoadError: (error: Error) => void;
25
+ /** Starts over after a failed load: a new key, so the host mounts a new runtime. */
26
+ retry: () => void;
27
+ }
28
+ /** The engine's phase for the agent the session shows; reset the moment another agent takes over. */
29
+ export declare const useFloatingAgentChatEngine: (agentChatId: string) => UseFloatingAgentChatEngineResult;
30
+ /** What the URL on screen tells: the page's route params, and its query as an object. */
31
+ export interface FloatingAgentChatUrlContext {
32
+ routeParams: Readonly<Record<string, string | undefined>>;
33
+ /** A key's value — its values, when the key repeats (`?tag=a&tag=b`). */
34
+ searchParams: Record<string, string | string[]>;
35
+ }
36
+ /** The query as an object: a key's value, or its values when the key repeats. */
37
+ export declare const floatingAgentChatSearchParams: (params: URLSearchParams) => FloatingAgentChatUrlContext["searchParams"];
38
+ /**
39
+ * The context the engine sends: the provider's (the app's, for every floating conversation), the
40
+ * opener's over it (a sidebar pick's layout context, `open`'s or `openPrompt`'s — key by key),
41
+ * and `urlContext` beside them. A plain object's keys stay at the top level (an agent's initial
42
+ * messages read `{{chatContext.<key>}}`); anything else goes under `context`.
43
+ */
44
+ export declare const floatingAgentChatContext: (provided: unknown, opener: unknown, urlContext: FloatingAgentChatUrlContext) => {
45
+ urlContext: FloatingAgentChatUrlContext;
46
+ };
47
+ export interface UseFloatingAgentChatContextOptions {
48
+ /** The provider's context: the app's, for every floating conversation. */
49
+ provided: unknown;
50
+ /** The opener's context, over the provider's. */
51
+ opener: unknown;
52
+ /** The router's values — react-common knows no router; the host passes `useParams()`'s and `useSearchParams()`'s. */
53
+ routeParams: FloatingAgentChatUrlContext["routeParams"];
54
+ searchParams: URLSearchParams;
55
+ }
56
+ /**
57
+ * The context the engine sends with every turn, memoized on the URL's content (the router hands
58
+ * out a fresh params object on every render of its host) and the contexts' identity: the engine
59
+ * re-renders for a change of the URL or of a context, never for one of the surface or its host.
60
+ */
61
+ export declare const useFloatingAgentChatContext: ({ provided, opener, routeParams, searchParams, }: UseFloatingAgentChatContextOptions) => {
62
+ urlContext: FloatingAgentChatUrlContext;
63
+ };
64
+ //# sourceMappingURL=floating-agent-chat-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-agent-chat-engine.d.ts","sourceRoot":"","sources":["../../src/hooks/floating-agent-chat-engine.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,4BAA4B,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzE,MAAM,WAAW,4BAA4B;IAC3C,wGAAwG;IACxG,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,0BAA0B,GAAI,aAAa,MAAM,EAAE,SAAS,MAAM,KAAG,MAAqC,CAAC;AAExH,4CAA4C;AAC5C,eAAO,MAAM,0BAA0B,GAAI,KAAK,MAAM,KAAG,4BAIvD,CAAC;AAEH,8FAA8F;AAC9F,eAAO,MAAM,4BAA4B,GACvC,MAAM,4BAA4B,EAClC,KAAK,MAAM,KACV,4BAAsF,CAAC;AAE1F,uGAAuG;AACvG,eAAO,MAAM,6BAA6B,GACxC,MAAM,4BAA4B,EAClC,KAAK,MAAM,EACX,WAAW,KAAK,KACf,4BAAkF,CAAC;AAEtF,sEAAsE;AACtE,eAAO,MAAM,4BAA4B,GAAI,OAAO,4BAA4B,KAAG,4BAClB,CAAC;AAElE,MAAM,WAAW,gCAAgC;IAC/C,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,4BAA4B,CAAC;IACpC,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,4CAA4C;IAC5C,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACpC,oFAAoF;IACpF,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,qGAAqG;AACrG,eAAO,MAAM,0BAA0B,GAAI,aAAa,MAAM,KAAG,gCAiBhE,CAAC;AAEF,yFAAyF;AACzF,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC1D,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;CACjD;AAED,iFAAiF;AACjF,eAAO,MAAM,6BAA6B,GAAI,QAAQ,eAAe,KAAG,2BAA2B,CAAC,cAAc,CAQjH,CAAC;AASF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,OAAO,EACjB,QAAQ,OAAO,EACf,YAAY,2BAA2B;;CAKvC,CAAC;AAEH,MAAM,WAAW,kCAAkC;IACjD,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB,qHAAqH;IACrH,WAAW,EAAE,2BAA2B,CAAC,aAAa,CAAC,CAAC;IACxD,YAAY,EAAE,eAAe,CAAC;CAC/B;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GAAI,kDAKzC,kCAAkC;;CAWpC,CAAC"}
@@ -0,0 +1,72 @@
1
+ // The floating chat's engine, headless: one chat runtime per agent the session shows (and per
2
+ // retry of a failed load), what it reports — up, or failed — is its own, never a previous
3
+ // engine's, and the context it sends with every turn: the app's and the opener's with what the
4
+ // URL on screen tells beside them. The agent-chat registry item mounts the runtime under the
5
+ // key and renders the phase. The reducers are pure and tested; the hooks are the thin React shell.
6
+ import { useCallback, useMemo, useState } from "react";
7
+ export const floatingAgentChatEngineKey = (agentChatId, attempt) => `${agentChatId}:${attempt}`;
8
+ /** A fresh engine: nothing reported yet. */
9
+ export const floatingAgentChatEngineFor = (key) => ({
10
+ key,
11
+ isReady: false,
12
+ loadError: null,
13
+ });
14
+ /** The engine with this key is up. A report from an engine since replaced changes nothing. */
15
+ export const floatingAgentChatEngineReady = (prev, key) => (prev.key === key ? { ...prev, isReady: true } : prev);
16
+ /** The engine with this key could not load. A report from an engine since replaced changes nothing. */
17
+ export const floatingAgentChatEngineFailed = (prev, key, loadError) => (prev.key === key ? { ...prev, loadError } : prev);
18
+ /** Ready once up; failed only while not up; loading before either. */
19
+ export const floatingAgentChatEnginePhase = (state) => state.isReady ? "ready" : state.loadError ? "error" : "loading";
20
+ /** The engine's phase for the agent the session shows; reset the moment another agent takes over. */
21
+ export const useFloatingAgentChatEngine = (agentChatId) => {
22
+ const [attempt, setAttempt] = useState(0);
23
+ const key = floatingAgentChatEngineKey(agentChatId, attempt);
24
+ const [state, setState] = useState(() => floatingAgentChatEngineFor(key));
25
+ // Another engine took over: a clean slate, adjusted during render so nothing commits with a
26
+ // previous engine's readiness.
27
+ if (state.key !== key) {
28
+ setState(floatingAgentChatEngineFor(key));
29
+ }
30
+ const onReady = useCallback(() => setState((prev) => floatingAgentChatEngineReady(prev, key)), [key]);
31
+ const onLoadError = useCallback((error) => setState((prev) => floatingAgentChatEngineFailed(prev, key, error)), [key]);
32
+ const retry = useCallback(() => setAttempt((count) => count + 1), []);
33
+ const phase = floatingAgentChatEnginePhase(state);
34
+ return useMemo(() => ({ key, phase, onReady, onLoadError, retry }), [key, phase, onReady, onLoadError, retry]);
35
+ };
36
+ /** The query as an object: a key's value, or its values when the key repeats. */
37
+ export const floatingAgentChatSearchParams = (params) => {
38
+ // No prototype: a key like `constructor` or `__proto__` is a query key, not an inherited member.
39
+ const object = Object.create(null);
40
+ params.forEach((value, key) => {
41
+ const seen = object[key];
42
+ object[key] = seen === undefined ? value : [].concat(seen, value);
43
+ });
44
+ return object;
45
+ };
46
+ const isPlainObject = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
47
+ /** A context as top-level keys: a plain object's own; anything else under `context`; none for none. */
48
+ const asTopLevelContext = (context) => isPlainObject(context) ? context : context == null ? {} : { context };
49
+ /**
50
+ * The context the engine sends: the provider's (the app's, for every floating conversation), the
51
+ * opener's over it (a sidebar pick's layout context, `open`'s or `openPrompt`'s — key by key),
52
+ * and `urlContext` beside them. A plain object's keys stay at the top level (an agent's initial
53
+ * messages read `{{chatContext.<key>}}`); anything else goes under `context`.
54
+ */
55
+ export const floatingAgentChatContext = (provided, opener, urlContext) => ({
56
+ ...asTopLevelContext(provided),
57
+ ...asTopLevelContext(opener),
58
+ urlContext,
59
+ });
60
+ /**
61
+ * The context the engine sends with every turn, memoized on the URL's content (the router hands
62
+ * out a fresh params object on every render of its host) and the contexts' identity: the engine
63
+ * re-renders for a change of the URL or of a context, never for one of the surface or its host.
64
+ */
65
+ export const useFloatingAgentChatContext = ({ provided, opener, routeParams, searchParams, }) => {
66
+ const routeParamsJson = JSON.stringify(routeParams);
67
+ const search = searchParams.toString();
68
+ return useMemo(() => floatingAgentChatContext(provided, opener, {
69
+ routeParams: JSON.parse(routeParamsJson),
70
+ searchParams: floatingAgentChatSearchParams(new URLSearchParams(search)),
71
+ }), [provided, opener, routeParamsJson, search]);
72
+ };
@@ -9,6 +9,11 @@ export interface FloatingAgentChatHandle {
9
9
  }
10
10
  /** What to open: a conversation (the `chatId` + `chatThreadId` pair), or the new chat. */
11
11
  export type FloatingAgentChatTarget = AgentConversationRef | "new";
12
+ /**
13
+ * How the open session shows: the floating prompt — the new chat as a one-line composer, until
14
+ * its first send — or the panel with the conversation. One engine underneath either way.
15
+ */
16
+ export type FloatingAgentChatFace = "prompt" | "panel";
12
17
  /**
13
18
  * Where the panel's expand goes for the conversation it shows — the opener knows the full route
14
19
  * (an agent mini-app's thread page); `null` hides the expand control. Never asked for a draft:
@@ -23,13 +28,16 @@ export interface FloatingAgentChatOpenOptions<Handle extends FloatingAgentChatHa
23
28
  expandHref?: FloatingAgentChatExpandHref;
24
29
  /** Extra context handed to the agent on every turn (like `AgentChat`'s `chatContext`). */
25
30
  chatContext?: unknown;
31
+ /** The face to open with — the panel by default; the prompt always opens the new chat. */
32
+ face?: FloatingAgentChatFace;
26
33
  }
27
34
  /** The open options with the ids resolved from the handle. */
28
- export interface FloatingAgentChatOpenRequest<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> extends Omit<FloatingAgentChatOpenOptions<Handle>, "target"> {
35
+ export interface FloatingAgentChatOpenRequest<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> extends Omit<FloatingAgentChatOpenOptions<Handle>, "target" | "face"> {
29
36
  agentChatId: string;
30
37
  /** The chat the agent's own conversations live under (agentInboxChatId). */
31
38
  ownChatId: string;
32
39
  target: FloatingAgentChatTarget;
40
+ face: FloatingAgentChatFace;
33
41
  }
34
42
  export interface FloatingAgentChatState<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> {
35
43
  agentChat: Handle;
@@ -39,6 +47,7 @@ export interface FloatingAgentChatState<Handle extends FloatingAgentChatHandle =
39
47
  /** The draft's thread id — the new chat, until its first send turns it into a thread. */
40
48
  draftThreadId: string;
41
49
  draftSent: boolean;
50
+ face: FloatingAgentChatFace;
42
51
  expandHref?: FloatingAgentChatExpandHref;
43
52
  chatContext?: unknown;
44
53
  }
@@ -48,30 +57,34 @@ export declare const isFloatingAgentChatDraft: (state: FloatingAgentChatState) =
48
57
  * The state after an open. Within one agent the draft's bookkeeping carries over — the new chat
49
58
  * is kept while untouched, stands by while a thread is open, and is minted afresh once sent;
50
59
  * another agent starts clean. Opening what is already shown changes nothing but the opener's
51
- * `expandHref` / `chatContext`.
60
+ * `expandHref` / `chatContext` (and the face). The prompt face is the new chat by definition:
61
+ * a prompt open with a thread target opens the new chat.
52
62
  */
53
63
  export declare const floatingAgentChatAfterOpen: <Handle extends FloatingAgentChatHandle>(prev: FloatingAgentChatState<Handle> | null, request: FloatingAgentChatOpenRequest<Handle>, mintThreadId: () => string) => FloatingAgentChatState<Handle>;
54
- /** After the first send on the draft; unchanged when the draft is not what is shown. */
64
+ /**
65
+ * After the first send on the draft: it is a thread now, shown in the panel — the prompt, if
66
+ * that is what sent it, turns into the panel. Unchanged when the draft is not what is shown.
67
+ */
55
68
  export declare const floatingAgentChatAfterDraftSent: <Handle extends FloatingAgentChatHandle>(prev: FloatingAgentChatState<Handle> | null) => FloatingAgentChatState<Handle> | null;
56
69
  export interface UseFloatingAgentChatControllerResult<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> {
57
- /** What the panel shows; null while it is closed. */
70
+ /** What the session shows; null while nothing is open. */
58
71
  state: FloatingAgentChatState<Handle> | null;
59
72
  isOpen: boolean;
60
- /** Open (or re-point) the panel. The same agent's draft carries over; another agent starts clean. */
73
+ /** Open (or re-point) the session. The same agent's draft carries over; another agent starts clean. */
61
74
  open: (options: FloatingAgentChatOpenOptions<Handle>) => void;
62
75
  close: () => void;
63
76
  /**
64
- * Close the panel when it shows one of this agent's conversations — for a surface that puts
77
+ * Close the session when it shows one of this agent's conversations — for a surface that puts
65
78
  * that agent's full transcript on screen (an agent mini-app's conversation routes).
66
79
  */
67
80
  closeForAgent: (agentChatId: string) => void;
68
- /** The panel's seam: the draft's first send made it a thread. */
81
+ /** The engine's seam: the draft's first send made it a thread (and the prompt the panel). */
69
82
  markDraftSent: () => void;
70
83
  }
71
84
  /**
72
85
  * The floating agent chat's state and transitions, for ONE provider at the app's root. Remembers
73
- * what had focus on the open that showed the panel (a sidebar row, an "Ask" button) and hands it
74
- * back on close, so keyboard users land where they were.
86
+ * what had focus on the open that showed the session (a sidebar row, an "Ask" button) and hands
87
+ * it back on close, so keyboard users land where they were.
75
88
  */
76
89
  export declare const useFloatingAgentChatController: <Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle>() => UseFloatingAgentChatControllerResult<Handle>;
77
90
  //# sourceMappingURL=floating-agent-chat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"floating-agent-chat.d.ts","sourceRoot":"","sources":["../../src/hooks/floating-agent-chat.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGrE,8FAA8F;AAC9F,MAAM,WAAW,uBAAuB;IACtC,0BAA0B,IAAI;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1F;AAED,0FAA0F;AAC1F,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,GAAG,KAAK,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,YAAY,EAAE,oBAAoB,KAAK,MAAM,GAAG,IAAI,CAAC;AAEhG,MAAM,WAAW,4BAA4B,CAAC,MAAM,SAAS,uBAAuB,GAAG,uBAAuB;IAC5G,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC,0FAA0F;IAC1F,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,8DAA8D;AAC9D,MAAM,WAAW,4BAA4B,CAC3C,MAAM,SAAS,uBAAuB,GAAG,uBAAuB,CAChE,SAAQ,IAAI,CAAC,4BAA4B,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,uBAAuB,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB,CAAC,MAAM,SAAS,uBAAuB,GAAG,uBAAuB;IACtG,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,oBAAoB,CAAC;IACnC,yFAAyF;IACzF,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,4DAA4D;AAC5D,eAAO,MAAM,wBAAwB,GAAI,OAAO,sBAAsB,KAAG,OACI,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GAAI,MAAM,SAAS,uBAAuB,EAC/E,MAAM,sBAAsB,CAAC,MAAM,CAAC,GAAG,IAAI,EAC3C,SAAS,4BAA4B,CAAC,MAAM,CAAC,EAC7C,cAAc,MAAM,MAAM,KACzB,sBAAsB,CAAC,MAAM,CAwB/B,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,+BAA+B,GAAI,MAAM,SAAS,uBAAuB,EACpF,MAAM,sBAAsB,CAAC,MAAM,CAAC,GAAG,IAAI,KAC1C,sBAAsB,CAAC,MAAM,CAAC,GAAG,IAC0C,CAAC;AAE/E,MAAM,WAAW,oCAAoC,CACnD,MAAM,SAAS,uBAAuB,GAAG,uBAAuB;IAEhE,qDAAqD;IACrD,KAAK,EAAE,sBAAsB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,qGAAqG;IACrG,IAAI,EAAE,CAAC,OAAO,EAAE,4BAA4B,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAC9D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;OAGG;IACH,aAAa,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,iEAAiE;IACjE,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,GACzC,MAAM,SAAS,uBAAuB,GAAG,uBAAuB,OAC7D,oCAAoC,CAAC,MAAM,CAuD/C,CAAC"}
1
+ {"version":3,"file":"floating-agent-chat.d.ts","sourceRoot":"","sources":["../../src/hooks/floating-agent-chat.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
- // The floating agent chat's state, headless: what the panel shows (which agent, which
2
- // conversation), the draft the new chat is until its first send, and the opener that gets focus
3
- // back on close. The agent-chat registry item renders it. Mirrors the conversation selection
4
- // rules of useAgentConversationSelection: a new chat is a draft minted here and listed nowhere
5
- // until the first send; "New chat" on an untouched draft keeps it; a thread opened beside it
6
- // leaves it standing by. The reducers are pure and tested; the hook is the thin React shell.
1
+ // The floating agent chat's state, headless: what the open session shows (which agent, which
2
+ // conversation), the face it wears (the floating prompt until a new chat's first send, the panel
3
+ // after), the draft the new chat is until that send, and the opener that gets focus back on
4
+ // close. The agent-chat registry item renders it. Mirrors the conversation selection rules of
5
+ // useAgentConversationSelection: a new chat is a draft minted here and listed nowhere until the
6
+ // first send; "New chat" on an untouched draft keeps it; a thread opened beside it leaves it
7
+ // standing by. The reducers are pure and tested; the hook is the thin React shell.
7
8
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
9
  import { agentInboxChatId } from "./use-agent-threads.js";
9
10
  /** The panel shows the new chat, nothing sent on it yet. */
@@ -12,7 +13,8 @@ export const isFloatingAgentChatDraft = (state) => state.conversation.chatThread
12
13
  * The state after an open. Within one agent the draft's bookkeeping carries over — the new chat
13
14
  * is kept while untouched, stands by while a thread is open, and is minted afresh once sent;
14
15
  * another agent starts clean. Opening what is already shown changes nothing but the opener's
15
- * `expandHref` / `chatContext`.
16
+ * `expandHref` / `chatContext` (and the face). The prompt face is the new chat by definition:
17
+ * a prompt open with a thread target opens the new chat.
16
18
  */
17
19
  export const floatingAgentChatAfterOpen = (prev, request, mintThreadId) => {
18
20
  const sameAgent = prev !== null && prev.agentChatId === request.agentChatId;
@@ -23,11 +25,13 @@ export const floatingAgentChatAfterOpen = (prev, request, mintThreadId) => {
23
25
  agentChat: request.agentChat,
24
26
  agentChatId: request.agentChatId,
25
27
  ownChatId: request.ownChatId,
28
+ face: request.face,
26
29
  expandHref: request.expandHref,
27
30
  chatContext: request.chatContext,
28
31
  };
29
- if (request.target !== "new") {
30
- return { ...base, ...draft, conversation: request.target };
32
+ const target = request.face === "prompt" ? "new" : request.target;
33
+ if (target !== "new") {
34
+ return { ...base, ...draft, conversation: target };
31
35
  }
32
36
  // A sent draft is a thread now; the new chat needs a fresh one.
33
37
  const draftThreadId = draft.draftSent ? mintThreadId() : draft.draftThreadId;
@@ -38,18 +42,21 @@ export const floatingAgentChatAfterOpen = (prev, request, mintThreadId) => {
38
42
  conversation: { chatId: request.ownChatId, chatThreadId: draftThreadId },
39
43
  };
40
44
  };
41
- /** After the first send on the draft; unchanged when the draft is not what is shown. */
42
- export const floatingAgentChatAfterDraftSent = (prev) => prev && isFloatingAgentChatDraft(prev) ? { ...prev, draftSent: true } : prev;
45
+ /**
46
+ * After the first send on the draft: it is a thread now, shown in the panel — the prompt, if
47
+ * that is what sent it, turns into the panel. Unchanged when the draft is not what is shown.
48
+ */
49
+ export const floatingAgentChatAfterDraftSent = (prev) => prev && isFloatingAgentChatDraft(prev) ? { ...prev, draftSent: true, face: "panel" } : prev;
43
50
  /**
44
51
  * The floating agent chat's state and transitions, for ONE provider at the app's root. Remembers
45
- * what had focus on the open that showed the panel (a sidebar row, an "Ask" button) and hands it
46
- * back on close, so keyboard users land where they were.
52
+ * what had focus on the open that showed the session (a sidebar row, an "Ask" button) and hands
53
+ * it back on close, so keyboard users land where they were.
47
54
  */
48
55
  export const useFloatingAgentChatController = () => {
49
56
  const [state, setState] = useState(null);
50
57
  const openerRef = useRef(null);
51
- // Focus goes back to the opener once the panel is gone — after the close commits, so the
52
- // panel's own focused element has left the DOM by then.
58
+ // Focus goes back to the opener once the session is gone — after the close commits, so the
59
+ // session's own focused element has left the DOM by then.
53
60
  useEffect(() => {
54
61
  if (state !== null) {
55
62
  return;
@@ -68,7 +75,7 @@ export const useFloatingAgentChatController = () => {
68
75
  : null;
69
76
  const { agentChatId } = options.agentChat.getAgentChatComponentProps();
70
77
  setState((prev) => {
71
- // Remembered on the open that shows the panel, not on a re-point while it is up.
78
+ // Remembered on the open that shows the session, not on a re-point while it is up.
72
79
  if (prev === null && active) {
73
80
  openerRef.current = active;
74
81
  }
@@ -77,6 +84,7 @@ export const useFloatingAgentChatController = () => {
77
84
  agentChatId,
78
85
  ownChatId: agentInboxChatId(agentChatId),
79
86
  target: options.target ?? "new",
87
+ face: options.face ?? "panel",
80
88
  expandHref: options.expandHref,
81
89
  chatContext: options.chatContext,
82
90
  }, () => crypto.randomUUID());
@@ -84,6 +92,6 @@ export const useFloatingAgentChatController = () => {
84
92
  }, []);
85
93
  const close = useCallback(() => setState(null), []);
86
94
  const closeForAgent = useCallback((agentChatId) => setState((prev) => (prev?.agentChatId === agentChatId ? null : prev)), []);
87
- const markDraftSent = useCallback(() => setState(floatingAgentChatAfterDraftSent), []);
95
+ const markDraftSent = useCallback(() => setState((prev) => floatingAgentChatAfterDraftSent(prev)), []);
88
96
  return useMemo(() => ({ state, isOpen: state !== null, open, close, closeForAgent, markDraftSent }), [state, open, close, closeForAgent, markDraftSent]);
89
97
  };
@@ -0,0 +1,28 @@
1
+ /** What the platform asks for: the agent to talk to, by its block name (`<Name>Agent.id`). */
2
+ export interface FloatingAgentPromptRequest {
3
+ agent: string;
4
+ }
5
+ /** How long a request waits for a subscriber before it is withdrawn. */
6
+ export declare const FLOATING_AGENT_PROMPT_CLAIM_TIMEOUT_MS = 5000;
7
+ /** Takes a request; `false` declines it (the agent is not on offer) — anything else claims it. */
8
+ export type FloatingAgentPromptListener = (request: FloatingAgentPromptRequest) => boolean | undefined;
9
+ export interface FloatingAgentPromptMailbox {
10
+ /**
11
+ * Hands the request to the subscriber; resolves `true` once one took it, `false` when none did
12
+ * in time or the subscriber declined it.
13
+ */
14
+ post(request: FloatingAgentPromptRequest): Promise<boolean>;
15
+ /** Takes every request from now on — and the one waiting, if any. Returns the unsubscribe. */
16
+ subscribe(listener: FloatingAgentPromptListener): () => void;
17
+ }
18
+ export interface FloatingAgentPromptMailboxTimers {
19
+ setTimeout(callback: () => void, ms: number): ReturnType<typeof setTimeout>;
20
+ clearTimeout(id: ReturnType<typeof setTimeout>): void;
21
+ }
22
+ /** One parked request at most: a newer post takes the slot (the older resolves `false`). */
23
+ export declare const createFloatingAgentPromptMailbox: (timers?: FloatingAgentPromptMailboxTimers) => FloatingAgentPromptMailbox;
24
+ /** app-render's side: the bridge's `onOpenAgentPrompt` resolves with this. */
25
+ export declare const postFloatingAgentPromptRequest: FloatingAgentPromptMailbox["post"];
26
+ /** The provider's side: opens the prompt for each request. */
27
+ export declare const subscribeFloatingAgentPromptRequests: FloatingAgentPromptMailbox["subscribe"];
28
+ //# sourceMappingURL=floating-agent-prompt-requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-agent-prompt-requests.d.ts","sourceRoot":"","sources":["../../src/hooks/floating-agent-prompt-requests.ts"],"names":[],"mappings":"AAQA,8FAA8F;AAC9F,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wEAAwE;AACxE,eAAO,MAAM,sCAAsC,OAAO,CAAC;AAE3D,kGAAkG;AAClG,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,EAAE,0BAA0B,KAAK,OAAO,GAAG,SAAS,CAAC;AAEvG,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,8FAA8F;IAC9F,SAAS,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM,IAAI,CAAC;CAC9D;AAED,MAAM,WAAW,gCAAgC;IAC/C,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC;CACvD;AAQD,4FAA4F;AAC5F,eAAO,MAAM,gCAAgC,GAC3C,SAAQ,gCAAgD,KACvD,0BAiDF,CAAC;AAIF,8EAA8E;AAC9E,eAAO,MAAM,8BAA8B,EAAE,0BAA0B,CAAC,MAAM,CAAsC,CAAC;AAErH,8DAA8D;AAC9D,eAAO,MAAM,oCAAoC,EAAE,0BAA0B,CAAC,WAAW,CAC5D,CAAC"}
@@ -0,0 +1,64 @@
1
+ // The platform's door to an app's floating agent prompt. The platform asks through the iframe
2
+ // bridge; app-render, which answers the bridge, posts the request here; the app's
3
+ // FloatingAgentChatProvider, which renders the prompt, subscribes. Both run in the iframe on
4
+ // this one module (`@blocksdiy/react-common/agent-threads` is a UMD external the bundle takes
5
+ // from app-render), so no window global is needed. A request posted before the provider mounts
6
+ // (the bundle is still loading) waits for it; one nothing claims in time is dropped and the
7
+ // platform told — an app built without the prompt.
8
+ /** How long a request waits for a subscriber before it is withdrawn. */
9
+ export const FLOATING_AGENT_PROMPT_CLAIM_TIMEOUT_MS = 5000;
10
+ // Read at call time, so a test's fake timers apply.
11
+ const defaultTimers = {
12
+ setTimeout: (callback, ms) => setTimeout(callback, ms),
13
+ clearTimeout: (id) => clearTimeout(id),
14
+ };
15
+ /** One parked request at most: a newer post takes the slot (the older resolves `false`). */
16
+ export const createFloatingAgentPromptMailbox = (timers = defaultTimers) => {
17
+ const listeners = new Set();
18
+ let parked = null;
19
+ const withdraw = (claimed) => {
20
+ if (!parked) {
21
+ return;
22
+ }
23
+ const { resolve, timer } = parked;
24
+ parked = null;
25
+ timers.clearTimeout(timer);
26
+ resolve(claimed);
27
+ };
28
+ return {
29
+ post: (request) => {
30
+ if (listeners.size > 0) {
31
+ let claimed = false;
32
+ listeners.forEach((listener) => {
33
+ if (listener(request) !== false) {
34
+ claimed = true;
35
+ }
36
+ });
37
+ return Promise.resolve(claimed);
38
+ }
39
+ withdraw(false);
40
+ return new Promise((resolve) => {
41
+ parked = {
42
+ request,
43
+ resolve,
44
+ timer: timers.setTimeout(() => withdraw(false), FLOATING_AGENT_PROMPT_CLAIM_TIMEOUT_MS),
45
+ };
46
+ });
47
+ },
48
+ subscribe: (listener) => {
49
+ listeners.add(listener);
50
+ if (parked) {
51
+ const { request } = parked;
52
+ withdraw(listener(request) !== false);
53
+ }
54
+ return () => {
55
+ listeners.delete(listener);
56
+ };
57
+ },
58
+ };
59
+ };
60
+ const mailbox = createFloatingAgentPromptMailbox();
61
+ /** app-render's side: the bridge's `onOpenAgentPrompt` resolves with this. */
62
+ export const postFloatingAgentPromptRequest = (request) => mailbox.post(request);
63
+ /** The provider's side: opens the prompt for each request. */
64
+ export const subscribeFloatingAgentPromptRequests = (listener) => mailbox.subscribe(listener);
@@ -0,0 +1,57 @@
1
+ import type { FloatingAgentChatExpandHref, FloatingAgentChatHandle, UseFloatingAgentChatControllerResult } from "./floating-agent-chat.js";
2
+ /**
3
+ * One agent the prompt can open, as the app resolved it: its id (the agent block's name — what
4
+ * the platform asks for), the agent's own chat the session opens, and where the panel's expand
5
+ * goes for a conversation started here.
6
+ */
7
+ export interface FloatingAgentPromptAgentEntry<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> {
8
+ id: string;
9
+ agentChatId: string;
10
+ handle: Handle;
11
+ expandHref?: FloatingAgentChatExpandHref;
12
+ }
13
+ /** The entry for an id, or the first entry when none is named; null for an id not on offer, or without entries. */
14
+ export declare const resolveFloatingAgentPromptAgent: <Handle extends FloatingAgentChatHandle>(agents: readonly FloatingAgentPromptAgentEntry<Handle>[], agentId?: string) => FloatingAgentPromptAgentEntry<Handle> | null;
15
+ /** What the open agent's chat lends the prompt, which renders outside it (it shows while the chat loads). */
16
+ export interface FloatingAgentPromptChat {
17
+ canSend: boolean;
18
+ send: (content: string) => void;
19
+ }
20
+ export interface FloatingAgentPromptOpenOptions {
21
+ /** One of the entries, by id; the first one by default. */
22
+ agent?: string;
23
+ /** Extra context for the conversation it starts (like the session's `open`). */
24
+ chatContext?: unknown;
25
+ }
26
+ export interface UseFloatingAgentPromptControllerOptions<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> {
27
+ /** The session the prompt opens: one controller per app. */
28
+ session: UseFloatingAgentChatControllerResult<Handle>;
29
+ agents: readonly FloatingAgentPromptAgentEntry<Handle>[];
30
+ /** False for an anonymous visitor: nothing opens, and the platform's requests go unclaimed. */
31
+ canOpen: boolean;
32
+ }
33
+ export interface UseFloatingAgentPromptControllerResult {
34
+ /** The session wears the prompt face. */
35
+ isOpen: boolean;
36
+ /** The open session's agent, as an entry id; null while nothing is open or for an agent not on offer. */
37
+ agentId: string | null;
38
+ /** True once the prompt opened; false without agents, for an agent not on offer, or for an anonymous visitor. */
39
+ openPrompt: (options?: FloatingAgentPromptOpenOptions) => boolean;
40
+ text: string;
41
+ setText: (text: string) => void;
42
+ /** Counts the opens, re-points included — the message takes focus on each. */
43
+ openCount: number;
44
+ /** The open agent's chat is up and free. */
45
+ canSend: boolean;
46
+ /** Sends through the open agent's chat; its first send turns the prompt into the panel. */
47
+ send: (content: string) => void;
48
+ /** The open agent's chat lends itself here once it is up, and takes itself back when it goes. */
49
+ setChat: (chat: FloatingAgentPromptChat | null) => void;
50
+ }
51
+ /**
52
+ * The prompt's state and transitions, for the one provider at the app's root. A fresh prompt
53
+ * starts empty; re-pointing it at another agent keeps the text; a sent message is the chat's
54
+ * (the pill is gone), a refused one stays where it was.
55
+ */
56
+ export declare const useFloatingAgentPromptController: <Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle>({ session, agents, canOpen, }: UseFloatingAgentPromptControllerOptions<Handle>) => UseFloatingAgentPromptControllerResult;
57
+ //# sourceMappingURL=floating-agent-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-agent-prompt.d.ts","sourceRoot":"","sources":["../../src/hooks/floating-agent-prompt.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,2BAA2B,EAC3B,uBAAuB,EACvB,oCAAoC,EACrC,MAAM,uBAAuB,CAAC;AAG/B;;;;GAIG;AACH,MAAM,WAAW,6BAA6B,CAAC,MAAM,SAAS,uBAAuB,GAAG,uBAAuB;IAC7G,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,2BAA2B,CAAC;CAC1C;AAED,mHAAmH;AACnH,eAAO,MAAM,+BAA+B,GAAI,MAAM,SAAS,uBAAuB,EACpF,QAAQ,SAAS,6BAA6B,CAAC,MAAM,CAAC,EAAE,EACxD,UAAU,MAAM,KACf,6BAA6B,CAAC,MAAM,CAAC,GAAG,IACiD,CAAC;AAE7F,6GAA6G;AAC7G,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,8BAA8B;IAC7C,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,uCAAuC,CACtD,MAAM,SAAS,uBAAuB,GAAG,uBAAuB;IAEhE,4DAA4D;IAC5D,OAAO,EAAE,oCAAoC,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,EAAE,SAAS,6BAA6B,CAAC,MAAM,CAAC,EAAE,CAAC;IACzD,+FAA+F;IAC/F,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sCAAsC;IACrD,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,yGAAyG;IACzG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,iHAAiH;IACjH,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,8BAA8B,KAAK,OAAO,CAAC;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,2FAA2F;IAC3F,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,iGAAiG;IACjG,OAAO,EAAE,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,KAAK,IAAI,CAAC;CACzD;AAED;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,GAAI,MAAM,SAAS,uBAAuB,GAAG,uBAAuB,EAAE,+BAIhH,uCAAuC,CAAC,MAAM,CAAC,KAAG,sCAuDpD,CAAC"}
@@ -0,0 +1,55 @@
1
+ // The floating agent prompt's state, headless: which of the app's agents it is for, the text
2
+ // typed, the opens (the message takes focus on each), what the open agent's chat lends it (can it
3
+ // send, the send), and the platform's requests for it (the rail's chat bubble, through
4
+ // app-render's mailbox). The session it opens is useFloatingAgentChatController's; the
5
+ // agent-chat registry item resolves the agents and renders the prompt.
6
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
+ import { subscribeFloatingAgentPromptRequests } from "./floating-agent-prompt-requests.js";
8
+ /** The entry for an id, or the first entry when none is named; null for an id not on offer, or without entries. */
9
+ export const resolveFloatingAgentPromptAgent = (agents, agentId) => (agentId === undefined ? agents[0] : agents.find((entry) => entry.id === agentId)) ?? null;
10
+ /**
11
+ * The prompt's state and transitions, for the one provider at the app's root. A fresh prompt
12
+ * starts empty; re-pointing it at another agent keeps the text; a sent message is the chat's
13
+ * (the pill is gone), a refused one stays where it was.
14
+ */
15
+ export const useFloatingAgentPromptController = ({ session, agents, canOpen, }) => {
16
+ const { state, open } = session;
17
+ const isOpen = state !== null && state.face === "prompt";
18
+ const [text, setText] = useState("");
19
+ const [openCount, setOpenCount] = useState(0);
20
+ const [chat, setChat] = useState(null);
21
+ // Opens the prompt for an agent; false when there is nothing to open — no agents, the agent
22
+ // asked for not among them, an anonymous visitor.
23
+ const openFor = useCallback((agentId, chatContext) => {
24
+ const entry = resolveFloatingAgentPromptAgent(agents, agentId);
25
+ if (!entry || !canOpen) {
26
+ return false;
27
+ }
28
+ if (!isOpen) {
29
+ setText("");
30
+ }
31
+ setOpenCount((count) => count + 1);
32
+ open({ agentChat: entry.handle, face: "prompt", expandHref: entry.expandHref, chatContext });
33
+ return true;
34
+ }, [agents, canOpen, isOpen, open]);
35
+ const openPrompt = useCallback((options) => {
36
+ const opened = openFor(options?.agent, options?.chatContext);
37
+ if (!opened) {
38
+ console.warn("Floating agent prompt: nothing to open — it needs agents on offer (the one asked for among them) and a signed-in user.");
39
+ }
40
+ return opened;
41
+ }, [openFor]);
42
+ // The platform's requests (the rail's chat bubble on an agent's row), posted through
43
+ // app-render: taken while mounted, and declined at once when there is nothing to open, so
44
+ // the platform falls back without waiting. An app without a provider leaves the request
45
+ // unclaimed; the mailbox withdraws it in time.
46
+ const openForRef = useRef(openFor);
47
+ useEffect(() => {
48
+ openForRef.current = openFor;
49
+ }, [openFor]);
50
+ useEffect(() => subscribeFloatingAgentPromptRequests((request) => openForRef.current(request.agent)), []);
51
+ const agentId = state === null ? null : (agents.find((entry) => entry.agentChatId === state.agentChatId)?.id ?? null);
52
+ const canSend = chat?.canSend ?? false;
53
+ const send = useCallback((content) => chat?.send(content), [chat]);
54
+ return useMemo(() => ({ isOpen, agentId, openPrompt, text, setText, openCount, canSend, send, setChat }), [isOpen, agentId, openPrompt, text, openCount, canSend, send]);
55
+ };
@@ -6,7 +6,10 @@ export { type AgentConversationChat, type AgentConversationRef, type AgentConver
6
6
  export { type AgentConversationContextValue, AgentConversationProvider, type AgentConversationProviderProps, AgentThreadConversationProvider, type AgentThreadConversationProviderProps, type AgentThreadFilters, useAgentConversationContext, } from "./agent-conversation-context.js";
7
7
  export { useAgentThread, type UseAgentThreadOptions, type UseAgentThreadResult } from "./use-agent-thread.js";
8
8
  export { useMediaQuery } from "./use-media-query.js";
9
- export { type FloatingAgentChatExpandHref, type FloatingAgentChatHandle, type FloatingAgentChatOpenOptions, type FloatingAgentChatOpenRequest, type FloatingAgentChatState, type FloatingAgentChatTarget, floatingAgentChatAfterDraftSent, floatingAgentChatAfterOpen, isFloatingAgentChatDraft, useFloatingAgentChatController, type UseFloatingAgentChatControllerResult, } from "./floating-agent-chat.js";
9
+ export { type FloatingAgentChatExpandHref, type FloatingAgentChatFace, type FloatingAgentChatHandle, type FloatingAgentChatOpenOptions, type FloatingAgentChatOpenRequest, type FloatingAgentChatState, type FloatingAgentChatTarget, floatingAgentChatAfterDraftSent, floatingAgentChatAfterOpen, isFloatingAgentChatDraft, useFloatingAgentChatController, type UseFloatingAgentChatControllerResult, } from "./floating-agent-chat.js";
10
+ export { type FloatingAgentChatEnginePhase, type FloatingAgentChatUrlContext, useFloatingAgentChatContext, useFloatingAgentChatEngine, type UseFloatingAgentChatEngineResult, } from "./floating-agent-chat-engine.js";
11
+ export { type FloatingAgentPromptAgentEntry, type FloatingAgentPromptChat, type FloatingAgentPromptOpenOptions, useFloatingAgentPromptController, type UseFloatingAgentPromptControllerOptions, type UseFloatingAgentPromptControllerResult, } from "./floating-agent-prompt.js";
12
+ export { type FloatingAgentPromptListener, type FloatingAgentPromptRequest, postFloatingAgentPromptRequest, subscribeFloatingAgentPromptRequests, } from "./floating-agent-prompt-requests.js";
10
13
  export { clampPanelSize, type PanelResizeAxis, type PanelResizeBounds, type PanelResizeHandleProps, type PanelSize, parseStoredPanelSize, useResizablePanel, type UseResizablePanelOptions, type UseResizablePanelResult, } from "./use-resizable-panel.js";
11
14
  /** The auth a reader carries — its SDK token and extra headers — read at call time. */
12
15
  export interface AgentThreadsAuth {
@@ -1 +1 @@
1
- {"version":3,"file":"use-agent-threads.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-threads.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-agent-threads.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-threads.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,9 @@ export { AgentConversationProvider, AgentThreadConversationProvider, useAgentCon
10
10
  export { useAgentThread } from "./use-agent-thread.js";
11
11
  export { useMediaQuery } from "./use-media-query.js";
12
12
  export { floatingAgentChatAfterDraftSent, floatingAgentChatAfterOpen, isFloatingAgentChatDraft, useFloatingAgentChatController, } from "./floating-agent-chat.js";
13
+ export { useFloatingAgentChatContext, useFloatingAgentChatEngine, } from "./floating-agent-chat-engine.js";
14
+ export { useFloatingAgentPromptController, } from "./floating-agent-prompt.js";
15
+ export { postFloatingAgentPromptRequest, subscribeFloatingAgentPromptRequests, } from "./floating-agent-prompt-requests.js";
13
16
  export { clampPanelSize, parseStoredPanelSize, useResizablePanel, } from "./use-resizable-panel.js";
14
17
  /** A non-2xx answer from the agent-threads API, with its status — a reader tells a 404 (no row) from a failure. */
15
18
  export class AgentThreadsRequestError extends Error {
@@ -89,5 +89,13 @@ export interface IframeApi extends Methods {
89
89
  * when its sample props re-render it.
90
90
  */
91
91
  onLockChatComponentFocus: (isLocked: boolean) => Promise<void>;
92
+ /**
93
+ * Opens the app's floating agent prompt for one of its agents (`agent` is the agent's block
94
+ * name). Resolves `false` when nothing in the app took the request — an app built without the
95
+ * prompt — so the platform can fall back to the agent's own new-chat page.
96
+ */
97
+ onOpenAgentPrompt: (args: {
98
+ agent: string;
99
+ }) => Promise<boolean>;
92
100
  }
93
101
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/iframe-communication/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/iframe-communication/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocksdiy/react-common",
3
- "version": "1.54.0",
3
+ "version": "1.55.1",
4
4
  "type": "module",
5
5
  "description": "React common",
6
6
  "keywords": [],
@@ -33,15 +33,16 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@ag-ui/client": "0.0.59",
36
+ "@blocksdiy/blocks-client-api": "1.26.1",
36
37
  "@copilotkit/react-core": "1.70.2",
37
38
  "@radix-ui/react-slot": "^1.2.3",
38
39
  "@vapi-ai/web": "^2.5.2",
39
40
  "penpal": "^8.0.0",
40
41
  "react": "^19.2.8",
41
- "use-stick-to-bottom": "1.1.4",
42
- "@blocksdiy/blocks-client-api": "1.5.0"
42
+ "use-stick-to-bottom": "1.1.4"
43
43
  },
44
44
  "devDependencies": {
45
+ "@blockscom/eslint-config": "4.6.4",
45
46
  "@types/react": "^19.2.18",
46
47
  "babel-plugin-react-compiler": "^1.0.0",
47
48
  "eslint-plugin-react": "^7.37.5",
@@ -49,11 +50,10 @@
49
50
  "jest": "^29.7.0",
50
51
  "ts-jest": "^29.2.5",
51
52
  "tsc-alias": "^1.8.10",
52
- "typescript": "^5.9.3",
53
- "@blockscom/eslint-config": "4.6.4"
53
+ "typescript": "^5.9.3"
54
54
  },
55
55
  "engines": {
56
- "node": ">=24.11.0"
56
+ "node": ">=24.14.0"
57
57
  },
58
58
  "scripts": {
59
59
  "clean": "rm -rf ./dist/ && rm -rf tsconfig.tsbuildinfo && rm -rf node_modules",