Compare commits

..

7 Commits

3 changed files with 178 additions and 41 deletions

View File

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

View File

@@ -37,18 +37,22 @@ data:
check inbox, calendar, and other configured sources and message check inbox, calendar, and other configured sources and message
you proactively when something needs attention. Without this, the you proactively when something needs attention. Without this, the
assistant only responds when you message it first. assistant only responds when you message it first.
# OpenClaw treats an absent agents.defaults.heartbeat block as # OpenClaw 2026.x ships heartbeat ON by default (30m, or 1h on
# "no heartbeat scheduler". When core-heartbeat is enabled, this # Anthropic OAuth) when agents.defaults.heartbeat is absent —
# patch installs the every-30-minute cadence. The actual checklist # 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 # the heartbeat reads lives in workspace HEARTBEAT.md (seeded
# separately via spec.workspaceFiles); without a HEARTBEAT.md the # separately via spec.workspaceFiles); without a HEARTBEAT.md
# heartbeat fires harmlessly and replies HEARTBEAT_OK. # the heartbeat fires harmlessly and replies HEARTBEAT_OK.
# #
# Quiet hours: OpenClaw supports both a config-level active window # Quiet hours: OpenClaw supports both a config-level activeHours
# under agents.defaults.heartbeat (skipped outside the window) and # window under agents.defaults.heartbeat (skipped outside the
# in-content rules inside HEARTBEAT.md. Neither is exposed in the # window) and in-content rules inside HEARTBEAT.md. Neither is
# portal yet — when added, they become extra fields on this # exposed in the portal yet — when added, they become extra
# package, not a separate core-quiet-hours package. # fields on this package, not a separate core-quiet-hours
# package.
config_patch: config_patch:
agents: agents:
defaults: defaults:
@@ -111,31 +115,86 @@ data:
name: Voice Interaction name: Voice Interaction
category: core category: core
description: > description: >
Speech-to-text on incoming voice notes and text-to-speech on Speech-to-text on incoming voice notes, automatic text-to-speech
replies. Routed through PieCed's LiteLLM gateway so audio cost on replies, and interactive Talk mode. Audio is routed through
is tracked per-tenant alongside chat. PieCed's LiteLLM gateway so STT/TTS spend is tracked per-tenant
# PHASE A: catalog entry only. No config_patch yet — toggling alongside chat usage. Inbound TTS uses kani-tts; Talk mode uses
# this package stores customer intent but does not change the kokoro-fastapi; STT uses self-hosted Whisper (faster-whisper-
# OCI config. PHASE B (next iteration) wires in chatterbox-tts large-v3). All three are private to the cluster.
# and a whisper adapter (or speaches-server) behind LiteLLM and # PHASE B — wired in. Toggling this package now installs the full
# adds the config_patch below, roughly: # voice surface into the tenant's OpenClawInstance config:
# #
# config_patch: # - messages.tts: auto TTS on inbound replies, routed to
# tools: # `pieced-tts-inbound` (kani-tts behind LiteLLM).
# media: # - talk: interactive Talk mode, routed to `pieced-tts-talk`
# audio: # (kokoro-fastapi behind LiteLLM). `interruptOnSpeech: true`
# enabled: true # so the agent stops talking when the user starts talking.
# models: # - tools.media.audio: STT for inbound voice notes, capped at
# - provider: openai # 20 MiB per message, routed to `pieced-stt` (whisper-openai
# model: pieced-whisper # behind LiteLLM).
# apiBase: http://litellm.inference.svc:4000/v1 #
# messages: # Provider config notes
# tts: # ---------------------
# auto: inbound # `models.providers.openai` is declared here with no chat models
# provider: openai # (`models: []`) — its only role is to give the STT block under
# openai: # `tools.media.audio` a place to resolve its apiKey/baseUrl from.
# model: pieced-tts # The agent's primary chat model still lives under
# voice: nova # `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 # CHANNELS — messaging integrations. Each ships a Channels map that
@@ -195,18 +254,96 @@ data:
2. Create app, add bot, copy token and app ID 2. Create app, add bot, copy token and app ID
3. Invite bot to server with messages scope 3. Invite bot to server with messages scope
# 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: Threema messaging via the PieCed central gateway
channels:
threema:
enabled: true
env_vars:
- 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: threema
egress_rules:
- 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.
# ===================================================================== # =====================================================================
# SKILLS — ClawHub skill installs. Operator passes each entry through # SKILLS — ClawHub skill installs. Operator passes each entry through
# to OpenClawInstance.spec.skills, where the OpenClaw operator's init # to spec.skills on the OpenClawInstance.
# container fetches it before the agent starts. Bare "<owner>/<slug>"
# resolves through ClawHub by default.
# ===================================================================== # =====================================================================
git-cli: git-cli:
name: Git CLI name: Git CLI
category: skill category: skill
description: > description: >
Standalone git command-line operations (clone, commit, branch, Use git from the assistant's shell (clone, commit, push, pull,
diff, log, status). For private repositories, configure diff, log, status). For private repositories, configure
credentials in your workspace. credentials in your workspace.
skills: skills:

View File

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