This commit is contained in:
@@ -1,9 +1,32 @@
|
||||
/**
|
||||
* Portal-side package catalog. Hardcoded mirror of the operator-side
|
||||
* catalog ConfigMap (deploy/helm/pieced-operator/templates/catalog-cm.yaml).
|
||||
*
|
||||
* The two have to stay in sync:
|
||||
* - `id` here must match the catalog key in the ConfigMap.
|
||||
* - `secrets[].key` here must match the catalog's env_vars[].secret_key
|
||||
* so that POST /api/tenants/:name/secrets writes to the same OpenBao
|
||||
* path the operator's ExternalSecret reads from.
|
||||
* - `requiresSecrets` is true when the catalog declares any env_var
|
||||
* that is a secret (vault_path_suffix set, no default value).
|
||||
*
|
||||
* Category model (Phase A rework):
|
||||
* - core — platform-behaviour toggles (heartbeat, cron,
|
||||
* active-memory, voice). Mostly no secrets. core-voice is
|
||||
* a catalog stub in Phase A — toggling stores customer
|
||||
* intent only; the OCI config_patch lands in Phase B.
|
||||
* - channel — messaging integration.
|
||||
* - skill — ClawHub skill install.
|
||||
*/
|
||||
|
||||
export interface PackageSecretField {
|
||||
key: string;
|
||||
labelKey: string;
|
||||
placeholderKey: string;
|
||||
}
|
||||
|
||||
export type PackageCategory = "core" | "channel" | "skill";
|
||||
|
||||
export interface PackageDef {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -12,10 +35,45 @@ export interface PackageDef {
|
||||
secrets?: PackageSecretField[];
|
||||
instructionsKey?: string;
|
||||
disclaimerKey?: string;
|
||||
category: "channel" | "skill";
|
||||
category: PackageCategory;
|
||||
}
|
||||
|
||||
export const PACKAGE_CATALOG: PackageDef[] = [
|
||||
// -------------------------------------------------------------------------
|
||||
// CORE
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
id: "core-heartbeat",
|
||||
name: "Heartbeat (Proactive Checks)",
|
||||
descriptionKey: "packages.coreHeartbeat.description",
|
||||
requiresSecrets: false,
|
||||
category: "core",
|
||||
},
|
||||
{
|
||||
id: "core-cron",
|
||||
name: "Scheduled Tasks (Cron)",
|
||||
descriptionKey: "packages.coreCron.description",
|
||||
requiresSecrets: false,
|
||||
category: "core",
|
||||
},
|
||||
{
|
||||
id: "core-active-memory",
|
||||
name: "Active Memory",
|
||||
descriptionKey: "packages.coreActiveMemory.description",
|
||||
requiresSecrets: false,
|
||||
category: "core",
|
||||
},
|
||||
{
|
||||
id: "core-voice",
|
||||
name: "Voice Interaction",
|
||||
descriptionKey: "packages.coreVoice.description",
|
||||
requiresSecrets: false,
|
||||
category: "core",
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// CHANNELS
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
id: "telegram",
|
||||
name: "Telegram",
|
||||
@@ -43,42 +101,181 @@ export const PACKAGE_CATALOG: PackageDef[] = [
|
||||
labelKey: "packages.discord.botTokenLabel",
|
||||
placeholderKey: "packages.discord.botTokenPlaceholder",
|
||||
},
|
||||
// app-id was missing from the portal catalog historically while the
|
||||
// operator catalog declared DISCORD_APP_ID as a required env var.
|
||||
// Tenants who enabled Discord ended up with the env var blank
|
||||
// because the secrets POST never wrote an `app-id` key to OpenBao
|
||||
// and the operator's ExternalSecret couldn't populate it. Added
|
||||
// here as part of the Phase A rework to close the alignment gap;
|
||||
// not strictly secret (the application ID is visible in the bot's
|
||||
// profile URL) but stored alongside the bot token for convenience.
|
||||
{
|
||||
key: "app-id",
|
||||
labelKey: "packages.discord.appIdLabel",
|
||||
placeholderKey: "packages.discord.appIdPlaceholder",
|
||||
},
|
||||
],
|
||||
instructionsKey: "packages.discord.instructions",
|
||||
disclaimerKey: "packages.discord.disclaimer",
|
||||
category: "channel",
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// SKILLS
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
id: "email",
|
||||
name: "Email",
|
||||
descriptionKey: "packages.email.description",
|
||||
requiresSecrets: true,
|
||||
secrets: [
|
||||
{ key: "smtp-host", labelKey: "packages.email.smtpHostLabel", placeholderKey: "packages.email.smtpHostPlaceholder" },
|
||||
{ key: "smtp-user", labelKey: "packages.email.smtpUserLabel", placeholderKey: "packages.email.smtpUserPlaceholder" },
|
||||
{ key: "smtp-password", labelKey: "packages.email.smtpPasswordLabel", placeholderKey: "packages.email.smtpPasswordPlaceholder" },
|
||||
{ key: "imap-host", labelKey: "packages.email.imapHostLabel", placeholderKey: "packages.email.imapHostPlaceholder" },
|
||||
],
|
||||
instructionsKey: "packages.email.instructions",
|
||||
disclaimerKey: "packages.email.disclaimer",
|
||||
category: "channel",
|
||||
},
|
||||
{
|
||||
id: "web-search",
|
||||
name: "Web Search",
|
||||
descriptionKey: "packages.webSearch.description",
|
||||
id: "git-cli",
|
||||
name: "Git CLI",
|
||||
descriptionKey: "packages.gitCli.description",
|
||||
requiresSecrets: false,
|
||||
category: "skill",
|
||||
},
|
||||
{
|
||||
id: "document-processing",
|
||||
name: "Document Processing",
|
||||
descriptionKey: "packages.documentProcessing.description",
|
||||
id: "github",
|
||||
name: "GitHub (gh CLI)",
|
||||
descriptionKey: "packages.github.description",
|
||||
requiresSecrets: true,
|
||||
secrets: [
|
||||
{
|
||||
key: "token",
|
||||
labelKey: "packages.github.tokenLabel",
|
||||
placeholderKey: "packages.github.tokenPlaceholder",
|
||||
},
|
||||
],
|
||||
instructionsKey: "packages.github.instructions",
|
||||
category: "skill",
|
||||
},
|
||||
{
|
||||
id: "gitea",
|
||||
name: "Gitea",
|
||||
descriptionKey: "packages.gitea.description",
|
||||
requiresSecrets: true,
|
||||
secrets: [
|
||||
{
|
||||
key: "token",
|
||||
labelKey: "packages.gitea.tokenLabel",
|
||||
placeholderKey: "packages.gitea.tokenPlaceholder",
|
||||
},
|
||||
],
|
||||
instructionsKey: "packages.gitea.instructions",
|
||||
category: "skill",
|
||||
},
|
||||
{
|
||||
id: "whisper-self-hosted",
|
||||
name: "Whisper (Self-Hosted Transcription)",
|
||||
descriptionKey: "packages.whisperSelfHosted.description",
|
||||
requiresSecrets: false,
|
||||
category: "skill",
|
||||
},
|
||||
{
|
||||
id: "searxng-local-search",
|
||||
name: "Web Search (SearXNG)",
|
||||
descriptionKey: "packages.searxngLocalSearch.description",
|
||||
requiresSecrets: false,
|
||||
category: "skill",
|
||||
},
|
||||
{
|
||||
id: "gog",
|
||||
name: "Google Workspace (Gog)",
|
||||
descriptionKey: "packages.gog.description",
|
||||
requiresSecrets: true,
|
||||
secrets: [
|
||||
{
|
||||
key: "client-id",
|
||||
labelKey: "packages.gog.clientIdLabel",
|
||||
placeholderKey: "packages.gog.clientIdPlaceholder",
|
||||
},
|
||||
{
|
||||
key: "client-secret",
|
||||
labelKey: "packages.gog.clientSecretLabel",
|
||||
placeholderKey: "packages.gog.clientSecretPlaceholder",
|
||||
},
|
||||
{
|
||||
key: "refresh-token",
|
||||
labelKey: "packages.gog.refreshTokenLabel",
|
||||
placeholderKey: "packages.gog.refreshTokenPlaceholder",
|
||||
},
|
||||
],
|
||||
instructionsKey: "packages.gog.instructions",
|
||||
disclaimerKey: "packages.gog.disclaimer",
|
||||
category: "skill",
|
||||
},
|
||||
{
|
||||
id: "mail",
|
||||
name: "Email (IMAP / SMTP)",
|
||||
descriptionKey: "packages.mail.description",
|
||||
requiresSecrets: true,
|
||||
secrets: [
|
||||
{
|
||||
key: "imap-host",
|
||||
labelKey: "packages.mail.imapHostLabel",
|
||||
placeholderKey: "packages.mail.imapHostPlaceholder",
|
||||
},
|
||||
{
|
||||
key: "imap-user",
|
||||
labelKey: "packages.mail.imapUserLabel",
|
||||
placeholderKey: "packages.mail.imapUserPlaceholder",
|
||||
},
|
||||
{
|
||||
key: "imap-pass",
|
||||
labelKey: "packages.mail.imapPassLabel",
|
||||
placeholderKey: "packages.mail.imapPassPlaceholder",
|
||||
},
|
||||
{
|
||||
key: "smtp-host",
|
||||
labelKey: "packages.mail.smtpHostLabel",
|
||||
placeholderKey: "packages.mail.smtpHostPlaceholder",
|
||||
},
|
||||
{
|
||||
key: "smtp-user",
|
||||
labelKey: "packages.mail.smtpUserLabel",
|
||||
placeholderKey: "packages.mail.smtpUserPlaceholder",
|
||||
},
|
||||
{
|
||||
key: "smtp-pass",
|
||||
labelKey: "packages.mail.smtpPassLabel",
|
||||
placeholderKey: "packages.mail.smtpPassPlaceholder",
|
||||
},
|
||||
],
|
||||
instructionsKey: "packages.mail.instructions",
|
||||
disclaimerKey: "packages.mail.disclaimer",
|
||||
category: "skill",
|
||||
},
|
||||
];
|
||||
|
||||
export function getPackageDef(id: string): PackageDef | undefined {
|
||||
return PACKAGE_CATALOG.find((p) => p.id === id);
|
||||
}
|
||||
|
||||
/**
|
||||
* IDs of channel-category packages. Derived from the catalog so it
|
||||
* cannot drift from the source of truth (previously hardcoded as
|
||||
* `["telegram", "discord", "email"]` in tenants/[name]/page.tsx —
|
||||
* removed as part of the Phase A package-model rework).
|
||||
*
|
||||
* Consumers: tenant detail page (filter spec.packages to channel set
|
||||
* before rendering the channel-users panel).
|
||||
*/
|
||||
export const CHANNEL_PACKAGE_IDS: string[] = PACKAGE_CATALOG
|
||||
.filter((p) => p.category === "channel")
|
||||
.map((p) => p.id);
|
||||
|
||||
/**
|
||||
* Default packages selected when the wizard opens a fresh onboarding
|
||||
* request. The three CORE behaviours that make the assistant feel
|
||||
* "smart out of the box":
|
||||
* - heartbeat: proactive checks (otherwise the assistant is purely
|
||||
* reactive).
|
||||
* - cron: scheduled tasks (daily briefings, reminders).
|
||||
* - active-memory: long-term recall of stable preferences and habits.
|
||||
*
|
||||
* Each adds some token cost — active-memory the most (one extra
|
||||
* sub-agent turn per inbound message) — so customers can untoggle any
|
||||
* of them before submitting. core-voice is deliberately excluded from
|
||||
* defaults until its config_patch lands in Phase B.
|
||||
*/
|
||||
export const DEFAULT_PACKAGE_IDS: string[] = [
|
||||
"core-heartbeat",
|
||||
"core-cron",
|
||||
"core-active-memory",
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user