v0.12.2 1adbe2f

model.go RawHistoryFolder

1package subagents
2
3import "time"
4
5// WebSearchPolicy is the capability decision propagated from a host agent to
6// a subagent worker. Inherit is used only before a supervisor resolves the
7// child decision; persisted and launched workers use Allow or Deny so their
8// capability does not change with a later config edit.
9type WebSearchPolicy uint8
10
11const (
12	WebSearchInherit WebSearchPolicy = iota
13	WebSearchDeny
14	WebSearchAllow
15)
16
17func (p WebSearchPolicy) Allows() bool { return p == WebSearchAllow }
18
19// childPolicy turns an unresolved or corrupt policy into an explicit deny.
20// Inherit is useful while a supervisor is resolving a spawn request, but it
21// must never cross the worker boundary because the child may otherwise apply
22// its own default-enabled configuration.
23func (p WebSearchPolicy) childPolicy() WebSearchPolicy {
24	if p == WebSearchAllow {
25		return WebSearchAllow
26	}
27	return WebSearchDeny
28}
29
30func (p WebSearchPolicy) String() string {
31	switch p {
32	case WebSearchAllow:
33		return "allow"
34	case WebSearchDeny:
35		return "deny"
36	case WebSearchInherit:
37		return "inherit"
38	default:
39		// Unknown values must not serialize as inherit: that would let a
40		// worker fall back to its own default and potentially regain access.
41		return "deny"
42	}
43}
44
45func childWebSearchPolicy(policy WebSearchPolicy, subagent string, toolNames []string) WebSearchPolicy {
46	if subagent != "" && NamedWebSearchPolicy(toolNames) != WebSearchAllow {
47		return WebSearchDeny
48	}
49	return policy.childPolicy()
50}
51
52// NamedWebSearchPolicy requires a named profile to opt in explicitly. An
53// omitted or empty profile tools list therefore denies web search without
54// changing the default selection of the other built-in tools.
55func NamedWebSearchPolicy(toolNames []string) WebSearchPolicy {
56	for _, name := range toolNames {
57		if name == "web_search" {
58			return WebSearchAllow
59		}
60	}
61	return WebSearchDeny
62}
63
64// ProcessState describes the lifetime of the supervised child process. It is
65// intentionally independent from TurnState: an alive worker can be idle
66// between turns, and a disconnected supervisor does not imply that the
67// worker's current turn failed.
68type ProcessState string
69
70const (
71	ProcessPending  ProcessState = "pending"
72	ProcessStarting ProcessState = "starting"
73	ProcessAlive    ProcessState = "alive"
74	ProcessDetached ProcessState = "detached"
75	ProcessExited   ProcessState = "exited"
76	ProcessKilled   ProcessState = "killed"
77)
78
79// TurnState describes one delegated prompt inside a worker process.
80type TurnState string
81
82const (
83	TurnIdle      TurnState = "idle"
84	TurnQueued    TurnState = "queued"
85	TurnRunning   TurnState = "running"
86	TurnCanceling TurnState = "canceling"
87	TurnSucceeded TurnState = "succeeded"
88	TurnFailed    TurnState = "failed"
89	TurnCanceled  TurnState = "canceled"
90)
91
92// WorkspaceMode selects how a child is allowed to access the repository.
93type WorkspaceMode string
94
95const (
96	WorkspaceShared   WorkspaceMode = "shared"
97	WorkspaceWorktree WorkspaceMode = "worktree"
98)
99
100// CaptureMode controls which durable worktree output is collected.
101type CaptureMode string
102
103const (
104	CapturePatch CaptureMode = "patch"
105	CaptureDiff  CaptureMode = "diff"
106)
107
108// SubagentPolicy contains manager-owned safety and resource limits. normalize
109// replaces zero MaxOutputBytes, MaxOutputLines, QueueTimeout, and
110// DefaultTimeout values with positive manager defaults. Other zero values retain
111// their documented semantics.
112type SubagentPolicy struct {
113	MaxConcurrent          int
114	MaxConcurrentPerParent int
115	QueueTimeout           time.Duration
116	DefaultTimeout         time.Duration
117	MaxTurns               int
118	MaxOutputBytes         int
119	MaxOutputLines         int
120	AllowedTools           []string
121	AllowedRoots           []string
122	HeartbeatInterval      time.Duration
123	IdleTimeout            time.Duration
124	ReconnectTimeout       time.Duration
125	CancelGracePeriod      time.Duration
126}
127
128func (p *SubagentPolicy) normalize() {
129	if p.MaxConcurrent <= 0 {
130		p.MaxConcurrent = 8
131	}
132	if p.MaxConcurrentPerParent <= 0 {
133		p.MaxConcurrentPerParent = 4
134	}
135	if p.QueueTimeout <= 0 {
136		p.QueueTimeout = 30 * time.Minute
137	}
138	if p.DefaultTimeout <= 0 {
139		p.DefaultTimeout = 20 * time.Minute
140	}
141	if p.MaxTurns <= 0 {
142		p.MaxTurns = 3
143	}
144	if p.MaxOutputBytes <= 0 {
145		p.MaxOutputBytes = 500_000
146	}
147	if p.MaxOutputLines <= 0 {
148		p.MaxOutputLines = 5_000
149	}
150	if p.HeartbeatInterval <= 0 {
151		p.HeartbeatInterval = 10 * time.Second
152	}
153	if p.IdleTimeout <= 0 {
154		p.IdleTimeout = 7 * time.Minute
155	}
156	if p.ReconnectTimeout <= 0 {
157		p.ReconnectTimeout = 5 * time.Second
158	}
159	if p.CancelGracePeriod <= 0 {
160		p.CancelGracePeriod = 10 * time.Second
161	}
162}
163
164func (p SubagentPolicy) allowedTool(name string) bool {
165	if len(p.AllowedTools) == 0 {
166		return true
167	}
168	for _, allowed := range p.AllowedTools {
169		if allowed == name {
170			return true
171		}
172	}
173	return false
174}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close