Service & Consumer 双层
6.1 Admin 层
- 通过 Web UI 登录,拥有完整权限
- 管理文件系统(
docs/scripts/generated/soul) - 配置 System Prompt + 用户画像
- 管理 Subagent + 能力提示词
- 发布 Service + 管理 API Key
- 配置定时任务 + 微信接入
6.2 Consumer 层
- 通过
sk-svc-...API Key 认证(或/s/{sid}?key=...自助链接) - 权限受限:仅访问 Service 配置的能力 +
allowed_docs/scripts - 文件系统隔离:
users/{admin}/services/{svc}/conversations/{conv}/ - 生成文件隔离:每个对话独立的
generated/ - 不能访问 Admin 的文件系统
6.3 Service 配置
每个 Service 是一个 published 配置:
users/{admin_id}/services/{service_id}/
├── config.json # 模型 + system_prompt + capabilities + allowed_docs/scripts + welcome_message + quick_questions + wechat_channel
├── keys.json # API Key(hashed)
├── wechat_sessions.json # WeChat 会话状态
├── conversations/ # Consumer 对话目录
└── tasks/ # Service 定时任务详细 schema 见 docs/filesystem-architecture.md §4。
6.4 Service 自助化(v2.x)
6.4.1 专属链接附 Key
- URL 格式:
/s/{service_id}?key=sk-svc-xxx - 后端:
consumer_ui.py注入模板变量,前端启动时URLSearchParams读key→ 写localStorage→history.replaceState立即清掉 query - 前端 admin:Key Modal 生成成功后额外展示带 key 的完整链接 + 警告(等同分享 Key)
6.4.2 欢迎语 + 快速问题
- 字段:
welcome_message: str+quick_questions: List[str] - 后端模板注入:
_safe_json_for_inline_script防 script breakout - 前端 chat 页:ChatGPT 风格首屏(大欢迎语 + 渐变 chips),发送第一条消息后自动隐藏
6.4.3 文件/脚本图形选择器
FileTreePicker.tsx:antdTreecheckable +loadData懒加载 + 「全部 (*)」 Switch- 文件夹勾选 = 整个目录递归(key 以
/结尾) - 根目录限定:
allowed_docs只展示/docs,allowed_scripts只展示/scripts - 空
allowed_docs自动回落["*"],空allowed_scripts保持空数组(语义=禁止脚本)
6.5 Consumer Agent channel-aware
create_consumer_agent(..., channel: str = "web")channel="web":不注入send_message,即便 humanchat capability 启用。原因:web 上 agent 输出已直接流给浏览器,再调 send_message 既无投递目标又会让消费者看到不该看的工具事件channel="wechat":注入send_message,工具结果由 delivery 层反向投递channel="scheduler":同 wechatcache_key中加入::ch={channel}(仅当非默认 web 时)
6.6 Codex / Cursor 套餐 Service(v1.3.1)
在「设置 → Service 管理」选择已授权连接和模型即可沿用网页、Consumer API 与 Service 微信入口。默认 DeepAgents Service 不变。管理员个人微信不是 Service 微信,其引擎路径未改变。
配置与资源
创建 / 更新 Service 的 runtime_choice 描述选择;runtime_binding 由服务端校验并生成,不接受调用方自行构造。创建请求仍需要顶层 model。以下为最小配置示意,替换连接、模型以及存在的文档目录后使用:
{
"name": "Team handbook",
"model": "<authorized-model-id>",
"runtime_choice": {
"runtime": "codex",
"profile_id": "<authorized-connection-id>",
"model": "<authorized-model-id>"
},
"allowed_docs": ["handbook"],
"allowed_scripts": [],
"capabilities": [],
"published": true
}runtime 也可为 cursor。allowed_docs / allowed_scripts 中 "*" 表示开放全部,空数组表示不开放;不要依赖默认值来限制资源。System Prompt 与 User Profile 使用 Service 选择的版本,发布前确认内容适合分享。访客不会自动获得 admin 的私有长期记忆。
创建 Key 使用 {"name":"team","billing":"hosted"},界面对应「使用已授权套餐」。套餐 Service 拒绝 BYOK;从 DeepAgents 改成套餐引擎后,旧 BYOK Key 也不能调用。
请求如何执行
Service 网页 / Consumer API / Service 微信
→ 校验 Service Key 或微信绑定、发布状态与 admin 模型授权
→ 固定连接与模型 → Runtime 队列(同连接串行)
→ jellyfish_service_* 工具 → 开放文档 / 脚本 / 当前对话产物
→ 流式事件、聊天记录、文件预览与下载app/runtime/consumer.py 处理会话与执行,consumer_tools.py 提供受限资源工具。原生命令与文件审批不对访客开放。客户端不能指定其他 admin、Service 或对话的资源路径。
Service 的连接、模型、资源或能力改变后,下轮新建原生会话;已有 Jellyfish 聊天记录保留。不同 Key / 渠道不复用原生会话。下线、删除 Key、撤权或权限变更会取消相应排队与运行任务。
API 与验收
GET /api/v1/models返回 Key 的billing、default_model、models与allowed_hosts;套餐 Key 为 hosted,模型固定。兼容 SDK 传入的model不会覆盖 Service 模型,provider/api_key/base_url/region被拒绝。- 原生搜索 / 生图需 Service 显式开放,且取决于客户端、模型和账号支持。套餐 Service 不支持定时任务、语音或视频;这些场景使用 DeepAgents。
- Service Key 是服务级共享访问边界,不是每个成员的独立身份。持有有效 Key 的调用方可访问该 Service 开放的会话。当前适用可信内部成员。
- 发布前分别检查:开放文档成功、范围外路径被拒绝、续聊、停止、Key 撤销、配置变更、产物下载;微信另验收真实消息和媒体投递。单元测试、模拟 UI 和构建不能替代真实供应商与渠道验收。
详细实现与部署侧验收边界见 Service 分发说明。