import { z } from 'zod' import { heartbeatScopeSchema } from './assistant-contracts' export const supervisionTriggerSchema = z.enum(['manual', 'heartbeat']) export type SupervisionTrigger = z.infer export const supervisionTimeRangeSchema = z .object({ from: z.string().datetime({ offset: true }), to: z.string().datetime({ offset: true }) }) .strict() .refine((value) => Date.parse(value.from) <= Date.parse(value.to), { message: '监督者时间范围无效' }) export const supervisionRunRequestSchema = z .object({ trigger: supervisionTriggerSchema, scope: heartbeatScopeSchema, timeRange: supervisionTimeRangeSchema, // Reviews skip processed, unchanged sources by default. Only an explicit // user re-analysis reads the whole interval again; it never moves progress. reanalyze: z.boolean().optional() }) .strict() export type SupervisionRunRequest = z.infer /** Whether a review reads and advances the shared incremental progress. */ export function isIncrementalReview(request: Pick): boolean { return request.trigger === 'heartbeat' || request.reanalyze !== true } export const supervisionSuggestionKindSchema = z.enum(['open_item', 'conflict', 'convention', 'revision', 'stalled', 'experience']) export type SupervisionSuggestionKind = z.infer export type SupervisionSuggestion = { id: string resultId: string | null heartbeatRunId: string | null scope: SupervisionRunRequest['scope'] kind: SupervisionSuggestionKind title: string detail: string sourceIds: string[] entityId: string | null relationId: string | null taskId: string | null status: 'pending' | 'accepted' | 'dismissed' createdAt: string /** Story the suggestion is about (stalled story, or where an experience may apply). */ storyId?: string | null experienceId?: string | null } export const supervisionSuggestionListRequestSchema = z.object({ status: z.enum(['pending', 'all']).default('pending'), limit: z.number().int().min(1).max(100).default(50), offset: z.number().int().min(0).max(100_000).default(0) }).strict() export const supervisionSuggestionActionSchema = z.object({ id: z.string().uuid(), action: z.enum(['accept', 'dismiss']) }).strict() export type SupervisionSuggestionAction = z.infer export const supervisionSuggestionRetrySchema = z.object({ heartbeatRunId: z.string().min(1).max(256) }).strict() export const supervisionActivityRequestSchema = z.object({ configId: z.string().min(1).max(256).optional(), limit: z.number().int().min(1).max(100).default(50), offset: z.number().int().min(0).max(100_000).default(0) }).strict() export type SupervisionActivityRequest = z.input export type SupervisionActivity = { id: string kind: 'supervision' | 'heartbeat' trigger: 'manual' | 'scheduled' | 'heartbeat' status: 'running' | 'completed' | 'failed' | 'skipped' | 'no_change' | 'paused' | 'cancelled' reviewProgress?: import('./supervision-review-contracts').SupervisionReviewProgress scope: SupervisionRunRequest['scope'] | null startedAt: string completedAt: string | null timeRange: SupervisionRunRequest['timeRange'] | null error: string | null summary: string | null resultId: string | null heartbeatStatus: 'claimed' | 'completed' | 'failed' | 'skipped' | 'no_change' | null supervisionStatus: 'running' | 'completed' | 'failed' | 'no_change' | 'paused' | 'cancelled' | null /** Intervention after an automatic review; null when not applicable. */ suggestionStatus?: 'running' | 'completed' | 'failed' | 'skipped' | null suggestionError?: string | null suggestionCount?: number } export const supervisionEvidenceSchema = z .object({ id: z.string().min(1).max(256), sourceType: z.enum(['conversation', 'task', 'note', 'memory', 'knowledge']), sourceId: z.string().min(1).max(256), title: z.string().max(500), content: z.string().max(8_000), occurredAt: z.string().datetime({ offset: true }), locator: z.record(z.string(), z.unknown()).optional() }) .strict() export type SupervisionEvidence = z.infer const sourceReferenceIdsSchema = z.array(z.string().min(1).max(256)) export const supervisionEventSchema = z .object({ title: z.string().min(1), description: z.string(), occurredAt: z.string().datetime({ offset: true }), eventType: z.enum(['decision', 'change', 'discussion', 'milestone']), entityIds: z.array(z.string().regex(/^[a-zA-Z0-9_-]{1,120}$/)), sourceReferenceIds: sourceReferenceIdsSchema }) .strict() export const supervisionEntitySchema = z .object({ id: z.string().regex(/^[a-zA-Z0-9_-]{1,120}$/), persistedId: z.string().uuid().optional(), label: z.string().min(1), description: z.string(), sourceReferenceIds: sourceReferenceIdsSchema }) .strict() export const supervisionRelationSchema = z .object({ fromEntityId: z.string().regex(/^[a-zA-Z0-9_-]{1,120}$/), toEntityId: z.string().regex(/^[a-zA-Z0-9_-]{1,120}$/), relationType: z.enum(['supports', 'depends-on', 'contrasts', 'related']), reason: z.string(), sourceReferenceIds: sourceReferenceIdsSchema }) .strict() export const supervisionEntityChangeSchema = z.object({ entityId: z.string().regex(/^[a-zA-Z0-9_-]{1,120}$/), changeType: z.enum(['proposed', 'added', 'verified', 'revised']), description: z.string(), sourceReferenceIds: sourceReferenceIdsSchema }).strict() export const supervisionSummaryOutputSchema = z .object({ summary: z.string().min(1), changeDigest: z.string(), openItems: z.array(z.string().min(1)), events: z.array(supervisionEventSchema), entities: z.array(supervisionEntitySchema), entityChanges: z.array(supervisionEntityChangeSchema), relations: z.array(supervisionRelationSchema) }) .strict() export type SupervisionSummaryOutput = z.infer< typeof supervisionSummaryOutputSchema > // Navigation combines saved summaries; it cannot create or replace leaf facts. export const supervisionNavigationOutputSchema = supervisionSummaryOutputSchema.pick({ summary: true, changeDigest: true, openItems: true }).extend({ events: z.array(z.never()).max(0).optional(), entities: z.array(z.never()).max(0).optional(), entityChanges: z.array(z.never()).max(0).optional(), relations: z.array(z.never()).max(0).optional() }).strict() export const supervisionEntityActionSchema = z .object({ resultId: z.string().min(1).optional(), entityId: z.string().regex(/^[a-zA-Z0-9_-]{1,120}$/), action: z.enum(['confirm', 'revise', 'revoke']), label: z.string().trim().min(1).optional(), description: z.string().optional() }) .strict() export const supervisionRelationActionSchema = z .object({ resultId: z.string().min(1).optional(), relationId: z.string().uuid(), action: z.enum(['confirm', 'revoke']) }) .strict() export const supervisionSourceRequestSchema = z .object({ sourceId: z.string().min(1).max(256) }) .strict() export const supervisionContinueContextRequestSchema = z.object({ sourceId: z.string().min(1).max(256), resultId: z.string().min(1).max(256) }).strict() export type SupervisionContinueContextRequest = z.infer export const supervisionContinueRequestSchema = z.object({ conversationId: z.string().min(1).max(128), prompt: z.string().trim().min(1).max(12_000), runtimeSelection: z.unknown().optional(), projectId: z.string().min(1).max(128).optional() }).strict() export type SupervisionContinueRequest = z.infer export const supervisionKnowledgePreviewRequestSchema = z.object({ operation: z.enum(['create-entity', 'update-entity']), libraryId: z.string().uuid(), entityId: z.string().uuid().optional(), label: z.string().trim().min(1).max(120), type: z.string().trim().min(1).max(120), description: z.string().trim().max(2_000), aliases: z.array(z.string().trim().min(1).max(120)).max(50), sourceId: z.string().min(1).max(256) }).strict().superRefine((value, context) => { if (value.operation === 'update-entity' && !value.entityId) { context.addIssue({ code: 'custom', path: ['entityId'], message: 'update-entity requires entityId' }) } }) export type SupervisionKnowledgePreviewRequest = z.infer export const supervisionKnowledgeCommitRequestSchema = z.object({ previewId: z.string().uuid() }).strict() export type SupervisionKnowledgeCommitRequest = z.infer export type SupervisionEntityAction = z.infer export type SupervisionRelationAction = z.infer export const supervisionResultViewSchema = z.object({ runId: z.string().optional(), coverage: z.record(z.string(), z.unknown()).optional(), storyLineId: z.string(), sourceId: z.string().nullable(), id: z.string(), summary: z.string(), changeDigest: z.string(), createdAt: z.string(), scope: heartbeatScopeSchema, timeRange: supervisionTimeRangeSchema, openItems: z.array(z.string()) }) export type SupervisionResultView = z.infer export const supervisionTargetSchema = z.discriminatedUnion('type', [ z.object({ type: z.literal('conversation'), conversationId: z.string().min(1).max(128) }).strict(), z.object({ type: z.literal('task'), taskId: z.string().min(1).max(128) }).strict() ]) export type SupervisionTarget = z.infer export const supervisionOverviewRequestSchema = z.object({ target: supervisionTargetSchema.optional(), resultId: z.string().min(1).max(256).optional() }).strict() export const supervisionGraphRequestSchema = z.object({ resultId: z.string().min(1).optional(), storyLineId: z.string().min(1).optional() }).strict() export type SupervisionGraphRequest = z.infer export const supervisionGraphViewSchema = z.object({ storyLine: z.object({ id: z.string(), scope_json: z.string() }).nullable(), events: z.array(z.object({ id: z.string(), title: z.string(), description: z.string(), occurred_at: z.string(), project_id: z.string().nullish(), started_at: z.string().nullish(), ended_at: z.string().nullish() })), entities: z.array(z.object({ id: z.string(), canonical_label: z.string(), description: z.string(), confirmation_state: z.string() })), relations: z.array(z.object({ id: z.string(), from_entity_id: z.string(), to_entity_id: z.string(), relation_type: z.string(), reason: z.string(), confirmation_state: z.string() })), sources: z.array(z.object({ id: z.string(), title: z.string(), occurred_at: z.string() })), eventEntities: z.array(z.object({ event_id: z.string(), entity_id: z.string() })), eventSources: z.array(z.object({ event_id: z.string(), source_id: z.string() })), attention: z.array(z.object({ start: z.string(), turns: z.number(), characters: z.number() })).optional() }) export type SupervisionAttentionSlot = { start: string; turns: number; characters: number } export type SupervisionGraphView = z.infer