create-loopengine 0.1.68 → 0.1.70

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.68",
3
+ "version": "0.1.70",
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,11 @@ 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,
139
138
  openSlackAnswerModal,
140
139
  parseSlackInteraction,
141
140
  replyInSlack,
@@ -1291,28 +1290,6 @@ async function handleApproversPut(req: IncomingMessage, res: ServerResponse, age
1291
1290
  }
1292
1291
  }
1293
1292
 
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
1293
  async function handleSlackMembers(res: ServerResponse, agentName: string): Promise<void> {
1317
1294
  const entry = getEntry(agentName)
1318
1295
  if (!entry) {
@@ -2316,7 +2293,12 @@ async function resolvePendingApproval(res: ServerResponse, pendingId: string, bo
2316
2293
  sessionId: checkpoint.sessionId,
2317
2294
  env: createAgentEnv(entry.config.name, agentDirFor(entry.config)),
2318
2295
  })
2319
- resultBlock = { type: 'tool_result', tool_use_id: item.toolUseId, content: JSON.stringify(output), is_error: false }
2296
+ // The agent's own history still shows the arguments it asked
2297
+ // for, so say when the approver changed them; otherwise its
2298
+ // reply describes what it asked for, not what ran.
2299
+ const changed = editedArgs && JSON.stringify(editedArgs) !== JSON.stringify(item.args)
2300
+ const content = changed ? `The approver changed the arguments before it ran: ${JSON.stringify(editedArgs)}. Result: ${JSON.stringify(output)}` : JSON.stringify(output)
2301
+ resultBlock = { type: 'tool_result', tool_use_id: item.toolUseId, content, is_error: false }
2320
2302
  } catch (err) {
2321
2303
  resultBlock = { type: 'tool_result', tool_use_id: item.toolUseId, content: `ERROR: ${err}`, is_error: true }
2322
2304
  }
@@ -2812,7 +2794,7 @@ async function handleSlackInteraction(req: IncomingMessage, res: ServerResponse,
2812
2794
  let ran = ''
2813
2795
  if (interaction.type === 'decide' && interaction.decision === 'approve') {
2814
2796
  const item = (await checkpoints.get(interaction.pendingId))?.outstanding[interaction.pendingId]
2815
- if (item) ran = `\nRan \`${item.tool}\` with \`${JSON.stringify(item.args)}\`.`
2797
+ if (item) ran = `\nRan \`${item.tool}\` with:\n${slackArgs(item.args, (await resolveAgentTool(entry.config, item.tool))?.input_schema)}`
2816
2798
  }
2817
2799
  const capture = captureResponse()
2818
2800
  if (interaction.type === 'decide') await resolvePendingApproval(capture.res, interaction.pendingId, { decision: interaction.decision })
@@ -2875,7 +2857,6 @@ function slackMessagingDeps(agentName: string, entry: RegistryEntry, botToken: s
2875
2857
  getHistory: (checkpoint) => sessions.getHistory(`${checkpoint.tenant}:${environment}:${checkpoint.agent}:${checkpoint.sessionId}`),
2876
2858
  plan: process.env.LOOPENGINE_PLAN,
2877
2859
  approvers: () => agentApprovers(entry.config),
2878
- confirmTools: () => agentConfirmTools(entry.config),
2879
2860
  decide: decideFromMessaging,
2880
2861
  toolSchema: async (toolName) => (await resolveAgentTool(entry.config, toolName))?.input_schema,
2881
2862
  // The same checks the console's approve-with-edits applies, plus the
@@ -3469,11 +3450,6 @@ const server = createServer(async (req, res) => {
3469
3450
  await handleApproversPut(req, res, decodeURIComponent(approversMatch[1]))
3470
3451
  return
3471
3452
  }
3472
- const confirmToolsMatch = req.method === 'PUT' && pathname.match(/^\/agents\/([^/]+)\/notifier\/confirm-tools$/)
3473
- if (confirmToolsMatch) {
3474
- await handleConfirmToolsPut(req, res, decodeURIComponent(confirmToolsMatch[1]))
3475
- return
3476
- }
3477
3453
  const slackMembersMatch = req.method === 'GET' && pathname.match(/^\/agents\/([^/]+)\/notifier\/slack-members$/)
3478
3454
  if (slackMembersMatch) {
3479
3455
  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.84",
12
+ "loopengine": "^0.1.86",
13
13
  "actauth": "^0.0.12",
14
14
  "tsx": "^4.19.0",
15
15
  "typescript": "^5.7.0"