@hamp10/agentforge 0.2.49 → 0.2.50

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": "@hamp10/agentforge",
3
- "version": "0.2.49",
3
+ "version": "0.2.50",
4
4
  "description": "AgentForge worker — connect your machine to agentforge.ai",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1820,7 +1820,7 @@ export class OpenClawCLI extends EventEmitter {
1820
1820
  if (!sessionFilePath || !existsSync(sessionFilePath)) return null;
1821
1821
  try {
1822
1822
  const lines = readFileSync(sessionFilePath, 'utf8').split('\n');
1823
- let input = 0, output = 0, costUsd = 0;
1823
+ let input = 0, output = 0, costUsd = 0, hasCost = false;
1824
1824
  for (const line of lines) {
1825
1825
  if (!line.trim()) continue;
1826
1826
  try {
@@ -1830,14 +1830,26 @@ export class OpenClawCLI extends EventEmitter {
1830
1830
  output += entry.message.usage.output || 0;
1831
1831
  // openclaw writes exact cost.total — use it directly instead of re-calculating
1832
1832
  if (entry.message.usage.cost?.total != null) {
1833
- costUsd += entry.message.usage.cost.total;
1833
+ const costTotal = Number(entry.message.usage.cost.total);
1834
+ if (Number.isFinite(costTotal) && costTotal >= 0) {
1835
+ costUsd += costTotal;
1836
+ hasCost = true;
1837
+ }
1834
1838
  }
1835
1839
  }
1836
1840
  } catch { /* skip malformed lines */ }
1837
1841
  }
1838
1842
  if (input > 0 || output > 0) {
1839
1843
  console.log(`[session-usage] Read from JSONL: input=${input} output=${output} cost=$${costUsd.toFixed(6)}`);
1840
- return { input_tokens: input, output_tokens: output, cost_usd: costUsd > 0 ? costUsd : undefined };
1844
+ return {
1845
+ input_tokens: input,
1846
+ output_tokens: output,
1847
+ ...(hasCost ? {
1848
+ cost_usd: costUsd,
1849
+ cost_source: 'provider_reported',
1850
+ cost_accuracy: 'exact',
1851
+ } : {}),
1852
+ };
1841
1853
  }
1842
1854
  return null;
1843
1855
  } catch (e) {
package/src/worker.js CHANGED
@@ -3890,7 +3890,10 @@ export class AgentForgeWorker extends EventEmitter {
3890
3890
  let uiRepairNudgeCount = 0;
3891
3891
  let taskResult;
3892
3892
  let iterationMessage = finalMessage;
3893
- let totalUsage = { input_tokens: 0, output_tokens: 0, cost_usd: 0 };
3893
+ let totalUsage = { input_tokens: 0, output_tokens: 0 };
3894
+ let totalUsageCostUsd = 0;
3895
+ let usageSegments = 0;
3896
+ let usageCostSegments = 0;
3894
3897
  // Fallback tracking: used at most once per task
3895
3898
  let usedFallback = false;
3896
3899
  let toolFailureRetryCount = 0;
@@ -4175,10 +4178,19 @@ export class AgentForgeWorker extends EventEmitter {
4175
4178
  break;
4176
4179
  }
4177
4180
  if (taskResult?.usage) {
4178
- totalUsage.input_tokens += taskResult.usage.input_tokens || 0;
4179
- totalUsage.output_tokens += taskResult.usage.output_tokens || 0;
4181
+ const inputTokens = Number(taskResult.usage.input_tokens || 0);
4182
+ const outputTokens = Number(taskResult.usage.output_tokens || 0);
4183
+ totalUsage.input_tokens += Number.isFinite(inputTokens) ? inputTokens : 0;
4184
+ totalUsage.output_tokens += Number.isFinite(outputTokens) ? outputTokens : 0;
4185
+ if ((inputTokens > 0 || outputTokens > 0) || taskResult.usage.cost_usd != null) {
4186
+ usageSegments += 1;
4187
+ }
4180
4188
  if (taskResult.usage.cost_usd != null) {
4181
- totalUsage.cost_usd += taskResult.usage.cost_usd;
4189
+ const costUsd = Number(taskResult.usage.cost_usd);
4190
+ if (Number.isFinite(costUsd) && costUsd >= 0) {
4191
+ totalUsageCostUsd += costUsd;
4192
+ usageCostSegments += 1;
4193
+ }
4182
4194
  }
4183
4195
  }
4184
4196
 
@@ -5065,7 +5077,12 @@ export class AgentForgeWorker extends EventEmitter {
5065
5077
  console.log(`[${taskId}] ℹ️ Task succeeded with no text output — using default completion message`);
5066
5078
  }
5067
5079
  console.log(`[${taskId}] 📤 finalOutput="${finalOutput.slice(0,100)}" response=${finalOutput ? `"${finalOutput.slice(0,80)}"` : 'undefined'}`);
5068
- const hasUsage = totalUsage.input_tokens > 0 || totalUsage.output_tokens > 0 || totalUsage.cost_usd > 0;
5080
+ if (usageSegments > 0 && usageCostSegments === usageSegments) {
5081
+ totalUsage.cost_usd = totalUsageCostUsd;
5082
+ totalUsage.cost_source = 'provider_reported';
5083
+ totalUsage.cost_accuracy = 'exact';
5084
+ }
5085
+ const hasUsage = totalUsage.input_tokens > 0 || totalUsage.output_tokens > 0 || totalUsage.cost_usd != null;
5069
5086
  const completionMessage = {
5070
5087
  type: 'task_complete',
5071
5088
  taskId,