npx moonpeak new my-app review| Part | File |
|---|---|
| View | src/resources/review/review.tsx, review.css |
| Tools | src/tools/plan-night.ts (model-visible, with View), src/tools/confirm-plan.ts (app-only) |
| Tests | tests/simulations/plan-night.json, confirm-plan.json, tests/e2e/review.spec.ts, tests/evals/review.eval.json |
The pattern
- The model calls
plan-nightwith a date and place. It returns a proposal (status: "proposed") with sky darkness and targets, and suggests a darker night when the moon is bright. - The View shows the proposal with Confirm plan and Pick another night.
- Confirm calls
confirm-planwithuseCallTool. That tool hasvisibility: ["app"], so hosts never offer it to the model: only the user's click can confirm. The View then tells the model withuseUpdateModelContext. - Decline posts a follow-up with
useSendMessage, asking for the darker night.
The decision is kept in useAppState, so a confirmed plan stays confirmed after a reload. Use the same shape for anything the model should propose but the user must approve: bookings, payments, sending email.