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:
parent
9c6f10902e
commit
e8862e26be
3 changed files with 102 additions and 4 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"core": {
|
||||
"agent": {
|
||||
"type": "stdio",
|
||||
"command": "core-agent",
|
||||
"args": ["mcp"],
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue