Plaita Console
Plaita 流程引擎可视化管理控制台
功能特性
- 服务拓扑视图 - 实时展示集群服务结构与关联关系
- 服务生命周期管理 - 启动/停止各类服务
- 执行实例管理 - 流程执行的查看、启动、停止
- 实时监控 - 执行状态、日志流、任务队列
- 可视化流程查看器 - 图形化展示流程执行进度
- 可视化 Flow 编排 - 浏览器内拖拽编排 Plaita 流程(节点面板 + 画布 + 配置抽屉 + 试跑),保存为带 semver 版本号的流程定义,支持草稿/发布版本管理
- 节点管理 - 查看内置节点 schema、注册/删除自定义节点描述
- 多租户 - 用户可属多个租户(成员制 + 会话内切换),流程/版本/执行/调度/凭据/自定义节点/审计按租户隔离;平台管理员跨租户管理与全量视角。本地单机档与集群档均支持(集群档经消息租户 + 键 namespace 隔离,见下方"多租户边界")
- 对外契约接口 - 暴露
/api/flowVersion/semver/detail(HMAC 鉴权),供plaita.PlaitaClient拉取已发布流程定义;支持按租户签发契约密钥(租户只能拉本租户流程),全局密钥仍兼容平台级拉取
多租户说明
- 模型:
tenants+tenant_members(用户↔租户多对多,租户内 admin/editor/viewer 角色);users.platform_admin为平台管理员(管理租户/成员,可带X-Tenant-ID头跨租户操作)。 - 会话:登录响应含
memberships与active_tenant;POST /api/auth/switch-tenant切换活跃租户,传{"tenant_id": null}(仅平台管理员)显式切到只读全量视角(清空会话活跃租户);前端侧边栏提供租户切换器。成员变更即吊销该用户全部会话。全量视角只读:租户作用域写操作返回 403「请先选择具体租户」,不再静默回退default。 - 无活跃租户 fail-closed(#254):普通用户会话若没有任何有效租户成员关系(典型:被移出租户后重新登录),管理 API 一律 403「当前会话无活跃租户」——不回退
users.role遗留全局角色,不把None当作平台全量视角,写路径也不回退default。平台管理员会话/API-Key/insecure 开发开关可读平台全量;其中会话型平台管理员的全量视角为只读,无状态 API-Key / insecure 凭证的写路径保留default回退(单租户时代集成兼容)。 - 租户角色 ≠ 平台身份(#260 / #261 / #263):
/api/users的全局账号变更(创建 / 改角色 / 改密 / 删除)要求users.platform_admin(或平台级 API-Key);租户 admin 只能经/api/tenants/{tid}/members/*管理本租户成员,不能操作platform_admin=True的账号,GET /api/users也只返回本租户成员。全局服务停止(POST /api/services/{id}/stop)同样只允许平台身份。/api/cluster/*与/api/clusters/*的全部端点(含 GET 读面)一律要求平台身份——基础设施连接串 / 完整集群配置没有租户内语义;响应再经序列化层脱敏(URL 口令段与PASSWORD/SECRET/TOKEN等 env 键值换***)作为纵深防御。/api/dispatch/ledger对非平台身份按本租户过滤(显式传他租户 403 + 审计),平台身份默认全量。任何已认证角色都可以修改自己的密码;被拒绝的尝试进审计(*.denied)。 - 隔离:流程/版本/执行/调度/凭据/自定义节点/属性类型/Copilot 会话/审计/部署记录全部携带
tenant_id,查询按会话租户过滤,跨租户访问即 not-found。存量库首次多租户启动时自动迁移:建default租户、回填数据、legacy admin 提升为平台管理员。 - 凭据明文归属(#254):
GET /api/credentials/{name}返回明文前校验租户归属——租户上下文必须命中本租户记录,跨租户同名凭据返回 404(不泄露存在性与明文)。 - 租户内唯一:
flow_id、凭据名、自定义节点 type、属性类型名的唯一性均为租户内唯一(同名流程可共存于不同租户)。 - 停用租户对运行面生效(#27):
POST /api/tenants/{id}/status置disabled后,该租户已签发会话的 API 调用按请求实时返回 403(无需等会话过期;平台管理员不受限,否则无法重新启用),其调度被置enabled=false、schedule_service不再入队。集群档还会把状态写入 Redisplaita:tenant_status,供 worker 丢弃该租户的 start/resume(含挂起执行的恢复)——跨 Redis 部署该闸门不生效(见docs-site/docs/distributed/ops-runbook.md)。 - 删除租户清理(#245/#255/#257/A54-01/03/04/05/06/09):
DELETE /api/tenants/{id}先校验租户内无流程(有 flow 拒绝,拒绝门先于一切清理)。随后同一事务删除credentials/成员/租户行、本地档四表(local_schedules/local_schedule_fires/local_executions/local_logs)与租户级 DB 资产(自定义节点描述/属性类型/Copilot 会话元数据/部署记录);凭据旁文件credentials_file(tenant_id)在 commit 之前删除(失败即回滚:租户行还在、可重试,绝不出现「租户已删、旧密钥仍可读」;旧版本留下的 404 残留由 404 路径补清扫)。集群档清理{ns}:*租户命名空间(执行状态/取消/fence/租约/重试计数/start-dedup、flow 发布定义)、平台键里归属该租户的调度/事件记录/事件订阅,并按条目tenant_id清理平台级日志 Streamplaita:logs:*;任务队列按键集合排空(console 队列 +PLAITA_QUEUE_NAME/QUEUE_NAME+PLAITA_CONSOLE_TENANT_PURGE_QUEUESallowlist + Redis 中已存在的同族版本队列,如plaita:flow:queue:v2),每条队列只删能明确归属的条目。删除后写 Redisplaita:tenant_status=disabled墓碑——在途 start/resume 与旧 enabled 调度不再执行;同名重建回填active。save_credential拒绝已删/不存在的租户(堵迟到写复活 store)。清理失败显式报错;重建同名租户读不到旧凭据/执行/日志/调度/节点/属性类型/Copilot/部署。审计audit_logs不物理删除(合规证据保留),但租户 admin 的/api/audit只返回当前世代(tenants.created_at之后)的记录,平台身份可全量审计。404 补清扫遇到残留 flow(租户行已不在)时返回 409 具名拒绝,要求显式归档/清除,绝不静默留给同名重建;create_tenant对任何前代遗留数据(flow/节点/属性类型/Copilot/部署)同样拒绝同名继承。 - 服务读面脱敏(#265):
GET /api/services的合成基础设施/组件条目在响应序列化层对连接串做脱敏(URL userinfo 口令、凭据键值换***,保留 scheme/host/port/path/db)——租户 viewer 仍可看实例状态与非敏感字段,但读不到口令;/api/services/{id}与/api/services/topology走同一脱敏层。 - 读面单请求上界(A2R20-02/03/04):
/api/services*全部改有界 SCAN(显式COUNT=1000,取值用分块MGET取代逐键 GET),/api/metrics每次抓取不再执行KEYS;/api/executions列表在{ns}:execution:index就绪时按start_timeZSET 真分页、只投影当页(size上限 200,超限 422),存量库首次访问用有界 SCAN 兜底并回填索引;/api/logs*的每键读取受全局条目预算(50k)与墙钟预算(0.3s)前置约束,/api/logs/stats的XRANGE必带count。任一预算/扫描触界时响应带truncated=true并记 WARNING,不静默返回部分结果。 - 投影一致性(A2R24-06/07):列表/详情同源投影——flow 详情补齐
tenant_id/created_at/updated_at(嵌套versions改为有类型摘要),credential 详情补齐updated_at,queue 详情补齐queue_type,tenant 详情补齐member_count,单版本详情补齐tenant_id;ExecutionInfo声明flow_name(集群档取自执行状态;本地档null= 该视图未提供)。晋升包tenant_id取实体租户(平台全量视角导出不再丢失源租户);平台全量视角下同名flow_id跨租户时详情/单版本/导出返回 409ambiguous_flow_id并列出available_tenants,要求带X-Tenant-ID指定,不再静默.first()。 - 列表/分页契约(A2R24-02/05):
/api/queues/{name}的start对 list 与 stream 都是索引(stream 不再被当作 Stream ID,翻页不会重复第一页),start上限 10000,count夹紧到 1..200;stream 另给排他游标next_start_id/start_id(深队列 O(log N)),响应带truncated。/api/logs、/api/logs/instance/{id}、/api/events的total是匹配总数(受全局扫描预算约束,truncated=true时为下界),新增returned与next_cursor(键集游标,回传cursor可翻完全部历史);limit有ge=1(0/负数 422),/logs/instance的order是Literal["asc","desc"](其他值 422,不再静默 asc)。 - 请求体未知字段严格拒绝(A2R24-10):请求体模型除
DispatchOneRequest(显式extra="ignore":shadow等服务端权威字段不接受请求体覆盖)外一律继承StrictRequestModel(extra="forbid")——拼错params/base_updated_at等未知字段返回 422,不再静默丢参或绕过乐观锁;响应模型不受影响(保持 ignore)。没有 body 参数的写端点(cancel/trigger/logout/rotate-secret/各 DELETE 等)挂EmptyRequestModel:空体、{}、null保持原行为,任何字段 422(此前请求体被 Starlette 读走后丢弃)。非模型的请求面不在本口径内:POST /api/copilot是 AG-UI 协议透传,POST /api/flowVersion/semver/detail是 form 契约面(缺字段按{code,message,data}业务码返回)。 - 调度立即触发(A2R24-08):
POST /api/schedules/{id}/trigger本地/集群两模式返回同一字段集{success, mode, execution_id, msg_id}(mode=local时msg_id=null,mode=cluster时execution_id=null),不再按模式字段互斥。 - SSE 契约(A2R24-09):
/api/logs/stream、/api/flows/ai-generate/stream的 OpenAPI 200 媒体类型声明为text/event-stream(不再同时标application/json);执行 SSE 本体仍刻意不进 schema,票据端点POST /api/executions/{id}/stream/ticket声明StreamTicketResponse({ticket, expires_in})。 - 启动/依赖预算(A2R20-05/06/07):Redis 客户端统一经
plaita.redis_client构造,connect/read 超时显式声明(console 交互面 2s/5s、worker/扩展服务/运维脚本 5s/30s,PLAITA_REDIS_CONNECT_TIMEOUT/PLAITA_REDIS_SOCKET_TIMEOUT可覆盖未显式传参的调用点),不再随 redis-py 5.x/8.x 在 ∞/5s 之间漂移。启动回填已发布流程改为每 200 版本一个 pipeline(SQL 侧按页读取),并受墙钟PLAITA_CONSOLE_ENGINE_SYNC_DEADLINE(默认 5s)与版本数..._MAX_VERSIONS(默认 5 万)约束;触界只降级不阻断启动,GET /health的engine_sync返回ready/degraded与计数。非 SQLite 库显式设置 connect/pool 超时(默认 5s)与 PGlock_timeout=5s,连接类失败 fail-fast 且启动日志中的目标 URL 已脱敏。 - 派发台账租户/世代隔离(A54-02):
GET /api/dispatch/ledger对平台身份返回全量台账与全局队列对账;租户身份只返回当前世代的本租户条目(条目含tenant_generation,缺失世代的旧行 fail-closed 不可见),不返回全局队列计数(queue_length=null、error说明对账仅平台身份可用)。 - 请求级租户世代(A51-02):会话解析用一条 JOIN 同时取成员资格/角色与
tenant.created_at + contract_secret_id(认证快照)。请求级依赖把该世代绑定到 ContextVar;save_credential/add_member的首次捕获与所有租户作用域写路径(成员角色/移除、flow/版本/节点描述/属性类型、本地执行/调度、凭据删除)在 flush 后同一事务内复核「请求世代 == 当前行世代」,delete+同名 create 跨 ABA 的旧请求写入重建租户会以TenantGenerationMismatch/UserError失败。平台身份带X-Tenant-ID时认证处读一次租户行(缺失 403);未挂依赖的 CLI/单测回退「首次读捕获」存量行为。 - 执行删除持久性(A43-01):
DELETE /api/executions/{id}只对终态开放;running/suspended 默认 409(指引先 cancel),显式force=true才「先取消再删」。集群档经delete_execution_state在同一次删除里清掉状态键、列表索引成员、取消标志、事件频道,并吊销{ns}:execution:fence:{id}与{ns}:execution:lease:{id}——在途 worker 的下一次 fenced 落盘因世代失配抛ExecutionLeaseError,不会把已删执行写回(删除后复活)。本地档force删除置位取消事件并有界等待执行线程收口;超时未退出时登记墓碑丢弃其后续日志写入,随后删除该执行的local_logs与local_executions行,删除后不可查。FencedExecutionStorage.delete_execution_state在持世代号时同样做 fence CAS,旧世代不能删除新世代的状态(A43-07)。A51-01/A52-01 起删除还会写平台根执行墓碑plaita:exec_tombstone:{id}(与四删同 pipeline/Lua),worker 在派发/直达启动/重投/死信守卫克隆前按同租户复核——删除后仍留在队列或 PEL 里的旧start载体不再重建执行;新execution_id正常放行,同 id 重放被丢弃。 - 契约密钥:每个租户一组
contract_secret_id/contract_secret_key(租户管理页创建/轮换,明文仅显示一次),只能拉取本租户已发布流程;全局PLAITA_CONSOLE_SECRET_ID/SECRET_KEY仍可用(平台上下文,可拉任意租户),存量集成不破坏。 - 多租户边界(如实说明):集群档的租户数据(流程定义、执行状态、resume 租约)按键 namespace 隔离(
plaita:{tenant}:*,default 租户保持历史前缀plaita:*以兼容存量数据),任务消息携带tenant_id(缺省视为 default),引擎日志/调度值/订阅内嵌租户字段供 console 过滤。仍保持平台级共享的:任务队列 Stream(机制通道,租户在消息内)、事件总线存储与 pubsub(跨租户事件总线,订阅按租户过滤;删除租户时按记录tenant_id清理该租户条目)、服务注册/控制通道。本地档凭据按租户导出到旁文件(.plaita-credentials.<tenant>.json),default 租户沿用历史文件路径。 - 滚动升级兼容:消息缺
tenant_id按 default 处理;default 租户流量走历史键前缀——旧 worker + 新 console(或反向)混跑时 default 租户不受影响,非 default 租户需双侧升级。
快速开始
使用 Docker Compose
# 推荐:从样例文件开始,填写三个必填项
cp .env.example plaita-console/docker/.env
# 编辑 plaita-console/docker/.env 后:
cd plaita-console/docker && docker compose up -d
也可以临时用内联环境变量(生产/共享环境必须覆盖三个默认值;空密钥时管理 API
fail-closed,change-me-* 只用于本地模板演示):
cd plaita-console/docker
PLAITA_CONSOLE_ADMIN_API_KEY=<strong-random> \
PLAITA_CONSOLE_SECRET_ID=<random-id> \
PLAITA_CONSOLE_SECRET_KEY=<random-secret> \
docker compose up -d
访问 http://localhost:5173 打开控制台。compose 的服务端口绑定宿主所有接口;
不要把它直接暴露到公网,生产请放在反向代理/内网之后(见
docs-site/docs/guide/deployment.md)。
本地单机档(无需 Redis)
不想装 Redis 时,后端可直接以本地单机模式跑起来(启动时 ping 不通 Redis 会自动降级,日志里会有明确提示):
cd plaita-console/backend
pip install -r requirements.txt
python run.py
流程定义、版本、执行历史、节点 trace 全部存 SQLite(默认 ./plaita_console.db,可用 PLAITA_CONSOLE_DB_URL 换库);流程在 console 进程内的后台线程执行。
DB 是敏感数据(A2R25-08/09):
local_executions.input_json/context_json(执行 params/$INPUT/checkpoint)与tenants.contract_secret_key(对外 HMAC 契约密钥)字段级加密落盘(enc:v1:密文,AES-GCM;主密钥与凭据加密同源、按用途 HKDF 派生)。ORM 读取透明解密;裸 SQL/备份只见密文;存量明文在init_engine回填 +VACUUM。SQLite 文件仍收紧为 0600(第二道闸),默认库名与.plaita-credentials*已进.gitignore。字段加密密钥与凭据密钥同文件、同解析规则:相对 SQLite URL 或相对显式PLAITA_CREDENTIALS_KEY_FILE按各进程 cwd 解析并打 WARNING(A67-04),首建/O_EXCL 落败复用均以 0600 收紧(A67-05)。备份 DB 必须同时保护.plaita-credentials.key,否则历史执行与租户契约密钥不可恢复;output_json/nodes_json仍是明文功能副本(读面脱敏),DB 备份/外发整体按凭据泄露处置。
想强制本地档(即使本机有 Redis 也不连),把 Redis URL 指向一个不可达地址即可:
PLAITA_CONSOLE_REDIS_URL=redis://127.0.0.1:1/0 python run.py
本地档能力边界(与集群档的差异,如实说明):
- 可用:流程编排/发布、本地执行与节点级 trace、挂起-恢复(审批/事件节点,checkpoint 存 SQLite)、日志/执行页、内置调度循环(替代集群档的 schedule_service 进程)、HMAC 契约接口
/api/flowVersion/semver/detail。 - UI 入口:本地档只起后端 API;干净 clone 下
backend/webDist/不存在(gitignore),访问/不会有前端页面。要看控制台界面,另起前端开发服务(cd frontend && pnpm install && pnpm dev,访问 http://localhost:5173),或运行scripts/build_package.sh生成 webDist(打包前会扫描产物,出现浏览器管理密钥通道即 fail-fast)。 - 用 PlaitaClient 拉流程:需要
requests(pip install "plaita[http]"或pip install requests),缺依赖时 plaita 会给出可操作的安装指引。 - 不可用:集群/服务拓扑/服务启停、事件总线、任务队列视图——对应管理 API 返回 503。
- 限制:执行与恢复必须在同一个 console 进程内;进程重启后进程内事件订阅丢失,挂起的执行需显式 resume 继续;cancel 为尽力而为(只标记状态,不中断正在运行的线程);HMAC 重放保护退化为进程内 nonce 判定,仅单进程部署有效。
启动第三方依赖服务
Plaita Console 依赖 Redis 来存储服务注册信息。可以使用以下方式启动:
# 方式 1: 使用本地 Redis
redis-server
# 方式 2: 使用 Docker 仅启动依赖服务(Redis 只绑 127.0.0.1)
cd plaita-console/docker
docker compose -f docker-compose.deps.yml up -d
# 可选:Redis Commander 调试 UI(默认不启动;必须提供 HTTP 基本认证)
REDIS_COMMANDER_USER=admin REDIS_COMMANDER_PASSWORD='<strong-random>' \
docker compose -f docker-compose.deps.yml \
-f docker-compose.redis-commander.yml up -d redis-commander
演示模式
如果你只是想测试 Plaita Console 的功能,可以运行演示脚本注册模拟服务:
# 确保 Redis 已启动,然后运行演示脚本
cd plaita-console
python scripts/demo_services.py
这会注册几个模拟服务(FlowWorker、DelayService 等),让你可以在控制台中看到服务拓扑和状态。
本地开发
后端
cd plaita-console/backend
# 安装依赖
pip install -r requirements.txt
# 方式 1: 使用启动脚本(推荐)
python run.py
# 方式 2: 使用 uvicorn
python -m uvicorn main:app --reload --port 8080
# 方式 3: 直接运行
python main.py
前端
cd plaita-console/frontend
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev
访问 http://localhost:5173 打开控制台。
项目结构
plaita-console/
├── frontend/ # 前端项目 (React + TypeScript + Vite)
│ ├── src/
│ │ ├── components/ # 可复用组件
│ │ ├── pages/ # 页面组件
│ │ ├── hooks/ # 自定义 Hooks
│ │ ├── services/ # API 调用
│ │ └── stores/ # 状态管理
│ ├── package.json
│ └── vite.config.ts
├── backend/ # 后端项目 (FastAPI)
│ ├── api/ # API 路由
│ ├── models/ # 数据模型
│ ├── services/ # 业务逻辑
│ └── main.py
├── docker/ # Docker 配置
│ ├── docker-compose.yml
│ ├── docker-compose.deps.yml
│ ├── docker-compose.redis-commander.yml
│ ├── Dockerfile.frontend
│ └── Dockerfile.backend
└── README.md
API 文档
启动后端后,访问 http://localhost:8080/docs 查看 Swagger API 文档。
Swagger 按 tag 分面:admin(管理面)/ contract(契约面)/ health。
API 分面
Console 对外暴露两套鉴权面,路径前缀同为 /api,鉴权方式不同:
| 分面 | 调用方 | 鉴权 | 未配置密钥 |
|---|---|---|---|
| 管理面 (admin) | Console 前端 / 运维 | X-Admin-API-Key 或 Authorization: Bearer |
503(除非 ALLOW_INSECURE_ADMIN=true) |
| 契约面 (contract) | 外部 PlaitaClient |
HMAC(Authorization 头,与 plaita/client.py 对称) |
503 |
| 健康检查 | 探针 | 无 | — |
路由挂载见 backend/main.py:_mount_admin / _mount_contract。契约面不加 require_admin_auth。
管理面 API
| 端点 | 方法 | 描述 |
|---|---|---|
/api/services |
GET | 获取所有服务列表 |
/api/services/topology |
GET | 获取服务拓扑 |
/api/services/{id}/stop |
POST | 停止服务 |
/api/executions |
GET | 获取执行列表 |
/api/executions |
POST | 启动新执行 |
/api/executions/{id} |
DELETE | 删除执行(仅终态;running/suspended 返回 409,需先取消或显式 force=true)。集群档同时删除状态/索引/取消标志/事件频道并吊销 fence/lease;本地档先取消并等待线程收口,再删除执行行与日志 |
/api/executions/{id}/resume |
POST | 恢复执行(resume_type=continue/retry/cancel/timeout/event,可选 data);可选 params(#157)只在 resume_type=continue 且盘上 checkpoint 为空时被引擎绑定为 $INPUT(手动 continue 抢在 pending start 被 reclaim 之前的窗口);不传/空/null 不落 params 键(与 #122 载体形状一致)。空 checkpoint 下的 retry/cancel/timeout/event 与本字段无关:它们被策略层守卫以 ResumeGuardError 拒绝——执行保持 running、消息被 ack 吞掉、$INPUT 永不绑定(预存语义,非本单引入);checkpoint 非空时 params 惰性,绑定值一律以盘上 checkpoint 为准 |
/api/queues |
GET | 获取队列状态(含死信 DLQ 键) |
/api/queues/dlq |
GET | 死信总览:各 DLQ Stream 堆积量与最近条目(?count=) |
/api/metrics |
GET | 集群 Prometheus 文本:队列积压 / DLQ 堆积 / 存活 worker 数 |
/api/logs |
GET | 获取日志 |
/api/logs/stream |
GET (SSE) | 实时日志流 |
/api/flows |
GET / POST | 流程列表 / 新建流程 |
/api/flows/{id} |
GET / DELETE | 流程详情(含版本列表)/ 删除流程 |
/api/flows/{id}/versions/{ver} |
GET / PUT / DELETE | 取版本 / 保存草稿(Flow 强校验)/ 删除版本 |
/api/flows/{id}/versions/{ver}/source |
GET | codeflow 源码视图:metadata.source(权威)优先,缺失时 emit_source 反编译兜底(source_kind 标注 authoritative/decompiled/unavailable) |
/api/flows/{id}/publish |
POST | 发布指定版本(draft → published) |
/api/flows/dry-run |
POST | 同步试跑 Flow JSON,返回节点级结果 |
/api/nodes |
GET / POST | 节点描述列表 / 注册自定义节点 |
/api/nodes/{type} |
DELETE | 删除自定义节点(内置不可删) |
/api/cluster/* · /api/clusters/* |
— | 集群配置 / 启停 / 基础设施(command 白名单)。全部端点(含读面)要求平台身份;响应脱敏 URL 口令与 env 密钥(#263) |
/api/dispatch/ledger |
GET | 派发台账 + 队列对账;非平台身份只看本租户(#263) |
/api/events/* |
— | 事件订阅与查询 |
契约面 API
| 端点 | 方法 | 描述 |
|---|---|---|
/api/flowVersion/semver/detail |
POST | HMAC 鉴权;application/x-www-form-urlencoded(flowId/version);返回已发布流程定义供 PlaitaClient 拉取 |
技术栈
前端
- React 18
- TypeScript
- Vite
- TailwindCSS
- @xyflow/react 12 (流程编排画布与拓扑图)
- TanStack Query (数据获取)
- Zustand (状态管理)
后端
- FastAPI
- Pydantic
- Redis
- SQLAlchemy (流程定义/版本/节点描述持久化)
- SSE (Server-Sent Events)
环境变量
后端
| 变量名 | 默认值 | 描述 |
|---|---|---|
PLAITA_CONSOLE_REDIS_URL |
redis://localhost:6379/0 |
Redis 连接 URL |
PLAITA_CONSOLE_HOST |
127.0.0.1 |
监听地址(默认仅本机;对外部署显式设 0.0.0.0,启动日志会打 warning,见 #208) |
PLAITA_CONSOLE_PORT |
8080 |
监听端口 |
PLAITA_CONSOLE_DEBUG |
false |
调试模式 |
PLAITA_CONSOLE_DB_URL |
sqlite:///./plaita_console.db |
流程定义/版本/节点描述持久化(SQLAlchemy) |
PLAITA_CONSOLE_DB_CONNECT_TIMEOUT |
5 |
非 SQLite 后端的连接超时(秒;PG/MySQL connect_timeout;黑洞/半开 DB fail-fast) |
PLAITA_CONSOLE_DB_POOL_TIMEOUT |
5 |
SQLAlchemy 连接池等待超时(秒;非 SQLite) |
PLAITA_CONSOLE_ENGINE_SYNC_BATCH |
200 |
启动回填每批版本数(一个 Redis pipeline) |
PLAITA_CONSOLE_ENGINE_SYNC_DEADLINE |
5 |
启动回填墙钟预算(秒;触界不阻断启动,/health.engine_sync=degraded) |
PLAITA_CONSOLE_ENGINE_SYNC_MAX_VERSIONS |
50000 |
单次回填版本数上限(与 deadline 双保险) |
PLAITA_REDIS_CONNECT_TIMEOUT / PLAITA_REDIS_SOCKET_TIMEOUT |
5 / 30 |
worker/扩展服务/运维脚本的 Redis 连接/读超时(秒);console 交互面固定 2s/5s。URL query 的 socket_timeout 优先 |
PLAITA_CONSOLE_ADMIN_API_KEY |
空 | 管理面 API Key(X-Admin-API-Key / Bearer)。空且未放开 insecure 时管理 API 返回 503 |
PLAITA_CONSOLE_ALLOW_INSECURE_ADMIN |
false |
显式允许无管理密钥启动(仅本地开发) |
PLAITA_CONSOLE_SECRET_ID |
空 | 对外契约 HMAC secret-id(空则 /api/flowVersion 返回 503,不再接受空串签名) |
PLAITA_CONSOLE_SECRET_KEY |
空 | 对外契约 HMAC secret-key |
PLAITA_CONSOLE_LANGFUSE |
auto |
Langfuse 观测(plaita.obs):auto=配了 LANGFUSE_PUBLIC_KEY 即开;true 强制开;false 强制关。trace id = 执行实例 ID;缺 plaita[langfuse] 依赖自动降级为不观测(集群档对应 worker 的 --langfuse / PLAITA_WORKER_LANGFUSE=1)。另需 LANGFUSE_PROJECT_ID(如 proj-plaita-local)——执行详情页的「Langfuse」深链依赖它计算 trace URL |
PLAITA_CONSOLE_ADMIN_API_KEY 只供服务端/CLI 等非浏览器调用方使用(X-Admin-API-Key 或 Bearer)。浏览器端一律使用会话登录后的 Bearer token——不要通过 VITE_* 把管理密钥注入前端 bundle(Vite 会在构建期内联,公开静态资源即可下载,见 #266)。
POST /api/flows/dry-run 有两层安全闸门:(1) 拒绝含 code / python / javascript 等危险节点的流程;(2) 试跑前统一注入 globalContext.dry_run=True,并在执行器读点 get_global_variable("dry_run") 上钉死(试跑专用 _DryRunExecution,随子执行下发——流程声明 dry_run=false 也改不回去)——经 PLAITA_CONSOLE_NODE_MODULES 注册的业务节点(gate / capture / agentrun / llm / email / webhooks / database / git_publish 等)据此跳过真实副作用(子进程 / 出网 / agent CLI),名黑名单枚举不到它们。二者共同防止 console 进程 RCE。
开发指南
UI 旅程 e2e(语义化节点 id 可读性)
两个层次,覆盖同一旅程(画布语义名/desc、抽屉源码跳转、拖拽 + 保存 round-trip):
- argusai browser suite(CI 主路径,随
scripts/e2e-run.sh全量跑):tests/e2e/ui-semantic-ids.yaml——声明式 browser 步骤,单跑:scripts/e2e-run.sh ui-semantic-ids。数据播种经浏览器 evaluate + fetch (Bearer 取自 localStorage;ui-backend 容器不设 ALLOW_INSECURE_ADMIN)。 - 本地等价执行器(无需 Docker/mcp2cli/argusai-mcp):
BASE_URL=... ADMIN_PASSWORD=... python scripts/e2e-ui-semantic-ids-local.py——按同一份 YAML 逐 case 执行与断言,用于本机快速回归。
注意:console 前端 vite base: './'(dsht 子路径部署取舍),双层深链直刷会
白屏(如 /flows/<id>/edit)——两个 e2e 全程走客户端路由导航,不使用深链接刷新。
许可证
MIT
租户上下文(plaita#239 phase 2)
console 进程启动时显式声明 default 租户
(set_current_tenant(DEFAULT_TENANT_ID, source="explicit"),已在
create_app() / lifespan 内置)。凭据/存储写路径对来源 default 已
fail-closed(TenantContextMissingError);自定义 WSGI/ASGI 启动器若绕过
create_app(),必须自行执行同一行声明,否则写操作会被拒绝。
Metadata
Release files for plaita-console 0.63
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| plaita_console-0.63-py3-none-any.whl | Python 3 | none | any | Details for plaita_console-0.63-py3-none-any.whl |
Release files / plaita_console-0.63-py3-none-any.whl
| Download URL | plaita_console-0.63-py3-none-any.whl |
|---|---|
| Size | 5.8 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0b35e0d1487bd6a6832761acf0e3bfeb616c6894dccad760218922f1d64ac99b
|
|
BLAKE2b-256 checksum How to use checksums |
6008f4e6f5eede9a84e8902f2cd490275522e8d25d903f37785870e287623371
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for plaita-console 0.63
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.