feat: add track-aware tool targeting and new agent tools, lifted the requirement of selection a MIDI region to use AI Agent

Introduces a shared `toolTargeting.ts` module that resolves the active MIDI
region/track from the user's current selection, enabling tools to operate on
the correct target without requiring explicit track IDs in most cases.

Adds two new read-only tools — `list_all_tracks` and
`get_user_selected_music_range_and_track` — so the agent can inspect
available tracks and the current selection context before acting.

Also refactors `AddNotesTool` to auto-create MIDI regions when no region
exists, refactors `RemoveNotesTool`, `ReadMusicTool`, and
`ReadChordProgressionTool` to use the new targeting helpers, adds a
`buildToolHistoryContent` hook to `BaseTool` for cleaner chat history
display, and updates system prompts and tests throughout.
This commit is contained in:
Xiaohan-Tian
2026-06-04 19:29:37 -07:00
parent 5c5a07b839
commit 8ee7ddac77
27 changed files with 1812 additions and 855 deletions
+10 -8
View File
@@ -341,13 +341,13 @@ export class KGDebugger {
* Usage examples in browser console:
*
* // Single tool call:
* await KGStudio.KGDebugger.testToolCall('{"name":"read_music","arguments":{"start":0,"length":8}}')
* await KGDebugger.testToolCall('{"name":"read_music","arguments":{"start":0,"length":8}}')
*
* // Multiple tool calls:
* await KGStudio.KGDebugger.testToolCall('[{"name":"remove_notes","arguments":{"start":0,"end_beat":4}},{"name":"add_notes","arguments":{"notes":[{"pitch":"C4","start":0,"length":1}]}}]')
* await KGDebugger.testToolCall('[{"name":"remove_notes","arguments":{"start":0,"end_beat":4}},{"name":"add_notes","arguments":{"notes":[{"pitch":"C4","start":0,"length":1}]}}]')
*
* // Can also pass a JS object directly (no need to stringify):
* await KGStudio.KGDebugger.testToolCall({name:"read_music",arguments:{start:0}})
* await KGDebugger.testToolCall({name:"read_music",arguments:{start:0}})
*
* @param input - JSON string, object, or array of tool call(s).
* Each tool call should have: { name: string, arguments: object }
@@ -430,13 +430,15 @@ export class KGDebugger {
console.log(" - Use browser developer tools for best experience");
console.log("");
console.log("💡 testToolCall examples:");
console.log(' await KGStudio.KGDebugger.testToolCall(\'{"name":"read_music","arguments":{"start":0,"length":8}}\')');
console.log(' await KGStudio.KGDebugger.testToolCall({name:"add_notes",arguments:{notes:[{pitch:"C4",start:0,length:1}]}})');
console.log(' await KGStudio.KGDebugger.testToolCall([{name:"remove_notes",arguments:{start:0,end_beat:4}},{name:"read_music",arguments:{}}])');
console.log(' await KGDebugger.testToolCall(\'{"name":"get_user_selected_music_range_and_track","arguments":{}}\')');
console.log(' await KGDebugger.testToolCall(\'{"name":"list_all_tracks","arguments":{}}\')');
console.log(' await KGDebugger.testToolCall(\'{"name":"read_music","arguments":{"start":0,"length":8}}\')');
console.log(' await KGDebugger.testToolCall({name:"add_notes",arguments:{notes:[{pitch:"C4",start:0,length:1}]}})');
console.log(' await KGDebugger.testToolCall([{name:"remove_notes",arguments:{start:0,end_beat:4}},{name:"read_music",arguments:{}}])');
console.log("");
console.log("💡 KGOne input examples:");
console.log(' await KGStudio.KGDebugger.inputKGOneCaption("Genre: Eurodance, 90s dance-pop, upbeat electronic...", 30)');
console.log(' await KGStudio.KGDebugger.inputKGOneLyrics("[Verse 1]\\nYour lyrics here...\\n\\n[Chorus]\\n...", 30)');
console.log(' await KGDebugger.inputKGOneCaption("Genre: Eurodance, 90s dance-pop, upbeat electronic...", 30)');
console.log(' await KGDebugger.inputKGOneLyrics("[Verse 1]\\nYour lyrics here...\\n\\n[Chorus]\\n...", 30)');
}
/**