refactor(vocab): prune producer-less variants — cache hints, agent source, continuation trigger

The vocabulary maps grow by declaration merging, and the admission policy
stated on TurnEndReasonMap is that a variant lands with its first emitter.
Three declared items had no producer and no consumer:

- CacheHint and the cache?: CacheHint fields on TextBlock/ToolResultBlock:
  nothing constructs a block with cache:, and neither adapter reads .cache —
  DeepSeek prompt caching is automatic (hints map OUT of responses, never IN).
- MessageSourceMap.agent: zero constructors; the subagent backends send the
  parent prompt with no source (logs as user), and the envelope renderer
  interpolates source.kind without routing on it.
- TurnTriggerMap.continuation: the loop structurally cannot emit it —
  continuation is further steps within a turn, never a new turn — and its only
  writer was an llm-replay test fixture that needed any non-message trigger
  (now an injection trigger).

Each variant returns the day it gains a real producer, via the same
merge-extensible maps. Docs updated in the same change: the MessageSourceMap
paste in core.md, the TurnTriggerMap paste in session.md (manifest untouched —
both symbols survive), the content-block vocabulary RFC's cache-hints
consequence line, and the RFC moved to implemented/ and amended to shipped
reality (the image block's own cache field had already left with the
drop-image RFC).
This commit is contained in:
Tianyi Cui
2026-07-04 17:50:50 +08:00
parent 2745879132
commit 3567d000c4
9 changed files with 34 additions and 43 deletions

View File

@@ -91,7 +91,6 @@ export interface CreateSessionOptions {
*/
export interface TurnTriggerMap {
message: { kind: 'message'; source: MessageSource }
continuation: { kind: 'continuation' }
/**
* An out-of-band context injection (`agent.inject()`) made while the agent
* was idle. The loop wraps the injected `context/message` in a one-shot turn

View File

@@ -22,14 +22,10 @@
import type { Branded } from '@deepseek-ai/dsh-brand'
import type { CallId } from './brand.ts'
/** Cache hint attached to a content block (provider-interpreted). */
export type CacheHint = 'ephemeral'
/** Plain text visible to the end user. */
export interface TextBlock {
type: 'text'
text: string
cache?: CacheHint
}
/** Reasoning / thinking content, distinct from visible text. */
@@ -54,7 +50,6 @@ export interface ToolResultBlock {
toolCallId: CallId
content: ContentBlock[]
isError?: boolean
cache?: CacheHint
}
/**
@@ -91,7 +86,6 @@ export interface Message {
export interface MessageSourceMap {
user: { kind: 'user' }
plugin: { kind: 'plugin'; plugin: string }
agent: { kind: 'agent'; agentId: string }
}
export type MessageSource = MessageSourceMap[keyof MessageSourceMap]

View File

@@ -118,7 +118,7 @@ describe('deriveReplayScript', () => {
it('ignores non-assistant/chunk events', () => {
let seq = 1
const events: SessionEvent[] = [
{ type: 'turn/start', seq: seq++, time: 0, data: { turn: 1, trigger: { kind: 'continuation' } } },
{ type: 'turn/start', seq: seq++, time: 0, data: { turn: 1, trigger: { kind: 'injection', source: { kind: 'user' } } } },
...TEXT_CHUNKS.map(c => chunkEvent(seq++, 1, 1, c)),
{ type: 'turn/end', seq: seq++, time: 0, data: { turn: 1, reason: { kind: 'completed' } } },
]