fix(web): 会话进度行时长从本轮开始算到结论正文,不再显示 0 秒(FIX-9)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
41a39f3cc8
commit
c5987a9db3
3 files changed
+74
-12
No files matched your search
@@ -54,6 +54,7 @@ import {
|
||||
activitySummary,
|
||||
authDenial,
|
||||
buildConversation,
|
||||
type ConvBlock,
|
||||
callCounts,
|
||||
callCountText,
|
||||
capabilityTitle,
|
||||
@@ -261,10 +262,16 @@ export function StepSummary({
|
||||
activity,
|
||||
running,
|
||||
auditByCall,
|
||||
since,
|
||||
until,
|
||||
}: {
|
||||
activity: ActivityItem[];
|
||||
running: boolean;
|
||||
auditByCall?: Map<string, InvocationAudit>;
|
||||
/** 这一轮开始的时间(会话开始 / 用户消息);只给回合里的第一段 */
|
||||
since?: string | null;
|
||||
/** 结论正文开始的时间 */
|
||||
until?: string | null;
|
||||
}) {
|
||||
const id = useId();
|
||||
const [open, setOpen] = useState(false);
|
||||
@@ -273,7 +280,7 @@ export function StepSummary({
|
||||
const done = activitySummary(calls.filter((c) => c.status !== "running"));
|
||||
const denied = calls.filter(isDenied).length;
|
||||
const failed = calls.filter((c) => c.status === "failed" && !isDenied(c)).length;
|
||||
const span = activitySpan(activity);
|
||||
const span = activitySpan(activity, { since, until });
|
||||
const counted = running ? "" : callCountText(callCounts(calls), "调用");
|
||||
const thinking = activity.some((a) => a.kind === "thinking");
|
||||
const head = current
|
||||
@@ -510,12 +517,12 @@ export function AgentConversation({
|
||||
return (
|
||||
<div className="flex flex-col gap-5 px-1 py-2">
|
||||
<UserMessage text={run.goal} tag={isProposeFirst(run) ? "先给方案" : undefined} />
|
||||
{blocks.map((b) =>
|
||||
{blocks.map((b, bi) =>
|
||||
b.kind === "user" ? (
|
||||
<UserMessage key={b.key} text={b.text} note={b.pending ? "已送达,等待智能体读取" : undefined} animateIn />
|
||||
) : (
|
||||
<section key={b.key} aria-label="智能体回合" className="flex w-full min-w-0 flex-col items-start gap-2">
|
||||
{b.parts.map((p) => {
|
||||
{b.parts.map((p, pi) => {
|
||||
const fresh = freshKeys.has(p.key.slice(1)) || freshKeys.has(p.key);
|
||||
switch (p.kind) {
|
||||
case "segment": {
|
||||
@@ -525,7 +532,13 @@ export function AgentConversation({
|
||||
return (
|
||||
<div key={p.key} className="flex w-full min-w-0 flex-col gap-1.5">
|
||||
{p.activity.length ? (
|
||||
<StepSummary activity={p.activity} running={running || thinkingNow} auditByCall={auditByCall} />
|
||||
<StepSummary
|
||||
activity={p.activity}
|
||||
running={running || thinkingNow}
|
||||
auditByCall={auditByCall}
|
||||
since={pi === 0 ? turnSince(blocks, bi, run) : null}
|
||||
until={p.body[0]?.at ?? null}
|
||||
/>
|
||||
) : null}
|
||||
{p.body.map((t) => {
|
||||
const streaming = streamingText && t.key === lastKey;
|
||||
@@ -586,6 +599,13 @@ export function AgentConversation({
|
||||
);
|
||||
}
|
||||
|
||||
/** 回合开始的时间:前一条用户消息;第一轮是会话开始 */
|
||||
function turnSince(blocks: ConvBlock[], index: number, run: AgentRunView): string | null {
|
||||
const prev = blocks[index - 1];
|
||||
if (prev?.kind === "user") return prev.at;
|
||||
return index === 0 ? run.startedAt : null;
|
||||
}
|
||||
|
||||
// ── 实际结果 ──
|
||||
|
||||
type ResultFact = { text: string; to?: string; tone?: "warning" };
|
||||
|
||||
Reference in new issue
Block a user