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: 20 additions & 3 deletions desktop/electron/resources/agent_families.generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@
"payload": {
"description": "$.description",
"last_tool_name": "$.last_tool_name",
"subagent_type": "$.subagent_type",
"subtype": "$.subtype",
"task_id": "$.task_id",
"text": "$.description"
"text": "$.description",
"tool_use_id": "$.tool_use_id"
}
}
},
Expand Down Expand Up @@ -140,6 +142,9 @@
"producer": "agent",
"payload": {
"message_id": "$$.message.id",
"parent_tool_use_id": "$$.parent_tool_use_id",
"subagent": "present($$.parent_tool_use_id)",
"subagent_type": "$$.subagent_type",
"text": "$.text"
}
}
Expand All @@ -154,7 +159,10 @@
"payload": {
"id": "$.id",
"input": "$.input",
"name": "$.name"
"name": "$.name",
"parent_tool_use_id": "$$.parent_tool_use_id",
"subagent": "present($$.parent_tool_use_id)",
"subagent_type": "$$.subagent_type"
}
}
},
Expand All @@ -168,7 +176,10 @@
"payload": {
"marker_only": "absent($.thinking)",
"message_id": "$$.message.id",
"parent_tool_use_id": "$$.parent_tool_use_id",
"signature_present": "present($.signature)",
"subagent": "present($$.parent_tool_use_id)",
"subagent_type": "$$.subagent_type",
"text": "nonempty($.thinking) || \"Thinking…\""
}
}
Expand All @@ -190,7 +201,10 @@
"message_id": "$.message.id",
"model": "$.message.model",
"output_tokens": "$.message.usage.output_tokens",
"service_tier": "$.message.usage.service_tier"
"parent_tool_use_id": "$.parent_tool_use_id",
"service_tier": "$.message.usage.service_tier",
"subagent": "present($.parent_tool_use_id)",
"subagent_type": "$.subagent_type"
}
}
},
Expand All @@ -213,6 +227,9 @@
"payload": {
"content": "$.content",
"is_error": "$.is_error",
"parent_tool_use_id": "$$.parent_tool_use_id",
"subagent": "present($$.parent_tool_use_id)",
"subagent_type": "$$.subagent_type",
"tool_use_id": "$.tool_use_id"
}
}
Expand Down
8 changes: 8 additions & 0 deletions desktop/src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ const en: Dict = {
'tx.dock.todos': 'Todos ({done}/{total})',
'tx.dock.close': 'Close panel',
'tx.dock.noTodos': 'No todos in the latest plan.',
// R5 — one sub-agent's own activity.
'tx.dock.back': 'Back to the list',
'tx.dock.subQuiet': 'This sub-agent has not done anything yet.',
'tx.dock.subUnreported': 'This engine does not report which events are a sub-agent’s, so its work cannot be separated from the main agent’s here. The request above is what it was asked to do.',
'tx.now': 'now',
'composer.attach': 'Attach file or image',
'composer.slashMenu': 'Slash commands',
Expand Down Expand Up @@ -2894,6 +2898,10 @@ const zh: Dict = {
'tx.dock.todos': '待办 ({done}/{total})',
'tx.dock.close': '关闭面板',
'tx.dock.noTodos': '最新的计划中没有待办。',
// R5 — 单个子代理的活动。
'tx.dock.back': '返回列表',
'tx.dock.subQuiet': '该子代理尚未有任何动作。',
'tx.dock.subUnreported': '该引擎不会标明哪些事件来自子代理,因此这里无法把它的工作与主代理分开。上方显示的是它被要求完成的任务。',
'tx.now': '刚刚',
'composer.attach': '附加文件或图片',
'composer.slashMenu': '斜杠命令',
Expand Down
73 changes: 73 additions & 0 deletions desktop/src/styles/partials/05-transcript-boards.css
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,79 @@
padding: var(--spacing-s4) 0;
font-size: var(--font-size-body-small);
}

/* R5 — a sub-agent row opens that agent's own activity. The button carries
the row's layout so the drill-down affordance doesn't reflow the list; only
the chevron is new. Shell rows keep the plain <li> and are unaffected. */
.sd-row-open {
display: flex;
align-items: center;
gap: var(--spacing-s6);
flex: 1;
min-width: 0;
padding: 0;
border: 0;
border-radius: var(--radius-sm);
background: transparent;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
}
.sd-row-open:hover {
background: var(--surface-hover);
}
.sd-row-chev {
margin-left: auto;
opacity: 0.5;
}
.sd-sub {
display: flex;
flex-direction: column;
gap: var(--spacing-s4);
min-width: 0;
}
.sd-sub-type {
display: inline-flex;
align-items: center;
gap: var(--spacing-s4);
color: var(--text-muted);
font-size: var(--font-size-caption);
}
/* The prompt is the one thing every engine can show, so it gets room to be
read — wrapped and selectable, not clamped to a row. */
.sd-sub-prompt {
max-height: 7em;
overflow-y: auto;
padding: var(--spacing-s4) var(--spacing-s8);
border-left: 2px solid var(--border);
color: var(--text);
font-size: var(--font-size-body-small);
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.sd-sub-now {
font-size: var(--font-size-caption);
font-style: italic;
}
.sd-sub-line {
gap: var(--spacing-s4);
}
.sd-sub-detail {
min-width: 0;
overflow: hidden;
color: var(--text-muted);
text-overflow: ellipsis;
white-space: nowrap;
}
/* Prose the sub-agent produced reads as prose, not as a tool row. */
.sd-sub-line.k-text .sd-sub-detail {
color: var(--text);
}
.sd-sub-line.k-thought .sd-sub-detail {
font-style: italic;
opacity: 0.8;
}
.sd-row-name {
flex: 0 0 auto;
font-weight: 600;
Expand Down
11 changes: 9 additions & 2 deletions desktop/src/surfaces/AgentTranscript.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { agentIsBusy, errorLabel, eventIsError, FEED_LENSES, isHiddenInFeed, mat
import { collapseStreamingPartials } from '../ui/streamingPartials';
import { groupToolCalls, toolCallUpdateParentId, type FeedRow } from '../ui/toolGroups';
import { ToolGroupCard } from '../ui/ToolGroupCard';
import { deriveStateDock } from '../ui/stateDock';
import { deriveStateDock, subagentDetail, type DockCall } from '../ui/stateDock';
// NB explicit .tsx: the pure module `stateDock.ts` differs from this file
// name only in casing, so on macOS's case-insensitive filesystem a bare
// '../ui/StateDock' import resolves to stateDock.ts (TS1149). The extension
Expand Down Expand Up @@ -396,6 +396,13 @@ export function AgentTranscript({ agentId, sessionId }: { agentId: string; sessi
() => deriveStateDock(feed, { nameById, resultById, updateById }),
[feed, nameById, resultById, updateById],
);
// R5 — one sub-agent's own activity, resolved on demand. A callback rather
// than a precomputed map because only the row the director opened needs the
// scan, and the dock re-derives on every event.
const subagentDetailFor = useCallback(
(call: DockCall) => subagentDetail(feed, call, { nameById, resultById, updateById }),
[feed, nameById, resultById, updateById],
);
// P1 tool-group collapse state (kimi-web parity — plan §7 decision 3):
// groups are EXPANDED by default and never auto-collapse; the header click
// is the only toggle, opt-in per group instance. Keyed by the group's
Expand Down Expand Up @@ -1314,7 +1321,7 @@ export function AgentTranscript({ agentId, sessionId }: { agentId: string; sessi
)}
{/* P2 state dock — live mode only, outside the virtual list,
directly above the composer. */}
<StateDock model={stateDock} />
<StateDock model={stateDock} subagentDetailFor={subagentDetailFor} />
{/* R2 — the ring sits in the composer's own row, not the header
strip, because its question ("is there room for this prompt?")
is asked while typing. The strip keeps the same numbers as text
Expand Down
Loading
Loading