Welcome to the final chapter of our ScheduleCronTool series!
In the previous chapter, Tool UI Rendering, we made our tools look beautiful with React components. We now have a system that can schedule tasks, save them to the hard drive, and display nice status updates.
But there is one major question left: Safety and Control.
Imagine you release this cool scheduling feature to 1,000 users.
You cannot simply "delete" the code from 1,000 computers instantly. You need a Remote Control.
We call this Feature Gating. It acts like a master circuit breaker. If we flip the switch, the scheduling tools completely disappear from the AI's utility belt, or their behavior changes instantly.
Our configuration system isn't just one switch; it is a security checkpoint with three gates. A user must pass all three to use the scheduler.
This is the most fundamental switch. It happens when the application is being compiled (built).
If feature('AGENT_TRIGGERS') is false, the code for the scheduler is literally removed from the application to save space. It's like building a house but leaving the "Guest Room" off the blueprints entirely.
// prompt.ts
import { feature } from 'bun:bundle'
const hasBlueprint = feature('AGENT_TRIGGERS')
// If false, the code inside is "dead" and removed.
Sometimes a developer or a system administrator wants to forcibly disable the feature on their specific machine, regardless of what the remote server says.
We look for a specific text setting in the computer's environment: CLAUDE_CODE_DISABLE_CRON.
// prompt.ts
import { isEnvTruthy } from '../../utils/envUtils.js'
// Returns true if the user manually disabled it locally
const isLocallyDisabled = isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_CRON)
This is the most powerful tool for us. We use a system called GrowthBook. It allows us to toggle features on or off for all users (or specific groups) instantly via a remote server, without them needing to update their app.
// prompt.ts
import { getFeatureValue_CACHED_WITH_REFRESH } from '../../services'
// Checks the remote server. Refreshes every 5 minutes.
const isRemoteEnabled = getFeatureValue_CACHED_WITH_REFRESH(
'tengu_kairos_cron', // The ID of the flag
true // The default value (if offline)
)
isKairosCronEnabledWe combine these three layers into one master function. This function dictates whether the Cron Tool Suite exists at all.
If this function returns false:
CronCreate, CronList, and CronDelete tools are hidden.Here is the implementation:
// prompt.ts
export function isKairosCronEnabled(): boolean {
// 1. Check Blueprint (Build flag)
if (!feature('AGENT_TRIGGERS')) return false
// 2. Check Local Override (Env var)
if (isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_CRON)) return false
// 3. Check Remote Control (GrowthBook)
return getFeatureValue_CACHED_WITH_REFRESH(
'tengu_kairos_cron',
true,
5 * 60 * 1000 // Refresh cache every 5 mins
)
}
Explanation: It is an "AND" relationship. The blueprint must exist AND the local override must be off AND the remote server must say "Go".
isDurableCronEnabledAs we learned in Durability & Persistence Logic, we have two modes: Session-Only (RAM) and Durable (Disk).
We might want the scheduler to be active for everyone (Session-Only), but disable writing to disk for security reasons. For this, we have a secondary gate.
// prompt.ts
export function isDurableCronEnabled(): boolean {
// A specific flag just for the "Write to Disk" capability
return getFeatureValue_CACHED_WITH_REFRESH(
'tengu_kairos_cron_durable',
true, // Defaults to true
5 * 60 * 1000
)
}
This gate is checked inside the CronCreateTool logic we wrote in Chapter 3.
Let's visualize the decision process when the application starts up and decides which tools to give the AI agent.
Finally, we need to make sure our tools actually use this logic. We do this in the isEnabled() method of the tool definition.
This is a lazy check. The tool isn't added to the agent until this returns true.
// CronCreateTool.ts
export const CronCreateTool = buildTool({
name: CRON_CREATE_TOOL_NAME,
// The system calls this before showing the tool to the AI
isEnabled() {
return isKairosCronEnabled()
},
// ... rest of the tool definition
})
By adding these 3 lines, we ensure that if we flip the switch on our remote server, the tool vanishes from the AI's context globally within 5 minutes (the cache refresh time).
Congratulations! You have completed the ScheduleCronTool tutorial series.
Let's review what we have built together:
Create, List, Delete) that act as the AI's hands.You now understand how to build a complex, production-grade tool for an AI agent. It isn't just about writing a function; it's about handling user expectations, managing system state, rendering UI, and ensuring safety through configuration.
Thank you for following along!
Generated by Code IQ