@xn-intenton-z2a/agentic-lib 7.1.84 → 7.1.86

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.
@@ -190,7 +190,10 @@ jobs:
190
190
 
191
191
  dispatch-supervisor:
192
192
  needs: [params, respond]
193
- if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.respond.outputs.action == 'request-supervisor'
193
+ if: >-
194
+ github.repository != 'xn-intenton-z2a/agentic-lib'
195
+ && needs.respond.outputs.action == 'request-supervisor'
196
+ && inputs.message == ''
194
197
  runs-on: ubuntu-latest
195
198
  steps:
196
199
  - name: Dispatch supervisor workflow
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.84",
3
+ "version": "7.1.86",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -71,6 +71,36 @@ async function dispatchBot(octokit, repo, message, discussionUrl) {
71
71
  }
72
72
  }
73
73
 
74
+ /**
75
+ * Post a comment directly to a discussion via GraphQL.
76
+ * Used for supervisor-originated messages to avoid triggering the bot workflow
77
+ * (which could loop back via request-supervisor).
78
+ */
79
+ async function postDirectReply(octokit, repo, nodeId, body) {
80
+ if (process.env.GITHUB_REPOSITORY === "xn-intenton-z2a/agentic-lib") {
81
+ core.info("Skipping direct reply — running in SDK repo");
82
+ return;
83
+ }
84
+ if (!nodeId || !body) {
85
+ core.warning(`Cannot post direct reply: ${!nodeId ? "no nodeId" : "no body"}`);
86
+ return;
87
+ }
88
+ try {
89
+ const mutation = `mutation($discussionId: ID!, $body: String!) {
90
+ addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
91
+ comment { url }
92
+ }
93
+ }`;
94
+ const { addDiscussionComment } = await octokit.graphql(mutation, {
95
+ discussionId: nodeId,
96
+ body,
97
+ });
98
+ core.info(`Posted direct reply: ${addDiscussionComment.comment.url}`);
99
+ } catch (err) {
100
+ core.warning(`Could not post direct reply: ${err.message}`);
101
+ }
102
+ }
103
+
74
104
  async function gatherContext(octokit, repo, config, t) {
75
105
  const mission = readOptionalFile(config.paths.mission.path);
76
106
  const intentionLogFull = readOptionalFile(config.intentionBot.intentionFilepath);
@@ -100,11 +130,21 @@ async function gatherContext(octokit, repo, config, t) {
100
130
  // Extract discussion URL from recent activity for supervisor reporting
101
131
  const discussionUrlMatch = recentActivity.match(/https:\/\/github\.com\/[^/]+\/[^/]+\/discussions\/\d+/);
102
132
  let activeDiscussionUrl = discussionUrlMatch ? discussionUrlMatch[0] : "";
133
+ let activeDiscussionNodeId = "";
103
134
 
104
135
  // Fallback: look up the "Talk to the repository" discussion if not found in activity log
105
136
  if (!activeDiscussionUrl) {
106
137
  const talk = await findTalkDiscussion(octokit, repo);
107
138
  activeDiscussionUrl = talk.url;
139
+ activeDiscussionNodeId = talk.nodeId;
140
+ }
141
+
142
+ // Resolve node ID from URL if we got the URL from activity log
143
+ if (activeDiscussionUrl && !activeDiscussionNodeId) {
144
+ const talk = await findTalkDiscussion(octokit, repo);
145
+ if (talk.url === activeDiscussionUrl) {
146
+ activeDiscussionNodeId = talk.nodeId;
147
+ }
108
148
  }
109
149
 
110
150
  const featuresPath = config.paths.features.path;
@@ -271,6 +311,7 @@ async function gatherContext(octokit, repo, config, t) {
271
311
  featureIssuesWipLimit: config.featureDevelopmentIssuesWipLimit,
272
312
  maintenanceIssuesWipLimit: config.maintenanceIssuesWipLimit,
273
313
  activeDiscussionUrl,
314
+ activeDiscussionNodeId,
274
315
  missionComplete,
275
316
  missionCompleteInfo,
276
317
  missionFailed,
@@ -670,14 +711,15 @@ export async function supervise(context) {
670
711
  // Step 2: Auto-announce on first run after init
671
712
  // Detect first supervisor run: initTimestamp exists but no prior supervisor workflow runs since init
672
713
  if (ctx.initTimestamp && !ctx.missionComplete && !ctx.missionFailed) {
673
- const hasPriorSupervisor = ctx.actionsSinceInit.some(
674
- (a) => a.name === "agentic-lib-workflow" && a.conclusion === "success" &&
675
- a.commitMessage?.toLowerCase().includes("supervisor"),
676
- ) || ctx.recentActivity.includes("supervised:");
714
+ // Check for any prior agentic-lib-workflow runs since init (count > 1 because current run is included)
715
+ const supervisorRunCount = ctx.actionsSinceInit.filter(
716
+ (a) => a.name === "agentic-lib-workflow",
717
+ ).length;
718
+ const hasPriorSupervisor = supervisorRunCount > 1 || ctx.recentActivity.includes("supervised:");
677
719
  if (!hasPriorSupervisor && ctx.mission && ctx.activeDiscussionUrl) {
678
- core.info("First supervisor run after init — announcing mission");
720
+ core.info("First supervisor run after init — announcing mission directly");
679
721
  const announcement = `New mission started!\n\n**Mission:** ${ctx.mission.substring(0, 300)}\n\n**Website:** ${websiteUrl}`;
680
- await dispatchBot(octokit, repo, announcement, ctx.activeDiscussionUrl);
722
+ await postDirectReply(octokit, repo, ctx.activeDiscussionNodeId, announcement);
681
723
  }
682
724
  }
683
725
 
@@ -738,16 +780,18 @@ export async function supervise(context) {
738
780
 
739
781
  // Step 3: Auto-respond when a message referral is present
740
782
  // If the workflow was triggered with a message (from bot's request-supervisor),
741
- // and the LLM didn't include a respond:discussions action, post back automatically
783
+ // and the LLM didn't include a respond:discussions action, post back directly.
784
+ // Posts directly via GraphQL to avoid triggering the bot workflow (which would
785
+ // request-supervisor again, creating an infinite loop).
742
786
  const workflowMessage = context.discussionUrl ? "" : (process.env.INPUT_MESSAGE || "");
743
787
  if (workflowMessage && ctx.activeDiscussionUrl) {
744
788
  const hasDiscussionResponse = results.some((r) => r.startsWith("respond-discussions:"));
745
789
  if (!hasDiscussionResponse) {
746
- core.info("Message referral detected — auto-responding to discussion");
790
+ core.info("Message referral detected — posting auto-response directly");
747
791
  const response = reasoning
748
792
  ? `Supervisor update: ${reasoning.substring(0, 400)}`
749
793
  : `Supervisor processed your request. Actions taken: ${results.join(", ")}`;
750
- await dispatchBot(octokit, repo, response, ctx.activeDiscussionUrl);
794
+ await postDirectReply(octokit, repo, ctx.activeDiscussionNodeId, response);
751
795
  results.push(`auto-respond:${ctx.activeDiscussionUrl}`);
752
796
  }
753
797
  }
@@ -17,7 +17,7 @@
17
17
  "author": "",
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
- "@xn-intenton-z2a/agentic-lib": "^7.1.84"
20
+ "@xn-intenton-z2a/agentic-lib": "^7.1.86"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@playwright/test": "^1.58.0",