| 245 | // JSON falls back to a clean key/value view; non-JSON to markdown. ----------- |
| 246 | |
| 247 | function ToolOutput(props: { data: any }): React.ReactElement { |
| 248 | const d = props.data; |
| 249 | const out = d.output != null |
| 250 | ? d.output |
| 251 | : (typeof d.result === "string" ? d.result |
| 252 | : (d.result != null ? JSON.stringify(d.result, null, 2) : "")); |
| 253 | const code = d.exit_code != null ? d.exit_code : d.status; |
| 254 | const ok = d.exit_code === 0 || d.status === "success" || d.status === "exited" || d.success === true; |
| 255 | return ( |
| 256 | <div className="hermes-lcm-tool"> |
| 257 | {(code != null || d.duration_seconds != null) ? ( |
| 258 | <div className="hermes-lcm-tool-meta"> |
| 259 | {code != null ? toolBadge((d.exit_code != null ? "exit " : "") + code, ok ? "ok" : "bad") : null} |
| 260 | {d.duration_seconds != null ? <span className="hermes-lcm-dim">{d.duration_seconds + "s"}</span> : null} |
| 261 | </div> |
| 262 | ) : null} |
| 263 | {out ? codeBlock(out) : null} |
| 264 | {d.error ? <div className="hermes-lcm-tool-err">{String(d.error)}</div> : null} |
| 265 | {d.timeout_note ? <div className="hermes-lcm-tool-err">{String(d.timeout_note)}</div> : null} |
| 266 | </div> |
| 267 | ); |
| 268 | } |
| 269 | |
| 270 | function ToolReadFile(props: { data: any }): React.ReactElement { |
| 271 | const d = props.data; |