Skip to content

[AI] fix(plugins): recognize document-extractors as a capability kind…#91597

Merged
steipete merged 4 commits into
openclaw:mainfrom
xydt-tanshanshan:fix/document-extractors-capability-kind-91539
Jun 28, 2026
Merged

[AI] fix(plugins): recognize document-extractors as a capability kind…#91597
steipete merged 4 commits into
openclaw:mainfrom
xydt-tanshanshan:fix/document-extractors-capability-kind-91539

Conversation

@xydt-tanshanshan

@xydt-tanshanshan xydt-tanshanshan commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

PluginCapabilityKind in inspect-shape.ts did not include "document-extractors", so plugins declaring contracts.documentExtractors (like the bundled document-extract plugin) showed capabilityCount: 0, tools: [], and shape: "non-capability" in openclaw plugins inspect. This made the plugin appear broken in diagnostics even though its contract declaration was correct.

Add "document-extractors" to the PluginCapabilityKind union type and read plugin.contracts?.documentExtractors in buildPluginCapabilityEntries(), so the inspection system correctly reflects the plugin's declared extraction capability.

Change Type

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue

Motivation

The document-extract plugin (bundled, contracts.documentExtractors: ["pdf"]) was misclassified as "non-capability" shape with capabilityCount: 0 in openclaw plugins inspect. Users upgrading to 2026.6.1 saw the plugin report zero capabilities despite the manifest contract being valid, causing confusion about whether PDF/DOCX extraction was functional.

The root cause is that PluginCapabilityKind — the enumeration used by buildPluginCapabilityEntries() to count and classify plugin capabilities — never included "document-extractors". All other contract types (providers, channels, etc.) have corresponding capability kinds, but documentExtractors was missing from the list.

Changes

File: src/plugins/inspect-shape.ts

  1. Added "document-extractors" to PluginCapabilityKind type union (alphabetically after "transcript-source")
  2. Added { kind: "document-extractors" as const, ids: plugin.contracts?.documentExtractors ?? [] } entry in buildPluginCapabilityEntries()

No new imports. Reads from plugin.contracts?.documentExtractors which already exists on PluginRecord via PluginManifestContracts.

Verification

  • src/plugins/contracts/shape.contract.test.ts — passed (1 test)
  • src/plugins/status.test.ts — passed (27 tests)
  • src/plugins/contracts/registry.contract.test.ts — passed (21 tests)

Real Behavior Proof

Behavior addressed: Plugins with contracts.documentExtractors now show correct capabilityCount, shape, and capabilities in openclaw plugins inspect output.

Real environment tested: Linux (Ubuntu), Node.js 22.19+, local checkout on branch fix/document-extractors-capability-kind-91539, commit 12b8f60.

Exact steps or command run after this patch:

pnpm build
pnpm openclaw plugins inspect document-extract --runtime --json

Evidence after fix: Live openclaw plugins inspect output confirms the fix:

Field Before (issue #91539) After (this patch)
shape "non-capability" "plain-capability"
capabilityCount 0 1
capabilityMode "none" "plain"
capabilities [] [{"kind":"document-extractors","ids":["pdf"]}]

Full after-fix output (redacted workspace path):

{
  "shape": "plain-capability",
  "capabilityMode": "plain",
  "capabilityCount": 1,
  "capabilities": [
    {
      "kind": "document-extractors",
      "ids": ["pdf"]
    }
  ],
  "plugin": {
    "id": "document-extract",
    "status": "loaded",
    "contracts": {
      "documentExtractors": ["pdf"]
    }
  }
}

Observed result after fix: Shape diagnostic correctly reflects document-extract contract as a plugin capability.

What was not tested: Runtime document extraction functionality (PDF/DOCX file reading) is unchanged — this PR only fixes diagnostic display.

Risks

  • Low risk: Only changes the inspection/diagnostic surface, not runtime resolution or plugin loading behavior.
  • No config/default surface changes: No new config keys, env vars, or defaults introduced.
  • Type surface: PluginCapabilityKind is used in PluginCapabilityEntry.kind and PluginShapeSummary.capabilities[].kind. Adding a new union member is additive — existing consumers that iterate or filter on kind will now see "document-extractors" entries. No breaking change for code that pattern-matches on the existing kinds.

@openclaw-barnacle openclaw-barnacle Bot added size: XS triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels Jun 9, 2026
@clawsweeper

clawsweeper Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 28, 2026, 5:01 AM ET / 09:01 UTC.

Summary
Adds document-extractors to plugin inspect capability classification, maps contracts.documentExtractors into inspect capabilities, and extends the plugin shape contract matrix.

PR surface: Source +2, Tests +20. Total +22 across 2 files.

Reproducibility: yes. for the inspect classification symptom by source inspection: current main and v2026.6.10 have the manifest contract but the inspect capability taxonomy omits it. The PR body also supplies after-fix CLI JSON output showing the corrected capability entry.

Review metrics: 1 noteworthy metric.

  • Public inspect capability kind: 1 added. The branch adds a machine-readable inspect JSON kind that public consumers may pattern-match.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #91539
Summary: This PR is a partial candidate fix for the linked user-facing document-extract issue, limited to inspect capability classification.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

Maintainer options:

  1. Accept Additive Inspect Kind (recommended)
    Merge once maintainers accept that openclaw plugins inspect --json may now emit document-extractors in capabilities[].kind.
  2. Pause Inspect Taxonomy
    Pause or close if document extractor contracts should remain visible only under plugin.contracts until a broader inspect taxonomy decision.

Next step before merge

  • [P2] Maintainers need to accept the additive public inspect JSON kind; there is no narrow automated code repair left.

Security
Cleared: The diff only changes a TypeScript inspect classifier and focused test coverage; it adds no dependency, script, secret, network, or code-execution surface.

Review details

Best possible solution:

Land the diagnostic fix after maintainers accept the additive public inspect kind, while keeping the broader document extraction runtime/build regression on its linked PR path.

Do we have a high-confidence way to reproduce the issue?

Yes for the inspect classification symptom by source inspection: current main and v2026.6.10 have the manifest contract but the inspect capability taxonomy omits it. The PR body also supplies after-fix CLI JSON output showing the corrected capability entry.

Is this the best way to solve the issue?

Yes for the diagnostic bug: wiring the existing manifest contract into the inspect classifier is the narrow owner-boundary fix. It is not the complete runtime document-reading fix for the linked user report.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 7ba9212665a7.

Label changes

Label justifications:

  • P2: This is a focused bundled plugin diagnostic/API correction with limited blast radius.
  • merge-risk: 🚨 compatibility: The diff adds a new JSON-visible and exported plugin inspect capability kind that existing consumers may exhaustively handle.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix CLI JSON from openclaw plugins inspect document-extract --runtime --json showing document-extractors in the capability list.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix CLI JSON from openclaw plugins inspect document-extract --runtime --json showing document-extractors in the capability list.
Evidence reviewed

PR surface:

Source +2, Tests +20. Total +22 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 2 0 +2
Tests 1 21 1 +20
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 23 1 +22

What I checked:

  • Current main inspect gap: Current main's PluginCapabilityKind and buildPluginCapabilityEntries() omit document-extractors, so a plugin whose only declared capability is contracts.documentExtractors is not counted by inspect shape. (src/plugins/inspect-shape.ts:5, 7ba9212665a7)
  • Inspect report exposes machine-readable capabilities: buildPluginInspectReport() exposes capabilityMode, capabilityCount, and capabilities from buildPluginShapeSummary(), so this change affects public inspect JSON output. (src/plugins/status.ts:58, 7ba9212665a7)
  • Manifest contract already exists: PluginManifestContracts already has documentExtractors, so the PR wires an existing manifest contract into diagnostics rather than inventing a new manifest field. (src/plugins/manifest.ts:406, 7ba9212665a7)
  • Bundled plugin declares the contract: The bundled document-extract plugin is enabled by default and declares contracts.documentExtractors: ["pdf"]. (extensions/document-extract/openclaw.plugin.json:9, 7ba9212665a7)
  • PR patch: The PR adds the document-extractors capability kind, reads plugin.contracts?.documentExtractors, and folds a document extractor fixture into the shape matrix. (src/plugins/inspect-shape.ts:11, 70ce170ad3db)
  • Latest release still has the gap: Release v2026.6.10 still omits document-extractors from inspect-shape while the bundled document-extract manifest declares documentExtractors, so the PR is still relevant. (src/plugins/inspect-shape.ts:5, aa69b12d0086)

Likely related people:

  • steipete: Commit metadata for 30cbfa3457ed shows recent work on src/plugins/inspect-shape.ts, src/plugins/status.ts, and the shape contract test that this PR extends. (role: recent plugin inspect-shape contributor; confidence: high; commits: 30cbfa3457ed, 70ce170ad3db; files: src/plugins/inspect-shape.ts, src/plugins/status.ts, src/plugins/contracts/shape.contract.test.ts)
  • vincentkoc: Commit metadata for 767dd0d4b4c4 and e3cba98f3904 shows the document extraction plugin and its manifest/runtime contract path were moved into the plugin architecture by this contributor. (role: document extraction feature contributor; confidence: high; commits: 767dd0d4b4c4, e3cba98f3904, 824257c9aafb; files: extensions/document-extract/openclaw.plugin.json, src/plugins/manifest.ts, src/plugins/contracts/registry.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 9, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels Jun 9, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 9, 2026
xydt-tanshanshan added a commit to xydt-tanshanshan/openclaw that referenced this pull request Jun 9, 2026
Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 9, 2026
@xydt-tanshanshan

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 9, 2026
xydt-tanshanshan added a commit to xydt-tanshanshan/openclaw that referenced this pull request Jun 15, 2026
Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.
@xydt-tanshanshan
xydt-tanshanshan force-pushed the fix/document-extractors-capability-kind-91539 branch from 0fafe27 to 459d11c Compare June 15, 2026 07:24
@xydt-tanshanshan

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 15, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 15, 2026
@clawsweeper clawsweeper Bot removed the merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. label Jun 15, 2026
@xydt-tanshanshan
xydt-tanshanshan force-pushed the fix/document-extractors-capability-kind-91539 branch from 459d11c to 5fad0c5 Compare June 23, 2026 08:38
xydt-tanshanshan added a commit to xydt-tanshanshan/openclaw that referenced this pull request Jun 23, 2026
Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.
@steipete steipete self-assigned this Jun 28, 2026
xydt-tanshanshan and others added 4 commits June 28, 2026 01:51
… in inspect-shape

PluginCapabilityKind did not include "document-extractors", causing
plugins that declare contracts.documentExtractors (like document-extract)
to show capabilityCount=0 and shape="non-capability" in plugins inspect.

Add "document-extractors" to PluginCapabilityKind and read from
plugin.contracts.documentExtractors in buildPluginCapabilityEntries().

Related to openclaw#91539
Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.
@steipete
steipete force-pushed the fix/document-extractors-capability-kind-91539 branch from 5fad0c5 to 70ce170 Compare June 28, 2026 08:51
@steipete

Copy link
Copy Markdown
Contributor

Land-ready verification for 70ce170ad3db45c82c98b21b75a5bc9d617a6757:

  • Prepared change: accepted the additive JSON-visible document-extractors capability kind and folded its coverage into the existing shape compatibility matrix, removing duplicate fixture/report setup.
  • Focused proof: node scripts/run-vitest.mjs src/plugins/contracts/shape.contract.test.ts src/plugins/status.test.ts src/plugins/contracts/registry.contract.test.ts — 49 tests passed across two shards after consolidation.
  • Fresh autoreview of the prepared shape: no findings, confidence 0.98.
  • Exact-head hosted CI: run 28317027947 passed.
  • Live evidence: the contributor's plugins inspect document-extract --runtime --json run reports plain-capability, count 1, and document-extractors with pdf.
  • Known local gap: my source-CLI rerun hit the repository-wide crabline allowlist bootstrap failure; a direct TypeScript entry fallback hung before JSON output and was terminated.

This lands the inspect-classification fix only. It does not claim to fix runtime PDF/DOCX extraction, so #91539 remains open for the separate package/runtime path.

@steipete
steipete merged commit d17b970 into openclaw:main Jun 28, 2026
93 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 29, 2026
openclaw#91597)

* [AI] fix(plugins): recognize document-extractors as a capability kind in inspect-shape

PluginCapabilityKind did not include "document-extractors", causing
plugins that declare contracts.documentExtractors (like document-extract)
to show capabilityCount=0 and shape="non-capability" in plugins inspect.

Add "document-extractors" to PluginCapabilityKind and read from
plugin.contracts.documentExtractors in buildPluginCapabilityEntries().

Related to openclaw#91539

* [AI] test(plugins): add document-extractors shape contract coverage

Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.

* [AI] chore: rebase on main to refresh CI

* test(plugins): fold extractor into shape matrix

---------

Co-authored-by: Peter Steinberger <[email protected]>
QiuYuang pushed a commit to QiuYuang/openclaw that referenced this pull request Jul 1, 2026
openclaw#91597)

* [AI] fix(plugins): recognize document-extractors as a capability kind in inspect-shape

PluginCapabilityKind did not include "document-extractors", causing
plugins that declare contracts.documentExtractors (like document-extract)
to show capabilityCount=0 and shape="non-capability" in plugins inspect.

Add "document-extractors" to PluginCapabilityKind and read from
plugin.contracts.documentExtractors in buildPluginCapabilityEntries().

Related to openclaw#91539

* [AI] test(plugins): add document-extractors shape contract coverage

Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.

* [AI] chore: rebase on main to refresh CI

* test(plugins): fold extractor into shape matrix

---------

Co-authored-by: Peter Steinberger <[email protected]>
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 1, 2026
openclaw#91597)

* [AI] fix(plugins): recognize document-extractors as a capability kind in inspect-shape

PluginCapabilityKind did not include "document-extractors", causing
plugins that declare contracts.documentExtractors (like document-extract)
to show capabilityCount=0 and shape="non-capability" in plugins inspect.

Add "document-extractors" to PluginCapabilityKind and read from
plugin.contracts.documentExtractors in buildPluginCapabilityEntries().

Related to openclaw#91539

* [AI] test(plugins): add document-extractors shape contract coverage

Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.

* [AI] chore: rebase on main to refresh CI

* test(plugins): fold extractor into shape matrix

---------

Co-authored-by: Peter Steinberger <[email protected]>
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 3, 2026
openclaw#91597)

* [AI] fix(plugins): recognize document-extractors as a capability kind in inspect-shape

PluginCapabilityKind did not include "document-extractors", causing
plugins that declare contracts.documentExtractors (like document-extract)
to show capabilityCount=0 and shape="non-capability" in plugins inspect.

Add "document-extractors" to PluginCapabilityKind and read from
plugin.contracts.documentExtractors in buildPluginCapabilityEntries().

Related to openclaw#91539

* [AI] test(plugins): add document-extractors shape contract coverage

Add a test case verifying that plugins declaring
contracts.documentExtractors are classified as
plain-capability shape with capabilityCount=1
and capabilities including the document-extractors kind.

Addresses ClawSweeper P2 review finding on PR openclaw#91597.

* [AI] chore: rebase on main to refresh CI

* test(plugins): fold extractor into shape matrix

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants