SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
68d7816 verified
Raw History Blame Contribute Delete
3.36 kB
import type { ContextMessage } from '#/agent/contextMemory/types';
export const DYNAMIC_TOOL_SCHEMA_VARIANT = 'dynamic_tool_schema';
export const LOADABLE_TOOLS_VARIANT = 'loadable-tools';
export function isDynamicToolSchemaMessage(message: ContextMessage): boolean {
return message.tools !== undefined && message.tools.length > 0;
}
export function isLoadableToolsAnnouncement(message: ContextMessage): boolean {
const origin = message.origin;
if (origin?.kind === 'injection') return origin.variant === LOADABLE_TOOLS_VARIANT;
return origin?.kind === 'system_trigger' && origin.name === LOADABLE_TOOLS_VARIANT;
}
export function stripDynamicToolContext(
history: readonly ContextMessage[],
): readonly ContextMessage[] {
if (!history.some((m) => isDynamicToolSchemaMessage(m) || isLoadableToolsAnnouncement(m))) {
return history;
}
const out: ContextMessage[] = [];
for (const message of history) {
if (isLoadableToolsAnnouncement(message)) continue;
if (isDynamicToolSchemaMessage(message)) {
const { tools: _tools, ...rest } = message;
void _tools;
if (rest.content.length === 0 && rest.toolCalls.length === 0) continue;
out.push(rest);
continue;
}
out.push(message);
}
return out;
}
export function collectLoadedDynamicToolNames(
history: readonly ContextMessage[],
): Set<string> {
const names = new Set<string>();
for (const message of history) {
if (message.tools === undefined) continue;
for (const tool of message.tools) {
names.add(tool.name);
}
}
return names;
}
const TOOLS_ADDED_BLOCK = /<tools_added>\n?([\s\S]*?)\n?<\/tools_added>/g;
const TOOLS_REMOVED_BLOCK = /<tools_removed>\n?([\s\S]*?)\n?<\/tools_removed>/g;
export function foldAnnouncedToolNames(history: readonly ContextMessage[]): Set<string> {
const announced = new Set<string>();
for (const message of history) {
if (!isLoadableToolsAnnouncement(message)) continue;
const text = message.content
.map((part) => (part.type === 'text' ? part.text : ''))
.join('');
for (const name of matchToolNameBlocks(text, TOOLS_REMOVED_BLOCK)) {
announced.delete(name);
}
for (const name of matchToolNameBlocks(text, TOOLS_ADDED_BLOCK)) {
announced.add(name);
}
}
return announced;
}
function matchToolNameBlocks(text: string, pattern: RegExp): string[] {
const names: string[] = [];
pattern.lastIndex = 0;
for (const match of text.matchAll(pattern)) {
const body = match[1] ?? '';
for (const line of body.split('\n')) {
const name = line.trim();
if (name.length > 0) names.push(name);
}
}
return names;
}
export function renderLoadableToolsAnnouncement(
added: readonly string[],
removed: readonly string[],
): string {
const sections: string[] = [];
if (added.length > 0) {
sections.push(`<tools_added>\n${added.join('\n')}\n</tools_added>`);
}
if (removed.length > 0) {
sections.push(`<tools_removed>\n${removed.join('\n')}\n</tools_removed>`);
}
sections.push(
'Use the select_tools tool with exact names to load full tool definitions before calling them. ' +
'Names listed as removed are no longer loadable — do not select them. ' +
'Fold all announcements in this conversation in order to get the current list.',
);
return sections.join('\n\n');
}