IronClaw Google Docs 扩展 format_text 操作全解析:从能力契约到 Google Docs API 的区间文本样式协议
2026/9/23 15:38:48 网站建设 项目流程

IronClaw Google Docs 扩展 format_text 操作全解析:从能力契约到 Google Docs API 的区间文本样式协议

【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw

导读

format_text是 IronClaw 开源仓库中 Google Docs 扩展(extension id:google-docs)提供的一项文本格式化能力,用于对文档中指定索引区间的文本批量应用加粗、斜体、下划线、删除线、字号、字体与前后景色等样式。本文以该操作的提示词文档(format_text.md)为核心骨架,结合其输入 Schema、WASM 工具实现与扩展清单(manifest),完整还原“能力调用 → 参数校验 → 样式构造 → Google Docs API 请求”的整条链路。读完本文,你将掌握该操作的完整参数语义、索引边界约定、底层updateTextStyle映射规则、宿主侧的安全边界,以及如何在自己的文档工作流中正确编排这一低层级操作。

一、操作契约:format_text 提示词文档说了什么

该扩展包的每个工具都配有一份极简的提示词文档(prompt doc),供模型在调用工具时理解操作语义。format_text.md全文只有两条核心约束:

  • 操作语义Format text in a range.——在某个区间内格式化文本。
  • 调用约束:宿主(host)通过能力 ID(capability id)选择该操作;调用方只需提供输入 Schema 描述的参数不得包含 action 字段

这两条约定在源码中都有强约束对应(详见下文第四节)。简言之,format_text是一个“区间定位 + 样式集合”的低层级文本样式工具:它不负责查找文本(那属于replace_text/apply_text_edits),只负责对给定的字符偏移区间施加样式。与之互补的是段落级样式操作format_paragraph(标题级别、对齐、行距),两者合起来构成 Docs 扩展的“文本样式 + 段落样式”能力面。

二、输入参数契约:从输入 Schema 看完整参数表

format_text的输入参数由 format_text.input.v1.json 精确定义,采用 JSON Schema draft-07。参数表如下:

参数类型必填说明
document_idstring文档 ID(与 Google Drive 文件 ID 相同)
start_indexinteger区间起始索引,(inclusive)
end_indexinteger区间结束索引,不含(exclusive)
boldboolean | null是否加粗
italicboolean | null是否斜体
underlineboolean | null是否下划线
strikethroughboolean | null是否删除线
font_sizenumber | null字号,单位是磅(points,PT)
font_familystring | null字体族名称
foreground_colorstring | null文字颜色,十六进制字符串(hex)
background_colorstring | null背景色,十六进制字符串(hex)

值得注意的 Schema 语义细节:

  1. 必填仅三项document_idstart_indexend_index。也就是说,一次调用可以只给区间而完全不指定任何样式属性。
  2. 所有样式属性都允许nulltype: ["boolean", "null"]等),用于表达“本次不修改该属性”;但结合实现看,若所有样式属性都为null/缺失,调用会直接失败(见第三节的错误码no_formatting_options)。
  3. additionalProperties: false:不接受 Schema 之外的多余字段,配合宿主侧参数注入,天然拒绝“野参数”。
  4. 索引语义为左闭右开[start_index, end_index),这是 Google Docs API 一贯的索引约定,与 Pythonslice一致。

三、源码实现:format_text 如何映射为 Google Docs API 请求

该扩展是纯数据包(data-only package),不包含 crate,工具半身以 WASM guest 形式随 wasm/google_docs_tool.wasm 发布,guest 源码位于 wasm-src。核心实现在 api.rs 的FormatTextOptionsformat_text函数中。

3.1 参数结构:FormatTextOptions

// crates/extensions/packages/google-docs/wasm-src/src/api.rs pub struct FormatTextOptions<'a> { pub document_id: &'a str, pub start_index: i64, pub end_index: i64, pub bold: Option<bool>, pub italic: Option<bool>, pub underline: Option<bool>, pub strikethrough: Option<bool>, pub font_size: Option<f64>, pub font_family: Option<&'a str>, pub foreground_color: Option<&'a str>, pub background_color: Option<&'a str>, }

所有样式属性都是Option,与 Schema 中允许null的设计一一对应。

3.2 样式构造与字段掩码(field mask)

format_text的核心逻辑是:只把显式提供的属性写进textStyle,并用字段掩码(fields)告诉 Docs API 本次要更新哪些字段。这是 Google DocsbatchUpdate的标准模式——未列入掩码的样式字段保持原样:

let mut style = serde_json::json!({}); let mut fields = Vec::new(); if let Some(b) = opts.bold { style["bold"] = serde_json::Value::Bool(b); fields.push("bold"); } // ... italic / underline / strikethrough 同理 ... if let Some(size) = opts.font_size { style["fontSize"] = serde_json::json!({ "magnitude": size, "unit": "PT" }); fields.push("fontSize"); } if let Some(family) = opts.font_family { style["weightedFontFamily"] = serde_json::json!({ "fontFamily": family }); fields.push("weightedFontFamily"); } // foregroundColor / backgroundColor 由 parse_hex_color 转换后加入

几个关键的底层映射规则(源码可查证):

  • font_sizefontSize:包装为{ "magnitude": <点数>, "unit": "PT" },即字号的单位固定为磅。
  • font_familyweightedFontFamily:包装为{ "fontFamily": <名称> }
  • 颜色 → RGB 浮点parse_hex_color先把字符串的#前缀剥掉,要求恰好 6 位十六进制字符,再按r/255、g/255、b/255转换为 Docs API 的rgbColor浮点结构;不符合格式(如#GG0000)时直接返回输入错误。
  • 最终请求:组装为updateTextStyle,携带range: { startIndex, endIndex }textStyle和逗号拼接的fields掩码,通过batch_update_raw提交给docs.googleapis.com

3.3 校验与错误码

实现中有两道显式校验,均返回input类失败并带稳定错误码:

场景错误码触发条件
颜色非法invalid_colorforeground_color/background_color不是合法 6 位 hex(如#GG0000
未指定任何样式no_formatting_options所有样式属性均为None/null

成功时返回UpdateResult,包含document_id与最新的revision_id,便于调用方感知文档版本变化。

四、宿主调度与安全边界:能力 ID、参数注入与凭证

4.1 能力 ID 驱动分发

format_text的能力 ID 是google-docs.format_text。在 lib.rs 中,action_from_context从调用上下文的capability_id解析出动作名:

match context.capability_id.as_str() { "google-docs.format_text" => Ok("format_text"), // ... 其余 14 个动作 ... _ => Err(input_failure("unsupported_google_docs_capability")), }

这正是提示词文档中“宿主从能力 ID 选择本操作”的代码落点:模型永远不需要、也不应该自己指定 action。

4.2 拒绝调用方自带的 action 字段

params_with_action会先检查参数中是否包含action键,若包含则直接拒绝:

if obj.contains_key("action") { return Err(input_failure("invalid_parameters")); } obj.insert("action".to_string(), serde_json::Value::String(action.to_string()));

随后由宿主从能力 ID 推导出的动作名注入到参数里,交给GoogleDocsAction反序列化。这一设计(对应提示词文档中的“不要包含 action 字段”)从根源上防止模型伪造或覆盖动作,对应的单元测试params_with_action_rejects_caller_supplied_action也验证了这一行为。

4.3 清单中的权限、效应与凭证

manifest.toml 对format_text工具的声明如下:

[[tools]] origin_gate_matrix = { loop_run = "gated_unless_granted", product = "forbidden", automation = "forbidden" } id = "google-docs.format_text" description = "Format text in a range." effects = ["network", "use_secret", "external_write"] default_permission = "ask" visibility = "model" input_schema_ref = "schemas/google-docs/format_text.input.v1.json" prompt_doc_ref = "prompts/google-docs/format_text.md" [[tools.credentials]] handle = "google_runtime_token" vendor = "google" scopes = ["https://www.googleapis.com/auth/documents"] audience = { scheme = "https", host = "docs.googleapis.com" } injection = { type = "header", name = "authorization", prefix = "Bearer " }

从中可以提炼出完整的安全与运行时信息:

  • 效应声明(effects)network(发起网络请求)、use_secret(使用凭证)、external_write(对外部系统产生写入)——external_write是写操作的重要标志。
  • 默认权限ask,即默认需要用户授权确认;visibility = "model"表示该工具对模型可见。
  • 来源门控(origin_gate_matrix):在loop_run场景默认gated_unless_granted(除非被授予否则门控),在productautomation场景直接forbidden,把高风险写入操作限制在受控的 agent loop 内。
  • 凭证注入:运行时由宿主把google_runtime_token(Google 产品认证账号令牌,scope 为documents写入权限)以Authorization: Bearer <token>请求头的形式注入到docs.googleapis.com域名的请求中,工具本身不接触明文凭证。
  • 认证链路:扩展级[auth.google]使用 OAuth 2.0 authorization code + PKCE(S256),scope 为documentsdocuments.readonly,客户端凭据由部署级管理配置(google_oauth_client_id/google_oauth_client_secret)统一提供。

4.4 Schema 与代码零漂移

lib.rs中的schema()schemars::schema_for!(types::GoogleDocsAction)自动生成,并在注释中明确说明“advertised schema can never drift from the serde contract”——对外公布的 Schema 与反序列化契约永远一致,避免了文档与实现脱节。这也是为什么本文第二节可以直接以format_text.input.v1.json为准展开。

五、索引约定与实战调用示例

5.1 索引语义(来自 lib.rs 文档注释与源码)

  • 索引是从 0 开始的字符偏移(0-based character offsets)。
  • 空文档的 body 在索引 0 处有一个换行符,因此在索引 1 处插入文本可以在文档开头前置内容
  • 使用-1表示在文档末尾追加。
  • 多次编辑时,从最高索引向最低索引处理,以避免索引漂移。
  • 正式工作中优先使用inspect_document获取段落/表格的真实索引,再调用format_text,避免手工猜测偏移。

5.2 可运行的调用示例

以下 JSON 是调用format_text的合法形态(动作名由宿主从能力 ID 注入,调用方只写 Schema 参数):

{ "document_id": "abc123", "start_index": 1, "end_index": 12, "bold": true, "font_size": 18 }

等价于对文档abc123[1, 12)区间文本设置加粗、18 磅字号;由于只传了这两个样式属性,其余样式字段通过 field mask 保持不变。组合其他属性:

{ "document_id": "abc123", "start_index": 5, "end_index": 20, "italic": true, "underline": true, "strikethrough": false, "font_family": "Arial", "foreground_color": "#FF0000", "background_color": "#FFFF00" }

反例(会被拒绝):

{ "action": "delete_all", "document_id": "doc-1" }

→ 因包含action字段返回invalid_parameters;若document_id/start_index/end_index缺失,则因不满足 Schema 的 required 约束而反序列化失败。

5.3 在文档工作流中的定位

扩展 README 建议:结构化编辑优先使用inspect_documentapply_text_edits/create_table_with_dataverify_document的语义化链路(通常只需 3~4 次模型可见调用,索引发现、批量写入、并发检查与回读都由扩展内部完成);而format_text这类低层级操作保留为兼容与逃生舱(escape-hatch)用途,适合对精确索引区间做样式微调。典型组合:inspect_document拿到段落索引 →format_text对标题区间加粗/改色 →get_documentverify_document确认结果。

六、测试与质量保障

该扩展的 WASM guest 内置单元测试,直接覆盖format_text的关键行为:

  • format_text_rejects_invalid_hex_colors(api.rs):对foreground_color: "#GG0000"返回invalid_color错误,message 为invalid foreground_color hex: #GG0000,验证了颜色校验路径。
  • params_with_action_rejects_caller_supplied_action:验证调用方传入action字段会被拒绝并返回invalid_parameters

此外,仓库还提供针对扩展包的回归检查:manifest 投影测试通过cargo test -p ironclaw_extension_registry执行;WASM 产物新鲜度由python3 scripts/ci/check-wasm-artifact-freshness.py校验,确保wasm/google_docs_tool.wasmwasm-src源码同步(详见 README.md)。

七、参考文件索引

  • 提示词文档:format_text.md
  • 输入 Schema:format_text.input.v1.json
  • 实现源码:api.rs 中 FormatTextOptions 与 format_text
  • 调度与 Schema 生成:lib.rs
  • 工具清单与凭证/权限声明:manifest.toml
  • 扩展包总览:google-docs/README.md

结语

format_text看似只是“格式化一段文字”,实则浓缩了 IronClaw 扩展体系的三层设计:契约层(提示词 + JSON Schema 定义参数与调用边界)、实现层(WASM guest 把参数翻译为带 field mask 的 Docs APIupdateTextStyle请求)、治理层(能力 ID 分发、action 注入防伪造、ask权限与external_write效应声明、OAuth 凭证头注入)。理解这一操作,也就理解了该仓库中其他 14 个 google-docs 操作(乃至整个google-*扩展家族)的通用工作方式:以最小化参数契约暴露能力,把鉴权、作用域与 API 细节封存在沙箱化的 WASM 工具内部。

【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询