Reference
Remy Reference/agent/defineJewel
?

defineJewel

Defines a jewel for a method, proposing its input and grading the proposal against what the human actually did.
defineJewel(method, { subject, propose, grade? }) → Jewel

Defines the jewel for one method, in a foo.jewel.ts file beside it, as three functions: subject projects the method's input down to what identifies the work, never the decision the human made; propose returns the input to submit, or null to abstain, with the deciding runTask transcript attached via trace; and an optional grade scores the proposal against what the human actually did. The jewel never writes anything, so the method's own auth and validation stay the only gate on its output. It runs as its own platform-managed user, and a failure inside subject or propose becomes an error on the pair record rather than breaking the app.

Parameters
method
JewelMethod
RequiredThe method this jewel shadows, imported by reference. Its input type is the jewel's output type.
subject
(input) => S
RequiredProjection from the method input to what identifies the work. Never the human's decision fields; handing the jewel the answer poisons every pair.
propose
(subject) => JewelProposal
RequiredArbitrary TypeScript returning { input, reasoning, trace? }. input: null is abstention. Throwing becomes an error on the pair, never a thrown exception.
grade
(ctx) => JewelVerdict
Optional. Scores { proposed, actual }; omit for a deep-equal on the method input. May be async and call a model.
A jewel (choose-one-of-N)
// dist/methods/src/categorizeRecord.jewel.ts
import { defineJewel, mindstudio } from '@mindstudio-ai/agent';
import { categorizeRecord } from './categorizeRecord';
import { getRecord, listCategories } from './common/records';

export default defineJewel(categorizeRecord, {
  subject: ({ recordId }) => ({ recordId }),          // never the decision
  propose: async ({ recordId }) => {
    const record = await getRecord(recordId);
    if (!record || record.category) return { input: null, reasoning: 'Nothing to categorize.' };
    const categories = (await listCategories()).map((c) => c.name);
    const task = await mindstudio.runTask({
      prompt: CATEGORIZATION_POLICY,
      input: { record, categories },
      tools: [{ appMethod: 'list-records', description: 'Precedent: how comparable records were categorized.' }],
      outputSchema: {
        type: 'object',
        properties: { category: { enum: [...categories, null] }, rationale: { type: 'string' } },
        required: ['category', 'rationale'],
      },
      model: 'claude-5-sonnet',
    });
    if (!task.output.category) return { input: null, reasoning: task.output.rationale };
    return { input: { recordId, category: task.output.category }, reasoning: task.output.rationale, trace: task.traceId };
  },
});