mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix: coverage
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import type { SessionEvent } from '@deepseek-ai/dsh-session/types'
|
||||
import type { ToolEventView } from '@deepseek-ai/dsh-client-connection/client'
|
||||
|
||||
/* oxlint-disable typescript/no-duplicate-type-constituents, typescript/no-redundant-type-constituents --
|
||||
* The unaugmented declaration-merge maps intentionally resolve to never in the Runtime program;
|
||||
* installed business packages supply their concrete keys in consuming Client programs. */
|
||||
|
||||
/** One raw log event plus its optional envelope-level presentation view. */
|
||||
export interface ConversationEventInput {
|
||||
readonly event: SessionEvent
|
||||
|
||||
@@ -712,9 +712,8 @@ export class ConversationNodeAssembler {
|
||||
context: InternalContext,
|
||||
scope: ConversationLocationDataScope,
|
||||
): ConversationLocationData | null {
|
||||
const build = context.definition.buildLocationData
|
||||
if (build === undefined) return null
|
||||
const data = build(contextSnapshot(context), scope)
|
||||
if (context.definition.buildLocationData === undefined) return null
|
||||
const data = context.definition.buildLocationData(contextSnapshot(context), scope)
|
||||
if (data === null) return null
|
||||
if (data.kind !== scope) {
|
||||
throw new Error(
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface ConversationLocationDataChange {
|
||||
class MutableLocationDataStore {
|
||||
private entries = new Map<string, OwnedLocationData>()
|
||||
|
||||
get<Key extends string>(key: Key): unknown {
|
||||
get(key: string): unknown {
|
||||
return this.entries.get(key)?.value
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
||||
'trt.panel': { kind: 'single'; scope: 'root'; owner: { label?: string } }
|
||||
'trt.chat': { kind: 'single'; scope: 'session' }
|
||||
'trt.rows': { kind: 'list'; scope: 'root' }
|
||||
'trt.rows.hole': { kind: 'single'; scope: 'root' }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +420,7 @@ describe('feature mount and disposal', () => {
|
||||
await feature.dispose()
|
||||
await feature.dispose() // idempotent
|
||||
expect(runtime.slots.entries('trt.rows')).toHaveLength(0)
|
||||
expect(runtime.slots.spec('trt.rows.hole' as never)).toBeUndefined()
|
||||
expect(runtime.slots.spec('trt.rows.hole')).toBeUndefined()
|
||||
expect(runtime.ctx.get('feature-service')).toBeUndefined()
|
||||
expect(view.queryByTestId('row')).toBeNull()
|
||||
await runtime.dispose()
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {
|
||||
export interface ChatNodeDataMap {}
|
||||
|
||||
/** Renderer kinds contributed by the currently installed Chat business modules. */
|
||||
export type ChatNodeKind = keyof ChatNodeDataMap & string
|
||||
export type ChatNodeKind = Extract<keyof ChatNodeDataMap, string>
|
||||
|
||||
/** Final Chat Node narrowed to one registered renderer kind and payload. */
|
||||
export type ChatNode<Kind extends ChatNodeKind = ChatNodeKind> = {
|
||||
|
||||
@@ -210,7 +210,7 @@ export interface TurnTailOwnerProps {
|
||||
}
|
||||
|
||||
/** Hook constrained to business data published on the current Chat Node's Turn. */
|
||||
export type UseChatNodeTurnData = <Key extends keyof ConversationTurnDataMap & string>(
|
||||
export type UseChatNodeTurnData = <Key extends Extract<keyof ConversationTurnDataMap, string>>(
|
||||
key: Key,
|
||||
) => Readonly<ConversationTurnDataMap[Key]> | undefined
|
||||
|
||||
|
||||
@@ -78,13 +78,16 @@ class FixtureLocationIndex implements ChatLocationNodeIndex {
|
||||
class FixtureTurnDataStore implements ConversationLocationDataStore<ConversationTurnDataMap> {
|
||||
private readonly values = new Map<string, unknown>()
|
||||
|
||||
get<Key extends keyof ConversationTurnDataMap & string>(
|
||||
get<Key extends Extract<keyof ConversationTurnDataMap, string>>(
|
||||
key: Key,
|
||||
): Readonly<ConversationTurnDataMap[Key]> | undefined {
|
||||
return this.values.get(key) as Readonly<ConversationTurnDataMap[Key]> | undefined
|
||||
}
|
||||
|
||||
set<Key extends keyof ConversationTurnDataMap & string>(key: Key, value: ConversationTurnDataMap[Key]): void {
|
||||
set<Key extends Extract<keyof ConversationTurnDataMap, string>>(
|
||||
key: Key,
|
||||
value: ConversationTurnDataMap[Key],
|
||||
): void {
|
||||
this.values.set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,12 +181,14 @@ function makeHarness(init?: Partial<ConversationSnapshot>) {
|
||||
if (key !== 'conversation.chat.node') return opts?.fallback ?? null
|
||||
const nodeOwner = owner as RoutedChatNodeOwner
|
||||
const nodeKey = opts?.hookContext as string | undefined
|
||||
const useTurnData = ((dataKey: string) => props.useSession((snapshot) => {
|
||||
const location = nodeKey === undefined ? undefined : snapshot.chat.nodes.get(nodeKey)?.location
|
||||
return location?.kind === 'turn' || location?.kind === 'step'
|
||||
? location.turn.data.get(dataKey as never)
|
||||
: undefined
|
||||
})) as UseChatNodeTurnData
|
||||
const useTurnData = ((dataKey: string) => {
|
||||
return props.useSession((snapshot) => {
|
||||
const location = nodeKey === undefined ? undefined : snapshot.chat.nodes.get(nodeKey)?.location
|
||||
return location?.kind === 'turn' || location?.kind === 'step'
|
||||
? location.turn.data.get(dataKey as never)
|
||||
: undefined
|
||||
})
|
||||
}) as UseChatNodeTurnData
|
||||
const nodeProps = <Kind extends ChatNode['kind']>(): ChatNodeViewProps<Kind> => (
|
||||
{ ...props, ...nodeOwner, useTurnData } as unknown as ChatNodeViewProps<Kind>
|
||||
)
|
||||
@@ -226,7 +228,7 @@ function makeHarness(init?: Partial<ConversationSnapshot>) {
|
||||
case 'unknown':
|
||||
return <UnknownNodeView {...nodeProps<'unknown'>()} />
|
||||
case 'tool-call': {
|
||||
const block = (nodeOwner.node.data as { readonly root: ToolCallBlock }).root
|
||||
const block = nodeOwner.node.data.root
|
||||
const toolName = 'kind' in block ? block.call?.name ?? '' : block.name
|
||||
const tool = {
|
||||
callId: block.callId,
|
||||
@@ -843,7 +845,7 @@ describe('ChatView', () => {
|
||||
mounted()
|
||||
return () => { unmounted() }
|
||||
}, [])
|
||||
const root = (node.data as { readonly root: ToolCallBlock }).root
|
||||
const root = node.data.root
|
||||
return (
|
||||
<div data-testid="stateful-tool" data-state={'kind' in root ? 'settled' : 'running'}>
|
||||
{root.callId}
|
||||
|
||||
@@ -34,13 +34,16 @@ afterEach(cleanup)
|
||||
class TestTurnDataStore implements ConversationLocationDataStore<ConversationTurnDataMap> {
|
||||
private readonly values = new Map<string, unknown>()
|
||||
|
||||
get<Key extends keyof ConversationTurnDataMap & string>(
|
||||
get<Key extends Extract<keyof ConversationTurnDataMap, string>>(
|
||||
key: Key,
|
||||
): Readonly<ConversationTurnDataMap[Key]> | undefined {
|
||||
return this.values.get(key) as Readonly<ConversationTurnDataMap[Key]> | undefined
|
||||
}
|
||||
|
||||
set<Key extends keyof ConversationTurnDataMap & string>(key: Key, value: ConversationTurnDataMap[Key]): void {
|
||||
set<Key extends Extract<keyof ConversationTurnDataMap, string>>(
|
||||
key: Key,
|
||||
value: ConversationTurnDataMap[Key],
|
||||
): void {
|
||||
this.values.set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ describe('ui-settings apply', () => {
|
||||
declare(before.slots)
|
||||
await before.ctx.plugin({ inject: [...inject], apply }).await()
|
||||
expect(before.slots.entries('sidebar.settings')[0]!.component).toBe(SettingsRoot)
|
||||
for (const [name, spec] of Object.entries(CHILD_SPECS)) {
|
||||
expect(before.slots.spec(name as never)).toEqual(spec)
|
||||
for (const name of Object.keys(CHILD_SPECS) as Array<keyof typeof CHILD_SPECS>) {
|
||||
expect(before.slots.spec(name)).toEqual(CHILD_SPECS[name])
|
||||
}
|
||||
|
||||
const after = await bench()
|
||||
@@ -120,8 +120,8 @@ describe('ui-settings apply', () => {
|
||||
declare(b.slots)
|
||||
await Promise.resolve()
|
||||
expect(b.slots.entries('sidebar.settings')[0]!.component).toBe(SettingsRoot)
|
||||
for (const [name, spec] of Object.entries(CHILD_SPECS)) {
|
||||
expect(b.slots.spec(name as never)).toEqual(spec)
|
||||
for (const name of Object.keys(CHILD_SPECS) as Array<keyof typeof CHILD_SPECS>) {
|
||||
expect(b.slots.spec(name)).toEqual(CHILD_SPECS[name])
|
||||
}
|
||||
})
|
||||
|
||||
@@ -132,8 +132,8 @@ describe('ui-settings apply', () => {
|
||||
await fiber.await()
|
||||
await fiber.dispose()
|
||||
expect(b.slots.entries('sidebar.settings')).toHaveLength(0)
|
||||
for (const name of Object.keys(CHILD_SPECS)) {
|
||||
expect(b.slots.spec(name as never)).toBeUndefined()
|
||||
for (const name of Object.keys(CHILD_SPECS) as Array<keyof typeof CHILD_SPECS>) {
|
||||
expect(b.slots.spec(name)).toBeUndefined()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -677,7 +677,10 @@ export class SlotCore {
|
||||
>(
|
||||
options: BaseOptions<K, EntryKey, D, H, M, N> & { inject?: undefined },
|
||||
component: C
|
||||
& SlotComponent<ComposedProps<K, NoInfer<EntryKey>, keyof NoInfer<D> & keyof SlotMap & string, HandleOf<NoInfer<H>>, object, NoInfer<M>, NoInfer<N>>>
|
||||
& SlotComponent<ComposedProps<
|
||||
K, NoInfer<EntryKey>, keyof NoInfer<D> & keyof SlotMap & string,
|
||||
HandleOf<NoInfer<H>>, object, NoInfer<M>, NoInfer<N>
|
||||
>>
|
||||
& RendersCheck<C, D>,
|
||||
): () => void
|
||||
/**
|
||||
@@ -702,7 +705,10 @@ export class SlotCore {
|
||||
>(
|
||||
options: BaseOptions<K, EntryKey, D, H, M, N> & { inject: (...args: InjectParams<K, H>) => I },
|
||||
component: C
|
||||
& SlotComponent<ComposedProps<K, NoInfer<EntryKey>, keyof NoInfer<D> & keyof SlotMap & string, HandleOf<NoInfer<H>>, I, NoInfer<M>, NoInfer<N>>>
|
||||
& SlotComponent<ComposedProps<
|
||||
K, NoInfer<EntryKey>, keyof NoInfer<D> & keyof SlotMap & string,
|
||||
HandleOf<NoInfer<H>>, I, NoInfer<M>, NoInfer<N>
|
||||
>>
|
||||
& RendersCheck<C, D>,
|
||||
): () => void
|
||||
/* jscpd:ignore-end */
|
||||
|
||||
@@ -274,7 +274,7 @@ export class WorkspaceAnalyzer {
|
||||
|
||||
constructor(options: WorkspaceAnalyzerOptions) {
|
||||
this.options = {
|
||||
root: resolve(options.root),
|
||||
root: realPath(options.root),
|
||||
hostConfig: options.hostConfig ?? 'tsconfig.host.json',
|
||||
clientConfig: options.clientConfig ?? 'tsconfig.client.json',
|
||||
faces: options.faces ?? ['host', 'client'],
|
||||
|
||||
Reference in New Issue
Block a user