diff --git a/api-reference/monitors.openapi.en.json b/api-reference/monitors.openapi.en.json index 8b5aaf9c..e58c3559 100644 --- a/api-reference/monitors.openapi.en.json +++ b/api-reference/monitors.openapi.en.json @@ -2711,7 +2711,7 @@ "Monitors/Diagnostics" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Use `target_locator` to identify the target; `target_kind` is optional and is auto-inferred when omitted. Built-in target kinds are `host` and `mysql`.\n- If multiple kinds match the same locator, the response is HTTP 200 with `data.error.code = \"ambiguous_target_kind\"` and a `target_kinds` list — retry with an explicit `target_kind`.\n- The catalog is a *candidate capability* view, not an execution guarantee. The target Agent may go offline between catalog and invoke, or local Agent policy may block individual tools at invoke time.\n- Set `include_output_shape: true` to additionally receive each tool's `output_shape`. Default is `false` to keep the response small for LLM consumption.\n- Business errors (`target_unavailable`, `unknown_toolset_hash`, `ambiguous_target_kind`) come back as HTTP 200 with `data.error` present and `data.tools = []`. Only protocol / auth / internal errors use the standard error envelope.\n- The response uses **sparse fields**: on success `error` is omitted rather than sent as `null`, and `target` is omitted when the locator could not be uniquely resolved. `tools` is always present.", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Use `target_locator` to identify the target; `target_kind` is optional and is inferred from current target routing when omitted.\n- If multiple kinds match the same locator, the response is HTTP 200 with `data.error.code = \"ambiguous_target_kind\"` and a `target_kinds` list — retry with an explicit `target_kind`.\n- The catalog is a candidate capability view, not an execution guarantee. The target Agent may go offline between catalog and invoke, or local Agent policy may block individual tools at invoke time.\n- Each tool entry exposes only `name`, `target_kind`, `description`, and `input_schema`. It does not expose tool versions, output contracts, catalog revisions, or execution limits.\n- Business errors (`target_unavailable`, `timeout`, `forward_failed`, `invalid_tool_result`, `ambiguous_target_kind`) return HTTP 200 with `data.error` present and `data.tools = []`. Only protocol, authentication, and internal errors use the standard error envelope.\n- The response uses **sparse fields**: on success `error` is omitted rather than sent as `null`, and `target` is omitted when the locator could not be uniquely resolved. `tools` is always present.", "href": "/en/api-reference/monitors/diagnostics/monit-read-tools-catalog", "metadata": { "sidebarTitle": "List target tool catalog" @@ -2726,8 +2726,7 @@ }, "example": { "account_id": 10001, - "target_locator": "web-01", - "include_output_shape": true + "target_locator": "web-01" } } } @@ -2768,144 +2767,6 @@ "type": "object", "additionalProperties": false, "properties": {} - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "cpu": { - "type": "object" - }, - "degradation_reasons": { - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - }, - "disk": { - "description": "Filesystems sorted by used_pct desc; rootfs always present; capped at host.disk.top_n. Sizes are in GB; used_pct/inode_used_pct in percent.", - "type": "array" - }, - "disk_errors": { - "description": "Mount points whose statfs returned a syscall error (EACCES / ENOENT / EIO / stale, etc.); each entry is `: `.", - "type": "array" - }, - "disk_io": { - "description": "Per-device disk I/O rates (util_pct, IOPS, throughput, await). Sorted by util_pct desc; capped at host.disk_io.top_n. Only whole-disk devices shown.", - "type": "object" - }, - "disk_timeouts": { - "description": "Mount points whose statfs hit per-mount timeout.", - "type": "array" - }, - "load": { - "type": "object" - }, - "memory": { - "description": "Memory and swap sizes are in MB; percentages are 0..100. Swap fields are always present when memory collection succeeds, including zero when swap is not configured.", - "properties": { - "available_mb": { - "type": "integer" - }, - "swap_configured": { - "description": "True when the kernel reports a non-zero SwapTotal.", - "type": "boolean" - }, - "swap_total_mb": { - "type": "integer" - }, - "swap_used_mb": { - "type": "integer" - }, - "swap_used_pct": { - "type": "number" - }, - "total_mb": { - "type": "integer" - }, - "used_mb": { - "type": "integer" - }, - "used_pct": { - "type": "number" - } - }, - "required": [ - "total_mb", - "available_mb", - "used_mb", - "used_pct", - "swap_configured", - "swap_total_mb", - "swap_used_mb", - "swap_used_pct" - ], - "type": "object" - }, - "network_io": { - "description": "Per-interface network throughput and error rates. Sorted by total traffic desc; capped at host.network_io.top_n. Virtual/container interfaces excluded by default.", - "type": "object" - }, - "procs": { - "type": "object" - }, - "sample_interval_sec": { - "description": "Shared sampling interval for CPU, disk_io, network_io counter-diff calculations.", - "type": "number" - }, - "tcp_connections": { - "description": "TCP connection state distribution via netlink SOCK_DIAG. Shows counts per state (established, time_wait, close_wait, listen, syn_recv, other, total).", - "type": "object" - }, - "uptime_sec": { - "type": "number" - }, - "vmstat": { - "description": "Sparse cumulative counters since the current boot; use them as historical clues, not current rates.", - "properties": { - "oom_kill_since_boot": { - "description": "OOM kills accumulated since boot; omitted when this kernel does not expose the counter.", - "type": "integer" - }, - "pgmajfault_since_boot": { - "description": "Major page faults accumulated since boot.", - "type": "integer" - } - }, - "required": [ - "pgmajfault_since_boot" - ], - "type": "object" - } - }, - "required": [ - "sample_interval_sec" - ], - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } }, { @@ -2927,65 +2788,6 @@ "type": "integer" } } - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "avg_ms": { - "type": "number" - }, - "max_ms": { - "type": "number" - }, - "min_ms": { - "type": "number" - }, - "probes": { - "items": { - "properties": { - "error": { - "type": "string" - }, - "latency_ms": { - "type": "number" - } - }, - "type": "object" - }, - "type": "array" - }, - "reachable": { - "type": "boolean" - }, - "resolved_ip": { - "type": "string" - } - }, - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } } ] @@ -3018,7 +2820,7 @@ "Monitors/Diagnostics" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Up to **8** tools per call (`MaxToolsPerInvoke`); larger batches must be split client-side. The 8-tool cap aligns with the per-target agent concurrency.\n- Tools execute in parallel on the agent; webapi returns `results[]` aligned with the request `tools[]` order.\n- Long-running: set client timeouts to **at least 35 s**. The endpoint is intended for AI-SRE / human-RCA flows, not interactive UI.\n- Request-level errors (`target_unavailable`, `ambiguous_target_kind`, `unknown_toolset_hash`, `forward_failed`) appear as HTTP 200 with `data.error` set and `data.results = []`.\n- Per-tool failures appear as HTTP 200 with `data.error` absent and `results[i].error` populated — always check **all three** layers (outer envelope `error`, `data.error`, then each `results[i].error`).\n- The response uses **sparse fields**: absent means empty. On success `error` is omitted entirely rather than sent as `null`; on failure `data`, `summary` and `truncated` are omitted. Do not key logic off placeholder `null` fields, and do not expect `target` when the locator could not be uniquely resolved.\n- `results[i].data` is the tool payload with the monit-agent result envelope **already unwrapped** — there is no nested `data.data`. The one-line distillation is `results[i].summary`, and `results[i].truncated` (carrying a `reason`) appears only when the result was genuinely truncated.\n- `results[i].params` echoes the params webapi received for that tool, so batched calls stay correlatable even when an individual tool fails.\n- Construct `tools[].params` against the `input_schema` returned by `/monit/tools/catalog`. For no-arg tools always pass `params: {}` explicitly.", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Up to **8** tools per call (`MaxToolsPerInvoke`); larger batches must be split client-side. The 8-tool cap aligns with the per-target agent concurrency.\n- Tools execute in parallel on the agent; webapi returns `results[]` aligned with the request `tools[]` order.\n- Long-running: set client timeouts to **at least 35 s**. The endpoint is intended for AI-SRE / human-RCA flows, not interactive UI.\n- Request-level errors (`target_unavailable`, `ambiguous_target_kind`, `forward_failed`) appear as HTTP 200 with `data.error` set and `data.results = []`.\n- Per-tool failures appear as HTTP 200 with `data.error` absent and `results[i].error` populated — always check **all three** layers (outer envelope `error`, `data.error`, then each `results[i].error`).\n- The response uses **sparse fields**: absent means empty. On success `error` is omitted entirely rather than sent as `null`; on failure `data`, `summary` and `truncated` are omitted. Do not key logic off placeholder `null` fields, and do not expect `target` when the locator could not be uniquely resolved.\n- `results[i].data` is the tool payload with the monit-agent result envelope **already unwrapped** — there is no nested `data.data`. The one-line distillation is `results[i].summary`, and `results[i].truncated` (carrying a `reason`) appears only when the result was genuinely truncated.\n- `results[i].params` echoes the params webapi received for that tool, so batched calls stay correlatable even when an individual tool fails.\n- Construct `tools[].params` against the `input_schema` returned by `/monit/tools/catalog`. For no-arg tools always pass `params: {}` explicitly.", "href": "/en/api-reference/monitors/diagnostics/monit-read-tools-invoke", "metadata": { "sidebarTitle": "Invoke target tools" @@ -3508,7 +3310,22 @@ }, "enabled_times": { "type": "array", - "description": "Time windows when the rule is active.", + "description": "Time windows when the rule is active. Defaults to all days from 00:00 to 23:59 when omitted or empty.", + "default": [ + { + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 0 + ], + "stime": "00:00", + "etime": "23:59" + } + ], "items": { "type": "object", "properties": { @@ -3541,7 +3358,9 @@ "enum": [ "text", "markdown" - ] + ], + "default": "text", + "description": "Format for the description. Defaults to `text` when omitted or empty." }, "description": { "type": "string" @@ -5559,12 +5378,7 @@ }, "target_kind": { "type": "string", - "description": "Optional target kind. When omitted webapi auto-infers across currently known kinds. Built-in kinds: `host`, `mysql`. Required on retry when the previous call returned `ambiguous_target_kind`." - }, - "include_output_shape": { - "type": "boolean", - "description": "When true, each tool entry includes its `output_shape` JSON Schema. Defaults to false to keep responses small for LLM consumption.", - "default": false + "description": "Optional target kind. When omitted, webapi infers it from current target routing. If the call returns `ambiguous_target_kind`, retry with a value from `target_kinds`." } } }, @@ -5605,11 +5419,6 @@ "input_schema": { "type": "object", "description": "JSON Schema for `tools[].params`." - }, - "output_shape": { - "type": "object", - "description": "JSON Schema of the tool result. Returned only when the request set `include_output_shape` to true.", - "x-flashduty-preserve-absence": true } } } @@ -5622,7 +5431,9 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", + "timeout", + "forward_failed", + "invalid_tool_result", "ambiguous_target_kind" ] }, @@ -5749,7 +5560,7 @@ "properties": { "code": { "type": "string", - "description": "Common values: `timeout`, `target_unavailable`, `edge_unsupported`, `invalid_tool_result`, `internal`, `invalid_args`, `unknown_tool`, `unknown_tool_version`, `unknown_toolset_hash`, `target_not_owned`, `wrong_agent`, `overloaded`, `denied`, `permission_denied`, `credential_unavailable`, `target_unreachable`." + "description": "Common WebAPI codes: `timeout`, `target_unavailable`, `invalid_tool_result`, `internal`, `invalid_args`, `unsupported_syntax`, `path_not_found`, and `catalog_changed`. Agent-specific tool errors may also be returned unchanged." }, "message": { "type": "string" @@ -5768,7 +5579,6 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", "forward_failed", "ambiguous_target_kind" ] diff --git a/api-reference/monitors.openapi.zh.json b/api-reference/monitors.openapi.zh.json index 592bc0bf..552c92bc 100644 --- a/api-reference/monitors.openapi.zh.json +++ b/api-reference/monitors.openapi.zh.json @@ -2711,7 +2711,7 @@ "Monitors/诊断分析" ], "x-mint": { - "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 使用 `target_locator` 标识监控对象;`target_kind` 可选,省略时自动推断。内置的 target kind 包括 `host` 与 `mysql`。\n- 若同一 locator 匹配多个 kind,响应为 HTTP 200,`data.error.code = \"ambiguous_target_kind\"`,并附带 `target_kinds` 列表——请带上显式的 `target_kind` 重试。\n- 工具能力清单是*候选能力*视图,并非执行保证。目标 Agent 可能在拿到清单与发起调用之间下线,本地 Agent 策略也可能在调用时拦截某些工具。\n- 设置 `include_output_shape: true` 可额外返回每个工具的 `output_shape`。默认为 `false`,以便为 LLM 消费保持响应精简。\n- 业务错误(`target_unavailable`、`unknown_toolset_hash`、`ambiguous_target_kind`)以 HTTP 200 返回,`data.error` 存在且 `data.tools = []`。只有协议 / 鉴权 / 内部错误才使用标准错误信封。\n- 响应采用**稀疏字段**:成功时 `error` 直接省略而非返回 `null`;当 locator 无法唯一解析时 `target` 不输出。`tools` 字段恒存在。", + "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 使用 `target_locator` 标识监控对象;`target_kind` 可选,省略时按当前监控对象路由自动推断。\n- 若同一 locator 匹配多个 kind,响应为 HTTP 200,`data.error.code = \"ambiguous_target_kind\"`,并附带 `target_kinds` 列表——请带上显式的 `target_kind` 重试。\n- 工具能力清单是候选能力视图,并非执行保证。目标 Agent 可能在拿到清单与发起调用之间下线,本地 Agent 策略也可能在调用时拦截某些工具。\n- 每个工具条目只返回 `name`、`target_kind`、`description` 和 `input_schema`,不会暴露工具版本、输出契约、目录版本或执行限制。\n- 业务错误(`target_unavailable`、`timeout`、`forward_failed`、`invalid_tool_result`、`ambiguous_target_kind`)以 HTTP 200 返回,`data.error` 存在且 `data.tools = []`。只有协议、鉴权和内部错误才使用标准错误信封。\n- 响应采用**稀疏字段**:成功时 `error` 直接省略而非返回 `null`;当 locator 无法唯一解析时,`target` 不输出。`tools` 字段恒存在。", "href": "/zh/api-reference/monitors/diagnostics/monit-read-tools-catalog", "metadata": { "sidebarTitle": "查询监控对象工具能力清单" @@ -2726,8 +2726,7 @@ }, "example": { "account_id": 10001, - "target_locator": "web-01", - "include_output_shape": true + "target_locator": "web-01" } } } @@ -2768,144 +2767,6 @@ "type": "object", "additionalProperties": false, "properties": {} - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "cpu": { - "type": "object" - }, - "degradation_reasons": { - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - }, - "disk": { - "description": "Filesystems sorted by used_pct desc; rootfs always present; capped at host.disk.top_n. Sizes are in GB; used_pct/inode_used_pct in percent.", - "type": "array" - }, - "disk_errors": { - "description": "Mount points whose statfs returned a syscall error (EACCES / ENOENT / EIO / stale, etc.); each entry is `: `.", - "type": "array" - }, - "disk_io": { - "description": "Per-device disk I/O rates (util_pct, IOPS, throughput, await). Sorted by util_pct desc; capped at host.disk_io.top_n. Only whole-disk devices shown.", - "type": "object" - }, - "disk_timeouts": { - "description": "Mount points whose statfs hit per-mount timeout.", - "type": "array" - }, - "load": { - "type": "object" - }, - "memory": { - "description": "Memory and swap sizes are in MB; percentages are 0..100. Swap fields are always present when memory collection succeeds, including zero when swap is not configured.", - "properties": { - "available_mb": { - "type": "integer" - }, - "swap_configured": { - "description": "True when the kernel reports a non-zero SwapTotal.", - "type": "boolean" - }, - "swap_total_mb": { - "type": "integer" - }, - "swap_used_mb": { - "type": "integer" - }, - "swap_used_pct": { - "type": "number" - }, - "total_mb": { - "type": "integer" - }, - "used_mb": { - "type": "integer" - }, - "used_pct": { - "type": "number" - } - }, - "required": [ - "total_mb", - "available_mb", - "used_mb", - "used_pct", - "swap_configured", - "swap_total_mb", - "swap_used_mb", - "swap_used_pct" - ], - "type": "object" - }, - "network_io": { - "description": "Per-interface network throughput and error rates. Sorted by total traffic desc; capped at host.network_io.top_n. Virtual/container interfaces excluded by default.", - "type": "object" - }, - "procs": { - "type": "object" - }, - "sample_interval_sec": { - "description": "Shared sampling interval for CPU, disk_io, network_io counter-diff calculations.", - "type": "number" - }, - "tcp_connections": { - "description": "TCP connection state distribution via netlink SOCK_DIAG. Shows counts per state (established, time_wait, close_wait, listen, syn_recv, other, total).", - "type": "object" - }, - "uptime_sec": { - "type": "number" - }, - "vmstat": { - "description": "Sparse cumulative counters since the current boot; use them as historical clues, not current rates.", - "properties": { - "oom_kill_since_boot": { - "description": "OOM kills accumulated since boot; omitted when this kernel does not expose the counter.", - "type": "integer" - }, - "pgmajfault_since_boot": { - "description": "Major page faults accumulated since boot.", - "type": "integer" - } - }, - "required": [ - "pgmajfault_since_boot" - ], - "type": "object" - } - }, - "required": [ - "sample_interval_sec" - ], - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } }, { @@ -2927,65 +2788,6 @@ "type": "integer" } } - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "avg_ms": { - "type": "number" - }, - "max_ms": { - "type": "number" - }, - "min_ms": { - "type": "number" - }, - "probes": { - "items": { - "properties": { - "error": { - "type": "string" - }, - "latency_ms": { - "type": "number" - } - }, - "type": "object" - }, - "type": "array" - }, - "reachable": { - "type": "boolean" - }, - "resolved_ip": { - "type": "string" - } - }, - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } } ] @@ -3018,7 +2820,7 @@ "Monitors/诊断分析" ], "x-mint": { - "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 单次调用至多 **8** 个工具(`MaxToolsPerInvoke`);超出需在客户端拆分。8 个工具的上限与单监控对象 Agent 的并发能力对齐。\n- 工具在 Agent 上并行执行;webapi 返回的 `results[]` 与请求中的 `tools[]` 顺序对齐。\n- 长耗时:客户端超时至少设置 **35 秒**。该接口面向 AI-SRE / 人工排障流程,不适用于交互式 UI。\n- 请求级错误(`target_unavailable`、`ambiguous_target_kind`、`unknown_toolset_hash`、`forward_failed`)以 HTTP 200 返回,`data.error` 不为空,`data.results = []`。\n- 单工具失败以 HTTP 200 返回,`data.error` 不输出,`results[i].error` 被填充——务必同时检查**三层**(外层信封 `error`、`data.error`、再到每个 `results[i].error`)。\n- 响应采用**稀疏字段**:字段不存在即表示为空。成功时 `error` 直接省略而非返回 `null`;失败时 `data`、`summary`、`truncated` 均不输出。不要依赖占位的 `null` 字段做判断;当 locator 无法唯一解析时,`target` 同样不会出现。\n- `results[i].data` 是 Tool 的业务数据,monit-agent 的 result envelope **已被解开**——不会出现嵌套的 `data.data`。一行摘要位于 `results[i].summary`;`results[i].truncated`(内含 `reason`)仅在结果确实被截断时出现。\n- `results[i].params` 回显 webapi 收到的该 Tool 调用参数,便于在批量调用中关联结果——即使其中某个 Tool 失败也能对上号。\n- 按 `/monit/tools/catalog` 返回的 `input_schema` 构造 `tools[].params`。对于无参工具,务必显式传 `params: {}`。", + "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 单次调用至多 **8** 个工具(`MaxToolsPerInvoke`);超出需在客户端拆分。8 个工具的上限与单监控对象 Agent 的并发能力对齐。\n- 工具在 Agent 上并行执行;webapi 返回的 `results[]` 与请求中的 `tools[]` 顺序对齐。\n- 长耗时:客户端超时至少设置 **35 秒**。该接口面向 AI-SRE / 人工排障流程,不适用于交互式 UI。\n- 请求级错误(`target_unavailable`、`ambiguous_target_kind`、`forward_failed`)以 HTTP 200 返回,`data.error` 不为空,`data.results = []`。\n- 单工具失败以 HTTP 200 返回,`data.error` 不输出,`results[i].error` 被填充——务必同时检查**三层**(外层信封 `error`、`data.error`、再到每个 `results[i].error`)。\n- 响应采用**稀疏字段**:字段不存在即表示为空。成功时 `error` 直接省略而非返回 `null`;失败时 `data`、`summary`、`truncated` 均不输出。不要依赖占位的 `null` 字段做判断;当 locator 无法唯一解析时,`target` 同样不会出现。\n- `results[i].data` 是 Tool 的业务数据,monit-agent 的 result envelope **已被解开**——不会出现嵌套的 `data.data`。一行摘要位于 `results[i].summary`;`results[i].truncated`(内含 `reason`)仅在结果确实被截断时出现。\n- `results[i].params` 回显 webapi 收到的该 Tool 调用参数,便于在批量调用中关联结果——即使其中某个 Tool 失败也能对上号。\n- 按 `/monit/tools/catalog` 返回的 `input_schema` 构造 `tools[].params`。对于无参工具,务必显式传 `params: {}`。", "href": "/zh/api-reference/monitors/diagnostics/monit-read-tools-invoke", "metadata": { "sidebarTitle": "调用监控对象工具" @@ -3508,7 +3310,22 @@ }, "enabled_times": { "type": "array", - "description": "规则生效的时间窗口。", + "description": "规则生效的时间窗口。省略或传空数组时,默认每天 00:00–23:59 生效。", + "default": [ + { + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 0 + ], + "stime": "00:00", + "etime": "23:59" + } + ], "items": { "type": "object", "properties": { @@ -3541,7 +3358,9 @@ "enum": [ "text", "markdown" - ] + ], + "default": "text", + "description": "描述内容的格式。省略或为空时默认使用 `text`。" }, "description": { "type": "string" @@ -5559,12 +5378,7 @@ }, "target_kind": { "type": "string", - "description": "可选的 target kind。省略时 webapi 在当前已知的 kind 中自动推断。内置 kind:`host`、`mysql`。上次返回 `ambiguous_target_kind` 时,重试必须传入此字段。" - }, - "include_output_shape": { - "type": "boolean", - "description": "为 true 时,每个工具条目额外返回其 `output_shape` JSON Schema。默认 false,以便为 LLM 消费保持响应精简。", - "default": false + "description": "可选的 target kind。省略时 webapi 会按当前监控对象路由自动推断。若返回 `ambiguous_target_kind`,请从 `target_kinds` 中选择一个值重试。" } } }, @@ -5605,11 +5419,6 @@ "input_schema": { "type": "object", "description": "用于 `tools[].params` 的 JSON Schema。" - }, - "output_shape": { - "type": "object", - "description": "Tool 结果的 JSON Schema。仅当请求将 `include_output_shape` 置为 true 时返回。", - "x-flashduty-preserve-absence": true } } } @@ -5622,7 +5431,9 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", + "timeout", + "forward_failed", + "invalid_tool_result", "ambiguous_target_kind" ] }, @@ -5749,7 +5560,7 @@ "properties": { "code": { "type": "string", - "description": "常见取值:`timeout`、`target_unavailable`、`edge_unsupported`、`invalid_tool_result`、`internal`、`invalid_args`、`unknown_tool`、`unknown_tool_version`、`unknown_toolset_hash`、`target_not_owned`、`wrong_agent`、`overloaded`、`denied`、`permission_denied`、`credential_unavailable`、`target_unreachable`。" + "description": "常见 WebAPI 错误码:`timeout`、`target_unavailable`、`invalid_tool_result`、`internal`、`invalid_args`、`unsupported_syntax`、`path_not_found` 和 `catalog_changed`。Agent 特有的工具错误也可能原样返回。" }, "message": { "type": "string" @@ -5768,7 +5579,6 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", "forward_failed", "ambiguous_target_kind" ] diff --git a/api-reference/on-call.openapi.en.json b/api-reference/on-call.openapi.en.json index a86c6ded..23311607 100644 --- a/api-reference/on-call.openapi.en.json +++ b/api-reference/on-call.openapi.en.json @@ -8075,6 +8075,99 @@ } } }, + "/incident/sdp/request/list": { + "post": { + "operationId": "incident-service-desk-plus-request-read-list", + "summary": "Get ServiceDeskPlus linked incidents", + "description": "List synchronization mappings between ServiceDeskPlus requests and Flashduty incidents.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Read** (`on-call`) |\n\n## Usage\n\n- Use this endpoint to inspect synchronization mappings between ServiceDeskPlus requests and Flashduty incidents, including the external request link and sync status.\n- When `incident_id` is not provided, `start_time` and `end_time` are required Unix-second timestamps; the time window cannot exceed 30 days.\n- `status` accepts only `success` and `failed`, representing successful and failed synchronization records.\n- Results are sorted by the internal record ID. Set `asc` to `true` for ascending order; otherwise records are returned descending. Pass the returned `search_after_ctx` to continue pagination.", + "href": "/en/api-reference/on-call/incidents/incident-service-desk-plus-request-read-list", + "metadata": { + "sidebarTitle": "Get ServiceDeskPlus linked incidents" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "items": [ + { + "created_at": 1779514631, + "status": "success", + "request_id": "100000000001", + "request_link": "https://servicedesk.example.com/app/itdesk/ui/requests/100000000001/details", + "integration_id": 98765, + "incident_id": "685d7f4e51b9a9a6d4d0c123", + "incident_title": "Checkout API 5xx rate increased", + "channel_id": 12345, + "channel_name": "Payments" + } + ], + "total": 1, + "has_next_page": false, + "search_after_ctx": "" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListRequest" + }, + "example": { + "start_time": 1779513600, + "end_time": 1779600000, + "status": "success", + "channel_ids": [ + 12345 + ], + "limit": 20 + } + } + } + } + } + }, "/insight/alert/topk-by-label": { "post": { "operationId": "insightTopkAlertsByLabel", @@ -11903,12 +11996,12 @@ "get": { "operationId": "statusPageChangeList", "summary": "List status page events", - "description": "List events (incidents and maintenances) for a status page.", + "description": "List status page events with only publicly visible affected components.", "tags": [ "On-call/Status pages" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Hidden affected components are omitted. Events remain in the result when none are visible, with an empty `affected_components` array.", "href": "/en/api-reference/on-call/status-pages/status-page-change-list", "metadata": { "sidebarTitle": "List status page events" @@ -26208,6 +26301,11 @@ "type": "string", "description": "Feishu app message template source." }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "default": false, + "description": "Render alert labels as a table in Feishu app cards." + }, "dingtalk_app": { "type": "string", "description": "DingTalk app message template source." @@ -26288,6 +26386,7 @@ "wecom", "feishu", "feishu_app", + "feishu_app_card_table_enabled", "dingtalk_app", "wecom_app", "slack_app", @@ -26354,6 +26453,10 @@ "type": "string", "description": "Feishu app message template source." }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "description": "Whether alert labels use table rendering in Feishu app cards." + }, "dingtalk_app": { "type": "string", "description": "DingTalk app message template source." @@ -26564,6 +26667,13 @@ "type": "string", "description": "Feishu app message template source." }, + "feishu_app_card_table_enabled": { + "type": [ + "boolean", + "null" + ], + "description": "When set, enable or disable table rendering for alert labels in Feishu app cards. Omit to keep the existing setting." + }, "dingtalk_app": { "type": "string", "description": "DingTalk app message template source." @@ -29351,6 +29461,173 @@ } } } + }, + "ServiceDeskPlusRequestListRequest": { + "type": "object", + "description": "Filters for listing ServiceDeskPlus request synchronization records. A time window is optional when querying by incident ID; otherwise provide a Unix-second window no longer than 30 days.", + "properties": { + "start_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Window start, Unix seconds. Optional when `incident_id` is provided." + }, + "end_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Window end, Unix seconds. Must be greater than or equal to `start_time`. Optional when `incident_id` is provided." + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Synchronization status filter." + }, + "channel_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Channel IDs to filter by." + }, + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "ServiceDeskPlus integration ID." + }, + "incident_id": { + "type": "string", + "maxLength": 64, + "description": "Flashduty incident ID. When set, the time window can be omitted." + }, + "request_id": { + "type": "string", + "maxLength": 64, + "description": "ServiceDeskPlus request ID." + }, + "asc": { + "type": "boolean", + "description": "When `true`, sort by internal record ID ascending; otherwise descending." + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Page number starting at 1. Ignored when `search_after_ctx` is set." + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "Page size. Defaults to 20; maximum 100." + }, + "search_after_ctx": { + "type": "string", + "description": "Cursor returned by the previous page." + } + } + }, + "ServiceDeskPlusRequestMappingItem": { + "type": "object", + "description": "A synchronization mapping between a ServiceDeskPlus request and a Flashduty incident.", + "required": [ + "created_at", + "status", + "request_id", + "request_link", + "integration_id", + "incident_id", + "incident_title", + "channel_id", + "channel_name" + ], + "properties": { + "created_at": { + "type": "integer", + "format": "int64", + "description": "Mapping record creation time, Unix seconds." + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Synchronization status." + }, + "request_id": { + "type": "string", + "description": "ServiceDeskPlus request ID." + }, + "request_link": { + "type": "string", + "description": "ServiceDeskPlus request detail URL." + }, + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ServiceDeskPlus integration ID." + }, + "incident_id": { + "type": "string", + "description": "Associated Flashduty incident ID." + }, + "incident_title": { + "type": "string", + "description": "Associated incident title." + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "Channel ID for the incident." + }, + "channel_name": { + "type": "string", + "description": "Channel name for the incident." + }, + "error_message": { + "type": "string", + "description": "Error message when synchronization failed. Usually absent on successful records." + } + } + }, + "ServiceDeskPlusRequestListResponse": { + "type": "object", + "description": "Paginated list of ServiceDeskPlus request synchronization records.", + "required": [ + "items", + "total", + "has_next_page" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" + }, + "description": "Synchronization records on the current page." + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching records, capped at 1,000 for counting." + }, + "has_next_page": { + "type": "boolean", + "description": "True when more results are available." + }, + "search_after_ctx": { + "type": "string", + "description": "Cursor for the next page. Empty when no more data is available." + } + } } } } diff --git a/api-reference/on-call.openapi.zh.json b/api-reference/on-call.openapi.zh.json index 35acfa54..19d75bcc 100644 --- a/api-reference/on-call.openapi.zh.json +++ b/api-reference/on-call.openapi.zh.json @@ -8067,6 +8067,99 @@ } } }, + "/incident/sdp/request/list": { + "post": { + "operationId": "incident-service-desk-plus-request-read-list", + "summary": "获取 ServiceDeskPlus 关联故障", + "description": "分页查询 ServiceDeskPlus 请求与 Flashduty 故障的同步映射记录。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障查看**(`on-call`) |\n\n## 使用说明\n\n- 查询 ServiceDeskPlus 请求与 Flashduty 故障之间的同步映射记录,用于排查 ITSM 同步状态或定位外部请求链接。\n- 不按 `incident_id` 查询时,`start_time` 和 `end_time` 必填,均为 Unix 秒时间戳;时间范围不能超过 30 天。\n- `status` 仅支持 `success` 和 `failed`,分别表示同步成功和同步失败。\n- 响应按内部记录 ID 排序;`asc` 为 `true` 时升序,否则降序。继续翻页时传入上次响应的 `search_after_ctx`。", + "href": "/zh/api-reference/on-call/incidents/incident-service-desk-plus-request-read-list", + "metadata": { + "sidebarTitle": "获取 ServiceDeskPlus 关联故障" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "items": [ + { + "created_at": 1779514631, + "status": "success", + "request_id": "100000000001", + "request_link": "https://servicedesk.example.com/app/itdesk/ui/requests/100000000001/details", + "integration_id": 98765, + "incident_id": "685d7f4e51b9a9a6d4d0c123", + "incident_title": "Checkout API 5xx rate increased", + "channel_id": 12345, + "channel_name": "Payments" + } + ], + "total": 1, + "has_next_page": false, + "search_after_ctx": "" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListRequest" + }, + "example": { + "start_time": 1779513600, + "end_time": 1779600000, + "status": "success", + "channel_ids": [ + 12345 + ], + "limit": 20 + } + } + } + } + } + }, "/insight/alert/topk-by-label": { "post": { "operationId": "insightTopkAlertsByLabel", @@ -11895,12 +11988,12 @@ "get": { "operationId": "statusPageChangeList", "summary": "查询状态页事件列表", - "description": "查询状态页的事件列表(故障和维护)。", + "description": "查询状态页事件列表;响应仅包含对外可见的受影响组件。", "tags": [ "On-call/状态页" ], "x-mint": { - "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 无 —— 持有有效的 `app_key` 即可调用 |", + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 无 —— 持有有效的 `app_key` 即可调用 |\n\n## 使用说明\n\n- 响应会过滤隐藏的受影响组件。若事件没有任何可见组件,事件仍会保留,但 `affected_components` 为空数组。", "href": "/zh/api-reference/on-call/status-pages/status-page-change-list", "metadata": { "sidebarTitle": "查询状态页事件列表" @@ -26199,6 +26292,11 @@ "type": "string", "description": "飞书应用消息模板源。" }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "default": false, + "description": "是否在飞书应用卡片中以表格渲染告警标签,默认关闭。" + }, "dingtalk_app": { "type": "string", "description": "钉钉应用消息模板源。" @@ -26279,6 +26377,7 @@ "wecom", "feishu", "feishu_app", + "feishu_app_card_table_enabled", "dingtalk_app", "wecom_app", "slack_app", @@ -26345,6 +26444,10 @@ "type": "string", "description": "飞书应用消息模板源。" }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "description": "是否在飞书应用卡片中以表格渲染告警标签。" + }, "dingtalk_app": { "type": "string", "description": "钉钉应用消息模板源。" @@ -26555,6 +26658,13 @@ "type": "string", "description": "飞书应用消息模板源。" }, + "feishu_app_card_table_enabled": { + "type": [ + "boolean", + "null" + ], + "description": "设置后开启或关闭飞书应用卡片中的告警标签表格渲染;省略时保持当前设置。" + }, "dingtalk_app": { "type": "string", "description": "钉钉应用消息模板源。" @@ -29342,6 +29452,173 @@ } } } + }, + "ServiceDeskPlusRequestListRequest": { + "type": "object", + "description": "查询 ServiceDeskPlus 请求同步记录的过滤条件。按故障 ID 查询时可不传时间窗口;否则必须传入不超过 30 天的 Unix 秒时间窗口。", + "properties": { + "start_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "时间窗口起点(Unix 秒)。按 `incident_id` 查询时可省略。" + }, + "end_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "时间窗口终点(Unix 秒),必须大于等于 `start_time`。按 `incident_id` 查询时可省略。" + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "同步状态过滤。" + }, + "channel_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "协作空间 ID 列表。" + }, + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "ServiceDeskPlus 集成 ID。" + }, + "incident_id": { + "type": "string", + "maxLength": 64, + "description": "Flashduty 故障 ID。提供后可不传时间窗口。" + }, + "request_id": { + "type": "string", + "maxLength": 64, + "description": "ServiceDeskPlus 请求 ID。" + }, + "asc": { + "type": "boolean", + "description": "为 `true` 时按内部记录 ID 升序返回;否则降序。" + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "页码,从 1 开始。使用 `search_after_ctx` 时忽略。" + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "分页大小,默认 20,最大 100。" + }, + "search_after_ctx": { + "type": "string", + "description": "上一页返回的翻页游标。" + } + } + }, + "ServiceDeskPlusRequestMappingItem": { + "type": "object", + "description": "ServiceDeskPlus 请求与 Flashduty 故障之间的一条同步映射记录。", + "required": [ + "created_at", + "status", + "request_id", + "request_link", + "integration_id", + "incident_id", + "incident_title", + "channel_id", + "channel_name" + ], + "properties": { + "created_at": { + "type": "integer", + "format": "int64", + "description": "映射记录创建时间(Unix 秒)。" + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "同步状态。" + }, + "request_id": { + "type": "string", + "description": "ServiceDeskPlus 请求 ID。" + }, + "request_link": { + "type": "string", + "description": "ServiceDeskPlus 请求详情链接。" + }, + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ServiceDeskPlus 集成 ID。" + }, + "incident_id": { + "type": "string", + "description": "关联的 Flashduty 故障 ID。" + }, + "incident_title": { + "type": "string", + "description": "关联故障标题。" + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "故障所属协作空间 ID。" + }, + "channel_name": { + "type": "string", + "description": "故障所属协作空间名称。" + }, + "error_message": { + "type": "string", + "description": "同步失败时的错误信息。成功记录通常不返回该字段。" + } + } + }, + "ServiceDeskPlusRequestListResponse": { + "type": "object", + "description": "分页的 ServiceDeskPlus 请求同步记录列表。", + "required": [ + "items", + "total", + "has_next_page" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" + }, + "description": "当前页同步记录。" + }, + "total": { + "type": "integer", + "format": "int64", + "description": "匹配记录总数,最多统计 1000 条。" + }, + "has_next_page": { + "type": "boolean", + "description": "是否还有更多页。" + }, + "search_after_ctx": { + "type": "string", + "description": "下一页翻页游标。无更多数据时为空。" + } + } } } } diff --git a/api-reference/openapi.en.json b/api-reference/openapi.en.json index bf4362ca..20663d35 100644 --- a/api-reference/openapi.en.json +++ b/api-reference/openapi.en.json @@ -316,6 +316,99 @@ } } }, + "/incident/sdp/request/list": { + "post": { + "operationId": "incident-service-desk-plus-request-read-list", + "summary": "Get ServiceDeskPlus linked incidents", + "description": "List synchronization mappings between ServiceDeskPlus requests and Flashduty incidents.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Read** (`on-call`) |\n\n## Usage\n\n- Use this endpoint to inspect synchronization mappings between ServiceDeskPlus requests and Flashduty incidents, including the external request link and sync status.\n- When `incident_id` is not provided, `start_time` and `end_time` are required Unix-second timestamps; the time window cannot exceed 30 days.\n- `status` accepts only `success` and `failed`, representing successful and failed synchronization records.\n- Results are sorted by the internal record ID. Set `asc` to `true` for ascending order; otherwise records are returned descending. Pass the returned `search_after_ctx` to continue pagination.", + "href": "/en/api-reference/on-call/incidents/incident-service-desk-plus-request-read-list", + "metadata": { + "sidebarTitle": "Get ServiceDeskPlus linked incidents" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "items": [ + { + "created_at": 1779514631, + "status": "success", + "request_id": "100000000001", + "request_link": "https://servicedesk.example.com/app/itdesk/ui/requests/100000000001/details", + "integration_id": 98765, + "incident_id": "685d7f4e51b9a9a6d4d0c123", + "incident_title": "Checkout API 5xx rate increased", + "channel_id": 12345, + "channel_name": "Payments" + } + ], + "total": 1, + "has_next_page": false, + "search_after_ctx": "" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListRequest" + }, + "example": { + "start_time": 1779513600, + "end_time": 1779600000, + "status": "success", + "channel_ids": [ + 12345 + ], + "limit": 20 + } + } + } + } + } + }, "/incident/info": { "post": { "operationId": "incidentInfo", @@ -11784,12 +11877,12 @@ "get": { "operationId": "statusPageChangeList", "summary": "List status page events", - "description": "List events (incidents and maintenances) for a status page.", + "description": "List status page events with only publicly visible affected components.", "tags": [ "On-call/Status pages" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Hidden affected components are omitted. Events remain in the result when none are visible, with an empty `affected_components` array.", "href": "/en/api-reference/on-call/status-pages/status-page-change-list", "metadata": { "sidebarTitle": "List status page events" @@ -20065,7 +20158,7 @@ "Monitors/Diagnostics" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Use `target_locator` to identify the target; `target_kind` is optional and is auto-inferred when omitted. Built-in target kinds are `host` and `mysql`.\n- If multiple kinds match the same locator, the response is HTTP 200 with `data.error.code = \"ambiguous_target_kind\"` and a `target_kinds` list — retry with an explicit `target_kind`.\n- The catalog is a *candidate capability* view, not an execution guarantee. The target Agent may go offline between catalog and invoke, or local Agent policy may block individual tools at invoke time.\n- Set `include_output_shape: true` to additionally receive each tool's `output_shape`. Default is `false` to keep the response small for LLM consumption.\n- Business errors (`target_unavailable`, `unknown_toolset_hash`, `ambiguous_target_kind`) come back as HTTP 200 with `data.error` present and `data.tools = []`. Only protocol / auth / internal errors use the standard error envelope.\n- The response uses **sparse fields**: on success `error` is omitted rather than sent as `null`, and `target` is omitted when the locator could not be uniquely resolved. `tools` is always present.", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Use `target_locator` to identify the target; `target_kind` is optional and is inferred from current target routing when omitted.\n- If multiple kinds match the same locator, the response is HTTP 200 with `data.error.code = \"ambiguous_target_kind\"` and a `target_kinds` list — retry with an explicit `target_kind`.\n- The catalog is a candidate capability view, not an execution guarantee. The target Agent may go offline between catalog and invoke, or local Agent policy may block individual tools at invoke time.\n- Each tool entry exposes only `name`, `target_kind`, `description`, and `input_schema`. It does not expose tool versions, output contracts, catalog revisions, or execution limits.\n- Business errors (`target_unavailable`, `timeout`, `forward_failed`, `invalid_tool_result`, `ambiguous_target_kind`) return HTTP 200 with `data.error` present and `data.tools = []`. Only protocol, authentication, and internal errors use the standard error envelope.\n- The response uses **sparse fields**: on success `error` is omitted rather than sent as `null`, and `target` is omitted when the locator could not be uniquely resolved. `tools` is always present.", "href": "/en/api-reference/monitors/diagnostics/monit-read-tools-catalog", "metadata": { "sidebarTitle": "List target tool catalog" @@ -20080,8 +20173,7 @@ }, "example": { "account_id": 10001, - "target_locator": "web-01", - "include_output_shape": true + "target_locator": "web-01" } } } @@ -20122,144 +20214,6 @@ "type": "object", "additionalProperties": false, "properties": {} - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "cpu": { - "type": "object" - }, - "degradation_reasons": { - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - }, - "disk": { - "description": "Filesystems sorted by used_pct desc; rootfs always present; capped at host.disk.top_n. Sizes are in GB; used_pct/inode_used_pct in percent.", - "type": "array" - }, - "disk_errors": { - "description": "Mount points whose statfs returned a syscall error (EACCES / ENOENT / EIO / stale, etc.); each entry is `: `.", - "type": "array" - }, - "disk_io": { - "description": "Per-device disk I/O rates (util_pct, IOPS, throughput, await). Sorted by util_pct desc; capped at host.disk_io.top_n. Only whole-disk devices shown.", - "type": "object" - }, - "disk_timeouts": { - "description": "Mount points whose statfs hit per-mount timeout.", - "type": "array" - }, - "load": { - "type": "object" - }, - "memory": { - "description": "Memory and swap sizes are in MB; percentages are 0..100. Swap fields are always present when memory collection succeeds, including zero when swap is not configured.", - "properties": { - "available_mb": { - "type": "integer" - }, - "swap_configured": { - "description": "True when the kernel reports a non-zero SwapTotal.", - "type": "boolean" - }, - "swap_total_mb": { - "type": "integer" - }, - "swap_used_mb": { - "type": "integer" - }, - "swap_used_pct": { - "type": "number" - }, - "total_mb": { - "type": "integer" - }, - "used_mb": { - "type": "integer" - }, - "used_pct": { - "type": "number" - } - }, - "required": [ - "total_mb", - "available_mb", - "used_mb", - "used_pct", - "swap_configured", - "swap_total_mb", - "swap_used_mb", - "swap_used_pct" - ], - "type": "object" - }, - "network_io": { - "description": "Per-interface network throughput and error rates. Sorted by total traffic desc; capped at host.network_io.top_n. Virtual/container interfaces excluded by default.", - "type": "object" - }, - "procs": { - "type": "object" - }, - "sample_interval_sec": { - "description": "Shared sampling interval for CPU, disk_io, network_io counter-diff calculations.", - "type": "number" - }, - "tcp_connections": { - "description": "TCP connection state distribution via netlink SOCK_DIAG. Shows counts per state (established, time_wait, close_wait, listen, syn_recv, other, total).", - "type": "object" - }, - "uptime_sec": { - "type": "number" - }, - "vmstat": { - "description": "Sparse cumulative counters since the current boot; use them as historical clues, not current rates.", - "properties": { - "oom_kill_since_boot": { - "description": "OOM kills accumulated since boot; omitted when this kernel does not expose the counter.", - "type": "integer" - }, - "pgmajfault_since_boot": { - "description": "Major page faults accumulated since boot.", - "type": "integer" - } - }, - "required": [ - "pgmajfault_since_boot" - ], - "type": "object" - } - }, - "required": [ - "sample_interval_sec" - ], - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } }, { @@ -20281,65 +20235,6 @@ "type": "integer" } } - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "avg_ms": { - "type": "number" - }, - "max_ms": { - "type": "number" - }, - "min_ms": { - "type": "number" - }, - "probes": { - "items": { - "properties": { - "error": { - "type": "string" - }, - "latency_ms": { - "type": "number" - } - }, - "type": "object" - }, - "type": "array" - }, - "reachable": { - "type": "boolean" - }, - "resolved_ip": { - "type": "string" - } - }, - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } } ] @@ -20372,7 +20267,7 @@ "Monitors/Diagnostics" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Up to **8** tools per call (`MaxToolsPerInvoke`); larger batches must be split client-side. The 8-tool cap aligns with the per-target agent concurrency.\n- Tools execute in parallel on the agent; webapi returns `results[]` aligned with the request `tools[]` order.\n- Long-running: set client timeouts to **at least 35 s**. The endpoint is intended for AI-SRE / human-RCA flows, not interactive UI.\n- Request-level errors (`target_unavailable`, `ambiguous_target_kind`, `unknown_toolset_hash`, `forward_failed`) appear as HTTP 200 with `data.error` set and `data.results = []`.\n- Per-tool failures appear as HTTP 200 with `data.error` absent and `results[i].error` populated — always check **all three** layers (outer envelope `error`, `data.error`, then each `results[i].error`).\n- The response uses **sparse fields**: absent means empty. On success `error` is omitted entirely rather than sent as `null`; on failure `data`, `summary` and `truncated` are omitted. Do not key logic off placeholder `null` fields, and do not expect `target` when the locator could not be uniquely resolved.\n- `results[i].data` is the tool payload with the monit-agent result envelope **already unwrapped** — there is no nested `data.data`. The one-line distillation is `results[i].summary`, and `results[i].truncated` (carrying a `reason`) appears only when the result was genuinely truncated.\n- `results[i].params` echoes the params webapi received for that tool, so batched calls stay correlatable even when an individual tool fails.\n- Construct `tools[].params` against the `input_schema` returned by `/monit/tools/catalog`. For no-arg tools always pass `params: {}` explicitly.", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **600 requests/minute**; **10 requests/second** per account |\n| Permissions | Any valid `app_key` (read-only; not gated by a specific permission class) |\n\n## Usage\n\n- Up to **8** tools per call (`MaxToolsPerInvoke`); larger batches must be split client-side. The 8-tool cap aligns with the per-target agent concurrency.\n- Tools execute in parallel on the agent; webapi returns `results[]` aligned with the request `tools[]` order.\n- Long-running: set client timeouts to **at least 35 s**. The endpoint is intended for AI-SRE / human-RCA flows, not interactive UI.\n- Request-level errors (`target_unavailable`, `ambiguous_target_kind`, `forward_failed`) appear as HTTP 200 with `data.error` set and `data.results = []`.\n- Per-tool failures appear as HTTP 200 with `data.error` absent and `results[i].error` populated — always check **all three** layers (outer envelope `error`, `data.error`, then each `results[i].error`).\n- The response uses **sparse fields**: absent means empty. On success `error` is omitted entirely rather than sent as `null`; on failure `data`, `summary` and `truncated` are omitted. Do not key logic off placeholder `null` fields, and do not expect `target` when the locator could not be uniquely resolved.\n- `results[i].data` is the tool payload with the monit-agent result envelope **already unwrapped** — there is no nested `data.data`. The one-line distillation is `results[i].summary`, and `results[i].truncated` (carrying a `reason`) appears only when the result was genuinely truncated.\n- `results[i].params` echoes the params webapi received for that tool, so batched calls stay correlatable even when an individual tool fails.\n- Construct `tools[].params` against the `input_schema` returned by `/monit/tools/catalog`. For no-arg tools always pass `params: {}` explicitly.", "href": "/en/api-reference/monitors/diagnostics/monit-read-tools-invoke", "metadata": { "sidebarTitle": "Invoke target tools" @@ -34977,6 +34872,7 @@ "wecom", "feishu", "feishu_app", + "feishu_app_card_table_enabled", "dingtalk_app", "wecom_app", "slack_app", @@ -35043,6 +34939,10 @@ "type": "string", "description": "Feishu app message template source." }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "description": "Whether alert labels use table rendering in Feishu app cards." + }, "dingtalk_app": { "type": "string", "description": "DingTalk app message template source." @@ -35261,6 +35161,11 @@ "type": "string", "description": "Feishu app message template source." }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "default": false, + "description": "Render alert labels as a table in Feishu app cards." + }, "dingtalk_app": { "type": "string", "description": "DingTalk app message template source." @@ -35370,6 +35275,13 @@ "type": "string", "description": "Feishu app message template source." }, + "feishu_app_card_table_enabled": { + "type": [ + "boolean", + "null" + ], + "description": "When set, enable or disable table rendering for alert labels in Feishu app cards. Omit to keep the existing setting." + }, "dingtalk_app": { "type": "string", "description": "DingTalk app message template source." @@ -38474,7 +38386,22 @@ }, "enabled_times": { "type": "array", - "description": "Time windows when the rule is active.", + "description": "Time windows when the rule is active. Defaults to all days from 00:00 to 23:59 when omitted or empty.", + "default": [ + { + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 0 + ], + "stime": "00:00", + "etime": "23:59" + } + ], "items": { "type": "object", "properties": { @@ -38507,7 +38434,9 @@ "enum": [ "text", "markdown" - ] + ], + "default": "text", + "description": "Format for the description. Defaults to `text` when omitted or empty." }, "description": { "type": "string" @@ -42856,12 +42785,7 @@ }, "target_kind": { "type": "string", - "description": "Optional target kind. When omitted webapi auto-infers across currently known kinds. Built-in kinds: `host`, `mysql`. Required on retry when the previous call returned `ambiguous_target_kind`." - }, - "include_output_shape": { - "type": "boolean", - "description": "When true, each tool entry includes its `output_shape` JSON Schema. Defaults to false to keep responses small for LLM consumption.", - "default": false + "description": "Optional target kind. When omitted, webapi infers it from current target routing. If the call returns `ambiguous_target_kind`, retry with a value from `target_kinds`." } } }, @@ -42902,11 +42826,6 @@ "input_schema": { "type": "object", "description": "JSON Schema for `tools[].params`." - }, - "output_shape": { - "type": "object", - "description": "JSON Schema of the tool result. Returned only when the request set `include_output_shape` to true.", - "x-flashduty-preserve-absence": true } } } @@ -42919,7 +42838,9 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", + "timeout", + "forward_failed", + "invalid_tool_result", "ambiguous_target_kind" ] }, @@ -43046,7 +42967,7 @@ "properties": { "code": { "type": "string", - "description": "Common values: `timeout`, `target_unavailable`, `edge_unsupported`, `invalid_tool_result`, `internal`, `invalid_args`, `unknown_tool`, `unknown_tool_version`, `unknown_toolset_hash`, `target_not_owned`, `wrong_agent`, `overloaded`, `denied`, `permission_denied`, `credential_unavailable`, `target_unreachable`." + "description": "Common WebAPI codes: `timeout`, `target_unavailable`, `invalid_tool_result`, `internal`, `invalid_args`, `unsupported_syntax`, `path_not_found`, and `catalog_changed`. Agent-specific tool errors may also be returned unchanged." }, "message": { "type": "string" @@ -43065,7 +42986,6 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", "forward_failed", "ambiguous_target_kind" ] @@ -49204,6 +49124,173 @@ "p95", "max" ] + }, + "ServiceDeskPlusRequestListRequest": { + "type": "object", + "description": "Filters for listing ServiceDeskPlus request synchronization records. A time window is optional when querying by incident ID; otherwise provide a Unix-second window no longer than 30 days.", + "properties": { + "start_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Window start, Unix seconds. Optional when `incident_id` is provided." + }, + "end_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Window end, Unix seconds. Must be greater than or equal to `start_time`. Optional when `incident_id` is provided." + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Synchronization status filter." + }, + "channel_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Channel IDs to filter by." + }, + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "ServiceDeskPlus integration ID." + }, + "incident_id": { + "type": "string", + "maxLength": 64, + "description": "Flashduty incident ID. When set, the time window can be omitted." + }, + "request_id": { + "type": "string", + "maxLength": 64, + "description": "ServiceDeskPlus request ID." + }, + "asc": { + "type": "boolean", + "description": "When `true`, sort by internal record ID ascending; otherwise descending." + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Page number starting at 1. Ignored when `search_after_ctx` is set." + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "Page size. Defaults to 20; maximum 100." + }, + "search_after_ctx": { + "type": "string", + "description": "Cursor returned by the previous page." + } + } + }, + "ServiceDeskPlusRequestMappingItem": { + "type": "object", + "description": "A synchronization mapping between a ServiceDeskPlus request and a Flashduty incident.", + "required": [ + "created_at", + "status", + "request_id", + "request_link", + "integration_id", + "incident_id", + "incident_title", + "channel_id", + "channel_name" + ], + "properties": { + "created_at": { + "type": "integer", + "format": "int64", + "description": "Mapping record creation time, Unix seconds." + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Synchronization status." + }, + "request_id": { + "type": "string", + "description": "ServiceDeskPlus request ID." + }, + "request_link": { + "type": "string", + "description": "ServiceDeskPlus request detail URL." + }, + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ServiceDeskPlus integration ID." + }, + "incident_id": { + "type": "string", + "description": "Associated Flashduty incident ID." + }, + "incident_title": { + "type": "string", + "description": "Associated incident title." + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "Channel ID for the incident." + }, + "channel_name": { + "type": "string", + "description": "Channel name for the incident." + }, + "error_message": { + "type": "string", + "description": "Error message when synchronization failed. Usually absent on successful records." + } + } + }, + "ServiceDeskPlusRequestListResponse": { + "type": "object", + "description": "Paginated list of ServiceDeskPlus request synchronization records.", + "required": [ + "items", + "total", + "has_next_page" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" + }, + "description": "Synchronization records on the current page." + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching records, capped at 1,000 for counting." + }, + "has_next_page": { + "type": "boolean", + "description": "True when more results are available." + }, + "search_after_ctx": { + "type": "string", + "description": "Cursor for the next page. Empty when no more data is available." + } + } } } } diff --git a/api-reference/openapi.zh.json b/api-reference/openapi.zh.json index 3b7c9fe6..a0082abd 100644 --- a/api-reference/openapi.zh.json +++ b/api-reference/openapi.zh.json @@ -316,6 +316,99 @@ } } }, + "/incident/sdp/request/list": { + "post": { + "operationId": "incident-service-desk-plus-request-read-list", + "summary": "获取 ServiceDeskPlus 关联故障", + "description": "分页查询 ServiceDeskPlus 请求与 Flashduty 故障的同步映射记录。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障查看**(`on-call`) |\n\n## 使用说明\n\n- 查询 ServiceDeskPlus 请求与 Flashduty 故障之间的同步映射记录,用于排查 ITSM 同步状态或定位外部请求链接。\n- 不按 `incident_id` 查询时,`start_time` 和 `end_time` 必填,均为 Unix 秒时间戳;时间范围不能超过 30 天。\n- `status` 仅支持 `success` 和 `failed`,分别表示同步成功和同步失败。\n- 响应按内部记录 ID 排序;`asc` 为 `true` 时升序,否则降序。继续翻页时传入上次响应的 `search_after_ctx`。", + "href": "/zh/api-reference/on-call/incidents/incident-service-desk-plus-request-read-list", + "metadata": { + "sidebarTitle": "获取 ServiceDeskPlus 关联故障" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "items": [ + { + "created_at": 1779514631, + "status": "success", + "request_id": "100000000001", + "request_link": "https://servicedesk.example.com/app/itdesk/ui/requests/100000000001/details", + "integration_id": 98765, + "incident_id": "685d7f4e51b9a9a6d4d0c123", + "incident_title": "Checkout API 5xx rate increased", + "channel_id": 12345, + "channel_name": "Payments" + } + ], + "total": 1, + "has_next_page": false, + "search_after_ctx": "" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestListRequest" + }, + "example": { + "start_time": 1779513600, + "end_time": 1779600000, + "status": "success", + "channel_ids": [ + 12345 + ], + "limit": 20 + } + } + } + } + } + }, "/incident/info": { "post": { "operationId": "incidentInfo", @@ -11776,12 +11869,12 @@ "get": { "operationId": "statusPageChangeList", "summary": "查询状态页事件列表", - "description": "查询状态页的事件列表(故障和维护)。", + "description": "查询状态页事件列表;响应仅包含对外可见的受影响组件。", "tags": [ "On-call/状态页" ], "x-mint": { - "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 无 —— 持有有效的 `app_key` 即可调用 |", + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 无 —— 持有有效的 `app_key` 即可调用 |\n\n## 使用说明\n\n- 响应会过滤隐藏的受影响组件。若事件没有任何可见组件,事件仍会保留,但 `affected_components` 为空数组。", "href": "/zh/api-reference/on-call/status-pages/status-page-change-list", "metadata": { "sidebarTitle": "查询状态页事件列表" @@ -20057,7 +20150,7 @@ "Monitors/诊断分析" ], "x-mint": { - "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 使用 `target_locator` 标识监控对象;`target_kind` 可选,省略时自动推断。内置的 target kind 包括 `host` 与 `mysql`。\n- 若同一 locator 匹配多个 kind,响应为 HTTP 200,`data.error.code = \"ambiguous_target_kind\"`,并附带 `target_kinds` 列表——请带上显式的 `target_kind` 重试。\n- 工具能力清单是*候选能力*视图,并非执行保证。目标 Agent 可能在拿到清单与发起调用之间下线,本地 Agent 策略也可能在调用时拦截某些工具。\n- 设置 `include_output_shape: true` 可额外返回每个工具的 `output_shape`。默认为 `false`,以便为 LLM 消费保持响应精简。\n- 业务错误(`target_unavailable`、`unknown_toolset_hash`、`ambiguous_target_kind`)以 HTTP 200 返回,`data.error` 存在且 `data.tools = []`。只有协议 / 鉴权 / 内部错误才使用标准错误信封。\n- 响应采用**稀疏字段**:成功时 `error` 直接省略而非返回 `null`;当 locator 无法唯一解析时 `target` 不输出。`tools` 字段恒存在。", + "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 使用 `target_locator` 标识监控对象;`target_kind` 可选,省略时按当前监控对象路由自动推断。\n- 若同一 locator 匹配多个 kind,响应为 HTTP 200,`data.error.code = \"ambiguous_target_kind\"`,并附带 `target_kinds` 列表——请带上显式的 `target_kind` 重试。\n- 工具能力清单是候选能力视图,并非执行保证。目标 Agent 可能在拿到清单与发起调用之间下线,本地 Agent 策略也可能在调用时拦截某些工具。\n- 每个工具条目只返回 `name`、`target_kind`、`description` 和 `input_schema`,不会暴露工具版本、输出契约、目录版本或执行限制。\n- 业务错误(`target_unavailable`、`timeout`、`forward_failed`、`invalid_tool_result`、`ambiguous_target_kind`)以 HTTP 200 返回,`data.error` 存在且 `data.tools = []`。只有协议、鉴权和内部错误才使用标准错误信封。\n- 响应采用**稀疏字段**:成功时 `error` 直接省略而非返回 `null`;当 locator 无法唯一解析时,`target` 不输出。`tools` 字段恒存在。", "href": "/zh/api-reference/monitors/diagnostics/monit-read-tools-catalog", "metadata": { "sidebarTitle": "查询监控对象工具能力清单" @@ -20072,8 +20165,7 @@ }, "example": { "account_id": 10001, - "target_locator": "web-01", - "include_output_shape": true + "target_locator": "web-01" } } } @@ -20114,144 +20206,6 @@ "type": "object", "additionalProperties": false, "properties": {} - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "cpu": { - "type": "object" - }, - "degradation_reasons": { - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - }, - "disk": { - "description": "Filesystems sorted by used_pct desc; rootfs always present; capped at host.disk.top_n. Sizes are in GB; used_pct/inode_used_pct in percent.", - "type": "array" - }, - "disk_errors": { - "description": "Mount points whose statfs returned a syscall error (EACCES / ENOENT / EIO / stale, etc.); each entry is `: `.", - "type": "array" - }, - "disk_io": { - "description": "Per-device disk I/O rates (util_pct, IOPS, throughput, await). Sorted by util_pct desc; capped at host.disk_io.top_n. Only whole-disk devices shown.", - "type": "object" - }, - "disk_timeouts": { - "description": "Mount points whose statfs hit per-mount timeout.", - "type": "array" - }, - "load": { - "type": "object" - }, - "memory": { - "description": "Memory and swap sizes are in MB; percentages are 0..100. Swap fields are always present when memory collection succeeds, including zero when swap is not configured.", - "properties": { - "available_mb": { - "type": "integer" - }, - "swap_configured": { - "description": "True when the kernel reports a non-zero SwapTotal.", - "type": "boolean" - }, - "swap_total_mb": { - "type": "integer" - }, - "swap_used_mb": { - "type": "integer" - }, - "swap_used_pct": { - "type": "number" - }, - "total_mb": { - "type": "integer" - }, - "used_mb": { - "type": "integer" - }, - "used_pct": { - "type": "number" - } - }, - "required": [ - "total_mb", - "available_mb", - "used_mb", - "used_pct", - "swap_configured", - "swap_total_mb", - "swap_used_mb", - "swap_used_pct" - ], - "type": "object" - }, - "network_io": { - "description": "Per-interface network throughput and error rates. Sorted by total traffic desc; capped at host.network_io.top_n. Virtual/container interfaces excluded by default.", - "type": "object" - }, - "procs": { - "type": "object" - }, - "sample_interval_sec": { - "description": "Shared sampling interval for CPU, disk_io, network_io counter-diff calculations.", - "type": "number" - }, - "tcp_connections": { - "description": "TCP connection state distribution via netlink SOCK_DIAG. Shows counts per state (established, time_wait, close_wait, listen, syn_recv, other, total).", - "type": "object" - }, - "uptime_sec": { - "type": "number" - }, - "vmstat": { - "description": "Sparse cumulative counters since the current boot; use them as historical clues, not current rates.", - "properties": { - "oom_kill_since_boot": { - "description": "OOM kills accumulated since boot; omitted when this kernel does not expose the counter.", - "type": "integer" - }, - "pgmajfault_since_boot": { - "description": "Major page faults accumulated since boot.", - "type": "integer" - } - }, - "required": [ - "pgmajfault_since_boot" - ], - "type": "object" - } - }, - "required": [ - "sample_interval_sec" - ], - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } }, { @@ -20273,65 +20227,6 @@ "type": "integer" } } - }, - "output_shape": { - "properties": { - "data": { - "properties": { - "avg_ms": { - "type": "number" - }, - "max_ms": { - "type": "number" - }, - "min_ms": { - "type": "number" - }, - "probes": { - "items": { - "properties": { - "error": { - "type": "string" - }, - "latency_ms": { - "type": "number" - } - }, - "type": "object" - }, - "type": "array" - }, - "reachable": { - "type": "boolean" - }, - "resolved_ip": { - "type": "string" - } - }, - "type": "object" - }, - "summary": { - "minLength": 1, - "type": "string" - }, - "truncated": { - "additionalProperties": false, - "properties": { - "reason": { - "minLength": 1, - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" } } ] @@ -20364,7 +20259,7 @@ "Monitors/诊断分析" ], "x-mint": { - "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 单次调用至多 **8** 个工具(`MaxToolsPerInvoke`);超出需在客户端拆分。8 个工具的上限与单监控对象 Agent 的并发能力对齐。\n- 工具在 Agent 上并行执行;webapi 返回的 `results[]` 与请求中的 `tools[]` 顺序对齐。\n- 长耗时:客户端超时至少设置 **35 秒**。该接口面向 AI-SRE / 人工排障流程,不适用于交互式 UI。\n- 请求级错误(`target_unavailable`、`ambiguous_target_kind`、`unknown_toolset_hash`、`forward_failed`)以 HTTP 200 返回,`data.error` 不为空,`data.results = []`。\n- 单工具失败以 HTTP 200 返回,`data.error` 不输出,`results[i].error` 被填充——务必同时检查**三层**(外层信封 `error`、`data.error`、再到每个 `results[i].error`)。\n- 响应采用**稀疏字段**:字段不存在即表示为空。成功时 `error` 直接省略而非返回 `null`;失败时 `data`、`summary`、`truncated` 均不输出。不要依赖占位的 `null` 字段做判断;当 locator 无法唯一解析时,`target` 同样不会出现。\n- `results[i].data` 是 Tool 的业务数据,monit-agent 的 result envelope **已被解开**——不会出现嵌套的 `data.data`。一行摘要位于 `results[i].summary`;`results[i].truncated`(内含 `reason`)仅在结果确实被截断时出现。\n- `results[i].params` 回显 webapi 收到的该 Tool 调用参数,便于在批量调用中关联结果——即使其中某个 Tool 失败也能对上号。\n- 按 `/monit/tools/catalog` 返回的 `input_schema` 构造 `tools[].params`。对于无参工具,务必显式传 `params: {}`。", + "content": "## 调用限制\n\n| 项 | 值 |\n| ------ | ----- |\n| 速率限制 | **600 次/分钟**;**10 次/秒** 每账户 |\n| 权限 | 任意有效的 `app_key`(只读;不受特定权限分类约束) |\n\n## 使用说明\n\n- 单次调用至多 **8** 个工具(`MaxToolsPerInvoke`);超出需在客户端拆分。8 个工具的上限与单监控对象 Agent 的并发能力对齐。\n- 工具在 Agent 上并行执行;webapi 返回的 `results[]` 与请求中的 `tools[]` 顺序对齐。\n- 长耗时:客户端超时至少设置 **35 秒**。该接口面向 AI-SRE / 人工排障流程,不适用于交互式 UI。\n- 请求级错误(`target_unavailable`、`ambiguous_target_kind`、`forward_failed`)以 HTTP 200 返回,`data.error` 不为空,`data.results = []`。\n- 单工具失败以 HTTP 200 返回,`data.error` 不输出,`results[i].error` 被填充——务必同时检查**三层**(外层信封 `error`、`data.error`、再到每个 `results[i].error`)。\n- 响应采用**稀疏字段**:字段不存在即表示为空。成功时 `error` 直接省略而非返回 `null`;失败时 `data`、`summary`、`truncated` 均不输出。不要依赖占位的 `null` 字段做判断;当 locator 无法唯一解析时,`target` 同样不会出现。\n- `results[i].data` 是 Tool 的业务数据,monit-agent 的 result envelope **已被解开**——不会出现嵌套的 `data.data`。一行摘要位于 `results[i].summary`;`results[i].truncated`(内含 `reason`)仅在结果确实被截断时出现。\n- `results[i].params` 回显 webapi 收到的该 Tool 调用参数,便于在批量调用中关联结果——即使其中某个 Tool 失败也能对上号。\n- 按 `/monit/tools/catalog` 返回的 `input_schema` 构造 `tools[].params`。对于无参工具,务必显式传 `params: {}`。", "href": "/zh/api-reference/monitors/diagnostics/monit-read-tools-invoke", "metadata": { "sidebarTitle": "调用监控对象工具" @@ -34968,6 +34863,7 @@ "wecom", "feishu", "feishu_app", + "feishu_app_card_table_enabled", "dingtalk_app", "wecom_app", "slack_app", @@ -35034,6 +34930,10 @@ "type": "string", "description": "飞书应用消息模板源。" }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "description": "是否在飞书应用卡片中以表格渲染告警标签。" + }, "dingtalk_app": { "type": "string", "description": "钉钉应用消息模板源。" @@ -35252,6 +35152,11 @@ "type": "string", "description": "飞书应用消息模板源。" }, + "feishu_app_card_table_enabled": { + "type": "boolean", + "default": false, + "description": "是否在飞书应用卡片中以表格渲染告警标签,默认关闭。" + }, "dingtalk_app": { "type": "string", "description": "钉钉应用消息模板源。" @@ -35361,6 +35266,13 @@ "type": "string", "description": "飞书应用消息模板源。" }, + "feishu_app_card_table_enabled": { + "type": [ + "boolean", + "null" + ], + "description": "设置后开启或关闭飞书应用卡片中的告警标签表格渲染;省略时保持当前设置。" + }, "dingtalk_app": { "type": "string", "description": "钉钉应用消息模板源。" @@ -38465,7 +38377,22 @@ }, "enabled_times": { "type": "array", - "description": "规则生效的时间窗口。", + "description": "规则生效的时间窗口。省略或传空数组时,默认每天 00:00–23:59 生效。", + "default": [ + { + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 0 + ], + "stime": "00:00", + "etime": "23:59" + } + ], "items": { "type": "object", "properties": { @@ -38498,7 +38425,9 @@ "enum": [ "text", "markdown" - ] + ], + "default": "text", + "description": "描述内容的格式。省略或为空时默认使用 `text`。" }, "description": { "type": "string" @@ -42847,12 +42776,7 @@ }, "target_kind": { "type": "string", - "description": "可选的 target kind。省略时 webapi 在当前已知的 kind 中自动推断。内置 kind:`host`、`mysql`。上次返回 `ambiguous_target_kind` 时,重试必须传入此字段。" - }, - "include_output_shape": { - "type": "boolean", - "description": "为 true 时,每个工具条目额外返回其 `output_shape` JSON Schema。默认 false,以便为 LLM 消费保持响应精简。", - "default": false + "description": "可选的 target kind。省略时 webapi 会按当前监控对象路由自动推断。若返回 `ambiguous_target_kind`,请从 `target_kinds` 中选择一个值重试。" } } }, @@ -42893,11 +42817,6 @@ "input_schema": { "type": "object", "description": "用于 `tools[].params` 的 JSON Schema。" - }, - "output_shape": { - "type": "object", - "description": "Tool 结果的 JSON Schema。仅当请求将 `include_output_shape` 置为 true 时返回。", - "x-flashduty-preserve-absence": true } } } @@ -42910,7 +42829,9 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", + "timeout", + "forward_failed", + "invalid_tool_result", "ambiguous_target_kind" ] }, @@ -43037,7 +42958,7 @@ "properties": { "code": { "type": "string", - "description": "常见取值:`timeout`、`target_unavailable`、`edge_unsupported`、`invalid_tool_result`、`internal`、`invalid_args`、`unknown_tool`、`unknown_tool_version`、`unknown_toolset_hash`、`target_not_owned`、`wrong_agent`、`overloaded`、`denied`、`permission_denied`、`credential_unavailable`、`target_unreachable`。" + "description": "常见 WebAPI 错误码:`timeout`、`target_unavailable`、`invalid_tool_result`、`internal`、`invalid_args`、`unsupported_syntax`、`path_not_found` 和 `catalog_changed`。Agent 特有的工具错误也可能原样返回。" }, "message": { "type": "string" @@ -43056,7 +42977,6 @@ "type": "string", "enum": [ "target_unavailable", - "unknown_toolset_hash", "forward_failed", "ambiguous_target_kind" ] @@ -49195,6 +49115,173 @@ "p95", "max" ] + }, + "ServiceDeskPlusRequestListRequest": { + "type": "object", + "description": "查询 ServiceDeskPlus 请求同步记录的过滤条件。按故障 ID 查询时可不传时间窗口;否则必须传入不超过 30 天的 Unix 秒时间窗口。", + "properties": { + "start_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "时间窗口起点(Unix 秒)。按 `incident_id` 查询时可省略。" + }, + "end_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "时间窗口终点(Unix 秒),必须大于等于 `start_time`。按 `incident_id` 查询时可省略。" + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "同步状态过滤。" + }, + "channel_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "协作空间 ID 列表。" + }, + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "ServiceDeskPlus 集成 ID。" + }, + "incident_id": { + "type": "string", + "maxLength": 64, + "description": "Flashduty 故障 ID。提供后可不传时间窗口。" + }, + "request_id": { + "type": "string", + "maxLength": 64, + "description": "ServiceDeskPlus 请求 ID。" + }, + "asc": { + "type": "boolean", + "description": "为 `true` 时按内部记录 ID 升序返回;否则降序。" + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "页码,从 1 开始。使用 `search_after_ctx` 时忽略。" + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "分页大小,默认 20,最大 100。" + }, + "search_after_ctx": { + "type": "string", + "description": "上一页返回的翻页游标。" + } + } + }, + "ServiceDeskPlusRequestMappingItem": { + "type": "object", + "description": "ServiceDeskPlus 请求与 Flashduty 故障之间的一条同步映射记录。", + "required": [ + "created_at", + "status", + "request_id", + "request_link", + "integration_id", + "incident_id", + "incident_title", + "channel_id", + "channel_name" + ], + "properties": { + "created_at": { + "type": "integer", + "format": "int64", + "description": "映射记录创建时间(Unix 秒)。" + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "同步状态。" + }, + "request_id": { + "type": "string", + "description": "ServiceDeskPlus 请求 ID。" + }, + "request_link": { + "type": "string", + "description": "ServiceDeskPlus 请求详情链接。" + }, + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ServiceDeskPlus 集成 ID。" + }, + "incident_id": { + "type": "string", + "description": "关联的 Flashduty 故障 ID。" + }, + "incident_title": { + "type": "string", + "description": "关联故障标题。" + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "故障所属协作空间 ID。" + }, + "channel_name": { + "type": "string", + "description": "故障所属协作空间名称。" + }, + "error_message": { + "type": "string", + "description": "同步失败时的错误信息。成功记录通常不返回该字段。" + } + } + }, + "ServiceDeskPlusRequestListResponse": { + "type": "object", + "description": "分页的 ServiceDeskPlus 请求同步记录列表。", + "required": [ + "items", + "total", + "has_next_page" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" + }, + "description": "当前页同步记录。" + }, + "total": { + "type": "integer", + "format": "int64", + "description": "匹配记录总数,最多统计 1000 条。" + }, + "has_next_page": { + "type": "boolean", + "description": "是否还有更多页。" + }, + "search_after_ctx": { + "type": "string", + "description": "下一页翻页游标。无更多数据时为空。" + } + } } } } diff --git a/docs.json b/docs.json index d12b60e7..4cddc09c 100644 --- a/docs.json +++ b/docs.json @@ -118,6 +118,7 @@ "pages": [ "zh/compliance/terms-of-service", "zh/compliance/user-agreement", + "zh/compliance/ai-sre-credit-package-purchase-agreement", "zh/compliance/microsoft-teams-app-privacy-policy", "zh/compliance/microsoft-teams-app-terms-of-use", "zh/compliance/service-sla", @@ -665,6 +666,7 @@ "POST /incident/alert/list", "POST /incident/feed", "POST /incident/past/list", + "POST /incident/sdp/request/list", "POST /incident/reset", "POST /incident/comment", "POST /incident/field/reset", @@ -1344,6 +1346,7 @@ "pages": [ "en/compliance/terms-of-service", "en/compliance/user-agreement", + "en/compliance/ai-sre-credit-package-purchase-agreement", "en/compliance/microsoft-teams-app-privacy-policy", "en/compliance/microsoft-teams-app-terms-of-use", "en/compliance/service-sla", @@ -1891,6 +1894,7 @@ "POST /incident/alert/list", "POST /incident/feed", "POST /incident/past/list", + "POST /incident/sdp/request/list", "POST /incident/reset", "POST /incident/comment", "POST /incident/field/reset", diff --git a/en/ai-sre/apps.mdx b/en/ai-sre/apps.mdx index 1ed7e673..c7912139 100644 --- a/en/ai-sre/apps.mdx +++ b/en/ai-sre/apps.mdx @@ -1,7 +1,7 @@ --- title: Apps -description: "Apps is where you manage authorized external applications in AI SRE. Each application appears as a card — today GitHub and GitLab. Once authorized, AI SRE can work directly inside your code repositories: read code, investigate changes / commits / PRs (or MRs), trace a PR / MR, and (when you ask) fix a bug, open a PR / MR, or file an issue. Its main job is to let the cloud sandbox reach your repositories safely." -keywords: ["AI SRE", "Apps", "App", "GitHub", "GitHub App", "GitLab", "GitLab App", "code repository", "gh", "glab", "git", "pull request", "merge request", "MR", "issue", "cloud sandbox", "Customize"] +description: "Apps is where you manage AI SRE's authorized external applications: GitHub, GitLab, and Kubernetes Apps. Authorize code repositories or connect a Kubernetes cluster to AI SRE with explicit namespace and permission boundaries." +keywords: ["AI SRE", "Apps", "App", "GitHub", "GitHub App", "GitLab", "GitLab App", "Kubernetes", "Kubernetes App", "K8s", "code repository", "cluster", "namespace", "gh", "glab", "git", "pull request", "merge request", "MR", "issue", "cloud sandbox", "Customize"] sidebarTitle: Apps --- @@ -15,7 +15,7 @@ sidebarTitle: Apps **Apps** is where you manage **authorized external applications**. Each external application appears as a **card** — you authorize it, manage its installations, and enable / disable or revoke it right from its card. -Apps today has two applications — **GitHub** and **GitLab** — covering the most common code-hosting platforms. Once you authorize one, AI SRE can **work directly inside your code repositories** during a session: understand and explore code, investigate recent changes / commits / PRs (MRs on GitLab), trace a PR / MR from a change ticket, answer questions about a codebase, and — when you ask — fix a bug, open a PR / MR, or file an issue. It all runs through native `gh` / `glab` / `git`, like an engineer working in a terminal. +Apps includes **GitHub**, **GitLab**, and **Kubernetes Apps**. GitHub and GitLab authorize access to code repositories: AI SRE can read code, investigate changes / commits / PRs (MRs on GitLab), and, when asked, fix a bug or open a PR / MR or issue. A Kubernetes App connects a selected Kubernetes cluster to AI SRE and limits the agent to the configured namespaces and permission level. ## Main Scenario: Letting the Cloud Sandbox Reach Your Repositories @@ -37,6 +37,34 @@ Go to **Plugins → Apps**. Apps is the **first and default** tab in the Plugins Viewing the Apps tab requires the appropriate permission; without it, the tab is hidden. Authorizing, disconnecting / revoking, and enabling / disabling each require their own action permission — when you lack one, the corresponding button is shown disabled. +## Kubernetes Apps + +--- + +A Kubernetes App connects an in-cluster agent to AI SRE. After installation, AI SRE can query cluster information and use the available Kubernetes tools within the namespaces and permission boundaries you configure. + +### Create and install + + + + Go to **Plugins → Apps → Kubernetes Apps** and click **Create Kubernetes App**. Enter a cluster name and choose its scope: **Shared** is available to all sessions in the account; **Team** is available to that team's sessions and to personal sessions of its members. Cluster names must be unique within a scope. + + + Choose **All namespaces** or **Specific namespaces**. All namespaces applies one permission level to current and future namespaces. With specific namespaces, set **Read-only** or **Read + limited modifications** for each namespace. Leaving the specific-namespace list empty allows the agent to read only basic cluster metadata. + + + Save the App, copy the generated installation command, and run it in the target cluster. Installation commands expire; reopen the installation setup or view the manifest to generate a new command without rotating the token. + + + + +After changing namespace access or permissions, run the installation command again so the in-cluster RBAC is updated. Before choosing **Read + limited modifications**, confirm that AI SRE is allowed to perform those actions in the namespace. + + +### Edit and revoke + +You can edit the cluster name, scope, and namespace access from the Kubernetes App list. Revoking immediately invalidates the connection and token, but it does not remove the in-cluster agent or RBAC automatically. Run the uninstall command shown by the console in the target cluster. It removes only resources for this Kubernetes App and preserves the shared `flashduty` namespace. + ## The GitHub App --- diff --git a/en/ai-sre/artifacts.mdx b/en/ai-sre/artifacts.mdx index d9c07fc0..38578125 100644 --- a/en/ai-sre/artifacts.mdx +++ b/en/ai-sre/artifacts.mdx @@ -1,6 +1,6 @@ --- title: Artifacts -description: The artifact gallery collects web pages and reports that AI SRE sessions produce with the present_files tool and publish with the publish_artifact tool (for example, /insight reports). Search, filter by scope, rename, share, download, and delete them here. +description: The artifact gallery collects web pages and reports that AI SRE sessions produce with the present_files tool and publish with the publish_artifact tool (for example, /insight reports). Search, filter or change scope, rename, share, download, and delete them here. keywords: ["AI SRE", "Artifacts", "present_files", "publish_artifact", "insight report", "artifact gallery"] sidebarTitle: Artifacts --- @@ -15,7 +15,7 @@ sidebarTitle: Artifacts An artifact is a file AI SRE produces in a session with the `present_files` tool and then publishes to the artifact gallery with the `publish_artifact` tool — typically a self-contained HTML report or page. For example, the operational insight report generated by typing `/insight` in a session is an artifact. -A published artifact inherits its source session's scope: artifacts from a personal session belong to their creator ("Personal"); artifacts from a session bound to a team belong to that team and can be shared with other account members. +A published artifact initially inherits its source session's scope: artifacts from a personal session belong to their creator ("Personal"); artifacts from a session bound to a team belong to that team and can be shared with other account members. Users with edit permission can change the scope later. Entry point: **AI SRE → Artifacts** in the left navigation, route `/ai-sre/artifacts`. @@ -66,6 +66,7 @@ The "More actions" menu on each card offers: | Copy link | Copies the full URL of the artifact's detail page, which you can share with other account members | | Download | Only appears when the artifact is linked to a file (`file_id` is non-empty); downloads the original file | | Rename | Only appears when you have edit permission on the artifact; opens a dialog to change the title | +| Change scope | Only appears when you have edit permission; choose Personal or an accessible team. Only the artifact creator can change the scope to Personal | | Delete | Only appears when you have edit permission on the artifact; requires confirmation. Deleting removes the artifact from the gallery, but the source session and underlying file are unaffected | ## Detail Page @@ -81,6 +82,7 @@ The detail page route is `/ai-sre/artifacts/:artifactId`. The top toolbar offers - **More actions**: this menu appears only when at least one of the following is available — - **Open session**: shown when you still have access to the artifact's source session; opens that session's full conversation (messages, tool calls, artifact history); - **Download**: shown when the artifact is linked to a file. + - **Change scope**: shown when you have edit permission. You can move the artifact to an accessible team; the creator can also change it back to Personal. The body renders the artifact according to its actual content type (for example, an HTML report renders inline as a page). @@ -88,7 +90,7 @@ The body renders the artifact according to its actual content type (for example, --- -Whether an artifact is editable (rename, delete) is determined by the `can_edit` field returned by the backend. Any one of the following grants management access: +Whether an artifact is editable (rename, change scope, delete) is determined by the `can_edit` field returned by the backend. Any one of the following grants management access: | Condition | Notes | |---|---| diff --git a/en/ai-sre/im.mdx b/en/ai-sre/im.mdx index 610d9f52..cbe08655 100644 --- a/en/ai-sre/im.mdx +++ b/en/ai-sre/im.mdx @@ -47,10 +47,11 @@ IM interaction requires that you have already connected the corresponding platfo --- -Open the corresponding IM integration under **On-call → Integration Center → Integration List → Instant Messaging**. After enabling war rooms under **Enhanced features**, you can configure that integration's AI SRE behavior. The following two switches are on by default: +Open the corresponding IM integration under **On-call → Integration Center → Integration List → Instant Messaging** and configure its AI SRE behavior under **Enhanced features**. The following switches are on by default: -- **Automatically start AI incident analysis**: when the integration successfully creates a war room, start one preliminary AI SRE diagnosis and post the result back to the war room. -- **Allow group chat @ AI SRE**: allow group @mentions to enter AI SRE. In Slack, the switch is labeled **Allow group chat @ AI SRE and /fd command**; turning it off makes both group @mentions and `/fd` commands silent. +- **Automatically start AI incident analysis**: available after you enable War Room. When the integration creates a war room, AI SRE starts one preliminary diagnosis and posts the result back to the room. +- **Allow group chat @ AI SRE**: available without enabling War Room. It allows group @mentions to enter AI SRE. In Slack, the switch is labeled **Allow group chat @ AI SRE and /fd command**; turning it off makes both group @mentions and `/fd` commands silent. +- **Use thread replies in normal group chats**: available only for Feishu/Lark and Slack. When enabled, each normal-group thread has an independent session; War Rooms still receive replies directly in the group. If AI SRE is not enabled for the account, these switches do not take effect. After AI SRE is enabled, each IM integration follows its own settings. diff --git a/en/ai-sre/knowledge.mdx b/en/ai-sre/knowledge.mdx index 242331f8..708740a3 100644 --- a/en/ai-sre/knowledge.mdx +++ b/en/ai-sre/knowledge.mdx @@ -73,7 +73,7 @@ Go to the **Knowledges** management page to create, edit, enable/disable, or del - Click **Create** in the top-right corner of the page to open the "Create knowledge base" dialog. A Knowledge Pack has no editable name of its own — it's a singleton resource per target (account or team), so the dialog only asks you to choose a **Scope**: account or a specific team. To create a team-level pack, you must belong to the target team; account-level creation is limited to the Account Owner or admins. Each target can own only one pack; targets that already have a pack are hidden from the dropdown. After choosing a scope, click **Create** to finish — the console uses the scope (account / team name) as the pack's display identifier. + Click **Create** in the top-right corner of the page to open the "Create knowledge base" dialog. A Knowledge Pack has no editable name of its own — it's a singleton resource per target (account or team), so the dialog only asks you to choose a **Scope**: account or a specific team. To create a team-level pack, you must belong to the target team; account-level creation is limited to the Account Owner or admins. Each target can own only one pack. Accounts and teams that already have a pack remain in the dropdown and are marked as having an existing Knowledge Pack; after you select one, the primary button becomes **Open knowledge base** and opens that pack instead of creating another. Choose a scope without a pack and click **Create** to make one. The console checks again immediately before creation, so if someone else has just created a pack for that scope, it opens the existing pack instead. The console uses the scope (account / team name) as the pack's display identifier. Click any row in the list to open the inspector. The left panel shows the file tree; the right panel is an inline editor. Click **New File** to enter a filename (e.g., `runbook.md`), or use **Upload** to import a local file. Markdown files support both **Preview** and **Source** views. Click **Save** after editing. diff --git a/en/ai-sre/sessions.mdx b/en/ai-sre/sessions.mdx index d22691dd..249597a0 100644 --- a/en/ai-sre/sessions.mdx +++ b/en/ai-sre/sessions.mdx @@ -208,9 +208,9 @@ Editing a historical message is, under the hood, a **rewind** operation: once su ### Forking a session -After a turn has fully completed, a **Fork** button appears beside the agent reply. Click it to open a "Fork from this message?" dialog: it defaults to the source session's environment and team, but you can switch to another online BYOC runner, or rebind to a personal scope or a different team. Click **Confirm** to create — and automatically open — a new session forked from the completed turn that produced that reply. +After a turn has fully completed, a **Fork** button appears beside the agent reply. Click it to open the **Fork new conversation** dialog. It pre-fills the source session's scope and environment as suggestions, but every fork requires an explicit target scope and environment. Choose Personal or an accessible team, then choose **Auto**, a cloud Sandbox, or an online BYOC Runner. Click **Confirm** to create — and automatically open — a new session forked from the completed turn that produced that reply. -Forking is useful when you want to try another path from the same investigation context. The new session keeps the conversation and tool-call history up to the selected turn; the environment and team default to the source session's, but are confirmed (or actively changed) by you in the fork dialog rather than simply inherited. Later turns from the source session are not included. The forked session includes a "Forked from conversation" divider; click it to return to the source position in the original session. +Forking is useful when you want to try another path from the same investigation context. The new session keeps the conversation and tool-call history up to the selected turn, but it never inherits the source environment binding on the server. Available environments are filtered by the target scope. If you are not a member of the source team, the dialog changes to Personal; if the source environment is deleted, offline, never connected, or outside the target scope, it changes to **Auto**. Later turns from the source session are not included. The forked session includes a "Forked from conversation" divider; click it to return to the source position in the original session. You can fork only from a **completed** turn in a top-level session. If the source session is still running, the selected turn has not settled, or the target is a Subagent child session, AI SRE rejects the fork. diff --git a/en/compliance/ai-sre-credit-package-purchase-agreement.mdx b/en/compliance/ai-sre-credit-package-purchase-agreement.mdx new file mode 100644 index 00000000..504b9cae --- /dev/null +++ b/en/compliance/ai-sre-credit-package-purchase-agreement.mdx @@ -0,0 +1,104 @@ +--- +title: "AI SRE credit package purchase agreement" +description: "Review the purchase scope, billing, validity, deduction order, and refund rules for an AI SRE credit package." +keywords: ["AI SRE", "credits", "credit package", "purchase agreement", "pay as you go", "refund"] +--- + +Last updated: July 26, 2026 +Agreement version: `ai-sre-credit-package-v1` + +This AI SRE credit package purchase agreement (the “Agreement”) supplements the [Flashduty Terms of Service](/en/compliance/terms-of-service). By selecting “I have read and agree” on the purchase page and submitting an order, you accept this Agreement on behalf of your account. If you have a separate written agreement with Flashduty that conflicts with this Agreement, that written agreement controls. + +## Scope + +AI SRE is metered in credits. A credit package is a one-time, account-scoped purchase of credits. It is not a subscription, seat, or auto-renewing service. You can purchase a package while AI SRE is closed. Using AI SRE, however, requires all three of the following: + +1. AI SRE is enabled for the account; +2. The account holds an active On-call Pro or higher subscription; +3. The member starting the work occupies an available Flashduty license (drawn from the same license pool as On-call and other products — there is no separately sold AI SRE license). + +Packages are shared by the account and are not affected by the number of seats. Purchasing a package does not enable AI SRE and does not replace the subscription and license requirements above. + + +Enable AI SRE before you buy a package. A package's validity period starts at successful payment, and an account without AI SRE enabled consumes no credits at all — buy first and enable later, and the package will sit idle while its validity runs out. + + +## Packages and orders + +The following fixed packages are currently available. An order purchases one package at one tier; to buy more credits, place additional orders — a package does not support a quantity multiplier within a single order. An account can hold several packages at once (the same tier or different tiers), and their credits accumulate. + +| Package | Credits per unit | Price per unit | +| --- | ---: | ---: | +| 1,000 credits | 1,000 | ¥950 | +| 5,000 credits | 5,000 | ¥4,500 | +| 20,000 credits | 20,000 | ¥17,000 | + +The purchase enquiry and order-confirmation page show the selected package and its price. The price and credits displayed and recorded in that enquiry/order confirmation govern that purchase. Flashduty may change package pricing or tiers for future orders, but does not retroactively change a paid order's price, credits, or validity period. + +A package is valid for 365 days from successful payment. Unused purchased credits expire at the end of that period. Packages do not renew automatically and are not replenished on any schedule. + + +Confirm the package and price before you purchase. Package credits can only offset AI SRE usage; they cannot be redeemed for cash, transferred to another account, or used for other Flashduty products. + + +## Credit deduction and pay-as-you-go billing + +For each AI SRE usage event, credits are deducted in this order: + +1. Any gifted credits Flashduty has granted to the account, if any; +2. Purchased package credits that expire first — when several packages are held, the one expiring soonest is drawn down first; then +3. Pay-as-you-go (PAYG). + +Gifted credits, if granted, are unrelated to this purchase and are granted and calculated under separate rules Flashduty publishes or communicates separately. They are usable only within the billing period they were granted for, do not carry over between periods, and cannot be transferred or refunded; any unused gifted credits are zeroed out when AI SRE is disabled for the account, while purchased-package balances and validity are unaffected. + +Enabling AI SRE authorizes PAYG. PAYG is settled from your account's general wallet at `1 credit = ¥1`. The billing period is a calendar month in the account's billing timezone (the 1st of the month through the 1st of the next), rolling over automatically at each month boundary — it is independent of On-call's billing cycle or renewal date. + +On the AI SRE billing page you can put PAYG into one of three states: + +- **Unlimited** (default): PAYG continues once packages are exhausted, with no ceiling; +- **Monthly cap**: PAYG spends at most the number of credits you set, per period; +- **PAYG forbidden**: PAYG is never used — runs stop once packages are exhausted. + +When gifted credits, purchased packages, and authorized PAYG are all insufficient, the system stops admitting new AI SRE runs. A top-level run that has already started is not interrupted, and the usage it goes on to produce is still metered. Metered is not the same as charged: **usage beyond the credits you had available and the PAYG you authorized is absorbed by Flashduty and is not billed to you** — PAYG can never be charged beyond the cap you set, and gifted or package balances are never drawn below zero. + +## Billing rules + +### What consumes credits + +AI SRE credit consumption comes from three independently metered sources: + +| Charge | Unit | Current unit price | +| --- | --- | ---: | +| Model usage | Per million tokens, split into fresh input / cache-hit input / output | 18 / 0.15 / 36 credits | +| Sandbox runtime | Metered continuously over online time (millisecond granularity, never rounded up to a whole hour) | 8 credits / hour | +| Web search | Per successful search request | 0.25 credits | + +The table reflects unit prices as of July 26, 2026 and is for reference; the prices Flashduty publishes at the time of use govern. Flashduty may change unit prices for future usage but does not retroactively change deductions already made. Model pricing is bound to a model tier, not to a specific supplier — even if a backend failover routes your call to a costlier fallback, your unit price does not change. + +Account billing pages show credits only, not model-token detail. AI SRE records the usage facts, while Flashduty's account settlement system produces settlement and bills. + +Account pages round displayed amounts and credits to two decimal places. Internal metering and settlement carry considerably more precision than the display. Display precision does not change the settled result. + +### What is and is not charged + +- Metering starts the moment you enable AI SRE. Usage from before then is not charged, and is not charged retroactively once you enable it. +- A model call with valid token usage is charged for its model-token usage, whether the task ultimately succeeds, fails, or is stopped. +- Sandboxes are charged for **online** time. Paused time is not charged. Sandbox charging is independent of whether any task is running — an online sandbox is metered regardless — so release a sandbox once you no longer need it. +- A search request that returns an error (for example, the search service is unavailable or the request is invalid) is not charged. A search that succeeds but matches nothing is still a successful search request and is charged normally. +- AI-generated output is for reference only. You are responsible for validating it against your own business, permissions, and change-management process, and for decisions to act or not act on it. + +### Account arrears + +PAYG is settled from the account's general wallet. If the wallet is exhausted or the account falls into arrears, Flashduty disables the account's pay-as-you-go resources, including the AI SRE service itself — no new AI SRE run can be started while it is disabled. Purchased packages are prepaid resources: they are not disabled by arrears, and their balance and validity are unaffected. Once the account is topped up, resources disabled for arrears are re-enabled automatically. + +## Refunds + +There is no self-service refund flow, and a refund is processed for a whole package only — partial refunds are not supported. To request one, contact [support@flashcat.cloud](mailto:support@flashcat.cloud) with your account, order ID, and reason for the request; Flashduty reviews eligibility manually. + +A package qualifies for a refund only if it is **completely unused** (its credit balance still equals the amount originally granted — not a single credit has been drawn) **and** unexpired. A package that has had any credits drawn from it, however little, or one that has expired, cannot be refunded. An approved refund returns the full amount paid for that package's order through Flashduty's standard refund channel; the same package cannot be refunded twice. Gifted credits are not refundable. + +Whether a refund is approved and its amount are subject to the review result, applicable law, and any separate agreement between you and Flashduty. Nothing in this Agreement limits any refund right that cannot be excluded by law. + +## Changes and contact + +Flashduty may update this Agreement to the extent permitted by applicable law. Changes that apply to future purchases are published on the purchase page or here. A paid order continues under the package, price, and validity confirmed for that order. For questions about this Agreement or AI SRE credit packages, contact [support@flashcat.cloud](mailto:support@flashcat.cloud). diff --git a/en/developer/cli.mdx b/en/developer/cli.mdx index 3ef484b7..c6fdbce6 100644 --- a/en/developer/cli.mdx +++ b/en/developer/cli.mdx @@ -460,7 +460,7 @@ Showing 2 results (page 1, total 2). -Machine-parseable, full payload, no truncation. Ideal for scripts and CI/CD pipelines. +Machine-parseable. Except for the commands with default compact fields listed below, it returns the command's full response data; table-column truncation does not apply to JSON. Ideal for scripts and CI/CD pipelines. ```bash flashduty incident list --json | jq '.[].title' @@ -468,7 +468,7 @@ flashduty incident list --json | jq '.[].title' -TOON (Token-Oriented Object Notation) emits the full payload without truncation, but for homogeneous arrays it drops the per-row field names that JSON repeats — cutting token usage substantially on list output, which suits feeding to AI agents. +TOON (Token-Oriented Object Notation) drops the per-row field names that JSON repeats for homogeneous arrays, cutting token usage substantially on list output and making it well suited to AI agents. Commands with default compact fields listed below emit their field projections and are size-bounded. ```bash flashduty incident list --output-format toon @@ -484,6 +484,25 @@ Table view with no column truncation — useful for copy-paste or wide terminals +### Field projections for structured output + +The following commands support `--fields` with `json` or `toon` output. Supply comma-separated top-level response fields; an unknown field fails immediately, and table output ignores this flag. + +| Command | Structured output when `--fields` is omitted | Limit | +| --- | --- | --- | +| `flashduty incident list` | `incident_id`, `title`, `incident_severity`, `progress`, `start_time`, `channel_id` | 16 KiB | +| `flashduty incident similar ` | `incident_id`, `title`, `incident_severity`, `progress`, `start_time`, `close_time`, `ack_time`, `alert_cnt`, `root_cause`, `score` | 16 KiB | +| `flashduty incident detail ` | Returns full detail when `--fields` is omitted; otherwise returns only the selected fields | 8 KiB for projections only | +| `flashduty alert-event list` | `event_id`, `alert_id`, `event_severity`, `event_status`, `event_time`, `title` | 16 KiB | + +For example, export only an incident ID, title, and progress: + +```bash +flashduty incident list --json --fields incident_id,title,progress +``` + +When a projected structured output exceeds its limit, the CLI keeps the selected field names, shortens long strings, and marks them with `...`. If non-string fields alone exceed the limit, the command asks you to reduce the fields or result count. `incident detail` without `--fields` is not subject to the projection limit. + ## Agent skills Flashduty CLI ships with 10 agent skills that teach AI coding agents — Claude Code, Cursor, Codex, Gemini CLI, Windsurf, and 40+ others — how to operate Flashduty from your terminal. diff --git a/en/monitors/targets/configure-targets.mdx b/en/monitors/targets/configure-targets.mdx index d6a5e8da..4a19bc45 100644 --- a/en/monitors/targets/configure-targets.mdx +++ b/en/monitors/targets/configure-targets.mdx @@ -51,7 +51,6 @@ host: shell_exec: enabled: true - pipeline_max_segments: 3 default_max_lines: 200 cat_max_file_size: 20971520 user_allow_list: [] @@ -67,10 +66,6 @@ mongodb: [] mongodb_mongos: [] kafka: [] elasticsearch: [] - -script_tool: - enabled: false - dir: /opt/monit-agent/tools.d ``` ## locator_mappings @@ -121,7 +116,6 @@ Recommendations: host: shell_exec: enabled: true - pipeline_max_segments: 3 default_max_lines: 200 cat_max_file_size: 20971520 user_allow_list: [] @@ -130,7 +124,10 @@ host: Recommendations: - Keep `enabled: true` when AI-SRE needs live host diagnostics. Only controlled shell commands can be executed. -- If some shell commands are blocked by built-in guardrails, add them manually to `user_allow_list` only after confirming that they are safe, read-only, and do not expose sensitive information. +- If a command is occasionally blocked, local root can [approve that command](/en/monitors/targets/install-agent#approve-a-blocked-shell-command). +- For a command that needs to run repeatedly, add the complete command to `user_allow_list` only after confirming that it is safe, read-only, and does not expose sensitive information. + +Neither human approval nor `user_allow_list` can allow high-risk operations such as shutdown, reboot, system destruction, or reading sensitive credentials. To urgently disable a tool, use `tool_policy.disabled_tools`: @@ -140,6 +137,8 @@ tool_policy: - shell.exec ``` +After changing `shell_exec.enabled` or `tool_policy.disabled_tools`, send SIGHUP to reload the configuration. The change takes effect without restarting the Agent. + ## MySQL To diagnose MySQL, add instance configuration under `mysql:`. Use a read-only MySQL account, and preferably store the password in a separate credential file: @@ -499,15 +498,3 @@ ES_PASSWORD= | `credential` | If Elasticsearch security authentication is disabled, credential can be omitted. Configure a read-only account in production. | Elasticsearch does not use `locator_mappings`. The Agent automatically obtains `cluster_name` from the cluster and uses it as the object address in the console. - -## script_tool - -`script_tool` is used to add custom script tools. Most users can keep it disabled: - -```yaml -script_tool: - enabled: false - dir: /opt/monit-agent/tools.d -``` - -Enable it only when you need custom diagnostic capabilities and can confirm that the script source and directory permissions are controlled. diff --git a/en/monitors/targets/install-agent.mdx b/en/monitors/targets/install-agent.mdx index e3d57bf7..12cbffaf 100644 --- a/en/monitors/targets/install-agent.mdx +++ b/en/monitors/targets/install-agent.mdx @@ -12,8 +12,8 @@ Prepare the following information before installation: | Item | Description | |---|---| -| Agent package download URL | `https://static.flashcat.cloud/monitagent/monitagent-v0.0.27-linux-amd64.tar.gz`. For ARM CPUs, replace `amd64` with `arm64`. | -| Edge address | For example, `ws://edge.example.com:6868` or `wss://edge.example.com:6868`. Edge version must be `>= v0.46.0`. View the Edge list and installation method [here](https://console.flashcat.cloud/monit/engine/list). | +| Agent package download URL | `https://static.flashcat.cloud/monitagent/monitagent-v0.1.6-linux-amd64.tar.gz`. For ARM CPUs, replace `amd64` with `arm64`. | +| Edge address | For example, `ws://edge.example.com:6868` or `wss://edge.example.com:6868`. Edge version must be `>= v0.47.0`. View the Edge list and installation method [here](https://console.flashcat.cloud/monit/engine/list). | | Local host object address | Use the current host's fixed private IP or DNS name, such as `10.0.1.12`. If omitted, the Agent uses the IP address associated with the local default route. | | Read-only accounts for databases and middleware | To diagnose MySQL, Redis, PostgreSQL, MongoDB, Kafka, Elasticsearch, and other services, prepare read-only accounts and credentials in advance. | @@ -27,8 +27,8 @@ The following steps use Linux as an example. sudo mkdir -p /opt/monit-agent cd /opt/monit-agent -sudo curl -sfLO "https://static.flashcat.cloud/monitagent/monitagent-v0.0.27-linux-amd64.tar.gz" -sudo tar -xzf monitagent-v0.0.27-linux-amd64.tar.gz --strip-components=1 +sudo curl -sfLO "https://static.flashcat.cloud/monitagent/monitagent-v0.1.6-linux-amd64.tar.gz" +sudo tar -xzf monitagent-v0.1.6-linux-amd64.tar.gz --strip-components=1 sudo chmod +x ./monitagent ``` @@ -132,6 +132,30 @@ If you modify the Edge address, Basic Auth, TLS parameters, or `hostLocator`, re sudo systemctl kill -s HUP monitagent ``` +## Approve a blocked Shell command + +`shell.exec` automatically runs read-only diagnostic commands that meet its built-in safety rules. If a command does not pass the automatic rules but you have confirmed that it is appropriate for the current machine, sign in to the Linux host running the Agent and open an approval session as root: + +```bash +sudo /opt/monit-agent/monitagent shell-approval +``` + +After the session connects, it displays a waiting status. When commands need approval, the terminal shows only the commands and a ten-second countdown: + +- Press Enter to approve every command in the current batch. +- Press `n` to reject every command in the current batch. +- If you do not respond within ten seconds, the batch is rejected automatically. Concurrent commands that arrive later are queued and receive a full ten-second window after they are displayed. +- Input while no command is pending does not execute anything; the terminal continues to display the waiting status. +- Press `Ctrl-C` to close the approval session. + +Only one approval session can be active for an Agent. To take over an existing session, run: + +```bash +sudo /opt/monit-agent/monitagent shell-approval --replace +``` + +Only root can open or replace a session. Pending commands are rejected if the Agent restarts or the session disconnects, and you must open a new session after a restart. High-risk operations such as shutdown, reboot, system destruction, or reading sensitive credentials cannot be enabled through human approval. + ## Next step After the Agent starts successfully, a host object usually appears on the monitoring object page within a few seconds. Next, read [Configure Monitoring Objects](/en/monitors/targets/configure-targets) to add database and middleware objects in `agent.yaml`. diff --git a/en/monitors/targets/overview.mdx b/en/monitors/targets/overview.mdx index d71116cf..f314c570 100644 --- a/en/monitors/targets/overview.mdx +++ b/en/monitors/targets/overview.mdx @@ -81,6 +81,6 @@ After objects appear, enable controlled query tools such as `mysql.query`, `redi Prepare the Edge address, download the Agent, and start it in the foreground or as a system service. - Configure hosts, databases, middleware, and custom script tools. + Configure hosts, databases, middleware, and controlled diagnostic tools. diff --git a/en/monitors/targets/reload-and-verify.mdx b/en/monitors/targets/reload-and-verify.mdx index 6e58fd04..504a600a 100644 --- a/en/monitors/targets/reload-and-verify.mdx +++ b/en/monitors/targets/reload-and-verify.mdx @@ -10,7 +10,7 @@ Different `monit-agent` configuration changes take effect in different ways. Thi | Change | How it takes effect | |---|---| -| Host collection, MySQL, Redis, PostgreSQL, MongoDB, Kafka, Elasticsearch, and other configurations in `agent.yaml` | Send SIGHUP to reload | +| Host collection, tool switches, MySQL, Redis, PostgreSQL, MongoDB, Kafka, Elasticsearch, and other configurations in `agent.yaml` | Send SIGHUP to reload | | Edge address, Basic Auth, TLS, `hostLocator`, audit directory | Restart the Agent | Send SIGHUP: @@ -29,6 +29,8 @@ sudo systemctl restart monitagent If you only add or adjust object configuration in `agent.yaml`, use SIGHUP reload first. Restart is needed only when startup parameters or service-level parameters change. +After changing tool switches, a successful reload updates the diagnostic tools currently available from the Agent. No restart is required. + ## Verify successful onboarding After the Agent starts, a host object usually appears on the monitoring object page within a few seconds. diff --git a/en/on-call/integration/change-integration/custom-event.mdx b/en/on-call/integration/change-integration/custom-event.mdx index e6cfd74f..2c57529f 100644 --- a/en/on-call/integration/change-integration/custom-event.mdx +++ b/en/on-call/integration/change-integration/custom-event.mdx @@ -27,7 +27,123 @@ Click **Save**, then copy the newly generated **Push URL** from the current page ## Implement Protocol -Please refer to the [Developer Documentation](/en/on-call/integration/change-integration/custom-event) to complete protocol development. +### Request description + +Request method: + +```http +POST, Content-Type: application/json +``` + +Use the **push URL** shown on the integration details page. The URL format is: + +```text +{api_host}/event/push/change/standard?integration_key={integration_key} +``` + +### Request parameters + +#### Headers + +| Field | Required | Type | Description | +| :--- | :---: | :--- | :--- | +| Content-Type | Yes | string | Fixed value: `application/json`. | + +#### Query strings + +| Field | Required | Type | Description | +| :--- | :---: | :--- | :--- | +| integration_key | Yes | string | Integration secret used for access control. You can get it from the push URL after creating the integration. | + +#### Payload + +| Field | Required | Type | Description | +| :--- | :---: | :--- | :--- | +| title | Yes | string | Change title, such as a release title, ticket title, or deployment task name. | +| change_key | Yes | string | Change identifier. Events with the same `change_key` are treated as the same change. Subsequent events update the change status, labels, and link. | +| change_status | Yes | string | Change status. Enum values are case-sensitive: `Planned`, `Ready`, `Processing`, `Canceled`, and `Done`. | +| event_time | No | integer | Event occurrence time as a Unix timestamp. Seconds and milliseconds are both supported. If omitted, Flashduty uses the time when the event is received. | +| description | No | string | Change description, such as change content, impact scope, execution steps, or rollback plan. | +| link | No | string | Change details link, such as a release, ticket, or CI/CD task URL. | +| labels | No | map | Change labels. Both keys and values must be strings. We recommend following the Prometheus label naming convention for keys. Flashduty replaces special characters such as spaces, dots, and slashes in label keys with underscores. | + + +When `change_status` is `Done` or `Canceled`, Flashduty records the event time as the change end time. If you report a non-terminal status again, the end time is cleared. + + +### Response + +| Field | Required | Type | Description | +| :--- | :---: | :--- | :--- | +| request_id | Yes | string | Request ID for tracing. | +| error | No | [Error](#error) | Error details. Returned only when an error occurs. | +| data | No | object | Empty object returned after a successful report. | + +#### Error + +| Field | Required | Type | Description | +| :--- | :---: | :--- | :--- | +| code | Yes | string | Error code. See [Code](#code). | +| message | No | string | Error message. | + +#### Code + +| Error code | HTTP status | Description | +| :--- | :---: | :--- | +| InvalidParameter | 400 | Invalid parameter, such as a missing required field, invalid status enum value, or invalid integration secret. | +| InvalidContentType | 400 | Unsupported `Content-Type`. | +| MethodNotAllowed | 405 | Unsupported HTTP method. | +| Unauthorized | 401 | Authentication failed. | +| AccessDenied | 403 | Permission check failed. | +| RequestTooFrequently | 429 | Requests are too frequent. | +| RouteNotFound | 404 | Request method and path do not match any route. | +| ResourceNotFound | 400 | The account has not purchased the resource. Go to Billing to place an order first. | +| NoLicense | 400 | The account does not have enough plan licenses. Upgrade or purchase a plan first. | +| InternalError | 500 | Internal or unknown error. | + +### Request example + +Request: + +```bash +curl -X POST '{api_host}/event/push/change/standard?integration_key={integration_key}' \ + -H 'Content-Type: application/json' \ + -d '{ + "title": "order-service v1.12.0 production release", + "change_key": "deploy-order-service-202607231030", + "change_status": "Processing", + "event_time": 1784773800, + "description": "Deploy order-service v1.12.0 to production cluster cn-shanghai-prod.", + "link": "https://deploy.example.com/releases/deploy-order-service-202607231030", + "labels": { + "service": "order-service", + "env": "prod", + "cluster": "cn-shanghai-prod", + "owner": "sre" + } + }' -v +``` + +Successful response: + +```json +{ + "request_id": "0ace00116215ab4ca0ec5244b8fc54b0", + "data": {} +} +``` + +Failed response: + +```json +{ + "request_id": "0ace00116215abc0ba4e52449bd305b0", + "error": { + "code": "InvalidParameter", + "message": "Key: 'ChangeEvent.ChangeStatus' Error:Field validation for 'ChangeStatus' failed on the 'oneof' tag" + } +} +``` ## Best Practices @@ -35,6 +151,7 @@ Labels describe events and should be as rich as possible: - **Change scope**: such as host, cluster, etc. - **Change ownership**: such as team, owner, etc. +- **Change lifecycle**: use the same `change_key` to report different `change_status` values as the change moves through planned, processing, completed, or canceled states. This helps restore the change process on the incident timeline. ## FAQ diff --git a/en/on-call/integration/instant-messaging/lark.mdx b/en/on-call/integration/instant-messaging/lark.mdx index cef25d96..aae3261c 100644 --- a/en/on-call/integration/instant-messaging/lark.mdx +++ b/en/on-call/integration/instant-messaging/lark.mdx @@ -148,10 +148,11 @@ Only one IM integration can have War Room enabled at a time. If you've already e ### AI SRE Controls -After you enable **War Room**, the configuration page shows the following AI SRE controls. Both are enabled by default: +Configure the following AI SRE controls separately under **Enhanced Features**. They are enabled by default: -- **Automatically start AI incident analysis**: Starts an AI incident analysis when a War Room is created successfully. -- **Allow group @ AI SRE**: Lets users start a conversation by @mentioning AI SRE in a group chat connected through this integration. When disabled, this entry point does not respond. +- **Automatically start AI incident analysis**: Available after you enable War Room. Starts an AI incident analysis when a War Room is created successfully. +- **Allow group @ AI SRE**: Available without enabling War Room. Lets users start a conversation by @mentioning AI SRE in a group chat connected through this integration. When disabled, this entry point does not respond. +- **Use thread replies in normal group chats**: Available without enabling War Room. When enabled, each normal-group thread has an independent session; War Rooms still receive replies directly in the group. These controls do not take effect until AI SRE is enabled for the account. diff --git a/en/on-call/integration/instant-messaging/slack.mdx b/en/on-call/integration/instant-messaging/slack.mdx index 3b2212b7..83ae14aa 100644 --- a/en/on-call/integration/instant-messaging/slack.mdx +++ b/en/on-call/integration/instant-messaging/slack.mdx @@ -68,10 +68,11 @@ After completing the previous steps, in the Flashduty On-call integration config ### AI SRE Controls -After you enable **War Room**, the configuration page shows the following AI SRE controls. Both are enabled by default: +Configure the following AI SRE controls separately under **Enhanced Features**. They are enabled by default: -- **Automatically start AI incident analysis**: Starts an AI incident analysis when a War Room is created successfully. -- **Allow group @ AI SRE and /fd commands**: Lets users @mention AI SRE or use `/fd` in a Slack group connected through this integration. When disabled, neither entry point responds. +- **Automatically start AI incident analysis**: Available after you enable War Room. Starts an AI incident analysis when a War Room is created successfully. +- **Allow group @ AI SRE and /fd commands**: Available without enabling War Room. Lets users @mention AI SRE or use `/fd` in a Slack group connected through this integration. When disabled, neither entry point responds. +- **Use thread replies in normal group chats**: Available without enabling War Room. When enabled, each normal-group thread has an independent session; War Rooms still receive replies directly in the group. These controls do not take effect until AI SRE is enabled for the account. diff --git a/en/openapi/api-catalog.mdx b/en/openapi/api-catalog.mdx index e98f0d16..91583ed9 100644 --- a/en/openapi/api-catalog.mdx +++ b/en/openapi/api-catalog.mdx @@ -3,13 +3,13 @@ title: "API Catalog" description: "Complete list of Flashduty Open API endpoints, organized by product module with links to detailed documentation" --- -Flashduty Open API provides **289** endpoints covering five major modules: On-call, Monitors, RUM, AI SRE, and Platform. All endpoints use unified authentication and request specifications. See [Quick Start](/en/openapi/introduction) for details. +Flashduty Open API provides **290** endpoints covering five major modules: On-call, Monitors, RUM, AI SRE, and Platform. All endpoints use unified authentication and request specifications. See [Quick Start](/en/openapi/introduction) for details. All endpoint URLs use `https://api.flashcat.cloud` as the base, authenticated via APP Key through query string. - + ### Incidents @@ -55,6 +55,7 @@ All endpoint URLs use `https://api.flashcat.cloud` as the base, authenticated vi | POST | [`/incident/post-mortem/template/delete`](/en/api-reference/on-call/incidents/postmortem-write-delete-template) | Delete post-mortem template | | POST | [`/incident/post-mortem/template/list`](/en/api-reference/on-call/incidents/postmortem-read-list-templates) | List post-mortem templates | | GET | [`/incident/post-mortem/template/info`](/en/api-reference/on-call/incidents/postmortem-read-template-info) | Get post-mortem template detail | +| POST | [`/incident/sdp/request/list`](/en/api-reference/on-call/incidents/incident-service-desk-plus-request-read-list) | Get ServiceDeskPlus linked incidents | ### Channels diff --git a/en/platform/permission-design.mdx b/en/platform/permission-design.mdx index 08671feb..7b03e50a 100644 --- a/en/platform/permission-design.mdx +++ b/en/platform/permission-design.mdx @@ -25,10 +25,10 @@ Flashduty **controls functional permissions based on roles (RBAC)**, with permis Has all permissions. Suitable for core members who need complete management capabilities. The Admin permission bitmap queries `account_id IN (0, current account ID)` with no upper bound on permission IDs, so it **automatically includes** every custom menu visit permission for that account — no explicit role binding required. - Has all **system** permissions except "Payment Center", "Members Manage", "Roles Manage", and "SSO Manage". Suitable for members handling daily operations work. The Responder query adds an `id < 100000` filter. Custom menu permission IDs are Snowflake-generated (far above 100000), so Responder does **not** automatically inherit any custom menu access — each menu must be explicitly bound to this role via the menu's `role_ids` configuration. + Has all **system** permissions except "Payment Center", "Members Manage", "Roles Manage", and "SSO Manage". Suitable for members handling daily operations work. The Responder query includes system permissions and current-account permissions (`account_id IN (0, current account ID)`); permissions marked `admin_only=1` are excluded from the Responder preset role. Therefore, non-admin-only account-level dynamic permissions, including custom menu access permissions, are included automatically. - Has most read-only **system** permissions except "Audit" and "Onboarding". Suitable for members who only need to view data. Like Responder, Viewer is also subject to the `id < 100000` filter and does **not** automatically inherit custom menu access — explicit role binding is required per menu. + Has most read-only **system** permissions except "Audit" and "Onboarding". Suitable for members who only need to view data. Viewer is subject to the `id < 100000` filter and does **not** automatically inherit custom menu access — explicit role binding is required per menu. @@ -77,7 +77,8 @@ Custom menu is a standalone permission scope, displayed alongside Platform, On-c **Custom menu permissions follow different inheritance rules depending on the preset role:** - **Admin**: Automatically inherits every custom menu visit permission in the account — no additional configuration needed. -- **Responder / Viewer**: Do **not** automatically inherit custom menu permissions. These two preset roles build their permission bitmaps from a query filtered by `id < 100000`, which are the system-defined permission IDs. Custom menu permission IDs are Snowflake-generated and are always far above that threshold, so they are excluded. To allow a Responder or Viewer member to see a specific custom menu, you must explicitly add the corresponding role in that menu's role binding configuration (`role_ids` field). +- **Responder**: Automatically includes the current account's permission points where `admin_only=0`. Non-admin-only custom menu access permissions therefore need no additional role binding; permissions reserved for admins are excluded from the Responder preset role. +- **Viewer**: Does **not** automatically inherit custom menu permissions. The Viewer permission bitmap contains only system-defined permission IDs (`id < 100000`), while custom menu permission IDs are Snowflake-generated and far above that threshold. To allow a Viewer member to see a specific custom menu, explicitly add Viewer in that menu's role binding configuration (`role_ids` field). - **Custom roles**: Also do not automatically inherit custom menu permissions; explicit binding per menu is required. diff --git a/zh/ai-sre/apps.mdx b/zh/ai-sre/apps.mdx index 1bb0b20c..54baf5cb 100644 --- a/zh/ai-sre/apps.mdx +++ b/zh/ai-sre/apps.mdx @@ -1,7 +1,7 @@ --- title: Apps -description: Apps 是 AI SRE 中管理「已授权的外部应用」的地方,每个应用以一张卡片呈现,目前是 GitHub 与 GitLab。授权后,AI SRE 能在会话里直接进入你的代码仓库:读代码、调查变更 / 提交 / PR(或 MR)、追溯 PR / MR,并在你需要时改缺陷、开 PR / MR、提 issue。它主要让云端沙箱也能安全地访问你的仓库。 -keywords: ["AI SRE", "Apps", "App", "GitHub", "GitHub App", "GitLab", "GitLab App", "代码仓库", "gh", "glab", "git", "Pull Request", "Merge Request", "MR", "Issue", "云端沙箱", "Customize"] +description: Apps 用于管理 AI SRE 已授权的外部应用,包括 GitHub、GitLab 与 Kubernetes App。你可以授权代码仓库,或将 Kubernetes 集群以指定的 namespace 与权限边界接入 AI SRE。 +keywords: ["AI SRE", "Apps", "App", "GitHub", "GitHub App", "GitLab", "GitLab App", "Kubernetes", "Kubernetes App", "K8s", "代码仓库", "集群", "namespace", "gh", "glab", "git", "Pull Request", "Merge Request", "MR", "Issue", "云端沙箱", "Customize"] sidebarTitle: Apps --- @@ -15,7 +15,7 @@ sidebarTitle: Apps **Apps** 是管理「已授权的外部应用」的地方。每个外部应用以一张**应用卡片**呈现——你在它的卡片上完成授权、管理安装、并随时启停或撤销。 -Apps 下目前有 **GitHub** 与 **GitLab** 两个应用,覆盖最常见的代码托管平台。授权其中之一后,AI SRE 就能在会话里**直接进入你的代码仓库工作**:读懂并探索代码、调查最近的变更 / 提交 / PR(GitLab 里是 MR)、从一张变更工单追溯到对应 PR / MR、回答关于代码库的问题,并在你需要时改一处缺陷、开一个 PR / MR 或提一个 issue——全程用原生 `gh` / `glab` / `git`,就像一名工程师在终端里干活。 +Apps 包含 **GitHub**、**GitLab** 和 **Kubernetes App**。GitHub 与 GitLab 用于授权代码仓库:AI SRE 可以在会话中读代码、调查变更 / 提交 / PR(GitLab 中为 MR),并按需修改缺陷、创建 PR / MR 或 issue。Kubernetes App 则把指定 Kubernetes 集群接入 AI SRE,并通过配置的 namespace 与权限边界限制 Agent 的操作范围。 ## 主要场景:让云端沙箱访问你的仓库 @@ -37,6 +37,34 @@ AI SRE 的会话默认运行在 **Flashduty 云端沙箱**里。沙箱是干净 查看 Apps 标签页需要相应权限;没有权限时该标签页不可见。授权、断开 / 撤销、启用 / 禁用各自还需对应的操作权限——无权限时对应按钮以禁用态显示。 +## Kubernetes App + +--- + +Kubernetes App 将集群中的 Agent 接入 AI SRE。创建后,AI SRE 可以在授权范围内查询集群信息并执行可用的 Kubernetes 工具;它只能访问你在配置中指定的 namespace 和权限级别。 + +### 创建并安装 + + + + 进入 **插件 → Apps → Kubernetes App**,点击 **创建 Kubernetes App**。填写集群名称,并选择范围:**共享** 可供账户内所有会话使用;**团队** 可供该团队会话及该团队成员的个人会话使用。同一范围内的集群名称不能重复。 + + + 选择 **全部 namespace** 或 **指定 namespace**。全部 namespace 会把同一权限应用到当前和未来的 namespace;指定 namespace 可以为每个 namespace 单独选择 **只读** 或 **读取 + 有限修改**。不填写指定 namespace 时,Agent 只能读取集群基础元数据。 + + + 保存后复制控制台生成的安装命令,并在目标集群中执行。安装命令会过期;过期后重新打开安装配置或查看 Manifest 生成新命令,无需轮换 Token。 + + + + +修改 namespace 或权限后,必须重新执行安装命令,集群中的 RBAC 才会更新。选择 **读取 + 有限修改** 前,请确认该 namespace 中允许 AI SRE 执行相应操作。 + + +### 编辑与撤销 + +你可以在 Kubernetes App 列表中编辑集群名称、范围和 namespace 权限。撤销会立即使连接和 Token 失效,但不会自动删除集群中的 Agent 与 RBAC。控制台会提供卸载命令;请在对应集群执行它。该命令只删除当前 Kubernetes App 的资源,不会删除共享的 `flashduty` namespace。 + ## GitHub 应用 --- diff --git a/zh/ai-sre/artifacts.mdx b/zh/ai-sre/artifacts.mdx index 5dec7e68..6524c4be 100644 --- a/zh/ai-sre/artifacts.mdx +++ b/zh/ai-sre/artifacts.mdx @@ -1,6 +1,6 @@ --- title: 产物 -description: 产物库集中呈现 AI SRE 会话中用 present_files 工具产出、再经 publish_artifact 工具发布的网页与报告(例如 /insight 报告),支持搜索、按范围筛选、重命名、分享、下载与删除。 +description: 产物库集中呈现 AI SRE 会话中用 present_files 工具产出、再经 publish_artifact 工具发布的网页与报告(例如 /insight 报告),支持搜索、按范围筛选与修改范围、重命名、分享、下载和删除。 keywords: ["AI SRE", "产物", "Artifacts", "present_files", "publish_artifact", "insight 报告", "产物库"] sidebarTitle: 产物 --- @@ -15,7 +15,7 @@ sidebarTitle: 产物 产物(Artifact)是 AI SRE 在会话中用 `present_files` 工具产出、再经 `publish_artifact` 工具发布到产物库的文件——通常是一份自包含的 HTML 报告或页面。例如在会话里输入 `/insight` 生成的运营洞察报告,就是一种产物。 -发布后的产物会继承来源会话的作用域:来自个人会话的产物归创建者「个人」所有;来自绑定了团队的会话的产物归该「团队」所有,可分享给账户内的其它成员查看。 +发布后的产物初始继承来源会话的作用域:来自个人会话的产物归创建者「个人」所有;来自绑定了团队的会话的产物归该「团队」所有,可分享给账户内的其它成员查看。拥有编辑权限时,之后还可以修改产物范围。 入口:左侧导航 **AI SRE → 产物**,对应路由 `/ai-sre/artifacts`。 @@ -66,6 +66,7 @@ Agent 会先向你确认目标读者、内容/数据来源、交互与视觉风 | 复制链接 | 复制该产物详情页的完整 URL,可分享给账户内的其它成员打开 | | 下载 | 仅当产物关联着文件(`file_id` 非空)时出现,下载原始文件 | | 重命名 | 仅当你对该产物有编辑权限时出现;打开一个对话框修改标题 | +| 修改范围 | 仅当你对该产物有编辑权限时出现;选择个人或可访问的团队。只有产物创建者可以将范围改为个人 | | 删除 | 仅当你对该产物有编辑权限时出现;删除前需二次确认,删除后产物从产物库移除,但来源会话与文件本身保留不受影响 | ## 详情页 @@ -81,6 +82,7 @@ Agent 会先向你确认目标读者、内容/数据来源、交互与视觉风 - **更多操作**:只有以下至少一项可用时才会出现这个菜单—— - **打开会话**:仅当产物的来源会话你仍有权限访问时出现,点击跳转到该会话的完整对话(消息、工具调用、产物历史); - **下载**:仅当产物关联着文件时出现。 + - **修改范围**:仅当你有编辑权限时出现,可将产物移至可访问的团队;产物创建者还可以改回个人范围。 正文区域按产物的实际内容类型渲染(例如 HTML 报告会直接内联展示为页面)。 @@ -88,7 +90,7 @@ Agent 会先向你确认目标读者、内容/数据来源、交互与视觉风 --- -产物是否可编辑(重命名、删除)由后端返回的 `can_edit` 字段决定,满足以下任一条件即可管理该产物: +产物是否可编辑(重命名、修改范围、删除)由后端返回的 `can_edit` 字段决定,满足以下任一条件即可管理该产物: | 条件 | 说明 | |---|---| diff --git a/zh/ai-sre/im.mdx b/zh/ai-sre/im.mdx index 94317dd0..b48b952f 100644 --- a/zh/ai-sre/im.mdx +++ b/zh/ai-sre/im.mdx @@ -47,10 +47,11 @@ IM 交互依赖你已在 Flashduty 中接入对应平台的机器人(用于告 --- -在 **On-call → 集成中心 → 集成列表 → 即时消息** 打开对应 IM 集成详情,并在 **增强功能** 中开启作战室后,可以配置该集成的 AI SRE 行为。以下两个开关默认开启: +在 **On-call → 集成中心 → 集成列表 → 即时消息** 打开对应 IM 集成详情,在 **增强功能** 中分别配置该集成的 AI SRE 行为。以下开关默认均为开启: -- **自动发起 AI 故障分析**:集成成功创建作战室时,自动发起一次 AI SRE 初步诊断并把结果回贴到作战室。 -- **允许群聊 @ AI SRE**:允许群聊中的 @ 提及进入 AI SRE。Slack 中该开关显示为 **允许群聊 @ AI SRE 和 /fd 命令**;关闭后,群聊 @ 提及和 `/fd` 命令都不会触发 AI SRE。 +- **自动发起 AI 故障分析**:开启作战室后可配置;集成成功创建作战室时,自动发起一次 AI SRE 初步诊断并把结果回贴到作战室。 +- **允许群聊 @ AI SRE**:无需开启作战室即可配置,允许群聊中的 @ 提及进入 AI SRE。Slack 中该开关显示为 **允许群聊 @ AI SRE 和 /fd 命令**;关闭后,群聊 @ 提及和 `/fd` 命令都不会触发 AI SRE。 +- **普通群聊中 AI SRE 使用话题回复**:仅飞书/Lark 与 Slack 提供。开启后,普通群聊中的每个话题对应一个独立 Session;作战室仍直接在群内回复。 若账户尚未开通 AI SRE,这些开关不会实际生效;开通后会按各 IM 集成自己的设置生效。 diff --git a/zh/ai-sre/knowledge.mdx b/zh/ai-sre/knowledge.mdx index fbb77219..0c496b34 100644 --- a/zh/ai-sre/knowledge.mdx +++ b/zh/ai-sre/knowledge.mdx @@ -73,7 +73,7 @@ Agent 读取 `DUTY.md` 后,会根据当前故障判断需要展开哪些 `@引 - 点击页面右上角的 **创建**,弹出「创建知识库」对话框。Knowledge Pack 本身没有可编辑的名称——它是按目标(账户或团队)的单例资源,弹窗里只需选择 **范围**:账户或某个团队。创建团队级 Pack 时,您必须是目标团队成员;账户级创建仅限账户 Owner 或管理员。每个目标只能拥有一个 Pack,已被占用的目标会从下拉中隐藏。选定范围后点击 **新建** 完成创建;控制台用范围(账户 / 团队名)作为该 Pack 的显示标识。 + 点击页面右上角的 **创建**,弹出「创建知识库」对话框。Knowledge Pack 本身没有可编辑的名称——它是按目标(账户或团队)的单例资源,弹窗里只需选择 **范围**:账户或某个团队。创建团队级 Pack 时,您必须是目标团队成员;账户级创建仅限账户 Owner 或管理员。每个目标只能拥有一个 Pack。已有 Pack 的账户或团队仍会出现在下拉列表中,并标记为「已有知识库」;选择后主按钮变为 **打开知识库**,点击即可直接进入该 Pack,不会重复创建。选择没有 Pack 的范围后,点击 **新建** 完成创建;提交前控制台会再次检查,若该范围刚被其他人创建为 Pack,则改为打开已有 Pack。控制台用范围(账户 / 团队名)作为该 Pack 的显示标识。 点击列表中的某一行打开检视器。左侧是文件树,右侧是行内编辑器。点击 **新建文件** 输入文件名(如 `runbook.md`),或用 **上传** 导入本地文件;Markdown 文件支持 **预览** 与 **源码** 两种视图。编辑后点击 **保存**。 diff --git a/zh/ai-sre/sessions.mdx b/zh/ai-sre/sessions.mdx index 9a9a8bcf..cddf1b2d 100644 --- a/zh/ai-sre/sessions.mdx +++ b/zh/ai-sre/sessions.mdx @@ -208,9 +208,9 @@ Agent 产出的文件会以产物形式提供预览。点击产物即在右侧 ### Fork 会话 -当一个回合已经完整结束后,Agent 回复右侧会出现 **Fork** 按钮。点击后会弹出「从之前的消息派生?」对话框:默认沿用源会话的运行环境与归属团队,您也可以在对话框内切换到其他在线的 BYOC Runner,或改绑到个人 / 其他团队;点击 **确认** 后才会从该回复所在的回合派生一个新会话,并自动打开。 +当一个回合已经完整结束后,Agent 回复右侧会出现 **Fork** 按钮。点击后会弹出「Fork 新对话」对话框:对话框会以源会话的范围和运行环境作为预填建议,但 Fork 必须明确选择目标范围与运行环境。你可以选择个人或可访问的团队,并从 **自动**、云端 Sandbox 或在线的 BYOC Runner 中选择运行环境;点击 **确认** 后才会从该回复所在的回合派生一个新会话,并自动打开。 -Fork 适合在同一段排查上下文上尝试另一条路线:新会话保留截至所选回合为止的对话与工具调用记录;环境与团队默认与源会话一致,但由您在派生对话框中确认或主动切换,而非单纯沿用原绑定。后续回合不会带入新会话。新会话会写入一条「由 Chat 派生」分隔线,点击分隔线可回到原会话的来源位置。 +Fork 适合在同一段排查上下文上尝试另一条路线:新会话保留截至所选回合为止的对话与工具调用记录,但不会在后端继承源会话的环境绑定。环境选项会按目标范围过滤;如果你不属于源团队,系统会改为个人范围;如果源环境已删除、离线、从未连接,或不属于目标范围,系统会改为 **自动**。后续回合不会带入新会话。新会话会写入一条「由 Chat 派生」分隔线,点击分隔线可回到原会话的来源位置。 只能从**已经完成**的主会话回合 Fork。源会话仍在运行、所选回合尚未完成,或目标是 Subagent 子会话时,系统会拒绝 Fork。 diff --git a/zh/compliance/ai-sre-credit-package-purchase-agreement.mdx b/zh/compliance/ai-sre-credit-package-purchase-agreement.mdx new file mode 100644 index 00000000..acd40053 --- /dev/null +++ b/zh/compliance/ai-sre-credit-package-purchase-agreement.mdx @@ -0,0 +1,104 @@ +--- +title: "AI SRE credits 资源包购买协议" +description: "购买 AI SRE credits 资源包前,请了解适用范围、计费、有效期、抵扣顺序和退款规则。" +keywords: ["AI SRE", "credits", "资源包", "购买协议", "按量付费", "退款"] +--- + +最后更新日期:2026-07-26 +协议版本:`ai-sre-credit-package-v1` + +本《AI SRE 资源包购买协议》(下称“本协议”)是 [Flashduty 服务条款](/zh/compliance/terms-of-service) 的补充。你在购买页勾选“我已阅读并同意”并提交订单,即表示你代表所在账户接受本协议;如与你和 Flashduty 另行签订的书面协议有冲突,以该书面协议为准。 + +## 适用范围 + +AI SRE 使用 credits 计量。资源包是一次性购买的账户级 credits,不是订阅、席位或自动续费服务。资源包可以在 AI SRE 已关闭时购买;但只有同时满足下面三个条件时才能使用 AI SRE: + +1. 账户已开通 AI SRE; +2. 账户持有有效的 On-call 专业版及以上订阅; +3. 发起使用的成员占用一个可用的 Flashduty 使用许可(与 On-call 等产品共用同一许可池,不是单独售卖的 AI SRE 许可)。 + +资源包在同一账户内共享,席位数量不影响资源包 credits。购买资源包不会自动开通 AI SRE,也不会替代上述订阅和许可要求。 + + +请先开通 AI SRE,再购买资源包。资源包的有效期从支付成功起算,而未开通 AI SRE 的账户不会产生任何 credits 消耗——先买后开通,资源包会在闲置中走完有效期。 + + +## 资源包与订单 + +当前可购买的固定资源包如下。每张订单购买一档资源包;如需更多 credits,请下多张订单——资源包不支持在同一张订单内按数量倍增。同一账户可以同时持有多张(同档或不同档的)资源包,credits 会累计使用。 + +| 资源包 | 单份 credits | 单份价格 | +| --- | ---: | ---: | +| 1,000 credits | 1,000 | ¥950 | +| 5,000 credits | 5,000 | ¥4,500 | +| 20,000 credits | 20,000 | ¥17,000 | + +购买页的询价和订单确认页会显示所选资源包与价格。该次询价/订单确认中显示并写入订单的价格和 credits 为本次交易的准据;Flashduty 可以调整后续新订单的资源包价格或档位,但不会追溯变更已支付订单的价格、credits 数量或有效期。 + +资源包自支付成功时起 365 天有效,到期后未使用的已购 credits 失效。资源包不自动续费,也不会自动补充。 + + +购买前请确认资源包档位和价格。资源包 credits 仅用于 AI SRE 抵扣,不能兑换现金、转让到其他账户或抵扣其他 Flashduty 产品费用。 + + +## credits 抵扣与按量付费 + +每次 AI SRE 消耗时,系统按以下顺序抵扣: + +1. Flashduty 可能不时向账户发放的赠送 credits(如有); +2. 未到期已购资源包中最早到期的 credits——多张资源包并存时,先消耗最早到期的一张; +3. 按量付费(PAYG)。 + +赠送 credits(如有发放)与本次购买无关,按 Flashduty 另行公布或告知的规则发放和计算,仅在发放所属的计费周期内可用,不跨周期累积、不可转让、不可退款;账户关闭 AI SRE 时,当时未使用的赠送 credits 将被清零,已购资源包的余额和有效期不受影响。 + +开通 AI SRE 即表示授权按量付费。按量部分按 `1 credit = ¥1` 从账户通用钱包结算。计费周期为账户所在计费时区下的自然月(每月 1 日至下月 1 日),到达月末自动开始下一周期,与 On-call 的计费周期或续费日期无关。 + +你可以在 AI SRE 计费页把按量付费设为三种状态之一: + +- **不限额**(默认):资源包用完后继续按量付费,不设上限; +- **设置月度上限**:本周期内按量付费最多消耗你设定的 credits 数; +- **禁止按量付费**:完全不使用按量付费,资源包用完后停止运行。 + +当赠送额度、已购资源包和已授权的按量额度都不足时,系统不再接受新的 AI SRE 运行。已经开始的一个顶层运行不会被中断,它后续产生的用量仍会照常计量。但计量不等于计费:**超出你当时可用 credits 与已授权按量额度的部分由 Flashduty 承担,不会向你收取**——按量付费的实际扣费金额不会超过你设定的上限,赠送和资源包余额也不会被扣成负数。 + +## 计费规则 + +### 哪些用量会消耗 credits + +AI SRE 的 credits 消耗来自三部分,各自独立计量: + +| 计费项 | 计量单位 | 当期单价 | +| --- | --- | ---: | +| 模型用量 | 每百万 token,分新输入 / 命中缓存的输入 / 输出三档 | 18 / 0.15 / 36 credits | +| 沙箱运行时长 | 按在线时长连续计量(毫秒精度,不按小时向上取整) | 8 credits / 小时 | +| 联网检索 | 每次成功的检索请求 | 0.25 credits | + +上表为 2026-07-26 的当期单价,仅供参考;实际以 Flashduty 公布的当期价格为准,Flashduty 可以调整后续用量的单价,但不会追溯变更已发生的扣减。模型单价绑定模型档位,不绑定具体供应商——即使后台因故障切换到成本更高的备用线路,你的单价也不变。 + +面向账户的计费页面只展示 credits,不展示模型 token 明细。credits 的计费事实由 AI SRE 运行时记录,结算和账单由 Flashduty 账户结算系统完成。 + +账户页面展示金额和 credits 时四舍五入到小数点后 2 位。内部计量和结算的精度远高于展示位数,展示时的四舍五入不改变实际结算结果。 + +### 计费与不计费的边界 + +- 计量从开通那一刻开始。开通 AI SRE 之前的历史用量不计费,也不会在开通后被追溯计费。 +- 只要模型调用产生了有效 token 用量,就按模型 token 计费;任务最终成功、失败或被停止不改变该部分费用。 +- 沙箱按**在线**时长计费。沙箱暂停期间不计费;沙箱计费与是否有任务在运行无关,只要沙箱处于在线状态就会计量,所以不再需要沙箱时请及时释放。 +- 检索请求返回错误时(例如检索服务不可用或请求无效),不计该次检索费用。检索成功但没有匹配结果,仍属于一次成功的检索请求,照常计费。 +- AI 生成内容仅供参考。你应结合自己的业务、权限和变更流程进行验证,并对采用、执行或不执行 AI 建议的决定负责。 + +### 账户欠费 + +按量付费从账户通用钱包结算。若账户钱包余额耗尽或出现欠费,Flashduty 会停用账户下按量付费类的资源,其中包括 AI SRE 服务本身——停用期间无法发起新的 AI SRE 运行。已购资源包属于预付费资源,不会因欠费被停用,其余额和有效期不受影响。账户补足余额后,因欠费被停用的资源会自动恢复。 + +## 退款 + +资源包不提供自助退款入口,退款以整份资源包为单位处理,不支持部分退款。如需申请退款,请联系 [support@flashcat.cloud](mailto:support@flashcat.cloud),并提供账户、订单号和申请原因,由 Flashduty 人工核验后处理。 + +一份资源包只有在**完全未使用**(该资源包的 credits 余额与初始发放数量一致,一 credit 都未消耗)且**未过期**时,才可以申请退款;已经消耗过 credits 的资源包(无论消耗多少),以及已过期的资源包,均不可退款。获批后,退款金额为该资源包对应订单的实付金额,通过 Flashduty 的正常退款渠道退回;同一份资源包不会被退款两次。赠送 credits 不可退款。 + +退款是否批准以核验结果、适用法律和双方另行约定为准。本协议不限制法律规定不得排除的退款权利。 + +## 协议变更与联系 + +Flashduty 可在适用法律允许的范围内更新本协议。对后续购买生效的变更会在购买页或本页面公布;已支付订单继续按订单确认时的资源包档位、价格和有效期执行。有关本协议或 AI SRE 资源包的问题,请联系 [support@flashcat.cloud](mailto:support@flashcat.cloud)。 diff --git a/zh/developer/cli.mdx b/zh/developer/cli.mdx index aa539c2f..36b4bd84 100644 --- a/zh/developer/cli.mdx +++ b/zh/developer/cli.mdx @@ -460,7 +460,7 @@ Showing 2 results (page 1, total 2). -机器可解析,完整数据,不截断。适合脚本、CI/CD 流水线消费。 +机器可解析。除下方列出的默认紧凑字段命令外,返回命令的完整响应数据;表格列截断不适用于 JSON。适合脚本、CI/CD 流水线消费。 ```bash flashduty incident list --json | jq '.[].title' @@ -468,7 +468,7 @@ flashduty incident list --json | jq '.[].title' -TOON(Token-Oriented Object Notation)输出完整数据且不截断,但对同构数组省去了 JSON 中每行重复的字段名,列表输出可显著减少 token 消耗,更适合喂给 AI / 智能体消费。 +TOON(Token-Oriented Object Notation)对同构数组省去了 JSON 中每行重复的字段名,列表输出可显著减少 token 消耗,更适合喂给 AI / 智能体消费。下方列出的默认紧凑字段命令会按其字段投影输出,并受大小限制。 ```bash flashduty incident list --output-format toon @@ -484,6 +484,25 @@ TOON 不能直接用 `jq` 解析;需要管道给 `jq` 时请改用 `--json`。 +### 结构化输出的字段投影 + +以下命令在 `json` 或 `toon` 输出时支持 `--fields`。用逗号分隔顶层响应字段;未知字段会直接报错,表格输出会忽略此参数。 + +| 命令 | 未指定 `--fields` 时的结构化输出 | 上限 | +| --- | --- | --- | +| `flashduty incident list` | `incident_id`、`title`、`incident_severity`、`progress`、`start_time`、`channel_id` | 16 KiB | +| `flashduty incident similar ` | `incident_id`、`title`、`incident_severity`、`progress`、`start_time`、`close_time`、`ack_time`、`alert_cnt`、`root_cause`、`score` | 16 KiB | +| `flashduty incident detail ` | 不指定 `--fields` 时返回完整详情;指定后只返回所选字段 | 仅投影输出为 8 KiB | +| `flashduty alert-event list` | `event_id`、`alert_id`、`event_severity`、`event_status`、`event_time`、`title` | 16 KiB | + +例如,只导出故障编号、标题和处理进度: + +```bash +flashduty incident list --json --fields incident_id,title,progress +``` + +投影后的结构化输出超过上限时,CLI 会在保留字段名的前提下截短过长的字符串,并以 `...` 标记;若非字符串字段本身已超过上限,命令会提示减少字段或结果数。`incident detail` 不使用 `--fields` 时不受该投影上限影响。 + ## Agent Skills Flashduty CLI 内置 10 个 Agent Skills,可让 Claude Code、Cursor、Codex、Gemini CLI、Windsurf 等 AI 编程代理通过 CLI 操作 Flashduty。 diff --git a/zh/monitors/targets/configure-targets.mdx b/zh/monitors/targets/configure-targets.mdx index 2f84ef42..1272e1e8 100644 --- a/zh/monitors/targets/configure-targets.mdx +++ b/zh/monitors/targets/configure-targets.mdx @@ -51,7 +51,6 @@ host: shell_exec: enabled: true - pipeline_max_segments: 3 default_max_lines: 200 cat_max_file_size: 20971520 user_allow_list: [] @@ -67,10 +66,6 @@ mongodb: [] mongodb_mongos: [] kafka: [] elasticsearch: [] - -script_tool: - enabled: false - dir: /opt/monit-agent/tools.d ``` ## locator_mappings @@ -121,7 +116,6 @@ locator_mappings: host: shell_exec: enabled: true - pipeline_max_segments: 3 default_max_lines: 200 cat_max_file_size: 20971520 user_allow_list: [] @@ -130,7 +124,10 @@ host: 建议: - 需要 AI-SRE 做主机现场诊断时,保持 `enabled: true`。只有受控的 shell 才能执行,放心开启。 -- 如果发现有些 shell 被内置护栏阻断,可以手工添加到 `user_allow_list`。只有确认命令安全、只读、不会输出敏感信息时才添加。 +- 命令偶尔被拦截时,可以由本机 root [人工审批该命令](/zh/monitors/targets/install-agent#人工审批被拦截的-shell-命令)。 +- 对于需要长期重复使用的命令,确认其安全、只读且不会输出敏感信息后,再将完整命令添加到 `user_allow_list`。 + +人工审批和 `user_allow_list` 都不能放开关机、重启、破坏系统或读取敏感凭据等高危操作。 如需紧急禁用某个工具,可以使用 `tool_policy.disabled_tools`: @@ -140,6 +137,8 @@ tool_policy: - shell.exec ``` +修改 `shell_exec.enabled` 或 `tool_policy.disabled_tools` 后,发送 SIGHUP reload 即可生效,无需重启 Agent。 + ## MySQL 如果需要诊断 MySQL,在 `mysql:` 中添加实例配置。推荐使用只读 MySQL 账号,并优先把密码放到独立凭据文件中: @@ -499,15 +498,3 @@ ES_PASSWORD= | `credential` | 如果 Elasticsearch 未启用安全认证,可以不配置。生产环境建议配置只读账号。 | Elasticsearch 不使用 `locator_mappings`,`cluster_name` 自动从集群获取作为页面上的对象地址。 - -## script_tool - -`script_tool` 用于接入自定义脚本工具。普通用户可以保持关闭: - -```yaml -script_tool: - enabled: false - dir: /opt/monit-agent/tools.d -``` - -只有在需要扩展自定义诊断能力,并且确认脚本来源和目录权限可控时,才建议开启。 diff --git a/zh/monitors/targets/install-agent.mdx b/zh/monitors/targets/install-agent.mdx index 8ed58109..add806d9 100644 --- a/zh/monitors/targets/install-agent.mdx +++ b/zh/monitors/targets/install-agent.mdx @@ -12,8 +12,8 @@ keywords: ["monit-agent", "Agent 安装", "Edge 地址", "系统服务", "监控 | 准备项 | 说明 | |---|---| -| Agent 安装包下载地址 | `https://static.flashcat.cloud/monitagent/monitagent-v0.0.27-linux-amd64.tar.gz`。如果是 arm 的 CPU,则把 `amd64` 换成 `arm64`。 | -| Edge 地址 | 例如 `ws://edge.example.com:6868` 或 `wss://edge.example.com:6868`。Edge 版本需要 `>= v0.46.0`,Edge 列表和安装方法[点此查看](https://console.flashcat.cloud/monit/engine/list)。 | +| Agent 安装包下载地址 | `https://static.flashcat.cloud/monitagent/monitagent-v0.1.6-linux-amd64.tar.gz`。如果是 arm 的 CPU,则把 `amd64` 换成 `arm64`。 | +| Edge 地址 | 例如 `ws://edge.example.com:6868` 或 `wss://edge.example.com:6868`。Edge 版本需要 `>= v0.47.0`,Edge 列表和安装方法[点此查看](https://console.flashcat.cloud/monit/engine/list)。 | | 本机对象地址 | 建议使用当前主机的固定内网 IP 或 DNS 名称,例如 `10.0.1.12`。不指定的话默认会使用本机默认路由对应的 IP。 | | 数据库/中间件只读账号 | 如需诊断 MySQL、Redis、PostgreSQL、MongoDB、Kafka、Elasticsearch 等服务,需提前准备对应的只读账号和凭据。 | @@ -27,8 +27,8 @@ Edge 地址必须带协议前缀,支持 `ws://`、`wss://`、`http://`、`http sudo mkdir -p /opt/monit-agent cd /opt/monit-agent -sudo curl -sfLO "https://static.flashcat.cloud/monitagent/monitagent-v0.0.27-linux-amd64.tar.gz" -sudo tar -xzf monitagent-v0.0.27-linux-amd64.tar.gz --strip-components=1 +sudo curl -sfLO "https://static.flashcat.cloud/monitagent/monitagent-v0.1.6-linux-amd64.tar.gz" +sudo tar -xzf monitagent-v0.1.6-linux-amd64.tar.gz --strip-components=1 sudo chmod +x ./monitagent ``` @@ -132,6 +132,30 @@ sudo journalctl -u monitagent -f sudo systemctl kill -s HUP monitagent ``` +## 人工审批被拦截的 Shell 命令 + +`shell.exec` 会自动执行符合内置安全规则的只读诊断命令。如果某条命令未通过自动规则,但你确认它可以在当前机器上执行,可以提前登录 Agent 所在的 Linux 主机,用 root 打开审批会话: + +```bash +sudo /opt/monit-agent/monitagent shell-approval +``` + +审批会话连接成功后会显示等待提示。出现待审批命令时,终端只展示命令本身和 10 秒倒计时: + +- 按回车批准当前批次中的全部命令。 +- 按 `n` 拒绝当前批次中的全部命令。 +- 10 秒内没有操作时自动拒绝;并发到达的后续命令会排队,并在显示后获得完整的 10 秒审批时间。 +- 没有待审批命令时,输入不会触发执行,终端会继续显示等待状态。 +- 按 `Ctrl-C` 退出审批会话。 + +同一台 Agent 同时只允许一个审批会话。如果已有会话且你需要接管,使用: + +```bash +sudo /opt/monit-agent/monitagent shell-approval --replace +``` + +只有 root 可以打开或接管会话。Agent 重启或会话断开时,待审批命令会被拒绝;重启后需要重新打开会话。关机、重启、破坏系统或读取敏感凭据等高危操作不能通过人工审批放开。 + ## 下一步 Agent 启动成功后,通常几秒内可以在监控对象页面看到一个主机对象。接下来可以继续阅读[配置监控对象](/zh/monitors/targets/configure-targets),在 `agent.yaml` 中添加数据库和中间件对象。 diff --git a/zh/monitors/targets/overview.mdx b/zh/monitors/targets/overview.mdx index dcda088b..8fa231a4 100644 --- a/zh/monitors/targets/overview.mdx +++ b/zh/monitors/targets/overview.mdx @@ -81,6 +81,6 @@ keywords: ["监控对象", "monit-agent", "AI-SRE", "对象接入", "现场诊 准备 Edge 地址,下载 Agent,并配置前台启动或系统服务。 - 配置主机、数据库、中间件和自定义脚本工具。 + 配置主机、数据库、中间件和受控诊断工具。 diff --git a/zh/monitors/targets/reload-and-verify.mdx b/zh/monitors/targets/reload-and-verify.mdx index 2ddf942f..55538ccd 100644 --- a/zh/monitors/targets/reload-and-verify.mdx +++ b/zh/monitors/targets/reload-and-verify.mdx @@ -10,7 +10,7 @@ keywords: ["monit-agent", "配置生效", "SIGHUP", "重启 Agent", "接入验 | 变更内容 | 生效方式 | |---|---| -| `agent.yaml` 中的主机采集、MySQL、Redis、PostgreSQL、MongoDB、Kafka、Elasticsearch 等配置 | 发送 SIGHUP reload | +| `agent.yaml` 中的主机采集、工具开关、MySQL、Redis、PostgreSQL、MongoDB、Kafka、Elasticsearch 等配置 | 发送 SIGHUP reload | | Edge 地址、Basic Auth、TLS、`hostLocator`、审计目录 | 重启 Agent | 发送 SIGHUP: @@ -29,6 +29,8 @@ sudo systemctl restart monitagent 如果只是新增或调整 `agent.yaml` 中的对象配置,优先使用 SIGHUP reload。只有启动参数或服务级参数变化时才需要重启。 +修改工具开关后,成功 reload 即可更新 Agent 当前可用的诊断工具,无需重启。 + ## 验证接入是否成功 启动 Agent 后,通常几秒内可以在监控对象页面看到一个主机对象。 diff --git a/zh/on-call/integration/change-integration/custom-event.mdx b/zh/on-call/integration/change-integration/custom-event.mdx index 7c292e0c..5c9b0880 100644 --- a/zh/on-call/integration/change-integration/custom-event.mdx +++ b/zh/on-call/integration/change-integration/custom-event.mdx @@ -28,7 +28,123 @@ Flashduty On-call 已适配部分常用工单、部署系统的 webhook 协议 ## 实现协议 -请参照 [开发文档](/zh/on-call/integration/change-integration/custom-event) 完成协议开发。 +### 请求描述 + +请求方式: + +```http +POST, Content-Type: application/json +``` + +请求地址为集成详情页展示的 **推送地址**,格式如下: + +```text +{api_host}/event/push/change/standard?integration_key={integration_key} +``` + +### 请求参数 + +#### Headers + +| 字段 | 必含 | 类型 | 说明 | +| :--- | :---: | :--- | :--- | +| Content-Type | 是 | string | 固定值:`application/json`。 | + +#### Query Strings + +| 字段 | 必含 | 类型 | 说明 | +| :--- | :---: | :--- | :--- | +| integration_key | 是 | string | 集成秘钥,用于访问控制。创建集成后可在推送地址中获取。 | + +#### Payload + +| 字段 | 必含 | 类型 | 说明 | +| :--- | :---: | :--- | :--- | +| title | 是 | string | 变更标题,例如发布单标题、工单标题或部署任务名称。 | +| change_key | 是 | string | 变更标识。相同 `change_key` 会被识别为同一个变更,后续事件会更新该变更的状态、标签和链接。 | +| change_status | 是 | string | 变更状态。枚举值(首字母大写):`Planned` 计划中、`Ready` 待执行、`Processing` 执行中、`Canceled` 已取消、`Done` 已完成。 | +| event_time | 否 | integer | 事件发生时间,Unix 时间戳。支持秒级或毫秒级时间戳;未传时使用 Flashduty 接收事件的时间。 | +| description | 否 | string | 变更描述,例如变更内容、影响范围、执行步骤或回滚方案。 | +| link | 否 | string | 变更详情链接,例如发布单、工单或 CI/CD 任务地址。 | +| labels | 否 | map | 变更标签集合,key 和 value 均为 string 类型。建议 key 遵循 Prometheus 标签命名规范;系统会将 key 中的空格、点号、斜杠等特殊字符替换为下划线。 | + + +当 `change_status` 为 `Done` 或 `Canceled` 时,Flashduty 会将该事件时间记录为变更结束时间;再次上报非结束状态时,结束时间会被清空。 + + +### 请求响应 + +| 字段 | 必含 | 类型 | 说明 | +| :--- | :---: | :--- | :--- | +| request_id | 是 | string | 请求 ID,用于链路追踪。 | +| error | 否 | [Error](#error) | 错误描述,仅当出现错误时返回。 | +| data | 否 | object | 上报成功时返回空对象。 | + +#### Error + +| 字段 | 必含 | 类型 | 说明 | +| :--- | :---: | :--- | :--- | +| code | 是 | string | 错误码,枚举值参考 [Code](#code)。 | +| message | 否 | string | 错误描述。 | + +#### Code + +| 错误码 | HTTP Status | 说明 | +| :--- | :---: | :--- | +| InvalidParameter | 400 | 参数错误,例如缺少必填字段、状态枚举值不合法或集成秘钥无效。 | +| InvalidContentType | 400 | `Content-Type` 不支持。 | +| MethodNotAllowed | 405 | HTTP Method 不支持。 | +| Unauthorized | 401 | 登录认证未通过。 | +| AccessDenied | 403 | 权限认证未通过。 | +| RequestTooFrequently | 429 | 请求过于频繁。 | +| RouteNotFound | 404 | 请求 Method 和 Path 未匹配。 | +| ResourceNotFound | 400 | 账户未购买资源,请先前往费用中心下单。 | +| NoLicense | 400 | 账户无充足订阅 License,请先升级或购买订阅。 | +| InternalError | 500 | 内部或未知错误。 | + +### 请求示例 + +请求: + +```bash +curl -X POST '{api_host}/event/push/change/standard?integration_key={integration_key}' \ + -H 'Content-Type: application/json' \ + -d '{ + "title": "order-service v1.12.0 production release", + "change_key": "deploy-order-service-202607231030", + "change_status": "Processing", + "event_time": 1784773800, + "description": "Deploy order-service v1.12.0 to production cluster cn-shanghai-prod.", + "link": "https://deploy.example.com/releases/deploy-order-service-202607231030", + "labels": { + "service": "order-service", + "env": "prod", + "cluster": "cn-shanghai-prod", + "owner": "sre" + } + }' -v +``` + +成功响应: + +```json +{ + "request_id": "0ace00116215ab4ca0ec5244b8fc54b0", + "data": {} +} +``` + +失败响应: + +```json +{ + "request_id": "0ace00116215abc0ba4e52449bd305b0", + "error": { + "code": "InvalidParameter", + "message": "Key: 'ChangeEvent.ChangeStatus' Error:Field validation for 'ChangeStatus' failed on the 'oneof' tag" + } +} +``` ## 最佳实践 @@ -36,6 +152,7 @@ Flashduty On-call 已适配部分常用工单、部署系统的 webhook 协议 - **变更的应用范围**:如 host、cluster 等 - **变更的归属信息**:如 team、owner 等 +- **变更的生命周期**:同一个变更在计划、执行、完成或取消时,使用相同 `change_key` 持续上报不同 `change_status`,便于在故障时间线上还原变更过程 ## 常见问题 @@ -55,4 +172,3 @@ Flashduty On-call 已适配部分常用工单、部署系统的 webhook 协议 如果以上步骤执行后仍未找到问题根因,请 **携带请求响应中的 request_id** 联系我们。 - diff --git a/zh/on-call/integration/instant-messaging/lark.mdx b/zh/on-call/integration/instant-messaging/lark.mdx index 0e32edeb..90e32f9d 100644 --- a/zh/on-call/integration/instant-messaging/lark.mdx +++ b/zh/on-call/integration/instant-messaging/lark.mdx @@ -149,10 +149,11 @@ keywords: ["飞书", "Lark", "即时消息", "告警通知", "IM集成"] ### AI SRE 控制项 -开启 **作战室** 后,配置页会显示以下 AI SRE 控制项,默认均为开启: +在 **增强功能** 中分别配置以下 AI SRE 控制项,默认均为开启: -- **自动发起 AI 故障分析**:作战室创建成功后,自动发起一次 AI 故障分析。 -- **允许群聊 @ AI SRE**:允许在此集成已接入的群聊中 @ AI SRE 发起对话;关闭后不会响应该入口。 +- **自动发起 AI 故障分析**:开启作战室后可配置;作战室创建成功后,自动发起一次 AI 故障分析。 +- **允许群聊 @ AI SRE**:无需开启作战室即可配置,允许在此集成已接入的群聊中 @ AI SRE 发起对话;关闭后不会响应该入口。 +- **普通群聊中 AI SRE 使用话题回复**:无需开启作战室即可配置。开启后,普通群聊中的每个话题对应一个独立 Session;作战室仍直接在群内回复。 如果账户尚未启用 AI SRE,以上配置暂不生效。 diff --git a/zh/on-call/integration/instant-messaging/slack.mdx b/zh/on-call/integration/instant-messaging/slack.mdx index 1bccad52..24c8cc33 100644 --- a/zh/on-call/integration/instant-messaging/slack.mdx +++ b/zh/on-call/integration/instant-messaging/slack.mdx @@ -69,10 +69,11 @@ keywords: ["Slack", "即时消息", "告警通知", "IM集成", "协作工具"] ### AI SRE 控制项 -开启 **作战室** 后,配置页会显示以下 AI SRE 控制项,默认均为开启: +在 **增强功能** 中分别配置以下 AI SRE 控制项,默认均为开启: -- **自动发起 AI 故障分析**:作战室创建成功后,自动发起一次 AI 故障分析。 -- **允许群聊 @ AI SRE 和 /fd 命令**:允许在此集成已接入的 Slack 群聊中 @ AI SRE 或使用 `/fd` 命令;关闭后两个入口都不会响应。 +- **自动发起 AI 故障分析**:开启作战室后可配置;作战室创建成功后,自动发起一次 AI 故障分析。 +- **允许群聊 @ AI SRE 和 /fd 命令**:无需开启作战室即可配置,允许在此集成已接入的 Slack 群聊中 @ AI SRE 或使用 `/fd` 命令;关闭后两个入口都不会响应。 +- **普通群聊中 AI SRE 使用话题回复**:无需开启作战室即可配置。开启后,普通群聊中的每个话题对应一个独立 Session;作战室仍直接在群内回复。 如果账户尚未启用 AI SRE,以上配置暂不生效。 diff --git a/zh/openapi/api-catalog.mdx b/zh/openapi/api-catalog.mdx index dab7ade6..69f93598 100644 --- a/zh/openapi/api-catalog.mdx +++ b/zh/openapi/api-catalog.mdx @@ -3,13 +3,13 @@ title: "API 目录" description: "Flashduty Open API 接口完整列表,按产品模块组织并链接到详细文档" --- -Flashduty Open API 提供 **289** 个接口,覆盖 On-call、Monitors、RUM、AI SRE 和平台五个主要模块。所有接口使用统一认证方式和请求规范。详情参见[快速开始](/zh/openapi/introduction)。 +Flashduty Open API 提供 **290** 个接口,覆盖 On-call、Monitors、RUM、AI SRE 和平台五个主要模块。所有接口使用统一认证方式和请求规范。详情参见[快速开始](/zh/openapi/introduction)。 所有接口 URL 均以 `https://api.flashcat.cloud` 为 base,通过 query string 中的 APP Key 认证。 - + ### 故障管理 @@ -55,6 +55,7 @@ Flashduty Open API 提供 **289** 个接口,覆盖 On-call、Monitors、RUM、 | POST | [`/incident/post-mortem/template/delete`](/zh/api-reference/on-call/incidents/postmortem-write-delete-template) | 删除故障复盘模板 | | POST | [`/incident/post-mortem/template/list`](/zh/api-reference/on-call/incidents/postmortem-read-list-templates) | 查询故障复盘模板列表 | | GET | [`/incident/post-mortem/template/info`](/zh/api-reference/on-call/incidents/postmortem-read-template-info) | 查看故障复盘模板详情 | +| POST | [`/incident/sdp/request/list`](/zh/api-reference/on-call/incidents/incident-service-desk-plus-request-read-list) | 获取 ServiceDeskPlus 关联故障 | ### 协作空间 diff --git a/zh/platform/permission-design.mdx b/zh/platform/permission-design.mdx index 97b659b7..3554e00f 100644 --- a/zh/platform/permission-design.mdx +++ b/zh/platform/permission-design.mdx @@ -25,10 +25,10 @@ Flashduty **基于角色(RBAC)来控制功能权限**,按模块划分权 拥有所有权限,适用于需要完整管理能力的核心成员。Admin 的权限位图查询范围为 `account_id IN (0, 当前账户 ID)`,因此会**自动包含**该账户下所有自定义菜单的访问权限点,无需单独绑定。 - 拥有除「费用中心」「成员管理」「角色管理」「单点登录管理」外的全部**系统权限**,适用于处理日常运维工作的成员。Responder 的权限查询附加了 `id < 100000` 过滤条件,自定义菜单权限点的 ID 为 Snowflake 生成(远大于 100000),因此 Responder **不会**自动获得任何自定义菜单的访问权限——需在自定义菜单的角色绑定中显式授权。 + 拥有除「费用中心」「成员管理」「角色管理」「单点登录管理」外的全部**系统权限**,适用于处理日常运维工作的成员。Responder 的权限查询范围为系统权限和当前账户权限(`account_id IN (0, 当前账户 ID)`),其中标记为 `admin_only=1` 的权限会从 Responder 预置角色中排除。因此,非管理员专用的账户级动态权限(包括自定义菜单访问权限)会自动包含。 - 拥有除「审计」「快速开始」外的绝大部分只读**系统权限**,适用于仅需查看数据的成员。与 Responder 相同,Viewer 同样受 `id < 100000` 过滤限制,**不会**自动获得任何自定义菜单的访问权限,需在自定义菜单中显式授权。 + 拥有除「审计」「快速开始」外的绝大部分只读**系统权限**,适用于仅需查看数据的成员。Viewer 受 `id < 100000` 过滤限制,**不会**自动获得任何自定义菜单的访问权限,需在自定义菜单中显式授权。 @@ -77,7 +77,8 @@ Flashduty 的权限点分为两类: **自定义菜单权限与预置角色的继承规则不同:** - **Admin**:自动继承账户内所有自定义菜单的访问权限,无需任何额外配置。 -- **Responder / Viewer**:**不会**自动继承自定义菜单权限。这两个预置角色的权限位图只包含系统预定义的权限点(`id < 100000`),而自定义菜单权限点的 ID 由 Snowflake 算法生成,远超该阈值,因此会被过滤掉。如需让 Responder 或 Viewer 成员访问某个自定义菜单,必须在该菜单的角色绑定配置(`role_ids` 字段)中显式添加对应角色。 +- **Responder**:会自动包含当前账户中 `admin_only=0` 的权限点。因此,非管理员专用的自定义菜单访问权限无需额外角色绑定;标记为管理员专用的权限会从 Responder 预置角色中排除。 +- **Viewer**:不会自动继承自定义菜单权限。Viewer 的权限位图只包含系统预定义的权限点(`id < 100000`),而自定义菜单权限点的 ID 由 Snowflake 算法生成,远超该阈值,因此会被过滤掉。如需让 Viewer 成员访问某个自定义菜单,必须在该菜单的角色绑定配置(`role_ids` 字段)中显式添加 Viewer。 - **自定义角色**:自定义角色同样不会自动继承自定义菜单权限,需在菜单的角色绑定中显式授权。