Shadway

Reference / Built-in capabilities

Built-in capabilities

A capability is one thing an agent can do. Shadway comes with built-in capabilities for common work, and you can add your own with a set input and output.

Built-in capabilities run on Shadway's own systems. You grant them and set limits, and Shadway handles the providers, the credentials, and the retries. Names describe the action, not the vendor: email.send says what happens, not who does it.

Available capabilities

CapabilityWhat it doesEffect
email.sendSend an email from the agent's own addresswrite
email.get_deliveryCheck the delivery status of a sent emailread
mailbox.read_threadRead a conversation in a connected mailboxread
mailbox.sendSend a new message from a connected mailboxwrite
mailbox.replyReply within an existing conversationwrite
phone.callPlace an outbound phone callwrite
phone.get_callCheck the status and outcome of a callread
browser.runRun a browsing task in a managed browserwrite
browser.get_runCheck a browser run's progress and resultread
browser.cancel_runCancel a running browser taskwrite

email and mailbox differ in whose address the mail comes from. email.send uses the agent's own address. The mailbox actions use a mailbox that a person connected, like their Gmail or Outlook, and send as that person.

Listing capabilities can return more than this table shows. Some actions are listed but can't run yet, and they show executionMode: "unavailable" (mailbox.search and mailbox.get_attachment are like this today). Check executionMode instead of assuming a listed name can run.

list-capabilities.ts
for await (const capability of shadway.capabilities.list()) {
  if (capability.status === "active" && capability.executionMode === "available") {
    console.log(capability.name, "-", capability.description);
  }
}

Configure a capability

capabilityConfig on the agent sets options for capabilities the agent already has. It never grants a capability. An entry here does nothing on its own without the grant.

configure.ts
const updated = await shadway.agents.update(agent.id, {
  capabilities: ["email.send", "email.get_delivery", "phone.call", "phone.get_call", "phone"],
  capabilityConfig: {
    phone: { country: "US", areaCode: "302" },
  },
});

The phone entry in the agent's capability list is what tells Shadway to get a phone number, and it holds the settings for it. The dotted action names are what a mandate can actually grant.

  • Phone: country (a two-letter country code) and areaCode say what kind of number you'd prefer. resource uses a number you already have instead of getting a new one.
  • Browser: model on the browser key runs browser work on a different model, which has to handle images and tools. Leave it out and browser work uses the default.

Getting a resource ready takes time. After you create or update an agent, read it back and check capabilityStatus. Each entry is provisioning, requires_action, ready, unavailable, or failed, with a detail for anything that isn't ready. Phone goes through real setup and shows its number once it's ready. A capability that has nothing to set up is ready as soon as the agent has it. A connected mailbox's health shows up on its source, not here, so check the workspace's sources if mailbox actions start failing.

Define your own capability

Your own capabilities work the same way as built-in ones: a dotted name, input and output schemas, and a declared risk, effect, verification, and idempotency. For a step-by-step, see Define your own capability.

Registering only defines the capability. In the current preview, capabilities you host yourself can't run. A registered capability stays executionMode: "unavailable" until something is set up to run it, and mandates can't grant it before then.

Continue building

On this page