diff --git a/pkg/agentic/deps.go b/pkg/agentic/deps.go index d1b036b..845f5f6 100644 --- a/pkg/agentic/deps.go +++ b/pkg/agentic/deps.go @@ -13,9 +13,8 @@ func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, workspaceDir, re goModPath := core.JoinPath(repoDir, "go.mod") r := fs.Read(goModPath) if !r.OK { - return // no go.mod — not a Go project + return } - // Parse requires from go.mod deps := parseCoreDeps(r.Value.(string)) if len(deps) == 0 { return @@ -25,7 +24,6 @@ func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, workspaceDir, re } process := s.Core().Process() - // Deduplicate (dappco.re and forge.lthn.ai may map to same repo) dedupSeen := make(map[string]bool) var unique []coreDep for _, dep := range deps { @@ -36,12 +34,11 @@ func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, workspaceDir, re } deps = unique - // Clone each dependency var cloned []string for _, dep := range deps { depDir := core.JoinPath(workspaceDir, dep.dir) if fs.IsDir(core.JoinPath(depDir, ".git")) { - cloned = append(cloned, dep.dir) // already cloned (resume) + cloned = append(cloned, dep.dir) continue } @@ -51,7 +48,6 @@ func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, workspaceDir, re } } - // Rebuild go.work with repo + all cloned deps if len(cloned) > 0 { b := core.NewBuilder() b.WriteString("go 1.26.0\n\nuse (\n") @@ -64,11 +60,11 @@ func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, workspaceDir, re } } -// coreDep maps a Go module path to a Forge repo clone target. +// dep := coreDep{module: "dappco.re/go/core", repo: "go", dir: "core-go"} type coreDep struct { - module string // e.g. "dappco.re/go/core" - repo string // e.g. "go" (Forge repo name) - dir string // e.g. "core-go" (workspace subdir) + module string + repo string + dir string } // deps := parseCoreDeps(goMod) @@ -80,12 +76,10 @@ func parseCoreDeps(gomod string) []coreDep { for _, line := range core.Split(gomod, "\n") { line = core.Trim(line) - // Skip indirect dependencies if core.Contains(line, "// indirect") { continue } - // Match dappco.re/go/* requires if core.HasPrefix(line, "dappco.re/go/") { parts := core.Split(line, " ") mod := parts[0] @@ -94,14 +88,9 @@ func parseCoreDeps(gomod string) []coreDep { } seen[mod] = true - // dappco.re/go/core → repo "go", dir "core-go" - // dappco.re/go/core/process → repo "go-process", dir "core-go-process" - // dappco.re/go/core/ws → repo "go-ws", dir "core-go-ws" - // dappco.re/go/mcp → repo "mcp", dir "core-mcp" suffix := core.TrimPrefix(mod, "dappco.re/go/") repo := suffix if core.HasPrefix(suffix, "core/") { - // core/process → go-process repoSuffix := core.TrimPrefix(suffix, "core/") repo = core.Concat("go-", repoSuffix) } else if suffix == "core" { @@ -110,29 +99,13 @@ func parseCoreDeps(gomod string) []coreDep { dir := core.Concat("core-", core.Replace(repo, "/", "-")) deps = append(deps, coreDep{module: mod, repo: repo, dir: dir}) } - - // Match forge.lthn.ai/core/* requires (legacy paths) - //if core.HasPrefix(line, "forge.lthn.ai/core/") { - // parts := core.Split(line, " ") - // mod := parts[0] - // if seen[mod] { - // continue - // } - // seen[mod] = true - // - // suffix := core.TrimPrefix(mod, "forge.lthn.ai/core/") - // repo := suffix - // dir := core.Concat("core-", core.Replace(repo, "/", "-")) - // deps = append(deps, coreDep{module: mod, repo: repo, dir: dir}) - //} } return deps } -// forgeSSHURL builds the Forge SSH clone URL for a repo. -// -// forgeSSHURL("core", "go-io") → "ssh://git@forge.lthn.ai:2223/core/go-io.git" +// url := forgeSSHURL("core", "go-io") +// core.Println(url) // "ssh://git@forge.lthn.ai:2223/core/go-io.git" func forgeSSHURL(org, repo string) string { return core.Concat("ssh://git@forge.lthn.ai:2223/", org, "/", repo, ".git") } diff --git a/pkg/agentic/handlers.go b/pkg/agentic/handlers.go index 3108596..8f6d3dd 100644 --- a/pkg/agentic/handlers.go +++ b/pkg/agentic/handlers.go @@ -58,9 +58,8 @@ func (s *PrepSubsystem) SpawnFromQueue(agent, prompt, workspaceDir string) core. return core.Result{Value: pid, OK: true} } -// resolveWorkspace converts a workspace name back to the full path. -// -// resolveWorkspace("core/go-io/task-5") → "/Users/snider/Code/.core/workspace/core/go-io/task-5" +// workspaceDir := resolveWorkspace("core/go-io/task-5") +// core.Println(workspaceDir) // "/srv/.core/workspace/core/go-io/task-5" func resolveWorkspace(name string) string { workspaceRoot := WorkspaceRoot() path := core.JoinPath(workspaceRoot, name) diff --git a/pkg/agentic/queue.go b/pkg/agentic/queue.go index 882c147..dc3db1d 100644 --- a/pkg/agentic/queue.go +++ b/pkg/agentic/queue.go @@ -17,14 +17,14 @@ type DispatchConfig struct { WorkspaceRoot string `yaml:"workspace_root"` } -// rate := agentic.RateConfig{ResetUTC: "06:00", SustainedDelay: 120, BurstWindow: 2, BurstDelay: 15} +// rate := agentic.RateConfig{ResetUTC: "06:00", DailyLimit: 200, MinDelay: 15, SustainedDelay: 120, BurstWindow: 2, BurstDelay: 15} type RateConfig struct { - ResetUTC string `yaml:"reset_utc"` // Daily quota reset time (UTC), e.g. "06:00" - DailyLimit int `yaml:"daily_limit"` // Max requests per day (0 = unknown) - MinDelay int `yaml:"min_delay"` // Minimum seconds between task starts - SustainedDelay int `yaml:"sustained_delay"` // Delay when pacing for full-day use - BurstWindow int `yaml:"burst_window"` // Hours before reset where burst kicks in - BurstDelay int `yaml:"burst_delay"` // Delay during burst window + ResetUTC string `yaml:"reset_utc"` + DailyLimit int `yaml:"daily_limit"` + MinDelay int `yaml:"min_delay"` + SustainedDelay int `yaml:"sustained_delay"` + BurstWindow int `yaml:"burst_window"` + BurstDelay int `yaml:"burst_delay"` } // claude: 1 → Total=1, Models=nil @@ -240,12 +240,10 @@ func (s *PrepSubsystem) canDispatchAgent(agent string) bool { return true } - // Check pool total if s.countRunningByAgent(base) >= limit.Total { return false } - // Check per-model limit if configured if limit.Models != nil { model := modelVariant(agent) if model != "" { @@ -261,7 +259,7 @@ func (s *PrepSubsystem) canDispatchAgent(agent string) bool { } // model := modelVariant("codex:gpt-5.4") -// _ = model +// core.Println(model) // "gpt-5.4" func modelVariant(agent string) string { parts := core.SplitN(agent, ":", 2) if len(parts) < 2 { @@ -301,19 +299,16 @@ func (s *PrepSubsystem) drainOne() bool { continue } - // Skip if agent pool is in rate-limit backoff pool := baseAgent(workspaceStatus.Agent) if until, ok := s.backoff[pool]; ok && time.Now().Before(until) { continue } - // Apply rate delay before spawning delay := s.delayForAgent(workspaceStatus.Agent) if delay > 0 { time.Sleep(delay) } - // Re-check concurrency after delay (another task may have started) if !s.canDispatchAgent(workspaceStatus.Agent) { continue }