Agents with shell tools can run commands that range from harmless to destructive. Reading release notes and deleting a file both fit the same input schema, but only the first should run without confirmation. Requiring a person to approve every call slows the agent down, while running every call without review leaves destructive commands unchecked. Approval rules based only on the tool name can't distinguish a routine read from a deletion.
eve lets Jev, a decision model from TypeSafe AI, review each proposed tool call before it runs. When you add approval: auto() from eve/tools/approval to a tool, Jev classifies the call as clear or caution. eve runs a clear call without a prompt and pauses a caution call until a person approves or rejects it, so the review happens before the executor receives the command.
Copy link to headingOverview
In this guide, you'll learn how to:
- Add a Jev review to eve's sandbox
bashtool so proposed commands are classified before they execute - Define
clearandcautioncriteria so routine calls run automatically and other calls require human approval - Approve or reject pending tool calls in eve's terminal UI and verify the result against disposable sandbox files
- Unit-test the approval policy with a mock evaluation model
Copy link to headingPrerequisites
Before you begin, make sure you have:
- A Vercel account.
- Vercel CLI installed (
npm i -g vercel) - Node.js 24+ and a package manager (e.g., pnpm)
Copy link to headingHow Jev differs from a language model
Jev is a probabilistic decision model, not a chat model. It evaluates supplied state against typed questions and returns choices, scores, and boolean probabilities without generating prose. Language models can also produce a structured "allow" or "ask" answer, but they do so through text generation, and any probability they report is itself a generated estimate.
For tool approval, this changes three things:
- The answer is a typed choice between fixed outcomes. eve maps
clearandcautiondirectly to approval statuses, with no prose to parse. - Jev returns probabilities alongside its choice. eve’s
auto()helper uses the selected option; applying a probability threshold requires a custom policy. - Jev generates no output tokens, so the review adds an input-only classification call rather than a second generation step.
Copy link to headingHow automatic approval works
When the agent's language model proposes a tool call, eve runs the tool's approval policy before handing the call to its executor. With auto(), that policy asks Jev to review the tool name and arguments.
Under the hood, auto() uses the AI SDK's experimental_evaluate API to ask Jev one choice question with two options, clear and caution; the instructions and criteria you pass shape that question.
The helper maps the result to an approval status:
| Review result | Policy status | What happens next |
|---|---|---|
clear | approved | eve runs the tool without a human approval prompt |
caution | user-approval | eve pauses the call for a person |
| Failed review or invalid answer | user-approval | eve requests human approval instead of proceeding automatically |
The approval helper defaults to typesafe-ai/jev. It sends the tool arguments to the evaluation provider, so keep credentials out of those arguments and resolve them inside your application when an executor needs them.
Copy link to headingSteps
Copy link to heading1. Create and configure the eve project
Install the latest version of eve (0.62.0 or later):
pnpm dlx eve@latest init jev-tool-approvalsnpx eve@latest init jev-tool-approvalsyarn dlx eve@latest init jev-tool-approvalsbunx eve@latest init jev-tool-approvalseve init installs the project dependencies, including a compatible AI SDK version, and opens eve's terminal UI, where you can:
- Run
/loginand choose Vercel Account to sign in. The agent's language model and Jev both share this connection during local development. - Run
/exitto close the terminal UI.
Then open the project directory:
Replace agent/agent.ts with:
defaultTools: false removes the optional default tools but keeps the files you author under agent/tools/. Without it, another file-writing tool would stay available and bypass the review you're about to add to bash.
Replace agent/instructions.md with:
Create agent/sandbox/sandbox.ts:
The just-bash backend runs these commands against a virtual filesystem. eve installs the optional just-bash package during local development if it is missing.
Create two files to seed the sandbox.
Save this as agent/sandbox/workspace/notes/release.md:
Save this as agent/sandbox/workspace/scratch.txt:
At the start of a session, eve copies these files into the sandbox at /workspace/notes/release.md and /workspace/scratch.txt. Commands operate on those copies, so your project files are never touched.
Copy link to heading2. Define which commands need a person
Define a policy that lets commands inspect ordinary demo files automatically but requires human review when they make changes or have unclear effects:
The criteria define when a command can run automatically and when it needs human review, including compound commands that both read and modify files.
For example, cat notes/release.md && rm scratch.txt includes a deletion even though it starts with a read.
The two models have separate responsibilities:
- The language model configured in
agent.tsproposes commands. - Jev evaluates those commands against the approval criteria.
The model parameter defaults to Jev and lets tests substitute a mock evaluator.
Copy link to heading3. Add the policy to the bash tool
Create agent/tools/bash.ts and import the approval policy:
Spreading the built-in bash definition preserves its input schema and sandbox executor, while the approval field adds a policy check before each command runs. Naming the file bash.ts overrides eve’s default bash tool.
Copy link to heading4. Run the automatic and human approval paths
Start the development server from the project root:
pnpm devnpm run devyarn devbun devThe terminal UI accepts messages and displays pending approval requests. Send this prompt to exercise the read path:
Under the policy you defined, this command belongs in clear. Check that the tool runs without an approval prompt and returns the release-note content:
Then send a request that changes the sandbox:
The policy should classify the deletion as caution, prompting eve to request approval before the command runs.
Reject the request, then ask the agent to read the file to confirm it still exists:
The file should still contain its original text. Ask for the deletion again and approve the new request; eve resumes the pending call and runs the command. Reading the same path afterward should report that the file no longer exists.
These checks exercise both the classifier and the pause-and-resume behavior. If a command takes the wrong path, inspect the actual tool arguments and adjust the review criteria before enabling the policy on your own tools.
Use /reset to start a fresh session with new copies of the seeded files.
Copy link to heading5. Test the policy without calling Jev
Use fixed model answers to check how the policy handles approval and review. Keep these tests outside agent/tools/ so eve doesn't discover them as tools.
Add Vitest as a development dependency:
pnpm add -D vitestnpm install -D vitestyarn add -D vitestbun add -d vitestCreate tests/command-approval.test.ts:
The test context supplies the tool name and command for review. Its sandbox method throws if called, ensuring the approval tests do not execute commands. The mock answers use permission, matching the question ID in Eve’s automatic approval helper.
Run the tests:
pnpm vitest run tests/command-approval.test.tsnpx vitest run tests/command-approval.test.tsyarn vitest run tests/command-approval.test.tsbunx vitest run tests/command-approval.test.tsYou should see four passing tests: the clear and caution mappings, an evaluator failure, and a missing answer.
These verify the policy's response to fixed results. To assess Jev's decisions, also evaluate representative commands with known review requirements, including compound commands and inputs whose effects are unclear.
Copy link to headingKeep permissions enforceable in code
Tool approval is one part of Jev's role in an agent loop. The executor still controls which resources a command can access, and a classifier's decision cannot establish that the caller owns those resources.
Use always() from eve/tools/approval when a tool requires human approval on every call, and enforce access rules such as tenant isolation in application code before execution. When approval is restricted to specific people, add an approval response policy to check the responder’s identity.
The just-bash virtual filesystem keeps file operations separate from your project files. Before giving an agent access to external services, configure the backend's permissions and network controls for those services; a shell-command classifier cannot supply those restrictions.
Copy link to headingTroubleshooting
Copy link to headingauto is not exported
Check that the import comes from eve/tools/approval and that the project uses eve 0.62.0 or later. The auto export from eve/models selects the agent's language model and serves a different purpose.
Copy link to headingEvery command asks for approval
Failed evaluations take the human approval path. Verify the AI Gateway connection with /login, then check provider errors and the supplied tool arguments. If evaluations succeed, inspect whether the criteria make ordinary reads ambiguous.
Copy link to headingFile changes run without a prompt
Check which tool made the change, since the policy applies to the authored bash tool and other tools may use different approval rules. Confirm that defaultTools: false is set, then inspect any additional tools under agent/tools/. If bash made the change, add the exact command to your evaluation cases to investigate why it was approved.
Copy link to headingThe demo files are missing
Check the paths under agent/sandbox/workspace/, then start a fresh session with /reset. Seed files are copied when a session starts, so an existing session may still contain earlier changes or deletions.
Copy link to headingFrequently asked questions
Copy link to headingDoes Jev see the conversation when reviewing a call?
The built-in auto() helper evaluates the tool name and arguments, along with its classifier instructions and criteria. It doesn't automatically include the conversation or the tool executor's implementation. If a decision requires additional context, use a custom approval policy that supplies the relevant state.
Copy link to headingCan I set a probability threshold on auto()?
No. In eve 0.62.0, the helper accepts a model, instructions, and descriptions for clear and caution; it acts on the selected choice. For a numeric cutoff, call evaluate in a custom approval policy and map the result to an approval status.
Copy link to headingDoes approving one call approve later calls too?
With auto(), each proposed call receives a new review. The separate once() helper supports approval that carries forward within a session, so choose it only when that behavior matches the tool's policy.
Copy link to headingDo I need a separate TypeSafe AI API key?
No. Jev runs through your AI Gateway connection, so no additional credentials are needed. If you pass a direct provider's evaluation model instead, configure that provider's credentials as required by its SDK.
Copy link to headingNext steps
- Explore Route form submissions with Jev and AI SDK to assign incoming requests to teams, using Jev's confidence to decide when a fallback model should make the final assignment
- Read Classify, route, and score with Jev and the AI SDK to call
experimental_evaluatedirectly, mix choice, score, and boolean questions, and pick thresholds from probabilities and confidence - See Jev gate a different kind of action in Moderate product reviews with Jev, TanStack AI, and AI Gateway, which holds reviews for a moderator the way this guide holds tool calls for approval
- Read What is Jev, TypeSafe AI's System One model? and When should you use Jev? to find other decisions in your application that fit a typed question
- Explore other Jev use cases for AI applications, including selecting a response model and evaluating generated answers against your requirements
- Evaluate Jev's probabilities and choose a threshold using labeled submissions to measure routing errors and assess whether
0.95suits your workflow - Check the AI Gateway evaluation docs and the Jev model page for pricing, limits, and the Gateway provider instance
- Explore the AI SDK evaluation guide for the
evaluateAPI, question types, andExperimental_EvaluationMockModelV4for tests