Developer Guide · 06
Service & Consumer Two-Tier Layer
6.1 Admin Layer
- Login via Web UI with full permissions
- Manage filesystem (
docs/scripts/generated/soul) - Configure System Prompt + user profile
- Manage Subagents + capability prompts
- Publish Services + manage API Keys
- Configure scheduled tasks + WeChat integration
6.2 Consumer Layer
- Authenticate via
sk-svc-...API Key (or/s/{sid}?key=...self-service link) - Restricted permissions: only access capabilities +
allowed_docs/scriptsconfigured in Service - Filesystem isolation:
users/{admin}/services/{svc}/conversations/{conv}/ - Generated file isolation: each conversation has its own
generated/ - Cannot access Admin's filesystem
6.3 Service Configuration
Each Service is a published config:
text
users/{admin_id}/services/{service_id}/
├── config.json # Model + system_prompt + capabilities + allowed_docs/scripts + welcome_message + quick_questions + wechat_channel
├── keys.json # API Keys (hashed)
├── wechat_sessions.json # WeChat session state
├── conversations/ # Consumer conversation directory
└── tasks/ # Service scheduled tasksFull schema in docs/filesystem-architecture.md §4.
6.4 Service Self-Service (v2.x)
6.4.1 Key-Attached Links
- URL format:
/s/{service_id}?key=sk-svc-xxx - Backend:
consumer_ui.pyinjects template variables; frontend readskeyfromURLSearchParams→ writes tolocalStorage→history.replaceStateimmediately clears query - Frontend admin: Key Modal on success additionally shows full link with key + warning (equivalent to sharing the key)
6.4.2 Welcome Message + Quick Questions
- Fields:
welcome_message: str+quick_questions: List[str] - Backend template injection:
_safe_json_for_inline_scriptprevents script breakout - Frontend chat: ChatGPT-style first screen (large welcome text + gradient chips), auto-hides after first message
6.4.3 Visual File/Script Selector
FileTreePicker.tsx: antdTreecheckable +loadDatalazy loading + "All (*)" Switch- Folder selection = entire directory recursively (key ends with
/) - Root constraint:
allowed_docsonly shows/docs,allowed_scriptsonly shows/scripts - Empty
allowed_docsfalls back to["*"], emptyallowed_scriptskeeps empty (semantic = no scripts)
6.5 Consumer Agent Channel-Awareness
python
create_consumer_agent(..., channel: str = "web")channel="web": does not injectsend_messageeven if humanchat capability is enabled. Reason: agent output on web is already streamed to browser; calling send_message would have no delivery target and would expose tool events to consumerschannel="wechat": injectssend_message, tool results delivered by the delivery layerchannel="scheduler": same as wechatcache_keyincludes::ch={channel}(only when non-default web)