mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
# Conflicts: # .agents/notes/implemented/simplification/2026-07-31-web-ui-no-steer-entry-or-interjection-chrome.i18n.yaml # .agents/notes/implemented/simplification/2026-07-31-web-ui-no-steer-entry-or-interjection-chrome.md # .agents/notes/implemented/simplification/2026-07-31-web-ui-no-steer-entry-or-interjection-chrome.zh.md # apps/web/tests/seeded-history.e2e.ts # apps/web/tests/snapshots/queue-actions/layout.expected.md # docs/core-data-structures/core.i18n.yaml # examples/acp-agent/tests/snapshots/code-mode-workspace-context/session.jsonl # examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl # examples/acp-agent/tests/snapshots/skill-load/session.jsonl # examples/acp-agent/tests/snapshots/workspace-context/session.jsonl # examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl # examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl # examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl # examples/headless-agent/tests/snapshots/pty-tools/session.jsonl # packages/client/runtime/README.i18n.yaml # packages/client/runtime/tests/history-fold.spec.ts # packages/client/ui-conversation/README.i18n.yaml # packages/client/ui-conversation/src/client/chat/MessageItem.tsx # packages/client/ui-conversation/tests/chat-branch-tails.spec.tsx # packages/context/workspace-context/src/index.ts # packages/context/workspace-context/tests/workspace-context.spec.ts # packages/skill/tool-skill/README.i18n.yaml # packages/skill/tool-skill/README.md # packages/skill/tool-skill/README.zh.md # packages/skill/tool-skill/src/index.ts # packages/skill/tool-skill/tests/tool-skill.spec.ts
103 lines
2.6 KiB
TypeScript
103 lines
2.6 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import type {
|
|
ConversationContext, ConversationNode, RequestView,
|
|
} from '@deepseek-ai/dsh-client-runtime/client'
|
|
import {
|
|
deriveTrajectoryContextBranches,
|
|
trajectoryBranchContainsRequest,
|
|
} from '../src/client/context-branches.ts'
|
|
|
|
const checkpoint = {
|
|
kind: 'context',
|
|
seq: 100,
|
|
time: 100,
|
|
content: [],
|
|
source: { kind: 'plugin', plugin: 'compact' },
|
|
provenance: { role: 'inject', label: 'compact' },
|
|
form: null,
|
|
} as ConversationNode
|
|
|
|
const abandoned = {
|
|
kind: 'assistant',
|
|
seq: 20,
|
|
time: 20,
|
|
turn: 1,
|
|
step: 1,
|
|
blocks: [{ kind: 'text', text: 'abandoned' }],
|
|
} as ConversationNode
|
|
|
|
const current = {
|
|
kind: 'user',
|
|
seq: 110,
|
|
time: 110,
|
|
content: [{ type: 'text', text: 'rewound' }],
|
|
source: { kind: 'plugin', plugin: 'rewind' },
|
|
} as ConversationNode
|
|
|
|
function request(
|
|
purpose: RequestView['purpose'],
|
|
startSeq: number,
|
|
resultSeq?: number,
|
|
replacementSeq?: number,
|
|
): RequestView {
|
|
const base = {
|
|
startSeq,
|
|
startedAt: startSeq,
|
|
completedAt: startSeq + 1,
|
|
status: 'complete' as const,
|
|
...(resultSeq === undefined ? {} : { resultSeq }),
|
|
}
|
|
return purpose === 'assistant'
|
|
? { ...base, purpose, turn: 1, step: 1 }
|
|
: {
|
|
...base,
|
|
purpose,
|
|
turn: 1,
|
|
step: 0,
|
|
...(replacementSeq === undefined ? {} : { replacementSeq }),
|
|
}
|
|
}
|
|
|
|
describe('trajectory context branches', () => {
|
|
it('inherits nodes and requests by retained surface position rather than seq cutoff', () => {
|
|
const contexts: ConversationContext[] = [
|
|
{ id: 0, nodes: [checkpoint, abandoned] },
|
|
{
|
|
id: 1,
|
|
parentId: 0,
|
|
origin: 'rewind',
|
|
originSeq: 110,
|
|
nodes: [checkpoint, current],
|
|
},
|
|
]
|
|
const branches = deriveTrajectoryContextBranches(contexts)
|
|
const successor = branches[1]!
|
|
|
|
expect(successor.key).toBe('rewind:110')
|
|
expect(successor.nodes.map(node => node.seq)).toEqual([110])
|
|
expect(trajectoryBranchContainsRequest(
|
|
successor,
|
|
request('assistant', 10, 20),
|
|
)).toBe(false)
|
|
expect(trajectoryBranchContainsRequest(
|
|
successor,
|
|
request('compaction', 90, 95, 100),
|
|
)).toBe(true)
|
|
expect(trajectoryBranchContainsRequest(
|
|
successor,
|
|
request('assistant', 111),
|
|
)).toBe(true)
|
|
})
|
|
|
|
it('keeps branch identity when prepended generations shift local ids', () => {
|
|
const branch = (id: number) => deriveTrajectoryContextBranches([{
|
|
id,
|
|
origin: 'rewind',
|
|
originSeq: 110,
|
|
nodes: [current],
|
|
}])[0]
|
|
|
|
expect(branch(1)?.key).toBe(branch(9)?.key)
|
|
})
|
|
})
|