import { describe, expect, test } from "vitest"; import { inspectRunContext } from "../src/agents/context-inspection.js"; import { buildSubscribedTelegramConversationContextPacket } from "../src/agents/context.js"; import { declarationFingerprint } from "../src/agents/declarations.js"; import { createOutputContractRegistry, outputContractForDeclaration } from "../src/agents/output-contracts.js"; import { composePiModelInput } from "../src/agents/pi.js"; import { canonicalJson, sha256, type JsonObject } from "../src/core/json.js"; import type { ThoughtAgentDeclaration } from "../src/agents/types.js"; import { temporaryProject, testStore } from "./helpers.js"; describe("run context inspection", () => { test("verifies one durable packet and keeps private content opt-in", async () => { const project = await temporaryProject(); const store = await testStore(project); try { const declaration = telegramDeclaration(); declaration.declarationFingerprint = declarationFingerprint(declaration); const documentContent = "# Identity\n\nPRIVATE DOCUMENT TEXT\n"; await store.appendDocumentVersion({ id: "identity-v1", source: "filesystem:telegram-agent-context", documentId: "identity", path: "identity.md", contentType: "text/markdown", sha256: sha256(documentContent), content: documentContent, sizeBytes: Buffer.byteLength(documentContent), mtimeMs: Date.parse("2026-08-03T17:00:00.000Z"), createdAt: "2026-08-03T17:00:00.000Z", }); await store.upsertCurrentDocument({ id: "filesystem:telegram-agent-context:identity", source: "filesystem:telegram-agent-context", documentId: "identity", path: "identity.md", versionId: "identity-v1", sha256: sha256(documentContent), contentType: "text/markdown", sizeBytes: Buffer.byteLength(documentContent), mtimeMs: Date.parse("2026-08-03T17:00:00.000Z"), deleted: false, updatedAt: "2026-08-03T17:00:00.000Z", }); const trigger = (await store.appendEvent({ type: "stream.thought.source.telegram.message", schemaVersion: 1, source: "telegram:fixture", sourceKind: "telegram", externalId: "context-inspection-trigger", idempotencyKey: "context-inspection-trigger", occurredAt: "2026-08-03T17:00:00.000Z", actor: "123456789", correlationId: "context-inspection-trigger", privacy: "sensitive", payload: { chatId: "123456789", senderId: "123456789", text: "CURRENT PRIVATE TEXT" }, })).event; const packet = await buildSubscribedTelegramConversationContextPacket(declaration, trigger, store); const declarationJson = JSON.parse(JSON.stringify(declaration)) as JsonObject; await store.upsertAgent({ id: declaration.id, version: declaration.version, enabled: true, spec: declarationJson, specHash: sha256(canonicalJson(declarationJson)), updatedAt: "2026-08-03T17:00:01.000Z", }); await store.upsertRun({ id: "run-context-inspection", executionKey: "execution-context-inspection", triggerEventId: trigger.id, agentId: declaration.id, agentVersion: declaration.version, status: "completed", inputEventIds: [trigger.id], outputEventIds: [], attempt: 1, provider: "tinker", model: "thinkingmachines/Inkling-Small", promptHash: sha256(declaration.systemPrompt), contextManifest: packet.manifest, result: { summary: "done", tags: ["conversation"], importance: "normal", confidence: 1 }, createdAt: "2026-08-03T17:00:01.000Z", startedAt: "2026-08-03T17:00:01.000Z", completedAt: "2026-08-03T17:00:02.000Z", updatedAt: "2026-08-03T17:00:02.000Z", }); const contract = createOutputContractRegistry().resolve(outputContractForDeclaration(declaration)); const modelInput = composePiModelInput(declaration, packet, { readOnlyToolCount: 0, readOnlyEvidenceText: "", resolvedContextImageCount: 0, outputContractPrompt: contract.prompt, }); await store.appendTrace({ id: "trace-context-inspection-system", runId: "run-context-inspection", sequence: 1, type: "system_prompt", payload: { data: { chars: modelInput.systemPrompt.length, redacted: true, sha256: sha256(modelInput.systemPrompt) } }, createdAt: "2026-08-03T17:00:01.000Z", }); await store.appendTrace({ id: "trace-context-inspection-prompt", runId: "run-context-inspection", sequence: 2, type: "prompt", payload: { data: { chars: modelInput.prompt.length, redacted: true, sha256: sha256(modelInput.prompt) } }, createdAt: "2026-08-03T17:00:01.001Z", }); const metadata = await inspectRunContext(store, "run-context-inspection"); expect(metadata).toMatchObject({ run: { id: "run-context-inspection", agentId: "telegram-conversation", agentVersion: 18 }, packet: { contentIncluded: false, currentTextChars: "CURRENT PRIVATE TEXT".length, messageCount: 0, messageRoles: [], currentTextSha256: expect.any(String), manifest: packet.manifest, }, modelInput: { exact: true, incompleteReasons: [], systemPromptChars: modelInput.systemPrompt.length, currentPromptChars: modelInput.prompt.length, }, }); expect(metadata.packet).not.toHaveProperty("systemText"); expect(metadata.packet).not.toHaveProperty("currentText"); expect(metadata.packet).not.toHaveProperty("messages"); expect(metadata.modelInput).not.toHaveProperty("systemPrompt"); expect(metadata.modelInput).not.toHaveProperty("currentPrompt"); expect(JSON.stringify(metadata)).not.toContain("CURRENT PRIVATE TEXT"); expect(JSON.stringify(metadata)).not.toContain("PRIVATE SYSTEM TEXT"); expect(JSON.stringify(metadata)).not.toContain("PRIVATE DOCUMENT TEXT"); const content = await inspectRunContext(store, "run-context-inspection", { includeContent: true }); expect(content.packet).toMatchObject({ contentIncluded: true, currentText: "CURRENT PRIVATE TEXT", }); expect(content.packet.systemText).toContain("PRIVATE DOCUMENT TEXT"); expect(content.modelInput).toMatchObject({ exact: true, systemPrompt: modelInput.systemPrompt, currentPrompt: "CURRENT PRIVATE TEXT", }); expect(content.modelInput.systemPrompt).toContain("PRIVATE SYSTEM TEXT"); expect(content.modelInput.systemPrompt).toContain("PRIVATE DOCUMENT TEXT"); await store.appendTrace({ id: "trace-context-inspection-ambiguous-system", runId: "run-context-inspection", sequence: 3, type: "system_prompt", payload: { data: { chars: 1, redacted: true, sha256: "0".repeat(64) } }, createdAt: "2026-08-03T17:00:01.002Z", }); const ambiguous = await inspectRunContext(store, "run-context-inspection", { includeContent: true }); expect(ambiguous.modelInput).toMatchObject({ exact: false, incompleteReasons: ["durable prompt hash traces are unavailable or ambiguous"], }); expect(ambiguous.modelInput).not.toHaveProperty("systemPrompt"); expect(ambiguous.modelInput).not.toHaveProperty("currentPrompt"); expect(await store.listEvents()).toHaveLength(1); expect(await store.listRuns()).toHaveLength(1); expect(await store.listTrace("run-context-inspection")).toHaveLength(3); } finally { await store.close(); } }); test("fails closed when snapshot storage evidence is inconsistent", async () => { const project = await temporaryProject(); const store = await testStore(project); try { await store.appendDocumentVersion({ id: "broken-snapshot", source: "context:telegram-conversation", documentId: "broken-snapshot", path: "context/broken.json", contentType: "application/json", sha256: "0".repeat(64), content: "{}", sizeBytes: 2, mtimeMs: Date.parse("2026-08-03T17:00:00.000Z"), createdAt: "2026-08-03T17:00:00.000Z", }); await store.upsertRun({ id: "run-broken-context", executionKey: "execution-broken-context", triggerEventId: "evt_missing", agentId: "telegram-conversation", agentVersion: 18, status: "completed", inputEventIds: ["evt_missing"], outputEventIds: [], attempt: 1, provider: "tinker", model: "thinkingmachines/Inkling-Small", promptHash: "fixture-prompt", contextManifest: { contextSnapshot: { id: "broken-snapshot" } }, result: { summary: "done", tags: ["conversation"], importance: "normal", confidence: 1 }, createdAt: "2026-08-03T17:00:01.000Z", startedAt: "2026-08-03T17:00:01.000Z", completedAt: "2026-08-03T17:00:02.000Z", updatedAt: "2026-08-03T17:00:02.000Z", }); await expect(inspectRunContext(store, "run-broken-context")) .rejects.toThrow("storage evidence is missing or inconsistent"); } finally { await store.close(); } }); }); function telegramDeclaration(): ThoughtAgentDeclaration { return { id: "telegram-conversation", version: 18, name: "The Stream", description: "Private Telegram conversation fixture", mode: "pi", provider: "tinker", providerProfile: "tinker-default", model: "thinkingmachines/Inkling-Small", outputMode: "conversation-text", eventTypes: ["stream.thought.source.telegram.message"], compiledEventTypes: ["stream.thought.source.telegram.message"], sourcePatterns: ["telegram:fixture"], acceptedPrivacy: ["sensitive"], outputEventType: "stream.thought.derived.message.observation", emit: ["stream.thought.derived.message.observation"], promptRef: "prompts/telegram-conversation.md", systemPrompt: "PRIVATE SYSTEM TEXT", enabled: true, maxEvents: 8, maxInputChars: 48_000, maxOutputTokens: 500, timeoutMs: 30_000, contextStrategy: "telegram-conversation", contextDocumentMaxChars: 8_000, contextDocumentSubscriptions: [{ source: "filesystem:telegram-agent-context", paths: ["identity.md"], required: true, }], conversationHistoryAgentIds: ["telegram-conversation"], tools: [], externalActions: false, }; }