Skip to content

Commit a5d1efa

Browse files
committed
chore(release): prepare v1.0.4-beta.2
1 parent 91b79b0 commit a5d1efa

5 files changed

Lines changed: 40 additions & 38 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## v1.0.4-beta.2 (2026-04-27)
4+
- Preserved interleaved reasoning output so mixed reasoning and answer streams stay in the correct order
5+
- Updated the Markstream renderer to the stable 0.0.13 release for more reliable Markdown streaming
6+
- Improved chat message transitions, sidebar updates, and side panel rendering performance
7+
- Fixed RTK and built-in knowledge configuration status handling across MCP tool setup flows
8+
- 保留交错 reasoning 输出顺序,确保 reasoning 与正文混合流式内容按预期展示
9+
- 将 Markstream 渲染器更新到稳定版 0.0.13,提升 Markdown 流式渲染可靠性
10+
- 优化聊天消息动效、侧边栏更新与侧边面板渲染性能
11+
- 修复 RTK 与内置知识库配置状态处理,完善 MCP 工具配置流程
12+
313
## v1.0.4-beta.1 (2026-04-25)
414
- Improved remote control media delivery across Discord, Feishu, QQ Bot, Telegram, and WeChat iLink, including block streaming and file handling
515
- Fixed ACP working directory propagation for remote executions so agent commands run in the intended workspace

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "DeepChat",
3-
"version": "1.0.4-beta.1",
3+
"version": "1.0.4-beta.2",
44
"description": "DeepChat,一个简单易用的 Agent 客户端",
55
"main": "./out/main/index.js",
66
"author": "ThinkInAIXYZ",

test/main/presenter/YoBrowserPresenter.test.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,15 @@ describe('YoBrowserPresenter', () => {
233233
}
234234
}
235235

236-
it('does not start session navigation before the renderer reports a stable host', async () => {
236+
it('starts session navigation immediately and resolves after dom-ready', async () => {
237237
const { presenter, windows, getSessionWebContents } = await setupPresenter()
238238
windows.set(1, new MockBrowserWindow(1))
239239

240240
const loadPromise = presenter.loadUrl('session-a', 'https://example.com')
241241
await Promise.resolve()
242242

243243
const webContents = getSessionWebContents('session-a')
244-
expect(webContents?.loadURL).not.toHaveBeenCalled()
244+
expect(webContents?.loadURL).toHaveBeenCalledWith('https://example.com')
245245

246246
await presenter.attachSessionBrowser('session-a', 1)
247247
await presenter.updateSessionBrowserBounds(
@@ -253,14 +253,12 @@ describe('YoBrowserPresenter', () => {
253253
await vi.advanceTimersByTimeAsync(130)
254254
await Promise.resolve()
255255

256-
expect(webContents?.loadURL).toHaveBeenCalledWith('https://example.com')
257-
258256
webContents?.emitDomReady()
259257
await loadPromise
260258
webContents?.finishLoad()
261259
})
262260

263-
it('resolves loadUrl only after host-ready and the first dom-ready', async () => {
261+
it('resolves loadUrl only after the first dom-ready', async () => {
264262
const { presenter, windows, getSessionWebContents } = await setupPresenter()
265263
windows.set(1, new MockBrowserWindow(1))
266264

@@ -277,7 +275,6 @@ describe('YoBrowserPresenter', () => {
277275
{ x: 10, y: 20, width: 300, height: 400 },
278276
true
279277
)
280-
await vi.advanceTimersByTimeAsync(130)
281278
await Promise.resolve()
282279

283280
expect(settled).toBe(false)
@@ -290,13 +287,13 @@ describe('YoBrowserPresenter', () => {
290287
webContents?.finishLoad()
291288
})
292289

293-
it('returns a clear error when session host-ready never arrives', async () => {
290+
it('returns a clear error when dom-ready never arrives', async () => {
294291
const { presenter, windows } = await setupPresenter()
295292
windows.set(1, new MockBrowserWindow(1))
296293

297-
const loadPromise = presenter.loadUrl('session-a', 'https://example.com')
294+
const loadPromise = presenter.loadUrl('session-a', 'https://example.com', 5000)
298295
const rejection = expect(loadPromise).rejects.toThrow(
299-
'Session browser host 1 did not become ready within 5000ms'
296+
'Timed out waiting for dom-ready: https://example.com'
300297
)
301298
await vi.advanceTimersByTimeAsync(5050)
302299
await rejection

test/renderer/components/App.startup.test.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,14 @@ const mountApp = async (options?: {
9292
activeSessionId: hasActiveSession ? 'session-1' : null,
9393
startNewConversation: vi.fn().mockResolvedValue(undefined),
9494
closeSession: vi.fn().mockResolvedValue(undefined),
95-
selectSession: vi.fn()
95+
selectSession: vi.fn(),
96+
fetchSessions: vi.fn().mockResolvedValue(undefined)
97+
}
98+
const providerStore = {
99+
ensureInitialized: vi.fn().mockResolvedValue(undefined)
100+
}
101+
const modelStore = {
102+
initialize: vi.fn().mockResolvedValue(undefined)
96103
}
97104
const toast = vi.fn(() => ({ dismiss: vi.fn() }))
98105
const ipcOn = vi.fn()
@@ -224,6 +231,12 @@ const mountApp = async (options?: {
224231
closeDialog: vi.fn()
225232
})
226233
}))
234+
vi.doMock('@/stores/providerStore', () => ({
235+
useProviderStore: () => providerStore
236+
}))
237+
vi.doMock('@/stores/modelStore', () => ({
238+
useModelStore: () => modelStore
239+
}))
227240
vi.doMock('@/lib/storeInitializer', () => ({
228241
initAppStores: vi.fn(),
229242
useMcpInstallDeeplinkHandler: () => ({

test/renderer/components/ProviderModelList.test.ts

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ const InputStub = defineComponent({
3434
'<input :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" />'
3535
})
3636

37-
const DynamicScrollerStub = defineComponent({
38-
name: 'DynamicScrollerStub',
37+
const RecycleScrollerStub = defineComponent({
38+
name: 'RecycleScrollerStub',
3939
props: {
4040
items: {
4141
type: Array,
@@ -46,29 +46,6 @@ const DynamicScrollerStub = defineComponent({
4646
'<div><slot v-for="(item, index) in items" :key="item.id" :item="item" :index="index" :active="true" /></div>'
4747
})
4848

49-
const DynamicScrollerItemStub = defineComponent({
50-
name: 'DynamicScrollerItemStub',
51-
props: {
52-
item: {
53-
type: Object,
54-
required: true
55-
},
56-
active: {
57-
type: Boolean,
58-
required: true
59-
},
60-
index: {
61-
type: Number,
62-
required: true
63-
},
64-
sizeDependencies: {
65-
type: Array,
66-
default: () => []
67-
}
68-
},
69-
template: '<div><slot /></div>'
70-
})
71-
7249
const ModelConfigItemStub = defineComponent({
7350
name: 'ModelConfigItemStub',
7451
props: {
@@ -101,7 +78,13 @@ describe('ProviderModelList', () => {
10178
vi.doMock('@/stores/modelStore', () => ({
10279
useModelStore: () => modelStore
10380
}))
81+
vi.doMock('@/stores/uiSettingsStore', () => ({
82+
useUiSettingsStore: () => ({
83+
traceDebugEnabled: false
84+
})
85+
}))
10486
vi.doMock('@vueuse/core', () => ({
87+
useDebounceFn: (fn: (...args: unknown[]) => unknown) => fn,
10588
useElementSize: () => ({ height: ref(48) })
10689
}))
10790
vi.doMock('vue-i18n', () => ({
@@ -177,8 +160,7 @@ describe('ProviderModelList', () => {
177160
Popover: passthrough('Popover'),
178161
PopoverContent: passthrough('PopoverContent'),
179162
PopoverTrigger: passthrough('PopoverTrigger'),
180-
DynamicScroller: DynamicScrollerStub,
181-
DynamicScrollerItem: DynamicScrollerItemStub,
163+
RecycleScroller: RecycleScrollerStub,
182164
AddCustomModelButton: passthrough('AddCustomModelButton'),
183165
ModelConfigItem: ModelConfigItemStub,
184166
Icon: true

0 commit comments

Comments
 (0)