- 后端
- 前端
- 协同办公
- 即时通讯
- 企业应用
- CRM
- AI Agent
- 人工智能
【免费下载链接】macro
Macro is a unified workspace for teams: email, chat, docs, tasks, agents, calls, and CRM — @-linked together with shared AI memory.
本文聚焦 Macro 仓库中由 OpenAPI 规范自动生成的 TypeScript 类型别名GetCodeExecutionErrors。该类型描述了 Agent Harness 浏览器 API 中「读取单次代码执行记录」端点(GET /agent-sessions/{session_id}/code-executions/{execution_id})的全部错误响应契约。读完本文,你可以准确理解该类型为何将四种 HTTP 状态码全部声明为unknown、这些状态码在服务端分别对应什么真实响应体,以及成功时返回的ExecutionRecord包含哪些关键字段,从而在客户端 SDK 中写出类型安全、可预期的错误处理代码。
GetCodeExecutionErrors 的定义与属性表
GetCodeExecutionErrors是 生成的 API 参考文档 中收录的一个类型别名,其完整定义为:
> **GetCodeExecutionErrors** = { > 401: unknown; > 403: unknown; > 404: unknown; > 500: unknown; > }属性列表如下(完整继承自生成文档):
| Property | Type |
|---|---|
401 | unknown |
403 | unknown |
404 | unknown |
500 | unknown |
这个结构的语义是:以 HTTP 状态码为键、以该状态码下可能的错误响应体类型为值的映射表。四个键401、403、404、500与 OpenAPI 规范中声明的响应码一一对应;值统一为unknown,表示规范侧没有为这些错误响应声明具体的响应体 Schema——生成器不会臆造错误体结构,而是诚实地将其标记为unknown,要求消费方在访问错误内容前自行收窄类型。
该类型的真实来源是 SDK 生成代码:
export type GetCodeExecutionErrors = { 401: unknown; 403: unknown; 404: unknown; 500: unknown; };值得注意的是,unknown并非这个 API 中错误类型的普遍形态。同一份生成文件中,相邻端点(例如GetAgentSessionChangesPatchErrors)的错误体被生成为string,而本端点的错误体却全部是unknown。这说明差异直接来自服务端 OpenAPI 注解对错误响应是否声明了 body:声明了才生成具体类型,未声明则回退为unknown。
该契约所属的端点:getCodeExecution
GetCodeExecutionErrors与一组配套类型共同描述同一个 GET 请求:
- GetCodeExecutionData:请求数据,声明了路径参数与 URL 模板:
export type GetCodeExecutionData = { body?: never; path: { /** * Owning session */ session_id: string; /** * Execution receipt identity */ execution_id: string; }; query?: never; url: '/agent-sessions/{session_id}/code-executions/{execution_id}'; };两个路径参数均为必填:session_id是「所属 agent session 的 ID」,execution_id是「执行回执的身份标识(Execution receipt identity)」。
GetCodeExecutionResponses:成功响应只有
200: ExecutionRecord一种。GetCodeExecutionErrors:即本文主题。
在 生成的客户端 SDK 中,三者通过泛型参数绑定到同一个方法:
public getCodeExecution<ThrowOnError extends boolean = false>( options: Options<GetCodeExecutionData, ThrowOnError> ): RequestResult<GetCodeExecutionResponses, GetCodeExecutionErrors, ThrowOnError> { return (options.client ?? this.client).get<GetCodeExecutionResponses, GetCodeExecutionErrors, ThrowOnError>({ url: '/agent-sessions/{session_id}/code-executions/{execution_id}', ...options, }); }从签名结构看,getCodeExecution接受Options<GetCodeExecutionData>(即必须提供session_id与execution_id),并返回一个以「成功响应表 / 错误响应表 / 是否抛错」为三元泛型的RequestResult。ThrowOnError泛型提供了两种消费方式:默认false时由调用方检查返回值处理错误,置为true时由客户端在失败时抛出异常。错误分支的类型上界正是GetCodeExecutionErrors这张状态码映射表,因此对error做任何字段访问前,都只能拿到unknown,必须自行断言或做防御性解析——这是该契约对客户端代码的直接约束。
服务端:四个状态码分别从何而来
GetCodeExecutionErrors的四个键不是凭空声明的,而是与服务端实现一一对应。该端点由 agent_code_mode crate 的 axum 路由 挂载,路由文件顶部注释说明其定位是「session-authorized reads for code execution's existing tool components」(在会话级授权下读取代码执行组件的既有能力),并在 agent_harness_service 的 main.rs 中通过with_code_executions合并进/agent-sessions路由族。
其 OpenAPI 注解精确声明了与生成类型一致的响应集合:
#[utoipa::path(get, path = "/agent-sessions/{session_id}/code-executions/{execution_id}", tag = "agent-sessions", operation_id = "get_code_execution", params(("session_id" = Uuid, Path, description = "Owning session"), ("execution_id" = Uuid, Path, description = "Execution receipt identity")), responses((status = 200, body = ExecutionRecord), (status = 401), (status = 403), (status = 404), (status = 500)))](见 axum_router.rs。)可以看到错误响应只写了状态码、没有写body = ...——这正是生成器把四个错误体全部落为unknown的原因。
各状态码的实际产生路径如下:
- 401 / 403:由请求进入 handler 之前的授权抽取器拦截。handler 的第一个参数是
AgentSessionAccessLevelExtractor<ViewAccessLevel, Access, Auth>(读取权限级别的实体访问抽取器),见 get_code_execution 签名。未认证请求在认证层被拒(401);已认证但对目标 session 没有 view 权限的请求返回 403,此时响应体来自 CodeExecutionApiError 的错误映射:
CodeModeError::Forbidden => (StatusCode::FORBIDDEN, "forbidden").into_response(),- 404:执行记录不存在(或无法经该 session 定位到),同样经由该映射表返回固定文本:
CodeModeError::NotFound => (StatusCode::NOT_FOUND, "code execution not found").into_response(),- 500:兜底分支。源码在此分支调用
tracing::error!(error = ?error, "code execution read failed")记录内部错误,但对客户端只返回脱敏文案"could not read code execution",刻意避免泄露基础设施细节(该注释即函数上方的 doc 意图:Map domain failures without exposing infrastructure details)。
也就是说,虽然规范层面四个错误体都是unknown,但从源码可以确认:403/404/500 的实际响应体都是纯文本字符串,401 的响应体由认证中间件决定。客户端拿到unknown类型的错误值后,按字符串处理是符合当前实现事实的推断,但仍建议保留防御性判断以兼容后续演进。
成功路径:ExecutionRecord 的字段结构
理解错误契约的另一面,是知道 200 时到底拿什么。GetCodeExecutionResponses的唯一成员 ExecutionRecord 定义了执行记录的持久化快照:
| 字段 | 类型 | 说明(引自生成类型注释) |
|---|---|---|
executionId | ExecutionId(即string) | 执行身份标识;类型注释说明这是「执行开始前就持久化在工具输入中的、由调用方选择的 UUID」 |
source | string | 提交的 JavaScript 模块(The submitted JavaScript module) |
status | ExecutionStatus | 整体执行状态,取值为'running' \| 'succeeded' \| 'failed' \| 'cancelled' \| 'timed_out' |
result | unknown | 程序成功时返回的 JSON |
error | string \| null | 安全的执行失败文本(Safe execution failure text) |
calls | Array<RecordedToolCall> | 历史桥接调用;直接 HTTP 执行时为空 |
activity | Array<ExecutionActivity> | 有界观察到的 SDK 操作活动,不含参数与响应内容 |
activityTruncated | boolean | 超出有界观察上限而被省略的活动标记 |
turnId | string \| null | 原始回合,防止其他请求方重放已保存的结果 |
actingAs | ToolActor \| null | 代执行身份 |
该类型的 doc 注释强调:它包含「持久化的来源与最终结果,以及存在时的历史桥接调用」,但完整日志(journal)并不包含在模型的 tool result 中。对消费方的含义是:status === 'running'时result尚不可用,'failed' | 'timed_out' | 'cancelled'时应读取error字段获取脱敏后的失败文本。
相关端点与错误契约的对照
同一 router 中还挂载了与执行记录相关的其它端点,其错误契约的差异有助于定位GetCodeExecutionErrors在整体设计中的位置:
| 端点 | URL | 错误契约(生成类型) |
|---|---|---|
get_code_execution | GET /agent-sessions/{session_id}/code-executions/{execution_id} | GetCodeExecutionErrors:401 / 403 / 404 / 500 |
list_execution_reviews | GET /agent-sessions/{session_id}/code-executions/{execution_id}/reviews | ListExecutionReviewsErrors:仅 403 |
create_session_review | POST /agent-sessions/{session_id}/reviews | 400 / 403 |
get_session_review | GET /agent-sessions/{session_id}/reviews/{review_id} | 403 / 404 |
decide_session_review | POST /agent-sessions/{session_id}/reviews/{review_id} | 403 / 409(review 已被并发修改) |
(以上 URL 与响应声明见 axum_router.rs 中各 utoipa 注解。)get_code_execution是其中错误面最宽的读端点:既可能未认证(401),也可能无权限(403)、记录不存在(404)、存储层故障(500);而列举 review 的端点在注解上只声明了 403。这类差异完全以服务端 utoipa 注解为准,生成文档(如 types.gen 目录索引)与 types.gen.ts 只是其 TypeScript 投影。
小结与延伸阅读
GetCodeExecutionErrors本身是一张「状态码 → 错误体类型」的映射表,四个键对应GET /agent-sessions/{session_id}/code-executions/{execution_id}的全部错误响应;值全为unknown是 OpenAPI 注解未声明错误 body 的直接结果,而非实现缺陷。- 服务端实现保证 403/404/500 返回固定脱敏文本,500 分支会在服务端日志中保留完整错误(
tracing::error!),便于排障时对照日志而非响应体。 - 客户端应基于
RequestResult<GetCodeExecutionResponses, GetCodeExecutionErrors, ThrowOnError>的泛型约束编写错误处理:在访问unknown错误体前显式收窄,成功后围绕ExecutionRecord.status的五态机(running / succeeded / failed / cancelled / timed_out)分支处理。
延伸阅读路径:
- 生成参考文档:GetCodeExecutionErrors.md、types.gen 类型索引
- 生成 SDK 类型与客户端:types.gen.ts、sdk.gen.ts
- 服务端路由与错误映射:axum_router.rs
- 路由挂载点:agent_harness_service main.rs
- 执行策略与领域模型所在 crate:crates/code_execution
- 后端
- 前端
- 协同办公
- 即时通讯
- 企业应用
- CRM
- AI Agent
- 人工智能
【免费下载链接】macro
Macro is a unified workspace for teams: email, chat, docs, tasks, agents, calls, and CRM — @-linked together with shared AI memory.
相关推荐
Macro Agent Harness SDK 中的 ExtractErrors:`/universal_input/extract` 四类错误契约与容错实现
Macro Agent Harness SDK 中的 ExtractErrors: /universal_input/extract 四类错误契约与容错实现 在
后端前端协同办公即时通讯企业应用CRMAI Agent人工智能Macro Agent Harness SDK 错误类型详解:GetAgentSessionChangesPatchError 与变更 Patch 接口的错误契约
Macro Agent Harness SDK 错误类型详解:GetAgentSessionChangesPatchError 与变更 Patch 接口的错误契
后端前端协同办公即时通讯企业应用CRMAI Agent人工智能Macro agent-harness SDK 中的 GetAgentSessionPermissionsErrors 错误类型解析:Agent 会话共享权限查询接口的错误契约
Macro agent harness SDK 中的 GetAgentSessionPermissionsErrors 错误类型解析:Agent 会话共享权限查
后端前端协同办公即时通讯企业应用CRMAI Agent人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考