feat(ui): complete trajectory request inspection

This commit is contained in:
_Kerman
2026-07-28 09:53:32 +08:00
parent 4137405cdd
commit b3ea0d987e
32 changed files with 1692 additions and 655 deletions

View File

@@ -125,7 +125,9 @@ export async function compactSurfaceRegion(
}
const shadowedTokenCount = selected.reduce((total, node) => total + node.tokens, 0)
const summarizationInput = buildSummarizationInput(session, shadowedSeqs)
const { summary, provider, model, maxTokens } = await dependencies.summarize(summarizationInput, agent, signal)
const {
summary, rawOutput, provider, model, maxTokens, usage,
} = await dependencies.summarize(summarizationInput, agent, signal)
const currentMeasurement = dependencies.meter.measure(session)
if (!isDeepStrictEqual(currentMeasurement.nodes, lockedMeasurement.nodes)) {
@@ -144,12 +146,14 @@ export async function compactSurfaceRegion(
const summaryEvent = session.append('compact/summary', {
summary,
...rawOutput === undefined ? {} : { rawOutput },
shadowedRange: { start, end },
shadowedSeqs,
shadowedTokenCount,
provider,
model,
...maxTokens === undefined ? {} : { maxTokens },
...usage === undefined ? {} : { usage },
})
session.append('user/message', {
content: framedSummary,
@@ -164,6 +168,7 @@ export async function compactSurfaceRegion(
summarySeq: summaryEvent.seq,
endSeq: endEvent.seq,
summary,
...rawOutput === undefined ? {} : { rawOutput },
shadowedRange: { start, end },
shadowedSeqs,
shadowedTokenCount,

View File

@@ -6,7 +6,9 @@
import type { Context } from 'cordis'
import { BlockAssembler } from '@deepseek-ai/dsh-llm'
import type { ContentBlock, FinishReason, GenerateOptions, Message, ToolSchema } from '@deepseek-ai/dsh-llm'
import type {
ContentBlock, FinishReason, GenerateOptions, Message, TokenUsage, ToolSchema,
} from '@deepseek-ai/dsh-llm'
import type { Agent } from '@deepseek-ai/dsh-agent'
interface SummaryConfig {
@@ -85,9 +87,13 @@ export interface SummarizationInput {
/** Safe summary content plus the exact auxiliary call envelope recorded in provenance. */
export interface SummaryResult {
summary: ContentBlock[]
/** Complete provider output before the text-only summary projection. */
rawOutput?: ContentBlock[]
provider: string
model: string
maxTokens?: number
/** Provider-reported usage for this summarization request. */
usage?: TokenUsage
}
/**
@@ -145,15 +151,18 @@ export async function summarizeWithLlm(
const error = finishError(assembler.finish)
if (error !== undefined) throw error
const summary = textOnly(assembler.message().content)
const rawOutput = assembler.message().content
const summary = textOnly(rawOutput)
if (!summary.some(block => block.text.trim().length > 0)) {
throw new Error('summarization produced no text summary content')
}
return {
summary,
rawOutput,
provider: options.provider,
model: options.model,
maxTokens: config.maxTokens,
...(assembler.usage === undefined ? {} : { usage: assembler.usage }),
}
}

View File

@@ -7,7 +7,7 @@
* @module @deepseek-ai/dsh-compact/types
*/
import type { ContentBlock } from '@deepseek-ai/dsh-llm'
import type { ContentBlock, TokenUsage } from '@deepseek-ai/dsh-llm'
declare module '@deepseek-ai/dsh-session' {
interface SessionEventMap {
@@ -21,6 +21,8 @@ declare module '@deepseek-ai/dsh-session' {
*/
'compact/summary': {
summary: ContentBlock[]
/** Complete provider output before the backend's safe summary projection. */
rawOutput?: ContentBlock[]
shadowedRange: { start: number; end: number }
shadowedSeqs: number[]
shadowedTokenCount: number
@@ -35,6 +37,8 @@ declare module '@deepseek-ai/dsh-session' {
model: string
/** The generation cap the summarize call sent, when one applied. */
maxTokens?: number
/** Provider-reported token usage for the summarization request, when emitted. */
usage?: TokenUsage
}
/** Marks the end of a compaction — log-only, releases the lock. `error` set if summarization failed. */
'compact/end': { turn: number; error?: string }
@@ -51,6 +55,8 @@ export interface CompactionResult {
endSeq: number
/** The summary content blocks produced by the backend. */
summary: ContentBlock[]
/** Complete provider output before the backend's safe summary projection. */
rawOutput?: ContentBlock[]
/**
* The surface-boundary pair that was shadowed: the seqs of the first
* (`start`) and last (`end`) surface nodes of the replaced range. A