This commit is contained in:
@@ -40,6 +40,22 @@ export function validatePair(pair: FirPair) {
|
||||
encodeFir(pair.left);
|
||||
encodeFir(pair.right);
|
||||
}
|
||||
export async function requireFirEnabled(
|
||||
api: Pick<LuxsinAPI, "getDeviceState">
|
||||
): Promise<void> {
|
||||
// Always query the device: a React state snapshot may predate the FIR toggle.
|
||||
const state = await api.getDeviceState();
|
||||
if (state.fir_enable !== 1) {
|
||||
throw new Error("FIR 未启用或无法确认开关状态,请先前往 Effect → FIR 手动启用,再重新分析。 / FIR is disabled or its status is unknown. Please manually enable it at Effect → FIR before analyzing.");
|
||||
}
|
||||
}
|
||||
export async function readEnabledCurrentFir(
|
||||
api: Pick<LuxsinAPI, "getDeviceState" | "getFirChannel">
|
||||
): Promise<FirPair> {
|
||||
await requireFirEnabled(api);
|
||||
return readCurrentFir(api);
|
||||
}
|
||||
|
||||
export async function readCurrentFir(
|
||||
api: Pick<LuxsinAPI, "getFirChannel">
|
||||
): Promise<FirPair> {
|
||||
|
||||
@@ -383,7 +383,7 @@ export class LuxsinAPI {
|
||||
|
||||
async getDeviceState(): Promise<DeviceState> {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/dev/info.cgi?action=syncData`);
|
||||
const response = await fetch(`${this.baseUrl}/dev/info.cgi?action=syncData`, { cache: "no-store" });
|
||||
const text = await response.text();
|
||||
const decoded = decodeCustomBase64(text.trim());
|
||||
const state = JSON.parse(decoded) as DeviceState;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import AiFirCard from '@/components/AiFirCard';
|
||||
import {aiFirText} from '@/lib/aiFirLocale';
|
||||
import {readCurrentFir, firMetrics, renderFir, type FirPair, type FirProposal, type FirAdjustment} from '@/lib/aiFir';
|
||||
import {readEnabledCurrentFir, requireFirEnabled, firMetrics, renderFir, type FirPair, type FirProposal, type FirAdjustment} from '@/lib/aiFir';
|
||||
/* ============================================================
|
||||
AI PAGE — Luxsin X9 AI Assistant
|
||||
- 首次进入: 中央 Logo + 建议气泡,引导用户如何提问
|
||||
@@ -260,11 +260,13 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
|
||||
try {
|
||||
if(block.name==='get_current_fir') {
|
||||
firSnapshot.current=null;
|
||||
const pair=await readCurrentFir(api);
|
||||
setFirProposal(null);
|
||||
const pair=await readEnabledCurrentFir(api);
|
||||
if(firDeviceRef.current!==device) throw new Error('Device changed');
|
||||
const id=makeId();firSnapshot.current={id,pair};
|
||||
return {ok:true,content:{snapshot_id:id,...firMetrics(pair)}};
|
||||
}
|
||||
await requireFirEnabled(api);
|
||||
const a=block.input as FirAdjustment;
|
||||
const snapshot=firSnapshot.current;
|
||||
if(!snapshot || a.snapshot_id!==snapshot.id) throw new Error('Read current FIR in this turn before proposing an adjustment');
|
||||
@@ -273,7 +275,7 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
|
||||
setFirCardVisible(true);
|
||||
setFirProposal({id:makeId(),device,before:snapshot.pair,after,adjustment:a,created:new Date().toISOString()});
|
||||
return {ok:true,content:{status:'awaiting_user_confirmation',before:firMetrics(snapshot.pair),after:firMetrics(after),message:'FIR arrays staged only. Device unchanged. User must confirm upload in the AI FIR card; backup precedes upload, then A/B is available.'}};
|
||||
}catch(error){return {ok:false,message:error instanceof Error?error.message:'FIR failed'};}
|
||||
}catch(error){firSnapshot.current=null;setFirProposal(null);return {ok:false,message:error instanceof Error?error.message:'FIR failed'};}
|
||||
};
|
||||
|
||||
const [chatId, setChatId] = useState<string | null>(null);
|
||||
@@ -534,7 +536,10 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
|
||||
// 组装新版 /sse/question 请求体
|
||||
const buildAndStream = async () => {
|
||||
let devicePeq: any;
|
||||
let latestDeviceState;
|
||||
try {
|
||||
latestDeviceState = await api.getDeviceState();
|
||||
if (firDeviceRef.current !== mac) throw new Error("Device changed");
|
||||
const peqState = await api.getPeqState();
|
||||
devicePeq = {
|
||||
peqSelect: peqState.peqSelect ?? deviceState.peqSelect ?? 0,
|
||||
@@ -566,7 +571,7 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
|
||||
const controller = streamQuestion(
|
||||
{
|
||||
question: trimmed,
|
||||
device_setting: { ...deviceState },
|
||||
device_setting: { ...latestDeviceState },
|
||||
device_peq: devicePeq,
|
||||
chat_id: currentChatId,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user