Download packages/shell/tool-bash/src/render.ts from SaylorTwift/deepseek-harness: direct link, hf CLI and curl.
- Browser
- Download file 4.61 kB
-
https://huggingface.co/SaylorTwift/deepseek-harness/resolve/main/packages/shell/tool-bash/src/render.ts
- Command line
-
hf download hf://SaylorTwift/deepseek-harness/packages/shell/tool-bash/src/render.ts
-
curl -L -o render.ts https://huggingface.co/SaylorTwift/deepseek-harness/resolve/main/packages/shell/tool-bash/src/render.ts
4.61 kB
| /** | |
| * Model-facing result rendering for the bash tool. | |
| * | |
| * @module @deepseek-ai/dsh-tool-bash/render | |
| */ | |
| import type { ShellProcessRead, ShellRunResult, ShellSandboxInfo, CollectedOutput } from '@deepseek-ai/dsh-shell' | |
| import type { SandboxMode } from '@deepseek-ai/dsh-sandbox' | |
| import { escalationHintMarker, sandboxDenialMarker } from '@deepseek-ai/dsh-sandbox' | |
| /** Append the truncation notice (with the full-output spill path) to a stream's text. */ | |
| function streamText(output: CollectedOutput): string { | |
| if (!output.truncated) return output.text | |
| return `${output.text}\n[output truncated; full output: ${output.spillPath ?? '(unavailable)'}]` | |
| } | |
| /** | |
| * Shape one finished run into the text the model sees: stdout, then a marked | |
| * stderr section, then exit-status markers. Non-zero exits are reported, not | |
| * errored — the model decides how to react; only infrastructure failures | |
| * (spawn errors, aborts) surface as isError results. | |
| * @param result - the completed foreground run from the executor. | |
| * @param escalationModes - the escalation targets this composition advertises; | |
| * non-empty adds the same-turn escalation hint after a denial marker | |
| * (default `[]`: no hint). | |
| * @returns the model-facing text: output body (or `(no output)`), then any timeout/signal/exit markers, each on its own line. | |
| */ | |
| export function renderResult( | |
| result: ShellRunResult, | |
| escalationModes: readonly SandboxMode[] = [], | |
| ): string { | |
| const out = streamText(result.stdout) | |
| const err = streamText(result.stderr) | |
| let body = out | |
| if (err.length > 0) { | |
| // Single newline between sections (stdout usually ends with one already). | |
| if (body.length > 0 && !body.endsWith('\n')) body += '\n' | |
| body += `[stderr]\n${err}` | |
| } | |
| if (body.length === 0) body = '(no output)' | |
| const markers: string[] = [] | |
| // Keep the exit marker last because parseExitStatus anchors there. | |
| if (result.sandbox?.denied) { | |
| markers.push(sandboxDenialMarker(result.sandbox.mode)) | |
| // Hint only when the composition exposes escalation, before the final exit marker. | |
| if (escalationModes.length > 0) { | |
| markers.push(escalationHintMarker('command')) | |
| } | |
| } | |
| // A command may trap SIGTERM and exit 0 after timeout; still report interruption. | |
| if (result.timedOut) markers.push(`[timed out after ${result.timeoutMs}ms]`) | |
| if (result.signal !== null) { | |
| markers.push(`[killed by signal: ${result.signal}]`) | |
| } else if (result.exitCode !== 0) { | |
| markers.push(`[exit code: ${result.exitCode}]`) | |
| } | |
| if (markers.length === 0) return body | |
| if (!body.endsWith('\n')) body += '\n' | |
| return body + markers.join('\n') | |
| } | |
| /** | |
| * Shape one background-process read into the `job_output` delta the model | |
| * sees: the incremental delta, plus the lossy-read notice (with full-stream | |
| * spill paths) when in-memory truncation dropped unread bytes. Empty-delta | |
| * rendering (`(no new output)`) is the generic job controller's job. | |
| * @param read - one incremental read from the process handle. | |
| * @param sandbox - settled sandbox facts, when this was a confined process. | |
| * @param escalationModes - escalation targets advertised by this composition. | |
| * @returns the delta text with any loss or sandbox notice appended. | |
| */ | |
| export function renderProcessRead( | |
| read: ShellProcessRead, | |
| sandbox?: ShellSandboxInfo, | |
| escalationModes: readonly SandboxMode[] = [], | |
| ): string { | |
| const notices: string[] = [] | |
| if (read.lossy) { | |
| const paths = [read.stdoutSpillPath, read.stderrSpillPath].filter((path): path is string => path !== undefined) | |
| notices.push(`[some output was dropped from memory; full output: ${paths.length > 0 ? paths.join(', ') : '(unavailable)'}]`) | |
| } | |
| if (sandbox?.runnerFailed) { | |
| notices.push(`[sandbox: the sandbox runner itself failed under ${sandbox.mode} mode — the command did not run; this is a sandbox problem, not a command failure]`) | |
| } else if (sandbox?.denied) { | |
| notices.push(sandboxDenialMarker(sandbox.mode)) | |
| if (escalationModes.length > 0) { | |
| notices.push(escalationHintMarker('command')) | |
| } | |
| } | |
| if (notices.length === 0) return read.delta | |
| return `${read.delta}${read.delta.length > 0 && !read.delta.endsWith('\n') ? '\n' : ''}${notices.join('\n')}` | |
| } | |
| /** | |
| * The exit-status parse is the shared marker-contract half of the shell-tool | |
| * rendering story, owned by `@deepseek-ai/dsh-shell` so `dsh-tool-pwsh` reuses | |
| * it (its renderer emits the same markers). Re-exported here to keep | |
| * `../src/render.ts` a single import root for bash-tool consumers. | |
| */ | |
| export { parseExitStatus, type ParsedExitStatus } from '@deepseek-ai/dsh-shell' | |