Compare commits

..

10 Commits

3 changed files with 472 additions and 35 deletions

View File

@@ -1,6 +1,6 @@
apiVersion: v2
name: pieced-operator
description: PieCed IT tenant lifecycle operator
version: 0.1.40
appVersion: "0.1.40"
version: 0.1.50
appVersion: "0.1.50"
type: application

View File

@@ -1,5 +1,18 @@
# The package catalog is deployed as a ConfigMap in the operator namespace.
# To update packages, edit the catalog data below and upgrade the Helm release.
#
# Categories:
# - core — toggles platform-level OpenClaw behaviour (heartbeat, cron,
# active-memory, voice) via config_patch. No channel bindings,
# no skills.
# - channel — adds a messaging channel (Telegram, Discord, …).
# - skill — adds a ClawHub or pack: skill ref to the OpenClawInstance.
#
# Quiet hours are not exposed as a separate package — in OpenClaw they live
# under the heartbeat config (via the active-window setting and via
# HEARTBEAT.md content rules). When we expose a tenant-tunable time range
# in the portal, it will become additional fields on core-heartbeat rather
# than its own package.
apiVersion: v1
kind: ConfigMap
metadata:
@@ -10,6 +23,185 @@ metadata:
data:
catalog.yaml: |
packages:
# =====================================================================
# CORE — platform behaviour toggles. Patched into OCI config.raw via
# config_patch (deep-merged on top of the operator's safe defaults).
# =====================================================================
core-heartbeat:
name: Heartbeat (Proactive Checks)
category: core
description: >
Periodic agent run (default every 30 min) that lets the assistant
check inbox, calendar, and other configured sources and message
you proactively when something needs attention. Without this, the
assistant only responds when you message it first.
# OpenClaw 2026.x ships heartbeat ON by default (30m, or 1h on
# Anthropic OAuth) when agents.defaults.heartbeat is absent —
# see issues openclaw/openclaw#64293, #19445, #8123. The builder
# accordingly writes `every: "0m"` (the known off-switch) into
# the baseline configRaw. core-heartbeat's config_patch below
# overlays the 30m cadence on top of that. The actual checklist
# the heartbeat reads lives in workspace HEARTBEAT.md (seeded
# separately via spec.workspaceFiles); without a HEARTBEAT.md
# the heartbeat fires harmlessly and replies HEARTBEAT_OK.
#
# Quiet hours: OpenClaw supports both a config-level activeHours
# window under agents.defaults.heartbeat (skipped outside the
# window) and in-content rules inside HEARTBEAT.md. Neither is
# exposed in the portal yet — when added, they become extra
# fields on this package, not a separate core-quiet-hours
# package.
config_patch:
agents:
defaults:
heartbeat:
every: "30m"
core-cron:
name: Scheduled Tasks (Cron)
category: core
description: >
Allow the assistant to run scheduled tasks (daily briefings,
recurring reminders, periodic reports). Off by default. When
off, the agent's cron tool stays available but no scheduled
job ever fires.
# Flips the cron scheduler on. Default base configRaw sets
# cron.enabled=false (see builder.go), so this overlay only
# writes true when the package is enabled. Job storage lives on
# the tenant PVC at ~/.openclaw/cron/jobs.json by default.
config_patch:
cron:
enabled: true
core-active-memory:
name: Active Memory
category: core
description: >
Lets the assistant recall stable preferences, recurring habits,
and long-term context from past conversations during a chat.
Uses an extra sub-agent turn per inbound message to query the
memory store. Direct-message sessions only — group and channel
sessions stay deterministic. Trades a small amount of token
cost for continuity and personalisation.
# OpenClaw 2026.5.x ships Active Memory as a plugin under
# plugins.entries.active-memory with a two-gate activation model:
# (1) the plugin must be enabled, (2) the request must be an
# eligible direct-chat session. Scoped to "main" agent and
# "direct" chat types for safe-default behaviour. The recall
# model inherits the session's chat model when available; the
# modelFallback is used only when nothing else resolves and
# should be present in LiteLLM. Adjust as needed for the
# platform's default cheap model.
config_patch:
plugins:
entries:
active-memory:
enabled: true
config:
enabled: true
agents: ["main"]
allowedChatTypes: ["direct"]
modelFallback: "pieced-mini"
queryMode: "recent"
promptStyle: "balanced"
timeoutMs: 15000
maxSummaryChars: 220
persistTranscripts: false
logging: false
core-voice:
name: Voice Interaction
category: core
description: >
Speech-to-text on incoming voice notes, automatic text-to-speech
on replies, and interactive Talk mode. Audio is routed through
PieCed's LiteLLM gateway so STT/TTS spend is tracked per-tenant
alongside chat usage. Inbound TTS uses kani-tts; Talk mode uses
kokoro-fastapi; STT uses self-hosted Whisper (faster-whisper-
large-v3). All three are private to the cluster.
# PHASE B — wired in. Toggling this package now installs the full
# voice surface into the tenant's OpenClawInstance config:
#
# - messages.tts: auto TTS on inbound replies, routed to
# `pieced-tts-inbound` (kani-tts behind LiteLLM).
# - talk: interactive Talk mode, routed to `pieced-tts-talk`
# (kokoro-fastapi behind LiteLLM). `interruptOnSpeech: true`
# so the agent stops talking when the user starts talking.
# - tools.media.audio: STT for inbound voice notes, capped at
# 20 MiB per message, routed to `pieced-stt` (whisper-openai
# behind LiteLLM).
#
# Provider config notes
# ---------------------
# `models.providers.openai` is declared here with no chat models
# (`models: []`) — its only role is to give the STT block under
# `tools.media.audio` a place to resolve its apiKey/baseUrl from.
# The agent's primary chat model still lives under
# `models.providers.litellm` (set in builder.go base) and is
# unaffected by this patch — deep-merge adds `openai` as a
# sibling provider, not a replacement.
#
# `allowPrivateNetwork: true` on the openai provider is required
# because the LiteLLM endpoint is a `http://*.svc` private-
# network address. Without it OpenClaw refuses the outbound
# call as a private-network destination.
#
# `${LITELLM_API_KEY}` is supplied via the tenant's envFrom
# secretRef (see builder.go), populated by ESO from
# secret/data/tenants/<ns>/litellm.
#
# Network policy
# --------------
# Audio traffic shares the existing LiteLLM egress hole in the
# per-tenant CiliumNetworkPolicy (toEndpoints inference ns,
# port 4000). No additional CNP rule needed — voice routes
# through the same gateway as chat completions.
config_patch:
models:
providers:
openai:
apiKey: "${LITELLM_API_KEY}"
baseUrl: "http://litellm.inference.svc:4000/v1"
models: []
request:
allowPrivateNetwork: true
messages:
tts:
auto: "inbound"
provider: "openai"
providers:
openai:
apiKey: "${LITELLM_API_KEY}"
baseUrl: "http://litellm.inference.svc:4000/v1"
model: "pieced-tts-inbound"
voice: "alloy"
talk:
provider: "openai"
providers:
openai:
apiKey: "${LITELLM_API_KEY}"
baseUrl: "http://litellm.inference.svc:4000/v1"
model: "pieced-tts-talk"
voice: "af_bella"
interruptOnSpeech: true
tools:
media:
audio:
enabled: true
maxBytes: 20971520
models:
- provider: "openai"
model: "pieced-stt"
baseUrl: "http://litellm.inference.svc:4000/v1"
# =====================================================================
# CHANNELS — messaging integrations. Each ships a Channels map that
# the builder copies into config.channels, env_vars for credentials,
# and bindings so messages route to the default agent.
# =====================================================================
telegram:
name: Telegram
category: channel
@@ -62,51 +254,296 @@ data:
2. Create app, add bot, copy token and app ID
3. Invite bot to server with messages scope
email:
name: Email (Gmail)
# Threema via the central PieCed gateway (pieced-threema-gateway in
# `threema-gateway` namespace). Differs from a typical channel
# package in two important ways:
#
# 1. No customer-supplied secret. The token + HMAC secret used
# by the openclaw-channel-threema-relay plugin are minted by
# the relay's /admin/tokens endpoint when the portal enables
# the package, then written to the same vault path suffix
# below. So `secret_key` here lists the keys the plugin reads;
# the WRITER is the portal (POST /api/tenants/:name/threema),
# not a customer wizard step.
#
# 2. Cross-namespace egress to `threema-gateway:8080`. The new
# `namespace` field on egress_rules emits a Cilium toEndpoints
# rule scoped to that namespace; in-cluster traffic to a
# sibling namespace would otherwise be blocked by the
# cluster-wide tenant isolation policy.
#
# The matching cross-namespace INGRESS rule (relay → OpenClaw 18789)
# is added by the builder when it sees `channels: { threema: ... }`
# in any enabled package.
threema:
name: Threema
category: channel
description: Email integration via Gmail IMAP/SMTP
description: Threema messaging via the PieCed central gateway
channels:
email:
threema:
enabled: true
settings:
provider: gmail
env_vars:
- name: EMAIL_ADDRESS
secret_key: address
vault_path_suffix: email
- name: EMAIL_APP_PASSWORD
secret_key: app-password
vault_path_suffix: email
- name: THREEMA_RELAY_URL
default: "http://pieced-threema-gateway.threema-gateway.svc:8080"
- name: THREEMA_RELAY_TOKEN
secret_key: token
vault_path_suffix: threema-relay
- name: THREEMA_RELAY_HMAC_SECRET
secret_key: hmac-secret
vault_path_suffix: threema-relay
bindings:
- match:
channel: email
channel: threema
egress_rules:
- host: imap.gmail.com
port: 993
- host: smtp.gmail.com
port: 465
- namespace: threema-gateway
port: 8080
# OpenClaw 2026.5.x loads external plugins from
# /data/extensions/<dir>/openclaw.plugin.json. Three gates must
# be open for the runtime to register an external plugin:
# 1. plugins.enabled: true — feature flag
# 2. plugins.allow contains the id — security allowlist
# 3. plugins.entries.<id>.enabled: true — per-plugin toggle
# Cedric's personal instance.yaml hand-codes the same three gates
# for his direct `openclaw-channel-threema` plugin; this patch
# generates them automatically for every tenant that enables
# threema. The init container that copies the plugin onto the
# PVC is emitted by the operator (plugin_image below).
config_patch:
plugins:
enabled: true
allow:
- "threema"
entries:
threema:
enabled: true
config: {}
plugin_image:
repository: registry.c5ai.ch/pieced/openclaw-channel-threema-relay
tag: "0.1.1"
target_dir: openclaw-channel-threema-relay
customer_instructions: |
1. Once enabled, register the Threema IDs you want to receive
messages from under "Authorized Users → threema".
2. PieCed will route messages between those Threema IDs and
your assistant via the central gateway — no Gateway account
of your own required.
3. Each Threema ID can only belong to one PieCed tenant. If a
registration fails, that ID is already claimed elsewhere.
disclaimer: >
Messages are end-to-end encrypted at the Threema boundary by
the PieCed central gateway. Inbound and outbound message
counts are logged per tenant for billing.
web-search:
name: Web Search
# =====================================================================
# SKILLS — ClawHub skill installs. Operator passes each entry through
# to spec.skills on the OpenClawInstance.
# =====================================================================
git-cli:
name: Git CLI
category: skill
description: Web search via internal SearXNG
description: >
Use git from the assistant's shell (clone, commit, push, pull,
diff, log, status). For private repositories, configure
credentials in your workspace.
skills:
- "pack:openclaw/skills/web-search@latest"
- "openlang-cn/git-cli"
egress_rules:
- host: github.com
port: 443
- host: gitlab.com
port: 443
github:
name: GitHub (gh CLI)
category: skill
description: >
Interact with GitHub repositories via the gh CLI — issues, PRs,
CI runs, releases, gists. Requires a personal access token.
skills:
- "steipete/github"
env_vars:
- name: GH_TOKEN
secret_key: token
vault_path_suffix: github
required: true
egress_rules:
- host: api.github.com
port: 443
- host: github.com
port: 443
- host: codeload.github.com
port: 443
customer_instructions: |
1. Open https://github.com/settings/tokens
2. Generate a fine-grained personal access token with the
repo scopes you want the assistant to use.
3. Copy the token (it is shown only once).
gitea:
name: Gitea
category: skill
description: >
Interact with a Gitea instance — repositories, issues, PRs,
releases. Defaults to the PieCed-platform Gitea at
git.c5ai.ch; supply your own GITEA_URL if you host elsewhere.
skills:
- "ericxliu1990/gitea"
env_vars:
- name: GITEA_URL
default: "https://git.c5ai.ch"
- name: GITEA_TOKEN
secret_key: token
vault_path_suffix: gitea
required: true
egress_rules:
- host: git.c5ai.ch
port: 443
customer_instructions: |
1. Log in to your Gitea instance (default https://git.c5ai.ch).
2. Go to Settings → Applications → Generate New Token.
3. Grant the scopes you want the assistant to use (repo, issue,
user — minimum needed for most workflows).
4. Copy the token.
whisper-self-hosted:
name: Whisper (Self-Hosted Transcription)
category: skill
description: >
Transcribe audio files via the platform's self-hosted Whisper
ASR instance. Useful for ad-hoc transcription tasks initiated
from chat; channel-level voice intake is handled separately by
the Voice CORE feature.
skills:
- "xavjer/openclaw-self-hosted-whisper"
env_vars:
- name: WHISPER_URL
default: "http://whisper-asr.whisper-asr.svc.cluster.local:9000"
searxng-local-search:
name: Web Search (SearXNG)
category: skill
description: >
Privacy-respecting web search via the platform's internal
SearXNG instance. Search the web, images, news, and more
without external API calls or trackers.
skills:
- "noblepayne/searxng-local-search"
env_vars:
- name: SEARXNG_URL
default: "http://searxng.searxng.svc.cluster.local:8080"
egress_rules: []
document-processing:
name: Document Processing
gog:
name: Google Workspace (Gog)
category: skill
description: PDF, DOCX, spreadsheet processing
description: >
Bundled access to Gmail, Calendar, Drive, Docs, Sheets, and
Contacts via Google OAuth. Setup requires a Google Cloud
project and an OAuth client. NOTE: OAuth flow is not yet
self-service in the portal — contact PieCed support for
credentials onboarding.
skills:
- "pack:openclaw/skills/document-processing@latest"
init_deps:
apt:
- pandoc
- libreoffice-writer-nogui
- ffmpeg
egress_rules: []
- "steipete/gog"
env_vars:
- name: GOG_CLIENT_ID
secret_key: client-id
vault_path_suffix: gog
required: true
- name: GOG_CLIENT_SECRET
secret_key: client-secret
vault_path_suffix: gog
required: true
- name: GOG_REFRESH_TOKEN
secret_key: refresh-token
vault_path_suffix: gog
required: true
egress_rules:
- host: oauth2.googleapis.com
port: 443
- host: www.googleapis.com
port: 443
- host: gmail.googleapis.com
port: 443
- host: calendar.googleapis.com
port: 443
- host: drive.googleapis.com
port: 443
- host: docs.googleapis.com
port: 443
- host: sheets.googleapis.com
port: 443
- host: people.googleapis.com
port: 443
customer_instructions: |
Google Workspace integration uses OAuth and requires manual
onboarding for now. Please open a support ticket to start
the setup process — we will exchange the client credentials
and a refresh token offline, then enable this package on
your tenant.
disclaimer: >
By enabling Google Workspace integration you authorize PieCed
to access Gmail, Calendar, Drive, Docs, Sheets, and Contacts
on your behalf. Data flows through Google's APIs subject to
Google's terms.
mail:
name: Email (IMAP / SMTP)
category: skill
description: >
Read, search, and manage email via IMAP; send via SMTP. Works
with Gmail (with an app password), Outlook, Fastmail, and any
standard IMAP/SMTP host. Replaces the previous Gmail-only
channel.
skills:
- "ivangdavila/mail"
env_vars:
- name: IMAP_HOST
secret_key: imap-host
vault_path_suffix: mail
required: true
- name: IMAP_USER
secret_key: imap-user
vault_path_suffix: mail
required: true
- name: IMAP_PASS
secret_key: imap-pass
vault_path_suffix: mail
required: true
- name: SMTP_HOST
secret_key: smtp-host
vault_path_suffix: mail
required: true
- name: SMTP_USER
secret_key: smtp-user
vault_path_suffix: mail
required: true
- name: SMTP_PASS
secret_key: smtp-pass
vault_path_suffix: mail
required: true
# The mail skill connects to tenant-supplied IMAP/SMTP servers on
# ports 993 / 465 / 587. The hostnames are not known at catalog
# time, so we open these ports to "world" rather than declaring
# FQDNs. Trade-off accepted for pilot — see catalog.EgressRule
# for the rule shape and rationale.
egress_rules:
- port: 993
world: true
- port: 465
world: true
- port: 587
world: true
customer_instructions: |
1. For Gmail: enable 2-Step Verification, then create an App
Password at https://myaccount.google.com/apppasswords and
use it as both IMAP and SMTP password.
2. For Outlook/Microsoft 365 with MFA: generate an app
password under your account's security settings.
3. For other providers: refer to their IMAP/SMTP documentation
for host names and ports.
4. Typical IMAP_HOST values: imap.gmail.com, outlook.office365.com.
5. Typical SMTP_HOST values: smtp.gmail.com, smtp.office365.com.
disclaimer: >
The assistant gains read/write access to the mailbox you
configure. Use a dedicated address rather than a personal
inbox if you want to limit scope.

View File

@@ -1,6 +1,6 @@
image:
repository: registry.c5ai.ch/pieced/pieced-operator
tag: "0.1.40"
tag: "0.1.50"
pullPolicy: IfNotPresent
imagePullSecrets: