Merge branch 'codex/tool-json-schema-dsl' into codex/canonical-tool-output
# Conflicts: # docs/config-catalog.md # docs/persistence-catalog.md # examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl # examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl # packages/cordis/tool-cordis/src/api-catalog.ts # packages/core/agent-loop/tests/contract-regressions.spec.ts # packages/ui/acp/src/index.ts # packages/ui/tui/src/index.ts
This commit is contained in:
@@ -11,9 +11,9 @@ import { isAbsolute } from 'node:path'
|
||||
import { deepFreeze } from '@deepseek-ai/dsh-llm'
|
||||
import { scopeOf, scopeTarget } from '@deepseek-ai/dsh-scope'
|
||||
import type { Scoped } from '@deepseek-ai/dsh-scope'
|
||||
import type { Message } from '@deepseek-ai/dsh-llm'
|
||||
import type { ContentBlock, Message } from '@deepseek-ai/dsh-llm'
|
||||
import { SESSION_FORMAT_VERSION, SessionId } from './types.ts'
|
||||
import type { CreateSessionOptions, EpochHeader, OutOfBandSessionEventType, SessionEvent, SessionEventMap, SessionEventType, SessionHeader, SurfaceIntent, SurfaceEventType, TurnTrigger } from './types.ts'
|
||||
import type { CreateSessionOptions, EpochHeader, OutOfBandSessionEventType, PromptMessageData, SessionEvent, SessionEventMap, SessionEventType, SessionHeader, SurfaceIntent, SurfaceEventType, TurnTrigger } from './types.ts'
|
||||
import { snapshotJsonValue } from './json.ts'
|
||||
import { SurfaceManager } from './surface.ts'
|
||||
import type { SessionSurface } from './surface.ts'
|
||||
@@ -29,6 +29,15 @@ export type { SessionSurface, SurfaceFoldReplacement, SurfaceFoldResult } from '
|
||||
export { foldSurface, isSurfaceEvent, isSurfaceEligibleType } from './surface.ts'
|
||||
export { canonicalHeader, foldRequestHeader, headerEquals } from './request-header.ts'
|
||||
|
||||
/**
|
||||
* Return the human-facing prompt blocks from a durable prompt message.
|
||||
* @param data - ordinary or steering prompt event data.
|
||||
* @returns the effective direct prompt, excluding baked prefix context.
|
||||
*/
|
||||
export function displayPromptContent(data: PromptMessageData): ContentBlock[] {
|
||||
return data.envelope?.displayContent ?? data.content
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the latest closed message-triggered turn, excluding injection and
|
||||
* plugin-owned zero-step turns.
|
||||
@@ -523,9 +532,11 @@ export class Session {
|
||||
// trace/replay data.
|
||||
|
||||
switch (event.type) {
|
||||
// Injected context and mid-turn steering project identically to a user
|
||||
// prompt: content verbatim, in user role. context's `source`/`meta` and
|
||||
// steering's `turn` are log-only and do not reach the model. Do NOT
|
||||
// Injected context, ordinary prompts, and mid-turn steering project
|
||||
// identically in user role: the event's model-facing content stays
|
||||
// verbatim. A prompt envelope is model-hidden display metadata; its
|
||||
// prefix bytes are already present in content. context's `source`/`meta`
|
||||
// and steering's `turn` are also log-only. Do NOT
|
||||
// re-add per-type framing (e.g. `<context>`/`<steering>`) here: framing is
|
||||
// caller-owned — a producer bakes it into `content`, as workspace-context
|
||||
// does with `<system-reminder>` — or, if reintroduced, must be driven by
|
||||
|
||||
@@ -180,6 +180,37 @@ export interface EpochHeader {
|
||||
*/
|
||||
export type RequestHeaderReason = 'initial' | 'resume' | 'change'
|
||||
|
||||
/** Durable model-hidden annotation for one context baked into a prompt message. */
|
||||
export interface PromptPrefixContext {
|
||||
/** Producer provenance retained for transcript presentation and inspection. */
|
||||
source: MessageSource
|
||||
/** Opaque JSON state retained in the session event but hidden from the model. */
|
||||
meta?: JsonValue
|
||||
}
|
||||
|
||||
/**
|
||||
* Human-facing view of a prompt whose exact model content includes prefixed
|
||||
* context. `content` on the owning event remains the reconstructable model
|
||||
* input; this envelope prevents transcript, title, and re-reference consumers
|
||||
* from treating the baked context as direct human text.
|
||||
*/
|
||||
export interface PromptMessageEnvelope {
|
||||
/** Effective user prompt after interception rewrites, without baked context. */
|
||||
displayContent: ContentBlock[]
|
||||
/** Ordered descriptors for contexts already baked into the event content. */
|
||||
prefixContexts: PromptPrefixContext[]
|
||||
}
|
||||
|
||||
/** Shared payload for ordinary and steering prompt messages. */
|
||||
export interface PromptMessageData {
|
||||
/** Exact model-facing blocks, including any baked prompt-prefix contexts. */
|
||||
content: ContentBlock[]
|
||||
/** Producer provenance for the direct prompt. */
|
||||
source: MessageSource
|
||||
/** Present only when prompt-prefix contexts were baked into `content`. */
|
||||
envelope?: PromptMessageEnvelope
|
||||
}
|
||||
|
||||
/**
|
||||
* The merge-extensible, append-only source of truth for an agent interaction.
|
||||
* Message history is derived from this log. Every event is lossless JSON and
|
||||
@@ -206,7 +237,7 @@ export interface SessionEventMap {
|
||||
/** Closes step `step` of turn `turn`. */
|
||||
'step/end': { turn: number; step: number }
|
||||
/** A user-visible prompt (the queued message claimed for this turn). */
|
||||
'user/message': { content: ContentBlock[]; source: MessageSource }
|
||||
'user/message': PromptMessageData
|
||||
/**
|
||||
* Durable record of a prompt veto and its reason. It is log-only: the blocked
|
||||
* prompt never enters the model-visible surface, and its turn runs zero steps.
|
||||
@@ -264,7 +295,7 @@ export interface SessionEventMap {
|
||||
meta?: JsonValue
|
||||
}
|
||||
/** Steering content injected between steps of a running turn. */
|
||||
'steering/message': { turn: number; content: ContentBlock[]; source: MessageSource }
|
||||
'steering/message': PromptMessageData & { turn: number }
|
||||
/** Whole-list snapshot; latest write wins on replay. Log-only UI state; never derived history. */
|
||||
'todo/write': { todos: TodoItem[] }
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user