@springbrand/chat-client 0.1.3-alpha.40 → 0.1.3-alpha.41
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@springbrand/chat-client",
|
|
3
|
-
"version": "0.1.3-alpha.
|
|
3
|
+
"version": "0.1.3-alpha.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
".": "./src/index.ts"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
+
"@cloudflare/ai-chat": "^0.11.0",
|
|
16
17
|
"agents": "^0.22.0",
|
|
17
18
|
"ai": "^7.0.0",
|
|
18
19
|
"react": "^19.0.0"
|
|
@@ -21,11 +22,12 @@
|
|
|
21
22
|
"nanoid": "^5.1.16"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
|
-
"@
|
|
25
|
-
"@types/react
|
|
26
|
-
"react-dom": "^19.2.
|
|
25
|
+
"@cloudflare/ai-chat": "0.11.0",
|
|
26
|
+
"@types/react": "^19.2.18",
|
|
27
|
+
"@types/react-dom": "^19.2.5",
|
|
28
|
+
"react-dom": "^19.2.8",
|
|
27
29
|
"typescript": "^7.0.2",
|
|
28
|
-
"@springbrand/agent-runtime": "0.2.0-alpha.
|
|
30
|
+
"@springbrand/agent-runtime": "0.2.0-alpha.53"
|
|
29
31
|
},
|
|
30
32
|
"scripts": {
|
|
31
33
|
"typecheck": "tsc --noEmit"
|
|
@@ -15,7 +15,7 @@ import type { ChatStatus, FileUIPart, UIMessage } from "ai";
|
|
|
15
15
|
import type { AgentToolRunState } from "agents";
|
|
16
16
|
import type { AgentConnectionError } from "agents/client";
|
|
17
17
|
import { MessageType } from "agents/chat";
|
|
18
|
-
import { getAgentMessages, useAgentChat } from "
|
|
18
|
+
import { getAgentMessages, useAgentChat } from "@cloudflare/ai-chat/react";
|
|
19
19
|
import { useAgent, useAgentToolEvents } from "agents/react";
|
|
20
20
|
import {
|
|
21
21
|
type ApprovalDecision,
|
|
@@ -95,6 +95,7 @@ type ChatQueuedSubmission = {
|
|
|
95
95
|
type ChatTurn = {
|
|
96
96
|
activeSubmissionId?: string;
|
|
97
97
|
activeRequestId?: string;
|
|
98
|
+
activeMessageId?: string;
|
|
98
99
|
recoveryAttempt?: number;
|
|
99
100
|
recoveryMax?: number;
|
|
100
101
|
recoveryReason?: "no_meaningful_model_progress" | "transient_model_error";
|
|
@@ -382,10 +383,12 @@ function queuedPreview(message: ChatMessage): string {
|
|
|
382
383
|
function loadInitialMessages(
|
|
383
384
|
url: string | undefined,
|
|
384
385
|
credentials: RequestCredentials | undefined,
|
|
386
|
+
view: "hydration" | "full" = "hydration",
|
|
385
387
|
): Promise<ChatMessage[]> {
|
|
386
388
|
if (!url) return Promise.resolve([]);
|
|
387
389
|
const messagesUrl = new URL(url);
|
|
388
390
|
messagesUrl.pathname = `${messagesUrl.pathname.replace(/\/$/, "")}/get-messages`;
|
|
391
|
+
if (view === "hydration") messagesUrl.searchParams.set("view", "hydration");
|
|
389
392
|
return getAgentMessages({
|
|
390
393
|
url: messagesUrl.toString(),
|
|
391
394
|
...(credentials === undefined ? {} : { credentials }),
|
|
@@ -449,7 +452,6 @@ export function useUniversalAgentChat(): ChatRuntime {
|
|
|
449
452
|
? {}
|
|
450
453
|
: { credentials: connection.credentials }),
|
|
451
454
|
syncMessagesToServer: false,
|
|
452
|
-
throttle: 16,
|
|
453
455
|
});
|
|
454
456
|
// The SDK keeps its advisory recovery flag until terminal settlement; a
|
|
455
457
|
// live server stream proves the recovered Turn is executing again.
|
|
@@ -481,14 +483,15 @@ export function useUniversalAgentChat(): ChatRuntime {
|
|
|
481
483
|
const runtimeErrorMessage = runtimeError instanceof Error
|
|
482
484
|
? runtimeError.message
|
|
483
485
|
: runtimeError;
|
|
484
|
-
const presentationError =
|
|
485
|
-
latestMessage?.metadata?.error === runtimeErrorMessage
|
|
486
|
+
const presentationError = isServerStreaming || isRecovering ||
|
|
487
|
+
(latestTurnStatus === "error" && latestMessage?.metadata?.error === runtimeErrorMessage)
|
|
486
488
|
? undefined
|
|
487
489
|
: runtimeError;
|
|
488
490
|
// RPC admissions bypass useChat's request lifecycle. Project the durable
|
|
489
491
|
// Turn here so presentation stays correct without a second send path.
|
|
490
|
-
const authoritativeStatus =
|
|
491
|
-
|
|
492
|
+
const authoritativeStatus = isServerStreaming
|
|
493
|
+
? "streaming"
|
|
494
|
+
: normalizedSdkStatus === "ready" &&
|
|
492
495
|
!isRecovering &&
|
|
493
496
|
approvals?.length === 0 &&
|
|
494
497
|
authoritativeTurn?.activeSubmissionId
|
|
@@ -506,6 +509,35 @@ export function useUniversalAgentChat(): ChatRuntime {
|
|
|
506
509
|
: authoritativeStatus;
|
|
507
510
|
const messagesRef = useRef(messages);
|
|
508
511
|
messagesRef.current = messages;
|
|
512
|
+
const replayFallbackMessageIdRef = useRef<string | undefined>(undefined);
|
|
513
|
+
useEffect(() => {
|
|
514
|
+
const activeMessageId = facetState?.turn?.activeMessageId;
|
|
515
|
+
if (
|
|
516
|
+
!activeMessageId ||
|
|
517
|
+
sdkStatus !== "error" ||
|
|
518
|
+
sdkIsRecovering ||
|
|
519
|
+
isServerStreaming ||
|
|
520
|
+
replayFallbackMessageIdRef.current === activeMessageId
|
|
521
|
+
) return;
|
|
522
|
+
const url = chatAgent.getHttpUrl();
|
|
523
|
+
if (!url) return;
|
|
524
|
+
replayFallbackMessageIdRef.current = activeMessageId;
|
|
525
|
+
void loadInitialMessages(url, connection.credentials, "full")
|
|
526
|
+
.then((snapshot) => {
|
|
527
|
+
setMessages(snapshot);
|
|
528
|
+
clearError();
|
|
529
|
+
})
|
|
530
|
+
.catch(() => undefined);
|
|
531
|
+
}, [
|
|
532
|
+
chatAgent,
|
|
533
|
+
clearError,
|
|
534
|
+
connection.credentials,
|
|
535
|
+
facetState?.turn?.activeMessageId,
|
|
536
|
+
isServerStreaming,
|
|
537
|
+
sdkIsRecovering,
|
|
538
|
+
sdkStatus,
|
|
539
|
+
setMessages,
|
|
540
|
+
]);
|
|
509
541
|
const turnTimingRef = useRef<ChatTurnTiming | null>(null);
|
|
510
542
|
|
|
511
543
|
useEffect(() => {
|