fix: make Nomos actually provision LXCs from chat (pct_create + web fetch)
Root cause of "asks permission but never acts": the approved pct_create execution failed to parse because the LLM emitted `"privileged":0` / `"nesting":1` (numbers) into strict `bool` fields, so the container was never created. Compounded by a hardcoded template name (debian-13.0-1) that no longer exists on the host, and no way for the agent to read the web. - flexBool: accept 0/1, "true", bool for privileged/nesting (the exact prod failure) - pct_create template pre-flight: list host cache, validate/auto-pick newest debian - pct_create services[] + post_install: one approval provisions a working service - new http_get MCP tool (sanitized, size-capped, SSRF-guarded) — agent can read repos/sites - request_execution description: target=host, full JSON schema + example - SOUL.md: agent CAN fetch the web; prefer one-step provisioning - default model deepseek-v4-flash -> v4-pro; maxIterations 15 -> 25 - unit tests for flexBool, template resolve, pkg sanitize, HTML sanitize + SSRF block Verified live on host:strong with a throwaway VMID 999: template auto-resolved, container created + booted, services installed, post_install ran, then destroyed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,10 @@ import (
|
||||
"github.com/openai/openai-go/shared"
|
||||
)
|
||||
|
||||
const maxIterations = 15
|
||||
// maxIterations bounds one chat turn's tool-calling loop. Provisioning a
|
||||
// service is a long chain (research → plan → request_execution → status), so
|
||||
// 15 was too tight and turns died with "max iterations reached" mid-deploy.
|
||||
const maxIterations = 25
|
||||
const maxLLMRetries = 1
|
||||
|
||||
var refusalDenylist = []string{
|
||||
@@ -41,7 +44,10 @@ func newAgent(ctx context.Context, mcpClient *mcpClient, st *store, agentSlug st
|
||||
apiKey := os.Getenv("OPENROUTER_API_KEY")
|
||||
model := os.Getenv("NOMOS_MODEL")
|
||||
if model == "" {
|
||||
model = "deepseek/deepseek-v4-flash"
|
||||
// v4-pro over v4-flash: the flash tier over-narrates, occasionally
|
||||
// emits canned refusals, and is unreliable at multi-step tool use —
|
||||
// exactly the agentic provisioning path the operator needs to work.
|
||||
model = "deepseek/deepseek-v4-pro"
|
||||
}
|
||||
|
||||
provider := openai.NewClient(
|
||||
|
||||
Reference in New Issue
Block a user