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
23 changes: 23 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -945,3 +945,26 @@ it natively. Each component lives in its own self-registering directory under
view, so a catalog/renderer mismatch never breaks the page. To add a component,
drop a folder there (frontend) and declare it in the agent's catalog (backend —
see `veadk.a2ui.BaseA2UICatalog`).

### Sleeping agents

Agent categories query live Sessions and Session snapshots without restoring them,
including legacy requests with `autoResumeSnapshots=true`. Studio presents the
latest saved record for each logical agent, unless a live Session already
represents it. Live and wakeable cards share the Ready label and styling; saved
records show Never expires. Details use the same Ready label and explain
separately when opening requires waking the agent. Snapshot `SessionMetadata` supplies its display
name, creator and agent kind, including on SDK versions that omit this field.
Owners can list, wake and delete their own records; administrators can also manage
legacy records without owner metadata. Records with a different agent kind are
excluded when kinds share a Tool.

Opening a sleeping agent explicitly restores it and then opens its normal entry
point. The UI explains the wait using “waking” language and permits retry after a
failure. Same-agent wake requests are serialized within a service instance, and
retries check for an existing live Session. This is not a distributed lock.
Deleting a sleeping agent requires confirmation and sends `ToolId` and `SnapshotId`
to `DeleteSessionSnapshot`; it deletes the selected saved record only. If that
logical agent has older records, the next latest record can appear on refresh.
Failed records remain visible for deletion but cannot be opened. The UI uses
agent terminology rather than exposing these control-plane resource types.
10 changes: 8 additions & 2 deletions frontend/src/adk/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export const CODEX_PROJECT_HANDOFF_PAIRING_TTL_SECONDS = 60 * 60;
export const SANDBOX_DISPLAY_NAME_MAX_LENGTH = 40;
export type SandboxAgentKind = "deepseek-harness" | "openclaw" | "hermes";

/** Present agent availability without changing the underlying lifecycle state. */
export function sandboxCardStatus(status: string): string {
const normalized = status.trim().toLowerCase();
return ["ready", "running", "wakeable"].includes(normalized) ? "ready" : normalized;
}

export function sandboxStatusLabel(status: string): string {
switch (status.trim().toLowerCase()) {
case "ready":
Expand Down Expand Up @@ -697,8 +703,8 @@ function parseSnapshot(
}

function sandboxListUrl(base: string, options?: SandboxListOptions): string {
if (!options?.autoResumeSnapshots) return base;
const params = new URLSearchParams({ autoResumeSnapshots: "true" });
if (options?.autoResumeSnapshots === undefined) return base;
const params = new URLSearchParams({ autoResumeSnapshots: String(options.autoResumeSnapshots) });
return `${base}?${params.toString()}`;
}

Expand Down
8 changes: 4 additions & 4 deletions frontend/src/i18n/resources/en-US/adk.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@
"sandbox": {
"status": {
"ready": "Ready",
"wakeable": "Wakeable",
"wakeable": "Asleep",
"creating": "Creating",
"starting": "Starting",
"pending": "Pending",
Expand Down Expand Up @@ -276,9 +276,9 @@
"missingSessionForTerminal": "The AgentKit session for the terminal is missing.",
"openTerminalFailed": "Unable to open the {{kind}} terminal.",
"deleteAgentFailed": "Unable to delete the {{kind}} agent.",
"missingSnapshot": "The AgentKit snapshot to wake is missing.",
"resumeSnapshotFailed": "Unable to wake the agent from its snapshot. Try again later.",
"deleteSnapshotFailed": "Unable to delete the agent snapshot.",
"missingSnapshot": "The agent to wake was not found.",
"resumeSnapshotFailed": "Unable to wake the agent. Try again later.",
"deleteSnapshotFailed": "Unable to delete the agent. Try again later.",
"missingSessionToConnect": "The AgentKit session to connect is missing.",
"connectCodexFailed": "Unable to connect to the Codex agent. Try again later.",
"sessionNotReady": "The AgentKit session is not ready. Current status: {{status}}.",
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/i18n/resources/en-US/newChat.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
"loadType": "Load {{type}}",
"connectGeneral": "Connect to General Agent",
"openLocal": "Open local Agent",
"openType": "Open {{type}}"
"openType": "Open {{type}}",
"wakingHint": "Waking the agent. This may take some time."
},
"skill": {
"spaceAria": "Skill spaces",
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/i18n/resources/en-US/sandbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
},
"agentDetails": {
"back": "Back to Agents",
"subtitle": "{{agent}} AgentKit Session details",
"subtitle": "{{agent}} agent details",
"type": "Agent type",
"status": "Status",
"createdBy": "Created by",
Expand All @@ -161,9 +161,12 @@
"wake": "Wake Agent",
"open": "Open Agent",
"deleteTitle": "Delete Agent?",
"deleteDescription": "This will delete “{{name}}” and its AgentKit {{resource}}. This action cannot be undone.",
"deleteDescription": "Delete “{{name}}” and its saved data? This cannot be undone.",
"deleting": "Deleting…",
"confirmDelete": "Delete"
"confirmDelete": "Delete",
"sleepingHint": "This agent is asleep. Waking it before opening may take some time.",
"wakingHint": "Waking the agent. This may take some time.",
"agentId": "Agent ID"
},
"agentWorkspace": {
"back": "Back to Agents",
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/i18n/resources/en-US/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -1338,7 +1338,7 @@
"remainingTime": "Time remaining",
"expiringSoon": "Expiring soon",
"sandboxRemaining": "{{hours}} hr {{minutes}} min",
"wakeable": "Wakeable",
"wakeable": "Asleep",
"neverExpires": "Never expires",
"editDraftNamed": "Edit draft {{name}}",
"viewProgress": "View progress",
Expand Down Expand Up @@ -1381,7 +1381,7 @@
},
"sandboxStatus": {
"ready": "Ready",
"wakeable": "Wakeable",
"wakeable": "Asleep",
"creating": "Creating",
"starting": "Starting",
"initializing": "Starting",
Expand All @@ -1394,7 +1394,8 @@
"deleting": "Deleting",
"deleted": "Deleted",
"unknown": "Unknown status"
}
},
"wakingHint": "Waking the agent. This may take some time."
},
"skillCenter": {
"library": "Skill library",
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/i18n/resources/zh-CN/adk.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@
"sandbox": {
"status": {
"ready": "就绪",
"wakeable": "可唤醒",
"wakeable": "已休眠",
"creating": "创建中",
"starting": "启动中",
"pending": "等待中",
Expand Down Expand Up @@ -276,9 +276,9 @@
"missingSessionForTerminal": "缺少要打开 Terminal 的 AgentKit Session。",
"openTerminalFailed": "无法打开 {{kind}} Terminal。",
"deleteAgentFailed": "无法删除 {{kind}} 智能体。",
"missingSnapshot": "缺少要唤醒的 AgentKit Snapshot。",
"resumeSnapshotFailed": "无法从快照唤醒智能体,请稍后重试。",
"deleteSnapshotFailed": "无法删除智能体快照。",
"missingSnapshot": "未找到要唤醒的智能体。",
"resumeSnapshotFailed": "无法唤醒智能体,请稍后重试。",
"deleteSnapshotFailed": "无法删除智能体,请稍后重试。",
"missingSessionToConnect": "缺少要连接的 AgentKit Session。",
"connectCodexFailed": "无法连接 Codex 智能体,请稍后重试。",
"sessionNotReady": "AgentKit Session 尚未就绪,当前状态:{{status}}。",
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/i18n/resources/zh-CN/newChat.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
"loadType": "加载 {{type}}",
"connectGeneral": "连接通用智能体",
"openLocal": "打开本地智能体",
"openType": "打开 {{type}}"
"openType": "打开 {{type}}",
"wakingHint": "正在唤醒智能体,可能需要一些时间。"
},
"skill": {
"spaceAria": "技能空间",
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/i18n/resources/zh-CN/sandbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
},
"agentDetails": {
"back": "返回智能体列表",
"subtitle": "{{agent}} AgentKit Session 详情",
"subtitle": "{{agent}} 智能体详情",
"type": "智能体类型",
"status": "状态",
"createdBy": "创建人",
Expand All @@ -161,9 +161,12 @@
"wake": "唤醒智能体",
"open": "打开智能体",
"deleteTitle": "删除智能体?",
"deleteDescription": "将删除“{{name}}”及其 AgentKit {{resource}},此操作无法撤销。",
"deleteDescription": "将删除“{{name}}”及其保存的数据,此操作无法撤销。",
"deleting": "删除中…",
"confirmDelete": "确认删除"
"confirmDelete": "确认删除",
"sleepingHint": "该智能体已休眠,进入时需要唤醒,可能需要一些时间。",
"wakingHint": "正在唤醒智能体,可能需要一些时间。",
"agentId": "智能体 ID"
},
"agentWorkspace": {
"back": "返回智能体列表",
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/i18n/resources/zh-CN/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -1338,7 +1338,7 @@
"remainingTime": "剩余时间",
"expiringSoon": "即将清空",
"sandboxRemaining": "{{hours}} 小时 {{minutes}} 分钟",
"wakeable": "可唤醒",
"wakeable": "已休眠",
"neverExpires": "永不过期",
"editDraftNamed": "编辑草稿 {{name}}",
"viewProgress": "查看进度",
Expand Down Expand Up @@ -1381,7 +1381,7 @@
},
"sandboxStatus": {
"ready": "就绪",
"wakeable": "可唤醒",
"wakeable": "已休眠",
"creating": "创建中",
"starting": "启动中",
"initializing": "启动中",
Expand All @@ -1394,7 +1394,8 @@
"deleting": "删除中",
"deleted": "已删除",
"unknown": "未知状态"
}
},
"wakingHint": "正在唤醒智能体,可能需要一些时间。"
},
"skillCenter": {
"library": "技能库",
Expand Down
33 changes: 27 additions & 6 deletions frontend/src/ui/MyAgents.css
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,6 @@
color: hsl(142 55% 28%);
}

.my-agent-status-label[data-wakeable] {
border-color: hsl(43 90% 48% / 0.3);
background: hsl(45 96% 52% / 0.14);
color: hsl(38 78% 36%);
}

.my-agent-compatibility-trigger {
flex: 0 0 auto;
display: inline-flex;
Expand Down Expand Up @@ -374,3 +368,30 @@
}

}

.my-agent-wake-note {
margin: 8px 0 0;
color: hsl(var(--muted-foreground));
font-size: 12px;
line-height: 1.5;
}

.my-agent-wake-note[role="alert"] {
position: relative;
z-index: 2;
min-width: 0;
min-height: 0;
max-height: 3em;
display: -webkit-box;
overflow: hidden;
overflow-wrap: anywhere;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
color: hsl(var(--destructive));
}

.my-agent-error-tooltip {
max-height: min(320px, 60vh);
overflow: auto;
overflow-wrap: anywhere;
}
Loading
Loading