Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`, `verify-translation-pairing --write` for the touched bilingual pairs, `gen-doc-graphs`, and one typert snapshot whose ids embed character offsets. `pnpm run rescope-vendor --check` verifies the result. Renames nine vendored packages (cordis, cosmokit, schemastery and the six @cordisjs plugins) and every reference that resolves them: manifest names and dependency keys, module specifiers including declare-module merges, cordis.yml plugin names, tsconfig paths, every Markdown fence, and `docs/` prose. Directory names, upstream versions, and dependency ranges are unchanged, so vendor/README.md still reads as an upstream snapshot; its manifest table gains an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed at each fork's origin. The tutorial tier follows the rename end to end: its yaml fences named plugins the Loader can no longer resolve, its `ts ignore-check` fences disagreed with the compiled fences beside them, and its prose quoted both. The contracts that told readers to keep upstream names — the root convention and the vendoring cookbook's tree comment and manifest invariant — now say to rescope instead. Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle purity gate now names the vendored libraries a browser bundle inlines, and the files where a bare `cordis` is an agent-preset id keep that product data.
84 lines
2.9 KiB
TypeScript
84 lines
2.9 KiB
TypeScript
import type { Context } from '@deepseek-ai/cordis'
|
|
import type {
|
|
ContextMessageNode, ConversationNodeDefinition, SteeringMessageNode, UserMessageNode,
|
|
} from '@deepseek-ai/dsh-client-runtime/client'
|
|
import {
|
|
contextForm, contextProvenance, isAppendSurfaceEvent, isReplacementSurfaceEvent,
|
|
} from '@deepseek-ai/dsh-client-runtime/client'
|
|
import type { InboxState } from './inbox.ts'
|
|
import { chatNode } from './common.ts'
|
|
|
|
type MessageNode = UserMessageNode | SteeringMessageNode | ContextMessageNode
|
|
|
|
declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
|
interface ChatNodeDataMap {
|
|
/** Ordinary turn-opening user message. */
|
|
user: UserMessageNode
|
|
/** User message admitted into an active turn. */
|
|
steering: SteeringMessageNode
|
|
/** Non-user context injected into model history. */
|
|
context: ContextMessageNode
|
|
}
|
|
}
|
|
|
|
function isCompactionCheckpoint(event: Parameters<ConversationNodeDefinition['match']>[0]): boolean {
|
|
if (event.type !== 'user/message' || !isReplacementSurfaceEvent(event)) return false
|
|
const source = event.data.source
|
|
return source.kind === 'plugin' && source.plugin === 'compact'
|
|
}
|
|
|
|
/** User, steering, and injected-context message classification Definition. */
|
|
export const messageDefinition: ConversationNodeDefinition<MessageNode> = {
|
|
kind: 'input-message',
|
|
match: event => event.type === 'user/message'
|
|
&& isAppendSurfaceEvent(event)
|
|
&& !isCompactionCheckpoint(event)
|
|
? { id: String(event.data.id), role: 'start' }
|
|
: null,
|
|
start: (_context, match, reader) => {
|
|
if (match.event.type !== 'user/message') throw new Error('input-message start requires user/message')
|
|
const event = match.event
|
|
if (event.data.source.kind !== 'user') {
|
|
return {
|
|
kind: 'context',
|
|
seq: event.seq,
|
|
time: event.time,
|
|
content: event.data.content,
|
|
source: event.data.source,
|
|
provenance: contextProvenance(event.data.source),
|
|
form: contextForm(event.data.source),
|
|
}
|
|
}
|
|
const claimed = reader.previous<InboxState>('inbox-next-step')?.state.claimed.has(String(event.data.id)) === true
|
|
return claimed
|
|
? {
|
|
kind: 'steering',
|
|
messageId: event.data.id,
|
|
seq: event.seq,
|
|
time: event.time,
|
|
content: event.data.content,
|
|
source: event.data.source,
|
|
}
|
|
: {
|
|
kind: 'user',
|
|
seq: event.seq,
|
|
time: event.time,
|
|
content: event.data.content,
|
|
source: event.data.source,
|
|
}
|
|
},
|
|
update: context => context.state,
|
|
buildViewNode: (context, target) => {
|
|
if (target !== 'chat' || context.state === undefined) return null
|
|
return chatNode(context, context.state.kind, context.state.seq, context.state)
|
|
},
|
|
}
|
|
|
|
/**
|
|
* Register the user, steering, and injected-context message contribution.
|
|
* @param ctx - owning UI Conversation context.
|
|
*/
|
|
export function registerMessageConversationNode(ctx: Context): void {
|
|
ctx.conversationEvents.register(messageDefinition)
|
|
}
|