initial commit

This commit is contained in:
2026-03-25 00:05:57 +01:00
commit 25c7d598ca
63 changed files with 5257 additions and 0 deletions

136
03-CRD/AgentRun.md Normal file
View File

@@ -0,0 +1,136 @@
# AgentRun
#sympozium #crd #agentrun
## Definicja
`AgentRun` reprezentuje **pojedyncze wywołanie agenta**. Każdy AgentRun reconciliuje się w Kubernetes Job (tryb task) lub Deployment (tryb server).
**Plik:** `api/v1alpha1/agentrun_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: AgentRun
metadata:
name: my-run-001
spec:
instanceRef: my-agent # Powiązanie z SympoziumInstance
agentId: default
sessionKey: session-123
task: "Sprawdź stan klastra"
systemPrompt: "Jesteś SRE inżynierem..."
model:
provider: anthropic
model: claude-sonnet-4-20250514
baseURL: ""
thinking: "high"
authSecretRef: anthropic-key
nodeSelector:
gpu-type: a100
mode: task|server # Job vs Deployment
parent: # Dla sub-agentów
runName: parent-run
sessionKey: parent-session
spawnDepth: 1
skills:
- skillPackRef: k8s-ops
toolPolicy:
allow: [read_file, list_directory]
deny: [execute_command]
timeout: 5m
cleanup: delete|keep # Po zakończeniu
sandbox: # Container-level sandbox
enabled: true
image: custom-sandbox:v1
agentSandbox: # Kernel-level sandbox (Sandbox CR)
enabled: true
runtimeClass: gvisor
warmPoolRef: wp-my-agent
env: # Custom env vars
MY_VAR: my-value
```
## Status
```yaml
status:
phase: Pending|Running|Serving|Succeeded|Failed
podName: my-run-001-abc123
jobName: my-run-001
sandboxName: my-run-001-sandbox # Agent Sandbox mode
startedAt: "2024-01-01T00:00:00Z"
completedAt: "2024-01-01T00:05:00Z"
result: "Klaster jest zdrowy. 15 podów running..."
error: ""
exitCode: 0
tokenUsage:
inputTokens: 1500
outputTokens: 800
totalTokens: 2300
toolCalls: 5
durationMs: 45000
traceID: "abc123def456" # OTel trace
deploymentName: "" # Server mode
serviceName: "" # Server mode
```
## Fazy lifecycle
```
""(empty) → Pending → Running → Succeeded
→ Failed
→ Serving (tryb server - długo żyjący)
```
### Przejścia faz
| Z fazy | Do fazy | Trigger |
|--------|---------|---------|
| "" / Pending | Running | Job/Sandbox CR utworzony, pod running |
| Running | Succeeded | Pod zakończył się z kodem 0 |
| Running | Failed | Pod zakończył się z kodem != 0 lub timeout |
| Pending | Serving | Mode=server, Deployment ready |
| Serving | Succeeded | AgentRun usunięty (cleanup Deployment) |
## Token Usage Tracking
AgentRun śledzi zużycie tokenów LLM:
- `inputTokens` - tokeny promptu
- `outputTokens` - tokeny odpowiedzi
- `totalTokens` - suma
- `toolCalls` - liczba wywołań narzędzi
- `durationMs` - czas wall-clock w ms
## Sub-agenty
AgentRun wspiera hierarchię parent-child:
```yaml
parent:
runName: parent-run-001
sessionKey: parent-session
spawnDepth: 1 # Głębokość w drzewie
```
Limity zdefiniowane w [[SympoziumInstance]] → `agents.default.subagents`:
- `maxDepth: 2` - max zagnieżdżenie
- `maxConcurrent: 5` - max równoległych
- `maxChildrenPerAgent: 3` - max dzieci per agent
## History Pruning
Controller utrzymuje max 50 zakończonych AgentRun per instancja (konfigurowalny `RunHistoryLimit`). Starsze są automatycznie usuwane.
---
Powiązane: [[SympoziumInstance]] | [[Cykl życia AgentRun]] | [[Cykl życia Agent Pod]]

104
03-CRD/MCPServer.md Normal file
View File

@@ -0,0 +1,104 @@
# MCPServer
#sympozium #crd #mcp
## Definicja
`MCPServer` zarządza lifecycle **serwerów MCP (Model Context Protocol)** w klastrze. Wspiera stdio (z HTTP adapterem), HTTP i external transport.
**Plik:** `api/v1alpha1/mcpserver_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: MCPServer
metadata:
name: github-mcp
spec:
transportType: stdio|http
# Dla external/pre-existing serwerów (bez deploymentu):
url: "http://external-mcp.example.com/mcp"
# Dla managed serwerów:
deployment:
image: ghcr.io/my-org/github-mcp:v1
cmd: "/usr/bin/github-mcp-server"
args: ["--stdio"]
port: 8080
env:
LOG_LEVEL: info
secretRefs:
- name: github-token
resources:
requests:
cpu: "100m"
memory: "128Mi"
serviceAccountName: github-mcp-sa
toolsPrefix: gh # Prefix unikający kolizji
timeout: 30
replicas: 1
toolsAllow: [create_issue] # Whitelist narzędzi
toolsDeny: [delete_repo] # Blacklist narzędzi
```
## Dwa tryby
### Managed (z deployment spec)
Controller tworzy Deployment + Service:
- stdio → HTTP adapter automatycznie
- Probing narzędzi po starcie
- Lifecycle zarządzany przez controller
### External (z URL)
Tylko referencja do istniejącego serwera:
- Brak deploymentu
- Probing narzędzi pod podanym URL
- Użytkownik zarządza lifecycle
## Tool Discovery
Po starcie MCPServer, controller:
1. Probeuje endpoint MCP
2. Odkrywa dostępne narzędzia
3. Aplikuje `toolsAllow` / `toolsDeny` filtry
4. Zapisuje listę narzędzi w `status.tools`
5. Prefiksuje nazwy: `gh_create_issue`, `gh_list_repos`
## Status
```yaml
status:
ready: true
url: "http://github-mcp.sympozium-system.svc:8080"
toolCount: 12
tools: [create_issue, list_repos, ...]
```
## Integracja z agentem
```
SympoziumInstance → mcpServers: [{name: github-mcp, toolsPrefix: gh}]
AgentRun tworzony → Reconciler:
1. Rozwiązuje MCPServer CR → pobiera URL ze status
2. Tworzy MCP ConfigMap z konfiguracją serwerów
3. Dodaje mcp-bridge sidecar do poda
Agent w podzie:
- mcp-bridge sidecar tłumaczy tool calls → MCP protocol
- Narzędzia widoczne jako prefixed: gh_create_issue, gh_list_repos
```
## Tool namespacing
Prefiksy zapobiegają kolizjom gdy wiele MCP serwerów jest aktywnych:
- `gh_create_issue` (GitHub MCP)
- `jira_create_ticket` (Jira MCP)
- `slack_send_message` (Slack MCP)
---
Powiązane: [[MCP Servers - Model Context Protocol]] | [[SympoziumInstance]] | [[Przepływ danych i IPC]]

132
03-CRD/PersonaPack.md Normal file
View File

@@ -0,0 +1,132 @@
# PersonaPack
#sympozium #crd #personapack
## Definicja
`PersonaPack` to CRD bundlujący **wiele pre-konfigurowanych person agentów**. Aktywacja packa powoduje automatyczne tworzenie SympoziumInstances, Schedules i memory seeds.
**Plik:** `api/v1alpha1/personapack_types.go`
## Analogia
PersonaPack jest dla agentów AI tym, czym Helm Chart dla aplikacji K8s - **deklaratywny bundle** który controller "rozpakowuje" w konkretne zasoby.
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: PersonaPack
metadata:
name: platform-team
spec:
enabled: true # Dopóki false - katalog; true - controller stampuje
description: "Core platform engineering team"
category: platform
version: "1.0.0"
authRefs: # Credentials (ustawiane przy aktywacji)
- provider: openai
secret: platform-team-openai-key
policyRef: restrictive # Wspólna polityka
baseURL: "" # Override dla lokalnych providerów
channelConfigs: # Mapowanie kanał → secret
telegram: telegram-creds
skillParams: # Parametry per-skill
github-gitops:
REPO: my-org/my-repo
taskOverride: "Focus on reducing MTTR" # Nadpisanie celów
excludePersonas: # Wyłączone persony
- cost-analyzer
channelAccessControl:
telegram:
allowedSenders: ["123456"]
agentSandbox: # Kernel-level isolation dla wszystkich
enabled: true
runtimeClass: gvisor
personas:
- name: security-guardian
displayName: "Security Guardian"
systemPrompt: |
You are a Kubernetes security specialist...
model: claude-sonnet-4-20250514
skills:
- k8s-ops
- sre-observability
toolPolicy:
allow: [execute_command, read_file, fetch_url]
channels:
- telegram
schedule:
type: heartbeat
interval: "30m"
task: "Run security audit on all namespaces"
memory:
enabled: true
seeds:
- "Track CVEs found in previous scans"
- "Remember cluster topology changes"
```
## Mechanizm aktywacji
```
PersonaPack (enabled: false) → Katalog (TUI pokazuje jako dostępny)
Użytkownik aktywuje (TUI wizard / kubectl patch)
PersonaPack (enabled: true, authRefs set) → Controller stampuje:
├── Secret: platform-team-openai-key
├── SympoziumInstance: platform-team-security-guardian
│ ├── SympoziumSchedule + ConfigMap memory (seeded)
├── SympoziumInstance: platform-team-sre-watchdog
│ ├── SympoziumSchedule + ConfigMap memory (seeded)
└── SympoziumInstance: platform-team-platform-engineer
└── SympoziumSchedule + ConfigMap memory (seeded)
```
## Wbudowane packi
| Pack | Kategoria | Agenty | Opis |
|------|-----------|--------|------|
| `platform-team` | Platform | Security Guardian, SRE Watchdog, Platform Engineer | Bezpieczeństwo, health, manifest review |
| `devops-essentials` | DevOps | Incident Responder, Cost Analyzer | Triage incydentów, right-sizing |
| `developer-team` | Development | 7 agentów (Tech Lead, Backend/Frontend Dev, QA, Code Reviewer, DevOps, Docs Writer) | Pełny zespół dev |
## Status
```yaml
status:
phase: Pending|Ready|Error
personaCount: 3
installedCount: 3
installedPersonas:
- name: security-guardian
instanceName: platform-team-security-guardian
scheduleName: platform-team-security-guardian-schedule
```
## ownerReferences
Wszystkie wygenerowane zasoby mają `ownerReference` → PersonaPack. Usunięcie packa = garbage collection całego zespołu.
## Znaczenie architektoniczne
PersonaPacks rozwiązują problem **Day 1 Experience** - zamiast ręcznie tworzyć Secret + Instance + Schedule + Memory per agent, użytkownik:
1. Wybiera pack w TUI
2. Podaje klucz API
3. Cały zespół agentów jest gotowy
To także wzorzec **Infrastructure as Code dla AI Teams** - deklarujesz zespół agentów w YAML, controller realizuje intent.
---
Powiązane: [[PersonaPacks - zespoły agentów]] | [[SympoziumInstance]] | [[SympoziumSchedule]]

131
03-CRD/SkillPack.md Normal file
View File

@@ -0,0 +1,131 @@
# SkillPack
#sympozium #crd #skillpack
## Definicja
`SkillPack` to CRD bundlujący **Markdown instrukcje + opcjonalny sidecar kontener + RBAC**. Skills montowane są jako pliki w podzie agenta.
**Plik:** `api/v1alpha1/skillpack_types.go`
## Dwuwarstwowa architektura skilli
### Warstwa 1: Instrukcje (Markdown)
Każdy skill to plik Markdown montowany w `/skills/` - agent czyta go jako instrukcje do LLM.
### Warstwa 2: Sidecar (opcjonalny)
Sidecar to kontener z narzędziami (kubectl, helm, git) + auto-provisioned RBAC.
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SkillPack
metadata:
name: k8s-ops
spec:
category: kubernetes
version: "1.0.0"
skills:
- name: k8s-ops
description: "Kubernetes operations"
content: |
# Kubernetes Operations
You have access to kubectl via the execute_command tool...
requires:
bins: [kubectl]
tools: [execute_command]
sidecar:
image: ghcr.io/sympozium-ai/sympozium/skill-k8s-ops:v0.0.25
command: ["sleep", "infinity"]
mountWorkspace: true
env:
- name: KUBECONFIG
value: /var/run/secrets/kubernetes.io/serviceaccount/token
resources:
cpu: "100m"
memory: "128Mi"
rbac: # Namespace-scoped RBAC
- apiGroups: ["", "apps"]
resources: ["pods", "deployments"]
verbs: ["get", "list", "watch"]
clusterRBAC: # Cluster-scoped RBAC
- apiGroups: [""]
resources: ["nodes", "namespaces"]
verbs: ["get", "list", "watch"]
secretRef: github-token # Sekrety montowane w sidecarze
secretMountPath: /secrets/github
hostAccess: # Dostęp do hosta (np. node-probe)
enabled: false
hostNetwork: false
hostPID: false
privileged: false
mounts:
- hostPath: /var/log
mountPath: /host-logs
readOnly: true
requiresServer: false # Czy wymaga Deployment zamiast Job
ports:
- name: http
containerPort: 8080
```
## Status
```yaml
status:
phase: Ready
configMapName: skillpack-k8s-ops
skillCount: 1
```
## Cykl życia
```
SkillPack CR utworzony
SkillPackReconciler → Generuje ConfigMap z Markdown contentem
SympoziumInstance referencjonuje skill
AgentRun tworzony → AgentRunReconciler:
1. Czyta SkillPack → wyciąga sidecar spec
2. Tworzy Role + RoleBinding (namespace RBAC)
3. Tworzy ClusterRole + ClusterRoleBinding (cluster RBAC)
4. Dodaje sidecar kontener do pod spec
5. Montuje ConfigMap jako /skills/ volume
Po zakończeniu AgentRun:
- Namespace RBAC: garbage-collected via ownerReference
- Cluster RBAC: cleaned up by controller via label selector
```
## Parametryzacja
SkillPacks mogą być parametryzowane per-instancja:
```yaml
# W SympoziumInstance
skills:
- skillPackRef: github-gitops
params:
REPO: my-org/my-repo
BRANCH: main
```
Parametry injektowane jako `SKILL_REPO`, `SKILL_BRANCH` env vars w sidecarze.
## RequiresServer
Gdy `sidecar.requiresServer: true`, AgentRun tworzony jest w trybie `server` (Deployment + Service zamiast Job). Przykład: skill `web-endpoint`.
---
Powiązane: [[Skill Sidecars i auto-RBAC]] | [[Efemeryczny RBAC per-run]] | [[SympoziumInstance]]

119
03-CRD/SympoziumInstance.md Normal file
View File

@@ -0,0 +1,119 @@
# SympoziumInstance
#sympozium #crd #instance
## Definicja
`SympoziumInstance` to centralny CRD reprezentujący **jednego tenanta/użytkownika**. Deklaruje konfigurację kanałów, agentów, skillów, polityk i memory.
**Plik:** `api/v1alpha1/sympoziuminstance_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SympoziumInstance
metadata:
name: my-agent
spec:
channels: # Podłączone kanały
- type: telegram
configRef:
secret: telegram-creds
accessControl:
allowedSenders: ["123456"]
agents:
default:
model: gpt-4.1
baseURL: "" # Override dla OpenAI-compat
thinking: "medium" # off/low/medium/high
sandbox:
enabled: false
agentSandbox: # Kernel-level isolation
enabled: true
runtimeClass: gvisor
warmPool:
size: 3
subagents:
maxDepth: 2
maxConcurrent: 5
maxChildrenPerAgent: 3
nodeSelector: # Pinning do GPU node'ów
gpu-type: "a100"
skills: # SkillPacks do montowania
- skillPackRef: k8s-ops
params:
CLUSTER: production
- skillPackRef: memory
policyRef: restrictive # Polityka bezpieczeństwa
authRefs: # Klucze API
- provider: openai
secret: openai-key
memory: # Legacy ConfigMap memory
enabled: true
maxSizeKB: 256
observability: # OpenTelemetry
enabled: true
otlpEndpoint: "otel-collector.observability.svc:4317"
mcpServers: # External tool providers
- name: github
toolsPrefix: gh
timeout: 30
```
## Status
```yaml
status:
phase: Running|Serving|Pending|Error
channels:
- type: telegram
status: Connected|Disconnected|Error
activeAgentPods: 2
totalAgentRuns: 150
webEndpoint:
status: Ready
url: "alice.sympozium.example.com"
```
## Kluczowe koncepty
### Multi-tenancy
Każda SympoziumInstance to osobny tenant z:
- Własnymi kanałami
- Własnymi credentials (AuthRefs)
- Własną polityką
- Własną memory
- Własnymi MCP serverami
### Reconciliation
`SympoziumInstanceReconciler` zarządza:
1. **Channel Deployments** - tworzy/aktualizuje Deployment per kanał
2. **Memory ConfigMap** - legacy `<name>-memory` ConfigMap
3. **Memory PVC** - SQLite DB dla memory SkillPack
4. **Memory Deployment** - memory-server Deployment + Service
5. **Web Endpoints** - server-mode AgentRun dla web-endpoint skill
### Finalizery
Przy usunięciu instancji controller:
- Czyści channel deployments
- Czyści memory ConfigMap
- Czyści memory deployment
### Channel Access Control
Kanały mogą ograniczać kto może komunikować się z agentem:
- `allowedSenders` - whitelist ID nadawców
- `deniedSenders` - blacklist (nadpisuje whitelist)
- `allowedChats` - whitelist ID czatów/grup
- `denyMessage` - wiadomość dla odrzuconych
---
Powiązane: [[AgentRun]] | [[PersonaPack]] | [[SympoziumPolicy]] | [[Kanały - Telegram Slack Discord WhatsApp]]

95
03-CRD/SympoziumPolicy.md Normal file
View File

@@ -0,0 +1,95 @@
# SympoziumPolicy
#sympozium #crd #policy #security
## Definicja
`SympoziumPolicy` definiuje **polityki governance** nad zachowaniem agentów: sandbox requirements, network isolation, tool access i resource limits.
**Plik:** `api/v1alpha1/sympoziumpolicy_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SympoziumPolicy
metadata:
name: restrictive
spec:
sandboxPolicy:
required: true # Sandbox obowiązkowy
defaultImage: sandbox:v1
maxCPU: "1"
maxMemory: "1Gi"
allowHostMounts: false
seccompProfile:
type: RuntimeDefault
agentSandboxPolicy: # Agent Sandbox (gVisor/Kata)
required: true
defaultRuntimeClass: gvisor
allowedRuntimeClasses: [gvisor, kata]
subagentPolicy:
maxDepth: 3 # Max zagnieżdżenie sub-agentów
maxConcurrent: 5 # Max równoległych
toolGating:
defaultAction: deny # deny/allow/ask
rules:
- tool: read_file
action: allow
- tool: execute_command
action: deny
- tool: write_file
action: ask
featureGates:
memory: true
web-endpoint: false
channels: true
networkPolicy:
denyAll: true # Deny-all egress
allowDNS: true # Wyjątek: DNS
allowEventBus: true # Wyjątek: NATS
allowedEgress: # Dodatkowe wyjątki
- host: "api.openai.com"
port: 443
```
## Enforcement
Polityki są enforced przez **admission webhook** - nie at runtime, ale **at admission time** (przed utworzeniem poda):
```
AgentRun CR → API Server → Admission Webhook → SympoziumPolicy check
├── PASS → CR created
└── DENY → CR rejected
```
## Presetowe polityki
| Polityka | Kto | Kluczowe reguły |
|----------|-----|-----------------|
| **Permissive** | Dev, demo | Wszystkie tools dozwolone, brak sandbox requirement |
| **Default** | Ogólne użycie | `execute_command` wymaga approval, reszta dozwolona |
| **Restrictive** | Produkcja | Wszystko domyślnie denied, whitelist, sandbox required |
## NetworkPolicy
Polityka `networkPolicy` generuje Kubernetes NetworkPolicy:
- **denyAll: true** - agent pods nie mają dostępu do internetu ani innych podów
- **allowDNS: true** - wyjątek dla rozwiązywania nazw
- **allowEventBus: true** - wyjątek dla NATS (tylko IPC bridge)
- **allowedEgress** - whitelist konkretnych endpointów (np. API providerów LLM)
## Status
```yaml
status:
boundInstances: 5 # Ile instancji używa tej polityki
```
---
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[Admission Webhooks i polityki]] | [[NetworkPolicy i izolacja sieciowa]]

View File

@@ -0,0 +1,77 @@
# SympoziumSchedule
#sympozium #crd #schedule
## Definicja
`SympoziumSchedule` definiuje **recurring tasks** dla SympoziumInstance - analogicznie do CronJob, ale tworzy AgentRun zamiast Pod.
**Plik:** `api/v1alpha1/sympoziumschedule_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SympoziumSchedule
metadata:
name: my-agent-health-check
spec:
instanceRef: my-agent
schedule: "*/30 * * * *" # Co 30 minut
task: "Run comprehensive health check"
type: heartbeat|scheduled|sweep
suspend: false
concurrencyPolicy: Forbid|Allow|Replace
includeMemory: true # Inject MEMORY.md do kontekstu
```
## Typy scheduli
| Typ | Opis | Typowy interwał |
|-----|------|-----------------|
| `heartbeat` | Regularne sprawdzanie stanu | 5-30 minut |
| `scheduled` | Zaplanowane zadania | Godzinowo/dziennie |
| `sweep` | Przeglądy i cleanup | Dziennie/tygodniowo |
## Concurrency Policy
| Polityka | Zachowanie |
|----------|------------|
| `Forbid` | Nie twórz nowego runu jeśli poprzedni jeszcze działa |
| `Allow` | Pozwól na równoległe uruchomienia |
| `Replace` | Anuluj poprzedni run i utwórz nowy |
## Self-scheduling
Agenty mogą **same zarządzać swoimi schedulami** przez narzędzie `schedule_task`:
```
Agent → /ipc/schedules/create-schedule.json → IPC Bridge → NATS: schedule.upsert
→ Schedule Router → tworzy/aktualizuje SympoziumSchedule CRD
```
Operacje: create, update, suspend, resume, delete.
## Status
```yaml
status:
phase: Active|Suspended|Error
lastRunTime: "2024-01-01T12:00:00Z"
nextRunTime: "2024-01-01T12:30:00Z"
lastRunName: my-agent-health-check-run-42
totalRuns: 200
```
## Reconciliation
`SympoziumScheduleReconciler`:
1. Oblicza `nextRunTime` z cron expression
2. Kiedy `now >= nextRunTime`:
- Sprawdza concurrency policy
- Tworzy AgentRun CR z task + opcjonalnie memory
- Aktualizuje `lastRunTime` i `lastRunName`
---
Powiązane: [[Scheduled Tasks - heartbeaty i swepy]] | [[SympoziumInstance]] | [[AgentRun]]