
Use vendor API definitions without another integration runtime
The vendor catalogue describes API operations as data: request methods, paths, inputs and authentication. Wildo’s executor uses those definitions to call the vendor.
Definitions come from open integration catalogues and can be supplemented with authored operations. Choose the vendor and action your product needs, then verify its account and request requirements.
Example — Post to a team channel
A Slack module includes an authored message operation alongside its imported definitions. The application calls that operation through the provider executor using its configured credential.
For engineers
The package exposes vendor subpaths, for example @wildo-ai/providers/slack, rather than a root barrel. Installing the package brings its definitions onto disk; importing a vendor does not eagerly evaluate the whole catalogue. The generated module records its source catalogue and revision.
Wonder CRM declares Slack with engineCapabilities: [], providerCapabilities: [] and protocols: ['REST_API']. That is intentional: the application addresses this REST provider directly rather than selecting it for an engine service slot. Install the package in the runtime owner, declare the scope, supply credentials and synchronize its runtime artifacts.
Call with an account and inspect the vendor result
This illustrative application-service body uses an injected ProviderOperationExecutorBackendService as executor and the current operation’s executionContext. channelId and messageText are application inputs. Slack must already be declared in this backend, with its account connected and permission to post to that channel. Import z from zod and the connection enums from @wildo-ai/external-connectors-models.
const response = await executor.execute(
{
providerRef: 'slack',
operationId: 'slack_post_message',
connection: {
ownerScope: ExternalProvider_Connection_OwnerScope.APPLICATION,
delegation: ExternalProvider_Connection_DelegationMode.SERVICE,
},
input: { channel: channelId, text: messageText },
},
executionContext,
);
const reply = z.looseObject({
ok: z.boolean(),
error: z.string().optional(),
channel: z.string().optional(),
ts: z.string().optional(),
}).parse(response.output);
if (response.status < 200 || response.status >= 300 || !reply.ok) {
throw new Error(`Slack did not accept the message: ${reply.error ?? response.status}`);
}
if (!reply.channel || !reply.ts) {
throw new Error('Slack accepted the request without a usable message reference');
}
const postedMessage = { channel: reply.channel, timestamp: reply.ts };
The explicit target uses the application’s account acting as a service; omitting connection has that same default. To spend a customer organization’s account, supply its authorized connection target instead. The execution context carries the caller’s authority; a provider reference alone does not choose a customer account.
Slack can report a rejected operation in a successful HTTP response. Its message API returns ok; the caller must inspect it. This operation has no declared output schema, so the example validates the reply before recording the remote message reference. A timeout is not proof that no message was posted: do not blindly repeat a write that may already have succeeded.
For a typed convenience client, createSlackClient(executor.forExecution(executionContext, { connection })) binds the same context and account. Its authored slackPostMessage method returns the vendor payload, without the status envelope; apply the same reply checks. Use executor.execute when the application needs both status and output.
Add operations through the authored supplement
Slack’s supplement contributes an operation the imported sources did not express as a callable HTTP endpoint:
Selected from slack.authored.ts; surrounding declarations and imports are omitted.
slack_post_message: {
operationId: 'slack_post_message',
domain: 'default',
method: API_HttpMethod.POST,
pathTemplate: '/api/chat.postMessage',
classification: ExternalOperation_Classification.WRITE,
summary: 'Posts a message to a channel, a direct message, or a thread.',
requestBody: { encoding: ProviderRestRequestBodyEncoding.JSON },
// `text` is optional at the wire because `blocks` may carry the whole message, but one of the
// two must be present. The vendor enforces that and answers `no_text`; declaring both required
// here would refuse a legitimate blocks-only post.
inputSchema: z.looseObject({
channel: z.string().describe('Channel, private group, or user id to post to (e.g. C1234567890).'),
text: z.string().describe('Message text. Fallback text when `blocks` is used.').optional(),
blocks: z.array(z.looseObject({})).describe("Slack Block Kit blocks. Takes precedence over `text` for rendering.").optional(),
thread_ts: z.string().describe('Timestamp of the parent message, to reply in its thread.').optional(),
reply_broadcast: z.boolean().describe('Also send a threaded reply to the channel.').optional(),
unfurl_links: z.boolean().describe('Whether to unfurl posted links.').optional(),
}),
},
The same entry declares its input schema; the supplement’s authoredClient exposes a typed method delegating to ProviderOperationExecute. It accepts a channel and message content and calls the stable slack_post_message operation ID. This is an existing authored declaration, not evidence that a message was sent in this website review.
Keep regeneration separate from corrections
Generated files are replaced by transposition. A missing endpoint belongs in the transposer/source or an authored supplement, not a manual patch of the generated operation file. The catalogue record preserves identity decisions and records refused or pending operations when an address cannot be established.
The imported integration projects are read as sources; their executable integration packages are not installed as this runtime’s clients. Wildo, its dependencies and any authored supplement remain software to review. Transposition is not a claim of zero supply-chain risk or complete vendor API coverage.