Merge pull request #2205 from deepseek-harness/worktree/preset-plane-fallout-p1

fix(preset): keep the token meter host-plane and name unjoined agents
This commit is contained in:
Yichen Jiang
2026-08-11 14:41:08 +08:00
committed by GitHub
53 changed files with 490 additions and 148 deletions

View File

@@ -129,17 +129,20 @@
# `compact-basic` reads `toolResultPrune` through `ctx.get`, so the pruner must
# share this realm rather than sit outside it.
#
# `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
# plane, and the rows here resolve that one instance. It takes no configuration,
# keys every fold by Session, and owns the context-meter projection units the
# browser reads for every session — behind a realm those units would come and go
# with whichever presets happen to be mounted. What a preset chooses is whether
# its agent compacts at all, which is `compact-basic` below.
- id: compaction
name: cordis:group
group: true
isolate:
tokenMeter: true
compact: true
toolResultPrune: true
config:
- id: token-meter
name: '@deepseek-ai/dsh-token-meter'
- id: compact-basic
name: '@deepseek-ai/dsh-compact-basic'

View File

@@ -110,17 +110,20 @@
# `compact-basic` reads `toolResultPrune` through `ctx.get`, so the pruner must
# share this realm rather than sit outside it.
#
# `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
# plane, and the rows here resolve that one instance. It takes no configuration,
# keys every fold by Session, and owns the context-meter projection units the
# browser reads for every session — behind a realm those units would come and go
# with whichever presets happen to be mounted. What a preset chooses is whether
# its agent compacts at all, which is `compact-basic` below.
- id: compaction
name: cordis:group
group: true
isolate:
tokenMeter: true
compact: true
toolResultPrune: true
config:
- id: token-meter
name: '@deepseek-ai/dsh-token-meter'
- id: compact-basic
name: '@deepseek-ai/dsh-compact-basic'

View File

@@ -49,16 +49,19 @@
# Model capacity comes from routed model metadata; this block states the
# compaction policy explicitly.
#
# `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
# plane, and the row here resolves that one instance. It takes no configuration,
# keys every fold by Session, and owns the context-meter projection units the
# browser reads for every session — behind a realm those units would come and go
# with whichever presets happen to be mounted. What a preset chooses is whether
# its agent compacts at all, which is `compact-basic` below.
- id: compaction
name: cordis:group
group: true
isolate:
tokenMeter: true
compact: true
config:
- id: token-meter
name: '@deepseek-ai/dsh-token-meter'
- id: compact-basic
name: '@deepseek-ai/dsh-compact-basic'
config:

View File

@@ -122,17 +122,20 @@
# `compact-basic` reads `toolResultPrune` through `ctx.get`, so the pruner must
# share this realm rather than sit outside it.
#
# `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
# plane, and the rows here resolve that one instance. It takes no configuration,
# keys every fold by Session, and owns the context-meter projection units the
# browser reads for every session — behind a realm those units would come and go
# with whichever presets happen to be mounted. What a preset chooses is whether
# its agent compacts at all, which is `compact-basic` below.
- id: compaction
name: cordis:group
group: true
isolate:
tokenMeter: true
compact: true
toolResultPrune: true
config:
- id: token-meter
name: '@deepseek-ai/dsh-token-meter'
- id: compact-basic
name: '@deepseek-ai/dsh-compact-basic'

View File

@@ -45,6 +45,7 @@
"@deepseek-ai/dsh-pty-local": "workspace:^",
"@deepseek-ai/dsh-pwsh-local": "workspace:^",
"@deepseek-ai/dsh-pwsh-sandbox": "workspace:^",
"@deepseek-ai/dsh-session-projection": "workspace:^",
"@deepseek-ai/dsh-session-reference": "workspace:^",
"@deepseek-ai/dsh-skill": "workspace:^",
"@deepseek-ai/dsh-skill-local": "workspace:^",

View File

@@ -17,6 +17,9 @@ import { CallId } from '@deepseek-ai/dsh-llm'
import type { BasicCompactService } from '@deepseek-ai/dsh-compact-basic'
import type {} from '@deepseek-ai/dsh-skill'
import type {} from '@deepseek-ai/dsh-tools'
// Type-only: resolves `ctx.get('sessionProjections')` and `ctx.get('tokenMeter')`.
import type {} from '@deepseek-ai/dsh-session-projection'
import type {} from '@deepseek-ai/dsh-token-meter'
const CONFIG_DIR = fileURLToPath(new URL('../config/', import.meta.url))
const REPO_ROOT = fileURLToPath(new URL('../../..', import.meta.url))
@@ -138,6 +141,33 @@ describe('the shipped Web composition', () => {
expect(toolNames(ctx)).toEqual([])
})
it('keeps the token meter and its context-meter projections on the host plane', async () => {
// Read before any preset in this file mounts, which is what makes this an
// ownership assertion rather than a mount-order coincidence: a preset-side
// meter sits behind an `isolate` realm and is invisible to `ctx.get`.
//
// The projection registry is process-wide rather than scope-layered, so a
// preset-side meter would also make the browser's context meter appear for
// a `minimal` session the moment some OTHER session mounted a preset that
// carries one, and vanish entirely in a process that only ever ran
// `minimal`. Host ownership is what makes the meter a per-session fact.
expect(ctx.get('tokenMeter')).toBeDefined()
const projections = ctx.get('sessionProjections')
if (projections === undefined) throw new Error('the Web composition must compose a projection registry')
const handle = await ctx.agents.create({
sessionId: SessionId('preset-minimal-meter'),
setup: agentCtx => ctx.agentPresets.mount(agentCtx, 'minimal').then(() => undefined),
})
try {
// A subset assertion: `tasks`, `goal`, and the rest register into the
// same process-wide table, and this is about the meter's three units.
expect(Object.keys(projections.snapshot(handle.agent.session).values))
.toEqual(expect.arrayContaining(['contextBreakdown', 'contextPressure', 'tokenUsage']))
} finally {
await handle.dispose()
}
})
it('supplies both shipped presets, and only those, from the system root', async () => {
const listed = await ctx.agentPresets.list()

View File

@@ -18,7 +18,6 @@ import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest'
import { createUserMessage } from '@deepseek-ai/dsh-llm'
import type { ContentBlock, Message } from '@deepseek-ai/dsh-llm'
import { deriveEventMessage, SessionId } from '@deepseek-ai/dsh-session'
import type {} from '@deepseek-ai/dsh-agent-presets'
import type { SessionEvent } from '@deepseek-ai/dsh-session'
import type { TokenMeterService } from '@deepseek-ai/dsh-token-meter'
import { join } from 'node:path'
@@ -195,21 +194,11 @@ describe('web e2e: seeded history renders through cold resume', () => {
if (MODE !== 'record') {
const raw = await readFile(SEED, 'utf8')
expect(fixtureUserPrompts(raw), 'seed fixture must carry exactly the drive prompt').toEqual([PROMPT])
// The meter belongs to an agent's preset, not to the process — token
// accounting is per session. It is used here as a pure pricing function
// over fixture content, so a throwaway composition is enough to reach one.
const priced = await scaffold.ctx.agents.create({
sessionId: SessionId('seeded-history-pricing'),
setup: agentCtx => scaffold.ctx.agentPresets.mount(agentCtx).then(() => undefined),
})
let realizedWithCompaction: string
try {
const meter = scaffold.ctx.agentPresets.serviceFor(priced.agent, 'tokenMeter')
if (meter === undefined) throw new Error('seeded-history requires the composed token meter')
realizedWithCompaction = withCompaction(realizeSeedFixture(scaffold, raw, SEED_ID), meter)
} finally {
await priced.dispose()
}
// The meter is host-plane — it takes no configuration and keys every
// fold by Session — so pricing fixture content needs no agent at all.
const meter = scaffold.ctx.get('tokenMeter')
if (meter === undefined) throw new Error('seeded-history requires the host token meter')
const realizedWithCompaction = withCompaction(realizeSeedFixture(scaffold, raw, SEED_ID), meter)
await seedSession(scaffold, realizedWithCompaction, SEED_ID)
}
browser = await chromium.launch()