@pikaa-ai/pikaa 0.2.2 → 0.2.3

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/dist/index.js CHANGED
@@ -152,6 +152,7 @@ class DefaultModelClientSession {
152
152
  model,
153
153
  messages,
154
154
  stream: true,
155
+ stream_options: { include_usage: true },
155
156
  temperature: params.temperature ?? 0.2
156
157
  };
157
158
  if (toolsPayload && toolsPayload.length > 0) {
@@ -200,6 +201,7 @@ class DefaultModelClientSession {
200
201
  const reader = response.body.getReader();
201
202
  const decoder = new TextDecoder;
202
203
  let buffer = "";
204
+ let usageMetrics = {};
203
205
  const pendingToolCalls = new Map;
204
206
  try {
205
207
  while (true) {
@@ -229,11 +231,23 @@ class DefaultModelClientSession {
229
231
  };
230
232
  }
231
233
  pendingToolCalls.clear();
232
- yield { type: "done" };
234
+ yield {
235
+ type: "done",
236
+ inputTokens: usageMetrics.inputTokens,
237
+ outputTokens: usageMetrics.outputTokens,
238
+ totalTokens: usageMetrics.totalTokens
239
+ };
233
240
  return;
234
241
  }
235
242
  try {
236
243
  const data = JSON.parse(dataStr);
244
+ if (data.usage) {
245
+ usageMetrics = {
246
+ inputTokens: data.usage.prompt_tokens,
247
+ outputTokens: data.usage.completion_tokens,
248
+ totalTokens: data.usage.total_tokens
249
+ };
250
+ }
237
251
  const choice = data.choices?.[0];
238
252
  if (!choice)
239
253
  continue;
@@ -489,7 +503,8 @@ function createShellTool(policy = new ExecPolicy) {
489
503
  if (!command) {
490
504
  return { output: "Error: 'command' argument cannot be empty", isError: true };
491
505
  }
492
- const policyDecision = policy.evaluate(command);
506
+ const activePolicy = ctx.execPolicy || policy;
507
+ const policyDecision = activePolicy.evaluate(command);
493
508
  if (policyDecision.decision === "deny") {
494
509
  return {
495
510
  output: `Error: Command execution denied by policy: ${policyDecision.reason}`,
@@ -1550,6 +1565,8 @@ async function runTurn(session, turnContext, input) {
1550
1565
  skillsPrompt
1551
1566
  });
1552
1567
  let iteration = 0;
1568
+ let accumulatedInputTokens = 0;
1569
+ let accumulatedOutputTokens = 0;
1553
1570
  const clientSession = session.modelClient.newSession();
1554
1571
  try {
1555
1572
  while (iteration < turnContext.maxIterations) {
@@ -1559,6 +1576,8 @@ async function runTurn(session, turnContext, input) {
1559
1576
  iteration++;
1560
1577
  let currentAgentText = "";
1561
1578
  const toolCallRequests = [];
1579
+ let iterInputTokens = Math.ceil((effectiveSystemPrompt.length + JSON.stringify(session.getHistory()).length) / 4);
1580
+ let iterOutputTokens = 0;
1562
1581
  const stream = clientSession.stream({
1563
1582
  model: turnContext.model,
1564
1583
  systemPrompt: effectiveSystemPrompt,
@@ -1585,10 +1604,20 @@ async function runTurn(session, turnContext, input) {
1585
1604
  });
1586
1605
  } else if (chunk.type === "tool_call") {
1587
1606
  toolCallRequests.push(chunk);
1607
+ } else if (chunk.type === "done") {
1608
+ if (chunk.inputTokens !== undefined)
1609
+ iterInputTokens = chunk.inputTokens;
1610
+ if (chunk.outputTokens !== undefined)
1611
+ iterOutputTokens = chunk.outputTokens;
1588
1612
  } else if (chunk.type === "error") {
1589
1613
  throw chunk.error;
1590
1614
  }
1591
1615
  }
1616
+ if (iterOutputTokens === 0) {
1617
+ iterOutputTokens = Math.ceil((currentAgentText.length + JSON.stringify(toolCallRequests).length) / 4);
1618
+ }
1619
+ accumulatedInputTokens += iterInputTokens;
1620
+ accumulatedOutputTokens += iterOutputTokens;
1592
1621
  if (currentAgentText.trim()) {
1593
1622
  const agentItem = {
1594
1623
  id: `msg_agent_${Date.now()}`,
@@ -1629,6 +1658,7 @@ async function runTurn(session, turnContext, input) {
1629
1658
  cwd: turnContext.environment.cwd,
1630
1659
  turnId,
1631
1660
  signal,
1661
+ execPolicy: session.execPolicy,
1632
1662
  requestApproval: async (description, command) => {
1633
1663
  const approvalId = `appr_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
1634
1664
  return session.requestApproval({
@@ -1666,9 +1696,16 @@ async function runTurn(session, turnContext, input) {
1666
1696
  }
1667
1697
  break;
1668
1698
  }
1699
+ const totalContextTokens = estimateTotalTokens(session.getHistory()) + Math.ceil(effectiveSystemPrompt.length / 4);
1700
+ const maxContextTokens = 128000;
1669
1701
  session.emitEvent({
1670
1702
  type: "TurnCompleted",
1671
- turnId
1703
+ turnId,
1704
+ inputTokens: accumulatedInputTokens,
1705
+ outputTokens: accumulatedOutputTokens,
1706
+ totalTokens: accumulatedInputTokens + accumulatedOutputTokens,
1707
+ contextTokens: totalContextTokens,
1708
+ maxContextTokens
1672
1709
  });
1673
1710
  } catch (error) {
1674
1711
  const isAborted = error instanceof TurnAbortedError || signal.aborted;
@@ -1762,6 +1799,7 @@ class Session {
1762
1799
  tools;
1763
1800
  skillsLoader;
1764
1801
  memoryStore;
1802
+ execPolicy;
1765
1803
  history = [];
1766
1804
  activeTurn = null;
1767
1805
  status = "idle";
@@ -1779,6 +1817,7 @@ class Session {
1779
1817
  this.tools = options.tools || new ToolRouter;
1780
1818
  this.skillsLoader = options.skillsLoader;
1781
1819
  this.memoryStore = options.memoryStore;
1820
+ this.execPolicy = options.execPolicy || new ExecPolicy;
1782
1821
  this.history = options.initialHistory ? [...options.initialHistory] : [];
1783
1822
  if (options.onEvent) {
1784
1823
  this.eventListeners.push(options.onEvent);
@@ -3987,7 +4026,7 @@ class AuthClient {
3987
4026
  </head>
3988
4027
  <body>
3989
4028
  <div class="box">
3990
- <h1>\u26A1 Authentication Successful!</h1>
4029
+ <h1>Authentication Successful!</h1>
3991
4030
  <p>You have successfully logged in to Groupy CLI. You can close this window and return to your terminal.</p>
3992
4031
  </div>
3993
4032
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikaa-ai/pikaa",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "PIKAA CLI - AI coding agent that runs locally in your terminal.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",