diff --git a/CHANGELOG.md b/CHANGELOG.md index 993e6ffe3a2..42f187ad8b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -217,6 +217,7 @@ Docs: https://docs.openclaw.ai - PI embedded runner/Feishu docs: propagate sender identity into embedded attempts so Feishu doc auto-grant restores requester access for embedded-runner executions. (#32915) thanks @cszhouwei. - Agents/usage normalization: normalize missing or partial assistant usage snapshots before compaction accounting so `openclaw agent --json` no longer crashes when provider payloads omit `totalTokens` or related usage fields. (#34977) thanks @sp-hk2ldn. - Venice/default model refresh: switch the built-in Venice default to `kimi-k2-5`, update onboarding aliasing, and refresh Venice provider docs/recommendations to match the current private and anonymized catalog. (from #12964) Fixes #20156. Thanks @sabrinaaquino and @vincentkoc. +- Agents/skill API write pacing: add a global prompt guardrail that treats skill-driven external API writes as rate-limited by default, so runners prefer batched writes, avoid tight request loops, and respect `429`/`Retry-After`. Thanks @vincentkoc. ## 2026.3.2 diff --git a/skills/notion/SKILL.md b/skills/notion/SKILL.md index 52b2ef5245d..f4152d23bf7 100644 --- a/skills/notion/SKILL.md +++ b/skills/notion/SKILL.md @@ -168,5 +168,7 @@ Common property formats for database items: - Page/database IDs are UUIDs (with or without dashes) - The API cannot set database view filters — that's UI-only -- Rate limit: ~3 requests/second average +- Rate limit: ~3 requests/second average, with `429 rate_limited` responses using `Retry-After` +- Append block children: up to 100 children per request, up to two levels of nesting in a single append request +- Payload size limits: up to 1000 block elements and 500KB overall - Use `is_inline: true` when creating data sources to embed them in pages diff --git a/src/agents/system-prompt.test.ts b/src/agents/system-prompt.test.ts index 57dfb26689c..64497364f8c 100644 --- a/src/agents/system-prompt.test.ts +++ b/src/agents/system-prompt.test.ts @@ -144,6 +144,9 @@ describe("buildAgentSystemPrompt", () => { expect(prompt).toContain("## Skills (mandatory)"); expect(prompt).toContain(""); + expect(prompt).toContain( + "When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.", + ); }); it("omits skills in minimal prompt mode when skillsPrompt is absent", () => { diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts index a60ae54306b..a3d593ab6b8 100644 --- a/src/agents/system-prompt.ts +++ b/src/agents/system-prompt.ts @@ -29,6 +29,7 @@ function buildSkillsSection(params: { skillsPrompt?: string; readToolName: strin "- If multiple could apply: choose the most specific one, then read/follow it.", "- If none clearly apply: do not read any SKILL.md.", "Constraints: never read more than one skill up front; only read after selecting.", + "- When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.", trimmed, "", ];