@hy-sde-org dsh-graph-host
英语| 中文
总结
dsh-graph-host 是Agent Graph的主平面组件:它打开图形控制单元(dsh-graph-control),构建操作符执行器(dsh-graph-executor)在真实的线束接缝上,通过运行身份分类账提供无身份执行器记录接收器,构建 AgentGraphController 监控工具运行,并驱动尾流交付(dsh-graph-wakes)在图根会话的空闲边界。该包不提供工具和提示部分-面向模型的表面保留在里面 dsh-tool-graph;这个包提供服务和持久 graph/change 事件流。
这个 graph-host Cordis插件声明 inject: ['agents', 'sessions', 'subagents', 'git', 'compaction'] 并在自己的光纤上发布两个服务:
| 服务 | 导出常数 | 价值 |
|---|---|---|
控制器与主管工具解决 ctx.get | SERVICE_AGENT_GRAPH_CONTROLLER | AGENT_GRAPH_CONTROLLER_SERVICE 从 dsh-tool-graph = 'agentGraphController' |
| 整个装配手柄 | SERVICE_GRAPH_HOST | 'graphHostServices' |
插件 Config 字段: rootSessionId (需要-图形根;只有这个会话可以驱动管理员工具,它拥有 graph/change 事件), subagentProvider (必需的-提供商名称转发到 subagents.start;所提供的进程内提供程序是 spawn), backend? (存储后端名称托管图形控制单元,默认 'sqlite'), worktreeRepoRoot? / worktreeBaseBranch? / worktreeMaxSlots? (工作树池几何),以及 maxNewActivations? (默认情况下,每个调和驱动器的新操作符激活上限 4)。
目录表
使用这个包
中的主机行 主机组成 -它注入主机服务并发布新的服务,所以它的任何东西都不能通过会话进行关键化。工具排在 代理预定 图根会话的;它只使用已发布的控制器。
# host composition (loaded before any session)
- id: graph-host
name: '@hy-sde-org/dsh-graph-host'
config:
rootSessionId: session-01HABC # the graph root session id
subagentProvider: spawn # one-shot in-process subagent provider
backend: sqlite # backend owning the graph control unit
maxNewActivations: 4 # new operator activations per drive (default 4)
# agent preset composition for the graph root session
- id: tool-graph
name: '@hy-sde-org/dsh-tool-graph'
当根代理发布(agent/created),或者在它已经处于活动状态时立即退出服务。程序集也可以显式地构建:
import { createGraphHostServices } from '@hy-sde-org/dsh-graph-host'
const services = await createGraphHostServices({
rootSessionId: session.id,
storage: { open: descriptor => backend.kv.open(descriptor) },
subagents: { provider: 'spawn', start: (name, request) => ctx.subagents.start(name, request) },
worktrees: {
repoRoot,
acquire: options => worktreeEngine.acquire(options),
list: () => worktreeEngine.list(),
},
compaction: { request: sessionId => agent.runMaintenance(signal => engine.compactNow(agent, signal).then(() => {})) },
sessionEvents: { appendGraphChange: (sessionId, data) => session.append('graph/change', data).then(() => true) },
idle: { observe: (rootSessionId, onIdle) => agent.ctx.on('agent/status', ({ status }) => {
if (status === 'idle') onIdle(rootSessionId)
}) },
resolveParentAgent: rootSessionId => ctx.agents.get(SessionId(rootSessionId)),
})
await services.attachGraph('graph_g1') // registers the controller, starts the wake runtime
const snapshot = await services.snapshotFor('graph_g1') // bounded session projection
await services.emitGraphChange(session.id, 'graph_g1', snapshot, snapshot.revision)
await services.dispose() // stops wake delivery, cancels children, closes the store
布线
上面的行是完整的布线:放置 graph-host 行中主机组成与 rootSessionId 左为 <ROOT_SESSION_ID> 占位符和 subagentProvider: spawn;将占位符替换为部署的图根会话id。预设行(@hy-sde-org/dsh-tool-graph, @hy-sde-org/dsh-graph-projection)挂载到图根会话的代理预设中,如上所示 tool-graph.
理解实现
平面分割:主机行与预设行相对
graph-host 是一个 host-plane行:它注入 agents, sessions, subagents, git, compaction 和发布 agentGraphController 加上 graphHostServices。注入在任何会话存在之前进行解析,因此没有代理可以通过——从预设领域发布将对主机和所有其他会话隐藏服务。 dsh-tool-graph 是 agent-plane行:它投机地消耗控制器 ctx.get 当它不在的时候,它会在负载时大声失败。预设行永远不能发布服务;这里唯一的预设行贡献是工具注册。
facade优于实际服务
每个组件需要的服务都被缩小到结构立面 src/types.ts,因此汇编程序及其测试永远不会扩展到完整的服务类。该插件映射每个facade:存储后端(ctx.get(storageBackendServiceKey(name)))、子代理(ctx.subagents.start)、git工作树引擎(primaryRepoRoot + acquireWorktree/listWorktrees)、压实(ctx.compaction 通过代理的维护缝),会话事件(session.append('graph/change', …))和闲散(agent/status === 'idle' 转发到唤醒运行时的观察结果)。
只有一次激活保护
执行程序序列化每个操作符的激活,但不记忆声明,因此汇编程序将其封装在其中 OncePerClaimGraphExecutor:一个claim id每个程序集运行一个子程序,并且在完成(或正在运行)激活后重新驱动返回折叠的终端记录,而不启动第二个子程序。守卫是流程本地的——持久索赔行仍然是重启权限。
记录折叠和无持久记录的决定
执行程序的 recordSink 接收 AgentGraphRecordSourceEvent 没有 操作符/会话标识(事件携带) runId 唯一的),所以 GraphRunIdentityLedger 从执行程序本身执行的子启动恢复标识(执行程序复制) claim.targetRunId (开始输入和发出的事件),以及 InProcessGraphRecordSource 折叠由operator×session键的终端事件。 readCommittedAgentGraphProjection (流层)像重播子会话日志一样重播该源,因此记录派生与流层在一个主机进程中的派生保持相同。
记录是派生状态,这个程序集保存它们 在进程内存中:持久的 graph/record 子会话上的事件将被持久化读取路径拒绝,直到 KNOWN_SESSION_EVENT_TYPES 重新生成(主机连接范围),并且将终端事件归因于子会话日志需要更改执行器。持久授权是一组控制行——调度、索赔、供应、唤醒。 主机重启会丢失操作员记录 直到主机布线添加属性持久事件;然后会话投影显示计划/索赔状态(例如: claimed),而不是最终结果,直到电线落地。
会话投影和图/变更合约
buildSessionGraphProjection 将控制器的全图快照转换为有界投影负载。每一个 graph/change 事件有 { graphId, snapshot, revision }:
interface SessionGraphProjection {
readonly schemaVersion: 1
readonly graphId: string
readonly status: 'active' | 'closed'
readonly revision: number
readonly closed: boolean
readonly work: readonly {
readonly workId: string
readonly status: 'requested' | 'claimed' | 'executing' | 'stopped' | 'finished' | 'failed'
readonly instruction: string // truncated to 300 characters with a trailing ellipsis
readonly operatorId?: string
readonly inputCount: number
}[]
readonly omitted: { readonly work: number; readonly records: number; readonly inputs: number }
readonly pendingWake: boolean
readonly updatedAt: number
}
工作条目的上限为(SESSION_PROJECTION_MAX_WORK = 128:请求的头加上终端尾),记录尾到 SESSION_PROJECTION_MAX_RECORDS = 64,指示 SESSION_PROJECTION_INSTRUCTION_MAX_CHARS = 300; omitted 携带被排除的计数。 pendingWake 当图形有 pending 或者 retryable_failed 后一行。状态优先:调度停止优先;然后,操作员的终端记录(执行者只有在孩子安顿下来后才折叠它) [operator failed] …/[operator cancelled] 摘要映射到 failed/stopped还有什么事吗? finished); 然后索赔入场状态(仅限飞行中);然后 requested。终端记录的级别高于索赔准入,因为准入状态没有终端状态。
emitChange (在每次调度提交、每次协调和每次唤醒交付之后调用)是尽力而为的,它由内容指纹删除,并按图序列化,因此并发触发器每次指纹更改最多发出一个事件。事件只被附加到根会话的日志中——没有表面放置——投影层折叠它。
后交货
attachGraph 注册控制器并启动以根会话为范围的唤醒运行时。交付只在空闲边界运行(observeIdle → handleIdle):交付钩子重新驱动协调器并发出一个fresh graph/change。闭合图短路成 superseded (运行时也折叠调度日志本身:a finish 更新或以图形/根为目标的停止取代无交付的尾流)。投递失败退货 retryable_failed;提供程序确认的上下文溢出(GraphHostContextOverflowError 或者一个 overflow === true 标记)触发运行时的一次压缩恢复,并且同一尾流的第二次溢出携带有界的部分快照(partialResult: true)因此尾流在尝试上限处耗尽(DEFAULT_MAX_DELIVERY_ATTEMPTS = 3),而不是重新尝试第三次完整分娩。调和后的投影读取是交付的一部分:溢出标记的失败触发相同的一次压缩路径。
进一步的探索
- dsh-graph-control -该程序集打开的持久存储(计划日志、索赔、供应、唤醒)。
- dsh-graph-stream -协调器和记录投影折叠执行器和控制器驱动器。
- dsh-graph-executor -操作符执行器及其子运行器/工作树池接缝。
- dsh-tool-graph -把监工的工具放下
agentGraphController. - dsh-graph-wakes -空闲门控尾流运行时间这个组装线。
- dsh-graph-projection ——折叠
graph/change事件到会话图投影。 tests/graph-host.spec.ts-真正的SQLite存储与假的子代理/工作树/压缩/会话事件/空闲。
模型经验
这里没有面向模型的提示文本。模型看到的是三种监管工具 dsh-tool-graph;这个包的贡献是它们运行的控制器服务和 graph/change 附加到根会话日志的事件(会话投影的持久输入,而不是表面元素)。没有kv缓存或令牌效果:执行者本身不调用模型提供者,它通过注入的接缝启动子代理子。
已知的限制和延迟的工作
- 操作员记录是过程本地的。 执行器的记录接收器不携带操作员/会话标识,持久子会话事件将被拒绝,直到
KNOWN_SESSION_EVENT_TYPES是再生的,所以呢InProcessGraphRecordSource+GraphRunIdentityLedger仅在内存中折叠终端记录:主机重新启动时丢失它们,并且会话投影回落到调度/声明状态,直到主机接线添加属性持久事件。 - 只执行一次的激活保护是进程本地的。
OncePerClaimGraphExecutor在内存中通过claim id进行记忆;重新启动后,重新驱动的索赔可以启动第二个子运行,因为持久索赔行记录了接纳,但不记录最终结果。 graph/changeDedup是每个程序集和内存中的:指纹图谱在重启时重置,所以重启后的主机可能会为一个未改变的图谱重新发出一个事件。- 每次挂载一个根会话:该插件的配置名称单个
rootSessionId(尾流运行时间和排放目标的范围是它),和agentGraphController服务名称是每个主机光纤的单例—具有多个图形根的部署需要在单独领域中的每个根主机行,而不是一个共享行。 - 终端工作项停留
requested在持久调度日志中 直到停止/完成更新提交;会话投影派生出finished从折叠的终端记录,所以主机重启丢失记录显示claimed/executing再次(参见记录折叠限制)。