Reference

refine_project

Change a saved project in words: one bounded agent turn that commits exactly once.

View as Markdown

What it does

  • Writes
  • Destructive
  • Account required

Conversational editing of a project that already exists. You pass the project, the change the user asked for, optionally what they had selected, and optionally screenshots the change needs. A supported request commits once and returns the diff that was actually committed. Ambiguity, an unsupported intent, a concurrent edit or a failed pass each return their own outcome with nothing partially saved. It returns no pixels — call render_project afterwards to see the result.

You can ask: “Give the Tidebook project a warmer background.”

A change that needs NEW pixels — swap this screen, add the checkout screen — takes them in attachments as refs from import_screenshot or request_screenshot_upload, at most ten. Bytes are not accepted here: get them into the account first, then name the ref. A placed screenshot replaces the one it displaces, which stays recoverable until the project is cleaned up, and the ref itself never reaches the Agent — it sees only the name.

Annotated destructive because a committed refine rewrites the saved project. The commit is all-or-nothing: there is no half-applied state to clean up.

A request about COMPOSITION — crop the phone, give the headline more room, make it store-ready, make it stand out — comes back as a change of layout template, not as hand-set placement numbers. The template is chosen on the same character axis describe_look returns, so the answer matches what the web app would have done with the same words.

Placement sent alongside a layout OVERWRITES it. The template expands first and explicit device or caption fields are applied after, which is how you say "that composition, but a bit lower" — and why sending both without meaning that silently loses the template.

Input

  • projectstringoptionalat least 1 character

    Which ShotOps project to target: its id (as returned by read_look/save_project), OR its NAME as the user says it — matched exactly, ignoring case and surrounding spaces. Omit = your most recently edited project. A name that matches none or several is refused with the account's projects listed, never resolved by guessing.

  • instructionstringrequiredat least 1 characterat most 1200 characters

    The change to make. One call runs one bounded Agent turn and commits at most once.

  • focusone of 4 shapesoptional

    The selected project, frame, device, or caption this instruction refers to. Omit for the whole project.

    1kind

    • kindstringrequiredalways "project"

    • labelstringrequiredat least 1 characterat most 180 characters

    2kind

    • kindstringrequiredalways "frame"

    • frameIdstringrequiredat least 1 characterat most 180 characters

    • labelstringrequiredat least 1 characterat most 180 characters

    3kind

    • kindstringrequiredalways "device"

    • frameIdstringrequiredat least 1 characterat most 180 characters

    • deviceIdstringrequiredat least 1 characterat most 180 characters

    • labelstringrequiredat least 1 characterat most 180 characters

    4kind

    • kindstringrequiredalways "caption"

    • frameIdstringrequiredat least 1 characterat most 180 characters

    • captionIndexintegerrequiredmin 0max 32

    • labelstringrequiredat least 1 characterat most 240 characters

  • attachmentsarrayoptionalat most 10 items

    Screenshots this turn may place — refs from import_screenshot or request_screenshot_upload, at most 10. Pass them for an instruction that supplies new pixels ("use this as the second screen", "swap the checkout screenshot"); an instruction that only restyles needs none. A placed screenshot replaces the one it displaces, which stays recoverable until the project is cleaned up.

    each item

    object

    • refstringrequiredat least 1 character

    • namestringoptionalat most 200 characters

      The screenshot's original filename (e.g. "03_statistics.png"). Pass it so that, if this render is saved as a project, the user's own screenshots folder re-loads exactly this file by name. Optional if the ref already carries a name (from request_screenshot_upload({ names })); omit entirely and the record falls back to a positional name (screen-N.png).

Result

  • okbooleanoptional

  • turnIdstringoptional

  • projectIdstringoptional

  • outcomeobjectoptional

    • statusstringrequired

      one ofappliedapplied_with_remainingalready_satisfiedneeds_clarificationneeds_assetunsupportedfailedcancelledconflict

    • reasonstringoptional

    • headlinestringrequired

    • detailstringoptional

    • capabilityIdstringoptional

    • changedarrayrequired

      each item

      string

    • remainingstringoptional

    • questionstringoptional

    • nextStepobjectoptional

      • kindstringrequired

      • labelstringrequired

  • changedarrayoptional

    The actual committed project diff; empty when nothing was written.

    each item

    string

  • broaderChangesarrayoptional

    each item

    string

  • remainingstring or nulloptional

  • committedbooleanoptional

  • recordVersionnumberoptional

  • usageobjectoptional

    • inputTokensnumberrequired

    • cacheReadTokensnumberrequired

    • imageTokensnumber or nullrequired

    • outputTokensnumberrequired

    • totalTokensnumberrequired

  • allowanceobjectoptional

    • remainingnumber or nullrequired

    • refundednumberrequired

    • settledbooleanrequired

Example

That request maps to this call:

{
  "name": "refine_project",
  "arguments": {
    "project": "Tidebook 2.4 launch",
    "instruction": "Warm the background up and make the headlines two lines instead of four"
  }
}

The committed diff, or a typed outcome explaining why nothing was committed.

Access and cost

  • Needs an account. Not available to an anonymous hosted caller.
  • This is the one tool that spends model tokens rather than render cloud credits. The daily ceiling and burst limits live in the monetization policy, not in this page.

When it refuses

The outcome says the request was ambiguous.
Nothing was saved. Ask the user the question the outcome names and call again with the answer folded into the request.
The outcome says a concurrent edit landed first.
Somebody edited the project mid-turn. Read it again and re-issue the request.
The outcome says the intent is unsupported.
The change is outside what a bounded turn can do. Do it in the web app, or express it as a look you compose yourself and save with save_look.
The outcome says the change needs a screenshot and none was supplied.
Nothing was saved. Get the pixels into the account first with import_screenshot or request_screenshot_upload, then call again passing the ref in attachments.
The call is refused because a supplied screenshot is not available to this project.
The ref is not one this account can place here. Re-import the screenshot and use the ref that call returns. No model tokens were spent.

Where this fits

What the agent is told

The title and description the server publishes on tools/list — this is the copy a model chooses between, reproduced verbatim.

Refine a saved project

Edit an existing ShotOps project conversationally through one bounded Agent turn. Pass the project id or exact name, the requested change, and optionally the selected frame, device, or caption as focus. A change that needs new pixels — swap this screenshot, add the checkout screen — passes them in attachments as refs from import_screenshot or request_screenshot_upload. A supported request commits exactly once and returns the actual committed diff. Ambiguity, missing input, unsupported intent, a concurrent edit, or a failed pass returns its own typed outcome with no partial project saved. This changes the saved project but returns no panel pixels; call render_project afterwards to see or export the result.