mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-12 04:01:20 +00:00
Four rounds of structural rework on the conversation surface, converging on one registration model for the whole client: - Review fixes: open() leaves the inject factory (SessionsService owns the semantic); ConversationService mounts via ctx.plugin(); the bespoke view registry retires into the 'conversation.view' list slot. - Ring alignment: createChatView factory retired (components get everything through checkable shares at the register call site); the hand-rolled t/i18n threading is deleted wholesale — a future framework-level i18n will supply t as a standard prop keyed by slot name, so no interim manual channel. - Toolview dissolution: ToolViewRegistry / ToolViewResolver / ToolViewOutlet / ctx.toolviews retire. Tool rows are entries of the 'conversation.chat.toolview' keyed slot (scope: session) declared by the chat entry; ToolRowOwnerProps is the unified owner payload; GenericToolCard becomes the call-site fallback; registrants are plain plugins (inject ['slots','conversation'] as the load-order seam); session-dimension dispatch moves into components (useSessions reads parentId); trajectory/waterfall gain same-shape slots the day they render tool rows (RendersCheck rejects empty declarations). Slot names mirror the composition path (<domain>.<entry>.<hole>). - Staging follows current: cell()/binding() are pure resolution (render-safe); the constructor subscribes to the list store and followCurrent opens the event window when the current session changes — staging IS the open signal, business verbs are the timing, React render/commit is decoupled from window lifecycle. A masked current (projection gap) keeps the stage untouched so deferred teardown semantics survive reconnects. Agent Note: .agents/notes/implemented/architecture/ 2026-07-23-toolview-dissolution.md (bilingual pair) records the decision, the four rejected alternatives, and the accepted semantic changes; the web client architecture note and packages/client/AGENTS.md carry the current-state narrative. Verified: typecheck 0, duplication 0 clones (478 files), full coverage run 6190 passed with zero threshold errors, knip 0, doc-sync 24/24, client aggregate tsc 0, render-count checks (one commit per chunk, zero row re-renders under streaming) green.
31 lines
1.2 KiB
TypeScript
31 lines
1.2 KiB
TypeScript
// TrajectoryView: P-I placeholder body for the trajectory tab — span stats
|
|
// header over a per-turn span list with node-count weights (no timing data
|
|
// exists yet; deviation ledger #3 defers real rendering to P-III).
|
|
|
|
import { useMemo } from 'react'
|
|
import type { ConvViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
|
import { deriveSpans } from './spans.ts'
|
|
import { TrajectoryStatsHeader } from './TrajectoryStatsHeader.tsx'
|
|
import css from './views.module.css'
|
|
|
|
export function TrajectoryView({ useSession }: ConvViewProps) {
|
|
const nodes = useSession((s) => s.nodes)
|
|
const spans = useMemo(() => deriveSpans(nodes), [nodes])
|
|
if (spans.length === 0) return <div className={css.root}><p className={css.empty}>暂无轨迹数据</p></div>
|
|
return (
|
|
<>
|
|
<TrajectoryStatsHeader useSession={useSession} />
|
|
<div className={css.root}>
|
|
{spans.map((span) => (
|
|
<div key={span.turn} className={css.row}>
|
|
<span className={css.turnTag}>turn {span.turn}</span>
|
|
<span className={css.meta}>
|
|
{span.steps} steps · {span.calls} calls · {span.nodes} nodes
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</>
|
|
)
|
|
}
|