mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
Merge pull request #3071 from deepseek-harness/worktree/3070-minimal-bash-card-expand
fix(web): expand persistent Bash result cards
This commit is contained in:
@@ -1,25 +1,41 @@
|
||||
import { mkdir, writeFile } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
|
||||
import type { Browser, Page } from 'playwright'
|
||||
import { chromium } from 'playwright'
|
||||
import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest'
|
||||
import type { AgentHandle } from '@deepseek-ai/dsh-agent'
|
||||
import { CallId, createUserMessage } from '@deepseek-ai/dsh-llm'
|
||||
import { SessionId } from '@deepseek-ai/dsh-session'
|
||||
import type {} from '@deepseek-ai/dsh-agent-presets'
|
||||
import type {} from '@deepseek-ai/dsh-system-prompt'
|
||||
import { assertFixtureInventory, launchWebScaffold, type WebScaffold } from './scaffold.ts'
|
||||
import {
|
||||
assertFixtureInventory,
|
||||
captureStableAria,
|
||||
compareOrRefreshGolden,
|
||||
launchWebScaffold,
|
||||
watchConsole,
|
||||
webSnapshotMode,
|
||||
type WebScaffold,
|
||||
} from './scaffold.ts'
|
||||
import { newEnglishPage, saveFailureShot } from './support.ts'
|
||||
|
||||
const SNAPSHOT_DIR = fileURLToPath(new URL('../../../snapshots/web/minimal-preset', import.meta.url))
|
||||
const FIXTURE = join(SNAPSHOT_DIR, 'session.jsonl')
|
||||
const PROMPT = 'Reply exactly MINIMAL_PRESET_REQUEST_OK and stop.'
|
||||
const UI_EXPECTED = join(SNAPSHOT_DIR, 'ui.expected.md')
|
||||
const MODE = webSnapshotMode()
|
||||
const PROMPT = "Use the bash tool to run exactly: printf 'MINIMAL_BASH_CARD_OK\\n'. Then reply exactly MINIMAL_PRESET_REQUEST_OK and stop."
|
||||
|
||||
describe('minimal agent preset', () => {
|
||||
let scaffold: WebScaffold
|
||||
let agentHandle: AgentHandle
|
||||
let disposeInjectedPrompt: () => void
|
||||
let browser: Browser | undefined
|
||||
let page: Page | undefined
|
||||
let tripwire: ReturnType<typeof watchConsole> | undefined
|
||||
|
||||
beforeAll(async () => {
|
||||
scaffold = await launchWebScaffold({ replayFixture: FIXTURE, compareReplaySession: true })
|
||||
scaffold = await launchWebScaffold({ replayFixture: FIXTURE, compareReplaySession: true, paceMs: 10 })
|
||||
disposeInjectedPrompt = scaffold.ctx.systemPrompt.section({
|
||||
name: 'test:injected-prompt',
|
||||
order: 999,
|
||||
@@ -31,10 +47,17 @@ describe('minimal agent preset', () => {
|
||||
agentOptions: { provider: 'deepseek-official', model: 'deepseek-v4-flash' },
|
||||
setup: agentCtx => scaffold.ctx.agentPresets.mount(agentCtx, 'minimal').then(() => undefined),
|
||||
})
|
||||
agentHandle.agent.followup(createUserMessage({
|
||||
content: [{ type: 'text', text: PROMPT }],
|
||||
source: { kind: 'user' },
|
||||
}))
|
||||
await agentHandle.agent.whenIdle()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
const failures: unknown[] = []
|
||||
await page?.close().catch((error: unknown) => failures.push(error))
|
||||
await browser?.close().catch((error: unknown) => failures.push(error))
|
||||
await agentHandle?.dispose().catch((error: unknown) => failures.push(error))
|
||||
try {
|
||||
disposeInjectedPrompt?.()
|
||||
@@ -47,12 +70,6 @@ describe('minimal agent preset', () => {
|
||||
})
|
||||
|
||||
it('sends the exact RL prompt and schemas, then executes the persistent shell and editor', async () => {
|
||||
agentHandle.agent.followup(createUserMessage({
|
||||
content: [{ type: 'text', text: PROMPT }],
|
||||
source: { kind: 'user' },
|
||||
}))
|
||||
await agentHandle.agent.whenIdle()
|
||||
|
||||
const requestHeader = agentHandle.agent.session.requestHeader()
|
||||
if (requestHeader === undefined) throw new Error('the minimal agent issued no model request')
|
||||
expect(agentHandle.agent.session.events.some(event => event.type === 'user/message'
|
||||
@@ -119,10 +136,48 @@ describe('minimal agent preset', () => {
|
||||
`)
|
||||
expect(requestHeader.tools?.toSorted((left, right) => left.name.localeCompare(right.name)))
|
||||
.toEqual(scaffold.ctx.tools.schemas(agentHandle.agent).toSorted((left, right) => left.name.localeCompare(right.name)))
|
||||
})
|
||||
|
||||
it.skipIf(MODE === 'record')('expands the completed persistent Bash call in the Web conversation', async () => {
|
||||
onTestFailed(() => { if (page !== undefined) void saveFailureShot(page, 'web-minimal-persistent-bash-card') })
|
||||
browser = await chromium.launch()
|
||||
page = await newEnglishPage(browser)
|
||||
tripwire = watchConsole(page)
|
||||
await page.goto(scaffold.authenticatedUrl, { waitUntil: 'load' })
|
||||
await page.waitForSelector('[class*="frame"]', { timeout: 30_000 })
|
||||
|
||||
const groupRow = page.locator('[role="treeitem"]').first()
|
||||
await groupRow.waitFor({ timeout: 15_000 })
|
||||
await groupRow.click()
|
||||
const sessionRow = page.locator('[role="treeitem"]').nth(1)
|
||||
await sessionRow.waitFor({ timeout: 10_000 })
|
||||
await sessionRow.click()
|
||||
await page.getByText('MINIMAL_PRESET_REQUEST_OK', { exact: true }).waitFor({ timeout: 15_000 })
|
||||
|
||||
const row = page.locator('[data-sample="bash"]').first()
|
||||
await row.waitFor({ timeout: 15_000 })
|
||||
await expect.poll(() => row.getAttribute('aria-expanded')).toBe('false')
|
||||
await row.click()
|
||||
|
||||
await expect.poll(() => row.getAttribute('aria-expanded')).toBe('true')
|
||||
const call = row.locator('xpath=..')
|
||||
await call.getByText('IN', { exact: true }).waitFor()
|
||||
await call.getByText('OUT', { exact: true }).waitFor()
|
||||
await call.getByText('MINIMAL_BASH_CARD_OK', { exact: true }).waitFor()
|
||||
await call.getByText(/"command": "printf 'MINIMAL_BASH_CARD_OK/).waitFor()
|
||||
|
||||
const snapshot = await captureStableAria(page, '[class*="centerCol"]', scaffold.workspaceCwd)
|
||||
await compareOrRefreshGolden(UI_EXPECTED, snapshot, MODE)
|
||||
expect(tripwire.pageErrors).toEqual([])
|
||||
expect(tripwire.warnings).toEqual([])
|
||||
}, 60_000)
|
||||
|
||||
it('keeps its snapshot inventory closed', async () => {
|
||||
await assertFixtureInventory(SNAPSHOT_DIR, [
|
||||
'session.jsonl',
|
||||
'system-prompt.expected.md',
|
||||
'tool-schemas.expected.json',
|
||||
'ui.expected.md',
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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-tool/README.md
|
||||
README.md: 2db7d716dc80fbf40a953b217810fb8674e2e98f
|
||||
README.zh.md: 79ed5befe751b329984c1320144921339fdf3d3f
|
||||
README.md: 8e3b4290d2402cf0bcb907f9887ddace35b349a6
|
||||
README.zh.md: f15899aaedcd52fe7f181c163ab7ab87e9bd20b8
|
||||
|
||||
@@ -30,7 +30,7 @@ ctx.slots.inject('tool.call.toolview', () =>
|
||||
|
||||
The owner payload is `ToolCallOwnerProps`: `callId`, `toolName`, the frozen `block`, optional `cwd` and `home`, and plain `openFile`/`inspect` callbacks. A Code Dispatch block retains its event's `parentCallId`; the field is absent on a root Session call, so row and Details card models preserve the generic flattened form for descendants without another placement flag. Path summaries relativize to the Session cwd first, then replace a leftover POSIX Host home with `~`; `filePath` and Host open keep the authored filesystem path. The registration receives the normal Session slot runtime share but no React node or Runtime service.
|
||||
|
||||
This package currently owns the generic fallback and the built-in shell/pwsh, read, write/edit, running `str_replace_editor` `create`/`str_replace`, grep/glob, web, todo, question, and Code Dispatch presentations. Structured cards derive directly from first-party raw event fields; Host `presentCall`/`presentResult` values never enter the Client. `ui-skill` demonstrates a business-owned registration for `skill`.
|
||||
This package currently owns the generic fallback and the built-in shell/pwsh, read, write/edit, running `str_replace_editor` `create`/`str_replace`, grep/glob, web, todo, question, and Code Dispatch presentations. Structured cards derive directly from first-party raw event fields; Host `presentCall`/`presentResult` values never enter the Client. Foreground one-shot shell results use terminal cards. Settled persistent-shell results use the expandable generic input/output card because reset and partial-output diagnostics do not always describe one process exit status; background acknowledgements remain collapsed. `ui-skill` demonstrates a business-owned registration for `skill`.
|
||||
|
||||
Card-specific limits and fallback rules remain in the owning [terminal](../../../.agents/notes/implemented/feature/2026-07-28-web-terminal-card.md), [diff](../../../.agents/notes/implemented/feature/2026-07-30-web-diff-card.md), [read](../../../.agents/notes/implemented/feature/2026-07-30-web-read-card-frontend.md), [search](../../../.agents/notes/implemented/feature/2026-07-30-web-search-card.md), and [web](../../../.agents/notes/implemented/feature/2026-07-30-web-result-card-frontend.md) notes.
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ ctx.slots.inject('tool.call.toolview', () =>
|
||||
|
||||
owner 载荷为 `ToolCallOwnerProps`:`callId`、`toolName`、冻结的 `block`、可选 `cwd` 与 `home`,以及普通的 `openFile`、`inspect` 回调。Code Dispatch block 保留其事件已有的 `parentCallId`;root Session call 没有该字段,因此 row 与 Details card model 无需另一项 placement 标志即可让 descendant 保持 generic 压平形态。路径摘要先相对 Session cwd 缩短,再把剩余的 POSIX Host home 写成 `~`;`filePath` 与 Host 打开仍使用作者给出的文件系统路径。注册项会收到常规 Session slot runtime share,但不会收到 React node 或 runtime service。
|
||||
|
||||
本包当前拥有 generic fallback,以及 shell/pwsh、read、write/edit、running `str_replace_editor` `create`/`str_replace`、grep/glob、web、todo、question 和 Code Dispatch 的内置展示。结构化卡片直接从第一方原始 event 字段派生;Host `presentCall`/`presentResult` 值不会进入 Client。`ui-skill` 展示了业务包自行拥有的 `skill` 注册项。
|
||||
本包当前拥有 generic fallback,以及 shell/pwsh、read、write/edit、running `str_replace_editor` `create`/`str_replace`、grep/glob、web、todo、question 和 Code Dispatch 的内置展示。结构化卡片直接从第一方原始 event 字段派生;Host `presentCall`/`presentResult` 值不会进入 Client。前台一次性 shell 结果使用 terminal 卡片。已完成的持久 shell 结果使用可展开的 generic 输入/输出卡片,因为 reset 与部分输出诊断不一定描述单个进程的退出状态;后台启动回执保持折叠。`ui-skill` 展示了业务包自行拥有的 `skill` 注册项。
|
||||
|
||||
各类卡片的上限与 fallback 规则仍由对应的 [terminal](../../../.agents/notes/implemented/feature/2026-07-28-web-terminal-card.zh.md)、[diff](../../../.agents/notes/implemented/feature/2026-07-30-web-diff-card.zh.md)、[read](../../../.agents/notes/implemented/feature/2026-07-30-web-read-card-frontend.zh.md)、[search](../../../.agents/notes/implemented/feature/2026-07-30-web-search-card.zh.md) 和 [web](../../../.agents/notes/implemented/feature/2026-07-30-web-result-card-frontend.zh.md) Agent Note 负责。
|
||||
|
||||
|
||||
@@ -205,6 +205,20 @@ function shellCall(name: string, args: Record<string, unknown>): ShellCall | nul
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify a settled root call from the persistent Bash or PowerShell tool.
|
||||
* Its result stays on the generic input/output path because the persistent
|
||||
* shell can report resets and partial output without one process exit status.
|
||||
* @param block - running or settled Tool block.
|
||||
* @returns whether the block is a settled persistent-shell call.
|
||||
*/
|
||||
export function isSettledPersistentShellCall(block: ToolCallBlock): boolean {
|
||||
if (!('kind' in block) || block.parentCallId !== undefined) return false
|
||||
const parsed = parsedToolCall(block)
|
||||
if (parsed === null) return false
|
||||
return shellCall(parsed.name, parsed.args)?.persistent === true
|
||||
}
|
||||
|
||||
interface TerminalSendCall {
|
||||
kind: 'terminal-send'
|
||||
text: string
|
||||
@@ -244,7 +258,8 @@ function parseExitStatus(text: string): { output: string; exitCode?: number; sig
|
||||
* Derive terminal props for supported root shell and terminal-send calls.
|
||||
* Standard shell results parse their final status marker; persistent shell
|
||||
* results, background calls, errors, malformed input, or child dispatches use
|
||||
* the generic path.
|
||||
* the generic path. {@link isSettledPersistentShellCall} lets that generic
|
||||
* persistent result remain expandable without inventing one process status.
|
||||
* @param block - running or settled Tool block.
|
||||
* @param sessionCwd - session workspace root used to resolve workdir.
|
||||
* @returns locale-neutral terminal-card data, or null for the generic path.
|
||||
|
||||
@@ -7,7 +7,11 @@ import {
|
||||
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'
|
||||
import type { ToolCallViewProps } from '../../contract/slots.ts'
|
||||
import {
|
||||
localizeTerminalCardModel, terminalBlockLabels, terminalCardModel, terminalFailed,
|
||||
isSettledPersistentShellCall,
|
||||
localizeTerminalCardModel,
|
||||
terminalBlockLabels,
|
||||
terminalCardModel,
|
||||
terminalFailed,
|
||||
} from '../models/terminal-card-model.ts'
|
||||
import { toolRowModel, type ToolRowState } from '../models/tool-call-model.ts'
|
||||
import { CONVERSATION_NS as NS } from '../../locale.ts'
|
||||
@@ -49,13 +53,13 @@ export function BashRow({ toolName, block, sessionId, useSessions, inspect, t }:
|
||||
: model.state
|
||||
const status = stateStatus(state, t)
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
// Execution failures (for example cancellation before the process reports a
|
||||
// terminal result) use the generic body. Keep their recorded args and
|
||||
// full error reachable instead of collapsing the row to the first line.
|
||||
const genericError = terminal === null
|
||||
&& model.state === 'error'
|
||||
// Execution failures and persistent-shell results have no terminal card.
|
||||
// Keep their recorded args and complete output reachable through the generic
|
||||
// body; background acknowledgements and malformed calls remain collapsed.
|
||||
const genericBody = terminal === null
|
||||
&& (model.state === 'error' || isSettledPersistentShellCall(block))
|
||||
&& (model.body !== null || model.output !== null)
|
||||
const expandable = terminal !== null || genericError
|
||||
const expandable = terminal !== null || genericBody
|
||||
const open = expanded && expandable
|
||||
const failureLine = model.state === 'error' ? model.errorSummary : null
|
||||
const toggleExpand = () => {
|
||||
@@ -123,7 +127,7 @@ export function BashRow({ toolName, block, sessionId, useSessions, inspect, t }:
|
||||
{model.output !== null && (
|
||||
<div className={css.ioSection}>
|
||||
<span className={css.ioLabel}>{t('row.output')}</span>
|
||||
<span className={css.ioText} data-error>
|
||||
<span className={css.ioText} data-error={state === 'error' || undefined}>
|
||||
{model.output}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -442,11 +442,24 @@ describe('BashRow terminal card', () => {
|
||||
expect(view.queryByText('List files')).toBeNull()
|
||||
})
|
||||
|
||||
it('keeps the command summary for a persistent shell with no description', () => {
|
||||
it('expands a settled persistent shell through the generic input/output card', () => {
|
||||
const view = render(<BashRow {...rowProps(settled({
|
||||
call: { name: 'bash', argsRaw: JSON.stringify({ command: 'ls -la' }) },
|
||||
}))} />)
|
||||
const row = view.container.querySelector('[data-sample="bash"]')!
|
||||
expect(view.getByText('ls -la')).toBeTruthy()
|
||||
expect(row.getAttribute('role')).toBe('button')
|
||||
expect(row.getAttribute('aria-expanded')).toBe('false')
|
||||
|
||||
fireEvent.click(row)
|
||||
|
||||
expect(row.getAttribute('aria-expanded')).toBe('true')
|
||||
expect(view.getByText('输入')).toBeTruthy()
|
||||
expect(view.getByText('输出')).toBeTruthy()
|
||||
expect(view.getByText(/"command": "ls -la"/)).toBeTruthy()
|
||||
expect(view.container.querySelector('[class*="_ioText_"][data-error]')).toBeNull()
|
||||
expect(view.container.querySelectorAll('[class*="_ioText_"]')[1]?.textContent)
|
||||
.toBe('a.ts b.ts\nc.ts d.ts\n')
|
||||
})
|
||||
|
||||
it('a non-terminal bash call (background start) renders the summary row alone', () => {
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
{"type":"session","version":0,"id":"{{session:1}}","createdAt":1787520042622,"cwd":"{{cwd}}","agentPreset":"minimal"}
|
||||
{"type":"session","version":0,"id":"{{session:1}}","createdAt":1787660564247,"cwd":"{{cwd}}","agentPreset":"minimal"}
|
||||
{"type":"permission/preset","data":{"preset":"workspace-write"}}
|
||||
{"type":"sandbox/mode","data":{"mode":"workspace-write"}}
|
||||
{"type":"approval/policy","data":{"policy":"ask"}}
|
||||
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply exactly MINIMAL_PRESET_REQUEST_OK and stop."}],"source":{"kind":"user"},"role":"user","id":"{{message:1}}"}]}}
|
||||
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Use the bash tool to run exactly: printf 'MINIMAL_BASH_CARD_OK\\n'. Then reply exactly MINIMAL_PRESET_REQUEST_OK and stop."}],"source":{"kind":"user"},"role":"user","id":"{{message:1}}"}]}}
|
||||
{"type":"turn/start","data":{"turn":1}}
|
||||
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
|
||||
{"type":"step/start","data":{"turn":1,"step":1}}
|
||||
{"type":"user/message","data":{"content":[{"type":"text","text":"Reply exactly MINIMAL_PRESET_REQUEST_OK and stop."}],"source":{"kind":"user"},"role":"user","id":"{{message:1}}"},"surfaceOp":"append"}
|
||||
{"type":"session/title","data":{"title":"Reply exactly MINIMAL_PRESET_REQUEST_OK","messageSeqs":[7],"source":{"kind":"fallback"}}}
|
||||
{"type":"user/message","data":{"content":[{"type":"text","text":"Use the bash tool to run exactly: printf 'MINIMAL_BASH_CARD_OK\\n'. Then reply exactly MINIMAL_PRESET_REQUEST_OK and stop."}],"source":{"kind":"user"},"role":"user","id":"{{message:1}}"},"surfaceOp":"append"}
|
||||
{"type":"session/title","data":{"title":"Use the bash tool to","messageSeqs":[7],"source":{"kind":"fallback"}}}
|
||||
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash","contextWindow":128000}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"MINIMAL_PRESET_REQUEST_OK"}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"MINIMAL_PRESET_REQUEST_OK"}}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"minimal-bash-card","name":"bash","argumentsDelta":"{\"command\":\"printf 'MINIMAL_BASH_CARD_OK\\\\n'\"}"}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"minimal-bash-card","name":"bash","arguments":"{\"command\":\"printf 'MINIMAL_BASH_CARD_OK\\\\n'\"}"}}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":4}}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"MINIMAL_PRESET_REQUEST_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:2}}"},"usage":{"inputTokens":10,"outputTokens":4}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"minimal-bash-card","name":"bash","arguments":"{\"command\":\"printf 'MINIMAL_BASH_CARD_OK\\\\n'\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:2}}"},"usage":{"inputTokens":10,"outputTokens":4}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"minimal-bash-card","name":"bash","arguments":"{\"command\":\"printf 'MINIMAL_BASH_CARD_OK\\\\n'\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"minimal-bash-card"},"content":[{"type":"tool-result","toolCallId":"minimal-bash-card","content":[{"type":"text","text":"MINIMAL_BASH_CARD_OK"}],"isError":false}],"role":"user","id":"{{message:3}}"}},"sourceEventSeqs":[17],"surfaceOp":"append"}
|
||||
{"type":"step/end","data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"MINIMAL_PRESET_REQUEST_OK"}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"MINIMAL_PRESET_REQUEST_OK"}}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":4}}}}
|
||||
{"type":"assistant/chunk","data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"MINIMAL_PRESET_REQUEST_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:4}}"},"usage":{"inputTokens":10,"outputTokens":4}},"sourceEventSeqs":[21,22,23,24,25],"surfaceOp":"append"}
|
||||
{"type":"step/end","data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
- banner:
|
||||
- navigation "Session hierarchy":
|
||||
- button "Use the bash tool to" [disabled]
|
||||
- img
|
||||
- text: Minimal mode
|
||||
- button "Session log":
|
||||
- text: Session log
|
||||
- img
|
||||
- tablist:
|
||||
- tab "Chat" [selected]
|
||||
- tab "Trajectory"
|
||||
- button "System prompt":
|
||||
- img
|
||||
- img
|
||||
- text: System prompt
|
||||
- text: "Use the bash tool to run exactly: printf 'MINIMAL_BASH_CARD_OK\\n'. Then reply exactly MINIMAL_PRESET_REQUEST_OK and stop. {{clock}}"
|
||||
- button "Copy":
|
||||
- img
|
||||
- button "Bash printf 'MINIMAL_BASH_CARD_OK\\n'" [expanded]:
|
||||
- img
|
||||
- text: Bash printf 'MINIMAL_BASH_CARD_OK\n'
|
||||
- text: "IN { \"command\": \"printf 'MINIMAL_BASH_CARD_OK\\\\n'\" } OUT MINIMAL_BASH_CARD_OK"
|
||||
- button "Inspect"
|
||||
- paragraph: MINIMAL_PRESET_REQUEST_OK
|
||||
- button "Copy":
|
||||
- img
|
||||
- button "Good response":
|
||||
- img
|
||||
- button "Bad response":
|
||||
- img
|
||||
- button "Branch into a new conversation":
|
||||
- img
|
||||
- text: {{clock}} Ran for {{duration}} TTFT {{duration}} {{throughput}} tok/s
|
||||
- textbox "Message the agent"
|
||||
- button "Commands":
|
||||
- img
|
||||
- 'button "Access mode, current: Workspace Write"': Workspace Write
|
||||
- button "Select model, current DeepSeek-V4-Flash":
|
||||
- text: DeepSeek-V4-Flash
|
||||
- img
|
||||
- button "0% of context used"
|
||||
- button "Send message" [disabled]
|
||||
- text: 1 turns · 2 steps LLM {{duration}} · Tool call {{duration}} TTFT avg {{duration}} · {{throughput}} tok/s Cache hit 0% Input 20 tok · Output 8 tok
|
||||
Reference in New Issue
Block a user