7a463dbe44
# Conflicts: # .agents/notes/implemented/feature/2026-07-17-dedicated-full-screen-tui-front-door.i18n.yaml # docs/architecture.i18n.yaml # docs/cookbook/extension-cookbook.i18n.yaml # docs/cordis-catalog/events.md # docs/cordis-catalog/services.md # docs/core-data-structures/core.i18n.yaml # docs/core-data-structures/core.md # docs/core-data-structures/core.zh.md # docs/core-data-structures/llm-streaming.i18n.yaml # docs/core-data-structures/llm-streaming.md # docs/core-data-structures/llm-streaming.zh.md # docs/core-data-structures/session.i18n.yaml # docs/event-producer-consumer.md # docs/persistence-catalog.md # packages/cordis/tool-cordis/src/api-catalog.ts # packages/core/agent-loop/README.i18n.yaml # packages/core/agent-loop/src/agent.ts # packages/core/agent/README.i18n.yaml # packages/core/session/README.i18n.yaml # packages/core/session/src/types.ts # packages/llm/llm/README.i18n.yaml # packages/llm/llm/README.md # packages/llm/llm/README.zh.md # packages/llm/llm/src/index.ts # packages/llm/llm/tests/service.spec.ts # packages/sdk/sdk-client/README.i18n.yaml # packages/sdk/sdk-protocol/README.i18n.yaml # packages/sdk/sdk-protocol/README.md # packages/sdk/sdk-protocol/README.zh.md # packages/subagent/subagent-dsh-sdk/README.i18n.yaml # packages/ui/jsonrpc/README.i18n.yaml # packages/ui/jsonrpc/README.md # packages/ui/jsonrpc/README.zh.md # packages/ui/tui/src/index.ts # python/sdk/README.i18n.yaml # scripts/gen-cordis-catalog.ts
77 lines
4.7 KiB
TypeScript
77 lines
4.7 KiB
TypeScript
/**
|
|
* events domain zod schemas: MuxFrame / HostFrame unions (discriminatedUnion('type')).
|
|
* A frame is the payload slot of the ServerRequest full form; the SessionEvent inside
|
|
* a session/event frame reuses sessions.schema's strict-envelope + wide-data passthrough branch.
|
|
*/
|
|
|
|
import { z } from 'zod'
|
|
import type { AskUserQuestionItem } from '@deepseek-ai/dsh-user-interaction/types'
|
|
import type { HostFrame, MuxFrame } from './events.ts'
|
|
import type { Wire } from './rpc.schema.ts'
|
|
import { rpcErrorSchema, rpcIdSchema } from './rpc.schema.ts'
|
|
import { approvalRequestIdSchema } from './approvals.schema.ts'
|
|
import {
|
|
contentBlockSchema, messageIdSchema, sessionEventSchema, sessionIdSchema, toolEventViewSchema,
|
|
} from './sessions.schema.ts'
|
|
import { workspaceIdSchema, workspaceViewSchema } from './workspace.schema.ts'
|
|
|
|
/** Question shape validated strictly against core dsh-user-interaction. */
|
|
export const askUserQuestionItemSchema = z.object({
|
|
id: z.string(),
|
|
question: z.string(),
|
|
header: z.string().optional(),
|
|
detail: z.string().optional(),
|
|
options: z.array(z.object({ label: z.string(), description: z.string().optional() })).optional(),
|
|
multiSelect: z.boolean().optional(),
|
|
// Presentation intent: a tagged union on the wire, so an unknown tag is a
|
|
// rejected frame rather than a silently generic render.
|
|
intent: z.discriminatedUnion('kind', [
|
|
z.object({ kind: z.literal('plan-review'), approve: z.string() }),
|
|
]).optional(),
|
|
}) satisfies z.ZodType<Wire<AskUserQuestionItem>>
|
|
|
|
/** User-message envelope carried by queue baselines. */
|
|
const userMessageSchema = z.object({
|
|
id: messageIdSchema,
|
|
role: z.literal('user'),
|
|
content: z.array(contentBlockSchema),
|
|
source: z.looseObject({ kind: z.string() }),
|
|
})
|
|
|
|
/** MuxFrame union (payload slot of a mux-stream ServerRequest). */
|
|
export const muxFrameSchema = z.discriminatedUnion('type', [
|
|
z.object({ type: z.literal('session/event'), sessionId: sessionIdSchema, event: sessionEventSchema, view: toolEventViewSchema.optional() }),
|
|
z.object({ type: z.literal('session/subscribed'), sessionId: sessionIdSchema, lastSeq: z.number().int() }),
|
|
z.object({ type: z.literal('approval/requested'), sessionId: sessionIdSchema, approvalId: approvalRequestIdSchema, toolName: z.string(), callId: z.string().optional(), reason: z.string().optional() }),
|
|
z.object({ type: z.literal('approval/resolved'), sessionId: sessionIdSchema, approvalId: approvalRequestIdSchema, outcome: z.union([z.literal('allowed-once'), z.literal('rejected'), z.literal('cancelled'), z.literal('unavailable')]) }),
|
|
// Non-empty by wire contract: the user-interaction service rejects empty
|
|
// batches at ask() (EMPTY_QUESTIONS), so an empty frame is host breakage
|
|
// and must fail loud here, not reach the composer.
|
|
z.object({ type: z.literal('question/requested'), sessionId: sessionIdSchema, questions: z.array(askUserQuestionItemSchema).min(1) }),
|
|
z.object({ type: z.literal('question/resolved'), sessionId: sessionIdSchema, questionRpcId: rpcIdSchema, outcome: z.union([z.literal('answered'), z.literal('cancelled')]) }),
|
|
z.object({
|
|
type: z.literal('session/queue'),
|
|
sessionId: sessionIdSchema,
|
|
items: z.array(userMessageSchema),
|
|
}),
|
|
// value stays wide: it already passed its unit's own schema on the host,
|
|
// and deep-validating here would import every domain's schema into the carrier.
|
|
z.object({ type: z.literal('session/projection'), sessionId: sessionIdSchema, key: z.string().min(1), value: z.unknown(), seq: z.number().int().nonnegative() }),
|
|
z.object({ type: z.literal('stream/error'), error: rpcErrorSchema }),
|
|
]) as unknown as z.ZodType<MuxFrame>
|
|
|
|
/** HostFrame union (payload slot of a host-stream ServerRequest). */
|
|
export const hostFrameSchema = z.discriminatedUnion('type', [
|
|
z.object({ type: z.literal('host/session-added'), sessionId: sessionIdSchema, blank: z.boolean(), parentSessionId: sessionIdSchema.optional(), cwd: z.string().optional() }),
|
|
z.object({ type: z.literal('host/session-removed'), sessionId: sessionIdSchema }),
|
|
z.object({ type: z.literal('host/session-status'), sessionId: sessionIdSchema, running: z.boolean() }),
|
|
z.object({ type: z.literal('host/agent-error'), sessionId: sessionIdSchema, message: z.string() }),
|
|
z.object({ type: z.literal('host/workspace-changed'), workspace: workspaceViewSchema }),
|
|
z.object({ type: z.literal('host/workspace-removed'), workspaceId: workspaceIdSchema }),
|
|
z.object({ type: z.literal('host/commands-changed') }),
|
|
z.object({ type: z.literal('host/settings-changed'), ns: z.string() }),
|
|
z.object({ type: z.literal('host/credentials-changed'), ref: z.string() }),
|
|
z.object({ type: z.literal('host/models-changed') }),
|
|
z.object({ type: z.literal('stream/error'), error: rpcErrorSchema }),
|
|
]) as unknown as z.ZodType<HostFrame>
|