Skip to content

Commit 7178031

Browse files
AlexsJonesclaude
andcommitted
feat: add GitHub repo + team instructions to all onboarding flows
Both the CLI (sympozium onboard) and TUI wizards now prompt for: - GitHub repository (owner/repo) — configures the github-gitops skill - Team instructions/objective — prepended to heartbeat and schedule tasks Changes: - CLI runOnboard(): add steps 4 (GitHub repo) and 5 (team task) - TUI ad-hoc wizard: add wizStepGithubRepo + wizStepTeamTask - TUI persona wizard: add wizStepPersonaGithubRepo + wizStepPersonaTeamTask (GitHub step only shown when pack uses github-gitops skill) - PersonaPackSpec: add TaskOverride field for team-level directives - Controller buildScheduleTask(): prepends TEAM OBJECTIVE to persona tasks - buildSympoziumInstanceYAML: accepts githubRepo, adds github-gitops skill - Integration test: validates taskOverride and schedule task composition - Helm examples: PersonaPack with GitHub, ad-hoc instance, values patterns Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 01b793e commit 7178031

File tree

9 files changed

+477
-34
lines changed

9 files changed

+477
-34
lines changed

api/v1alpha1/personapack_types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ type PersonaPackSpec struct {
5757
// Set during onboarding when the user configures skill-specific settings.
5858
// +optional
5959
SkillParams map[string]map[string]string `json:"skillParams,omitempty"`
60+
61+
// TaskOverride replaces each persona's default schedule task with a
62+
// team-level objective. Set during onboarding when the user provides
63+
// instructions for the team. Each persona's schedule task is prepended
64+
// with this directive so every agent works toward the same goal.
65+
// +optional
66+
TaskOverride string `json:"taskOverride,omitempty"`
6067
}
6168

6269
// PersonaSpec defines a single agent persona within a PersonaPack.

charts/sympozium/crds/sympozium.ai_personapacks.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,13 @@ spec:
241241
holds key/value pairs injected as SKILL_<KEY> environment variables.
242242
Set during onboarding when the user configures skill-specific settings.
243243
type: object
244+
taskOverride:
245+
description: |-
246+
TaskOverride replaces each persona's default schedule task with a
247+
team-level objective. Set during onboarding when the user provides
248+
instructions for the team. Each persona's schedule task is prepended
249+
with this directive so every agent works toward the same goal.
250+
type: string
244251
version:
245252
description: Version is the persona pack version.
246253
type: string

cmd/sympozium/main.go

Lines changed: 143 additions & 33 deletions
Large diffs are not rendered by default.

config/crd/bases/sympozium.ai_personapacks.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,13 @@ spec:
241241
holds key/value pairs injected as SKILL_<KEY> environment variables.
242242
Set during onboarding when the user configures skill-specific settings.
243243
type: object
244+
taskOverride:
245+
description: |-
246+
TaskOverride replaces each persona's default schedule task with a
247+
team-level objective. Set during onboarding when the user provides
248+
instructions for the team. Each persona's schedule task is prepended
249+
with this directive so every agent works toward the same goal.
250+
type: string
244251
version:
245252
description: Version is the persona pack version.
246253
type: string
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
# Example: Ad-hoc SympoziumInstance with github-gitops skill.
3+
#
4+
# This creates a single agent instance (not a PersonaPack) that has
5+
# the github-gitops skill configured with a target repository.
6+
# Useful for quick one-off agents or testing.
7+
#
8+
# Prerequisites:
9+
# 1. Install Sympozium: sympozium install
10+
# 2. Create the API key secret:
11+
# kubectl create secret generic my-agent-openai-key \
12+
# --from-literal=OPENAI_API_KEY=sk-...
13+
# 3. Create the GitHub token secret:
14+
# kubectl create secret generic github-gitops-token \
15+
# --from-literal=github-token=ghp_... \
16+
# -n sympozium-system
17+
# 4. Apply: kubectl apply -f personapack-adhoc-with-github.yaml
18+
#
19+
apiVersion: sympozium.ai/v1alpha1
20+
kind: SympoziumInstance
21+
metadata:
22+
name: my-github-agent
23+
namespace: default
24+
spec:
25+
agents:
26+
default:
27+
model: gpt-4o
28+
authRefs:
29+
- provider: openai
30+
secret: my-agent-openai-key
31+
skills:
32+
- skillPackRef: k8s-ops
33+
- skillPackRef: llmfit
34+
- skillPackRef: github-gitops
35+
params:
36+
repo: "myorg/myapp" # owner/repo format
37+
memory:
38+
enabled: true
39+
maxSizeKB: 256
40+
policyRef: default-policy
41+
---
42+
# Heartbeat schedule that references the instance above.
43+
# The task includes a team objective so the agent knows what to work on.
44+
apiVersion: sympozium.ai/v1alpha1
45+
kind: SympoziumSchedule
46+
metadata:
47+
name: my-github-agent-heartbeat
48+
namespace: default
49+
spec:
50+
instanceRef: my-github-agent
51+
schedule: "0 * * * *"
52+
task: |
53+
OBJECTIVE: Review open PRs and triage new issues in the repository.
54+
55+
Review your memory. Summarise what you know so far and note anything
56+
that needs attention.
57+
type: heartbeat
58+
concurrencyPolicy: Forbid
59+
includeMemory: true
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
# Example: Developer Team PersonaPack pointed at a GitHub repository.
3+
#
4+
# This activates the built-in developer-team pack with:
5+
# - A target GitHub repo for all agents to collaborate on
6+
# - A team-level objective that overrides each persona's default task
7+
# - OpenAI provider with a pre-created secret
8+
#
9+
# Prerequisites:
10+
# 1. Install Sympozium: sympozium install
11+
# 2. Create the API key secret:
12+
# kubectl create secret generic dev-team-openai-key \
13+
# --from-literal=OPENAI_API_KEY=sk-...
14+
# 3. Create the GitHub token secret:
15+
# kubectl create secret generic github-gitops-token \
16+
# --from-literal=github-token=ghp_... \
17+
# -n sympozium-system
18+
# 4. Apply this file: kubectl apply -f personapack-developer-team-github.yaml
19+
#
20+
apiVersion: sympozium.ai/v1alpha1
21+
kind: PersonaPack
22+
metadata:
23+
name: developer-team
24+
namespace: default
25+
spec:
26+
enabled: true
27+
description: "A 2-pizza software development team collaborating on a single GitHub repository."
28+
category: development
29+
version: "1.0.0"
30+
31+
# AI provider credentials
32+
authRefs:
33+
- provider: openai
34+
secret: dev-team-openai-key
35+
36+
# Target GitHub repository — all personas with the github-gitops skill
37+
# will receive this as SKILL_REPO in their sidecar container.
38+
skillParams:
39+
github-gitops:
40+
repo: "myorg/myapp"
41+
42+
# Team-level objective — prepended to every persona's scheduled task.
43+
# Each persona still executes their role-specific task, but with this
44+
# overarching goal guiding their work.
45+
taskOverride: "We are building a REST API for user management. Focus on the /api/v1/users endpoints. Follow the existing Go project conventions."
46+
47+
personas:
48+
- name: tech-lead
49+
displayName: "Tech Lead"
50+
model: gpt-4o
51+
systemPrompt: |
52+
You are the tech lead of a software development team.
53+
You coordinate work by triaging issues, reviewing architecture,
54+
and ensuring PRs meet quality standards before merge.
55+
skills:
56+
- github-gitops
57+
- code-review
58+
- software-dev
59+
schedule:
60+
type: scheduled
61+
interval: "2h"
62+
task: "Review open PRs, triage new issues, and merge approved PRs that pass CI."
63+
memory:
64+
enabled: true
65+
seeds:
66+
- "Track team velocity and open PR count across runs"
67+
68+
- name: backend-dev
69+
displayName: "Backend Developer"
70+
model: gpt-4o
71+
systemPrompt: |
72+
You are a backend software developer. You implement server-side
73+
features, APIs, data models, and business logic.
74+
skills:
75+
- github-gitops
76+
- code-review
77+
- software-dev
78+
schedule:
79+
type: sweep
80+
interval: "1h"
81+
task: "Pick up the highest priority backend issue, implement the fix, write tests, and open a PR."
82+
memory:
83+
enabled: true
84+
seeds:
85+
- "Note the project's tech stack and code conventions"
86+
87+
- name: qa-engineer
88+
displayName: "QA Engineer"
89+
model: gpt-4o
90+
systemPrompt: |
91+
You are a QA engineer. You ensure software quality through
92+
testing, bug discovery, and coverage analysis.
93+
skills:
94+
- github-gitops
95+
- code-review
96+
- software-dev
97+
schedule:
98+
type: sweep
99+
interval: "45m"
100+
task: "Review recent PRs for test coverage gaps and open follow-up PRs adding tests."
101+
memory:
102+
enabled: true
103+
seeds:
104+
- "Track test coverage trends and areas with low coverage"
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
# Helm values examples for deploying PersonaPacks via the Sympozium chart.
3+
#
4+
# Install with:
5+
# helm install sympozium ./charts/sympozium -f personapack-helm-values-examples.yaml
6+
#
7+
# These values show different ways to configure persona packs at install time.
8+
9+
# ─────────────────────────────────────────────────────────────────────────────
10+
# Example 1: Enable built-in packs (deployed from charts/sympozium/files/personas/)
11+
# ─────────────────────────────────────────────────────────────────────────────
12+
defaultPersonas:
13+
enabled: true # Installs developer-team, devops-essentials, platform-team
14+
15+
# ─────────────────────────────────────────────────────────────────────────────
16+
# Example 2: Override values for an existing pack post-install
17+
# ─────────────────────────────────────────────────────────────────────────────
18+
# After helm install, activate and configure the developer-team pack:
19+
#
20+
# kubectl patch personapack developer-team --type=merge -p '{
21+
# "spec": {
22+
# "enabled": true,
23+
# "authRefs": [{"provider": "openai", "secret": "dev-team-openai-key"}],
24+
# "skillParams": {
25+
# "github-gitops": {"repo": "myorg/myapp"}
26+
# },
27+
# "taskOverride": "Build the v2 REST API. Focus on backward compatibility."
28+
# }
29+
# }'
30+
#
31+
# Or via the TUI: sympozium → Personas tab → select pack → Enter
32+
33+
# ─────────────────────────────────────────────────────────────────────────────
34+
# Example 3: Activate via the Sympozium API server
35+
# ─────────────────────────────────────────────────────────────────────────────
36+
# The API server exposes a PATCH endpoint for PersonaPacks:
37+
#
38+
# curl -X PATCH http://localhost:19090/api/v1/personapacks/developer-team \
39+
# -H "Content-Type: application/json" \
40+
# -d '{
41+
# "enabled": true,
42+
# "provider": "anthropic",
43+
# "secretName": "dev-team-anthropic-key",
44+
# "model": "claude-sonnet-4-20250514",
45+
# "skillParams": {
46+
# "github-gitops": {"repo": "myorg/myapp"}
47+
# },
48+
# "taskOverride": "Migrate the codebase from Express to Fastify."
49+
# }'
50+
51+
# ─────────────────────────────────────────────────────────────────────────────
52+
# Example 4: Custom PersonaPack in a Helm post-install hook
53+
# ─────────────────────────────────────────────────────────────────────────────
54+
# Place this in charts/sympozium/templates/custom-pack.yaml:
55+
#
56+
# apiVersion: sympozium.ai/v1alpha1
57+
# kind: PersonaPack
58+
# metadata:
59+
# name: my-custom-team
60+
# annotations:
61+
# "helm.sh/hook": post-install
62+
# spec:
63+
# enabled: true
64+
# description: "My custom team"
65+
# category: custom
66+
# authRefs:
67+
# - provider: openai
68+
# secret: my-team-openai-key
69+
# skillParams:
70+
# github-gitops:
71+
# repo: "myorg/myapp"
72+
# taskOverride: "Ship the MVP by end of sprint."
73+
# personas:
74+
# - name: dev
75+
# displayName: "Developer"
76+
# systemPrompt: "You are a full-stack developer."
77+
# model: gpt-4o
78+
# skills: [github-gitops, code-review, software-dev]
79+
# schedule:
80+
# type: sweep
81+
# interval: "1h"
82+
# task: "Pick up the top issue and implement it."
83+
84+
# ─────────────────────────────────────────────────────────────────────────────
85+
# Example 5: Deploying with Ollama (no API key, local models)
86+
# ─────────────────────────────────────────────────────────────────────────────
87+
# kubectl patch personapack developer-team --type=merge -p '{
88+
# "spec": {
89+
# "enabled": true,
90+
# "authRefs": [{"provider": "ollama"}],
91+
# "skillParams": {
92+
# "github-gitops": {"repo": "myorg/myapp"}
93+
# }
94+
# }
95+
# }'
96+
#
97+
# Each persona will use Ollama's default model. Override per-persona with:
98+
# spec.personas[].model: "llama3"

internal/controller/personapack_controller.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,14 +466,27 @@ func (r *PersonaPackReconciler) buildSchedule(
466466
Spec: sympoziumv1alpha1.SympoziumScheduleSpec{
467467
InstanceRef: instanceName,
468468
Schedule: cron,
469-
Task: persona.Schedule.Task,
469+
Task: r.buildScheduleTask(pack, persona),
470470
Type: persona.Schedule.Type,
471471
ConcurrencyPolicy: "Forbid",
472472
IncludeMemory: true,
473473
},
474474
}
475475
}
476476

477+
// buildScheduleTask constructs the task string for a persona's schedule.
478+
// If the pack has a TaskOverride, it prepends the team-level directive.
479+
func (r *PersonaPackReconciler) buildScheduleTask(
480+
pack *sympoziumv1alpha1.PersonaPack,
481+
persona *sympoziumv1alpha1.PersonaSpec,
482+
) string {
483+
base := persona.Schedule.Task
484+
if pack.Spec.TaskOverride != "" {
485+
return fmt.Sprintf("TEAM OBJECTIVE: %s\n\nYOUR ROLE TASK: %s", pack.Spec.TaskOverride, base)
486+
}
487+
return base
488+
}
489+
477490
// reconcileMemorySeeds creates or patches the memory ConfigMap with seed data.
478491
func (r *PersonaPackReconciler) reconcileMemorySeeds(
479492
ctx context.Context,

test/integration/test-api-github-repo-onboarding.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ADHOC_INSTANCE_NAME="inttest-ghrepo-adhoc-$(date +%s)"
2323
ADHOC_SECRET_NAME="${ADHOC_INSTANCE_NAME}-openai-key"
2424

2525
GITHUB_REPO="octocat/Hello-World"
26+
TEAM_TASK="Build the v2 REST API with backward compatibility"
2627
MODEL_NAME="gpt-4o-mini"
2728

2829
RED='\033[0;31m'
@@ -265,6 +266,7 @@ spec:
265266
skillParams:
266267
github-gitops:
267268
repo: "${GITHUB_REPO}"
269+
taskOverride: "${TEAM_TASK}"
268270
personas:
269271
- name: ${PERSONA_NAME}
270272
displayName: "Test Developer"
@@ -333,6 +335,42 @@ EOF
333335
pass "Pack run inherited github-gitops repo param"
334336
fi
335337

338+
# Verify taskOverride is persisted on the PersonaPack.
339+
pack_json="$(kubectl get personapack "$PACK_NAME" -n "$NAMESPACE" -o json)"
340+
got_task="$(printf "%s" "$pack_json" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("spec",{}).get("taskOverride",""))')"
341+
if [[ "$got_task" != "$TEAM_TASK" ]]; then
342+
fail "Pack taskOverride mismatch (got '${got_task}', want '${TEAM_TASK}')"
343+
else
344+
pass "Pack taskOverride is set correctly"
345+
fi
346+
347+
# Verify the schedule task includes the team objective.
348+
sched_name="${PACK_INSTANCE_NAME}-schedule"
349+
elapsed=0
350+
while [[ "$elapsed" -lt 30 ]]; do
351+
if kubectl get sympoziumschedule "$sched_name" -n "$NAMESPACE" >/dev/null 2>&1; then
352+
break
353+
fi
354+
sleep 2
355+
elapsed=$((elapsed + 2))
356+
done
357+
if kubectl get sympoziumschedule "$sched_name" -n "$NAMESPACE" >/dev/null 2>&1; then
358+
sched_json="$(kubectl get sympoziumschedule "$sched_name" -n "$NAMESPACE" -o json)"
359+
sched_task="$(printf "%s" "$sched_json" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("spec",{}).get("task",""))')"
360+
if echo "$sched_task" | grep -q "TEAM OBJECTIVE:"; then
361+
pass "Schedule task contains TEAM OBJECTIVE prefix"
362+
else
363+
fail "Schedule task missing TEAM OBJECTIVE prefix (got: ${sched_task:0:80})"
364+
fi
365+
if echo "$sched_task" | grep -q "test github task"; then
366+
pass "Schedule task preserves persona's original task"
367+
else
368+
fail "Schedule task missing persona's original task"
369+
fi
370+
else
371+
info "Schedule '${sched_name}' not found — skipping task override check (controller may not have created it yet)"
372+
fi
373+
336374
# ──────────────────────────────────────────────────────────────
337375
# Summary
338376
# ──────────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)