feat(core): implement tool-based topic grouping (Chapters) (#23150)

Co-authored-by: Christian Gunderman <gundermanc@google.com>
This commit is contained in:
Abhijit Balaji
2026-03-27 18:28:25 -07:00
committed by GitHub
parent ae123c547c
commit afc1d50c20
22 changed files with 663 additions and 50 deletions
@@ -125,3 +125,9 @@ export const PLAN_MODE_PARAM_REASON = 'reason';
// -- sandbox --
export const PARAM_ADDITIONAL_PERMISSIONS = 'additional_permissions';
// -- update_topic --
export const UPDATE_TOPIC_TOOL_NAME = 'update_topic';
export const TOPIC_PARAM_TITLE = 'title';
export const TOPIC_PARAM_SUMMARY = 'summary';
export const TOPIC_PARAM_STRATEGIC_INTENT = 'strategic_intent';
@@ -17,6 +17,7 @@ import {
getShellDeclaration,
getExitPlanModeDeclaration,
getActivateSkillDeclaration,
getUpdateTopicDeclaration,
} from './dynamic-declaration-helpers.js';
// Re-export names for compatibility
@@ -38,6 +39,7 @@ export {
ASK_USER_TOOL_NAME,
EXIT_PLAN_MODE_TOOL_NAME,
ENTER_PLAN_MODE_TOOL_NAME,
UPDATE_TOPIC_TOOL_NAME,
// Shared parameter names
PARAM_FILE_PATH,
PARAM_DIR_PATH,
@@ -91,6 +93,9 @@ export {
PLAN_MODE_PARAM_REASON,
EXIT_PLAN_PARAM_PLAN_FILENAME,
SKILL_PARAM_NAME,
TOPIC_PARAM_TITLE,
TOPIC_PARAM_SUMMARY,
TOPIC_PARAM_STRATEGIC_INTENT,
} from './base-declarations.js';
// Re-export sets for compatibility
@@ -221,6 +226,13 @@ export const ENTER_PLAN_MODE_DEFINITION: ToolDefinition = {
overrides: (modelId) => getToolSet(modelId).enter_plan_mode,
};
export const UPDATE_TOPIC_DEFINITION: ToolDefinition = {
get base() {
return getUpdateTopicDeclaration();
},
overrides: (modelId) => getToolSet(modelId).update_topic,
};
// ============================================================================
// DYNAMIC TOOL DEFINITIONS (LEGACY EXPORTS)
// ============================================================================
@@ -24,6 +24,10 @@ import {
EXIT_PLAN_PARAM_PLAN_FILENAME,
SKILL_PARAM_NAME,
PARAM_ADDITIONAL_PERMISSIONS,
UPDATE_TOPIC_TOOL_NAME,
TOPIC_PARAM_TITLE,
TOPIC_PARAM_SUMMARY,
TOPIC_PARAM_STRATEGIC_INTENT,
} from './base-declarations.js';
/**
@@ -204,3 +208,34 @@ export function getActivateSkillDeclaration(
parametersJsonSchema: zodToJsonSchema(schema),
};
}
/**
* Returns the FunctionDeclaration for updating the topic context.
*/
export function getUpdateTopicDeclaration(): FunctionDeclaration {
return {
name: UPDATE_TOPIC_TOOL_NAME,
description:
'Manages your narrative flow. Include `title` and `summary` only when starting a new Chapter (logical phase) or shifting strategic intent.',
parametersJsonSchema: {
type: 'object',
properties: {
[TOPIC_PARAM_TITLE]: {
type: 'string',
description: 'The title of the new topic or chapter.',
},
[TOPIC_PARAM_SUMMARY]: {
type: 'string',
description:
'(OPTIONAL) A detailed summary (5-10 sentences) covering both the work completed in the previous topic and the strategic intent of the new topic. This is required when transitioning between topics to maintain continuity.',
},
[TOPIC_PARAM_STRATEGIC_INTENT]: {
type: 'string',
description:
'A mandatory one-sentence statement of your immediate intent.',
},
},
required: [TOPIC_PARAM_STRATEGIC_INTENT],
},
};
}
@@ -78,6 +78,7 @@ import {
getShellDeclaration,
getExitPlanModeDeclaration,
getActivateSkillDeclaration,
getUpdateTopicDeclaration,
} from '../dynamic-declaration-helpers.js';
import {
DEFAULT_MAX_LINES_TEXT_FILE,
@@ -724,4 +725,5 @@ The agent did not use the todo list because this task could be completed by a ti
exit_plan_mode: () => getExitPlanModeDeclaration(),
activate_skill: (skillNames) => getActivateSkillDeclaration(skillNames),
update_topic: getUpdateTopicDeclaration(),
};
@@ -50,4 +50,5 @@ export interface CoreToolSet {
enter_plan_mode: FunctionDeclaration;
exit_plan_mode: () => FunctionDeclaration;
activate_skill: (skillNames: string[]) => FunctionDeclaration;
update_topic?: FunctionDeclaration;
}