feat(events): add phase1 ecosystem contracts
This commit is contained in:
parent
3d59e7bbed
commit
76f1b47484
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"eventId": "evt_phase1_002",
|
||||||
|
"eventName": "artifact.created",
|
||||||
|
"eventVersion": 1,
|
||||||
|
"occurredAt": "2026-04-03T18:17:01.000Z",
|
||||||
|
"productId": "notelett",
|
||||||
|
"sourceSurface": "web",
|
||||||
|
"userId": "user_saravana",
|
||||||
|
"orgId": null,
|
||||||
|
"sessionId": "sess_lysnr_001",
|
||||||
|
"runId": "run_notes_001",
|
||||||
|
"artifactId": "art_note_001",
|
||||||
|
"actor": {
|
||||||
|
"actorType": "agent",
|
||||||
|
"actorId": "notes_ingest_agent"
|
||||||
|
},
|
||||||
|
"trace": {
|
||||||
|
"correlationId": "corr_phase1_001",
|
||||||
|
"causationId": "evt_phase1_001",
|
||||||
|
"parentEventId": "evt_phase1_001"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"artifactType": "note",
|
||||||
|
"title": "Standup follow-up",
|
||||||
|
"status": "draft"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"eventId": "evt_phase1_003",
|
||||||
|
"eventName": "artifact.linked",
|
||||||
|
"eventVersion": 1,
|
||||||
|
"occurredAt": "2026-04-03T18:17:02.000Z",
|
||||||
|
"productId": "notelett",
|
||||||
|
"sourceSurface": "web",
|
||||||
|
"userId": "user_saravana",
|
||||||
|
"orgId": null,
|
||||||
|
"sessionId": "sess_lysnr_001",
|
||||||
|
"runId": "run_notes_001",
|
||||||
|
"artifactId": "art_note_001",
|
||||||
|
"actor": {
|
||||||
|
"actorType": "agent",
|
||||||
|
"actorId": "notes_ingest_agent"
|
||||||
|
},
|
||||||
|
"trace": {
|
||||||
|
"correlationId": "corr_phase1_001",
|
||||||
|
"causationId": "evt_phase1_002",
|
||||||
|
"parentEventId": "evt_phase1_002"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"sourceArtifactId": "art_note_001",
|
||||||
|
"targetArtifactId": "art_transcript_001",
|
||||||
|
"relation": "summarizes"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"eventId": "evt_phase1_001",
|
||||||
|
"eventName": "capture.transcript.created",
|
||||||
|
"eventVersion": 1,
|
||||||
|
"occurredAt": "2026-04-03T18:15:01.000Z",
|
||||||
|
"productId": "lysnrai",
|
||||||
|
"sourceSurface": "mobile",
|
||||||
|
"userId": "user_saravana",
|
||||||
|
"orgId": null,
|
||||||
|
"sessionId": "sess_lysnr_001",
|
||||||
|
"runId": null,
|
||||||
|
"artifactId": "art_transcript_001",
|
||||||
|
"actor": {
|
||||||
|
"actorType": "user",
|
||||||
|
"actorId": "user_saravana"
|
||||||
|
},
|
||||||
|
"trace": {
|
||||||
|
"correlationId": "corr_phase1_001",
|
||||||
|
"causationId": null,
|
||||||
|
"parentEventId": null
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"artifactId": "art_transcript_001",
|
||||||
|
"durationMs": 42150,
|
||||||
|
"language": "en",
|
||||||
|
"transcriptSource": "microphone"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"id": "art_memory_001",
|
||||||
|
"artifactType": "memory",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"productId": "mindlyst",
|
||||||
|
"sourceSurface": "service",
|
||||||
|
"title": "Saravana prefers deployment checklist reminders after standup",
|
||||||
|
"summary": "Memory candidate inferred from the standup transcript and note.",
|
||||||
|
"createdAt": "2026-04-03T18:20:00.000Z",
|
||||||
|
"updatedAt": "2026-04-03T18:20:00.000Z",
|
||||||
|
"createdBy": {
|
||||||
|
"actorType": "agent",
|
||||||
|
"actorId": "memory_ingest_agent"
|
||||||
|
},
|
||||||
|
"ownership": {
|
||||||
|
"userId": "user_saravana",
|
||||||
|
"orgId": null
|
||||||
|
},
|
||||||
|
"visibility": {
|
||||||
|
"scope": "private"
|
||||||
|
},
|
||||||
|
"status": "proposed",
|
||||||
|
"tags": ["memory", "workflow"],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"relation": "derived-from",
|
||||||
|
"targetArtifactId": "art_transcript_001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"relation": "generated-memory",
|
||||||
|
"targetArtifactId": "art_note_001"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"provenance": {
|
||||||
|
"originProductId": "lysnrai",
|
||||||
|
"originActionId": "capture_001",
|
||||||
|
"sessionId": "sess_lysnr_001",
|
||||||
|
"runId": "run_memory_001",
|
||||||
|
"approvalId": null,
|
||||||
|
"correlationId": "corr_phase1_001",
|
||||||
|
"lineage": [
|
||||||
|
{
|
||||||
|
"stepType": "captured",
|
||||||
|
"productId": "lysnrai",
|
||||||
|
"actorType": "user",
|
||||||
|
"timestamp": "2026-04-03T18:15:00.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stepType": "note-created",
|
||||||
|
"productId": "notelett",
|
||||||
|
"actorType": "agent",
|
||||||
|
"timestamp": "2026-04-03T18:17:00.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stepType": "memory-proposed",
|
||||||
|
"productId": "mindlyst",
|
||||||
|
"actorType": "agent",
|
||||||
|
"timestamp": "2026-04-03T18:20:00.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"memoryKind": "preference",
|
||||||
|
"text": "Saravana benefits from deployment checklist reminders immediately after standup capture.",
|
||||||
|
"confidence": 0.82,
|
||||||
|
"sourceArtifactIds": ["art_transcript_001", "art_note_001"],
|
||||||
|
"reviewState": "proposed"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"eventId": "evt_phase1_004",
|
||||||
|
"eventName": "memory.entry.created",
|
||||||
|
"eventVersion": 1,
|
||||||
|
"occurredAt": "2026-04-03T18:20:01.000Z",
|
||||||
|
"productId": "mindlyst",
|
||||||
|
"sourceSurface": "service",
|
||||||
|
"userId": "user_saravana",
|
||||||
|
"orgId": null,
|
||||||
|
"sessionId": "sess_lysnr_001",
|
||||||
|
"runId": "run_memory_001",
|
||||||
|
"artifactId": "art_memory_001",
|
||||||
|
"actor": {
|
||||||
|
"actorType": "agent",
|
||||||
|
"actorId": "memory_ingest_agent"
|
||||||
|
},
|
||||||
|
"trace": {
|
||||||
|
"correlationId": "corr_phase1_001",
|
||||||
|
"causationId": "evt_phase1_003",
|
||||||
|
"parentEventId": "evt_phase1_003"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"artifactId": "art_memory_001",
|
||||||
|
"memoryKind": "preference",
|
||||||
|
"reviewState": "proposed",
|
||||||
|
"confidence": 0.82,
|
||||||
|
"sourceArtifactIds": ["art_transcript_001", "art_note_001"]
|
||||||
|
}
|
||||||
|
}
|
||||||
57
packages/events/fixtures/ecosystem/phase1/note-artifact.json
Normal file
57
packages/events/fixtures/ecosystem/phase1/note-artifact.json
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"id": "art_note_001",
|
||||||
|
"artifactType": "note",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"productId": "notelett",
|
||||||
|
"sourceSurface": "web",
|
||||||
|
"title": "Standup follow-up",
|
||||||
|
"summary": "Structured note created from a LysnrAI transcript.",
|
||||||
|
"createdAt": "2026-04-03T18:17:00.000Z",
|
||||||
|
"updatedAt": "2026-04-03T18:17:00.000Z",
|
||||||
|
"createdBy": {
|
||||||
|
"actorType": "agent",
|
||||||
|
"actorId": "notes_ingest_agent"
|
||||||
|
},
|
||||||
|
"ownership": {
|
||||||
|
"userId": "user_saravana",
|
||||||
|
"orgId": null
|
||||||
|
},
|
||||||
|
"visibility": {
|
||||||
|
"scope": "private"
|
||||||
|
},
|
||||||
|
"status": "draft",
|
||||||
|
"tags": ["derived", "standup"],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"relation": "summarizes",
|
||||||
|
"targetArtifactId": "art_transcript_001"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"provenance": {
|
||||||
|
"originProductId": "lysnrai",
|
||||||
|
"originActionId": "capture_001",
|
||||||
|
"sessionId": "sess_lysnr_001",
|
||||||
|
"runId": "run_notes_001",
|
||||||
|
"approvalId": null,
|
||||||
|
"correlationId": "corr_phase1_001",
|
||||||
|
"lineage": [
|
||||||
|
{
|
||||||
|
"stepType": "captured",
|
||||||
|
"productId": "lysnrai",
|
||||||
|
"actorType": "user",
|
||||||
|
"timestamp": "2026-04-03T18:15:00.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stepType": "note-created",
|
||||||
|
"productId": "notelett",
|
||||||
|
"actorType": "agent",
|
||||||
|
"timestamp": "2026-04-03T18:17:00.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"noteFormat": "markdown",
|
||||||
|
"body": "# Standup follow-up\n\n- Billing sync finished\n- Clean up follow-up notes\n- Review deployment checklist",
|
||||||
|
"excerpt": "Billing sync finished; follow-up notes and deployment checklist remain."
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"id": "art_transcript_001",
|
||||||
|
"artifactType": "transcript",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"productId": "lysnrai",
|
||||||
|
"sourceSurface": "mobile",
|
||||||
|
"title": "Daily standup voice capture",
|
||||||
|
"summary": "Transcript captured from Saravana's daily standup reflection.",
|
||||||
|
"createdAt": "2026-04-03T18:15:00.000Z",
|
||||||
|
"updatedAt": "2026-04-03T18:15:00.000Z",
|
||||||
|
"createdBy": {
|
||||||
|
"actorType": "user",
|
||||||
|
"actorId": "user_saravana"
|
||||||
|
},
|
||||||
|
"ownership": {
|
||||||
|
"userId": "user_saravana",
|
||||||
|
"orgId": null
|
||||||
|
},
|
||||||
|
"visibility": {
|
||||||
|
"scope": "private",
|
||||||
|
"allowedProducts": ["learning_ai_notes", "learning_multimodal_memory_agents"]
|
||||||
|
},
|
||||||
|
"status": "completed",
|
||||||
|
"tags": ["voice", "standup"],
|
||||||
|
"links": [],
|
||||||
|
"provenance": {
|
||||||
|
"originProductId": "lysnrai",
|
||||||
|
"originActionId": "capture_001",
|
||||||
|
"sessionId": "sess_lysnr_001",
|
||||||
|
"runId": null,
|
||||||
|
"approvalId": null,
|
||||||
|
"correlationId": "corr_phase1_001",
|
||||||
|
"lineage": [
|
||||||
|
{
|
||||||
|
"stepType": "captured",
|
||||||
|
"productId": "lysnrai",
|
||||||
|
"actorType": "user",
|
||||||
|
"timestamp": "2026-04-03T18:15:00.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"transcriptText": "Today I finished the billing sync, I need to clean up follow-up notes, and I should remember to review the deployment checklist.",
|
||||||
|
"transcriptSource": "microphone",
|
||||||
|
"language": "en",
|
||||||
|
"durationMs": 42150,
|
||||||
|
"segments": [
|
||||||
|
{
|
||||||
|
"speaker": null,
|
||||||
|
"startedAtMs": 0,
|
||||||
|
"endedAtMs": 42150,
|
||||||
|
"text": "Today I finished the billing sync, I need to clean up follow-up notes, and I should remember to review the deployment checklist."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
59
packages/events/src/ecosystem.test.ts
Normal file
59
packages/events/src/ecosystem.test.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import transcriptArtifact from '../fixtures/ecosystem/phase1/transcript-artifact.json' with { type: 'json' };
|
||||||
|
import noteArtifact from '../fixtures/ecosystem/phase1/note-artifact.json' with { type: 'json' };
|
||||||
|
import memoryArtifact from '../fixtures/ecosystem/phase1/memory-artifact.json' with { type: 'json' };
|
||||||
|
import captureTranscriptCreatedEvent from '../fixtures/ecosystem/phase1/capture-transcript-created.event.json' with { type: 'json' };
|
||||||
|
import artifactCreatedEvent from '../fixtures/ecosystem/phase1/artifact-created.event.json' with { type: 'json' };
|
||||||
|
import artifactLinkedEvent from '../fixtures/ecosystem/phase1/artifact-linked.event.json' with { type: 'json' };
|
||||||
|
import memoryEntryCreatedEvent from '../fixtures/ecosystem/phase1/memory-entry-created.event.json' with { type: 'json' };
|
||||||
|
import {
|
||||||
|
Phase1ArtifactEnvelopeSchema,
|
||||||
|
Phase1EcosystemEventSchema,
|
||||||
|
Phase1EcosystemEventSchemas,
|
||||||
|
} from './ecosystem.js';
|
||||||
|
|
||||||
|
describe('phase1 ecosystem contracts', () => {
|
||||||
|
it('validates canonical transcript, note, and memory artifacts', () => {
|
||||||
|
const transcript = Phase1ArtifactEnvelopeSchema.parse(transcriptArtifact);
|
||||||
|
const note = Phase1ArtifactEnvelopeSchema.parse(noteArtifact);
|
||||||
|
const memory = Phase1ArtifactEnvelopeSchema.parse(memoryArtifact);
|
||||||
|
|
||||||
|
expect(transcript.artifactType).toBe('transcript');
|
||||||
|
expect(note.links).toContainEqual({
|
||||||
|
relation: 'summarizes',
|
||||||
|
targetArtifactId: transcript.id,
|
||||||
|
});
|
||||||
|
expect(memory.links).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
{
|
||||||
|
relation: 'generated-memory',
|
||||||
|
targetArtifactId: note.id,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('validates canonical phase1 events', () => {
|
||||||
|
const events = [
|
||||||
|
captureTranscriptCreatedEvent,
|
||||||
|
artifactCreatedEvent,
|
||||||
|
artifactLinkedEvent,
|
||||||
|
memoryEntryCreatedEvent,
|
||||||
|
].map(event => Phase1EcosystemEventSchema.parse(event));
|
||||||
|
|
||||||
|
expect(events.map(event => event.eventName)).toEqual([
|
||||||
|
'capture.transcript.created',
|
||||||
|
'artifact.created',
|
||||||
|
'artifact.linked',
|
||||||
|
'memory.entry.created',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exposes event-specific schemas keyed by canonical event name', () => {
|
||||||
|
const created = Phase1EcosystemEventSchemas['artifact.created'].parse(artifactCreatedEvent);
|
||||||
|
const linked = Phase1EcosystemEventSchemas['artifact.linked'].parse(artifactLinkedEvent);
|
||||||
|
|
||||||
|
expect(created.payload.artifactType).toBe('note');
|
||||||
|
expect(linked.payload.relation).toBe('summarizes');
|
||||||
|
});
|
||||||
|
});
|
||||||
232
packages/events/src/ecosystem.ts
Normal file
232
packages/events/src/ecosystem.ts
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const EcosystemArtifactTypeSchema = z.enum([
|
||||||
|
'transcript',
|
||||||
|
'note',
|
||||||
|
'memory',
|
||||||
|
'plan',
|
||||||
|
'routine',
|
||||||
|
'habit-checkin',
|
||||||
|
'trail-report',
|
||||||
|
'route-session',
|
||||||
|
'agent-output',
|
||||||
|
'document',
|
||||||
|
'digest',
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const ArtifactLinkRelationSchema = z.enum([
|
||||||
|
'derived-from',
|
||||||
|
'summarizes',
|
||||||
|
'generated-task',
|
||||||
|
'generated-routine',
|
||||||
|
'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 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 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']),
|
||||||
|
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']),
|
||||||
|
});
|
||||||
|
|
||||||
|
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 Phase1ArtifactEnvelope = z.infer<typeof Phase1ArtifactEnvelopeSchema>;
|
||||||
|
export type EcosystemEvent = z.infer<typeof BaseEcosystemEventSchema>;
|
||||||
|
export type Phase1EcosystemEvent = z.infer<typeof Phase1EcosystemEventSchema>;
|
||||||
@ -3,6 +3,37 @@ export type { EmitResult, EmitError } from './memory.js';
|
|||||||
export { DurableEventBus } from './durable.js';
|
export { DurableEventBus } from './durable.js';
|
||||||
export type { DurableEventBusOptions } from './durable.js';
|
export type { DurableEventBusOptions } from './durable.js';
|
||||||
export { PlatformEventSchemas } from './types.js';
|
export { PlatformEventSchemas } from './types.js';
|
||||||
|
export {
|
||||||
|
ArtifactCreatedBySchema,
|
||||||
|
ArtifactLineageStepSchema,
|
||||||
|
ArtifactLinkRelationSchema,
|
||||||
|
ArtifactLinkSchema,
|
||||||
|
ArtifactOwnershipSchema,
|
||||||
|
ArtifactProvenanceSchema,
|
||||||
|
ArtifactVisibilitySchema,
|
||||||
|
BaseArtifactEnvelopeSchema,
|
||||||
|
BaseEcosystemEventSchema,
|
||||||
|
CaptureTranscriptCreatedEventSchema,
|
||||||
|
CaptureTranscriptCreatedPayloadSchema,
|
||||||
|
EcosystemArtifactTypeSchema,
|
||||||
|
EcosystemEventActorSchema,
|
||||||
|
EcosystemEventTraceSchema,
|
||||||
|
MemoryArtifactEnvelopeSchema,
|
||||||
|
MemoryEntryCreatedEventSchema,
|
||||||
|
MemoryEntryCreatedPayloadSchema,
|
||||||
|
MemoryPayloadSchema,
|
||||||
|
NoteArtifactEnvelopeSchema,
|
||||||
|
NotePayloadSchema,
|
||||||
|
Phase1ArtifactEnvelopeSchema,
|
||||||
|
Phase1EcosystemEventSchema,
|
||||||
|
Phase1EcosystemEventSchemas,
|
||||||
|
TranscriptArtifactEnvelopeSchema,
|
||||||
|
TranscriptPayloadSchema,
|
||||||
|
ArtifactCreatedEventSchema,
|
||||||
|
ArtifactCreatedPayloadSchema,
|
||||||
|
ArtifactLinkedEventSchema,
|
||||||
|
ArtifactLinkedPayloadSchema,
|
||||||
|
} from './ecosystem.js';
|
||||||
export type {
|
export type {
|
||||||
PlatformEventName,
|
PlatformEventName,
|
||||||
PlatformEventPayload,
|
PlatformEventPayload,
|
||||||
@ -10,3 +41,11 @@ export type {
|
|||||||
EventHandler,
|
EventHandler,
|
||||||
EventSubscription,
|
EventSubscription,
|
||||||
} from './types.js';
|
} from './types.js';
|
||||||
|
export type {
|
||||||
|
EcosystemEvent,
|
||||||
|
MemoryArtifactEnvelope,
|
||||||
|
NoteArtifactEnvelope,
|
||||||
|
Phase1ArtifactEnvelope,
|
||||||
|
Phase1EcosystemEvent,
|
||||||
|
TranscriptArtifactEnvelope,
|
||||||
|
} from './ecosystem.js';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user