Compare commits
5 Commits
55e0dcfb4f
...
70d2bceb45
| Author | SHA1 | Date | |
|---|---|---|---|
| 70d2bceb45 | |||
| dd08845bbc | |||
| 4b78fd6d40 | |||
| 011f9e14bc | |||
| 8da4a596eb |
@ -259,6 +259,8 @@ class MainTerminal(MainTerminalCommandMixin, MainTerminalContextMixin, MainTermi
|
||||
self.terminal_manager.set_host_execution_mode(mode)
|
||||
if getattr(self, "sub_agent_manager", None):
|
||||
self.sub_agent_manager.set_host_execution_mode(mode)
|
||||
if getattr(self, "file_manager", None):
|
||||
self.file_manager.set_host_execution_mode(mode)
|
||||
|
||||
def _init_host_network_permission(self):
|
||||
default_permission = str(HOST_SANDBOX_NETWORK_PERMISSION or "restricted").strip().lower()
|
||||
|
||||
@ -54,8 +54,15 @@ class FileManagerBase:
|
||||
self.container_session: Optional["ContainerHandle"] = None
|
||||
self._container_proxy: Optional[ContainerFileProxy] = None
|
||||
self._data_dir: Optional[str] = data_dir
|
||||
# 宿主机执行环境(sandbox / direct),由主终端同步;
|
||||
# direct 时与 run_command 对齐:不走路径授权检查(不套沙箱语义)。
|
||||
self.host_execution_mode: str = "sandbox"
|
||||
self.set_container_session(container_session)
|
||||
|
||||
def set_host_execution_mode(self, mode: str) -> None:
|
||||
normalized = str(mode or "").strip().lower()
|
||||
self.host_execution_mode = "direct" if normalized == "direct" else "sandbox"
|
||||
|
||||
def _load_personalization_config(self) -> Optional[Dict]:
|
||||
"""加载个性化配置"""
|
||||
if not self._data_dir:
|
||||
|
||||
@ -175,6 +175,11 @@ class PathMixin:
|
||||
def _ensure_host_access(self, full_path: Path, access: str) -> Tuple[bool, str]:
|
||||
if not self._is_host_mode():
|
||||
return True, ""
|
||||
# 执行环境为 direct(完全访问权限)时,run_command 不套沙箱、可读写任意路径;
|
||||
# read_file/write_file/edit_file 为进程内文件操作,本就不走 OS 沙箱,此处与
|
||||
# run_command 语义对齐,直接放行。sandbox 模式下保持授权范围检查不变。
|
||||
if getattr(self, "host_execution_mode", "sandbox") == "direct":
|
||||
return True, ""
|
||||
check_target = full_path
|
||||
if access == "write" and not full_path.exists():
|
||||
check_target = full_path.parent.resolve()
|
||||
|
||||
@ -107,6 +107,7 @@ export const stateMethods = {
|
||||
this.imageEntries = [];
|
||||
this.imageLoading = false;
|
||||
this.conversationHasImages = false;
|
||||
this.conversationHasVideos = false;
|
||||
this.toolSetSettingsLoading(false);
|
||||
this.toolSetSettings([]);
|
||||
this.pendingToolApprovals = [];
|
||||
|
||||
@ -189,11 +189,20 @@ export const resourceMethods = {
|
||||
} else {
|
||||
this.pendingExecutionMode = '';
|
||||
}
|
||||
if (status && typeof status.has_images !== 'undefined') {
|
||||
this.conversationHasImages = !!status.has_images;
|
||||
}
|
||||
if (status && typeof status.has_videos !== 'undefined') {
|
||||
this.conversationHasVideos = !!status.has_videos;
|
||||
// has_images/has_videos 遵循与上面模型/运行模式相同的权威规则:
|
||||
// 有打开对话时才从 status 同步;空对话/显式新建路由(/new)上 status 里的值
|
||||
// 是 terminal 残留的旧对话上下文,不能应用——空对话语义上无图片/视频,
|
||||
// 直接置 false,否则会误拦 handleModelSelect 的图片/视频能力检查。
|
||||
if (hasConversation && !onExplicitNewRoute) {
|
||||
if (status && typeof status.has_images !== 'undefined') {
|
||||
this.conversationHasImages = !!status.has_images;
|
||||
}
|
||||
if (status && typeof status.has_videos !== 'undefined') {
|
||||
this.conversationHasVideos = !!status.has_videos;
|
||||
}
|
||||
} else {
|
||||
this.conversationHasImages = false;
|
||||
this.conversationHasVideos = false;
|
||||
}
|
||||
const compression = status?.conversation?.compression;
|
||||
if (compression && typeof compression === 'object') {
|
||||
|
||||
@ -389,6 +389,18 @@ function lineNumber(line: any): string {
|
||||
color: var(--state-danger);
|
||||
}
|
||||
|
||||
/* 列表最多显示 5 行(32px/行),超出内部滚动;滚动条隐藏(同 QuickDock 惯例) */
|
||||
.edit-summary-card__list {
|
||||
max-height: 160px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.edit-summary-card__list::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.edit-summary-card__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -311,7 +311,7 @@
|
||||
}
|
||||
|
||||
.qd-run-item.is-active {
|
||||
background: var(--surface-soft);
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
.qd-run-status {
|
||||
@ -418,7 +418,7 @@
|
||||
}
|
||||
|
||||
.qd-file-item.is-active {
|
||||
background: var(--surface-soft);
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
.qd-file-name {
|
||||
|
||||
@ -308,8 +308,22 @@
|
||||
data-tutorial="quick-menu-open"
|
||||
@click.stop="$emit('toggle-quick-menu')"
|
||||
:disabled="!isConnected"
|
||||
aria-label="快捷菜单"
|
||||
>
|
||||
+
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M5 12h14" /><path d="M12 5v14" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="agent-type-switcher" :class="{ 'is-disabled': agentTypeLocked }">
|
||||
<button
|
||||
|
||||
@ -886,10 +886,6 @@ body[data-theme='light'] {
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.stadium-btn.send-btn {
|
||||
background: var(--accent);
|
||||
color: var(--on-accent);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user