mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 16:06:08 +00:00
Introduce SDK 0.4, manifest v3, protocol v4, the isolated plugin runtime, and cpr-plugin packaging CLI for independently maintained plugins. Support installation, permissions, one active configuration per plugin, version-specific settings, rollback, management pages, and CLI extensions. Isolate plugin failures so native gateway startup and requests remain available. Keep provider registration and UI choices fixed to built-in OpenAI and xAI. Support nine extension capabilities with permission-scoped model and account callbacks to the host. Unify plugin settings and version management, support plugin icons, and improve narrow layouts. Use the fixed GitHub UI dependency and pnpm 12 for standalone frontend and container builds. Reduce runtime test packaging cost and align preparation modules with the repository layout. Co-authored-by: Codex <noreply@openai.com>
146 lines
7.2 KiB
SQL
146 lines
7.2 KiB
SQL
-- 更新规则可变;制品保存安装时的来源事实,包体随 PostgreSQL 备份恢复。
|
|
create table plugin_update_sources (
|
|
plugin_id text primary key check (
|
|
octet_length(plugin_id) <= 64
|
|
and plugin_id ~ '^[a-z0-9]([a-z0-9-]*[a-z0-9])?[.][a-z0-9]([a-z0-9-]*[a-z0-9])?$'
|
|
),
|
|
source_json jsonb not null check (jsonb_typeof(source_json) = 'object'),
|
|
policy_json jsonb not null default '{"kind":"manual"}'::jsonb
|
|
check (jsonb_typeof(policy_json) = 'object'),
|
|
outbound_proxy_id text references outbound_proxies(id) on delete restrict
|
|
);
|
|
|
|
create index plugin_update_sources_outbound_proxy_id_idx on plugin_update_sources(outbound_proxy_id);
|
|
|
|
create table plugin_artifacts (
|
|
sha256 text primary key check (sha256 ~ '^[0-9a-f]{64}$'),
|
|
plugin_id text not null references plugin_update_sources(plugin_id),
|
|
version text not null check (length(version) between 1 and 128),
|
|
metadata_json jsonb not null check (jsonb_typeof(metadata_json) = 'object'),
|
|
source_json jsonb not null check (jsonb_typeof(source_json) = 'object'),
|
|
-- 历史下载引用阻止代理被误删;地址与认证仍只存在受管代理记录中。
|
|
outbound_proxy_id text references outbound_proxies(id) on delete restrict,
|
|
archive bytea not null check (octet_length(archive) between 1 and 33554432),
|
|
installed_at timestamptz not null default now(),
|
|
-- 接受事实绑定不可变包;实例运行权限从包声明派生。
|
|
accepted_at timestamptz
|
|
);
|
|
|
|
create index plugin_artifacts_plugin_id_idx on plugin_artifacts(plugin_id);
|
|
create index plugin_artifacts_outbound_proxy_id_idx on plugin_artifacts(outbound_proxy_id);
|
|
|
|
-- 平台逐项约束,避免通过增加另一平台条目绕过同版本不可变规则。
|
|
create table plugin_artifact_platforms (
|
|
plugin_id text not null,
|
|
version text not null,
|
|
platform text not null,
|
|
artifact_sha256 text not null references plugin_artifacts(sha256) on delete cascade,
|
|
primary key (plugin_id, version, platform)
|
|
);
|
|
|
|
create index plugin_artifact_platforms_artifact_sha256_idx on plugin_artifact_platforms(artifact_sha256);
|
|
|
|
-- 下载鉴权单独持久化;普通列表和审计只返回 info_json,不读取 secret_json。
|
|
create table plugin_source_credentials (
|
|
id uuid primary key,
|
|
info_json jsonb not null check (jsonb_typeof(info_json) = 'object'),
|
|
secret_json jsonb not null check (jsonb_typeof(secret_json) = 'object')
|
|
);
|
|
|
|
create table plugin_artifact_credentials (
|
|
artifact_sha256 text not null references plugin_artifacts(sha256) on delete cascade,
|
|
credential_id uuid not null references plugin_source_credentials(id),
|
|
primary key (artifact_sha256, credential_id)
|
|
);
|
|
|
|
create index plugin_artifact_credentials_credential_id_idx on plugin_artifact_credentials(credential_id);
|
|
|
|
create table plugin_instances (
|
|
id uuid primary key,
|
|
artifact_sha256 text not null references plugin_artifacts(sha256),
|
|
name text not null check (length(name) between 1 and 128),
|
|
enabled boolean not null,
|
|
configuration_json jsonb not null check (jsonb_typeof(configuration_json) = 'object' and octet_length(configuration_json::text) <= 65536),
|
|
bindings_json jsonb not null check (jsonb_typeof(bindings_json) = 'array'),
|
|
revision bigint not null check (revision > 0)
|
|
);
|
|
|
|
create index plugin_instances_artifact_sha256_idx on plugin_instances(artifact_sha256);
|
|
|
|
create table plugin_instance_secrets (
|
|
instance_id uuid primary key references plugin_instances(id) on delete cascade,
|
|
secrets_json jsonb not null check (jsonb_typeof(secrets_json) = 'object' and octet_length(secrets_json::text) <= 65536)
|
|
);
|
|
|
|
-- 私有状态与配置 revision 分离;普通状态写入不得推进全局 revision。
|
|
create table plugin_state_generations (
|
|
id uuid primary key,
|
|
transition_id uuid,
|
|
instance_id uuid not null references plugin_instances(id) on delete cascade,
|
|
namespace text not null check (namespace ~ '^[a-z][a-z0-9_.-]{0,63}$'),
|
|
artifact_sha256 text not null references plugin_artifacts(sha256),
|
|
schema_version bigint not null check (schema_version between 1 and 4294967295),
|
|
schema_sha256 text not null check (schema_sha256 ~ '^[0-9a-f]{64}$'),
|
|
maximum_records bigint not null check (maximum_records between 1 and 10000),
|
|
maximum_bytes bigint not null check (maximum_bytes between 1 and 16777216),
|
|
maximum_value_bytes bigint not null check (
|
|
maximum_value_bytes between 1 and 262144
|
|
and maximum_value_bytes <= maximum_bytes
|
|
),
|
|
instance_revision bigint not null check (instance_revision > 0),
|
|
fence uuid not null,
|
|
status text not null check (status in ('staging', 'active')),
|
|
source_generation_id uuid references plugin_state_generations(id),
|
|
next_record_version bigint not null default 1 check (next_record_version > 0),
|
|
record_count bigint not null default 0 check (record_count between 0 and maximum_records),
|
|
total_bytes bigint not null default 0 check (total_bytes between 0 and maximum_bytes),
|
|
migration_cursor text,
|
|
migration_complete boolean not null default false,
|
|
created_at timestamptz not null default now(),
|
|
promoted_at timestamptz,
|
|
unique (instance_id, namespace, status),
|
|
unique (transition_id, namespace),
|
|
check (source_generation_id is null or source_generation_id <> id),
|
|
check (
|
|
(status = 'staging' and transition_id is not null)
|
|
or (status = 'active' and transition_id is null and source_generation_id is null
|
|
and migration_cursor is null and migration_complete and promoted_at is not null)
|
|
)
|
|
);
|
|
|
|
create index plugin_state_generations_artifact_sha256_idx on plugin_state_generations(artifact_sha256);
|
|
create index plugin_state_generations_source_generation_id_idx on plugin_state_generations(source_generation_id);
|
|
|
|
create table plugin_state_records (
|
|
generation_id uuid not null references plugin_state_generations(id) on delete cascade,
|
|
-- 游标分页与 Rust 字符串比较都按 UTF-8 字节序,不受数据库 locale 影响。
|
|
state_key text collate "C" not null check (
|
|
length(state_key) between 1 and 256
|
|
and octet_length(state_key) <= 512
|
|
and state_key !~ '[[:cntrl:]]'
|
|
),
|
|
value_json jsonb not null,
|
|
value_bytes bigint not null check (value_bytes between 1 and 262144),
|
|
record_version bigint not null check (record_version > 0),
|
|
primary key (generation_id, state_key)
|
|
);
|
|
|
|
-- 授权回执与账号写入同事务提交;不保存 flow、回调地址或凭据文档。
|
|
create table authorization_receipts (
|
|
provider_kind text not null,
|
|
flow_digest text not null check (flow_digest ~ '^[0-9a-f]{64}$'),
|
|
owner_digest text not null check (owner_digest ~ '^[0-9a-f]{64}$'),
|
|
config_revision bigint not null check (config_revision > 0),
|
|
accounts_json jsonb not null check (
|
|
jsonb_typeof(accounts_json) = 'array'
|
|
and jsonb_array_length(accounts_json) between 1 and 200
|
|
and octet_length(accounts_json::text) <= 65536
|
|
),
|
|
created_at timestamptz not null default now(),
|
|
expires_at timestamptz not null default (now() + interval '24 hours'),
|
|
primary key (provider_kind, flow_digest),
|
|
check (expires_at > created_at)
|
|
);
|
|
|
|
create index authorization_receipts_expiry_idx on authorization_receipts (expires_at);
|