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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-loopengine",
3
- "version": "0.1.69",
3
+ "version": "0.1.71",
4
4
  "description": "Scaffold a new loopengine agent project — a runnable HTTP server with one example agent, in your own repo.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -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
- agentConfirmTools,
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 changed = editedArgs && JSON.stringify(editedArgs) !== JSON.stringify(item.args)
2323
- const content = changed ? `The approver changed the arguments before it ran: ${JSON.stringify(editedArgs)}. Result: ${JSON.stringify(output)}` : JSON.stringify(output)
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 \`${JSON.stringify(item.args)}\`.`
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]))
@@ -9,7 +9,7 @@
9
9
  "cli": "tsx adapters/cli.ts"
10
10
  },
11
11
  "dependencies": {
12
- "loopengine": "^0.1.85",
12
+ "loopengine": "^0.1.88",
13
13
  "actauth": "^0.0.12",
14
14
  "tsx": "^4.19.0",
15
15
  "typescript": "^5.7.0"