Skip to content

Commit 9849c78

Browse files
authored
Add SessionSharingConfig to AmbientAgentConfig (#53)
1 parent 5c06c15 commit 9849c78

3 files changed

Lines changed: 106 additions & 2 deletions

File tree

internal/common/task_utils.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,21 @@ func AugmentArgsForTask(task *types.Task, args []string, opts TaskAugmentOptions
6565
args = append(args, "--harness", harness)
6666
}
6767
}
68+
69+
// Pass public session-sharing if configured. This is additive to the
70+
// collaborator-oriented --share args already set by the worker launcher
71+
// (team:edit). The bundled Warp client applies an anyone-with-link ACL
72+
// after the session bootstraps; the workspace-level
73+
// AnyoneWithLinkSharingEnabled setting still gates whether the ACL
74+
// write succeeds. FULL is rejected at the public API layer, so we only
75+
// expect VIEWER or EDITOR here and silently skip unsupported values
76+
// as a defensive fallback.
77+
if task.AgentConfigSnapshot.SessionSharing != nil &&
78+
task.AgentConfigSnapshot.SessionSharing.PublicAccess != nil {
79+
if level := shareAccessLevelForEmission(*task.AgentConfigSnapshot.SessionSharing.PublicAccess); level != "" {
80+
args = append(args, "--share", fmt.Sprintf("public:%s", level))
81+
}
82+
}
6883
}
6984

7085
if task.AgentConfigSnapshot != nil && task.AgentConfigSnapshot.EnvironmentID != nil {
@@ -86,6 +101,21 @@ func AugmentArgsForTask(task *types.Task, args []string, opts TaskAugmentOptions
86101
return args
87102
}
88103

104+
// shareAccessLevelForEmission maps an internal AccessLevel to the string
105+
// accepted by the CLI's --share flag. Returns empty string for values that
106+
// the CLI cannot represent (e.g. FULL), in which case the caller should
107+
// omit the emission entirely.
108+
func shareAccessLevelForEmission(access types.AccessLevel) string {
109+
switch access {
110+
case types.AccessLevelViewer:
111+
return "view"
112+
case types.AccessLevelEditor:
113+
return "edit"
114+
default:
115+
return ""
116+
}
117+
}
118+
89119
func resolveIdleOnComplete(task *types.Task, opts TaskAugmentOptions) (string, bool) {
90120
if task != nil &&
91121
task.AgentConfigSnapshot != nil &&

internal/common/task_utils_test.go

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import (
77
"github.com/warpdotdev/oz-agent-worker/internal/types"
88
)
99

10-
func strPtr(v string) *string { return &v }
11-
func intPtr(v int) *int { return &v }
10+
func strPtr(v string) *string { return &v }
11+
func intPtr(v int) *int { return &v }
12+
func accessPtr(v types.AccessLevel) *types.AccessLevel { return &v }
1213

1314
func TestAugmentArgsForTask_IdleOnCompletePrecedence(t *testing.T) {
1415
baseArgs := []string{"agent", "run"}
@@ -86,6 +87,60 @@ func TestAugmentArgsForTask_IdleOnCompletePrecedence(t *testing.T) {
8687
opts: TaskAugmentOptions{},
8788
expected: []string{"agent", "run", "--model", "claude-sonnet-4", "--idle-on-complete", "12m"},
8889
},
90+
{
91+
name: "adds --share public:view when session_sharing.public_access is VIEWER",
92+
task: &types.Task{
93+
AgentConfigSnapshot: &types.AmbientAgentConfig{
94+
SessionSharing: &types.SessionSharingConfig{
95+
PublicAccess: accessPtr(types.AccessLevelViewer),
96+
},
97+
},
98+
},
99+
opts: TaskAugmentOptions{},
100+
expected: []string{"agent", "run", "--share", "public:view", "--idle-on-complete"},
101+
},
102+
{
103+
name: "adds --share public:edit when session_sharing.public_access is EDITOR",
104+
task: &types.Task{
105+
AgentConfigSnapshot: &types.AmbientAgentConfig{
106+
SessionSharing: &types.SessionSharingConfig{
107+
PublicAccess: accessPtr(types.AccessLevelEditor),
108+
},
109+
},
110+
},
111+
opts: TaskAugmentOptions{},
112+
expected: []string{"agent", "run", "--share", "public:edit", "--idle-on-complete"},
113+
},
114+
{
115+
name: "skips --share public when session_sharing is absent",
116+
task: &types.Task{
117+
AgentConfigSnapshot: &types.AmbientAgentConfig{},
118+
},
119+
opts: TaskAugmentOptions{},
120+
expected: []string{"agent", "run", "--idle-on-complete"},
121+
},
122+
{
123+
name: "skips --share public when public_access is nil",
124+
task: &types.Task{
125+
AgentConfigSnapshot: &types.AmbientAgentConfig{
126+
SessionSharing: &types.SessionSharingConfig{},
127+
},
128+
},
129+
opts: TaskAugmentOptions{},
130+
expected: []string{"agent", "run", "--idle-on-complete"},
131+
},
132+
{
133+
name: "silently omits --share public for unsupported access levels (defensive: FULL rejected earlier)",
134+
task: &types.Task{
135+
AgentConfigSnapshot: &types.AmbientAgentConfig{
136+
SessionSharing: &types.SessionSharingConfig{
137+
PublicAccess: accessPtr(types.AccessLevel("FULL")),
138+
},
139+
},
140+
},
141+
opts: TaskAugmentOptions{},
142+
expected: []string{"agent", "run", "--idle-on-complete"},
143+
},
89144
}
90145

91146
for _, tt := range tests {

internal/types/messages.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,24 @@ type HarnessAuthSecrets struct {
7878
ClaudeAuthSecretName *string `json:"claude_auth_secret_name,omitempty"`
7979
}
8080

81+
// AccessLevel is the serialized access-level string used inside SessionSharingConfig.
82+
// Values mirror warp-server's model/types/enums.AccessLevel JSON representation.
83+
type AccessLevel string
84+
85+
const (
86+
AccessLevelViewer AccessLevel = "VIEWER"
87+
AccessLevelEditor AccessLevel = "EDITOR"
88+
)
89+
90+
// SessionSharingConfig mirrors warp-server's sources.SessionSharingConfig and
91+
// carries the session-sharing choices snapshotted onto the run.
92+
type SessionSharingConfig struct {
93+
// PublicAccess, when set, causes the worker to emit --share public:<level>
94+
// so the bundled Warp client applies an anyone-with-link ACL after the
95+
// shared session bootstraps.
96+
PublicAccess *AccessLevel `json:"public_access,omitempty"`
97+
}
98+
8199
// AmbientAgentConfig represents the agent configuration.
82100
type AmbientAgentConfig struct {
83101
EnvironmentID *string `json:"environment_id,omitempty"`
@@ -90,6 +108,7 @@ type AmbientAgentConfig struct {
90108
IdleTimeoutMinutes *int `json:"idle_timeout_minutes,omitempty"`
91109
Harness *Harness `json:"harness,omitempty"`
92110
HarnessAuthSecrets *HarnessAuthSecrets `json:"harness_auth_secrets,omitempty"`
111+
SessionSharing *SessionSharingConfig `json:"session_sharing,omitempty"`
93112
}
94113

95114
// Task represents an ambient agent job.

0 commit comments

Comments
 (0)