feat: align conversation state, composer and scoped approvals

This commit is contained in:
dot committed 2026-10-21 03:46:53 +09:00
1 parent 771ca540f7
commit 308b98df23
61 files changed
+1701 -292

No files matched your search

+9 -5
View File
@@ -1,9 +1,10 @@
import assert from 'node:assert/strict'
import { useChatStore } from '../src/renderer/src/stores/chat'
import { useSettingsStore } from '../src/renderer/src/stores/settings'
import type { ActiveChatRun, SendResult } from '../src/shared/ipc'
import type { ChatEvent, ChatMessage, ContextUsageSnapshot, SessionMeta, ToolCallRecord } from '../src/shared/types'
const session: SessionMeta = { id: 'session-1', title: 'Regression', createdAt: 1, updatedAt: 1 }
const session: SessionMeta = { id: 'session-1', title: 'Regression', modelId: 'model-profile-1', createdAt: 1, updatedAt: 1 }
function tool(overrides: Partial<ToolCallRecord> = {}): ToolCallRecord {
return {
@@ -73,6 +74,7 @@ function activeRunSnapshot(
}
function resetStore(): void {
useSettingsStore.setState({ models: [{ id: 'model-profile-1', name: 'Fixture', providerId: 'fixture', model: 'fixture', baseUrl: 'http://localhost', hasApiKey: false, keyStorage: 'none' }], selectedModelId: 'model-profile-1' })
useChatStore.setState({
sessions: [session],
currentSessionId: session.id,
@@ -85,7 +87,7 @@ function resetStore(): void {
sendingSessions: [],
running: null,
sending: false,
loading: false,
loading: false, loadError: null,
error: null,
draftContext: {},
draftId: 0
@@ -188,7 +190,7 @@ async function testFailedCreatedSessionIsRemoved(): Promise<void> {
assert.equal(created.id in state.sessionContextWindow, false)
assert.equal(state.sessions.some((item) => item.id === created.id), false)
assert.equal(state.draftId, 7, 'failure recovery must preserve the draft owner id')
assert.deepEqual(state.draftContext, { workspaceId: 'space-draft' }, 'failure recovery must preserve draft context')
assert.deepEqual(state.draftContext, { workspaceId: 'space-draft', modelId: 'model-profile-1' }, 'failure recovery must preserve draft context')
assert.equal(state.sending, false)
assert.match(state.error ?? '', /send rejected after create/)
}
@@ -326,6 +328,8 @@ async function testModelChangePreservesFrozenUsage(): Promise<void> {
assert.deepEqual(useChatStore.getState().sessionUsage[session.id], used,
'a rejected model change must leave the existing usage sample intact')
assert.equal(useChatStore.getState().sessionContextWindow[session.id], 64_000)
window.ycode.session.updateContext = async (_id, patch) => ({ ...session, ...patch })
await useChatStore.getState().selectModel('model-profile-1') // Explicit repair clears the failed request-settings barrier.
}
async function testRevertRestoresBranchUsage(): Promise<void> {
@@ -580,7 +584,7 @@ async function testHydrationBuffersKnownRunAndFiltersByWatermark(): Promise<void
installFakeWindow(async () => sendResult('unused'))
window.ycode.chat.activeRun = async () => active.promise
const selection = useChatStore.getState().selectSession(session.id)
const selection = useChatStore.getState().selectSession(session.id, { reload: true })
useChatStore.getState().applyEvent({
sessionId: session.id,
runId: 'run-watermark',
@@ -648,7 +652,7 @@ async function testTerminalActiveSnapshotDoesNotCreateRunning(): Promise<void> {
if (status === 'error') assistant.error = 'snapshot failed'
window.ycode.chat.activeRun = async () => snapshot
await useChatStore.getState().selectSession(session.id)
await useChatStore.getState().selectSession(session.id, { reload: true })
const state = useChatStore.getState()
assert.equal(state.messages.find((message) => message.id === snapshot.assistantMessageId)?.status, status)