-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathPreviewView.tsx
More file actions
140 lines (123 loc) · 4.19 KB
/
Copy pathPreviewView.tsx
File metadata and controls
140 lines (123 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { useCallback, useEffect, useRef, useState } from 'react';
import { AgentMessage } from './agent/AgentMessage.js';
import { AgentSettings } from './agent/AgentSettings.js';
import { useAgent } from './agent/use-agent.js';
import { ChatInput } from './chat/ChatInput.js';
import { BackendLogDrawer } from './preview/BackendLogPane.js';
import { PreviewPanel } from './preview/PreviewPanel.js';
import { clearSubmissionLog } from './preview/insurance-backend.js';
import { INSURANCE_FLOW_PROMPT } from './preview/insurance-flow-prompt.js';
import { useInsuranceFlow } from './preview/use-insurance-flow.js';
import { usePreviewAutoplay } from './preview/use-preview-autoplay.js';
import { usePreviewValidation } from './preview/use-preview-validation.js';
function countToolUseBlocks(turns: ReturnType<typeof useAgent>['turns']): number {
let count = 0;
for (const turn of turns) {
if (turn.role !== 'assistant') continue;
for (const block of turn.blocks) if (block.type === 'tool_use') count++;
}
return count;
}
export function PreviewView() {
const {
turns,
isGenerating,
error,
input,
setInput,
config,
updateConfig,
send,
sendText,
sendHidden,
stop,
clear,
inputRef,
} = useAgent({ flowPrompt: INSURANCE_FLOW_PROMPT, useAuthorSubAgent: true });
const [selectedBlockId, setSelectedBlockId] = useState<string | null>(null);
const previewState = usePreviewValidation({
turns,
selectedBlockId,
agentConfig: config,
});
const insuranceFlow = useInsuranceFlow({
currentStore: previewState.store,
sendHidden,
isGenerating,
});
// Snap back to the latest step whenever a new tool_use block appears so
// the user doesn't get stuck viewing the previous step.
const prevToolUseCountRef = useRef(0);
useEffect(() => {
const count = countToolUseBlocks(turns);
if (count > prevToolUseCountRef.current) setSelectedBlockId(null);
prevToolUseCountRef.current = count;
}, [turns]);
const chatEndRef = useRef<HTMLDivElement>(null);
const prevCountRef = useRef(turns.length);
useEffect(() => {
if (turns.length > prevCountRef.current) {
chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}
prevCountRef.current = turns.length;
}, [turns]);
const handleClear = useCallback(() => {
clear();
setSelectedBlockId(null);
clearSubmissionLog();
insuranceFlow.reset();
}, [clear, insuranceFlow]);
// Auto-play the full claim flow hands-free (kickoff message → fill & submit
// each step form). Mirrors the scripted demo in the Agent Chat view.
const { isPlaying, play } = usePreviewAutoplay({
previewState,
isGenerating,
sendText,
setInput,
reset: handleClear,
});
return (
<div className="preview-layout">
<div className="preview-chat">
<AgentSettings config={config} onUpdate={updateConfig} />
<div className="chat-messages">
{turns.length === 0 && (
<div className="chat-empty">
<p className="chat-empty-title">Insurance Claim Demo</p>
<p className="chat-empty-hint">
Ask the agent to start a new insurance claim. It will walk you through name &
birthday, claim details, bank account, and a final confirmation — each step rendered
live in the preview pane on the right.
</p>
</div>
)}
{turns.map((turn) => (
<AgentMessage
key={turn.id}
turn={turn}
compactToolUse
activeToolUseId={previewState.blockId}
onSelectToolUse={setSelectedBlockId}
/>
))}
{error && <div className="chat-error">{error}</div>}
<div ref={chatEndRef} />
</div>
<ChatInput
value={input}
onChange={setInput}
onSend={send}
onStop={stop}
onClear={handleClear}
isGenerating={isGenerating}
hasMessages={turns.length > 0}
inputRef={inputRef}
onPlayDemo={play}
isPlaying={isPlaying}
/>
</div>
<PreviewPanel state={previewState} />
<BackendLogDrawer />
</div>
);
}