TaskSultan Docs tasksultan.com

Capabilities

Capabilities

The engines a Robot must provide, how an automation declares the ones it needs and what happens when the Robot cannot supply one.

TaskSultan keeps every engine a Robot can drive behind a declared Capability. An automation does not open a browser or a workbook itself. It declares which engines it needs and calls a facade the Robot provides. That keeps generated automations small. It also lets the Orchestrator place a job only on a robot that can actually run it.

#The declared list

RobotCapability (framework/types.ts) is a closed union of eight tokens:

Capability The facade the Robot provides
web ctx.page, ctx.browser, ctx.context (Playwright)
excel ctx.excel
files ctx.files
api ctx.api
database ctx.db
email ctx.email
pdf ctx.pdf
desktop ctx.desktop

The list is closed on purpose. A token that is not in the union does not compile, which is how the platform keeps its vocabulary honest.

#How an automation declares what it needs

Each automation carries a capabilities array in its defineAutomation call. The array is optional, but a capability that gates a facade has to be declared or the facade refuses by name.

import { defineAutomation } from '../framework';

export default defineAutomation({
  id: 'process-orders-excel',
  displayName: 'Process orders (Excel queue)',
  capabilities: ['web', 'excel'],
  url: 'http://localhost:4300',
  getTransaction: async (ctx) => null,
  processTransaction: async (ctx, tx) => {
    await ctx.page.goto('/orders');
    const table = await ctx.excel.readTable('orders.xlsx');
    ctx.log.info(`Read ${table.rowCount} rows`);
  },
});

#What happens when the Robot cannot provide one

There are two refusal points and they fire at different times.

The first is placement. The declared capabilities travel into the packaged manifest (runtime/packager.ts writes capabilities: def.capabilities ?? []) and the Orchestrator's dispatcher will not place a job on a robot that does not declare them. The refusal names what was missing:

no eligible robot for capabilities [web, excel]

For desktop the message is longer, because a desktop run needs a robot sitting on an interactive session. The dispatcher says so rather than leaving the operator to guess.

The second is at the facade. When a run reaches a facade the Robot did not supply, the facade throws a SystemException carrying a stable code rather than returning an empty answer. For files, email, api, database, pdf and desktop there are two codes, because there are two ways to arrive at a facade with no engine behind it:

  • *_NOT_DECLARED when the automation never listed the capability;
  • *_UNAVAILABLE when it did declare it but the Robot supplied no provider.

So DESKTOP_NOT_DECLARED, FILES_NOT_DECLARED and the rest sit beside DESKTOP_UNAVAILABLE, FILES_UNAVAILABLE and the rest.

Two capabilities do not follow that shape. web is always present, because the runner launches the browser itself, so there is no WEB_NOT_DECLARED code. excel has a single code, EXCEL_UNAVAILABLE: the runner does not check the declaration before supplying the facade. A bare runner with no Robot refuses with that one code.

#Things that catch people out

Declaring a capability you do not use is harmless. Not declaring one you do use is not. A ctx.files call in an automation whose capabilities array omits 'files' fails with FILES_NOT_DECLARED, even though the TypeScript looks fine and nothing else about the file changed.

That refusal is the product working. A facade that returned an empty workbook, or a control with no name, would turn a missing engine into a green run with no evidence. A run that guesses is a run you cannot put in front of an auditor.