fix(client): address tool presentation review
This commit is contained in:
@@ -81,7 +81,7 @@ export const AssistantMarkdown = memo(function AssistantMarkdown({
|
||||
case 'text': return (
|
||||
<MarkdownText key={i} text={block.text} streaming={streaming} codeLabels={codeLabels} />
|
||||
)
|
||||
case 'reasoning': return <ReasoningRow key={i} text={block.text} running={streaming && i === last} />
|
||||
case 'reasoning': return <ReasoningRow key={i} text={block.text} running={streaming && i === last} t={t} />
|
||||
// Grouped into tool rows by ChatView; hasVisible above skips an empty shell.
|
||||
case 'tool-call': return null
|
||||
default: return (
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { useState, type ReactNode } from 'react'
|
||||
import type { ChatViewSlotProps, CommandRowOwnerProps } from '../contract/slots.ts'
|
||||
import { DisclosureRow, IconApiOutline14, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import a11yCss from './accessibility.module.css'
|
||||
import css from './GenericCommandCard.module.css'
|
||||
|
||||
type CommandRowState = 'running' | 'ok' | 'error'
|
||||
@@ -42,6 +43,7 @@ export function GenericCommandCard({ node, t }: GenericCommandCardProps) {
|
||||
const open = expanded && body !== null
|
||||
return (
|
||||
<div className={css.root} data-state={state}>
|
||||
{state === 'error' && <span className={a11yCss.visuallyHidden}>{t('row.failed')}</span>}
|
||||
<DisclosureRow
|
||||
rowClassName={css.row}
|
||||
leadingClassName={css.leading}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/** Assistant reasoning disclosure, independent of Tool-call presentation. */
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { DisclosureRow, IconThinkOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import type { ChatViewSlotProps } from '../contract/slots.ts'
|
||||
import { useThrottledVisualUpdate } from './use-throttled-visual-update.ts'
|
||||
import a11yCss from './accessibility.module.css'
|
||||
import css from './ReasoningRow.module.css'
|
||||
|
||||
function firstLine(text: string): string {
|
||||
@@ -19,9 +21,10 @@ function latestLine(text: string): string {
|
||||
* Render one assistant reasoning block as the Think disclosure row.
|
||||
* @param props.text - complete or streaming reasoning text.
|
||||
* @param props.running - whether this block is the streaming tail.
|
||||
* @param props.t - conversation locale seat for the running status.
|
||||
* @returns the reasoning disclosure.
|
||||
*/
|
||||
export function ReasoningRow({ text, running }: { text: string; running: boolean }) {
|
||||
export function ReasoningRow({ text, running, t }: { text: string; running: boolean; t: ChatViewSlotProps['t'] }) {
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
const summaryRef = useRef<HTMLSpanElement>(null)
|
||||
const summary = running ? latestLine(text) : firstLine(text)
|
||||
@@ -36,6 +39,7 @@ export function ReasoningRow({ text, running }: { text: string; running: boolean
|
||||
|
||||
return (
|
||||
<div className={css.root} data-state={running ? 'running' : 'ok'}>
|
||||
{running && <span className={a11yCss.visuallyHidden}>{t('row.running')}</span>}
|
||||
<DisclosureRow
|
||||
rowClassName={css.row}
|
||||
leadingClassName={css.leading}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
.visuallyHidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -33,6 +33,8 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
||||
/**
|
||||
* One root Tool call at its ordered ChatFlow position. The chat view owns
|
||||
* placement; ui-tool owns root/subcall composition and keyed dispatch.
|
||||
* The filler preserves the call-anchor DOM contract documented by
|
||||
* {@link ToolTreeOwnerProps} for every root and child wrapper.
|
||||
*/
|
||||
'conversation.chat.tool': { kind: 'single'; scope: 'session'; owner: ToolTreeOwnerProps }
|
||||
/**
|
||||
@@ -176,7 +178,12 @@ export interface TurnTailOwnerProps {
|
||||
openFile: (path: string) => void
|
||||
}
|
||||
|
||||
/** Owner currency of the chat view's whole-Tool rendering seat. */
|
||||
/**
|
||||
* Owner currency of the chat view's whole-Tool rendering seat. The filler
|
||||
* wraps every rendered root and child with `data-chat-anchor-key="call:<id>"`
|
||||
* and `data-chat-call-id="<id>"`, plus `data-selected="true"` for the selected
|
||||
* call. ChatView consumes those anchors to restore prepend/paging position.
|
||||
*/
|
||||
export interface ToolTreeOwnerProps {
|
||||
/** Root Tool call identity, stable across running → settled. */
|
||||
callId: CallId
|
||||
|
||||
Reference in New Issue
Block a user