Merge remote-tracking branch 'origin/master' into simpl-b2-app-boot

# Conflicts:
#	docs/rfc/README.md
This commit is contained in:
Tianyi Cui
2026-07-04 22:58:26 +08:00
92 changed files with 967 additions and 646 deletions

View File

@@ -69,8 +69,8 @@ export function turnEndToStopReason(reason: TurnEndReason): StopReason {
* client as message content. Today only `text` maps; `resource_link` is an
* ACP prompt-only input rendered into text by {@link acpPromptToText};
* `reasoning` is surfaced via `agent_thought_chunk`
* streaming rather than as a message block, and `tool-call`/`tool-result`/
* `image` are handled by the tool-call update path or not advertised.
* streaming rather than as a message block, and `tool-call`/`tool-result`
* are handled by the tool-call update path.
*/
export function harnessBlockToAcpContent(block: ContentBlock): AcpContentBlock | undefined {
switch (block.type) {
@@ -78,7 +78,7 @@ export function harnessBlockToAcpContent(block: ContentBlock): AcpContentBlock |
return { type: 'text', text: block.text }
// reasoning → streamed as agent_thought_chunk, not a message block
// tool-call / tool-result → the tool_call / tool_call_update path
// image → not advertised
// plugin-added block types → not surfaced
default:
return undefined
}

View File

@@ -1,4 +1,5 @@
import { describe, expect, it } from 'vitest'
import type { ContentBlock } from '@deepseek-ai/dsh-llm'
import type { TurnEndReason } from '@deepseek-ai/dsh-session'
import type { ContentBlock as AcpContentBlock } from '@agentclientprotocol/sdk'
import {
@@ -33,9 +34,9 @@ describe('harnessBlockToAcpContent', () => {
expect(harnessBlockToAcpContent({ type: 'text', text: 'hi' })).toEqual({ type: 'text', text: 'hi' })
})
it('returns undefined for non-text blocks (reasoning/tool/image)', () => {
it('returns undefined for non-text blocks (reasoning / plugin-added)', () => {
expect(harnessBlockToAcpContent({ type: 'reasoning', text: 'think' })).toBeUndefined()
expect(harnessBlockToAcpContent({ type: 'image', url: 'https://x/y.png', mimeType: 'image/png' })).toBeUndefined()
expect(harnessBlockToAcpContent({ type: 'chart', data: 'x' } as unknown as ContentBlock)).toBeUndefined()
})
})

View File

@@ -91,7 +91,7 @@ describe('streamSessionEventUpdate', () => {
it('drops non-text tool-result content (text-only)', () => {
const update = updatesFor(evt('tool/result', {
turn: 1, step: 1, callId: CallId('c1'),
content: [{ type: 'image', url: 'https://x/y.png' }],
content: [{ type: 'reasoning', text: 'private' }],
isError: false,
}))[0]
expect((update as { content: unknown[] }).content).toEqual([])