Plug-In: AFM • Prompt for Array Response

REQUIRES: macOS 26, iOS 26, iPados 26, visionOS 26 • OmniFocus 4.8

This plug-in template demonstrates how to interact with the on-device Apple Foundation Model (AFM) through an Omni Automation plug-in.

The plug-in accepts a user-provided natural languageA human written or spoken language as opposed to a computer language. prompt for the AFM that requests the response as a simple array of either strings (text), integers, or decimal values, depending upon the option chosen by the user.

(New to creating Omni Automation plug-ins?)

The prompt, combined with a corresponding JSON schema (see below), is passed to a new AFM session instance, and a data array is returned as the value of a “result” property of the response JSON object.

Schema for Response


{ name: "array-schema", properties: [ { name: "result", schema: { arrayOf: { type: "string" } } } ] }

Example prompts:

prompt for array dialog Automation Console window showing the result
AFM • Prompt for Array Response
  
/*{ "type": "action", "targets": ["omnifocus","omnioutliner","omniplan","omnigraffle"], "author": "Otto Automator", "identifier": "com.omni-automation.all.prompt-for-array", "version": "1.0", "description": "A template for prompting the Apple Foundation Models to return data as an array of strings, integers, or decimals.", "label": "AFM • Prompt for Array Response", "shortLabel": "AFM • Array Response", "paletteLabel": "AFM • Array Response", "image": "apple.intelligence" }*/ (() => { // DECLARE PREFERENCES INSTANCE var preferences = new Preferences() // NO ID = PLUG-IN ID const action = new PlugIn.Action(async function(selection, sender){ try { // RETRIEVE PREVIOUSLY STORED PROMPT textPrompt = preferences.readString("textPrompt") if(!textPrompt){ textPrompt = "Provide as an array of XXXXX, …" } // CREATE FORM FOR GATHERING USER INPUT inputForm = new Form() // CREATE TEXT FIELD textField = new Form.Field.String( "textPrompt", "Prompt", textPrompt ) // CREATE MENU popupMenu = new Form.Field.Option( "arrayTypeIndex", "Array Type", [0,1,2], ["String", "Integer", "Decimal"], 0 ) // ADD THE FIELDS TO THE FORM inputForm.addField(textField) inputForm.addField(popupMenu) // VALIDATE THE USER INPUT inputForm.validate = function(formObject){ textValue = formObject.values["textPrompt"] textStatus = (textValue && textValue.length > 0) ? true:false return textStatus } // PRESENT THE FORM TO THE USER formPrompt = "Enter prompt and choose data type:" formObject = await inputForm.show(formPrompt, "Continue") // PROCESSING USING THE DATA EXTRACTED FROM THE FORM prompt = formObject.values["textPrompt"] preferences.write("textPrompt", prompt) arrayTypeIndex = formObject.values["arrayTypeIndex"] // CHOSEN SCHEMA schemata = [ {name:"array-schema",properties:[{name:"result",schema:{arrayOf:{type:"string"}}}]}, {name:"array-schema",properties:[{name:"result",schema:{arrayOf:{type:"integer"}}}]}, {name:"array-schema",properties:[{name:"result",schema:{arrayOf:{type:"decimal"}}}]} ] chosenSchema = schemata[arrayTypeIndex] // LOG USER INPUT console.log("prompt", prompt) console.log(JSON.stringify(chosenSchema, 0, 2)) // QUERY THE APPLE LANGUAGE MODEL schema = LanguageModel.Schema.fromJSON(chosenSchema) session = new LanguageModel.Session() responseStr = await session.respondWithSchema(prompt, schema); response = JSON.parse(responseStr) // LOG RESULT console.log(response.result) } catch(err){ if(!err.causedByUserCancelling){ console.error(err.name, err.message) new Alert(err.name, err.message).show() } } }); action.validate = function(selection, sender){ targetVersion = new Version("26") return (Device.current.operatingSystemVersion.atLeast(targetVersion)) }; return action; })();