Before Execution Modifiers
If you're building an agent, we recommend using sessions instead. Sessions handle tool fetching, authentication, and execution automatically.
Before execution modifiers are part of Devcaster SDK's powerful middleware capabilities that allow you to customize and extend the behavior of tools.
These modifiers are called before the tool is executed by the LLM. This allows you to modify the arguments called by the LLM before they are executed by Devcaster.
Useful for:
- Injecting an argument into the tool execution
- Overriding the arguments emitted by the LLM

Below we use the beforeExecute modifier to modify the number of posts returned by HACKERNEWS_GET_LATEST_POSTS.
With Chat Completions
Since completion providers don't have a function execution step, Devcaster executes the tool call directly. The modifier is configured on the tools.execute method.
from openai import OpenAI
from devcaster import Devcaster, before_execute
from devcaster.types import ToolExecuteParams
devcaster = Devcaster()
openai_client = OpenAI()
user_id = "user@email.com"
@before_execute(tools=["HACKERNEWS_GET_LATEST_POSTS"])
def before_execute_modifier(
tool: str,
toolkit: str,
params: ToolExecuteParams,
) -> ToolExecuteParams:
params["arguments"]["size"] = 1
return params
# Get tools
tools = devcaster.tools.get(user_id=user_id, slug="HACKERNEWS_GET_LATEST_POSTS")
# Get response from the LLM
response = openai_client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=[{"role": "user", "content": "Fetch latest posts from hackernews"}],
)
print(response)
# Execute the function calls
result = devcaster.provider.handle_tool_calls(
response=response,
user_id="default",
modifiers=[
before_execute_modifier,
],
)
print(result)const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages,
tools,
tool_choice: "auto",
});
const { tool_calls } = response.choices[0].message;
console.log(tool_calls);
if (tool_calls) {
const {
function: { arguments: toolArgs },
} = tool_calls[0];
const result = await devcaster.tools.execute(
"HACKERNEWS_GET_LATEST_POSTS",
{
userId,
arguments: JSON.parse(toolArgs),
},
{
beforeExecute: ({ toolSlug, toolkitSlug, params }) => {
if (toolSlug === "HACKERNEWS_GET_LATEST_POSTS") {
params.arguments.size = 1;
}
console.log(params);
return params;
},
}
);
console.log(JSON.stringify(result, null, 2));
}With Agentic Frameworks
Agentic providers have a function execution step. The modifier is configured on the tools.get method which modifies the execution logic within the framework.
from devcaster import Devcaster, before_execute
from devcaster.types import ToolExecuteParams
from devcaster_crewai import CrewAIProvider
devcaster = Devcaster(provider=CrewAIProvider())
@before_execute(tools=["LINEAR_CREATE_LINEAR_ISSUE"])
def modify_linear_project_id(
tool: str,
toolkit: str,
params: ToolExecuteParams,
) -> ToolExecuteParams:
params["arguments"]["project_id"] = "1234567890"
return params
tools = devcaster.tools.get(
user_id="default",
tools=[
"HACKERNEWS_GET_LATEST_POSTS",
"HACKERNEWS_GET_USER",
"LINEAR_CREATE_LINEAR_ISSUE",
],
modifiers=[
modify_linear_project_id,
]
)import { Devcaster } from "@devcaster/core";
import { MastraProvider } from "@devcaster/mastra";
const devcaster = new Devcaster({
apiKey: process.env.DEVCASTER_API_KEY,
provider: new MastraProvider(),
});
const userId = "user@acme.com";
const agenticTools = await devcaster.tools.get(
userId,
{
tools: [
"HACKERNEWS_GET_LATEST_POSTS",
"HACKERNEWS_GET_USER",
"LINEAR_CREATE_LINEAR_ISSUE",
],
},
{
beforeExecute: ({toolSlug, toolkitSlug, params}) => {
if (toolSlug === "LINEAR_CREATE_LINEAR_ISSUE") {
params.arguments.project_id = "1234567890";
}
return params;
},
}
);