loopengine 0.3.8 → 0.3.10

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.
@@ -6,11 +6,11 @@
6
6
  // one without changing anything that agent already does.
7
7
  import { join } from 'node:path';
8
8
  import { addGatewayTool, readGatewayToolsFromDir } from '../core/gateway-tools.js';
9
- import { addActauthRule, readActauthConfig } from './actauth-admin.js';
9
+ import { applyPlannedRules } from './actauth-admin.js';
10
10
  import { writeSkill } from './skills-admin.js';
11
11
  import { createFromTemplateObject, installFailureReason, templateChecklist } from './templates-admin.js';
12
12
  import { templateScheduleStart } from '../core/system-agents/templates.js';
13
- import { planParameters, planWebhook, planWorkflowWithModel, slugify, workflowTemplate } from '../core/system-agents/workflow-planner.js';
13
+ import { planParameters, planWebhook, planWorkflowWithModel, workflowTemplate } from '../core/system-agents/workflow-planner.js';
14
14
  import { createTrigger, getTriggerStore, listTriggers, publicTrigger } from '../core/workflow-triggers.js';
15
15
  import { mcpAbilityNames } from '../core/mcp-ability-generator.js';
16
16
  import { clearWorkflowFields, migrateWorkflowsFile, readWorkflow, readWorkflows, setWorkflowFields, validateParams, workflowRunMessage } from '../core/workflows.js';
@@ -375,18 +375,7 @@ export async function createWorkflow(input, deps) {
375
375
  if (!agent)
376
376
  throw new WorkflowError(`There's no agent named ${target.agent ?? '(none)'}.`);
377
377
  const check = checkWorkflowForAgent(plan, agent);
378
- // 1. Rules: only for tools the agent has no rule for.
379
- const { rules: current } = readActauthConfig(agent.name);
380
- for (const rule of plan.rules) {
381
- if (current.some((r) => r.tool === rule.tool))
382
- continue;
383
- let name = slugify(`${plan.id}-${rule.tool}`, `${plan.id}-rule`);
384
- for (let i = 2; current.some((r) => r.name === name); i++)
385
- name = `${slugify(`${plan.id}-${rule.tool}`)}-${i}`;
386
- addActauthRule(agent.name, { name, scope: '*/*', tool: rule.tool, decision: rule.decision });
387
- current.push({ name, scope: '*/*', tool: rule.tool, decision: rule.decision });
388
- }
389
- // 2. Abilities it doesn't have yet.
378
+ // 1. Abilities it doesn't have yet (their rules come with them).
390
379
  const installed = [];
391
380
  const failed = [...mcp.failed];
392
381
  for (const spec of check.toInstall) {
@@ -441,6 +430,10 @@ export async function createWorkflow(input, deps) {
441
430
  const connected = copyConnectedTools(plan, agent.name, agents, deps.agentDir);
442
431
  installed.push(...connected.copied);
443
432
  failed.push(...connected.failed);
433
+ // 2. Rules, now that what was installed has added its own: none twice,
434
+ // a stricter one (ask where an ability allows) placed so it counts,
435
+ // and a decision the agent already has never loosened.
436
+ const ruled = applyPlannedRules(agent.name, plan.rules);
444
437
  // 3. Its steps, as a skill; then load the agent again with all of it.
445
438
  writeSkill(agent.name, plan.id, { description: plan.skill.description, body: plan.skill.body });
446
439
  let loadError;
@@ -477,7 +470,7 @@ export async function createWorkflow(input, deps) {
477
470
  newAgent: false,
478
471
  workflow: plan.name,
479
472
  abilities: { installed, failed },
480
- keptDecisions: check.conflicts,
473
+ keptDecisions: ruled.kept,
481
474
  checklist: [...withMissingSteps(plan, agent.name, templateChecklist(template, agent.name, deps, failed, appsToConnect)), ...hook.checklist],
482
475
  ...(hook.webhook ? { webhook: hook.webhook } : {}),
483
476
  ...(hook.webhookError ? { webhookError: hook.webhookError } : {}),
@@ -263,7 +263,7 @@ ${consoleShellScript}
263
263
  '<p class="hint" style="margin:0"><strong>Starts:</strong> ' + esc(p.trigger.description) + (p.trigger.kind === 'schedule' ? ' (created paused; you turn it on)' : '') + '</p>' +
264
264
  webhookPlanHtml(p) +
265
265
  (p.trigger.kind === 'schedule' || p.trigger.kind === 'webhook'
266
- ? '<label class="wf-notify"><input type="checkbox" id="wfNotify"' + (p.notify && p.notify.on ? ' checked' : '') + '> Send each run' + String.fromCharCode(8217) + 's result to you through the agent' + String.fromCharCode(8217) + 's messaging app</label>' +
266
+ ? '<label class="wf-notify"><input type="checkbox" id="wfNotify"' + (p.notify && p.notify.on ? ' checked' : '') + '> Message me the result when it finishes <span class="hint">(through its Messaging tab: Slack, email, Lark or a webhook)</span></label>' +
267
267
  (p.notify && p.notify.reason ? '<p class="hint" style="margin:0 0 0 24px">' + esc(p.notify.reason) + '</p>' : '')
268
268
  : '') +
269
269
  paramsSectionHtml(p) +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopengine",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "type": "module",
5
5
  "description": "Runtime for tool-using AI agents with a transparent ReAct loop.",
6
6
  "license": "MIT",
@@ -48,6 +48,8 @@
48
48
  "dist/core/usage.d.ts",
49
49
  "dist/core/run-events.js",
50
50
  "dist/core/run-events.d.ts",
51
+ "dist/core/official-abilities.js",
52
+ "dist/core/official-abilities.d.ts",
51
53
  "dist/core/email-senders.js",
52
54
  "dist/core/email-senders.d.ts",
53
55
  "dist/core/notifier-file.js",