From 3dae2aa22b229a50f884cbfefa6650fb8a9ffbfa Mon Sep 17 00:00:00 2001 From: clh02467605 Date: Mon, 9 Nov 2026 15:54:30 +0800 Subject: [PATCH] feat(telemetry): add callerType=script attribution - Distinguish reusable script/template bl invocations from agent/unknown so dashboards can keep agent/(agent+unknown+script) without dropping scripts from the denominator. - reinforce script caller attribution in business skills --- docs/agents/skill-change.md | 2 +- docs/agents/telemetry-change.md | 11 ++-- packages/core/src/telemetry/caller.ts | 54 +++++++++++-------- packages/core/src/telemetry/event.ts | 4 +- packages/core/tests/telemetry-caller.test.ts | 26 +++++++++ packages/core/tests/telemetry-tracker.test.ts | 38 +++++++++++++ .../runtime/tests/telemetry-stage.test.ts | 19 +++++++ skills/bailian-cli/SKILL.md | 4 +- skills/bailian-finetune/SKILL.md | 4 +- skills/bailian-gen/SKILL.md | 4 +- skills/bailian-knowledge/SKILL.md | 2 +- skills/bailian-managed-agent/SKILL.md | 4 +- skills/bailian-memory/SKILL.md | 4 +- skills/bailian-protocol/SKILL.md | 44 +++++++++++---- skills/bailian-sandbox/SKILL.md | 4 +- skills/bailian-web-search/SKILL.md | 4 +- 16 files changed, 176 insertions(+), 52 deletions(-) diff --git a/docs/agents/skill-change.md b/docs/agents/skill-change.md index 79e8264e..d73e7996 100644 --- a/docs/agents/skill-change.md +++ b/docs/agents/skill-change.md @@ -40,7 +40,7 @@ bailian-gen bailian-finetune bailian-managed-agent bailian-web-search - [ ] **整包装齐**:安装 / 缺 skill 文案主推 `bl skill init`;升级同步用 `bl skill update`(只更新已安装,不装新 skill);业务 skill **不**声明 `companions` - [ ] **协议读取**:CRITICAL / references 可链 `../bailian-protocol/…`;若读不到 → 停止执行 `bl`,提示 `bl skill init` -- [ ] **调用归因**:协议 `SKILL.md` 放 bash + PowerShell 双模板与协议样例;每个业务 skill **只留一条**填好的样例并链回协议;其余示例 / `assets/` / `reference/` 保持裸 `bl …`。Agent 执行时再套模板;人类终端不要设这些变量 +- [ ] **调用归因**:协议 `SKILL.md` 放 bash + PowerShell 的 agent / script 模板与协议样例;每个业务 skill **只留一条**填好的 agent 样例并链回协议;其余示例 / `assets/` / `reference/` 保持裸 `bl …`。Agent 当面 inline 套 agent 四变量;**抄进可复用脚本时改用 protocol `script` 模板**,并写明「样例仅当面 inline」。禁止为冒充 agent 而设变量,也禁止写入 shell profile / direnv / CI 全局环境 - [ ] **高风险确认**:统一由 `bailian-protocol` 定义;reference / leaf help 以 `risk: high` 明示风险,业务 skill 不得引导 Agent 自动补 `--yes`。遇到 exit code 7 / `requires_confirmation` 时停止执行并请求确认;目标或范围变化后重新确认 - [ ] **正常控制流**:`requires_confirmation` 不是 CLI bug,`assets/issue-reporting.md` 必须将 exit code 7 保持在 EXCLUDE 范围 - [ ] **软 hand-off**:兄弟业务 skill **只写 skill 名**;已安装则 Read,未安装则 `bl … --help` 或提示整包安装;**不要**把 `../bailian-gen/…` 等写成执行前提 diff --git a/docs/agents/telemetry-change.md b/docs/agents/telemetry-change.md index f9b4a03d..beda0159 100644 --- a/docs/agents/telemetry-change.md +++ b/docs/agents/telemetry-change.md @@ -97,17 +97,20 @@ source-config 只用于百炼 / DashScope API 侧消费,不发送到通用网 - `cliVersion`、`nodeVersion`、`os` - `commandPrefix`(调用入口,来自 `Identity`) - `authMethod` -- `callerType`(必填:`agent` 或 `unknown`);`callerType=agent` 时可选 `callerName`、`skillName`、`skillVersion` +- `callerType`(必填:`agent` | `script` | `unknown`) +- `callerName`:`agent` 与 `script` 时发送(缺省/非法 → `"unknown"`);`skillName` / `skillVersion` 仅 `agent` 时可选发送 - 失败时的 `errorMessage`、`exitCode`、`httpStatus`、`requestId` - 安全 allowlist 过滤后的 `params` 调用方归因只认本次进程的 `BAILIAN_CALLER_*`(由 `readCaller` 归一化后写入事件): - `BAILIAN_CALLER_TYPE` 为 `agent` / `ai_agent`(大小写不敏感)→ `callerType=agent` +- `BAILIAN_CALLER_TYPE` 为 `script`(大小写不敏感,trim)→ `callerType=script`;读取 `callerName`,**忽略** skill env - 未设置、空白或其他值 → `callerType=unknown`;不要把该字段当成人工 -- `callerName` / `skillName` / `skillVersion` 仅在 `agent` 时发送;`kscli` 通常没有 skill 字段 +- `callerName` 在 `agent` 与 `script` 时发送;缺省、空白或非法名称一律归一为 `"unknown"`(看板会出现 `callerType=script, callerName=unknown` 等组合,属预期兜底,不是漏字段) +- `skillName` / `skillVersion` 仅在 `agent` 时发送;`kscli` 通常没有 skill 字段 -新 CLI 每条进入 middleware 的命令事件都有 `callerType`。旧 CLI 没有该字段。看板只统计带 `callerType` 的事件,不能把字段缺失混进分母。`unknown` 只表示未识别为 agent,不是人工。新 CLI + 旧 skill / Agent 漏设变量时,会落进 `unknown`。`BAILIAN_CALLER_*` 是调用方声明,不是 `Identity`,不得用来猜 `bl` / `kscli`。 +新 CLI 每条进入 middleware 的命令事件都有 `callerType`。旧 CLI 没有该字段。看板只统计带 `callerType` 的事件,不能把字段缺失混进分母。已归因 := `agent + unknown + script`。Agent 调用率主口径:`agent / (agent + unknown + script)`;`script` 进分母、不进分子,也不得从分母剔除。`unknown` 只表示未识别为 agent/script,不是人工。新 CLI + 旧 skill / Agent 漏设变量时,会落进 `unknown`。`BAILIAN_CALLER_*` 是调用方声明,不是 `Identity`,不得用来猜 `bl` / `kscli`。看板禁止按 `callerName` 跨 `callerType` 聚合。 参数默认不上传,只有 `packages/core/src/telemetry/tracker.ts` 的 `PARAM_ALLOWLIST` 中字段会进入事件。不得加入 prompt、凭证、文件路径、URL、账号/租户/工作空间 ID 或其他用户内容。 @@ -173,7 +176,7 @@ AEM 映射: - [ ] 更新 `TrackingEvent`、`createTrackingEvent()` 与 `buildRemoteAemOptions()` 的字段映射 - [ ] 本地 JSONL 与远端 AEM 必须基于同一结构化事件,不能维护两套字段口径 - [ ] 三种入口分别核对 `commandPrefix`;共享路径也必须可区分,旧数据缺字段保留为未知 -- [ ] 调用方字段经 `readCaller` → `TrackingDeps.caller` → 事件;仅显式 `agent` / `ai_agent` 为 `agent`,其余为 `unknown` +- [ ] 调用方字段经 `readCaller` → `TrackingDeps.caller` → 事件;显式 `agent` / `ai_agent` → `agent`,显式 `script` → `script`,其余 → `unknown` - [ ] 成功与失败均覆盖;遥测异常必须静默且不改变业务退出码 - [ ] runtime 本地语义错误应记录 `exitCode`;新增字段默认随 AEM `ext` 上报,无需占用新的 `c1`—`c5` - [ ] 检查 `DO_NOT_TRACK=1` 与 `telemetry: false` 两个关闭入口 diff --git a/packages/core/src/telemetry/caller.ts b/packages/core/src/telemetry/caller.ts index 8fbde3f6..bc6a2791 100644 --- a/packages/core/src/telemetry/caller.ts +++ b/packages/core/src/telemetry/caller.ts @@ -1,4 +1,4 @@ -/** Parse BAILIAN_CALLER_*. Only an explicit agent is `agent`; everything else is `unknown`. */ +/** Parse BAILIAN_CALLER_*. Explicit agent/ai_agent → agent; explicit script → script; everything else → unknown. */ export type CallerAttribution = | { callerType: "unknown" } @@ -7,7 +7,8 @@ export type CallerAttribution = callerName: string; skillName?: string; skillVersion?: string; - }; + } + | { callerType: "script"; callerName: string }; const CALLER_TYPE_ENV = "BAILIAN_CALLER_TYPE"; const CALLER_NAME_ENV = "BAILIAN_CALLER_NAME"; @@ -35,25 +36,36 @@ function normalizeCallerName(raw: string | undefined): string { /** Env-only attribution; no TTY or install-path heuristics. */ export function readCaller(env: NodeJS.ProcessEnv): CallerAttribution { const callerType = readTrimmed(env, CALLER_TYPE_ENV)?.toLowerCase(); - if (callerType !== "agent" && callerType !== "ai_agent") { - return { callerType: "unknown" }; + + if (callerType === "agent" || callerType === "ai_agent") { + const skillNameRaw = readTrimmed(env, SKILL_NAME_ENV)?.toLowerCase(); + const skillName = + skillNameRaw !== undefined && SKILL_NAME_PATTERN.test(skillNameRaw) + ? skillNameRaw + : undefined; + const skillVersionRaw = readTrimmed(env, SKILL_VERSION_ENV); + const skillVersion = + skillName !== undefined && + skillVersionRaw !== undefined && + SKILL_VERSION_PATTERN.test(skillVersionRaw) + ? skillVersionRaw + : undefined; + + return { + callerType: "agent", + callerName: normalizeCallerName(readTrimmed(env, CALLER_NAME_ENV)), + ...(skillName !== undefined ? { skillName } : {}), + ...(skillVersion !== undefined ? { skillVersion } : {}), + }; + } + + if (callerType === "script") { + return { + callerType: "script", + // script 只带执行/维护宿主名,不读取 skill* + callerName: normalizeCallerName(readTrimmed(env, CALLER_NAME_ENV)), + }; } - const skillNameRaw = readTrimmed(env, SKILL_NAME_ENV)?.toLowerCase(); - const skillName = - skillNameRaw !== undefined && SKILL_NAME_PATTERN.test(skillNameRaw) ? skillNameRaw : undefined; - const skillVersionRaw = readTrimmed(env, SKILL_VERSION_ENV); - const skillVersion = - skillName !== undefined && - skillVersionRaw !== undefined && - SKILL_VERSION_PATTERN.test(skillVersionRaw) - ? skillVersionRaw - : undefined; - - return { - callerType: "agent", - callerName: normalizeCallerName(readTrimmed(env, CALLER_NAME_ENV)), - ...(skillName !== undefined ? { skillName } : {}), - ...(skillVersion !== undefined ? { skillVersion } : {}), - }; + return { callerType: "unknown" }; } diff --git a/packages/core/src/telemetry/event.ts b/packages/core/src/telemetry/event.ts index 0691ba09..cb42045d 100644 --- a/packages/core/src/telemetry/event.ts +++ b/packages/core/src/telemetry/event.ts @@ -18,7 +18,7 @@ export interface TrackingEvent { os: string; authMethod?: AuthRequirement; params?: Record; - /** Always present on new CLI events: `agent` or `unknown`. */ + /** Always present on new CLI events: `agent` | `script` | `unknown`. */ callerType: CallerAttribution["callerType"]; callerName?: string; skillName?: string; @@ -51,6 +51,8 @@ export function createTrackingEvent(opts: { event.callerName = opts.caller.callerName; if (opts.caller.skillName !== undefined) event.skillName = opts.caller.skillName; if (opts.caller.skillVersion !== undefined) event.skillVersion = opts.caller.skillVersion; + } else if (opts.caller.callerType === "script") { + event.callerName = opts.caller.callerName; } if (opts.authMethod) { diff --git a/packages/core/tests/telemetry-caller.test.ts b/packages/core/tests/telemetry-caller.test.ts index e949e630..ce72fb80 100644 --- a/packages/core/tests/telemetry-caller.test.ts +++ b/packages/core/tests/telemetry-caller.test.ts @@ -140,3 +140,29 @@ test("ignores agent detail fields when callerType is not agent", () => { }), ).toEqual({ callerType: "unknown" }); }); + +test.each([ + { label: "script", type: "script" }, + { label: "Script", type: "Script" }, + { label: "SCRIPT", type: "SCRIPT" }, + { label: "padded script", type: " script " }, +])("accepts $label as script without skill fields", ({ type }) => { + expect( + readCaller({ + BAILIAN_CALLER_TYPE: type, + BAILIAN_CALLER_NAME: "cursor", + BAILIAN_SKILL_NAME: "bailian-cli", + BAILIAN_SKILL_VERSION: "2.5.0", + }), + ).toEqual({ + callerType: "script", + callerName: "cursor", + }); +}); + +test("script falls back to unknown callerName when NAME is missing", () => { + expect(readCaller({ BAILIAN_CALLER_TYPE: "script" })).toEqual({ + callerType: "script", + callerName: "unknown", + }); +}); diff --git a/packages/core/tests/telemetry-tracker.test.ts b/packages/core/tests/telemetry-tracker.test.ts index 8d7d01ac..a5e5cab5 100644 --- a/packages/core/tests/telemetry-tracker.test.ts +++ b/packages/core/tests/telemetry-tracker.test.ts @@ -32,6 +32,10 @@ const agentCaller: CallerAttribution = { skillName: "bailian-cli", skillVersion: "2.5.0", }; +const scriptCaller: CallerAttribution = { + callerType: "script", + callerName: "cursor", +}; test("derives event version and prefix from identity", () => { const event = createTrackingEvent({ @@ -253,6 +257,40 @@ test("keeps agent attribution on success and in AEM ext", async () => { }); }); +test("keeps script attribution with callerName and without skill leak", async () => { + sinkMocks.localSink.mockClear(); + sinkMocks.remoteSink.mockClear(); + + await trackCommandExecution( + { + identity, + settings: { telemetry: true } as Settings, + authMethod: "apiKey", + caller: scriptCaller, + }, + ["config", "show"], + {}, + async () => {}, + ); + + const event = sinkMocks.localSink.mock.calls[0]![0]; + expect(event).toMatchObject({ + success: true, + callerType: "script", + callerName: "cursor", + }); + expect(event.skillName).toBeUndefined(); + expect(event.skillVersion).toBeUndefined(); + expect(event.params).toBeUndefined(); + const remoteExt = buildRemoteAemOptions(event).ext as Record; + expect(remoteExt).toMatchObject({ + callerType: "script", + callerName: "cursor", + }); + expect(remoteExt).not.toHaveProperty("skillName"); + expect(remoteExt).not.toHaveProperty("skillVersion"); +}); + test("does not call sinks when telemetry is disabled", async () => { sinkMocks.localSink.mockClear(); sinkMocks.remoteSink.mockClear(); diff --git a/packages/runtime/tests/telemetry-stage.test.ts b/packages/runtime/tests/telemetry-stage.test.ts index c575441e..77f5ec65 100644 --- a/packages/runtime/tests/telemetry-stage.test.ts +++ b/packages/runtime/tests/telemetry-stage.test.ts @@ -85,3 +85,22 @@ test("defaults to unknown when caller env is unset", async () => { }; expect(deps.caller).toEqual({ callerType: "unknown" }); }); + +test("wires script caller env without skill fields", async () => { + vi.stubEnv("BAILIAN_CALLER_TYPE", "script"); + vi.stubEnv("BAILIAN_CALLER_NAME", "cursor"); + vi.stubEnv("BAILIAN_SKILL_NAME", "bailian-cli"); + vi.stubEnv("BAILIAN_SKILL_VERSION", "2.5.0"); + const next = vi.fn(async () => {}); + + await telemetryStage(makeContext(), next); + + const deps = trackerMocks.trackCommandExecution.mock.calls[0]![0] as { + caller: CallerAttribution; + }; + expect(deps.caller).toEqual({ + callerType: "script", + callerName: "cursor", + }); + expect(next).toHaveBeenCalledOnce(); +}); diff --git a/skills/bailian-cli/SKILL.md b/skills/bailian-cli/SKILL.md index 2f0e49cf..3d35413b 100644 --- a/skills/bailian-cli/SKILL.md +++ b/skills/bailian-cli/SKILL.md @@ -23,10 +23,10 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-cli`; replace `codex` with this host): +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-cli`; replace `codex` with this host). **When copying commands into a reusable script / template / task definition, switch to the protocol `script` template (never keep `agent`); the sample below is for this-turn inline execution only. Strip attribution when handing a command to the user to paste.** ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 bl text chat --message "Write a poem about spring" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION= bl text chat --message "Write a poem about spring" ``` > **Family hub** — This skill owns Bailian resource commands and the hub `reference/` (apps, usage, auth, config, …). diff --git a/skills/bailian-finetune/SKILL.md b/skills/bailian-finetune/SKILL.md index 3d4f1f39..a917118a 100644 --- a/skills/bailian-finetune/SKILL.md +++ b/skills/bailian-finetune/SKILL.md @@ -18,10 +18,10 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) (dataset / finetune / deploy) and `bl --help` — do not guess flags. Examples in `reference/` stay bare; wrap with Call attribution when running. The whole pipeline requires an API key. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-finetune`; replace `codex` with this host). After deploy, `bl text chat` is owned by `bailian-cli`. +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-finetune`; replace `codex` with this host). After deploy, `bl text chat` is owned by `bailian-cli`. **When copying commands into a reusable script / template / task definition, switch to the protocol `script` template (never keep `agent`); the sample below is for this-turn inline execution only. Strip attribution when handing a command to the user to paste.** ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-finetune BAILIAN_SKILL_VERSION=2.5.0 bl dataset validate --file train.jsonl +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-finetune BAILIAN_SKILL_VERSION= bl dataset validate --file train.jsonl ``` ## End-to-end workflow (follow in order) diff --git a/skills/bailian-gen/SKILL.md b/skills/bailian-gen/SKILL.md index 64f55592..18f54a36 100644 --- a/skills/bailian-gen/SKILL.md +++ b/skills/bailian-gen/SKILL.md @@ -22,10 +22,10 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent (one-time ask templates), Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/`](reference/index.md) and `bl --help` — do not guess flags. Examples in `reference/` stay bare; wrap with Call attribution when running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-gen`; replace `codex` with this host): +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-gen`; replace `codex` with this host). **When copying commands into a reusable script / template / task definition, switch to the protocol `script` template (never keep `agent`); the sample below is for this-turn inline execution only. Strip attribution when handing a command to the user to paste.** ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION=2.5.0 bl image generate --prompt "A cat in space" --out-dir ./out/ +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-gen BAILIAN_SKILL_VERSION= bl image generate --prompt "A cat in space" --out-dir ./out/ ``` ## Consent (short version; full rules in bailian-protocol) diff --git a/skills/bailian-knowledge/SKILL.md b/skills/bailian-knowledge/SKILL.md index 09093c13..14c2ac87 100644 --- a/skills/bailian-knowledge/SKILL.md +++ b/skills/bailian-knowledge/SKILL.md @@ -70,7 +70,7 @@ description: >- ## 命令执行与参考 -执行任何 `bl` 命令前读取 [共享协议](../bailian-protocol/SKILL.md),完成版本预检、鉴权和实际风险确认;协议缺失不妨碍本地发现与解释,但须提示 `bl skill init` 补齐后再执行。沿用当前产品,用 `bl knowledge --introspect` 或 `kscli --introspect` 发现能力,切换产品或更新版本后重新读取。不猜 flag,不替换前缀推导路径;当前 schema 不支持的能力如实说明,不承诺升级一定提供。 +执行任何 `bl` 命令前读取 [共享协议](../bailian-protocol/SKILL.md),完成版本预检、鉴权、[调用归因](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command)和实际风险确认;协议缺失不妨碍本地发现与解释,但须提示 `bl skill init` 补齐后再执行。沿用当前产品,用 `bl knowledge --introspect` 或 `kscli --introspect` 发现能力,切换产品或更新版本后重新读取。不猜 flag,不替换前缀推导路径;当前 schema 不支持的能力如实说明,不承诺升级一定提供。 **把命令写入可复用脚本 / 模板 / 任务定义时,改用协议的 `script` 模板(不要保留 `agent`);若出现 agent 样例,仅适用于当面 inline。交给用户手动粘贴时去掉归因前缀。** 个人绑定的业务调用显式传已核实的 `--workspace-id`,优先 `--output json`。使用真实返回的 ID;知识库 index ID 不能当作检索 agent ID。凭证与签名上传 URL 不进入回复、绑定或版本库。用户文本作为参数传递,不作为 shell 代码执行。 diff --git a/skills/bailian-managed-agent/SKILL.md b/skills/bailian-managed-agent/SKILL.md index 3082558f..2761aff6 100644 --- a/skills/bailian-managed-agent/SKILL.md +++ b/skills/bailian-managed-agent/SKILL.md @@ -20,10 +20,10 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): High-risk operation confirmation, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), and CLI errors: report an issue. Command details are authoritative in [`reference/managed-agent.md`](reference/managed-agent.md) and `bl managed-agent --help` — do not guess flags. Examples in `reference/` stay bare; wrap with Call attribution when running. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-managed-agent`; replace `codex` with this host): +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-managed-agent`; replace `codex` with this host). **When copying commands into a reusable script / template / task definition (including project scripts), switch to the protocol `script` template (never keep `agent`); the sample below is for this-turn inline execution only. Strip attribution when handing a command to the user to paste.** ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-managed-agent BAILIAN_SKILL_VERSION=2.5.0 bl managed-agent plan +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-managed-agent BAILIAN_SKILL_VERSION= bl managed-agent plan ``` ## Safety guardrail (the most important rule) diff --git a/skills/bailian-memory/SKILL.md b/skills/bailian-memory/SKILL.md index 65c11181..a02354f0 100644 --- a/skills/bailian-memory/SKILL.md +++ b/skills/bailian-memory/SKILL.md @@ -21,10 +21,10 @@ description: >- 执行任何 `bl` 命令前,先读取共享协议 [bailian-protocol](../bailian-protocol/SKILL.md),遵循鉴权、版本预检、调用归因和高风险确认。协议缺失不妨碍识别记忆意图或解释启用流程;但执行命令前须补齐,提示 `bl skill init`,不能静默退回内置记忆并声称本服务已工作。 -**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-memory`; replace `codex` with this host). Fill `` / `` from `~/.bailian/personal-memory/config.json`; do not invent ids. Command names in the tables below are arguments only. +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-memory`; replace `codex` with this host). Fill `` / `` from `~/.bailian/personal-memory/config.json`; do not invent ids. Command names in the tables below are arguments only. **When copying commands into a reusable script / template / task definition, switch to the protocol `script` template (never keep `agent`); the sample below is for this-turn inline execution only. Strip attribution when handing a command to the user to paste.** ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-memory BAILIAN_SKILL_VERSION=2.5.0 bl memory list --user-id --workspace-id --page-size 1 --output json +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-memory BAILIAN_SKILL_VERSION= bl memory list --user-id --workspace-id --page-size 1 --output json ``` ## 入口与范围 diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index 1ea125e4..f58f858b 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -82,13 +82,25 @@ Commands declaring `preparation: "read-only"` may authenticate and read remote r ## Call attribution (mandatory for every Agent `bl` command) -Examples in this protocol, `assets/`, business skills, and generated `reference/` show bare `bl …`. When an Agent **runs** a command, wrap that single invocation with one of the templates below. Humans must not set these variables. Anything other than an explicit agent is recorded as `unknown`. +Examples in this protocol, `assets/`, business skills, and generated `reference/` show bare `bl …`. When an Agent **runs** a command, wrap that single invocation with the matching template below. Humans must not set these variables to impersonate an agent; reusable script files may use the `script` prefix described below. Explicit `agent` / `ai_agent` → recorded as `agent`; explicit `script` → recorded as `script`; anything else → `unknown`. -`--help` and `--version` skip telemetry and need no prefix. Every other `bl` does, including `bl skill init`, `bl skill update`, and `bl update`. Do not `export` the variables into the shell session. If the host accepts a one-shot env map without rewriting the command string, set the same four variables there instead. +`--help` and `--version` skip telemetry and need no prefix. Every other `bl` does, including `bl skill init`, `bl skill update`, and `bl update`. Do not `export` these variables into an interactive shell session, shell profile, direnv, or CI global environment. Local assignment **inside a reusable script file** is allowed. If the host accepts a one-shot env map without rewriting the command string, set the same variables there instead. -Pick the template that matches the **current shell**. Windows Codex defaults to PowerShell — do not paste the bash form into PowerShell. Sample host id is `codex`; replace with this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Use `unknown` only when you cannot tell. Do not borrow another product's name. Do not scan install directories. +Pick the template that matches the **artifact**: -### bash / zsh / Git Bash / WSL +| Artifact | Declare | +| --------------------------------------------------------------------------- | -------------------------------------------------------------- | +| Agent runs `bl` inline in the current turn (not written to a reusable file) | `agent` four-variable prefix | +| Command written into a reusable file / template / task definition | `script` prefix — **never** `agent`, whoever later executes it | +| Both coexist | File contents stay `script`; live inline stays `agent` | +| Hand the command to the user to paste manually | Strip attribution prefixes | +| Shell profile / direnv / CI global env | Forbidden | + +`script` does not require an Agent author — CI- or human-maintained reusable scripts may declare it too. Business skills that generate scripts should point here; they need not repeat this section. + +Pick the template that matches the **current shell**. Windows Codex defaults to PowerShell — do not paste the bash form into PowerShell. Sample host id is `codex`; replace with this host's stable id (examples: `codex`, `qwen-code`, `claude-code`, `cursor`, `qoder`). Use `unknown` only when you cannot tell. Do not borrow another product's name. Do not scan install directories. For `script`, `BAILIAN_CALLER_NAME` is the host that authored or maintains the script. + +### bash / zsh / Git Bash / WSL — agent (inline) ```bash BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME= BAILIAN_SKILL_NAME= BAILIAN_SKILL_VERSION= bl @@ -97,7 +109,7 @@ BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME= BAILIAN_SKILL_NAME= bl skill init ``` Inside a command substitution: put the four variables inside `$(...)`. @@ -105,10 +117,16 @@ Inside a command substitution: put the four variables inside `$(...)`. With `NO_COLOR` (config is owned by `bailian-cli`): ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION=2.5.0 NO_COLOR=1 bl config show --output text +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-cli BAILIAN_SKILL_VERSION= NO_COLOR=1 bl config show --output text ``` -### PowerShell (Windows Codex default) +### bash / zsh / Git Bash / WSL — script (reusable file) + +```bash +BAILIAN_CALLER_TYPE=script BAILIAN_CALLER_NAME= bl +``` + +### PowerShell (Windows Codex default) — agent (inline) ```powershell $env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME=''; $env:BAILIAN_SKILL_NAME=''; $env:BAILIAN_SKILL_VERSION=''; bl ; $code=$LASTEXITCODE; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue; if ($code -ne 0) { exit $code } @@ -117,14 +135,20 @@ $env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME=''; $env:BAILIA Filled sample for this protocol: ```powershell -$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME='codex'; $env:BAILIAN_SKILL_NAME='bailian-protocol'; $env:BAILIAN_SKILL_VERSION='2.5.0'; bl skill init; $code=$LASTEXITCODE; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue; if ($code -ne 0) { exit $code } +$env:BAILIAN_CALLER_TYPE='agent'; $env:BAILIAN_CALLER_NAME='codex'; $env:BAILIAN_SKILL_NAME='bailian-protocol'; $env:BAILIAN_SKILL_VERSION=''; bl skill init; $code=$LASTEXITCODE; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME,Env:BAILIAN_SKILL_NAME,Env:BAILIAN_SKILL_VERSION -ErrorAction SilentlyContinue; if ($code -ne 0) { exit $code } ``` Clear the four variables after each command so they do not linger in the Codex session. Save `$LASTEXITCODE` before `Remove-Item` and `exit` only on nonzero — a trailing successful cleanup must not mask `bl` failures (e.g. exit 7 `requires_confirmation`). +### PowerShell — script (reusable file) + +```powershell +$env:BAILIAN_CALLER_TYPE='script'; $env:BAILIAN_CALLER_NAME=''; bl ; $code=$LASTEXITCODE; Remove-Item Env:BAILIAN_CALLER_TYPE,Env:BAILIAN_CALLER_NAME -ErrorAction SilentlyContinue; if ($code -ne 0) { exit $code } +``` + ### Owning skill -Reuse the same four-variable shape on every later `bl`, but change `BAILIAN_SKILL_NAME` when the command belongs to a different skill; keep `BAILIAN_CALLER_NAME` as this host. Each business skill shows one filled-in sample for its own commands. +Reuse the same four-variable shape on every later **inline agent** `bl`, but change `BAILIAN_SKILL_NAME` when the command belongs to a different skill; keep `BAILIAN_CALLER_NAME` as this host. `script` invocations omit skill variables. Each business skill shows one filled-in agent sample for its own commands. | Task | `` | | ------------------------------------------------------------------------ | -------------------------------------- | @@ -133,7 +157,7 @@ Reuse the same four-variable shape on every later `bl`, but change `BAILIAN_SKIL | image / video / speech / vision / omni | `bailian-gen` | | Other domain commands | The `bailian-*` skill currently in use | -`BAILIAN_SKILL_VERSION`: copy `metadata.version` from that owning skill's `SKILL.md` frontmatter. The family currently shares one version; if the frontmatter differs from `2.5.0` in a sample, use the frontmatter. +`BAILIAN_SKILL_VERSION`: replace `` with the owning skill's `SKILL.md` frontmatter `metadata.version` (do not paste the placeholder literally). The family currently shares one version across skills. ## Version & updates (after provider selection, before the first `bl` command) diff --git a/skills/bailian-sandbox/SKILL.md b/skills/bailian-sandbox/SKILL.md index fc2bd3f6..3044da9c 100644 --- a/skills/bailian-sandbox/SKILL.md +++ b/skills/bailian-sandbox/SKILL.md @@ -17,10 +17,10 @@ description: >- Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKILL.md) for consent, high-risk confirmation, version checks, call attribution, authentication, and error handling. If it is missing, stop execution and prompt the user to install the full family with `bl skill init`. Examples in `reference/` stay bare; wrap with Call attribution when running. -**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-sandbox`; replace `codex` with this host). `bl auth` / `bl config` are owned by `bailian-cli`. +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-sandbox`; replace `codex` with this host). `bl auth` / `bl config` are owned by `bailian-cli`. **When copying commands into a reusable script / template / task definition, switch to the protocol `script` template (never keep `agent`); the sample below is for this-turn inline execution only. Strip attribution when handing a command to the user to paste.** ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-sandbox BAILIAN_SKILL_VERSION=2.5.0 bl sandbox list +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-sandbox BAILIAN_SKILL_VERSION= bl sandbox list ``` ## Scope and setup diff --git a/skills/bailian-web-search/SKILL.md b/skills/bailian-web-search/SKILL.md index 38c72d38..ff87fd4c 100644 --- a/skills/bailian-web-search/SKILL.md +++ b/skills/bailian-web-search/SKILL.md @@ -20,10 +20,10 @@ description: >- **CRITICAL — Before executing, MUST read the shared protocol in [`../bailian-protocol/SKILL.md`](../bailian-protocol/SKILL.md): Provider selection and consent, Version & updates (pre-flight checklist), Call attribution (every Agent `bl` command), Setup & auth, and CLI errors: report an issue. If that protocol file is missing, stop and run `bl skill init`; do not guess auth/consent.** -**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-web-search`; replace `codex` with this host). `bl config` / `bl text chat` are owned by `bailian-cli`. +**Call attribution:** Examples below and in `reference/` stay bare `bl …`. When running a command, wrap it with [`bailian-protocol` → Call attribution](../bailian-protocol/SKILL.md#call-attribution-mandatory-for-every-agent-bl-command) (bash or PowerShell). One sample for this skill (`BAILIAN_SKILL_NAME=bailian-web-search`; replace `codex` with this host). `bl config` / `bl text chat` are owned by `bailian-cli`. **When copying commands into a reusable script / template / task definition, switch to the protocol `script` template (never keep `agent`); the sample below is for this-turn inline execution only. Strip attribution when handing a command to the user to paste.** ```bash -BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION=2.5.0 bl search web --query "阿里云百炼最新功能" +BAILIAN_CALLER_TYPE=agent BAILIAN_CALLER_NAME=codex BAILIAN_SKILL_NAME=bailian-web-search BAILIAN_SKILL_VERSION= bl search web --query "阿里云百炼最新功能" ``` > **Scope:** model-aware routing for web search inside Agent-driven `bl` workflows — this skill owns the routing decision only.