Skip to content

docs(rfc): propose plugin interfaces - #2549

Merged
hidb4ai merged 12 commits into
oceanbase:masterfrom
jasper-yl:rfc/plugin-interfaces
Nov 13, 2026
Merged

hidb4ai merged 12 commits into
oceanbase:masterfrom
jasper-yl:rfc/plugin-interfaces

Conversation

@jasper-yl

@jasper-yl jasper-yl commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Which issue or RFC does this PR close?

This PR proposes a new RFC that replaces the plugin contracts and management mechanisms of RFC #2175 (Artifact plugins, implemented in #2246). It is implemented in #2616. Standalone Source plugins and collection, which replace RFC #2012, are proposed separately in #2617.

Rationale for this change

The managed Artifact plugin framework makes PC Server carry plugin lifecycle on behalf of third-party code: persisted enable/disable/reload/unload state machines, registration-generation fencing, and frozen content schemas with framework-built declarative indexes. As discussed with maintainers, plugins should instead implement a few interfaces that PC Server calls when needed, similar to Dify's plugin model, and own their content structure and indexes.

What changes are included in this PR?

New RFC docs/{en,zh}/rfcs/2549-plugin-interfaces.md (Chinese first, English translation in sync):

  • Plugin shape: a directory with plugin.py, which assigns an ArtifactPlugin declaration to plugin; no manifest file. setup(ctx) returns the plugin object.
  • Methods: render_artifact (required), generate (required with a schedule or on_sources), and optional search_artifacts and user-change methods (create_artifact, update_artifact, merge_artifacts, forget_artifact, restore_artifact). A methods-at-a-glance table lists when each is called and where it runs. Reads, history, governance, and tags call no plugin method.
  • Presentation and search belong to the plugin: core builds no index for plugin families. GET .../{artifact_id}/rendering returns the plugin's default presentation. Generic search passes the complete request to search_artifacts, and core keeps only current, active revisions the caller may read. Prepared Context sections may list plugin families, with an optional search passed through.
  • Generation and user changes: generate writes in async with writer.transaction(), committed with the consumption cursor; user changes go through the plugin, with core handling authorization, version checks, and provenance. Plugins may declare their own Source types to record what users asked for.
  • Execution: background calls run in Supervisor Workers; synchronous calls run in a per-plugin host process that core manages. ctx.storage and ctx.models give plugins dedicated storage and the Server's models without credentials.
  • Persistence: one new migration revision removes the old framework's storage only when it holds no data (otherwise the upgrade is refused), adds pc_artifacts.metadata with the writing plugin's name and version, accepts plugin: bindings without registration, and keeps frozen revision resources unchanged; portable revision records gain metadata.
  • Lifecycle: plugins load at startup with no persisted plugin state. Hot reload, data upgrades, plugin APIs, and pages are in RFC #2579.

Are there any user-facing changes?

This PR changes documentation only. The proposed design, implemented in #2616, removes /v1/admin/artifact-plugins, powercontext.artifact_plugins, and POWERCONTEXT_SERVER_ARTIFACT_PLUGINS_DIR, and refuses to upgrade while plugins of the old framework still hold data. Typed clients see CreateArtifactRequest become a choice between built-in and plugin branches, and several family fields (ArtifactCreated.family, TaggableArtifactFamily, ContextAssemblySection.family, receipt families) and CreateSourceRequest.source_type become strings; wire formats of existing requests are unchanged.

How was this change tested?

AI usage statement

Drafted with Claude Code (Claude Opus 5.5) under the author's direction and review.

🤖 Generated with Claude Code

Replace the Source and Artifact plugin frameworks with a few interfaces
that PC Server calls through the Supervisor. Core keeps only Sources,
Artifacts, collection targets, and consumption progress; plugins no
longer have managed lifecycle state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jasper-yl and others added 2 commits November 8, 2026 10:45
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jasper-yl and others added 2 commits November 9, 2026 18:55
…APIs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dge collection

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@hidb4ai hidb4ai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The simplification is reasonable, but the retry/storage and no-op/provenance contracts need to be consistent before this RFC is accepted. The two inline findings apply to both translations.

Comment thread docs/en/rfcs/2549-plugin-interfaces.md Resolved
Comment thread docs/en/rfcs/2549-plugin-interfaces.md Resolved
Bring the RFC in line with the implementation and the decisions since the last
revision: user changes run through the plugin in a host process that starts for
every loaded plugin; Artifact plugins may declare their own Source Definitions;
Inputs can name a Projection per Source type; plugin storage, models, and the
generic create and Source write contracts are spelled out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@hidb4ai hidb4ai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content-digest storage guidance and the explicit distinction between generation no-ops and user-edit provenance address my earlier RFC findings. One new contract gap remains: plugins cannot detect a same-dimension embedding-model change.

Comment on lines +595 to +598
class PluginModels(Protocol):
embedding_available: bool # whether Server has an embedding model
embedding_dimension: int | None # vector dimension; None without an embedding model
generation_available: bool # whether Server has a generation model

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve an embedding-space identity for plugin indexes

Replacing embedding_profile with availability flags and a dimension leaves plugins unable to implement the rebuild-on-configuration-change rule below. If an index was built with model A and Server restarts with a different model B of the same dimension, all exposed metadata stays unchanged, but embed() now returns vectors from a different space. The plugin can silently compare them with A's persisted vectors or mix both spaces in the same index. The existing core distinguishes same-dimension profiles for precisely this reason. Expose a non-secret embedding-space/profile fingerprint that changes with the model or relevant encoding configuration, and require it to match the persisted index before reuse. Please align both language versions.

jasper-yl and others added 5 commits November 12, 2026 10:22
…place the old frameworks in one migration

- Rename the factory to setup; render_artifact is required, search_artifacts
  optional, and generate required only with a schedule or on_sources, with a
  methods-at-a-glance table.
- Core no longer indexes plugin families: generic search passes the complete
  request to the plugin, and Prepared Context sections may list plugin families
  with optional search controls.
- One new migration revision adds pc_artifacts.metadata (plugin name and
  version), accepts plugin: bindings without registration, keeps the FTS check
  to built-in rows, bumps the export record format, and refuses to upgrade while
  the old plugin frameworks still hold data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ir own Source types

Standalone Source plugins, collection targets, and edge collection move to a
follow-up proposal, which will replace the old Source plugin framework; this
RFC replaces only the old Artifact plugin framework, and the old Source plugin
framework stays unchanged until then.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d Context budget as the request's

Prepared Context passes the request's byte budget and fills plugin entries in
section order, and receipt families become strings so plugin entries count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…plugin

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jasper-yl added a commit to jasper-yl/powercontext that referenced this pull request Nov 13, 2026
… and change their own Artifacts

Implements the Artifact plugin part of RFC oceanbase#2549 and the plugin APIs and
Dashboard pages of RFC oceanbase#2579, and replaces the managed Artifact plugin
framework (oceanbase#2246).

- A plugin is a directory with plugin.py assigning an ArtifactPlugin. Server
  checks it in a child process; generate runs in Supervisor Workers, and
  render_artifact, search_artifacts, user changes, Source writes of the
  plugin's own types, and plugin routes run in a per-plugin host process.
- Plugins present (GET .../rendering) and search their own families: generic
  search passes the complete request to search_artifacts, and Prepared Context
  sections may list plugin families. Core builds no index for them.
- Revision v1_5_0_005 removes the previous framework's storage only when it is
  empty, adds pc_artifacts.metadata (plugin name and code digest), and accepts
  plugin: bindings; frozen revision resources are unchanged. Portable revision
  records move to schema version 3 and still restore version 2.
- Plugin APIs mount at /v1/plugins/{name}/api with a configurable body
  ceiling, and plugin pages run in a sandboxed Dashboard frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jasper-yl added a commit to jasper-yl/powercontext that referenced this pull request Nov 13, 2026
RFC oceanbase#2549 renamed the factory to setup and requires render_artifact; standalone
Source plugins moved to RFC oceanbase#2617, so the examples declare routes and pages on
an Artifact plugin that brings its own Source type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@hidb4ai hidb4ai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hidb4ai
hidb4ai merged commit b5742c8 into oceanbase:master Nov 13, 2026
38 checks passed
hidb4ai pushed a commit that referenced this pull request Nov 14, 2026
* docs(rfc): propose plugin hot reload and plugin-defined APIs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): number plugin hot reload RFC as 2579

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): import plugins from version snapshots and mount routes as a group

Pin every call to a read-only snapshot named by the content digest so a
draining host never mixes versions and a failed update keeps the old one,
detect changes by content instead of size and mtime, mount plugin routes
under their own group with per-route Scope authorization, let plugins
create Scopes with core's existing permission, and state page isolation
as session isolation, stopping forwarding once the iframe navigates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): keep the plugin reload RFC at the contract level

Move scan, host replacement, and hosting page flows and the literal CSP header to the implementation design.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): let plugin routes opt in as MCP tools

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): let plugins upgrade their own data through a load hook

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): confirm write access in handlers, declare route body limits, and record API changes as Sources

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): name the factory setup and show routes on an Artifact plugin

RFC #2549 renamed the factory to setup and requires render_artifact; standalone
Source plugins moved to RFC #2617, so the examples declare routes and pages on
an Artifact plugin that brings its own Source type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(rfc): run upgrade on every role, keep it small, and name MCP tools without collisions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
jasper-yl added a commit to jasper-yl/powercontext that referenced this pull request Nov 14, 2026
… and change their own Artifacts

Implements the Artifact plugin part of RFC oceanbase#2549 and the plugin APIs and
Dashboard pages of RFC oceanbase#2579, and replaces the managed Artifact plugin
framework (oceanbase#2246).

- A plugin is a directory with plugin.py assigning an ArtifactPlugin. Server
  checks it in a child process; generate runs in Supervisor Workers, and
  render_artifact, search_artifacts, user changes, Source writes of the
  plugin's own types, and plugin routes run in a per-plugin host process.
- Plugins present (GET .../rendering) and search their own families: generic
  search passes the complete request to search_artifacts, and Prepared Context
  sections may list plugin families. Core builds no index for them.
- Revision v1_5_0_005 removes the previous framework's storage only when it is
  empty, adds pc_artifacts.metadata (plugin name and code digest), and accepts
  plugin: bindings; frozen revision resources are unchanged. Portable revision
  records move to schema version 3 and still restore version 2.
- Plugin APIs mount at /v1/plugins/{name}/api with a configurable body
  ceiling, and plugin pages run in a sandboxed Dashboard frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.6.0 v1.6.0 release tracking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants