DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Unreal Agentlink — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
U

dsh-unreal-agentlink

Unreal Agentlink

DSH 插件,用于桥接 UnrealAgentLink 编辑器协议——纯桥接:DSH 的原生代理负责规划,此插件仅公开 UE 编辑器功能

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:hackmagic/dsh-unreal-agentlink#3c34d66aeba4664442a00669d9174e2295a91307
README兼容性版本

兼容性与来源证明

Unreal Agentlink 以 dsh-unreal-agentlink 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/10/14

版本

0.1.0stable
2026/10/14

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/16
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 integrations-communication 分类下经过校验的插件。

Im@xmanrui/dsh-im将微信、飞书、企微、钉钉、QQ、Telegram、WhatsApp、Slack、Discord 和 Matrix 接入 DSH。Free Searchdsh-free-searchDeepSeek Harness 的免费网页搜索:24 个引擎(Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel 无需密钥;通过 MCP 使用 Zhihu 全局/站内搜索,以及 Perplexity/SerpBase/DeepSeek/You.com/Baidu/Kimi/Aliyun/Doubao,需密钥;OpenAI/Gemini/ClaudeDafeiyudsh-dafeiyu由 DeepSeek Harness 会话事件驱动的原生桌面端 BigFish companion。Wechat Plugindsh-wechat-pluginDeepSeek Harness 的微信渠道:锁定电脑后离开,通过手机驱动代理。无需 OpenClaw,也无需公网 IP。

README

English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Deutsch · Español · Français · Русский

dsh-unreal-agentlink

A DSH plugin that puts your Unreal Editor under your agent.

Pure bridge. The agent plans; this plugin only translates.

DSH agent  ──tool calls──►  dsh-unreal-agentlink  ◄──WebSocket──  Unreal Editor
(plans, decides)            (this plugin: server, translator)   editor dials out

Requirements · Quick start · Tools · Configuration · Documentation

npm install && npm run check


Your agent can already read files and run commands. This plugin gives it the editor itself: query the level, spawn actors, edit blueprints and materials, render sequences, take screenshots it can actually see, and roll its own work back when something goes wrong.

It does not plan tasks. Planning belongs to DSH's native agent. This plugin is a translator with a safety layer — it turns agent intent into UnrealAgentLink commands and turns the editor's answers back into something an agent can act on.


Requirements

ItemRequirement
Unreal Engine5.0 – 5.8
UnrealAgentLinkthe C++ plugin itself, dropped into your project's Plugins/
Node.js^22.19.0 || >=24.0.0
DSH runtimethis plugin installed as a bundle

You do not need UEBox

The UEBox desktop app is not a dependency. It is another client from the same vendor that happens to use port 17860 too, so running both at once is a port conflict — that is the whole relationship. The evidence:

  • UnrealAgentLink.uplugin:25-34 declares exactly two dependencies, both engine-shipped: IKRig and PythonScriptPlugin. No uebox module.
  • Every entry in UnrealAgentLink.Build.cs is an engine module (UnrealEd / AssetRegistry / MovieScene / Landscape …). No uebox SDK.
  • The string uebox appears three times in the entire source, all of them // Copyright uebox.ai headers.
  • Nothing in the source calls uebox.ai. The only FHttpModule use reads the local machine's proxy settings (UAL_ProxyDiagnostics.cpp:167).

Once the plugin is in your project it runs on its own: StartupModule unconditionally calls Init("ws://127.0.0.1:17860") (Core/UnrealAgentLink.cpp:86-97), pushes project.info the moment it connects, and has no handshake, token, or authentication.

To move the port: -UALServer=ws://127.0.0.1:17861 on the editor side, and the port setting on this side.


Quick start

npm install
npm run check      # typecheck (src + tests) + 162 tests + catalog + doc reconciliation, one command

To install as a DSH bundle: package.json declares dsh.bundle.patch, and cordis.patch.yml inserts one line by published package name — {id: unreal-agentlink, name: dsh-unreal-agentlink}.

Configuration layering: a later layer replaces that row's config wholesale rather than deep-merging it. To override anything, rewrite every key you want to keep.

For the end-to-end path see the tutorial — UE-side install, first connection, common workflows, and how to read failures.


Documentation

DocumentContents
TutorialEnd-to-end: install the plugin, get it connected, common workflows, troubleshooting
Protocol referenceMessage shapes, events, the 13 status codes, serialization rules, timeout and concurrency semantics
ArchitectureThe gate chain, session isolation and rollback, error translation, verification strategy, the traps we hit
Command referenceParams / required keys / result keys / status codes for all 170 commands (generated)

All four exist in every language listed at the top of this file, under docs/<lang>/ — en (canonical, at docs/ directly), zh, zh-TW, ja, ko, de, es, fr, ru.

Only the prose is translated. Command names, parameter keys, result keys, status codes, config keys and C++ line references stay verbatim everywhere, because UE silently ignores a key it does not recognize — a translated asset_path would be a silently dead key, not a localization. tests/i18n.test.ts enforces the invariants that make this maintainable: every language has its files, every switcher bar lists every language, and every internal link and #anchor resolves. That last one matters because anchors are derived from the translated heading, so rewording a heading silently breaks every link pointing at it.


Four facts to establish first

These are not design choices. They are existing UnrealAgentLink constraints, and they determine how every operation is written.

  1. The direction is reversed. This plugin does not dial the editor — the editor dials out. Startup order does not matter: open the editor first and it retries every 5 seconds until the plugin appears.
  2. There is no authentication. No token, no header, no subprotocol. The port is the credential, so it binds loopback only by default. Do not change it to 0.0.0.0.
  3. Commands run serially on the game thread. And while a blocking command runs, the editor answers nothing — not even a progress query like sequence.render_status.
  4. There is no cancellation. query_task and cancel_task do not exist. Killing a ual_task job only stops this plugin's wait; the engine keeps going and the result still comes back.

12 tools

Surfacing 170 commands as 170 tools would spend a large slice of every request's prompt on capabilities a given task never touches. So discovering capability is two steps, not zero:

ToolPurpose
ual_statusEditor connections / breaker / rate limit / session / orphaned commands. Read this first when anything is wrong
ual_toolsList all 170 commands (22 families), filterable by family or keyword
ual_schemaThe exact key names for one command — check before calling; UE silently ignores unknown keys
ual_callRun one command, return the editor's result verbatim
ual_batchSeveral commands in one round trip (capped by maxBatchCalls; one dangerous item puts the whole batch through approval)
ual_screenshotCapture and return a real image the agent can see
ual_logsRead the local log ring (UE-side forwarding is off by default — see the tutorial)
ual_undo / ual_undo_historyPer-session rollback / inspect the undo buffer
ual_locksClaim asset locks; the editor draws an "AI is editing" badge
ual_editor_bindPin a session to one editor when several are connected
ual_taskTurn a long blocking command into a real background job so the conversation continues

Risk tiers

read 65 / write 89 / destructive 2 / dangerous 14 (the last 16 go through approval).

tools/pre-execute returns {kind:'ask'} for destructive and dangerous methods (including any dangerous item inside a ual_batch), leaving the decision to session policy. An unregistered method is denied outright and never reaches the editor.

Note that under a never policy, ask is auto-rejected — which is the correct reading of "unattended sessions must not touch the editor".


Configuration

Defaults are "alive but lazy". The full table with reasoning is in tutorial §7.

KeyDefaultMeaning
host / port127.0.0.1 / 17860Keep it on loopback: with no auth, reaching the port means driving the editor
timeoutMs180000Blocking commands raise their own floors
cacheTtlMs / cacheMaxEntries2000 / 128Per-session read cache
rateLimitRps / rateLimitQueue5 / 32Commands per second / queue cap (0 disables rate limiting)
breakerThreshold / breakerCooldownMs3 / 30000Consecutive transport failures to open / cooldown
logCapacity / logMinLevel512 / DisplayLog ring
logForwardingEnabledfalseSet true only after running ual.ForwardLogs inside the editor
rollbackOnDisposefalseOnly a LIFO suffix is exact — see the architecture doc
notifyOnEditorChangetrueInject a line into the agent when an editor connects or drops
screenshotAttachments / screenshotMaxBytestrue / 12MBImage blocks / size cap
maxBatchCalls12Per-ual_batch cap

Development

npm run build       # tsc → lib/
npm run dev         # tsc --watch
npm run check       # typecheck + tests + catalog reconciliation (run before committing)
npm test            # tests only
npm run typecheck   # src and tests typechecked separately

Source layout

src/
  index.ts                  Cordis lifecycle, approval gate, dispose-time rollback
  config.ts                 Schemastery schema (the single source of default values)
  service.ts                call() gate chain: catalog → requires → read cache → breaker → rate limit → send → ledger → translate
  protocol/{bridge,serialization,types}.ts   WS server / outbound validation / wire types
  catalog/{method-data,method-overrides,methods}.ts   170-command catalog (data extracted from C++)
  errors/translate.ts       Error classification (by class name / status code, never by message text)
  resilience/breaker.ts     Rate limiter + circuit breaker
  sessions/state.ts         Session ledger / LIFO test / lock merging / cache / log filtering
  tools/                    The 12 tools
scripts/                    Catalog extraction and reconciliation, doc generation and normalization, language set
docs/                       Tutorial / protocol / architecture / command reference, in 9 languages
tests/                      162 tests

Generated files: do not edit by hand

src/catalog/method-data.ts and docs/<lang>/command-reference.md are both generated:

node scripts/extract-methods.mjs .ua-ref/plugin/UnrealAgentLink/Source   # rebuild the catalog from C++
npm run build && node scripts/gen-docs.mjs                             # rebuild the command reference (all 9 languages)

A hand-maintained table that nobody imports is a recurring defect class in this project (REQUIRED_KEYS, EXTRA_PARAM_KEYS and UAL_CODES have all been caught by it). The countermeasure is to make each check ask the source rather than ask the table — see architecture §9.

Tests and checks

npm run check                       # typecheck (src + tests) + 162 passed + catalog + doc reconciliation
npm test                            # 162 passed
node scripts/check-catalog.mjs      # 170/170 zero drift; every requires key appears in C++; code set matches C++
node scripts/gen-docs.mjs --check   # is the command reference up to date in all 9 languages
node scripts/normalize-doc-headers.mjs --check   # are the language bars canonical in all 45 files
node scripts/normalize-doc-links.mjs --check     # do the body links resolve from where they sit
npm run docs                        # regenerate + rewrite the 45 doc headers and links

The eight test files are divided by the kind of defect they can find, each for a reason — see architecture §11.

requires is not hand-written: it is derived from the handlers' own SendError(..., 400, "Missing field: X") messages (28 sites), because a wrong required key makes the bridge reject a valid call before the engine sees it. The result lands in method-data.ts as REQUIRED_KEYS, and methods.ts's requiresOf() merges it into runtime use (the early rejection in service.call(), the REQUIRED: line in ual_schema, and error hints all go through that one function).

It deliberately narrows only, never widens: a message containing or ("Missing field: name or path") is skipped entirely, and keys harvested from a called function in the same file are dropped as branch-local — see REQUIRED_DROPPED in scripts/extract-methods.mjs, where every entry cites its C++ line number. So "no keys harvested" is the safe default, not a missed check.


Protocol essentials

UE → plugin:  { ver:"1.0", type:"req",  method, id, params }     // id is generated by the server
plugin → UE:  { ver:"1.0", type:"res",  id, code, result }        // the key is omitted when empty
UE → plugin:  { ver,       type:"evt", method, payload }
  • Failure is expressed by code alone. There is no envelope-level error field.
  • Human-readable text is in result.message (Chinese or English depending on editor culture — do not parse it); machine-readable detail is in result.details.
  • Many handlers return 200 with result.ok === false (editor.undo, blueprint.compile, pie.observe), so the plugin judges success with judge(), not by code alone. There are 55 SetStringField(TEXT("error"), ...) sites across 14 C++ files — this is the norm, not an anomaly.
  • content.import_folder / content.import_assets are fire-and-forget outbound pushes: no id, no reply expected. The plugin turns them into logs and agent notifications and does not fabricate a res — replying ok:false would only show the user a false "import failed" dialog, which is worse than silence.

Full detail (all 13 status codes, serialization rules, timeout semantics) is in the protocol reference.


License

MIT