Merge branch 'feature/workspace-conversations' into main

This commit is contained in:
JOJO 2026-05-27 23:38:30 +08:00
commit 5cef9c4b2b

View File

@ -1209,6 +1209,663 @@
打开
</button>
</div>
<div class="behavior-section">
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">使用自定义称呼</span>
<p class="field-desc">
开启后对话区域将使用您在"个性化设置"中配置的自称和称呼关闭则显示默认的"AI
Assistant"和"用户"
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.use_custom_names"
@change="
personalization.updateField({
key: 'use_custom_names',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>在对话中显示自定义称呼</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">增强工具显示</span>
<p class="field-desc">
开启后工具块将显示格式化的内容关闭则显示原始 JSON 数据默认开启
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.enhanced_tool_display"
@change="
personalization.updateField({
key: 'enhanced_tool_display',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>显示格式化的工具结果更清晰易读</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">AGENTS.md 自动注入</span>
<p class="field-desc">
开启后如果工作区根目录存在 AGENTS.md 文件系统会自动将其内容注入到系统提示词中
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.agents_md_auto_inject"
@change="
personalization.updateField({
key: 'agents_md_auto_inject',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>自动注入 AGENTS.md 到系统提示词</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">最近对话提示</span>
<p class="field-desc">
开启后系统会把当前工作区最近若干个非空对话的标题和首条用户消息注入到系统提示词中帮助智能体主动判断是否需要回顾历史
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.recent_conversations_prompt_enabled"
@change="
personalization.updateField({
key: 'recent_conversations_prompt_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>在提示词中加入最近对话</span>
</label>
<div
v-if="form.recent_conversations_prompt_enabled"
class="compression-custom-grid"
>
<label class="compression-input-row">
<span>注入数量</span>
<input
type="number"
:min="recentConversationsPromptLimitRange.min"
:max="recentConversationsPromptLimitRange.max"
step="1"
placeholder="默认 10"
:value="form.recent_conversations_prompt_limit"
@input="handleRecentConversationsPromptLimitInput"
@change="commitRecentConversationsPromptLimitInput"
@blur="commitRecentConversationsPromptLimitInput"
@focus="personalization.clearFeedback()"
/>
</label>
<p class="field-desc compression-custom-hint">
范围 {{ recentConversationsPromptLimitRange.min }}~{{
recentConversationsPromptLimitRange.max
}}
空对话不会注入
</p>
</div>
<div
v-if="form.recent_conversations_prompt_enabled"
class="compression-actions-row"
>
<button
type="button"
class="compression-reset-btn"
@click.prevent="restoreRecentConversationsPromptLimit"
>
恢复默认
</button>
</div>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">允许根目录创建文件</span>
<p class="field-desc">
开启后允许在工作区根目录创建文件关闭则禁止在根目录创建文件需要先创建子目录
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.allow_root_file_creation"
@change="
personalization.updateField({
key: 'allow_root_file_creation',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>允许在根目录创建文件</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">上下文压缩策略</span>
<p class="field-desc">可分别控制自动浅层压缩与自动深层压缩</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.auto_shallow_compress_enabled"
@change="
personalization.updateField({
key: 'auto_shallow_compress_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>自动浅层压缩</span>
</label>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.auto_deep_compress_enabled"
@change="
personalization.updateField({
key: 'auto_deep_compress_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>自动深层压缩</span>
</label>
<div class="compression-custom-grid">
<label class="compression-input-row">
<span>浅压缩触发上下文</span>
<input
type="number"
min="1000"
step="1"
placeholder="默认 80000"
:value="form.shallow_compress_trigger_tokens ?? ''"
@input="
handleCompressionNumberInput(
'shallow_compress_trigger_tokens',
$event
)
"
@focus="personalization.clearFeedback()"
/>
</label>
<label class="compression-input-row">
<span>浅压缩保留最近 Tool 条数</span>
<input
type="number"
min="0"
step="1"
placeholder="默认 15"
:value="form.shallow_compress_keep_recent_tools ?? ''"
@input="
handleCompressionNumberInput(
'shallow_compress_keep_recent_tools',
$event
)
"
@focus="personalization.clearFeedback()"
/>
</label>
<label class="compression-input-row">
<span>浅压缩保留用户输入后 Tool 条数</span>
<input
type="number"
min="0"
max="50"
step="1"
placeholder="默认 3"
:value="form.shallow_compress_keep_user_turn_tools ?? ''"
@input="
handleCompressionNumberInput(
'shallow_compress_keep_user_turn_tools',
$event
)
"
@focus="personalization.clearFeedback()"
/>
</label>
<label class="compression-input-row">
<span>浅压缩每轮最多替换条数</span>
<input
type="number"
min="1"
step="1"
placeholder="默认 10"
:value="form.shallow_compress_max_replace_per_round ?? ''"
@input="
handleCompressionNumberInput(
'shallow_compress_max_replace_per_round',
$event
)
"
@focus="personalization.clearFeedback()"
/>
</label>
<label class="compression-input-row">
<span>浅压缩触发间隔Tool 调用次数</span>
<input
type="number"
min="1"
step="1"
placeholder="默认 10"
:value="form.shallow_compress_trigger_tool_calls_interval ?? ''"
@input="
handleCompressionNumberInput(
'shallow_compress_trigger_tool_calls_interval',
$event
)
"
@focus="personalization.clearFeedback()"
/>
</label>
<label class="compression-input-row">
<span>深压缩触发上下文</span>
<input
type="number"
min="1000"
step="1"
placeholder="默认 150000"
:value="form.deep_compress_trigger_tokens ?? ''"
@input="
handleCompressionNumberInput(
'deep_compress_trigger_tokens',
$event
)
"
@focus="personalization.clearFeedback()"
/>
</label>
</div>
<div class="compression-actions-row">
<button
type="button"
class="compression-reset-btn"
@click.prevent="restoreCompressionDefaults"
>
恢复默认
</button>
</div>
<p class="field-desc compression-custom-hint">
自定义项留空则使用默认值深压缩触发上下文必须大于浅压缩触发上下文
</p>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">堆叠块显示模式</span>
<p class="field-desc">选择思考/工具块的显示方式默认为堆叠动画</p>
</div>
<div class="run-mode-options">
<button
v-for="option in blockDisplayOptions"
:key="option.id"
type="button"
class="run-mode-card"
:class="{ active: experiments.blockDisplayMode === option.value }"
:aria-pressed="experiments.blockDisplayMode === option.value"
@click.prevent="handleBlockDisplayModeChange(option.value)"
>
<div class="run-mode-card-header">
<span class="run-mode-title">{{ option.label }}</span>
<span v-if="option.badge" class="run-mode-badge">{{
option.badge
}}</span>
</div>
<p class="run-mode-desc">{{ option.desc }}</p>
</button>
</div>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">静默禁用</span>
<p class="field-desc">
禁用工具时不再注入提示消息模型不会感知被禁用项
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.silent_tool_disable"
@change="
personalization.updateField({
key: 'silent_tool_disable',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>静默禁用工具不向模型提示</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">自动生成对话标题</span>
<p class="field-desc">默认开启关闭后标题将沿用首条消息</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.auto_generate_title"
@change="
personalization.updateField({
key: 'auto_generate_title',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>使用快速模型为新对话生成含 emoji 的简短标题</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">工具意图提示</span>
<p class="field-desc">
开启后调用工具时会先用约15字告诉你要做什么替代正在/完成文案
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.tool_intent_enabled"
@change="
personalization.updateField({
key: 'tool_intent_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>在工具块显示"我要做什么"的简短提示</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">Skill 提示系统</span>
<p class="field-desc">
开启后检测到特定关键词时会自动提示模型阅读相关 skill
terminal-guidesub-agent-guide
</p>
</div>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.skill_hints_enabled"
@change="
personalization.updateField({
key: 'skill_hints_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>根据关键词自动提示阅读相关 skill</span>
</label>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">强约束系统</span>
<p class="field-desc">
开启后若未在当前对话先阅读对应
SKILL.md直接调用工具会返回必须先阅读仅对个人空间中已启用的 skill
生效
</p>
</div>
<div class="strict-skill-grid">
<label class="toggle-row">
<input
type="checkbox"
:checked="form.skill_strict_terminal_enabled"
@change="
personalization.updateField({
key: 'skill_strict_terminal_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>Terminal 系列工具</span>
</label>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.skill_strict_sub_agent_enabled"
@change="
personalization.updateField({
key: 'skill_strict_sub_agent_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>子智能体系列工具</span>
</label>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.skill_strict_run_command_foreground_enabled"
@change="
personalization.updateField({
key: 'skill_strict_run_command_foreground_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>run_command 前台模式</span>
</label>
<label class="toggle-row">
<input
type="checkbox"
:checked="form.skill_strict_run_command_background_enabled"
@change="
personalization.updateField({
key: 'skill_strict_run_command_background_enabled',
value: $event.target.checked
})
"
/>
<span class="fancy-check" aria-hidden="true">
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>run_command 后台模式</span>
</label>
</div>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">默认禁用工具类别</span>
<p class="field-desc">
选择后这些类别在新任务中会保持关闭也可随时通过快捷菜单临时开启
</p>
</div>
<div class="tool-category-grid" v-if="toolCategories.length">
<label
v-for="category in toolCategories"
:key="category.id"
class="tool-category-chip"
>
<input
type="checkbox"
:checked="form.disabled_tool_categories.includes(category.id)"
@change="toggleCategory(category.id)"
/>
<span>{{ category.label }}</span>
</label>
</div>
<p class="behavior-hint" v-else>暂无可配置的工具类别</p>
</div>
<div class="behavior-field">
<div class="behavior-field-header">
<span class="field-title">智能体交流风格</span>
<p class="field-desc">智能体和您交流时使用何种形式</p>
</div>
<div class="run-mode-options">
<button
type="button"
class="run-mode-card"
:class="{ active: form.communication_style === 'default' }"
:aria-pressed="form.communication_style === 'default'"
@click.prevent="setCommunicationStyle('default')"
>
<div class="run-mode-card-header">
<span class="run-mode-title">默认</span>
</div>
<p class="run-mode-desc">智能体会使用标准的AI风格的语言和您交流</p>
</button>
<button
type="button"
class="run-mode-card"
:class="{ active: form.communication_style === 'human_like' }"
:aria-pressed="form.communication_style === 'human_like'"
@click.prevent="setCommunicationStyle('human_like')"
>
<div class="run-mode-card-header">
<span class="run-mode-title">拟人</span>
</div>
<p class="run-mode-desc">智能体会像聊天一样模仿人类的语言风格和您交流</p>
</button>
</div>
</div>
</div>
<div class="settings-action-row">
<span class="settings-row-copy"
><span class="settings-row-title">管理员监控入口</span
@ -1310,7 +1967,8 @@ const {
skillsCatalog,
thinkingIntervalDefault,
thinkingIntervalRange,
recentConversationsPromptLimitRange
recentConversationsPromptLimitRange,
experiments
} = storeToRefs(personalization);
type IconKey = keyof typeof ICONS;