Development & Runtime

dsh-agent-sdk

salathleizhang/dsh-agent-sdk · ★ 0

salathleizhang

Embeddable, plugin-based coding-agent runtime built on DeepSeek Harness

License
MIT
Added
2026-08-23
Maintenance
active
Install kind
github

No manifest check is available; listing does not imply compatibility or security review.

安装

dsh plugin --profile web add github:salathleizhang/dsh-agent-sdk

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. Requirements
  2. Install
  3. One-shot query
  4. Reusable runtime
  5. Security and approvals
  6. Plugins and custom tools
  7. Development
  8. License

DSH Agent SDK is an embeddable, plugin-based coding-agent runtime. It exposes a small TypeScript API over the public DeepSeek Harness packages while keeping Cordis available for trusted extensions.

The default runtime forms a runnable coding loop: DeepSeek model routing, durable session events, sandboxed Bash, filesystem read/write/edit, glob, grep, cancellation, approvals, and deterministic teardown. Skills, goals, jobs, browser tools, subagents, and UI integrations are not registered as placeholders. Applications add those capabilities only when their provider, consumer, policy, and lifecycle are complete.

Requirements

  • Node.js ^22.19.0 or >=24.0.0
  • DEEPSEEK_API_KEY for the default DeepSeek adapter

Install

npm install dsh-agent-sdk

One-shot query

import { query } from 'dsh-agent-sdk'

for await (const item of query({
  cwd: process.cwd(),
  prompt: 'Find the failing test and fix it.',
})) {
  if (item.type === 'session_event') {
    console.log(item.event.type)
  } else {
    console.log(item.result.text)
  }
}

query() owns a fresh runtime and agent. Leaving its iterator early cancels active work and disposes both.

Reusable runtime

import { createRuntime } from 'dsh-agent-sdk'

const runtime = await createRuntime()
try {
  const agent = await runtime.createAgent({ cwd: process.cwd() })
  const first = await agent.prompt('Inspect this project.')
  const second = await agent.prompt('Now implement the smallest safe fix.')
  console.log(first.text, second.text)
  await agent.close()
} finally {
  await runtime.close()
}

Call close() on agents and runtimes when the host cannot use explicit resource management. A reusable agent accepts one active query at a time.

Security and approvals

The default workspace-write mode confines filesystem and process operations to codingTools.workspaceRoot, which defaults to process.cwd(). A model request for one-shot unrestricted execution fails closed unless the host provides codingTools.onApproval.

const runtime = await createRuntime({
  codingTools: {
    workspaceRoot: '/absolute/project',
    onApproval(request) {
      console.warn(`Denied escalation for ${request.toolName}: ${request.reason ?? 'no reason'}`)
      return 'rejected'
    },
  },
})

The approval request contains the agent, tool identity, call id, and human-readable reason; it does not duplicate tool arguments. A UI can associate the call id with the tool call already present in the event stream. Use codingTools: false to omit all six built-in coding tools. Use spine.toolBash: false to omit only Bash.

Plugins and custom tools

runtimeSetup receives the process-wide Cordis context after the built-in composition loads. createAgent({ setup }) receives the agent-local context before publication. Registrations made in either callback are disposed with their owning runtime or agent.

import { createRuntime, defineTool } from 'dsh-agent-sdk'

const ping = defineTool({
  name: 'ping',
  description: 'Return pong.',
  parameters: {},
  output: {
    schema: { type: 'string' },
    render: (_args, value) => [{ type: 'text', text: value }],
  },
  async execute() {
    return 'pong'
  },
})

const runtime = await createRuntime({
  runtimeSetup(ctx) {
    // Mount trusted process-wide plugins here.
  },
})
const agent = await runtime.createAgent({ cwd: process.cwd(), tools: [ping] })

The stream carries exact committed session events followed by one result. Consumers should switch on item.type and treat unknown future SessionEvent variants according to their own compatibility policy.

Development

npm install
npm run check

See docs/architecture.md for composition and ownership rules.

License

MIT