feat(headless): exclude AskUserQuestion from headless mode toolset (#1266)

Co-authored-by: Letta Code <noreply@letta.com>
This commit is contained in:
Kevin Lin
2026-03-04 16:21:01 -08:00
committed by GitHub
parent 3059d508d8
commit ee00ac7280
2 changed files with 15 additions and 2 deletions

View File

@@ -910,7 +910,8 @@ async function main(): Promise<void> {
specifiedModel,
specifiedToolset as "auto" | "codex" | "default" | "gemini" | undefined,
);
await loadTools(modelForTools);
// Exclude interactive-only tools that can't function without a live user session
await loadTools(modelForTools, { exclude: ["AskUserQuestion"] });
markMilestone("TOOLS_LOADED");
// Keep headless startup in sync with interactive name resolution.

View File

@@ -787,9 +787,15 @@ export async function loadSpecificTools(toolNames: string[]): Promise<void> {
* Acquires the toolset switch lock during loading to prevent message sends from
* reading stale tools. Callers should use waitForToolsetReady() before sending messages.
*
* @param modelIdentifier - Optional model identifier to select the appropriate toolset
* @param options - Optional configuration
* @param options.exclude - Tool names to exclude from the loaded toolset
* @returns Promise that resolves when all tools are loaded
*/
export async function loadTools(modelIdentifier?: string): Promise<void> {
export async function loadTools(
modelIdentifier?: string,
options?: { exclude?: ToolName[] },
): Promise<void> {
// Acquire lock to signal that a switch is in progress
acquireSwitchLock();
@@ -823,6 +829,12 @@ export async function loadTools(modelIdentifier?: string): Promise<void> {
baseToolNames = TOOL_NAMES;
}
// Apply exclusions (e.g. remove interactive-only tools in headless mode)
if (options?.exclude && options.exclude.length > 0) {
const excludeSet = new Set(options.exclude);
baseToolNames = baseToolNames.filter((name) => !excludeSet.has(name));
}
// Build new registry in a temporary map (all async work happens above)
const newRegistry: ToolRegistry = new Map();