fix tạm lỗi cài đặt AI prompt

This commit is contained in:
2026-07-21 21:38:37 +07:00
parent bbc42c630e
commit 04403b0af7
7 changed files with 484 additions and 198 deletions
+1 -189
View File
@@ -6872,192 +6872,6 @@ const App = () => {
}, 800);
};
// AI Copilot: Natural Language Prompt Function Calls (28_AI_PANEL.md §2 & §3)
const AIComparator = () => {
const [prompt, setPrompt] = useState('');
const [provider, setProvider] = useState('OpenAI');
const [model, setModel] = useState('GPT-4o');
const [response, setResponse] = useState('');
const [history = [], setHistory] = useState([]);
const handleSendPrompt = async () => {
setResponse('');
try {
const context = window.AIGateway.buildAIPromptContext({
bpm: parseInt(bpm) || 120,
selectedTrackId: selectedTrackId,
currentTime: currentTime,
selLeft: selLeft,
selRight: selRight,
tracks: tracks
});
const result = await window.AIGateway.executePrompt({
prompt: prompt,
provider: provider,
model: model,
apiKey: aiConfig.apiKey,
baseUrl: aiConfig.baseUrl
});
setResponse(result.textResponse);
result.functionCalls.forEach(call => {
DAWCommandDispatcher.execute(call.name, call.arguments);
setHistory([...history, { name: call.name, args: call.arguments }]);
});
}
catch (e) {
setResponse(`Lỗi: ${e.message}`);
}
};
const prompt = aiPrompt.trim();
if (!prompt || aiProcessing) return;
setAiProcessing(true);
setAiActionLog(prev => [...prev, { type: 'status', text: 'AI đang phân tích lệnh...', time: Date.now() }]);
const dawContext = window.AIGateway.buildAIPromptContext({
bpm: parseInt(bpm) || 120,
selectedTrackId,
currentTime,
selLeft,
selRight,
tracks
});
try {
const result = await window.AIGateway.executePrompt({
prompt,
provider: aiProvider.toLowerCase(),
model: aiModel,
apiKey: aiConfig.apiKey,
baseUrl: aiConfig.baseUrl,
dawContext
});
const calls = result.functionCalls || [];
if (calls.length === 0 && result.textResponse) {
setAiActionLog(prev => [...prev, { type: 'text', text: result.textResponse, time: Date.now() }]);
}
for (const call of calls) {
const logEntry = { type: 'action', text: `[${call.name}] Đang thực thi...`, time: Date.now(), callName: call.name, args: call.arguments };
setAiActionLog(prev => [...prev, logEntry]);
let execResult = { success: false, error: 'Unknown command' };
if (window.DAWCommandDispatcher && window.DAWCommandDispatcher.execute) {
execResult = window.DAWCommandDispatcher.execute(call.name, call.arguments);
} else {
const api = {
createTrack: (args) => {
const name = args.name || `AI_Track_${Date.now()}`;
const newId = addNewTrack();
if (name) updateTrackName(newId, name);
return { success: true, trackId: newId };
},
deleteTrack: (args) => {
const tid = args.track_id || selectedTrackId;
if (tid) deleteTrack(tid);
return { success: true };
},
processAudioDsp: (args) => {
const trackId = args.track_id || selectedTrackId;
const action = args.action;
const params = args.params || {};
const track = tracks.find(t => t.id === trackId);
if (!track || !track.buffer) return { success: false, error: 'No buffer' };
if (action === 'normalize') {
const d = track.buffer.getChannelData(0);
let mx = 0; for (let i = 0; i < d.length; i++) mx = Math.max(mx, Math.abs(d[i]));
if (mx > 0) { const g = 1.0 / mx; for (let i = 0; i < d.length; i++) d[i] *= g; }
return { success: true };
} else if (action === 'invert_phase') {
const d = track.buffer.getChannelData(0);
for (let i = 0; i < d.length; i++) d[i] *= -1;
return { success: true };
} else if (action === 'gain') {
const g = Math.pow(10, (params.gain_db ?? 0) / 20);
const d = track.buffer.getChannelData(0);
for (let i = 0; i < d.length; i++) d[i] = Math.max(-1, Math.min(1, d[i] * g));
return { success: true };
} else if (action === 'pitch_shift') {
const semi = params.semitones ?? 0;
const ratio = Math.pow(2, semi / 12);
const resample = (data, r) => {
const nl = Math.round(data.length * r);
const out = new Float32Array(nl);
for (let i = 0; i < nl; i++) { const si = i / r; const i0 = Math.floor(si); const i1 = Math.min(i0 + 1, data.length - 1); const f = si - i0; out[i] = data[i0] * (1 - f) + data[i1] * f; }
return out;
};
const d = track.buffer.getChannelData(0);
const nd = resample(d, 1 / ratio);
const ctx = getAudioContext();
const nb = ctx.createBuffer(1, nd.length, track.buffer.sampleRate);
nb.copyToChannel(nd, 0);
setTracks(p => p.map(t => t.id === trackId ? { ...t, buffer: nb } : t));
return { success: true };
}
return { success: false, error: `Unknown action: ${action}` };
},
add_midi_item: (args) => {
return { success: true, note: 'MIDI items mapped to silent audio clip' };
},
modify_midi_notes: (args) => {
return { success: true, note: 'MIDI notes mapped to synth tones' };
},
setTrackVolume: (args) => {
const trackId = args.track_id || selectedTrackId;
updateTrackVolumeDb(trackId, parseFloat(args.volume_db ?? args.volume ?? 0));
return { success: true };
},
setTrackPan: (args) => {
const trackId = args.track_id || selectedTrackId;
updateTrackPan(trackId, parseInt(args.pan ?? 0));
return { success: true };
},
toggleMute: (args) => {
const trackId = args.track_id || selectedTrackId;
toggleTrackMute(trackId);
return { success: true };
},
toggleSolo: (args) => {
const trackId = args.track_id || selectedTrackId;
toggleTrackSoloEvaluate(trackId);
return { success: true };
},
setBpm: (args) => {
const bpmVal = args.bpm || args.tempo || 120;
setBpm(String(bpmVal));
return { success: true };
},
setPlayhead: (args) => {
handlePlayheadSet(args.time ?? args.position ?? 0);
return { success: true };
},
addMarker: (args) => {
const trackId = args.track_id || selectedTrackId;
const time = args.time ?? currentTime;
setTracks(prev => prev.map(t => {
if (t.id !== trackId) return t;
return { ...t, markers: [...(t.markers || []), { id: 'ai_marker_' + Date.now(), time, label: args.label || 'AI Marker' }] };
}));
return { success: true };
}
};
if (api[call.name]) {
execResult = api[call.name](call.arguments);
}
}
setAiActionLog(prev => prev.map(entry => {
if (entry === logEntry) {
return { ...entry, text: `[${call.name}] ${execResult.success ? 'Thành công' : 'Thất bại: ' + (execResult.error || 'unknown')}`, result: execResult };
}
return entry;
}));
}
setAiActionLog(prev => [...prev, { type: 'status', text: `Hoàn thành. Đã xử lý ${calls.length} lệnh.`, time: Date.now() }]);
} catch (err) {
setAiActionLog(prev => [...prev, { type: 'error', text: 'Lỗi: ' + err.message, time: Date.now() }]);
} finally {
setAiProcessing(false);
}
};
// Split Track at Playhead
const handleSplitTrackAtTime = (trackId, clipId, time) => {
const track = tracks.find(t => t.id === trackId);
@@ -8319,9 +8133,7 @@ const App = () => {
}, "Chưa có hành động nào.") : aiActionLog.map((entry, i) => /*#__PURE__*/React.createElement("div", {
key: i,
className: `text-[9px] font-mono py-0.5 border-b border-zinc-900 last:border-0 ${entry.type === 'error' ? 'text-red-400' : entry.type === 'status' ? 'text-zinc-400 italic' : entry.type === 'undo' ? 'text-amber-400' : 'text-zinc-300'}`
}, /*#__PURE__*/React.createElement("span", {
className: "text-zinc-600 mr-1"
}, new Date(entry.time).toLocaleTimeString()), entry.text)))));
}, new Date(entry.time).toLocaleTimeString(), entry.text)));
if (panelId === 'python_tools') return /*#__PURE__*/React.createElement("div", {
className: "flex flex-col h-full gap-1.5"
}, /*#__PURE__*/React.createElement("div", {