@agent-native/toolkit 0.201.1 → 0.202.0-nightly-20261006033736
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/agent-native.eject.json +39 -12
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +292 -23
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +5 -0
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +5 -0
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +78 -3
- package/dist/app/auth/AuthPage.d.ts.map +1 -1
- package/dist/app/auth/AuthPage.js +7 -14
- package/dist/app/auth/AuthPage.js.map +1 -1
- package/dist/app/auth/server.d.ts +6 -0
- package/dist/app/auth/server.d.ts.map +1 -0
- package/dist/app/auth/server.js +19 -0
- package/dist/app/auth/server.js.map +1 -0
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +164 -83
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentSidebar.d.ts +2 -1
- package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
- package/dist/app/chat/AgentSidebar.js +2 -2
- package/dist/app/chat/AgentSidebar.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +13 -3
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +2 -0
- package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +41 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +41 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +41 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +41 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +41 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +41 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +41 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +41 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +41 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +41 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +41 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +41 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/shared/StarfieldBackground.d.ts +1 -6
- package/dist/app/shared/StarfieldBackground.d.ts.map +1 -1
- package/dist/app/shared/StarfieldBackground.js +1 -368
- package/dist/app/shared/StarfieldBackground.js.map +1 -1
- package/dist/app/shared/WaveBackground.d.ts +5 -0
- package/dist/app/shared/WaveBackground.d.ts.map +1 -0
- package/dist/app/shared/WaveBackground.js +34 -0
- package/dist/app/shared/WaveBackground.js.map +1 -0
- package/dist/app/shared/WebGlWaveBackground.d.ts +9 -0
- package/dist/app/shared/WebGlWaveBackground.d.ts.map +1 -0
- package/dist/app/shared/WebGlWaveBackground.js +433 -0
- package/dist/app/shared/WebGlWaveBackground.js.map +1 -0
- package/dist/app/shared/index.d.ts +1 -0
- package/dist/app/shared/index.d.ts.map +1 -1
- package/dist/app/shared/index.js +1 -0
- package/dist/app/shared/index.js.map +1 -1
- package/dist/app/shared/ocean/bloom-blur.wgsl +43 -0
- package/dist/app/shared/ocean/bloom-blur.wgsl.js +1 -0
- package/dist/app/shared/ocean/bloom-bright.wgsl +21 -0
- package/dist/app/shared/ocean/bloom-bright.wgsl.js +1 -0
- package/dist/app/shared/ocean/bloom-composite.wgsl +40 -0
- package/dist/app/shared/ocean/bloom-composite.wgsl.js +1 -0
- package/dist/app/shared/ocean/brand-colors.d.ts +9 -0
- package/dist/app/shared/ocean/brand-colors.d.ts.map +1 -0
- package/dist/app/shared/ocean/brand-colors.js +45 -0
- package/dist/app/shared/ocean/brand-colors.js.map +1 -0
- package/dist/app/shared/ocean/camera.d.ts +5 -0
- package/dist/app/shared/ocean/camera.d.ts.map +1 -0
- package/dist/app/shared/ocean/camera.js +24 -0
- package/dist/app/shared/ocean/camera.js.map +1 -0
- package/dist/app/shared/ocean/hero-ocean-background.d.ts +8 -0
- package/dist/app/shared/ocean/hero-ocean-background.d.ts.map +1 -0
- package/dist/app/shared/ocean/hero-ocean-background.js +186 -0
- package/dist/app/shared/ocean/hero-ocean-background.js.map +1 -0
- package/dist/app/shared/ocean/ifft-stage.wgsl +36 -0
- package/dist/app/shared/ocean/ifft-stage.wgsl.js +1 -0
- package/dist/app/shared/ocean/initial-spectrum.wgsl +36 -0
- package/dist/app/shared/ocean/initial-spectrum.wgsl.js +1 -0
- package/dist/app/shared/ocean/noise.wgsl +24 -0
- package/dist/app/shared/ocean/noise.wgsl.js +1 -0
- package/dist/app/shared/ocean/normal-foam.wgsl +32 -0
- package/dist/app/shared/ocean/normal-foam.wgsl.js +1 -0
- package/dist/app/shared/ocean/ocean-colors.d.ts +6 -0
- package/dist/app/shared/ocean/ocean-colors.d.ts.map +1 -0
- package/dist/app/shared/ocean/ocean-colors.js +6 -0
- package/dist/app/shared/ocean/ocean-colors.js.map +1 -0
- package/dist/app/shared/ocean/ocean-common.wgsl +15 -0
- package/dist/app/shared/ocean/ocean-common.wgsl.js +1 -0
- package/dist/app/shared/ocean/ocean-graph.d.ts +12 -0
- package/dist/app/shared/ocean/ocean-graph.d.ts.map +1 -0
- package/dist/app/shared/ocean/ocean-graph.js +16 -0
- package/dist/app/shared/ocean/ocean-graph.js.map +1 -0
- package/dist/app/shared/ocean/particles.wgsl +139 -0
- package/dist/app/shared/ocean/particles.wgsl.js +1 -0
- package/dist/app/shared/ocean/present.wgsl +40 -0
- package/dist/app/shared/ocean/present.wgsl.js +1 -0
- package/dist/app/shared/ocean/renderer.d.ts +66 -0
- package/dist/app/shared/ocean/renderer.d.ts.map +1 -0
- package/dist/app/shared/ocean/renderer.js +535 -0
- package/dist/app/shared/ocean/renderer.js.map +1 -0
- package/dist/app/shared/ocean/spectrum.wgsl +35 -0
- package/dist/app/shared/ocean/spectrum.wgsl.js +1 -0
- package/dist/app/shared/ocean/tuning.d.ts +48 -0
- package/dist/app/shared/ocean/tuning.d.ts.map +1 -0
- package/dist/app/shared/ocean/tuning.js +74 -0
- package/dist/app/shared/ocean/tuning.js.map +1 -0
- package/dist/app/shared/ocean/webgpu-support.d.ts +3 -0
- package/dist/app/shared/ocean/webgpu-support.d.ts.map +1 -0
- package/dist/app/shared/ocean/webgpu-support.js +13 -0
- package/dist/app/shared/ocean/webgpu-support.js.map +1 -0
- package/dist/app/sharing/AccessRequestApprovalPage.d.ts +23 -0
- package/dist/app/sharing/AccessRequestApprovalPage.d.ts.map +1 -0
- package/dist/app/sharing/AccessRequestApprovalPage.js +95 -0
- package/dist/app/sharing/AccessRequestApprovalPage.js.map +1 -0
- package/dist/app/sharing/AccessRequestsSection.d.ts +5 -0
- package/dist/app/sharing/AccessRequestsSection.d.ts.map +1 -0
- package/dist/app/sharing/AccessRequestsSection.js +47 -0
- package/dist/app/sharing/AccessRequestsSection.js.map +1 -0
- package/dist/app/sharing/ResourceAccessScreen.d.ts +53 -0
- package/dist/app/sharing/ResourceAccessScreen.d.ts.map +1 -0
- package/dist/app/sharing/ResourceAccessScreen.js +132 -0
- package/dist/app/sharing/ResourceAccessScreen.js.map +1 -0
- package/dist/app/sharing/ShareButton.d.ts.map +1 -1
- package/dist/app/sharing/ShareButton.js +4 -2
- package/dist/app/sharing/ShareButton.js.map +1 -1
- package/dist/app/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/app/sharing/ShareDialog.js +7 -5
- package/dist/app/sharing/ShareDialog.js.map +1 -1
- package/dist/app/sharing/index.d.ts +2 -0
- package/dist/app/sharing/index.d.ts.map +1 -1
- package/dist/app/sharing/index.js +2 -0
- package/dist/app/sharing/index.js.map +1 -1
- package/dist/app/styles/agent-native.css +21 -1
- package/dist/app/styles/tokens/agent-kit.css +3 -1
- package/dist/composer/AgentSuggestionBar.d.ts +1 -1
- package/dist/composer/AgentSuggestionBar.d.ts.map +1 -1
- package/dist/composer/AgentSuggestionBar.js +75 -6
- package/dist/composer/AgentSuggestionBar.js.map +1 -1
- package/package.json +14 -4
- package/src/app/agentkit/react/components.tsx +492 -60
- package/src/app/agentkit/react/context.tsx +10 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +487 -1
- package/src/app/agentkit/react/styles.css +78 -3
- package/src/app/auth/AuthPage.spec.tsx +11 -7
- package/src/app/auth/AuthPage.tsx +16 -35
- package/src/app/auth/server.spec.ts +68 -0
- package/src/app/auth/server.ts +29 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +287 -290
- package/src/app/chat/AgentKitAssistantChat.tsx +219 -116
- package/src/app/chat/AgentSidebar.tsx +3 -0
- package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +85 -0
- package/src/app/chat/agentkit-chat/guided-questions.tsx +12 -5
- package/src/app/chat/chat/surface-types.ts +2 -0
- package/src/app/i18n/catalogs/ar-SA.ts +44 -0
- package/src/app/i18n/catalogs/de-DE.ts +55 -0
- package/src/app/i18n/catalogs/en-US.ts +46 -0
- package/src/app/i18n/catalogs/es-ES.ts +53 -0
- package/src/app/i18n/catalogs/fr-FR.ts +53 -0
- package/src/app/i18n/catalogs/hi-IN.ts +47 -0
- package/src/app/i18n/catalogs/ja-JP.ts +54 -0
- package/src/app/i18n/catalogs/ko-KR.ts +50 -0
- package/src/app/i18n/catalogs/pt-BR.ts +52 -0
- package/src/app/i18n/catalogs/zh-CN.ts +42 -0
- package/src/app/i18n/catalogs/zh-TW.ts +43 -0
- package/src/app/shared/StarfieldBackground.tsx +4 -423
- package/src/app/shared/WaveBackground.spec.tsx +104 -0
- package/src/app/shared/WaveBackground.tsx +60 -0
- package/src/app/shared/WebGlWaveBackground.spec.tsx +106 -0
- package/src/app/shared/WebGlWaveBackground.tsx +499 -0
- package/src/app/shared/index.ts +1 -0
- package/src/app/shared/ocean/bloom-blur.wgsl +43 -0
- package/src/app/shared/ocean/bloom-bright.wgsl +21 -0
- package/src/app/shared/ocean/bloom-composite.wgsl +40 -0
- package/src/app/shared/ocean/brand-colors.ts +49 -0
- package/src/app/shared/ocean/camera.ts +28 -0
- package/src/app/shared/ocean/hero-ocean-background.spec.tsx +369 -0
- package/src/app/shared/ocean/hero-ocean-background.tsx +238 -0
- package/src/app/shared/ocean/ifft-stage.wgsl +36 -0
- package/src/app/shared/ocean/initial-spectrum.wgsl +36 -0
- package/src/app/shared/ocean/noise.wgsl +24 -0
- package/src/app/shared/ocean/normal-foam.wgsl +32 -0
- package/src/app/shared/ocean/ocean-colors.ts +11 -0
- package/src/app/shared/ocean/ocean-common.wgsl +15 -0
- package/src/app/shared/ocean/ocean-graph.ts +29 -0
- package/src/app/shared/ocean/particles.wgsl +139 -0
- package/src/app/shared/ocean/present.wgsl +40 -0
- package/src/app/shared/ocean/renderer.spec.ts +100 -0
- package/src/app/shared/ocean/renderer.ts +693 -0
- package/src/app/shared/ocean/spectrum.wgsl +35 -0
- package/src/app/shared/ocean/tuning.ts +131 -0
- package/src/app/shared/ocean/webgpu-support.ts +12 -0
- package/src/app/sharing/AccessRequestApprovalPage.spec.tsx +276 -0
- package/src/app/sharing/AccessRequestApprovalPage.tsx +307 -0
- package/src/app/sharing/AccessRequestsSection.tsx +163 -0
- package/src/app/sharing/ResourceAccessScreen.spec.tsx +235 -0
- package/src/app/sharing/ResourceAccessScreen.tsx +331 -0
- package/src/app/sharing/ShareButton.spec.tsx +171 -5
- package/src/app/sharing/ShareButton.tsx +15 -2
- package/src/app/sharing/ShareDialog.spec.tsx +71 -2
- package/src/app/sharing/ShareDialog.tsx +24 -2
- package/src/app/sharing/index.ts +2 -0
- package/src/app/styles/agent-native.css +21 -1
- package/src/app/styles/agent-native.spec.ts +16 -3
- package/src/app/styles/tokens/agent-kit.css +3 -1
- package/src/composer/AgentSuggestionBar.overflow.spec.tsx +277 -0
- package/src/composer/AgentSuggestionBar.tsx +113 -8
- package/src/wgsl-env.d.ts +6 -0
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
} from "@agent-native/core/client/agent-chat";
|
|
47
47
|
import { dispatchAgentChatRunning } from "@agent-native/core/client/agent-chat";
|
|
48
48
|
import {
|
|
49
|
+
fetchAgentEngineConfiguredState,
|
|
49
50
|
useAgentEngineConfigured,
|
|
50
51
|
type AgentEngineConfiguredState,
|
|
51
52
|
} from "@agent-native/core/client/agent-chat";
|
|
@@ -84,6 +85,7 @@ import {
|
|
|
84
85
|
import { cn } from "@agent-native/toolkit/utils";
|
|
85
86
|
import {
|
|
86
87
|
IconAlertTriangle,
|
|
88
|
+
IconLoader2,
|
|
87
89
|
IconMessage,
|
|
88
90
|
IconPlayerStopFilled,
|
|
89
91
|
IconQuote,
|
|
@@ -728,6 +730,11 @@ export const AgentKitAssistantChat = forwardRef<
|
|
|
728
730
|
},
|
|
729
731
|
agents: t("agentChat.activity.agents"),
|
|
730
732
|
tasks: t("agentChat.activity.tasks"),
|
|
733
|
+
toolInput: t("agentChat.tool.input"),
|
|
734
|
+
toolResult: t("agentChat.tool.result"),
|
|
735
|
+
activityValueIdentifierHidden: t("agentChat.tool.identifierHidden"),
|
|
736
|
+
activityValueOmitted: t("agentChat.tool.contentOmitted"),
|
|
737
|
+
activityValueCircular: t("agentChat.tool.circularReference"),
|
|
731
738
|
working: t("agentChat.status.working"),
|
|
732
739
|
workingFor: t("agentChat.status.workingFor", {
|
|
733
740
|
duration: "{{duration}}",
|
|
@@ -1158,27 +1165,61 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
1158
1165
|
tabId: props.tabId,
|
|
1159
1166
|
threadId,
|
|
1160
1167
|
});
|
|
1168
|
+
const [submissionReadiness, setSubmissionReadiness] =
|
|
1169
|
+
useState<AgentEngineConfiguredState | null>(null);
|
|
1170
|
+
const readinessRequestIdRef = useRef(0);
|
|
1171
|
+
const providerReadinessRequestRef = useRef<{
|
|
1172
|
+
requestId: number;
|
|
1173
|
+
promise: Promise<AgentEngineConfiguredState>;
|
|
1174
|
+
} | null>(null);
|
|
1175
|
+
const latestResolvedReadinessRef = useRef<{
|
|
1176
|
+
requestId: number;
|
|
1177
|
+
state: AgentEngineConfiguredState;
|
|
1178
|
+
} | null>(null);
|
|
1179
|
+
const passiveReadinessRef = useRef(readiness.state);
|
|
1180
|
+
const providerReadinessPassRef = useRef<number | null>(null);
|
|
1181
|
+
const latestSubmissionReadinessRef = useRef(readiness.state);
|
|
1182
|
+
useEffect(() => {
|
|
1183
|
+
if (passiveReadinessRef.current !== readiness.state) {
|
|
1184
|
+
const explicitReadinessPassed =
|
|
1185
|
+
providerReadinessPassRef.current === readinessRequestIdRef.current &&
|
|
1186
|
+
latestResolvedReadinessRef.current?.requestId ===
|
|
1187
|
+
readinessRequestIdRef.current &&
|
|
1188
|
+
latestResolvedReadinessRef.current.state === "configured";
|
|
1189
|
+
if (readiness.state === "unavailable" && explicitReadinessPassed) {
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
passiveReadinessRef.current = readiness.state;
|
|
1193
|
+
readinessRequestIdRef.current += 1;
|
|
1194
|
+
providerReadinessRequestRef.current = null;
|
|
1195
|
+
providerReadinessPassRef.current = null;
|
|
1196
|
+
latestSubmissionReadinessRef.current = readiness.state;
|
|
1197
|
+
setSubmissionReadiness(null);
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
if (submissionReadiness === readiness.state) {
|
|
1201
|
+
latestSubmissionReadinessRef.current = readiness.state;
|
|
1202
|
+
setSubmissionReadiness(null);
|
|
1203
|
+
}
|
|
1204
|
+
}, [readiness.state, submissionReadiness]);
|
|
1161
1205
|
const modelCatalogPending =
|
|
1162
1206
|
props.showModelSelector !== false && props.modelListLoading === true;
|
|
1163
1207
|
const modelListUnavailable =
|
|
1164
1208
|
props.showModelSelector !== false && props.modelListError === true;
|
|
1165
|
-
const
|
|
1209
|
+
const effectiveReadiness = submissionReadiness ?? readiness.state;
|
|
1210
|
+
const canChat = !providerChecksEnabled || effectiveReadiness === "configured";
|
|
1166
1211
|
const setupMissing =
|
|
1167
|
-
providerChecksEnabled &&
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
const providerSubmissionPending =
|
|
1179
|
-
!canChat &&
|
|
1180
|
-
!setupMissing &&
|
|
1181
|
-
(providerStatus === "unknown" || providerStatus === "unavailable");
|
|
1212
|
+
providerChecksEnabled && effectiveReadiness === "missing";
|
|
1213
|
+
const providerStatus: AgentEngineConfiguredState = setupMissing
|
|
1214
|
+
? "missing"
|
|
1215
|
+
: modelListUnavailable
|
|
1216
|
+
? "unavailable"
|
|
1217
|
+
: modelCatalogPending
|
|
1218
|
+
? "unknown"
|
|
1219
|
+
: providerChecksEnabled
|
|
1220
|
+
? effectiveReadiness
|
|
1221
|
+
: "configured";
|
|
1222
|
+
const composerPreflightRunActiveRef = useRef<boolean | null>(null);
|
|
1182
1223
|
const retryProviderStatus = useCallback(() => {
|
|
1183
1224
|
window.dispatchEvent(new Event("agent-engine:configured-changed"));
|
|
1184
1225
|
}, []);
|
|
@@ -1365,6 +1406,14 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
1365
1406
|
const bounceSetupCard = useCallback(() => {
|
|
1366
1407
|
if (setupMissing) setSetupBouncePulse((pulse) => pulse + 1);
|
|
1367
1408
|
}, [setupMissing]);
|
|
1409
|
+
const reportMissingProvider = useCallback(() => {
|
|
1410
|
+
bounceSetupCard();
|
|
1411
|
+
window.dispatchEvent(
|
|
1412
|
+
new CustomEvent("agent-chat:missing-api-key", {
|
|
1413
|
+
detail: { tabId: props.tabId, threadId },
|
|
1414
|
+
}),
|
|
1415
|
+
);
|
|
1416
|
+
}, [bounceSetupCard, props.tabId, threadId]);
|
|
1368
1417
|
const lastCustomRunningStateRef = useRef<{
|
|
1369
1418
|
custom: boolean;
|
|
1370
1419
|
isRunning: boolean;
|
|
@@ -1849,71 +1898,139 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
1849
1898
|
return () => window.clearInterval(interval);
|
|
1850
1899
|
}, [isRunning]);
|
|
1851
1900
|
|
|
1852
|
-
const
|
|
1853
|
-
if (
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
new CustomEvent("agent-chat:missing-api-key", {
|
|
1864
|
-
detail: { tabId: props.tabId, threadId },
|
|
1865
|
-
}),
|
|
1866
|
-
);
|
|
1867
|
-
}
|
|
1868
|
-
return null;
|
|
1901
|
+
const refreshProviderReadiness = useCallback(async () => {
|
|
1902
|
+
if (!providerChecksEnabled) return "configured";
|
|
1903
|
+
let request = providerReadinessRequestRef.current;
|
|
1904
|
+
if (!request || request.requestId !== readinessRequestIdRef.current) {
|
|
1905
|
+
const requestId = ++readinessRequestIdRef.current;
|
|
1906
|
+
providerReadinessPassRef.current = null;
|
|
1907
|
+
request = {
|
|
1908
|
+
requestId,
|
|
1909
|
+
promise: fetchAgentEngineConfiguredState(true, { fresh: true }),
|
|
1910
|
+
};
|
|
1911
|
+
providerReadinessRequestRef.current = request;
|
|
1869
1912
|
}
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1913
|
+
let currentRequest = request;
|
|
1914
|
+
while (true) {
|
|
1915
|
+
const nextReadiness = await currentRequest.promise;
|
|
1916
|
+
if (currentRequest.requestId === readinessRequestIdRef.current) {
|
|
1917
|
+
if (providerReadinessRequestRef.current === currentRequest) {
|
|
1918
|
+
providerReadinessRequestRef.current = null;
|
|
1919
|
+
}
|
|
1920
|
+
latestResolvedReadinessRef.current = {
|
|
1921
|
+
requestId: currentRequest.requestId,
|
|
1922
|
+
state: nextReadiness,
|
|
1923
|
+
};
|
|
1924
|
+
latestSubmissionReadinessRef.current = nextReadiness;
|
|
1925
|
+
setSubmissionReadiness(nextReadiness);
|
|
1926
|
+
return nextReadiness;
|
|
1927
|
+
}
|
|
1928
|
+
const latestRequest = providerReadinessRequestRef.current;
|
|
1929
|
+
if (
|
|
1930
|
+
latestRequest &&
|
|
1931
|
+
latestRequest.requestId === readinessRequestIdRef.current &&
|
|
1932
|
+
latestRequest.requestId > currentRequest.requestId
|
|
1933
|
+
) {
|
|
1934
|
+
currentRequest = latestRequest;
|
|
1935
|
+
continue;
|
|
1936
|
+
}
|
|
1937
|
+
const latestResolved = latestResolvedReadinessRef.current;
|
|
1938
|
+
if (latestResolved?.requestId === readinessRequestIdRef.current) {
|
|
1939
|
+
return latestResolved.state;
|
|
1940
|
+
}
|
|
1941
|
+
return latestSubmissionReadinessRef.current;
|
|
1874
1942
|
}
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1943
|
+
}, [providerChecksEnabled]);
|
|
1944
|
+
|
|
1945
|
+
const acquireSubmission = useCallback(
|
|
1946
|
+
async (useReadinessPass = false) => {
|
|
1947
|
+
const readinessPass = providerReadinessPassRef.current;
|
|
1948
|
+
const hasReadinessPass =
|
|
1949
|
+
useReadinessPass &&
|
|
1950
|
+
readinessPass !== null &&
|
|
1951
|
+
readinessPass === readinessRequestIdRef.current &&
|
|
1952
|
+
latestResolvedReadinessRef.current?.requestId === readinessPass &&
|
|
1953
|
+
latestResolvedReadinessRef.current.state === "configured";
|
|
1954
|
+
if (useReadinessPass) providerReadinessPassRef.current = null;
|
|
1955
|
+
if (
|
|
1956
|
+
isRestoring ||
|
|
1957
|
+
props.composerDisabled ||
|
|
1958
|
+
props.composerSubmissionDisabled
|
|
1959
|
+
)
|
|
1960
|
+
return null;
|
|
1961
|
+
if (providerChecksEnabled) {
|
|
1962
|
+
const currentReadiness = hasReadinessPass
|
|
1963
|
+
? "configured"
|
|
1964
|
+
: await refreshProviderReadiness();
|
|
1965
|
+
if (currentReadiness !== "configured") {
|
|
1966
|
+
if (currentReadiness === "missing") reportMissingProvider();
|
|
1967
|
+
return null;
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
if (history) {
|
|
1971
|
+
const release = await history.beginSubmission();
|
|
1972
|
+
if (!release) return null;
|
|
1973
|
+
return release;
|
|
1974
|
+
}
|
|
1975
|
+
return () => undefined;
|
|
1976
|
+
},
|
|
1977
|
+
[
|
|
1978
|
+
history,
|
|
1979
|
+
isRestoring,
|
|
1980
|
+
props.composerDisabled,
|
|
1981
|
+
props.composerSubmissionDisabled,
|
|
1982
|
+
providerChecksEnabled,
|
|
1983
|
+
refreshProviderReadiness,
|
|
1984
|
+
reportMissingProvider,
|
|
1985
|
+
],
|
|
1986
|
+
);
|
|
1887
1987
|
|
|
1888
1988
|
const beforeSubmit = useCallback(async () => {
|
|
1989
|
+
providerReadinessPassRef.current = null;
|
|
1990
|
+
composerPreflightRunActiveRef.current = null;
|
|
1889
1991
|
if (
|
|
1890
1992
|
isRestoring ||
|
|
1891
1993
|
props.composerDisabled ||
|
|
1892
1994
|
props.composerSubmissionDisabled
|
|
1893
1995
|
)
|
|
1894
1996
|
return false;
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
new CustomEvent("agent-chat:missing-api-key", {
|
|
1900
|
-
detail: { tabId: props.tabId, threadId },
|
|
1901
|
-
}),
|
|
1902
|
-
);
|
|
1903
|
-
}
|
|
1904
|
-
return providerSubmissionPending;
|
|
1997
|
+
const runWasActive = isThreadRunning();
|
|
1998
|
+
if (!providerChecksEnabled) {
|
|
1999
|
+
composerPreflightRunActiveRef.current = runWasActive;
|
|
2000
|
+
return true;
|
|
1905
2001
|
}
|
|
2002
|
+
let currentReadiness = await refreshProviderReadiness();
|
|
2003
|
+
let resolvedReadiness = latestResolvedReadinessRef.current;
|
|
2004
|
+
while (
|
|
2005
|
+
currentReadiness === "configured" &&
|
|
2006
|
+
(!resolvedReadiness ||
|
|
2007
|
+
resolvedReadiness.requestId !== readinessRequestIdRef.current ||
|
|
2008
|
+
resolvedReadiness.state !== "configured")
|
|
2009
|
+
) {
|
|
2010
|
+
currentReadiness = await refreshProviderReadiness();
|
|
2011
|
+
resolvedReadiness = latestResolvedReadinessRef.current;
|
|
2012
|
+
}
|
|
2013
|
+
if (currentReadiness !== "configured") {
|
|
2014
|
+
if (currentReadiness === "missing") reportMissingProvider();
|
|
2015
|
+
return false;
|
|
2016
|
+
}
|
|
2017
|
+
if (
|
|
2018
|
+
!resolvedReadiness ||
|
|
2019
|
+
resolvedReadiness.requestId !== readinessRequestIdRef.current
|
|
2020
|
+
) {
|
|
2021
|
+
return false;
|
|
2022
|
+
}
|
|
2023
|
+
composerPreflightRunActiveRef.current = runWasActive;
|
|
2024
|
+
providerReadinessPassRef.current = resolvedReadiness.requestId;
|
|
1906
2025
|
return true;
|
|
1907
2026
|
}, [
|
|
1908
|
-
bounceSetupCard,
|
|
1909
|
-
canChat,
|
|
1910
2027
|
isRestoring,
|
|
1911
2028
|
props.composerDisabled,
|
|
1912
2029
|
props.composerSubmissionDisabled,
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
2030
|
+
providerChecksEnabled,
|
|
2031
|
+
isThreadRunning,
|
|
2032
|
+
refreshProviderReadiness,
|
|
2033
|
+
reportMissingProvider,
|
|
1917
2034
|
]);
|
|
1918
2035
|
|
|
1919
2036
|
const dispatch = useCallback(
|
|
@@ -2120,13 +2237,7 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2120
2237
|
);
|
|
2121
2238
|
const release = await acquireSubmission();
|
|
2122
2239
|
if (!release) {
|
|
2123
|
-
if (
|
|
2124
|
-
!setupMissing &&
|
|
2125
|
-
(isRestoring ||
|
|
2126
|
-
(providerChecksEnabled &&
|
|
2127
|
-
(readiness.state === "unknown" ||
|
|
2128
|
-
readiness.state === "unavailable")))
|
|
2129
|
-
) {
|
|
2240
|
+
if (isRestoring) {
|
|
2130
2241
|
try {
|
|
2131
2242
|
const selectionHydration = pendingSelectionHydrationRef.current;
|
|
2132
2243
|
await selectionHydration?.promise;
|
|
@@ -2218,9 +2329,10 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2218
2329
|
throw error;
|
|
2219
2330
|
}
|
|
2220
2331
|
}
|
|
2221
|
-
const reason =
|
|
2222
|
-
|
|
2223
|
-
|
|
2332
|
+
const reason =
|
|
2333
|
+
setupMissing || latestSubmissionReadinessRef.current === "missing"
|
|
2334
|
+
? "engine-not-configured"
|
|
2335
|
+
: "submission-unavailable";
|
|
2224
2336
|
reportAgentChatSubmitResult(options.submitMessageId, false, reason);
|
|
2225
2337
|
return { status: "rejected", reason };
|
|
2226
2338
|
}
|
|
@@ -2260,8 +2372,6 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2260
2372
|
isRestoring,
|
|
2261
2373
|
isThreadRunning,
|
|
2262
2374
|
props.tabId,
|
|
2263
|
-
providerChecksEnabled,
|
|
2264
|
-
readiness.state,
|
|
2265
2375
|
setupMissing,
|
|
2266
2376
|
t,
|
|
2267
2377
|
threadId,
|
|
@@ -2276,38 +2386,13 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2276
2386
|
composerOptions: AgentKitSuggestionSubmitOptions,
|
|
2277
2387
|
prepare?: () => Promise<PromptComposerSubmitOptions>,
|
|
2278
2388
|
) => {
|
|
2279
|
-
const runWasActiveAtSubmit =
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
) {
|
|
2287
|
-
try {
|
|
2288
|
-
const preparedOptions = prepare ? await prepare() : composerOptions;
|
|
2289
|
-
const submittedOptions = captureQueuedRunState(
|
|
2290
|
-
preserveQueuedIntent(preparedOptions, composerOptions),
|
|
2291
|
-
runWasActiveAtSubmit,
|
|
2292
|
-
);
|
|
2293
|
-
const result = await submit(
|
|
2294
|
-
text,
|
|
2295
|
-
files,
|
|
2296
|
-
references,
|
|
2297
|
-
submittedOptions,
|
|
2298
|
-
);
|
|
2299
|
-
if (result.status === "rejected") {
|
|
2300
|
-
throw new Error(t("agentChat.recovery.deferredSubmissionFailed"));
|
|
2301
|
-
}
|
|
2302
|
-
} catch (error) {
|
|
2303
|
-
dispatchSetupRequiredEvent(error, props.tabId, threadId);
|
|
2304
|
-
throw error;
|
|
2305
|
-
}
|
|
2306
|
-
} else {
|
|
2307
|
-
throw new Error(t("agentChat.recovery.deferredSubmissionFailed"));
|
|
2308
|
-
}
|
|
2309
|
-
return;
|
|
2310
|
-
}
|
|
2389
|
+
const runWasActiveAtSubmit = providerReadinessPassRef.current
|
|
2390
|
+
? (composerPreflightRunActiveRef.current ?? isThreadRunning())
|
|
2391
|
+
: isThreadRunning();
|
|
2392
|
+
composerPreflightRunActiveRef.current = null;
|
|
2393
|
+
const release = await acquireSubmission(true);
|
|
2394
|
+
if (!release)
|
|
2395
|
+
throw new Error(t("agentChat.recovery.deferredSubmissionFailed"));
|
|
2311
2396
|
try {
|
|
2312
2397
|
const preparedOptions = prepare ? await prepare() : composerOptions;
|
|
2313
2398
|
await dispatch(
|
|
@@ -2333,8 +2418,6 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2333
2418
|
props.composerDisabled,
|
|
2334
2419
|
props.composerSubmissionDisabled,
|
|
2335
2420
|
props.tabId,
|
|
2336
|
-
providerSubmissionPending,
|
|
2337
|
-
submit,
|
|
2338
2421
|
t,
|
|
2339
2422
|
threadId,
|
|
2340
2423
|
],
|
|
@@ -3102,7 +3185,9 @@ function AgentKitTranscript({ children, threadId }: AgentKitRegionRenderProps) {
|
|
|
3102
3185
|
? []
|
|
3103
3186
|
: getAgentKitThreadHandoffMessages(thread, surface.handoffSnapshot);
|
|
3104
3187
|
const guided = useGuidedQuestionFlow({
|
|
3105
|
-
enabled:
|
|
3188
|
+
enabled:
|
|
3189
|
+
surface.props.isActiveComposer !== false &&
|
|
3190
|
+
surface.props.showGuidedQuestions !== false,
|
|
3106
3191
|
stateKey: "guided-questions",
|
|
3107
3192
|
queryKey: ["guided-questions", "agentkit"],
|
|
3108
3193
|
browserTabId: surface.props.browserTabId,
|
|
@@ -3337,7 +3422,8 @@ function AgentKitTranscript({ children, threadId }: AgentKitRegionRenderProps) {
|
|
|
3337
3422
|
</span>
|
|
3338
3423
|
</div>
|
|
3339
3424
|
) : null}
|
|
3340
|
-
{
|
|
3425
|
+
{surface.props.showGuidedQuestions !== false &&
|
|
3426
|
+
guided.questions?.length ? (
|
|
3341
3427
|
<div className="px-3 pb-3">
|
|
3342
3428
|
<GuidedQuestionFlow
|
|
3343
3429
|
questions={guided.questions}
|
|
@@ -3797,8 +3883,9 @@ function AgentKitComposerSurface({
|
|
|
3797
3883
|
}
|
|
3798
3884
|
/>
|
|
3799
3885
|
) : null}
|
|
3800
|
-
{
|
|
3801
|
-
(
|
|
3886
|
+
{!setupMissing &&
|
|
3887
|
+
(modelListUnavailable ||
|
|
3888
|
+
(!canChat && providerStatus !== "configured")) ? (
|
|
3802
3889
|
<GuidedQuestionProviderGate
|
|
3803
3890
|
providerStatus={providerStatus}
|
|
3804
3891
|
modelListUnavailable={modelListUnavailable}
|
|
@@ -3911,7 +3998,23 @@ function AgentKitComposerSurface({
|
|
|
3911
3998
|
{props.composerToolbarSlot}
|
|
3912
3999
|
</>
|
|
3913
4000
|
}
|
|
3914
|
-
extraActionButton={
|
|
4001
|
+
extraActionButton={
|
|
4002
|
+
<>
|
|
4003
|
+
{props.composerExtraActionButton}
|
|
4004
|
+
{composerSubmissionPending ? (
|
|
4005
|
+
<span
|
|
4006
|
+
className="inline-flex items-center gap-1.5 text-xs text-muted-foreground"
|
|
4007
|
+
role="status"
|
|
4008
|
+
aria-live="polite"
|
|
4009
|
+
aria-label={t("agentChat.common.waiting")}
|
|
4010
|
+
data-testid="provider-preflight-pending"
|
|
4011
|
+
>
|
|
4012
|
+
<IconLoader2 className="size-3.5 animate-spin motion-reduce:animate-none" />
|
|
4013
|
+
<span>{t("agentChat.common.waiting")}</span>
|
|
4014
|
+
</span>
|
|
4015
|
+
) : null}
|
|
4016
|
+
</>
|
|
4017
|
+
}
|
|
3915
4018
|
includeDefaultSlashCommands
|
|
3916
4019
|
includeDefaultSlashSkills
|
|
3917
4020
|
onSlashCommand={props.onSlashCommand}
|
|
@@ -266,6 +266,7 @@ export interface AgentSidebarProps {
|
|
|
266
266
|
suppressInlineOpenApp?: AssistantChatProps["suppressInlineOpenApp"];
|
|
267
267
|
composerPlaceholder?: AssistantChatProps["composerPlaceholder"];
|
|
268
268
|
showMissingApiKeySetup?: AssistantChatProps["showMissingApiKeySetup"];
|
|
269
|
+
showGuidedQuestions?: AssistantChatProps["showGuidedQuestions"];
|
|
269
270
|
openOnChatRunning?: boolean;
|
|
270
271
|
onFullscreenRequest?: (threadId?: string) => void;
|
|
271
272
|
onOpenSettings?: (section?: string) => void;
|
|
@@ -340,6 +341,7 @@ export function AgentSidebar({
|
|
|
340
341
|
suppressInlineOpenApp,
|
|
341
342
|
composerPlaceholder,
|
|
342
343
|
showMissingApiKeySetup,
|
|
344
|
+
showGuidedQuestions,
|
|
343
345
|
openOnChatRunning = false,
|
|
344
346
|
onFullscreenRequest,
|
|
345
347
|
onOpenSettings,
|
|
@@ -1158,6 +1160,7 @@ export function AgentSidebar({
|
|
|
1158
1160
|
suppressInlineOpenApp={suppressInlineOpenApp}
|
|
1159
1161
|
composerPlaceholder={composerPlaceholder}
|
|
1160
1162
|
showMissingApiKeySetup={showMissingApiKeySetup}
|
|
1163
|
+
showGuidedQuestions={showGuidedQuestions}
|
|
1161
1164
|
missingApiKeySetupLayout="sidebar"
|
|
1162
1165
|
defaultMode={defaultMode}
|
|
1163
1166
|
onCollapse={() => setOpenPersisted(false)}
|
|
@@ -235,6 +235,29 @@ describe("useGuidedQuestionFlow scoped reads", () => {
|
|
|
235
235
|
expect(result.current().questions?.length).toBe(1);
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
+
it("hides a thread-scoped question until its owner thread is known", async () => {
|
|
239
|
+
vi.stubGlobal(
|
|
240
|
+
"fetch",
|
|
241
|
+
vi.fn(async (input: RequestInfo | URL) =>
|
|
242
|
+
readResponse(String(input), (key) =>
|
|
243
|
+
key === "guided-questions:tab123"
|
|
244
|
+
? JSON.stringify({ ...payload, threadId: "chat-a" })
|
|
245
|
+
: "",
|
|
246
|
+
),
|
|
247
|
+
),
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const result = await renderFlow({
|
|
251
|
+
stateKey: "guided-questions",
|
|
252
|
+
queryKey: ["guided-questions"],
|
|
253
|
+
browserTabId: "tab123",
|
|
254
|
+
refetchInterval: false,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
expect(result.current().questions).toBeNull();
|
|
258
|
+
expect(result.current().payload).toBeNull();
|
|
259
|
+
});
|
|
260
|
+
|
|
238
261
|
it("renders a payload with no threadId in any chat", async () => {
|
|
239
262
|
vi.stubGlobal(
|
|
240
263
|
"fetch",
|
|
@@ -401,6 +424,68 @@ describe("useGuidedQuestionFlow scoped reads", () => {
|
|
|
401
424
|
expect(deleted).toContain("guided-questions:tab123");
|
|
402
425
|
});
|
|
403
426
|
|
|
427
|
+
it("does not restore an in-flight read after clear", async () => {
|
|
428
|
+
let resolveRead: (() => void) | null = null;
|
|
429
|
+
const fetchMock = vi.fn((input: RequestInfo | URL, init?: RequestInit) => {
|
|
430
|
+
const url = String(input);
|
|
431
|
+
if (init?.method === "DELETE") {
|
|
432
|
+
return Promise.resolve(new Response("", { status: 200 }));
|
|
433
|
+
}
|
|
434
|
+
return new Promise<Response>((resolve) => {
|
|
435
|
+
resolveRead = () =>
|
|
436
|
+
resolve(
|
|
437
|
+
readResponse(url, (key) =>
|
|
438
|
+
key === "guided-questions" ? JSON.stringify(payload) : "",
|
|
439
|
+
),
|
|
440
|
+
);
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
444
|
+
|
|
445
|
+
const client = new QueryClient({
|
|
446
|
+
defaultOptions: { queries: { retry: false } },
|
|
447
|
+
});
|
|
448
|
+
let latest: HookResult | null = null;
|
|
449
|
+
function Harness() {
|
|
450
|
+
const flow = useGuidedQuestionFlow({
|
|
451
|
+
providerStatusChecksEnabled: false,
|
|
452
|
+
stateKey: "guided-questions",
|
|
453
|
+
queryKey: ["guided-questions"],
|
|
454
|
+
refetchInterval: false,
|
|
455
|
+
});
|
|
456
|
+
latest = flow;
|
|
457
|
+
return flow.questions ? (
|
|
458
|
+
<GuidedQuestionFlow
|
|
459
|
+
questions={flow.questions}
|
|
460
|
+
onSubmit={() => {}}
|
|
461
|
+
onSkip={() => {}}
|
|
462
|
+
/>
|
|
463
|
+
) : null;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
await act(async () => {
|
|
467
|
+
root.render(
|
|
468
|
+
<QueryClientProvider client={client}>
|
|
469
|
+
<Harness />
|
|
470
|
+
</QueryClientProvider>,
|
|
471
|
+
);
|
|
472
|
+
await Promise.resolve();
|
|
473
|
+
});
|
|
474
|
+
for (let i = 0; i < 20 && !resolveRead; i += 1) await flush();
|
|
475
|
+
expect(resolveRead).toEqual(expect.any(Function));
|
|
476
|
+
|
|
477
|
+
await act(async () => {
|
|
478
|
+
latest!.clear();
|
|
479
|
+
expect(latest!.questions).toBeNull();
|
|
480
|
+
resolveRead!();
|
|
481
|
+
await Promise.resolve();
|
|
482
|
+
});
|
|
483
|
+
await flush();
|
|
484
|
+
|
|
485
|
+
expect(latest!.questions).toBeNull();
|
|
486
|
+
expect(container.textContent).not.toContain("Which range?");
|
|
487
|
+
});
|
|
488
|
+
|
|
404
489
|
// The agent ids every question it asks `q1`, so an answer that travels as
|
|
405
490
|
// `q1: 7d` only means something while the turn that asked it survives
|
|
406
491
|
// history trimming alongside it. When it did not, the agent re-asked the
|
|
@@ -1095,10 +1095,12 @@ function payloadBelongsToThread(
|
|
|
1095
1095
|
payload: GuidedQuestionPayload,
|
|
1096
1096
|
threadId: string | undefined,
|
|
1097
1097
|
): boolean {
|
|
1098
|
+
const requestedThread = threadId?.trim();
|
|
1098
1099
|
const asker =
|
|
1099
1100
|
typeof payload.threadId === "string" ? payload.threadId.trim() : "";
|
|
1100
1101
|
if (!asker) return true;
|
|
1101
|
-
|
|
1102
|
+
if (!requestedThread) return false;
|
|
1103
|
+
return asker === requestedThread;
|
|
1102
1104
|
}
|
|
1103
1105
|
|
|
1104
1106
|
export function useGuidedQuestionFlow({
|
|
@@ -1119,6 +1121,7 @@ export function useGuidedQuestionFlow({
|
|
|
1119
1121
|
}: UseGuidedQuestionFlowOptions = {}) {
|
|
1120
1122
|
const queryClient = useQueryClient();
|
|
1121
1123
|
const [payload, setPayload] = useState<GuidedQuestionPayload | null>(null);
|
|
1124
|
+
const queryGenerationRef = useRef(0);
|
|
1122
1125
|
const normalizedBrowserTabId = useMemo(
|
|
1123
1126
|
() => normalizeBrowserTabId(browserTabId),
|
|
1124
1127
|
[browserTabId],
|
|
@@ -1154,6 +1157,7 @@ export function useGuidedQuestionFlow({
|
|
|
1154
1157
|
queryKey: resolvedQueryKey,
|
|
1155
1158
|
enabled,
|
|
1156
1159
|
queryFn: async () => {
|
|
1160
|
+
const queryGeneration = queryGenerationRef.current;
|
|
1157
1161
|
const read = async (key: string) => {
|
|
1158
1162
|
const parsed = await readClientAppState<GuidedQuestionPayload>(
|
|
1159
1163
|
key,
|
|
@@ -1163,10 +1167,11 @@ export function useGuidedQuestionFlow({
|
|
|
1163
1167
|
}
|
|
1164
1168
|
return null;
|
|
1165
1169
|
};
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
);
|
|
1170
|
+
const scopedPayload = normalizedBrowserTabId
|
|
1171
|
+
? await read(scopedKey)
|
|
1172
|
+
: null;
|
|
1173
|
+
const result = scopedPayload ?? (await read(stateKey));
|
|
1174
|
+
return queryGeneration === queryGenerationRef.current ? result : null;
|
|
1170
1175
|
},
|
|
1171
1176
|
refetchInterval: resolvedRefetchInterval,
|
|
1172
1177
|
structuralSharing: false,
|
|
@@ -1221,6 +1226,8 @@ export function useGuidedQuestionFlow({
|
|
|
1221
1226
|
const submissionInFlightRef = useRef(false);
|
|
1222
1227
|
|
|
1223
1228
|
const clear = useCallback(() => {
|
|
1229
|
+
// A read already in flight may return the submitted question after clear.
|
|
1230
|
+
queryGenerationRef.current += 1;
|
|
1224
1231
|
setPayload(null);
|
|
1225
1232
|
queryClient.setQueryData(resolvedQueryKey, null);
|
|
1226
1233
|
const del = (key: string) => deleteClientAppState(key).catch(() => {});
|
|
@@ -353,6 +353,8 @@ export interface AssistantChatProps {
|
|
|
353
353
|
providerStatusChecksEnabled?: boolean;
|
|
354
354
|
/** Replace the built-in transport with an AgentKit-native BYO transport. */
|
|
355
355
|
createTransport?: (context: AssistantChatAdapterContext) => AgentTransport;
|
|
356
|
+
/** Hide the default guided-question card when another host owns its flow. */
|
|
357
|
+
showGuidedQuestions?: boolean;
|
|
356
358
|
/**
|
|
357
359
|
* Bring-your-own agent runtime. When supplied, AssistantChat keeps the
|
|
358
360
|
* standard composer/transcript/tool rendering shell but sends turns through
|