Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions openless-all/app/src-tauri/src/polish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1910,7 +1910,13 @@ pub mod prompts {
const OUTPUT_BLOCK: &str = "# 输出\n\
直接输出最终文本正文。需要结构化时直接从标题 / 段落 / 编号开始。\n\
禁止以\u{201C}根据你/您给的内容\u{201D}\u{201C}我整理如下\u{201D}\u{201C}以下是整理后的内容\u{201D}\u{201C}优化如下\u{201D}\u{201C}结构化整理如下\u{201D}等句式开头。\n\
\u{4E0D}加解释、总结、客套话、代码围栏(\\`\\`\\`)或 markdown 元注释。";
\u{4E0D}加解释、总结、客套话、代码围栏(\\`\\`\\`)或 markdown 元注释。\n\
\n\
# 反 AI 自述式表达(强约束)\n\
- \u{4E0D}加 AI 自评 / 自述视角的语句:\u{201C}\u{6211}\u{4EEC}\u{770B}\u{4E86}\u{4E00}\u{4E0B}\u{201D}\u{201C}\u{6211}\u{4EEC}\u{53D1}\u{73B0}\u{201D}\u{201C}\u{7ECF}\u{8FC7}\u{5206}\u{6790}\u{201D}\u{201C}\u{7EFC}\u{5408}\u{6765}\u{770B}\u{201D}\u{201C}\u{603B}\u{4F53}\u{800C}\u{8A00}\u{201D}\u{201C}\u{6574}\u{4F53}\u{6765}\u{8BF4}\u{201D}\u{201C}\u{4F9D}\u{6211}\u{6240}\u{89C1}\u{201D}\u{201C}\u{6839}\u{636E}\u{60C5}\u{51B5}\u{201D}\u{201C}\u{4ECE}\u{7ED3}\u{679C}\u{6765}\u{770B}\u{201D}\u{7B49}\u{3002}\n\
- 保持原句的人称视角:原句是\u{201C}\u{6211}\u{201D}就用\u{201C}\u{6211}\u{201D},原句没有\u{201C}\u{6211}\u{4EEC}\u{201D}/\u{201C}\u{54B1}\u{4EEC}\u{201D}就\u{4E0D}凭空引入。\n\
- 直陈用户的实际诉求:原句说\u{201C}没问题\u{201D}就输出\u{201C}没问题\u{201D},\u{4E0D}扩写为\u{201C}\u{6211}\u{4EEC}\u{770B}\u{4E86}\u{4E00}\u{4E0B}\u{6CA1}\u{4EC0}\u{4E48}\u{5927}\u{95EE}\u{9898}\u{201D}\u{3002}\n\
- \u{4E0D}加修饰副词或铺垫句(\u{201C}\u{503C}\u{5F97}\u{4E00}\u{63D0}\u{7684}\u{662F}\u{201D}\u{201C}\u{503C}\u{5F97}\u{6CE8}\u{610F}\u{201D}\u{201C}\u{503C}\u{5F97}\u{8003}\u{8651}\u{201D}\u{7B49}\u{6F2B}\u{8C08}\u{8FC7}\u{6E21}\u{53E5})\u{3002}";

pub fn system_prompt(mode: PolishMode) -> String {
let task_and_example = match mode {
Expand All @@ -1928,14 +1934,32 @@ pub mod prompts {
去掉明显口癖、重复、无意义停顿;补充自然标点。\n\
保留用户原意、语气和表达习惯;\u{4E0D}扩写、\u{4E0D}创作。\n\
\n\
# 示例\n\
**工程化直陈**:开发协作 / 任务清单 / 技术沟通 / 工作汇报等场景下,按\u{4E3B}\u{8C13}\u{5BBE}陈述事实,\
\u{4E0D}加修饰副词、铺垫句、AI 自述(\u{201C}\u{6211}\u{4EEC}\u{770B}\u{4E86}\u{4E00}\u{4E0B}\u{201D}\u{201C}\u{603B}\u{4F53}\u{6765}\u{8BF4}\u{201D}等)。\
输出长度尽量贴近原句字数(± 20% 以内),\u{4E0D}让\u{8F7B}\u{5EA6}\u{6DA6}\u{8272}变成扩写。\n\
\n\
# 示例 1\n\
原:那个我觉得这个方案吧大概可以但是可能在性能上还要再看看\n\
出:我觉得这个方案大概可以,但性能上还要再看看。",
出:我觉得这个方案大概可以,但性能上还要再看看。\n\
\n\
# 示例 2(工程化直陈,\u{4E0D}加 AI 自述)\n\
原:嗯我们目前看了一下没什么大问题就是缓存策略可能要改一下\n\
出:目前没什么大问题,缓存策略需要调整。\
\u{200B}(注意:原句\u{6CA1}\u{6709}\u{660E}\u{786E}\u{7684}\u{201C}\u{6211}\u{4EEC}\u{201D}\u{4F5C}\u{4E3A}\u{96C6}\u{4F53},不引入\u{201C}\u{6211}\u{4EEC}\u{770B}\u{4E86}\u{4E00}\u{4E0B}\u{201D}\u{8FD9}\u{79CD}\u{81EA}\u{8FF0}\u{8868}\u{8FBE})",

PolishMode::Structured => "# 任务(清晰结构)\n\
把口述整理为脉络清晰、可直接复制走的结构化文本:保留用户的口语引子(润色后作为首行过渡),\
主动按语义把扁平事项归类成 2\u{2013}4 个主题,用双层格式呈现,尾巴查询用自然收尾句。\n\
\n\
**默认行为:双层 list。判断事项的标准**:\
以下任意一种都算一个事项 \u{2192} \u{4E0D}\u{4F9D}\u{8D56}\u{7528}\u{6237}\u{662F}\u{5426}\u{660E}\u{8BF4}\u{201C}\u{7B2C}\u{4E00}\u{201D}\u{201C}\u{7B2C}\u{4E8C}\u{201D}\u{201C}\u{53E6}\u{5916}\u{201D}\u{7B49}\u{8FDE}\u{63A5}\u{8BCD}\u{3002}\n\
\u{2003}\u{2003}1) 可独立成句的陈述(\u{4E3B}+\u{8C13}+\u{5BBE},如\u{201C}\u{300A}\u{67D0}\u{4E1C}\u{897F}\u{300B}\u{8FD8}\u{662F}\u{767D}\u{8272}\u{201D})\n\
\u{2003}\u{2003}2) 一个独立的请求 / 建议 / 处理方案(\u{5982}\u{201C}\u{8BA9}\u{5B83}\u{6D88}\u{5931}\u{201D}\u{201C}\u{6539}\u{6210}\u{5B9E}\u{9A8C}\u{6027}\u{201D})\n\
\u{2003}\u{2003}3) 一个状态判断 / 结论(\u{5982}\u{201C}\u{6CA1}\u{4EC0}\u{4E48}\u{5927}\u{95EE}\u{9898}\u{201D})\n\
\u{2003}\u{2003}4) 一个针对模块 / 主题 / 实体的描述\u{6216}\u{6307}\u{6307}\u{8981}\u{6C42}\n\
把上述事项数清,\u{2265}3 强制双层化,\u{4E0D}允许把多个独立陈述合\u{6210}一段连贯文字。\n\
即使输入听起来像\u{201C}一段顺着说下来\u{201D}的口播,只要能拆出 \u{2265}3 个独立关注点也必须双层化。\n\
\n\
**不可降级到轻度润色**:本任务的最低输出形态是双层 list 结构,\u{4E0D}允许只补标点 / 断句 / 去口癖然后输出连贯段落。\
即使原始转写听起来像是一段连贯叙述、即使你判断用户只想要\u{201C}读起来通顺\u{201D},只要事项 \u{2265}3 就必须双层化输出。\
输出连贯段落 = 失败。\n\
Expand Down Expand Up @@ -2034,9 +2058,17 @@ pub mod prompts {
\u{4E0D}引入空泛客套(\u{201C}希望您一切顺利\u{201D}\u{201C}祝商祺\u{201D}等);\
\u{4E0D}擅自承诺或扩写事实;邮件场景自动识别问候 / 落款。\n\
\n\
# 示例\n\
**工程化正式**:正式 ≠ 扩张。直陈用户原意,\u{4E0D}展开为商务铺垫,\u{4E0D}加\u{201C}\u{7ECF}\u{8FC7}\u{5206}\u{6790}\u{201D}\u{201C}\u{7EFC}\u{5408}\u{6765}\u{770B}\u{201D}\u{201C}\u{503C}\u{5F97}\u{6CE8}\u{610F}\u{7684}\u{662F}\u{201D}\u{7B49}\u{4EE3}\u{5165}\u{7B2C}\u{4E09}\u{65B9}\u{89C6}\u{89D2}\u{7684}\u{8BED}\u{53E5}\u{3002}\
输出长度尽量贴近原句字数(± 30% 以内),\u{4E0D}让\u{6B63}\u{5F0F}\u{5316}\u{6269}\u{5F20}\u{5230}\u{4E24}\u{500D}\u{957F}\u{5EA6}\u{3002}\n\
\n\
# 示例 1\n\
原:那个老板我跟你说下今天的发布我们可能要推迟因为测试还没跑完\n\
出:今天的发布需要推迟,原因是测试尚未完成。",
出:今天的发布需要推迟,原因是测试尚未完成。\n\
\n\
# 示例 2(工程化正式,\u{4E0D}加铺垫与代入语)\n\
原:嗯这次发版前我们看了一下其实问题不大但还是建议把缓存改一改\n\
出:本次发版整体问题不大,建议调整缓存策略。\
\u{200B}(注意:\u{4E0D}写\u{201C}\u{6211}\u{4EEC}\u{770B}\u{4E86}\u{4E00}\u{4E0B}\u{201D}\u{201C}\u{7ECF}\u{8FC7}\u{8BC4}\u{4F30}\u{201D}\u{4E4B}\u{7C7B}\u{4EE3}\u{5165}\u{8BED})",
};

format!(
Expand Down
32 changes: 18 additions & 14 deletions openless-all/app/src/components/Capsule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,18 @@ function Pill({ os, state, level, insertedChars, message, onCancel, onConfirm }:
>
<span
style={{
// 放大 11 → 14 让 thinking 在胶囊里更显眼。
fontSize: 14,
// 字重 500:用户反馈 700 太粗。500 是 medium 视觉重量,扫光更稳。
fontWeight: 500,
letterSpacing: 0.5,
// 字号 14 + 字重 500 时小写 g/y/p 等下伸字符在 line-height: 1 下会被
// clip。给 line-height 一点冗余 + 上下 1px padding,descender 不再被切。
// v1.3.1-6 用户反馈"thinking 不明显"——字号 14 → 17、字重 500 → 700、
// 配色由用户拍板:两侧底字浅亮黄(#FCD34D / amber-300),中段扫光深蓝
// (var(--ol-blue) ≈ #2563EB)。浅黄底色 + 深蓝扫光对比强但暖底不刺眼。
fontSize: 17,
fontWeight: 700,
letterSpacing: 0.3,
// 字号 17 + 字重 700 时小写 g/y/p 等下伸字符在 line-height: 1 下会被 clip。
// 给 line-height 冗余 + 上下 padding,descender 不再被切。
paddingBlock: 1,
// 扫光:渐变中段用更饱和的 ol-blue(不靠透明度),尾段保留 ink-3 作收尾,
// 整条 stripe 比之前更醒目(用户反馈"扫光不够明显")。
color: 'var(--ol-ink-2)',
backgroundImage:
'linear-gradient(100deg, var(--ol-ink-3) 0%, var(--ol-ink-3) 35%, var(--ol-blue) 50%, var(--ol-ink-3) 65%, var(--ol-ink-3) 100%)',
'linear-gradient(100deg, #FCD34D 0%, #FCD34D 35%, var(--ol-blue) 50%, #FCD34D 65%, #FCD34D 100%)',
backgroundSize: '220% auto',
WebkitBackgroundClip: 'text',
backgroundClip: 'text',
Expand Down Expand Up @@ -285,9 +284,10 @@ function Pill({ os, state, level, insertedChars, message, onCancel, onConfirm }:
);
}

// 与 @keyframes capsule-out 的 0.24s 时长一致——必须同步,否则定时器先于
// 与 @keyframes capsule-out 的 0.36s 时长一致——必须同步,否则定时器先于
// 动画结束就 unmount → 用户看到半截动画被截断。
const EXIT_ANIM_MS = 240;
// v1.3.1-6: 从 240ms 加到 360ms 让用户看清退出动画(240ms 太快感知不到)。
const EXIT_ANIM_MS = 360;
// 初始可见 state:Tauri 内运行从 idle 开始(等后端 capsule:state 事件),
// 浏览器 dev 模式从 recording 开始以便直接看到胶囊。
const INITIAL_VISIBLE_STATE: CapsuleState = isTauri ? 'idle' : 'recording';
Expand Down Expand Up @@ -398,8 +398,12 @@ export function Capsule() {
// 三平台一致 —— 旧版 Windows 走 animation:'none' 的分支已删除。
// transformOrigin 默认就是 50% 50%,所以 scaleX 天然以中央为锚点。
animation: leaving
? 'capsule-out .24s cubic-bezier(.4,0,.7,.2) forwards'
: 'capsule-in .26s cubic-bezier(.2,.9,.3,1.1) both',
// v1.3.1-6 调整:
// - 入场 .26s → .38s,cubic-bezier 加强 spring overshoot(更曲线感)
// - 出场 .24s → .36s(前面 EXIT_ANIM_MS 也同步到 360),曲线改成 ease-in-out 平滑
// 收缩 + 下移 + 淡出三段同步进行
? 'capsule-out .36s cubic-bezier(.55,.06,.68,.19) forwards'
: 'capsule-in .38s cubic-bezier(.16,.86,.32,1.18) both',
transformOrigin: 'center',
willChange: 'transform, opacity',
}}
Expand Down
1 change: 1 addition & 0 deletions openless-all/app/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ export const en: typeof zhCN = {
title: 'Models',
desc: 'Manage on-device ASR models. Windows can use Microsoft Foundry Local Whisper; Qwen3-ASR model management stays separate.',
qwenTitle: 'Qwen3-ASR model manager',
qwenExperimentalBadge: 'Experimental',
engineUnavailable: 'The Qwen3-ASR inference engine is not bundled on this platform. You can still download models, but Qwen3-ASR cannot be activated here yet.',
qwenUnavailableOnWindows: 'Qwen3-ASR is not supported on Windows yet. Please use Foundry Local Whisper above instead.',
foundryTitle: 'Windows Foundry Local Whisper',
Expand Down
1 change: 1 addition & 0 deletions openless-all/app/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ export const ja: typeof zhCN = {
title: 'モデル設定',
desc: '本機の ASR モデルを管理します。Windows では Microsoft Foundry Local Whisper を使用でき、Qwen3-ASR のモデル管理は独立しています。',
qwenTitle: 'Qwen3-ASR モデル管理',
qwenExperimentalBadge: '実験的',
engineUnavailable: '現在のプラットフォームには Qwen3-ASR 推論エンジンが同梱されていません。モデルのダウンロードは可能ですが、ここではまだ Qwen3-ASR を有効化できません。',
qwenUnavailableOnWindows: 'Windows では Qwen3-ASR にまだ対応していません。上記の Foundry Local Whisper をご利用ください。',
foundryTitle: 'Windows Foundry Local Whisper',
Expand Down
1 change: 1 addition & 0 deletions openless-all/app/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ export const ko: typeof zhCN = {
title: '모델 설정',
desc: '기기 내 ASR 모델을 관리합니다. Windows 에서는 Microsoft Foundry Local Whisper 를 사용할 수 있으며, Qwen3-ASR 모델 관리는 별도로 유지됩니다.',
qwenTitle: 'Qwen3-ASR 모델 관리',
qwenExperimentalBadge: '실험적',
engineUnavailable: '현재 플랫폼에는 Qwen3-ASR 추론 엔진이 포함되어 있지 않습니다. 모델은 다운로드할 수 있지만 여기서는 아직 Qwen3-ASR 을 활성화할 수 없습니다.',
qwenUnavailableOnWindows: 'Windows 에서는 아직 Qwen3-ASR 을 지원하지 않습니다. 위의 Foundry Local Whisper 를 사용해 주세요.',
foundryTitle: 'Windows Foundry Local Whisper',
Expand Down
1 change: 1 addition & 0 deletions openless-all/app/src/i18n/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ export const zhCN = {
title: '模型设置',
desc: '管理本机 ASR 模型。Windows 可使用 Microsoft Foundry Local Whisper;Qwen3-ASR 模型管理保持独立。',
qwenTitle: 'Qwen3-ASR 模型管理',
qwenExperimentalBadge: '实验性',
engineUnavailable: '当前平台暂未集成 Qwen3-ASR 推理引擎。可下载模型,但暂时无法启用 Qwen3-ASR。',
qwenUnavailableOnWindows: 'Windows 暂不支持 Qwen3-ASR,请使用上方 Foundry Local Whisper。',
foundryTitle: 'Windows Foundry Local Whisper',
Expand Down
1 change: 1 addition & 0 deletions openless-all/app/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ export const zhTW: typeof zhCN = {
title: '模型設置',
desc: '管理本機 ASR 模型。Windows 可使用 Microsoft Foundry Local Whisper;Qwen3-ASR 模型管理保持獨立。',
qwenTitle: 'Qwen3-ASR 模型管理',
qwenExperimentalBadge: '實驗性',
engineUnavailable: '當前平臺暫未集成 Qwen3-ASR 推理引擎。可下載模型,但暫時無法啟用 Qwen3-ASR。',
qwenUnavailableOnWindows: 'Windows 暫不支援 Qwen3-ASR,請使用上方的 Foundry Local Whisper。',
foundryTitle: 'Windows Foundry Local Whisper',
Expand Down
32 changes: 17 additions & 15 deletions openless-all/app/src/pages/LocalAsr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -763,13 +763,9 @@ export function LocalAsr({ embedded = false }: LocalAsrProps = {}) {
灰显 + 禁用交互 + 顶部横幅说明不可用,引导他们使用上方 Foundry Local Whisper。
Linux 当前没有任何本地 ASR 提供,沿用 IS_MAC 隐藏(dead UI 仍然要藏)。 */}
{(IS_MAC || IS_WINDOWS) && (<>
{IS_WINDOWS && (
<Card style={{ marginBottom: 16, background: 'rgba(255, 235, 200, 0.4)' }}>
<div role="alert" style={{ fontSize: 13, color: 'var(--ol-ink-2)' }}>
{t('localAsr.qwenUnavailableOnWindows')}
</div>
</Card>
)}
{/* v1.3.1-6 用户反馈:Windows 顶部"暂不支持"banner 白底太显眼。已经整段 opacity/grayscale
+ inert 灰显 + 不可交互了,banner 是 noise,直接删。AT 仍可通过区域 aria-disabled
+ 灰显视觉判断不可用。 */}
<div
aria-disabled={IS_WINDOWS || undefined}
// @ts-expect-error — `inert` 是 HTML5 标准属性(React 19+ 一类型,TS lib.dom 旧版未收录)。
Expand All @@ -789,8 +785,17 @@ export function LocalAsr({ embedded = false }: LocalAsrProps = {}) {
</Card>
)}

<div style={{ fontSize: 13, fontWeight: 700, color: 'var(--ol-ink)', margin: '4px 0 10px' }}>
{t('localAsr.qwenTitle')}
<div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: '4px 0 10px' }}>
{/* v1.3.1-6 用户拍板:千问3 ASR 改为「实验性」分组,独立于 Foundry/云端 ASR。
浅 amber badge 跟 thinking 扫光暖色调一致。 */}
<span style={{
fontSize: 10.5, fontWeight: 600, padding: '2px 7px', borderRadius: 4,
background: 'rgba(245, 158, 11, 0.15)', color: '#B45309',
letterSpacing: '0.02em', textTransform: 'uppercase',
}}>{t('localAsr.qwenExperimentalBadge')}</span>
<div style={{ fontSize: 13, fontWeight: 700, color: 'var(--ol-ink)' }}>
{t('localAsr.qwenTitle')}
</div>
</div>

<Card style={{ marginBottom: 16 }}>
Expand Down Expand Up @@ -912,12 +917,9 @@ export function LocalAsr({ embedded = false }: LocalAsrProps = {}) {
))}
</div>
) : (
/* Windows 灰显占位:后端列表为空,给一个静态 Card 表明这里"本该是模型列表"。 */
<Card>
<div style={{ fontSize: 13, color: 'var(--ol-ink-3)' }}>
{t('localAsr.qwenUnavailableOnWindows')}
</div>
</Card>
/* v1.3.1-6: Windows 列表为空时不再画白底 banner Card(用户反馈"白色显眼"),
留个低调的灰色 placeholder 维持容器高度。整段已 inert + 灰显,AT 用户感知到的也是"不可用"。 */
<div style={{ minHeight: 60 }} />
)}
</div>
)}
Expand Down
Loading