@hy-sde-org/dsh-graph-executor

中文文档
0.2.1-rc.5发布于 2026/11/01MITTypeScriptES Module零依赖

Operator executor adapter for the Agent Graph: deterministic worktree leases, durable operator bindings, and child-run serialization with terminal record emission.

原始使用文档
文档目录10 节
  1. Summary
  2. Table of Contents
  3. Use this package
  4. Understand the implementation
  5. Provision: lease key, binding, and the durable row
  6. Run: admission, serialization, and settlement
  7. Bindings in the control store
  8. Further Exploration
  9. Model Experience
  10. Known Limitations and Deferred Work

@hy-sde-org/dsh-graph-executor

English | 中文

Summary

dsh-graph-executor is the child-operator executor adapter of the Agent Graph. It implements the coordinator's AgentGraphExecutor surface over two injected seams: a GraphOperatorWorktreePool (acquire/release worktree leases for one repository) and a GraphOperatorChildRunner (one provider-backed child run per activation). The control store stays the durable authority — provisions and bindings are rows, and everything else is derived.

Provisioning is deterministic and idempotent: provisionOperator derives graph_operator_lease_<sha256(graphId, workId, provisionFingerprint)[32]> from the provision, so a retry adopts the same lease key, and pool.acquire is idempotent per key (process-local by design; the binding row is the durable hint a real pool consults after a restart). When no lease can be acquired the method returns undefined and the reconciler defers the work to a later drive.

Execution is serialized per operator (one child run at a time) and settles into exactly one terminal record per activation: the runner's summary is truncated to 16 KiB (truncateUtf8, … suffix) and emitted as an AgentGraphRecordSourceEvent (facets: ['message', 'terminal']) through recordSink; a failed run without a summary emits [operator failed] <message>. A child failure never throws from runClaimedAgentGraphIntent — records are the observation channel.

This package contributes no tool, prompt, or plugin row — the stream-layer coordinator and the supervisor tools consume it.

Table of Contents

Use this package

import { GraphControlStore } from '@hy-sde-org/dsh-graph-control'
import { AgentGraphCoordinator } from '@hy-sde-org/dsh-graph-stream'
import { createGraphOperatorExecutor } from '@hy-sde-org/dsh-graph-executor'

const executor = createGraphOperatorExecutor({
  store,
  pool: worktreePool,       // GraphOperatorWorktreePool over the git worktree engine
  childRunner: childRunner, // GraphOperatorChildRunner over the subagent runtime
  recordSink: recordSink,   // commits AgentGraphRecordSourceEvent rows
  newId,
})

const coordinator = new AgentGraphCoordinator(graphId, {
  store,
  executor,
  recordSource,
  newId,
  maxNewActivations: 4,
})

Understand the implementation

Provision: lease key, binding, and the durable row

provisionKey(request) hashes { graphId, workId, provisionFingerprint } with stableHash32, so retries of the same provision reuse one lease key. provisionOperator then acquires the lease (or adopts it), persists bindOperatorWorktree({ graphId, workId, provisionId, leaseId, path, repoRoot, boundAt }), and finally commits the provision row through the store — the same revision-conditional, closure-blocked write the control store already owns. Acquire failure returns undefined; the binding row is never written without a lease. Re-binding the same provision with a different lease id is rejected (binding-conflict), so a provision owns exactly one worktree.

Run: admission, serialization, and settlement

runClaimedAgentGraphIntent queues the activation on a per-operator promise chain, so one operator never runs two children at once. Inside the queue it first evaluates admitExecution (post-serialization revision gate) and aborts when it returns cancelled; then it resolves the operator's binding — through the ${graphId}:${workId} index when the intent's readiness id names the provisioning work (dynamic operators), or through the provision's operatorId for operator-targeted work, which re-runs a provisioned operator — and starts the child with { sessionId, instructions, workspace: binding.path, runId, labels, abortSignal }. concurrencyHint optionally caps concurrently running child starts across operators.

After the child settles, one AgentGraphRecordSourceEvent is built (runtimeEventId from newId, seq 1, the claim's targetRunId, truncated summary) and handed to recordSink; the folded AgentGraphRecord is also returned. recordSink failure propagates — the terminal record is the commit point that stops the reconciler from re-dispatching the same claim.

Bindings in the control store

The control store gained one authoritative table, operator_bindings (row key provisionId), with a derived ${graphId}:${workId} index rebuilt at open. Methods: bindOperatorWorktree (idempotent same-lease rebind keeps the original boundAt; different-lease rebind throws binding-conflict), readOperatorBinding, readOperatorBindingByWork, listOperatorBindings(graphId?).

Further Exploration

Model Experience

No model-facing surface. The package is host-side machinery: it renders no prompt (the stream layer does), and the terminal summaries it records are what the supervisor tools present.

Known Limitations and Deferred Work

  • Lease idempotency is process-local: a real pool implementation adopts a previously leased worktree after a restart by matching listWorktrees; nothing here re-derives leases from the store binding (the binding is the durable hint, not the lease authority).
  • Worktrees intentionally survive terminal runs (Maka contract); the executor never releases a lease. Pool release is wired in for graph teardown by the host assembly.
  • recordSink failures propagate as execution failures — the reconciler reports them and the host retries; there is no crash-consistent terminal-event log yet.
  • runClaimedAgentGraphIntent observes the seam contract the dsh-graph-stream README documents (provisionOperator may return undefined); the AgentGraphExecutor type in dsh-graph-stream's src/types.ts still declares a non-optional provision result and is expected to line up on integration.

版本与发布记录

@hy-sde-org/dsh-graph-executor 共发布 9 个版本,首次发布于 2026/09/10;过去 12 个月发布了 9 个版本。

版本发布日期距今
0.2.1-rc.5latest2026/11/012 天前
0.2.1-rc.32026/10/259 天前
0.2.1-alpha.42026/10/1618 天前
0.2.1-alpha.22026/10/1321 天前
0.2.0-rc.22026/10/031 个月前
0.1.7-rc.22026/09/291 个月前

关于 @hy-sde-org/dsh-graph-executor 的常见问题

@hy-sde-org/dsh-graph-executor 是什么?

用于代理图的操作符执行器适配器:确定性工作树租约、持久操作符绑定和带有终端记录发射的子运行序列化。

如何安装 @hy-sde-org/dsh-graph-executor?

在项目目录运行 npm install @hy-sde-org/dsh-graph-executor,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@hy-sde-org/dsh-graph-stream(^0.2.1-rc.5)、@hy-sde-org/dsh-graph-control(^0.2.1-rc.5)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@hy-sde-org/dsh-graph-executor 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@hy-sde-org/dsh-graph-executor 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@hy-sde-org/dsh-graph-executor 可以商用吗?

@hy-sde-org/dsh-graph-executor 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@hy-sde-org/dsh-graph-executor 还在维护吗?

最新版本 0.2.1-rc.5 发布于 2026/11/01(2 天前);至今共发布 9 个版本,其中过去 12 个月发布了 9 个;首次发布于 2026/09/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。