接入 AI 模型
目标:用 LFModel 调用PluginX AI 网关,做一个点击按钮流式输出 AI 总结的小应用。
main.js
js
// ==UserScript==
// @name AI Page Summary
// @description 一键让 AI 总结当前页面标题
// @match https://example.com/*
// @require dom
// @require model
// ==/UserScript==
LFDOM.ready(() => {
const panel = LFDOM.createFloatingRoot({ id: "ai-summary" });
panel.innerHTML =
"<button id='lf-sum'>AI Summary</button><div id='lf-out' style='max-width:280px'></div>";
panel.querySelector("#lf-sum").addEventListener("click", async () => {
const out = panel.querySelector("#lf-out");
out.textContent = "";
try {
const { models } = await LFModel.listModels();
const chatModel = models.find((m) => m.kind === "chat");
for await (const chunk of LFModel.chatStream({
model: chatModel.id,
messages: [{ role: "user", content: `用一句话总结这个页面标题: ${document.title}` }],
})) {
if (chunk.kind === "delta") out.textContent += chunk.data.choices?.[0]?.delta?.content ?? "";
}
} catch (error) {
out.textContent = `调用失败: ${error.errorCode || error.message}`;
}
});
});关键点
listModels()返回当前账号可用的模型列表,对话模型和图片模型混在一起,按kind === "chat"挑选,不要硬编码模型 IDchat()总是一次性返回完整结果(传stream: true也会被改成 false),要逐字输出必须用chatStream()chatStream()返回异步迭代器,chunk.kind === "delta"的分片里chunk.data是 OpenAI 流式 chunk 对象,增量文本在chunk.data.choices[0].delta.content- 出错时循环抛
LFModelError,按errorCode分支(如INSUFFICIENT_BALANCE、APP_BUDGET_EXHAUSTED) - 调用会计入当前应用预算;
cost_points/charge_points是规范积分字段(1 CNY = 200 points)。用getBudget()/getUsage()查询额度与消耗 - 模型调用经扩展后台携带PluginX登录态,无法指定其它应用的身份