blun-king-cli 9.1.466 → 9.1.468
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/agent-api-http-adapter.mjs +318 -0
- package/bin/agent-api-runtime.mjs +11 -11
- package/bin/subagent-tool-policy.cjs +60 -0
- package/blun.mjs +4 -1
- package/package.json +1 -1
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
const AGENT_TURNS_PATH = '/v1/agent/turns';
|
|
2
|
+
const PUBLIC_MODEL_ID = 'king';
|
|
3
|
+
const PUBLIC_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/u;
|
|
4
|
+
|
|
5
|
+
class AgentApiHttpAdapterError extends Error {
|
|
6
|
+
constructor(code, message, status = 400) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'AgentApiHttpAdapterError';
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.status = status;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function adapterError(code, message, status = 400) {
|
|
15
|
+
return new AgentApiHttpAdapterError(code, message, status);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function requireTrustedId(value, label) {
|
|
19
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
20
|
+
throw adapterError('AGENT_API_UNAUTHENTICATED', `${label} is required`, 401);
|
|
21
|
+
}
|
|
22
|
+
return value.trim();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function requirePublicId(value, label) {
|
|
26
|
+
if (typeof value !== 'string' || !PUBLIC_ID_PATTERN.test(value)) {
|
|
27
|
+
throw adapterError(
|
|
28
|
+
'AGENT_API_INVALID_ID',
|
|
29
|
+
`${label} must match ${PUBLIC_ID_PATTERN}`,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function requireBody(value) {
|
|
36
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
37
|
+
throw adapterError('AGENT_API_INVALID_BODY', 'request body must be a JSON object');
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function requireKing(value) {
|
|
43
|
+
if (value !== PUBLIC_MODEL_ID) {
|
|
44
|
+
throw adapterError('AGENT_API_INVALID_MODEL', 'model must be king');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function normalizePrompt(value) {
|
|
49
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
50
|
+
throw adapterError('AGENT_API_INVALID_INPUT', 'input must be a non-empty string');
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function normalizeTools(value) {
|
|
56
|
+
if (value === undefined) return [];
|
|
57
|
+
if (!Array.isArray(value)) {
|
|
58
|
+
throw adapterError('AGENT_API_INVALID_TOOLS', 'tools must be an array');
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function decodeRequestId(value) {
|
|
64
|
+
let decoded;
|
|
65
|
+
try {
|
|
66
|
+
decoded = decodeURIComponent(value);
|
|
67
|
+
} catch {
|
|
68
|
+
throw adapterError('AGENT_API_INVALID_ID', 'request ID is not valid URL encoding');
|
|
69
|
+
}
|
|
70
|
+
return requirePublicId(decoded, 'request ID');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function routeFor(method, rawPath) {
|
|
74
|
+
const path = String(rawPath ?? '').split('?', 1)[0];
|
|
75
|
+
if (method === 'POST' && path === AGENT_TURNS_PATH) return { kind: 'start' };
|
|
76
|
+
if (!path.startsWith(`${AGENT_TURNS_PATH}/`)) {
|
|
77
|
+
if (path.startsWith('/v1/agent/')) return { kind: 'unknown' };
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const tail = path.slice(AGENT_TURNS_PATH.length + 1);
|
|
82
|
+
const toolSuffix = '/tool-results';
|
|
83
|
+
if (method === 'POST' && tail.endsWith(toolSuffix)) {
|
|
84
|
+
return {
|
|
85
|
+
kind: 'continue',
|
|
86
|
+
requestId: decodeRequestId(tail.slice(0, -toolSuffix.length)),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (method === 'DELETE' && !tail.includes('/')) {
|
|
90
|
+
return { kind: 'cancel', requestId: decodeRequestId(tail) };
|
|
91
|
+
}
|
|
92
|
+
return { kind: 'unknown' };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function jsonResponse(status, body) {
|
|
96
|
+
return {
|
|
97
|
+
status,
|
|
98
|
+
headers: { 'content-type': 'application/json' },
|
|
99
|
+
body,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function publicCompletion(response) {
|
|
104
|
+
if (response === null || typeof response !== 'object' || Array.isArray(response)) {
|
|
105
|
+
throw adapterError('AGENT_API_INVALID_CONTROLLER_RESPONSE', 'Agent response is invalid', 502);
|
|
106
|
+
}
|
|
107
|
+
return { ...response, model: PUBLIC_MODEL_ID };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function publicErrorResponse(error) {
|
|
111
|
+
if (error instanceof AgentApiHttpAdapterError) {
|
|
112
|
+
return jsonResponse(error.status, {
|
|
113
|
+
error: {
|
|
114
|
+
type: 'invalid_request_error',
|
|
115
|
+
code: error.code,
|
|
116
|
+
message: error.message,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const code = typeof error?.code === 'string' ? error.code : '';
|
|
122
|
+
if (code === 'AGENT_API_TURN_SCOPE_MISMATCH') {
|
|
123
|
+
return jsonResponse(403, {
|
|
124
|
+
error: {
|
|
125
|
+
type: 'permission_error',
|
|
126
|
+
code,
|
|
127
|
+
message: 'Agent turn belongs to a different request.',
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (code === 'AGENT_API_SESSION_BUSY' || code === 'AGENT_API_TURN_NOT_ACTIVE') {
|
|
132
|
+
return jsonResponse(409, {
|
|
133
|
+
error: {
|
|
134
|
+
type: 'conflict_error',
|
|
135
|
+
code,
|
|
136
|
+
message: 'Agent session is not ready for this operation.',
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (code.startsWith('AGENT_API_INVALID_')) {
|
|
141
|
+
return jsonResponse(400, {
|
|
142
|
+
error: {
|
|
143
|
+
type: 'invalid_request_error',
|
|
144
|
+
code,
|
|
145
|
+
message: 'Agent request is invalid.',
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (code === 'AGENT_API_TURN_FAILED') {
|
|
150
|
+
return jsonResponse(502, {
|
|
151
|
+
error: {
|
|
152
|
+
type: 'upstream_error',
|
|
153
|
+
code,
|
|
154
|
+
message: 'Agent turn failed.',
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return jsonResponse(500, {
|
|
159
|
+
error: {
|
|
160
|
+
type: 'internal_error',
|
|
161
|
+
code: 'AGENT_API_INTERNAL',
|
|
162
|
+
message: 'Agent request failed.',
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function scopeKey(sessionId, requestId) {
|
|
168
|
+
return `${sessionId}\0${requestId}`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function responseNeedsToolResult(response) {
|
|
172
|
+
return response?.choices?.[0]?.finish_reason === 'tool_calls';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function validateController(controller) {
|
|
176
|
+
if (controller === null || typeof controller !== 'object') {
|
|
177
|
+
throw new TypeError('controller is required');
|
|
178
|
+
}
|
|
179
|
+
for (const method of ['startTurn', 'continueTurn', 'cancelTurn']) {
|
|
180
|
+
if (typeof controller[method] !== 'function') {
|
|
181
|
+
throw new TypeError(`controller.${method} must be a function`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return controller;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function createAgentApiHttpAdapter(options = {}) {
|
|
188
|
+
const controller = validateController(options.controller);
|
|
189
|
+
if (typeof options.resolveSession !== 'function') {
|
|
190
|
+
throw new TypeError('resolveSession must be a function');
|
|
191
|
+
}
|
|
192
|
+
const owners = new Map();
|
|
193
|
+
|
|
194
|
+
function requireOwner(principalId, sessionId, requestId) {
|
|
195
|
+
const key = scopeKey(sessionId, requestId);
|
|
196
|
+
const owner = owners.get(key);
|
|
197
|
+
if (owner === undefined) {
|
|
198
|
+
throw adapterError(
|
|
199
|
+
'AGENT_API_TURN_NOT_ACTIVE',
|
|
200
|
+
'Agent turn is not active.',
|
|
201
|
+
409,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
if (owner !== principalId) {
|
|
205
|
+
throw adapterError(
|
|
206
|
+
'AGENT_API_FORBIDDEN',
|
|
207
|
+
'Agent turn belongs to a different account.',
|
|
208
|
+
403,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return key;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function trackScope(key, principalId, response) {
|
|
215
|
+
if (responseNeedsToolResult(response)) owners.set(key, principalId);
|
|
216
|
+
else owners.delete(key);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async function handleStart(input, principalId) {
|
|
220
|
+
const body = requireBody(input.body);
|
|
221
|
+
requireKing(body.model);
|
|
222
|
+
if (body.stream === true) {
|
|
223
|
+
throw adapterError(
|
|
224
|
+
'AGENT_API_STREAMING_UNSUPPORTED',
|
|
225
|
+
'streaming is not available on Agent turns yet',
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
const sessionId = requirePublicId(body.session_id, 'session_id');
|
|
229
|
+
const requestId = requirePublicId(body.request_id, 'request_id');
|
|
230
|
+
const session = await options.resolveSession({
|
|
231
|
+
principalId,
|
|
232
|
+
sessionId,
|
|
233
|
+
create: true,
|
|
234
|
+
});
|
|
235
|
+
if (session?.id !== sessionId) {
|
|
236
|
+
throw adapterError(
|
|
237
|
+
'AGENT_API_SESSION_SCOPE_MISMATCH',
|
|
238
|
+
'resolved session does not match session_id',
|
|
239
|
+
403,
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
const response = publicCompletion(await controller.startTurn({
|
|
243
|
+
session,
|
|
244
|
+
requestId,
|
|
245
|
+
prompt: normalizePrompt(body.input),
|
|
246
|
+
tools: normalizeTools(body.tools),
|
|
247
|
+
}));
|
|
248
|
+
trackScope(scopeKey(sessionId, requestId), principalId, response);
|
|
249
|
+
return jsonResponse(200, response);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async function handleContinue(input, principalId, requestId) {
|
|
253
|
+
const body = requireBody(input.body);
|
|
254
|
+
const sessionId = requirePublicId(body.session_id, 'session_id');
|
|
255
|
+
const key = requireOwner(principalId, sessionId, requestId);
|
|
256
|
+
const response = publicCompletion(await controller.continueTurn({
|
|
257
|
+
sessionId,
|
|
258
|
+
requestId,
|
|
259
|
+
toolResults: body.tool_results,
|
|
260
|
+
}));
|
|
261
|
+
trackScope(key, principalId, response);
|
|
262
|
+
return jsonResponse(200, response);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async function handleCancel(input, principalId, requestId) {
|
|
266
|
+
const body = requireBody(input.body ?? {});
|
|
267
|
+
const sessionId = requirePublicId(body.session_id, 'session_id');
|
|
268
|
+
const key = requireOwner(principalId, sessionId, requestId);
|
|
269
|
+
await controller.cancelTurn({
|
|
270
|
+
sessionId,
|
|
271
|
+
requestId,
|
|
272
|
+
reason: typeof body.reason === 'string' ? body.reason : undefined,
|
|
273
|
+
});
|
|
274
|
+
owners.delete(key);
|
|
275
|
+
return jsonResponse(200, {
|
|
276
|
+
id: `agent-${requestId}`,
|
|
277
|
+
object: 'agent.turn.cancelled',
|
|
278
|
+
model: PUBLIC_MODEL_ID,
|
|
279
|
+
cancelled: true,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async function handleRequest(input) {
|
|
284
|
+
if (input === null || typeof input !== 'object') return null;
|
|
285
|
+
const method = String(input.method ?? '').toUpperCase();
|
|
286
|
+
let route;
|
|
287
|
+
try {
|
|
288
|
+
route = routeFor(method, input.path);
|
|
289
|
+
if (route === null) return null;
|
|
290
|
+
if (route.kind === 'unknown') {
|
|
291
|
+
return jsonResponse(404, {
|
|
292
|
+
error: {
|
|
293
|
+
type: 'invalid_request_error',
|
|
294
|
+
code: 'AGENT_API_ROUTE_NOT_FOUND',
|
|
295
|
+
message: 'Agent API route not found.',
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
const principalId = requireTrustedId(input.principalId, 'principalId');
|
|
300
|
+
if (route.kind === 'start') return await handleStart(input, principalId);
|
|
301
|
+
if (route.kind === 'continue') {
|
|
302
|
+
return await handleContinue(input, principalId, route.requestId);
|
|
303
|
+
}
|
|
304
|
+
return await handleCancel(input, principalId, route.requestId);
|
|
305
|
+
} catch (error) {
|
|
306
|
+
return publicErrorResponse(error);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return Object.freeze({ handleRequest });
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export {
|
|
314
|
+
AGENT_TURNS_PATH,
|
|
315
|
+
AgentApiHttpAdapterError,
|
|
316
|
+
PUBLIC_MODEL_ID,
|
|
317
|
+
createAgentApiHttpAdapter,
|
|
318
|
+
};
|
|
@@ -6,7 +6,12 @@ const { createAgentApiToolBroker } = require('./agent-api-tool-broker.cjs');
|
|
|
6
6
|
|
|
7
7
|
const CLIENT_TOOL_NAME_PATTERN = /^[A-Za-z0-9_-]{1,64}$/u;
|
|
8
8
|
const INTERNAL_TOOL_PREFIX = 'client__';
|
|
9
|
-
const
|
|
9
|
+
const AGENT_API_INTERNAL_TOOLS = Object.freeze([
|
|
10
|
+
'Agent',
|
|
11
|
+
'TaskList',
|
|
12
|
+
'TaskOutput',
|
|
13
|
+
'TaskStop',
|
|
14
|
+
]);
|
|
10
15
|
|
|
11
16
|
class AgentApiRuntimeError extends Error {
|
|
12
17
|
constructor(code, message) {
|
|
@@ -112,10 +117,6 @@ function internalToolName(publicName, index) {
|
|
|
112
117
|
return `${prefix}${publicName.slice(0, available)}${suffix}`;
|
|
113
118
|
}
|
|
114
119
|
|
|
115
|
-
function noClientToolsSentinel(sessionId, requestId) {
|
|
116
|
-
return `${NO_CLIENT_TOOLS_PREFIX}${shortHash(`${sessionId}\0${requestId}`, 16)}`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
120
|
function validateSession(session) {
|
|
120
121
|
if (session === null || typeof session !== 'object') {
|
|
121
122
|
throw runtimeError('AGENT_API_INVALID_SESSION', 'session must be an SDK session');
|
|
@@ -188,11 +189,10 @@ function createAgentApiRuntime(options = {}) {
|
|
|
188
189
|
registeredNames.push(tool.internalName);
|
|
189
190
|
}
|
|
190
191
|
|
|
191
|
-
await input.session.setAllowedTools(
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
);
|
|
192
|
+
await input.session.setAllowedTools([
|
|
193
|
+
...AGENT_API_INTERNAL_TOOLS,
|
|
194
|
+
...registeredNames,
|
|
195
|
+
]);
|
|
196
196
|
} catch (error) {
|
|
197
197
|
broker.abortRequest({
|
|
198
198
|
sessionId,
|
|
@@ -244,9 +244,9 @@ function createAgentApiRuntime(options = {}) {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
export {
|
|
247
|
+
AGENT_API_INTERNAL_TOOLS,
|
|
247
248
|
AgentApiRuntimeError,
|
|
248
249
|
CLIENT_TOOL_NAME_PATTERN,
|
|
249
|
-
NO_CLIENT_TOOLS_PREFIX,
|
|
250
250
|
createAgentApiRuntime,
|
|
251
251
|
normalizeClientToolDefinitions,
|
|
252
252
|
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const NESTED_AGENT_LIFECYCLE_TOOLS = Object.freeze([
|
|
4
|
+
'Agent',
|
|
5
|
+
'TaskList',
|
|
6
|
+
'TaskOutput',
|
|
7
|
+
'TaskStop',
|
|
8
|
+
]);
|
|
9
|
+
|
|
10
|
+
function validateParentAllowedTools(parentTools) {
|
|
11
|
+
if (parentTools === null || typeof parentTools !== 'object') {
|
|
12
|
+
throw new TypeError('parentTools is required');
|
|
13
|
+
}
|
|
14
|
+
const allowed = parentTools.allowedTools;
|
|
15
|
+
if (allowed !== undefined && !Array.isArray(allowed)) {
|
|
16
|
+
throw new TypeError('parentTools.allowedTools must be an array or undefined');
|
|
17
|
+
}
|
|
18
|
+
return allowed;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function inheritSubagentLifecycleTools(parentTools, childTools) {
|
|
22
|
+
const allowed = validateParentAllowedTools(parentTools);
|
|
23
|
+
if (allowed === undefined) return [];
|
|
24
|
+
if (childTools === null || typeof childTools !== 'object'
|
|
25
|
+
|| typeof childTools.data !== 'function'
|
|
26
|
+
|| typeof childTools.setActiveTools !== 'function'
|
|
27
|
+
|| typeof childTools.refreshBuiltinTools !== 'function') {
|
|
28
|
+
throw new TypeError('childTools lifecycle controls are required');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const toolData = childTools.data();
|
|
32
|
+
if (!Array.isArray(toolData)) throw new TypeError('childTools.data() must return an array');
|
|
33
|
+
const available = new Set(toolData.map((tool) => tool?.name).filter(Boolean));
|
|
34
|
+
const inherited = NESTED_AGENT_LIFECYCLE_TOOLS.filter((name) => (
|
|
35
|
+
allowed.includes(name) && available.has(name)
|
|
36
|
+
));
|
|
37
|
+
if (inherited.length === 0) return [];
|
|
38
|
+
|
|
39
|
+
const active = toolData.filter((tool) => tool?.active === true).map((tool) => tool.name);
|
|
40
|
+
childTools.setActiveTools([...new Set([...active, ...inherited])]);
|
|
41
|
+
childTools.refreshBuiltinTools();
|
|
42
|
+
return inherited;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function inheritSubagentAllowedTools(parentTools, childTools) {
|
|
46
|
+
const allowed = validateParentAllowedTools(parentTools);
|
|
47
|
+
if (childTools === null || typeof childTools !== 'object'
|
|
48
|
+
|| typeof childTools.setAllowedTools !== 'function') {
|
|
49
|
+
throw new TypeError('childTools.setAllowedTools is required');
|
|
50
|
+
}
|
|
51
|
+
const inherited = allowed === undefined ? undefined : [...allowed];
|
|
52
|
+
childTools.setAllowedTools(inherited);
|
|
53
|
+
return inherited;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
NESTED_AGENT_LIFECYCLE_TOOLS,
|
|
58
|
+
inheritSubagentAllowedTools,
|
|
59
|
+
inheritSubagentLifecycleTools,
|
|
60
|
+
};
|
package/blun.mjs
CHANGED
|
@@ -252406,7 +252406,7 @@ function shouldSuppressQueuedAttemptFailureEvent(options, error) {
|
|
|
252406
252406
|
if (isProviderRateLimitError(error)) return true;
|
|
252407
252407
|
return isAbortError$4(error) || options.signal.aborted;
|
|
252408
252408
|
}
|
|
252409
|
-
var DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation, buildSubagentUsageDelta, SUBAGENT_MAX_TOKENS_ERROR, SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT, buildSubagentMaxTokensFailure, shouldRequestSubagentHandoff, SUMMARY_MIN_LENGTH, SUMMARY_CONTINUATION_ATTEMPTS, HOOK_TEXT_PREVIEW_LENGTH, TOOL_CALL_DISABLED_MESSAGE, SUBAGENT_PROMPT_ORIGIN, SIDE_QUESTION_SYSTEM_REMINDER, SessionSubagentHost;
|
|
252409
|
+
var DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation, buildSubagentUsageDelta, inheritSubagentAllowedTools, inheritSubagentLifecycleTools, SUBAGENT_MAX_TOKENS_ERROR, SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT, buildSubagentMaxTokensFailure, shouldRequestSubagentHandoff, SUMMARY_MIN_LENGTH, SUMMARY_CONTINUATION_ATTEMPTS, HOOK_TEXT_PREVIEW_LENGTH, TOOL_CALL_DISABLED_MESSAGE, SUBAGENT_PROMPT_ORIGIN, SIDE_QUESTION_SYSTEM_REMINDER, SessionSubagentHost;
|
|
252410
252410
|
var init_subagent_host = __esmMin((() => {
|
|
252411
252411
|
init_src$4();
|
|
252412
252412
|
init_errors$8();
|
|
@@ -252420,6 +252420,7 @@ var init_subagent_host = __esmMin((() => {
|
|
|
252420
252420
|
init_summary_continuation();
|
|
252421
252421
|
({ DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation } = createRequire(import.meta.url)("./bin/subagent-timeout-policy.cjs"));
|
|
252422
252422
|
({ buildSubagentUsageDelta } = createRequire(import.meta.url)("./bin/subagent-usage-rollup-policy.cjs"));
|
|
252423
|
+
({ inheritSubagentAllowedTools, inheritSubagentLifecycleTools } = createRequire(import.meta.url)("./bin/subagent-tool-policy.cjs"));
|
|
252423
252424
|
({
|
|
252424
252425
|
SUBAGENT_MAX_TOKENS_ERROR,
|
|
252425
252426
|
SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT,
|
|
@@ -252729,6 +252730,8 @@ IMPORTANT:
|
|
|
252729
252730
|
const context = await prepareSystemPromptContext(this.session.systemContextKaos(child.kaos.getcwd()), this.session.options.blunHomeDir, { additionalDirs: child.getAdditionalDirs() });
|
|
252730
252731
|
child.useProfile(profile, context, this.session.options.blunHomeDir);
|
|
252731
252732
|
child.tools.inheritUserTools(parent.tools);
|
|
252733
|
+
inheritSubagentLifecycleTools(parent.tools, child.tools);
|
|
252734
|
+
inheritSubagentAllowedTools(parent.tools, child.tools);
|
|
252732
252735
|
}
|
|
252733
252736
|
async triggerSubagentStart(parent, profileName, prompt, signal) {
|
|
252734
252737
|
await parent.hooks?.trigger("SubagentStart", {
|