更新时间:2026-06-17 GMT+08:00
分享

Hooks

Hooks(钩子)是码道CLI插件系统的核心机制,允许开发者在工具执行、消息处理、权限控制等关键节点注入自定义逻辑。插件通过返回一个Hooks对象来声明自己关注的生命周期事件,当对应事件触发时,插件的自定义函数将被调用。

插件及依赖文件存放路径

插件是一个JavaScript/TypeScript模块,通过导出插件函数来工作。每个函数接收一个上下文对象,并返回对应的Hook对象。如果插件文件中需要使用外部包,必须在配置目录中创建package.json文件并配置所需的依赖项。华为云码道在启动时会自动安装这些依赖项。

表1 插件文件加载路径

插件类型

插件文件存放路径

插件依赖文件存放路径

说明

项目级

当前项目根目录./.codeartsdoer/plugin或./.codeartsdoer/plugins

当前项目根目录./.codeartsdoer/

仅对当前项目有效。

个人级

本地%USERPROFILE%/.codeartsdoer/plugin或

%USERPROFILE%/.codeartsdoer/plugins

本地%USERPROFILE%/.codeartsdoer/

对当前用户下所有项目均有效。

支持的Hook事件

码道CLI支持的Hook事件请参考表2,各Hook事件示例详见文档Hook事件参考

表2 支持的Hook事件

事件分类

事件名称

触发时机

可阻断

典型使用场景

说明

聊天消息

chat.message

用户发送消息后、进入处理流程前

聊天消息处理

新消息到达时自动触发,支持对消息内容及Parts进行编辑

聊天参数

chat.params

每次调用LLM前

聊天参数修改

支持动态调整大模型推理参数,包含temperature、topP、topK等,按需优化模型输出结果

聊天请求头

chat.headers

每次调用LLM前

聊天请求头修改

支持自定义修改HTTP请求头字段,适配网络代理、接口鉴权等复杂场景需求

聊天响应

chat.response

LLM返回响应后

聊天响应记录

自动捕获模型响应的Tokens、Cost、Duration等核心指标,实现精准计费统计、高效故障排查与完整日志留存

聊天错误

chat.error

LLM调用发生错误时

聊天错误记录

记录LLM调用失败时的错误日志

聊天压缩

chat.compression

上下文压缩时

聊天压缩记录

记录上下文压缩前后的Token数量,辅助存储与性能调优

聊天结束

chat.finished

聊天会话结束时

聊天结束记录

记录会话结束事件,包含本次运行的Token消耗和运行信息

用户审批

user.approval

需要用户确认/审批操作时

用户审批记录

拦截高风险操作,发起人工确认审批,管控敏感操作执行权限

Turn结束

turn.end

每个对话轮次结束时

Turn结束记录

记录每轮对话结束日志,包含处理耗时、终止原因等关键信息

命令执行

command.execute.before

命令执行前

命令执行前置处理

支持对Parts进行自定义配置,实现命令的前置处理与灵活适配

工具执行

tool.execute.before

工具执行前

工具执行前置参数调整

支持在工具执行前自定义修改参数args,实现校验、动态改写与业务适配

tool.execute.after

工具执行后

工具执行后置结果处理

支持自定义修改返回结果,包括title、output及metadata字段

工具定义

tool.definition

工具定义发送给LLM前

工具定义修改

支持在工具推送模型前自定义配置描述与参数,确保精准适配业务场景

Shell环境

shell.env

获取Shell环境变量时

Shell环境变量配置管理

获取Shell环境变量时,支持添加或修改环境变量

权限请求

permission.ask

需要权限验证时

权限请求处理

处理权限校验请求,支持配置allow(允许)、deny(拒绝)、ask(询问)三种策略

消息转换

experimental.chat.messages.transform

消息列表发送给LLM前

消息转换

支持在模型上报前预处理聊天消息列表

系统消息转换

experimental.chat.system.transform

系统提示词发送前

系统消息转换

支持在系统提示词发送前优化指令内容

会话压缩

experimental.session.compacting

上下文压缩开始前

会话压缩

支持在执行上下文压缩前,自定义压缩提示词

文本补全

experimental.text.complete

文本补全完成时触发

文本补全结果定制

文本补全完成后,支持对输出内容进行修改

配置加载

config

应用启动配置加载时

配置加载

在加载自定义配置时触发,用于执行配置初始化及动态参数注入

通用事件

event

订阅所有Bus事件时触发

事件处理

通用事件处理

编写示例

本文以创建个人级别的Hook为例。

以下示例创建一个JsonFormatPlugin插件,在读取.json文件后,自动将挤成一行的压缩JSON,整理成2个空格缩进的格式化形式。

  1. 进入“~\.codeartsdoer\plugin”,创建并编写文件“JsonFormatPlugin.ts”。

    // 导入Plugin类型,用于定义插件
    import type { Plugin } from "@opencode-ai/plugin"
    // 导入文件系统模块,用于读写磁盘文件
    import { readFileSync, writeFileSync } from "fs"
    
    // 导出插件实现,Plugin是一个异步函数,接收插件输入参数并返回Hooks对象
    export const JsonFormatPlugin: Plugin = async ({}) => {
      return {
        // 监听工具执行后的钩子,在工具执行完成后触发
        "tool.execute.after": async (
          // 输入参数:包含工具名称、会话ID、调用ID、参数等信息
          input: { tool: string; sessionID: string; callID: string; args: any },
          // 输出参数:包含工具执行结果的标题、输出内容、元数据
          output: { title: string; output: string; metadata: any },
        ) => {
          if (input.tool !== "read") return
    
          // 获取文件路径,只处理.json文件
          const filePath = input.args?.filePath || input.args?.[0] || ""
          if (!filePath.endsWith(".json")) return
    
          try {
            const raw = readFileSync(filePath, "utf-8").trim()
            const parsed = JSON.parse(raw)
            const formatted = JSON.stringify(parsed, null, 2) + "\n"
            if (formatted === raw) return
    
            // 将格式化后的内容写回磁盘文件
            writeFileSync(filePath, formatted, "utf-8")
          } catch {}
        },
      }
    }

  2. 创建并编写测试文件“test-plugin.json”,内容为压缩格式的JSON。

    {"plugin":"JsonFormatPlugin","test":{"input":"压缩的单行JSON","output":"格式化的多行JSON"}}
    图1 格式化前

  3. 根据不同的开发模式,执行命令:

    • 如果是TUI开发模式,在TUI对话框中输入如下指令并回车:
      读取 test-plugin.json
    • 如果是CLI开发模式,请执行如下命令:
      codearts run "读取 test-plugin.json"
      图2 CLI开发模式的命令截图

  4. 执行完成后,“test-plugin.json”文件将被自动格式化为多行缩进形式。再次读取同一文件时,由于已是格式化状态,不会重复处理。

    如下图所示,该JSON文件已经被格式化。

    图3 格式化后的效果图

相关文档