create-loopengine 0.1.69 → 0.1.71
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/package.json +1 -1
- package/template/adapters/http.ts +7 -33
- package/template/package.json +1 -1
package/package.json
CHANGED
|
@@ -130,12 +130,12 @@ import {
|
|
|
130
130
|
setAgentApprovers,
|
|
131
131
|
listAgentSlackMembers,
|
|
132
132
|
replyPrivatelyInSlack,
|
|
133
|
+
slackArgs,
|
|
133
134
|
type MessagingDecision,
|
|
134
135
|
type DecisionOutcome,
|
|
135
136
|
type MessagingDeps,
|
|
136
137
|
handleMessagingAction,
|
|
137
|
-
|
|
138
|
-
setAgentConfirmTools,
|
|
138
|
+
describeChange,
|
|
139
139
|
openSlackAnswerModal,
|
|
140
140
|
parseSlackInteraction,
|
|
141
141
|
replyInSlack,
|
|
@@ -1291,28 +1291,6 @@ async function handleApproversPut(req: IncomingMessage, res: ServerResponse, age
|
|
|
1291
1291
|
}
|
|
1292
1292
|
}
|
|
1293
1293
|
|
|
1294
|
-
// Messaging tab → Confirm-required tools: tools whose approval by reply
|
|
1295
|
-
// needs a Confirm click. Admin login needed, like the approvers.
|
|
1296
|
-
async function handleConfirmToolsPut(req: IncomingMessage, res: ServerResponse, agentName: string): Promise<void> {
|
|
1297
|
-
const entry = getEntry(agentName)
|
|
1298
|
-
if (!entry) {
|
|
1299
|
-
res.writeHead(404, { 'content-type': 'application/json' }).end(JSON.stringify({ error: `unknown agent '${agentName}'` }))
|
|
1300
|
-
return
|
|
1301
|
-
}
|
|
1302
|
-
if (!secretsProtected) {
|
|
1303
|
-
res.writeHead(403, { 'content-type': 'application/json' }).end(JSON.stringify({ error: 'Changing Confirm-required tools needs LOOPENGINE_ADMIN_AUTH set on the server.' }))
|
|
1304
|
-
return
|
|
1305
|
-
}
|
|
1306
|
-
const body = await readJsonBody(req)
|
|
1307
|
-
try {
|
|
1308
|
-
const tools = setAgentConfirmTools(entry.config, body.tools)
|
|
1309
|
-
res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ tools }))
|
|
1310
|
-
} catch (err) {
|
|
1311
|
-
const status = err instanceof NotifierFileError ? 400 : 500
|
|
1312
|
-
res.writeHead(status, { 'content-type': 'application/json' }).end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }))
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
1294
|
async function handleSlackMembers(res: ServerResponse, agentName: string): Promise<void> {
|
|
1317
1295
|
const entry = getEntry(agentName)
|
|
1318
1296
|
if (!entry) {
|
|
@@ -2319,8 +2297,10 @@ async function resolvePendingApproval(res: ServerResponse, pendingId: string, bo
|
|
|
2319
2297
|
// The agent's own history still shows the arguments it asked
|
|
2320
2298
|
// for, so say when the approver changed them; otherwise its
|
|
2321
2299
|
// reply describes what it asked for, not what ran.
|
|
2322
|
-
const
|
|
2323
|
-
const content =
|
|
2300
|
+
const changes = editedArgs ? describeChange(item.args, editedArgs) : []
|
|
2301
|
+
const content = changes.length
|
|
2302
|
+
? `A person approved this call after changing its arguments (${changes.join('; ')}). It ran with ${JSON.stringify(editedArgs)}. Result: ${JSON.stringify(output)}`
|
|
2303
|
+
: JSON.stringify(output)
|
|
2324
2304
|
resultBlock = { type: 'tool_result', tool_use_id: item.toolUseId, content, is_error: false }
|
|
2325
2305
|
} catch (err) {
|
|
2326
2306
|
resultBlock = { type: 'tool_result', tool_use_id: item.toolUseId, content: `ERROR: ${err}`, is_error: true }
|
|
@@ -2817,7 +2797,7 @@ async function handleSlackInteraction(req: IncomingMessage, res: ServerResponse,
|
|
|
2817
2797
|
let ran = ''
|
|
2818
2798
|
if (interaction.type === 'decide' && interaction.decision === 'approve') {
|
|
2819
2799
|
const item = (await checkpoints.get(interaction.pendingId))?.outstanding[interaction.pendingId]
|
|
2820
|
-
if (item) ran = `\nRan \`${item.tool}\` with
|
|
2800
|
+
if (item) ran = `\nRan \`${item.tool}\` with:\n${slackArgs(item.args, (await resolveAgentTool(entry.config, item.tool))?.input_schema)}`
|
|
2821
2801
|
}
|
|
2822
2802
|
const capture = captureResponse()
|
|
2823
2803
|
if (interaction.type === 'decide') await resolvePendingApproval(capture.res, interaction.pendingId, { decision: interaction.decision })
|
|
@@ -2880,7 +2860,6 @@ function slackMessagingDeps(agentName: string, entry: RegistryEntry, botToken: s
|
|
|
2880
2860
|
getHistory: (checkpoint) => sessions.getHistory(`${checkpoint.tenant}:${environment}:${checkpoint.agent}:${checkpoint.sessionId}`),
|
|
2881
2861
|
plan: process.env.LOOPENGINE_PLAN,
|
|
2882
2862
|
approvers: () => agentApprovers(entry.config),
|
|
2883
|
-
confirmTools: () => agentConfirmTools(entry.config),
|
|
2884
2863
|
decide: decideFromMessaging,
|
|
2885
2864
|
toolSchema: async (toolName) => (await resolveAgentTool(entry.config, toolName))?.input_schema,
|
|
2886
2865
|
// The same checks the console's approve-with-edits applies, plus the
|
|
@@ -3474,11 +3453,6 @@ const server = createServer(async (req, res) => {
|
|
|
3474
3453
|
await handleApproversPut(req, res, decodeURIComponent(approversMatch[1]))
|
|
3475
3454
|
return
|
|
3476
3455
|
}
|
|
3477
|
-
const confirmToolsMatch = req.method === 'PUT' && pathname.match(/^\/agents\/([^/]+)\/notifier\/confirm-tools$/)
|
|
3478
|
-
if (confirmToolsMatch) {
|
|
3479
|
-
await handleConfirmToolsPut(req, res, decodeURIComponent(confirmToolsMatch[1]))
|
|
3480
|
-
return
|
|
3481
|
-
}
|
|
3482
3456
|
const slackMembersMatch = req.method === 'GET' && pathname.match(/^\/agents\/([^/]+)\/notifier\/slack-members$/)
|
|
3483
3457
|
if (slackMembersMatch) {
|
|
3484
3458
|
await handleSlackMembers(res, decodeURIComponent(slackMembersMatch[1]))
|