350 lines
11 KiB
TypeScript
350 lines
11 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
export const EcosystemArtifactTypeSchema = z.enum([
|
|
'transcript',
|
|
'note',
|
|
'memory',
|
|
'plan',
|
|
'routine',
|
|
'habit',
|
|
'habit-checkin',
|
|
'trail-report',
|
|
'route-session',
|
|
'agent-output',
|
|
'document',
|
|
'digest',
|
|
]);
|
|
|
|
export const ArtifactLinkRelationSchema = z.enum([
|
|
'derived-from',
|
|
'summarizes',
|
|
'generated-task',
|
|
'generated-routine',
|
|
'generated-habit',
|
|
'generated-memory',
|
|
'evidence-for',
|
|
'review-of',
|
|
'attached-to',
|
|
]);
|
|
|
|
export const ArtifactLinkSchema = z.object({
|
|
relation: ArtifactLinkRelationSchema,
|
|
targetArtifactId: z.string().min(1),
|
|
});
|
|
|
|
export const ArtifactCreatedBySchema = z.object({
|
|
actorType: z.enum(['user', 'agent', 'system', 'mixed']),
|
|
actorId: z.string().min(1).nullable(),
|
|
});
|
|
|
|
export const ArtifactOwnershipSchema = z.object({
|
|
userId: z.string().min(1),
|
|
orgId: z.string().min(1).nullable().optional(),
|
|
});
|
|
|
|
export const ArtifactVisibilitySchema = z.object({
|
|
scope: z.enum(['private', 'org', 'shared', 'local-only']),
|
|
allowedProducts: z.array(z.string().min(1)).optional(),
|
|
});
|
|
|
|
export const ArtifactLineageStepSchema = z.object({
|
|
stepType: z.string().min(1),
|
|
productId: z.string().min(1),
|
|
actorType: z.enum(['user', 'agent', 'system']),
|
|
timestamp: z.string().datetime(),
|
|
});
|
|
|
|
export const ArtifactProvenanceSchema = z.object({
|
|
originProductId: z.string().min(1),
|
|
originActionId: z.string().min(1).nullable().optional(),
|
|
sessionId: z.string().min(1).nullable().optional(),
|
|
runId: z.string().min(1).nullable().optional(),
|
|
approvalId: z.string().min(1).nullable().optional(),
|
|
correlationId: z.string().min(1).nullable().optional(),
|
|
lineage: z.array(ArtifactLineageStepSchema).min(1),
|
|
});
|
|
|
|
export const BaseArtifactEnvelopeSchema = z.object({
|
|
id: z.string().min(1),
|
|
artifactType: EcosystemArtifactTypeSchema,
|
|
schemaVersion: z.literal(1),
|
|
productId: z.string().min(1),
|
|
sourceSurface: z.string().min(1),
|
|
title: z.string().min(1).nullable(),
|
|
summary: z.string().min(1).nullable(),
|
|
createdAt: z.string().datetime(),
|
|
updatedAt: z.string().datetime(),
|
|
createdBy: ArtifactCreatedBySchema,
|
|
ownership: ArtifactOwnershipSchema,
|
|
visibility: ArtifactVisibilitySchema,
|
|
status: z.string().min(1),
|
|
tags: z.array(z.string().min(1)),
|
|
links: z.array(ArtifactLinkSchema),
|
|
provenance: ArtifactProvenanceSchema,
|
|
payload: z.record(z.unknown()),
|
|
});
|
|
|
|
export const TranscriptPayloadSchema = z.object({
|
|
transcriptText: z.string().min(1),
|
|
transcriptSource: z.enum(['microphone', 'upload', 'call', 'browser', 'other']),
|
|
language: z.string().min(1),
|
|
durationMs: z.number().int().nonnegative(),
|
|
segments: z
|
|
.array(
|
|
z.object({
|
|
speaker: z.string().min(1).nullable().optional(),
|
|
startedAtMs: z.number().int().nonnegative(),
|
|
endedAtMs: z.number().int().nonnegative(),
|
|
text: z.string().min(1),
|
|
})
|
|
)
|
|
.default([]),
|
|
});
|
|
|
|
export const NotePayloadSchema = z.object({
|
|
noteFormat: z.enum(['markdown', 'plain-text', 'rich-text']),
|
|
body: z.string().min(1),
|
|
excerpt: z.string().min(1).nullable().optional(),
|
|
});
|
|
|
|
export const MemoryPayloadSchema = z.object({
|
|
memoryKind: z.enum(['fact', 'preference', 'person', 'project', 'insight', 'todo']),
|
|
text: z.string().min(1),
|
|
confidence: z.number().min(0).max(1),
|
|
sourceArtifactIds: z.array(z.string().min(1)).min(1),
|
|
reviewState: z.enum(['proposed', 'accepted', 'rejected']),
|
|
});
|
|
|
|
export const PlanPayloadSchema = z.object({
|
|
weekOf: z.string().min(1),
|
|
taskCount: z.number().int().nonnegative(),
|
|
scheduledEntryCount: z.number().int().nonnegative(),
|
|
totalScheduledMinutes: z.number().int().nonnegative(),
|
|
entries: z.array(
|
|
z.object({
|
|
taskTitle: z.string().min(1),
|
|
scheduledDate: z.string().min(1),
|
|
startTime: z.string().min(1),
|
|
endTime: z.string().min(1),
|
|
durationMinutes: z.number().int().nonnegative(),
|
|
flowName: z.string().min(1).nullable(),
|
|
zoneName: z.string().min(1).nullable(),
|
|
priority: z.string().min(1),
|
|
})
|
|
),
|
|
});
|
|
|
|
export const RoutinePayloadSchema = z.object({
|
|
routineId: z.string().min(1),
|
|
stepCount: z.number().int().nonnegative(),
|
|
totalDurationMinutes: z.number().nonnegative(),
|
|
status: z.string().min(1),
|
|
isTemplate: z.boolean(),
|
|
category: z.string().min(1).nullable().optional(),
|
|
steps: z.array(
|
|
z.object({
|
|
label: z.string().min(1),
|
|
durationMinutes: z.number().nonnegative(),
|
|
transition: z.string().min(1),
|
|
status: z.string().min(1),
|
|
})
|
|
),
|
|
});
|
|
|
|
export const HabitPayloadSchema = z.object({
|
|
habitId: z.string().min(1),
|
|
identityId: z.string().min(1),
|
|
frequency: z.enum(['daily', 'weekly', 'custom']),
|
|
customDays: z.array(z.number().int().min(0).max(6)).optional(),
|
|
targetCount: z.number().int().positive(),
|
|
reminderTime: z.string().min(1).nullable().optional(),
|
|
isActive: z.boolean(),
|
|
sourceRoutineId: z.string().min(1),
|
|
});
|
|
|
|
export const TrailReportPayloadSchema = z.object({
|
|
sourceProduct: z.literal('claw-cowork'),
|
|
sourceTaskId: z.string().min(1).nullable().optional(),
|
|
generatedFrom: z.enum(['audit-export-json', 'audit-query-json']),
|
|
reportGeneratedAt: z.string().datetime(),
|
|
actionCount: z.number().int().nonnegative(),
|
|
toolCallCount: z.number().int().nonnegative(),
|
|
approvalCount: z.number().int().nonnegative(),
|
|
failureCount: z.number().int().nonnegative(),
|
|
safetySignalCount: z.number().int().nonnegative(),
|
|
tasks: z.array(z.string().min(1)),
|
|
actionBreakdown: z.array(
|
|
z.object({
|
|
action: z.string().min(1),
|
|
count: z.number().int().positive(),
|
|
})
|
|
),
|
|
entries: z.array(
|
|
z.object({
|
|
timestamp: z.string().datetime(),
|
|
taskId: z.string().min(1).nullable(),
|
|
action: z.string().min(1),
|
|
tool: z.string().min(1).nullable().optional(),
|
|
result: z.string().min(1).nullable().optional(),
|
|
approval: z.string().min(1).nullable().optional(),
|
|
inputSummary: z.string().min(1).nullable().optional(),
|
|
metadata: z.record(z.unknown()).nullable().optional(),
|
|
})
|
|
),
|
|
});
|
|
|
|
export const TranscriptArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
|
|
artifactType: z.literal('transcript'),
|
|
payload: TranscriptPayloadSchema,
|
|
});
|
|
|
|
export const NoteArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
|
|
artifactType: z.literal('note'),
|
|
payload: NotePayloadSchema,
|
|
});
|
|
|
|
export const MemoryArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
|
|
artifactType: z.literal('memory'),
|
|
payload: MemoryPayloadSchema,
|
|
});
|
|
|
|
export const PlanArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
|
|
artifactType: z.literal('plan'),
|
|
payload: PlanPayloadSchema,
|
|
});
|
|
|
|
export const RoutineArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
|
|
artifactType: z.literal('routine'),
|
|
payload: RoutinePayloadSchema,
|
|
});
|
|
|
|
export const HabitArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
|
|
artifactType: z.literal('habit'),
|
|
payload: HabitPayloadSchema,
|
|
});
|
|
|
|
export const TrailReportArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
|
|
artifactType: z.literal('trail-report'),
|
|
payload: TrailReportPayloadSchema,
|
|
});
|
|
|
|
export const Phase1ArtifactEnvelopeSchema = z.discriminatedUnion('artifactType', [
|
|
TranscriptArtifactEnvelopeSchema,
|
|
NoteArtifactEnvelopeSchema,
|
|
MemoryArtifactEnvelopeSchema,
|
|
]);
|
|
|
|
export const EcosystemEventActorSchema = z.object({
|
|
actorType: z.enum(['user', 'agent', 'system', 'device']),
|
|
actorId: z.string().min(1).nullable().optional(),
|
|
});
|
|
|
|
export const EcosystemEventTraceSchema = z.object({
|
|
correlationId: z.string().min(1).nullable(),
|
|
causationId: z.string().min(1).nullable(),
|
|
parentEventId: z.string().min(1).nullable(),
|
|
});
|
|
|
|
export const BaseEcosystemEventSchema = z.object({
|
|
eventId: z.string().min(1),
|
|
eventName: z.string().min(1),
|
|
eventVersion: z.literal(1),
|
|
occurredAt: z.string().datetime(),
|
|
productId: z.string().min(1),
|
|
sourceSurface: z.string().min(1),
|
|
userId: z.string().min(1).nullable().optional(),
|
|
orgId: z.string().min(1).nullable().optional(),
|
|
sessionId: z.string().min(1).nullable().optional(),
|
|
runId: z.string().min(1).nullable().optional(),
|
|
artifactId: z.string().min(1).nullable().optional(),
|
|
actor: EcosystemEventActorSchema,
|
|
trace: EcosystemEventTraceSchema,
|
|
payload: z.record(z.unknown()),
|
|
});
|
|
|
|
export const CaptureTranscriptCreatedPayloadSchema = z.object({
|
|
artifactId: z.string().min(1),
|
|
durationMs: z.number().int().nonnegative(),
|
|
language: z.string().min(1),
|
|
transcriptSource: z.enum(['microphone', 'upload', 'call', 'browser', 'other']),
|
|
});
|
|
|
|
export const ArtifactCreatedPayloadSchema = z.object({
|
|
artifactType: z.enum([
|
|
'transcript',
|
|
'note',
|
|
'memory',
|
|
'plan',
|
|
'routine',
|
|
'habit',
|
|
'trail-report',
|
|
]),
|
|
title: z.string().min(1).nullable(),
|
|
status: z.string().min(1),
|
|
});
|
|
|
|
export const ArtifactLinkedPayloadSchema = z.object({
|
|
sourceArtifactId: z.string().min(1),
|
|
targetArtifactId: z.string().min(1),
|
|
relation: z.enum([
|
|
'summarizes',
|
|
'generated-memory',
|
|
'generated-routine',
|
|
'generated-habit',
|
|
'derived-from',
|
|
]),
|
|
});
|
|
|
|
export const MemoryEntryCreatedPayloadSchema = z.object({
|
|
artifactId: z.string().min(1),
|
|
memoryKind: MemoryPayloadSchema.shape.memoryKind,
|
|
reviewState: MemoryPayloadSchema.shape.reviewState,
|
|
confidence: MemoryPayloadSchema.shape.confidence,
|
|
sourceArtifactIds: z.array(z.string().min(1)).min(1),
|
|
});
|
|
|
|
export const CaptureTranscriptCreatedEventSchema = BaseEcosystemEventSchema.extend({
|
|
eventName: z.literal('capture.transcript.created'),
|
|
payload: CaptureTranscriptCreatedPayloadSchema,
|
|
});
|
|
|
|
export const ArtifactCreatedEventSchema = BaseEcosystemEventSchema.extend({
|
|
eventName: z.literal('artifact.created'),
|
|
payload: ArtifactCreatedPayloadSchema,
|
|
});
|
|
|
|
export const ArtifactLinkedEventSchema = BaseEcosystemEventSchema.extend({
|
|
eventName: z.literal('artifact.linked'),
|
|
payload: ArtifactLinkedPayloadSchema,
|
|
});
|
|
|
|
export const MemoryEntryCreatedEventSchema = BaseEcosystemEventSchema.extend({
|
|
eventName: z.literal('memory.entry.created'),
|
|
payload: MemoryEntryCreatedPayloadSchema,
|
|
});
|
|
|
|
export const Phase1EcosystemEventSchema = z.discriminatedUnion('eventName', [
|
|
CaptureTranscriptCreatedEventSchema,
|
|
ArtifactCreatedEventSchema,
|
|
ArtifactLinkedEventSchema,
|
|
MemoryEntryCreatedEventSchema,
|
|
]);
|
|
|
|
export const Phase1EcosystemEventSchemas = {
|
|
'capture.transcript.created': CaptureTranscriptCreatedEventSchema,
|
|
'artifact.created': ArtifactCreatedEventSchema,
|
|
'artifact.linked': ArtifactLinkedEventSchema,
|
|
'memory.entry.created': MemoryEntryCreatedEventSchema,
|
|
} as const;
|
|
|
|
export type ArtifactEnvelope = z.infer<typeof BaseArtifactEnvelopeSchema>;
|
|
export type TranscriptArtifactEnvelope = z.infer<typeof TranscriptArtifactEnvelopeSchema>;
|
|
export type NoteArtifactEnvelope = z.infer<typeof NoteArtifactEnvelopeSchema>;
|
|
export type MemoryArtifactEnvelope = z.infer<typeof MemoryArtifactEnvelopeSchema>;
|
|
export type PlanArtifactEnvelope = z.infer<typeof PlanArtifactEnvelopeSchema>;
|
|
export type RoutineArtifactEnvelope = z.infer<typeof RoutineArtifactEnvelopeSchema>;
|
|
export type HabitArtifactEnvelope = z.infer<typeof HabitArtifactEnvelopeSchema>;
|
|
export type Phase1ArtifactEnvelope = z.infer<typeof Phase1ArtifactEnvelopeSchema>;
|
|
export type EcosystemEvent = z.infer<typeof BaseEcosystemEventSchema>;
|
|
export type Phase1EcosystemEvent = z.infer<typeof Phase1EcosystemEventSchema>;
|