Skip to content
Pilotoo
v0.1

Agent tools

Connected services reach an agent through two registered tools, not through one function definition per provider tool. That keeps the model’s tool list small however many providers a tenant enables.

PilotooModule.forRoot({
connections: { providers: [githubProvider()], tools: true },
});

Both tools register as opt-in. An agent with tools: null does not get them; one that names them does:

tools: [connections_search, connections_execute]

The names are also exported as CONNECTION_TOOL_NAMES. Without storage or an encryption key the tools are not registered at all. See Tools for how definitions select tools.

Argument Rule
query Required, 1 to 200 characters of keywords, such as list issues.
provider Optional provider id to restrict the search.
limit 1 to 20, default 8.

It answers { ok: true, results }, best match first. Each result holds name (qualified), description, access, provider, connected, status when a connection exists, accounts, the JSON schema of the arguments as parameters, and a hint when the caller is not connected, telling the model to ask the user (or an administrator, for an organisation account) to connect or reconnect.

accounts lists the accounts the caller may use for that tool, each as { id, label, scope, default, status }: their own, then the organisation’s whose sharing admits the caller’s roles. scope is user or tenant.

Ranking is deterministic keyword matching over the qualified name, tool name, description and provider text. Only tools the caller may use appear: the caller needs a connection role, the provider must be enabled for the tenant, and the tool must pass the tenant’s tool settings: in allowedTools when set, matching one of includeTools when that list is not empty, and matching none of excludeTools (patterns over the provider’s unqualified tool names, * matching any run of characters, such as ticket_* or *_delete).

Argument Rule
name The qualified name from search, <provider>__<tool>.
arguments An object matching the tool’s schema.
account Optional. A connection id, account id or label from the search result. Without it the call runs on the caller’s default account, else on the organisation’s default the caller may use.

The server then:

  1. Finds the tool and checks policy: role, provider enabled, tool allowed, connection scopes, and the organisation account’s sharing rules.
  2. Parses arguments with the tool’s zod schema.
  3. Resolves the caller’s credential, refreshing it first when it is near expiry.
  4. Runs the tool under a deadline (CONNECTIONS_TOOL_TIMEOUT_MS, default 30000).
  5. On a provider 401, refreshes once and retries once.
  6. Returns { "ok": true, "result": ... }, and writes an audit row.

The identity comes from the run’s context, never from the model’s arguments, so one cached agent graph serves every caller safely.

A result longer than CONNECTIONS_TOOL_RESULT_MAX_BYTES (default 32768) is cut at a character boundary and returned as { ok: true, truncated: true, originalBytes, result }.

Failures are returned, not thrown:

{ "ok": false, "error": { "code": "not_connected", "message": "You are not connected to github." } }
code Meaning
forbidden No connection role, tool not allowed, or the connection lacks a required scope.
provider_disabled The tenant has not enabled the provider.
not_found No tool has that name.
not_connected The caller has no connection to the provider.
needs_reauth The connection stopped working; the user must reconnect.
invalid_arguments Arguments do not fit the schema; error.issues lists them.
tool_failed The provider answered an error; error.status carries the HTTP status.
timeout The tool did not finish before the deadline.

Provider error text is truncated to 300 characters and has the caller’s tokens replaced by [redacted] before the model sees it.

The same two tools can answer from a remote source. With several sources, tool names and account ids carry a <source>: prefix, and a search answer may add an unavailable array naming the sources that were skipped.

Every connections_execute call appends a tool_call audit row with the qualified name, outcome, error code, duration and the argument names only. Argument values are never recorded. A run on an organisation account is audited under the real user as the actor, with no owner.