@agent-assistant/harness
@agent-assistant/harness 是一个助手转接的限定运行时间,其中包含迭代模型/工具/模型执行,真实的停止语义学,结构化续接有效载荷,以及痕量钩.
其存在是为了填补一发一发的助理运行时间和无约束的自主代理框架之间的空白.
它拥有什么
- 单助手回合的限定执行
- 迭代模型/工具/模型循环
- 真实结果:
completed, (中文(简体) ),needs_clarification, (中文(简体) ),awaiting_approval, (中文(简体) ),deferred, (中文(简体) ),failed - 明确停止原因
- 用于澄清、核准和延期恢复的紧凑续载荷
- 微量/遥测生命周期事件
- 模型、工具、批准和痕量汇的适配接器
它不拥有的东西
- 辅助寿命周期或运行时间登记(
@agent-assistant/core(中文(简体) ) - 持续举办(
@agent-assistant/sessions(中文(简体) ) - 内存存储或检索( e)
@agent-assistant/memory(中文(简体) ) - 路线政策所有权
@agent-assistant/routing(中文(简体) ) - 政策所有权
@agent-assistant/policy(中文(简体) ) - 协调/工作流程引擎
@agent-assistant/coordination(中文(简体) ) - 劳动力定义a
安装
npm install @agent-assistant/harness
工作空间 VFS 工具
createWorkspaceToolRegistry 暴露提供者中性 workspace_search, (中文(简体) ), workspace_list, (中文(简体) ), workspace_read,以及 workspace_read_json 辅助工具 VfsProvider 从 @agent-assistant/vfs。这些工具释放VFS路径,包括 sourcePath-为 JSON 所读的样式结构化输出,所以调用者可以在用户可见的答复中引用文件路径,而不是从内存中回答工作空间问题.
公共 GitHub 工具
GitHubPublicFetcher 支持对一个公开的 GitHub repo 进行有限制的只读检查:元数据、 README/ package 摘录、 目录列表、 焦点文件读取、 最近的承诺和认证代码搜索。 默认获取后退读取 globalThis.fetch 因此Cloudflare工人消费者可以安全地支接或依靠平台取回绑定.
使用 createPublicGitHubToolRegistry({ owner, repo }) 当一个助手已经解决了一个明确命名的公用回购,并且需要通过 public_repo_metadata, (中文(简体) ), public_repo_list_tree, (中文(简体) ), public_repo_read_file, (中文(简体) ), public_repo_recent_commits,可选择 public_repo_search_code。 。 。 .
快速示例
import { createHarness } from '@agent-assistant/harness';
const harness = createHarness({
model: {
async nextStep(input) {
if (input.toolCallCount === 0) {
return {
type: 'tool_request',
calls: [
{
id: 'call-1',
name: 'lookup_weather',
input: { city: 'Oslo' },
},
],
};
}
return {
type: 'final_answer',
text: 'It looks chilly in Oslo today.',
};
},
},
tools: {
async listAvailable() {
return [{ name: 'lookup_weather', description: 'Get current weather' }];
},
async execute(call) {
return {
callId: call.id,
toolName: call.name,
status: 'success',
output: '{"temperatureC":8}',
};
},
},
});
const result = await harness.runTurn({
assistantId: 'sage',
turnId: 'turn-123',
sessionId: 'session-123',
message: {
id: 'msg-1',
text: 'What is the weather in Oslo?',
receivedAt: new Date().toISOString(),
},
instructions: {
systemPrompt: 'You are Sage. Be concise and truthful.',
},
});
OpenRouter 执行适配器
现在的被套装还暴露出OpenRouter后置转弯的受限主机执行适配器.
这是什么
这个 OpenRouterExecutionAdapter 是一个直接寄存的后端, 后面的已有 ExecutionAdapter 缝合.
这意味着代理助理仍然拥有:
- 助理身份
- 转折文本组装
- 政策
- 继续语义
- 二. 内继合作
适配器只拥有:
- 请求翻译
- 后端引用
- 产出正常化
- 真实能力/降级报告
目前范围
此适配器在当前切片中有意缩小:
- 后端代码 :
openrouter-api - 直接托管的 API 执行
- 没有工具只转
- 微量追踪事实
- 说实话
unsupported/已退化的谈判
当前非目标
这个适配器是 没有 当前支持 :
- 带有工具的执行
- 结构化工具调用
- 附录
- 结构化延续支助
- 核准中断
示例
import {
OpenRouterExecutionAdapter,
type ExecutionRequest,
} from '@agent-assistant/harness';
const adapter = new OpenRouterExecutionAdapter({
apiKey: process.env.OPENROUTER_API_KEY,
model: 'openai/gpt-5-mini',
});
const request: ExecutionRequest = {
assistantId: 'sage',
turnId: 'turn-456',
message: {
id: 'msg-2',
text: 'Summarize the current PR status.',
receivedAt: new Date().toISOString(),
},
instructions: {
systemPrompt: 'You are Sage. Be concise and truthful.',
developerPrompt: 'Do not invent missing GitHub state.',
},
context: {
blocks: [
{
id: 'ctx-1',
label: 'Scope',
text: 'Only summarize what is present in the supplied context.',
},
],
},
};
const negotiation = adapter.negotiate(request);
if (!negotiation.supported) {
throw new Error(negotiation.reasons.map((reason) => reason.message).join(' '));
}
const result = await adapter.execute(request);
诚实的使用指南
需要时使用此适配器 :
- a 主机API后端
- 一个无入地转弯
- 已正常化
ExecutionResult输出通过与其他后端相同的执行接合
执行 没有 将它作为替换:
- 本地 CLI 控制 BYOH 路径
- 二. 内继合作
- 未来能够使用的工具的主办执行工作
本地命令执行适配器
套装也暴露了可重复使用 LocalCommandExecutionAdapter bYOH/当地
CLI执行. 它不偏重任何产品:产品保持助理身份、政策、记忆和
转折语装配,而适配器只拥有本地进程引用和结果
正常化.
当一个本地吊带能够表现为:
- 产卵命令
- 来自
ExecutionRequest - 一个输出解析器为普通助理输出
- 已声明
ExecutionCapabilities
import {
LocalCommandExecutionAdapter,
type ExecutionRequest,
} from '@agent-assistant/harness';
const adapter = new LocalCommandExecutionAdapter({
backendId: 'my-local-harness',
command: 'my-harness',
capabilities: {
toolUse: 'adapter-mediated',
structuredToolCalls: true,
continuationSupport: 'none',
approvalInterrupts: 'none',
traceDepth: 'minimal',
attachments: false,
},
buildArgs(request: ExecutionRequest) {
return ['--json', '--prompt', request.message.text];
},
parseOutput(stdout) {
const parsed = JSON.parse(stdout) as { text?: string };
return parsed.text ? { text: parsed.text } : null;
},
});
ClaudeCodeExecutionAdapter 现在是一个预设 在这个相同的本地命令原始。 就是这样
Claude Code 支持完好无损,同时允许其他本地用具使用相同的
ExecutionAdapter 合同.
代理中继执行适配器
对于长生不老的当地人来说, AgentRelayExecutionAdapter 使用代理中继器作为本地
控制飞机 它向中继工作人发布一个打印执行请求,并等待一个打印
执行结果在同一线索上.
import {
AgentRelayExecutionAdapter,
} from '@agent-assistant/harness';
const adapter = new AgentRelayExecutionAdapter({
cwd: process.cwd(),
channelId: 'nightcto-local-byoh',
workerName: 'nightcto-local-harness',
orchestratorName: 'nightcto-local-chat',
});
请求信件正文为 JSON 有类型 agent-assistant.execution-request.v1。 。 。 .
工人用JSON类型回答 agent-assistant.execution-result.v1 还有一个 executionResult
遵循常态 ExecutionResult 合同。 旋转成功应使用
executionResult.status: "completed" 把助手的回答输入
executionResult.output.text。适配器也容忍常见的本地工人的短手
例如 status: "ok" 加号 answer 并使他们恢复正常 ExecutionResult
形状。 这保留了Claude Code, Codex, OpenCode 或 Relay 背后的定制本地工人
而不是在产品中烘焙供货商特有的CLI argv.
产卵工人与工人-桥梁
AgentRelayExecutionAdapter是因为 spawnWorker.enabled 产出一个裸露的CLI
中继代理并期望它能自行响应符合协议的信息.
只有产卵式CLI有MCP工具有线发送打入的中继器才有效
消息 – 不是大多数 CLI 的默认 。 离开 spawnWorker.enabled
虚假和运行 a 工人桥梁 进程(见下一节)
是推荐的形状;桥对协议进行翻译,这样
CLI只是一个即时的,文本输出的子进程.
工人-桥梁@agent-assistant/harness/worker-bridge(中文(简体) )
适配器的双相. 聆听 agent-assistant.execution-request.v1
中继通道上的信件,引用非交互的 CLI 会话
(单位:千美元)claude -p, (中文(简体) ), codex exec, (中文(简体) ), opencode run, (中文(简体) ), gemini -p,或者一个击球杆
测试,抓取 stdout,以及用正确形状的回复
agent-assistant.execution-result.v1 留言.
// RelayAdapter wraps @agent-relay/harness-driver's broker client. It was
// exported by @agent-relay/sdk up to 6.x; the SDK no longer ships it.
import { RelayAdapter } from '@agent-assistant/harness/agent-relay';
import {
createClaudeCliRunner,
createRelayWorkerBridge,
} from '@agent-assistant/harness/worker-bridge';
const relay = new RelayAdapter({ cwd: process.cwd(), channels: ['specialists'] });
await relay.start();
const bridge = await createRelayWorkerBridge({
relay,
channelId: 'specialists',
workerName: 'specialist-worker',
runner: createClaudeCliRunner(),
timeoutMs: 120_000,
});
// ... later
bridge.dispose();
await relay.shutdown();
提供运行器 : createClaudeCliRunner, (中文(简体) ), createCodexCliRunner, (中文(简体) ),
createOpenCodeCliRunner, (中文(简体) ), createGeminiCliRunner,以及
createBashCliRunner (用于免签测试). 每个都要选择
{ command, spawnFn } 覆盖可执行文件或插入文件的配置
模拟 child_process.spawn。 。 。 .
CliRunner 是一个最小的接口( e){ id, run(input) }这样你就可以插上
或嵌入式函数.
适配器+桥是有意在生产中分离的工艺:
适配器住在哪里 你的管弦乐手运行, 桥梁住在
机器/容器,实际上应该引用CLI。 跨进程中介
发现是通过 {cwd}/.agent-relay/connection.json。 。 。 .
packages/webhook-runtime/examples/byoh-worker.ts 是薄薄的包装
这个 API 曝光 --cli, (中文(简体) ), --channel, (中文(简体) ), --worker-name, (中文(简体) ), --model,以及
--timeout-ms 旗为"双地"局部实验流.
公共 API
import {
AgentRelayExecutionAdapter,
HarnessConfigError,
LocalCommandExecutionAdapter,
OpenRouterExecutionAdapter,
createAgentRelayExecutionAdapter,
createHarness,
createLocalCommandAdapter,
createOpenRouterAdapter,
type ExecutionAdapter,
type ExecutionRequest,
type ExecutionResult,
type HarnessConfig,
type HarnessContinuation,
type HarnessModelAdapter,
type HarnessResult,
type HarnessRuntime,
type HarnessToolRegistry,
type HarnessTraceSink,
type HarnessTurnInput,
} from '@agent-assistant/harness';
运行时行为说明
- v1 工具执行默认顺序
- 批准是适配器接合; 软件包不拥有政策
- 限制停止返回
deferred持续有效载荷的结果 - 无效的模型输出仅在配置范围内被容忍
- 运行时间/模型/工具故障作为结构化结果出现,而不是隐藏在假补全之后
发展
从软件包目录 :
npm test
npm run build
目前软件包验证包括一个非三角测试套件,涵盖:
- 最后答复执行
- 相继工具循环
- 澄清和核准
- 无效的输出恢复和失败界限
- 可重试 vs 无法恢复的工具错误
- 延期结果和预算上限
- 运行时出错 :
- 聚焦 OpenRouter 适配器覆盖范围, 用于锁定无工具主机执行
危险 包件 模拟