Something went wrong. Try again.
A local-first event pipeline for independent agents, built on Jazz.
Something went wrong. Try again.
6.7 kB · 153 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154import { z } from "zod";import { createOutputContractRegistry } from "../agents/output-contracts.js";import { outputContractIdentitySchema, proposalMemoryTargetSchema } from "../agents/proposals.js";import { sha256, type JsonObject, type JsonValue } from "../core/json.js";
export const MEMORY_PROPOSAL_EVENT_TYPE = "stream.thought.agent.memory-change.proposed";export const CORRECTION_PROPOSAL_EVENT_TYPE = "stream.thought.agent.correction.proposed";export const PROPOSAL_DECISION_EVENT_TYPE = "stream.thought.agent.proposal.decision";export const MEMORY_MATERIALIZED_EVENT_TYPE = "stream.thought.agent.memory-change.materialized";export const MEMORY_MATERIALIZATION_FAILED_EVENT_TYPE = "stream.thought.agent.memory-change.materialization.failed";export const AGENT_PROPOSAL_SCHEMA_VERSION = 1;
const idSchema = z.string().min(1).max(500);const sha256Schema = z.string().regex(/^[a-f0-9]{64}$/);const jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() => z.union([ z.string(), z.number(), z.boolean(), z.null(), z.array(jsonValueSchema), z.record(z.string(), jsonValueSchema),]));const objectSchema = z.record(z.string(), jsonValueSchema) as z.ZodType<JsonObject>;const evidenceIdsSchema = z.array(idSchema).max(16).superRefine((ids, context) => { if (new Set(ids).size !== ids.length) context.addIssue({ code: "custom", message: "Proposal evidence ids must be unique" });});
const proposerSchema = z.object({ runId: idSchema, outputEventId: idSchema, triggerEventId: idSchema, agentId: idSchema, agentVersion: z.number().int().positive(), declarationFingerprint: sha256Schema, provider: z.string().min(1).max(200), model: z.string().min(1).max(500), contextSnapshotId: idSchema,}).strict();
export const memoryProposalPayloadSchema = z.object({ proposalState: z.literal("agent-proposed"), proposer: proposerSchema, target: proposalMemoryTargetSchema, operation: z.enum(["append", "replace-document"]), proposedText: z.string().min(1).max(32_768), proposedTextChars: z.number().int().positive().max(32_768), proposedTextSha256: sha256Schema, reason: z.string().min(1).max(1_000), evidenceEventIds: evidenceIdsSchema, publicationEligible: z.literal(false),}).strict().superRefine((value, context) => { if (value.proposedText.length !== value.proposedTextChars) { context.addIssue({ code: "custom", path: ["proposedTextChars"], message: "Proposal text length does not match" }); } if (sha256(value.proposedText) !== value.proposedTextSha256) { context.addIssue({ code: "custom", path: ["proposedTextSha256"], message: "Proposal text hash does not match" }); }});
const correctionTargetSchema = z.object({ runId: idSchema, outputEventId: idSchema, deliveryReceiptEventId: idSchema, sourceRootEventId: idSchema, outputContract: outputContractIdentitySchema,}).strict();
export const correctionProposalPayloadSchema = z.object({ proposalState: z.literal("agent-proposed"), proposer: proposerSchema, target: correctionTargetSchema, replacementOutput: objectSchema, replacementText: z.string().min(1).max(4_096), replacementTextChars: z.number().int().positive().max(4_096), replacementTextSha256: sha256Schema, reason: z.string().min(1).max(1_000), evidenceEventIds: evidenceIdsSchema, qualityEligible: z.literal(false), externalExportEligible: z.literal(false), publicationEligible: z.literal(false),}).strict().superRefine((value, context) => { if (value.replacementText.length !== value.replacementTextChars) { context.addIssue({ code: "custom", path: ["replacementTextChars"], message: "Correction text length does not match" }); } if (sha256(value.replacementText) !== value.replacementTextSha256) { context.addIssue({ code: "custom", path: ["replacementTextSha256"], message: "Correction text hash does not match" }); } try { createOutputContractRegistry().canonicalize(value.target.outputContract, value.replacementOutput); } catch { context.addIssue({ code: "custom", path: ["replacementOutput"], message: "Correction replacement does not satisfy the frozen output contract" }); }});
export const proposalDecisionPayloadSchema = z.object({ proposalEventId: idSchema, proposalType: z.enum(["memory-change", "self-correction"]), disposition: z.enum(["accept", "edit", "reject"]), submissionId: idSchema, authority: z.literal("human"), replacementText: z.string().min(1).max(32_768).optional(), replacementTextChars: z.number().int().positive().max(32_768).optional(), replacementTextSha256: sha256Schema.optional(),}).strict().superRefine((value, context) => { const hasReplacement = value.replacementText !== undefined; if ((value.disposition === "edit") !== hasReplacement) { context.addIssue({ code: "custom", path: ["replacementText"], message: "Only edit decisions require replacement text" }); } if (hasReplacement && (value.replacementText!.length !== value.replacementTextChars || sha256(value.replacementText!) !== value.replacementTextSha256)) { context.addIssue({ code: "custom", path: ["replacementTextSha256"], message: "Decision replacement metadata does not match" }); } if (value.proposalType === "self-correction" && hasReplacement && value.replacementText!.length > 4_096) { context.addIssue({ code: "custom", path: ["replacementText"], message: "Correction edit exceeds its output bound" }); }});
export const memoryMaterializedPayloadSchema = z.object({ proposalEventId: idSchema, decisionEventId: idSchema, operation: z.enum(["append", "replace-document"]), base: proposalMemoryTargetSchema, result: z.object({ documentId: idSchema, versionId: idSchema, sha256: sha256Schema, sizeBytes: z.number().int().positive().max(2_000_000), filesystemEventId: idSchema, }).strict(), materializedBy: z.literal("trusted-local-memory-materializer@1"),}).strict();
export const MEMORY_MATERIALIZATION_FAILURE_CODES = [ "decision-rejected", "stale-base", "base-evidence-invalid", "root-invalid", "target-invalid", "symlink-refused", "frontmatter-invalid", "document-identity-changed", "content-too-large", "write-failed", "filesystem-scan-failed", "receipt-mismatch", "already-decided",] as const;export type MemoryMaterializationFailureCode = typeof MEMORY_MATERIALIZATION_FAILURE_CODES[number];
export const memoryMaterializationFailedPayloadSchema = z.object({ proposalEventId: idSchema, decisionEventId: idSchema, baseVersionId: idSchema, baseSha256: sha256Schema, reasonCode: z.enum(MEMORY_MATERIALIZATION_FAILURE_CODES), contentRedacted: z.literal(true), materializedBy: z.literal("trusted-local-memory-materializer@1"),}).strict();