
Agent Zero 前端 JSON API 前置扩展点json_api_call_before 钩子深度解析与实战【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero导读json_api_call_before是 Agent Zero 前端WebUI扩展体系中负责在callJsonApi()实际发起请求之前拦截并处理上下文的扩展点。本文以其 DOX 契约文档 extensions/webui/json_api_call_before/AGENTS.md 为骨架结合 webui/js/api.js、webui/js/extensions.js 等核心源码讲清楚该钩子的触发时机、上下文对象结构、模块契约、加载机制与编写规范并给出可直接落地的扩展编写示例与验证方法。读完本文你将掌握如何在 Agent Zero 的 WebUI 中安全地注入请求前逻辑如参数归一化、日志记录、条件拦截同时不破坏 CSRF 鉴权与 JSON 载荷契约。扩展点定位Own 前置钩子的职责边界DOX 文档首先明确了json_api_call_before的目的Purpose与所有权Ownership该文件夹拥有所有在callJsonApi()调用之前运行的**前端frontend**扩展钩子文件夹内的文件负责 JSON API 请求的 before-call 行为before-call behavior该扩展点是 WebUI 侧浏览器内运行的 JavaScript 扩展而非 Python 后端扩展。在 Agent Zero 的 WebUI 扩展体系中extensions/webui/下的每个直接子目录对应一个前端扩展点extension point。依据 extensions/webui/AGENTS.md该目录内的.js/.mjs文件导出默认函数由callJsExtensions统一调用。json_api_call_before与同级的 json_api_call_after请求后、fetch_api_call_before原始 fetch 前共同构成 WebUI 对 JSON API 调用的三层拦截能力本文聚焦于请求前这一层。callJsonApi 生命周期前置钩子的精确触发时机要理解json_api_call_before必须先看它的宿主函数callJsonApi。其完整实现位于 webui/js/api.jsexport async function callJsonApi(endpoint, data) { const apiUrl _normalizeApiUrl(endpoint); /** type {{ endpoint: string, data: any, response: Response | null, result: any, error: Error | null }} */ const ctx { endpoint, data, response: null, result: null, error: null, }; if (await _shouldCallApiExtensions(apiUrl)) { const extensions await _getExtensions(); await extensions.callJsExtensions(json_api_call_before, ctx); } const response await fetchApi(ctx.endpoint, { method: POST, headers: { Content-Type: application/json }, credentials: same-origin, body: JSON.stringify(ctx.data), }); ctx.response response; if (!response.ok) { const error await response.text(); ctx.error new Error(error); // ... json_api_call_error 钩子 ... if (ctx.error) throw ctx.error; return ctx.result; } ctx.result await response.json(); // ... json_api_call_after 钩子 ... return ctx.result; }从源码可以梳理出关键事实触发顺序callJsonApi构建ctx上下文对象后在发起fetchApi之前先同步await执行所有json_api_call_before扩展请求成功后再触发json_api_call_after失败时触发json_api_call_error。整个生命周期为before→ HTTP POST →error失败或after成功。共享可变上下文ctx前置钩子收到的正是后续请求所使用的同一个ctx对象。因此在 before 扩展中修改ctx.endpoint或ctx.data会直接影响后续实际发出的请求第 25-32 行的fetchApi使用ctx.endpoint与ctx.data。这是该扩展点最强大的能力也是 DOX 文档警告避免宽泛请求修改的原因。未序列化前的原始数据钩子触发时data尚未经过JSON.stringify扩展看到的是原始 JavaScript 对象可以在不破坏 JSON 序列化的情况下做字段级处理。端点归一化_normalizeApiUrlwebui/js/api.js会把cache_reset之类的短名称规范化为/api/cache_reset/api/...或api/...前缀则保持为/api/...形式。注意ctx.endpoint仍保留调用方传入的原始值cache_reset而ctx.data之后的请求 URL 用的是归一化结果——编写按端点分流的扩展时应对照ctx.endpoint的原始形态。排除端点_shouldCallApiExtensions会检查 webui/js/extensions.js 中的API_EXTENSION_EXCLUDED_ENDPOINTS集合目前包含/api/load_webui_extensions避免扩展加载本身触发扩展递归。底层 fetch 层的 CSRF 与重试callJsonApi实际调用的是fetchApiwebui/js/api.js该函数在请求前通过getCsrfToken()获取 CSRF token 并写入X-CSRF-Token请求头若响应为 403 且允许重试会清除缓存 token 后自动重试一次同时处理登录重定向redirect。这意味着前置扩展无需也不应自行处理 CSRF 与鉴权——DOX 文档明确要求保留/js/api.js期望的 CSRF/auth 行为与 JSON 载荷形态。本地契约扩展模块必须遵守的规则DOX 文档的Local Contracts是扩展开发者的硬性规范JavaScript 模块必须导出默认函数default functioncallJsExtensions的调用逻辑位于 webui/js/extensions.js它对每个扩展模块执行await extension.module.default(...data)。因此扩展文件必须形如export default async function (ctx) { ... }接收的唯一实参就是ctx上下文对象。保留 CSRF/auth 行为与 JSON 载荷形态不要在 before 扩展中篡改请求头、凭据或试图绕过鉴权也不要破坏ctx.data的可序列化性例如塞入循环引用、函数或BigInt否则JSON.stringify会抛错。错误隔离callJsExtensions内部对每个扩展包了try/catch见 webui/js/extensions.js单个扩展抛错只会console.error打印路径与错误不会中断其他扩展或阻断callJsonApi主流程。但要注意契约并未要求 before 扩展吞掉业务异常若你在扩展中抛出错误它会被该 try/catch 捕获而不会向上传播——因此不要在扩展内依赖抛错即中止请求的行为如需中止请求应显式修改ctx并做好记录。扩展加载机制从 manifest 到模块执行json_api_call_before扩展点下的.js文件是如何被发现的链路如下loadJsExtensions(extensionPoint)webui/js/extensions.js首先从manifestExtensionPaths(js, extensionPoint)读取运行时注入的globalThis.runtimeInfo.webuiExtensionsmanifest若 manifest 不可用则回退调用后端 APIcallJsonApi(/api/load_webui_extensions, { extension_point, filters: [*.js, *.mjs] })获取扩展路径列表对每个路径执行动态import(normalizePath(path))将模块按扩展点缓存到JS_CACHE_AREAfrontend_extensions_js(extensions)(plugins)之后callJsExtensions命中缓存直接逐个调用module.default(...data)。后端侧api/load_webui_extensions.py 的LoadWebuiExtensions.process从helpers.extension.get_webui_extensions汇总扩展文件路径并返回{extensions: [...]}。这也解释了 DOX 文档文件在此文件夹即生效的所有权模型只要把符合契约的.js/.mjs文件放进extensions/webui/json_api_call_before/或插件对应的同名扩展点就会被自动发现、加载并执行无需额外注册。实战示例编写一个 json_api_call_before 扩展下面给出一个符合 DOX 契约的扩展编写范式。仓库中json_api_call_before目录目前仅包含 DOX 文档尚无扩展文件因此以下示例是依据源码契约编写的示意代码可直接套用该模式。同时可对照真实的 after 扩展 extensions/webui/json_api_call_after/cache_reset.js 体会前后置钩子的写法差异// extensions/webui/json_api_call_before/example_log.js // 契约必须导出默认函数接收 callJsonApi 的 ctx 上下文对象 export default async function beforeJsonApiCall(ctx) { try { // 1. 只针对特定端点生效避免宽泛修改影响无关调用 if (ctx.endpoint ! some_specific_api) return; // 2. 在 JSON.stringify 之前做字段级归一化保证 payload 形态不被破坏 if (ctx.data typeof ctx.data object) { ctx.data.traceId webui-${Date.now()}; } // 3. 记录请求前状态日志、埋点等副作用应保持轻量 console.debug([json_api_call_before], ctx.endpoint, ctx.data); } catch (e) { // 自身异常自行消化不要影响主流程 console.error(e); } }与 after 扩展的对比对比 cache_reset.js请求后它通过ctx.endpoint cache_reset判断端点随后遍历ctx.data.areas调用 webui/js/cache.js 的clear(area)清除前端缓存区域。可以看到前后置钩子共享同一套 ctx 结构与端点分流写法区别仅在于before 阶段ctx.response、ctx.result均为nullctx.error也为null可用信息只有endpoint与dataafter 阶段才可读取ctx.response、ctx.result成功或ctx.error失败由json_api_call_error钩子处理。工作指引安全边界与反模式DOX 文档的Work Guidance只有一条但分量十足Avoid broad request mutation that affects unrelated plugin or core API calls.避免影响无关插件或核心 API 调用的宽泛请求修改。结合源码这意味着务必按ctx.endpoint白名单分流callJsonApi被 WebUI 各处广泛使用消息队列、模型门控、插件列表、项目、设置、通知、MCP 服务器管理等 20 个 store可参见 webui/components 下的各 store 文件未加端点判断的全局修改会波及所有功能不要碰请求头与凭据CSRF token 注入与 403 重试由fetchApi统一负责扩展层修改fetch选项会破坏 webui/js/api.js 的既有契约保持 ctx.data 可序列化JSON.stringify(ctx.data)发生在钩子之后任何不可序列化的污染都会直接抛错副作用保持轻量参考 extensions/webui/AGENTS.md 的建议优先委托既有 WebUI store 或 helpers用户可见的提示走 notification store。验证方法改完如何确认没破坏 API 调用DOX 文档的Verification要求修改后对受影响的 JSON API 调用做 smoke test冒烟测试。实际操作建议端点级冒烟在浏览器 DevTools 中依次触发受影响的 API如切换设置、加载项目、发送消息队列确认请求正常发出、无 4xx/5xx、控制台无扩展报错观察扩展错误日志callJsExtensions的 catch 会以Error calling extension: path形式输出任何 before 扩展异常都会暴露在此验证扩展加载链路后端侧可参考测试 tests/test_webui_extension_surfaces.py该测试直接实例化LoadWebuiExtensions并借助get_webui_extension_manifest验证各扩展点表面的路径装配是扩展点契约的后端回归保障缓存清理验证由于扩展模块按扩展点缓存JS_CACHE_AREA新增/修改扩展文件后若未生效应确认clearCache()webui/js/extensions.js路径是否被触发。小结钩子、契约与边界json_api_call_before是 Agent Zero WebUI 中请求前干预的标准扩展点它在callJsonApi构造ctx之后、fetchApi发出 POST 之前执行通过共享的可变ctx允许扩展读取乃至修正endpoint与data。其全部规范浓缩为三条契约导出默认函数、保留 CSRF/auth 与 JSON payload 形态、避免宽泛修改配合 webui/js/extensions.js 的自动发现与缓存机制开发者只需放入一个导出默认函数的.js文件即可生效。遵循 DOX 文档的边界与验证要求就能在不破坏核心 API 调用链的前提下为 WebUI 注入稳定、可控的请求前逻辑。【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考