Something went wrong. Try again.
A local-first event pipeline for independent agents, built on Jazz.
Something went wrong. Try again.
4.7 kB · 135 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136import fs from "node:fs/promises";import path from "node:path";import { afterEach, describe, expect, test } from "vitest";import { FOCUS_DECLARATION_PROPOSED_EVENT_TYPE, focusDeclarationFingerprint, listFocusProposals, loadFocusDeclaration, proposeFocusDeclaration,} from "../src/focuses/declarations.js";import { temporaryProject, testStore } from "./helpers.js";
const roots: string[] = [];
afterEach(async () => { await Promise.all(roots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true })));});
describe("focus declarations", () => { test("loads a strict declaration and produces a stable canonical fingerprint", async () => { const root = await temporaryProject("thoughtstream-focus-load-"); roots.push(root); const first = path.join(root, "first.yaml"); const second = path.join(root, "second.yaml"); await fs.writeFile(first, focusYaml()); await fs.writeFile(second, focusYaml().replace("id: news\nversion: 1", "version: 1\nid: news"));
const left = await loadFocusDeclaration(first); const right = await loadFocusDeclaration(second);
expect(left).toMatchObject({ id: "news", version: 1, subscriptions: { replay: "now" }, permissions: { requestedReadTools: [], requestedExternalActions: [] }, }); expect(focusDeclarationFingerprint(left)).toBe(focusDeclarationFingerprint(right)); });
test("rejects ambiguous lineage, scope, and undeclared fields", async () => { const root = await temporaryProject("thoughtstream-focus-invalid-"); roots.push(root); const file = path.join(root, "invalid.yaml"); await fs.writeFile(file, focusYaml() .replace("parentFocusIds: []", "parentFocusIds: [news]") .replace("excludeTags: []", "excludeTags: [news]") .replace("retirementRule:", "unknownAuthority: true\nretirementRule:"));
await expect(loadFocusDeclaration(file)).rejects.toThrow(); });
test("appends one inert proposal and requires a version bump for changed content", async () => { const root = await temporaryProject("thoughtstream-focus-propose-"); roots.push(root); const file = path.join(root, "news.yaml"); await fs.writeFile(file, focusYaml()); const store = await testStore(root); try { const declaration = await loadFocusDeclaration(file); const first = await proposeFocusDeclaration(store, declaration, { occurredAt: "2026-08-03T08:00:00.000Z" }); const repeated = await proposeFocusDeclaration(store, declaration, { occurredAt: "2026-08-03T09:00:00.000Z" });
expect(first.inserted).toBe(true); expect(repeated.inserted).toBe(false); expect(repeated.event.id).toBe(first.event.id); expect(first.event).toMatchObject({ type: FOCUS_DECLARATION_PROPOSED_EVENT_TYPE, privacy: "sensitive", source: "operator:focus-declarations", payload: { resolution: { eventTypes: "unchecked", sourcePatterns: "unchecked", requestedPermissions: "unchecked", parentLineage: "unchecked", }, authority: { activatesFocus: false, expandsDataAccess: false, grantsExternalActions: false, startsTraining: false, promotesAdapter: false, }, }, });
const proposals = await listFocusProposals(store); expect(proposals).toEqual([expect.objectContaining({ eventId: first.event.id, focusId: "news", focusVersion: 1, parentFocusIds: [], proposalSchemaVersion: 1, })]);
await fs.writeFile(file, focusYaml().replace("Produce concise", "Produce ranked")); const changed = await loadFocusDeclaration(file); await expect(proposeFocusDeclaration(store, changed)).rejects.toThrow("Idempotency key reused with different payload"); } finally { await store.close(); } });});
function focusYaml(): string { return `id: newsversion: 1name: Newsdescription: Broad public-source news focus.parentFocusIds: []scope: summary: Observe news events. includeTags: [news] excludeTags: []objective: statement: Produce concise observations from direct evidence.subscriptions: eventTypes: - stream.thought.source.rss.item - stream.thought.source.atproto.commit sourcePatterns: [rss:*, jetstream:*] privacy: [public-source]budgets: inference: maxCallsPerDay: 24 maxInputTokensPerDay: 480000 maxOutputTokensPerDay: 12000 attention: maxDeliveriesPerDay: 6permissions: requestedReadTools: [] requestedExternalActions: []retirementRule: Retire after 100 eligible events without an accepted observation.`;}