// Descriptor-pin unit test, plain vitest + effect. `support.summarize`: // its executor calls `generateObject` (a real model inference), which a unit // harness can't provide — so we do NOT run the executor. Instead we assert the // wire CONTRACT that both the client and the model are bound to: the action's // name, and that `SummaryResult` (the shared schema constraining the model's // output AND the RPC output) decodes a valid object and rejects a bad one. // // This is the meaningful hermetic test for an AI action — the schema is the // single source of truth the model must satisfy; pinning it catches an // accidental shape change without a model in the loop. Run with `voltro test`. import { describe, it, expect } from 'vitest' import { Schema } from 'effect' import { summarize, SummaryResult } from '../actions/summarize.action' describe('support.summarize (action descriptor)', () => { it('declares the expected wire name', () => { expect(summarize.name).toBe('support.summarize') }) it('accepts a valid { text } input and rejects a malformed one', () => { const decode = Schema.decodeUnknownSync(summarize.input) expect(decode({ text: 'a support thread' })).toEqual({ text: 'a support thread' }) expect(() => decode({})).toThrow() // missing text }) it('decodes a valid SummaryResult', () => { const decode = Schema.decodeUnknownSync(SummaryResult) const ok = decode({ title: 'Refund request', summary: 'The customer wants a refund for a late order.', keyPoints: ['order was late', 'requests refund'], sentiment: 'negative', }) expect(ok.sentiment).toBe('negative') expect(ok.keyPoints).toEqual(['order was late', 'requests refund']) }) it('rejects a SummaryResult whose sentiment is outside the literal union', () => { const decode = Schema.decodeUnknownSync(SummaryResult) expect(() => decode({ title: 'x', summary: 'y', keyPoints: [], sentiment: 'furious', // not 'positive' | 'neutral' | 'negative' }), ).toThrow() }) })