@xn-intenton-z2a/agentic-lib 7.1.32 → 7.1.33

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": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.32",
3
+ "version": "7.1.33",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -76,12 +76,27 @@ export async function runCopilotTask({ model, systemMessage, prompt, writablePat
76
76
  core.warning(`[copilot] Auth check failed: ${authErr.message}`);
77
77
  }
78
78
 
79
+ // Accumulate usage from assistant.usage events (tokens are NOT on the sendAndWait response)
80
+ let totalInputTokens = 0;
81
+ let totalOutputTokens = 0;
82
+ let totalCost = 0;
83
+
79
84
  // Register wildcard event handler for ALL events
80
85
  session.on((event) => {
81
86
  const eventType = event?.type || "unknown";
82
87
  if (eventType === "assistant.message") {
83
88
  const preview = event?.data?.content?.substring(0, 100) || "(no content)";
84
89
  core.info(`[copilot] event=${eventType}: ${preview}...`);
90
+ } else if (eventType === "assistant.usage") {
91
+ const d = event?.data || {};
92
+ const input = d.inputTokens || 0;
93
+ const output = d.outputTokens || 0;
94
+ const cacheRead = d.cacheReadTokens || 0;
95
+ const cost = d.cost || 0;
96
+ totalInputTokens += input;
97
+ totalOutputTokens += output;
98
+ totalCost += cost;
99
+ core.info(`[copilot] event=${eventType}: model=${d.model} input=${input} output=${output} cacheRead=${cacheRead} cost=${cost}`);
85
100
  } else if (eventType === "session.idle") {
86
101
  core.info(`[copilot] event=${eventType}`);
87
102
  } else if (eventType === "session.error") {
@@ -94,10 +109,10 @@ export async function runCopilotTask({ model, systemMessage, prompt, writablePat
94
109
  core.info("[copilot] Sending prompt and waiting for idle...");
95
110
  const response = await session.sendAndWait({ prompt }, 600000);
96
111
  core.info(`[copilot] sendAndWait resolved`);
97
- const tokensUsed = response?.data?.usage?.totalTokens || 0;
112
+ const tokensUsed = totalInputTokens + totalOutputTokens;
98
113
  const content = response?.data?.content || "";
99
114
 
100
- return { content, tokensUsed };
115
+ return { content, tokensUsed, inputTokens: totalInputTokens, outputTokens: totalOutputTokens, cost: totalCost };
101
116
  } finally {
102
117
  await client.stop();
103
118
  }
@@ -105,6 +105,9 @@ async function run() {
105
105
  prNumber: result.prNumber,
106
106
  commitUrl: result.commitUrl,
107
107
  tokensUsed: result.tokensUsed,
108
+ inputTokens: result.inputTokens,
109
+ outputTokens: result.outputTokens,
110
+ cost: result.cost,
108
111
  model: result.model || model,
109
112
  details: result.details,
110
113
  workflowUrl: `${process.env.GITHUB_SERVER_URL}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`,
@@ -19,7 +19,10 @@ import * as core from "@actions/core";
19
19
  * @param {string} [options.issueNumber] - Related issue number
20
20
  * @param {string} [options.prNumber] - Related PR number
21
21
  * @param {string} [options.commitUrl] - URL to the commit
22
- * @param {number} [options.tokensUsed] - Tokens consumed
22
+ * @param {number} [options.tokensUsed] - Total tokens consumed (input + output)
23
+ * @param {number} [options.inputTokens] - Input tokens consumed
24
+ * @param {number} [options.outputTokens] - Output tokens consumed
25
+ * @param {number} [options.cost] - Cost reported by Copilot SDK
23
26
  * @param {string} [options.model] - Model used
24
27
  * @param {string} [options.details] - Additional details
25
28
  * @param {string} [options.workflowUrl] - URL to the workflow run
@@ -32,6 +35,9 @@ export function logActivity({
32
35
  prNumber,
33
36
  commitUrl,
34
37
  tokensUsed,
38
+ inputTokens,
39
+ outputTokens,
40
+ cost,
35
41
  model,
36
42
  details,
37
43
  workflowUrl,
@@ -48,7 +54,8 @@ export function logActivity({
48
54
  if (prNumber) parts.push(`**PR:** #${prNumber}`);
49
55
  if (commitUrl) parts.push(`**Commit:** [${commitUrl}](${commitUrl})`);
50
56
  if (model) parts.push(`**Model:** ${model}`);
51
- if (tokensUsed !== undefined) parts.push(`**Tokens:** ${tokensUsed}`);
57
+ if (tokensUsed) parts.push(`**Tokens:** ${tokensUsed} (in: ${inputTokens || 0}, out: ${outputTokens || 0})`);
58
+ if (cost) parts.push(`**Cost:** ${cost}`);
52
59
  if (workflowUrl) parts.push(`**Workflow:** [${workflowUrl}](${workflowUrl})`);
53
60
  if (details) {
54
61
  parts.push("");
@@ -158,7 +158,7 @@ export async function discussions(context) {
158
158
  const discussion = await fetchDiscussion(octokit, discussionUrl);
159
159
  const prompt = buildPrompt(discussionUrl, discussion, context);
160
160
 
161
- const { content, tokensUsed } = await runCopilotTask({
161
+ const { content, tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
162
162
  model,
163
163
  systemMessage:
164
164
  "You are this repository. Respond in first person. Be concise and engaging — never repeat what you said in your last reply. Adapt to the user's language level. Encourage experimentation and suggest interesting projects. When a user requests an action, pass it to the supervisor via [ACTION:request-supervisor]. Protect the mission: push back on requests that contradict it.",
@@ -178,6 +178,9 @@ export async function discussions(context) {
178
178
  return {
179
179
  outcome: `discussion-${action}`,
180
180
  tokensUsed,
181
+ inputTokens,
182
+ outputTokens,
183
+ cost,
181
184
  model,
182
185
  details: `Action: ${action}${argSuffix}\nReply: ${replyBody.substring(0, 200)}`,
183
186
  action,
@@ -59,7 +59,7 @@ export async function enhanceIssue(context) {
59
59
  "Output ONLY the new issue body text, no markdown code fences.",
60
60
  ].join("\n");
61
61
 
62
- const { content: enhancedBody, tokensUsed } = await runCopilotTask({
62
+ const { content: enhancedBody, tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
63
63
  model,
64
64
  systemMessage: "You are a requirements analyst. Enhance GitHub issues with clear, testable acceptance criteria.",
65
65
  prompt,
@@ -96,6 +96,9 @@ export async function enhanceIssue(context) {
96
96
  return {
97
97
  outcome: "issue-enhanced",
98
98
  tokensUsed,
99
+ inputTokens,
100
+ outputTokens,
101
+ cost,
99
102
  model,
100
103
  details: `Enhanced issue #${issueNumber} with acceptance criteria`,
101
104
  };
@@ -53,7 +53,7 @@ export async function fixCode(context) {
53
53
  "- Make minimal changes to fix the failing tests",
54
54
  ].join("\n");
55
55
 
56
- const { tokensUsed } = await runCopilotTask({
56
+ const { tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
57
57
  model,
58
58
  systemMessage: `You are an autonomous coding agent fixing failing tests on PR #${prNumber}. Make minimal, targeted changes to fix the test failures.`,
59
59
  prompt,
@@ -65,6 +65,9 @@ export async function fixCode(context) {
65
65
  return {
66
66
  outcome: "fix-applied",
67
67
  tokensUsed,
68
+ inputTokens,
69
+ outputTokens,
70
+ cost,
68
71
  model,
69
72
  details: `Applied fix for ${failedChecks.length} failing check(s) on PR #${prNumber}`,
70
73
  };
@@ -62,7 +62,7 @@ export async function maintainFeatures(context) {
62
62
  "- Feature files must be markdown with a descriptive filename (e.g. HTTP_SERVER.md)",
63
63
  ].join("\n");
64
64
 
65
- const { tokensUsed } = await runCopilotTask({
65
+ const { tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
66
66
  model,
67
67
  systemMessage:
68
68
  "You are a feature lifecycle manager. Create, update, and prune feature specification files to keep the project focused on its mission.",
@@ -73,6 +73,9 @@ export async function maintainFeatures(context) {
73
73
  return {
74
74
  outcome: "features-maintained",
75
75
  tokensUsed,
76
+ inputTokens,
77
+ outputTokens,
78
+ cost,
76
79
  model,
77
80
  details: `Maintained features (${features.length} existing, limit ${featureLimit})`,
78
81
  };
@@ -50,7 +50,7 @@ export async function maintainLibrary(context) {
50
50
  `- Maximum ${libraryLimit} library documents`,
51
51
  ].join("\n");
52
52
 
53
- const { tokensUsed } = await runCopilotTask({
53
+ const { tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
54
54
  model,
55
55
  systemMessage:
56
56
  "You are a knowledge librarian. Maintain a library of technical documents extracted from web sources.",
@@ -61,6 +61,9 @@ export async function maintainLibrary(context) {
61
61
  return {
62
62
  outcome: "library-maintained",
63
63
  tokensUsed,
64
+ inputTokens,
65
+ outputTokens,
66
+ cost,
64
67
  model,
65
68
  details: `Maintained library (${libraryDocs.length} docs, limit ${libraryLimit})`,
66
69
  };
@@ -78,7 +78,7 @@ export async function resolveIssue(context) {
78
78
  contributing ? `\n## Contributing Guidelines\n${contributing}` : "",
79
79
  ].join("\n");
80
80
 
81
- const { content: resultContent, tokensUsed } = await runCopilotTask({
81
+ const { content: resultContent, tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
82
82
  model,
83
83
  systemMessage: `You are an autonomous coding agent resolving GitHub issue #${issueNumber}. Write clean, tested code. Only modify files listed under "Writable" paths. Read-only paths are for context only.`,
84
84
  prompt,
@@ -91,6 +91,9 @@ export async function resolveIssue(context) {
91
91
  outcome: "code-generated",
92
92
  prNumber: null,
93
93
  tokensUsed,
94
+ inputTokens,
95
+ outputTokens,
96
+ cost,
94
97
  model,
95
98
  commitUrl: null,
96
99
  details: `Generated code for issue #${issueNumber}: ${resultContent.substring(0, 200)}`,
@@ -74,7 +74,7 @@ export async function reviewIssue(context) {
74
74
  '- "OPEN: <reason>" if the issue is not yet resolved',
75
75
  ].join("\n");
76
76
 
77
- const { content: verdict, tokensUsed } = await runCopilotTask({
77
+ const { content: verdict, tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
78
78
  model,
79
79
  systemMessage: "You are a code reviewer determining if GitHub issues have been resolved.",
80
80
  prompt,
@@ -108,6 +108,9 @@ export async function reviewIssue(context) {
108
108
  return {
109
109
  outcome: "issue-closed",
110
110
  tokensUsed,
111
+ inputTokens,
112
+ outputTokens,
113
+ cost,
111
114
  model,
112
115
  details: `Closed issue #${targetIssueNumber}: ${verdict.substring(0, 200)}`,
113
116
  };
@@ -117,6 +120,9 @@ export async function reviewIssue(context) {
117
120
  return {
118
121
  outcome: "issue-still-open",
119
122
  tokensUsed,
123
+ inputTokens,
124
+ outputTokens,
125
+ cost,
120
126
  model,
121
127
  details: `Issue #${targetIssueNumber} remains open: ${verdict.substring(0, 200)}`,
122
128
  };
@@ -257,7 +257,7 @@ export async function supervise(context) {
257
257
  const agentInstructions = instructions || "You are the supervisor. Decide what actions to take.";
258
258
  const prompt = buildPrompt(ctx, agentInstructions);
259
259
 
260
- const { content, tokensUsed } = await runCopilotTask({
260
+ const { content, tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
261
261
  model,
262
262
  systemMessage:
263
263
  "You are the supervisor of an autonomous coding repository. Your job is to advance the mission by choosing which workflows to dispatch and which GitHub actions to take. Pick multiple actions when appropriate. Be strategic — consider what's already in progress, what's blocked, and what will make the most impact.",
@@ -286,6 +286,9 @@ export async function supervise(context) {
286
286
  return {
287
287
  outcome: actions.length === 0 ? "nop" : `supervised:${actions.length}-actions`,
288
288
  tokensUsed,
289
+ inputTokens,
290
+ outputTokens,
291
+ cost,
289
292
  model,
290
293
  details: `Actions: ${results.join(", ")}\nReasoning: ${reasoning.substring(0, 300)}`,
291
294
  };
@@ -85,7 +85,7 @@ export async function transform(context) {
85
85
 
86
86
  core.info(`Transform prompt length: ${prompt.length} chars`);
87
87
 
88
- const { content: resultContent, tokensUsed } = await runCopilotTask({
88
+ const { content: resultContent, tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
89
89
  model,
90
90
  systemMessage:
91
91
  "You are an autonomous code transformation agent. Your goal is to advance the repository toward its mission by making the most impactful change possible in a single step.",
@@ -98,6 +98,9 @@ export async function transform(context) {
98
98
  return {
99
99
  outcome: "transformed",
100
100
  tokensUsed,
101
+ inputTokens,
102
+ outputTokens,
103
+ cost,
101
104
  model,
102
105
  details: resultContent.substring(0, 500),
103
106
  };
@@ -207,6 +210,9 @@ async function transformTdd({
207
210
  return {
208
211
  outcome: "transformed-tdd",
209
212
  tokensUsed: totalTokens,
213
+ inputTokens: (phase1.inputTokens || 0) + (phase2.inputTokens || 0),
214
+ outputTokens: (phase1.outputTokens || 0) + (phase2.outputTokens || 0),
215
+ cost: (phase1.cost || 0) + (phase2.cost || 0),
210
216
  model,
211
217
  details: `TDD transformation: Phase 1 (failing test) + Phase 2 (implementation). ${testResult.substring(0, 200)}`,
212
218
  };
@@ -14,7 +14,7 @@
14
14
  "author": "",
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
- "@xn-intenton-z2a/agentic-lib": "^7.1.32"
17
+ "@xn-intenton-z2a/agentic-lib": "^7.1.33"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@vitest/coverage-v8": "^4.0.0",
@@ -48,7 +48,7 @@ jobs:
48
48
  weekly: '0 6 * * 1',
49
49
  daily: '0 6 * * *',
50
50
  hourly: '0 * * * *',
51
- continuous: '*/10 * * * *',
51
+ continuous: '*/15 * * * *',
52
52
  };
53
53
 
54
54
  let content = fs.readFileSync(workflowPath, 'utf8');