@ag-ui/claude管理代理人
连接一个 乌干达 前端为 克劳德管理代理人Anthropic的经纪人运行时间。 每个 AG- UI 线程映射到一个管理的会话 。 每次运行都会驱动该会话的一个转弯,并将代理的事件作为AG-UI事件回流.
安装
npm install @ag-ui/claude-managed-agents @anthropic-ai/sdk
使用量
创建管理过的代理器和一次环境(在控制台,或通过SDK),然后将其包起来:
import { ManagedAgentsAgent } from "@ag-ui/claude-managed-agents";
const agent = new ManagedAgentsAgent({
managedAgentId: "agent_...",
environmentId: "env_...",
});
agent
.run({ threadId, runId, messages, tools, state, context, forwardedProps })
.subscribe({
next: (event) => console.log(event.type),
});
Anthropic 客户端读取 ANTHROPIC_API_KEY 从环境。 过 client 提供你自己的.
它会做什么
| 管理机构 | 乌干达 |
|---|---|
agent.message (与 event_delta 预览) | TEXT_MESSAGE_START 编号 : CONTENT 编号 : END |
agent.thinking | REASONING_START 编号 : REASONING_MESSAGE_START 编号 : REASONING_MESSAGE_END 编号 : REASONING_END |
agent.tool_use, (中文(简体) ), agent.mcp_tool_use + 结果 | TOOL_CALL_* + 键 TOOL_CALL_RESULT (服务器执行,仅显示) |
agent.custom_tool_use 对于前端工具 | TOOL_CALL_*,然后运行结束,以便客户端可以运行工具 |
agent.custom_tool_use 用于后端工具 | TOOL_CALL_* + 键 TOOL_CALL_RESULT,处理器的结果被放回 |
session.error (终) | RUN_ERROR 错误类型为 code |
session.status_idle (单位:千美元)end_turn(中文(简体) ) | RUN_FINISHED |
前端工具( 人行即时)
工具传入 RunAgentInput.tools 在会话中注册为自定义工具。 当代理呼叫一个时,运行会发出工具呼叫并完成,离开会话停放. 客户端执行工具并启动下一个运行 role: "tool" 信件带有 toolCallId。适配器作为工具结果将其转发到会话中并恢复流出.
后端工具
您服务器执行的工具进入 backendTools数字 :
new ManagedAgentsAgent({
managedAgentId,
environmentId,
backendTools: [
{
name: "get_weather",
description: "Get the weather for a location.",
parameters: {
type: "object",
properties: { location: { type: "string" } },
},
handler: async (input) => JSON.stringify({ temperature: 21 }),
},
],
});
工具调用及其结果流到UI,结果返回代理.
选项
| 选项 | 默认 | |
|---|---|---|
managedAgentId, (中文(简体) ), environmentId | 所需经费 | 被管理的代理人agent_...(a) 每届会议背后的环境. |
agentVersion | 最新消息 | 给一个代理版本. |
client | new Anthropic() | 带上你自己的Anthropic客户端. |
sessionStore | 记忆 | 线段映射, 按键 managedAgentId:threadId。提供自己在重启中生存的机会. |
backendTools | [] | 服务器执行自定义工具 . |
sessionTitle | AG-UI thread <id> | 创建会话的标题 . |
vaultIds | [] | 断层标识( E)vlt_...用于存储的证书,例如认证的MCP服务器。 用于会话创建. |
toolConfirmation | 批准中断 | "allow"编号 :"deny" 在新跑道上回答内置工具。 重新连接需要明确的批准答复. |
turnTimeoutMs | 30万个 | 中断转动 运行更长. |
streamDeltas | true | 请求文本/ 思考预览以进行符号流 . |
onError | 无 | 最佳操作失败时通知 。 也许是 async;它的拒绝被吸收了,所以它所做的任何事情都不能失败跑步. 像其他最好的电话一样被捆绑, 所以一个永远解决不了的钩子不能维持跑步。 没有钩子,原因就到了 console.error 而不是 永远不要对客户. |
安全性:认证和绑定线程给呼叫者
AG-UI 线程 ID 由客户端提供, 而此代理密钥线程%%% session state by managedAgentId:threadId,所以线程ID实际上是一个无记名标识符: 任何提出线程ID的呼叫者都会恢复线程. AG-UI协议没有自己的用户身份,因此授权是您主机的责任:
- 把终点放在你自己的认证后面。 永远不要暴露它未经认证.
RUN_ERROR永不转发失败的文本, 此整合没有作者 。 SDK、会话存储或 API 例外可以带会话 ID、 请求路径或证书, 因此其消息会转到onError客户端得到稳定的信息 加上机器可读code有两点是有意的,因为它们是事件的要点:asession.error从 API (自有结构的字段)type代码,以及唯一关于一个会话破裂的原因的描述)和后端工具自己的例外消息(你的代码,以及代理需要恢复的内容).- 在多租户部署中,将线程绑定在经认证的呼叫器上,这样一个呼叫器无法通过猜测或重放线程ID来恢复另一个的会话. 用这个
sessionStore其密钥包括来自您的认证层( 从未来自请求机构) 的呼叫者身份 :
代理传递的密钥已经被范围化给被管理的代理;把它当作一个不透明的字符串,并用调用者的身份前缀,而不是解析:
class PerCallerStore implements SessionStore {
constructor(
private ownerId: string,
private inner = new Map<string, SessionRecord>(),
) {}
private scoped = (key: string) => `${this.ownerId}|${key}`;
get = (key: string) => this.inner.get(this.scoped(key));
set = (key: string, record: SessionRecord) =>
void this.inner.set(this.scoped(key), record);
delete = (key: string) => void this.inner.delete(this.scoped(key));
}
重复使用每个呼叫者的一存储实例——一次构建并缓存:
const shared = new Map<string, SessionRecord>();
const stores = new Map<string, PerCallerStore>();
const storeFor = (ownerId: string): PerCallerStore => {
let store = stores.get(ownerId);
if (!store)
stores.set(ownerId, (store = new PerCallerStore(ownerId, shared)));
return store;
};
运行在存储实例中按每条线程进行序列化,因此每个请求一个新鲜的包装器会让双提交的线程站两次进入同一会话. 缓存存储( 如上) , 用 storeFor(ownerId)。 。 。 .
页:1
- 默认会话存储为内存:重启进程启动新会话. 管理好的会话本身持续服务器侧.
- 转动是串行每行。 在繁忙的有代码的线程错误上进行第二次运行
run_in_progress。 。 。 . - 只转发用户信件的文本 。 带有图像或二进制部件且没有带代码的文本错误的信息
empty_run而不是创建会话. - 当客户端在新回合(或
abortRun()调用,适配器位置user.interrupt停止会话。 在不中断现有会话的情况下重新连接其流 。 转来转去turnTimeoutMs和错误。 仍然在那个点运行的后端工具处理器被丢弃并用出错回答,所以会话不会被停放. - 内建工具(bash,文件编辑,web)在管理环境中执行. 这个适配器将它们表面显示, 因此可以像往常一样在您的代理上显示它们 .
- 工具结果
text块到达 UI 逐字记录: 它们携带文字输出( 文件读取, shell 记录), 其中<意思是那四个角色 仅search_result块,其体从 HTML 中取出,其实体被解码. - 工具结果后立即张贴的后继消息可以与会话同步的不park相竞争并被以400个拒绝. 这种具体的拒绝是经过重审的,与包含
waiting on responses——未证实反对活泼API的措辞. 如果API重写它,则重试停止射击,400个表面作为跑出错误;没有其他任何影响. 见"相会"上的评论. - 默认的内存商店是被绑定的( N)
IN_MEMORY_SESSION_STORE_MAX_ENTRIES, 10000 映射 : 线程 ids 是客户端提供的, 所以过去最不常用的映射被删除 线程开始一个新的会话 。 把一个较小的盖子递到new InMemorySessionStore(n),或提供持久商店. - 被中断的运行——转会超时,客户端断接,或被屏蔽的动作,这种集成无法回答——忘记了它记录的被停放的前端工具呼叫. 打断会话取消任何等待的时间,所以在下一轮的比赛中回答其中一次电话会因为呆滞而被拒绝. 如果中断本身无法发送,则保留身份证,因为会议可能仍然停在身份证上.
- 注册自定义工具的会话会持有一个完整的替换工具列表,在上次更新时被冻结,因此代理器自己的工具每次运行后都会被重新读取,以捕捉一个Console编辑到它们. 没有自定义工具的会话将代理运行为-is并跳过完全读取的会话 .
运行实例
cd integrations/claude-managed-agents/typescript
pnpm install
export ANTHROPIC_API_KEY=sk-ant-... # or ANTHROPIC_AUTH_TOKEN
pnpm setup:examples # provisions an environment + one agent per Dojo feature (idempotent)
pnpm dev:examples # http://localhost:8024
设置将提供的ID写入 examples/.managed-agents.json (恶作剧). 它按名称重新使用现有剂剂,不修改:应用即时或模型更改从 examples/agents.ts,归档代理并重新运行设置.
实例默认为 claude-sonnet-5-5,通过本地系统消息支持运行时上下文. MANAGED_AGENTS_MODEL 覆盖此默认; 从 系统注入支持列表。在 Sonnet 5 上创建的现有代理不通过更改此变量或重运行设置来升级。 要迁移,归档旧的示例代理,重新运行到提供替换的设置并重写所保存的ID,然后重新启动示例服务器并启动新的会话. 现有会议仍受原机构的约束.
重新连接现有会话
提供持久性 SessionStore 以保持线程/会话绑定,等待
请求和本地事件光标跨越后端重新启动 。 默认商店是
在记忆中。 存储器必须使用经认证的调用器分割记录并序列化
横跨复制;适配器的在进程锁定不协调服务器.
对于导入的会议,配置 resolveSession(threadId) 在服务器上。 这个
callback必须授权呼叫者访问并返回原装订:
resolveSession: async (threadId) => {
const imported = await authorizedImports.find(threadId);
if (!imported) return undefined; // Only for genuinely new conversations.
return {
sessionId: imported.sessionId,
lastUserMessageId: imported.lastUserMessageId,
lastEventId: imported.lastNativeEventId,
};
};
authorizedImports 代表您的认证应用程序的持久导入
映射,不是客户端提供的会话选择器. 因无法进入或缺失而抛出
导入的会话而不是返回 undefined,允许新届会
创建. lastUserMessageId 是最后一个导入的 AG- UI 用户消息ID ;
lastEventId 是进口商已经保存的最后一个本地事件。 如果省略,则,
初始收养将提交的用户历史和当前本地历史视为
已经导入。 提供两个边界允许第一个后续和任何
活动自导入后与旧历史区分.
空运行在不发送用户文本的情况下重新连接已有的映射 。 通过 会话保留其本地工具配置 。 重新连接打开本地 在列出历史之前,恢复其原始身份号码的待拨电话, 并重放保存的事件光标后的活动,而不执行旧的工具. 终止或不可用的会话返回一个明显的运行错误并保留它们 绑定; 启动一个新的 AG- UI 线程以创建替换 .
自定义工具答案使用普通 role: "tool" 带原始信件
toolCallId。原始工具权限显示为 RUN_FINISHED.outcome
以理由打断 tool-approval; 以
resume: [{ interruptId, status: "resolved", payload: "allow" }] 或有效载荷
"deny"。 。 。 . status: "cancelled" 明确拒绝这一要求。 部分答复
让其他请求待决;新的用户信息永远不会拒绝.
约束可包括: sessionThreadId 检查并回答孩子的线索.
本地工具 ID 路由结果自动给正确的孩子 。 新用户
信息必须针对主会话;适配器拒绝儿童跟进
而不是送他们给错误的代理人。 其他本地内容重播
由于RAW事件仍可供记录应用程序使用; 使内容更加丰富
内容取决于应用程序的事件处理.