Skip to content
dsh.fish
Agent preset

deskpet-bridge

DeskPet Bridge - a local JS agent preset for DSH (DeepSeek Harness)

Source
dfzjb
stars
3 stars
Updated
Updated 6 hours ago

Readme

# DeskPet Bridge

English | [中文](README.zh.md)

A local JavaScript **agent preset** for [DSH (DeepSeek Harness)](https://github.com/deepseek-ai/deepseek-harness) that exposes the agent's runtime status over HTTP + SSE and adds a **programmable approval channel**.

## Overview

`deskpet-bridge` is a standalone agent preset (three files) that you drop into DSH's `.agent-presets/` directory. It requires **no modification to the DSH codebase**.

## What it does for DSH

### 1. Extends DSH's web server

Registers three new routes on DSH's built-in `webServer`, giving DSH a few externally-callable endpoints:

| Endpoint | Purpose |
|---|---|
| `GET /api/deskpet/v2/get-status` | Query the current agent status snapshot |
| `GET /api/deskpet/v2/events` | Server-Sent Events realtime stream |
| `POST /api/deskpet/v2/approve` | Submit an approval decision |

### 2. Status observability

Listens to DSH's internal `agent/status` event, maintains a status cache (`idle` / `running` …), and counts state changes (`changes`) plus agent count (`agentCount`) — making DSH's runtime state queryable and subscribable by external programs.

### 3. Programmable approval channel (core)

Acts as an **answerer** in DSH's approval mechanism:

- Registers on `approval/request` with `{ prepend: true }`, claiming the approval ahead of DSH's default approval panel (`api-proxy`).
- Holds the approval (returns a pending Promise) and pushes the request to external clients over SSE.
- Resolves the approval when an external client submits a decision via `/approve` — **allowed-once** or **rejected**.
- Times out after 120 s (or on abort signal) as **cancelled**, so approvals never hang forever.

### 4. Realtime event stream

Broadcasts DSH internal events over SSE: `hello` / `agent-status` / `approval-request` / `approval-decided` / `approval-expired`, with a 5-second heartbeat.

### 5. Graceful fallback

When no external client is connected, the approval answerer calls `next()`, falling back to DSH's default approval panel — so DSH's original approval flow stays intact.

## Files

| File | Purpose |
|---|---|
| `agent.cordis.yml` | Composition entry: `id: deskpet-bridge` + `name: ./bridge.js` |
| `bridge.js` | Core plugin (ESM: `export name / inject / apply`) |
| `preset.yml` | Preset metadata (name + description) |

## Installation

Copy the three files into `%DSH_HOME%/.agent-presets/deskpet-bridge/`, then select (or set as default) the `deskpet-bridge` preset for your agent session.

## API Contract

Base: `http://127.0.0.1:3080` · Prefix: `/api/deskpet/v2/`

**GET /get-status**

```json
{"ok":true,"status":"idle","agentCount":4,"changes":0,"connectedClients":0,"pendingApprovals":0}
```

**GET /events** (SSE, `text/event-stream`)

Events: `hello` / `agent-status` / `approval-request` / `approval-decided` / `approval-expired`

**POST /approve**

```json
{"approvalId":"appr_N","decision":"approve-once"}  → 200 {"ok":true,"outcome":"allowed-once"}
{"approvalId":"appr_N","decision":"reject"}         → 200 {"ok":true,"outcome":"rejected"}
Unknown approvalId                                  → 404 {"ok":false,"error":"unknown approvalId"}
```

## How approval works

```text
approval/request (waterfall)
   └─ prepend answerer claims it
        ├─ external client connected → hold + push SSE approval-request
        │      └─ POST /approve → resolve allowed-once / rejected
        └─ no client → next() → DSH default approval panel

120s timeout / abort → cancelled
```

## License

MIT — aligned with DSH's license.

Install

# Copy the composition to $DSH_HOME/.agent-presets/deskpet-bridge/agent.cordis.yml

Profile: web

Source