Merge master into docs/post-v3-release-proofreading

This commit is contained in:
xjt
2026-08-12 20:48:08 +08:00
148 changed files with 2028 additions and 408 deletions

View File

@@ -352,7 +352,7 @@ function fixtureUsage(turn: number, step: number): TokenUsage {
}
}
/** fx-alpha history script: 74 turns (~150+ messages -> 4 pages at PAGE_MESSAGES=50),
/** fx-alpha history script: 75 turns (~150+ messages -> 4 pages at PAGE_MESSAGES=50),
* mixing reasoning blocks / tool call+result / context. */
function buildAlphaLog(): SessionEvent[] {
const events: Record<string, unknown>[] = []
@@ -488,7 +488,7 @@ function buildAlphaLog(): SessionEvent[] {
push({ type: 'step/end', data: { turn, step: 0 } })
push({ type: 'turn/end', data: { turn, reason: { kind: 'completed' } } })
}
// Turn 73: todo_write sample — the TodoRow toolview in the flow plus the
// Turn 74: todo_write sample — the TodoRow toolview in the flow plus the
// todo/write snapshot event feeding the TodoPanel plan strip. Two items are
// in_progress: this fixture chooses the parallel policy, so both surfaces
// must render a parallel plan rather than the first active item alone.
@@ -547,20 +547,35 @@ function buildAlphaLog(): SessionEvent[] {
toolTurn(70, 'web_search', '{"query":"deepseek harness architecture"}', 'Search results for deepseek harness architecture.')
toolTurn(71, 'web_fetch', '{"url":"https://www.deepseek.com/blog/harness-architecture"}', '# Harness architecture\n\nEverything is a plugin.')
// Turn 72: user and assistant images share one durable fixture object.
// The todo turn remains last so its standing projection stays visible.
// Turn 72: max-tokens sample — the provider ends the turn at its output cap
// mid-sentence, so the chat flow must render the turn-max-tokens notice
// instead of ending silently. Ordered before the todo turn for the same
// standing-plan reason the bash turn is.
push({ type: 'turn/start', data: { turn: 72 } })
push({ type: 'user/message', surfaceOp: 'append', data: userMessage(text('问题 72请完整列出全部一百条条目。')) })
push({ type: 'step/start', data: { turn: 72, step: 0 } })
push({
type: 'assistant/message',
surfaceOp: 'append',
data: { turn: 72, step: 0, message: assistantMessage(text('条目 1第一条。条目 2第二条。条目 3这一条写到一半被')) },
})
push({ type: 'step/end', data: { turn: 72, step: 0 } })
push({ type: 'turn/end', data: { turn: 72, reason: { kind: 'max-tokens' } } })
// Turn 73: user and assistant images share one durable fixture object.
// The todo turn remains last so its standing projection stays visible.
push({ type: 'turn/start', data: { turn: 73 } })
push({
type: 'user/message',
surfaceOp: 'append',
data: userMessage([{ type: 'image', attachment: FIXTURE_IMAGE_REF }, ...text('历史用户图片')]),
})
push({ type: 'step/start', data: { turn: 72, step: 0 } })
push({ type: 'step/start', data: { turn: 73, step: 0 } })
push({
type: 'assistant/message',
surfaceOp: 'append',
data: {
turn: 72,
turn: 73,
step: 0,
message: assistantMessage(
[...text('结构化模型图片:'), { type: 'image', attachment: FIXTURE_IMAGE_REF }],
@@ -568,11 +583,11 @@ function buildAlphaLog(): SessionEvent[] {
),
},
})
push({ type: 'step/end', data: { turn: 72, step: 0 } })
push({ type: 'turn/end', data: { turn: 72, reason: { kind: 'completed' } } })
push({ type: 'step/end', data: { turn: 73, step: 0 } })
push({ type: 'turn/end', data: { turn: 73, reason: { kind: 'completed' } } })
const todoArgs = JSON.stringify({ todos: fixtureTodos })
toolTurn(73, 'todo_write', todoArgs, 'Updated todo list: 1 pending, 2 in progress, 1 completed.')
toolTurn(74, 'todo_write', todoArgs, 'Updated todo list: 1 pending, 2 in progress, 1 completed.')
// The real tool appends the snapshot mid-execution — between tool/call and
// tool/result — so the fixture reproduces that exact ordering (the last
// toolTurn events run ... tool/call, tool/result, step/end, turn/end).
@@ -1444,7 +1459,7 @@ function createFixtureWorld(options: FixtureOptions): FixtureWorld {
['my-agent', { trust: 'user', content: "- id: tool-read\n name: '@deepseek-ai/dsh-tool-read'\n" }],
])
let fixtureDefaultPreset = 'standard'
const nextTurn = new Map<SessionId, number>([[sid('fx-alpha'), 74]])
const nextTurn = new Map<SessionId, number>([[sid('fx-alpha'), 75]])
let nextSession = 1
let nextRpc = 1
let attachedSessions = options.empty ? 0 : 1