assistant — AI 助手(Copilot)
面试 / 答辩 / 会议副驾:热键求助、上下文打包、多模态问答、防投屏浮窗。可多开。
声明
json
{
"id": "community.assistant.interview_copilot",
"name": "AI 面试答题助手",
"version": "1.0.0",
"target_app_version": "0.2",
"type": "assistant",
"entrypoint": "copilot.py:InterviewCopilotPlugin",
"icon": "icon.svg",
"has_settings_tab": true,
"tab_id": "copilot",
"tab_title": "AI 面试助手",
"ui_extensions": {
"copilot_window": "Window.qml",
"style_bar_actions": "Action.qml",
"settings_view": "SettingsView.qml"
},
"config_schema": [
{ "key": "provider_preset", "label": "服务商预设", "type": "select",
"choices": ["小米 Token Plan", "DeepSeek", "Ollama 本地", "自定义"],
"presets": {
"Ollama 本地": { "base_url": "http://127.0.0.1:11434/v1", "model": "qwen2.5" }
} },
{ "key": "api_key", "label": "API Key", "type": "password", "is_secret": true }
]
}形态
python
from transbox.plugins.base import BaseAssistantPlugin
class InterviewCopilot(BaseAssistantPlugin):
def action_ask(self, prompt="", image_data="", include_history=True, turns=5, **kwargs):
# 1. 取带说话人标注的结构化历史(只有 ASR 原文,不含机翻,避免失真)
recent_turns = self.host.get_recent_conversation(turns)
# 2. 耗时的网络请求丢后台守护线程,绝不阻塞 Qt UI
self.run_in_background(self._do_stream, prompt, image_data, recent_turns)
def _do_stream(self, prompt, image_data, history):
# 3. 逐 token 推流式打字机事件到 QML
self.emit_event("stream_chunk", {"delta": "要点…", "done": False})
self.emit_event("stream_done", {"full_text": "完整答案…"})
def action_cancel(self, **kwargs):
...action_ask由 QML 通过bridge.invokePluginActionAsync(pluginId, "ask", {...})或热键触发。get_recent_conversation()返回{id, speaker, speaker_label, transcript, translation, time},speaker是peer/self。只用transcript(原文)喂模型,机翻会引入二次失真。- 用
self.emit_event()把中间态推给 QML(见 事件总线)。
挂载浮窗
json
"ui_extensions": {
"copilot_window": "Window.qml",
"style_bar_actions": "Action.qml"
}copilot_window:独立顶层毛玻璃交互浮窗(宿主main.qml按需挂载)。互斥槽位—— 同时只有一个助手能用它。style_bar_actions:在字幕条控制栏插入自定义动作按钮。
需要多个独立浮窗(不只是 copilot 那一个)时用 插件浮窗 SPI:host.create_plugin_window(...) 支持多开、定位、穿透、防录屏。
防录屏 / 防投屏(面试场景刚需)
在 QML 窗口里:
qml
Component.onCompleted: bridge.setWindowExcludeFromCapture(this, true)走 Windows 原生 SetWindowDisplayAffinity(0x00000011)——腾讯会议 / Zoom / Teams 等屏幕共享该窗口完全隐形。非 Windows 平台返回 False。
设计美学规范
- 所有 QML 必须通过
ThemeTokens与PluggableWindowBackground自动适配主题切换。 - 坚决杜绝字符字形与 Emoji 当图标,必须纯矢量 SVG。
参考实现
extensions/community_ai_interview_copilot/。
