initial agent-mgr: app builder platform MVP
Go API server + Preact UI + Claude Code adapter. - App-centric model (ideas, not repos) - AgentProvider interface for multi-agent support - K8s pod lifecycle for sandboxed agent sessions - Gitea integration (create repos, push branches) - WebSocket streaming for live session output - Woodpecker CI/CD pipelines (kaniko build + kubectl deploy)
This commit is contained in:
122
internal/provider/claudecode/pod.go
Normal file
122
internal/provider/claudecode/pod.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package claudecode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/agentsphere/agent-mgr/internal/provider"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
Namespace = "agent-mgr"
|
||||
RunnerImage = "git.asp.now/platform/claude-code-runner:latest"
|
||||
GitImage = "alpine/git:latest"
|
||||
)
|
||||
|
||||
func buildPod(cfg provider.SessionConfig, opts *Config) *corev1.Pod {
|
||||
podName := fmt.Sprintf("agent-%s", cfg.SessionID.String()[:8])
|
||||
branch := cfg.Branch
|
||||
|
||||
cloneScript := fmt.Sprintf(`
|
||||
set -eu
|
||||
git clone %s /workspace
|
||||
cd /workspace
|
||||
git checkout -b %s
|
||||
git config user.name "agent-mgr-bot"
|
||||
git config user.email "bot@asp.now"
|
||||
`, cfg.RepoClone, branch)
|
||||
|
||||
claudeArgs := []string{"--output-format", "stream-json", "--permission-mode", "auto-accept-only"}
|
||||
if opts != nil {
|
||||
if opts.Model != "" {
|
||||
claudeArgs = append(claudeArgs, "--model", opts.Model)
|
||||
}
|
||||
if opts.MaxTurns > 0 {
|
||||
claudeArgs = append(claudeArgs, "--max-turns", fmt.Sprintf("%d", opts.MaxTurns))
|
||||
}
|
||||
}
|
||||
|
||||
return &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: podName,
|
||||
Namespace: Namespace,
|
||||
Labels: map[string]string{
|
||||
"app": "agent-session",
|
||||
"session-id": cfg.SessionID.String(),
|
||||
},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
ServiceAccountName: "agent-runner",
|
||||
InitContainers: []corev1.Container{
|
||||
{
|
||||
Name: "git-clone",
|
||||
Image: GitImage,
|
||||
Command: []string{"sh", "-c", cloneScript},
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{Name: "workspace", MountPath: "/workspace"},
|
||||
},
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
corev1.ResourceCPU: resource.MustParse("50m"),
|
||||
corev1.ResourceMemory: resource.MustParse("64Mi"),
|
||||
},
|
||||
Limits: corev1.ResourceList{
|
||||
corev1.ResourceCPU: resource.MustParse("200m"),
|
||||
corev1.ResourceMemory: resource.MustParse("128Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "claude",
|
||||
Image: RunnerImage,
|
||||
Args: claudeArgs,
|
||||
Stdin: true,
|
||||
TTY: false,
|
||||
WorkingDir: "/workspace",
|
||||
Env: []corev1.EnvVar{
|
||||
{
|
||||
Name: "ANTHROPIC_API_KEY",
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: &corev1.SecretKeySelector{
|
||||
LocalObjectReference: corev1.LocalObjectReference{Name: "agent-mgr-secrets"},
|
||||
Key: "anthropic-api-key",
|
||||
},
|
||||
},
|
||||
},
|
||||
{Name: "SESSION_ID", Value: cfg.SessionID.String()},
|
||||
},
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{Name: "workspace", MountPath: "/workspace"},
|
||||
},
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
corev1.ResourceCPU: resource.MustParse("200m"),
|
||||
corev1.ResourceMemory: resource.MustParse("256Mi"),
|
||||
},
|
||||
Limits: corev1.ResourceList{
|
||||
corev1.ResourceCPU: resource.MustParse("500m"),
|
||||
corev1.ResourceMemory: resource.MustParse("512Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Volumes: []corev1.Volume{
|
||||
{
|
||||
Name: "workspace",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
EmptyDir: &corev1.EmptyDirVolumeSource{
|
||||
SizeLimit: resourcePtr(resource.MustParse("1Gi")),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourcePtr(q resource.Quantity) *resource.Quantity { return &q }
|
||||
Reference in New Issue
Block a user