From 9f3327e7dd1fd4e872f8148cfc2688f944488441 Mon Sep 17 00:00:00 2001 From: pijiang <419471640@qq.com> Date: Mon, 14 Sep 2026 13:40:50 +0800 Subject: [PATCH 01/14] docs(integration): add New Relic alert setup --- docs.json | 2 + .../alert-sources/new-relic.mdx | 112 +++++++++++++ integration-docs/src/doc-map.mjs | 1 + .../alert-sources/new-relic.mdx | 154 ++++++++++++++++++ 4 files changed, 269 insertions(+) create mode 100644 en/on-call/integration/alert-integration/alert-sources/new-relic.mdx create mode 100644 zh/on-call/integration/alert-integration/alert-sources/new-relic.mdx diff --git a/docs.json b/docs.json index d8e68309..aa7e0476 100644 --- a/docs.json +++ b/docs.json @@ -1680,6 +1680,7 @@ "zh/on-call/integration/alert-integration/alert-sources/prometheus", "zh/on-call/integration/alert-integration/alert-sources/grafana", "zh/on-call/integration/alert-integration/alert-sources/datadog", + "zh/on-call/integration/alert-integration/alert-sources/new-relic", "zh/on-call/integration/alert-integration/alert-sources/zabbix", "zh/on-call/integration/alert-integration/alert-sources/flashcat", "zh/on-call/integration/alert-integration/alert-sources/open-falcon", @@ -3048,6 +3049,7 @@ "en/on-call/integration/alert-integration/alert-sources/prometheus", "en/on-call/integration/alert-integration/alert-sources/grafana", "en/on-call/integration/alert-integration/alert-sources/datadog", + "en/on-call/integration/alert-integration/alert-sources/new-relic", "en/on-call/integration/alert-integration/alert-sources/zabbix", "en/on-call/integration/alert-integration/alert-sources/flashcat", "en/on-call/integration/alert-integration/alert-sources/open-falcon", diff --git a/en/on-call/integration/alert-integration/alert-sources/new-relic.mdx b/en/on-call/integration/alert-integration/alert-sources/new-relic.mdx new file mode 100644 index 00000000..2d5e8967 --- /dev/null +++ b/en/on-call/integration/alert-integration/alert-sources/new-relic.mdx @@ -0,0 +1,112 @@ +--- +title: "New Relic alert integration" +description: "Send New Relic Issues to Flashduty On-call through Workflow webhooks and correlate activation, update, and closure notifications." +keywords: ["alert integration", "New Relic", "Workflow", "webhook", "Issue"] +--- + +Use a New Relic Workflow webhook to send Issues to Flashduty On-call. One New Relic Issue maps to one Flashduty alert. Priority changes, Alert Event additions or closures, Issue merges, and closure notifications update that alert. + +
+ +## In Flashduty On-call +--- + +Create either a dedicated or shared **New Relic** alert integration and copy its complete Push URL. + +
+ +## Configure New Relic +--- + + + + +1. In New Relic, go to **Alerts → Enrich and Notify → Destinations** +2. Create a **Webhook** destination named `Flashduty` +3. Paste the complete Flashduty integration Push URL into Endpoint URL + + + + + +Create a Workflow whose Issue filters select the required policies, conditions, entities, or tags. Add the webhook destination. Enable at least **Activated** and **Closed**. Also enable **Priority changed** and **Other updates** to receive priority changes, Alert Event membership changes, and post-merge snapshots. + + + + + +```json +{ + "issue_id": "{{issueId}}", + "issue_url": {{json issuePageUrl}}, + "title": {{json issueTitle}}, + "description": {{json accumulations.conditionDescription.[0]}}, + "priority": "{{priority}}", + "state": "{{state}}", + "trigger_event": "{{triggerEvent}}", + "is_correlated": {{isCorrelated}}, + "account_id": {{nrAccountId}}, + "incident_ids": {{json incidentIds}}, + "sources": {{json accumulations.sources}}, + "policy_names": {{json accumulations.policyName}}, + "condition_names": {{json accumulations.conditionName}}, + "entity_names": {{json entitiesData.names}}, + "entity_ids": {{json entitiesData.ids}}, + "workflow_name": {{json workflowName}} +} +``` + +Keep `issue_id`, `state`, and `priority`. Flashduty rejects a missing `issue_id` because a random key cannot correlate later updates and closure. + + + + + +Open a real Issue and confirm an active Flashduty alert. Change its priority or add another Alert Event and confirm an update on the same alert. Finally close the Issue and confirm the original alert recovers. A test notification proves connectivity only, not lifecycle correlation. + + + + +## Alert Key and Issue merges +--- + +Flashduty uses `issue_id` (`issueId`) directly as the Alert Key. Titles, priorities, policies, conditions, entities, and `incident_ids` do not affect it. `incident_ids` is the list of Alert Events aggregated into the Issue and is stored only as context. + +For `trigger_event=MERGE_REQUEST`, Flashduty updates the surviving Issue identified by the payload's `issue_id`. This version does not invoke Flashduty's internal alert merge operation or infer and close a source Issue. + +## Status and severity +--- + +| New Relic value | Flashduty status or severity | +| :--- | :--- | +| `state = CLOSED` | Recovered | +| `state = CREATED` or `ACTIVATED` | Active alert | +| `priority = CRITICAL` | Critical | +| `priority = HIGH` | Warning | +| `priority = MEDIUM` or `LOW` | Info | +| Empty or unknown priority | Warning | + +New Relic warning thresholds create `HIGH` priority Alert Events, so `HIGH` maps to Flashduty Warning. Use an [Alert Processing Pipeline](/en/on-call/integration/alert-integration/alert-pipelines) for a different mapping. + +## Add custom labels +--- + +Add a top-level `custom_labels` object to send more Workflow variables: + +```json +{ + "issue_id": "{{issueId}}", + "priority": "{{priority}}", + "state": "{{state}}", + "custom_labels": { + "team": {{json accumulations.tag.team.[0]}}, + "environment": {{json accumulations.tag.environment.[0]}}, + "muting_state": "{{mutingState}}", + "open_alert_events": {{openIncidentsCount}} + } +} +``` + +`custom_labels` accepts at most 50 entries. Use snake_case keys. Strings, numbers, booleans, arrays, and objects are accepted; arrays and objects are stored as JSON strings. Empty values are discarded, built-in labels win collisions, and the final event may contain at most 50 labels. Never send secrets. + +For the complete variable list, see [New Relic Workflow variables](https://docs.newrelic.com/docs/alerts/get-notified/custom-variables-alert-event-workflows/). diff --git a/integration-docs/src/doc-map.mjs b/integration-docs/src/doc-map.mjs index 7893bbba..c570094b 100644 --- a/integration-docs/src/doc-map.mjs +++ b/integration-docs/src/doc-map.mjs @@ -64,6 +64,7 @@ export const docMap = { JDCloudMonitor: `${alertBase}/jdcloud.mdx`, KSCloudMonitor: `${alertBase}/kscloud-monitor.mdx`, Datadog: `${alertBase}/datadog.mdx`, + NewRelic: `${alertBase}/new-relic.mdx`, AliyunPrometheus: `${alertBase}/aliyun-prometheus.mdx`, HttpPull: `${alertBase}/http-pull.mdx`, DbPull: `${alertBase}/db-pull.mdx`, diff --git a/zh/on-call/integration/alert-integration/alert-sources/new-relic.mdx b/zh/on-call/integration/alert-integration/alert-sources/new-relic.mdx new file mode 100644 index 00000000..35e07691 --- /dev/null +++ b/zh/on-call/integration/alert-integration/alert-sources/new-relic.mdx @@ -0,0 +1,154 @@ +--- +title: "New Relic 告警集成" +description: "通过 Workflow Webhook 将 New Relic Issue 同步到 Flashduty On-call,并关联激活、更新和关闭事件。" +keywords: ["告警集成", "New Relic", "Workflow", "Webhook", "Issue"] +--- + +通过 New Relic Workflow Webhook 将 Issue 同步到 Flashduty On-call。一个 New Relic Issue 对应一条 Flashduty 告警;同一 Issue 后续发生等级变化、Alert Event 加入或关闭、Issue 合并、关闭时,会继续更新这条告警。 + +
+ +## 在 Flashduty On-call +--- +您可通过以下两种方式获取集成推送地址,任选其一即可。 + +### 使用专属集成 + +1. 进入 Flashduty 控制台,选择 **协作空间**,打开一个协作空间 +2. 选择 **集成数据**,点击 **添加一个集成** +3. 选择 **New Relic**,点击 **保存** +4. 打开生成的集成卡片,复制 **推送地址** + +### 使用共享集成 + +1. 进入 Flashduty 控制台,选择 **集成中心 → 告警事件** +2. 选择 **New Relic**,填写集成名称 +3. 配置默认路由并选择协作空间;创建后可在 **路由** 中增加更多规则 +4. 点击 **保存**,复制生成的 **推送地址** + +
+ +## 在 New Relic 中配置 +--- + + + + +1. 登录 New Relic,进入 **Alerts → Enrich and Notify → Destinations** +2. 创建一个 **Webhook** Destination +3. 名称可填写 `Flashduty` +4. 将 Flashduty 集成的完整推送地址粘贴到 Endpoint URL + + + + + +1. 进入 **Alerts → Enrich and Notify → Workflows**,点击创建 Workflow +2. 设置 Issue 过滤条件,选择需要发送到 Flashduty 的 Policy、Condition、实体或标签 +3. 添加刚创建的 Webhook Destination +4. 在通知触发器中至少启用 **Activated** 和 **Closed** +5. 建议同时启用 **Priority changed** 和 **Other updates**,以同步等级变化、Alert Event 增减及 Issue 合并后的最新快照 + + + + + +将 Webhook 的自定义 Payload 替换为: + +```json +{ + "issue_id": "{{issueId}}", + "issue_url": {{json issuePageUrl}}, + "title": {{json issueTitle}}, + "description": {{json accumulations.conditionDescription.[0]}}, + "priority": "{{priority}}", + "state": "{{state}}", + "trigger_event": "{{triggerEvent}}", + "is_correlated": {{isCorrelated}}, + "account_id": {{nrAccountId}}, + "incident_ids": {{json incidentIds}}, + "sources": {{json accumulations.sources}}, + "policy_names": {{json accumulations.policyName}}, + "condition_names": {{json accumulations.conditionName}}, + "entity_names": {{json entitiesData.names}}, + "entity_ids": {{json entitiesData.ids}}, + "workflow_name": {{json workflowName}} +} +``` + + +请保留 `issue_id`、`state` 和 `priority`。缺少 `issue_id` 时 Flashduty 会拒绝请求,因为随机 Key 无法保证后续更新和关闭命中同一条告警。 + + + + + + +让 Alert Condition 进入阈值,确认 Flashduty 收到活动告警;提高优先级或产生新的 Alert Event,确认同一条告警收到更新;最后让 Issue 关闭,确认原告警恢复。 + +New Relic 的测试通知只能验证 Webhook 可达。Alert Key、更新和恢复必须通过真实 Issue 生命周期验证。 + + + + +## Alert Key 与 Issue 合并 +--- + +Flashduty 直接使用 `issue_id`(New Relic 变量 `issueId`)作为 Alert Key。标题、优先级、Policy、Condition、实体和 `incident_ids` 的变化都不会改变 Alert Key。 + +`incident_ids` 是当前 Issue 聚合的 Alert Event ID 列表,只作为详情标签。它不能作为 Alert Key,否则一个 Alert Event 加入、关闭或相关性计算变化时会拆出新告警。 + +当 `trigger_event=MERGE_REQUEST` 时,Flashduty 将请求视为合并后目标 Issue 的一次普通更新,并继续使用 Payload 中的 `issue_id`。当前版本不调用 Flashduty 内部的告警合并能力,也不会推断或关闭来源 Issue。 + +## 状态和告警等级 +--- + +恢复只根据 `state` 判断,与 `trigger_event` 和等级映射相互独立。 + +| New Relic 值 | Flashduty 状态或等级 | +| :--- | :--- | +| `state = CLOSED` | 恢复 | +| `state = CREATED`、`ACTIVATED` | 活动告警 | +| `priority = CRITICAL` | Critical | +| `priority = HIGH` | Warning | +| `priority = MEDIUM`、`LOW` | Info | +| `priority` 为空或未知 | Warning | + +New Relic 的 Warning 阈值会生成 `HIGH` 优先级 Alert Event,因此 `HIGH` 映射为 Flashduty Warning。如需其他映射,可通过[告警处理 Pipeline](/zh/on-call/integration/alert-integration/alert-pipelines)调整。 + +## 增加自定义标签 +--- + +如果需要传递更多 Workflow 变量,在默认 Payload 顶层增加 `custom_labels`: + +```json +{ + "issue_id": "{{issueId}}", + "title": {{json issueTitle}}, + "priority": "{{priority}}", + "state": "{{state}}", + "custom_labels": { + "team": {{json accumulations.tag.team.[0]}}, + "environment": {{json accumulations.tag.environment.[0]}}, + "muting_state": "{{mutingState}}", + "open_alert_events": {{openIncidentsCount}} + } +} +``` + +- `custom_labels` 最多包含 50 个条目,key 建议使用 snake_case +- 字符串、数字、布尔值、数组和对象都可接收;数组和对象会保存为 JSON 字符串 +- 空值不会生成标签;基础字段优先,同名自定义标签不能覆盖基础标签 +- 单次请求包含基础标签在内,最多生成 50 个标签 +- 不要传递 API Key、Token、密码、Cookie 或其他敏感信息 + +## 排查问题 +--- + +- **只收到测试通知,真实告警没有通知**:确认 Workflow 已启用,并且过滤条件能够命中真实 Issue +- **Flashduty 返回参数错误**:确认 Payload 是有效 JSON,且包含非空的 `issue_id` 和支持的 `state` +- **告警没有恢复**:确认 Destination 启用了 **Closed**,关闭 Payload 仍携带与激活时相同的 `issue_id` +- **等级或合并变化没有更新**:启用 **Priority changed** 和 **Other updates** +- **部分列表为空**:不同 Condition 和 Issue 类型提供的上下文不同,Flashduty 会忽略空标签 + +字段含义和可用变量请参阅 [New Relic Workflow variables](https://docs.newrelic.com/docs/alerts/get-notified/custom-variables-alert-event-workflows/)。 From 7e3a424b50d3b698b4a492ab84977bd1be45ac04 Mon Sep 17 00:00:00 2001 From: Fiona Date: Mon, 14 Sep 2026 19:50:26 -0700 Subject: [PATCH 02/14] docs(api): document linked source code repositories on RUM applications Add `repositories` to RumApplicationItem, RumApplicationCreateRequest and RumApplicationUpdateRequest, backed by a new RumApplicationRepository schema ({repo: "owner/name", subdir}). On update the list is replaced when present, cleared by an empty array, and left unchanged when omitted. --- api-reference/openapi.en.json | 48 +++++++++++++++++++++++++++++++ api-reference/openapi.zh.json | 48 +++++++++++++++++++++++++++++++ api-reference/rum.openapi.en.json | 48 +++++++++++++++++++++++++++++++ api-reference/rum.openapi.zh.json | 48 +++++++++++++++++++++++++++++++ 4 files changed, 192 insertions(+) diff --git a/api-reference/openapi.en.json b/api-reference/openapi.en.json index 6f739801..f3eb8403 100644 --- a/api-reference/openapi.en.json +++ b/api-reference/openapi.en.json @@ -19376,6 +19376,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "Optional external-link integration configuration." }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "Source code repositories to link, in order; the first entry is the primary repository. At most 10 entries." + }, "no_geo": { "description": "Do not infer geographic location.", "type": "boolean" @@ -19522,6 +19530,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "External-link integration configuration." }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "Linked source code repositories, in order; the first entry is the primary repository. Linking grants no access by itself: AI sessions can only read repositories granted to the account's GitHub App installations." + }, "no_geo": { "description": "If `true`, geographic location is not inferred from IP.", "type": "boolean" @@ -19778,6 +19794,15 @@ "description": "External-link integration configuration. Omit to leave unchanged.", "x-flashduty-preserve-absence": true }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "Replaces the linked source code repositories when present; an empty array removes all links, and omitting the field leaves them unchanged. At most 10 entries.", + "x-flashduty-preserve-absence": true + }, "no_geo": { "description": "When `true`, stop inferring geographic location from IP; when `false`, resume inferring it. Omit to leave unchanged.", "type": [ @@ -29091,6 +29116,29 @@ "description": "Why the recipient was skipped. Only present when `status` is `skipped`. `not_member` — not an active member of the caller's account; `no_email` — the member has no email address on file; `email_disabled` — the member's notification preferences for this kind of message exclude email; `duplicate` — this recipient already received a message from the same AI SRE session turn; `rate_limited` — this recipient has already been sent 20 emails through this endpoint within the last hour; `send_failed` — enqueueing the email failed." } } + }, + "RumApplicationRepository": { + "type": "object", + "description": "Source code repository that builds the application.", + "required": [ + "repo" + ], + "properties": { + "repo": { + "type": "string", + "description": "GitHub repository in `owner/name` form.", + "examples": [ + "acme/web-app" + ] + }, + "subdir": { + "type": "string", + "description": "Directory holding the application inside the repository, relative to the repository root. `.` is the repository root; an empty value is saved as `.`.", + "examples": [ + "apps/web" + ] + } + } } }, "securitySchemes": { diff --git a/api-reference/openapi.zh.json b/api-reference/openapi.zh.json index 401b058d..57ffc368 100644 --- a/api-reference/openapi.zh.json +++ b/api-reference/openapi.zh.json @@ -19376,6 +19376,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "外部链接集成配置,可选。" }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "要关联的代码仓库,有序;第一个为主仓库。最多 10 个。" + }, "no_geo": { "description": "不推断地理位置。", "type": "boolean" @@ -19522,6 +19530,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "外部链接集成配置。" }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "关联的代码仓库,有序;第一个为主仓库。关联本身不授予任何访问权限:AI 会话只能读取本账户 GitHub App 安装已授权的仓库。" + }, "no_geo": { "description": "为 `true` 时不推断地理位置。", "type": "boolean" @@ -19778,6 +19794,15 @@ "description": "外部链接集成配置;不传则保持不变。", "x-flashduty-preserve-absence": true }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "传入时整体替换关联的代码仓库;传空数组表示清空,不传则保持不变。最多 10 个。", + "x-flashduty-preserve-absence": true + }, "no_geo": { "description": "为 `true` 时不再基于 IP 推断地理位置,为 `false` 时恢复推断;不传则保持不变。", "type": [ @@ -29091,6 +29116,29 @@ "description": "跳过原因,仅当 `status` 为 `skipped` 时出现。`not_member` —— 不是调用方账户的活跃成员;`no_email` —— 该成员没有邮箱地址;`email_disabled` —— 该成员针对此类消息的通知偏好中未包含邮件;`duplicate` —— 该收件人在同一个 AI SRE 会话轮次中已经收到过一次消息;`rate_limited` —— 该收件人通过该接口在过去一小时内已被发送 20 封邮件;`send_failed` —— 邮件入队失败。" } } + }, + "RumApplicationRepository": { + "type": "object", + "description": "构建该应用的代码仓库。", + "required": [ + "repo" + ], + "properties": { + "repo": { + "type": "string", + "description": "GitHub 仓库,格式为 `owner/name`。", + "examples": [ + "acme/web-app" + ] + }, + "subdir": { + "type": "string", + "description": "应用在仓库内所在的目录,相对仓库根目录。`.` 表示仓库根目录;传空值时保存为 `.`。", + "examples": [ + "apps/web" + ] + } + } } }, "securitySchemes": { diff --git a/api-reference/rum.openapi.en.json b/api-reference/rum.openapi.en.json index eca2d6ac..61dd9d3b 100644 --- a/api-reference/rum.openapi.en.json +++ b/api-reference/rum.openapi.en.json @@ -610,6 +610,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "Optional external-link integration configuration." }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "Source code repositories to link, in order; the first entry is the primary repository. At most 10 entries." + }, "no_geo": { "description": "Do not infer geographic location.", "type": "boolean" @@ -756,6 +764,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "External-link integration configuration." }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "Linked source code repositories, in order; the first entry is the primary repository. Linking grants no access by itself: AI sessions can only read repositories granted to the account's GitHub App installations." + }, "no_geo": { "description": "If `true`, geographic location is not inferred from IP.", "type": "boolean" @@ -1012,6 +1028,15 @@ "description": "External-link integration configuration. Omit to leave unchanged.", "x-flashduty-preserve-absence": true }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "Replaces the linked source code repositories when present; an empty array removes all links, and omitting the field leaves them unchanged. At most 10 entries.", + "x-flashduty-preserve-absence": true + }, "no_geo": { "description": "When `true`, stop inferring geographic location from IP; when `false`, resume inferring it. Omit to leave unchanged.", "type": [ @@ -3938,6 +3963,29 @@ } }, "type": "object" + }, + "RumApplicationRepository": { + "type": "object", + "description": "Source code repository that builds the application.", + "required": [ + "repo" + ], + "properties": { + "repo": { + "type": "string", + "description": "GitHub repository in `owner/name` form.", + "examples": [ + "acme/web-app" + ] + }, + "subdir": { + "type": "string", + "description": "Directory holding the application inside the repository, relative to the repository root. `.` is the repository root; an empty value is saved as `.`.", + "examples": [ + "apps/web" + ] + } + } } }, "securitySchemes": { diff --git a/api-reference/rum.openapi.zh.json b/api-reference/rum.openapi.zh.json index c0362e4d..213c0676 100644 --- a/api-reference/rum.openapi.zh.json +++ b/api-reference/rum.openapi.zh.json @@ -610,6 +610,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "外部链接集成配置,可选。" }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "要关联的代码仓库,有序;第一个为主仓库。最多 10 个。" + }, "no_geo": { "description": "不推断地理位置。", "type": "boolean" @@ -756,6 +764,14 @@ "$ref": "#/components/schemas/RumApplicationLinks", "description": "外部链接集成配置。" }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "关联的代码仓库,有序;第一个为主仓库。关联本身不授予任何访问权限:AI 会话只能读取本账户 GitHub App 安装已授权的仓库。" + }, "no_geo": { "description": "为 `true` 时不推断地理位置。", "type": "boolean" @@ -1012,6 +1028,15 @@ "description": "外部链接集成配置;不传则保持不变。", "x-flashduty-preserve-absence": true }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RumApplicationRepository" + }, + "maxItems": 10, + "description": "传入时整体替换关联的代码仓库;传空数组表示清空,不传则保持不变。最多 10 个。", + "x-flashduty-preserve-absence": true + }, "no_geo": { "description": "为 `true` 时不再基于 IP 推断地理位置,为 `false` 时恢复推断;不传则保持不变。", "type": [ @@ -3938,6 +3963,29 @@ } }, "type": "object" + }, + "RumApplicationRepository": { + "type": "object", + "description": "构建该应用的代码仓库。", + "required": [ + "repo" + ], + "properties": { + "repo": { + "type": "string", + "description": "GitHub 仓库,格式为 `owner/name`。", + "examples": [ + "acme/web-app" + ] + }, + "subdir": { + "type": "string", + "description": "应用在仓库内所在的目录,相对仓库根目录。`.` 表示仓库根目录;传空值时保存为 `.`。", + "examples": [ + "apps/web" + ] + } + } } }, "securitySchemes": { From 12a51b53493f42a21bd3a2d49fa5b8c706519779 Mon Sep 17 00:00:00 2001 From: ysyneu Date: Mon, 14 Sep 2026 23:26:48 -0700 Subject: [PATCH 03/14] Drop the flag emoji from the Taiwan SMS region card --- en/on-call/quickstart/faq.mdx | 2 +- zh/on-call/quickstart/faq.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/en/on-call/quickstart/faq.mdx b/en/on-call/quickstart/faq.mdx index 77980caa..6d8d8da6 100644 --- a/en/on-call/quickstart/faq.mdx +++ b/en/on-call/quickstart/faq.mdx @@ -215,7 +215,7 @@ description: "Learn about the most common questions when using Flashduty On-call - + diff --git a/zh/on-call/quickstart/faq.mdx b/zh/on-call/quickstart/faq.mdx index 21645221..77ab54c8 100644 --- a/zh/on-call/quickstart/faq.mdx +++ b/zh/on-call/quickstart/faq.mdx @@ -216,7 +216,7 @@ keywords: ["常见问题", "FAQ", "On-call", "故障排查", "使用帮助"] - + From d4a7a0f42fb76ba6f520ebf13233a04782901789 Mon Sep 17 00:00:00 2001 From: flashduty-ai-sre Date: Tue, 15 Sep 2026 08:30:34 +0000 Subject: [PATCH 04/14] =?UTF-8?q?docs(api):=20daily=20audit=202026-09-15?= =?UTF-8?q?=20=E2=80=94=20surface=20template=20closed-card=20action=20apps?= =?UTF-8?q?,=20session=20and=20feed=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api-reference/on-call.openapi.en.json | 62 ++++++++++++- api-reference/on-call.openapi.zh.json | 62 ++++++++++++- api-reference/openapi.en.json | 121 +++++++++++++++++++++++++- api-reference/openapi.zh.json | 121 +++++++++++++++++++++++++- api-reference/safari.openapi.en.json | 59 ++++++++++++- api-reference/safari.openapi.zh.json | 59 ++++++++++++- 6 files changed, 476 insertions(+), 8 deletions(-) diff --git a/api-reference/on-call.openapi.en.json b/api-reference/on-call.openapi.en.json index 252afe6a..a76fc6d4 100644 --- a/api-reference/on-call.openapi.en.json +++ b/api-reference/on-call.openapi.en.json @@ -22750,6 +22750,14 @@ "type": "integer", "format": "int64", "description": "Soft-delete time, Unix epoch milliseconds. Omitted when not deleted." + }, + "via": { + "type": "string", + "description": "Surface that wrote the entry on a user's behalf; currently only `ai_sre`. Omitted when a user created the entry directly." + }, + "agent_session_id": { + "type": "string", + "description": "AI SRE session that produced the entry. Omitted when no agent wrote it." } } }, @@ -28552,6 +28560,20 @@ "type": "string", "description": "Zoom bot message template source." }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "IM apps whose closed-incident cards keep the custom action buttons. Supported values: `feishu_app`, `dingtalk_app`, `wecom_app`, `slack_app`, `teams_app`. An empty list hides the buttons on every app." + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "Incident card fields hidden per IM app type." @@ -28626,6 +28648,7 @@ "updated_by", "created_at", "updated_at", + "incident_card_closed_action_apps", "incident_card_hidden_fields" ], "properties": { @@ -28725,6 +28748,20 @@ "type": "string", "description": "Zoom bot message template source." }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "IM apps whose closed-incident cards keep the custom action buttons. Supported values: `feishu_app`, `dingtalk_app`, `wecom_app`, `slack_app`, `teams_app`. An empty list hides the buttons on every app." + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "Incident card fields hidden per IM app type; an empty object when none are configured." @@ -29015,6 +29052,20 @@ ], "description": "Zoom bot message template source. Omit to keep the current content; send an empty string to clear it." }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "Replaces the retained-app list when sent. Supported values: `feishu_app`, `dingtalk_app`, `wecom_app`, `slack_app`, `teams_app`. Omit the field to leave it unchanged." + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "Incident card fields hidden per IM app type." @@ -29691,7 +29742,8 @@ "incident_id", "status", "created_at", - "plugin_type" + "plugin_type", + "chat_name" ], "properties": { "account_id": { @@ -29734,6 +29786,14 @@ "plugin_type": { "type": "string", "description": "IM plugin type (e.g. `feishu`, `dingtalk`, `wecom`, `slack`)." + }, + "chat_name": { + "type": "string", + "description": "Display name of the group chat on the IM side." + }, + "integration_unavailable": { + "type": "boolean", + "description": "True when the IM integration behind this war room is disabled or no longer exists." } } }, diff --git a/api-reference/on-call.openapi.zh.json b/api-reference/on-call.openapi.zh.json index c203decf..3d49ef29 100644 --- a/api-reference/on-call.openapi.zh.json +++ b/api-reference/on-call.openapi.zh.json @@ -22750,6 +22750,14 @@ "type": "integer", "format": "int64", "description": "软删除时间,Unix 时间戳(毫秒)。未删除时不返回该字段。" + }, + "via": { + "type": "string", + "description": "由 AI SRE 代为写入该记录时的来源标识,目前只有 `ai_sre`;用户直接操作创建的记录不返回该字段。" + }, + "agent_session_id": { + "type": "string", + "description": "写入该记录的 AI SRE 会话 ID;非智能体写入时不返回该字段。" } } }, @@ -28552,6 +28560,20 @@ "type": "string", "description": "Zoom 机器人消息模板源。" }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "已关闭故障的卡片仍保留自定义操作按钮的 IM 应用。可选值:`feishu_app`、`dingtalk_app`、`wecom_app`、`slack_app`、`teams_app`;空列表表示所有应用都隐藏这些按钮。" + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "按 IM 应用类型隐藏的故障卡片字段。" @@ -28626,6 +28648,7 @@ "updated_by", "created_at", "updated_at", + "incident_card_closed_action_apps", "incident_card_hidden_fields" ], "properties": { @@ -28725,6 +28748,20 @@ "type": "string", "description": "Zoom 机器人消息模板源。" }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "已关闭故障的卡片仍保留自定义操作按钮的 IM 应用。可选值:`feishu_app`、`dingtalk_app`、`wecom_app`、`slack_app`、`teams_app`;空列表表示所有应用都隐藏这些按钮。" + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "按 IM 应用类型配置的故障卡片隐藏字段,未配置时为空对象。" @@ -29015,6 +29052,20 @@ ], "description": "Zoom 机器人消息模板源。省略时保持当前内容;传空字符串表示清空。" }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "传入时整体替换保留自定义操作按钮的应用列表。可选值:`feishu_app`、`dingtalk_app`、`wecom_app`、`slack_app`、`teams_app`;不传该字段则保持不变。" + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "按 IM 应用类型隐藏的故障卡片字段。" @@ -29691,7 +29742,8 @@ "incident_id", "status", "created_at", - "plugin_type" + "plugin_type", + "chat_name" ], "properties": { "account_id": { @@ -29734,6 +29786,14 @@ "plugin_type": { "type": "string", "description": "IM 插件类型(如 `feishu`、`dingtalk`、`wecom`、`slack`)。" + }, + "chat_name": { + "type": "string", + "description": "IM 侧群聊的显示名称。" + }, + "integration_unavailable": { + "type": "boolean", + "description": "该作战室背后的 IM 集成已禁用或已不存在时为 true。" } } }, diff --git a/api-reference/openapi.en.json b/api-reference/openapi.en.json index 6f739801..2a0e5890 100644 --- a/api-reference/openapi.en.json +++ b/api-reference/openapi.en.json @@ -7575,6 +7575,46 @@ } } }, + "PendingUserMessage": { + "type": "object", + "description": "A queued user message that the agent has not consumed yet, as carried by `pending_messages`.", + "required": [ + "invocation_id", + "person_id", + "query" + ], + "properties": { + "invocation_id": { + "type": "string", + "description": "Invocation ID of the queued message." + }, + "client_msg_id": { + "type": "string", + "description": "Client-supplied message ID, echoed back for de-duplication. Omitted when absent." + }, + "person_id": { + "type": "integer", + "format": "int64", + "description": "Person ID of the sender." + }, + "steering": { + "type": "boolean", + "description": "True when the message was sent as a mid-turn steering instruction. Omitted when false." + }, + "query": { + "type": "string", + "description": "Message text." + }, + "parts": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + }, + "description": "Request parts passed through verbatim (text, file, ref, or skill entries). Omitted when the original message carried none." + } + } + }, "PrometheusQueryParams": { "type": "object", "additionalProperties": true, @@ -10511,6 +10551,14 @@ "description": "Last update timestamp in Unix epoch milliseconds.", "format": "int64", "type": "integer" + }, + "via": { + "type": "string", + "description": "Surface that wrote the entry on a user's behalf; currently only `ai_sre`. Omitted when a user created the entry directly." + }, + "agent_session_id": { + "type": "string", + "description": "AI SRE session that produced the entry. Omitted when no agent wrote it." } }, "required": [ @@ -23651,13 +23699,21 @@ "suggest_init": { "description": "Account-wide onboarding flag: true when the account has zero knowledge packs in any scope; not specific to this session.", "type": "boolean" + }, + "pending_messages": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PendingUserMessage" + }, + "description": "Human messages queued but not yet picked up by the agent, in execution order. Always an array — empty when nothing is queued." } }, "required": [ "session", "events", "has_more_older", - "suggest_init" + "suggest_init", + "pending_messages" ], "type": "object" }, @@ -23768,6 +23824,10 @@ "description": "True when an agent turn is currently in flight for this session.", "type": "boolean" }, + "standing_tasks": { + "type": "integer", + "description": "Number of process-type tasks (background shell or monitor) still alive when the response was rendered." + }, "last_event_at": { "description": "Unix timestamp in milliseconds of the most recent assistant-side event.", "format": "int64", @@ -23781,6 +23841,10 @@ "description": "Creator person id.", "type": "string" }, + "creator_name": { + "type": "string", + "description": "Display name of the session creator, resolved when the response is rendered. Omitted when the member lookup fails." + }, "pinned_at": { "description": "Caller's per-user pin time as a Unix timestamp in milliseconds; 0 means not pinned.", "format": "int64", @@ -23872,6 +23936,7 @@ "archived_at", "pinned_at", "is_running", + "standing_tasks", "has_unread", "current_turn_started_at", "current_turn_active_ms", @@ -26107,6 +26172,20 @@ "type": "boolean", "description": "Show the Create War Room button on Feishu app cards." }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "IM apps whose closed-incident cards keep the custom action buttons. Supported values: `feishu_app`, `dingtalk_app`, `wecom_app`, `slack_app`, `teams_app`. An empty list hides the buttons on every app." + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "Incident card fields hidden per IM app type." @@ -26265,6 +26344,20 @@ "type": "boolean", "description": "Whether Feishu app cards show the Create War Room button. Hidden when the incident has no responders." }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "IM apps whose closed-incident cards keep the custom action buttons. Supported values: `feishu_app`, `dingtalk_app`, `wecom_app`, `slack_app`, `teams_app`. An empty list hides the buttons on every app." + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "Incident card fields hidden per IM app type; an empty object when none are configured." @@ -26373,6 +26466,7 @@ "updated_by", "created_at", "updated_at", + "incident_card_closed_action_apps", "incident_card_hidden_fields" ], "type": "object" @@ -26532,6 +26626,20 @@ ], "description": "When set, show or hide the Create War Room button on Feishu app cards. Omit to keep the existing setting." }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "Replaces the retained-app list when sent. Supported values: `feishu_app`, `dingtalk_app`, `wecom_app`, `slack_app`, `teams_app`. Omit the field to leave it unchanged." + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "Incident card fields hidden per IM app type." @@ -28021,6 +28129,14 @@ "deleted" ], "type": "string" + }, + "chat_name": { + "type": "string", + "description": "Display name of the group chat on the IM side." + }, + "integration_unavailable": { + "type": "boolean", + "description": "True when the IM integration behind this war room is disabled or no longer exists." } }, "required": [ @@ -28031,7 +28147,8 @@ "incident_id", "status", "created_at", - "plugin_type" + "plugin_type", + "chat_name" ], "type": "object" }, diff --git a/api-reference/openapi.zh.json b/api-reference/openapi.zh.json index 401b058d..eac96606 100644 --- a/api-reference/openapi.zh.json +++ b/api-reference/openapi.zh.json @@ -7575,6 +7575,46 @@ } } }, + "PendingUserMessage": { + "type": "object", + "description": "尚未被智能体消费的排队用户消息,由 `pending_messages` 返回。", + "required": [ + "invocation_id", + "person_id", + "query" + ], + "properties": { + "invocation_id": { + "type": "string", + "description": "该排队消息的 invocation ID。" + }, + "client_msg_id": { + "type": "string", + "description": "客户端传入的消息 ID,原样返回用于去重;未传时不返回。" + }, + "person_id": { + "type": "integer", + "format": "int64", + "description": "发送者 person ID。" + }, + "steering": { + "type": "boolean", + "description": "该消息是轮次中的 steering 指令时为 true;false 时不返回。" + }, + "query": { + "type": "string", + "description": "消息正文。" + }, + "parts": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + }, + "description": "原样透传的请求 parts(text / file / ref / skill 等);原消息未携带时不返回。" + } + } + }, "PrometheusQueryParams": { "type": "object", "additionalProperties": true, @@ -10511,6 +10551,14 @@ "description": "最后更新时间,Unix 毫秒时间戳。", "format": "int64", "type": "integer" + }, + "via": { + "type": "string", + "description": "由 AI SRE 代为写入该记录时的来源标识,目前只有 `ai_sre`;用户直接操作创建的记录不返回该字段。" + }, + "agent_session_id": { + "type": "string", + "description": "写入该记录的 AI SRE 会话 ID;非智能体写入时不返回该字段。" } }, "required": [ @@ -23651,13 +23699,21 @@ "suggest_init": { "description": "账户级引导标志:当账户在任何范围内都没有知识包时为 true;并非该会话独有的属性。", "type": "boolean" + }, + "pending_messages": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PendingUserMessage" + }, + "description": "已排队但尚未被智能体消费的用户消息,按执行顺序排列。始终返回数组;无排队消息时为空数组。" } }, "required": [ "session", "events", "has_more_older", - "suggest_init" + "suggest_init", + "pending_messages" ], "type": "object" }, @@ -23768,6 +23824,10 @@ "description": "当该会话当前有正在进行的智能体轮次时为 true。", "type": "boolean" }, + "standing_tasks": { + "type": "integer", + "description": "渲染响应时仍存活的进程型任务数(后台命令或 monitor)。" + }, "last_event_at": { "description": "最近一条助手侧事件的时间,Unix 毫秒时间戳。", "format": "int64", @@ -23781,6 +23841,10 @@ "description": "创建者人员 ID。", "type": "string" }, + "creator_name": { + "type": "string", + "description": "会话创建者的显示名,渲染响应时解析得到;成员查询失败时不返回该字段。" + }, "pinned_at": { "description": "调用者的个人置顶时间,Unix 毫秒时间戳;0 表示未置顶。", "format": "int64", @@ -23872,6 +23936,7 @@ "archived_at", "pinned_at", "is_running", + "standing_tasks", "has_unread", "current_turn_started_at", "current_turn_active_ms", @@ -26107,6 +26172,20 @@ "type": "boolean", "description": "飞书应用卡片展示「创建作战室」按钮。" }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "已关闭故障的卡片仍保留自定义操作按钮的 IM 应用。可选值:`feishu_app`、`dingtalk_app`、`wecom_app`、`slack_app`、`teams_app`;空列表表示所有应用都隐藏这些按钮。" + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "按 IM 应用类型隐藏的故障卡片字段。" @@ -26265,6 +26344,20 @@ "type": "boolean", "description": "飞书应用卡片是否展示「创建作战室」按钮;故障无响应人时不展示。" }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "已关闭故障的卡片仍保留自定义操作按钮的 IM 应用。可选值:`feishu_app`、`dingtalk_app`、`wecom_app`、`slack_app`、`teams_app`;空列表表示所有应用都隐藏这些按钮。" + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "按 IM 应用类型配置的故障卡片隐藏字段,未配置时为空对象。" @@ -26373,6 +26466,7 @@ "updated_by", "created_at", "updated_at", + "incident_card_closed_action_apps", "incident_card_hidden_fields" ], "type": "object" @@ -26532,6 +26626,20 @@ ], "description": "设置后决定飞书应用卡片是否展示「创建作战室」按钮;省略时保持当前设置。" }, + "incident_card_closed_action_apps": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "wecom_app", + "slack_app", + "teams_app" + ] + }, + "description": "传入时整体替换保留自定义操作按钮的应用列表。可选值:`feishu_app`、`dingtalk_app`、`wecom_app`、`slack_app`、`teams_app`;不传该字段则保持不变。" + }, "incident_card_hidden_fields": { "$ref": "#/components/schemas/IncidentCardHiddenFields", "description": "按 IM 应用类型隐藏的故障卡片字段。" @@ -28021,6 +28129,14 @@ "deleted" ], "type": "string" + }, + "chat_name": { + "type": "string", + "description": "IM 侧群聊的显示名称。" + }, + "integration_unavailable": { + "type": "boolean", + "description": "该作战室背后的 IM 集成已禁用或已不存在时为 true。" } }, "required": [ @@ -28031,7 +28147,8 @@ "incident_id", "status", "created_at", - "plugin_type" + "plugin_type", + "chat_name" ], "type": "object" }, diff --git a/api-reference/safari.openapi.en.json b/api-reference/safari.openapi.en.json index 8c513b5e..3a9ab1d0 100644 --- a/api-reference/safari.openapi.en.json +++ b/api-reference/safari.openapi.en.json @@ -7049,6 +7049,46 @@ "preflight" ] }, + "PendingUserMessage": { + "type": "object", + "description": "A queued user message that the agent has not consumed yet, as carried by `pending_messages`.", + "required": [ + "invocation_id", + "person_id", + "query" + ], + "properties": { + "invocation_id": { + "type": "string", + "description": "Invocation ID of the queued message." + }, + "client_msg_id": { + "type": "string", + "description": "Client-supplied message ID, echoed back for de-duplication. Omitted when absent." + }, + "person_id": { + "type": "integer", + "format": "int64", + "description": "Person ID of the sender." + }, + "steering": { + "type": "boolean", + "description": "True when the message was sent as a mid-turn steering instruction. Omitted when false." + }, + "query": { + "type": "string", + "description": "Message text." + }, + "parts": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + }, + "description": "Request parts passed through verbatim (text, file, ref, or skill entries). Omitted when the original message carried none." + } + } + }, "PreflightResult": { "type": "object", "description": "Readiness checks computed before a manual run is allowed to start.", @@ -7215,13 +7255,21 @@ "suggest_init": { "type": "boolean", "description": "Account-wide onboarding flag: true when the account has zero knowledge packs in any scope; not specific to this session." + }, + "pending_messages": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PendingUserMessage" + }, + "description": "Human messages queued but not yet picked up by the agent, in execution order. Always an array — empty when nothing is queued." } }, "required": [ "session", "events", "has_more_older", - "suggest_init" + "suggest_init", + "pending_messages" ] }, "SessionItem": { @@ -7259,6 +7307,10 @@ "type": "string", "description": "Creator person id." }, + "creator_name": { + "type": "string", + "description": "Display name of the session creator, resolved when the response is rendered. Omitted when the member lookup fails." + }, "team_id": { "type": "integer", "format": "int64", @@ -7387,6 +7439,10 @@ "type": "boolean", "description": "True when an agent turn is currently in flight for this session." }, + "standing_tasks": { + "type": "integer", + "description": "Number of process-type tasks (background shell or monitor) still alive when the response was rendered." + }, "has_unread": { "type": "boolean", "description": "True when there is assistant output the caller has not yet viewed." @@ -7436,6 +7492,7 @@ "archived_at", "pinned_at", "is_running", + "standing_tasks", "has_unread", "current_turn_started_at", "current_turn_active_ms", diff --git a/api-reference/safari.openapi.zh.json b/api-reference/safari.openapi.zh.json index be93ac17..702d9e9e 100644 --- a/api-reference/safari.openapi.zh.json +++ b/api-reference/safari.openapi.zh.json @@ -7049,6 +7049,46 @@ "preflight" ] }, + "PendingUserMessage": { + "type": "object", + "description": "尚未被智能体消费的排队用户消息,由 `pending_messages` 返回。", + "required": [ + "invocation_id", + "person_id", + "query" + ], + "properties": { + "invocation_id": { + "type": "string", + "description": "该排队消息的 invocation ID。" + }, + "client_msg_id": { + "type": "string", + "description": "客户端传入的消息 ID,原样返回用于去重;未传时不返回。" + }, + "person_id": { + "type": "integer", + "format": "int64", + "description": "发送者 person ID。" + }, + "steering": { + "type": "boolean", + "description": "该消息是轮次中的 steering 指令时为 true;false 时不返回。" + }, + "query": { + "type": "string", + "description": "消息正文。" + }, + "parts": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + }, + "description": "原样透传的请求 parts(text / file / ref / skill 等);原消息未携带时不返回。" + } + } + }, "PreflightResult": { "type": "object", "description": "在允许发起手动运行前计算出的就绪检查结果。", @@ -7215,13 +7255,21 @@ "suggest_init": { "type": "boolean", "description": "账户级引导标志:当账户在任何范围内都没有知识包时为 true;并非该会话独有的属性。" + }, + "pending_messages": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PendingUserMessage" + }, + "description": "已排队但尚未被智能体消费的用户消息,按执行顺序排列。始终返回数组;无排队消息时为空数组。" } }, "required": [ "session", "events", "has_more_older", - "suggest_init" + "suggest_init", + "pending_messages" ] }, "SessionItem": { @@ -7259,6 +7307,10 @@ "type": "string", "description": "创建者人员 ID。" }, + "creator_name": { + "type": "string", + "description": "会话创建者的显示名,渲染响应时解析得到;成员查询失败时不返回该字段。" + }, "team_id": { "type": "integer", "format": "int64", @@ -7387,6 +7439,10 @@ "type": "boolean", "description": "当该会话当前有正在进行的智能体轮次时为 true。" }, + "standing_tasks": { + "type": "integer", + "description": "渲染响应时仍存活的进程型任务数(后台命令或 monitor)。" + }, "has_unread": { "type": "boolean", "description": "当存在调用者尚未查看的助手输出时为 true。" @@ -7436,6 +7492,7 @@ "archived_at", "pinned_at", "is_running", + "standing_tasks", "has_unread", "current_turn_started_at", "current_turn_active_ms", From 52ad8c42795f151e7f01ed2693b42e37f8192070 Mon Sep 17 00:00:00 2001 From: ysyneu Date: Tue, 15 Sep 2026 01:52:06 -0700 Subject: [PATCH 05/14] Sync docs to Meilisearch as a full reconcile on every run The upload script had two ways to leave stale documents in the index: - Full mode upserted every doc but never deleted anything, so pages removed from the repo stayed searchable. - Incremental mode diffed only HEAD~1: a push carrying several commits lost the changes of all but the last one, a renamed file was uploaded under its new path while the old path was never deleted, and a failed or cancelled run dropped its changes for good. Replace both modes with one sync: scan zh/ and en/, list every document id in the index (paginated), upsert all docs, and delete ids that no current file produces. Meilisearch only re-embeds documents whose content changed, so re-uploading unchanged docs is cheap. The run fails without writing anything if the scan is empty or the listing is incomplete. The workflow drops the full_upload input and the fetch depth it no longer needs, and serializes runs per environment so an older sync cannot delete docs a newer one just added. Also strip HTML/MDX tags after joining lines: a tag whose attributes span several lines (e.g.