import { sdk } from '../sdk' import { configFile } from '../file-models/config' const { InputSpec, Value, List } = sdk const inputSpec = InputSpec.of({ reviewers: Value.list( List.obj( { name: 'Review Panel', description: 'Who sits on the panel — one entry per review. Add as many as you like. ' + 'Each reviewer is a model from your catalog plus a PERSONA: the lens it ' + 'reads through, so the same document gets examined from different angles.', default: [], minLength: 1, maxLength: 32, }, { uniqueBy: 'name', displayAs: '{{name}} ({{model}})', spec: InputSpec.of({ name: Value.text({ name: 'Name', description: 'Unique reviewer name. Becomes its container and report filename.', required: true, default: null, placeholder: 'risk-counsel', patterns: [ { regex: '^[A-Za-z0-9][A-Za-z0-9 _-]{0,40}$', description: 'Letters, numbers, spaces, dashes, underscores (max 41 chars).' }, ], }), model: Value.text({ name: 'Model Alias', description: 'Which catalog model this reviewer uses (must match an alias from "Configure Models").', required: true, default: null, placeholder: 'reviewer-a', }), persona: Value.textarea({ name: 'Persona / Lens', description: 'How THIS reviewer should read the documents — its priorities and ' + 'weighting. Injected into its system prompt. e.g. "You are skeptical ' + 'legal counsel: weight liability, ambiguous obligations, and missing ' + 'clauses above everything." Leave empty for a neutral reviewer.', required: false, default: null, minRows: 3, maxRows: 16, placeholder: 'You are a financial-controls reviewer. Focus on numbers that do not ' + 'reconcile, unstated assumptions behind projections, and anything that ' + 'would concern an auditor. Organize findings by severity.', }), temperature: Value.number({ name: 'Sampling Temperature (optional)', description: 'Best-effort per-reviewer sampling temperature for extra diversity. ' + 'Persona is the primary lever. Leave empty to use the model default.', required: false, default: null, integer: false, min: 0, max: 2, }), }), }, ), ), }) export const configureReviewers = sdk.Action.withInput( 'configure-reviewers', async ({ effects }) => ({ name: 'Configure Reviewers', description: 'Define the review panel: which models and which personas, and how many reviews.', warning: null, allowedStatuses: 'any', group: null, visibility: 'enabled', }), inputSpec, async ({ effects }) => { const cfg = await configFile.read().const(effects) if (!cfg) return {} return { reviewers: cfg.reviewers } }, async ({ effects, input }) => { await configFile.merge(effects, { reviewers: input.reviewers }) return { version: '1', title: 'Panel Configured', message: 'Saved a panel of ' + input.reviewers.length + ' reviewer(s). Each model ' + 'alias must exist in "Configure Models". Set the rubric in "Configure ' + 'Review", then drop documents and run a review.', result: { type: 'single', value: input.reviewers.map((r) => r.name).join(', '), copyable: false, qr: false, masked: false, }, } }, )