jevrecipes

Recipe catalog / finger-actions

Choose an action for every finger

On beat, which listed option should each finger in fingers take, given music and style, or rest?

A playing loop advances one subdivision at a time and wants every finger to pick from its own reachable options in a single call.

Explore this recipe interactively ยท Source and implementation guide

Use finger-actions in TypeScript

Install with npm install jev-recipes. Requires Node.js 22.9 or newer and ES modules. Set TYPESAFE_API_KEY in your server environment for live calls, which send input to TypeSafe and use API quota. See the installation guide.

import { fingerActions } from 'jev-recipes/finger-actions';

const result = await fingerActions({
  "music": "Key C major, 72 bpm, gentle ballad. Last bar: right hand melody E4 D4 C4 (quarter, quarter, half) over a C major chord held in the left hand. The phrase just ended on the tonic.",
  "beat": "Bar 5, eighth 1, start of a new phrase",
  "fingers": [
    {
      "id": "rh-thumb",
      "text": "Right thumb, resting on C4, free to move",
      "options": [
        {
          "id": "c4",
          "text": "Press C4 to restate the tonic"
        },
        {
          "id": "hold",
          "text": "Keep C4 sounding from the previous bar"
        }
      ]
    },
    {
      "id": "rh-index",
      "text": "Right index, hovering over D4 and E4",
      "options": [
        {
          "id": "e4",
          "text": "Press E4 to start the melody a third above"
        },
        {
          "id": "d4",
          "text": "Press D4 to start stepwise"
        }
      ]
    },
    {
      "id": "lh-pinky",
      "text": "Left pinky, on C3 which is currently sounding",
      "options": [
        {
          "id": "c3",
          "text": "Re-strike C3 for a fresh bass note"
        },
        {
          "id": "g2",
          "text": "Move down to G2 for a dominant pedal"
        }
      ]
    }
  ],
  "style": "Keep the texture sparse; melody on top, single bass notes below.",
  "minConfidence": 0.8
});
console.log(result);

Input contract

FieldTypeNeeded
musicstringRequired
beatstringRequired
fingersarrayRequired
stylestringOptional
minConfidencenumberOptional
Full input and result schemas
{
  "input": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "music": {
        "type": "string"
      },
      "beat": {
        "type": "string"
      },
      "fingers": {
        "minItems": 1,
        "maxItems": 20,
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "text": {
              "type": "string"
            },
            "options": {
              "minItems": 1,
              "maxItems": 50,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "text"
                ]
              }
            }
          },
          "required": [
            "id",
            "text",
            "options"
          ]
        }
      },
      "style": {
        "type": "string"
      },
      "minConfidence": {
        "type": "number",
        "minimum": 0,
        "maximum": 1
      }
    },
    "required": [
      "music",
      "beat",
      "fingers"
    ]
  },
  "result": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "model": {
        "type": "string"
      },
      "usage": {
        "type": "object",
        "properties": {
          "input_tokens": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "output_tokens": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "input_tokens",
          "output_tokens"
        ],
        "additionalProperties": false
      },
      "status": {
        "type": "string",
        "enum": [
          "ready",
          "review"
        ]
      },
      "assignments": {
        "minItems": 1,
        "maxItems": 20,
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "status": {
              "type": "string",
              "enum": [
                "ready",
                "review"
              ]
            },
            "verdict": {
              "type": "string",
              "enum": [
                "chosen",
                "rest",
                "ambiguous"
              ]
            },
            "action": {
              "type": [
                "string",
                "null"
              ]
            },
            "suggestedAction": {
              "type": [
                "string",
                "null"
              ]
            },
            "confidence": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            },
            "probabilities": {
              "type": "object",
              "properties": {
                "options": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  }
                },
                "rest": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                },
                "ambiguous": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                }
              },
              "required": [
                "options",
                "rest",
                "ambiguous"
              ],
              "additionalProperties": false
            }
          },
          "required": [
            "id",
            "status",
            "verdict",
            "action",
            "suggestedAction",
            "confidence",
            "probabilities"
          ],
          "additionalProperties": false
        }
      }
    },
    "required": [
      "model",
      "usage",
      "status",
      "assignments"
    ],
    "additionalProperties": false
  }
}

Saved example result

This hand-authored response demonstrates the contract. It is not a model accuracy measurement. Run it without an API key: npx jev-recipes demo finger-actions.

{
  "model": "demo-fixture",
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0
  },
  "status": "ready",
  "assignments": [
    {
      "id": "rh-thumb",
      "status": "ready",
      "verdict": "rest",
      "action": null,
      "suggestedAction": null,
      "confidence": 0.84,
      "probabilities": {
        "options": {
          "c4": 0.08,
          "hold": 0.06
        },
        "rest": 0.84,
        "ambiguous": 0.02
      }
    },
    {
      "id": "rh-index",
      "status": "ready",
      "verdict": "chosen",
      "action": "e4",
      "suggestedAction": "e4",
      "confidence": 0.86,
      "probabilities": {
        "options": {
          "e4": 0.86,
          "d4": 0.1
        },
        "rest": 0.03,
        "ambiguous": 0.01
      }
    },
    {
      "id": "lh-pinky",
      "status": "ready",
      "verdict": "chosen",
      "action": "c3",
      "suggestedAction": "c3",
      "confidence": 0.9,
      "probabilities": {
        "options": {
          "c3": 0.9,
          "g2": 0.06
        },
        "rest": 0.03,
        "ambiguous": 0.01
      }
    }
  ]
}

Evaluation evidence

Fixture only

No verified live accuracy measurement is available. Evaluate representative cases before using this decision in your workflow.

Use the evaluation guide to measure this decision on your own labeled cases.

Limitations

Related recipes