evoke

How a sentence you type becomes a program call.

A reflex is a small program you install and ask for in your words. This page follows one natural-language command to the program it runs. A classifier reads the sentence, and a bar set by what the program changes decides whether it runs, asks you first, or stops.

A reflex

01

A reflex brings its program and the words to ask for it.

A reflex is a program with a manifest, reflex.toml, beside it. The manifest states what the program does, what it is not for, which inputs it takes, and how careful to be. The classifier reads these words. The program receives the values of its inputs.

contact/reflex.tomlby the author
reflex = 1

description = """
Look up a person's email address in the team directory.
One person at a time; prints the address."""

not_for = ["writing to anyone", "phone numbers", "adding a person to the directory"]
tags    = ["people"]
effect  = "read"
confirm = "Look up {name}'s address?"
run     = "contact.mts"

[args.name]
ask   = "Whose address?"
vocab = "people"

[yields]
email = "email"

[examples]
"look up dana's address"    = {}
"what is sam's email"       = {}
"find the address for dana" = {}
description · not_for
What it is for, and what it is not. A plain description, and the near misses it must turn down.
effect
How careful to be. The author declares read, write or destructive. A read needs less certainty to run than a write, and a destructive one always asks. You can make it stricter, never looser.
confirm
Its own question. The line you answer when evoke wants your yes first.
run
The program that runs. A file its author wrote, or a command you already use. Your sentence fills its inputs and never changes what runs.
[needs]
What it touches. The paths, the network and the programs the author declares; the kernel holds the program there. contact declares nothing, so it touches nothing but its own folder.
[args.name]
The input it takes. A word from people, a list you keep. Every input has one source: options the author listed, a word list you keep, a piece of what you typed, or a yes/no switch.
[yields]
What its result holds. An email address. A later step in the same sentence that needs one can take it.
[examples]
Sentences that show it in use. The classifier reads these too, with the description and the near misses.
See both manifests in the contact example →

contact is a stand-in from evoke's tests: it makes an address up from the name, and you cannot install it. You can install the collection's fifteen Mac reflexes, or write a reflex of your own.

Your sentence

02

Your sentence picks the reflex and fills its inputs.

The classifier is Jev, TypeSafe AI's model. evoke turns every installed manifest into closed questions and sends them all in one request. A sentence with «and» or «then» can make a few more. Jev answers each question with a probability, and evoke accepts only an answer from the choices it offered.

  1. 01Which reflex?One choice over every installed reflex, or none of them. Built from each description, its near misses and its examples.
  2. 02Which value?One choice per input: an option the author listed, a word from a list you keep, or a piece of your sentence taken word for word. Or «unstated».
  3. 03Is that all you said?The call is read back against your sentence. When it leaves part of it out, evoke asks you before anything runs.
evoke try
$ evoke try "kill the lights in the den"
  "kill the lights in the den"

  which reflex            lights 0.95   (none of them 0.03 · timer 0.01)
  room                    den 0.92   (not said 0.05 · office 0.03)
  state                   off 0.94   (on 0.03 · dim 0.02)
  holds all you said      0.90
  → runs: lights room="den" state="off"  0.92
a missing value
$ evoke "kill the lights"
  Which room?  [1] den  [2] office  [+] add one  [0] none of these  > 1
  lights room="den" state="off" · write · weakest: state 0.74
    a write runs at 0.90 or more
  Set the den lights off?  [y]es [n]o [t]each > t
+ overlays/lights.toml  [examples] "kill the lights" = { state = "off" }
den lights off
  1. 1«den» matched a word of yours. Rooms are a word list you keep, called a vocabulary. The classifier reads each word's meaning, and the program gets its value.
  2. 2«kill» meant off at 0.94. Off is an option the author listed. Without «in the den», the room was unstated, so evoke asked for it.
  3. 3Then evoke asked for a yes. Off got only 0.74 this time, under the bar for a write. Typing t answered yes and saved the phrase in a file of yours.
  4. 4Some things are never read from a sentence. A setting like a bridge address, or a secret, is set once with evoke config.

evoke try shows every answer and runs nothing. The lights reflex here comes from evoke's tests, and so do these lines, over answers written for those tests. Your own numbers will differ. Every judgment, explained →

If you know LLM function calling, this is the same step: a sentence becomes a call to your code. evoke adds three things. Every value is one the reflex allows, and every answer carries a probability. A bar set by what the program changes decides what runs without a question. Where evoke fits beside an LLM →

The gate

03

How sure evoke must be depends on what the program changes.

evoke guarantees that every value is one the reflex allows. It cannot guarantee that it read you right. That is why a bar, set by what the program changes, decides what runs without a question.

Each effect has its own bar. A decision's confidence is its weakest answer: the lowest probability among the reflex chosen and each of its values. Under 0.5 for the best reflex, nothing runs. A read runs without a question at 0.8 or more, a write at 0.9, and a destructive reflex always asks.
  1. RunAt or over the bar, with every required input stated. It runs on the classifier's reading, without a question. The call prints with its confidence, then the result.
  2. AskA required input was not stated, or a value fell outside its range. evoke asks the input's own question, then checks the bar again with your answer.
  3. Confirmevoke shows the call and waits for your yes: under the bar, or when the call leaves out part of what you typed. A destructive reflex always waits.
  4. StopNothing fits, and evoke abstains: the ranking prints and nothing runs. In a sentence of several steps, one part that fits nothing stops the whole sentence.

What a number means. The classifier's provider trains its probabilities to be calibrated: across many answers, those given 0.85 should be right about 85 times in 100. evoke shows every one, and evoke test checks your own sentences. You can read and change the bars in a file you own.

Every outcome, in the manual → See a restart ask first, even at 0.98

Approval set by what a program changes → Natural-language commands from a fixed list →

A handoff

04

One step's result can fill the next step's input.

One sentence can ask for several reflexes, and evoke shows the numbered plan before anything runs. When your words point back to an earlier step, and its result holds the kind of value a later step lacks, that value passes along.

The kinds match. «them» in the sentence points back to step 1. Its email field holds an address, and mail needs one for to.
evoke
$ evoke "look up dana's address and email them"
  1  contact name="dana"  0.95
  2  mail · takes email from 1
dana <dana@example.com>
  2  mail to="dana@example.com"  0.94
drafted to dana@example.com
  1. 1The plan comes first. Two numbered lines show each step, and what step 2 takes from step 1. A required input is filled with the value. An optional one is decided again, the value written into that step's words.
  2. 2No field is guessed. When two fields could fit, evoke stops and names them. When a step points back but takes nothing, evoke asks before anything runs. When a part matches nothing, evoke refuses the whole sentence.

A field of a result passes to a later step only when all of this holds.

A reflex can also return its whole result under a name, for a later reflex that takes that name: nothing points back, and nothing is asked.

contact and this mail are stand-ins from evoke's tests, and so are the numbers. The collection's mail opens a draft in your mail app, and nothing is sent. In the collection, download and screenshot yield the path they saved to, and note takes it.

Pass a result to the next step, in the contact example → The rule, in the manual

A branch

05

A result picks among the steps the author listed.

A playbook is a reflex whose body is a plan of sentences. A step may run only under a value an earlier step yields, and the author lists every such step right after it. The whole list prints before anything runs. The result picks, and a result never writes a step.

Five sentences, one plan. The check yields landing, and the two steps after it each name the value they run under. The one not chosen is skipped and says so.
~/runbook
$ evoke "drain the primary"
  1  drain  0.90 · runbook 1
  2  failover · destructive · weakest: route 0.90 · runbook 2
  3  verify  0.90 · runbook 3 · then 4 on "yes", 5 on "no"
  4  tell channel="#ops"  0.90 · runbook 4 · if 3 yields landing "yes"
  5  failback · destructive · weakest: route 0.90 · runbook 5 · if 3 yields landing "no"
Run the failover runbook?  [y]es [n]o [t]each > y
primary drained
Promote the replica now?  [y]es [n]o [t]each > y
replica promoted
writes landing on the new primary
told #ops
  5  failback · skipped · not chosen: step 3 yielded landing "yes"
  1. 1A closed list. The author wrote both branches, and the plan shows each with the value it waits on. A value no step lists picks nothing, and the plan goes on.
  2. 2Every step is gated on its own. The failover cannot be undone, so it asks at its turn whatever the yes over the whole plan said.

View the runbook example →

Your words

06

Your names and phrases stay in your files.

A vocabulary is a word list you keep, like rooms or people, and each word has a meaning the classifier reads. An overlay holds your phrases for one reflex. Both sit on top of the shipped manifest, and an update keeps them.

Your files change wording, never the program. An overlay adds and replaces wording. It cannot change what runs, which inputs exist, or where their values come from. If your file does not parse, the reflex sits out every decision until you fix it. It never becomes looser.
evoke show
$ evoke show lights
  description = "Turn the lights in one room on, off, or dim them.\nCeiling and lamp lights only."
  …
  [args.state]
+ ask = "On, off or dim?"
  options.on = "Switch on."
  …
  [examples]
  "turn on the kitchen lights" = { state = "on" }
+ "kill the lights" = { state = "off" }
  1. 1A + marks a line of yours. Teach one with evoke teach, or answer t when evoke asks for a yes. You can also edit the file by hand.
  2. 2An update never overwrites your files. It lists what changed, takes the author's new wording where you had none, and keeps yours where you had some.

The lights reflex here comes from evoke's tests. You cannot install it.

Teach evoke your words, in the manual → Service names as a word list: the ops example

Your application

07

What stays yours to decide.

evoke decides which call a sentence means, and whether it may run without a question. Four things stay with you and your application.

Read the security manual → Read the privacy policy

Questions

Requests, running by name, and changing the bars.

How many requests does one sentence make?

A sentence that asks for one thing is one request, carrying every question at once. When it has a word like «and» or «then», one request first asks whether each such word joins two steps. With three steps or more, another may ask which step a word like «them» points to. Then each step is one request, and a step decided again with a value from an earlier step makes one more.

At the terminal, a sentence you repeat, with the same reflexes installed, is answered from a local cache without a request.

How a sentence with several steps is read →

Can I run a reflex without the classifier?

Yes. evoke run takes a call you write yourself, like evoke run power action=restart, and asks no classifier. Every value is still checked, so a word missing from your list or a number out of range is refused. A destructive reflex still asks for your yes.

Running by name, in the manual →

Can I change the bars?

Yes. The defaults are 0.5 to pick a reflex at all, 0.8 for a reflex that only reads, and 0.9 for one that writes. You can raise or lower them for your machine in evoke.toml. A read's bar can never be higher than a write's, and nothing lets a destructive reflex run without your yes.

The bars, in the manual →

Every reflex you install is one more thing you can ask for.

Install evoke, add the collection's fifteen reflexes for the Mac, and type a sentence of your own. On Linux, start with a reflex that wraps a command you already use. evoke try shows a decision without running it.