refactor(agent): scope queue actions to edit and remove
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-conversation/README.md
|
||||
README.md: 5bf3077c748c6e9be2c0a54474dce06c42eb0b2d
|
||||
README.zh.md: b4e1c9a23f1786c3dcba2063a9657a29445ed47f
|
||||
README.md: a017de28e612474dd4ad94b75385e6320e682955
|
||||
README.zh.md: b352f6f745a1458d9f0555a5d7d269fe67b8e307
|
||||
|
||||
@@ -40,5 +40,5 @@ None; this package neither assembles nor sends a provider request.
|
||||
- **The sparkle icon for the others tool row is a hand-drawn approximation** — the design glyph's vector geometry is not exportable locally; promotion into ui-primitives waits on an exact export.
|
||||
- **The approval panel's "Always allow this type" is deferred** — durable grants need a grant-storage design; only allow-once/reject answer today.
|
||||
- **TodoPanel truncates long item text to one ellipsized line** — the figma strip has no wrap or expand affordance; full text is not readable inline.
|
||||
- **Queue edit is text-only** — rows containing non-text blocks still show a flattened preview, but their edit control is disabled because the inline editor cannot preserve those blocks. A text row's edit mode replaces delete with save and cancel; Enter saves and Escape cancels. QueueDock exposes no send-now control; protocol-level promotion remains separate from the Web interaction.
|
||||
- **Web exposes pending Queue only** — QueueDock omits pending steering until steering has its own interaction. A consumed `steering/message` still renders in the durable transcript so external steering remains truthful on replay.
|
||||
- **Queue edit is text-only** — rows containing non-text blocks still show a flattened preview, but their edit control is disabled because the inline editor cannot preserve those blocks. A text row's edit mode replaces delete with save and cancel; Enter saves and Escape cancels. QueueDock exposes no send-now control.
|
||||
- **Web exposes pending Queue only** — the Host omits pending steering from the Queue snapshot until steering has its own interaction. A consumed `steering/message` still renders in the durable transcript so external steering remains truthful on replay.
|
||||
|
||||
@@ -40,5 +40,5 @@ todo 两个面就是在该形状上的两个注册项,都是普通注册方插
|
||||
- **others 工具行的闪光图标是手绘近似版本**:无法在本地导出设计字形的矢量几何;等到存在精确导出后再将其提升到 ui-primitives。
|
||||
- **审批面板的「始终允许此类」暂缓**:持久授权需要授权存储设计;今天只能回答允许一次/拒绝。
|
||||
- **TodoPanel 将过长条目截成单行省略号**:figma 条没有换行或展开入口,完整文本无法在行内读完。
|
||||
- **Queue 编辑仅支持文本**:包含非文本块的行仍显示扁平化预览,但由于内联编辑器无法保留这些块,其编辑控件会被禁用。文本行进入编辑模式后,删除会替换为保存和取消;Enter 保存,Escape 取消。QueueDock 不提供立即发送控件;协议层的前移操作与 Web 交互保持分离。
|
||||
- **Web 仅暴露待处理 Queue**:在 steering(中途引导)拥有专用交互之前,QueueDock 不展示待处理的 steering。已消费的 `steering/message` 仍会渲染到持久 transcript(文本记录)中,因此从外部提交的 steering 在回放时仍能如实呈现。
|
||||
- **Queue 编辑仅支持文本**:包含非文本块的行仍显示扁平化预览,但由于内联编辑器无法保留这些块,其编辑控件会被禁用。文本行进入编辑模式后,删除会替换为保存和取消;Enter 保存,Escape 取消。QueueDock 不提供立即发送控件。
|
||||
- **Web 仅暴露待处理 Queue**:在 steering(中途引导)拥有专用交互之前,Host 不会把待处理 steering 纳入 Queue 快照。已消费的 `steering/message` 仍会渲染到持久 transcript(文本记录)中,因此从外部提交的 steering 在回放时仍能如实呈现。
|
||||
|
||||
@@ -105,7 +105,6 @@ export interface QueuedMessage {
|
||||
readonly id: InboxItemId
|
||||
readonly preview: string
|
||||
readonly text: string | null
|
||||
readonly placement: 'queued' | 'steering'
|
||||
}
|
||||
|
||||
/** Guard union of the scoped consume-token event, checked by the machine. */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// The 'conversation.input.dock' SlotMap declaration lives in
|
||||
// ../contract/slots.ts beside the other input-region slots.
|
||||
import type { Context } from 'cordis'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type { InboxItemId, QueueAction } from '@deepseek-ai/dsh-client-connection/client'
|
||||
@@ -24,10 +24,7 @@ export type QueueDockProps = PropsRuntime<'conversation.input.dock'> & QueueDock
|
||||
|
||||
/** Queue strip: one preview line per queued message; renders null when the queue is empty. */
|
||||
export function QueueDock({ useSession, updateQueue, notify }: QueueDockProps) {
|
||||
const inbox = useSession(s => s.queue)
|
||||
// TODO(web-steer-ui): Give pending steering its own interaction before
|
||||
// exposing it; QueueDock owns only independent queued turns.
|
||||
const queue = useMemo(() => inbox.filter(row => row.placement === 'queued'), [inbox])
|
||||
const queue = useSession(s => s.queue)
|
||||
const [editing, setEditing] = useState<{ id: InboxItemId; text: string } | null>(null)
|
||||
const [busy, setBusy] = useState<InboxItemId | null>(null)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export interface IConversation {
|
||||
/**
|
||||
* Apply one operation to a pending queue occurrence.
|
||||
* @param itemId - agent-owned inbox occurrence identity.
|
||||
* @param action - edit, remove, or promote operation.
|
||||
* @param action - edit or remove operation.
|
||||
* @returns completion; business failures reject.
|
||||
*/
|
||||
updateQueue(itemId: InboxItemId, action: QueueAction): Promise<void>
|
||||
|
||||
@@ -20,7 +20,7 @@ const SID = 's1' as SessionId
|
||||
const iid = (id: string): InboxItemId => id as InboxItemId
|
||||
|
||||
function row(id: string, text: string | null, preview = text ?? '[image]'): QueuedMessage {
|
||||
return { id: iid(id), preview, text, placement: 'queued' }
|
||||
return { id: iid(id), preview, text }
|
||||
}
|
||||
|
||||
function snapshotWith(queue: QueuedMessage[]): ConversationSnapshot {
|
||||
@@ -78,19 +78,6 @@ describe('QueueDock', () => {
|
||||
expect(container.innerHTML).toBe('')
|
||||
})
|
||||
|
||||
it('hides pending steering until it has a dedicated Web interaction', () => {
|
||||
const steering = { ...row('i-steer', 'steer separately'), placement: 'steering' as const }
|
||||
const snap = snapshotWith([steering])
|
||||
const source = liveSession(snap)
|
||||
const { container } = render(<QueueDock {...kitFor(snap)} useSession={source.useSession} />)
|
||||
expect(container.innerHTML).toBe('')
|
||||
|
||||
act(() => { source.push(snapshotWith([steering, row('i-queue', 'queue visibly')])) })
|
||||
expect(container.textContent).toContain('queue visibly')
|
||||
expect(container.textContent).not.toContain('steer separately')
|
||||
expect(container.querySelectorAll('button')).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('renders active actions and disables editing for mixed-content rows', () => {
|
||||
const snap = snapshotWith([
|
||||
row('i-1', '第一条排队消息'),
|
||||
|
||||
Reference in New Issue
Block a user