fix: forward project permissions to agent launches (#198)
This commit is contained in:
parent
d432738b1c
commit
295cda5787
|
|
@ -216,13 +216,15 @@ func (m *Manager) Spawn(ctx context.Context, cfg ports.SpawnConfig) (domain.Sess
|
||||||
m.markSpawnFailedTerminated(ctx, id)
|
m.markSpawnFailedTerminated(ctx, id)
|
||||||
return domain.SessionRecord{}, fmt.Errorf("spawn %s: %w", id, err)
|
return domain.SessionRecord{}, fmt.Errorf("spawn %s: %w", id, err)
|
||||||
}
|
}
|
||||||
|
agentConfig := effectiveAgentConfig(cfg.Kind, project.Config)
|
||||||
argv, err := agent.GetLaunchCommand(ctx, ports.LaunchConfig{
|
argv, err := agent.GetLaunchCommand(ctx, ports.LaunchConfig{
|
||||||
SessionID: string(id),
|
SessionID: string(id),
|
||||||
WorkspacePath: ws.Path,
|
WorkspacePath: ws.Path,
|
||||||
Prompt: prompt,
|
Prompt: prompt,
|
||||||
SystemPrompt: systemPrompt,
|
SystemPrompt: systemPrompt,
|
||||||
IssueID: string(cfg.IssueID),
|
IssueID: string(cfg.IssueID),
|
||||||
Config: effectiveAgentConfig(cfg.Kind, project.Config),
|
Config: agentConfig,
|
||||||
|
Permissions: agentConfig.Permissions,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = m.workspace.Destroy(ctx, ws)
|
_ = m.workspace.Destroy(ctx, ws)
|
||||||
|
|
@ -823,7 +825,7 @@ func restoreArgv(ctx context.Context, agent ports.Agent, id domain.SessionID, wo
|
||||||
WorkspacePath: workspacePath,
|
WorkspacePath: workspacePath,
|
||||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: meta.AgentSessionID},
|
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: meta.AgentSessionID},
|
||||||
}
|
}
|
||||||
cmd, ok, err := agent.GetRestoreCommand(ctx, ports.RestoreConfig{Session: ref, Config: agentConfig})
|
cmd, ok, err := agent.GetRestoreCommand(ctx, ports.RestoreConfig{Session: ref, Config: agentConfig, Permissions: agentConfig.Permissions})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("restore command: %w", err)
|
return nil, fmt.Errorf("restore command: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -835,6 +837,7 @@ func restoreArgv(ctx context.Context, agent ports.Agent, id domain.SessionID, wo
|
||||||
WorkspacePath: workspacePath,
|
WorkspacePath: workspacePath,
|
||||||
Prompt: meta.Prompt,
|
Prompt: meta.Prompt,
|
||||||
Config: agentConfig,
|
Config: agentConfig,
|
||||||
|
Permissions: agentConfig.Permissions,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("launch command: %w", err)
|
return nil, fmt.Errorf("launch command: %w", err)
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,9 @@ func (fakeAgents) Agent(domain.AgentHarness) (ports.Agent, bool) { return fakeAg
|
||||||
// session manager resolved and forwarded a project's agent config.
|
// session manager resolved and forwarded a project's agent config.
|
||||||
type recordingAgent struct {
|
type recordingAgent struct {
|
||||||
fakeAgent
|
fakeAgent
|
||||||
lastConfig ports.AgentConfig
|
lastConfig ports.AgentConfig
|
||||||
lastLaunch ports.LaunchConfig
|
lastLaunch ports.LaunchConfig
|
||||||
|
lastRestore ports.RestoreConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *recordingAgent) GetLaunchCommand(_ context.Context, cfg ports.LaunchConfig) ([]string, error) {
|
func (a *recordingAgent) GetLaunchCommand(_ context.Context, cfg ports.LaunchConfig) ([]string, error) {
|
||||||
|
|
@ -166,6 +167,7 @@ func (a *recordingAgent) GetLaunchCommand(_ context.Context, cfg ports.LaunchCon
|
||||||
|
|
||||||
func (a *recordingAgent) GetRestoreCommand(_ context.Context, cfg ports.RestoreConfig) ([]string, bool, error) {
|
func (a *recordingAgent) GetRestoreCommand(_ context.Context, cfg ports.RestoreConfig) ([]string, bool, error) {
|
||||||
a.lastConfig = cfg.Config
|
a.lastConfig = cfg.Config
|
||||||
|
a.lastRestore = cfg
|
||||||
return []string{"resume"}, true, nil
|
return []string{"resume"}, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -497,6 +499,57 @@ func TestSpawn_DefaultsBranchFromSessionID(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSpawn_ForwardsResolvedAgentConfigPermissions(t *testing.T) {
|
||||||
|
st := newFakeStore()
|
||||||
|
st.projects["mer"] = domain.ProjectRecord{ID: "mer", Config: domain.ProjectConfig{
|
||||||
|
AgentConfig: domain.AgentConfig{Permissions: domain.PermissionModeAuto},
|
||||||
|
Worker: domain.RoleOverride{AgentConfig: domain.AgentConfig{Permissions: domain.PermissionModeBypassPermissions}},
|
||||||
|
}}
|
||||||
|
agent := &recordingAgent{}
|
||||||
|
lookPath := func(string) (string, error) { return "/bin/true", nil }
|
||||||
|
m := New(Deps{Runtime: &fakeRuntime{}, Agents: singleAgent{agent: agent}, Workspace: &fakeWorkspace{}, Store: st, Messenger: &fakeMessenger{}, Lifecycle: &fakeLCM{store: st}, LookPath: lookPath})
|
||||||
|
|
||||||
|
_, err := m.Spawn(ctx, ports.SpawnConfig{ProjectID: "mer", Kind: domain.KindWorker})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if agent.lastLaunch.Config.Permissions != domain.PermissionModeBypassPermissions {
|
||||||
|
t.Fatalf("launch config permissions = %q, want bypass", agent.lastLaunch.Config.Permissions)
|
||||||
|
}
|
||||||
|
if agent.lastLaunch.Permissions != domain.PermissionModeBypassPermissions {
|
||||||
|
t.Fatalf("launch permissions = %q, want bypass", agent.lastLaunch.Permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRestore_ForwardsResolvedAgentConfigPermissions(t *testing.T) {
|
||||||
|
st := newFakeStore()
|
||||||
|
st.projects["mer"] = domain.ProjectRecord{ID: "mer", Config: domain.ProjectConfig{
|
||||||
|
AgentConfig: domain.AgentConfig{Permissions: domain.PermissionModeBypassPermissions},
|
||||||
|
}}
|
||||||
|
st.sessions["mer-1"] = domain.SessionRecord{
|
||||||
|
ID: "mer-1",
|
||||||
|
ProjectID: "mer",
|
||||||
|
Kind: domain.KindWorker,
|
||||||
|
IsTerminated: true,
|
||||||
|
Metadata: domain.SessionMetadata{Branch: "ao/mer-1", WorkspacePath: "/tmp/ws", AgentSessionID: "native-1"},
|
||||||
|
}
|
||||||
|
agent := &recordingAgent{}
|
||||||
|
m := New(Deps{Runtime: &fakeRuntime{}, Agents: singleAgent{agent: agent}, Workspace: &fakeWorkspace{}, Store: st, Messenger: &fakeMessenger{}, Lifecycle: &fakeLCM{store: st}, LookPath: func(string) (string, error) { return "/bin/true", nil }})
|
||||||
|
|
||||||
|
_, err := m.Restore(ctx, "mer-1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if agent.lastRestore.Config.Permissions != domain.PermissionModeBypassPermissions {
|
||||||
|
t.Fatalf("restore config permissions = %q, want bypass", agent.lastRestore.Config.Permissions)
|
||||||
|
}
|
||||||
|
if agent.lastRestore.Permissions != domain.PermissionModeBypassPermissions {
|
||||||
|
t.Fatalf("restore permissions = %q, want bypass", agent.lastRestore.Permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSpawnWorker_AppendsActiveOrchestratorContact(t *testing.T) {
|
func TestSpawnWorker_AppendsActiveOrchestratorContact(t *testing.T) {
|
||||||
st := newFakeStore()
|
st := newFakeStore()
|
||||||
st.num = 1
|
st.num = 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue