JingHao-Leon/dsh-daily-digest

dsh-daily-digest

Daily tech digest agent demo for DeepSeek Harness (dsh): one Cordis plugin (fetch_feed + save_digest), one patch overlay, one AGENTS.md — RSS → Chinese markdown digest, headless & cron-ready. 中文 README 完整。

Uncategorizedagent-harnessai-agentcordis

dsh-daily-digest

A Daily Tech Digest Agent built on DeepSeek Harness plugins: five RSS feeds in, one grouped, deduplicated, commented Chinese markdown digest out

中文完整版:README.md

Keywords: DeepSeek Harness demo, dsh plugin example, Cordis plugin tutorial, agent harness custom tools, dsh headless mode, RSS AI digest agent, DeepSeek agent framework, LangGraph alternative demo, AI agent RSS summarizer.

demo

What this is

A deliberately tiny — one 200-line TypeScript plugin, one YAML overlay, one AGENTS.md — but complete DeepSeek Harness (dsh) demo outside the usual coding-agent niche. With one command, an agent fetches five Chinese + international tech RSS feeds, groups the items by topic, dedupes them, and writes a Chinese markdown digest to digests/.

It demonstrates the four building blocks that separate dsh from "just prompt an API":

dsh mechanismIn this demo
Everything is a plugin (Cordis effects)plugins/digest-tools.ts registers two model-visible tools (fetch_feed, save_digest); they unregister automatically on unload
Configuration as composition (patch overlays)overlays/digest.cordis.yml stacks the local plugin plus the official time-context/schedule plugins onto the stock profile — zero changes to dsh itself
Instruction-chain injection (dsh-agent-instructions)AGENTS.md defines the digest pipeline and is injected into durable history automatically
Unattended runs (headless profile)dsh --profile headless "..." runs once and exits — cron/CI-ready

Companion deep-dive (architecture, event sourcing, capability seams, comparisons with LangGraph / Claude Agent SDK / Google ADK): DeepSeek Harness guide.

Quickstart

Prerequisites: Node.js ^22.19 or >=24, and dsh's runtime installed (npx @deepseek-ai/dsh web once, so ~/.dsh/profiles/node_modules exists).

git clone https://github.com/JingHao-Leon/dsh-daily-digest.git
cd dsh-daily-digest
./scripts/install.sh        # generates the absolute-path overlay + node_modules symlink

# Option A: headless one-shot (cron/CI friendly)
npx @deepseek-ai/dsh --profile headless \
  --patch overlays/digest.cordis.yml "生成今日科技摘要"

# Option B: Web UI at http://127.0.0.1:3080
npx @deepseek-ai/dsh web --patch overlays/digest.cordis.yml

Then read digests/YYYY-MM-DD.md.

The default model goes through DeepSeek's official provider (agent-default-model in ~/.dsh/settings.yaml). If you haven't configured a key yet, follow the dsh onboarding first.

How it works

one prompt ──▶ dsh headless profile
                 │
                 ├─ AGENTS.md injected (discovered from project root → cwd)
                 │    "read feeds.txt → fetch_feed ×5 → group → save_digest → report"
                 │
                 ├─ patch overlay mounts 3 plugins
                 │    digest-tools.ts ─┬─ fetch_feed(url, limit)   fetch + parse RSS/Atom
                 │                     └─ save_digest(name, md)     write digests/*.md
                 │    dsh-time-context / dsh-schedule (optional in-session reminders)
                 │
                 └─ agent loop: the model orchestrates the tools itself ──▶ digests/2026-08-15.md

The key point: a plugin is just a .ts file. No npm publishing, no build step, no fork of dsh — point the overlay at an absolute path and it's mounted. Even the RSS parsing inside fetch_feed is 30 lines of hand-written regex; the whole demo has zero third-party dependencies.

Take it further

  • Run daily: put the headless command in crontab, e.g. 7 9 * * * cd ~/dsh-daily-digest && node ~/.dsh/profiles/node_modules/@deepseek-ai/dsh/lib/bin.js --profile headless --patch overlays/digest.cordis.yml "生成今日科技摘要".
  • Change sources: edit feeds.txt (one RSS/Atom URL per line); AGENTS.md needs no changes.
  • In-session reminders: the overlay already mounts the official schedule plugin — in the Web UI just say "remind me every day at 9am to generate the digest" (schedule_create).
  • Change language/topics: edit step 4 of AGENTS.md (English digest, AI-only topics, etc.).

Repository layout

dsh-daily-digest/
├── AGENTS.md                          # digest pipeline instructions (auto-injected)
├── feeds.txt                          # feed list (verified reachable)
├── plugins/
│   └── digest-tools.ts                # custom plugin: fetch_feed + save_digest
├── overlays/
│   ├── digest.cordis.yml.template     # overlay template (__PROJECT_DIR__ placeholder)
│   └── digest.cordis.yml              # generated by install.sh — do not edit
├── scripts/
│   ├── install.sh                     # one-step setup
│   ├── demo.sh                        # the real session recorded in assets/demo.gif
│   └── render_gif.py                  # terminal GIF renderer (Pillow only, reusable)
├── digests/                           # output (created on first run; one real sample committed)
└── assets/demo.gif                    # real terminal recording

FAQ

  • sh: dsh: command not found when running npx inside the repo: the node_modules symlink created by install.sh makes npx think the package is installed locally. Use node ~/.dsh/profiles/node_modules/@deepseek-ai/dsh/lib/bin.js ... instead, or run npx from outside the repo.
  • A feed fails to fetch: the pipeline skips failed sources by design and continues; that source simply won't appear in the digest.
  • Plugin edits not picked up: save triggers hot reload (cordis-plugin-hmr); headless runs always start fresh anyway.

Limitations

  • Depends on the dsh runtime and its version: this demo is not a standalone program — the plugin relies on dsh's tools capability seam and the @deepseek-ai/dsh-tools API. dsh is a Developer Preview, so future releases may break compatibility. overlays/digest.cordis.yml is generated by install.sh with an absolute path; re-run the script after moving the repo.
  • The RSS parser is a simplified implementation: fetch_feed's parser is ~30 lines of regex covering only common RSS 2.0 / Atom tags, with summary truncated at 280 characters; feeds with unusual namespaces, malformed XML, or non-XML formats (e.g. JSON Feed) may fail to parse or lose fields.
  • Digest quality depends on the model: topic grouping, dedup, and the one-line comments come from the agent-default-model in ~/.dsh/settings.yaml — the comments are quick model summaries, not fact-checks; open the original links before citing. The date in the digest filename relies on dsh-time-context; if that plugin is not active the filename may be wrong.
  • Feed reachability is not guaranteed: sources in feeds.txt may change, rate-limit, or be unreachable from some networks. The pipeline skips failed sources by design, so a day's digest may be missing sources; fetch_feed has no retry or caching.
  • Same-day reruns overwrite: save_digest writes digests/YYYY-MM-DD.md directly, with no versioning or concurrency protection — multiple runs on the same day overwrite each other. Handle it yourself in high-frequency cron setups.

License

MIT © JingHao-Leon. This is a community demo, not affiliated with DeepSeek. DeepSeek Harness itself: deepseek-ai/deepseek-harness (MIT, Developer Preview).