@athenaintel/react 0.35.0 → 0.36.0

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.
Files changed (66) hide show
  1. package/README.md +49 -0
  2. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +4 -0
  3. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  4. package/dist/agent-runtime/src/generated/runconfig-contract.js +4 -0
  5. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  6. package/dist/agent-runtime/src/tool-metadata.cjs +11 -0
  7. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  8. package/dist/agent-runtime/src/tool-metadata.js +11 -0
  9. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  10. package/dist/catalog/agent-mode-menu.cjs +115 -0
  11. package/dist/catalog/agent-mode-menu.cjs.map +1 -0
  12. package/dist/catalog/agent-mode-menu.d.ts +101 -0
  13. package/dist/catalog/agent-mode-menu.js +115 -0
  14. package/dist/catalog/agent-mode-menu.js.map +1 -0
  15. package/dist/catalog/chat-pickers.cjs +51 -0
  16. package/dist/catalog/chat-pickers.cjs.map +1 -1
  17. package/dist/catalog/chat-pickers.d.ts +28 -0
  18. package/dist/catalog/chat-pickers.js +52 -1
  19. package/dist/catalog/chat-pickers.js.map +1 -1
  20. package/dist/catalog/runtime-catalog.cjs +4 -0
  21. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  22. package/dist/catalog/runtime-catalog.d.ts +16 -0
  23. package/dist/catalog/runtime-catalog.js +5 -1
  24. package/dist/catalog/runtime-catalog.js.map +1 -1
  25. package/dist/catalog/use-athena-chat-mode.cjs +139 -0
  26. package/dist/catalog/use-athena-chat-mode.cjs.map +1 -0
  27. package/dist/catalog/use-athena-chat-mode.d.ts +43 -0
  28. package/dist/catalog/use-athena-chat-mode.js +139 -0
  29. package/dist/catalog/use-athena-chat-mode.js.map +1 -0
  30. package/dist/chat/AthenaChat.cjs +2 -0
  31. package/dist/chat/AthenaChat.cjs.map +1 -1
  32. package/dist/chat/AthenaChat.js +2 -0
  33. package/dist/chat/AthenaChat.js.map +1 -1
  34. package/dist/chat-ui/statewire.cjs +3 -0
  35. package/dist/chat-ui/statewire.cjs.map +1 -1
  36. package/dist/chat-ui/statewire.d.ts +4 -2
  37. package/dist/chat-ui/statewire.js +3 -0
  38. package/dist/chat-ui/statewire.js.map +1 -1
  39. package/dist/index.cjs +3 -0
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.ts +4 -2
  42. package/dist/index.js +4 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/provider/AthenaProvider.cjs +52 -1
  45. package/dist/provider/AthenaProvider.cjs.map +1 -1
  46. package/dist/provider/AthenaProvider.d.ts +11 -1
  47. package/dist/provider/AthenaProvider.js +53 -2
  48. package/dist/provider/AthenaProvider.js.map +1 -1
  49. package/dist/provider/chat-mode-context.cjs +6 -0
  50. package/dist/provider/chat-mode-context.cjs.map +1 -0
  51. package/dist/provider/chat-mode-context.d.ts +35 -0
  52. package/dist/provider/chat-mode-context.js +6 -0
  53. package/dist/provider/chat-mode-context.js.map +1 -0
  54. package/dist/react/package.json.cjs +1 -1
  55. package/dist/react/package.json.js +1 -1
  56. package/dist/runtime/statewire-run-config.cjs +10 -6
  57. package/dist/runtime/statewire-run-config.cjs.map +1 -1
  58. package/dist/runtime/statewire-run-config.d.ts +7 -0
  59. package/dist/runtime/statewire-run-config.js +10 -6
  60. package/dist/runtime/statewire-run-config.js.map +1 -1
  61. package/dist/runtime/useAthenaStatewireRuntime.cjs +2 -0
  62. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  63. package/dist/runtime/useAthenaStatewireRuntime.d.ts +2 -0
  64. package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
  65. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  66. package/package.json +1 -1
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const react$1 = require("@assistant-ui/react");
4
+ const reactQuery = require("@tanstack/react-query");
5
+ const react = require("react");
6
+ const apiClient = require("../chat-ui/mentions/suggestions/data/api-client.cjs");
7
+ const agentSelectionContext = require("../provider/agent-selection-context.cjs");
8
+ const chatModeContext = require("../provider/chat-mode-context.cjs");
9
+ const agentModeMenu = require("./agent-mode-menu.cjs");
10
+ const runtimeCatalog = require("./runtime-catalog.cjs");
11
+ const OFF = { status: "off" };
12
+ const LOADING = { status: "loading" };
13
+ const NO_MODES = [];
14
+ const ATHENA_SESSION_MODE_QUERY = `
15
+ query AthenaSessionMode($assetId: String!) {
16
+ getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }
17
+ }
18
+ `;
19
+ function useAthenaChatMode() {
20
+ var _a, _b, _c;
21
+ const selection = react.useContext(chatModeContext.AthenaChatModeSelectionContext);
22
+ const agentSelection = react.useContext(agentSelectionContext.AthenaAgentSelectionContext);
23
+ const agentAssetId = (agentSelection == null ? void 0 : agentSelection.agentAssetId) ?? null;
24
+ const channel = (agentSelection == null ? void 0 : agentSelection.channel) ?? null;
25
+ const hostModes = (selection == null ? void 0 : selection.hostModes) ?? NO_MODES;
26
+ const enabled = selection !== null && hostModes.length > 0 && agentAssetId !== null;
27
+ const auth = runtimeCatalog.useCatalogAuth();
28
+ const principal = runtimeCatalog.useCatalogPrincipal();
29
+ const queryClient = runtimeCatalog.useCatalogQueryClient();
30
+ const agentRead = reactQuery.useQuery(
31
+ {
32
+ queryKey: ["athena-sdk", "catalog", "agent-modes", auth.backendUrl, principal, agentAssetId],
33
+ queryFn: async () => {
34
+ try {
35
+ const data = await apiClient.fetchGraphQL(
36
+ auth,
37
+ runtimeCatalog.ATHENA_AGENT_MODELS_QUERY,
38
+ { assetId: agentAssetId }
39
+ );
40
+ if (data.getAssetById === null) return { readable: false };
41
+ return {
42
+ readable: true,
43
+ source: agentModeMenu.publishedAgentModeSource(data.getAssetById.athenaMetadata)
44
+ };
45
+ } catch (error) {
46
+ if (runtimeCatalog.isAgentReadDenial(error)) return { readable: false };
47
+ throw error;
48
+ }
49
+ },
50
+ enabled,
51
+ staleTime: runtimeCatalog.AGENT_MODELS_REFRESH_MS,
52
+ refetchInterval: (query) => query.state.data !== void 0 && !query.state.data.readable ? false : runtimeCatalog.AGENT_MODELS_REFRESH_MS
53
+ },
54
+ queryClient
55
+ );
56
+ const threadEmpty = react$1.useAuiState((state) => {
57
+ var _a2;
58
+ return ((_a2 = state.optional.thread) == null ? void 0 : _a2.isEmpty) ?? true;
59
+ });
60
+ const threadRunning = react$1.useAuiState((state) => {
61
+ var _a2;
62
+ return ((_a2 = state.optional.thread) == null ? void 0 : _a2.isRunning) ?? false;
63
+ });
64
+ const threadId = (selection == null ? void 0 : selection.threadId) ?? null;
65
+ const sessionStarted = (selection == null ? void 0 : selection.isNewChat) === false || !threadEmpty;
66
+ const readSession = enabled && threadId !== null && sessionStarted;
67
+ const sessionRead = reactQuery.useQuery(
68
+ {
69
+ queryKey: ["athena-sdk", "chat-mode", "session", auth.backendUrl, principal, threadId],
70
+ queryFn: async () => {
71
+ const data = await apiClient.fetchGraphQL(
72
+ auth,
73
+ ATHENA_SESSION_MODE_QUERY,
74
+ { assetId: `asset_${threadId}` }
75
+ );
76
+ const asset = data.getAssetById;
77
+ return asset ? { exists: true, channel: agentModeMenu.sessionChannelFromMetadata(asset.athenaMetadata) } : { exists: false };
78
+ },
79
+ enabled: readSession,
80
+ staleTime: 0,
81
+ refetchOnWindowFocus: true,
82
+ retry: false
83
+ },
84
+ queryClient
85
+ );
86
+ const refetchSession = sessionRead.refetch;
87
+ const wasRunning = react.useRef(threadRunning);
88
+ react.useEffect(() => {
89
+ const ended = wasRunning.current && !threadRunning;
90
+ wasRunning.current = threadRunning;
91
+ if (ended && readSession) void refetchSession();
92
+ }, [threadRunning, readSession, refetchSession]);
93
+ const source = ((_a = agentRead.data) == null ? void 0 : _a.readable) ? agentRead.data.source : null;
94
+ const menu = react.useMemo(
95
+ () => source ? agentModeMenu.agentModeMenu({ source, channel, hostModes }) : null,
96
+ [source, channel, hostModes]
97
+ );
98
+ const pick = (selection == null ? void 0 : selection.pick) ?? null;
99
+ const session = readSession ? sessionRead.data : void 0;
100
+ const sessionChannel = (session == null ? void 0 : session.exists) ? session.channel : null;
101
+ const setPick = selection == null ? void 0 : selection.setPick;
102
+ const setSessionChannel = selection == null ? void 0 : selection.setSessionChannel;
103
+ react.useEffect(() => {
104
+ if (!threadId || !setSessionChannel || session === void 0) return;
105
+ setSessionChannel({ threadId, channel: sessionChannel });
106
+ }, [threadId, setSessionChannel, session, sessionChannel]);
107
+ react.useEffect(() => {
108
+ if (!threadId || !setPick || pick === null) return;
109
+ const applied = sessionChannel !== null && (sessionChannel === pick || source !== null && agentModeMenu.agentModeOfChannel({ source, channel: sessionChannel }) === pick);
110
+ const withdrawn = menu !== null && !menu.options.some((option) => option.id === pick);
111
+ if (applied || withdrawn) setPick({ threadId, modeId: null });
112
+ }, [threadId, setPick, pick, sessionChannel, source, menu]);
113
+ const canSwitch = !((menu == null ? void 0 : menu.locked) && sessionStarted);
114
+ const options = menu == null ? void 0 : menu.options;
115
+ const select = react.useCallback(
116
+ (modeId) => {
117
+ if (!threadId || !setPick || !canSwitch) return;
118
+ if (!(options == null ? void 0 : options.some((option) => option.id === modeId))) return;
119
+ setPick({ threadId, modeId });
120
+ },
121
+ [threadId, setPick, canSwitch, options]
122
+ );
123
+ if (!enabled) return OFF;
124
+ if (agentRead.isPending) return LOADING;
125
+ if (!menu || menu.options.length < 2) return OFF;
126
+ const current = pick ?? (source && sessionChannel !== null ? agentModeMenu.agentModeOfChannel({ source, channel: sessionChannel }) : menu.firstSendModeId);
127
+ const currentLabel = ((_b = menu.options.find((option) => option.id === current)) == null ? void 0 : _b.label) ?? (current === "base" ? "Default" : ((_c = source == null ? void 0 : source.channels[current]) == null ? void 0 : _c.label) ?? current);
128
+ return {
129
+ status: "ready",
130
+ options: menu.options,
131
+ current,
132
+ currentLabel,
133
+ canSwitch,
134
+ locked: menu.locked,
135
+ select
136
+ };
137
+ }
138
+ exports.useAthenaChatMode = useAthenaChatMode;
139
+ //# sourceMappingURL=use-athena-chat-mode.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-athena-chat-mode.cjs","sources":["../../src/catalog/use-athena-chat-mode.ts"],"sourcesContent":["import { useAuiState } from '@assistant-ui/react';\nimport { useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useEffect, useMemo, useRef } from 'react';\nimport { fetchGraphQL } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { AthenaAgentSelectionContext } from '../provider/agent-selection-context';\nimport { AthenaChatModeSelectionContext } from '../provider/chat-mode-context';\nimport {\n type AgentModeSource,\n type AthenaChatModeOption,\n agentModeMenu,\n agentModeOfChannel,\n publishedAgentModeSource,\n sessionChannelFromMetadata,\n} from './agent-mode-menu';\nimport {\n AGENT_MODELS_REFRESH_MS,\n ATHENA_AGENT_MODELS_QUERY,\n isAgentReadDenial,\n useCatalogAuth,\n useCatalogPrincipal,\n useCatalogQueryClient,\n} from './runtime-catalog';\n\n/**\n * The open chat's mode menu (`AthenaProvider` `modes`):\n *\n * - `off`: no menu: the host listed no modes, no collab agent is selected, the\n * agent cannot be read or was never published, or it offers fewer than two\n * of the listed modes on the provider's `channel`;\n * - `loading`: the agent is being read;\n * - `ready`: the modes to offer, the one the open session runs in (or a new\n * one starts in), and `select` to switch. `canSwitch` is false on a session\n * of a channel its author locks: there, people pick the mode before a\n * session's first message.\n */\nexport type AthenaChatMode =\n | { status: 'off' }\n | { status: 'loading' }\n | {\n status: 'ready';\n options: readonly AthenaChatModeOption[];\n /** The mode the open session runs in, or a new session starts in. */\n current: string;\n /** The current mode's name, also when it is none of `options`. */\n currentLabel: string;\n /** Whether a pick applies now. */\n canSwitch: boolean;\n /** The channel keeps each session in the mode it starts in. */\n locked: boolean;\n /** Run the open session's next sends in `modeId` (one of `options`). */\n select: (modeId: string) => void;\n };\n\ntype AgentModeRead = { readable: true; source: AgentModeSource | null } | { readable: false };\n\n/** The open thread's session asset: absent until its first send mints it. */\ntype SessionRead = { exists: false } | { exists: true; channel: string | null };\n\nconst OFF: AthenaChatMode = { status: 'off' };\nconst LOADING: AthenaChatMode = { status: 'loading' };\nconst NO_MODES: readonly string[] = [];\n\nconst ATHENA_SESSION_MODE_QUERY = `\n query AthenaSessionMode($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The mode menu of the chat inside the nearest `AthenaProvider`, from the\n * agent's published definition, the open session's own mode, and the\n * provider's `modes`, `agent` and `channel`. `AthenaChat` renders it in its\n * composer; use it to build a menu of your own.\n *\n * The open session's mode is read again when the chat regains focus and after\n * every run, and its sends name it, so a session switched in another browser\n * continues where it is. A pick holds until the session runs in it (or the\n * menu stops offering it); only a pick not yet sent overrides the session.\n */\nexport function useAthenaChatMode(): AthenaChatMode {\n const selection = useContext(AthenaChatModeSelectionContext);\n const agentSelection = useContext(AthenaAgentSelectionContext);\n const agentAssetId = agentSelection?.agentAssetId ?? null;\n const channel = agentSelection?.channel ?? null;\n const hostModes = selection?.hostModes ?? NO_MODES;\n const enabled = selection !== null && hostModes.length > 0 && agentAssetId !== null;\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n\n const agentRead = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-modes', auth.backendUrl, principal, agentAssetId],\n queryFn: async (): Promise<AgentModeRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId: agentAssetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModeSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) =>\n query.state.data !== undefined && !query.state.data.readable\n ? false\n : AGENT_MODELS_REFRESH_MS,\n },\n queryClient,\n );\n\n // The open thread as this chat holds it: its first send ends a new chat's\n // pick-before-start window even where the provider cannot tell (a\n // standalone chat on a thread id it minted), and the end of each run, which\n // may have switched the session (here or in another browser), reads it again.\n const threadEmpty = useAuiState((state) => state.optional.thread?.isEmpty ?? true);\n const threadRunning = useAuiState((state) => state.optional.thread?.isRunning ?? false);\n\n const threadId = selection?.threadId ?? null;\n const sessionStarted = selection?.isNewChat === false || !threadEmpty;\n const readSession = enabled && threadId !== null && sessionStarted;\n const sessionRead = useQuery(\n {\n queryKey: ['athena-sdk', 'chat-mode', 'session', auth.backendUrl, principal, threadId],\n queryFn: async (): Promise<SessionRead> => {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_SESSION_MODE_QUERY,\n { assetId: `asset_${threadId}` },\n );\n const asset = data.getAssetById;\n return asset\n ? { exists: true, channel: sessionChannelFromMetadata(asset.athenaMetadata) }\n : { exists: false };\n },\n enabled: readSession,\n staleTime: 0,\n refetchOnWindowFocus: true,\n retry: false,\n },\n queryClient,\n );\n const refetchSession = sessionRead.refetch;\n const wasRunning = useRef(threadRunning);\n useEffect(() => {\n const ended = wasRunning.current && !threadRunning;\n wasRunning.current = threadRunning;\n if (ended && readSession) void refetchSession();\n }, [threadRunning, readSession, refetchSession]);\n\n const source = agentRead.data?.readable ? agentRead.data.source : null;\n const menu = useMemo(\n () => (source ? agentModeMenu({ source, channel, hostModes }) : null),\n [source, channel, hostModes],\n );\n const pick = selection?.pick ?? null;\n const session = readSession ? sessionRead.data : undefined;\n const sessionChannel = session?.exists ? session.channel : null;\n const setPick = selection?.setPick;\n const setSessionChannel = selection?.setSessionChannel;\n\n useEffect(() => {\n if (!threadId || !setSessionChannel || session === undefined) return;\n setSessionChannel({ threadId, channel: sessionChannel });\n }, [threadId, setSessionChannel, session, sessionChannel]);\n\n useEffect(() => {\n if (!threadId || !setPick || pick === null) return;\n const applied =\n sessionChannel !== null &&\n (sessionChannel === pick ||\n (source !== null && agentModeOfChannel({ source, channel: sessionChannel }) === pick));\n const withdrawn = menu !== null && !menu.options.some((option) => option.id === pick);\n if (applied || withdrawn) setPick({ threadId, modeId: null });\n }, [threadId, setPick, pick, sessionChannel, source, menu]);\n\n const canSwitch = !(menu?.locked && sessionStarted);\n const options = menu?.options;\n const select = useCallback(\n (modeId: string) => {\n if (!threadId || !setPick || !canSwitch) return;\n if (!options?.some((option) => option.id === modeId)) return;\n setPick({ threadId, modeId });\n },\n [threadId, setPick, canSwitch, options],\n );\n\n if (!enabled) return OFF;\n if (agentRead.isPending) return LOADING;\n if (!menu || menu.options.length < 2) return OFF;\n const current =\n pick ??\n (source && sessionChannel !== null\n ? agentModeOfChannel({ source, channel: sessionChannel })\n : menu.firstSendModeId);\n const currentLabel =\n menu.options.find((option) => option.id === current)?.label ??\n (current === 'base' ? 'Default' : (source?.channels[current]?.label ?? current));\n return {\n status: 'ready',\n options: menu.options,\n current,\n currentLabel,\n canSwitch,\n locked: menu.locked,\n select,\n };\n}\n"],"names":["useContext","AthenaChatModeSelectionContext","AthenaAgentSelectionContext","useCatalogAuth","useCatalogPrincipal","useCatalogQueryClient","useQuery","fetchGraphQL","ATHENA_AGENT_MODELS_QUERY","publishedAgentModeSource","isAgentReadDenial","AGENT_MODELS_REFRESH_MS","useAuiState","_a","sessionChannelFromMetadata","useRef","useEffect","useMemo","agentModeMenu","agentModeOfChannel","useCallback"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type AthenaChatModeOption } from './agent-mode-menu';
2
+ /**
3
+ * The open chat's mode menu (`AthenaProvider` `modes`):
4
+ *
5
+ * - `off`: no menu: the host listed no modes, no collab agent is selected, the
6
+ * agent cannot be read or was never published, or it offers fewer than two
7
+ * of the listed modes on the provider's `channel`;
8
+ * - `loading`: the agent is being read;
9
+ * - `ready`: the modes to offer, the one the open session runs in (or a new
10
+ * one starts in), and `select` to switch. `canSwitch` is false on a session
11
+ * of a channel its author locks: there, people pick the mode before a
12
+ * session's first message.
13
+ */
14
+ export type AthenaChatMode = {
15
+ status: 'off';
16
+ } | {
17
+ status: 'loading';
18
+ } | {
19
+ status: 'ready';
20
+ options: readonly AthenaChatModeOption[];
21
+ /** The mode the open session runs in, or a new session starts in. */
22
+ current: string;
23
+ /** The current mode's name, also when it is none of `options`. */
24
+ currentLabel: string;
25
+ /** Whether a pick applies now. */
26
+ canSwitch: boolean;
27
+ /** The channel keeps each session in the mode it starts in. */
28
+ locked: boolean;
29
+ /** Run the open session's next sends in `modeId` (one of `options`). */
30
+ select: (modeId: string) => void;
31
+ };
32
+ /**
33
+ * The mode menu of the chat inside the nearest `AthenaProvider`, from the
34
+ * agent's published definition, the open session's own mode, and the
35
+ * provider's `modes`, `agent` and `channel`. `AthenaChat` renders it in its
36
+ * composer; use it to build a menu of your own.
37
+ *
38
+ * The open session's mode is read again when the chat regains focus and after
39
+ * every run, and its sends name it, so a session switched in another browser
40
+ * continues where it is. A pick holds until the session runs in it (or the
41
+ * menu stops offering it); only a pick not yet sent overrides the session.
42
+ */
43
+ export declare function useAthenaChatMode(): AthenaChatMode;
@@ -0,0 +1,139 @@
1
+ import { useAuiState } from "@assistant-ui/react";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { useContext, useRef, useEffect, useMemo, useCallback } from "react";
4
+ import { fetchGraphQL } from "../chat-ui/mentions/suggestions/data/api-client.js";
5
+ import { AthenaAgentSelectionContext } from "../provider/agent-selection-context.js";
6
+ import { AthenaChatModeSelectionContext } from "../provider/chat-mode-context.js";
7
+ import { publishedAgentModeSource, sessionChannelFromMetadata, agentModeMenu, agentModeOfChannel } from "./agent-mode-menu.js";
8
+ import { useCatalogAuth, useCatalogPrincipal, useCatalogQueryClient, AGENT_MODELS_REFRESH_MS, ATHENA_AGENT_MODELS_QUERY, isAgentReadDenial } from "./runtime-catalog.js";
9
+ const OFF = { status: "off" };
10
+ const LOADING = { status: "loading" };
11
+ const NO_MODES = [];
12
+ const ATHENA_SESSION_MODE_QUERY = `
13
+ query AthenaSessionMode($assetId: String!) {
14
+ getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }
15
+ }
16
+ `;
17
+ function useAthenaChatMode() {
18
+ var _a, _b, _c;
19
+ const selection = useContext(AthenaChatModeSelectionContext);
20
+ const agentSelection = useContext(AthenaAgentSelectionContext);
21
+ const agentAssetId = (agentSelection == null ? void 0 : agentSelection.agentAssetId) ?? null;
22
+ const channel = (agentSelection == null ? void 0 : agentSelection.channel) ?? null;
23
+ const hostModes = (selection == null ? void 0 : selection.hostModes) ?? NO_MODES;
24
+ const enabled = selection !== null && hostModes.length > 0 && agentAssetId !== null;
25
+ const auth = useCatalogAuth();
26
+ const principal = useCatalogPrincipal();
27
+ const queryClient = useCatalogQueryClient();
28
+ const agentRead = useQuery(
29
+ {
30
+ queryKey: ["athena-sdk", "catalog", "agent-modes", auth.backendUrl, principal, agentAssetId],
31
+ queryFn: async () => {
32
+ try {
33
+ const data = await fetchGraphQL(
34
+ auth,
35
+ ATHENA_AGENT_MODELS_QUERY,
36
+ { assetId: agentAssetId }
37
+ );
38
+ if (data.getAssetById === null) return { readable: false };
39
+ return {
40
+ readable: true,
41
+ source: publishedAgentModeSource(data.getAssetById.athenaMetadata)
42
+ };
43
+ } catch (error) {
44
+ if (isAgentReadDenial(error)) return { readable: false };
45
+ throw error;
46
+ }
47
+ },
48
+ enabled,
49
+ staleTime: AGENT_MODELS_REFRESH_MS,
50
+ refetchInterval: (query) => query.state.data !== void 0 && !query.state.data.readable ? false : AGENT_MODELS_REFRESH_MS
51
+ },
52
+ queryClient
53
+ );
54
+ const threadEmpty = useAuiState((state) => {
55
+ var _a2;
56
+ return ((_a2 = state.optional.thread) == null ? void 0 : _a2.isEmpty) ?? true;
57
+ });
58
+ const threadRunning = useAuiState((state) => {
59
+ var _a2;
60
+ return ((_a2 = state.optional.thread) == null ? void 0 : _a2.isRunning) ?? false;
61
+ });
62
+ const threadId = (selection == null ? void 0 : selection.threadId) ?? null;
63
+ const sessionStarted = (selection == null ? void 0 : selection.isNewChat) === false || !threadEmpty;
64
+ const readSession = enabled && threadId !== null && sessionStarted;
65
+ const sessionRead = useQuery(
66
+ {
67
+ queryKey: ["athena-sdk", "chat-mode", "session", auth.backendUrl, principal, threadId],
68
+ queryFn: async () => {
69
+ const data = await fetchGraphQL(
70
+ auth,
71
+ ATHENA_SESSION_MODE_QUERY,
72
+ { assetId: `asset_${threadId}` }
73
+ );
74
+ const asset = data.getAssetById;
75
+ return asset ? { exists: true, channel: sessionChannelFromMetadata(asset.athenaMetadata) } : { exists: false };
76
+ },
77
+ enabled: readSession,
78
+ staleTime: 0,
79
+ refetchOnWindowFocus: true,
80
+ retry: false
81
+ },
82
+ queryClient
83
+ );
84
+ const refetchSession = sessionRead.refetch;
85
+ const wasRunning = useRef(threadRunning);
86
+ useEffect(() => {
87
+ const ended = wasRunning.current && !threadRunning;
88
+ wasRunning.current = threadRunning;
89
+ if (ended && readSession) void refetchSession();
90
+ }, [threadRunning, readSession, refetchSession]);
91
+ const source = ((_a = agentRead.data) == null ? void 0 : _a.readable) ? agentRead.data.source : null;
92
+ const menu = useMemo(
93
+ () => source ? agentModeMenu({ source, channel, hostModes }) : null,
94
+ [source, channel, hostModes]
95
+ );
96
+ const pick = (selection == null ? void 0 : selection.pick) ?? null;
97
+ const session = readSession ? sessionRead.data : void 0;
98
+ const sessionChannel = (session == null ? void 0 : session.exists) ? session.channel : null;
99
+ const setPick = selection == null ? void 0 : selection.setPick;
100
+ const setSessionChannel = selection == null ? void 0 : selection.setSessionChannel;
101
+ useEffect(() => {
102
+ if (!threadId || !setSessionChannel || session === void 0) return;
103
+ setSessionChannel({ threadId, channel: sessionChannel });
104
+ }, [threadId, setSessionChannel, session, sessionChannel]);
105
+ useEffect(() => {
106
+ if (!threadId || !setPick || pick === null) return;
107
+ const applied = sessionChannel !== null && (sessionChannel === pick || source !== null && agentModeOfChannel({ source, channel: sessionChannel }) === pick);
108
+ const withdrawn = menu !== null && !menu.options.some((option) => option.id === pick);
109
+ if (applied || withdrawn) setPick({ threadId, modeId: null });
110
+ }, [threadId, setPick, pick, sessionChannel, source, menu]);
111
+ const canSwitch = !((menu == null ? void 0 : menu.locked) && sessionStarted);
112
+ const options = menu == null ? void 0 : menu.options;
113
+ const select = useCallback(
114
+ (modeId) => {
115
+ if (!threadId || !setPick || !canSwitch) return;
116
+ if (!(options == null ? void 0 : options.some((option) => option.id === modeId))) return;
117
+ setPick({ threadId, modeId });
118
+ },
119
+ [threadId, setPick, canSwitch, options]
120
+ );
121
+ if (!enabled) return OFF;
122
+ if (agentRead.isPending) return LOADING;
123
+ if (!menu || menu.options.length < 2) return OFF;
124
+ const current = pick ?? (source && sessionChannel !== null ? agentModeOfChannel({ source, channel: sessionChannel }) : menu.firstSendModeId);
125
+ const currentLabel = ((_b = menu.options.find((option) => option.id === current)) == null ? void 0 : _b.label) ?? (current === "base" ? "Default" : ((_c = source == null ? void 0 : source.channels[current]) == null ? void 0 : _c.label) ?? current);
126
+ return {
127
+ status: "ready",
128
+ options: menu.options,
129
+ current,
130
+ currentLabel,
131
+ canSwitch,
132
+ locked: menu.locked,
133
+ select
134
+ };
135
+ }
136
+ export {
137
+ useAthenaChatMode
138
+ };
139
+ //# sourceMappingURL=use-athena-chat-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-athena-chat-mode.js","sources":["../../src/catalog/use-athena-chat-mode.ts"],"sourcesContent":["import { useAuiState } from '@assistant-ui/react';\nimport { useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useEffect, useMemo, useRef } from 'react';\nimport { fetchGraphQL } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { AthenaAgentSelectionContext } from '../provider/agent-selection-context';\nimport { AthenaChatModeSelectionContext } from '../provider/chat-mode-context';\nimport {\n type AgentModeSource,\n type AthenaChatModeOption,\n agentModeMenu,\n agentModeOfChannel,\n publishedAgentModeSource,\n sessionChannelFromMetadata,\n} from './agent-mode-menu';\nimport {\n AGENT_MODELS_REFRESH_MS,\n ATHENA_AGENT_MODELS_QUERY,\n isAgentReadDenial,\n useCatalogAuth,\n useCatalogPrincipal,\n useCatalogQueryClient,\n} from './runtime-catalog';\n\n/**\n * The open chat's mode menu (`AthenaProvider` `modes`):\n *\n * - `off`: no menu: the host listed no modes, no collab agent is selected, the\n * agent cannot be read or was never published, or it offers fewer than two\n * of the listed modes on the provider's `channel`;\n * - `loading`: the agent is being read;\n * - `ready`: the modes to offer, the one the open session runs in (or a new\n * one starts in), and `select` to switch. `canSwitch` is false on a session\n * of a channel its author locks: there, people pick the mode before a\n * session's first message.\n */\nexport type AthenaChatMode =\n | { status: 'off' }\n | { status: 'loading' }\n | {\n status: 'ready';\n options: readonly AthenaChatModeOption[];\n /** The mode the open session runs in, or a new session starts in. */\n current: string;\n /** The current mode's name, also when it is none of `options`. */\n currentLabel: string;\n /** Whether a pick applies now. */\n canSwitch: boolean;\n /** The channel keeps each session in the mode it starts in. */\n locked: boolean;\n /** Run the open session's next sends in `modeId` (one of `options`). */\n select: (modeId: string) => void;\n };\n\ntype AgentModeRead = { readable: true; source: AgentModeSource | null } | { readable: false };\n\n/** The open thread's session asset: absent until its first send mints it. */\ntype SessionRead = { exists: false } | { exists: true; channel: string | null };\n\nconst OFF: AthenaChatMode = { status: 'off' };\nconst LOADING: AthenaChatMode = { status: 'loading' };\nconst NO_MODES: readonly string[] = [];\n\nconst ATHENA_SESSION_MODE_QUERY = `\n query AthenaSessionMode($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The mode menu of the chat inside the nearest `AthenaProvider`, from the\n * agent's published definition, the open session's own mode, and the\n * provider's `modes`, `agent` and `channel`. `AthenaChat` renders it in its\n * composer; use it to build a menu of your own.\n *\n * The open session's mode is read again when the chat regains focus and after\n * every run, and its sends name it, so a session switched in another browser\n * continues where it is. A pick holds until the session runs in it (or the\n * menu stops offering it); only a pick not yet sent overrides the session.\n */\nexport function useAthenaChatMode(): AthenaChatMode {\n const selection = useContext(AthenaChatModeSelectionContext);\n const agentSelection = useContext(AthenaAgentSelectionContext);\n const agentAssetId = agentSelection?.agentAssetId ?? null;\n const channel = agentSelection?.channel ?? null;\n const hostModes = selection?.hostModes ?? NO_MODES;\n const enabled = selection !== null && hostModes.length > 0 && agentAssetId !== null;\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n\n const agentRead = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-modes', auth.backendUrl, principal, agentAssetId],\n queryFn: async (): Promise<AgentModeRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId: agentAssetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModeSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) =>\n query.state.data !== undefined && !query.state.data.readable\n ? false\n : AGENT_MODELS_REFRESH_MS,\n },\n queryClient,\n );\n\n // The open thread as this chat holds it: its first send ends a new chat's\n // pick-before-start window even where the provider cannot tell (a\n // standalone chat on a thread id it minted), and the end of each run, which\n // may have switched the session (here or in another browser), reads it again.\n const threadEmpty = useAuiState((state) => state.optional.thread?.isEmpty ?? true);\n const threadRunning = useAuiState((state) => state.optional.thread?.isRunning ?? false);\n\n const threadId = selection?.threadId ?? null;\n const sessionStarted = selection?.isNewChat === false || !threadEmpty;\n const readSession = enabled && threadId !== null && sessionStarted;\n const sessionRead = useQuery(\n {\n queryKey: ['athena-sdk', 'chat-mode', 'session', auth.backendUrl, principal, threadId],\n queryFn: async (): Promise<SessionRead> => {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_SESSION_MODE_QUERY,\n { assetId: `asset_${threadId}` },\n );\n const asset = data.getAssetById;\n return asset\n ? { exists: true, channel: sessionChannelFromMetadata(asset.athenaMetadata) }\n : { exists: false };\n },\n enabled: readSession,\n staleTime: 0,\n refetchOnWindowFocus: true,\n retry: false,\n },\n queryClient,\n );\n const refetchSession = sessionRead.refetch;\n const wasRunning = useRef(threadRunning);\n useEffect(() => {\n const ended = wasRunning.current && !threadRunning;\n wasRunning.current = threadRunning;\n if (ended && readSession) void refetchSession();\n }, [threadRunning, readSession, refetchSession]);\n\n const source = agentRead.data?.readable ? agentRead.data.source : null;\n const menu = useMemo(\n () => (source ? agentModeMenu({ source, channel, hostModes }) : null),\n [source, channel, hostModes],\n );\n const pick = selection?.pick ?? null;\n const session = readSession ? sessionRead.data : undefined;\n const sessionChannel = session?.exists ? session.channel : null;\n const setPick = selection?.setPick;\n const setSessionChannel = selection?.setSessionChannel;\n\n useEffect(() => {\n if (!threadId || !setSessionChannel || session === undefined) return;\n setSessionChannel({ threadId, channel: sessionChannel });\n }, [threadId, setSessionChannel, session, sessionChannel]);\n\n useEffect(() => {\n if (!threadId || !setPick || pick === null) return;\n const applied =\n sessionChannel !== null &&\n (sessionChannel === pick ||\n (source !== null && agentModeOfChannel({ source, channel: sessionChannel }) === pick));\n const withdrawn = menu !== null && !menu.options.some((option) => option.id === pick);\n if (applied || withdrawn) setPick({ threadId, modeId: null });\n }, [threadId, setPick, pick, sessionChannel, source, menu]);\n\n const canSwitch = !(menu?.locked && sessionStarted);\n const options = menu?.options;\n const select = useCallback(\n (modeId: string) => {\n if (!threadId || !setPick || !canSwitch) return;\n if (!options?.some((option) => option.id === modeId)) return;\n setPick({ threadId, modeId });\n },\n [threadId, setPick, canSwitch, options],\n );\n\n if (!enabled) return OFF;\n if (agentRead.isPending) return LOADING;\n if (!menu || menu.options.length < 2) return OFF;\n const current =\n pick ??\n (source && sessionChannel !== null\n ? agentModeOfChannel({ source, channel: sessionChannel })\n : menu.firstSendModeId);\n const currentLabel =\n menu.options.find((option) => option.id === current)?.label ??\n (current === 'base' ? 'Default' : (source?.channels[current]?.label ?? current));\n return {\n status: 'ready',\n options: menu.options,\n current,\n currentLabel,\n canSwitch,\n locked: menu.locked,\n select,\n };\n}\n"],"names":["_a"],"mappings":"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"}
@@ -6,6 +6,7 @@ const AthenaChatErrorBoundary = require("./AthenaChatErrorBoundary.cjs");
6
6
  const StatewireApprovalCard = require("./StatewireApprovalCard.cjs");
7
7
  const StatewireQueuedMessages = require("./StatewireQueuedMessages.cjs");
8
8
  const statewireBanners = require("./statewire-banners.cjs");
9
+ const chatPickers = require("../catalog/chat-pickers.cjs");
9
10
  const StatewireRunRefusalNotice = require("./StatewireRunRefusalNotice.cjs");
10
11
  const WaitingOnYouBanner = require("./WaitingOnYouBanner.cjs");
11
12
  const wakeMarker = require("../chat-ui/messages/wake-marker.cjs");
@@ -544,6 +545,7 @@ const AthenaChatComposer = ({ tools, slots, dictation, welcomeSuggestionCount })
544
545
  }
545
546
  }
546
547
  ),
548
+ /* @__PURE__ */ jsxRuntime.jsx(chatPickers.AthenaChatModeMenu, {}),
547
549
  slots == null ? void 0 : slots.toolbarStart
548
550
  ] }) }),
549
551
  toolbarEnd: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: recording ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [