편집자 노트

Webhook 桥接

Generic webhook receiver for DeepSeek Harness — POST to a local endpoint and wake a dsh agent. CI, monitoring, or any HTTP-capable service can feed messages to a harness agent over plain HTTP. Zero runtime dependencies beyond the official schema library ( node:http only).

이것은 DeepSeek Harness(DSH) 플러그인입니다. 이 사이트는 GitHub README, 설치 정보, 유지보수 상태, 공개 보안 시그널을 모아 보여줍니다.

업스트림에서 중국어 README를 제공하지 않아 저장소 원본 내용을 표시합니다.

dsh-webhook-bridge

Generic webhook receiver for DeepSeek Harness — POST to a local endpoint and wake a dsh agent. CI, monitoring, or any HTTP-capable service can feed messages to a harness agent over plain HTTP. Zero runtime dependencies beyond the official schema library (node:http only).

Overview

dsh-webhook-bridge exposes a small local HTTP server. Each request to POST /hook/:channel delivers a message to that channel's agent session; committed assistant text can be streamed back to an optional callback URL. It is a protocol driver in the dsh extension model — the same role as the official ACP/JSON-RPC bridges, but for any system that can send HTTP.

Who is it for?

  • CI pipelines that want an agent to triage a failed build.
  • Monitoring/alerting systems that want an agent to investigate an incident.
  • IM bots and webhooks (GitHub, GitLab, generic services) that need to hand a payload to a harness agent.
  • Developers who want a readable reference for writing an HTTP-based protocol-driver plugin.

What it does

  • Serves POST /hook/:channel (Bearer-secret auth) and GET /health.
  • Maps one channel to one agent session; the first message creates the agent, later messages followup() into the same session.
  • Extracts message text with a documented precedence: JSON message > text > content; non-JSON bodies are used verbatim.
  • Optional reply_url in the body: committed assistant text is POSTed back as {"text": "..."}.
  • Rejects unauthorized, malformed, and oversized requests (401/400/413).

What it does not do (yet)

  • No TLS (terminate TLS at a reverse proxy; the endpoint binds loopback by default).
  • No webhook signature verification beyond the shared Bearer secret.
  • No cross-restart persistence of channel→session mapping (in-memory; see Compatibility).

Compatibility

  • Requires Node.js ≥ 22.19 (global fetch, node:http).
  • Built and verified against @deepseek-ai/dsh@0.1.0-rc.6 / @deepseek-ai/cordis@^4.0.1.
  • Last verified: 2026-08-14.
  • Channel→session mapping lives in memory: restarting dsh loses open sessions (a new request recreates them).
  • dsh is in developer preview; re-verify after harness updates.

Install / Uninstall

Install into a dsh profile (local checkout):

cd /path/to/deepseek-harness
pnpm dsh plugin --profile web add /path/to/dsh-webhook-bridge

From GitHub (source install — pnpm runs the prepare script, so allow it once):

pnpm dsh plugin --profile web add github:<you>/dsh-webhook-bridge
# pnpm ≥10 blocks the build script on first install; copy the printed package key
# into <profile>/pnpm-workspace.yaml under allowBuilds, then re-run.

Uninstall:

pnpm dsh plugin --profile web remove dsh-webhook-bridge

Quick start

  1. Pick a shared secret (e.g. openssl rand -hex 24) and set it in the profile's cordis.patch.yml (or export DSH_WEBHOOK_SECRET):

    - id: dsh-webhook-bridge
      name: dsh-webhook-bridge
      config:
        secret: 'your-shared-secret'
    
  2. Start dsh, then deliver a message:

    curl -X POST http://127.0.0.1:8788/hook/ci \
      -H "Authorization: Bearer your-shared-secret" \
      -H "Content-Type: application/json" \
      -d '{"message": "CI failed on main: run the release pipeline diagnosis"}'
    
  3. To receive the agent's answer back:

    curl -X POST http://127.0.0.1:8788/hook/incident \
      -H "Authorization: Bearer your-shared-secret" \
      -d '{"message": "Investigate the 5xx spike", "reply_url": "https://your-service.example/hook/agent-reply"}'
    

Configuration

All keys live under the dsh-webhook-bridge row's config:

KeyTypeDefaultMeaning
hoststring127.0.0.1Bind host. Loopback only by default; bind 0.0.0.0 only behind a firewall/proxy.
portnumber8788Bind port.
secretstringenv DSH_WEBHOOK_SECRETRequired in Authorization: Bearer <secret>. Empty = every request rejected.
providerstringProvider route for created agents (falls back to profile default).
modelstringModel for created agents (falls back to profile default).
cwdstringprocess.cwd()Working directory for created agent sessions.
maxBodyBytesnumber1048576Request body limit; larger bodies get 413.

Permissions & data

  • Network exposure: the server binds 127.0.0.1 by default. If you bind externally, put it behind a reverse proxy with TLS; the shared secret is the only gate.
  • Auth: constant-time comparison (timingSafeEqual); unauthenticated requests get 401 and never create an agent session.
  • Reply callbacks: only to an explicit reply_url supplied in the request body, restricted to http:/https:.
  • Filesystem: the plugin writes nothing; agent sessions inherit the harness workspace policy.
  • Secrets: never commit the secret to the repository; use the env-var form in the shipped patch.

Troubleshooting

SymptomCauseFix
401 on every requestWrong/missing Authorization header or empty secretCheck config.secret and the header spelling (Bearer prefix required)
413 payload_too_largeBody over maxBodyBytesRaise maxBodyBytes or send smaller payloads
400 empty_messageNo message/text/content field and empty raw bodyInclude one of the recognized fields
404 not_foundWrong path or methodUse POST /hook/<channel>; /health is GET only
Replies not arrivingNo reply_url supplied for the channelInclude reply_url; the plugin only calls back when one is set
Agent error surfaces in logsModel/provider failure in the harnessFix the agent composition; the plugin forwards the request as 500

Development

pnpm install
pnpm run typecheck     # tsc --noEmit
pnpm run build         # tsc → lib/
pnpm run test          # vitest: HTTP behavior 200/401/400/413 + extraction helpers

Structure:

  • src/index.ts — plugin entry (name/inject/Config/apply), session mapping, and createBridge (pure HTTP transport, injectable message handler).
  • tests/ — integration tests start a real server on an ephemeral port and assert the HTTP contract without booting a full harness.

Design notes:

  • createBridge(config, deps) separates transport from agent logic: the HTTP layer is fully unit-testable, and apply supplies the handleMessage callback that creates sessions and forwards messages.
  • Zero runtime dependencies is a goal — node:http and node:crypto cover everything needed here.

License & security

MIT. Report security issues privately via the repository's security advisory. The bridge executes no agent code itself; all agent behavior is governed by the harness's own permission and sandbox policy.

REPOSITORY SIGNALS

보안 및 설치 증거

이 점수는 공개 저장소 메타데이터와 이 사이트에 등록된 설치 증거에만 기반하며, 코드 보안 감사와 다릅니다.

출처 추적 가능

공개 플러그인 카탈로그에서 왔으며, 공개 GitHub 저장소로 연결됩니다.

라이선스

GitHub 메타데이터에서 라이선스가 감지되지 않았습니다.

유지보수 활동

최근 180일 내 코드 업데이트가 있습니다.

설치 증거

재현 가능한 정확한 설치 메타데이터가 아직 등록되지 않았습니다. 저장소 설명에 따라 직접 확인하세요.

설치 라이프사이클 스크립트

검사한 패키지 메타데이터에 설치 라이프사이클 스크립트가 선언되지 않았습니다.

주의 사항missing-license