Functions
Let an agent request work implemented by your application.
On this page
Define a functionLoad functions on demandSearch argumentsContext and costHandle a required actionReturn the resultFunctions and MCPExecution boundary and recoveryFunctions and Dynamic WorkflowReceive function requests by webhookA function tool describes a callable operation. Your application executes that operation and sends its result back to the waiting Turn.
The API client can be your backend server; it does not have to be a browser or phone. The same result protocol applies to direct and scheduled Agent runs. Your server may use MCP, Composio, or another service internally without changing the Function contract exposed to Rebyte.
Define a function
Include a function definition in agent.tools:
const tools = [{
type: 'function',
name: 'lookup_order',
description: 'Look up an order by its ID.',
parameters: {
type: 'object',
properties: { order_id: { type: 'string' } },
required: ['order_id'],
additionalProperties: false,
},
}];
Tools and MCP server labels must have unique names. The rebyte_ prefix and built-in names (exec_command, write_stdin, apply_patch, view_image, list_mcp_resources, list_mcp_resource_templates, read_mcp_resource, search_tools, call_tool, tool_search, run_code) are reserved.
Load functions on demand
Functions are visible to the model immediately by default. For a large tool set,
include { type: 'tool_search' } and mark selected functions with
defer_loading: true:
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.REBYTE_API_KEY,
baseURL: 'https://api.rebyte.ai/v1',
maxRetries: 0,
});
const agent = await client.beta.agents.create({
model: 'gpt-5.6-luna',
tools: [
{ type: 'tool_search' },
{
type: 'function',
name: 'lookup_order',
description: 'Look up an order and its delivery status by order ID.',
defer_loading: true,
parameters: {
type: 'object',
properties: { order_id: { type: 'string' } },
required: ['order_id'],
additionalProperties: false,
},
},
],
});
const session = await client.beta.agents.sessions.create({
agent_id: agent.id,
input: 'Look up delivery status for order 42.',
});
No environment is needed. You still send the complete definitions to Rebyte;
only their exposure to the model is deferred. Rebyte executes tool_search,
loads the selected definitions, and lets the model call the discovered function.
Your application then handles required_actions and returns the result as below.
You supply schemas, not executable code or a callback URL.
| Configuration | Behavior |
|---|---|
Omitted or false defer_loading | Function is available from the first model call. |
defer_loading: true with tool_search | Function becomes available after discovery. |
defer_loading: true without tool_search | Agent creation/update or Session override fails with HTTP 400. |
tool_search with eager functions | Eager functions stay visible; they are not searched. |
Discovery persists in that Session across Turns and client-result waits. It does
not load tools into another Session or modify the saved Agent. A Session
agent.tools override replaces the entire list, including the tool_search entry.
Search arguments
The model calls tool_search with exactly one of:
query: text ranked using BM25 over tool and parameter names/descriptions.pattern: a case-insensitive JavaScript regular expression over the same catalog.
limit is optional (default 5, maximum 20). A text query can be
{"query":"order delivery status","limit":3}; a regex query can be
{"pattern":"lookup_.*order","limit":3}. The model chooses which mode to use;
there is no embedding job or secondary model call for ranking. Text queries are
limited to 500 characters; regex patterns to 200, with a 500 ms execution deadline.
An empty result loads nothing. BM25 matches words, so use the language of the
function descriptions rather than assuming translation or synonym expansion.
Context and cost
Defer less frequently used tools and keep a small, commonly used set eager. Discovery adds model steps, and discovered definitions remain available in later Turns. It can reduce initial context, but does not guarantee lower total tokens, latency, or cost. Measure a complete workflow, including cached input tokens. Rebyte avoids repeating discovered schemas in later search-result history.
The opt-in configuration and client handoff follow the OpenAI Agents API. Rebyte implements BM25/regex search; ranking and provider prompt-cache placement are not promises of identical OpenAI internal behavior.
The SDK already accepts these request fields. Rebyte CLI 0.2.1 also includes the
resolved Session response type and CLI manifest support. See the runnable
deferred-functions recipe.
Handle a required action
When the model calls your function, the Session enters requires_action. Retrieve the Session or consume its events. Each function action includes turn_id, call_id, name, and arguments.
Validate the arguments, authenticate the operation for the current user, and execute your application handler. The runtime waits for the result; it does not execute your function implementation itself.
Return the result
After your handler produces order, submit it with the IDs from action:
await client.beta.agents.sessions.events.create(sessionId, {
'Idempotency-Key': `result-${action.call_id}`,
events: [{
type: 'agent.session.input.tool_result',
turn_id: action.turn_id,
call_id: action.call_id,
success: true,
output: JSON.stringify(order),
}],
});
To report failure, send success: false and an error string. Reuse an idempotency key only for an identical result submission.
output can also be a content array to return an image alongside text:
output: [
{ type: 'input_text', text: 'Chart rendered.' },
{ type: 'input_image', image_url: 'https://your-app.example.com/charts/42.png' },
],
image_url is either an https:// URL your application already hosts, or an
inline data:image/...;base64,... image; the string is capped at 1 MB, which
limits an inline image to roughly 750 KB of image data. There is no file_id
form — Rebyte has no separate file-upload endpoint, so a function that needs
to return an image must host it or inline it. There is no detail control either; whichever provider serves the Session's
model applies its own default image handling.
Functions and MCP
Function tools hand execution to your application. MCP tools execute through the configured MCP connection and produce mcp_call Items instead. They do not require your application to post a function result.
Execution boundary and recovery
A function_call Item alone is not a client handoff. Hosted built-ins such as
apply_patch, write_stdin and view_image also appear as function-call Items,
but Rebyte executes them. Execute only the calls in the Session's authoritative
required_actions, obtained by retrieval or agent.session.requires_action.
Waiting function state survives service restarts. Each direct function waiting
round has a 24-hour deadline; partial results do not extend it. Expired results
are rejected and an abandoned direct wait fails the Turn with
request_timeout. Returning valid results continues that Turn. Explicitly cancel
the Turn or delete its Session when the application abandons the work.
For handlers with side effects, persist call_id and the result with your operation;
input idempotency prevents duplicate submissions, not duplicate host-side writes.
Runnable Node function example and Python Commerce host.
Functions and Dynamic Workflow
Client functions continue to use required_actions and application-submitted
results when Dynamic Workflow is enabled.
They are callable inside generated programs. Submit each nested result in its own
request with one event, using the exact Turn and call IDs. The program continues
with the supplied value; it may then ask for another function. Each nested pause
has its own 24-hour deadline. An uncaught function error or expired nested wait
fails the program and returns an error to the Agent, which can continue the Turn.
Fixed-code Workflow Agents
support the same function declarations but use their own run resource and
/v1/workflow-agents/runs/:runId/tool-results endpoint.
Receive function requests by webhook
A backend can subscribe to agent.session.action_required, verify the signature,
then retrieve the Session and execute its current required_actions. This also
covers Dynamic Workflow and scheduled Agents. Acknowledgment and function-result
submission are separate. See Webhooks.