feat(dispatch): LEM profiles + native Claude agents

- Add isLEMProfile(): codex:lemmy/lemer/lemma/lemrd use --profile not --model
- Add isNativeAgent(): Claude agents run natively (not in Docker)
- Update localAgentCommandScript for LEM profile support
- 12 new tests (Good/Bad/Ugly for profiles, native agent, codex variants)

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-04-08 17:17:33 +01:00
parent 9c6f10902e
commit e8862e26be
3 changed files with 102 additions and 4 deletions

View file

@ -1,6 +1,6 @@
{
"mcpServers": {
"core": {
"agent": {
"type": "stdio",
"command": "core-agent",
"args": ["mcp"],

View file

@ -105,7 +105,11 @@ func agentCommandResult(agent, prompt string) core.Result {
"-o", "../.meta/agent-codex.log",
}
if model != "" {
args = append(args, "--model", model)
if isLEMProfile(model) {
args = append(args, "--profile", model)
} else {
args = append(args, "--model", model)
}
}
args = append(args, prompt)
return core.Result{Value: agentCommandResultValue{command: "codex", args: args}, OK: true}
@ -142,11 +146,41 @@ func agentCommandResult(agent, prompt string) core.Result {
}
}
// isNativeAgent returns true if the agent should run natively (not in Docker).
// Claude agents need direct filesystem access, MCP tools, and native binary execution.
//
// isNativeAgent("claude") // true
// isNativeAgent("claude:opus") // true
// isNativeAgent("codex") // false (runs in Docker)
func isNativeAgent(agent string) bool {
parts := core.SplitN(agent, ":", 2)
return parts[0] == "claude"
}
// isLEMProfile returns true if the model name is a known LEM profile
// (lemer, lemma, lemmy, lemrd) configured in codex config.toml.
//
// isLEMProfile("lemmy") // true
// isLEMProfile("gpt-5.4") // false
func isLEMProfile(model string) bool {
switch model {
case "lemer", "lemma", "lemmy", "lemrd":
return true
default:
return false
}
}
// localAgentCommandScript("devstral-24b", "Review the last 2 commits")
func localAgentCommandScript(model, prompt string) string {
builder := core.NewBuilder()
builder.WriteString("socat TCP-LISTEN:11434,fork,reuseaddr TCP:host.docker.internal:11434 & sleep 0.5")
builder.WriteString(" && codex exec --dangerously-bypass-approvals-and-sandbox --oss --local-provider ollama -m ")
builder.WriteString(" && codex exec --dangerously-bypass-approvals-and-sandbox")
if isLEMProfile(model) {
builder.WriteString(" --profile ")
} else {
builder.WriteString(" --oss --local-provider ollama -m ")
}
builder.WriteString(shellQuote(model))
builder.WriteString(" -o ../.meta/agent-codex.log ")
builder.WriteString(shellQuote(prompt))
@ -373,7 +407,9 @@ func (s *PrepSubsystem) spawnAgent(agent, prompt, workspaceDir string) (int, str
fs.Delete(WorkspaceBlockedPath(workspaceDir))
command, args = containerCommand(command, args, workspaceDir, metaDir)
if !isNativeAgent(agent) {
command, args = containerCommand(command, args, workspaceDir, metaDir)
}
processResult := s.Core().Service("process")
if !processResult.OK {

View file

@ -106,6 +106,68 @@ func TestDispatch_LocalAgentCommandScript_Good_ShellQuoting(t *testing.T) {
assert.Contains(t, script, "'can'\\''t break quoting'")
}
func TestDispatch_AgentCommand_Good_CodexLEMProfile(t *testing.T) {
cmd, args, err := agentCommand("codex:lemmy", "implement the scorer")
require.NoError(t, err)
assert.Equal(t, "codex", cmd)
assert.Contains(t, args, "--profile")
assert.Contains(t, args, "lemmy")
assert.NotContains(t, args, "--model")
}
func TestDispatch_AgentCommand_Good_CodexLemer(t *testing.T) {
cmd, args, err := agentCommand("codex:lemer", "add docs")
require.NoError(t, err)
assert.Equal(t, "codex", cmd)
assert.Contains(t, args, "--profile")
assert.Contains(t, args, "lemer")
}
func TestDispatch_AgentCommand_Good_CodexLemrd(t *testing.T) {
cmd, args, err := agentCommand("codex:lemrd", "review code")
require.NoError(t, err)
assert.Equal(t, "codex", cmd)
assert.Contains(t, args, "--profile")
assert.Contains(t, args, "lemrd")
}
func TestDispatch_IsLEMProfile_Good(t *testing.T) {
assert.True(t, isLEMProfile("lemer"))
assert.True(t, isLEMProfile("lemma"))
assert.True(t, isLEMProfile("lemmy"))
assert.True(t, isLEMProfile("lemrd"))
}
func TestDispatch_IsLEMProfile_Bad(t *testing.T) {
assert.False(t, isLEMProfile("gpt-5.4"))
assert.False(t, isLEMProfile("gemini-2.5-flash"))
assert.False(t, isLEMProfile(""))
}
func TestDispatch_IsLEMProfile_Ugly(t *testing.T) {
assert.False(t, isLEMProfile("Lemmy"))
assert.False(t, isLEMProfile("LEMRD"))
assert.False(t, isLEMProfile("lem"))
}
func TestDispatch_IsNativeAgent_Good(t *testing.T) {
assert.True(t, isNativeAgent("claude"))
assert.True(t, isNativeAgent("claude:opus"))
assert.True(t, isNativeAgent("claude:haiku"))
}
func TestDispatch_IsNativeAgent_Bad(t *testing.T) {
assert.False(t, isNativeAgent("codex"))
assert.False(t, isNativeAgent("codex:gpt-5.4"))
assert.False(t, isNativeAgent("gemini"))
}
func TestDispatch_IsNativeAgent_Ugly(t *testing.T) {
assert.False(t, isNativeAgent(""))
assert.False(t, isNativeAgent("codex:lemmy"))
assert.False(t, isNativeAgent("local:mistral"))
}
func TestDispatch_AgentCommand_Bad_Unknown(t *testing.T) {
cmd, args, err := agentCommand("robot-from-the-future", "take over")
assert.Error(t, err)