fix: đã sửa lỗi AI gửi prompt và thêm các tool để AI thực hiện

This commit is contained in:
2026-07-22 09:23:05 +07:00
parent e0b849fdf2
commit 022fbb3351
6 changed files with 385 additions and 44 deletions
+115 -7
View File
@@ -7004,14 +7004,21 @@ const App = () => {
dawContext,
tools: window.AIGateway.DEFAULT_TOOLS
});
if (result.textResponse) {
const hasText = !!result.textResponse;
const hasCalls = result.functionCalls && result.functionCalls.length > 0;
if (hasText) {
setAiActionLog(prev => [...prev, {
type: 'status',
text: ` AI: ${result.textResponse}`,
text: ` AI: ${result.textResponse.slice(0, 500)}`,
time: Date.now()
}]);
}
if (result.functionCalls && result.functionCalls.length > 0) {
if (hasCalls) {
setAiActionLog(prev => [...prev, {
type: 'info',
text: ` Gọi ${result.functionCalls.length} lệnh...`,
time: Date.now()
}]);
for (const fc of result.functionCalls) {
setAiActionLog(prev => [...prev, {
type: 'info',
@@ -7034,9 +7041,22 @@ const App = () => {
time: Date.now()
}]);
}
} else {
setAiActionLog(prev => [...prev, {
type: 'error',
text: `${fc.name}: DAWCommandDispatcher not available`,
time: Date.now()
}]);
}
}
}
if (!hasText && !hasCalls) {
setAiActionLog(prev => [...prev, {
type: 'error',
text: ` AI không trả về lệnh hoặc text. Kiểm tra provider/model có hỗ trợ function calling.`,
time: Date.now()
}]);
}
setAiActionLog(prev => [...prev, {
type: 'status',
text: ` Hoàn tất.`,
@@ -7224,7 +7244,9 @@ const App = () => {
},
addClip: args => {
const trackId = args.track_id || selectedTrackId;
const startTime = args.start_time || args.start_bar ? args.start_bar * (60 / parseInt(bpm || 120)) * 4 : currentTime;
const barDur = 60 / parseInt(bpm || 120) * 4;
let startTime;
if (args.start_time !== undefined && args.start_time !== null) startTime = args.start_time;else if (args.start_bar !== undefined && args.start_bar !== null) startTime = args.start_bar * barDur;else startTime = currentTime;
const track = tracks.find(t => t.id === trackId);
if (!track) return {
success: false,
@@ -7232,7 +7254,8 @@ const App = () => {
};
const ctx = getAudioContext();
const sr = 44100;
const duration = args.duration_seconds || args.length_bars ? args.length_bars * (60 / parseInt(bpm || 120)) * 4 : 2;
let duration;
if (args.duration_seconds !== undefined && args.duration_seconds !== null) duration = args.duration_seconds;else if (args.length_bars !== undefined && args.length_bars !== null) duration = args.length_bars * barDur;else duration = 2;
const buffer = ctx.createBuffer(1, Math.floor(sr * duration), sr);
const data = buffer.getChannelData(0);
for (let i = 0; i < data.length; i++) data[i] = 0;
@@ -7395,6 +7418,89 @@ const App = () => {
error: `Unknown action: ${action}`
};
},
renameTrack: args => {
const tid = args.track_id || selectedTrackId;
const name = args.name;
if (!tid) return {
success: false,
error: 'No track_id provided'
};
if (!name) return {
success: false,
error: 'No name provided'
};
updateTrackName(tid, name);
return {
success: true,
trackId: tid,
name
};
},
setSelection: args => {
const barDur = 60 / parseInt(bpm || 120) * 4;
let start, end;
if (args.start_time !== undefined && args.start_time !== null) start = args.start_time;else if (args.start_bar !== undefined && args.start_bar !== null) start = args.start_bar * barDur;else start = currentTime;
if (args.end_time !== undefined && args.end_time !== null) end = args.end_time;else if (args.length_bars !== undefined && args.length_bars !== null) end = start + args.length_bars * barDur;else if (args.end_bar !== undefined && args.end_bar !== null) end = args.end_bar * barDur;else end = start + barDur;
clearLocalSelection();
setSelectionMode('global');
setSelectionStart(start);
setSelectionEnd(end);
return {
success: true,
start: parseFloat(start.toFixed(3)),
end: parseFloat(end.toFixed(3)),
length: parseFloat((end - start).toFixed(3))
};
},
scanTrack: args => {
const tid = args.track_id || selectedTrackId;
const track = tracks.find(t => t.id === tid);
if (!track) return {
success: false,
error: 'Track not found'
};
if (!track.buffer) return {
success: false,
error: 'Track has no audio buffer. Load audio first.'
};
const buffer = track.buffer;
const data = buffer.getChannelData(0);
const sr = buffer.sampleRate;
const channels = buffer.numberOfChannels;
const duration = buffer.duration;
const totalSamples = buffer.length;
const windowSize = Math.min(sr * 3, data.length);
let detectedBPM = 0;
if (windowSize > sr) {
let maxCorr = 0;
for (let lag = Math.floor(sr * 0.3); lag <= Math.floor(sr * 2.0); lag++) {
let corr = 0;
const step = 4;
for (let i = 0; i < windowSize && i + lag < data.length; i += step) corr += data[i] * data[i + lag];
corr /= windowSize / step;
if (corr > maxCorr) {
maxCorr = corr;
detectedBPM = 60 / (lag / sr);
}
}
}
detectedBPM = Math.round(Math.min(300, Math.max(30, detectedBPM)));
const bitDepth = 16;
const bitrate = Math.round(sr * channels * bitDepth / 1000);
return {
success: true,
trackId: tid,
trackName: track.name,
bpm: detectedBPM,
sampleRate: sr,
channels,
duration: parseFloat(duration.toFixed(3)),
totalSamples,
bitDepth,
bitrateKbps: bitrate,
hasAudio: true
};
},
setBpm: args => {
const bpmVal = args.bpm || args.tempo || 120;
setBpm(String(bpmVal));
@@ -7404,11 +7510,13 @@ const App = () => {
};
},
setPlayhead: args => {
const time = args.time ?? args.position ?? 0;
const barDur = 60 / parseInt(bpm || 120) * 4;
let time;
if (args.time !== undefined && args.time !== null) time = args.time;else if (args.bar !== undefined && args.bar !== null) time = args.bar * barDur;else time = 0;
handlePlayheadSet(time);
return {
success: true,
time
time: parseFloat(time.toFixed(3))
};
},
addMarker: args => {